[
  {
    "path": ".github/workflows/build_android.yml",
    "content": "name: build android\r\non:\r\n  push: {tags:  ['v*']} #  Push events to matching v*, i.e. v1.0, v20.15.10\r\n\r\npermissions:\r\n  contents: write\r\n\r\nenv:\r\n  BUILD_NAME: krk2yuri_android\r\n\r\njobs:\r\n  fetch_thirdparty_build:\r\n    runs-on: ubuntu-20.04\r\n    steps:\r\n    - uses: actions/checkout@v3\r\n    \r\n    - name: check thirdparty build\r\n      id: check_thirdparty_build\r\n      uses: actions/cache@v3\r\n      with: \r\n        path: ./thirdparty/build\r\n        key: thirdparty_build\r\n    \r\n    - name: fetch thirdparty build\r\n      if: steps.check_thirdparty_build.outputs.cache-hit != 'true'\r\n      run: |\r\n        wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_build.tar.gz\r\n        tar xvzf thirdparty_build.tar.gz\r\n\r\n  fetch_thirdparty_port:\r\n    runs-on: ubuntu-20.04\r\n    steps:\r\n    - uses: actions/checkout@v3\r\n    \r\n    - name: check thirdparty port\r\n      id: check_thirdparty_port\r\n      uses: actions/cache@v3\r\n      with: \r\n        path: ./thirdparty/port\r\n        key: thirdparty_port\r\n    \r\n    - name: fetch thirdparty port\r\n      if: steps.check_thirdparty_port.outputs.cache-hit != 'true'\r\n      run: |\r\n        wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_port.tar.gz\r\n        tar xvzf thirdparty_port.tar.gz\r\n\r\n  build_android:\r\n    runs-on: ubuntu-20.04\r\n    needs: \r\n      - fetch_thirdparty_build\r\n      - fetch_thirdparty_port\r\n\r\n    steps:\r\n    - uses: actions/checkout@v3\r\n\r\n    - name: get thirdparty build cache\r\n      uses: actions/cache@v3\r\n      with: \r\n        key: thirdparty_build\r\n        path: ./thirdparty/build\r\n\r\n    - name: get thirdparty port cache\r\n      uses: actions/cache@v3\r\n      with: \r\n        key: thirdparty_port\r\n        path: ./thirdparty/port\r\n   \r\n    - uses: actions/setup-java@v3\r\n      with:\r\n        java-version:  |\r\n            8\r\n            11\r\n        distribution: 'temurin'\r\n        cache: gradle\r\n\r\n    - name: build krkr2yuri android\r\n      env:\r\n        SIGN_KEY_ALIAS: ${{ secrets.SIGN_KEY_ALIAS }}\r\n        SIGN_KEY_PASS: ${{ secrets.SIGN_KEY_PASS }}\r\n        SIGN_STORE_PASS: ${{ secrets.SIGN_STORE_PASS }}\r\n      run: |\r\n        wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk\r\n        7z x Kirikiroid2_yuri_1.3.9.apk assets\r\n        sudo mkdir /build_android && sudo chmod 777 /build_android \r\n        cd project/android\r\n        chmod +x ./gradlew \r\n        ./gradlew assembleDebug --no-daemon\r\n    \r\n    - name: create release\r\n      uses: ncipollo/release-action@v1\r\n      with:\r\n        artifacts: \"./build_android/outputs/apk/debug/*.apk\"\r\n        allowUpdates: \"true\"\r\n        prerelease: \"true\"\r\n        token: ${{ secrets.GITHUB_TOKEN }}"
  },
  {
    "path": ".gitignore",
    "content": "# general\r\nassets/**\r\nbuild/**\r\nbuild_*/**\r\nthirdparty/build/**\r\nthirdparty/port/**\r\n.vscode/settings.json\r\n\r\n# android\r\nlocal.properties\r\nsign.properties\r\nproject/onsyuri_android/.gradle\r\nproject/android/local.properties\r\nproject/android/.idea/caches/**\r\nproject/android/.idea/modules/**\r\nproject/android/.idea/libraries/**\r\nproject/android/.idea/modules.xml\r\nproject/android/.idea/workspace.xml\r\nproject/android/.idea/navEditor.xml\r\nproject/android/.idea/assetWizardSettings.xml\r\nproject/android/.idea/deploymentTargetDropDown.xml\r\nproject/android/.idea/inspectionProfiles\r\nproject/android/app/.cxx/**\r\nproject/android/app/debug/**\r\nproject/android/app/release/**"
  },
  {
    "path": ".vscode/c_cpp_properties.json",
    "content": "{\n    \"env\": { // edit your env here\n        \"androidsdk\": \"D:/Software/env/sdk/androidsdk\",\n        \"androidndk\": \"${androidsdk}/ndk/25.2.9519653\"\n    },\n    \"configurations\": [\n        {\n            \"name\": \"Android (win)\",\n            \"includePath\": [\n                \"${workspaceFolder}/src/core/**\",\n                \"${workspaceFolder}/src/core/sound/**\",\n                \"${workspaceFolder}/thirdparty/build/arch_androida64/include/**\",\n                \"${workspaceFolder}/thirdparty/build/arch_androida64/sdk/native/jni/include/**\",\n                \"${workspaceFolder}/thirdparty/port/cocos2d-x/**\",\n                \"${workspaceFolder}/thirdparty/port/cocos2d-x/external/**\",\n                \"${workspaceFolder}/thirdparty/port/cocos2d-x/cocos/**\",\n                \"${env:androidndk}/sources/android/cpufeatures\"\n            ],\n            \"defines\": [\n                \"__linux__\"\n            ],\n            \"compilerPath\": \"${androidndk}/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe\",\n            \"intelliSenseMode\": \"linux-clang-arm64\",\n            \"compilerArgs\": [\"--target=aarch64-linux-android21\"]\n        }\n    ],\n    \"version\": 4\n}"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.6)\nproject(krkr2yuri)\n\nset(CMAKE_CXX_STANDARD 11)\nset(KRKR2CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/core)\nset(KRKR2PLUGIN_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/plugins)\nset(COCOS2DX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/port/cocos2d-x)\n\n# build library\nadd_subdirectory(${KRKR2CORE_PATH})\nadd_subdirectory(${KRKR2PLUGIN_PATH})\n\n# build main\nif(CMAKE_SYSTEM_NAME MATCHES \"Android\")\n    add_library(${PROJECT_NAME} SHARED \n        project/android/app/cpp/krkr2_android.cpp\n    )\nelseif(CMAKE_SYSTEM_NAME MATCHES \"Linux\")\n    message(\"${CMAKE_SYSTEM_NAME} not support yet\")\nelseif(CMAKE_SYSTEM_NAME MATCHES \"Windows\")\n    message(\"${CMAKE_SYSTEM_NAME} not support yet\")\nelse()\n    message(\"${CMAKE_SYSTEM_NAME} not support yet\")\nendif()\ntarget_compile_options(${PROJECT_NAME} PUBLIC\n    -fPIE\n)\ntarget_include_directories(${PROJECT_NAME} PUBLIC\n    src/cocos\n    ${KRKR2CORE_PATH}/environ/cocos2d\n    ${PORTBUILD_PATH}/include\n    ${PORTBUILD_PATH}/include/breakpad\n    ${COCOS2DX_PATH}/cocos\n    ${COCOS2DX_PATH}/cocos/audio/include\n)\ntarget_link_directories(${PROJECT_NAME} PUBLIC\n    ${PORTBUILD_PATH}/lib\n)\ntarget_link_libraries(${PROJECT_NAME} PUBLIC \n    -Wl,-Bstatic\n    -Wl,--whole-archive # cpp_android_spec for jni function, this is important to add whole libraries !\n    cpp_android_spec krkr2plugin \n    -Wl,--no-whole-archive\n    krkr2core \n)"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c), W.Dee and contributors All rights reserved.\nContributors\n Go Watanabe, Kenjo, Kiyobee, Kouhei Yanagita, mey, MIK, Takenori Imoto, yun\nKirikiri Z Project Contributors\nW.Dee, casper, 有限会社MCF, Biscrat, 青猫, nagai, ルー, 高際 雅之, 永劫,\nゆんゆん探偵, りょうご（今は無きあの星）, AZ-UME, 京 秋人, \nKatsumasa Tsuneyoshi, 小池潤, miahmie, サークル獏, アザナシ, はっしぃ, \n棚中製作所, わっふる/waffle, ワムソフト, TYPE-MOON, 有限会社エムツー,\nTakenori Imoto\nKirikiri Z 64bit Project Contributors\n合資会社ワムソフト, Takenori Imoto, 他\n----------------------------------------------------------------------------\nソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満\nたす場合に限り、再頒布および使用が許可されます。\n\n・ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責\n  条項を含めること。\n・バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の\n  著作権表示、本条件一覧、および下記免責条項を含めること。\n・書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売\n  促進に、組織の名前またはコントリビューターの名前を使用してはならない。\n\n本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供\nされており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適\n合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありませ\nん。著作権者もコントリビューターも、事由のいかんを問わず、損害発生の原因いか\nんを問わず、かつ責任の根拠が契約であるか厳格責任であるか（過失その他の）不法\n行為であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとし\nても、本ソフトウェアの使用によって発生した（代替品または代用サービスの調達、\n使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されな\nい）直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害に\nついて、一切責任を負わないものとします。\n\n------------------------------------------------------------------------------\nThanks for many libraries to contributors and other supporters that were not\nlisted here.\n\nThis software is based in part on the work of Independent JPEG Group.\n------------------------------------------------------------------------------\nlibjpeg-turbo\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n?\tRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n?\tRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation and/or\nother materials provided with the distribution.\n?\tNeither the name of the libjpeg-turbo Project nor the names of its contributors\nmay be used to endorse or promote products derived from this software without\nspecific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\", AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA,\nOR PROFITS;  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\nOF THE POSSIBILITY OF SUCH DAMAGE.\n------------------------------------------------------------------------------\nUsing \"A C-program for MT19937\"\n\n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   All rights reserved.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n     1. Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n\n     2. Redistributions in binary form must reproduce the above copyright\n        notice, this list of conditions and the following disclaimer in the\n        documentation and/or other materials provided with the distribution.\n\n     3. The names of its contributors may not be used to endorse or promote\n        products derived from this software without specific prior written\n        permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n------------------------------------------------------------------------------\nlibpng LICENSE\n\nThis copy of the libpng notices is provided for your convenience.  In case of\nany discrepancy between this copy and the notices in the file png.h that is\nincluded in the libpng distribution, the latter shall prevail.\n\nCOPYRIGHT NOTICE, DISCLAIMER, and LICENSE:\n\nIf you modify libpng you may insert additional notices immediately following\nthis sentence.\n\nThis code is released under the libpng license.\n\nlibpng versions 1.2.6, August 15, 2004, through 1.6.1, March 28, 2013, are\nCopyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are\ndistributed according to the same disclaimer and license as libpng-1.2.5\nwith the following individual added to the list of Contributing Authors\n\n   Cosmin Truta\n\nlibpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are\nCopyright (c) 2000-2002 Glenn Randers-Pehrson, and are\ndistributed according to the same disclaimer and license as libpng-1.0.6\nwith the following individuals added to the list of Contributing Authors\n\n   Simon-Pierre Cadieux\n   Eric S. Raymond\n   Gilles Vollant\n\nand with the following additions to the disclaimer:\n\n   There is no warranty against interference with your enjoyment of the\n   library or against infringement.  There is no warranty that our\n   efforts or the library will fulfill any of your particular purposes\n   or needs.  This library is provided with all faults, and the entire\n   risk of satisfactory quality, performance, accuracy, and effort is with\n   the user.\n\nlibpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are\nCopyright (c) 1998, 1999 Glenn Randers-Pehrson, and are\ndistributed according to the same disclaimer and license as libpng-0.96,\nwith the following individuals added to the list of Contributing Authors:\n\n   Tom Lane\n   Glenn Randers-Pehrson\n   Willem van Schaik\n\nlibpng versions 0.89, June 1996, through 0.96, May 1997, are\nCopyright (c) 1996, 1997 Andreas Dilger\nDistributed according to the same disclaimer and license as libpng-0.88,\nwith the following individuals added to the list of Contributing Authors:\n\n   John Bowler\n   Kevin Bracey\n   Sam Bushell\n   Magnus Holmgren\n   Greg Roelofs\n   Tom Tanner\n\nlibpng versions 0.5, May 1995, through 0.88, January 1996, are\nCopyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\nFor the purposes of this copyright and license, \"Contributing Authors\"\nis defined as the following set of individuals:\n\n   Andreas Dilger\n   Dave Martindale\n   Guy Eric Schalnat\n   Paul Schmidt\n   Tim Wegner\n\nThe PNG Reference Library is supplied \"AS IS\".  The Contributing Authors\nand Group 42, Inc. disclaim all warranties, expressed or implied,\nincluding, without limitation, the warranties of merchantability and of\nfitness for any purpose.  The Contributing Authors and Group 42, Inc.\nassume no liability for direct, indirect, incidental, special, exemplary,\nor consequential damages, which may result from the use of the PNG\nReference Library, even if advised of the possibility of such damage.\n\nPermission is hereby granted to use, copy, modify, and distribute this\nsource code, or portions hereof, for any purpose, without fee, subject\nto the following restrictions:\n\n1. The origin of this source code must not be misrepresented.\n\n2. Altered versions must be plainly marked as such and must not\n   be misrepresented as being the original source.\n\n3. This Copyright notice may not be removed or altered from any\n   source or altered source distribution.\n\nThe Contributing Authors and Group 42, Inc. specifically permit, without\nfee, and encourage the use of this source code as a component to\nsupporting the PNG file format in commercial products.  If you use this\nsource code in a product, acknowledgment is not required but would be\nappreciated.\n\n\nA \"png_get_copyright\" function is available, for convenient use in \"about\"\nboxes and the like:\n\n   printf(\"%s\",png_get_copyright(NULL));\n\nAlso, the PNG logo (in PNG format, of course) is supplied in the\nfiles \"pngbar.png\" and \"pngbar.jpg (88x31) and \"pngnow.png\" (98x31).\n\nLibpng is OSI Certified Open Source Software.  OSI Certified Open Source is a\ncertification mark of the Open Source Initiative.\n\nGlenn Randers-Pehrson\nglennrp at users.sourceforge.net\nMarch 28, 2013\n------------------------------------------------------------------------------\nzlib LICENSE\n\n  The deflate format used by zlib was defined by Phil Katz.  The deflate and\n  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the\n  people who reported problems and suggested various improvements in zlib; they\n  are too numerous to cite here.\n\nCopyright notice:\n\n (C) 1995-2012 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\nIf you use the zlib library in a product, we would appreciate *not* receiving\nlengthy legal documents to sign.  The sources are provided for free but without\nwarranty of any kind.  The library has been entirely written by Jean-loup\nGailly and Mark Adler; it does not include third-party code.\n\nIf you redistribute modified sources, we would appreciate that you include in\nthe file ChangeLog history information documenting your changes.  Please read\nthe FAQ for more information on the distribution of modified source versions.\n------------------------------------------------------------------------------\n\nOniguruma LICENSE\n-----------------\n\n/*-\n * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n------------------------------------------------------------------------------\n                    The FreeType Project LICENSE\n                    ----------------------------\n\n                            2006-Jan-27\n\n                    Copyright 1996-2002, 2006 by\n          David Turner, Robert Wilhelm, and Werner Lemberg\n\n\n\nIntroduction\n============\n\n  The FreeType  Project is distributed in  several archive packages;\n  some of them may contain, in addition to the FreeType font engine,\n  various tools and  contributions which rely on, or  relate to, the\n  FreeType Project.\n\n  This  license applies  to all  files found  in such  packages, and\n  which do not  fall under their own explicit  license.  The license\n  affects  thus  the  FreeType   font  engine,  the  test  programs,\n  documentation and makefiles, at the very least.\n\n  This  license   was  inspired  by  the  BSD,   Artistic,  and  IJG\n  (Independent JPEG  Group) licenses, which  all encourage inclusion\n  and  use of  free  software in  commercial  and freeware  products\n  alike.  As a consequence, its main points are that:\n\n    o We don't promise that this software works. However, we will be\n      interested in any kind of bug reports. (`as is' distribution)\n\n    o You can  use this software for whatever you  want, in parts or\n      full form, without having to pay us. (`royalty-free' usage)\n\n    o You may not pretend that  you wrote this software.  If you use\n      it, or  only parts of it,  in a program,  you must acknowledge\n      somewhere  in  your  documentation  that  you  have  used  the\n      FreeType code. (`credits')\n\n  We  specifically  permit  and  encourage  the  inclusion  of  this\n  software, with  or without modifications,  in commercial products.\n  We  disclaim  all warranties  covering  The  FreeType Project  and\n  assume no liability related to The FreeType Project.\n\n\n  Finally,  many  people  asked  us  for  a  preferred  form  for  a\n  credit/disclaimer to use in compliance with this license.  We thus\n  encourage you to use the following text:\n\n   \"\"\"\n    Portions of this software are copyright ｩ <year> The FreeType\n    Project (www.freetype.org).  All rights reserved.\n   \"\"\"\n\n  Please replace <year> with the value from the FreeType version you\n  actually use.\n\n\nLegal Terms\n===========\n\n0. Definitions\n--------------\n\n  Throughout this license,  the terms `package', `FreeType Project',\n  and  `FreeType  archive' refer  to  the  set  of files  originally\n  distributed  by the  authors  (David Turner,  Robert Wilhelm,  and\n  Werner Lemberg) as the `FreeType Project', be they named as alpha,\n  beta or final release.\n\n  `You' refers to  the licensee, or person using  the project, where\n  `using' is a generic term including compiling the project's source\n  code as  well as linking it  to form a  `program' or `executable'.\n  This  program is  referred to  as  `a program  using the  FreeType\n  engine'.\n\n  This  license applies  to all  files distributed  in  the original\n  FreeType  Project,   including  all  source   code,  binaries  and\n  documentation,  unless  otherwise  stated   in  the  file  in  its\n  original, unmodified form as  distributed in the original archive.\n  If you are  unsure whether or not a particular  file is covered by\n  this license, you must contact us to verify this.\n\n  The FreeType  Project is copyright (C) 1996-2000  by David Turner,\n  Robert Wilhelm, and Werner Lemberg.  All rights reserved except as\n  specified below.\n\n1. No Warranty\n--------------\n\n  THE FREETYPE PROJECT  IS PROVIDED `AS IS' WITHOUT  WARRANTY OF ANY\n  KIND, EITHER  EXPRESS OR IMPLIED,  INCLUDING, BUT NOT  LIMITED TO,\n  WARRANTIES  OF  MERCHANTABILITY   AND  FITNESS  FOR  A  PARTICULAR\n  PURPOSE.  IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS\n  BE LIABLE  FOR ANY DAMAGES CAUSED  BY THE USE OR  THE INABILITY TO\n  USE, OF THE FREETYPE PROJECT.\n\n2. Redistribution\n-----------------\n\n  This  license  grants  a  worldwide, royalty-free,  perpetual  and\n  irrevocable right  and license to use,  execute, perform, compile,\n  display,  copy,   create  derivative  works   of,  distribute  and\n  sublicense the  FreeType Project (in  both source and  object code\n  forms)  and  derivative works  thereof  for  any  purpose; and  to\n  authorize others  to exercise  some or all  of the  rights granted\n  herein, subject to the following conditions:\n\n    o Redistribution of  source code  must retain this  license file\n      (`FTL.TXT') unaltered; any  additions, deletions or changes to\n      the original  files must be clearly  indicated in accompanying\n      documentation.   The  copyright   notices  of  the  unaltered,\n      original  files must  be  preserved in  all  copies of  source\n      files.\n\n    o Redistribution in binary form must provide a  disclaimer  that\n      states  that  the software is based in part of the work of the\n      FreeType Team,  in  the  distribution  documentation.  We also\n      encourage you to put an URL to the FreeType web page  in  your\n      documentation, though this isn't mandatory.\n\n  These conditions  apply to any  software derived from or  based on\n  the FreeType Project,  not just the unmodified files.   If you use\n  our work, you  must acknowledge us.  However, no  fee need be paid\n  to us.\n\n3. Advertising\n--------------\n\n  Neither the  FreeType authors and  contributors nor you  shall use\n  the name of the  other for commercial, advertising, or promotional\n  purposes without specific prior written permission.\n\n  We suggest,  but do not require, that  you use one or  more of the\n  following phrases to refer  to this software in your documentation\n  or advertising  materials: `FreeType Project',  `FreeType Engine',\n  `FreeType library', or `FreeType Distribution'.\n\n  As  you have  not signed  this license,  you are  not  required to\n  accept  it.   However,  as  the FreeType  Project  is  copyrighted\n  material, only  this license, or  another one contracted  with the\n  authors, grants you  the right to use, distribute,  and modify it.\n  Therefore,  by  using,  distributing,  or modifying  the  FreeType\n  Project, you indicate that you understand and accept all the terms\n  of this license.\n\n4. Contacts\n-----------\n\n  There are two mailing lists related to FreeType:\n\n    o freetype@nongnu.org\n\n      Discusses general use and applications of FreeType, as well as\n      future and  wanted additions to the  library and distribution.\n      If  you are looking  for support,  start in  this list  if you\n      haven't found anything to help you in the documentation.\n\n    o freetype-devel@nongnu.org\n\n      Discusses bugs,  as well  as engine internals,  design issues,\n      specific licenses, porting, etc.\n\n  Our home page can be found at\n\n    http://www.freetype.org\n------------------------------------------------------------------------------\npicojson LICENSE\n\n/* Copyright 2009 Cybozu Labs, Inc.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n * \n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *    and/or other materials provided with the distribution.\n * \n * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * The views and conclusions contained in the software and documentation are\n * those of the authors and should not be interpreted as representing official\n * policies, either expressed or implied, of Cybozu Labs, Inc.\n *\n */\n------------------------------------------------------------------------------\n\n   Copyright (c) 2012, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n------------------------------------------------------------------------------\nMicrosoft Corporation Technical Documentation License Agreement for the \nspecification “JPEG XR Device Porting Kit”\nCopyright (c) 2013 Microsoft Corp.\nAll rights reserved.\nRedistribution and use in source and binary forms, with or without modification,\n are permitted provided that the following conditions are met:\n Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"AND\n ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED\n WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BELIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE..\n------------------------------------------------------------------------------\n------------------------------------------------------------------------\n*** vorbis\n*** ogg\n\nCopyright (c) 1994-2004 Xiph.org Foundation\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\n  notice, this list of conditions and the following disclaimer in the\n  documentation and/or other materials provided with the distribution.\n\n- Neither the name of the Xiph.org Foundation nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\n------------------------------------------------------------------------\n*** theora\n\nCopyright (C) 2002-2008 Xiph.org Foundation and contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n- Neither the name of the Xiph.org Foundation nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION\nOR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n------------------------------------------------------------------------\n*** libfishsound\n*** dsfSeeking\n\nCopyright (C) 2003, 2004 Commonwealth Scientific and Industrial Research\n  Organisation (CSIRO) Australia\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n- Neither the name of the CSIRO Australia nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n------------------------------------------------------------------------ \n*** libCMMLParse\n*** libCMMLTags\n*** libCMMLTagsDotNET\n*** libOOOggChef\n*** libTemporalURI\n*** libWinCMMLParse\n*** dsfCMMLDecoder\n*** dsfAnxDemux\n*** AnxCutter\n*** CMMLDump\n*** mod_oggchef\n\nCopyright (C) 2003-2005 Zentaro Kavanagh\n\nCopyright (C) 2003-2005 Commonwealth Scientific and Industrial Research\n  Organisation (CSIRO) Australia\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n- Neither the name of CSIRO Australia nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n------------------------------------------------------------------------ \n*** dsfOggDemux\n*** dsfOggMux\n*** dsfSpeexDecoder\n*** dsfSpeexEncoder\n*** dsfVorbisDecoder\n*** dsfVorbisEncoder\n*** dsfFLACDecoder\n*** dsfFLACEncoder\n*** dsfTheoraDecoder\n*** dsfTheoraEncoder\n*** dsfAbstractAudioDecoder\n*** dsfAbstractAudioEncoder\n*** dsfAbstractVideoDecoder\n*** dsfAbstractVideoEncoder\n*** dsfSubtitleVMR9\n*** libiWrapper\n*** libilliCore\n*** libOOTheora\n*** libOOOgg\n*** libOOOggSeek\n*** libVorbisComment\n*** libVorbisCommentDotNET\n*** OOOggDump\n*** OOOggStat\n*** OOOggCommentDump\n*** CLOgg\n*** DNPlay\n*** iOCE\n\nCopyright (C) 2008-2010 Cristian Adam\nCopyright (C) 2003-2005 Zentaro Kavanagh\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n- Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n\n- Redistributions in binary form must reproduce the above copyright\n  notice, this list of conditions and the following disclaimer in the\n  documentation and/or other materials provided with the distribution.\n\n- Neither the name of Zentaro Kavanagh nor the names of contributors \n  may be used to endorse or promote products derived from this software \n  without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n------------------------------------------------------------------------\n"
  },
  {
    "path": "project/android/.gitignore",
    "content": ".gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n/.externalNativeBuild\n"
  },
  {
    "path": "project/android/.idea/.gitignore",
    "content": "# Default ignored files\r\n/shelf/\r\n/workspace.xml\r\n"
  },
  {
    "path": "project/android/.idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <codeStyleSettings language=\"XML\">\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n      <arrangement>\n        <rules>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:android</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:id</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>style</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>ANDROID_ATTRIBUTE_ORDER</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>.*</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n        </rules>\n      </arrangement>\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": "project/android/.idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <bytecodeTargetLevel target=\"11\" />\n  </component>\n</project>"
  },
  {
    "path": "project/android/.idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"testRunner\" value=\"GRADLE\" />\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"gradleJvm\" value=\"JDK\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n            <option value=\"$PROJECT_DIR$/../../thirdparty/port/cocos2d-x/cocos/platform/android/libcocos2dx\" />\n          </set>\n        </option>\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": "project/android/.idea/jarRepositories.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RemoteRepositoriesConfiguration\">\n    <remote-repository>\n      <option name=\"id\" value=\"central\" />\n      <option name=\"name\" value=\"Maven Central repository\" />\n      <option name=\"url\" value=\"https://repo1.maven.org/maven2\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"jboss.community\" />\n      <option name=\"name\" value=\"JBoss Community repository\" />\n      <option name=\"url\" value=\"https://repository.jboss.org/nexus/content/repositories/public/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"BintrayJCenter\" />\n      <option name=\"name\" value=\"BintrayJCenter\" />\n      <option name=\"url\" value=\"https://jcenter.bintray.com/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"Google\" />\n      <option name=\"name\" value=\"Google\" />\n      <option name=\"url\" value=\"https://dl.google.com/dl/android/maven2/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"MavenRepo\" />\n      <option name=\"name\" value=\"MavenRepo\" />\n      <option name=\"url\" value=\"https://repo.maven.apache.org/maven2/\" />\n    </remote-repository>\n  </component>\n</project>"
  },
  {
    "path": "project/android/.idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_11\" default=\"true\" project-jdk-name=\"JDK\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": "project/android/.idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project version=\"4\">\r\n  <component name=\"VcsDirectoryMappings\">\r\n    <mapping directory=\"$PROJECT_DIR$/../../thirdparty/port/cocos2d-x\" vcs=\"Git\" />\r\n  </component>\r\n</project>"
  },
  {
    "path": "project/android/app/.gitignore",
    "content": "/.externalNativeBuild\n/.cxx\n/build\n/release\n"
  },
  {
    "path": "project/android/app/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Replace org.libsdl.app with the identifier of your game below, e.g.\n     com.gamemaker.game\n-->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.yuri.kirikiri2\"\n      android:versionCode=\"64\"\n      android:versionName=\"1.4.0beta\"\n      android:installLocation=\"auto\">\n\n    <!-- OpenGL ES 2.0 -->\n    <uses-feature android:glEsVersion=\"0x00020000\" />\n\n    <!-- Allow writing to external storage -->\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\n        tools:ignore=\"ScopedStorage\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <application android:label=\"@string/app_name\"\n                 android:icon=\"@mipmap/ic_launcher\"\n                 android:allowBackup=\"true\" android:resizeableActivity=\"true\"\n                 android:requestLegacyExternalStorage=\"true\"\n        tools:targetApi=\"n\">\n        <meta-data android:name=\"android.app.lib_name\"\n                   android:value=\"krkr2yuri\" />\n        <activity android:name=\".MainActivity\"\n            android:screenOrientation=\"sensorLandscape\"\n                  android:configChanges=\"keyboardHidden|orientation|screenSize\"\n                  android:windowSoftInputMode=\"adjustPan\" android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest> \n"
  },
  {
    "path": "project/android/app/build.gradle",
    "content": "plugins {\n    id 'com.android.application'\n}\n\nandroid {\n    // compileSdkVersion PROP_TARGET_SDK_VERSION\n    ndkVersion '25.2.9519653'\n    buildToolsVersion '33.0.2'\n    compileSdkVersion PROP_TARGET_SDK_VERSION.toInteger()\n    compileOptions {\n//        sourceCompatibility JavaVersion.VERSION_11\n//        targetCompatibility JavaVersion.VERSION_11\n    }\n\n    defaultConfig {\n        applicationId \"com.yuri.kirikiri2\"\n        targetSdkVersion PROP_TARGET_SDK_VERSION\n        minSdkVersion PROP_MIN_SDK_VERSION\n\n        ndk {\n            abiFilters = []\n            abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})\n        }\n\n        externalNativeBuild {\n            if (PROP_BUILD_TYPE == 'cmake') {\n                cmake {\n                    version '3.22.1'\n                    targets 'krkr2yuri'\n                    arguments \"-DCMAKE_FIND_ROOT_PATH=\", \"-DANDROID_STL=c++_static\", \"-DANDROID_TOOLCHAIN=clang\", \"-DANDROID_ARM_NEON=TRUE\"\n                    cppFlags \"-frtti -fexceptions -fsigned-char\"\n                }\n            }\n        }\n        versionCode 1\n        versionName \"1.4.0beta\"\n    }\n    signingConfigs {\n        release {\n            storeFile file('sign.jks')\n            def signPropsFile = file('sign.properties')\n            if (signPropsFile.exists()) {\n                Properties signProps = new Properties()\n                signProps.load(new FileInputStream(signPropsFile))\n                keyAlias signProps['SIGN_KEY_ALIAS']\n                keyPassword signProps['SIGN_KEY_PASS']\n                storePassword signProps['SIGN_STORE_PASS']\n            }\n            else {\n                keyAlias System.getenv(\"SIGN_KEY_ALIAS\")\n                keyPassword System.getenv(\"SIGN_KEY_PASS\")\n                storePassword System.getenv(\"SIGN_STORE_PASS\")\n            }\n        }\n    }\n    buildTypes {\n        release {\n            debuggable false\n            renderscriptDebuggable false\n            minifyEnabled true\n            shrinkResources true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n            signingConfig signingConfigs.release\n        }\n\n        debug {\n            debuggable true\n            jniDebuggable true\n            jniDebuggable true\n            renderscriptDebuggable true\n            signingConfig signingConfigs.release\n        }\n    }\n\n    sourceSets{\n        main{\n            manifest.srcFile \"AndroidManifest.xml\"\n            java.srcDirs = [\"java\"]\n            res.srcDirs = [\"res\"]\n            assets.srcDirs =[\"../../../assets\"]\n        }\n\n    }\n\n    externalNativeBuild {\n        cmake {\n            version '3.22.1'\n            path \"cpp/CMakeLists.txt\"\n        }\n    }\n\n    android.applicationVariants.all { variant ->\n        variant.outputs.all {\n            outputFileName = \"krkr2yuri_v${defaultConfig.versionName}.apk\"\n        }\n    }\n}\n\ndependencies {\n    //implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation project(':cocos2dx')\n\n    implementation \"androidx.documentfile:documentfile:1.0.1\"\n    //noinspection GradleDependency\n    implementation \"androidx.activity:activity:1.2.3\"\n    //noinspection GradleDependency\n    implementation \"androidx.fragment:fragment:1.3.4\"\n}\n"
  },
  {
    "path": "project/android/app/cpp/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.7)\r\nproject(krkr2yuri_android)\r\n\r\nset(KRKR2YURI_DIR ${CMAKE_SOURCE_DIR}/../../../..)\r\nif(${ANDROID_ABI} MATCHES \"arm64-v8a\")\r\n    set(PORTBUILD_PATH ${KRKR2YURI_DIR}/thirdparty/build/arch_androida64)\r\nelse()\r\n    set(PORTBUILD_PATH ${KRKR2YURI_DIR}/thirdparty/build/arch_androida64)\r\nendif()\r\n\r\nif (CMAKE_BUILD_TYPE STREQUAL \"Debug\")\r\n    set(CMAKE_CXX_FLAGS_DEBUG \"${CMAKE_CXX_FLAGS_DEBUG} -O0 -g\")\r\nendif()\r\n\r\nadd_subdirectory(${KRKR2YURI_DIR} ${KRKR2YURI_DIR}/build_android)"
  },
  {
    "path": "project/android/app/cpp/krkr2_android.cpp",
    "content": "/* Include the SDL main definition header */\n#include <jni.h>\n#include \"platform/android/jni/JniHelper.h\"\n#include \"cocos2d/AppDelegate.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n#include \"Application.h\"\n\n/*******************************************************************************\n                 Functions called by JNI\n*******************************************************************************/\n#include <string.h>\n#include <string>\n#include <condition_variable>\n#include <mutex>\n#include \"breakpad/client/linux/handler/exception_handler.h\"\n#include \"breakpad/client/linux/handler/minidump_descriptor.h\"\n\n//std::string Android_GetDumpStoragePath();\n\nstatic bool __DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,\n\tvoid* context, bool succeeded)\n{\n\treturn succeeded;\n}\n\nextern bool TVPSystemUninitCalled;\n\nstatic bool __DumpFilter(void *data) {\n\tif(TVPSystemUninitCalled) return false; // if trying exit system, ignore all exception\n\treturn true;\n}\n\n\n//static void __InitAndroidDump() {\n//    static google_breakpad::MinidumpDescriptor descriptor(Android_GetDumpStoragePath());\n//\tstatic google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback,\n//\t\tNULL, true, -1);\n//}\n\nvoid cocos_android_app_init (JNIEnv* env) { // for cocos3.10+\n//\t__InitAndroidDump();\n\t__android_log_print(ANDROID_LOG_INFO,\"## krkr2yuri\",\"in cocos_android_app_init\");\n\tstatic TVPAppDelegate *pAppDelegate = new TVPAppDelegate();\n}\n\nnamespace kr2android {\n\textern std::condition_variable MessageBoxCond;\n\textern std::mutex MessageBoxLock;\n\textern int MsgBoxRet;\n    extern std::string MessageBoxRetText;\n}\nvoid Android_PushEvents(const std::function<void()> &func);\nusing namespace kr2android;\nextern \"C\" {\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_initDump(JNIEnv* env, jclass cls, jstring path) {\n\t\tconst char* pszPath = env->GetStringUTFChars(path, NULL);\n\t\tif (pszPath && *pszPath) {\n\t\t\tstatic google_breakpad::MinidumpDescriptor descriptor(pszPath);\n\t\t\tstatic google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback,\n\t\t\t\tNULL, true, -1);\n\t\t}\n\t\tenv->ReleaseStringUTFChars(path, pszPath);\n\t}\n\t\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxOK(JNIEnv* env, jclass cls, jint nButton) {\n\t\tMsgBoxRet = nButton;\n\t\tMessageBoxCond.notify_one();\n\t}\n    \n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxText(JNIEnv* env, jclass cls, jstring text) {\n\t\tconst char* pszText = env->GetStringUTFChars(text, NULL);\n\t\tif (pszText && *pszText) {\n            MessageBoxRetText = pszText;\n\t\t}\n\t\tenv->ReleaseStringUTFChars(text, pszText);\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {\n\t\tintptr_t idlong = id;\n\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);\n\t\t});\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {\n\t\tintptr_t idlong = id;\n\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);\n\t\t});\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesMove(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {\n\t\tint size = env->GetArrayLength(ids);\n\t\tif (size == 1) {\n\t\t\tintptr_t idlong;\n\t\t\tjint id;\n\t\t\tjfloat x;\n\t\t\tjfloat y;\n\t\t\tenv->GetIntArrayRegion(ids, 0, size, &id);\n\t\t\tenv->GetFloatArrayRegion(xs, 0, size, &x);\n\t\t\tenv->GetFloatArrayRegion(ys, 0, size, &y);\n\t\t\tidlong = id;\n\t\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tjint id[size];\n\t\tstd::vector<jfloat> x; x.resize(size);\n\t\tstd::vector<jfloat> y; y.resize(size);\n\n\t\tenv->GetIntArrayRegion(ids, 0, size, id);\n\t\tenv->GetFloatArrayRegion(xs, 0, size, &x[0]);\n\t\tenv->GetFloatArrayRegion(ys, 0, size, &y[0]);\n\n\t\tstd::vector<intptr_t> idlong; idlong.resize(size);\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tidlong[i] = id[i];\n\n\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]);\n\t\t});\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesCancel(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {\n\t\tint size = env->GetArrayLength(ids);\n\t\tif (size == 1) {\n\t\t\tintptr_t idlong;\n\t\t\tjint id;\n\t\t\tjfloat x;\n\t\t\tjfloat y;\n\t\t\tenv->GetIntArrayRegion(ids, 0, size, &id);\n\t\t\tenv->GetFloatArrayRegion(xs, 0, size, &x);\n\t\t\tenv->GetFloatArrayRegion(ys, 0, size, &y);\n\t\t\tidlong = id;\n\t\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tjint id[size];\n\t\tstd::vector<jfloat> x; x.resize(size);\n\t\tstd::vector<jfloat> y; y.resize(size);\n\n\t\tenv->GetIntArrayRegion(ids, 0, size, id);\n\t\tenv->GetFloatArrayRegion(xs, 0, size, &x[0]);\n\t\tenv->GetFloatArrayRegion(ys, 0, size, &y[0]);\n\n\t\tstd::vector<intptr_t> idlong; idlong.resize(size);\n\t\tfor (int i = 0; i < size; i++)\n\t\t\tidlong[i] = id[i];\n\n\t\tAndroid_PushEvents([idlong, x, y](){\n\t\t\tcocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]);\n\t\t});\n\t}\n\n#define KEYCODE_BACK 0x04\n#define KEYCODE_MENU 0x52\n#define KEYCODE_DPAD_UP 0x13\n#define KEYCODE_DPAD_DOWN 0x14\n#define KEYCODE_DPAD_LEFT 0x15\n#define KEYCODE_DPAD_RIGHT 0x16\n#define KEYCODE_ENTER 0x42\n#define KEYCODE_PLAY  0x7e\n#define KEYCODE_DPAD_CENTER  0x17\n#define KEYCODE_DEL 0x43\n\n\tJNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeKeyAction(JNIEnv * env, jclass cls, jint keyCode, jboolean isPress) {\n\t\tcocos2d::EventKeyboard::KeyCode pKeyCode;\n\t\tswitch (keyCode) {\n\t\tcase KEYCODE_BACK\t\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ESCAPE\t; break;\n\t\tcase KEYCODE_MENU\t\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_MENU\t\t; break;\n\t\tcase KEYCODE_DPAD_UP\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_UP\t; break;\n\t\tcase KEYCODE_DPAD_DOWN\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_DOWN\t; break;\n\t\tcase KEYCODE_DPAD_LEFT\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_LEFT\t; break;\n\t\tcase KEYCODE_DPAD_RIGHT\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_RIGHT; break;\n\t\tcase KEYCODE_ENTER\t\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ENTER\t\t; break;\n\t\tcase KEYCODE_PLAY\t\t: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_PLAY\t\t; break;\n\t\tcase KEYCODE_DPAD_CENTER: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_CENTER; break;\n        case KEYCODE_DEL          : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE; break;\n\t\tdefault: return JNI_FALSE;\n\t\t}\n\n\t\tAndroid_PushEvents([pKeyCode, isPress](){\n\t\t\tcocos2d::EventKeyboard event(pKeyCode, isPress);\n\t\t\tcocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);\n\t\t});\n\t\treturn JNI_TRUE;\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeInsertText(JNIEnv* env, jclass cls, jstring text) {\n\t\tconst char* pszText = env->GetStringUTFChars(text, NULL);\n\t\tif (pszText && *pszText) {\n\t\t\tstd::string str = pszText;\n\t\t\tAndroid_PushEvents([str](){\n\t\t\t\tcocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(str.c_str(), str.length());\n\t\t\t});\n\t\t}\n\t\tenv->ReleaseStringUTFChars(text, pszText);\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeDeleteBackward(JNIEnv* env, jclass cls) {\n\t\tAndroid_PushEvents(std::bind(&cocos2d::IMEDispatcher::dispatchDeleteBackward,\n\t\t\tcocos2d::IMEDispatcher::sharedDispatcher()));\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCharInput(JNIEnv* env, jclass cls, jint keyCode) {\n\t\tTVPMainScene *pScene = TVPMainScene::GetInstance();\n\t\tif (!pScene) return;\n\t\tpScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onCharInput, keyCode));\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCommitText(\n\t\tJNIEnv* env, jclass cls,\n\t\tjstring text, jint newCursorPosition)\n\t{\n\t\tTVPMainScene *pScene = TVPMainScene::GetInstance();\n\t\tif (!pScene) return;\n\t\tconst char *utftext = env->GetStringUTFChars(text, NULL);\n\t\tstd::string str(utftext);\n\t\tpScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onTextInput, str));\n\t\tenv->ReleaseStringUTFChars(text, utftext);\n\t}\n\n\tJNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeGetHideSystemButton(JNIEnv* env, jclass cls)\n\t{\n\t\treturn GlobalConfigManager::GetInstance()->GetValue<bool>(\"hide_android_sys_btn\", false);\n\t}\n\n\tstatic float _mouseX, _mouseY;\n\n\tJNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeHoverMoved(JNIEnv* env, jclass cls, jfloat x, jfloat y)\n\t{\n\t\tAndroid_PushEvents([x, y]() {\n\t\t\tcocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView();\n\t\t\tfloat _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY();\n\t\t\t_mouseX = x; _mouseY = y;\n\t\t\tconst cocos2d::Rect _viewPortRect = glview->getViewPortRect();\n\n\t\t\tfloat cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;\n\t\t\tfloat cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;\n\n\t\t\tcocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_MOVE);\n\t\t\tevent.setCursorPosition(cursorX, cursorY);\n\t\t\tcocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);\n\t\t});\n\t\treturn true;\n\t}\n\n\tJNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeMouseScrolled(JNIEnv* env, jclass cls, jfloat v)\n\t{\n\t\tAndroid_PushEvents([v]() {\n\t\t\tcocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView();\n\t\t\tfloat _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY();\n\t\t\tconst cocos2d::Rect _viewPortRect = glview->getViewPortRect();\n\n\t\t\tfloat cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;\n\t\t\tfloat cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;\n\n\t\t\tcocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_SCROLL);\n\t\t\tevent.setScrollData(0, v);\n\t\t\tevent.setCursorPosition(cursorX, cursorY);\n\t\t\tcocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);\n\t\t});\n\t\treturn true;\n\t}\n\n\tJNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeOnLowMemory(JNIEnv* env, jclass cls)\n\t{\n\t\tAndroid_PushEvents([]() {\n\t\t\t::Application->OnLowMemory();\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "project/android/app/java/com/yuri/kirikiri2/MainActivity.java",
    "content": "package com.yuri.kirikiri2;\nimport org.tvp.kirikiri2.KR2Activity;\n\npublic class MainActivity extends KR2Activity {\n\tstatic {\n\t\t// System.loadLibrary(\"krkr2yuri\");\n\t}\n\t@Override\n\tpublic int get_res_sd_operate_step() { return R.drawable.sd_operate_step; }\n}\n"
  },
  {
    "path": "project/android/app/java/org/tvp/kirikiri2/KR2Activity.java",
    "content": "package org.tvp.kirikiri2;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android.app.AlertDialog;\nimport android.content.ContentResolver;\nimport android.content.ContentValues;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.content.SharedPreferences;\nimport android.content.pm.ActivityInfo;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.database.Cursor;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Debug;\nimport android.os.Environment;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.os.storage.StorageManager;\nimport android.preference.PreferenceManager;\nimport android.provider.BaseColumns;\nimport android.provider.MediaStore;\nimport android.util.AttributeSet;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.inputmethod.BaseInputConnection;\nimport android.view.inputmethod.EditorInfo;\nimport android.view.inputmethod.InputConnection;\nimport android.view.inputmethod.InputMethodManager;\nimport android.widget.EditText;\nimport android.widget.FrameLayout;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\n\nimport androidx.annotation.NonNull;\nimport androidx.core.app.ActivityCompat;\nimport androidx.documentfile.provider.DocumentFile;\n\nimport org.cocos2dx.lib.Cocos2dxActivity;\nimport org.cocos2dx.lib.Cocos2dxGLSurfaceView;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\n\n/**\n * Utility class for handling the media store.\n */\n@SuppressWarnings(\"ALL\")\nabstract class MediaStoreUtil {\n    public static Uri getUriFromFile(final String path,Context context) {\n        ContentResolver resolver = context.getContentResolver();\n        Cursor filecursor = resolver.query(MediaStore.Files.getContentUri(\"external\"),\n                new String[] { BaseColumns._ID }, MediaStore.MediaColumns.DATA + \" = ?\",\n                new String[] { path }, MediaStore.MediaColumns.DATE_ADDED + \" desc\");\n        filecursor.moveToFirst();\n\n        if (filecursor.isAfterLast()) {\n            filecursor.close();\n            ContentValues values = new ContentValues();\n            values.put(MediaStore.MediaColumns.DATA, path);\n            return resolver.insert(MediaStore.Files.getContentUri(\"external\"), values);\n        }\n        else {\n            int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID));\n            Uri uri = MediaStore.Files.getContentUri(\"external\").buildUpon().appendPath(\n                    Integer.toString(imageId)).build();\n            filecursor.close();\n            return uri;\n        }\n    }\n\n    public static void addFileToMediaStore(final String path, Context context) {\n        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);\n        File file = new File(path);\n        Uri contentUri = Uri.fromFile(file);\n        mediaScanIntent.setData(contentUri);\n        context.sendBroadcast(mediaScanIntent);\n    }\n\n}\n\n/* This is a fake invisible editor view that receives the input and defines the\n * pan&scan region\n */\nclass DummyEdit extends View implements View.OnKeyListener {\n    InputConnection ic;\n\n    public DummyEdit(Context context) {\n        super(context);\n        setFocusableInTouchMode(true);\n        setFocusable(true);\n        setOnKeyListener(this);\n    }\n\n    @Override\n    public boolean onCheckIsTextEditor() {\n        return true;\n    }\n\n    @Override\n    public boolean onKey(View v, int keyCode, KeyEvent event) {\n\n        // This handles the hardware keyboard input\n        if (event.isPrintingKey()) {\n            if (event.getAction() == KeyEvent.ACTION_DOWN) {\n                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);\n            }\n            return true;\n        }\n        return false;\n    }\n        \n    //\n    @Override\n    public boolean onKeyPreIme (int keyCode, KeyEvent event) {\n        // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event\n        // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639\n        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not\n        // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear\n        // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android\n        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)\n        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {\n            if (KR2Activity.mTextEdit != null && KR2Activity.mTextEdit.getVisibility() == View.VISIBLE) {\n            \tKR2Activity.hideTextInput();\n            \t//KR2Activity.nativeKeyboardFocusLost();\n            }\n        }\n        return super.onKeyPreIme(keyCode, event);\n    }\n\n    @Override\n    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {\n        ic = new SDLInputConnection(this, true);\n\n        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI\n                | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;\n\n        return ic;\n    }\n}\n\nclass SDLInputConnection extends BaseInputConnection {\n\n    public SDLInputConnection(View targetView, boolean fullEditor) {\n        super(targetView, fullEditor);\n\n    }\n\n    @Override\n    public boolean sendKeyEvent(KeyEvent event) {\n        /*\n         * This handles the keycodes from soft keyboard (and IME-translated\n         * input from hardkeyboard)\n         */\n        int keyCode = event.getKeyCode();\n        if (event.getAction() == KeyEvent.ACTION_DOWN) {\n            if (event.isPrintingKey()) {\n                commitText(String.valueOf((char) event.getUnicodeChar()), 1);\n                KR2Activity.nativeCharInput(keyCode);\n            } else if(keyCode == KeyEvent.KEYCODE_DEL) {\n            \tKR2Activity.nativeKeyAction(keyCode, true);\n            }\n            return true;\n        } else if (event.getAction() == KeyEvent.ACTION_UP) {\n        \tif(keyCode == KeyEvent.KEYCODE_DEL) {\n            \tKR2Activity.nativeKeyAction(keyCode, false);\n            }\n        \t//KR2Activity.nativeKeyAction(keyCode, false);\n            return true;\n        }\n        return super.sendKeyEvent(event);\n    }\n\n    @Override\n    public boolean commitText(CharSequence text, int newCursorPosition) {\n\n    \tKR2Activity.nativeCommitText(text.toString(), newCursorPosition);\n\n        return super.commitText(text, newCursorPosition);\n    }\n\n    @Override\n    public boolean setComposingText(CharSequence text, int newCursorPosition) {\n\n        //nativeSetComposingText(text.toString(), newCursorPosition);\n\n        return super.setComposingText(text, newCursorPosition);\n    }\n\n    //public native void nativeSetComposingText(String text, int newCursorPosition);\n\n    @Override\n    public boolean deleteSurroundingText(int beforeLength, int afterLength) {       \n        // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection\n        if (beforeLength == 1 && afterLength == 0) {\n            // backspace\n            return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))\n                && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));\n        }\n\n        return super.deleteSurroundingText(beforeLength, afterLength);\n    }\n}\n\n@SuppressWarnings(\"ALL\")\npublic class KR2Activity extends Cocos2dxActivity implements ActivityCompat.OnRequestPermissionsResultCallback {\n\n    public static final int RC_WRITE_EXTERNAL = 1;\n    public static final int RC_PHONE_STATE = 2;\n\n\tstatic ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();\n\tstatic ActivityManager mAcitivityManager = null;\n\tstatic Debug.MemoryInfo mDbgMemoryInfo = new Debug.MemoryInfo();\n\tpublic static void updateMemoryInfo() {\n\t\tif(mAcitivityManager == null) {\n\t\t\tmAcitivityManager =(ActivityManager)sInstance.getSystemService(Activity.ACTIVITY_SERVICE);\n\t\t}\n\t\tmAcitivityManager.getMemoryInfo(memoryInfo);\n\t\tDebug.getMemoryInfo(mDbgMemoryInfo);\n\t}\n\t\n\tpublic static long getAvailMemory() {\n\t\treturn memoryInfo.availMem;\n\t}\n\n\tpublic static long getUsedMemory() {\n\t\treturn mDbgMemoryInfo.getTotalPss(); // in kB\n\t}\n\n    private static void requestPhoneState() {\n        // Permission has not been granted and must be requested.\n        if (ActivityCompat.shouldShowRequestPermissionRationale(sInstance,\n                Manifest.permission.READ_PHONE_STATE)) {\n            // Provide an additional rationale to the user if the permission was not granted\n            // and the user would benefit from additional context for the use of the permission.\n            // Display a SnackBar with cda button to request the missing permission.\n            ActivityCompat.requestPermissions(sInstance,\n                    new String[]{Manifest.permission.READ_PHONE_STATE},\n                    RC_PHONE_STATE);\n\n        } else {\n            // Request the permission. The result will be received in onRequestPermissionResult().\n            ActivityCompat.requestPermissions(sInstance,\n                    new String[]{Manifest.permission.READ_PHONE_STATE}, RC_PHONE_STATE);\n        }\n    }\n\n    private static void requestExternalWrite() {\n        // Permission has not been granted and must be requested.\n        if (ActivityCompat.shouldShowRequestPermissionRationale(sInstance,\n                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {\n            // Provide an additional rationale to the user if the permission was not granted\n            // and the user would benefit from additional context for the use of the permission.\n            // Display a SnackBar with cda button to request the missing permission.\n            ActivityCompat.requestPermissions(sInstance,\n                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},\n                    RC_WRITE_EXTERNAL);\n\n        } else {\n            // Request the permission. The result will be received in onRequestPermissionResult().\n            ActivityCompat.requestPermissions(sInstance,\n                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_WRITE_EXTERNAL);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults);\n        switch (requestCode) {\n            case RC_PHONE_STATE:\n                Log.d(\"Krkr2\", \"onRequestPermissionsResult: PHONE STATE\");\n                break;\n            case RC_WRITE_EXTERNAL:\n                Log.d(\"Krkr2\", \"onRequestPermissionsResult: WRITE EXTERNAL\");\n                break;\n        }\n    }\n\n\n    static public String getDeviceId() { // ## fix android.permission.READ_PRIVILEGED_PHONE_STATE\n\t\treturn \"\";\n\t}\n\n\tstatic public KR2Activity sInstance;\n\tstatic public KR2Activity GetInstance() {return sInstance;}\n    \n\t@Override\n\tpublic void onCreate(Bundle savedInstanceState) {\n\t\tsInstance = this;\n        Sp = PreferenceManager.getDefaultSharedPreferences(this);\n\t\tsuper.onCreate(savedInstanceState);\n\t\n\t\tif (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {\n\t\t\tfor(String path : getExtSdCardPaths(this)) {\n\t\t        if (!isWritableNormalOrSaf(path)) {\n\t\t            guideDialogForLEXA(path);\n\t\t        }\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            requestExternalWrite();\n        }\n\t\tinitDump(this.getFilesDir().getAbsolutePath() + \"/dump\");\n\t}\n\t\n\t@Override\n\tpublic void onDestroy() {\n\t\tsuper.onDestroy();\n\t\tSystem.exit(0);\n\t}\n\t\n\t@Override\n\tpublic void onLowMemory() {\n\t\tnativeOnLowMemory();\n\t}\n\t\n\tstatic class DialogMessage\n\t{\n\t\tpublic String Title;\n\t\tpublic String Text;\n\t\tpublic String[] Buttons;\n\t\tpublic EditText TextEditor = null;\n\n\t\tpublic DialogMessage()\n\t\t{\n\t\t}\n\t\t\n\t\tpublic void Init(final String title, final String text, final String[] buttons)\n\t\t{\n\t\t\tthis.Title = title;\n\t\t\tthis.Text = text;\n\t\t\tthis.Buttons = buttons;\n\t\t}\n\t\t\n\t\tvoid onButtonClick(int n) {\n\t\t\tif(TextEditor != null) {\n\t\t\t\tonMessageBoxText(TextEditor.getText().toString());\n\t\t\t}\n        \tonMessageBoxOK(n);\n\t\t}\n\t\t\n\t\tpublic AlertDialog.Builder CreateBuilder() {\n\t\t/*\tTextView showText = new TextView(sInstance);\n\t\t\tshowText.setText(Text);\n\t\t\tif (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)\n\t\t\t\tshowText.setTextIsSelectable(true);*/\n\t\t\tAlertDialog.Builder builder = new AlertDialog.Builder(sInstance).\n                setTitle(Title).\n                setMessage(Text).\n                //setView(showText).\n\t\t\t\tsetCancelable(false);\n\t\t\tif(Buttons.length >= 1) {\n                builder = builder.setPositiveButton(Buttons[0], new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                    \tonButtonClick(0);\n                    }\n                });\n\t\t\t}\n\t\t\tif(Buttons.length >= 2) {\n                builder = builder.setNeutralButton(Buttons[1], new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                    \tonButtonClick(1);\n                    }\n                });\n    \t\t}\n\t\t\tif(Buttons.length >= 3) {\n                builder = builder.setNegativeButton(Buttons[2], new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                    \tonButtonClick(2);\n                    }\n                });\n    \t\t}\n\t\t\treturn builder;\n\t\t}\n\t\t\n\t\tpublic void ShowMessageBox()\n\t\t{\n\t\t\tCreateBuilder().create().show();\n\t\t}\n\t\t\n\t\tpublic void ShowInputBox(final String text) {\n\t\t\tAlertDialog.Builder builder = CreateBuilder();\n\t\t\tTextEditor = new EditText(sInstance);  \n\t\t\tLinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(\n\t\t\t                     LinearLayout.LayoutParams.MATCH_PARENT,\n\t\t\t                     LinearLayout.LayoutParams.MATCH_PARENT);\n\t\t\tTextEditor.setLayoutParams(lp);\n\t\t\tTextEditor.setText(text);\n\t\t\tbuilder.setView(TextEditor);\n\t\t\tAlertDialog ad = builder.create(); \n\t\t\tad.show();\n\t\t\tTextEditor.requestFocus();\n            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);\n            imm.showSoftInput(TextEditor, 0);\n\t\t}\n\t}\n\tstatic DialogMessage mDialogMessage = new DialogMessage();\n\n    protected static View mTextEdit = null;\n    SharedPreferences Sp;\n\t\n\tstatic Handler msgHandler = new Handler() {\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tsInstance.handleMessage(msg);\n\t\t}\n\t};\n\t\n\tpublic void handleMessage(Message msg) {\n\t\t\n\t}\n\t\n\tstatic public void ShowMessageBox(final String title, final String text, final String[] Buttons) {\n\t\tmDialogMessage.Init(title, text, Buttons);\n\t\tmsgHandler.post(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tmDialogMessage.ShowMessageBox();\n\t\t\t}\n\t\t});\n\t}\n\t\n\tstatic public void ShowInputBox(final String title, final String prompt, final String text, final String[] Buttons) {\n\t\tmDialogMessage.Init(title, prompt, Buttons);\n\t\tmsgHandler.post(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tmDialogMessage.ShowInputBox(text);\n\t\t\t}\n\t\t});\n\t}\n\t\n    static class ShowTextInputTask implements Runnable {\n        /*\n         * This is used to regulate the pan&scan method to have some offset from\n         * the bottom edge of the input region and the top edge of an input\n         * method (soft keyboard)\n         */\n        static final int HEIGHT_PADDING = 15;\n\n        public int x, y, w, h;\n\n        public ShowTextInputTask(int x, int y, int w, int h) {\n            this.x = x;\n            this.y = y;\n            this.w = w;\n            this.h = h;\n        }\n\n\t\t@Override\n        public void run() {\n\t\t\tFrameLayout.LayoutParams params = new FrameLayout.LayoutParams(w, h + HEIGHT_PADDING);\n\t\t\tparams.leftMargin = x;\n\t\t\tparams.topMargin = y;\n\n            if (mTextEdit == null) {\n                mTextEdit = new DummyEdit(getContext());\n\n                sInstance.mFrameLayout.addView(mTextEdit, params);\n            } else {\n                mTextEdit.setLayoutParams(params);\n            }\n\n            mTextEdit.setVisibility(View.VISIBLE);\n            mTextEdit.requestFocus();\n\n            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);\n            imm.showSoftInput(mTextEdit, 0);\n        }\n    }\n    \n\tstatic public void showTextInput(int x, int y, int w, int h) {\n\t\tmsgHandler.post(new ShowTextInputTask(x, y, w, h));\n\t}\n\tstatic public void hideTextInput() {\n\t\tmsgHandler.post(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t        if (mTextEdit != null) {\n\t\t            mTextEdit.setVisibility(View.GONE);\n\t\t            InputMethodManager imm = (InputMethodManager) sInstance.getSystemService(Context.INPUT_METHOD_SERVICE);\n\t\t            imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);\n\t\t        }\n\t\t\t}\n\t\t});\n\t}\n\t\n\tstatic private native void onMessageBoxOK(int nButton);\n\tstatic private native void onMessageBoxText(String text);\n\tstatic private native void onNativeExit();\n\tstatic public native void onNativeInit();\n\tstatic public native void onBannerSizeChanged(int w, int h);\n\tstatic private native void initDump(String path);\n\tstatic private native void nativeOnLowMemory();\n\t\n\tstatic public void MessageController(int what, int arg1, int arg2) {\n        Message msg = msgHandler.obtainMessage();\n        msg.what = what;\n        msg.arg1 = arg1;\n        msg.arg2 = arg2;\n\t\tmsgHandler.sendMessage(msg);\n\t}\n\t\n\tstatic public String GetVersion() {\n\t\tString verstr = null;\n\t\ttry {\n\t\t\tverstr = sInstance.getPackageManager().getPackageInfo(sInstance.getPackageName(), 0).versionName;\n\t\t} catch (NameNotFoundException e1) {\n\t\t}\n\t\treturn verstr;\n\t}\n\t\n\tStorageManager mStorageManager = null;\n    Method mMethodGetPaths = null;\n    Method mGetVolumeState = null;\n    \n    public String[] getStoragePath() {\n    \tString[] ret = new String[0];\n    \tif(mStorageManager == null) {\n        \tmStorageManager = (StorageManager)getSystemService(STORAGE_SERVICE);\n            try {\n                mMethodGetPaths = StorageManager.class.getMethod(\"getVolumePaths\");\n                mGetVolumeState = StorageManager.class.getMethod(\"getVolumeState\", String.class);\n            } catch (NoSuchMethodException e) {\n                e.printStackTrace();\n            }\n    \t}\n    \tif(mMethodGetPaths != null) {\n            try {\n            \tret = (String[])mMethodGetPaths.invoke(mStorageManager);\n            } catch (IllegalArgumentException e) {\n     \n            } catch (IllegalAccessException e) {\n     \n            } catch (InvocationTargetException e) {\n     \n            } catch (Exception e) {\n     \n            }\n    \t}\n        \n        if(mGetVolumeState != null) {\n            try {\n            \tfor(int i = 0; i < ret.length; ++i) {\n            \t\tString status = (String)mGetVolumeState.invoke(mStorageManager, ret[i]);\n            \t\tif(Environment.MEDIA_MOUNTED.equals(status) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)) {\n            \t\t\t;\n            \t\t} else {\n            \t\t\tret[i] = null;\n            \t\t}\n            \t}\n            } catch (IllegalArgumentException e) {\n     \n            } catch (IllegalAccessException e) {\n     \n            } catch (InvocationTargetException e) {\n     \n            } catch (Exception e) {\n     \n            }\n        }\n        \n\t\treturn ret;\n    }\n    \n    private static native void nativeTouchesBegin(final int id, final float x, final float y);\n    private static native void nativeTouchesEnd(final int id, final float x, final float y);\n    private static native void nativeTouchesMove(final int[] ids, final float[] xs, final float[] ys);\n    private static native void nativeTouchesCancel(final int[] ids, final float[] xs, final float[] ys);\n    public static native boolean nativeKeyAction(final int keyCode, final boolean isPress);\n    public static native void nativeCharInput(final int keyCode);\n    public static native void nativeCommitText(String text, int newCursorPosition);\n    \n    private static native void nativeInsertText(final String text);\n    public static native void nativeDeleteBackward();\n    private static native String nativeGetContentText();\n    private static native void nativeHoverMoved(final float x, final float y);\n    private static native void nativeMouseScrolled(final float scroll);\n    \n    class KR2GLSurfaceView extends Cocos2dxGLSurfaceView {\n\n        public KR2GLSurfaceView(final Context context) {\n            super(context);\n        }\n\n        public KR2GLSurfaceView(final Context context, final AttributeSet attrs) {\n            super(context, attrs);\n        }\n        \n        @Override\n        public void insertText(final String pText) {\n        \tnativeInsertText(pText);\n        }\n\n        @Override\n        public void deleteBackward() {\n        \tnativeDeleteBackward();\n        }\n\n        @Override\n        public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {\n            switch (pKeyCode) {\n                case KeyEvent.KEYCODE_BACK:\n                case KeyEvent.KEYCODE_MENU:\n                case KeyEvent.KEYCODE_DPAD_LEFT:\n                case KeyEvent.KEYCODE_DPAD_RIGHT:\n                case KeyEvent.KEYCODE_DPAD_UP:\n                case KeyEvent.KEYCODE_DPAD_DOWN:\n                case KeyEvent.KEYCODE_ENTER:\n                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:\n                case KeyEvent.KEYCODE_DPAD_CENTER:\n                \tnativeKeyAction(pKeyCode, true);\n                    return true;\n                default:\n                    return super.onKeyDown(pKeyCode, pKeyEvent);\n            }\n        }\n\n        @Override\n        public boolean onKeyUp(final int pKeyCode, final KeyEvent pKeyEvent) {\n            switch (pKeyCode) {\n                case KeyEvent.KEYCODE_BACK:\n                case KeyEvent.KEYCODE_MENU:\n                case KeyEvent.KEYCODE_DPAD_LEFT:\n                case KeyEvent.KEYCODE_DPAD_RIGHT:\n                case KeyEvent.KEYCODE_DPAD_UP:\n                case KeyEvent.KEYCODE_DPAD_DOWN:\n                case KeyEvent.KEYCODE_ENTER:\n                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:\n                case KeyEvent.KEYCODE_DPAD_CENTER:\n                \tnativeKeyAction(pKeyCode, false);\n                    return true;\n                default:\n                    return super.onKeyUp(pKeyCode, pKeyEvent);\n            }\n        }\n        \n        @Override\n        public boolean onHoverEvent(final MotionEvent pMotionEvent) {\n            final int pointerNumber = pMotionEvent.getPointerCount();\n            final float[] xs = new float[pointerNumber];\n            final float[] ys = new float[pointerNumber];\n            for (int i = 0; i < pointerNumber; i++) {\n                xs[i] = pMotionEvent.getX(i);\n                ys[i] = pMotionEvent.getY(i);\n            }\n            \n        \tswitch(pMotionEvent.getActionMasked()) {\n        \tcase MotionEvent.ACTION_HOVER_MOVE:\n        \t\tnativeHoverMoved(xs[0], ys[0]);\n        \t\tbreak;\n        \t}\n        \treturn true;\n        }\n        \n        @Override\n        public boolean onTouchEvent(final MotionEvent pMotionEvent) {\n        \t\n            // these data are used in ACTION_MOVE and ACTION_CANCEL\n            final int pointerNumber = pMotionEvent.getPointerCount();\n            final int[] ids = new int[pointerNumber];\n            final float[] xs = new float[pointerNumber];\n            final float[] ys = new float[pointerNumber];\n\n            for (int i = 0; i < pointerNumber; i++) {\n                ids[i] = pMotionEvent.getPointerId(i);\n                xs[i] = pMotionEvent.getX(i);\n                ys[i] = pMotionEvent.getY(i);\n            }\n\n            switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {\n                case MotionEvent.ACTION_POINTER_DOWN:\n                    final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;\n                    final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);\n                    final float xPointerDown = pMotionEvent.getX(indexPointerDown);\n                    final float yPointerDown = pMotionEvent.getY(indexPointerDown);\n                    nativeTouchesBegin(idPointerDown, xPointerDown, yPointerDown);\n                    break;\n\n                case MotionEvent.ACTION_DOWN:\n                    // there are only one finger on the screen\n                    final int idDown = pMotionEvent.getPointerId(0);\n                    final float xDown = xs[0];\n                    final float yDown = ys[0];\n                    nativeTouchesBegin(idDown, xDown, yDown);\n                    break;\n\n                case MotionEvent.ACTION_MOVE:\n                \tnativeTouchesMove(ids, xs, ys);\n                    break;\n\n                case MotionEvent.ACTION_POINTER_UP:\n                    final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;\n                    final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);\n                    final float xPointerUp = pMotionEvent.getX(indexPointUp);\n                    final float yPointerUp = pMotionEvent.getY(indexPointUp);\n                    nativeTouchesEnd(idPointerUp, xPointerUp, yPointerUp);\n                    break;\n\n                case MotionEvent.ACTION_UP:\n                    // there are only one finger on the screen\n                    final int idUp = pMotionEvent.getPointerId(0);\n                    final float xUp = xs[0];\n                    final float yUp = ys[0];\n                    nativeTouchesEnd(idUp, xUp, yUp);\n                    break;\n\n                case MotionEvent.ACTION_CANCEL:\n                \tnativeTouchesCancel(ids, xs, ys);\n                    break;\n            }\n\n            /*\n            if (BuildConfig.DEBUG) {\n                Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);\n            }\n            */\n            return true;\n        }\n        \n\t\t@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @Override  \n        public boolean onGenericMotionEvent(MotionEvent event) {\n        \tswitch (event.getActionMasked()) {\n\t        case MotionEvent.ACTION_SCROLL:\n\t        \tfloat v = event.getAxisValue(MotionEvent.AXIS_VSCROLL);\n\t        \tnativeMouseScrolled(-v);\n                return true;\n            default:\n            \tbreak;\n        \t}\n        \treturn super.onGenericMotionEvent(event);\n        }\n    }\n    \n    //@Override\n    // ## fix private function\n//    public Cocos2dxGLSurfaceView onCreateView() {\n//        Cocos2dxGLSurfaceView glSurfaceView = new KR2GLSurfaceView(this);\n//    \thideSystemUI();\n//\n//        // this line is need on some device if we specify an alpha bits\n//        if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);\n//\n//        Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs);\n//        glSurfaceView.setEGLConfigChooser(chooser);\n//\n//        return glSurfaceView;\n//    }\n    \n    public int get_res_sd_operate_step() { return -1; }\n\n    static void requireLEXA(final String path) {\n\t\tmsgHandler.post(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tguideDialogForLEXA(path);\n\t\t\t}\n\t\t});\n    }\n    static void guideDialogForLEXA(final String path) {\n    \tAlertDialog.Builder builder = new AlertDialog.Builder(sInstance);\n    \tImageView image = new ImageView(sInstance);\n    \timage.setImageResource(sInstance.get_res_sd_operate_step());\n    \tbuilder\n    \t\t.setView(image)\n    \t\t.setTitle(path)\n    \t\t.setPositiveButton(\"OK\", new DialogInterface.OnClickListener() {\n                @Override\n                public void onClick(DialogInterface dialog, int which) {\n                    triggerStorageAccessFramework();\n                }\n            })\n            .setNegativeButton(\"Cancel\", new DialogInterface.OnClickListener() {\n                @Override\n                public void onClick(DialogInterface dialog, int which) {\n                \t// nothing to do\n                }\n            })\n            .show();\n    }\n    \n    static final boolean isWritable(final File file) {\n        if(file==null)\n            return false;\n        boolean isExisting = file.exists();\n\n        try {\n            FileOutputStream output = new FileOutputStream(file, true);\n            try {\n                output.close();\n            }\n            catch (IOException e) {\n                // do nothing.\n            }\n        }\n        catch (FileNotFoundException e) {\n            return false;\n        }\n        boolean result = file.canWrite();\n\n        // Ensure that file is not created during this process.\n        if (!isExisting) {\n            file.delete();\n        }\n\n        return result;\n    }\n\n    static final boolean isWritableNormal(final String path) {\n        boolean ret = isWritableNormalOrSaf(path);\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            requestExternalWrite();\n            return isWritableNormalOrSaf(path);\n        }\n        return ret;\n    }\n\n\n    static final boolean isWritableNormalOrSaf(final String path) {\n\n        Log.i(\"kr2activaty\",\"check path \" + path + \"permision\");\n\n    \tContext c = sInstance;\n    \tFile folder = new File(path);\n    \tfolder.mkdir();\n    \t// Log.d(\"ke2activate\", String.format(\"%b  and  %b\", folder.exists(), folder.isDirectory()));\n        if (!folder.exists() || !folder.isDirectory()) {\n           return false;\n        }\n\n        // Find a non-existing file in this directory.\n        int i = 0;\n        File file;\n        do {\n            String fileName = \"AugendiagnoseDummyFile\" + (++i);\n            file = new File(folder, fileName);\n        }\n        while (file.exists());\n\n        // First check regular writability\n        Log.d(\"ke2activate\", String.format(\"%b  \", isWritable(file)));\n        if (isWritable(file)) {\n            return true;\n        }\n\n        // Next check SAF writability.\n        DocumentFile document = getDocumentFile(file, false,c);\n\n        if (document == null) {\n            return false;\n        }\n\n        // This should have created the file - otherwise something is wrong with access URL.\n        boolean result = document.canWrite() && file.exists();\n\n        // Ensure that the dummy file is not remaining.\n        document.delete();\n        DocumentFile.fromFile(folder).delete();\n\n        return result;\n    }\n    \n    @TargetApi(Build.VERSION_CODES.KITKAT)\n    private static String[] getExtSdCardPaths(Context context) {\n        List<String> paths = new ArrayList<String>();\n        for (File file : context.getExternalFilesDirs(\"external\")) {\n            if (file != null && !file.equals(context.getExternalFilesDir(\"external\"))) {\n                int index = file.getAbsolutePath().lastIndexOf(\"/Android/data\");\n                if (index < 0) {\n                    Log.w(\"FileUtils\", \"Unexpected external file dir: \" + file.getAbsolutePath());\n                } else {\n                    String path = file.getAbsolutePath().substring(0, index);\n                    try {\n                        path = new File(path).getCanonicalPath();\n                    }\n                    catch (IOException e) {\n                        // Keep non-canonical path.\n                    }\n                    paths.add(path);\n                }\n            }\n        }\n        //if(paths.isEmpty())paths.add(\"/storage/sdcard1\");\n        return paths.toArray(new String[0]);\n    }\n    static String[] _extSdPaths;\n\n    public static String getExtSdCardFolder(final File file,Context context) {\n    \tif(_extSdPaths == null)\n    \t\t_extSdPaths = getExtSdCardPaths(context);\n        try {\n            for (int i = 0; i < _extSdPaths.length; i++) {\n                if (file.getCanonicalPath().startsWith(_extSdPaths[i])) {\n                    return _extSdPaths[i];\n                }\n            }\n        }\n        catch (IOException e) {\n            return null;\n        }\n        return null;\n    }\n    \n    public static boolean isOnExtSdCard(final File file,Context c) {\n        return getExtSdCardFolder(file,c) != null;\n    }\n    \n    public static DocumentFile getDocumentFile(final File file, final boolean isDirectory,Context context) {\n        String baseFolder = getExtSdCardFolder(file,context);\n        boolean originalDirectory=false;\n        if (baseFolder == null) {\n            return null;\n        }\n\n        String relativePath = null;\n        try {\n            String fullPath = file.getCanonicalPath();\n            if(!baseFolder.equals(fullPath))\n            relativePath = fullPath.substring(baseFolder.length() + 1);\n            else originalDirectory=true;\n        }\n        catch (IOException e) {\n            return null;\n        }\n        catch (Exception f){\n            originalDirectory=true;\n            //continue\n        }\n        String as=PreferenceManager.getDefaultSharedPreferences(context).getString(\"URI\",null);\n\n        Uri treeUri =null;\n        if(as!=null)treeUri=Uri.parse(as);\n        if (treeUri == null) {\n            return null;\n        }\n\n        // start with root of SD card and then parse through document tree.\n        DocumentFile document = DocumentFile.fromTreeUri(context, treeUri);\n        if(originalDirectory)return document;\n        String[] parts = relativePath.split(\"\\\\/\");\n        for (int i = 0; i < parts.length; i++) {\n            DocumentFile nextDocument = document.findFile(parts[i]);\n            if (nextDocument == null) {\n            \ttry {\n\t                if ((i < parts.length - 1) || isDirectory) {\n\t                    nextDocument = document.createDirectory(parts[i]);\n\t                } else {\n\t                    nextDocument = document.createFile(\"image\", parts[i]);\n\t                }\n\t            } catch (Exception e) {\n\t            \treturn null;\n\t            }\n            }\n            document = nextDocument;\n        }\n\n        return document;\n    }\n    \n    static public boolean RenameFile(String from, String to) {\n    \tFile file = new File(from);\n    \tFile target = new File(to);\n    \tif(!file.exists())\n    \t\treturn false;\n    \tif(target.exists()) {\n    \t\tif(!DeleteFile(target.getAbsolutePath())) return false;\n    \t}\n    \t\n    \tFile parent = target.getParentFile();\n    \tif(!parent.exists()) {\n    \t\tif(!CreateFolders(parent.getAbsolutePath())) return false;\n    \t}\n    \t// Try the normal way\n        if(file.renameTo(target)) return true;\n        \n        // Try with Storage Access Framework.\n        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) {\n            DocumentFile document = getDocumentFile(file, false, sInstance);\n        \tif(document.renameTo(to))\n        \t\treturn true;\n        }\n        \n        // Try Media Store Hack\n        if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {\n        \ttry {\n\t\t\t\tFileInputStream input = new FileInputStream(file);\n\t        \tint filesize = (int) file.length();\n\t\t\t\tbyte []buffer = new byte[filesize];\n\t\t\t\tinput.read(buffer);\n\t\t\t\tinput.close();\n            \tOutputStream out = MediaStoreHack.getOutputStream(sInstance, target.getAbsolutePath());\n                out.write(buffer);\n                out.close();\n                return MediaStoreHack.delete(sInstance, file);\n\t\t\t} catch (IOException e) {\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\treturn false;\n\t\t\t\t//e.printStackTrace();\n\t\t\t}\n        }\n        \n    \treturn false;\n    }\n    \n    public static final boolean deleteFilesInFolder(final File folder,Context context) {\n        boolean totalSuccess = true;\n        if(folder==null)\n            return false;\n        if (folder.isDirectory()) {\n            for (File child : folder.listFiles()) {\n                deleteFilesInFolder(child, context);\n            }\n\n            if (!folder.delete())\n                totalSuccess = false;\n        } else {\n\n            if (!folder.delete())\n                totalSuccess = false;\n        }\n        return totalSuccess;\n    }\n\n    static public boolean DeleteFile(String path) {\n    \tFile file = new File(path);\n    \t// First try the normal deletion.\n        boolean fileDelete = deleteFilesInFolder(file, sInstance);\n        if (file.delete() || fileDelete)\n            return true;\n\n        // Try with Storage Access Framework.\n        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP && isOnExtSdCard(file, sInstance)) {\n\n            DocumentFile document = getDocumentFile(file, false,sInstance);\n            return document.delete();\n        }\n\n        // Try the Kitkat workaround.\n        if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {\n            ContentResolver resolver = sInstance.getContentResolver();\n\n            try {\n                Uri uri = MediaStoreHack.getUriFromFile(file.getAbsolutePath(),sInstance);\n                resolver.delete(uri, null, null);\n                return !file.exists();\n            }\n            catch (Exception e) {\n                Log.e(\"FileUtils\", \"Error when deleting file \" + file.getAbsolutePath(), e);\n                return false;\n            }\n        }\n\n        return !file.exists();\n    }\n    \n\tpublic static OutputStream getOutputStream(@NonNull final File target,Context context,long s)throws Exception {\n\t    OutputStream outStream = null;\n\t    try {\n\t        // First try the normal way\n\t\t\tif (isWritable(target)) {\n\t\t\t    // standard way\n\t\t\t    outStream = new FileOutputStream(target);\n\t\t\t} else {\n\t\t\t    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {\n\t\t\t        // Storage Access Framework\n\t\t\t    DocumentFile targetDocument = getDocumentFile(target, false,context);\n\t\t\t    outStream = context.getContentResolver().openOutputStream(targetDocument.getUri());\n\t\t\t} else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {\n\t\t\t    // Workaround for Kitkat ext SD card\n\t\t        return MediaStoreHack.getOutputStream(context,target.getPath());\n\t\t        }\n\t\t    }\n\t\t} catch (Exception e) {\n\t\t    Log.e(\"FileUtils\",\n    \t\t\t\"Error when copying file from \" +  target.getAbsolutePath(), e);\n\t    }\n\t  return outStream;\n    }\n\n    \n    static public boolean WriteFile(String path, byte data[]) {\n        File target = new File(path);\n        if(target.exists()) {\n        \tDeleteFile(target.getAbsolutePath()); // to avoid number suffix name\n        } else {\n            File parent = target.getParentFile();\n            if(!parent.exists())\n            \tCreateFolders(parent.getAbsolutePath());\n        }\n        OutputStream out = null;\n        \n    \t// Try the normal way\n    \ttry {\n        \tif(isWritable(target)) {\n        \t\tOutputStream os = new FileOutputStream(target);\n    \t\t\tos.write(data);\n    \t\t\tos.close();\n    \t\t\treturn true;\n        \t}\n\n            // Try with Storage Access Framework.\n            if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) {\n                DocumentFile document = getDocumentFile(target, false, sInstance);\n                try {\n                \tUri docUri = document.getUri();\n                    out = sInstance.getContentResolver().openOutputStream(docUri);\n                } //catch (FileNotFoundException e) {\n                    // e.printStackTrace();}\n                catch (IOException e) {\n                    // e.printStackTrace();\n                }\n            } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {\n                // Workaround for Kitkat ext SD card\n                Uri uri = MediaStoreHack.getUriFromFile(target.getAbsolutePath(),sInstance);\n                out = sInstance.getContentResolver().openOutputStream(uri);\n            } else {\n                return false;\n            }\n            \n            if (out != null) {\n                out.write(data);\n                out.close();\n                return true;\n            }\n\t\t} catch (FileNotFoundException e) {\n\t\t\t//return false;\n\t\t} catch (IOException e) {\n\t\t\t//return false;\n\t\t}\n\n    \treturn false;\n    }\n    \n    static public boolean CreateFolders(String path) {\n    \tFile file = new File(path);\n    \t\n        // Try the normal way\n    \tif(file.mkdirs()) {\n    \t\treturn true;\n    \t}\n\n        // Try with Storage Access Framework.\n        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& FileUtil.isOnExtSdCard(file, context)*/) {\n            DocumentFile document = getDocumentFile(file, true,sInstance);\n            // getDocumentFile implicitly creates the directory.\n\n            return document.exists();\n        }\n        \n        // Try the Kitkat workaround.\n        if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {\n            try {\n            \treturn MediaStoreHack.mkdir(sInstance,file);\n            } catch (IOException e) {\n                //return false;\n            }\n        }\n        \n    \treturn false;\n    }\n\n    @Override\n    public void onWindowFocusChanged(boolean hasFocus) {\n        super.onWindowFocusChanged(hasFocus);\n\n        //SDLActivity.mHasFocus = hasFocus;\n        if (hasFocus) {\n        \thideSystemUI();\n        }\n    }\n    \n    @TargetApi(Build.VERSION_CODES.HONEYCOMB)\n    void doSetSystemUiVisibility() {\n\t\tint uiOpts = View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n\t\t        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n\t\t        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n\t\t        | View.SYSTEM_UI_FLAG_FULLSCREEN\n\t\t        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION\n\t\t        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;\n\t\tgetWindow().getDecorView().setSystemUiVisibility(uiOpts);\n    }\n\n    private static native boolean nativeGetHideSystemButton();\n    void hideSystemUI() {\n    \tif(nativeGetHideSystemButton() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {\n    \t\tdoSetSystemUiVisibility();\n    \t}\n    }\n    \n    static public String getLocaleName() {\n    \tLocale defloc = Locale.getDefault();\n    \tString lang = defloc.getLanguage();\n    \tString country = defloc.getCountry();\n    \tif(!country.isEmpty()) {\n    \t\tlang += \"_\";\n    \t\tlang += country.toLowerCase();\n    \t}\n    \treturn lang;\n    }\n    \n    static public void exit() {\n    \tSystem.exit(0);\n    }\n    \n    static final int ORIENT_VERTICAL = 1;\n    static final int ORIENT_HORIZONTAL = 2;\n    \n    static public void setOrientation(int orient) {\n    \tif(orient == ORIENT_VERTICAL) {\n    \t\tsInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);\n    \t} else if(orient == ORIENT_HORIZONTAL) {\n    \t\tsInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);\n    \t}\n    }\n    \n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n\tstatic public void triggerStorageAccessFramework() {\n        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);\n        sInstance.startActivityForResult(intent, 3);\n    }\n\n    @SuppressLint(\"WrongConstant\")\n    @TargetApi(Build.VERSION_CODES.KITKAT)\n    protected void onActivityResult(int requestCode, int responseCode, Intent intent) {\n        if (requestCode == 3) {\n            String p = Sp.getString(\"URI\", null);\n            Uri oldUri = null;\n            if (p != null) oldUri = Uri.parse(p);\n            Uri treeUri = null;\n            if (responseCode == Activity.RESULT_OK) {\n                // Get Uri from Storage Access Framework.\n                treeUri = intent.getData();\n                // Persist URI - this is required for verification of writability.\n                if (treeUri != null) Sp.edit().putString(\"URI\", treeUri.toString()).commit();\n            }\n\n            // If not confirmed SAF, or if still not writable, then revert settings.\n            if (responseCode != Activity.RESULT_OK) {\n               /* DialogUtil.displayError(getActivity(), R.string.message_dialog_cannot_write_to_folder_saf, false,\n                        currentFolder);||!FileUtil.isWritableNormalOrSaf(currentFolder)\n*/\n                if (treeUri != null) Sp.edit().putString(\"URI\", oldUri.toString()).commit();\n                return;\n            }\n\n            // After confirmation, update stored value of folder.\n            // Persist access permissions.\n            final int takeFlags = intent.getFlags()\n                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION\n                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);\n            getContentResolver().takePersistableUriPermission(treeUri, takeFlags);\n        }\n    }\n\n}\n"
  },
  {
    "path": "project/android/app/java/org/tvp/kirikiri2/MediaStoreHack.java",
    "content": "package org.tvp.kirikiri2;\n\n/**\n * Created by Arpit on 29-06-2015.\n */\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Locale;\n\nimport android.annotation.SuppressLint;\nimport android.content.ContentResolver;\nimport android.content.ContentValues;\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.net.Uri;\nimport android.os.ParcelFileDescriptor;\nimport android.provider.BaseColumns;\nimport android.provider.MediaStore;\nimport android.util.Log;\n\n/**\n * Wrapper for manipulating files via the Android Media Content Provider. As of Android 4.4 KitKat,\n * applications can no longer write to the \"secondary storage\" of a device. Write operations using\n * the java.io.File API will thus fail. This class restores access to those write operations by way\n * of the Media Content Provider.</p>\n *\n * Note that this class relies on the internal operational characteristics of the media content\n * provider API, and as such is not guaranteed to be future-proof. Then again, we did all think the\n * java.io.File API was going to be future-proof for media card access, so all bets are off.</p>\n *\n * If you're forced to use this class, it's because Google/AOSP made a very poor API decision in\n * Android 4.4 KitKat. Read more at https://plus.google.com/+TodLiebeck/posts/gjnmuaDM8sn</p>\n *\n * Your application must declare the permission \"android.permission.WRITE_EXTERNAL_STORAGE\".</p>\n *\n * Adapted from: http://forum.xda-developers.com/showpost.php?p=52151865&postcount=20</p>\n *\n * @author Jared Rummler <jared.rummler@gmail.com>\n */\npublic class MediaStoreHack {\n\n    private static final String ALBUM_ART_URI = \"content://media/external/audio/albumart\";\n\n    private static final String[] ALBUM_PROJECTION = {\n            BaseColumns._ID, MediaStore.Audio.AlbumColumns.ALBUM_ID, \"media_type\"\n    };\n\n    /**\n     * Deletes the file. Returns true if the file has been successfully deleted or otherwise does\n     * not exist. This operation is not recursive.\n     */\n    public static boolean delete(final Context context, final File file) {\n        final String where = MediaStore.MediaColumns.DATA + \"=?\";\n        final String[] selectionArgs = new String[] {\n                file.getAbsolutePath()\n        };\n        final ContentResolver contentResolver = context.getContentResolver();\n        final Uri filesUri = MediaStore.Files.getContentUri(\"external\");\n        // Delete the entry from the media database. This will actually delete media files.\n        contentResolver.delete(filesUri, where, selectionArgs);\n        // If the file is not a media file, create a new entry.\n        if (file.exists()) {\n            final ContentValues values = new ContentValues();\n            values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());\n            contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);\n            // Delete the created entry, such that content provider will delete the file.\n            contentResolver.delete(filesUri, where, selectionArgs);\n        }\n        return !file.exists();\n    }\n\n    private static File getExternalFilesDir(final Context context) {\n        return context.getExternalFilesDir(null);\n    }\n\n    public static InputStream\n    getInputStream(final Context context, final File file, final long size) {\n        try {\n            final String where = MediaStore.MediaColumns.DATA + \"=?\";\n            final String[] selectionArgs = new String[] {\n                    file.getAbsolutePath()\n            };\n            final ContentResolver contentResolver = context.getContentResolver();\n            final Uri filesUri = MediaStore.Files.getContentUri(\"external\");\n            contentResolver.delete(filesUri, where, selectionArgs);\n            final ContentValues values = new ContentValues();\n            values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());\n            values.put(MediaStore.MediaColumns.SIZE, size);\n            final Uri uri = contentResolver.insert(filesUri, values);\n            return contentResolver.openInputStream(uri);\n        } catch (final Throwable t) {\n            return null;\n        }\n    }\n    public static OutputStream getOutputStream(Context context,String str) {\n        OutputStream outputStream = null;\n        Uri fileUri = getUriFromFile(str,context);\n        if (fileUri != null) {\n            try {\n                outputStream = context.getContentResolver().openOutputStream(fileUri);\n            } catch (Throwable th) {\n            }\n        }\n        return outputStream;\n    }\n    public static Uri getUriFromFile(final String path,Context context) {\n        ContentResolver resolver = context.getContentResolver();\n\n        Cursor filecursor = resolver.query(MediaStore.Files.getContentUri(\"external\"),\n                new String[] { BaseColumns._ID }, MediaStore.MediaColumns.DATA + \" = ?\",\n                new String[] { path }, MediaStore.MediaColumns.DATE_ADDED + \" desc\");\n        filecursor.moveToFirst();\n\n        if (filecursor.isAfterLast()) {\n            filecursor.close();\n            ContentValues values = new ContentValues();\n            values.put(MediaStore.MediaColumns.DATA, path);\n            return resolver.insert(MediaStore.Files.getContentUri(\"external\"), values);\n        }\n        else {\n            @SuppressLint(\"Range\") int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID));\n            Uri uri = MediaStore.Files.getContentUri(\"external\").buildUpon().appendPath(\n                    Integer.toString(imageId)).build();\n            filecursor.close();\n            return uri;\n        }\n    }\n\n    /**\n     * Returns an OutputStream to write to the file. The file will be truncated immediately.\n     */\n\n    private static int getTemporaryAlbumId(final Context context) {\n        final File temporaryTrack;\n        try {\n            temporaryTrack = installTemporaryTrack(context);\n        } catch (final IOException ex) {\n            Log.w(\"MediaFile\", \"Error installing tempory track.\", ex);\n            return 0;\n        }\n        final Uri filesUri = MediaStore.Files.getContentUri(\"external\");\n        final String[] selectionArgs = {\n                temporaryTrack.getAbsolutePath()\n        };\n        final ContentResolver contentResolver = context.getContentResolver();\n        Cursor cursor = contentResolver.query(filesUri, ALBUM_PROJECTION,\n                MediaStore.MediaColumns.DATA + \"=?\", selectionArgs, null);\n        if (cursor == null || !cursor.moveToFirst()) {\n            if (cursor != null) {\n                cursor.close();\n                cursor = null;\n            }\n            final ContentValues values = new ContentValues();\n            values.put(MediaStore.MediaColumns.DATA, temporaryTrack.getAbsolutePath());\n            values.put(MediaStore.MediaColumns.TITLE, \"{MediaWrite Workaround}\");\n            values.put(MediaStore.MediaColumns.SIZE, temporaryTrack.length());\n            values.put(MediaStore.MediaColumns.MIME_TYPE, \"audio/mpeg\");\n            values.put(MediaStore.Audio.AudioColumns.IS_MUSIC, true);\n            contentResolver.insert(filesUri, values);\n        }\n        cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA\n                + \"=?\", selectionArgs, null);\n        if (cursor == null) {\n            return 0;\n        }\n        if (!cursor.moveToFirst()) {\n            cursor.close();\n            return 0;\n        }\n        final int id = cursor.getInt(0);\n        final int albumId = cursor.getInt(1);\n        final int mediaType = cursor.getInt(2);\n        cursor.close();\n        final ContentValues values = new ContentValues();\n        boolean updateRequired = false;\n        if (albumId == 0) {\n            values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, 13371337);\n            updateRequired = true;\n        }\n        if (mediaType != 2) {\n            values.put(\"media_type\", 2);\n            updateRequired = true;\n        }\n        if (updateRequired) {\n            contentResolver.update(filesUri, values, BaseColumns._ID + \"=\" + id, null);\n        }\n        cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA\n                + \"=?\", selectionArgs, null);\n        if (cursor == null) {\n            return 0;\n        }\n        try {\n            if (!cursor.moveToFirst()) {\n                return 0;\n            }\n            return cursor.getInt(1);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    private static final byte [] temptrack_mp3 = new byte [] {\n    \t73, 68, 51, 4, 0, 0, 0, 0, 8, 65, 84, 80, 69, 49, 0, 0,\n    \t0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105, 116, 101,\n    \t32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 65, 76, 66,\n    \t0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105,\n    \t116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 73,\n    \t84, 50, 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87,\n    \t114, 105, 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125,\n    \t65, 80, 73, 67, 0, 0, 2, 33, 0, 0, 0, 105, 109, 97, 103, 101,\n    \t47, 112, 110, 103, 0, 3, 0, -119, 80, 78, 71, 13, 10, 26, 10, 0,\n    \t0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 32, 0, 0, 0, 32, 8,\n    \t2, 0, 0, 0, -4, 24, -19, -93, 0, 0, 0, 1, 115, 82, 71, 66,\n    \t0, -82, -50, 28, -23, 0, 0, 0, -50, 73, 68, 65, 84, 72, -57, -19,\n    \t85, -55, 10, -128, 64, 8, 77, -1, -1, -97, -19, 48, 36, -30, 62, 83,\n    \t-76, 64, 30, 66, -59, -52, 124, 79, -35, -74, 95, -34, 38, 68, 68, 68,\n    \t82, 81, -2, -95, -69, 78, 25, 31, 102, 87, -70, 124, 70, -2, 40, 114,\n    \t8, 74, 3, 0, -22, 42, 76, 77, 0, -112, 4, -96, -78, 59, -33, -112,\n    \t1, 101, 60, 90, 0, -72, 34, -42, 71, 22, 78, 20, -107, 92, -2, -51,\n    \t45, 20, -78, 96, 42, -14, -48, 33, 74, -17, 98, 96, 69, 117, -103, -101,\n    \t-58, -26, 28, -56, -106, 106, 121, 103, 75, 70, -96, 11, 84, -97, 39, 37,\n    \t-86, -24, -66, -48, 39, 67, 107, -128, -97, 100, 81, -78, 121, 58, 0, -44,\n    \t44, 82, -112, 44, -20, 18, -100, 34, -122, 59, -25, 57, 12, 53, -117, -94,\n    \t-103, 96, 61, 31, -123, -126, 69, 35, -53, -45, 27, 102, -115, 72, -10, -94,\n    \t37, -121, -56, 61, -126, -2, -70, 118, -69, -100, 0, -93, -100, 54, 12, -49,\n    \t92, -85, -23, -125, 51, 123, -83, 58, -21, 8, 59, -47, -110, 75, 57, -81,\n    \t-66, 70, -71, 95, 46, -111, 29, -73, 67, 31, -101, 122, -93, -81, 8, 0,\n    \t0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126, 84, 68, 84, 71, 0,\n    \t0, 0, 20, 0, 0, 0, 50, 48, 49, 52, 45, 48, 52, 45, 48, 49,\n    \t84, 50, 49, 58, 51, 57, 58, 51, 53, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -6, -112, -64, 95,\n    \t-85, 0, 0, 0, 0, 1, -92, 24, 0, 0, 0, 0, 0, 52, -125, -128,\n    \t0, 0, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64,\n    \t-26, -97, -59, 3, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128,\n    \t0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46,\n    \t57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6,\n    \t-110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0,\n    \t52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69,\n    \t51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t-1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0,\n    \t0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65,\n    \t77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0,\n    \t0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92,\n    \t0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,\n    \t85, 85, 85, 85, 85, 85\n    };\n    \n    private static File installTemporaryTrack(final Context context) throws IOException {\n        final File externalFilesDir = getExternalFilesDir(context);\n        if (externalFilesDir == null) {\n            return null;\n        }\n        final File temporaryTrack = new File(externalFilesDir, \"temptrack.mp3\");\n        OutputStream out = null;\n        try {\n            out = new FileOutputStream(temporaryTrack);\n            out.write(temptrack_mp3);\n        } finally {\n            out.close();\n        }\n        return temporaryTrack;\n    }\n\n    public static boolean mkdir(final Context context, final File file) throws IOException {\n        if (file.exists()) {\n            return file.isDirectory();\n        }\n        final File tmpFile = new File(file, \".MediaWriteTemp\");\n        final int albumId = getTemporaryAlbumId(context);\n        if (albumId == 0) {\n            throw new IOException(\"Failed to create temporary album id.\");\n        }\n        final Uri albumUri = Uri.parse(String.format(Locale.US, ALBUM_ART_URI + \"/%d\", albumId));\n        final ContentValues values = new ContentValues();\n        values.put(MediaStore.MediaColumns.DATA, tmpFile.getAbsolutePath());\n        final ContentResolver contentResolver = context.getContentResolver();\n        if (contentResolver.update(albumUri, values, null, null) == 0) {\n            values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, albumId);\n            contentResolver.insert(Uri.parse(ALBUM_ART_URI), values);\n        }\n        try {\n            final ParcelFileDescriptor fd = contentResolver.openFileDescriptor(albumUri, \"r\");\n            fd.close();\n        } finally {\n            delete(context, tmpFile);\n        }\n        return file.exists();\n    }\n\n    public static boolean mkfile(final Context context, final File file) {\n        final OutputStream outputStream = getOutputStream(context, file.getPath());\n        if (outputStream == null) {\n            return false;\n        }\n        try {\n            outputStream.close();\n            return true;\n        } catch (final IOException e) {\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "project/android/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in E:\\developSoftware\\Android\\SDK/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Proguard Cocos2d-x for release\n-keep public class org.cocos2dx.** { *; }\n-dontwarn org.cocos2dx.**\n-keep public class com.chukong.** { *; }\n-dontwarn com.chukong.**\n-keep public class com.huawei.android.** { *; }\n-dontwarn com.huawei.android.**\n-keep public class com.oppo.oiface.engine.** { *; }\n-dontwarn com.oppo.oiface.engine.**\n\n# Proguard Apache HTTP for release\n-keep class org.apache.http.** { *; }\n-dontwarn org.apache.http.**\n\n# Proguard Android Webivew for release. uncomment if you are using a webview in cocos2d-x\n#-keep public class android.net.http.SslError\n#-keep public class android.webkit.WebViewClient\n\n#-dontwarn android.webkit.WebView\n#-dontwarn android.net.http.SslError\n#-dontwarn android.webkit.WebViewClient"
  },
  {
    "path": "project/android/app/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Kirikiroid2-Yuri</string>\n</resources>\n"
  },
  {
    "path": "project/android/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n    id 'com.android.application' version '7.4.2' apply false\n    id 'com.android.library' version '7.4.2' apply false\n}\n\nallprojects {\n    buildDir = \"./../../../build_android\"\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}"
  },
  {
    "path": "project/android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sat Mar 11 01:47:25 JST 2023\r\ndistributionBase=GRADLE_USER_HOME\r\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-7.5-bin.zip\r\ndistributionPath=wrapper/dists\r\nzipStorePath=wrapper/dists\r\nzipStoreBase=GRADLE_USER_HOME\r\n"
  },
  {
    "path": "project/android/gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\n# Android SDK version that will be used as the compile project\nPROP_COMPILE_SDK_VERSION=29\n \n# Android SDK version that will be used as the earliest version of android this application can run on\nPROP_MIN_SDK_VERSION=22\n\n# Android SDK version that will be used as the latest version of android this application has been tested on\nPROP_TARGET_SDK_VERSION=29\n\n\n# List of CPU Archtexture to build that application with\n# Available architextures (armeabi-v7a | arm64-v8a | x86)\n# To build for multiple architexture, use the `:` between them\n# Example - PROP_APP_ABI=armeabi-v7a:arm64-v8a:x86\nPROP_APP_ABI=arm64-v8a\n\n# android native code build type\n# none, native code will never be compiled.\n# cmake, native code will be compiled by CMakeLists.txt\n# ndk-build, native code will be compiled by Android.mk\nPROP_BUILD_TYPE=cmake\n\n# uncomment it and fill in sign information for release mode\n#RELEASE_STORE_FILE=file path of keystore\n#RELEASE_STORE_PASSWORD=password of keystore\n#RELEASE_KEY_ALIAS=alias of key\n#RELEASE_KEY_PASSWORD=password of key\nandroid.useAndroidX=True"
  },
  {
    "path": "project/android/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "project/android/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "project/android/settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\ninclude ':cocos2dx'\nproject(':cocos2dx').projectDir = new File(settingsDir, '../../thirdparty/port/cocos2d-x/cocos/platform/android/libcocos2dx')\ninclude ':krkr2yuri'\nproject(':krkr2yuri').projectDir = new File(settingsDir, 'app')\n"
  },
  {
    "path": "project/ui/.cocos-project.json",
    "content": "{\n    \"engine_type\": \"prebuilt\", \n    \"engine_version\": \"cocos2d-x-3.6\", \n    \"project_type\": \"cpp\"\n}"
  },
  {
    "path": "project/ui/Resources/res/locale/en_us.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Locale lang=\"en_us\">\n    <Item id=\"preference_title\" text=\"Global Preference\"/>\n    <Item id=\"preference_title_individual\" text=\"Individual Preference\"/>\n    <Item id=\"preference_output_log\" text=\"Output Log\"/>\n    <Item id=\"preference_select_renderer\" text=\"Select Renderer\"/>\n    <Item id=\"preference_opengl\" text=\"OpenGL(Experimental)\"/>\n    <Item id=\"preference_software\" text=\"Software\"/>\n    <Item id=\"preference_renderer_opt\" text=\"Advanced Renderer Option\"/>\n    <Item id=\"preference_soft_renderer_opt\" text=\"Soft Renderer Option\"/>\n    <Item id=\"preference_opengl_renderer_opt\" text=\"OpenGL Renderer Option\"/>\n    <Item id=\"preference_multi_draw_thread\" text=\"Draw Thread\"/>\n    <Item id=\"preference_draw_thread_auto\" text=\"Auto\"/>\n    <Item id=\"preference_draw_thread_1\" text=\"1\"/>\n    <Item id=\"preference_draw_thread_2\" text=\"2\"/>\n    <Item id=\"preference_draw_thread_3\" text=\"3\"/>\n    <Item id=\"preference_draw_thread_4\" text=\"4\"/>\n    <Item id=\"preference_draw_thread_5\" text=\"5\"/>\n    <Item id=\"preference_draw_thread_6\" text=\"6\"/>\n    <Item id=\"preference_draw_thread_7\" text=\"7\"/>\n    <Item id=\"preference_draw_thread_8\" text=\"8\"/>\n    <Item id=\"preference_software_compress_tex\" text=\"Texture Compression\"/>\n    <Item id=\"preference_soft_compress_tex_none\" text=\"None\"/>\n    <Item id=\"preference_soft_compress_tex_halfline\" text=\"Half Line\"/>\n    <Item id=\"preference_ogl_compress_tex\" text=\"Texture Compression\"/>\n    <Item id=\"preference_ogl_compress_tex_none\" text=\"None\"/>\n    <Item id=\"preference_ogl_compress_tex_half\" text=\"Quarter Pixel\"/>\n    <Item id=\"preference_remember_last_path\" text=\"Remember Last Path\"/>\n    <Item id=\"preference_keep_screen_alive\" text=\"Keep Screen Alive\"/>\n    <Item id=\"preference_custom_option\" text=\"Custom Option\"/>\n    <Item id=\"preference_opengl_dup_target\" text=\"Copy Render Target Texture\"/>\n    <Item id=\"preference_ogl_accurate_render\" text=\"Accurate Rendering\"/>\n    <Item id=\"preference_ogl_max_texsize\" text=\"Max Texture Size\"/>\n    <Item id=\"preference_ogl_texsize_auto\" text=\"Auto\"/>\n    <Item id=\"preference_ogl_texsize_1024\" text=\"1024\"/>\n    <Item id=\"preference_ogl_texsize_2048\" text=\"2048\"/>\n    <Item id=\"preference_ogl_texsize_4096\" text=\"4096\"/>\n    <Item id=\"preference_ogl_texsize_8192\" text=\"8192\"/>\n    <Item id=\"preference_ogl_texsize_16384\" text=\"16384\"/>\n    <Item id=\"preference_mem_limit\" text=\"Attempt to Limit Memory Usage\"/>\n    <Item id=\"preference_mem_unlimited\" text=\"Unlimited\"/>\n    <Item id=\"preference_mem_high\" text=\"High Memory(<300MB)\"/>\n    <Item id=\"preference_mem_medium\" text=\"Medium Memory(<200MB)\"/>\n    <Item id=\"preference_mem_low\" text=\"Low Memory(<100MB)\"/>\n    <Item id=\"preference_show_fps\" text=\"Show FPS\"/>\n    <Item id=\"preference_fps_limit\" text=\"FPS Limit\"/>\n    <Item id=\"preference_hide_loading_ad\" text=\"Hide Ads while loading\"/>\n    <Item id=\"preference_rotate_screen_180\" text=\"Rotate Game Screen\"/>\n    <Item id=\"preference_virtual_cursor_scale\" text=\"Virtual Cursor Scale\"/>\n    <Item id=\"preference_menu_handler_opacity\" text=\"Menu Handler Opacity\"/>\n    <Item id=\"preference_reset\" text=\"Reset\"/>\n    <Item id=\"preference_hide_android_sys_btn\" text=\"Hide System Bar\"/>\n    <Item id=\"preference_default_font\" text=\"Default Font(Internal If Empty)\"/>\n    <Item id=\"preference_force_def_font\" text=\"Force using default font\"/>\n    <Item id=\"ok\" text=\"OK\"/>\n    <Item id=\"cancel\" text=\"Cancel\"/>\n    <Item id=\"retry\" text=\"Retry\"/>\n    <Item id=\"start\" text=\"Start\"/>\n    <Item id=\"stop\" text=\"Stop\"/>\n    <Item id=\"reactive\" text=\"Reactive\"/>\n    <Item id=\"ensure_to_override_file\" text=\"Please ensure to override:\"/>\n    <Item id=\"readonly_storage\" text=\"Read-only external storage detected\"/>\n    <Item id=\"cannot_create_preference\" text=\"Can not create individual preference file.\"/>\n    <Item id=\"use_internal_path\" text=\"Cannot access write permission for external storage, please copy/move data into the package paths listed below then try again:\"/>\n    <Item id=\"continue_run\" text=\"Continue\"/>\n    <Item id=\"get_sdcard_permission\" text=\"Fetch Permission(May Slow)\"/>\n    <Item id=\"crash_report\" text=\"Crash Report\"/>\n    <Item id=\"crash_report_msg\" text=\"Crash detected, send data (%d files) to help improving this app?\"/>\n    <Item id=\"menu_rotate\" text=\"Rotate Screen\"/>\n    <Item id=\"menu_global_preference\" text=\"Global Pref.\"/>\n    <Item id=\"menu_new_local_pref\" text=\"New Individual Pref.\"/>\n    <Item id=\"menu_local_pref\" text=\"Individual Pref.\"/>\n    <Item id=\"menu_new_folder\" text=\"New Folder\"/>\n    <Item id=\"menu_about\" text=\"About\"/>\n    <Item id=\"menu_exit\" text=\"Exit\"/>\n    <Item id=\"menu_help\" text=\"View Help\"/>\n    <Item id=\"menu_archive_repack\" text=\"Conv/Dec XP3\"/>\n    <Item id=\"menu_web_server\" text=\"Web File Server\"/>\n    <Item id=\"about_content\" text=\"Find patch here:&#10https://zeas2.github.io/Kirikiroid2_patch/patch&#10Report bugs here:&#10;https://github.com/zeas2/Kirikiroid2/issues\"/>\n    <Item id=\"about_content_i\" text=\"\"/>\n    <Item id=\"sure_to_exit\" text=\"Sure to exit?\"/>\n    <Item id=\"msgbox_yes\" text=\"Yes\"/>\n    <Item id=\"msgbox_no\" text=\"No\"/>\n    <Item id=\"msgbox_ok\" text=\"OK\"/>\n    <Item id=\"msgbox_nerver_notice\" text=\"Don't Notice Again\"/>\n    <Item id=\"use_last_path\" text=\"Use last path:\"/>\n\t\n    <Item id=\"notice\" text=\"Notice\"/>\n    <Item id=\"err_narrow_to_wide\" text=\"Cannot convert given narrow string to wide string,&#10;Data could be corrupted or encrypted or wrong text encoding.&#10;Maybe you need xp3filter.tjs if data is encrypted,&#10;or use patch.tjs to specify correct encoding if text is not encoded in SHIFT-JIS\"/>\n\t<Item id=\"err_no_memory\" text=\"Insufficent Memory&#10;If this error occured frequently, you can try limit memory usage in preference.\"/>\n\t<Item id=\"err_occured\" text=\"Error Occured\"/>\n\t<Item id=\"err_read_error\" text=\"Read Error\"/>\n\t<Item id=\"err_not_xp3_archive\" text=\"%1 is not valid XP3 archive. The data may be corrupted.\"/>\n\t<Item id=\"err_cannot_suggest_graph_ext\" text=\"%1 Cannot suggest extension name of this graphic. The data may lost or there has error in script.\"/>\n\t<Item id=\"delete\" text=\"Delete\"/>\n\t<Item id=\"file_operate_menu_title\" text=\"File Operation\"/>\n\t<Item id=\"file_operate_menu_text\" text=\"Please select opreation:\"/>\n\t<Item id=\"ensure_to_delete_file\" text=\"Please ensure to delete:\"/>\n\t<Item id=\"ensure_item_count\" text=\"%d items\"/>\n\t<Item id=\"device_info\" text=\"Device Info\"/>\n\t<Item id=\"supported_opengl_extension\" text=\"OpenGL Extensions(Only usable list):\"/>\n\t<Item id=\"preference_opengl_extension_opt\" text=\"OpenGL Extensions\"/>\n\t<Item id=\"startup_patch_fail\" text=\"Patch fail, please update patch.tjs\"/>\n\t<Item id=\"browse_patch_lib\" text=\"Patch Lib\"/>\n\t<Item id=\"preference_opengl_extension_desc\" text=\"May be usable OpenGL extension list here.&#10;Some features may cause wrong rendering result on some devices.\"/>\n\t<Item id=\"preference_android_fetch_sdcard_permission\" text=\"Fetch external sd-card write permission\"/>\n\t\n\t<Item id=\"filemgr_unselect\" text=\"Cancel\"/>\n\t<Item id=\"filemgr_browse\" text=\"View\"/>\n\t<Item id=\"filemgr_delete\" text=\"Delete\"/>\n\t<Item id=\"filemgr_copy\" text=\"Copy\"/>\n\t<Item id=\"filemgr_cut\" text=\"Cut\"/>\n\t<Item id=\"filemgr_paste\" text=\"Paste to here\"/>\n\t<Item id=\"filemgr_sendto\" text=\"Send to...\"/>\n\t<Item id=\"filemgr_unpack\" text=\"Unpack\"/>\n\t<Item id=\"filemgr_rename\" text=\"Rename\"/>\n\t<Item id=\"file_operate_failed\" text=\"File operation fail:\"/>\n\t<Item id=\"fail_to_open_archive\" text=\"Fail to open archive:\"/>\n\t\n\t<Item id=\"archive_repack_desc\" text=\"Convert and dec the archive could speed up and reduce heat. Please ensure the free spaec is larger than the maximum archive size, otherwise the operation may fail.\"/>\n\t<Item id=\"archive_repack_merge_img\" text=\"Merge mask image\"/>\n\t<Item id=\"archive_repack_conv_etc2\" text=\"Conv img to ETC2\"/>\n\t<Item id=\"archive_repack_proc_title\" text=\"Converting...\"/>\n\t<Item id=\"archive_repack_no_xp3filter\" text=\"No xp3filter found in current path. Continue ?\"/>\n\t<Item id=\"archive_repack_no_xp3\" text=\"No xp3 archvie found, stop.\"/>\n</Locale>"
  },
  {
    "path": "project/ui/Resources/res/locale/ja_jp.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Locale lang=\"en_us\">\n    <Item id=\"preference_title\" text=\"全体設定\"/>\n    <Item id=\"preference_title_individual\" text=\"個別設定\"/>\n    <Item id=\"preference_output_log\" text=\"ログを出力する\"/>\n    <Item id=\"preference_select_renderer\" text=\"画面の描画方法\"/>\n    <Item id=\"preference_opengl\" text=\"OpenGL（実験的）\"/>\n    <Item id=\"preference_software\" text=\"ソフトウェア\"/>\n    <Item id=\"preference_renderer_opt\" text=\"レンダラ詳細オプション\"/>\n    <Item id=\"preference_soft_renderer_opt\" text=\"ソフトウェアレンダラ\"/>\n    <Item id=\"preference_opengl_renderer_opt\" text=\"OpenGLレンダラ\"/>\n    <Item id=\"preference_multi_draw_thread\" text=\"描画スレッド分割数\"/>\n    <Item id=\"preference_draw_thread_auto\" text=\"自動\"/>\n    <Item id=\"preference_draw_thread_1\" text=\"1\"/>\n    <Item id=\"preference_draw_thread_2\" text=\"2\"/>\n    <Item id=\"preference_draw_thread_3\" text=\"3\"/>\n    <Item id=\"preference_draw_thread_4\" text=\"4\"/>\n    <Item id=\"preference_draw_thread_5\" text=\"5\"/>\n    <Item id=\"preference_draw_thread_6\" text=\"6\"/>\n    <Item id=\"preference_draw_thread_7\" text=\"7\"/>\n    <Item id=\"preference_draw_thread_8\" text=\"8\"/>\n    <Item id=\"preference_software_compress_tex\" text=\"テクスチャ圧縮\"/>\n    <Item id=\"preference_soft_compress_tex_none\" text=\"オリジナル\"/>\n    <Item id=\"preference_soft_compress_tex_halfline\" text=\"半減\"/>\n    <Item id=\"preference_ogl_compress_tex\" text=\"テクスチャ圧縮\"/>\n    <Item id=\"preference_ogl_compress_tex_none\" text=\"オリジナル\"/>\n    <Item id=\"preference_ogl_compress_tex_half\" text=\"半減\"/>\n    <Item id=\"preference_remember_last_path\" text=\"最後に使用したパスを保存する\"/>\n    <Item id=\"preference_keep_screen_alive\" text=\"画面がスリープに入らないようにする\"/>\n    <Item id=\"preference_custom_option\" text=\"カスタムオプション\"/>\n    <Item id=\"preference_opengl_dup_target\" text=\"ターゲットテクスチャをコピーする\"/>\n    <Item id=\"preference_ogl_accurate_render\" text=\"正確なレンダリング\"/>\n    <Item id=\"preference_ogl_max_texsize\" text=\"最大テクスチャサイズ\"/>\n    <Item id=\"preference_ogl_texsize_auto\" text=\"自動\"/>\n    <Item id=\"preference_ogl_texsize_1024\" text=\"1024\"/>\n    <Item id=\"preference_ogl_texsize_2048\" text=\"2048\"/>\n    <Item id=\"preference_ogl_texsize_4096\" text=\"4096\"/>\n    <Item id=\"preference_ogl_texsize_8192\" text=\"8192\"/>\n    <Item id=\"preference_ogl_texsize_16384\" text=\"16384\"/>\n    <Item id=\"preference_mem_limit\" text=\"メモリ使用量を制限（ゲームに応じて）\"/>\n    <Item id=\"preference_mem_unlimited\" text=\"制限なし\"/>\n    <Item id=\"preference_mem_high\" text=\"多く(<300MB)\"/>\n    <Item id=\"preference_mem_medium\" text=\"中(<200MB)\"/>\n    <Item id=\"preference_mem_low\" text=\"少なく(<100MB)\"/>\n    <Item id=\"preference_show_fps\" text=\"FPSを表示する\"/>\n    <Item id=\"preference_fps_limit\" text=\"FPS制限\"/>\n    <Item id=\"preference_hide_loading_ad\" text=\"ロード時に広告を表示しない\"/>\n    <Item id=\"preference_rotate_screen_180\" text=\"画面反転\"/>\n    <Item id=\"preference_virtual_cursor_scale\" text=\"仮想マウスの拡大縮小\"/>\n    <Item id=\"preference_menu_handler_opacity\" text=\"メニューハンドラの不透明度\"/>\n    <Item id=\"preference_reset\" text=\"RESET\"/>\n    <Item id=\"preference_hide_android_sys_btn\" text=\"ナビバーを隠す（再起動必要）\"/>\n    <Item id=\"preference_default_font\" text=\"デフォルトフォント（空白の場合は組み込みのを使用する）\"/>\n    <Item id=\"preference_force_def_font\" text=\"強制的にデフォルトフォントを使用する\"/>\n    <Item id=\"ok\" text=\"OK\"/>\n    <Item id=\"cancel\" text=\"キャンセル\"/>\n    <Item id=\"retry\" text=\"再試行\"/>\n    <Item id=\"start\" text=\"スタート\"/>\n    <Item id=\"stop\" text=\"Stop\"/>\n    <Item id=\"reactive\" text=\"再認証\"/>\n    <Item id=\"ensure_to_override_file\" text=\"上書きしますか：\"/>\n    <Item id=\"readonly_storage\" text=\"読み取り専用ストレージを検出します\"/>\n    <Item id=\"cannot_create_preference\" text=\"個別設定を作成することが出来ません\"/>\n    <Item id=\"use_internal_path\" text=\"外部ストレージに書き込むことはできません。ファイルを次のパスに移動またはコピーして、再度実行してみてください：\"/>\n    <Item id=\"crash_report\" text=\"クラッシュ報告\"/>\n    <Item id=\"crash_report_msg\" text=\"このアプリを改善するためにクラッシュデータ（%dファイル）をアップロードしますか？\"/>\n    <Item id=\"menu_rotate\" text=\"画面回転\"/>\n    <Item id=\"menu_global_preference\" text=\"全体設定\"/>\n    <Item id=\"menu_new_local_pref\" text=\"新規設定を作成\"/>\n    <Item id=\"menu_local_pref\" text=\"個別設定\"/>\n    <Item id=\"menu_new_folder\" text=\"新規フォルダ\"/>\n    <Item id=\"menu_about\" text=\"バージョン情報\"/>\n    <Item id=\"menu_exit\" text=\"終了\"/>\n    <Item id=\"menu_help\" text=\"ヘルプ\"/>\n    <Item id=\"menu_archive_repack\" text=\"変換/復号化XP3\"/>\n    <Item id=\"menu_web_server\" text=\"Webサーバー\"/>\n    <Item id=\"about_content\" text=\"Find patch here:&#10https://zeas2.github.io/Kirikiroid2_patch/patch&#10Report bugs here:&#10;https://github.com/zeas2/Kirikiroid2/issues\"/>\n    <Item id=\"about_content_i\" text=\"\"/>\n    <Item id=\"sure_to_exit\" text=\"終了しますか？\"/>\n    <Item id=\"msgbox_yes\" text=\"はい\"/>\n    <Item id=\"msgbox_no\" text=\"いいえ\"/>\n    <Item id=\"msgbox_ok\" text=\"OK\"/>\n    <Item id=\"use_last_path\" text=\"前回のパスを開きますか\"/>\n\t\n    <Item id=\"notice\" text=\"お知らせ\"/>\n    <Item id=\"err_narrow_to_wide\" text=\"ANSI 文字列を UNICODE 文字列に変換できません。&#10;現在のコードページで解釈できない文字が含まれてます。patch.tjsで正しいコードページを指定してください。&#10;正しいデータが指定されているかを確認してください。データが破損している可能性もあります。データが暗号化されている場合はxp3filter.tjsが必要かもしれない。\"/>\n\t<Item id=\"err_no_memory\" text=\"メモリが足りません（もしこの問題がよく発生する場合は、オプションの「メモリ使用量を制限」を使用してみる）\"/>\n\t<Item id=\"err_occured\" text=\"エラーが発生しました\"/>\n\t<Item id=\"err_read_error\" text=\"読み込みエラーが発生しました。ファイルが破損している可能性や、デバイスからの読み込みに失敗した可能性があります\"/>\n\t<Item id=\"err_not_xp3_archive\" text=\"%1 は正しいXP3アーカイブではありません。ファイルが破損している可能性があります。\"/>\n\t<Item id=\"err_cannot_suggest_graph_ext\" text=\"%1 について適切な拡張子を持ったファイルを見つけられませんでした\"/>\n\t<Item id=\"delete\" text=\"削除\"/>\n\t<Item id=\"file_operate_menu_title\" text=\"ファイル管理\"/>\n\t<Item id=\"file_operate_menu_text\" text=\"操作を選択してください\"/>\n\t<Item id=\"ensure_to_delete_file\" text=\"削除しますか：\"/>\n\t<Item id=\"ensure_item_count\" text=\"%d アイテム\"/>\n\t<Item id=\"device_info\" text=\"デバイス情報\"/>\n\t<Item id=\"supported_opengl_extension\" text=\"OpenGL拡張（利用可能なもの）：\"/>\n\t<Item id=\"preference_opengl_extension_opt\" text=\"OpenGL拡張\"/>\n\t<Item id=\"startup_patch_fail\" text=\"パッチ失敗しました。patch.tjsを更新してください。\"/>\n\t<Item id=\"browse_patch_lib\" text=\"パッチ庫\"/>\n\t<Item id=\"preference_opengl_extension_desc\" text=\"レンダリング効率を改善するために利用することができるOpenGL拡張のリストです。&#10;いくつかの機能がオンになったら、デバイスに応じて、レンダリングエラーが発生することがあります。\"/>\n\t<Item id=\"preference_android_fetch_sdcard_permission\" text=\"外部記憶の書き込みの権限を取得する\"/>\n\t\n\t<Item id=\"filemgr_unselect\" text=\"キャンセル\"/>\n\t<Item id=\"filemgr_browse\" text=\"ビュー\"/>\n\t<Item id=\"filemgr_delete\" text=\"削除\"/>\n\t<Item id=\"filemgr_copy\" text=\"コピー\"/>\n\t<Item id=\"filemgr_cut\" text=\"カット\"/>\n\t<Item id=\"filemgr_paste\" text=\"ここに貼り付ける\"/>\n\t<Item id=\"filemgr_sendto\" text=\"送信する\"/>\n\t<Item id=\"filemgr_unpack\" text=\"解凍する\"/>\n\t<Item id=\"filemgr_rename\" text=\"名前を変更する\"/>\n\t<Item id=\"file_operate_failed\" text=\"ファイル操作が失敗しました：\"/>\n\t<Item id=\"fail_to_open_archive\" text=\"アーカイブ操作が失敗しました：\"/>\n\t\n\t<Item id=\"archive_repack_desc\" text=\"Convert and dec the archive could speed up and reduce heat. Please ensure the free spaec is larger than the maximum archive size, otherwise the operation may fail.\"/>\n\t<Item id=\"archive_repack_merge_img\" text=\"Merge mask image\"/>\n\t<Item id=\"archive_repack_conv_etc2\" text=\"Conv image to ETC2\"/>\n\t<Item id=\"archive_repack_proc_title\" text=\"Converting...\"/>\n\t<Item id=\"archive_repack_no_xp3filter\" text=\"No xp3filter found in current path. Continue ?\"/>\n\t<Item id=\"archive_repack_no_xp3\" text=\"No xp3 archvie found, stop.\"/>\n</Locale>"
  },
  {
    "path": "project/ui/Resources/res/locale/zh_cn.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Locale lang=\"en_us\">\n    <Item id=\"preference_title\" text=\"全局设置\"/>\n    <Item id=\"preference_title_individual\" text=\"独立设置\"/>\n    <Item id=\"preference_output_log\" text=\"打印日志\"/>\n    <Item id=\"preference_select_renderer\" text=\"图形渲染器\"/>\n    <Item id=\"preference_opengl\" text=\"OpenGL（试验性）\"/>\n    <Item id=\"preference_software\" text=\"软件渲染器\"/>\n    <Item id=\"preference_renderer_opt\" text=\"渲染器高级选项\"/>\n    <Item id=\"preference_soft_renderer_opt\" text=\"软件渲染器选项\"/>\n    <Item id=\"preference_opengl_renderer_opt\" text=\"OpenGL渲染器选项\"/>\n    <Item id=\"preference_multi_draw_thread\" text=\"渲染线程数\"/>\n    <Item id=\"preference_draw_thread_auto\" text=\"自动\"/>\n    <Item id=\"preference_draw_thread_1\" text=\"1\"/>\n    <Item id=\"preference_draw_thread_2\" text=\"2\"/>\n    <Item id=\"preference_draw_thread_3\" text=\"3\"/>\n    <Item id=\"preference_draw_thread_4\" text=\"4\"/>\n    <Item id=\"preference_draw_thread_5\" text=\"5\"/>\n    <Item id=\"preference_draw_thread_6\" text=\"6\"/>\n    <Item id=\"preference_draw_thread_7\" text=\"7\"/>\n    <Item id=\"preference_draw_thread_8\" text=\"8\"/>\n    <Item id=\"preference_software_compress_tex\" text=\"纹理压缩\"/>\n    <Item id=\"preference_soft_compress_tex_none\" text=\"无压缩\"/>\n    <Item id=\"preference_soft_compress_tex_halfline\" text=\"半线压缩\"/>\n    <Item id=\"preference_ogl_compress_tex\" text=\"纹理压缩\"/>\n    <Item id=\"preference_ogl_compress_tex_none\" text=\"无压缩\"/>\n    <Item id=\"preference_ogl_compress_tex_half\" text=\"质量减半\"/>\n    <Item id=\"preference_remember_last_path\" text=\"记住最后使用的路径\"/>\n    <Item id=\"preference_keep_screen_alive\" text=\"保持屏幕常亮\"/>\n    <Item id=\"preference_custom_option\" text=\"自定义选项\"/>\n    <Item id=\"preference_opengl_dup_target\" text=\"复制目标纹理\"/>\n    <Item id=\"preference_ogl_accurate_render\" text=\"精确渲染模式\"/>\n    <Item id=\"preference_ogl_max_texsize\" text=\"最大纹理尺寸\"/>\n    <Item id=\"preference_ogl_texsize_auto\" text=\"自动\"/>\n    <Item id=\"preference_ogl_texsize_1024\" text=\"1024\"/>\n    <Item id=\"preference_ogl_texsize_2048\" text=\"2048\"/>\n    <Item id=\"preference_ogl_texsize_4096\" text=\"4096\"/>\n    <Item id=\"preference_ogl_texsize_8192\" text=\"8192\"/>\n    <Item id=\"preference_ogl_texsize_16384\" text=\"16384\"/>\n    <Item id=\"preference_mem_limit\" text=\"限制内存用量（视具体游戏）\"/>\n    <Item id=\"preference_mem_unlimited\" text=\"不限\"/>\n    <Item id=\"preference_mem_high\" text=\"高占用(<300MB)\"/>\n    <Item id=\"preference_mem_medium\" text=\"中等占用(<200MB)\"/>\n    <Item id=\"preference_mem_low\" text=\"低占用(<100MB)\"/>\n    <Item id=\"preference_show_fps\" text=\"显示 FPS\"/>\n    <Item id=\"preference_fps_limit\" text=\"限制 FPS\"/>\n    <Item id=\"preference_hide_loading_ad\" text=\"加载时不显示广告\"/>\n    <Item id=\"preference_rotate_screen_180\" text=\"反转游戏屏幕\"/>\n    <Item id=\"preference_virtual_cursor_scale\" text=\"虚拟鼠标缩放比\"/>\n    <Item id=\"preference_menu_handler_opacity\" text=\"菜单按钮不透明度\"/>\n    <Item id=\"preference_reset\" text=\"重置\"/>\n    <Item id=\"preference_hide_android_sys_btn\" text=\"隐藏系统键（需重启软件）\"/>\n    <Item id=\"preference_default_font\" text=\"默认字体（留空使用内置字体）\"/>\n    <Item id=\"preference_force_def_font\" text=\"强制使用默认字体\"/>\n    <Item id=\"ok\" text=\"OK\"/>\n    <Item id=\"cancel\" text=\"取消\"/>\n    <Item id=\"retry\" text=\"重试\"/>\n    <Item id=\"start\" text=\"开始\"/>\n    <Item id=\"stop\" text=\"停止\"/>\n    <Item id=\"reactive\" text=\"重新激活\"/>\n    <Item id=\"ensure_to_override_file\" text=\"确认要覆盖吗：\"/>\n    <Item id=\"readonly_storage\" text=\"发现只读的外部存储器\"/>\n    <Item id=\"cannot_create_preference\" text=\"无法创建配置\"/>\n    <Item id=\"use_internal_path\" text=\"外部存储目录无法安全写入文件，请移动或复制文件到些下列位置之后再尝试启动：\"/>\n    <Item id=\"continue_run\" text=\"仍然继续\"/>\n    <Item id=\"get_sdcard_permission\" text=\"获取写入权限\"/>\n    <Item id=\"crash_report\" text=\"崩溃报告\"/>\n    <Item id=\"crash_report_msg\" text=\"发现崩溃数据，发送数据（%d个文件）到服务器以助我们改进这个应用？\"/>\n    <Item id=\"menu_rotate\" text=\"旋转屏幕\"/>\n    <Item id=\"menu_global_preference\" text=\"全局设置\"/>\n    <Item id=\"menu_new_local_pref\" text=\"新建独立设置\"/>\n    <Item id=\"menu_local_pref\" text=\"独立设置\"/>\n    <Item id=\"menu_new_folder\" text=\"新建文件夹\"/>\n    <Item id=\"menu_about\" text=\"关于\"/>\n    <Item id=\"menu_exit\" text=\"退出\"/>\n    <Item id=\"menu_help\" text=\"查看帮助\"/>\n    <Item id=\"menu_archive_repack\" text=\"转换/解密XP3封包\"/>\n    <Item id=\"menu_web_server\" text=\"Web文件服务器\"/>\n    <Item id=\"about_content\" text=\"可以在github补丁页面寻找补丁：&#10;https://zeas2.github.io/Kirikiroid2_patch/patch&#10;如遇到问题，请反馈到到项目页面：&#10;https://github.com/zeas2/Kirikiroid2/issues&#10;或者到百度贴吧寻找解决方案：&#10;百度Kirikiroid2吧\"/>\n    <Item id=\"about_content_i\" text=\"\"/>\n    <Item id=\"sure_to_exit\" text=\"确定退出吗？\"/>\n    <Item id=\"msgbox_yes\" text=\"是\"/>\n    <Item id=\"msgbox_no\" text=\"否\"/>\n    <Item id=\"msgbox_ok\" text=\"确定\"/>\n    <Item id=\"msgbox_nerver_notice\" text=\"不再提示\"/>\n    <Item id=\"use_last_path\" text=\"使用最近启动的路径：\"/>\n\t\n    <Item id=\"notice\" text=\"提示\"/>\n    <Item id=\"err_narrow_to_wide\" text=\"无法转换字节字符为宽字符，可能数据被加密或损坏，也可能是使用了错误的文本编码。&#10;如果数据被加密，您可能需要xp3filter.tjs&#10;如果文本不是以SHIFT_JIS编码，需要用patch.tjs指定正确的编码格式。\"/>\n\t<Item id=\"err_no_memory\" text=\"内存不足（若经常出现此问题，可以试着在选项里限制内存用量）\"/>\n\t<Item id=\"err_occured\" text=\"发生错误\"/>\n\t<Item id=\"err_read_error\" text=\"读取错误，数据或已损坏\"/>\n\t<Item id=\"err_not_xp3_archive\" text=\"%1 不是有效的XP3包。数据或已损坏。\"/>\n\t<Item id=\"err_cannot_suggest_graph_ext\" text=\"%1 无法加载此图片，可能是数据不完整或脚本错误\"/>\n\t<Item id=\"delete\" text=\"删除\"/>\n\t<Item id=\"file_operate_menu_title\" text=\"文件管理\"/>\n\t<Item id=\"file_operate_menu_text\" text=\"请选择操作\"/>\n\t<Item id=\"ensure_to_delete_file\" text=\"确定要删除吗：\"/>\n\t<Item id=\"ensure_item_count\" text=\"%d 个项目\"/>\n\t<Item id=\"device_info\" text=\"设备信息\"/>\n\t<Item id=\"supported_opengl_extension\" text=\"OpenGL扩展特性（仅列出当前可用的扩展）：\"/>\n\t<Item id=\"preference_opengl_extension_opt\" text=\"OpenGL扩展\"/>\n\t<Item id=\"startup_patch_fail\" text=\"补丁失败，请更新patch.tjs\"/>\n\t<Item id=\"browse_patch_lib\" text=\"浏览补丁库\"/>\n\t<Item id=\"preference_opengl_extension_desc\" text=\"这里是可能利用的OpenGL扩展列表，用于提高渲染的效率。&#10;视设备的不同，部分特性开启后可能会出现渲染错误。\"/>\n\t<Item id=\"preference_android_fetch_sdcard_permission\" text=\"获取外部存储卡写入权限\"/>\n\t\n\t<Item id=\"filemgr_unselect\" text=\"取消\"/>\n\t<Item id=\"filemgr_browse\" text=\"浏览\"/>\n\t<Item id=\"filemgr_delete\" text=\"删除\"/>\n\t<Item id=\"filemgr_copy\" text=\"复制\"/>\n\t<Item id=\"filemgr_cut\" text=\"剪切\"/>\n\t<Item id=\"filemgr_paste\" text=\"粘贴到这里\"/>\n\t<Item id=\"filemgr_sendto\" text=\"发送到\"/>\n\t<Item id=\"filemgr_unpack\" text=\"解压缩\"/>\n\t<Item id=\"filemgr_rename\" text=\"重命名\"/>\n\t<Item id=\"file_operate_failed\" text=\"文件操作失败：\"/>\n\t<Item id=\"fail_to_open_archive\" text=\"无法作为压缩包打开：\"/>\n\t\n\t<Item id=\"archive_repack_desc\" text=\"解密并转换封包可以加快运行的速度并减少发热量。请保证剩余的空间大于最大的封包文件大小，否则转换操作可能会失败。\"/>\n\t<Item id=\"archive_repack_merge_img\" text=\"合并遮罩图片\"/>\n\t<Item id=\"archive_repack_conv_etc2\" text=\"转换图片格式为ETC2\"/>\n\t<Item id=\"archive_repack_proc_title\" text=\"转换进行中...\"/>\n\t<Item id=\"archive_repack_no_xp3filter\" text=\"当前目录未发现xp3filter，可能不需要进行转换。仍然继续？\"/>\n\t<Item id=\"archive_repack_no_xp3\" text=\"当前目录未发现xp3封包，操作中止。\"/>\n</Locale>"
  },
  {
    "path": "project/ui/Resources/res/locale/zh_tw.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Locale lang=\"en_us\">\n    <Item id=\"preference_title\" text=\"全局设置\"/>\n    <Item id=\"preference_title_individual\" text=\"独立设置\"/>\n    <Item id=\"preference_output_log\" text=\"打印日志\"/>\n    <Item id=\"preference_select_renderer\" text=\"图形渲染器\"/>\n    <Item id=\"preference_opengl\" text=\"OpenGL（试验性）\"/>\n    <Item id=\"preference_software\" text=\"软件渲染器\"/>\n    <Item id=\"preference_renderer_opt\" text=\"渲染器高级选项\"/>\n    <Item id=\"preference_soft_renderer_opt\" text=\"软件渲染器选项\"/>\n    <Item id=\"preference_opengl_renderer_opt\" text=\"OpenGL渲染器选项\"/>\n    <Item id=\"preference_multi_draw_thread\" text=\"渲染线程数\"/>\n    <Item id=\"preference_draw_thread_auto\" text=\"自动\"/>\n    <Item id=\"preference_draw_thread_1\" text=\"1\"/>\n    <Item id=\"preference_draw_thread_2\" text=\"2\"/>\n    <Item id=\"preference_draw_thread_3\" text=\"3\"/>\n    <Item id=\"preference_draw_thread_4\" text=\"4\"/>\n    <Item id=\"preference_draw_thread_5\" text=\"5\"/>\n    <Item id=\"preference_draw_thread_6\" text=\"6\"/>\n    <Item id=\"preference_draw_thread_7\" text=\"7\"/>\n    <Item id=\"preference_draw_thread_8\" text=\"8\"/>\n    <Item id=\"preference_software_compress_tex\" text=\"纹理压缩\"/>\n    <Item id=\"preference_soft_compress_tex_none\" text=\"无压缩\"/>\n    <Item id=\"preference_soft_compress_tex_halfline\" text=\"半线压缩\"/>\n    <Item id=\"preference_ogl_compress_tex\" text=\"纹理压缩\"/>\n    <Item id=\"preference_ogl_compress_tex_none\" text=\"无压缩\"/>\n    <Item id=\"preference_ogl_compress_tex_half\" text=\"质量减半\"/>\n    <Item id=\"preference_remember_last_path\" text=\"记住最后使用的路径\"/>\n    <Item id=\"preference_keep_screen_alive\" text=\"保持屏幕常亮\"/>\n    <Item id=\"preference_custom_option\" text=\"自定义选项\"/>\n    <Item id=\"preference_opengl_dup_target\" text=\"复制目标纹理\"/>\n    <Item id=\"preference_ogl_accurate_render\" text=\"精确渲染模式\"/>\n    <Item id=\"preference_ogl_max_texsize\" text=\"最大纹理尺寸\"/>\n    <Item id=\"preference_ogl_texsize_auto\" text=\"自动\"/>\n    <Item id=\"preference_ogl_texsize_1024\" text=\"1024\"/>\n    <Item id=\"preference_ogl_texsize_2048\" text=\"2048\"/>\n    <Item id=\"preference_ogl_texsize_4096\" text=\"4096\"/>\n    <Item id=\"preference_ogl_texsize_8192\" text=\"8192\"/>\n    <Item id=\"preference_ogl_texsize_16384\" text=\"16384\"/>\n    <Item id=\"preference_mem_limit\" text=\"限制内存用量（视具体游戏）\"/>\n    <Item id=\"preference_mem_unlimited\" text=\"不限\"/>\n    <Item id=\"preference_mem_high\" text=\"高占用(<300MB)\"/>\n    <Item id=\"preference_mem_medium\" text=\"中等占用(<200MB)\"/>\n    <Item id=\"preference_mem_low\" text=\"低占用(<100MB)\"/>\n    <Item id=\"preference_show_fps\" text=\"显示 FPS\"/>\n    <Item id=\"preference_fps_limit\" text=\"限制 FPS\"/>\n    <Item id=\"preference_hide_loading_ad\" text=\"加载时不显示广告\"/>\n    <Item id=\"preference_rotate_screen_180\" text=\"反转游戏屏幕\"/>\n    <Item id=\"preference_virtual_cursor_scale\" text=\"虚拟鼠标缩放比\"/>\n    <Item id=\"preference_menu_handler_opacity\" text=\"菜单按钮不透明度\"/>\n    <Item id=\"preference_reset\" text=\"重置\"/>\n    <Item id=\"preference_hide_android_sys_btn\" text=\"隐藏系统键（需重启软件）\"/>\n    <Item id=\"preference_default_font\" text=\"默认字体（留空使用内置字体）\"/>\n    <Item id=\"preference_force_def_font\" text=\"强制使用默认字体\"/>\n    <Item id=\"ok\" text=\"OK\"/>\n    <Item id=\"cancel\" text=\"取消\"/>\n    <Item id=\"retry\" text=\"重试\"/>\n    <Item id=\"start\" text=\"开始\"/>\n    <Item id=\"stop\" text=\"停止\"/>\n    <Item id=\"reactive\" text=\"重新激活\"/>\n    <Item id=\"ensure_to_override_file\" text=\"确认要覆盖吗：\"/>\n    <Item id=\"readonly_storage\" text=\"发现只读的外部存储器\"/>\n    <Item id=\"cannot_create_preference\" text=\"无法创建配置\"/>\n    <Item id=\"use_internal_path\" text=\"外部存储目录无法安全写入文件，请移动或复制文件到些下列位置之后再尝试启动：\"/>\n    <Item id=\"continue_run\" text=\"仍然继续\"/>\n    <Item id=\"get_sdcard_permission\" text=\"获取写入权限\"/>\n    <Item id=\"crash_report\" text=\"崩溃报告\"/>\n    <Item id=\"crash_report_msg\" text=\"发现崩溃数据，发送数据（%d个文件）到服务器以助我们改进这个应用？\"/>\n    <Item id=\"menu_rotate\" text=\"旋转屏幕\"/>\n    <Item id=\"menu_global_preference\" text=\"全局设置\"/>\n    <Item id=\"menu_new_local_pref\" text=\"新建独立设置\"/>\n    <Item id=\"menu_local_pref\" text=\"独立设置\"/>\n    <Item id=\"menu_new_folder\" text=\"新建文件夹\"/>\n    <Item id=\"menu_about\" text=\"关于\"/>\n    <Item id=\"menu_exit\" text=\"退出\"/>\n    <Item id=\"menu_help\" text=\"查看幫助\"/>\n    <Item id=\"menu_archive_repack\" text=\"转换/解密XP3封包\"/>\n    <Item id=\"menu_web_server\" text=\"Web文件服务器\"/>\n    <Item id=\"about_content\" text=\"可以在github补丁页面寻找补丁：&#10;https://zeas2.github.io/Kirikiroid2_patch/patch&#10;如遇到问题，请反馈到到项目页面：&#10;https://github.com/zeas2/Kirikiroid2/issues&#10;或者到百度贴吧寻找解决方案：&#10;百度Kirikiroid2吧\"/>\n    <Item id=\"about_content_i\" text=\"\"/>\n    <Item id=\"sure_to_exit\" text=\"确定退出吗？\"/>\n    <Item id=\"msgbox_yes\" text=\"是\"/>\n    <Item id=\"msgbox_no\" text=\"否\"/>\n    <Item id=\"msgbox_ok\" text=\"确定\"/>\n    <Item id=\"msgbox_nerver_notice\" text=\"不再提示\"/>\n    <Item id=\"use_last_path\" text=\"使用最近启动的路径：\"/>\n\t\n    <Item id=\"notice\" text=\"提示\"/>\n    <Item id=\"err_narrow_to_wide\" text=\"无法转换字节字符为宽字符，可能数据被加密或损坏，也可能是使用了错误的文本编码。&#10;如果数据被加密，您可能需要xp3filter.tjs&#10;如果文本不是以SHIFT_JIS编码，需要用patch.tjs指定正确的编码格式。\"/>\n\t<Item id=\"err_no_memory\" text=\"内存不足（若经常出现此问题，可以试着在选项里限制内存用量）\"/>\n\t<Item id=\"err_occured\" text=\"发生错误\"/>\n\t<Item id=\"err_read_error\" text=\"读取错误，数据或已损坏\"/>\n\t<Item id=\"err_not_xp3_archive\" text=\"%1 不是有效的XP3包。数据或已损坏。\"/>\n\t<Item id=\"err_cannot_suggest_graph_ext\" text=\"%1 无法加载此图片，可能是数据不完整或脚本错误\"/>\n\t<Item id=\"delete\" text=\"删除\"/>\n\t<Item id=\"file_operate_menu_title\" text=\"文件管理\"/>\n\t<Item id=\"file_operate_menu_text\" text=\"请选择操作\"/>\n\t<Item id=\"ensure_to_delete_file\" text=\"确定要删除吗：\"/>\n\t<Item id=\"ensure_item_count\" text=\"%d 个项目\"/>\n\t<Item id=\"device_info\" text=\"设备信息\"/>\n\t<Item id=\"supported_opengl_extension\" text=\"OpenGL扩展特性（仅列出当前可用的扩展）：\"/>\n\t<Item id=\"preference_opengl_extension_opt\" text=\"OpenGL扩展\"/>\n\t<Item id=\"startup_patch_fail\" text=\"补丁失败，请更新patch.tjs\"/>\n\t<Item id=\"browse_patch_lib\" text=\"浏览补丁库\"/>\n\t<Item id=\"preference_opengl_extension_desc\" text=\"这里是可能利用的OpenGL扩展列表，用于提高渲染的效率。&#10;视设备的不同，部分特性开启后可能会出现渲染错误。\"/>\n\t<Item id=\"preference_android_fetch_sdcard_permission\" text=\"获取外部存储卡写入权限\"/>\n\t\n\t<Item id=\"filemgr_unselect\" text=\"取消\"/>\n\t<Item id=\"filemgr_browse\" text=\"浏览\"/>\n\t<Item id=\"filemgr_delete\" text=\"删除\"/>\n\t<Item id=\"filemgr_copy\" text=\"复制\"/>\n\t<Item id=\"filemgr_cut\" text=\"剪切\"/>\n\t<Item id=\"filemgr_paste\" text=\"粘贴到这里\"/>\n\t<Item id=\"filemgr_sendto\" text=\"发送到\"/>\n\t<Item id=\"filemgr_unpack\" text=\"解压缩\"/>\n\t<Item id=\"filemgr_rename\" text=\"重命名\"/>\n\t<Item id=\"file_operate_failed\" text=\"文件操作失败：\"/>\n\t<Item id=\"fail_to_open_archive\" text=\"无法作为压缩包打开：\"/>\n\t\n\t<Item id=\"archive_repack_desc\" text=\"解密并转换封包可以加快运行的速度并减少发热量。请保证剩余的空间大于最大的封包文件大小，否则转换操作可能会失败。\"/>\n\t<Item id=\"archive_repack_merge_img\" text=\"合并遮罩图片\"/>\n\t<Item id=\"archive_repack_conv_etc2\" text=\"转换图片格式为ETC2\"/>\n\t<Item id=\"archive_repack_proc_title\" text=\"转换进行中...\"/>\n\t<Item id=\"archive_repack_no_xp3filter\" text=\"当前目录未发现xp3filter，可能不需要进行转换。仍然继续？\"/>\n\t<Item id=\"archive_repack_no_xp3\" text=\"当前目录未发现xp3封包，操作中止。\"/>\n</Locale>"
  },
  {
    "path": "project/ui/cocosstudio/ui/BottomBar.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"BottomBar\" Type=\"Layer\" ID=\"d6e3d7ad-9136-4e50-9628-78faf448d52c\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"47\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"panel\" ActionTag=\"-1964975631\" Tag=\"52\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ScrollDirectionType=\"0\" ItemMargin=\"8\" VerticalType=\"Align_VerticalCenter\" ctype=\"ListViewObjectData\">\n            <Size X=\"720.0000\" Y=\"96.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"360.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/BottomBarTextInput.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"BottomBarTextInput\" Type=\"Layer\" ID=\"47c22677-e81d-45f8-908b-834ed07ae23b\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"38\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"340.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_4\" ActionTag=\"-1868766583\" Tag=\"47\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"340.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_14_9\" ActionTag=\"-1137104828\" Tag=\"50\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"90.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"700.0000\" Y=\"240.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"input\" ActionTag=\"-486188303\" Tag=\"51\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"72\" IsCustomSize=\"True\" LabelText=\"\" PlaceHolderText=\"Touch to input\" MaxLengthText=\"10\" ctype=\"TextFieldObjectData\">\n                    <Size X=\"700.0000\" Y=\"240.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"350.0000\" Y=\"120.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"10.0000\" Y=\"90.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0139\" Y=\"0.3750\" />\n                <PreSize X=\"1.0000\" Y=\"0.4167\" />\n                <SingleColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"cancel\" ActionTag=\"-124580242\" Tag=\"61\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"20.0000\" RightMargin=\"440.0000\" TopMargin=\"160.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" FontSize=\"72\" ButtonText=\"Cancel\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"260.0000\" Y=\"70.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"45.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0278\" Y=\"0.1875\" />\n                <PreSize X=\"0.3611\" Y=\"0.2917\" />\n                <TextColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"ok\" ActionTag=\"273088593\" Tag=\"62\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"440.0000\" RightMargin=\"20.0000\" TopMargin=\"160.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" FontSize=\"72\" ButtonText=\"OK\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"260.0000\" Y=\"70.0000\" />\n                <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n                <Position X=\"700.0000\" Y=\"45.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.9722\" Y=\"0.1875\" />\n                <PreSize X=\"0.3611\" Y=\"0.2917\" />\n                <TextColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/CheckListDialog.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"CheckListDialog\" Type=\"Layer\" ID=\"cd4e123b-aa28-45db-a853-9eb0a0b833ce\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"192\" ctype=\"GameLayerObjectData\">\n        <Size X=\"1280.0000\" Y=\"720.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_20\" ActionTag=\"-1299952620\" Tag=\"114\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"38\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"1280.0000\" Y=\"720.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"101332157\" Tag=\"194\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" LeftMargin=\"64.0000\" RightMargin=\"64.0000\" TopMargin=\"36.0000\" BottomMargin=\"36.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"1152.0000\" Y=\"648.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"title\" ActionTag=\"-97033936\" Tag=\"195\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"5.0000\" RightMargin=\"856.0000\" TopMargin=\"5.0000\" BottomMargin=\"559.0000\" FontSize=\"64\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"291.0000\" Y=\"84.0000\" />\n                <AnchorPoint ScaleY=\"1.0000\" />\n                <Position X=\"5.0000\" Y=\"643.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0043\" Y=\"0.9923\" />\n                <PreSize X=\"0.2526\" Y=\"0.1296\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-715448789\" Tag=\"197\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"BothEdge\" TopMargin=\"100.0000\" BottomMargin=\"118.0000\" TouchEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"1152.0000\" Y=\"430.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_4\" ActionTag=\"284813943\" Tag=\"199\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" RightMargin=\"576.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"576.0000\" Y=\"430.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"list_1\" ActionTag=\"-1742361560\" Tag=\"193\" IconVisible=\"False\" PercentHeightEnable=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" RightMargin=\"8.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"True\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n                        <Size X=\"568.0000\" Y=\"430.0000\" />\n                        <AnchorPoint />\n                        <Position />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition />\n                        <PreSize X=\"0.9861\" Y=\"1.0000\" />\n                        <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.5000\" Y=\"1.0000\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_5\" ActionTag=\"-1721326462\" Tag=\"200\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" LeftMargin=\"576.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"576.0000\" Y=\"430.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"list_2\" ActionTag=\"-17686331\" Tag=\"196\" IconVisible=\"False\" PercentHeightEnable=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"8.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"True\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" IsBounceEnabled=\"True\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n                        <Size X=\"568.0000\" Y=\"430.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"8.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0139\" />\n                        <PreSize X=\"0.9861\" Y=\"1.0000\" />\n                        <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"576.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" />\n                    <PreSize X=\"0.5000\" Y=\"1.0000\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"118.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.1821\" />\n                <PreSize X=\"1.0000\" Y=\"0.6636\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"btn_list\" ActionTag=\"-1606216519\" Tag=\"209\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" TopMargin=\"543.0000\" TouchEnable=\"True\" ClipAble=\"True\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"Horizontal\" ctype=\"ScrollViewObjectData\">\n                <Size X=\"1152.0000\" Y=\"105.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btn_cell\" ActionTag=\"-653816359\" Tag=\"205\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"451.0000\" RightMargin=\"451.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"250.0000\" Y=\"105.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_7\" ActionTag=\"-2083873151\" Tag=\"206\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"4.0000\" RightMargin=\"4.0000\" TopMargin=\"4.0000\" BottomMargin=\"4.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"242.0000\" Y=\"97.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"btn\" ActionTag=\"1642759840\" Tag=\"207\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"64\" ButtonText=\"Button\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                            <Size X=\"242.0000\" Y=\"97.0000\" />\n                            <AnchorPoint />\n                            <Position />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                            <TextColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                            <DisabledFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                            <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                            <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"4.0000\" Y=\"4.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0160\" Y=\"0.0381\" />\n                        <PreSize X=\"0.9680\" Y=\"0.9238\" />\n                        <SingleColor A=\"255\" R=\"153\" G=\"153\" B=\"153\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"576.0000\" Y=\"52.5000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.2170\" Y=\"1.0000\" />\n                    <SingleColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                    <FirstColor A=\"255\" R=\"136\" G=\"136\" B=\"136\" />\n                    <EndColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" />\n                <Position X=\"576.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" />\n                <PreSize X=\"1.0000\" Y=\"0.1620\" />\n                <SingleColor A=\"255\" R=\"255\" G=\"150\" B=\"100\" />\n                <FirstColor A=\"255\" R=\"255\" G=\"150\" B=\"100\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n                <InnerNodeSize Width=\"1152\" Height=\"105\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"640.0000\" Y=\"360.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"0.9000\" Y=\"0.9000\" />\n            <SingleColor A=\"255\" R=\"64\" G=\"64\" B=\"64\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/FileItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"FileItem\" Type=\"Layer\" ID=\"003d7daa-f264-4050-83c1-fc022b6799e2\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"18\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"filename\" ActionTag=\"1244672719\" Tag=\"19\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"8.0000\" RightMargin=\"80.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" IsCustomSize=\"True\" FontSize=\"64\" LabelText=\"\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"552.0000\" Y=\"80.0000\" />\n            <AnchorPoint />\n            <Position X=\"8.0000\" Y=\"8.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0125\" Y=\"0.0833\" />\n            <PreSize X=\"0.8625\" Y=\"0.8333\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"518500198\" Tag=\"24\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" TopMargin=\"92.0000\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"2\" ColorAngle=\"0.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"640.0000\" Y=\"4.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"0.0417\" />\n            <SingleColor A=\"255\" R=\"133\" G=\"133\" B=\"133\" />\n            <FirstColor A=\"255\" R=\"229\" G=\"229\" B=\"229\" />\n            <EndColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <ColorVector ScaleX=\"1.0000\" ScaleY=\"0.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"highlight\" ActionTag=\"-1409623701\" Alpha=\"51\" Tag=\"109\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"640.0000\" Y=\"96.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"select_check\" ActionTag=\"-1565335157\" Tag=\"309\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"552.0000\" RightMargin=\"8.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" CheckedState=\"True\" ctype=\"CheckBoxObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"632.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9875\" Y=\"0.5000\" />\n            <PreSize X=\"0.1250\" Y=\"0.8333\" />\n            <NormalBackFileData Type=\"Normal\" Path=\"img/CheckBox_Normal.png\" Plist=\"\" />\n            <PressedBackFileData Type=\"Normal\" Path=\"img/CheckBox_Press.png\" Plist=\"\" />\n            <DisableBackFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <NodeNormalFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Normal.png\" Plist=\"\" />\n            <NodeDisableFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"dir_icon\" ActionTag=\"759566553\" Tag=\"62\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"552.0000\" RightMargin=\"8.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_2_9_4\" ActionTag=\"303139165\" Tag=\"63\" RotationSkewX=\"-135.0000\" RotationSkewY=\"-135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"30.0000\" BottomMargin=\"40.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"45.0000\" Y=\"10.0000\" />\n                <AnchorPoint />\n                <Position X=\"70.0000\" Y=\"40.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2_0_11_6\" ActionTag=\"1575774268\" Tag=\"64\" RotationSkewX=\"135.0006\" RotationSkewY=\"135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"40.0000\" BottomMargin=\"30.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"45.0000\" Y=\"10.0000\" />\n                <AnchorPoint ScaleY=\"1.0000\" />\n                <Position X=\"70.0000\" Y=\"40.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"632.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9875\" Y=\"0.5000\" />\n            <PreSize X=\"0.1250\" Y=\"0.8333\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/FileManageMenu.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"FileManageMenu\" Type=\"Layer\" ID=\"0157d9b8-af36-4c34-ab31-3a6ace980d66\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"416\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"1000.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_6\" ActionTag=\"1691454058\" Tag=\"437\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"-2.0000\" RightMargin=\"-2.0000\" TopMargin=\"-2.0000\" BottomMargin=\"-2.0000\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"724.0000\" Y=\"1004.0000\" />\n            <AnchorPoint />\n            <Position X=\"-2.0000\" Y=\"-2.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"-0.0028\" Y=\"-0.0020\" />\n            <PreSize X=\"1.0056\" Y=\"1.0040\" />\n            <SingleColor A=\"255\" R=\"162\" G=\"162\" B=\"162\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"992433925\" Tag=\"420\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"TopEdge\" BottomMargin=\"904.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"96.0000\" />\n            <AnchorPoint />\n            <Position Y=\"904.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"0.9040\" />\n            <PreSize X=\"1.0000\" Y=\"0.0960\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"title\" ActionTag=\"-806811186\" Tag=\"500\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" VerticalEdge=\"TopEdge\" LeftMargin=\"24.5000\" RightMargin=\"24.5000\" TopMargin=\"6.0000\" BottomMargin=\"910.0000\" FontSize=\"64\" LabelText=\"file_operate_menu_text\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"671.0000\" Y=\"84.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"360.0000\" Y=\"952.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n            <PrePosition X=\"0.5000\" Y=\"0.9520\" />\n            <PreSize X=\"0.9319\" Y=\"0.0840\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"list\" ActionTag=\"235528911\" Tag=\"417\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"BothEdge\" TopMargin=\"98.0000\" TouchEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"True\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n            <Size X=\"720.0000\" Y=\"902.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"unselect\" ActionTag=\"-1971645612\" Tag=\"310\" IconVisible=\"False\" BottomMargin=\"806.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnUnselect\" ActionTag=\"-1172839931\" Tag=\"311\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"back_icon_4\" ActionTag=\"-103016334\" Tag=\"320\" RotationSkewX=\"135.0000\" RotationSkewY=\"134.9975\" IconVisible=\"False\" LeftMargin=\"-16.0000\" RightMargin=\"608.0000\" TopMargin=\"-16.0000\" BottomMargin=\"-16.0000\" FlipX=\"True\" ctype=\"SpriteObjectData\">\n                    <Size X=\"128.0000\" Y=\"128.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <CColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1778\" Y=\"1.3333\" />\n                    <FileData Type=\"Normal\" Path=\"img/back_icon.png\" Plist=\"\" />\n                    <BlendFunc Src=\"1\" Dst=\"771\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleUnselect\" ActionTag=\"-809848444\" Tag=\"319\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"149.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_unselect\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"475.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.6597\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"806.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.8936\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"browse\" ActionTag=\"1869104691\" ZOrder=\"1\" Tag=\"647\" IconVisible=\"False\" TopMargin=\"96.0000\" BottomMargin=\"710.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnBrowse\" ActionTag=\"1868109539\" Tag=\"648\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_40\" ActionTag=\"610007834\" Tag=\"649\" IconVisible=\"False\" LeftMargin=\"-130.0897\" RightMargin=\"493.9103\" TopMargin=\"-140.3253\" BottomMargin=\"-146.3253\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"356.1794\" Y=\"382.6505\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_36\" ActionTag=\"152437700\" Tag=\"650\" IconVisible=\"False\" LeftMargin=\"78.0900\" RightMargin=\"78.0894\" TopMargin=\"41.3253\" BottomMargin=\"41.3252\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" ActionTag=\"1514860367\" Tag=\"651\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" ActionTag=\"-1154829638\" Tag=\"652\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" ActionTag=\"-1382055658\" Tag=\"653\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"178.0900\" Y=\"191.3252\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_86\" ActionTag=\"2146182298\" Tag=\"658\" RotationSkewX=\"135.0009\" RotationSkewY=\"134.9991\" IconVisible=\"False\" LeftMargin=\"257.9067\" RightMargin=\"72.5715\" TopMargin=\"159.1678\" BottomMargin=\"120.6946\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"25.7012\" Y=\"102.7881\" />\n                        <AnchorPoint />\n                        <Position X=\"257.9067\" Y=\"120.6946\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.7241\" Y=\"0.3154\" />\n                        <PreSize X=\"0.0722\" Y=\"0.2686\" />\n                        <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"about_icon_53\" ActionTag=\"1034064973\" Tag=\"657\" RotationSkewX=\"225.0000\" RotationSkewY=\"225.0000\" IconVisible=\"False\" LeftMargin=\"176.4542\" RightMargin=\"115.7252\" TopMargin=\"200.6442\" BottomMargin=\"118.0063\" ctype=\"SpriteObjectData\">\n                        <Size X=\"64.0000\" Y=\"64.0000\" />\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"208.4542\" Y=\"150.0063\" />\n                        <Scale ScaleX=\"2.0000\" ScaleY=\"2.0000\" />\n                        <CColor A=\"255\" R=\"229\" G=\"229\" B=\"229\" />\n                        <PrePosition X=\"0.5853\" Y=\"0.3920\" />\n                        <PreSize X=\"0.1797\" Y=\"0.1673\" />\n                        <FileData Type=\"Normal\" Path=\"img/about_icon.png\" Plist=\"\" />\n                        <BlendFunc Src=\"1\" Dst=\"771\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.4947\" Y=\"3.9859\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleBrowse\" ActionTag=\"134626095\" Tag=\"656\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"181.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_browse\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"443.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.6153\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"710.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.7871\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"paste\" ActionTag=\"1336476886\" ZOrder=\"2\" Tag=\"538\" IconVisible=\"False\" TopMargin=\"192.0000\" BottomMargin=\"614.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnPaste\" ActionTag=\"1425966242\" Tag=\"539\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_40\" ActionTag=\"-1360512389\" Tag=\"540\" IconVisible=\"False\" LeftMargin=\"-130.0897\" RightMargin=\"493.9103\" TopMargin=\"-140.3253\" BottomMargin=\"-146.3253\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"356.1794\" Y=\"382.6505\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_36\" CanEdit=\"False\" ActionTag=\"-152416975\" Tag=\"541\" IconVisible=\"False\" LeftMargin=\"25.3715\" RightMargin=\"130.8079\" TopMargin=\"13.1390\" BottomMargin=\"69.5115\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" CanEdit=\"False\" ActionTag=\"-718037591\" Tag=\"542\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-1851290327\" Tag=\"543\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"-1460524141\" Tag=\"544\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"25.3715\" Y=\"69.5115\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0712\" Y=\"0.1817\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_36_0\" CanEdit=\"False\" ActionTag=\"-734947750\" Tag=\"545\" IconVisible=\"False\" LeftMargin=\"131.5878\" RightMargin=\"24.5916\" TopMargin=\"72.7092\" BottomMargin=\"9.9413\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" CanEdit=\"False\" ActionTag=\"-1048546903\" Tag=\"546\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-1827825088\" Tag=\"547\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"638525145\" Tag=\"548\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"131.5878\" Y=\"9.9413\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.3694\" Y=\"0.0260\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_49\" ActionTag=\"1509069589\" Tag=\"552\" RotationSkewX=\"45.0000\" RotationSkewY=\"45.0000\" IconVisible=\"False\" LeftMargin=\"52.0000\" RightMargin=\"176.1794\" TopMargin=\"187.6505\" BottomMargin=\"165.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"128.0000\" Y=\"30.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"right_triangle_25\" ActionTag=\"-600493592\" Tag=\"553\" RotationSkewX=\"225.0000\" RotationSkewY=\"225.0000\" IconVisible=\"False\" LeftMargin=\"56.0000\" RightMargin=\"-56.0000\" TopMargin=\"-49.0000\" BottomMargin=\"-49.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"120.0000\" Y=\"15.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"0\" G=\"77\" B=\"163\" />\n                            <PrePosition X=\"0.9375\" Y=\"0.5000\" />\n                            <PreSize X=\"1.0000\" Y=\"4.2667\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n                        <Position X=\"180.0000\" Y=\"180.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5054\" Y=\"0.4704\" />\n                        <PreSize X=\"0.3594\" Y=\"0.0784\" />\n                        <SingleColor A=\"255\" R=\"0\" G=\"77\" B=\"163\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.4947\" Y=\"3.9859\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titlePaste\" ActionTag=\"-1167440626\" Tag=\"549\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"236.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_paste\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"388.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.5389\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"614.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.6807\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"copy\" ActionTag=\"1458837513\" ZOrder=\"3\" Tag=\"520\" IconVisible=\"False\" TopMargin=\"288.0000\" BottomMargin=\"518.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnCopy\" ActionTag=\"-1963333081\" Tag=\"521\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_40\" ActionTag=\"-1589941153\" Tag=\"537\" IconVisible=\"False\" LeftMargin=\"-130.0897\" RightMargin=\"493.9103\" TopMargin=\"-140.3253\" BottomMargin=\"-146.3253\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"356.1794\" Y=\"382.6505\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_36\" ActionTag=\"2066274906\" Tag=\"525\" IconVisible=\"False\" LeftMargin=\"25.3715\" RightMargin=\"130.8079\" TopMargin=\"13.1390\" BottomMargin=\"69.5115\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" ActionTag=\"-1622872115\" Tag=\"526\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-442082974\" Tag=\"529\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"485683397\" Tag=\"531\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"25.3715\" Y=\"69.5115\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0712\" Y=\"0.1817\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_36_0\" CanEdit=\"False\" ActionTag=\"-1114440579\" Tag=\"533\" IconVisible=\"False\" LeftMargin=\"131.5878\" RightMargin=\"24.5916\" TopMargin=\"72.7092\" BottomMargin=\"9.9413\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" CanEdit=\"False\" ActionTag=\"197724435\" Tag=\"534\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-946532523\" Tag=\"535\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"832528889\" Tag=\"536\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"131.5878\" Y=\"9.9413\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.3694\" Y=\"0.0260\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_28_0\" ActionTag=\"-477594453\" Tag=\"550\" IconVisible=\"False\" LeftMargin=\"215.8450\" RightMargin=\"70.3344\" TopMargin=\"284.7919\" BottomMargin=\"87.8586\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"70.0000\" Y=\"10.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_28_0\" ActionTag=\"-287830773\" Tag=\"551\" RotationSkewX=\"90.0000\" RotationSkewY=\"90.0000\" IconVisible=\"False\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"70.0000\" Y=\"10.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"35.0000\" Y=\"5.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <SingleColor A=\"255\" R=\"0\" G=\"178\" B=\"83\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"250.8450\" Y=\"92.8586\" />\n                        <Scale ScaleX=\"2.0000\" ScaleY=\"2.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.7043\" Y=\"0.2427\" />\n                        <PreSize X=\"0.1965\" Y=\"0.0261\" />\n                        <SingleColor A=\"255\" R=\"0\" G=\"178\" B=\"83\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.4947\" Y=\"3.9859\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleCopy\" ActionTag=\"-907337533\" Tag=\"524\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"254.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_copy\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"370.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.5139\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"518.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.5743\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"unpack\" ActionTag=\"2127441022\" ZOrder=\"4\" Tag=\"89\" IconVisible=\"False\" TopMargin=\"384.0000\" BottomMargin=\"422.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnUnpack\" ActionTag=\"-228576734\" Tag=\"90\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleUnpack\" ActionTag=\"-2082459462\" Tag=\"98\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"180.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_unpack\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"444.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.6167\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_3\" ActionTag=\"1511200133\" Tag=\"88\" IconVisible=\"False\" LeftMargin=\"-132.7136\" RightMargin=\"652.7136\" TopMargin=\"51.8487\" BottomMargin=\"-105.8487\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"200.0000\" Y=\"150.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_10\" ActionTag=\"2055335152\" Tag=\"99\" RotationSkewX=\"30.0000\" IconVisible=\"False\" TopMargin=\"-100.0000\" BottomMargin=\"150.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"100.0000\" />\n                        <AnchorPoint />\n                        <Position Y=\"150.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"1.0000\" />\n                        <PreSize X=\"1.0000\" Y=\"0.6667\" />\n                        <SingleColor A=\"255\" R=\"51\" G=\"51\" B=\"51\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-797320115\" Tag=\"87\" RotationSkewY=\"-60.0000\" IconVisible=\"False\" LeftMargin=\"200.0000\" RightMargin=\"-100.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"100.0000\" Y=\"150.0000\" />\n                        <AnchorPoint ScaleY=\"1.0000\" />\n                        <Position X=\"200.0000\" Y=\"150.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                        <PreSize X=\"0.5000\" Y=\"1.0000\" />\n                        <SingleColor A=\"255\" R=\"150\" G=\"150\" B=\"150\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_10_0\" ActionTag=\"615003097\" Tag=\"103\" RotationSkewX=\"29.9999\" RotationSkewY=\"20.0000\" IconVisible=\"False\" LeftMargin=\"-90.0000\" RightMargin=\"200.0000\" TopMargin=\"-100.0000\" BottomMargin=\"150.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"90.0000\" Y=\"100.0000\" />\n                        <AnchorPoint ScaleX=\"1.0000\" />\n                        <Position Y=\"150.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"1.0000\" />\n                        <PreSize X=\"0.4500\" Y=\"0.6667\" />\n                        <SingleColor A=\"255\" R=\"162\" G=\"162\" B=\"162\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_10_0_0\" ActionTag=\"1592534510\" Tag=\"104\" RotationSkewX=\"29.9999\" RotationSkewY=\"-25.0000\" IconVisible=\"False\" LeftMargin=\"200.0000\" RightMargin=\"-90.0000\" TopMargin=\"-100.0000\" BottomMargin=\"150.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"90.0000\" Y=\"100.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"200.0000\" Y=\"150.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                        <PreSize X=\"0.4500\" Y=\"0.6667\" />\n                        <SingleColor A=\"255\" R=\"183\" G=\"178\" B=\"178\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_10_1\" ActionTag=\"-1384384564\" Tag=\"105\" RotationSkewX=\"10.0000\" IconVisible=\"False\" LeftMargin=\"50.0000\" RightMargin=\"-50.0000\" TopMargin=\"-147.0000\" BottomMargin=\"237.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"60.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"50.0000\" Y=\"237.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.2500\" Y=\"1.5800\" />\n                        <PreSize X=\"1.0000\" Y=\"0.4000\" />\n                        <SingleColor A=\"255\" R=\"135\" G=\"135\" B=\"135\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <Position X=\"67.2864\" Y=\"44.1513\" />\n                    <Scale ScaleX=\"0.2000\" ScaleY=\"0.2000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0935\" Y=\"0.4599\" />\n                    <PreSize X=\"0.2778\" Y=\"1.5625\" />\n                    <SingleColor A=\"255\" R=\"207\" G=\"207\" B=\"207\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"422.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.4678\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"rename\" ActionTag=\"1412152790\" ZOrder=\"5\" Tag=\"381\" IconVisible=\"False\" TopMargin=\"480.0000\" BottomMargin=\"326.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnRename\" ActionTag=\"757640737\" Tag=\"382\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleRename\" ActionTag=\"-295986795\" Tag=\"383\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"170.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_rename\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"454.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.6306\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Text_0\" ActionTag=\"517696897\" Tag=\"393\" IconVisible=\"False\" LeftMargin=\"34.0236\" RightMargin=\"662.9764\" TopMargin=\"6.0000\" BottomMargin=\"6.0000\" FontSize=\"64\" LabelText=\"I\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"23.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"45.5236\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.4000\" ScaleY=\"1.4000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.0632\" Y=\"0.5000\" />\n                    <PreSize X=\"0.0319\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"326.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.3614\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"cut\" ActionTag=\"719063930\" ZOrder=\"6\" Tag=\"554\" IconVisible=\"False\" TopMargin=\"576.0000\" BottomMargin=\"230.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnCut\" ActionTag=\"-1746235388\" Tag=\"555\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_40\" ActionTag=\"-1691651096\" Tag=\"556\" IconVisible=\"False\" LeftMargin=\"-130.0897\" RightMargin=\"493.9103\" TopMargin=\"-140.3253\" BottomMargin=\"-146.3253\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"356.1794\" Y=\"382.6505\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_36\" CanEdit=\"False\" ActionTag=\"2145531031\" Tag=\"557\" IconVisible=\"False\" LeftMargin=\"25.3715\" RightMargin=\"130.8079\" TopMargin=\"13.1390\" BottomMargin=\"69.5115\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" CanEdit=\"False\" ActionTag=\"2059548205\" Tag=\"558\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-654977822\" Tag=\"559\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"-206585989\" Tag=\"560\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"25.3715\" Y=\"69.5115\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0712\" Y=\"0.1817\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.4947\" Y=\"3.9859\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleCut\" ActionTag=\"-481402969\" Tag=\"567\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"301.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_cut\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"323.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.4486\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"0_0\" ActionTag=\"-2069803638\" Tag=\"574\" RotationSkewX=\"-52.6506\" RotationSkewY=\"-52.6472\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"51.1423\" RightMargin=\"631.8577\" TopMargin=\"28.6611\" BottomMargin=\"-16.6611\" FontSize=\"64\" LabelText=\"b\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"37.0000\" Y=\"84.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"_0\" ActionTag=\"-1774036884\" Tag=\"573\" RotationSkewX=\"45.0000\" RotationSkewY=\"45.0000\" IconVisible=\"False\" LeftMargin=\"-25.0000\" RightMargin=\"27.0000\" FontSize=\"64\" LabelText=\"d\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                        <Size X=\"35.0000\" Y=\"84.0000\" />\n                        <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n                        <Position X=\"10.0000\" Y=\"42.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"30\" G=\"144\" B=\"255\" />\n                        <PrePosition X=\"0.2703\" Y=\"0.5000\" />\n                        <PreSize X=\"0.9459\" Y=\"1.0000\" />\n                        <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                        <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                        <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"0_0\" ActionTag=\"-1503496564\" Tag=\"575\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"-0.0007\" RightMargin=\"22.0007\" TopMargin=\"-29.0000\" BottomMargin=\"29.0000\" FontSize=\"64\" LabelText=\"l\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                        <Size X=\"15.0000\" Y=\"84.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"_0\" ActionTag=\"1934593569\" Tag=\"576\" RotationSkewX=\"45.0000\" RotationSkewY=\"45.0000\" IconVisible=\"False\" LeftMargin=\"-15.0000\" RightMargin=\"15.0000\" TopMargin=\"-1.4067\" BottomMargin=\"1.4067\" FontSize=\"64\" LabelText=\"l\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                            <Size X=\"15.0000\" Y=\"84.0000\" />\n                            <AnchorPoint ScaleX=\"1.0000\" />\n                            <Position Y=\"1.4067\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"187\" G=\"187\" B=\"187\" />\n                            <PrePosition Y=\"0.0167\" />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleY=\"0.5000\" />\n                        <Position X=\"-0.0007\" Y=\"71.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"229\" G=\"229\" B=\"229\" />\n                        <PrePosition X=\"0.0000\" Y=\"0.8452\" />\n                        <PreSize X=\"0.4054\" Y=\"1.0000\" />\n                        <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                        <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                        <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"51.1423\" Y=\"25.3389\" />\n                    <Scale ScaleX=\"0.6000\" ScaleY=\"0.6000\" />\n                    <CColor A=\"255\" R=\"30\" G=\"144\" B=\"255\" />\n                    <PrePosition X=\"0.0710\" Y=\"0.2639\" />\n                    <PreSize X=\"0.0514\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"230.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.2550\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"delete\" ActionTag=\"-677530050\" ZOrder=\"7\" Tag=\"496\" IconVisible=\"False\" TopMargin=\"672.0000\" BottomMargin=\"134.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnDelete\" ActionTag=\"-531707876\" Tag=\"519\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_36_1\" ActionTag=\"1029675219\" Tag=\"568\" IconVisible=\"False\" LeftMargin=\"-52.0000\" RightMargin=\"572.0000\" TopMargin=\"-99.0000\" BottomMargin=\"-105.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"200.0000\" Y=\"300.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_37\" ActionTag=\"2145282953\" Tag=\"569\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"180.0000\" Y=\"280.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"10.0000\" Y=\"10.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                        <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                        <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"1699214789\" Tag=\"570\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                        <Size X=\"128.0000\" Y=\"128.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"200.0000\" Y=\"300.0000\" />\n                        <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                        <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                        <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                        <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                        <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                        <BlendFunc Src=\"1\" Dst=\"771\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"-1828350060\" Tag=\"571\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                        <Size X=\"128.0000\" Y=\"128.0000\" />\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"171.0000\" Y=\"271.0000\" />\n                        <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                        <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                        <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                        <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                        <BlendFunc Src=\"1\" Dst=\"771\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_28\" ActionTag=\"-1673288170\" Tag=\"514\" RotationSkewX=\"45.0000\" RotationSkewY=\"45.0000\" IconVisible=\"False\" LeftMargin=\"61.8137\" RightMargin=\"68.1863\" TopMargin=\"156.8250\" BottomMargin=\"133.1750\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"70.0000\" Y=\"10.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_28_0\" ActionTag=\"346682984\" Tag=\"516\" RotationSkewX=\"90.0000\" RotationSkewY=\"90.0000\" IconVisible=\"False\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"70.0000\" Y=\"10.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"35.0000\" Y=\"5.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <SingleColor A=\"255\" R=\"177\" G=\"77\" B=\"77\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"96.8137\" Y=\"138.1750\" />\n                        <Scale ScaleX=\"3.0000\" ScaleY=\"3.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.4841\" Y=\"0.4606\" />\n                        <PreSize X=\"0.3500\" Y=\"0.0333\" />\n                        <SingleColor A=\"255\" R=\"177\" G=\"77\" B=\"77\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.2778\" Y=\"3.1250\" />\n                    <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleDelete\" ActionTag=\"1443906044\" Tag=\"501\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"214.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_delete\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"410.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.5694\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"134.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.1486\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"sendto\" ActionTag=\"1125643210\" ZOrder=\"8\" Tag=\"633\" IconVisible=\"False\" TopMargin=\"768.0000\" BottomMargin=\"38.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnSendTo\" ActionTag=\"247155124\" Tag=\"634\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_40\" ActionTag=\"506086123\" Tag=\"635\" IconVisible=\"False\" LeftMargin=\"-130.0897\" RightMargin=\"493.9103\" TopMargin=\"-140.3253\" BottomMargin=\"-146.3253\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"356.1794\" Y=\"382.6505\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_36\" ActionTag=\"-682988043\" Tag=\"636\" IconVisible=\"False\" LeftMargin=\"68.0342\" RightMargin=\"88.1452\" TopMargin=\"39.6017\" BottomMargin=\"43.0488\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"300.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_37\" CanEdit=\"False\" ActionTag=\"-2104484166\" Tag=\"637\" IconVisible=\"False\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"180.0000\" Y=\"280.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"10.0000\" Y=\"10.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0500\" Y=\"0.0333\" />\n                            <PreSize X=\"0.9000\" Y=\"0.9333\" />\n                            <SingleColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15\" CanEdit=\"False\" ActionTag=\"-1813842658\" Tag=\"638\" RotationSkewX=\"180.0000\" RotationSkewY=\"180.0000\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"200.0000\" RightMargin=\"-128.0000\" TopMargin=\"-128.0000\" BottomMargin=\"300.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint />\n                            <Position X=\"200.0000\" Y=\"300.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"right_triangle_15_0\" CanEdit=\"False\" ActionTag=\"1697625765\" Tag=\"639\" IconVisible=\"False\" LeftMargin=\"107.0000\" RightMargin=\"-35.0000\" TopMargin=\"-35.0000\" BottomMargin=\"207.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"171.0000\" Y=\"271.0000\" />\n                            <Scale ScaleX=\"0.4500\" ScaleY=\"0.4500\" />\n                            <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                            <PrePosition X=\"0.8550\" Y=\"0.9033\" />\n                            <PreSize X=\"0.6400\" Y=\"0.4267\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"68.0342\" Y=\"43.0488\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.1910\" Y=\"0.1125\" />\n                        <PreSize X=\"0.5615\" Y=\"0.7840\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_49\" ActionTag=\"-698441579\" Tag=\"644\" IconVisible=\"False\" LeftMargin=\"128.2952\" RightMargin=\"99.8842\" TopMargin=\"171.3093\" BottomMargin=\"181.3412\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"128.0000\" Y=\"30.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"right_triangle_25\" ActionTag=\"-1605088766\" Tag=\"645\" RotationSkewX=\"225.0000\" RotationSkewY=\"225.0000\" IconVisible=\"False\" LeftMargin=\"56.0000\" RightMargin=\"-56.0000\" TopMargin=\"-49.0000\" BottomMargin=\"-49.0000\" ctype=\"SpriteObjectData\">\n                            <Size X=\"128.0000\" Y=\"128.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"120.0000\" Y=\"15.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"165\" B=\"0\" />\n                            <PrePosition X=\"0.9375\" Y=\"0.5000\" />\n                            <PreSize X=\"1.0000\" Y=\"4.2667\" />\n                            <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                            <BlendFunc Src=\"1\" Dst=\"771\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n                        <Position X=\"256.2952\" Y=\"196.3412\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.7196\" Y=\"0.5131\" />\n                        <PreSize X=\"0.3594\" Y=\"0.0784\" />\n                        <SingleColor A=\"255\" R=\"255\" G=\"165\" B=\"0\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"48.0000\" Y=\"45.0000\" />\n                    <Scale ScaleX=\"0.2200\" ScaleY=\"0.2200\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0667\" Y=\"0.4688\" />\n                    <PreSize X=\"0.4947\" Y=\"3.9859\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleSendTo\" ActionTag=\"717103601\" Tag=\"646\" IconVisible=\"False\" VerticalEdge=\"TopEdge\" LeftMargin=\"96.0000\" RightMargin=\"195.0000\" TopMargin=\"8.0000\" BottomMargin=\"4.0000\" FontSize=\"64\" LabelText=\"filemgr_sendto\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"429.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"96.0000\" Y=\"46.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1333\" Y=\"0.4792\" />\n                    <PreSize X=\"0.5958\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"38.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.0421\" />\n                <PreSize X=\"1.0000\" Y=\"0.1064\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"0.9020\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/GameMenu.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"GameMenu\" Type=\"Layer\" ID=\"efdda4e0-63f0-41c1-ab04-41466bb5c117\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"6\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"130.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"handler\" ActionTag=\"-763993771\" Alpha=\"38\" Tag=\"8\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"672.0000\" TopMargin=\"-48.0000\" BottomMargin=\"130.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"48\" Scale9Height=\"48\" ctype=\"PanelObjectData\">\n            <Size X=\"48.0000\" Y=\"48.0000\" />\n            <AnchorPoint />\n            <Position X=\"672.0000\" Y=\"130.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9333\" Y=\"1.0000\" />\n            <PreSize X=\"0.0667\" Y=\"0.3200\" />\n            <FileData Type=\"Normal\" Path=\"img/menu_handler.png\" Plist=\"\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"1202708352\" Tag=\"47\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" PercentHeightEnable=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" BottomMargin=\"-130.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"260.0000\" />\n            <AnchorPoint ScaleY=\"1.0000\" />\n            <Position Y=\"130.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"1.0000\" />\n            <PreSize X=\"1.0000\" Y=\"2.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-1649466821\" Tag=\"9\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"130.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"btn_gamemenu\" ActionTag=\"-1047771991\" Tag=\"10\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" RightMargin=\"576.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"144.0000\" Y=\"130.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Image_1\" ActionTag=\"-165536338\" Tag=\"12\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"40.0000\" RightMargin=\"40.0000\" TopMargin=\"33.0000\" BottomMargin=\"33.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"64.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5333\" Y=\"0.5333\" />\n                    <FileData Type=\"Normal\" Path=\"img/menu_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.2000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"btn_window\" ActionTag=\"-2083979054\" Tag=\"28\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" LeftMargin=\"144.0000\" RightMargin=\"432.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"144.0000\" Y=\"130.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Image_4_8\" ActionTag=\"-1634530225\" Tag=\"29\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"36.0000\" RightMargin=\"36.0000\" TopMargin=\"29.0000\" BottomMargin=\"29.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"72.0000\" Y=\"72.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.6000\" Y=\"0.5538\" />\n                    <FileData Type=\"Normal\" Path=\"img/windows_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"144.0000\" Y=\"65.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.2000\" Y=\"0.5000\" />\n                <PreSize X=\"0.2000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"btn_mousemode\" ActionTag=\"-1674973713\" Tag=\"13\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" LeftMargin=\"288.0000\" RightMargin=\"288.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"144.0000\" Y=\"130.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"icon_touch\" ActionTag=\"164483739\" Tag=\"22\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"40.0000\" RightMargin=\"40.0000\" TopMargin=\"33.0000\" BottomMargin=\"33.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"64.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5333\" Y=\"0.4923\" />\n                    <FileData Type=\"Normal\" Path=\"img/touch_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"icon_mouse\" ActionTag=\"344908074\" Tag=\"23\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"40.0000\" RightMargin=\"40.0000\" TopMargin=\"33.0000\" BottomMargin=\"33.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"64.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5333\" Y=\"0.4923\" />\n                    <FileData Type=\"Normal\" Path=\"img/mouse_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"288.0000\" Y=\"65.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.4000\" Y=\"0.5000\" />\n                <PreSize X=\"0.2000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"btn_keyboard\" ActionTag=\"-915984177\" Tag=\"24\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" LeftMargin=\"432.0000\" RightMargin=\"144.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"144.0000\" Y=\"130.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Image_4\" ActionTag=\"-1525681453\" Tag=\"25\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"40.0000\" RightMargin=\"40.0000\" TopMargin=\"38.0000\" BottomMargin=\"47.0000\" Scale9Width=\"64\" Scale9Height=\"45\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"64.0000\" Y=\"45.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.4000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5333\" Y=\"0.3462\" />\n                    <FileData Type=\"Normal\" Path=\"img/keyboard_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"432.0000\" Y=\"65.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.6000\" Y=\"0.5000\" />\n                <PreSize X=\"0.2000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"btn_exit\" ActionTag=\"680601329\" Tag=\"26\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" LeftMargin=\"575.9999\" RightMargin=\"0.0001\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"144.0000\" Y=\"130.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"1346961464\" Tag=\"27\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"40.0000\" RightMargin=\"40.0000\" TopMargin=\"33.0000\" BottomMargin=\"33.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"64.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"65.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5333\" Y=\"0.4923\" />\n                    <FileData Type=\"Normal\" Path=\"img/exit_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"575.9999\" Y=\"65.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.8000\" Y=\"0.5000\" />\n                <PreSize X=\"0.2000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.2778\" Y=\"1.3333\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_3\" ActionTag=\"-450460497\" Tag=\"14\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" BottomMargin=\"127.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"3.0000\" />\n            <AnchorPoint ScaleY=\"1.0000\" />\n            <Position Y=\"130.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"1.0000\" />\n            <PreSize X=\"1.0000\" Y=\"0.0200\" />\n            <SingleColor A=\"255\" R=\"161\" G=\"161\" B=\"161\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/KeySelect.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"KeySelect\" Type=\"Layer\" ID=\"18132b85-255a-4049-bb5b-4343880f3a4c\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"22\" ctype=\"GameLayerObjectData\">\n        <Size X=\"1280.0000\" Y=\"720.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"-457238893\" Tag=\"23\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"389.9991\" RightMargin=\"390.0009\" TopMargin=\"260.0005\" BottomMargin=\"259.9995\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"500.0000\" Y=\"200.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Text_1\" ActionTag=\"-1266043054\" Tag=\"25\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"38.0000\" RightMargin=\"38.0000\" BottomMargin=\"137.0000\" FontSize=\"48\" LabelText=\"press_key_or_select\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"424.0000\" Y=\"63.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"1.0000\" />\n                <Position X=\"250.0000\" Y=\"200.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"1.0000\" />\n                <PreSize X=\"0.8480\" Y=\"0.3150\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-2042266371\" Tag=\"24\" IconVisible=\"False\" RightMargin=\"300.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"200.0000\" Y=\"200.0000\" />\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.4000\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"639.9991\" Y=\"359.9995\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"0.3906\" Y=\"0.2778\" />\n            <SingleColor A=\"255\" R=\"109\" G=\"109\" B=\"109\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/ListItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"ListItem\" Type=\"Layer\" ID=\"e5c95844-665a-46e4-afbd-60543ed667b5\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"57\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"item\" ActionTag=\"18966105\" Tag=\"59\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"64\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"720.0000\" Y=\"96.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"360.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"0.0014\" Y=\"0.0104\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <TextColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/ListView.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"ListView\" Type=\"Layer\" ID=\"c3c5322b-fc57-4810-92d1-7bc184317759\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"12\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"960.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"list\" ActionTag=\"1488899371\" Tag=\"13\" IconVisible=\"False\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" IsBounceEnabled=\"True\" ScrollDirectionType=\"0\" ItemMargin=\"11\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n            <Size X=\"720.0000\" Y=\"960.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MainFileSelector.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MainFileSelector\" Type=\"Layer\" ID=\"203fa2aa-590f-4f65-83d4-2c4dd4c4af72\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"122\" ctype=\"GameLayerObjectData\">\n        <Size X=\"1280.0000\" Y=\"720.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"recentList\" ActionTag=\"-501046127\" Tag=\"124\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"LeftEdge\" RightMargin=\"646.4000\" TouchEnable=\"True\" ClipAble=\"True\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" IsBounceEnabled=\"True\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n            <Size X=\"633.6000\" Y=\"720.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.4950\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"fileList\" ActionTag=\"-1099973759\" Tag=\"126\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" LeftMargin=\"646.4000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"633.6000\" Y=\"720.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" />\n            <Position X=\"1280.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"1.0000\" />\n            <PreSize X=\"0.4950\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"942186096\" Tag=\"25\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" LeftMargin=\"633.6000\" RightMargin=\"633.6000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"12.8000\" Y=\"720.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" />\n            <Position X=\"640.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" />\n            <PreSize X=\"0.0100\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"121\" G=\"121\" B=\"121\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MediaPlayerBody.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MediaPlayerBody\" Type=\"Layer\" ID=\"fa47b835-295e-4e57-a27a-597467d49fab\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"640.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Overlay\" ActionTag=\"1050439757\" Tag=\"76\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"960.0000\" Y=\"640.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.2083\" Y=\"0.3125\" />\n            <SingleColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"OSD\" ActionTag=\"-1094385537\" Tag=\"42\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"288.0000\" RightMargin=\"288.0000\" TopMargin=\"224.0000\" BottomMargin=\"224.0000\" ClipAble=\"False\" BackColorAlpha=\"191\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"384.0000\" Y=\"192.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"OSDText\" ActionTag=\"1094389482\" Tag=\"41\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"45.5000\" RightMargin=\"45.5000\" TopMargin=\"54.0000\" BottomMargin=\"54.0000\" FontSize=\"64\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"293.0000\" Y=\"84.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"192.0000\" Y=\"96.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"0.7630\" Y=\"0.4375\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"480.0000\" Y=\"320.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"0.4000\" Y=\"0.3000\" />\n            <SingleColor A=\"255\" R=\"32\" G=\"32\" B=\"32\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MediaPlayerFoot.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MediaPlayerFoot\" Type=\"Layer\" ID=\"ad9190bd-3a12-4ad9-8901-8daca7c1d3ec\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"640.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"ControlBar\" ActionTag=\"832483805\" Tag=\"38\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" TopMargin=\"460.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"960.0000\" Y=\"180.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"PlayBtn\" ActionTag=\"-320188485\" Tag=\"44\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"390.0000\" RightMargin=\"390.0000\" TouchEnable=\"True\" ClipAble=\"False\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"180.0000\" Y=\"180.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"PlayBtnNormal\" ActionTag=\"-795481223\" Tag=\"46\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"20.0000\" RightMargin=\"20.0000\" TopMargin=\"20.0000\" BottomMargin=\"20.0000\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" Scale9Width=\"72\" Scale9Height=\"72\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"140.0000\" Y=\"140.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"90.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.3600\" Y=\"0.3600\" />\n                    <FileData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"PlayBtnPress\" Visible=\"False\" ActionTag=\"1230712086\" Tag=\"50\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"20.0000\" RightMargin=\"20.0000\" TopMargin=\"20.0000\" BottomMargin=\"20.0000\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" Scale9Width=\"72\" Scale9Height=\"72\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"140.0000\" Y=\"140.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"90.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.3600\" Y=\"0.3600\" />\n                    <FileData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"PlayIconNormal\" Visible=\"False\" ActionTag=\"454087153\" Tag=\"47\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"70.0000\" RightMargin=\"50.0000\" TopMargin=\"60.0000\" BottomMargin=\"60.0000\" Scale9Width=\"256\" Scale9Height=\"256\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"72.0000\" Y=\"72.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"99.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5500\" Y=\"0.5000\" />\n                    <PreSize X=\"0.4000\" Y=\"0.4000\" />\n                    <FileData Type=\"Normal\" Path=\"img/triangle.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"PlayIconPress\" Visible=\"False\" ActionTag=\"2025361399\" Tag=\"51\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"70.0000\" RightMargin=\"50.0000\" TopMargin=\"60.0000\" BottomMargin=\"60.0000\" Scale9Width=\"256\" Scale9Height=\"256\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"72.0000\" Y=\"72.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"99.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                    <PrePosition X=\"0.5500\" Y=\"0.5000\" />\n                    <PreSize X=\"0.4000\" Y=\"0.4000\" />\n                    <FileData Type=\"Normal\" Path=\"img/triangle.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"PauseIconNormal\" ActionTag=\"-144474216\" Tag=\"53\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"69.9872\" RightMargin=\"109.9808\" TopMargin=\"70.0000\" BottomMargin=\"70.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"20.0000\" Y=\"60.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"PauseIconNormal_0\" ActionTag=\"-1425671774\" Tag=\"54\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"40.0000\" RightMargin=\"-40.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                        <Size X=\"20.0000\" Y=\"60.0000\" />\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"50.0000\" Y=\"30.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"2.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.1000\" Y=\"0.3000\" />\n                        <SingleColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.4000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1000\" Y=\"0.3000\" />\n                    <SingleColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"PauseIconPress\" ActionTag=\"-2107513274\" Tag=\"55\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"69.9872\" RightMargin=\"109.9808\" TopMargin=\"70.0000\" BottomMargin=\"70.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"20.0000\" Y=\"60.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"PauseIconNormal_0\" ActionTag=\"648398234\" Tag=\"56\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"40.0000\" RightMargin=\"-40.0000\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                        <Size X=\"20.0000\" Y=\"60.0000\" />\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"50.0000\" Y=\"30.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"2.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.1000\" Y=\"0.3000\" />\n                        <SingleColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"72.0000\" Y=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                    <PrePosition X=\"0.4000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1000\" Y=\"0.3000\" />\n                    <SingleColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"480.0000\" Y=\"90.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"0.1875\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"0.2813\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MediaPlayerNavi.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MediaPlayerNavi\" Type=\"Layer\" ID=\"1579a466-7977-464e-b402-ea4d21282e25\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"640.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"NaviBar\" ActionTag=\"210411868\" Tag=\"10\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" BottomMargin=\"490.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"960.0000\" Y=\"150.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Title\" ActionTag=\"-2067758255\" Tag=\"11\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"80.0000\" RightMargin=\"80.0000\" TopMargin=\"20.0000\" BottomMargin=\"58.0000\" StretchWidthEnable=\"True\" IsCustomSize=\"True\" FontSize=\"40\" LabelText=\"Text Label\" HorizontalAlignmentType=\"HT_Center\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"800.0000\" Y=\"52.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"1.0000\" />\n                <Position X=\"480.0000\" Y=\"130.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"1.0000\" />\n                <PreSize X=\"0.1521\" Y=\"0.4200\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Timeline\" ActionTag=\"-1226225042\" Tag=\"12\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"20.0000\" RightMargin=\"20.0000\" TopMargin=\"93.0000\" BottomMargin=\"45.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" PercentInfo=\"50\" ctype=\"SliderObjectData\">\n                <Size X=\"920.0000\" Y=\"20.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"480.0000\" Y=\"55.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1250\" />\n                <PreSize X=\"0.9583\" Y=\"0.1538\" />\n                <BackGroundData Type=\"Default\" Path=\"Default/Slider_Back.png\" Plist=\"\" />\n                <ProgressBarData Type=\"Default\" Path=\"Default/Slider_PressBar.png\" Plist=\"\" />\n                <BallNormalData Type=\"Default\" Path=\"Default/SliderNode_Normal.png\" Plist=\"\" />\n                <BallPressedData Type=\"Default\" Path=\"Default/SliderNode_Press.png\" Plist=\"\" />\n                <BallDisabledData Type=\"Default\" Path=\"Default/SliderNode_Disable.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Back\" ActionTag=\"259485318\" Tag=\"37\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"20.0000\" RightMargin=\"620.0000\" BottomMargin=\"20.0000\" TouchEnable=\"True\" FontSize=\"18\" Scale9Width=\"64\" Scale9Height=\"64\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"110.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0278\" Y=\"0.5000\" />\n                <PreSize X=\"0.1111\" Y=\"0.8333\" />\n                <TextColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"PlayTime\" ActionTag=\"1409097770\" Tag=\"39\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"20.0000\" RightMargin=\"794.0000\" TopMargin=\"103.0000\" BottomMargin=\"5.0000\" FontSize=\"32\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"146.0000\" Y=\"42.0000\" />\n                <AnchorPoint />\n                <Position X=\"20.0000\" Y=\"5.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0208\" Y=\"0.0333\" />\n                <PreSize X=\"0.1521\" Y=\"0.2800\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"RemainTime\" ActionTag=\"-1091607380\" Tag=\"40\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"794.0000\" RightMargin=\"20.0000\" TopMargin=\"98.0000\" BottomMargin=\"5.0000\" FontSize=\"32\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"146.0000\" Y=\"42.0000\" />\n                <AnchorPoint ScaleX=\"1.0000\" />\n                <Position X=\"940.0000\" Y=\"5.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0521\" Y=\"-0.0667\" />\n                <PreSize X=\"0.1521\" Y=\"0.2800\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position Y=\"490.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"0.7656\" />\n            <PreSize X=\"1.0000\" Y=\"0.2344\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MenuList.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MenuList\" Type=\"Layer\" ID=\"2f5502d5-e035-4193-8733-5dee9cc4863c\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"97\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"600.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Layout_1\" ActionTag=\"-1483003744\" Tag=\"58\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"600.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"useless_0\" ActionTag=\"355642564\" VisibleForFrame=\"False\" Tag=\"27\" IconVisible=\"False\" TopMargin=\"-72.0000\" BottomMargin=\"576.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"96.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"btnRotate\" ActionTag=\"-2093853760\" Tag=\"28\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"-846504098\" Tag=\"34\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"7.5000\" RightMargin=\"627.5000\" TopMargin=\"5.5000\" BottomMargin=\"5.5000\" LeftEage=\"21\" RightEage=\"21\" TopEage=\"19\" BottomEage=\"20\" Scale9OriginX=\"21\" Scale9OriginY=\"19\" Scale9Width=\"22\" Scale9Height=\"25\" ctype=\"ImageViewObjectData\">\n                <Size X=\"85.0000\" Y=\"85.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"50.0000\" Y=\"48.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                <PreSize X=\"0.1181\" Y=\"0.8854\" />\n                <FileData Type=\"Normal\" Path=\"img/circle_arrow.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"titleRotate\" ActionTag=\"-1854333013\" Tag=\"30\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"224.0000\" TopMargin=\"12.0000\" BottomMargin=\"12.0000\" FontSize=\"72\" LabelText=\"menu_rotate\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                <Size X=\"396.0000\" Y=\"72.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"100.0000\" Y=\"48.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                <PreSize X=\"0.5500\" Y=\"0.7500\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position Y=\"576.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"0.9600\" />\n            <PreSize X=\"1.0000\" Y=\"0.1600\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"menulist\" ActionTag=\"255385562\" Tag=\"44\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TopMargin=\"160.0000\" BottomMargin=\"160.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n            <Size X=\"720.0000\" Y=\"280.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"globalPref\" ActionTag=\"1722242325\" Tag=\"46\" IconVisible=\"False\" BottomMargin=\"576.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnGlobalPref\" ActionTag=\"1659990628\" Tag=\"45\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"-82135101\" Tag=\"42\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"11.0000\" RightMargin=\"631.0000\" TopMargin=\"9.0000\" BottomMargin=\"9.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"78.0000\" Y=\"78.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1083\" Y=\"0.8125\" />\n                    <FileData Type=\"Normal\" Path=\"img/syssetting_btn_ff.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleGlobalPref\" ActionTag=\"962638723\" Tag=\"38\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"-178.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_global_preference\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"798.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"1.1083\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"672.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.8571\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"newLocalPref\" ActionTag=\"-131264903\" ZOrder=\"1\" Tag=\"74\" IconVisible=\"False\" TopMargin=\"96.0000\" BottomMargin=\"480.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnNewLocalPref\" ActionTag=\"-1717897800\" Tag=\"75\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"-1090496650\" Tag=\"76\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"11.0000\" RightMargin=\"631.0000\" TopMargin=\"9.0000\" BottomMargin=\"9.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"78.0000\" Y=\"78.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1083\" Y=\"0.8125\" />\n                    <FileData Type=\"Normal\" Path=\"img/syssetting_btn_ff.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Text_8\" ActionTag=\"-1276047011\" Tag=\"82\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"56.3752\" RightMargin=\"628.6248\" TopMargin=\"21.1872\" BottomMargin=\"-9.1872\" FontSize=\"64\" LabelText=\"+\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"35.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"73.8752\" Y=\"32.8128\" />\n                    <Scale ScaleX=\"1.5000\" ScaleY=\"1.5000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.1026\" Y=\"0.3418\" />\n                    <PreSize X=\"0.0486\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleNewLocalPref\" ActionTag=\"-1180841830\" Tag=\"77\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"-83.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_new_local_pref\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"703.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.9764\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"576.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.7143\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"localPref\" ActionTag=\"704539655\" ZOrder=\"2\" Tag=\"78\" IconVisible=\"False\" TopMargin=\"192.0000\" BottomMargin=\"384.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnLocalPref\" ActionTag=\"1643073024\" Tag=\"79\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"1214326439\" Tag=\"80\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"11.0000\" RightMargin=\"631.0000\" TopMargin=\"9.0000\" BottomMargin=\"9.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"78.0000\" Y=\"78.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1083\" Y=\"0.8125\" />\n                    <FileData Type=\"Normal\" Path=\"img/syssetting_btn_ff.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Text_8_0\" ActionTag=\"1679538103\" Tag=\"83\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"58.6921\" RightMargin=\"628.3079\" TopMargin=\"20.3424\" BottomMargin=\"-8.3424\" FontSize=\"64\" LabelText=\"L\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"33.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"75.1921\" Y=\"33.6576\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.1044\" Y=\"0.3506\" />\n                    <PreSize X=\"0.0458\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleLocalPref\" ActionTag=\"-1682152072\" Tag=\"81\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"82.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_local_pref\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"538.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.7472\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"480.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.5714\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"newFolder\" ActionTag=\"-795689569\" ZOrder=\"3\" Tag=\"42\" IconVisible=\"False\" TopMargin=\"288.0000\" BottomMargin=\"384.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnNewFolder\" ActionTag=\"-695067171\" Tag=\"43\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_11\" ActionTag=\"-594190038\" Tag=\"152\" IconVisible=\"False\" LeftMargin=\"15.0000\" RightMargin=\"638.5888\" TopMargin=\"35.0500\" BottomMargin=\"10.9500\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"66.4112\" Y=\"50.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_12\" ActionTag=\"-1414365160\" Tag=\"154\" IconVisible=\"False\" LeftMargin=\"8.8975\" RightMargin=\"32.4112\" TopMargin=\"-8.7769\" BottomMargin=\"25.7075\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                        <Size X=\"25.1025\" Y=\"33.0694\" />\n                        <AnchorPoint ScaleX=\"1.0000\" />\n                        <Position X=\"34.0000\" Y=\"25.7075\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5120\" Y=\"0.5141\" />\n                        <PreSize X=\"0.3780\" Y=\"0.6614\" />\n                        <SingleColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"right_triangle_1\" ActionTag=\"-1499925675\" Tag=\"153\" IconVisible=\"False\" LeftMargin=\"34.0000\" RightMargin=\"-95.5888\" TopMargin=\"-128.0000\" BottomMargin=\"50.0000\" ctype=\"SpriteObjectData\">\n                        <Size X=\"128.0000\" Y=\"128.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"34.0000\" Y=\"50.0000\" />\n                        <Scale ScaleX=\"0.0694\" ScaleY=\"0.0694\" />\n                        <CColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n                        <PrePosition X=\"0.5120\" Y=\"1.0000\" />\n                        <PreSize X=\"1.9274\" Y=\"2.5600\" />\n                        <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                        <BlendFunc Src=\"1\" Dst=\"771\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"right_triangle_1_0\" ActionTag=\"1933045678\" Tag=\"155\" RotationSkewX=\"-90.0000\" RotationSkewY=\"-90.0000\" IconVisible=\"False\" LeftMargin=\"9.0000\" RightMargin=\"-70.5888\" TopMargin=\"-128.0000\" BottomMargin=\"50.0000\" ctype=\"SpriteObjectData\">\n                        <Size X=\"128.0000\" Y=\"128.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"9.0000\" Y=\"50.0000\" />\n                        <Scale ScaleX=\"0.0694\" ScaleY=\"0.0694\" />\n                        <CColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n                        <PrePosition X=\"0.1355\" Y=\"1.0000\" />\n                        <PreSize X=\"1.9274\" Y=\"2.5600\" />\n                        <FileData Type=\"Normal\" Path=\"img/right_triangle.png\" Plist=\"\" />\n                        <BlendFunc Src=\"1\" Dst=\"771\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_11_0\" ActionTag=\"1089377195\" Tag=\"156\" RotationSkewX=\"-10.0000\" IconVisible=\"False\" TopMargin=\"5.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"66.4112\" Y=\"45.0000\" />\n                        <AnchorPoint />\n                        <Position />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition />\n                        <PreSize X=\"1.0000\" Y=\"0.9000\" />\n                        <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"15.0000\" Y=\"10.9500\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0208\" Y=\"0.1141\" />\n                    <PreSize X=\"0.0922\" Y=\"0.5208\" />\n                    <SingleColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Text_8\" ActionTag=\"687147959\" Tag=\"45\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"56.3752\" RightMargin=\"628.6248\" TopMargin=\"21.1872\" BottomMargin=\"-9.1872\" FontSize=\"64\" LabelText=\"+\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"35.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"73.8752\" Y=\"32.8128\" />\n                    <Scale ScaleX=\"1.5000\" ScaleY=\"1.5000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.1026\" Y=\"0.3418\" />\n                    <PreSize X=\"0.0486\" Y=\"0.8750\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleNewFolder\" ActionTag=\"-746684841\" Tag=\"46\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"41.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_new_folder\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"579.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.8042\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"384.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.5000\" />\n                <PreSize X=\"1.0000\" Y=\"0.1250\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"repack\" ActionTag=\"-378099458\" ZOrder=\"4\" Tag=\"182\" IconVisible=\"False\" TopMargin=\"288.0000\" BottomMargin=\"288.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnRepack\" ActionTag=\"619244246\" Tag=\"183\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_3\" ActionTag=\"-1089538273\" Tag=\"188\" IconVisible=\"False\" LeftMargin=\"-50.0000\" RightMargin=\"570.0000\" TopMargin=\"-52.0000\" BottomMargin=\"-52.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"200.0000\" Y=\"200.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-593635235\" Tag=\"187\" IconVisible=\"False\" TopMargin=\"140.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"50.0000\" />\n                        <AnchorPoint />\n                        <Position Y=\"10.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"0.0500\" />\n                        <PreSize X=\"1.0000\" Y=\"0.2500\" />\n                        <SingleColor A=\"255\" R=\"0\" G=\"165\" B=\"44\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_2_0\" ActionTag=\"-1599493087\" Tag=\"189\" IconVisible=\"False\" TopMargin=\"75.0000\" BottomMargin=\"75.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"50.0000\" />\n                        <AnchorPoint />\n                        <Position Y=\"75.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"0.3750\" />\n                        <PreSize X=\"1.0000\" Y=\"0.2500\" />\n                        <SingleColor A=\"255\" R=\"71\" G=\"124\" B=\"255\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_2_1\" ActionTag=\"-773389432\" Tag=\"190\" IconVisible=\"False\" TopMargin=\"10.0000\" BottomMargin=\"140.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"200.0000\" Y=\"50.0000\" />\n                        <AnchorPoint />\n                        <Position Y=\"140.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"0.7000\" />\n                        <PreSize X=\"1.0000\" Y=\"0.2500\" />\n                        <SingleColor A=\"255\" R=\"182\" G=\"0\" B=\"0\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_6\" ActionTag=\"-1280202489\" Tag=\"191\" IconVisible=\"False\" LeftMargin=\"80.0000\" RightMargin=\"80.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"40.0000\" Y=\"180.0000\" />\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"100.0000\" Y=\"100.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.2000\" Y=\"0.9000\" />\n                        <SingleColor A=\"255\" R=\"255\" G=\"189\" B=\"44\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"0.3600\" ScaleY=\"0.3600\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.2778\" Y=\"2.0833\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleRepack\" ActionTag=\"1831073566\" Tag=\"186\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"-82.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_archive_repack\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"702.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.9750\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"288.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.4286\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"help\" ActionTag=\"2030815397\" ZOrder=\"5\" Tag=\"399\" IconVisible=\"False\" TopMargin=\"384.0000\" BottomMargin=\"192.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnHelp\" ActionTag=\"1740874877\" Tag=\"400\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4\" ActionTag=\"-1721078367\" Tag=\"401\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"10.0000\" RightMargin=\"630.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"80.0000\" Y=\"80.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1111\" Y=\"0.8333\" />\n                    <FileData Type=\"Normal\" Path=\"img/about_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleHelp\" ActionTag=\"-546953597\" Tag=\"402\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"261.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_help\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"359.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.4986\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"192.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.2857\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"about\" ActionTag=\"1241537713\" ZOrder=\"6\" Tag=\"65\" IconVisible=\"False\" TopMargin=\"480.0000\" BottomMargin=\"96.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnAbout\" ActionTag=\"-356846176\" Tag=\"66\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4\" ActionTag=\"1536752089\" Tag=\"69\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"10.0000\" RightMargin=\"630.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"80.0000\" Y=\"80.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1111\" Y=\"0.8333\" />\n                    <FileData Type=\"Normal\" Path=\"img/about_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleAbout\" ActionTag=\"652205002\" Tag=\"68\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"212.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_about\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"408.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5667\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"96.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.1429\" />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"exit\" ActionTag=\"610831709\" ZOrder=\"7\" Tag=\"70\" IconVisible=\"False\" TopMargin=\"576.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"720.0000\" Y=\"96.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btnExit\" ActionTag=\"-1752648075\" Tag=\"71\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"720.0000\" Y=\"96.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Image_4_6\" ActionTag=\"1820919453\" Tag=\"72\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"10.0000\" RightMargin=\"630.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                    <Size X=\"80.0000\" Y=\"80.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"50.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.0694\" Y=\"0.5000\" />\n                    <PreSize X=\"0.1111\" Y=\"0.8333\" />\n                    <FileData Type=\"Normal\" Path=\"img/exit_icon.png\" Plist=\"\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"titleExit\" ActionTag=\"-889510232\" Tag=\"73\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" LeftMargin=\"100.0000\" RightMargin=\"282.0000\" TopMargin=\"1.0000\" BottomMargin=\"1.0000\" FontSize=\"72\" LabelText=\"menu_exit\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"338.0000\" Y=\"94.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"48.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                    <PrePosition X=\"0.1389\" Y=\"0.5000\" />\n                    <PreSize X=\"0.4694\" Y=\"0.9792\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"1.0000\" Y=\"0.1429\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position Y=\"160.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"0.2667\" />\n            <PreSize X=\"1.0000\" Y=\"0.4667\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/MessageBox.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MessageBox\" Type=\"Layer\" ID=\"dcd674b2-1a82-418f-b8c5-708a548451ac\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"0.9833\" />\n      <ObjectData Name=\"Layer\" Tag=\"5\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"960.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"1171670077\" Tag=\"6\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"960.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"1630129227\" Tag=\"7\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"72.0000\" RightMargin=\"72.0000\" TopMargin=\"264.0000\" BottomMargin=\"264.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"576.0000\" Y=\"432.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_6\" ActionTag=\"435307517\" Tag=\"15\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"3.0000\" RightMargin=\"3.0000\" TopMargin=\"3.0000\" BottomMargin=\"130.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"570.0000\" Y=\"299.0000\" />\n                    <AnchorPoint />\n                    <Position X=\"3.0000\" Y=\"130.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0052\" Y=\"0.3009\" />\n                    <PreSize X=\"0.9931\" Y=\"0.6944\" />\n                    <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_3\" ActionTag=\"-2101547886\" Tag=\"19\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" TopMargin=\"95.0000\" BottomMargin=\"317.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"576.0000\" Y=\"20.0000\" />\n                    <AnchorPoint />\n                    <Position Y=\"317.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition Y=\"0.7338\" />\n                    <PreSize X=\"1.0000\" Y=\"0.0463\" />\n                    <SingleColor A=\"255\" R=\"85\" G=\"85\" B=\"85\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"text\" ActionTag=\"-971714321\" Tag=\"11\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"5.0000\" RightMargin=\"5.0000\" TopMargin=\"130.0000\" BottomMargin=\"150.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"True\" ColorAngle=\"90.0000\" ScrollDirectionType=\"Vertical\" ctype=\"ScrollViewObjectData\">\n                    <Size X=\"566.0000\" Y=\"152.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"content\" ActionTag=\"58004573\" Tag=\"8\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"20.0000\" RightMargin=\"20.0000\" BottomMargin=\"64.0000\" StretchWidthEnable=\"True\" IsCustomSize=\"True\" FontSize=\"56\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                        <Size X=\"526.0000\" Y=\"64.0000\" />\n                        <AnchorPoint ScaleY=\"1.0000\" />\n                        <Position X=\"20.0000\" Y=\"222.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0354\" Y=\"1.0000\" />\n                        <PreSize X=\"1.0000\" Y=\"0.5000\" />\n                        <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                        <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                        <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"5.0000\" Y=\"150.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0087\" Y=\"0.3472\" />\n                    <PreSize X=\"0.9653\" Y=\"0.6944\" />\n                    <SingleColor A=\"255\" R=\"32\" G=\"32\" B=\"32\" />\n                    <FirstColor A=\"255\" R=\"255\" G=\"150\" B=\"100\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                    <InnerNodeSize Width=\"566\" Height=\"222\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"title\" ActionTag=\"263594957\" Tag=\"9\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" VerticalEdge=\"TopEdge\" LeftMargin=\"141.4999\" RightMargin=\"141.4999\" TopMargin=\"10.0000\" BottomMargin=\"194.0000\" FontSize=\"64\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"293.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"1.0000\" />\n                    <Position X=\"288.0000\" Y=\"422.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.9653\" />\n                    <PreSize X=\"0.5087\" Y=\"0.2917\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"btnList\" ActionTag=\"975070262\" Tag=\"12\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"5.0000\" RightMargin=\"5.0001\" TopMargin=\"211.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"565.9999\" Y=\"120.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"btn\" ActionTag=\"-1909097187\" Tag=\"14\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"10.0000\" RightMargin=\"305.9999\" TopMargin=\"10.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                        <Size X=\"250.0000\" Y=\"105.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_7\" ActionTag=\"2017295163\" Tag=\"16\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"4.0000\" RightMargin=\"4.0000\" TopMargin=\"4.0000\" BottomMargin=\"4.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                            <Size X=\"242.0000\" Y=\"97.0000\" />\n                            <Children>\n                              <AbstractNodeData Name=\"btnBody\" ActionTag=\"1302713611\" Tag=\"13\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"64\" ButtonText=\"Button\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                                <Size X=\"242.0000\" Y=\"97.0000\" />\n                                <AnchorPoint />\n                                <Position />\n                                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                                <PrePosition />\n                                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                                <TextColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                                <DisabledFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                                <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                              </AbstractNodeData>\n                            </Children>\n                            <AnchorPoint />\n                            <Position X=\"4.0000\" Y=\"4.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0200\" Y=\"0.0533\" />\n                            <PreSize X=\"1.0000\" Y=\"3.6364\" />\n                            <SingleColor A=\"255\" R=\"153\" G=\"153\" B=\"153\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"10.0000\" Y=\"5.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0177\" Y=\"0.0714\" />\n                        <PreSize X=\"0.4417\" Y=\"0.8750\" />\n                        <SingleColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                        <FirstColor A=\"255\" R=\"136\" G=\"136\" B=\"136\" />\n                        <EndColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"5.0000\" Y=\"5.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0087\" Y=\"0.0174\" />\n                    <PreSize X=\"0.9826\" Y=\"0.3571\" />\n                    <SingleColor A=\"255\" R=\"32\" G=\"32\" B=\"32\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"360.0000\" Y=\"480.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"0.8000\" Y=\"0.4500\" />\n                <SingleColor A=\"255\" R=\"85\" G=\"85\" B=\"85\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.2778\" Y=\"0.2083\" />\n            <SingleColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/NaviBar.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"NaviBar\" Type=\"Layer\" ID=\"e0c48d51-440d-45d7-a047-668f6791ee65\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"18\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"120.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"-1733638915\" Tag=\"19\" IconVisible=\"False\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"120.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"left\" ActionTag=\"-1066593416\" Tag=\"44\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"LeftEdge\" LeftMargin=\"20.0000\" RightMargin=\"600.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" FontSize=\"18\" Scale9Width=\"64\" Scale9Height=\"64\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"100.0000\" Y=\"100.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"60.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0278\" Y=\"0.5000\" />\n                <PreSize X=\"0.1389\" Y=\"0.8333\" />\n                <TextColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"554958899\" Tag=\"32\" IconVisible=\"False\" PercentHeightEnable=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"110.0000\" RightMargin=\"110.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"True\" BackColorAlpha=\"0\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"500.0000\" Y=\"120.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"title\" ActionTag=\"-779724123\" Tag=\"33\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" TouchEnable=\"True\" FontSize=\"64\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"500.0000\" Y=\"120.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position Y=\"60.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition Y=\"0.5000\" />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <TextColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"110.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1528\" />\n                <PreSize X=\"0.6944\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"right\" ActionTag=\"125654759\" Tag=\"57\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"610.0000\" RightMargin=\"10.0000\" TopMargin=\"10.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"100.0000\" Y=\"100.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"660.0000\" Y=\"60.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.9167\" Y=\"0.5000\" />\n                <PreSize X=\"0.1389\" Y=\"0.8333\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/NaviBarWithMenu.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"NaviBarWithMenu\" Type=\"Layer\" ID=\"d2a2f3ee-482c-4afc-874d-4dc87e58b6b1\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"73\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"120.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"-558826945\" Tag=\"74\" IconVisible=\"False\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"120.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"left\" ActionTag=\"-1706704630\" Tag=\"75\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"LeftEdge\" LeftMargin=\"20.0000\" RightMargin=\"620.0000\" TopMargin=\"20.0000\" BottomMargin=\"20.0000\" TouchEnable=\"True\" FontSize=\"18\" Scale9Width=\"64\" Scale9Height=\"64\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"60.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0278\" Y=\"0.5000\" />\n                <PreSize X=\"0.1111\" Y=\"0.6667\" />\n                <TextColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"-431653019\" Tag=\"31\" IconVisible=\"False\" PercentHeightEnable=\"True\" PercentHeightEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"110.0000\" RightMargin=\"110.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"True\" BackColorAlpha=\"0\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"500.0000\" Y=\"120.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"title\" ActionTag=\"-322343071\" Tag=\"76\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"64\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"500.0000\" Y=\"120.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position Y=\"60.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition Y=\"0.5000\" />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <TextColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"110.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1528\" />\n                <PreSize X=\"0.6944\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"right\" ActionTag=\"-1376432436\" Tag=\"78\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"620.0000\" RightMargin=\"20.0000\" TopMargin=\"20.0000\" BottomMargin=\"20.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"34\" Scale9Height=\"42\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"660.0000\" Y=\"60.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.9167\" Y=\"0.5000\" />\n                <PreSize X=\"0.1111\" Y=\"0.6667\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Normal\" Path=\"img/menu_icon.png\" Plist=\"\" />\n                <PressedFileData Type=\"Normal\" Path=\"img/menu_press.png\" Plist=\"\" />\n                <NormalFileData Type=\"Normal\" Path=\"img/menu_icon.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/ProgressBox.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"ProgressBox\" Type=\"Layer\" ID=\"bf9b3cee-a64d-48be-a767-64e6f23af9b5\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"0.9833\" />\n      <ObjectData Name=\"Layer\" Tag=\"5\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"960.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"1171670077\" Tag=\"6\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"960.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_2\" ActionTag=\"1630129227\" Tag=\"7\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"72.0000\" RightMargin=\"72.0000\" TopMargin=\"180.0000\" BottomMargin=\"180.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"576.0000\" Y=\"600.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_6\" ActionTag=\"435307517\" Tag=\"15\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"3.0000\" RightMargin=\"3.0000\" TopMargin=\"3.0000\" BottomMargin=\"130.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"570.0000\" Y=\"467.0000\" />\n                    <AnchorPoint />\n                    <Position X=\"3.0000\" Y=\"130.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0052\" Y=\"0.2167\" />\n                    <PreSize X=\"0.9896\" Y=\"0.7783\" />\n                    <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_3\" ActionTag=\"-2101547886\" Tag=\"19\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" TopMargin=\"95.0000\" BottomMargin=\"485.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"576.0000\" Y=\"20.0000\" />\n                    <AnchorPoint />\n                    <Position Y=\"485.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition Y=\"0.8083\" />\n                    <PreSize X=\"1.0000\" Y=\"0.0333\" />\n                    <SingleColor A=\"255\" R=\"85\" G=\"85\" B=\"85\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_4\" ActionTag=\"-1533722917\" Tag=\"120\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"20.0000\" RightMargin=\"20.0000\" TopMargin=\"130.0000\" BottomMargin=\"150.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                    <Size X=\"536.0000\" Y=\"320.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_5\" ActionTag=\"1296826855\" Tag=\"121\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"TopEdge\" BottomMargin=\"256.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                        <Size X=\"536.0000\" Y=\"64.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"progrss_1\" ActionTag=\"1338629523\" Tag=\"118\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" ProgressInfo=\"50\" ctype=\"LoadingBarObjectData\">\n                            <Size X=\"536.0000\" Y=\"64.0000\" />\n                            <AnchorPoint />\n                            <Position />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <ImageFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"progress_text_1\" ActionTag=\"46485031\" Tag=\"122\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"156.5000\" RightMargin=\"156.5000\" TopMargin=\"-2.5000\" BottomMargin=\"-2.5000\" FontSize=\"48\" LabelText=\"Text Label\" OutlineSize=\"3\" OutlineEnabled=\"True\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                            <Size X=\"223.0000\" Y=\"69.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"268.0000\" Y=\"32.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                            <PreSize X=\"0.4160\" Y=\"1.0781\" />\n                            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                            <OutlineColor A=\"255\" R=\"77\" G=\"77\" B=\"77\" />\n                            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position Y=\"256.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition Y=\"0.8000\" />\n                        <PreSize X=\"1.0000\" Y=\"0.2000\" />\n                        <SingleColor A=\"255\" R=\"26\" G=\"26\" B=\"26\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"Panel_5_0\" ActionTag=\"-1180897590\" Tag=\"123\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"TopEdge\" LeftMargin=\"0.2520\" RightMargin=\"-0.2520\" TopMargin=\"80.0000\" BottomMargin=\"176.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"536.0000\" Y=\"64.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"progrss_2\" ActionTag=\"-2136225183\" Tag=\"124\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" ProgressInfo=\"50\" ctype=\"LoadingBarObjectData\">\n                            <Size X=\"536.0000\" Y=\"64.0000\" />\n                            <AnchorPoint />\n                            <Position />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition />\n                            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                            <ImageFileData Type=\"Normal\" Path=\"img/white.png\" Plist=\"\" />\n                          </AbstractNodeData>\n                          <AbstractNodeData Name=\"progress_text_2\" ActionTag=\"725777923\" Tag=\"125\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"156.5000\" RightMargin=\"156.5000\" TopMargin=\"-2.5000\" BottomMargin=\"-2.5000\" FontSize=\"48\" LabelText=\"Text Label\" OutlineSize=\"3\" OutlineEnabled=\"True\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                            <Size X=\"223.0000\" Y=\"69.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"268.0000\" Y=\"32.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                            <PreSize X=\"0.4160\" Y=\"1.0781\" />\n                            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                            <OutlineColor A=\"255\" R=\"77\" G=\"77\" B=\"77\" />\n                            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint />\n                        <Position X=\"0.2520\" Y=\"176.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0005\" Y=\"0.5500\" />\n                        <PreSize X=\"1.0000\" Y=\"0.2000\" />\n                        <SingleColor A=\"255\" R=\"26\" G=\"26\" B=\"26\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                      <AbstractNodeData Name=\"text\" ActionTag=\"58004573\" Tag=\"8\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"2.0000\" RightMargin=\"0.0001\" TopMargin=\"160.8994\" StretchWidthEnable=\"True\" IsCustomSize=\"True\" FontSize=\"56\" LabelText=\"Text Label&#xA;line2\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                        <Size X=\"533.9999\" Y=\"159.1006\" />\n                        <AnchorPoint />\n                        <Position X=\"2.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.0037\" />\n                        <PreSize X=\"0.9963\" Y=\"0.4972\" />\n                        <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                        <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                        <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleY=\"1.0000\" />\n                    <Position X=\"20.0000\" Y=\"470.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0347\" Y=\"0.7833\" />\n                    <PreSize X=\"0.9306\" Y=\"0.5333\" />\n                    <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"title\" ActionTag=\"263594957\" Tag=\"9\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" VerticalEdge=\"TopEdge\" LeftMargin=\"142.5000\" RightMargin=\"142.5000\" TopMargin=\"10.0000\" BottomMargin=\"506.0000\" FontSize=\"64\" LabelText=\"Text Label\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"291.0000\" Y=\"84.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"1.0000\" />\n                    <Position X=\"288.0000\" Y=\"590.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.9833\" />\n                    <PreSize X=\"0.5052\" Y=\"0.1400\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"btnList\" ActionTag=\"975070262\" Tag=\"12\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"5.0000\" RightMargin=\"5.0001\" TopMargin=\"475.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"565.9999\" Y=\"120.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"btnCell\" ActionTag=\"-1909097187\" Tag=\"14\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"157.9999\" RightMargin=\"157.9999\" TopMargin=\"7.5000\" BottomMargin=\"7.5000\" TouchEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"250.0000\" Y=\"105.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Panel_7\" ActionTag=\"2017295163\" Tag=\"16\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"4.0000\" RightMargin=\"4.0000\" TopMargin=\"4.0000\" BottomMargin=\"4.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                            <Size X=\"242.0000\" Y=\"97.0000\" />\n                            <Children>\n                              <AbstractNodeData Name=\"btn\" ActionTag=\"1302713611\" Tag=\"13\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"64\" ButtonText=\"Button\" Scale9Enable=\"True\" Scale9Width=\"1\" Scale9Height=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                                <Size X=\"242.0000\" Y=\"97.0000\" />\n                                <AnchorPoint />\n                                <Position />\n                                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                                <PrePosition />\n                                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                                <TextColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                                <DisabledFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                                <PressedFileData Type=\"Normal\" Path=\"img/gray.png\" Plist=\"\" />\n                                <NormalFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n                                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                              </AbstractNodeData>\n                            </Children>\n                            <AnchorPoint />\n                            <Position X=\"4.0000\" Y=\"4.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <PrePosition X=\"0.0160\" Y=\"0.0381\" />\n                            <PreSize X=\"0.9680\" Y=\"0.9238\" />\n                            <SingleColor A=\"255\" R=\"153\" G=\"153\" B=\"153\" />\n                            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                            <ColorVector ScaleY=\"1.0000\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"282.9999\" Y=\"60.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.4417\" Y=\"0.8750\" />\n                        <SingleColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                        <FirstColor A=\"255\" R=\"136\" G=\"136\" B=\"136\" />\n                        <EndColor A=\"255\" R=\"68\" G=\"68\" B=\"68\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"5.0000\" Y=\"5.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.0087\" Y=\"0.0083\" />\n                    <PreSize X=\"0.9826\" Y=\"0.2000\" />\n                    <SingleColor A=\"255\" R=\"32\" G=\"32\" B=\"32\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"360.0000\" Y=\"480.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"0.8000\" Y=\"0.6250\" />\n                <SingleColor A=\"255\" R=\"85\" G=\"85\" B=\"85\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/RecentListItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"RecentListItem\" Type=\"Layer\" ID=\"9debbcf9-7030-4c9d-8021-6c277ec0a91e\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"127\" ctype=\"GameLayerObjectData\">\n        <Size X=\"480.0000\" Y=\"120.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"scrollview\" ActionTag=\"538025425\" Tag=\"133\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" BottomMargin=\"60.0000\" TouchEnable=\"True\" ClipAble=\"False\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"Horizontal\" ctype=\"ScrollViewObjectData\">\n            <Size X=\"480.0000\" Y=\"60.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"panel_delete\" ActionTag=\"2056246478\" Tag=\"134\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"480.0000\" RightMargin=\"-60.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"60.0000\" Y=\"60.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"btn_delete\" ActionTag=\"132216541\" Tag=\"130\" IconVisible=\"False\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"10\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                    <Size X=\"60.0000\" Y=\"60.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                    <DisabledFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n                    <PressedFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n                    <NormalFileData Type=\"Normal\" Path=\"img/Cancel_Normal.png\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"480.0000\" Y=\"30.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"1.0000\" Y=\"0.5000\" />\n                <PreSize X=\"0.1250\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"151\" G=\"0\" B=\"1\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"prefix\" ActionTag=\"545306432\" Tag=\"129\" IconVisible=\"False\" RightMargin=\"390.0000\" TopMargin=\"13.0000\" FontSize=\"36\" LabelText=\"path\\\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"90.0000\" Y=\"47.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"path\" ActionTag=\"1906585251\" Tag=\"128\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"90.0000\" RightMargin=\"-102.0000\" TopMargin=\"-18.0000\" FontSize=\"50\" LabelText=\"Path\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"102.0000\" Y=\"65.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"file\" ActionTag=\"-145038778\" Tag=\"132\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" LeftMargin=\"102.0000\" RightMargin=\"-65.0000\" TopMargin=\"18.0000\" FontSize=\"36\" LabelText=\"\\file\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                        <Size X=\"65.0000\" Y=\"47.0000\" />\n                        <AnchorPoint />\n                        <Position X=\"102.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                        <PrePosition X=\"1.0000\" />\n                        <PreSize X=\"0.6373\" Y=\"0.7231\" />\n                        <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                        <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                        <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint />\n                    <Position X=\"90.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"1.0000\" />\n                    <PreSize X=\"1.1333\" Y=\"1.3830\" />\n                    <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"128\" G=\"128\" B=\"128\" />\n                <PrePosition />\n                <PreSize X=\"0.1875\" Y=\"0.7833\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position Y=\"60.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"0.5000\" />\n            <PreSize X=\"1.0000\" Y=\"0.5000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"255\" G=\"150\" B=\"100\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n            <InnerNodeSize Width=\"480\" Height=\"60\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"btn_jump\" ActionTag=\"1263288345\" Tag=\"131\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"415.0000\" RightMargin=\"15.0000\" TopMargin=\"65.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" FlipX=\"True\" FontSize=\"14\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"34\" Scale9Height=\"42\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"50.0000\" Y=\"50.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" />\n            <Position X=\"440.0000\" Y=\"5.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9167\" Y=\"0.0417\" />\n            <PreSize X=\"0.1042\" Y=\"0.4167\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"btn_conf\" ActionTag=\"-1673357661\" Tag=\"135\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"350.0000\" RightMargin=\"80.0000\" TopMargin=\"65.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"34\" Scale9Height=\"42\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"50.0000\" Y=\"50.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" />\n            <Position X=\"375.0000\" Y=\"5.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.7813\" Y=\"0.0417\" />\n            <PreSize X=\"0.1042\" Y=\"0.4167\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/syssetting_btn_on.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/syssetting_btn_on.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/syssetting_btn_ff.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"btn_play\" ActionTag=\"-1221264795\" Tag=\"136\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" VerticalEdge=\"BottomEdge\" LeftMargin=\"89.0480\" RightMargin=\"340.9520\" TopMargin=\"65.0000\" BottomMargin=\"5.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"226\" Scale9Height=\"234\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"50.0000\" Y=\"50.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" />\n            <Position X=\"114.0480\" Y=\"5.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n            <PrePosition X=\"0.2376\" Y=\"0.0417\" />\n            <PreSize X=\"0.1042\" Y=\"0.4167\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/triangle.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/triangle.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/triangle.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_2\" ActionTag=\"1651684711\" Tag=\"138\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" TopMargin=\"118.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"480.0000\" Y=\"2.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"0.0167\" />\n            <SingleColor A=\"255\" R=\"160\" G=\"160\" B=\"160\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/SelectList.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SelectList\" Type=\"Layer\" ID=\"fb5f9ac2-71b8-4d44-bd74-5bdffeabc31b\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"29\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"480.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_4\" ActionTag=\"1135387664\" Tag=\"52\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"480.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"title\" ActionTag=\"1366729226\" Tag=\"43\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" VerticalEdge=\"TopEdge\" LeftMargin=\"314.0000\" RightMargin=\"314.0000\" TopMargin=\"7.0000\" BottomMargin=\"410.0000\" FontSize=\"48\" LabelText=\"Title\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"92.0000\" Y=\"63.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"360.0000\" Y=\"441.5000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.9198\" />\n                <PreSize X=\"0.1278\" Y=\"0.1312\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_5\" ActionTag=\"697373835\" Tag=\"53\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentWidthEnabled=\"True\" VerticalEdge=\"BothEdge\" TopMargin=\"80.0000\" TouchEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"True\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"400.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_17\" ActionTag=\"-1215190169\" Tag=\"67\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"80.0000\" RightMargin=\"80.0000\" TopMargin=\"152.0000\" BottomMargin=\"152.0000\" StretchWidthEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"38\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"560.0000\" Y=\"96.0000\" />\n                <AnchorPoint ScaleY=\"0.5000\" />\n                <Position X=\"80.0000\" Y=\"200.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1111\" Y=\"0.5000\" />\n                <PreSize X=\"0.7778\" Y=\"0.2400\" />\n                <SingleColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"pageview\" ActionTag=\"-142522138\" Tag=\"60\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"80.0000\" RightMargin=\"80.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"560.0000\" Y=\"400.0000\" />\n                <AnchorPoint />\n                <Position X=\"80.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1111\" />\n                <PreSize X=\"0.7778\" Y=\"1.0000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"dir_icon\" ActionTag=\"1905600206\" Tag=\"54\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"LeftEdge\" RightMargin=\"640.0000\" TopMargin=\"160.0000\" BottomMargin=\"160.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_2_9_8\" ActionTag=\"-1619199232\" Tag=\"55\" RotationSkewX=\"-135.0000\" RotationSkewY=\"-135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"30.0000\" BottomMargin=\"40.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"45.0000\" Y=\"10.0000\" />\n                    <AnchorPoint />\n                    <Position X=\"70.0000\" Y=\"40.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                    <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_0_11_10\" ActionTag=\"413048241\" Tag=\"56\" RotationSkewX=\"135.0006\" RotationSkewY=\"135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"40.0000\" BottomMargin=\"30.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"45.0000\" Y=\"10.0000\" />\n                    <AnchorPoint ScaleY=\"1.0000\" />\n                    <Position X=\"70.0000\" Y=\"40.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                    <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n                <Position X=\"80.0000\" Y=\"200.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1111\" Y=\"0.5000\" />\n                <PreSize X=\"0.1111\" Y=\"0.2000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"dir_icon_0\" ActionTag=\"214394180\" Tag=\"58\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"640.0000\" TopMargin=\"160.0000\" BottomMargin=\"160.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_2_9_8_13\" ActionTag=\"-112702401\" Tag=\"58\" RotationSkewX=\"-135.0000\" RotationSkewY=\"-135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"30.0000\" BottomMargin=\"40.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"45.0000\" Y=\"10.0000\" />\n                    <AnchorPoint />\n                    <Position X=\"70.0000\" Y=\"40.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                    <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_0_11_10_15\" ActionTag=\"2004678246\" Tag=\"59\" RotationSkewX=\"135.0006\" RotationSkewY=\"135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"40.0000\" BottomMargin=\"30.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"45.0000\" Y=\"10.0000\" />\n                    <AnchorPoint ScaleY=\"1.0000\" />\n                    <Position X=\"70.0000\" Y=\"40.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                    <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                    <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"680.0000\" Y=\"200.0000\" />\n                <Scale ScaleX=\"-1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.9444\" Y=\"0.5000\" />\n                <PreSize X=\"0.1111\" Y=\"0.2000\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"0.8333\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"cancel\" ActionTag=\"-2131293610\" Tag=\"46\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" RightMargin=\"640.0000\" BottomMargin=\"400.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position Y=\"440.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"214\" G=\"15\" B=\"15\" />\n            <PrePosition Y=\"0.9167\" />\n            <PreSize X=\"0.1111\" Y=\"0.1667\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/Cancel_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"ok\" ActionTag=\"-1982738977\" Tag=\"45\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"640.0000\" BottomMargin=\"400.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"720.0000\" Y=\"440.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"0\" G=\"255\" B=\"52\" />\n            <PrePosition X=\"1.0000\" Y=\"0.9167\" />\n            <PreSize X=\"0.1111\" Y=\"0.1667\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/SelectListItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SelectListItem\" Type=\"Layer\" ID=\"554ef725-5acc-490d-a2b6-54230ba7700a\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"42\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"text\" ActionTag=\"-832335906\" Tag=\"43\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" IsCustomSize=\"True\" FontSize=\"72\" LabelText=\"Text Label\" HorizontalAlignmentType=\"HT_Center\" VerticalAlignmentType=\"VT_Center\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"640.0000\" Y=\"96.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/TableView.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"TableView\" Type=\"Layer\" ID=\"23410f2e-2ffa-4490-ba35-5eb7172f5c97\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"12\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"960.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"table\" ActionTag=\"1520823067\" Tag=\"36\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"960.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.2778\" Y=\"0.2083\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/TextPairInput.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"TextPairInput\" Type=\"Layer\" ID=\"01f597c4-7c9e-45eb-b10c-5410df277c58\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"15\" ctype=\"GameLayerObjectData\">\n        <Size X=\"720.0000\" Y=\"480.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_4\" ActionTag=\"1468209997\" Tag=\"29\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"720.0000\" Y=\"480.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_13\" ActionTag=\"-515610504\" Tag=\"35\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"80.0000\" BottomMargin=\"320.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"700.0000\" Y=\"80.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"input1\" ActionTag=\"-1316102677\" Tag=\"34\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"72\" IsCustomSize=\"True\" LabelText=\"\" PlaceHolderText=\"Touch to input\" MaxLengthText=\"10\" ctype=\"TextFieldObjectData\">\n                    <Size X=\"700.0000\" Y=\"80.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"350.0000\" Y=\"40.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"10.0000\" Y=\"320.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0139\" Y=\"0.6667\" />\n                <PreSize X=\"0.9722\" Y=\"0.1667\" />\n                <SingleColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_14\" ActionTag=\"826264957\" Tag=\"36\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"10.0000\" RightMargin=\"10.0000\" TopMargin=\"180.0000\" BottomMargin=\"10.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"700.0000\" Y=\"290.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"input2\" ActionTag=\"1741385435\" Tag=\"37\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" FontSize=\"72\" IsCustomSize=\"True\" LabelText=\"\" PlaceHolderText=\"Touch to input\" MaxLengthText=\"10\" ctype=\"TextFieldObjectData\">\n                    <Size X=\"700.0000\" Y=\"290.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"350.0000\" Y=\"145.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"10.0000\" Y=\"10.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0139\" Y=\"0.0208\" />\n                <PreSize X=\"1.0000\" Y=\"0.4167\" />\n                <SingleColor A=\"255\" R=\"199\" G=\"199\" B=\"199\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"cancel\" ActionTag=\"-1303371487\" Tag=\"32\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" RightMargin=\"640.0000\" BottomMargin=\"400.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position Y=\"440.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"214\" G=\"15\" B=\"15\" />\n            <PrePosition Y=\"0.9167\" />\n            <PreSize X=\"0.1111\" Y=\"0.1667\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/Cancel_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"ok\" ActionTag=\"-1372489870\" Tag=\"33\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"640.0000\" BottomMargin=\"400.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"720.0000\" Y=\"440.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"0\" G=\"255\" B=\"52\" />\n            <PrePosition X=\"1.0000\" Y=\"0.9167\" />\n            <PreSize X=\"0.1111\" Y=\"0.1667\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"255\" G=\"127\" B=\"80\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/WinMgrOverlay.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"WinMgrOverlay\" Type=\"Layer\" ID=\"992a2fb5-67d5-4fa3-b7bb-2533fafa6727\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"640.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"-2128505626\" Tag=\"6\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"51\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"960.0000\" Y=\"640.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"480.0000\" Y=\"320.0000\" />\n            <Scale ScaleX=\"2.0000\" ScaleY=\"2.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n            <PreSize X=\"0.2083\" Y=\"0.3125\" />\n            <SingleColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"ok\" ActionTag=\"-219132164\" Tag=\"2\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"860.0000\" RightMargin=\"60.0000\" TopMargin=\"60.0000\" BottomMargin=\"540.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"40.0000\" Y=\"40.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"CheckBoxNode_Normal_1\" CanEdit=\"False\" ActionTag=\"672451984\" Tag=\"5\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" ctype=\"SpriteObjectData\">\n                <Size X=\"40.0000\" Y=\"40.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"20.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/CheckBoxNode_Normal.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"880.0000\" Y=\"560.0000\" />\n            <Scale ScaleX=\"2.0000\" ScaleY=\"2.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9167\" Y=\"0.8750\" />\n            <PreSize X=\"0.0417\" Y=\"0.0625\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/CheckBox_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/CheckBox_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"left\" ActionTag=\"-1581397684\" Tag=\"3\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"LeftEdge\" LeftMargin=\"20.0000\" RightMargin=\"876.0000\" TopMargin=\"288.0000\" BottomMargin=\"288.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"34\" Scale9Height=\"42\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"64.0000\" Y=\"64.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"20.0000\" Y=\"320.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0208\" Y=\"0.5000\" />\n            <PreSize X=\"0.0667\" Y=\"0.1000\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"right\" ActionTag=\"-724672713\" Tag=\"4\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"876.0000\" RightMargin=\"20.0000\" TopMargin=\"288.0000\" BottomMargin=\"288.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"34\" Scale9Height=\"42\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"64.0000\" Y=\"64.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"908.0000\" Y=\"320.0000\" />\n            <Scale ScaleX=\"-1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9458\" Y=\"0.5000\" />\n            <PreSize X=\"0.0667\" Y=\"0.1000\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/back_btn_on.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"fillscr\" ActionTag=\"-2030113146\" Tag=\"14\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"60.0000\" RightMargin=\"860.0000\" TopMargin=\"60.0000\" BottomMargin=\"540.0000\" TouchEnable=\"True\" FontSize=\"14\" Scale9Enable=\"True\" LeftEage=\"13\" RightEage=\"13\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"13\" Scale9OriginY=\"11\" Scale9Width=\"14\" Scale9Height=\"18\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"40.0000\" Y=\"40.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"CheckBoxNode_Normal_1\" ActionTag=\"-116912945\" Tag=\"15\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"-20.0000\" RightMargin=\"-20.0000\" TopMargin=\"-20.0000\" BottomMargin=\"-20.0000\" ctype=\"SpriteObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"20.0000\" Y=\"20.0000\" />\n                <Scale ScaleX=\"0.4000\" ScaleY=\"0.4000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/windows_icon.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n            <Position X=\"80.0000\" Y=\"560.0000\" />\n            <Scale ScaleX=\"1.9000\" ScaleY=\"1.9000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0833\" Y=\"0.8750\" />\n            <PreSize X=\"0.0417\" Y=\"0.0625\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/CheckBox_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/CheckBox_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/CheckBoxItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"CheckBoxItem\" Type=\"Layer\" ID=\"e39f38cb-fb62-4fa8-8343-2cc7467c3eac\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"112\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"title\" ActionTag=\"1659873677\" Tag=\"113\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"BothEdge\" LeftMargin=\"8.0000\" RightMargin=\"95.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" StretchWidthEnable=\"True\" IsCustomSize=\"True\" FontSize=\"64\" LabelText=\"\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"537.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"8.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0125\" Y=\"0.5000\" />\n            <PreSize X=\"0.8391\" Y=\"0.8333\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Panel_5\" ActionTag=\"1964271860\" Tag=\"122\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"552.0000\" RightMargin=\"8.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" TouchEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"checkbox\" ActionTag=\"-1952433904\" Tag=\"121\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"TopEdge\" TouchEnable=\"True\" CheckedState=\"True\" ctype=\"CheckBoxObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"40.0000\" Y=\"40.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                <NormalBackFileData Type=\"Normal\" Path=\"img/CheckBox_Normal.png\" Plist=\"\" />\n                <PressedBackFileData Type=\"Normal\" Path=\"img/CheckBox_Press.png\" Plist=\"\" />\n                <DisableBackFileData Type=\"Normal\" Path=\"img/CheckBox_Disable.png\" Plist=\"\" />\n                <NodeNormalFileData Type=\"Normal\" Path=\"img/CheckBoxNode_Normal.png\" Plist=\"\" />\n                <NodeDisableFileData Type=\"Normal\" Path=\"img/empty.png\" Plist=\"\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"632.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9875\" Y=\"0.5000\" />\n            <PreSize X=\"0.1250\" Y=\"0.8333\" />\n            <SingleColor A=\"255\" R=\"102\" G=\"102\" B=\"102\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"highlight\" ActionTag=\"-877127030\" VisibleForFrame=\"False\" Tag=\"73\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"640.0000\" Y=\"96.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/SelectListItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SelectListItem\" Type=\"Layer\" ID=\"06796c6a-085b-45a0-90bd-30563bdf31c3\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"48\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"160.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"highlight\" ActionTag=\"1720299844\" VisibleForFrame=\"False\" Tag=\"51\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"640.0000\" Y=\"160.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"title\" ActionTag=\"1559126503\" Tag=\"49\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"8.0000\" RightMargin=\"339.0000\" TopMargin=\"8.0000\" BottomMargin=\"68.0000\" FontSize=\"64\" LabelText=\"Text Label\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"293.0000\" Y=\"84.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"8.0000\" Y=\"110.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0125\" Y=\"0.6875\" />\n            <PreSize X=\"0.9750\" Y=\"0.4500\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"selected\" ActionTag=\"-1163656747\" Tag=\"50\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"376.0000\" RightMargin=\"8.0000\" TopMargin=\"79.0000\" BottomMargin=\"8.0000\" FontSize=\"56\" LabelText=\"Text Label\" HorizontalAlignmentType=\"HT_Right\" VerticalAlignmentType=\"VT_Bottom\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"256.0000\" Y=\"73.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"632.0000\" Y=\"44.5000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9875\" Y=\"0.2781\" />\n            <PreSize X=\"0.9375\" Y=\"0.4500\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/SeperateItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SeperateItem\" Type=\"Layer\" ID=\"3a906c4c-e6a3-497b-96d8-bcea8cd53981\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"7\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"5.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_2\" ActionTag=\"39795932\" Tag=\"12\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"640.0000\" Y=\"5.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"162\" G=\"162\" B=\"162\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/SliderIconItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SliderIconItem\" Type=\"Layer\" ID=\"ee67d08c-e2db-4261-b60a-4800efc50f53\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"12\" ctype=\"GameLayerObjectData\">\n        <Size X=\"1280.0000\" Y=\"240.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_14\" ActionTag=\"-841405037\" Tag=\"49\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" RightMargin=\"160.0000\" TopMargin=\"96.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"1120.0000\" Y=\"144.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"slider\" ActionTag=\"620239051\" Tag=\"18\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"240.0000\" RightMargin=\"80.0000\" TopMargin=\"40.0000\" BottomMargin=\"90.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ctype=\"SliderObjectData\">\n                <Size X=\"800.0000\" Y=\"14.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"640.0000\" Y=\"97.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.5714\" Y=\"0.6736\" />\n                <PreSize X=\"0.7143\" Y=\"0.0972\" />\n                <BackGroundData Type=\"Default\" Path=\"Default/Slider_Back.png\" Plist=\"\" />\n                <ProgressBarData Type=\"Default\" Path=\"Default/Slider_PressBar.png\" Plist=\"\" />\n                <BallNormalData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                <BallPressedData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                <BallDisabledData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"reset\" ActionTag=\"976875283\" Tag=\"19\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"15.0000\" RightMargin=\"955.0000\" TopMargin=\"49.0000\" BottomMargin=\"15.0000\" TouchEnable=\"True\" FontSize=\"56\" ButtonText=\"preference_reset\" Scale9Enable=\"True\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"16\" Scale9Height=\"14\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"150.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" />\n                <Position X=\"90.0000\" Y=\"15.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.0804\" Y=\"0.1042\" />\n                <PreSize X=\"0.1339\" Y=\"0.5556\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Default\" Path=\"Default/Button_Disable.png\" Plist=\"\" />\n                <PressedFileData Type=\"Default\" Path=\"Default/Button_Press.png\" Plist=\"\" />\n                <NormalFileData Type=\"Default\" Path=\"Default/Button_Normal.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.8750\" Y=\"0.6000\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"icon\" ActionTag=\"-1211004810\" Tag=\"26\" IconVisible=\"True\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"1160.0000\" RightMargin=\"120.0000\" TopMargin=\"120.0000\" BottomMargin=\"120.0000\" ctype=\"SingleNodeObjectData\">\n            <Size X=\"0.0000\" Y=\"0.0000\" />\n            <AnchorPoint />\n            <Position X=\"1160.0000\" Y=\"120.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9063\" Y=\"0.5000\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"title\" ActionTag=\"1009150853\" Tag=\"39\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"8.0000\" RightMargin=\"120.0000\" TopMargin=\"8.0000\" BottomMargin=\"152.0000\" StretchWidthEnable=\"True\" IsCustomSize=\"True\" FontSize=\"64\" LabelText=\"\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"1152.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"8.0000\" Y=\"192.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0063\" Y=\"0.8000\" />\n            <PreSize X=\"0.9000\" Y=\"0.3333\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/SliderTextItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SliderTextItem\" Type=\"Layer\" ID=\"2ac4a8de-1c1e-445e-9c24-6cbdf6f3d88e\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"10\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"240.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_14\" ActionTag=\"-162230027\" Tag=\"11\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" RightMargin=\"160.0000\" TopMargin=\"96.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"480.0000\" Y=\"144.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"slider\" ActionTag=\"-58693844\" Tag=\"12\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"240.0000\" RightMargin=\"80.0000\" TopMargin=\"40.0000\" BottomMargin=\"90.0000\" TouchEnable=\"True\" StretchWidthEnable=\"True\" ctype=\"SliderObjectData\">\n                <Size X=\"160.0000\" Y=\"14.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"320.0000\" Y=\"97.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.6667\" Y=\"0.6736\" />\n                <PreSize X=\"0.4167\" Y=\"0.1228\" />\n                <BackGroundData Type=\"Default\" Path=\"Default/Slider_Back.png\" Plist=\"\" />\n                <ProgressBarData Type=\"Default\" Path=\"Default/Slider_PressBar.png\" Plist=\"\" />\n                <BallNormalData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                <BallPressedData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n                <BallDisabledData Type=\"Normal\" Path=\"img/circle_white.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"reset\" ActionTag=\"-250147453\" Tag=\"13\" IconVisible=\"False\" HorizontalEdge=\"LeftEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"15.0000\" RightMargin=\"315.0000\" TopMargin=\"49.0000\" BottomMargin=\"15.0000\" TouchEnable=\"True\" FontSize=\"56\" ButtonText=\"preference_reset\" Scale9Enable=\"True\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"16\" Scale9Height=\"14\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n                <Size X=\"150.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" />\n                <Position X=\"90.0000\" Y=\"15.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.1875\" Y=\"0.1042\" />\n                <PreSize X=\"0.3125\" Y=\"0.7018\" />\n                <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n                <DisabledFileData Type=\"Default\" Path=\"Default/Button_Disable.png\" Plist=\"\" />\n                <PressedFileData Type=\"Default\" Path=\"Default/Button_Press.png\" Plist=\"\" />\n                <NormalFileData Type=\"Default\" Path=\"Default/Button_Normal.png\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"0.3125\" Y=\"0.5429\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"text\" ActionTag=\"998803420\" Tag=\"33\" IconVisible=\"False\" HorizontalEdge=\"RightEdge\" VerticalEdge=\"BottomEdge\" LeftMargin=\"489.0000\" RightMargin=\"35.0000\" TopMargin=\"112.0000\" BottomMargin=\"70.0000\" FontSize=\"58\" LabelText=\"Text\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n            <Size X=\"116.0000\" Y=\"58.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"605.0000\" Y=\"99.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9453\" Y=\"0.4125\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"title\" ActionTag=\"-1320320728\" Tag=\"15\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"TopEdge\" LeftMargin=\"8.0000\" RightMargin=\"120.0000\" TopMargin=\"8.0000\" BottomMargin=\"152.0000\" IsCustomSize=\"True\" FontSize=\"64\" LabelText=\"\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"512.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"8.0000\" Y=\"192.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0125\" Y=\"0.8000\" />\n            <PreSize X=\"0.8391\" Y=\"0.5000\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/comctrl/SubDirItem.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"SubDirItem\" Type=\"Layer\" ID=\"de386a4b-11bd-472d-bc71-dbeaa9c6a850\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"15\" ctype=\"GameLayerObjectData\">\n        <Size X=\"640.0000\" Y=\"96.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"title\" ActionTag=\"807950898\" Tag=\"16\" IconVisible=\"False\" HorizontalEdge=\"BothEdge\" VerticalEdge=\"BothEdge\" LeftMargin=\"8.0000\" RightMargin=\"75.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" StretchWidthEnable=\"True\" StretchHeightEnable=\"True\" IsCustomSize=\"True\" FontSize=\"64\" LabelText=\"\" OutlineSize=\"0\" ShadowOffsetX=\"0.0000\" ShadowOffsetY=\"0.0000\" ctype=\"TextObjectData\">\n            <Size X=\"557.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleY=\"0.5000\" />\n            <Position X=\"8.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0125\" Y=\"0.5000\" />\n            <PreSize X=\"0.8625\" Y=\"0.0000\" />\n            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"dir_icon\" ActionTag=\"543627081\" Tag=\"26\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"552.0000\" RightMargin=\"8.0000\" TopMargin=\"8.0000\" BottomMargin=\"8.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Panel_2_9\" ActionTag=\"-1835816871\" Tag=\"27\" RotationSkewX=\"-135.0000\" RotationSkewY=\"-135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"30.0000\" BottomMargin=\"40.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" Rotation=\"-135.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"45.0000\" Y=\"10.0000\" />\n                <AnchorPoint />\n                <Position X=\"70.0000\" Y=\"40.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_2_0_11\" ActionTag=\"273376623\" Tag=\"28\" RotationSkewX=\"135.0006\" RotationSkewY=\"135.0000\" IconVisible=\"False\" PositionPercentYEnabled=\"True\" HorizontalEdge=\"RightEdge\" LeftMargin=\"70.0000\" RightMargin=\"-35.0000\" TopMargin=\"40.0000\" BottomMargin=\"30.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" Rotation=\"135.0006\" ctype=\"PanelObjectData\">\n                <Size X=\"45.0000\" Y=\"10.0000\" />\n                <AnchorPoint ScaleY=\"1.0000\" />\n                <Position X=\"70.0000\" Y=\"40.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition X=\"0.8750\" Y=\"0.5000\" />\n                <PreSize X=\"0.5625\" Y=\"0.1250\" />\n                <SingleColor A=\"255\" R=\"191\" G=\"191\" B=\"191\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"0.5000\" />\n            <Position X=\"632.0000\" Y=\"48.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.9875\" Y=\"0.5000\" />\n            <PreSize X=\"0.1250\" Y=\"0.8333\" />\n            <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"highlight\" ActionTag=\"1281646941\" VisibleForFrame=\"False\" Tag=\"47\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" ClipAble=\"False\" BackColorAlpha=\"102\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n            <Size X=\"640.0000\" Y=\"96.0000\" />\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/help/AllTips.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"AllTips\" Type=\"Layer\" ID=\"36208f0a-d8c3-4c07-bd77-a553d27dfa57\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"0\" Speed=\"1.0000\" />\n      <ObjectData Name=\"Layer\" Tag=\"149\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"480.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"tipslist\" ActionTag=\"158529181\" Tag=\"150\" IconVisible=\"False\" PercentWidthEnable=\"True\" PercentHeightEnable=\"True\" PercentWidthEnabled=\"True\" PercentHeightEnabled=\"True\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ScrollDirectionType=\"0\" DirectionType=\"Vertical\" ctype=\"ListViewObjectData\">\n            <Size X=\"960.0000\" Y=\"480.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"touchTip\" ActionTag=\"-439603325\" Tag=\"151\" IconVisible=\"False\" BottomMargin=\"180.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"960.0000\" Y=\"360.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"FileNode_1\" ActionTag=\"-1503309661\" Tag=\"153\" IconVisible=\"True\" StretchWidthEnable=\"False\" StretchHeightEnable=\"False\" InnerActionSpeed=\"1.0000\" CustomSizeEnabled=\"False\" ctype=\"ProjectNodeObjectData\">\n                    <Size X=\"960.0000\" Y=\"360.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <FileData Type=\"Normal\" Path=\"ui/help/TouchModeTips.csd\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position Y=\"180.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition Y=\"0.3333\" />\n                <PreSize X=\"1.0000\" Y=\"0.6667\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"screenTip\" ActionTag=\"1913524774\" ZOrder=\"1\" Tag=\"126\" IconVisible=\"False\" TopMargin=\"360.0000\" ClipAble=\"False\" BackColorAlpha=\"102\" ColorAngle=\"90.0000\" ctype=\"PanelObjectData\">\n                <Size X=\"960.0000\" Y=\"180.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"FileNode_2\" ActionTag=\"-2136036669\" Tag=\"127\" IconVisible=\"True\" StretchWidthEnable=\"False\" StretchHeightEnable=\"False\" InnerActionSpeed=\"1.0000\" CustomSizeEnabled=\"False\" ctype=\"ProjectNodeObjectData\">\n                    <Size X=\"960.0000\" Y=\"180.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"1.0000\" Y=\"1.0000\" />\n                    <FileData Type=\"Normal\" Path=\"ui/help/ScreenModeTips.csd\" Plist=\"\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"1.0000\" Y=\"0.3333\" />\n                <SingleColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition />\n            <PreSize X=\"1.0000\" Y=\"1.0000\" />\n            <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"150\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"btn_close\" ActionTag=\"1683260622\" Tag=\"152\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"880.0000\" BottomMargin=\"400.0000\" TouchEnable=\"True\" FontSize=\"14\" LeftEage=\"15\" RightEage=\"15\" TopEage=\"11\" BottomEage=\"11\" Scale9OriginX=\"15\" Scale9OriginY=\"11\" Scale9Width=\"10\" Scale9Height=\"18\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"ButtonObjectData\">\n            <Size X=\"80.0000\" Y=\"80.0000\" />\n            <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <Position X=\"960.0000\" Y=\"480.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"1.0000\" Y=\"1.0000\" />\n            <PreSize X=\"0.0833\" Y=\"0.1667\" />\n            <TextColor A=\"255\" R=\"65\" G=\"65\" B=\"70\" />\n            <DisabledFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n            <PressedFileData Type=\"Normal\" Path=\"img/Cancel_Press.png\" Plist=\"\" />\n            <NormalFileData Type=\"Normal\" Path=\"img/Cancel_Normal.png\" Plist=\"\" />\n            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/help/MouseModeTips.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"MouseModeTips\" Type=\"Layer\" ID=\"90f387b1-60d8-4bed-ab52-3c6c51d094f9\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"450\" Speed=\"1.0000\">\n        <Timeline ActionTag=\"229197645\" Property=\"Position\">\n          <PointFrame FrameIndex=\"0\" X=\"150.5588\" Y=\"75.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"30\" X=\"141.3700\" Y=\"157.3591\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"390\" X=\"141.3700\" Y=\"157.3591\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"410\" X=\"141.3700\" Y=\"120.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n        <Timeline ActionTag=\"229197645\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"0\" X=\"1.0000\" Y=\"1.6000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"30\" X=\"1.5000\" Y=\"0.1000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"450\" X=\"1.5000\" Y=\"0.1000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"229197645\" Property=\"RotationSkew\">\n          <ScaleFrame FrameIndex=\"0\" X=\"0.0000\" Y=\"0.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"30\" X=\"60.0000\" Y=\"0.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"229197645\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"0\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"30\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"390\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"410\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1824443952\" Property=\"Position\">\n          <PointFrame FrameIndex=\"20\" X=\"167.8663\" Y=\"210.7975\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"40\" X=\"150.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"250\" X=\"150.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"280\" X=\"180.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"305\" X=\"180.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"340\" X=\"150.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"370\" X=\"150.0000\" Y=\"160.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"400\" X=\"180.0000\" Y=\"190.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1824443952\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"20\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"40\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"370\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"400\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-2012265606\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"30\" X=\"3.0000\" Y=\"3.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"40\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-2012265606\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"0\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"30\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"40\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"95\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"105\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"1613641018\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"90\" X=\"3.0000\" Y=\"3.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"100\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"1613641018\" Property=\"VisibleForFrame\">\n          <BoolFrame FrameIndex=\"0\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"90\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"165\" Tween=\"False\" Value=\"False\" />\n        </Timeline>\n        <Timeline ActionTag=\"1613641018\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"90\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"100\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"155\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"165\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-936106288\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"150\" X=\"3.0000\" Y=\"3.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"160\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-936106288\" Property=\"VisibleForFrame\">\n          <BoolFrame FrameIndex=\"0\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"150\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"225\" Tween=\"False\" Value=\"False\" />\n        </Timeline>\n        <Timeline ActionTag=\"-936106288\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"150\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"160\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"215\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"225\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1983356721\" Property=\"Position\">\n          <PointFrame FrameIndex=\"0\" X=\"350.0000\" Y=\"215.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"250\" X=\"350.0000\" Y=\"215.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"280\" X=\"400.0000\" Y=\"215.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"305\" X=\"400.0000\" Y=\"215.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"340\" X=\"350.0000\" Y=\"215.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1983356721\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"0\" X=\"0.5000\" Y=\"0.5000\">\n            <EasingData Type=\"-1\">\n              <Points>\n                <PointF />\n                <PointF />\n                <PointF X=\"1.0000\" Y=\"1.0000\" />\n                <PointF X=\"1.0000\" Y=\"1.0000\" />\n              </Points>\n            </EasingData>\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"219\" X=\"0.5000\" Y=\"0.5000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"220\" X=\"0.4000\" Y=\"0.4000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"369\" X=\"0.4000\" Y=\"0.4000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"370\" X=\"0.5000\" Y=\"0.5000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n      </Animation>\n      <AnimationList>\n        <AnimationInfo Name=\"autoplay\" StartIndex=\"0\" EndIndex=\"450\">\n          <RenderColor A=\"150\" R=\"255\" G=\"160\" B=\"122\" />\n        </AnimationInfo>\n      </AnimationList>\n      <ObjectData Name=\"Layer\" Tag=\"91\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"240.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Panel_1\" ActionTag=\"229197645\" Alpha=\"0\" Tag=\"93\" IconVisible=\"False\" LeftMargin=\"100.5588\" RightMargin=\"759.4412\" TopMargin=\"65.0000\" BottomMargin=\"75.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n            <Size X=\"100.0000\" Y=\"100.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" />\n            <Position X=\"150.5588\" Y=\"75.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.6000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.1568\" Y=\"0.3125\" />\n            <PreSize X=\"0.1042\" Y=\"0.4167\" />\n            <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n            <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n            <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <ColorVector ScaleY=\"1.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"touch1_1\" ActionTag=\"-1824443952\" Alpha=\"0\" Tag=\"92\" RotationSkewX=\"-150.2268\" RotationSkewY=\"-150.2268\" IconVisible=\"False\" LeftMargin=\"135.8663\" RightMargin=\"760.1337\" TopMargin=\"29.2025\" BottomMargin=\"142.7975\" FlipX=\"True\" ctype=\"SpriteObjectData\">\n            <Size X=\"64.0000\" Y=\"68.0000\" />\n            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"1.0000\" />\n            <Position X=\"167.8663\" Y=\"210.7975\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.1749\" Y=\"0.8783\" />\n            <PreSize X=\"0.0667\" Y=\"0.2833\" />\n            <FileData Type=\"Normal\" Path=\"img/touch1.png\" Plist=\"\" />\n            <BlendFunc Src=\"1\" Dst=\"771\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Node_1\" ActionTag=\"-518149107\" Tag=\"95\" IconVisible=\"True\" LeftMargin=\"113.9297\" RightMargin=\"846.0703\" TopMargin=\"39.9164\" BottomMargin=\"200.0836\" ctype=\"SingleNodeObjectData\">\n            <Size X=\"0.0000\" Y=\"0.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Text_3\" ActionTag=\"-2012265606\" Alpha=\"0\" Tag=\"94\" IconVisible=\"False\" LeftMargin=\"-11.5000\" RightMargin=\"-11.5000\" TopMargin=\"-26.0000\" BottomMargin=\"-26.0000\" FontSize=\"40\" LabelText=\"3\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"23.0000\" Y=\"52.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position />\n                <Scale ScaleX=\"3.0000\" ScaleY=\"3.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Text_2\" ActionTag=\"1613641018\" VisibleForFrame=\"False\" Alpha=\"0\" Tag=\"96\" IconVisible=\"False\" LeftMargin=\"-11.5000\" RightMargin=\"-11.5000\" TopMargin=\"-26.0000\" BottomMargin=\"-26.0000\" FontSize=\"40\" LabelText=\"2\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"23.0000\" Y=\"52.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position />\n                <Scale ScaleX=\"3.0000\" ScaleY=\"3.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Text_1\" ActionTag=\"-936106288\" VisibleForFrame=\"False\" Alpha=\"0\" Tag=\"97\" IconVisible=\"False\" LeftMargin=\"-13.5000\" RightMargin=\"-3.5000\" TopMargin=\"-26.0000\" BottomMargin=\"-26.0000\" FontSize=\"40\" LabelText=\"1\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                <Size X=\"17.0000\" Y=\"52.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"-5.0000\" />\n                <Scale ScaleX=\"3.0000\" ScaleY=\"3.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position X=\"113.9297\" Y=\"200.0836\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.1187\" Y=\"0.8337\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"Node_3\" ActionTag=\"-1102304925\" Tag=\"105\" IconVisible=\"True\" LeftMargin=\"0.0002\" RightMargin=\"959.9998\" TopMargin=\"249.4386\" BottomMargin=\"-9.4386\" ctype=\"SingleNodeObjectData\">\n            <Size X=\"0.0000\" Y=\"0.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"Node_2\" ActionTag=\"-1983356721\" Tag=\"100\" IconVisible=\"True\" LeftMargin=\"350.0000\" RightMargin=\"-350.0000\" TopMargin=\"-215.0000\" BottomMargin=\"215.0000\" ctype=\"SingleNodeObjectData\">\n                <Size X=\"0.0000\" Y=\"0.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"CheckBox_Normal_2\" ActionTag=\"-1106334161\" Tag=\"104\" IconVisible=\"False\" LeftMargin=\"-20.0000\" RightMargin=\"-20.0000\" TopMargin=\"-20.0000\" BottomMargin=\"-20.0000\" ctype=\"SpriteObjectData\">\n                    <Size X=\"40.0000\" Y=\"40.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position />\n                    <Scale ScaleX=\"2.0000\" ScaleY=\"2.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <FileData Type=\"Normal\" Path=\"img/CheckBox_Normal.png\" Plist=\"\" />\n                    <BlendFunc Src=\"770\" Dst=\"771\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2\" ActionTag=\"403988143\" Tag=\"98\" RotationSkewX=\"150.0000\" RotationSkewY=\"90.0000\" IconVisible=\"False\" RightMargin=\"-100.0000\" TopMargin=\"-20.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"100.0000\" Y=\"20.0000\" />\n                    <AnchorPoint />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"172\" G=\"172\" B=\"172\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_0\" ActionTag=\"-2070787841\" Tag=\"99\" RotationSkewX=\"-30.0000\" RotationSkewY=\"30.0000\" IconVisible=\"False\" RightMargin=\"-100.0000\" BottomMargin=\"-20.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"100.0000\" Y=\"20.0000\" />\n                    <AnchorPoint ScaleY=\"1.0000\" />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"172\" G=\"172\" B=\"172\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_2\" ActionTag=\"1400222952\" Tag=\"355\" RotationSkewX=\"120.0000\" RotationSkewY=\"90.0000\" IconVisible=\"False\" LeftMargin=\"8.1029\" RightMargin=\"-25.9099\" TopMargin=\"-56.4722\" BottomMargin=\"-12.0673\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"17.8069\" Y=\"68.5395\" />\n                    <AnchorPoint />\n                    <Position X=\"8.1029\" Y=\"-12.0673\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"172\" G=\"172\" B=\"172\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_2_0\" ActionTag=\"2094979710\" Tag=\"356\" IconVisible=\"False\" LeftMargin=\"2.7225\" RightMargin=\"-24.8633\" TopMargin=\"27.7120\" BottomMargin=\"-85.9961\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"22.1407\" Y=\"58.2841\" />\n                    <AnchorPoint />\n                    <Position X=\"2.7225\" Y=\"-85.9961\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"172\" G=\"172\" B=\"172\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_2_0_0\" ActionTag=\"-2013820637\" Tag=\"357\" IconVisible=\"False\" LeftMargin=\"21.5505\" RightMargin=\"-43.6912\" TopMargin=\"31.8455\" BottomMargin=\"-59.1972\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"22.1407\" Y=\"27.3517\" />\n                    <AnchorPoint />\n                    <Position X=\"21.5505\" Y=\"-59.1972\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"172\" G=\"172\" B=\"172\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_1\" ActionTag=\"516243834\" Tag=\"101\" RotationSkewX=\"-30.0000\" RotationSkewY=\"-60.0007\" IconVisible=\"False\" RightMargin=\"-57.0000\" TopMargin=\"100.0000\" BottomMargin=\"-120.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"57.0000\" Y=\"20.0000\" />\n                    <AnchorPoint ScaleY=\"1.0000\" />\n                    <Position Y=\"-100.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"73\" G=\"73\" B=\"73\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Panel_2_0_0_0\" ActionTag=\"-1817336782\" Tag=\"103\" RotationSkewX=\"-30.0000\" IconVisible=\"False\" LeftMargin=\"27.5000\" RightMargin=\"-87.0000\" TopMargin=\"50.0000\" BottomMargin=\"-70.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"59.5000\" Y=\"20.0000\" />\n                    <AnchorPoint ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <Position X=\"87.0000\" Y=\"-50.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <SingleColor A=\"255\" R=\"73\" G=\"73\" B=\"73\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"350.0000\" Y=\"215.0000\" />\n                <Scale ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position X=\"0.0002\" Y=\"-9.4386\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0000\" Y=\"-0.0393\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/help/ScreenModeTips.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"ScreenModeTips\" Type=\"Layer\" ID=\"aa5e7d29-36d3-4a83-9579-f8971574964e\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"120\" Speed=\"1.0000\">\n        <Timeline ActionTag=\"-921877692\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"0\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"50\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"60\" X=\"1.3800\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"110\" X=\"1.3800\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"120\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n      </Animation>\n      <AnimationList>\n        <AnimationInfo Name=\"autoplay\" StartIndex=\"0\" EndIndex=\"120\">\n          <RenderColor A=\"255\" R=\"184\" G=\"134\" B=\"11\" />\n        </AnimationInfo>\n      </AnimationList>\n      <ObjectData Name=\"Layer\" Tag=\"14\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"180.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Node_4\" ActionTag=\"546684255\" Tag=\"86\" IconVisible=\"True\" LeftMargin=\"42.0000\" RightMargin=\"918.0000\" TopMargin=\"262.0000\" BottomMargin=\"-82.0000\" ctype=\"SingleNodeObjectData\">\n            <Size X=\"0.0000\" Y=\"0.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"windows_icon_3\" ActionTag=\"-51065590\" Tag=\"32\" IconVisible=\"False\" LeftMargin=\"22.0000\" RightMargin=\"-102.0000\" TopMargin=\"-217.0000\" BottomMargin=\"137.0000\" ctype=\"SpriteObjectData\">\n                <Size X=\"80.0000\" Y=\"80.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"62.0000\" Y=\"177.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/windows_icon.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_21\" ActionTag=\"-128018732\" Tag=\"82\" IconVisible=\"False\" LeftMargin=\"193.0000\" RightMargin=\"-393.0000\" TopMargin=\"-232.0000\" BottomMargin=\"112.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"200.0000\" Y=\"120.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Panel_21_0\" ActionTag=\"291493735\" Tag=\"83\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"3.0000\" RightMargin=\"3.0000\" TopMargin=\"3.0000\" BottomMargin=\"3.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                    <Size X=\"194.0000\" Y=\"114.0000\" />\n                    <Children>\n                      <AbstractNodeData Name=\"Panel_21_0_0\" ActionTag=\"-921877692\" Tag=\"84\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"27.0000\" RightMargin=\"27.0000\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                        <Size X=\"140.0000\" Y=\"114.0000\" />\n                        <Children>\n                          <AbstractNodeData Name=\"Text_15\" ActionTag=\"-586077753\" Tag=\"85\" IconVisible=\"False\" PositionPercentXEnabled=\"True\" PositionPercentYEnabled=\"True\" LeftMargin=\"10.5000\" RightMargin=\"10.5000\" TopMargin=\"15.0000\" BottomMargin=\"15.0000\" FontSize=\"64\" LabelText=\"ABC\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                            <Size X=\"119.0000\" Y=\"84.0000\" />\n                            <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                            <Position X=\"70.0000\" Y=\"57.0000\" />\n                            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                            <CColor A=\"255\" R=\"0\" G=\"0\" B=\"0\" />\n                            <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                            <PreSize X=\"0.8500\" Y=\"0.7368\" />\n                            <FontResource Type=\"Normal\" Path=\"DroidSansFallback.ttf\" Plist=\"\" />\n                            <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                            <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                          </AbstractNodeData>\n                        </Children>\n                        <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                        <Position X=\"97.0000\" Y=\"57.0000\" />\n                        <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                        <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                        <PreSize X=\"0.7216\" Y=\"1.0000\" />\n                        <SingleColor A=\"255\" R=\"60\" G=\"177\" B=\"255\" />\n                        <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                        <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                        <ColorVector ScaleY=\"1.0000\" />\n                      </AbstractNodeData>\n                    </Children>\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position X=\"100.0000\" Y=\"60.0000\" />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.5000\" Y=\"0.5000\" />\n                    <PreSize X=\"0.9700\" Y=\"0.9500\" />\n                    <SingleColor A=\"255\" R=\"42\" G=\"42\" B=\"42\" />\n                    <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                    <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <ColorVector ScaleY=\"1.0000\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"193.0000\" Y=\"112.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <SingleColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position X=\"42.0000\" Y=\"-82.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0437\" Y=\"-0.4556\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/cocosstudio/ui/help/TouchModeTips.csd",
    "content": "<GameFile>\n  <PropertyGroup Name=\"TouchModeTips\" Type=\"Layer\" ID=\"95c42862-de39-4543-9b10-37115a1a9992\" Version=\"3.10.0.0\" />\n  <Content ctype=\"GameProjectContent\">\n    <Content>\n      <Animation Duration=\"175\" Speed=\"1.0000\" ActivedAnimationName=\"autoplay\">\n        <Timeline ActionTag=\"-1984647807\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"43\" X=\"0.6000\" Y=\"0.6000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"58\" X=\"0.9000\" Y=\"0.9000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1984647807\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"43\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"46\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"58\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1822566326\" Property=\"Position\">\n          <PointFrame FrameIndex=\"0\" X=\"200.0000\" Y=\"400.6157\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"15\" X=\"220.0000\" Y=\"400.6157\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"40\" X=\"220.0000\" Y=\"400.6157\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"43\" X=\"224.0000\" Y=\"404.6200\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"46\" X=\"220.0000\" Y=\"400.6157\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-1822566326\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"0\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"15\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"60\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"75\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-667323553\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"140\" X=\"0.6000\" Y=\"0.6000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"155\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-667323553\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"140\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"142\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"155\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-40639660\" Property=\"Scale\">\n          <ScaleFrame FrameIndex=\"140\" X=\"0.6000\" Y=\"0.6000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n          <ScaleFrame FrameIndex=\"155\" X=\"1.0000\" Y=\"1.0000\">\n            <EasingData Type=\"0\" />\n          </ScaleFrame>\n        </Timeline>\n        <Timeline ActionTag=\"-40639660\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"140\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"142\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"155\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"174983373\" Property=\"Position\">\n          <PointFrame FrameIndex=\"100\" X=\"200.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"115\" X=\"220.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"137\" X=\"220.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"140\" X=\"224.0000\" Y=\"404.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"143\" X=\"220.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n        <Timeline ActionTag=\"174983373\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"100\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"115\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"160\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"175\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"1686072714\" Property=\"VisibleForFrame\">\n          <BoolFrame FrameIndex=\"0\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"43\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"50\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"140\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"148\" Tween=\"False\" Value=\"True\" />\n        </Timeline>\n        <Timeline ActionTag=\"1686072714\" Property=\"Alpha\">\n          <IntFrame FrameIndex=\"0\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"15\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"160\" Value=\"255\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n          <IntFrame FrameIndex=\"175\" Value=\"0\">\n            <EasingData Type=\"0\" />\n          </IntFrame>\n        </Timeline>\n        <Timeline ActionTag=\"677008033\" Property=\"VisibleForFrame\">\n          <BoolFrame FrameIndex=\"0\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"43\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"50\" Tween=\"False\" Value=\"False\" />\n        </Timeline>\n        <Timeline ActionTag=\"-1154764237\" Property=\"VisibleForFrame\">\n          <BoolFrame FrameIndex=\"0\" Tween=\"False\" Value=\"False\" />\n          <BoolFrame FrameIndex=\"140\" Tween=\"False\" Value=\"True\" />\n          <BoolFrame FrameIndex=\"148\" Tween=\"False\" Value=\"False\" />\n        </Timeline>\n        <Timeline ActionTag=\"-1756020638\" Property=\"Position\">\n          <PointFrame FrameIndex=\"0\" X=\"390.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n          <PointFrame FrameIndex=\"15\" X=\"400.0000\" Y=\"400.0000\">\n            <EasingData Type=\"0\" />\n          </PointFrame>\n        </Timeline>\n      </Animation>\n      <AnimationList>\n        <AnimationInfo Name=\"autoplay\" StartIndex=\"0\" EndIndex=\"240\">\n          <RenderColor A=\"255\" R=\"139\" G=\"0\" B=\"139\" />\n        </AnimationInfo>\n      </AnimationList>\n      <ObjectData Name=\"Layer\" Tag=\"35\" ctype=\"GameLayerObjectData\">\n        <Size X=\"960.0000\" Y=\"360.0000\" />\n        <Children>\n          <AbstractNodeData Name=\"Node_2\" ActionTag=\"457267296\" Tag=\"87\" IconVisible=\"True\" RightMargin=\"960.0000\" TopMargin=\"480.0000\" BottomMargin=\"-120.0000\" ctype=\"SingleNodeObjectData\">\n            <Size X=\"0.0000\" Y=\"0.0000\" />\n            <Children>\n              <AbstractNodeData Name=\"icon_touch\" ActionTag=\"651567504\" Tag=\"52\" IconVisible=\"False\" LeftMargin=\"58.0627\" RightMargin=\"-122.0627\" TopMargin=\"-432.2832\" BottomMargin=\"368.2832\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                <Size X=\"64.0000\" Y=\"64.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"90.0627\" Y=\"400.2832\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/touch_icon.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"icon_mouse\" ActionTag=\"1679595494\" Tag=\"65\" IconVisible=\"False\" LeftMargin=\"62.7248\" RightMargin=\"-126.7248\" TopMargin=\"-245.3902\" BottomMargin=\"181.3902\" Scale9Width=\"64\" Scale9Height=\"64\" ctype=\"ImageViewObjectData\">\n                <Size X=\"64.0000\" Y=\"64.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"94.7248\" Y=\"213.3902\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"208\" G=\"208\" B=\"208\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/mouse_icon.png\" Plist=\"\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"touch1_3\" ActionTag=\"-1822566326\" Alpha=\"0\" Tag=\"69\" IconVisible=\"False\" LeftMargin=\"168.0000\" RightMargin=\"-232.0000\" TopMargin=\"-434.6157\" BottomMargin=\"366.6157\" ctype=\"SpriteObjectData\">\n                <Size X=\"64.0000\" Y=\"68.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Text_1\" ActionTag=\"-1984647807\" Alpha=\"0\" Tag=\"71\" RotationSkewX=\"-90.0000\" RotationSkewY=\"-90.0042\" IconVisible=\"False\" LeftMargin=\"26.6563\" RightMargin=\"-10.6563\" TopMargin=\"-19.1275\" BottomMargin=\"39.1275\" FontSize=\"48\" LabelText=\"）\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"48.0000\" Y=\"48.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"26.6563\" Y=\"63.1275\" />\n                    <Scale ScaleX=\"0.6000\" ScaleY=\"0.6000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.4165\" Y=\"0.9283\" />\n                    <PreSize X=\"0.7500\" Y=\"0.7059\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"200.0000\" Y=\"400.6157\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/touch1.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"touch2_4\" ActionTag=\"174983373\" Alpha=\"0\" Tag=\"70\" IconVisible=\"False\" LeftMargin=\"168.0000\" RightMargin=\"-232.0000\" TopMargin=\"-434.0000\" BottomMargin=\"366.0000\" ctype=\"SpriteObjectData\">\n                <Size X=\"64.0000\" Y=\"68.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"Text_1_0\" ActionTag=\"-667323553\" Alpha=\"0\" Tag=\"72\" RotationSkewX=\"-90.0000\" RotationSkewY=\"-90.0042\" IconVisible=\"False\" LeftMargin=\"26.3152\" RightMargin=\"-10.3152\" TopMargin=\"-21.5995\" BottomMargin=\"41.5995\" FontSize=\"48\" LabelText=\"）\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"48.0000\" Y=\"48.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"26.3152\" Y=\"65.5995\" />\n                    <Scale ScaleX=\"0.6000\" ScaleY=\"0.6000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.4112\" Y=\"0.9647\" />\n                    <PreSize X=\"0.7500\" Y=\"0.7059\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"Text_1_1\" ActionTag=\"-40639660\" Alpha=\"0\" Tag=\"73\" RotationSkewX=\"-90.0000\" RotationSkewY=\"-90.0042\" IconVisible=\"False\" LeftMargin=\"56.5821\" RightMargin=\"-40.5821\" TopMargin=\"-13.6352\" BottomMargin=\"33.6352\" FontSize=\"48\" LabelText=\"）\" ShadowOffsetX=\"2.0000\" ShadowOffsetY=\"-2.0000\" ctype=\"TextObjectData\">\n                    <Size X=\"48.0000\" Y=\"48.0000\" />\n                    <AnchorPoint ScaleY=\"0.5000\" />\n                    <Position X=\"56.5821\" Y=\"57.6352\" />\n                    <Scale ScaleX=\"0.6000\" ScaleY=\"0.6000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition X=\"0.8841\" Y=\"0.8476\" />\n                    <PreSize X=\"0.7500\" Y=\"0.7059\" />\n                    <OutlineColor A=\"255\" R=\"255\" G=\"0\" B=\"0\" />\n                    <ShadowColor A=\"255\" R=\"110\" G=\"110\" B=\"110\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"200.0000\" Y=\"400.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/touch2.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Node_1\" ActionTag=\"-1756020638\" Tag=\"83\" IconVisible=\"True\" LeftMargin=\"390.0000\" RightMargin=\"-390.0000\" TopMargin=\"-400.0000\" BottomMargin=\"400.0000\" ctype=\"SingleNodeObjectData\">\n                <Size X=\"0.0000\" Y=\"0.0000\" />\n                <Children>\n                  <AbstractNodeData Name=\"mouse_2btn_5\" ActionTag=\"1686072714\" Alpha=\"0\" Tag=\"80\" IconVisible=\"False\" LeftMargin=\"-21.5000\" RightMargin=\"-21.5000\" TopMargin=\"-32.0000\" BottomMargin=\"-32.0000\" ctype=\"SpriteObjectData\">\n                    <Size X=\"43.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <FileData Type=\"Normal\" Path=\"img/mouse_2btn.png\" Plist=\"\" />\n                    <BlendFunc Src=\"1\" Dst=\"771\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"mouse_left_btn_6\" ActionTag=\"677008033\" VisibleForFrame=\"False\" Tag=\"81\" IconVisible=\"False\" LeftMargin=\"-21.5000\" RightMargin=\"-21.5000\" TopMargin=\"-32.0000\" BottomMargin=\"-32.0000\" ctype=\"SpriteObjectData\">\n                    <Size X=\"43.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <FileData Type=\"Normal\" Path=\"img/mouse_left_btn.png\" Plist=\"\" />\n                    <BlendFunc Src=\"1\" Dst=\"771\" />\n                  </AbstractNodeData>\n                  <AbstractNodeData Name=\"mouse_right_btn_7\" ActionTag=\"-1154764237\" VisibleForFrame=\"False\" Tag=\"82\" IconVisible=\"False\" LeftMargin=\"-21.5000\" RightMargin=\"-21.5000\" TopMargin=\"-32.0000\" BottomMargin=\"-32.0000\" ctype=\"SpriteObjectData\">\n                    <Size X=\"43.0000\" Y=\"64.0000\" />\n                    <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                    <Position />\n                    <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                    <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                    <PrePosition />\n                    <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                    <FileData Type=\"Normal\" Path=\"img/mouse_right_btn.png\" Plist=\"\" />\n                    <BlendFunc Src=\"1\" Dst=\"771\" />\n                  </AbstractNodeData>\n                </Children>\n                <AnchorPoint />\n                <Position X=\"390.0000\" Y=\"400.0000\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"back_btn_off_8\" ActionTag=\"1213383067\" Tag=\"85\" RotationSkewX=\"90.0000\" RotationSkewY=\"89.9996\" IconVisible=\"False\" LeftMargin=\"60.0000\" RightMargin=\"-124.0000\" TopMargin=\"-348.0630\" BottomMargin=\"284.0630\" ctype=\"SpriteObjectData\">\n                <Size X=\"64.0000\" Y=\"64.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"92.0000\" Y=\"316.0630\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"back_btn_off_8_0\" ActionTag=\"-2009143488\" Tag=\"86\" RotationSkewX=\"-90.0000\" RotationSkewY=\"-90.0009\" IconVisible=\"False\" LeftMargin=\"60.0000\" RightMargin=\"-124.0000\" TopMargin=\"-334.7714\" BottomMargin=\"270.7714\" ctype=\"SpriteObjectData\">\n                <Size X=\"64.0000\" Y=\"64.0000\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"92.0000\" Y=\"302.7714\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <FileData Type=\"Normal\" Path=\"img/back_btn_off.png\" Plist=\"\" />\n                <BlendFunc Src=\"1\" Dst=\"771\" />\n              </AbstractNodeData>\n              <AbstractNodeData Name=\"Panel_5\" ActionTag=\"-500678024\" Tag=\"66\" IconVisible=\"False\" LeftMargin=\"88.2050\" RightMargin=\"-95.7950\" TopMargin=\"-339.9524\" BottomMargin=\"278.0334\" TouchEnable=\"True\" ClipAble=\"False\" ComboBoxIndex=\"1\" ColorAngle=\"90.0000\" Scale9Width=\"1\" Scale9Height=\"1\" ctype=\"PanelObjectData\">\n                <Size X=\"7.5900\" Y=\"61.9190\" />\n                <AnchorPoint ScaleX=\"0.5000\" ScaleY=\"0.5000\" />\n                <Position X=\"92.0000\" Y=\"308.9929\" />\n                <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n                <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <PrePosition />\n                <PreSize X=\"0.0000\" Y=\"0.0000\" />\n                <SingleColor A=\"255\" R=\"192\" G=\"192\" B=\"192\" />\n                <FirstColor A=\"255\" R=\"150\" G=\"200\" B=\"255\" />\n                <EndColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n                <ColorVector ScaleY=\"1.0000\" />\n              </AbstractNodeData>\n            </Children>\n            <AnchorPoint />\n            <Position Y=\"-120.0000\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition Y=\"-0.3333\" />\n            <PreSize X=\"0.0000\" Y=\"0.0000\" />\n          </AbstractNodeData>\n          <AbstractNodeData Name=\"FileNode_2\" ActionTag=\"106093384\" Tag=\"106\" IconVisible=\"True\" LeftMargin=\"86.8356\" RightMargin=\"-86.8356\" TopMargin=\"209.6661\" BottomMargin=\"-89.6661\" StretchWidthEnable=\"False\" StretchHeightEnable=\"False\" InnerActionSpeed=\"1.0000\" CustomSizeEnabled=\"False\" ctype=\"ProjectNodeObjectData\">\n            <Size X=\"960.0000\" Y=\"240.0000\" />\n            <AnchorPoint />\n            <Position X=\"86.8356\" Y=\"-89.6661\" />\n            <Scale ScaleX=\"1.0000\" ScaleY=\"1.0000\" />\n            <CColor A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n            <PrePosition X=\"0.0905\" Y=\"-0.2491\" />\n            <PreSize X=\"1.0000\" Y=\"0.6667\" />\n            <FileData Type=\"Normal\" Path=\"ui/help/MouseModeTips.csd\" Plist=\"\" />\n          </AbstractNodeData>\n        </Children>\n      </ObjectData>\n    </Content>\n  </Content>\n</GameFile>"
  },
  {
    "path": "project/ui/kr2.ccs",
    "content": "<Solution>\n  <PropertyGroup Name=\"kr2\" Version=\"3.10.0.0\" Type=\"CocosStudio\" />\n  <SolutionFolder>\n    <Group ctype=\"ResourceGroup\">\n      <RootFolder Name=\".\">\n        <Folder Name=\"img\">\n          <Image Name=\"about_icon.png\" />\n          <Image Name=\"back_btn_off.png\" />\n          <Image Name=\"back_btn_on.png\" />\n          <Image Name=\"back_icon.png\" />\n          <Image Name=\"Cancel_Normal.png\" />\n          <Image Name=\"Cancel_Press.png\" />\n          <Image Name=\"CheckBox_Disable.png\" />\n          <Image Name=\"CheckBox_Normal.png\" />\n          <Image Name=\"CheckBox_Press.png\" />\n          <Image Name=\"CheckBoxNode_Normal.png\" />\n          <Image Name=\"CheckBoxNode_Press.png\" />\n          <Image Name=\"circle_arrow.png\" />\n          <Image Name=\"circle_arrow_normal.png\" />\n          <Image Name=\"circle_arrow_press.png\" />\n          <Image Name=\"circle_white.png\" />\n          <Image Name=\"empty.png\" />\n          <Image Name=\"exit_icon.png\" />\n          <Image Name=\"gray.png\" />\n          <Image Name=\"keyboard_icon.png\" />\n          <Image Name=\"menu_handler.png\" />\n          <Image Name=\"menu_icon.png\" />\n          <Image Name=\"menu_press.png\" />\n          <Image Name=\"mouse_2btn.png\" />\n          <Image Name=\"mouse_icon.png\" />\n          <Image Name=\"mouse_left_btn.png\" />\n          <Image Name=\"mouse_right_btn.png\" />\n          <Image Name=\"right_triangle.png\" />\n          <Image Name=\"syssetting_btn_ff.png\" />\n          <Image Name=\"syssetting_btn_on.png\" />\n          <Image Name=\"touch_icon.png\" />\n          <Image Name=\"touch1.png\" />\n          <Image Name=\"touch2.png\" />\n          <Image Name=\"triangle.png\" />\n          <Image Name=\"white.png\" />\n          <Image Name=\"windows_icon.png\" />\n        </Folder>\n        <Folder Name=\"ui\">\n          <Folder Name=\"comctrl\">\n            <Project Name=\"CheckBoxItem.csd\" Type=\"Layer\" />\n            <Project Name=\"SelectListItem.csd\" Type=\"Layer\" />\n            <Project Name=\"SeperateItem.csd\" Type=\"Layer\" />\n            <Project Name=\"SliderIconItem.csd\" Type=\"Layer\" />\n            <Project Name=\"SliderTextItem.csd\" Type=\"Layer\" />\n            <Project Name=\"SubDirItem.csd\" Type=\"Layer\" />\n          </Folder>\n          <Folder Name=\"help\">\n            <Project Name=\"AllTips.csd\" Type=\"Layer\" />\n            <Project Name=\"MouseModeTips.csd\" Type=\"Layer\" />\n            <Project Name=\"ScreenModeTips.csd\" Type=\"Layer\" />\n            <Project Name=\"TouchModeTips.csd\" Type=\"Layer\" />\n          </Folder>\n          <Project Name=\"BottomBar.csd\" Type=\"Layer\" />\n          <Project Name=\"BottomBarTextInput.csd\" Type=\"Layer\" />\n          <Project Name=\"CheckListDialog.csd\" Type=\"Layer\" />\n          <Project Name=\"FileItem.csd\" Type=\"Layer\" />\n          <Project Name=\"FileManageMenu.csd\" Type=\"Layer\" />\n          <Project Name=\"GameMenu.csd\" Type=\"Layer\" />\n          <Project Name=\"KeySelect.csd\" Type=\"Layer\" />\n          <Project Name=\"ListItem.csd\" Type=\"Layer\" />\n          <Project Name=\"ListView.csd\" Type=\"Layer\" />\n          <Project Name=\"MainFileSelector.csd\" Type=\"Layer\" />\n          <Project Name=\"MediaPlayerBody.csd\" Type=\"Layer\" />\n          <Project Name=\"MediaPlayerFoot.csd\" Type=\"Layer\" />\n          <Project Name=\"MediaPlayerNavi.csd\" Type=\"Layer\" />\n          <Project Name=\"MenuList.csd\" Type=\"Layer\" />\n          <Project Name=\"MessageBox.csd\" Type=\"Layer\" />\n          <Project Name=\"NaviBar.csd\" Type=\"Layer\" />\n          <Project Name=\"NaviBarWithMenu.csd\" Type=\"Layer\" />\n          <Project Name=\"ProgressBox.csd\" Type=\"Layer\" />\n          <Project Name=\"RecentListItem.csd\" Type=\"Layer\" />\n          <Project Name=\"SelectList.csd\" Type=\"Layer\" />\n          <Project Name=\"SelectListItem.csd\" Type=\"Layer\" />\n          <Project Name=\"TableView.csd\" Type=\"Layer\" />\n          <Project Name=\"TextPairInput.csd\" Type=\"Layer\" />\n          <Project Name=\"WinMgrOverlay.csd\" Type=\"Layer\" />\n        </Folder>\n        <TTF Name=\"DroidSansFallback.ttf\" />\n      </RootFolder>\n    </Group>\n  </SolutionFolder>\n</Solution>"
  },
  {
    "path": "project/ui/kr2.cfg",
    "content": "<SolutionConfig Version=\"3.10.0.0\">\n  <PublishDirectory Value=\"Resources/res\" />\n  <PackageDirectory Value=\"package\\\" />\n  <PublishType Value=\"Reference\" />\n  <SolutionSize Value=\"1280 * 720\" />\n  <ResolutionName Value=\"Android\" />\n  <DefaultSerializer Value=\"Serializer_FlatBuffers\" />\n  <CustomSerializer Value=\"Serializer_FlatBuffers\" />\n  <IsNameStandardized Value=\"False\" />\n  <CustomProperties>\n    <Item Key=\"CCS_CocosPropertis\">\n      <Value ctype=\"CocosProperties\">\n        <SolutionCodeType Value=\"Complete\" />\n        <ProgramLanguage Value=\"cpp\" />\n        <CreateFrameworkVersion Value=\"cocos2d-x-3.6\" />\n        <CurrentFrameworkVersion Value=\"cocos2d-x-3.6\" />\n        <EngineType Value=\"Prebuilt\" />\n      </Value>\n    </Item>\n  </CustomProperties>\n</SolutionConfig>"
  },
  {
    "path": "readme.md",
    "content": "# Krikiroid2-Yuri  \n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/YuriSizuku/Kirikiroid2Yuri?color=green&label=krkr2yuri&style=flat-square7&logo=4chan)  ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/YuriSizuku/Kirikiroid2Yuri/build_android.yml?label=android%28aarch64%29&style=flat-square)\n\n☘️ A krikiroid2 project matained by Yurisizuku.  \nIt will support the newer android device and more formats.\n\nRoadmap :\n\n- core\n  - [ ] replace rendering from cocos to SDL2\n  - [ ] command line or config files for setting\n  - [ ] recent cx game (hash filename) decryption support\n- plugin\n  - [ ] [windowEx](https://github.com/wamsoft/windowEx)\n  - [ ] [layerEx](https://github.com/wamsoft/layerEx)\n  - [ ] [layerExDraw](https://github.com/wamsoft/layerExDraw) (gdiPlus)\n  - [ ] [scriptsEx](https://github.com/wamsoft/scriptsEx)\n- platform\n  - android\n    - [x] SDK level above 21 (android 5.1, Lolipop)\n    - [x] bypass scoped storage\n    - [ ] access extern sdcard by saf\n  - windows\n  - linux\n- develop  \n  - [x] camke project structure, documention for develop\n  - [x] scripts to compile or cross compile\n  - [x] vscode and android studio project for multi enviroment\n  - [x] ci in github action to automaticly build\n\n(This project is heavily relying on cocos. Sooner or later, I might rewrite these parts and replace them by SDL2. And because that the upstream didn't provide all the plugins source code, it still needs sometime to adapt them.)\n\n## 1. usage  \n\nAlthough now the apk build from source is runable, it is not perfect. Beta version has some problems due to the cocos version change, incomplecate of some code. Currently the beta version is only aimed for debug. Please use [Kirikiroid2_yuri_1.3.9.apk](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk) instead.  \n\n## 2. Build  \n\nI add some futures by reverse engine before, and now this project can be build from source.  This is really a very hard work, because there are so many dependencies, lack of files, code not compatible problems.  \n\n### (1) prepare  \n\n- wget, 7z, git, make, cmake  \n- python2(for cocos2d-x v3), msys2 (if windows)  \n- thirdparty depedency (see `_fetch.sh` in detail)  \n\n``` shell\n# wget \nhttps://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz\nhttps://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz\nhttps://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.gz\nhttps://downloads.xiph.org/releases/opus/opusfile-0.12.tar.gz\nhttps://www.rarlab.com/rar/unrarsrc-6.0.7.tar.gz\nhttps://www.libsdl.org/release/SDL2-2.0.14.tar.gz\n\n# git\nhttps://github.com/krkrz/oniguruma\nhttps://github.com/google/breakpad\nhttps://github.com/zeas2/FFmpeg\n\n# git with version\nhttps://github.com/google/oboe/archive/refs/tags/1.7.0.tar.gz\nhttps://github.com/kcat/openal-soft/archive/refs/tags/1.23.0.tar.gz\nhttps://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/2.1.5.1.tar.gz\nhttps://github.com/opencv/opencv/archive/refs/tags/4.7.0.tar.gz\nhttps://github.com/lz4/lz4/archive/refs/tags/v1.9.4.tar.gz\nhttps://github.com/libarchive/libarchive/archive/refs/tags/v3.6.2.tar.gz\nhttps://github.com/cocos2d/cocos2d-x/archive/refs/tags/cocos2d-x-3.17.2.tar.gz\n```\n\nIn windows, you must use msys2 to build ffmpeg port.  \nYou can also download the prebuild ports from [thirdparty_ports.tar.gz](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_ports.tar.gz\"), [thirdparty_build.tar.gz](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_build.tar.gz).  \n\n## (2) android  \n\n- android sdk with `ANDROID_HOME` variable in env  \n- android ndk 25.2.9519653  \n\nSee `_androida64.sh` for how to build dependencies.\nUse `script/cross_android64.sh` to build ports and the use `project/android/gradlew assembleDebug` to build apk.\n\n## 3. Compatibility  \n\n|game|version|status|description|\n|----|-------|------|-----------|\n\n## 4. Issues (including solved)\n\n(build from souce, beta version)  \n\nmajor:  \n\n- title path button click position is not correct\n- crash in game menu form  \n- game alert window button can not click  \n- member GdiPlus does not exist\n- global preference can not save\n\nminor:  \n\n- ~~android studio buildDir not worked and it make dir at root~~ fixed by cmake `add_subdirectory` build dir\n\n## 5. Todo\n\nSee Roadmap.  \n___\nOriginal information about kirikiroid2 bellow, also refered some dependencies from [ningshanwutuobang](https://github.com/ningshanwutuobang/Kirikiroid2).  \n\n## Kirikiroid2 - A cross-platform port of Kirikiri2/KirikiriZ  \n\n==========================================================\n\nBased on most code from [Kirikiri2](http://kikyou.info/tvp/) and [KirikiriZ](https://github.com/krkrz/krkrz)\n\nVideo playback module modified from [kodi](https://github.com/xbmc/xbmc)\n\nSome string code from [glibc](https://www.gnu.org/s/libc) and [Apple Libc](https://opensource.apple.com/source/Libc).\n\nReal-time texture codec modified from [etcpak](https://bitbucket.org/wolfpld/etcpak.git), [pvrtccompressor](https://bitbucket.org/jthlim/pvrtccompressor), [astcrt](https://github.com/daoo/astcrt)\n\nAndroid storage accessing code from [AmazeFileManager](https://github.com/arpitkh96/AmazeFileManager)\n"
  },
  {
    "path": "script/_androida64.sh",
    "content": "# must use after _fetch.sh from cross_androida64.sh\n\n# audio\nbuild_opus() \n{\n    if ! [ -d $OPUS_SRC/build_$PLATFORM ]; then mkdir -p $OPUS_SRC/build_$PLATFORM ;fi\n    \n    pushd $OPUS_SRC/build_$PLATFORM\n    ../configure --host=aarch64-linux-android \\\n        CC=aarch64-linux-android21-clang  AR=llvm-ar \\\n        CXX=aarch64-linux-android21-clang++ \\\n        --prefix=$PORTBUILD_PATH --with-pic\n    make -j$CORE_NUM &&  make install\n    popd\n}\n\nbuild_ogg() \n{\n    if ! [ -d $OGG_SRC/build_$PLATFORM ]; then mkdir -p $OGG_SRC/build_$PLATFORM ;fi\n    \n    pushd $OGG_SRC/build_$PLATFORM\n    ../configure --host=aarch64-linux-android \\\n        CC=aarch64-linux-android21-clang  AR=llvm-ar \\\n        CXX=aarch64-linux-android21-clang++ \\\n        --prefix=$PORTBUILD_PATH --with-pic\n    make -j$CORE_NUM &&  make install\n    popd\n}\n\nbuild_vorbis() \n{\n    if ! [ -d $VORBIS_SRC/build_$PLATFORM ]; then mkdir -p $VORBIS_SRC/build_$PLATFORM ;fi\n    \n    pushd $VORBIS_SRC/build_$PLATFORM\n    ../configure --host=aarch64-linux-android \\\n        CC=aarch64-linux-android21-clang  AR=llvm-ar \\\n        CXX=aarch64-linux-android21-clang++ \\\n        --prefix=$PORTBUILD_PATH --with-pic \\\n        --with-ogg=$PORTBUILD_PATH\n    make -j$CORE_NUM &&  make install\n    popd\n}\n\nbuild_opusfile() # after ogg, opus, vorbits\n{\n    if ! [ -d $OPUSFILE_SRC/build_$PLATFORM ]; then mkdir -p $OPUSFILE_SRC/build_$PLATFORM ;fi\n    \n    pushd $OPUSFILE_SRC/build_$PLATFORM\n    ../configure --host=aarch64-linux-android \\\n        CC=aarch64-linux-android21-clang  AR=llvm-ar \\\n        CXX=aarch64-linux-android21-clang++ \\\n        --prefix=$PORTBUILD_PATH --with-pic \\\n        DEPS_CFLAGS=\"-I$PORTBUILD_PATH/include -I$PORTBUILD_PATH/include/opus\" \\\n        DEPS_LIBS=\"-L$PORTBUILD_PATH/lib -logg -lopus\" \\\n        --disable-http --disable-examples\n    make -j$CORE_NUM &&  make install\n    \n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/opus/opusfile.h $PORTBUILD_PATH/include/opus/opusfile.h\n    \n    popd\n}\n\nbuild_oboe()\n{\n    if ! [ -d $OBOE_SRC/build_$PLATFORM ]; then mkdir -p $OBOE_SRC/build_$PLATFORM ;fi\n    \n    pushd $OBOE_SRC/build_$PLATFORM \n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_C_FLAGS=\"-fPIC\" -DCMAKE_CXX_FLAGS=\"-fPIC\" \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \\\n        -DLIBTYPE=STATIC\n    make -j$CORE_NUM &&  make install \n\n    mv -f $PORTBUILD_PATH/lib/arm64-v8a/liboboe.a $PORTBUILD_PATH/lib/liboboe.a\n\n    popd\n}\n\nbuild_openal()\n{\n    if ! [ -d $OPENAL_SRC/build_$PLATFORM ]; then mkdir -p $OPENAL_SRC/build_$PLATFORM ;fi\n\n    pushd $OPENAL_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_C_FLAGS=\"-fPIC\" -DCMAKE_CXX_FLAGS=\"-fPIC\" \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \\\n        -DLIBTYPE=STATIC\n    make -j$CORE_NUM &&  make install \n    popd\n}\n\n# video\nbuild_jpeg() \n{\n    if ! [ -d $JPEG_SRC/build_$PLATFORM ]; then mkdir -p $JPEG_SRC/build_$PLATFORM ;fi\n    \n    pushd $JPEG_SRC/build_$PLATFORM\n    NDK_PATH=$NDK_HOME\n    TOOLCHAIN=clang\n    ANDROID_VERSION=21\n    cmake .. -G \"Unix Makefiles\" \\\n        -DANDROID_ABI=arm64-v8a \\\n        -DANDROID_ARM_MODE=arm \\\n        -DANDROID_PLATFORM=android-${ANDROID_VERSION} \\\n        -DANDROID_TOOLCHAIN=${TOOLCHAIN} \\\n        -DCMAKE_ASM_FLAGS=\"--target=aarch64-linux-android${ANDROID_VERSION}\" \\\n        -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH\n    make -j$CORE_NUM &&  make install\n    popd\n}\n\nbuild_opencv()\n{\n    if ! [ -d $OPENCV_SRC/build_$PLATFORM ]; then mkdir -p $OPENCV_SRC/build_$PLATFORM ;fi\n\n    pushd $OPENCV_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \\\n        -DWITH_CUDA=OFF -DWITH_MATLAB=OFF -DBUILD_ANDROID_EXAMPLES=OFF \\\n        -DBUILD_DOCS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF \\\n        -DBUILD_opencv_video=OFF -DBUILD_opencv_videoio=OFF -DBUILD_opencv_features2d=OFF \\\n        -DBUILD_opencv_flann=OFF -DBUILD_opencv_highgui=OFF -DBUILD_opencv_ml=OFF \\\n        -DBUILD_opencv_dnn=OFF -DBUILD_opencv_gapi=OFF -DBUILD_opencv_hal=ON \\\n        -DBUILD_opencv_photo=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_shape=OFF \\\n        -DBUILD_opencv_stitching=OFF -DBUILD_opencv_superres=OFF -DWITH_ITT=OFF \\\n        -DBUILD_opencv_ts=OFF -DBUILD_opencv_videostab=OFF -DBUILD_ANDROID_PROJECTS=OFF\n    make -j$CORE_NUM &&  make install\n    \n    cp -rf  $PORTBUILD_PATH/sdk/native/3rdparty/libs/arm64-v8a/*.a $PORTBUILD_PATH/lib\n    cp -rf  $PORTBUILD_PATH/sdk/native/staticlibs/arm64-v8a/libtegra_hal.a $PORTBUILD_PATH/lib\n    \n    popd\n}\n\nbuild_ffmpeg() \n{\n    if ! [ -d $FFMPEG_SRC/build_$PLATFORM ]; then mkdir -p $FFMPEG_SRC/build_$PLATFORM ;fi\n    \n    pushd $FFMPEG_SRC\n    git apply  $CMAKELISTS_PATH/thirdparty/patch/ffmpeg/android_ffmpeg.diff\n    cd build_$PLATFORM\n    ../configure --enable-cross-compile --cross-prefix=aarch64-linux-android- \\\n        --cc=aarch64-linux-android21-clang  --ar=llvm-ar \\\n        --cxx=aarch64-linux-android21-clang++ --ranlib=llvm-ranlib \\\n        --strip=llvm-strip --prefix=$PORTBUILD_PATH \\\n        --arch=aarch64 --target-os=android --enable-pic --disable-asm \\\n        --enable-static --enable-shared --enable-small --enable-swscale \\\n        --disable-ffmpeg --disable-ffplay --disable-ffprobe \\\n        --disable-avdevice --disable-programs --disable-doc --enable-stripping\n\n    # use sh directory is not available in windows (absolute path), must use msys2 shell\n    make -j$CORE_NUM &&  make install\n    popd\n}\n\n# archive\nbuild_unrar() \n{   \n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/unrar/android_ulinks.cpp $UNRAR_SRC/ulinks.cpp\n    \n    pushd $UNRAR_SRC\n    make clean\n    make lib -j$CORE_NUM \\\n        CXX=aarch64-linux-android21-clang++ \\\n        AR=llvm-ar STRIP=llvm-strip \\\n        DESTDIR=$PORTBUILD_PATH  \n    \n    if ! [ -d $PORTBUILD_PATH/include/unrar ]; then mkdir -p $PORTBUILD_PATH/include/unrar ;fi \n    cp -rf *.a $PORTBUILD_PATH/lib\n    cp -rf *.hpp $PORTBUILD_PATH/include/unrar\n    \n    popd\n}\n\nbuild_lz4()\n{\n    pushd $LZ4_SRC\n    make clean\n    make lib -j$CORE_NUM \\\n        CC=aarch64-linux-android21-clang \\\n        CXX=aarch64-linux-android21-clang++ \\\n        AR=llvm-ar STRIP=llvm-strip \\\n        WINBASED=no\n    \n    if ! [ -d $PORTBUILD_PATH/include/lz4 ]; then mkdir -p $PORTBUILD_PATH/include/lz4 ;fi \n    cp -rp lib/*.a $PORTBUILD_PATH/lib\n    cp -rp lib/*.h $PORTBUILD_PATH/include/lz4\n    \n    popd\n}\n\nbuild_archive()\n{\n    if ! [ -d $ARCHIVE_SRC/build_$PLATFORM ]; then mkdir -p $ARCHIVE_SRC/build_$PLATFORM ;fi\n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/android_android_lf.h  $ARCHIVE_SRC/libarchive/android_lf.h\n    \n    pushd $ARCHIVE_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DENABLE_OPENSSL=OFF -DENABLE_TEST=OFF \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH\n    make -j$CORE_NUM &&  make install\n\n    if ! [ -d $PORTBUILD_PATH/include/libarchive ]; then mkdir -p $PORTBUILD_PATH/include/libarchive ;fi \n    mv -f $PORTBUILD_PATH/include/archive.h $PORTBUILD_PATH/include/libarchive\n    mv -f $PORTBUILD_PATH/include/archive_entry.h $PORTBUILD_PATH/include/libarchive\n    \n    popd\n}\n\nbuild_p7zip()\n{\n    if ! [ -d $P7ZIP_SRC/build_$PLATFORM ]; then mkdir -p $P7ZIP_SRC/build_$PLATFORM ;fi\n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/p7zip/7z* $P7ZIP_SRC/C\n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/p7zip/android_p7zip.cmake $P7ZIP_SRC/CPP/ANDROID/7za/jni/CMakeLists.txt\n\n    pushd $P7ZIP_SRC/build_$PLATFORM\n    cmake ../CPP/ANDROID/7za/jni -G \"Unix Makefiles\" \\\n        -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake\n    make -j$CORE_NUM\n    \n    if ! [ -d $PORTBUILD_PATH/include/p7zip/C ]; then mkdir -p $PORTBUILD_PATH/include/p7zip/C ;fi \n    if ! [ -d $PORTBUILD_PATH/include/p7zip/CPP ]; then mkdir -p $PORTBUILD_PATH/include/p7zip/CPP ;fi \n    cp -rf lib7za.a $PORTBUILD_PATH/lib\n    cp -rf ../C/*.h  $PORTBUILD_PATH/include/p7zip/C\n    cp -rf ../CPP  $PORTBUILD_PATH/include/p7zip\n    rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/*.cpp\n    rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/*.cpp\n    rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/**/*.cpp\n    rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/**/**/*.cpp\n    rm -rf $PORTBUILD_PATH/include/p7zip/CPP/ANDROID/7za/obj\n\n    popd\n}\n\n# others\nbuild_oniguruma()\n{\n    if ! [ -d $ONIGURUMA_SRC/build_$PLATFORM ]; then mkdir -p $ONIGURUMA_SRC/build_$PLATFORM ;fi\n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/oniguruma/oniguruma.cmake $ONIGURUMA_SRC/CMakeLists.txt\n    \n    pushd $ONIGURUMA_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \n    make -j$CORE_NUM &&  make install \n    popd\n}\n\nbuild_breakpad() # after linux-syscall\n{\n    if ! [ -d $BREAKPAD_SRC/build_$PLATFORM ]; then mkdir -p $BREAKPAD_SRC/build_$PLATFORM ;fi\n    cp -rf $SYSCALL_SRC/lss $BREAKPAD_SRC/src/third_party/\n    \n    pushd $BREAKPAD_SRC/build_$PLATFORM\n    ../configure --host=aarch64-linux-android \\\n        CC=aarch64-linux-android21-clang  AR=llvm-ar \\\n        CXX=aarch64-linux-android21-clang++ STRIP=llvm-strip \\\n        --prefix=$PORTBUILD_PATH \\\n        --disable-tools\n    make -j$CORE_NUM &&  make install-strip\n    popd\n}\n\n# framework\nbuild_sdl2()\n{\n    if ! [ -d $SDL2_SRC/build_$PLATFORM ]; then mkdir -p $SDL2_SRC/build_$PLATFORM ;fi\n    cp -rf $CMAKELISTS_PATH/thirdparty/patch/sdl2/android_SDL_android.c  $SDL2_SRC/src/core/android/SDL_android.c\n    \n    pushd $SDL2_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DANDROID=ON -DCMAKE_SYSTEM_NAME=Linux \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \\\n        -DHIDAPI=OFF -DHAVE_GCC_WDECLARATION_AFTER_STATEMENT=OFF\n    make -j$CORE_NUM &&  make install \n    popd\n}\n\nbuild_cocos2dx()\n{\n    if ! [ -d $COCOS2DX_SRC/platform/build_$PLATFORM ]; then mkdir -p $COCOS2DX_SRC/build_$PLATFORM ;fi\n    cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_cocos2dx.cmake $COCOS2DX_SRC/CMakeLists.txt\n    cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_CCFileUtils-android.h $COCOS2DX_SRC/cocos/platform/android/CCFileUtils-android.h\n    cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_CCFileUtils-android.cpp $COCOS2DX_SRC/cocos/platform/android/CCFileUtils-android.cpp\n    cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.h $COCOS2DX_SRC/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h\n    cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.cpp $COCOS2DX_SRC/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.cpp\n\n\n    pushd $COCOS2DX_SRC/build_$PLATFORM\n    cmake .. -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=MinSizeRel \\\n        -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n        -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n        -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \\\n        -DBUILD_TESTS=OFF -DBUILD_LUA_LIBS=OFF -DBUILD_JS_LIBS=OFF\n    make -j$CORE_NUM\n    \n    cp -rf lib/libcocos2d.a $PORTBUILD_PATH/lib/\n    cp -rf lib/libext_*.a $PORTBUILD_PATH/lib/\n    cp -rf engine/cocos/android/libcpp_android_spec.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/zlib/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/png/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/tiff/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/webp/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/freetype2/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/chipmunk/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    cp -rf ../external/bullet/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/\n    \n    popd\n}"
  },
  {
    "path": "script/_fetch.sh",
    "content": "# prepare dirs\nif ! [ -d $CMAKELISTS_PATH/thirdparty/port ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/port; fi\nif ! [ -d $CMAKELISTS_PATH/thirdparty/build/arch_androida32 ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/build/arch_androida32; fi\nif ! [ -d $CMAKELISTS_PATH/thirdparty/build/arch_androida64 ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/build/arch_androida64; fi\n\n# fetch by wget\nfunction fetch_port() # urlbase, name, outpath\n{\n    if ! [ -d \"$CMAKELISTS_PATH/thirdparty/port/$2\" ]; then\n        echo \"## fetch_port $1 $2\"\n        wget $1/$2.tar.gz -O $CMAKELISTS_PATH/thirdparty/port/$2.tar.gz \n        tar zxf $CMAKELISTS_PATH/thirdparty/port/$2.tar.gz -C $CMAKELISTS_PATH/thirdparty/port\n    fi\n}\n\n# fetch by git\nfunction fetch_port2()\n{\n    if ! [ -d \"$CMAKELISTS_PATH/thirdparty/port/$2\" ]; then\n        inpath=$1/$2.git\n        outpath=$CMAKELISTS_PATH/thirdparty/port/$2\n        tag=$3\n        echo \"## fetch_port $inpath $tag\"\n        if [ -n \"$tag\" ]; then \n            git clone --recursive --depth 1 --branch $tag $inpath $outpath \n        else\n            git clone --recursive --depth 1 $inpath $outpath\n        fi\n    fi\n}\n\n# wget ports\nfunction fetch_vorbis()\n{\n    VORBIS_NAME=libvorbis-1.3.7\n    VORBIS_SRC=$CMAKELISTS_PATH/thirdparty/port/$VORBIS_NAME\n    fetch_port https://downloads.xiph.org/releases/vorbis $VORBIS_NAME\n}\n\nfunction fetch_opus()\n{\n    OPUS_NAME=opus-1.3.1\n    OPUS_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPUS_NAME\n    fetch_port https://archive.mozilla.org/pub/opus $OPUS_NAME\n}\n\nfunction fetch_ogg()\n{\n    OGG_NAME=libogg-1.3.5\n    OGG_SRC=$CMAKELISTS_PATH/thirdparty/port/$OGG_NAME\n    fetch_port https://downloads.xiph.org/releases/ogg $OGG_NAME\n}\n\nfunction fetch_opusfile()\n{\n    OPUSFILE_NAME=opusfile-0.12\n    OPUSFILE_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPUSFILE_NAME\n    fetch_port https://downloads.xiph.org/releases/opus $OPUSFILE_NAME\n}\n\nfunction fetch_unrar()\n{\n    UNRAR_NAME=unrarsrc-6.0.7\n    UNRAR_SRC=$CMAKELISTS_PATH/thirdparty/port/$UNRAR_NAME\n    fetch_port https://www.rarlab.com/rar $UNRAR_NAME\n    if [ -d $CMAKELISTS_PATH/thirdparty/port/unrar ]; then\n        mv $CMAKELISTS_PATH/thirdparty/port/unrar $UNRAR_SRC\n    fi\n}\n\nfunction fetch_p7zip()\n{\n    P7ZIP_NAME=p7zip_16.02\n    P7ZIP_SRC=$CMAKELISTS_PATH/thirdparty/port/$P7ZIP_NAME\n    if ! [ -d \"$P7ZIP_SRC\" ]; then\n        echo \"## fetch_port $P7ZIP_NAME\"\n        wget https://sourceforge.net/projects/p7zip/files/p7zip/16.02/p7zip_16.02_src_all.tar.bz2 \\\n            -O $CMAKELISTS_PATH/thirdparty/port/$P7ZIP_NAME.tar.bz2\n        tar zxf $CMAKELISTS_PATH/thirdparty/port//$P7ZIP_NAME.tar.bz2 \\\n            -C $CMAKELISTS_PATH/thirdparty/port\n    fi \n}\n\nfunction fetch_sdl2()\n{\n    SDL2_NAME=SDL2-2.0.14\n    SDL2_SRC=$CMAKELISTS_PATH/thirdparty/port/$SDL2_NAME\n    fetch_port https://www.libsdl.org/release $SDL2_NAME\n}\n\n# git ports\nfunction fetch_openal()\n{\n    OPENAL_NAME=openal-soft\n    OPENAL_VERSION=1.23.0\n    OPENAL_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPENAL_NAME\n    fetch_port2 https://github.com/kcat $OPENAL_NAME $OPENAL_VERSION\n}\n\nfunction fetch_oboe()\n{\n    OBOE_NAME=oboe\n    OBOE_VERSION=1.7.0\n    OBOE_SRC=$CMAKELISTS_PATH/thirdparty/port/$OBOE_NAME\n    fetch_port2 https://github.com/google $OBOE_NAME $OBOE_VERSION\n}\n\nfunction fetch_jpeg()\n{\n    JPEG_NAME=libjpeg-turbo\n    JPEG_SRC=$CMAKELISTS_PATH/thirdparty/port/$JPEG_NAME\n    JPEG_VERSION=2.1.5.1\n    fetch_port2 https://github.com/libjpeg-turbo $JPEG_NAME $JPEG_VERSION\n}\n\nfunction fetch_opencv()\n{\n    OPENCV_NAME=opencv\n    OPENCV_VERSION=4.7.0\n    OPENCV_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPENCV_NAME\n    fetch_port2 https://github.com/opencv $OPENCV_NAME $OPENCV_VERSION\n}\n\nfunction fetch_ffmpeg()\n{\n    FFMPEG_NAME=ffmpeg\n    FFMPEG_SRC=$CMAKELISTS_PATH/thirdparty/port/$FFMPEG_NAME\n    fetch_port2 https://github.com/zeas2 $FFMPEG_NAME\n}\n\nfunction fetch_lz4()\n{\n    LZ4_NAME=lz4\n    LZ4_VERSION=v1.9.4\n    LZ4_SRC=$CMAKELISTS_PATH/thirdparty/port/$LZ4_NAME\n    fetch_port2 https://github.com/lz4 $LZ4_NAME $LZ4_VERSION\n}\n\nfunction fetch_archive()\n{\n    ARCHIVE_NAME=libarchive\n    ARCHIVE_VERSION=v3.6.2\n    ARCHIVE_SRC=$CMAKELISTS_PATH/thirdparty/port/$ARCHIVE_NAME\n    fetch_port2 https://github.com/libarchive $ARCHIVE_NAME $ARCHIVE_VERSION\n}\n\nfunction fetch_oniguruma()\n{\n    ONIGURUMA_NAME=oniguruma\n    ONIGURUMA_SRC=$CMAKELISTS_PATH/thirdparty/port/$ONIGURUMA_NAME\n    fetch_port2 https://github.com/krkrz $ONIGURUMA_NAME\n}\n\nfunction fetch_syscall()\n{\n    SYSCALL_NAME=linux-syscall-support\n    SYSCALL_SRC=$CMAKELISTS_PATH/thirdparty/port/$SYSCALL_NAME\n    fetch_port2 https://github.com/adelshokhy112 $SYSCALL_NAME\n}\n\nfunction fetch_breakpad()\n{\n    BREAKPAD_NAME=breakpad\n    BREAKPAD_SRC=$CMAKELISTS_PATH/thirdparty/port/$BREAKPAD_NAME\n    fetch_port2 https://github.com/google $BREAKPAD_NAME\n}\n\nfunction fetch_cocos2dx()\n{\n    COCOS2DX_NAME=cocos2d-x\n    COCOS2DX_VERSION=cocos2d-x-3.17.2\n    COCOS2DX_SRC=$CMAKELISTS_PATH/thirdparty/port/$COCOS2DX_NAME\n    fetch_port2 https://github.com/cocos2d $COCOS2DX_NAME $COCOS2DX_VERSION\n\n    if ! [ -d \"$CMAKELISTS_PATH/thirdparty/port/$COCOS2DX_NAME\" ]; then    \n        pushd $COCOS2DX_SRC\n            python2 download-deps.py # must use cocos v3 and python2\n            git config --global url.https://github.com/.insteadOf git://github.com/\n            git submodule update --init # submodule might cuse some problem, as it use git@\n        popd\n    fi\n}\n\n# android \nfunction fetch_asset()\n{\n    if ! [ -d \"$CMAKELISTS_PATH/assets\" ]; then\n        wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk \\\n            -O $CMAKELISTS_PATH/thirdparty/port/Kirikiroid2_yuri_1.3.9.apk\n        7z x -o$CMAKELISTS_PATH $CMAKELISTS_PATH/thirdparty/port/Kirikiroid2_yuri_1.3.9.apk assets\n    fi\n}\n\n# notused  ports\nfunction fetch_bpg()\n{\n    BPG_NAME=android-bpg\n    BPG_SRC=$CMAKELISTS_PATH/thirdparty/port/$BPG_NAME\n    fetch_port2 https://github.com/alexandruc $BPG_NAME\n}\n\nfunction fetch_jxr()\n{\n    JXR_NAME=jxrlib\n    JXR_SRC=$CMAKELISTS_PATH/thirdparty/port/$JXR_NAME\n    fetch_port2 https://github.com/krkrz $JXR_NAME\n}"
  },
  {
    "path": "script/cross_androida64.sh",
    "content": "# bash -c \"export SKIP_PORTS=yes && ./cross_androida64.sh\"\nPLATFORM=androida64\nBUILD_PATH=./../build_${PLATFORM}\nCMAKELISTS_PATH=$(pwd)/..\nPORTBUILD_PATH=$CMAKELISTS_PATH/thirdparty/build/arch_$PLATFORM\nANDROID_THIRDPARTY_PATH=$CMAKELISTS_PATH/src/onsyuri_android/app/cpp/thirdparty\nCORE_NUM=$(cat /proc/cpuinfo | grep -c ^processor)\nTARGETS=$@\n\nfunction fetch_ports()\n{\n    # audio\n    fetch_opus\n    fetch_ogg\n    fetch_vorbis\n    fetch_opusfile\n    fetch_oboe\n    fetch_openal\n    \n    # video\n    fetch_jpeg\n    fetch_opencv\n    fetch_ffmpeg\n\n    # archive\n    fetch_unrar\n    fetch_lz4\n    fetch_archive\n    fetch_p7zip\n\n    # others\n    fetch_oniguruma\n    fetch_syscall\n    fetch_breakpad\n\n    # framework\n    fetch_sdl2\n    fetch_cocos2dx    \n}\n\nfunction build_ports()\n{\n    # audio\n    build_opus\n    build_ogg\n    build_vorbis\n    build_opusfile\n    build_oboe\n    build_openal\n\n    # video\n    build_jpeg\n    build_opencv\n    build_ffmpeg\n\n    # archive\n    build_unrar\n    build_lz4\n    build_archive\n    build_p7zip\n\n    # others\n    build_oniguruma\n    build_breakpad\n\n    # framework\n    build_sdl2\n    build_cocos2dx\n}\n\n# prepare env, tested with ndk 25.2.9519653\nif [ -z \"$ANDROID_HOME\" ]; then ANDROID_HOME=/d/Software/env/sdk/androidsdk; fi\nNDK_HOME=$ANDROID_HOME/ndk/$(ls -A $ANDROID_HOME/ndk | tail -n 1)\nPREBUILT_DIR=$NDK_HOME/toolchains/llvm/prebuilt\nPREBUILT_DIR=$PREBUILT_DIR/$(ls -A $PREBUILT_DIR | tail -n 1)\nPATH=$NDK_HOME/build:$PREBUILT_DIR/bin:$PATH\nCC=$(which aarch64-linux-android21-clang)\nCXX=$(which aarch64-linux-android21-clang++)\nAR=$(which llvm-ar)\nRANLIB=$(which llvm-ranlib)\nNM=$(which llvm-nm)\nSTRIP=$(which llvm-strip)\nNDKBUILD=$(which ndk-build)\nSYSROOT=$PREBUILT_DIR/sysroot\necho \"## ANDROID_HOME=$ANDROID_HOME\"\necho \"## NDK-BUILD=$NDKBUILD\"\necho \"## CC=$CC\"\necho \"## AR=$AR\"\n\n# fetch and build ports\n# SKIP_PORTS=\"yes\"\nsource ./_fetch.sh\nsource ./_$PLATFORM.sh\nfetch_asset\nif [ -z \"$SKIP_PORTS\" ]; then\n    fetch_ports\n    build_ports\nfi\n\n# config and build project\nif [ -z \"$BUILD_TYPE\" ]; then BUILD_TYPE=MinSizeRel; fi\nif [ -z \"$TARGETS\" ]; then TARGETS=all; fi\n\ncmake -B $BUILD_PATH -S $CMAKELISTS_PATH \\\n    -G \"Unix Makefiles\" -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n    -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \\\n    -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \\\n    -DPORTBUILD_PATH=$PORTBUILD_PATH\nmake -C $BUILD_PATH $TARGETS -j$CORE_NUM\n# make -C $BUILD_PATH $TARGETS -j1\n# $STRIP $BUILD_PATH/libkrkr2yuri.so"
  },
  {
    "path": "src/core/Android.mk",
    "content": "LOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := krkr2\n\nLOCAL_SRC_FILES := \\\n$(filter-out $(LOCAL_PATH)/visual/Resampler.cpp, $(wildcard $(LOCAL_PATH)/visual/*.cpp)) \\\n$(wildcard $(LOCAL_PATH)/base/7zip/*.c) \\\n$(wildcard $(LOCAL_PATH)/base/7zip/C/*.c) \\\n$(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*/*/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/base/*.cpp) \\\n$(filter-out $(LOCAL_PATH)/base/win32/FuncStubs.cpp $(LOCAL_PATH)/base/win32/SusieArchive.cpp, $(wildcard $(LOCAL_PATH)/base/win32/*.cpp)) \\\n$(filter-out $(LOCAL_PATH)/environ/MainFormUnit.cpp, $(wildcard $(LOCAL_PATH)/environ/*.cpp)) \\\n$(wildcard $(LOCAL_PATH)/environ/cocos2d/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/environ/android/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/environ/linux/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/environ/ui/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/environ/ui/extension/*.cpp) \\\nenviron/win32/SystemControl.cpp         \\\n$(wildcard $(LOCAL_PATH)/extension/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/movie/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/movie/*/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/msg/*.cpp) \\\nmsg/win32/MsgImpl.cpp               \\\nmsg/win32/OptionsDesc.cpp               \\\n$(filter-out $(LOCAL_PATH)/sound/xmmlib.cpp $(LOCAL_PATH)/sound/WaveFormatConverter_SSE.cpp, $(wildcard $(LOCAL_PATH)/sound/*.cpp)) \\\n$(wildcard $(LOCAL_PATH)/sound/win32/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/tjs2/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/utils/*.c) \\\n$(wildcard $(LOCAL_PATH)/utils/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/utils/encoding/*.c) \\\n$(wildcard $(LOCAL_PATH)/utils/minizip/*.c) \\\n$(wildcard $(LOCAL_PATH)/utils/minizip/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/utils/win32/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/visual/gl/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/visual/ogl/*.cpp) \\\n$(filter-out $(LOCAL_PATH)/visual/win32/GDIFontRasterizer.cpp $(LOCAL_PATH)/visual/win32/NativeFreeTypeFace.cpp \\\n\t$(LOCAL_PATH)/visual/win32/TVPSysFont.cpp $(LOCAL_PATH)/visual/win32/VSyncTimingThread.cpp \\\n\t, $(wildcard $(LOCAL_PATH)/visual/win32/*.cpp)) \\\n\nLOCAL_SRC_FILES := $(LOCAL_SRC_FILES:$(LOCAL_PATH)/%=%)\n\nLOCAL_C_INCLUDES += $(LOCAL_PATH)/base  \\\n                 $(LOCAL_PATH)/base/win32 \\\n                 $(LOCAL_PATH)/environ \\\n                 $(LOCAL_PATH)/environ/win32 \\\n                 $(LOCAL_PATH)/environ/android \\\n                 $(LOCAL_PATH)/environ/sdl \\\n                 $(LOCAL_PATH)/msg \\\n                 $(LOCAL_PATH)/msg/win32 \\\n                 $(LOCAL_PATH)/extension \\\n                 $(LOCAL_PATH)/sound \\\n                 $(LOCAL_PATH)/sound/win32 \\\n                 $(LOCAL_PATH)/tjs2 \\\n                 $(LOCAL_PATH)/utils \\\n                 $(LOCAL_PATH)/utils/win32 \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/freetype/current/include \\\n                 $(LOCAL_PATH)/visual \\\n                 $(LOCAL_PATH)/visual/ARM \\\n                 $(LOCAL_PATH)/visual/win32 \\\n                 $(LOCAL_PATH)/../plugins \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/jxrlib/current/common/include \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/jxrlib/current/image/sys \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/jxrlib/current/jxrgluelib \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/libjpeg-turbo/current \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/onig/current \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/libiconv/current/include \\\n\t\t\t\t $(LOCAL_PATH)/../../vendor/fmod/include \\\n                 $(LOCAL_PATH)/../../vendor/libgdiplus/src \\\n                 $(LOCAL_PATH)/../../vendor/opus/current/include \\\n                 $(LOCAL_PATH)/../../vendor/opus/opusfile/include \\\n                 $(LOCAL_PATH)/../../vendor/opencv/current/build/include \\\n                 $(LOCAL_PATH)/../../vendor/openal/current/include \\\n                 $(LOCAL_PATH)/../../vendor/lz4 \\\n\t\t\t\t $(LOCAL_PATH)/../../libs/android/bpg/include \\\n\t\t\t\t $(LOCAL_PATH)/../../libs/android/ffmpeg/include \\\n\t\t\t\t $(LOCAL_PATH)/../../libs/android/libarchive/include \\\n                 $(LOCAL_PATH)/visual/RenderScript/rs \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/cocos \\\n\t$(LOCAL_PATH)/../../vendor/cocos2d-x/current/cocos/platform \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/webp/include/android \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/jpeg/include/android \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/png/include/android \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external \\\n\nLOCAL_CPPFLAGS += -DTJS_TEXT_OUT_CRLF -D__STDC_CONSTANT_MACROS -DUSE_UNICODE_FSTRING\nLOCAL_CFLAGS += -DTJS_TEXT_OUT_CRLF -D_7ZIP_ST\nLOCAL_STATIC_LIBRARIES := ffmpeg libopencv_imgproc libopencv_core libopencv_hal libtbb gdiplus_static cpufeatures \\\n        opusfile_static opus_static onig_static libbpg_static vorbis_static cairo_static pixman_static expat_static \\\n\t\tbreakpad_client openal_static jxrlib_static libarchive_static\n# libRScpp_static\n\ninclude $(BUILD_STATIC_LIBRARY)\n$(call import-module, android/cpufeatures)\n$(call import-module, opus)\n$(call import-module, opusfile)\n$(call import-module, onig)\n$(call import-module, bpg)\n$(call import-module, opencv)\n$(call import-module, openal)\n$(call import-module, vorbis)\n#$(call import-module, android-ndk-profiler)\n$(call import-module, jxrlib)\n$(call import-module, ffmpeg)\n$(call import-module, cairo)\n$(call import-module, pixman)\n$(call import-module, gdiplus)\n$(call import-module, expat)\n$(call import-module, google_breakpad)\n#$(call import-module, libRScpp)\n$(call import-module, libarchive)"
  },
  {
    "path": "src/core/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.6)\r\nproject(krkr2core)\r\n\r\nset(KRKR2CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR})\r\nset(COCOS2DX_PATH ${KRKR2CORE_PATH}/../../thirdparty/port/cocos2d-x)\r\n\r\n# prepare static lib\r\nfunction(add_static_library TARGET LIBNAME)\r\n    if (\"${LIBNAME}\" STREQUAL \"\")\r\n        set(LIBNAME \"lib${TARGET}.a\")\r\n    endif()\r\n    add_library(\"${TARGET}_static\" STATIC IMPORTED GLOBAL)\r\n    set_target_properties(\"${TARGET}_static\"\r\n        PROPERTIES IMPORTED_LOCATION\r\n        ${PORTBUILD_PATH}/lib/${LIBNAME}\r\n    )\r\nendfunction()\r\n\r\nadd_static_library(jpeg libturbojpeg.a)\r\nadd_static_library(ogg \"\")\r\nadd_static_library(opus \"\")\r\nadd_static_library(opusfile \"\")\r\nadd_static_library(vorbis \"\")\r\nadd_static_library(vorbisfile \"\")\r\nadd_static_library(vorbisenc \"\")\r\nadd_static_library(openal \"\")\r\nadd_static_library(archive \"\")\r\nadd_static_library(avutil \"\")\r\nadd_static_library(avfilter \"\")\r\nadd_static_library(avformat \"\")\r\nadd_static_library(avcodec \"\")\r\nadd_static_library(swscale \"\")\r\nadd_static_library(swresample \"\")\r\nadd_static_library(onig \"\")\r\nadd_static_library(sdl2 libSDL2.a)\r\n\r\n# search kr2core src\r\nfile(GLOB KRKR2CORE_CODE\r\n    ${KRKR2CORE_PATH}/visual/*.cpp\r\n    ${KRKR2CORE_PATH}/base/*.cpp\r\n    ${KRKR2CORE_PATH}/base/win32/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/ConfigManager/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/cocos2d/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/linux/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/ui/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/ui/extension/*.cpp\r\n    ${KRKR2CORE_PATH}/environ/win32/SystemControl.cpp \r\n    ${KRKR2CORE_PATH}/extension/*.cpp\r\n    ${KRKR2CORE_PATH}/movie/*.cpp\r\n    ${KRKR2CORE_PATH}/movie/*/*.cpp\r\n    ${KRKR2CORE_PATH}/msg/*.cpp\r\n    ${KRKR2CORE_PATH}/msg/win32/MsgImpl.cpp\r\n    ${KRKR2CORE_PATH}/msg/win32/OptionsDesc.cpp \r\n    ${KRKR2CORE_PATH}/sound/*.cpp\r\n    ${KRKR2CORE_PATH}/sound/win32/*.cpp\r\n    ${KRKR2CORE_PATH}/tjs2/*.cpp\r\n    ${KRKR2CORE_PATH}/utils/*.c\r\n    ${KRKR2CORE_PATH}/utils/*.cpp\r\n    ${KRKR2CORE_PATH}/utils/encoding/*.c\r\n    ${KRKR2CORE_PATH}/utils/minizip/*.c\r\n    ${KRKR2CORE_PATH}/utils/minizip/*.cpp\r\n    ${KRKR2CORE_PATH}/utils/win32/*.cpp\r\n    ${KRKR2CORE_PATH}/visual/gl/*.cpp\r\n    ${KRKR2CORE_PATH}/visual/ogl/*.cpp\r\n    ${KRKR2CORE_PATH}/visual/win32/*.cpp\r\n)\r\n\r\nfile(GLOB KRKR2CORE_CODEANDROID\r\n    ${KRKR2CORE_PATH}/environ/android/*.cpp\r\n    ${KRKR2CORE_PATH}/sound/ARM/*.c\r\n    ${KRKR2CORE_PATH}/sound/ARM/*.cpp\r\n    ${KRKR2CORE_PATH}/visual/ARM/*.cpp\r\n    ${KRKR2CORE_PATH}/visual/ARM/*.c\r\n)\r\n\r\nlist(REMOVE_ITEM KRKR2CORE_CODE\r\n    ${KRKR2CORE_PATH}/base/win32/FuncStubs.cpp\r\n    ${KRKR2CORE_PATH}/base/win32/SusieArchive.cpp\r\n    ${KRKR2CORE_PATH}/environ/MainFormUnit.cpp\r\n    ${KRKR2CORE_PATH}/environ/XP3ArchiveRepack.cpp\r\n    ${KRKR2CORE_PATH}/environ/ui/XP3RepackForm.cpp\r\n    ${KRKR2CORE_PATH}/sound/xmmlib.cpp\r\n    ${KRKR2CORE_PATH}/sound/WaveFormatConverter_SSE.cpp\r\n    ${KRKR2CORE_PATH}/visual/Resampler.cpp\r\n    ${KRKR2CORE_PATH}/visual/win32/GDIFontRasterizer.cpp \r\n    ${KRKR2CORE_PATH}/visual/win32/NativeFreeTypeFace.cpp\r\n    ${KRKR2CORE_PATH}/visual/win32/TVPSysFont.cpp \r\n    ${KRKR2CORE_PATH}/visual/win32/VSyncTimingThread.cpp\r\n    ${KRKR2CORE_PATH}/visual/LoadJXR.cpp\r\n    ${KRKR2CORE_PATH}/visual/LoadBPG.cpp\r\n)\r\n\r\nif(CMAKE_SYSTEM_NAME MATCHES \"Android\")\r\n    list(APPEND KRKR2CORE_CODE ${KRKR2CORE_CODEANDROID})\r\n    set(PLATFORM android)\r\nelseif(CMAKE_SYSTEM_NAME MATCHES \"Linux\")\r\n    set(PLATFORM linux)\r\nelseif(CMAKE_SYSTEM_NAME MATCHES \"Windows\")\r\n    set(PLATFORM win32)\r\nelse()\r\n    set(PLATFORM android)\r\nendif()\r\n\r\n# make krkr2core\r\nadd_library(${PROJECT_NAME} STATIC ${KRKR2CORE_CODE})\r\nif(CMAKE_SYSTEM_NAME MATCHES \"Android\")\r\n    target_include_directories(${PROJECT_NAME} PUBLIC\r\n        ${PORTBUILD_PATH}/sdk/native/jni/include\r\n        ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures\r\n    )\r\n    target_link_libraries(${PROJECT_NAME} PUBLIC\r\n        -Wl,-Bdynamic\r\n        log\r\n        android\r\n        EGL\r\n        GLESv2\r\n        GLESv1_CM\r\n        OpenSLES\r\n    )\r\nendif()\r\ntarget_include_directories(${PROJECT_NAME} PUBLIC     \r\n    ${KRKR2CORE_PATH}/\r\n    ${KRKR2CORE_PATH}/base\r\n    ${KRKR2CORE_PATH}/base/win32 \r\n    ${KRKR2CORE_PATH}/environ \r\n    ${KRKR2CORE_PATH}/environ/win32 \r\n    ${KRKR2CORE_PATH}/environ/android \r\n    ${KRKR2CORE_PATH}/environ/sdl \r\n    ${KRKR2CORE_PATH}/msg \r\n    ${KRKR2CORE_PATH}/msg/win32 \r\n    ${KRKR2CORE_PATH}/extension\r\n    ${KRKR2CORE_PATH}/sound \r\n    ${KRKR2CORE_PATH}/sound/win32 \r\n    ${KRKR2CORE_PATH}/tjs2\r\n    ${KRKR2CORE_PATH}/utils \r\n    ${KRKR2CORE_PATH}/utils/win32\r\n    ${KRKR2CORE_PATH}/visual\r\n    ${KRKR2CORE_PATH}/visual/ARM\r\n    ${KRKR2CORE_PATH}/visual/win32\r\n    ${KRKR2CORE_PATH}/visual/RenderScript/rs\r\n    ${KRKR2CORE_PATH}/../plugins\r\n\r\n    ${COCOS2DX_PATH}\r\n    ${COCOS2DX_PATH}/cocos\r\n    ${COCOS2DX_PATH}/cocos/scripting\r\n    ${COCOS2DX_PATH}/cocos/editor-support\r\n    ${COCOS2DX_PATH}/extensions\r\n    ${COCOS2DX_PATH}/external\r\n    ${COCOS2DX_PATH}/external/png/include/${PLATFORM}\r\n    ${COCOS2DX_PATH}/external/webp/include/${PLATFORM}\r\n    ${COCOS2DX_PATH}/external/freetype2/include/${PLATFORM}\r\n    ${COCOS2DX_PATH}/external/freetype2/include/${PLATFORM}/freetype2\r\n\r\n    ${PORTBUILD_PATH}/include\r\n)\r\n\r\ntarget_compile_definitions(${PROJECT_NAME} PUBLIC\r\n    -DTJS_TEXT_OUT_CRLF -D__STDC_CONSTANT_MACROS -DUSE_UNICODE_FSTRING\r\n    -DTJS_TEXT_OUT_CRLF -D_7ZIP_ST \r\n)\r\ntarget_compile_options(${PROJECT_NAME} PUBLIC \r\n    -fPIC\r\n)\r\n\r\ntarget_link_directories(${PROJECT_NAME} PUBLIC\r\n    ${PORTBUILD_PATH}/lib\r\n)\r\ntarget_link_libraries(${PROJECT_NAME} PUBLIC\r\n    -Wl,-Bstatic\r\n    # audio\r\n    ogg_static\r\n    opus_static\r\n    vorbis_static \r\n    vorbisfile_static\r\n    vorbisenc_static\r\n    opusfile_static\r\n    oboe\r\n    openal_static\r\n\r\n    # image\r\n    jpeg_static\r\n    opencv_imgproc\r\n    opencv_core\r\n    tegra_hal\r\n    \r\n    # video\r\n    avutil_static\r\n    avfilter_static\r\n    avformat_static\r\n    avcodec_static\r\n    swscale_static\r\n    swresample_static\r\n\r\n    # archive\r\n    unrar\r\n    lz4\r\n    archive_static #  libbpg_static jxrlib_static\r\n    7za\r\n\r\n    # others\r\n    onig_static\r\n    breakpad\r\n    breakpad_client\r\n    \r\n    # framework\r\n    sdl2_static\r\n    cocos2d\r\n    ext_unzip\r\n    ext_tinyxml2\r\n    ext_xxhash\r\n    ext_edtaa3func\r\n    ext_poly2tri\r\n    ext_recast\r\n    ext_clipper\r\n    ext_convertUTF\r\n    ext_pvmp3dec\r\n    chipmunk\r\n    BulletCollision\r\n    BulletDynamics\r\n    BulletMultiThreaded\r\n    LinearMath\r\n    MiniCL\r\n\r\n    z\r\n    png\r\n    webp\r\n    tiff\r\n    freetype\r\n)"
  },
  {
    "path": "src/core/base/7zArchive.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"StorageIntf.h\"\n#include \"UtilStreams.h\"\n#include <algorithm>\nextern \"C\" {\n#include \"p7zip/C/7z.h\"\n#include \"p7zip/C/7zFile.h\"\n#include \"p7zip/C/7zCrc.h\"\n}\n#include \"StorageImpl.h\"\n\nstatic ISzAlloc allocImp = {\n\t[](void *p, size_t size) -> void *{ return malloc(size); },\n\t[](void *p, void *addr) { free(addr); }\n};\n\nclass SevenZipStreamWrap {\npublic:\n\tCSzArEx db;\n\ttTJSBinaryStream *_stream;\n\tCLookToRead lookStream;\n\tstruct CSeekInStream : public ISeekInStream {\n\t\tSevenZipStreamWrap *Host;\n\t} archiveStream;\n\npublic:\n\tSevenZipStreamWrap(tTJSBinaryStream * st) : _stream(st) {\n\t\tarchiveStream.Host = this;\n\t\tarchiveStream.Read = [](void *p, void *buf, size_t *size)->SRes {return ((CSeekInStream*)p)->Host->StreamRead(buf, size); };\n\t\tarchiveStream.Seek = [](void *p, Int64 *pos, ESzSeek origin)->SRes {return ((CSeekInStream*)p)->Host->StreamSeek(pos, origin); };\n\t\tLookToRead_CreateVTable(&lookStream, false);\n\t\tlookStream.realStream = &archiveStream;\n\t\tSzArEx_Init(&db);\n\t\tif (!g_CrcTable[1]) CrcGenerateTable();\n\t}\n\t~SevenZipStreamWrap() {\n\t\tSzArEx_Free(&db, &allocImp);\n\t\tdelete _stream;\n\t}\n\tSRes StreamRead(void *buf, size_t *size) {\n\t\t*size = _stream->Read(buf, *size);\n\t\treturn SZ_OK;\n\t}\n\tSRes StreamSeek(Int64 *pos, ESzSeek origin) {\n\t\ttjs_int whence = TJS_BS_SEEK_SET;\n\t\tswitch (origin) {\n\t\tcase SZ_SEEK_CUR: whence = TJS_BS_SEEK_CUR; break;\n\t\tcase SZ_SEEK_END: whence = TJS_BS_SEEK_END; break;\n\t\tcase SZ_SEEK_SET: whence = TJS_BS_SEEK_SET; break;\n\t\tdefault: break;\n\t\t}\n\n\t\t*pos = _stream->Seek(*pos, whence);\n\t\treturn SZ_OK;\n\t}\n};\n\nclass SevenZipArchive : public tTVPArchive, public SevenZipStreamWrap {\n\tstd::vector<std::pair<ttstr, tjs_uint> > filelist;\n\npublic:\n\tSevenZipArchive(const ttstr & name, tTJSBinaryStream *st) : tTVPArchive(name), SevenZipStreamWrap(st) {\n\t}\n\n\tvirtual ~SevenZipArchive() { }\n\n\tvirtual tjs_uint GetCount() { return filelist.size(); }\n\tvirtual ttstr GetName(tjs_uint idx) { return filelist[idx].first; }\n\tvirtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) {\n\t\ttjs_uint fileIndex = filelist[idx].second;\n\t\tUInt64 fileSize = SzArEx_GetFileSize(&db, fileIndex);\n\t\tif (fileSize <= 0) return new tTVPMemoryStream();\n\n\t\tUInt32 folderIndex = db.FileToFolder[fileIndex];\n\t\tif (folderIndex == (UInt32)-1) return nullptr;\n\n\t\tconst CSzAr *p = &db.db;\n\t\tCSzFolder folder;\n\t\tCSzData sd;\n\t\tconst Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];\n\t\tsd.Data = data;\n\t\tsd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];\n\n\t\tif (SzGetNextFolderItem(&folder, &sd) != SZ_OK) return nullptr;\n\t\tif (folder.NumCoders == 1) {\n\t\t\tUInt64 startPos = db.dataPos;\n\t\t\tconst UInt64 *packPositions = p->PackPositions + p->FoStartPackStreamIndex[folderIndex];\n\t\t\tUInt64 offset = packPositions[0];\n\t\t\tUInt64 inSize = packPositions[1] - offset;\n#define k_Copy 0\n\t\t\tif (folder.Coders[0].MethodID == k_Copy && inSize == fileSize) {\n\t\t\t\treturn new TArchiveStream(this, startPos + offset, inSize);\n\t\t\t}\n\t\t}\n\n\t\tUInt32 blockIndex;\n\t\tByte *outBuffer = nullptr;\n\t\tsize_t outBufferSize;\n\t\tsize_t offset, outSizeProcessed;\n\t\tSRes res = SzArEx_Extract(&db, &lookStream.s, fileIndex, &blockIndex, &outBuffer, &outBufferSize,\n\t\t\t&offset, &outSizeProcessed, &allocImp, &allocImp);\n\t\ttTVPMemoryStream *mem;\n\t\tif (offset == 0 && fileSize <= outBufferSize) {\n\t\t\tmem = new tTVPMemoryStream(outBuffer, outBufferSize);\n\t\t} else {\n\t\t\tByte *buf = new Byte[fileSize];\n\t\t\tmemcpy(buf, outBuffer, fileSize);\n\t\t\tmem = new tTVPMemoryStream(buf, fileSize);\n\t\t\tdelete outBuffer;\n\t\t}\n\t\treturn mem;\n\t}\n\n\tbool Open(bool normalizeFileName) {\n\t\tSRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocImp);\n\t\tif (res != SZ_OK) {\n\t\t\t_stream = nullptr;\n\t\t\treturn false;\n\t\t}\n\t\tfor (int i = 0; i < db.NumFiles; i++) {\n\t\t\tsize_t offset = 0;\n\t\t\tsize_t outSizeProcessed = 0;\n\t\t\tbool isDir = SzArEx_IsDir(&db, i);\n\t\t\tif (isDir) continue;\n\t\t\tsize_t len = SzArEx_GetFileNameUtf16(&db, i, NULL);\n\t\t\tttstr filename;\n\t\t\tSzArEx_GetFileNameUtf16(&db, i, (UInt16*)filename.AllocBuffer(len));\n\t\t\tfilename.FixLen();\n\t\t\tif (normalizeFileName)\n\t\t\t\tNormalizeInArchiveStorageName(filename);\n\t\t\tfilelist.emplace_back(filename, i);\n\t\t}\n\t\tif (normalizeFileName) {\n\t\t\tstd::sort(filelist.begin(), filelist.end(), [](const std::pair<ttstr, tjs_uint>& a, const std::pair<ttstr, tjs_uint>& b) {\n\t\t\t\treturn a.first < b.first;\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n};\n\ntTVPArchive * TVPOpen7ZArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) {\n\ttjs_uint64 pos = st->GetPosition();\n\tbool checkZIP = st->ReadI16LE() == 0x7A37; // '7z'\n\tst->SetPosition(pos);\n\tif (!checkZIP) return nullptr;\n\tSevenZipArchive *arc = new SevenZipArchive(name, st);\n\tif (!arc->Open(normalizeFileName)) {\n\t\tdelete arc;\n\t\treturn nullptr;\n\t}\n\treturn arc;\n}\n\n#if 0\nvoid TVPUnpack7ZArchive(tTJSBinaryStream *st, ttstr outpath) {\n\ttjs_uint64 origpos = st->GetPosition();\n\tSevenZipStreamWrap szsw(st);\n\tCSzArEx &db = szsw.db;\n\tSRes res = SzArEx_Open(&db, &szsw.lookStream.s, &allocImp, &allocImp);\n\tif (res != SZ_OK) return;\n\toutpath += TJS_W(\"/\");\n\tfor (int i = 0; i < db.db.NumFolders; ++i) {\n\t\t;\n\t}\n\tfor (int i = 0; i < db.NumFiles; i++) {\n\t\tsize_t offset = 0;\n\t\tsize_t outSizeProcessed = 0;\n\t\tsize_t len = SzArEx_GetFileNameUtf16(&db, i, NULL);\n\t\tttstr filename;\n\t\tSzArEx_GetFileNameUtf16(&db, i, (UInt16*)filename.AllocBuffer(len));\n\t\tfilename.FixLen();\n\t\tbool isDir = SzArEx_IsDir(&db, i);\n\t\tttstr fullpath = outpath + filename;\n\t\tif (isDir) {\n\t\t\tif (!TVPCheckExistentLocalFolder(fullpath))\n\t\t\t\tTVPCreateFolders(fullpath);\n\t\t} else {\n\t\t\ttjs_uint fileIndex = i;\n\t\t\tUInt64 fileSize = SzArEx_GetFileSize(&db, fileIndex);\n\t\t\tif (fileSize <= 0) {\n\t\t\t\tFILE *fp = fopen(fullpath.AsStdString().c_str(), \"wb\");\n\t\t\t\tfclose(fp);\n\t\t\t}\n\n\t\t\tUInt32 folderIndex = db.FileToFolder[fileIndex];\n\t\t\tif (folderIndex == (UInt32)-1) continue;\n\n\t\t\tconst CSzAr *p = &db.db;\n\t\t\tCSzFolder folder;\n\t\t\tCSzData sd;\n\t\t\tconst Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];\n\t\t\tsd.Data = data;\n\t\t\tsd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];\n\n\t\t\tif (SzGetNextFolderItem(&folder, &sd) != SZ_OK) continue;\n\t\t\tif (folder.NumCoders == 1) {\n\t\t\t\tUInt64 startPos = db.dataPos;\n\t\t\t\tconst UInt64 *packPositions = p->PackPositions + p->FoStartPackStreamIndex[folderIndex];\n\t\t\t\tUInt64 offset = packPositions[0];\n\t\t\t\tUInt64 inSize = packPositions[1] - offset;\n\t\t\t\tif (folder.Coders[0].MethodID == k_Copy && inSize == fileSize) {\n\t\t\t\t\tCopyStreamToFile(st, origpos + startPos + offset, inSize, fullpath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUInt32 blockIndex;\n\t\t\tByte *outBuffer = nullptr;\n\t\t\tsize_t outBufferSize;\n\t\t\tsize_t offset, outSizeProcessed;\n\t\t\tSRes res = SzArEx_Extract(&db, &szsw.lookStream.s, fileIndex, &blockIndex, &outBuffer, &outBufferSize,\n\t\t\t\t&offset, &outSizeProcessed, &allocImp, &allocImp);\n\t\t\ttTVPMemoryStream *mem;\n\t\t\tif (offset == 0 && fileSize <= outBufferSize) {\n\t\t\t\tmem = new tTVPMemoryStream(outBuffer, outBufferSize);\n\t\t\t} else {\n\t\t\t\tByte *buf = new Byte[fileSize];\n\t\t\t\tmemcpy(buf, outBuffer, fileSize);\n\t\t\t\tmem = new tTVPMemoryStream(buf, fileSize);\n\t\t\t\tdelete outBuffer;\n\t\t\t}\n\t\t\treturn mem;\n\t\t}\n\t}\n}\n#endif"
  },
  {
    "path": "src/core/base/BinaryStream.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text read/write stream\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <zlib.h>\n#include \"TextStream.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"EventIntf.h\"\n#include \"UtilStreams.h\"\n#include \"tjsError.h\"\n\n\n/*\n\tText stream is used by TJS's Array.saveStruct, Dictionary.saveStruct etc.\n\tto input/output binary files.\n*/\n\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TVPCreateBinaryStreamForRead(const ttstr & name,\n\tconst ttstr & modestr)\n{\n\t// check o mode\n\ttTJSBinaryStream* stream = TVPCreateStream(name, TJS_BS_READ);\n\n\tconst tjs_char* o_ofs = TJS_strchr(modestr.c_str(), TJS_W('o'));\n\tif(o_ofs != NULL) {\n\t\t// seek to offset\n\t\to_ofs++;\n\t\ttjs_char buf[256];\n\t\tint i;\n\t\tfor(i = 0; i < 255; i++) {\n\t\t\tif(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9'))\n\t\t\t\tbuf[i] = o_ofs[i];\n\t\t\telse break;\n\t\t}\n\t\tbuf[i] = 0;\n\t\ttjs_uint64 ofs = ttstr(buf).AsInteger();\n\t\tstream->SetPosition(ofs);\n\t}\n\treturn stream;\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TVPCreateBinaryStreamForWrite(const ttstr & name,\n\tconst ttstr & modestr)\n{\n\ttTJSBinaryStream* stream;\n\t// check o mode\n\tconst tjs_char * o_ofs;\n\to_ofs = TJS_strchr(modestr.c_str(), TJS_W('o'));\n\tif(o_ofs != NULL) {\n\t\t// seek to offset\n\t\to_ofs++;\n\t\ttjs_char buf[256];\n\t\tint i;\n\t\tfor(i = 0; i < 255; i++) {\n\t\t\tif(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9'))\n\t\t\t\tbuf[i] = o_ofs[i];\n\t\t\telse break;\n\t\t}\n\t\tbuf[i] = 0;\n\t\ttjs_uint64 ofs = ttstr(buf).AsInteger();\n\t\tstream = TVPCreateStream(name, TJS_BS_UPDATE);\n\t\tstream->SetPosition(ofs);\n\t} else {\n\t\tstream = TVPCreateStream(name, TJS_BS_WRITE);\n\t}\n\treturn stream;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n"
  },
  {
    "path": "src/core/base/BinaryStream.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text read/write stream\n//---------------------------------------------------------------------------\n#ifndef BinaryStreamH\n#define BinaryStreamH\n\n\n#include \"StorageIntf.h\"\n\n//---------------------------------------------------------------------------\n// BinaryStream Functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamForRead, (const ttstr &name, const ttstr &modestr));\nTJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamForWrite, (const ttstr &name, const ttstr &modestr));\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/CharacterSet.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Character code conversion\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"CharacterSet.h\"\n#include \"MsgIntf.h\"\n//---------------------------------------------------------------------------\nstatic tjs_int inline TVPWideCharToUtf8(tjs_char in, char * out)\n{\n\t// convert a wide character 'in' to utf-8 character 'out'\n\tif     (in < (1<< 7))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)in;\n\t\t}\n\t\treturn 1;\n\t}\n\telse if(in < (1<<11))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)(0xc0 | (in >> 6));\n\t\t\tout[1] = (char)(0x80 | (in & 0x3f));\n\t\t}\n\t\treturn 2;\n\t}\n\telse if(in < (1<<16))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)(0xe0 | (in >> 12));\n\t\t\tout[1] = (char)(0x80 | ((in >> 6) & 0x3f));\n\t\t\tout[2] = (char)(0x80 | (in & 0x3f));\n\t\t}\n\t\treturn 3;\n\t}\n#if 1\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TJS_W(\"Out of UTF-16 range conversion from UTF-8 code\"));\n\t}\n#else\n\t// ȉIWĩR[hǁAʂȂ͂B\n\telse if(in < (1<<21))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)(0xf0 | (in >> 18));\n\t\t\tout[1] = (char)(0x80 | ((in >> 12) & 0x3f));\n\t\t\tout[2] = (char)(0x80 | ((in >> 6 ) & 0x3f));\n\t\t\tout[3] = (char)(0x80 | (in & 0x3f));\n\t\t}\n\t\treturn 4;\n\t}\n\telse if(in < (1<<26))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)(0xf8 | (in >> 24));\n\t\t\tout[1] = (char)(0x80 | ((in >> 16) & 0x3f));\n\t\t\tout[2] = (char)(0x80 | ((in >> 12) & 0x3f));\n\t\t\tout[3] = (char)(0x80 | ((in >> 6 ) & 0x3f));\n\t\t\tout[4] = (char)(0x80 | (in & 0x3f));\n\t\t}\n\t\treturn 5;\n\t}\n\telse if(in < (1<<31))\n\t{\n\t\tif(out)\n\t\t{\n\t\t\tout[0] = (char)(0xfc | (in >> 30));\n\t\t\tout[1] = (char)(0x80 | ((in >> 24) & 0x3f));\n\t\t\tout[2] = (char)(0x80 | ((in >> 18) & 0x3f));\n\t\t\tout[3] = (char)(0x80 | ((in >> 12) & 0x3f));\n\t\t\tout[4] = (char)(0x80 | ((in >> 6 ) & 0x3f));\n\t\t\tout[5] = (char)(0x80 | (in & 0x3f));\n\t\t}\n\t\treturn 6;\n\t}\n#endif\n\treturn -1;\n}\n//---------------------------------------------------------------------------\ntjs_int TVPWideCharToUtf8String(const tjs_char *in, char * out)\n{\n\t// convert input wide string to output utf-8 string\n\tint count = 0;\n\twhile(*in)\n\t{\n\t\ttjs_int n;\n\t\tif(out)\n\t\t{\n\t\t\tn = TVPWideCharToUtf8(*in, out);\n\t\t\tout += n;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tn = TVPWideCharToUtf8(*in, NULL);\n\t\t\t\t/*\n\t\t\t\t\tin this situation, the compiler's inliner\n\t\t\t\t\twill collapse all null check parts in\n\t\t\t\t\tTVPWideCharToUtf8.\n\t\t\t\t*/\n\t\t}\n\t\tif(n == -1) return -1; // invalid character found\n\t\tcount += n;\n\t\tin++;\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\nstatic bool inline TVPUtf8ToWideChar(const char * & in, tjs_char *out)\n{\n\t// convert a utf-8 charater from 'in' to wide charater 'out'\n\tconst unsigned char * & p = (const unsigned char * &)in;\n\tif(p[0] < 0x80)\n\t{\n\t\tif(out) *out = (tjs_char)in[0];\n\t\tin++;\n\t\treturn true;\n\t}\n\telse if(p[0] < 0xc2)\n\t{\n\t\t// invalid character\n\t\treturn false;\n\t}\n\telse if(p[0] < 0xe0)\n\t{\n\t\t// two bytes (11bits)\n\t\tif((p[1] & 0xc0) != 0x80) return false;\n\t\tif(out) *out = ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);\n\t\tin += 2;\n\t\treturn true;\n\t}\n\telse if(p[0] < 0xf0)\n\t{\n\t\t// three bytes (16bits)\n\t\tif((p[1] & 0xc0) != 0x80) return false;\n\t\tif((p[2] & 0xc0) != 0x80) return false;\n\t\tif(out) *out = ((p[0] & 0x1f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f);\n\t\tin += 3;\n\t\treturn true;\n\t}\n\telse if(p[0] < 0xf8)\n\t{\n\t\t// four bytes (21bits)\n\t\tif((p[1] & 0xc0) != 0x80) return false;\n\t\tif((p[2] & 0xc0) != 0x80) return false;\n\t\tif((p[3] & 0xc0) != 0x80) return false;\n\t\tif(out) *out = ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) +\n\t\t\t((p[2] & 0x3f) << 6) + (p[3] & 0x3f);\n\t\tin += 4;\n\t\treturn true;\n\t}\n\telse if(p[0] < 0xfc)\n\t{\n\t\t// five bytes (26bits)\n\t\tif((p[1] & 0xc0) != 0x80) return false;\n\t\tif((p[2] & 0xc0) != 0x80) return false;\n\t\tif((p[3] & 0xc0) != 0x80) return false;\n\t\tif((p[4] & 0xc0) != 0x80) return false;\n\t\tif(out) *out = ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18) +\n\t\t\t((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6) + (p[4] & 0x3f);\n\t\tin += 5;\n\t\treturn true;\n\t}\n\telse if(p[0] < 0xfe)\n\t{\n\t\t// six bytes (31bits)\n\t\tif((p[1] & 0xc0) != 0x80) return false;\n\t\tif((p[2] & 0xc0) != 0x80) return false;\n\t\tif((p[3] & 0xc0) != 0x80) return false;\n\t\tif((p[4] & 0xc0) != 0x80) return false;\n\t\tif((p[5] & 0xc0) != 0x80) return false;\n\t\tif(out) *out = ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24) +\n\t\t\t((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12) +\n\t\t\t((p[4] & 0x3f) << 6) + (p[5] & 0x3f);\n\t\tin += 6;\n\t\treturn true;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\ntjs_int TVPUtf8ToWideCharString(const char * in, tjs_char *out)\n{\n\t// convert input utf-8 string to output wide string\n\tint count = 0;\n\twhile(*in)\n\t{\n\t\ttjs_char c;\n\t\tif(out)\n\t\t{\n\t\t\tif(!TVPUtf8ToWideChar(in, &c))\n\t\t\t\treturn -1; // invalid character found\n\t\t\t*out++ = c;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPUtf8ToWideChar(in, NULL))\n\t\t\t\treturn -1; // invalid character found\n\t\t}\n\t\tcount ++;\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\ntjs_int TVPUtf8ToWideCharString(const char * in, tjs_uint length, tjs_char *out)\n{\n\t// convert input utf-8 string to output wide string\n\tint count = 0;\n\tconst char *end = in + length;\n\twhile(*in && in < end)\n\t{\n\t\tif(in + 6 > end)\n\t\t{\n\t\t\t// fetch utf-8 character length\n\t\t\tconst unsigned char ch = *(const unsigned char *)in;\n\n\t\t\tif(ch >= 0x80)\n\t\t\t{\n\t\t\t\ttjs_uint len = 0;\n\n\t\t\t\tif(ch < 0xc2) return -1;\n\t\t\t\telse if(ch < 0xe0) len = 2;\n\t\t\t\telse if(ch < 0xf0) len = 3;\n\t\t\t\telse if(ch < 0xf8) len = 4;\n\t\t\t\telse if(ch < 0xfc) len = 5;\n\t\t\t\telse if(ch < 0xfe) len = 6;\n\t\t\t\telse return -1;\n\n\t\t\t\tif(in + len > end) return -1;\n\t\t\t}\n\t\t}\n\n\t\ttjs_char c;\n\t\tif(out)\n\t\t{\n\t\t\tif(!TVPUtf8ToWideChar(in, &c))\n\t\t\t\treturn -1; // invalid character found\n\t\t\t*out++ = c;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPUtf8ToWideChar(in, NULL))\n\t\t\t\treturn -1; // invalid character found\n\t\t}\n\t\tcount ++;\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/base/CharacterSet.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Character code conversion\n//---------------------------------------------------------------------------\n\n#ifndef __CharacterSet_H__\n#define __CharacterSet_H__\n\n// various character conding conversion.\n// currently only utf-8 related functions are implemented.\n#include \"tjsTypes.h\"\n\n\nTJS_EXP_FUNC_DEF(tjs_int, TVPWideCharToUtf8String, (const tjs_char *in, char * out));\nTJS_EXP_FUNC_DEF(tjs_int, TVPUtf8ToWideCharString, (const char * in, tjs_char *out));\n\nextern tjs_int TVPUtf8ToWideCharString(const char * in, tjs_uint length, tjs_char *out);\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/EventIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script/Window Event Handling and Dispatching / System Idle Event Delivering\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"SysInitIntf.h\"\n#include \"EventIntf.h\"\n#include \"WindowIntf.h\"\n#include \"tjsDictionary.h\"\n#include \"MsgIntf.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"TickCount.h\"\n#include \"SystemImpl.h\"\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPEvent  : script event class\n//---------------------------------------------------------------------------\nextern tjs_uint64 TVPEventSequenceNumber;\nclass tTVPEvent\n{\n\tiTJSDispatch2 *Target;\n\tiTJSDispatch2 *Source;\n\tttstr EventName;\n\ttjs_uint32 Tag;\n\ttjs_uint NumArgs;\n\ttTJSVariant *Args;\n\ttjs_uint32 Flags;\n\ttjs_uint64 Sequence;\n\npublic:\n\ttTVPEvent(iTJSDispatch2 *target, iTJSDispatch2 *source,\n\t\tttstr &eventname, tjs_uint32 tag, tjs_uint numargs, tTJSVariant *args,\n\t\ttjs_uint32 flags)\n\t{\n\t\t// constructor\n\n\t\t// eventname is not a const object but this object only touch to\n\t\t// eventname.GetHint()\n\n\t\tArgs = NULL;\n\t\tTarget = NULL;\n\t\tSource = NULL;\n\n\t\tSequence = TVPEventSequenceNumber;\n\t\tEventName = eventname;\n\t\tNumArgs = numargs;\n\t\tArgs = new tTJSVariant[NumArgs];\n\t\tfor(tjs_uint i=0; i<NumArgs; i++)\n\t\t\tArgs[i]=args[i];\n\t\tTarget = target;\n\t\tSource = source;\n\t\tTag = tag;\n\t\tFlags = flags;\n\t\tif(Target) Target->AddRef();\n\t\tif(Source) Source->AddRef();\n\t}\n\n\n\ttTVPEvent(const tTVPEvent &ref)\n\t{\n\t\t// copy constructor\n\t\tArgs = NULL;\n\t\tTarget = NULL;\n\t\tSource = NULL;\n\n\t\tEventName = ref.EventName;\n\t\tNumArgs = ref.NumArgs;\n\t\tArgs = new tTJSVariant[NumArgs];\n\t\tfor(tjs_uint i=0; i<NumArgs; i++)\n\t\t\tArgs[i]=ref.Args[i];\n\t\tTarget = ref.Target;\n\t\tSource = ref.Source;\n\t\tTag = ref.Tag;\n\t\tif(Target) Target->AddRef();\n\t\tif(Source) Source->AddRef();\n\t}\n\n\t~tTVPEvent()\n\t{\n\t\tif(Args) delete [] Args;\n\t\tif(Target) Target->Release();\n\t\tif(Source) Source->Release();\n\t}\n\n\tvoid Deliver()\n\t{\n\t\tif(!TJSIsObjectValid(Target->IsValid(0, NULL, NULL, Target)))\n\t\t\treturn; // The target had been invalidated\n\t\ttTJSVariant **ArgsPtr = new tTJSVariant*[NumArgs];\n\t\tfor(tjs_uint i=0; i<NumArgs; i++)\n\t\t\tArgsPtr[i] = Args + i;\n\t\ttry\n\t\t{\n\t\t\tTarget->FuncCall(0, EventName.c_str(), EventName.GetHint(),\n\t\t\t\tNULL, NumArgs, ArgsPtr,\n\t\t\t\tTarget);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete [] ArgsPtr;\n\t\t\tthrow;\n\t\t}\n\t\tdelete [] ArgsPtr;\n\t}\n\n\n\tiTJSDispatch2 * GetTargetNoAddRef() const { return Target; }\n\tiTJSDispatch2 * GetSourceNoAddRef() const { return Source; }\n\tttstr & GetEventName() { return EventName; }\n\ttjs_uint32 GetTag() const { return Tag; }\n\ttjs_uint32 GetFlags() const { return Flags; }\n\ttjs_uint64 GetSequence() const;\n};\n//---------------------------------------------------------------------------\ntjs_uint64 tTVPEvent::GetSequence() const { return Sequence; }\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWinUpdateEvent : window update event class\n//---------------------------------------------------------------------------\nclass tTVPWinUpdateEvent\n{\n\ttTJSNI_BaseWindow *Window;\n\npublic:\n\ttTVPWinUpdateEvent(tTJSNI_BaseWindow *window)\n\t{\n\t\tWindow = window;\n\t}\n\n\ttTVPWinUpdateEvent(const tTVPWinUpdateEvent & ref)\n\t{\n\t\tWindow = ref.Window;\n\t}\n\n\t~tTVPWinUpdateEvent()\n\t{\n\t}\n\n\tvoid Deliver() const\n\t{\n\t\tif (static_cast<tTJSNI_Window*>(Window)->GetVisible())\n\t\t\tWindow->UpdateContent();\n\t}\n\n    tTJSNI_BaseWindow * GetWindow() const { return Window; }\n\n\tvoid MarkEmpty() { Window = NULL; }\n\n\tbool IsEmpty() const { return Window == NULL; }\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// global/static definitions\n//---------------------------------------------------------------------------\n// event queue must be a globally sequential queue\nstd::vector<tTVPBaseInputEvent *> TVPInputEventQueue;\nstd::vector<tTVPEvent *> TVPEventQueue;\nstd::vector<tTVPWinUpdateEvent> TVPWinUpdateEventQueue;\nbool TVPExclusiveEventPosted = false; // true if exclusive event is posted\ntjs_uint64 TVPEventSequenceNumber = 0; // event sequence number\ntjs_uint64 TVPEventSequenceNumberToProcess = 0;\n\t// current event sequence which must be processed\n\nstatic void TVPDestroyEventQueue()\n{\n\t// delete all event objects\n\t// deletion of event object may cause other deletion of event objects.\n\t{\n\t\tstd::vector<tTVPEvent *>::iterator i;\n\t\twhile(TVPEventQueue.size())\n\t\t{\n\t\t\ti = TVPEventQueue.end() -1;\n\t\t\ttTVPEvent * ev = *i;\n\t\t\tTVPEventQueue.erase(i);\n\t\t\tdelete ev;\n\t\t}\n\t}\n//--\n\t{\n\t\tstd::vector<tTVPBaseInputEvent *>::iterator i;\n\t\twhile(TVPInputEventQueue.size())\n\t\t{\n\t\t\ti = TVPInputEventQueue.end() - 1;\n\t\t\ttTVPBaseInputEvent * ev = *i;\n\t\t\tTVPInputEventQueue.erase(i);\n\t\t\tdelete ev;\n\t\t}\n\t}\n}\n\nstatic tTVPAtExit TVPDestroyEventQueueAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPDestroyEventQueue);\n\nbool TVPEventDisabled = false;\nbool TVPEventInterrupting = false;\n\n//#define TVP_EVENT_TASK_RETURN_TICK 100000\n\t/* TVP event system once returns to Operation system when\n\t\tTVP_EVENT_TASK_RETURN_TICK is elapsed during event delivering. */\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPPostEvent\n//---------------------------------------------------------------------------\nvoid TVPPostEvent(iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tttstr &eventname, tjs_uint32 tag, tjs_uint32 flag,\n\ttjs_uint numargs, tTJSVariant *args)\n{\n\tbool evdisabled = TVPEventDisabled || TVPGetSystemEventDisabledState();\n\n\tif((flag & TVP_EPT_DISCARDABLE) &&\n\t\t(TVPEventInterrupting || evdisabled)) return;\n\n\ttjs_int method = flag & TVP_EPT_METHOD_MASK;\n\n\tif(method == TVP_EPT_IMMEDIATE)\n\t{\n\t\t// the event is delivered immediately\n\n\t\tif(evdisabled) return;\n\n\t\ttry\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttTVPEvent(target, source, eventname, tag, numargs, args, flag).\n\t\t\t\t\tDeliver();\n\t\t\t}\n\t\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t\t}\n\t\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"immediate event\"));\n\n\t\treturn;\n\t}\n\n\n\tif(method == TVP_EPT_REMOVE_POST)\n\t{\n\t\t// events in queue that have same target/source/name/tag are to be removed\n\t\tstd::vector<tTVPEvent *>::iterator i;\n\t\ti = TVPEventQueue.begin();\n\t\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t\t{\n\t\t\tif(source == (*i)->GetSourceNoAddRef() &&\n\t\t\t\ttarget == (*i)->GetTargetNoAddRef() &&\n\t\t\t\teventname == (*i)->GetEventName() &&\n\t\t\t\t((tag==0)?true:(tag==(*i)->GetTag())) )\n\t\t\t{\n\t\t\t\ttTVPEvent *ev = *i;\n\t\t\t\tTVPEventQueue.erase(i);\n\t\t\t\ti = TVPEventQueue.begin();\n\t\t\t\tdelete ev;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// put into queue\n\tTVPEventQueue.push_back(new tTVPEvent(target, source, eventname, tag,\n\t\t\t\t\t\t\t\t\tnumargs, args, flag));\n\n\t// is exclusive?\n\tif((flag & TVP_EPT_PRIO_MASK) == TVP_EPT_EXCLUSIVE) TVPExclusiveEventPosted = true;\n\n\t// make sure that the event is to be delivered.\n\tTVPInvokeEvents();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCancelEvents\n//---------------------------------------------------------------------------\ntjs_int TVPCancelEvents(iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag)\n{\n\ttjs_int count = 0;\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif(source == (*i)->GetSourceNoAddRef() &&\n\t\t\ttarget == (*i)->GetTargetNoAddRef() &&\n\t\t\teventname == (*i)->GetEventName() &&\n\t\t\t\t((tag==0)?true:(tag==(*i)->GetTag())) )\n\t\t{\n\t\t\ttTVPEvent *ev = *i;\n\t\t\tTVPEventQueue.erase(i);\n\t\t\ti = TVPEventQueue.begin();\n\t\t\tdelete ev;\n\t\t\tcount ++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ti++;\n\t\t}\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPAreEventsInQueue\n//---------------------------------------------------------------------------\nbool TVPAreEventsInQueue(iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag)\n{\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif(source == (*i)->GetSourceNoAddRef() &&\n\t\t\ttarget == (*i)->GetTargetNoAddRef() &&\n\t\t\teventname == (*i)->GetEventName() &&\n\t\t\t\t((tag==0)?true:(tag==(*i)->GetTag())) )\n\t\treturn true;\n\t\ti++;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCountEventsInQueue\n//---------------------------------------------------------------------------\ntjs_int TVPCountEventsInQueue(iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag)\n{\n\ttjs_int count = 0;\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif(source == (*i)->GetSourceNoAddRef() &&\n\t\t\ttarget == (*i)->GetTargetNoAddRef() &&\n\t\t\teventname == (*i)->GetEventName() &&\n\t\t\t\t((tag==0)?true:(tag==(*i)->GetTag())) )\n\t\tcount ++;\n\t\ti++;\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCancelEventByTag\n//---------------------------------------------------------------------------\nvoid TVPCancelEventsByTag(iTJSDispatch2 * source, iTJSDispatch2 *target,\n\ttjs_uint32 tag)\n{\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif(source == (*i)->GetSourceNoAddRef() &&\n\t\t\ttarget == (*i)->GetTargetNoAddRef() &&\n\t\t\t\t((tag==0)?true:(tag==(*i)->GetTag())) )\n\t\t{\n\t\t\ttTVPEvent *ev = *i;\n\t\t\tTVPEventQueue.erase(i);\n\t\t\ti = TVPEventQueue.begin();\n\t\t\tdelete ev;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ti++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCancelSourceEvent\n//---------------------------------------------------------------------------\nvoid TVPCancelSourceEvents(iTJSDispatch2 * source)\n{\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif(source == (*i)->GetSourceNoAddRef())\n\t\t{\n\t\t\ttTVPEvent *ev = *i;\n\t\t\tTVPEventQueue.erase(i);\n\t\t\ti = TVPEventQueue.begin();\n\t\t\tdelete ev;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ti++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDiscardAllDiscardableEvents\n//---------------------------------------------------------------------------\nvoid TVPDiscardAllDiscardableEvents()\n{\n\tstd::vector<tTVPEvent *>::iterator i;\n\ti = TVPEventQueue.begin();\n\twhile(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end())\n\t{\n\t\tif((*i)->GetFlags() & TVP_EPT_DISCARDABLE)\n\t\t{\n\t\t\ttTVPEvent *ev = *i;\n\t\t\tTVPEventQueue.erase(i);\n\t\t\ti = TVPEventQueue.begin();\n\t\t\tdelete ev;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ti++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDeliverAllEvents\n//---------------------------------------------------------------------------\nstatic void _TVPDeliverEventByPrio(tjs_uint prio)\n{\n\twhile(true)\n\t{\n\t\ttTVPEvent *e;\n\n\t\t// retrieve item to deliver\n\t\tif(TVPEventQueue.size() == 0) break;\n\t\tstd::vector<tTVPEvent *>::iterator i =\n\t\t\tTVPEventQueue.begin();\n\t\twhile(i != TVPEventQueue.end())\n\t\t{\n\t\t\tif((*i)->GetSequence() <= TVPEventSequenceNumberToProcess &&\n\t\t\t\t(((*i)->GetFlags() & TVP_EPT_PRIO_MASK) == prio)) break;\n\t\t\ti++;\n\t\t}\n\t\tif(i == TVPEventQueue.end()) break;\n\t\te = *i;\n\t\tTVPEventQueue.erase(i);\n\n\t\t// event delivering\n\t\ttry\n\t\t{\n\t\t\te->Deliver();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete e;\n\t\t\tthrow;\n\t\t}\n\t\tdelete e;\n\t}\n}\n\n\nstatic bool _TVPDeliverAllEvents2()\n{\n\tTVPExclusiveEventPosted = false;\n\n\t// process exclusive events\n\t_TVPDeliverEventByPrio(TVP_EPT_EXCLUSIVE);\n\n\t// check exclusive events\n\tif(TVPExclusiveEventPosted) return true;\n\n\t// process input event queue\n\twhile(true)\n\t{\n\t\ttTVPBaseInputEvent *e;\n\n\t\t// retrieve item to deliver\n\t\tif(TVPInputEventQueue.size() == 0) break;\n\t\tstd::vector<tTVPBaseInputEvent *>::iterator i =\n\t\t\tTVPInputEventQueue.begin();\n\t\te = *i;\n\t\tTVPInputEventQueue.erase(i);\n\n\t\t// event delivering\n\t\ttry\n\t\t{\n\t\t\te->Deliver();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete e;\n\t\t\tthrow;\n\t\t}\n\t\tdelete e;\n\n\t\t// check exclusive events\n\t\tif(TVPExclusiveEventPosted) return true;\n\n\t}\n\n\t// process normal event queue\n\t_TVPDeliverEventByPrio(TVP_EPT_NORMAL);\n\n\t// check exclusive events\n\tif(TVPExclusiveEventPosted) return true;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nstatic bool _TVPDeliverAllEvents()\n{\n\t// deliver all pending events to targets.\n\tif(TVPEventDisabled) return true;\n\n\t// event invokation was received...\n\tTVPEventReceived();\n\n\t// for script event objects\n\n\tbool ret_value;\n\n\tret_value = _TVPDeliverAllEvents2();\n\n\treturn ret_value;\n}\n//---------------------------------------------------------------------------\nvoid TVPDeliverAllEvents()\n{\n\tbool r;\n\n\tif(!TVPEventInterrupting)\n\t{\n\t\tTVPEventSequenceNumberToProcess = TVPEventSequenceNumber;\n\t\tTVPEventSequenceNumber ++; // increment sequence number\n\t}\n\n\tTVPEventInterrupting = false;\n\ttry\n\t{\n\t   try\n\t\t{\n\t\t\tr = _TVPDeliverAllEvents();\n\t\t}\n\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t}\n\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"event\"));\n\n\tif(!r)\n\t{\n\t\t// event processing is to be interrupted\n\t\t// XXX: currently this is not functional\n\t\tTVPEventInterrupting = true;\n\t\tTVPCallDeliverAllEventsOnIdle();\n\t}\n\n\tif(!TVPExclusiveEventPosted && !TVPEventInterrupting)\n\t{\n\t\ttry\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// process idle event queue\n\t\t\t\t_TVPDeliverEventByPrio(TVP_EPT_IDLE);\n\t\t\t}\n\t\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t\t}\n\t\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"idle event\"));\n\n\t\t// process continuous events\n\t\tif(TVPProcessContinuousHandlerEventFlag)\n\t\t{\n\t\t\tTVPProcessContinuousHandlerEventFlag = false; // processed\n\t\t\t// XXX: strictly saying, we need something like InterlockedExchange\n\t\t\t// to look/set this flag, because TVPProcessContinuousHandlerEventFlag\n\t\t\t// may be accessed by another thread. But I have no dought about\n\t\t\t// that no one does care of missing one event in rare race condition.\n\n\t\t\tTVPDeliverContinuousEvent();\n\t\t}\n\t\ttry\n\t\t{\n\t\t   try\n\t\t\t{\n\t\t\t\t// for window content updating\n\t\t\t\tTVPDeliverWindowUpdateEvents();\n\t\t\t}\n\t\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t\t}\n\t\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"window update\"));\n\t} else {\n\t}\n\n\tif(TVPEventQueue.size() == 0)\n\t{\n\t\tTVPEventSequenceNumber = 0; // reset the number\n\t}\n\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPPostWindowUpdate\n//---------------------------------------------------------------------------\nbool TVPWindowUpdateEventsDelivering = false;\nvoid TVPPostWindowUpdate(tTJSNI_BaseWindow *window)\n{\n\n\tif(!TVPWindowUpdateEventsDelivering)\n\t{\n\t\tif(TVPWinUpdateEventQueue.size())\n\t\t{\n\t\t\t// since duplication is not allowed ...\n\t\t\tstd::vector<tTVPWinUpdateEvent>::const_iterator i;\n\t\t\tfor(i = TVPWinUpdateEventQueue.begin();\n\t\t\t\ti !=TVPWinUpdateEventQueue.end(); i++)\n\t\t\t{\n\t\t\t\tif(!i->IsEmpty() && window == i->GetWindow()) return;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(TVPWinUpdateEventQueue.size())\n\t\t{\n\t\t\t// duplication is allowed up to two\n\t\t\ttjs_int count = 0;\n\t\t\tstd::vector<tTVPWinUpdateEvent>::const_iterator i;\n\t\t\tfor(i = TVPWinUpdateEventQueue.begin();\n\t\t\t\ti !=TVPWinUpdateEventQueue.end(); i++)\n\t\t\t{\n\t\t\t\tif(!i->IsEmpty() && window == i->GetWindow())\n\t\t\t\t{\n\t\t\t\t\tcount++;\n\t\t\t\t\tif(count == 2) return;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// put into queue.\n\tTVPWinUpdateEventQueue.emplace_back(window);\n\n\t// make sure that the event is to be delivered.\n\tTVPInvokeEvents();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPRemoveWindowUpdate\n//---------------------------------------------------------------------------\nvoid TVPRemoveWindowUpdate(tTJSNI_BaseWindow *window)\n{\n\t// removes all window update events from queue.\n\tif(TVPWinUpdateEventQueue.size())\n\t{\n\t\tstd::vector<tTVPWinUpdateEvent>::iterator i;\n\t\tfor(i = TVPWinUpdateEventQueue.begin();\n\t\t\ti !=TVPWinUpdateEventQueue.end(); i++)\n\t\t{\n\t\t\tif(!i->IsEmpty() && window == i->GetWindow())\n\t\t\t\ti->MarkEmpty();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDeliverWindowUpdateEvents\n//---------------------------------------------------------------------------\nvoid TVPDeliverWindowUpdateEvents()\n{\n\tif(TVPWindowUpdateEventsDelivering) return; // does not allow re-entering\n\tTVPWindowUpdateEventsDelivering = true;\n\n\ttry\n\t{\n\t\tfor(tjs_uint i = 0; i < TVPWinUpdateEventQueue.size(); i++)\n\t\t{\n\t\t\tif(!TVPWinUpdateEventQueue[i].IsEmpty())\n\t\t\t\tTVPWinUpdateEventQueue[i].Deliver();\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tTVPWinUpdateEventQueue.clear();\n\t\tTVPWindowUpdateEventsDelivering = false;\n\t\tthrow;\n\t}\n\tTVPWinUpdateEventQueue.clear();\n\tTVPWindowUpdateEventsDelivering = false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Input Event related\n//---------------------------------------------------------------------------\ntjs_int TVPInputEventTagMax = 0;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPPostInputEvent\n//---------------------------------------------------------------------------\nvoid TVPPostInputEvent(tTVPBaseInputEvent *ev, tjs_uint32 flags)\n{\n\t// flag check\n\tif((flags & TVP_EPT_DISCARDABLE) &&\n\t\t(TVPEventDisabled || TVPGetSystemEventDisabledState()))\n\t{\n\t\tdelete ev;\n\t\treturn;\n\t}\n\n\tif(flags & TVP_EPT_REMOVE_POST)\n\t{\n\t\t// cancel previously posted events\n\t\tTVPCancelInputEvents(ev->GetSource(), ev->GetTag());\n\t}\n\n\n\t// push into the event queue\n\tTVPInputEventQueue.push_back(ev);\n\n\t// make sure that the event is to be delivered.\n\tTVPInvokeEvents();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCancelInputEvents\n//---------------------------------------------------------------------------\nvoid TVPCancelInputEvents(void * source)\n{\n\t// removes all evens which have the same source\n\tif(TVPInputEventQueue.size())\n\t{\n\t\tstd::vector<tTVPBaseInputEvent *>::iterator i;\n\t\tfor(i = TVPInputEventQueue.begin();\n\t\t\ti !=TVPInputEventQueue.end();)\n\t\t{\n\t\t\tif(source == (*i)->GetSource())\n\t\t\t{\n\t\t\t\ttTVPBaseInputEvent *ev = *i;\n\t\t\t\ti = TVPInputEventQueue.erase(i);\n\t\t\t\tdelete ev;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPCancelInputEvents(void * source, tjs_int tag)\n{\n\t// removes all evens which have the same source and the same tag\n\tif(TVPInputEventQueue.size())\n\t{\n\t\tstd::vector<tTVPBaseInputEvent *>::iterator i;\n\t\tfor(i = TVPInputEventQueue.begin();\n\t\t\ti !=TVPInputEventQueue.end();)\n\t\t{\n\t\t\tif(source == (*i)->GetSource() && tag == (*i)->GetTag())\n\t\t\t{\n\t\t\t\ttTVPBaseInputEvent *ev = *i;\n\t\t\t\ti = TVPInputEventQueue.erase(i);\n\t\t\t\tdelete ev;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetInputEventCount\n//---------------------------------------------------------------------------\ntjs_int TVPGetInputEventCount()\n{\n\treturn (tjs_int)TVPInputEventQueue.size();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateEventObject\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateEventObject(const tjs_char *type,\n\tiTJSDispatch2 *targthis, iTJSDispatch2 *targ)\n{\n\t// create a dictionary object for event dispatching ( to \"action\" method )\n\tiTJSDispatch2 * object = TJSCreateDictionaryObject();\n\n\tstatic ttstr type_name(TJS_W(\"type\"));\n\tstatic ttstr target_name(TJS_W(\"target\"));\n\n\t{\n\t\ttTJSVariant val(type);\n\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP,\n\t\t\ttype_name.c_str(), type_name.GetHint(), &val, object)))\n\t\t\t\tTVPThrowInternalError;\n\t}\n\n\t{\n\t\ttTJSVariant val(targthis, targ);\n\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP,\n\t\t\ttarget_name.c_str(), target_name.GetHint(), &val, object)))\n\t\t\t\tTVPThrowInternalError;\n\t}\n\t\n\treturn object;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nttstr TVPActionName(TJS_W(\"action\"));\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Continuous Event Delivering related\n//---------------------------------------------------------------------------\nbool TVPProcessContinuousHandlerEventFlag = false;\nstatic std::vector<tTVPContinuousEventCallbackIntf *> TVPContinuousEventVector;\nstatic std::vector<tTJSVariantClosure> TVPContinuousHandlerVector;\nstatic bool TVPContinuousEventProcessing = false;\n\nstatic void TVPDestroyContinuousHandlerVector()\n{\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\tfor(i = TVPContinuousHandlerVector.begin();\n\t\ti != TVPContinuousHandlerVector.end();\n\t\ti++)\n\t{\n\t\ti->Release();\n\t}\n\tTVPContinuousHandlerVector.clear();\n}\n\nstatic tTVPAtExit TVPDestroyContinuousHandlerVectorAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPDestroyContinuousHandlerVector);\n//---------------------------------------------------------------------------\nvoid TVPAddContinuousEventHook(tTVPContinuousEventCallbackIntf *cb)\n{\n\tTVPBeginContinuousEvent();\n\tTVPContinuousEventVector.push_back(cb);\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveContinuousEventHook(tTVPContinuousEventCallbackIntf *cb)\n{\n\tstd::vector<tTVPContinuousEventCallbackIntf *>::iterator i;\n\tfor(i = TVPContinuousEventVector.begin();\n\t\ti !=TVPContinuousEventVector.end();)\n\t{\n\t\tif(cb == *i) *i = NULL; // simply assign a null\n\t\ti++;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void _TVPDeliverContinuousEvent() // internal\n{\n\tTVPStartTickCount();\n\ttjs_uint64 tick = TVPGetTickCount();\n\n\tif(TVPContinuousEventVector.size())\n\t{\n\t\tbool emptyflag = false;\n\t\tfor(tjs_uint32 i = 0; i < TVPContinuousEventVector.size(); i++)\n\t\t{\n\t\t\t// note that the handler can remove itself while the event\n\t\t\tif(TVPContinuousEventVector[i])\n\t\t\t\tTVPContinuousEventVector[i]->OnContinuousCallback(tick);\n\t\t\telse\n\t\t\t\temptyflag = true;\n\n\t\t\tif(TVPExclusiveEventPosted) return;  // check exclusive events\n\t\t}\n\n\t\tif(emptyflag)\n\t\t{\n\t\t\t// the array has empty cell\n\n\t\t\t// eliminate empty\n            std::vector<tTVPContinuousEventCallbackIntf *>::iterator i;\n\t\t\tfor(i = TVPContinuousEventVector.begin();\n\t\t\t\ti !=TVPContinuousEventVector.end();)\n\t\t\t{\n\t\t\t\tif(*i == NULL)\n\t\t\t\t\ti = TVPContinuousEventVector.erase(i);\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\n\tif(!TVPEventDisabled && TVPContinuousHandlerVector.size())\n\t{\n\t\tbool emptyflag = false;\n\t\ttTJSVariant vtick((tjs_int64)tick);\n\t\ttTJSVariant *pvtick = &vtick;\n\t\tfor(tjs_uint i = 0; i < TVPContinuousHandlerVector.size(); i++)\n\t\t{\n\t\t\tif(TVPContinuousHandlerVector[i].Object)\n\t\t\t{\n\t\t\t\ttjs_error er;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\ter =\n\t\t\t\t\t\tTVPContinuousHandlerVector[i].FuncCall(0, NULL, NULL, NULL, 1, &pvtick, NULL);\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\t// failed\n\t\t\t\t\tTVPContinuousHandlerVector[i].Release();\n\t\t\t\t\tTVPContinuousHandlerVector[i].Object =\n\t\t\t\t\tTVPContinuousHandlerVector[i].ObjThis = NULL;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tif(TJS_FAILED(er))\n\t\t\t\t{\n\t\t\t\t\t// failed\n\t\t\t\t\tTVPContinuousHandlerVector[i].Release();\n\t\t\t\t\tTVPContinuousHandlerVector[i].Object =\n\t\t\t\t\tTVPContinuousHandlerVector[i].ObjThis = NULL;\n\t\t\t\t\temptyflag = true;\n\t\t\t\t}\n\t\t\t\tif(TVPExclusiveEventPosted) return;  // check exclusive events\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\temptyflag = true;\n\t\t\t}\n\n\t\t}\n\n\t\tif(emptyflag)\n\t\t{\n\t\t\t// the array has empty cell\n\n\t\t\t// eliminate empty\n            std::vector<tTJSVariantClosure>::iterator i;\n\t\t\tfor(i = TVPContinuousHandlerVector.begin();\n\t\t\t\ti !=TVPContinuousHandlerVector.end();)\n\t\t\t{\n\t\t\t\tif(!i->Object)\n\t\t\t\t{\n\t\t\t\t\ti->Release();\n\t\t\t\t\ti = TVPContinuousHandlerVector.erase(i);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif(!TVPContinuousEventVector.size() && !TVPContinuousHandlerVector.size())\n\t\tTVPEndContinuousEvent();\n}\n//---------------------------------------------------------------------------\nvoid TVPDeliverContinuousEvent()\n{\n\tif(TVPContinuousEventProcessing) return;\n\tTVPContinuousEventProcessing = true;\n\ttry\n\t{\n\t\ttry\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t_TVPDeliverContinuousEvent();\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tTVPContinuousEventProcessing = false;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t}\n\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"continuous event\"));\n\n\tTVPContinuousEventProcessing = false;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TVPAddContinuousHandler(tTJSVariantClosure clo)\n{\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\ti = std::find(TVPContinuousHandlerVector.begin(),\n\t\tTVPContinuousHandlerVector.end(), clo);\n\tif(i == TVPContinuousHandlerVector.end())\n\t{\n\t\tTVPBeginContinuousEvent();\n\t\tclo.AddRef();\n\t\tTVPContinuousHandlerVector.emplace_back(clo);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveContinuousHandler(tTJSVariantClosure clo)\n{\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\ti = std::find(TVPContinuousHandlerVector.begin(),\n\t\tTVPContinuousHandlerVector.end(), clo);\n\tif(i != TVPContinuousHandlerVector.end())\n\t{\n\t\ti->Release();\n\t\ti->Object = i->ObjThis = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// \"Compact\" Event Delivering related\n//---------------------------------------------------------------------------\n// Compact events are to be delivered when:\n// 1. the application is in idle state for long duration\n// 2. the application had been deactivated ( application has lost the focus )\n// 3. the application had been minimized\n// these are to reduce memory usage, like garbage collection, cache cleaning,\n// or etc ...\n//---------------------------------------------------------------------------\nstatic std::vector<tTVPCompactEventCallbackIntf *> TVPCompactEventVector;\nbool TVPEnableGlobalHeapCompaction = false;\n//---------------------------------------------------------------------------\nvoid TVPAddCompactEventHook(tTVPCompactEventCallbackIntf *cb)\n{\n\tTVPCompactEventVector.push_back(cb);\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveCompactEventHook(tTVPCompactEventCallbackIntf *cb)\n{\n\tstd::vector<tTVPCompactEventCallbackIntf *>::iterator i;\n\tfor(i = TVPCompactEventVector.begin();\n\t\ti !=TVPCompactEventVector.end();)\n\t{\n\t\tif(cb == *i) *i = NULL; // simply assign a null\n\t\ti++;\n\t}\n}\n//---------------------------------------------------------------------------\nextern void TVPDoSaveSystemVariables();\nvoid TVPDeliverCompactEvent(tjs_int level)\n{\n\t// must be called by each platforms's implementation\n\t//std::vector<tTVPCompactEventCallbackIntf *>::iterator i;\n\tif(TVPCompactEventVector.size())\n\t{\n\t\tbool emptyflag = false;\n\t\tfor(tjs_uint i = 0; i < TVPCompactEventVector.size(); i ++)\n\t\t{\n\t\t\t// note that the handler can remove itself while the event\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif(TVPCompactEventVector[i])\n\t\t\t\t\t\tTVPCompactEventVector[i]->OnCompact(level); else emptyflag = true;\n\t\t\t\t}\n\t\t\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t\t\t}\n\t\t\tTVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION_FORCE_SHOW_EXCEPTION(TJS_W(\"Compact Event\"));\n\t\t}\n\n\t\tif(emptyflag)\n\t\t{\n\t\t\t// the array has empty cell\n\n\t\t\t// eliminate empty\n\t\t\tstd::vector<tTVPCompactEventCallbackIntf *>::iterator i;\n\t\t\tfor(i = TVPCompactEventVector.begin();\n\t\t\t\ti !=TVPCompactEventVector.end();)\n\t\t\t{\n\t\t\t\tif(*i == NULL)\n\t\t\t\t\ti = TVPCompactEventVector.erase(i);\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\tTVPDoSaveSystemVariables();\n#if 0\n\tif( level >= TVP_COMPACT_LEVEL_MAX && TVPEnableGlobalHeapCompaction )\n\t{\t// Do compact CRT and Global Heap\n\t\tHANDLE hHeap = ::GetProcessHeap();\n\t\tif( hHeap ) {\n\t\t\t::HeapCompact( hHeap, 0 );\n\t\t}\n\t\tHANDLE hCrtHeap = (HANDLE)_get_heap_handle();\n\t\tif( hCrtHeap && hCrtHeap != hHeap ) {\n\t\t\t::HeapCompact( hCrtHeap, 0 );\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// AsyncTrigger related\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_AsyncTrigger\n//---------------------------------------------------------------------------\ntTJSNI_AsyncTrigger::tTJSNI_AsyncTrigger()\n{\n\tOwner = NULL;\n\tCached = true;\n\tIdlePendingCount = 0;\n\tMode = atmNormal;\n\tActionOwner.Object = ActionOwner.ObjThis = NULL;\n\tActionName = TVPActionName;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\t\ttTJSNI_AsyncTrigger::Construct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tActionName = *param[1]; // action function to be called\n\n\tActionOwner = param[0]->AsObjectClosure();\n\tOwner = tjs_obj;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_AsyncTrigger::Invalidate()\n{\n\tTVPCancelSourceEvents(Owner);\n\tOwner = NULL;\n\n\tActionOwner.Release();\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_AsyncTrigger::Trigger()\n{\n\t// trigger event\n\tif(Owner)\n\t{\n\t\tif(Cached)\n\t\t{\n\t\t\t// remove undelivered events from queue when \"Cached\" flag is set\n\t\t\tTVPCancelSourceEvents(Owner);\n\t\t}\n\t\tstatic ttstr eventname(TJS_W(\"onFire\"));\n\n\t\ttjs_uint32 flags = TVP_EPT_POST;\n\t\tif(Mode == atmExclusive) flags |= TVP_EPT_EXCLUSIVE;  // fire exclusive event\n\t\tif(Mode == atmAtIdle)    flags |= TVP_EPT_IDLE;       // fire idle event\n\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, flags, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_AsyncTrigger::Cancel()\n{\n\t// cancel event\n\tif(Owner) TVPCancelSourceEvents(Owner);\n\tIdlePendingCount = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_AsyncTrigger::SetCached(bool b)\n{\n\t// set cached operation flag.\n\t// when this flag is set, only one event is delivered at once.\n\tif(Cached != b)\n\t{\n\t\tCached = b;\n\t\tCancel(); // all events are canceled\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_AsyncTrigger::SetMode(tTVPAsyncTriggerMode m)\n{\n\tif(Mode != m)\n\t{\n\t\tMode = m;\n\t\tCancel();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_AsyncTrigger\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_AsyncTrigger::ClassID = -1;\ntTJSNC_AsyncTrigger::tTJSNC_AsyncTrigger() : inherited(TJS_W(\"AsyncTrigger\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(AsyncTrigger) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_AsyncTrigger,\n\t/*TJS class name*/AsyncTrigger)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/AsyncTrigger)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/trigger)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t_this->Trigger();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/trigger)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/cancel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t_this->Cancel();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/cancel)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFire)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_AsyncTrigger);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tttstr & actionname = _this->GetActionName();\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onFire\", objthis);\n\t\tTVP_ACTION_INVOKE_END_NAME(obj,\n\t\t\tactionname.IsEmpty() ? NULL :actionname.c_str(),\n\t\t\tactionname.IsEmpty() ? NULL :actionname.GetHint());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFire)\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(cached)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t\t*result = _this->GetCached();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t\t_this->SetCached(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(cached)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t\t*result = (tjs_int)_this->GetMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger);\n\t\t_this->SetMode((tTVPAsyncTriggerMode)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mode)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_AsyncTrigger::CreateNativeInstance()\n{\n\treturn new tTJSNI_AsyncTrigger();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_AsyncTrigger()\n{\n\treturn new tTJSNC_AsyncTrigger();\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/base/EventIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script Event/Window Handling and Dispatching / System Idle Event Delivering\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#ifndef EventIntfH\n#define EventIntfH\n\n#include \"tjsNative.h\"\n\n\n\n//---------------------------------------------------------------------------\n// Event dispatching\n//---------------------------------------------------------------------------\nextern void TVPDeliverAllEvents(); // called from (indirectly) the OS\n\nextern bool TVPEventDisabled;  // do not write to this variable directly\n\nextern void TVPInvokeEvents();\n\t// implement this in each platform,\n\t// to ensure calling \"TVPDeliverAllEvents\" when the Application is\n\t// ready to deliver the events.\nextern void TVPEventReceived();\n\t// implement this in each platform.\n\t// notifies that events are delivered and ensure being ready for next event.\n\nextern void TVPCallDeliverAllEventsOnIdle();\n\t// implement this in each platform.\n\t// once return control to OS, and set to call TVPInvokeEvents() after it.\n\n\n\n//---------------------------------------------------------------------------\n// somewhat public\n\nTJS_EXP_FUNC_DEF(void, TVPBreathe, ());\n\t// implement this in each platform\n\t// to handle OS's message events\n\t// this should be called when in a long time processing, something like a\n\t// network access, to reply to user's Windowing message, repainting, etc...\n\t// in TVPBreathe, TVP events must not be invoked. ( happened events over the\n\t// long time processing are pending until next timing of message delivering. )\n\nTJS_EXP_FUNC_DEF(bool, TVPGetBreathing, ()); // return whether now is in event breathing\n\nTJS_EXP_FUNC_DEF(void, TVPSetSystemEventDisabledState, (bool en));\n\t/*\n\t\tsets whether system overall event handling is enabled.\n\t\tthis works distinctly from TVPEventDisabled.\n\t*/\n\nTJS_EXP_FUNC_DEF(bool, TVPGetSystemEventDisabledState, ());\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// Script Event Related\n//---------------------------------------------------------------------------\n#define TVP_EPT_POST\t\t\t0x00  // normal post, simply add to queue\n#define TVP_EPT_REMOVE_POST\t\t0x01\n\t\t// remove event in pending queue that has same target, source, tag and\n\t\t// name before post\n\t\t// (for input events, only the source and the tag are to be checked)\n#define TVP_EPT_IMMEDIATE\t\t0x02\n\t\t// the event will be delivered immediately\n\n#define TVP_EPT_DISCARDABLE\t\t0x10\n\t\t// the event can be discarded when event system is disabled\n\n#define TVP_EPT_NORMAL\t\t\t0x00\n\t\t// (with TVP_EPT_POST only)\n\t\t// the event will have normal priority.\n\n#define TVP_EPT_EXCLUSIVE\t\t0x20\n\t\t// (with TVP_EPT_POST only)\n\t\t// the event is given priority and other posted events are not processed\n\t\t// until the exclusive event is processed.\n\n#define TVP_EPT_IDLE\t\t\t0x40\n\t\t// (with TVP_EPT_POST only)\n\t\t// the event is only delivered after the system processes all other events.\n\t\t// this will have a priority roughly identical to \"continuous\" events.\n\n#define TVP_EPT_PRIO_MASK\t\t0xe0\n\n#define TVP_EPT_METHOD_MASK\t\t0x0f\n/*]*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPPostEvent, (iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tttstr &eventname, tjs_uint32 tag, tjs_uint32 flag,\n\ttjs_uint numargs, tTJSVariant *args));\n\t\t// posts TVP event. this function itself is thread-safe.\n\nTJS_EXP_FUNC_DEF(tjs_int, TVPCancelEvents, (iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag = 0));\n\t\t// removes events that has specified source/target/name/tag.\n\t\t// tag == 0 removes all tag from queue.\n\t\t// returns count of removed events.\n\nTJS_EXP_FUNC_DEF(bool, TVPAreEventsInQueue, (iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag));\n\t\t// returns whether the events are in queue that have specified\n\t\t// source/target/name/tag.\n\t\t// tag == 0 matches all tag in queue.\n\nTJS_EXP_FUNC_DEF(tjs_int, TVPCountEventsInQueue, (iTJSDispatch2 * source, iTJSDispatch2 *target,\n\tconst ttstr &eventname, tjs_uint32 tag));\n\t\t// returns count of the events in queue that have specified\n\t\t// source/target/name/tag.\n\t\t// tag == 0 matches all tag in queue.\n\nTJS_EXP_FUNC_DEF(void, TVPCancelEventsByTag, (iTJSDispatch2 * source, iTJSDispatch2 *target,\n\ttjs_uint32 tag = 0));\n\t\t// removes all events which have the same source/target/tag.\n\t\t// tag == 0 removes all tag from queue.\n\nTJS_EXP_FUNC_DEF(void, TVPCancelSourceEvents, (iTJSDispatch2 * source));\n\t\t// removes all events that has specified source.\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Window update event related\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseWindow;\nextern void TVPPostWindowUpdate(tTJSNI_BaseWindow *window);\nextern void TVPRemoveWindowUpdate(tTJSNI_BaseWindow *window);\nextern void TVPDeliverWindowUpdateEvents();\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// User input event related\n//---------------------------------------------------------------------------\nclass tTVPBaseInputEvent // base user input event class\n{\n\tvoid * Source;\n\ttjs_int Tag;\npublic:\n\ttTVPBaseInputEvent(void *source, tjs_int tag) { Source = source; Tag = tag; }\n\tvirtual ~tTVPBaseInputEvent() {};\n\tvirtual void Deliver() const = 0;\n\tvoid * GetSource() const { return Source; }\n\ttjs_int GetTag() const { return Tag; }\n};\n//---------------------------------------------------------------------------\nextern tjs_int TVPInputEventTagMax;\nclass tTVPUniqueTagForInputEvent // a class for getting unique tag per a event class\n{\npublic:\n\ttjs_int Tag;\n\ttTVPUniqueTagForInputEvent() : Tag(++TVPInputEventTagMax) {;}\n\n\toperator tjs_int() const { return Tag; }\n};\n//---------------------------------------------------------------------------\nextern void TVPPostInputEvent(tTVPBaseInputEvent *ev, tjs_uint32 flags = 0);\nextern void TVPCancelInputEvents(void * source);\nextern void TVPCancelInputEvents(void * source, tjs_int tag);\nextern tjs_int TVPGetInputEventCount();\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateEventObject\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TVPCreateEventObject, (const tjs_char *type,\n\tiTJSDispatch2 *targthis, iTJSDispatch2 *targ));\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// some macros for driving \"action\" method\n//---------------------------------------------------------------------------\nextern ttstr TVPActionName;\n#define TVP_ACTION_INVOKE_BEGIN(argnum, name, object) \\\n\t{ \\\n\t\tif(numparams < (argnum)) return TJS_E_BADPARAMCOUNT; \\\n\t\ttjs_int arg_count = 0; \\\n\t\tiTJSDispatch2 *evobj = TVPCreateEventObject(TJS_W(name), (object), \\\n\t\t\t(object)); \\\n\t\ttTJSVariant evval(evobj, evobj); \\\n\t\tevobj->Release();\n\n#define TVP_ACTION_INVOKE_MEMBER(name) \\\n\t{\\\n\t\tstatic ttstr member_name(TJS_W(name)); \\\n\t\tevobj->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, \\\n\t\t\tmember_name.c_str(), member_name.GetHint(), param[arg_count++], \\\n\t\t\tevobj); \\\n\t}\n\n#define TVP_ACTION_INVOKE_END(object) \\\n\t\ttTJSVariant *pevval = &evval; \\\n\t\t(object).FuncCall(0, TVPActionName.c_str(), TVPActionName.GetHint(), \\\n\t\t\tresult, 1, &pevval, NULL); \\\n\t}\n\n#define TVP_ACTION_INVOKE_END_NAME(object, name, hint) \\\n\t\ttTJSVariant *pevval = &evval; \\\n\t\t(object).FuncCall(0, (name), (hint), \\\n\t\t\tresult, 1, &pevval, NULL); \\\n\t}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Continuous Event related\n//---------------------------------------------------------------------------\n/*[*/\nclass tTVPContinuousEventCallbackIntf // callback class for continuous event delivering\n{\npublic:\n\tvirtual void TJS_INTF_METHOD OnContinuousCallback(tjs_uint64 tick) = 0;\n};\n/*]*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPAddContinuousEventHook, (tTVPContinuousEventCallbackIntf *cb));\nTJS_EXP_FUNC_DEF(void, TVPRemoveContinuousEventHook, (tTVPContinuousEventCallbackIntf *cb));\n\nextern void TVPBeginContinuousEvent();\n\t// must be implemented in each platforms\n\t// this must begin calling TVPDeliverContinuousEvent\n\nextern void TVPEndContinuousEvent();\n\t// must be implemented in each platforms\n\t// this must stop calling TVPDeliverContinuousEvent\n\nextern void TVPDeliverContinuousEvent();\n\t// must be called by each platforms's implementation\n\nextern void TVPAddContinuousHandler(tTJSVariantClosure clo);\n\t// add callback function written in TJS\nextern void TVPRemoveContinuousHandler(tTJSVariantClosure clo);\n\t// remove callback function added by TVPAddIdleHandler\n\nextern bool TVPProcessContinuousHandlerEventFlag;\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// System \"Compact\" Event related\n//---------------------------------------------------------------------------\n#define TVP_COMPACT_LEVEL_IDLE        5  // the application is in idle state\n#define TVP_COMPACT_LEVEL_DEACTIVATE 10  // the application had been deactivated\n#define TVP_COMPACT_LEVEL_MINIMIZE   15  // the application had been minimized\n#define TVP_COMPACT_LEVEL_MAX       100  // strongest level, should clear all caches\n//---------------------------------------------------------------------------\nclass tTVPCompactEventCallbackIntf // callback class for compact event delivering\n{\npublic:\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level) = 0;\n};\n/*]*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPAddCompactEventHook, (tTVPCompactEventCallbackIntf *cb));\nTJS_EXP_FUNC_DEF(void, TVPRemoveCompactEventHook, (tTVPCompactEventCallbackIntf *cb));\n\nextern void TVPDeliverCompactEvent(tjs_int level);\n\t// must be called by each platforms's implementation\n//---------------------------------------------------------------------------\n\n\n\n\n\n/*\n\tAsyncTrigger is a class for invoking events at asynchronous.\n\tScript can trigger event but the event is not delivered immediately,\n\tis delivered at next event flush phase.\n*/\n/*[*/\n//---------------------------------------------------------------------------\n// AsyncTrigger related\n//---------------------------------------------------------------------------\nenum tTVPAsyncTriggerMode\n{\n\tatmNormal, atmExclusive, atmAtIdle\n};\n/*]*/\n\n//---------------------------------------------------------------------------\n// tTJSNI_AsyncTrigger : TJS AsyncTrigger native instance\n//---------------------------------------------------------------------------\nclass tTJSNI_AsyncTrigger : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\nprotected:\n\tiTJSDispatch2 *Owner;\n\ttTJSVariantClosure ActionOwner; // object to send action\n\tttstr ActionName;\n\n\tbool Cached; // cached operation\n\ttTVPAsyncTriggerMode Mode; // event mode\n\ttjs_int IdlePendingCount;\n\npublic:\n\ttTJSNI_AsyncTrigger();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n\tttstr & GetActionName() { return ActionName; }\n\n\tvoid Trigger();\n\tvoid Cancel();\n\n\tbool GetCached() const { return Cached; }\n\tvoid SetCached(bool b);\n\n\ttTVPAsyncTriggerMode GetMode() const { return Mode; }\n\tvoid SetMode(tTVPAsyncTriggerMode m);\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_AsyncTrigger : TJS AsyncTrigger class\n//---------------------------------------------------------------------------\nclass tTJSNC_AsyncTrigger : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_AsyncTrigger();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_AsyncTrigger();\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/PluginIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Plugins\" class interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include \"PluginIntf.h\"\n#include \"MsgIntf.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Plugins\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Plugins::ClassID = -1;\ntTJSNC_Plugins::tTJSNC_Plugins() : inherited(TJS_W(\"Plugins\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Plugins)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\n\n//--properties\n\n//---------------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance * tTJSNC_Plugins::CreateNativeInstance()\n{\n\t// this class cannot create an instance\n\tTVPThrowExceptionMessage(TVPCannotCreateInstance);\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/base/PluginIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Plugins\" class interface\n//---------------------------------------------------------------------------\n#ifndef PluginIntfH\n#define PluginIntfH\n\n#include \"tjsNative.h\"\n#if 0\n#ifndef __stdcall\n#define __stdcall\n#endif\n#ifndef __cdecl\n#define __cdecl\n#endif\n#ifndef _stdcall\n#define _stdcall\n#endif\n#ifndef _cdecl\n#define _cdecl\n#endif\n#endif\n\n//---------------------------------------------------------------------------\n// tTJSNC_Plugins : TJS Plugins class\n//---------------------------------------------------------------------------\nclass tTJSNC_Plugins : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Plugins();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Plugins();\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/ScriptMgnIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 Script Managing\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjs.h\"\n#include \"tjsDebug.h\"\n#include \"tjsArray.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"StorageIntf.h\"\n#include \"DebugIntf.h\"\n#include \"WindowIntf.h\"\n#include \"LayerIntf.h\"\n#include \"CDDAIntf.h\"\n#include \"MIDIIntf.h\"\n#include \"WaveIntf.h\"\n#include \"TimerIntf.h\"\n#include \"EventIntf.h\"\n#include \"SystemIntf.h\"\n#include \"PluginIntf.h\"\n#include \"MenuItemIntf.h\"\n#include \"ClipboardIntf.h\"\n#include \"MsgIntf.h\"\n#include \"KAGParser.h\"\n#include \"VideoOvlIntf.h\"\n#include \"PadIntf.h\"\n#include \"TextStream.h\"\n#include \"Random.h\"\n#include \"tjsRandomGenerator.h\"\n#include \"SysInitIntf.h\"\n#include \"PhaseVocoderFilter.h\"\n#include \"BasicDrawDevice.h\"\n#include \"BinaryStream.h\"\n#include \"SysInitImpl.h\"\n#include \"SystemControl.h\"\n#include \"Application.h\"\n\n#include \"RectItf.h\"\n#include \"ImageFunction.h\"\n#include \"BitmapIntf.h\"\n#include \"tjsScriptBlock.h\"\n#include \"ApplicationSpecialPath.h\"\n#include \"SystemImpl.h\"\n#include \"BitmapLayerTreeOwner.h\"\n#include \"Extension.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n\n//---------------------------------------------------------------------------\n// Script system initialization script\n//---------------------------------------------------------------------------\nstatic const tjs_nchar * TVPInitTJSScript =\n\t// note that this script is stored as narrow string\nTJS_N(\"const\\\n\\\n/* constants */\\\n /* tTVPBorderStyle */ bsNone=0,  bsSingle=1,  bsSizeable=2,  bsDialog=3,  bsToolWindow=4,  bsSizeToolWin=5,\\\n /* tTVPUpdateType */ utNormal=0,  utEntire =1,\\\n /* tTVPMouseButton */  mbLeft=0,  mbRight=1,  mbMiddle=2, mbX1=3, mbX2=4,\\\n /* tTVPMouseCursorState */ mcsVisible=0, mcsTempHidden=1, mcsHidden=2,\\\n /* tTVPImeMode */ imDisable=0, imClose=1, imOpen=2, imDontCare=3, imSAlpha=4, imAlpha=5, imHira=6, imSKata=7, imKata=8, imChinese=9, imSHanguel=10, imHanguel=11,\\\n /* Set of shift state */  ssShift=(1<<0),  ssAlt=(1<<1),  ssCtrl=(1<<2),  ssLeft=(1<<3),  ssRight=(1<<4),  ssMiddle=(1<<5),  ssDouble =(1<<6),  ssRepeat = (1<<7),\\\n /* TVP_FSF_???? */ fsfFixedPitch=1, fsfSameCharSet=2, fsfNoVertical=4, \\\n\tfsfTrueTypeOnly=8, fsfUseFontFace=0x100, fsfIgnoreSymbol=0x10,\\\n /* tTVPLayerType */ ltBinder=0, ltCoverRect=1, ltOpaque=1, ltTransparent=2, ltAlpha=2, ltAdditive=3, ltSubtractive=4, ltMultiplicative=5, ltEffect=6, ltFilter=7, ltDodge=8, ltDarken=9, ltLighten=10, ltScreen=11, ltAddAlpha = 12,\\\n\tltPsNormal = 13, ltPsAdditive = 14, ltPsSubtractive = 15, ltPsMultiplicative = 16, ltPsScreen = 17, ltPsOverlay = 18, ltPsHardLight = 19, ltPsSoftLight = 20, ltPsColorDodge = 21, ltPsColorDodge5 = 22, ltPsColorBurn = 23, ltPsLighten = 24, ltPsDarken = 25, ltPsDifference = 26, ltPsDifference5 = 27, ltPsExclusion = 28, \\\n /* tTVPBlendOperationMode */ omPsNormal = ltPsNormal,omPsAdditive = ltPsAdditive,omPsSubtractive = ltPsSubtractive,omPsMultiplicative = ltPsMultiplicative,omPsScreen = ltPsScreen,omPsOverlay = ltPsOverlay,omPsHardLight = ltPsHardLight,omPsSoftLight = ltPsSoftLight,omPsColorDodge = ltPsColorDodge,omPsColorDodge5 = ltPsColorDodge5,omPsColorBurn = ltPsColorBurn,omPsLighten = ltPsLighten,omPsDarken = ltPsDarken,omPsDifference = ltPsDifference,omPsDifference5 = ltPsDifference5,omPsExclusion = ltPsExclusion, \\\n\tomAdditive=ltAdditive, omSubtractive=ltSubtractive, omMultiplicative=ltMultiplicative, omDodge=ltDodge, omDarken=ltDarken, omLighten=ltLighten, omScreen=ltScreen, omAddAlpha=ltAddAlpha, omOpaque=ltOpaque, omAlpha=ltAlpha, omAuto = 128,\\\n /* tTVPDrawFace */ dfBoth=0, dfAlpha = dfBoth, dfAddAlpha = 4, dfMain=1, dfOpaque = dfMain, dfMask=2, dfProvince=3, dfAuto=128,\\\n /* tTVPHitType */ htMask=0, htProvince=1,\\\n /* tTVPScrollTransFrom */ sttLeft=0, sttTop=1, sttRight=2, sttBottom=3,\\\n /* tTVPScrollTransStay */ ststNoStay=0, ststStayDest=1, ststStaySrc=2, \\\n /* tTVPKAGDebugLevel */ tkdlNone=0, tkdlSimple=1, tkdlVerbose=2, \\\n /* tTVPAsyncTriggerMode */\tatmNormal=0, atmExclusive=1, atmAtIdle=2, \\\n /* tTVPBBStretchType */ stNearest=0, stFastLinear=1, stLinear=2, stCubic=3, stSemiFastLinear = 4, stFastCubic = 5, stLanczos2 = 6, stFastLanczos2 = 7, stLanczos3 = 8, stFastLanczos3 = 9, stSpline16 = 10, stFastSpline16 = 11, stSpline36 = 12, stFastSpline36 = 13, stAreaAvg = 14, stFastAreaAvg = 15, stGaussian = 16, stFastGaussian = 17, stBlackmanSinc = 18, stFastBlackmanSinc = 19, stRefNoClip = 0x10000,\\\n /* tTVPClipboardFormat */ cbfText = 1,\\\n /* TVP_COMPACT_LEVEL_???? */ clIdle = 5, clDeactivate = 10, clMinimize = 15, clAll = 100,\\\n /* tTVPVideoOverlayMode Add: T.Imoto */ vomOverlay=0, vomLayer=1, vomMixer=2, vomMFEVR=3,\\\n /* tTVPPeriodEventReason */ perLoop = 0, perPeriod = 1, perPrepare = 2, perSegLoop = 3,\\\n /* tTVPSoundGlobalFocusMode */ sgfmNeverMute = 0, sgfmMuteOnMinimize = 1, sgfmMuteOnDeactivate = 2,\\\n /* tTVPTouchDevice */ tdNone=0, tdIntegratedTouch=0x01, tdExternalTouch=0x02, tdIntegratedPen=0x04, tdExternalPen=0x08, tdMultiInput=0x40, tdDigitizerReady=0x80,\\\n    tdMouse=0x0100, tdMouseWheel=0x0200,\\\n /* Display Orientation */ oriUnknown=0, oriPortrait=1, oriLandscape=2,\\\n\\\n/* file attributes */\\\n faReadOnly=0x01, faHidden=0x02, faSysFile=0x04, faVolumeID=0x08, faDirectory=0x10, faArchive=0x20, faAnyFile=0x3f,\\\n/* mouse cursor constants */\\\n crDefault = 0x0,\\\n crNone = -1,\\\n crArrow = -2,\\\n crCross = -3,\\\n crIBeam = -4,\\\n crSize = -5,\\\n crSizeNESW = -6,\\\n crSizeNS = -7,\\\n crSizeNWSE = -8,\\\n crSizeWE = -9,\\\n crUpArrow = -10,\\\n crHourGlass = -11,\\\n crDrag = -12,\\\n crNoDrop = -13,\\\n crHSplit = -14,\\\n crVSplit = -15,\\\n crMultiDrag = -16,\\\n crSQLWait = -17,\\\n crNo = -18,\\\n crAppStart = -19,\\\n crHelp = -20,\\\n crHandPoint = -21,\\\n crSizeAll = -22,\\\n crHBeam = 1,\\\n/* color constants */\\\n clScrollBar = 0x80000000,\\\n clBackground = 0x80000001,\\\n clActiveCaption = 0x80000002,\\\n clInactiveCaption = 0x80000003,\\\n clMenu = 0x80000004,\\\n clWindow = 0x80000005,\\\n clWindowFrame = 0x80000006,\\\n clMenuText = 0x80000007,\\\n clWindowText = 0x80000008,\\\n clCaptionText = 0x80000009,\\\n clActiveBorder = 0x8000000a,\\\n clInactiveBorder = 0x8000000b,\\\n clAppWorkSpace = 0x8000000c,\\\n clHighlight = 0x3399ff,\\\n clHighlightText = 0x8000000e,\\\n clBtnFace = 0xf0f0f0,\\\n clBtnShadow = 0x787878,\\\n clGrayText = 0x80000011,\\\n clBtnText = 0x000000,\\\n clInactiveCaptionText = 0x80000013,\\\n clBtnHighlight = 0x80000014,\\\n cl3DDkShadow = 0x80000015,\\\n cl3DLight = 0x80000016,\\\n clInfoText = 0x80000017,\\\n clInfoBk = 0x80000018,\\\n clNone = 0x1fffffff,\\\n clAdapt= 0x01ffffff,\\\n clPalIdx = 0x3000000,\\\n clAlphaMat = 0x4000000,\\\n/* for Menu.trackPopup (see winuser.h) */\\\n tpmLeftButton      = 0x0000,\\\n tpmRightButton     = 0x0002,\\\n tpmLeftAlign       = 0x0000,\\\n tpmCenterAlign     = 0x0004,\\\n tpmRightAlign      = 0x0008,\\\n tpmTopAlign        = 0x0000,\\\n tpmVCenterAlign    = 0x0010,\\\n tpmBottomAlign     = 0x0020,\\\n tpmHorizontal      = 0x0000,\\\n tpmVertical        = 0x0040,\\\n tpmNoNotify        = 0x0080,\\\n tpmReturnCmd       = 0x0100,\\\n tpmRecurse         = 0x0001,\\\n tpmHorPosAnimation = 0x0400,\\\n tpmHorNegAnimation = 0x0800,\\\n tpmVerPosAnimation = 0x1000,\\\n tpmVerNegAnimation = 0x2000,\\\n tpmNoAnimation     = 0x4000,\\\n/* for Pad.showScrollBars (see Vcl/stdctrls.hpp :: enum TScrollStyle) */\\\n ssNone       = 0,\\\n ssHorizontal = 1,\\\n ssVertical   = 2,\\\n ssBoth       = 3,\\\n/* virtual keycodes */\\\n VK_LBUTTON =0x01,\\\n VK_RBUTTON =0x02,\\\n VK_CANCEL =0x03,\\\n VK_MBUTTON =0x04,\\\n VK_BACK =0x08,\\\n VK_TAB =0x09,\\\n VK_CLEAR =0x0C,\\\n VK_RETURN =0x0D,\\\n VK_SHIFT =0x10,\\\n VK_CONTROL =0x11,\\\n VK_MENU =0x12,\\\n VK_PAUSE =0x13,\\\n VK_CAPITAL =0x14,\\\n VK_KANA =0x15,\\\n VK_HANGEUL =0x15,\\\n VK_HANGUL =0x15,\\\n VK_JUNJA =0x17,\\\n VK_FINAL =0x18,\\\n VK_HANJA =0x19,\\\n VK_KANJI =0x19,\\\n VK_ESCAPE =0x1B,\\\n VK_CONVERT =0x1C,\\\n VK_NONCONVERT =0x1D,\\\n VK_ACCEPT =0x1E,\\\n VK_MODECHANGE =0x1F,\\\n VK_SPACE =0x20,\\\n VK_PRIOR =0x21,\\\n VK_NEXT =0x22,\\\n VK_END =0x23,\\\n VK_HOME =0x24,\\\n VK_LEFT =0x25,\\\n VK_UP =0x26,\\\n VK_RIGHT =0x27,\\\n VK_DOWN =0x28,\\\n VK_SELECT =0x29,\\\n VK_PRINT =0x2A,\\\n VK_EXECUTE =0x2B,\\\n VK_SNAPSHOT =0x2C,\\\n VK_INSERT =0x2D,\\\n VK_DELETE =0x2E,\\\n VK_HELP =0x2F,\\\n VK_0 =0x30,\\\n VK_1 =0x31,\\\n VK_2 =0x32,\\\n VK_3 =0x33,\\\n VK_4 =0x34,\\\n VK_5 =0x35,\\\n VK_6 =0x36,\\\n VK_7 =0x37,\\\n VK_8 =0x38,\\\n VK_9 =0x39,\\\n VK_A =0x41,\\\n VK_B =0x42,\\\n VK_C =0x43,\\\n VK_D =0x44,\\\n VK_E =0x45,\\\n VK_F =0x46,\\\n VK_G =0x47,\\\n VK_H =0x48,\\\n VK_I =0x49,\\\n VK_J =0x4A,\\\n VK_K =0x4B,\\\n VK_L =0x4C,\\\n VK_M =0x4D,\\\n VK_N =0x4E,\\\n VK_O =0x4F,\\\n VK_P =0x50,\\\n VK_Q =0x51,\\\n VK_R =0x52,\\\n VK_S =0x53,\\\n VK_T =0x54,\\\n VK_U =0x55,\\\n VK_V =0x56,\\\n VK_W =0x57,\\\n VK_X =0x58,\\\n VK_Y =0x59,\\\n VK_Z =0x5A,\\\n VK_LWIN =0x5B,\\\n VK_RWIN =0x5C,\\\n VK_APPS =0x5D,\\\n VK_NUMPAD0 =0x60,\\\n VK_NUMPAD1 =0x61,\\\n VK_NUMPAD2 =0x62,\\\n VK_NUMPAD3 =0x63,\\\n VK_NUMPAD4 =0x64,\\\n VK_NUMPAD5 =0x65,\\\n VK_NUMPAD6 =0x66,\\\n VK_NUMPAD7 =0x67,\\\n VK_NUMPAD8 =0x68,\\\n VK_NUMPAD9 =0x69,\\\n VK_MULTIPLY =0x6A,\\\n VK_ADD =0x6B,\\\n VK_SEPARATOR =0x6C,\\\n VK_SUBTRACT =0x6D,\\\n VK_DECIMAL =0x6E,\\\n VK_DIVIDE =0x6F,\\\n VK_F1 =0x70,\\\n VK_F2 =0x71,\\\n VK_F3 =0x72,\\\n VK_F4 =0x73,\\\n VK_F5 =0x74,\\\n VK_F6 =0x75,\\\n VK_F7 =0x76,\\\n VK_F8 =0x77,\\\n VK_F9 =0x78,\\\n VK_F10 =0x79,\\\n VK_F11 =0x7A,\\\n VK_F12 =0x7B,\\\n VK_F13 =0x7C,\\\n VK_F14 =0x7D,\\\n VK_F15 =0x7E,\\\n VK_F16 =0x7F,\\\n VK_F17 =0x80,\\\n VK_F18 =0x81,\\\n VK_F19 =0x82,\\\n VK_F20 =0x83,\\\n VK_F21 =0x84,\\\n VK_F22 =0x85,\\\n VK_F23 =0x86,\\\n VK_F24 =0x87,\\\n VK_NUMLOCK =0x90,\\\n VK_SCROLL =0x91,\\\n VK_LSHIFT =0xA0,\\\n VK_RSHIFT =0xA1,\\\n VK_LCONTROL =0xA2,\\\n VK_RCONTROL =0xA3,\\\n VK_LMENU =0xA4,\\\n VK_RMENU =0xA5,\\\n/* VK_PADXXXX are KIRIKIRI specific */\\\n VK_PADLEFT =0x1B5,\\\n VK_PADUP =0x1B6,\\\n VK_PADRIGHT =0x1B7,\\\n VK_PADDOWN =0x1B8,\\\n VK_PAD1 =0x1C0,\\\n VK_PAD2 =0x1C1,\\\n VK_PAD3 =0x1C2,\\\n VK_PAD4 =0x1C3,\\\n VK_PAD5 =0x1C4,\\\n VK_PAD6 =0x1C5,\\\n VK_PAD7 =0x1C6,\\\n VK_PAD8 =0x1C7,\\\n VK_PAD9 =0x1C8,\\\n VK_PAD10 =0x1C9,\\\n VK_PADANY = 0x1DF,\\\n VK_PROCESSKEY =0xE5,\\\n VK_ATTN =0xF6,\\\n VK_CRSEL =0xF7,\\\n VK_EXSEL =0xF8,\\\n VK_EREOF =0xF9,\\\n VK_PLAY =0xFA,\\\n VK_ZOOM =0xFB,\\\n VK_NONAME =0xFC,\\\n VK_PA1 =0xFD,\\\n VK_OEM_CLEAR =0xFE,\\\n frFreeType=0,\\\n frGDI=1,\\\n/* graphic cache system */\\\n gcsAuto=-1,\\\n/* image 'mode' tag (mainly is generated by image format converter) constants */\\\n imageTagLayerType = %[\\\nopaque\t\t:%[type:ltOpaque\t\t\t],\\\nrect\t\t:%[type:ltOpaque\t\t\t],\\\nalpha\t\t:%[type:ltAlpha\t\t\t\t],\\\ntransparent\t:%[type:ltAlpha\t\t\t\t],\\\naddalpha\t:%[type:ltAddAlpha\t\t\t],\\\nadd\t\t\t:%[type:ltAdditive\t\t\t],\\\nsub\t\t\t:%[type:ltSubtractive\t\t],\\\nmul\t\t\t:%[type:ltMultiplicative\t],\\\ndodge\t\t:%[type:ltDodge\t\t\t\t],\\\ndarken\t\t:%[type:ltDarken\t\t\t],\\\nlighten\t\t:%[type:ltLighten\t\t\t],\\\nscreen\t\t:%[type:ltScreen\t\t\t],\\\npsnormal\t:%[type:ltPsNormal\t\t\t],\\\npsadd\t\t:%[type:ltPsAdditive\t\t],\\\npssub\t\t:%[type:ltPsSubtractive\t\t],\\\npsmul\t\t:%[type:ltPsMultiplicative\t],\\\npsscreen\t:%[type:ltPsScreen\t\t\t],\\\npsoverlay\t:%[type:ltPsOverlay\t\t\t],\\\npshlight\t:%[type:ltPsHardLight\t\t],\\\npsslight\t:%[type:ltPsSoftLight\t\t],\\\npsdodge\t\t:%[type:ltPsColorDodge\t\t],\\\npsdodge5\t:%[type:ltPsColorDodge5\t\t],\\\npsburn\t\t:%[type:ltPsColorBurn\t\t],\\\npslighten\t:%[type:ltPsLighten\t\t\t],\\\npsdarken\t:%[type:ltPsDarken\t\t\t],\\\npsdiff\t\t:%[type:ltPsDifference\t\t],\\\npsdiff5\t\t:%[type:ltPsDifference5\t\t],\\\npsexcl\t\t:%[type:ltPsExclusion\t\t],\\\n],\\\n/* draw thread num */\\\n dtnAuto=0\\\n;\");\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// global variables\n//---------------------------------------------------------------------------\ntTJS *TVPScriptEngine = NULL;\nttstr TVPStartupScriptName(TJS_W(\"startup.tjs\"));\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Garbage Collection stuff\n//---------------------------------------------------------------------------\nclass tTVPTJSGCCallback : public tTVPCompactEventCallbackIntf\n{\n\tvoid TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\t// OnCompact method from tTVPCompactEventCallbackIntf\n\t\t// called when the application is idle, deactivated, minimized, or etc...\n\t\tif(TVPScriptEngine)\n\t\t{\n\t\t\tif(level >= TVP_COMPACT_LEVEL_IDLE)\n\t\t\t{\n\t\t\t\tTVPScriptEngine->DoGarbageCollection();\n\t\t\t}\n\t\t}\n\t}\n} static TVPTJSGCCallback;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPInitScriptEngine\n//---------------------------------------------------------------------------\nstatic bool TVPScriptEngineInit = false;\nvoid TVPInitScriptEngine()\n{\n\tif(TVPScriptEngineInit) return;\n\tTVPScriptEngineInit = true;\n\n\ttTJSVariant val;\n\n\t// Set eval expression mode\n\tif(TVPGetCommandLine(TJS_W(\"-evalcontext\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"global\"))\n\t\t{\n\t\t\tTJSEvalOperatorIsOnGlobal = true;\n\t\t\tTJSWarnOnNonGlobalEvalOperator = true;\n\t\t}\n\t}\n\n\t// Set igonre-prop compat mode\n\tif(TVPGetCommandLine(TJS_W(\"-unaryaster\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"compat\"))\n\t\t{\n\t\t\tTJSUnaryAsteriskIgnoresPropAccess = true;\n\t\t}\n\t}\n\n\t// Set debug mode\n\tif(TVPGetCommandLine(TJS_W(\"-debug\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t{\n\t\t\tTJSEnableDebugMode = true;\n\t\t\tTVPAddImportantLog((const tjs_char *)TVPWarnDebugOptionEnabled);\n//\t\t\tif(TVPGetCommandLine(TJS_W(\"-warnrundelobj\"), &val) )\n//\t\t\t{\n//\t\t\t\tstr = val;\n//\t\t\t\tif(str == TJS_W(\"yes\"))\n//\t\t\t\t{\n\t\t\t\t\tTJSWarnOnExecutionOnDeletingObject = true;\n//\t\t\t\t}\n//\t\t\t}\n\t\t}\n\t}\n\t// Set Read text encoding\n#if 0\n\tif(TVPGetCommandLine(TJS_W(\"-readencoding\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tTVPSetDefaultReadEncoding( str );\n\t}\n\tTVPScriptTextEncoding = ttstr(TVPGetDefaultReadEncoding());\n#endif\n#ifdef TVP_START_UP_SCRIPT_NAME\n\tTVPStartupScriptName = TVP_START_UP_SCRIPT_NAME;\n#else\n\t// Set startup script name\n\tif(TVPGetCommandLine(TJS_W(\"-startup\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tTVPStartupScriptName = str;\n\t}\n#endif\n\n\t// create script engine object\n\tTVPScriptEngine = new tTJS();\n\n\t// add kirikiriz\n\t//TVPScriptEngine->SetPPValue( TJS_W(\"kirikiriz\"), 1 );\n\n\t// set TJSGetRandomBits128\n\tTJSGetRandomBits128 = TVPGetRandomBits128;\n\n\t// script system initialization\n\tTVPScriptEngine->ExecScript(ttstr(TVPInitTJSScript));\n\n\t// set console output gateway handler\n\tTVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway());\n\n\n\t// set text stream functions\n\tTJSCreateTextStreamForRead = TVPCreateTextStreamForRead;\n\tTJSCreateTextStreamForWrite = TVPCreateTextStreamForWrite;\n\t\n\t// set binary stream functions\n\tTJSCreateBinaryStreamForRead = TVPCreateBinaryStreamForRead;\n\tTJSCreateBinaryStreamForWrite = TVPCreateBinaryStreamForWrite;\n\n\t// register some TVP classes/objects/functions/propeties\n\tiTJSDispatch2 *dsp;\n\tiTJSDispatch2 *global = TVPScriptEngine->GetGlobalNoAddRef();\n\n\n#define REGISTER_OBJECT(classname, instance) \\\n\tdsp = (instance); \\\n\tval = tTJSVariant(dsp/*, dsp*/); \\\n\tdsp->Release(); \\\n\tglobal->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, TJS_W(#classname), NULL, \\\n\t\t&val, global);\n\n\t/* classes */\n\tREGISTER_OBJECT(Debug, TVPCreateNativeClass_Debug());\n\tREGISTER_OBJECT(Font, TVPCreateNativeClass_Font());\n\tREGISTER_OBJECT(Layer, TVPCreateNativeClass_Layer());\n\tREGISTER_OBJECT(CDDASoundBuffer, TVPCreateNativeClass_CDDASoundBuffer());\n\tREGISTER_OBJECT(MIDISoundBuffer, TVPCreateNativeClass_MIDISoundBuffer());\n\tREGISTER_OBJECT(Timer, TVPCreateNativeClass_Timer());\n\tREGISTER_OBJECT(AsyncTrigger, TVPCreateNativeClass_AsyncTrigger());\n\tREGISTER_OBJECT(System, TVPCreateNativeClass_System());\n\tREGISTER_OBJECT(Storages, TVPCreateNativeClass_Storages());\n\tREGISTER_OBJECT(Plugins, TVPCreateNativeClass_Plugins());\n\tREGISTER_OBJECT(VideoOverlay, TVPCreateNativeClass_VideoOverlay());\n\tREGISTER_OBJECT(Pad, TVPCreateNativeClass_Pad());\n\tREGISTER_OBJECT(Clipboard, TVPCreateNativeClass_Clipboard());\n\tREGISTER_OBJECT(Scripts, TVPCreateNativeClass_Scripts()); // declared in this file\n\tREGISTER_OBJECT(Rect, TVPCreateNativeClass_Rect());\n\tREGISTER_OBJECT(Bitmap, TVPCreateNativeClass_Bitmap());\n\tREGISTER_OBJECT(ImageFunction, TVPCreateNativeClass_ImageFunction());\n\tREGISTER_OBJECT(BitmapLayerTreeOwner, TVPCreateNativeClass_BitmapLayerTreeOwner());\n\n\t/* KAG special support */\n\tREGISTER_OBJECT(KAGParser, TVPCreateNativeClass_KAGParser());\n\n\t/* WaveSoundBuffer and its filters */\n\tiTJSDispatch2 * waveclass = NULL;\n\tREGISTER_OBJECT(WaveSoundBuffer, (waveclass = TVPCreateNativeClass_WaveSoundBuffer()));\n\tdsp = new tTJSNC_PhaseVocoder();\n\tval = tTJSVariant(dsp);\n\tdsp->Release();\n\twaveclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER,\n\t\tTJS_W(\"PhaseVocoder\"), NULL, &val, waveclass);\n\n\t/* Window and its drawdevices */\n\tiTJSDispatch2 * windowclass = NULL;\n\tREGISTER_OBJECT(Window, (windowclass = TVPCreateNativeClass_Window()));\n\tdsp = new tTJSNC_BasicDrawDevice();\n\tval = tTJSVariant(dsp);\n\tdsp->Release();\n\twindowclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER,\n\t\tTJS_W(\"BasicDrawDevice\"), NULL, &val, windowclass);\n\n\twindowclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER,\n\t\tTJS_W(\"PassThroughDrawDevice\"), NULL, &val, windowclass); // compatible for old version kr2\n\tREGISTER_OBJECT(MenuItem, TVPCreateNativeClass_MenuItem()); // register \"menu\" to windowclass\n\n\t// Add Extension Classes\n\tTVPCauseAtInstallExtensionClass( global );\n\n\t// Garbage Collection Hook\n\tTVPAddCompactEventHook(&TVPTJSGCCallback);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPUninitScriptEngine\n//---------------------------------------------------------------------------\nstatic bool TVPScriptEngineUninit = false;\nvoid TVPUninitScriptEngine()\n{\n\tif(TVPScriptEngineUninit) return;\n\tTVPScriptEngineUninit = true;\n\n\t//TVPScriptEngine->Shutdown();\n\tTVPScriptEngine->Release();\n\t/*\n\t\tObjects, theirs lives are contolled by reference counter, may not be all\n\t\tfreed here in some occations.\n\t*/\n\tTVPScriptEngine = NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPRestartScriptEngine\n//---------------------------------------------------------------------------\nvoid TVPRestartScriptEngine()\n{\n\tTVPUninitScriptEngine();\n\tTVPScriptEngineInit = false;\n\tTVPInitScriptEngine();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetScriptEngine\n//---------------------------------------------------------------------------\ntTJS * TVPGetScriptEngine()\n{\n\treturn TVPScriptEngine;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetScriptDispatch\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPGetScriptDispatch()\n{\n\tif(TVPScriptEngine) return TVPScriptEngine->GetGlobal(); else return NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPExecuteScript\n//---------------------------------------------------------------------------\nvoid TVPExecuteScript(const ttstr& content, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->ExecScript(content, result);\n\telse\n\t\tTVPThrowInternalError;\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteScript(const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->ExecScript(content, result, NULL, &name, lineofs);\n\telse\n\t\tTVPThrowInternalError;\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteScript(const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->ExecScript(content, result, context);\n\telse\n\t\tTVPThrowInternalError;\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteScript(const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->ExecScript(content, result, context, &name, lineofs);\n\telse\n\t\tTVPThrowInternalError;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPExecuteExpression\n//---------------------------------------------------------------------------\nvoid TVPExecuteExpression(const ttstr& content, tTJSVariant *result)\n{\n\tTVPExecuteExpression(content, NULL, result);\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteExpression(const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result)\n{\n\tTVPExecuteExpression(content, name, lineofs, NULL, result);\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteExpression(const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t{\n\t\tiTJSConsoleOutput *output = TVPScriptEngine->GetConsoleOutput();\n\t\tTVPScriptEngine->SetConsoleOutput(NULL); // once set TJS console to null\n\t\ttry\n\t\t{\n\t\t\tTVPScriptEngine->EvalExpression(content, result, context);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPScriptEngine->SetConsoleOutput(output);\n\t\t\tthrow;\n\t\t}\n\t\tTVPScriptEngine->SetConsoleOutput(output);\n\t}\n\telse\n\t{\n\t\tTVPThrowInternalError;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteExpression(const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result)\n{\n\tif(TVPScriptEngine)\n\t{\n\t\tiTJSConsoleOutput *output = TVPScriptEngine->GetConsoleOutput();\n\t\tTVPScriptEngine->SetConsoleOutput(NULL); // once set TJS console to null\n\t\ttry\n\t\t{\n\t\t\tTVPScriptEngine->EvalExpression(content, result, context, &name, lineofs);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPScriptEngine->SetConsoleOutput(output);\n\t\t\tthrow;\n\t\t}\n\t\tTVPScriptEngine->SetConsoleOutput(output);\n\t}\n\telse\n\t{\n\t\tTVPThrowInternalError;\n\t}\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// TVPExecuteBytecode\n//---------------------------------------------------------------------------\nvoid TVPExecuteBytecode( const tjs_uint8* content, size_t len, iTJSDispatch2 *context, tTJSVariant *result, const tjs_char *name )\n{\n\tif(!TVPScriptEngine) TVPThrowInternalError;\n\n\tTVPScriptEngine->LoadByteCode( content, len, result, context, name);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TVPExecuteStorage(const ttstr &name, tTJSVariant *result, bool isexpression,\n\tconst tjs_char * modestr)\n{\n\tTVPExecuteStorage(name, NULL, result, isexpression, modestr);\n}\n//---------------------------------------------------------------------------\nvoid TVPExecuteStorage(const ttstr &name, iTJSDispatch2 *context, tTJSVariant *result, bool isexpression,\n\tconst tjs_char * modestr)\n{\n\t// execute storage which contains script\n\tif(!TVPScriptEngine) TVPThrowInternalError;\n\t\n\t{ // for bytecode\n\t\tttstr place(TVPSearchPlacedPath(name));\n\t\tttstr shortname(TVPExtractStorageName(place));\n\t\ttTJSBinaryStream* stream = TVPCreateBinaryStreamForRead(place, modestr);\n\t\tif( stream ) {\n\t\t\tbool isbytecode = false;\n\t\t\ttry {\n\t\t\t\tisbytecode = TVPScriptEngine->LoadByteCode( stream, result, context, shortname.c_str() );\n\t\t\t} catch(...) {\n\t\t\t\tdelete stream;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete stream;\n\t\t\tif( isbytecode ) return;\n\t\t}\n\t}\n\n\tttstr place(TVPSearchPlacedPath(name));\n\tttstr shortname(TVPExtractStorageName(place));\n\n\tiTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, modestr);\n\tttstr buffer;\n\ttry\n\t{\n\t\tstream->Read(buffer, 0);\n\t}\n\tcatch(...)\n\t{\n\t\tstream->Destruct();\n\t\tthrow;\n\t}\n\tstream->Destruct();\n\n\tif(TVPScriptEngine)\n\t{\n\t\tif(!isexpression)\n\t\t\tTVPScriptEngine->ExecScript(buffer, result, context,\n\t\t\t\t&shortname);\n\t\telse\n\t\t\tTVPScriptEngine->EvalExpression(buffer, result, context,\n\t\t\t\t&shortname);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPCompileStorage( const ttstr& name, bool isrequestresult, bool outputdebug, bool isexpression, const ttstr& outputpath ) {\n\t// execute storage which contains script\n\tif(!TVPScriptEngine) TVPThrowInternalError;\n\n\tttstr place(TVPSearchPlacedPath(name));\n\tttstr shortname(TVPExtractStorageName(place));\n\tiTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, TJS_W(\"\"));\n\n\tttstr buffer;\n\ttry {\n\t\tstream->Read(buffer, 0);\n\t} catch(...) {\n\t\tstream->Destruct();\n\t\tthrow;\n\t}\n\tstream->Destruct();\n\n\ttTJSBinaryStream* outputstream = TVPCreateStream(outputpath, TJS_BS_WRITE);\n\tif(TVPScriptEngine) {\n\t\ttry {\n\t\t\tTVPScriptEngine->CompileScript( buffer.c_str(), outputstream, isrequestresult, outputdebug, isexpression, name.c_str(), 0 );\n\t\t} catch(...) {\n\t\t\tdelete outputstream;\n\t\t\tthrow;\n\t\t}\n\t}\n\tdelete outputstream;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPCreateMessageMapFile\n//---------------------------------------------------------------------------\nvoid TVPCreateMessageMapFile(const ttstr &filename)\n{\n#ifdef TJS_TEXT_OUT_CRLF\n\tttstr script(TJS_W(\"{\\r\\n\\tvar r = System.assignMessage;\\r\\n\"));\n#else\n\tttstr script(TJS_W(\"{\\n\\tvar r = System.assignMessage;\\n\"));\n#endif\n\n\tscript += TJSCreateMessageMapString();\n\n\tscript += TJS_W(\"}\");\n\n\tiTJSTextWriteStream * stream = TVPCreateTextStreamForWrite(\n\t\tfilename, TJS_W(\"\"));\n\ttry\n\t{\n\t\tstream->Write(script);\n\t}\n\tcatch(...)\n\t{\n\t\tstream->Destruct();\n\t\tthrow;\n\t}\n\n\tstream->Destruct();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDumpScriptEngine\n//---------------------------------------------------------------------------\nvoid TVPDumpScriptEngine()\n{\n\tTVPTJS2StartDump();\n\tTVPScriptEngine->SetConsoleOutput(TVPGetTJS2DumpOutputGateway());\n\ttry\n\t{\n\t\tTVPScriptEngine->Dump();\n\t}\n\tcatch(...)\n\t{\n\t\tTVPTJS2EndDump();\n\t\tTVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway());\n\t\tthrow;\n\t}\n\tTVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway());\n\tTVPTJS2EndDump();\n}\n//---------------------------------------------------------------------------\n\n\nbool TVPStartupSuccess = false;\nvoid TVPOpenPatchLibUrl();\n//---------------------------------------------------------------------------\n// TVPExecuteStartupScript\n//---------------------------------------------------------------------------\nvoid TVPExecuteStartupScript()\n{\n\tttstr strPatchError;\n    try {\n        ttstr patch = TVPGetAppPath() + \"patch.tjs\";\n        if(TVPIsExistentStorageNoSearch(patch))\n\t\t\tTVPExecuteStorage(patch);\n\t} catch (const TJS::eTJSScriptError &e) {\n\t\tttstr &msg = strPatchError;\n\t\tmsg += e.GetMessage();\n\t\tconst tjs_char *pszBlockName = e.GetBlockName();\n\t\tif (pszBlockName && *pszBlockName) {\n\t\t\tmsg += TJS_W(\"\\n@line(\");\n\t\t\ttjs_char tmp[34];\n\t\t\tmsg += TJS_int_to_str(e.GetSourceLine(), tmp);\n\t\t\tmsg += TJS_W(\") \");\n\t\t\tmsg += pszBlockName;\n\t\t}\n\t\tmsg += TJS_W(\"\\n\");\n\t\tmsg += e.GetTrace();\n\t} catch (const TJS::eTJS &e) {\n\t\tif (!TVPSystemUninitCalled)\n\t\t\tstrPatchError = e.GetMessage();\n\t} catch (const std::exception &e) {\n\t\tstrPatchError = e.what();\n\t} catch (const char* e) {\n\t\tstrPatchError = e;\n\t} catch (const tjs_char* e) {\n\t\tstrPatchError = e;\n\t}\n\n\tif (!strPatchError.IsEmpty()) {\n\t\tttstr msg = LocaleConfigManager::GetInstance()->GetText(\"startup_patch_fail\");\n\t\tmsg += \"\\n\";\n\t\tmsg += strPatchError;\n\t\tstd::vector<ttstr> btns;\n\t\tbtns.emplace_back(LocaleConfigManager::GetInstance()->GetText(\"msgbox_ok\"));\n\t\tbtns.emplace_back(LocaleConfigManager::GetInstance()->GetText(\"browse_patch_lib\"));\n\t\tif (TVPShowSimpleMessageBox(msg, TVPGetPackageVersionString(), btns) == 1) {\n\t\t\tTVPOpenPatchLibUrl();\n\t\t}\n\t}\n\n\t// execute \"startup.tjs\"\n// \ttry\n// \t{\n\t\ttry\n\t\t{\n\n            ttstr place(TVPSearchPlacedPath(TVPStartupScriptName));\n            TVPAddLog(TJS_W(\"(info) Loading startup script : \") + place);\n\t\t\tTVPStartupSuccess = false;\n            try {\n                iTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, \"\");\n                stream->Destruct();\n                TVPExecuteStorage(TVPStartupScriptName);\n\t\t\t\tTVPStartupSuccess = true;\n            }\n            catch (...)\n            {\n\t\t\t\tif (!TVPIsExistentStorage(TJS_W(\"System/Initialize.tjs\"))) {\n\t\t\t\t\tthrow;\n\t\t\t\t}\n            }\n\t\t\tif (TVPStartupSuccess) {\n            } else {\n                // try direct execute initialize.tjs to compatible for some patch\n                TVPExecuteStorage(TJS_W(\"System/Initialize.tjs\"));\n\t\t\t\tTVPStartupSuccess = true;\n            }\n\t\t\tTVPAddLog(TJS_W(\"(info) Startup script ended.\"));\n\t\t\ttry {\n\t\t\t\tttstr patch = TVPGetAppPath() + \"AfterStartup.tjs\";\n\t\t\t\tif (TVPIsExistentStorageNoSearch(patch))\n\t\t\t\t\tTVPExecuteStorage(patch);\n\t\t\t}\n\t\t\tcatch (...) {}\n\t\t}\n\t\tTJS_CONVERT_TO_TJS_EXCEPTION\n\t//}\n\t//TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W(\"startup\"))\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// unhandled exception handler related\n//---------------------------------------------------------------------------\nstatic bool  TJSGetSystem_exceptionHandler_Object(tTJSVariantClosure & dest)\n{\n\t// get System.exceptionHandler\n\tiTJSDispatch2 * global = TVPGetScriptEngine()->GetGlobalNoAddRef();\n\tif(!global) return false;\n\n\ttTJSVariant val;\n\ttTJSVariant val2;\n\ttTJSVariantClosure clo;\n\n\ttjs_error er;\n\ter = global->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"System\"), NULL, &val, global);\n\tif(TJS_FAILED(er)) return false;\n\n\tif(val.Type() != tvtObject) return false;\n\n\tclo = val.AsObjectClosureNoAddRef();\n\n\tif(clo.Object == NULL) return false;\n\n\tclo.PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"exceptionHandler\"), NULL, &val2, NULL);\n\n\tif(val2.Type() != tvtObject) return false;\n\n\tdest = val2.AsObjectClosure();\n\n\tif(!dest.Object)\n\t{\n\t\tdest.Release();\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool TVPProcessUnhandledException(eTJSScriptException &e)\n{\n\tbool result;\n\ttTJSVariantClosure clo;\n\tclo.Object = clo.ObjThis = NULL;\n\n\ttry\n\t{\n\t\t// get the script engine\n\t\ttTJS *engine = TVPGetScriptEngine();\n\t\tif(!engine)\n\t\t\treturn false; // the script engine had been shutdown\n\n\t\t// get System.exceptionHandler\n\t\tif(!TJSGetSystem_exceptionHandler_Object(clo))\n\t\t\treturn false; // System.exceptionHandler cannot be retrieved\n\n\t\t// execute clo\n\t\ttTJSVariant obj(e.GetValue());\n\n\t\ttTJSVariant *pval[] =  { &obj };\n\n\t\ttTJSVariant res;\n\n\t\tclo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL);\n\n\t\tresult = res.operator bool();\n\t}\n\tcatch(eTJSScriptError &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(eTJS &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\n\treturn result;\n}\n//---------------------------------------------------------------------------\nbool TVPProcessUnhandledException(eTJSScriptError &e)\n{\n\tbool result;\n\ttTJSVariantClosure clo;\n\tclo.Object = clo.ObjThis = NULL;\n\n\ttry\n\t{\n\t\t// get the script engine\n\t\ttTJS *engine = TVPGetScriptEngine();\n\t\tif(!engine)\n\t\t\treturn false; // the script engine had been shutdown\n\n\t\t// get System.exceptionHandler\n\t\tif(!TJSGetSystem_exceptionHandler_Object(clo))\n\t\t\treturn false; // System.exceptionHandler cannot be retrieved\n\n\t\t// execute clo\n\t\ttTJSVariant obj;\n\t\ttTJSVariant msg(e.GetMessage());\n\t\ttTJSVariant trace(e.GetTrace());\n\t\tTJSGetExceptionObject(engine, &obj, msg, &trace);\n\n\t\ttTJSVariant *pval[] =  { &obj };\n\n\t\ttTJSVariant res;\n\n\t\tclo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL);\n\n\t\tresult = res.operator bool();\n\t}\n\tcatch(eTJSScriptError &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(eTJS &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\n\treturn result;\n}\n//---------------------------------------------------------------------------\nbool TVPProcessUnhandledException(eTJS &e)\n{\n\tbool result;\n\ttTJSVariantClosure clo;\n\tclo.Object = clo.ObjThis = NULL;\n\n\ttry\n\t{\n\t\t// get the script engine\n\t\ttTJS *engine = TVPGetScriptEngine();\n\t\tif(!engine)\n\t\t\treturn false; // the script engine had been shutdown\n\n\t\t// get System.exceptionHandler\n\t\tif(!TJSGetSystem_exceptionHandler_Object(clo))\n\t\t\treturn false; // System.exceptionHandler cannot be retrieved\n\n\t\t// execute clo\n\t\ttTJSVariant obj;\n\t\ttTJSVariant msg(e.GetMessage());\n\t\tTJSGetExceptionObject(engine, &obj, msg);\n\n\t\ttTJSVariant *pval[] =  { &obj };\n\n\t\ttTJSVariant res;\n\n\t\tclo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL);\n\n\t\tresult = res.operator bool();\n\t}\n\tcatch(eTJSScriptError &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(eTJS &e)\n\t{\n\t\tclo.Release();\n\t\tTVPShowScriptException(e);\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\n\treturn result;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid TVPStartObjectHashMap()\n{\n\t// addref ObjectHashMap if the program is being debugged.\n\tif(TJSEnableDebugMode)\n\t\tTJSAddRefObjectHashMap();\n}\n\n//---------------------------------------------------------------------------\n// TVPBeforeProcessUnhandledException\n//---------------------------------------------------------------------------\nvoid TVPBeforeProcessUnhandledException()\n{\n\tTVPDumpHWException();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPShowScriptException\n//---------------------------------------------------------------------------\n/*\n\tThese functions display the error location, reason, etc.\n\tAnd disable the script event dispatching to avoid massive occurrence of\n\terrors.\n*/\nextern ttstr TVPGetErrorDialogTitle();\n//---------------------------------------------------------------------------\nvoid TVPShowScriptException(eTJS &e)\n{\n\tTVPSetSystemEventDisabledState(true);\n\tTVPOnError();\n\n\tif(!TVPSystemUninitCalled)\n\t{\n\t\tttstr errstr = (ttstr(TVPScriptExceptionRaised) + TJS_W(\"\\n\") + e.GetMessage());\n\t\tTVPAddLog(ttstr(TVPScriptExceptionRaised) + TJS_W(\"\\n\") + e.GetMessage());\n\t\tTVPShowSimpleMessageBox(errstr, TVPGetErrorDialogTitle());\n\t\t//Application->MessageDlg( errstr.AsStdString(), std::wstring(), mtError, mbOK );\n\t\tTVPTerminateSync(1);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPShowScriptException(eTJSScriptError &e)\n{\n\tTVPSetSystemEventDisabledState(true);\n\tTVPOnError();\n\n\tif(!TVPSystemUninitCalled)\n\t{\n\t\tttstr errstr = (ttstr(TVPScriptExceptionRaised) + TJS_W(\"\\n\") + e.GetMessage());\n\t\tTVPAddLog(ttstr(TVPScriptExceptionRaised) + TJS_W(\"\\n\") + e.GetMessage());\n\t\tif(e.GetTrace().GetLen() != 0)\n\t\t\tTVPAddLog(ttstr(TJS_W(\"trace : \")) + e.GetTrace());\n\t\tTVPShowSimpleMessageBox(errstr, TVPGetErrorDialogTitle());\n\t//\tApplication->MessageDlg( errstr.AsStdString(), Application->GetTitle(), mtStop, mbOK );\n\n#ifdef TVP_ENABLE_EXECUTE_AT_EXCEPTION\n\t\tconst tjs_char* scriptName = e.GetBlockNoAddRef()->GetName();\n\t\tif( scriptName != NULL && scriptName[0] != 0 ) {\n\t\t\tttstr path(scriptName);\n\t\t\ttry {\n\t\t\t\tttstr newpath = TVPGetPlacedPath(path);\n\t\t\t\tif( newpath.IsEmpty() ) {\n\t\t\t\t\tpath = TVPNormalizeStorageName(path);\n\t\t\t\t} else {\n\t\t\t\t\tpath = newpath;\n\t\t\t\t}\n\t\t\t\tTVPGetLocalName( path );\n\t\t\t\tstd::wstring scriptPath( path.AsStdString() );\n\t\t\t\ttjs_int lineno = 1+e.GetBlockNoAddRef()->SrcPosToLine(e.GetPosition() )- e.GetBlockNoAddRef()->GetLineOffset();\n\n#if defined(WIN32) && defined(_DEBUG) && !defined(ENABLE_DEBUGGER)\n// fobKsĂ鎞AVisual Studio ōsWv鎞̎wfobOo͂ɏoāAbreak Œ~\n\t\t\t\tif( ::IsDebuggerPresent() ) {\n\t\t\t\t\tstd::wstring debuglile( std::wstring(L\"2>\")+path.AsStdString()+L\"(\"+std::to_wstring(lineno)+L\"): error :\" + errstr.AsStdString() );\n\t\t\t\t\t::OutputDebugString( debuglile.c_str() );\n\t\t\t\t\t//  breakŒ~AȌo͍s_uNbN΁AOӏ̃XNvgVisual StudioŊJ\n\t\t\t\t\t::DebugBreak();\n\t\t\t\t}\n#endif\n\t\t\t\tscriptPath = std::wstring(L\"\\\"\") + scriptPath + std::wstring(L\"\\\"\");\n\t\t\t\ttTJSVariant val;\n\t\t\t\tif( TVPGetCommandLine(TJS_W(\"-exceptionexe\"), &val) )\n\t\t\t\t{\n\t\t\t\t\tttstr exepath(val);\n\t\t\t\t\t//exepath = ttstr(TJS_W(\"\\\"\")) + exepath + ttstr(TJS_W(\"\\\"\"));\n\t\t\t\t\tif( TVPGetCommandLine(TJS_W(\"-exceptionarg\"), &val) )\n\t\t\t\t\t{\n\t\t\t\t\t\tttstr arg(val);\n\t\t\t\t\t\tif( !exepath.IsEmpty() && !arg.IsEmpty() ) {\n\t\t\t\t\t\t\tstd::wstring str( arg.AsStdString() );\n\t\t\t\t\t\t\tstr = ApplicationSpecialPath::ReplaceStringAll( str, std::wstring(L\"%filepath%\"), scriptPath );\n\t\t\t\t\t\t\tstr = ApplicationSpecialPath::ReplaceStringAll( str, std::wstring(L\"%line%\"), std::to_wstring(lineno) );\n\t\t\t\t\t\t\t//exepath = exepath + ttstr(str);\n\t\t\t\t\t\t\t//_wsystem( exepath.c_str() );\n\t\t\t\t\t\t\targ = ttstr(str);\n\t\t\t\t\t\t\tTVPAddLog( ttstr(TJS_W(\"(execute) \"))+exepath+ttstr(TJS_W(\" \"))+arg);\n\t\t\t\t\t\t\tTVPShellExecute( exepath, arg );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch(...) {\n\t\t\t}\n\t\t}\n#endif\n\t\tTVPTerminateSync(1);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPInitializeStartupScript\n//---------------------------------------------------------------------------\nvoid TVPInitializeStartupScript()\n{\n\tTVPStartObjectHashMap();\n\n\tTVPExecuteStartupScript();\n\tif(TVPTerminateOnNoWindowStartup && TVPGetWindowCount() == 0 ) {\n\t\t// no window is created and main window is invisible\n\t\tApplication->Terminate();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Scripts\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Scripts::ClassID = -1;\ntTJSNC_Scripts::tTJSNC_Scripts() : inherited(TJS_W(\"Scripts\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Scripts)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Scripts)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Scripts)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/execStorage)\n{\n\t// execute script which stored in storage\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\n\tttstr modestr;\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\tmodestr = *param[1];\n\n\tiTJSDispatch2 *context = numparams >= 3 && param[2]->Type() != tvtVoid ? param[2]->AsObjectNoAddRef() : NULL;\n\t\n\tTVPExecuteStorage(name, context, result, false, modestr.c_str());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/execStorage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/evalStorage)\n{\n\t// execute expression which stored in storage\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\n\tttstr modestr;\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\tmodestr = *param[1];\n\n\tiTJSDispatch2 *context = numparams >= 3 && param[2]->Type() != tvtVoid ? param[2]->AsObjectNoAddRef() : NULL;\n\n\tTVPExecuteStorage(name, context, result, true, modestr.c_str());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/evalStorage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/compileStorage) // bytecode\n{\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\tttstr output = *param[1];\n\n\tbool isresult = false;\n\tif( numparams >= 3 && (tjs_int)*param[2] ) {\n\t\tisresult = true;\n\t}\n\n\tbool outputdebug = false;\n\tif( numparams >= 4 && (tjs_int)*param[3] ) {\n\t\toutputdebug = true;\n\t}\n\n\tbool isexpression = false;\n\tif( numparams >= 5 && (tjs_int)*param[4] ) {\n\t\tisexpression = true;\n\t}\n\tTVPCompileStorage( name, isresult, outputdebug, isexpression, output );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/compileStorage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exec)\n{\n\t// execute given string as a script\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr content = *param[0];\n\n\tttstr name;\n\ttjs_int lineofs = 0;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) name = *param[1];\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid) lineofs = *param[2];\n\n\tiTJSDispatch2 *context = numparams >= 4 && param[3]->Type() != tvtVoid ? param[3]->AsObjectNoAddRef() : NULL;\n\t\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->ExecScript(content, result, context,\n\t\t\t&name, lineofs);\n\telse\n\t\tTVPThrowInternalError;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/exec)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/eval)\n{\n\t// execute given string as a script\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr content = *param[0];\n\n\tttstr name;\n\ttjs_int lineofs = 0;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) name = *param[1];\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid) lineofs = *param[2];\n\n\tiTJSDispatch2 *context = numparams >= 4 && param[3]->Type() != tvtVoid ? param[3]->AsObjectNoAddRef() : NULL;\n\t\n\tif(TVPScriptEngine)\n\t\tTVPScriptEngine->EvalExpression(content, result, context,\n\t\t\t&name, lineofs);\n\telse\n\t\tTVPThrowInternalError;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/eval)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dump)\n{\n\t// execute given string as a script\n\tTVPDumpScriptEngine();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/dump)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTraceString)\n{\n\t// get current stack trace as string\n\ttjs_int limit = 0;\n\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tlimit = *param[0];\n\n\tif(result)\n\t{\n\t\t*result = TJSGetStackTraceString(limit);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getTraceString)\n//----------------------------------------------------------------------\n#ifdef TJS_DEBUG_DUMP_STRING\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dumpStringHeap)\n{\n\t// dump all strings held by TJS2 framework\n\tTJSDumpStringHeap();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/dumpStringHeap)\n#endif\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setCallMissing) /* UNDOCUMENTED: subject to change */\n{\n\t// set to call \"missing\" method\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tiTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef();\n\n\tif(dsp)\n\t{\n\t\ttTJSVariant missing(TJS_W(\"missing\"));\n\t\tdsp->ClassInstanceInfo(TJS_CII_SET_MISSING, 0, &missing);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/setCallMissing) /* UNDOCUMENTED: subject to change */\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getClassNames) /* UNDOCUMENTED: subject to change */\n{\n\t// get class name as an array, last (most end) class first.\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tiTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef();\n\n\tif(dsp)\n\t{\n\t\tiTJSDispatch2 * array =  TJSCreateArrayObject();\n\t\ttry\n\t\t{\n\t\t\ttjs_uint num = 0;\n\t\t\twhile(true)\n\t\t\t{\n\t\t\t\ttTJSVariant val;\n\t\t\t\ttjs_error err = dsp->ClassInstanceInfo(TJS_CII_GET, num, &val);\n\t\t\t\tif(TJS_FAILED(err)) break;\n\t\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE, num, &val, array);\n\t\t\t\tnum ++;\n\t\t\t}\n\t\t\tif(result) *result = tTJSVariant(array, array);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tarray->Release();\n\t\t\tthrow;\n\t\t}\n\t\tarray->Release();\n\t}\n\telse\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getClassNames) /* UNDOCUMENTED: subject to change */\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(textEncoding)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetDefaultReadEncoding();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPSetDefaultReadEncoding(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(textEncoding)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance * tTJSNC_Scripts::CreateNativeInstance()\n{\n\t// this class cannot create an instance\n\tTVPThrowExceptionMessage(TVPCannotCreateInstance);\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Scripts\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Scripts()\n{\n\ttTJSNC_Scripts *cls = new tTJSNC_Scripts();\n\n\t// setup some platform-specific members\n\n//----------------------------------------------------------------------\n\n// currently none\n\n//----------------------------------------------------------------------\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/base/ScriptMgnIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 Script Managing\n//---------------------------------------------------------------------------\n#ifndef ScriptMgnImtfH\n#define ScriptMgnImtfH\n\n#include \"tjs.h\"\n\n#include \"tjsNative.h\"\n#include \"tjsError.h\"\n\n//---------------------------------------------------------------------------\n// implementation in this unit\n//---------------------------------------------------------------------------\nextern ttstr TVPStartupScriptName;\n\n\nextern void TVPInitScriptEngine();\nextern void TVPUninitScriptEngine();\nextern void TVPRestartScriptEngine();\nextern tTJS*  TVPGetScriptEngine();\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TVPGetScriptDispatch, ());\nTJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, iTJSDispatch2 *context, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, const ttstr &name, tjs_int lineofs, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteStorage, (const ttstr &name, tTJSVariant *result = NULL,\n\tbool isexpression = false, const tjs_char *modestr = NULL));\nTJS_EXP_FUNC_DEF(void, TVPExecuteStorage, (const ttstr &name, iTJSDispatch2 *context, tTJSVariant *result = NULL,\n\tbool isexpression = false, const tjs_char *modestr = NULL));\nTJS_EXP_FUNC_DEF(void, TVPDumpScriptEngine, ());\n\nTJS_EXP_FUNC_DEF(void, TVPExecuteBytecode, (const tjs_uint8* content, size_t len, iTJSDispatch2 *context, tTJSVariant *result = NULL, const tjs_char *name = NULL ));\n\nextern void TVPExecuteStartupScript();\nTJS_EXP_FUNC_DEF(void, TVPCreateMessageMapFile, (const ttstr &filename));\n\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// implementation in each platform to show script exception message\n//---------------------------------------------------------------------------\nextern void TVPShowScriptException(eTJS &e);\nextern void TVPShowScriptException(eTJSScriptError &e);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPBeforeProcessUnhandledException (implementation in each platform)\n//---------------------------------------------------------------------------\nextern void TVPBeforeProcessUnhandledException();\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// unhandled exception handler related macros\n//---------------------------------------------------------------------------\nextern bool TVPProcessUnhandledException(eTJSScriptException &e);\nextern bool TVPProcessUnhandledException(eTJSScriptError &e);\nextern bool TVPProcessUnhandledException(eTJS &e);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPInitializeStartupScript\n//---------------------------------------------------------------------------\nextern void TVPInitializeStartupScript();\nextern bool TVPCheckProcessLog();\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// unhandled exception handler related macros\n//---------------------------------------------------------------------------\n#define TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(origin) \\\n\tcatch(eTJSScriptException &e) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\te.AddTrace(ttstr(origin)); \\\n\t\tif(!TVPProcessUnhandledException(e)) \\\n\t\t\tTVPShowScriptException(e); \\\n\t} \\\n\tcatch(eTJSScriptError &e) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\te.AddTrace(ttstr(origin)); \\\n\t\tif(!TVPProcessUnhandledException(e)) \\\n\t\t\tTVPShowScriptException(e); \\\n\t} \\\n\tcatch(eTJS &e) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\tif(!TVPProcessUnhandledException(e)) \\\n\t\t\tTVPShowScriptException(e); \\\n\t} \\\n\tcatch(...) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\tthrow; \\\n\t}\n#define TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION_FORCE_SHOW_EXCEPTION(origin) \\\n\tcatch(eTJSScriptError &e) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\te.AddTrace(ttstr(origin)); \\\n\t\tTVPShowScriptException(e); \\\n\t} \\\n\tcatch(eTJS &e) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\tTVPShowScriptException(e); \\\n\t} \\\n\tcatch(...) \\\n\t{ \\\n\t\tTVPBeforeProcessUnhandledException(); \\\n\t\tthrow; \\\n\t}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Scripts : TJS Scripts class\n//---------------------------------------------------------------------------\nclass tTJSNC_Scripts : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Scripts();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Scripts();\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/StorageIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Universal Storage System\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include <stdexcept>\n#include <memory>\n#include \"StorageIntf.h\"\n#include \"tjsUtils.h\"\n#include \"MsgIntf.h\"\n#include \"EventIntf.h\"\n#include \"DebugIntf.h\"\n#include \"tjsArray.h\"\n#include \"SysInitIntf.h\"\n#include \"XP3Archive.h\"\n#include \"TickCount.h\"\n\n\n\n#define TVP_DEFAULT_ARCHIVE_CACHE_NUM 64\n#define TVP_DEFAULT_AUTOPATH_CACHE_NUM 256\n\n\n\n//---------------------------------------------------------------------------\n// global variables\n//---------------------------------------------------------------------------\n// current media ( ex. \"http\" \"ftp\" \"file\" )\nttstr TVPCurrentMedia;\n// archive delimiter\n// this changes '>' from '#' since 2.19 beta 14\ntjs_char  TVPArchiveDelimiter = '>';\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// statics\n//---------------------------------------------------------------------------\nstatic tTJSStaticCriticalSection TVPCreateStreamCS;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// utilities\n//---------------------------------------------------------------------------\nttstr TVPStringFromBMPUnicode(const tjs_uint16 *src, tjs_int maxlen)\n{\n\t// convert to ttstr from BMP unicode\n\tif(sizeof(tjs_char) == 2)\n\t{\n\t\t// sizeof(tjs_char) is 2 (windows native)\n\t\tif(maxlen == -1)\n\t\t\treturn ttstr((const tjs_char*)src);\n\t\telse\n\t\t\treturn ttstr((const tjs_char*)src, maxlen);\n\t}\n\telse if(sizeof(tjs_char) == 4)\n\t{\n\t\t// sizeof(tjs_char) is 4 (UCS32)\n  \t\t// FIXME: NOT TESTED CODE\n\t\ttjs_int len = 0;\n\t\tconst tjs_uint16 *p = src;\n\t\twhile(*p) len++, p++;\n\t\tif(maxlen != -1 && len > maxlen) len = maxlen;\n\t\tttstr ret((tTJSStringBufferLength)(len));\n\t\ttjs_char *dest = ret.Independ();\n\t\tp = src;\n\t\twhile(len && *p)\n\t\t{\n\t\t\t*dest = *p;\n\t\t\tdest++;\n\t\t\tp++;\n\t\t\tlen --;\n\t\t}\n\t\t*dest = 0;\n\t\tret.FixLen();\n\t\treturn ret;\n\t}\n\treturn (const tjs_char*)TVPTjsCharMustBeTwoOrFour;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPStorageMediaManager\n//---------------------------------------------------------------------------\nclass tTVPStorageMediaManager\n{\n\tclass tMediaNameString : public tTJSString\n\t{\n\tpublic:\n\t\tbool operator == (const tMediaNameString &rhs) const\n\t\t{\n\t\t\tconst tjs_char * l_p = c_str();\n\t\t\tconst tjs_char * r_p = rhs.c_str();\n\n\t\t\twhile(*l_p && *r_p)\n\t\t\t{\n\t\t\t\tif(*l_p == TJS_W(':')) break;\n\t\t\t\tif(*r_p == TJS_W(':')) break;\n\t\t\t\tif(*l_p != *r_p) break;\n\t\t\t\tl_p++;\n\t\t\t\tr_p++;\n\t\t\t}\n\t\t\tif((*l_p == TJS_W(':') || *l_p == 0) &&\n\t\t\t\t(*r_p == TJS_W(':') || *r_p == 0)) return true;\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tclass tHashFunc\n\t{\n\tpublic:\n\t\tstatic tjs_uint32 Make(const tMediaNameString &key)\n\t\t{\n\t\t\tif(key.IsEmpty()) return 0;\n\t\t\tconst tjs_char *str = key.c_str();\n\t\t\ttjs_uint32 ret = 0;\n\t\t\twhile(*str && *str != ':')\n\t\t\t{\n\t\t\t\tret += *str;\n\t\t\t\tret += (ret << 10);\n\t\t\t\tret ^= (ret >> 6);\n\t\t\t\tstr++;\n\t\t\t}\n\t\t\tret += (ret << 3);\n\t\t\tret ^= (ret >> 11);\n\t\t\tret += (ret << 15);\n\t\t\tif(!ret) ret = (tjs_uint32)-1;\n\t\t\treturn ret;\n\t\t}\n\t};\n\n\tclass tMediaRecord\n\t{\n\tpublic:\n\t\tttstr CurrentDomain;\n\t\tttstr CurrentPath;\n\t\ttTJSRefHolder<iTVPStorageMedia> MediaIntf;\n\t\ttjs_int MediaNameLen;\n//\t\tbool IsCaseSensitive;\n\n\t\ttMediaRecord(iTVPStorageMedia *media) : MediaIntf(media), CurrentDomain(\".\"), CurrentPath(\"/\")\n\t\t\t{ ttstr name; media->GetName(name); MediaNameLen = name.GetLen();\n\t\t\t/*IsCaseSensitive = media->IsCaseSensitive();*/ }\n\n\t\tconst tjs_char *GetDomainAndPath(const ttstr &name)\n\t\t{\n\t\t\treturn name.c_str() + MediaNameLen + 3;\n\t\t\t\t// 3 = strlen(\"://\")\n\t\t}\n\t};\n\n\ttypedef tTJSHashTable<tMediaNameString, tMediaRecord, tHashFunc, 16> tHashTable;\n\n\ttHashTable HashTable;\n\npublic:\n\ttTVPStorageMediaManager();\n\t~tTVPStorageMediaManager();\n\nprivate:\n\tstatic void ThrowUnsupportedMediaType(const ttstr &name);\n\ttMediaRecord * GetMediaRecord(const ttstr &name);\n\npublic:\n\tvoid Register(iTVPStorageMedia * media);\n\tvoid Unregister(iTVPStorageMedia * media);\n\n\tttstr NormalizeStorageName(const ttstr &name, ttstr *ret_media = NULL,\n\t\tttstr *ret_domain = NULL, ttstr *ret_path = NULL);\n\n\tvoid SetCurrentDirectory(const ttstr &name);\n\n\tstatic ttstr ExtractMediaName(const ttstr &name);\n\n\tbool CheckExistentStorage(const ttstr & name);\n\ttTJSBinaryStream * Open(const ttstr & name, tjs_uint32 flags);\n\tvoid GetListAt(const ttstr &name, iTVPStorageLister *lister);\n\tttstr GetLocallyAccessibleName(const ttstr &name);\n} TVPStorageMediaManager;\n//---------------------------------------------------------------------------\ntTVPStorageMediaManager::tTVPStorageMediaManager()\n{\n\tiTVPStorageMedia *filemedia = TVPCreateFileMedia();\n\tRegister(filemedia);\n\tfilemedia->Release();\n}\n//---------------------------------------------------------------------------\ntTVPStorageMediaManager::~tTVPStorageMediaManager()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTVPStorageMediaManager::ThrowUnsupportedMediaType(const ttstr &name)\n{\n\tTVPThrowExceptionMessage(TVPUnsupportedMediaName, ExtractMediaName(name));\n}\n//---------------------------------------------------------------------------\ntTVPStorageMediaManager::tMediaRecord *\n\ttTVPStorageMediaManager::GetMediaRecord(const ttstr &name)\n{\n\ttMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&name);\n\tif(!rec) ThrowUnsupportedMediaType(name);\n\treturn rec;\n}\n//---------------------------------------------------------------------------\nvoid tTVPStorageMediaManager::Register(iTVPStorageMedia * media)\n{\n\tttstr medianame;\n\tmedia->GetName(medianame);\n\n\ttMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&medianame);\n\tif(rec)\n\t\tTVPThrowExceptionMessage( TVPMediaNameHadAlreadyBeenRegistered, medianame );\n\n\ttMediaRecord new_rec(media);\n\n\tHashTable.Add(*(tMediaNameString*)&medianame, new_rec);\n}\n//---------------------------------------------------------------------------\nvoid tTVPStorageMediaManager::Unregister(iTVPStorageMedia * media)\n{\n\tttstr medianame;\n\tmedia->GetName(medianame);\n\n\ttMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&medianame);\n\tif(!rec)\n\t\tTVPThrowExceptionMessage( TVPMediaNameIsNotRegistered, medianame );\n\tHashTable.Delete(*(tMediaNameString*)&medianame);\n}\n//---------------------------------------------------------------------------\nttstr tTVPStorageMediaManager::NormalizeStorageName(const ttstr &name,\n\tttstr *ret_media, ttstr *ret_domain, ttstr *ret_path)\n{\n\t// Normalize storage name.\n\n\t// storage name is basically in following form:\n\t// media://domain/path\n\n\t// media is sort of access method, like \"file\", \"http\" ...etc.\n\t// domain represents in which computer the data is.\n\t// path is where the data is in the computer.\n\n\t// empty check\n\tif(name.IsEmpty()) return name; // empty name is empty name\n\n\t// pre-normalize\n\tconst tjs_char *pca;//, *pcb, *pcc;\n\ttjs_char *pa, *pb, *pc;\n\n\tttstr tmp(name);\n\tTVPPreNormalizeStorageName(tmp);\n\n\t// unify path delimiter\n\tpa = tmp.Independ();\n\twhile(*pa)\n\t{\n\t\tif(*pa == TJS_W('\\\\')) *pa = TJS_W('/');\n\t\tpa++;\n\t}\n\n\t// save in-archive storage name and normalize it\n\tttstr inarchive_name;\n\tbool inarc_name_found = false;\n\tpca = tmp.c_str();\n\tpa = const_cast<tjs_char *>(TJS_strchr(pca, TVPArchiveDelimiter));\n\tif(pa)\n\t{\n\t\tinarchive_name = ttstr(pa + 1);\n\t\ttTVPArchive::NormalizeInArchiveStorageName(inarchive_name);\n\t\tinarc_name_found = true;\n\t\ttmp = ttstr(pca, (int)(pa - pca));\n\t}\n\tif(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPInvalidPathName, name);\n\n\n\t// split the name into media, domain, path\n\t// (and guess what component is omitted)\n\tttstr media, domain, path;\n\n\t// - find media name\n\t//   media name is: /^[A-Za-z]+:/\n\tpa = pb = tmp.Independ();\n\twhile(*pa)\n\t{\n\t\tif(!(\n\t\t\t(*pa >= TJS_W('A') && *pa <= TJS_W('Z')) ||\n\t\t\t(*pa >= TJS_W('a') && *pa <= TJS_W('z')) )) break;\n\t\tpa ++;\n\t}\n\n\tif(*pa == TJS_W(':'))\n\t{\n\t\t// media name found\n\t\tmedia = ttstr(pb, (int)(pa - pb));\n\t\tpa ++;\n\t}\n\telse\n\t{\n\t\tpa = pb;\n\t}\n\n\t// - find domain name\n\t// at this place, pa may point one of following:\n\t//  ///path        (domain is omitted)\n\t//  //domain/path  (none is omitted)\n\t//  /path          (domain is omitted)\n\t//  relative-path  (domain and current path are omitted)\n\n\tif(pa[0] == TJS_W('/'))\n\t{\n\t\tif(pa[1] == TJS_W('/'))\n\t\t{\n\t\t\tif(pa[2] == TJS_W('/'))\n\t\t\t{\n\t\t\t\t// slash count 3: domain is ommited\n\t\t\t\tpa += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// slash count 2: none is omitted\n\t\t\t\tpa += 2;\n\t\t\t\t// find '/' as a domain delimiter\n\t\t\t\tpc = TJS_strchr(pa, TJS_W('/'));\n\t\t\t\tif(!pc)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPInvalidPathName, name);\n\t\t\t\tdomain = ttstr(pa, (int)(pc - pa));\n\t\t\t\tpa = pc;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// slash count 1: domain is omitted\n\t\t\t;\n\t\t\t//\n\t\t}\n\t}\n\n\t// - get path name\n\tpath = pa;\n\n\t// supply omitted and normalize\n\tif(media.IsEmpty())\n\t{\n\t\tmedia = TVPCurrentMedia;\n\t}\n\telse\n\t{\n\t\t// normalize media name ( make them all small )\n\t\ttjs_char *p = media.Independ();\n\t\twhile(*p)\n\t\t{\n\t\t\tif(*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t\t*p += (TJS_W('a') - TJS_W('A'));\n\t\t\tp ++;\n\t\t}\n\t}\n\n\ttMediaRecord * mediarec = GetMediaRecord(media);\n\n\tif(domain.IsEmpty()) domain = mediarec->CurrentDomain;\n\tmediarec->MediaIntf.GetObjectNoAddRef()->NormalizeDomainName(domain);\n\n\tif(path.IsEmpty())\n\t{\n\t\tpath = TJS_W(\"/\");\n\t}\n\telse if(path.c_str()[0] != TJS_W('/'))\n\t{\n\t\tpath = mediarec->CurrentPath + path;\n\t}\n\tmediarec->MediaIntf.GetObjectNoAddRef()->NormalizePathName(path);\n\n\t// compress redudant path accesses\n\tif(inarc_name_found)\n\t{\n\t\ttjs_char tmp[2];\n\t\ttmp[0] = TVPArchiveDelimiter;\n\t\ttmp[1] = 0;\n\t\tpath += tmp + inarchive_name;\n\t}\n\n\tpa = pb = pc = path.Independ(); // pa = read pointer, pb = write pointer, pc = start\n\ttjs_int dot_count = -1;\n\n\twhile(true)\n\t{\n\t\tif(*pa == TVPArchiveDelimiter || *pa == TJS_W('/') || *pa == 0)\n\t\t{\n\t\t\ttjs_char delim = 0;\n\n\t\t\tif(*pa && dot_count == 0)\n\t\t\t{\n\t\t\t\t// duplicated slashes\n\t\t\t\tpb --;\n\t\t\t}\n\t\t\telse if(dot_count > 0)\n\t\t\t{\n\t\t\t\tpb --;\n\t\t\t\twhile(pb >= pc)\n\t\t\t\t{\n\t\t\t\t\tif(*pb == TJS_W('/') || *pb == TVPArchiveDelimiter)\n\t\t\t\t\t{\n\t\t\t\t\t\tdot_count --;\n\t\t\t\t\t\tif(dot_count == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdelim = *pb;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(*pb == TVPArchiveDelimiter) TVPThrowExceptionMessage(TVPInvalidPathName, name);\n\t\t\t\t\t}\n\t\t\t\t\tpb --;\n\t\t\t\t}\n\t\t\t\tif(pb < pc) TVPThrowExceptionMessage(TVPInvalidPathName, name);\n\t\t\t}\n\n\t\t\tif(!delim)\n\t\t\t\t*pb = *pa;\n\t\t\telse\n\t\t\t\t*pb = delim;\n\t\t\tif(*pa == 0) break;\n\t\t\tpb ++;\n\t\t\tpa ++;\n\t\t\tdot_count = 0;\n\t\t}\n\t\telse if(*pa == TJS_W('.'))\n\t\t{\n\t\t\t*(pb++) = *(pa++);\n\t\t\tif(dot_count != -1) dot_count ++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*(pb++) = *(pa++);\n\t\t\tdot_count = -1;\n\t\t}\n\t}\n\n\tpath.FixLen();\n\n\t// merge and return normalize storage name\n\tif(ret_media) *ret_media = media;\n\tif(ret_domain) *ret_domain = domain;\n\tif(ret_path) *ret_path = path;\n\n\ttmp = media + TJS_W(\"://\") + domain + path;\n\n\treturn tmp;\n}\n//---------------------------------------------------------------------------\nvoid tTVPStorageMediaManager::SetCurrentDirectory(const ttstr &name)\n{\n\ttjs_char ch = name.GetLastChar();\n\tif(ch != TJS_W('/') && ch != TJS_W('\\\\') && ch != TVPArchiveDelimiter)\n\t\tTVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast);\n\n\tttstr media, domain, path;\n\tNormalizeStorageName(name, &media, &domain, &path);\n\n\ttMediaRecord *rec = GetMediaRecord(media);\n\trec->CurrentDomain = domain;\n\trec->CurrentPath = path;\n\tTVPCurrentMedia = media;\n}\n//---------------------------------------------------------------------------\nttstr tTVPStorageMediaManager::ExtractMediaName(const ttstr &name)\n{\n\t// extract media name from normalized storage named \"name\".\n\t// returned media name does not contain colon.\n\n\tconst tjs_char * p = name.c_str();\n\tconst tjs_char * po = p;\n\twhile(*p && *p != TJS_W(':')) p++;\n\treturn ttstr(po, (int)(p - po));\n}\n//---------------------------------------------------------------------------\nbool tTVPStorageMediaManager::CheckExistentStorage(const ttstr & name)\n{\n\t// gateway for CheckExistentStorage\n\t// name must not be an in-archive storage name\n\ttMediaRecord *rec = GetMediaRecord(name);\n\treturn rec->MediaIntf.GetObjectNoAddRef()->CheckExistentStorage(rec->GetDomainAndPath(name));\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * tTVPStorageMediaManager::Open(const ttstr & name, tjs_uint32 flags)\n{\n\t// gateway for Open\n\t// name must not be an in-archive storage name\n\ttMediaRecord *rec = GetMediaRecord(name);\n\treturn rec->MediaIntf.GetObjectNoAddRef()->Open(rec->GetDomainAndPath(name), flags);\n}\n//---------------------------------------------------------------------------\nvoid tTVPStorageMediaManager::GetListAt(const ttstr &name, iTVPStorageLister * lister)\n{\n\t// gateway for GetListAt\n\t// name must not be an in-archive storage name\n\ttMediaRecord *rec = GetMediaRecord(name);\n\t/*return */rec->MediaIntf.GetObjectNoAddRef()->GetListAt(rec->GetDomainAndPath(name), lister);\n}\n//---------------------------------------------------------------------------\nttstr tTVPStorageMediaManager::GetLocallyAccessibleName(const ttstr &name)\n{\n\t// gateway for GetLocallyAccessibleName\n\t// name must not be an in-archive storage name\n\ttMediaRecord *rec = GetMediaRecord(name);\n\tttstr dname = rec->GetDomainAndPath(name);\n\trec->MediaIntf.GetObjectNoAddRef()->GetLocallyAccessibleName(dname);\n\treturn dname;\n}\n//---------------------------------------------------------------------------\nvoid TVPGetListAt(const ttstr &name, iTVPStorageLister * lister) {\n\tTVPStorageMediaManager.GetListAt(name, lister);\n}\n\n//---------------------------------------------------------------------------\nvoid TVPRegisterStorageMedia(iTVPStorageMedia *media)\n{\n\tTVPStorageMediaManager.Register(media);\n}\n//---------------------------------------------------------------------------\nvoid TVPUnregisterStorageMedia(iTVPStorageMedia *media)\n{\n\tTVPStorageMediaManager.Unregister(media);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPNormalizeStorgeName : storage name normalization\n//---------------------------------------------------------------------------\nttstr TVPNormalizeStorageName(const ttstr & _name)\n\t// TODO: check what is done in TVPNormalizeStorageName\n{\n\treturn TVPStorageMediaManager.NormalizeStorageName(_name);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSetCurrentDirectory\n//---------------------------------------------------------------------------\nvoid TVPSetCurrentDirectory(const ttstr & _name)\n{\n\tTVPStorageMediaManager.SetCurrentDirectory(_name);\n\tTVPClearStorageCaches();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetLocalName and TVPGetLocallyAccessibleName\n//---------------------------------------------------------------------------\nvoid TVPGetLocalName(ttstr &name)\n{\n\tttstr tmp = TVPGetLocallyAccessibleName(name);\n\tif(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPCannotGetLocalName, name);\n\tname = tmp;\n}\n//---------------------------------------------------------------------------\nttstr TVPGetLocallyAccessibleName(const ttstr &name)\n{\n\tif(TJS_strchr(name.c_str(), TVPArchiveDelimiter)) return TJS_W(\"\");\n\t\t // in-archive storage is always not accessible from local file system\n\treturn TVPStorageMediaManager.GetLocallyAccessibleName(name);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPArchive\n//---------------------------------------------------------------------------\nvoid tTVPArchive::NormalizeInArchiveStorageName(ttstr & name)\n{\n\t// normalization of in-archive storage name does :\n\tif(name.IsEmpty()) return;\n\n\t// make all characters small\n\t// change '\\\\' to '/'\n\ttjs_char *ptr = name.Independ();\n\twhile(*ptr)\n\t{\n\t\tif(*ptr >= TJS_W('A') && *ptr <= TJS_W('Z'))\n\t\t\t*ptr += TJS_W('a') - TJS_W('A');\n\t\telse if(*ptr == TJS_W('\\\\'))\n\t\t\t*ptr = TJS_W('/');\n\t\tptr++;\n\t}\n\n\t// eliminate duplicated slashes\n\tptr = name.Independ();\n\ttjs_char *org_ptr = ptr;\n\ttjs_char *dest = ptr;\n\twhile(*ptr)\n\t{\n\t\tif(*ptr != TJS_W('/'))\n\t\t{\n\t\t\t*dest = *ptr;\n\t\t\tptr ++;\n\t\t\tdest ++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(ptr != org_ptr)\n\t\t\t{\n\t\t\t\t*dest = *ptr;\n\t\t\t\tptr ++;\n\t\t\t\tdest ++;\n\t\t\t}\n\t\t\twhile(*ptr == TJS_W('/')) ptr++;\n\t\t}\n\t}\n\t*dest = 0;\n\n\tname.FixLen();\n}\n//---------------------------------------------------------------------------\nvoid tTVPArchive::AddToHash()\n{\n\t// enter all names to the hash table\n\ttjs_uint Count = GetCount();\n\ttjs_uint i;\n\tfor(i = 0; i < Count; i++)\n\t{\n\t\tttstr name = GetName(i);\n\t\tNormalizeInArchiveStorageName(name);\n\t\tHash.Add(name, i);\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * tTVPArchive::CreateStream(const ttstr & name)\n{\n\tif(name.IsEmpty()) return NULL;\n\n\tif(!Init)\n\t{\n\t\tInit = true;\n\t\tAddToHash();\n\t}\n\n\ttjs_uint *p = Hash.Find(name);\n\tif(!p) TVPThrowExceptionMessage(TVPStorageInArchiveNotFound,\n\t\tname, ArchiveName);\n\n\treturn CreateStreamByIndex(*p);\n}\n//---------------------------------------------------------------------------\nbool tTVPArchive::IsExistent(const ttstr & name)\n{\n\tif(name.IsEmpty()) return false;\n\n\tif(!Init)\n\t{\n\t\tInit = true;\n\t\tAddToHash();\n\t}\n\n\treturn Hash.Find(name) != NULL;\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPArchive::GetFirstIndexStartsWith(const ttstr & prefix)\n{\n\t// returns first index which have 'prefix' at start of the name.\n\t// returns -1 if the target is not found.\n\t// the item must be sorted by ttstr::operator < , otherwise this function\n\t// will not work propertly.\n\ttjs_uint total_count = GetCount();\n\ttjs_int s = 0, e = total_count;\n\twhile(e - s > 1)\n\t{\n\t\ttjs_int m = (e + s) / 2;\n\t\tif(!(GetName(m) < prefix))\n\t\t{\n\t\t\t// m is after or at the target\n\t\t\te = m;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// m is before the target\n\t\t\ts = m;\n\t\t}\n\t}\n\n\t// at this point, s or s+1 should point the target.\n\t// be certain.\n\tif(s >= (tjs_int)total_count) return -1; // out of the index\n\tif(GetName(s).StartsWith(prefix)) return s;\n\ts++;\n\tif(s >= (tjs_int)total_count) return -1; // out of the index\n\tif(GetName(s).StartsWith(prefix)) return s;\n\treturn -1;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPArchiveCache\n//---------------------------------------------------------------------------\nclass tTVPArchiveCache\n{\n\ttypedef tTJSRefHolder<tTVPArchive> tHolder;\n\ttTJSHashCache<ttstr, tHolder> ArchiveCache;\n\ttTJSCriticalSection CS;\n\n\npublic:\n\ttTVPArchiveCache() : ArchiveCache(TVP_DEFAULT_ARCHIVE_CACHE_NUM)\n\t{\n\t}\n\n\t~tTVPArchiveCache()\n\t{\n\t}\n\n\tvoid SetMaxCount(tjs_int maxcount)\n\t{\n\t\tArchiveCache.SetMaxCount(maxcount);\n\t}\n\n\tvoid Clear()\n\t{\n\t\t// releases all elements\n\t\tArchiveCache.Clear();\n\t}\n\n\ttTVPArchive * Get(ttstr name)\n\t{\n\t\tname = TVPNormalizeStorageName(name);\n\t\ttTJSCSH csh(CS);\n\t\ttjs_uint32 hash = tTJSHashCache<ttstr, tHolder>::MakeHash(name);\n\t\ttHolder *ptr = ArchiveCache.FindAndTouchWithHash(name, hash);\n\t\tif(ptr)\n\t\t{\n\t\t\t// exist in the cache\n\t\t\treturn ptr->GetObject();\n\t\t}\n\n\t\tif(!TVPIsExistentStorageNoSearch(name))\n\t\t{\n\t\t\t// storage not found\n\t\t\tTVPThrowExceptionMessage(TVPCannotFindStorage, name);\n\t\t}\n\n\t\t// not exist in the cache\n\t\ttTVPArchive *arc = TVPOpenArchive(name, true);\n\t\ttHolder holder(arc);\n\t\tArchiveCache.AddWithHash(name, hash, holder);\n\t\treturn arc;\n\t}\n\nprivate:\n\n} TVPArchiveCache;\nstatic void TVPClearArchiveCache() { TVPArchiveCache.Clear(); }\nstatic tTVPAtExit TVPClearArchiveCacheAtExit\n\t(TVP_ATEXIT_PRI_SHUTDOWN, TVPClearArchiveCache);\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPIsExistentStorageNoSearch\n//---------------------------------------------------------------------------\nbool TVPIsExistentStorageNoSearchNoNormalize(const ttstr &name)\n{\n\t// does name contain > ?\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\tconst tjs_char * sharp_pos = TJS_strchr(name.c_str(), TVPArchiveDelimiter);\n\tif(sharp_pos)\n\t{\n\t\t// this storagename indicates a file in an archive\n\n\t\tttstr arcname(name, (int)(sharp_pos - name.c_str()));\n\n\t\ttTVPArchive *arc;\n\t\tarc = TVPArchiveCache.Get(arcname);\n\t\tbool ret;\n\t\ttry\n\t\t{\n\t\t\tttstr in_arc_name(sharp_pos + 1);\n\t\t\ttTVPArchive::NormalizeInArchiveStorageName(in_arc_name);\n\t\t\tret = arc->IsExistent(in_arc_name);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tarc->Release();\n\t\t\tthrow;\n\t\t}\n\t\tarc->Release();\n\t\treturn ret;\n\t}\n\n\treturn TVPStorageMediaManager.CheckExistentStorage(name);\n}\n//---------------------------------------------------------------------------\nbool TVPIsExistentStorageNoSearch(const ttstr &_name)\n{\n\treturn TVPIsExistentStorageNoSearchNoNormalize(TVPNormalizeStorageName(_name));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPExtractStorageExt\n//---------------------------------------------------------------------------\nttstr TVPExtractStorageExt(const ttstr & name)\n{\n\t// extract an extension from name.\n\t// returned string will contain extension delimiter ( '.' ), except for\n\t// missing extension of the input string.\n\t// ( returns null string when input string does not have an extension )\n\n\tconst tjs_char * s = name.c_str();\n\ttjs_int slen = name.GetLen();\n\tconst tjs_char * p = s + slen;\n\tp--;\n\twhile(p>=s)\n\t{\n\t\tif(*p == TJS_W('\\\\')) break;\n\t\tif(*p == TJS_W('/')) break;\n\t\tif(*p == TVPArchiveDelimiter) break;\n\t\tif(*p == TJS_W('.'))\n\t\t{\n\t\t\t// found extension delimiter\n\t\t\ttjs_int extlen = (tjs_int)(slen - ( p - s ));\n\t\t\treturn ttstr(p, extlen);\n\t\t}\n\n\t\tp--;\n\t}\n\n\t// not found\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPExtractStorageName\n//---------------------------------------------------------------------------\nttstr TVPExtractStorageName(const ttstr & name)\n{\n\t// extract \"name\"'s storage name ( excluding path ) and return it.\n\tconst tjs_char * s = name.c_str();\n\ttjs_int slen = name.GetLen();\n\tconst tjs_char * p = s + slen;\n\tp--;\n\twhile(p>=s)\n\t{\n\t\tif(*p == TJS_W('\\\\')) break;\n\t\tif(*p == TJS_W('/')) break;\n\t\tif(*p == TVPArchiveDelimiter) break;\n\n\t\tp--;\n\t}\n\n\tp++;\n\tif(p == s)\n\t\treturn name;\n\telse\n\t\treturn ttstr(p, (int)(slen - (p -s)));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPExtractStoragePath\n//---------------------------------------------------------------------------\nttstr TVPExtractStoragePath(const ttstr & name)\n{\n\t// extract \"name\"'s path ( including last delimiter ) and return it.\n\tconst tjs_char * s = name.c_str();\n\ttjs_int slen = name.GetLen();\n\tconst tjs_char * p = s + slen;\n\tp--;\n\twhile(p>=s)\n\t{\n\t\tif(*p == TJS_W('\\\\')) break;\n\t\tif(*p == TJS_W('/')) break;\n\t\tif(*p == TVPArchiveDelimiter) break;\n\n\t\tp--;\n\t}\n\n\tp++;\n\treturn ttstr(s, (int)(p-s));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPChopStorageExt\n//---------------------------------------------------------------------------\nextern ttstr TVPChopStorageExt(const ttstr & name)\n{\n\t// chop storage's extension and return it.\n\tconst tjs_char * s = name.c_str();\n\ttjs_int slen = name.GetLen();\n\tconst tjs_char * p = s + slen;\n\tp--;\n\twhile(p>=s)\n\t{\n\t\tif(*p == TJS_W('\\\\')) break;\n\t\tif(*p == TJS_W('/')) break;\n\t\tif(*p == TVPArchiveDelimiter) break;\n\t\tif(*p == TJS_W('.'))\n\t\t{\n\t\t\t// found extension delimiter\n\t\t\treturn ttstr(s, (int)(p-s));\n\t\t}\n\n\t\tp--;\n\t}\n\n\t// not found\n\treturn name;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Auto search path support\n//---------------------------------------------------------------------------\n#define TVP_AUTO_PATH_HASH_SIZE 1024\nstd::vector<ttstr> TVPAutoPathList;\ntTJSHashCache<ttstr, ttstr> TVPAutoPathCache(TVP_DEFAULT_AUTOPATH_CACHE_NUM);\ntTJSHashTable<ttstr, ttstr, tTJSHashFunc<ttstr>, TVP_AUTO_PATH_HASH_SIZE>\n\tTVPAutoPathTable;\nbool AutoPathTableInit = false;\n//---------------------------------------------------------------------------\nstatic void TVPClearAutoPathCache()\n{\n\tTVPAutoPathCache.Clear();\n\tTVPAutoPathTable.Clear();\n\tAutoPathTableInit = false;\n}\n//---------------------------------------------------------------------------\nstruct tTVPClearAutoPathCacheCallback : public tTVPCompactEventCallbackIntf\n{\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\tif(level >= TVP_COMPACT_LEVEL_DEACTIVATE)\n\t\t{\n\t\t\t// clear the auto search path cache on application deactivate\n\t\t\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\t\t\tTVPClearAutoPathCache();\n\t\t}\n\t}\n} static TVPClearAutoPathCacheCallback;\nstatic bool TVPClearAutoPathCacheCallbackInit = false;\n//---------------------------------------------------------------------------\nvoid TVPAddAutoPath(const ttstr & name)\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\ttjs_char lastchar = name.GetLastChar();\n\tif(lastchar != TVPArchiveDelimiter && lastchar != TJS_W('/') && lastchar != TJS_W('\\\\'))\n\t\tTVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast);\n\n\tttstr normalized = TVPNormalizeStorageName(name);\n\n\tstd::vector<ttstr>::iterator i =\n\t\tstd::find(TVPAutoPathList.begin(), TVPAutoPathList.end(), normalized);\n\tif(i == TVPAutoPathList.end())\n\t\tTVPAutoPathList.push_back(normalized);\n\n\tTVPClearAutoPathCache();\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveAutoPath(const ttstr &name)\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\ttjs_char lastchar = name.GetLastChar();\n\tif(lastchar != TVPArchiveDelimiter && lastchar != TJS_W('/') && lastchar != TJS_W('\\\\'))\n\t\tTVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast);\n\n\tttstr normalized = TVPNormalizeStorageName(name);\n\n\tstd::vector<ttstr>::iterator i =\n\t\tstd::find(TVPAutoPathList.begin(), TVPAutoPathList.end(), normalized);\n\tif(i != TVPAutoPathList.end())\n\t\tTVPAutoPathList.erase(i);\n\n\tTVPClearAutoPathCache();\n}\n//---------------------------------------------------------------------------\nstatic tjs_uint TVPRebuildAutoPathTable()\n{\n\t// rebuild auto path table\n\tif(AutoPathTableInit) return 0;\n\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\tTVPAutoPathTable.Clear();\n\n\ttjs_uint64 tick = TVPGetTickCount();\n \tTVPAddLog( (const tjs_char*)TVPInfoRebuildingAutoPath );\n\n\ttjs_uint totalcount = 0;\n\n\tstd::vector<ttstr>::iterator it;\n\tfor(it = TVPAutoPathList.begin(); it != TVPAutoPathList.end(); it++)\n\t{\n\t\tconst ttstr & path = *it;\n\t\ttjs_uint count = 0;\n\n\t\tconst tjs_char * sharp_pos = TJS_strchr(path.c_str(), TVPArchiveDelimiter);\n\t\tif(sharp_pos)\n\t\t{\n\t\t\t// this storagename indicates a file in an archive\n\n\t\t\tttstr arcname(path, (int)(sharp_pos - path.c_str()));\n\t\t\tttstr in_arc_name(sharp_pos + 1);\n\t\t\ttTVPArchive::NormalizeInArchiveStorageName(in_arc_name);\n\t\t\ttjs_int in_arc_name_len = in_arc_name.GetLen();\n\n\t\t\ttTVPArchive *arc;\n\t\t\tarc = TVPArchiveCache.Get(arcname);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttjs_uint storagecount = arc->GetCount();\n\n\t\t\t\t// get first index which the item has 'in_arc_name' as its start\n\t\t\t\t// of the string.\n\t\t\t\ttjs_int i = arc->GetFirstIndexStartsWith(in_arc_name);\n\t\t\t\tif(i != -1)\n\t\t\t\t{\n\t\t\t\t\tfor(; i < (tjs_int)storagecount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tttstr name = arc->GetName(i);\n\n\t\t\t\t\t\tif(name.StartsWith(in_arc_name))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!TJS_strchr(name.c_str() + in_arc_name_len, TJS_W('/')))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tttstr sname = TVPExtractStorageName(name);\n\t\t\t\t\t\t\t\tTVPAutoPathTable.Add(sname, path);\n\t\t\t\t\t\t\t\tcount ++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// no need to check more;\n\t\t\t\t\t\t\t// because the list is sorted by the name.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tarc->Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tarc->Release();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// normal folder\n\t\t\tclass tLister : public iTVPStorageLister\n\t\t\t{\n\t\t\tpublic:\n\t\t\t\tstd::vector<ttstr> list;\n\t\t\t\tvoid TJS_INTF_METHOD Add(const ttstr &file)\n\t\t\t\t{\n\t\t\t\t\tlist.push_back(file);\n\t\t\t\t}\n\t\t\t} lister;\n\n\t\t\tTVPStorageMediaManager.GetListAt(path, &lister);\n\t\t\tfor(std::vector<ttstr>::iterator i = lister.list.begin();\n\t\t\t\ti != lister.list.end(); i++)\n\t\t\t{\n\t\t\t\tTVPAutoPathTable.Add(*i, path);\n\t\t\t\tcount ++;\n\t\t\t}\n\t\t}\n\n//\t\tTVPAddLog(ttstr(TJS_W(\"(info) Path \")) + path + TJS_W(\" contains \") +\n//\t\t\tttstr((tjs_int)count) + TJS_W(\" file(s).\"));\n\n\t\ttotalcount += count;\n\t}\n\n\ttjs_uint64 endtick = TVPGetTickCount();\n\n\tTVPAddLog(ttstr(TJS_W(\"(info) Total \")) +\n\t\t\tttstr((tjs_int)totalcount) + TJS_W(\" file(s) found, \") +\n\t\t\tttstr((tjs_int)TVPAutoPathTable.GetCount()) + TJS_W(\" file(s) activated.\") + \n\t\t\tTJS_W(\" (\") + ttstr((tjs_int)(endtick - tick)) + TJS_W(\"ms)\"));\n\n\tAutoPathTableInit = true;\n\n\treturn totalcount;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetPlacedPath\n//---------------------------------------------------------------------------\nttstr TVPGetPlacedPath(const ttstr & name)\n{\n\t// search path and return the path which the \"name\" is placed.\n\t// returned name is normalized. returns empty string if the storage is not\n\t// found.\n#if 0 // needn't\n\tif(!TVPClearAutoPathCacheCallbackInit)\n\t{\n\t\tTVPAddCompactEventHook(&TVPClearAutoPathCacheCallback);\n\t\tTVPClearAutoPathCacheCallbackInit = true;\n\t}\n#endif\n\n\tttstr * incache = TVPAutoPathCache.FindAndTouch(name);\n\tif(incache) return *incache; // found in cache\n\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\tttstr normalized(TVPNormalizeStorageName(name));\n\n\tbool found = TVPIsExistentStorageNoSearchNoNormalize(normalized);\n\tif(found)\n\t{\n\t\t// found in current folder\n\t\tTVPAutoPathCache.Add(name, normalized);\n\t\treturn normalized;\n\t}\n\n\t// not found in current folder\n\t// search through auto path table\n\n\tttstr storagename = TVPExtractStorageName(normalized);\n\n\tTVPRebuildAutoPathTable(); // ensure auto path table\n\tttstr *result = TVPAutoPathTable.Find(storagename);\n\tif(result)\n\t{\n\t\t// found in table\n\t\tttstr found = *result + storagename;\n\t\tTVPAutoPathCache.Add(name, found);\n\t\treturn found;\n\t}\n\n\t// not found\n\t// TVPAutoPathCache.Add(name, ttstr()); // do not cache now\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSearchPlacedPath\n//---------------------------------------------------------------------------\nttstr TVPSearchPlacedPath(const ttstr & name)\n{\n\tttstr place = TVPGetPlacedPath(name);\n\tif(place.IsEmpty()) TVPThrowExceptionMessage(TVPCannotFindStorage, name);\n\treturn place;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPIsExistentStorage\n//---------------------------------------------------------------------------\nbool TVPIsExistentStorage(const ttstr &name)\n{\n\treturn !TVPGetPlacedPath(name).IsEmpty();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateStream\n//---------------------------------------------------------------------------\nstatic tTJSBinaryStream * _TVPCreateStream(const ttstr & _name, tjs_uint32 flags)\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n\n\tttstr name;\n\n\ttjs_uint32 access = flags & TJS_BS_ACCESS_MASK;\n\tif(access == TJS_BS_WRITE)\n\t\tname = TVPNormalizeStorageName(_name);\n\telse\n\t\tname = TVPGetPlacedPath(_name); // file must exist\n\n\tif (name.IsEmpty()) {\n\t\tif (access >= 1) TVPRemoveFromStorageCache(_name);\n\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, _name);\n\t}\n\n\t// does name contain > ?\n\tconst tjs_char * sharp_pos = TJS_strchr(name.c_str(), TVPArchiveDelimiter);\n\tif(sharp_pos)\n\t{\n\t\t// this storagename indicates a file in an archive\n\t\tif((flags & TJS_BS_ACCESS_MASK ) !=TJS_BS_READ)\n\t\t\tTVPThrowExceptionMessage(TVPCannotWriteToArchive);\n\n\t\tttstr arcname(name, (int)(sharp_pos - name.c_str()));\n\n\t\ttTVPArchive *arc;\n\t\ttTJSBinaryStream *stream;\n\t\tarc = TVPArchiveCache.Get(arcname);\n\t\ttry\n\t\t{\n\t\t\tttstr in_arc_name(sharp_pos + 1);\n\t\t\ttTVPArchive::NormalizeInArchiveStorageName(in_arc_name);\n\t\t\tstream = arc->CreateStream(in_arc_name);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tarc->Release();\n\t\t\tif(access >= 1) TVPRemoveFromStorageCache(_name);\n\t\t\tthrow;\n\t\t}\n\t\tif(access >= 1) TVPRemoveFromStorageCache(_name);\n\t\tarc->Release();\n\t\treturn stream;\n\t}\n\n\ttTJSBinaryStream *stream;\n\ttry\n\t{\n\t\tstream = TVPStorageMediaManager.Open(name, flags);\n\t}\n\tcatch(...)\n\t{\n\t\tif(access >= 1) TVPRemoveFromStorageCache(_name);\n\t\tthrow;\n\t}\n\tif (access >= 1) TVPRemoveFromStorageCache(_name);\n\treturn stream;\n}\n\ntTJSBinaryStream * TVPCreateStream(const ttstr & _name, tjs_uint32 flags)\n{\n\ttry\n\t{\n\t\treturn _TVPCreateStream(_name, flags);\n\t}\n\tcatch(eTJSScriptException &e)\n\t{\n\t\tif(TJS_strchr(_name.c_str(), '#'))\n\t\t\te.AppendMessage(TJS_W(\"[\") +\n\t\t\t\tTVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W(\"]\"));\n\t\tthrow e;\n\t}\n\tcatch(eTJSScriptError &e)\n\t{\n\t\tif(TJS_strchr(_name.c_str(), '#'))\n\t\t\te.AppendMessage(TJS_W(\"[\") +\n\t\t\t\tTVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W(\"]\"));\n\t\tthrow e;\n\t}\n\tcatch(eTJSError &e)\n\t{\n\t\tif(TJS_strchr(_name.c_str(), '#'))\n\t\t\te.AppendMessage(TJS_W(\"[\") +\n\t\t\t\tTVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W(\"]\"));\n\t\tthrow e;\n\t}\n\tcatch(...)\n\t{\n\t\t// check whether the filename contains '#' (former delimiter for archive\n\t\t// filename before 2.19 beta 14)\n\t\tif(TJS_strchr(_name.c_str(), '#'))\n\t\t\tTVPAddLog(TVPFormatMessage(TVPFilenameContainsSharpWarn, _name));\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPClearStorageCaches\n//---------------------------------------------------------------------------\nvoid TVPClearStorageCaches()\n{\n\t// clear all storage related caches\n\tTVPClearXP3SegmentCache();\n\tTVPClearAutoPathCache();\n}\n//---------------------------------------------------------------------------\n\nvoid TVPRemoveFromStorageCache(const ttstr &name) {\n\tTVPAutoPathCache.Delete(name);\n}\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Storages\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Storages::ClassID = -1;\ntTJSNC_Storages::tTJSNC_Storages() : inherited(TJS_W(\"Storages\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Storages)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addAutoPath)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tTVPAddAutoPath(path);\n\n\tif(result) result->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/addAutoPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeAutoPath)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tTVPRemoveAutoPath(path);\n\n\tif(result) result->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/removeAutoPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getFullPath)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPNormalizeStorageName(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getFullPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getPlacedPath)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPGetPlacedPath(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getPlacedPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/isExistentStorage)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = (tjs_int)TVPIsExistentStorage(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/isExistentStorage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStorageExt)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPExtractStorageExt(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStorageExt)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStorageName)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPExtractStorageName(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStorageName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStoragePath)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPExtractStoragePath(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStoragePath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/chopStorageExt)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr path = *param[0];\n\n\tif(result)\n\t\t*result = TVPChopStorageExt(path);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/chopStorageExt)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clearArchiveCache)\n{\n\tTVPClearArchiveCache();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/clearArchiveCache)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance * tTJSNC_Storages::CreateNativeInstance()\n{\n\t// this class cannot create an instance\n\tTVPThrowExceptionMessage(TVPCannotCreateInstance);\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/base/StorageIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Universal Storage System\n//---------------------------------------------------------------------------\n#ifndef StorageIntfH\n#define StorageIntfH\n\n#include \"tjsNative.h\"\n#include \"tjsHashSearch.h\"\n#include <vector>\n\n//---------------------------------------------------------------------------\n// archive delimiter\n//---------------------------------------------------------------------------\nextern tjs_char  TVPArchiveDelimiter; //  = '>';\n\n\n\n//---------------------------------------------------------------------------\n// utilities\n//---------------------------------------------------------------------------\nttstr TVPStringFromBMPUnicode(const tjs_uint16 *src, tjs_int maxlen = -1);\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPArchive base archive class\n//---------------------------------------------------------------------------\nclass tTVPArchive\n{\nprivate:\n\ttjs_uint RefCount;\n\npublic:\n\t//-- constructor\n\ttTVPArchive(const ttstr & name)\n\t\t{ ArchiveName = name; Init = false; RefCount = 1; }\n\tvirtual ~tTVPArchive() { ; }\n\n\t//-- AddRef and Release\n\tvoid AddRef() { RefCount++; }\n\tvoid Release() { if(RefCount == 1) delete this; else RefCount--; }\n\n\t//-- must be implemented by delivered class\n\tvirtual tjs_uint GetCount() = 0;\n\tvirtual ttstr GetName(tjs_uint idx) = 0;\n\t\t// returned name must be already normalized using NormalizeInArchiveStorageName\n\t\t// and the index must be sorted by its name, using ttstr::operator < .\n\t\t// this is needed by fast directory search.\n\n\tvirtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) = 0;\n\n\t//-- others, implemented in this class\nprivate:\n\n\ttTJSHashTable<ttstr, tjs_uint, tTJSHashFunc<ttstr>, 1024> Hash;\n\tbool Init;\n\npublic:\n\tttstr ArchiveName;\n\npublic:\n\tstatic void NormalizeInArchiveStorageName(ttstr & name);\n\nprivate:\n\tvoid AddToHash();\npublic:\n\ttTJSBinaryStream * CreateStream(const ttstr & name);\n\tbool IsExistent(const ttstr & name);\n\n\ttjs_int GetFirstIndexStartsWith(const ttstr & prefix);\n\t\t// returns first index which have 'prefix' at start of the name.\n};\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// iTVPStorageMedia\n//---------------------------------------------------------------------------\n/*\n\tabstract class for managing media ( like file: http: etc.)\n*/\n/*]*/\n#if 0\n/*[*/\n\t// for plug-in\nclass tTJSBinaryStream;\n/*]*/\n#endif\n/*[*/\n//---------------------------------------------------------------------------\nclass iTVPStorageLister // callback class for GetListAt\n{\npublic:\n\tvirtual void TJS_INTF_METHOD Add(const ttstr &file) = 0;\n};\n//---------------------------------------------------------------------------\nclass iTVPStorageMedia\n{\npublic:\n\tvirtual ~iTVPStorageMedia() {} // add by ZeaS\n\tvirtual void TJS_INTF_METHOD AddRef() = 0;\n\tvirtual void TJS_INTF_METHOD Release() = 0;\n\n\tvirtual void TJS_INTF_METHOD GetName(ttstr &name) = 0;\n\t\t// returns media name like \"file\", \"http\" etc.\n\n//\tvirtual bool TJS_INTF_METHOD IsCaseSensitive() = 0;\n\t\t// returns whether this media is case sensitive or not\n\n\tvirtual void TJS_INTF_METHOD NormalizeDomainName(ttstr &name) = 0;\n\t\t// normalize domain name according with the media's rule\n\n\tvirtual void TJS_INTF_METHOD NormalizePathName(ttstr &name) = 0;\n\t\t// normalize path name according with the media's rule\n\n\t// \"name\" below is normalized but does not contain media, eg.\n\t// not \"media://domain/path\" but \"domain/path\"\n\n\tvirtual bool TJS_INTF_METHOD CheckExistentStorage(const ttstr &name) = 0;\n\t\t// check file existence\n\n\tvirtual tTJSBinaryStream * TJS_INTF_METHOD Open(const ttstr & name, tjs_uint32 flags) = 0;\n\t\t// open a storage and return a tTJSBinaryStream instance.\n\t\t// name does not contain in-archive storage name but\n\t\t// is normalized.\n\n\tvirtual void TJS_INTF_METHOD GetListAt(const ttstr &name, iTVPStorageLister * lister) = 0;\n\t\t// list files at given place\n\n\tvirtual void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name) = 0;\n\t\t// basically the same as above,\n\t\t// check wether given name is easily accessible from local OS filesystem.\n\t\t// if true, returns local OS native name. otherwise returns an empty string.\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n\n//---------------------------------------------------------------------------\n// must be implemented in each platform\n//---------------------------------------------------------------------------\nextern tTVPArchive * TVPOpenArchive(const ttstr & name, bool normalizeFileName);\n\t// open archive and return tTVPArchive instance.\n\nTJS_EXP_FUNC_DEF(ttstr, TVPGetTemporaryName, ());\n\t// retrieve file name to store temporary data ( must be unique, local name )\n\nTJS_EXP_FUNC_DEF(ttstr, TVPGetAppPath, ());\n\t// retrieve program path, in normalized storage name\n\nvoid TVPPreNormalizeStorageName(ttstr &name);\n\t\t// called by TVPNormalizeStorageName before it process the storage name.\n\t\t// user may pass the OS's native filename to the TVP storage system,\n\t\t// so that this function must convert it to the TVP storage name rules.\n\niTVPStorageMedia * TVPCreateFileMedia();\n\t// create basic default \"file:\" storage media\n/*\nextern void TVPPreNormalizeStorageName(ttstr &name);\n\nextern tTJSBinaryStream * TVPOpenStream(const ttstr & name, tjs_uint32 flags);\n\t// open a storage and return a tTJSBinaryStream instance.\n\t// name does not contain in-archive storage name but\n\t// is normalized.\n\nextern bool TVPCheckExistentStorage(const ttstr &name);\n\t// check file existence\n\nextern void TVPGetStorageListAt(const ttstr &name, std::vector<ttstr> & list);\n\nextern ttstr TVPGetMediaCurrent(const ttstr & name);\nextern void TVPSetMediaCurrent(const ttstr & name, const ttstr & dir);\n\nextern ttstr TVPGetNativeName(const ttstr &name);\n\t// retrieve OS native name\n\nextern ttstr TVPGetLocallyAccessibleName(const ttstr &name);\n\t// check wether given name is easily accessible from local OS filesystem.\n\t// if true, returns local OS native name. otherwise returns an empty string.\n\n*/\nextern bool TVPRemoveFile(const ttstr &name);\n\t// remove local file ( \"name\" is a local *native* name )\n\t// this must not throw an exception ( return false if error )\nextern bool TVPRemoveFolder(const ttstr &name);\n\t// remove local directory ( \"name\" is a local *native* name )\n\t// this must not throw an exception ( return false if error )\nbool TVPCreateFolders(const ttstr &folder);\n\t// create folder along with the argument recursively (like mkdir -p).\n\t// 'folder' must be a local native name.\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// implementation in this unit\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPRegisterStorageMedia, (iTVPStorageMedia *media));\n\t// register storage media\nTJS_EXP_FUNC_DEF(void, TVPUnregisterStorageMedia, (iTVPStorageMedia *media));\n\t// remove storage media\n\n\nextern tTJSBinaryStream * TVPCreateStream(const ttstr & name, tjs_uint32 flags = 0);\n\t// open \"name\" and return tTJSBinaryStream instance.\n\t// name will be local storage, network storage, in-archive storage, etc...\n\nTJS_EXP_FUNC_DEF(bool, TVPIsExistentStorageNoSearch, (const ttstr &name));\n\t// if \"name\" is exists, return true. otherwise return false.\n\t// this does not search any auto search path.\n\nTJS_EXP_FUNC_DEF(bool, TVPIsExistentStorageNoSearchNoNormalize, (const ttstr &name));\n\nTJS_EXP_FUNC_DEF(ttstr, TVPNormalizeStorageName, (const ttstr & name));\n\nTJS_EXP_FUNC_DEF(void, TVPSetCurrentDirectory, (const ttstr & name));\n\t// set system current directory.\n\t// directory must end with path delimiter '/',\n\t// or archive delimiter '>'.\n\nTJS_EXP_FUNC_DEF(void, TVPGetLocalName, (ttstr &name));\n\nttstr TVPGetLocallyAccessibleName(const ttstr &name);\n\n\nTJS_EXP_FUNC_DEF(ttstr, TVPExtractStorageExt, (const ttstr & name));\n\t// extract \"name\"'s extension and return it.\n\n\nTJS_EXP_FUNC_DEF(ttstr, TVPExtractStorageName, (const ttstr & name));\n\t// extract \"name\"'s storage name ( excluding path ) and return it.\n\nTJS_EXP_FUNC_DEF(ttstr, TVPExtractStoragePath, (const ttstr & name));\n\t// extract \"name\"'s path ( including last delimiter ) and return it.\n\nTJS_EXP_FUNC_DEF(ttstr, TVPChopStorageExt, (const ttstr & name));\n\t// chop storage's extension and return it.\n\t// extensition delimiter '.' will not be held.\n\n\nTJS_EXP_FUNC_DEF(void, TVPAddAutoPath, (const ttstr & name));\n\t// add given path to auto search path\n\nTJS_EXP_FUNC_DEF(void, TVPRemoveAutoPath, (const ttstr &name));\n\t// remove given path from auto search path\n\nTJS_EXP_FUNC_DEF(ttstr, TVPGetPlacedPath, (const ttstr & name));\n\t// search path and return the path which the \"name\" is placed.\n\nextern ttstr TVPSearchPlacedPath(const ttstr & name);\n\t// the same as TVPGetPlacedPath, except for rising exception when the storage\n\t// is not found.\n\nTJS_EXP_FUNC_DEF(bool, TVPIsExistentStorage, (const ttstr &name));\n\t// if \"name\" is exists, return true. otherwise return false.\n\t// this searches auto search path.\n\nTJS_EXP_FUNC_DEF(void, TVPClearStorageCaches, ());\n\t// clear all internal storage related caches.\nvoid TVPRemoveFromStorageCache(const ttstr &name);\nextern tjs_uint TVPSegmentCacheLimit; // XP3 segment cache limit, in bytes.\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Storages : TJS Storages class\n//---------------------------------------------------------------------------\nclass tTJSNC_Storages : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Storages();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Storages();\n//---------------------------------------------------------------------------\n\nclass tTVPStorageMedia : public iTVPStorageMedia {\nprotected:\n\ttjs_int refCount;\n\ttTVPStorageMedia() : refCount(1) {}\n\n\tvirtual void TJS_INTF_METHOD AddRef() override { refCount++; }\n\tvirtual void TJS_INTF_METHOD Release() override {\n\t\tif (refCount == 1) {\n\t\t\tdelete this;\n\t\t} else {\n\t\t\trefCount--;\n\t\t}\n\t}\n\tvirtual void TJS_INTF_METHOD NormalizeDomainName(ttstr &name) override {}\n\tvirtual void TJS_INTF_METHOD NormalizePathName(ttstr &name) override {}\n\tvirtual void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name) override {}\n};\n\nclass TArchiveStream : public tTJSBinaryStream {\n\ttTVPArchive *Owner;\n\ttjs_int64 CurrentPos;\n\ttjs_uint64 StartPos, DataLength;\n\ttTJSBinaryStream *_instr;\n\npublic:\n\tTArchiveStream(tTVPArchive *owner, tjs_uint64 off, tjs_uint64 len);\n\tvirtual ~TArchiveStream();\n\tvirtual tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence) {\n\t\tswitch (whence) {\n\t\tcase TJS_BS_SEEK_SET:\n\t\t\tCurrentPos = offset;\n\t\t\tbreak;\n\n\t\tcase TJS_BS_SEEK_CUR:\n\t\t\tCurrentPos = offset + CurrentPos;\n\t\t\tbreak;\n\n\t\tcase TJS_BS_SEEK_END:\n\t\t\tCurrentPos = offset + DataLength;\n\t\t\tbreak;\n\t\t}\n\t\tif (CurrentPos < 0) CurrentPos = 0;\n\t\telse if (CurrentPos > (tjs_int64)DataLength) CurrentPos = DataLength;\n\t\t_instr->SetPosition(CurrentPos + StartPos);\n\t\treturn CurrentPos;\n\t}\n\tvirtual tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size) {\n\t\tif (CurrentPos + read_size >= (tjs_int64)DataLength) {\n\t\t\tread_size = (tjs_uint)(DataLength - CurrentPos);\n\t\t}\n\n\t\t_instr->ReadBuffer(buffer, read_size);\n\n\t\tCurrentPos += read_size;\n\n\t\treturn read_size;\n\t}\n\tvirtual tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size) {\n\t\treturn 0;\n\t}\n\tvirtual tjs_uint64 TJS_INTF_METHOD GetSize() {\n\t\treturn DataLength;\n\t}\n};\n#endif\n"
  },
  {
    "path": "src/core/base/SysInitIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Initialization and Uninitialization\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <vector>\n#include <algorithm>\n#include <functional>\n\n#include \"tjsUtils.h\"\n#include \"SysInitIntf.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tvpgl.h\"\n// #include \"Protect.h\"\n\n\n//---------------------------------------------------------------------------\n// global data\n//---------------------------------------------------------------------------\nttstr TVPProjectDir; // project directory (in unified storage name)\nttstr TVPDataPath; // data directory (in unified storage name)\n//---------------------------------------------------------------------------\n\n\n\nextern void TVPGL_C_Init();\n//---------------------------------------------------------------------------\n// TVPSystemInit : Entire System Initialization\n//---------------------------------------------------------------------------\nvoid TVPSystemInit(void)\n{\n#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32\n#ifndef CC_TARGET_OS_IPHONE\n\tif (!TVPProtectInit()) return;\n#endif\n//#else\n#ifdef USING_PROTECT\n\twhile (!TVPProtectInit()) {\n\t\tTVPUpdateLicense();\n\t}\n#endif\n#endif\n\n\tTVPBeforeSystemInit();\n\n\tTVPInitScriptEngine();\n\n\tTVPInitTVPGL();\n//\tTVPGL_C_Init();\n\n\tTVPAfterSystemInit();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSystemUninit : System shutdown, cleanup, etc...\n//---------------------------------------------------------------------------\nstatic void TVPCauseAtExit();\nbool TVPSystemUninitCalled = false;\nvoid TVPSystemUninit(void)\n{\n\tif(TVPSystemUninitCalled) return;\n\tTVPSystemUninitCalled = true;\n\n\tTVPBeforeSystemUninit();\n\n\tTVPUninitTVPGL();\n\n\ttry\n\t{\n\t\tTVPUninitScriptEngine();\n\t}\n\tcatch(...)\n\t{\n\t\t// ignore errors\n\t}\n\n\tTVPAfterSystemUninit();\n\n\tTVPCauseAtExit();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPAddAtExitHandler related\n//---------------------------------------------------------------------------\nstruct tTVPAtExitInfo\n{\n\ttTVPAtExitInfo(tjs_int pri, void(*handler)())\n\t{\n\t\tPriority = pri, Handler = handler;\n\t}\n\n\ttjs_int Priority;\n\tvoid (*Handler)();\n\n\tbool operator <(const tTVPAtExitInfo & r) const\n\t\t{ return this->Priority < r.Priority; }\n\tbool operator >(const tTVPAtExitInfo & r) const\n\t\t{ return this->Priority > r.Priority; }\n\tbool operator ==(const tTVPAtExitInfo & r) const\n\t\t{ return this->Priority == r.Priority; }\n\n};\nstatic std::vector<tTVPAtExitInfo> *TVPAtExitInfos = NULL;\nstatic bool TVPAtExitShutdown = false;\n//---------------------------------------------------------------------------\nvoid TVPAddAtExitHandler(tjs_int pri, void (*handler)())\n{\n\tif(TVPAtExitShutdown) return;\n\n\tif(!TVPAtExitInfos) TVPAtExitInfos = new std::vector<tTVPAtExitInfo>();\n\tTVPAtExitInfos->push_back(tTVPAtExitInfo(pri, handler));\n}\n//---------------------------------------------------------------------------\nstatic void TVPCauseAtExit()\n{\n\tif(TVPAtExitShutdown) return;\n\tTVPAtExitShutdown = true;\n\n\tstd::sort(TVPAtExitInfos->begin(), TVPAtExitInfos->end()); // descending sort\n\n\tstd::vector<tTVPAtExitInfo>::iterator i;\n\tfor(i = TVPAtExitInfos->begin(); i!=TVPAtExitInfos->end(); i++)\n\t{\n\t\ti->Handler();\n\t}\n\n\tdelete TVPAtExitInfos;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n"
  },
  {
    "path": "src/core/base/SysInitIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Initialization and Uninitialization\n//---------------------------------------------------------------------------\n#ifndef SysInitIntfH\n#define SysInitIntfH\n\n\n//---------------------------------------------------------------------------\n// System initialization and uninitialization\n//---------------------------------------------------------------------------\n\n//-- global data\nextern ttstr TVPProjectDir; // project directory\nextern ttstr TVPDataPath; // data directory\n\n\n//-- implementation in this unit\nextern void TVPSystemInit(void);\nextern void TVPSystemUninit(void);\n\n\n\n//-- implement in each platform\nextern void TVPBeforeSystemInit(); // this must set TVPProjectDir\nextern void TVPAfterSystemInit();\nextern void TVPBeforeSystemUninit();\nextern void TVPAfterSystemUninit();\n\nextern void TVPTerminateAsync(int code=0); // do acynchronous teminating of application\nextern void TVPTerminateSync(int code=0); // do synchronous teminating of application(never return)\nextern void TVPMainWindowClosed(); // called from WindowIntf.cpp, caused by closing main window.\n\t// this function must shutdown the application, unless the controller window is visible.\n//---------------------------------------------------------------------------\n\nextern bool TVPSystemUninitCalled;\n\t// whether TVPSystemUninit is called or not\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// AtExit related\n//---------------------------------------------------------------------------\nvoid TVPAddAtExitHandler(tjs_int pri, void (*handler)());\nstruct tTVPAtExit\n{\n\ttTVPAtExit(tjs_int pri, void (*handler)())\n\t{\n\t\tTVPAddAtExitHandler(pri, handler);\n\t}\n};\n#define TVP_ATEXIT_PRI_PREPARE    10\n#define TVP_ATEXIT_PRI_SHUTDOWN   100\n#define TVP_ATEXIT_PRI_RELEASE    1000\n#define TVP_ATEXIT_PRI_CLEANUP    10000\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Command line parameter operations (implement in each platform)\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(bool, TVPGetCommandLine, (const tjs_char * name, tTJSVariant *value = NULL));\n\t// retrieves command line parameter named \"name\".\n\t// command line parameter format must be \"-name=value\"\n\t// returns false if the the parameter is not exist, otherwise\n\t// sets the value to \"value\" and returns true.\nTJS_EXP_FUNC_DEF(tjs_int, TVPGetCommandLineArgumentGeneration, ());\n\t// retrieves command line argument generation count. you can check\n\t// whether the command line options has changed, by comparing this value\n\t// to your value which is remembered when of previous call of this.\nTJS_EXP_FUNC_DEF(void, TVPSetCommandLine, (const tjs_char * name, const ttstr & value));\n\t// sets command line to the specified value.\n\t// note that this function does not check any consistency or correctness of the value.\n\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/base/SystemIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"System\" class interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsMessage.h\"\n#include \"SystemIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"MsgIntf.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"EventIntf.h\"\n#include \"LayerIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"Random.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"DebugIntf.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"Platform.h\"\n\nextern bool TVPStartupSuccess;\n\n//---------------------------------------------------------------------------\n// TVPFireOnApplicationActivateEvent\n//---------------------------------------------------------------------------\nvoid TVPFireOnApplicationActivateEvent(bool activate_or_deactivate)\n{\n\t// get the script engine\n\ttTJS *engine = TVPGetScriptEngine();\n\tif(!engine)\n\t\treturn; // the script engine had been shutdown\n\n\t// get System.onActivate or System.onDeactivate\n\t// and call it.\n\tiTJSDispatch2 * global = TVPGetScriptEngine()->GetGlobalNoAddRef();\n\tif(!global) return;\n\n\ttTJSVariant val;\n\ttTJSVariant val2;\n\ttTJSVariantClosure clo;\n\ttTJSVariantClosure func;\n\n\ttry\n\t{\n\t\ttjs_error er;\n\t\ter = global->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"System\"), NULL, &val, global);\n\t\tif(TJS_FAILED(er)) return;\n\n\t\tif(val.Type() != tvtObject) return;\n\n\t\tclo = val.AsObjectClosureNoAddRef();\n\n\t\tif(clo.Object == NULL) return;\n\n\t\tclo.PropGet(TJS_MEMBERMUSTEXIST,\n\t\t\t\tactivate_or_deactivate?\n\t\t\t\t\tTJS_W(\"onActivate\"):\n\t\t\t\t\tTJS_W(\"onDeactivate\"),\n\t\t\tNULL, &val2, NULL);\n\n\t\tif(val2.Type() != tvtObject) return;\n\n\t\tfunc = val2.AsObjectClosureNoAddRef();\n\t}\n\tcatch(const eTJS &e)\n\t{\n\t\t// the system should not throw exceptions during retrieving the function\n\t\tTVPAddLog( TVPFormatMessage( TVPErrorInRetrievingSystemOnActivateOnDeactivate, e.GetMessage() ) );\n\t\treturn;\n\t}\n\n\tif(func.Object != NULL) func.FuncCall(0, NULL, NULL, NULL, 0, NULL, NULL);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_System\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_System::ClassID = -1;\ntTJSNC_System::tTJSNC_System() : inherited(TJS_W(\"System\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(System)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/System)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/System)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/terminate)\n{\n\tint code = numparams > 0 ? param[0]->AsInteger() : 0;\n\tif (!TVPStartupSuccess) {\n\t\t;\n\t} else {\n\tTVPTerminateAsync(code);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/terminate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exit)\n{\n\t// this method does not return\n\n\tint code = numparams > 0 ? param[0]->AsInteger() : 0;\n\tif (!TVPStartupSuccess) {\n\t\t;\n\t} else {\n\tTVPTerminateSync(code);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/exit)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/inputString)\n{\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\tttstr value = *param[2];\n\n//\tbool b = TVPInputQuery(*param[0], *param[1], value);\n\n\tttstr caption = *param[0], prompt = *param[1];\n\t// this shows a dialog box which let user to input a string.\n\t// return false if the user selects \"cancel\", otherwise return true.\n\t// implement in each platform.\n\tstd::vector<ttstr> btns;\n\tbtns.emplace_back(LocaleConfigManager::GetInstance()->GetText(\"msgbox_ok\"));\n\tbtns.emplace_back(LocaleConfigManager::GetInstance()->GetText(\"cancel\"));\n\tint ret = TVPShowSimpleInputBox(value, caption, prompt, btns);\n\tbool b = ret == 0; // the left button clicked\n\n\tif(result)\n\t{\n\t\tif(b)\n\t\t\t*result = value;\n\t\telse\n\t\t\tresult->Clear();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/inputString)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addContinuousHandler)\n{\n\t// add function to continus handler list\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\n\tTVPAddContinuousHandler(clo);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/addContinuousHandler)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeContinuousHandler)\n{\n\t// remove function from continuous handler list\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\n\tTVPRemoveContinuousHandler(clo);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/removeContinuousHandler)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/toActualColor)\n{\n\t// convert color codes to 0xRRGGBB format.\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\ttjs_uint32 color = (tjs_int)(*param[0]);\n\t\tcolor = TVPToActualColor(color);\n\t\t*result = (tjs_int)color;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/toActualColor)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clearGraphicCache)\n{\n\t// clear graphic cache\n\tTVPClearGraphicCache();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/clearGraphicCache)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/touchImages)\n{\n\t// try to cache graphics\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tstd::vector<ttstr> storages;\n\ttTJSVariantClosure array = param[0]->AsObjectClosureNoAddRef();\n\n\ttjs_int count = 0;\n\twhile(true)\n\t{\n\t\ttTJSVariant val;\n\t\tif(TJS_FAILED(array.Object->PropGetByNum(0, count, &val, array.ObjThis)))\n\t\t\tbreak;\n\t\tif(val.Type() == tvtVoid) break;\n\t\tstorages.push_back(ttstr(val));\n\t\tcount++;\n\t}\n\n\ttjs_int64 limit = 0;\n\ttjs_uint64 timeout = 0;\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) limit = (tjs_int64)*param[1];\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid) timeout = (tjs_int64)*param[2];\n\n\tTVPTouchImages(storages, limit, timeout);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/touchImages)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/createUUID)\n{\n\t// create UUID\n\t// return UUID string in form of \"43abda37-c597-4646-a279-c27a1373af90\"\n\n\ttjs_uint8 uuid[16];\n\n\tTVPGetRandomBits128(uuid);\n\n\tuuid[8] &= 0x3f;\n\tuuid[8] |= 0x80; // override clock_seq\n\n\tuuid[6] &= 0x0f;\n\tuuid[6] |= 0x40; // override version\n\n\ttjs_char buf[40];\n\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char),\nTJS_W(\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"),\n\t\tuuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3],\n\t\tuuid[ 4], uuid[ 5], uuid[ 6], uuid[ 7],\n\t\tuuid[ 8], uuid[ 9], uuid[10], uuid[11],\n\t\tuuid[12], uuid[13], uuid[14], uuid[15]);\n\n\tif(result) *result = tTJSVariant(buf);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/createUUID)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/assignMessage)\n{\n\t// assign system message\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tttstr id(*param[0]);\n\tttstr msg(*param[1]);\n\n\tbool res = TJSAssignMessage(id.c_str(), msg.c_str());\n\n\tif(result) *result = tTJSVariant((tjs_int)res);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/assignMessage)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doCompact)\n{\n\t// compact memory usage\n\n\ttjs_int level = TVP_COMPACT_LEVEL_MAX;\n\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tlevel = (tjs_int)*param[0];\n\n\tTVPDeliverCompactEvent(level);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/doCompact)\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(versionString)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetVersionString();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(versionString)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(versionInformation)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetVersionInformation();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(versionInformation)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(eventDisabled)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetSystemEventDisabledState();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPSetSystemEventDisabledState(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(eventDisabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(graphicCacheLimit)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)TVPGetGraphicCacheLimit();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPSetGraphicCacheLimit((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(graphicCacheLimit)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(platformName)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetPlatformName();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(platformName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(osName)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetOSName();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(osName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(exitOnWindowClose)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPTerminateOnWindowClose;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPTerminateOnWindowClose = 0!=(tjs_int)*param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(exitOnWindowClose)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(drawThreadNum)\n{\n        TJS_BEGIN_NATIVE_PROP_GETTER\n          {\n            *result = TVPDrawThreadNum;\n            return TJS_S_OK;\n          }\n        TJS_END_NATIVE_PROP_GETTER\n        TJS_BEGIN_NATIVE_PROP_SETTER\n          {\n            TVPDrawThreadNum = (tjs_int)*param;\n            return TJS_S_OK;\n          }\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(drawThreadNum)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(processorNum)\n{\n        TJS_BEGIN_NATIVE_PROP_GETTER\n          {\n            *result = TVPGetProcessorNum();\n            return TJS_S_OK;\n          }\n        TJS_END_NATIVE_PROP_GETTER\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(processorNum)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(exeBits)\n{\n        TJS_BEGIN_NATIVE_PROP_GETTER\n          {\n#ifdef TJS_64BIT_OS\n            *result = 64;\n#else\n            *result = 32;\n#endif\n            return TJS_S_OK;\n          }\n        TJS_END_NATIVE_PROP_GETTER\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(exeBits)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(osBits)\n{\n        TJS_BEGIN_NATIVE_PROP_GETTER\n          {\n          \t*result = TVPGetOSBits();\n            return TJS_S_OK;\n          }\n        TJS_END_NATIVE_PROP_GETTER\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(osBits)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(exitOnNoWindowStartup)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPTerminateOnNoWindowStartup;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPTerminateOnNoWindowStartup = 0!=(tjs_int)*param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(exitOnNoWindowStartup)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n\n\t// register default \"exceptionHandler\" member\n\ttTJSVariant val((iTJSDispatch2*)NULL, (iTJSDispatch2*)NULL);\n\tPropSet(TJS_MEMBERENSURE, TJS_W(\"exceptionHandler\"), NULL, &val, this);\n\n\t// and onActivate, onDeactivate\n\tPropSet(TJS_MEMBERENSURE, TJS_W(\"onActivate\"), NULL, &val, this);\n\tPropSet(TJS_MEMBERENSURE, TJS_W(\"onDeactivate\"), NULL, &val, this);\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance * tTJSNC_System::CreateNativeInstance()\n{\n\t// this class cannot create an instance\n\tTVPThrowExceptionMessage(TVPCannotCreateInstance);\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/base/SystemIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"System\" class interface\n//---------------------------------------------------------------------------\n#ifndef SystemIntfH\n#define SystemIntfH\n#include \"tjsNative.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNC_System : TJS System class\n//---------------------------------------------------------------------------\nclass tTJSNC_System : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_System();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_System();\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(ttstr, TVPGetPlatformName, ());\n\t\t// retrieve platform name (eg. \"Win32\")\n\t\t// implement in each platform.\nTJS_EXP_FUNC_DEF(ttstr, TVPGetOSName, ());\n\t\t// retrieve OS name\n\t\t// implement in each platform.\nextern void TVPFireOnApplicationActivateEvent(bool activate_or_deactivate);\nextern tjs_int TVPGetOSBits();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/base/TARArchive.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"StorageIntf.h\"\n#include \"UtilStreams.h\"\n#include \"Platform.h\"\n#include \"MsgIntf.h\"\n#include <algorithm>\n\nvoid TVPFreeArchiveHandlePoolByPointer(void * pointer);\nvoid TVPReleaseCachedArchiveHandle(void * pointer, tTJSBinaryStream * stream);\n\nvoid storeFilename(ttstr &name, const char *narrowName, const ttstr &filename)\n{\n\ttjs_int len = TJS_narrowtowidelen(narrowName);\n\tif (len == -1) {\n\t\tttstr msg(\"Filename is not encoded in UTF8 in archive:\\n\");\n\t\tTVPShowSimpleMessageBox(msg + filename, TJS_W(\"Error\"));\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid archive entry name\"));\n\t}\n\ttjs_char *p = name.AllocBuffer(len);\n\tp[TJS_narrowtowide(p, narrowName, len)] = 0;\n\tname.FixLen();\n}\n\n//---------------------------------------------------------------------------\n// tar archive\n//---------------------------------------------------------------------------\ntjs_uint64 parseOctNum(const char *oct, int length)\n{\n\ttjs_uint64 num = 0;\n\tfor (int i = 0; i < length; i++){\n\t\tchar c = oct[i];\n\t\tif ('0' <= c && c <= '9'){\n\t\t\tnum = num * 8 + (c - '0');\n\t\t}\n\t}\n\treturn num;\n}\n#include \"tar.h\"\nclass TARArchive : public tTVPArchive {\n\tstruct EntryInfo {\n\t\tttstr filename;\n\t\ttjs_uint64 offset;\n\t\ttjs_uint64 size;\n\t};\n\tstd::vector<EntryInfo> filelist;\n\tfriend class TARArchiveStream;\n\npublic:\n\tTARArchive(const ttstr & arcname) : tTVPArchive(arcname) {\n\t}\n\t~TARArchive() {\n\t\tTVPFreeArchiveHandlePoolByPointer(this);\n\t}\n\tbool init(tTJSBinaryStream * _instr, bool normalizeFileName) {\n\t\tif (_instr) {\n\t\t\ttjs_uint64 archiveSize = _instr->GetSize();\n\t\t\tTAR_HEADER tar_header;\n\t\t\t// check first header\n\t\t\tif (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) {\n\t\t\t\t//delete _instr;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tunsigned int checksum = parseOctNum(tar_header.dbuf.chksum, sizeof(tar_header.dbuf.chksum));\n\t\t\tif (checksum != tar_header.compsum() && (int)checksum != tar_header.compsum_oldtar()) {\n\t\t\t\t//delete _instr;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t_instr->SetPosition(0);\n\t\t\twhile (_instr->GetPosition() <= archiveSize - sizeof(tar_header)) {\n\t\t\t\tif (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) break;\n\t\t\t\ttjs_uint64 original_size = parseOctNum(tar_header.dbuf.size, sizeof(tar_header.dbuf.size));\n\t\t\t\tstd::vector<char> filename;\n\t\t\t\tif (tar_header.dbuf.typeflag == LONGLINK) {\t// tar_header.dbuf.name == \"././@LongLink\"\n\t\t\t\t\tunsigned int readsize = (original_size + (TBLOCK - 1)) & ~(TBLOCK - 1);\n\t\t\t\t\tfilename.resize(readsize + 1);\t//TODO:size lost\n\t\t\t\t\tif (_instr->Read(&filename[0], readsize) != readsize) break;\n\t\t\t\t\tfilename[readsize] = 0;\n\t\t\t\t\tif (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) break;\n\t\t\t\t\toriginal_size = parseOctNum(tar_header.dbuf.size, sizeof(tar_header.dbuf.size));\n\t\t\t\t}\n\t\t\t\tif (tar_header.dbuf.typeflag != REGTYPE) continue; // only accept regular file\n\t\t\t\tif (filename.empty()) {\n\t\t\t\t\tfilename.resize(101);\n\t\t\t\t\tmemcpy(&filename[0], tar_header.dbuf.name, sizeof(tar_header.dbuf.name));\n\t\t\t\t\tfilename[100] = 0;\n\t\t\t\t}\n\t\t\t\tEntryInfo item;\n\t\t\t\tstoreFilename(item.filename, &filename[0], ArchiveName);\n\t\t\t\tif (normalizeFileName)\n\t\t\t\t\tNormalizeInArchiveStorageName(item.filename);\n\t\t\t\titem.size = original_size;\n\t\t\t\titem.offset = _instr->GetPosition();\n\t\t\t\tfilelist.emplace_back(item);\n\t\t\t\ttjs_uint64 readsize = (original_size + (TBLOCK - 1)) & ~(TBLOCK - 1);\n\t\t\t\t_instr->SetPosition(item.offset + readsize);\n\t\t\t}\n\t\t\tif (normalizeFileName) {\n\t\t\t\tstd::sort(filelist.begin(), filelist.end(), [](const EntryInfo& a, const EntryInfo& b) {\n\t\t\t\t\treturn a.filename < b.filename;\n\t\t\t\t});\n\t\t\t}\n\t\t\tTVPReleaseCachedArchiveHandle(this, _instr);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tvirtual tjs_uint GetCount() { return filelist.size(); }\n\tvirtual ttstr GetName(tjs_uint idx) { return filelist[idx].filename; }\n\tvirtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx);\n};\n\ntTJSBinaryStream * TARArchive::CreateStreamByIndex(tjs_uint idx) {\n\tconst EntryInfo &info = filelist[idx];\n\treturn new TArchiveStream(this, info.offset, info.size);\n}\n\ntTVPArchive * TVPOpenTARArchive(const ttstr & name, tTJSBinaryStream * st, bool normalizeFileName) {\n\tTARArchive *arc = new TARArchive(name);\n\tif (!arc->init(st, normalizeFileName)) {\n\t\tdelete arc;\n\t\treturn nullptr;\n\t}\n\treturn arc;\n}\n"
  },
  {
    "path": "src/core/base/TextStream.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text read/write stream\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <zlib.h>\n#include \"TextStream.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"EventIntf.h\"\n#include \"UtilStreams.h\"\n#include \"tjsError.h\"\n#include \"CharacterSet.h\"\n\nextern \"C\" int sjis_mbtowc(unsigned short *wc, const unsigned char *s);\nextern \"C\" int gbk_mbtowc(unsigned short *wc, const unsigned char *s);\n\nint utf8_mbtowc(unsigned short *pwc, const unsigned char *s) {\n\tunsigned char c = s[0];\n\n\tif (c < 0x80) {\n\t\t*pwc = c;\n\t\treturn 1;\n\t} else if (c < 0xc2) {\n\t\treturn -1;\n\t} else if (c < 0xe0) {\n\t\tif (!((s[1] ^ 0x80) < 0x40))\n\t\t\treturn -1;\n\t\t*pwc = ((unsigned short)(c & 0x1f) << 6)\n\t\t\t| (unsigned short)(s[1] ^ 0x80);\n\t\treturn 2;\n\t} else if (c < 0xf0) {\n\t\tif (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n\t\t\t&& (c >= 0xe1 || s[1] >= 0xa0)))\n\t\t\treturn -1;\n\t\t*pwc = ((unsigned short)(c & 0x0f) << 12)\n\t\t\t| ((unsigned short)(s[1] ^ 0x80) << 6)\n\t\t\t| (unsigned short)(s[2] ^ 0x80);\n\t\treturn 3;\n\t} else\n\t\treturn -1;\n}\n\nint(*mbtowc_for_text_stream)(unsigned short *wc, const unsigned char *s) = nullptr;\n\nstatic size_t _TextStream_mbstowcs(int(*func_mbtowc)(unsigned short *, const unsigned char *), tjs_char *pwcs, const tjs_nchar *s, size_t n)\n{\n    if(!s) return -1;\n    if(pwcs && n == 0) return 0;\n\n    size_t count = 0;\n    int cl;\n    if(!pwcs) {\n        while(*s) {\n\t\t\tunsigned short wc;\n\t\t\tcl = func_mbtowc(&wc, (const unsigned char*)s);\n            if(cl <= 0)\n                return -1;\n            s += cl;\n            ++count;\n        }\n    } else {\n        while(*s && n > 0) {\n\t\t\tcl = func_mbtowc((unsigned short *)pwcs, (const unsigned char*)s);\n            if(cl <= 0)\n                return -1;\n            n --;\n            s += cl;\n            pwcs++;\n            ++count;\n        }\n    }\n    return count;\n}\n\n/*\n\tText stream is used by TJS's Array.save, Dictionary.saveStruct etc.\n\tto input/output text files.\n*/\n\nextern size_t TextStream_mbstowcs(tjs_char *pwcs, const tjs_nchar *s, size_t n) {\n\tif (mbtowc_for_text_stream) {\n\t\treturn _TextStream_mbstowcs(mbtowc_for_text_stream, pwcs, s, n);\n\t}\n\t// trying every encoding available\n\tsize_t ret = _TextStream_mbstowcs(sjis_mbtowc, pwcs, s, n);\n\tif (ret == (size_t)-1) {\n\t\tret = _TextStream_mbstowcs(utf8_mbtowc, pwcs, s, n);\n\t\tif (ret != (size_t)-1) {\n\t\t\tmbtowc_for_text_stream = utf8_mbtowc;\n\t\t\treturn ret;\n\t\t}\n\t\tret = _TextStream_mbstowcs(gbk_mbtowc, pwcs, s, n);\n\t\tif (ret != (size_t)-1) {\n\t\t\tmbtowc_for_text_stream = gbk_mbtowc;\n\t\t\treturn ret;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic ttstr enc_utf8 = TJS_W(\"utf8\"), enc_utf8_2 = TJS_W(\"utf-8\"), enc_utf16 = TJS_W(\"utf16\"),\n\tenc_utf16_2 = TJS_W(\"utf-16\"), enc_gbk = TJS_W(\"gbk\"), enc_jis = TJS_W(\"sjis\"),\n\tenc_jis_2 = TJS_W(\"shiftjis\"), enc_jis_3 = TJS_W(\"shift_jis\"), enc_jis_4 = TJS_W(\"shift-jis\");\nbool TVPStringDecode(const void *p, int len, ttstr& result, ttstr encoding /*= \"utf8\"*/) {\n\tif (encoding == enc_utf8 || encoding == enc_utf8_2) {\n\t\tint n = (int)TJS_mbstowcs(NULL, (char*)p, len);\n\t\tif (n == -1) return false;\n\t\tTJS_mbstowcs(result.AllocBuffer(n), (char*)p, len);\n\t} else if (encoding == enc_utf16 || encoding == enc_utf16_2) {\n\t\tmemcpy(result.AllocBuffer(len / 2), p, len);\n\t\tresult.FixLen();\n\t} else if (encoding == enc_jis || encoding == enc_jis_2 || encoding == enc_jis_3 || encoding == enc_jis_4) {\n\t\tint n = _TextStream_mbstowcs(sjis_mbtowc, NULL, (char*)p, len);\n\t\tif (n == -1) return false;\n\t\t_TextStream_mbstowcs(sjis_mbtowc, result.AllocBuffer(n), (char*)p, len);\n\t} else if (encoding == enc_gbk) {\n\t\tint n = _TextStream_mbstowcs(gbk_mbtowc, NULL, (char*)p, len);\n\t\tif (n == -1) return false;\n\t\t_TextStream_mbstowcs(gbk_mbtowc, result.AllocBuffer(n), (char*)p, len);\n\t} else {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool TVPStringEncode(const ttstr &src, std::string &result, ttstr encoding /*= \"utf8\"*/)\n{\n\tif (encoding == enc_utf8 || encoding == enc_utf8_2) {\n\t\tresult = src.AsNarrowStdString();\n\t} else if (encoding == enc_utf16 || encoding == enc_utf16_2) {\n\t\tresult.resize(src.length() * 2);\n\t\tmemcpy((char*)result.c_str(), src.c_str(), src.length() * 2);\n// \t} else if (encoding == enc_jis || encoding == enc_jis_2 || encoding == enc_jis_3 || encoding == enc_jis_4) {\n// \t} else if (encoding == enc_gbk) { // unsupported yet\n\t} else {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n#ifdef TVP_TEXT_READ_ANSI_MBCS\nstatic ttstr DefaultReadEncoding = TJS_W(\"Shift_JIS\");\n#else\nstatic ttstr DefaultReadEncoding = TJS_W(\"UTF-8\");\n#endif\n//---------------------------------------------------------------------------\n// Interface to tTJSTextStream\n//---------------------------------------------------------------------------\n/*\n\tnote: encryption of mode 0 or 1 ( simple crypt ) does never intend data pretection\n\t\t  security.\n*/\nclass tTVPTextReadStream : public iTJSTextReadStream\n{\n\ttTJSBinaryStream * Stream;\n\tbool DirectLoad;\n\ttjs_char *Buffer;\n\tsize_t BufferLen;\n\ttjs_char *BufferPtr;\n\ttjs_int CryptMode;\n\npublic:\n\ttTVPTextReadStream(const ttstr  & name, const ttstr & modestr)\n\t{\n\t\t// following syntax of modestr is currently supported.\n\t\t// oN: read from binary offset N (in bytes)\n\n#ifndef TVP_NO_CHECK_WIDE_CHAR_SIZE\n\t\tif(sizeof(tjs_char)  != 2)\n\t\t\tTVPThrowExceptionMessage( TVPTheHostIsNotA16BitUnicodeSystem );\n#endif\n\n\t\tStream = NULL;\n\t\tBuffer = NULL;\n\t\tDirectLoad = false;\n\t\tCryptMode = -1;\n\n\t\t// check o mode\n\t\tStream = TVPCreateStream(name, TJS_BS_READ);\n\n\t\ttjs_uint64 ofs = 0;\n\t\tconst tjs_char * o_ofs;\n\t\to_ofs = TJS_strchr(modestr.c_str(), TJS_W('o'));\n\t\tif(o_ofs != NULL)\n\t\t{\n\t\t\t// seek to offset\n\t\t\to_ofs++;\n\t\t\ttjs_char buf[256];\n\t\t\tint i;\n\t\t\tfor(i = 0; i < 255; i++)\n\t\t\t{\n\t\t\t\tif(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9'))\n\t\t\t\t\tbuf[i] = o_ofs[i];\n\t\t\t\telse break;\n\t\t\t}\n\t\t\tbuf[i] = 0;\n\t\t\tofs = ttstr(buf).AsInteger();\n\t\t\tStream->SetPosition(ofs);\n\t\t}\n\n\t\t// check first of the file - whether the file is unicode\n\t\ttry\n\t\t{\n\t\t\ttjs_uint8 mark[3] = {0,0};\n\t\t\tStream->Read(mark, 3);\n\t\t\tif(mark[0] == 0xff && mark[1] == 0xfe)\n\t\t\t{\n\t\t\t\t// unicode\n\t\t\t\tStream->SetPosition(ofs + 2);\n\t\t\t\tDirectLoad = true;\n\t\t\t}\n\t\t\telse if(mark[0] == 0xfe && mark[1] == 0xfe)\n\t\t\t{\n\t\t\t\t// ciphered text or compressed\n\t\t\t\ttjs_uint8 mode = mark[2];\n\t\t\t\tif(mode != 0 && mode != 1 && mode != 2)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPUnsupportedCipherMode, name);\n\t\t\t\t\t// currently only mode0 and mode1, and compressed (mode2) are supported\n\t\t\t\tCryptMode = mode;\n\t\t\t\tDirectLoad = CryptMode != 2;\n\n\t\t\t\tStream->Read(mark, 2); // original bom code comes here (is not compressed)\n\t\t\t\tif(mark[0] != 0xff || mark[1] != 0xfe)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPUnsupportedCipherMode, name);\n\n\n\t\t\t\tif(CryptMode == 2)\n\t\t\t\t{\n\t\t\t\t\t// compressed text stream\n\t\t\t\t\ttjs_uint64 compressed = Stream->ReadI64LE();\n\t\t\t\t\ttjs_uint64 uncompressed = Stream->ReadI64LE();\n\t\t\t\t\tif(compressed != (unsigned long)compressed ||\n\t\t\t\t\t\tuncompressed != (unsigned long)uncompressed)\n\t\t\t\t\t\tTVPThrowExceptionMessage(TVPUnsupportedCipherMode, name);\n\t\t\t\t\t\t\t// too large stream\n\t\t\t\t\tunsigned long destlen ;\n\t\t\t\t\ttjs_uint8 *nbuf = new tjs_uint8[(unsigned long)compressed + 1];\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tStream->ReadBuffer(nbuf, (unsigned long)compressed);\n\t\t\t\t\t\tBuffer = new tjs_char [ (BufferLen = (destlen =\n\t\t\t\t\t\t\t\t(unsigned long)uncompressed) / 2) + 1];\n\t\t\t\t\t\tint result = uncompress( /* uncompress from zlib */\n\t\t\t\t\t\t\t(unsigned char*)Buffer,\n\t\t\t\t\t\t\t&destlen, (unsigned char*)nbuf,\n\t\t\t\t\t\t\t(unsigned long)compressed);\n\t\t\t\t\t\tif(result != Z_OK ||\n\t\t\t\t\t\t\tdestlen != (unsigned long)uncompressed)\n\t\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPUnsupportedCipherMode, name);\n\t\t\t\t\t\t\t// uncompression failed.\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\tBuffer[BufferLen] = 0;\n\t\t\t\t\tBufferPtr = Buffer;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// check UTF-8 BOM\n\t\t\t\tif(mark[0] == 0xef && mark[1] == 0xbb && mark[2] == 0xbf) {\n\t\t\t\t\t// UTF-8 BOM\n\t\t\t\t\ttjs_uint size = (tjs_uint)(Stream->GetSize() - 3) - ofs;\n\t\t\t\t\ttjs_uint8 *nbuf = new tjs_uint8[size + 1];\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tStream->ReadBuffer(nbuf, size);\n\t\t\t\t\t\tnbuf[size] = 0; // terminater\n\t\t\t\t\t\tBufferLen = TVPUtf8ToWideCharString((const char*)nbuf, NULL);\n\t\t\t\t\t\tif(BufferLen == (size_t)-1) TVPThrowExceptionMessage(TJSNarrowToWideConversionError);\n\t\t\t\t\t\tBuffer = new tjs_char [ BufferLen +1];\n\t\t\t\t\t\tTVPUtf8ToWideCharString((const char*)nbuf, Buffer);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\tBuffer[BufferLen] = 0;\n\t\t\t\t\tBufferPtr = Buffer;\n\t\t\t\t} else {\n\t\t\t\t\t// ansi/mbcs\n\t\t\t\t\t// read whole and hold it\n\t\t\t\t\tStream->SetPosition(ofs);\n\t\t\t\t\ttjs_uint size = (tjs_uint)(Stream->GetSize()) - ofs;\n\t\t\t\t\ttjs_uint8 *nbuf = new tjs_uint8[size + 1];\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tStream->ReadBuffer(nbuf, size);\n\t\t\t\t\t\tnbuf[size] = 0; // terminater\n\t\t\t\t\t\tBufferLen = TextStream_mbstowcs(NULL, (tjs_nchar*)nbuf, 0);\n\t\t\t\t\t\tif (BufferLen == (size_t)-1) {\n\t\t\t\t\t\t\tttstr msg(TVPGetMessageByLocale(\"err_narrow_to_wide\"));\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(msg.c_str());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tBuffer = new tjs_char [ BufferLen +1];\n\t\t\t\t\t\tTextStream_mbstowcs(Buffer, (tjs_nchar*)nbuf, BufferLen);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tdelete [] nbuf;\n\t\t\t\t\tBuffer[BufferLen] = 0;\n\t\t\t\t\tBufferPtr = Buffer;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete Stream; Stream = NULL;\n\t\t\tthrow;\n\t\t}\n\t}\n\n\n\t~tTVPTextReadStream()\n\t{\n\t\tif(Stream) delete Stream;\n\t\tif(Buffer) delete [] Buffer;\n\t}\n\n\ttjs_uint TJS_INTF_METHOD Read(tTJSString & targ, tjs_uint size)\n\t{\n\t\tif(DirectLoad)\n\t\t{\n\t\t\tif(sizeof(tjs_char) == 2)\n\t\t\t{\n\t\t\t\tif(size == 0) size = static_cast<tjs_uint>(Stream->GetSize() - Stream->GetPosition());\n\t\t\t\tif(!size)\n\t\t\t\t{\n\t\t\t\t\ttarg.Clear();\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\ttjs_char *buf = targ.AllocBuffer(size);\n\t\t\t\ttjs_uint read = Stream->Read(buf, size * 2); // 2 = BMP unicode size\n\t\t\t\tread /= 2;\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\t\t\t// re-order input\n\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t{\n\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\tbuf[i] = ((ch >> 8) & 0xff) + ((ch & 0xff) << 8);\n\t\t\t\t}\n#endif\n\t\t\t\tif(CryptMode == 0)\n\t\t\t\t{\n\t\t\t\t\t// simple crypt\n\t\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\t\tif(ch >= 0x20) buf[i] = ch ^ (((ch&0xfe) << 8)^1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(CryptMode == 1)\n\t\t\t\t{\n\t\t\t\t\t// simple crypt\n\t\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\t\tch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1);\n\t\t\t\t\t\tbuf[i] = ch;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbuf[read] = 0;\n\t\t\t\ttarg.FixLen();\n\t\t\t\treturn read;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// sizeof(tjs_char) is 4\n\t\t\t\t// FIXME: NOT TESTED CODE\n\t\t\t\tif(size == 0) size = static_cast<tjs_uint>(Stream->GetSize() - Stream->GetPosition());\n\t\t\t\ttjs_uint16 *buf = new tjs_uint16[size / 2];\n\t\t\t\ttjs_uint read;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tread = Stream->Read(buf, size * 2); // 2 = BMP unicode size\n\t\t\t\t\tread /= 2;\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\t\t\t\t// re-order input\n\t\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\t\tbuf[i] = ((ch >> 8) & 0xff) + ((ch & 0xff) << 8);\n\t\t\t\t\t}\n#endif\n\t\t\t\t\tif(CryptMode == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// simple crypt (buggy version)\n\t\t\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\t\t\tif(ch >= 0x20) buf[i] = ch ^ (((ch&0xfe) << 8)^1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(CryptMode == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// simple crypt\n\t\t\t\t\t\tfor(tjs_uint i = 0; i<read; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_char ch = buf[i];\n\t\t\t\t\t\t\tch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1);\n\t\t\t\t\t\t\tbuf[i] = ch;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbuf[read] = 0;\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\tdelete [] buf;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\ttarg = TVPStringFromBMPUnicode(buf);\n\t\t\t\tdelete [] buf;\n\t\t\t\treturn read;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(size == 0) size = (tjs_uint)BufferLen;\n\t\t\tif(size)\n\t\t\t{\n\t\t\t\ttjs_char *buf = targ.AllocBuffer(size);\n\t\t\t\tTJS_strncpy(buf, BufferPtr, size);\n\t\t\t\tbuf[size] = 0;\n\t\t\t\tBufferPtr += size;\n\t\t\t\tBufferLen -= size;\n\t\t\t\ttarg.FixLen();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttarg.Clear();\n\t\t\t}\n\t\t\treturn size;\n\t\t}\n\t}\n\n\tvoid TJS_INTF_METHOD Destruct() { delete this; }\n\n};\n//---------------------------------------------------------------------------\nclass tTVPTextWriteStream : public iTJSTextWriteStream\n{\n\t// TODO: 32bit wchar_t support\n\n\n        static const tjs_uint COMPRESSION_BUFFER_SIZE = 1024 * 1024;\n\n\ttTJSBinaryStream * Stream;\n\ttjs_int CryptMode;\n\t\t// -1 for no-crypt\n\t\t// 0: (unused)\t(old buggy crypt mode)\n\t\t// 1: simple crypt\n\t\t// 2: complessed\n    int CompressionLevel; // compression level of zlib\n\n\tz_stream_s *ZStream;\n\ttjs_uint CompressionSizePosition;\n\ttjs_nchar *CompressionBuffer;\n\tbool CompressionFailed;\n\npublic:\n\ttTVPTextWriteStream(const ttstr & name, const ttstr &modestr)\n\t{\n\t\t// modestr supports following modes:\n\t\t// dN: deflate(compress) at mode N ( currently not implemented )\n\t\t// cN: write in cipher at mode N ( currently n is ignored )\n\t\t// zN: write with compress at mode N ( N is compression level )\n\t\t// oN: write from binary offset N (in bytes)\n\t\tStream = NULL;\n\t\tCryptMode = -1;\n\t\tCompressionLevel = Z_DEFAULT_COMPRESSION;\n\t\tZStream = NULL;\n\t\tCompressionSizePosition = 0;\n\t\tCompressionBuffer = NULL;\n\t\tCompressionFailed = false;\n\n\t\t// check c/z mode\n\t\tconst tjs_char *p;\n\t\tif((p = TJS_strchr(modestr.c_str(), TJS_W('c'))) != NULL)\n\t\t{\n\t\t\tCryptMode = 1; // simple crypt\n\t\t\tif(p[1] >= TJS_W('0') && p[1] <= TJS_W('9'))\n\t\t\t\tCryptMode = p[1] - TJS_W('0');\n\t\t}\n\n\t\tif((p = TJS_strchr(modestr.c_str(), TJS_W('z'))) != NULL)\n\t\t{\n\t\t\tCryptMode = 2; // compressed (cannot be with 'c')\n\t\t\tif(p[1] >= TJS_W('0') && p[1] <= TJS_W('9'))\n\t\t\t\tCompressionLevel = p[1] - TJS_W('0');\n\t\t}\n\n\t\tif(CryptMode != -1 && CryptMode != 1 && CryptMode != 2)\n\t\t\tTVPThrowExceptionMessage(TVPUnsupportedModeString,\n\t\t\t\tTJS_W(\"unsupported cipher mode\"));\n\n\t\t// check o mode\n\t\tconst tjs_char * o_ofs;\n\t\to_ofs = TJS_strchr(modestr.c_str(), TJS_W('o'));\n\t\tif(o_ofs != NULL)\n\t\t{\n\t\t\t// seek to offset\n\t\t\to_ofs++;\n\t\t\ttjs_char buf[256];\n\t\t\tint i;\n\t\t\tfor(i = 0; i < 255; i++)\n\t\t\t{\n\t\t\t\tif(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9'))\n\t\t\t\t\tbuf[i] = o_ofs[i];\n\t\t\t\telse break;\n\t\t\t}\n\t\t\tbuf[i] = 0;\n\t\t\ttjs_uint64 ofs = ttstr(buf).AsInteger();\n\t\t\tStream = TVPCreateStream(name, TJS_BS_UPDATE);\n\t\t\tStream->SetPosition(ofs);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tStream = TVPCreateStream(name, TJS_BS_WRITE);\n\t\t}\n\n\n\t\tif(CryptMode == 1 || CryptMode == 2)\n\t\t{\n\t\t\t// simple crypt or compressed\n\t\t\ttjs_uint8 crypt_mode_sig[4];\n\t\t\tcrypt_mode_sig[0] = crypt_mode_sig[1] = 0xfe;\n\t\t\tcrypt_mode_sig[2] = (tjs_uint8)CryptMode;\n\t\t\tcrypt_mode_sig[3] = 0;\n\t\t\tStream->WriteBuffer(crypt_mode_sig, 3);\n\t\t}\n\n\t\t// now output text stream will write unicode texts\n\t\tstatic tjs_uint8 bommark[4] = { 0xff, 0xfe,\n\t\t\t\t\t\t\t\t\t\t0x00, 0x00/*dummy 2bytes*/ };\n\t\tStream->WriteBuffer(bommark, 2);\n\n\t\tif(CryptMode == 2)\n\t\t{\n\t\t\t// allocate and initialize zlib straem\n\t\t\tZStream = new z_stream_s();\n\t\t\tZStream->zalloc = Z_NULL;\n\t\t\tZStream->zfree = Z_NULL;\n\t\t\tZStream->opaque = Z_NULL;\n\t\t\tif (deflateInit(ZStream, CompressionLevel) != Z_OK) {\n\t\t\t\tCompressionFailed = true;\n\t\t\t\tTVPThrowExceptionMessage(TVPCompressionFailed);\n\t\t\t}\n\n\t\t\tCompressionBuffer = new tjs_nchar[COMPRESSION_BUFFER_SIZE];\n\n\t\t\tZStream->next_in = NULL;\n\t\t\tZStream->avail_in = 0;\n\t\t\tZStream->next_out = reinterpret_cast<Bytef*>( CompressionBuffer );\n\t\t\tZStream->avail_out = COMPRESSION_BUFFER_SIZE;\n\n\t\t\t// Compression Size (write dummy)\n\t\t\tCompressionSizePosition = static_cast<tjs_uint>(Stream->GetPosition());\n\t\t\tWriteI64LE((tjs_uint64)0);\n\t\t\tWriteI64LE((tjs_uint64)0);\n\t\t}\n\t}\n\n\t~tTVPTextWriteStream()\n\t{\n\t\tif(CryptMode == 2)\n\t\t{\n\n\t\t\tif (! CompressionFailed) {\n\t\t\t\ttry {\n\t\t\t\t\t// close zlib stream\n\t\t\t\t\tint result = 0;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tresult = deflate(ZStream, Z_FINISH);\n\t\t\t\t\t\tif (result != Z_OK\n\t\t\t\t\t\t    && result != Z_STREAM_END) {\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPCompressionFailed);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tStream->WriteBuffer(CompressionBuffer, COMPRESSION_BUFFER_SIZE - ZStream->avail_out);\n\t\t\t\t\t\tZStream->next_out = reinterpret_cast<Bytef*>( CompressionBuffer );\n\t\t\t\t\t\tZStream->avail_out = COMPRESSION_BUFFER_SIZE;\n\t\t\t\t\t} while (result != Z_STREAM_END);\n\n\t\t\t\t\t// rollback and write compression size.\n\t\t\t\t\tStream->SetPosition(CompressionSizePosition);\n\t\t\t\t\tWriteI64LE((tjs_uint64)ZStream->total_out);\n\t\t\t\t\tWriteI64LE((tjs_uint64)ZStream->total_in);\n\t\t\t\t}\n\t\t\t\tcatch(...) {\n\t\t\t\t\t// delete zlib compress stream\n\t\t\t\t\tif (ZStream) {\n\t\t\t\t\t\tdeflateEnd(ZStream);\n\t\t\t\t\t\tdelete ZStream;\n\t\t\t\t\t}\n\t\t\t\t\tdelete[] CompressionBuffer;\n\t\t\t\t\tdelete Stream;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// delete zlib compress stream\n\t\t\tif (ZStream) {\n\t\t\t\tdeflateEnd(ZStream);\n\t\t\t\tdelete ZStream;\n\t\t\t}\n\t\t\tdelete[] CompressionBuffer;\n\n\t\t}\n\n\t\tif(Stream) delete Stream;\n\t}\n\n\tvoid WriteI64LE(tjs_uint64 v)\n\t{\n\t\t// write 64bit little endian value to the file.\n\t\ttjs_uint8 buf[8];\n\t\tbuf[0] = (tjs_uint8)(v\t>>\t(0*8));\n\t\tbuf[1] = (tjs_uint8)(v\t>>\t(1*8));\n\t\tbuf[2] = (tjs_uint8)(v\t>>\t(2*8));\n\t\tbuf[3] = (tjs_uint8)(v\t>>\t(3*8));\n\t\tbuf[4] = (tjs_uint8)(v\t>>\t(4*8));\n\t\tbuf[5] = (tjs_uint8)(v\t>>\t(5*8));\n\t\tbuf[6] = (tjs_uint8)(v\t>>\t(6*8));\n\t\tbuf[7] = (tjs_uint8)(v\t>>\t(7*8));\n\n\t\tStream->WriteBuffer(buf, 8);\n\t}\n\n\tvoid TJS_INTF_METHOD Write(const ttstr & targ)\n\t{\n\t\ttjs_uint16 *buf;\n\t\ttjs_int len = targ.GetLen();\n\t\tbuf = new tjs_uint16 [len + 1];\n\t\ttry\n\t\t{\n\t\t\tconst tjs_char *src = targ.c_str();\n\t\t\ttjs_int i;\n\t\t\tfor(i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tif(src[i] < 0x10000)\n\t\t\t\t\tbuf[i] = src[i];\n\t\t\t\telse\n\t\t\t\t\tbuf[i] = TJS_W('?');\n\t\t\t}\n\t\t\tbuf[i] = 0;\n\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\t\ttjs_uint16 *p;\n\t\t\tif(CryptMode == 1)\n\t\t\t{\n\t\t\t\t// simple crypt\n\t\t\t\tp = buf;\n\t\t\t\tif(p)\n\t\t\t\t{\n\t\t\t\t\twhile(*p)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char ch = *p;\n\t\t\t\t\t\tch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1);\n\t\t\t\t\t\t*p = ch;\n\t\t\t\t\t\tp++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// re-order to little endian unicode text\n\t\t\tp = buf;\n\t\t\tif(p)\n\t\t\t{\n\t\t\t\twhile(*p)\n\t\t\t\t{\n\t\t\t\t\t*p = ((*p >> 8) & 0xff) + ((*p & 0xff) << 8);\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tWriteRawData(str.c_str(), len * sizeof(tjs_char));\n#else\n\t\t\tif(CryptMode == 1)\n\t\t\t{\n\t\t\t\t// simple crypt\n\t\t\t\ttjs_uint16 *p;\n\t\t\t\tp = buf;\n\t\t\t\tif(p)\n\t\t\t\t{\n\t\t\t\t\twhile(*p)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char ch = *p;\n\t\t\t\t\t\tch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1);\n\t\t\t\t\t\t*p = ch;\n\t\t\t\t\t\tp++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tWriteRawData(buf, len * sizeof(tjs_uint16));\n\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteRawData(buf, len * sizeof(tjs_uint16));\n\t\t\t}\n#endif\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete [] buf;\n\t\t\tthrow;\n\t\t}\n\t\tdelete [] buf;\n\t}\n\n\tvoid WriteRawData(void *ptr, size_t size)\n\t{\n\t\tif(CryptMode == 2)\n\t\t{\n\t\t\t// compressed with zlib stream.\n\t\t\tZStream->next_in = (Bytef*)ptr;\n\t\t\tZStream->avail_in = (uInt)size;\n\n\t\t\twhile (ZStream->avail_in > 0) {\n\t\t\t\tint result = deflate(ZStream, Z_NO_FLUSH);\n\t\t\t\tif (result != Z_OK) {\n\t\t\t\t\tCompressionFailed = true;\n\t\t\t\t\tTVPThrowExceptionMessage(TVPCompressionFailed);\n\t\t\t\t}\n\t\t\t\tif (ZStream->avail_out == 0) {\n\t\t\t\t\tStream->WriteBuffer(CompressionBuffer, COMPRESSION_BUFFER_SIZE);\n\t\t\t\t\tZStream->next_out = reinterpret_cast<Bytef*>( CompressionBuffer );\n\t\t\t\t\tZStream->avail_out = COMPRESSION_BUFFER_SIZE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tStream->WriteBuffer(ptr, (tjs_uint)size); // write directly\n\t\t}\n\t}\n\n\tvoid TJS_INTF_METHOD Destruct() { delete this; }\n};\n//---------------------------------------------------------------------------\niTJSTextReadStream * TVPCreateTextStreamForRead(const ttstr & name,\n\tconst ttstr & modestr)\n{\n\treturn new tTVPTextReadStream(name, modestr);\n}\n//---------------------------------------------------------------------------\niTJSTextReadStream * TVPCreateTextStreamForReadByEncoding(const ttstr & name,\n\tconst ttstr & modestr)\n{\n\treturn new tTVPTextReadStream(name, modestr);\n}\n//---------------------------------------------------------------------------\niTJSTextWriteStream * TVPCreateTextStreamForWrite(const ttstr & name,\n\tconst ttstr & modestr)\n{\n\treturn new tTVPTextWriteStream(name, modestr);\n}\n//---------------------------------------------------------------------------\nvoid TVPSetDefaultReadEncoding(const ttstr& encoding)\n{\n\tDefaultReadEncoding = encoding;\n\tttstr codestr = encoding;  codestr.ToLowerCase();\n\tif (codestr == enc_gbk) {\n\t\tmbtowc_for_text_stream = gbk_mbtowc;\n\t} else if (codestr == enc_utf8 || codestr == enc_utf8_2) {\n\t\tmbtowc_for_text_stream = utf8_mbtowc;\n\t} else if (codestr == enc_jis || codestr == enc_jis_2 || codestr == enc_jis_3 || codestr == enc_jis_4) {\n\t\tmbtowc_for_text_stream = sjis_mbtowc;\n\t} else {\n\t\tTVPThrowExceptionMessage(TVPUnsupportedEncoding, encoding);\n\t}\n}\n//---------------------------------------------------------------------------\nconst tjs_char* TVPGetDefaultReadEncoding()\n{\n\treturn DefaultReadEncoding.c_str();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/base/TextStream.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text read/write stream\n//---------------------------------------------------------------------------\n#ifndef TextStreamH\n#define TextStreamH\n\n\n#include \"StorageIntf.h\"\n\n//---------------------------------------------------------------------------\n// TextStream Functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTJSTextReadStream *, TVPCreateTextStreamForRead, (const ttstr &name, const ttstr &modestr));\nTJS_EXP_FUNC_DEF(iTJSTextWriteStream *, TVPCreateTextStreamForWrite, (const ttstr &name, const ttstr &modestr));\nTJS_EXP_FUNC_DEF(void, TVPSetDefaultReadEncoding, (const ttstr& encoding));\nTJS_EXP_FUNC_DEF(const tjs_char*, TVPGetDefaultReadEncoding, ());\nbool TVPStringDecode(const void *p, int len, ttstr& result, ttstr encoding = \"utf8\");\nbool TVPStringEncode(const ttstr &s, std::string &result, ttstr encoding = \"utf8\");\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/base/UserEvent.h",
    "content": "\n\n#ifndef __USER_EVENT_H__\n#define __USER_EVENT_H__\n\n#ifndef WM_APP\n#define WM_APP 0x10000\n#endif\n#define TVP_EV_TIMER_THREAD\t\t\t(WM_APP + 1)\n#define TVP_EV_WAVE_SND_BUF_THREAD\t(TVP_EV_TIMER_THREAD + 1)\n#define TVP_EV_VSYNC_TIMING_THREAD\t(TVP_EV_WAVE_SND_BUF_THREAD + 1)\n#define TVP_EV_CONTINUE_LIMIT_THREAD\t(TVP_EV_VSYNC_TIMING_THREAD + 1)\n#define TVP_EV_DELIVER_EVENTS_DUMMY\t(TVP_EV_CONTINUE_LIMIT_THREAD + 1)\n#define TVP_EV_KEEP_ALIVE\t\t\t(TVP_EV_DELIVER_EVENTS_DUMMY + 1)\n#define TVP_EV_IMAGE_LOAD_THREAD\t(TVP_EV_KEEP_ALIVE + 1)\n#define TVP_EV_WINDOW_RELEASE\t\t(TVP_EV_IMAGE_LOAD_THREAD + 1)\n\n#endif // __USER_EVENT_H__\n\n"
  },
  {
    "path": "src/core/base/UtilStreams.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Stream related utilities / utility streams\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"UtilStreams.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"EventIntf.h\"\n#include \"StorageIntf.h\"\n#include <thread>\n#include <mutex>\n#include <condition_variable>\n#include \"Platform.h\"\n#include <codecvt>\n#include <locale>\n\n//---------------------------------------------------------------------------\n// tTVPLocalTempStorageHolder\n//---------------------------------------------------------------------------\n#define TVP_LOCAL_TEMP_COPY_BLOCK_SIZE 65536*2\ntTVPLocalTempStorageHolder::tTVPLocalTempStorageHolder(const ttstr & name)\n{\n\t// name must be normalized !!!\n\n\tFileMustBeDeleted = false;\n\tFolderMustBeDeleted = false;\n\tLocalName = TVPGetLocallyAccessibleName(name);\n\tif(LocalName.IsEmpty())\n\t{\n\t\t// file must be copied to local filesystem\n\n\t\t// note that the basename is much more important than the directory\n\t\t// which the file is to be in, so we create a temporary folder and\n\t\t// store the file in it.\n\n\t\tLocalFolder = TVPGetTemporaryName();\n\t\tLocalName = LocalFolder + TJS_W(\"/\") + TVPExtractStorageName(name);\n\t\tTVPCreateFolders(LocalFolder); // create temporary folder\n\t\tFolderMustBeDeleted = true;\n\t\tFileMustBeDeleted = true;\n\n\t\ttry\n\t\t{\n\t\t\t// copy to local file\n\t\t\ttTVPStreamHolder src(name);\n\t\t\ttTVPStreamHolder dest(LocalName, TJS_BS_WRITE|TJS_BS_DELETE_ON_CLOSE);\n\t\t\ttjs_uint8 * buffer = new tjs_uint8[TVP_LOCAL_TEMP_COPY_BLOCK_SIZE];\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttjs_uint read;\n\t\t\t\twhile(true)\n\t\t\t\t{\n\t\t\t\t\tread = src->Read(buffer, TVP_LOCAL_TEMP_COPY_BLOCK_SIZE);\n\t\t\t\t\tif(read == 0) break;\n\t\t\t\t\tdest->WriteBuffer(buffer, read);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tdelete [] buffer;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete [] buffer;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(FileMustBeDeleted) TVPRemoveFile(LocalName);\n\t\t\tif(FolderMustBeDeleted) TVPRemoveFolder(LocalFolder);\n\t\t\tthrow;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPLocalTempStorageHolder::~tTVPLocalTempStorageHolder()\n{\n\tif(FileMustBeDeleted) TVPRemoveFile(LocalName);\n\tif(FolderMustBeDeleted) TVPRemoveFolder(LocalFolder);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPMemoryStream\n//---------------------------------------------------------------------------\ntTVPMemoryStream::tTVPMemoryStream()\n{\n\tInit();\n}\n//---------------------------------------------------------------------------\ntTVPMemoryStream::tTVPMemoryStream(const void * block, tjs_uint size)\n{\n\tInit();\n\tBlock = (void*)block;\n\tif(!Block)\n\t{\n\t\tBlock = Alloc(size);\n\t\tif(!Block) TVPThrowExceptionMessage(TVPInsufficientMemory);\n\t}\n\telse\n\t{\n\t\tReference = true; // memory block was given\n\t}\n\tSize = size;\n\tAllocSize = size;\n\tCurrentPos = 0;\n}\n//---------------------------------------------------------------------------\ntTVPMemoryStream::~tTVPMemoryStream()\n{\n\tif(Block && !Reference) Free(Block);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPMemoryStream::Seek(tjs_int64 offset, tjs_int whence)\n{\n\ttjs_int64 newpos;\n\tswitch(whence)\n\t{\n\tcase TJS_BS_SEEK_SET:\n\t\tif(offset >= 0)\n\t\t{\n\t\t\tif(offset <= Size) CurrentPos = static_cast<tjs_uint>(offset);\n\t\t}\n\t\treturn CurrentPos;\n\n\tcase TJS_BS_SEEK_CUR:\n\t\tif((newpos = offset + (tjs_int64)CurrentPos) >= 0)\n\t\t{\n\t\t\ttjs_uint np = (tjs_uint)newpos;\n\t\t\tif(np <= Size) CurrentPos = np;\n\t\t}\n\t\treturn CurrentPos;\n\n\tcase TJS_BS_SEEK_END:\n\t\tif((newpos = offset + (tjs_int64)Size) >= 0)\n\t\t{\n\t\t\ttjs_uint np = (tjs_uint)newpos;\n\t\t\tif(np <= Size) CurrentPos = np;\n\t\t}\n\t\treturn CurrentPos;\n\t}\n\treturn CurrentPos;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPMemoryStream::Read(void *buffer, tjs_uint read_size)\n{\n\tif(CurrentPos + read_size >= Size)\n\t{\n\t\tread_size = Size - CurrentPos;\n\t}\n\n\tmemcpy(buffer, (tjs_uint8*)Block + CurrentPos, read_size);\n\n\tCurrentPos += read_size;\n\n\treturn read_size;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPMemoryStream::Write(const void *buffer, tjs_uint write_size)\n{\n\t// writing may increase the internal buffer size.\n\tif(Reference) TVPThrowExceptionMessage(TVPWriteError);\n\n\ttjs_uint newpos = CurrentPos + write_size;\n\tif(newpos >= AllocSize)\n\t{\n\t\t// exceeds AllocSize\n\t\ttjs_uint onesize;\n\t\tif(AllocSize < 64*1024) onesize = 4*1024;\n\t\telse if(AllocSize < 512*1024) onesize = 16*1024;\n\t\telse if(AllocSize < 4096*1024) onesize = 256*1024;\n\t\telse onesize = 2024*1024;\n\t\tAllocSize += onesize;\n\n\t\tif(CurrentPos + write_size >= AllocSize) // still insufficient ?\n\t\t{\n\t\t\tAllocSize = CurrentPos + write_size;\n\t\t}\n\n\t\tBlock = Realloc(Block, AllocSize);\n\n\t\tif(AllocSize && !Block)\n\t\t\tTVPThrowExceptionMessage(TVPInsufficientMemory);\n\t\t\t// this exception cannot be repaird; a fatal error.\n\t}\n\n\tmemcpy((tjs_uint8*)Block + CurrentPos, buffer, write_size);\n\n\tCurrentPos = newpos;\n\n\tif(CurrentPos > Size) Size = CurrentPos;\n\n\treturn write_size;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPMemoryStream::SetEndOfStorage()\n{\n\tif(Reference) TVPThrowExceptionMessage(TVPWriteError);\n\n\tSize = CurrentPos;\n\tAllocSize = Size;\n\tBlock = Realloc(Block, Size);\n\tif(Size && !Block)\n\t\tTVPThrowExceptionMessage(TVPInsufficientMemory);\n}\n//---------------------------------------------------------------------------\nvoid tTVPMemoryStream::Clear(void)\n{\n\tif(Block && !Reference) Free(Block);\n\tInit();\n}\n//---------------------------------------------------------------------------\nvoid tTVPMemoryStream::SetSize(tjs_uint size)\n{\n\tif(Reference) TVPThrowExceptionMessage(TVPWriteError);\n\n\tif(Size > size)\n\t{\n\t\t// decrease\n\t\tSize = size;\n\t\tAllocSize = size;\n\t\tBlock = Realloc(Block, size);\n\t\tif(CurrentPos > Size) CurrentPos = Size;\n\t\tif(size && !Block)\n\t\t\tTVPThrowExceptionMessage(TVPInsufficientMemory);\n\t}\n\telse\n\t{\n\t\t// increase\n\t\tAllocSize = size;\n\t\tSize = size;\n\t\tBlock = Realloc(Block, size);\n\t\tif(size && !Block)\n\t\t\tTVPThrowExceptionMessage(TVPInsufficientMemory);\n\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPMemoryStream::Init()\n{\n\tBlock = NULL;\n\tReference = false;\n\tSize = 0;\n\tAllocSize = 0;\n\tCurrentPos = 0;\n}\n//---------------------------------------------------------------------------\nvoid * tTVPMemoryStream::Alloc(size_t size)\n{\n\treturn TJS_malloc(size);\n}\n//---------------------------------------------------------------------------\nvoid * tTVPMemoryStream::Realloc(void *orgblock, size_t size)\n{\n\treturn TJS_realloc(orgblock, size);\n}\n//---------------------------------------------------------------------------\nvoid tTVPMemoryStream::Free(void *block)\n{\n\tTJS_free(block);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPPartialStream\n//---------------------------------------------------------------------------\ntTVPPartialStream::tTVPPartialStream(tTJSBinaryStream *stream, tjs_uint64 start,\n\ttjs_uint64 size)\n{\n\t// the stream given as a argument here will be owned by this instance,\n\t// and freed at the destruction.\n\n\tStream = stream;\n\tStart = start;\n\tSize = size;\n\tCurrentPos = 0;\n\n\ttry\n\t{\n\t\tStream->SetPosition(Start);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete Stream;\n\t\tStream = NULL;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPPartialStream::~tTVPPartialStream()\n{\n\tif(Stream) delete Stream;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPPartialStream::Seek(tjs_int64 offset, tjs_int whence)\n{\n\ttjs_int64 newpos;\n\tswitch(whence)\n\t{\n\tcase TJS_BS_SEEK_SET:\n\t\tnewpos = offset;\n\t\tif(offset >= 0 && offset <= static_cast<tjs_int64>(Size) )\n\t\t{\n\t\t\tnewpos += Start;\n\t\t\tCurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start;\n\t\t}\n\t\treturn CurrentPos;\n\n\tcase TJS_BS_SEEK_CUR:\n\t\tnewpos = offset + CurrentPos;\n\t\tif(offset >= 0 && offset <= static_cast<tjs_int64>(Size) )\n\t\t{\n\t\t\tnewpos += Start;\n\t\t\tCurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start;\n\t\t}\n\t\treturn CurrentPos;\n\n\tcase TJS_BS_SEEK_END:\n\t\tnewpos = offset + Size;\n\t\tif(offset >= 0 && offset <= static_cast<tjs_int64>(Size) )\n\t\t{\n\t\t\tnewpos += Start;\n\t\t\tCurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start;\n\t\t}\n\t\treturn CurrentPos;\n\t}\n\treturn CurrentPos;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPPartialStream::Read(void *buffer, tjs_uint read_size)\n{\n\tif(CurrentPos + read_size >= Size)\n\t{\n\t\tread_size = static_cast<tjs_uint>(Size - CurrentPos);\n\t}\n\n\ttjs_uint read = Stream->Read(buffer, read_size);\n\n\tCurrentPos += read;\n\n\treturn read;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPPartialStream::Write(const void *buffer, tjs_uint write_size)\n{\n\treturn 0;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPPartialStream::GetSize()\n{\n\treturn Size;\n}\n//---------------------------------------------------------------------------\n\n\n\nextern \"C\" {\n#include \"libarchive/archive.h\"\n#include \"libarchive/archive_entry.h\"\n}\n#if 0\nclass LibArchive_Archive : public tTVPArchive {\n\tstruct archive *_arc;\n\ttTJSBinaryStream *_stream;\n\tstatic const int BUFFER_SIZE = 16 * 1024;\n\ttjs_uint8 *_buffer = new tjs_uint8[BUFFER_SIZE];\n\tstd::vector<std::pair<ttstr, struct archive_entry *> > _filelist;\n\n\tvoid Clear() {\n\t\tif (_arc) {\n\t\t\tarchive_read_free(_arc);\n\t\t\t_arc = nullptr;\n\t\t}\n\t\tfor (std::pair<ttstr, struct archive_entry *> &it : _filelist) {\n\t\t\tarchive_entry_free(it.second);\n\t\t}\n\t\t_filelist.clear();\n\t}\n\npublic:\n\tLibArchive_Archive(const ttstr & name, tTJSBinaryStream *st) : tTVPArchive(name), _stream(st) {\n\t\t_arc = archive_read_new();\n\t}\n\t~LibArchive_Archive() {\n\t\tClear();\n\t\tif (_stream)\n\t\t\tdelete _stream;\n\t\tif (_buffer)\n\t\t\tdelete[] _buffer;\n\t}\n\n\tvirtual tjs_uint GetCount() { return _filelist.size(); }\n\tvirtual ttstr GetName(tjs_uint idx) { return _filelist[idx].first; }\n\tvirtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) {\n\t\tstruct archive_entry * entry = _filelist[idx].second;\n\t\ttjs_uint64 fileSize = archive_entry_size(entry);\n\t\tif (fileSize <= 0) return new tTVPMemoryStream();\n\t\treturn nullptr;\n\t}\n\n\tbool Open(bool normalizeFileName) {\n\t\tarchive_read_support_filter_all(_arc);\n\t\tarchive_read_support_format_all(_arc);\n\t\tarchive_read_set_seek_callback(_arc, seek_callback);\n\t\tarchive_read_open2(_arc, this, nullptr, read_callback, nullptr, nullptr);\n\n\t\tstruct archive_entry *entry = archive_entry_new2(_arc);\n\t\twhile (archive_read_next_header2(_arc, entry) == ARCHIVE_OK) {\n\t\t\tttstr filename(archive_entry_pathname_utf8(entry));\n\t\t\tif (normalizeFileName)\n\t\t\t\tNormalizeInArchiveStorageName(filename);\n\t\t\t_filelist.emplace_back(filename, entry);\n\t\t\tentry = archive_entry_new2(_arc);\n\t\t}\n\t\tarchive_entry_free(entry);\n\t\tif (normalizeFileName) {\n\t\t\tstd::sort(_filelist.begin(), _filelist.end(), [](const std::pair<ttstr, struct archive_entry*>& a, const std::pair<ttstr, struct archive_entry*>& b) {\n\t\t\t\treturn a.first < b.first;\n\t\t\t});\n\t\t}\n\t}\n\n\tvoid Detach() {\n\t\tClear();\n\t\t_stream = nullptr;\n\t}\n\n\tstatic la_ssize_t read_callback(struct archive *, void *_client_data, const void **_buffer) {\n\t\tLibArchive_Archive *_this = (LibArchive_Archive *)_client_data;\n\t\t*_buffer = _this->_buffer;\n\t\treturn _this->_stream->Read(_this->_buffer, BUFFER_SIZE);\n\t}\n\n\tstatic la_int64_t seek_callback(struct archive *, void *_client_data, la_int64_t offset, int whence) {\n\t\tLibArchive_Archive *_this = (LibArchive_Archive *)_client_data;\n\t\treturn _this->_stream->Seek(offset, whence);\n\t}\n\n\tstatic la_int64_t skip_callback(struct archive *, void *_client_data, la_int64_t request) {\n\t\tLibArchive_Archive *_this = (LibArchive_Archive *)_client_data;\n\t\treturn _this->_stream->Seek(request, TJS_BS_SEEK_CUR);\n\t}\n};\n\ntTVPArchive *TVPOpenLibArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) {\n\tLibArchive_Archive *arc = new LibArchive_Archive(name, st);\n\tif (arc->Open(normalizeFileName)) {\n\t\treturn arc;\n\t}\n\tarc->Detach();\n\tdelete arc;\n\treturn nullptr;\n}\n#endif\n\nstatic FILE *_fileopen(const std::string &strpath) {\n\tFILE *fp = fopen(strpath.c_str(), \"wb\");\n\tif (!fp) { // make dirs\n\t\tttstr path = TVPExtractStoragePath(strpath);\n\t\tTVPCreateFolders(path);\n\t\tfp = fopen(strpath.c_str(), \"wb\");\n\t}\n\treturn fp;\n}\n\nclass tTVPUnpackArchiveThread {\n\tstd::thread *ThreadObj;\n\tstd::mutex Mutex;\n\tstd::condition_variable Cond;\n\ttTVPUnpackArchive *Owner;\n\n\tvoid Entry() {\n\t\t{\n\t\t\tstd::unique_lock<std::mutex> lk(Mutex);\n\t\t\tCond.wait(lk);\n\t\t}\n\t\tOwner->Process();\n\t}\n\npublic:\n\ttTVPUnpackArchiveThread(tTVPUnpackArchive *owner) : Owner(owner) {\n\t\tThreadObj = new std::thread(&tTVPUnpackArchiveThread::Entry, this);\n\t}\n\n\t~tTVPUnpackArchiveThread() {\n\t\tif (ThreadObj->joinable()) {\n\t\t\tThreadObj->join();\n\t\t}\n\t\tdelete ThreadObj;\n\t}\n\n\tvoid Start() {\n\t\tCond.notify_all();\n\t}\n};\n\nclass tTVPUnpackArchiveImplWrap : public iTVPUnpackArchiveImpl {\n\ttTVPArchive *pTVPArc = nullptr;\n\ttjs_int64 _totalSize = 0;\n\tint _totalFileCount = 0;\n\npublic:\n\tvirtual ~tTVPUnpackArchiveImplWrap() {\n\t\tif (pTVPArc)\n\t\t\tpTVPArc->Release();\n\t}\n\tvirtual bool Open(const std::string &path) override {\n\t\tpTVPArc = TVPOpenArchive(path, false);\n\t\tint file_count = 0;\n\t\tif (pTVPArc) {\n\t\t\tfile_count = pTVPArc->GetCount();\n\t\t\t_totalSize = 0;\n\t\t\tfor (int i = 0; i < file_count; ++i) {\n\t\t\t\ttTJSBinaryStream *str = pTVPArc->CreateStreamByIndex(i);\n\t\t\t\tif (str) {\n\t\t\t\t\t_totalSize += str->GetSize();\n\t\t\t\t\tdelete str;\n\t\t\t\t}\n\t\t\t}\n\t\t\t_totalFileCount = file_count;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tvirtual int GetFileCount() override { return _totalFileCount; }\n\tvirtual tjs_int64 GetTotalSize() override { return _totalSize; }\n\tvirtual void ExtractTo(const std::string &OutPath) {\n\t\ttjs_uint64 total_size = 0;\n\t\tint file_count = pTVPArc->GetCount();\n\t\tstd::vector<char> buffer; buffer.resize(4 * 1024 * 1024);\n\t\tfor (int index = 0; index < file_count && !StopRequired; ++index) {\n\t\t\ttjs_uint64 file_size = 0;\n\t\t\tstd::string filename = pTVPArc->GetName(index).AsStdString();\n\t\t\tif (filename.size() > 600) continue;\n\t\t\tstd::string fullpath = OutPath + filename;\n\t\t\tFILE *fp = _fileopen(fullpath);\n\t\t\tif (!fp) {\n\t\t\t\t_callbacks->FuncOnError(ARCHIVE_FAILED, \"Cannot open output file\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttTJSBinaryStream *str = pTVPArc->CreateStreamByIndex(index);\n\t\t\tif (!str) {\n\t\t\t\t_callbacks->FuncOnError(ARCHIVE_FAILED, \"Cannot open archive stream\");\n\t\t\t\tfclose(fp);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t_callbacks->FuncOnNewFile(index, filename.c_str(), str->GetSize());\n\t\t\twhile (!StopRequired) {\n\t\t\t\ttjs_uint readed = str->Read(&buffer.front(), buffer.size());\n\t\t\t\tif (readed == 0) break;\n\t\t\t\tif (readed != fwrite(&buffer.front(), 1, readed, fp)) {\n\t\t\t\t\t_callbacks->FuncOnError(ARCHIVE_FAILED, \"Fail to write file.\\nPlease check the disk space.\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfile_size += readed;\n\t\t\t\ttotal_size += readed;\n\t\t\t\t_callbacks->FuncOnProgress(total_size, file_size);\n\t\t\t\tif (readed < buffer.size())\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdelete str;\n\t\t\tfclose(fp);\n\t\t}\n\t\tpTVPArc->Release();\n\t\tpTVPArc = nullptr;\n\t\t_callbacks->FuncOnEnded();\n\t}\n};\n\nclass tTVPUnpackArchiveImplLibArchive : public iTVPUnpackArchiveImpl {\nprotected:\n\tstruct archive* ArcObj = nullptr;\n\ttjs_int64 _totalSize = 0;\n\tint _totalFileCount = 0;\n\t//FILE *FpIn = nullptr;\n\tstd::string _filepath;\n\n\tstatic const char * _onPassphraseCallback(struct archive *, void *clientdata);\n\tstd::string onPassphraseCallback();\npublic:\n\tvirtual ~tTVPUnpackArchiveImplLibArchive() {\n// \t\tif (FpIn) {\n// \t\t\tfclose(FpIn);\n// \t\t\tFpIn = nullptr;\n// \t\t}\n\t\tif (ArcObj) {\n\t\t\tarchive_read_free(ArcObj);\n\t\t\tArcObj = nullptr;\n\t\t}\n\t}\n\n\tvirtual bool Open(const std::string &path) override {\n\t\t//FpIn = fopen(path.c_str(), \"rb\");\n\t\t_filepath = path;\n\t\tint file_count = 0;\n\t\ttjs_uint64 size_count = 0;\n\t\tArcObj = archive_read_new();\n\t\tarchive_read_support_filter_all(ArcObj);\n\t\tarchive_read_support_format_all(ArcObj);\n\t\tarchive_read_set_passphrase_callback(ArcObj, this, _onPassphraseCallback);\n#ifdef _MSC_VER\n\t\tint r = archive_read_open_filename_w(ArcObj, ttstr(path).c_str(), 32768);\n#else\n\t\tint r = archive_read_open_filename(ArcObj, path.c_str(), 32768);\n#endif\n\n\t\tif (r < ARCHIVE_OK) {\n// \t\t\tfclose(FpIn);\n// \t\t\tFpIn = nullptr;\n\t\t\tarchive_read_free(ArcObj);\n\t\t\tArcObj = nullptr;\n\t\t\treturn false;\n\t\t}\n\t\tif (archive_read_has_encrypted_entries(ArcObj) > 0) {\n\t\t\tstd::string psw = onPassphraseCallback();\n\t\t\tif (psw.empty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tarchive_read_add_passphrase(ArcObj, psw.c_str());\n\t\t}\n\t\tr = 0;\n\t\twhile (true) {\n\t\t\tstruct archive_entry *entry;\n\t\t\tint r = archive_read_next_header(ArcObj, &entry);\n\t\t\tif (r == ARCHIVE_EOF) {\n\t\t\t\tr = ARCHIVE_OK;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (r < ARCHIVE_OK)\n\t\t\t\t_callbacks->FuncOnError(r, archive_error_string(ArcObj));\n\t\t\tif (r < ARCHIVE_WARN)\n\t\t\t\tbreak;\n\t\t\t++file_count;\n\t\t\tsize_count += archive_entry_size(entry);\n\t\t}\n\n\t\t_totalSize = size_count;\n\t\t_totalFileCount = file_count;\n\t\tarchive_read_close(ArcObj);\n\t\tarchive_read_free(ArcObj);\n\t\tArcObj = nullptr;\n\t\treturn true;\n\t}\n\n\tvirtual int GetFileCount() override { return _totalFileCount; }\n\tvirtual tjs_int64 GetTotalSize() override { return _totalSize; }\n\n\tvirtual void ExtractTo(const std::string &OutPath) {\n\t\ttjs_uint64 total_size = 0;\n\t\t// fseek(FpIn, 0, SEEK_SET);\n\t\tArcObj = archive_read_new();\n\t\tarchive_read_support_filter_all(ArcObj);\n\t\tarchive_read_support_format_all(ArcObj);\n#ifdef _MSC_VER\n\t\tint r = archive_read_open_filename_w(ArcObj, ttstr(_filepath).c_str(), 32768);\n#else\n\t\tint r = archive_read_open_filename(ArcObj, _filepath.c_str(), 32768);\n#endif\n\n\t\tif (r < ARCHIVE_OK) {\n\t\t\t_callbacks->FuncOnError(r, archive_error_string(ArcObj));\n\t\t\t_callbacks->FuncOnEnded();\n\t\t\treturn;\n\t\t}\n\t\tfor (int index = 0; !StopRequired; ++index) {\n\t\t\tstruct archive_entry *entry;\n\t\t\tint r = archive_read_next_header(ArcObj, &entry);\n\t\t\tif (r == ARCHIVE_EOF) {\n\t\t\t\tr = ARCHIVE_OK;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (r < ARCHIVE_OK)\n\t\t\t\t_callbacks->FuncOnError(r, archive_error_string(ArcObj));\n\t\t\tif (r < ARCHIVE_WARN)\n\t\t\t\tbreak;\n\t\t\tconst char *sfilename = archive_entry_pathname_utf8(entry);\n\t\t\tstd::string filename;\n\t\t\tif (sfilename) {\n\t\t\t\tfilename = sfilename;\n\t\t\t} else {\n\t\t\t\tconst wchar_t* wfilename = archive_entry_pathname_w(entry);\n\t\t\t\tstd::wstring_convert<std::codecvt_utf8<wchar_t> > cvt;\n\t\t\t\tfilename = cvt.to_bytes(wfilename);\n\t\t\t}\n\t\t\tif (filename.back() == '/' || filename.back() == '\\\\') {\n\t\t\t\t// skip folder\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstd::string fullpath = OutPath + filename;\n\t\t\tFILE *fp = _fileopen(fullpath);\n\t\t\tif (!fp) {\n\t\t\t\t_callbacks->FuncOnError(ARCHIVE_FAILED, \"Cannot open output file\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t_callbacks->FuncOnNewFile(index, filename, archive_entry_size(entry));\n\n\t\t\tconst void *buff;\n\t\t\tsize_t size;\n\t\t\tla_int64_t offset;\n\t\t\ttjs_uint64 file_size = 0;\n\t\t\tconst char *errmsg;\n\t\t\twhile (!StopRequired) {\n\t\t\t\tr = archive_read_data_block(ArcObj, &buff, &size, &offset);\n\t\t\t\tif (r == ARCHIVE_EOF) {\n\t\t\t\t\tr = ARCHIVE_OK;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (r < ARCHIVE_OK) {\n\t\t\t\t\terrmsg = archive_error_string(ArcObj);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (size != fwrite(buff, 1, size, fp)) {\n\t\t\t\t\tr = ARCHIVE_FAILED;\n\t\t\t\t\terrmsg = \"Fail to write file.\\nPlease check the disk space.\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfile_size += size;\n\t\t\t\ttotal_size += size;\n\t\t\t\t_callbacks->FuncOnProgress(total_size, file_size);\n\t\t\t}\n\t\t\tfclose(fp);\n\t\t\tif (r < ARCHIVE_OK)\n\t\t\t\t_callbacks->FuncOnError(r, errmsg);\n\t\t\tif (r < ARCHIVE_WARN)\n\t\t\t\tbreak;\n\t\t\tif (archive_entry_mtime_is_set(entry)) {\n\t\t\t\tTVP_utime(fullpath.c_str(), archive_entry_mtime(entry));\n\t\t\t}\n\t\t}\n\t\tarchive_read_close(ArcObj);\n\t\t_callbacks->FuncOnEnded();\n\t}\n};\n\nstd::string tTVPUnpackArchiveImplLibArchive::onPassphraseCallback()\n{\n\treturn _callbacks->FuncPassword();\n}\n\nconst char * tTVPUnpackArchiveImplLibArchive::_onPassphraseCallback(struct archive *, void *clientdata)\n{\n\tstatic std::string psw = ((tTVPUnpackArchiveImplLibArchive*)clientdata)->onPassphraseCallback();\n\treturn psw.c_str();\n}\n\nextern \"C\" {\n#include \"p7zip/C/7z.h\"\n#include \"p7zip/C/7zFile.h\"\n#include \"p7zip/C/7zCrc.h\"\n}\n#include <fcntl.h>\n#include <unistd.h>\n#include \"win32io.h\"\n\nstatic ISzAlloc allocImp = {\n\t[](void *p, size_t size) -> void * { return malloc(size); },\n\t[](void *p, void *addr) { free(addr); }\n};\nclass tTVPUnpackArchiveImpl7Zip : public tTVPUnpackArchiveImplLibArchive {\n\tint _stream;\n\tCLookToRead lookStream;\n\tstruct CSeekInStream : public ISeekInStream {\n\t\ttTVPUnpackArchiveImpl7Zip *Host;\n\t} archiveStream;\n\n\tSRes StreamRead(void *buf, size_t *size) {\n\t\t*size = read(_stream, buf, *size);\n\t\treturn SZ_OK;\n\t}\n\tSRes StreamSeek(Int64 *pos, ESzSeek origin) {\n\t\tint whence = SEEK_SET;\n\t\tswitch (origin) {\n\t\tcase SZ_SEEK_CUR: whence = SEEK_CUR; break;\n\t\tcase SZ_SEEK_END: whence = SEEK_END; break;\n\t\tcase SZ_SEEK_SET: whence = SEEK_SET; break;\n\t\tdefault: break;\n\t\t}\n\n\t\t*pos = lseek64(_stream, *pos, whence);\n\t\treturn SZ_OK;\n\t}\n\npublic:\n\ttTVPUnpackArchiveImpl7Zip() {\n\t\tarchiveStream.Host = this;\n\t\tarchiveStream.Read = [](void *p, void *buf, size_t *size)->SRes {return ((CSeekInStream*)p)->Host->StreamRead(buf, size); };\n\t\tarchiveStream.Seek = [](void *p, Int64 *pos, ESzSeek origin)->SRes {return ((CSeekInStream*)p)->Host->StreamSeek(pos, origin); };\n\t\tLookToRead_CreateVTable(&lookStream, false);\n\t\tlookStream.realStream = &archiveStream;\n\t\tif (!g_CrcTable[1]) CrcGenerateTable();\n\t}\n\n\tvirtual bool Open(const std::string &path) override {\n\t\t// FpIn = fopen(path.c_str(), \"rb\");\n\t\t_filepath = path;\n\t\tCSzArEx db;\n\t\tSzArEx_Init(&db);\n\t\t_stream = open(path.c_str(), O_RDONLY, 0666);\n\t\tif (!_stream)\n\t\t\treturn false;\n\n\t\tSRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocImp);\n\t\tif (res != SZ_OK) return false;\n\t\t_totalFileCount = 0;\n\t\t_totalSize = 0;\n\t\tfor (int i = 0; i < db.NumFiles; i++) {\n\t\t\tsize_t offset = 0;\n\t\t\tsize_t outSizeProcessed = 0;\n\t\t\tbool isDir = SzArEx_IsDir(&db, i);\n\t\t\tif (isDir) continue;\n\t\t\t++_totalFileCount;\n\t\t\t_totalSize += SzArEx_GetFileSize(&db, i);\n\t\t}\n\t\tSzArEx_Free(&db, &allocImp);\n\t\tclose(_stream);\n\t\treturn true;\n\t}\n};\n\n#include \"unrar/raros.hpp\"\n#include \"unrar/dll.hpp\"\nclass tTVPUnpackArchiveImplUnRAR : public iTVPUnpackArchiveImpl {\n\tstd::string _archivePath;\n\ttjs_int _filecount;\n\ttjs_int64 _totalSize, _totalProcessedBytes, _curProcessedBytes;\n\tstd::string _lastUsedPassword;\n\tstd::mutex _mutex;\n\tstd::condition_variable _cond;\n\t\n\tbool _reqBreak = false;\n\tstruct RARArc {\n\t\tRAROpenArchiveDataEx _archiveData;\n\t\tvoid *_handle = nullptr;\n\t\tRARArc() {}\n\t\t~RARArc() {\n\t\t\tClose();\n\t\t}\n\t\tbool Open(const std::string &path, int mode) {\n\t\t\tmemset(&_archiveData, 0, sizeof(_archiveData));\n#ifdef _MSC_VER\n\t\t\tttstr _path(path);\n\t\t\t_archiveData.ArcNameW = (wchar_t*)_path.c_str();\n#else\n\t\t\t_archiveData.ArcName = (char *)path.c_str();\n#endif\n\t\t\t_archiveData.OpenMode = mode;\n\t\t\t_handle = RAROpenArchiveEx(&_archiveData);\n\t\t\treturn !!_handle;\n\t\t}\n\t\tvoid Close() {\n\t\t\tif (_handle) RARCloseArchive(_handle);\n\t\t\t_handle = nullptr;\n\t\t}\n\t};\n\tint OnCallback(UINT msg, LPARAM P1, LPARAM P2) {\n\t\tswitch (msg) {\n\t\tcase UCM_CHANGEVOLUME:\n\t\tcase UCM_CHANGEVOLUMEW:\n\t\t\treturn -1; // manual change multi-volume file name is not supported yet\n\t\tcase UCM_NEEDPASSWORD: {\n\t\t\tbool hasPsw = !_lastUsedPassword.empty();\n\t\t\tif (!hasPsw) {\n\t\t\t\t_lastUsedPassword = _callbacks->FuncPassword();\n\t\t\t}\n\t\t\tif (_lastUsedPassword.empty()) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tint len = _lastUsedPassword.size();\n\t\t\tif (len > P2) len = P2;\n\t\t\tstrncpy((char*)P1, _lastUsedPassword.c_str(), len);\n\t\t\tif (hasPsw)\n\t\t\t\t_lastUsedPassword.clear();\n\t\t\treturn 0;\n\t\t}\n\t\tcase UCM_PROCESSDATA:\n\t\t\t_totalProcessedBytes += P2;\n\t\t\t_curProcessedBytes += P2;\n\t\t\t_callbacks->FuncOnProgress(_totalProcessedBytes, _curProcessedBytes);\n\t\t\treturn _reqBreak ? -1 : 0;\n\t\t}\n\t\treturn -1;\n\t}\npublic:\n\tvirtual ~tTVPUnpackArchiveImplUnRAR() {\n\t}\n\tvirtual bool Open(const std::string &path) override {\n\t\t_archivePath = path;\n\t\tRARArc arc;\n\t\tif (!arc.Open(_archivePath, RAR_OM_LIST)) {\n\t\t\treturn false;\n\t\t}\n\t\tRARSetCallback(arc._handle, [](UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)->int {\n\t\t\treturn ((tTVPUnpackArchiveImplUnRAR*)UserData)->OnCallback(msg, P1, P2);\n\t\t}, (LPARAM)this);\n\t\t\n\t\tarc._handle;\n\t\tRARHeaderData headerData;\n\t\t_totalSize = 0;\n\t\t_filecount = 0;\n\t\twhile (1) {\n\t\t\tRARHeaderDataEx headerData;\n\t\t\tmemset(&headerData, 0, sizeof(headerData));\n\t\t\tint result = RARReadHeaderEx(arc._handle, &headerData);\n\t\t\tif (result != 0) {\n\t\t\t\tif (result != ERAR_END_ARCHIVE) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t_totalSize += ((tjs_int64)headerData.UnpSizeHigh << 32) | headerData.UnpSize;\n\t\t\t++_filecount;\n\t\t\t// Find next file\n\t\t\tresult = RARProcessFile(arc._handle, RAR_SKIP, NULL, NULL);\n\t\t\tif (result != 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\tvirtual int GetFileCount() override { return _filecount; }\n\tvirtual tjs_int64 GetTotalSize() override { return _totalSize; }\n\tvirtual void ExtractTo(const std::string &path) override {\n\t\tRARArc arc;\n\t\tif (!arc.Open(_archivePath, RAR_OM_EXTRACT)) {\n\t\t\t_callbacks->FuncOnError(1001, \"Cannot open file\");\n\t\t\treturn;\n\t\t}\n\t\tRARSetCallback(arc._handle, [](UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)->int {\n\t\t\treturn ((tTVPUnpackArchiveImplUnRAR*)UserData)->OnCallback(msg, P1, P2);\n\t\t}, (LPARAM)this);\n\t\tRARHeaderData headerData;\n\t\t\n\t\tfor (int counter = 0; ;++counter) {\n\t\t\tRARHeaderDataEx headerData;\n\t\t\tmemset(&headerData, 0, sizeof(headerData));\n\t\t\tint result = RARReadHeaderEx(arc._handle, &headerData);\n\t\t\tif (result != 0) {\n\t\t\t\tif (result != ERAR_END_ARCHIVE) {\n\t\t\t\t\t_callbacks->FuncOnError(result, \"Extraction Fail\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// _filelist.emplace_back(headerData.FileName);\n\t\t\t_callbacks->FuncOnNewFile(counter, headerData.FileName, ((tjs_int64)headerData.UnpSizeHigh << 32) | headerData.UnpSize);\n\t\t\t_curProcessedBytes = 0;\n\t\t\t// Find next file\n#ifdef _MSC_VER\n\t\t\tttstr _path(path);\n\t\t\tresult = RARProcessFileW(arc._handle, RAR_EXTRACT, (wchar_t*)_path.c_str(), NULL);\n#else\n\t\t\tresult = RARProcessFile(arc._handle, RAR_EXTRACT, (char*)path.c_str(), NULL);\n#endif\n\t\t\tif (result != 0) {\n\t\t\t\t_callbacks->FuncOnError(result, \"Extraction Fail\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t_callbacks->FuncOnEnded();\n\t}\n};\n\nint tTVPUnpackArchive::Prepare(const std::string &path, const std::string &_outpath, tjs_uint64 *totalSize) {\n\tFILE *FpIn = fopen(path.c_str(), \"rb\");\n\tif (!FpIn) return -1;\n\tchar signature[4];\n\tif (fread(signature, 1, 4, FpIn) != 4) {\n\t\tfclose(FpIn);\n\t\treturn -2;\n\t}\n\tOutPath = _outpath + \"/\";\n\tfclose(FpIn);\n\tif (!memcmp(signature, \"Rar!\", 4)) {\n\t\t_impl = new tTVPUnpackArchiveImplUnRAR();\n\t} else if (!memcmp(signature, \"PK\", 2)) {\n\t\t_impl = new tTVPUnpackArchiveImplLibArchive();\n\t} else if (!memcmp(signature, \"7z\", 2)) {\n\t\t// _impl = new tTVPUnpackArchiveImpl7Zip();\n\t\t_impl = new tTVPUnpackArchiveImplLibArchive();\n\t} else {\n\t\t_impl = new tTVPUnpackArchiveImplWrap(); // xp3, etc\n\t\t_impl->SetCallback(this);\n\t\tif (!_impl->Open(path)) {\n\t\t\tClose();\n\t\t\t_impl = new tTVPUnpackArchiveImplLibArchive();\n\t\t}\n\t}\n\t_impl->SetCallback(this);\n\tif (!_impl->Open(path)) {\n\t\tClose();\n\t\treturn -2;\n\t}\n\tif (totalSize) *totalSize = _impl->GetTotalSize();\n\tint file_count = _impl->GetFileCount();\n\tif (file_count) {\n\t\tArcThread = new tTVPUnpackArchiveThread(this);\n\t}\n\treturn file_count;\n}\n\nvoid tTVPUnpackArchive::Start()\n{\n\t_impl->StopRequired = false;\n\tArcThread->Start();\n}\n\nvoid tTVPUnpackArchive::Stop()\n{\n\t_impl->StopRequired = true;\n\tArcThread->Start();\n}\n\nvoid tTVPUnpackArchive::Close()\n{\n\tif (_impl) delete _impl;\n\t_impl = nullptr;\n}\n\nvoid tTVPUnpackArchive::Process()\n{\n\tif (_impl->StopRequired)\n\t\treturn;\n\t_impl->ExtractTo(OutPath);\n}\n\ntTVPUnpackArchive::tTVPUnpackArchive()\n{\n}\n\ntTVPUnpackArchive::~tTVPUnpackArchive()\n{\n\tif (ArcThread) delete ArcThread;\n}\n"
  },
  {
    "path": "src/core/base/UtilStreams.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Stream related utilities / utility streams\n//---------------------------------------------------------------------------\n#ifndef UtilStreamsH\n#define UtilStreamsH\n\n\n#include \"StorageIntf.h\"\n#include <functional>\n\n\n\n//---------------------------------------------------------------------------\n// tTVPStreamHolder\n//---------------------------------------------------------------------------\nclass tTVPStreamHolder\n{\n\ttTJSBinaryStream *Stream;\npublic:\n\ttTVPStreamHolder()\n\t{\n\t\tStream = NULL;\n\t}\n\n\ttTVPStreamHolder(const ttstr& name, tjs_uint32 mode = 0)\n\t{\n\t\tStream = TVPCreateStream(name, mode);\n\t}\n\n\t~tTVPStreamHolder()\n\t{\n\t\tif(Stream) delete Stream;\n\t}\n\n\ttTJSBinaryStream * operator ->() const { return Stream; }\n\n\ttTJSBinaryStream * Get() const { return Stream; }\n\n\tvoid Close()\n\t{\n\t\tif(Stream)\n\t\t{\n\t\t\tdelete Stream;\n\t\t\tStream = NULL;\n\t\t}\n\t}\n\n\tvoid Disown()\n\t{\n\t\tStream = NULL;\n\t}\n\n\tvoid Open(const ttstr & name, tjs_uint32 flag = 0)\n\t{\n\t\tif(Stream) delete Stream, Stream = NULL;\n\t\tStream = TVPCreateStream(name, flag);\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPLocalTempStorageHolder\n//---------------------------------------------------------------------------\n// this class holds storage as local filesystem file ( does not open it ).\n// storage is copied to local fliesystem if needed.\nclass tTVPLocalTempStorageHolder\n{\n\tbool FileMustBeDeleted;\n\tbool FolderMustBeDeleted;\n\tttstr LocalName;\n\tttstr LocalFolder;\npublic:\n\ttTVPLocalTempStorageHolder(const ttstr & name);\n\t~tTVPLocalTempStorageHolder();\n\n\tbool IsTemporaryFile() const { return FileMustBeDeleted; }\n\n\tconst ttstr & GetLocalName() const { return LocalName; }\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPMemoryStream\n//---------------------------------------------------------------------------\n/*\n\tthis class provides a tTJSBinaryStream based access method for a memory block.\n*/\nclass tTVPMemoryStream : public tTJSBinaryStream\n{\nprotected:\n\tvoid * Block;\n\tbool Reference;\n\ttjs_uint Size;\n\ttjs_uint AllocSize;\n\ttjs_uint CurrentPos;\n\npublic:\n\ttTVPMemoryStream();\n\ttTVPMemoryStream(const void * block, tjs_uint size);\n\t~tTVPMemoryStream();\n\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence);\n\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size);\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size);\n\tvoid TJS_INTF_METHOD SetEndOfStorage();\n\n\ttjs_uint64 TJS_INTF_METHOD GetSize() { return Size; }\n\n\t// non-tTJSBinaryStream based methods\n\tvoid * GetInternalBuffer()  const { return Block; }\n\tvoid Clear(void);\n\tvoid SetSize(tjs_uint size);\n\nprotected:\n\tvoid Init();\n\nprotected:\n\tvirtual void * Alloc(size_t size);\n\tvirtual void * Realloc(void *orgblock, size_t size);\n\tvirtual void Free(void *block);\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPPartialStream\n//---------------------------------------------------------------------------\n/*\n\tthis class offers read-only accesses for a partial of the other stream,\n\tlimited by given start position for original stream and given limited size.\n*/\n//---------------------------------------------------------------------------\nclass tTVPPartialStream : public tTJSBinaryStream\n{\nprivate:\n\ttTJSBinaryStream *Stream;\n\ttjs_uint64 Start;\n\ttjs_uint64 Size;\n\ttjs_uint64 CurrentPos;\n\npublic:\n\ttTVPPartialStream(tTJSBinaryStream *stream, tjs_uint64 start, tjs_uint64 size);\n\t~tTVPPartialStream();\n\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence);\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size);\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size);\n\n\t// void SetEndOfStorage(); // use default behavior\n\n\ttjs_uint64 TJS_INTF_METHOD GetSize();\n\n};\n//---------------------------------------------------------------------------\nstruct tTVPUnpackArchiveCallbacks {\n\tstd::function<void()> FuncOnEnded;\n\tstd::function<void(int, const char *)> FuncOnError;\n\tstd::function<void(tjs_uint64, tjs_uint64)> FuncOnProgress;\n\tstd::function<void(int, const std::string &, tjs_uint64)> FuncOnNewFile;\n\tstd::function<std::string()> FuncPassword;\n};\nclass tTVPUnpackArchiveThread;\nclass iTVPUnpackArchiveImpl {\nprotected:\n\tconst tTVPUnpackArchiveCallbacks *_callbacks = nullptr;\n\npublic:\n\tbool StopRequired = false;\n\n\tvirtual ~iTVPUnpackArchiveImpl() {}\n\t\n\tvoid SetCallback(const tTVPUnpackArchiveCallbacks* cb) { _callbacks = cb; }\n\n\tvirtual bool Open(const std::string &path) = 0;\n\tvirtual int GetFileCount() = 0; // -1 for unknown file count\n\tvirtual tjs_int64 GetTotalSize() = 0; // -1 for unknown size\n\tvirtual void ExtractTo(const std::string &path) = 0;\n};\n\nclass tTVPUnpackArchive : public tTVPUnpackArchiveCallbacks {\npublic:\n\ttTVPUnpackArchive();\n\tvirtual ~tTVPUnpackArchive(); // must ve deconstructed from main thread\n\tint Prepare(const std::string &path, const std::string &_outpath, tjs_uint64 *totalSize);\n\tvoid Start();\n\tvoid Stop();\n\tvoid Close();\n\n\tvoid SetCallback(\n\t\tconst std::function<void()> &funcOnEnded,\n\t\tconst std::function<void(int, const char *)> &funcOnError,\n\t\tconst std::function<void(tjs_uint64, tjs_uint64)> &funcOnProgress,\n\t\tconst std::function<void(int, const std::string&, tjs_uint64)> &funcOnNewFile,\n\t\tconst std::function<std::string()>& funcPassword) {\n\t\tFuncOnEnded = funcOnEnded;\n\t\tFuncOnError = funcOnError;\n\t\tFuncOnProgress = funcOnProgress;\n\t\tFuncOnNewFile = funcOnNewFile;\n\t\tFuncPassword = funcPassword;\n\t}\n\nprotected:\n\t// these callbacks are not in main thread !\n\tvirtual void OnEnded() {\n\t\tif (FuncOnEnded)\n\t\t\tFuncOnEnded();\n\t}\n\tvirtual void OnProgress(tjs_uint64 total_size, tjs_uint64 file_size) {\n\t\tif (FuncOnProgress)\n\t\t\tFuncOnProgress(total_size, file_size);\n\t}\n\tvirtual void OnNewFile(int idx, const char * utf8name, tjs_uint64 file_size) {\n\t\tif (FuncOnNewFile)\n\t\t\tFuncOnNewFile(idx, utf8name, file_size);\n\t}\n\nprivate:\n\tvoid Process();\n\n\tiTVPUnpackArchiveImpl *_impl = nullptr;\n\tstd::string OutPath;\n\tfriend class tTVPUnpackArchiveThread;\n\ttTVPUnpackArchiveThread *ArcThread = nullptr;\n};\n\n#endif\n"
  },
  {
    "path": "src/core/base/XP3Archive.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// XP3 virtual file system support\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"XP3Archive.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"EventIntf.h\"\n#include \"UtilStreams.h\"\n#include \"SysInitIntf.h\"\n\n#include <zlib.h>\n#include <algorithm>\n\nbool TVPAllowExtractProtectedStorage = true;\n\n\n//---------------------------------------------------------------------------\n// archive filter related\n//---------------------------------------------------------------------------\ntTVPXP3ArchiveExtractionFilter TVPXP3ArchiveExtractionFilter  = NULL;\nvoid TVPSetXP3ArchiveExtractionFilter(tTVPXP3ArchiveExtractionFilter filter)\n{\n\tTVPXP3ArchiveExtractionFilter = filter;\n}\n//---------------------------------------------------------------------------\n\nstatic tTVPXP3ArchiveContentFilter TVPXP3ArchiveContentFilter = nullptr;\nvoid TVPSetXP3ArchiveContentFilter(tTVPXP3ArchiveContentFilter filter)\n{\n\tTVPXP3ArchiveContentFilter = filter;\n}\n\n\n//---------------------------------------------------------------------------\n// tTVPXP3ArchiveHandleCache\n//---------------------------------------------------------------------------\n#define TVP_MAX_ARCHIVE_HANDLE_CACHE 8\nstatic tjs_uint TVPArchiveHandleCacheAge = 0;\nstruct tTVPArchiveHandleCacheItem\n{\n\tvoid * Pointer;\n\ttTJSBinaryStream * Stream;\n\ttjs_uint Age;\n};\n//---------------------------------------------------------------------------\nstatic tTVPArchiveHandleCacheItem * TVPArchiveHandleCachePool = NULL;\nstatic bool TVPArchiveHandleCacheInit = false;\nstatic bool TVPArchiveHandleCacheShutdown = false;\nstatic tTJSCriticalSection TVPArchiveHandleCacheCS;\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TVPGetCachedArchiveHandle(void * pointer, const ttstr & name)\n{\n\t// get cached archive file handle from the pool\n\tif(TVPArchiveHandleCacheShutdown)\n\t{\n\t\t// the pool has shutdown\n\t\treturn TVPCreateStream(name);\n\t}\n\n\ttTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS);\n\n\tif(!TVPArchiveHandleCacheInit)\n\t{\n\t\t// initialize the pool\n\t\tTVPArchiveHandleCachePool =\n\t\t\tnew tTVPArchiveHandleCacheItem[TVP_MAX_ARCHIVE_HANDLE_CACHE];\n\t\tfor(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t\t{\n\t\t\tTVPArchiveHandleCachePool[i].Pointer = NULL;\n\t\t\tTVPArchiveHandleCachePool[i].Stream = NULL;\n\t\t\tTVPArchiveHandleCachePool[i].Age = 0;\n\t\t}\n\t\tTVPArchiveHandleCacheInit = true;\n\t}\n\n\t// linear search wiil be enough here because the \n\t// TVP_MAX_ARCHIVE_HANDLE_CACHE is relatively small\n\tfor(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t{\n\t\ttTVPArchiveHandleCacheItem *item =\n\t\t\tTVPArchiveHandleCachePool + i;\n\t\tif(item->Stream && item->Pointer == pointer)\n\t\t{\n\t\t\t// found in the pool\n\t\t\ttTJSBinaryStream * stream = item->Stream;\n\t\t\titem->Stream = NULL;\n\t\t\treturn stream;\n\t\t}\n\t}\n\n\t// not found in the pool\n\t// simply create a stream and return it\n\treturn TVPCreateStream(name);\n}\n//---------------------------------------------------------------------------\n/*static*/ void TVPReleaseCachedArchiveHandle(void * pointer,\n\t\t\t\t\t\ttTJSBinaryStream * stream)\n{\n\t// release archive file handle\n\tif(TVPArchiveHandleCacheShutdown) return;\n\tif(!TVPArchiveHandleCacheInit) return;\n\n\ttTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS);\n\n\t// search empty cell in the pool\n\ttjs_uint oldest_age = 0;\n\ttjs_int oldest = 0;\n\tfor(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t{\n\t\ttTVPArchiveHandleCacheItem *item =\n\t\t\tTVPArchiveHandleCachePool + i;\n\t\tif(item->Stream == NULL)\n\t\t{\n\t\t\t// found the empty cell; fill it\n\t\t\titem->Pointer = pointer;\n\t\t\titem->Stream = stream;\n\t\t\titem->Age = ++TVPArchiveHandleCacheAge;\n\t\t\t\t// counter overflow in TVPArchiveHandleCacheAge\n\t\t\t\t// is not so a big problem.\n\t\t\t\t// counter overflow can worsen the cache performance,\n\t\t\t\t// but it occurs only when the counter is overflowed\n\t\t\t\t// (it's too far less than usual)\n\t\t\treturn;\n\t\t}\n\n\t\tif(i == 0 || oldest_age > item->Age)\n\t\t{\n\t\t\toldest_age = item->Age;\n\t\t\toldest = i;\n\t\t}\n\t}\n\n\t// empty cell not found\n\t// free oldest cell and fill it\n\ttTVPArchiveHandleCacheItem *oldest_item =\n\t\tTVPArchiveHandleCachePool + oldest;\n\tdelete oldest_item->Stream, oldest_item->Stream = NULL;\n\toldest_item->Pointer = pointer;\n\toldest_item->Stream = stream;\n\toldest_item->Age = ++TVPArchiveHandleCacheAge;\n}\n//---------------------------------------------------------------------------\n/*static*/ void TVPFreeArchiveHandlePoolByPointer(void * pointer)\n{\n\t// free all streams which have specified pointer\n\tif(TVPArchiveHandleCacheShutdown) return;\n\tif(!TVPArchiveHandleCacheInit) return;\n\n\ttTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS);\n\n\tfor(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t{\n\t\ttTVPArchiveHandleCacheItem *item =\n\t\t\tTVPArchiveHandleCachePool + i;\n\t\tif(item->Stream && item->Pointer == pointer)\n\t\t{\n\t\t\tdelete item->Stream, item->Stream = NULL;\n\t\t\titem->Pointer = NULL;\n\t\t\titem->Age = 0;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPFreeArchiveHandlePool()\n{\n\t// free all streams\n\tif(TVPArchiveHandleCacheShutdown) return;\n\tif(!TVPArchiveHandleCacheInit) return;\n\n\ttTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS);\n\n\tfor(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t{\n\t\ttTVPArchiveHandleCacheItem *item =\n\t\t\tTVPArchiveHandleCachePool + i;\n\t\tif(item->Stream)\n\t\t{\n\t\t\tdelete item->Stream, item->Stream = NULL;\n\t\t\titem->Pointer = NULL;\n\t\t\titem->Age = 0;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPShutdownArchiveHandleCache()\n{\n\t// free all stream and shutdown the pool\n\ttTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS);\n\n\tTVPArchiveHandleCacheShutdown = true;\n\tif(!TVPArchiveHandleCacheInit) return;\n\n\tfor(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++)\n\t{\n\t\tif(TVPArchiveHandleCachePool[i].Stream)\n\t\t\tdelete TVPArchiveHandleCachePool[i].Stream;\n\t}\n\tdelete [] TVPArchiveHandleCachePool;\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPShutdownArchiveCacheAtExit\n\t(TVP_ATEXIT_PRI_CLEANUP, TVPShutdownArchiveHandleCache);\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPXP3Archive\n//---------------------------------------------------------------------------\n/*\n\tTVP XPK3 virtual file system support. (in short : XP3)\n\tTVP supports no longer archive type of \"XPK1/XPK2\"\n\t( XPK1/XPK2 is used by TVP ver under 0.9x ).\n\n\there word \"in-archive\" is used for the storages which are contained in\n\tarchive.\n*/\n//---------------------------------------------------------------------------\nbool TVPGetXP3ArchiveOffset(tTJSBinaryStream *st, const ttstr name,\n\ttjs_uint64 & offset, bool raise)\n{\n\tst->SetPosition(0);\n\ttjs_uint8 mark[11+1];\n\tstatic tjs_uint8 XP3Mark1[] =\n\t\t{ 0x58/*'X'*/, 0x50/*'P'*/, 0x33/*'3'*/, 0x0d/*'\\r'*/,\n\t\t  0x0a/*'\\n'*/, 0x20/*' '*/, 0x0a/*'\\n'*/, 0x1a/*EOF*/,\n\t\t  0xff /* sentinel */ };\n\tstatic tjs_uint8 XP3Mark2[] =\n\t\t{ 0x8b, 0x67, 0x01, 0xff/* sentinel */ };\n\n\t// XP3 header mark contains:\n\t// 1. line feed and carriage return to detect corruption by unnecessary\n\t//    line-feeds convertion\n\t// 2. 1A EOF mark which indicates file's text readable header ending.\n\t// 3. 8B67 KANJI-CODE to detect curruption by unnecessary code convertion\n\t// 4. 01 file structure version and character coding\n\t//    higher 4 bits are file structure version, currently 0.\n\t//    lower 4 bits are character coding, currently 1, is BMP 16bit Unicode.\n\n\tstatic tjs_uint8 XP3Mark[11+1];\n\t\t// +1: I was warned by CodeGuard that the code will do\n\t\t// access overrun... because a number of 11 is not aligned by DWORD, \n\t\t// and the processor may read the value of DWORD at last of this array\n\t\t// from offset 8. Then the last 1 byte would cause a fail.\n\tstatic bool DoInit = true;\n\tif(DoInit)\n\t{\n\t\t// the XP3 header above is splitted into two part; to avoid\n\t\t// mis-finding of the header in the program's initialized data area.\n\t\tDoInit = false;\n\t\tmemcpy(XP3Mark, XP3Mark1, 8);\n\t\tmemcpy(XP3Mark + 8, XP3Mark2, 3);\n\t\t// here joins it.\n\t}\n\n\tmark[0] = 0; // sentinel\n\tst->ReadBuffer(mark, 11);\n\tif(mark[0] == 0x4d/*'M'*/ && mark[1] == 0x5a/*'Z'*/)\n\t{\n\t\t// \"MZ\" is a mark of Win32/DOS executables,\n\t\t// TVP searches the first mark of XP3 archive\n\t\t// in the executeble file.\n\t\tbool found = false;\n\n\t\toffset = 16;\n\t\tst->SetPosition(16);\n\n\t\t// XP3 mark must be aligned by a paragraph ( 16 bytes )\n\t\tconst tjs_uint one_read_size = 256*1024;\n\t\ttjs_uint read;\n\t\ttjs_uint8 *buffer = new tjs_uint8[one_read_size]; // read 256kbytes at once\n\n\t\twhile(0!=(read = st->Read(buffer, one_read_size)))\n\t\t{\n\t\t\ttjs_uint p = 0;\n\t\t\twhile(p<read)\n\t\t\t{\n\t\t\t\tif(!memcmp(XP3Mark, buffer + p, 11))\n\t\t\t\t{\n\t\t\t\t\t// found the mark\n\t\t\t\t\toffset += p;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tp+=16;\n\t\t\t}\n\t\t\tif(found) break;\n\t\t\toffset += one_read_size;\n\t\t}\n        delete[] buffer;\n\t\tif(!found)\n\t\t{\n\t\t\tif(raise)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotUnbindXP3EXE, name);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t}\n\telse if(!memcmp(XP3Mark, mark, 11))\n\t{\n\t\t// XP3 mark found\n\t\toffset = 0;\n\t}\n\telse\n\t{\n\t\tif (raise) {\n\t\t\tttstr msg(TVPGetMessageByLocale(\"err_not_xp3_archive\"));\n\t\t\tTVPThrowExceptionMessage(msg.c_str(), name);\n\t\t\t//TVPThrowExceptionMessage(TVPCannotFindXP3Mark, name);\n\t\t}\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool TVPIsXP3Archive(const ttstr &name)\n{\n\ttTVPStreamHolder holder(name);\n\ttry\n\t{\n\t\ttjs_uint64 offset;\n\t\treturn TVPGetXP3ArchiveOffset(holder.Get(), name, offset, false);\n\t}\n\tcatch(...)\n\t{\n\t\treturn false;\n\t}\n}\n\n//---------------------------------------------------------------------------\nvoid tTVPXP3Archive::Init(tTJSBinaryStream *st, tjs_int64 off, bool normalizeName)\n{\n\ttjs_uint64 offset = off;\n\n\ttjs_uint8 *indexdata = NULL;\n\n\tstatic const tjs_uint8 cn_File[] =\n\t\t{ 0x46/*'F'*/, 0x69/*'i'*/, 0x6c/*'l'*/, 0x65/*'e'*/ };\n\tstatic const tjs_uint8 cn_info[] =\n\t\t{ 0x69/*'i'*/, 0x6e/*'n'*/, 0x66/*'f'*/, 0x6f/*'o'*/ };\n\tstatic const tjs_uint8 cn_segm[] =\n\t\t{ 0x73/*'s'*/, 0x65/*'e'*/, 0x67/*'g'*/, 0x6d/*'m'*/ };\n\tstatic const tjs_uint8 cn_adlr[] =\n\t\t{ 0x61/*'a'*/, 0x64/*'d'*/, 0x6c/*'l'*/, 0x72/*'r'*/ };\n\n\tTVPAddLog( TVPFormatMessage(TVPInfoTryingToReadXp3VirtualFileSystemInformationFrom, ArchiveName) );\n\n\tint segmentcount = 0;\n\ttry\n\t{\n\t\t// retrieve archive offset\n\t\tif(off < 0) TVPGetXP3ArchiveOffset(st, ArchiveName, offset, true);\n\n\t\t// read index position and seek\n\t\tst->SetPosition(11 + offset);\n\n\t\t// read all XP3 indices\n\t\twhile(true)\n\t\t{\n\t\t\tif(indexdata) delete [] indexdata;\n\n\t\t\ttjs_uint64 index_ofs = st->ReadI64LE();\n\t\t\tst->SetPosition(index_ofs + offset);\n\n\t\t\t// read index to memory\n\t\t\ttjs_uint8 index_flag;\n\t\t\tst->ReadBuffer(&index_flag, 1);\n\t\t\ttjs_uint index_size;\n\n\t\t\tif((index_flag & TVP_XP3_INDEX_ENCODE_METHOD_MASK) ==\n\t\t\t\tTVP_XP3_INDEX_ENCODE_ZLIB)\n\t\t\t{\n\t\t\t\t// compressed index\n\t\t\t\ttjs_uint64 compressed_size = st->ReadI64LE();\n\t\t\t\ttjs_uint64 r_index_size = st->ReadI64LE();\n\n\t\t\t\tif((tjs_uint)compressed_size != compressed_size ||\n\t\t\t\t\t(tjs_uint)r_index_size != r_index_size)\n\t\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\t\t\t\t\t\t// too large to handle, or corrupted\n\t\t\t\tindex_size = (tjs_int)r_index_size;\n\t\t\t\tindexdata = new tjs_uint8[index_size];\n\t\t\t\ttjs_uint8 *compressed = new tjs_uint8[(tjs_uint)compressed_size];\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tst->ReadBuffer(compressed, (tjs_uint)compressed_size);\n\n\t\t\t\t\tunsigned long destlen = (unsigned long)index_size;\n\n\t\t\t\t\tint result = uncompress(  /* uncompress from zlib */\n\t\t\t\t\t\t(unsigned char *)indexdata,\n\t\t\t\t\t\t&destlen, (unsigned char*)compressed,\n\t\t\t\t\t\t\t(unsigned long)compressed_size);\n\t\t\t\t\tif(result != Z_OK ||\n\t\t\t\t\t\tdestlen != (unsigned long)index_size)\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPUncompressionFailed);\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\tdelete [] compressed;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tdelete [] compressed;\n\t\t\t}\n\t\t\telse if((index_flag & TVP_XP3_INDEX_ENCODE_METHOD_MASK) ==\n\t\t\t\tTVP_XP3_INDEX_ENCODE_RAW)\n\t\t\t{\n\t\t\t\t// uncompressed index\n\t\t\t\ttjs_uint64 r_index_size = st->ReadI64LE();\n\t\t\t\tif((tjs_uint)r_index_size != r_index_size)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\t\t\t\t\t\t// too large to handle or corrupted\n\t\t\t\tindex_size = (tjs_uint)r_index_size;\n\t\t\t\tindexdata = new tjs_uint8[index_size];\n\t\t\t\tst->ReadBuffer(indexdata, index_size);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// unknown encode method\n\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\t\t\t}\n\n\n\t\t\t// read index information from memory\n\t\t\ttjs_uint ch_file_start = 0;\n\t\t\ttjs_uint ch_file_size = index_size;\n\t\t\t//Count = 0;\n\t\t\tfor(;;)\n\t\t\t{\n\t\t\t\t// find 'File' chunk\n\t\t\t\tif(!FindChunk(indexdata, cn_File, ch_file_start, ch_file_size))\n\t\t\t\t\tbreak; // not found\n\n\t\t\t\t// find 'info' sub-chunk\n\t\t\t\ttjs_uint ch_info_start = ch_file_start;\n\t\t\t\ttjs_uint ch_info_size = ch_file_size;\n\t\t\t\tif(!FindChunk(indexdata, cn_info, ch_info_start, ch_info_size))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\n\t\t\t\t// read info sub-chunk\n\t\t\t\ttArchiveItem item;\n\t\t\t\ttjs_uint32 flags = ReadI32FromMem(indexdata + ch_info_start + 0);\n\t\t\t\tif(!TVPAllowExtractProtectedStorage && (flags & TVP_XP3_FILE_PROTECTED))\n\t\t\t\t\tTVPThrowExceptionMessage( TVPSpecifiedStorageHadBeenProtected );\n\t\t\t\titem.OrgSize = ReadI64FromMem(indexdata + ch_info_start + 4);\n\t\t\t\titem.ArcSize = ReadI64FromMem(indexdata + ch_info_start + 12);\n\n\t\t\t\ttjs_int len = ReadI16FromMem(indexdata + ch_info_start + 20);\n\t\t\t\tttstr name = TVPStringFromBMPUnicode(\n\t\t\t\t\t\t(const tjs_uint16 *)(indexdata + ch_info_start + 22), len);\n\t\t\t\titem.Name = name;\n\t\t\t\tif (normalizeName)\n\t\t\t\t\tNormalizeInArchiveStorageName(item.Name);\n\n\t\t\t\t// find 'segm' sub-chunk\n\t\t\t\t// Each of in-archive storages can be splitted into some segments.\n\t\t\t\t// Each segment can be compressed or uncompressed independently.\n\t\t\t\t// segments can share partial area of archive storage. ( this is used for\n\t\t\t\t// OggVorbis' VQ code book sharing )\n\t\t\t\ttjs_uint ch_segm_start = ch_file_start;\n\t\t\t\ttjs_uint ch_segm_size = ch_file_size;\n\t\t\t\tif(!FindChunk(indexdata, cn_segm, ch_segm_start, ch_segm_size))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\n\t\t\t\t// read segm sub-chunk\n\t\t\t\ttjs_int segment_count = ch_segm_size / 28;\n\t\t\t\ttjs_uint64 offset_in_archive = 0;\n\t\t\t\tfor(tjs_int i = 0; i<segment_count; i++)\n\t\t\t\t{\n\t\t\t\t\ttjs_uint pos_base = i * 28 + ch_segm_start;\n\t\t\t\t\ttTVPXP3ArchiveSegment seg;\n\t\t\t\t\ttjs_uint32 flags = ReadI32FromMem(indexdata + pos_base);\n\n\t\t\t\t\tif((flags & TVP_XP3_SEGM_ENCODE_METHOD_MASK) ==\n\t\t\t\t\t\t\tTVP_XP3_SEGM_ENCODE_RAW)\n\t\t\t\t\t\tseg.IsCompressed = false;\n\t\t\t\t\telse if((flags & TVP_XP3_SEGM_ENCODE_METHOD_MASK) ==\n\t\t\t\t\t\t\tTVP_XP3_SEGM_ENCODE_ZLIB)\n\t\t\t\t\t\tseg.IsCompressed = true;\n\t\t\t\t\telse\n\t\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError); // unknown encode method\n\t\t\t\t\t\t\n\t\t\t\t\tseg.Start = ReadI64FromMem(indexdata + pos_base + 4) + offset;\n\t\t\t\t\t\t// data offset in archive\n\t\t\t\t\tseg.Offset = offset_in_archive; // offset in in-archive storage\n\t\t\t\t\tseg.OrgSize = ReadI64FromMem(indexdata + pos_base + 12); // original size\n\t\t\t\t\tseg.ArcSize = ReadI64FromMem(indexdata + pos_base + 20); // archived size\n\t\t\t\t\titem.Segments.push_back(seg);\n\t\t\t\t\toffset_in_archive += seg.OrgSize;\n\t\t\t\t\tsegmentcount ++;\n\t\t\t\t}\n\n\t\t\t\t// find 'aldr' sub-chunk\n\t\t\t\ttjs_uint ch_adlr_start = ch_file_start;\n\t\t\t\ttjs_uint ch_adlr_size = ch_file_size;\n\t\t\t\tif(!FindChunk(indexdata, cn_adlr, ch_adlr_start, ch_adlr_size))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\n\t\t\t\t// read 'aldr' sub-chunk\n\t\t\t\titem.FileHash = ReadI32FromMem(indexdata + ch_adlr_start);\n\n\t\t\t\t// push information\n\t\t\t\tItemVector.push_back(item);\n\n\t\t\t\t// to next file\n\t\t\t\tch_file_start += ch_file_size;\n\t\t\t\tch_file_size = index_size - ch_file_start;\n\t\t\t\tCount++;\n\t\t\t}\n\n\t\t\tif(!(index_flag & TVP_XP3_INDEX_CONTINUE))\n\t\t\t\tbreak; // continue reading index when the bit sets\n\t\t}\n\n\t\t// sort item vector by its name (required for tTVPArchive specification)\n\t\tif(normalizeName)\n\t\t\tstd::stable_sort(ItemVector.begin(), ItemVector.end());\n\t}\n\tcatch(...)\n\t{\n\t\tif(indexdata) delete [] indexdata;\n\t\tdelete st;\n \t\tTVPAddLog( (const tjs_char*)TVPInfoFailed );\n\t\tthrow;\n\t}\n\tif(indexdata) delete [] indexdata;\n\tdelete st;\n\n\tTVPAddLog( TVPFormatMessage( TVPInfoDoneWithContains, ttstr(Count), ttstr(segmentcount) ) );\n}\n\n//---------------------------------------------------------------------------\ntTVPXP3Archive::tTVPXP3Archive(const ttstr & name, tTJSBinaryStream *st, tjs_int64 offset, bool normalizeFileName) : tTVPArchive(name)\n{\n\tif (!st) st = TVPCreateStream(name);\n\tInit(st, offset, normalizeFileName);\n}\n//---------------------------------------------------------------------------\ntTVPXP3Archive::~tTVPXP3Archive()\n{\n\tTVPFreeArchiveHandlePoolByPointer(this);\n}\n\ntTVPArchive * tTVPXP3Archive::Create(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName)\n{\n\tbool refStream = st;\n\tif (!st) {\n\t\tst = TVPCreateStream(name);\n\t}\n\ttjs_uint64 offset;\n\tif (!TVPGetXP3ArchiveOffset(st, name, offset, false)) {\n\t\tif (!refStream) delete st;\n\t\treturn nullptr;\n\t}\n\treturn new tTVPXP3Archive(name, st, offset, normalizeFileName);\n}\n\n//---------------------------------------------------------------------------\ntTJSBinaryStream * tTVPXP3Archive::CreateStreamByIndex(tjs_uint idx)\n{\n\tif(idx >= ItemVector.size()) TVPThrowExceptionMessage(TVPReadError);\n\n\ttArchiveItem &item = ItemVector[idx];\n\n\ttTJSBinaryStream *stream = TVPGetCachedArchiveHandle(this, ArchiveName);\n\n\ttTVPXP3ArchiveStream *out;\n\ttry\n\t{\n\t\tout = new tTVPXP3ArchiveStream(this, idx, &(item.Segments), stream,\n\t\t\titem.OrgSize);\n\t\tif (TVPXP3ArchiveContentFilter) {\n\t\t\ttjs_int result = TVPXP3ArchiveContentFilter(item.Name, ArchiveName, item.OrgSize, &out->GetFilterContext());\n#define XP3_CONTENT_FILTER_FETCH_FULLDATA 1\n\t\t\tif (result == XP3_CONTENT_FILTER_FETCH_FULLDATA) {\n\t\t\t\ttTVPMemoryStream *memstr = new tTVPMemoryStream();\n\t\t\t\tmemstr->SetSize(item.OrgSize);\n\t\t\t\tout->ReadBuffer(memstr->GetInternalBuffer(), item.OrgSize);\n\t\t\t\tdelete out;\n\t\t\t\treturn memstr;\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tTVPReleaseCachedArchiveHandle(this, stream);\n\t\tthrow;\n\t}\n\n\treturn out;\n}\n//---------------------------------------------------------------------------\nbool tTVPXP3Archive::FindChunk(const tjs_uint8 *data, const tjs_uint8 * name,\n\t\ttjs_uint &start, tjs_uint &size)\n{\n\ttjs_uint start_save = start;\n\ttjs_uint size_save = size;\n\n\ttjs_uint pos = 0;\n\twhile(pos < size)\n\t{\n\t\tbool found = !memcmp(data + start, name, 4);\n\t\tstart += 4;\n\t\ttjs_uint64 r_size = ReadI64FromMem(data + start);\n\t\tstart += 8;\n\t\ttjs_uint size_chunk = (tjs_uint)r_size;\n\t\tif(size_chunk != r_size)\n\t\t\tTVPThrowExceptionMessage(TVPReadError);\n\t\tif(found)\n\t\t{\n\t\t\t// found\n\t\t\tsize = size_chunk;\n\t\t\treturn true;\n\t\t}\n\t\tstart += size_chunk;\n\t\tpos += size_chunk + 4 + 8;\n\t}\n\n\tstart = start_save;\n\tsize = size_save;\n\treturn false;\n}\n//---------------------------------------------------------------------------\ntjs_int16 tTVPXP3Archive::ReadI16FromMem(const tjs_uint8 *mem)\n{\n\ttjs_uint16 ret = (tjs_uint16)mem[0] | ((tjs_uint16)mem[1] << 8);\n\treturn (tjs_int16)ret;\n}\n//---------------------------------------------------------------------------\ntjs_int32 tTVPXP3Archive::ReadI32FromMem(const tjs_uint8 *mem)\n{\n\ttjs_uint32 ret =  (tjs_uint32)mem[0] | ((tjs_uint32)mem[1] << 8) |\n\t\t((tjs_uint32)mem[2] << 16) | ((tjs_uint32)mem[3] << 24);\n\treturn (tjs_int32)ret;\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTVPXP3Archive::ReadI64FromMem(const tjs_uint8 *mem)\n{\n\ttjs_uint64 ret = (tjs_uint64)mem[0] | ((tjs_uint64)mem[1] << 8) |\n\t\t((tjs_uint64)mem[2] << 16) | ((tjs_uint64)mem[3] << 24) |\n\t\t((tjs_uint64)mem[4] << 32) | ((tjs_uint64)mem[5] << 40) |\n\t\t((tjs_uint64)mem[6] << 48) | ((tjs_uint64)mem[7] << 56);\n\treturn (tjs_int64)ret;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Compressed segment cache related\n//---------------------------------------------------------------------------\n#define TVP_SEGCACHE_ONE_LIMIT (1024*1024)     // max size limit for each segment\n#define TVP_SEGCACHE_TOTAL_LIMIT (1024*1024)   // total segment cache size\ntjs_uint TVPSegmentCacheLimit = TVP_SEGCACHE_TOTAL_LIMIT;\n//---------------------------------------------------------------------------\nstruct tTVPSegmentCacheSearchData\n{\n\tttstr Name; // archive name\n\ttjs_int StorageIndex; // storage index in archive\n\ttjs_int SegmentIndex; // segment index in storage\n\n\tbool operator == (const tTVPSegmentCacheSearchData &rhs) const\n\t{\n\t\treturn Name == rhs.Name && StorageIndex == rhs.StorageIndex &&\n\t\t\tSegmentIndex == rhs.SegmentIndex;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPSegmentCacheSearchHashFunc\n{\npublic:\n\tstatic tjs_uint32 Make(const tTVPSegmentCacheSearchData &val)\n\t{\n\t\ttjs_uint32 v = tTJSHashFunc<ttstr>::Make(val.Name);\n\n\t\tv ^= val.StorageIndex;\n\t\tv ^= (val.SegmentIndex<<2);\n\t\treturn v;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPSegmentData\n{\n\ttjs_int RefCount;\n\ttjs_uint Size;\n\ttjs_uint8 *Data;\n\npublic:\n\ttTVPSegmentData() { RefCount = 1; Size = 0; Data = NULL; }\n\t~tTVPSegmentData() { if(Data) delete [] Data; }\n\n\tvoid SetData(unsigned long outsize, tTJSBinaryStream *instream,\n\t\tunsigned long insize)\n\t{\n\t\t// uncompress data\n\t\ttjs_uint8 * indata = new tjs_uint8 [insize];\n\t\ttry\n\t\t{\n\t\t\tinstream->Read(indata, insize);\n\n\t\t\tData = new tjs_uint8 [outsize];\n\t\t\tunsigned long destlen = outsize;\n\t\t\tint result = uncompress( (unsigned char*)Data, &outsize,\n\t\t\t\t(unsigned char*)indata, insize);\n\t\t\tif(result != Z_OK || destlen != outsize)\n\t\t\t\tTVPThrowExceptionMessage(TVPUncompressionFailed);\n\t\t\tSize = outsize;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete [] indata;\n\t\t\tthrow;\n\t\t}\n\t\tdelete [] indata;\n\t}\n\n\tconst tjs_uint8 * GetData() const { return Data; }\n\ttjs_uint GetSize() const { return Size; }\n\n\tvoid AddRef() { RefCount ++; }\n\tvoid Release()\n\t{\n\t\tif(RefCount == 1)\n\t\t{\n\t\t\tdelete this;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tRefCount--;\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\ntypedef tTJSRefHolder<tTVPSegmentData> tTVPSegmentDataHolder;\n\ntypedef\ntTJSHashTable<tTVPSegmentCacheSearchData, tTVPSegmentDataHolder, tTVPSegmentCacheSearchHashFunc>\n\ttTVPSegmentCache;\nstatic tTVPSegmentCache TVPSegmentCache;\nstatic tjs_uint TVPSegmentCacheTotalBytes = 0;\n\nstatic tTJSCriticalSection TVPSegmentCacheCS;\n//---------------------------------------------------------------------------\nstatic void TVPCheckSegmentCacheLimit()\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS);\n\n\twhile(TVPSegmentCacheTotalBytes > TVPSegmentCacheLimit)\n\t{\n\t\t// chop last segment\n\t\ttTVPSegmentCache::tIterator i;\n\t\ti = TVPSegmentCache.GetLast();\n\t\tif(!i.IsNull())\n\t\t{\n\t\t\ttjs_uint size = i.GetValue().GetObjectNoAddRef()->GetSize();\n\t\t\tTVPSegmentCacheTotalBytes -= size;\n\t\t\tTVPSegmentCache.ChopLast(1);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPClearXP3SegmentCache()\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS);\n\n\tTVPSegmentCache.Clear();\n\tTVPSegmentCacheTotalBytes = 0;\n}\n//---------------------------------------------------------------------------\nstruct tTVPClearSegmentCacheCallback : public tTVPCompactEventCallbackIntf\n{\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\tif(level >= TVP_COMPACT_LEVEL_DEACTIVATE)\n\t\t{\n\t\t\t// clear the segment cache on application deactivate\n\t\t\tTVPClearXP3SegmentCache();\n\t\t\t// also free archive handle pool\n\t\t\tTVPFreeArchiveHandlePool();\n\t\t}\n\t}\n} static TVPClearSegmentCacheCallback;\nstatic bool TVPClearSegmentCacheCallbackInit = false;\n//---------------------------------------------------------------------------\nstatic tTVPSegmentData * TVPSearchFromSegmentCache(\n\tconst tTVPSegmentCacheSearchData &sdata, tjs_uint32 hash)\n{\n\ttTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS);\n\n\ttTVPSegmentDataHolder * ptr =\n\t\tTVPSegmentCache.FindAndTouchWithHash(sdata, hash);\n\tif(ptr)\n\t{\n\t\t// found in cache\n\t\treturn ptr->GetObject(); // add-refed\n\t}\n\n\treturn NULL; // not found in cache\n}\n//---------------------------------------------------------------------------\nstatic void TVPPushToSegmentCache(const tTVPSegmentCacheSearchData &sdata, tjs_uint32 hash,\n\ttTVPSegmentData *data)\n{\n\tif(!TVPClearSegmentCacheCallbackInit)\n\t{\n\t\tTVPAddCompactEventHook(&TVPClearSegmentCacheCallback);\n\t\tTVPClearSegmentCacheCallbackInit = true;\n\t}\n\n\ttTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS);\n\n\ttTVPSegmentDataHolder holder(data);\n\tTVPSegmentCache.AddWithHash(sdata, hash, holder);\n\tTVPSegmentCacheTotalBytes += data->GetSize();\n\n\tTVPCheckSegmentCacheLimit();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPXP3ArchiveStream : stream class for in-archive storage\n//---------------------------------------------------------------------------\ntTVPXP3ArchiveStream::tTVPXP3ArchiveStream(tTVPXP3Archive *owner,\n\ttjs_int storageindex,\n\tstd::vector<tTVPXP3ArchiveSegment> *segments, tTJSBinaryStream * stream,\n\t\ttjs_uint64 orgsize)\n{\n\tStorageIndex = storageindex;\n\tSegments = segments;\n\tSegmentData = NULL;\n\tCurSegmentNum = 0;\n\tCurSegment = &(Segments->operator [](0));\n\tSegmentPos = 0;\n\tSegmentRemain = CurSegment->OrgSize;\n\tSegmentOpened = false;\n\tCurPos = 0;\n\n\tLastOpenedSegmentNum = -1;\n\n\tOwner = owner;\n\tOwner->AddRef(); // hook\n\tStream = stream;\n\tOrgSize = orgsize;\n}\n//---------------------------------------------------------------------------\ntTVPXP3ArchiveStream::~tTVPXP3ArchiveStream()\n{\n\tTVPReleaseCachedArchiveHandle(Owner, Stream);\n\tOwner->Release(); // unhook\n\tif(SegmentData) SegmentData->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTVPXP3ArchiveStream::EnsureSegment()\n{\n\t// ensure accessing to current segment\n\tif(SegmentOpened) return;\n\n\tif(LastOpenedSegmentNum == CurSegmentNum)\n\t{\n\t\tif(!CurSegment->IsCompressed)\n\t\t\tStream->SetPosition(CurSegment->Start + SegmentPos);\n\t\treturn;\n\t}\n\n\t// erase buffer\n\tif(SegmentData) SegmentData->Release(), SegmentData = NULL;\n\n\t// is compressed segment ?\n\tif(CurSegment->IsCompressed)\n\t{\n\t\t// a compressed segment\n\n\t\tif(CurSegment->OrgSize >= TVP_SEGCACHE_ONE_LIMIT)\n\t\t{\n\t\t\t// too large to cache\n\t\t\tStream->SetPosition(CurSegment->Start);\n\t\t\tSegmentData = new tTVPSegmentData;\n\t\t\tSegmentData->SetData((tjs_uint)CurSegment->OrgSize,\n\t\t\t\tStream, (tjs_uint)CurSegment->ArcSize);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// search thru segment cache\n\t\t\ttTVPSegmentCacheSearchData sdata;\n\t\t\tsdata.Name = Owner->GetName();\n\t\t\tsdata.StorageIndex = StorageIndex;\n\t\t\tsdata.SegmentIndex = CurSegmentNum;\n\n\t\t\ttjs_uint32 hash;\n\t\t\thash = tTVPSegmentCacheSearchHashFunc::Make(sdata);\n\n\t\t\tSegmentData = TVPSearchFromSegmentCache(sdata, hash);\n\t\t\tif(!SegmentData)\n\t\t\t{\n\t\t\t\t// not found in cache\n\t\t\t\tStream->SetPosition(CurSegment->Start);\n\t\t\t\tSegmentData = new tTVPSegmentData;\n\t\t\t\tSegmentData->SetData((tjs_uint)CurSegment->OrgSize,\n\t\t\t\t\tStream, (tjs_uint)CurSegment->ArcSize);\n\n\t\t\t\t// add to cache\n\t\t\t\tTVPPushToSegmentCache(sdata, hash, SegmentData);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// not a compressed segment\n\n\t\tStream->SetPosition(CurSegment->Start + SegmentPos);\n\t}\n\n\tSegmentOpened = true;\n\tLastOpenedSegmentNum = CurSegmentNum;\n}\n//---------------------------------------------------------------------------\nvoid tTVPXP3ArchiveStream::SeekToPosition(tjs_uint64 pos)\n{\n\t// open segment at 'pos' and seek\n\t// pos must between zero thru OrgSize\n\tif(CurPos == pos) return;\n\n\t// do binary search to determine current segment number\n\ttjs_int st = 0;\n\ttjs_int et = (tjs_int)Segments->size();\n\ttjs_int seg_num;\n\n\twhile(true)\n\t{\n\t\tif(et-st <= 1) { seg_num = st; break; }\n\t\ttjs_int m = st + (et-st)/2;\n\t\tif(Segments->operator[](m).Offset > pos)\n\t\t\tet = m;\n\t\telse\n\t\t\tst = m;\n\t}\n\n\tCurSegmentNum = seg_num;\n\tCurSegment = &(Segments->operator [](CurSegmentNum));\n\tSegmentOpened = false;\n\n\tSegmentPos = pos - CurSegment->Offset;\n\tSegmentRemain = CurSegment->OrgSize - SegmentPos;\n\tCurPos = pos;\n}\n//---------------------------------------------------------------------------\nbool tTVPXP3ArchiveStream::OpenNextSegment()\n{\n\t// open next segment\n\tif(CurSegmentNum == (tjs_int)(Segments->size() -1))\n\t\treturn false; // no more segments\n\tCurSegmentNum ++;\n\tCurSegment = &(Segments->operator [](CurSegmentNum));\n\tSegmentOpened = false;\n\tSegmentPos = 0;\n\tSegmentRemain = CurSegment->OrgSize;\n\tCurPos = CurSegment->Offset;\n\tEnsureSegment();\n\treturn true;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPXP3ArchiveStream::Seek(tjs_int64 offset, tjs_int whence)\n{\n\ttjs_int64 newpos;\n\tswitch(whence)\n\t{\n\tcase TJS_BS_SEEK_SET:\n\t\tnewpos = offset;\n\t\tif(newpos >= 0 && newpos <= static_cast<tjs_int64>(OrgSize) )\n\t\t{\n\t\t\tSeekToPosition(newpos);\n\t\t}\n\t\treturn CurPos;\n\n\tcase TJS_BS_SEEK_CUR:\n\t\tnewpos = offset + CurPos;\n\t\tif(newpos >= 0 && newpos <= static_cast<tjs_int64>(OrgSize) )\n\t\t{\n\t\t\tSeekToPosition(newpos);\n\t\t}\n\t\treturn CurPos;\n\n\tcase TJS_BS_SEEK_END:\n\t\tnewpos = offset + OrgSize;\n\t\tif(newpos >= 0 && newpos <= static_cast<tjs_int64>(OrgSize) )\n\t\t{\n\t\t\tSeekToPosition(newpos);\n\t\t}\n\t\treturn CurPos;\n\t}\n\treturn CurPos;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPXP3ArchiveStream::Read(void *buffer, tjs_uint read_size)\n{\n\tEnsureSegment();\n\n\ttjs_uint write_size = 0;\n\twhile(read_size)\n\t{\n\t\twhile(SegmentRemain == 0)\n\t\t{\n\t\t\t// must go next segment\n\t\t\tif(!OpenNextSegment()) // open next segment\n\t\t\t\treturn write_size; // could not read more\n\t\t}\n\n\t\ttjs_uint one_size =\n\t\t\tread_size > SegmentRemain ? (tjs_uint)SegmentRemain : read_size;\n\n\t\tif(CurSegment->IsCompressed)\n\t\t{\n\t\t\t// compressed segment; read from uncompressed data in memory\n\t\t\tmemcpy((tjs_uint8*)buffer + write_size,\n\t\t\t\tSegmentData->GetData() + (tjs_uint)SegmentPos, one_size);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// read directly from stream\n\t\t\tStream->ReadBuffer((tjs_uint8*)buffer + write_size, one_size);\n\t\t}\n\n\t\t// execute filter (for encryption method)\n\t\tif(TVPXP3ArchiveExtractionFilter)\n\t\t{\n\t\t\ttTVPXP3ExtractionFilterInfo info(CurPos, (tjs_uint8*)buffer + write_size,\n\t\t\t\tone_size, Owner->GetFileHash(StorageIndex), Owner->GetName(StorageIndex));\n\t\t\tTVPXP3ArchiveExtractionFilter\n\t\t\t\t( (tTVPXP3ExtractionFilterInfo*) &info, &FilterContext );\n\t\t}\n\n\t\t// adjust members\n\t\tSegmentPos += one_size;\n\t\tCurPos += one_size;\n\t\tSegmentRemain -= one_size;\n\t\tread_size -= one_size;\n\t\twrite_size += one_size;\n\t}\n\n\treturn write_size;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPXP3ArchiveStream::Write(const void *buffer, tjs_uint write_size)\n{\n\treturn 0;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPXP3ArchiveStream::GetSize()\n{\n\treturn OrgSize;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Archive extraction utility\n//---------------------------------------------------------------------------\n#define TVP_LOCAL_TEMP_COPY_BLOCK_SIZE 65536*2\n#if 0\n// this routine is obsoleted because the Releaser includes over 256-characters\n// file name if the user specifies \"protect over the archive\" option.\n// Windows cannot handle such too long filename.\nvoid TVPExtractArchive(const ttstr & name, const ttstr & _destdir, bool allowextractprotected)\n{\n\t// extract file to\n\tbool TVPAllowExtractProtectedStorage_save =\n\t\tTVPAllowExtractProtectedStorage;\n\tTVPAllowExtractProtectedStorage = allowextractprotected;\n\ttry\n\t{\n\n\t\tttstr destdir(_destdir);\n\t\ttjs_char last = _destdir.GetLastChar();\n\t\tif(_destdir.GetLen() >= 1 && (last != TJS_W('/') && last != TJS_W('\\\\')))\n\t\t\tdestdir += TJS_W('/');\n\n\t\ttTVPArchive *arc = TVPOpenArchive(name);\n\t\ttry\n\t\t{\n\t\t\ttjs_int count = arc->GetCount();\n\t\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tttstr name = arc->GetName(i);\n\n\t\t\t\ttTJSBinaryStream *src = arc->CreateStreamByIndex(i);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\ttTVPStreamHolder dest(destdir + name, TJS_BS_WRITE);\n\t\t\t\t\ttjs_uint8 * buffer = new tjs_uint8[TVP_LOCAL_TEMP_COPY_BLOCK_SIZE];\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_uint read;\n\t\t\t\t\t\twhile(true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tread = src->Read(buffer, TVP_LOCAL_TEMP_COPY_BLOCK_SIZE);\n\t\t\t\t\t\t\tif(read == 0) break;\n\t\t\t\t\t\t\tdest->WriteBuffer(buffer, read);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] buffer;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tdelete [] buffer;\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n//\t\t\t\t\tdelete src;\n//\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tdelete src;\n\t\t\t}\n\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tarc->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\tarc->Release();\n\t}\n\tcatch(...)\n\t{\n\t\tTVPAllowExtractProtectedStorage =\n\t\t\tTVPAllowExtractProtectedStorage_save;\n\t\tthrow;\n\t}\n\tTVPAllowExtractProtectedStorage =\n\t\tTVPAllowExtractProtectedStorage_save;\n}\n#endif\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/base/XP3Archive.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// XP3 virtual file system support\n//---------------------------------------------------------------------------\n\n#ifndef XP3ArchiveH\n#define XP3ArchiveH\n\n\n#include \"StorageIntf.h\"\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// Extraction filter related\n//---------------------------------------------------------------------------\n#pragma pack(push, 4)\nstruct tTVPXP3ExtractionFilterInfo\n{\n\tconst tjs_uint SizeOfSelf; // structure size of tTVPXP3ExtractionFilterInfo itself\n\tconst tjs_uint64 Offset; // offset of the buffer data in uncompressed stream position\n\tvoid * Buffer; // target data buffer\n\tconst tjs_uint BufferSize; // buffer size in bytes pointed by \"Buffer\"\n\tconst tjs_uint32 FileHash; // hash value of the file (since inteface v2)\n\tconst ttstr &FileName;\n\n\ttTVPXP3ExtractionFilterInfo(tjs_uint64 offset, void *buffer,\n\t\ttjs_uint buffersize, tjs_uint32 filehash, const ttstr& filename) :\n\t\t\tOffset(offset), Buffer(buffer), BufferSize(buffersize),\n\t\t\tFileHash(filehash), FileName(filename),\n\t\t\tSizeOfSelf(sizeof(tTVPXP3ExtractionFilterInfo)) {;}\n};\n#pragma pack(pop)\n\n#ifndef TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION\n\t#ifdef _WIN32\n\t\t#define\tTVP_tTVPXP3ArchiveExtractionFilter_CONVENTION _stdcall\n\t#else\n\t\t#define TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION\n\t#endif\n#endif\n\t// TVP_tTVPXP3ArchiveExtractionFilter_CONV is _stdcall on win32 platforms,\n\t// for backward application compatibility.\n\ntypedef void (TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION *\n\ttTVPXP3ArchiveExtractionFilter)(tTVPXP3ExtractionFilterInfo *info, tTJSVariant *ctx);\ntypedef tjs_int (TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION *\n\ttTVPXP3ArchiveContentFilter)(const ttstr &filepath, const ttstr &archivename, tjs_uint64 filesize, tTJSVariant *ctx);\n\n/*]*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPSetXP3ArchiveExtractionFilter, (tTVPXP3ArchiveExtractionFilter filter));\nTJS_EXP_FUNC_DEF(void, TVPSetXP3ArchiveContentFilter, (tTVPXP3ArchiveContentFilter filter));\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPXP3Archive  : XP3 ( TVP's native archive format ) Implmentation\n//---------------------------------------------------------------------------\n#define TVP_XP3_INDEX_ENCODE_METHOD_MASK 0x07\n#define TVP_XP3_INDEX_ENCODE_RAW      0\n#define TVP_XP3_INDEX_ENCODE_ZLIB     1\n\n#define TVP_XP3_INDEX_CONTINUE   0x80\n\n#define TVP_XP3_FILE_PROTECTED (1<<31)\n\n#define TVP_XP3_SEGM_ENCODE_METHOD_MASK  0x07\n#define TVP_XP3_SEGM_ENCODE_RAW       0\n#define TVP_XP3_SEGM_ENCODE_ZLIB      1\n\n//---------------------------------------------------------------------------\nextern bool TVPIsXP3Archive(const ttstr &name); // check XP3 archive\nextern void TVPClearXP3SegmentCache(); // clear XP3 segment cache\n//---------------------------------------------------------------------------\nstruct tTVPXP3ArchiveSegment\n{\n\ttjs_uint64 Start;  // start position in archive storage\n\ttjs_uint64 Offset; // offset in in-archive storage (in uncompressed offset)\n\ttjs_uint64 OrgSize; // original segment (uncompressed) size\n\ttjs_uint64 ArcSize; // in-archive segment (compressed) size\n\tbool IsCompressed; // is compressed ?\n};\n//---------------------------------------------------------------------------\nclass tTVPXP3Archive : public tTVPArchive\n{\npublic:\n\tstruct tArchiveItem\n\t{\n\t\tttstr Name;\n\t\ttjs_uint32 FileHash;\n\t\ttjs_uint64 OrgSize; // original ( uncompressed ) size\n\t\ttjs_uint64 ArcSize; // in-archive size\n\t\tstd::vector<tTVPXP3ArchiveSegment> Segments;\n\t\tbool operator < (const tArchiveItem &rhs) const\n\t\t{\n\t\t\treturn this->Name < rhs.Name;\n\t\t}\n\t};\n\n\ttjs_int Count = 0;\n\n\tstd::vector<tArchiveItem> ItemVector;\n\tvoid Init(tTJSBinaryStream *st, tjs_int64 offset, bool normalizeName = true);\n\npublic:\n\ttTVPXP3Archive(const ttstr & name, int) : tTVPArchive(name) {}\n\ttTVPXP3Archive(const ttstr & name, tTJSBinaryStream *st = nullptr, tjs_int64 offset = -1, bool normalizeFileName = true);\n\t~tTVPXP3Archive();\n\n\tstatic tTVPArchive *Create(const ttstr & name, tTJSBinaryStream *st = nullptr, bool normalizeFileName = true);\n\n\ttjs_uint GetCount() { return Count; }\n\tconst ttstr & GetName(tjs_uint idx) const { return ItemVector[idx].Name; }\n\ttjs_uint32 GetFileHash(tjs_uint idx) const { return ItemVector[idx].FileHash; }\n\tttstr GetName(tjs_uint idx) { return ItemVector[idx].Name; }\n\n\tconst ttstr & GetName() const { return ArchiveName; }\n\n\ttTJSBinaryStream * CreateStreamByIndex(tjs_uint idx);\n\nprivate:\n\tstatic bool FindChunk(const tjs_uint8 *data, const tjs_uint8 * name,\n\t\ttjs_uint &start, tjs_uint &size);\n\tstatic tjs_int16 ReadI16FromMem(const tjs_uint8 *mem);\n\tstatic tjs_int32 ReadI32FromMem(const tjs_uint8 *mem);\n\tstatic tjs_int64 ReadI64FromMem(const tjs_uint8 *mem);\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPXP3ArchiveStream  : XP3 In-Archive Stream Implmentation\n//---------------------------------------------------------------------------\nclass tTVPSegmentData;\nclass tTVPXP3ArchiveStream : public tTJSBinaryStream\n{\n\ttTVPXP3Archive * Owner;\n\n\ttjs_int StorageIndex; // index in archive\n\n\tstd::vector<tTVPXP3ArchiveSegment> * Segments;\n\ttTJSBinaryStream * Stream;\n\ttjs_uint64 OrgSize; // original storage size\n\n\ttjs_int CurSegmentNum;\n\ttTVPXP3ArchiveSegment *CurSegment;\n\t\t// currently opened segment ( NULL for not opened )\n\n\ttjs_int LastOpenedSegmentNum;\n\n\ttjs_uint64 CurPos; // current position in absolute file position\n\n\ttjs_uint64 SegmentRemain; // remain bytes in current segment\n\ttjs_uint64 SegmentPos; // offset from current segment's start\n\n\ttTVPSegmentData *SegmentData; // uncompressed segment data\n\n\tbool SegmentOpened;\n\ttTJSVariant FilterContext;\n\npublic:\n\ttTVPXP3ArchiveStream(tTVPXP3Archive *owner, tjs_int storageindex,\n\t\tstd::vector<tTVPXP3ArchiveSegment> *segments, tTJSBinaryStream *stream,\n\t\t\ttjs_uint64 orgsize);\n\t~tTVPXP3ArchiveStream();\n\ttTJSVariant &GetFilterContext() { return FilterContext; }\n\nprivate:\n\tvoid EnsureSegment(); // ensure accessing to current segment\n\tvoid SeekToPosition(tjs_uint64 pos); // open segment at 'pos' and seek\n\tbool OpenNextSegment();\n\n\npublic:\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence);\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size);\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size);\n\ttjs_uint64 TJS_INTF_METHOD GetSize();\n\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/ZIPArchive.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"StorageIntf.h\"\n#include \"UtilStreams.h\"\n#include <algorithm>\n\n#ifndef NOUNCRYPT\n        #define NOUNCRYPT\n#endif\n\n#include \"unzip/ioapi_mem.h\"\n#include \"unzip/unzip.h\"\n#undef ZEXPORT\n#define ZEXPORT\n\n//using namespace cocos2d;\ntypedef cocos2d::ZPOS64_T ZPOS64_T;\ntypedef cocos2d::zlib_filefunc64_32_def zlib_filefunc64_32_def;\ntypedef cocos2d::unz_global_info64 unz_global_info64;\ntypedef cocos2d::zlib_filefunc_def zlib_filefunc_def;\ntypedef cocos2d::zlib_filefunc64_def zlib_filefunc64_def;\ntypedef cocos2d::unz_global_info unz_global_info;\ntypedef cocos2d::tm_unz tm_unz;\ntypedef struct unz_file_info_s\n{\n\tuLong version;              /* version made by                 2 bytes */\n\tuLong version_needed;       /* version needed to extract       2 bytes */\n\tuLong flag;                 /* general purpose bit flag        2 bytes */\n\tuLong compression_method;   /* compression method              2 bytes */\n\tuLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n\tuLong crc;                  /* crc-32                          4 bytes */\n\tuLong compressed_size;      /* compressed size                 4 bytes */\n\tuLong uncompressed_size;    /* uncompressed size               4 bytes */\n\tuLong size_filename;        /* filename length                 2 bytes */\n\tuLong size_file_extra;      /* extra field length              2 bytes */\n\tuLong size_file_comment;    /* file comment length             2 bytes */\n\tZPOS64_T offset_curfile;\n\tuLong disk_num_start;       /* disk number start               2 bytes */\n\tuLong internal_fa;          /* internal file attributes        2 bytes */\n\tuLong external_fa;          /* external file attributes        4 bytes */\n\n\ttm_unz tmu_date;\n} unz_file_info;\ntypedef cocos2d::unz_file_pos unz_file_pos;\ntypedef struct unz64_file_pos_s\n{\n\tZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */\n\tZPOS64_T num_of_file;            /* # of file */\n} unz64_file_pos;\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\n    extern int errno;\n#else\n#   include <errno.h>\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n\n#ifndef CASESENSITIVITYDEFAULT_NO\n#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)\n#    define CASESENSITIVITYDEFAULT_NO\n#  endif\n#endif\n\n\n#ifndef UNZ_BUFSIZE\n#define UNZ_BUFSIZE (16384)\n#endif\n\n#ifndef UNZ_MAXFILENAMEINZIP\n#define UNZ_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n# define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n# define TRYFREE(p) {if (p) free(p);}\n#endif\n\n#define SIZECENTRALDIRITEM (0x2e)\n#define SIZEZIPLOCALHEADER (0x1e)\n\n\nconst char unz_copyright[] =\n   \" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n/* unz_file_info_interntal contain internal info about a file in zipfile*/\ntypedef struct unz_file_info64_internal_s\n{\n    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */\n} unz_file_info64_internal;\n\n\n/* file_in_zip_read_info_s contain internal information about a file in zipfile,\n    when reading and decompress it */\ntypedef struct\n{\n    char  *read_buffer;         /* internal buffer for compressed data */\n    z_stream stream;            /* zLib stream structure for inflate */\n\n#ifdef HAVE_BZIP2\n    bz_stream bstream;          /* bzLib stream structure for bziped */\n#endif\n\n    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/\n    uLong stream_initialised;   /* flag set if stream structure is initialized*/\n\n    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */\n    uInt  size_local_extrafield;/* size of the local extra field */\n    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/\n    ZPOS64_T total_out_64;\n\n    uLong crc32;                /* crc32 of all data uncompressed */\n    uLong crc32_wait;           /* crc32 we must obtain after decompress all */\n    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */\n    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/\n    //zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;        /* io structure of the zipfile */\n    uLong compression_method;   /* compression method (0==store) */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    int   raw;\n} file_in_zip64_read_info_s;\n\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_info64_s\n{\n    uLong version;              /* version made by                 2 bytes */\n    uLong version_needed;       /* version needed to extract       2 bytes */\n    uLong flag;                 /* general purpose bit flag        2 bytes */\n    uLong compression_method;   /* compression method              2 bytes */\n    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    uLong crc;                  /* crc-32                          4 bytes */\n    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */\n    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */\n    uLong size_filename;        /* filename length                 2 bytes */\n    uLong size_file_extra;      /* extra field length              2 bytes */\n    uLong size_file_comment;    /* file comment length             2 bytes */\n    \n    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */\n    uLong disk_num_start;       /* disk number start               2 bytes */\n    uLong internal_fa;          /* internal file attributes        2 bytes */\n    uLong external_fa;          /* external file attributes        4 bytes */\n    \n    tm_unz tmu_date;\n} unz_file_info64;\n\n/* unz64_s contain internal information about the zipfile\n*/\ntypedef struct\n{\n    //zlib_filefunc64_32_def z_filefunc;\n    int is64bitOpenFunction;\n    voidpf filestream;        /* io structure of the zipfile */\n    unz_global_info64 gi;       /* public global information */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    ZPOS64_T num_file;             /* number of the current file in the zipfile*/\n    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/\n    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/\n    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/\n\n    ZPOS64_T size_central_dir;     /* size of the central directory  */\n    ZPOS64_T offset_central_dir;   /* offset of start of central directory with\n                                   respect to the starting disk number */\n\n    unz_file_info64 cur_file_info; /* public info about the current file in zip*/\n    unz_file_info64_internal cur_file_info_internal; /* private info about it*/\n    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current\n                                        file if we are decompressing it */\n    int encrypted;\n\n    int isZip64;\n\n#    ifndef NOUNCRYPT\n    unsigned long keys[3];     /* keys defining the pseudo-random sequence */\n    const unsigned long* pcrc_32_tab;\n#    endif\n} unz64_s;\n\n\n#ifndef NOUNCRYPT\n#include \"crypt.h\"\n#endif\n\nstatic voidpf zip_open64file(voidpf opaque, const void * filename, int mode) {\n\tif (mode == (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING))\n\t\treturn (voidpf)filename;\n\treturn nullptr;\n}\n\nstatic uLong zip_readfile(voidpf, voidpf s, void *buf, uLong size);\nstatic uLong zip_writefile(voidpf, voidpf s, const void *buf, uLong size);\nstatic ZPOS64_T zip_tell64file(voidpf, voidpf s);\nstatic long zip_seek64file(voidpf, voidpf s, ZPOS64_T offset, int origin);\n\nstatic int zip_closefile(voidpf, voidpf s) {\n//\tdelete ((tTJSBinaryStream*)s);\n\treturn 0;\n}\n\nstatic zlib_filefunc64_32_def zipfunc = {\n\t{\n\t\tzip_open64file,\n\t\tzip_readfile,\n\t\tzip_writefile,\n\t\tzip_tell64file,\n\t\tzip_seek64file,\n\t\tzip_closefile,\n\t\tnullptr,\n\t\tnullptr\n\t},\n\tnullptr,\n\tnullptr,\n\tnullptr\n};\n\n/* ===========================================================================\n     Read a byte from a gz_stream; update next_in and avail_in. Return EOF\n   for end of file.\n   IN assertion: the stream s has been successfully opened for reading.\n*/\n\n\nlocal int unz64local_getByte OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    int *pi));\n\nlocal int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)\n{\n    unsigned char c;\n    int err = (int)zip_readfile(nullptr,filestream,&c,1);\n    if (err==1)\n    {\n        *pi = (int)c;\n        return UNZ_OK;\n    }\n    else\n    {\n//         if (ZERROR64(nullptr,filestream))\n//             return UNZ_ERRNO;\n//         else\n            return UNZ_EOF;\n    }\n}\n\n\n/* ===========================================================================\n   Reads a long in LSB order from the given gz_stream. Sets\n*/\nlocal int unz64local_getShort OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                             voidpf filestream,\n                             uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<24;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    ZPOS64_T *pX));\n\n\nlocal int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            ZPOS64_T *pX)\n{\n    ZPOS64_T x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (ZPOS64_T)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<24;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<32;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<40;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<48;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<56;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\n/* My own strcmpi / strcasecmp */\nlocal int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)\n{\n    for (;;)\n    {\n        char c1=*(fileName1++);\n        char c2=*(fileName2++);\n        if ((c1>='a') && (c1<='z'))\n            c1 -= 0x20;\n        if ((c2>='a') && (c2<='z'))\n            c2 -= 0x20;\n        if (c1=='\\0')\n            return ((c2=='\\0') ? 0 : -1);\n        if (c2=='\\0')\n            return 1;\n        if (c1<c2)\n            return -1;\n        if (c1>c2)\n            return 1;\n    }\n}\n\n\n#ifdef  CASESENSITIVITYDEFAULT_NO\n#define CASESENSITIVITYDEFAULTVALUE 2\n#else\n#define CASESENSITIVITYDEFAULTVALUE 1\n#endif\n\n#ifndef STRCMPCASENOSENTIVEFUNCTION\n#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal\n#endif\n\n/*\n   Compare two filename (fileName1,fileName2).\n   If iCaseSenisivity = 1, comparison is case sensitivity (like strcmp)\n   If iCaseSenisivity = 2, comparison is not case sensitivity (like strcmpi\n                                                                or strcasecmp)\n   If iCaseSenisivity = 0, case sensitivity is default of your operating system\n        (like 1 on Unix, 2 on Windows)\n\n*/\nint ZEXPORT unzStringFileNameCompare (const char*  fileName1,\n                                                 const char*  fileName2,\n                                                 int iCaseSensitivity)\n\n{\n    if (iCaseSensitivity==0)\n        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;\n\n    if (iCaseSensitivity==1)\n        return strcmp(fileName1,fileName2);\n\n    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);\n}\n\n#ifndef BUFREADCOMMENT\n#define BUFREADCOMMENT (0x400)\n#endif\n\n/*\n  Locate the Central directory of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\nlocal ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n\n\tif (zip_seek64file(nullptr, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n\tuSizeFile = zip_tell64file(nullptr, filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos ;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n\t\tif (zip_seek64file(nullptr, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            break;\n\n\t\tif (zip_readfile(nullptr, filestream, buf, uReadSize) != uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    return uPosFound;\n}\n\n\n/*\n  Locate the Central directory 64 of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream));\n\nlocal ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                                      voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n    uLong uL;\n                ZPOS64_T relativeOffset;\n\n    if (zip_seek64file(nullptr,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n    uSizeFile = zip_tell64file(nullptr,filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n        if (zip_seek64file(nullptr,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            break;\n\n        if (zip_readfile(nullptr,filestream,buf,uReadSize)!=uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    if (uPosFound == 0)\n        return 0;\n\n    /* Zip64 end of central directory locator */\n    if (zip_seek64file(nullptr,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n    /* the signature, already checked */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    /* number of the disk with the start of the zip64 end of  central directory */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 0)\n        return 0;\n\n    /* relative offset of the zip64 end of central directory record */\n    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)\n        return 0;\n\n    /* total number of disks */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 1)\n        return 0;\n\n    /* Goto end of central directory record */\n    if (zip_seek64file(nullptr,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n     /* the signature */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    if (uL != 0x06064b50)\n        return 0;\n\n    return relativeOffset;\n}\n\nint ZEXPORT unzGoToFirstFile64(unzFile file,\n\tunz_file_info64 *pfile_info,\n\tchar *szFileName,\n\tuLong fileNameBufferSize);\n\n/*\n  Open a Zip file. path contain the full pathname (by example,\n     on a Windows NT computer \"c:\\\\test\\\\zlib114.zip\" or on an Unix computer\n     \"zlib/zlib114.zip\".\n     If the zipfile cannot be opened (file doesn't exist or in not valid), the\n       return value is NULL.\n     Else, the return value is a unzFile Handle, usable with other function\n       of this unzip package.\n*/\nlocal unzFile unzOpenInternal (const void *path,\n                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,\n                               int is64bitOpenFunction)\n{\n    unz64_s us;\n    unz64_s *s;\n    ZPOS64_T central_pos;\n    uLong   uL;\n\n    uLong number_disk;          /* number of the current dist, used for\n                                   spanning ZIP, unsupported, always 0*/\n    uLong number_disk_with_CD;  /* number the the disk with central dir, used\n                                   for spanning ZIP, unsupported, always 0*/\n    ZPOS64_T number_entry_CD;      /* total number of entries in\n                                   the central dir\n                                   (same than number_entry on nospan) */\n\n    int err=UNZ_OK;\n\n    if (unz_copyright[0]!=' ')\n        return NULL;\n\n//     us.z_filefunc.zseek32_file = NULL;\n//     us.z_filefunc.ztell32_file = NULL;\n//     us.z_filefunc = *pzlib_filefunc64_32_def;\n    us.is64bitOpenFunction = is64bitOpenFunction;\n\n\n\n\tus.filestream = zip_open64file(nullptr,\n                                                 path,\n                                                 ZLIB_FILEFUNC_MODE_READ |\n                                                 ZLIB_FILEFUNC_MODE_EXISTING);\n    if (us.filestream==NULL)\n        return NULL;\n\n    central_pos = unz64local_SearchCentralDir64(nullptr,us.filestream);\n    if (central_pos)\n    {\n        uLong uS;\n        ZPOS64_T uL64;\n\n        us.isZip64 = 1;\n\n\t\tif (zip_seek64file(nullptr, us.filestream,\n                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n\t\tif (unz64local_getLong(nullptr, us.filestream, &uL) != UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* size of zip64 end of central directory record */\n        if (unz64local_getLong64(nullptr, us.filestream,&uL64)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version made by */\n        if (unz64local_getShort(nullptr, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version needed to extract */\n        if (unz64local_getShort(nullptr, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getLong(nullptr, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getLong(nullptr, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory on this disk */\n        if (unz64local_getLong64(nullptr, us.filestream,&us.gi.number_entry)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory */\n        if (unz64local_getLong64(nullptr, us.filestream,&number_entry_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong64(nullptr, us.filestream,&us.size_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* offset of start of central directory with respect to the\n          starting disk number */\n        if (unz64local_getLong64(nullptr, us.filestream,&us.offset_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        us.gi.size_comment = 0;\n    }\n    else\n    {\n        central_pos = unz64local_SearchCentralDir(nullptr,us.filestream);\n        if (central_pos==0)\n            err=UNZ_ERRNO;\n\n        us.isZip64 = 0;\n\n        if (zip_seek64file(nullptr, us.filestream,\n                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getShort(nullptr, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getShort(nullptr, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central dir on this disk */\n        if (unz64local_getShort(nullptr, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.gi.number_entry = uL;\n\n        /* total number of entries in the central dir */\n        if (unz64local_getShort(nullptr, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        number_entry_CD = uL;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.size_central_dir = uL;\n\n        /* offset of start of central directory with respect to the\n            starting disk number */\n        if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.offset_central_dir = uL;\n\n        /* zipfile comment length */\n        if (unz64local_getShort(nullptr, us.filestream,&us.gi.size_comment)!=UNZ_OK)\n            err=UNZ_ERRNO;\n    }\n\n    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&\n        (err==UNZ_OK))\n        err=UNZ_BADZIPFILE;\n\n    if (err!=UNZ_OK)\n    {\n\t\tzip_closefile(nullptr, us.filestream);\n        return NULL;\n    }\n\n    us.byte_before_the_zipfile = central_pos -\n                            (us.offset_central_dir+us.size_central_dir);\n    us.central_pos = central_pos;\n    us.pfile_in_zip_read = NULL;\n    us.encrypted = 0;\n\n\n    s=(unz64_s*)ALLOC(sizeof(unz64_s));\n    if( s != NULL)\n    {\n        *s=us;\n\t\tunzGoToFirstFile64((unzFile)s, NULL, NULL, 0);\n    }\n    return (unzFile)s;\n}\n    \nint ZEXPORT unzCloseCurrentFile(unzFile file);\n/*\n  Close a ZipFile opened with unzipOpen.\n  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),\n    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.\n  return UNZ_OK if there is no problem. */\nint ZEXPORT unzClose (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    if (s->pfile_in_zip_read!=NULL)\n        unzCloseCurrentFile(file);\n\n\tzip_closefile(nullptr, s->filestream);\n    TRYFREE(s);\n    return UNZ_OK;\n}\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem. */\nint ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    *pglobal_info=s->gi;\n    return UNZ_OK;\n}\n\nint ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    /* to do : check if number_entry is not truncated */\n    pglobal_info32->number_entry = (uLong)s->gi.number_entry;\n    pglobal_info32->size_comment = s->gi.size_comment;\n    return UNZ_OK;\n}\n/*\n   Translate date/time from Dos format to tm_unz (readable more easily)\n*/\nlocal void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)\n{\n    ZPOS64_T uDate;\n    uDate = (ZPOS64_T)(ulDosDate>>16);\n    ptm->tm_mday = (uInt)(uDate&0x1f) ;\n    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;\n    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;\n\n    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);\n    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;\n    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;\n}\n\n/*\n  Get Info about the current file in the zipfile, with internal only info\n*/\nlocal int unz64local_GetCurrentFileInfoInternal (unzFile file,\n                                                  unz_file_info64 *pfile_info,\n                                                  unz_file_info64_internal\n                                                  *pfile_info_internal,\n                                                  char *szFileName,\n                                                  uLong fileNameBufferSize,\n                                                  void *extraField,\n                                                  uLong extraFieldBufferSize,\n                                                  char *szComment,\n                                                  uLong commentBufferSize)\n{\n    unz64_s* s;\n    unz_file_info64 file_info;\n    unz_file_info64_internal file_info_internal;\n    int err=UNZ_OK;\n    uLong uMagic;\n    long lSeek=0;\n    uLong uL;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\tif (zip_seek64file(nullptr, s->filestream,\n              s->pos_in_central_dir+s->byte_before_the_zipfile,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n\n    /* we check the magic */\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(nullptr, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x02014b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.version) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.version_needed) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.flag) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.compression_method) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(nullptr, s->filestream,&file_info.dosDate) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);\n\n    if (unz64local_getLong(nullptr, s->filestream,&file_info.crc) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.compressed_size = uL;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.uncompressed_size = uL;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.size_file_extra) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.size_file_comment) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.disk_num_start) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&file_info.internal_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(nullptr, s->filestream,&file_info.external_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n                // relative offset of local header\n    if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info_internal.offset_curfile = uL;\n\n    lSeek+=file_info.size_filename;\n    if ((err==UNZ_OK) && (szFileName!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_filename<fileNameBufferSize)\n        {\n            *(szFileName+file_info.size_filename)='\\0';\n            uSizeRead = file_info.size_filename;\n        }\n        else\n            uSizeRead = fileNameBufferSize;\n\n        if ((file_info.size_filename>0) && (fileNameBufferSize>0))\n\t\t\tif (zip_readfile(nullptr, s->filestream, szFileName, uSizeRead) != uSizeRead)\n                err=UNZ_ERRNO;\n        lSeek -= uSizeRead;\n    }\n\n    // Read extrafield\n    if ((err==UNZ_OK) && (extraField!=NULL))\n    {\n        ZPOS64_T uSizeRead ;\n        if (file_info.size_file_extra<extraFieldBufferSize)\n            uSizeRead = file_info.size_file_extra;\n        else\n            uSizeRead = extraFieldBufferSize;\n\n        if (lSeek!=0)\n        {\n\t\t\tif (zip_seek64file(nullptr, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))\n\t\t\tif (zip_readfile(nullptr, s->filestream, extraField, (uLong)uSizeRead) != uSizeRead)\n                err=UNZ_ERRNO;\n\n        lSeek += file_info.size_file_extra - (uLong)uSizeRead;\n    }\n    else\n        lSeek += file_info.size_file_extra;\n\n\n    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))\n    {\n                                uLong acc = 0;\n\n        // since lSeek now points to after the extra field we need to move back\n        lSeek -= file_info.size_file_extra;\n\n        if (lSeek!=0)\n        {\n\t\t\tif (zip_seek64file(nullptr, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        while(acc < file_info.size_file_extra)\n        {\n            uLong headerId;\n            uLong dataSize;\n\n            if (unz64local_getShort(nullptr, s->filestream,&headerId) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            if (unz64local_getShort(nullptr, s->filestream,&dataSize) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            /* ZIP64 extra fields */\n            if (headerId == 0x0001)\n            {\n                uLong uL2;\n\n                if (file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)\n                {\n                    if (unz64local_getLong64(nullptr, s->filestream,&file_info.uncompressed_size) != UNZ_OK)\n                        err=UNZ_ERRNO;\n                    }\n\n                if (file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)\n                {\n                    if (unz64local_getLong64(nullptr, s->filestream,&file_info.compressed_size) != UNZ_OK)\n                        err=UNZ_ERRNO;\n                }\n\n                if (file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)\n                {\n                    /* Relative Header offset */\n                    if (unz64local_getLong64(nullptr, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)\n                        err=UNZ_ERRNO;\n                }\n\n                if(file_info.disk_num_start == (unsigned long)-1)\n                {\n                    /* Disk Start Number */\n                    if (unz64local_getLong(nullptr, s->filestream, &uL2) != UNZ_OK)\n                        err=UNZ_ERRNO;\n                }\n\n            }\n            else\n            {\n\t\t\t\tif (zip_seek64file(nullptr, s->filestream, dataSize, ZLIB_FILEFUNC_SEEK_CUR) != 0)\n                    err=UNZ_ERRNO;\n            }\n\n            acc += 2 + 2 + dataSize;\n        }\n    }\n\n    if ((err==UNZ_OK) && (szComment!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_file_comment<commentBufferSize)\n        {\n            *(szComment+file_info.size_file_comment)='\\0';\n            uSizeRead = file_info.size_file_comment;\n        }\n        else\n            uSizeRead = commentBufferSize;\n\n        if (lSeek!=0)\n        {\n            if (zip_seek64file(nullptr, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) {\n              //lSeek=0;\n\t\t\t}\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_comment>0) && (commentBufferSize>0))\n            if (zip_readfile(nullptr, s->filestream,szComment,uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n        //lSeek+=file_info.size_file_comment - uSizeRead;\n    }\n    //else\n    //    lSeek+=file_info.size_file_comment;\n\n\n\tif ((err == UNZ_OK) && (pfile_info != NULL)) {\n\t\t*pfile_info = file_info;\n\t\tpfile_info->offset_curfile = file_info_internal.offset_curfile +\n\t\t\ts->byte_before_the_zipfile;\n\t}\n\n    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))\n        *pfile_info_internal=file_info_internal;\n\n    return err;\n}\n\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem.\n*/\nint ZEXPORT unzGetCurrentFileInfo64 (unzFile file,\n                                          unz_file_info64 * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize,\n                                          char* szComment,  uLong commentBufferSize)\n{\n    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                szComment,commentBufferSize);\n}\n\nint ZEXPORT unzGetCurrentFileInfo (unzFile file,\n                                          unz_file_info * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize)\n{\n    int err;\n    unz_file_info64 file_info64;\n    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                nullptr,0);\n    if (err==UNZ_OK)\n    {\n        pfile_info->version = file_info64.version;\n        pfile_info->version_needed = file_info64.version_needed;\n        pfile_info->flag = file_info64.flag;\n        pfile_info->compression_method = file_info64.compression_method;\n        pfile_info->dosDate = file_info64.dosDate;\n        pfile_info->crc = file_info64.crc;\n\n        pfile_info->size_filename = file_info64.size_filename;\n        pfile_info->size_file_extra = file_info64.size_file_extra;\n        pfile_info->size_file_comment = file_info64.size_file_comment;\n\n        pfile_info->disk_num_start = file_info64.disk_num_start;\n        pfile_info->internal_fa = file_info64.internal_fa;\n        pfile_info->external_fa = file_info64.external_fa;\n\n\t\tpfile_info->tmu_date = file_info64.tmu_date,\n\t\tpfile_info->offset_curfile = file_info64.offset_curfile;\n\n        pfile_info->compressed_size = (uLong)file_info64.compressed_size;\n        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;\n\n    }\n    return err;\n}\n\n/*\n  Set the current file of the zipfile to the first file\n  with retrieving an information about the file.\n  return UNZ_OK if there is no problem\n*/\nint ZEXPORT unzGoToFirstFile64 (unzFile file,\n                        unz_file_info64 *pfile_info,\n                        char *szFileName,\n                        uLong fileNameBufferSize)\n{\n    int err=UNZ_OK;\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    s->pos_in_central_dir=s->offset_central_dir;\n    s->num_file=0;\n    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                             &s->cur_file_info_internal,\n                                             szFileName,fileNameBufferSize,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    if (pfile_info)\n        *pfile_info = s->cur_file_info;\n    return err;\n}\n\n/*\n  Set the current file of the zipfile to the next file\n  with retrieving an information about the file.\n  return UNZ_OK if there is no problem\n  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.\n*/\nint ZEXPORT unzGoToNextFile64 (unzFile file,\n                       unz_file_info64 *pfile_info,\n                       char *szFileName,\n                       uLong fileNameBufferSize)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */\n      if (s->num_file+1==s->gi.number_entry)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +\n            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;\n    s->num_file++;\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               szFileName,fileNameBufferSize,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    if (pfile_info)\n        *pfile_info = s->cur_file_info;\n    return err;\n}\n\n/*\n///////////////////////////////////////////\n// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)\n// I need random access\n//\n// Further optimization could be realized by adding an ability\n// to cache the directory in memory. The goal being a single\n// comprehensive file read to put the file I need in a memory.\n*/\n\n/*\ntypedef struct unz_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   // offset in file\n    ZPOS64_T num_of_file;            // # of file\n} unz_file_pos;\n*/\n\nint ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)\n{\n    unz64_s* s;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;\n    file_pos->num_of_file           = s->num_file;\n\n    return UNZ_OK;\n}\n\nint ZEXPORT unzGetFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    int err = unzGetFilePos64(file,&file_pos64);\n    if (err==UNZ_OK)\n    {\n        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;\n        file_pos->num_of_file = (uLong)file_pos64.num_of_file;\n    }\n    return err;\n}\n\nint ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    /* jump to the right spot */\n    s->pos_in_central_dir = file_pos->pos_in_zip_directory;\n    s->num_file           = file_pos->num_of_file;\n\n    /* set the current file */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               NULL,0,NULL,0,NULL,0);\n    /* return results */\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nint ZEXPORT unzGoToFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    if (file_pos == NULL)\n        return UNZ_PARAMERROR;\n\n    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;\n    file_pos64.num_of_file = file_pos->num_of_file;\n    return unzGoToFilePos64(file,&file_pos64);\n}\n\n/*\n// Unzip Helper Functions - should be here?\n///////////////////////////////////////////\n*/\n\n/*\n  Read the local header of the current zipfile\n  Check the coherency of the local header and info in the end of central\n        directory about this file\n  store in *piSizeVar the size of extra info in local header\n        (filename and size of extra field data)\n*/\nlocal int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,\n                                                    ZPOS64_T * poffset_local_extrafield,\n                                                    uInt  * psize_local_extrafield)\n{\n    uLong uMagic,uData,uFlags;\n    uLong size_filename;\n    uLong size_extra_field;\n    int err=UNZ_OK;\n\n    *piSizeVar = 0;\n    *poffset_local_extrafield = 0;\n    *psize_local_extrafield = 0;\n\n    if (zip_seek64file(nullptr, s->filestream,s->cur_file_info_internal.offset_curfile +\n                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(nullptr, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x04034b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(nullptr, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n/*\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))\n        err=UNZ_BADZIPFILE;\n*/\n    if (unz64local_getShort(nullptr, s->filestream,&uFlags) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(nullptr, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))\n        err=UNZ_BADZIPFILE;\n\n    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n                         (s->cur_file_info.compression_method!=Z_DEFLATED))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* date/time */\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* crc */\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* size compr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* size uncompr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getShort(nullptr, s->filestream,&size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))\n        err=UNZ_BADZIPFILE;\n\n    *piSizeVar += (uInt)size_filename;\n\n    if (unz64local_getShort(nullptr, s->filestream,&size_extra_field) != UNZ_OK)\n        err=UNZ_ERRNO;\n    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +\n                                    SIZEZIPLOCALHEADER + size_filename;\n    *psize_local_extrafield = (uInt)size_extra_field;\n\n    *piSizeVar += (uInt)size_extra_field;\n\n    return err;\n}\n\n/*\n  Open for reading data the current file in the zipfile.\n  If there is no error and the file is opened, the return value is UNZ_OK.\n*/\nint ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,\n                                            int* level, int raw, const char* password)\n{\n    int err=UNZ_OK;\n    uInt iSizeVar;\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */\n    uInt  size_local_extrafield;    /* size of the local extra field */\n#    ifndef NOUNCRYPT\n    char source[12];\n#    else\n    if (password != NULL)\n        return UNZ_PARAMERROR;\n#    endif\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_PARAMERROR;\n\n    if (s->pfile_in_zip_read != NULL)\n        unzCloseCurrentFile(file);\n\n    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)\n        return UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_INTERNALERROR;\n\n    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);\n    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;\n    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;\n    pfile_in_zip_read_info->pos_local_extrafield=0;\n    pfile_in_zip_read_info->raw=raw;\n\n    if (pfile_in_zip_read_info->read_buffer==NULL)\n    {\n        TRYFREE(pfile_in_zip_read_info);\n        return UNZ_INTERNALERROR;\n    }\n\n    pfile_in_zip_read_info->stream_initialised=0;\n\n    if (method!=NULL)\n        *method = (int)s->cur_file_info.compression_method;\n\n    if (level!=NULL)\n    {\n        *level = 6;\n        switch (s->cur_file_info.flag & 0x06)\n        {\n          case 6 : *level = 1; break;\n          case 4 : *level = 2; break;\n          case 2 : *level = 9; break;\n        }\n    }\n\n    if ((s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n        (s->cur_file_info.compression_method!=Z_DEFLATED)) {\n\n        //err=UNZ_BADZIPFILE;\n    }\n    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;\n    pfile_in_zip_read_info->crc32=0;\n    pfile_in_zip_read_info->total_out_64=0;\n    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;\n    pfile_in_zip_read_info->filestream=s->filestream;\n    //pfile_in_zip_read_info->z_filefunc=s->z_filefunc;\n    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;\n\n    pfile_in_zip_read_info->stream.total_out = 0;\n\n    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))\n    {\n#ifdef HAVE_BZIP2\n      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;\n      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;\n      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->bstream.state = (voidpf)0;\n\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = (voidpf)0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n#else\n      pfile_in_zip_read_info->raw=1;\n#endif\n    }\n    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))\n    {\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = 0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n        /* windowBits is passed < 0 to tell that there is no zlib header.\n         * Note that in this case inflate *requires* an extra \"dummy\" byte\n         * after the compressed stream in order to complete decompression and\n         * return Z_STREAM_END.\n         * In unzip, i don't wait absolutely Z_STREAM_END because I known the\n         * size of both compressed and uncompressed data\n         */\n    }\n    pfile_in_zip_read_info->rest_read_compressed =\n            s->cur_file_info.compressed_size ;\n    pfile_in_zip_read_info->rest_read_uncompressed =\n            s->cur_file_info.uncompressed_size ;\n\n\n    pfile_in_zip_read_info->pos_in_zipfile =\n            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +\n              iSizeVar;\n\n    pfile_in_zip_read_info->stream.avail_in = (uInt)0;\n\n    s->pfile_in_zip_read = pfile_in_zip_read_info;\n                s->encrypted = 0;\n\n#    ifndef NOUNCRYPT\n    if (password != NULL)\n    {\n        int i;\n        s->pcrc_32_tab = get_crc_table();\n        init_keys(password,s->keys,s->pcrc_32_tab);\n        if (zip_seek64file(s->z_filefunc, s->filestream,\n                  s->pfile_in_zip_read->pos_in_zipfile +\n                     s->pfile_in_zip_read->byte_before_the_zipfile,\n                  SEEK_SET)!=0)\n            return UNZ_INTERNALERROR;\n        if(zip_readfile(s->z_filefunc, s->filestream,source, 12)<12)\n            return UNZ_INTERNALERROR;\n\n        for (i = 0; i<12; i++)\n            zdecode(s->keys,s->pcrc_32_tab,source[i]);\n\n        s->pfile_in_zip_read->pos_in_zipfile+=12;\n        s->encrypted=1;\n    }\n#    endif\n\n\n    return UNZ_OK;\n}\n\nint ZEXPORT unzOpenCurrentFile (unzFile file)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);\n}\n\n/** Addition for GDAL : START */\n\nZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    s=(unz64_s*)file;\n    if (file==NULL)\n        return 0; //UNZ_PARAMERROR;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n    if (pfile_in_zip_read_info==NULL)\n        return 0; //UNZ_PARAMERROR;\n    return pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile;\n}\n\n/** Addition for GDAL : END */\n\n/*\n  Read bytes from the current file.\n  buf contain buffer where data must be copied\n  len the size of buf.\n\n  return the number of byte copied if some bytes are copied\n  return 0 if the end of file was reached\n  return <0 with error code if there is an error\n    (UNZ_ERRNO for IO error, or zLib error for uncompress error)\n*/\nint ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)\n{\n    int err=UNZ_OK;\n    uInt iRead = 0;\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if (pfile_in_zip_read_info->read_buffer == NULL)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (len==0)\n        return 0;\n\n    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;\n\n    pfile_in_zip_read_info->stream.avail_out = (uInt)len;\n\n    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&\n        (!(pfile_in_zip_read_info->raw)))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;\n\n    if ((len>pfile_in_zip_read_info->rest_read_compressed+\n           pfile_in_zip_read_info->stream.avail_in) &&\n         (pfile_in_zip_read_info->raw))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_compressed+\n            pfile_in_zip_read_info->stream.avail_in;\n\n    while (pfile_in_zip_read_info->stream.avail_out>0)\n    {\n        if ((pfile_in_zip_read_info->stream.avail_in==0) &&\n            (pfile_in_zip_read_info->rest_read_compressed>0))\n        {\n            uInt uReadThis = UNZ_BUFSIZE;\n            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)\n                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;\n            if (uReadThis == 0)\n                return UNZ_EOF;\n            if (zip_seek64file(nullptr,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile,\n                         ZLIB_FILEFUNC_SEEK_SET)!=0)\n                return UNZ_ERRNO;\n            if (zip_readfile(nullptr,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->read_buffer,\n                      uReadThis)!=uReadThis)\n                return UNZ_ERRNO;\n\n\n#            ifndef NOUNCRYPT\n            if(s->encrypted)\n            {\n                uInt i;\n                for(i=0;i<uReadThis;i++)\n                  pfile_in_zip_read_info->read_buffer[i] =\n                      zdecode(s->keys,s->pcrc_32_tab,\n                              pfile_in_zip_read_info->read_buffer[i]);\n            }\n#            endif\n\n\n            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;\n\n            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;\n\n            pfile_in_zip_read_info->stream.next_in =\n                (Bytef*)pfile_in_zip_read_info->read_buffer;\n            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;\n        }\n\n        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))\n        {\n            uInt uDoCopy,i ;\n\n            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                return (iRead==0) ? UNZ_EOF : iRead;\n\n            if (pfile_in_zip_read_info->stream.avail_out <\n                            pfile_in_zip_read_info->stream.avail_in)\n                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;\n            else\n                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;\n\n            for (i=0;i<uDoCopy;i++)\n                *(pfile_in_zip_read_info->stream.next_out+i) =\n                        *(pfile_in_zip_read_info->stream.next_in+i);\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,\n                                pfile_in_zip_read_info->stream.next_out,\n                                uDoCopy);\n            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;\n            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;\n            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;\n            pfile_in_zip_read_info->stream.next_out += uDoCopy;\n            pfile_in_zip_read_info->stream.next_in += uDoCopy;\n            pfile_in_zip_read_info->stream.total_out += uDoCopy;\n            iRead += uDoCopy;\n        }\n        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)\n        {\n#ifdef HAVE_BZIP2\n            uLong uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            uLong uOutThis;\n\n            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;\n            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;\n            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;\n            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;\n            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;\n            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;\n            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;\n            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;\n\n            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;\n            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;\n\n            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);\n\n            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));\n            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;\n            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;\n            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;\n            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;\n            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;\n            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;\n\n            if (err==BZ_STREAM_END)\n              return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=BZ_OK)\n              break;\n#endif\n        } // end Z_BZIP2ED\n        else\n        {\n            ZPOS64_T uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            ZPOS64_T uOutThis;\n            int flush=Z_SYNC_FLUSH;\n\n            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;\n            bufBefore = pfile_in_zip_read_info->stream.next_out;\n\n            /*\n            if ((pfile_in_zip_read_info->rest_read_uncompressed ==\n                     pfile_in_zip_read_info->stream.avail_out) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                flush = Z_FINISH;\n            */\n            err=inflate(&pfile_in_zip_read_info->stream,flush);\n\n            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))\n              err = Z_DATA_ERROR;\n\n            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 =\n                crc32(pfile_in_zip_read_info->crc32,bufBefore,\n                        (uInt)(uOutThis));\n\n            pfile_in_zip_read_info->rest_read_uncompressed -=\n                uOutThis;\n\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            if (err==Z_STREAM_END)\n                return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=Z_OK)\n                break;\n        }\n    }\n\n    if (err==Z_OK)\n        return iRead;\n    return err;\n}\n\n\n/*\n  Give the current position in uncompressed data\n*/\nz_off_t ZEXPORT unztell (unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    return (z_off_t)pfile_in_zip_read_info->stream.total_out;\n}\n\nZPOS64_T ZEXPORT unztell64 (unzFile file)\n{\n\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return (ZPOS64_T)-1;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return (ZPOS64_T)-1;\n\n    return pfile_in_zip_read_info->total_out_64;\n}\n\n\n/*\n  return 1 if the end of file was reached, 0 elsewhere\n*/\nint ZEXPORT unzeof (unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)\n        return 1;\n    else\n        return 0;\n}\n\n\n\n/*\nRead extra field from the current file (opened by unzOpenCurrentFile)\nThis is the local-header version of the extra field (sometimes, there is\nmore info in the local-header version than in the central-header)\n\n  if buf==NULL, it return the size of the local extra field that can be read\n\n  if buf!=NULL, len is the size of the buffer, the extra header is copied in\n    buf.\n  the return value is the number of bytes copied in buf, or (if <0)\n    the error code\n*/\nint ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    uInt read_now;\n    ZPOS64_T size_to_read;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -\n                pfile_in_zip_read_info->pos_local_extrafield);\n\n    if (buf==NULL)\n        return (int)size_to_read;\n\n    if (len>size_to_read)\n        read_now = (uInt)size_to_read;\n    else\n        read_now = (uInt)len ;\n\n    if (read_now==0)\n        return 0;\n\n    if (zip_seek64file(nullptr,\n              pfile_in_zip_read_info->filestream,\n              pfile_in_zip_read_info->offset_local_extrafield +\n              pfile_in_zip_read_info->pos_local_extrafield,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (zip_readfile(nullptr,\n              pfile_in_zip_read_info->filestream,\n              buf,read_now)!=read_now)\n        return UNZ_ERRNO;\n\n    return (int)read_now;\n}\n\n/*\n  Close the file in zip opened with unzipOpenCurrentFile\n  Return UNZ_CRCERROR if all the file was read but the CRC is not good\n*/\nint ZEXPORT unzCloseCurrentFile (unzFile file)\n{\n    int err=UNZ_OK;\n\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&\n        (!pfile_in_zip_read_info->raw))\n    {\n        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)\n            err=UNZ_CRCERROR;\n    }\n\n\n    TRYFREE(pfile_in_zip_read_info->read_buffer);\n    pfile_in_zip_read_info->read_buffer = NULL;\n    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)\n        inflateEnd(&pfile_in_zip_read_info->stream);\n#ifdef HAVE_BZIP2\n    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)\n        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);\n#endif\n\n\n    pfile_in_zip_read_info->stream_initialised = 0;\n    TRYFREE(pfile_in_zip_read_info);\n\n    s->pfile_in_zip_read=NULL;\n\n    return err;\n}\n\n\n/*\n  Get the global comment string of the ZipFile, in the szComment buffer.\n  uSizeBuf is the size of the szComment buffer.\n  return the number of byte copied or an error code <0\n*/\nint ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)\n{\n    unz64_s* s;\n    uLong uReadThis ;\n    if (file==NULL)\n        return (int)UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    uReadThis = uSizeBuf;\n    if (uReadThis>s->gi.size_comment)\n        uReadThis = s->gi.size_comment;\n\n    if (zip_seek64file(nullptr,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (uReadThis>0)\n    {\n      *szComment='\\0';\n\t  if (zip_readfile(nullptr, s->filestream, szComment, uReadThis) != uReadThis)\n        return UNZ_ERRNO;\n    }\n\n    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))\n        *(szComment+s->gi.size_comment)='\\0';\n    return (int)uReadThis;\n}\n\n/* Additions by RX '2004 */\nZPOS64_T ZEXPORT unzGetOffset64(unzFile file)\n{\n    unz64_s* s;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n      return 0;\n    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)\n      if (s->num_file==s->gi.number_entry)\n         return 0;\n    return s->pos_in_central_dir;\n}\n\nuLong ZEXPORT unzGetOffset (unzFile file)\n{\n    ZPOS64_T offset64;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    offset64 = unzGetOffset64(file);\n    return (uLong)offset64;\n}\n\nint ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    s->pos_in_central_dir = pos;\n    s->num_file = s->gi.number_entry;      /* hack */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                              &s->cur_file_info_internal,\n                                              NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nint ZEXPORT unzSetOffset (unzFile file, uLong pos)\n{\n    return unzSetOffset64(file,pos);\n}\n\nclass ZipArchive : public tTVPArchive {\n\tunzFile uf;\n\ttypedef std::pair<ttstr, unz64_file_pos> FileEntry;\n\tstd::vector<FileEntry> filelist;\n\npublic:\n\t~ZipArchive();\n\tZipArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName);\n\n\tbool isValid() { return uf != nullptr; }\n\tvirtual tjs_uint GetCount() { return filelist.size(); }\n\tvirtual ttstr GetName(tjs_uint idx) { return filelist[idx].first; }\n\tvirtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx);\n\n\ttTJSBinaryStream *_st = nullptr;\n};\n\nstatic uLong zip_readfile(voidpf, voidpf s, void *buf, uLong size) {\n\treturn ((ZipArchive*)s)->_st->Read(buf, size);\n}\n\nstatic uLong zip_writefile(voidpf, voidpf s, const void *buf, uLong size) {\n\treturn ((ZipArchive*)s)->_st->Write(buf, size);\n}\n\nstatic ZPOS64_T zip_tell64file(voidpf, voidpf s) {\n\treturn ((ZipArchive*)s)->_st->GetPosition();\n}\n\nstatic long zip_seek64file(voidpf, voidpf s, ZPOS64_T offset, int origin) {\n\t((ZipArchive*)s)->_st->Seek(offset, origin);\n\treturn 0;\n}\n\ntTVPArchive * TVPOpenZIPArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) {\n\ttjs_uint64 pos = st->GetPosition();\n\tbool checkZIP = st->ReadI16LE() == 0x4B50; // 'PK'\n\tst->SetPosition(pos);\n\tif (!checkZIP) return nullptr;\n\tZipArchive *arc = new ZipArchive(name, st, normalizeFileName);\n\tif (!arc->isValid()) {\n\t\tarc->_st = nullptr;\n\t\tdelete arc;\n\t\treturn nullptr;\n\t}\n\treturn arc;\n}\n\ntTJSBinaryStream * ZipArchive::CreateStreamByIndex(tjs_uint idx) {\n\tif (unzGoToFilePos64(uf, &filelist[idx].second) != UNZ_OK) return nullptr;\n\t// decompress and hold in memory for random access\n\tunz_file_info file_info;\n\tif (unzGetCurrentFileInfo(uf, &file_info, NULL, 0, NULL, 0) != UNZ_OK) return nullptr;\n\tif (file_info.compression_method == 0) { // uncompressed\n\t\tuInt iSizeVar;\n\t\tZPOS64_T offset_local_extrafield;  /* offset of the local extra field */\n\t\tuInt  size_local_extrafield;    /* size of the local extra field */\n\t\tif (unz64local_CheckCurrentFileCoherencyHeader((unz64_s*)uf, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)\n\t\t\treturn nullptr;\n\t\treturn new TArchiveStream(this, file_info.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar, file_info.uncompressed_size);\n\t} else {\n\t\tif (unzOpenCurrentFile(uf) != UNZ_OK) return nullptr;\n\t\ttTVPMemoryStream *mem = new tTVPMemoryStream();\n\t\tmem->SetSize(file_info.uncompressed_size);\n\t\tunzReadCurrentFile(uf, mem->GetInternalBuffer(), file_info.uncompressed_size);\n\t\tunzCloseCurrentFile(uf);\n\t\treturn mem;\n\t}\n}\n\nZipArchive::~ZipArchive() {\n\tif (uf) {\n\t\tunzClose(uf);\n\t\tuf = NULL;\n\t}\n\tif (_st) {\n\t\tdelete _st;\n\t\t_st = nullptr;\n\t}\n}\n\nvoid storeFilename(ttstr &name, const char *narrowName, const ttstr &filename);\nZipArchive::ZipArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) : tTVPArchive(name) {\n\tif (!st) st = TVPCreateStream(name);\n\t_st = st;\n\tif ((uf = unzOpenInternal(this, &zipfunc, 1)) != NULL) {\n\t\t//unzGoToFirstFile64(uf, NULL, NULL, 0);\n\t\tunz_file_info file_info;\n\t\tdo {\n\t\t\tunz64_file_pos entry;\n\t\t\tif (unzGetFilePos64(uf, &entry) == UNZ_OK) {\n\t\t\t\tttstr filename;\n\t\t\t\tchar filename_inzip[1024];\n\t\t\t\tif (unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0) == UNZ_OK) {\n\t\t\t\t\tstoreFilename(filename, filename_inzip, name);\n\t\t\t\t\tif (normalizeFileName)\n\t\t\t\t\t\tNormalizeInArchiveStorageName(filename);\n\t\t\t\t\tfilelist.emplace_back(filename, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t} while (unzGoToNextFile64(uf, NULL, NULL, 0) == UNZ_OK);\n\t\tif (normalizeFileName) {\n\t\t\tstd::sort(filelist.begin(), filelist.end(), [](const FileEntry& a, const FileEntry& b) {\n\t\t\t\treturn a.first < b.first;\n\t\t\t});\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/core/base/common.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TVP2 common header file\n//---------------------------------------------------------------------------\n\n#ifndef __CommonH__\n#define __CommonH__\n\n#include \"tjsConfig.h\"\n\n#include \"config.h\"\n\n#include <string>\n\n\nusing namespace TJS;\n\ntypedef std::basic_string<tjs_char> stdstring;\ntypedef std::basic_string<tjs_nchar> stdnstring;\n\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/base/tar.h",
    "content": "#ifndef __TAR_H\n#define __TAR_H\n\n/*\n * tar header block definition\n *\n * From IEEE Std 1003.1-1988, pp.156\n */\n\n\n//POSIX magic\n#define\tTMAGIC\t\t\"ustar\"\n#define\tTMAGLEN\t\t6\n\n//GNU magic+version:\n#define\tTOMAGIC\t\t\"ustar  \"\n#define\tTOMAGLEN\t8\n\n//POSIX version\n#define\tTVERSION\t\"00\"\n#define\tTVERSLEN\t2\n\n#define\tREGTYPE\t\t'0'\t/* Regular file */\n#define\tAREGTYPE\t'\\0'\t/* Regular file; old V7 format */\n#define\tLNKTYPE\t\t'1'\t/* Link */\n#define\tSYMTYPE\t\t'2'\t/* Symbolic link */\n#define\tCHRTYPE\t\t'3'\t/* Character special */\n#define\tBLKTYPE\t\t'4'\t/* Block special */\n#define\tDIRTYPE\t\t'5'\t/* Directory */\n#define\tFIFOTYPE\t'6'\t/* FIFO special */\n#define\tCONTTYPE\t'7'\t/* Continguous file */\n#define LONGLINK\t'L' /* Long name Link by tantan*/\n#define PAX_ENTRTY  'x' /* PAX header block for file entry : added by claybird 2011.11.29 */\n#define PAX_GLOBAL  'g' /* PAX global extended header : added by claybird 2011.11.29 */\n\n#define\tMULTYPE\t\t'M'\t/* Added by GNUtar, not POSIX */\n#define\tVOLTYPE\t\t'V'\t/* Added by GNUtar, not POSIX */\n\n\n#define\tTSUID\t\t04000\t/* Set UID on execution */\n#define\tTSGID\t\t02000\t/* Set GID on execution */\n#define\tTSVTX\t\t01000\t/* Reserved */\n\t\t\t\t/* File permissions */\n#define\tTUREAD\t\t00400\t/* read by owner */\n#define\tTUWRITE\t\t00200\t/* write by owner */\n#define\tTUEXEC\t\t00100\t/* execute/search by owner */\n#define\tTGREAD\t\t00040\t/* read by group */\n#define\tTGWRITE\t\t00020\t/* write by group */\n#define\tTGEXEC\t\t00010\t/* execute/search by group */\n#define\tTOREAD\t\t00004\t/* read by other */\n#define\tTOWRITE\t\t00002\t/* write by other */\n#define\tTOEXEC\t\t00001\t/* execute/search by other */\n\n\n#define\tTBLOCK\t512\n#define\tNAMSIZ\t100\n\n//added by claybird(2009.12.05)\n#define TAR_FORMAT_GNU\t\t0\n#define TAR_FORMAT_POSIX\t1\n\ntypedef\tunion\thblock\t{\n\tchar\tdummy[TBLOCK];\n\tstruct\t{\n\t\tchar\tname[NAMSIZ];\n\t\tchar\tmode[8];\n\t\tchar\tuid[8];\n\t\tchar\tgid[8];\n\t\tchar\tsize[12];\n\t\tchar\tmtime[12];\n\t\tchar\tchksum[8];\n\t\tchar\ttypeflag;\n\t\tchar\tlinkname[NAMSIZ];\n\t\tchar\tmagic[6];\n\t\tchar\tversion[2];\n\t\tchar\tuname[32];\n\t\tchar\tgname[32];\n\t\tchar\tdevmajor[8];\n\t\tchar\tdevminor[8];\n\t\tunion _exthead{\t//header extension\n\t\t\tstruct _POSIX{\t//POSIX ustar format\n\t\t\t\tchar prefix[155];\n\t\t\t\tchar pad[12];\n\t\t\t}posix;\n\t\t\tstruct _GNU{\t//GNUtar format\n\t\t\t/* Following fields were added by GNUtar */\n\t\t\t\tchar\tatime[12];\n\t\t\t\tchar\tctime[12];\n\t\t\t\tchar\toffset[12];\n\t\t\t}gnu;\n\t\t}exthead;\n\t} dbuf;\n\tunsigned int compsum(){\n\t\tunsigned int sum = 0;\n\t\tint i;\n\t\tfor(i=0;i<TBLOCK;i++){\n\t\t\tsum += (unsigned char)dummy[i];\n\t\t}\n\t\t/* calc without checksum field */\n\t\tfor(i=0;i<sizeof(dbuf.chksum);i++){\n\t\t\tsum -= dbuf.chksum[i];\n\t\t\tsum += ' ';\n\t\t}\n\t\treturn sum;\n\t}\n\t//added by claybird(2011.01.13)\n\tint compsum_oldtar(){\t\n\t\tunsigned int sum = 0;\n\t\tint i;\n\t\tfor(i=0;i<TBLOCK;i++){\n\t\t\tsum += (signed char)dummy[i];\t//different way to compute like old unix\n\t\t}\n\t\t/* calc without checksum field */\n\t\tfor(i=0;i<sizeof(dbuf.chksum);i++){\n\t\t\tsum -= dbuf.chksum[i];\n\t\t\tsum += ' ';\n\t\t}\n\t\treturn sum;\n\t}\n\tint getFormat()const{\n\t\tif(dbuf.magic[5]==TOMAGIC[5]){\n\t\t\treturn TAR_FORMAT_GNU;\n\t\t}else{\n\t\t\treturn TAR_FORMAT_POSIX;\n\t\t}\n\t}\n} TAR_HEADER;\n\n\n\n#endif\t/* __TAR_H */\n"
  },
  {
    "path": "src/core/base/win32/EventImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script Event Handling and Dispatching\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"EventImpl.h\"\n#include \"SystemControl.h\"\n#include \"ThreadIntf.h\"\n#include \"TickCount.h\"\n#include \"TimerIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n#include \"WindowImpl.h\"\n//#include <mmsystem.h>\n\n#include \"Application.h\"\n#include \"NativeEventQueue.h\"\n#include \"UserEvent.h\"\n\n//---------------------------------------------------------------------------\n// TVPInvokeEvents\n//---------------------------------------------------------------------------\nbool TVPEventInvoked = false;\nvoid TVPInvokeEvents()\n{\n\tif(TVPEventInvoked) return;\n\tTVPEventInvoked = true;\n\tif(TVPSystemControl)\n\t{\n\t\tTVPSystemControl->InvokeEvents();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPEventReceived\n//---------------------------------------------------------------------------\nvoid TVPEventReceived()\n{\n\tTVPEventInvoked = false;\n\tif( TVPSystemControl ) TVPSystemControl->NotifyEventDelivered();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCallDeliverAllEventsOnIdle\n//---------------------------------------------------------------------------\nvoid TVPCallDeliverAllEventsOnIdle()\n{\n\tif(TVPSystemControl)\n\t{\n\t\tTVPSystemControl->CallDeliverAllEventsOnIdle();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPBreathe\n//---------------------------------------------------------------------------\nstatic bool TVPBreathing = false;\nvoid TVPBreathe()\n{\n\tTVPEventDisabled = true; // not to call TVP events...\n\tTVPBreathing = true;\n\ttry\n\t{\n\t\tApplication->ProcessMessages(); // do Windows message pumping\n\t}\n\tcatch(...)\n\t{\n\t\tTVPBreathing = false;\n\t\tTVPEventDisabled = false;\n\t\tthrow;\n\t}\n\n\tTVPBreathing = false;\n\tTVPEventDisabled = false;\n}\n//---------------------------------------------------------------------------\nbool TVPGetBreathing()\n{\n\t// return whether now is in event breathing\n\treturn TVPBreathing;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSystemEventDisabledState\n//---------------------------------------------------------------------------\nvoid TVPSetSystemEventDisabledState(bool en)\n{\n\tTVPSystemControl->SetEventEnabled( !en );\n\tif(!en) TVPDeliverAllEvents();\n}\n//---------------------------------------------------------------------------\nbool TVPGetSystemEventDisabledState()\n{\n\treturn !TVPSystemControl->GetEventEnabled();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPContinuousHandlerCallLimitThread\n//---------------------------------------------------------------------------\nclass tTVPContinuousHandlerCallLimitThread : public tTVPThread\n{\n\ttjs_uint64 NextEventTick;\n\ttjs_uint64 Interval;\n\ttTVPThreadEvent Event;\n\ttTJSCriticalSection CS;\n\n\tbool Enabled;\n\n\tNativeEventQueue<tTVPContinuousHandlerCallLimitThread> EventQueue;\n\npublic:\n\ttTVPContinuousHandlerCallLimitThread();\n\t~tTVPContinuousHandlerCallLimitThread();\n\nprotected:\n\tvoid Execute();\n\n\tvoid WndProc(NativeEvent& ev) {\n\t\tEventQueue.HandlerDefault(ev);\n\t}\n\npublic:\n\tvoid SetEnabled(bool enabled);\n\n\tvoid SetInterval(tjs_uint64 interval) { Interval = interval; }\n\n\n} static * TVPContinuousHandlerCallLimitThread = NULL;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTVPContinuousHandlerCallLimitThread::tTVPContinuousHandlerCallLimitThread()\n\t : tTVPThread(true), EventQueue(this,&tTVPContinuousHandlerCallLimitThread::WndProc)\n{\n\tNextEventTick = 0;\n\tInterval = (1<<TVP_SUBMILLI_FRAC_BITS)*1000/60; // default 60Hz\n\tEnabled = false;\n\tEventQueue.Allocate();\n\tResume();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTVPContinuousHandlerCallLimitThread::~tTVPContinuousHandlerCallLimitThread()\n{\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n\tEventQueue.Deallocate();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPContinuousHandlerCallLimitThread::Execute()\n{\n\twhile(!GetTerminated())\n\t{\n\t\ttjs_uint64 curtick = TVPGetTickCount() << TVP_SUBMILLI_FRAC_BITS;\n\t\ttjs_uint32 sleeptime;\n\n\t\t{\t// thread-protected\n\t\t\ttTJSCriticalSectionHolder holder(CS);\n\n\t\t\tif(Enabled)\n\t\t\t{\n\t\t\t\tif(NextEventTick <= curtick)\n\t\t\t\t{\n\t\t\t\t\tTVPProcessContinuousHandlerEventFlag = true; // set flag to process event on next idle\n\t\t\t\t\tEventQueue.PostEvent( NativeEvent(TVP_EV_CONTINUE_LIMIT_THREAD) );\n\t\t\t\t\twhile(NextEventTick <= curtick) NextEventTick += Interval;\n\t\t\t\t}\n\t\t\t\ttjs_uint64 sleeptime_64 = NextEventTick - curtick;\n\t\t\t\tsleeptime = (tjs_uint32)(sleeptime_64 >> TVP_SUBMILLI_FRAC_BITS) +\n\t\t\t\t\t\t((sleeptime_64 & ((1<<TVP_SUBMILLI_FRAC_BITS)-1))?1:0);\n\t\t\t\t\t\t\t// add 1 if fraction exists\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsleeptime = 10000; // how long to sleep when disabled does not matter\n\t\t\t}\n\n\n\t\t}\t// end-of-thread-protected\n\n\t\tif(sleeptime == 0) sleeptime = 1; // 0 will let thread sleeping forever ...\n\t\tEvent.WaitFor(sleeptime);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPContinuousHandlerCallLimitThread::SetEnabled(bool enabled)\n{\n\ttTJSCriticalSectionHolder holder(CS);\n\n\tEnabled = enabled;\n\tif(enabled)\n\t{\n\t\ttjs_uint64 curtick = TVPGetTickCount() << TVP_SUBMILLI_FRAC_BITS;\n\t\tNextEventTick = ((curtick + 1) / Interval) * Interval;\n\t\tEvent.Set();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic tjs_int TVPContinousHandlerLimitFrequency = 0;\n//---------------------------------------------------------------------------\nvoid TVPBeginContinuousEvent()\n{\n\t// read commandline options\n\tstatic tjs_int ArgumentGeneration = 0;\n\tif(ArgumentGeneration != TVPGetCommandLineArgumentGeneration())\n\t{\n\t\tArgumentGeneration = TVPGetCommandLineArgumentGeneration();\n\n\t\ttTJSVariant val;\n\t\tif( TVPGetCommandLine(TJS_W(\"-contfreq\"), &val) )\n\t\t{\n\t\t\tTVPContinousHandlerLimitFrequency = (tjs_int)val;\n\t\t}\n\t}\n//\tif(!TVPIsWaitVSync())\n\t{\n\t\tif(TVPContinousHandlerLimitFrequency == 0)\n\t\t{\n\t\t\t// no limit\n\t\t\t// this notifies continuous calling of TVPDeliverAllEvents.\n\t\t\tif(TVPSystemControl) TVPSystemControl->BeginContinuousEvent();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// has limit\n\t\t\tif(!TVPContinuousHandlerCallLimitThread)\n\t\t\t\tTVPContinuousHandlerCallLimitThread = new tTVPContinuousHandlerCallLimitThread();\n\t\t\tTVPContinuousHandlerCallLimitThread->SetInterval(\n\t\t\t\t (1<<TVP_SUBMILLI_FRAC_BITS)*1000/TVPContinousHandlerLimitFrequency);\n\t\t\tTVPContinuousHandlerCallLimitThread->SetEnabled(true);\n\t\t}\n\t}\n\n\t// TVPEnsureVSyncTimingThread();\n\t// if we wait vsync, the continuous handler will be executed at the every timing of\n\t// vsync.\n}\n//---------------------------------------------------------------------------\nvoid TVPEndContinuousEvent()\n{\n\t// anyway\n\tif(TVPContinuousHandlerCallLimitThread)\n\t\tTVPContinuousHandlerCallLimitThread->SetEnabled(false);\n\n\t// anyway\n\tif(TVPSystemControl) TVPSystemControl->EndContinuousEvent();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic void TVPReleaseContinuousHandlerCallLimitThread()\n{\n\tif(TVPContinuousHandlerCallLimitThread)\n\t\tdelete TVPContinuousHandlerCallLimitThread,\n\t\t\tTVPContinuousHandlerCallLimitThread = NULL;\n}\n// to release TVPContinuousHandlerCallLimitThread at exit\nstatic tTVPAtExit TVPTimerThreadUninitAtExit(TVP_ATEXIT_PRI_SHUTDOWN,\n\tTVPReleaseContinuousHandlerCallLimitThread);\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/base/win32/EventImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script Event Handling and Dispatching\n//---------------------------------------------------------------------------\n#ifndef EventImplH\n#define EventImplH\n\n#include \"EventIntf.h\"\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/base/win32/FileSelector.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// File Selector dialog box\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n// #include <cderr.h>\n// #include <commdlg.h>\n\n#include \"MsgIntf.h\"\n#include \"StorageImpl.h\"\n#include \"WindowImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n\n#include \"TVPScreen.h\"\n\nstd::string TVPShowFileSelector(\n    const std::string &title,\n    const std::string &filename,\n    std::string initdir,\n    bool issave\n    );\n\n//---------------------------------------------------------------------------\n// TVPSelectFile related\n//---------------------------------------------------------------------------\n#define TVP_OLD_OFN_STRUCT_SIZE 76\n//---------------------------------------------------------------------------\n#if 0\nstatic tjs_int TVPLastScreenWidth = 0;\nstatic tjs_int TVPLastScreenHeight = 0;\nstatic tjs_int TVPLastOFNLeft = -30000;\nstatic tjs_int TVPLastOFNTop = -30000;\nstatic UINT_PTR APIENTRY TVPOFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam,\n\tLPARAM lParam)\n{\n\tif(uiMsg == WM_INITDIALOG)\n\t{\n\t\tint left, top;\n\t\tHWND parent = GetParent(hdlg);\n\t\tif((TVPLastOFNLeft == -30000 && TVPLastOFNTop == -30000) ||\n\t\t\tTVPLastScreenWidth != tTVPScreen::GetWidth() || TVPLastScreenHeight != tTVPScreen::GetHeight() )\n\t\t{\n\t\t\t// center the window\n\t\t\tRECT rect;\n\t\t\tGetWindowRect(parent, &rect);\n\t\t\tleft = ((tTVPScreen::GetWidth() - rect.right + rect.left) / 2);\n\t\t\ttop = ((tTVPScreen::GetHeight() - rect.bottom + rect.top) / 3);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// set last position\n\t\t\tleft = TVPLastOFNLeft;\n\t\t\ttop = TVPLastOFNTop;\n\t\t}\n\n\t\tTVPLastScreenWidth = tTVPScreen::GetWidth();\n\t\tTVPLastScreenHeight = tTVPScreen::GetHeight();\n\n\t\tSetWindowPos(parent, 0,\n\t\t\tleft,\n\t\t\ttop,\n\t\t\t0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);\n\t}\n\telse if(uiMsg == WM_DESTROY ||\n\t\t(uiMsg == WM_NOTIFY && ((OFNOTIFY*)lParam)->hdr.code == CDN_FILEOK))\n\t{\n\t\tHWND parent = GetParent(hdlg);\n\t\tRECT rect;\n\t\tGetWindowRect(parent, &rect);\n\t\tTVPLastOFNLeft = rect.left;\n\t\tTVPLastOFNTop = rect.top;\n\t}\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nstatic void TVPPushFilterPair(std::vector<std::wstring> &filters, std::wstring filter)\n{\n\tstd::wstring::size_type vpos = filter.find_first_of(L\"|\");\n\tif( vpos != std::wstring::npos )\n\t{\n\t\tstd::wstring name = filter.substr(0, vpos);\n\t\tstd::wstring wild = filter.c_str() + vpos+1;\n\t\tfilters.push_back(name);\n\t\tfilters.push_back(wild);\n\t}\n\telse\n\t{\n\t\tfilters.push_back(filter);\n\t\tfilters.push_back(filter);\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool TVPSelectFile(iTJSDispatch2 *params)\n{\n\t// show open dialog box\n\t// NOTE: currently this only shows ANSI version of file open dialog.\n\ttTJSVariant val;\n\tstd::string initialdir;\n\tstd::string title;\n\tstd::string defaultext;\n#if 0\n\twchar_t* filter = NULL;\n\twchar_t* filename = NULL;\n\n\tBOOL result;\n\n\ttry\n\t{\n\t\t// prepare OPENFILENAME structure\n\n\t\tOPENFILENAME ofn;\n\t\tmemset(&ofn, 0, sizeof(ofn));\n\t\tofn.lStructSize = sizeof(ofn);\n\t\tofn.hwndOwner = TVPGetModalWindowOwnerHandle();\n\t\tif( ofn.hwndOwner == INVALID_HANDLE_VALUE ) {\n\t\t\tofn.hwndOwner = NULL;\n\t\t}\n\t\tofn.hInstance = NULL;\n\n\t\t// set application window position to current window position\n\t\t\n\n\t\t// get filter\n\t\tofn.lpstrFilter = NULL;\n\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"filter\"), 0,\n\t\t\t&val, params)))\n\t\t{\n\t\t\tstd::vector<std::wstring> filterlist;\n\t\t\tif(val.Type() != tvtObject)\n\t\t\t{\n\t\t\t\tTVPPushFilterPair(filterlist, ttstr(val).AsStdString());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tiTJSDispatch2 * array = val.AsObjectNoAddRef();\n\t\t\t\ttjs_int count;\n\t\t\t\ttTJSVariant tmp;\n\t\t\t\tif(TJS_SUCCEEDED(array->PropGet(TJS_MEMBERMUSTEXIST,\n\t\t\t\t\tTJS_W(\"count\"), 0, &tmp, array)))\n\t\t\t\t\tcount = tmp;\n\t\t\t\telse\n\t\t\t\t\tcount = 0;\n\n\t\t\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t\t\t{\n\t\t\t\t\tif(TJS_SUCCEEDED(array->PropGetByNum(TJS_MEMBERMUSTEXIST,\n\t\t\t\t\t\ti, &tmp, array)))\n\t\t\t\t\t{\n\t\t\t\t\t\tTVPPushFilterPair(filterlist, ttstr(tmp).AsStdString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// create filter buffer\n\t\t\ttjs_int bufsize = 2;\n\t\t\tfor(std::vector<std::wstring>::iterator i = filterlist.begin(); i != filterlist.end(); i++)\n\t\t\t{\n\t\t\t\tbufsize += (tjs_int)(i->length() + 1);\n\t\t\t}\n\n\t\t\tfilter = new wchar_t[bufsize];\n\n\t\t\twchar_t* p = filter;\n\t\t\tfor(std::vector<std::wstring>::iterator i = filterlist.begin(); i != filterlist.end(); i++)\n\t\t\t{\n\t\t\t\tTJS_strcpy(p, i->c_str());\n\t\t\t\tp += i->length() + 1;\n\t\t\t}\n\t\t\t*(p++) = 0;\n\t\t\t*(p++) = 0;\n\n\t\t\tofn.lpstrFilter = filter;\n\t\t}\n\n\t\tofn.lpstrCustomFilter = NULL;\n\t\tofn.nMaxCustFilter = 0;\n\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"filterIndex\"), 0, &val, params)))\n\t\t\tofn.nFilterIndex = (tjs_int)val;\n\t\telse\n\t\t\tofn.nFilterIndex = 0;\n\n\t\t// filenames\n\t\tfilename = new wchar_t[MAX_PATH + 1];\n \t\tfilename[0] = 0;\n\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"name\"), 0, &val, params)))\n\t\t{\n\t\t\tttstr lname(val);\n\t\t\tif(!lname.IsEmpty())\n\t\t\t{\n\t\t\t\tlname = TVPNormalizeStorageName(lname);\n\t\t\t\tTVPGetLocalName(lname);\n\t\t\t\tstd::wstring name = lname.AsStdString();\n\t\t\t\tTJS_strncpy(filename, name.c_str(), MAX_PATH);\n\t\t\t\tfilename[MAX_PATH] = 0;\n\t\t\t}\n\t\t}\n\n\t\tofn.lpstrFile = filename;\n\t\tofn.nMaxFile = MAX_PATH + 1;\n\t\tofn.lpstrFileTitle = NULL;\n\t\tofn.nMaxFileTitle = 0;\n\n\t\t// initial dir\n\t\tofn.lpstrInitialDir = NULL;\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"initialDir\"), 0, &val, params)))\n\t\t{\n\t\t\tttstr lname(val);\n\t\t\tif(!lname.IsEmpty())\n\t\t\t{\n\t\t\t\tlname = TVPNormalizeStorageName(lname);\n\t\t\t\tTVPGetLocalName(lname);\n\t\t\t\tinitialdir = lname.AsStdString();\n\t\t\t\tofn.lpstrInitialDir = initialdir.c_str();\n\t\t\t}\n\t\t}\n\t\n\t\t// title\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"title\"), 0, &val, params)))\n\t\t{\n\t\t\ttitle = ttstr(val).AsStdString();\n\t\t\tofn.lpstrTitle = title.c_str();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tofn.lpstrTitle = NULL;\n\t\t}\n\n\t\t// flags\n\t\tbool issave = false;\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"save\"), 0, &val, params)))\n\t\t\tissave = val.operator bool();\n\n\t\tofn.Flags = OFN_ENABLEHOOK|OFN_EXPLORER|OFN_NOCHANGEDIR|\n\t\t\tOFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_ENABLESIZING;\n\n\n\t\tif(!issave)\n\t\t\tofn.Flags |= OFN_FILEMUSTEXIST;\n\t\telse\n\t\t\tofn.Flags |= OFN_OVERWRITEPROMPT;\n\n\t\t// default extension\n\t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"defaultExt\"), 0, &val, params)))\n\t\t{\n\t\t\tdefaultext = ttstr(val).AsStdString();\n\t\t\tofn.lpstrDefExt = defaultext.c_str();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tofn.lpstrDefExt = NULL;\n\t\t}\n\n\t\t// hook proc\n\t\tofn.lpfnHook = TVPOFNHookProc;\n\n\t\t// show dialog box\n\t\tif(!issave)\n\t\t\tresult = GetOpenFileName(&ofn);\n\t\telse\n\t\t\tresult = GetSaveFileName(&ofn);\n\n\n\t\tif(!result && CommDlgExtendedError() == CDERR_STRUCTSIZE)\n\t\t{\n\t\t\t// for old windows\n\t\t\t// set lStructSize to old Windows' structure size\n\t\t\tofn.lStructSize = TVP_OLD_OFN_STRUCT_SIZE;\n\t\t\tif(!issave)\n\t\t\t\tresult = GetOpenFileName(&ofn);\n\t\t\telse\n\t\t\t\tresult = GetSaveFileName(&ofn);\n\t\t}\n\n\t\tif(result)\n\t\t{\n\t\t\t// returns some informations\n\n\t\t\t// filter index\n\t\t\tval = (tjs_int)ofn.nFilterIndex;\n\t\t\tparams->PropSet(TJS_MEMBERENSURE, TJS_W(\"filterIndex\"), 0, &val, params);\n\n\t\t\t// file name\n\t\t\tval = TVPNormalizeStorageName(ttstr(filename));\n\t\t\tparams->PropSet(TJS_MEMBERENSURE, TJS_W(\"name\"), 0, &val, params);\n\t\t}\n\n\t}\n\tcatch(...)\n\t{\n\t\tif(filter) delete [] filter;\n\t\tif(filename) delete [] filename;\n\t\tthrow;\n\t}\n\n\tdelete [] filter;\n\tdelete [] filename;\n\n\treturn 0!=result;\n#endif\n\n    std::string filename;\n\tstd::string result;\n\n\t// get filter\n\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"filter\"), 0,\n\t\t&val, params)))\n\t{\n\t}\n\n// \t\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"filterIndex\"), 0,\n// \t\t\t&val, params)))\n// \t\t\tofn.nFilterIndex = (tjs_int)val;\n// \t\telse\n// \t\t\tofn.nFilterIndex = 0;\n\n\t// initial dir\n\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"initialDir\"), 0,\n\t\t&val, params)))\n\t{\n\t\tttstr lname(val);\n\t\tif (!lname.IsEmpty()){\n\t\t\tTVPGetLocalName(lname);\n\t\t\tinitialdir = tTJSNarrowStringHolder(lname.c_str());\n\t\t}\n\t}\n        \n\t// default extension\n\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"defaultExt\"), 0,\n\t\t&val, params)))\n\t{\n\t\tdefaultext = tTJSNarrowStringHolder(val.AsStringNoAddRef()->operator const tjs_char*());\n\t}\n\n\t// filenames\n\tif (TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"name\"), 0,\n\t\t&val, params)))\n\t{\n\t\tttstr lname(val);\n\t\tif (!lname.IsEmpty())\n\t\t{\n\t\t\tif (lname.IndexOf('/') >= 0) {\n\t\t\t\tlname = TVPNormalizeStorageName(lname);\n\t\t\t\tTVPGetLocalName(lname);\n\t\t\t\tttstr path = TVPExtractStoragePath(lname);\n\t\t\t\tttstr name = TVPExtractStorageName(lname);\n\t\t\t\tlname = name;\n\t\t\t\tinitialdir = path.AsStdString();\n\t\t\t} else {\n\t\t\t}\n\n\t\t\tif (!defaultext.empty() && TVPExtractStorageExt(lname).IsEmpty()) {\n\t\t\t\tif (defaultext[0] != '.')\n\t\t\t\t\tlname += TJS_W(\".\");\n\t\t\t\tlname += defaultext.c_str();\n\t\t\t}\n\t\t\tfilename = tTJSNarrowStringHolder(lname.c_str());\n\t\t}\n\t}\n\t\n\t// title\n\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"title\"), 0,\n\t\t&val, params)))\n\t{\n        title = tTJSNarrowStringHolder(val.AsStringNoAddRef()->operator const tjs_char*());\n\t}\n\n\t// flags\n\tbool issave = false;\n\tif(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"save\"), 0,\n\t\t&val, params)))\n\t\tissave = val.operator bool();\n\n\t// show dialog box\n    result = TVPShowFileSelector(title, filename, initialdir, issave);\n\n\tif(!result.empty())\n\t{\n\t\t// returns some informations\n\n\t\t// filter index\n\t\tval = (tjs_int)0;\n\t\tparams->PropSet(TJS_MEMBERENSURE, TJS_W(\"filterIndex\"), 0,\n\t\t\t&val, params);\n\n\t\t// file name\n\t\tttstr tresult = TVPNormalizeStorageName(ttstr(result.c_str()));\n\t\tval = tresult;\n\t\tparams->PropSet(TJS_MEMBERENSURE, TJS_W(\"name\"), 0,\n\t\t\t&val, params);\n        return true;\n\t}\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n"
  },
  {
    "path": "src/core/base/win32/FileSelector.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// File Selector dialog box\n//---------------------------------------------------------------------------\n#ifndef FileSelectorH\n#define FileSelectorH\n//---------------------------------------------------------------------------\n\n#include \"tjs.h\"\n\n\nextern bool TVPSelectFile(iTJSDispatch2 *params);\n\n#endif\n"
  },
  {
    "path": "src/core/base/win32/FuncStubs.cpp",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/* This file is always generated by makestub.pl . */\n/* Modification by hand will be lost. */\n\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsVariant.h\"\n#include \"tjsString.h\"\n#include \"PluginImpl.h\"\n\nstatic void __stdcall TVP_Stub_3d4b725f0b4234d79524822e7c34486b(tTJSVariant * _this, iTJSDispatch2 * objthis)\n{\n\treturn _this->ChangeClosureObjThis(objthis);\n}\nstatic void __stdcall TVP_Stub_3fc0c32ee41ea0c515f8fbb681e37982(tTJSVariant * _this)\n{\n\t::new (_this) tTJSVariant();\n}\nstatic void __stdcall TVP_Stub_e8dbd4fe012262d9da831e0735aa33b3(tTJSVariant * _this, const tTJSVariant & ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_ace6cce1353865d7376caca1f2124216(tTJSVariant * _this, iTJSDispatch2 * ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_5055344aa8055bc238b79e5f88fc3300(tTJSVariant * _this, iTJSDispatch2 * obj , iTJSDispatch2 * objthis)\n{\n\t::new (_this) tTJSVariant(obj, objthis);\n}\nstatic void __stdcall TVP_Stub_8238c542b814acf1a83c00cced57ba26(tTJSVariant * _this, const tjs_char * ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_bd2a14ca8c345fd7f151b08d1792fb60(tTJSVariant * _this, const tTJSString & ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_16d432f9f86738a7688cbfc9b12441ec(tTJSVariant * _this, const tjs_nchar * ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_6dac00582b8ba529e548ef058c4e869e(tTJSVariant * _this, const tjs_uint8 * ref , tjs_uint len)\n{\n\t::new (_this) tTJSVariant(ref, len);\n}\nstatic void __stdcall TVP_Stub_9193ae470b5efdfe617b5e94cd8f5da6(tTJSVariant * _this, bool ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_ec455b6ef0f5da178063db3875973260(tTJSVariant * _this, tjs_int32 ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_a56aaf685bd171b63b0ef3c894d80ecf(tTJSVariant * _this, tjs_int64 ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_9a5fe199cebb9841f94ac0bb7a4a3b6a(tTJSVariant * _this, tjs_real ref)\n{\n\t::new (_this) tTJSVariant(ref);\n}\nstatic void __stdcall TVP_Stub_2acb76a1f86e34afc5fe934d406c6c4c(tTJSVariant * _this, const tjs_uint8 * * src)\n{\n\t::new (_this) tTJSVariant(src);\n}\nstatic void __stdcall TVP_Stub_3a4d914ca7d24989c236ad223c002d49(tTJSVariant * _this)\n{\n\t_this->~tTJSVariant();\n}\nstatic tTJSVariantType __stdcall TVP_Stub_8fca7d3a123df1eacf228ba89f6a02ff(tTJSVariant * _this)\n{\n\treturn _this->Type();\n}\nstatic void __stdcall TVP_Stub_58be195f96a36c158d638e3b0c79308b(tTJSVariant * _this)\n{\n\treturn _this->Clear();\n}\nstatic tTJSVariantClosure & __stdcall TVP_Stub_eaa4d5b1d186a807a63311ab6d5e16e4(tTJSVariant * _this)\n{\n\treturn _this->AsObjectClosure();\n}\nstatic void __stdcall TVP_Stub_246f30d208c1d3a4e2b558090f403734(tTJSVariant * _this)\n{\n\treturn _this->ToObject();\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_3206ef9b7a8013d6572decdea49e7e2e(tTJSVariant * _this)\n{\n\treturn _this->operator iTJSDispatch2 *();\n}\nstatic void __stdcall TVP_Stub_c5a30d297c3a121879b1392bc6c604ef(tTJSVariant * _this)\n{\n\treturn _this->ToString();\n}\nstatic tjs_uint32 * __stdcall TVP_Stub_e398f5aef0ab92bc1323f3b094722fb1(tTJSVariant * _this)\n{\n\treturn _this->GetHint();\n}\nstatic void __stdcall TVP_Stub_0733b0ac80880897d327dc6f3b04ea9e(tTJSVariant * _this)\n{\n\treturn _this->ToOctet();\n}\nstatic void __stdcall TVP_Stub_4cb055ed9d8ef71d1af10898965c940c(tTJSVariant * _this)\n{\n\treturn _this->ToInteger();\n}\nstatic void __stdcall TVP_Stub_ef8d198596b7d3143d02ed4450ccefa1(tTJSVariant * _this)\n{\n\treturn _this->ToReal();\n}\nstatic tTJSVariant & __stdcall TVP_Stub_d48ea419e040ffe8c20c1e86d80c9a5f(tTJSVariant * _this, const tTJSVariant & ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic void __stdcall TVP_Stub_679b215ff76a269871d5f325b981e561(tTJSVariant * _this, const tTJSVariant & ref)\n{\n\treturn _this->CopyRef(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_1039eff4a4443f9238438485a35a93a7(tTJSVariant * _this, iTJSDispatch2 * ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_2f873b0ee1c6591ba28bc4b9c0e4c954(tTJSVariant * _this, iTJSDispatch2 * ref)\n{\n\treturn _this->SetObject(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_a583ffb56cdb2ede691e15053a8a165a(tTJSVariant * _this, iTJSDispatch2 * object , iTJSDispatch2 * objthis)\n{\n\treturn _this->SetObject(object, objthis);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_e09ed277802c1b117e1908421448886d(tTJSVariant * _this, tTJSVariantClosure ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_e76dfb9e00f4a9d491117d815f30db7f(tTJSVariant * _this, tTJSVariantString * ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_b000dd8934508d8ec6d6ef976a6ff49b(tTJSVariant * _this, tTJSVariantOctet * ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_d98ab5c968ebfde4e924901d09190774(tTJSVariant * _this, const tTJSString & ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_661e8c10d5d477e6823a840244937cd8(tTJSVariant * _this, const tjs_char * ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_6b39e70ea89c4f883689f51289029b69(tTJSVariant * _this, const tjs_nchar * ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_4a18b1c0afe37b84e2b35a7fc07c4e0f(tTJSVariant * _this, bool ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_48b85c8774d91ca40b2992f0e452f19e(tTJSVariant * _this, tjs_int32 ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_5ea8db9a9193fe6bab53baf2bee06b6b(tTJSVariant * _this, const tTVInteger ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic tTJSVariant & __stdcall TVP_Stub_46b92626ff6894e993c4f193a129540b(tTJSVariant * _this, tjs_real ref)\n{\n\treturn _this->operator =(ref);\n}\nstatic void __stdcall TVP_Stub_6efc1d1f66f0e01a81faf767d7576816(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->logicalorequal(rhs);\n}\nstatic void __stdcall TVP_Stub_4ededf58eae77c320b4a6f5f701acafb(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->logicalandequal(rhs);\n}\nstatic void __stdcall TVP_Stub_028d5fda2f4568f6ab14b49d89650a4d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator |=(rhs);\n}\nstatic void __stdcall TVP_Stub_11912984b8c094d2df26bf3c3677d096(tTJSVariant * _this)\n{\n\treturn _this->increment();\n}\nstatic void __stdcall TVP_Stub_6c0df790c33142e286aea9af6993d931(tTJSVariant * _this)\n{\n\treturn _this->decrement();\n}\nstatic void __stdcall TVP_Stub_c27d85b695cd6e144210785bdfd446ce(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator ^=(rhs);\n}\nstatic void __stdcall TVP_Stub_8422ef7f42009be0ad58a09d64149051(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator &=(rhs);\n}\nstatic void __stdcall TVP_Stub_ee07e6522577952453206ede39cdf54c(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator >>=(rhs);\n}\nstatic void __stdcall TVP_Stub_786a65424247e711f6ca31f0a10603d7(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->rbitshiftequal(rhs);\n}\nstatic void __stdcall TVP_Stub_995a222f2038dd2007f2c1f6429bd19e(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator <<=(rhs);\n}\nstatic void __stdcall TVP_Stub_da8c6e750d6a9c0557a56ef7f7fd8e88(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator %=(rhs);\n}\nstatic void __stdcall TVP_Stub_9cf7b0f119bcf3fa4564837ae25429b3(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator /=(rhs);\n}\nstatic void __stdcall TVP_Stub_17cbcacad2ed350215d7d700c676ea40(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->idivequal(rhs);\n}\nstatic void __stdcall TVP_Stub_2bd375c0598e9148d88579a51b2f07a8(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator *=(rhs);\n}\nstatic void __stdcall TVP_Stub_4d2c157f8b0b49e57c3e9b5abc9deb0f(tTJSVariant * _this)\n{\n\treturn _this->logicalnot();\n}\nstatic void __stdcall TVP_Stub_4b7eaccf64af0f3a4c4fe64f4e2dd3fd(tTJSVariant * _this)\n{\n\treturn _this->bitnot();\n}\nstatic void __stdcall TVP_Stub_3a4d2602c392a8d1f4c38d537a8c95e0(tTJSVariant * _this)\n{\n\treturn _this->tonumber();\n}\nstatic void __stdcall TVP_Stub_8d915d35ef8e857f245c5d46798618e4(tTJSVariant * _this)\n{\n\treturn _this->changesign();\n}\nstatic void __stdcall TVP_Stub_1e463482afa8ca30f5fa7bea4fa5741d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator -=(rhs);\n}\nstatic void __stdcall TVP_Stub_fdf270e4080c986abd1649fa9fffdeab(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator +=(rhs);\n}\nstatic tTJSVariantType __stdcall TVP_Stub_972e0f9a6ec4648a9fb82bcf5d9095ff(tTJSVariant * _this)\n{\n\treturn _this->Type();\n}\nstatic bool __stdcall TVP_Stub_9d76731c37c4664d654db026644c64b4(tTJSVariant * _this, const tTJSVariant & val2)\n{\n\treturn _this->NormalCompare(val2);\n}\nstatic bool __stdcall TVP_Stub_4f1620cb699874b9c8cedf6e321c606e(tTJSVariant * _this, const tTJSVariant & val2)\n{\n\treturn _this->DiscernCompare(val2);\n}\nstatic bool __stdcall TVP_Stub_ef1c6b2b601d1b0ff70272a4d447aa3c(tTJSVariant * _this, const tTJSVariant & val2)\n{\n\treturn _this->DiscernCompareStrictReal(val2);\n}\nstatic bool __stdcall TVP_Stub_9b7872860c95cfdafb056ab30318e99c(tTJSVariant * _this, const tTJSVariant & val2)\n{\n\treturn _this->GreaterThan(val2);\n}\nstatic bool __stdcall TVP_Stub_53360f194a04fc142ddae2b9a3ab4c92(tTJSVariant * _this, const tTJSVariant & val2)\n{\n\treturn _this->LittlerThan(val2);\n}\nstatic bool __stdcall TVP_Stub_ce1dcb05e5e7c4cafbc4ed37f63b256e(tTJSVariant * _this, const tjs_char * classname)\n{\n\treturn _this->IsInstanceOf(classname);\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_841ce4492b37321eea0c1b500de9b352(tTJSVariant * _this)\n{\n\treturn _this->AsObject();\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_61785de870894968cd9d95e17e88eafc(tTJSVariant * _this)\n{\n\treturn _this->AsObjectNoAddRef();\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_ad3236e727398311c3b8e1ddd5f4b293(tTJSVariant * _this)\n{\n\treturn _this->AsObjectThis();\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_80e0b7be488545ff9b8bc52c9ab5fba5(tTJSVariant * _this)\n{\n\treturn _this->AsObjectThisNoAddRef();\n}\nstatic tTJSVariantClosure & __stdcall TVP_Stub_4eaa3e4efb319707db6ef81db1c6f147(tTJSVariant * _this)\n{\n\treturn _this->AsObjectClosureNoAddRef();\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_693a0152f098caee7fc77f545dd3e954(tTJSVariant * _this)\n{\n\treturn _this->AsString();\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_42840710f5fba9bb32b95290b1796a55(tTJSVariant * _this)\n{\n\treturn _this->AsStringNoAddRef();\n}\nstatic const tjs_char * __stdcall TVP_Stub_adec3f9ef429aa9a284081f0fc6a1b5b(tTJSVariant * _this)\n{\n\treturn _this->GetString();\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_674a7948152a1d7a49050b9d98796403(tTJSVariant * _this)\n{\n\treturn _this->AsOctet();\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_aa6f132b2031c83062f6149c90f2df5f(tTJSVariant * _this)\n{\n\treturn _this->AsOctetNoAddRef();\n}\nstatic tTVInteger __stdcall TVP_Stub_b52f446e22bb92d495f7e65ac71c9bf9(tTJSVariant * _this)\n{\n\treturn _this->AsInteger();\n}\nstatic void __stdcall TVP_Stub_d4899fd4a8beb06f192dcb1d300e3319(tTJSVariant * _this, tTJSVariant & targ)\n{\n\treturn _this->AsNumber(targ);\n}\nstatic tTVInteger __stdcall TVP_Stub_d3f5ec78464d29ee6988a1f90c2e3e1b(tTJSVariant * _this)\n{\n\treturn _this->operator tTVInteger();\n}\nstatic bool __stdcall TVP_Stub_a463ad6a757c3f04e09a72e288737d06(tTJSVariant * _this)\n{\n\treturn _this->operator bool();\n}\nstatic tjs_int __stdcall TVP_Stub_27857bb89d35113183b682c3917d6c7a(tTJSVariant * _this)\n{\n\treturn _this->operator tjs_int();\n}\nstatic tTVReal __stdcall TVP_Stub_a5f80951cfb882ac6a3e06c0b9a95807(tTJSVariant * _this)\n{\n\treturn _this->AsReal();\n}\nstatic tTVReal __stdcall TVP_Stub_35aadb63079c8bd84ebc0389bae306e0(tTJSVariant * _this)\n{\n\treturn _this->operator tTVReal();\n}\nstatic tTJSVariant __stdcall TVP_Stub_fb6573df5887c2020ae58136f8342ed4(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator ||(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_86c67d2197c46824ab10f59e568ad13a(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator &&(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_263a0c5b335b2c4d5bc1f55b51b8315e(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator |(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_975c1099e57ab67122ddef0f44fd7dd5(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator ^(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_04493e5237a7ca97afd391cb7e831ba0(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator &(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_9996100acc7705cb2b0c904d6bad4401(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator !=(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_5d91cff3b2a26ff7c0543e0f6d737117(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator ==(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_ef1dedc2cb58dc4e1afc14238b6fc518(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator <(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_f18397fe81c043ba2346e31b359f6a73(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator >(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_2ee45ad60b0c06a8d0feebc3a6aad9e7(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator <=(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_44500491c57e17032951fe6ed268ff1d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator >=(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_056f5d278c75750df792bf8b081fbf7d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator >>(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_04233bc4f7d4df92c260d23110320afe(tTJSVariant * _this, tjs_int count)\n{\n\treturn _this->rbitshift(count);\n}\nstatic tTJSVariant __stdcall TVP_Stub_cdc475c4419e77c22508e337428c4074(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator <<(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_06bacb2910308a47bbe27ff7efa1226d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator %(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_521e053199a4aeb4e0f24d9f4a6cc682(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator /(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_02164e6fb4c925843ac774ec1e4c6e5d(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->idiv(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_5110cbbcddbd9688281ee5418e3f9023(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator *(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_1db54b61f00bf931452218c4a39e79ef(tTJSVariant * _this)\n{\n\treturn _this->operator !();\n}\nstatic tTJSVariant __stdcall TVP_Stub_9d0edd8f51f155767301017bd3d256da(tTJSVariant * _this)\n{\n\treturn _this->operator ~();\n}\nstatic tTJSVariant __stdcall TVP_Stub_8f744c5aa8df5471939b960bc759f12b(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator -(rhs);\n}\nstatic tTJSVariant __stdcall TVP_Stub_ba7ff7b0b4192bd2cc7f49c7b688ad57(tTJSVariant * _this)\n{\n\treturn _this->operator +();\n}\nstatic tTJSVariant __stdcall TVP_Stub_7773ac921bb82c85de3be69ef86265fd(tTJSVariant * _this)\n{\n\treturn _this->operator -();\n}\nstatic tTJSVariant __stdcall TVP_Stub_114a781ed71edace31abb352a2671f41(tTJSVariant * _this, const tTJSVariant & rhs)\n{\n\treturn _this->operator +(rhs);\n}\nstatic void * __stdcall TVP_Stub_2bc5f4a97decfa82c625430479ec512b(size_t size)\n{\n\treturn tTJSVariant::operator new(size);\n}\nstatic void __stdcall TVP_Stub_066fb79f94523d95d12480f23c58cc8e(void * p)\n{\n\treturn tTJSVariant::operator delete(p);\n}\nstatic void * __stdcall TVP_Stub_803906b8de16ff825d4e69e1952d872f(size_t size)\n{\n\treturn tTJSVariant::operator new [](size);\n}\nstatic void __stdcall TVP_Stub_34cc96a5118ee1e12b0750ea64d40b1f(void * p)\n{\n\treturn tTJSVariant::operator delete [](p);\n}\nstatic void * __stdcall TVP_Stub_dbe821fb8b651d42a9c8e730517c408c(size_t size , void * buf)\n{\n\treturn tTJSVariant::operator new(size, buf);\n}\nstatic void __stdcall TVP_Stub_8970ba46068ac74746c3e84299937d8f(tTJSVariantOctet * _this, const tjs_uint8 * data , tjs_uint length)\n{\n\t::new (_this) tTJSVariantOctet(data, length);\n}\nstatic void __stdcall TVP_Stub_438e27dcbb077284213eb4d7dcd43f8f(tTJSVariantOctet * _this, const tjs_uint8 * data1 , tjs_uint len1 , const tjs_uint8 * data2 , tjs_uint len2)\n{\n\t::new (_this) tTJSVariantOctet(data1, len1, data2, len2);\n}\nstatic void __stdcall TVP_Stub_a98d712ca19a49afe07d0a7c5d064cef(tTJSVariantOctet * _this, const tTJSVariantOctet * o1 , const tTJSVariantOctet * o2)\n{\n\t::new (_this) tTJSVariantOctet(o1, o2);\n}\nstatic void __stdcall TVP_Stub_08aef69683bcfe2a5c63d4c7866de8e9(tTJSVariantOctet * _this)\n{\n\t_this->~tTJSVariantOctet();\n}\nstatic void __stdcall TVP_Stub_dbc9bc2e27068c8426b1c6a7f89424e0(tTJSVariantOctet * _this)\n{\n\treturn _this->AddRef();\n}\nstatic void __stdcall TVP_Stub_5eeb98ca016123f57966457533bb639e(tTJSVariantOctet * _this)\n{\n\treturn _this->Release();\n}\nstatic tjs_uint __stdcall TVP_Stub_98fdc846d0b4a83412f3521f65bb98b4(tTJSVariantOctet * _this)\n{\n\treturn _this->GetLength();\n}\nstatic const tjs_uint8 * __stdcall TVP_Stub_3309591d3c7f6f688e81588f169dba21(tTJSVariantOctet * _this)\n{\n\treturn _this->GetData();\n}\nstatic void __stdcall TVP_Stub_d83a866389246d824efcc83303a04484(tTJSString * _this)\n{\n\t::new (_this) tTJSString();\n}\nstatic void __stdcall TVP_Stub_6cf6f332a6a14a15e8dce62301f5c840(tTJSString * _this, const tTJSString & rhs)\n{\n\t::new (_this) tTJSString(rhs);\n}\nstatic void __stdcall TVP_Stub_566eeea3c5f009b0fc6fa123ba30f496(tTJSString * _this, tTJSVariantString * vstr)\n{\n\t::new (_this) tTJSString(vstr);\n}\nstatic void __stdcall TVP_Stub_88806e38e35c73b36acadd4061a4fe0b(tTJSString * _this, const tjs_char * str)\n{\n\t::new (_this) tTJSString(str);\n}\nstatic void __stdcall TVP_Stub_3bb69d3886159aaecc333b6ff17287bf(tTJSString * _this, const tjs_nchar * str)\n{\n\t::new (_this) tTJSString(str);\n}\nstatic void __stdcall TVP_Stub_3e36278551a9c8b29cb2e8017db6af0d(tTJSString * _this, const tTJSStringBufferLength len)\n{\n\t::new (_this) tTJSString(len);\n}\nstatic void __stdcall TVP_Stub_5de99d84f3dc902cb0812fb85a7d5c88(tTJSString * _this, tjs_char rch)\n{\n\t::new (_this) tTJSString(rch);\n}\nstatic void __stdcall TVP_Stub_31e85cbc73f8fbd4cea895a751480059(tTJSString * _this, const tTJSVariant & val)\n{\n\t::new (_this) tTJSString(val);\n}\nstatic void __stdcall TVP_Stub_6ae29e405ede762f1a89a9dd526cb36e(tTJSString * _this, const tTJSString & str , int n)\n{\n\t::new (_this) tTJSString(str, n);\n}\nstatic void __stdcall TVP_Stub_c95bd66d95c153cdac41b5243e555f5f(tTJSString * _this, const tjs_char * str , int n)\n{\n\t::new (_this) tTJSString(str, n);\n}\nstatic void __stdcall TVP_Stub_72a67e9c52fd27dbb66eded47efeea74(tTJSString * _this, tjs_int n)\n{\n\t::new (_this) tTJSString(n);\n}\nstatic void __stdcall TVP_Stub_fb13e41bda53e4e59403e3e14effccd6(tTJSString * _this)\n{\n\t_this->~tTJSString();\n}\nstatic tTJSString & __stdcall TVP_Stub_9a5c710e620e47f105752453ad5d6ab1(tTJSString * _this, const tTJSString & rhs)\n{\n\treturn _this->operator =(rhs);\n}\nstatic tTJSString & __stdcall TVP_Stub_18f1ad16c11429707cbf8ea4d1d4a21e(tTJSString * _this, const tjs_char * rhs)\n{\n\treturn _this->operator =(rhs);\n}\nstatic tTJSString & __stdcall TVP_Stub_550f317b573a1256af00586890ae82f1(tTJSString * _this, const tjs_nchar * rhs)\n{\n\treturn _this->operator =(rhs);\n}\nstatic void __stdcall TVP_Stub_cd50da721dfb63f36c1ebb1226830428(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator +=(ref);\n}\nstatic void __stdcall TVP_Stub_fbba3dd6a087599d1277ae58f6cec18e(tTJSString * _this, const tTJSVariantString * ref)\n{\n\treturn _this->operator +=(ref);\n}\nstatic void __stdcall TVP_Stub_43cc5b5a61a6090af83333d115b5b868(tTJSString * _this, const tjs_char * ref)\n{\n\treturn _this->operator +=(ref);\n}\nstatic void __stdcall TVP_Stub_616fb5060d81eb5bab58647596582df4(tTJSString * _this, tjs_char rch)\n{\n\treturn _this->operator +=(rch);\n}\nstatic void __stdcall TVP_Stub_168cf4c1b9ef70b98f2e0ab3695a4f3b(tTJSString * _this)\n{\n\treturn _this->Clear();\n}\nstatic tjs_char * __stdcall TVP_Stub_314573cca30a7c2aecc9166fbf5400c9(tTJSString * _this, tjs_uint len)\n{\n\treturn _this->AllocBuffer(len);\n}\nstatic tjs_char * __stdcall TVP_Stub_03da356426c038fad663c836c3e330ef(tTJSString * _this, tjs_uint len)\n{\n\treturn _this->AppendBuffer(len);\n}\nstatic void __stdcall TVP_Stub_31dbebdedc08d75e34a2cd564ce60586(tTJSString * _this)\n{\n\treturn _this->FixLen();\n}\nstatic void __stdcall TVP_Stub_d9224ad7a0de743a7eea15fdb2c5f934(tTJSString * _this, const tTJSString & from , const tTJSString & to , bool forall = true)\n{\n\treturn _this->Replace(from, to, forall);\n}\nstatic void __stdcall TVP_Stub_c01b0720b49ce4f792446d8965d2c31f(tTJSString * _this)\n{\n\treturn _this->ToLowerCase();\n}\nstatic void __stdcall TVP_Stub_4af47e46a11e1357cb994f405289d13e(tTJSString * _this)\n{\n\treturn _this->ToUppserCase();\n}\nstatic tjs_uint32 * __stdcall TVP_Stub_25b6dafa19bfa5bde1a8b519da248f82(tTJSString * _this)\n{\n\treturn _this->GetHint();\n}\nstatic tjs_char * __stdcall TVP_Stub_72425405819c900aec719491cbd90c6d(tTJSString * _this)\n{\n\treturn _this->Independ();\n}\nstatic const tjs_char * __stdcall TVP_Stub_a79942af73f33bff6e432c9fd808e469(tTJSString * _this)\n{\n\treturn _this->c_str();\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_df106470a4141ebc7eda22160859ffdc(tTJSString * _this)\n{\n\treturn _this->AsVariantStringNoAddRef();\n}\nstatic tjs_int64 __stdcall TVP_Stub_469bc225b0ecd9561aae5a46b85ded42(tTJSString * _this)\n{\n\treturn _this->AsInteger();\n}\nstatic bool __stdcall TVP_Stub_a6663c078b3aa79b39ee2d09f3875765(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator ==(ref);\n}\nstatic bool __stdcall TVP_Stub_efbe634ce4f13633e220cae167cf63fb(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator !=(ref);\n}\nstatic tjs_int __stdcall TVP_Stub_57f4147bcc09e4e4442ffc9b0895727e(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->CompareIC(ref);\n}\nstatic bool __stdcall TVP_Stub_1fb2d2e44cf83aebef7b26fd6b20bc2b(tTJSString * _this, const tjs_char * ref)\n{\n\treturn _this->operator ==(ref);\n}\nstatic bool __stdcall TVP_Stub_bd6aa777bac947f5cffd891e9c724794(tTJSString * _this, const tjs_char * ref)\n{\n\treturn _this->operator !=(ref);\n}\nstatic tjs_int __stdcall TVP_Stub_83c662330b75d616cdc8a4e11d7ababa(tTJSString * _this, const tjs_char * ref)\n{\n\treturn _this->CompareIC(ref);\n}\nstatic bool __stdcall TVP_Stub_bbde02fe30c8a6cadb7073174ea3a874(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator <(ref);\n}\nstatic bool __stdcall TVP_Stub_cc1c14f63867f90bc883de03e9212cbc(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator >(ref);\n}\nstatic tTJSString __stdcall TVP_Stub_236e007b32bc2631b5f6dc1eda6be0a9(tTJSString * _this, const tTJSString & ref)\n{\n\treturn _this->operator +(ref);\n}\nstatic tTJSString __stdcall TVP_Stub_cfbb9809e0e6d954b2652856e935ced9(tTJSString * _this, const tjs_char * ref)\n{\n\treturn _this->operator +(ref);\n}\nstatic tTJSString __stdcall TVP_Stub_60ee96ae4a7704340bef20fb35ba6ade(tTJSString * _this, tjs_char rch)\n{\n\treturn _this->operator +(rch);\n}\nstatic tjs_char __stdcall TVP_Stub_564b37278b50f4e5597dff6540868d49(tTJSString * _this, tjs_uint i)\n{\n\treturn _this->operator [](i);\n}\nstatic void __stdcall TVP_Stub_890b3a4831b824653e919b4a5197358d(tTJSString * _this, tTJSString & dest)\n{\n\treturn _this->AsLowerCase(dest);\n}\nstatic void __stdcall TVP_Stub_2dfa6c77c5051d160b8a06f540e0d68b(tTJSString * _this, tTJSString & dest)\n{\n\treturn _this->AsUpperCase(dest);\n}\nstatic void __stdcall TVP_Stub_05f88567d510fd84659ccbf493f647ed(tTJSString * _this, tTJSString & dest)\n{\n\treturn _this->EscapeC(dest);\n}\nstatic void __stdcall TVP_Stub_7166b8f7bb9688c980e4fa172f06f30c(tTJSString * _this, tTJSString & dest)\n{\n\treturn _this->UnescapeC(dest);\n}\nstatic bool __stdcall TVP_Stub_b9456ecba8b7898d80d2e5caa64035c9(tTJSString * _this, const tjs_char * string)\n{\n\treturn _this->StartsWith(string);\n}\nstatic bool __stdcall TVP_Stub_dd44464bd8430a5be5fef0cffcd97117(tTJSString * _this, const tTJSString & string)\n{\n\treturn _this->StartsWith(string);\n}\nstatic tjs_int __stdcall TVP_Stub_a57696ca0c157cd7d3cd4e58c1df957c(tTJSString * _this)\n{\n\treturn _this->GetNarrowStrLen();\n}\nstatic void __stdcall TVP_Stub_1aea9f8a38bbb875b6d052f330da9178(tTJSString * _this, tjs_nchar * dest , tjs_int destmaxlen)\n{\n\treturn _this->ToNarrowStr(dest, destmaxlen);\n}\nstatic bool __stdcall TVP_Stub_2d3b3d6e22ee139cda9eee47dc031945(tTJSString * _this)\n{\n\treturn _this->IsEmpty();\n}\nstatic tjs_int __stdcall TVP_Stub_8ff49e56c3c4c566561dcdd5c9ecc4db(tTJSString * _this)\n{\n\treturn _this->GetLen();\n}\nstatic tjs_int __stdcall TVP_Stub_490b547e93e40082d0b83312467104f9(tTJSString * _this)\n{\n\treturn _this->length();\n}\nstatic tjs_char __stdcall TVP_Stub_2c1ef06748df47df52b586ac0fbc6a34(tTJSString * _this)\n{\n\treturn _this->GetLastChar();\n}\nstatic void * __stdcall TVP_Stub_b6b2a03160b88239eccd18d89b1537d3(size_t size)\n{\n\treturn tTJSString::operator new(size);\n}\nstatic void __stdcall TVP_Stub_8becefbd52c76c7ecb0ea7b7f50b7915(void * p)\n{\n\treturn tTJSString::operator delete(p);\n}\nstatic void * __stdcall TVP_Stub_74b9687a3bfd3b2c7abe226efc4225c1(size_t size)\n{\n\treturn tTJSString::operator new [](size);\n}\nstatic void __stdcall TVP_Stub_7cafc2bf5965b594e60830e3057bbd58(void * p)\n{\n\treturn tTJSString::operator delete [](p);\n}\nstatic void * __stdcall TVP_Stub_80f111939c5694cbf43d07cf0ad1726c(size_t size , void * buf)\n{\n\treturn tTJSString::operator new(size, buf);\n}\nstatic void __stdcall TVP_Stub_8dc9cef84191f79b38403a2070952fd4(tTJSVariantString * _this)\n{\n\treturn _this->AddRef();\n}\nstatic void __stdcall TVP_Stub_1d42bd1e659b36886c20567497b7ee96(tTJSVariantString * _this)\n{\n\treturn _this->Release();\n}\nstatic void __stdcall TVP_Stub_0848fbdc7eeddb12c80bcd9c31383a64(tTJSVariantString * _this, const tjs_char * ref , tjs_int maxlen = - 1)\n{\n\treturn _this->SetString(ref, maxlen);\n}\nstatic void __stdcall TVP_Stub_1f1123c906c28ab6d16b6bef3f7ae978(tTJSVariantString * _this, const tjs_nchar * ref)\n{\n\treturn _this->SetString(ref);\n}\nstatic void __stdcall TVP_Stub_b84394e20cc73a90349cf5be4e783111(tTJSVariantString * _this, tjs_uint len)\n{\n\treturn _this->AllocBuffer(len);\n}\nstatic void __stdcall TVP_Stub_76e0db3797851fe8ff90cf84780c50ad(tTJSVariantString * _this, const tjs_char * ref)\n{\n\treturn _this->ResetString(ref);\n}\nstatic void __stdcall TVP_Stub_6616241156c22bced42cd9f2f647677e(tTJSVariantString * _this, tjs_uint applen)\n{\n\treturn _this->AppendBuffer(applen);\n}\nstatic void __stdcall TVP_Stub_1ace346a3dd546c66ad115a33d8cf693(tTJSVariantString * _this, const tjs_char * str)\n{\n\treturn _this->Append(str);\n}\nstatic void __stdcall TVP_Stub_96fb9bbe33531d4268573355c658e165(tTJSVariantString * _this, const tjs_char * str , tjs_int applen)\n{\n\treturn _this->Append(str, applen);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_c90b5737134c76f9ed0bb5da7cfaad8c(tTJSVariantString * _this)\n{\n\treturn _this->FixLength();\n}\nstatic tjs_uint32 * __stdcall TVP_Stub_070ed05259a265cabdd82bfedabdd638(tTJSVariantString * _this)\n{\n\treturn _this->GetHint();\n}\nstatic const tjs_char * __stdcall TVP_Stub_008b7e3a4c5bb23ee991f684a5064737(tTJSVariantString * _this)\n{\n\treturn _this->operator const tjs_char *();\n}\nstatic tjs_int __stdcall TVP_Stub_b64741dc4544ed43c44ddb6d0eb838ea(tTJSVariantString * _this)\n{\n\treturn _this->GetLength();\n}\nstatic tTVInteger __stdcall TVP_Stub_5b83e28b2d9ab0f75d7c7f6f61b5ded6(tTJSVariantString * _this)\n{\n\treturn _this->ToInteger();\n}\nstatic tTVReal __stdcall TVP_Stub_b948c9f43837efa489b0b91f3f675710(tTJSVariantString * _this)\n{\n\treturn _this->ToReal();\n}\nstatic void __stdcall TVP_Stub_eb83216f6f718245468ef48b97ab4c2d(tTJSVariantString * _this, tTJSVariant & dest)\n{\n\treturn _this->ToNumber(dest);\n}\nstatic tjs_int __stdcall TVP_Stub_c66ab4868b743de9c0ba8b26c67b23da(tTJSVariantString * _this)\n{\n\treturn _this->GetRefCount();\n}\n#include \"tjsTypes.h\"\n#include \"tjsConfig.h\"\nstatic tjs_int __stdcall TVP_Stub_586e16d502a6ad98b08161bdb090f8b6(const tjs_char * s)\n{\n\treturn TJS_atoi(s);\n}\nstatic tjs_char * __stdcall TVP_Stub_d8bc9c71c80b200c39b29167d795cad0(tjs_int value , tjs_char * string)\n{\n\treturn TJS_int_to_str(value, string);\n}\nstatic tjs_char * __stdcall TVP_Stub_85df4beb87f6503891e116ce046353c3(tjs_int64 value , tjs_char * string)\n{\n\treturn TJS_tTVInt_to_str(value, string);\n}\nstatic tjs_int __stdcall TVP_Stub_35b6a7e1c73f257aae91e05fa9826e84(const tjs_char * s1 , const tjs_char * s2 , size_t maxlen)\n{\n\treturn TJS_strnicmp(s1, s2, maxlen);\n}\nstatic tjs_int __stdcall TVP_Stub_a25b46701e25030af1ed847e0df229eb(const tjs_char * s1 , const tjs_char * s2)\n{\n\treturn TJS_stricmp(s1, s2);\n}\nstatic void __stdcall TVP_Stub_c8906bf1efa5e86f9fddfab55a01c8f6(tjs_char * d , const tjs_char * s , size_t len)\n{\n\treturn TJS_strcpy_maxlen(d, s, len);\n}\nstatic void __stdcall TVP_Stub_8141059f613820f694608af28e20cbad(tjs_char * d , const tjs_char * s)\n{\n\treturn TJS_strcpy(d, s);\n}\nstatic size_t __stdcall TVP_Stub_cf2690e47099ac6378ed50df4a8a8e90(const tjs_char * d)\n{\n\treturn TJS_strlen(d);\n}\n#include \"tjsVariantString.h\"\nstatic tjs_char * __stdcall TVP_Stub_810c7054e44f535cf250f00707105417(tjs_uint len)\n{\n\treturn TJSVS_malloc(len);\n}\nstatic tjs_char * __stdcall TVP_Stub_52a9af7905ddc71d8b4e0ef7366eebdd(tjs_char * buf , tjs_uint len)\n{\n\treturn TJSVS_realloc(buf, len);\n}\nstatic void __stdcall TVP_Stub_1635dbae2d91b338ddfd0430f8aa7f10(tjs_char * buf)\n{\n\treturn TJSVS_free(buf);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_30df0c29ad8f672f7fe0742b4b11cd7f(const tjs_char * ref1 , const tjs_char * ref2)\n{\n\treturn TJSAllocVariantString(ref1, ref2);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_61c82dec644c58290a25f34a69478870(const tjs_char * ref , tjs_int n)\n{\n\treturn TJSAllocVariantString(ref, n);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_f08e347d2d47dc5fc9a3cb59355b4fbb(const tjs_char * ref)\n{\n\treturn TJSAllocVariantString(ref);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_5c62e59c2062f658d4c79d5257a9a586(const tjs_nchar * ref)\n{\n\treturn TJSAllocVariantString(ref);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_259c72d8bfed1210ca71c54f24cacc7a(const tjs_uint8 * * src)\n{\n\treturn TJSAllocVariantString(src);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_801a92ace08eb7ed001406869a39a75f(tjs_uint len)\n{\n\treturn TJSAllocVariantStringBuffer(len);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_e22e647af4ded8e51b1e76c845b4c8e2(tTJSVariantString * str , const tjs_char * app)\n{\n\treturn TJSAppendVariantString(str, app);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_12902221314df9bcf7f7cb74a5242fe0(tTJSVariantString * str , const tTJSVariantString * app)\n{\n\treturn TJSAppendVariantString(str, app);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_b10feea1619ba8ac11237c12002cdb3e(const tjs_char * format , tjs_uint numparams , tTJSVariant * * params)\n{\n\treturn TJSFormatString(format, numparams, params);\n}\n#include \"tjsUtils.h\"\nstatic const tjs_char * __stdcall TVP_Stub_19755b50d241edcb477bdcac22663778(tTJSVariantType type)\n{\n\treturn TJSVariantTypeToTypeString(type);\n}\nstatic tTJSString __stdcall TVP_Stub_040a0ecf46963e094ee8ec32ab3f1962(const tTJSVariant & val , tjs_int maxlen = 512)\n{\n\treturn TJSVariantToReadableString(val, maxlen);\n}\nstatic tTJSString __stdcall TVP_Stub_525c529dc687b5d86424d775d00bdfce(const tTJSVariant & val)\n{\n\treturn TJSVariantToExpressionString(val);\n}\nstatic void * __stdcall TVP_Stub_c96107b91e2a215f560a2612c6e85931(tjs_uint bytes , tjs_uint align_bits)\n{\n\treturn TJSAlignedAlloc(bytes, align_bits);\n}\nstatic void __stdcall TVP_Stub_b8788eaa2ca495263c6ea2df264af5f5(void * ptr)\n{\n\treturn TJSAlignedDealloc(ptr);\n}\nstatic tjs_uint32 __stdcall TVP_Stub_4c6494008c520d896d699f82aca30b25(tjs_real r)\n{\n\treturn TJSGetFPClass(r);\n}\n#include \"tjsString.h\"\nstatic tTJSString __stdcall TVP_Stub_7d8f8d5e0832ecf248b19a89801ead0e(const tjs_char * lhs , const tTJSString & rhs)\n{\n\treturn operator +(lhs, rhs);\n}\nstatic tTJSString __stdcall TVP_Stub_70849965060a6402f41b0b11ec2bb3a7(tjs_uint32 num , int zeropad = 8)\n{\n\treturn TJSInt32ToHex(num, zeropad);\n}\n#include \"tjsInterface.h\"\n#include \"tjsErrorDefs.h\"\n#include \"tjsNative.h\"\nstatic tjs_int32 __stdcall TVP_Stub_c72efa6b4efaa6664ae637a03e98e866(const tjs_char * name)\n{\n\treturn TJSRegisterNativeClass(name);\n}\nstatic tjs_int32 __stdcall TVP_Stub_a250e46575d0df1166e1542613218a5c(const tjs_char * name)\n{\n\treturn TJSFindNativeClassID(name);\n}\nstatic const tjs_char * __stdcall TVP_Stub_a7bcff67b8d380c225b9d0d83921b3ae(tjs_int32 id)\n{\n\treturn TJSFindNativeClassName(id);\n}\nstatic tTJSNativeClassMethod * __stdcall TVP_Stub_fb68a3aa16bd2eb7d7550283170321bf(tTJSNativeClassMethodCallback callback)\n{\n\treturn TJSCreateNativeClassMethod(callback);\n}\nstatic tTJSNativeClassMethod * __stdcall TVP_Stub_35b4299ede11f511b331b713ba9f38a8(tTJSNativeClassMethodCallback callback)\n{\n\treturn TJSCreateNativeClassConstructor(callback);\n}\nstatic tTJSNativeClassProperty * __stdcall TVP_Stub_efe52691cff20b2dfaa16e8e16caac0a(tTJSNativeClassPropertyGetCallback get , tTJSNativeClassPropertySetCallback set)\n{\n\treturn TJSCreateNativeClassProperty(get, set);\n}\nstatic void __stdcall TVP_Stub_38eed43ef69251c34dc45695b8cf35c0(tTJSNativeClass * cls , const tjs_char * name , iTJSDispatch2 * dsp , const tjs_char * classname , tTJSNativeInstanceType type , tjs_uint32 flags = 0)\n{\n\treturn TJSNativeClassRegisterNCM(cls, name, dsp, classname, type, flags);\n}\nstatic void __stdcall TVP_Stub_2058b65abdfb7598910f0d584d40a19d(tTJSNativeClass * cls , tjs_int32 classid)\n{\n\treturn TJSNativeClassSetClassID(cls, classid);\n}\nstatic tTJSNativeClassForPlugin * __stdcall TVP_Stub_1ebecaefe2ffdc811fccbac42e67e544(const ttstr & name , tTJSCreateNativeInstance createinstance)\n{\n\treturn TJSCreateNativeClassForPlugin(name, createinstance);\n}\n#include \"tjsVariant.h\"\nstatic void __stdcall TVP_Stub_09e0f0912f8d758d3736ece9478c2686()\n{\n\treturn TJSThrowNullAccess();\n}\nstatic void __stdcall TVP_Stub_23d61eda3959b087b618e348471e2c36()\n{\n\treturn TJSThrowDivideByZero();\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_e99b22c79b5bf04f3382f959c7bb69ca(const tjs_uint8 * data , tjs_uint length)\n{\n\treturn TJSAllocVariantOctet(data, length);\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_9c4bb9ebee4db0fcebeae11c34950f97(const tjs_uint8 * data1 , tjs_uint len1 , const tjs_uint8 * data2 , tjs_uint len2)\n{\n\treturn TJSAllocVariantOctet(data1, len1, data2, len2);\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_505a9563aeb1b0255cfcc8197bee7d9e(const tTJSVariantOctet * o1 , const tTJSVariantOctet * o2)\n{\n\treturn TJSAllocVariantOctet(o1, o2);\n}\nstatic tTJSVariantOctet * __stdcall TVP_Stub_f5ab80fc67ee04570330b9035144e760(const tjs_uint8 * * src)\n{\n\treturn TJSAllocVariantOctet(src);\n}\nstatic void __stdcall TVP_Stub_af50188bbaa019ee88b19ecd931f7cce(tTJSVariantOctet * o)\n{\n\treturn TJSDeallocVariantOctet(o);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_268c452e85a6ac75301a6132f4f5e38b(const tTJSVariantOctet * oct)\n{\n\treturn TJSOctetToListString(oct);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_646770a19b1768b372c9991ef0d3de85(const tTJSVariantClosure & dsp)\n{\n\treturn TJSObjectToString(dsp);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_5ec88e04fcb8e1877752281e172173ed(tjs_int64 i)\n{\n\treturn TJSIntegerToString(i);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_923f8161f2d2ba0e883bc4edc2901960(tjs_real r)\n{\n\treturn TJSRealToString(r);\n}\nstatic tTJSVariantString * __stdcall TVP_Stub_6f70cdb7586cbe571204f286f43c9780(tjs_real r)\n{\n\treturn TJSRealToHexString(r);\n}\nstatic tTVInteger __stdcall TVP_Stub_9a4eaa6a627038799015c093609bdde7(const tjs_char * str)\n{\n\treturn TJSStringToInteger(str);\n}\nstatic tTVReal __stdcall TVP_Stub_c8bb6590f4a7adc906d7b3e42d907267(const tjs_char * str)\n{\n\treturn TJSStringToReal(str);\n}\n#include \"tjsArray.h\"\nstatic iTJSDispatch2 * __stdcall TVP_Stub_8323d57f26876d87271dbfa257b7f7e2(iTJSDispatch2 * * classout = NULL)\n{\n\treturn TJSCreateArrayObject(classout);\n}\nstatic tjs_int __stdcall TVP_Stub_4d6f148e8997e1ae0cc0006ec1bd9618(iTJSDispatch2 * dsp)\n{\n\treturn TJSGetArrayElementCount(dsp);\n}\nstatic tjs_int __stdcall TVP_Stub_7f03a4ddb254d0518642d15513eaea85(iTJSDispatch2 * dsp , tTJSVariant * dest , tjs_uint start , tjs_int count)\n{\n\treturn TJSCopyArrayElementTo(dsp, dest, start, count);\n}\n#include \"tjsDictionary.h\"\nstatic iTJSDispatch2 * __stdcall TVP_Stub_4add3926c72ba9df9259be58b680de0d(iTJSDispatch2 * * classout = NULL)\n{\n\treturn TJSCreateDictionaryObject(classout);\n}\n#include \"tjs.h\"\n#include \"tjsMessage.h\"\nstatic ttstr __stdcall TVP_Stub_075d42cff8dc0c1fbd99c7459a63e526(const tjs_char * name)\n{\n\treturn TJSGetMessageMapMessage(name);\n}\n#include \"tjsGlobalStringMap.h\"\nstatic ttstr __stdcall TVP_Stub_b6bc45b28e194c7ac98bfdea88edee36(const ttstr & string)\n{\n\treturn TJSMapGlobalStringMap(string);\n}\n#include \"tjsObject.h\"\nstatic void __stdcall TVP_Stub_6dff6abb075da1a304520e60c011ef7b(tjs_int op , tTJSVariant & target , const tTJSVariant * param)\n{\n\treturn TJSDoVariantOperation(op, target, param);\n}\nstatic void __stdcall TVP_Stub_892ffbdb8375851fc557e4abe9589b77()\n{\n\treturn TJSDoRehash();\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_b2f3538284fc2adda2a43272ee654a96()\n{\n\treturn TJSCreateCustomObject();\n}\n#include \"StorageIntf.h\"\nstatic ttstr __stdcall TVP_Stub_e0ff899ea4a9cc49a0e3b38deaf93b45()\n{\n\treturn TVPGetTemporaryName();\n}\nstatic ttstr __stdcall TVP_Stub_4b9c9ac2aafad07af4b16f34e9d4bba2()\n{\n\treturn TVPGetAppPath();\n}\nstatic void __stdcall TVP_Stub_c2e423356d9ca3f26f9c1d294ee9b742(iTVPStorageMedia * media)\n{\n\treturn TVPRegisterStorageMedia(media);\n}\nstatic void __stdcall TVP_Stub_c07314686fdf5815ce9b058020da942b(iTVPStorageMedia * media)\n{\n\treturn TVPUnregisterStorageMedia(media);\n}\nstatic bool __stdcall TVP_Stub_4a197be1985d45ee86d5672d24134560(const ttstr & name)\n{\n\treturn TVPIsExistentStorageNoSearch(name);\n}\nstatic bool __stdcall TVP_Stub_dec720a9c3cd2b378f195cf71a9ff8b0(const ttstr & name)\n{\n\treturn TVPIsExistentStorageNoSearchNoNormalize(name);\n}\nstatic ttstr __stdcall TVP_Stub_5726a5c7af641ebaa504dc9ec8380938(const ttstr & name)\n{\n\treturn TVPNormalizeStorageName(name);\n}\nstatic void __stdcall TVP_Stub_1c53bc96ac9dfd483c2227bc5fa44825(const ttstr & name)\n{\n\treturn TVPSetCurrentDirectory(name);\n}\nstatic void __stdcall TVP_Stub_1940c8fa03145aa029d0b7718ce0c809(ttstr & name)\n{\n\treturn TVPGetLocalName(name);\n}\nstatic ttstr __stdcall TVP_Stub_b37f047c0f9bd143b34a2fc87ce5f16e(const ttstr & name)\n{\n\treturn TVPExtractStorageExt(name);\n}\nstatic ttstr __stdcall TVP_Stub_dec35fbd2a24fc32e5c220174d864cf4(const ttstr & name)\n{\n\treturn TVPExtractStorageName(name);\n}\nstatic ttstr __stdcall TVP_Stub_86fd45a126296891aee413388597203e(const ttstr & name)\n{\n\treturn TVPExtractStoragePath(name);\n}\nstatic ttstr __stdcall TVP_Stub_603243e54f3508c37d993e8359b735dc(const ttstr & name)\n{\n\treturn TVPChopStorageExt(name);\n}\nstatic void __stdcall TVP_Stub_c3eadbd75b32dabe6faecebf492eb486(const ttstr & name)\n{\n\treturn TVPAddAutoPath(name);\n}\nstatic void __stdcall TVP_Stub_725e49de1d970ef04b179776666f2c34(const ttstr & name)\n{\n\treturn TVPRemoveAutoPath(name);\n}\nstatic ttstr __stdcall TVP_Stub_55a9b73f877bfd4c6d8157e7b1c458df(const ttstr & name)\n{\n\treturn TVPGetPlacedPath(name);\n}\nstatic bool __stdcall TVP_Stub_d070209f152dd22087e6e996e02c85cf(const ttstr & name)\n{\n\treturn TVPIsExistentStorage(name);\n}\nstatic void __stdcall TVP_Stub_308f905626bc51c7ef9b65b2c0ca34b2()\n{\n\treturn TVPClearStorageCaches();\n}\n#include \"TextStream.h\"\nstatic iTJSTextReadStream * __stdcall TVP_Stub_95aab2a1ac9491e8026f4977e0918760(const ttstr & name , const ttstr & modestr)\n{\n\treturn TVPCreateTextStreamForRead(name, modestr);\n}\nstatic iTJSTextReadStream * __stdcall TVP_Stub_e0ac94325eb783ca2fe7856a54444c90(const ttstr & name , const ttstr & modestr , const ttstr & encoding)\n{\n\treturn TVPCreateTextStreamForReadByEncoding(name, modestr, encoding);\n}\nstatic iTJSTextWriteStream * __stdcall TVP_Stub_0c99a79e866f08b4df3914e83fc203dc(const ttstr & name , const ttstr & modestr)\n{\n\treturn TVPCreateTextStreamForWrite(name, modestr);\n}\nstatic void __stdcall TVP_Stub_f2de531a016173057ff3540e47fed4e6(const ttstr & encoding)\n{\n\treturn TVPSetDefaultReadEncoding(encoding);\n}\nstatic const tjs_char * __stdcall TVP_Stub_4224a9066d8d13d6d7e12f1ace6a5beb()\n{\n\treturn TVPGetDefaultReadEncoding();\n}\n#include \"CharacterSet.h\"\nstatic tjs_int __stdcall TVP_Stub_900476efbc2031e643c042ca8e63a3d7(const tjs_char * in , char * out)\n{\n\treturn TVPWideCharToUtf8String(in, out);\n}\nstatic tjs_int __stdcall TVP_Stub_07dfce61d490cf671a2d5359d713d64a(const char * in , tjs_char * out)\n{\n\treturn TVPUtf8ToWideCharString(in, out);\n}\n#include \"XP3Archive.h\"\nstatic void __stdcall TVP_Stub_52d30ac8479ef7e870b5aff076482799(tTVPXP3ArchiveExtractionFilter filter)\n{\n\treturn TVPSetXP3ArchiveExtractionFilter(filter);\n}\n#include \"EventIntf.h\"\nstatic void __stdcall TVP_Stub_8e4d0392ed46e87f94e5fcf675a124a1()\n{\n\treturn TVPBreathe();\n}\nstatic bool __stdcall TVP_Stub_73f46e08d17e707725f433b454f05a89()\n{\n\treturn TVPGetBreathing();\n}\nstatic void __stdcall TVP_Stub_80d60e682fa72973071e335db272a2a2(bool en)\n{\n\treturn TVPSetSystemEventDisabledState(en);\n}\nstatic bool __stdcall TVP_Stub_6bd6262185fa0b9cf1750f6a525d893a()\n{\n\treturn TVPGetSystemEventDisabledState();\n}\nstatic void __stdcall TVP_Stub_cf29f737d4eb450b26789d421d0ec69a(iTJSDispatch2 * source , iTJSDispatch2 * target , ttstr & eventname , tjs_uint32 tag , tjs_uint32 flag , tjs_uint numargs , tTJSVariant * args)\n{\n\treturn TVPPostEvent(source, target, eventname, tag, flag, numargs, args);\n}\nstatic tjs_int __stdcall TVP_Stub_13c0e371c08fd1b9da2f0c103d01c59a(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag = 0)\n{\n\treturn TVPCancelEvents(source, target, eventname, tag);\n}\nstatic bool __stdcall TVP_Stub_82693e38df8f033ea98f9b7969d66d7b(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag)\n{\n\treturn TVPAreEventsInQueue(source, target, eventname, tag);\n}\nstatic tjs_int __stdcall TVP_Stub_6e3f8a3b18f55dae6153a889f00a3e87(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag)\n{\n\treturn TVPCountEventsInQueue(source, target, eventname, tag);\n}\nstatic void __stdcall TVP_Stub_efe14a197131b4813656d6669cc3475b(iTJSDispatch2 * source , iTJSDispatch2 * target , tjs_uint32 tag = 0)\n{\n\treturn TVPCancelEventsByTag(source, target, tag);\n}\nstatic void __stdcall TVP_Stub_ba4ecf60f872f757b69c84f457b3e941(iTJSDispatch2 * source)\n{\n\treturn TVPCancelSourceEvents(source);\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_dffedabe32ce886e3b7e695b44ad3547(const tjs_char * type , iTJSDispatch2 * targthis , iTJSDispatch2 * targ)\n{\n\treturn TVPCreateEventObject(type, targthis, targ);\n}\nstatic void __stdcall TVP_Stub_f518c60b165658d19a0fadd8f69586aa(tTVPContinuousEventCallbackIntf * cb)\n{\n\treturn TVPAddContinuousEventHook(cb);\n}\nstatic void __stdcall TVP_Stub_6fefcb1c2ca01a876c301ab41dbdab9f(tTVPContinuousEventCallbackIntf * cb)\n{\n\treturn TVPRemoveContinuousEventHook(cb);\n}\nstatic void __stdcall TVP_Stub_df55083347df0483b4ca6ba1e4f0b9a0(tTVPCompactEventCallbackIntf * cb)\n{\n\treturn TVPAddCompactEventHook(cb);\n}\nstatic void __stdcall TVP_Stub_d8d28310f702714733c4c5dc850058df(tTVPCompactEventCallbackIntf * cb)\n{\n\treturn TVPRemoveCompactEventHook(cb);\n}\n#include \"SystemIntf.h\"\nstatic ttstr __stdcall TVP_Stub_52d24c38b05be174bc5c4fdcf02e9b9f()\n{\n\treturn TVPGetPlatformName();\n}\nstatic ttstr __stdcall TVP_Stub_f27f455c8f30cbaf1706faac3c7b8e02()\n{\n\treturn TVPGetOSName();\n}\n#include \"SystemImpl.h\"\nstatic bool __stdcall TVP_Stub_78ec453a50b2800bb01347e8ebbac000(tjs_uint keycode , bool getcurrent = true)\n{\n\treturn TVPGetAsyncKeyState(keycode, getcurrent);\n}\n#include \"ScriptMgnIntf.h\"\nstatic iTJSDispatch2 * __stdcall TVP_Stub_0936d0f6fc53339d255893e58bcc6699()\n{\n\treturn TVPGetScriptDispatch();\n}\nstatic void __stdcall TVP_Stub_f4f7181b7fd679784c50b0cc7ba4c60e(const ttstr & content , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteScript(content, result);\n}\nstatic void __stdcall TVP_Stub_79816d7e5741c2416fefe2c2a8baef00(const ttstr & content , iTJSDispatch2 * context , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteScript(content, context, result);\n}\nstatic void __stdcall TVP_Stub_42a3d248fab928f16555abcceca62834(const ttstr & content , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteExpression(content, result);\n}\nstatic void __stdcall TVP_Stub_926d6212b8b1b238e7bef9b17a3ee643(const ttstr & content , iTJSDispatch2 * context , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteExpression(content, context, result);\n}\nstatic void __stdcall TVP_Stub_236e3d626784d80ca2cc5b2fe14cd9c6(const ttstr & content , const ttstr & name , tjs_int lineofs , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteScript(content, name, lineofs, result);\n}\nstatic void __stdcall TVP_Stub_1bfac11a5f95c842f97a8bb57d4019de(const ttstr & content , const ttstr & name , tjs_int lineofs , iTJSDispatch2 * context , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteScript(content, name, lineofs, context, result);\n}\nstatic void __stdcall TVP_Stub_198ce21c54b0cea4c1bf5eeba35349ab(const ttstr & content , const ttstr & name , tjs_int lineofs , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteExpression(content, name, lineofs, result);\n}\nstatic void __stdcall TVP_Stub_590a1ec7f64904eaa32b5c771bb5f8cd(const ttstr & content , const ttstr & name , tjs_int lineofs , iTJSDispatch2 * context , tTJSVariant * result = NULL)\n{\n\treturn TVPExecuteExpression(content, name, lineofs, context, result);\n}\nstatic void __stdcall TVP_Stub_dd13d4bc2b48540a92f047bf015b829b(const ttstr & name , tTJSVariant * result = NULL , bool isexpression = false , const tjs_char * modestr = NULL)\n{\n\treturn TVPExecuteStorage(name, result, isexpression, modestr);\n}\nstatic void __stdcall TVP_Stub_0ff502d492598d2211405180bfb4d1e1(const ttstr & name , iTJSDispatch2 * context , tTJSVariant * result = NULL , bool isexpression = false , const tjs_char * modestr = NULL)\n{\n\treturn TVPExecuteStorage(name, context, result, isexpression, modestr);\n}\nstatic void __stdcall TVP_Stub_cf5401746759bfe38918087aaab6c57b()\n{\n\treturn TVPDumpScriptEngine();\n}\nstatic void __stdcall TVP_Stub_04e84aa7d8cf0477d55c700164544b38(const tjs_uint8 * content , size_t len , iTJSDispatch2 * context , tTJSVariant * result = NULL , const tjs_char * name = NULL)\n{\n\treturn TVPExecuteBytecode(content, len, context, result, name);\n}\nstatic void __stdcall TVP_Stub_449039d3afbfbd52a63130a3b227a490(const ttstr & filename)\n{\n\treturn TVPCreateMessageMapFile(filename);\n}\n#include \"StorageImpl.h\"\nstatic bool __stdcall TVP_Stub_347a4fa85af84e223c4b61d33ead694a(const ttstr & name)\n{\n\treturn TVPCheckExistentLocalFolder(name);\n}\nstatic bool __stdcall TVP_Stub_4ad1dd24b3b4769ee10149eea006af7a(const ttstr & name)\n{\n\treturn TVPCheckExistentLocalFile(name);\n}\nstatic bool __stdcall TVP_Stub_b246b17b62d273bdc04e9d9e827f5c74(const ttstr & folder)\n{\n\treturn TVPCreateFolders(folder);\n}\nstatic IStream * __stdcall TVP_Stub_9974ebc6296f925cff55d8bcb2d52ce9(const ttstr & name , tjs_uint32 flags)\n{\n\treturn TVPCreateIStream(name, flags);\n}\nstatic tTJSBinaryStream * __stdcall TVP_Stub_0e0c9d9107d8c56b8bc4d4198ae9208a(IStream * refstream)\n{\n\treturn TVPCreateBinaryStreamAdapter(refstream);\n}\n#include \"PluginImpl.h\"\nstatic void __stdcall TVP_Stub_c23ece207f6ec2dd7c76ef873047aee3(const char * funcname)\n{\n\treturn TVPThrowPluginUnboundFunctionError(funcname);\n}\nstatic void __stdcall TVP_Stub_81507020bc646be2f53ab95b9430ba27(const tjs_char * funcname)\n{\n\treturn TVPThrowPluginUnboundFunctionError(funcname);\n}\nstatic void * __stdcall TVP_Stub_acc0d3861d1b971abcbdda1c075dd681(size_t size)\n{\n\treturn TVP_malloc(size);\n}\nstatic void * __stdcall TVP_Stub_ff2dccead1b31e3f34e8be3e2ba5bbf1(void * pp , size_t size)\n{\n\treturn TVP_realloc(pp, size);\n}\nstatic void __stdcall TVP_Stub_e17db0d4f69625c61aba7fffe540dded(void * pp)\n{\n\treturn TVP_free(pp);\n}\nstatic tjs_int __stdcall TVP_Stub_5bbc872e7bba5b761c509d31116e4460()\n{\n\treturn TVPGetAutoLoadPluginCount();\n}\nstatic int __stdcall TVP_Stub_4adf361303eae78829250c7b732a5722(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen)\n{\n\treturn ZLIB_uncompress(dest, destlen, source, sourcelen);\n}\nstatic int __stdcall TVP_Stub_bf172364c57c1aa561b145fd5cacda0c(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen)\n{\n\treturn ZLIB_compress(dest, destlen, source, sourcelen);\n}\nstatic int __stdcall TVP_Stub_d7687aa80dac10f88deac7aa7e70538a(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen , int level)\n{\n\treturn ZLIB_compress2(dest, destlen, source, sourcelen, level);\n}\nstatic void __stdcall TVP_Stub_b18b7259f98029f745c75291d6855ab1(TVP_md5_state_t * pms)\n{\n\treturn TVP_md5_init(pms);\n}\nstatic void __stdcall TVP_Stub_b79e5d877116025576ca1f76af124009(TVP_md5_state_t * pms , const tjs_uint8 * data , int nbytes)\n{\n\treturn TVP_md5_append(pms, data, nbytes);\n}\nstatic void __stdcall TVP_Stub_8aea098dfe8a36c705cc2a9e1a189b84(TVP_md5_state_t * pms , tjs_uint8 * digest)\n{\n\treturn TVP_md5_finish(pms, digest);\n}\nstatic HWND __stdcall TVP_Stub_4ccd3f6ab60d61be6dbfc59e8e3d1726()\n{\n\treturn TVPGetApplicationWindowHandle();\n}\nstatic void __stdcall TVP_Stub_3d70bb72a7d7765c7e8ea580079ab7e9()\n{\n\treturn TVPProcessApplicationMessages();\n}\nstatic void __stdcall TVP_Stub_eba9b272d78a4b0cd7f9212e29a58607()\n{\n\treturn TVPHandleApplicationMessage();\n}\nstatic bool __stdcall TVP_Stub_cfbe8ee9d43aa64ae4190eac91f7c55f(const tjs_char * name , iTJSDispatch2 * dsp)\n{\n\treturn TVPRegisterGlobalObject(name, dsp);\n}\nstatic bool __stdcall TVP_Stub_a4308a386968ef5d23025ab8a9e8c6db(const tjs_char * name)\n{\n\treturn TVPRemoveGlobalObject(name);\n}\nstatic void __stdcall TVP_Stub_5a4fcbe1e398e3d9690d571acbbbae9f(tTVPTryBlockFunction tryblock , tTVPCatchBlockFunction catchblock , tTVPFinallyBlockFunction finallyblock , void * data)\n{\n\treturn TVPDoTryBlock(tryblock, catchblock, finallyblock, data);\n}\nstatic bool __stdcall TVP_Stub_5b62f504fe6d22428d7518d6c52d775d(const wchar_t * module_filename , tjs_int & major , tjs_int & minor , tjs_int & release , tjs_int & build)\n{\n\treturn TVPGetFileVersionOf(module_filename, major, minor, release, build);\n}\n#include \"SysInitIntf.h\"\nstatic bool __stdcall TVP_Stub_fb3b405f8747b54f26c332b9e6af81cd(const tjs_char * name , tTJSVariant * value = NULL)\n{\n\treturn TVPGetCommandLine(name, value);\n}\nstatic tjs_int __stdcall TVP_Stub_b7ccd11d130f186883c109d2ba17b598()\n{\n\treturn TVPGetCommandLineArgumentGeneration();\n}\nstatic void __stdcall TVP_Stub_cf8ab6c24f25993ccc7663e572ac2991(const tjs_char * name , const ttstr & value)\n{\n\treturn TVPSetCommandLine(name, value);\n}\n#include \"SysInitImpl.h\"\n#include \"DetectCPU.h\"\nstatic tjs_uint32 __stdcall TVP_Stub_ba40ffbca76695b54a02aa8c1f1e047b()\n{\n\treturn TVPGetCPUType();\n}\n#include \"ThreadIntf.h\"\nstatic tjs_int __stdcall TVP_Stub_c97720e639e95ba5130ce9dd78d30403()\n{\n\treturn TVPGetProcessorNum();\n}\nstatic tjs_int __stdcall TVP_Stub_c5557ac5391b1b831a22e64b65d1746c()\n{\n\treturn TVPGetThreadNum();\n}\nstatic void __stdcall TVP_Stub_3243a4c32d4f674f1bbc8d3895257568(tjs_int num)\n{\n\treturn TVPBeginThreadTask(num);\n}\nstatic void __stdcall TVP_Stub_78390a3d08879903ee9558e9df68db4d(TVP_THREAD_TASK_FUNC func , TVP_THREAD_PARAM param)\n{\n\treturn TVPExecThreadTask(func, param);\n}\nstatic void __stdcall TVP_Stub_58e9454d7096a52808f9a83b9ce25ff0()\n{\n\treturn TVPEndThreadTask();\n}\n#include \"DebugIntf.h\"\nstatic void __stdcall TVP_Stub_cdefadd0c3bf15b4639b2f0338a40585(const ttstr & line)\n{\n\treturn TVPAddLog(line);\n}\nstatic void __stdcall TVP_Stub_4bf80e9bac16b9e3f9bf385b2fbce657(const ttstr & line)\n{\n\treturn TVPAddImportantLog(line);\n}\n#include \"Random.h\"\nstatic void __stdcall TVP_Stub_51aeacf2b6ef9deb01c3b3db201d6bf9(const void * buf , tjs_int bufsize)\n{\n\treturn TVPPushEnvironNoise(buf, bufsize);\n}\nstatic void __stdcall TVP_Stub_9ed5432d73448da47991df9577ee97bc(void * dest)\n{\n\treturn TVPGetRandomBits128(dest);\n}\n#include \"ClipboardIntf.h\"\nstatic bool __stdcall TVP_Stub_cf1d02d1cc1aff0aae6c038c95dac80f(tTVPClipboardFormat format)\n{\n\treturn TVPClipboardHasFormat(format);\n}\nstatic void __stdcall TVP_Stub_ddb0e05c72c0692e78af885ac7ec82dc(const ttstr & text)\n{\n\treturn TVPClipboardSetText(text);\n}\nstatic bool __stdcall TVP_Stub_a3029db6292616cd16c228b91dc4af13(ttstr & text)\n{\n\treturn TVPClipboardGetText(text);\n}\n#include \"TickCount.h\"\nstatic tjs_uint64 __stdcall TVP_Stub_2d90871c6bc15a9e8d97d24c29e78e3b()\n{\n\treturn TVPGetTickCount();\n}\n#include \"MsgIntf.h\"\nstatic ttstr __stdcall TVP_Stub_0af6744e35e38276d6a98c1f382b1519(const tjs_char * msg , const ttstr & p1)\n{\n\treturn TVPFormatMessage(msg, p1);\n}\nstatic ttstr __stdcall TVP_Stub_ad40567a051208757642e5e087f3e741(const tjs_char * msg , const ttstr & p1 , const ttstr & p2)\n{\n\treturn TVPFormatMessage(msg, p1, p2);\n}\nstatic void __stdcall TVP_Stub_6a15185daab9b274963fe5ef46305775(const tjs_char * msg)\n{\n\treturn TVPThrowExceptionMessage(msg);\n}\nstatic void __stdcall TVP_Stub_073a2332a8ab3ed31ab81daea3d3f2c4(const tjs_char * msg , const ttstr & p1 , tjs_int num)\n{\n\treturn TVPThrowExceptionMessage(msg, p1, num);\n}\nstatic void __stdcall TVP_Stub_01216e91225e06c7422bef0c2febc0cc(const tjs_char * msg , const ttstr & p1)\n{\n\treturn TVPThrowExceptionMessage(msg, p1);\n}\nstatic void __stdcall TVP_Stub_16ce22ad500a5bdfd5d5743c847a28b6(const tjs_char * msg , const ttstr & p1 , const ttstr & p2)\n{\n\treturn TVPThrowExceptionMessage(msg, p1, p2);\n}\nstatic ttstr __stdcall TVP_Stub_59251c4104f736fa2690c5f77fb0a908()\n{\n\treturn TVPGetAboutString();\n}\nstatic ttstr __stdcall TVP_Stub_f923750e0fdb51a6fc6c304832cb3dd3()\n{\n\treturn TVPGetVersionInformation();\n}\nstatic ttstr __stdcall TVP_Stub_bc77a1e312ff7827d90387fb92f0f5b0()\n{\n\treturn TVPGetVersionString();\n}\nstatic void __stdcall TVP_Stub_2090afd7ae8bcb021ec4d04947d0d845(tjs_int & major , tjs_int & minor , tjs_int & release , tjs_int & build)\n{\n\treturn TVPGetSystemVersion(major, minor, release, build);\n}\nstatic void __stdcall TVP_Stub_3a0f858bdf86199dc2d00b583a3b915f(tjs_int & major , tjs_int & minor , tjs_int & release)\n{\n\treturn TVPGetTJSVersion(major, minor, release);\n}\n#include \"WaveIntf.h\"\nstatic void __stdcall TVP_Stub_0d316a141f7a502ff8d9ffe2d38d25a8(tjs_int16 * output , const void * input , const tTVPWaveFormat & format , tjs_int count , bool downmix)\n{\n\treturn TVPConvertPCMTo16bits(output, input, format, count, downmix);\n}\nstatic void __stdcall TVP_Stub_b31ff64ae2d8f93dbf28161d5080b295(tjs_int16 * output , const void * input , tjs_int channels , tjs_int bytespersample , tjs_int bitspersample , bool isfloat , tjs_int count , bool downmix)\n{\n\treturn TVPConvertPCMTo16bits(output, input, channels, bytespersample, bitspersample, isfloat, count, downmix);\n}\nstatic void __stdcall TVP_Stub_d9b1c73516daea6a9c6564e2b731615a(float * output , const void * input , tjs_int channels , tjs_int bytespersample , tjs_int bitspersample , bool isfloat , tjs_int count)\n{\n\treturn TVPConvertPCMToFloat(output, input, channels, bytespersample, bitspersample, isfloat, count);\n}\nstatic void __stdcall TVP_Stub_003f9d3de568fcd71dd532f33d38839c(float * output , const void * input , const tTVPWaveFormat & format , tjs_int count)\n{\n\treturn TVPConvertPCMToFloat(output, input, format, count);\n}\n#include \"WaveImpl.h\"\nstatic void __stdcall TVP_Stub_5da29a19bbe279a89be00e16c59d7641()\n{\n\treturn TVPReleaseDirectSound();\n}\nstatic IDirectSound * __stdcall TVP_Stub_c1b52e8f3578d11f369552a887e13c5b()\n{\n\treturn TVPGetDirectSound();\n}\n#include \"GraphicsLoaderIntf.h\"\nstatic void __stdcall TVP_Stub_b94ead6de9316bc65758c5aefb564078(const ttstr & name , tTVPGraphicLoadingHandlerForPlugin loading , tTVPGraphicHeaderLoadingHandlerForPlugin header , tTVPGraphicSaveHandlerForPlugin save , tTVPGraphicAcceptSaveHandler accept , void * formatdata)\n{\n\treturn TVPRegisterGraphicLoadingHandler(name, loading, header, save, accept, formatdata);\n}\nstatic void __stdcall TVP_Stub_8a35be936d2aca049e398a081e511c97(const ttstr & name , tTVPGraphicLoadingHandlerForPlugin loading , tTVPGraphicHeaderLoadingHandlerForPlugin header , tTVPGraphicSaveHandlerForPlugin save , tTVPGraphicAcceptSaveHandler accept , void * formatdata)\n{\n\treturn TVPUnregisterGraphicLoadingHandler(name, loading, header, save, accept, formatdata);\n}\nstatic void __stdcall TVP_Stub_5b1fa785e397e643dd09cb43c2f2f4db()\n{\n\treturn TVPClearGraphicCache();\n}\n#include \"tvpfontstruc.h\"\n#include \"tvpinputdefs.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"drawable.h\"\n#include \"ComplexRect.h\"\n#include \"LayerIntf.h\"\nstatic tjs_uint32 __stdcall TVP_Stub_29af78765c764c566e6adc77e0ea7041(tjs_uint32 col)\n{\n\treturn TVPToActualColor(col);\n}\nstatic tjs_uint32 __stdcall TVP_Stub_9e0df54e4c24ee28d5517c1743faa3a3(tjs_uint32 col)\n{\n\treturn TVPFromActualColor(col);\n}\nstatic iTJSDispatch2 * __stdcall TVP_Stub_d3aaa55d66777d7308ffa7a348c84841(tTJSNI_BaseLayer * layer)\n{\n\treturn TVPGetObjectFrom_NI_BaseLayer(layer);\n}\n#include \"LayerManager.h\"\n#include \"WindowIntf.h\"\n#include \"WindowImpl.h\"\nstatic tjs_uint32 __stdcall TVP_Stub_b426fbfb6ccb4e89c252b6af566995b8()\n{\n\treturn TVPGetCurrentShiftKeyState();\n}\nstatic void __stdcall TVP_Stub_c145419db7b63f7488ea05a2a8826c1d(HWND hWnd , char virt , short key , short cmd)\n{\n\treturn TVPRegisterAcceleratorKey(hWnd, virt, key, cmd);\n}\nstatic void __stdcall TVP_Stub_d795cd5ebfb6ca6f1b91bafbe66d7a65(HWND hWnd , short cmd)\n{\n\treturn TVPUnregisterAcceleratorKey(hWnd, cmd);\n}\nstatic void __stdcall TVP_Stub_4564a3ce5cf48cb47e63a3948cef03be(HWND hWnd)\n{\n\treturn TVPDeleteAcceleratorKeyTable(hWnd);\n}\nstatic void __stdcall TVP_Stub_bee2775f2e4042043b7cb08056d2ae5c()\n{\n\treturn TVPEnsureDirect3DObject();\n}\nstatic IDirect3D9 * __stdcall TVP_Stub_5fd8dfd2816a2cfd4a51cab41053d575()\n{\n\treturn TVPGetDirect3DObjectNoAddRef();\n}\n#include \"DrawDevice.h\"\n#include \"voMode.h\"\n#include \"VideoOvlIntf.h\"\n#include \"TransIntf.h\"\nstatic iTVPScanLineProvider * __stdcall TVP_Stub_9982ebedc12d343cb098e2a7b25bdef1(const ttstr & name , tjs_int bpp , tjs_uint32 key , tjs_uint w , tjs_uint h)\n{\n\treturn TVPSLPLoadImage(name, bpp, key, w, h);\n}\nstatic void __stdcall TVP_Stub_81eeacbed5ee6129bef4b370e28b5d10(iTVPTransHandlerProvider * pro)\n{\n\treturn TVPAddTransHandlerProvider(pro);\n}\nstatic void __stdcall TVP_Stub_6ed1088905d99012d2fb5827ea19527e(iTVPTransHandlerProvider * pro)\n{\n\treturn TVPRemoveTransHandlerProvider(pro);\n}\n#include \"transhandler.h\"\n#include \"tvpgl.h\"\nstatic void __stdcall TVP_Stub_b4d6c64cc0004ffaba804f0e8f02ab9b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAlphaBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_2c3e08b8df93ec50451edd916c707030(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAlphaBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_eba070d1583ca5f5d02630ba33a5504b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAlphaBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_ee474537852ce5eb165cb1761950faba(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAlphaBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_eed221c603243522667e2f1c6ace3ba4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAlphaBlend_d(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_1f973c5e3cfaf00fa752b7e22d7ba481(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAlphaBlend_a(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_b9d5260bba9edd7503f1adf882218979(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAlphaBlend_do(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_aedbd2eda61145de808e295331884245(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAlphaBlend_ao(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_ce0f184e84752eb279e4f900d8b53c18(tjs_uint32 * dest , const tjs_uint32 color , tjs_int len)\n{\n\treturn TVPAlphaColorMat(dest, color, len);\n}\nstatic void __stdcall TVP_Stub_0217d49393163b80897d044c1d93092f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAdditiveAlphaBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_5bbd9d5b364840e9615af35a62f69d7d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAdditiveAlphaBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_2b2837e81fcaeec35f61a2a3ecf2fb2d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAdditiveAlphaBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_bb0706a78e9066944bfbffd1406be2d4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAdditiveAlphaBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_770e67c91215292980b88cc6efb9f2a5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAdditiveAlphaBlend_a(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_068ab11f05731f2c2e9ea8c5fdb16a9f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAdditiveAlphaBlend_ao(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_b9873a0ad2653952cb2948b817e786e4(tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPConvertAdditiveAlphaToAlpha(buf, len);\n}\nstatic void __stdcall TVP_Stub_11d9804ae4db32d731af69c397769cbf(tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPConvertAlphaToAdditiveAlpha(buf, len);\n}\nstatic void __stdcall TVP_Stub_421f5aa6dbaaaf946f74942c77aac9bc(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAlphaBlend(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_563ee9dcb14a2914fc246e64679f42b5(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAlphaBlend_HDA(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_e23a54b6b80bd03111a40f669524724f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAlphaBlend_o(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_c90c8bbd18a7190636ae4269c36ad005(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAlphaBlend_HDA_o(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_03c54a8e8c86e171f868a624e490691f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAlphaBlend_d(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_30b63f3cc59b39f1a71829bbbdf6e45d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAlphaBlend_a(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_705bcc30a0561ec679c2267e1a573b23(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAlphaBlend_do(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_5c627d080007e455b0393a9b4457cd4d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAlphaBlend_ao(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_72a64cecd44d80f95fc93faf0d239e32(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAdditiveAlphaBlend(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_ef838904712bfdc614dbc689fbe7fb18(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPInterpStretchAdditiveAlphaBlend(dest, destlen, src1, src2, blend_y, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_acc97936adc40656e824cfdf7a34e20c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAdditiveAlphaBlend_HDA(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_5ea1ba3602f9d9fee344de6c3406d7a3(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAdditiveAlphaBlend_o(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_d25f0771b8fc7715d69f01d950463a49(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPInterpStretchAdditiveAlphaBlend_o(dest, destlen, src1, src2, blend_y, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_f8ab11c930782ce058e517d0440ec87f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAdditiveAlphaBlend_HDA_o(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_b8157e369d53c2d944b76494980ced7b(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchAdditiveAlphaBlend_a(dest, len, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_aba94f656b4c1de827d11c72b36a5e9c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchAdditiveAlphaBlend_ao(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_0656942f5a95783a4de73ca6e654d3b5(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_5c2b7d12713dd5a94ef8e6eff1f79752(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_6f1d30ac7e812cc5a059459c47638cd0(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAlphaBlend_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_1d51684322635e7848ef53f7f6be8a1e(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAlphaBlend_HDA_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_a1f2d56d138a4038fe1678328910a81d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAlphaBlend_d(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_c135ef491b533febfd49696d22a1dd3d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_579117a873b466d78bf93e49c4a078da(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAlphaBlend_do(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_ec8fa08705639eb7ae5d44ab63dea5e8(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAlphaBlend_ao(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_b49dc1cda6109256815dae7b4293725d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAdditiveAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_912a670f56707ac70f2fee13660c2af8(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPInterpLinTransAdditiveAlphaBlend(dest, destlen, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_d0159986645df76b8c66fdb662efffde(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAdditiveAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_cd7a2e6f91bf8d2daa3e28139d7d9f5c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAdditiveAlphaBlend_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_676004ca892b2bfee6859d0bb132fdd7(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPInterpLinTransAdditiveAlphaBlend_o(dest, destlen, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_d4b161d8a745baa5e2113669773a758f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAdditiveAlphaBlend_HDA_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_ef7537293f6e3b6127480f6c5fd018a1(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransAdditiveAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_6f6f73b75cffe40a28566d1832ae1224(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransAdditiveAlphaBlend_ao(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_7adc5aad39e459e01543d07c239efe57(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPCopyOpaqueImage(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_3ff6b480097eec3f5fdb7bfad685fd2a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_b2c50c3a1dfea7e9d05fed69818bafc3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_HDA(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_8024df9077e2c85b5b718ad2c87e57e7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_d(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_989769d4eb8e42e9c9bbe721b296406c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_a(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_cc1ac928b5c31570dfba7ed8f565be4b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchCopyOpaqueImage(dest, destlen, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_62931efed5729a332e60bd1f7c7cecdf(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchConstAlphaBlend(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_53c18160b157088f72a9afd79737b48b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPInterpStretchConstAlphaBlend(dest, destlen, src1, src2, blend_y, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_48135697fd7f4df87402a7dd4d761555(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchConstAlphaBlend_HDA(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_e2c71cf04e876069eb7315c800a96898(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchConstAlphaBlend_d(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_1f63c018cf805ca1168af192cf8a4b41(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa)\n{\n\treturn TVPStretchConstAlphaBlend_a(dest, len, src, srcstart, srcstep, opa);\n}\nstatic void __stdcall TVP_Stub_704a9574dafd3669e10d546549948e03(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransCopyOpaqueImage(dest, destlen, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_97905c510b9502c20c9322c9f5fb4188(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransConstAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_b23e84230c4736667279c7a71f4ca53e(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPInterpLinTransConstAlphaBlend(dest, destlen, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_eb41fc900b0a6e3aba9d531f266137f1(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransConstAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_5bd02c627b74bbb22d5a525b8bcbbd27(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransConstAlphaBlend_d(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_cc82e6a6b31ea743b9ebbdeed1ddedc3(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa)\n{\n\treturn TVPLinTransConstAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void __stdcall TVP_Stub_247b25d497e48bc0191fdb2ac530f4ca(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_SD(dest, src1, src2, len, opa);\n}\nstatic void __stdcall TVP_Stub_6bbea3af36c35631641cc8356ff65475(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_SD_a(dest, src1, src2, len, opa);\n}\nstatic void __stdcall TVP_Stub_cac02dfd62ba94abf6a346bef0bf3ab9(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa)\n{\n\treturn TVPConstAlphaBlend_SD_d(dest, src1, src2, len, opa);\n}\nstatic void __stdcall TVP_Stub_68eeb36d76d88ff00014f04b23454254(tjs_uint32 * table , tjs_int phase , tjs_int vague)\n{\n\treturn TVPInitUnivTransBlendTable(table, phase, vague);\n}\nstatic void __stdcall TVP_Stub_65e03b1c849b6e9cb5c478024aa9a5b7(tjs_uint32 * table , tjs_int phase , tjs_int vague)\n{\n\treturn TVPInitUnivTransBlendTable_d(table, phase, vague);\n}\nstatic void __stdcall TVP_Stub_7670c0c5630625ee6a73b7b9ee093650(tjs_uint32 * table , tjs_int phase , tjs_int vague)\n{\n\treturn TVPInitUnivTransBlendTable_a(table, phase, vague);\n}\nstatic void __stdcall TVP_Stub_68a0abce6eefa08e74353ec48c4c87a8(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len)\n{\n\treturn TVPUnivTransBlend(dest, src1, src2, rule, table, len);\n}\nstatic void __stdcall TVP_Stub_ccb6e098b9a0791a0f20e9f1af55e341(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv)\n{\n\treturn TVPUnivTransBlend_switch(dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\nstatic void __stdcall TVP_Stub_0f817efe47b451fd719c05a104c2b803(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len)\n{\n\treturn TVPUnivTransBlend_d(dest, src1, src2, rule, table, len);\n}\nstatic void __stdcall TVP_Stub_efad1a3d774747bd2b5adb221ede2678(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv)\n{\n\treturn TVPUnivTransBlend_switch_d(dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\nstatic void __stdcall TVP_Stub_563285ed004ddd2945f91db7b5347d3c(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len)\n{\n\treturn TVPUnivTransBlend_a(dest, src1, src2, rule, table, len);\n}\nstatic void __stdcall TVP_Stub_4c032260ef83d44bfe05fdc16843a8f9(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv)\n{\n\treturn TVPUnivTransBlend_switch_a(dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\nstatic void __stdcall TVP_Stub_96fd614457f06499a430b0c6e0e8a941(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_d6e36d304ff7253088ab4bc1aaf13a98(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap_o(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_eddacf49735189e23d9d49831851ffdb(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap65(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_20275a5de4aef464b85d3f6db2800063(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap65_o(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_872d1c626e6d4e3d5e86a257f0b14536(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap_HDA(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_a7ebb70cdec339f26c2ea7fd9a471b88(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap_HDA_o(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_d748ffef5cde2a6a3333e75b7fa3fb49(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap65_HDA(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_15e1fe0e6230e7b60e216e266f927f7b(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap65_HDA_o(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_f8179eafd0cbe8116874310519207dc0(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap_d(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_accbc3bed3223d552de2723366cfc2b6(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap65_d(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_e2c3e74d2a20a601c1f393348f58aeb2(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap_a(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_e0163a6ca3397c2e71715132cccefa1d(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPApplyColorMap65_a(dest, src, len, color);\n}\nstatic void __stdcall TVP_Stub_2c3ea1ea88799dfde81025bf1959333a(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap_do(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_a6bb56b3f4b7a89fe78d63956a0f444c(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap65_do(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_09a81ac18a121d8fbb67285a081bf9c6(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap_ao(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_46fdfe0f5369bf234c3ed60a43947d9d(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPApplyColorMap65_ao(dest, src, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_d866cb6c8a47444bbac60eeffbfc6d96(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPConstColorAlphaBlend(dest, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_7b5718fc67458089c685dbb900126890(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPConstColorAlphaBlend_d(dest, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_5713dfe9525662357d3819229e0204c2(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa)\n{\n\treturn TVPConstColorAlphaBlend_a(dest, len, color, opa);\n}\nstatic void __stdcall TVP_Stub_8954a6b4a7f8b378c2af16a00d5059b0(tjs_uint32 * dest , tjs_int len , tjs_int strength)\n{\n\treturn TVPRemoveConstOpacity(dest, len, strength);\n}\nstatic void __stdcall TVP_Stub_2ed4faa38db6f3dee0dea18ebe973d35(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len)\n{\n\treturn TVPRemoveOpacity(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_d0338dedb0af532d22f2075a85373548(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_int strength)\n{\n\treturn TVPRemoveOpacity_o(dest, src, len, strength);\n}\nstatic void __stdcall TVP_Stub_583d57c3bb9491f8f9904c266d3f52e8(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len)\n{\n\treturn TVPRemoveOpacity65(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_8ac206da43e322eb8e34fce2b0959656(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_int strength)\n{\n\treturn TVPRemoveOpacity65_o(dest, src, len, strength);\n}\nstatic void __stdcall TVP_Stub_14f5f97d90bd8da89b68d035367f4ba4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAddBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_ac3b21181ef4c1be73cf5e0edb4e1a8f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPAddBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_1d7d97509292a4ca9269f2539dcc70fd(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAddBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_c4033f54a99517783b8d6ad23c90aeed(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPAddBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_f19e38d48755c971fc35408ac65562fa(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPSubBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_e01204e226d8aa9520b3620b68da6196(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPSubBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_b50000da98f1257cf789fc63fb1fda02(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPSubBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_c55f38b1a7623646aa5cc45d4f4f479b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPSubBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_983d270549ec0e83e2a863b43e1e6f70(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPMulBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_b48d779dc6a881c67c5f8fa12655aa28(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPMulBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_d3967c6e24d0c4ad107a03c1cadd57b1(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPMulBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_6b6f416b5725a7cafb4774ffc3a00f10(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPMulBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_bc7fc5dfa228152a09d2230823c2fe71(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPColorDodgeBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_a1cb941317b947beb88e29fa8d46a2be(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPColorDodgeBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_8e185e82bb27a7fb40f0b08f560a57e9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPColorDodgeBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_4b7b264b61ee0eea68213934217f5865(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPColorDodgeBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_e872f12593d6853ebdffebbb5d003c10(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPDarkenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_e86fcf60fa658129d937de3728d3c432(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPDarkenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_350741a7398a187628866f5b397c7a99(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPDarkenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_3b5a3e187077b0b5eac9a040c99dd9e7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPDarkenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_2d9b2bb2cd57220048fe170f1e960cb7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPLightenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_260624e275a20115e8861eb7b0383971(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPLightenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_15b31724287dbbecb775b2e46dc35fb9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPLightenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_ff652293eef07b5a7ec4f372e5504e2c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPLightenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_99b773033e9a2c631b483d4d0e3881f8(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPScreenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_3787960fc29b8545629d894ff46d4641(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPScreenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_3fc76257bb1639de4bfa0c0fcedf9c4a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPScreenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_292ee2eeb8131e34368ba9ee144b737a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPScreenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_ec144655bc61bfa2c6e9505cc1a0a298(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchCopy(dest, destlen, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_230218bdabfc34178a8306a54276a3c8(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPInterpStretchCopy(dest, destlen, src1, src2, blend_y, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_617dfb046aaf40078ee76715fa4756af(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src)\n{\n\treturn TVPFastLinearInterpH2F(dest, destlen, src);\n}\nstatic void __stdcall TVP_Stub_8116bb2b26dcafd9fefca76e9f1d9b24(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src)\n{\n\treturn TVPFastLinearInterpH2B(dest, destlen, src);\n}\nstatic void __stdcall TVP_Stub_12962f857563cd39b3cb1f9894775cc7(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src0 , const tjs_uint32 * src1)\n{\n\treturn TVPFastLinearInterpV2(dest, destlen, src0, src1);\n}\nstatic void __stdcall TVP_Stub_50c0d25cd9af311a5fb0aca78f691c3b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep)\n{\n\treturn TVPStretchColorCopy(dest, destlen, src, srcstart, srcstep);\n}\nstatic void __stdcall TVP_Stub_6c37a1ccda816c4fbab4f0117ca75e8a(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_e21c21762dd0e36d6f7d2cedaac97383(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPInterpLinTransCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_487ee86557f94113db9a981e08d29caa(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch)\n{\n\treturn TVPLinTransColorCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void __stdcall TVP_Stub_dfdfe0e494845bf484612cc97145f85c(tjs_uint32 * dest , tjs_int len , tjs_uint32 key)\n{\n\treturn TVPMakeAlphaFromKey(dest, len, key);\n}\nstatic void __stdcall TVP_Stub_e74dc11dbd56fb450eed1388a65d3102(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPCopyMask(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_6981c02247de5799ea7dfbd79fdc208d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPCopyColor(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_7c559043315f6ecd7a86ec7d8d820f6d(tjs_uint32 * main , const tjs_uint8 * mask , tjs_int len)\n{\n\treturn TVPBindMaskToMain(main, mask, len);\n}\nstatic void __stdcall TVP_Stub_3a8b6aca73c83d6fc9ce813661ec734d(tjs_uint32 * dest , tjs_int len , tjs_uint32 value)\n{\n\treturn TVPFillARGB(dest, len, value);\n}\nstatic void __stdcall TVP_Stub_20d7ce65e240b745b10616bb5da1f897(tjs_uint32 * dest , tjs_int len , tjs_uint32 value)\n{\n\treturn TVPFillARGB_NC(dest, len, value);\n}\nstatic void __stdcall TVP_Stub_f4d1217249674ac9274d358c381afc0b(tjs_uint32 * dest , tjs_int len , tjs_uint32 color)\n{\n\treturn TVPFillColor(dest, len, color);\n}\nstatic void __stdcall TVP_Stub_ca77323bbe361f88f68536018fa94c50(tjs_uint32 * dest , tjs_int len , tjs_uint32 mask)\n{\n\treturn TVPFillMask(dest, len, mask);\n}\nstatic void __stdcall TVP_Stub_17983ecc7e7fe370bce664281a84c948(tjs_uint16 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len)\n{\n\treturn TVPAddSubVertSum16(dest, addline, subline, len);\n}\nstatic void __stdcall TVP_Stub_61a2f61030362903d00ba21a3cebecdd(tjs_uint16 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len)\n{\n\treturn TVPAddSubVertSum16_d(dest, addline, subline, len);\n}\nstatic void __stdcall TVP_Stub_e9f985403dbd18540d8230a2af6ed76b(tjs_uint32 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len)\n{\n\treturn TVPAddSubVertSum32(dest, addline, subline, len);\n}\nstatic void __stdcall TVP_Stub_be0523c9a72ba26cb4bfa3cb188cacf6(tjs_uint32 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len)\n{\n\treturn TVPAddSubVertSum32_d(dest, addline, subline, len);\n}\nstatic void __stdcall TVP_Stub_8ac7cf651223c8ba53df90cf4f3d3bbc(tjs_uint32 * dest , tjs_uint16 * sum , const tjs_uint16 * add , const tjs_uint16 * sub , tjs_int n , tjs_int len)\n{\n\treturn TVPDoBoxBlurAvg16(dest, sum, add, sub, n, len);\n}\nstatic void __stdcall TVP_Stub_873e73aa35096ad4c684d394a10135a6(tjs_uint32 * dest , tjs_uint16 * sum , const tjs_uint16 * add , const tjs_uint16 * sub , tjs_int n , tjs_int len)\n{\n\treturn TVPDoBoxBlurAvg16_d(dest, sum, add, sub, n, len);\n}\nstatic void __stdcall TVP_Stub_3342548f105147c86019ae31ece01d4e(tjs_uint32 * dest , tjs_uint32 * sum , const tjs_uint32 * add , const tjs_uint32 * sub , tjs_int n , tjs_int len)\n{\n\treturn TVPDoBoxBlurAvg32(dest, sum, add, sub, n, len);\n}\nstatic void __stdcall TVP_Stub_607ee0956cbb16b2afb7cb2227aa6267(tjs_uint32 * dest , tjs_uint32 * sum , const tjs_uint32 * add , const tjs_uint32 * sub , tjs_int n , tjs_int len)\n{\n\treturn TVPDoBoxBlurAvg32_d(dest, sum, add, sub, n, len);\n}\nstatic void __stdcall TVP_Stub_816d84c86e86d5e7c0018d551e741e4f(tjs_uint8 * line1 , tjs_uint8 * line2 , tjs_int len)\n{\n\treturn TVPSwapLine8(line1, line2, len);\n}\nstatic void __stdcall TVP_Stub_985fcda0141eb3b4c6bd8342e947f130(tjs_uint32 * line1 , tjs_uint32 * line2 , tjs_int len)\n{\n\treturn TVPSwapLine32(line1, line2, len);\n}\nstatic void __stdcall TVP_Stub_d00e4f9e493334d2f65ea379ff03d717(tjs_uint8 * pixels , tjs_int len)\n{\n\treturn TVPReverse8(pixels, len);\n}\nstatic void __stdcall TVP_Stub_0c246e6c7c8798e4c10d2bbfc66326c9(tjs_uint32 * pixels , tjs_int len)\n{\n\treturn TVPReverse32(pixels, len);\n}\nstatic void __stdcall TVP_Stub_501015843a83368b3ff1c7c9ef5f3bcb(tjs_uint32 * dest , tjs_int len)\n{\n\treturn TVPDoGrayScale(dest, len);\n}\nstatic void __stdcall TVP_Stub_61d5fc5a060f346752a3a8b6886d17bc(tTVPGLGammaAdjustTempData * temp , const tTVPGLGammaAdjustData * data)\n{\n\treturn TVPInitGammaAdjustTempData(temp, data);\n}\nstatic void __stdcall TVP_Stub_0debe3e1caf0f57572a59917851676d3(tTVPGLGammaAdjustTempData * temp)\n{\n\treturn TVPUninitGammaAdjustTempData(temp);\n}\nstatic void __stdcall TVP_Stub_ee3a36682f48639166ba04a19fe1b332(tjs_uint32 * dest , tjs_int len , tTVPGLGammaAdjustTempData * temp)\n{\n\treturn TVPAdjustGamma(dest, len, temp);\n}\nstatic void __stdcall TVP_Stub_4d99b9e38121251b40a90cd2bd5fea63(tjs_uint32 * dest , tjs_int len , tTVPGLGammaAdjustTempData * temp)\n{\n\treturn TVPAdjustGamma_a(dest, len, temp);\n}\nstatic void __stdcall TVP_Stub_f1509827696ebf5627bee1a45d675fb8(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level)\n{\n\treturn TVPChBlurMulCopy65(dest, src, len, level);\n}\nstatic void __stdcall TVP_Stub_bbb625e23229350453161810c41419dd(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level)\n{\n\treturn TVPChBlurAddMulCopy65(dest, src, len, level);\n}\nstatic void __stdcall TVP_Stub_489a6aae30de0feff5d3c5fbd42ae325(tjs_uint8 * dest , tjs_int destpitch , tjs_int destwidth , tjs_int destheight , const tjs_uint8 * src , tjs_int srcpitch , tjs_int srcwidth , tjs_int srcheight , tjs_int blurwidth , tjs_int blurlevel)\n{\n\treturn TVPChBlurCopy65(dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel);\n}\nstatic void __stdcall TVP_Stub_6b9a349305f8c689dcfdbcea2566769c(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level)\n{\n\treturn TVPChBlurMulCopy(dest, src, len, level);\n}\nstatic void __stdcall TVP_Stub_6320d208ce1a570aca52c3cdf7421f7c(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level)\n{\n\treturn TVPChBlurAddMulCopy(dest, src, len, level);\n}\nstatic void __stdcall TVP_Stub_0f83f0459badd1cd352041b9243d712f(tjs_uint8 * dest , tjs_int destpitch , tjs_int destwidth , tjs_int destheight , const tjs_uint8 * src , tjs_int srcpitch , tjs_int srcwidth , tjs_int srcheight , tjs_int blurwidth , tjs_int blurlevel)\n{\n\treturn TVPChBlurCopy(dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel);\n}\nstatic void __stdcall TVP_Stub_186a94b2fed609ed2d2a7ac1a2bed87f(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand1BitTo8BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_bde8efb9971664f2b52fe912745e2791(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPBLExpand1BitTo8Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_386d6fa5cb73e3519b62d20470e5414b(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand1BitTo32BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_c61f97ec3d99bdbb23afe93870001bbf(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand4BitTo8BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_f92821f2b23662c6f1256511a626cd3f(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPBLExpand4BitTo8Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_76b0732e3e2886897d5f26b4b0545dee(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand4BitTo32BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_903ed11ef3863850e837bd4b3b1d61a1(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand8BitTo8BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_2661124b39595ffafe2fb0bfb7bd2efc(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal)\n{\n\treturn TVPBLExpand8BitTo32BitPal(dest, buf, len, pal);\n}\nstatic void __stdcall TVP_Stub_d0b7170e54398c2f9d27dcc513c4cf46(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPExpand8BitTo32BitGray(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_31bdd2a1eed3785c1422fab5ea6b3ce7(tjs_uint8 * dest , const tjs_uint16 * buf , tjs_int len)\n{\n\treturn TVPBLConvert15BitTo8Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_dbc300d1dadc1a60cb0dcadfb92f1aee(tjs_uint32 * dest , const tjs_uint16 * buf , tjs_int len)\n{\n\treturn TVPBLConvert15BitTo32Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_1d4d9f8bdf55bd4c78abd90656af0364(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPBLConvert24BitTo8Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_5c7049e712e84b40ac05942421202de5(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPBLConvert24BitTo32Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_5dca8992bb340d70ba65ddab65c28371(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len)\n{\n\treturn TVPConvert24BitTo32Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_85f1f38f783ebfcf638f3c443bc9b204(tjs_uint8 * dest , const tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPBLConvert32BitTo8Bit(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_7d61d143884bfa4b6c50dae11c2b659f(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPBLConvert32BitTo32Bit_NoneAlpha(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_793a2ad7ad3411be3670576a8e6ddcf8(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPBLConvert32BitTo32Bit_MulAddAlpha(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_68d8eec33254f1684e53bbc0aa8b2466(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len)\n{\n\treturn TVPBLConvert32BitTo32Bit_AddAlpha(dest, buf, len);\n}\nstatic void __stdcall TVP_Stub_b09652d2197b29f7d38aff0298c69f17(tjs_uint16 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs)\n{\n\treturn TVPDither32BitTo16Bit565(dest, src, len, xofs, yofs);\n}\nstatic void __stdcall TVP_Stub_be7db03ddcf1886cb7233e58f19c8c77(tjs_uint16 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs)\n{\n\treturn TVPDither32BitTo16Bit555(dest, src, len, xofs, yofs);\n}\nstatic void __stdcall TVP_Stub_b4c8fedc1ffbe30d9703cb2b8d3c0e7b(tjs_uint8 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs)\n{\n\treturn TVPDither32BitTo8Bit(dest, src, len, xofs, yofs);\n}\nstatic void __stdcall TVP_Stub_77efef3b4ffc0cb577b76304e06e39f3(tjs_uint8 * outp , const tjs_uint8 * upper , tjs_uint8 * const * buf , tjs_int width)\n{\n\treturn TVPTLG5ComposeColors3To4(outp, upper, buf, width);\n}\nstatic void __stdcall TVP_Stub_0e55187bde599d6585eaabd2c4ac3f02(tjs_uint8 * outp , const tjs_uint8 * upper , tjs_uint8 * const * buf , tjs_int width)\n{\n\treturn TVPTLG5ComposeColors4To4(outp, upper, buf, width);\n}\nstatic tjs_int __stdcall TVP_Stub_f72e3fc3b97a9141b6f516f5e53bf9b8(tjs_uint8 * out , const tjs_uint8 * in , tjs_int insize , tjs_uint8 * text , tjs_int initialr)\n{\n\treturn TVPTLG5DecompressSlide(out, in, insize, text, initialr);\n}\nstatic void __stdcall TVP_Stub_e7a1ac237f00bb6320d0e0ac7e6d51c6(tjs_int8 * pixelbuf , tjs_int pixel_count , tjs_uint8 * bit_pool)\n{\n\treturn TVPTLG6DecodeGolombValuesForFirst(pixelbuf, pixel_count, bit_pool);\n}\nstatic void __stdcall TVP_Stub_d87682f6d691350878077bd101b7f0fc(tjs_int8 * pixelbuf , tjs_int pixel_count , tjs_uint8 * bit_pool)\n{\n\treturn TVPTLG6DecodeGolombValues(pixelbuf, pixel_count, bit_pool);\n}\nstatic void __stdcall TVP_Stub_d7ae155eaabd8e65d6b4d356fe4af496(tjs_uint32 * prevline , tjs_uint32 * curline , tjs_int width , tjs_int start_block , tjs_int block_limit , tjs_uint8 * filtertypes , tjs_int skipblockbytes , tjs_uint32 * in , tjs_uint32 initialp , tjs_int oddskip , tjs_int dir)\n{\n\treturn TVPTLG6DecodeLineGeneric(prevline, curline, width, start_block, block_limit, filtertypes, skipblockbytes, in, initialp, oddskip, dir);\n}\nstatic void __stdcall TVP_Stub_be3a1844ea6af533bd4e7b0a76c826a1(tjs_uint32 * prevline , tjs_uint32 * curline , tjs_int width , tjs_int block_count , tjs_uint8 * filtertypes , tjs_int skipblockbytes , tjs_uint32 * in , tjs_uint32 initialp , tjs_int oddskip , tjs_int dir)\n{\n\treturn TVPTLG6DecodeLine(prevline, curline, width, block_count, filtertypes, skipblockbytes, in, initialp, oddskip, dir);\n}\nstatic void __stdcall TVP_Stub_aa531d2c3c87f456e48a14722faa1c1f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsAlphaBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_6889cd886e1c2e7faf541528636c16c3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsAlphaBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_5d9266e6a8a154fe4ba80b0995e109ab(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsAlphaBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_a7dc19b023737979ad1ae1ae01d560d2(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsAlphaBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_d20444b7a6243d668a0d3956d95af510(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsAddBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_1458dec9eee36816c8002d4049840355(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsAddBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_21137ff5351245b1611852301b7f5796(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsAddBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_c07fc4e45fc2dc44d839c5e012d0be60(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsAddBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_6815b962a3122ae967284239932cc656(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsSubBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_e96cccbe1f16b0fb74673f2ec3343ff8(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsSubBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_e8cd7494f919b18a992cb8c2722b2bf0(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsSubBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_990fdefcafc0de5e8e1f502c1b341e44(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsSubBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_de5d83ba307e822825062377fb76c2ba(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsMulBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_5e28bcc0f5ad6a038eb5a6535b56386c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsMulBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_e33419e8ede4bb501ab1787cf17c7ca5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsMulBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_1cd7cb9580c0cf723dea402b85a720b1(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsMulBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_d18ca17fad389ff60ce3caa769083798(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsScreenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_0a959a5ff02530a8eb122e7e1f8ceed3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsScreenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_a4774ea559e64b4667b3845f8540d207(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsScreenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_52eae3e8106494bfa604c15492ecb9f4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsScreenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_882f458df5e05bb9ab2222e79f6c81cf(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsOverlayBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_6069a18bf7d3f394c230cdcf2f574ef4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsOverlayBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_75b60565caf44027cc52b2b5cf6b0ea3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsOverlayBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_9d735149c3ad586363895f76645abf2e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsOverlayBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_ea5168fae254acdd8c8db6f1f3d2da03(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsHardLightBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_f5a42bd5239e1a0be29f92eb838d2c8c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsHardLightBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_7cc8cd9f415b183b42c546635aeade7f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsHardLightBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_ad2fefa53e05528f9c1fe29d27db0f37(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsHardLightBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_f3e06fed4c82a9bd1b53252abaf50847(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsSoftLightBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_960db7ea36202bf7ec3bf6b767cc045e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsSoftLightBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_7bf5d357eb52dd206a269b54c8136e0e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsSoftLightBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_ba1c9b771c5cdb725128de684af3c9ca(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsSoftLightBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_69cc6311196adc134fd153c4c5346bc5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorDodgeBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_8ed68f8e79efe1c767f92e7d92eb8b54(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorDodgeBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_60da1e9ec15b251ff18ddcdf8a3e93e0(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorDodgeBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_ef47304bad87a036e38f0319b48c1f6e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorDodgeBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_182d19020e4e2d5cd1462d7c8ef24d1f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorDodge5Blend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_9e1fa429a92a5c99d397a06c20fd6705(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorDodge5Blend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_74ac7c291299eb928aa4c2899df5567e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorDodge5Blend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_fb645d9ec0ef3fd2aba2b762ef6b9a15(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorDodge5Blend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_f988626275257574050ac789f9060a3b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorBurnBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_1831064ed23493cef407648763ba4d69(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorBurnBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_305390c94750daa7124db3ff6e77931c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsColorBurnBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_4fb384a391bfcf6a3a2932661d3051aa(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsColorBurnBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_305537c4820e23cf217a15efb56dba1c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsLightenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_aacf83677ca7df75117f7bafa7a53791(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsLightenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_d14b922fefc6c07aa536b94762579fe5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsLightenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_00fd650a79c603bdeb2f8e36f667a782(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsLightenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_a36ee133c07c30185b0bbc6375954e88(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDarkenBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_dc657ecacf8e578870314427216864d9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDarkenBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_e79d02b58a8bfdee439bc0694d7edd6d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDarkenBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_6b7537b66b71d27384bea45bc2bf24b4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDarkenBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_b3456dbad652b52f5bce1889b6f4d0ef(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDiffBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_9a50803a03e1ccb60120dff8b92ecdcd(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDiffBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_0f6b3940dc72e3e56cd15216b53b9126(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDiffBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_23b647f1c825e214a7465de3ebe9968d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDiffBlend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_8ec96bc7b777180f23e1a2e43bf9a413(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDiff5Blend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_cffd45014652659638d59abe11daf3be(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDiff5Blend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_a784285a35b1bc76bb367305b5099e35(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsDiff5Blend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_03773751329896facf2003ab79bbc475(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsDiff5Blend_HDA_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_923884216edf134d07d8e70f8f57e827(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsExclusionBlend(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_e48798dc69498f80b6633bb405eda6eb(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsExclusionBlend_o(dest, src, len, opa);\n}\nstatic void __stdcall TVP_Stub_998a5e1aa5cd85689795348fc540a655(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len)\n{\n\treturn TVPPsExclusionBlend_HDA(dest, src, len);\n}\nstatic void __stdcall TVP_Stub_5f6d263c0d48d03f6eb0dc44c9dd0be2(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa)\n{\n\treturn TVPPsExclusionBlend_HDA_o(dest, src, len, opa);\n}\n#include \"tvpgl_ia32_intf.h\"\n#include \"TVPVideoOverlay.h\"\nstatic void __stdcall TVP_Stub_bf363ba3d5b54df9d6df35a518deb6b0(const ttstr & name , void * guid , tTVPCreateDSFilter splitter , tTVPCreateDSFilter video , tTVPCreateDSFilter audio , void * formatdata)\n{\n\treturn TVPRegisterDSVideoCodec(name, guid, splitter, video, audio, formatdata);\n}\nstatic void __stdcall TVP_Stub_6cc8a24cc7ce23179d1d4ccab7a8c97b(const ttstr & name , void * guid , tTVPCreateDSFilter splitter , tTVPCreateDSFilter video , tTVPCreateDSFilter audio , void * formatdata)\n{\n\treturn TVPUnregisterDSVideoCodec(name, guid, splitter, video, audio, formatdata);\n}\n\n#include <zlib/zlib.h>\n/* function table is pretty large; is compressed via zlib */\nstatic tjs_uint8 compressed_functable[] = {\n0x78, 0x9c, 0xd5, 0x5d, 0x6b, 0x73, 0xdb, 0xba, 0xd1, 0xce, 0x4f, 0x49, 0x3f, 0x34, 0xa3, 0x93, \n0xe3, 0x4e, 0x27, 0x4e, 0xec, 0x49, 0x3b, 0xe7, 0x9c, 0x19, 0x5d, 0x7c, 0x51, 0x6b, 0x3b, 0x6a, \n0xa4, 0x38, 0x9d, 0x76, 0xde, 0x7a, 0x60, 0x12, 0xb6, 0x78, 0x42, 0x11, 0x2a, 0x49, 0x39, 0x56, \n0xa7, 0x73, 0x7e, 0x7b, 0x71, 0xe1, 0x05, 0x77, 0x82, 0x04, 0x94, 0xcc, 0xfb, 0xc5, 0xb6, 0x88, \n0xdd, 0x67, 0x17, 0x8b, 0xc5, 0x62, 0xb1, 0x00, 0xe5, 0x27, 0x94, 0xc4, 0x2f, 0xcb, 0xd5, 0x5f, \n0x96, 0xb7, 0x20, 0x4f, 0x40, 0x56, 0xfe, 0xf9, 0xcf, 0xd3, 0x35, 0xc8, 0x1e, 0xe1, 0x34, 0x45, \n0xc5, 0x2e, 0x87, 0x1f, 0xee, 0x7f, 0x5d, 0xad, 0x93, 0x62, 0x94, 0x60, 0x8a, 0x59, 0x52, 0x6c, \n0x41, 0x19, 0xad, 0x8f, 0x5f, 0xbe, 0xfe, 0xe1, 0x85, 0xc0, 0xc2, 0x7d, 0x18, 0x59, 0x9a, 0x22, \n0x94, 0x15, 0x25, 0x2f, 0xec, 0xe5, 0x2b, 0x0b, 0xb5, 0xbb, 0x48, 0x89, 0xf2, 0xc8, 0x9d, 0xb3, \n0xd2, 0xe8, 0xd7, 0xe2, 0x2e, 0x5a, 0x83, 0xdc, 0x85, 0x14, 0x3f, 0x59, 0x96, 0x79, 0x92, 0x3d, \n0x5a, 0x75, 0x6f, 0x71, 0x33, 0x57, 0x60, 0x4c, 0xbb, 0x4b, 0xb2, 0xf2, 0x3d, 0xd6, 0xbf, 0xfe, \n0xdb, 0xc2, 0x74, 0x8f, 0x50, 0x6a, 0x69, 0x26, 0x08, 0x18, 0xe0, 0xed, 0x71, 0x37, 0xcd, 0xe9, \n0xbb, 0x0e, 0x9a, 0x1c, 0x02, 0x9b, 0x28, 0x45, 0x7d, 0xa5, 0xb3, 0xbf, 0xbd, 0x34, 0xfa, 0xc7, \n0x6a, 0xbf, 0x85, 0xa2, 0xf7, 0x91, 0x27, 0x98, 0xe6, 0x49, 0x75, 0xcb, 0x14, 0x82, 0x5c, 0xe4, \n0xae, 0x7c, 0xf4, 0xe5, 0x2b, 0x91, 0x72, 0x5c, 0x60, 0xaf, 0x85, 0x51, 0xdd, 0xac, 0x45, 0x5b, \n0x21, 0x46, 0x23, 0xbb, 0x2b, 0xda, 0xc2, 0x1c, 0x94, 0x28, 0x7f, 0x29, 0xf9, 0x90, 0x01, 0x84, \n0xb9, 0x02, 0x01, 0xa9, 0xfa, 0xff, 0x16, 0xd3, 0x8a, 0x44, 0x17, 0xb0, 0xbc, 0x4c, 0x68, 0xbf, \n0xb5, 0x5a, 0x44, 0x25, 0x34, 0xb5, 0xcd, 0xb3, 0x12, 0x3e, 0xc2, 0xdc, 0xd0, 0xfa, 0x11, 0x0f, \n0x8b, 0xa8, 0xbd, 0x6c, 0x87, 0xa6, 0x2f, 0x3f, 0xeb, 0x67, 0x9e, 0xc6, 0xc6, 0x68, 0xbb, 0xff, \n0x08, 0x1f, 0x3a, 0x27, 0xaa, 0x45, 0x92, 0x6d, 0xee, 0xc9, 0x6c, 0x4b, 0x58, 0x56, 0xa3, 0x10, \n0x84, 0xcb, 0x3a, 0xef, 0x2d, 0x2a, 0xab, 0x1e, 0x35, 0x80, 0xb3, 0x0a, 0x0a, 0x43, 0x84, 0x52, \n0x1f, 0x70, 0xe7, 0xec, 0x08, 0x44, 0xdd, 0x9c, 0xfa, 0x68, 0xe7, 0xc4, 0xa7, 0x8b, 0x66, 0x16, \n0x46, 0x25, 0x4a, 0xd9, 0x0c, 0xa2, 0x0d, 0x59, 0x0e, 0x76, 0xb8, 0xad, 0xe6, 0x49, 0x1f, 0x41, \n0x2c, 0xa6, 0xa9, 0x13, 0x20, 0x45, 0x8f, 0x49, 0x04, 0x52, 0x94, 0xc3, 0x7f, 0xef, 0xf0, 0xf4, \n0x72, 0x9c, 0x36, 0x15, 0x17, 0xc8, 0xe2, 0x5e, 0x6c, 0x8d, 0x4e, 0xff, 0x75, 0x9e, 0xa0, 0x49, \n0x16, 0xe5, 0x70, 0x03, 0x0d, 0xe1, 0x24, 0x86, 0xb6, 0xd6, 0x46, 0xdc, 0xbf, 0x9c, 0xc5, 0x35, \n0x2c, 0xaf, 0xfa, 0xb3, 0xfc, 0xf2, 0x8b, 0x33, 0x4f, 0x7e, 0x9f, 0x94, 0xc5, 0x3a, 0x79, 0x28, \n0x87, 0x99, 0xef, 0xa7, 0x9f, 0xfa, 0x6b, 0xf7, 0xfb, 0xfe, 0x2c, 0x7f, 0x74, 0x1f, 0xa5, 0x38, \n0x79, 0x1a, 0xd6, 0x95, 0xd7, 0xce, 0x32, 0x2a, 0x9f, 0xcb, 0x90, 0x7e, 0xb0, 0xb1, 0x45, 0x4d, \n0x4d, 0x25, 0xca, 0x76, 0x9b, 0x7b, 0xc3, 0xba, 0x12, 0xd1, 0xe4, 0xaf, 0x48, 0x1e, 0x33, 0xbb, \n0x0f, 0xfd, 0xa1, 0xbf, 0xfd, 0x7e, 0x34, 0xb0, 0x38, 0xa4, 0x03, 0x2f, 0x29, 0xe3, 0x0b, 0x12, \n0x4e, 0xc4, 0xe6, 0x1b, 0x94, 0x6f, 0x40, 0x3a, 0x45, 0x9b, 0x2d, 0xc0, 0x0b, 0xbd, 0x0e, 0xde, \n0xc8, 0x8a, 0x17, 0x8a, 0x08, 0xe6, 0x59, 0x00, 0x5e, 0x12, 0x86, 0xa3, 0x92, 0xae, 0xc7, 0xbd, \n0x50, 0x2e, 0x70, 0x14, 0x2a, 0x61, 0xbe, 0xc2, 0x26, 0xef, 0xc7, 0x78, 0x95, 0x94, 0x65, 0x3a, \n0x84, 0x71, 0x5e, 0xcc, 0x71, 0x03, 0xc8, 0x22, 0xf8, 0xe1, 0x41, 0x5d, 0x0d, 0x2a, 0x36, 0x69, \n0x15, 0xd5, 0xe7, 0x56, 0xa3, 0x5e, 0xd4, 0x37, 0x68, 0x1c, 0xc7, 0x24, 0xb1, 0xe8, 0xc5, 0x45, \n0x37, 0x1e, 0xbd, 0x39, 0x14, 0x59, 0xbd, 0x13, 0x46, 0x1b, 0x42, 0xbd, 0xcc, 0xcb, 0x00, 0x75, \n0x22, 0xd8, 0x97, 0x43, 0x91, 0x25, 0x8f, 0x8a, 0x92, 0x4c, 0x9a, 0x25, 0x55, 0x79, 0x84, 0xd2, \n0x37, 0x96, 0x62, 0xf6, 0xa3, 0xd7, 0xd8, 0xa0, 0x5e, 0x67, 0x65, 0xfa, 0x26, 0x4d, 0xad, 0x28, \n0xd5, 0x10, 0x30, 0x2e, 0x6e, 0x58, 0xc4, 0xd1, 0xba, 0xa9, 0x3e, 0x5a, 0xb4, 0xf2, 0x74, 0xaa, \n0x73, 0x84, 0xc4, 0xcb, 0x3b, 0x48, 0xaa, 0xd4, 0x82, 0xef, 0x0b, 0x99, 0xad, 0xb2, 0x92, 0x2c, \n0xa3, 0xee, 0xd2, 0xca, 0x44, 0x65, 0x5a, 0xdb, 0xff, 0x6b, 0x9b, 0xa2, 0xdd, 0xfc, 0xaf, 0x5e, \n0xf9, 0xf1, 0x7b, 0x8a, 0xff, 0x97, 0xa7, 0xf6, 0x7e, 0xec, 0xbf, 0xd3, 0x2f, 0x19, 0xce, 0xfc, \n0x3f, 0x7b, 0xf2, 0xff, 0xe4, 0xc7, 0xfe, 0x8b, 0xa7, 0x74, 0x4f, 0xed, 0x0d, 0x09, 0x98, 0x3b, \n0xff, 0x30, 0xfd, 0x9b, 0x6c, 0xae, 0x4e, 0xe9, 0x7b, 0xf4, 0xd8, 0xd3, 0xe0, 0xbf, 0xf7, 0x63, \n0xff, 0xe3, 0x20, 0x76, 0x92, 0xed, 0xf9, 0xc9, 0x7d, 0xed, 0x39, 0x4b, 0x7a, 0x84, 0xa3, 0xdf, \n0x7a, 0xd0, 0xfe, 0xc1, 0x4f, 0xad, 0x1f, 0x7b, 0x89, 0xea, 0x83, 0x6b, 0x51, 0x8b, 0x2e, 0x3e, \n0xaf, 0x0d, 0x9c, 0x19, 0xfc, 0x3a, 0x2a, 0x92, 0xff, 0xc0, 0xbb, 0xd2, 0x9a, 0xa8, 0xc6, 0x30, \n0x85, 0x25, 0x1c, 0x31, 0xa8, 0x1f, 0x3a, 0x21, 0x5f, 0xfe, 0xf3, 0xff, 0xdc, 0x51, 0x09, 0xb1, \n0x2b, 0x70, 0x85, 0x7a, 0x54, 0xd3, 0xcb, 0x4b, 0xb7, 0x50, 0x87, 0x63, 0xab, 0xbc, 0x63, 0x2d, \n0xb1, 0x3f, 0xfb, 0x51, 0x18, 0x64, 0x25, 0xf9, 0x38, 0x32, 0x35, 0xe8, 0x50, 0x7f, 0x53, 0xe8, \n0x34, 0x9b, 0x94, 0x8a, 0xb6, 0x4e, 0x5f, 0x4c, 0xed, 0x1f, 0xf1, 0x70, 0x80, 0x02, 0x72, 0xa5, \n0x3b, 0x0d, 0x11, 0x4e, 0xb7, 0xae, 0x60, 0xf6, 0x58, 0xae, 0x35, 0xe9, 0x59, 0x5d, 0xed, 0xd4, \n0x72, 0xcd, 0x40, 0x09, 0x04, 0x97, 0x66, 0x59, 0x1b, 0x33, 0x4c, 0x5b, 0x34, 0xd4, 0x37, 0x98, \n0x0a, 0x3c, 0x1a, 0x52, 0x4d, 0x9e, 0xd9, 0x05, 0x2b, 0x55, 0x7f, 0xac, 0x84, 0x99, 0x1b, 0x65, \n0xf3, 0x60, 0xb2, 0x7b, 0x78, 0x80, 0x39, 0x33, 0x99, 0x59, 0xe7, 0x4a, 0x03, 0x07, 0x54, 0x69, \n0x97, 0xe8, 0x64, 0xab, 0xa3, 0xc6, 0x25, 0x1d, 0x6c, 0x60, 0x25, 0xae, 0x97, 0x2f, 0xa1, 0xfd, \n0xb7, 0x97, 0x86, 0x21, 0xac, 0x36, 0x15, 0x35, 0x9d, 0x43, 0xc1, 0xce, 0x91, 0x4f, 0x3b, 0x60, \n0x2e, 0x5c, 0xcd, 0xe8, 0x35, 0x53, 0x40, 0x21, 0xff, 0x51, 0xaf, 0x9d, 0x23, 0x83, 0xe2, 0x79, \n0x2e, 0x7c, 0x5c, 0x77, 0xac, 0xe4, 0xad, 0x9b, 0x28, 0x64, 0xcd, 0x51, 0x80, 0xb8, 0x4b, 0xaa, \n0x9b, 0xc7, 0x69, 0x8a, 0x22, 0xe6, 0x8a, 0x23, 0x2e, 0x48, 0x19, 0x88, 0xb7, 0x5b, 0x98, 0xc5, \n0x0a, 0xb5, 0x22, 0xf3, 0x3c, 0x79, 0xc6, 0x7e, 0x3d, 0xd2, 0xb4, 0x7c, 0x84, 0xdb, 0x14, 0x44, \n0x50, 0xe7, 0x8a, 0x9a, 0x47, 0xac, 0x24, 0xaa, 0x80, 0xac, 0xd0, 0x15, 0xfa, 0x0a, 0xf3, 0x29, \n0x0b, 0x49, 0x9a, 0xe6, 0x4f, 0xdb, 0x6d, 0xd1, 0xb4, 0x2b, 0xa7, 0x0d, 0x35, 0x5d, 0x7b, 0xd8, \n0x60, 0xe8, 0xee, 0x3c, 0x8b, 0x21, 0xe9, 0x30, 0xa6, 0xd0, 0xee, 0x34, 0x6b, 0xba, 0xe8, 0xae, \n0x28, 0xb5, 0x3b, 0x2f, 0x61, 0x3b, 0xdb, 0x18, 0xb1, 0x10, 0x5a, 0xd5, 0xcd, 0x63, 0x7d, 0xd4, \n0x24, 0x71, 0xc9, 0x3b, 0xbc, 0xa6, 0x62, 0xa1, 0xfa, 0xb5, 0xd6, 0x51, 0x3b, 0xd9, 0x7e, 0x67, \n0x63, 0xab, 0xb4, 0x12, 0x5d, 0x8b, 0x95, 0x74, 0xe6, 0xd3, 0x41, 0xe2, 0x7e, 0xd6, 0x78, 0x79, \n0x0f, 0x1d, 0x15, 0x26, 0x27, 0x0d, 0x7b, 0x88, 0xfa, 0x69, 0x50, 0xaf, 0x7e, 0xb1, 0xd9, 0xb0, \n0x7d, 0xa6, 0x9f, 0xc8, 0x21, 0x78, 0x55, 0xbb, 0x74, 0x72, 0x36, 0xd1, 0x83, 0xb3, 0x24, 0xc5, \n0xd0, 0xd2, 0xe3, 0xa4, 0xac, 0x99, 0xfa, 0x72, 0x15, 0xa3, 0xf5, 0xd6, 0x76, 0x86, 0xea, 0x7a, \n0xa3, 0x61, 0xc0, 0x73, 0xb6, 0x0f, 0xc3, 0x59, 0x11, 0x81, 0x2d, 0x9c, 0xba, 0x11, 0x7f, 0xca, \n0xa0, 0x85, 0x5c, 0x19, 0xcc, 0x65, 0x09, 0xf2, 0xb2, 0xf8, 0x9c, 0xe0, 0x54, 0xc6, 0xd9, 0x6d, \n0x54, 0x1e, 0xc7, 0x49, 0x84, 0xa3, 0xd0, 0x0d, 0xc8, 0x73, 0xf4, 0x15, 0x3f, 0xa0, 0x41, 0xd3, \n0xd4, 0x89, 0x15, 0x6a, 0xe8, 0x46, 0xdc, 0x8a, 0x75, 0x24, 0x6d, 0x1c, 0x15, 0xcd, 0xe6, 0xc5, \n0xd9, 0x66, 0x5b, 0xee, 0xe5, 0xf8, 0x22, 0x2b, 0xc1, 0xcb, 0xd6, 0x91, 0xa4, 0x62, 0x6e, 0xa7, \n0xf5, 0x11, 0x02, 0x03, 0x8a, 0x72, 0xba, 0x06, 0x52, 0x85, 0xeb, 0xb5, 0xde, 0x95, 0xb4, 0x7b, \n0x0c, 0x85, 0xca, 0xbc, 0xc5, 0xd0, 0x01, 0x6a, 0x77, 0x18, 0x06, 0x4c, 0xc3, 0x06, 0xc3, 0xa2, \n0xe7, 0x91, 0x40, 0xae, 0x84, 0x7a, 0x4b, 0x2a, 0xdd, 0xae, 0x80, 0x75, 0x2e, 0x6d, 0xa2, 0x58, \n0x36, 0x75, 0x4b, 0x25, 0x03, 0x6b, 0xb2, 0xac, 0x3e, 0xbc, 0x6a, 0x6a, 0x23, 0xeb, 0xac, 0xcd, \n0x01, 0xcc, 0x1d, 0x28, 0x8c, 0x0a, 0x5a, 0x64, 0x74, 0xa4, 0x0e, 0x5a, 0xf2, 0xde, 0xf8, 0x16, \n0x8b, 0x99, 0x96, 0x65, 0x09, 0x87, 0xa5, 0x2e, 0xd4, 0xd3, 0x8d, 0xf7, 0x14, 0x34, 0x09, 0x84, \n0xda, 0xd8, 0x38, 0x8f, 0xac, 0x92, 0x76, 0x96, 0xa9, 0xc8, 0xd2, 0x5e, 0x4a, 0x5f, 0x52, 0x6e, \n0x63, 0x83, 0x5a, 0xff, 0x55, 0xca, 0xb6, 0x2d, 0xb1, 0x50, 0x96, 0x35, 0x59, 0x14, 0xc7, 0x1b, \n0x5b, 0x21, 0xda, 0xaa, 0x3c, 0x9e, 0x02, 0x53, 0xb4, 0xe3, 0xab, 0xc8, 0x15, 0x39, 0x86, 0xfd, \n0xcb, 0xf2, 0x0e, 0xdb, 0x25, 0xd1, 0x65, 0xec, 0x6d, 0x7a, 0xc5, 0xe8, 0x30, 0xc7, 0x5d, 0x89, \n0x68, 0x76, 0x55, 0x01, 0x1c, 0x59, 0xe9, 0x99, 0x91, 0x24, 0x96, 0xd3, 0x77, 0x0a, 0x53, 0xab, \n0x09, 0xa6, 0xcb, 0x92, 0x68, 0xb3, 0x55, 0x1d, 0x47, 0x79, 0x50, 0x07, 0x15, 0x05, 0xc0, 0x8d, \n0xbf, 0x72, 0xdd, 0x86, 0x2b, 0xda, 0xee, 0xef, 0x36, 0xe0, 0x19, 0x87, 0xd5, 0x91, 0x8b, 0x54, \n0x85, 0xd9, 0xc6, 0xf5, 0xc3, 0x0b, 0xc6, 0xd6, 0x32, 0x10, 0x31, 0xdd, 0x06, 0xbf, 0x5d, 0x62, \n0x95, 0x48, 0x30, 0xd0, 0x6f, 0x05, 0x6a, 0x1a, 0x72, 0x21, 0xa0, 0x26, 0xe2, 0xa6, 0x19, 0x37, \n0xa3, 0x6b, 0xca, 0x87, 0x1c, 0xc2, 0x91, 0x20, 0x51, 0x33, 0x0b, 0x29, 0x31, 0x8d, 0x41, 0x42, \n0x8b, 0x8b, 0x49, 0xbd, 0xe0, 0xac, 0xa1, 0xc1, 0x15, 0x65, 0x28, 0xb7, 0xee, 0x72, 0x48, 0x0f, \n0x76, 0xfd, 0xf5, 0xb1, 0x2e, 0x00, 0x75, 0x9f, 0x67, 0xe4, 0xa5, 0xe1, 0x54, 0x94, 0xae, 0x21, \n0xee, 0x35, 0x24, 0xfd, 0x20, 0x75, 0x5b, 0x66, 0x23, 0xf6, 0x39, 0x39, 0xda, 0xb6, 0x0e, 0x34, \n0xad, 0xcb, 0xf1, 0x91, 0x8c, 0xda, 0x4e, 0xd9, 0xd6, 0x31, 0xc7, 0x65, 0x24, 0xe4, 0x38, 0x7d, \n0x85, 0xc8, 0x4f, 0x55, 0x5b, 0xf2, 0x54, 0x28, 0x31, 0x08, 0x8c, 0x24, 0xc0, 0xc6, 0xe0, 0x3e, \n0x85, 0xa2, 0x46, 0x7c, 0x1c, 0x15, 0xbd, 0x4f, 0x0b, 0x72, 0xf6, 0xbc, 0xcd, 0x61, 0x51, 0x24, \n0x28, 0x33, 0xc3, 0x34, 0x79, 0x4b, 0x35, 0xe2, 0xc9, 0x63, 0x06, 0xe3, 0xb1, 0x30, 0x85, 0xb5, \n0x73, 0xb3, 0xa2, 0x9c, 0x55, 0x33, 0xb9, 0xa9, 0x9a, 0xb6, 0x2b, 0x1e, 0x25, 0xc3, 0xa1, 0xfc, \n0x7c, 0x31, 0x4d, 0x41, 0x51, 0x48, 0xb7, 0x1b, 0x1b, 0x85, 0x2d, 0x1b, 0x10, 0xcd, 0x8e, 0x5e, \n0xed, 0xed, 0x9c, 0x08, 0x5b, 0xa1, 0x4b, 0xf8, 0x3c, 0x6a, 0x85, 0x1f, 0x35, 0x91, 0x87, 0xd3, \n0xe5, 0x23, 0x7c, 0x4c, 0x8a, 0x12, 0xe6, 0x37, 0xa0, 0x4c, 0x9e, 0x20, 0x53, 0x4a, 0x1f, 0xd2, \n0x38, 0xa6, 0xf3, 0x24, 0x8b, 0x39, 0x86, 0xf9, 0x4c, 0xc3, 0xa2, 0x77, 0x02, 0x89, 0xf3, 0x06, \n0x6c, 0xa0, 0x7c, 0xed, 0x8a, 0x6b, 0xbe, 0x86, 0xe5, 0x1a, 0x35, 0xe3, 0x30, 0xa5, 0x97, 0x15, \n0x94, 0xe6, 0x91, 0x96, 0x69, 0x8a, 0x87, 0xe0, 0x1e, 0x44, 0x5f, 0xfa, 0x62, 0x4e, 0x89, 0xda, \n0xf9, 0x2e, 0xc2, 0xc6, 0xef, 0x09, 0xbc, 0xc8, 0xc9, 0xa8, 0x95, 0x7b, 0x23, 0x74, 0x4d, 0x20, \n0xe3, 0xd6, 0xcf, 0xb1, 0x5b, 0xd4, 0xe0, 0x47, 0x06, 0x92, 0x65, 0x4b, 0xc2, 0xfb, 0x1d, 0x47, \n0xd9, 0x8c, 0xe7, 0xf4, 0x5a, 0x96, 0xa3, 0x5b, 0x08, 0xe5, 0xfb, 0x8b, 0xea, 0x2c, 0x6f, 0x30, \n0xea, 0x7b, 0x1b, 0x64, 0x92, 0x1e, 0xb5, 0x5e, 0x65, 0xd0, 0x83, 0x68, 0x5a, 0xf9, 0x86, 0xaa, \n0x86, 0x79, 0xc4, 0x71, 0xc8, 0x59, 0xa4, 0xbb, 0xc7, 0x24, 0x33, 0x5a, 0xb1, 0xa1, 0xa8, 0x7d, \n0xae, 0xc4, 0xe3, 0x45, 0x66, 0xbe, 0x44, 0x5c, 0xab, 0xcb, 0xeb, 0xb7, 0x5a, 0xe3, 0x9d, 0xde, \n0xcd, 0x2e, 0x4d, 0xc7, 0x51, 0x84, 0x63, 0xc0, 0x48, 0x69, 0x9b, 0x25, 0x4f, 0x49, 0x0c, 0x27, \n0xfb, 0x7f, 0xc0, 0x1c, 0x89, 0x09, 0x68, 0x7d, 0x53, 0x41, 0x59, 0x03, 0xfa, 0x9f, 0x7a, 0x0c, \n0x41, 0xe9, 0x75, 0xf8, 0xd1, 0x29, 0x40, 0xa1, 0xef, 0x71, 0x06, 0xd2, 0x43, 0x7b, 0x31, 0x3d, \n0xab, 0xa2, 0xa2, 0xc0, 0xd2, 0x21, 0x50, 0x5c, 0x8e, 0x28, 0xc5, 0x0a, 0x5d, 0x61, 0xff, 0x36, \n0x85, 0x6e, 0x07, 0x10, 0x76, 0x4b, 0x07, 0x99, 0x10, 0x9a, 0xfb, 0x39, 0x16, 0x8c, 0x6a, 0x57, \n0xd0, 0x80, 0xe8, 0xaf, 0xb1, 0x8b, 0x3c, 0x64, 0x73, 0x20, 0x30, 0x28, 0x77, 0xda, 0x75, 0xf4, \n0x38, 0x80, 0x6b, 0x58, 0x9a, 0x3d, 0x0b, 0xa5, 0x64, 0x04, 0xed, 0x5e, 0x45, 0x97, 0x3c, 0xb0, \n0x5d, 0x8b, 0x40, 0xce, 0x5f, 0x16, 0xe3, 0x68, 0xe5, 0x4b, 0x4e, 0xdc, 0x24, 0x1c, 0xe7, 0x39, \n0xd8, 0xeb, 0xef, 0x3d, 0x2b, 0x5b, 0x00, 0x1c, 0xcb, 0x28, 0xf9, 0x59, 0x4a, 0x6f, 0x83, 0xb2, \n0x6d, 0x8b, 0x7a, 0x39, 0x9a, 0x67, 0x21, 0x37, 0xbf, 0x79, 0x9e, 0x15, 0x52, 0x6e, 0x57, 0x0b, \n0x99, 0xc6, 0x91, 0xb0, 0x14, 0xd3, 0x89, 0x60, 0x51, 0x7e, 0x96, 0x44, 0x25, 0x5e, 0xf3, 0x41, \n0x6e, 0xeb, 0x01, 0x0d, 0x25, 0xb5, 0xfe, 0xd7, 0x38, 0x42, 0x80, 0x47, 0x78, 0x0d, 0xb6, 0xd5, \n0x5f, 0x3a, 0xcb, 0xb6, 0x1c, 0x98, 0xee, 0x22, 0x45, 0xf7, 0x20, 0x65, 0x06, 0xc6, 0x1f, 0xc5, \n0x00, 0x25, 0x4c, 0x05, 0x54, 0xfb, 0x2b, 0x5d, 0xe7, 0xb1, 0x5e, 0xed, 0x4e, 0x4c, 0x48, 0x67, \n0xd4, 0xdc, 0x44, 0x9c, 0x52, 0x78, 0x14, 0xd7, 0xa0, 0x20, 0xbb, 0x6a, 0x4b, 0xd7, 0xa7, 0xbb, \n0xa2, 0x44, 0x9b, 0xf6, 0x65, 0x83, 0x5a, 0xe7, 0xdb, 0x05, 0xee, 0xe5, 0x0a, 0x6e, 0xb6, 0x28, \n0xc7, 0x66, 0xa1, 0x4b, 0xb1, 0xdc, 0x8a, 0xb3, 0xcb, 0x05, 0xa0, 0xbb, 0xf6, 0x5a, 0xe8, 0xed, \n0xa2, 0x5e, 0x61, 0x96, 0x78, 0x89, 0x24, 0xf6, 0x81, 0x71, 0x02, 0xb0, 0x35, 0x6f, 0x17, 0xfc, \n0x03, 0x5e, 0xcf, 0xdb, 0xc5, 0xa7, 0x2c, 0x77, 0x65, 0xa2, 0x85, 0x36, 0xca, 0x34, 0x2f, 0xce, \n0x9e, 0x09, 0x0f, 0x99, 0x19, 0x94, 0xe6, 0x06, 0x2d, 0x21, 0xc8, 0xa3, 0xb5, 0x6c, 0x57, 0x07, \n0x96, 0x1b, 0xc4, 0xae, 0x69, 0xe2, 0xfd, 0x9b, 0xcc, 0xcd, 0x75, 0xb8, 0xa1, 0xa9, 0xb9, 0x89, \n0x49, 0x0c, 0x83, 0x88, 0x35, 0xc7, 0x2b, 0xdc, 0x2e, 0xcf, 0xb1, 0xb0, 0x59, 0x92, 0x43, 0x92, \n0x30, 0xec, 0xcd, 0xc4, 0xa4, 0xf4, 0x80, 0x22, 0x90, 0xb2, 0x84, 0x47, 0x23, 0xfb, 0xec, 0xb9, \n0xcc, 0x41, 0x54, 0xeb, 0x8d, 0x3f, 0x59, 0xf4, 0x14, 0x69, 0x75, 0x5a, 0x1a, 0x89, 0xe9, 0x68, \n0x9a, 0x89, 0xa7, 0x6b, 0xb4, 0x35, 0xab, 0xd0, 0x76, 0x67, 0x1c, 0xc7, 0xe3, 0x5d, 0x89, 0x74, \n0x68, 0xbc, 0xa3, 0x6c, 0xd0, 0x13, 0x34, 0xd1, 0x89, 0x8e, 0xb6, 0x20, 0xe7, 0x57, 0xb1, 0x8e, \n0xce, 0x32, 0xba, 0x66, 0xd1, 0xf4, 0x78, 0xae, 0xa2, 0x9a, 0x82, 0x68, 0x0d, 0x8b, 0x6a, 0x8a, \n0xac, 0xe0, 0x33, 0xb9, 0x26, 0x1b, 0xe3, 0x49, 0x0a, 0xc1, 0x86, 0xcd, 0x13, 0x4c, 0x4e, 0xe7, \n0x09, 0x69, 0x63, 0xcf, 0x71, 0x8e, 0x41, 0x88, 0xa4, 0x0c, 0x43, 0x92, 0xd6, 0x1b, 0x6e, 0xb2, \n0x3f, 0xcb, 0x22, 0x14, 0x73, 0xcb, 0x8e, 0x0e, 0xd8, 0x24, 0xe6, 0x73, 0x9e, 0x94, 0xb0, 0x53, \n0x0e, 0xa5, 0xb2, 0xeb, 0x2d, 0x78, 0xf0, 0x0c, 0x3e, 0x80, 0x5d, 0x4a, 0xfb, 0xa0, 0x57, 0x4e, \n0x9f, 0xc8, 0xd3, 0x31, 0xd3, 0xf1, 0x0a, 0x31, 0xfd, 0x76, 0xf1, 0x19, 0x67, 0x53, 0xa4, 0x6e, \n0xbd, 0x42, 0x9f, 0xca, 0x87, 0xf7, 0xc6, 0x0a, 0x84, 0x5a, 0x44, 0xc2, 0x31, 0x03, 0x33, 0xac, \n0x50, 0x0d, 0x20, 0xb0, 0x72, 0x1b, 0x50, 0xb9, 0x0a, 0x44, 0x3b, 0xf5, 0xf7, 0xc5, 0xdb, 0x31, \n0x9e, 0xf4, 0x38, 0x09, 0xac, 0x9c, 0x1f, 0x07, 0xd8, 0xf3, 0x24, 0x2d, 0x69, 0xd5, 0xed, 0x76, \n0x61, 0x6e, 0xe6, 0x71, 0x26, 0xc4, 0xb8, 0x6b, 0x12, 0x12, 0x5b, 0x0f, 0xc4, 0x9d, 0x66, 0x8f, \n0x59, 0x57, 0x05, 0xa1, 0xcb, 0x3d, 0x76, 0xcd, 0xcd, 0xd9, 0x13, 0x8d, 0x07, 0x05, 0xd9, 0xa6, \n0x62, 0xaf, 0xc0, 0xc3, 0x53, 0xbd, 0x81, 0x22, 0x80, 0x18, 0x69, 0x79, 0xcc, 0x05, 0x2a, 0x4a, \n0x4a, 0xd2, 0xf5, 0x92, 0xd1, 0x51, 0x93, 0x02, 0xb7, 0x5b, 0x3d, 0xcd, 0x9f, 0x47, 0xd2, 0x32, \n0x22, 0x58, 0x7b, 0x4a, 0x52, 0xe5, 0x94, 0x8a, 0x53, 0xde, 0xb4, 0x34, 0x6d, 0x12, 0x14, 0xa9, \n0x7c, 0x2f, 0xc7, 0x39, 0x64, 0x68, 0xf3, 0xec, 0x6f, 0x3b, 0xb8, 0x83, 0x1e, 0xa0, 0xa2, 0xa2, \n0x24, 0x93, 0x08, 0x85, 0xcc, 0x05, 0x0c, 0xae, 0xff, 0x93, 0xfd, 0x0a, 0x3c, 0x76, 0x1b, 0xdd, \n0x82, 0xb3, 0x44, 0xbb, 0x3c, 0x82, 0x7a, 0x6b, 0x6a, 0x97, 0xea, 0x7a, 0x2e, 0x53, 0x96, 0x6a, \n0xa5, 0xee, 0xdc, 0xab, 0x29, 0xc0, 0x42, 0x7c, 0xc6, 0x1b, 0xd9, 0x32, 0xc9, 0x76, 0x68, 0x57, \n0x50, 0xd0, 0x4b, 0x84, 0xbe, 0x50, 0xef, 0x97, 0x9e, 0xd7, 0xdb, 0x49, 0x9c, 0x3d, 0x3e, 0x88, \n0x18, 0x2c, 0x7c, 0x7b, 0xc3, 0x50, 0x55, 0x36, 0x5b, 0x3c, 0xcd, 0x64, 0x80, 0xf6, 0x61, 0xb7, \n0x12, 0x3d, 0x01, 0x94, 0xc5, 0xa5, 0x7c, 0xc0, 0x6b, 0xbb, 0x36, 0xc5, 0xf9, 0xb0, 0xac, 0x1e, \n0x0b, 0x33, 0x74, 0x5c, 0xec, 0xb3, 0xe8, 0xaf, 0x70, 0xcf, 0xa6, 0x65, 0x33, 0x85, 0xd8, 0x5c, \n0xd6, 0x0e, 0x20, 0x99, 0xd6, 0x51, 0x9e, 0x6c, 0xcb, 0xba, 0x45, 0x98, 0xcc, 0x67, 0xcf, 0x30, \n0xda, 0xe1, 0xf8, 0x4d, 0x29, 0x34, 0x3b, 0x57, 0x4d, 0x7a, 0x67, 0x67, 0xb2, 0xa6, 0xc6, 0x1a, \n0x90, 0xb6, 0xec, 0xd5, 0x53, 0xba, 0x91, 0xb1, 0xaf, 0x06, 0xda, 0x6e, 0xa8, 0x73, 0x53, 0x13, \n0xa9, 0x7c, 0xa0, 0x82, 0xd9, 0x69, 0x98, 0xa6, 0x3d, 0xe1, 0x7a, 0xdb, 0x54, 0x97, 0x08, 0x49, \n0xdb, 0x24, 0xe2, 0xb3, 0x96, 0x73, 0x93, 0x0e, 0x2c, 0xfb, 0x16, 0xac, 0x13, 0x7b, 0xb6, 0xdb, \n0x6c, 0xd9, 0x68, 0x9d, 0x65, 0x8f, 0x49, 0x06, 0x75, 0x93, 0x62, 0xb2, 0x2f, 0x21, 0x4e, 0x1f, \n0xf8, 0xfd, 0x55, 0x5d, 0xe3, 0xa8, 0x8e, 0x87, 0xed, 0x4a, 0xd8, 0xe4, 0xb3, 0xb0, 0xda, 0x6e, \n0xe5, 0xf0, 0x3a, 0xaf, 0xa4, 0x8d, 0xed, 0xc4, 0x9f, 0xae, 0x61, 0xf4, 0xa5, 0x4e, 0x32, 0x69, \n0xbe, 0x7e, 0x8e, 0xd2, 0xb8, 0xdd, 0x53, 0x3b, 0x71, 0xd8, 0x25, 0x50, 0x7d, 0x18, 0x6a, 0x21, \n0x93, 0xcd, 0x75, 0xe9, 0x5d, 0xf5, 0x50, 0x1e, 0x62, 0x7e, 0x7d, 0xc4, 0xd6, 0x98, 0x24, 0x64, \n0x6b, 0xab, 0xe3, 0xe7, 0x5b, 0xc6, 0x31, 0xd8, 0x92, 0x2c, 0xa8, 0x11, 0xc4, 0x9b, 0x8a, 0x16, \n0xc0, 0x58, 0x69, 0xed, 0x53, 0x76, 0x8f, 0x97, 0xd9, 0xf8, 0x7c, 0x97, 0xd1, 0xe4, 0xe8, 0x2c, \n0xcf, 0x51, 0x2e, 0xe4, 0x5e, 0xfd, 0xf9, 0x94, 0xe1, 0xa9, 0x94, 0xac, 0x8f, 0xc6, 0x84, 0x13, \n0xb9, 0xba, 0x2d, 0x17, 0x0a, 0xe9, 0xca, 0xa9, 0x1d, 0xa6, 0xa0, 0x47, 0x61, 0x7c, 0x9d, 0xbd, \n0x49, 0x14, 0x48, 0x10, 0xc7, 0x5b, 0x8f, 0x2b, 0x04, 0x62, 0xa6, 0x5c, 0x75, 0x74, 0xfa, 0x82, \n0x51, 0xfc, 0xe3, 0x6a, 0x3e, 0xb9, 0xc3, 0x7a, 0xe2, 0x45, 0x84, 0x4c, 0xd0, 0xd1, 0x2e, 0x2b, \n0x68, 0xed, 0xbe, 0x4e, 0x2e, 0x9b, 0xcf, 0x29, 0xe2, 0xce, 0x4f, 0xac, 0x54, 0x02, 0xf4, 0xc1, \n0x81, 0x8f, 0x43, 0x20, 0x1f, 0x09, 0x07, 0x18, 0x64, 0x34, 0xe2, 0x13, 0x6c, 0xc2, 0xa4, 0x1c, \n0xd5, 0x1f, 0x0a, 0xb2, 0x00, 0xde, 0x49, 0xd1, 0x87, 0xb6, 0x00, 0x76, 0x37, 0x40, 0x21, 0xd4, \n0x94, 0x2a, 0x75, 0x52, 0x1e, 0xb0, 0x98, 0x62, 0xad, 0x61, 0xe7, 0x18, 0x7f, 0x78, 0x71, 0xf9, \n0xf9, 0x66, 0xc6, 0x57, 0x23, 0xd2, 0x24, 0xa2, 0xf5, 0x92, 0xcf, 0x49, 0x16, 0xa3, 0xaf, 0x97, \n0x20, 0x8b, 0x53, 0x29, 0x6b, 0xce, 0x11, 0x29, 0xed, 0x72, 0xa4, 0xd5, 0xe4, 0x2f, 0x04, 0x32, \n0xc6, 0xa9, 0x52, 0x09, 0x79, 0x40, 0x5d, 0xe9, 0x60, 0x75, 0x1d, 0xc7, 0xb4, 0x4c, 0x04, 0x20, \n0xd9, 0x8b, 0x95, 0x5d, 0x08, 0x96, 0x68, 0x95, 0xef, 0x27, 0xd8, 0xe1, 0x59, 0x82, 0x53, 0x7f, \n0xa8, 0xa7, 0xd3, 0x11, 0xcd, 0x7a, 0x88, 0x18, 0xf5, 0xf1, 0x39, 0x9e, 0xe5, 0x69, 0x2a, 0xd1, \n0xd7, 0xf3, 0x42, 0xc8, 0x6c, 0x48, 0x7c, 0xba, 0xc5, 0xc1, 0x07, 0x13, 0x34, 0x6f, 0x60, 0x7e, \n0x25, 0xba, 0x34, 0xc6, 0x4f, 0xf8, 0x93, 0x34, 0xfd, 0x5f, 0x12, 0x26, 0x4e, 0xc5, 0x36, 0xd8, \n0xa0, 0x57, 0x24, 0xc0, 0x6b, 0x4f, 0x10, 0x4c, 0xdb, 0x0e, 0x91, 0x77, 0x9c, 0x3f, 0xee, 0x48, \n0xe5, 0xef, 0x02, 0x66, 0x75, 0x59, 0x4c, 0x2e, 0xb8, 0xd8, 0x04, 0xc9, 0x05, 0x06, 0xe1, 0xd4, \n0x8d, 0xc9, 0x5a, 0x7c, 0xaa, 0xbe, 0xdc, 0x43, 0xd6, 0xa2, 0x72, 0x1b, 0x94, 0xdf, 0xec, 0x36, \n0x9a, 0x66, 0x1c, 0xe3, 0xf0, 0x2e, 0x97, 0xb5, 0x71, 0x5b, 0x44, 0xec, 0x1f, 0x19, 0x6b, 0x5a, \n0x81, 0xe2, 0x4b, 0x7b, 0x5b, 0x5b, 0x5c, 0xe2, 0x38, 0x0a, 0xe2, 0xed, 0xab, 0xcb, 0x8f, 0x67, \n0xe3, 0xd9, 0xdd, 0x6a, 0xbc, 0xfc, 0xeb, 0xdd, 0xf9, 0xa7, 0x9b, 0xe9, 0x11, 0xf7, 0x70, 0x31, \n0xfe, 0x38, 0xbe, 0x16, 0xf8, 0xb3, 0x98, 0x63, 0x97, 0xf2, 0xea, 0x2b, 0xa4, 0x6c, 0xd6, 0x85, \n0xf6, 0x39, 0x29, 0xed, 0x95, 0x80, 0x2c, 0x4c, 0x16, 0xc2, 0xc5, 0xae, 0x58, 0x9f, 0x65, 0x4f, \n0x49, 0x8e, 0xb2, 0x1b, 0x94, 0x14, 0xb5, 0x61, 0xab, 0x98, 0xab, 0xe9, 0x13, 0xb9, 0x89, 0x82, \n0x07, 0x01, 0x6d, 0x26, 0x49, 0x59, 0xbc, 0x39, 0x7e, 0x3f, 0x52, 0xfd, 0x6c, 0x9a, 0x26, 0xdb, \n0x7b, 0x04, 0xf2, 0xf8, 0x12, 0x14, 0xec, 0x14, 0x99, 0xa5, 0xec, 0xf5, 0x63, 0xf6, 0x4c, 0xac, \n0xd8, 0x54, 0x4d, 0x4b, 0x52, 0x93, 0x54, 0x6b, 0x4f, 0x1a, 0xec, 0x8b, 0x8a, 0x52, 0x19, 0xf1, \n0xd3, 0x77, 0xed, 0xc0, 0x25, 0xd1, 0x97, 0x3a, 0xf0, 0x73, 0x79, 0x3f, 0x93, 0x6f, 0xaa, 0xeb, \n0x2a, 0x9e, 0x34, 0x8c, 0xd1, 0x5c, 0x78, 0xa1, 0x4b, 0xe6, 0xd9, 0x73, 0x04, 0xb7, 0x7c, 0xe8, \n0xb1, 0x85, 0x06, 0x37, 0x0e, 0x7d, 0x56, 0xe9, 0x8b, 0xe3, 0xad, 0x87, 0xb5, 0xf2, 0x37, 0xc6, \n0x29, 0x43, 0xf3, 0x46, 0xb1, 0xd4, 0x56, 0xc5, 0xa9, 0x79, 0xf6, 0x40, 0xcd, 0xce, 0x02, 0x82, \n0x96, 0xa4, 0x01, 0x10, 0xdc, 0x94, 0xd5, 0x59, 0x2a, 0x92, 0x91, 0x73, 0x6c, 0x13, 0x30, 0x48, \n0xf4, 0x72, 0x01, 0x10, 0x9c, 0x19, 0x65, 0x4f, 0x30, 0x2f, 0x17, 0xd3, 0xeb, 0x15, 0x7a, 0x73, \n0x4a, 0x5e, 0x46, 0xac, 0x79, 0xdf, 0x9c, 0x36, 0xd6, 0xa9, 0x26, 0x58, 0x5d, 0xe2, 0xbf, 0x5d, \n0x7c, 0x06, 0x4f, 0x90, 0xf9, 0x17, 0xb7, 0x23, 0xe0, 0x2e, 0xeb, 0xf7, 0x86, 0x6e, 0x36, 0x29, \n0xd2, 0x6f, 0x9a, 0xb5, 0xbb, 0x08, 0x38, 0x4f, 0x11, 0x9e, 0xb9, 0x0f, 0xe4, 0xe7, 0x10, 0xec, \n0x01, 0xb0, 0x76, 0x6b, 0x88, 0x95, 0x01, 0x7a, 0xe3, 0x93, 0xd5, 0xde, 0x97, 0x24, 0xed, 0xc4, \n0xa3, 0x3f, 0xe7, 0x3e, 0xf2, 0x95, 0x4a, 0x81, 0x48, 0x3d, 0xca, 0xb8, 0xc8, 0xc1, 0x76, 0x9d, \n0x44, 0x24, 0x57, 0xc4, 0x5e, 0xc4, 0x72, 0x83, 0x5c, 0xd9, 0x54, 0x61, 0x28, 0x1d, 0x5d, 0x73, \n0x20, 0xcd, 0x93, 0x5c, 0xe2, 0x90, 0x0d, 0x73, 0x07, 0xc2, 0x25, 0xee, 0xa6, 0xad, 0x9d, 0x9c, \n0x54, 0x6f, 0x4b, 0x8e, 0x4a, 0xbc, 0x2b, 0x2b, 0x1d, 0xaf, 0xfc, 0x3f, 0xef, 0x08, 0x2d, 0xdb, \n0x57, 0xf4, 0xb4, 0x6c, 0x3f, 0x52, 0x97, 0xf1, 0x15, 0x1a, 0x47, 0xe5, 0x8e, 0x7c, 0xe3, 0x46, \n0x8a, 0x72, 0xee, 0x76, 0x8b, 0x4a, 0x79, 0x9e, 0xa3, 0x8d, 0x89, 0xd6, 0x54, 0xc2, 0x61, 0x59, \n0x1a, 0xe1, 0xbc, 0xbb, 0x99, 0xdf, 0x4d, 0xb0, 0x83, 0x5d, 0x81, 0x7d, 0x75, 0x5b, 0x93, 0x7f, \n0xa0, 0x5e, 0xeb, 0x61, 0x09, 0x06, 0x3b, 0x10, 0x5a, 0x92, 0x77, 0x8f, 0x9b, 0xea, 0x91, 0xce, \n0xe3, 0x88, 0x35, 0x52, 0x76, 0xc7, 0x07, 0xd3, 0x8d, 0x48, 0x9a, 0x4b, 0xcb, 0xe0, 0x47, 0xc5, \n0x1a, 0x2f, 0xd9, 0xec, 0xa7, 0x7e, 0x88, 0x75, 0x9c, 0x0a, 0xf9, 0x8c, 0x5e, 0xc4, 0x16, 0x49, \n0x57, 0xa4, 0xce, 0x4c, 0xe9, 0xc5, 0x04, 0x83, 0x1c, 0x77, 0xb3, 0x09, 0xf2, 0x76, 0xd6, 0x1c, \n0x12, 0xce, 0xeb, 0x27, 0x7f, 0x52, 0xa6, 0x51, 0x4d, 0xd5, 0xbe, 0x62, 0xf3, 0x82, 0x1e, 0xe4, \n0x45, 0x20, 0x23, 0x79, 0x19, 0xce, 0xa4, 0xc8, 0x1d, 0x8a, 0xe6, 0xa0, 0x60, 0x79, 0xb5, 0x20, \n0xde, 0x33, 0xdf, 0x68, 0xea, 0x14, 0x5c, 0xec, 0x50, 0x8a, 0xd5, 0xca, 0xf5, 0x2a, 0x9a, 0xd2, \n0xac, 0x72, 0x90, 0x15, 0x95, 0x03, 0xd5, 0x92, 0xe8, 0x39, 0xa2, 0xae, 0x41, 0x57, 0x4a, 0xf4, \n0x00, 0x18, 0xa7, 0xdb, 0x35, 0x98, 0xa4, 0x64, 0xd3, 0xc3, 0x0d, 0xbd, 0xbc, 0xdf, 0x79, 0x7b, \n0xac, 0xcf, 0x9a, 0x5a, 0xee, 0xbb, 0xcb, 0xd9, 0xd8, 0x13, 0x01, 0xb9, 0xf2, 0x77, 0x6b, 0x12, \n0x0c, 0xcb, 0xd7, 0x2a, 0xc0, 0x93, 0x3f, 0x0e, 0xd5, 0x11, 0xe0, 0x0f, 0x44, 0x03, 0xce, 0x35, \n0x28, 0xed, 0x40, 0x5a, 0xf6, 0x38, 0x4e, 0xc8, 0xf5, 0x25, 0x4f, 0x67, 0x53, 0x50, 0x06, 0x3b, \n0x9d, 0x8a, 0xe4, 0x67, 0x1e, 0xad, 0x66, 0xc1, 0x31, 0x87, 0x39, 0x93, 0x06, 0xc7, 0x4b, 0xb1, \n0x2a, 0xe9, 0x11, 0x70, 0xf1, 0xfa, 0x45, 0x7e, 0x8d, 0xba, 0x94, 0xa9, 0x79, 0x2b, 0x1e, 0x1e, \n0xa2, 0x93, 0x97, 0x94, 0xf7, 0xf0, 0xc2, 0x66, 0xf2, 0xa1, 0x5a, 0xe3, 0x7e, 0x9d, 0x51, 0x40, \n0x55, 0x97, 0x0a, 0x05, 0x8c, 0x86, 0xc2, 0x3a, 0xeb, 0x7d, 0x68, 0x11, 0x07, 0xb2, 0xb8, 0x7e, \n0xe8, 0xbd, 0x61, 0xe5, 0xd0, 0x19, 0xda, 0x1a, 0xf2, 0x2c, 0x0a, 0x83, 0xdf, 0x11, 0x29, 0x87, \n0x19, 0x67, 0x9e, 0xe1, 0x1c, 0x6b, 0xeb, 0x2f, 0x22, 0x70, 0xd7, 0x42, 0xcf, 0xb5, 0xce, 0xa8, \n0xee, 0x37, 0x44, 0x1d, 0x56, 0xec, 0x21, 0xcc, 0x5d, 0x7e, 0x6f, 0x7b, 0x1e, 0x26, 0x06, 0x74, \n0xae, 0x45, 0xa1, 0x07, 0x2e, 0xec, 0xe4, 0xc2, 0x29, 0x3c, 0xcd, 0x84, 0xfd, 0x67, 0xd5, 0x30, \n0x69, 0x3e, 0x8e, 0x3e, 0x50, 0xa2, 0xb7, 0xfd, 0x86, 0xf7, 0xf4, 0xbb, 0xc9, 0xfe, 0xd6, 0xa3, \n0x3a, 0x78, 0x0e, 0x0c, 0xed, 0xdf, 0xf7, 0x32, 0xac, 0xff, 0x6c, 0xec, 0x25, 0x38, 0xd8, 0x1a, \n0xe8, 0x1e, 0xd5, 0xbf, 0x8f, 0x6c, 0xb3, 0xd4, 0x6f, 0x16, 0x31, 0x0e, 0xb0, 0x66, 0x86, 0xb0, \n0xfa, 0x37, 0x8e, 0x21, 0x07, 0x5a, 0x4a, 0x3d, 0x75, 0xf8, 0x36, 0xf1, 0xe5, 0x10, 0x8b, 0xaf, \n0x8b, 0x02, 0xe4, 0xd5, 0x88, 0x0f, 0x5b, 0xf0, 0xef, 0x1d, 0x64, 0x65, 0x34, 0x01, 0xd7, 0x6d, \n0x6f, 0x3b, 0x25, 0x54, 0xfd, 0x8b, 0x0a, 0x0e, 0x50, 0x7d, 0x2a, 0x0b, 0x2e, 0x70, 0x41, 0x75, \n0x73, 0xae, 0x03, 0x58, 0x72, 0x2e, 0xab, 0xf5, 0xdd, 0x07, 0x5c, 0x8b, 0x6c, 0x19, 0x94, 0xfe, \n0xae, 0x64, 0xcc, 0xc0, 0x87, 0xca, 0x09, 0x92, 0x7c, 0x77, 0xba, 0x8b, 0x5f, 0x47, 0x0d, 0x52, \n0x82, 0x1a, 0xd3, 0x20, 0xc3, 0x3b, 0xe8, 0xe8, 0x82, 0x4c, 0x20, 0x6f, 0xeb, 0x27, 0x32, 0xa8, \n0x1b, 0xf6, 0x5f, 0xd4, 0xbe, 0x83, 0x02, 0x06, 0xd1, 0x87, 0x48, 0x26, 0xfa, 0x88, 0xff, 0xae, \n0x7d, 0x0f, 0xbe, 0x88, 0xba, 0x44, 0xe8, 0xe5, 0xac, 0x33, 0x44, 0xfb, 0x2d, 0x01, 0xcb, 0x99, \n0xc3, 0x2a, 0xe0, 0x2d, 0xa2, 0x7b, 0xd5, 0xea, 0x5b, 0x87, 0x4a, 0xca, 0x4f, 0x59, 0xf2, 0x44, \n0x07, 0x8a, 0x4a, 0x61, 0xe7, 0x77, 0x9e, 0xfc, 0x26, 0x07, 0xeb, 0x81, 0x60, 0xf0, 0x12, 0x0d, \n0x82, 0xc8, 0x3d, 0xc4, 0x40, 0xe2, 0xa3, 0xf7, 0xce, 0xd9, 0x8e, 0x28, 0xf9, 0xae, 0xf8, 0x9a, \n0x90, 0x0b, 0xf9, 0x07, 0x56, 0xc0, 0xdd, 0x14, 0xc3, 0xbc, 0x25, 0xa8, 0x31, 0x0e, 0xaf, 0x42, \n0x0f, 0x73, 0x0c, 0x9a, 0x9f, 0x61, 0xcd, 0x71, 0x70, 0x15, 0x6c, 0xe6, 0x20, 0xf7, 0x50, 0xf7, \n0xd5, 0x99, 0xe1, 0xd6, 0xa6, 0xc8, 0x7b, 0x09, 0x8f, 0x91, 0x19, 0xa1, 0xec, 0xc7, 0x6a, 0x7a, \n0xb0, 0x4e, 0xfd, 0x4e, 0x4f, 0x02, 0x6a, 0x78, 0x7a, 0x72, 0x10, 0x1d, 0xbb, 0xf6, 0x24, 0x7d, \n0xed, 0xd8, 0x79, 0x44, 0x39, 0xd8, 0x96, 0x81, 0x35, 0x65, 0x80, 0x87, 0xb1, 0xa9, 0x35, 0x62, \n0xf4, 0xd7, 0x33, 0x24, 0x9c, 0x7d, 0xfa, 0xf6, 0xd7, 0x2d, 0x24, 0x5c, 0xc7, 0xc5, 0x84, 0xe1, \n0x9e, 0x73, 0x10, 0xdc, 0x8e, 0x13, 0xef, 0xe1, 0xda, 0x86, 0xc2, 0xa5, 0xb9, 0x17, 0xc5, 0xed, \n0xda, 0x30, 0xf4, 0xc7, 0xb1, 0x65, 0x47, 0x3d, 0x91, 0x2c, 0x59, 0x92, 0x19, 0xa9, 0x79, 0xe5, \n0xb2, 0x28, 0xf1, 0x16, 0x30, 0x4a, 0xca, 0xbd, 0x73, 0xae, 0xc5, 0x58, 0xb5, 0x5c, 0x46, 0x4b, \n0x1b, 0xf9, 0xfb, 0xc5, 0x0f, 0x1b, 0x92, 0xf3, 0x62, 0x61, 0x41, 0xf0, 0xd2, 0x66, 0x1c, 0xc7, \n0x3e, 0xb7, 0x68, 0x7c, 0xef, 0xce, 0x84, 0xb9, 0x31, 0x13, 0xe8, 0x9e, 0xcc, 0x72, 0x77, 0x3f, \n0xd8, 0x16, 0x35, 0xef, 0x50, 0x5b, 0x34, 0xfc, 0x41, 0x7a, 0xe0, 0x6f, 0x8b, 0xeb, 0x5d, 0x3a, \n0xd8, 0x16, 0x35, 0xef, 0x50, 0x5b, 0x34, 0xfc, 0x41, 0x7a, 0xe0, 0x6f, 0x0b, 0x1a, 0xbb, 0x66, \n0x28, 0x7e, 0x84, 0x83, 0x4d, 0x22, 0x41, 0x0c, 0xb5, 0x8c, 0x0c, 0x13, 0xb2, 0x5b, 0xfe, 0x76, \n0x9a, 0x81, 0xfc, 0x0b, 0xcc, 0x06, 0xdb, 0x88, 0x63, 0x1f, 0x6a, 0x1f, 0x1e, 0x22, 0x54, 0x57, \n0xfc, 0xed, 0x72, 0x95, 0x3c, 0xae, 0x4b, 0x0f, 0xc3, 0xf0, 0xfc, 0x43, 0x2d, 0x23, 0x60, 0x04, \n0xeb, 0x4d, 0x80, 0x98, 0x1b, 0xe5, 0xd0, 0xc3, 0x34, 0x1c, 0xfb, 0xe0, 0xc8, 0xcb, 0x41, 0x84, \n0xea, 0x4a, 0x00, 0xbb, 0xb4, 0x67, 0x2b, 0xc1, 0xaf, 0x6d, 0xf5, 0x02, 0x1d, 0xb6, 0x63, 0x3f, \n0x07, 0x45, 0x49, 0x6e, 0xbb, 0x83, 0x9c, 0x49, 0xbe, 0x3c, 0x3e, 0x77, 0x95, 0x68, 0x87, 0x99, \n0x84, 0x80, 0xb9, 0x3d, 0xf6, 0xe8, 0xbe, 0x76, 0x94, 0x70, 0x24, 0x0d, 0x35, 0x54, 0xfc, 0x41, \n0xc7, 0xb7, 0xbb, 0xad, 0x70, 0x68, 0x69, 0xad, 0x1c, 0x4f, 0x53, 0xb9, 0x08, 0xbb, 0x06, 0x5f, \n0xd8, 0x21, 0x34, 0x79, 0x51, 0x85, 0xbc, 0x05, 0x62, 0x04, 0x54, 0xf7, 0xa6, 0x44, 0xb7, 0xeb, \n0xfa, 0x6d, 0xd5, 0xde, 0xcb, 0xf3, 0x76, 0x2f, 0xbf, 0x4b, 0xe3, 0xcc, 0x3c, 0x49, 0xb2, 0x98, \n0x08, 0x5e, 0xa1, 0x6b, 0x90, 0x64, 0x03, 0xb6, 0x05, 0xe7, 0x49, 0x9a, 0x8e, 0x3f, 0x5e, 0x18, \n0x66, 0x88, 0xbe, 0xb7, 0x35, 0xcf, 0xdd, 0xcd, 0xb4, 0x2f, 0x9b, 0xa6, 0xa3, 0xdd, 0x4c, 0xaa, \n0x65, 0xed, 0x3c, 0x38, 0xb9, 0xc7, 0x39, 0xed, 0x2d, 0xcc, 0xcb, 0xe5, 0x6e, 0xf3, 0xe6, 0xb4, \n0x61, 0xe5, 0x5e, 0xe6, 0x1b, 0x60, 0x6a, 0x09, 0x95, 0xdb, 0xd6, 0x06, 0xc4, 0x7d, 0x7b, 0xdc, \n0xe9, 0x05, 0x83, 0x50, 0xbd, 0x8e, 0x52, 0x84, 0x1c, 0x07, 0x4d, 0xd0, 0xf3, 0x24, 0xdd, 0xe5, \n0xe3, 0xa7, 0x47, 0xce, 0xb4, 0x0d, 0xb9, 0xc1, 0x1e, 0xa6, 0x47, 0x96, 0xf9, 0x28, 0x4a, 0xd2, \n0x55, 0x11, 0x0e, 0x23, 0x4b, 0x1e, 0x82, 0xe1, 0x76, 0xeb, 0x96, 0x64, 0xea, 0x55, 0x18, 0x59, \n0xcb, 0xaf, 0x80, 0x84, 0x6a, 0xf8, 0xbe, 0x11, 0xc2, 0x7f, 0xc5, 0xad, 0x21, 0x20, 0xd4, 0x4c, \n0x56, 0x33, 0x68, 0xf8, 0x3e, 0xc2, 0x27, 0x98, 0x17, 0x1a, 0x59, 0x7a, 0x3a, 0x1d, 0xbc, 0x62, \n0xaa, 0x8b, 0x1c, 0xec, 0x97, 0x11, 0x30, 0x9c, 0xd0, 0xc9, 0xe7, 0x6a, 0x17, 0x60, 0xb3, 0x01, \n0xe3, 0xf8, 0xd7, 0x5d, 0x41, 0xbf, 0x80, 0x93, 0xfe, 0xaf, 0x3e, 0xfa, 0xae, 0xe4, 0x95, 0xa6, \n0xa5, 0x35, 0xa6, 0x4c, 0xc1, 0x5a, 0xa5, 0xc3, 0x8d, 0xfe, 0xf0, 0xe2, 0x64, 0x24, 0x6d, 0x94, \n0xcc, 0x10, 0xc7, 0x7a, 0xe3, 0x18, 0x6b, 0x61, 0x6e, 0x48, 0xd3, 0x35, 0xf1, 0x41, 0xbc, 0xdb, \n0x25, 0xab, 0x0f, 0x57, 0x4f, 0x52, 0x8f, 0x5b, 0x3a, 0x4a, 0x41, 0x0c, 0x08, 0x47, 0x9b, 0x60, \n0x58, 0x1a, 0x14, 0xd3, 0x2a, 0xde, 0x89, 0xee, 0xb2, 0xee, 0x0b, 0xa6, 0x08, 0x67, 0x88, 0x10, \n0x66, 0xf8, 0x76, 0x46, 0x98, 0x5c, 0x9d, 0x3d, 0x6f, 0x41, 0x16, 0xbf, 0x99, 0x24, 0xe5, 0x0a, \n0xbd, 0xc7, 0x3f, 0x17, 0x20, 0x75, 0xec, 0x82, 0x3d, 0xdb, 0x55, 0x91, 0xdd, 0x60, 0xcd, 0x18, \n0x6f, 0x8f, 0x25, 0xf5, 0x3a, 0x0a, 0x98, 0x6e, 0xfa, 0xbd, 0x3b, 0x58, 0xcf, 0xdf, 0x05, 0xe8, \n0xf9, 0xbb, 0x03, 0xf6, 0xfc, 0xfd, 0xc1, 0x7a, 0xfe, 0xfe, 0x00, 0x5a, 0x2b, 0xc8, 0x64, 0x91, \n0x18, 0x90, 0xf8, 0x4e, 0xae, 0xa6, 0xec, 0x65, 0xc0, 0x37, 0x27, 0x2e, 0xe3, 0xc3, 0x67, 0x10, \n0x36, 0x18, 0xaa, 0x92, 0x4d, 0x9d, 0x4e, 0xa0, 0x63, 0x3f, 0x7f, 0x11, 0x51, 0x3a, 0xd5, 0x31, \n0xe0, 0x84, 0x41, 0x69, 0xb4, 0xa1, 0x00, 0x9d, 0x7d, 0x32, 0x6e, 0x72, 0x24, 0x18, 0xfa, 0xeb, \n0xee, 0x06, 0x65, 0xba, 0x37, 0x37, 0x7d, 0x20, 0x71, 0xe8, 0x26, 0x5f, 0xc2, 0x1c, 0x16, 0xd4, \n0x07, 0x71, 0x96, 0x94, 0x6b, 0x98, 0x57, 0x70, 0x6f, 0x4e, 0xf1, 0xaf, 0x13, 0x6e, 0x69, 0x34, \n0xed, 0x3b, 0x1c, 0xe2, 0xbd, 0x06, 0xf8, 0x24, 0x3c, 0x70, 0x8f, 0xf1, 0xb6, 0x61, 0xae, 0xae, \n0x2e, 0x4e, 0xc8, 0x17, 0x93, 0xa2, 0x02, 0xd2, 0xfd, 0x63, 0xf1, 0x76, 0x85, 0xde, 0x39, 0xcc, \n0x8d, 0xea, 0xef, 0xea, 0xdf, 0x9a, 0x69, 0x0d, 0xac, 0x40, 0xbf, 0xf3, 0x84, 0xae, 0xfe, 0x68, \n0xd1, 0x67, 0xb0, 0xfe, 0x72, 0xb9, 0x65, 0x9a, 0xc4, 0xb0, 0x47, 0x5a, 0x60, 0x99, 0x58, 0x18, \n0xf8, 0x74, 0x46, 0xbf, 0xdf, 0xf1, 0x02, 0x6b, 0xbd, 0xb9, 0xbf, 0x05, 0xe9, 0x0e, 0x92, 0x2f, \n0x85, 0x3a, 0x4f, 0xf2, 0x82, 0x99, 0xdc, 0x0c, 0xd8, 0x0d, 0x34, 0x08, 0x80, 0x6c, 0x1a, 0xe8, \n0x97, 0x8c, 0x25, 0xd1, 0x48, 0x19, 0x61, 0xa7, 0xc2, 0x8c, 0xc9, 0x08, 0x12, 0x4a, 0x87, 0xab, \n0x70, 0xea, 0xf4, 0xd4, 0x23, 0x80, 0xfc, 0x85, 0xf1, 0x1d, 0x3f, 0xb7, 0x09, 0xbf, 0xb0, 0xbc, \n0x43, 0xd7, 0x6f, 0xf3, 0xb7, 0xb0, 0xbe, 0xff, 0x37, 0x40, 0x1b, 0xef, 0xea, 0xf4, 0xa2, 0xf0, \n0x39, 0x37, 0x6e, 0xb9, 0x43, 0x69, 0xe1, 0x61, 0x95, 0x60, 0xa7, 0xc7, 0x8b, 0xc2, 0xe7, 0xfc, \n0xb8, 0xe5, 0x0e, 0xa5, 0xc5, 0x70, 0x9b, 0x84, 0x3b, 0x45, 0x5e, 0x14, 0x3e, 0xe7, 0xc8, 0x2d, \n0x77, 0x28, 0x2d, 0x86, 0xdb, 0x24, 0xdc, 0x69, 0x32, 0xb6, 0xaf, 0xdf, 0x99, 0x97, 0x00, 0x10, \n0x50, 0x17, 0x0f, 0x87, 0x09, 0x79, 0xf2, 0xb5, 0x28, 0x3e, 0xe0, 0xc4, 0x2b, 0x05, 0x7b, 0x0f, \n0x03, 0xf1, 0x08, 0x21, 0xb5, 0x19, 0x6e, 0x22, 0x19, 0xc5, 0x57, 0xab, 0x4b, 0x90, 0xc7, 0xf4, \n0x24, 0xd6, 0xc3, 0x4a, 0x22, 0x46, 0x58, 0x8d, 0x86, 0x5b, 0x4a, 0xc5, 0xf1, 0xf6, 0x71, 0xf4, \n0x50, 0xfa, 0xda, 0x4a, 0xc4, 0x08, 0xab, 0x91, 0xc7, 0xc4, 0x53, 0x70, 0x7c, 0x35, 0x0b, 0x70, \n0xd7, 0x45, 0x01, 0x09, 0xac, 0xd3, 0x70, 0x73, 0x05, 0xbf, 0xf1, 0xc2, 0x43, 0x9e, 0x04, 0x31, \n0xd8, 0x49, 0x60, 0x8b, 0x9d, 0x04, 0x33, 0xd9, 0x49, 0x58, 0x9b, 0x4d, 0x76, 0xb9, 0xcf, 0x12, \n0x28, 0x62, 0x84, 0xd5, 0xc8, 0xd3, 0x5a, 0x02, 0x8e, 0xaf, 0x66, 0xbe, 0x77, 0x87, 0x44, 0x84, \n0x90, 0xda, 0x0c, 0xb7, 0x52, 0xd8, 0x1b, 0x44, 0x8b, 0xc2, 0xf3, 0xde, 0x99, 0x00, 0x10, 0x50, \n0x97, 0xe1, 0x06, 0x0a, 0x7a, 0xfb, 0x0c, 0xc3, 0x25, 0x0f, 0x0f, 0x3e, 0xd6, 0xa9, 0xd9, 0x83, \n0xe9, 0xe1, 0x61, 0x19, 0x1e, 0x22, 0x84, 0x3e, 0x3e, 0x51, 0xbb, 0xe5, 0x0f, 0xa7, 0x89, 0x9f, \n0x69, 0xc2, 0xc5, 0xe8, 0xb3, 0xe7, 0x28, 0xdd, 0x91, 0x6f, 0x75, 0xf6, 0xb0, 0x8f, 0x88, 0x11, \n0x56, 0xa3, 0xe1, 0x76, 0x52, 0x71, 0xfc, 0x34, 0xab, 0xbf, 0xb2, 0x76, 0xb6, 0xbc, 0x4d, 0x62, \n0x88, 0xa6, 0x28, 0x86, 0x91, 0xf4, 0x45, 0xae, 0x94, 0xf8, 0x35, 0xfb, 0xff, 0x04, 0xec, 0xbf, \n0x6d, 0x2e, 0xd9, 0x3f, 0x54, 0x73, 0x7c, 0xc4, 0xf8, 0xc5, 0x73, 0xec, 0xfc, 0xdb, 0x89, 0xfd, \n0x1f, 0x79, 0x51, 0x95, 0x71, \n\n};\nstatic void * func_ptrs[] = {\n\tTVP_Stub_3d4b725f0b4234d79524822e7c34486b,\n\tTVP_Stub_3fc0c32ee41ea0c515f8fbb681e37982,\n\tTVP_Stub_e8dbd4fe012262d9da831e0735aa33b3,\n\tTVP_Stub_ace6cce1353865d7376caca1f2124216,\n\tTVP_Stub_5055344aa8055bc238b79e5f88fc3300,\n\tTVP_Stub_8238c542b814acf1a83c00cced57ba26,\n\tTVP_Stub_bd2a14ca8c345fd7f151b08d1792fb60,\n\tTVP_Stub_16d432f9f86738a7688cbfc9b12441ec,\n\tTVP_Stub_6dac00582b8ba529e548ef058c4e869e,\n\tTVP_Stub_9193ae470b5efdfe617b5e94cd8f5da6,\n\tTVP_Stub_ec455b6ef0f5da178063db3875973260,\n\tTVP_Stub_a56aaf685bd171b63b0ef3c894d80ecf,\n\tTVP_Stub_9a5fe199cebb9841f94ac0bb7a4a3b6a,\n\tTVP_Stub_2acb76a1f86e34afc5fe934d406c6c4c,\n\tTVP_Stub_3a4d914ca7d24989c236ad223c002d49,\n\tTVP_Stub_8fca7d3a123df1eacf228ba89f6a02ff,\n\tTVP_Stub_58be195f96a36c158d638e3b0c79308b,\n\tTVP_Stub_eaa4d5b1d186a807a63311ab6d5e16e4,\n\tTVP_Stub_246f30d208c1d3a4e2b558090f403734,\n\tTVP_Stub_3206ef9b7a8013d6572decdea49e7e2e,\n\tTVP_Stub_c5a30d297c3a121879b1392bc6c604ef,\n\tTVP_Stub_e398f5aef0ab92bc1323f3b094722fb1,\n\tTVP_Stub_0733b0ac80880897d327dc6f3b04ea9e,\n\tTVP_Stub_4cb055ed9d8ef71d1af10898965c940c,\n\tTVP_Stub_ef8d198596b7d3143d02ed4450ccefa1,\n\tTVP_Stub_d48ea419e040ffe8c20c1e86d80c9a5f,\n\tTVP_Stub_679b215ff76a269871d5f325b981e561,\n\tTVP_Stub_1039eff4a4443f9238438485a35a93a7,\n\tTVP_Stub_2f873b0ee1c6591ba28bc4b9c0e4c954,\n\tTVP_Stub_a583ffb56cdb2ede691e15053a8a165a,\n\tTVP_Stub_e09ed277802c1b117e1908421448886d,\n\tTVP_Stub_e76dfb9e00f4a9d491117d815f30db7f,\n\tTVP_Stub_b000dd8934508d8ec6d6ef976a6ff49b,\n\tTVP_Stub_d98ab5c968ebfde4e924901d09190774,\n\tTVP_Stub_661e8c10d5d477e6823a840244937cd8,\n\tTVP_Stub_6b39e70ea89c4f883689f51289029b69,\n\tTVP_Stub_4a18b1c0afe37b84e2b35a7fc07c4e0f,\n\tTVP_Stub_48b85c8774d91ca40b2992f0e452f19e,\n\tTVP_Stub_5ea8db9a9193fe6bab53baf2bee06b6b,\n\tTVP_Stub_46b92626ff6894e993c4f193a129540b,\n\tTVP_Stub_6efc1d1f66f0e01a81faf767d7576816,\n\tTVP_Stub_4ededf58eae77c320b4a6f5f701acafb,\n\tTVP_Stub_028d5fda2f4568f6ab14b49d89650a4d,\n\tTVP_Stub_11912984b8c094d2df26bf3c3677d096,\n\tTVP_Stub_6c0df790c33142e286aea9af6993d931,\n\tTVP_Stub_c27d85b695cd6e144210785bdfd446ce,\n\tTVP_Stub_8422ef7f42009be0ad58a09d64149051,\n\tTVP_Stub_ee07e6522577952453206ede39cdf54c,\n\tTVP_Stub_786a65424247e711f6ca31f0a10603d7,\n\tTVP_Stub_995a222f2038dd2007f2c1f6429bd19e,\n\tTVP_Stub_da8c6e750d6a9c0557a56ef7f7fd8e88,\n\tTVP_Stub_9cf7b0f119bcf3fa4564837ae25429b3,\n\tTVP_Stub_17cbcacad2ed350215d7d700c676ea40,\n\tTVP_Stub_2bd375c0598e9148d88579a51b2f07a8,\n\tTVP_Stub_4d2c157f8b0b49e57c3e9b5abc9deb0f,\n\tTVP_Stub_4b7eaccf64af0f3a4c4fe64f4e2dd3fd,\n\tTVP_Stub_3a4d2602c392a8d1f4c38d537a8c95e0,\n\tTVP_Stub_8d915d35ef8e857f245c5d46798618e4,\n\tTVP_Stub_1e463482afa8ca30f5fa7bea4fa5741d,\n\tTVP_Stub_fdf270e4080c986abd1649fa9fffdeab,\n\tTVP_Stub_972e0f9a6ec4648a9fb82bcf5d9095ff,\n\tTVP_Stub_9d76731c37c4664d654db026644c64b4,\n\tTVP_Stub_4f1620cb699874b9c8cedf6e321c606e,\n\tTVP_Stub_ef1c6b2b601d1b0ff70272a4d447aa3c,\n\tTVP_Stub_9b7872860c95cfdafb056ab30318e99c,\n\tTVP_Stub_53360f194a04fc142ddae2b9a3ab4c92,\n\tTVP_Stub_ce1dcb05e5e7c4cafbc4ed37f63b256e,\n\tTVP_Stub_841ce4492b37321eea0c1b500de9b352,\n\tTVP_Stub_61785de870894968cd9d95e17e88eafc,\n\tTVP_Stub_ad3236e727398311c3b8e1ddd5f4b293,\n\tTVP_Stub_80e0b7be488545ff9b8bc52c9ab5fba5,\n\tTVP_Stub_4eaa3e4efb319707db6ef81db1c6f147,\n\tTVP_Stub_693a0152f098caee7fc77f545dd3e954,\n\tTVP_Stub_42840710f5fba9bb32b95290b1796a55,\n\tTVP_Stub_adec3f9ef429aa9a284081f0fc6a1b5b,\n\tTVP_Stub_674a7948152a1d7a49050b9d98796403,\n\tTVP_Stub_aa6f132b2031c83062f6149c90f2df5f,\n\tTVP_Stub_b52f446e22bb92d495f7e65ac71c9bf9,\n\tTVP_Stub_d4899fd4a8beb06f192dcb1d300e3319,\n\tTVP_Stub_d3f5ec78464d29ee6988a1f90c2e3e1b,\n\tTVP_Stub_a463ad6a757c3f04e09a72e288737d06,\n\tTVP_Stub_27857bb89d35113183b682c3917d6c7a,\n\tTVP_Stub_a5f80951cfb882ac6a3e06c0b9a95807,\n\tTVP_Stub_35aadb63079c8bd84ebc0389bae306e0,\n\tTVP_Stub_fb6573df5887c2020ae58136f8342ed4,\n\tTVP_Stub_86c67d2197c46824ab10f59e568ad13a,\n\tTVP_Stub_263a0c5b335b2c4d5bc1f55b51b8315e,\n\tTVP_Stub_975c1099e57ab67122ddef0f44fd7dd5,\n\tTVP_Stub_04493e5237a7ca97afd391cb7e831ba0,\n\tTVP_Stub_9996100acc7705cb2b0c904d6bad4401,\n\tTVP_Stub_5d91cff3b2a26ff7c0543e0f6d737117,\n\tTVP_Stub_ef1dedc2cb58dc4e1afc14238b6fc518,\n\tTVP_Stub_f18397fe81c043ba2346e31b359f6a73,\n\tTVP_Stub_2ee45ad60b0c06a8d0feebc3a6aad9e7,\n\tTVP_Stub_44500491c57e17032951fe6ed268ff1d,\n\tTVP_Stub_056f5d278c75750df792bf8b081fbf7d,\n\tTVP_Stub_04233bc4f7d4df92c260d23110320afe,\n\tTVP_Stub_cdc475c4419e77c22508e337428c4074,\n\tTVP_Stub_06bacb2910308a47bbe27ff7efa1226d,\n\tTVP_Stub_521e053199a4aeb4e0f24d9f4a6cc682,\n\tTVP_Stub_02164e6fb4c925843ac774ec1e4c6e5d,\n\tTVP_Stub_5110cbbcddbd9688281ee5418e3f9023,\n\tTVP_Stub_1db54b61f00bf931452218c4a39e79ef,\n\tTVP_Stub_9d0edd8f51f155767301017bd3d256da,\n\tTVP_Stub_8f744c5aa8df5471939b960bc759f12b,\n\tTVP_Stub_ba7ff7b0b4192bd2cc7f49c7b688ad57,\n\tTVP_Stub_7773ac921bb82c85de3be69ef86265fd,\n\tTVP_Stub_114a781ed71edace31abb352a2671f41,\n\tTVP_Stub_2bc5f4a97decfa82c625430479ec512b,\n\tTVP_Stub_066fb79f94523d95d12480f23c58cc8e,\n\tTVP_Stub_803906b8de16ff825d4e69e1952d872f,\n\tTVP_Stub_34cc96a5118ee1e12b0750ea64d40b1f,\n\tTVP_Stub_dbe821fb8b651d42a9c8e730517c408c,\n\tTVP_Stub_8970ba46068ac74746c3e84299937d8f,\n\tTVP_Stub_438e27dcbb077284213eb4d7dcd43f8f,\n\tTVP_Stub_a98d712ca19a49afe07d0a7c5d064cef,\n\tTVP_Stub_08aef69683bcfe2a5c63d4c7866de8e9,\n\tTVP_Stub_dbc9bc2e27068c8426b1c6a7f89424e0,\n\tTVP_Stub_5eeb98ca016123f57966457533bb639e,\n\tTVP_Stub_98fdc846d0b4a83412f3521f65bb98b4,\n\tTVP_Stub_3309591d3c7f6f688e81588f169dba21,\n\tTVP_Stub_d83a866389246d824efcc83303a04484,\n\tTVP_Stub_6cf6f332a6a14a15e8dce62301f5c840,\n\tTVP_Stub_566eeea3c5f009b0fc6fa123ba30f496,\n\tTVP_Stub_88806e38e35c73b36acadd4061a4fe0b,\n\tTVP_Stub_3bb69d3886159aaecc333b6ff17287bf,\n\tTVP_Stub_3e36278551a9c8b29cb2e8017db6af0d,\n\tTVP_Stub_5de99d84f3dc902cb0812fb85a7d5c88,\n\tTVP_Stub_31e85cbc73f8fbd4cea895a751480059,\n\tTVP_Stub_6ae29e405ede762f1a89a9dd526cb36e,\n\tTVP_Stub_c95bd66d95c153cdac41b5243e555f5f,\n\tTVP_Stub_72a67e9c52fd27dbb66eded47efeea74,\n\tTVP_Stub_fb13e41bda53e4e59403e3e14effccd6,\n\tTVP_Stub_9a5c710e620e47f105752453ad5d6ab1,\n\tTVP_Stub_18f1ad16c11429707cbf8ea4d1d4a21e,\n\tTVP_Stub_550f317b573a1256af00586890ae82f1,\n\tTVP_Stub_cd50da721dfb63f36c1ebb1226830428,\n\tTVP_Stub_fbba3dd6a087599d1277ae58f6cec18e,\n\tTVP_Stub_43cc5b5a61a6090af83333d115b5b868,\n\tTVP_Stub_616fb5060d81eb5bab58647596582df4,\n\tTVP_Stub_168cf4c1b9ef70b98f2e0ab3695a4f3b,\n\tTVP_Stub_314573cca30a7c2aecc9166fbf5400c9,\n\tTVP_Stub_03da356426c038fad663c836c3e330ef,\n\tTVP_Stub_31dbebdedc08d75e34a2cd564ce60586,\n\tTVP_Stub_d9224ad7a0de743a7eea15fdb2c5f934,\n\tTVP_Stub_c01b0720b49ce4f792446d8965d2c31f,\n\tTVP_Stub_4af47e46a11e1357cb994f405289d13e,\n\tTVP_Stub_25b6dafa19bfa5bde1a8b519da248f82,\n\tTVP_Stub_72425405819c900aec719491cbd90c6d,\n\tTVP_Stub_a79942af73f33bff6e432c9fd808e469,\n\tTVP_Stub_df106470a4141ebc7eda22160859ffdc,\n\tTVP_Stub_469bc225b0ecd9561aae5a46b85ded42,\n\tTVP_Stub_a6663c078b3aa79b39ee2d09f3875765,\n\tTVP_Stub_efbe634ce4f13633e220cae167cf63fb,\n\tTVP_Stub_57f4147bcc09e4e4442ffc9b0895727e,\n\tTVP_Stub_1fb2d2e44cf83aebef7b26fd6b20bc2b,\n\tTVP_Stub_bd6aa777bac947f5cffd891e9c724794,\n\tTVP_Stub_83c662330b75d616cdc8a4e11d7ababa,\n\tTVP_Stub_bbde02fe30c8a6cadb7073174ea3a874,\n\tTVP_Stub_cc1c14f63867f90bc883de03e9212cbc,\n\tTVP_Stub_236e007b32bc2631b5f6dc1eda6be0a9,\n\tTVP_Stub_cfbb9809e0e6d954b2652856e935ced9,\n\tTVP_Stub_60ee96ae4a7704340bef20fb35ba6ade,\n\tTVP_Stub_564b37278b50f4e5597dff6540868d49,\n\tTVP_Stub_890b3a4831b824653e919b4a5197358d,\n\tTVP_Stub_2dfa6c77c5051d160b8a06f540e0d68b,\n\tTVP_Stub_05f88567d510fd84659ccbf493f647ed,\n\tTVP_Stub_7166b8f7bb9688c980e4fa172f06f30c,\n\tTVP_Stub_b9456ecba8b7898d80d2e5caa64035c9,\n\tTVP_Stub_dd44464bd8430a5be5fef0cffcd97117,\n\tTVP_Stub_a57696ca0c157cd7d3cd4e58c1df957c,\n\tTVP_Stub_1aea9f8a38bbb875b6d052f330da9178,\n\tTVP_Stub_2d3b3d6e22ee139cda9eee47dc031945,\n\tTVP_Stub_8ff49e56c3c4c566561dcdd5c9ecc4db,\n\tTVP_Stub_490b547e93e40082d0b83312467104f9,\n\tTVP_Stub_2c1ef06748df47df52b586ac0fbc6a34,\n\tTVP_Stub_b6b2a03160b88239eccd18d89b1537d3,\n\tTVP_Stub_8becefbd52c76c7ecb0ea7b7f50b7915,\n\tTVP_Stub_74b9687a3bfd3b2c7abe226efc4225c1,\n\tTVP_Stub_7cafc2bf5965b594e60830e3057bbd58,\n\tTVP_Stub_80f111939c5694cbf43d07cf0ad1726c,\n\tTVP_Stub_8dc9cef84191f79b38403a2070952fd4,\n\tTVP_Stub_1d42bd1e659b36886c20567497b7ee96,\n\tTVP_Stub_0848fbdc7eeddb12c80bcd9c31383a64,\n\tTVP_Stub_1f1123c906c28ab6d16b6bef3f7ae978,\n\tTVP_Stub_b84394e20cc73a90349cf5be4e783111,\n\tTVP_Stub_76e0db3797851fe8ff90cf84780c50ad,\n\tTVP_Stub_6616241156c22bced42cd9f2f647677e,\n\tTVP_Stub_1ace346a3dd546c66ad115a33d8cf693,\n\tTVP_Stub_96fb9bbe33531d4268573355c658e165,\n\tTVP_Stub_c90b5737134c76f9ed0bb5da7cfaad8c,\n\tTVP_Stub_070ed05259a265cabdd82bfedabdd638,\n\tTVP_Stub_008b7e3a4c5bb23ee991f684a5064737,\n\tTVP_Stub_b64741dc4544ed43c44ddb6d0eb838ea,\n\tTVP_Stub_5b83e28b2d9ab0f75d7c7f6f61b5ded6,\n\tTVP_Stub_b948c9f43837efa489b0b91f3f675710,\n\tTVP_Stub_eb83216f6f718245468ef48b97ab4c2d,\n\tTVP_Stub_c66ab4868b743de9c0ba8b26c67b23da,\n\tTVP_Stub_586e16d502a6ad98b08161bdb090f8b6,\n\tTVP_Stub_d8bc9c71c80b200c39b29167d795cad0,\n\tTVP_Stub_85df4beb87f6503891e116ce046353c3,\n\tTVP_Stub_35b6a7e1c73f257aae91e05fa9826e84,\n\tTVP_Stub_a25b46701e25030af1ed847e0df229eb,\n\tTVP_Stub_c8906bf1efa5e86f9fddfab55a01c8f6,\n\tTVP_Stub_8141059f613820f694608af28e20cbad,\n\tTVP_Stub_cf2690e47099ac6378ed50df4a8a8e90,\n\tTVP_Stub_810c7054e44f535cf250f00707105417,\n\tTVP_Stub_52a9af7905ddc71d8b4e0ef7366eebdd,\n\tTVP_Stub_1635dbae2d91b338ddfd0430f8aa7f10,\n\tTVP_Stub_30df0c29ad8f672f7fe0742b4b11cd7f,\n\tTVP_Stub_61c82dec644c58290a25f34a69478870,\n\tTVP_Stub_f08e347d2d47dc5fc9a3cb59355b4fbb,\n\tTVP_Stub_5c62e59c2062f658d4c79d5257a9a586,\n\tTVP_Stub_259c72d8bfed1210ca71c54f24cacc7a,\n\tTVP_Stub_801a92ace08eb7ed001406869a39a75f,\n\tTVP_Stub_e22e647af4ded8e51b1e76c845b4c8e2,\n\tTVP_Stub_12902221314df9bcf7f7cb74a5242fe0,\n\tTVP_Stub_b10feea1619ba8ac11237c12002cdb3e,\n\tTVP_Stub_19755b50d241edcb477bdcac22663778,\n\tTVP_Stub_040a0ecf46963e094ee8ec32ab3f1962,\n\tTVP_Stub_525c529dc687b5d86424d775d00bdfce,\n\tTVP_Stub_c96107b91e2a215f560a2612c6e85931,\n\tTVP_Stub_b8788eaa2ca495263c6ea2df264af5f5,\n\tTVP_Stub_4c6494008c520d896d699f82aca30b25,\n\tTVP_Stub_7d8f8d5e0832ecf248b19a89801ead0e,\n\tTVP_Stub_70849965060a6402f41b0b11ec2bb3a7,\n\tTVP_Stub_c72efa6b4efaa6664ae637a03e98e866,\n\tTVP_Stub_a250e46575d0df1166e1542613218a5c,\n\tTVP_Stub_a7bcff67b8d380c225b9d0d83921b3ae,\n\tTVP_Stub_fb68a3aa16bd2eb7d7550283170321bf,\n\tTVP_Stub_35b4299ede11f511b331b713ba9f38a8,\n\tTVP_Stub_efe52691cff20b2dfaa16e8e16caac0a,\n\tTVP_Stub_38eed43ef69251c34dc45695b8cf35c0,\n\tTVP_Stub_2058b65abdfb7598910f0d584d40a19d,\n\tTVP_Stub_1ebecaefe2ffdc811fccbac42e67e544,\n\tTVP_Stub_09e0f0912f8d758d3736ece9478c2686,\n\tTVP_Stub_23d61eda3959b087b618e348471e2c36,\n\tTVP_Stub_e99b22c79b5bf04f3382f959c7bb69ca,\n\tTVP_Stub_9c4bb9ebee4db0fcebeae11c34950f97,\n\tTVP_Stub_505a9563aeb1b0255cfcc8197bee7d9e,\n\tTVP_Stub_f5ab80fc67ee04570330b9035144e760,\n\tTVP_Stub_af50188bbaa019ee88b19ecd931f7cce,\n\tTVP_Stub_268c452e85a6ac75301a6132f4f5e38b,\n\tTVP_Stub_646770a19b1768b372c9991ef0d3de85,\n\tTVP_Stub_5ec88e04fcb8e1877752281e172173ed,\n\tTVP_Stub_923f8161f2d2ba0e883bc4edc2901960,\n\tTVP_Stub_6f70cdb7586cbe571204f286f43c9780,\n\tTVP_Stub_9a4eaa6a627038799015c093609bdde7,\n\tTVP_Stub_c8bb6590f4a7adc906d7b3e42d907267,\n\tTVP_Stub_8323d57f26876d87271dbfa257b7f7e2,\n\tTVP_Stub_4d6f148e8997e1ae0cc0006ec1bd9618,\n\tTVP_Stub_7f03a4ddb254d0518642d15513eaea85,\n\tTVP_Stub_4add3926c72ba9df9259be58b680de0d,\n\tTVP_Stub_075d42cff8dc0c1fbd99c7459a63e526,\n\tTVP_Stub_b6bc45b28e194c7ac98bfdea88edee36,\n\tTVP_Stub_6dff6abb075da1a304520e60c011ef7b,\n\tTVP_Stub_892ffbdb8375851fc557e4abe9589b77,\n\tTVP_Stub_b2f3538284fc2adda2a43272ee654a96,\n\tTVP_Stub_e0ff899ea4a9cc49a0e3b38deaf93b45,\n\tTVP_Stub_4b9c9ac2aafad07af4b16f34e9d4bba2,\n\tTVP_Stub_c2e423356d9ca3f26f9c1d294ee9b742,\n\tTVP_Stub_c07314686fdf5815ce9b058020da942b,\n\tTVP_Stub_4a197be1985d45ee86d5672d24134560,\n\tTVP_Stub_dec720a9c3cd2b378f195cf71a9ff8b0,\n\tTVP_Stub_5726a5c7af641ebaa504dc9ec8380938,\n\tTVP_Stub_1c53bc96ac9dfd483c2227bc5fa44825,\n\tTVP_Stub_1940c8fa03145aa029d0b7718ce0c809,\n\tTVP_Stub_b37f047c0f9bd143b34a2fc87ce5f16e,\n\tTVP_Stub_dec35fbd2a24fc32e5c220174d864cf4,\n\tTVP_Stub_86fd45a126296891aee413388597203e,\n\tTVP_Stub_603243e54f3508c37d993e8359b735dc,\n\tTVP_Stub_c3eadbd75b32dabe6faecebf492eb486,\n\tTVP_Stub_725e49de1d970ef04b179776666f2c34,\n\tTVP_Stub_55a9b73f877bfd4c6d8157e7b1c458df,\n\tTVP_Stub_d070209f152dd22087e6e996e02c85cf,\n\tTVP_Stub_308f905626bc51c7ef9b65b2c0ca34b2,\n\tTVP_Stub_95aab2a1ac9491e8026f4977e0918760,\n\tTVP_Stub_e0ac94325eb783ca2fe7856a54444c90,\n\tTVP_Stub_0c99a79e866f08b4df3914e83fc203dc,\n\tTVP_Stub_f2de531a016173057ff3540e47fed4e6,\n\tTVP_Stub_4224a9066d8d13d6d7e12f1ace6a5beb,\n\tTVP_Stub_900476efbc2031e643c042ca8e63a3d7,\n\tTVP_Stub_07dfce61d490cf671a2d5359d713d64a,\n\tTVP_Stub_52d30ac8479ef7e870b5aff076482799,\n\tTVP_Stub_8e4d0392ed46e87f94e5fcf675a124a1,\n\tTVP_Stub_73f46e08d17e707725f433b454f05a89,\n\tTVP_Stub_80d60e682fa72973071e335db272a2a2,\n\tTVP_Stub_6bd6262185fa0b9cf1750f6a525d893a,\n\tTVP_Stub_cf29f737d4eb450b26789d421d0ec69a,\n\tTVP_Stub_13c0e371c08fd1b9da2f0c103d01c59a,\n\tTVP_Stub_82693e38df8f033ea98f9b7969d66d7b,\n\tTVP_Stub_6e3f8a3b18f55dae6153a889f00a3e87,\n\tTVP_Stub_efe14a197131b4813656d6669cc3475b,\n\tTVP_Stub_ba4ecf60f872f757b69c84f457b3e941,\n\tTVP_Stub_dffedabe32ce886e3b7e695b44ad3547,\n\tTVP_Stub_f518c60b165658d19a0fadd8f69586aa,\n\tTVP_Stub_6fefcb1c2ca01a876c301ab41dbdab9f,\n\tTVP_Stub_df55083347df0483b4ca6ba1e4f0b9a0,\n\tTVP_Stub_d8d28310f702714733c4c5dc850058df,\n\tTVP_Stub_52d24c38b05be174bc5c4fdcf02e9b9f,\n\tTVP_Stub_f27f455c8f30cbaf1706faac3c7b8e02,\n\tTVP_Stub_78ec453a50b2800bb01347e8ebbac000,\n\tTVP_Stub_0936d0f6fc53339d255893e58bcc6699,\n\tTVP_Stub_f4f7181b7fd679784c50b0cc7ba4c60e,\n\tTVP_Stub_79816d7e5741c2416fefe2c2a8baef00,\n\tTVP_Stub_42a3d248fab928f16555abcceca62834,\n\tTVP_Stub_926d6212b8b1b238e7bef9b17a3ee643,\n\tTVP_Stub_236e3d626784d80ca2cc5b2fe14cd9c6,\n\tTVP_Stub_1bfac11a5f95c842f97a8bb57d4019de,\n\tTVP_Stub_198ce21c54b0cea4c1bf5eeba35349ab,\n\tTVP_Stub_590a1ec7f64904eaa32b5c771bb5f8cd,\n\tTVP_Stub_dd13d4bc2b48540a92f047bf015b829b,\n\tTVP_Stub_0ff502d492598d2211405180bfb4d1e1,\n\tTVP_Stub_cf5401746759bfe38918087aaab6c57b,\n\tTVP_Stub_04e84aa7d8cf0477d55c700164544b38,\n\tTVP_Stub_449039d3afbfbd52a63130a3b227a490,\n\tTVP_Stub_347a4fa85af84e223c4b61d33ead694a,\n\tTVP_Stub_4ad1dd24b3b4769ee10149eea006af7a,\n\tTVP_Stub_b246b17b62d273bdc04e9d9e827f5c74,\n\tTVP_Stub_9974ebc6296f925cff55d8bcb2d52ce9,\n\tTVP_Stub_0e0c9d9107d8c56b8bc4d4198ae9208a,\n\tTVP_Stub_c23ece207f6ec2dd7c76ef873047aee3,\n\tTVP_Stub_81507020bc646be2f53ab95b9430ba27,\n\tTVP_Stub_acc0d3861d1b971abcbdda1c075dd681,\n\tTVP_Stub_ff2dccead1b31e3f34e8be3e2ba5bbf1,\n\tTVP_Stub_e17db0d4f69625c61aba7fffe540dded,\n\tTVP_Stub_5bbc872e7bba5b761c509d31116e4460,\n\tTVP_Stub_4adf361303eae78829250c7b732a5722,\n\tTVP_Stub_bf172364c57c1aa561b145fd5cacda0c,\n\tTVP_Stub_d7687aa80dac10f88deac7aa7e70538a,\n\tTVP_Stub_b18b7259f98029f745c75291d6855ab1,\n\tTVP_Stub_b79e5d877116025576ca1f76af124009,\n\tTVP_Stub_8aea098dfe8a36c705cc2a9e1a189b84,\n\tTVP_Stub_4ccd3f6ab60d61be6dbfc59e8e3d1726,\n\tTVP_Stub_3d70bb72a7d7765c7e8ea580079ab7e9,\n\tTVP_Stub_eba9b272d78a4b0cd7f9212e29a58607,\n\tTVP_Stub_cfbe8ee9d43aa64ae4190eac91f7c55f,\n\tTVP_Stub_a4308a386968ef5d23025ab8a9e8c6db,\n\tTVP_Stub_5a4fcbe1e398e3d9690d571acbbbae9f,\n\tTVP_Stub_5b62f504fe6d22428d7518d6c52d775d,\n\tTVP_Stub_fb3b405f8747b54f26c332b9e6af81cd,\n\tTVP_Stub_b7ccd11d130f186883c109d2ba17b598,\n\tTVP_Stub_cf8ab6c24f25993ccc7663e572ac2991,\n\tTVP_Stub_ba40ffbca76695b54a02aa8c1f1e047b,\n\tTVP_Stub_c97720e639e95ba5130ce9dd78d30403,\n\tTVP_Stub_c5557ac5391b1b831a22e64b65d1746c,\n\tTVP_Stub_3243a4c32d4f674f1bbc8d3895257568,\n\tTVP_Stub_78390a3d08879903ee9558e9df68db4d,\n\tTVP_Stub_58e9454d7096a52808f9a83b9ce25ff0,\n\tTVP_Stub_cdefadd0c3bf15b4639b2f0338a40585,\n\tTVP_Stub_4bf80e9bac16b9e3f9bf385b2fbce657,\n\tTVP_Stub_51aeacf2b6ef9deb01c3b3db201d6bf9,\n\tTVP_Stub_9ed5432d73448da47991df9577ee97bc,\n\tTVP_Stub_cf1d02d1cc1aff0aae6c038c95dac80f,\n\tTVP_Stub_ddb0e05c72c0692e78af885ac7ec82dc,\n\tTVP_Stub_a3029db6292616cd16c228b91dc4af13,\n\tTVP_Stub_2d90871c6bc15a9e8d97d24c29e78e3b,\n\tTVP_Stub_0af6744e35e38276d6a98c1f382b1519,\n\tTVP_Stub_ad40567a051208757642e5e087f3e741,\n\tTVP_Stub_6a15185daab9b274963fe5ef46305775,\n\tTVP_Stub_073a2332a8ab3ed31ab81daea3d3f2c4,\n\tTVP_Stub_01216e91225e06c7422bef0c2febc0cc,\n\tTVP_Stub_16ce22ad500a5bdfd5d5743c847a28b6,\n\tTVP_Stub_59251c4104f736fa2690c5f77fb0a908,\n\tTVP_Stub_f923750e0fdb51a6fc6c304832cb3dd3,\n\tTVP_Stub_bc77a1e312ff7827d90387fb92f0f5b0,\n\tTVP_Stub_2090afd7ae8bcb021ec4d04947d0d845,\n\tTVP_Stub_3a0f858bdf86199dc2d00b583a3b915f,\n\tTVP_Stub_0d316a141f7a502ff8d9ffe2d38d25a8,\n\tTVP_Stub_b31ff64ae2d8f93dbf28161d5080b295,\n\tTVP_Stub_d9b1c73516daea6a9c6564e2b731615a,\n\tTVP_Stub_003f9d3de568fcd71dd532f33d38839c,\n\tTVP_Stub_5da29a19bbe279a89be00e16c59d7641,\n\tTVP_Stub_c1b52e8f3578d11f369552a887e13c5b,\n\tTVP_Stub_b94ead6de9316bc65758c5aefb564078,\n\tTVP_Stub_8a35be936d2aca049e398a081e511c97,\n\tTVP_Stub_5b1fa785e397e643dd09cb43c2f2f4db,\n\tTVP_Stub_29af78765c764c566e6adc77e0ea7041,\n\tTVP_Stub_9e0df54e4c24ee28d5517c1743faa3a3,\n\tTVP_Stub_d3aaa55d66777d7308ffa7a348c84841,\n\tTVP_Stub_b426fbfb6ccb4e89c252b6af566995b8,\n\tTVP_Stub_c145419db7b63f7488ea05a2a8826c1d,\n\tTVP_Stub_d795cd5ebfb6ca6f1b91bafbe66d7a65,\n\tTVP_Stub_4564a3ce5cf48cb47e63a3948cef03be,\n\tTVP_Stub_bee2775f2e4042043b7cb08056d2ae5c,\n\tTVP_Stub_5fd8dfd2816a2cfd4a51cab41053d575,\n\tTVP_Stub_9982ebedc12d343cb098e2a7b25bdef1,\n\tTVP_Stub_81eeacbed5ee6129bef4b370e28b5d10,\n\tTVP_Stub_6ed1088905d99012d2fb5827ea19527e,\n\tTVP_Stub_b4d6c64cc0004ffaba804f0e8f02ab9b,\n\tTVP_Stub_2c3e08b8df93ec50451edd916c707030,\n\tTVP_Stub_eba070d1583ca5f5d02630ba33a5504b,\n\tTVP_Stub_ee474537852ce5eb165cb1761950faba,\n\tTVP_Stub_eed221c603243522667e2f1c6ace3ba4,\n\tTVP_Stub_1f973c5e3cfaf00fa752b7e22d7ba481,\n\tTVP_Stub_b9d5260bba9edd7503f1adf882218979,\n\tTVP_Stub_aedbd2eda61145de808e295331884245,\n\tTVP_Stub_ce0f184e84752eb279e4f900d8b53c18,\n\tTVP_Stub_0217d49393163b80897d044c1d93092f,\n\tTVP_Stub_5bbd9d5b364840e9615af35a62f69d7d,\n\tTVP_Stub_2b2837e81fcaeec35f61a2a3ecf2fb2d,\n\tTVP_Stub_bb0706a78e9066944bfbffd1406be2d4,\n\tTVP_Stub_770e67c91215292980b88cc6efb9f2a5,\n\tTVP_Stub_068ab11f05731f2c2e9ea8c5fdb16a9f,\n\tTVP_Stub_b9873a0ad2653952cb2948b817e786e4,\n\tTVP_Stub_11d9804ae4db32d731af69c397769cbf,\n\tTVP_Stub_421f5aa6dbaaaf946f74942c77aac9bc,\n\tTVP_Stub_563ee9dcb14a2914fc246e64679f42b5,\n\tTVP_Stub_e23a54b6b80bd03111a40f669524724f,\n\tTVP_Stub_c90c8bbd18a7190636ae4269c36ad005,\n\tTVP_Stub_03c54a8e8c86e171f868a624e490691f,\n\tTVP_Stub_30b63f3cc59b39f1a71829bbbdf6e45d,\n\tTVP_Stub_705bcc30a0561ec679c2267e1a573b23,\n\tTVP_Stub_5c627d080007e455b0393a9b4457cd4d,\n\tTVP_Stub_72a64cecd44d80f95fc93faf0d239e32,\n\tTVP_Stub_ef838904712bfdc614dbc689fbe7fb18,\n\tTVP_Stub_acc97936adc40656e824cfdf7a34e20c,\n\tTVP_Stub_5ea1ba3602f9d9fee344de6c3406d7a3,\n\tTVP_Stub_d25f0771b8fc7715d69f01d950463a49,\n\tTVP_Stub_f8ab11c930782ce058e517d0440ec87f,\n\tTVP_Stub_b8157e369d53c2d944b76494980ced7b,\n\tTVP_Stub_aba94f656b4c1de827d11c72b36a5e9c,\n\tTVP_Stub_0656942f5a95783a4de73ca6e654d3b5,\n\tTVP_Stub_5c2b7d12713dd5a94ef8e6eff1f79752,\n\tTVP_Stub_6f1d30ac7e812cc5a059459c47638cd0,\n\tTVP_Stub_1d51684322635e7848ef53f7f6be8a1e,\n\tTVP_Stub_a1f2d56d138a4038fe1678328910a81d,\n\tTVP_Stub_c135ef491b533febfd49696d22a1dd3d,\n\tTVP_Stub_579117a873b466d78bf93e49c4a078da,\n\tTVP_Stub_ec8fa08705639eb7ae5d44ab63dea5e8,\n\tTVP_Stub_b49dc1cda6109256815dae7b4293725d,\n\tTVP_Stub_912a670f56707ac70f2fee13660c2af8,\n\tTVP_Stub_d0159986645df76b8c66fdb662efffde,\n\tTVP_Stub_cd7a2e6f91bf8d2daa3e28139d7d9f5c,\n\tTVP_Stub_676004ca892b2bfee6859d0bb132fdd7,\n\tTVP_Stub_d4b161d8a745baa5e2113669773a758f,\n\tTVP_Stub_ef7537293f6e3b6127480f6c5fd018a1,\n\tTVP_Stub_6f6f73b75cffe40a28566d1832ae1224,\n\tTVP_Stub_7adc5aad39e459e01543d07c239efe57,\n\tTVP_Stub_3ff6b480097eec3f5fdb7bfad685fd2a,\n\tTVP_Stub_b2c50c3a1dfea7e9d05fed69818bafc3,\n\tTVP_Stub_8024df9077e2c85b5b718ad2c87e57e7,\n\tTVP_Stub_989769d4eb8e42e9c9bbe721b296406c,\n\tTVP_Stub_cc1ac928b5c31570dfba7ed8f565be4b,\n\tTVP_Stub_62931efed5729a332e60bd1f7c7cecdf,\n\tTVP_Stub_53c18160b157088f72a9afd79737b48b,\n\tTVP_Stub_48135697fd7f4df87402a7dd4d761555,\n\tTVP_Stub_e2c71cf04e876069eb7315c800a96898,\n\tTVP_Stub_1f63c018cf805ca1168af192cf8a4b41,\n\tTVP_Stub_704a9574dafd3669e10d546549948e03,\n\tTVP_Stub_97905c510b9502c20c9322c9f5fb4188,\n\tTVP_Stub_b23e84230c4736667279c7a71f4ca53e,\n\tTVP_Stub_eb41fc900b0a6e3aba9d531f266137f1,\n\tTVP_Stub_5bd02c627b74bbb22d5a525b8bcbbd27,\n\tTVP_Stub_cc82e6a6b31ea743b9ebbdeed1ddedc3,\n\tTVP_Stub_247b25d497e48bc0191fdb2ac530f4ca,\n\tTVP_Stub_6bbea3af36c35631641cc8356ff65475,\n\tTVP_Stub_cac02dfd62ba94abf6a346bef0bf3ab9,\n\tTVP_Stub_68eeb36d76d88ff00014f04b23454254,\n\tTVP_Stub_65e03b1c849b6e9cb5c478024aa9a5b7,\n\tTVP_Stub_7670c0c5630625ee6a73b7b9ee093650,\n\tTVP_Stub_68a0abce6eefa08e74353ec48c4c87a8,\n\tTVP_Stub_ccb6e098b9a0791a0f20e9f1af55e341,\n\tTVP_Stub_0f817efe47b451fd719c05a104c2b803,\n\tTVP_Stub_efad1a3d774747bd2b5adb221ede2678,\n\tTVP_Stub_563285ed004ddd2945f91db7b5347d3c,\n\tTVP_Stub_4c032260ef83d44bfe05fdc16843a8f9,\n\tTVP_Stub_96fd614457f06499a430b0c6e0e8a941,\n\tTVP_Stub_d6e36d304ff7253088ab4bc1aaf13a98,\n\tTVP_Stub_eddacf49735189e23d9d49831851ffdb,\n\tTVP_Stub_20275a5de4aef464b85d3f6db2800063,\n\tTVP_Stub_872d1c626e6d4e3d5e86a257f0b14536,\n\tTVP_Stub_a7ebb70cdec339f26c2ea7fd9a471b88,\n\tTVP_Stub_d748ffef5cde2a6a3333e75b7fa3fb49,\n\tTVP_Stub_15e1fe0e6230e7b60e216e266f927f7b,\n\tTVP_Stub_f8179eafd0cbe8116874310519207dc0,\n\tTVP_Stub_accbc3bed3223d552de2723366cfc2b6,\n\tTVP_Stub_e2c3e74d2a20a601c1f393348f58aeb2,\n\tTVP_Stub_e0163a6ca3397c2e71715132cccefa1d,\n\tTVP_Stub_2c3ea1ea88799dfde81025bf1959333a,\n\tTVP_Stub_a6bb56b3f4b7a89fe78d63956a0f444c,\n\tTVP_Stub_09a81ac18a121d8fbb67285a081bf9c6,\n\tTVP_Stub_46fdfe0f5369bf234c3ed60a43947d9d,\n\tTVP_Stub_d866cb6c8a47444bbac60eeffbfc6d96,\n\tTVP_Stub_7b5718fc67458089c685dbb900126890,\n\tTVP_Stub_5713dfe9525662357d3819229e0204c2,\n\tTVP_Stub_8954a6b4a7f8b378c2af16a00d5059b0,\n\tTVP_Stub_2ed4faa38db6f3dee0dea18ebe973d35,\n\tTVP_Stub_d0338dedb0af532d22f2075a85373548,\n\tTVP_Stub_583d57c3bb9491f8f9904c266d3f52e8,\n\tTVP_Stub_8ac206da43e322eb8e34fce2b0959656,\n\tTVP_Stub_14f5f97d90bd8da89b68d035367f4ba4,\n\tTVP_Stub_ac3b21181ef4c1be73cf5e0edb4e1a8f,\n\tTVP_Stub_1d7d97509292a4ca9269f2539dcc70fd,\n\tTVP_Stub_c4033f54a99517783b8d6ad23c90aeed,\n\tTVP_Stub_f19e38d48755c971fc35408ac65562fa,\n\tTVP_Stub_e01204e226d8aa9520b3620b68da6196,\n\tTVP_Stub_b50000da98f1257cf789fc63fb1fda02,\n\tTVP_Stub_c55f38b1a7623646aa5cc45d4f4f479b,\n\tTVP_Stub_983d270549ec0e83e2a863b43e1e6f70,\n\tTVP_Stub_b48d779dc6a881c67c5f8fa12655aa28,\n\tTVP_Stub_d3967c6e24d0c4ad107a03c1cadd57b1,\n\tTVP_Stub_6b6f416b5725a7cafb4774ffc3a00f10,\n\tTVP_Stub_bc7fc5dfa228152a09d2230823c2fe71,\n\tTVP_Stub_a1cb941317b947beb88e29fa8d46a2be,\n\tTVP_Stub_8e185e82bb27a7fb40f0b08f560a57e9,\n\tTVP_Stub_4b7b264b61ee0eea68213934217f5865,\n\tTVP_Stub_e872f12593d6853ebdffebbb5d003c10,\n\tTVP_Stub_e86fcf60fa658129d937de3728d3c432,\n\tTVP_Stub_350741a7398a187628866f5b397c7a99,\n\tTVP_Stub_3b5a3e187077b0b5eac9a040c99dd9e7,\n\tTVP_Stub_2d9b2bb2cd57220048fe170f1e960cb7,\n\tTVP_Stub_260624e275a20115e8861eb7b0383971,\n\tTVP_Stub_15b31724287dbbecb775b2e46dc35fb9,\n\tTVP_Stub_ff652293eef07b5a7ec4f372e5504e2c,\n\tTVP_Stub_99b773033e9a2c631b483d4d0e3881f8,\n\tTVP_Stub_3787960fc29b8545629d894ff46d4641,\n\tTVP_Stub_3fc76257bb1639de4bfa0c0fcedf9c4a,\n\tTVP_Stub_292ee2eeb8131e34368ba9ee144b737a,\n\tTVP_Stub_ec144655bc61bfa2c6e9505cc1a0a298,\n\tTVP_Stub_230218bdabfc34178a8306a54276a3c8,\n\tTVP_Stub_617dfb046aaf40078ee76715fa4756af,\n\tTVP_Stub_8116bb2b26dcafd9fefca76e9f1d9b24,\n\tTVP_Stub_12962f857563cd39b3cb1f9894775cc7,\n\tTVP_Stub_50c0d25cd9af311a5fb0aca78f691c3b,\n\tTVP_Stub_6c37a1ccda816c4fbab4f0117ca75e8a,\n\tTVP_Stub_e21c21762dd0e36d6f7d2cedaac97383,\n\tTVP_Stub_487ee86557f94113db9a981e08d29caa,\n\tTVP_Stub_dfdfe0e494845bf484612cc97145f85c,\n\tTVP_Stub_e74dc11dbd56fb450eed1388a65d3102,\n\tTVP_Stub_6981c02247de5799ea7dfbd79fdc208d,\n\tTVP_Stub_7c559043315f6ecd7a86ec7d8d820f6d,\n\tTVP_Stub_3a8b6aca73c83d6fc9ce813661ec734d,\n\tTVP_Stub_20d7ce65e240b745b10616bb5da1f897,\n\tTVP_Stub_f4d1217249674ac9274d358c381afc0b,\n\tTVP_Stub_ca77323bbe361f88f68536018fa94c50,\n\tTVP_Stub_17983ecc7e7fe370bce664281a84c948,\n\tTVP_Stub_61a2f61030362903d00ba21a3cebecdd,\n\tTVP_Stub_e9f985403dbd18540d8230a2af6ed76b,\n\tTVP_Stub_be0523c9a72ba26cb4bfa3cb188cacf6,\n\tTVP_Stub_8ac7cf651223c8ba53df90cf4f3d3bbc,\n\tTVP_Stub_873e73aa35096ad4c684d394a10135a6,\n\tTVP_Stub_3342548f105147c86019ae31ece01d4e,\n\tTVP_Stub_607ee0956cbb16b2afb7cb2227aa6267,\n\tTVP_Stub_816d84c86e86d5e7c0018d551e741e4f,\n\tTVP_Stub_985fcda0141eb3b4c6bd8342e947f130,\n\tTVP_Stub_d00e4f9e493334d2f65ea379ff03d717,\n\tTVP_Stub_0c246e6c7c8798e4c10d2bbfc66326c9,\n\tTVP_Stub_501015843a83368b3ff1c7c9ef5f3bcb,\n\tTVP_Stub_61d5fc5a060f346752a3a8b6886d17bc,\n\tTVP_Stub_0debe3e1caf0f57572a59917851676d3,\n\tTVP_Stub_ee3a36682f48639166ba04a19fe1b332,\n\tTVP_Stub_4d99b9e38121251b40a90cd2bd5fea63,\n\tTVP_Stub_f1509827696ebf5627bee1a45d675fb8,\n\tTVP_Stub_bbb625e23229350453161810c41419dd,\n\tTVP_Stub_489a6aae30de0feff5d3c5fbd42ae325,\n\tTVP_Stub_6b9a349305f8c689dcfdbcea2566769c,\n\tTVP_Stub_6320d208ce1a570aca52c3cdf7421f7c,\n\tTVP_Stub_0f83f0459badd1cd352041b9243d712f,\n\tTVP_Stub_186a94b2fed609ed2d2a7ac1a2bed87f,\n\tTVP_Stub_bde8efb9971664f2b52fe912745e2791,\n\tTVP_Stub_386d6fa5cb73e3519b62d20470e5414b,\n\tTVP_Stub_c61f97ec3d99bdbb23afe93870001bbf,\n\tTVP_Stub_f92821f2b23662c6f1256511a626cd3f,\n\tTVP_Stub_76b0732e3e2886897d5f26b4b0545dee,\n\tTVP_Stub_903ed11ef3863850e837bd4b3b1d61a1,\n\tTVP_Stub_2661124b39595ffafe2fb0bfb7bd2efc,\n\tTVP_Stub_d0b7170e54398c2f9d27dcc513c4cf46,\n\tTVP_Stub_31bdd2a1eed3785c1422fab5ea6b3ce7,\n\tTVP_Stub_dbc300d1dadc1a60cb0dcadfb92f1aee,\n\tTVP_Stub_1d4d9f8bdf55bd4c78abd90656af0364,\n\tTVP_Stub_5c7049e712e84b40ac05942421202de5,\n\tTVP_Stub_5dca8992bb340d70ba65ddab65c28371,\n\tTVP_Stub_85f1f38f783ebfcf638f3c443bc9b204,\n\tTVP_Stub_7d61d143884bfa4b6c50dae11c2b659f,\n\tTVP_Stub_793a2ad7ad3411be3670576a8e6ddcf8,\n\tTVP_Stub_68d8eec33254f1684e53bbc0aa8b2466,\n\tTVP_Stub_b09652d2197b29f7d38aff0298c69f17,\n\tTVP_Stub_be7db03ddcf1886cb7233e58f19c8c77,\n\tTVP_Stub_b4c8fedc1ffbe30d9703cb2b8d3c0e7b,\n\tTVP_Stub_77efef3b4ffc0cb577b76304e06e39f3,\n\tTVP_Stub_0e55187bde599d6585eaabd2c4ac3f02,\n\tTVP_Stub_f72e3fc3b97a9141b6f516f5e53bf9b8,\n\tTVP_Stub_e7a1ac237f00bb6320d0e0ac7e6d51c6,\n\tTVP_Stub_d87682f6d691350878077bd101b7f0fc,\n\tTVP_Stub_d7ae155eaabd8e65d6b4d356fe4af496,\n\tTVP_Stub_be3a1844ea6af533bd4e7b0a76c826a1,\n\tTVP_Stub_aa531d2c3c87f456e48a14722faa1c1f,\n\tTVP_Stub_6889cd886e1c2e7faf541528636c16c3,\n\tTVP_Stub_5d9266e6a8a154fe4ba80b0995e109ab,\n\tTVP_Stub_a7dc19b023737979ad1ae1ae01d560d2,\n\tTVP_Stub_d20444b7a6243d668a0d3956d95af510,\n\tTVP_Stub_1458dec9eee36816c8002d4049840355,\n\tTVP_Stub_21137ff5351245b1611852301b7f5796,\n\tTVP_Stub_c07fc4e45fc2dc44d839c5e012d0be60,\n\tTVP_Stub_6815b962a3122ae967284239932cc656,\n\tTVP_Stub_e96cccbe1f16b0fb74673f2ec3343ff8,\n\tTVP_Stub_e8cd7494f919b18a992cb8c2722b2bf0,\n\tTVP_Stub_990fdefcafc0de5e8e1f502c1b341e44,\n\tTVP_Stub_de5d83ba307e822825062377fb76c2ba,\n\tTVP_Stub_5e28bcc0f5ad6a038eb5a6535b56386c,\n\tTVP_Stub_e33419e8ede4bb501ab1787cf17c7ca5,\n\tTVP_Stub_1cd7cb9580c0cf723dea402b85a720b1,\n\tTVP_Stub_d18ca17fad389ff60ce3caa769083798,\n\tTVP_Stub_0a959a5ff02530a8eb122e7e1f8ceed3,\n\tTVP_Stub_a4774ea559e64b4667b3845f8540d207,\n\tTVP_Stub_52eae3e8106494bfa604c15492ecb9f4,\n\tTVP_Stub_882f458df5e05bb9ab2222e79f6c81cf,\n\tTVP_Stub_6069a18bf7d3f394c230cdcf2f574ef4,\n\tTVP_Stub_75b60565caf44027cc52b2b5cf6b0ea3,\n\tTVP_Stub_9d735149c3ad586363895f76645abf2e,\n\tTVP_Stub_ea5168fae254acdd8c8db6f1f3d2da03,\n\tTVP_Stub_f5a42bd5239e1a0be29f92eb838d2c8c,\n\tTVP_Stub_7cc8cd9f415b183b42c546635aeade7f,\n\tTVP_Stub_ad2fefa53e05528f9c1fe29d27db0f37,\n\tTVP_Stub_f3e06fed4c82a9bd1b53252abaf50847,\n\tTVP_Stub_960db7ea36202bf7ec3bf6b767cc045e,\n\tTVP_Stub_7bf5d357eb52dd206a269b54c8136e0e,\n\tTVP_Stub_ba1c9b771c5cdb725128de684af3c9ca,\n\tTVP_Stub_69cc6311196adc134fd153c4c5346bc5,\n\tTVP_Stub_8ed68f8e79efe1c767f92e7d92eb8b54,\n\tTVP_Stub_60da1e9ec15b251ff18ddcdf8a3e93e0,\n\tTVP_Stub_ef47304bad87a036e38f0319b48c1f6e,\n\tTVP_Stub_182d19020e4e2d5cd1462d7c8ef24d1f,\n\tTVP_Stub_9e1fa429a92a5c99d397a06c20fd6705,\n\tTVP_Stub_74ac7c291299eb928aa4c2899df5567e,\n\tTVP_Stub_fb645d9ec0ef3fd2aba2b762ef6b9a15,\n\tTVP_Stub_f988626275257574050ac789f9060a3b,\n\tTVP_Stub_1831064ed23493cef407648763ba4d69,\n\tTVP_Stub_305390c94750daa7124db3ff6e77931c,\n\tTVP_Stub_4fb384a391bfcf6a3a2932661d3051aa,\n\tTVP_Stub_305537c4820e23cf217a15efb56dba1c,\n\tTVP_Stub_aacf83677ca7df75117f7bafa7a53791,\n\tTVP_Stub_d14b922fefc6c07aa536b94762579fe5,\n\tTVP_Stub_00fd650a79c603bdeb2f8e36f667a782,\n\tTVP_Stub_a36ee133c07c30185b0bbc6375954e88,\n\tTVP_Stub_dc657ecacf8e578870314427216864d9,\n\tTVP_Stub_e79d02b58a8bfdee439bc0694d7edd6d,\n\tTVP_Stub_6b7537b66b71d27384bea45bc2bf24b4,\n\tTVP_Stub_b3456dbad652b52f5bce1889b6f4d0ef,\n\tTVP_Stub_9a50803a03e1ccb60120dff8b92ecdcd,\n\tTVP_Stub_0f6b3940dc72e3e56cd15216b53b9126,\n\tTVP_Stub_23b647f1c825e214a7465de3ebe9968d,\n\tTVP_Stub_8ec96bc7b777180f23e1a2e43bf9a413,\n\tTVP_Stub_cffd45014652659638d59abe11daf3be,\n\tTVP_Stub_a784285a35b1bc76bb367305b5099e35,\n\tTVP_Stub_03773751329896facf2003ab79bbc475,\n\tTVP_Stub_923884216edf134d07d8e70f8f57e827,\n\tTVP_Stub_e48798dc69498f80b6633bb405eda6eb,\n\tTVP_Stub_998a5e1aa5cd85689795348fc540a655,\n\tTVP_Stub_5f6d263c0d48d03f6eb0dc44c9dd0be2,\n\tTVP_Stub_bf363ba3d5b54df9d6df35a518deb6b0,\n\tTVP_Stub_6cc8a24cc7ce23179d1d4ccab7a8c97b,\n\n};\n\n\nvoid TVPExportFunctions()\n{\n\tconst unsigned long compressed_size = 5173;\n\tconst unsigned long decompressed_size = 42625;\n\tconst tjs_int function_count = 653;\n\tunsigned char * dest = new unsigned char [decompressed_size];\n\n\ttry\n\t{\n\t\tunsigned long dest_size = decompressed_size;\n\n\t\tint result = uncompress(dest, &dest_size,\n\t\t\t(unsigned char*)compressed_functable, compressed_size);\n\t\tif(result != Z_OK || dest_size != decompressed_size) { TVPThrowInternalError; }\n\n\t\tconst unsigned char *p = dest;\n\n\t\tfor(tjs_int i = 0; i < function_count; i++)\n\t\t{\n\t\t\tTVPAddExportFunction((const char *)p, ((void **)func_ptrs)[i]);\n\t\t\twhile(*p) p++;\n\t\t\tp++;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] dest;\n\t\tthrow;\n\t}\n\tdelete [] dest;\n}\n"
  },
  {
    "path": "src/core/base/win32/FuncStubs.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/* This file is always generated by makestub.pl . */\n/* Modification by hand will be lost. */\n\nextern void TVPExportFunctions();\n\n"
  },
  {
    "path": "src/core/base/win32/NativeEventQueue.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"NativeEventQueue.h\"\n#include \"Application.h\"\n\nvoid NativeEventQueueImplement::PostEvent(const NativeEvent& ev) {\n\tApplication->PostUserMessage([this, ev](){ Dispatch(*const_cast<NativeEvent*>(&ev)); }, this);\n}\n\nvoid NativeEventQueueImplement::Clear(int msg)\n{\n\tApplication->FilterUserMessage([this, msg](std::vector<std::tuple<void*, int, tTVPApplication::tMsg> > &lst){\n\t\tfor (auto it = lst.begin(); it != lst.end();) {\n\t\t\tif (std::get<0>(*it) == this && (!msg || std::get<1>(*it) == msg)) {\n\t\t\t\tit = lst.erase(it);\n\t\t\t} else {\n\t\t\t\t++it;\n\t\t\t}\n\t\t}\n\t});\n}\n\n"
  },
  {
    "path": "src/core/base/win32/NativeEventQueue.h",
    "content": "\n#ifndef __NATIVE_EVENT_QUEUE_H__\n#define __NATIVE_EVENT_QUEUE_H__\n\n// ĂяonhVOXbhœ삷CxgL[\n\nclass NativeEvent {\npublic:\n// \tLRESULT Result;\n// \tHWND HWnd;\n \tunsigned int Message;\n\tintptr_t WParam;\n\tintptr_t LParam;\n\n//\tNativeEvent(){}\n\tNativeEvent( int mes ) : /*Result(0), HWnd(NULL),*/ Message(mes), WParam(0), LParam(0) {}\n};\n#if 0\nclass NativeEventQueueIntarface {\npublic:\n\t// ftHgnh\n\tvirtual void HandlerDefault( class NativeEvent& event ) = 0;\n\n\t// Queue ̐\n\tvirtual void Allocate() = 0;\n\n\t// Queue ̍폜\n\tvirtual void Deallocate() = 0;\n\n\tvirtual void Dispatch( class NativeEvent& event ) = 0;\n\n\tvirtual void PostEvent( const NativeEvent& event ) = 0;\n};\n#endif\nclass NativeEventQueueImplement/* : public NativeEventQueueIntarface*/ {\n//\tHWND window_handle_;\n//\tWNDCLASSEX\twc_;\n\n\tint CreateUtilWindow();\n//\tstatic LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\npublic:\n//\tNativeEventQueueImplement() : window_handle_(NULL) {}\n\n\t// ftHgnh\n\tvoid HandlerDefault(NativeEvent& event) {}\n\n\t// Queue ̐\n\tvoid Allocate() {}\n\n\t// Queue ̍폜\n\tvoid Deallocate() {}\n\n\tvoid PostEvent( const NativeEvent& event );\n\n\tvoid Clear(int msg = 0);\n\n//\tvoid* GetOwner() { return window_handle_; }\n\tvirtual void Dispatch(class NativeEvent& event) = 0;\n};\n\n\ntemplate<typename T>\nclass NativeEventQueue : public NativeEventQueueImplement {\n\tvoid (T::*handler_)(NativeEvent&);\n\tT* owner_;\n\npublic:\n\tNativeEventQueue( T* owner, void (T::*Handler)(NativeEvent&) ) : owner_(owner), handler_(Handler) {}\n\n\tvoid Dispatch( NativeEvent &ev ) {\n\t\t(owner_->*handler_)(ev);\n\t}\n\n\tT* GetOwner() { return owner_; }\n};\n\n#endif // __NATIVE_EVENT_QUEUE_H__\n"
  },
  {
    "path": "src/core/base/win32/PluginImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Plugins\" class implementation / Service for plug-ins\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include <functional>\n#include \"ScriptMgnIntf.h\"\n#include \"PluginImpl.h\"\n#include \"StorageImpl.h\"\n#include \"GraphicsLoaderImpl.h\"\n\n#include \"MsgImpl.h\"\n#include \"SysInitIntf.h\"\n\n#include \"tjsHashSearch.h\"\n#include \"EventIntf.h\"\n#include \"TransIntf.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"DebugIntf.h\"\n#include \"FuncStubs.h\"\n#include \"tjs.h\"\n\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\t#include \"oldwaveunpacker.h\"\n#endif\n\n#pragma pack(push, 8)\n\t///  tvpsnd.h needs packing size of 8\n\t//#include \"tvpsnd.h\"\n#pragma pack(pop)\n\n#ifdef TVP_SUPPORT_KPI\n\t#include \"kmp_pi.h\"\n#endif\n\n#include \"FilePathUtil.h\"\n#include \"Application.h\"\n#include \"SysInitImpl.h\"\n#include <set>\n#ifdef _MSC_VER\n#define strcasecmp _stricmp\n#endif\n\n#if 0\n//---------------------------------------------------------------------------\n// export table\n//---------------------------------------------------------------------------\nstatic tTJSHashTable<ttstr, void *> TVPExportFuncs;\nstatic bool TVPExportFuncsInit = false;\nvoid TVPAddExportFunction(const char *name, void *ptr)\n{\n\tTVPExportFuncs.Add(name, ptr);\n}\nvoid TVPAddExportFunction(const tjs_char *name, void *ptr)\n{\n\tTVPExportFuncs.Add(name, ptr);\n}\nstatic void TVPInitExportFuncs()\n{\n\tif(TVPExportFuncsInit) return;\n\tTVPExportFuncsInit = true;\n\n\n\t// Export functions\n\tTVPExportFunctions();\n}\n//---------------------------------------------------------------------------\nstruct tTVPFunctionExporter : iTVPFunctionExporter\n{\n\tbool TJS_INTF_METHOD QueryFunctions(const tjs_char **name, void **function,\n\t\ttjs_uint count);\n\tbool TJS_INTF_METHOD QueryFunctionsByNarrowString(const char **name,\n\t\tvoid **function, tjs_uint count);\n} static TVPFunctionExporter;\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPFunctionExporter::QueryFunctions(const tjs_char **name, void **function,\n\t\ttjs_uint count)\n{\n\t// retrieve function table by given name table.\n\t// return false if any function is missing.\n\tbool ret = true;\n\tttstr tname;\n\tfor(tjs_uint i = 0; i<count; i++)\n\t{\n\t\ttname = name[i];\n\t\tvoid ** ptr = TVPExportFuncs.Find(tname);\n\t\tif(ptr)\n\t\t\tfunction[i] = *ptr;\n\t\telse\n\t\t\tfunction[i] = NULL, ret= false;\n\t}\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPFunctionExporter::QueryFunctionsByNarrowString(\n\tconst char **name, void **function, tjs_uint count)\n{\n\t// retrieve function table by given name table.\n\t// return false if any function is missing.\n\tbool ret = true;\n\tttstr tname;\n\tfor(tjs_uint i = 0; i<count; i++)\n\t{\n\t\ttname = name[i];\n\t\tvoid ** ptr = TVPExportFuncs.Find(tname);\n\t\tif(ptr)\n\t\t\tfunction[i] = *ptr;\n\t\telse\n\t\t\tfunction[i] = NULL, ret= false;\n\t}\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nextern \"C\" iTVPFunctionExporter * __stdcall TVPGetFunctionExporter()\n{\n\t// for external applications\n\tTVPInitExportFuncs();\n    return &TVPFunctionExporter;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TVPThrowPluginUnboundFunctionError(const char *funcname)\n{\n\tTVPThrowExceptionMessage(TVPPluginUnboundFunctionError, funcname);\n}\n//---------------------------------------------------------------------------\nvoid TVPThrowPluginUnboundFunctionError(const tjs_char *funcname)\n{\n\tTVPThrowExceptionMessage(TVPPluginUnboundFunctionError, funcname);\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n#if 0\n//---------------------------------------------------------------------------\n// implementation of IStorageProvider\n//---------------------------------------------------------------------------\nclass tTVPStorageProvider : public ITSSStorageProvider\n{\n\tHRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObjOut)\n\t{\n\t\tif(!ppvObjOut) return E_INVALIDARG;\n\n\t\t*ppvObjOut = NULL;\n\t\tif(!memcmp(&iid, &IID_IUnknown, 16))\n\t\t\t*ppvObjOut = (IUnknown*)this;\n\t\telse if(!memcmp(&iid, &IID_ITSSStorageProvider, 16))\n\t\t\t*ppvObjOut = (ITSSStorageProvider*)this;\n\n\t\tif(*ppvObjOut)\n\t\t{\n\t\t\tAddRef();\n\t\t\treturn S_OK;\n\t\t}\n\t\treturn E_NOINTERFACE;\n\t}\n\n\tULONG STDMETHODCALLTYPE AddRef(void) { return 1; }\n\tULONG STDMETHODCALLTYPE Release(void) { return 1; }\n\n\tHRESULT __stdcall GetStreamForRead(\n\t\tLPWSTR url,\n\t\tIUnknown * *stream);\n\n\tHRESULT __stdcall GetStreamForWrite(\n\t\tLPWSTR url,\n\t\tIUnknown * *stream) { return E_NOTIMPL; }\n\n\tHRESULT __stdcall GetStreamForUpdate(\n\t\tLPWSTR url,\n\t\tIUnknown * *stream) { return E_NOTIMPL; }\n};\n//---------------------------------------------------------------------------\nHRESULT __stdcall tTVPStorageProvider::GetStreamForRead(\n\t\tLPWSTR url,\n\t\tIUnknown * *stream)\n{\n\ttTJSBinaryStream *stream0;\n\ttry\n\t{\n\t\tstream0 = TVPCreateStream(url);\n\t}\n\tcatch(...)\n\t{\n\t\treturn E_FAIL;\n\t}\n\n\tIUnknown *istream = (IUnknown*)(IStream*)new tTVPIStreamAdapter(stream0);\n\t*stream = istream;\n\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Plug-ins management\n//---------------------------------------------------------------------------\nstruct tTVPPlugin\n{\n\tttstr Name;\n\tHINSTANCE Instance;\n\n\ttTVPPluginHolder *Holder;\n\n\tbool IsSusiePicturePlugin; // Susie picture plugins are managed in GraphicsLoaderImpl.cpp\n\tbool IsSusieArchivePlugin; // Susie archive plugins are managed in SusieArchive.cpp\n\n\tITSSModule *TSSModule;\n\n#ifdef TVP_SUPPORT_KPI\n\tKMPMODULE *KMPModule;\n#endif\n\n\ttTVPV2LinkProc V2Link;\n\ttTVPV2UnlinkProc V2Unlink;\n\n\n\ttTVPGetModuleInstanceProc GetModuleInstance;\n\ttTVPGetModuleThreadModelProc GetModuleThreadModel;\n\ttTVPShowConfigWindowProc ShowConfigWindow;\n\ttTVPCanUnloadNowProc CanUnloadNow;\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\ttTVPCreateWaveUnpackerProc CreateWaveUnpacker;\n#endif\n\n#ifdef TVP_SUPPORT_KPI\n\tpfnGetKMPModule GetKMPModule;\n#endif\n\n\tstd::vector<ttstr> SupportedExts;\n\n\ttTVPPlugin(const ttstr & name, ITSSStorageProvider *storageprovider);\n\t~tTVPPlugin();\n\n\tbool Uninit();\n};\n//---------------------------------------------------------------------------\ntTVPPlugin::tTVPPlugin(const ttstr & name, ITSSStorageProvider *storageprovider)\n{\n\tName = name;\n\n\tInstance = NULL;\n\tHolder = NULL;\n\tIsSusiePicturePlugin = false;\n\tIsSusieArchivePlugin = false;\n\tTSSModule = NULL;\n\n#ifdef TVP_SUPPORT_KPI\n\tKMPModule = NULL;\n#endif\n\n\tV2Link = NULL;\n\tV2Unlink = NULL;\n\n\tGetModuleInstance = NULL;\n\tGetModuleThreadModel = NULL;\n\tShowConfigWindow = NULL;\n\tCanUnloadNow = NULL;\n\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\tCreateWaveUnpacker = NULL;\n#endif\n\n#ifdef TVP_SUPPORT_KPI\n\tGetKMPModule = NULL;\n#endif\n\n\t// load DLL\n\tHolder = new tTVPPluginHolder(name);\n\tInstance = LoadLibrary(Holder->GetLocalName().AsStdString().c_str());\n\tif(!Instance)\n\t{\n\t\tdelete Holder;\n\t\tTVPThrowExceptionMessage(TVPCannotLoadPlugin, name);\n\t}\n\n\ttry\n\t{\n\t\t// retrieve each functions\n\t\tV2Link = (tTVPV2LinkProc)\n\t\t\tGetProcAddress(Instance, \"V2Link\");\n\t\tV2Unlink = (tTVPV2UnlinkProc)\n\t\t\tGetProcAddress(Instance, \"V2Unlink\");\n\n\t\tGetModuleInstance = (tTVPGetModuleInstanceProc)\n\t\t\tGetProcAddress(Instance, \"GetModuleInstance\");\n\t\tGetModuleThreadModel = (tTVPGetModuleThreadModelProc)\n\t\t\tGetProcAddress(Instance, \"GetModuleThreadModel\");\n\t\tShowConfigWindow = (tTVPShowConfigWindowProc)\n\t\t\tGetProcAddress(Instance, \"ShowConfigWindow\");\n\t\tCanUnloadNow = (tTVPCanUnloadNowProc)\n\t\t\tGetProcAddress(Instance, \"CanUnloadNow\");\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\t\tCreateWaveUnpacker = (tTVPCreateWaveUnpackerProc)\n\t\t\tGetProcAddress(Instance, \"CreateWaveUnpacker\");\n#endif\n\n#ifdef TVP_SUPPORT_KPI\n\t\tGetKMPModule = (pfnGetKMPModule)\n\t\t\tGetProcAddress(Instance, SZ_KMP_GETMODULE);\n#endif\n\n\t\t// link\n\t\tif(V2Link)\n\t\t{\n\t\t\tV2Link(TVPGetFunctionExporter());\n\t\t}\n\n\t\t// retrieve ModuleInstance\n\t\t// Susie Plug-in check\n\t\tif(GetProcAddress(Instance, \"GetPicture\"))\n\t\t{\n\t\t\tIsSusiePicturePlugin = true;\n\t\t\tTVPLoadPictureSPI(Instance);\n\t\t\treturn;\n\t\t}\n\t\tif(GetProcAddress(Instance, \"GetFile\"))\n\t\t{\n\t\t\tIsSusieArchivePlugin = true;\n\t\t\tTVPLoadArchiveSPI(Instance);\n\t\t\treturn;\n\t\t}\n\n\t\tif(GetModuleInstance)\n\t\t{\n\t\t\tHRESULT hr = GetModuleInstance(&TSSModule, storageprovider,\n\t\t\t\t NULL, Application->GetHandle());\n\t\t\tif(FAILED(hr) || TSSModule == NULL)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotLoadPlugin, name);\n\n\t\t\t// get supported extensions\n\t\t\tunsigned long index = 0;\n\t\t\twhile(true)\n\t\t\t{\n\t\t\t\twchar_t mediashortname[33];\n\t\t\t\twchar_t buf[256];\n\t\t\t\tHRESULT hr = TSSModule->GetSupportExts(index,\n\t\t\t\t\tmediashortname, buf, 255);\n\t\t\t\tif(hr == S_OK)\n\t\t\t\t\tSupportedExts.push_back(ttstr(buf).AsLowerCase());\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t\tindex ++;\n\t\t\t}\n\t\t}\n\n\n#ifdef TVP_SUPPORT_KPI\n\t\t// retrieve KbMediaPlayer Plug-in module instance\n\t\tif(GetKMPModule)\n\t\t{\n\t\t\tKMPModule = GetKMPModule();\n\t\t\tif(KMPModule->dwVersion != 100)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotLoadPlugin, name +\n\t\t\t\t\tTJS_W(\" (invalid version)\"));\n\t\t\tif(!KMPModule->dwReentrant)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotLoadPlugin, name +\n\t\t\t\t\tTJS_W(\" (is not re-entrant)\"));\n\n\t\t\tif(KMPModule->Init) KMPModule->Init();\n\t\t}\n#endif\n\t}\n\tcatch(...)\n\t{\n\t\tFreeLibrary(Instance);\n\t\tdelete Holder;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPPlugin::~tTVPPlugin()\n{\n}\n//---------------------------------------------------------------------------\nbool tTVPPlugin::Uninit()\n{\n\ttTJS *tjs = TVPGetScriptEngine();\n\tif(tjs) tjs->DoGarbageCollection(); // to release unused objects\n\n\tif(V2Unlink)\n\t{\n \t\tif(FAILED(V2Unlink())) return false;\n\t}\n#ifdef TVP_SUPPORT_KPI\n\tif(KMPModule) if(KMPModule->Deinit) KMPModule->Deinit();\n#endif\n\tif(TSSModule) TSSModule->Release();\n\tif(IsSusiePicturePlugin) TVPUnloadPictureSPI(Instance);\n\tif(IsSusieArchivePlugin) TVPUnloadArchiveSPI(Instance);\n\tFreeLibrary(Instance);\n\tdelete Holder;\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nbool TVPPluginUnloadedAtSystemExit = false;\ntypedef std::vector<tTVPPlugin*> tTVPPluginVectorType;\nstruct tTVPPluginVectorStruc\n{\n\ttTVPPluginVectorType Vector;\n\ttTVPStorageProvider StorageProvider;\n} static TVPPluginVector;\nstatic void TVPDestroyPluginVector(void)\n{\n\t// state all plugins are to be released\n\tTVPPluginUnloadedAtSystemExit = true;\n\n\t// delete all objects\n\ttTVPPluginVectorType::iterator i;\n\twhile(TVPPluginVector.Vector.size())\n\t{\n\t\ti = TVPPluginVector.Vector.end() - 1;\n\t\ttry\n\t\t{\n\t\t\t(*i)->Uninit();\n\t\t\tdelete *i;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t}\n\t\tTVPPluginVector.Vector.pop_back();\n\t}\n}\ntTVPAtExit TVPDestroyPluginVectorAtExit\n\t(TVP_ATEXIT_PRI_RELEASE, TVPDestroyPluginVector);\n#endif\n//---------------------------------------------------------------------------\nbool TVPLoadInternalPlugin(const ttstr &_name);\nextern std::set<ttstr> TVPRegisteredPlugins;\nstatic bool TVPPluginLoading = false;\nvoid TVPLoadPlugin(const ttstr & name)\n{\n\tbool success = TVPLoadInternalPlugin(name);\n    return; // seal all plugins\n#if 0\n\t// load plugin\n\tif(TVPPluginLoading)\n\t\tTVPThrowExceptionMessage(TVPCannnotLinkPluginWhilePluginLinking);\n\t\t\t// linking plugin while other plugin is linking, is prohibited\n\t\t\t// by data security reason.\n\n\t// check whether the same plugin was already loaded\n\ttTVPPluginVectorType::iterator i;\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->Name == name) return;\n\t}\n\n\ttTVPPlugin * p;\n\n\ttry\n\t{\n\t\tTVPPluginLoading = true;\n\t\tp = new tTVPPlugin(name, &TVPPluginVector.StorageProvider);\n\t\tTVPPluginLoading = false;\n\t}\n\tcatch(...)\n\t{\n\t\tTVPPluginLoading = false;\n\t\tthrow;\n\t}\n\n\tTVPPluginVector.Vector.push_back(p);\n#endif\n}\n//---------------------------------------------------------------------------\nbool TVPUnloadPlugin(const ttstr & name)\n{\n\t// unload plugin\n#if 0\n\ttTVPPluginVectorType::iterator i;\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->Name == name)\n\t\t{\n\t\t\tif(!(*i)->Uninit()) return false;\n\t\t\tdelete *i;\n\t\t\tTVPPluginVector.Vector.erase(i);\n\t\t\treturn true;\n\t\t}\n\t}\n\tTVPThrowExceptionMessage(TVPNotLoadedPlugin, name);\n\treturn false;\n#endif\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// plug-in autoload support\n//---------------------------------------------------------------------------\nstruct tTVPFoundPlugin\n{\n\tstd::string Path;\n\tstd::string Name;\n\tbool operator < (const tTVPFoundPlugin &rhs) const { return Name < rhs.Name; }\n};\nstatic tjs_int TVPAutoLoadPluginCount = 0;\nstatic void TVPSearchPluginsAt(std::vector<tTVPFoundPlugin> &list, std::string folder)\n{\n\tTVPListDir(folder, [&](const std::string &filename, int mask){\n\t\tif (mask & S_IFREG) {\n\t\t\tif (!strcasecmp(filename.c_str() + filename.length() - 4, \".tpm\")) {\n\t\t\t\ttTVPFoundPlugin fp;\n\t\t\t\tfp.Path = folder;\n\t\t\t\tfp.Name = filename;\n\t\t\t\tlist.emplace_back(fp);\n\t\t\t}\n\t\t}\n\t});\n#if 0\n\tWIN32_FIND_DATA ffd;\n\tHANDLE handle = ::FindFirstFile((folder + L\"*.tpm\").c_str(), &ffd);\n\tif(handle != INVALID_HANDLE_VALUE)\n\t{\n\t\tBOOL cont;\n\t\tdo\n\t\t{\n\t\t\tif(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))\n\t\t\t{\n\t\t\t\ttTVPFoundPlugin fp;\n\t\t\t\tfp.Path = folder;\n\t\t\t\tfp.Name = ffd.cFileName;\n\t\t\t\tlist.push_back(fp);\n\t\t\t}\n\t\t\tcont = FindNextFile(handle, &ffd);\n\t\t} while(cont);\n\t\tFindClose(handle);\n\t}\n#endif\n}\n\nvoid TVPLoadInternalPlugins();\nvoid TVPLoadPluigins(void)\n{\n\tTVPLoadInternalPlugins();\n\t// This function searches plugins which have an extension of \".tpm\"\n\t// in the default path: \n\t//    1. a folder which holds kirikiri executable\n\t//    2. \"plugin\" folder of it\n\t// Plugin load order is to be decided using its name;\n\t// aaa.tpm is to be loaded before aab.tpm (sorted by ASCII order)\n\n\t// search plugins from path: (exepath), (exepath)\\system, (exepath)\\plugin\n\tstd::vector<tTVPFoundPlugin> list;\n\n\tstd::string exepath = ExtractFileDir(TVPNativeProjectDir.AsNarrowStdString());\n\n\tTVPSearchPluginsAt(list, exepath);\n\tTVPSearchPluginsAt(list, exepath + \"/system\");\n\tTVPSearchPluginsAt(list, exepath + \"/plugin\");\n\n\t// sort by filename\n\tstd::sort(list.begin(), list.end());\n\n\t// load each plugin\n\tTVPAutoLoadPluginCount = (tjs_int)list.size();\n\tfor(std::vector<tTVPFoundPlugin>::iterator i = list.begin();\n\t\ti != list.end();\n\t\ti++)\n\t{\n\t\tTVPAddImportantLog(ttstr(TJS_W(\"(info) Loading \")) + ttstr(i->Name.c_str()));\n\t\tTVPLoadPlugin((i->Path + \"/\" + i->Name).c_str());\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int TVPGetAutoLoadPluginCount() { return TVPAutoLoadPluginCount; }\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// interface to Wave decode plugins\n//---------------------------------------------------------------------------\nITSSWaveDecoder * TVPSearchAvailTSSWaveDecoder(const ttstr & storage, const ttstr & extension)\n{\n\ttTVPPluginVectorType::iterator i;\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->TSSModule)\n\t\t{\n\t\t\t// check whether the plugin supports extension\n\t\t\tbool supported = false;\n\t\t\tstd::vector<ttstr>::iterator ei;\n\t\t\tfor(ei = (*i)->SupportedExts.begin(); ei != (*i)->SupportedExts.end(); ei++)\n\t\t\t{\n\t\t\t\tif(ei->GetLen() == 0) { supported = true; break; }\n\t\t\t\tif(extension == *ei) { supported = true; break; }\n\t\t\t}\n\n\t\t\tif(!supported) continue;\n\n\t\t\t// retrieve instance from (*i)->TSSModule\n\t\t\tIUnknown *intf = NULL;\n\t\t\tHRESULT hr = (*i)->TSSModule->GetMediaInstance(\n\t\t\t\t(wchar_t*)storage.c_str(), &intf);\n\t\t\tif(SUCCEEDED(hr))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// check  whether the instance has IID_ITSSWaveDecoder\n\t\t\t\t\t// interface.\n\t\t\t\t\tITSSWaveDecoder * decoder;\n\t\t\t\t\tif(SUCCEEDED(intf->QueryInterface(IID_ITSSWaveDecoder,\n\t\t\t\t\t\t(void**) &decoder)))\n\t\t\t\t\t{\n\t\t\t\t\t\tintf->Release();\n\t\t\t\t\t\treturn decoder; // OK\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\tintf->Release();\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tintf->Release();\n\t\t\t}\n\n\t\t}\n\t}\n\treturn NULL; // not found\n}\n//---------------------------------------------------------------------------\n#endif\n//---------------------------------------------------------------------------\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\nIWaveUnpacker * TVPSearchAvailWaveUnpacker(const ttstr & storage, IStream **stream)\n{\n\ttTVPPluginVectorType::iterator i;\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->CreateWaveUnpacker) break;\n\t}\n\tif(i == TVPPluginVector.Vector.end()) return NULL; // KPI not found\n\n\t// retrieve IStream interface\n\tAnsiString ansiname = storage.AsAnsiString();\n\n\ttTJSBinaryStream *stream0 = NULL;\n\tlong size;\n\ttry\n\t{\n\t\tstream0 = TVPCreateStream(storage);\n\t\tsize = (long)stream0->GetSize();\n\t}\n\tcatch(...)\n\t{\n\t\tif(stream0) delete stream0;\n\t\treturn NULL;\n\t}\n\n\tIStream *istream = new tTVPIStreamAdapter(stream0);\n\n\ttry\n\t{\n\n\t\tfor(i = TVPPluginVector.Vector.begin();\n\t\t\ti != TVPPluginVector.Vector.end(); i++)\n\t\t{\n\t\t\tif((*i)->CreateWaveUnpacker)\n\t\t\t{\n\t\t\t\t// call CreateWaveUnpacker to retrieve decoder instance\n\t\t\t\tIWaveUnpacker *out;\n\t\t\t\tHRESULT hr = (*i)->CreateWaveUnpacker(istream, size,\n\t\t\t\t\tansiname.c_str(), &out);\n\t\t\t\tif(SUCCEEDED(hr))\n\t\t\t\t{\n\t\t\t\t\t*stream = istream;\n\t\t\t\t\treturn out;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tistream->Release();\n\t\treturn NULL;\n\t}\n\tistream->Release();\n\treturn NULL; // not found\n}\n#endif\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n#ifdef TVP_SUPPORT_KPI\nvoid * TVPSearchAvailKMPWaveDecoder(const ttstr & storage, KMPMODULE ** module,\n\tSOUNDINFO * info)\n{\n\ttTVPPluginVectorType::iterator i;\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->KMPModule) break;\n\t}\n\tif(i == TVPPluginVector.Vector.end()) return NULL; // KPI not found\n\n\tAnsiString localname;\n\n\tif(TJS_strchr(storage.c_str(), TVPArchiveDelimiter)) return NULL;\n\t\t// in-archive storage is not supported\n\n\ttry\n\t{\n\t\tttstr ln(TVPSearchPlacedPath(storage));\n\t\tTVPGetLocalName(ln);\n\t\tlocalname  = ln.AsAnsiString();\n\t}\n\tcatch(...)\n\t{\n\t\treturn NULL;\n\t}\n\n\tAnsiString ext = TVPExtractStorageExt(storage).AsAnsiString();\n\n\tfor(i = TVPPluginVector.Vector.begin();\n\t\ti != TVPPluginVector.Vector.end(); i++)\n\t{\n\t\tif((*i)->KMPModule)\n\t\t{\n\t\t\t// search over available extensions\n\t\t\tconst char **module_ext = (*i)->KMPModule->ppszSupportExts;\n\t\t\twhile(*module_ext)\n\t\t\t{\n\t\t\t\tif(!strcmpi(ext.c_str(), *module_ext)) break;\n\t\t\t\tmodule_ext ++;\n\t\t\t}\n\t\t\tif(!*module_ext) continue; // not found in this plug-in\n\n\t\t\t*module = (*i)->KMPModule;\n\t\t\tHKMP hkmp = (*i)->KMPModule->Open(localname.c_str(), info);\n\t\t\tif(hkmp)\n\t\t\t\t(*i)->KMPModule->SetPosition(hkmp, 0);\n\t\t\t\t\t// rewind; some plug-ins crash when the initial rewind is\n\t\t\t\t\t// not processed...\n\t\t\treturn hkmp;\n\t\t}\n\t}\n\treturn NULL; // not found\n}\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// some service functions for plugin\n//---------------------------------------------------------------------------\n#include <zlib.h>\nint ZLIB_uncompress(unsigned char *dest, unsigned long *destlen,\n\tconst unsigned char *source, unsigned long sourcelen)\n{\n\treturn uncompress(dest, destlen, source, sourcelen);\n}\n//---------------------------------------------------------------------------\nint ZLIB_compress(unsigned char *dest, unsigned long *destlen,\n\tconst unsigned char *source, unsigned long sourcelen)\n{\n\treturn compress(dest, destlen, source, sourcelen);\n}\n//---------------------------------------------------------------------------\nint ZLIB_compress2(unsigned char *dest, unsigned long *destlen,\n\tconst unsigned char *source, unsigned long sourcelen, int level)\n{\n\treturn compress2(dest, destlen, source, sourcelen, level);\n}\n//---------------------------------------------------------------------------\n#include \"md5.h\"\nstatic char TVP_assert_md5_state_t_size[\n\t (sizeof(TVP_md5_state_t) >= sizeof(md5_state_t))];\n\t// if this errors, sizeof(TVP_md5_state_t) is not equal to sizeof(md5_state_t).\n\t// sizeof(TVP_md5_state_t) must be equal to sizeof(md5_state_t).\n//---------------------------------------------------------------------------\nvoid TVP_md5_init(TVP_md5_state_t *pms)\n{\n\tmd5_init((md5_state_t*)pms);\n}\n//---------------------------------------------------------------------------\nvoid TVP_md5_append(TVP_md5_state_t *pms, const tjs_uint8 *data, int nbytes)\n{\n\tmd5_append((md5_state_t*)pms, (const md5_byte_t*)data, nbytes);\n}\n//---------------------------------------------------------------------------\nvoid TVP_md5_finish(TVP_md5_state_t *pms, tjs_uint8 *digest)\n{\n\tmd5_finish((md5_state_t*)pms, digest);\n}\n#if 0\n//---------------------------------------------------------------------------\nHWND TVPGetApplicationWindowHandle()\n{\n\treturn Application->GetHandle();\n}\n//---------------------------------------------------------------------------\nvoid TVPProcessApplicationMessages()\n{\n\tApplication->ProcessMessages();\n}\n//---------------------------------------------------------------------------\nvoid TVPHandleApplicationMessage()\n{\n\tApplication->HandleMessage();\n}\n#endif\n//---------------------------------------------------------------------------\nbool TVPRegisterGlobalObject(const tjs_char *name, iTJSDispatch2 * dsp)\n{\n\t// register given object to global object\n\ttTJSVariant val(dsp);\n\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = global->PropSet(TJS_MEMBERENSURE, name, NULL, &val, global);\n\t}\n\tcatch(...)\n\t{\n\t\tglobal->Release();\n\t\treturn false;\n\t}\n\tglobal->Release();\n\treturn TJS_SUCCEEDED(er);\n}\n//---------------------------------------------------------------------------\nbool TVPRemoveGlobalObject(const tjs_char *name)\n{\n\t// remove registration of global object\n\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\tif(!global) return false;\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = global->DeleteMember(0, name, NULL, global);\n\t}\n\tcatch(...)\n\t{\n\t\tglobal->Release();\n\t\treturn false;\n\t}\n\tglobal->Release();\n\treturn TJS_SUCCEEDED(er);\n}\n//---------------------------------------------------------------------------\nvoid TVPDoTryBlock(\n\ttTVPTryBlockFunction tryblock,\n\ttTVPCatchBlockFunction catchblock,\n\ttTVPFinallyBlockFunction finallyblock,\n\tvoid *data)\n{\n\ttry\n\t{\n\t\ttryblock(data);\n\t}\n\tcatch(const eTJS & e)\n\t{\n\t\tif(finallyblock) finallyblock(data);\n\t\ttTVPExceptionDesc desc;\n\t\tdesc.type = TJS_W(\"eTJS\");\n\t\tdesc.message = e.GetMessage();\n\t\tif(catchblock(data, desc)) throw;\n\t\treturn;\n\t}\n\tcatch(...)\n\t{\n\t\tif(finallyblock) finallyblock(data);\n\t\ttTVPExceptionDesc desc;\n\t\tdesc.type = TJS_W(\"unknown\");\n\t\tif(catchblock(data, desc)) throw;\n\t\treturn;\n\t}\n\tif(finallyblock) finallyblock(data);\n}\n//---------------------------------------------------------------------------\n\n\n#if 0\n//---------------------------------------------------------------------------\n// TVPGetFileVersionOf\n//---------------------------------------------------------------------------\nbool TVPGetFileVersionOf(const wchar_t* module_filename, tjs_int &major, tjs_int &minor, tjs_int &release, tjs_int &build)\n{\n\t// retrieve file version\n\tmajor = minor = release = build = 0;\n\n\tVS_FIXEDFILEINFO *FixedFileInfo;\n\tBYTE *VersionInfo;\n\tbool got = false;\n\n\tUINT dum;\n\tDWORD dum2;\n\n\twchar_t* filename = new wchar_t[TJS_strlen(module_filename) + 1];\n\ttry\n\t{\n\t\tTJS_strcpy(filename, module_filename);\n\n\t\tDWORD size = ::GetFileVersionInfoSize (filename, &dum2);\n\t\tif(size)\n\t\t{\n\t\t\tVersionInfo = new BYTE[size + 2];\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(::GetFileVersionInfo(filename, 0, size, (void*)VersionInfo))\n\t\t\t\t{\n\t\t\t\t\tif(::VerQueryValue((void*)VersionInfo, L\"\\\\\", (void**)(&FixedFileInfo),\n\t\t\t\t\t\t&dum))\n\t\t\t\t\t{\n\t\t\t\t\t\tmajor   = FixedFileInfo->dwFileVersionMS >> 16;\n\t\t\t\t\t\tminor   = FixedFileInfo->dwFileVersionMS & 0xffff;\n\t\t\t\t\t\trelease = FixedFileInfo->dwFileVersionLS >> 16;\n\t\t\t\t\t\tbuild   = FixedFileInfo->dwFileVersionLS & 0xffff;\n\t\t\t\t\t\tgot = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tdelete [] VersionInfo;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete [] VersionInfo;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] filename;\n\t\tthrow;\n\t}\n\n\tdelete [] filename;\n\n\treturn got;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Plugins\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Plugins()\n{\n\ttTJSNC_Plugins *cls = new tTJSNC_Plugins();\n\n\n\t// setup some platform-specific members\n//---------------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/link)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\n\tTVPLoadPlugin(name);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/link)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/unlink)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\n\tbool res = TVPUnloadPlugin(name);\n\n\tif(result) *result = (tjs_int)res;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/unlink)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(getList)\n{\n\tiTJSDispatch2 * array = TJSCreateArrayObject();\n\ttry\n\t{\n\t\ttjs_int idx = 0;\n\t\tfor (ttstr name : TVPRegisteredPlugins) {\n\t\t\ttTJSVariant val(name);\n\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE, idx++, &val, array);\n\t\t}\n#if 0\n\t\ttTVPPluginVectorType::iterator i;\n\t\ttjs_int idx = 0;\n\t\tfor(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++)\n\t\t{\n\t\t\ttTJSVariant val = (*i)->Name.c_str();\n\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE, idx++, &val, array);\n\t\t}\n#endif\n\t\tif (result) *result = tTJSVariant(array, array);\n\t}\n\tcatch(...)\n\t{\n\t\tarray->Release();\n\t\tthrow;\n\t}\n\tarray->Release();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(cls, getList)\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/base/win32/PluginImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Plugins\" class implementation / Service for plug-ins\n//---------------------------------------------------------------------------\n#ifndef PluginImplH\n#define PluginImplH\n//---------------------------------------------------------------------------\n#include <memory.h>\n\n#include \"PluginIntf.h\"\n#include \"win32type.h\"\n#ifdef TVP_SUPPORT_KPI\n\t#include \"kmp_pi.h\"\n#endif\n#if 0\n\n//---------------------------------------------------------------------------\n/*[*/\n//---------------------------------------------------------------------------\n// iTVPFunctionExporter, exporting main module's functions\n//---------------------------------------------------------------------------\nstruct iTVPFunctionExporter\n{\n\tvirtual bool TJS_INTF_METHOD QueryFunctions(const tjs_char **name, void **function,\n\t\ttjs_uint count) = 0;\n\tvirtual bool TJS_INTF_METHOD QueryFunctionsByNarrowString(const char **name,\n\t\tvoid **function, tjs_uint count) = 0;\n};\n//---------------------------------------------------------------------------\n\n\n/*]*/\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstruct ITSSModule;\nstruct IWaveUnpacker;\nstruct ITSSStorageProvider;\nextern \"C\"\n{\n\tiTVPFunctionExporter * __stdcall TVPGetFunctionExporter();\n\n\t// V2 plug-in\n\ttypedef HRESULT (_stdcall * tTVPV2LinkProc)(iTVPFunctionExporter *);\n\ttypedef HRESULT (_stdcall * tTVPV2UnlinkProc)();\n\n\t// TSS\n\ttypedef HRESULT (_stdcall * tTVPGetModuleInstanceProc)(ITSSModule **out,\n\t\tITSSStorageProvider *provider, IStream * config, HWND mainwin);\n\ttypedef ULONG (_stdcall * tTVPGetModuleThreadModelProc)(void);\n\ttypedef HRESULT (_stdcall * tTVPShowConfigWindowProc)(HWND parentwin,\n\t\tIStream * storage );\n\ttypedef ULONG (_stdcall * tTVPCanUnloadNowProc)(void);\n\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\t// WaveUnpacker\n\ttypedef HRESULT (_stdcall * tTVPCreateWaveUnpackerProc)(IStream *storage,long size,\n\t\tchar *name,IWaveUnpacker **out); // old WaveUnpacker stuff\n#endif\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nstruct ITSSWaveDecoder;\nextern ITSSWaveDecoder * TVPSearchAvailTSSWaveDecoder(const ttstr & storage, const ttstr & extension);\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\nclass IWaveUnpacker;\nextern IWaveUnpacker * TVPSearchAvailWaveUnpacker(const ttstr & storage, IStream **stream);\n#endif\n#ifdef TVP_SUPPORT_KPI\nextern void * TVPSearchAvailKMPWaveDecoder(const ttstr & storage, KMPMODULE ** module,\n\tSOUNDINFO * info);\n#endif\nextern void TVPAddExportFunction(const tjs_char *name, void *ptr);\nextern void TVPAddExportFunction(const char *name, void *ptr);\nTJS_EXP_FUNC_DEF(void, TVPThrowPluginUnboundFunctionError, (const char *funcname));\nTJS_EXP_FUNC_DEF(void, TVPThrowPluginUnboundFunctionError, (const tjs_char *funcname));\n#endif\ninline TJS_EXP_FUNC_DEF(void *, TVP_malloc, (size_t size)) { return malloc(size); }\n// inline TJS_EXP_FUNC_DEF(void *, TVP_realloc, (void *pp, size_t size)) { return realloc(pp, size); }\ninline TJS_EXP_FUNC_DEF(void, TVP_free, (void *pp)) { return free(pp); }\nTJS_EXP_FUNC_DEF(tjs_int, TVPGetAutoLoadPluginCount, ());\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(int, ZLIB_uncompress, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen));\nTJS_EXP_FUNC_DEF(int, ZLIB_compress, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen));\nTJS_EXP_FUNC_DEF(int, ZLIB_compress2, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen, int level));\n\n/*[*/\n\n//---------------------------------------------------------------------------\n// this stub includes exported function from Independent implementation of\n// MD5 (RFC 1321) by Aladdin Enterprises.\n//---------------------------------------------------------------------------\n// TVP_md5_init, TVP_md5_append, TVP_md5_finish are exported\ntypedef struct TVP_md5_state_s { tjs_uint8 buffer[4*2+8+4*4+8+64]; } TVP_md5_state_t; // md5_state_t \n//---------------------------------------------------------------------------\n\n\n/*]*/\n\nTJS_EXP_FUNC_DEF(void, TVP_md5_init, (TVP_md5_state_t *pms));\nTJS_EXP_FUNC_DEF(void, TVP_md5_append, (TVP_md5_state_t *pms, const tjs_uint8 *data, int nbytes));\nTJS_EXP_FUNC_DEF(void, TVP_md5_finish, (TVP_md5_state_t *pms, tjs_uint8 *digest));\n\n//TJS_EXP_FUNC_DEF(HWND, TVPGetApplicationWindowHandle, ());\nTJS_EXP_FUNC_DEF(void, TVPProcessApplicationMessages, ());\nTJS_EXP_FUNC_DEF(void, TVPHandleApplicationMessage, ());\n\nTJS_EXP_FUNC_DEF(bool, TVPRegisterGlobalObject, (const tjs_char *name, iTJSDispatch2 * dsp));\nTJS_EXP_FUNC_DEF(bool, TVPRemoveGlobalObject, (const tjs_char *name));\n\n/*[*/\n//---------------------------------------------------------------------------\n// data types for TVPDoTryBlock\n//---------------------------------------------------------------------------\n\t// TVPDoTryBlock executes specified 'tryblock' in try block.\n\t// If any exception occured,\n\t// 'catchblock' is to be executed. 'data' is applicatoin defined data\n\t// block passed to 'tryblock' and 'catchblock' and 'finallyblock'.\n\t// if the 'catchblock' returns true, the exception is to be rethrown.\n\t// if false then the exception is to be vanished.\n\t// 'finallyblock' can be null, is to be executed whatever the exception\n\t// is generated or not.\n\nstruct tTVPExceptionDesc\n{\n\tttstr type; // the exception type, currently 'eTJS' or 'unknown'\n\tttstr message; // the exception message (if exists. otherwise empty).\n};\n\ntypedef void (TJS_USERENTRY *tTVPTryBlockFunction)(void * data);\ntypedef bool (TJS_USERENTRY *tTVPCatchBlockFunction)(void * data, const tTVPExceptionDesc & desc);\ntypedef void (TJS_USERENTRY *tTVPFinallyBlockFunction)(void *data);\n//---------------------------------------------------------------------------\n\n\n\n\n/*]*/\n\nTJS_EXP_FUNC_DEF(void, TVPDoTryBlock, (tTVPTryBlockFunction tryblock, tTVPCatchBlockFunction catchblock, tTVPFinallyBlockFunction finallyblock, void *data));\n\n\n//TJS_EXP_FUNC_DEF(bool, TVPGetFileVersionOf, (const wchar_t* module_filename, tjs_int &major, tjs_int &minor, tjs_int &release, tjs_int &build));\n\n\n//---------------------------------------------------------------------------\nextern bool TVPPluginUnloadedAtSystemExit;\nextern void TVPLoadPluigins(void);\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/base/win32/ScriptMgnImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 Script Managing\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"SystemControl.h\"\n#include \"WindowIntf.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsScriptBlock.h\"\n#include \"EventIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n#include \"StorageImpl.h\"\n#include \"tjsDebug.h\"\n\n#include \"Application.h\"\n//---------------------------------------------------------------------------\n\n/*\n\tObject Hash Map (implemented in tjsDebug) is a simple object memory leak\n\tdetector.\n\tObject Hash Map rely on TVP logging facility for logging unfreed objects.\n\tBut TVP logging facility ends before some of TJS2 objects had been freed.\n\n\tTo solve this problem, TJS2 uses two method to track objects;\n\t\ton-memory hash map and interprocess communication (IPC).\n\n\tOn-memory hash map is a simple method, tracking object's creation and\n\tdestruction on one hash map.\n\n\tInterprocess communication throws all object creation/destruction log\n\tto a process, which is specially created as a child-process for processing\n\treceived log. Interprocess communication is implemented using low-level\n\tAPI, works very end of the parent process.\n\n\tTVP switches these two methods at framework finalization.\n\tOn-memory hash map is used during most of the time.\n\tAt the end of the framework, the framework switches to interprocess\n\tcommunication method. This continues rest of Object Hash Map operation until\n\tthe process ends.\n\n\tProcess of receiving object hash map log is implemented as the same executable\n\tof Kirikiri (There is a command line option for running this facility).\n*/\n#if 0\n//---------------------------------------------------------------------------\n// tTVPPipeStream to do IPC (used for Object Hash Map)\n//---------------------------------------------------------------------------\nclass tTVPPipeStream : public tTJSBinaryStream\n{\nprivate:\n\tHANDLE Handle;\n\npublic:\n\ttTVPPipeStream(HANDLE handle)\n\t{\n\t\tHandle = handle;\n\t}\n\n\t~tTVPPipeStream()\n\t{\n\t\tCloseHandle(Handle);\n\t}\n\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence)\n\t{\n\t\treturn 0; // pipes does not support seeking\n\t}\n\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size)\n\t{\n\t\tDWORD ret = 0;\n\t\tReadFile(Handle, buffer, read_size, &ret, NULL);\n\t\treturn ret;\n\t}\n\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size)\n\t{\n\t\tDWORD ret = 0;\n\t\tWriteFile(Handle, buffer, write_size, &ret, NULL);\n\t\tFlushFileBuffers(Handle);\n\t\treturn ret;\n\t}\n\n\tvoid TJS_INTF_METHOD SetEndOfStorage()\n\t{\n\t\treturn;\n\t}\n\n\ttjs_uint64 TJS_INTF_METHOD GetSize()\n\t{\n\t\treturn 0;\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Object Hash Map (memory leak detector) related\n//---------------------------------------------------------------------------\nstatic char TVPObjectHashMapLogStream[sizeof(tTVPPipeStream)];\n\n//---------------------------------------------------------------------------\nvoid TVPStartObjectHashMapLog(void)\n{\n#ifndef ENABLE_DEBUGGER\n\tif(TJSObjectHashMapEnabled())\n\t{\n\t\t// begin logging\n\n\t\t// create anonymous pipe to communicate with child kirikiri process\n\t\tHANDLE read, write;\n\t\tSECURITY_ATTRIBUTES sa;\n\t\tZeroMemory(&sa, sizeof(sa));\n\t\tsa.nLength = sizeof(sa);\n\t\tsa.bInheritHandle = TRUE;\n\t\tCreatePipe(&read, &write, &sa, 0);\n\n\t\t// redirect stdin to output the object hash map log\n\t\tHANDLE org_stdin = GetStdHandle(STD_INPUT_HANDLE);\n\t\tHANDLE childdupwrite;\n\t\tSetStdHandle(STD_INPUT_HANDLE, read);\n\t\tDuplicateHandle(GetCurrentProcess(), write, GetCurrentProcess(),\n\t\t\t&childdupwrite, 0, FALSE, DUPLICATE_SAME_ACCESS);\n\t\tCloseHandle(write);\n\t\twrite = childdupwrite;\n\n\t\t// create child kirikiri process\n\t\tSTARTUPINFO si;\n\t\tPROCESS_INFORMATION pi;\n\t\tZeroMemory(&si, sizeof(si));\n\t\tsi.cb = sizeof(si);\n\t\tsi.dwFlags = STARTF_USESHOWWINDOW;\n\t\tsi.wShowWindow = SW_SHOWNORMAL;\n\n\t\twchar_t szFull[_MAX_PATH];\n\t\t::GetModuleFileName(NULL, szFull, sizeof(szFull) / sizeof(wchar_t));\n\t\tstd::wstring exepath(szFull);\n\t\tBOOL ret =\n\t\t\t::CreateProcess(\n\t\t\t\tNULL,\n\t\t\t\tconst_cast<LPTSTR>((exepath + L\" -@processohmlog\").c_str()),\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\tTRUE,\n\t\t\t\t0,\n\t\t\t\tNULL,\n\t\t\t\tNULL,\n\t\t\t\t&si,\n\t\t\t\t&pi);\n\n\t\tif(ret)\n\t\t{\n\t\t\tCloseHandle(pi.hThread);\n\t\t\tCloseHandle(pi.hProcess);\n\t\t}\n\n\t\t// close unneeded handle\n\t\tCloseHandle(read);\n\n\t\t// restore original stdin handle\n\t\tSetStdHandle(STD_INPUT_HANDLE, org_stdin);\n\n\t\t// create tTJSBinaryStream object in STATIC AREA\n\t\t::new (TVPObjectHashMapLogStream) tTVPPipeStream(write);\n\n\t\t// set object hash map log\n\t\tTJSObjectHashMapSetLog((tTVPLocalFileStream*)TVPObjectHashMapLogStream);\n\n\t\t// write all objects to log\n\t\tTJSWriteAllUnfreedObjectsToLog();\n\n\t\t// end object mapping\n\t\tTJSReleaseObjectHashMap();\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPReportUnfreedObjectsAtExit\n\t(TVP_ATEXIT_PRI_CLEANUP - 1, TVPStartObjectHashMapLog);\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nbool TVPCheckProcessLog()\n{\n\t// process object hash map log\n\tint argc = Application->ArgC;\n\tchar** argv = Application->ArgV;\n\n\ttjs_int i;\n\tfor(i=1; i<argc; i++)\n\t{\n\t\tif(!strcmp(argv[i], \"-@processohmlog\")) // this does not refer TVPGetCommandLine\n\t\t{\n\t\t\t// create object hash map\n\t\t\tTJSAddRefObjectHashMap();\n\n\t\t\t// create pipe object\n\t\t\ttTVPPipeStream pipe(GetStdHandle(STD_INPUT_HANDLE));\n\n\t\t\t// set object hash map log\n\t\t\tTJSObjectHashMapSetLog(&pipe);\n\n\t\t\t// read from stdin\n            TJSReplayObjectHashMapLog();\n\n\t\t\t// output report if object had been leaked\n\t\t\tif(TJSObjectHashAnyUnfreed())\n\t\t\t{\n\t\t\t\tTVPOnError();\n\t\t\t\tTJSReportAllUnfreedObjects(TVPGetTJS2ConsoleOutputGateway());\n\t\t\t}\n\n\t\t\t// release object hash map\n\t\t\tTJSReleaseObjectHashMap();\n\n\t\t\treturn true; // processed\n\t\t}\n\t}\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n\n"
  },
  {
    "path": "src/core/base/win32/ScriptMgnImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 Script Managing\n//---------------------------------------------------------------------------\n#ifndef ScriptMgnImplH\n#define ScriptMgnImplH\n\n\n#include \"ScriptMgnIntf.h\"\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPInitializeStartupScript\n//---------------------------------------------------------------------------\nextern void TVPInitializeStartupScript();\n//extern bool TVPCheckProcessLog(int argc, char *argv[]);\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/base/win32/StorageImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Universal Storage System\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n// #include <cderr.h>\n// #include <objbase.h>\n\n#include \"MsgIntf.h\"\n\n#include \"StorageImpl.h\"\n#include \"WindowImpl.h\"\n#include \"GraphicsLoaderImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n#include \"Random.h\"\n#include \"XP3Archive.h\"\n//#include \"SusieArchive.h\"\n#include \"FileSelector.h\"\n#include \"Random.h\"\n\n#include <time.h>\n\n#include \"Application.h\"\n#include \"StringUtil.h\"\n#include \"FilePathUtil.h\"\n#include \"Platform.h\"\n#include \"platform/CCPlatformConfig.h\"\n#include \"dirent.h\"\n#include \"TickCount.h\"\n#include <fcntl.h>\n#include <unistd.h>\n#include \"combase.h\"\n#include \"win32io.h\"\n\n//---------------------------------------------------------------------------\n// tTVPFileMedia\n//---------------------------------------------------------------------------\nclass tTVPFileMedia : public iTVPStorageMedia\n{\n\ttjs_uint RefCount;\n\npublic:\n\ttTVPFileMedia() { RefCount = 1; }\n\t~tTVPFileMedia() {;}\n\n\tvoid TJS_INTF_METHOD AddRef() { RefCount ++; }\n\tvoid TJS_INTF_METHOD Release()\n\t{\n\t\tif(RefCount == 1)\n\t\t\tdelete this;\n\t\telse\n\t\t\tRefCount --;\n\t}\n\n\tvoid TJS_INTF_METHOD GetName(ttstr &name) { name = TJS_W(\"file\"); }\n\n\tvoid TJS_INTF_METHOD NormalizeDomainName(ttstr &name);\n\tvoid TJS_INTF_METHOD NormalizePathName(ttstr &name);\n\tbool TJS_INTF_METHOD CheckExistentStorage(const ttstr &name);\n\ttTJSBinaryStream * TJS_INTF_METHOD Open(const ttstr & name, tjs_uint32 flags);\n\tvoid TJS_INTF_METHOD GetListAt(const ttstr &name, iTVPStorageLister *lister);\n\tvoid TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name);\n\npublic:\n\tvoid TJS_INTF_METHOD GetLocalName(ttstr &name);\n};\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPFileMedia::NormalizeDomainName(ttstr &name)\n{\n\t// normalize domain name\n\t// make all characters small\n\ttjs_char *p = name.Independ();\n\twhile(*p)\n\t{\n\t\tif(*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t*p += TJS_W('a') - TJS_W('A');\n\t\tp++;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPFileMedia::NormalizePathName(ttstr &name)\n{\n\t// normalize path name\n\t// make all characters small\n\ttjs_char *p = name.Independ();\n\twhile(*p)\n\t{\n\t\tif(*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t*p += TJS_W('a') - TJS_W('A');\n\t\tp++;\n\t}\n}\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPFileMedia::CheckExistentStorage(const ttstr &name)\n{\n\tif(name.IsEmpty()) return false;\n\n\tttstr _name(name);\n\tGetLocalName(_name);\n\n\treturn TVPCheckExistentLocalFile(_name);\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TJS_INTF_METHOD tTVPFileMedia::Open(const ttstr & name, tjs_uint32 flags)\n{\n\t// open storage named \"name\".\n\t// currently only local/network(by OS) storage systems are supported.\n\tif(name.IsEmpty())\n\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, TJS_W(\"\\\"\\\"\"));\n\n\tttstr origname = name;\n\tttstr _name(name);\n\tGetLocalName(_name);\n\n\treturn new tTVPLocalFileStream(origname, _name, flags);\n}\n\nvoid TVPListDir(const std::string &folder, std::function<void(const std::string&, int)> cb) {\n\tDIR *dirp;\n\tstruct dirent *direntp;\n\ttTVP_stat stat_buf;\n\tif ((dirp = opendir(folder.c_str())))\n\t{\n\t\twhile ((direntp = readdir(dirp)) != NULL)\n\t\t{\n\t\t\tstd::string fullpath = folder + \"/\" + direntp->d_name;\n\t\t\tif (!TVP_stat(fullpath.c_str(), stat_buf))\n\t\t\t\tcontinue;\n\t\t\tcb(direntp->d_name, stat_buf.st_mode);\n\t\t}\n\t\tclosedir(dirp);\n\t}\n}\n\nvoid TVPGetLocalFileListAt(const ttstr &name, const std::function<void(const ttstr&, tTVPLocalFileInfo*)>& cb) {\n\tDIR *dirp;\n\tstruct dirent *direntp;\n\ttTVP_stat stat_buf;\n\tstd::string folder(name.AsNarrowStdString());\n\tif ((dirp = opendir(folder.c_str())))\n\t{\n\t\twhile ((direntp = readdir(dirp)) != NULL)\n\t\t{\n\t\t\tstd::string fullpath = folder + \"/\" + direntp->d_name;\n\t\t\tif (!TVP_stat(fullpath.c_str(), stat_buf))\n\t\t\t\tcontinue;\n\t\t\tttstr file(direntp->d_name);\n\t\t\tif (file.length() <= 2) {\n\t\t\t\tif (file == TJS_W(\".\") || file == TJS_W(\"..\"))\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttjs_char *p = file.Independ();\n\t\t\twhile (*p)\n\t\t\t{\n\t\t\t\t// make all characters small\n\t\t\t\tif (*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t\t\t*p += TJS_W('a') - TJS_W('A');\n\t\t\t\tp++;\n\t\t\t}\n\t\t\ttTVPLocalFileInfo info;\n\t\t\tinfo.NativeName = direntp->d_name;\n\t\t\tinfo.Mode = stat_buf.st_mode;\n\t\t\tinfo.Size = stat_buf.st_size;\n\t\t\tinfo.AccessTime = stat_buf.st_atime;\n\t\t\tinfo.ModifyTime = stat_buf.st_mtime;\n\t\t\tinfo.CreationTime = stat_buf.st_ctime;\n\t\t\tcb(file, &info);\n\t\t}\n\t\tclosedir(dirp);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPFileMedia::GetListAt(const ttstr &_name, iTVPStorageLister *lister)\n{\n\tttstr name(_name);\n\tGetLocalName(name);\n#if 0\n\tname += TJS_W(\"*.*\");\n\n\t// perform UNICODE operation\n\tWIN32_FIND_DATAW ffd;\n\tHANDLE handle = ::FindFirstFile(name.c_str(), &ffd);\n\tif(handle != INVALID_HANDLE_VALUE)\n\t{\n\t\tBOOL cont;\n\t\tdo\n\t\t{\n\t\t\tif(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))\n\t\t\t{\n\t\t\t\tttstr file(ffd.cFileName);\n\t\t\t\ttjs_char *p = file.Independ();\n\t\t\t\twhile(*p)\n\t\t\t\t{\n\t\t\t\t\t// make all characters small\n\t\t\t\t\tif(*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t\t\t\t*p += TJS_W('a') - TJS_W('A');\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tlister->Add(file);\n\t\t\t}\n\n\t\t\tcont = ::FindNextFile(handle, &ffd);\n\t\t} while(cont);\n\t\tFindClose(handle);\n\t}\n#endif\n\tTVPGetLocalFileListAt(name, [lister](const ttstr &name, tTVPLocalFileInfo* s) {\n\t\tif (s->Mode & (S_IFREG)) {\n\t\t\tlister->Add(name);\n\t\t}\n\t});\n}\n\nstatic int _utf8_strcasecmp(const char *a, const char *b) {\n    for(; *a && *b; ++a, ++b) {\n        int ca = *a, cb = *b;\n        if('A' <= ca && ca <= 'Z') ca += 'a' - 'A';\n        if('A' <= cb && cb <= 'Z') cb += 'a' - 'A';\n        int ret = ca - cb;\n        if(ret) return ret;\n    }\n    return *a - *b;\n}\n\n#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS\nconst std::vector<std::string> &TVPGetApplicationHomeDirectory();\nconst std::vector<ttstr> &_getPrefixPath() {\n\tstatic std::vector<ttstr> ret;\n\tif (ret.empty()) {\n\t\tfor (const std::string &path : TVPGetApplicationHomeDirectory()) {\n\t\t\tret.emplace_back(path);\n\t\t}\n\t}\n\treturn ret;\n}\nconst std::vector<std::string> &_getHomeDir() {\n\tstatic std::vector<std::string> ret;\n\tif (ret.empty()) {\n\t\tfor (const std::string &path : TVPGetApplicationHomeDirectory()) {\n\t\t\tret.emplace_back(path + \"/\");\n\t\t}\n\t}\n\treturn ret;\n}\n#endif\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPFileMedia::GetLocallyAccessibleName(ttstr &name)\n{\n\tttstr newname;\n\n\tconst tjs_char *ptr = name.c_str();\n\n#ifdef WIN32\n\tif(TJS_strncmp(ptr, TJS_W(\"./\"), 2))\n\t{\n\t\t// differs from \"./\",\n\t\t// this may be a UNC file name.\n\t\t// UNC first two chars must be \"\\\\\\\\\" ?\n\t\t// AFAIK 32-bit version of Windows assumes that '/' can be used as a path\n\t\t// delimiter. Can UNC \"\\\\\\\\\" be replaced by \"//\" though ?\n\n\t\tnewname = ttstr(TJS_W(\"\\\\\\\\\")) + ptr;\n\t}\n\telse\n\t{\n\t\tptr += 2;  // skip \"./\"\n\t\tif(!*ptr) {\n\t\t\tnewname = TJS_W(\"\");\n\t\t} else {\n\t\t\ttjs_char dch = *ptr;\n\t\t\tif(*ptr < TJS_W('a') || *ptr > TJS_W('z')) {\n\t\t\t\tnewname = TJS_W(\"\");\n\t\t\t} else {\n\t\t\t\tptr++;\n\t\t\t\tif(*ptr != TJS_W('/')) {\n\t\t\t\t\tnewname = TJS_W(\"\");\n\t\t\t\t} else {\n\t\t\t\t\tnewname = ttstr(dch) + TJS_W(\":\") + ptr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// change path delimiter to '\\\\'\n\ttjs_char *pp = newname.Independ();\n\twhile(*pp)\n\t{\n\t\tif(*pp == TJS_W('/')) *pp = TJS_W('\\\\');\n\t\tpp++;\n\t}\n#else // posix\n    if(!TJS_strncmp(ptr, TJS_W(\"./\"), 2)) {\n        ptr += 2;  // skip \"./\"\n        newname.Clear();\n    }\n#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS\n    {\n        std::string prefix = \"/\";\n        prefix += tTJSNarrowStringHolder(ptr).Buf;\n        static const std::vector<ttstr> &prefixPath = _getPrefixPath();\n\t\tstatic const std::vector<std::string> &homeDir = _getHomeDir();\n\t\tfor (int i = 0; i < prefixPath.size(); ++i) {\n\t\t\tconst std::string &dir = homeDir[i];\n\t\t\tif (prefix.length() < dir.length()) continue;\n\t\t\tstd::string actualPrefix = prefix.substr(0, dir.length());\n\t\t\tif (!_utf8_strcasecmp(actualPrefix.c_str(), dir.c_str())) {\n\t\t\t\tnewname = prefixPath[i];\n\t\t\t\tptr += prefixPath[i].length();\n\t\t\t\twhile (*ptr && *ptr == TJS_W('/')) ++ptr;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n    }\n#endif\n    while(*ptr) {\n    \tconst tjs_char *ptr_end = ptr;\n    \twhile(*ptr_end && *ptr_end != TJS_W('/')) ++ptr_end;\n    \tif(ptr_end == ptr) break;\n        const tjs_char *ptr_cur = ptr;\n    \ttTJSNarrowStringHolder walker(ttstr(ptr, ptr_end - ptr).c_str());\n    \twhile(*ptr_end && *ptr_end == TJS_W('/')) ++ptr_end;\n    \tptr = ptr_end;\n\n        DIR *dirp;\n        struct dirent *direntp;\n\t\tnewname += \"/\";\n        if ((dirp = opendir( tTJSNarrowStringHolder(newname.c_str()) ))) {\n        \tbool found = false;\n            while ((direntp = readdir( dirp)) != NULL) {\n            \tif(!_utf8_strcasecmp(walker, direntp->d_name)) {\n            \t\tnewname += direntp->d_name;\n            \t\tfound = true;\n            \t\tbreak;\n            \t}\n            }\n            closedir(dirp);\n            if(!found) {\n                newname += ptr_cur;\n            \tbreak;\n            }\n        } else {\n            newname += ptr_cur;\n            break;\n        }\n    }\n\n#endif\n\tname = newname;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPFileMedia::GetLocalName(ttstr &name)\n{\n\tttstr tmp = name;\n\tGetLocallyAccessibleName(tmp);\n\tif(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPCannotGetLocalName, name);\n\tname = tmp;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\niTVPStorageMedia * TVPCreateFileMedia()\n{\n\treturn new tTVPFileMedia;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPPreNormalizeStorageName\n//---------------------------------------------------------------------------\nvoid TVPPreNormalizeStorageName(ttstr &name)\n{\n\t// if the name is an OS's native expression, change it according with the\n\t// TVP storage system naming rule.\n\ttjs_int namelen = name.GetLen();\n\tif(namelen == 0) return;\n#ifdef WIN32\n\tif(namelen >= 2)\n\t{\n\t\tif((name[0] >= TJS_W('a') && name[0]<=TJS_W('z') ||\n\t\t\tname[0] >= TJS_W('A') && name[0]<=TJS_W('Z') ) &&\n\t\t\tname[1] == TJS_W(':'))\n\t\t{\n\t\t\t// Windows drive:path expression\n\t\t\tttstr newname(TJS_W(\"file://./\"));\n\t\t\tnewname += name[0];\n\t\t\tnewname += (name.c_str()+2);\n            name = newname;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif(namelen>=3)\n\t{\n\t\tif(name[0] == TJS_W('\\\\') && name[1] == TJS_W('\\\\') ||\n\t\t\tname[0] == TJS_W('/') && name[1] == TJS_W('/'))\n\t\t{\n\t\t\t// unc expression\n\t\t\tname = ttstr(TJS_W(\"file:\")) + name;\n\t\t\treturn;\n\t\t}\n\t}\n#else // posix\n    if(namelen>=1) {\n        if(name[0] == TJS_W('/')) {\n            name = ttstr(TJS_W(\"file://.\")) + name;\n            return;\n        }\n    }\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetTemporaryName\n//---------------------------------------------------------------------------\nstatic tjs_int TVPTempUniqueNum = 0;\nstatic tTJSCriticalSection TVPTempUniqueNumCS;\nstatic ttstr TVPTempPath;\nbool TVPTempPathInit = false;\nstatic tjs_int TVPProcessID;\nttstr TVPGetTemporaryName()\n{\n\tstatic tjs_int TVPTempUniqueNum = (tjs_int)TVPGetRoughTickCount32();\n\ttjs_int num = TVPTempUniqueNum++;\n\tttstr TVPTempPath = TVPGetAppPath();\n#if 0\n\ttjs_int num;\n\n\t{\n\t\ttTJSCriticalSectionHolder holder(TVPTempUniqueNumCS);\n\n\t\tif(!TVPTempPathInit)\n\t\t{\n\t\t\twchar_t tmp[MAX_PATH+1];\n\t\t\t::GetTempPath(MAX_PATH, tmp);\n\t\t\tTVPTempPath = tmp;\n\n\t\t\tif(TVPTempPath.GetLastChar() != TJS_W('\\\\')) TVPTempPath += TJS_W(\"\\\\\");\n\t\t\tTVPProcessID = (tjs_int) GetCurrentProcessId();\n\t\t\tTVPTempUniqueNum = (tjs_int) GetTickCount();\n\t\t\tTVPTempPathInit = true;\n\t\t}\n\t\tnum = TVPTempUniqueNum ++;\n\t}\n#endif\n\tunsigned char buf[16];\n\tTVPGetRandomBits128(buf);\n\ttjs_char random[128];\n\tTJS_snprintf(random, sizeof(random)/sizeof(tjs_char), TJS_W(\"%02x%02x%02x%02x%02x%02x\"),\n\t\tbuf[0], buf[1], buf[2], buf[3],\n\t\tbuf[4], buf[5]);\n\n\treturn TVPTempPath + TJS_W(\"krkr_\") + ttstr(random) +\n\t\tTJS_W(\"_\") + ttstr(num) + TJS_W(\"_\") + ttstr(TVPProcessID);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPRemoveFile\n//---------------------------------------------------------------------------\nbool TVPRemoveFile(const ttstr &name)\n{\n    tTJSNarrowStringHolder holder(name.c_str());\n    return !remove(holder);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPRemoveFolder\n//---------------------------------------------------------------------------\nbool TVPRemoveFolder(const ttstr &name)\n{\n    tTJSNarrowStringHolder holder(name.c_str());\n    return !unlink(holder);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetAppPath\n//---------------------------------------------------------------------------\nttstr TVPGetAppPath()\n{\n#if 0\n\tstatic ttstr exepath(TVPExtractStoragePath(TVPNormalizeStorageName(ExePath())));\n\treturn exepath;\n#endif\n\tstatic ttstr apppath(TVPExtractStoragePath(TVPProjectDir));\n\treturn apppath;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// TVPOpenStream\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TVPOpenStream(const ttstr & _name, tjs_uint32 flags)\n{\n\t// open storage named \"name\".\n\t// currently only local/network(by OS) storage systems are supported.\n\tif(_name.IsEmpty())\n\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, TJS_W(\"\\\"\\\"\"));\n\n\tttstr origname = _name;\n\tttstr name(_name);\n\tTVPGetLocalName(name);\n\n\treturn new tTVPLocalFileStream(origname, name, flags);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCheckExistantLocalFile\n//---------------------------------------------------------------------------\nbool TVPCheckExistentLocalFile(const ttstr &name)\n{\n#if 0\n\tDWORD attrib = ::GetFileAttributes(name.c_str());\n\tif(attrib == 0xffffffff || (attrib & FILE_ATTRIBUTE_DIRECTORY))\n\t\treturn false; // not a file\n\telse\n\t\treturn true; // a file\n#endif\n\ttTVP_stat s;\n    if(!TVP_stat(name.c_str(), s)) {\n        return false; // not exist\n    }\n    return s.st_mode & S_IFREG;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCheckExistantLocalFolder\n//---------------------------------------------------------------------------\nbool TVPCheckExistentLocalFolder(const ttstr &name)\n{\n#if 0\n\tDWORD attrib = GetFileAttributes(name.c_str());\n\tif(attrib != 0xffffffff && (attrib & FILE_ATTRIBUTE_DIRECTORY))\n\t\treturn true; // a folder\n\telse\n\t\treturn false; // not a folder\n#endif\n\ttTVP_stat s;\n\tif (!TVP_stat(name.c_str(), s)) {\n        return false; // not exist\n    }\n\n    return s.st_mode & S_IFDIR;\n}\n//---------------------------------------------------------------------------\n\n\n\ntTVPArchive * TVPOpenZIPArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName);\ntTVPArchive * TVPOpen7ZArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName);\ntTVPArchive * TVPOpenTARArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName);\nstatic tTVPArchive*(*ArchiveCreators[])(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) = {\n\tTVPOpenZIPArchive,\n\tTVPOpen7ZArchive,\n\tTVPOpenTARArchive,\n\ttTVPXP3Archive::Create\n};\n\n//---------------------------------------------------------------------------\n// TVPOpenArchive\n//---------------------------------------------------------------------------\ntTVPArchive * TVPOpenArchive(const ttstr & name, bool normalizeFileName)\n{\n#if 0\n\ttTVPArchive * archive = TVPOpenSusieArchive(name); // in SusieArchive.h\n\tif(!archive) return new tTVPXP3Archive(name); else return archive;\n#endif\n\ttTJSBinaryStream *st = TVPCreateStream(name);\n\tif (!st) return nullptr;\n\tfor (int i = 0; i < sizeof(ArchiveCreators) / sizeof(ArchiveCreators[0]); ++i) {\n\t\ttTVPArchive*(*creator)(const ttstr &, tTJSBinaryStream*, bool) = ArchiveCreators[i];\n\t\ttTVPArchive * archive = creator(name, st, normalizeFileName);\n\t\tif (archive) return archive;\n\t\tst->SetPosition(0);\n\t}\n\tdelete st;\n\treturn nullptr;\n}\n//---------------------------------------------------------------------------\nint TVPCheckArchive(const ttstr &localname)\n{\n\ttTVPArchive *arc = nullptr;\n\tint validArchive = 2; // archive but no startup.tjs\n\ttry {\n\t\tarc = TVPOpenArchive(TVPNormalizeStorageName(localname), false);\n\t\tif (arc) {\n\t\t\ttjs_uint count = arc->GetCount();\n\t\t\tttstr str_startup_tjs = TJS_W(\"startup.tjs\");\n\t\t\t//ttstr str_sys_init_tjs = TJS_W(\"system/initialize.tjs\");\n\t\t\tfor (int i = 0; i < count; ++i) {\n\t\t\t\tttstr name = arc->GetName(i);\n\t\t\t\tif (name.length() == str_startup_tjs.length()) {\n\t\t\t\t\tarc->NormalizeInArchiveStorageName(name);\n\t\t\t\t\tif (name == str_startup_tjs) {\n\t\t\t\t\t\tvalidArchive = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n// \t\t\t\telse if (name.length() == str_sys_init_tjs.length()) {\n// \t\t\t\t\tarc->NormalizeInArchiveStorageName(name);\n// \t\t\t\t\tif (name == str_sys_init_tjs) {\n// \t\t\t\t\t\tvalidArchive = true;\n// \t\t\t\t\t\tbreak;\n// \t\t\t\t\t}\n// \t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (eTJSError e) {\n\t\t//arc = nullptr;\n\t}\n\tif (arc) {\n\t\tdelete arc;\n\t\treturn validArchive;\n\t}\n\treturn 0; // not archive\n}\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPLocalExtrectFilePath\n//---------------------------------------------------------------------------\nttstr TVPLocalExtractFilePath(const ttstr & name)\n{\n\t// this extracts given name's path under local filename rule\n\tconst tjs_char *p = name.c_str();\n\ttjs_int i = name.GetLen() -1;\n\tfor(; i >= 0; i--)\n\t{\n\t\tif(p[i] == TJS_W(':') || p[i] == TJS_W('/') ||\n\t\t\tp[i] == TJS_W('\\\\'))\n\t\t\tbreak;\n\t}\n\treturn ttstr(p, i + 1);\n}\n//---------------------------------------------------------------------------\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// TVPCreateFolders\n//---------------------------------------------------------------------------\nstatic bool _TVPCreateFolders(const ttstr &folder)\n{\n\t// create directories along with \"folder\"\n\tif(folder.IsEmpty()) return true;\n\n\tif(TVPCheckExistentLocalFolder(folder))\n\t\treturn true; // already created\n\n\tconst tjs_char *p = folder.c_str();\n\ttjs_int i = folder.GetLen() - 1;\n\n\tif(p[i] == TJS_W(':')) return true;\n\n\twhile(i >= 0 && (p[i] == TJS_W('/') || p[i] == TJS_W('\\\\'))) i--;\n\n\tif(i >= 0 && p[i] == TJS_W(':')) return true;\n\n\tfor(; i >= 0; i--)\n\t{\n\t\tif(p[i] == TJS_W(':') || p[i] == TJS_W('/') ||\n\t\t\tp[i] == TJS_W('\\\\'))\n\t\t\tbreak;\n\t}\n\n\tttstr parent(p, i + 1);\n\n\tif(!_TVPCreateFolders(parent)) return false;\n\n\tBOOL res = ::CreateDirectory(folder.c_str(), NULL);\n\treturn 0!=res;\n}\n\nbool TVPCreateFolders(const ttstr &folder)\n{\n\tif(folder.IsEmpty()) return true;\n\n\tconst tjs_char *p = folder.c_str();\n\ttjs_int i = folder.GetLen() - 1;\n\n\tif(p[i] == TJS_W(':')) return true;\n\n\tif(p[i] == TJS_W('/') || p[i] == TJS_W('\\\\')) i--;\n\n\treturn _TVPCreateFolders(ttstr(p, i+1));\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPLocalFileStream\n//---------------------------------------------------------------------------\ntTVPLocalFileStream::tTVPLocalFileStream(const ttstr &origname,\n\tconst ttstr &localname, tjs_uint32 flag)\n    : MemBuffer(nullptr), FileName(localname), Handle(-1)\n{\n\ttjs_uint32 access = flag & TJS_BS_ACCESS_MASK;\n    if(access == TJS_BS_WRITE) {\n        if (TVPCheckExistentLocalFile(localname)) {\n        } else {\n\t\t\tttstr dirpath = TVPLocalExtractFilePath(localname);\n\t\t\tconst tjs_char *p = dirpath.c_str();\n\t\t\ttjs_int i = dirpath.GetLen();\n\t\t\tif (p[i-1] == TJS_W('/') || p[i-1] == TJS_W('\\\\')) i--;\n\t\t\tdirpath = dirpath.SubString(0, i);\n\t\t\tif (!TVPCheckExistentLocalFolder(dirpath) && !TVPCreateFolders(dirpath)) {\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, origname);\n\t\t\t}\n//\t\t\t_lastFileSystemChanged = true;\n        }\n\t\tMemBuffer = new tTVPMemoryStream();\n\t\treturn;\n\t}\n\n\tunsigned int rw = 0;\n\tswitch(access)\n\t{\n\tcase TJS_BS_READ:\n\t\trw |= O_RDONLY;\t\t\t\tbreak;\n\tcase TJS_BS_WRITE:\n\t\trw |= O_RDWR | O_CREAT | O_TRUNC;\tbreak;\n\tcase TJS_BS_APPEND:\n        rw |= O_APPEND;\t    break;\n\tcase TJS_BS_UPDATE:\n\t\trw |= O_RDWR;\t\t\t    break;\n\t}\n\n\ttTJSNarrowStringHolder holder(localname.c_str());\n\tHandle = open(holder, rw, 0666);\n\tif (Handle < 0) {\n\t\tif (access == TJS_BS_APPEND || access == TJS_BS_UPDATE) {\n\t\t\t// use whole file writing\n\t\t\tHandle = open(holder, O_RDONLY, 0666);\n\t\t\tif (Handle >= 0) {\n\t\t\t\ttjs_uint64 size = GetSize();\n\t\t\t\tif (size < 4 * 1024 * 1024) { // only support file size <= 4M\n\t\t\t\t\tMemBuffer = new tTVPMemoryStream();\n\t\t\t\t\tMemBuffer->SetSize(size);\n\t\t\t\t\tread(Handle, MemBuffer->GetInternalBuffer(), size);\n\t\t}\n\t\t\t\tclose(Handle);\n\t\t\t\tHandle = -1;\n\t\t\t}\n\t\t}\n\t\tif (!MemBuffer)\n\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, origname);\n\t}\n\t// push current tick as an environment noise\n\tuint32_t tick = TVPGetRoughTickCount32();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n}\n//---------------------------------------------------------------------------\nbool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int len);\ntTVPLocalFileStream::~tTVPLocalFileStream()\n{\n    if(MemBuffer) {\n\t\tif (!TVPWriteDataToFile(FileName, MemBuffer->GetInternalBuffer(), MemBuffer->GetSize())) {\n\t\t\tdelete MemBuffer;\n\t\t\tttstr filename(FileName);\n\t\t\tFileName.~tTJSString();\n\t\t\tfree(this);\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"File Writing Error: %1\"), filename);\n\t\t}\n\t\tdelete MemBuffer;\n    }\n    if (Handle >= 0) {\n\t\tclose(Handle);\n\t}\n\n\t// push current tick as an environment noise\n\t// (timing information from file accesses may be good noises)\n\tuint32_t tick = TVPGetRoughTickCount32();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPLocalFileStream::Seek(tjs_int64 offset, tjs_int whence)\n{\n    if(MemBuffer) {\n        return MemBuffer->Seek(offset, whence);\n\t}\n\treturn lseek64(Handle, offset, whence);\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Read(void *buffer, tjs_uint read_size)\n{\n    if(MemBuffer) {\n        return MemBuffer->Read(buffer, read_size);\n\t}\n    return read(Handle, buffer, read_size);\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Write(const void *buffer, tjs_uint write_size)\n{\n    if(MemBuffer) {\n        return MemBuffer->Write(buffer, write_size);\n\t}\n    return write(Handle, buffer, write_size);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLocalFileStream::SetEndOfStorage()\n{\n    if(MemBuffer) {\n        return MemBuffer->SetEndOfStorage();\n\t}\n    lseek64(Handle, 0, SEEK_END);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPLocalFileStream::GetSize()\n{\n    if(MemBuffer) {\n        return MemBuffer->GetSize();\n    }\n\ttjs_uint64 ret;\n    tjs_int64 curpos = lseek64(Handle, 0, SEEK_CUR);\n    ret = lseek64(Handle, 0, SEEK_END);\n    lseek64(Handle, curpos, SEEK_SET);\n\treturn ret;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n#ifdef TJS_SUPPORT_VCL\n//---------------------------------------------------------------------------\n// TTVPStreamAdapter\n//---------------------------------------------------------------------------\n__fastcall TTVPStreamAdapter::TTVPStreamAdapter(tTJSBinaryStream *ref)\n{\n\tStream = ref;\n\tStream->SetPosition(0);\n}\n//---------------------------------------------------------------------------\n__fastcall TTVPStreamAdapter::~TTVPStreamAdapter()\n{\n\tdelete Stream;\n}\n//---------------------------------------------------------------------------\nint __fastcall TTVPStreamAdapter::Read(void *Buffer, int Count)\n{\n\treturn (int)Stream->Read(Buffer, Count);\n}\n//---------------------------------------------------------------------------\nint __fastcall TTVPStreamAdapter::Seek(int Offset, WORD Origin)\n{\n\ttjs_int whence;\n\tswitch(Origin)\n\t{\n\tcase soFromBeginning:\twhence = TJS_BS_SEEK_SET;\t\tbreak;\n\tcase soFromCurrent:\t\twhence = TJS_BS_SEEK_CUR;\t\tbreak;\n\tcase soFromEnd:\t\t\twhence = TJS_BS_SEEK_END;\t\tbreak;\n\t}\n\n\treturn (int)Stream->Seek(Offset, whence);\n}\n//---------------------------------------------------------------------------\nint __fastcall TTVPStreamAdapter::Write(const void *Buffer,int Count)\n{\n\treturn (int)Stream->Write(Buffer, Count);\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n#if 1\n//---------------------------------------------------------------------------\n// tTVPIStreamAdapter\n//---------------------------------------------------------------------------\n/*\nthis class provides COM's IStream adapter for tTJSBinaryStream\n*/\nclass tTVPIStreamAdapter : public IStream\n{\nprivate:\n\ttTJSBinaryStream *Stream;\n\tULONG RefCount;\n\npublic:\n\ttTVPIStreamAdapter(tTJSBinaryStream *ref);\n\t/*\n\tthe stream passed by argument here is freed by this instance'\n\tdestruction.\n\t*/\n\n\t~tTVPIStreamAdapter();\n\n\n\t// IUnknown\n\tHRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,\n\t\tvoid **ppvObject);\n\tULONG STDMETHODCALLTYPE AddRef(void);\n\tULONG STDMETHODCALLTYPE Release(void);\n\n\t// ISequentialStream\n\tHRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead);\n\tHRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb,\n\t\tULONG *pcbWritten);\n\n\t// IStream\n\tHRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove,\n\t\tDWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);\n\tHRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize);\n\tHRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb,\n\t\tULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);\n\tHRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags);\n\tHRESULT STDMETHODCALLTYPE Revert(void);\n\tHRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset,\n\t\tULARGE_INTEGER cb, DWORD dwLockType);\n\tHRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset,\n\t\tULARGE_INTEGER cb, DWORD dwLockType);\n\tHRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag);\n\tHRESULT STDMETHODCALLTYPE Clone(IStream **ppstm);\n\n\tvoid ClearStream() {\n\t\tStream = NULL;\n\t}\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTVPIStreamAdapter\n//---------------------------------------------------------------------------\n/*\n\tthis class provides adapter for COM's IStream\n*/\ntTVPIStreamAdapter::tTVPIStreamAdapter(tTJSBinaryStream *ref)\n{\n\tStream = ref;\n\tRefCount = 1;\n}\n//---------------------------------------------------------------------------\ntTVPIStreamAdapter::~tTVPIStreamAdapter()\n{\n\tdelete Stream;\n}\n//---------------------------------------------------------------------------\nextern \"C\" const IID IID_IUnknown;\nextern \"C\" const IID IID_IStream;\nextern \"C\" const IID IID_ISequentialStream;\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::QueryInterface(REFIID riid,\n\t\tvoid **ppvObject)\n{\n\tif(!ppvObject) return E_INVALIDARG;\n\n\t*ppvObject=NULL;\n\tif(!memcmp(&riid,&IID_IUnknown,16))\n\t\t*ppvObject=(IUnknown*)this;\n\telse if(!memcmp(&riid,&IID_ISequentialStream,16))\n\t\t*ppvObject=(ISequentialStream*)this;\n\telse if(!memcmp(&riid,&IID_IStream,16))\n\t\t*ppvObject=(IStream*)this;\n\n\tif(*ppvObject)\n\t{\n\t\tAddRef();\n\t\treturn S_OK;\n\t}\n\treturn E_NOINTERFACE;\n}\n//---------------------------------------------------------------------------\nULONG STDMETHODCALLTYPE tTVPIStreamAdapter::AddRef(void)\n{\n\treturn ++ RefCount;\n}\n//---------------------------------------------------------------------------\nULONG STDMETHODCALLTYPE tTVPIStreamAdapter::Release(void)\n{\n\tif(RefCount == 1)\n\t{\n\t\tdelete this;\n\t\treturn 0;\n\t}\n\telse\n\t{\n\t\treturn --RefCount;\n\t}\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Read(void *pv, ULONG cb, ULONG *pcbRead)\n{\n\ttry\n\t{\n\t\tULONG read;\n\t\tread = Stream->Read(pv, cb);\n\t\tif(pcbRead) *pcbRead = read;\n\t}\n\tcatch(...)\n\t{\n\t\treturn E_FAIL;\n\t}\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Write(const void *pv, ULONG cb,\n\t\tULONG *pcbWritten)\n{\n\ttry\n\t{\n\t\tULONG written;\n\t\twritten = Stream->Write(pv, cb);\n\t\tif(pcbWritten) *pcbWritten = written;\n\t}\n\tcatch(...)\n\t{\n\t\treturn E_FAIL;\n\t}\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Seek(LARGE_INTEGER dlibMove,\n\tDWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)\n{\n\ttry\n\t{\n\t\tswitch(dwOrigin)\n\t\t{\n\t\tcase STREAM_SEEK_SET:\n\t\t\tif(plibNewPosition)\n\t\t\t\t(*plibNewPosition).QuadPart =\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_SET);\n\t\t\telse\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_SET);\n\t\t\tbreak;\n\t\tcase STREAM_SEEK_CUR:\n\t\t\tif(plibNewPosition)\n\t\t\t\t(*plibNewPosition).QuadPart =\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_CUR);\n\t\t\telse\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_CUR);\n\t\t\tbreak;\n\t\tcase STREAM_SEEK_END:\n\t\t\tif(plibNewPosition)\n\t\t\t\t(*plibNewPosition).QuadPart =\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_END);\n\t\t\telse\n\t\t\t\t\tStream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_END);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn E_FAIL;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\treturn E_FAIL;\n\t}\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::SetSize(ULARGE_INTEGER libNewSize)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::CopyTo(IStream *pstm, ULARGE_INTEGER cb,\n\tULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Commit(DWORD grfCommitFlags)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Revert(void)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::LockRegion(ULARGE_INTEGER libOffset,\n\tULARGE_INTEGER cb, DWORD dwLockType)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::UnlockRegion(ULARGE_INTEGER libOffset,\n\tULARGE_INTEGER cb, DWORD dwLockType)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Stat(STATSTG *pstatstg, DWORD grfStatFlag)\n{\n\t// This method imcompletely fills the target structure, because some\n\t// informations like access mode or stream name are already lost\n\t// at this point.\n\n\tif(pstatstg)\n\t{\n\t\tmemset(pstatstg, 0, sizeof(*pstatstg));\n\n\t\t// pwcsName\n\t\t// this object's storage pointer does not have a name ...\n\t\tif(!(grfStatFlag &  STATFLAG_NONAME))\n\t\t{\n\t\t\t// anyway returns an empty string\n\t\t\tpstatstg->pwcsName = (LPOLESTR)TJS_W(\"\");\n\t\t}\n\n\t\t// type\n\t\tpstatstg->type = STGTY_STREAM;\n\n\t\t// cbSize\n\t\tpstatstg->cbSize.QuadPart = Stream->GetSize();\n\n\t\t// mtime, ctime, atime unknown\n\n\t\t// grfMode unknown\n\t\tpstatstg->grfMode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_DENY_WRITE ;\n\t\t\t// Note that this method always returns flags above, regardless of the\n\t\t\t// actual mode.\n\t\t\t// In the return value, the stream is to be indicated that the\n\t\t\t// stream can be written, but of cource, the Write method will fail\n\t\t\t// if the stream is read-only.\n\n\t\t// grfLockSuppoted\n\t\tpstatstg->grfLocksSupported = 0;\n\n\t\t// grfStatBits unknown\n\t}\n\telse\n\t{\n\t\treturn E_INVALIDARG;\n\t}\n\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nHRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Clone(IStream **ppstm)\n{\n\treturn E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n#endif\n\nIStream * TVPCreateIStream(tTJSBinaryStream *s) { return new tTVPIStreamAdapter(s); }\n//---------------------------------------------------------------------------\n// IStream creator\n//---------------------------------------------------------------------------\nIStream * TVPCreateIStream(const ttstr &name, tjs_uint32 flags)\n{\n\t// convert tTJSBinaryStream to IStream thru TStream\n\n\ttTJSBinaryStream *stream0 = NULL;\n\ttry\n\t{\n\t\tstream0 = TVPCreateStream(name, flags);\n\t}\n\tcatch(...)\n\t{\n\t\tif(stream0) delete stream0;\n\t\treturn NULL;\n\t}\n\n\tIStream *istream = new tTVPIStreamAdapter(stream0);\n\n\treturn istream;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// tTVPBinaryStreamAdapter\n//---------------------------------------------------------------------------\ntTVPBinaryStreamAdapter::tTVPBinaryStreamAdapter(IStream *ref)\n{\n\tStream = ref;\n\tStream->AddRef();\n}\n//---------------------------------------------------------------------------\ntTVPBinaryStreamAdapter::~tTVPBinaryStreamAdapter()\n{\n\tStream->Release();\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPBinaryStreamAdapter::Seek(tjs_int64 offset, tjs_int whence)\n{\n\tDWORD origin;\n\n\tswitch(whence)\n\t{\n\tcase TJS_BS_SEEK_SET:\t\t\torigin = STREAM_SEEK_SET;\t\tbreak;\n\tcase TJS_BS_SEEK_CUR:\t\t\torigin = STREAM_SEEK_CUR;\t\tbreak;\n\tcase TJS_BS_SEEK_END:\t\t\torigin = STREAM_SEEK_END;\t\tbreak;\n\tdefault:\t\t\t\t\t\torigin = STREAM_SEEK_SET;\t\tbreak;\n\t}\n\n\tLARGE_INTEGER ofs;\n\tULARGE_INTEGER newpos;\n\n\tofs.QuadPart = 0;\n\tHRESULT hr = Stream->Seek(ofs, STREAM_SEEK_CUR, &newpos);\n\tbool orgpossaved;\n\tLARGE_INTEGER orgpos;\n\tif(FAILED(hr))\n\t{\n\t\torgpossaved = false;\n\t}\n\telse\n\t{\n\t\torgpossaved = true;\n\t\t*(LARGE_INTEGER*)&orgpos = *(LARGE_INTEGER*)&newpos;\n\t}\n\n\tofs.QuadPart = offset;\n\n\thr = Stream->Seek(ofs, origin, &newpos);\n\tif(FAILED(hr))\n\t{\n\t\tif(orgpossaved)\n\t\t{\n\t\t\tStream->Seek(orgpos, STREAM_SEEK_SET, &newpos);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPSeekError);\n\t\t}\n\t}\n\n\treturn newpos.QuadPart;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPBinaryStreamAdapter::Read(void *buffer, tjs_uint read_size)\n{\n\tULONG cb = read_size;\n\tULONG read;\n\tHRESULT hr = Stream->Read(buffer, cb, &read);\n\tif(FAILED(hr)) read = 0;\n\treturn read;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD tTVPBinaryStreamAdapter::Write(const void *buffer, tjs_uint write_size)\n{\n\tULONG cb = write_size;\n\tULONG written;\n\tHRESULT hr = Stream->Write(buffer, cb, &written);\n\tif(FAILED(hr)) written = 0;\n\treturn written;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTVPBinaryStreamAdapter::GetSize()\n{\n\tHRESULT hr;\n\tSTATSTG stg;\n\n\thr = Stream->Stat(&stg, STATFLAG_NONAME);\n\tif(FAILED(hr))\n\t{\n\t\treturn inherited::GetSize(); // use default routine\n\t}\n\n\treturn stg.cbSize.QuadPart;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBinaryStreamAdapter::SetEndOfStorage()\n{\n\tULARGE_INTEGER pos;\n\tpos.QuadPart = GetPosition();\n\tHRESULT hr = Stream->SetSize(pos);\n\tif(FAILED(hr)) TVPThrowExceptionMessage(TVPTruncateError);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPCreateBinaryStreamAdapter\n//---------------------------------------------------------------------------\ntTJSBinaryStream * TVPCreateBinaryStreamAdapter(IStream *refstream)\n{\n\treturn new  tTVPBinaryStreamAdapter(refstream);\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPPluginHolder\n//---------------------------------------------------------------------------\ntTVPPluginHolder::tTVPPluginHolder(const ttstr &aname)\n{\n\tLocalTempStorageHolder = NULL;\n\n\t// search in TVP storage system\n\tttstr place(TVPGetPlacedPath(aname));\n\tif(!place.IsEmpty())\n\t{\n\t\tLocalTempStorageHolder = new tTVPLocalTempStorageHolder(place);\n\t}\n\telse\n\t{\n\t\t// not found in TVP storage system; search exepath, exepath\\system, exepath\\plugin\n#if 0\n\t\tttstr exepath =\n\t\t\tIncludeTrailingBackslash(ExtractFileDir(ExePath()));\n\t\tttstr pname = exepath + aname;\n\t\tif(TVPCheckExistentLocalFile(pname))\n\t\t{\n\t\t\tLocalName = pname;\n\t\t\treturn;\n\t\t}\n\n\t\tpname = exepath + TJS_W(\"system\\\\\") + aname;\n\t\tif(TVPCheckExistentLocalFile(pname))\n\t\t{\n\t\t\tLocalName = pname;\n\t\t\treturn;\n\t\t}\n\n#ifdef TJS_64BIT_OS\n\t\tpname = exepath + TJS_W(\"plugin64\\\\\") + aname;\n#else\n\t\tpname = exepath + TJS_W(\"plugin\\\\\") + aname;\n#endif\n\t\tif(TVPCheckExistentLocalFile(pname))\n\t\t{\n\t\t\tLocalName = pname;\n\t\t\treturn;\n\t\t}\n#endif\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPPluginHolder::~tTVPPluginHolder()\n{\n\tif(LocalTempStorageHolder)\n\t{\n\t\tdelete LocalTempStorageHolder;\n\t}\n}\n//---------------------------------------------------------------------------\nconst ttstr & tTVPPluginHolder::GetLocalName() const\n{\n\tif(LocalTempStorageHolder) return LocalTempStorageHolder->GetLocalName();\n\treturn LocalName;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSearchCD\n//---------------------------------------------------------------------------\nttstr TVPSearchCD(const ttstr & name)\n{\n\t// search CD which has specified volume label name.\n\t// return drive letter ( such as 'A' or 'B' )\n\t// return empty string if not found.\n#if 0\n\tstd::wstring narrow_name = name.AsStdString();\n\n\twchar_t dr[4];\n\tfor(dr[0]=L'A',dr[1]=L':',dr[2]=L'\\\\',dr[3]=0;dr[0]<=L'Z';dr[0]++)\n\t{\n\t\tif(::GetDriveType(dr) == DRIVE_CDROM)\n\t\t{\n\t\t\twchar_t vlabel[256];\n\t\t\twchar_t fs[256];\n\t\t\tDWORD mcl = 0,sfs = 0;\n\t\t\tGetVolumeInformation(dr, vlabel, 255, NULL, &mcl, &sfs, fs, 255);\n\t\t\tif( icomp(std::wstring(vlabel),narrow_name) )\n\t\t\t//if(std::string(vlabel).AnsiCompareIC(narrow_name)==0)\n\t\t\t\treturn ttstr((tjs_char)dr[0]);\n\t\t}\n\t}\n#endif\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n\n\ntTJSBinaryStream * TVPGetCachedArchiveHandle(void * pointer, const ttstr & name);\nvoid TVPReleaseCachedArchiveHandle(void * pointer, tTJSBinaryStream * stream);\nTArchiveStream::TArchiveStream(tTVPArchive *owner, tjs_uint64 off, tjs_uint64 len) : Owner(owner), StartPos(off), DataLength(len) {\n\tOwner->AddRef();\n\t_instr = TVPGetCachedArchiveHandle(Owner, Owner->ArchiveName);\n\tCurrentPos = 0;\n\t_instr->SetPosition(off);\n}\n\nTArchiveStream::~TArchiveStream() {\n\tTVPReleaseCachedArchiveHandle(Owner, _instr);\n\tOwner->Release();\n}\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Storages\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Storages()\n{\n\ttTJSNC_Storages *cls = new tTJSNC_Storages();\n\n\n\t// setup some platform-specific members\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/searchCD)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t\t*result = TVPSearchCD(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/searchCD)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getLocalName)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tttstr str(TVPNormalizeStorageName(*param[0]));\n\t\tTVPGetLocalName(str);\n\t\t*result = str;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/getLocalName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/selectFile)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tiTJSDispatch2 * dsp =  param[0]->AsObjectNoAddRef();\n\n\tbool res = TVPSelectFile(dsp);\n\n\tif(result) *result = (tjs_int)res;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/selectFile)\n//----------------------------------------------------------------------\n\n\n\treturn cls;\n\n}\n//---------------------------------------------------------------------------\n\nstatic FILE *_fileopen(ttstr path) {\n\tstd::string strpath = path.AsStdString();\n\tFILE *fp = fopen(strpath.c_str(), \"wb\");\n\tif (!fp) { // make dirs\n\t\tpath = TVPExtractStoragePath(path);\n\t\tTVPCreateFolders(path);\n\t\tfp = fopen(strpath.c_str(), \"wb\");\n\t}\n\treturn fp;\n}\n\nbool TVPSaveStreamToFile(tTJSBinaryStream *st, tjs_uint64 offset, tjs_uint64 size, ttstr outpath) {\n\tFILE *fp = _fileopen(outpath);\n\tif (!fp) return false;\n\ttjs_uint64 origpos = st->GetPosition();\n\tst->SetPosition(offset);\n\tstd::vector<char> buffer; buffer.resize(2 * 1024 * 1024);\n\twhile (size > 0) {\n\t\tunsigned int readsize = size > buffer.size() ? buffer.size() : size;\n\t\treadsize = st->Read(&buffer.front(), readsize);\n\t\tfwrite(&buffer.front(), 1, readsize, fp);\n\t\tsize -= readsize;\n\t}\n\tfclose(fp);\n\tst->SetPosition(origpos);\n\treturn true;\n}\n"
  },
  {
    "path": "src/core/base/win32/StorageImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Universal Storage System\n//---------------------------------------------------------------------------\n#ifndef StorageImplH\n#define StorageImplH\n//---------------------------------------------------------------------------\n#include \"StorageIntf.h\"\n#include \"UtilStreams.h\"\n#include <functional>\n\n//#include <objidl.h> // for IStream\n\n#if 0\n//---------------------------------------------------------------------------\n// Susie plug-in related\n//---------------------------------------------------------------------------\nvoid TVPLoadArchiveSPI(HINSTANCE inst);\nvoid TVPUnloadArchiveSPI(HINSTANCE inst);\n//---------------------------------------------------------------------------\n#endif\n\n#ifndef S_IFMT\n#define S_IFDIR  0x4000 // Directory\n#define S_IFREG  0x8000 // Regular\n#endif\n\nstruct tTVPLocalFileInfo {\n\tconst char * NativeName;\n\tunsigned short Mode; // S_IFMT\n\ttjs_uint64         Size;\n\ttime_t         AccessTime;\n\ttime_t         ModifyTime;\n\ttime_t         CreationTime;\n};\n\nvoid TVPGetLocalFileListAt(const ttstr &name, const std::function<void(const ttstr&, tTVPLocalFileInfo*)>& cb);\n\n//---------------------------------------------------------------------------\n// tTVPLocalFileStream\n//---------------------------------------------------------------------------\nclass tTVPLocalFileStream : public tTJSBinaryStream\n{\nprivate:\n\t//HANDLE Handle;\n    int Handle;\n    tTVPMemoryStream *MemBuffer = nullptr;\n    ttstr FileName;\n\npublic:\n\ttTVPLocalFileStream(const ttstr &origname, const ttstr & localname,\n\t\ttjs_uint32 flag);\n\t~tTVPLocalFileStream();\n\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence);\n\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size);\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size);\n\n\tvoid TJS_INTF_METHOD SetEndOfStorage();\n\n\ttjs_uint64 TJS_INTF_METHOD GetSize();\n\n\tint GetHandle() const { return Handle; }\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(bool, TVPCheckExistentLocalFolder, (const ttstr &name));\n\t/* name must be an OS's NATIVE folder name */\n\nTJS_EXP_FUNC_DEF(bool, TVPCheckExistentLocalFile, (const ttstr &name));\n\t/* name must be an OS's NATIVE file name */\n\nTJS_EXP_FUNC_DEF(bool, TVPCreateFolders, (const ttstr &folder));\n\t/* make folders recursively, like mkdir -p. folder must be OS NATIVE folder name */\n//---------------------------------------------------------------------------\n\n\n\n\n\n#ifdef TJS_SUPPORT_VCL\n//---------------------------------------------------------------------------\n// TTVPStreamAdapter\n//---------------------------------------------------------------------------\n/*\n\tthis class provides VCL's TStream adapter for tTJSBinaryStream\n*/\nclass TTVPStreamAdapter : public TStream\n{\nprivate:\n\ttTJSBinaryStream *Stream;\n\npublic:\n\t__fastcall TTVPStreamAdapter(tTJSBinaryStream *ref);\n\t/*\n\t\tthe stream passed by argument here is freed by this instance'\n\t\tdestruction.\n\t*/\n\n\t__fastcall ~TTVPStreamAdapter();\n\n\tint __fastcall Read(void *Buffer,int Count);\n\t\t// read\n\tint __fastcall Seek(int Offset,WORD Origin);\n\t\t// seek\n\tint __fastcall Write(const void *Buffer,int Count);\n\n\t__property Size;\n\t__property Position;\n};\n//---------------------------------------------------------------------------\n#endif\n\nclass tTVPIStreamAdapter;\n\n\nstruct IStream;\n//---------------------------------------------------------------------------\n// IStream creator\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(IStream *, TVPCreateIStream, (const ttstr &name, tjs_uint32 flags));\nTJS_EXP_FUNC_DEF(IStream *, TVPCreateIStream, (tTJSBinaryStream *));\n//---------------------------------------------------------------------------\n#if 0\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPBinaryStreamAdapter\n//---------------------------------------------------------------------------\n/*\n\tthis class provides tTJSBinaryStream adapter for IStream\n*/\nclass tTVPBinaryStreamAdapter : public tTJSBinaryStream\n{\n\ttypedef tTJSBinaryStream inherited;\n\nprivate:\n\tIStream *Stream;\n\npublic:\n\ttTVPBinaryStreamAdapter(IStream *ref);\n\t/*\n\t\tthe stream passed by argument here is freed by this instance'\n\t\tdestruction.\n\t*/\n\n\t~tTVPBinaryStreamAdapter();\n\n\ttjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence);\n\ttjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size);\n\ttjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size);\n\ttjs_uint64 TJS_INTF_METHOD GetSize();\n\tvoid TJS_INTF_METHOD SetEndOfStorage();\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPBinaryStreamAdapter creator\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamAdapter, (IStream *refstream));\n//---------------------------------------------------------------------------\n#endif\n\n\n//---------------------------------------------------------------------------\n// tTVPPluginHolder\n//---------------------------------------------------------------------------\n/*\n\ttTVPPluginHolder holds plug-in. if the plug-in is not a local storage,\n\tplug-in is to be extracted to temporary directory and be held until\n\tthe program done using it.\n*/\nclass tTVPPluginHolder\n{\nprivate:\n\tttstr LocalName;\n\ttTVPLocalTempStorageHolder * LocalTempStorageHolder;\n\npublic:\n\ttTVPPluginHolder(const ttstr &aname);\n\t~tTVPPluginHolder();\n\n\tconst ttstr & GetLocalName() const;\n};\n//---------------------------------------------------------------------------\n\nvoid TVPListDir(const std::string &folder, std::function<void(const std::string&, int)> cb);\nbool TVPSaveStreamToFile(tTJSBinaryStream *st, tjs_uint64 offset, tjs_uint64 size, ttstr outpath);\n#endif\n"
  },
  {
    "path": "src/core/base/win32/SusieArchive.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Archive eXtractor Susie plug-in support\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <time.h>\n#include \"StorageImpl.h\"\n#include \"SusieArchive.h\"\n#include \"GraphicsLoaderImpl.h\"\n#include \"DebugIntf.h\"\n#include \"XP3Archive.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include <algorithm>\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPSusieArchivePlugin\n//---------------------------------------------------------------------------\n#pragma pack(push, 1)\nstruct tTVPSusieFileInfo\n{\n\tunsigned char method[8];\t// compression method\n\tunsigned long position;\t\t// position in archive file\n\tunsigned long compsize;\t\t// compressed size\n\tunsigned long filesize;\t\t// original size\n\ttime_t timestamp;\t\t\t// update timestamp\n\tchar path[200];\t\t\t\t// relative path\n\tchar filename[200];\t\t\t// filename\n\tunsigned long crc;\t\t\t// CRC\n};\n#pragma pack(pop)\nstruct tTVPSusieFileRecord\n{\n\tttstr Name;\n\tunsigned long Position;\n\tunsigned long Size;\n\tbool operator < (const tTVPSusieFileRecord & rhs) const\n\t{\n\t\treturn this->Name < rhs.Name;\n\t}\n};\n//---------------------------------------------------------------------------\n// tTVPSusiePlugin is defined in GraphicLoaderImpl.h\nclass tTVPSusieArchivePlugin : public tTVPSusiePlugin\n{\n\ttTJSCriticalSection CS;\n\ttjs_int LockCount;\n\npublic:\n\ttTVPSusieArchivePlugin(HINSTANCE inst);\n\t~tTVPSusieArchivePlugin();\n\n\tvoid Lock();\n\tvoid Unlock();\n\n\tbool CanRelease() { return LockCount <= 0; }\n\n\tbool CheckSupported(tTVPLocalFileStream * stream, std::string localname);\n\n\tvoid GetFileList(std::wstring localname, std::vector<tTVPSusieFileRecord> &dest);\n\n\ttTJSBinaryStream * CreateStream(std::wstring localname,\n\t\tunsigned long pos, unsigned long sise);\n\n\ttTJSCriticalSection & GetCS() { return CS; }\n};\n//---------------------------------------------------------------------------\ntTVPSusieArchivePlugin::tTVPSusieArchivePlugin(HINSTANCE inst) :\n\ttTVPSusiePlugin(inst, \"00AM\")\n{\n\tLockCount = 0;\n}\n//---------------------------------------------------------------------------\ntTVPSusieArchivePlugin::~tTVPSusieArchivePlugin()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTVPSusieArchivePlugin::Lock()\n{\n\ttTJSCriticalSectionHolder holder(CS);\n\n\tLockCount++;\n}\n//---------------------------------------------------------------------------\nvoid tTVPSusieArchivePlugin::Unlock()\n{\n\ttTJSCriticalSectionHolder holder(CS);\n\n\tLockCount--;\n}\n//---------------------------------------------------------------------------\nbool tTVPSusieArchivePlugin::CheckSupported(tTVPLocalFileStream * stream,\n\tstd::string localname)\n{\n\tint res = IsSupported(const_cast<LPSTR>(localname.c_str()), (DWORD)stream->GetHandle());\n\n\treturn 0!=res;\n}\n//---------------------------------------------------------------------------\nvoid tTVPSusieArchivePlugin::GetFileList(std::wstring localname,\n\tstd::vector<tTVPSusieFileRecord> &dest)\n{\n\t// retrieve file list\n\tTVPAddLog( TVPFormatMessage(TVPInfoListingFiles, ttstr(localname.c_str()) ) );\n\n\tHLOCAL infohandle = NULL;\n\tint errorcode = 0xff&GetArchiveInfo(const_cast<LPSTR>(ttstr(localname).AsNarrowStdString().c_str()), 0, 0x00, &infohandle);\n\tif(infohandle == NULL)\n\t{\n\t\tTVPThrowExceptionMessage(TVPSusiePluginError,\n\t\t\tttstr(TJS_W(\"tTVPSusieArchivePlugin::GetArchiveInfo failed, errorcode = \")) +\n\t\t\tttstr((tjs_int)errorcode));\n\t}\n\telse\n\t{\n\t\tif(errorcode != 0)\n\t\t{\n\t\t\tTVPAddLog(TJS_W(\"Warning : invalid errorcode \") + ttstr((tjs_int)errorcode) +\n\t\t\t\tTJS_W(\" was returned from tTVPSusieArchivePlugin::GetArchiveInfo, \")\n\t\t\t\t\tTJS_W(\"continuing anyway.\"));\n\t\t}\n\t}\n\n\n\tconst tTVPSusieFileInfo *info = (const tTVPSusieFileInfo*)LocalLock(infohandle);\n\tif(info == NULL)\n\t{\n\t\tTVPThrowExceptionMessage(TVPSusiePluginError,\n\t\t\tttstr(TJS_W(\"tTVPSusieArchivePlugin::GetArchiveInfo failed : invalid memory block.\")));\n\t}\n\n\ttry\n\t{\n\t\twhile(info->method[0])\n\t\t{\n\t\t\tif(info->filename[0])\n\t\t\t{\n\t\t\t\tchar buf[401];\n\t\t\t\tTJS_nstrcpy(buf, info->path);\n\t\t\t\tTJS_nstrcat(buf, \"/\");\n\t\t\t\tTJS_nstrcat(buf, info->filename);\n\n\t\t\t\ttTVPSusieFileRecord record;\n\t\t\t\trecord.Name = buf;\n\t\t\t\ttTVPArchive::NormalizeInArchiveStorageName(record.Name);\n\t\t\t\trecord.Position = info->position;\n\t\t\t\trecord.Size = info->filesize;\n\n\t\t\t\tdest.push_back(record);\n\t\t\t}\n\n\t\t\tinfo++;\n\t\t}\n\n\t\t// sort item vector by its name (required for tTVPArchive specification)\n\t\tstd::stable_sort(dest.begin(), dest.end());\n\t}\n\tcatch(...)\n\t{\n\t\tLocalUnlock(infohandle);\n\t\tLocalFree(infohandle);\n\t\tthrow;\n\t}\n\n\tLocalUnlock(infohandle);\n\tLocalFree(infohandle);\n\n\tTVPAddLog(TJS_W(\"(info) \") + ttstr((tjs_int)dest.size()) + TJS_W(\" files found.\"));\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * tTVPSusieArchivePlugin::CreateStream(std::wstring localname,\n\tunsigned long pos, unsigned long size)\n{\n\tHLOCAL memhandle = NULL;\n\tint errorcode = 0xff & GetFile(const_cast<LPSTR>(ttstr(localname).AsNarrowStdString().c_str()), pos, (LPSTR)(void*)&memhandle,\n\t\t0x0100, (FARPROC)ProgressCallback, 0);\n\tif(errorcode || memhandle == NULL)\n\t{\n\t\tTVPThrowExceptionMessage(TVPSusiePluginError,\n\t\t\tttstr(TJS_W(\"tTVPSusieArchivePlugin::GetFile failed, errorcode = \")) +\n\t\t\tttstr((tjs_int)errorcode));\n\t}\n\n\ttTVPMemoryStream *memstream = new tTVPMemoryStream;\n\tvoid *memblock = NULL;\n\n\ttry\n\t{\n\t\tmemblock = LocalLock(memhandle);\n\t\tif(memblock == NULL)\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPSusiePluginError,\n\t\t\t\tttstr(TJS_W(\"tTVPSusieArchivePlugin::GetFile failed : invalid memory block.\")));\n\t\t}\n\n\t\t// write to on-memory stream\n\t\tmemstream->WriteBuffer(memblock, size);\n\t\tmemstream->SetPosition(0);\n\t}\n\tcatch(...)\n\t{\n\t\tif(memblock) LocalUnlock(memhandle);\n\t\tLocalFree(memhandle);\n\t\tdelete memstream;\n\t\tthrow;\n\t}\n\n\tif(memblock) LocalUnlock(memhandle);\n\tLocalFree(memhandle);\n\treturn memstream;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic std::vector<tTVPSusieArchivePlugin*> TVPSusiePluginVector;\n\nstatic void TVPDestroySusiePluginList()\n{\n\tstd::vector<tTVPSusieArchivePlugin*>::iterator i;\n\tfor(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++)\n\t{\n\t\tdelete *i;\n\t}\n}\nstatic tTVPAtExit TVPDestroySusiePluginListAtExit\n\t(TVP_ATEXIT_PRI_CLEANUP, TVPDestroySusiePluginList);\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPLoadArchiveSPI/TVPUnloadArchiveSPI : load/unload archive spi\n//---------------------------------------------------------------------------\nvoid TVPLoadArchiveSPI(HINSTANCE inst)\n{\n\t// load specified Susie plug-in.\n\tstd::vector<tTVPSusieArchivePlugin*>::iterator i;\n\tfor(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++)\n\t{\n\t\tif((*i)->GetModuleInstance() == inst)\n\t\t\tTVPThrowInternalError;\n\t}\n\n\ttTVPSusieArchivePlugin *spi = new tTVPSusieArchivePlugin(inst);\n\n\tTVPSusiePluginVector.push_back(spi);\n}\n//---------------------------------------------------------------------------\nvoid TVPUnloadArchiveSPI(HINSTANCE inst)\n{\n\t// unload specified Susie plug-in from system.\n\tstd::vector<tTVPSusieArchivePlugin*>::iterator i;\n\tfor(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++)\n\t{\n\t\tif((*i)->GetModuleInstance() == inst) break;\n\t}\n\n\tif(i == TVPSusiePluginVector.end())\n\t\tTVPThrowExceptionMessage(TVPNotLoadedPlugin);\n\n\tif(!(*i)->CanRelease())\n\t\tTVPThrowExceptionMessage(TVPCannotReleasePlugin);\n\n\tfor(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end();)\n\t{\n\t\tif((*i)->GetModuleInstance() == inst)\n\t\t\ti = TVPSusiePluginVector.erase(i);\n\t\telse\n\t\t\ti++;\n\t}\n\n\tdelete *i;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCheckSusieSupport : checks which plugin supports specified archive\n//---------------------------------------------------------------------------\ntTVPSusieArchivePlugin * TVPCheckSusieSupport(const ttstr &name, std::wstring &a_localname)\n{\n\tif(TVPSusiePluginVector.size() == 0) return NULL;\n\n\tttstr localname = TVPGetLocallyAccessibleName(name);\n\ttTVPLocalFileStream stream(name, localname, TJS_BS_READ);\n\n\tif(localname.GetLen() == 0) return NULL; // only local filesystem stream is supported\n\n\ta_localname = localname.AsStdString();\n\n\tstd::vector<tTVPSusieArchivePlugin*>::iterator i;\n\tfor(i = TVPSusiePluginVector.end() - 1; i >= TVPSusiePluginVector.begin(); i--)\n\t{\n\t\tstream.SetPosition(0);\n\t\tif((*i)->CheckSupported(&stream, localname.AsNarrowStdString()))\n\t\t\treturn *i;\n\t}\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPSusieArchive\n//---------------------------------------------------------------------------\nclass tTVPSusieArchive : public tTVPArchive\n{\n\ttTVPSusieArchivePlugin *Plugin;\n\tstd::wstring LocalName;\n\tstd::vector<tTVPSusieFileRecord> FileRecords;\n\npublic:\n\ttTVPSusieArchive(tTVPSusieArchivePlugin *plugin, const ttstr & name,\n\t\tstd::wstring localname);\n\t~tTVPSusieArchive();\n\n\ttjs_uint GetCount();\n\tttstr GetName(tjs_uint idx);\n\n\ttTJSBinaryStream * CreateStreamByIndex(tjs_uint idx);\n};\n//---------------------------------------------------------------------------\ntTVPSusieArchive::tTVPSusieArchive(tTVPSusieArchivePlugin *plugin,\n\tconst ttstr &name, std::wstring localname) : tTVPArchive(name)\n{\n\tLocalName = localname;\n\tPlugin = plugin;\n\n\ttTJSCriticalSectionHolder(Plugin->GetCS());\n\n\tPlugin->Lock();\n\n\tPlugin->GetFileList(LocalName, FileRecords);\n\n}\n//---------------------------------------------------------------------------\ntTVPSusieArchive::~tTVPSusieArchive()\n{\n\tPlugin->Unlock();\n}\n//---------------------------------------------------------------------------\ntjs_uint tTVPSusieArchive::GetCount()\n{\n\treturn (tjs_uint)FileRecords.size();\n}\n//---------------------------------------------------------------------------\nttstr tTVPSusieArchive::GetName(tjs_uint idx)\n{\n\treturn FileRecords[idx].Name;\n}\n//---------------------------------------------------------------------------\ntTJSBinaryStream * tTVPSusieArchive::CreateStreamByIndex(tjs_uint idx)\n{\n\ttTJSCriticalSectionHolder(Plugin->GetCS());\n\n\treturn Plugin->CreateStream(LocalName, FileRecords[idx].Position,\n\t\tFileRecords[idx].Size);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPOpenSusieArchive\n//---------------------------------------------------------------------------\ntTVPArchive * TVPOpenSusieArchive(const ttstr & name)\n{\n\tstd::wstring localname;\n\ttTVPSusieArchivePlugin *plugin = TVPCheckSusieSupport(name, localname);\n\tif(plugin)\n\t{\n\t\treturn new tTVPSusieArchive(plugin, name, localname);\n\t}\n\telse\n\t{\n\t\treturn NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/base/win32/SusieArchive.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Archive eXtractor Susie plug-in support\n//---------------------------------------------------------------------------\n#ifndef SusieArchiveH\n#define SusieArchiveH\n//---------------------------------------------------------------------------\n#include \"StorageIntf.h\"\n\nvoid TVPLoadArchiveSPI(HINSTANCE inst);\nvoid TVPUnloadArchiveSPI(HINSTANCE inst);\nclass tTVPArchive;\ntTVPArchive * TVPOpenSusieArchive(const ttstr & name);\n\n#endif\n"
  },
  {
    "path": "src/core/base/win32/SysInitImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Initialization and Uninitialization\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include \"FilePathUtil.h\"\n// #include <delayimp.h>\n// #include <mmsystem.h>\n// #include <objbase.h>\n// #include <commdlg.h>\n\n#include \"SysInitImpl.h\"\n#include \"StorageIntf.h\"\n#include \"StorageImpl.h\"\n#include \"MsgIntf.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"SystemControl.h\"\n#include \"DebugIntf.h\"\n#include \"tjsLex.h\"\n#include \"LayerIntf.h\"\n#include \"Random.h\"\n#include \"DetectCPU.h\"\n#include \"XP3Archive.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"XP3Archive.h\"\n//#include \"VersionFormUnit.h\"\n#include \"EmergencyExit.h\"\n\n//#include \"tvpgl_ia32_intf.h\"\n\n#include \"BinaryStream.h\"\n#include \"Application.h\"\n#include \"Exception.h\"\n#include \"ApplicationSpecialPath.h\"\n//#include \"resource.h\"\n//#include \"ConfigFormUnit.h\"\n#include \"TickCount.h\"\n#ifdef IID\n#undef IID\n#endif\n#define uint32_t unsigned int\n#include <thread>\n#undef uint32_t\n#include \"Platform.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n\n//---------------------------------------------------------------------------\n// global data\n//---------------------------------------------------------------------------\nttstr TVPNativeProjectDir;\nttstr TVPNativeDataPath;\nbool TVPProjectDirSelected = false;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// System security options\n//---------------------------------------------------------------------------\n// system security options are held inside the executable, where\n// signature checker will refer. This enables the signature checker\n// (or other security modules like XP3 encryption module) to check\n// the changes which is not intended by the contents author.\nconst static char TVPSystemSecurityOptions[] =\n\"-- TVPSystemSecurityOptions disablemsgmap(0):forcedataxp3(0):acceptfilenameargument(0) --\";\n//---------------------------------------------------------------------------\nint GetSystemSecurityOption(const char *name)\n{\n\tsize_t namelen = TJS_nstrlen(name);\n\tconst char *p = TJS_nstrstr(TVPSystemSecurityOptions, name);\n\tif(!p) return 0;\n\tif(p[namelen] == '(' && p[namelen + 2] == ')')\n\t\treturn p[namelen+1] - '0';\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// delayed DLL load procedure hook\n//---------------------------------------------------------------------------\n// for supporting of \"_inmm.dll\" (C) irori\n// http://www.geocities.co.jp/Playtown-Domino/8282/\n//---------------------------------------------------------------------------\n/*\nnote:\n\t_inmm.dll is a replacement of winmm.dll ( windows multimedia system dll ).\n\t_inmm.dll enables \"MCI CD-DA supporting applications\" to play musics using\n\tvarious way, including midi, mp3, wave or digital CD-DA, by applying a\n\tpatch on those applications.\n\n\tTVP(kirikiri) system has a special structure of executable file --\n\tdelayed loading of winmm.dll, in addition to compressed code/data area\n\tby the UPX executable packer.\n\t_inmm.dll's patcher can not recognize TVP's import area.\n\n\tSo we must implement supporting of _inmm.dll alternatively.\n\n\tThis function only works when -_inmm=yes or -inmm=yes option is specified at\n\tcommand line or embeded options area.\n*/\n//---------------------------------------------------------------------------\n#if 0\nstatic HMODULE _inmm = NULL;\nstatic FARPROC WINAPI DllLoadHook(dliNotification dliNotify,  DelayLoadInfo * pdli)\n{\n\tif(dliNotify == dliNotePreLoadLibrary)\n\t{\n\t\tif(!stricmp(pdli->szDll, \"winmm.dll\"))\n\t\t{\n\t\t\tHMODULE mod = LoadLibrary(\"_inmm.dll\");\n\t\t\tif(mod) _inmm = mod;\n\t\t\treturn (FARPROC)mod;\n\t\t}\n\t}\n\telse if(dliNotify == dliNotePreGetProcAddress)\n\t{\n\t\tif(_inmm == pdli->hmodCur)\n\t\t{\n\t\t\tchar buf[256];\n\t\t\tbuf[1] = 0;\n\t\t\tTJS_nstrcpy(buf, pdli->dlp.szProcName);\n\t\t\tbuf[0] = '_';\n\t\t\treturn (FARPROC)GetProcAddress(_inmm, buf);\n\t\t}\n\t}\n\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nstatic void RegisterDllLoadHook(void)\n{\n\tbool flag = false;\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-_inmm\"), &val) ||\n\t\tTVPGetCommandLine(TJS_W(\"-inmm\" ), &val) )\n\t{\n\t\t// _inmm support\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t\tflag = true;\n\t}\n\tif(flag) __pfnDliNotifyHook = DllLoadHook;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n#ifdef TVP_REPORT_HW_EXCEPTION\n//---------------------------------------------------------------------------\n// Hardware Exception Report Related\n//---------------------------------------------------------------------------\n// TVP's Hardware Exception Report comes with hacking RTL source.\n// insert following code into rtl/soruce/except/xx.cpp\n/*\ntypedef void __cdecl (*__dee_hacked_getExceptionObjectHook_type)(int ErrorCode,\n\t\tEXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx);\nstatic __dee_hacked_getExceptionObjectHook_type __dee_hacked_getExceptionObjectHook = NULL;\n\nextern \"C\"\n{\n\t__dee_hacked_getExceptionObjectHook_type\n\t\t__cdecl __dee_hacked_set_getExceptionObjectHook(\n\t\t__dee_hacked_getExceptionObjectHook_type handler)\n\t{\n\t\t__dee_hacked_getExceptionObjectHook_type oldhandler;\n\t\toldhandler = __dee_hacked_getExceptionObjectHook;\n\t\t__dee_hacked_getExceptionObjectHook = handler;\n\t\treturn oldhandler;\n\t}\n}\n*/\n// and insert following code into getExceptionObject\n/*\n\tif(__dee_hacked_getExceptionObjectHook)\n\t\t__dee_hacked_getExceptionObjectHook(ErrorCode, P, osEsp, osERR, ctx);\n*/\n//---------------------------------------------------------------------------\n/*\ntypedef void __cdecl (*__dee_hacked_getExceptionObjectHook_type)(int ErrorCode,\n\t\tEXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx);\nextern \"C\"\n{\n\textern __dee_hacked_getExceptionObjectHook_type\n\t\t__cdecl __dee_hacked_set_getExceptionObjectHook(\n\t\t__dee_hacked_getExceptionObjectHook_type handler);\n}\n*/\n\n//---------------------------------------------------------------------------\n// data\n#define TVP_HWE_MAX_CODES_AT_EIP 96\n#define TVP_HWE_MAX_STACK_AT_ESP 80\n#define TVP_HWE_MAX_STACK_DATA_DUMP  16\n#define TVP_HWE_MAX_CALL_TRACE 32\n#define TVP_HWE_MAX_CALL_CODE_DUMP 26\nstatic bool TVPHWExcRaised = false;\nstruct tTVPHWExceptionData\n{\n\ttjs_int Code;\n\ttjs_uint8 *EIP;\n\ttjs_uint32 *ESP;\n\tULONG_PTR AccessFlag; // for EAccessViolation (0=read, 1=write, 8=execute)\n\tvoid *AccessTarget; // for EAccessViolation\n\tCONTEXT Context; // OS exception context\n\twchar_t Module[MAX_PATH]; // module name which caused the exception\n\n\ttjs_uint8 CodesAtEIP[TVP_HWE_MAX_CODES_AT_EIP];\n\ttjs_int CodesAtEIPLen;\n\tvoid * StackAtESP[TVP_HWE_MAX_STACK_AT_ESP];\n\ttjs_int StackAtESPLen;\n\ttjs_uint8 StackDumps[TVP_HWE_MAX_STACK_AT_ESP][TVP_HWE_MAX_STACK_DATA_DUMP];\n\ttjs_int StackDumpsLen[TVP_HWE_MAX_STACK_AT_ESP];\n\n\tvoid * CallTrace[TVP_HWE_MAX_CALL_TRACE];\n\ttjs_int CallTraceLen;\n\ttjs_uint8 CallTraceDumps[TVP_HWE_MAX_CALL_TRACE][TVP_HWE_MAX_CALL_CODE_DUMP];\n\ttjs_int CallTraceDumpsLen[TVP_HWE_MAX_CALL_TRACE];\n};\nstatic tTVPHWExceptionData TVPLastHWExceptionData;\n\nHANDLE TVPHWExceptionLogHandle = NULL;\n//---------------------------------------------------------------------------\nstatic wchar_t TVPHWExceptionLogFilename[MAX_PATH];\n\nstatic void TVPWriteHWELogFile()\n{\n\tTVPEnsureDataPathDirectory();\n\tTJS_strcpy(TVPHWExceptionLogFilename, TVPNativeDataPath.c_str());\n\tTJS_strcat(TVPHWExceptionLogFilename, L\"hwexcept.log\");\n\tTVPHWExceptionLogHandle = CreateFile(TVPHWExceptionLogFilename, GENERIC_WRITE,\n\t\tFILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);\n\n\tif(TVPHWExceptionLogHandle == INVALID_HANDLE_VALUE) return;\n\tDWORD filesize;\n\tfilesize = GetFileSize(TVPHWExceptionLogHandle, NULL);\n\tSetFilePointer(TVPHWExceptionLogHandle, filesize, NULL, FILE_BEGIN);\n\n\t// write header\n\tconst wchar_t headercomment[] =\n\t\tL\"THIS IS A HARDWARE EXCEPTION LOG FILE OF KIRIKIRI. \"\n\t\tL\"PLEASE SEND THIS FILE TO THE AUTHOR WITH *.console.log FILE. \";\n\tDWORD written = 0;\n\tfor(int i = 0; i < 4; i++)\n\t\tWriteFile(TVPHWExceptionLogHandle, L\"----\", 4*sizeof(wchar_t), &written, NULL);\n\tWriteFile(TVPHWExceptionLogHandle, headercomment, sizeof(headercomment)-1,\n\t\t&written, NULL);\n\tfor(int i = 0; i < 4; i++)\n\t\tWriteFile(TVPHWExceptionLogHandle, L\"----\", 4*sizeof(wchar_t), &written, NULL);\n\t\t\n\n\t// write version\n\tWriteFile(TVPHWExceptionLogHandle, &TVPVersionMajor,\n\t\tsizeof(TVPVersionMajor), &written, NULL);\n\tWriteFile(TVPHWExceptionLogHandle, &TVPVersionMinor,\n\t\tsizeof(TVPVersionMinor), &written, NULL);\n\tWriteFile(TVPHWExceptionLogHandle, &TVPVersionRelease,\n\t\tsizeof(TVPVersionRelease), &written, NULL);\n\tWriteFile(TVPHWExceptionLogHandle, &TVPVersionBuild,\n\t\tsizeof(TVPVersionBuild), &written, NULL);\n\n\t// write tTVPHWExceptionData\n\tWriteFile(TVPHWExceptionLogHandle, &TVPLastHWExceptionData,\n\t\tsizeof(TVPLastHWExceptionData), &written, NULL);\n\n\n\t// close the handle\n\tif(TVPHWExceptionLogHandle != INVALID_HANDLE_VALUE)\n\t\tCloseHandle(TVPHWExceptionLogHandle);\n\n}\n//---------------------------------------------------------------------------\n//void __cdecl TVP__dee_hacked_getExceptionObjectHook(int ErrorCode,\n//\t\tEXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx)\n#ifdef TJS_64BIT_OS\nvoid TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long long osEsp, PCONTEXT ctx)\n#else\nvoid TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, PCONTEXT ctx)\n#endif\n{\n\t// exception hook function\n\tint len;\n\ttTVPHWExceptionData * d = &TVPLastHWExceptionData;\n\n\td->Code = ErrorCode;\n\n\t// get AccessFlag and AccessTarget\n\tif(d->Code == 11) // EAccessViolation\n\t{\n\t\td->AccessFlag = P->ExceptionInformation[0];\n\t\td->AccessTarget = (void*)P->ExceptionInformation[1];\n\t}\n\n\t// get OS context\n\tif(!IsBadReadPtr(ctx, sizeof(*ctx)))\n\t{\n\t\tmemcpy(&(d->Context), ctx, sizeof(*ctx));\n\t}\n\telse\n\t{\n\t\tmemset(&(d->Context), 0, sizeof(*ctx));\n\t}\n\n\t// get codes at eip\n\td->EIP = (tjs_uint8*)P->ExceptionAddress;\n\tlen = TVP_HWE_MAX_CODES_AT_EIP;\n\n\twhile(len)\n\t{\n\t\tif(!IsBadReadPtr(d->EIP, len))\n\t\t{\n\t\t\tmemcpy(d->CodesAtEIP, d->EIP, len);\n\t\t\td->CodesAtEIPLen = len;\n\t\t\tbreak;\n\t\t}\n\t\tlen--;\n\t}\n\n\t// get module name\n\tMEMORY_BASIC_INFORMATION mbi;\n\tVirtualQuery(d->EIP, &mbi, sizeof(mbi));\n\tif(mbi.State == MEM_COMMIT)\n\t{\n\t\tif(!GetModuleFileName((HMODULE)mbi.AllocationBase, d->Module,\n\t\t\tMAX_PATH))\n\t\t{\n\t\t\td->Module[0] = 0;\n\t\t}\n\t}\n\telse\n\t{\n\t\td->Module[0] = 0;\n\t}\n\n\n\t// get stack at esp\n\td->ESP = (tjs_uint32*)osEsp;\n\tlen = TVP_HWE_MAX_STACK_AT_ESP;\n\n\twhile(len)\n\t{\n\t\tif(!IsBadReadPtr(d->ESP, len * sizeof(tjs_uint32)))\n\t\t{\n\t\t\tmemcpy(d->StackAtESP, d->ESP, len * sizeof(tjs_uint32));\n\t\t\td->StackAtESPLen = len;\n\t\t\tbreak;\n\t\t}\n\t\tlen--;\n\t}\n\n\t// get data pointed by each stack data\n\tfor(tjs_int i = 0; i<d->StackAtESPLen; i++)\n\t{\n\t\tvoid * base = d->StackAtESP[i];\n\t\tlen = TVP_HWE_MAX_STACK_DATA_DUMP;\n\t\twhile(len)\n\t\t{\n\t\t\tif(!IsBadReadPtr(base, len))\n\t\t\t{\n\t\t\t\tmemcpy(d->StackDumps[i], base, len);\n\t\t\t\td->StackDumpsLen[i] = len;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlen--;\n\t\t}\n\t}\n\n\t// get call trace at esp\n\td->CallTraceLen = 0;\n\ttjs_int p = 0;\n\twhile(d->CallTraceLen < TVP_HWE_MAX_CALL_TRACE)\n\t{\n\t\tif(IsBadReadPtr(d->ESP + p, sizeof(tjs_uint32)))\n\t\t\tbreak;\n\n\t\tif(!IsBadReadPtr((void*)d->ESP[p], 4))\n\t\t{\n\t\t\tVirtualQuery((void*)d->ESP[p], &mbi, sizeof(mbi));\n\t\t\tif(mbi.State == MEM_COMMIT)\n\t\t\t{\n\t\t\t\twchar_t module[MAX_PATH];\n\t\t\t\tif(::GetModuleFileName((HMODULE)mbi.AllocationBase, module, MAX_PATH))\n\t\t\t\t{\n\t\t\t\t\ttjs_uint8 buf[16];\n\t\t\t\t\tif((DWORD)d->ESP[p] >= 16 &&\n\t\t\t\t\t\t!IsBadReadPtr((void*)((DWORD)d->ESP[p] - 16), 16))\n\t\t\t\t\t{\n\t\t\t\t\t\tmemcpy(buf, (void*)((DWORD)d->ESP[p] - 16), 16);\n\t\t\t\t\t\tbool flag = false;\n\t\t\t\t\t\tif(buf[11] == 0xe8) flag = true;\n\t\t\t\t\t\tif(!flag)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor(tjs_int i = 0; i<15; i++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(buf[i] == 0xff && (buf[i+1] & 0x38) == 0x10)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tflag = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(flag)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// this seems to be a call code\n\t\t\t\t\t\t\td->CallTrace[d->CallTraceLen] = (void *) d->ESP[p];\n\t\t\t\t\t\t\td->CallTraceLen ++;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tp ++;\n\t}\n\n\t// get data pointed by each call trace data\n\tfor(tjs_int i = 0; i<d->CallTraceLen; i++)\n\t{\n\t\tvoid * base = d->CallTrace[i];\n\t\tlen = TVP_HWE_MAX_STACK_DATA_DUMP;\n\t\twhile(len)\n\t\t{\n\t\t\tif(!IsBadReadPtr(base, len))\n\t\t\t{\n\t\t\t\tmemcpy(d->CallTraceDumps[i], base, len);\n\t\t\t\td->CallTraceDumpsLen[i] = len;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlen--;\n\t\t}\n\t}\n\n\tTVPHWExcRaised = true;\n\n\tTVPWriteHWELogFile();\n}\n//---------------------------------------------------------------------------\nstatic void TVPDumpCPUFlags(ttstr &line, DWORD flags, DWORD bit, tjs_char *name)\n{\n\tline += name;\n\tif(flags & bit)\n\t\tline += TJS_W(\"+ \");\n\telse\n\t\tline += TJS_W(\"- \");\n}\n//---------------------------------------------------------------------------\nvoid TVPDumpOSContext(const CONTEXT &ctx)\n{\n\t// dump OS context block\n\tstatic const int BUF_SIZE = 256;\n\ttjs_char buf[BUF_SIZE];\n\n\t// mask FP exception\n\tTJSSetFPUE();\n\n\t// - context flags\n\tttstr line;\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Context Flags : 0x%08X [ \"), ctx.ContextFlags);\n\tline += buf;\n\tif(ctx.ContextFlags & CONTEXT_DEBUG_REGISTERS)\n\t\tline += TJS_W(\"CONTEXT_DEBUG_REGISTERS \");\n\tif(ctx.ContextFlags & CONTEXT_FLOATING_POINT)\n\t\tline += TJS_W(\"CONTEXT_FLOATING_POINT \");\n\tif(ctx.ContextFlags & CONTEXT_SEGMENTS)\n\t\tline += TJS_W(\"CONTEXT_SEGMENTS \");\n\tif(ctx.ContextFlags & CONTEXT_INTEGER)\n\t\tline += TJS_W(\"CONTEXT_INTEGER \");\n\tif(ctx.ContextFlags & CONTEXT_CONTROL)\n\t\tline += TJS_W(\"CONTEXT_CONTROL \");\n#ifndef TJS_64BIT_OS\n\tif(ctx.ContextFlags & CONTEXT_EXTENDED_REGISTERS)\n\t\tline += TJS_W(\"CONTEXT_EXTENDED_REGISTERS \");\n#endif\n\tline += TJS_W(\"]\");\n\n\tTVPAddLog(line);\n\n\n\t// - debug registers\n#ifndef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE,\n\t\tTJS_W(\"Debug Registers   : \")\n\t\tTJS_W(\"0:0x%08X  \")\n\t\tTJS_W(\"1:0x%08X  \")\n\t\tTJS_W(\"2:0x%08X  \")\n\t\tTJS_W(\"3:0x%08X  \")\n\t\tTJS_W(\"6:0x%08X  \")\n\t\tTJS_W(\"7:0x%08X  \"),\n\t\t\tctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7);\n#else\n\tTJS_snprintf(buf, BUF_SIZE,\n\t\tTJS_W(\"Debug Registers   : \")\n\t\tTJS_W(\"0:0x%016lx  \")\n\t\tTJS_W(\"1:0x%016lx  \")\n\t\tTJS_W(\"2:0x%016lx  \")\n\t\tTJS_W(\"3:0x%016lx  \")\n\t\tTJS_W(\"6:0x%016lx  \")\n\t\tTJS_W(\"7:0x%016lx  \"),\n\t\t\tctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7);\n#endif\n\tTVPAddLog(buf);\n\n\n\t// - Segment registers\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Segment Registers : GS:0x%04X  FS:0x%04X  ES:0x%04X  DS:0x%04X  CS:0x%04X  SS:0x%04X\"),\n\t\tctx.SegGs, ctx.SegFs, ctx.SegEs, ctx.SegDs, ctx.SegCs, ctx.SegSs);\n\tTVPAddLog(buf);\n\n\t// - Generic Integer Registers\n#ifdef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Integer Registers : RAX:0x%016lx  RBX:0x%016lx  RCX:0x%016lx  RDX:0x%016lx\"),\n\t\tctx.Rax, ctx.Rbx, ctx.Rcx, ctx.Rdx);\n\tTVPAddLog(buf);\n\t\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"R8 :0x%016lx  R9 :0x%016lx  R10:0x%016lx  R11:0x%016lx\"), ctx.R8, ctx.R9, ctx.R10, ctx.R11);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"R12:0x%016lx  R13:0x%016lx  R14:0x%016lx  R15:0x%016lx\"), ctx.R12, ctx.R13, ctx.R14, ctx.R15);\n\tTVPAddLog(buf);\n#else\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Integer Registers : EAX:0x%08X  EBX:0x%08X  ECX:0x%08X  EDX:0x%08X\"),\n\t\tctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx);\n\tTVPAddLog(buf);\n#endif\n\n\t// - Index Registers\n#ifdef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Index Registers   : RSI:0x%016lx  RDI:0x%016lx\"),\n\t\tctx.Rsi, ctx.Rdi);\n#else\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Index Registers   : ESI:0x%08X  EDI:0x%08X\"),\n\t\tctx.Esi, ctx.Edi);\n#endif\n\tTVPAddLog(buf);\n\n\t// - Pointer Registers\n#ifdef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Pointer Registers : RBP:0x%016lx  RSP:0x%016lx  RIP:0x%016lx\"),\n\t\tctx.Rbp, ctx.Rsp, ctx.Rip);\n#else\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Pointer Registers : EBP:0x%08X  ESP:0x%08X  EIP:0x%08X\"),\n\t\tctx.Ebp, ctx.Esp, ctx.Eip);\n#endif\n\tTVPAddLog(buf);\n\n\t// - Flag Register\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"Flag Register     : 0x%08X [ \"),\n\t\tctx.EFlags);\n\tline = buf;\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 0), TJS_W(\"CF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 2), TJS_W(\"PF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 4), TJS_W(\"AF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 6), TJS_W(\"ZF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 7), TJS_W(\"SF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 8), TJS_W(\"TF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<< 9), TJS_W(\"IF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<10), TJS_W(\"DF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<11), TJS_W(\"OF\"));\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"IO%d \"), (ctx.EFlags >> 12) & 0x03);\n\tline += buf;\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<14), TJS_W(\"NF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<16), TJS_W(\"RF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<17), TJS_W(\"VM\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<18), TJS_W(\"AC\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<19), TJS_W(\"VF\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<20), TJS_W(\"VP\"));\n\tTVPDumpCPUFlags(line, ctx.EFlags, (1<<21), TJS_W(\"ID\"));\n\tline += TJS_W(\"]\");\n\tTVPAddLog(line);\n\n\t// - FP registers\n\n\t// -- control words\n#ifdef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Control Word : 0x%08X   FP Status Word : 0x%08X   FP Tag Word : 0x%08X\"),\n\t\tctx.FltSave.ControlWord, ctx.FltSave.StatusWord, ctx.FltSave.TagWord);\n\tTVPAddLog(buf);\n\n\t// -- offsets/selectors\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Error Offset : 0x%08X   FP Error Selector : 0x%08X\"),\n\t\tctx.FltSave.ErrorOffset, ctx.FltSave.ErrorSelector);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Data Offset  : 0x%08X   FP Data Selector  : 0x%08X\"),\n\t\tctx.FltSave.DataOffset, ctx.FltSave.DataSelector);\n\n\t// -- registers\n\tlong double *ptr = (long double *)&(ctx.FltSave.FloatRegisters[0]);\n\tfor(tjs_int i = 0; i < 8; i++)\n\t{\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP ST(%d) : %28.20Lg 0x%04X%016I64X\"), i,\n\t\t\tptr[i], (unsigned int)*(tjs_uint16*)(((tjs_uint8*)(ptr + i)) + 8),\n\t\t\t*(tjs_uint64*)(ptr + i));\n\t\tTVPAddLog(buf);\n\t}\n\n\t// -- Cr0NpxState\n\tTJS_snprintf(buf, BUF_SIZE,TJS_W(\"FP MX CSR   : 0x%08X\"), ctx.FltSave.MxCsr);\t//\n\tTVPAddLog(buf);\n#else\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Control Word : 0x%08X   FP Status Word : 0x%08X   FP Tag Word : 0x%08X\"),\n\t\tctx.FloatSave.ControlWord, ctx.FloatSave.StatusWord, ctx.FloatSave.TagWord);\n\tTVPAddLog(buf);\n\n\t// -- offsets/selectors\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Error Offset : 0x%08X   FP Error Selector : 0x%08X\"),\n\t\tctx.FloatSave.ErrorOffset, ctx.FloatSave.ErrorSelector);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP Data Offset  : 0x%08X   FP Data Selector  : 0x%08X\"),\n\t\tctx.FloatSave.DataOffset, ctx.FloatSave.DataSelector);\n\n\t// -- registers\n\tlong double *ptr = (long double *)&(ctx.FloatSave.RegisterArea[0]);\n\tfor(tjs_int i = 0; i < 8; i++)\n\t{\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"FP ST(%d) : %28.20Lg 0x%04X%016I64X\"), i,\n\t\t\tptr[i], (unsigned int)*(tjs_uint16*)(((tjs_uint8*)(ptr + i)) + 8),\n\t\t\t*(tjs_uint64*)(ptr + i));\n\t\tTVPAddLog(buf);\n\t}\n\n\t// -- Cr0NpxState\n\tTJS_snprintf(buf, BUF_SIZE,TJS_W(\"FP CR0 NPX State  : 0x%08X\"), ctx.FloatSave.Cr0NpxState);\n\tTVPAddLog(buf);\n#endif\n\n\t// -- SSE/SSE2 registers\n#ifdef TJS_64BIT_OS\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  0 : 0x%016lx 0x%016lx\"),ctx.Xmm0.High, ctx.Xmm0.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  1 : 0x%016lx 0x%016lx\"),ctx.Xmm1.High, ctx.Xmm1.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  2 : 0x%016lx 0x%016lx\"),ctx.Xmm2.High, ctx.Xmm2.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  3 : 0x%016lx 0x%016lx\"),ctx.Xmm3.High, ctx.Xmm3.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  4 : 0x%016lx 0x%016lx\"),ctx.Xmm4.High, ctx.Xmm4.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  5 : 0x%016lx 0x%016lx\"),ctx.Xmm5.High, ctx.Xmm5.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  6 : 0x%016lx 0x%016lx\"),ctx.Xmm6.High, ctx.Xmm6.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  7 : 0x%016lx 0x%016lx\"),ctx.Xmm7.High, ctx.Xmm7.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  8 : 0x%016lx 0x%016lx\"),ctx.Xmm8.High, ctx.Xmm8.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM  9 : 0x%016lx 0x%016lx\"),ctx.Xmm9.High, ctx.Xmm9.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 10 : 0x%016lx 0x%016lx\"),ctx.Xmm10.High, ctx.Xmm10.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 11 : 0x%016lx 0x%016lx\"),ctx.Xmm11.High, ctx.Xmm11.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 12 : 0x%016lx 0x%016lx\"),ctx.Xmm12.High, ctx.Xmm12.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 13 : 0x%016lx 0x%016lx\"),ctx.Xmm13.High, ctx.Xmm13.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 14 : 0x%016lx 0x%016lx\"),ctx.Xmm14.High, ctx.Xmm14.Low);\n\tTVPAddLog(buf);\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"XMM 15 : 0x%016lx 0x%016lx\"),ctx.Xmm15.High, ctx.Xmm15.Low);\n\tTVPAddLog(buf);\n\n\tTJS_snprintf(buf,BUF_SIZE,  TJS_W(\"MXCSR : 0x%08x\"), ctx.MxCsr );\n\tTVPAddLog(buf);\n#else\n\tif(ctx.ContextFlags & CONTEXT_EXTENDED_REGISTERS)\n\t{\n\t\t// ExtendedRegisters is a area which meets fxsave and fxrstor instruction?\n\t\t#pragma pack(push,1)\n\t\tunion xmm_t\n\t\t{\n\t\t\tstruct\n\t\t\t{\n\t\t\t\tfloat sA;\n\t\t\t\tfloat sB;\n\t\t\t\tfloat sC;\n\t\t\t\tfloat sD;\n\t\t\t};\n\t\t\tstruct\n\t\t\t{\n\t\t\t\tdouble dA;\n\t\t\t\tdouble dB;\n\t\t\t};\n\t\t\tstruct\n\t\t\t{\n\t\t\t\ttjs_uint64 i64A;\n\t\t\t\ttjs_uint64 i64B;\n\t\t\t};\n\t\t};\n\t\t#pragma pack(pop)\n\t\tfor(tjs_int i = 0; i < 8; i++)\n\t\t{\n\t\t\txmm_t * xmm = (xmm_t *)(ctx.ExtendedRegisters + i * 16+ 0xa0);\n\t\t\tTJS_snprintf(buf, BUF_SIZE,\n\t\t\t\tTJS_W(\"XMM %d : [ %15.8g %15.8g %15.8g %15.8g ] [ %24.16lg %24.16lg ] [ 0x%016I64X-0x%016I64X ]\"),\n\t\t\t\ti,\n\t\t\t\txmm->sD, xmm->sC, xmm->sB, xmm->sA,\n\t\t\t\txmm->dB, xmm->dA,\n\t\t\t\txmm->i64B, xmm->i64A);\n\t\t\tTVPAddLog(buf);\n\t\t}\n\t\tTJS_snprintf(buf,BUF_SIZE,  TJS_W(\"MXCSR : 0x%08X\"),\n\t\t\t*(DWORD*)(ctx.ExtendedRegisters + 0x18));\n\t\tTVPAddLog(buf);\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TVPDumpHWException()\n{\n\t// dump latest hardware exception if it exists\n\n\tif(!TVPHWExcRaised) return;\n\tTVPHWExcRaised = false;\n\n\tTVPOnError();\n\t\n\tstatic const int BUF_SIZE = 256;\n\ttjs_char buf[BUF_SIZE];\n\ttTVPHWExceptionData * d = &TVPLastHWExceptionData;\n\n\tTVPAddLog(ttstr(TVPHardwareExceptionRaised));\n\n\tttstr line;\n\n\tline = TJS_W(\"Exception : \");\n\n\ttjs_char *p = NULL;\n\tswitch(d->Code)\n\t{\n\tcase  3:\tp = TJS_W(\"Divide By Zero\"); break;\n\tcase  4:\tp = TJS_W(\"Range Error\"); break;\n\tcase  5:\tp = TJS_W(\"Integer Overflow\"); break;\n\tcase  6:\tp = TJS_W(\"Invalid Operation\"); break;\n\tcase  7:\tp = TJS_W(\"Zero Divide\"); break;\n\tcase  8:\tp = TJS_W(\"Overflow\"); break;\n\tcase  9:\tp = TJS_W(\"Underflow\"); break;\n\tcase 10:\tp = TJS_W(\"Invalid Cast\"); break;\n\tcase 11:\tp = TJS_W(\"Access Violation\"); break;\n\tcase 12:\tp = TJS_W(\"Privilege Violation\"); break;\n\tcase 13:\tp = TJS_W(\"Control C\"); break;\n\tcase 14:\tp = TJS_W(\"Stack Overflow\"); break;\n\t}\n\n\tif(p) line += p;\n\n\tif(d->Code == 11)\n\t{\n\t\t// EAccessViolation\n\t\tconst tjs_char *mode = TJS_W(\"unknown\");\n\t\tif(d->AccessFlag == 0)\n\t\t\tmode = TJS_W(\"read\");\n\t\telse if(d->AccessFlag == 1)\n\t\t\tmode = TJS_W(\"write\");\n\t\telse if(d->AccessFlag == 8)\n\t\t\tmode = TJS_W(\"execute\");\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"(%ls access to 0x%p)\"), mode, d->AccessTarget);\n\t\tline += buf;\n\t}\n\n\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"  at  EIP = 0x%p   ESP = 0x%p\"), d->EIP, d->ESP);\n\tline += buf;\n\tif(d->Module[0])\n\t{\n\t\tline += TJS_W(\"   in \") + ttstr(d->Module);\n\t}\n\n\tTVPAddLog(line);\n\n\t// dump OS context\n\tTVPDumpOSContext(d->Context);\n\n\t// dump codes at EIP\n\tline = TJS_W(\"Codes at EIP : \");\n\tfor(tjs_int i = 0; i<d->CodesAtEIPLen; i++)\n\t{\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"0x%02X \"), d->CodesAtEIP[i]);\n\t\tline += buf;\n\t}\n\tTVPAddLog(line);\n\n\tTVPAddLog(TJS_W(\"Stack data and data pointed by each stack data :\"));\n\n\t// dump stack and data\n\tfor(tjs_int s = 0; s<d->StackAtESPLen; s++)\n\t{\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"0x%p (ESP+%3d) : 0x%p : \"),\n\t\t\t(DWORD)d->ESP + s*sizeof(tjs_uint32),\n\t\t\ts*sizeof(tjs_uint32), d->StackAtESP[s]);\n\t\tline = buf;\n\n\t\tfor(tjs_int i = 0; i<d->StackDumpsLen[s]; i++)\n\t\t{\n\t\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"0x%02X \"), d->StackDumps[s][i]);\n\t\t\tline += buf;\n\t\t}\n\t\tTVPAddLog(line);\n\t}\n\n\t// dump call trace\n\tTVPAddLog(TJS_W(\"Call Trace :\"));\n\tfor(tjs_int s = 0; s<d->CallTraceLen; s++)\n\t{\n\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"0x%p : \"),\n\t\t\td->CallTrace[s]);\n\t\tline = buf;\n\n\t\tfor(tjs_int i = 0; i<d->CallTraceDumpsLen[s]; i++)\n\t\t{\n\t\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\"0x%02X \"), d->CallTraceDumps[s][i]);\n\t\t\tline += buf;\n\t\t}\n\t\tMEMORY_BASIC_INFORMATION mbi;\n\t\tVirtualQuery((void*)d->CallTrace[s], &mbi, sizeof(mbi));\n\t\tif(mbi.State == MEM_COMMIT)\n\t\t{\n\t\t\twchar_t module[MAX_PATH];\n\t\t\tif(::GetModuleFileName((HMODULE)mbi.AllocationBase, module, MAX_PATH))\n\t\t\t{\n\t\t\t\tline += ttstr(ExtractFileName(module).c_str());\n\t\t\t\tTJS_snprintf(buf, BUF_SIZE, TJS_W(\" base 0x%p\"), mbi.AllocationBase);\n\t\t\t\tline += buf;\n\t\t\t}\n\t\t}\n\t\tTVPAddLog(line);\n\t}\n}\n//---------------------------------------------------------------------------\n#else\nvoid TVPDumpHWException(void)\n{\n\t// dummy\n}\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// random generator initializer\n//---------------------------------------------------------------------------\nstatic BOOL CALLBACK TVPInitRandomEnumWinProc(HWND hwnd, LPARAM lparam)\n{\n\tRECT r;\n\tGetWindowRect(hwnd, &r);\n\tTVPPushEnvironNoise(&hwnd, sizeof(hwnd));\n\tTVPPushEnvironNoise(&r, sizeof(r));\n\tDWORD procid, threadid;\n\tthreadid = GetWindowThreadProcessId(hwnd, &procid);\n\tTVPPushEnvironNoise(&procid, sizeof(procid));\n\tTVPPushEnvironNoise(&threadid, sizeof(threadid));\n\treturn TRUE;\n}\n#endif\n//---------------------------------------------------------------------------\nstatic void TVPInitRandomGenerator()\n{\n\t// initialize random generator\n#if 0\n\tDWORD tick = GetTickCount();\n\tTVPPushEnvironNoise(&tick, sizeof(DWORD));\n\tGUID guid;\n\tCoCreateGuid(&guid);\n\tTVPPushEnvironNoise(&guid, sizeof(guid));\n\tDWORD id = GetCurrentProcessId();\n\tTVPPushEnvironNoise(&id, sizeof(id));\n\tid = GetCurrentThreadId();\n\tTVPPushEnvironNoise(&id, sizeof(id));\n\tSYSTEMTIME systime;\n\tGetSystemTime(&systime);\n\tTVPPushEnvironNoise(&systime, sizeof(systime));\n\tPOINT pt;\n\tGetCursorPos(&pt);\n\tTVPPushEnvironNoise(&pt, sizeof(pt));\n\n\tEnumWindows((WNDENUMPROC)TVPInitRandomEnumWinProc, 0);\n#endif\n\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tstd::thread::id tid = std::this_thread::get_id();\n\tTVPPushEnvironNoise(&tid, sizeof(tid));\n\ttime_t curtime = time(NULL);\n\tTVPPushEnvironNoise(&curtime, sizeof(curtime));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPInitializeBaseSystems\n//---------------------------------------------------------------------------\nvoid TVPInitializeBaseSystems()\n{\n\t// set system archive delimiter\n\ttTJSVariant v;\n\tif(TVPGetCommandLine(TJS_W(\"-arcdelim\"), &v))\n\t\tTVPArchiveDelimiter = ttstr(v)[0];\n\n\t// set default current directory\n\t{\n\t\tTVPSetCurrentDirectory( IncludeTrailingBackslash(ExtractFileDir(ExePath())) );\n\t}\n\n\t// load message map file\n\tbool load_msgmap = GetSystemSecurityOption(\"disablemsgmap\") == 0;\n\n\tif(load_msgmap)\n\t{\n\t\tconst tjs_char name_msgmap [] = TJS_W(\"msgmap.tjs\");\n\t\tif(TVPIsExistentStorage(name_msgmap))\n\t\t\tTVPExecuteStorage(name_msgmap, NULL, false, TJS_W(\"\"));\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// system initializer / uninitializer\n//---------------------------------------------------------------------------\n#if 0\n// tH_I_CAÕR[obN֐\nstatic int CALLBACK TVPBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)\n{\n    if(uMsg==BFFM_INITIALIZED){\n\t\twchar_t exeDir[MAX_PATH];\n\t\tTJS_strcpy(exeDir, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n        ::SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)exeDir);\n    }\n    return 0;\n}\n#endif\nstatic tjs_uint64 TVPTotalPhysMemory = 0;\nstatic void TVPInitProgramArgumentsAndDataPath(bool stop_after_datapath_got);\nvoid TVPBeforeSystemInit()\n{\n\t//RegisterDllLoadHook();\n\t\t// register DLL delayed import hook to support _inmm.dll\n\n\tTVPInitProgramArgumentsAndDataPath(false); // ensure command line\n\n\t// set system archive delimiter after patch.tjs specified\n\ttTJSVariant v;\n\tif (TVPGetCommandLine(TJS_W(\"-arcdelim\"), &v))\n\t\tTVPArchiveDelimiter = ttstr(v)[0];\n\n\tif (TVPIsExistentStorageNoSearchNoNormalize(TVPProjectDir)) {\n\t\tTVPProjectDir += TVPArchiveDelimiter;\n\t} else {\n\t\tTVPProjectDir += TJS_W(\"/\");\n\t}\n\tTVPSetCurrentDirectory(TVPProjectDir);\n\n#ifdef TVP_REPORT_HW_EXCEPTION\n\t// __dee_hacked_set_getExceptionObjectHook(TVP__dee_hacked_getExceptionObjectHook);\n\t\t// register hook function for hardware exceptions\n#endif\n#if 0\n\tApplication->SetHintHidePause( 24*60*60*1000 );\n\t\t// not to hide tool tip hint immediately\n\tApplication->SetShowHint( false );\n\tApplication->SetShowHint( true );\n\t\t// to ensure assigning new HintWindow Class defined in HintWindow.cpp \n#endif\n\n\t// randomize\n\tTVPInitRandomGenerator();\n\n\t// memory usage\n\t{\n#if 0\n\t\tMEMORYSTATUSEX status = { sizeof(MEMORYSTATUSEX) };\n\t\t::GlobalMemoryStatusEx(&status);\n\n\t\tTVPPushEnvironNoise(&status, sizeof(status));\n\n\t\tTVPTotalPhysMemory = status.ullTotalPhys;\n\n\t\tttstr memstr( std::to_wstring(TVPTotalPhysMemory).c_str() );\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPInfoTotalPhysicalMemory, memstr) );\n\n\t\ttTJSVariant opt;\n\t\tif(TVPGetCommandLine(TJS_W(\"-memusage\"), &opt))\n\t\t{\n\t\t\tttstr str(opt);\n\t\t\tif(str == TJS_W(\"low\"))\n\t\t\t\tTVPTotalPhysMemory = 0; // assumes zero\n\t\t}\n\n\t\tif(TVPTotalPhysMemory <= 36*1024*1024)\n\t\t{\n\t\t\t// very very low memory, forcing to assume zero memory\n\t\t\tTVPTotalPhysMemory = 0;\n\t\t}\n\n\t\tif(TVPTotalPhysMemory < 48*1024*1024ULL)\n\t\t{\n\t\t\t// extra low memory\n\t\t\tif(TJSObjectHashBitsLimit > 0)\n\t\t\t\tTJSObjectHashBitsLimit = 0;\n\t\t\tTVPSegmentCacheLimit = 0;\n\t\t\tTVPFreeUnusedLayerCache = true; // in LayerIntf.cpp\n\t\t}\n\t\telse if(TVPTotalPhysMemory < 64*1024*1024)\n\t\t{\n\t\t\t// low memory\n\t\t\tif(TJSObjectHashBitsLimit > 4)\n\t\t\t\tTJSObjectHashBitsLimit = 4;\n\t\t}\n#endif\n\t\tTVPMemoryInfo meminf;\n\t\tTVPGetMemoryInfo(meminf);\n\t\tTVPPushEnvironNoise(&meminf, sizeof(meminf));\n\t\t\n\t\tTVPTotalPhysMemory = meminf.MemTotal * 1024;\n\t\tif (TVPTotalPhysMemory > 768 * 1024 * 1024) {\n\t\t\tTVPTotalPhysMemory -= 512 * 1024 * 1024; // assume that system reserved 512M memory\n\t\t} else {\n\t\t\tTVPTotalPhysMemory /= 2; // use half memory in small memory devices\n\t\t}\n\n\t\tTVPAddImportantLog(TVPFormatMessage(TVPInfoTotalPhysicalMemory, tjs_int64(TVPTotalPhysMemory)));\n\t\tif (TVPTotalPhysMemory > 256 * 1024 * 1024) {\n\t\t\tstd::string str = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"memusage\", \"unlimited\");\n\t\t\tif (str == (\"low\"))\n\t\t\t\tTVPTotalPhysMemory = 0; // assumes zero\n\t\t\telse if (str == (\"medium\"))\n\t\t\t\tTVPTotalPhysMemory = 128 * 1024 * 1024;\n\t\t\telse if (str == (\"high\"))\n\t\t\t\tTVPTotalPhysMemory = 256 * 1024 * 1024;\n\t\t} else { // use minimum memory usage if less than 256M(512M physics)\n\t\t\tTVPTotalPhysMemory = 0;\n\t\t}\n\n\t\tif (TVPTotalPhysMemory < 128 * 1024 * 1024)\n\t\t{\n\t\t\t// very very low memory, forcing to assume zero memory\n\t\t\tTVPTotalPhysMemory = 0;\n\t\t}\n\n\t\tif (TVPTotalPhysMemory < 128 * 1024 * 1024)\n\t\t{\n\t\t\t// extra low memory\n\t\t\tif (TJSObjectHashBitsLimit > 0)\n\t\t\t\tTJSObjectHashBitsLimit = 0;\n\t\t\tTVPSegmentCacheLimit = 0;\n\t\t\tTVPFreeUnusedLayerCache = true; // in LayerIntf.cpp\n\t\t} else if (TVPTotalPhysMemory < 256 * 1024 * 1024)\n\t\t{\n\t\t\t// low memory\n\t\t\tif (TJSObjectHashBitsLimit > 4)\n\t\t\t\tTJSObjectHashBitsLimit = 4;\n\t\t}\n\t}\n#if 0\n\n\twchar_t buf[MAX_PATH];\n\tbool bufset = false;\n\tbool nosel = false;\n\tbool forcesel = false;\n\n\tbool forcedataxp3 = GetSystemSecurityOption(\"forcedataxp3\") != 0;\n\tbool acceptfilenameargument = GetSystemSecurityOption(\"acceptfilenameargument\") != 0;\n\n\tif(!forcedataxp3 && !acceptfilenameargument)\n\t{\n\t\tif(TVPGetCommandLine(TJS_W(\"-nosel\")) || TVPGetCommandLine(TJS_W(\"-about\")))\n\t\t{\n\t\t\tnosel = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twchar_t exeDir[MAX_PATH];\n\t\t\tTJS_strcpy(exeDir, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n\t\t\tfor(tjs_int i = 1; i<_argc; i++)\n\t\t\t{\n\t\t\t\tif(_argv[i][0] == '-' && _argv[i][1] == '-' && _argv[i][2] == 0)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif(_argv[i][0] != '-')\n\t\t\t\t{\n\t\t\t\t\t// TODO: set the current directory\n\t\t\t\t\t::SetCurrentDirectory( exeDir );\n\t\t\t\t\tTJS_strncpy(buf, ttstr(_argv[i]).c_str(), MAX_PATH-1);\n\t\t\t\t\tbuf[MAX_PATH-1] = TJS_W('\\0');\n\t\t\t\t\tif(DirectoryExists(buf)) // is directory?\n\t\t\t\t\t\tTJS_strcat(buf, TJS_W(\"\\\\\"));\n\n\t\t\t\t\tTVPProjectDirSelected = true;\n\t\t\t\t\tbufset = true;\n\t\t\t\t\tnosel = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// check \"-sel\" option, to force show folder selection window\n\tif(!forcedataxp3 && TVPGetCommandLine(TJS_W(\"-sel\")))\n\t{\n\t\t// sel option was set\n\t\tif(bufset)\n\t\t{\n\t\t\twchar_t path[MAX_PATH];\n\t\t\twchar_t *dum = 0;\n\t\t\tGetFullPathName(buf, MAX_PATH-1, path, &dum);\n\t\t\tTJS_strcpy(buf, path);\n\t\t\tTVPProjectDirSelected = false;\n\t\t\tbufset = true;\n\t\t}\n\t\tnosel = true;\n\t\tforcesel = true;\n\t}\n\n\t// check \"content-data\" directory\n\tif(!forcedataxp3 && !nosel)\n\t{\n\t\twchar_t tmp[MAX_PATH];\n\t\tTJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n\t\tTJS_strcat(tmp, TJS_W(\"content-data\"));\n\t\tif(DirectoryExists(tmp))\n\t\t{\n\t\t\tTJS_strcat(tmp, TJS_W(\"\\\\\"));\n\t\t\tTJS_strcpy(buf, tmp);\n\t\t\tTVPProjectDirSelected = true;\n\t\t\tbufset = true;\n\t\t\tnosel = true;\n\t\t}\n\t}\n\n\t// check \"data.xp3\" archive\n \tif(!nosel)\n\t{\n\t\twchar_t tmp[MAX_PATH];\n\t\tTJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n\t\tTJS_strcat(tmp, TJS_W(\"data.xp3\"));\n\t\tif(FileExists(tmp))\n\t\t{\n\t\t\tTJS_strcpy(buf, tmp);\n\t\t\tTVPProjectDirSelected = true;\n\t\t\tbufset = true;\n\t\t\tnosel = true;\n\t\t}\n\t}\n\n\t// check \"data.exe\" archive\n \tif(!nosel)\n\t{\n\t\twchar_t tmp[MAX_PATH];\n\t\tTJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n\t\tTJS_strcat(tmp, TJS_W(\"data.exe\"));\n\t\tif(FileExists(tmp))\n\t\t{\n\t\t\tTJS_strcpy(buf, tmp);\n\t\t\tTVPProjectDirSelected = true;\n\t\t\tbufset = true;\n\t\t\tnosel = true;\n\t\t}\n\t}\n\n\t// check self combined xpk archive\n\tif(!nosel)\n\t{\n\t\tif(TVPIsXP3Archive(TVPNormalizeStorageName(ExePath())))\n\t\t{\n\t\t\tTJS_strcpy(buf, ExePath().c_str());\n\t\t\tTVPProjectDirSelected = true;\n\t\t\tbufset = true;\n\t\t\tnosel = true;\n\t\t}\n\t}\n\n\n\t// check \"data\" directory\n\tif(!forcedataxp3 && !nosel)\n\t{\n\t\twchar_t tmp[MAX_PATH];\n\t\tTJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str());\n\t\tTJS_strcat(tmp, TJS_W(\"data\"));\n\t\tif(DirectoryExists(tmp))\n\t\t{\n\t\t\tTJS_strcat(tmp, TJS_W(\"\\\\\"));\n\t\t\tTJS_strcpy(buf, tmp);\n\t\t\tTVPProjectDirSelected = true;\n\t\t\tbufset = true;\n\t\t\tnosel = true;\n\t\t}\n\t}\n\n\t// decide a directory to execute or to show folder selection\n\tif(!bufset)\n\t{\n\t\tif(forcedataxp3) throw EAbort(TJS_W(\"Aborted\"));\n\t\tTJS_strcpy(buf, ExtractFileDir(ExePath()).c_str());\n\t\tint curdirlen = (int)TJS_strlen(buf);\n\t\tif(buf[curdirlen-1] != TJS_W('\\\\')) buf[curdirlen] = TJS_W('\\\\'), buf[curdirlen+1] = 0;\n\t}\n\n#ifndef TVP_DISABLE_SELECT_XP3_OR_FOLDER\n\tif(!forcedataxp3 && (!nosel || forcesel))\n\t{\n\t\tBOOL\t\t\tbRes;\n\t\twchar_t\t\t\tchPutFolder[MAX_PATH];\n\t\tLPITEMIDLIST\tpidlRetFolder;\n\t\tBROWSEINFO\t\tstBInfo;\n\t\t::ZeroMemory( &stBInfo, sizeof(stBInfo) );\n\n\t\tstBInfo.pidlRoot = NULL;\n\t\tstBInfo.hwndOwner = NULL;\n\t\tstBInfo.pszDisplayName = chPutFolder;\n\t\tstBInfo.lpszTitle = TVPSelectXP3FileOrFolder;\n\t\tstBInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_DONTGOBELOWDOMAIN|BIF_RETURNONLYFSDIRS;\n\t\tstBInfo.lpfn = TVPBrowseCallbackProc;\n\t\tstBInfo.lParam = NULL;\n\n\t\tpidlRetFolder = ::SHBrowseForFolder( &stBInfo );\n\t\tif( pidlRetFolder != NULL ) {\n\t\t\tbRes = ::SHGetPathFromIDList( pidlRetFolder, chPutFolder );\n\t\t\tif( bRes != FALSE ) {\n\t\t\t\twcsncpy( buf, chPutFolder, MAX_PATH );\n\t\t\t\ttjs_int buflen = (tjs_int)TJS_strlen(buf);\n\t\t\t\tif( buflen >= 1 ) {\n\t\t\t\t\tif( buf[buflen-1] != TJS_W('\\\\') && buflen < (MAX_PATH-2) ) {\n\t\t\t\t\t\tbuf[buflen] = TJS_W('\\\\');\n\t\t\t\t\t\tbuf[buflen+1] = TJS_W('\\0');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tTVPProjectDirSelected = true;\n\t\t\t}\n\t\t\t::CoTaskMemFree( pidlRetFolder );\n\t\t}\n\t}\n#endif\n\n\t// check project dir and store some environmental variables\n\tif(TVPProjectDirSelected)\n\t{\n\t\tApplication->SetShowMainForm( false );\n\t}\n\n\ttjs_int buflen = (tjs_int)TJS_strlen(buf);\n\tif(buflen >= 1)\n\t{\n\t\tif(buf[buflen-1] != TJS_W('\\\\')) buf[buflen] = TVPArchiveDelimiter, buf[buflen+1] = 0;\n\t}\n\n\tTVPProjectDir = TVPNormalizeStorageName(buf);\n\tTVPSetCurrentDirectory(TVPProjectDir);\n\tTVPNativeProjectDir = buf;\n\n\tif(TVPProjectDirSelected)\n\t{\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPInfoSelectedProjectDirectory, TVPProjectDir) );\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nstatic void TVPDumpOptions();\n//---------------------------------------------------------------------------\nextern bool TVPEnableGlobalHeapCompaction;\nextern void TVPGL_SSE2_Init();\nextern \"C\" void TVPGL_ASM_Init();\nextern bool TVPAutoSaveBookMark;\nstatic bool TVPHighTimerPeriod = false;\nstatic uint32_t TVPTimeBeginPeriodRes = 0;\n//---------------------------------------------------------------------------\nvoid TVPAfterSystemInit()\n{\n\t// check CPU type\n\tTVPDetectCPU();\n\n\tTVPAllocGraphicCacheOnHeap = false; // always false since beta 20\n\n\t// determine maximum graphic cache limit\n\ttTJSVariant opt;\n\ttjs_int64 limitmb = -1;\n\tif(TVPGetCommandLine(TJS_W(\"-gclim\"), &opt))\n\t{\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"auto\"))\n\t\t\tlimitmb = -1;\n\t\telse\n\t\t\tlimitmb = opt.AsInteger();\n\t}\n\n\n\tif(limitmb == -1)\n\t{\n\t\tif(TVPTotalPhysMemory <= 32*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 0;\n\t\telse if(TVPTotalPhysMemory <= 48*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 0;\n\t\telse if(TVPTotalPhysMemory <= 64*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 0;\n\t\telse if(TVPTotalPhysMemory <= 96*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 4;\n\t\telse if(TVPTotalPhysMemory <= 128*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 8;\n\t\telse if(TVPTotalPhysMemory <= 192*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 12;\n\t\telse if(TVPTotalPhysMemory <= 256*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 20;\n\t\telse if(TVPTotalPhysMemory <= 512*1024*1024)\n\t\t\tTVPGraphicCacheSystemLimit = 40;\n\t\telse\n\t\t\tTVPGraphicCacheSystemLimit = tjs_uint64(TVPTotalPhysMemory / (1024*1024*10));\t// cachemem = physmem / 10\n\t\tTVPGraphicCacheSystemLimit *= 1024*1024;\n\t}\n\telse\n\t{\n\t\tTVPGraphicCacheSystemLimit = limitmb * 1024*1024;\n\t}\n\t// 32bit Ȃ̂ 512MB ܂łɐ\n\tif( TVPGraphicCacheSystemLimit >= 512*1024*1024 )\n\t\tTVPGraphicCacheSystemLimit = 512*1024*1024;\n\n\n\tif(TVPTotalPhysMemory <= 64*1024*1024)\n\t\tTVPSetFontCacheForLowMem();\n\n//\tTVPGraphicCacheSystemLimit = 1*1024*1024; // DEBUG \n\n\tif(TVPGetCommandLine(TJS_W(\"-autosave\"), &opt))\n\t{\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"yes\")) {\n\t\t\tTVPAutoSaveBookMark = true;\n\t\t}\n\t}\n\t// check TVPGraphicSplitOperation option\n\tstd::string _val = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"renderer\", \"software\");\n\tif (_val != \"software\") {\n\t\tTVPGraphicSplitOperationType = gsotNone;\n\t} else {\n\t\tTVPDrawThreadNum = IndividualConfigManager::GetInstance()->GetValue<int>(\"software_draw_thread\", 0);\n\t\tif (TVPGetCommandLine(TJS_W(\"-gsplit\"), &opt))\n\t\t{\n\t\t\tttstr str(opt);\n\t\t\tif (str == TJS_W(\"no\"))\n\t\t\t\tTVPGraphicSplitOperationType = gsotNone;\n\t\t\telse if (str == TJS_W(\"int\"))\n\t\t\t\tTVPGraphicSplitOperationType = gsotInterlace;\n\t\t\telse if (str == TJS_W(\"yes\") || str == TJS_W(\"simple\"))\n\t\t\t\tTVPGraphicSplitOperationType = gsotSimple;\n\t\t\telse if (str == TJS_W(\"bidi\"))\n\t\t\t\tTVPGraphicSplitOperationType = gsotBiDirection;\n\n\t\t}\n\t}\n\n\t// check TVPDefaultHoldAlpha option\n\tif(TVPGetCommandLine(TJS_W(\"-holdalpha\"), &opt))\n\t{\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"yes\") || str == TJS_W(\"true\"))\n\t\t\tTVPDefaultHoldAlpha = true;\n\t\telse\n\t\t\tTVPDefaultHoldAlpha = false;\n\t}\n\n\t// check TVPJPEGFastLoad option\n\tif(TVPGetCommandLine(TJS_W(\"-jpegdec\"), &opt)) // this specifies precision for JPEG decoding\n\t{\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"normal\"))\n\t\t\tTVPJPEGLoadPrecision = jlpMedium;\n\t\telse if(str == TJS_W(\"low\"))\n\t\t\tTVPJPEGLoadPrecision = jlpLow;\n\t\telse if(str == TJS_W(\"high\"))\n\t\t\tTVPJPEGLoadPrecision = jlpHigh;\n\n\t}\n\n\t// dump option\n\tTVPDumpOptions();\n\n\t// initilaize x86 graphic routines\n#if 0\n#ifndef TJS_64BIT_OS\n\tTVPGL_IA32_Init();\n#endif\n\tTVPGL_SSE2_Init();\n#endif\n\tTVPGL_ASM_Init();\n\n\t// timer precision\n\tuint32_t prectick = 1;\n\tif(TVPGetCommandLine(TJS_W(\"-timerprec\"), &opt))\n\t{\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"high\")) prectick = 1;\n\t\tif(str == TJS_W(\"higher\")) prectick = 5;\n\t\tif(str == TJS_W(\"normal\")) prectick = 10;\n\t}\n\n        // draw thread num\n        tjs_int drawThreadNum = 0;\n        if (TVPGetCommandLine(TJS_W(\"-drawthread\"), &opt)) {\n          ttstr str(opt);\n          if (str == TJS_W(\"auto\"))\n            drawThreadNum = 0;\n          else\n            drawThreadNum = (tjs_int)opt;\n        }\n        TVPDrawThreadNum = drawThreadNum;\n#if 0\n\tif(prectick)\n\t{\n\t\t// retrieve minimum timer resolution\n\t\tTIMECAPS tc;\n\t\ttimeGetDevCaps(&tc, sizeof(tc));\n\t\tif(prectick < tc.wPeriodMin)\n\t\t\tTVPTimeBeginPeriodRes = tc.wPeriodMin;\n\t\telse\n\t\t\tTVPTimeBeginPeriodRes = prectick;\n\t\tif(TVPTimeBeginPeriodRes > tc.wPeriodMax)\n\t\t\tTVPTimeBeginPeriodRes = tc.wPeriodMax;\n\t\t// set timer resolution\n\t\ttimeBeginPeriod(TVPTimeBeginPeriodRes);\n\t\tTVPHighTimerPeriod = true;\n\t}\n\n\tTVPPushEnvironNoise(&TVPCPUType, sizeof(TVPCPUType));\n\n\t// set LFH\n\tif(TVPGetCommandLine(TJS_W(\"-uselfh\"), &opt)) {\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"yes\") || str == TJS_W(\"true\")) {\n\t\t\tULONG HeapInformation = 2;\n\t\t\tBOOL lfhenable = ::HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &HeapInformation, sizeof(HeapInformation) );\n\t\t\tif( lfhenable ) {\n\t\t\t\tTVPAddLog( TJS_W(\"(info) Enable LFH\") );\n\t\t\t} else {\n\t\t\t\tTVPAddLog( TJS_W(\"(info) Cannot Enable LFH\") );\n\t\t\t}\n\t\t}\n\t}\n\t// Global Heap Compact\n\tif(TVPGetCommandLine(TJS_W(\"-ghcompact\"), &opt)) {\n\t\tttstr str(opt);\n\t\tif(str == TJS_W(\"yes\") || str == TJS_W(\"true\")) {\n\t\t\tTVPEnableGlobalHeapCompaction = true;\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TVPBeforeSystemUninit()\n{\n\t// TVPDumpHWException(); // dump cached hw exceptoin\n}\n//---------------------------------------------------------------------------\nvoid TVPAfterSystemUninit()\n{\n#if 0\n\t// restore timer precision\n\tif(TVPHighTimerPeriod)\n\t{\n\t\ttimeEndPeriod(TVPTimeBeginPeriodRes);\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\nbool TVPTerminated = false;\nbool TVPTerminateOnWindowClose = true;\nbool TVPTerminateOnNoWindowStartup = true;\nint TVPTerminateCode = 0;\n//---------------------------------------------------------------------------\nvoid TVPTerminateAsync(int code)\n{\n\t// do \"A\"synchronous temination of application\n\tTVPTerminated = true;\n\tTVPTerminateCode = code;\n\n\t// posting dummy message will prevent \"missing WM_QUIT bug\" in Direct3D framework.\n\tif(TVPSystemControl) TVPSystemControl->CallDeliverAllEventsOnIdle();\n\n\tApplication->Terminate();\n\n\tif(TVPSystemControl) TVPSystemControl->CallDeliverAllEventsOnIdle();\n}\n//---------------------------------------------------------------------------\nvoid TVPTerminateSync(int code)\n{\n\t// do synchronous temination of application (never return)\n\tTVPSystemUninit();\n\tTVPExitApplication(code);\n}\n//---------------------------------------------------------------------------\nvoid TVPMainWindowClosed()\n{\n\t// called from WindowIntf.cpp, caused by closing all window.\n\tif( TVPTerminateOnWindowClose) TVPTerminateAsync();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// GetCommandLine\n//---------------------------------------------------------------------------\nstatic std::vector<std::string> * TVPGetEmbeddedOptions()\n{\n#if 0\n\tHMODULE hModule = ::GetModuleHandle(NULL);\n\tconst char *buf = NULL;\n\tunsigned int size = 0;\n\tHRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(IDR_OPTION), TEXT(\"TEXT\"));\n\tif( hRsrc != NULL ) {\n\t\tsize = ::SizeofResource( hModule, hRsrc );\n\t\tHGLOBAL hGlobal = ::LoadResource( hModule, hRsrc );\n\t\tif( hGlobal != NULL ) {\n\t\t\tbuf = reinterpret_cast<const char*>(::LockResource(hGlobal));\n\t\t}\n\t}\n\tif( buf == NULL ) return NULL;\n#endif\n\tstd::vector<std::string> *ret = NULL;\n#if 0\n\ttry {\n\t\tret = new std::vector<std::string>();\n\t\tconst char *tail = buf + size;\n\t\tconst char *start = buf;\n\t\twhile( buf < tail ) {\n\t\t\tif( buf[0] == 0x0D && buf[1] == 0x0A ) {\t// CR LF\n\t\t\t\tret->push_back( std::string(start,buf) );\n\t\t\t\tstart = buf + 2;\n\t\t\t\tbuf++;\n\t\t\t} else if( buf[0] == 0x0D || buf[0] == 0x0A ) {\t// CR or LF\n\t\t\t\tret->push_back( std::string(start,buf) );\n\t\t\t\tstart = buf + 1;\n\t\t\t} else if( buf[0] == '\\0' ) {\n\t\t\t\tret->push_back( std::string(start,buf) );\n\t\t\t\tstart = buf + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbuf++;\n\t\t}\n\t\tif( start < buf ) {\n\t\t\tret->push_back( std::string(start,buf) );\n\t\t}\n\t} catch(...) {\n\t\tif(ret) delete ret;\n\t\tthrow;\n\t}\n\tTVPAddImportantLog( (const tjs_char*)TVPInfoLoadingExecutableEmbeddedOptionsSucceeded );\n#endif\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nstatic std::vector<std::string> * TVPGetConfigFileOptions(const ttstr& filename)\n{\n#if 0\n\t// load .cf file\n\tstd::wstring errmsg;\n\tif(!FileExists(filename))\n\t\terrmsg = (const tjs_char*)TVPFileNotFound;\n#endif\n\tstd::vector<std::string> * ret = NULL; // new std::vector<std::string>();\n#if 0\n\tif (errmsg == TJS_W(\"\"))\n\t{\n\t\ttry\n\t\t{\n\t\t\tret = LoadLinesFromFile(filename);\n\t\t}\n\t\tcatch(Exception & e)\n\t\t{\n\t\t\terrmsg = e.what();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete ret;\n\t\t\tthrow;\n\t\t}\n\t}\n\n\tif(errmsg != TJS_W(\"\"))\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPInfoLoadingConfigurationFileFailed, filename.c_str(), errmsg.c_str()) );\n\telse\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPInfoLoadingConfigurationFileSucceeded, filename.c_str()) );\n#endif\n\treturn ret;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\nstatic ttstr TVPParseCommandLineOne(const ttstr &i)\n{\n\t// value is specified\n\tconst tjs_char *p, *o;\n\tp = o = i.c_str();\n\tp = TJS_strchr(p, '=');\n\n\tif(p == NULL) { return i + TJS_W(\"=yes\"); }\n\n\tp++;\n\n\tttstr optname(o, (int)(p - o));\n\n\tif(*p == TJS_W('\\'') || *p == TJS_W('\\\"'))\n\t{\n\t\t// as an escaped string\n\t\ttTJSVariant v;\n\t\tTJSParseString(v, &p);\n\n\t\treturn optname + ttstr(v);\n\t}\n\telse\n\t{\n\t\t// as a string\n\t\treturn optname + p;\n\t}\n}\n//---------------------------------------------------------------------------\nstd::vector <ttstr> TVPProgramArguments;\nstatic bool TVPProgramArgumentsInit = false;\nstatic tjs_int TVPCommandLineArgumentGeneration = 0;\nstatic bool TVPDataPathDirectoryEnsured = false;\n//---------------------------------------------------------------------------\ntjs_int TVPGetCommandLineArgumentGeneration() { return TVPCommandLineArgumentGeneration; }\n//---------------------------------------------------------------------------\nvoid TVPEnsureDataPathDirectory()\n{\n\tif(!TVPDataPathDirectoryEnsured)\n\t{\n\t\tTVPDataPathDirectoryEnsured = true;\n\t\t// ensure data path existence\n\t\tif(!TVPCheckExistentLocalFolder(TVPNativeDataPath.c_str()))\n\t\t{\n\t\t\tif(TVPCreateFolders(TVPNativeDataPath.c_str()))\n\t\t\t\tTVPAddImportantLog( TVPFormatMessage( TVPInfoDataPathDoesNotExistTryingToMakeIt, (const tjs_char*)TVPOk ) );\n\t\t\telse\n\t\t\t\tTVPAddImportantLog( TVPFormatMessage( TVPInfoDataPathDoesNotExistTryingToMakeIt, (const tjs_char*)TVPFaild ) );\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void PushAllCommandlineArguments()\n{\n#if 0\n\t// store arguments given by commandline to \"TVPProgramArguments\"\n\tbool acceptfilenameargument = GetSystemSecurityOption(\"acceptfilenameargument\") != 0;\n\n\tbool argument_stopped = false;\n\tif(acceptfilenameargument) argument_stopped = true;\n\tint file_argument_count = 0;\n\tfor(tjs_int i = 1; i<_argc; i++)\n\t{\n\t\tif(argument_stopped)\n\t\t{\n\t\t\tttstr arg_name_and_value = TJS_W(\"-arg\") + ttstr(file_argument_count) + TJS_W(\"=\")\n\t\t\t\t+ ttstr(_argv[i]);\n\t\t\tfile_argument_count++;\n\t\t\tTVPProgramArguments.push_back(arg_name_and_value);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(_argv[i][0] == '-')\n\t\t\t{\n\t\t\t\tif(_argv[i][1] == '-' && _argv[i][2] == 0)\n\t\t\t\t{\n\t\t\t\t\t// argument stopper\n\t\t\t\t\targument_stopped = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tttstr value(_argv[i]);\n\t\t\t\t\tif(!TJS_strchr(value.c_str(), TJS_W('=')))\n\t\t\t\t\t\tvalue += TJS_W(\"=yes\");\n\t\t\t\t\tTVPProgramArguments.push_back(TVPParseCommandLineOne(value));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nstatic void PushConfigFileOptions(const std::vector<std::string> * options)\n{\n\tif(!options) return;\n\tfor(unsigned int j = 0; j < options->size(); j++)\n\t{\n\t\tif( (*options)[j].c_str()[0] != ';') // unless comment\n\t\t\tTVPProgramArguments.push_back(\n\t\t\tTVPParseCommandLineOne(TJS_W(\"-\") + ttstr((*options)[j].c_str())));\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPInitProgramArgumentsAndDataPath(bool stop_after_datapath_got)\n{\n\tif(!TVPProgramArgumentsInit)\n\t{\n\t\tTVPProgramArgumentsInit = true;\n\n\t\t// find options from self executable image\n\t\tconst int num_option_layers = 3;\n\t\tstd::vector<std::string> * options[num_option_layers];\n\t\tfor(int i = 0; i < num_option_layers; i++) options[i] = NULL;\n\t\ttry\n\t\t{\n\t\t\t// read embedded options and default configuration file\n\t\t\toptions[0] = TVPGetEmbeddedOptions();\n//\t\t\toptions[1] = TVPGetConfigFileOptions(ApplicationSpecialPath::GetConfigFileName(ExePath()));\n\n\t\t\t// at this point, we need to push all exsting known options\n\t\t\t// to be able to see datapath\n\t\t\tPushAllCommandlineArguments();\n\t\t\tPushConfigFileOptions(options[1]); // has more priority\n\t\t\tPushConfigFileOptions(options[0]); // has lesser priority\n\n\t\t\t// read datapath\n\t\t\ttTJSVariant val;\n\t\t\tttstr config_datapath;\n// \t\t\tif(TVPGetCommandLine(TJS_W(\"-datapath\"), &val))\n// \t\t\t\tconfig_datapath = ((ttstr)val).AsStdString();\n\t\t\tTVPNativeDataPath = ApplicationSpecialPath::GetDataPathDirectory(config_datapath, ExePath());\n\n\t\t\tif(stop_after_datapath_got) return;\n\n\t\t\t// read per-user configuration file\n//\t\t\toptions[2] = TVPGetConfigFileOptions(ApplicationSpecialPath::GetUserConfigFileName(config_datapath, ExePath()));\n\n\t\t\t// push each options into option stock\n\t\t\t// we need to clear TVPProgramArguments first because of the\n\t\t\t// option priority order.\n\t\t\tTVPProgramArguments.clear();\n\t\t\tPushAllCommandlineArguments();\n\t\t\tPushConfigFileOptions(options[2]); // has more priority\n\t\t\tPushConfigFileOptions(options[1]); // has more priority\n\t\t\tPushConfigFileOptions(options[0]); // has lesser priority\n\t\t} catch(...) {\n\t\t\tfor(int i = 0; i < num_option_layers; i++)\n\t\t\t\tif(options[i]) delete options[i];\n\t\t\tthrow;\n\t\t}\n\t\tfor(int i = 0; i < num_option_layers; i++)\n\t\t\tif(options[i]) delete options[i];\n\n\n\t\t// set data path\n\t\tTVPDataPath = TVPNormalizeStorageName(TVPNativeDataPath);\n\t\tTVPAddImportantLog( TVPFormatMessage( TVPInfoDataPath, TVPDataPath) );\n\n\t\t// set log output directory\n\t\tTVPSetLogLocation(TVPNativeDataPath);\n\n\t\t// increment TVPCommandLineArgumentGeneration\n\t\tTVPCommandLineArgumentGeneration++;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPDumpOptions()\n{\n\tstd::vector<ttstr>::const_iterator i;\n \tttstr options( TVPInfoSpecifiedOptionEarlierItemHasMorePriority );\n\tif(TVPProgramArguments.size())\n\t{\n\t\tfor(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++)\n\t\t{\n\t\t\toptions += TJS_W(\" \");\n\t\t\toptions += *i;\n\t\t}\n\t}\n\telse\n\t{\n\t\toptions += (const tjs_char*)TVPNone;\n\t}\n\tTVPAddImportantLog(options);\n}\n//---------------------------------------------------------------------------\nbool TVPGetCommandLine(const tjs_char * name, tTJSVariant *value)\n{\n\tTVPInitProgramArgumentsAndDataPath(false);\n\n\ttjs_int namelen = (tjs_int)TJS_strlen(name);\n\tstd::vector<ttstr>::const_iterator i;\n\tfor(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++)\n\t{\n\t\tif(!TJS_strncmp(i->c_str(), name, namelen))\n\t\t{\n\t\t\tif(i->c_str()[namelen] == TJS_W('='))\n\t\t\t{\n\t\t\t\t// value is specified\n\t\t\t\tconst tjs_char *p = i->c_str() + namelen + 1;\n\t\t\t\tif(value) *value = p;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(i->c_str()[namelen] == 0)\n\t\t\t{\n\t\t\t\t// value is not specified\n\t\t\t\tif(value) *value = TJS_W(\"yes\");\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid TVPSetCommandLine(const tjs_char * name, const ttstr & value)\n{\n//\tTVPInitProgramArgumentsAndDataPath(false);\n\n\ttjs_int namelen = (tjs_int)TJS_strlen(name);\n\tstd::vector<ttstr>::iterator i;\n\tfor(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++)\n\t{\n\t\tif(!TJS_strncmp(i->c_str(), name, namelen))\n\t\t{\n\t\t\tif(i->c_str()[namelen] == TJS_W('=') || i->c_str()[namelen] == 0)\n\t\t\t{\n\t\t\t\t// value found\n\t\t\t\t*i = ttstr(i->c_str(), namelen) + TJS_W(\"=\") + value;\n\t\t\t\tTVPCommandLineArgumentGeneration ++;\n\t\t\t\tif(TVPCommandLineArgumentGeneration == 0) TVPCommandLineArgumentGeneration = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// value not found; insert argument into front\n\tTVPProgramArguments.insert(TVPProgramArguments.begin(), ttstr(name) + TJS_W(\"=\") + value);\n\tTVPCommandLineArgumentGeneration ++;\n\tif(TVPCommandLineArgumentGeneration == 0) TVPCommandLineArgumentGeneration = 1;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCheckPrintDataPath\n//---------------------------------------------------------------------------\nbool TVPCheckPrintDataPath()\n{\n#if 0\n\t// print current datapath to stdout, then exit\n\tfor(int i=1; i<_argc; i++)\n\t{\n\t\tif(!strcmp(_argv[i], \"-printdatapath\")) // this does not refer TVPGetCommandLine\n\t\t{\n\t\t\tTVPInitProgramArgumentsAndDataPath(true);\n\t\t\twprintf(L\"%s\\n\", TVPNativeDataPath.c_str());\n\n\t\t\treturn true; // processed\n\t\t}\n\t}\n#endif\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCheckAbout\n//---------------------------------------------------------------------------\nbool TVPCheckAbout(void)\n{\n#if 0\n\tif(TVPGetCommandLine(TJS_W(\"-about\")))\n\t{\n\t\tSleep(600);\n\t\ttjs_char msg[80];\n\t\tTJS_snprintf(msg, sizeof(msg)/sizeof(tjs_char), TVPInfoCpuClockRoughly, (int)TVPCPUClock);\n\t\tTVPAddImportantLog(msg);\n\n\t\tTVPShowVersionForm();\n\t\treturn true;\n\t}\n#endif\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPExecuteAsync\n//---------------------------------------------------------------------------\nstatic void TVPExecuteAsync( const std::wstring& progname)\n{\n#if 0\n\tSTARTUPINFO si;\n\tPROCESS_INFORMATION pi;\n\tZeroMemory(&si, sizeof(si));\n\tsi.cb = sizeof(si);\n\tsi.dwFlags = STARTF_USESHOWWINDOW;\n\tsi.wShowWindow = SW_SHOWNORMAL;\n\n\tBOOL ret =\n\t\tCreateProcess(\n\t\t\tNULL,\n\t\t\tconst_cast<LPTSTR>(progname.c_str()),\n\t\t\tNULL,\n\t\t\tNULL,\n\t\t\tFALSE,\n\t\t\t0,\n\t\t\tNULL,\n\t\t\tNULL,\n\t\t\t&si,\n\t\t\t&pi);\n\n\tif(ret)\n\t{\n\t\tCloseHandle(pi.hThread);\n\t\tCloseHandle(pi.hProcess);\n\t\treturn;\n\t}\n\n\tthrow Exception(ttstr(TVPExecutionFail).AsStdString());\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPWaitWritePermit\n//---------------------------------------------------------------------------\nstatic bool TVPWaitWritePermit(const std::wstring& fn)\n{\n\treturn false;\n#if 0\n\ttjs_int timeout = 10; // 10/1 = 5 seconds\n\twhile(true)\n\t{\n\t\tHANDLE h = CreateFile(fn.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL,\n\t\t\tOPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n\t\tif(h != INVALID_HANDLE_VALUE)\n\t\t{\n\t\t\tCloseHandle(h);\n\t\t\treturn true;\n\t\t}\n\n\t\tSleep(500);\n\t\ttimeout--;\n\t\tif(timeout == 0) return false;\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n#if 0\n//---------------------------------------------------------------------------\n// TVPShowUserConfig\n//---------------------------------------------------------------------------\nstatic void TVPShowUserConfig(std::string orgexe)\n{\n\tTVPEnsureDataPathDirectory();\n\n\tApplication->SetTitle( ChangeFileExt(ExtractFileName(orgexe), \"\") );\n\tTConfSettingsForm *form = new TConfSettingsForm(Application, true);\n\tform->InitializeConfig(orgexe);\n\tform->ShowModal();\n\tdelete form;\n}\n//---------------------------------------------------------------------------\n#endif\n\n//---------------------------------------------------------------------------\n// TVPExecuteUserConfig\n//---------------------------------------------------------------------------\nbool TVPExecuteUserConfig()\n{\n\treturn false;\n\t// check command line argument\n#if 0\n\ttjs_int i;\n\tbool process = false;\n\tfor(i=1; i<_argc; i++)\n\t{\n\t\tif(!strcmp(_argv[i], \"-userconf\")) // this does not refer TVPGetCommandLine\n\t\t\tprocess = true;\n\t}\n\n\tif(!process) return false;\n\n\t// execute user config mode\n\t//TVPShowUserConfig(ExePath());\n\tTVPShowUserConfig();\n\n\t// exit\n\treturn true;\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n"
  },
  {
    "path": "src/core/base/win32/SysInitImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Initialization and Uninitialization\n//---------------------------------------------------------------------------\n#ifndef SysInitImplH\n#define SysInitImplH\n\n//---------------------------------------------------------------------------\nextern void TVPDumpHWException();\n\nextern void TVPInitializeBaseSystems();\n\nextern ttstr TVPNativeProjectDir;\nextern ttstr TVPNativeDataPath;\n\nextern bool TVPProjectDirSelected;\nextern void TVPEnsureDataPathDirectory();\n\n\nextern bool TVPExecuteUserConfig();\n\nextern bool TVPTerminated;\nextern bool TVPTerminateOnWindowClose;\nextern bool TVPTerminateOnNoWindowStartup;\nextern int TVPTerminateCode;\n\n//---------------------------------------------------------------------------\n\n\n#include \"SysInitIntf.h\"\n\n#endif\n"
  },
  {
    "path": "src/core/base/win32/SystemImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"System\" class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n// #include <shellapi.h>\n// #include <shlobj.h>\n\n#include \"GraphicsLoaderImpl.h\"\n\n#include \"SystemImpl.h\"\n#include \"SystemIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"StorageIntf.h\"\n#include \"StorageImpl.h\"\n#include \"TickCount.h\"\n#include \"ComplexRect.h\"\n#include \"WindowImpl.h\"\n#include \"SystemControl.h\"\n#include \"DInputMgn.h\"\n\n#include \"Application.h\"\n#include \"TVPScreen.h\"\n//#include \"CompatibleNativeFuncs.h\"\n#include \"DebugIntf.h\"\n//#include \"VersionFormUnit.h\"\n#include \"vkdefine.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tjsArray.h\"\n#include \"Platform.h\"\n\n//---------------------------------------------------------------------------\nstatic ttstr TVPAppTitle;\nstatic bool TVPAppTitleInit = false;\n//---------------------------------------------------------------------------\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// TVPShowSimpleMessageBox\n//---------------------------------------------------------------------------\nstatic void TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption)\n{\n\tHWND hWnd = TVPGetModalWindowOwnerHandle();\n\tif( hWnd == INVALID_HANDLE_VALUE ) {\n\t\thWnd = NULL;\n\t}\n\t::MessageBox( hWnd, text.AsStdString().c_str(), caption.AsStdString().c_str(), MB_OK|MB_ICONINFORMATION );\n}\n//---------------------------------------------------------------------------\n#endif\n\nbool TVPGetKeyMouseAsyncState(tjs_uint keycode, bool getcurrent);\n//---------------------------------------------------------------------------\n// TVPGetAsyncKeyState\n//---------------------------------------------------------------------------\nbool TVPGetAsyncKeyState(tjs_uint keycode, bool getcurrent)\n{\n\t// get keyboard state asynchronously.\n\t// return current key state if getcurrent is true.\n\t// otherwise, return whether the key is pushed during previous call of\n\t// TVPGetAsyncKeyState at the same keycode.\n\n\tif(keycode >= VK_PAD_FIRST  && keycode <= VK_PAD_LAST)\n\t{\n\t\t// JoyPad related keys are treated in DInputMgn.cpp\n\t\treturn TVPGetJoyPadAsyncState(keycode, getcurrent);\n\t}\n\n\treturn TVPGetKeyMouseAsyncState(keycode, getcurrent);\n#if 0\n\tif(keycode == VK_LBUTTON || keycode == VK_RBUTTON)\n\t{\n\t\t// check whether the mouse button is swapped\n\t\tif(GetSystemMetrics(SM_SWAPBUTTON))\n\t\t{\n\t\t\t// mouse button had been swapped; swap key code\n\t\t\tif(keycode == VK_LBUTTON)\n\t\t\t\tkeycode = VK_RBUTTON;\n\t\t\telse\n\t\t\t\tkeycode = VK_LBUTTON;\n\t\t}\n\t}\n\n\treturn 0!=( GetAsyncKeyState(keycode) & ( getcurrent?0x8000:0x0001) );\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// TVPGetPlatformName\n//---------------------------------------------------------------------------\nttstr TVPGetPlatformName()\n{\n\tSYSTEM_INFO sysInfo;\n\t::GetNativeSystemInfo( &sysInfo );\n\tswitch( sysInfo.wProcessorArchitecture )\n\t{\n\t\tcase PROCESSOR_ARCHITECTURE_AMD64:\n\t\tcase PROCESSOR_ARCHITECTURE_IA64:\n\t\t\treturn ttstr(TJS_W(\"Win64\"));\n\n\t\tcase PROCESSOR_ARCHITECTURE_INTEL:\n\t\tcase PROCESSOR_ARCHITECTURE_UNKNOWN:\n\t\tdefault:\n\t\t\treturn ttstr(TJS_W(\"Win32\"));\n\t}\n}\n//---------------------------------------------------------------------------\n\n\ntypedef void (WINAPI *RtlGetVersionFunc)(OSVERSIONINFOEX* );\n//---------------------------------------------------------------------------\n// TVPGetOSName\n//---------------------------------------------------------------------------\nttstr TVPGetOSName()\n{\n\tOSVERSIONINFOEX ovi;\n\tovi.dwOSVersionInfoSize = sizeof(ovi);\n\n\tbool isGetVersion = false;\n\tHMODULE hModule = ::LoadLibrary( L\"ntdll.dll\" );\n\tif( hModule ) {\n\t\tRtlGetVersionFunc func;\n\t\tfunc = (RtlGetVersionFunc)::GetProcAddress( hModule, \"RtlGetVersion\" );\n\t\tif( func ) {\n\t\t\tfunc( &ovi );\n\t\t\tisGetVersion = true;\n\t\t}\n\t\t::FreeLibrary( hModule );\n\t\thModule = NULL;\n\t}\n\tif( isGetVersion == false ) {\n\t\tGetVersionEx((OSVERSIONINFO*)&ovi);\n\t}\n\ttjs_char buf[256];\n\tconst tjs_char *osname = NULL;\n\n\tswitch(ovi.dwPlatformId)\n\t{\n\tcase VER_PLATFORM_WIN32s:\n\t\tosname = TJS_W(\"Win32s\"); break;\n\tcase VER_PLATFORM_WIN32_WINDOWS:\n\t\tswitch((ovi.dwBuildNumber&0xffff ))\n\t\t{\n\t\tcase 1998:\n\t\t\tosname = TJS_W(\"Windows 98\"); break;\n\t\tcase 95:\n\t\t\tosname = TJS_W(\"Windows 95\"); break;\n\t\tdefault:\n\t\t\tosname = TJS_W(\"Win9x\"); break;\n\t\t}\n\t\tbreak;\n\tcase VER_PLATFORM_WIN32_NT:\n\t\tif( ovi.dwMajorVersion == 5 ) {\n\t\t\tswitch(ovi.dwMinorVersion) {\n\t\t\tcase 0:\n\t\t\t\tosname = TJS_W(\"Windows 2000\");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tosname = TJS_W(\"Windows XP\");\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tosname = TJS_W(\"Windows Server 2003\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if( ovi.dwMajorVersion == 6 ) {\n\t\t\tswitch(ovi.dwMinorVersion) {\n\t\t\tcase 0:\n\t\t\t\tif( ovi.wProductType == VER_NT_WORKSTATION )\n\t\t\t\t\tosname = TJS_W(\"Windows Vista\");\n\t\t\t\telse\n\t\t\t\t\tosname = TJS_W(\"Windows Server 2008\");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tif( ovi.wProductType == VER_NT_WORKSTATION )\n\t\t\t\t\tosname = TJS_W(\"Windows 7\");\n\t\t\t\telse\n\t\t\t\t\tosname = TJS_W(\"Windows Server 2008 R2\");\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif( ovi.wProductType == VER_NT_WORKSTATION )\n\t\t\t\t\tosname = TJS_W(\"Windows 8\");\n\t\t\t\telse\n\t\t\t\t\tosname = TJS_W(\"Windows Server 2012\");\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tif( ovi.wProductType == VER_NT_WORKSTATION )\n\t\t\t\t\tosname = TJS_W(\"Windows 8.1\");\n\t\t\t\telse\n\t\t\t\t\tosname = TJS_W(\"Windows Server 2012 R2\");\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif( ovi.wProductType == VER_NT_WORKSTATION )\n\t\t\t\t\tosname = TJS_W(\"Windows 10\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif( osname == NULL ) osname = TJS_W(\"Windows NT\");\n\t\tbreak;\n\tdefault:\n\t\tosname = TJS_W(\"Unknown\"); break;\n\t}\n\n\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"%ls %d.%d.%d \"), osname, ovi.dwMajorVersion,\n\t\tovi.dwMinorVersion, ovi.dwBuildNumber&0xfff);\n\n\tttstr str(buf);\n\tstr += ttstr(ovi.szCSDVersion);\n\n\treturn str;\n}\n//---------------------------------------------------------------------------\n#endif\n\n//---------------------------------------------------------------------------\n// TVPGetOSBits\n//---------------------------------------------------------------------------\ntjs_int TVPGetOSBits()\n{\n#if 0\n\tSYSTEM_INFO sysInfo;\n\t::GetNativeSystemInfo( &sysInfo );\n\tswitch( sysInfo.wProcessorArchitecture )\n\t{\n\t\tcase PROCESSOR_ARCHITECTURE_AMD64:\n\t\tcase PROCESSOR_ARCHITECTURE_IA64:\n\t\t\treturn 64;\n\t\tcase PROCESSOR_ARCHITECTURE_INTEL:\n\t\tcase PROCESSOR_ARCHITECTURE_UNKNOWN:\n\t\tdefault:\n\t\t\treturn 32;\n\t}\n#endif\n\treturn 32;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPShellExecute\n//---------------------------------------------------------------------------\nbool TVPShellExecute(const ttstr &target, const ttstr &param)\n{\n\t// open or execute target file\n//\tttstr file = TVPGetNativeName(TVPNormalizeStorageName(target));\n#if 0\n\treturn TVPIsExistentStorageNoSearchNoNormalize(target);\n\tif (::ShellExecute(NULL, NULL,\n\t\ttarget.c_str(),\n\t\tparam.IsEmpty() ? NULL : param.c_str(),\n\t\tL\"\",\n\t\tSW_SHOWNORMAL)\n\t\t<=(void *)32)\n\t{\n\t\treturn false;\n\t}\n\telse\n#endif\n\t{\n\t\treturn true;\n\t}\n}\n//---------------------------------------------------------------------------\n\nstatic tTJSVariant RegisterData;\nttstr TVPGetAppDataPath();\nvoid TVPExecuteStorage(const ttstr &name, tTJSVariant *result, bool isexpression,\n\tconst tjs_char * modestr);\nstatic void InitRegisterData()\n{\n\tstatic bool dataInited = false;\n\tif (!dataInited) {\n\t\tttstr regfile = TVPGetAppDataPath() + TJS_W(\"RegisterData.tjs\");\n\t\tif (TVPIsExistentStorageNoSearch(regfile)) {\n\t\t\tTVPExecuteStorage(regfile, &RegisterData, true, TJS_W(\"\"));\n\t\t}\n\t}\n}\n\n//---------------------------------------------------------------------------\n// TVPReadRegValue\n//---------------------------------------------------------------------------\nstatic void TVPReadRegValue(tTJSVariant &result, const ttstr & key)\n{\n\t// open specified registry key\n\tif(key.IsEmpty()) { result.Clear(); return; }\n\n\t// check whether the key contains root key name\n\t//HKEY root = HKEY_CURRENT_USER;\n\tconst tjs_char *key_p = key.c_str();\n\n\tInitRegisterData();\n\t// search value name\n\ttTJSVariant CurrentNode = RegisterData;\n\tconst tjs_char *start = key_p;\n\twhile (*start && CurrentNode.Type() != tvtObject) {\n\t\tiTJSDispatch2 *pObj;\n\n\t\tswitch (*key_p) {\n\t\tcase '\\\\':\n\t\tcase '/':\n\t\t\t++key_p;\n\t\tcase '\\0':\n\t\t\tstart = key_p;\n\t\t\tif (CurrentNode.Type() != tvtObject) {\n\t\t\t\tCurrentNode.Clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpObj = CurrentNode.AsObject();\n\t\t\tif (!pObj) {\n\t\t\t\tCurrentNode.Clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!TJS_SUCCEEDED(pObj->PropGet(TJS_MEMBERMUSTEXIST, ttstr(start, key_p - start - 1).c_str(), 0, &CurrentNode, pObj))) {\n\t\t\t\tCurrentNode.Clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tstart = key_p;\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\t++key_p;\n\t\t\tcontinue;\n\t\t}\n\t}\n\tif (*start) {\n\t\tCurrentNode.Clear();\n\t\treturn;\n\t}\n\tresult = CurrentNode;\n#if 0\n\tif(key.StartsWith(TJS_W(\"HKEY_CLASSES_ROOT\")))\n\t{\n\t\tkey_p += 17;\n\t\troot = HKEY_CLASSES_ROOT;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_CURRENT_CONFIG\")))\n\t{\n\t\tkey_p += 19;\n\t\troot = HKEY_CURRENT_CONFIG;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_CURRENT_USER\")))\n\t{\n\t\tkey_p += 17;\n\t\troot = HKEY_CURRENT_USER;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_LOCAL_MACHINE\")))\n\t{\n\t\tkey_p += 18;\n\t\troot = HKEY_LOCAL_MACHINE;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_USERS\")))\n\t{\n\t\tkey_p += 10;\n\t\troot = HKEY_USERS;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_PERFORMANCE_DATA\")))\n\t{\n\t\tkey_p += 21;\n\t\troot = HKEY_PERFORMANCE_DATA;\n\t}\n\telse if(key.StartsWith(TJS_W(\"HKEY_DYN_DATA\")))\n\t{\n\t\tkey_p += 13;\n\t\troot = HKEY_DYN_DATA;\n\t}\n\n\tif(*key_p == TJS_W('\\\\')) key_p ++;\n\n\t// search value name\n\tconst tjs_char *start = key_p;\n\tkey_p += TJS_strlen(key_p);\n\tkey_p--;\n\twhile(start <= key_p && *key_p != TJS_W('\\\\')) key_p--;\n\tttstr valuename(key_p+1);\n\tif(key_p < start || *key_p != TJS_W('\\\\')) key_p++;\n\n\tttstr keyname(start, (int)(key_p - start));\n\n\t// open key\n\tHKEY handle;\n\tLONG res = RegOpenKeyEx(root, keyname.AsStdString().c_str(), 0, KEY_READ, &handle);\n\tif(res != ERROR_SUCCESS) { result.Clear(); return; }\n\n\t// try query value size and read key\n\tDWORD size;\n\tDWORD type;\n\n\t// query size\n\tres = RegQueryValueEx(handle, valuename.c_str(), 0, &type, NULL, &size);\n\n\tif(res != ERROR_SUCCESS)\n\t{\n\t\tRegCloseKey(handle);\n\t\tresult.Clear();\n\t\treturn;\n\t}\n\n\n\tswitch(type)\n\t{\n\tcase REG_DWORD:\n//\tcase REG_DWORD_LITTLE_ENDIAN: // is actually the same as REG_DWORD\n\tcase REG_DWORD_BIG_ENDIAN:\n\tcase REG_EXPAND_SZ:\n\tcase REG_SZ:\n\t\tbreak; // these should be OK\n\n\tcase REG_MULTI_SZ: // sorry not yet implemented\n\tcase REG_BINARY:\n\tcase REG_LINK:\n\tcase REG_NONE:\n\tcase REG_RESOURCE_LIST:\n\tdefault:\n\t\t// not capable types\n\t\tRegCloseKey(handle);\n\t\tresult.Clear();\n\t\treturn;\n\t}\n\n\twhile(true)\n\t{\n\t\ttjs_uint8 * data = new tjs_uint8[size];\n\n\t\ttry\n\t\t{\n\t\t\tDWORD size2 = size;\n\t\t\tres = RegQueryValueEx(handle, valuename.c_str(), 0, NULL, data, &size2);\n\n\t\t\tif(res == ERROR_MORE_DATA)\n\t\t\t{\n\t\t\t\t// more data required\n\t\t\t\tdelete [] data;\n\t\t\t\tsize += 1024;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if(res != ERROR_SUCCESS)\n\t\t\t{\n\t\t\t\tRegCloseKey(handle);\n\t\t\t\tresult.Clear();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// query succeeded\n\n\n\t\t\t// store data into result\n\t\t\tswitch(type)\n\t\t\t{\n\t\t\tcase REG_DWORD:\n//\t\t\tcase REG_DWORD_LITTLE_ENDIAN:\n\t\t\t\tresult = (tTVInteger)*(DWORD*)data;\n\t\t\t\tbreak;\n\n\t\t\tcase REG_DWORD_BIG_ENDIAN:\n\t\t\t\t{\n\t\t\t\t\tDWORD val = *(DWORD*)data;\n\t\t\t\t\tval = (val >> 24) + ((val >> 8) & 0x0000ff00) +\n\t\t\t\t\t\t((val << 8) & 0x00ff0000) + (val << 24);\n\t\t\t\t\tresult = (tTVInteger)val;\n\t\t\t  \t}\n\t\t\t\tbreak;\n\n\t\t\tcase REG_EXPAND_SZ:\n\t\t\tcase REG_SZ:\n\t\t\t\t// data is stored in unicode\n\t\t\t\tresult = ttstr((const tjs_char*)data);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tRegCloseKey(handle);\n\t\t\tdelete [] data;\n\t\t\tthrow;\n\t\t}\n\t\tRegCloseKey(handle);\n\t\tdelete [] data;\n\n\t\tbreak;\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// Static function for retrieving special folder path\n//---------------------------------------------------------------------------\nstatic ttstr TVPGetSpecialFolderPath(int csidl)\n{\n\tWCHAR path[MAX_PATH+1];\n\tif(!SHGetSpecialFolderPath(NULL, path, csidl, false))\n\t\treturn ttstr();\n\treturn ttstr(path);\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetPersonalPath\n//---------------------------------------------------------------------------\nttstr TVPGetPersonalPath()\n{\n#if 0\n\t// Retrieve personal directory;\n\t// This usually refers \"My Documents\".\n\t// If this is not exist, returns application data path, then exe path.\n\t// for windows vista, this refers application data path.\n\tttstr path;\n\tpath = TVPGetSpecialFolderPath(CSIDL_PERSONAL);\n\tif(path.IsEmpty())\n\t\tpath = TVPGetSpecialFolderPath(CSIDL_APPDATA);\n\t\n\tif(!path.IsEmpty())\n\t{\n\t\tpath = TVPNormalizeStorageName(path);\n\t\tif(path.GetLastChar() != TJS_W('/')) path += TJS_W('/');\n\t\treturn path;\n\t}\n#endif\n\treturn TVPGetAppPath();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetAppDataPath\n//---------------------------------------------------------------------------\nttstr TVPGetAppDataPath()\n{\n#if 0\n\t// Retrieve application data directory;\n\t// If this is not exist, returns application exe path.\n\n\tttstr path = TVPGetSpecialFolderPath(CSIDL_APPDATA);\n\t\n\tif(!path.IsEmpty())\n\t{\n\t\tpath = TVPNormalizeStorageName(path);\n\t\tif(path.GetLastChar() != TJS_W('/')) path += TJS_W('/');\n\t\treturn path;\n\t}\n#endif\n\treturn TVPGetAppPath();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetSavedGamesPath\n//---------------------------------------------------------------------------\nttstr TVPGetSavedGamesPath()\n{\n#if 0\n\tttstr path;\n\tPWSTR ppszPath = NULL;\n\tHRESULT hr = ::SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &ppszPath);\n\tif( hr == S_OK ) {\n\t\tpath = ppszPath;\n\t\t::CoTaskMemFree( ppszPath );\n\t}\n\treturn path;\n#endif\n\treturn TVPGetAppPath();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateAppLock\n//---------------------------------------------------------------------------\nbool TVPCreateAppLock(const ttstr &lockname)\n{\n#if 0\n\t// lock application using mutex\n\tCreateMutex(NULL, TRUE, lockname.c_str());\n\n\tif(GetLastError())\n\t{\n\t\treturn false; // already running\n\t}\n#endif\n\n\t// No need to release the mutex object because the mutex is automatically\n\t// released when the calling thread exits.\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nenum tTVPTouchDevice {\n\ttdNone\t\t\t\t= 0,\n\ttdIntegratedTouch\t= 0x00000001,\n\ttdExternalTouch\t\t= 0x00000002,\n\ttdIntegratedPen\t\t= 0x00000004,\n\ttdExternalPen\t\t= 0x00000008,\n\ttdMultiInput\t\t= 0x00000040,\n\ttdDigitizerReady\t= 0x00000080,\n\ttdMouse\t\t\t\t= 0x00000100,\n\ttdMouseWheel\t\t= 0x00000200\n};\n/**\n * ^b`foCX(ƃ}EX)̐ڑԂ擾\n **/\nstatic int TVPGetSupportTouchDevice()\n{\n\tint result = 0;\n#if 0\n\tif( procRegisterTouchWindow ) {\n\t\tint value = ::GetSystemMetrics( SM_DIGITIZER );\n\n\t\tif( value & NID_INTEGRATED_TOUCH ) result |= tdIntegratedTouch;\n\t\tif( value & NID_EXTERNAL_TOUCH ) result |= tdExternalTouch;\n\t\tif( value & NID_INTEGRATED_PEN ) result |= tdIntegratedPen;\n\t\tif( value & NID_EXTERNAL_PEN ) result |= tdExternalPen;\n\t\tif( value & NID_MULTI_INPUT ) result |= tdMultiInput;\n\t\tif( value & NID_READY ) result |= tdDigitizerReady;\n\t}\n\tint value = ::GetSystemMetrics( SM_MOUSEPRESENT );\n\tif( value ) {\n\t\tresult |= tdMouse;\n\t\tvalue = ::GetSystemMetrics( SM_MOUSEWHEELPRESENT );\n\t\tif( value ) result |= tdMouseWheel;\n\t}\n#endif\n\tresult |= tdMouse;\n\tresult |= tdMouseWheel;\n\treturn result;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// System.onActivate and System.onDeactivate related\n//---------------------------------------------------------------------------\nstatic void TVPOnApplicationActivate(bool activate_or_deactivate);\n//---------------------------------------------------------------------------\nclass tTVPOnApplicationActivateEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\tbool ActivateOrDeactivate; // true for activate; otherwise deactivate\npublic:\n\ttTVPOnApplicationActivateEvent(bool activate_or_deactivate) :\n\t\ttTVPBaseInputEvent(Application, Tag),\n\t\tActivateOrDeactivate(activate_or_deactivate) {};\n\tvoid Deliver() const\n\t{ TVPOnApplicationActivate(ActivateOrDeactivate); }\n};\ntTVPUniqueTagForInputEvent tTVPOnApplicationActivateEvent              ::Tag;\n//---------------------------------------------------------------------------\nvoid TVPPostApplicationActivateEvent()\n{\n\tTVPPostInputEvent(new tTVPOnApplicationActivateEvent(true), TVP_EPT_REMOVE_POST);\n}\n//---------------------------------------------------------------------------\nvoid TVPPostApplicationDeactivateEvent()\n{\n\tTVPPostInputEvent(new tTVPOnApplicationActivateEvent(false), TVP_EPT_REMOVE_POST);\n}\n//---------------------------------------------------------------------------\nstatic void TVPOnApplicationActivate(bool activate_or_deactivate)\n{\n\t// called by event system, to fire System.onActivate or\n\t// System.onDeactivate event\n\tif(!TVPSystemControlAlive) return;\n\n\t// check the state again (because the state may change during the event delivering).\n\t// but note that this implementation might fire activate events even in the application\n\t// is already activated (the same as deactivation).\n\tif(activate_or_deactivate != Application->GetActivating()) return;\n\n\t// fire the event\n\tTVPFireOnApplicationActivateEvent(activate_or_deactivate);\n}\n//---------------------------------------------------------------------------\n\n#if 0\n//---------------------------------------------------------------------------\nstatic void TVPHeapDump()\n{\n\ttjs_char buff[128];\n\tHANDLE heaps[100];\n\tDWORD c = ::GetProcessHeaps (100, heaps);\n\tTJS_sprintf( buff, 128, TJS_W(\"The process has %d heaps.\"), c );\n\tTVPAddLog( buff );\n\n\tconst HANDLE default_heap = ::GetProcessHeap();\n\tconst HANDLE crt_heap = (HANDLE)_get_heap_handle();\n\tfor( unsigned int i = 0; i < c; i++ ) {\n\t\tULONG heap_info = 0;\n\t\tSIZE_T ret_size = 0;\n\t\tbool isdefault = false;\n\t\tbool isCRT = false;\n\t\tif( ::HeapQueryInformation( heaps[i], HeapCompatibilityInformation, &heap_info, sizeof(heap_info), &ret_size) ) {\n\t\t\ttjs_char* type = NULL;\n\t\t\tswitch( heap_info ) {\n\t\t\tcase 0:\n\t\t\t\ttype = TJS_W(\"standard\");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\ttype = TJS_W(\"LAL\");\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttype = TJS_W(\"LFH\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttype = TJS_W(\"unknown\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif( heaps[i] == default_heap ) {\n\t\t\t\tisdefault = true;\n\t\t\t}\n\t\t\tif( heaps [i] == crt_heap ) {\n\t\t\t\tisCRT = true;\n\t\t\t}\n\n\t\t\tPROCESS_HEAP_ENTRY entry;\n\t\t\tmemset( &entry, 0, sizeof (entry) );\n\t\t\tstruct Info {\n\t\t\t\tint count;\n\t\t\t\ttjs_int64 total;\n\t\t\t\ttjs_int64 overhead;\n\t\t\t\tInfo() : count(0), total(0), overhead(0) {}\n\t\t\t} use, uncommit, unused;\n\t\t\twhile( ::HeapWalk( heaps[i], &entry) ) {\n\t\t\t\tif( entry.wFlags & PROCESS_HEAP_ENTRY_BUSY ) {\n\t\t\t\t\tuse.count++;\n\t\t\t\t\tuse.total += entry.cbData;\n\t\t\t\t\tuse.overhead += entry.cbOverhead;\n\t\t\t\t} else if( entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE ) {\n\t\t\t\t\tuncommit.count++;\n\t\t\t\t\tuncommit.total += entry.cbData;\n\t\t\t\t\tuncommit.overhead += entry.cbOverhead;\n\t\t\t\t} else {\n\t\t\t\t\tunused.count++;\n\t\t\t\t\tunused.total += entry.cbData;\n\t\t\t\t\tunused.overhead += entry.cbOverhead;\n\t\t\t\t}\n\t\t\t}\n\t\t\tttstr mes( TJS_W(\"#\") );\n\t\t\tmes += ttstr((tjs_int)(i+1)) + TJS_W(\" type: \") + type;\n\t\t\tif( isdefault ) mes += TJS_W(\" [default]\");\n\t\t\tif( isCRT ) mes += TJS_W(\" [CRT]\");\n\t\t\tTVPAddLog( mes );\n\t\t\tTJS_sprintf( buff, 128, L\"  Allocated: %d, size: %lld, overhead: %lld\", use.count, use.total, use.overhead );\n\t\t\tTVPAddLog( buff );\n\t\t\tTJS_sprintf( buff, 128, L\"  Uncommitted: %d, size: %lld, overhead: %lld\", uncommit.count, uncommit.total, uncommit.overhead );\n\t\t\tTVPAddLog( buff );\n\t\t\tTJS_sprintf( buff, 128, L\"  Unused: %d, size: %lld, overhead: %lld\", unused.count, unused.total, unused.overhead );\n\t\t\tTVPAddLog( buff );\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n#endif\nbool TVPAutoSaveBookMark = false;\nextern void TVPDoSaveSystemVariables()\n{\n\ttry {\n\t\t// hack for save system variable\n\t\tiTJSDispatch2* global = TVPGetScriptDispatch();\n\t\tif (!global) return;\n\t\ttTJSVariant var;\n\t\tif (global->PropGet(0, TJS_W(\"kag\"), nullptr, &var, global) == TJS_S_OK && var.Type() == tvtObject) {\n\t\t\tiTJSDispatch2* kag = var.AsObjectNoAddRef();\n\t\t\tif (kag->PropGet(0, TJS_W(\"saveSystemVariables\"), nullptr, &var, kag) == TJS_S_OK) {\n\t\t\t\tiTJSDispatch2* fn = var.AsObjectNoAddRef();\n\t\t\t\tif (fn->IsInstanceOf(0, 0, 0, TJS_W(\"Function\"), fn)) {\n\t\t\t\t\ttTJSVariant *args = nullptr;\n\t\t\t\t\tfn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(TVPAutoSaveBookMark\n\t\t\t\t&& kag->PropGet(0, TJS_W(\"saveBookMark\"), nullptr, &var, kag) == TJS_S_OK\n\t\t\t\t&& var.Type() == tvtObject)\n\t\t\t{\n\t\t\t\tiTJSDispatch2* fn = var.AsObjectNoAddRef();\n\t\t\t\tif (fn->IsInstanceOf(0, 0, 0, TJS_W(\"Function\"), fn)) {\n\t\t\t\t\ttTJSVariant num((tjs_int32)0);\n\t\t\t\t\ttTJSVariant *args = &num;\n\t\t\t\t\tfn->FuncCall(0, nullptr, nullptr, nullptr, 1, &args, kag);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (...) {\n\t\t;\n\t}\n}\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_System\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_System()\n{\n\ttTJSNC_System *cls = new tTJSNC_System();\n\n\n\t// setup some platform-specific members\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/inform)\n{\n\t// show simple message box\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr text = *param[0];\n\n\tttstr caption;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tcaption = *param[1];\n\telse\n\t\tcaption = TJS_W(\"Information\");\n\n\tif (numparams >= 3 && param[2]->Type() != tvtVoid) {\n\t\tif (param[2]->Type() == tvtObject) { // vector of button\n\t\t\ttTJSArrayNI* ni;\n\t\t\tparam[2]->AsObjectNoAddRef()->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJSGetArrayClassID(), (iTJSNativeInstance**)&ni);\n\t\t\tstd::vector<ttstr> vecButtons;\n\t\t\tvecButtons.reserve(ni->Items.size());\n\t\t\tfor (const ttstr &label : ni->Items) {\n\t\t\t\tvecButtons.emplace_back(label);\n\t\t\t}\n\t\t\tint ret = TVPShowSimpleMessageBox(text, caption, vecButtons);\n\t\t\tif (result) result->operator =(ret);\n\t\t} else {\n\t\t\tint nButtons = param[2]->AsInteger();\n\t\t\tstd::vector<ttstr> vecButtons;\n\t\t\tif (nButtons >= 1)\n\t\t\t\tvecButtons.emplace_back(TJS_W(\"OK\"));\n\t\t\tif (nButtons >= 2)\n\t\t\t\tvecButtons.emplace_back(TJS_W(\"Cancel\"));\n\t\t\tint ret = TVPShowSimpleMessageBox(text, caption, vecButtons);\n\t\t\tif (result) result->operator =(ret);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\n\tTVPShowSimpleMessageBox(text, caption);\n\n\tif(result) result->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/inform)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTickCount)\n{\n\tif(result)\n\t{\n\t\tTVPStartTickCount();\n\n\t\t*result = (tjs_int64) TVPGetTickCount();\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/getTickCount)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getKeyState)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_uint code = (tjs_int)*param[0];\n\n\tbool getcurrent = true;\n\tif(numparams >= 2) getcurrent = 0!=(tjs_int)*param[1];\n\n\tbool res = TVPGetAsyncKeyState(code, getcurrent);\n\n\tif(result) *result = (tjs_int)res;\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/getKeyState)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/shellExecute)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr target = *param[0];\n\tttstr execparam;\n\n\tif(numparams >= 2) execparam = *param[1];\n\n\tbool res = TVPShellExecute(target, execparam);\n\n\tif(result) *result = (tjs_int)res;\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/shellExecute)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/system)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr target = *param[0];\n\n\tint ret = 0;// _wsystem(target.c_str());\n\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX); // this should clear all caches\n\n\tif(result) *result = (tjs_int)ret;\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/system)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/readRegValue)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif(!result) return TJS_S_OK;\n\n\tttstr key = *param[0];\n\n\n\tTVPReadRegValue(*result, key);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/readRegValue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getArgument)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif(!result) return TJS_S_OK;\n\n\tttstr name = *param[0];\n\n\tbool res = TVPGetCommandLine(name.c_str(), result);\n\n\tif(!res) result->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/getArgument)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setArgument)\n{\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name = *param[0];\n\tttstr value = *param[1];\n\n\tTVPSetCommandLine(name.c_str(), value);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/setArgument)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/createAppLock)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif(!result) return TJS_S_OK;\n\n\tttstr lockname = *param[0];\n\n\tbool res = TVPCreateAppLock(lockname);\n\n\tif(result) *result = (tjs_int)res;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/createAppLock)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dumpHeap)\n{\n//\tTVPHeapDump();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/dumpHeap)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/nullpo)\n{\n\t// force make a null-po\n#ifdef _MSC_VER\n\t*(int *)0  = 0;\n#else\n\t__builtin_trap();\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/nullpo)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/showVersion)\n{\n//\tTVPShowVersionForm();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/showVersion)\n//---------------------------------------------------------------------------\n\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(exePath)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetAppPath();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, exePath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(personalPath)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetPersonalPath();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, personalPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(appDataPath)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetAppDataPath();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, appDataPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(dataPath)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPDataPath;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, dataPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(exeName)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tstatic ttstr exename(TVPNormalizeStorageName(ExePath()));\n\t\t*result = exename;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, exeName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(savedGamesPath)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetSavedGamesPath();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, savedGamesPath)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(title)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tif(!TVPAppTitleInit)\n\t\t{\n\t\t\tTVPAppTitleInit = true;\n\t\t\tTVPAppTitle = Application->GetTitle();\n\t\t}\n\t\t*result = TVPAppTitle;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPAppTitle = *param;\n\t\tApplication->SetTitle( TVPAppTitle.AsStdString() );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, title)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(screenWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, screenWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(screenHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, screenHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(desktopLeft)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetDesktopLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopLeft)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(desktopTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetDesktopTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopTop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(desktopWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetDesktopWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(desktopHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTVPScreen::GetDesktopHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(touchDevice)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetSupportTouchDevice();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, touchDevice)\n//----------------------------------------------------------------------\n\n\n\treturn cls;\n\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/base/win32/SystemImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"System\" class implementation\n//---------------------------------------------------------------------------\n#ifndef SystemImplH\n#define SystemImplH\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(bool, TVPGetAsyncKeyState, (tjs_uint keycode, bool getcurrent = true));\n//---------------------------------------------------------------------------\nextern void TVPPostApplicationActivateEvent();\nextern void TVPPostApplicationDeactivateEvent();\nextern bool TVPShellExecute(const ttstr &target, const ttstr &param);\nextern void TVPDoSaveSystemVariables();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/base/win32/win32io.h",
    "content": "#pragma once\n#ifdef WIN32\n// posix io api\nextern \"C\" {\n\textern __int64 __cdecl lseek64(int _FileHandle, __int64 _Offset, int _Origin);\n\textern void* valloc(int n);\n\textern void vfree(void *p);\n}\n#endif\n#ifdef CC_TARGET_OS_IPHONE\n#define lseek64 lseek\n#endif"
  },
  {
    "path": "src/core/environ/Application.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include <string>\n#include <vector>\n#include <assert.h>\n\n#include \"tjsError.h\"\n#include \"tjsDebug.h\"\n\n#include \"Application.h\"\n#include \"SysInitIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"DebugIntf.h\"\n#include \"MsgIntf.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tjsError.h\"\n#include \"PluginImpl.h\"\n#include \"SystemIntf.h\"\n\n#include \"Exception.h\"\n//#include \"Resource.h\"\n#include \"SystemControl.h\"\n//#include \"MouseCursor.h\"\n#include \"SystemImpl.h\"\n#include \"WaveImpl.h\"\n#include \"GraphicsLoadThread.h\"\n#include \"Platform.h\"\n#include \"EventIntf.h\"\n#include <thread>\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"StorageIntf.h\"\nextern \"C\" {\n#include <libavutil/avstring.h>\n}\n#include \"TVPColor.h\"\n#include \"FontImpl.h\"\n\n//#include \"resource.h\"\n\n//#pragma comment(lib,\"dbghelp.lib\")\n/*\nkernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;dsound.lib;version.lib;mpr.lib;shlwapi.lib;vfw32.lib;imm32.lib;zlib_d.lib;jpeg-6bx_d.lib;libpng_d.lib;onig_s_d.lib;freetype250MT_D.lib;tvpgl_ia32.lib;tvpsnd_ia32.lib;%(AdditionalDependencies)\nkernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;dsound.lib;version.lib;mpr.lib;shlwapi.lib;vfw32.lib;imm32.lib;zlib.lib;jpeg-6bx.lib;libpng.lib;onig_s.lib;freetype250MT.lib;tvpgl_ia32.lib;tvpsnd_ia32.lib;%(AdditionalDependencies)\n*/\n\ntTVPApplication* Application = new tTVPApplication;\nstd::thread::id TVPMainThreadID;\nstatic tTJSCriticalSection _NoMemCallBackCS;\nstatic void *_reservedMem = malloc(1024 * 1024 * 4); // 4M reserved mem\nstatic bool _project_startup = false;\ntTJS *TVPAppScriptEngine;\n// ## fix ld: error: undefined symbol: __real_malloc\n// #define HOOK_MALLOC \n\nstatic void _do_compact() {\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX);\n}\n\nstatic void _no_memory_cb() {\n\ttTJSCSH lock(_NoMemCallBackCS);\n\tfree(_reservedMem);\n\tif (TVPMainThreadID == std::this_thread::get_id()) {\n\t\t_do_compact();\n\t} else {\n\t\tApplication->PostUserMessage(_do_compact);\n\t}\n\t_reservedMem = realloc(0, 1024 * 1024 * 4);\n}\n\nstatic std::string _title, _msg, _retry, _cancel;\nstatic tTJSCriticalSection _cs;\ntypedef void* F_alloc_t(void*, size_t);\nstatic void* __do_alloc_func(F_alloc_t *f, void *p, size_t c) {\n\tvoid *ptr = f(p, c);\n\n\tif (!ptr) {\n\t\t_no_memory_cb();\n\t\tptr = f(p, c);\n\t\tif (!ptr) {\n\t\t\ttTJSCSH lock(_cs);\n\t\t\tconst char *btns[2] = { _retry.c_str(), _cancel.c_str() };\n\t\t\twhile (!ptr && TVPShowSimpleMessageBox(_msg.c_str(), _title.c_str(), 2, btns) == 0) {\n\t\t\t\tptr = f(p, c);\n\t\t\t}\n\t\t\t//TVPExitApplication(-1);\n\t\t}\n\t}\n\treturn ptr;\n}\n\nttstr TVPGetErrorDialogTitle() {\n\tconst ttstr &title = Application->GetTitle();\n\tif (title.IsEmpty()) {\n\t\treturn TVPGetPackageVersionString() + \" Error\";\n\t} else {\n\t\treturn ttstr(TVPGetPackageVersionString()) + \" \" + title;\n\t}\n}\n\n#ifdef HOOK_MALLOC\nextern \"C\" {\n\tvoid* tc_malloc(size_t size);\n\tvoid tc_free(void* ptr);\n\tvoid* tc_realloc(void* ptr, size_t size);\n\tvoid* tc_calloc(size_t nmemb, size_t size);\n\n\tvoid *__real_malloc(size_t);\n\tvoid __real_free(void*);\n\tvoid* __real_realloc(void*, size_t);\n\tvoid* __real_calloc(size_t nmemb, size_t size);\n#ifdef WIN32\n\tvoid* tc_malloc(size_t size) { return nullptr; }\n\tvoid tc_free(void* ptr) {}\n\tvoid* tc_realloc(void* ptr, size_t size){ return nullptr; }\n\tvoid* tc_calloc(size_t nmemb, size_t size){ return nullptr; }\n\n\tvoid *__real_malloc(size_t) { return nullptr; }\n\tvoid __real_free(void*) { return; }\n\tvoid* __real_realloc(void*, size_t) { return nullptr; }\n\tvoid* __real_calloc(size_t nmemb, size_t size){ return nullptr; }\n#endif\n\n\tstatic void *__func_malloc(void *, size_t c) {\n#ifdef TC_MALLOC\n\t\tint *ptr;\n\t\tif (tc_malloc_startup) {\n\t\t\tptr = (int *)tc_malloc(c + sizeof(int));\n\t\t\tif (ptr) {\n\t\t\t\t*ptr++ = 1;\n\t\t\t}\n\t\t} else {\n\t\t\tptr = (int *)__real_malloc(c + sizeof(int));\n\t\t\tif (ptr) {\n\t\t\t\t*ptr++ = 0;\n\t\t\t}\n\t\t}\n\t\treturn ptr;\n#else\n\t\treturn __real_malloc(c);\n#endif\n\t}\n\n\tvoid *__wrap_malloc(size_t c)\n\t{\n#ifdef HOOK_MALLOC_FOR_OVERRUN\n\t\ttry {\n\t\t\treturn __real_malloc(c);\n\t\t}\n\t\tcatch (...) {\n\t\t\tTVPExitApplication(-1);\n\t\t}\n#else\n\t\treturn __do_alloc_func(__func_malloc, nullptr, c);\n#endif\n\t}\n\n\tstatic void *__func_realloc(void *p, size_t c) {\n#ifdef TC_MALLOC\n\t\tif (!p) return __func_malloc(p, c);\n\t\tint *ptr = (int *)p;\n\t\tif (ptr[-1]) {\n\t\t\tptr = (int *)tc_realloc(ptr - 1, c + sizeof(int));\n\t\t} else {\n\t\t\tptr = (int *)__real_realloc(ptr - 1, c + sizeof(int));\n\t\t}\n\t\treturn ptr;\n#else\n\t\treturn __real_realloc(p, c);\n#endif\n\t}\n\n\tvoid *__wrap_realloc(void *p, size_t c) {\n#ifdef HOOK_MALLOC_FOR_OVERRUN\n\t\ttry {\n\t\t\treturn __real_realloc(p, c);\n\t\t}\n\t\tcatch (...) {\n\t\t\tTVPExitApplication(-1);\n\t\t}\n#else\n\t\treturn __do_alloc_func(__func_realloc, p, c);\n#endif\n\t}\n\n\tstatic void *__func_calloc(void *p, size_t c) {\n#ifdef TC_MALLOC\n\t\tint *ptr;\n\t\tif (tc_malloc_startup) {\n\t\t\tptr = (int *)tc_calloc(c + sizeof(int), 1);\n\t\t\tif (ptr) {\n\t\t\t\t*ptr++ = 1;\n\t\t\t}\n\t\t} else {\n\t\t\tptr = (int *)__real_calloc(c + sizeof(int), 1);\n\t\t\tif (ptr) {\n\t\t\t\t*ptr++ = 0;\n\t\t\t}\n\t\t}\n\t\tif (ptr) memset(ptr, 0, c);\n\t\treturn ptr;\n#else\n\t\treturn __real_calloc(c, 1);\n#endif\n\t}\n\n\tvoid *__wrap_calloc(size_t nmemb, size_t size) {\n#ifdef HOOK_MALLOC_FOR_OVERRUN\n\t\ttry {\n\t\t\treturn __real_calloc(nmemb, size);\n\t\t}\n\t\tcatch (...) {\n\t\t\tTVPExitApplication(-1);\n\t\t}\n#else\n\t\tsize *= nmemb;\n\t\tvoid* p = __do_alloc_func(__func_malloc, nullptr, size);\n\t\tif (p) memset(p, 0, size);\n\t\treturn p;\n#endif\n\t}\n\n\tvoid __wrap_free(void *p) {\n#ifdef HOOK_MALLOC_FOR_OVERRUN\n\t\ttry {\n\t\t\treturn __real_free(p);\n\t\t}\n\t\tcatch (...) {\n\t\t\tTVPExitApplication(-1);\n\t\t}\n#elif defined(TC_MALLOC)\n\t\tint *ptr = (int *)p;\n\t\tif (ptr[-1] == 0) __real_free(ptr - 1);\n\t\telse tc_free(ptr - 1);\n#else\n\t\t__real_free(p);\n#endif\n\t}\n}\n#endif\n\n#if 0\n#ifdef TJS_64BIT_OS\nextern void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long long osEsp, PCONTEXT ctx);\n#else\nextern void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, PCONTEXT ctx);\n#endif\n\n// �A�v���P�[�V�����̊J�n���ɌĂ�\ninline void CheckMemoryLeaksStart()\n{\n#ifdef  _DEBUG\n   _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);\n#endif  // _DEBUG\n}\n\ninline void DumpMemoryLeaks()\n{\n#ifdef  _DEBUG\n\tint is_leak = _CrtDumpMemoryLeaks();\n\tassert( !is_leak );\n#endif  // _DEBUG\n}\n#endif\n\nttstr ExePath() {\n\treturn TVPNativeProjectDir;\n}\n\nbool TVPCheckAbout();\nbool TVPCheckPrintDataPath();\nvoid TVPOnError();\nvoid TVPLockSoundMixer();\nvoid TVPUnlockSoundMixer();\n\nstatic bool _warnLowMem = true;\nvoid TVPCheckMemory() {\n#if defined(_DEBUG)\n\tif (_warnLowMem) {\n\t\ttjs_int freeMem = TVPGetSystemFreeMemory();\n\t\tif (freeMem < 24) {\n\t\t\tchar buf[256];\n\t\t\tsprintf(buf, \"Insufficient memory (%dMB available)\\nYou can diable this notice in global preference.\", freeMem);\n\t\t\tconst char *btn = \"OK\";\n\t\t\tTVPShowSimpleMessageBox(buf, \"No Memory Warning\", 1, &btn);\n\t\t\t_warnLowMem = false;\n\t\t}\n\t}\n#endif\n}\n\nint TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption) {\n\tstd::vector<ttstr> normal; normal.emplace_back(LocaleConfigManager::GetInstance()->GetText(\"msgbox_ok\"));\n\treturn TVPShowSimpleMessageBox(text, caption, normal);\n}\n\nint TVPShowSimpleMessageBoxYesNo(const ttstr & text, const ttstr & caption) {\n\tstd::vector<ttstr> normal;\n\tLocaleConfigManager *mgr = LocaleConfigManager::GetInstance();\n\tnormal.emplace_back(mgr->GetText(\"msgbox_yes\"));\n\tnormal.emplace_back(mgr->GetText(\"msgbox_no\"));\n\treturn TVPShowSimpleMessageBox(text, caption, normal);\n}\n\nttstr TVPGetMessageByLocale(const std::string &key) {\n\treturn LocaleConfigManager::GetInstance()->GetText(key);\n}\n\nint _argc;\nchar ** _argv;\n#if 0\nextern void TVPInitCompatibleNativeFunctions();\nextern void TVPLoadMessage();\nAcceleratorKeyTable::AcceleratorKeyTable() {\n\t// �f�t�H���g��ǂݍ���\n\thAccel_ = ::LoadAccelerators( (HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDC_TVPWIN32));\n}\nAcceleratorKeyTable::~AcceleratorKeyTable() {\n\tstd::map<HWND,AcceleratorKey*>::iterator i = keys_.begin();\n\tfor( ; i != keys_.end(); i++ ) {\n\t\tdelete (i->second);\n\t}\n}\nvoid AcceleratorKeyTable::AddKey( HWND hWnd, WORD id, WORD key, BYTE virt ) {\n\tstd::map<HWND,AcceleratorKey*>::iterator i = keys_.find(hWnd);\n\tif( i != keys_.end() ) {\n\t\ti->second->AddKey(id,key,virt);\n\t} else {\n\t\tAcceleratorKey* acc = new AcceleratorKey();\n\t\tacc->AddKey( id, key, virt );\n\t\tkeys_.insert( std::map<HWND, AcceleratorKey*>::value_type( hWnd, acc ) );\n\t}\n}\nvoid AcceleratorKeyTable::DelKey( HWND hWnd, WORD id ) {\n\tstd::map<HWND,AcceleratorKey*>::iterator i = keys_.find(hWnd);\n\tif( i != keys_.end() ) {\n\t\ti->second->DelKey(id);\n\t}\n}\n\nvoid AcceleratorKeyTable::DelTable( HWND hWnd ) {\n\tstd::map<HWND,AcceleratorKey*>::iterator i = keys_.find(hWnd);\n\tif( i != keys_.end() ) {\n\t\tdelete (i->second);\n\t\tkeys_.erase(i);\n\t}\n}\nAcceleratorKey::AcceleratorKey() : hAccel_(NULL), keys_(NULL), key_count_(0) {\n}\nAcceleratorKey::~AcceleratorKey() {\n\tif( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ );\n\tdelete[] keys_;\n}\nvoid AcceleratorKey::AddKey( WORD id, WORD key, BYTE virt ) {\n\t// �܂��͑��݂��邩�`�F�b�N����\n\tbool found = false;\n\tint index = 0;\n\tfor( int i = 0; i < key_count_; i++ ) {\n\t\tif( keys_[i].cmd == id ) {\n\t\t\tindex = i;\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif( found ) {\n\t\t// ���ɓo�^����Ă���R�}���h�Ȃ̂ŃL�[���̍X�V���s��\n\t\tif( keys_[index].key == key && keys_[index].fVirt == virt ) {\n\t\t\t// �ύX����Ă��Ȃ�\n\t\t\treturn;\n\t\t}\n\t\tkeys_[index].key = key;\n\t\tkeys_[index].fVirt = virt;\n\t\tHACCEL hAccel = ::CreateAcceleratorTable( keys_, key_count_ );\n\t\tif( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ );\n\t\thAccel_ = hAccel;\n\t} else {\n\t\tACCEL* table = new ACCEL[key_count_+1];\n\t\tfor( int i = 0; i < key_count_; i++ ) {\n\t\t\ttable[i] = keys_[i];\n\t\t}\n\t\ttable[key_count_].cmd = id;\n\t\ttable[key_count_].key = key;\n\t\ttable[key_count_].fVirt = virt;\n\t\tkey_count_++;\n\t\tHACCEL hAccel = ::CreateAcceleratorTable( table, key_count_ );\n\t\tif( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ );\n\t\thAccel_ = hAccel;\n\t\tdelete[] keys_;\n\t\tkeys_ = table;\n\t}\n\n}\nvoid AcceleratorKey::DelKey( WORD id ) {\n\t// �܂��͑��݂��邩�`�F�b�N����\n\tbool found = false;\n\tfor( int i = 0; i < key_count_; i++ ) {\n\t\tif( keys_[i].cmd == id ) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif( found == false ) return;\n\n\t// ���݂����ꍇ��蒼��\n\tACCEL* table = new ACCEL[key_count_-1];\n\tint dest = 0;\n\tfor( int i = 0; i < key_count_; i++ ) {\n\t\tif( keys_[i].cmd != id ) {\n\t\t\ttable[dest] = keys_[i];\n\t\t\tdest++;\n\t\t}\n\t}\n\tkey_count_--;\n\tHACCEL hAccel = ::CreateAcceleratorTable( table, key_count_ );\n\tif( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ );\n\thAccel_ = hAccel;\n\tdelete[] keys_;\n\tkeys_ = table;\n}\n\nint APIENTRY WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) {\n\ttry {\n\t\tCheckMemoryLeaksStart();\n\t\t// �E�H�b�`�� _crtBreakAlloc �ɃZ�b�g����\n\n\t\t// XP ����Ŏg����API�𓮓I�ɓǂݍ���Ō݊��������\n\t\tTVPInitCompatibleNativeFunctions();\n\n\t\t// ���b�Z�[�W����������\\�[�X����Ǎ���\n\t\tTVPLoadMessage();\n\n\t\t_argc = __argc;\n\t\t_argv = __argv;\n\n\t\tMouseCursor::Initialize();\n\t\tApplication = new tTVPApplication();\n\t\tApplication->StartApplication( __argc, __argv );\n\t\n\t\t// delete application and exit forcely\n\t\t// this prevents ugly exception message on exit\n\t\t// �A�v���P�[�V�������폜�������I��������B\n\t\t// ����͏I�����̏X����O���b�Z�[�W��}�~����\n\t\tdelete Application;\n\n#ifndef _DEBUG\n//\t\t::ExitProcess(TVPTerminateCode); // �����ŏI��������ƃ��������[�N�\\�����s���Ȃ�\n#endif\n\t} catch (...) {\n\t\treturn 2;\n\t}\n\treturn TVPTerminateCode;\n}\n#endif\ntTVPApplication::tTVPApplication() : is_attach_console_(false), tarminate_(false), application_activating_(true)\n\t , image_load_thread_(NULL), has_map_report_process_(false)\n{\n}\ntTVPApplication::~tTVPApplication() {\n// \twhile( windows_list_.size() ) {\n// \t\tstd::vector<TTVPWindowForm*>::iterator i = windows_list_.begin();\n// \t\tdelete (*i);\n// \t\t// TTVPWindowForm �̃f�X�g���N�^���Ń��X�g����폜�����͂�\n// \t}\n// \twindows_list_.clear();\n\tdelete image_load_thread_;\n}\n#if 0\nstruct SEHException {\n\tunsigned int Code;\n\t_EXCEPTION_POINTERS* ExceptionPointers;\n\tSEHException( unsigned int code, _EXCEPTION_POINTERS* ep )\n\t\t: Code(code), ExceptionPointers(ep)\n\t{}\n};\n\nint TVPWriteHWEDumpFile( EXCEPTION_POINTERS* pExceptionPointers ) {\n\tBOOL bMiniDumpSuccessful;\n\tWCHAR szPath[MAX_PATH]; \n\tWCHAR szFileName[MAX_PATH]; \n\tconst wchar_t* szAppName = TVPKirikiri;\n\tconst wchar_t* szVersion = TVPGetVersionString().c_str();\n\n\tTVPEnsureDataPathDirectory();\n\tTJS_strcpy(szPath, TVPNativeDataPath.c_str());\n\n\tSYSTEMTIME stLocalTime;\n\t::GetLocalTime( &stLocalTime );\n\tStringCchPrintf( szFileName, MAX_PATH, L\"%s%s%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp\",\n\t\t\t\tszPath, szAppName, szVersion,\n\t\t\t\tstLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,\n\t\t\t\tstLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,\n\t\t\t\tGetCurrentProcessId(), GetCurrentThreadId());\n\tHANDLE hDumpFile = ::CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,\n\t\t\t\tFILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);\n\n\tMINIDUMP_EXCEPTION_INFORMATION ExpParam;\n\tExpParam.ThreadId = ::GetCurrentThreadId();\n\tExpParam.ExceptionPointers = pExceptionPointers;\n\tExpParam.ClientPointers = TRUE;\n\tbMiniDumpSuccessful = MiniDumpWriteDump( ::GetCurrentProcess(), ::GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);\n\treturn EXCEPTION_EXECUTE_HANDLER;\n}\nstatic bool TVPIsHandledHWException = false;\nvoid se_translator_function(unsigned int code, struct _EXCEPTION_POINTERS* ep) {\n\tif( !TVPIsHandledHWException ) {\n\t\t//ShowStackTrace( ep->ContextRecord );\n\t\tTVPWriteHWEDumpFile( ep );\n#ifdef TJS_64BIT_OS\n\t\tTVPHandleSEHException( code, ep->ExceptionRecord, ep->ContextRecord->Rsp, ep->ContextRecord );\n#else\n\t\tTVPHandleSEHException( code, ep->ExceptionRecord, ep->ContextRecord->Esp, ep->ContextRecord );\n#endif\n\t\tTVPIsHandledHWException = true;\n\t}\n\tthrow SEHException(code,ep);\n}\nconst wchar_t* SECodeToMessage( unsigned int code ) {\n\tswitch(code){\n\tcase EXCEPTION_ACCESS_VIOLATION: return TVPExceptionAccessViolation;\n\tcase EXCEPTION_BREAKPOINT: return TVPExceptionBreakpoint;\n\tcase EXCEPTION_DATATYPE_MISALIGNMENT: return TVPExceptionDatatypeMisalignment;\n\tcase EXCEPTION_SINGLE_STEP: return TVPExceptionSingleStep;\n\tcase EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return TVPExceptionArrayBoundsExceeded;\n\tcase EXCEPTION_FLT_DENORMAL_OPERAND: return TVPExceptionFltDenormalOperand;\n\tcase EXCEPTION_FLT_DIVIDE_BY_ZERO: return TVPExceptionFltDivideByZero;\n\tcase EXCEPTION_FLT_INEXACT_RESULT: return TVPExceptionFltInexactResult;\n\tcase EXCEPTION_FLT_INVALID_OPERATION: return TVPExceptionFltInvalidOperation;\n\tcase EXCEPTION_FLT_OVERFLOW: return TVPExceptionFltOverflow;\n\tcase EXCEPTION_FLT_STACK_CHECK: return TVPExceptionFltStackCheck;\n\tcase EXCEPTION_FLT_UNDERFLOW: return TVPExceptionFltUnderflow;\n\tcase EXCEPTION_INT_DIVIDE_BY_ZERO: return TVPExceptionIntDivideByZero;\n\tcase EXCEPTION_INT_OVERFLOW: return TVPExceptionIntOverflow;\n\tcase EXCEPTION_PRIV_INSTRUCTION: return TVPExceptionPrivInstruction;\n\tcase EXCEPTION_NONCONTINUABLE_EXCEPTION: return TVPExceptionNoncontinuableException;\n\tcase EXCEPTION_GUARD_PAGE: return TVPExceptionGuardPage;\n\tcase EXCEPTION_ILLEGAL_INSTRUCTION: return TVPExceptionIllegalInstruction;\n\tcase EXCEPTION_IN_PAGE_ERROR: return TVPExceptionInPageError;\n\tcase EXCEPTION_INVALID_DISPOSITION: return TVPExceptionInvalidDisposition;\n\tcase EXCEPTION_INVALID_HANDLE: return TVPExceptionInvalidHandle;\n\tcase EXCEPTION_STACK_OVERFLOW: return TVPExceptionStackOverflow;\n\tcase STATUS_UNWIND_CONSOLIDATE: return TVPExceptionUnwindCconsolidate;\n\t}\n\treturn L\"Unknown\";\n}\n#endif\nextern void TVPLoadPluigins(void);\nbool tTVPApplication::StartApplication(ttstr path) {\n//\t_set_se_translator(se_translator_function);\n\n\tArgC = 0;\n\tArgV = nullptr;\n#if 0\n\tfor( int i = 0; i < argc; i++ ) {\n\t\tif(!strcmp(argv[i], \"-@processohmlog\")) {\n\t\t\thas_map_report_process_ = true;\n\t\t}\n\t}\n#endif\n\tTVPTerminateCode = 0;\n\tLocaleConfigManager *mgr = LocaleConfigManager::GetInstance();\n\t_retry = mgr->GetText(\"retry\");\n\t_cancel = mgr->GetText(\"cancel\");\n\t_msg = mgr->GetText(\"err_no_memory\");\n\t_title = mgr->GetText(\"err_occured\");\n\tTVPNativeProjectDir = path;\n\n\tCheckConsole();\n\n\t// try starting the program!\n\ttry {\n//\t\tif(TVPCheckProcessLog()) return true; // sub-process for processing object hash map log\n\n\t\tTVPProjectDir = TVPNormalizeStorageName(path);\n\n\t\tTVPInitScriptEngine();\n\t\tTVPInitFontNames();\n\n\t\t// banner\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPProgramStartedOn, TVPGetOSName(), TVPGetPlatformName()) );\n\n\t\t// TVPInitializeBaseSystems\n\t\tTVPInitializeBaseSystems();\n\n\t\tInitialize();\n\n\t\tif(TVPCheckPrintDataPath()) return true;\n\t\tif(TVPExecuteUserConfig()) return true;\n\t\t\n\t\timage_load_thread_ = new tTVPAsyncImageLoader();\n\n\t\tTVPLoadPluigins(); // load plugin module *.tpm\n\t\tTVPSystemInit();\n\n\t\tif(TVPCheckAbout()) return true; // version information dialog box;\n\n\t\tSetTitle(TVPKirikiri.operator const tjs_char *());\n\t\tTVPSystemControl = new tTVPSystemControl();\n\t\t// Check digitizer\n\t\tCheckDigitizer();\n\n\t\t// start image load thread\n\t\timage_load_thread_->Resume();\n\n\t\t/*if(TVPProjectDirSelected)*/ TVPInitializeStartupScript();\n\t\t_project_startup = true;\n//\t\tRun();\n#if 0\n\t\ttry {\n\t\t\t// image_load_thread_->ExitRequest();\n\t\t\tdelete image_load_thread_;\n\t\t\timage_load_thread_ = NULL;\n\t\t} catch(...) {\n\t\t\t// ignore errors\n\t\t}\n\t\ttry {\n\t\t\tTVPSystemUninit();\n\t\t} catch(...) {\n\t\t\t// ignore errors\n\t\t}\n#endif\n\t} catch( const EAbort & ) {\n\t\t// nothing to do\n#if !(defined(_MSC_VER) && defined(_DEBUG))\n\t} catch (const Exception &exception) {\n\t\tTVPOnError();\n\t\tif(!TVPSystemUninitCalled)\n\t\t\tShowException(exception.what());\n\t} catch( const TJS::eTJSScriptError &e ) {\n\t\tTVPOnError();\n\t\tif (!TVPSystemUninitCalled) {\n\t\t\tttstr msg;\n\t\t\tif (!title_.IsEmpty()) {\n\t\t\t\tmsg += title_;\n\t\t\t\tmsg += \"\\n\";\n\t\t\t}\n\t\t\tmsg += e.GetMessage();\n\t\t\tconst tjs_char *pszBlockName = e.GetBlockName();\n\t\t\tif (pszBlockName && *pszBlockName) {\n\t\t\t\tmsg += TJS_W(\"\\n@line(\");\n\t\t\t\ttjs_char tmp[34];\n\t\t\t\tmsg += TJS_int_to_str(e.GetSourceLine(), tmp);\n\t\t\t\tmsg += TJS_W(\") \");\n\t\t\t\tmsg += pszBlockName;\n\t\t\t}\n\t\t\tmsg += TJS_W(\"\\n\");\n\t\t\tmsg += e.GetTrace();\n\t\t\tShowException(msg);\n\t\t}\n\t} catch( const TJS::eTJS &e) {\n\t\tTVPOnError();\n\t\tif(!TVPSystemUninitCalled)\n\t\t\tShowException( e.GetMessage() );\n\t} catch( const std::exception &e ) {\n\t\tShowException( e.what() );\n\t} catch( const char* e ) {\n\t\tShowException( e );\n\t} catch( const tjs_char* e ) {\n\t\tShowException( e );\n#if 0\n\t} catch( const SEHException& e ) {\n\t\tPEXCEPTION_RECORD rec = e.ExceptionPointers->ExceptionRecord;\n\t\tstd::wstring text(SECodeToMessage(e.Code));\n\t\tttstr result = TJSGetStackTraceString( 10 );\n\t\tPrintConsole( result.c_str(), result.length(), true );\n\n\t\tTVPDumpHWException();\n\t\tShowException( text.c_str() );\n#endif\n\t} catch(...) {\n\t\tShowException( (const tjs_char*)TVPUnknownError );\n#endif\n\t}\n\n\treturn false;\n}\n/**\n * �R���\\�[������̋N�����m�F���A�R���\\�[������̋N���̏ꍇ�́A�W���o�͂����蓖�Ă�\n */\nvoid tTVPApplication::CheckConsole() {\n#ifdef TVP_LOG_TO_COMMANDLINE_CONSOLE\n\tif( has_map_report_process_ ) return; // �����o���p�q�v���Z�X���ċN������Ă������̓R���\\�[���ڑ����Ȃ�\n\tHANDLE hin  = ::GetStdHandle(STD_INPUT_HANDLE);\n\tHANDLE hout = ::GetStdHandle(STD_OUTPUT_HANDLE);\n\tHANDLE herr = ::GetStdHandle(STD_ERROR_HANDLE);\n\n\tDWORD curProcId = ::GetCurrentProcessId();\n\tDWORD processList[256];\n\tDWORD count = ::GetConsoleProcessList( processList, 256 );\n\tbool thisProcHasConsole = false;\n\tfor( DWORD i = 0; i < count; i++ ) {\n\t\tif( processList[i] == curProcId ) {\n\t\t\tthisProcHasConsole = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tbool attachedConsole = true;\n\tif( thisProcHasConsole == false ) {\n\t\tattachedConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != 0;\n\t}\n\n\tif( (hin==0||hout==0||herr==0) && attachedConsole ) {\n\t\twchar_t console[256];\n\t\t::GetConsoleTitle( console, 256 );\n\t\tconsole_title_ = std::wstring( console );\n\t\t// ���̃n���h�����Ċ��蓖��\n\t\tif (hin)  ::SetStdHandle(STD_INPUT_HANDLE, hin);\n\t\tif (hout) ::SetStdHandle(STD_OUTPUT_HANDLE, hout);\n\t\tif (herr) ::SetStdHandle(STD_ERROR_HANDLE, herr);\n\t}\n\tis_attach_console_ = attachedConsole;\n#endif\n}\n\nvoid tTVPApplication::CloseConsole() {\n#if 0\n\twchar_t buf[100];\n\tDWORD len = TJS_snprintf(buf, 100, TVPExitCode, TVPTerminateCode);\n\tPrintConsole(buf, len);\n\tif( is_attach_console_ ) {\n\t\t::SetConsoleTitle( console_title_.c_str() );\n\t\t::FreeConsole();\n\t\tis_attach_console_ = false;\n\t}\n#endif\n}\nvoid TVPConsoleLog(const ttstr &mes, bool important);\nvoid tTVPApplication::PrintConsole(const ttstr &mes, bool important) {\n\tTVPConsoleLog(mes, important);\n}\n#if 0\nHWND tTVPApplication::GetHandle() {\n\tif( windows_list_.size() > 0 ) {\n\t\treturn windows_list_[0]->GetHandle();\n\t} else {\n\t\treturn INVALID_HANDLE_VALUE;\n\t}\n}\nvoid tTVPApplication::Minimize() {\n\tsize_t size = windows_list_.size();\n\tfor( size_t i = 0; i < size; i++ ) {\n\t\tif( windows_list_[i]->GetVisible() ) {\n\t\t\t::ShowWindow( windows_list_[i]->GetHandle(), SW_MINIMIZE );\n\t\t}\n\t}\n}\nvoid tTVPApplication::Restore() {\n\tsize_t size = windows_list_.size();\n\tfor( size_t i = 0; i < size; i++ ) {\n\t\tif( windows_list_[i]->GetVisible() ) {\n\t\t\t::ShowWindow( windows_list_[i]->GetHandle(), SW_RESTORE );\n\t\t}\n\t}\n}\nvoid tTVPApplication::BringToFront() {\n\tsize_t size = windows_list_.size();\n\tfor( size_t i = 0; i < size; i++ ) {\n\t\twindows_list_[i]->BringToFront();\n\t}\n}\n#endif\nvoid tTVPApplication::ShowException(const ttstr& e) {\n\tTVPShowSimpleMessageBox(e, TVPGetErrorDialogTitle());\n\tTVPSystemUninit();\n\tTVPExitApplication(0);\n}\nvoid tTVPApplication::Run() {\n\ttry {\n\t\tif (TVPTerminated) {\n\t\t\tTVPSystemUninit();\n\t\t\tTVPExitApplication(TVPTerminateCode);\n\t\t}\n\t//\tTVPBreathe();\n\t\tProcessMessages();\n\t\tif (TVPSystemControl) TVPSystemControl->SystemWatchTimerTimer();\n//\t\tTVPDeliverWindowUpdateEvents(); // from SystemWatchTimerTimer\n\t} catch (const EAbort &) {\n\t\t// nothing to do\n#if !(defined(_MSC_VER) && defined(_DEBUG))\n\t} catch (const Exception &exception) {\n\t\tTVPOnError();\n\t\tif(!TVPSystemUninitCalled)\n\t\t\tShowException(exception.what());\n\t} catch( const TJS::eTJSScriptError &e ) {\n\t\tTVPOnError();\n\t\tif (!TVPSystemUninitCalled) {\n\t\t\tttstr msg;\n\t\t\tif (!title_.IsEmpty()) {\n\t\t\t\tmsg += title_;\n\t\t\t\tmsg += \"\\n\";\n\t\t\t}\n\t\t\tmsg += e.GetMessage();\n\t\t\tconst tjs_char *pszBlockName = e.GetBlockName();\n\t\t\tif (pszBlockName && *pszBlockName) {\n\t\t\t\tmsg += TJS_W(\"\\n@line(\");\n\t\t\t\ttjs_char tmp[34];\n\t\t\t\tmsg += TJS_int_to_str(e.GetSourceLine(), tmp);\n\t\t\t\tmsg += TJS_W(\") \");\n\t\t\t\tmsg += pszBlockName;\n\t\t\t}\n\t\t\tmsg += TJS_W(\"\\n\");\n\t\t\tmsg += e.GetTrace();\n\t\t\tShowException(msg);\n\t\t}\n\t} catch( const TJS::eTJS &e) {\n\t\tTVPOnError();\n\t\tif(!TVPSystemUninitCalled)\n\t\t\tShowException( e.GetMessage() );\n\t} catch( const std::exception &e ) {\n\t\tShowException( e.what() );\n\t} catch( const char* e ) {\n\t\tShowException( e );\n\t} catch( const tjs_char* e ) {\n\t\tShowException( e );\n\t} catch (...) {\n\t\tShowException((const tjs_char*)TVPUnknownError);\n#endif\n\t}\n}\n\nvoid tTVPApplication::ProcessMessages()\n{\n\tstd::vector<std::tuple<void*, int, tMsg> > lstUserMsg;\n\t{\n\t\tstd::lock_guard<std::mutex> cs(m_msgQueueLock);\n\t\tm_lstUserMsg.swap(lstUserMsg);\n\t}\n\tfor (std::tuple<void*, int, tMsg>& it : lstUserMsg) {\n\t\tstd::get<2>(it)();\n\t}\n\tTVPTimer::ProgressAllTimer();\n}\n\n#if 0\nbool tTVPApplication::ProcessMessage( MSG &msg ) {\n\tbool result = false;\n\tif( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE) ) {\n\t\tBOOL msgExists = ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE);\n\t\tif( msgExists == 0 ) {\n\t\t\treturn result;\n\t\t}\n\t\tresult = true;\n\t\tif( msg.message != WM_QUIT ) {\n\t\t\tHACCEL hAccelTable = accel_key_.GetHandle(msg.hwnd);\n\t\t\tif( !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) ) {\n\t\t\t\tTranslateMessage(&msg);\n\t\t\t\tDispatchMessage(&msg);\n\t\t\t}\n\t\t} else {\n\t\t\tTVPTerminateCode = (int)msg.wParam;\n\t\t\ttarminate_ = true;\n\t\t}\n\t}\n\treturn result;\n}\nvoid tTVPApplication::ProcessMessages() {\n\tMSG msg = {0};\n\twhile(ProcessMessage(msg));\n}\nvoid tTVPApplication::HandleMessage() {\n\tMSG msg = {0};\n\tif( !ProcessMessage(msg) ) {\n\t\tHandleIdle(msg);\n\t}\n}\nvoid tTVPApplication::HandleIdle(MSG &) {\n\tbool done = true;\n\tif( TVPSystemControl ) {\n\t\tdone = TVPSystemControl->ApplicationIdle();\n\t}\n\tif( done ) ::WaitMessage();\n}\n#endif\nvoid tTVPApplication::SetTitle(const ttstr& caption) {\n\ttitle_ = caption;\n#if 0\n\tif( windows_list_.size() > 0 ) {\n\t\twindows_list_[0]->SetCaption( caption );\n\t}\n\tif( is_attach_console_ ) {\n\t\t::SetConsoleTitle( caption.c_str() );\n\t}\n#endif\n}\n\nvoid tTVPApplication::Terminate()\n{\n\t//::PostQuitMessage(0);\n\ttarminate_ = true;\n\tTVPTerminated = true;\n}\n#if 0\nHWND tTVPApplication::GetMainWindowHandle() const {\n\tif( windows_list_.size() > 0 ) {\n\t\treturn windows_list_[0]->GetHandle();\n\t}\n\treturn INVALID_HANDLE_VALUE;\n}\n\nvoid tTVPApplication::RemoveWindow( TTVPWindowForm* win ) {\n\tstd::vector<class TTVPWindowForm*>::iterator it = std::remove( windows_list_.begin(), windows_list_.end(), win );\n\tif( it != windows_list_.end() ) {\n\t\twindows_list_.erase( it, windows_list_.end() );\n\t}\n}\nvoid tTVPApplication::PostMessageToMainWindow(UINT message, WPARAM wParam, LPARAM lParam) {\n\tif( windows_list_.size() > 0 ) {\n\t\t::PostMessage( windows_list_[0]->GetHandle(), message, wParam, lParam );\n\t}\n}\nvoid tTVPApplication::GetDisableWindowList( std::vector<class TTVPWindowForm*>& win ) {\n\tsize_t count = windows_list_.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\tif( windows_list_[i]->GetEnable() == false ) {\n\t\t\twin.push_back( windows_list_[i] );\n\t\t}\n\t}\n}\nvoid tTVPApplication::GetEnableWindowList( std::vector<class TTVPWindowForm*>& win, class TTVPWindowForm* activeWindow ) {\n\tsize_t count = windows_list_.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\tif( activeWindow != windows_list_[i] && windows_list_[i]->GetEnable() ) {\n\t\t\twin.push_back( windows_list_[i] );\n\t\t}\n\t}\n}\n\nvoid tTVPApplication::DisableWindows() {\n\tsize_t count = windows_list_.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\twindows_list_[i]->SetEnable( false );\n\t}\n}\nvoid tTVPApplication::EnableWindows( const std::vector<TTVPWindowForm*>& win ) {\n\tsize_t count = win.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\twin[i]->SetEnable( true );\n\t}\n\t/*\n\tsize_t count = windows_list_.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\tTTVPWindowForm* win = windows_list_[i];\n\t\tstd::vector<TTVPWindowForm*>::const_iterator f = std::find( ignores.begin(), ignores.end(), win );\n\t\tif( f == ignores.end() ) {\n\t\t\twindows_list_[i]->SetEnable( true );\n\t\t}\n\t}\n\t*/\n}\nvoid tTVPApplication::FreeDirectInputDeviceForWindows() {\n\tsize_t count = windows_list_.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\twindows_list_[i]->FreeDirectInputDevice();\n\t}\n}\n\nvoid tTVPApplication::RegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd) {\n\taccel_key_.AddKey( hWnd, cmd, key, virt );\n}\nvoid tTVPApplication::UnregisterAcceleratorKey(HWND hWnd, short cmd) {\n\taccel_key_.DelKey( hWnd, cmd );\n}\nvoid tTVPApplication::DeleteAcceleratorKeyTable( HWND hWnd ) {\n\taccel_key_.DelTable( hWnd );\n}\n#endif\nvoid tTVPApplication::CheckDigitizer() {\n\t// Windows 7 �ȍ~�ł̂ݗL��\n#if 0\n\tOSVERSIONINFOEX ovi;\n\tovi.dwOSVersionInfoSize = sizeof(ovi);\n\t::GetVersionEx((OSVERSIONINFO*)&ovi);\n\tif( ovi.dwPlatformId == VER_PLATFORM_WIN32_NT &&\n\t\tovi.dwMajorVersion >= 6 && ovi.dwMinorVersion >= 1 ) {\n\n\t\tint value = ::GetSystemMetrics(SM_DIGITIZER);\n\t\tif( value == 0 ) return;\n\n\t\tTVPAddLog( (const tjs_char*)TVPEnableDigitizer );\n\t\tif( value & NID_INTEGRATED_TOUCH ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchIntegratedTouch );\n\t\t}\n\t\tif( value & NID_EXTERNAL_TOUCH ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchExternalTouch );\n\t\t}\n\t\tif( value & NID_INTEGRATED_PEN ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchIntegratedPen );\n\t\t}\n\t\tif( value & NID_EXTERNAL_PEN ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchExternalPen );\n\t\t}\n\t\tif( value & NID_MULTI_INPUT ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchMultiInput );\n\t\t}\n\t\tif( value & NID_READY ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPTouchReady );\n\t\t}\n\t}\n#endif\n}\n\nvoid tTVPApplication::PostUserMessage(const std::function<void()> &func, void* host, int msg)\n{\n\tstd::lock_guard<std::mutex> cs(m_msgQueueLock);\n\tm_lstUserMsg.emplace_back(host, msg, func);\n}\n\nvoid tTVPApplication::FilterUserMessage(const std::function<void(std::vector<std::tuple<void*, int, tMsg> > &)> &func)\n{\n\tstd::lock_guard<std::mutex> cs(m_msgQueueLock);\n\tfunc(m_lstUserMsg);\n}\n\nvoid tTVPApplication::OnActivate()\n{\n\tapplication_activating_ = true;\n\tif (!_project_startup) return;\n\n//\tTVPRestoreFullScreenWindowAtActivation();\n\tTVPResetVolumeToAllSoundBuffer();\n\tTVPUnlockSoundMixer();\n\n\t// trigger System.onActivate event\n\tTVPPostApplicationActivateEvent();\n\tfor (auto & it : m_activeEvents) {\n\t\tit.second(it.first, eTVPActiveEvent::onActive);\n\t}\n}\nvoid tTVPApplication::OnDeactivate(  )\n{\n\tapplication_activating_ = false;\n\tif (!_project_startup) return;\n\n//\tTVPMinimizeFullScreenWindowAtInactivation();\n\t\n\t// fire compact event\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_DEACTIVATE);\n\n\t// set sound volume\n\tTVPResetVolumeToAllSoundBuffer();\n\tTVPLockSoundMixer();\n\n\t// trigger System.onDeactivate event\n\tTVPPostApplicationDeactivateEvent();\n\tfor (auto & it : m_activeEvents) {\n\t\tit.second(it.first, eTVPActiveEvent::onDeactive);\n\t}\n}\n\nvoid tTVPApplication::OnExit()\n{\n\tTVPUninitScriptEngine();\n\n\tif (TVPSystemControl) delete TVPSystemControl;\n\tTVPSystemControl = NULL;\n\n\tCloseConsole();\n}\n\nvoid tTVPApplication::OnLowMemory()\n{\n\tif (!_project_startup) return;\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX);\n}\n\nbool tTVPApplication::GetNotMinimizing() const\n{\n\treturn !application_activating_;\n#if 0\n\tHWND hWnd = GetMainWindowHandle();\n\tif( hWnd != INVALID_HANDLE_VALUE && hWnd != NULL ) {\n\t\treturn ::IsIconic( hWnd ) == 0;\n\t}\n\treturn true; // ���C�����Ȃ����͍ŏ�������Ă���Ƃ݂Ȃ�\n#endif\n}\n#if 0\nvoid tTVPApplication::OnActiveAnyWindow() {\n\tif( modal_window_stack_.empty() != true ) {\n\t\ttTVPWindow* win = modal_window_stack_.top();\n\t\tif( win->GetVisible() && win->GetEnable() ) {\n\t\t\twin->BringToFront();\n\t\t}\n\t}\n}\nvoid tTVPApplication::ModalFinished() {\n\tmodal_window_stack_.pop();\n\tif( modal_window_stack_.empty() != true ) {\n\t\ttTVPWindow* win = modal_window_stack_.top();\n\t\tif( win->GetVisible() && win->GetEnable() ) {\n\t\t\twin->BringToFront();\n\t\t}\n\t}\n}\n#endif\nvoid tTVPApplication::LoadImageRequest( class iTJSDispatch2 *owner, class tTJSNI_Bitmap* bmp, const ttstr &name ) {\n\tif( image_load_thread_ ) {\n\t\timage_load_thread_->LoadRequest( owner, bmp, name );\n\t}\n}\n\nvoid tTVPApplication::RegisterActiveEvent(void *host, const std::function<void(void*, eTVPActiveEvent)>& func/*empty = unregister*/)\n{\n\tif (func)\n\t\tm_activeEvents.emplace(host, func);\n\telse\n\t\tm_activeEvents.erase(host);\n}\n\n#if 0\nstd::vector<std::string>* LoadLinesFromFile( const std::wstring& path ) {\n\tFILE *fp = NULL;\n\t_wfopen_s( &fp, path.c_str(), L\"r\");\n    if( fp == NULL ) {\n\t\treturn NULL;\n    }\n\tchar buff[1024];\n\tstd::vector<std::string>* ret = new std::vector<std::string>();\n    while( fgets(buff, 1024, fp) != NULL ) {\n\t\tret->push_back( std::string(buff) );\n    }\n    fclose(fp);\n\treturn ret;\n}\n\nvoid TVPRegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd) {\n\tif( Application ) Application->RegisterAcceleratorKey( hWnd, virt, key, cmd );\n}\nvoid TVPUnregisterAcceleratorKey(HWND hWnd, short cmd) {\n\tif( Application ) Application->UnregisterAcceleratorKey( hWnd, cmd );\n}\nvoid TVPDeleteAcceleratorKeyTable( HWND hWnd ) {\n\tif( Application ) Application->DeleteAcceleratorKeyTable( hWnd );\n}\n#endif\n\nvoid TVPInitWindowOptions() {\n\t;\n}\n\nstd::string ExtractFileDir(const std::string & FileName) {\n\treturn av_dirname((char*)FileName.c_str());\n}\n\nunsigned long ColorToRGB(unsigned int col)\n{\n\t// 0xBBGGRR\n\tswitch (col) {\n\tcase clScrollBar:\n\t\treturn 0xc8c8c8;\n\tcase clBackground:\n\t\treturn 0;\n\tcase clActiveCaption:\n\t\treturn 0xd1b499;\n\tcase clInactiveCaption:\n\t\treturn 0xdbcdbf;\n\tcase clMenu:\n\t\treturn 0xf0f0f0;\n\tcase clWindow:\n\t\treturn 0xffffff;\n\tcase clWindowFrame:\n\t\treturn 0x646464;\n\tcase clMenuText:\n\t\treturn 0;\n\tcase clWindowText:\n\t\treturn 0;\n\tcase clCaptionText:\n\t\treturn 0;\n\tcase clActiveBorder:\n\t\treturn 0xb4b4b4;\n\tcase clInactiveBorder:\n\t\treturn 0xfcf7f4;\n\tcase clAppWorkSpace:\n\t\treturn 0xababab;\n\tcase clHighlight:\n\t\treturn 0xff9933;\n\tcase clHighlightText:\n\t\treturn 0xffffff;\n\tcase clBtnFace:\n\t\treturn 0xf0f0f0;\n\tcase clBtnShadow:\n\t\treturn 0xa0a0a0;\n\tcase clGrayText:\n\t\treturn 0x6d6d6d;\n\tcase clBtnText:\n\t\treturn 0;\n\tcase clInactiveCaptionText:\n\t\treturn 0x544e43;\n\tcase clBtnHighlight:\n\t\treturn 0xffffff;\n\tcase cl3DDkShadow:\n\t\treturn 0x696969;\n\tcase cl3DLight:\n\t\treturn 0xe3e3e3;\n\tcase clInfoText:\n\t\treturn 0;\n\tcase clInfoBk:\n\t\treturn 0xe1ffff;\n\tcase clUnknown:\n\t\treturn 0;\n\tcase clHotLight:\n\t\treturn 0xcc6600;\n\tcase clGradientActiveCaption:\n\t\treturn 0xead1b9;\n\tcase clGradientInactiveCaption:\n\t\treturn 0xf2e4d7;\n\tcase clMenuLight:\n\t\treturn 0xff9933;\n\tcase clMenuBar:\n\t\treturn 0xf0f0f0;\n\tdefault:\n\t\treturn col & 0xFFFFFF;\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/Application.h",
    "content": "\n#ifndef __T_APPLICATION_H__\n#define __T_APPLICATION_H__\n\n#include \"tjsVariant.h\"\n#include \"tjsString.h\"\n#include <vector>\n#include <functional>\n#include <mutex>\n#include <tuple>\n#include <map>\n\nttstr ExePath();\n\n// ʂ̂悢@ɕύXǂ\nextern int _argc;\nextern char ** _argv;\n\nenum {\n\tmrOk,\n\tmrAbort,\n\tmrCancel,\n};\n\nenum {\n  mtWarning = /*MB_ICONWARNING*/0x00000030L,\n  mtError = /*MB_ICONERROR*/0x00000010L,\n  mtInformation = /*MB_ICONINFORMATION*/0x00000040L,\n  mtConfirmation = /*MB_ICONQUESTION*/0x00000020L,\n  mtStop = /*MB_ICONSTOP*/0x00000010L,\n  mtCustom = 0\n};\nenum {\n\tmbOK = /*MB_OK*/0x00000000L,\n};\nenum class eTVPActiveEvent {\n\tonActive,\n\tonDeactive,\n};\n#if 0\nclass AcceleratorKey {\n\tHACCEL hAccel_;\n\tACCEL* keys_;\n\tint key_count_;\n\npublic:\n\tAcceleratorKey();\n\t~AcceleratorKey();\n\tvoid AddKey( WORD id, WORD key, BYTE virt );\n\tvoid DelKey( WORD id );\n\tHACCEL GetHandle() { return hAccel_; }\n};\nclass AcceleratorKeyTable {\n\tstd::map<HWND,AcceleratorKey*> keys_;\n\tHACCEL hAccel_;\n\npublic:\n\tAcceleratorKeyTable();\n\t~AcceleratorKeyTable();\n\tvoid AddKey( HWND hWnd, WORD id, WORD key, BYTE virt );\n\tvoid DelKey( HWND hWnd, WORD id );\n\tvoid DelTable( HWND hWnd );\n\tHACCEL GetHandle(HWND hWnd) {\n\t\tstd::map<HWND,AcceleratorKey*>::iterator i = keys_.find(hWnd);\n\t\tif( i != keys_.end() ) {\n\t\t\treturn i->second->GetHandle();\n\t\t}\n\t\treturn hAccel_;\n\t}\n};\n#endif\nclass tTVPApplication {\n//\tstd::vector<class TTVPWindowForm*> windows_list_;\n\tttstr title_;\n\n\tbool is_attach_console_;\n\tttstr console_title_;\n//\tAcceleratorKeyTable accel_key_;\n\tbool tarminate_;\n\tbool application_activating_;\n\tbool has_map_report_process_;\n\n\tclass tTVPAsyncImageLoader* image_load_thread_;\n#if 0\n\tstd::stack<class tTVPWindow*> modal_window_stack_;\n#endif\nprivate:\n\tvoid CheckConsole();\n\tvoid CloseConsole();\n\tvoid CheckDigitizer();\n\tvoid ShowException( const ttstr& e );\n\tvoid Initialize() {}\n\npublic:\n\ttTVPApplication();\n\t~tTVPApplication();\n\tbool StartApplication(ttstr path);\n\tvoid Run();\n\tvoid ProcessMessages();\n\n\tstatic void PrintConsole(const ttstr &mes, bool important = false);\n\tbool IsAttachConsole() { return is_attach_console_; }\n\n\tbool IsTarminate() const { return tarminate_; }\n\n//\tHWND GetHandle();\n\tbool IsIconic() {\n#if 0\n\t\tHWND hWnd = GetHandle();\n\t\tif( hWnd != INVALID_HANDLE_VALUE ) {\n\t\t\treturn 0 != ::IsIconic(hWnd);\n\t\t}\n#endif\n\t\treturn true; // EBhEȂ\n\t}\n#if 0\n\tvoid Minimize();\n\tvoid Restore();\n\tvoid BringToFront();\n\n\tvoid AddWindow( class TTVPWindowForm* win ) {\n\t\twindows_list_.push_back( win );\n\t}\n\tvoid RemoveWindow( class TTVPWindowForm* win );\n\tunsigned int GetWindowCount() const {\n\t\treturn (unsigned int)windows_list_.size();\n\t}\n\n\tvoid FreeDirectInputDeviceForWindows();\n\n\tbool ProcessMessage( MSG &msg );\n\tvoid ProcessMessages();\n\tvoid HandleMessage();\n\tvoid HandleIdle(MSG &msg);\n#endif\n\tconst ttstr &GetTitle() const { return title_; }\n\tvoid SetTitle( const ttstr& caption );\n#if 0\n\tstatic inline int MessageDlg( const ttstr& string, const ttstr& caption, int type, int button ) {\n\t\treturn ::MessageBox( NULL, string.c_str(), caption.c_str(), type|button  );\n\t}\n#endif\n\tvoid Terminate();\n\tvoid SetHintHidePause( int v ) {}\n\tvoid SetShowHint( bool b ) {}\n\tvoid SetShowMainForm( bool b ) {}\n\n\n//\tHWND GetMainWindowHandle() const;\n\n\tint ArgC;\n\tchar ** ArgV;\n\ttypedef std::function<void()> tMsg;\n\n//\tvoid PostMessageToMainWindow(UINT message, WPARAM wParam, LPARAM lParam);\n\tvoid PostUserMessage(const std::function<void()> &func, void* param1 = nullptr, int param2 = 0);\n\tvoid FilterUserMessage(const std::function<void(std::vector<std::tuple<void*, int, tMsg> > &)> &func);\n\n#if 0\n\tvoid ModalStarted( class tTVPWindow* form ) {\n\t\tmodal_window_stack_.push(form);\n\t}\n\n\tvoid ModalFinished();\n\tvoid OnActiveAnyWindow();\n\tvoid DisableWindows();\n\tvoid EnableWindows( const std::vector<class TTVPWindowForm*>& win );\n\tvoid GetDisableWindowList( std::vector<class TTVPWindowForm*>& win );\n\tvoid GetEnableWindowList( std::vector<class TTVPWindowForm*>& win, class TTVPWindowForm* activeWindow );\n\n\tvoid RegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd);\n\tvoid UnregisterAcceleratorKey(HWND hWnd, short cmd);\n\tvoid DeleteAcceleratorKeyTable( HWND hWnd );\n#endif\n\tvoid OnActivate(  );\n\tvoid OnDeactivate(  );\n\tvoid OnExit();\n\tvoid OnLowMemory();\n\n\tbool GetActivating() const { return application_activating_; }\n\tbool GetNotMinimizing() const;\n\n\t/**\n\t * 摜̔񓯊Ǎݗv\n\t */\n\tvoid LoadImageRequest( class iTJSDispatch2 *owner, class tTJSNI_Bitmap* bmp, const ttstr &name );\n\ttTVPAsyncImageLoader* GetAsyncImageLoader() { return image_load_thread_; }\n\n\tvoid RegisterActiveEvent(void *host, const std::function<void(void*, eTVPActiveEvent)>& func/*empty = unregister*/);\n\nprivate:\n\tstd::mutex m_msgQueueLock;\n\n\tstd::vector<std::tuple<void*, int, tMsg> > m_lstUserMsg;\n\tstd::map<void*, std::function<void(void*, eTVPActiveEvent)> > m_activeEvents;\n};\nstd::vector<std::string>* LoadLinesFromFile( const ttstr& path );\n\n//inline HINSTANCE GetHInstance() { return ((HINSTANCE)GetModuleHandle(0)); }\nextern class tTVPApplication* Application;\n\n\n#endif // __T_APPLICATION_H__\n"
  },
  {
    "path": "src/core/environ/ConfigManager/GlobalConfigManager.cpp",
    "content": "#include \"GlobalConfigManager.h\"\n#include \"tinyxml2/tinyxml2.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"Platform.h\"\n#include \"UtilStreams.h\"\n#include \"LocaleConfigManager.h\"\n\nbool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int len);\nclass XMLMemPrinter : public tinyxml2::XMLPrinter {\n\ttTVPMemoryStream _stream;\n\tchar _buffer[4096];\npublic:\n\tvirtual void Print(const char* format, ...) {\n\t\tva_list param;\n\t\tva_start(param, format);\n\t\tint n = vsnprintf(_buffer, 4096, format, param);\n\t\tva_end(param);\n\t\t_stream.Write(_buffer, n);\n\t}\n\tvoid SaveFile(const std::string &path) {\n\t\tif (!TVPWriteDataToFile(path, _stream.GetInternalBuffer(), _stream.GetSize())) {\n\t\t\tTVPShowSimpleMessageBox(\n\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"cannot_create_preference\"),\n\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"readonly_storage\"));\n\t\t}\n\t}\n};\n\n\nGlobalConfigManager::GlobalConfigManager() {\n\tInitialize();\n}\n\nGlobalConfigManager* GlobalConfigManager::GetInstance() {\n\tstatic GlobalConfigManager instance;\n\treturn &instance;\n}\n\nvoid iSysConfigManager::Initialize() {\n\tAllConfig.clear();\n\tConfigUpdated = false;\n\n\ttinyxml2::XMLDocument doc;\n\n\tFILE *fp = nullptr;\n#ifdef _MSC_VER\n\tfp = _wfopen(ttstr(GetFilePath()).c_str(), TJS_W(\"rb\"));\n#else\n\tfp = fopen(GetFilePath().c_str(), \"rb\");\n#endif\n\n\tif (fp && !doc.LoadFile(fp)) {\n\t\ttinyxml2::XMLElement *rootElement = doc.RootElement();\n\t\tif (rootElement) {\n\t\t\tfor (tinyxml2::XMLElement *item = rootElement->FirstChildElement(\"Item\"); item; item = item->NextSiblingElement(\"Item\")) {\n\t\t\t\tconst char *key = item->Attribute(\"key\");\n\t\t\t\tconst char *val = item->Attribute(\"value\");\n\t\t\t\tif (key && val) {\n\t\t\t\t\tAllConfig[key] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (tinyxml2::XMLElement *item = rootElement->FirstChildElement(\"Custom\"); item; item = item->NextSiblingElement(\"Custom\")) {\n\t\t\t\tconst char *key = item->Attribute(\"key\");\n\t\t\t\tconst char *val = item->Attribute(\"value\");\n\t\t\t\tif (key && val) {\n\t\t\t\t\tCustomArguments.emplace_back(key, val);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (tinyxml2::XMLElement *item = rootElement->FirstChildElement(\"KeyMap\"); item; item = item->NextSiblingElement(\"KeyMap\")) {\n\t\t\t\tint key, val;\n\t\t\t\tif (tinyxml2::XML_SUCCESS == item->QueryIntAttribute(\"key\", &key) &&\n\t\t\t\t\ttinyxml2::XML_SUCCESS == item->QueryIntAttribute(\"value\", &val) &&\n\t\t\t\t\tkey && val) {\n\t\t\t\t\tKeyMap.emplace(key, val);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (fp) fclose(fp);\n}\n\nvoid iSysConfigManager::SaveToFile() {\n\tif (!ConfigUpdated) return;\n\tstd::string filepath = GetFilePath();\n\tif (filepath.empty()) return;\n\ttinyxml2::XMLDocument doc;\n\tdoc.LinkEndChild(doc.NewDeclaration());\n\ttinyxml2::XMLElement *rootElement = doc.NewElement(\"GlobalPreference\");\n\tfor (auto it = AllConfig.begin(); it != AllConfig.end(); ++it) {\n\t\ttinyxml2::XMLElement *item = doc.NewElement(\"Item\");\n\t\titem->SetAttribute(\"key\", it->first.c_str());\n\t\titem->SetAttribute(\"value\", it->second.c_str());\n\t\trootElement->LinkEndChild(item);\n\t}\n\tfor (auto it = CustomArguments.begin(); it != CustomArguments.end(); ++it) {\n\t\ttinyxml2::XMLElement *item = doc.NewElement(\"Custom\");\n\t\titem->SetAttribute(\"key\", it->first.c_str());\n\t\titem->SetAttribute(\"value\", it->second.c_str());\n\t\trootElement->LinkEndChild(item);\n\t}\n\tfor (auto &it : KeyMap) {\n\t\tif (it.first && it.second) {\n\t\t\ttinyxml2::XMLElement *item = doc.NewElement(\"KeyMap\");\n\t\t\titem->SetAttribute(\"key\", it.first);\n\t\t\titem->SetAttribute(\"value\", it.second);\n\t\t\trootElement->LinkEndChild(item);\n\t\t}\n\t}\n\tdoc.LinkEndChild(rootElement);\n\tXMLMemPrinter stream;\n\tdoc.Print(&stream);\n\tstream.SaveFile(GetFilePath());\n\tConfigUpdated = false;\n}\n\nbool iSysConfigManager::IsValueExist(const std::string &name)\n{\n\tauto it = AllConfig.find(name);\n\treturn it != AllConfig.end();\n}\n\nstd::string GlobalConfigManager::GetFilePath() {\n\treturn TVPGetInternalPreferencePath() + \"GlobalPreference.xml\";\n}\n\ntemplate<>\nbool iSysConfigManager::GetValue<bool>(const std::string &name, const bool& defVal) {\n\treturn !!GetValue<int>(name, defVal);\n}\n\ntemplate<>\nint iSysConfigManager::GetValue<int>(const std::string &name, const int& defVal) {\n\tauto it = AllConfig.find(name);\n\tif (it == AllConfig.end()) {\n\t\tSetValueInt(name, defVal);\n\t\treturn defVal;\n\t}\n\treturn atoi(it->second.c_str());\n}\n\ntemplate<>\nfloat iSysConfigManager::GetValue<float>(const std::string &name, const float& defVal) {\n\tauto it = AllConfig.find(name);\n\tif (it == AllConfig.end()) {\n\t\tSetValueFloat(name, defVal);\n\t\treturn defVal;\n\t}\n\treturn atof(it->second.c_str());\n}\n\ntemplate<>\nstd::string iSysConfigManager::GetValue<std::string>(const std::string &name, const std::string& defVal) {\n\tauto it = AllConfig.find(name);\n\tif (it == AllConfig.end()) {\n\t\tSetValue(name, defVal);\n\t\treturn defVal;\n\t}\n\treturn it->second;\n}\n\nvoid iSysConfigManager::SetValueInt(const std::string &name, int val) {\n\tchar buf[16];\n\tsprintf(buf, \"%d\", val);\n\tAllConfig[name] = buf;\n\tConfigUpdated = true;\n}\n\nvoid iSysConfigManager::SetValueFloat(const std::string &name, float val) {\n\tchar buf[24];\n\tsprintf(buf, \"%g\", val);\n\tAllConfig[name] = buf;\n\tConfigUpdated = true;\n}\n\nvoid iSysConfigManager::SetValue(const std::string &name, const std::string & val) {\n\tAllConfig[name] = val;\n\tConfigUpdated = true;\n}\n\nvoid iSysConfigManager::SetKeyMap(int k/* 0 means remove */, int v)\n{\n\tif (v == 0) {\n\t\tKeyMap.erase(k);\n\t} else {\n\t\tKeyMap[k] = v;\n\t}\n}\n\nstd::vector<std::string> iSysConfigManager::GetCustomArgumentsForPush() {\n\tstd::vector<std::string> ret;\n\tfor (auto arg : CustomArguments) {\n\t\tstd::string line(\"-\");\n\t\tline += arg.first;\n\t\tline += \"=\";\n\t\tline += arg.second;\n\t\tret.emplace_back(line);\n\t}\n\treturn ret;\n}\n\n"
  },
  {
    "path": "src/core/environ/ConfigManager/GlobalConfigManager.h",
    "content": "#pragma once\n#include <unordered_map>\n#include <string>\n#include <vector>\n#include <map>\n\nclass iSysConfigManager {\nprotected:\n\tstd::unordered_map<std::string, std::string> AllConfig;\n\tstd::vector<std::pair<std::string, std::string> > CustomArguments;\n\tstd::map<int, int> KeyMap;\n\n\tbool ConfigUpdated;\n\n\tvirtual std::string GetFilePath() = 0;\n\n\tvoid Initialize();\n\npublic:\n\tvoid SaveToFile();\n\n\tbool IsValueExist(const std::string &name);\n\n\ttemplate<typename T>\n\tT GetValue(const std::string &name, const T& defVal);\n\n\tvoid SetValueInt(const std::string &name, int val);\n\tvoid SetValueFloat(const std::string &name, float val);\n\tvoid SetValue(const std::string &name, const std::string & val);\n\n\tstd::vector<std::pair<std::string, std::string> > &GetCustomArgumentsForModify() {\n\t\tConfigUpdated = true;\n\t\treturn CustomArguments;\n\t}\n\n\tconst std::map<int, int>& GetKeyMap() { return KeyMap; }\n\tvoid SetKeyMap(int k, int v/* 0 means remove */);\n\n\tconst std::vector<std::pair<std::string, std::string> > &GetCustomArguments() const { return CustomArguments; }\n\n\tstd::vector<std::string> GetCustomArgumentsForPush();\n};\n\ntemplate<> bool iSysConfigManager::GetValue<bool>(const std::string &name, const bool& defVal);\ntemplate<> int iSysConfigManager::GetValue<int>(const std::string &name, const int& defVal);\ntemplate<> float iSysConfigManager::GetValue<float>(const std::string &name, const float& defVal);\ntemplate<> std::string iSysConfigManager::GetValue<std::string>(const std::string &name, const std::string& defVal);\n\nclass GlobalConfigManager : public iSysConfigManager {\n\n\tvirtual std::string GetFilePath() override;\n\n\tGlobalConfigManager();\n\npublic:\n\tstatic GlobalConfigManager* GetInstance();\n};"
  },
  {
    "path": "src/core/environ/ConfigManager/IndividualConfigManager.cpp",
    "content": "#include \"IndividualConfigManager.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"LocaleConfigManager.h\"\n#include \"Platform.h\"\n\n#define FILENAME \"Kirikiroid2Preference.xml\"\n\nIndividualConfigManager* IndividualConfigManager::GetInstance() {\n\tstatic IndividualConfigManager instance;\n\treturn &instance;\n}\n\nstd::string IndividualConfigManager::GetFilePath() {\n\treturn CurrentPath;\n}\n\nvoid IndividualConfigManager::Clear()\n{\n\tAllConfig.clear();\n\tCustomArguments.clear();\n\tConfigUpdated = false;\n\tCurrentPath.clear();\n}\n\nbool IndividualConfigManager::CheckExistAt(const std::string &folder) {\n\tstd::string fullpath = folder + \"/\" FILENAME;\n\treturn cocos2d::FileUtils::getInstance()->isFileExist(fullpath);\n}\n\nbool IndividualConfigManager::CreatePreferenceAt(const std::string &folder) {\n\tstd::string fullpath = folder + \"/\" FILENAME;\n// \tFILE *fp =\n// #ifdef _MSC_VER\n// \t\t_wfopen(ttstr(fullpath).c_str(), TJS_W(\"w\"));\n// #else\n// \t\tfopen(fullpath.c_str(), \"w\");\n// #endif\n\tClear();\n// \tif (!fp) {\n// \t\tTVPShowSimpleMessageBox(\n// \t\t\tLocaleConfigManager::GetInstance()->GetText(\"cannot_create_preference\"),\n// \t\t\tLocaleConfigManager::GetInstance()->GetText(\"readonly_storage\"));\n// \t\treturn false;\n// \t}\n\tCurrentPath = fullpath;\n\treturn true;\n}\n\nbool IndividualConfigManager::UsePreferenceAt(const std::string &folder)\n{\n\tstd::string fullpath = folder + \"/\" FILENAME;\n\tif (CurrentPath == fullpath) return true;\n\tClear();\n\tif (!cocos2d::FileUtils::getInstance()->isFileExist(fullpath)) return false;\n\tCurrentPath = fullpath;\n\tInitialize();\n\treturn true;\n}\n\ntemplate<>\nbool IndividualConfigManager::GetValue<bool>(const std::string &name, const bool &defVal /*= false*/)\n{\n\treturn inherit::GetValue<bool>(name, GlobalConfigManager::GetInstance()->GetValue<bool>(name, defVal));\n}\ntemplate<>\nint IndividualConfigManager::GetValue<int>(const std::string &name, const int &defVal /*= 0*/)\n{\n\treturn inherit::GetValue<int>(name, GlobalConfigManager::GetInstance()->GetValue<int>(name, defVal));\n}\ntemplate<>\nfloat IndividualConfigManager::GetValue<float>(const std::string &name, const float &defVal /*= 0*/)\n{\n\treturn inherit::GetValue<float>(name, GlobalConfigManager::GetInstance()->GetValue<float>(name, defVal));\n}\ntemplate<>\nstd::string IndividualConfigManager::GetValue<std::string>(const std::string &name, const std::string &defVal /*= \"\"*/)\n{\n\treturn inherit::GetValue<std::string>(name, GlobalConfigManager::GetInstance()->GetValue<std::string>(name, defVal));\n}\n\nstd::vector<std::string> IndividualConfigManager::GetCustomArgumentsForPush()\n{\n\tif (CustomArguments.empty()) {\n\t\treturn GlobalConfigManager::GetInstance()->GetCustomArgumentsForPush();\n\t}\n\treturn inherit::GetCustomArgumentsForPush();\n}\n"
  },
  {
    "path": "src/core/environ/ConfigManager/IndividualConfigManager.h",
    "content": "#pragma once\n#include <unordered_map>\n#include <string>\n#include <vector>\n#include \"GlobalConfigManager.h\"\n\nclass IndividualConfigManager : public iSysConfigManager {\n\ttypedef iSysConfigManager inherit;\n\n\tvirtual std::string GetFilePath() override;\n\n\tvoid Clear();\n\n\tstd::string CurrentPath;\n\npublic:\n\tstatic IndividualConfigManager* GetInstance();\n\tstatic bool CheckExistAt(const std::string &folder);\n\tbool CreatePreferenceAt(const std::string &folder);\n\tbool UsePreferenceAt(const std::string &folder);\n\n\ttemplate<typename T>\n\tT GetValue(const std::string &name, const T& defVal);\n\n\tstd::vector<std::string> GetCustomArgumentsForPush();\n};\n\ntemplate<> bool IndividualConfigManager::GetValue<bool>(const std::string &name, const bool& defVal);\ntemplate<> int IndividualConfigManager::GetValue<int>(const std::string &name, const int& defVal);\ntemplate<> float IndividualConfigManager::GetValue<float>(const std::string &name, const float& defVal);\ntemplate<> std::string IndividualConfigManager::GetValue<std::string>(const std::string &name, const std::string& defVal);"
  },
  {
    "path": "src/core/environ/ConfigManager/LocaleConfigManager.cpp",
    "content": "#include \"LocaleConfigManager.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"GlobalConfigManager.h\"\n#include \"tinyxml2/tinyxml2.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIButton.h\"\n\nLocaleConfigManager::LocaleConfigManager() {\n\n}\n\nstd::string LocaleConfigManager::GetFilePath() {\n\tstd::string pathprefix = \"locale/\"; // constant file in app package\n\tstd::string fullpath = pathprefix + currentLangCode + \".xml\"; // exp. \"local/en_us.xml\"\n\tif (!cocos2d::FileUtils::getInstance()->isFileExist(fullpath)) {\n\t\tcurrentLangCode = \"en_us\"; // restore to default language config(must exist)\n\t\treturn GetFilePath();\n\t}\n\treturn cocos2d::FileUtils::getInstance()->fullPathForFilename(fullpath);\n}\n\nLocaleConfigManager* LocaleConfigManager::GetInstance() {\n\tstatic LocaleConfigManager instance;\n\treturn &instance;\n}\n\nconst std::string &LocaleConfigManager::GetText(const std::string &tid) {\n\tauto it = AllConfig.find(tid);\n\tif (it == AllConfig.end()) {\n\t\tAllConfig[tid] = tid;\n\t\treturn AllConfig[tid];\n\t}\n\treturn it->second;\n}\n\nvoid LocaleConfigManager::Initialize(const std::string &sysLang) {\n\t// override by global configured lang\n\tcurrentLangCode = GlobalConfigManager::GetInstance()->GetValue<std::string>(\"user_language\", \"\");\n\tif (currentLangCode.empty()) currentLangCode = sysLang;\n\tAllConfig.clear();\n\ttinyxml2::XMLDocument doc;\n\tstd::string xmlData = cocos2d::FileUtils::getInstance()->getStringFromFile(GetFilePath());\n\tbool _writeBOM = false;\n\tconst char* p = xmlData.c_str();\n\tp = tinyxml2::XMLUtil::ReadBOM(p, &_writeBOM);\n\tdoc.ParseDeep((char*)p, nullptr);\n\ttinyxml2::XMLElement *rootElement = doc.RootElement();\n\tif (rootElement) {\n\t\tfor (tinyxml2::XMLElement *item = rootElement->FirstChildElement(); item; item = item->NextSiblingElement()) {\n\t\t\tconst char *key = item->Attribute(\"id\");\n\t\t\tconst char *val = item->Attribute(\"text\");\n\t\t\tif (key && val) {\n\t\t\t\tAllConfig[key] = val;\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool LocaleConfigManager::initText(cocos2d::ui::Text *ctrl) {\n\tif (!ctrl) return false;\n\treturn initText(ctrl, ctrl->getString());\n}\n\nbool LocaleConfigManager::initText(cocos2d::ui::Button *ctrl)\n{\n\tif (!ctrl) return false;\n\treturn initText(ctrl, ctrl->getTitleText());\n}\n\nbool LocaleConfigManager::initText(cocos2d::ui::Text *ctrl, const std::string &tid) {\n\tif (!ctrl) return false;\n\n\tstd::string txt = GetText(tid);\n\tif (txt.empty()) {\n\t\tctrl->setString(tid);\n\t\tctrl->setColor(cocos2d::Color3B::RED);\n\t\treturn false;\n\t}\n\n\tctrl->setString(txt);\n\treturn true;\n}\n\nbool LocaleConfigManager::initText(cocos2d::ui::Button *ctrl, const std::string &tid) {\n\tif (!ctrl) return false;\n\n\tstd::string txt = GetText(tid);\n\tif (txt.empty()) {\n\t\tctrl->setTitleText(tid);\n\t\tctrl->setTitleColor(cocos2d::Color3B::RED);\n\t\treturn false;\n\t}\n\n\tctrl->setTitleText(txt);\n\treturn true;\n}\n\n"
  },
  {
    "path": "src/core/environ/ConfigManager/LocaleConfigManager.h",
    "content": "// multi language config mainly for ui\n#pragma once\n#include <unordered_map>\n#include <string>\n#include <vector>\n\nnamespace cocos2d {\n\tnamespace ui {\n\t\tclass Text;\n\t\tclass Button;\n\t}\n}\n\nclass LocaleConfigManager {\n\n\tstd::unordered_map<std::string, std::string> AllConfig; // tid->text in utf8\n\n\tbool ConfigUpdated;\n\n\tLocaleConfigManager();\n\n\tstd::string GetFilePath();\n\npublic:\n\tstatic LocaleConfigManager* GetInstance();\n\n\tvoid Initialize(const std::string &sysLang);\n\n\tconst std::string &GetText(const std::string &tid); // in utf8\n\n\tbool initText(cocos2d::ui::Text *ctrl);\n\tbool initText(cocos2d::ui::Button *ctrl);\n\tbool initText(cocos2d::ui::Text *ctrl, const std::string &tid);\n\tbool initText(cocos2d::ui::Button *ctrl, const std::string &tid);\n\nprivate:\n\n\tstd::string currentLangCode;\n};"
  },
  {
    "path": "src/core/environ/DetectCPU.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CPU idetification / features detection routine\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"cpu_types.h\"\n#include \"DebugIntf.h\"\n#include \"SysInitIntf.h\"\n\n#include \"ThreadIntf.h\"\n#include \"Exception.h\"\n\n/*\n\tNote: CPU clock measuring routine is in EmergencyExit.cpp, reusing\n\thot-key watching thread.\n*/\n\n//---------------------------------------------------------------------------\nextern \"C\"\n{\n\ttjs_uint32 TVPCPUType = 0; // CPU type\n    tjs_uint32 TVPCPUFeatures\t=\t0;\n}\n\nstatic bool TVPCPUChecked = false;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetCPUTypeForOne\n//---------------------------------------------------------------------------\nstatic void TVPGetCPUTypeForOne()\n{\n\ttry\n\t{\n        TVPCPUFeatures = 0;\n\n\t\t//TVPCheckCPU(); // in detect_cpu.nas\n\t}\n\tcatch(.../*EXCEPTION_EXECUTE_HANDLER*/)\n\t{\n\t\t// exception had been ocured\n\t\tthrow Exception(\"CPU check failure.\");\n\t}\n\n\t// check OSFXSR\n// \tif(TVPCPUFeatures & TVP_CPU_HAS_SSE)\n// \t{\n// \t\t__try\n// \t\t{\n// \t\t\t__emit__(0x0f, 0x57, 0xc0); // xorps xmm0, xmm0   (SSE)\n// \t\t}\n// \t\t__except(EXCEPTION_EXECUTE_HANDLER)\n// \t\t{\n// \t\t\t// exception had been ocured\n// \t\t\t// execution of 'xorps' is failed (XMM registers not available)\n// \t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE;\n// \t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE2;\n// \t\t}\n// \t}\n\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic ttstr TVPDumpCPUFeatures(tjs_uint32 features)\n{\n\tttstr ret;\n// #define TVP_DUMP_CPU(x, n) { ret += TJS_W(\"  \") TJS_W(n);  \\\n// \tif(features & x) ret += TJS_W(\":yes\"); else ret += TJS_W(\":no\"); }\n// \n// \tTVP_DUMP_CPU(TVP_CPU_HAS_FPU, \"FPU\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_MMX, \"MMX\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_3DN, \"3DN\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_SSE, \"SSE\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_CMOV, \"CMOVcc\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_E3DN, \"E3DN\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_EMMX, \"EMMX\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_SSE2, \"SSE2\");\n// \tTVP_DUMP_CPU(TVP_CPU_HAS_TSC, \"TSC\");\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nstatic ttstr TVPDumpCPUInfo(tjs_int cpu_num)\n{\n\t// dump detected cpu type\n\tttstr features(TJS_W(\"(info) CPU #\") + ttstr(cpu_num) +\n\t\tTJS_W(\" : \"));\n\n\tfeatures += TVPDumpCPUFeatures(TVPCPUFeatures);\n\n\ttjs_uint32 vendor = TVPCPUFeatures & TVP_CPU_VENDOR_MASK;\n\n// #undef TVP_DUMP_CPU\n// #define TVP_DUMP_CPU(x, n) { \\\n// \tif(vendor == x) features += TJS_W(\"  \") TJS_W(n); }\n// \n// \tTVP_DUMP_CPU(TVP_CPU_IS_INTEL, \"Intel\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_AMD, \"AMD\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_IDT, \"IDT\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_CYRIX, \"Cyrix\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_NEXGEN, \"NexGen\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_RISE, \"Rise\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_UMC, \"UMC\");\n// \tTVP_DUMP_CPU(TVP_CPU_IS_TRANSMETA, \"Transmeta\");\n// \n// \tTVP_DUMP_CPU(TVP_CPU_IS_UNKNOWN, \"Unknown\");\n// \n// #undef TVP_DUMP_CPU\n\n//\tfeatures += TJS_W(\"(\") + ttstr((const tjs_nchar *)TVPCPUVendor) + TJS_W(\")\");\n\n// \tif(TVPCPUName[0]!=0)\n// \t\tfeatures += TJS_W(\" [\") + ttstr((const tjs_nchar *)TVPCPUName) + TJS_W(\"]\");\n\n// \tfeatures += TJS_W(\"  CPUID(1)/EAX=\") + TJSInt32ToHex(TVPCPUID1_EAX);\n// \tfeatures += TJS_W(\" CPUID(1)/EBX=\") + TJSInt32ToHex(TVPCPUID1_EBX);\n\n\tTVPAddImportantLog(features);\n\n// \tif(((TVPCPUID1_EAX >> 8) & 0x0f) <= 4)\n// \t\tthrow Exception(\"CPU check failure: CPU family 4 or lesser is not supported\\r\\n\"+\n// \t\tfeatures.AsAnsiString());\n\n\treturn features;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDetectCPU\n//---------------------------------------------------------------------------\nstatic void TVPDisableCPU(tjs_uint32 featurebit, const tjs_char *name)\n{\n#if 0\n\ttTJSVariant val;\n\tttstr str;\n\tif(TVPGetCommandLine(name, &val))\n\t{\n\t\tstr = val;\n\t\tif(str == TJS_W(\"no\"))\n\t\t\tTVPCPUType &=~ featurebit;\n\t\telse if(str == TJS_W(\"force\"))\n\t\t\tTVPCPUType |= featurebit;\n\t}\n#endif\n}\n\n#if defined(WIN32) || defined(__ANDROID__)\n#include <cpu-features.h>\n#endif\n//---------------------------------------------------------------------------\nvoid TVPDetectCPU()\n{\n    if(TVPCPUChecked) return;\n    TVPCPUChecked = true;\n\n\t//if(SDL_HasSSE2()) TVPCPUFeatures |= TVP_CPU_HAS_SSE2 | TVP_CPU_HAS_EMMX;\n\t//if(SDL_HasSSE())  TVPCPUFeatures |= TVP_CPU_HAS_SSE;\n\t//if(SDL_HasMMX())  TVPCPUFeatures |= TVP_CPU_HAS_MMX;\n\t//if(SDL_HasSSE2()) TVPCPUFeatures |= TVP_CPU_HAS_SSE2;\n#if defined(__ANDROID__) || defined(WIN32)\n    //if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) {\n        TVPCPUFeatures |= TVP_CPU_FAMILY_ARM; // must be arm\n#if defined(__arm64__) || defined(__aarch64__) || defined(__LP64__)\n\t\tTVPCPUFeatures |= TVP_CPU_HAS_NEON; // aka. asimd\n#else\n        if((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {\n            TVPCPUFeatures |= TVP_CPU_HAS_NEON;\n        }\n#endif\n    //}\n#endif\n#ifdef __APPLE__\n    // must be iOS\n    TVPCPUFeatures |= TVP_CPU_FAMILY_ARM | TVP_CPU_HAS_NEON;\n#endif\n\n    tjs_uint32 features = 0;\n    features =  (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n    TVPCPUType &= ~ TVP_CPU_FEATURE_MASK;\n    TVPCPUType |= features;\n\n// \t// get process affinity mask\n// \tDWORD pam = 1;\n// \tHANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());\n// \tif(hp)\n// \t{\n// \t\tDWORD sam = 1;\n// \t\tGetProcessAffinityMask(hp, &pam, &sam);\n// \t\tCloseHandle(hp);\n// \t}\n// \n// \t// for each CPU...\n// \tttstr cpuinfo;\n// \tbool first = true;\n// \tfor(tjs_int cpu = 0; cpu < 32; cpu++)\n// \t{\n// \t\tif(pam & (1<<cpu))\n// \t\t{\n// \t\t\ttTVPCPUCheckThread * thread = new tTVPCPUCheckThread(1<<cpu);\n// \t\t\tthread->WaitEnd();\n// \t\t\tbool succeeded = thread->GetSucceeded();\n// \t\t\tdelete thread;\n// \t\t\tif(!succeeded) throw Exception(\"CPU check failure\");\n// \t\t\tcpuinfo += TVPDumpCPUInfo(cpu) + TJS_W(\"\\r\\n\");\n// \n// \t\t\t// mask features\n// \t\t\tif(first)\n// \t\t\t{\n// \t\t\t\tfeatures =  (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n// \t\t\t\tTVPCPUType = TVPCPUFeatures;\n// \t\t\t\tfirst = false;\n// \t\t\t}\n// \t\t\telse\n// \t\t\t{\n// \t\t\t\tfeatures &= (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n// \t\t\t}\n// \t\t}\n// \t}\n\n\t// Disable or enable cpu features by option\n// \tTVPDisableCPU(TVP_CPU_HAS_MMX,  TJS_W(\"-cpummx\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_3DN,  TJS_W(\"-cpu3dn\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_SSE,  TJS_W(\"-cpusse\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_CMOV, TJS_W(\"-cpucmov\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_E3DN, TJS_W(\"-cpue3dn\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_EMMX, TJS_W(\"-cpuemmx\"));\n// \tTVPDisableCPU(TVP_CPU_HAS_SSE2, TJS_W(\"-cpusse2\"));\n \tTVPDisableCPU(TVP_CPU_HAS_NEON, TJS_W(\"-cpuneon\"));\n\n// \tif(TVPCPUType == 0)\n// \t\tthrow Exception(\"CPU check failure: Not supported CPU\\r\\n\" +\n// \t\tcpuinfo.AsAnsiString());\n// \n// \tTVPAddImportantLog(TJS_W(\"(info) finally detected CPU features : \") +\n//     \tTVPDumpCPUFeatures(TVPCPUType));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// jpeg and png loader support functions\n//---------------------------------------------------------------------------\nunsigned long MMXReady = 0;\nextern \"C\"\n{\n\tvoid CheckMMX(void)\n\t{\n\t\tTVPDetectCPU();\n\t\tMMXReady = TVPCPUType & TVP_CPU_HAS_MMX;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetCPUType\n//---------------------------------------------------------------------------\ntjs_uint32 TVPGetCPUType()\n{\n\tTVPDetectCPU();\n\treturn TVPCPUType;\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/environ/DetectCPU.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CPU idetification / features detection routine\n//---------------------------------------------------------------------------\n#ifndef DetectCPUH\n#define DetectCPUH\n//---------------------------------------------------------------------------\nextern \"C\"\n{\n\textern tjs_uint32 TVPCPUType;\n}\n\nextern void TVPDetectCPU();\nTJS_EXP_FUNC_DEF(tjs_uint32, TVPGetCPUType, ());\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/environ/DumpSend.cpp",
    "content": "#include \"network/HttpRequest.h\"\n#include \"network/HttpClient.h\"\n#include \"base/CCDirector.h\"\n#include \"base/CCScheduler.h\"\n#include \"base/base64.h\"\n#include \"Platform.h\"\n#include \"SysInitIntf.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"StorageImpl.h\"\n#include \"minizip/ioapi.h\"\n#include \"minizip/zip.h\"\n#include <sstream>\n#include <iomanip>\n#include <condition_variable>\n\nstatic void ClearDumps(const std::string &dumpdir, std::vector<std::string> &allDumps) {\n\tfor (const std::string &path : allDumps) {\n\t\tremove((dumpdir + \"/\" + path).c_str());\n\t}\n\t//allDumps.clear();\n}\n\nstatic std::map<std::string, tTVPMemoryStream*> _inmemFiles;\n\nstruct zlib_inmem_func64 : public zlib_filefunc64_def {\n\tstatic voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) {\n\t\ttTVPMemoryStream *str = new tTVPMemoryStream;\n\t\t_inmemFiles[(const char*)filename] = str;\n\t\treturn str;\n\t}\n\t\n\tstatic uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) {\n\t\ttTVPMemoryStream* str = (tTVPMemoryStream*)stream;\n\t\treturn str->Read(buf, size);\n\t}\n\n\tstatic uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) {\n\t\ttTVPMemoryStream* str = (tTVPMemoryStream*)stream;\n\t\treturn str->Write(buf, size);\n\t}\n\n\tstatic ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) {\n\t\ttTVPMemoryStream* str = (tTVPMemoryStream*)stream;\n\t\treturn str->GetPosition();\n\t}\n\n\tstatic long ZCALLBACK fseek64_file_func(voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)\n\t{\n\t\tint fseek_origin = TJS_BS_SEEK_SET;\n\t\tswitch (origin)\n\t\t{\n\t\tcase ZLIB_FILEFUNC_SEEK_CUR:\n\t\t\tfseek_origin = TJS_BS_SEEK_CUR;\n\t\t\tbreak;\n\t\tcase ZLIB_FILEFUNC_SEEK_END:\n\t\t\tfseek_origin = TJS_BS_SEEK_END;\n\t\t\tbreak;\n\t\tcase ZLIB_FILEFUNC_SEEK_SET:\n\t\t\tfseek_origin = TJS_BS_SEEK_SET;\n\t\t\tbreak;\n\t\tdefault: return -1;\n\t\t}\n\t\ttTVPMemoryStream* str = (tTVPMemoryStream*)stream;\n\t\tstr->Seek(offset, fseek_origin);\n\t\treturn 0;\n\t}\n\n\tstatic int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream)\n\t{\n\t\treturn 0;\n\t}\n\n\tstatic int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream)\n\t{\n\t\treturn 0;\n\t}\n\n\tzlib_inmem_func64() {\n\t\tzopen64_file = fopen64_file_func;\n\t\tzread_file = fread_file_func;\n\t\tzwrite_file = fwrite_file_func;\n\t\tztell64_file = ftell64_file_func;\n\t\tzseek64_file = fseek64_file_func;\n\t\tzclose_file = fclose_file_func;\n\t\tzerror_file = ferror_file_func;\n\t\topaque = NULL;\n\t}\n};\n\nstatic zlib_filefunc64_def* GetZlibIOFunc() {\n\tstatic zlib_inmem_func64 func;\n\treturn &func;\n}\n\nstatic std::string url_encode(const std::string &value) {\n\tstd::ostringstream escaped;\n\tescaped.fill('0');\n\tescaped << std::hex;\n\n\tfor (std::string::value_type c : value) {\n\t\t// Keep alphanumeric and other accepted characters intact\n\t\tif (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {\n\t\t\tescaped << c;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Any other characters are percent-encoded\n\t\tescaped << '%' << std::setw(2) << int((unsigned char)c);\n\t}\n\n\treturn escaped.str();\n}\n\n#define FLAG_UTF8 (1<<11)\nstatic void SendDumps(std::string dumpdir, std::vector<std::string> allDumps, std::string packageName, std::string versionStr) {\n\tstd::mutex _mutex;\n\tstd::condition_variable _cond;\n\tfor (const std::string &filename : allDumps) {\n\t\tstd::string fullpath = dumpdir + \"/\" + filename;\n\t\tdo {\n\t\t\tstruct tTVP_stat stat_buf;\n\t\t\tif (!TVP_stat(fullpath.c_str(), stat_buf)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tFILE *fp = fopen(fullpath.c_str(), \"rb\");\n\t\t\tif (!fp) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tstd::vector<unsigned char> buf;\n\t\t\tbuf.resize(stat_buf.st_size);\n\t\t\tfseek(fp, 0, SEEK_SET);\n\t\t\tfread(&buf[0], 1, stat_buf.st_size, fp);\n\t\t\tfclose(fp);\n\n\t\t\tzip_fileinfo zi;\n\t\t\tmemset(&zi, 0, sizeof zi);\n\n\t\t\ttime_t _t = stat_buf.st_mtime;\n\t\t\tstruct tm *time = localtime(&_t);\n\t\t\tzi.tmz_date.tm_year = time->tm_year;\n\t\t\tzi.tmz_date.tm_mon = time->tm_mon;\n\t\t\tzi.tmz_date.tm_mday = time->tm_mday;\n\t\t\tzi.tmz_date.tm_hour = time->tm_hour;\n\t\t\tzi.tmz_date.tm_min = time->tm_min;\n\t\t\tzi.tmz_date.tm_sec = time->tm_sec;\n\n\t\t\t// CRCӋ\n\t\t\tunsigned long crcFile = 0;\n\t\t\tcrcFile = crc32(crcFile, (const Bytef *)&buf[0], buf.size());\n\t\t\t// ե׷\n\t\t\t// UTF8Ǹ{\n\t\t\tzipFile zf = zipOpen2_64((const void*)filename.c_str(), 0, NULL, GetZlibIOFunc());\n\t\t\tif (zf == NULL) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (zipOpenNewFileInZip4(zf, filename.c_str(), &zi,\n\t\t\t\tNULL, 0, NULL, 0, NULL /* comment*/,\n\t\t\t\tZ_DEFLATED, 9, 0,\n\t\t\t\t-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n\t\t\t\tNULL,\n\t\t\t\tcrcFile, 0, FLAG_UTF8) != ZIP_OK) {\n\t\t\t\tzipClose(zf, NULL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tzipWriteInFileInZip(zf, (const Bytef *)&buf[0], buf.size());\n\t\t\tzipCloseFileInZip(zf);\n\t\t\tzipClose(zf, NULL);\n\n\t\t\tcocos2d::network::HttpRequest* pRequest = new cocos2d::network::HttpRequest();\n\t\t\tstd::string strUrl = \n#ifdef _DEBUG\n\t\t\t\t\"http://127.0.0.1:7777/upload_dump.php\"\n#else\n\t\t\t\t\"http://avgfun.net/upload_dump.php\"\n#endif\n\t\t\t\t;\n\t\t\tpRequest->setUrl(strUrl.c_str());\n\t\t\tpRequest->setRequestType(cocos2d::network::HttpRequest::Type::POST);\n\t\t\tstd::ostringstream postData;\n\t\t\tpostData << \"appid=\" << url_encode(packageName);\n\t\t\tpostData << \"&version=\" << url_encode(versionStr);\n\t\t\tpostData << \"&time=\" << _t;\n\t\t\ttTVPMemoryStream *bs = _inmemFiles.begin()->second;\n\t\t\tchar *base64str;\n\t\t\tcocos2d::base64Encode((const unsigned char *)bs->GetInternalBuffer(), bs->GetSize(), &base64str);\n\t\t\tpostData << \"&data=\" << url_encode(base64str);\n\t\t\tfree(base64str);\n\t\t\tstd::string postStr = postData.str();\n\t\t\tpRequest->setRequestData(postStr.c_str(), postStr.length());\n\t\t\tpRequest->setResponseCallback([&](cocos2d::network::HttpClient* client, cocos2d::network::HttpResponse* response){\n\t\t\t\t_cond.notify_one();\n\t\t\t});\n\t\t\tpRequest->setTag(\"POST\");\n\t\t\tstd::unique_lock<std::mutex> lk(_mutex);\n\t\t\tcocos2d::network::HttpClient::getInstance()->send(pRequest);\n\t\t\t_cond.wait(lk);\n\t\t\tpRequest->release();\n\t\t} while (false);\n\t\tremove(fullpath.c_str());\n\t\tfor (auto it : _inmemFiles) {\n\t\t\tdelete it.second;\n\t\t}\n\t\t_inmemFiles.clear();\n\t}\n\t//allDumps.clear();\n}\n\nvoid TVPCheckAndSendDumps(const std::string &dumpdir, const std::string &packageName, const std::string &versionStr) {\n\tstd::vector<std::string> allDumps;\n\tTVPListDir(dumpdir, [&](const std::string &name, int mask) {\n\t\tif (mask & (S_IFREG | S_IFDIR)) {\n\t\t\tif (name.size() <= 4) return;\n\t\t\tif (name.substr(name.size() - 4) != \".dmp\") return;\n\t\t\tallDumps.emplace_back(name);\n\t\t}\n\t});\n\tif (!allDumps.empty()) {\n\t\tstd::string title = LocaleConfigManager::GetInstance()->GetText(\"crash_report\");\n\t\tstd::string msgfmt = LocaleConfigManager::GetInstance()->GetText(\"crash_report_msg\");\n\t\tchar buf[256];\n\t\tsprintf(buf, msgfmt.c_str(), allDumps.size());\n\t\tif (TVPShowSimpleMessageBoxYesNo(buf, title) == 0) {\n\t\t\tstatic std::thread dumpthread;\n\t\t\tdumpthread = std::thread(std::bind(SendDumps, dumpdir, allDumps, packageName, versionStr));\n\t\t} else {\n\t\t\tClearDumps(dumpdir, allDumps);\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/core/environ/Platform.h",
    "content": "#pragma once\n#include \"tjsCommHead.h\"\n#include <string>\n#include <vector>\n\nstruct TVPMemoryInfo\n{ // all in kB\n    unsigned long MemTotal;\n    unsigned long MemFree;\n    unsigned long SwapTotal;\n    unsigned long SwapFree;\n    unsigned long VirtualTotal;\n    unsigned long VirtualUsed;\n};\n\nvoid TVPGetMemoryInfo(TVPMemoryInfo &m);\ntjs_int TVPGetSystemFreeMemory(); // in MB\ntjs_int TVPGetSelfUsedMemory(); // in MB\n\nextern \"C\" int TVPShowSimpleMessageBox(const char * text, const char * caption, unsigned int nButton, const char **btnText); // C-style\n\nint TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption, const std::vector<ttstr> &vecButtons);\nint TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption);\nint TVPShowSimpleMessageBoxYesNo(const ttstr & text, const ttstr & caption);\n\nint TVPShowSimpleInputBox(ttstr &text, const ttstr &caption, const ttstr &prompt, const std::vector<ttstr> &vecButtons);\n\nstd::vector<std::string> TVPGetDriverPath();\nstd::vector<std::string> TVPGetAppStoragePath();\nbool TVPCheckStartupPath(const std::string &path);\nstd::string TVPGetPackageVersionString();\nvoid TVPExitApplication(int code);\nvoid TVPCheckMemory();\nconst std::string &TVPGetInternalPreferencePath();\nbool TVPDeleteFile(const std::string &filename);\nbool TVPRenameFile(const std::string &from, const std::string &to);\nbool TVPCopyFile(const std::string &from, const std::string &to);\n\nvoid TVPShowIME(int x, int y, int w, int h);\nvoid TVPHideIME();\n\nvoid TVPRelinquishCPU();\nvoid TVPPrintLog(const char *str);\n\nvoid TVPFetchSDCardPermission(); // for android only\n\nstruct tTVP_stat {\n\tuint16_t st_mode;\n\tuint64_t st_size;\n\tuint64_t st_atime;\n\tuint64_t st_mtime;\n\tuint64_t st_ctime;\n};\n\nbool TVP_stat(const tjs_char *name, tTVP_stat &s);\nbool TVP_stat(const char *name, tTVP_stat &s);\nvoid TVP_utime(const char *name, time_t modtime);\n\nvoid TVPSendToOtherApp(const std::string &filename);\nstd::string TVPGetCurrentLanguage();\n"
  },
  {
    "path": "src/core/environ/XP3ArchiveRepack.cpp",
    "content": "#include \"XP3ArchiveRepack.h\"\n#include <functional>\n#include \"p7zip/CPP/7zip/Archive/7z/7zOut.h\"\n#include \"p7zip/CPP/7zip/Common/StreamObjects.h\"\nextern \"C\" {\n#include \"p7zip/C/7zCrc.h\"\n}\n#include \"TextStream.h\"\n#include \"StorageImpl.h\"\n#include \"XP3Archive.h\"\n#include <time.h>\n#include <assert.h>\n#include <thread>\n#include <fcntl.h>\n#include <unistd.h>\n#include \"win32io.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"ogl/etcpak.h\"\n#include <unordered_map>\n#include \"LayerIntf.h\"\n#include \"MsgIntf.h\"\n#include \"ncbind/ncbind.hpp\"\n#include \"visual/tvpgl_asm_init.h\"\n#include \"DetectCPU.h\"\n#include <set>\n\nusing namespace TJS;\nusing namespace NArchive::N7z;\n\n#define COMPRESS_THRESHOLD 4 * 1024 * 1024\n#define S_INTERRUPT ((HRESULT)0x114705)\n\nvoid TVPSetXP3FilterScript(ttstr content);\nvoid TVPSavePVRv3(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\n\nclass tTVPXP3ArchiveEx : public tTVPXP3Archive {\npublic:\n\ttTVPXP3ArchiveEx(const ttstr & name, tTJSBinaryStream *st) : tTVPXP3Archive(name, 0) {\n\t\tInit(st, -1, false);\n\t}\n\n\tuint64_t TotalSize = 0;\n};\n\nclass OutStreamFor7z : public IOutStream {\n\tlong fp;\n\tunsigned int RefCount = 1;\n\npublic:\n\tOutStreamFor7z(const std::string &path) {\n\t\tfp = open(path.c_str(), O_RDWR | O_CREAT, 0666);\n\t}\n\t~OutStreamFor7z() {\n\t\tclose(fp);\n\t}\n\n\tULONG AddRef() { return ++RefCount; }\n\tULONG Release() {\n\t\tif (RefCount == 1) {\n\t\t\tdelete this;\n\t\t\treturn 0;\n\t\t}\n\t\treturn --RefCount;\n\t}\n\tHRESULT QueryInterface(REFIID iid, void **ppOut) {\n\t\tif (!memcmp(&iid, &IID_IOutStream, sizeof(IID_IOutStream))) {\n\t\t\t*ppOut = (IOutStream*)this;\n\t\t\treturn S_OK;\n\t\t}\n\t\t*ppOut = nullptr;\n\t\treturn E_NOTIMPL;\n\t}\n\n\tHRESULT Write(const void *data, UInt32 size, UInt32 *processedSize) {\n\t\t*processedSize = write(fp, data, size);\n\t\treturn S_OK;\n\t}\n\tHRESULT Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) override {\n\t\tint64_t pos = lseek64(fp, offset, seekOrigin);\n\t\tif (newPosition) *newPosition = pos;\n\t\treturn S_OK;\n\t}\n\tHRESULT SetSize(UInt64 newSize) {\n\t\treturn S_OK;\n\t}\n};\n\nclass OutStreamMemory : public IOutStream, public tTVPMemoryStream {\n\tunsigned int RefCount = 1;\n\npublic:\n\tULONG AddRef() { return ++RefCount; }\n\tULONG Release() {\n\t\tif (RefCount == 1) {\n\t\t\tdelete this;\n\t\t\treturn 0;\n\t\t}\n\t\treturn --RefCount;\n\t}\n\tHRESULT QueryInterface(REFIID iid, void **ppOut) {\n\t\tif (!memcmp(&iid, &IID_IOutStream, sizeof(IID_IOutStream))) {\n\t\t\t*ppOut = (IOutStream*)this;\n\t\t\treturn S_OK;\n\t\t}\n\t\t*ppOut = nullptr;\n\t\treturn E_NOTIMPL;\n\t}\n\n\tHRESULT Write(const void *data, UInt32 size, UInt32 *processedSize) override {\n\t\t*processedSize = tTVPMemoryStream::Write(data, size);\n\t\treturn S_OK;\n\t}\n\tHRESULT Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) override  {\n\t\t*newPosition = tTVPMemoryStream::Seek(offset, seekOrigin);\n\t\treturn S_OK;\n\t}\n\tHRESULT SetSize(UInt64 newSize) {\n\t\ttTVPMemoryStream::SetSize(newSize);\n\t\treturn S_OK;\n\t}\n};\n\nclass SequentialInStreamFor7z : public ISequentialInStream {\n\ttTJSBinaryStream *fp;\n\tunsigned int RefCount = 1;\n\npublic:\n\tSequentialInStreamFor7z(tTJSBinaryStream *s) {\n\t\tfp = s;\n\t}\n\t~SequentialInStreamFor7z() {\n\t\tfp = nullptr;\n\t}\n\n\tULONG AddRef() { return ++RefCount; }\n\tULONG Release() {\n\t\tif (RefCount == 1) {\n\t\t\tdelete this;\n\t\t\treturn 0;\n\t\t}\n\t\treturn --RefCount;\n\t}\n\tHRESULT QueryInterface(REFIID iid, void **ppOut) {\n\t\tif (!memcmp(&iid, &IID_IInStream, sizeof(IID_IInStream))) {\n\t\t\t*ppOut = (ISequentialInStream*)this;\n\t\t\treturn S_OK;\n\t\t}\n\t\t*ppOut = nullptr;\n\t\treturn E_NOTIMPL;\n\t}\n\n\tHRESULT Read(void *data, UInt32 size, UInt32 *processedSize) {\n\t\t*processedSize = fp->Read(data, size);\n\t\treturn S_OK;\n\t}\n};\n\nclass XP3ArchiveRepackAsyncImpl\n\t: ICompressProgressInfo\n{\npublic:\n\tXP3ArchiveRepackAsyncImpl();\n\t~XP3ArchiveRepackAsyncImpl();\n\tvoid Clear();\n\tvoid Start();\n\tvoid Stop() { bStopRequired = true; }\n\tvoid DoConv();\n\tuint64_t AddTask(const std::string &src);\n\tvoid SetXP3Filter(const std::string &xp3filter);\n\tvoid SetCallback(\n\t\tconst std::function<void(int, uint64_t, const std::string &)> &onNewFile,\n\t\tconst std::function<void(int, uint64_t, const std::string &)> &onNewArchive,\n\t\tconst std::function<void(uint64_t, uint64_t, uint64_t)> &onProgress,\n\t\tconst std::function<void(int, const std::string &)> &onError,\n\t\tconst std::function<void()> &onEnded) {\n\t\tOnNewFile = onNewFile;\n\t\tOnNewArchive = onNewArchive;\n\t\tOnProgress = onProgress;\n\t\tOnError = onError;\n\t\tOnEnded = onEnded;\n\t}\n\tvoid SetOption(const std::string &name, bool v);\n\npublic:\n\tbool OptionUsingETC2 = false;\n\tbool OptionMergeMaskImg = true;\n\nprivate:\n\tHRESULT AddTo7zArchive(tTJSBinaryStream* s, const ttstr &_naem);\n\n\t// ICompressProgressInfo\n\tvirtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) override;\n\t// IUnknown\n\tvirtual HRESULT QueryInterface(REFIID riid, void **ppvObject) override { return E_NOTIMPL; }\n\tvirtual ULONG AddRef(void) override { return 0; }\n\tvirtual ULONG Release(void) override { return 0; }\n\n\tstd::vector<std::pair<tTVPXP3ArchiveEx*, std::string> > ConvFileList;\n\tstd::thread* Thread = nullptr;\n\tCCreatedCoder CoderCompress, CoderCopy;\n\tstatic const int nCodecMethod = 0x30101, // LZMA\n\t\tnCodecMethodCopy = 0;\n\tCArchiveDatabaseOut newDatabase;\n\tOutStreamFor7z *strout;\n\tCByteBuffer props;\n\tbool bStopRequired = false;\n\tuint64_t nTotalSize = 0, nArcSize = 0;\n\n\tstd::function<void(int, uint64_t, const std::string &)> OnNewFile;\n\tstd::function<void(int, uint64_t, const std::string &)> OnNewArchive;\n\tstd::function<void(uint64_t, uint64_t, uint64_t)> OnProgress;\n\tstd::function<void(int, const std::string &)> OnError;\n\tstd::function<void()> OnEnded;\n};\n\nXP3ArchiveRepackAsync::XP3ArchiveRepackAsync()\n\t: _impl(new XP3ArchiveRepackAsyncImpl())\n{\n\tTVPDetectCPU();\n\tTVPGL_ASM_Init();\n}\n\nXP3ArchiveRepackAsync::~XP3ArchiveRepackAsync() {\n\tdelete _impl;\n}\n\nuint64_t XP3ArchiveRepackAsync::AddTask(const std::string &src) {\n\treturn _impl->AddTask(src);\n}\n\nvoid XP3ArchiveRepackAsync::Start()\n{\n\t_impl->Start();\n}\n\nvoid XP3ArchiveRepackAsync::Stop()\n{\n\t_impl->Stop();\n}\n\nvoid XP3ArchiveRepackAsync::SetXP3Filter(const std::string &xp3filter)\n{\n\t_impl->SetXP3Filter(xp3filter);\n}\n\nvoid XP3ArchiveRepackAsync::SetCallback(\n\tconst std::function<void(int, uint64_t, const std::string &)> &onNewFile,\n\tconst std::function<void(int, uint64_t, const std::string &)> &onNewArchive,\n\tconst std::function<void(uint64_t, uint64_t, uint64_t)> &onProgress,\n\tconst std::function<void(int, const std::string &)> &onError,\n\tconst std::function<void()> &onEnded)\n{\n\t_impl->SetCallback(onNewFile, onNewArchive, onProgress, onError, onEnded);\n}\n\nvoid XP3ArchiveRepackAsync::SetOption(const std::string &name, bool v)\n{\n\t_impl->SetOption(name, v);\n}\n\nXP3ArchiveRepackAsyncImpl::XP3ArchiveRepackAsyncImpl()\n{\n\tif (!g_CrcTable[1]) CrcGenerateTable();\n\tCreateCoder(nCodecMethod, true, CoderCompress);\n\tCreateCoder(nCodecMethodCopy, true, CoderCopy);\n\n\tCMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;\n\tCMyComPtr<ICompressSetCoderProperties> setCoderProperties;\n\tCoderCompress.Coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);\n\tCoderCompress.Coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);\n\n\tif (setCoderProperties) {\n\t\tconst int nProp = 1;\n\t\tPROPVARIANT propvars[nProp];\n\t\tPROPID props[nProp] = {\n\t\t\tNCoderPropID::kDictionarySize,\n\t\t};\n\t\tpropvars[0].vt = VT_UI4;\n\t\tpropvars[0].ulVal = 4 * 1024 * 1024;\n\t\tsetCoderProperties->SetCoderProperties(props, propvars, nProp);\n\t}\n\tif (writeCoderProperties) {\n\t\tCDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;\n\t\tCMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);\n\t\toutStreamSpec->Init();\n\t\twriteCoderProperties->WriteCoderProperties(dynOutStream);\n\t\toutStreamSpec->CopyToBuffer(props);\n\t}\n}\n\nXP3ArchiveRepackAsyncImpl::~XP3ArchiveRepackAsyncImpl()\n{\n\tstd::thread* t = Thread;\n\tif (t && t->joinable()) {\n\t\tt->join();\n\t\tdelete t;\n\t}\n\tClear();\n}\n\nuint64_t XP3ArchiveRepackAsyncImpl::AddTask(const std::string &src/*, const std::string &dst*/)\n{\n\tttstr path(src);\n\ttTVPLocalFileStream *str = new tTVPLocalFileStream(path, path, TJS_BS_READ);\n\ttTVPXP3ArchiveEx *xp3arc = new tTVPXP3ArchiveEx(path, str);\n\tfor (const tTVPXP3Archive::tArchiveItem &item : xp3arc->ItemVector) {\n\t\txp3arc->TotalSize += item.OrgSize;\n\t}\n\tConvFileList.emplace_back(xp3arc, src);\n\treturn xp3arc->TotalSize;\n}\n\nvoid XP3ArchiveRepackAsyncImpl::SetXP3Filter(const std::string &xp3filter)\n{\n\tttstr xp3filterScript;\n\tiTJSTextReadStream * stream = TVPCreateTextStreamForRead(xp3filter, \"\");\n\tstream->Read(xp3filterScript, 0);\n\tdelete stream;\n\tTVPSetXP3FilterScript(xp3filterScript);\n}\n\nvoid XP3ArchiveRepackAsyncImpl::SetOption(const std::string &name, bool v)\n{\n\tif (name == \"merge_mask_img\") {\n\t\tOptionMergeMaskImg = v;\n\t} else if (name == \"conv_etc2\") {\n\t\tOptionUsingETC2 = v;\n\t}\n}\n\nvoid XP3ArchiveRepackAsyncImpl::Clear()\n{\n\tfor (auto & it : ConvFileList) {\n\t\tif (it.first)\n\t\t\tdelete it.first;\n\t}\n\tConvFileList.clear();\n\tTVPSetXP3FilterScript(TJS_W(\"\"));\n}\n\nvoid XP3ArchiveRepackAsyncImpl::Start()\n{\n\tif (!Thread) {\n\t\tThread = new std::thread(std::bind(&XP3ArchiveRepackAsyncImpl::DoConv, this));\n\t}\n}\n\nstatic bool CheckIsImage(tTJSBinaryStream *s) {\n\t// convert image > 8k\n\ttjs_uint8 header[16];\n\ttjs_uint readed = s->Read(header, 16);\n\ts->SetPosition(0);\n\tif (readed != 16) return false;\n\tif (!memcmp(header, \"BM\", 2)) {\n\t\treturn true;\n\t} else if (!memcmp(header, \"\\x89PNG\", 4)) {\n\t\treturn true;\n\t} else if (!memcmp(header, \"\\xFF\\xD8\\xFF\", 3)) { // JPEG\n\t\treturn true;\n\t} else if (!memcmp(header, \"TLG\", 3)) {\n\t\treturn true;\n\t} else if (!memcmp(header, \"\\x49\\x49\\xbc\\x01\", 4)) { // JXR\n\t\treturn true;\n\t} else if (!memcmp(header, \"BPG\", 3)) {\n\t\treturn true;\n\t} else if (!memcmp(header, \"RIFF\", 4)) {\n\t\tif (!memcmp(header + 8, \"WEBPVP8\", 7)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nHRESULT XP3ArchiveRepackAsyncImpl::AddTo7zArchive(tTJSBinaryStream* s, const ttstr &_name) {\n\tCFileItem file;\n\tCFileItem2 file2;\n\tSequentialInStreamFor7z str(s);\n\ttjs_uint64 origSize = s->GetSize();\n\tfile.Size = origSize;\n\tfile2.Init();\n\tUString name(_name.c_str());\n\tUInt64 inSizeForReduce = origSize;\n\tUInt64 newSize = origSize;\n\tbool compressable = origSize > 64 && origSize < 4 * 1024 * 1024;\n\tif (compressable) {\n\t\t// compressable quick check\n\t\ttjs_uint8 header[16];\n\t\ts->Read(header, 16);\n\t\tif (!memcmp(header, \"\\x89PNG\", 4)) {\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"OggS\\x00\", 5)) {\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"\\xFF\\xD8\\xFF\", 3)) { // JPEG\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"TLG\", 3)) {\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"0&\\xB2\\x75\\x8E\\x66\\xCF\\x11\", 8)) { // wmv/wma\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"AJPM\", 4)) { // AMV\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"\\x49\\x49\\xbc\\x01\", 4)) { // JXR\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"BPG\", 3)) {\n\t\t\tcompressable = false;\n\t\t} else if (!memcmp(header, \"RIFF\", 4)) {\n\t\t\tif (!memcmp(header + 8, \"WEBPVP8\", 7)) {\n\t\t\t\tcompressable = false;\n\t\t\t}\n\t\t}\n\t\ts->SetPosition(0);\n\t}\n\tHRESULT ret;\n\tif (compressable) {\n\t\tUInt64 expectedSize = origSize * 4 / 5;\n\t\tOutStreamMemory tmp;\n\t\tif ((ret = CoderCompress.Coder->Code(&str, &tmp, &inSizeForReduce, &newSize, this)) != S_OK)\n\t\t\treturn ret;\n\t\tif (tmp.GetSize() < expectedSize) {\n\t\t\tUInt32 writed;\n\t\t\tif ((ret = strout->Write(tmp.GetInternalBuffer(), tmp.GetSize(), &writed)) != S_OK) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\tif (writed != tmp.GetSize())\n\t\t\t\treturn E_FAIL;\n\t\t\tnewDatabase.PackSizes.Add(tmp.GetSize());\n\t\t\tnewDatabase.CoderUnpackSizes.Add(origSize);\n\t\t\tnewDatabase.NumUnpackStreamsVector.Add(1);\n\t\t\tCFolder &folder = newDatabase.Folders.AddNew();\n\t\t\tfolder.Bonds.SetSize(0);\n\t\t\tfolder.Coders.SetSize(1);\n\t\t\tCCoderInfo &cod = folder.Coders[0];\n\t\t\tcod.MethodID = nCodecMethod;\n\t\t\tcod.NumStreams = 1;\n\t\t\tcod.Props = props;\n\t\t\tfolder.PackStreams.SetSize(1);\n\t\t\tfolder.PackStreams[0] = 0; // only 1 stream\n\t\t\tnewDatabase.AddFile(file, file2, name);\n\t\t\treturn S_OK;\n\t\t}\n\t\ts->SetPosition(0);\n\t}\n\t// direct copy\n\tnewSize = origSize;\n\tif ((ret = CoderCopy.Coder->Code(&str, strout, &inSizeForReduce, &newSize, this)) != S_OK) {\n\t\treturn ret;\n\t}\n\tnewDatabase.PackSizes.Add(s->GetSize());\n\tnewDatabase.CoderUnpackSizes.Add(origSize);\n\tnewDatabase.NumUnpackStreamsVector.Add(1);\n\tCFolder &folder = newDatabase.Folders.AddNew();\n\tfolder.Bonds.SetSize(0);\n\tfolder.Coders.SetSize(1);\n\tCCoderInfo &cod = folder.Coders[0];\n\tcod.MethodID = nCodecMethodCopy;\n\tcod.NumStreams = 1;\n\tfolder.PackStreams.SetSize(1);\n\tfolder.PackStreams[0] = 0; // only 1 stream\n\tnewDatabase.AddFile(file, file2, name);\n\treturn S_OK;\n}\n\nHRESULT XP3ArchiveRepackAsyncImpl::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\n{\n\tif (OnProgress) {\n\t\tOnProgress(nTotalSize + *inSize, nArcSize + *inSize, *inSize);\n\t}\n\treturn bStopRequired ? S_INTERRUPT : S_OK;\n}\n\nvoid XP3ArchiveRepackAsyncImpl::DoConv()\n{\n\tnTotalSize = 0;\n\tfor (unsigned int arcidx = 0; arcidx < ConvFileList.size(); ++arcidx) {\n\t\tauto &it = ConvFileList[arcidx];\n\t\tif (bStopRequired) break;\n\t\tif (OnNewArchive)\n\t\t\tOnNewArchive(arcidx, it.first->TotalSize, it.second);\n\n\t\ttTVPXP3ArchiveEx *xp3arc = it.first;\n\t\ttjs_uint totalFile = xp3arc->GetCount();\n\n\t\tstd::string tmpname = it.second + \".7z\";\n\t\tstrout = new OutStreamFor7z(tmpname);\n\n\t\tCOutArchive archive;\n\t\tif (archive.Create(strout, false) != S_OK) {\n\t\t\tif (OnError)\n\t\t\t\tOnError(-1, \"Fail to create output archive.\");\n\t\t\tbreak;\n\t\t}\n\t\tarchive.SkipPrefixArchiveHeader();\n\t\tnewDatabase.Clear();\n\n\t\tnArcSize = 0;\n\n\t\t// filter image files <idx, mask_img_idx>, img_mask = -1 means no mask available or normal file\n\t\tstd::map<tjs_uint, tjs_uint> imglist;\n\t\tstd::vector<tjs_uint> filelist; // normal files\n\t\t{\n\t\t\tstd::unordered_multimap<ttstr, const tTVPXP3Archive::tArchiveItem*, ttstr_hasher> allFileName;\n\t\t\tstd::vector<tjs_uint> allfilelist;\n\t\t\tstd::set<tjs_uint> masklist;\n\t\t\tfor (tjs_uint idx = 0; idx < xp3arc->ItemVector.size(); ++idx) {\n\t\t\t\tconst tTVPXP3Archive::tArchiveItem &item = xp3arc->ItemVector[idx];\n\t\t\t\tif (!item.OrgSize) {\n\t\t\t\t\t// add empty files first\n\t\t\t\t\tCFileItem file;\n\t\t\t\t\tCFileItem2 file2;\n\t\t\t\t\tfile2.Init();\n\t\t\t\t\tUString name(item.Name.c_str());\n\t\t\t\t\tfile.Size = item.OrgSize;\n\t\t\t\t\tfile.HasStream = false;\n\t\t\t\t\tnewDatabase.AddFile(file, file2, name);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (item.Name.length() > 256 && item.Name.StartsWith(TJS_W(\"$$$\")))\n\t\t\t\t\tcontinue;\n\t\t\t\tttstr name = TVPChopStorageExt(item.Name);\n\t\t\t\tallFileName.emplace(name, &item);\n\t\t\t\tallfilelist.emplace_back(idx);\n\t\t\t}\n\t\t\tif(OptionMergeMaskImg)\n\t\t\tfor (tjs_uint idx : allfilelist) {\n\t\t\t\tconst tTVPXP3Archive::tArchiveItem &item = xp3arc->ItemVector[idx];\n\t\t\t\tttstr name = TVPChopStorageExt(item.Name);\n\t\t\t\ttjs_int pos = name.length() - 2;\n\t\t\t\tif (pos > 0 && name.SubString(pos, 2) == TJS_W(\"_m\")) {\n\t\t\t\t\tttstr prefix = name.SubString(0, pos);\n\t\t\t\t\tint count = 0;\n\t\t\t\t\tauto itpair = allFileName.equal_range(prefix);\n\t\t\t\t\tfor (auto it = itpair.first; it != itpair.second; ++it) {\n\t\t\t\t\t\t++count;\n\t\t\t\t\t}\n\t\t\t\t\tif (count == 1) { // assume that one mask associate to one image\n\t\t\t\t\t\tconst tTVPXP3Archive::tArchiveItem* imgItem = itpair.first->second;\n\t\t\t\t\t\tallFileName.erase(itpair.first);\n\t\t\t\t\t\tallFileName.erase(name);\n\t\t\t\t\t\timglist.emplace(imgItem - &xp3arc->ItemVector.front(), idx);\n\t\t\t\t\t\tmasklist.emplace(idx);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (tjs_uint idx : allfilelist) {\n\t\t\t\tif (imglist.find(idx) != imglist.end() || masklist.find(idx) != masklist.end())\n\t\t\t\t\tcontinue;\n\t\t\t\tfilelist.push_back(idx);\n\t\t\t}\n\t\t}\n\n\t\t// merge image with mask\n\t\t// actual TVPLoadGraphicRouter\n\t\tstatic tTVPGraphicHandlerType *handler = TVPGetGraphicLoadHandler(TJS_W(\".png\"));\n\t\tfor (const auto &it : imglist) {\n\t\t\tif (bStopRequired) break;\n\t\t\tconst tTVPXP3Archive::tArchiveItem &imgItem = xp3arc->ItemVector[it.first];\n\t\t\tconst tTVPXP3Archive::tArchiveItem &maskItem = xp3arc->ItemVector[it.second];\n\t\t\tstd::auto_ptr<tTJSBinaryStream> strImg(xp3arc->CreateStreamByIndex(&imgItem - &xp3arc->ItemVector.front()));\n\t\t\tstd::auto_ptr<tTJSBinaryStream> strMask(xp3arc->CreateStreamByIndex(&maskItem - &xp3arc->ItemVector.front()));\n\t\t\tbool isImage = CheckIsImage(strImg.get()) && CheckIsImage(strMask.get());\n\t\t\tif (isImage) {\n\t\t\t\t// skip 8-bit image\n\t\t\t\tiTJSDispatch2 *dic = nullptr;\n\t\t\t\thandler->Header(strImg.get(), &dic);\n\t\t\t\tstrImg->SetPosition(0);\n\t\t\t\tif (dic) {\n\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\tdic->PropGet(0, TJS_W(\"bpp\"), 0, &val, dic);\n\t\t\t\t\tdic->Release();\n\t\t\t\t\tint bpp = val.AsInteger();\n\t\t\t\t\tisImage = bpp == 24 || bpp == 32;\n\t\t\t\t} else {\n\t\t\t\t\tisImage = false; // unknown error, skip\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!isImage) {\n\t\t\t\tfilelist.push_back(it.first);\n\t\t\t\tfilelist.push_back(it.second);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstruct BmpInfoWithMask {\n\t\t\t\ttTVPBitmap* bmp = nullptr;\n\t\t\t\ttTVPBitmap* bmpForMask = nullptr;\n\t\t\t\tstd::unordered_map<ttstr, ttstr, ttstr_hasher> metainfo;\n\t\t\t\t~BmpInfoWithMask() {\n\t\t\t\t\tif (bmp) delete bmp;\n\t\t\t\t\tif (bmpForMask) delete bmpForMask;\n\t\t\t\t}\n\t\t\t} data;\n\n\t\t\tif (OnNewFile)\n\t\t\t\tOnNewFile(it.first, imgItem.OrgSize, imgItem.Name.AsStdString());\n\n\t\t\t// main part\n\t\t\thandler->Load(handler->FormatData, &data,\n\t\t\t\t[](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int{\n\t\t\t\tBmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata;\n\t\t\t\tif (!data->bmp) {\n\t\t\t\t\tdata->bmp = new tTVPBitmap(w, h, 32);\n\t\t\t\t}\n\t\t\t\treturn data->bmp->GetPitch();\n\t\t\t}, [](void *callbackdata, tjs_int y)->void* {\n\t\t\t\tBmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata;\n\t\t\t\tif (y >= 0) {\n\t\t\t\t\treturn data->bmp->GetScanLine(y);\n\t\t\t\t}\n\t\t\t\treturn nullptr;\n\t\t\t}, [](void *callbackdata, const ttstr & name, const ttstr & value) {\n\t\t\t\tBmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata;\n\t\t\t\tdata->metainfo.emplace(name, value);\n\t\t\t}, strImg.get(), TVP_clNone, glmNormal);\n\n\t\t\t// mask part\n\t\t\thandler->Load(handler->FormatData, &data,\n\t\t\t\t[](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int {\n\t\t\t\tBmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata;\n\t\t\t\tif (data->bmp->GetWidth() != w || data->bmp->GetHeight() != h)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMaskSizeMismatch);\n\t\t\t\tif (!data->bmpForMask) {\n\t\t\t\t\tdata->bmpForMask = new tTVPBitmap(w, h, 8);\n\t\t\t\t}\n\t\t\t\treturn data->bmpForMask->GetPitch();\n\t\t\t}, [](void *callbackdata, tjs_int y)->void* {\n\t\t\t\tBmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata;\n\t\t\t\tif (y >= 0) {\n\t\t\t\t\treturn data->bmpForMask->GetScanLine(y);\n\t\t\t\t}\n\t\t\t\treturn nullptr;\n\t\t\t}, [](void *callbackdata, const ttstr & name, const ttstr & value) {\n\t\t\t\t// no metainfo for mask\n\t\t\t}, strMask.get(), TVP_clNone, glmGrayscale);\n\n\t\t\tfor (tjs_uint y = 0; y < data.bmp->GetHeight(); ++y) {\n\t\t\t\tTVPBindMaskToMain((tjs_uint32*)data.bmp->GetScanLine(y), (tjs_uint8*)data.bmpForMask->GetScanLine(y), data.bmp->GetWidth());\n\t\t\t}\n\t\t\tdelete data.bmpForMask;\n\t\t\tdata.bmpForMask = nullptr;\n\t\t\tncbDictionaryAccessor meta;\n\t\t\tfor (const auto &it : data.metainfo) {\n\t\t\t\tmeta.SetValue(it.first.c_str(), it.second);\n\t\t\t}\n\t\t\ttTVPMemoryStream memstr;\n\t\t\ttTVPBaseBitmap *bmp = new tTVPBaseBitmap(data.bmp->GetWidth(), data.bmp->GetHeight());\n\t\t\tbmp->AssignBitmap(data.bmp);\n\n\t\t\tif (OptionUsingETC2) {\n\t\t\t\tTVPSavePVRv3(nullptr, &memstr, bmp, TJS_W(\"ETC2_RGBA\"), meta.GetDispatch());\n\t\t\t} else {\n\t\t\t\t// convert to tlg5 for better performance\n\t\t\t\tTVPSaveAsTLG(nullptr, &memstr, bmp, TJS_W(\"tlg5\"), meta.GetDispatch());\n\t\t\t}\n\t\t\tdelete bmp;\n\t\t\tmemstr.SetPosition(0);\n\t\t\tHRESULT ret = AddTo7zArchive(&memstr, imgItem.Name);\n\t\t\tif (OnProgress) {\n\t\t\t\tuint64_t size = imgItem.OrgSize + maskItem.OrgSize;\n\t\t\t\tnArcSize += size;\n\t\t\t\tnTotalSize += size;\n\t\t\t\tOnProgress(nTotalSize, nArcSize, size);\n\t\t\t}\n\t\t\tif (ret != S_OK) {\n\t\t\t\tif (ret != S_INTERRUPT && OnError) {\n\t\t\t\t\tOnError(ret, \"Write to file fail.\");\n\t\t\t\t}\n\t\t\t\tbStopRequired = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfor (tjs_uint idx : filelist) {\n\t\t\tconst tTVPXP3Archive::tArchiveItem& item = xp3arc->ItemVector[idx];\n\t\t\t\n\t\t\tif (bStopRequired) break;\n\t\t\tstd::auto_ptr<tTJSBinaryStream> s(xp3arc->CreateStreamByIndex(idx));\n\n\t\t\tif (OnNewFile)\n\t\t\t\tOnNewFile(&item - &xp3arc->ItemVector.front(), item.OrgSize, item.Name.AsStdString());\n\n\t\t\tif (OptionUsingETC2 && item.OrgSize > 8192) {\n\t\t\t\t// convert image > 8k\n\t\t\t\tbool isImage = CheckIsImage(s.get());\n\t\t\t\tint width = 0, height = 0;\n\t\t\t\tstruct BmpInfo {\n\t\t\t\t\ttTVPBitmap* bmp = nullptr;\n\t\t\t\t\tstd::unordered_map<ttstr, ttstr, ttstr_hasher> metainfo;\n\t\t\t\t\ttTVPGraphicPixelFormat fmt = gpfLuminance;\n\t\t\t\t\t~BmpInfo() {\n\t\t\t\t\t\tif (bmp) delete bmp;\n\t\t\t\t\t}\n\t\t\t\t} data;\n\t\t\t\t\n\t\t\t\tif (isImage) {\n\t\t\t\t\t// main part\n\t\t\t\t\thandler->Load(handler->FormatData, &data,\n\t\t\t\t\t\t[](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int {\n\t\t\t\t\t\tBmpInfo * data = (BmpInfo *)callbackdata;\n\t\t\t\t\t\tif (!data->bmp) {\n\t\t\t\t\t\t\tdata->bmp = new tTVPBitmap(w, h, 32);\n\t\t\t\t\t\t\tdata->fmt = fmt;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn data->bmp->GetPitch();\n\t\t\t\t\t}, [](void *callbackdata, tjs_int y)->void* {\n\t\t\t\t\t\tBmpInfo * data = (BmpInfo *)callbackdata;\n\t\t\t\t\t\tif (y >= 0) {\n\t\t\t\t\t\t\treturn data->bmp->GetScanLine(y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nullptr;\n\t\t\t\t\t}, [](void *callbackdata, const ttstr & name, const ttstr & value) {\n\t\t\t\t\t\tBmpInfo * data = (BmpInfo *)callbackdata;\n\t\t\t\t\t\tdata->metainfo.emplace(name, value);\n\t\t\t\t\t}, s.get(), TVP_clNone, glmNormal);\n\n\t\t\t\t\t// skip 8-bit image\n\t\t\t\t\tif (data.fmt != gpfRGB || data.fmt != gpfRGBA) {\n\t\t\t\t\t\tisImage = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isImage) {\n\t\t\t\t\ttTVPBaseBitmap *bmp = new tTVPBaseBitmap(data.bmp->GetWidth(), data.bmp->GetHeight());\n\t\t\t\t\tbmp->AssignBitmap(data.bmp);\n\t\t\t\t\ts.reset(new tTVPMemoryStream);\n\t\t\t\t\tncbDictionaryAccessor meta;\n\t\t\t\t\tfor (const auto &it : data.metainfo) {\n\t\t\t\t\t\tmeta.SetValue(it.first.c_str(), it.second);\n\t\t\t\t\t}\n\t\t\t\t\tTVPSavePVRv3(nullptr, s.get(), bmp,\n\t\t\t\t\t\tdata.fmt == gpfRGB ? TJS_W(\"ETC2_RGB\") : TJS_W(\"ETC2_RGBA\"),\n\t\t\t\t\t\tmeta.GetDispatch());\n\t\t\t\t\tdelete bmp;\n\t\t\t\t\ts->SetPosition(0);\n\t\t\t\t}\n\t\t\t}\n\t\t\tHRESULT ret = AddTo7zArchive(s.get(), item.Name);\n\t\t\tnArcSize += item.OrgSize;\n\t\t\tnTotalSize += item.OrgSize;\n\t\t\tif (ret != S_OK) {\n\t\t\t\tif (ret != S_INTERRUPT && OnError) {\n\t\t\t\t\tOnError(ret, \"Write to file fail.\");\n\t\t\t\t}\n\t\t\t\tbStopRequired = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (bStopRequired)\n\t\t\tbreak;\n\t\tCCompressionMethodMode mode;\n\t\tCHeaderOptions hdropt;\n\t\thdropt.CompressMainHeader = true;\n\t\tarchive.WriteDatabase(newDatabase, &mode, hdropt);\n\t\tarchive.Close();\n\t\tstrout = nullptr;\n\t\tdelete xp3arc;\n\t\tit.first = nullptr;\n\t\tremove(it.second.c_str());\n\t\trename(tmpname.c_str(), it.second.c_str());\n\t}\n\tClear();\n\tif (OnEnded) OnEnded();\n}\n"
  },
  {
    "path": "src/core/environ/XP3ArchiveRepack.h",
    "content": "#pragma once\n#include <string>\n#include <vector>\n#include <functional>\n\nclass XP3ArchiveRepackAsyncImpl;\nclass XP3ArchiveRepackAsync {\n\npublic:\n\tXP3ArchiveRepackAsync();\n\t~XP3ArchiveRepackAsync();\n\tuint64_t AddTask(const std::string &src);\n\tvoid Start();\n\tvoid Stop();\n\tvoid SetXP3Filter(const std::string &xp3filter);\n\tvoid SetCallback(\n\t\tconst std::function<void(int, uint64_t, const std::string &)> &onNewFile,\n\t\tconst std::function<void(int, uint64_t, const std::string &)> &onNewArchive,\n\t\tconst std::function<void(uint64_t, uint64_t, uint64_t)> &onProgress,\n\t\tconst std::function<void(int, const std::string &)> &onError,\n\t\tconst std::function<void()> &onEnded);\n\n\tvoid SetOption(const std::string &name, bool v);\n\nprivate:\n\tXP3ArchiveRepackAsyncImpl *_impl;\n};\n"
  },
  {
    "path": "src/core/environ/android/AndroidUtils.cpp",
    "content": "#include \"AndroidUtils.h\"\n#include \"minizip/unzip.h\"\n#include \"zlib.h\"\n#include <map>\n#include <string>\n#include <vector>\n#include \"tjs.h\"\n#include \"MsgIntf.h\"\n#include \"md5.h\"\n#include \"DebugIntf.h\"\n#include <condition_variable>\n#include <mutex>\n#include \"platform/android/jni/JniHelper.h\"\n#include <set>\n#include <sstream>\n#include \"SysInitIntf.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"Platform.h\"\n#include \"platform/CCCommon.h\"\n#include <EGL/egl.h>\n#include <queue>\n#include \"base/CCDirector.h\"\n#include \"base/CCScheduler.h\"\n#include <unistd.h>\n#include <fcntl.h>\n#include <android/log.h>\n#include \"TickCount.h\"\n#include \"StorageImpl.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"EventIntf.h\"\n#include \"RenderManager.h\"\n#include <sys/stat.h>\n#include \"deprecated/CCString.h\"\n\nUSING_NS_CC;\n\n#define KR2ActJavaPath \"org/tvp/kirikiri2/KR2Activity\"\n//#define KR2EntryJavaPath \"org/tvp/kirikiri2/Kirikiroid2\"\n\nextern unsigned int __page_size = getpagesize();\n\nvoid TVPPrintLog(const char *str) {\n\t__android_log_print(ANDROID_LOG_INFO, \"kr2 debug info\", \"%s\", str);\n}\n\nstatic tjs_uint32 _lastMemoryInfoQuery = 0;\nstatic tjs_int _availMemory, _usedMemory;\nstatic void _updateMemoryInfo() {\n\tif (TVPGetRoughTickCount32() - _lastMemoryInfoQuery > 3000) { // freq in 3s\n\n\t\tJniMethodInfo methodInfo;\n\t\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"updateMemoryInfo\", \"()V\"))\n\t\t{\n\t\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);\n\t\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\t}\n\n\t\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"getAvailMemory\", \"()J\"))\n\t\t{\n\t\t\t_availMemory = methodInfo.env->CallStaticLongMethod(methodInfo.classID, methodInfo.methodID) / (1024 * 1024);\n\t\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\t}\n\n\t\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"getUsedMemory\", \"()J\"))\n\t\t{\n\t\t\t// in kB\n\t\t\t_usedMemory = methodInfo.env->CallStaticLongMethod(methodInfo.classID, methodInfo.methodID) / 1024;\n\t\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\t}\n\n\t\t_lastMemoryInfoQuery = TVPGetRoughTickCount32();\n\t}\n}\n\ntjs_int TVPGetSystemFreeMemory()\n{\n\t_updateMemoryInfo();\n\treturn _availMemory;\n}\n\ntjs_int TVPGetSelfUsedMemory()\n{\n\t_updateMemoryInfo();\n\treturn _usedMemory;\n}\n\nvoid TVPForceSwapBuffer() {\n\teglSwapBuffers(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW));\n}\n\nstd::string TVPGetDeviceID()\n{\n    std::string ret;\n\n    // use pure jni to avoid java code\n// \tjclass classID = pEnv->FindClass(KR2EntryJavaPath);\n// \tstd::string strtmp(\"()L\"); strtmp += KR2EntryJavaPath; strtmp += \";\";\n// \tjmethodID methodGetInstance = pEnv->GetStaticMethodID(classID, \"GetInstance\", strtmp.c_str());\n// \tjobject sInstance = pEnv->CallStaticObjectMethod(classID, methodGetInstance);\n// \tjmethodID getSystemService = pEnv->GetMethodID(classID, \"getSystemService\", \"(Ljava/lang/String;)Ljava/lang/Object;\");\n// \tjstring jstrPhone = pEnv->NewStringUTF(\"phone\");\n// \tjobject telephonyManager = pEnv->CallObjectMethod(sInstance, getSystemService, jstrPhone);\n// \tpEnv->DeleteLocalRef(jstrPhone);\n// \n// \tjclass clsTelephonyManager = pEnv->FindClass(\"android/telephony/TelephonyManager\");\n// \tjmethodID getDeviceId = pEnv->GetMethodID(clsTelephonyManager, \"getDeviceId\", \"()Ljava/lang/String;\");\n// \tjstring jstrDevID = (jstring)pEnv->CallObjectMethod(telephonyManager, getDeviceId);\n// \tif (jstrDevID) {\n// \t\tconst char *p = pEnv->GetStringUTFChars(jstrDevID, 0);\n// \t\tif (p && *p) {\n// \t\t\tret = \"DevID=\";\n// \t\t\tret += p;\n// \t\t\tpEnv->ReleaseStringUTFChars(jstrDevID, p);\n// \t\t} else {\n// \t\t\tif (p) {\n// \t\t\t\tpEnv->ReleaseStringUTFChars(jstrDevID, p);\n// \t\t\t}\n// \t\t\tjmethodID getContentResolver = pEnv->GetMethodID(classID, \"getContentResolver\", \"()Landroid/content/ContentResolver;\");\n// \t\t\tjobject contentResolver = pEnv->CallObjectMethod(sInstance, getContentResolver);\n// \n// \t\t\tjclass clsSecure = pEnv->FindClass(\"android/provider/Settings/Secure\");\n// \t\t\tif (clsSecure) {\n// \t\t\t\tjmethodID Secure_getString = pEnv->GetMethodID(clsSecure, \"getString\", \"(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;\");\n// \t\t\t\tjstring jastrAndroid_ID = pEnv->NewStringUTF(\"android_id\");\n// \t\t\t\tjstring jstrAndroidID = (jstring)pEnv->CallStaticObjectMethod(clsSecure, Secure_getString, contentResolver, jastrAndroid_ID);\n// \t\t\t\tif (jstrAndroidID) {\n// \t\t\t\t\tconst char *p = pEnv->GetStringUTFChars(jstrAndroidID, 0);\n// \t\t\t\t\tif (p && strlen(p) > 8 && strcmp(p, \"9774d56d682e549c\")) {\n// \t\t\t\t\t\tret = \"AndroidID=\";\n// \t\t\t\t\t\tret += p;\n// \t\t\t\t\t}\n// \t\t\t\t}\n// \t\t\t\tpEnv->ReleaseStringUTFChars(jstrAndroidID, p);\n// \t\t\t\tpEnv->DeleteLocalRef(jastrAndroid_ID);\n// \t\t\t}\n// \t\t}\n// \t}\n// \tif (ret.empty())\n\t{\n\t\tJniMethodInfo methodInfo;\n\t\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"getDeviceId\", \"()Ljava/lang/String;\"))\n\t\t{\n\t\t\tjstring result = (jstring)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);\n\t\t\tret = JniHelper::jstring2string(result);\n\t\t\tmethodInfo.env->DeleteLocalRef(result);\n\t\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\t\tchar *t = (char*)ret.c_str();\n\t\t\twhile (*t) {\n\t\t\t\tif (*t == ':') {\n\t\t\t\t\t*t = '=';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tt++;\n\t\t\t}\n\t\t}\n\t}\n\n    return ret;\n}\n\nstatic jobject GetKR2ActInstance() {\n\tJniMethodInfo methodInfo;\n\tstd::string strtmp(\"()L\"); strtmp += KR2ActJavaPath; strtmp += \";\";\n\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"GetInstance\", strtmp.c_str())) {\n\t\tjobject ret = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\treturn ret;\n\t}\n\treturn 0;\n}\n\nstatic std::string GetApkStoragePath() {\n\tJniMethodInfo methodInfo;\n\tjobject sInstance = GetKR2ActInstance();\n\tif (!JniHelper::getMethodInfo(methodInfo, \"android/content/Context\", \"getApplicationInfo\", \"()Landroid/content/pm/ApplicationInfo;\")) {\n\t\tmethodInfo.env->DeleteLocalRef(sInstance);\n\t\treturn \"\";\n\t}\n\tjobject ApplicationInfo = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID);\n\tjclass clsApplicationInfo = methodInfo.env->FindClass(\"android/content/pm/ApplicationInfo\");\n\tjfieldID id_sourceDir = methodInfo.env->GetFieldID(clsApplicationInfo, \"sourceDir\", \"Ljava/lang/String;\");\n\tmethodInfo.env->DeleteLocalRef(sInstance);\n\treturn JniHelper::jstring2string((jstring)methodInfo.env->GetObjectField(ApplicationInfo, id_sourceDir));\n}\n\nstatic std::string GetPackageName() {\n\tJniMethodInfo methodInfo;\n\tjobject sInstance = GetKR2ActInstance();\n\tif (!JniHelper::getMethodInfo(methodInfo, \"android/content/ContextWrapper\", \"getPackageName\", \"()Ljava/lang/String;\")) {\n\t\tmethodInfo.env->DeleteLocalRef(sInstance);\n\t\treturn \"\";\n\t}\n\treturn JniHelper::jstring2string((jstring)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID));\n}\n\n// from unzip.cpp\n#define FLAG_UTF8 (1<<11)\nextern zlib_filefunc64_def TVPZlibFileFunc;\nclass ZipFile\n{\n\tunzFile uf;\n\tbool utf8;\n\npublic:\n\tZipFile() : uf(0) {\n\t}\n\t~ZipFile() {\n\t\tif (uf) {\n\t\t\tunzClose(uf);\n\t\t\tuf = NULL;\n\t\t}\n\t}\n    bool Open(const char *filename) {\n        if ((uf = unzOpen(filename)) == NULL) {\n            ttstr msg = filename;\n            msg += TJS_W(\" can't open.\");\n            TVPThrowExceptionMessage(msg.c_str());\n            return false;\n        }\n        // UTF8�ʥե����������ɤ������ж�������Υե�����ǛQ���\n        unzGoToFirstFile(uf);\n        unz_file_info file_info;\n        if (unzGetCurrentFileInfo(uf, &file_info, NULL, 0, NULL, 0, NULL, 0) == UNZ_OK) {\n            utf8 = (file_info.flag & FLAG_UTF8) != 0;\n            return true;\n        }\n        return false;\n    }\n\tbool GetData(std::vector<unsigned char> &buff, const char *filename) {\n\t\tbool ret = false;\n\t\tif (unzLocateFile(uf, filename, 1) == UNZ_OK) {\n\t\t\tint result = unzOpenCurrentFile(uf);\n\t\t\tif (result == UNZ_OK) {\n\t\t\t\tunz_file_info info;\n\t\t\t\tunzGetCurrentFileInfo(uf, &info, NULL, 0, NULL, 0, NULL, 0);\n\t\t\t\tbuff.resize(info.uncompressed_size);\n\t\t\t\tunsigned int size = unzReadCurrentFile(uf, &buff[0], info.uncompressed_size);\n\t\t\t\tif (size == info.uncompressed_size) ret = true;\n\t\t\t\tunzCloseCurrentFile(uf);\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t}\n    tjs_int64 GetMD5InZip(const char *filename) {\n        std::vector<unsigned char> buff;\n        if(!GetData(buff, filename)) return 0;\n        md5_state_t state;\n        md5_init(&state);\n        md5_append(&state, (const md5_byte_t*)&buff[0], buff.size());\n        union {\n            tjs_int64 _s64[2];\n            tjs_uint8 _u8[16];\n        } digest;\n        md5_finish(&state, digest._u8);\n        return digest._s64[0] ^ digest._s64[1];\n    }\nprivate:\n\tunzFile zipFile;\n};\n\nstd::string TVPGetDeviceLanguage() {\n\t// use pure jni to avoid java code\n\tJniMethodInfo methodInfo;\n\tif (!JniHelper::getStaticMethodInfo(methodInfo, \"java/util/Locale\", \"getDefault\", \"()Ljava/util/Locale;\"))\n\t\treturn \"\";\n\tjobject LocaleObj = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);\n\tif (!JniHelper::getMethodInfo(methodInfo, \"java/util/Locale\", \"getLanguage\", \"()Ljava/lang/String;\"))\n\t\treturn \"\";\n\tjstring languageID = (jstring)methodInfo.env->CallObjectMethod(LocaleObj, methodInfo.methodID);\n\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\treturn JniHelper::jstring2string(languageID);\n}\n\nstd::string TVPGetPackageVersionString() {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, \"GetVersion\", \"()Ljava/lang/String;\")) {\n\t\treturn JniHelper::jstring2string((jstring)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID));\n\t}\n\treturn \"\";\n}\n\nstatic std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {\n\tstd::stringstream ss(s);\n\tstd::string item;\n\twhile (std::getline(ss, item, delim)) {\n\t\telems.emplace_back(item);\n\t}\n\treturn elems;\n}\n\nstatic std::string File_getAbsolutePath(jobject FileObj) {\n\tif (!FileObj) return \"\";\n\tJniMethodInfo methodInfo;\n\tif (!JniHelper::getMethodInfo(methodInfo, \"java/io/File\", \"exists\", \"()Z\")) return \"\";\n\tif (!methodInfo.env->CallBooleanMethod(FileObj, methodInfo.methodID)) return \"\";\n\tif (!JniHelper::getMethodInfo(methodInfo, \"java/io/File\", \"getAbsolutePath\", \"()Ljava/lang/String;\")) return \"\";\n\tjstring path = (jstring)methodInfo.env->CallObjectMethod(FileObj, methodInfo.methodID);\n\tstd::string ret = cocos2d::JniHelper::jstring2string(path);\n\treturn ret;\n}\n\nstatic std::string GetInternalStoragePath() {\n\tjobject sInstance = GetKR2ActInstance();\n\tJniMethodInfo methodInfo;\n\tif (!JniHelper::getMethodInfo(methodInfo, \"android/content/ContextWrapper\", \"getFilesDir\", \"()Ljava/io/File;\")) {\n\t\treturn \"\";\n\t}\n\tjobject FileObj = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID);\n\treturn File_getAbsolutePath(FileObj);\n}\n\nstd::string Android_GetDumpStoragePath() {\n\treturn GetInternalStoragePath() + \"/dump\";\n}\n\nstatic int InsertFilepathInto(JNIEnv *env, std::vector<std::string>& vec, jobjectArray FileObjs) {\n\tint count = env->GetArrayLength(FileObjs);\n\tfor (int i = 0; i < count; ++i) {\n\t\tjobject FileObj = env->GetObjectArrayElement(FileObjs, i);\n\t\tstd::string path = File_getAbsolutePath(FileObj);\n\t\tif (!path.empty()) vec.emplace_back(path);\n\t}\n\treturn count;\n}\n\nstatic int GetExternalStoragePath(std::vector<std::string> &ret) {\n\tint count = 0;\n\tJniMethodInfo methodInfo;\n\tjobject sInstance = GetKR2ActInstance();\n// \tif (JniHelper::getMethodInfo(methodInfo, \"android/content/Context\", \"getExternalMediaDirs\", \"()[Ljava/io/File;\")) {\n// \t\tjobjectArray FileObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID);\n// \t\tif(FileObjs) count += InsertFilepathInto(methodInfo.env, ret, FileObjs);\n// \t}\n\tif (JniHelper::getMethodInfo(methodInfo, \"android/content/Context\", \"getExternalFilesDirs\", \"(Ljava/lang/String;)[Ljava/io/File;\")) {\n\t\tjobjectArray FileObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID, nullptr);\n\t\tif (FileObjs) count += InsertFilepathInto(methodInfo.env, ret, FileObjs);\n\t} else if (JniHelper::getMethodInfo(methodInfo, \"android/content/Context\", \"getExternalFilesDir\", \"(Ljava/lang/String;)Ljava/io/File;\")) {\n\t\tjobject FileObj = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID, nullptr);\n\t\tif (FileObj) {\n\t\t\tret.emplace_back(File_getAbsolutePath(FileObj));\n\t\t\t++count;\n\t\t}\n\t}\n\treturn count;\n}\n\nstd::vector<std::string> TVPGetAppStoragePath() {\n\tstd::vector<std::string> ret;\n\tret.emplace_back(GetInternalStoragePath());\n\tGetExternalStoragePath(ret);\n\treturn ret;\n}\n\nstd::vector<std::string> TVPGetDriverPath() {\n\tstd::vector<std::string> ret;\n\tjobject sInstance = GetKR2ActInstance();\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getMethodInfo(methodInfo, KR2ActJavaPath, \"getStoragePath\", \"()[Ljava/lang/String;\")) {\n\t\tjobjectArray PathObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID);\n\t\tif (PathObjs) {\n\t\t\tint count = methodInfo.env->GetArrayLength(PathObjs);\n\t\t\tfor (int i = 0; i < count; ++i) {\n\t\t\t\tjstring path = (jstring)methodInfo.env->GetObjectArrayElement(PathObjs, i);\n\t\t\t\tif (path) ret.emplace_back(cocos2d::JniHelper::jstring2string(path));\n\t\t\t}\n\t\t}\n\t}\n\t\n\tif (!ret.empty()) return ret;\n\n\tchar buffer[256] = { 0 };\n\n\t// enum all mounted storages\n\tFILE *fp = fopen(\"/proc/mounts\", \"r\");\n\tstd::set<std::string> mounted;\n\twhile (fgets(buffer, sizeof(buffer), fp)) {\n\t\tstd::vector<std::string> tabs;\n\t\tsplit(buffer, ' ', tabs);\n\t\tif (tabs.size() < 3) continue;\n\t\tif (mounted.find(tabs[0]) != mounted.end()) continue;\n\t\tconst std::string &path = tabs[1];\n\t\tif (tabs[3].find(\"rw,\") != std::string::npos && (tabs[2] == \"vfat\" || path.find(\"/mnt\") != std::string::npos)) {\n\t\t\tif (path.find(\"/mnt/secure\") != std::string::npos ||\n\t\t\t\tpath.find(\"/mnt/asec\") != std::string::npos ||\n\t\t\t\tpath.find(\"/mnt/mapper\") != std::string::npos ||\n\t\t\t\tpath.find(\"/mnt/obb\") != std::string::npos ||\n\t\t\t\ttabs[0] == \"tmpfs\" || tabs[2] == \"tmpfs\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmounted.insert(tabs[0]);\n\t\t\tret.emplace_back(path);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n// extern \"C\" int TVPCheckValidate()\n// {\n//     JNIEnv *pEnv = 0;\n//     bool ret = true;\n// \n//     if (! getEnv(&pEnv))\n//     {\n//         return false;\n//     }\n// \t{\n// \t\tjclass classID = pEnv->FindClass(KR2EntryJavaPath);\n// \t\tstd::string strtmp(\"()L\"); strtmp += KR2EntryJavaPath; strtmp += \";\";\n// \t\tjmethodID methodGetInstance = pEnv->GetStaticMethodID(classID, \"GetInstance\", strtmp.c_str());\n// \t\tjobject sInstance = pEnv->CallStaticObjectMethod(classID, methodGetInstance);\n// \t\t\n// \t\tjclass clsPreferenceManager = pEnv->FindClass(\"android.preference.PreferenceManager\");\n// \t\tjmethodID getDefaultSharedPreferences = pEnv->GetMethodID(clsPreferenceManager, \"getDefaultSharedPreferences\", \"(Landroid/content/Context;)Landroid.preference.PreferenceManager;\");\n// \t\tjobject PreferenceManager = pEnv->CallStaticObjectMethod(clsPreferenceManager, getDefaultSharedPreferences, sInstance);\n// \t\tjmethodID getString = pEnv->GetMethodID(clsPreferenceManager, \"getString\", \"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;\");\n// \t\tjstring jstrConstAPPID = pEnv->NewStringUTF(\"APP_ID\");\n// \t\tjstring jstrNull = pEnv->NewStringUTF(\"\");\n// \t\tjstring jstrAPPID = (jstring)pEnv->CallObjectMethod(PreferenceManager, getString, jstrConstAPPID, jstrNull);\n// \t\tpEnv->DeleteLocalRef(jstrConstAPPID);\n// \t\tpEnv->DeleteLocalRef(jstrNull);\n// \t\tconst char *p = pEnv->GetStringUTFChars(jstrAPPID, 0);\n// \t\tif(0x929e08af != adler32(0, (const Bytef*)p, strlen(p))) ret = false;\n// \t\tpEnv->ReleaseStringUTFChars(jstrAPPID, p);\n// \t}\n// \n//     return ret;\n// }\nnamespace kr2android {\n\tstd::condition_variable MessageBoxCond;\n\tstd::mutex MessageBoxLock;\n\tint MsgBoxRet = -2;\n\tstd::string MessageBoxRetText;\n}\nusing namespace kr2android;\n\nint TVPShowSimpleMessageBox(const char *pszText, const char *pszTitle, unsigned int nButton, const char **btnText) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"ShowMessageBox\", \"(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V\"))\n\t{\n\t\tjstring jstrTitle = methodInfo.env->NewStringUTF(pszTitle);\n\t\tjstring jstrText = methodInfo.env->NewStringUTF(pszText);\n\t\tjclass strcls = methodInfo.env->FindClass(\"java/lang/String\");\n\t\tjobjectArray btns = methodInfo.env->NewObjectArray(nButton, strcls, nullptr);\n\t\tfor (unsigned int i = 0; i < nButton; ++i) {\n\t\t\tjstring jstrBtn = methodInfo.env->NewStringUTF(btnText[i]);\n\t\t\tmethodInfo.env->SetObjectArrayElement(btns, i, jstrBtn);\n\t\t\tmethodInfo.env->DeleteLocalRef(jstrBtn);\n\t\t}\n\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrTitle, jstrText, btns);\n\n\t\tmethodInfo.env->DeleteLocalRef(jstrTitle);\n\t\tmethodInfo.env->DeleteLocalRef(jstrText);\n\t\tmethodInfo.env->DeleteLocalRef(btns);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\n\t\tstd::unique_lock<std::mutex> lk(MessageBoxLock);\n\t\twhile (MsgBoxRet == -2) {\n\t\t\tMessageBoxCond.wait_for(lk, std::chrono::milliseconds(200));\n\t\t\tif (MsgBoxRet == -2) {\n\t\t\t\tTVPForceSwapBuffer(); // update opengl events\n\t\t\t}\n\t\t}\n\t\treturn MsgBoxRet;\n\t}\n\treturn -1;\n}\n\nint TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption, const std::vector<ttstr> &vecButtons) {\n\ttTJSNarrowStringHolder pszText(text.c_str());\n\ttTJSNarrowStringHolder pszTitle(caption.c_str());\n\tstd::vector<const char *> btnText; btnText.reserve(vecButtons.size());\n\tstd::vector<std::string> btnTextHold; btnTextHold.reserve(vecButtons.size());\n\tfor (const ttstr &btn : vecButtons) {\n\t\tbtnTextHold.emplace_back(btn.AsStdString());\n\t\tbtnText.emplace_back(btnTextHold.back().c_str());\n\t}\n\treturn TVPShowSimpleMessageBox(pszText, pszTitle, btnText.size(), &btnText[0]);\n}\n\nint TVPShowSimpleInputBox(ttstr &text, const ttstr &caption, const ttstr &prompt, const std::vector<ttstr> &vecButtons) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"ShowInputBox\", \"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V\"))\n\t{\n\t\tjstring jstrTitle = methodInfo.env->NewStringUTF(caption.AsStdString().c_str());\n\t\tjstring jstrText = methodInfo.env->NewStringUTF(text.AsStdString().c_str());\n\t\tjstring jstrPrompt = methodInfo.env->NewStringUTF(prompt.AsStdString().c_str());\n\t\tjclass strcls = methodInfo.env->FindClass(\"java/lang/String\");\n\t\tjobjectArray btns = methodInfo.env->NewObjectArray(vecButtons.size(), strcls, nullptr);\n\t\tfor (unsigned int i = 0; i < vecButtons.size(); ++i) {\n\t\t\tjstring jstrBtn = methodInfo.env->NewStringUTF(vecButtons[i].AsStdString().c_str());\n\t\t\tmethodInfo.env->SetObjectArrayElement(btns, i, jstrBtn);\n\t\t\tmethodInfo.env->DeleteLocalRef(jstrBtn);\n\t\t}\n\n\t\tMsgBoxRet = -2;\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrTitle, jstrPrompt, jstrText, btns);\n\n\t\tmethodInfo.env->DeleteLocalRef(jstrTitle);\n\t\tmethodInfo.env->DeleteLocalRef(jstrText);\n\t\tmethodInfo.env->DeleteLocalRef(jstrPrompt);\n\t\tmethodInfo.env->DeleteLocalRef(btns);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\n\t\tstd::unique_lock<std::mutex> lk(MessageBoxLock);\n\t\twhile (MsgBoxRet == -2) {\n\t\t\tMessageBoxCond.wait_for(lk, std::chrono::milliseconds(200));\n\t\t\tif (MsgBoxRet == -2) {\n\t\t\t\tTVPForceSwapBuffer(); // update opengl events\n\t\t\t}\n\t\t}\n\t\ttext = MessageBoxRetText;\n\t\treturn MsgBoxRet;\n\t}\n\treturn -1;\n}\n\nextern std::string Android_ShowInputDialog(const char* pszTitle, const char *pszInitText);\nextern std::string Android_ShowFileBrowser(const char* pszTitle, const char *pszInitDir, bool showEditor);\nextern ttstr TVPGetAppPath();\nextern ttstr TVPGetLocallyAccessibleName(const ttstr &name);\n\nstd::vector<ttstr> Android_GetExternalStoragePath() {\n\tstatic std::vector<ttstr> ret;\n\tif (ret.empty()) {\n\t\tstd::vector<std::string> pathlist;\n\t\tGetExternalStoragePath(pathlist);\n\t\tfor (const std::string &path : pathlist) {\n\t\t\tstd::string strPath = \"file://.\";\n\t\t\tstrPath += path;\n\t\t\tret.emplace_back(strPath);\n\t\t}\n\t}\n\treturn ret;\n}\n\nttstr Android_GetInternalStoragePath() {\n\tstatic ttstr strPath;\n\tif (strPath.IsEmpty()) {\n\t\tstrPath = \"file://.\";\n\t\tstrPath += GetInternalStoragePath();\n\t}\n\treturn strPath;\n}\n\nttstr Android_GetApkStoragePath() {\n\tstatic ttstr strPath;\n\tif (strPath.IsEmpty()) {\n\t\tstrPath = \"file://.\";\n\t\tstrPath += GetApkStoragePath();\n\t}\n\treturn strPath;\n}\n#if 0\nstruct _eventQueueNode {\n\tstd::function<void()> func;\n\t_eventQueueNode *prev;\n\t_eventQueueNode *next;\n};\n\nstatic std::atomic<_eventQueueNode*> _lastQueuedEvents(nullptr);\nstatic void _processEvents(float) {\n\t_eventQueueNode* q = _lastQueuedEvents.exchange(nullptr);\n\tif (q) {\n\t\tq->next = nullptr;\n\t\twhile (q->prev) {\n\t\t\tq->prev->next = q;\n\t\t\tq = q->prev;\n\t\t}\n\t}\n\twhile (q) {\n\t\tq->func();\n\t\t_eventQueueNode *nq = q->next;\n\t\tdelete q;\n\t\tq = nq;\n\t}\n}\n\nvoid Android_PushEvents(const std::function<void()> &func) {\n\t_eventQueueNode *node = new _eventQueueNode;\n\tnode->func = func;\n\tnode->next = nullptr;\n\tnode->prev = nullptr;\n\twhile (!_lastQueuedEvents.compare_exchange_weak(node->prev, node)) {}\n}\n#endif\nvoid TVPCheckAndSendDumps(const std::string &dumpdir, const std::string &packageName, const std::string &versionStr);\nbool TVPCheckStartupArg() {\n\t// check dump\n\tTVPCheckAndSendDumps(Android_GetDumpStoragePath(), GetPackageName(), TVPGetPackageVersionString());\n#if 0\n\t// register event dispatcher\n\tcocos2d::Director *director = cocos2d::Director::getInstance();\n\tclass HackForScheduler : public cocos2d::Scheduler {\n\tpublic:\n\t\tvoid regProcessEvents() {\n\t\t\tschedulePerFrame(_processEvents, &_lastQueuedEvents, -1, false);\n\t\t}\n\t};\n\tstatic_cast<HackForScheduler*>(director->getScheduler())->regProcessEvents();\n#endif\n\treturn false;\n}\n\n\nvoid Android_PushEvents(const std::function<void()> &func) {\n\tcocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(func);\n}\n\nvoid TVPControlAdDialog(int adType, int arg1, int arg2) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"MessageController\", \"(III)V\")) {\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, adType, arg1, arg2);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t}\n}\n\nstatic int _GetAndroidSDKVersion() {\n\tJNIEnv *pEnv = JniHelper::getEnv();\n\tjclass classID = pEnv->FindClass(\"android/os/Build$VERSION\");\n\tjfieldID idSDK_INT = pEnv->GetStaticFieldID(classID, \"SDK_INT\", \"I\");\n\treturn pEnv->GetStaticIntField(classID, idSDK_INT);\n}\nstatic int GetAndroidSDKVersion() {\n\tstatic int result = _GetAndroidSDKVersion();\n\treturn result;\n}\n\nstatic bool IsLollipop() {\n\treturn GetAndroidSDKVersion() >= 21;\n}\n\nstatic bool IsOreo() {\n\treturn GetAndroidSDKVersion() >= 26;\n}\n\nvoid TVPFetchSDCardPermission() {\n\tif (!IsLollipop())\n\t\treturn;\n\tstd::vector<std::string> paths;\n\tGetExternalStoragePath(paths);\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"requireLEXA\", \"(Ljava/lang/String;)V\")) {\n\t\tjstring jstrPath = methodInfo.env->NewStringUTF(paths.back().c_str());\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrPath);\n\t\tmethodInfo.env->DeleteLocalRef(jstrPath);\n\t\treturn;\n\t}\n\treturn;\n}\n\nbool TVPCheckStartupPath(const std::string &path) {\n\t// check writing permission first\n\tint pos = path.find_last_of('/');\n\tif (pos == path.npos) return false;\n\tstd::string parent = path.substr(0, pos);\n\tstd::string testPath = parent + cocos2d::StringUtils::format(\"/_check_save_%d.tmp\", time(nullptr));\n\tJniMethodInfo methodInfo;\n\tbool success = false;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"isWritableNormal\", \"(Ljava/lang/String;)Z\")) {\n\t\tjstring jstrPath = methodInfo.env->NewStringUTF(testPath.c_str());\n\t\tsuccess = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrPath);\n\t\tmethodInfo.env->DeleteLocalRef(jstrPath);\n\t\tTVPDeleteFile(testPath.c_str());\n#if 0\n\t\tif (success) {\n\t\t\tparent += \"/savedata\";\n\t\t\tif (!TVPCheckExistentLocalFolder(parent)) {\n\t\t\t\tTVPCreateFolders(parent);\n\t\t\t}\n\t\t\tjstrPath = methodInfo.env->NewStringUTF(parent.c_str());\n\t\t\tsuccess = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrPath);\n\t\t\tmethodInfo.env->DeleteLocalRef(jstrPath);\n\t\t}\n#endif\n\t}\n\n\tif (!success) {\n\t\tstd::vector<std::string> paths;\n\t\t// paths.emplace_back(GetInternalStoragePath());\n\t\tGetExternalStoragePath(paths);\n\t\tstd::string pathlist;\n\t\tfor (const std::string &path : paths) {\n\t\t\tpathlist += \"\\n\";\n\t\t\tpathlist += path;\n\t\t}\n\t\tstd::string msg = LocaleConfigManager::GetInstance()->GetText(\"use_internal_path\") + pathlist;\n#if 0\n\t\tif (pathlist.size() > 0) {\n\t\t\tsize_t pos = msg.find(\"%1\");\n\t\t\tif (pos != msg.npos) {\n\t\t\t\tmsg = msg.replace(msg.begin() + pos, msg.begin() + pos + 2, pathlist.back());\n\t\t\t}\n\t\t}\n#endif\n\t\tstd::vector<ttstr> btns;\n\t\tbtns.emplace_back(\"OK\");\n\t\tTVPShowSimpleMessageBox(msg, LocaleConfigManager::GetInstance()->GetText(\"readonly_storage\"), btns);\n\t\treturn false;\n#if 0\n\t\tbtns.push_back(LocaleConfigManager::GetInstance()->GetText(\"continue_run\"));\n\t\tbool isLOLLIPOP = IsLollipop();\n\t\tif (isLOLLIPOP)\n\t\t\tbtns.push_back(LocaleConfigManager::GetInstance()->GetText(\"get_sdcard_permission\"));\n\t\telse\n\t\t\tbtns.push_back(LocaleConfigManager::GetInstance()->GetText(\"cancel\"));\n\t\tint result = TVPShowSimpleMessageBox(msg, LocaleConfigManager::GetInstance()->GetText(\"readonly_storage\"), btns);\n\t\tif (isLOLLIPOP && result == 1) {\n\t\t\tTVPFetchSDCardPermission();\n\t\t}\n\t\tif (result != 0)\n\t\t\treturn false;\n#endif\n\t}\n\n\treturn true;\n}\n\nbool TVPCreateFolders(const ttstr &folder)\n{\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"CreateFolders\", \"(Ljava/lang/String;)Z\")) {\n\t\tjstring jstr = methodInfo.env->NewStringUTF(folder.AsStdString().c_str());\n\t\tbool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr);\n\t\tmethodInfo.env->DeleteLocalRef(jstr);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\treturn ret;\n\t}\n\treturn false;\n}\n\nstatic bool TVPWriteDataToFileJava(const std::string &filename, const void* data, unsigned int size) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"WriteFile\", \"(Ljava/lang/String;[B)Z\")) {\n\t\tcocos2d::FileUtils *fileutil = cocos2d::FileUtils::getInstance();\n\t\tbool ret = false;\n\t\tint retry = 3;\n\t\tdo {\n\t\t\tjstring jstr = methodInfo.env->NewStringUTF(filename.c_str());\n\t\t\tjbyteArray arr = methodInfo.env->NewByteArray(size);\n\t\t\tmethodInfo.env->SetByteArrayRegion(arr, 0, size, (jbyte*)data);\n\t\t\tret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr, arr);\n\t\t\tmethodInfo.env->DeleteLocalRef(arr);\n\t\t\tmethodInfo.env->DeleteLocalRef(jstr);\n\t\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\t} while (!fileutil->isFileExist(filename) && --retry);\n\t\treturn ret;\n\t}\n\treturn false;\n}\n\nbool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int size) {\n\tstd::string filename = filepath.AsStdString();\n\tcocos2d::FileUtils *fileutil = cocos2d::FileUtils::getInstance();\n\twhile (fileutil->isFileExist(filename)) {\n\t\t// for number filename suffix issue\n\t\ttime_t t = time(nullptr);\n\t\tstd::vector<char> buffer;\n\t\tbuffer.resize(filename.size() + 32);\n\t\tsprintf(&buffer.front(), \"%s.%d.bak\", filename.c_str(), (int)t);\n\t\tstd::string tempname = &buffer.front();\n\t\tif (rename(filename.c_str(), tempname.c_str()) == 0) {\n\t\t\t// file api is OK\n\t\t\tFILE *fp = fopen(filename.c_str(), \"wb\");\n\t\t\tif (fp) {\n\t\t\t\tbool ret = fwrite(data, 1, size, fp) == size;\n\t\t\t\tfclose(fp);\n\t\t\t\tremove(tempname.c_str());\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t}\n\t\tbool ret = TVPWriteDataToFileJava(filename, data, size);\n\t\tif (fileutil->isFileExist(tempname.c_str())) {\n\t\t\tTVPDeleteFile(tempname);\n\t\t}\n\t\treturn ret;\n\t}\n\tFILE *fp = fopen(filename.c_str(), \"wb\");\n\tif (fp) {\n\t\t// file api is OK\n\t\tint writed = fwrite(data, 1, size, fp);\n\t\tfclose(fp);\n\t\treturn writed == size;\n\t}\n\treturn TVPWriteDataToFileJava(filename, data, size);\n}\n\nstd::string TVPGetCurrentLanguage() {\n\tJniMethodInfo t;\n\tstd::string ret(\"\");\n\t\n\tif (JniHelper::getStaticMethodInfo(t, \"org/tvp/kirikiri2/KR2Activity\", \"getLocaleName\", \"()Ljava/lang/String;\")) {\n\t\tjstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);\n\t\tt.env->DeleteLocalRef(t.classID);\n\t\tret = JniHelper::jstring2string(str);\n\t\tt.env->DeleteLocalRef(str);\n\t}\n\n\treturn ret;\n}\n\nvoid TVPExitApplication(int code) {\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX);\n\tif (!TVPIsSoftwareRenderManager())\n\t\tiTVPTexture2D::RecycleProcess();\n\tJniMethodInfo t;\n\tif (JniHelper::getStaticMethodInfo(t, \"org/tvp/kirikiri2/KR2Activity\", \"exit\", \"()V\")) {\n\t\tt.env->CallStaticVoidMethod(t.classID, t.methodID);\n\t\tt.env->DeleteLocalRef(t.classID);\n\t}\n\texit(code);\n}\n\nvoid TVPHideIME() {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"hideTextInput\", \"()V\")) {\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);\n\t}\n}\n\nvoid TVPShowIME(int x, int y, int w, int h) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"showTextInput\", \"(IIII)V\")) {\n\t\tmethodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, x, y, w, h);\n\t}\n}\n\nvoid TVPProcessInputEvents() {}\n\nbool TVPDeleteFile(const std::string &filename) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"DeleteFile\", \"(Ljava/lang/String;)Z\")) {\n\t\tjstring jstr = methodInfo.env->NewStringUTF(filename.c_str());\n\t\tbool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr);\n\t\tmethodInfo.env->DeleteLocalRef(jstr);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\treturn ret;\n\t}\n\treturn false;\n}\n\nbool TVPRenameFile(const std::string &from, const std::string &to) {\n\tJniMethodInfo methodInfo;\n\tif (JniHelper::getStaticMethodInfo(methodInfo, \"org/tvp/kirikiri2/KR2Activity\", \"RenameFile\", \"(Ljava/lang/String;Ljava/lang/String;)Z\")) {\n\t\tjstring jstr = methodInfo.env->NewStringUTF(from.c_str());\n\t\tjstring jstr2 = methodInfo.env->NewStringUTF(to.c_str());\n\t\tbool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr, jstr2);\n\t\tmethodInfo.env->DeleteLocalRef(jstr);\n\t\tmethodInfo.env->DeleteLocalRef(jstr2);\n\t\tmethodInfo.env->DeleteLocalRef(methodInfo.classID);\n\t\treturn ret;\n\t}\n\treturn false;\n}\n\ntjs_uint32 TVPGetRoughTickCount32()\n{\n\ttjs_uint32 uptime = 0;\n\tstruct timespec on;\n\tif (clock_gettime(CLOCK_MONOTONIC, &on) == 0)\n\t\tuptime = on.tv_sec * 1000 + on.tv_nsec / 1000000;\n\treturn uptime;\n}\n\nbool TVP_stat(const tjs_char *name, tTVP_stat &s) {\n\ttTJSNarrowStringHolder holder(name);\n\treturn TVP_stat(holder, s);\n}\n\n#undef st_atime\n#undef st_ctime\n#undef st_mtime\n//int stat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21); // force link it !\nbool TVP_stat(const char *name, tTVP_stat &s) {\n\tstruct stat t;\n\t// static_assert(sizeof(t.st_size) == 4, \"\");\n\tstatic_assert(sizeof(t.st_size) == 8, \"\");\n\tbool ret = !stat(name, &t);\n\ts.st_mode = t.st_mode;\n\ts.st_size = t.st_size;\n\ts.st_atime = t.st_atim.tv_sec;\n\ts.st_mtime = t.st_mtim.tv_sec;\n\ts.st_ctime = t.st_ctim.tv_sec;\n\treturn ret;\n}\n\nvoid TVPSendToOtherApp(const std::string &filename) {\n\n}\n"
  },
  {
    "path": "src/core/environ/android/AndroidUtils.h",
    "content": "#pragma once\n#include <jni.h>\n#include <string>\n\nstd::string TVPGetDeviceID();\n"
  },
  {
    "path": "src/core/environ/cocos2d/AppDelegate.cpp",
    "content": "#include \"AppDelegate.h\"\n#include \"MainScene.h\"\n#include \"ui/MainFileSelectorForm.h\"\n#include \"ui/extension/UIExtension.h\"\n#include \"cocostudio/FlatBuffersSerialize.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n#include \"Application.h\"\n#include \"Platform.h\"\n#include \"ui/MessageBox.h\"\n#include \"ui/GlobalPreferenceForm.h\"\n#include \"CustomFileUtils.h\"\n\nUSING_NS_CC;\n\ncocos2d::FileUtils *TVPCreateCustomFileUtils();\nextern \"C\" void SDL_SetMainReady(void);\nextern std::thread::id TVPMainThreadID;\nstatic Size designResolutionSize(960, 640);\nbool TVPCheckStartupArg();\ncocos2d::FileUtils *TVPCreateCustomFileUtils();\n\nvoid TVPAppDelegate::applicationWillEnterForeground() {\n\t::Application->OnActivate();\n\tDirector::getInstance()->startAnimation();\n}\n\nvoid TVPAppDelegate::applicationDidEnterBackground() {\n\t::Application->OnDeactivate();\n\tDirector::getInstance()->stopAnimation();\n}\n\nbool TVPAppDelegate::applicationDidFinishLaunching() {\n\tSDL_SetMainReady();\n\tTVPMainThreadID = std::this_thread::get_id();\n\tcocos2d::log(\"applicationDidFinishLaunching\");\n\t// initialize director\n\tFileUtils::setDelegate(TVPCreateCustomFileUtils());\n\tauto director = Director::getInstance();\n\tauto glview = director->getOpenGLView();\n\tif (!glview) {\n\t\tglview = GLViewImpl::create(\"kirikiri2 frame\");\n\t\tdirector->setOpenGLView(glview);\n#if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM\n\t\tglview->setFrameSize(960, 640);\n#endif\n\t}\n\t// Set the design resolution\n\tSize screenSize = glview->getFrameSize();\n\tif (screenSize.width < screenSize.height) {\n\t\tstd::swap(screenSize.width, screenSize.height);\n\t}\n\tSize designSize = designResolutionSize;\n\tdesignSize.height = designSize.width * screenSize.height / screenSize.width;\n\tglview->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::SHOW_ALL);\n\n\tSize frameSize = glview->getFrameSize();\n\n\tstd::vector<std::string> searchPath;\n\n\t// In this demo, we select resource according to the frame's height.\n\t// If the resource size is different from design resolution size, you need to set contentScaleFactor.\n\t// We use the ratio of resource's height to the height of design resolution,\n\t// this can make sure that the resource's height could fit for the height of design resolution.\n\tsearchPath.emplace_back(\"res\");\n\n\tTVPSkinManager::getInstance()->InitSkin();\n\n\t// set searching path\n\tFileUtils::getInstance()->setSearchPaths(searchPath);\n\n\t// turn on display FPS\n\tdirector->setDisplayStats(false);\n\n\t// set FPS. the default value is 1.0/60 if you don't call this\n\tdirector->setAnimationInterval(1.0f / 60);\n\n\tTVPInitUIExtension();\n\n\t// initialize something\n\tLocaleConfigManager::GetInstance()->Initialize(TVPGetCurrentLanguage());\n\t// create a scene. it's an autorelease object\n\tTVPMainScene *scene = TVPMainScene::CreateInstance();\n\n\t// run\n\tdirector->runWithScene(scene);\n\n\t//director->getConsole()->listenOnTCP(16006);\n\n\tscene->scheduleOnce([](float dt){\n\t\tTVPMainScene::GetInstance()->unschedule(\"launch\");\n\t\tTVPGlobalPreferenceForm::Initialize();\n\t\tif (!TVPCheckStartupArg()) {\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPMainFileSelectorForm::create());\n\t\t}\n\t}, 0, \"launch\");\n\n\treturn true;\n}\n\nvoid TVPAppDelegate::initGLContextAttrs() {\n\tGLContextAttrs glContextAttrs = {\n\t\t8, 8, 8, 8, 24, 8\n\t};\n\tGLView::setGLContextAttrs(glContextAttrs);\n}\n\nvoid TVPAppDelegate::applicationScreenSizeChanged(int newWidth, int newHeight)\n{\n// \tauto director = Director::getInstance();\n// \tdirector->getOpenGLView()->setFrameSize(newWidth, newHeight);\n}\n\nvoid TVPOpenPatchLibUrl() {\n\tcocos2d::Application::getInstance()->openURL(\"https://zeas2.github.io/Kirikiroid2_patch/patch\");\n}\n"
  },
  {
    "path": "src/core/environ/cocos2d/AppDelegate.h",
    "content": "#pragma once\n#include \"cocos2d.h\"\n\nclass TVPAppDelegate : public cocos2d::Application {\n\n\tvirtual void initGLContextAttrs();\n\n\t/**\n\t@brief    Implement Director and Scene init code here.\n\t@return true    Initialize success, app continue.\n\t@return false   Initialize failed, app terminate.\n\t*/\n\tvirtual bool applicationDidFinishLaunching();\n\n\t/**\n\t@brief  The function be called when the application enter background\n\t@param  the pointer of the application\n\t*/\n\tvirtual void applicationDidEnterBackground();\n\n\t/**\n\t@brief  The function be called when the application enter foreground\n\t@param  the pointer of the application\n\t*/\n\tvirtual void applicationWillEnterForeground();\n\n\tvirtual void applicationScreenSizeChanged(int newWidth, int newHeight);\n};"
  },
  {
    "path": "src/core/environ/cocos2d/CCKeyCodeConv.cpp",
    "content": "#include \"CCKeyCodeConv.h\"\n#include \"cocos/base/CCController.h\"\n#include \"vkdefine.h\"\n\nint TVPConvertMouseBtnToVKCode(tTVPMouseButton _mouseBtn)\n{\n\tint btncode;\n\tswitch (_mouseBtn) {\n\tcase mbLeft:    btncode = VK_LBUTTON;\tbreak;\n\tcase mbMiddle:  btncode = VK_MBUTTON;\tbreak;\n\tcase mbRight:   btncode = VK_RBUTTON;\tbreak;\n\tdefault:\t\tbtncode = 0;\t\t\tbreak;\n\t}\n\treturn btncode;\n}\n\nint TVPConvertKeyCodeToVKCode(cocos2d::EventKeyboard::KeyCode keyCode)\n{\n#define CASE(x) case cocos2d::EventKeyboard::KeyCode::KEY_##x:\treturn VK_##x\n\tswitch (keyCode) {\n\t\tCASE(0);\n\t\tCASE(1);\n\t\tCASE(2);\n\t\tCASE(3);\n\t\tCASE(4);\n\t\tCASE(5);\n\t\tCASE(6);\n\t\tCASE(7);\n\t\tCASE(8);\n\t\tCASE(9);\n\t\tCASE(A);\n\t\tCASE(B);\n\t\tCASE(C);\n\t\tCASE(D);\n\t\tCASE(E);\n\t\tCASE(F);\n\t\tCASE(G);\n\t\tCASE(H);\n\t\tCASE(I);\n\t\tCASE(J);\n\t\tCASE(K);\n\t\tCASE(L);\n\t\tCASE(M);\n\t\tCASE(N);\n\t\tCASE(O);\n\t\tCASE(P);\n\t\tCASE(Q);\n\t\tCASE(R);\n\t\tCASE(S);\n\t\tCASE(T);\n\t\tCASE(U);\n\t\tCASE(V);\n\t\tCASE(W);\n\t\tCASE(X);\n\t\tCASE(Y);\n\t\tCASE(Z);\n\t\tCASE(F1);\n\t\tCASE(F2);\n\t\tCASE(F3);\n\t\tCASE(F4);\n\t\tCASE(F5);\n\t\tCASE(F6);\n\t\tCASE(F7);\n\t\tCASE(F8);\n\t\tCASE(F9);\n\t\tCASE(F10);\n\t\tCASE(F11);\n\t\tCASE(F12);\n\t\tCASE(PAUSE);\n\t\tCASE(PRINT);\n\t\tCASE(ESCAPE);\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_BACK_TAB:\n\t\tCASE(TAB);\n\t\tCASE(RETURN);\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_SCROLL_LOCK:\treturn VK_SCROLL;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_SYSREQ:\treturn VK_SNAPSHOT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_BREAK:\treturn VK_CANCEL;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE:\treturn VK_BACK;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPS_LOCK:\treturn VK_CAPITAL;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_SHIFT:\treturn VK_SHIFT; // LR the same\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_SHIFT:\treturn VK_SHIFT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_CTRL:\treturn VK_CONTROL; // LR the same\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_CTRL:\treturn VK_CONTROL;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ALT:\treturn VK_MENU;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ALT:\treturn VK_MENU;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_MENU:\treturn VK_APPS;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_HYPER:\treturn VK_LWIN;\n\t\tCASE(INSERT);\n\t\tCASE(HOME);\n\t\tCASE(DELETE);\n\t\tCASE(END);\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_PG_UP:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PG_UP:\treturn VK_PRIOR;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_PG_DOWN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PG_DOWN:\treturn VK_NEXT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_LEFT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ARROW:\treturn VK_LEFT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_RIGHT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ARROW:\treturn VK_RIGHT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_UP:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_UP_ARROW:\treturn VK_UP;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_DOWN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DOWN_ARROW:\treturn VK_DOWN;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_NUM_LOCK:\treturn VK_NUMLOCK;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_PLUS:\treturn VK_ADD;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_MINUS:\treturn VK_SUBTRACT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_MULTIPLY:\treturn VK_MULTIPLY;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_DIVIDE:\treturn VK_DIVIDE;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_ENTER:\treturn VK_RETURN;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_HOME:\treturn VK_HOME;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_FIVE:\treturn VK_NUMPAD5;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_END:\treturn VK_END;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_INSERT:\treturn VK_INSERT;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_KP_DELETE:\treturn VK_DELETE;\n\t\tCASE(SPACE);\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_EXCLAM:\treturn VK_SPACE;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_QUOTE:\treturn VK_OEM_7;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_COMMA:\treturn VK_OEM_COMMA;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_MINUS:\treturn VK_OEM_MINUS;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PERIOD:\treturn VK_OEM_PERIOD;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_EQUAL: return VK_OEM_PLUS;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_SLASH:\treturn VK_OEM_2;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_SEMICOLON:\treturn VK_OEM_1;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_BACK_SLASH:\treturn VK_OEM_5;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_BRACE:\treturn VK_OEM_4;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_BRACE:\treturn VK_OEM_6;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PLAY:\treturn VK_PLAY;\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_NUMBER:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DOLLAR:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PERCENT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CIRCUMFLEX:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_AMPERSAND:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_APOSTROPHE:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_PARENTHESIS:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_PARENTHESIS:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_ASTERISK:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_COLON:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LESS_THAN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_PLUS:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_GREATER_THAN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_QUESTION:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_AT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_A:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_B:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_C:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_D:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_E:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_F:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_G:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_H:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_I:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_J:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_K:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_L:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_M:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_N:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_O:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_P:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Q:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_R:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_S:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_T:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_U:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_V:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_W:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_X:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Y:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Z:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_LEFT_BRACKET:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_BRACKET:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_UNDERSCORE:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_GRAVE:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_BAR:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_TILDE:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_EURO:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_POUND:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_YEN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_MIDDLE_DOT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_SEARCH:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DPAD_LEFT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DPAD_RIGHT:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DPAD_UP:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DPAD_DOWN:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_DPAD_CENTER:\n\tcase cocos2d::EventKeyboard::KeyCode::KEY_ENTER:\n\tdefault: return 0;\n\t}\n#undef CASE\n}\n\nint TVPConvertPadKeyCodeToVKCode(int keyCode)\n{\n\tswitch (keyCode) {\n\tcase cocos2d::Controller::BUTTON_A: return VK_PAD1;\n\tcase cocos2d::Controller::BUTTON_B: return VK_PAD2;\n\tcase cocos2d::Controller::BUTTON_C: return VK_PAD3;\n\tcase cocos2d::Controller::BUTTON_X: return VK_PAD4;\n\tcase cocos2d::Controller::BUTTON_Y: return VK_PAD5;\n\tcase cocos2d::Controller::BUTTON_Z: return VK_PAD6;\n\tcase cocos2d::Controller::BUTTON_LEFT_SHOULDER: return VK_PAD7;\n\tcase cocos2d::Controller::BUTTON_RIGHT_SHOULDER: return VK_PAD8;\n\tcase cocos2d::Controller::BUTTON_LEFT_THUMBSTICK: return VK_PAD9;\n\tcase cocos2d::Controller::BUTTON_RIGHT_THUMBSTICK: return VK_PAD10;\n\tcase cocos2d::Controller::BUTTON_START: return VK_PAD9;\n\tcase cocos2d::Controller::BUTTON_SELECT: return VK_PAD10;\n\tcase cocos2d::Controller::AXIS_LEFT_TRIGGER: return VK_PAD5;\n\tcase cocos2d::Controller::AXIS_RIGHT_TRIGGER: return VK_PAD6;\n\tcase cocos2d::Controller::BUTTON_PAUSE: return VK_PAD7;\n\tcase cocos2d::Controller::BUTTON_DPAD_UP: return VK_PADUP;\n\tcase cocos2d::Controller::BUTTON_DPAD_DOWN: return VK_PADDOWN;\n\tcase cocos2d::Controller::BUTTON_DPAD_LEFT: return VK_PADLEFT;\n\tcase cocos2d::Controller::BUTTON_DPAD_RIGHT: return VK_PADRIGHT;\n\tcase cocos2d::Controller::BUTTON_DPAD_CENTER:\n\tdefault: return 0;\n\t}\n}\n\n\nconst std::unordered_map<std::string, int> & TVPGetVKCodeNameMap()\n{\n\tstatic std::unordered_map<std::string, int> ret({\n#define CASE(x) { #x, VK_##x }\n\t\tCASE(0),\n\t\tCASE(1),\n\t\tCASE(2),\n\t\tCASE(3),\n\t\tCASE(4),\n\t\tCASE(5),\n\t\tCASE(6),\n\t\tCASE(7),\n\t\tCASE(8),\n\t\tCASE(9),\n\t\tCASE(A),\n\t\tCASE(B),\n\t\tCASE(C),\n\t\tCASE(D),\n\t\tCASE(E),\n\t\tCASE(F),\n\t\tCASE(G),\n\t\tCASE(H),\n\t\tCASE(I),\n\t\tCASE(J),\n\t\tCASE(K),\n\t\tCASE(L),\n\t\tCASE(M),\n\t\tCASE(N),\n\t\tCASE(O),\n\t\tCASE(P),\n\t\tCASE(Q),\n\t\tCASE(R),\n\t\tCASE(S),\n\t\tCASE(T),\n\t\tCASE(U),\n\t\tCASE(V),\n\t\tCASE(W),\n\t\tCASE(X),\n\t\tCASE(Y),\n\t\tCASE(Z),\n\t\tCASE(F1),\n\t\tCASE(F2),\n\t\tCASE(F3),\n\t\tCASE(F4),\n\t\tCASE(F5),\n\t\tCASE(F6),\n\t\tCASE(F7),\n\t\tCASE(F8),\n\t\tCASE(F9),\n\t\tCASE(F10),\n\t\tCASE(F11),\n\t\tCASE(F12),\n\t\tCASE(PAUSE),\n\t\tCASE(PRINT),\n\t\tCASE(ESCAPE),\n\t\tCASE(TAB),\n\t\tCASE(RETURN),\n\t\tCASE(SCROLL),\n\t\tCASE(SNAPSHOT),\n\t\tCASE(CANCEL),\n\t\tCASE(BACK),\n\t\tCASE(CAPITAL),\n\t\tCASE(SHIFT),\n\t\tCASE(CONTROL),\n\t\tCASE(MENU),\n\t\tCASE(APPS),\n\t\tCASE(LWIN),\n\t\tCASE(INSERT),\n\t\tCASE(HOME),\n\t\tCASE(DELETE),\n\t\tCASE(END),\n\t\tCASE(PRIOR),\n\t\tCASE(NEXT),\n\t\tCASE(LEFT),\n\t\tCASE(RIGHT),\n\t\tCASE(UP),\n\t\tCASE(DOWN),\n\t\tCASE(NUMLOCK),\n\t\tCASE(ADD),\n\t\tCASE(SUBTRACT),\n\t\tCASE(MULTIPLY),\n\t\tCASE(DIVIDE),\n\t\tCASE(HOME),\n\t\tCASE(NUMPAD5),\n\t\tCASE(END),\n\t\tCASE(INSERT),\n\t\tCASE(DELETE),\n\t\tCASE(SPACE),\n\t\tCASE(OEM_COMMA),\n\t\tCASE(OEM_MINUS),\n\t\tCASE(OEM_PERIOD),\n\t\tCASE(OEM_PLUS),\n\t\tCASE(OEM_1),\n\t\tCASE(OEM_2),\n\t\tCASE(OEM_4),\n\t\tCASE(OEM_5),\n\t\tCASE(OEM_6),\n\t\tCASE(OEM_7),\n\t\tCASE(PLAY),\n#undef CASE\n\t});\n\treturn ret;\n}\n\nstd::string TVPGetVKCodeName(int keyCode)\n{\n\treturn \"\";\n}\n"
  },
  {
    "path": "src/core/environ/cocos2d/CCKeyCodeConv.h",
    "content": "#include \"tjsTypes.h\"\n#include \"tvpinputdefs.h\"\n#include \"cocos2d.h\"\n\nint TVPConvertMouseBtnToVKCode(tTVPMouseButton _mouseBtn);\nint TVPConvertKeyCodeToVKCode(cocos2d::EventKeyboard::KeyCode keyCode);\nint TVPConvertPadKeyCodeToVKCode(int keyCode);\nconst std::unordered_map<std::string, int> &TVPGetVKCodeNameMap();\nstd::string TVPGetVKCodeName(int keyCode);"
  },
  {
    "path": "src/core/environ/cocos2d/CustomFileUtils.cpp",
    "content": "#include \"CustomFileUtils.h\"\n#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32\n#include \"platform/win32/CCFileUtils-win32.h\"\n#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS\n#import <Foundation/NSBundle.h>\n#import \"platform/apple/CCFileUtils-apple.h\"\n#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n#include \"platform/android/CCFileUtils-android.h\"\n#endif\n#ifdef MINIZIP_FROM_SYSTEM\n#include <minizip/unzip.h>\n#else // from our embedded sources\n#include \"external/unzip/unzip.h\"\n#endif\n#include \"ConfigManager/LocaleConfigManager.h\"\n\nNS_CC_BEGIN\n\ntypedef\n#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32\nFileUtilsWin32\n#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS\nFileUtilsApple\n#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\nFileUtilsAndroid\n#endif\nFileUtilsInherit;\n\nclass CustomFileUtils : public FileUtilsInherit\n{\npublic:\n\tCustomFileUtils();\n\n\tvoid addAutoSearchArchive(const std::string& path);\n\tvirtual std::string fullPathForFilename(const std::string &filename) const override;\n\tvirtual std::string getStringFromFile(const std::string& filename);\n\tvirtual Data getDataFromFile(const std::string& filename);\n\tvirtual unsigned char* getFileData(const std::string& filename, const char* mode, ssize_t *size);\n\tvirtual bool isFileExistInternal(const std::string& strFilePath) const override;\n\tvirtual bool isDirectoryExistInternal(const std::string& dirPath) const override;\n\tvirtual bool init() override {\n\t\treturn FileUtilsInherit::init();\n\t}\n\nprivate:\n\tunsigned char* getFileDataFromArchive(const std::string& filename, ssize_t *size);\n\n\tstd::unordered_map<std::string, std::pair<unzFile, unz_file_pos> > _autoSearchArchive;\n\tstd::mutex _lock;\n};\n\nCustomFileUtils::CustomFileUtils()\n{\n}\n\nvoid CustomFileUtils::addAutoSearchArchive(const std::string& path)\n{\n\tif (!this->isFileExist(path)) return;\n\tunzFile file = nullptr;\n\tfile = unzOpen(FileUtils::getInstance()->getSuitableFOpen(path).c_str());\n\tunz_file_info file_info;\n\tdo {\n\t\tunz_file_pos entry;\n\t\tif (unzGetFilePos(file, &entry) == UNZ_OK) {\n\t\t\tchar filename_inzip[1024];\n\t\t\tif (unzGetCurrentFileInfo(file, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0) == UNZ_OK) {\n\t\t\t\t_autoSearchArchive[filename_inzip] = std::make_pair(file, entry);\n\t\t\t}\n\t\t}\n\t} while (unzGoToNextFile(file) == UNZ_OK);\n}\n\nstd::string CustomFileUtils::fullPathForFilename(const std::string &filename) const\n{\n\tauto it = _autoSearchArchive.find(filename);\n\tif (_autoSearchArchive.end() != it) {\n\t\treturn filename;\n\t}\n\treturn FileUtilsInherit::fullPathForFilename(filename);\n}\n\nunsigned char* CustomFileUtils::getFileData(const std::string& filename, const char* mode, ssize_t *size)\n{\n\tunsigned char* ret = getFileDataFromArchive(filename, size);\n\tif (ret) return ret;\n\treturn FileUtilsInherit::getFileData(filename, mode, size);\n}\n\nbool CustomFileUtils::isFileExistInternal(const std::string& strFilePath) const\n{\n\tauto it = _autoSearchArchive.find(strFilePath);\n\tif (_autoSearchArchive.end() != it) {\n\t\treturn true;\n\t}\n\treturn FileUtilsInherit::isFileExistInternal(strFilePath);\n}\n\nbool CustomFileUtils::isDirectoryExistInternal(const std::string& dirPath) const\n{\n\tfor (auto &it : _autoSearchArchive) {\n\t\tif (it.first.size() <= dirPath.size()) continue;\n\t\tif (!strncmp(it.first.c_str(), dirPath.c_str(), dirPath.size()) && it.first[dirPath.size()] == '/') {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn FileUtilsInherit::isDirectoryExistInternal(dirPath);\n}\n\nunsigned char* CustomFileUtils::getFileDataFromArchive(const std::string& filename, ssize_t *size)\n{\n\tauto it = _autoSearchArchive.find(filename);\n\tif (_autoSearchArchive.end() != it) {\n\t\t_lock.lock();\n\t\tif (unzGoToFilePos(it->second.first, &it->second.second) != UNZ_OK) return nullptr;\n\t\tunz_file_info fileInfo;\n\t\tif (unzGetCurrentFileInfo(it->second.first, &fileInfo, NULL, 0, NULL, 0, NULL, 0) != UNZ_OK) return nullptr;\n\t\tunsigned char *buffer = (unsigned char*)malloc(fileInfo.uncompressed_size);\n\t\tint readedSize = unzReadCurrentFile(it->second.first, buffer, static_cast<unsigned>(fileInfo.uncompressed_size));\n\t\t_lock.unlock();\n\t\tCCASSERT(readedSize == 0 || readedSize == (int)fileInfo.uncompressed_size, \"the file size is wrong\");\n\t\t*size = fileInfo.uncompressed_size;\n\t\treturn buffer;\n\t}\n\treturn nullptr;\n}\n\ncocos2d::Data CustomFileUtils::getDataFromFile(const std::string& filename)\n{\n\tssize_t size;\n\tunsigned char* buffer = getFileDataFromArchive(filename, &size);\n\tif (buffer) {\n\t\tData ret;\n\t\tret.fastSet(buffer, size);\n\t\treturn ret;\n\t}\n\treturn FileUtilsInherit::getDataFromFile(filename);\n}\n\nstd::string CustomFileUtils::getStringFromFile(const std::string& filename)\n{\n\tData data = getDataFromFile(filename);\n\tif (data.isNull())\n\t\treturn \"\";\n\n\tstd::string ret((const char*)data.getBytes());\n\treturn ret;\n}\n\nNS_CC_END\n\ncocos2d::FileUtils *TVPCreateCustomFileUtils() {\n\tcocos2d::CustomFileUtils *ret = new cocos2d::CustomFileUtils;\n\tret->init();\n\treturn ret;\n}\n\nvoid TVPAddAutoSearchArchive(const std::string &path)\n{\n\tcocos2d::CustomFileUtils *fileutils =static_cast<cocos2d::CustomFileUtils*>(cocos2d::FileUtils::getInstance());\n\tfileutils->addAutoSearchArchive(path);\n}\n\n#include \"StorageImpl.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n#include \"tinyxml2/tinyxml2.h\"\n\nUSING_NS_CC;\n\nstatic bool TVPCopyFolder(const std::string &from, const std::string &to) {\n\tif (!TVPCheckExistentLocalFolder(to) && !TVPCreateFolders(to)) {\n\t\treturn false;\n\t}\n\n\tbool success = true;\n\tTVPListDir(from, [&](const std::string &_name, int mask) {\n\t\tif (_name == \".\" || _name == \"..\") return;\n\t\tif (!success) return;\n\t\tif (mask & S_IFREG) {\n\t\t\tsuccess = TVPCopyFile(from + \"/\" + _name, to + \"/\" + _name);\n\t\t}\n\t\telse if (mask & S_IFDIR) {\n\t\t\tsuccess = TVPCopyFolder(from + \"/\" + _name, to + \"/\" + _name);\n\t\t}\n\t});\n\treturn success;\n}\n\nbool TVPCopyFile(const std::string &from, const std::string &to)\n{\n\tFILE * ffrom = fopen(from.c_str(), \"rb\");\n\tif (!ffrom) { // try folder copy\n\t\treturn TVPCopyFolder(from, to);\n\t}\n\tFILE * fto = fopen(to.c_str(), \"wb\");\n\tif (!fto) {\n\t\tif (ffrom) fclose(ffrom);\n\t\treturn false;\n\t}\n\tconst int bufSize = 1 * 1024 * 1024;\n\tstd::vector<char> buffer; buffer.resize(bufSize);\n\tint readed = 0;\n\twhile ((readed = fread(&buffer.front(), 1, bufSize, ffrom))) {\n\t\tfwrite(&buffer.front(), 1, readed, fto);\n\t}\n\tfclose(ffrom);\n\tfclose(fto);\n\treturn true;\n}\n\nTVPSkinManager* TVPSkinManager::getInstance()\n{\n\tstatic TVPSkinManager instance;\n\treturn &instance;\n}\n\nvoid TVPSkinManager::InitSkin()\n{\n\tstd::string skinpath = GlobalConfigManager::GetInstance()->GetValue<std::string>(\"skin_path\", \"\");\n\tif (!skinpath.empty()) {\n\t\tif (!Check(skinpath)) {\n\t\t\tTVPShowSimpleMessageBox(\n\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"invalid_skin_desc\"),\n\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"invalid_skin\"));\n\t\t\tReset();\n\t\t} else {\n\t\t\tstatic_cast<CustomFileUtils*>(FileUtils::getInstance())->addAutoSearchArchive(skinpath);\n\t\t}\n\t}\n}\n\nstatic const char *_adapted_skin_version = \"1.3.4\";\n\nbool TVPSkinManager::Check(const std::string &path)\n{\n\tif (!cocos2d::FileUtils::getInstance()->isFileExist(path)) {\n\t\treturn false;\n\t}\n\n\ttinyxml2::XMLDocument doc;\n\n\tunzFile file = nullptr;\n\tfile = unzOpen(FileUtils::getInstance()->getSuitableFOpen(path).c_str());\n\tunz_file_info file_info;\n\tdo {\n\t\tunz_file_pos entry;\n\t\tif (unzGetFilePos(file, &entry) == UNZ_OK) {\n\t\t\tchar filename_inzip[1024];\n\t\t\tif (unzGetCurrentFileInfo(file, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0) == UNZ_OK) {\n\t\t\t\tif (strcmp(filename_inzip, \"meta.xml\")) {\n\t\t\t\t\tif (unzGoToFilePos(&file, &entry) != UNZ_OK)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tunsigned char *buffer = (unsigned char*)malloc(file_info.uncompressed_size);\n\t\t\t\t\tint readedSize = unzReadCurrentFile(&file, buffer, static_cast<unsigned>(file_info.uncompressed_size));\n\t\t\t\t\tif (readedSize != (int)file_info.uncompressed_size) {\n\t\t\t\t\t\tfree(buffer);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdoc.Parse((char*)buffer);\n\t\t\t\t\tfree(buffer);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while (unzGoToNextFile(file) == UNZ_OK);\n\tunzClose(file);\n\n\ttinyxml2::XMLElement* root = doc.RootElement();\n\tif (!root)\n\t\treturn false;\n\n\tconst char *s = root->Attribute(\"version\");\n\tif (!s)\n\t\treturn false;\n\t\n\treturn !strcmp(s, _adapted_skin_version);\n}\n\nvoid TVPSkinManager::Reset()\n{\n\tGlobalConfigManager::GetInstance()->SetValue(\"skin_path\", \"\");\n\tGlobalConfigManager::GetInstance()->SaveToFile();\n}\n\nbool TVPSkinManager::Use(const std::string &skin_path)\n{\n\tGlobalConfigManager::GetInstance()->SetValue(\"skin_path\", skin_path);\n\tGlobalConfigManager::GetInstance()->SaveToFile();\n\treturn true;\n}\n\nbool TVPSkinManager::InstallAndUse(const std::string &skin_path)\n{\n\tstd::string path = FileUtils::getInstance()->getWritablePath() + \"default.skin\";\n\tFileUtils::getInstance()->removeFile(path);\n\tif (!TVPCopyFile(skin_path, path)) {\n\t\treturn false;\n\t}\n\tGlobalConfigManager::GetInstance()->SetValue(\"skin_path\", path);\n\treturn true;\n}\n"
  },
  {
    "path": "src/core/environ/cocos2d/CustomFileUtils.h",
    "content": "#pragma once\n#include \"cocos2d.h\"\n\nvoid TVPAddAutoSearchArchive(const std::string &path);\nclass TVPSkinManager {\npublic:\n\tstatic TVPSkinManager* getInstance();\n\n\tvoid InitSkin();\n\tstatic bool Check(const std::string &skin_path);\n\tstatic void Reset();\n\tstatic bool Use(const std::string &skin_path);\n\tstatic bool InstallAndUse(const std::string &skin_path);\n};\n"
  },
  {
    "path": "src/core/environ/cocos2d/CustomFileUtils.mm",
    "content": "#include \"CustomFileUtils.cpp\""
  },
  {
    "path": "src/core/environ/cocos2d/MainScene.cpp",
    "content": "#include \"MainScene.h\"\n#include \"cocos2d.h\"\n#include \"cocos-ext.h\"\n#include \"tjsCommHead.h\"\n#include \"StorageIntf.h\"\n#include \"EventIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"WindowImpl.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerBitmapImpl.h\"\n#include \"ui/BaseForm.h\"\n#include \"ui/GameMainMenu.h\"\n#include \"ui/UIHelper.h\"\n#include \"TickCount.h\"\n#include \"Random.h\"\n#include \"UtilStreams.h\"\n#include \"vkdefine.h\"\n#include \"base/CCEventListenerController.h\"\n#include \"base/CCController.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"Platform.h\"\n#include \"ui/ConsoleWindow.h\"\n#include \"ui/FileSelectorForm.h\"\n#include \"ui/DebugViewLayerForm.h\"\n#include \"ui/UIButton.h\"\n#include \"Application.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"win32/TVPWindow.h\"\n#include \"VelocityTracker.h\"\n#include \"SystemImpl.h\"\n#include \"RenderManager.h\"\n#include \"VideoOvlIntf.h\"\n#include \"Exception.h\"\n#include \"win32/SystemControl.h\"\n\nUSING_NS_CC;\n\nenum SCENE_ORDER {\n\tGAME_SCENE_ORDER,\n\tGAME_CONSOLE_ORDER,\n\tGAME_WINMGR_ORDER, // also for the virtual mouse cursor\n\tGAME_MENU_ORDER,\n\tUI_NODE_ORDER,\n};\n\nconst float UI_CHANGE_DURATION = 0.3f;\nclass TVPWindowLayer;\nstatic TVPWindowLayer *_lastWindowLayer, *_currentWindowLayer;\nclass TVPWindowManagerOverlay;\nstatic TVPWindowManagerOverlay *_windowMgrOverlay = nullptr;\nstatic TVPConsoleWindow* _consoleWin = nullptr;\nstatic float _touchMoveThresholdSq;\nstatic cocos2d::Node *_mouseCursor;\nstatic float _mouseCursorScale;\nstatic Vec2 _mouseTouchPoint, _mouseBeginPoint;\nstatic std::set<Touch*> _mouseTouches;\nstatic tTVPMouseButton _mouseBtn;\nstatic int _touchBeginTick;\nstatic bool _virutalMouseMode = false;\nstatic bool _mouseMoved, _mouseClickedDown;\nstatic tjs_uint8 _scancode[0x200];\nstatic tjs_uint16 _keymap[0x200];\nstatic Label *_fpsLabel = nullptr;\n\n#include \"CCKeyCodeConv.h\"\n\n#ifndef GL_UNPACK_ROW_LENGTH\n#define GL_UNPACK_ROW_LENGTH 0x0CF2\n#endif\n\nstatic void(*_postUpdate)() = nullptr;\nvoid TVPSetPostUpdateEvent(void(*f)()) { _postUpdate = f; }\n\nstatic void _refadeMouseCursor() {\n\t_mouseCursor->stopAllActions();\n\t_mouseCursor->setOpacity(255);\n\t_mouseCursor->runAction(Sequence::createWithTwoActions(DelayTime::create(3), FadeOut::create(0.3f)));\n}\n\nstatic void AdjustNumerAndDenom(tjs_int &n, tjs_int &d)\n{\n\ttjs_int a = n;\n\ttjs_int b = d;\n\twhile (b)\n\t{\n\t\ttjs_int t = b;\n\t\tb = a % b;\n\t\ta = t;\n\t}\n\tn = n / a;\n\td = d / a;\n}\n\nbool TVPGetKeyMouseAsyncState(tjs_uint keycode, bool getcurrent)\n{\n\tif (keycode >= sizeof(_scancode) / sizeof(_scancode[0])) return false;\n\ttjs_uint8 code = _scancode[keycode];\n\t_scancode[keycode] &= 1;\n\treturn code & (getcurrent ? 1 : 0x10);\n}\n\nbool TVPGetJoyPadAsyncState(tjs_uint keycode, bool getcurrent)\n{\n\tif (keycode >= sizeof(_scancode) / sizeof(_scancode[0])) return false;\n\ttjs_uint8 code = _scancode[keycode];\n\t_scancode[keycode] &= 1;\n\treturn code & (getcurrent ? 1 : 0x10);\n}\n\nvoid TVPForceSwapBuffer();\nvoid TVPProcessInputEvents();\nvoid TVPControlAdDialog(int adType, int arg1, int arg2);\n// void TVPShowIME(int x, int y, int w, int h);\n// void TVPHideIME();\n\nint TVPDrawSceneOnce(int interval) {\n\tstatic tjs_uint64 lastTick = TVPGetRoughTickCount32();\n\ttjs_uint64 curTick = TVPGetRoughTickCount32();\n\tint remain = interval - (curTick - lastTick);\n\tif (remain <= 0) {\n\t\tif (_postUpdate) _postUpdate();\n\t\tDirector* director = Director::getInstance();\n\t\tdirector->drawScene(/*true*/);\n\t\tTVPForceSwapBuffer();\n\t\tlastTick = curTick;\n\t\treturn 0;\n\t} else {\n\t\treturn remain;\n\t}\n}\n\nstruct tTVPCursor {\n\tNode *RootNode;\n\tAction *Anim = nullptr;\n};\n\n#pragma pack(push)\n#pragma pack(1)\nenum eIconType {\n\teIconTypeNone,\n\teIconTypeICO,\n\teIconTypeCUR\n};\n\nstruct ICONDIR {\n\tuint16_t idReserved; // must be 0\n\tuint16_t idType; //eIconType\n\tuint16_t idCount;\n};\n\nstruct ICODIREntry {\n\tuint8_t bWidth; // 0 -> 256\n\tuint8_t bHeight; // 0 -> 256\n\tuint8_t bColorCount;\n\tuint8_t bReserved;\n\tunion {\n\t\tstruct {\n\t\t\tuint16_t wPlanes;\n\t\t\tuint16_t wBitCount;\n\t\t};\n\t\tstruct {\n\t\t\tuint16_t wHotSpotX;\n\t\t\tuint16_t wHotSpotY;\n\t\t};\n\t};\n\tuint32_t dwBytesInRes;\n\tuint32_t dwImageOffset;\n};\n#pragma pack(pop)\n\nSprite *TVPLoadCursorCUR(tTJSBinaryStream *pStream) {\n\tICONDIR header;\n\tpStream->ReadBuffer(&header, sizeof(header));\n\tif ((header.idReserved != 0) || (header.idType != eIconTypeCUR) || (header.idCount == 0)) {\n\t\treturn nullptr;\n\t}\n\n\tstd::vector<ICODIREntry> cur_dir;\n\tcur_dir.resize(header.idCount);\n\tpStream->ReadBuffer(&cur_dir[0], sizeof(ICODIREntry)* header.idCount);\n\tICODIREntry bestentry = { 0 };\n\tfor (int i = 0; i < cur_dir.size(); ++i) {\n\t\tconst ICODIREntry &entry = cur_dir[i];\n\t\tif (entry.bHeight > bestentry.bHeight) bestentry = entry;\n\t}\n\tcur_dir.clear();\n\tcur_dir.emplace_back(bestentry);\n\n\tfor (int i = 0; i < cur_dir.size(); ++i) {\n\t\tconst ICODIREntry &entry = cur_dir[i];\n\t\tint bWidth = entry.bWidth;\n\t\tint bHeight = entry.bHeight;\n\t\tint bColorCount = entry.bColorCount;\n\t\tif (!bWidth) bWidth = 256;\n\t\tif (!bHeight) bHeight = 256;\n\t\tif (!bColorCount) bColorCount = 256;\n\n\t\tpStream->SetPosition(entry.dwImageOffset);\n\t\tTVPBITMAPINFOHEADER bmhdr;\n\t\tpStream->ReadBuffer(&bmhdr, sizeof(bmhdr));\n\t\tif (bmhdr.biSize != 40) continue;\n\t\tif (bmhdr.biCompression) continue;\n\t\tint bmpPitch, pad;\n\t\tswitch (bmhdr.biBitCount) {\n\t\tcase 1:\n\t\t\tbmpPitch = (bmhdr.biWidth + 7) >> 3;\n\t\t\tpad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tbmpPitch = (bmhdr.biWidth + 1) >> 1;\n\t\t\tpad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tbmpPitch = bmhdr.biWidth;\n\t\t\tpad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcontinue;\n\t\t}\n\t\tbmhdr.biHeight /= 2;\n\t\tstd::vector<unsigned char> pixbuf; pixbuf.resize(bmhdr.biWidth * bmhdr.biHeight * 4);\n\t\ttjs_uint32 palette[256];\n\t\tif (bmhdr.biBitCount <= 8) {\n\t\t\tif (bmhdr.biClrUsed == 0) bmhdr.biClrUsed = 1 << bmhdr.biBitCount;\n\t\t\tfor (unsigned int j = 0; j < bmhdr.biClrUsed; ++j) {\n\t\t\t\tunion {\n\t\t\t\t\ttjs_uint32 u32;\n\t\t\t\t\ttjs_uint8 u8[4];\n\t\t\t\t} clr, rclr;\n\t\t\t\tpStream->ReadBuffer(&clr.u32, 4);\n\t\t\t\trclr.u8[0] = clr.u8[2];\n\t\t\t\trclr.u8[1] = clr.u8[1];\n\t\t\t\trclr.u8[2] = clr.u8[0];\n\t\t\t\trclr.u8[3] = clr.u8[3];\n\t\t\t\tpalette[j] = rclr.u32;\n\t\t\t}\n\t\t}\n\t\t/* Read the surface pixels.  Note that the bmp image is upside down */\n\t\tint pitch = bmhdr.biWidth * 4;\n\t\ttjs_uint8 *bits = (tjs_uint8 *)&pixbuf[0] + (bmhdr.biHeight * pitch);\n\t\tswitch (bmhdr.biBitCount) {\n\t\tcase 1:\n\t\tcase 4:\n\t\tcase 8:\n\t\t\twhile (bits > (tjs_uint8 *)&pixbuf[0]) {\n\t\t\t\tbits -= pitch;\n\t\t\t\ttjs_uint8 pixel = 0;\n\t\t\t\tint shift = (8 - bmhdr.biBitCount);\n\t\t\t\tfor (i = 0; i < bmhdr.biWidth; ++i) {\n\t\t\t\t\tif (i % (8 / bmhdr.biBitCount) == 0) {\n\t\t\t\t\t\tpStream->ReadBuffer(&pixel, 1);\n\t\t\t\t\t}\n\t\t\t\t\t*((tjs_uint32 *)bits + i) = (palette[pixel >> shift]);\n\t\t\t\t\tpixel <<= bmhdr.biBitCount;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Skip padding bytes, ugh */\n\t\t\tif (pad) {\n\t\t\t\ttjs_uint8 padbyte;\n\t\t\t\tfor (i = 0; i < pad; ++i) {\n\t\t\t\t\tpStream->ReadBuffer(&padbyte, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\tbmpPitch = bmhdr.biWidth * 4;\n\t\t\tpad = 0;\n\t\t\twhile (bits > (tjs_uint8 *) &pixbuf[0]) {\n\t\t\t\tbits -= pitch;\n\t\t\t\tpStream->ReadBuffer(bits, pitch);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Read the mask pixels.  Note that the bmp image is upside down */\n\t\tbits = (tjs_uint8 *)&pixbuf[0] + (bmhdr.biHeight * pitch);\n\t\tbmpPitch = (bmhdr.biWidth + 7) >> 3;\n\t\tpad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);\n\t\twhile (bits > (tjs_uint8 *)&pixbuf[0]) {\n\t\t\ttjs_uint8 pixel = 0;\n\t\t\tint shift = (8 - 1);\n\t\t\tbits -= pitch;\n\t\t\tfor (i = 0; i < bmhdr.biWidth; ++i) {\n\t\t\t\tif (i % (8 / 1) == 0) {\n\t\t\t\t\tpStream->ReadBuffer(&pixel, 1);\n\t\t\t\t}\n\t\t\t\t*((tjs_uint32 *)bits + i) |= ((pixel >> shift) ? 0 : 0xFF000000);\n\t\t\t\tpixel <<= 1;\n\t\t\t}\n\t\t\t/* Skip padding bytes, ugh */\n\t\t\tif (pad) {\n\t\t\t\ttjs_uint8 padbyte;\n\t\t\t\tfor (i = 0; i < pad; ++i) {\n\t\t\t\t\tpStream->ReadBuffer(&padbyte, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcocos2d::Image *surface = new cocos2d::Image;\n\t\tsurface->initWithRawData(&pixbuf[0], pixbuf.size(), bmhdr.biWidth, bmhdr.biHeight, 0, false) ; //Texture2D::PixelFormat::RGBA8888, false);\n\t\tTexture2D *tex = new Texture2D();\n\t\ttex->initWithImage(surface);\n\t\tSprite *sprite = Sprite::create();\n\t\tsprite->setTexture(tex);\n\t\tsprite->setTextureRect(Rect(0, 0, bmhdr.biWidth, bmhdr.biHeight));\n\t\tsprite->setAnchorPoint(Vec2((float)entry.wHotSpotX / bmhdr.biWidth, 1.f - (float)entry.wHotSpotY / bmhdr.biHeight));\n\t\tfloat scale = sqrtf(Device::getDPI() / 150.f);\n\t\tsprite->setScale(scale);\n\t\treturn sprite; // only the first one\n\t}\n\treturn nullptr;\n}\n\ntTVPCursor *TVPLoadCursorANI(tTJSBinaryStream *pStream) {\n\t// TODO http://www.gdgsoft.com/anituner/help/aniformat.htm\n\treturn nullptr;\n}\n\ntTVPCursor *TVPLoadCursor(tTJSBinaryStream *stream) {\n\tif (!stream) return nullptr;\n\tunsigned char sig[4];\n\tstream->Read(sig, 4);\n\tstream->SetPosition(0);\n\tif (memcmp(sig, \"RIFF\", 4) == 0) { // ani format\n\t\treturn TVPLoadCursorANI(stream);\n\t} else { // cur format\n\t\tSprite * cur = TVPLoadCursorCUR(stream);\n\t\ttTVPCursor * ret = nullptr;\n\t\tif (cur) {\n\t\t\tret = new tTVPCursor;\n\t\t\tret->RootNode = cur;\n\t\t\tcur->retain();\n\t\t}\n\t\treturn ret;\n\t}\n}\n\ntTVPMouseButton TVP_TMouseButton_To_tTVPMouseButton(int button) {\n\treturn (tTVPMouseButton)button;\n}\n// instead of TTVPWindowForm\nclass TVPWindowLayer : public cocos2d::extension::ScrollView, public iWindowLayer {\n\ttypedef cocos2d::extension::ScrollView inherit;\n\ttTJSNI_Window *TJSNativeInstance;\n\ttjs_int ActualZoomDenom; // Zooming factor denominator (actual)\n\ttjs_int ActualZoomNumer; // Zooming factor numerator (actual)\n\tSprite *DrawSprite = nullptr;\n\tNode *PrimaryLayerArea = nullptr;\n\tint LayerWidth = 0, LayerHeight = 0;\n\t//iTVPTexture2D *DrawTexture = nullptr;\n\tTVPWindowLayer *_prevWindow, *_nextWindow;\n\tfriend class TVPWindowManagerOverlay;\n\tfriend class TVPMainScene;\n\tint _LastMouseX = 0, _LastMouseY = 0;\n\tstd::string _caption;\n//\tstd::map<tTJSNI_BaseVideoOverlay*, Sprite*> _AllOverlay;\n\tfloat _drawSpriteScaleX = 1.0f, _drawSpriteScaleY = 1.0f;\n\tfloat _drawTextureScaleX = 1.f, _drawTextureScaleY = 1.f;\n\tbool UseMouseKey = false, MouseLeftButtonEmulatedPushed = false, MouseRightButtonEmulatedPushed = false;\n\tbool LastMouseMoved = false, Visible = false;\n\ttjs_uint32 LastMouseKeyTick = 0;\n\ttjs_int MouseKeyXAccel = 0;\n\ttjs_int MouseKeyYAccel = 0;\n\tint LastMouseDownX = 0, LastMouseDownY = 0;\n\tVelocityTrackers TouchVelocityTracker;\n\tVelocityTracker MouseVelocityTracker;\n\tstatic const int TVP_MOUSE_MAX_ACCEL = 30;\n\tstatic const int TVP_MOUSE_SHIFT_ACCEL = 40;\n\tstatic const int TVP_TOOLTIP_SHOW_DELAY = 500;\n\npublic:\n\tTVPWindowLayer(tTJSNI_Window *w)\n\t\t: TJSNativeInstance(w)\n\t{\n\t\t_nextWindow = nullptr;\n\t\t_prevWindow = _lastWindowLayer;\n\t\t_lastWindowLayer = this;\n\t\tActualZoomDenom = 1;\n\t\tActualZoomNumer = 1;\n\t\tif (_prevWindow) {\n\t\t\t_prevWindow->_nextWindow = this;\n\t\t}\n\t}\n\n\tvirtual ~TVPWindowLayer() {\n\t\tif (_lastWindowLayer == this) _lastWindowLayer = _prevWindow;\n\t\tif (_nextWindow) _nextWindow->_prevWindow = _prevWindow;\n\t\tif (_prevWindow) _prevWindow->_nextWindow = _nextWindow;\n\n\t\tif (_currentWindowLayer == this) {\n\t\t\tTVPWindowLayer *anotherWin = _lastWindowLayer;\n\t\t\twhile (anotherWin && !anotherWin->isVisible()) {\n\t\t\t\tanotherWin = anotherWin->_prevWindow;\n\t\t\t}\n\t\t\tif (anotherWin && anotherWin->isVisible()) {\n\t\t\t\tanotherWin->setPosition(0, 0);\n\t\t\t\t//anotherWin->setVisible(true);\n\t\t\t}\n\t\t\t_currentWindowLayer = anotherWin;\n\t\t}\n\t}\n\n\tbool init() {\n\t\tbool ret = inherit::init();\n\t\tsetClippingToBounds(false);\n\t\tDrawSprite = Sprite::create();\n\t\tDrawSprite->setAnchorPoint(Vec2(0, 1)); // top-left\n\t\tPrimaryLayerArea = Node::create();\n\t\taddChild(PrimaryLayerArea);\n\t\tPrimaryLayerArea->addChild(DrawSprite);\n\t\tsetAnchorPoint(Size::ZERO);\n\t\tEventListenerMouse *evmouse = EventListenerMouse::create();\n\t\tevmouse->onMouseScroll = std::bind(&TVPWindowLayer::onMouseScroll, this, std::placeholders::_1);\n\t\tevmouse->onMouseDown = std::bind(&TVPWindowLayer::onMouseDownEvent, this, std::placeholders::_1);\n\t\tevmouse->onMouseUp = std::bind(&TVPWindowLayer::onMouseUpEvent, this, std::placeholders::_1);\n\t\tevmouse->onMouseMove = std::bind(&TVPWindowLayer::onMouseMoveEvent, this, std::placeholders::_1);\n\t\t_eventDispatcher->addEventListenerWithSceneGraphPriority(evmouse, this);\n\t\tsetTouchEnabled(false);\n\t\t//_touchListener->setSwallowTouches(true);\n\t\tsetVisible(false);\n\t\treturn ret;\n\t}\n\n\tstatic TVPWindowLayer *create(tTJSNI_Window *w) {\n\t\tTVPWindowLayer *ret = new TVPWindowLayer (w);\n\t\tret->init();\n\t\tret->autorelease();\n\t\treturn ret;\n\t}\n\n\tvirtual cocos2d::Node *GetPrimaryArea() override {\n\t\treturn PrimaryLayerArea;\n\t}\n\n\tvirtual Vec2 minContainerOffset() { // override {\n\t\tconst Size &size = getContentSize();\n\t\tfloat scale = _container->getScale();\n\t\tVec2 ret(_viewSize.width - size.width * scale * _drawSpriteScaleX,\n\t\t\t_viewSize.height - size.height * scale * _drawSpriteScaleY);\n\n\t\tif (ret.x > 0) {\n\t\t\tret.x /= 2;\n\t\t} else {\n\t\t\t//ret.x = 0;\n\t\t}\n\t\tif (ret.y > 0) {\n\t\t\tret.y /= 2;\n\t\t} else {\n\t\t\t//ret.y = 0;\n\t\t}\n\t\treturn ret;\n\t}\n\n\tvirtual Vec2 maxContainerOffset(){ // override {\n\t\t// bottom-left\n\t\tconst Size &size = getContentSize();\n\t\tfloat scale = _container->getScale();\n\t\tVec2 ret(_viewSize.width - size.width * scale * _drawSpriteScaleX,\n\t\t\t_viewSize.height - size.height * scale * _drawSpriteScaleY);\n\t\tif (ret.x > 0) {\n\t\t\tret.x /= 2;\n\t\t} else {\n\t\t\tret.x = 0;\n\t\t}\n\t\tif (ret.y > 0) {\n\t\t\tret.y /= 2;\n\t\t} else {\n\t\t\tret.y = 0;\n\t\t}\n\t\treturn ret;\n\t}\n\n\tvoid onMouseDownEvent(Event *_e) {\n\t\tEventMouse *e = static_cast<EventMouse*>(_e);\n\t\tswitch (e->getMouseButton()) {\n\t\tcase EventMouse::MouseButton::BUTTON_RIGHT:\n\t\t\t_mouseBtn = mbRight;\n\t\t\tonMouseDown(e->getLocation());\n\t\t\tbreak;\n\t\tcase EventMouse::MouseButton::BUTTON_MIDDLE:\n\t\t\t_mouseBtn = mbMiddle;\n\t\t\tonMouseDown(e->getLocation());\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tvoid onMouseUpEvent(Event *_e) {\n\t\tEventMouse *e = static_cast<EventMouse*>(_e);\n\t\tswitch (e->getMouseButton()) {\n\t\tcase EventMouse::MouseButton::BUTTON_RIGHT:\n\t\t\t_mouseBtn = mbRight;\n\t\t\tonMouseUp(e->getLocation());\n\t\t\tbreak;\n\t\tcase EventMouse::MouseButton::BUTTON_MIDDLE:\n\t\t\t_mouseBtn = mbMiddle;\n\t\t\tonMouseUp(e->getLocation());\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tvoid onMouseMoveEvent(Event *_e) {\n\t\tif (!_virutalMouseMode && _currentWindowLayer == this && !_touchMoved) {\n\t\t\tEventMouse *e = static_cast<EventMouse*>(_e);\n\t\t\tVec2 pt(e->getCursorX(), e->getCursorY());\n\t\t\tonMouseMove(pt);\n\t\t}\n\t}\n\n\tvoid onMouseScroll(Event *_e) {\n\t\tEventMouse *e = static_cast<EventMouse*>(_e);\n\t\tif (!_windowMgrOverlay) {\n\t\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(e->getLocation());\n\t\t\tint X = nsp.x, Y = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t\tTJSNativeInstance->OnMouseWheel(TVPGetCurrentShiftKeyState(), e->getScrollY() > 0 ? -120 : 120, X, Y);\n\t\t\treturn;\n\t\t}\n\t\tfloat scale = getZoomScale();\n\t\tif (e->getScrollY() > 0) {\n\t\t\tscale *= 0.9f;\n\t\t} else {\n\t\t\tscale *= 1.1f;\n\t\t}\n\t\tsetZoomScale(scale);\n\t\tsetContentOffset(getContentOffset());\n\t\tupdateInset();\n\t\trelocateContainer(false);\n\t}\n\n\tvirtual bool onTouchBegan(Touch *touch, Event *unused_event) override {\n\t\tif (_windowMgrOverlay) return inherit::onTouchBegan(touch, unused_event);\n\t\tif (std::find(_touches.begin(), _touches.end(), touch) == _touches.end())\n\t\t{\n\t\t\t_touches.push_back(touch);\n\t\t}\n\t\tswitch (_touches.size()) {\n\t\tcase 1:\n\t\t\t_touchPoint = touch->getLocation();\n\t\t\t_touchMoved = false;\n\t\t\t_touchLength = 0.0f;\n\t\t\t_touchBeginTick = TVPGetRoughTickCount32();\n\t\t\t_mouseBtn = ::mbLeft;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t_mouseBtn = ::mbRight;\n\t\t\t_touchPoint = (_touchPoint + touch->getLocation()) / 2;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\t_mouseBtn = ::mbMiddle;\n\t\t\t//_touchPoint = (_touchPoint + touch->getLocation()) / 2;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\tvirtual void onTouchMoved(Touch* touch, Event* unused_event) override {\n\t\tif (_windowMgrOverlay) return inherit::onTouchMoved(touch, unused_event);\n\t\tif (TJSNativeInstance) {\n\t\t\tif (_touches.size() == 1) {\n\t\t\t\tif (!_touchMoved && (TVPGetRoughTickCount32() - _touchBeginTick > 150 || _touchPoint.getDistanceSq(touch->getLocation()) > _touchMoveThresholdSq)) {\n\t\t\t\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(_touchPoint);\n\t\t\t\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()));\n\t\t\t\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x11;\n\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t\t\t\t\t_touchMoved = true;\n\t\t\t\t} else if (_touchMoved) {\n\t\t\t\t\tVec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch);\n\t\t\t\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE);\n\t\t\t\t\tint pos = (_LastMouseY << 16) + _LastMouseX;\n\t\t\t\t\tTVPPushEnvironNoise(&pos, sizeof(pos));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvirtual void onTouchEnded(Touch *touch, Event *unused_event) override {\n\t\tif (_windowMgrOverlay) return inherit::onTouchEnded(touch, unused_event);\n\t\tauto touchIter = std::find(_touches.begin(), _touches.end(), touch);\n\n\t\tif (touchIter != _touches.end())\n\t\t{\n\t\t\tif (_touches.size() == 1)\n\t\t\t{\n\t\t\t\tif (TJSNativeInstance) {\n\t\t\t\t\tVec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch);\n\t\t\t\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t\t\t\tif (!_touchMoved) {\n\t\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()));\n\t\t\t\t\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(_touchPoint);\n\t\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, nsp.x,\n\t\t\t\t\t\t\tPrimaryLayerArea->getContentSize().height - nsp.y, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t\t\t\t\t\tTVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY));\n\t\t\t\t\t}\n\t\t\t\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x10;\n\t\t\t\t\tTVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t\t\t\t}\n\t\t\t}\n\t\t\t_touches.erase(touchIter);\n\t\t}\n\n\t\tif (_touches.size() == 0)\n\t\t{\n\t\t\t_dragging = false;\n\t\t\t_touchMoved = false;\n\t\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] &= 0x10;\n\t\t}\n\t}\n\n\tvirtual void onTouchCancelled(Touch *touch, Event *unused_event) override {\n\t\tif (_windowMgrOverlay) return inherit::onTouchCancelled(touch, unused_event);\n\t\tauto touchIter = std::find(_touches.begin(), _touches.end(), touch);\n\t\tif (touchIter != _touches.end())\n\t\t{\n\t\t\t_touches.erase(touchIter);\n\t\t}\n\n\t\tif (_touches.size() == 0)\n\t\t{\n\t\t\t_dragging = false;\n\t\t\t_touchMoved = false;\n\n\t\t\tif (TJSNativeInstance) {\n\t\t\t\tVec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch);\n\t\t\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t\t\tTVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid onMouseDown(const Vec2 &pt) {\n\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt);\n\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x11;\n\t\tTVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t}\n\n\tvoid onMouseUp(const Vec2 &pt) {\n\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt);\n\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] &= 0x10;\n\t\tTVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t}\n\n\tvoid onMouseMove(const Vec2 &pt) {\n\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt);\n\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\tTVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE);\n\t\tint pos = (_LastMouseY << 16) + _LastMouseX;\n\t\tTVPPushEnvironNoise(&pos, sizeof(pos));\n\t}\n\n\tvoid onMouseClick(const Vec2 &pt) {\n\t\tVec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt);\n\t\t_LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y;\n\t\tTVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE);\n\t\t_scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x10;\n\t\tTVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t\tTVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY));\n\t\tTVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState()));\n\t}\n\n\tvirtual void SetPaintBoxSize(tjs_int w, tjs_int h) {\n\t\tLayerWidth = w; LayerHeight = h;\n\t\tRecalcPaintBox();\n\t}\n\n\tvirtual bool GetFormEnabled() {\n\t\treturn isVisible();\n\t}\n\n\tvirtual void SetDefaultMouseCursor() {\n\t\t;\n\t}\n\tvirtual void GetCursorPos(tjs_int &x, tjs_int &y) {\n\t\tx = _LastMouseX;\n\t\ty = _LastMouseY;\n\t}\n\n\tvirtual void SetCursorPos(tjs_int x, tjs_int y) {\n\t\tVec2 worldPt = PrimaryLayerArea->convertToWorldSpace(Vec2(x, PrimaryLayerArea->getContentSize().height - y));\n\t\tVec2 pt = getParent()->convertToNodeSpace(worldPt);\n\t\t_LastMouseX = pt.x;\n\t\t_LastMouseY = pt.y;\n\t\tif (_mouseCursor) {\n\t\t\t_mouseCursor->setPosition(pt);\n\t\t\t_refadeMouseCursor();\n\t\t}\n\t}\n\n\tvirtual void SetHintText(const ttstr &text) {\n\n\t}\n\n\ttjs_int _textInputPosY;\n\n\tvirtual void SetAttentionPoint(tjs_int left, tjs_int top, const struct tTVPFont * font) override {\n\t\t_textInputPosY = top;\n\t}\n\n\tvirtual void SetImeMode(tTVPImeMode mode) {\n\t\tswitch (mode) {\n\t\tcase ::imDisable:\n\t\tcase ::imClose:\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\t\t\tTVPHideIME();\n#else\n//#ifdef _MSC_VER\n\t\t\tTVPMainScene::GetInstance()->detachWithIME();\n#endif\n\t\t\tbreak;\n\t\tcase ::imOpen:\n\t\t\t//TVPMainScene::GetInstance()->attachWithIME();\n\t\t\t//break;\n\t\tdefault:\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\t\t{\n\t\t\tSize screenSize = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize();\n\t\t\tTVPShowIME(0, _textInputPosY, screenSize.width, screenSize.height / 4);\n\t\t}\n#else\n//#ifdef _MSC_VER\n\t\t\tTVPMainScene::GetInstance()->attachWithIME();\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tvirtual void ZoomRectangle(\n\t\ttjs_int & left, tjs_int & top,\n\t\ttjs_int & right, tjs_int & bottom) {\n\t\tleft = tjs_int64(left) * ActualZoomNumer / ActualZoomDenom;\n\t\ttop = tjs_int64(top) * ActualZoomNumer / ActualZoomDenom;\n\t\tright = tjs_int64(right) * ActualZoomNumer / ActualZoomDenom;\n\t\tbottom = tjs_int64(bottom) * ActualZoomNumer / ActualZoomDenom;\n\t}\n\n\tvirtual void BringToFront() {\n\t\tif (_currentWindowLayer != this) {\n\t\t\tif (_currentWindowLayer) {\n\t\t\t\tconst Size &size = _currentWindowLayer->getViewSize();\n\t\t\t\t_currentWindowLayer->setPosition(Vec2(size.width, 0));\n\t\t\t\t_currentWindowLayer->TJSNativeInstance->OnReleaseCapture();\n\t\t\t}\n\t\t\t_currentWindowLayer = this;\n\t\t}\n\t}\n\n\tvirtual void ShowWindowAsModal() {\n\t\tin_mode_ = true;\n\t\tsetVisible(true);\n\t\tBringToFront();\n\t\tif (_consoleWin) {\n\t\t\t_consoleWin->removeFromParent();\n\t\t\t_consoleWin = nullptr;\n\t\t\tTVPMainScene::GetInstance()->scheduleUpdate();\n\n\t\t\tcocos2d::Director::getInstance()->purgeCachedData();\n\t\t\tTVPControlAdDialog(0x10002, 0, 0); // ensure to close banner ad\n\t\t}\n\t\tDirector* director = Director::getInstance();\n\t\tmodal_result_ = 0;\n\t\twhile (this == _currentWindowLayer && !modal_result_) {\n\t\t\tint remain = TVPDrawSceneOnce(30); // 30 fps\n\t\t\tTVPProcessInputEvents(); // for iOS\n\t\t\tif (::Application->IsTarminate()) {\n\t\t\t\tmodal_result_ = mrCancel;\n\t\t\t} else if (modal_result_ != 0) {\n\t\t\t\tbreak;\n\t\t\t} else if (remain > 0) {\n\t\t\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(remain));\n\t\t\t}\n\t\t}\n\t\tin_mode_ = false;\n\t}\n\n\tvirtual bool GetVisible() {\n\t\treturn isVisible();\n\t}\n\n\tvirtual void SetVisible(bool bVisible) {\n\t\tVisible = bVisible;\n\t\tsetVisible(bVisible);\n\t\tif (bVisible) {\n\t\t\tBringToFront();\n\t\t} else {\n\t\t\tif (_currentWindowLayer == this) {\n\t\t\t\t_currentWindowLayer = _prevWindow ? _prevWindow : _nextWindow;\n\t\t\t}\n\t\t}\n\t}\n\n\tvirtual const char *GetCaption() {\n\t\treturn _caption.c_str();\n\t}\n\n\tvirtual void SetCaption(const std::string &s) {\n\t\t_caption = s;\n\t}\n\n\tvoid ResetDrawSprite() {\n\t\tif (DrawSprite) {\n\t\t\tSize size = getContentSize();\n\t\t\tfloat scale = (float)ActualZoomNumer / ActualZoomDenom;\n#ifdef _DEBUG\n\t\t\tSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);\n\t\t\tprintf(\"reset sprite: size=(%f,%f), Numer=%d, Denom=%d Layer=(%d,%d)\\n\",\n\t\t\t\tsize.width, size.height, ActualZoomNumer, ActualZoomDenom, LayerWidth, LayerHeight);\n\t\t\tSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);\n\t\t\tif (!LayerWidth || !LayerHeight) {\n\t\t\t\tLayerHeight = LayerHeight;\n\t\t\t}\n#endif\n\t\t\tsize = size / scale;\n\t\t\t//DrawSprite->setTextureRect(Rect(0, 0, size.width, size.height));\n\t\t\tDrawSprite->setScale(_drawTextureScaleX, _drawTextureScaleY);\n\t\t\tDrawSprite->setTextureRect(Rect(0, 0, LayerWidth, LayerHeight));\n\t\t\tDrawSprite->setPosition(Vec2(0, size.height));\n\t\t\tPrimaryLayerArea->setContentSize(size);\n\t\t\tPrimaryLayerArea->setScale(scale);\n\t\t}\n\t}\n\tvoid RecalcPaintBox() {\n\t\tif (!LayerWidth || !LayerHeight) return;\n\t\tResetDrawSprite();\n\t\tSize size = getViewSize();\n\t\tSize contSize = getContentSize();\n\t\tfloat r = size.width / size.height;\n\t\tfloat R = contSize.width / contSize.height;\n\t\tfloat scale; Vec2 offset;\n\t\tif (R > r) {\n\t\t\tscale = size.width / contSize.width;\n \t\t\toffset.x = 0;\n\t\t\toffset.y = (size.height - contSize.height * scale) / 2;\n\t\t} else {\n\t\t\tscale = size.height / contSize.height;\n\t\t\toffset.x = (size.width - contSize.width * scale) / 2;\n \t\t\toffset.y = 0;\n\t\t}\n\t\tsetMinScale(scale);\n\t\tsetMaxScale(scale * 2);\n\t\tsetZoomScale(scale);\n\t\tsetContentOffset(offset);\n\t\tupdateInset();\n\t}\n\tvirtual void SetWidth(tjs_int w) {\n\t\tSize size = getContentSize();\n\t\tsize.width = w;\n\t\tsetContentSize(size);\n\t\tRecalcPaintBox();\n\t}\n\tvirtual void SetHeight(tjs_int h) {\n\t\tSize size = getContentSize();\n\t\tsize.height = h;\n\t\tsetContentSize(size);\n\t\tRecalcPaintBox();\n\t}\n\tvirtual void SetSize(tjs_int w, tjs_int h) {\n\t\tsetContentSize(Size(w,h));\n\t\tRecalcPaintBox();\n\t}\n\tvirtual void GetSize(tjs_int &w, tjs_int &h) {\n\t\tSize size = getContentSize();\n\t\tw = size.width; h = size.height;\n\t}\n\tvirtual void GetWinSize(tjs_int &w, tjs_int &h) {\n\t\tSize size = getViewSize();\n\t\tw = size.width; h = size.height;\n\t}\n\tvirtual tjs_int GetWidth() const override { return getContentSize().width; }\n\tvirtual tjs_int GetHeight() const override { return getContentSize().height; }\n\tvirtual void SetZoom(tjs_int numer, tjs_int denom) {\n\t\tAdjustNumerAndDenom(numer, denom);\n\t\tZoomNumer = numer;\n\t\tZoomDenom = denom;\n\t\tActualZoomDenom = denom;\n\t\tActualZoomNumer = numer;\n\t\tRecalcPaintBox();\n\t}\n\n\tvirtual void UpdateDrawBuffer(iTVPTexture2D *tex) {\n\t\tif (!tex) return;\n//\t\tiTVPRenderManager *mgr = TVPGetRenderManager();\n// \t\tif (!mgr->IsSoftware()) {\n// \t\t\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"CopyOpaqueImage\");\n// \t\t\tSize size = DrawSprite->getContentSize();\n// \t\t\ttTVPRect rctar(0, 0, size.width, size.height);\n// \t\t\tif (!DrawTexture) {\n// \t\t\t\tDrawTexture = mgr->CreateTexture2D(nullptr, 0, size.width, size.height, TVPTextureFormat::RGBA);\n// \t\t\t} else {\n// \t\t\t\tDrawTexture->SetSize(size.width, size.height);\n// \t\t\t}\n// \t\t\tstd::pair<iTVPTexture2D*, tTVPRect> src_tex[] = {\n// \t\t\t\tstd::pair<iTVPTexture2D*, tTVPRect>(tex, rctar)\n// \t\t\t};\n// \t\t\tmgr->OperateRect(method, DrawTexture, nullptr, rctar, src_tex);\n// \t\t\ttex = DrawTexture;\n// \t\t}\n\t\tTexture2D *tex2d = DrawSprite->getTexture();\n\t\tTexture2D *newtex = tex->GetAdapterTexture(tex2d);\n\t\tif (tex2d != newtex) {\n\t\t\tDrawSprite->setTexture(newtex);\n\t\t\tfloat sw, sh;\n\t\t\ttex->GetScale(_drawTextureScaleX, _drawTextureScaleY);\n\t\t\tif (_drawTextureScaleX == 1.f) sw = LayerWidth;// tex->GetWidth();\n\t\t\telse {\n\t\t\t\tsw = tex->GetInternalWidth() * ((float)LayerWidth / tex->GetWidth());\n\t\t\t\t_drawTextureScaleX = 1 / _drawTextureScaleX;\n\t\t\t}\n\t\t\tif (_drawTextureScaleY == 1.f) sh = LayerHeight;// tex->GetHeight();\n\t\t\telse {\n\t\t\t\tsh = tex->GetInternalHeight()* ((float)LayerHeight / tex->GetHeight());\n\t\t\t\t_drawTextureScaleY = 1 / _drawTextureScaleY;\n\t\t\t}\n\t\t\tDrawSprite->setTextureRect(Rect(0, 0, sw, sh));\n\t\t\tDrawSprite->setBlendFunc(BlendFunc::DISABLE);\n\t\t\tResetDrawSprite();\n\t\t}\n\t}\n\n\ttTJSNI_Window* GetWindow() { return TJSNativeInstance; }\n#if 0\n\tvirtual void AddOverlay(tTJSNI_BaseVideoOverlay *ovl) {\n\t\tif (_AllOverlay.find(ovl) != _AllOverlay.end()) return;\n\t\tSprite *pSprite = Sprite::create();\n\t\tcocos2d::Texture2D* pTex = new cocos2d::Texture2D;\n\t\tpSprite->setTexture(pTex);\n\t\t//pSprite->setFlippedY(true);\n\t\tpSprite->setAnchorPoint(Vec2(0, 1));\n\t\tPrimaryLayerArea->addChild(pSprite);\n\t\t_AllOverlay[ovl] = pSprite;\n\t}\n\tvirtual void RemoveOverlay(tTJSNI_BaseVideoOverlay *ovl) {\n\t\tauto it = _AllOverlay.find(ovl);\n\t\tif (it == _AllOverlay.end()) return;\n\t\tit->second->removeFromParent();\n\t\t_AllOverlay.erase(it);\n\t}\n\tvirtual void UpdateOverlay() {\n\t\tfor (auto it : _AllOverlay) {\n\t\t\tSprite *pSprite = it.second;\n\t\t\tif (!it.first->GetVisible()) {\n\t\t\t\tpSprite->setVisible(false);\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tpSprite->setVisible(true);\n\t\t\t}\n\t\t\ttjs_int w, h;\n\t\t\tif (!it.first->GetVideoSize(w, h)) continue;\n\t\t\tSize videoSize(w, h);\n\t\t\tcocos2d::Texture2D *pTex = pSprite->getTexture();\n\t\t\tconst Size &size = pTex->getContentSize();\n\t\t\tstd::function<void(const void*, int, int, int)> drawer;\n\t\t\tif (size.width != videoSize.width || size.height != videoSize.height) {\n\t\t\t\tif (size.width < videoSize.width || size.height < videoSize.height) {\n\t\t\t\t\tdrawer = [pTex, pSprite](const void* data, int pitch, int w, int h) {\n\t\t\t\t\t\tpTex->initWithData(data, pitch * h, cocos2d::Texture2D::PixelFormat::RGBA8888,\n\t\t\t\t\t\t\tw, h, cocos2d::Size::ZERO);\n\t\t\t\t\t\tpSprite->setTextureRect(Rect(0, 0, w, h));\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tpSprite->setTextureRect(Rect(0, 0, videoSize.width, videoSize.height));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!drawer) {\n\t\t\t\tdrawer = [pTex](const void* data, int pitch, int w, int h) {\n\t\t\t\t\tpTex->updateWithData(data, 0, 0, w, h);\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!it.first->DrawToTexture(drawer)) continue;\n\t\t\tconst tTVPRect & rc = it.first->GetBounds();\n\t\t\tfloat scaleX = rc.get_width() / videoSize.width;\n\t\t\tfloat scaleY = rc.get_height() / videoSize.height;\n\t\t\tif (scaleX != pSprite->getScaleX())\n\t\t\t\tpSprite->setScaleX(scaleX);\n\t\t\tif(scaleY != pSprite->getScaleY())\n\t\t\t\tpSprite->setScaleY(scaleY);\n\t\t\tVec2 pos = pSprite->getPosition();\n\t\t\tint top = PrimaryLayerArea->getContentSize().height - rc.top;\n\t\t\tif ((int)pos.x != rc.left || (int)pos.y != top) {\n\t\t\t\tpSprite->setPosition(rc.left, top);\n\t\t\t}\n\t\t}\n\t}\n#endif\n\tvoid toogleFillScale() {\n\t\tfloat scaleX = PrimaryLayerArea->getScaleX();\n\t\tfloat scaleY = PrimaryLayerArea->getScaleY();\n\t\tconst Size &drawSize = PrimaryLayerArea->getContentSize();\n\t\tSize viewSize = getViewSize();\n\t\tfloat R = viewSize.width / viewSize.height;\n\t\tfloat r = drawSize.width / drawSize.height;\n\t\tif (fabs(R - r) < 0.01) {\n\t\t\treturn; // do not fill border if screen ratio is almost the same\n\t\t}\n\n\t\tif (scaleX == scaleY) {\n\t\t\tif (R > r) { // border @ left/right\n\t\t\t\t_drawSpriteScaleX = R / r;\n\t\t\t\tPrimaryLayerArea->setScaleX(scaleY * _drawSpriteScaleX);\n\t\t\t} else { // border @ top/bottom\n\t\t\t\t_drawSpriteScaleY = r / R;\n\t\t\t\tPrimaryLayerArea->setScaleY(scaleX * _drawSpriteScaleY);\n\t\t\t}\n\t\t} else {\n\t\t\tPrimaryLayerArea->setScale(std::min(scaleX, scaleY));\n\t\t\t_drawSpriteScaleX = 1.0f;\n\t\t\t_drawSpriteScaleY = 1.0f;\n\t\t}\n\n\t\tupdateInset();\n\t\tsetContentOffset(Vec2::ZERO);\n\t\trelocateContainer(false);\n\t}\n\n\tvirtual void InvalidateClose() override {\n\t\t// closing action by object invalidation;\n\t\t// this will not cause any user confirmation of closing the window.\n\n\t\t//TVPRemoveWindowLayer(this);\n\t\tthis->removeFromParent(); // and delete this\n\t}\n\tvirtual bool GetWindowActive() override {\n\t\treturn _currentWindowLayer == this;\n\t}\n\tint GetMouseButtonState() const {\n\t\tint s = 0;\n\t\tif (TVPGetAsyncKeyState(VK_LBUTTON)) s |= ssLeft;\n\t\tif (TVPGetAsyncKeyState(VK_RBUTTON)) s |= ssRight;\n\t\tif (TVPGetAsyncKeyState(VK_MBUTTON)) s |= ssMiddle;\n\t\treturn s;\n\t}\n\tvoid OnMouseDown(int button, int shift, int x, int y) {\n\t\t//if (!CanSendPopupHide()) DeliverPopupHide();\n\n\t\tMouseVelocityTracker.addMovement(TVPGetRoughTickCount32(), (float)x, (float)y);\n\n\t\tLastMouseDownX = x;\n\t\tLastMouseDownY = y;\n\n\t\tif (TJSNativeInstance) {\n\t\t\ttjs_uint32 s = shift;\n\t\t\ts |= GetMouseButtonState();\n\t\t\ttTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button);\n\t\t\tTVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, x, y, b, s));\n\t\t}\n\t}\n\tvoid OnMouseClick(int button, int shift, int x, int y) {\n\t\t// fire click event\n\t\tif (TJSNativeInstance) {\n\t\t\tTVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, LastMouseDownX, LastMouseDownY));\n\t\t}\n\t}\n\n\tvoid GenerateMouseEvent(bool fl, bool fr, bool fu, bool fd) {\n\t\tif (!fl && !fr && !fu && !fd) {\n\t\t\tif (TVPGetRoughTickCount32() - 45 < LastMouseKeyTick) return;\n\t\t}\n\n\t\tbool shift = 0 != (TVPGetKeyMouseAsyncState(VK_SHIFT, true));\n\t\tbool left = fl || TVPGetKeyMouseAsyncState(VK_LEFT, true) || TVPGetJoyPadAsyncState(VK_PADLEFT, true);\n\t\tbool right = fr || TVPGetKeyMouseAsyncState(VK_RIGHT, true) || TVPGetJoyPadAsyncState(VK_PADRIGHT, true);\n\t\tbool up = fu || TVPGetKeyMouseAsyncState(VK_UP, true) || TVPGetJoyPadAsyncState(VK_PADUP, true);\n\t\tbool down = fd || TVPGetKeyMouseAsyncState(VK_DOWN, true) || TVPGetJoyPadAsyncState(VK_PADDOWN, true);\n\n\t\tuint32_t flags = 0;\n\t\tif (left || right || up || down) flags |= /*MOUSEEVENTF_MOVE*/1;\n\n\t\tif (!right && !left && !up && !down) {\n\t\t\tLastMouseMoved = false;\n\t\t\tMouseKeyXAccel = MouseKeyYAccel = 0;\n\t\t}\n\n\t\tif (!shift) {\n\t\t\tif (!right && left && MouseKeyXAccel > 0) MouseKeyXAccel = -0;\n\t\t\tif (!left && right && MouseKeyXAccel < 0) MouseKeyXAccel = 0;\n\t\t\tif (!down && up && MouseKeyYAccel > 0) MouseKeyYAccel = -0;\n\t\t\tif (!up && down && MouseKeyYAccel < 0) MouseKeyYAccel = 0;\n\t\t} else {\n\t\t\tif (left) MouseKeyXAccel = -TVP_MOUSE_SHIFT_ACCEL;\n\t\t\tif (right) MouseKeyXAccel = TVP_MOUSE_SHIFT_ACCEL;\n\t\t\tif (up) MouseKeyYAccel = -TVP_MOUSE_SHIFT_ACCEL;\n\t\t\tif (down) MouseKeyYAccel = TVP_MOUSE_SHIFT_ACCEL;\n\t\t}\n\n\t\tif (right || left || up || down) {\n\t\t\tif (left) if (MouseKeyXAccel > -TVP_MOUSE_MAX_ACCEL)\n\t\t\t\tMouseKeyXAccel = MouseKeyXAccel ? MouseKeyXAccel - 2 : -2;\n\t\t\tif (right) if (MouseKeyXAccel < TVP_MOUSE_MAX_ACCEL)\n\t\t\t\tMouseKeyXAccel = MouseKeyXAccel ? MouseKeyXAccel + 2 : +2;\n\t\t\tif (!left && !right) {\n\t\t\t\tif (MouseKeyXAccel > 0) MouseKeyXAccel--;\n\t\t\t\telse if (MouseKeyXAccel < 0) MouseKeyXAccel++;\n\t\t\t}\n\n\t\t\tif (up) if (MouseKeyYAccel > -TVP_MOUSE_MAX_ACCEL)\n\t\t\t\tMouseKeyYAccel = MouseKeyYAccel ? MouseKeyYAccel - 2 : -2;\n\t\t\tif (down) if (MouseKeyYAccel < TVP_MOUSE_MAX_ACCEL)\n\t\t\t\tMouseKeyYAccel = MouseKeyYAccel ? MouseKeyYAccel + 2 : +2;\n\t\t\tif (!up && !down) {\n\t\t\t\tif (MouseKeyYAccel > 0) MouseKeyYAccel--;\n\t\t\t\telse if (MouseKeyYAccel < 0) MouseKeyYAccel++;\n\t\t\t}\n\n\t\t}\n\n\t\tif (flags) {\n\t\t\t_LastMouseX += MouseKeyXAccel >> 1;\n\t\t\t_LastMouseY += MouseKeyYAccel >> 1;\n\t\t\tLastMouseMoved = true;\n\t\t}\n\t\tLastMouseKeyTick = TVPGetRoughTickCount32();\n\t}\n\n\tvirtual void InternalKeyDown(tjs_uint16 key, tjs_uint32 shift) override {\n\t\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\t\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\t\tTVPPushEnvironNoise(&key, sizeof(key));\n\t\tTVPPushEnvironNoise(&shift, sizeof(shift));\n\n\t\tif (UseMouseKey) {\n\t\t\tif (key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) {\n\t\t\t\tVec2 p(_LastMouseX, _LastMouseY);\n\t\t\t\tSize size = PrimaryLayerArea->getContentSize();\n\t\t\t\tif (p.x >= 0 && p.y >= 0 && p.x < size.width && p.y < size.height) {\n\t\t\t\t\tif (key == VK_RETURN || key == VK_SPACE || key == VK_PAD1) {\n\t\t\t\t\t\tMouseLeftButtonEmulatedPushed = true;\n\t\t\t\t\t\tOnMouseDown(mbLeft, 0, p.x, p.y);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (key == VK_ESCAPE || key == VK_PAD2) {\n\t\t\t\t\t\tMouseRightButtonEmulatedPushed = true;\n\t\t\t\t\t\tOnMouseDown(mbLeft, 0, p.x, p.y);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tswitch (key) {\n\t\t\tcase VK_LEFT:\n\t\t\tcase VK_PADLEFT:\n\t\t\t\tif (MouseKeyXAccel == 0 && MouseKeyYAccel == 0) {\n\t\t\t\t\tGenerateMouseEvent(true, false, false, false);\n\t\t\t\t\tLastMouseKeyTick = TVPGetRoughTickCount32() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_RIGHT:\n\t\t\tcase VK_PADRIGHT:\n\t\t\t\tif (MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, true, false, false);\n\t\t\t\t\tLastMouseKeyTick = TVPGetRoughTickCount32() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_UP:\n\t\t\tcase VK_PADUP:\n\t\t\t\tif (MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, false, true, false);\n\t\t\t\t\tLastMouseKeyTick = TVPGetRoughTickCount32() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_DOWN:\n\t\t\tcase VK_PADDOWN:\n\t\t\t\tif (MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, false, false, true);\n\t\t\t\t\tLastMouseKeyTick = TVPGetRoughTickCount32() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tTVPPostInputEvent(new tTVPOnKeyDownInputEvent(TJSNativeInstance, key, shift));\n\t}\n\tvoid InternalKeyUp(tjs_uint16 key, tjs_uint32 shift) {\n\t\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\t\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\t\tTVPPushEnvironNoise(&key, sizeof(key));\n\t\tTVPPushEnvironNoise(&shift, sizeof(shift));\n\t\tif (TJSNativeInstance) {\n\t\t\tif (UseMouseKey /*&& PaintBox*/) {\n\t\t\t\tif (key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) {\n\t\t\t\t\tVec2 p(_LastMouseX, _LastMouseY);\n\t\t\t\t\tSize size = PrimaryLayerArea->getContentSize();\n\t\t\t\t\tif (p.x >= 0 && p.y >= 0 && p.x < size.width && p.y < size.height) {\n\t\t\t\t\t\tif (key == VK_RETURN || key == VK_SPACE || key == VK_PAD1) {\n\t\t\t\t\t\t\tOnMouseClick(mbLeft, 0, p.x, p.y);\n\t\t\t\t\t\t\tMouseLeftButtonEmulatedPushed = false;\n\t\t\t\t\t\t\tOnMouseUp(mbLeft, 0, p.x, p.y);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (key == VK_ESCAPE || key == VK_PAD2) {\n\t\t\t\t\t\t\tMouseRightButtonEmulatedPushed = false;\n\t\t\t\t\t\t\tOnMouseUp(mbRight, 0, p.x, p.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tTVPPostInputEvent(new tTVPOnKeyUpInputEvent(TJSNativeInstance, key, shift));\n\t\t}\n\t}\n\tvirtual void OnKeyUp(tjs_uint16 vk, int shift) override {\n\t\ttjs_uint32 s = (shift);\n\t\ts |= GetMouseButtonState();\n\t\tInternalKeyUp(vk, s);\n\t}\n\tvirtual void OnKeyPress(tjs_uint16 vk, int repeat, bool prevkeystate, bool convertkey) override {\n\t\tif (TJSNativeInstance && vk) {\n\t\t\tif (UseMouseKey && (vk == 0x1b || vk == 13 || vk == 32)) return;\n\t\t\t// UNICODE ʤΤǤΤޤ޶ɤƤޤ\n\t\t\tTVPPostInputEvent(new tTVPOnKeyPressInputEvent(TJSNativeInstance, vk));\n\t\t}\n\t}\n\ttTVPImeMode LastSetImeMode = ::imDisable;\n\ttTVPImeMode DefaultImeMode = ::imDisable;\n\tvirtual tTVPImeMode GetDefaultImeMode() const override { return DefaultImeMode; }\n\tvirtual void ResetImeMode() override { SetImeMode(DefaultImeMode); }\n\tbool Closing = false, ProgramClosing = false, CanCloseWork = false;\n\tbool in_mode_ = false; // is modal\n\tint modal_result_ = 0;\n\tenum CloseAction {\n\t\tcaNone,\n\t\tcaHide,\n\t\tcaFree,\n\t\tcaMinimize\n\t};\n\tvoid OnClose(CloseAction& action) {\n\t\tif (modal_result_ == 0)\n\t\t\taction = caNone;\n\t\telse\n\t\t\taction = caHide;\n\n\t\tif (ProgramClosing) {\n\t\t\tif (TJSNativeInstance) {\n\t\t\t\tif (TJSNativeInstance->IsMainWindow()) {\n\t\t\t\t\t// this is the main window\n\t\t\t\t} else \t\t\t{\n\t\t\t\t\t// not the main window\n\t\t\t\t\taction = caFree;\n\t\t\t\t}\n\t\t\t\t//if (TVPFullScreenedWindow != this) {\n\t\t\t\t\t// if this is not a fullscreened window\n\t\t\t\t//\tSetVisible(false);\n\t\t\t\t//}\n\t\t\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\t\t\tTJSNativeInstance->NotifyWindowClose();\n\t\t\t\tobj->Invalidate(0, NULL, NULL, obj);\n\t\t\t\tTJSNativeInstance = NULL;\n\t\t\t\tSetVisible(false);\n\t\t\t\tscheduleOnce([this](float){removeFromParent(); }, 0, \"remove\");\n\t\t\t}\n\t\t}\n\t}\n\tbool OnCloseQuery() {\n\t\t// closing actions are 3 patterns;\n\t\t// 1. closing action by the user\n\t\t// 2. \"close\" method\n\t\t// 3. object invalidation\n\n\t\tif (TVPGetBreathing()) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// the default event handler will invalidate this object when an onCloseQuery\n\t\t// event reaches the handler.\n\t\tif (TJSNativeInstance && (modal_result_ == 0 ||\n\t\t\tmodal_result_ == mrCancel/* mrCancel=when close button is pushed in modal window */)) {\n\t\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\t\tif (obj) {\n\t\t\t\ttTJSVariant arg[1] = { true };\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onCloseQuery\"));\n\n\t\t\t\tif (!ProgramClosing) {\n\t\t\t\t\t// close action does not happen immediately\n\t\t\t\t\tif (TJSNativeInstance) {\n\t\t\t\t\t\tTVPPostInputEvent(new tTVPOnCloseInputEvent(TJSNativeInstance));\n\t\t\t\t\t}\n\n\t\t\t\t\tClosing = true; // waiting closing...\n\t\t\t\t//\tTVPSystemControl->NotifyCloseClicked();\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tCanCloseWork = true;\n\t\t\t\t\tTVPPostEvent(obj, obj, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t\t\t\t\tTVPDrawSceneOnce(0); // for post event\n\t\t\t\t\t// this event happens immediately\n\t\t\t\t\t// and does not return until done\n\t\t\t\t\treturn CanCloseWork; // CanCloseWork is set by the event handler\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\tvirtual void Close() override {\n\t\t// closing action by \"close\" method\n\t\tif (Closing) return; // already waiting closing...\n\n\t\tProgramClosing = true;\n\t\ttry {\n\t\t\t//tTVPWindow::Close();\n\t\t\tif (in_mode_) {\n\t\t\t\tmodal_result_ = mrCancel;\n\t\t\t} else if (OnCloseQuery()) {\n\t\t\t\tCloseAction action = caFree;\n\t\t\t\tOnClose(action);\n\t\t\t\tswitch (action) {\n\t\t\t\tcase caNone:\n\t\t\t\t\tbreak;\n\t\t\t\tcase caHide:\n\t\t\t\t\tHide();\n\t\t\t\t\tbreak;\n\t\t\t\tcase caMinimize:\n\t\t\t\t\t//::ShowWindow(GetHandle(), SW_MINIMIZE);\n\t\t\t\t\tbreak;\n\t\t\t\tcase caFree:\n\t\t\t\tdefault:\n\t\t\t\t\tscheduleOnce([this](float){\n\t\t\t\t\t\tremoveFromParent();\n\t\t\t\t\t}, 0, \"Close\");\n\t\t\t\t\t//::PostMessage(GetHandle(), TVP_EV_WINDOW_RELEASE, 0, 0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (...) {\n\t\t\tProgramClosing = false;\n\t\t\tthrow;\n\t\t}\n\t\tProgramClosing = false;\n\t}\n\tvirtual void OnCloseQueryCalled(bool b) {\n\t\t// closing is allowed by onCloseQuery event handler\n\t\tif (!ProgramClosing) {\n\t\t\t// closing action by the user\n\t\t\tif (b) {\n\t\t\t\tif (in_mode_)\n\t\t\t\t\tmodal_result_ = 1; // when modal\n\t\t\t\telse\n\t\t\t\t\tSetVisible(false);  // just hide\n\n\t\t\t\tClosing = false;\n\t\t\t\tif (TJSNativeInstance) {\n\t\t\t\t\tif (TJSNativeInstance->IsMainWindow()) {\n\t\t\t\t\t\t// this is the main window\n\t\t\t\t\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\t\t\t\t\tobj->Invalidate(0, NULL, NULL, obj);\n\t\t\t\t\t\t// TJSNativeInstance = NULL; // ζAǤϼȤthisƤ뤿ᡢЩ`إƤϤʤ\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdelete this;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tClosing = false;\n\t\t\t}\n\t\t} else {\n\t\t\t// closing action by the program\n\t\t\tCanCloseWork = b;\n\t\t}\n\t}\n\tvirtual void UpdateWindow(tTVPUpdateType type) {\n\t\tif (TJSNativeInstance) {\n\t\t\ttTVPRect r;\n\t\t\tr.left = 0;\n\t\t\tr.top = 0;\n\t\t\tr.right = LayerWidth;\n\t\t\tr.bottom = LayerHeight;\n\t\t\tTJSNativeInstance->NotifyWindowExposureToLayer(r);\n\t\t\tTVPDeliverWindowUpdateEvents();\n\t\t}\n\t}\n\tvirtual void SetVisibleFromScript(bool b) {\n\t\tSetVisible(b);\n// \t\tif (Focusable) {\n// \t\t\tSetVisible(b);\n// \t\t} else {\n// \t\t\tif (!GetVisible()) {\n// \t\t\t\t// just show window, not activate\n// \t\t\t\tSetWindowPos(GetHandle(), GetStayOnTop() ? HWND_TOPMOST : HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);\n// \t\t\t\tSetVisible(true);\n// \t\t\t} else {\n// \t\t\t\tSetVisible(false);\n// \t\t\t}\n// \t\t}\n\t}\n\tvirtual void SetUseMouseKey(bool b) {\n\t\tUseMouseKey = b;\n\t\tif (b) {\n\t\t\tMouseLeftButtonEmulatedPushed = false;\n\t\t\tMouseRightButtonEmulatedPushed = false;\n\t\t\tLastMouseKeyTick = TVPGetRoughTickCount32();\n\t\t} else {\n\t\t\tif (MouseLeftButtonEmulatedPushed) {\n\t\t\t\tMouseLeftButtonEmulatedPushed = false;\n\t\t\t\tOnMouseUp(mbLeft, 0, _LastMouseX, _LastMouseY);\n\t\t\t}\n\t\t\tif (MouseRightButtonEmulatedPushed) {\n\t\t\t\tMouseRightButtonEmulatedPushed = false;\n\t\t\t\tOnMouseUp(mbRight, 0, _LastMouseX, _LastMouseY);\n\t\t\t}\n\t\t}\n\t}\n\tvirtual bool GetUseMouseKey() const { return UseMouseKey; }\n\tvoid OnMouseUp(int button, int shift, int x, int y) {\n\t//\tTranslateWindowToDrawArea(x, y);\n\t//\tReleaseMouseCapture();\n\t\tMouseVelocityTracker.addMovement(TVPGetRoughTickCount32(), (float)x, (float)y);\n\t\tif (TJSNativeInstance) {\n\t\t\ttjs_uint32 s = shift;\n\t\t\ts |= GetMouseButtonState();\n\t\t\ttTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button);\n\t\t\tTVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, x, y, b, s));\n\t\t}\n\t}\n\tvirtual void ResetTouchVelocity(tjs_int id) {\n\t\tTouchVelocityTracker.end(id);\n\t}\n\tvirtual void ResetMouseVelocity() {\n\t\tMouseVelocityTracker.clear();\n\t}\n\tbool GetMouseVelocity(float& x, float& y, float& speed) const {\n\t\tif (MouseVelocityTracker.getVelocity(x, y)) {\n\t\t\tspeed = hypotf(x, y);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tvirtual void TickBeat() override {\n\t\tbool focused = _currentWindowLayer == this;\n\t\t// mouse key\n\t\tif (UseMouseKey &&  focused) {\n\t\t\tGenerateMouseEvent(false, false, false, false);\n\t\t}\n\t}\n};\n\ntTJSNI_Window *TVPGetActiveWindow() {\n\tif (!_currentWindowLayer) return nullptr;\n\treturn _currentWindowLayer->GetWindow();\n}\n\nclass TVPWindowManagerOverlay : public iTVPBaseForm {\npublic:\n\tstatic TVPWindowManagerOverlay *create() {\n\t\tTVPWindowManagerOverlay* ret = new TVPWindowManagerOverlay();\n\t\tret->autorelease();\n\t\tret->initFromFile(nullptr, \"ui/WinMgrOverlay.csb\", nullptr);\n\t\treturn ret;\n\t}\n\tvirtual void rearrangeLayout() {\n\t\tSize sceneSize = TVPMainScene::GetInstance()->getGameNodeSize();\n\t\tsetContentSize(sceneSize);\n\t\tRootNode->setContentSize(sceneSize);\n\t\tui::Helper::doLayout(RootNode);\n\t}\n\n\tvirtual void bindBodyController(const NodeMap &allNodes) {\n\t\t_left = static_cast<ui::Button*>(allNodes.findController(\"left\"));\n\t\t_right = static_cast<ui::Button*>(allNodes.findController(\"right\"));\n\t\t_ok = static_cast<ui::Button*>(allNodes.findController(\"ok\"));\n\n\t\tauto funcUpdate = std::bind(&TVPWindowManagerOverlay::updateButtons, this);\n\n\t\t_left->addClickEventListener([=](Ref*){\n\t\t\tif (!_currentWindowLayer || !_currentWindowLayer->_prevWindow) return;\n\t\t\t//_currentWindowLayer->_prevWindow->setVisible(true);\n\t\t\tSize size = _currentWindowLayer->_prevWindow->getViewSize();\n\t\t\t_currentWindowLayer->_prevWindow->setPosition(-size.width, 0);\n\t\t\t_currentWindowLayer->_prevWindow->runAction(\n\t\t\t\tEaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO)));\n\t\t\t_currentWindowLayer->runAction(Sequence::createWithTwoActions(\n\t\t\t\tEaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0))),\n\t\t\t\tSequence::createWithTwoActions(Hide::create(), CallFunc::create(funcUpdate))\n\t\t\t\t));\n\t\t\t_currentWindowLayer = _currentWindowLayer->_prevWindow;\n\t\t\t_left->setVisible(false);\n\t\t\t_right->setVisible(false);\n\t\t});\n\n\t\t_right->addClickEventListener([=](Ref*){\n\t\t\tif (!_currentWindowLayer || !_currentWindowLayer->_nextWindow) return;\n\t\t\t//_currentWindowLayer->_nextWindow->setVisible(true);\n\t\t\tSize size = _currentWindowLayer->_nextWindow->getViewSize();\n\t\t\t_currentWindowLayer->_nextWindow->setPosition(size.width, 0);\n\t\t\t_currentWindowLayer->_nextWindow->runAction(\n\t\t\t\tEaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO)));\n\t\t\t_currentWindowLayer->runAction(Sequence::createWithTwoActions(\n\t\t\t\tEaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(-size.width, 0))),\n\t\t\t\tSequence::createWithTwoActions(Hide::create(), CallFunc::create(funcUpdate))\n\t\t\t\t));\n\t\t\t_currentWindowLayer = _currentWindowLayer->_nextWindow;\n\t\t\t_left->setVisible(false);\n\t\t\t_right->setVisible(false);\n\t\t});\n\n\t\t_ok->addClickEventListener([](Ref*){\n\t\t\tTVPMainScene::GetInstance()->showWindowManagerOverlay(false);\n\t\t});\n\n\t\tui::Button* fillscr = static_cast<ui::Button*>(allNodes.findController(\"fillscr\"));\n\t\tfillscr->addClickEventListener([](Ref*){\n\t\t\tif (!_currentWindowLayer) return;\n\t\t\t_currentWindowLayer->toogleFillScale();\n\t\t});\n\n\t\tupdateButtons();\n\t}\n\n\tvoid updateButtons() {\n\t\tif (!_currentWindowLayer) return;\n\t\tif (_left) {\n\t\t\tTVPWindowLayer *pLay = _currentWindowLayer->_prevWindow;\n\t\t\twhile (pLay && !pLay->Visible) {\n\t\t\t\tpLay = pLay->_prevWindow;\n\t\t\t}\n\t\t\t_left->setVisible(pLay && pLay->Visible);\n\t\t}\n\t\tif (_right) {\n\t\t\tTVPWindowLayer *pLay = _currentWindowLayer->_nextWindow;\n\t\t\twhile (pLay && !pLay->Visible) {\n\t\t\t\tpLay = pLay->_nextWindow;\n\t\t\t}\n\t\t\t_right->setVisible(pLay && pLay->Visible);\n\t\t}\n\t}\n\t\nprivate:\n\tui::Button *_left, *_right, *_ok;\n};\n\nstatic std::function<bool(Touch *, Event *)> _func_mask_layer_touchbegan;\n\nclass MaskLayer : public LayerColor {\npublic:\n\tstatic LayerColor * create(const Color4B& color, GLfloat width, GLfloat height) {\n\t\tLayerColor * layer = LayerColor::create(color, width, height);\n\t\tauto listener = EventListenerTouchOneByOne::create();\n\t\tlistener->setSwallowTouches(true);\n\t\tif (_func_mask_layer_touchbegan) {\n\t\t\tlistener->onTouchBegan = _func_mask_layer_touchbegan;\n\t\t\t_func_mask_layer_touchbegan = nullptr;\n\t\t} else {\n\t\t\tlistener->onTouchBegan = [](Touch *, Event *)->bool{return true; };\n\t\t}\n\t\tlistener->onTouchMoved = [](Touch *, Event *) {};\n\t\tlistener->onTouchEnded = [](Touch *, Event *) {};\n\t\tlistener->onTouchCancelled = [](Touch *, Event *) {};\n\n\t\tDirector::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, layer);\n\n\t\treturn layer;\n\t}\n};\n\nstatic TVPMainScene *_instance = nullptr;\n\nTVPMainScene* TVPMainScene::GetInstance() {\n\treturn _instance;\n}\n\nTVPMainScene* TVPMainScene::CreateInstance() {\n\t_instance = create();\n\treturn _instance;\n}\n\nvoid TVPMainScene::initialize() {\n\tauto glview = cocos2d::Director::getInstance()->getOpenGLView();\n\tSize screenSize = glview->getFrameSize();\n\tSize designSize = glview->getDesignResolutionSize();\n\tScreenRatio = screenSize.height / designSize.height;\n\tdesignSize.width = designSize.height * screenSize.width / screenSize.height;\n\tinitWithSize(designSize);\n\taddChild(LayerColor::create(Color4B::BLACK, designSize.width, designSize.height));\n\tGameNode = cocos2d::Node::create();\n\t// horizontal\n\t//std::swap(designSize.width, designSize.height);\n\tGameNode->setContentSize(designSize);\n\tUINode = cocos2d::Node::create();\n\tUINode->setContentSize(designSize);\n\tUINode->setAnchorPoint(Vec2::ZERO);\n\tUINode->setPosition(Vec2::ZERO);\n\tUISize = designSize;\n\taddChild(UINode, UI_NODE_ORDER);\n\tGameNode->setAnchorPoint(Vec2(0, 0));\n\t//GameNode->setRotation(-90);\n\t//GameNode->setPosition(getContentSize() / 2);\n\taddChild(GameNode, GAME_SCENE_ORDER);\n\n\tEventListenerKeyboard* keylistener = EventListenerKeyboard::create();\n\tkeylistener->onKeyPressed = CC_CALLBACK_2(TVPMainScene::onKeyPressed, this);\n\tkeylistener->onKeyReleased = CC_CALLBACK_2(TVPMainScene::onKeyReleased, this);\n\t_eventDispatcher->addEventListenerWithFixedPriority(keylistener, 1);\n\n\t_touchListener = EventListenerTouchOneByOne::create();\n\t_touchListener->onTouchBegan = CC_CALLBACK_2(TVPMainScene::onTouchBegan, this);\n\t_touchListener->onTouchMoved = CC_CALLBACK_2(TVPMainScene::onTouchMoved, this);\n\t_touchListener->onTouchEnded = CC_CALLBACK_2(TVPMainScene::onTouchEnded, this);\n\t_touchListener->onTouchCancelled = CC_CALLBACK_2(TVPMainScene::onTouchCancelled, this);\n\n\t_eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this);\n\n\tEventListenerController *ctrllistener = EventListenerController::create();\n\tctrllistener->onAxisEvent = CC_CALLBACK_3(TVPMainScene::onAxisEvent, this);\n\tctrllistener->onKeyDown = CC_CALLBACK_3(TVPMainScene::onPadKeyDown, this);\n\tctrllistener->onKeyUp = CC_CALLBACK_3(TVPMainScene::onPadKeyUp, this);\n\tctrllistener->onKeyRepeat = CC_CALLBACK_3(TVPMainScene::onPadKeyRepeat, this);\n\t_eventDispatcher->addEventListenerWithSceneGraphPriority(ctrllistener, this);\n\tcocos2d::Controller::startDiscoveryController(); // for win32 & iOS\n}\n\nTVPMainScene * TVPMainScene::create() {\n\tTVPMainScene * ret = new TVPMainScene;\n\tret->initialize();\n\tret->autorelease();\n\n\t_touchMoveThresholdSq = Device::getDPI() / 10;\n\t_touchMoveThresholdSq *= _touchMoveThresholdSq;\n\treturn ret;\n}\n\nvoid TVPMainScene::pushUIForm(cocos2d::Node *ui, eEnterAni ani) {\n\tTVPControlAdDialog(0x10002, 1, 0);\n\tint n = UINode->getChildrenCount();\n\tif (ani == eEnterAniNone) {\n\t\tUINode->addChild(ui);\n\t} else if (ani == eEnterAniOverFromRight) {\n\t\tif (n > 0) {\n\t\t\tSize size = UINode->getContentSize();\n\t\t\tcocos2d::Node *lastui = UINode->getChildren().back();\n\t\t\tlastui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION,\n\t\t\t\tVec2(size.width / -5, 0))));\n\t\t\tcocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 0), size.width, size.height);\n\t\t\tColorMask->setPosition(Vec2(-size.width, 0));\n\t\t\tui->addChild(ColorMask);\n\t\t\tColorMask->runAction(FadeTo::create(UI_CHANGE_DURATION, 128));\n\t\t\tui->setPosition(size.width, 0);\n\t\t\tui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO)));\n\t\t\trunAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){\n\t\t\t\tColorMask->removeFromParent();\n\t\t\t})));\n\t\t}\n\t\tUINode->addChild(ui);\n\t} else if (ani == eEnterFromBottom) {\n\t\tSize size = UINode->getContentSize();\n\t\tcocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 0), size.width, size.height);\n\t\tColorMask->runAction(FadeTo::create(UI_CHANGE_DURATION, 128));\n\t\tui->setPositionY(-ui->getContentSize().height);\n\t\tColorMask->addChild(ui);\n\t\tUINode->addChild(ColorMask);\n\t\tui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO)));\n\t}\n}\n\nvoid TVPMainScene::popUIForm(cocos2d::Node *form, eLeaveAni ani) {\n\tint n = UINode->getChildrenCount();\n\tif (n <= 0) return;\n\tif (n == 1) {\n\t\tTVPControlAdDialog(0x10002, 0, 0);\n\t}\n\tauto children = UINode->getChildren();\n\tif (ani == eLeaveAniNone) {\n\t\tif (n > 1) {\n\t\t\tNode *lastui = children.at(n - 2);\n\t\t\tlastui->setPosition(0, 0);\n\t\t}\n\t\tNode *ui = children.back();\n\t\tif (form) CCAssert(form == ui, \"must be the same form\");\n\t\tui->removeFromParent();\n\t} else if (ani == eLeaveAniLeaveFromLeft) {\n\t\tNode *ui = children.back();\n\t\tif (form) CCAssert(form == ui, \"must be the same form\");\n\t\tSize size = UINode->getContentSize();\n\t\tif (n > 1) {\n\t\t\tNode *lastui = children.at(n - 2);\n\t\t\tlastui->setPosition(size.width / -5, 0);\n\t\t\tlastui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO)));\n\t\t}\n\t\tcocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 128), size.width, size.height);\n\t\tColorMask->setPosition(Vec2(-size.width, 0));\n\t\tui->addChild(ColorMask);\n\t\tColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION));\n\t\tui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0))));\n\t\trunAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){\n\t\t\tui->removeFromParent();\n\t\t})));\n\t} else if (ani == eLeaveToBottom) {\n\t\tcocos2d::Node *ColorMask = children.back();\n\t\tColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION));\n\t\tNode *ui = ColorMask->getChildren().at(0);\n\t\tif (form) CCAssert(form == ui, \"must be the same form\");\n\t\tui->runAction(EaseQuadraticActionIn::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(0, -ui->getContentSize().height))));\n\t\trunAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){\n\t\t\tColorMask->removeFromParent();\n\t\t})));\n\t}\n}\n\nbool TVPMainScene::startupFrom(const std::string &path) {\n\t// startup from dir\n#ifdef _MSC_VER\n\t//TVPSetSystemOption(\"outputlog\", \"yes\");\n// \tTVPSetSystemOption(\"ogl_dup_target\", \"yes\");\n\t//_set_new_handler(_no_memory_cb_vc);\n#endif\n\tif (!TVPCheckStartupPath(path)) {\n\t\treturn false;\n\t}\n\tIndividualConfigManager *pGlobalCfgMgr = IndividualConfigManager::GetInstance();\n\tpGlobalCfgMgr->UsePreferenceAt(TVPBaseFileSelectorForm::PathSplit(path).first);\n\tif (UINode->getChildrenCount()) {\n\t\tpopUIForm(nullptr);\n\t}\n\n\tif (GlobalConfigManager::GetInstance()->GetValue<bool>(\"keep_screen_alive\", true)) {\n\t\tDevice::setKeepScreenOn(true);\n\t}\n\n\tfor (int i = 0; i < sizeof(_keymap) / sizeof(_keymap[0]); ++i) {\n\t\t_keymap[i] = i;\n\t}\n\t\n\tconst auto& keymap = pGlobalCfgMgr->GetKeyMap();\n\tfor (const auto &it : keymap) {\n\t\tif (!it.second) continue;\n\t\t_keymap[it.first] = _keymap[it.second];\n \t}\n\t// \tif (pGlobalCfgMgr->GetValueBool(\"rot_screen_180\", false)) {\n// \t\tGameNode->setRotation(90);\n// \t}\n\n\tscheduleOnce(std::bind(&TVPMainScene::doStartup, this, std::placeholders::_1, path), 0, \"startup\");\n\n\treturn true;\n}\n\nvoid TVPMainScene::doStartup(float dt, std::string path) {\n\tunschedule(\"startup\");\n\tIndividualConfigManager *pGlobalCfgMgr = IndividualConfigManager::GetInstance();\n\t_consoleWin = TVPConsoleWindow::create(14, nullptr);\n\n\tauto glview = cocos2d::Director::getInstance()->getOpenGLView();\n\tSize screenSize = glview->getFrameSize();\n\tfloat scale = screenSize.height / getContentSize().height;\n\t_consoleWin->setScale(1 / scale);\n\t_consoleWin->setContentSize(getContentSize() * scale);\n\t_consoleWin->setFontSize(16);\n\tGameNode->addChild(_consoleWin, GAME_CONSOLE_ORDER);\n\t::Application->StartApplication(path);\n\t// update one frame\n\tupdate(0);\n\t//_ResotreGLStatues(); // already in update()\n\tGLubyte handlerOpacity = pGlobalCfgMgr->GetValue<float>(\"menu_handler_opa\", 0.15f) * 255;\n\t_gameMenu = TVPGameMainMenu::create(handlerOpacity);\n\tGameNode->addChild(_gameMenu, GAME_MENU_ORDER);\n\t_gameMenu->shrinkWithTime(1);\n\tif (_consoleWin) {\n\t\t_consoleWin->removeFromParent();\n\t\t_consoleWin = nullptr;\n\t\tscheduleUpdate();\n\n\t\tcocos2d::Director::getInstance()->purgeCachedData();\n\t\tTVPControlAdDialog(0x10002, 0, 0); // ensure to close banner ad\n\t}\n\n\tTVPWindowLayer *pWin = _lastWindowLayer;\n\twhile (pWin) {\n\t\tpWin->setVisible(true);\n\t\tpWin = pWin->_prevWindow;\n\t}\n\n\tif (pGlobalCfgMgr->GetValue<bool>(\"showfps\", false)) {\n\t\t_fpsLabel = cocos2d::Label::createWithTTF(\"\", \"DroidSansFallback.ttf\", 16);\n\t\t_fpsLabel->setAnchorPoint(Vec2(0, 1));\n\t\t_fpsLabel->setPosition(Vec2(0, GameNode->getContentSize().height));\n\t\t_fpsLabel->setColor(Color3B::WHITE);\n\t\t_fpsLabel->enableOutline(Color4B::BLACK, 1);\n\t\tGameNode->addChild(_fpsLabel, GAME_MENU_ORDER);\n\t}\n\tint fps = pGlobalCfgMgr->GetValue<int>(\"fps_limit\", 60);\n\tcocos2d::Director::getInstance()->setAnimationInterval(1.0f / fps);\n}\n\nextern ttstr TVPGetErrorDialogTitle();\nvoid TVPOnError();\ntjs_uint TVPGetGraphicCacheTotalBytes();\nvoid TVPMainScene::update(float delta) {\n\t::Application->Run();\n//\tif (_currentWindowLayer) _currentWindowLayer->UpdateOverlay();\n\tiTVPTexture2D::RecycleProcess();\n\t//_ResotreGLStatues();\n\tif (_postUpdate) _postUpdate();\n\tif (_fpsLabel) {\n\t\tunsigned int drawCount;\n\t\tuint64_t vmemsize;\n\t\tTVPGetRenderManager()->GetRenderStat(drawCount, vmemsize);\n\t\tstatic timeval _lastUpdate;\n\t\t//static int _lastUpdateReq = gettimeofday(&_lastUpdate, nullptr);\n\t\tstruct timeval now;\n\t\tgettimeofday(&now, nullptr);\n\t\tfloat _deltaTime = (now.tv_sec - _lastUpdate.tv_sec) + (now.tv_usec - _lastUpdate.tv_usec) / 1000000.0f;\n\t\t_lastUpdate = now;\n\n\t\tstatic float prevDeltaTime = 0.016f; // 60FPS\n\t\tstatic const float FPS_FILTER = 0.10f;\n\t\tstatic float _accumDt = 0;\n\t\tstatic unsigned int prevDrawCount = 0;\n\t\t_accumDt += _deltaTime;\n\t\tfloat dt = _deltaTime * FPS_FILTER + (1 - FPS_FILTER) * prevDeltaTime;\n\t\tprevDeltaTime = dt;\n\t\tif (drawCount > prevDrawCount)\n\t\t\tprevDrawCount = drawCount;\n\n\t\tchar buffer[30];\n\t\tif (_accumDt > 0.1f) {\n\t\t\tsprintf(buffer, \"%.1f (%d draws)\", 1 / dt, drawCount);\n\t\t\t_fpsLabel->setString(buffer);\n//#ifdef _MSC_VER\n\t\t\tstd::string msg = buffer; msg += \"\\n\";\n\t\t\t//sprintf(buffer, \"%.2f MB\", TVPGetGraphicCacheTotalBytes() / (float)(1024 * 1024));\n\t\t\tvmemsize >>= 10;\n\t\t\tsprintf(buffer, \"%d MB(%.2f MB) %d MB\\n\", TVPGetSelfUsedMemory(), (float)vmemsize / 1024.f, TVPGetSystemFreeMemory());\n\t\t\tmsg += buffer;\n\t\t\t_fpsLabel->setString(msg);\n//#endif\n\t\t\t_accumDt = 0;\n\t\t\tprevDrawCount = 0;\n\t\t}\n\t}\n}\n\ncocos2d::Size TVPMainScene::getUINodeSize() {\n\treturn UINode->getContentSize();\n}\n\nvoid TVPMainScene::addLayer(TVPWindowLayer* lay) {\n\tGameNode->addChild(lay, GAME_SCENE_ORDER);\n\tlay->setViewSize(GameNode->getContentSize());\n\tlay->setContentSize(lay->getViewSize());\n// \tif (_currentWindowLayer) {\n// \t\t_currentWindowLayer->setVisible(false);\n// \t}\n// \t_currentWindowLayer = lay;\n}\n\nvoid TVPMainScene::rotateUI() {\n\tfloat rot = UINode->getRotation();\n\tif (rot < 1) {\n\t\tUINode->setRotation(90);\n\t\tUINode->setContentSize(Size(UISize.height, UISize.width));\n\t} else {\n\t\tUINode->setRotation(0);\n\t\tUINode->setContentSize(UISize);\n\t}\n\tfor (Node* ui : UINode->getChildren()) {\n\t\tstatic_cast<iTVPBaseForm*>(ui)->rearrangeLayout();\n\t}\n}\n\nvoid TVPMainScene::setMaskLayTouchBegain(const std::function<bool(cocos2d::Touch *, cocos2d::Event *)> &func) {\n\t_func_mask_layer_touchbegan = func;\n}\n\nstatic float _getUIScale() {\n\tauto glview = Director::getInstance()->getOpenGLView();\n\tfloat factor = (glview->getScaleX() + glview->getScaleY()) / 2;\n\tfactor /= Device::getDPI(); // inch per pixel\n\tSize screenSize = glview->getFrameSize();\n\tSize designSize = glview->getDesignResolutionSize();\n\tdesignSize.width = designSize.height * screenSize.width / screenSize.height;\n\tscreenSize.width = factor * designSize.width;\n#ifdef _WIN32\n\t//if (screenSize.width > 3.5433) return 0.35f; // 7 inch @ 16:9 device\n\treturn 0.35f;\n#endif\n// \tchar tmp[128];\n// \tsprintf(tmp, \"screenSize.width = %f\", (float)screenSize.width);\n// \tTVPPrintLog(tmp);\n// #if CC_PLATFORM_IOS == CC_TARGET_PLATFORM\n// \treturn /*sqrtf*/(0.0005f / factor) * screenSize.width;\n// #else\n\treturn /*sqrtf*/(0.0005f / factor) * screenSize.width;\n//#endif\n}\n\nfloat TVPMainScene::getUIScale() {\n\tstatic float uiscale = _getUIScale();\n\treturn uiscale;\n}\n\nvoid TVPMainScene::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event) {\n\tVector<Node*>& uiChild = UINode->getChildren();\n\tif (!uiChild.empty()) {\n\t\tiTVPBaseForm* uiform = dynamic_cast<iTVPBaseForm*>(uiChild.back());\n\t\tif (uiform) uiform->onKeyPressed(keyCode, event);\n\t\treturn;\n\t}\n\tswitch (keyCode) {\n\tcase EventKeyboard::KeyCode::KEY_MENU:\n\t\tif (UINode->getChildren().empty()) {\n\t\t\tif (_gameMenu) _gameMenu->toggle();\n\t\t}\n\t\treturn;\n\t\tbreak;\n\tcase EventKeyboard::KeyCode::KEY_BACK:\n\t\tif (!UINode->getChildren().empty()) {\n\t\t\treturn;\n\t\t}\n\t\tif (_gameMenu && !_gameMenu->isShrinked()) {\n\t\t\t_gameMenu->shrink();\n\t\t\treturn;\n\t\t}\n\t\tkeyCode = EventKeyboard::KeyCode::KEY_ESCAPE;\n\t\tbreak;\n#ifdef _DEBUG\n\tcase EventKeyboard::KeyCode::KEY_PAUSE:\n\t\tGameNode->addChild(DebugViewLayerForm::create());\n\t\treturn;\n\tcase EventKeyboard::KeyCode::KEY_F12:\n\t\tif (TVPGetCurrentShiftKeyState() & ssShift) {\n\t\t\tstd::vector<ttstr> btns({ \"OK\", \"Cancel\" });\n\t\t\tttstr text; tTJSVariant result;\n\t\t\tif (TVPShowSimpleInputBox(text, \"console command\", \"\", btns) == 0) {\n\t\t\t\ttry {\n\t\t\t\t\tTVPExecuteExpression(text, &result);\n\t\t\t\t} catch (...) {\n\t\t\t\t\t;\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult = text;\n\t\t}\n\t\tbreak;\n#endif\n\tdefault:\n\t\tbreak;\n\t}\n\tunsigned int code = TVPConvertKeyCodeToVKCode(keyCode);\n\tif (!code || code >= 0x200) return;\n\tcode = _keymap[code];\n\n\t_scancode[code] = 0x11;\n\tif (_currentWindowLayer) {\n\t\t_currentWindowLayer->InternalKeyDown(code, TVPGetCurrentShiftKeyState());\n\t}\n}\n\nvoid TVPMainScene::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) {\n#ifdef _DEBUG\n\tif (keyCode == EventKeyboard::KeyCode::KEY_PAUSE) return;\n#endif\n\tif (keyCode == EventKeyboard::KeyCode::KEY_MENU) return;\n\tif (keyCode == EventKeyboard::KeyCode::KEY_BACK) keyCode = EventKeyboard::KeyCode::KEY_ESCAPE;\n\tif (keyCode == EventKeyboard::KeyCode::KEY_PLAY) { // auto play\n\t\tiTJSDispatch2* global = TVPGetScriptDispatch();\n\t\ttTJSVariant var;\n\t\tif (global->PropGet(0, TJS_W(\"kag\"), nullptr, &var, global) == TJS_S_OK && var.Type() == tvtObject) {\n\t\t\tiTJSDispatch2* kag = var.AsObjectNoAddRef();\n\t\t\tif (kag->PropGet(0, TJS_W(\"autoMode\"), nullptr, &var, kag) == TJS_S_OK) {\n\t\t\t\tif (var.operator bool()) {\n\t\t\t\t\tif (kag->PropGet(0, TJS_W(\"cancelAutoMode\"), nullptr, &var, kag) == TJS_S_OK && var.Type() == tvtObject) {\n\t\t\t\t\t\tiTJSDispatch2* fn = var.AsObjectNoAddRef();\n\t\t\t\t\t\tif (fn->IsInstanceOf(0, 0, 0, TJS_W(\"Function\"), fn)) {\n\t\t\t\t\t\t\ttTJSVariant *args = nullptr;\n\t\t\t\t\t\t\tfn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (kag->PropGet(0, TJS_W(\"enterAutoMode\"), nullptr, &var, kag) == TJS_S_OK && var.Type() == tvtObject) {\n\t\t\t\t\t\tiTJSDispatch2* fn = var.AsObjectNoAddRef();\n\t\t\t\t\t\tif (fn->IsInstanceOf(0, 0, 0, TJS_W(\"Function\"), fn)) {\n\t\t\t\t\t\t\ttTJSVariant *args = nullptr;\n\t\t\t\t\t\t\tfn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tglobal->Release();\n\t}\n\tunsigned int code = TVPConvertKeyCodeToVKCode(keyCode);\n\tif (!code || code >= 0x200) return;\n\tcode = _keymap[code];\n\tbool isPressed = _scancode[code] & 1;\n\t_scancode[code] &= 0x10;\n\tif (isPressed && _currentWindowLayer) {\n\t\t_currentWindowLayer->OnKeyUp(code, TVPGetCurrentShiftKeyState());\n\t}\n}\n\nTVPMainScene::TVPMainScene() {\n\t_gameMenu = nullptr;\n\t_windowMgrOverlay = nullptr;\n}\n\nvoid TVPMainScene::showWindowManagerOverlay(bool bVisible) {\n\tif (bVisible) {\n\t\tif (!_windowMgrOverlay) {\n\t\t\tif (_currentWindowLayer && _currentWindowLayer->in_mode_) return;\n\t\t\t_windowMgrOverlay = TVPWindowManagerOverlay::create();\n\t\t\tGameNode->addChild(_windowMgrOverlay, GAME_WINMGR_ORDER);\n\t\t\t_gameMenu->setVisible(false);\n\t\t}\n\t} else {\n\t\tif (_windowMgrOverlay) {\n\t\t\t_windowMgrOverlay->removeFromParent();\n\t\t\t_windowMgrOverlay = nullptr;\n\t\t\t_gameMenu->setVisible(true);\n\t\t}\n\t}\n}\n\nvoid TVPMainScene::popAllUIForm() {\n    TVPControlAdDialog(0x10002, 0, 0);\n\tauto children = UINode->getChildren();\n\tfor (auto ui : children) {\n\t\tSize size = getContentSize();\n\t\tcocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 128), size.width, size.height);\n\t\tColorMask->setPosition(Vec2(-size.width, 0));\n\t\tui->addChild(ColorMask);\n\t\tColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION));\n\t\tui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0))));\n\t\trunAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){\n\t\t\tui->removeFromParent();\n\t\t})));\n\t}\n}\n\nvoid TVPMainScene::toggleVirtualMouseCursor() {\n\tshowVirtualMouseCursor(!_mouseCursor || !_mouseCursor->isVisible());\n}\n\nSprite *TVPCreateCUR() {\n\tstd::string fullPath = FileUtils::getInstance()->fullPathForFilename(\"default.cur\");\n\tData buf = FileUtils::getInstance()->getDataFromFile(fullPath);\n\n\ttTVPMemoryStream stream(buf.getBytes(), buf.getSize());\n\treturn TVPLoadCursorCUR(&stream);\n}\n\nvoid TVPMainScene::showVirtualMouseCursor(bool bVisible) {\n\tif (!bVisible) {\n\t\tif (_mouseCursor) _mouseCursor->setVisible(false);\n\t\t_virutalMouseMode = bVisible;\n\t\treturn;\n\t}\n\tif (!_mouseCursor) {\n\t\t_mouseCursor = TVPCreateCUR();\n\t\tif (!_mouseCursor) return;\n\n\t\t_mouseCursorScale = _mouseCursor->getScale() *\n\t\t\tconvertCursorScale(IndividualConfigManager::GetInstance()->GetValue<float>(\"vcursor_scale\", 0.5f));\n\t\t_mouseCursor->setScale(_mouseCursorScale);\n\t\tGameNode->addChild(_mouseCursor, GAME_WINMGR_ORDER);\n\t\t_mouseCursor->setPosition(GameNode->getContentSize() / 2);\n\t}\n\t_mouseCursor->setVisible(true);\n\t_virutalMouseMode = bVisible;\n}\n\nbool TVPMainScene::isVirtualMouseMode() const {\n\treturn _mouseCursor && _mouseCursor->isVisible();\n}\n\nbool TVPMainScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event) {\n\tif (UINode->getChildrenCount()) return false;\n\tif (!_currentWindowLayer) return false;\n\tif (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchBegan(touch, event);\n\t_mouseTouches.insert(touch);\n\tswitch (_mouseTouches.size()) {\n\tcase 1:\n\t\t_mouseTouchPoint = GameNode->convertToNodeSpace(touch->getLocation());\n\t\t_mouseBeginPoint = _mouseCursor->getPosition();\n\t\t_touchBeginTick = TVPGetRoughTickCount32();\n\t\t_mouseMoved = false;\n\t\t_mouseClickedDown = false;\n\t\t_mouseBtn = ::mbLeft;\n\t\t_mouseCursor->stopAllActions();\n\t\t_mouseCursor->setOpacity(255);\n\t\t_mouseCursor->setScale(_mouseCursorScale);\n\t\t_mouseCursor->runAction(Sequence::createWithTwoActions(DelayTime::create(1), CallFuncN::create([this](Node*p){\n\t\t\tp->setScale(_mouseCursorScale * 0.8f);\n\t\t\t_currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(_mouseBeginPoint));\n\t\t\t_currentWindowLayer->onMouseDown(GameNode->convertToWorldSpace(_mouseBeginPoint));\n\t\t\t_mouseClickedDown = true;\n\t\t\t_mouseMoved = true;\n\t\t})));\n\t\tbreak;\n\tcase 2:\n\t\t_mouseBtn = ::mbRight;\n\t\t_mouseTouchPoint = (_mouseTouchPoint + GameNode->convertToNodeSpace(touch->getLocation())) / 2;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn true;\n}\n\nvoid TVPMainScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event) {\n\tif (!_currentWindowLayer) return;\n\tif (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchMoved(touch, event);\n\tif (_mouseTouches.size()) {\n\t\tVec2 pt, newpt;\n\t\tif (_mouseTouches.size() == 1) {\n\t\t\tpt = touch->getLocation();\n\t\t} else if (_mouseTouches.size() == 2) {\n\t\t\tauto it = _mouseTouches.begin();\n\t\t\tpt = (*it)->getLocation();\n\t\t\tpt = (pt + (*++it)->getLocation()) / 2;\n\t\t}\n\t\tVec2 moveDistance, newPoint;\n\t\tnewPoint = GameNode->convertToNodeSpace(pt);\n\t\tmoveDistance = newPoint - _mouseTouchPoint;\n\t\tpt = _mouseBeginPoint + moveDistance;\n\t\tSize size = GameNode->getContentSize();\n\t\tnewpt = pt;\n\t\tif (pt.x < 0) newpt.x = 0;\n\t\telse if (pt.x > size.width) newpt.x = size.width;\n\t\tif (pt.y < 0) newpt.y = 0;\n\t\telse if (pt.y > size.height) newpt.y = size.height;\n\t\t_mouseBeginPoint += newpt - pt;\n\t\t_mouseCursor->setPosition(newpt);\n\t\t_currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(newpt));\n\t\tif (!_mouseMoved) {\n\t\t\tif (TVPGetRoughTickCount32() - _touchBeginTick > 1000) {\n\t\t\t\t_currentWindowLayer->onMouseDown(GameNode->convertToWorldSpace(newpt));\n\t\t\t\t_mouseClickedDown = true;\n\t\t\t\t_mouseMoved = true;\n\t\t\t} else if (moveDistance.getLengthSq() > _touchMoveThresholdSq) {\n\t\t\t\t_mouseCursor->stopAllActions();\n\t\t\t\t_mouseMoved = true;\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid TVPMainScene::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event) {\n\tif (!_currentWindowLayer) return;\n\tif (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchEnded(touch, event);\n\tif (_mouseTouches.size() == 1) {\n\t\tVec2 pt = _mouseCursor->getPosition();\n\t\tif (!_mouseClickedDown && TVPGetRoughTickCount32() - _touchBeginTick < 150) {\n\t\t\t_currentWindowLayer->onMouseClick(GameNode->convertToWorldSpace(pt));\n\t\t} else if (_mouseClickedDown) {\n\t\t\t_currentWindowLayer->onMouseUp(GameNode->convertToWorldSpace(pt));\n\t\t}\n\t}\n\t_mouseTouches.erase(touch);\n\tif (_mouseTouches.size() == 0) {\n\t\t_mouseMoved = false;\n\t\t_mouseClickedDown = false;\n\t\t_refadeMouseCursor();\n\t\t_mouseCursor->setScale(_mouseCursorScale);\n\t\t_mouseCursor->stopAllActions();\n\t}\n}\n\nvoid TVPMainScene::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event) {\n\tif (!_currentWindowLayer) return;\n\tif (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchCancelled(touch, event);\n\t_mouseTouches.erase(touch);\n\t_mouseMoved = false;\n\t_refadeMouseCursor();\n}\n\nbool TVPMainScene::attachWithIME()\n{\n\tbool ret = IMEDelegate::attachWithIME();\n\tif (ret)\n\t{\n\t\t// open keyboard\n\t\tauto pGlView = Director::getInstance()->getOpenGLView();\n\t\tif (pGlView)\n\t\t{\n#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)\n\t\t\tpGlView->setIMEKeyboardState(true);\n#else\n\t\t\tpGlView->setIMEKeyboardState(true, \"\");\n#endif\n\t\t}\n\t}\n\treturn ret;\n}\n\nbool TVPMainScene::detachWithIME()\n{\n\tbool ret = IMEDelegate::detachWithIME();\n\tif (ret)\n\t{\n\t\t// close keyboard\n\t\tauto glView = Director::getInstance()->getOpenGLView();\n\t\tif (glView)\n\t\t{\n#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)\n\t\t\tglView->setIMEKeyboardState(false);\n#else\n\t\t\tglView->setIMEKeyboardState(false, \"\");\n#endif\n\t\t}\n\t}\n\treturn ret;\n}\n\nbool TVPMainScene::canAttachWithIME()\n{\n\treturn true;\n}\n\nbool TVPMainScene::canDetachWithIME()\n{\n\treturn true;\n}\n\nvoid TVPMainScene::deleteBackward()\n{\n#ifndef _WIN32\n\tif (_currentWindowLayer) {\n\t\t_currentWindowLayer->InternalKeyDown(VK_BACK, TVPGetCurrentShiftKeyState());\n\t\t_currentWindowLayer->OnKeyUp(VK_BACK, TVPGetCurrentShiftKeyState());\n\t}\n#endif\n}\n\nvoid TVPMainScene::insertText(const char * text, size_t len)\n{\n\tstd::string utf8(text, len);\n\tonTextInput(utf8);\n}\n\nvoid TVPMainScene::onCharInput(int keyCode) {\n\t_currentWindowLayer->OnKeyPress((tjs_char)keyCode, 0, false, false);\n}\n\nvoid TVPMainScene::onTextInput(const std::string &text) {\n\tstd::u16string buf;\n\tif (StringUtils::UTF8ToUTF16(text, buf)) {\n\t\tfor (int i = 0; i < buf.size(); ++i) {\n\t\t\t_currentWindowLayer->OnKeyPress(buf[i], 0, false, false);\n\t\t}\n\t}\n}\n\nvoid TVPMainScene::onAxisEvent(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) {\n\tif (!_currentWindowLayer || !_currentWindowLayer->PrimaryLayerArea) return;\n\tif (!_virutalMouseMode || _windowMgrOverlay) return;\n\tconst float threashold = 0.1f;\n\tconst cocos2d::Controller::KeyStatus& keyStatus = ctrl->getKeyStatus(keyCode);\n//\tCCLOG(\"Axis KeyCode:%d Axis Value:%f\", keyCode, keyStatus.value);\n\tif (std::abs(keyStatus.value) < threashold) {\n\t\treturn;\n\t}\n\tfloat offv = keyStatus.value;\n\tif (offv > 0) offv = (offv - threashold) / (1 - threashold);\n\telse offv = (offv + threashold) / (1 - threashold);\n\tVec2 pt = Vec2(_currentWindowLayer->_LastMouseX, _currentWindowLayer->_LastMouseY);\n\tfloat *pValue = nullptr;\n\tswitch (keyCode) {\n\tcase cocos2d::Controller::JOYSTICK_LEFT_X:\n\t\tpValue = &pt.x; break;\n\tcase cocos2d::Controller::JOYSTICK_LEFT_Y:\n\t\tpValue = &pt.y; break;\n\tdefault:\n\t\treturn;\n\t}\n\t*pValue += offv * 16;\n\tpt = _currentWindowLayer->PrimaryLayerArea->convertToWorldSpace(pt);\n\tpt = GameNode->convertToNodeSpace(pt);\n\tVec2 newpt = pt;\n\tSize size = GameNode->getContentSize();\n\tif (pt.x < 0) newpt.x = 0;\n\telse if (pt.x > size.width) newpt.x = size.width;\n\tif (pt.y < 0) newpt.y = 0;\n\telse if (pt.y > size.height) newpt.y = size.height;\n\t_mouseCursor->setPosition(newpt);\n\t_currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(newpt));\n}\n\nvoid TVPMainScene::onPadKeyDown(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) {\n\tif (!UINode->getChildren().empty()) return;\n\tunsigned int code = TVPConvertPadKeyCodeToVKCode(keyCode);\n\tif (!code || code >= 0x200) return;\n\tcode = _keymap[code];\n\t_scancode[code] = 0x11;\n\tif (_currentWindowLayer) {\n\t\t_currentWindowLayer->InternalKeyDown(code, TVPGetCurrentShiftKeyState());\n\t}\n}\n\nvoid TVPMainScene::onPadKeyUp(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) {\n\tunsigned int code = TVPConvertPadKeyCodeToVKCode(keyCode);\n\tif (!code || code >= 0x200) return;\n\tcode = _keymap[code];\n\tbool isPressed = _scancode[code] & 1;\n\t_scancode[code] &= 0x10;\n\tif (isPressed && _currentWindowLayer) {\n\t\t_currentWindowLayer->OnKeyUp(code, TVPGetCurrentShiftKeyState());\n\t}\n}\n\nvoid TVPMainScene::onPadKeyRepeat(cocos2d::Controller* ctrl, int code, cocos2d::Event *e) {\n\n}\n\nfloat TVPMainScene::convertCursorScale(float val/*0 ~ 1*/) {\n\tif (val <= 0.5f) {\n\t\treturn 0.25f + (val * 2) * 0.75f;\n\t} else {\n\t\treturn 1.f + (val - 0.5f) * 2.f;\n\t}\n}\n\niWindowLayer *TVPCreateAndAddWindow(tTJSNI_Window *w) {\n\tTVPWindowLayer* ret = TVPWindowLayer::create(w);\n\tTVPMainScene::GetInstance()->addLayer(ret);\n\tif (_consoleWin) ret->setVisible(false);\n\treturn ret;\n}\n\nvoid TVPRemoveWindowLayer(iWindowLayer *lay) {\n\tstatic_cast<TVPWindowLayer*>(lay)->removeFromParent();\n}\n\nvoid TVPConsoleLog(const ttstr &l, bool important) {\n\tstatic bool TVPLoggingToConsole = IndividualConfigManager::GetInstance()->GetValue<bool>(\"outputlog\", true);\n\tif (!TVPLoggingToConsole) return;\n\tif (_consoleWin) {\n\t\t_consoleWin->addLine(l, important ? Color3B::YELLOW : Color3B::GRAY);\n\t\tTVPDrawSceneOnce(100); // force update in 10fps\n\t}\n#ifdef _WIN32\n\t//cocos2d::log(\"%s\", utf8.c_str());\n\tchar buf[16384] = { 0 };\n\tWideCharToMultiByte(CP_ACP, 0, l.c_str(), -1, buf, sizeof(buf), nullptr, FALSE);\n\tputs(buf);\n#else\n    cocos2d::log(\"%ls\", l.c_str());\n// \tstd::string utf8;\n// \tif (StringUtils::UTF16ToUTF8(l.c_str(), utf8))\n// \t\tcocos2d::log(\"%s\", utf8.c_str());\n#endif\n}\n\nnamespace TJS {\n\tstatic const int MAX_LOG_LENGTH = 16 * 1024;\n\tvoid TVPConsoleLog(const tjs_char *l) {\n\t\tstd::string utf8;\n\t\tassert(sizeof(tjs_char) == sizeof(char16_t));\n\t\tstd::u16string buf((const char16_t*)l);\n\t\tif (StringUtils::UTF16ToUTF8(buf, utf8))\n\t\t\tcocos2d::log(\"%s\", utf8.c_str());\n\t}\n\n\tvoid TVPConsoleLog(const tjs_nchar *format, ...) {\n\t\tva_list args;\n\t\tva_start(args, format);\n\t\tchar buf[MAX_LOG_LENGTH];\n\t\tvsnprintf(buf, MAX_LOG_LENGTH - 3, format, args);\n\t\tcocos2d::log(\"%s\", buf);\n\t\tva_end(args);\n\t}\n}\n\nbool TVPGetScreenSize(tjs_int idx, tjs_int &w, tjs_int &h) {\n\tif (idx != 0) return false;\n\tconst cocos2d::Size &size = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize();\n\t//w = size.height; h = size.width;\n\tw = 2048;\n\th = w * (size.height / size.width);\n\treturn true;\n}\n\nttstr TVPGetDataPath() {\n\tstd::string path = cocos2d::FileUtils::getInstance()->getWritablePath();\n\treturn path;\n}\n\n#include \"StorageImpl.h\"\nstatic std::string _TVPGetInternalPreferencePath() {\n\tstd::string path = cocos2d::FileUtils::getInstance()->getWritablePath();\n\tpath += \".preference\";\n\tif (!TVPCheckExistentLocalFolder(path)) {\n\t\tTVPCreateFolders(path);\n\t}\n\tpath += \"/\";\n\treturn path;\n}\n\nconst std::string &TVPGetInternalPreferencePath() {\n\tstatic std::string ret = _TVPGetInternalPreferencePath();\n\treturn ret;\n}\n\ntjs_uint32 TVPGetCurrentShiftKeyState()\n{\n\ttjs_uint32 f = 0;\n\n\tif (_scancode[VK_SHIFT] & 1) f |= ssShift;\n\tif (_scancode[VK_MENU] & 1) f |= ssAlt;\n\tif (_scancode[VK_CONTROL] & 1) f |= ssCtrl;\n\tif (_scancode[VK_LBUTTON] & 1) f |= ssLeft;\n\tif (_scancode[VK_RBUTTON] & 1) f |= ssRight;\n\t//if (_scancode[VK_MBUTTON] & 1) f |= TVP_SS_MIDDLE;\n\n\treturn f;\n}\n\nttstr TVPGetPlatformName()\n{\n\tswitch (cocos2d::Application::getInstance()->getTargetPlatform()) {\n\tcase ApplicationProtocol::Platform::OS_WINDOWS:\n\t\treturn \"Win32\";\n\tcase ApplicationProtocol::Platform::OS_LINUX:\n\t\treturn \"Linux\";\n\tcase ApplicationProtocol::Platform::OS_MAC:\n\t\treturn \"MacOS\";\n\tcase ApplicationProtocol::Platform::OS_ANDROID:\n\t\treturn \"Android\";\n\tcase ApplicationProtocol::Platform::OS_IPHONE:\n\t\treturn \"iPhone\";\n\tcase ApplicationProtocol::Platform::OS_IPAD:\n\t\treturn \"iPad\";\n\tcase ApplicationProtocol::Platform::OS_BLACKBERRY:\n\t\treturn \"BlackBerry\";\n\tcase ApplicationProtocol::Platform::OS_NACL:\n\t\treturn \"Nacl\";\n\tcase ApplicationProtocol::Platform::OS_TIZEN:\n\t\treturn \"Tizen\";\n\tcase ApplicationProtocol::Platform::OS_WINRT:\n\t\treturn \"WinRT\";\n\tcase ApplicationProtocol::Platform::OS_WP8:\n\t\treturn \"WinPhone8\";\n\tdefault:\n\t\treturn \"Unknown\";\n\t}\n}\n\nttstr TVPGetOSName()\n{\n\treturn TVPGetPlatformName();\n}\n"
  },
  {
    "path": "src/core/environ/cocos2d/MainScene.h",
    "content": "#pragma once\n\n#include \"2d/CCScene.h\"\n#include \"ui/UIWidget.h\"\n#include \"base/CCIMEDelegate.h\"\n\nnamespace cocos2d {\n\tclass Controller;\n}\n\nclass TVPWindowLayer;\nclass TVPGameMainMenu;\nclass TVPMainScene : public cocos2d::Scene, public cocos2d::IMEDelegate\n{\n\tTVPMainScene();\n\tstatic TVPMainScene *create();\n\tvirtual void update(float delta) override;\n\tvoid initialize();\n\tfriend class TVPAppDelegate;\npublic:\n\tstatic TVPMainScene* GetInstance();\n\tstatic TVPMainScene* CreateInstance();\n\n\tstatic void setMaskLayTouchBegain(const std::function<bool(cocos2d::Touch *, cocos2d::Event *)> &func);\n\n\tenum eEnterAni {\n\t\teEnterAniNone,\n\t\teEnterAniOverFromRight,\n\t\teEnterFromBottom,\n\t};\n\n\tvoid pushUIForm(cocos2d::Node *node, eEnterAni ani = eEnterAniOverFromRight);\n\n\tenum eLeaveAni {\n\t\teLeaveAniNone,\n\t\teLeaveAniLeaveFromLeft,\n\t\teLeaveToBottom,\n\t};\n\tvoid popUIForm(cocos2d::Node *node, eLeaveAni ani = eLeaveAniLeaveFromLeft);\n\tvoid popAllUIForm();\n\n\tvoid addLayer(TVPWindowLayer* lay);\n\tcocos2d::Size getUINodeSize();\n\tcocos2d::Size getGameNodeSize() { return GameNode->getContentSize(); }\n\tvoid rotateUI();\n\n\tbool startupFrom(const std::string &path);\n\n\tfloat getUIScale();\n\n\tvoid showWindowManagerOverlay(bool bVisible);\n\n\tvoid toggleVirtualMouseCursor();\n\tvoid showVirtualMouseCursor(bool bVisible);\n\tbool isVirtualMouseMode() const;\n\n\tvirtual bool attachWithIME() override;\n\tvirtual bool detachWithIME() override;\n\n\tstatic void onCharInput(int keyCode);\n\tstatic void onTextInput(const std::string &text);\n\n\tstatic float convertCursorScale(float cfgScale/*0 ~ 1*/);\n\nprivate:\n\tvoid onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\tvoid onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\n\tbool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event);\n\tvoid onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event);\n\tvoid onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event);\n\tvoid onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event);\n\n\tvoid onAxisEvent(cocos2d::Controller* ctrl, int code, cocos2d::Event *e);\n\tvoid onPadKeyDown(cocos2d::Controller* ctrl, int code, cocos2d::Event *e);\n\tvoid onPadKeyUp(cocos2d::Controller* ctrl, int code, cocos2d::Event *e);\n\tvoid onPadKeyRepeat(cocos2d::Controller* ctrl, int code, cocos2d::Event *e);\n\n\tvirtual bool canAttachWithIME() override;\n\tvirtual bool canDetachWithIME() override;\n\tvirtual void deleteBackward();\n\tvirtual void insertText(const char * text, size_t len);\n\n\tvoid doStartup(float dt, std::string path);\n\n\tfloat ScreenRatio;\n\tcocos2d::Size SceneSize, UISize;\n\tcocos2d::Node *UINode, *GameNode;\n\tcocos2d::EventListenerTouchOneByOne* _touchListener;\n\tTVPGameMainMenu *_gameMenu;\n};"
  },
  {
    "path": "src/core/environ/cocos2d/YUVSprite.cpp",
    "content": "#include \"YUVSprite.h\"\n\nusing namespace cocos2d;\n\n// #define USE_VAO\n\nstatic const char *_yuvRenderProgram_fsh =\n\t\"#ifdef GL_ES\"\t\t\t\t\t\t\"\\n\"\n\t\"precision lowp float;\"\t\t\t\t\"\\n\"\n\t\"#endif\"\t\t\t\t\t\t\t\"\\n\"\n\n\t\"varying vec4 v_fragmentColor;\"\t\t\t\t\"\\n\"\n\t\"varying vec2 v_texCoord;\"\t\t\t\t\"\\n\"\n\n\t\"void main() {\"\t\t\t\t\t\t\t\t\t\t\t\t\"\\n\"\n\t\"\tvec3 yuv;\"\t\t\t\t\t\t\t\t\t\t\t\t\"\\n\"\n\t\"\tyuv.x = texture2D(CC_Texture0, v_texCoord).r - 0.0625;\"\t\t\t\"\\n\"\n\t\"\tyuv.y = texture2D(CC_Texture1, v_texCoord).r - 0.5;\"\t\"\\n\"\n\t\"\tyuv.z = texture2D(CC_Texture2, v_texCoord).r - 0.5;\"\t\"\\n\"\n\t\"\tvec3 rgb = mat3(1.164, 1.164, 1.164,\"\t\t\t\t\t\t\t\"\\n\"\n\t\"\t\t0.0, -0.392, 2.017,\"\t\t\t\t\t\t\t\"\\n\"\n\t\"\t\t1.596, -0.813, 0.0) * yuv;\"\t\t\t\t\t\t\"\\n\"\n\t\"\tgl_FragColor = vec4(rgb, 1.0) * v_fragmentColor;\"\t\t\"\\n\"\n\t\"}\"\n;\n\nstatic cocos2d::GLProgram* _getYUVRenderProgram() {\n\tstatic cocos2d::GLProgram* _program = nullptr;\n\tif (!_program) {\n\t\tstatic cocos2d::EventListenerCustom *_backgroundListener = nullptr;\n\t\tif (!_backgroundListener) {\n\t\t\t_backgroundListener = cocos2d::EventListenerCustom::create(EVENT_RENDERER_RECREATED, [](cocos2d::EventCustom*)\t{\n\t\t\t\t_program->reset();\n\t\t\t\t_program->initWithByteArrays(cocos2d::ccPositionTextureColor_vert, _yuvRenderProgram_fsh);\n\t\t\t\t_program->link();\n\t\t\t\t_program->updateUniforms();\n\t\t\t});\n\t\t\tcocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backgroundListener, -1);\n\t\t}\n\t\t_program = cocos2d::GLProgram::createWithByteArrays(cocos2d::ccPositionTextureColor_vert, _yuvRenderProgram_fsh);\n\t}\n\treturn _program;\n}\n\nvoid TVPYUVSprite::setupVBOAndVAO()\n{\n#ifdef USE_VAO\n\t//generate vbo and vao for trianglesCommand\n\tglGenVertexArrays(1, &_buffersVAO);\n\tcocos2d::GL::bindVAO(_buffersVAO);\n\n\tglGenBuffers(2, &_buffersVBO[0]);\n\n\tglBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);\n\tglBufferData(GL_ARRAY_BUFFER, sizeof(_polyInfo.triangles.verts[0]) * _polyInfo.triangles.vertCount, _polyInfo.triangles.verts, GL_DYNAMIC_DRAW);\n\n\t// vertices\n\tGL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION);\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, vertices));\n\n\t// colors\n\tGL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR);\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, colors));\n\n\t// tex coords\n\tGL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD);\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, texCoords));\n\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);\n\tglBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_polyInfo.triangles.indices[0]) * _polyInfo.triangles.indexCount, _polyInfo.triangles.indices, GL_DYNAMIC_DRAW);\n\n\t// Must unbind the VAO before changing the element buffer.\n\tGL::bindVAO(0);\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);\n\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n\n\tCHECK_GL_ERROR_DEBUG();\n#endif\n}\n\nvoid TVPYUVSprite::updateTextureDataInternal(cocos2d::Texture2D *pTex, const void* data, int width, int height, cocos2d::Texture2D::PixelFormat pixfmt)\n{\n\tconst cocos2d::Size &size = pTex->getContentSize();\n\tcocos2d::Size videoSize(width, height);\n\tif (size.width != videoSize.width || size.height != videoSize.height || pTex->getPixelFormat() != pixfmt) {\n\t\tif (size.width < videoSize.width || size.height < videoSize.height || pTex->getPixelFormat() != pixfmt) {\n\t\t\tssize_t datasize = width * height;\n\t\t\tswitch (pixfmt) {\n\t\t\tcase cocos2d::Texture2D::PixelFormat::BGRA8888:\n\t\t\tcase cocos2d::Texture2D::PixelFormat::RGBA8888:\n\t\t\t\tdatasize *= 4; break;\n\t\t\tcase cocos2d::Texture2D::PixelFormat::RGB888:\n\t\t\t\tdatasize *= 3; break;\n\t\t\tcase cocos2d::Texture2D::PixelFormat::RGB565:\n\t\t\tcase cocos2d::Texture2D::PixelFormat::AI88:\n\t\t\tcase cocos2d::Texture2D::PixelFormat::RGBA4444:\n\t\t\t\tdatasize *= 2; break;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpTex->initWithData(data, datasize, pixfmt,\n\t\t\t\twidth, height, cocos2d::Size::ZERO);\n\t\t\tpTex = nullptr;\n\t\t}\n}\n\tif (pTex) {\n\t\tpTex->updateWithData(data, 0, 0, width, height);\n\t}\n}\n\nTVPYUVSprite::~TVPYUVSprite()\n{\n\tCC_SAFE_RELEASE(_textureU);\n\tCC_SAFE_RELEASE(_textureV);\n}\n\nTVPYUVSprite* TVPYUVSprite::create()\n{\n\tTVPYUVSprite* sprite = new TVPYUVSprite;\n\tsprite->init();\n\tsprite->autorelease();\n\treturn sprite;\n}\n\nbool TVPYUVSprite::init()\n{\n\tinitWithTexture(new cocos2d::Texture2D);\n\tsetupVBOAndVAO();\n\t_drawCommand.func = std::bind(&TVPYUVSprite::onDraw, this);\n\t_textureU = new cocos2d::Texture2D; _textureU->retain();\n\t_textureV = new cocos2d::Texture2D; _textureV->retain();\n\tsetGLProgram(_getYUVRenderProgram());\n\treturn true;\n}\n\nvoid TVPYUVSprite::updateTextureData(const void* data, int width, int height)\n{\n\tcocos2d::Texture2D *pTex = getTexture();\n\tconst cocos2d::Size &size = pTex->getContentSize();\n\tupdateTextureDataInternal(getTexture(), data, width, height, cocos2d::Texture2D::PixelFormat::RGBA8888);\n\tif (size.width != width || size.height != height) {\n\t\tsetTextureRect(cocos2d::Rect(0, 0, width, height));\n\t}\n}\n\nvoid TVPYUVSprite::updateTextureData(const void* Y, int YW, int YH, const void* U, int UW, int UH, const void* V, int VW, int VH)\n{\n\tcocos2d::Texture2D *pTex = getTexture();\n\tconst cocos2d::Size &size = pTex->getContentSize();\n\tupdateTextureDataInternal(getTexture(), Y, YW, YH, cocos2d::Texture2D::PixelFormat::I8);\n\tupdateTextureDataInternal(_textureU, U, UW, UH, cocos2d::Texture2D::PixelFormat::I8);\n\tupdateTextureDataInternal(_textureV, V, VW, VH, cocos2d::Texture2D::PixelFormat::I8);\n\tif (size.width != YW || size.height != YH) {\n\t\tsetTextureRect(cocos2d::Rect(0, 0, YW, YH));\n\t}\n}\n\nvoid TVPYUVSprite::onDraw()\n{\n\tCCAssert(_polyInfo.triangles.vertCount == 4, \"\");\n#ifdef USE_VAO\n\tGL::bindVAO(_buffersVAO);\n\tglBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);\n\t//\tglBufferData(GL_ARRAY_BUFFER, sizeof(_polyInfo.triangles.verts[0]) * _polyInfo.triangles.vertCount, nullptr, GL_DYNAMIC_DRAW);\n\tvoid *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);\n\tmemcpy(buf, _polyInfo.triangles.verts, sizeof(_polyInfo.triangles.verts[0]) * 4);\n\tglUnmapBuffer(GL_ARRAY_BUFFER);\n\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);\n\tglBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_polyInfo.triangles.indices[0]) * _polyInfo.triangles.indexCount, _polyInfo.triangles.indices, GL_DYNAMIC_DRAW);\n\n\tcocos2d::GL::bindTexture2DN(0, _texture->getName());\n\tcocos2d::GL::bindTexture2DN(1, _textureU->getName());\n\tcocos2d::GL::bindTexture2DN(2, _textureV->getName());\n\tcocos2d::GL::blendFunc(_blendFunc.src, _blendFunc.dst);\n\t_glProgramState->apply(_mv);\n\tglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL);\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);\n\tGL::bindVAO(0);\n\tCHECK_GL_ERROR_DEBUG();\n\treturn;\n#endif\n\n\tcocos2d::GL::bindTexture2DN(0, _texture->getName());\n\tcocos2d::GL::bindTexture2DN(1, _textureU->getName());\n\tcocos2d::GL::bindTexture2DN(2, _textureV->getName());\n\tcocos2d::GL::blendFunc(_blendFunc.src, _blendFunc.dst);\n\t_glProgramState->apply(_mv);\n\tcocos2d::GL::enableVertexAttribs(cocos2d::GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);\n\tcocos2d::Vec3 vertices[4] = {\n\t\t_polyInfo.triangles.verts[0].vertices,\n\t\t_polyInfo.triangles.verts[1].vertices,\n\t\t_polyInfo.triangles.verts[2].vertices,\n\t\t_polyInfo.triangles.verts[3].vertices\n\t};\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, vertices);\n\tcocos2d::Color4B colors[4] = {\n\t\t_polyInfo.triangles.verts[0].colors,\n\t\t_polyInfo.triangles.verts[1].colors,\n\t\t_polyInfo.triangles.verts[2].colors,\n\t\t_polyInfo.triangles.verts[3].colors\n\t};\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors);\n\tcocos2d::Tex2F texCoords[4] = {\n\t\t_polyInfo.triangles.verts[0].texCoords,\n\t\t_polyInfo.triangles.verts[1].texCoords,\n\t\t_polyInfo.triangles.verts[2].texCoords,\n\t\t_polyInfo.triangles.verts[3].texCoords\n\t};\n\tglVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);\n\tglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\n}\n\nvoid TVPYUVSprite::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)\n{\n\t_mv = transform;\n\t_drawCommand.init(_globalZOrder);\n\trenderer->addCommand(&_drawCommand);\n}\n"
  },
  {
    "path": "src/core/environ/cocos2d/YUVSprite.h",
    "content": "#pragma once\n#include \"cocos2d.h\"\n\nclass TVPYUVSprite : public cocos2d::Sprite {\n\tcocos2d::Texture2D* _textureU = nullptr, *_textureV = nullptr;\n\tcocos2d::Texture2D::PixelFormat _texfmtY = cocos2d::Texture2D::PixelFormat::NONE,\n\t\t_texfmtU = cocos2d::Texture2D::PixelFormat::NONE,\n\t\t_texfmtV = cocos2d::Texture2D::PixelFormat::NONE;\n\tcocos2d::CustomCommand _drawCommand;\n\n\tGLuint _buffersVAO;\n\tGLuint _buffersVBO[2]; //0: vertex  1: indices\n\n\tvoid setupVBOAndVAO();\n\n\tvoid updateTextureDataInternal(cocos2d::Texture2D *pTex, const void* data, int width, int height,\n\t\tcocos2d::Texture2D::PixelFormat pixfmt);\n\npublic:\n\tvirtual ~TVPYUVSprite();\n\n\tstatic TVPYUVSprite* create();\n\n\tbool init();\n\n\tvoid updateTextureData(const void* data, int width, int height);\n\n\tvoid updateTextureData(\n\t\tconst void* Y, int YW, int YH,\n\t\tconst void* U, int UW, int UH,\n\t\tconst void* V, int VW, int VH);\n\nprivate:\n\tcocos2d::Mat4 _mv;\n\n\tvoid onDraw();\n\n\tvoid draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;\n};\n"
  },
  {
    "path": "src/core/environ/combase.h",
    "content": "#pragma once\n#include \"typedefine.h\"\n#include \"win32type.h\"\n#include <stdint.h>\n\n#ifndef S_OK\n#define S_OK            ((HRESULT)0L)\n#define S_FALSE         ((HRESULT)1L)\n#define S_UNKNOWN       ((HRESULT)0x7FFFFFFFL)\n#define E_NOINTERFACE   ((HRESULT)0x80004002L)\n#define E_INVALIDARG    ((HRESULT)0x80000003L)\n#define E_FAIL          ((HRESULT)0x80004005L)\n#define E_NOTIMPL       ((HRESULT)0x80004001L)\n#define E_NOINTERFACE   ((HRESULT)0x80004002L)\n#define E_OUTOFMEMORY   ((HRESULT)0x8007000EL)\n#define FAILED(hr)      (((HRESULT)(hr)) < 0)\n#define SUCCEEDED(hr)   (((HRESULT)(hr)) >= 0)\n#define TRUE 1\n\ntypedef struct _IID\n{\n    uint32_t x;\n\tuint16_t s1;\n\tuint16_t s2;\n\tuint8_t  c[8];\n} IID/*IID*/;\n#define REFIID const IID &\n\n#endif\n\n#ifndef STDMETHODCALLTYPE\n#ifdef WIN32\n#define STDMETHODCALLTYPE __stdcall\n#else\n#define STDMETHODCALLTYPE\n#endif\n\nclass IUnknown\n{\npublic:\n    virtual HRESULT STDMETHODCALLTYPE QueryInterface( \n        /* [in] */ REFIID riid,\n        /* [iid_is][out] */ void **ppvObject) = 0;\n\n    virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;\n\n    virtual ULONG STDMETHODCALLTYPE Release( void) = 0;\n\n};\n\nclass ISequentialStream : public IUnknown\n{\npublic:\n    virtual HRESULT STDMETHODCALLTYPE Read( \n        /* [annotation][write_to] */ \n        void *pv,\n        /* [annotation][in] */ \n        ULONG cb,\n        /* [annotation][out_opt] */ \n        ULONG *pcbRead) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE Write( \n        /* [annotation] */ \n        const void *pv,\n        /* [annotation][in] */ \n        ULONG cb,\n        /* [annotation][out_opt] */ \n        ULONG *pcbWritten) = 0;\n\n};\n\ntypedef char      OLECHAR;\ntypedef LPSTR     LPOLESTR;\ntypedef LPCSTR    LPCOLESTR;\ntypedef struct tagSTATSTG\n{\n    LPOLESTR pwcsName;\n#ifdef _MAC\n    //FSSpec is Macintosh only, defined in macos\\files.h\n    FSSpec *pspec;\n#endif //_MAC\n    DWORD type;\n    ULARGE_INTEGER cbSize;\n    FILETIME mtime;\n    FILETIME ctime;\n    FILETIME atime;\n    DWORD grfMode;\n    DWORD grfLocksSupported;\n    //CLSID clsid;\n    DWORD grfStateBits;\n    DWORD reserved;\n} \tSTATSTG;\n\ntypedef \n    enum tagSTREAM_SEEK\n{\n    STREAM_SEEK_SET\t= 0,\n    STREAM_SEEK_CUR\t= 1,\n    STREAM_SEEK_END\t= 2\n} \tSTREAM_SEEK;\n\ntypedef \n    enum tagSTATFLAG\n{\n    STATFLAG_DEFAULT\t= 0,\n    STATFLAG_NONAME\t= 1,\n    STATFLAG_NOOPEN\t= 2\n} \tSTATFLAG;\ntypedef \n    enum tagSTGTY\n{\n    STGTY_STORAGE\t= 1,\n    STGTY_STREAM\t= 2,\n    STGTY_LOCKBYTES\t= 3,\n    STGTY_PROPERTY\t= 4\n} \tSTGTY;\n#define STGM_DIRECT             0x00000000L\n#define STGM_TRANSACTED         0x00010000L\n#define STGM_SIMPLE             0x08000000L\n#define STGM_READ               0x00000000L\n#define STGM_WRITE              0x00000001L\n#define STGM_READWRITE          0x00000002L\n#define STGM_SHARE_DENY_NONE    0x00000040L\n#define STGM_SHARE_DENY_READ    0x00000030L\n#define STGM_SHARE_DENY_WRITE   0x00000020L\n#define STGM_SHARE_EXCLUSIVE    0x00000010L\nstruct IStream : public ISequentialStream\n{\npublic:\n    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Seek( \n        /* [in] */ LARGE_INTEGER dlibMove,\n        /* [in] */ DWORD dwOrigin,\n        /* [annotation] */ \n        ULARGE_INTEGER *plibNewPosition) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE SetSize( \n        /* [in] */ ULARGE_INTEGER libNewSize) = 0;\n\n    virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( \n        /* [annotation][unique][in] */ \n        IStream *pstm,\n        /* [in] */ ULARGE_INTEGER cb,\n        /* [annotation] */ \n        ULARGE_INTEGER *pcbRead,\n        /* [annotation] */ \n        ULARGE_INTEGER *pcbWritten) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE Commit( \n        /* [in] */ DWORD grfCommitFlags) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE Revert( void) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE LockRegion( \n        /* [in] */ ULARGE_INTEGER libOffset,\n        /* [in] */ ULARGE_INTEGER cb,\n        /* [in] */ DWORD dwLockType) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE UnlockRegion( \n        /* [in] */ ULARGE_INTEGER libOffset,\n        /* [in] */ ULARGE_INTEGER cb,\n        /* [in] */ DWORD dwLockType) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE Stat( \n        /* [out] */ STATSTG *pstatstg,\n        /* [in] */ DWORD grfStatFlag) = 0;\n\n    virtual HRESULT STDMETHODCALLTYPE Clone( \n        /* [out] */ IStream **ppstm) = 0;\n\n};\n#endif\n"
  },
  {
    "path": "src/core/environ/cpu_types.h",
    "content": "// ; this is a part of TVP (KIRIKIRI) software source.\n// ; see other sources for license.\n// ; (C)2001-2003 W.Dee <dee@kikyou.info> and contributors\n// \n// ;;[emit_c_h]/*[*/\n// ;;[emit_c_h]//---------------------------------------------------------------------------\n// ;;[emit_c_h]// CPU Types\n// ;;[emit_c_h]//---------------------------------------------------------------------------\n// ;;[emit_c_h]/*]*/\n// \n// ;;[emit_c_h_equ_begin]\n#pragma once\n\n#define TVP_CPU_HAS_FPU\t\t\t0x00010000\n#define TVP_CPU_HAS_MMX\t\t\t0x00020000\n#define TVP_CPU_HAS_3DN\t\t\t0x00040000\n#define TVP_CPU_HAS_SSE\t\t\t0x00080000\n#define TVP_CPU_HAS_CMOV\t\t0x00100000\n#define TVP_CPU_HAS_E3DN\t\t0x00200000\n#define TVP_CPU_HAS_EMMX\t\t0x00400000\n#define TVP_CPU_HAS_SSE2\t\t0x00800000\n#define TVP_CPU_HAS_TSC\t\t\t0x01000000\n#define TVP_CPU_HAS_NEON\t\t0x02000000\n\n#define TVP_CPU_FEATURE_MASK\t0xffff0000\n    \n#define TVP_CPU_IS_INTEL\t\t0x00000010\n#define TVP_CPU_IS_AMD\t\t\t0x00000020\n#define TVP_CPU_IS_IDT\t\t\t0x00000030\n#define TVP_CPU_IS_CYRIX\t\t0x00000040\n#define TVP_CPU_IS_NEXGEN\t\t0x00000050\n#define TVP_CPU_IS_RISE\t\t\t0x00000060\n#define TVP_CPU_IS_UMC\t\t\t0x00000070\n#define TVP_CPU_IS_TRANSMETA\t0x00000080\n#define TVP_CPU_IS_UNKNOWN\t\t0x00000000\n\n#define TVP_CPU_VENDOR_MASK\t\t0x00000ff0\n    \n#define TVP_CPU_FAMILY_X86      0x00000001\n#define TVP_CPU_FAMILY_X64      0x00000002\n#define TVP_CPU_FAMILY_ARM      0x00000003\n#define TVP_CPU_FAMILY_MIPS     0x00000003\n\n#define TVP_CPU_FAMILY_MASK\t\t0x0000000f\n\n#ifdef __cplusplus\nextern \"C\" unsigned int TVPCPUFeatures;\n#else\nextern unsigned int TVPCPUFeatures;\n#endif\n\n// ;;[emit_c_h_equ_end]\n// \n// ; note: EMMX is refered to as MMX2\n"
  },
  {
    "path": "src/core/environ/linux/Platform.cpp",
    "content": "#include \"Platform.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n#include <string.h>\n#include <sys/sysinfo.h>\n#include <sys/time.h>\n#include <sys/resource.h>\n\nvoid TVPGetMemoryInfo(TVPMemoryInfo &m)\n{\n    /* to read /proc/meminfo */\n    FILE* meminfo;\n    char buffer[100] = {0};\n    char* end;\n    int found = 0;\n\n    /* Try to read /proc/meminfo, bail out if fails */\n\tmeminfo = fopen(\"/proc/meminfo\", \"r\");\n\n    static const char\n        pszMemFree[] = \"MemFree:\",\n        pszMemTotal[] = \"MemTotal:\",\n        pszSwapTotal[] = \"SwapTotal:\",\n        pszSwapFree[] = \"SwapFree:\",\n        pszVmallocTotal[] = \"VmallocTotal:\",\n        pszVmallocUsed[] = \"VmallocUsed:\";\n\n    /* Read each line untill we got all we ned */\n    while( fgets( buffer, sizeof( buffer ), meminfo ) )\n    {\n        if( strstr( buffer, pszMemFree ) == buffer )\n        {\n            m.MemFree = strtol( buffer + sizeof(pszMemFree), &end, 10 );\n            found++;\n        }\n        else if( strstr( buffer, pszMemTotal ) == buffer )\n        {\n            m.MemTotal = strtol( buffer + sizeof(pszMemTotal), &end, 10 );\n            found++;\n        }\n        else if( strstr( buffer, pszSwapTotal ) == buffer )\n        {\n            m.SwapTotal = strtol( buffer + sizeof(pszSwapTotal), &end, 10 );\n            found++;\n            break;\n        }\n        else if( strstr( buffer, pszSwapFree ) == buffer )\n        {\n            m.SwapFree = strtol( buffer + sizeof(pszSwapFree), &end, 10 );\n            found++;\n            break;\n        }\n        else if( strstr( buffer, pszVmallocTotal ) == buffer )\n        {\n            m.VirtualTotal = strtol( buffer + sizeof(pszVmallocTotal), &end, 10 );\n            found++;\n            break;\n        }\n        else if( strstr( buffer, pszVmallocUsed ) == buffer )\n        {\n            m.VirtualUsed = strtol( buffer + sizeof(pszVmallocUsed), &end, 10 );\n            found++;\n            break;\n        }\n    }\n    fclose(meminfo);\n}\n\n#include <sched.h>\nvoid TVPRelinquishCPU(){\n\tsched_yield();\n}\n\nvoid TVP_utime(const char *name, time_t modtime) {\n\ttimeval mt[2];\n\tmt[0].tv_sec = modtime;\n\tmt[0].tv_usec = 0;\n\tmt[1].tv_sec = modtime;\n\tmt[1].tv_usec = 0;\n\tutimes(name, mt);\n}\n"
  },
  {
    "path": "src/core/environ/sdl/tvpsdl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TVP Win32 Project File\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <assert.h>\n//---------------------------------------------------------------------------\nvoid TVPOnError();\n//---------------------------------------------------------------------------\n#ifdef TVP_SUPPORT_ERI\n#\tpragma link \"../../../../Lib/liberina.lib\"\n#endif\n//---------------------------------------------------------------------------\n#if defined(WIN32) && defined(_DEBUG)\n#include <new.h>\n#define TVP_MAIN_DEBUG\n//#include <vld.h>\n#include \"GraphicsLoaderIntf.h\"\n#include <set>\n#else\n#include <new>\n#endif\n#include \"StorageIntf.h\"\n#include <thread>\n#include \"EventIntf.h\"\n#include \"Application.h\"\n#include \"SysInitImpl.h\"\n#include \"TickCount.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"DebugIntf.h\"\n//#include \"PluginImpl.h\"\n#include \"ScriptMgnImpl.h\"\n#include \"SystemIntf.h\"\n#include \"ThreadIntf.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"Exception.h\"\n\n//#define HOOK_MALLOC_FOR_OVERRUN\n//#define TC_MALLOC\n\nextern \"C\" void monstartup(const char *libname);\n\nstatic bool tc_malloc_startup = false;\n"
  },
  {
    "path": "src/core/environ/typedefine.h",
    "content": "#pragma once\n#ifndef _BASETSD_H_\n#ifndef MAX_PATH\n#define MAX_PATH  260\n#endif\n#include \"tjsTypes.h\"\n#include <stdint.h>\n\n/* public enums and structures that GDI+ reuse from the other Windows API */\n\n#define LF_FACESIZE\t\t32\n\n/* SetBkMode */\n//#define TRANSPARENT\t\t1\n//#define OPAQUE\t\t\t2\n\n/* SetMapMode */\n#define MM_TEXT\t\t\t1\n#define MM_LOMETRIC\t\t2\n#define MM_HIMETRIC\t\t3\n#define MM_LOENGLISH\t\t4\n#define MM_HIENGLISH\t\t5\n#define MM_TWIPS\t\t6\n#define MM_ISOTROPIC\t\t7\n#define MM_ANISOTROPIC\t\t8\n\n/* CreatePenIndirect */\n#define PS_NULL\t\t\t0x00000005\n#define PS_STYLE_MASK\t\t0x0000000F\n#define PS_ENDCAP_ROUND\t\t0x00000000\n#define PS_ENDCAP_SQUARE\t0x00000100\n#define PS_ENDCAP_FLAT\t\t0x00000200\n#define PS_ENDCAP_MASK\t\t0x00000F00\n#define PS_JOIN_ROUND\t\t0x00000000\n#define PS_JOIN_BEVEL\t\t0x00001000\n#define PS_JOIN_MITER\t\t0x00002000\n#define PS_JOIN_MASK\t\t0x0000F000\n\n/* CreateBrushIndirect */\n#define BS_SOLID\t\t0\n#define BS_NULL\t\t\t1\n#define BS_HATCHED\t\t2\n#define BS_PATTERN\t\t3\n#define BS_INDEXED\t\t4\n\n/* SetPolyFillMode */\n//#define ALTERNATE\t\t1\n//#define WINDING\t\t\t2\n\n/* SetRelabs */\n//#define ABSOLUTE\t\t1\n//#define RELATIVE\t\t2\n\n/* ModifyWorldTransform */\n#define MWT_IDENTITY\t\t1\n#define MWT_LEFTMULTIPLY\t2\n#define MWT_RIGHTMULTIPLY\t3\n\ntypedef int LANGID;\ntypedef int INT;\ntypedef uint32_t UINT;\ntypedef uint32_t ARGB;\ntypedef uint32_t UINT32;\ntypedef int32_t PROPID;\n//typedef uint32_t ULONG_PTR; /* not a pointer! */\ntypedef float REAL;\n\ntypedef void* HBITMAP;\ntypedef void* HDC;\ntypedef void* HENHMETAFILE;\ntypedef void* HFONT;\ntypedef void* HICON;\ntypedef void* HINSTANCE;\ntypedef void* HMETAFILE;\ntypedef void* HPALETTE;\n\n/* mono/io-layer/uglify.h also has these typedefs.\n * To avoid a dependency on mono we have copied all\n * the required stuff here. We don't include our defs\n * if uglify.h is included somehow.\n */\n//#ifndef _WAPI_UGLIFY_H_\t\t/* to avoid conflict with uglify.h */\n\n//typedef const tjs_char *LPCTSTR;\n//typedef tjs_char *LPTSTR;\ntypedef uint8_t BYTE;\ntypedef uint8_t *LPBYTE;\ntypedef uint16_t WORD;\n#ifdef _MSC_VER\n#define DWORD uint32_t\n#else\ntypedef uint32_t DWORD;\n#endif\ntypedef void* PVOID;\ntypedef void* LPVOID;\ntypedef uint32_t *LPDWORD;\ntypedef int16_t SHORT;\ntypedef int32_t LONG;\ntypedef uint32_t ULONG;\ntypedef int32_t *PLONG;\ntypedef int64_t LONGLONG;\n//typedef tjs_char TCHAR;\ntypedef size_t SIZE_T;\n\ntypedef void* HANDLE;\ntypedef void* *LPHANDLE;\ntypedef uint32_t SOCKET;\ntypedef void* HMODULE;\ntypedef void* HRGN;\n#define CONST const\n#define VOID void\n\n#define IN\n#define OUT\n//#define WINAPI\n\ntypedef unsigned char BYTE;\ntypedef unsigned char *LPBYTE;\ntypedef unsigned short WORD;\ntypedef unsigned short UINT16;\ntypedef short INT16;\ntypedef unsigned int  UINT_PTR;\ntypedef unsigned int  UINT;\ntypedef unsigned int UINT32;\ntypedef float REAL;\ntypedef int                 INT;\ntypedef signed int INT32;\n//typedef long long LONGLONG;\ntypedef uint64_t ULONGLONG;\ntypedef tjs_char *LPWSTR;\ntypedef union _ULARGE_INTEGER {\n    struct {\n        DWORD LowPart;\n        DWORD HighPart;\n    } u;\n    ULONGLONG QuadPart;\n} ULARGE_INTEGER;\ntypedef union _LARGE_INTEGER {\n    struct {\n        DWORD LowPart;\n        LONG HighPart;\n    } u;\n    LONGLONG QuadPart;\n} LARGE_INTEGER;\ntypedef char CHAR;\ntypedef CHAR *NPSTR, *LPSTR, *PSTR;\ntypedef const CHAR *LPCSTR;\ntypedef struct _FILETIME\n{\n    DWORD dwLowDateTime;\n    DWORD dwHighDateTime;\n} \tFILETIME;\ntypedef void *HWND;\n#define TYPE_RECT_DEFINED\ntypedef struct {\n\tint\tleft;\n\tint\ttop;\n\tint\tright;\n\tint\tbottom;\n} RECT, RECTL;\ntypedef intptr_t\t\t\tLONG_PTR;\ntypedef LONG HRESULT;\n#define TYPE_GUID_DEFINED\ntypedef struct {\n\tDWORD Data1;\n\tWORD  Data2;\n\tWORD  Data3;\n\tBYTE  Data4[8];\n} GUID, Guid, CLSID;\n#endif"
  },
  {
    "path": "src/core/environ/ui/BaseForm.cpp",
    "content": "#include \"BaseForm.h\"\n#include \"cocos2d.h\"\n#include \"cocostudio/ActionTimeline/CSLoader.h\"\n#include \"Application.h\"\n#include \"ui/UIWidget.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIListView.h\"\n#include \"Platform.h\"\n#include \"cocostudio/ActionTimeline/CCActionTimeline.h\"\n#include \"extensions/GUI/CCScrollView/CCTableView.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nNodeMap::NodeMap() : FileName(nullptr) { }\nNodeMap::NodeMap(const char *filename, cocos2d::Node* node) : FileName(filename) {\n\tinitFromNode(node);\n}\n\ntemplate <>\ncocos2d::Node * NodeMap::findController<cocos2d::Node>(const std::string &name, bool notice) const {\n\tauto it = this->find(name);\n\tif (it != this->end())\n\t\treturn it->second;\n\tif (notice) {\n\t\tstd::string warntext(\"Node \");\n\t\twarntext += name.c_str();\n\t\twarntext += \" not exist in \";\n\t\twarntext += FileName;\n\t\tTVPShowSimpleMessageBox(warntext, \"Fail to load ui\");\n\t}\n\treturn nullptr;\n}\n\nvoid NodeMap::initFromNode(cocos2d::Node* node) {\n\tconst Vector<Node*>& childlist = node->getChildren();\n\tfor (auto it = childlist.begin(); it != childlist.end(); ++it) {\n\t\tNode *child = *it; std::string name = child->getName();\n\t\tif (!name.empty()) (*this)[name] = child;\n\t\tinitFromNode(child);\n\t}\n}\n\nvoid NodeMap::onLoadError(const std::string &name) const\n{\n\tstd::string warntext(\"Node \");\n\twarntext += name.c_str();\n\twarntext += \" wrong controller type in \";\n\twarntext += FileName;\n\tTVPShowSimpleMessageBox(warntext, \"Fail to load ui\");\n}\n\nNode* CSBReader::Load(const char *filename) {\n\tclear();\n\tFileName = filename;\n\tNode* ret = CSLoader::createNode(filename, [this](Ref* p){\n\t\tNode* node = static_cast<Node*>(p);\n\t\tstd::string name = node->getName();\n\t\tif (!name.empty()) operator[](name) = node;\n\t\tint nAction = node->getNumberOfRunningActions();\n\t\tif (nAction == 1) {\n\t\t\tcocostudio::timeline::ActionTimeline* action =\n\t\t\t\tdynamic_cast<cocostudio::timeline::ActionTimeline*>(node->getActionByTag(node->getTag()));\n\t\t\tif (action && action->IsAnimationInfoExists(\"autoplay\")) {\n\t\t\t\taction->play(\"autoplay\", true);\n\t\t\t}\n\t\t}\n\t});\n\tif (!ret) {\n\t\tTVPShowSimpleMessageBox(filename, \"Fail to load ui file\");\n\t}\n\treturn ret;\n}\n\niTVPBaseForm::~iTVPBaseForm() {\n\n}\n\nvoid iTVPBaseForm::Show() {\n\n}\n\nbool iTVPBaseForm::initFromFile(const char *navibar, const char *body, const char *bottombar, cocos2d::Node *parent) {\n\tbool ret = cocos2d::Node::init();\n\t//NaviBar.Title = nullptr;\n\tNaviBar.Left = nullptr;\n\tNaviBar.Right = nullptr;\n\tNaviBar.Root = nullptr;\n\tCSBReader reader;\n\tif (navibar) {\n\t\tNaviBar.Root = reader.Load(navibar);\n\t\tif (!NaviBar.Root) {\n\t\t\treturn false;\n\t\t}\n// \t\tNaviBar.Title = static_cast<Button*>(reader.findController(\"title\"));\n// \t\tif (NaviBar.Title) {\n// \t\t\tNaviBar.Title->setEnabled(false); // normally\n// \t\t}\n\t\tNaviBar.Left = static_cast<Button*>(reader.findController(\"left\", false));\n\t\tNaviBar.Right = static_cast<Widget*>(reader.findController(\"right\", false));\n\t\tbindHeaderController(reader);\n\t}\n\n\tBottomBar.Root = nullptr;\n\t//BottomBar.Panel = nullptr;\n\tif (bottombar) {\n\t\tBottomBar.Root = reader.Load(bottombar);\n\t\tif (!BottomBar.Root) {\n\t\t\treturn false;\n\t\t}\n\t\t//BottomBar.Panel = static_cast<ListView*>(reader.findController(\"panel\"));\n\t\tbindFooterController(reader);\n\t}\n\tRootNode = static_cast<Widget*>(reader.Load(body));\n\tif (!RootNode) {\n\t\treturn false;\n\t}\n\tif (!parent) {\n\t\tparent = this;\n\t}\n\tparent->addChild(RootNode);\n\tif (NaviBar.Root) parent->addChild(NaviBar.Root);\n\tif (BottomBar.Root) parent->addChild(BottomBar.Root);\n\trearrangeLayout();\n\tbindBodyController(reader);\n\treturn ret;\n}\n\nvoid iTVPBaseForm::rearrangeLayout() {\n\tfloat scale = TVPMainScene::GetInstance()->getUIScale();\n\tSize sceneSize = TVPMainScene::GetInstance()->getUINodeSize();\n\tsetContentSize(sceneSize);\n\tSize bodySize = RootNode->getParent()->getContentSize();\n\tif (NaviBar.Root) {\n\t\tSize size = NaviBar.Root->getContentSize();\n\t\tsize.width = bodySize.width / scale;\n\t\tNaviBar.Root->setContentSize(size);\n\t\tNaviBar.Root->setScale(scale);\n\t\tui::Helper::doLayout(NaviBar.Root);\n\t\tsize.height *= scale;\n\t\tbodySize.height -= size.height;\n\t\tNaviBar.Root->setPosition(0, bodySize.height);\n\t}\n\tif (BottomBar.Root) {\n\t\tSize size = BottomBar.Root->getContentSize();\n\t\tsize.width = bodySize.width / scale;\n\t\tBottomBar.Root->setContentSize(size);\n\t\tBottomBar.Root->setScale(scale);\n\t\tui::Helper::doLayout(BottomBar.Root);\n\t\tsize.height *= scale;\n\t\tbodySize.height -= size.height;\n\t\tBottomBar.Root->setPosition(Vec2::ZERO);\n\t}\n\tif (RootNode) {\n\t\tbodySize.height /= scale;\n\t\tbodySize.width /= scale;\n\t\tRootNode->setContentSize(bodySize);\n\t\tRootNode->setScale(scale);\n\t\tui::Helper::doLayout(RootNode);\n\t\tif (BottomBar.Root) RootNode->setPosition(Vec2(0, BottomBar.Root->getContentSize().height * scale));\n\t}\n}\n\nvoid iTVPBaseForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) {\n\tif (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) {\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniLeaveFromLeft);\n\t}\n}\n\n// void iTVPBaseForm::initBottomBar(std::vector<std::pair<std::string, std::function<void()> > > args) {\n// \tif (!BottomBar.Panel) return;\n// \tBottomBar.Panel->removeAllItems();\n// \tCSBReader reader;\n// \tfor (auto it : args) {\n// \t\tWidget *root = static_cast<Widget*>(reader.Load(it.first.c_str()));\n// \t\tWidget *btn = static_cast<Widget*>(reader.findController(\"button\"));\n// \t\tstd::function<void()> func = it.second;\n// \t\tif (btn) btn->addClickEventListener([=](cocos2d::Ref*){ func(); });\n// \t\tBottomBar.Panel->pushBackCustomItem(root);\n// \t}\n// }\n\nvoid iTVPFloatForm::rearrangeLayout()\n{\n\tfloat scale = TVPMainScene::GetInstance()->getUIScale();\n\tSize sceneSize = TVPMainScene::GetInstance()->getUINodeSize();\n\tsetContentSize(sceneSize);\n\tVec2 center = sceneSize / 2;\n\tsceneSize.height *= 0.75f;\n\tsceneSize.width *= 0.75f;\n\tif (RootNode) {\n\t\tsceneSize.width /= scale;\n\t\tsceneSize.height /= scale;\n\t\tRootNode->setContentSize(sceneSize);\n\t\tui::Helper::doLayout(RootNode);\n\t\tRootNode->setScale(scale);\n\t\tRootNode->setAnchorPoint(Vec2(0.5f, 0.5f));\n\t\tRootNode->setPosition(center);\n\t}\n}\n\nvoid ReloadTableViewAndKeepPos(cocos2d::extension::TableView *pTableView)\n{\n\tVec2 off = pTableView->getContentOffset();\n\tfloat origHeight = pTableView->getContentSize().height;\n\tpTableView->reloadData();\n\toff.y += origHeight - pTableView->getContentSize().height;\n\tbool bounceable = pTableView->isBounceable();\n\tpTableView->setBounceable(false);\n\tpTableView->setContentOffset(off);\n\tpTableView->setBounceable(bounceable);\n}\n"
  },
  {
    "path": "src/core/environ/ui/BaseForm.h",
    "content": "#pragma once\n#include \"2d/CCNode.h\"\n#include <unordered_map>\n#include \"ui/UIWidget.h\"\n#include \"extensions/GUI/CCScrollView/CCTableViewCell.h\"\n\nnamespace cocos2d {\n\tclass Ref;\n\tclass Node;\n\tnamespace ui {\n\t\tclass Widget;\n\t\tclass Button;\n\t\tclass Text;\n\t\tclass ListView;\n\t\tclass CheckBox;\n\t\tclass PageView;\n\t\tclass TextField;\n\t\tclass Slider;\n\t\tclass ScrollView;\n\t\tclass LoadingBar;\n\t}\n\tnamespace extension {\n\t\tclass TableView;\n\t}\n}\n\nnamespace cocostudio {\n\tnamespace timeline {\n\t\tclass ActionTimeline;\n\t}\n}\n\nclass NodeMap : public std::unordered_map<std::string, cocos2d::Node*> {\nprotected:\n\tconst char *FileName;\n\tvoid onLoadError(const std::string &name) const;\n\npublic:\n\tNodeMap();\n\tNodeMap(const char *filename, cocos2d::Node* node);\n\ttemplate<typename T = cocos2d::Node>\n\tT *findController(const std::string &name, bool notice = true) const {\n\t\tcocos2d::Node *node = findController<cocos2d::Node>(name, notice);\n\t\tif (node) {\n\t\t\tT *ret = dynamic_cast<T*>(node);\n\t\t\tif (!ret) {\n\t\t\t\tonLoadError(name);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t\treturn nullptr;\n\t}\n\tcocos2d::ui::Widget *findWidget(const std::string &name, bool notice = true) const {\n\t\treturn findController<cocos2d::ui::Widget>(name, notice);\n\t}\n\tvoid initFromNode(cocos2d::Node* node);\n};\ntemplate<> cocos2d::Node *NodeMap::findController<cocos2d::Node>(const std::string &name, bool notice) const;\n\nclass CSBReader : public NodeMap {\npublic:\n\tcocos2d::Node* Load(const char *filename);\n};\n\nclass iTVPBaseForm : public cocos2d::Node {\npublic:\n\tiTVPBaseForm()\n\t\t: RootNode(nullptr){}\n\tvirtual ~iTVPBaseForm();\n\n\tvoid Show();\n\n\tvirtual void rearrangeLayout();\n\tvirtual void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\nprotected:\n\tbool initFromFile(const char *navibar, const char *body, const char *bottombar, cocos2d::Node *parent = nullptr);\n\tbool initFromFile(const char *body) {\n\t\treturn initFromFile(nullptr, body, nullptr);\n\t}\n\n\tvirtual void bindBodyController(const NodeMap &allNodes) {}\n\tvirtual void bindFooterController(const NodeMap &allNodes) {}\n\tvirtual void bindHeaderController(const NodeMap &allNodes) {}\n\n\tcocos2d::ui::Widget *RootNode;\n\n\tstruct {\n\t\t//cocos2d::ui::Button *Title;\n\t\tcocos2d::ui::Button *Left;\n\t\tcocos2d::ui::Widget *Right;\n\t\tcocos2d::Node *Root;\n\t} NaviBar;\n\n\tstruct {\n\t\t//cocos2d::ui::ListView *Panel;\n\t\tcocos2d::Node *Root;\n\t} BottomBar;\n};\n\nclass TTouchEventRouter : public cocos2d::ui::Widget {\npublic:\n\ttypedef std::function<void(cocos2d::ui::Widget::TouchEventType event,\n\t\tcocos2d::ui::Widget* sender, cocos2d::Touch *touch)> EventFunc;\n\n\tstatic TTouchEventRouter *create() {\n\t\tTTouchEventRouter * ret = new TTouchEventRouter;\n\t\tret->init();\n\t\tret->autorelease();\n\t\treturn ret;\n\t}\n\n\tvoid setEventFunc(const EventFunc &func) {\n\t\t_func = func;\n\t}\n\n\tvirtual void interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event,\n\t\tcocos2d::ui::Widget* sender, cocos2d::Touch *touch) override {\n\t\tif (_func) _func(event, sender, touch);\n\t}\n\nprivate:\n\tEventFunc _func;\n};\n\nclass TCommonTableCell : public cocos2d::extension::TableViewCell {\n\ttypedef cocos2d::extension::TableViewCell inherit;\n\nprotected: // must be inherited\n\tTCommonTableCell() : _router(nullptr) {}\n\npublic:\n\tvirtual ~TCommonTableCell() {\n\t\tif (_router) _router->release();\n\t}\n\n\tvirtual void setContentSize(const cocos2d::Size& contentSize) {\n\t\tinherit::setContentSize(contentSize);\n\t\tif (_router) _router->setContentSize(contentSize);\n\t}\n\n\tvirtual bool init() {\n\t\tbool ret = inherit::init();\n\t\t_router = TTouchEventRouter::create();\n\t\treturn ret;\n\t}\n\nprotected:\n\tTTouchEventRouter *_router;\n};\n\nclass iTVPFloatForm : public iTVPBaseForm {\npublic:\n\tvirtual void rearrangeLayout() override;\n};\n\nvoid ReloadTableViewAndKeepPos(cocos2d::extension::TableView *pTableView);\n"
  },
  {
    "path": "src/core/environ/ui/ConsoleWindow.cpp",
    "content": "#include \"ConsoleWindow.h\"\n#include \"cocos2d/MainScene.h\"\n\nusing namespace cocos2d;\n\nTVPConsoleWindow::TVPConsoleWindow() {\n\n}\n\nTVPConsoleWindow* TVPConsoleWindow::create(int fontSize, cocos2d::Node *parent) {\n\tTVPConsoleWindow *ret = new TVPConsoleWindow;\n\tret->init();\n\tret->setAnchorPoint(Vec2::ZERO);\n\tret->setFontSize(fontSize);\n\tret->autorelease();\n\tif (parent) {\n\t\tret->setContentSize(parent->getContentSize());\n\t}\n\treturn ret;\n}\n\nextern std::thread::id TVPMainThreadID;\nvoid TVPConsoleWindow::addLine(const ttstr &line, cocos2d::Color3B clr) {\n\tassert(TVPMainThreadID == std::this_thread::get_id());\n\tif (_queuedLines.size() > _maxQueueSize) {\n\t\t_queuedLines.pop_front();\n\t}\n\t_queuedLines.emplace_back(line, clr);\n}\n\n\nvoid TVPConsoleWindow::setFontSize(float size) {\n\t_fontSize = size;\n\t_maxQueueSize = getContentSize().height / size + 2;\n}\n\nvoid TVPConsoleWindow::visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) {\n\tif (!_queuedLines.empty()) {\n\t\tfloat height = 0;\n\t\tstd::vector<cocos2d::Label* > _queuedLabels;\n\t\tfor (std::pair<ttstr, cocos2d::Color3B> &line : _queuedLines) {\n\t\t\tcocos2d::Label* label;\n\t\t\tif (_unusedLabels.empty()) {\n\t\t\t\tSize dim(getContentSize());\n\t\t\t\tdim.height = 0;\n\t\t\t\tlabel = cocos2d::Label::createWithTTF(\"\", \"DroidSansFallback.ttf\", _fontSize, dim);\n\t\t\t\tlabel->setAnchorPoint(Vec2::ZERO);\n\t\t\t\taddChild(label);\n\t\t\t} else {\n\t\t\t\tlabel = _unusedLabels.back();\n\t\t\t\t_unusedLabels.pop_back();\n\t\t\t\tlabel->setVisible(true);\n\t\t\t}\n\t\t\tlabel->setColor(line.second);\n\t\t\tttstr t = line.first.length() > 200 ? line.first.SubString(0, 200) : line.first;\n\t\t\tlabel->setString(t.AsStdString());\n\t\t\tlabel->setPosition(0, height);\n\t\t\theight += label->getContentSize().height;\n\t\t\t_queuedLabels.emplace_back(label);\n\t\t}\n\t\tSize size = getContentSize();\n\t\t// remove out of range text\n\t\twhile (!_dispLabels.empty()) {\n\t\t\tcocos2d::Label* label = _dispLabels.front();\n\t\t\tconst Vec2 &pos = label->getPosition();\n\t\t\tif (pos.y + height > size.height) {\n\t\t\t\tlabel->setVisible(false);\n\t\t\t\t_unusedLabels.emplace_back(label);\n\t\t\t\t_dispLabels.pop_front();\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// adjust position\n\t\tfor (cocos2d::Label* label : _dispLabels) {\n\t\t\tVec2 pos = label->getPosition();\n\t\t\tpos.y += height;\n\t\t\tlabel->setPosition(pos);\n\t\t}\n\n\t\tfor (cocos2d::Label* label : _queuedLabels) {\n\t\t\t_dispLabels.emplace_back(label);\n\t\t}\n\t\t_queuedLabels.clear();\n\t\t_queuedLines.clear();\n\t}\n\tcocos2d::Node::visit(renderer, parentTransform, parentFlags);\n}\n"
  },
  {
    "path": "src/core/environ/ui/ConsoleWindow.h",
    "content": "#pragma once\n\n#include \"2d/CCNode.h\"\n#include \"2d/CCLabel.h\"\n#include <deque>\n#include <vector>\n#include \"tjsCommHead.h\"\n\nclass TVPConsoleWindow : public cocos2d::Node {\n\tTVPConsoleWindow();\npublic:\n\tstatic TVPConsoleWindow* create(int fontSize, cocos2d::Node *parent);\n\n\tvoid addLine(const ttstr &line, cocos2d::Color3B clr);\n\n\tvoid setFontSize(float size);\n\n\tvirtual void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags) override;\nprivate:\n\tfloat _fontSize;\n\n\tstd::deque<cocos2d::Label*> _dispLabels;\n\tstd::vector<cocos2d::Label*> _unusedLabels;\n\tstd::deque<std::pair<ttstr, cocos2d::Color3B> > _queuedLines;\n\tunsigned int _maxQueueSize;\n};\n"
  },
  {
    "path": "src/core/environ/ui/DebugViewLayerForm.cpp",
    "content": "#include \"DebugViewLayerForm.h\"\n#include \"extensions/GUI/CCScrollView/CCTableView.h\"\n#include \"WindowIntf.h\"\n#include \"DrawDevice.h\"\n#include \"cocos2d/MainScene.h\"\n#include <ui/UIButton.h>\n#include <2d/CCSprite.h>\n#include <2d/CCLabel.h>\n#include \"RenderManager.h\"\n\nUSING_NS_CC;\nUSING_NS_CC_EXT;\n\nclass DebugViewLayerForm::DebugViewLayerCell : public TableViewCell {\npublic:\n\tstatic DebugViewLayerCell* create() {\n\t\tDebugViewLayerCell* ret = new DebugViewLayerCell;\n\t\tret->autorelease();\n\t\tret->init();\n\t\treturn ret;\n\t}\n\n\tvirtual bool init() override {\n\t\tTableViewCell::init();\n\t\t_bottomLine = LayerColor::create(Color4B::WHITE, 100, 1);\n\t\taddChild(_bottomLine);\n\t\t_sprite = Sprite::create();\n\t\t_sprite->setAnchorPoint(Vec2::ZERO);\n\t\taddChild(_sprite);\n\t\t_name = Label::createWithTTF(\"\", \"DroidSansFallback.ttf\", 16);\n\t\t_name->setAnchorPoint(Vec2::ZERO);\n\t\taddChild(_name);\n\t\t_memsize = Label::createWithTTF(\"\", \"DroidSansFallback.ttf\", 16);\n\t\t_memsize->setAnchorPoint(Vec2(1, 0));\n\t\taddChild(_memsize);\n\t\treturn true;\n\t}\n\n\tvirtual void setContentSize(const Size& contentSize) override {\n\t\tTableViewCell::setContentSize(contentSize);\n\t\t_bottomLine->setContentSize(Size(contentSize.width, 2));\n\t}\n\n\tvoid setData(const Size &laySize, const LayerInfo &data) {\n\t\tfloat left = data.Indent * 5;\n\t\tiTVPTexture2D *tex = data.Texture;\n\t\tif (tex) {\n\t\t\t_sprite->setVisible(true);\n\t\t\tTexture2D* cctex = _sprite->getTexture();\n\t\t\tTexture2D* newtex = tex->GetAdapterTexture(cctex);\n\t\t\tfloat scalex, scaley;\n\t\t\ttex->GetScale(scalex, scaley);\n\t\t\tif (newtex != cctex) {\n\t\t\t\t_sprite->setTexture(newtex);\n\t\t\t\tfloat sw, sh;\n\t\t\t\tif (scalex == 1.f) sw = tex->GetWidth();\n\t\t\t\telse sw = tex->GetInternalWidth();\n\t\t\t\tif (scaley == 1.f) sh = tex->GetHeight();\n\t\t\t\telse sh = tex->GetInternalHeight();\n\t\t\t\t_sprite->setTextureRect(Rect(0, 0, sw, sh));\n\t\t\t}\n\t\t\t_sprite->setPosition(left, 2);\n\t\t\tfloat r = laySize.height / tex->GetHeight();\n\t\t\t_sprite->setScale(r * scalex, r * scaley);\n\t\t\tconst char *prefix = tex->IsStatic() ? \"static \" : \"\";\n\t\t\tchar tmp[64];\n\t\t\tsprintf(tmp, \"%s[%d x %d] %.2fMB\", prefix, (int)tex->GetWidth(), (int)tex->GetHeight(), data.VMemSize / (1024.f * 1024.f));\n\t\t\t_memsize->setVisible(true);\n\t\t\t_memsize->setString(tmp);\n\t\t\t_memsize->setPosition(laySize.width, laySize.height + 2);\n\t\t} else {\n\t\t\t_sprite->setVisible(false);\n\t\t\t_memsize->setVisible(false);\n\t\t}\n\t\t_name->setPosition(/*left*/0, laySize.height + 2);\n\t\t_name->setString(data.Name);\n\t\tSize newSize(laySize);\n\t\tnewSize.height += 24;\n\t\tsetContentSize(newSize);\n\t}\n\nprivate:\n\tLayerColor *_bottomLine;\n\tSprite *_sprite;\n\tLabel *_name, *_memsize;\n};\n\nDebugViewLayerForm * DebugViewLayerForm::create() {\n\tDebugViewLayerForm * ret = new DebugViewLayerForm;\n\tret->autorelease();\n\tret->init();\n\treturn ret;\n}\n\nclass tHackTVPDrawDevice : public tTVPDrawDevice {\npublic:\n\tiTVPLayerManager *getPrimaryLayerManager() {\n\t\treturn GetLayerManagerAt(PrimaryLayerManagerIndex);\n\t}\n};\n\nclass tHackTableView : public TableView {\npublic:\n\tvoid setSwallowTouches(bool swallow) {\n\t\tif (_touchListener) {\n\t\t\t_touchListener->setSwallowTouches(swallow);\n\t\t}\n\t}\n};\n\nstatic unsigned char _2x2_block_Image[] = {\n\t// RGBA8888\n\t0x2F, 0x2F, 0x2F, 0xFF,\n\t0x40, 0x40, 0x40, 0xFF,\n\t0x40, 0x40, 0x40, 0xFF,\n\t0x2F, 0x2F, 0x2F, 0xFF\n};\n\nbool DebugViewLayerForm::init() {\n\tNode::init();\n\tSize selfsize = TVPMainScene::GetInstance()->getGameNodeSize();\n\tsetContentSize(selfsize);\n\n\tTexture2D* tex = new Texture2D();\n\ttex->autorelease();\n\ttex->initWithData(_2x2_block_Image, 16, Texture2D::PixelFormat::RGBA8888, 2, 2, Size::ZERO);\n\ttex->setTexParameters(Texture2D::TexParams{\n\t\tGL_NEAREST, GL_NEAREST, GL_REPEAT, GL_REPEAT\n\t});\n\tSprite *_backGround = Sprite::create();\n\t_backGround->setTexture(tex);\n\t_backGround->setScale(16);\n\t_backGround->setTextureRect(Rect(0, 0, selfsize.width / 16, selfsize.height / 16));\n\t//LayerColor *_backGround = LayerColor::create(Color4B(16, 16, 16, 255), selfsize.width, selfsize.height);\n\t_backGround->setAnchorPoint(Vec2::ZERO);\n\taddChild(_backGround);\n\n\t_tableView = TableView::create(this, getContentSize());\n\t_tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);\n\tstatic_cast<tHackTableView*>(_tableView)->setSwallowTouches(true);\n\taddChild(_tableView);\n\tsetOnExitCallback(std::bind(&DebugViewLayerForm::onExitCallback, this));\n\n\t_totalSize = Label::createWithTTF(\"\", \"DroidSansFallback.ttf\", 16);\n\t_totalSize->setAnchorPoint(Vec2(1, 1));\n\n\tiTVPLayerManager *manager = static_cast<tHackTVPDrawDevice*>(TVPMainWindow->GetDrawDevice())->getPrimaryLayerManager();\n\tuint64_t totalSize = addToLayerVec(0, \"\", manager->GetPrimaryLayer());\n\tchar tmp[32];\n\tsprintf(tmp, \"%.2fMB\", (float)((double)totalSize / (1024.f * 1024.f)));\n\t_totalSize->setString(tmp);\n\taddChild(_totalSize);\n\n\tui::Button *btnClose = ui::Button::create(\"img/Cancel_Normal.png\", \"img/Cancel_Press.png\");\n\tbtnClose->setTouchEnabled(true);\n\tbtnClose->addClickEventListener([this](Ref*){\n\t\tremoveFromParent();\n\t});\n\tbtnClose->setPosition(getContentSize() - btnClose->getContentSize());\n\taddChild(btnClose);\n\t_totalSize->setPosition(btnClose->getPosition().x, getContentSize().height);\n\n\t_tableView->reloadData();\n\treturn true;\n}\n\nSize DebugViewLayerForm::tableCellSizeForIndex(TableView *table, ssize_t idx) {\n\tiTVPTexture2D *tex = _layers[idx].Texture;\n\tcocos2d::Size laySize(getContentSize().width, 0);\n\tif (tex) {\n\t\tlaySize.width = tex->GetWidth();\n\t\tlaySize.height = tex->GetHeight();\n\t\tfloat maxHeight = getContentSize().height / 2.5f;\n\t\tif (laySize.height > maxHeight) {\n\t\t\tlaySize.height = maxHeight;\n\t\t}\n\t}\n\tlaySize.height += 24;\n\treturn laySize;\n}\n\ncocos2d::extension::TableViewCell* DebugViewLayerForm::tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) {\n\tiTVPTexture2D *tex = _layers[idx].Texture;\n\tcocos2d::Size laySize(getContentSize().width, 0);\n\tif (tex) {\n\t\tlaySize.height = tex->GetHeight();\n\t\tfloat maxHeight = getContentSize().height / 2.5f;\n\t\tif (laySize.height > maxHeight) {\n\t\t\tlaySize.height = maxHeight;\n\t\t}\n\t}\n\n\tDebugViewLayerCell *cell = static_cast<DebugViewLayerCell*>(table->dequeueCell());\n\tif (!cell) cell = DebugViewLayerCell::create();\n\n\tcell->setData(laySize, _layers[idx]);\n\treturn cell;\n}\n\nvoid DebugViewLayerForm::onExitCallback() {\n\tfor (const LayerInfo& info : _layers) {\n\t\tif (info.Texture) info.Texture->Release();\n\t}\n\tTVPMainScene::GetInstance()->scheduleUpdate();\n}\n\nuint64_t DebugViewLayerForm::addToLayerVec(int indent, const std::string &prefix, tTJSNI_BaseLayer* lay) {\n\tif (!lay) return 0;\n\tiTVPBaseBitmap *img = lay->GetMainImage();\n\tiTVPTexture2D *tex = nullptr;\n\tuint64_t vmemsize = 0;\n\tif (img) {\n\t\ttex = img->GetTexture();\n\t\ttex->AddRef();\n\t\tif (!TVPGetRenderManager()->GetTextureStat(tex, vmemsize)) vmemsize = 0;\n\t}\n\tstd::string name(prefix + lay->GetName().AsStdString());\n\t_layers.emplace_back(LayerInfo{ name, tex, (size_t)vmemsize, indent++ });\n\tstd::string _prefix(name);\n\t_prefix += \"/\";\n\t//lay->GetOwnerNoAddRef()->AddRef();\n\t\n\ttjs_int childCount = lay->GetCount();\n\tfor (tjs_int i = 0; i < childCount; ++i) {\n\t\tvmemsize += addToLayerVec(indent, _prefix, lay->GetChildren(i));\n\t}\n\n\treturn vmemsize;\n}\n"
  },
  {
    "path": "src/core/environ/ui/DebugViewLayerForm.h",
    "content": "#pragma once\n#include \"2d/CCNode.h\"\n#include \"extensions/GUI/CCScrollView/CCTableView.h\"\n#include \"2d/CCLabel.h\"\n\nclass tTJSNI_BaseLayer;\nclass iTVPTexture2D;\nclass DebugViewLayerForm : public cocos2d::Node, public cocos2d::extension::TableViewDataSource {\npublic:\n\tstatic DebugViewLayerForm *create();\n\n\tvirtual bool init() override;\n\nprivate:\n\tvirtual cocos2d::Size tableCellSizeForIndex(cocos2d::extension::TableView *table, ssize_t idx) override;\n\tvirtual cocos2d::extension::TableViewCell* tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) override;\n\tvirtual ssize_t numberOfCellsInTableView(cocos2d::extension::TableView *table) override { return _layers.size(); }\n\tvoid onExitCallback();\n\tuint64_t addToLayerVec(int indent, const std::string &prefix, tTJSNI_BaseLayer* lay);\n\n\tclass DebugViewLayerCell;\n\tstruct LayerInfo {\n\t\tstd::string Name;\n\t\tiTVPTexture2D *Texture;\n\t\tsize_t VMemSize;\n\t\tint Indent;\n\t};\n\n\tcocos2d::Label *_totalSize;\n\tcocos2d::extension::TableView *_tableView;\n\t// pair<ident, layer>\n\tstd::vector<LayerInfo> _layers;\n};"
  },
  {
    "path": "src/core/environ/ui/FileSelectorForm.cpp",
    "content": "#include \"FileSelectorForm.h\"\n#include \"StorageImpl.h\"\n#include \"ui/UIListView.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UITextField.h\"\n#include \"ui/UICheckBox.h\"\n#include \"Platform.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"cocostudio/ActionTimeline/CSLoader.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"base/CCDirector.h\"\n#include \"MessageBox.h\"\n#include \"platform/CCDevice.h\"\n#include \"base/CCScheduler.h\"\n#include \"utils/TickCount.h\"\n#include <condition_variable>\n\nusing namespace cocos2d;\nusing namespace cocos2d::extension;\nusing namespace cocos2d::ui;\n\nextern std::thread::id TVPMainThreadID;\n\nconst char * const FileName_Cell = \"ui/FileItem.csb\";\nstatic TVPListForm* _listform;\n#define MOVE_INCH            7.0f/160.0f\nstatic const std::string str_long_press(\"long_press\");\n\nstatic float convertDistanceFromPointToInch(const Vec2& dis)\n{\n\tauto glview = cocos2d::Director::getInstance()->getOpenGLView();\n\tint dpi = cocos2d::Device::getDPI();\n\tfloat distance = Vec2(dis.x * glview->getScaleX() / dpi, dis.y * glview->getScaleY() / dpi).getLength();\n\treturn distance;\n}\n\nstatic bool IsPathExist(const std::string &path) {\n\ttTVP_stat s;\n\tif (!TVP_stat(path.c_str(), s)) {\n\t\treturn false; // not exist\n\t}\n\treturn true;\n}\n\nstd::pair<std::string, std::string> TVPBaseFileSelectorForm::PathSplit(const std::string &path) {\n\tstd::pair<std::string, std::string> ret;\n\tif (path.size() <= 1) {\n\t\tret.second = path;\n\t\treturn ret;\n\t}\n\tfor (auto it = path.end() - 1; it > path.begin(); --it) {\n\t\tswitch (*it) {\n\t\tcase '/': case '\\\\':\n\t\t\tif (it == path.end() - 1) {\n\t\t\t\tret.second = path;\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\tret.first = std::string(path.begin(), it);\n\t\t\tret.second = std::string(it + 1, path.end());\n\t\t\twhile(!ret.first.empty()) {\n\t\t\t\tchar c = ret.first.back();\n\t\t\t\tif (c == '/' || c == '\\\\') {\n\t\t\t\t\tret.first.pop_back();\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#if CC_PLATFORM_WIN32 != CC_TARGET_PLATFORM && CC_PLATFORM_WINRT != CC_TARGET_PLATFORM && CC_PLATFORM_WP8 != CC_TARGET_PLATFORM\n\t\t\tif (ret.first.empty()) ret.first = \"/\"; // posix root\n#endif\n\t\t\treturn ret;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\tret.second = path;\n\treturn ret;\n}\n\nTVPBaseFileSelectorForm::TVPBaseFileSelectorForm()\n\t: FileList(nullptr)\n{\n\tstd::vector<std::string> paths;\n\tgetShortCutDirList(paths); // for init \n\tstd::vector<std::string> appPath = TVPGetAppStoragePath();\n\tif (appPath.empty() && paths.size() == 1) { // ios-like sandbox environment\n\t\tRootPathLen = paths.front().size();\n\t}\n}\n\nTVPBaseFileSelectorForm::~TVPBaseFileSelectorForm() {\n\tCC_SAFE_RELEASE_NULL(CellTemplateForSize);\n}\n\nvoid TVPBaseFileSelectorForm::bindHeaderController(const NodeMap &allNodes)\n{\n\t_title = static_cast<Button*>(allNodes.findController(\"title\"));\n\tif (_title) {\n\t\t_title->setEnabled(true);\n\t\t_title->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onTitleClicked, this, std::placeholders::_1));\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::bindBodyController(const NodeMap &allNodes) {\n\tNode *TableNode = allNodes.findController(\"table\");\n\tFileList = TableView::create(this, TableNode->getContentSize());\n\tFileList->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);\n\tFileList->setAnchorPoint(Vec2::ZERO);\n\tFileList->setClippingToBounds(false);\n\tTableNode->addChild(FileList);\n// \tListView::ccListViewCallback func = [this](Ref* cell, ListView::EventType e){\n// \t\tif (e == ListView::EventType::ON_SELECTED_ITEM_END) {\n// \t\t\tonCellClicked(static_cast<ListView*>(cell)->getCurSelectedIndex());\n// \t\t}\n// \t};\n// \tFileList->addEventListener(func);\n\n\tif (NaviBar.Left) {\n\t\tNaviBar.Left->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onBackClicked, this, std::placeholders::_1));\n\t}\n}\n\nstatic const std::string _path_current(\".\");\nstatic const std::string _path_parent(\"..\");\nstatic const std::string str_diricon(\"dir_icon\");\nstatic const std::string str_select(\"select_check\");\nstatic const std::string str_filename(\"filename\");\nvoid TVPBaseFileSelectorForm::ListDir(std::string path) {\n\tstd::pair<std::string, std::string> split_path = PathSplit(path);\n\tParentPath = split_path.first;\n\tif (_title) {\n#if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM\n\t\t// for better screenshot\n\t\t_title->setTitleFontName(\"SIMHEI.ttf\");\n\t\tif (!split_path.second.empty() && (split_path.second.back() == '/' || split_path.second.back() == '\\\\')) {\n\t\t\tsplit_path.second.pop_back();\n\t\t}\n#endif\n\t\t_title->setTitleText(split_path.second);\n\n\t\tSize dispSize = _title->getTitleRenderer()->getContentSize();\n\t\tSize realSize = _title->getContentSize();\n\t\tif (dispSize.width > realSize.width) {\n\t\t\tconst std::string suffix(\"...\");\n\t\t\t_title->setTitleText(suffix);\n\t\t\tfloat suffixlen = _title->getTitleRenderer()->getContentSize().width * 1.5;\n\t\t\tfloat ratio = (realSize.width - suffixlen) / dispSize.width;\n\t\t\tttstr path = split_path.second;\n\t\t\tint charCutCount = path.length() * ratio - suffix.size() + 1;\n\t\t\tpath = path.SubString(0, charCutCount);\n\t\t\t_title->setTitleText(path.AsStdString() + suffix);\n\t\t}\n\t}\n\n\tif (path.size() > RootPathLen && path.back() == '/') {\n\t\tpath.pop_back();\n\t}\n\n\tif (NaviBar.Left) {\n\t\tNaviBar.Left->setVisible(path.size() > RootPathLen);\n\t}\n\n\tCurrentDirList.clear(); CurrentDirList.reserve(16);\n\tTVPListDir(path, [&](const std::string &name, int mask) {\n\t\tif (mask & (S_IFREG | S_IFDIR)) {\n\t\t\tif (name.empty() || name.front() == '.') return;\n\t\t\tCurrentDirList.resize(CurrentDirList.size() + 1);\n\t\t\tFileInfo &info = CurrentDirList.back();\n\t\t\tinfo.NameForDisplay = name;\n\t\t\tinfo.NameForCompare = name;\n\t\t\tinfo.IsDir = mask & S_IFDIR;\n\t\t\tstd::transform(info.NameForCompare.begin(), info.NameForCompare.end(), info.NameForCompare.begin(), [](int c)->int {\n\t\t\t\tif (c <= 'Z' && c >= 'A')\n\t\t\t\t\treturn c - ('A' - 'a');\n\t\t\t\treturn c;\n\t\t\t});\n\t\t}\n\t});\n\t// fill fullpath\n\tfor (auto it = CurrentDirList.begin(); it != CurrentDirList.end(); ++it) {\n\t\tit->FullPath = path + \"/\" + it->NameForDisplay;\n\t}\n\tstd::sort(CurrentDirList.begin(), CurrentDirList.end());\n\n\t// update\n\tbool keepPos = CurrentPath == path;\n\tCurrentPath = path;\n\tif (keepPos) {\n\t\tReloadTableViewAndKeepPos(FileList);\n\t} else {\n\t\tFileList->reloadData();\n\t}\n\n\tif (!_selectedFileIndex.empty()) {\n\t\t_selectedFileIndex.clear();\n\t\tupdateFileMenu();\n\t} else if (_clipboardForFileManager.size()) {\n\t\tupdateFileMenu();\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::onCellClicked(int idx) {\n\tconst FileInfo &info = CurrentDirList[idx];\n\tif (info.IsDir) {\n\t\tListDir(info.FullPath);\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::onCellLongPress(int idx)\n{\n\tif (_fileOperateMenuNode) { // full file function\n\t\tif (!_selectedFileIndex.empty()) {\n\t\t\treturn;\n\t\t}\n\t\tif (!_fileOperateMenu) {\n\t\t\tCSBReader reader;\n\t\t\t_fileOperateMenu = reader.Load(\"ui/FileManageMenu.csb\");\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"title\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleUnselect\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleView\", false));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleCopy\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleCut\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titlePaste\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleUnpack\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleDelete\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleSendTo\"));\n\t\t\tLocaleConfigManager::GetInstance()->initText(reader.findController<Text>(\"titleRename\"));\n\t\t\t_fileOperateMenulist = reader.findController<ListView>(\"list\");\n\t\t\t_fileOperateCell_unselect = reader.findWidget(\"unselect\");\n\t\t\t_fileOperateCell_view = reader.findWidget(\"view\", false);\n\t\t\t_fileOperateCell_copy = reader.findWidget(\"copy\");\n\t\t\t_fileOperateCell_cut = reader.findWidget(\"cut\");\n\t\t\t_fileOperateCell_paste = reader.findWidget(\"paste\");\n\t\t\t_fileOperateCell_delete = reader.findWidget(\"delete\");\n\t\t\t_fileOperateCell_unpack = reader.findWidget(\"unpack\", false);\n\t\t\t_fileOperateCell_sendto = reader.findWidget(\"sendto\");\n\t\t\t_fileOperateCell_rename = reader.findWidget(\"rename\", false);\n\t\t\tWidget *btn;;\n\t\t\tif ((btn = reader.findWidget(\"btnUnselect\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onUnselectClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnView\", false))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onViewClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnCopy\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onCopyClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnCut\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onCutClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnPaste\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onPasteClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnUnpack\", false))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onUnpackClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnDelete\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onDeleteClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnSendTo\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onSendToClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\tif ((btn = reader.findWidget(\"btnRename\"))) {\n\t\t\t\tbtn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onBtnRenameClicked, this, std::placeholders::_1));\n\t\t\t}\n\t\t\t_fileOperateMenulist->removeAllChildrenWithCleanup(false);\n\t\t\tfloat scale = 1.5;\n\t\t\t_fileOperateMenu->setScale(1 / scale);\n\t\t\t_fileOperateMenu->setContentSize(_fileOperateMenuNode->getContentSize() * scale);\n\t\t\t_fileOperateMenu->setPosition(_fileOperateMenuNode->getPosition());\n\t\t\t_fileOperateMenuNode->getParent()->addChild(_fileOperateMenu);\n\t\t\tui::Helper::doLayout(_fileOperateMenu);\n\t\t\t_fileOperateMenu->setVisible(false);\n\t\t}\n\t\tif (!_fileOperateMenu->isVisible()) {\n\t\t\t_fileOperateMenu->setVisible(true);\n\t\t//\t_fileOperateMenu->setAnchorPoint(Vec2(1, 0));\n\t\t}\n\n\t\tFileList->setTouchEnabled(false); // trick to release all touches\n\t\tFileList->setTouchEnabled(true);\n\t\t_selectedFileIndex.clear();\n\t\t_selectedFileIndex.insert(idx);\n\t\tupdateFileMenu();\n\t\treturn;\n\t}\n\t// simple file manage\n\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\tconst char *btnTitles[] = {\n\t\tlocaleMgr->GetText(\"delete\").c_str(),\n\t\tlocaleMgr->GetText(\"cancel\").c_str(),\n\t};\n\tint n = TVPShowSimpleMessageBox(\n\t\tlocaleMgr->GetText(\"file_operate_menu_text\").c_str(),\n\t\tlocaleMgr->GetText(\"file_operate_menu_title\").c_str(),\n\t\tsizeof(btnTitles) / sizeof(btnTitles[0]), btnTitles);\n\tconst FileInfo &info = CurrentDirList[idx];\n\tswitch (n) {\n\tcase 0:\n\t\t_selectedFileIndex.insert(idx);\n\t\tonDeleteClicked(nullptr);\n\t\t_selectedFileIndex.clear();\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::getShortCutDirList(std::vector<std::string> &pathlist) {\n\tstd::vector<std::string> paths = TVPGetDriverPath();\n\tfor (const std::string &path : paths) {\n\t\tpathlist.emplace_back(path);\n\t}\n\tstd::vector<std::string> appPath = TVPGetAppStoragePath();\n\tfor (auto path : appPath) {\n\t\tcocos2d::log(\"appPath: %s\", path.c_str());\n\t\tpathlist.emplace_back(path);\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::onTitleClicked(cocos2d::Ref *owner) {\n\tif (_listform) return;\n\tstd::vector<std::string> paths;\n\tgetShortCutDirList(paths);\n\n\tstd::vector<Widget*> cells;\n\tstd::vector<Button*> buttons;\n\tauto func = [this](cocos2d::Ref* node) {\n        // __android_log_print(ANDROID_LOG_INFO, \"## krkr2yuri\", \"onTitleClicked listener %p\", node);\n\t\tListDir(static_cast<Button*>(node)->getCallbackName());\n\t\tTVPMainScene::GetInstance()->popUIForm(nullptr, TVPMainScene::eLeaveToBottom);\n\t};\n\n\tfor (const std::string &path : paths) {\n\t\tCSBReader reader;\n\t\tWidget *cell = static_cast<Widget*>(reader.Load(\"ui/ListItem.csb\"));\n\t\tButton *item = dynamic_cast<Button*>(reader.findController(\"item\"));\n\t\t__android_log_print(ANDROID_LOG_INFO, \"## krkr2yuri\",\n                            \"onTitleClicked path=%s, cell=%p, item=%p, func=%p\", path.c_str(), cell, item, func);\n\n\t\t// ## fix Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x39 cocos2d::ui::LinearLayoutParameter::setGravity\n\t\t// Widget Inherits ProtectedNode, and LayoutParameterProtocol.\n//\t\tWidget* cell2 = new Widget();\n//\t\tcell2->setContentSize(cell->getContentSize());\n//      cell2->addChild(item);\n\t\titem->setContentSize(cell->getContentSize());\n\t\titem->setCallbackName(path);\n\t\titem->setTitleText(path);\n\t\titem->addClickEventListener(func);\n\t\t// ## fixme, button click position error\n\t\tcells.emplace_back(item);\n\t\tbuttons.emplace_back(item);\n\t}\n\t_listform = TVPListForm::create(cells);\n\t_listform->show();\n\n\t// march all button's text in its width\n\tfor (Button* btn : buttons) {\n\t\tSize dispSize = btn->getTitleRenderer()->getContentSize();\n\t\tSize realSize = btn->getContentSize();\n\t\tif (dispSize.width > realSize.width) {\n\t\t\tstd::string text = btn->getTitleText();\n\t\t\tfloat ratio = realSize.width / dispSize.width;\n\t\t\tconst std::string prefix(\"...\");\n\t\t\tint charCutCount = text.size() * (1 - ratio) + prefix.size() + 1;\n\t\t\tbtn->setTitleText(prefix + text.substr(charCutCount));\n\t\t}\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::onBackClicked(cocos2d::Ref *owner) {\n\tListDir(ParentPath);\n}\n\nTVPBaseFileSelectorForm::FileItemCellImpl* TVPBaseFileSelectorForm::FetchCell(FileItemCellImpl* CellModel, cocos2d::extension::TableView *table, ssize_t idx) {\n\tif (!CellModel) {\n\t\tCellModel = FileItemCellImpl::create(FileName_Cell, table->getViewSize().width);\n\t\tCellModel->setAnchorPoint(Vec2::ZERO);\n\t\tCellModel->setEventFunc([this](Widget::TouchEventType ev, Widget* sender, Touch *touch){\n\t\t\tVec2 touchPoint = touch->getLocation();\n\t\t\tswitch (ev) {\n\t\t\tcase Widget::TouchEventType::BEGAN:\n\t\t\t\tFileList->onTouchBegan(touch, nullptr);\n\t\t\t\tbreak;\n\t\t\tcase Widget::TouchEventType::MOVED:\n\t\t\t\tFileList->onTouchMoved(touch, nullptr);\n\t\t\t\tif (sender->isHighlighted() &&\n\t\t\t\t\tconvertDistanceFromPointToInch(sender->getTouchBeganPosition() - touchPoint) > MOVE_INCH) {\n\t\t\t\t\tsender->setHighlighted(false);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase Widget::TouchEventType::CANCELED:\n\t\t\t\tFileList->onTouchCancelled(touch, nullptr);\n\t\t\t\tbreak;\n\t\t\tcase Widget::TouchEventType::ENDED:\n\t\t\t\tFileList->onTouchEnded(touch, nullptr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t\tCellModel->retain();\n\t}\n\tbool selected = _selectedFileIndex.find(idx) != _selectedFileIndex.end();\n\tCellModel->setInfo(idx, CurrentDirList[idx], selected, !_selectedFileIndex.empty());\n\treturn CellModel;\n}\n\nTableViewCell* TVPBaseFileSelectorForm::tableCellAtIndex(TableView *table, ssize_t idx) {\n\tTableViewCell *pCell = table->dequeueCell();\n\tFileItemCell *cell = nullptr;\n\tif (pCell) {\n\t\tcell = static_cast<FileItemCell *>(pCell);\n\t} else {\n\t\tcell = FileItemCell::create(this);\n\t}\n\tif ((size_t)idx >= CurrentDirList.size()) {\n\t\tcell->setVisible(false);\n\t\treturn cell;\n\t}\n\tcell->setVisible(true);\n\tFileItemCellImpl *impl = cell->detach();\n\tcell->attach(FetchCell(impl, table, idx));\n\treturn cell;\n}\n\nssize_t TVPBaseFileSelectorForm::numberOfCellsInTableView(TableView *table) {\n\treturn CurrentDirList.empty() ? 0 : CurrentDirList.size() + 1;\n}\n\nSize TVPBaseFileSelectorForm::tableCellSizeForIndex(TableView *table, ssize_t idx) {\n\tif ((size_t)idx >= CurrentDirList.size()) {\n\t\treturn Size(table->getContentSize().width, 200);\n\t}\n\tFileInfo &info = CurrentDirList[idx];\n\tif (info.CellSize.width == 0.f) {\n\t\tif (!CellTemplateForSize) {\n\t\t\tCellTemplateForSize = FetchCell(nullptr, table, idx);\n\t\t} else {\n\t\t\tCellTemplateForSize->setInfo(idx, CurrentDirList[idx], false, false);\n\t\t}\n\t\tinfo.CellSize = CellTemplateForSize->getContentSize();\n\t}\n\treturn info.CellSize;\n}\n\nvoid TVPBaseFileSelectorForm::rearrangeLayout() {\n\tiTVPBaseForm::rearrangeLayout();\n\tif (FileList) FileList->setViewSize(FileList->getParent()->getContentSize());\n}\n\nvoid TVPBaseFileSelectorForm::onUnselectClicked(cocos2d::Ref *owner)\n{\n\tclearFileMenu();\n}\n\nvoid TVPBaseFileSelectorForm::onViewClicked(cocos2d::Ref *owner)\n{\n\n}\n\nvoid TVPBaseFileSelectorForm::onCopyClicked(cocos2d::Ref *owner)\n{\n\t_clipboardForMoving = false;\n\t_clipboardForFileManager.clear();\n\tfor (int idx : _selectedFileIndex) {\n\t\t_clipboardForFileManager.emplace_back(CurrentDirList[idx].FullPath);\n\t}\n\t_clipboardPath = CurrentPath;\n\t_selectedFileIndex.clear();\n\tupdateFileMenu();\n}\n\nvoid TVPBaseFileSelectorForm::onCutClicked(cocos2d::Ref *owner)\n{\n\tonCopyClicked(owner);\n\t_clipboardForMoving = true;\n}\n\nvoid TVPBaseFileSelectorForm::onPasteClicked(cocos2d::Ref *owner)\n{\n\t// TODO progress bar\n\tauto func = _clipboardForMoving ? TVPRenameFile : TVPCopyFile;\n\tfor (const std::string &path : _clipboardForFileManager) {\n\t\tauto split_path = PathSplit(path);\n\t\tstd::string target = CurrentPath + \"/\" + split_path.second;\n\t\tif (IsPathExist(target)) {\n\t\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\t\tif (TVPShowSimpleMessageBoxYesNo(target, localeMgr->GetText(\"ensure_to_override_file\")) != 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (!func(path, target)) {\n\t\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\t\tTVPShowSimpleMessageBox(target, localeMgr->GetText(\"file_operate_failed\"));\n\t\t\tbreak;\n\t\t}\n\t}\n\tclearFileMenu();\n\tListDir(CurrentPath);\n}\n\nvoid TVPBaseFileSelectorForm::onUnpackClicked(cocos2d::Ref *owner)\n{\n\tif (_selectedFileIndex.size() != 1) {\n\t\treturn;\n\t}\n\tFileInfo &info = CurrentDirList[*_selectedFileIndex.begin()];\n\t_selectedFileIndex.clear();\n\tclearFileMenu();\n\tttstr outpath = TVPChopStorageExt(info.FullPath);\n\n\tclass UnpackArchive  {\n\t\tconst int UpdateMS = 100; // update rate 10 fps\n\t\ttTVPUnpackArchive ArcUnpacker;\n\t\tstd::string ArcPath;\n\t\tstd::string PasswordBuffer;\n\n\tpublic:\n\t\tbool Init(const std::string &path, const std::string &outpath) {\n\t\t\tArcPath = path;\n\t\t\tArcUnpacker.SetCallback(\n\t\t\t\tstd::bind(&UnpackArchive::OnEnded, this),\n\t\t\t\tstd::bind(&UnpackArchive::OnError, this, std::placeholders::_1, std::placeholders::_2),\n\t\t\t\tstd::bind(&UnpackArchive::OnProgress, this, std::placeholders::_1, std::placeholders::_2),\n\t\t\t\tstd::bind(&UnpackArchive::OnNewFile, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),\n\t\t\t\tstd::bind(&UnpackArchive::OnPassword, this)\n\t\t\t);\n\t\t\tif (ArcUnpacker.Prepare(path, outpath, &TotalSize) <= 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (TotalSize > 1024 * 1024) {\n\t\t\t\tProgressForm = TVPSimpleProgressForm::create();\n\t\t\t\tTVPMainScene::GetInstance()->pushUIForm(ProgressForm, TVPMainScene::eEnterAniNone);\n\t\t\t\tstd::vector<std::pair<std::string, std::function<void(cocos2d::Ref*)> > > vecButtons;\n\t\t\t\tvecButtons.emplace_back(\"Stop\", [this](Ref*) {\n\t\t\t\t\tArcUnpacker.Stop();\n\t\t\t\t});\n\t\t\t\tProgressForm->initButtons(vecButtons);\n\t\t\t\tProgressForm->setTitle(\"Unpacking...\");\n\t\t\t\tProgressForm->setPercentOnly(0);\n\t\t\t\tProgressForm->setPercentOnly2(0);\n\t\t\t\tProgressForm->setPercentText(\"\");\n\t\t\t\tProgressForm->setPercentText2(\"\");\n\t\t\t\tProgressForm->setContent(\"\");\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tvirtual ~UnpackArchive() {\n\t\t\tif (ProgressForm) {\n\t\t\t\tTVPMainScene::GetInstance()->popUIForm(ProgressForm, TVPMainScene::eLeaveAniNone);\n\t\t\t\tProgressForm = nullptr;\n\t\t\t}\n\t\t}\n\t\tvoid Start(const std::function<void()> &onEnded) {\n\t\t\tFuncOnEnded = onEnded;\n\t\t\tArcUnpacker.Start();\n\t\t}\n\n\tprivate:\n\t\tvoid OnEnded() {\n\t\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this] {\n\t\t\t\tif (FuncOnEnded)\n\t\t\t\t\tFuncOnEnded();\n\t\t\t\tdelete this;\n\t\t\t});\n\t\t}\n\t\tvoid OnError(int err, const char *msg) {\n\t\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, err, msg] {\n\t\t\t\tchar buf[64];\n\t\t\t\tsprintf(buf, \"Error %d\\n\", err);\n\t\t\t\tttstr strmsg(buf);\n\t\t\t\tstrmsg += msg;\n\t\t\t\tTVPShowSimpleMessageBox(strmsg, TJS_W(\"Fail to unpack archive\"));\n\t\t\t});\n\t\t}\n\t\tvoid OnProgress(tjs_uint64 total_size, tjs_uint64 file_size) {\n\t\t\tif (!ProgressForm) return;\n\t\t\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\t\t\tif ((int)(tick - LastUpdate) < UpdateMS) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tLastUpdate = tick;\n\t\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, total_size, file_size] {\n\t\t\t\tProgressForm->setPercentOnly((float)total_size / TotalSize);\n\t\t\t\tProgressForm->setPercentOnly2((float)file_size / CurrentFileSize);\n\t\t\t\tchar buf[64];\n\t\t\t\tint sizeMB = static_cast<int>(total_size / (1024 * 1024)),\n\t\t\t\t\ttotalMB = static_cast<int>(TotalSize / (1024 * 1024));\n\t\t\t\tsprintf(buf, \"%d / %dMB\", sizeMB, totalMB);\n\t\t\t\tProgressForm->setPercentText(buf);\n\t\t\t\tsizeMB = static_cast<int>(file_size / (1024 * 1024));\n\t\t\t\ttotalMB = static_cast<int>(CurrentFileSize / (1024 * 1024));\n\t\t\t\tsprintf(buf, \"%d / %dMB\", sizeMB, totalMB);\n\t\t\t\tProgressForm->setPercentText2(buf);\n\t\t\t});\n\t\t}\n\t\tvoid OnNewFile(int idx, const std::string &utf8name, tjs_uint64 file_size) {\n\t\t\tif (!ProgressForm) return;\n\t\t\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\t\t\tif ((int)(tick - LastUpdate) < UpdateMS && file_size < 1024 * 1024) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tLastUpdate = tick;\n\t\t\tCurrentFileSize = file_size;\n\t\t\tstd::string filename(utf8name);\n\t\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, filename] {\n\t\t\t\tProgressForm->setContent(filename);\n\t\t\t});\n\t\t}\n\t\tbool _onPassword() {\n\t\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\t\tstd::vector<ttstr> btns;\n\t\t\tbtns.emplace_back(localeMgr->GetText(\"ok\"));\n\t\t\tbtns.emplace_back(localeMgr->GetText(\"cancel\"));\n\t\t\tttstr text(ArcPath);\n\t\t\tif (TVPShowSimpleInputBox(text, localeMgr->GetText(\"please_input_password\"), \"\", btns) == 0) {\n\t\t\t\tPasswordBuffer = text.AsStdString();\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\tArcUnpacker.Stop();\n\t\t\t\tPasswordBuffer.clear();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tstd::string OnPassword() {\n\t\t\tif (TVPMainThreadID == std::this_thread::get_id()) {\n\t\t\t\t_onPassword();\n\t\t\t} else {\n\t\t\t\tstd::mutex mtx;\n\t\t\t\tstd::condition_variable cond;\n\t\t\t\tstd::unique_lock<std::mutex> lk(mtx);\n\t\t\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([&]() {\n\t\t\t\t\t_onPassword();\n\t\t\t\t\tcond.notify_all();\n\t\t\t\t});\n\t\t\t\tcond.wait(lk);\n\t\t\t}\n\t\t\treturn PasswordBuffer;\n\t\t}\n\n\t\tTVPSimpleProgressForm *ProgressForm = nullptr;\n\t\ttjs_uint32 LastUpdate = 0;\n\t\ttjs_uint64 TotalSize, CurrentFileSize;\n\t\tstd::function<void()> FuncOnEnded;\n\t};\n\tUnpackArchive *unpacker = new UnpackArchive;\n\t// using libarchive to unpack archive\n\tif (unpacker->Init(info.FullPath, outpath.AsStdString())) {\n\t\tunpacker->Start([this]() {\n\t\t\tListDir(CurrentPath);\n\t\t});\n\t\treturn;\n\t}\n\tdelete unpacker;\n\n\t// use internal archive module\n\ttTVPArchive *arc = TVPOpenArchive(info.FullPath, false);\n\tif (!arc) {\n\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\tTVPShowSimpleMessageBox(info.FullPath, localeMgr->GetText(\"fail_to_open_archive\"));\n\t\treturn;\n\t}\n\t\n\ttjs_uint count = arc->GetCount();\n\tfor (tjs_uint i = 0; i < count; ++i) {\n\t\tttstr name = arc->GetName(i);\n\t\tttstr fullpath = outpath + name;\n\t\ttTJSBinaryStream *st = arc->CreateStreamByIndex(i);\n\t\tif (!st) continue;\n\t\tTVPSaveStreamToFile(st, 0, st->GetSize(), fullpath);\n\t\tdelete st;\n\t}\n\n\tdelete arc;\n}\n\nvoid TVPBaseFileSelectorForm::onDeleteClicked(cocos2d::Ref *owner)\n{\n\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\tstd::string content;\n\tif (_selectedFileIndex.size() == 1) {\n\t\tconst FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()];\n\t\tcontent = info.FullPath;\n\t} else {\n\t\tcontent = localeMgr->GetText(\"ensure_item_count\");\n\t\tchar tmp[64];\n\t\tsnprintf(tmp, 64, content.c_str(), _selectedFileIndex.size());\n\t\tcontent = tmp;\n\t}\n\tif (TVPShowSimpleMessageBoxYesNo(content, localeMgr->GetText(\"ensure_to_delete_file\")) == 0) {\n\t\tfor (int idx : _selectedFileIndex) {\n\t\t\tTVPDeleteFile(CurrentDirList[idx].FullPath);\n\t\t}\n\t\tscheduleOnce([this](float) {\n\t\t\tListDir(CurrentPath);\n\t\t}, 0, \"refresh_path\");\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::onSendToClicked(cocos2d::Ref *owner)\n{\n\tif (_selectedFileIndex.size() != 1) return;\n\tFileInfo &info = CurrentDirList[*_selectedFileIndex.begin()];\n\tTVPSendToOtherApp(info.FullPath);\n\tclearFileMenu();\n}\n\nvoid TVPBaseFileSelectorForm::onBtnRenameClicked(cocos2d::Ref *owner)\n{\n\tif (_selectedFileIndex.size() != 1) return;\n\tFileInfo &info = CurrentDirList[*_selectedFileIndex.begin()];\n\tttstr name = info.NameForDisplay.c_str();\n\tstd::vector<ttstr> btns;\n\tbtns.emplace_back(\"OK\");\n\tbtns.emplace_back(\"Cancel\");\n\tif (TVPShowSimpleInputBox(name, \"Input new name\", \"\", btns) == 0) {\n\t\tttstr newname = TVPExtractStoragePath(info.FullPath);\n\t\tnewname += name;\n\t\tstd::string strNewName = newname.AsNarrowStdString();\n\t\tTVPRenameFile(info.FullPath, strNewName);\n\t\tinfo.FullPath = strNewName;\n\t\tinfo.NameForDisplay = name.AsNarrowStdString();\n\t\tReloadTableViewAndKeepPos(FileList);\n\t}\n\tclearFileMenu();\n}\n\nvoid TVPBaseFileSelectorForm::updateFileMenu()\n{\n\tReloadTableViewAndKeepPos(FileList);\n\tif (_selectedFileIndex.empty() && _clipboardForFileManager.empty()) { // close menu\n\t\tif (_fileOperateMenu->isVisible()) {\n\t\t\t_fileOperateMenu->setVisible(false);\n\t\t//\t_fileOperateMenu->setAnchorPoint(Vec2(0, 0));\n\t\t}\n\t\treturn;\n\t}\n\t_fileOperateMenulist->removeAllChildrenWithCleanup(false);\n\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_unselect.get());\n\tif (!_clipboardForFileManager.empty() && _clipboardPath != CurrentPath) {\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_paste.get());\n\t}\n\tif (_selectedFileIndex.size() == 1) {\n\t\tif (_fileOperateCell_view) _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_view.get());\n\t\tFileInfo &info = CurrentDirList[*_selectedFileIndex.begin()];\n\t\tif (!info.IsDir) _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_unpack.get());\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_rename.get());\n#if CC_PLATFORM_IOS == CC_TARGET_PLATFORM // TODO implement other platform\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_sendto.get());\n#endif\n\t}\n\tif (!_selectedFileIndex.empty()) {\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_copy.get());\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_cut.get());\n\t\t_fileOperateMenulist->pushBackCustomItem(_fileOperateCell_delete.get());\n\t}\n}\n\nvoid TVPBaseFileSelectorForm::clearFileMenu()\n{\n\t_selectedFileIndex.clear();\n\t_clipboardForFileManager.clear();\n\tupdateFileMenu();\n}\n\nvoid TVPBaseFileSelectorForm::_onCellClicked(int idx)\n{\n\tif (_selectedFileIndex.empty())\n\t\treturn onCellClicked(idx);\n\tauto it = _selectedFileIndex.find(idx);\n\tif (it == _selectedFileIndex.end()) {\n\t\t_selectedFileIndex.insert(idx);\n\t} else {\n\t\t_selectedFileIndex.erase(idx);\n\t}\n\tupdateFileMenu();\n}\n\nbool TVPBaseFileSelectorForm::FileInfo::operator<(const FileInfo &rhs) const {\n\tif (IsDir != rhs.IsDir) return IsDir > rhs.IsDir;\n\treturn NameForCompare < rhs.NameForCompare;\n}\n\nTVPListForm * TVPListForm::create(const std::vector<cocos2d::ui::Widget*> &cells) {\n\tTVPListForm *ret = new TVPListForm;\n\tret->initFromInfo(cells);\n\tret->autorelease();\n\treturn ret;\n}\n\nvoid TVPListForm::initFromInfo(const std::vector<cocos2d::ui::Widget*> &cells) {\n\tinit();\n\tfloat scale = TVPMainScene::GetInstance()->getUIScale();\n\tcocos2d::Size sceneSize = TVPMainScene::GetInstance()->getUINodeSize() / scale;\n\tsetScale(scale);\n\tsetContentSize(sceneSize);\n\tCSBReader reader;\n\t_root = reader.Load(\"ui/ListView.csb\");\n\tListView* listview = dynamic_cast<ListView*>(reader.findController(\"list\"));\n\n\tfloat height = 10;\n\tfor (Widget* cell : cells) {\n\t\theight += cell->getContentSize().height;\n\t}\n\n\t_root->setAnchorPoint(Size(0.5, 0.5));\n\t_root->setPosition(sceneSize / 2);\n\tsceneSize.width *= 0.8f;\n\tsceneSize.height *= 0.8f;\n\tif (height < sceneSize.height * scale) {\n\t\tsceneSize.height = height;\n\t}\n\t_root->setContentSize(sceneSize);\n\tui::Helper::doLayout(_root);\n\tfloat width = listview->getContentSize().width;\n\tint i=0;\n\tfor (Widget* cell : cells) {\n\t\tSize size = cell->getContentSize();\n\t\tsize.width = width;\n\t\tcell->setContentSize(size);\n\t\tui::Helper::doLayout(cell);\n\t\tlistview->pushBackCustomItem(cell);\n\t}\n\tif(!listview->getItems().empty()) {\n\t\tif (listview->getItems().back()->getBottomBoundary() < 0) {\n\t\t\tlistview->setClippingEnabled(true);\n\t\t} else {\n\t\t\tlistview->setBounceEnabled(false);\n\t\t}\n\t}\n\taddChild(_root);\n\t// __android_log_print(ANDROID_LOG_INFO, \"## krkr2yuri\", \"after initFromInfo\");\n}\n\nvoid TVPListForm::show() {\n\tTVPMainScene::setMaskLayTouchBegain(std::bind(&TVPListForm::onMaskTouchBegan, this, std::placeholders::_1, std::placeholders::_2));\n\tTVPMainScene::GetInstance()->pushUIForm(this, TVPMainScene::eEnterFromBottom);\n}\n\nbool TVPListForm::onMaskTouchBegan(cocos2d::Touch *t, cocos2d::Event *) {\n\tRect rc;\n\trc.size = getContentSize();\n\tif (rc.containsPoint(convertTouchToNodeSpace(t))) {\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nTVPListForm::~TVPListForm() {\n\tif (_listform == this) _listform = nullptr;\n}\n\nint TVPDrawSceneOnce(int interval);\nvoid TVPProcessInputEvents();\nstd::string TVPShowFileSelector(const std::string &title, const std::string &initfilename, std::string initdir, bool issave)\n{\n\tif (initdir.empty()) {\n\t\tttstr dir = TVPGetAppPath();\n\t\tTVPGetLocalName(dir);\n\t\tinitdir = dir.AsStdString();\n\t}\n\tstd::string _fileSelectorResult;\n\tTVPFileSelectorForm* _fileSelector = TVPFileSelectorForm::create(initfilename, initdir, issave);\n\t_fileSelector->setOnClose([&](const std::string &result) {\n\t\t_fileSelectorResult = result;\n\t\t_fileSelector = nullptr;\n\t});\n\tTVPMainScene::GetInstance()->pushUIForm(_fileSelector);\n\tDirector* director = Director::getInstance();\n\twhile (_fileSelector) {\n\t\tTVPProcessInputEvents();\n\t\tint remain = TVPDrawSceneOnce(30); // 30 fps\n\t\tif (remain > 0) {\n            std::this_thread::sleep_for(std::chrono::milliseconds(remain));\n\t\t}\n\t}\n\treturn _fileSelectorResult;\n}\n\nconst char * const FileName_NaviBar = \"ui/NaviBar.csb\";\nconst char * const FileName_Body = \"ui/TableView.csb\";\nconst char * const FileName_BottomBar = \"ui/BottomBarTextInput.csb\";\n\nTVPFileSelectorForm * TVPFileSelectorForm::create(const std::string &initfilename, const std::string &initdir, bool issave)\n{\n\tTVPFileSelectorForm *ret = new TVPFileSelectorForm;\n\tret->autorelease();\n\tret->initFromPath(initfilename, initdir, issave);\n\treturn ret;\n}\n\nvoid TVPFileSelectorForm::initFromPath(const std::string &initfilename, const std::string &initdir, bool issave) {\n\t_isSaveMode = issave;\n\tinitFromFile(FileName_NaviBar, FileName_Body, FileName_BottomBar);\n\t_input->setString(initfilename);\n\tListDir(initdir); // getCurrentDir()\n}\n\nvoid TVPFileSelectorForm::bindFooterController(const NodeMap &allNodes) {\n\t_buttonOK = static_cast<Button*>(allNodes.findController(\"ok\"));\n\t_buttonCancel = static_cast<Button*>(allNodes.findController(\"cancel\"));\n\t_input = static_cast<TextField*>(allNodes.findController(\"input\"));\n\t\n\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\tlocaleMgr->initText(_buttonOK, \"ok\");\n\tlocaleMgr->initText(_buttonCancel, \"cancel\");\n\t_buttonOK->addClickEventListener([this](Ref*){\n\t\t_result = _input->getString();\n\t\tif (!_result.empty()) {\n\t\t\t_result = CurrentPath + \"/\" + _result;\n\t\t\tbool fileExist = FileUtils::getInstance()->isFileExist(_result);\n\t\t\tif (_isSaveMode) {\n\t\t\t\tif (fileExist) {\n\t\t\t\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\t\t\t\tTVPMessageBoxForm::showYesNo(localeMgr->GetText(\"ensure_to_override_file\"), _result,\n\t\t\t\t\t\t[this](int result) {\n\t\t\t\t\t\tif (result == 0) { // yes\n\t\t\t\t\t\t\tclose();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tclose();\n\t\t\t\t}\n\t\t\t} else { // read mode\n\t\t\t\tif (fileExist) {\n\t\t\t\t\tclose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t_buttonCancel->addClickEventListener([this](Ref*){\n\t\t_result.clear();\n\t\tclose();\n\t});\n}\n\nvoid TVPFileSelectorForm::onCellClicked(int idx) {\n\tFileInfo info = CurrentDirList[idx];\n\tTVPBaseFileSelectorForm::onCellClicked(idx);\n\tif (info.IsDir) {\n\t} else {\n\t\t_input->setString(info.NameForDisplay);\n\t}\n}\n\nvoid TVPFileSelectorForm::close() {\n\tif (_funcOnClose) _funcOnClose(_result);\n\tTVPMainScene::GetInstance()->popUIForm(this);\n}\n\nvoid TVPBaseFileSelectorForm::FileItemCellImpl::initFromFile(const char * filename, float width) {\n\tCSBReader reader;\n\t_root = reader.Load(filename);\n\taddChild(_root);\n\tOrigCellModelSize = _root->getContentSize();\n\tOrigCellModelSize.width = width;\n\t_root->setContentSize(OrigCellModelSize);\n\tsetContentSize(OrigCellModelSize);\n\tDirIcon = reader.findController(str_diricon);\n\tSelectBox = reader.findController<CheckBox>(str_select);\n\t//SelectBox->setTouchEnabled(false);\n\tFileNameNode = static_cast<Text *>(reader.findController(str_filename));\n\tif (DirIcon && FileNameNode) {\n\t\tCellTextAreaSize = DirIcon->getContentSize();\n\t\tCellTextAreaSize.width = OrigCellModelSize.width - CellTextAreaSize.width;\n\t\tCellTextAreaSize.height = 0;\n\t\tOrigCellTextSize = FileNameNode->getContentSize();\n#if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM\n\t\tFileNameNode->setFontName(\"SIMHEI.ttf\");\n#endif\n\t}\n\tstatic const std::string str_highlight(\"highlight\");\n\tWidget *HighLight = static_cast<Widget *>(reader.findController(str_highlight));\n\tif (HighLight) {\n\t\tHighLight->addClickEventListener(std::bind(&FileItemCellImpl::onClicked, this, std::placeholders::_1));\n\t\tHighLight->addTouchEventListener([this](Ref* p, Widget::TouchEventType ev){\n\t\t\tWidget* sender = static_cast<Widget*>(p);\n\t\t\tswitch (ev) {\n\t\t\tcase Widget::TouchEventType::BEGAN:\n\t\t\t\tsender->scheduleOnce([this, sender](float){\n\t\t\t\t\tif (sender->isHighlighted()) {\n\t\t\t\t\t\tsender->scheduleOnce([this, sender](float){\n\t\t\t\t\t\t\t_owner->onLongPress();\n\t\t\t\t\t\t\tsender->setHighlighted(false);\n\t\t\t\t\t\t//\tsender->interceptTouchEvent(TouchEventType::CANCELED, sender, touch);\n\t\t\t\t\t\t}, 0, \"delay_call\");\n\t\t\t\t\t}\n\t\t\t\t}, 1.0f, str_long_press);\n\t\t\t\tbreak;\n\t\t\t// ## fix scole bug\n            case Widget::TouchEventType::MOVED: {\n                auto diff = sender->getTouchMovePosition() - sender->getTouchBeganPosition();\n                if (abs(diff.x) > 5 and abs(diff.y) > 5) {\n                    sender->unschedule(str_long_press);\n                }\n                break;\n            }\n\t\t\tcase Widget::TouchEventType::CANCELED:\n\t\t\t\tsender->unschedule(str_long_press);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\tHighLight->setSwallowTouches(false);\n\t}\n\tBgOdd = reader.findController(\"bg_odd\", false);\n\tBgEven = reader.findController(\"bg_even\", false);\n}\n\nvoid TVPBaseFileSelectorForm::FileItemCellImpl::setInfo(int idx, const FileInfo &info, bool selected, bool showSelect) {\n\tif (FileNameNode) {\n\t\tFileNameNode->ignoreContentAdaptWithSize(true);\n\t\tFileNameNode->setTextAreaSize(CellTextAreaSize);\n\t\tFileNameNode->setString(info.NameForDisplay);\n\t\tSize size(OrigCellModelSize);\n\t\tsize.height += FileNameNode->getContentSize().height - OrigCellTextSize.height;\n\t\t_root->setContentSize(size);\n\t\tsetContentSize(size);\n\t\tFileNameNode->ignoreContentAdaptWithSize(false);\n\t}\n\tif (DirIcon) DirIcon->setVisible(info.IsDir && !showSelect);\n\tSelectBox->setVisible(showSelect);\n\tif (showSelect) SelectBox->setSelected(selected);\n\tui::Helper::doLayout(_root);\n\t_set = true;\n\tif (BgOdd) BgOdd->setVisible((idx + 1) & 1);\n\tif (BgEven) BgEven->setVisible(idx & 1);\n}\n\nvoid TVPBaseFileSelectorForm::FileItemCellImpl::onClicked(cocos2d::Ref* p) {\n\tWidget* sender = static_cast<Widget*>(p);\n\tif (sender->isScheduled(str_long_press)) {\n\t\tsender->unschedule(str_long_press);\n\t\t_owner->onClicked();\n\t}\n}"
  },
  {
    "path": "src/core/environ/ui/FileSelectorForm.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n#include \"GUI/CCScrollView/CCTableView.h\"\n#include \"base/CCRefPtr.h\"\n\nclass TVPListForm : public cocos2d::Node {\npublic:\n\tvirtual ~TVPListForm();;\n\tstatic TVPListForm * create(const std::vector<cocos2d::ui::Widget*> &cells);\n\n\tvoid initFromInfo(const std::vector<cocos2d::ui::Widget*> &cells);\n\n\tvoid show(); // for background fading\n\n\tvoid close();\n\nprivate:\n\tbool onMaskTouchBegan(cocos2d::Touch *t, cocos2d::Event *);\n\n\tcocos2d::Node *_root;\n};\n\nclass TVPFileOperateMenu;\nclass TVPBaseFileSelectorForm : public iTVPBaseForm, public cocos2d::extension::TableViewDataSource {\npublic:\n\tTVPBaseFileSelectorForm();\n\tvirtual ~TVPBaseFileSelectorForm();\n\n\tvirtual cocos2d::Size tableCellSizeForIndex(cocos2d::extension::TableView *table, ssize_t idx) override;\n\tvirtual cocos2d::extension::TableViewCell* tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) override;\n\tvirtual ssize_t numberOfCellsInTableView(cocos2d::extension::TableView *table) override;\n\tvirtual void onCellClicked(int idx);\n\tvirtual void onCellLongPress(int idx);\n\tvirtual void rearrangeLayout() override;\n\tstatic std::pair<std::string, std::string> PathSplit(const std::string &path);\n\nprotected:\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvirtual void bindHeaderController(const NodeMap &allNodes) override;\n\n\tvoid ListDir(std::string path);\n\tvirtual void getShortCutDirList(std::vector<std::string> &pathlist);\n\n\tvoid onCellItemClicked(cocos2d::Ref *owner);\n\tvoid onTitleClicked(cocos2d::Ref *owner);\n\tvoid onBackClicked(cocos2d::Ref *owner);\n\tvoid _onCellClicked(int idx);\n\n\tcocos2d::extension::TableView *FileList;\n\tcocos2d::ui::Button *_title;\n\n\tcocos2d::Node *_fileOperateMenuNode = nullptr;\n\tcocos2d::Node *_fileOperateMenu = nullptr;\n\tcocos2d::ui::ListView *_fileOperateMenulist;\n\tcocos2d::RefPtr<cocos2d::ui::Widget>\n\t\t_fileOperateCell_unselect,\n\t\t_fileOperateCell_view,\n\t\t_fileOperateCell_copy,\n\t\t_fileOperateCell_cut,\n\t\t_fileOperateCell_paste,\n\t\t_fileOperateCell_unpack,\n\t\t_fileOperateCell_repack, // TODO\n\t\t_fileOperateCell_delete,\n\t\t_fileOperateCell_rename,\n\t\t_fileOperateCell_sendto;\n\t\n\tstd::vector<std::string> _clipboardForFileManager;\n\tstd::string _clipboardPath;\n\tbool _clipboardForMoving = false;\n\tstd::set<int> _selectedFileIndex;\n\tvoid onUnselectClicked(cocos2d::Ref *owner);\n\tvoid onViewClicked(cocos2d::Ref *owner);\n\tvoid onCopyClicked(cocos2d::Ref *owner);\n\tvoid onCutClicked(cocos2d::Ref *owner);\n\tvoid onPasteClicked(cocos2d::Ref *owner);\n\tvoid onUnpackClicked(cocos2d::Ref *owner);\n\tvoid onDeleteClicked(cocos2d::Ref *owner);\n\tvoid onSendToClicked(cocos2d::Ref *owner);\n\tvoid onBtnRenameClicked(cocos2d::Ref *owner);\n\tvoid updateFileMenu();\n\tvoid clearFileMenu();\n\n\tstruct FileInfo {\n\t\tstd::string FullPath;\n\t\tstd::string NameForDisplay;\n\t\tstd::string NameForCompare;\n\t\tbool IsDir;\n\t\tcocos2d::Size CellSize;\n\n\t\tbool operator < (const FileInfo &rhs) const;\n\t};\n\n\tint RootPathLen = 1; // '/'\n\tstd::vector<FileInfo> CurrentDirList;\n\tstd::string ParentPath, CurrentPath;\n\tclass FileItemCell;\n\tclass FileItemCellImpl : public TTouchEventRouter {\n\tpublic:\n\t\tFileItemCellImpl() : _set(false), _owner(nullptr) {}\n\t\t\n\t\tstatic FileItemCellImpl *create(const char * filename, float width) {\n\t\t\tFileItemCellImpl* ret = new FileItemCellImpl();\n\t\t\tret->autorelease();\n\t\t\tret->init();\n\t\t\tret->initFromFile(filename, width);\n\t\t\treturn ret;\n\t\t}\n\n\t\tvoid initFromFile(const char * filename, float width);\n\n\t\tvoid setInfo(int idx, const FileInfo &info, bool selected, bool showSelect);\n\n\t\tvoid reset() {\n\t\t\t_set = false;\n\t\t}\n\n\t\tbool isSet() {\n\t\t\treturn _set;\n\t\t}\n\n\t\tvoid setOwner(FileItemCell* owner) {\n\t\t\t_owner = owner;\n\t\t}\n\n\tprivate:\n\t\tvoid onClicked(cocos2d::Ref*);\n\n\t\tbool _set;\n\t\tcocos2d::Size OrigCellModelSize, CellTextAreaSize, OrigCellTextSize;\n\t\tcocos2d::ui::Text *FileNameNode;\n\t\tcocos2d::Node *DirIcon, *_root, *BgOdd, *BgEven;\n\t\tcocos2d::ui::CheckBox *SelectBox;\n\t\tFileItemCell *_owner;\n\t};\n\tcocos2d::RefPtr<FileItemCellImpl> CellTemplateForSize;\n\tFileItemCellImpl* FetchCell(FileItemCellImpl* CellModel, cocos2d::extension::TableView *table, ssize_t idx);\n\n\tclass FileItemCell : public cocos2d::extension::TableViewCell {\n\t\ttypedef cocos2d::extension::TableViewCell inherit;\n\n\tpublic:\n\t\tFileItemCell(TVPBaseFileSelectorForm *owner) : _owner(owner), _impl(nullptr) {}\n\n\t\tstatic FileItemCell *create(TVPBaseFileSelectorForm *owner) {\n\t\t\tFileItemCell *ret = new FileItemCell(owner);\n\t\t\tret->init();\n\t\t\tret->autorelease();\n\t\t\treturn ret;\n\t\t}\n\n\t\t// retained\n\t\tFileItemCellImpl* detach() {\n\t\t\tFileItemCellImpl *ret = _impl;\n\t\t\tif (ret) {\n\t\t\t\t_impl = nullptr;\n\t\t\t\tret->retain();\n\t\t\t\tret->removeFromParentAndCleanup(false);\n\t\t\t\tret->reset();\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\t// release\n\t\tvoid attach(FileItemCellImpl *impl) {\n\t\t\t_impl = impl;\n\t\t\taddChild(impl);\n\t\t\tsetContentSize(impl->getContentSize());\n\t\t\timpl->setOwner(this);\n\t\t\timpl->release();\n\t\t}\n\n\t\tvoid onClicked() {\n\t\t\t_owner->_onCellClicked(getIdx());\n\t\t}\n\n\t\tvoid onLongPress() {\n\t\t\t_owner->onCellLongPress(getIdx());\n\t\t}\n\n\tprivate:\n\t\tFileItemCellImpl *_impl;\n\t\tTVPBaseFileSelectorForm *_owner;\n\t};\n};\n\nclass TVPFileSelectorForm : public TVPBaseFileSelectorForm {\n\ttypedef TVPBaseFileSelectorForm inherit;\n\npublic:\n\tstatic TVPFileSelectorForm *create(const std::string &initfilename, const std::string &initdir, bool issave);\n\tvoid initFromPath(const std::string &initfilename, const std::string &initdir, bool issave);\n\tvoid setOnClose(const std::function<void(const std::string &)> &func) { _funcOnClose = func; }\n\nprotected:\n\tvirtual void bindFooterController(const NodeMap &allNodes) override;\n\tvirtual void onCellClicked(int idx) override;\n\tvoid close();\n\n\tcocos2d::ui::Button *_buttonOK, *_buttonCancel;\n\tcocos2d::ui::TextField *_input;\n\tstd::function<void(const std::string &)> _funcOnClose;\n\tstd::string _result;\n\tbool _isSaveMode;\n};\n"
  },
  {
    "path": "src/core/environ/ui/GameMainMenu.cpp",
    "content": "#include \"GameMainMenu.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"Application.h\"\n#include \"WindowIntf.h\"\n#include \"ui/UIHelper.h\"\n#include \"base/CCEventDispatcher.h\"\n#include \"base/CCEventListenerTouch.h\"\n#include \"2d/CCActionInterval.h\"\n#include \"TickCount.h\"\n#include \"MenuItemImpl.h\"\n#include \"InGameMenuForm.h\"\n#include \"base/CCDirector.h\"\n#include \"platform/CCGLView.h\"\n#include \"Platform.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nconst float _shrinkSpd = 700; // px/sec\nconst float _expandSpd = 700; // px/sec\nconst float _handlerFadeInTime = 0.15f;\nconst float _handlerFadeOutTime = 0.35f;\n\nTVPGameMainMenu::TVPGameMainMenu(GLubyte opa) {\n\t_shrinked = false;\n\t_hitted = false;\n\t_handler_inactive_opacity = opa;\n}\n\nTVPGameMainMenu * TVPGameMainMenu::create(GLubyte opa) {\n\tTVPGameMainMenu *ret = new TVPGameMainMenu(opa);\n\tret->init();\n\tret->autorelease();\n\treturn ret;\n}\n\niTJSDispatch2* TVPGetMenuDispatch(tTVInteger hWnd);\ntTJSNI_Window *TVPGetActiveWindow();\n\nbool TVPGameMainMenu::init() {\n\tbool ret = Node::init();\n\n\tCSBReader reader;\n\t_root = reader.Load(\"ui/GameMenu.csb\");\n\tSize size = TVPMainScene::GetInstance()->getGameNodeSize();\n\tfloat scale;\n\tif (size.width > size.height) {\n\t\tscale = size.height / 720;\n\t} else {\n\t\tscale = size.width / 720;\n\t}\n\tsetScale(scale);\n\tsize.width /= scale;\n\tsize.height = _root->getContentSize().height;\n\t_root->setContentSize(size);\n\tui::Helper::doLayout(_root);\n\taddChild(_root);\n\n\t_handler = reader.findController(\"handler\");\n\t//_handler_inactive_opacity = _handler->getOpacity();\n\t_eventDispatcher->removeEventListenersForTarget(_handler);\n\tEventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create();\n\tlistener->setSwallowTouches(true);\n\tlistener->onTouchBegan = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchBegan, this);\n\tlistener->onTouchMoved = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchMoved, this);\n\tlistener->onTouchEnded = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchEnded, this);\n\tlistener->onTouchCancelled = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchCancelled, this);\n\t_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _handler);\n\n\tlistener = EventListenerTouchOneByOne::create();\n\tlistener->setSwallowTouches(true);\n\tlistener->onTouchBegan = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchBegan, this);\n\tlistener->onTouchMoved = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchMoved, this);\n\tlistener->onTouchEnded = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchEnded, this);\n\tlistener->onTouchCancelled = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchCancelled, this);\n\t_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _root);\n\n\treader.findWidget(\"btn_gamemenu\")->addClickEventListener([this](Ref*){\n\t\tiTJSDispatch2 *menuobj = TVPGetMenuDispatch((tjs_intptr_t)TVPGetActiveWindow());\n\t\tif (!menuobj) return;\n\t\ttTJSNI_MenuItem *menu;\n\t\tmenuobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_MenuItem::ClassID, (iTJSNativeInstance**)&menu);\n\t\tif (!menu->GetChildren().empty())\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPInGameMenuForm::create(\"GameMenu\", menu));\n\t\tshrink();\n\t});\n\n\treader.findWidget(\"btn_window\")->addClickEventListener([this](Ref*){\n\t\tTVPMainScene::GetInstance()->showWindowManagerOverlay(true);\n\t\tshrink();\n\t});\n\n\t_icon_touch = reader.findController(\"icon_touch\");\n\t_icon_mouse = reader.findController(\"icon_mouse\");\n\tsetMouseIcon(true);\n\n\treader.findWidget(\"btn_mousemode\")->addClickEventListener([this](Ref*){\n\t\tTVPMainScene::GetInstance()->toggleVirtualMouseCursor();\n\t\tsetMouseIcon(!TVPMainScene::GetInstance()->isVirtualMouseMode());\n\t\tshrink();\n\t});\n\n\treader.findWidget(\"btn_keyboard\")->addClickEventListener([this](Ref*){\n \t\tSize screenSize = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize();\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\t\tTVPShowIME(0, 0, screenSize.width, screenSize.height);\n#else\n\t\tTVPMainScene::GetInstance()->attachWithIME();\n#endif\n\t\tshrink();\n\t});\n\n\treader.findWidget(\"btn_exit\")->addClickEventListener([this](Ref*){\n\t\tApplication->PostUserMessage([](){\n\t\t\tTVPGetActiveWindow()->Close();\n\t\t});\n\t\tshrink();\n\t});\n\n\treturn ret;\n}\n\nvoid TVPGameMainMenu::setMouseIcon(bool bMouse) {\n\tif (_icon_mouse) _icon_mouse->setVisible(bMouse);\n\tif (_icon_touch) _icon_touch->setVisible(!bMouse);\n}\n\nbool TVPGameMainMenu::onHandlerTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\t_hitted = false;\n\t_touchBeganPosition = _handler->convertToNodeSpace(touch->getLocation());\n\tRect bb;\n\tbb.size = _handler->getContentSize();\n\t_hitted = bb.containsPoint(_touchBeganPosition);\n\n\tif (_hitted) {\n\t\t_root->stopAllActions();\n\t\t_handler->stopAllActions();\n\t\t_handler->runAction(FadeIn::create(_handlerFadeInTime));\n\t\t_draggingY = false;\n\t\t_draggingX = false;\n\t\t_touchBeganTime = TVPGetTickCount();\n\t}\n\treturn _hitted;\n}\n\nvoid TVPGameMainMenu::onHandlerTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\tVec2 nsp = _handler->convertToNodeSpace(touch->getLocation());\n\tVec2 movDist = nsp - _touchBeganPosition;\n\tif (!_draggingY && std::abs(movDist.y) > 1) {\n\t\t_draggingY = true;\n\t}\n\tif (!_draggingX && std::abs(movDist.x) > 1) {\n\t\t_draggingX = true;\n\t}\n\n\t_handler->setPositionX(_handler->getPositionX() + movDist.x);\n\tconst Vec2 &pos = _handler->getPosition();\n\tconst Size &size = _handler->getContentSize();\n\tconst Vec2 &anchor = _handler->getAnchorPointInPoints();\n\tconst Size &rootsize = _root->getContentSize();\n\tfloat handlerLeftBoundary = pos.x - anchor.x;\n\tfloat handlerRightBoundary = handlerLeftBoundary + size.width;\n\tif (handlerLeftBoundary < 0) {\n\t\t_handler->setPositionX(anchor.x);\n\t} else {\n\t\tif (handlerRightBoundary > rootsize.width) {\n\t\t\t_handler->setPositionX(rootsize.width - size.width + anchor.x);\n\t\t}\n\t}\n\n\tfloat newPosY = _root->getPositionY() + movDist.y;\n\tif (newPosY < -rootsize.height) newPosY = -rootsize.height;\n\telse if (newPosY > 0) {\n\t\tfloat t = rootsize.height / 2;\n\t\tnewPosY = (1 - 1 / (newPosY / t + 1)) * t;\n\t}\n\t_root->setPositionY(newPosY);\n}\n\nvoid TVPGameMainMenu::onHandlerTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\t_hitted = false;\n\tVec2 nsp = _handler->convertToNodeSpace(touch->getLocation());\n\tbool isClick = TVPGetTickCount() - _touchBeganTime < 500;\n\tbool doExpand = false;\n\tif (isClick && !_draggingY) {\n\t\tdoExpand = _shrinked ^ _draggingX;\n\t} else {\n\t\tconst Size &rootsize = _root->getContentSize();\n\t\tif (_shrinked) {\n\t\t\tdoExpand = _root->getPositionY() > -rootsize.height * 0.75f;\n\t\t} else {\n\t\t\tdoExpand = _root->getPositionY() > -rootsize.height * 0.25f;\n\t\t}\n\t}\n\tif (doExpand) {\n\t\texpand();\n\t} else {\n\t\tshrink();\n\t}\n}\n\nvoid TVPGameMainMenu::onHandlerTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\tonHandlerTouchEnded(touch, unusedEvent);\n}\n\nvoid TVPGameMainMenu::shrink() {\n\tif (_hitted) return;\n\t_shrinked = true;\n\n\tfloat h = _root->getContentSize().height * _root->getScaleY();\n\tfloat topBoundary = _root->getPosition().y + h;\n\tfloat duration = topBoundary / _shrinkSpd;\n\n\t_root->stopAllActions();\n\t_root->runAction(MoveTo::create(duration, Vec2(0, -h)));\n\n\t_handler->runAction(Sequence::createWithTwoActions(DelayTime::create(2),\n\t\tFadeTo::create(_handlerFadeOutTime, _handler_inactive_opacity)));\n}\n\nvoid TVPGameMainMenu::shrinkWithTime(float dur) {\n\t_shrinked = true;\n\tfloat h = _root->getContentSize().height * _root->getScaleY();\n\tfloat topBoundary = _root->getPosition().y + h;\n\tfloat duration = topBoundary / _shrinkSpd;\n\t_handler->setOpacity(255);\n\t_root->runAction(Sequence::createWithTwoActions(DelayTime::create(dur), MoveTo::create(duration, Vec2(0, -h))));\n\t_handler->runAction(Sequence::createWithTwoActions(DelayTime::create(2 + dur),\n\t\tFadeTo::create(_handlerFadeOutTime, _handler_inactive_opacity)));\n}\n\nvoid TVPGameMainMenu::expand() {\n\tif (_hitted) return;\n\t_shrinked = false;\n\n\tfloat bottomBoundary = _root->getPosition().y;\n\tfloat duration = std::abs(bottomBoundary) / _expandSpd;\n\n\t_root->stopAllActions();\n\t_root->runAction(MoveTo::create(duration, Vec2(0, 0)));\n\t_handler->runAction(FadeIn::create(_handlerFadeInTime));\n}\n\nbool TVPGameMainMenu::onBackgroundTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\tif (!_shrinked) {\n\t\tshrink();\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nvoid TVPGameMainMenu::onBackgroundTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\n}\n\nvoid TVPGameMainMenu::onBackgroundTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\n}\n\nvoid TVPGameMainMenu::onBackgroundTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) {\n\n}\n\nvoid TVPGameMainMenu::toggle() {\n\tif (_hitted) return; // in touching\n\tif (_shrinked) expand();\n\telse shrink();\n}\n\nbool TVPGameMainMenu::isShrinked() {\n\treturn _shrinked;\n}\n"
  },
  {
    "path": "src/core/environ/ui/GameMainMenu.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n\nclass TVPGameMainMenu : public cocos2d::Node {\npublic:\n\tTVPGameMainMenu(GLubyte opa);\n\tstatic TVPGameMainMenu *create(GLubyte opa);\n\n\tvirtual bool init() override;\n\n\tvoid setMouseIcon(bool bMouse);\n\n\tvoid shrink();\n\tvoid expand();\n\tvoid toggle();\n\tvoid shrinkWithTime(float dur);\n\tbool isShrinked();\n\nprivate:\n\tbool onHandlerTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onHandlerTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onHandlerTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onHandlerTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\n\tbool onBackgroundTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onBackgroundTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onBackgroundTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\tvoid onBackgroundTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent);\n\n\tGLubyte _handler_inactive_opacity;\n\tbool _hitted;\n\tbool _shrinked;\n\tbool _draggingX, _draggingY;\n\n\tcocos2d::Node *_root;\n\tcocos2d::Node *_handler;\n\tcocos2d::Node *_icon_touch;\n\tcocos2d::Node *_icon_mouse;\n\n\tcocos2d::Vec2 _touchBeganPosition;\n\tcocos2d::Vec2 _touchMovePosition;\n\tcocos2d::Vec2 _touchEndPosition;\n\n\tunsigned int _touchBeganTime;\n};"
  },
  {
    "path": "src/core/environ/ui/GlobalPreferenceForm.cpp",
    "content": "#include \"GlobalPreferenceForm.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"ui/UIButton.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ui/UIListView.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"Platform.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n#define GLOBAL_PREFERENCE\n\nconst char * const FileName_NaviBar = \"ui/NaviBar.csb\";\nconst char * const FileName_Body = \"ui/ListView.csb\";\n\nstatic iSysConfigManager* GetConfigManager() {\n\treturn GlobalConfigManager::GetInstance();\n}\n#include \"PreferenceConfig.h\"\n\nTVPGlobalPreferenceForm * TVPGlobalPreferenceForm::create(const tPreferenceScreen *config) {\n\tInitialize();\n\tif (!config) config = &RootPreference;\n\tTVPGlobalPreferenceForm *ret = new TVPGlobalPreferenceForm();\n\tret->autorelease();\n\tret->initFromFile(FileName_NaviBar, FileName_Body, nullptr);\n\tPrefListSize = ret->PrefList->getContentSize();\n\tret->initPref(config);\n\tret->setOnExitCallback(std::bind(&GlobalConfigManager::SaveToFile, GlobalConfigManager::GetInstance()));\n\treturn ret;\n}\n\nstatic void WalkConfig(tPreferenceScreen* pref) {\n\tfor (iTVPPreferenceInfo* info : pref->Preferences) {\n\t\tinfo->InitDefaultConfig();\n\t\ttPreferenceScreen* subpref = info->GetSubScreenInfo();\n\t\tif (subpref) {\n\t\t\tWalkConfig(subpref);\n\t\t}\n\t}\n}\n\nvoid TVPGlobalPreferenceForm::Initialize()\n{\n\tstatic bool Inited = false;\n\tif (!Inited) {\n\t\tInited = true;\n\t\tif (!GlobalConfigManager::GetInstance()->IsValueExist(\"GL_EXT_shader_framebuffer_fetch\")) {\n\t\t\t// disable GL_EXT_shader_framebuffer_fetch normally for adreno GPU\n\t\t\tif (strstr((const char*)glGetString(GL_RENDERER), \"Adreno\")) {\n\t\t\t\tGlobalConfigManager::GetInstance()->SetValueInt(\"GL_EXT_shader_framebuffer_fetch\", 0);\n\t\t\t}\n\t\t}\n\n\t\tinitAllConfig();\n\t\tWalkConfig(&RootPreference);\n\t\tWalkConfig(&SoftRendererOptPreference);\n\t\tWalkConfig(&OpenglOptPreference);\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/ui/GlobalPreferenceForm.h",
    "content": "#pragma once\n#include \"PreferenceForm.h\"\n\nclass TVPGlobalPreferenceForm : public TVPPreferenceForm {\npublic:\n\tstatic TVPGlobalPreferenceForm *create(const tPreferenceScreen *config = nullptr);\n\tstatic void Initialize();\n};"
  },
  {
    "path": "src/core/environ/ui/InGameMenuForm.cpp",
    "content": "#include \"InGameMenuForm.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIListView.h\"\n#include \"ui/UIText.h\"\n#include \"MenuItemImpl.h\"\n#include \"ui/UIHelper.h\"\n#include \"tjsGlobalStringMap.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nconst char * const FileName_NaviBar = \"ui/NaviBar.csb\";\nconst char * const FileName_Body = \"ui/ListView.csb\";\n\nTVPInGameMenuForm * TVPInGameMenuForm::create(const std::string& title, tTJSNI_MenuItem *item) {\n\tTVPInGameMenuForm *ret = new TVPInGameMenuForm;\n\tret->autorelease();\n\tret->initFromFile(FileName_NaviBar, FileName_Body, nullptr);\n\tret->initMenu(title, item);\n\treturn ret;\n}\n\nvoid TVPInGameMenuForm::bindBodyController(const NodeMap &allNodes) {\n\t_list = static_cast<ListView*>(allNodes.findController(\"list\"));\n\tif (NaviBar.Left) {\n\t\tNaviBar.Left->addClickEventListener([this](cocos2d::Ref*){\n\t\t\tTVPMainScene::GetInstance()->popUIForm(this);\n\t\t});\n\t}\n}\n\nvoid TVPInGameMenuForm::bindHeaderController(const NodeMap &allNodes)\n{\n\t_title = static_cast<Button*>(allNodes.findController(\"title\"));\n\tif (_title) _title->setEnabled(false);\n}\n\nvoid TVPInGameMenuForm::initMenu(const std::string& title, tTJSNI_MenuItem *item) {\n\t_list->removeAllItems();\n\tif (_title) {\n\t\tif (title.empty()) {\n\t\t\tttstr caption; item->GetCaption(caption);\n\t\t\t_title->setTitleText(caption.AsStdString());\n\t\t} else {\n\t\t\t_title->setTitleText(title);\n\t\t}\n\t}\n\n\tint count = item->GetChildren().size();\n\tint idx = 0;\n\tttstr seperator = TJS::TJSMapGlobalStringMap(TJS_W(\"-\"));\n\tfor (int i = 0; i < count; ++i) {\n\t\ttTJSNI_MenuItem *subitem = static_cast<tTJSNI_MenuItem*>(item->GetChildren().at(i));\n\t\tttstr caption; subitem->GetCaption(caption);\n\t\tif (caption.IsEmpty() || caption == TJS_W(\"+\")) continue;\n\t\t_list->pushBackCustomItem(createMenuItem(idx, subitem, caption.AsStdString()));\n\t\tif(caption != seperator)\n\t\t\t++idx;\n\t}\n}\n\ncocos2d::ui::Widget * TVPInGameMenuForm::createMenuItem(int idx, tTJSNI_MenuItem *item, const std::string &caption) {\n\tiPreferenceItem *ret = nullptr;\n\tconst Size &size = _list->getContentSize();\n\tif (!item->GetChildren().empty()) {\n\t\tret = CreatePreferenceItem<tPreferenceItemSubDir>(idx, size, caption);\n\t\tret->addClickEventListener([=](Ref*){\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(create(caption, item));\n\t\t});\n\t} else if (item->GetGroup() > 0 || item->GetRadio()) {\n\t\tauto getter = [=]()->bool{ return item->GetChecked(); };\n\t\tauto setter = [=](bool b){\n\t\t\titem->OnClick();\n\t\t\tTVPMainScene::GetInstance()->popAllUIForm();\n\t\t};\n\t\tret = CreatePreferenceItem<tPreferenceItemCheckBox>(idx, size, caption,\n\t\t\t[=](tPreferenceItemCheckBox* item) {\n\t\t\titem->_getter = getter;\n\t\t\titem->_setter = setter;\n\t\t});\n\t} else if (item->GetChecked()) {\n\t\tauto getter = [=]()->bool{ return item->GetChecked(); };\n\t\tauto setter = [=](bool b){ item->OnClick(); };\n\t\tret = CreatePreferenceItem<tPreferenceItemCheckBox>(idx, size, caption,\n\t\t\t[=](tPreferenceItemCheckBox* item) {\n\t\t\titem->_getter = getter;\n\t\t\titem->_setter = setter;\n\t\t});\n\t} else if(caption == \"-\") {\n\t\tCSBReader reader;\n\t\tWidget * root = static_cast<Widget*>(reader.Load(\"ui/comctrl/SeperateItem.csb\"));\n\t\tSize rootsize = root->getContentSize();\n\t\trootsize.width = size.width;\n\t\troot->setContentSize(rootsize);\n\t\tui::Helper::doLayout(root);\n\t\treturn root;\n\t} else {\n\t\tret = CreatePreferenceItem<tPreferenceItemConstant>(idx, size, caption);\n\t\tret->addClickEventListener([=](Ref*){\n\t\t\tTVPMainScene::GetInstance()->scheduleOnce(\n\t\t\t\tstd::bind(&TVPMainScene::popAllUIForm, TVPMainScene::GetInstance()), 0, \"close_menu\");\n\t\t\titem->OnClick();\n\t\t});\n\t\tret->setTouchEnabled(true);\n\t}\n\treturn ret;\n}\n\nvoid TVPShowPopMenu(tTJSNI_MenuItem* menu) {\n\tTVPMainScene::GetInstance()->pushUIForm(TVPInGameMenuForm::create(std::string(), menu));\n}\n"
  },
  {
    "path": "src/core/environ/ui/InGameMenuForm.h",
    "content": "#pragma once\n#include \"PreferenceForm.h\"\n\nclass tTJSNI_MenuItem;\n\nclass TVPInGameMenuForm : public iTVPBaseForm {\npublic:\n\tstatic TVPInGameMenuForm *create(const std::string& title, tTJSNI_MenuItem *item);\n\n\tvirtual void bindBodyController(const NodeMap &allNodes);\n\tvirtual void bindHeaderController(const NodeMap &allNodes);\n\n\tvoid initMenu(const std::string& title, tTJSNI_MenuItem *item);\n\nprivate:\n\tcocos2d::ui::Widget *createMenuItem(int idx, tTJSNI_MenuItem *item, const std::string &caption);\n\n\tcocos2d::ui::ListView *_list;\n\tcocos2d::ui::Button *_title;\n};"
  },
  {
    "path": "src/core/environ/ui/IndividualPreferenceForm.cpp",
    "content": "#include \"IndividualPreferenceForm.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"ui/UIButton.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ui/UIListView.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"Platform.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n#define INDIVIDUAL_PREFERENCE\n\nconst char * const FileName_NaviBar = \"ui/NaviBar.csb\";\nconst char * const FileName_Body = \"ui/ListView.csb\";\n#define TVPGlobalPreferenceForm IndividualPreferenceForm\n\nstatic iSysConfigManager* GetConfigManager() {\n\treturn IndividualConfigManager::GetInstance();\n}\n#include \"PreferenceConfig.h\"\n\n#undef TVPGlobalPreferenceForm\n\nstatic void initInividualConfig() {\n\tif (!RootPreference.Preferences.empty()) return;\n\tinitAllConfig();\n\tRootPreference.Title = \"preference_title_individual\";\n}\n\nIndividualPreferenceForm * IndividualPreferenceForm::create(const tPreferenceScreen *config) {\n\tinitInividualConfig();\n\tif (!config) config = &RootPreference;\n\tIndividualPreferenceForm *ret = new IndividualPreferenceForm();\n\tret->autorelease();\n\tret->initFromFile(FileName_NaviBar, FileName_Body, nullptr);\n\tPrefListSize = ret->PrefList->getContentSize();\n\tret->initPref(config);\n\tret->setOnExitCallback(std::bind(&IndividualConfigManager::SaveToFile, IndividualConfigManager::GetInstance()));\n\treturn ret;\n}\n"
  },
  {
    "path": "src/core/environ/ui/IndividualPreferenceForm.h",
    "content": "#pragma once\n#include \"PreferenceForm.h\"\n\nclass IndividualPreferenceForm : public TVPPreferenceForm {\npublic:\n\tstatic IndividualPreferenceForm *create(const tPreferenceScreen *config = nullptr);\n};"
  },
  {
    "path": "src/core/environ/ui/MainFileSelectorForm.cpp",
    "content": "#include \"MainFileSelectorForm.h\"\n#include \"cocos2d.h\"\n#include \"cocostudio/CocoLoader.h\"\n#include \"cocostudio/CCSSceneReader.h\"\n#include \"Application.h\"\n#include \"Platform.h\"\n#include \"cocostudio/ActionTimeline/CCActionTimeline.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIListView.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"GlobalPreferenceForm.h\"\n#include \"IndividualPreferenceForm.h\"\n#include \"MessageBox.h\"\n#include \"SimpleMediaFilePlayer.h\"\n#include \"tinyxml2/tinyxml2.h\"\n#include \"StorageImpl.h\"\n#include \"TipsHelpForm.h\"\n#include \"XP3RepackForm.h\"\n#include \"cocos2d/CustomFileUtils.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nconst float UI_ACTION_DUR = 0.3f;\nconst char * const FileName_NaviBar = \"ui/NaviBarWithMenu.csb\";\nconst char * const FileName_Body = \"ui/TableView.csb\";\n//const char * const FileName_BottomBar = \"ui/BottomBar.csb\";\n//const char * const FileName_BtnPref = \"ui/button/Pref.csb\";\nconst char * const FileName_RecentPathListXML = \"recentpath.xml\";\n\nbool TVPIsFirstLaunch = false;\n\nstd::deque<std::string> _HistoryPath;\n\nstatic void _AskExit() {\n\tif (TVPShowSimpleMessageBoxYesNo(\n\t\tLocaleConfigManager::GetInstance()->GetText(\"sure_to_exit\"),\n\t\t\"Kirikiroid2\") == 0) TVPExitApplication(0);\n}\n\nbool TVPCheckIsVideoFile(const char *uri);\nstatic std::string _GetHistoryXMLPath() {\n\treturn TVPGetInternalPreferencePath() + FileName_RecentPathListXML;\n}\n\nstatic void _LoadHistory() {\n\tstd::string xmlpath = _GetHistoryXMLPath();\n\ttinyxml2::XMLDocument doc;\n\tif (!doc.LoadFile(xmlpath.c_str())) {\n\t\ttinyxml2::XMLElement *rootElement = doc.RootElement();\n\t\tif (rootElement) {\n\t\t\tfor (tinyxml2::XMLElement *item = rootElement->FirstChildElement(\"Item\"); item; item = item->NextSiblingElement(\"Item\")) {\n\t\t\t\tconst char *path = item->Attribute(\"Path\");\n\t\t\t\tif (path) {\n\t\t\t\t\t_HistoryPath.emplace_back(path);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tTVPIsFirstLaunch = true;\n\t}\n}\n\nstatic void _SaveHistory() {\n\tstd::string xmlpath = _GetHistoryXMLPath();\n\n\tif (_HistoryPath.empty() && !FileUtils::getInstance()->isFileExist(xmlpath)) return;\n\n\ttinyxml2::XMLDocument doc;\n\tdoc.LinkEndChild(doc.NewDeclaration());\n\ttinyxml2::XMLElement *rootElement = doc.NewElement(\"RecentPathList\");\n\tfor (const std::string& path : _HistoryPath) {\n\t\ttinyxml2::XMLElement *item = doc.NewElement(\"Item\");\n\t\titem->SetAttribute(\"Path\", path.c_str());\n\t\trootElement->LinkEndChild(item);\n\t}\n\n\tdoc.LinkEndChild(rootElement);\n\tdoc.SaveFile(xmlpath.c_str());\n}\n\nstatic void _RemoveHistory(const std::string &path) {\n\tauto it = std::find(_HistoryPath.begin(), _HistoryPath.end(), path);\n\tif (it != _HistoryPath.end()) {\n\t\t_HistoryPath.erase(it);\n\t\t_SaveHistory();\n\t}\n}\n\nstatic void _AddHistory(const std::string &path) {\n\tif (!_HistoryPath.empty() && _HistoryPath.front() == path) return;\n\t_RemoveHistory(path);\n\t_HistoryPath.emplace_front(path);\n\t_SaveHistory();\n}\n\nstatic bool _CheckGameFolder(const std::string &path) {\n\tbool isValidGameFolder = false;\n\tstd::vector<std::string> subFolders;\n\tTVPListDir(path, [&](const std::string &name, int mask) {\n\t\tif (isValidGameFolder || name.empty() || name.front() == '.') return;\n\t\tif (mask & S_IFREG) {\n\t\t\tstd::string lowername = name;\n\t\t\tstd::transform(lowername.begin(), lowername.end(), lowername.begin(), [](int c)->int {\n\t\t\t\tif (c <= 'Z' && c >= 'A')\n\t\t\t\t\treturn c - ('A' - 'a');\n\t\t\t\treturn c;\n\t\t\t});\n\t\t\tsize_t pos = lowername.rfind('.');\n\t\t\tif (pos == lowername.npos) return;\n\t\t\tif (lowername.substr(pos) == \".xp3\") {\n\t\t\t\tisValidGameFolder = true;\n\t\t\t}\n\t\t} else if (mask & S_IFDIR) {\n\t\t\tsubFolders.emplace_back(path + \"/\" + name);\n\t\t}\n\t});\n\twhile (!isValidGameFolder) {\n\t\tif (subFolders.empty()) break;\n\t\tisValidGameFolder = _CheckGameFolder(subFolders.back());\n\t\tsubFolders.pop_back();\n\t}\n\treturn isValidGameFolder;\n}\n\nTVPMainFileSelectorForm::TVPMainFileSelectorForm() {\n\t_menu = nullptr;\n}\n\nvoid TVPMainFileSelectorForm::onEnter()\n{\n\tinherit::onEnter();\n\tif (_historyList) {\n\t\t_historyList->doLayout();\n\t\tauto & allcell = _historyList->getItems();\n\t\tfor (Widget* cell : allcell) {\n\t\t\tstatic_cast<HistoryCell*>(cell)->rearrangeLayout();\n\t\t}\n\t}\n}\n\nvoid TVPMainFileSelectorForm::bindBodyController(const NodeMap &allNodes) {\n\tTVPBaseFileSelectorForm::bindBodyController(allNodes);\n\n\tif (NaviBar.Right) {\n\t\tNaviBar.Right->addClickEventListener(std::bind(&TVPMainFileSelectorForm::showMenu, this, std::placeholders::_1));\n\t}\n}\n\nextern \"C\" void TVPGL_ASM_Test();\nvoid TVPMainFileSelectorForm::show() {\n#ifdef _DEBUG\n\tTVPGL_ASM_Test();\n#endif\n\tListHistory(); // filter history data\n\n\tbool first = true;\n\tstd::string lastpath;\n\tif (!_HistoryPath.empty()) lastpath = _HistoryPath.front();\n\twhile (first || (lastpath.size() > RootPathLen && !FileUtils::getInstance()->isDirectoryExist(lastpath))) {\n\t\tfirst = false;\n\t\tstd::pair<std::string, std::string> split_path = PathSplit(lastpath);\n\t\tif (split_path.second.empty()) {\n\t\t\tlastpath.clear();\n\t\t\tbreak;\n\t\t}\n\t\tlastpath = split_path.first;\n\t}\n\tif (lastpath.size() <= RootPathLen) {\n\t\tlastpath = TVPGetDriverPath()[0];\n\t}\n\tListDir(lastpath); // getCurrentDir()\n\t// TODO show usage\n}\n\nstatic const std::string str_startup_tjs(\"startup.tjs\");\n\nbool TVPMainFileSelectorForm::CheckDir(const std::string &path) {\n\tfor (const FileInfo &info : CurrentDirList) {\n\t\tif (info.NameForCompare == str_startup_tjs) return true;\n\t}\n\treturn false;\n}\n\nint TVPCheckArchive(const ttstr &localname);\nvoid TVPMainFileSelectorForm::onCellClicked(int idx) {\n\tFileInfo info = CurrentDirList[idx];\n\tTVPBaseFileSelectorForm::onCellClicked(idx);\n\tint archiveType;\n\tif (info.IsDir) {\n\t\tif (CheckDir(info.FullPath)) {\n\t\t\tstartup(info.FullPath);\n\t\t}\n\t} else if ((archiveType = TVPCheckArchive(info.FullPath.c_str())) == 1) {\n\t\tstartup(info.FullPath);\n\t} else if (archiveType == 0 && TVPCheckIsVideoFile(info.FullPath.c_str())) {\n\t\tSimpleMediaFilePlayer *player = SimpleMediaFilePlayer::create();\n\t\tTVPMainScene::GetInstance()->addChild(player, 10);// pushUIForm(player);\n\t\tplayer->PlayFile(info.FullPath.c_str());\n\t} else if (archiveType && FileUtils::getInstance()->getFileExtension(info.NameForCompare) == \".skin\") {\n\t\t// maybe skin\n\t\tif (TVPSkinManager::Check(info.FullPath)) {\n\t\t\tstd::vector<ttstr> btns;\n\t\t\tbtns.emplace_back(\"Direct Use\");\n\t\t\tbtns.emplace_back(\"Install\");\n\t\t\tbtns.emplace_back(\"Cancel\");\n\t\t\tswitch (TVPShowSimpleMessageBox(\"Install or direct use it ? (restart needed)\", \"Skin found\", btns)) {\n\t\t\tcase 0: // direct use\n\t\t\t\tTVPSkinManager::Use(info.FullPath);\n\t\t\t\tTVPShowSimpleMessageBox(\"Active after restart.\", \"Skin\");\n\t\t\t\tbreak;\n\t\t\tcase 1: // install\n\t\t\t\tTVPSkinManager::InstallAndUse(info.FullPath);\n\t\t\t\tTVPShowSimpleMessageBox(\"Active after restart.\", \"Skin\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid TVPMainFileSelectorForm::getShortCutDirList(std::vector<std::string> &pathlist) {\n\tif (!_lastpath.empty()) {\n\t\tpathlist.emplace_back(_lastpath);\n\t}\n\tTVPBaseFileSelectorForm::getShortCutDirList(pathlist);\n}\n\nTVPMainFileSelectorForm * TVPMainFileSelectorForm::create() {\n\tTVPMainFileSelectorForm *ret = new  TVPMainFileSelectorForm();\n\tret->autorelease();\n\tret->initFromFile();\n\tret->show();\n\treturn ret;\n}\n\nvoid TVPMainFileSelectorForm::initFromFile()\n{\n\t_LoadHistory();\n//\tif (!_HistoryPath.empty())\n\t{\n\t\tCSBReader reader;\n\t\tNode *root = reader.Load(\"ui/MainFileSelector.csb\");\n\t\t_fileList = reader.findController(\"fileList\");\n\t\t_historyList = static_cast<ListView*>(reader.findController(\"recentList\"));\n\t\t// TODO new node\n\t\t_fileOperateMenuNode = _historyList;\n\t\tLocaleConfigManager::GetInstance()->initText(static_cast<Text*>(reader.findController(\"recentTitle\", false)));\n\t\taddChild(root);\n\t\tSize sceneSize = TVPMainScene::GetInstance()->getUINodeSize();\n\t\tsetContentSize(sceneSize);\n\t\troot->setContentSize(sceneSize);\n\t\tui::Helper::doLayout(root);\n\t}\n\tinherit::initFromFile(FileName_NaviBar, FileName_Body, nullptr/*FileName_BottomBar*/, _fileList);\n}\n\n// std::string _getLastPathFilePath() {\n// \treturn TVPGetInternalPreferencePath() + \"lastpath.txt\";\n// }\n\nvoid TVPMainFileSelectorForm::startup(const std::string &path) {\n\tif (TVPIsFirstLaunch) {\n\t\tTVPTipsHelpForm::show()->setOnExitCallback([this, path](){\n\t\t\tscheduleOnce([this, path](float) {doStartup(path); }, 0, \"startup\");\n\t\t});\n\t} else {\n\t\tdoStartup(path);\n\t}\n}\n\nvoid TVPMainFileSelectorForm::doStartup(const std::string &path) {\n\tif (TVPMainScene::GetInstance()->startupFrom(path)) {\n\t\tif (GlobalConfigManager::GetInstance()->GetValue<bool>(\"remember_last_path\", true)) {\n\t\t\t_AddHistory(path);\n\t\t}\n\t}\n}\n\nstd::string TVPGetOpenGLInfo();\nvoid TVPOpenPatchLibUrl();\n\nvoid TVPMainFileSelectorForm::showMenu(Ref*) {\n\tif (!_menu) {\n\t\tSize uiSize = getContentSize();\n\t\tCSBReader reader;\n\t\t_menu = reader.Load(\"ui/MenuList.csb\");\n\t\t_menu->setAnchorPoint(Vec2::ZERO);\n\t\t_menu->setPosition(Vec2(uiSize.width, 0));\n\t\t_mask = LayerColor::create(Color4B::BLACK, uiSize.width, uiSize.height);\n\t\t_mask->setOpacity(0);\n\t\t_touchHideMenu = ui::Widget::create();\n\t\t_touchHideMenu->setAnchorPoint(Vec2::ZERO);\n\t\t_touchHideMenu->setContentSize(uiSize);\n\t\t_touchHideMenu->addClickEventListener([this](Ref*) {\n\t\t\tif (isMenuShowed())\n\t\t\t\thideMenu(nullptr);\n\t\t});\n\t\t_mask->addChild(_touchHideMenu);\n\t\taddChild(_mask);\n\t\taddChild(_menu);\n\t\tif (uiSize.width > uiSize.height) {\n\t\t\tuiSize.width /= 3;\n\t\t} else {\n\t\t\tuiSize.width *= 0.6f;\n\t\t}\n\t\tSize menuSize = _menu->getContentSize();\n\t\tfloat scale = uiSize.width / menuSize.width;\n\t\tmenuSize.height = uiSize.height / scale;\n\t\t_menu->setScale(scale);\n\t\t_menu->setContentSize(menuSize);\n\t\tui::Helper::doLayout(_menu);\n\n\t\tnewLocalPref = reader.findController(\"newLocalPref\");\n\t\tlocalPref = reader.findController(\"localPref\");\n\t\tsizeNewLocalPref = newLocalPref->getContentSize();\n\t\tsizeLocalPref = localPref->getContentSize();\n\n\t\t_menuList = dynamic_cast<ui::ListView*>(reader.findController(\"menulist\"));\n\n\t\t// captions\n\t\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleRotate\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleGlobalPref\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleNewLocalPref\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleLocalPref\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleHelp\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleAbout\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleExit\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleRepack\"));\n\t\tlocaleMgr->initText(reader.findController<Text>(\"titleNewFolder\"));\n\n\t\t// button events\n\t\treader.findWidget(\"btnRotate\")->addClickEventListener([](Ref*) {\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create());\n\t\t});\n\t\treader.findWidget(\"btnGlobalPref\")->addClickEventListener([](Ref*) {\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create());\n\t\t});\n\t\treader.findWidget(\"btnNewLocalPref\")->addClickEventListener([this](Ref*) {\n\t\t\tif (IndividualConfigManager::GetInstance()->CreatePreferenceAt(CurrentPath)) {\n\t\t\t\tTVPMainScene::GetInstance()->pushUIForm(IndividualPreferenceForm::create());\n\t\t\t\thideMenu(nullptr);\n\t\t\t}\n\t\t});\n\t\treader.findWidget(\"btnLocalPref\")->addClickEventListener([this](Ref*) {\n\t\t\tonShowPreferenceConfigAt(CurrentPath);\n\t\t});\n\t\treader.findWidget(\"btnHelp\")->addClickEventListener([this](Ref*) {\n\t\t\tTVPTipsHelpForm::show();\n\t\t});\n\t\tbool showSimpleAbout = false;\n\t\tif(showSimpleAbout) {\n\t\t\treader.findWidget(\"btnAbout\")->addClickEventListener([](Ref*) {\n\t\t\t\tstd::string versionText = \"Version \";\n\t\t\t\tversionText += TVPGetPackageVersionString();\n\n\t\t\t\tstd::string btnText = LocaleConfigManager::GetInstance()->GetText(\"ok\");\n\t\t\t\tconst char *pszBtnText = btnText.c_str();\n\t\t\t\tstd::string strCaption = LocaleConfigManager::GetInstance()->GetText(\"menu_about\");\n\t\t\t\tconst char *caption = strCaption.c_str();\n\t\t\t\tTVPShowSimpleMessageBox(versionText.c_str(), caption, 1, &pszBtnText);\n\t\t\t});\n\t\t\treader.findWidget(\"btnExit\")->addClickEventListener([](Ref*) {\n\t\t\t\tif (TVPShowSimpleMessageBoxYesNo(\n\t\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"sure_to_exit\"),\n\t\t\t\t\t\"XP3Player\") == 0) TVPExitApplication(0);\n\t\t\t});\n\t\t} else {\n\t\t\treader.findWidget(\"btnAbout\")->addClickEventListener([](Ref*) {\n\t\t\t\tstd::string versionText = \"Version \";\n\t\t\t\tversionText += TVPGetPackageVersionString();\n\t\t\t\tversionText += \"\\n\";\n\t\t\t\tversionText += LocaleConfigManager::GetInstance()->GetText(\"about_content\");\n\n\t\t\t\tconst char * pszBtnText[] = {\n\t\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"ok\").c_str(),\n\t\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"browse_patch_lib\").c_str(),\n\t\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"device_info\").c_str(),\n\t\t\t\t};\n\n\t\t\t\tstd::string strCaption = LocaleConfigManager::GetInstance()->GetText(\"menu_about\");\n\t\t\t\tint n = TVPShowSimpleMessageBox(versionText.c_str(), strCaption.c_str(),\n\t\t\t\t\tsizeof(pszBtnText) / sizeof(pszBtnText[0]), pszBtnText);\n\n\t\t\t\tswitch (n) {\n\t\t\t\tcase 1:\n\t\t\t\t\tTVPOpenPatchLibUrl();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tcocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread([]{\n\t\t\t\t\t\tstd::string text = TVPGetOpenGLInfo();\n\t\t\t\t\t\tconst char *pOK = LocaleConfigManager::GetInstance()->GetText(\"ok\").c_str();\n\t\t\t\t\t\tTVPShowSimpleMessageBox(text.c_str(),\n\t\t\t\t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"device_info\").c_str(),\n\t\t\t\t\t\t\t1, &pOK);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t});\n\t\t\treader.findWidget(\"btnExit\")->addClickEventListener([](Ref*) {\n\t\t\t\t_AskExit();\n\t\t\t});\n\t\t}\n\t\t// ## fix repack can not compile\n\t\t// reader.findWidget(\"btnRepack\")->addClickEventListener([this](Ref*) {\n\t\t// \tTVPProcessXP3Repack(CurrentPath);\n\t\t// \thideMenu(nullptr);\n\t\t// });\n\t\treader.findWidget(\"btnNewFolder\")->addClickEventListener([this](Ref*) {\n\t\t\tttstr name = TJS_W(\"New Folder\");\n\t\t\tstd::vector<ttstr> btns;\n\t\t\tbtns.emplace_back(\"OK\");\n\t\t\tbtns.emplace_back(\"Cancel\");\n\t\t\tif (TVPShowSimpleInputBox(name, \"Input name\", \"\", btns) == 0) {\n\t\t\t\tttstr newname(CurrentPath);\n\t\t\t\tnewname += TJS_W(\"/\");\n\t\t\t\tnewname += name;\n\t\t\t\tif (!TVPCreateFolders(newname)) {\n\t\t\t\t\tTVPShowSimpleMessageBox(TJS_W(\"Fail to create folder.\"), TJS_W(\"Error\"));\n\t\t\t\t} else {\n\t\t\t\t\tListDir(CurrentPath);\n\t\t\t\t}\n\t\t\t}\n\t\t\thideMenu(nullptr);\n\t\t});\n\n\t}\n\tconst Size &uiSize = getContentSize();\n\tconst Vec2 &pos = _menu->getPosition();\n\tconst Size &size = _menu->getContentSize();\n\tfloat w = size.width * _menu->getScale();\n\tif (pos.x > uiSize.width - w / 10.0f) {\n\t\tif (IndividualConfigManager::CheckExistAt(CurrentPath)) {\n\t\t\tlocalPref->setVisible(true);\n\t\t\tlocalPref->setContentSize(sizeLocalPref);\n\t\t\tnewLocalPref->setVisible(false);\n\t\t\tnewLocalPref->setContentSize(Size::ZERO);\n\t\t} else {\n\t\t\tnewLocalPref->setVisible(true);\n\t\t\tnewLocalPref->setContentSize(sizeNewLocalPref);\n\t\t\tlocalPref->setVisible(false);\n\t\t\tlocalPref->setContentSize(Size::ZERO);\n\t\t}\n\t\t_menuList->requestDoLayout();\n\t\t_mask->stopAllActions();\n\t\t_mask->runAction(FadeTo::create(UI_ACTION_DUR, 128));\n\t\t_menu->stopAllActions();\n\t\t_menu->runAction(EaseQuadraticActionOut::create(\n\t\t\tMoveTo::create(UI_ACTION_DUR, Vec2(uiSize.width - w, pos.y))));\n\t\t_touchHideMenu->setTouchEnabled(true);\n\t}\n}\n\nvoid TVPMainFileSelectorForm::hideMenu(cocos2d::Ref*)\n{\n\tif (!_menu) return;\n\t_mask->stopAllActions();\n\t_mask->runAction(FadeOut::create(UI_ACTION_DUR));\n\t_menu->stopAllActions();\n\t_menu->runAction(EaseQuadraticActionOut::create(\n\t\tMoveTo::create(UI_ACTION_DUR, Vec2(getContentSize().width, _menu->getPositionY()))));\n\t_touchHideMenu->setTouchEnabled(false);\n}\n\nbool TVPMainFileSelectorForm::isMenuShowed()\n{\n\tif (!_menu) return false;\n\tconst Vec2 &pos = _menu->getPosition();\n\tconst Size &size = _menu->getContentSize();\n\tfloat w = size.width * _menu->getScale();\n\tif (pos.x < getContentSize().width - w * 0.9f) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nbool TVPMainFileSelectorForm::isMenuShrinked()\n{\n\tif (!_menu) return true;\n\tconst Vec2 &pos = _menu->getPosition();\n\tconst Size &size = _menu->getContentSize();\n\tfloat w = size.width * _menu->getScale();\n\tif (pos.x > getContentSize().width - w / 10.0f) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid TVPMainFileSelectorForm::onShowPreferenceConfigAt(const std::string &path)\n{\n\tif (IndividualConfigManager::GetInstance()->UsePreferenceAt(path)) {\n\t\tTVPMainScene::GetInstance()->pushUIForm(IndividualPreferenceForm::create());\n\t}\n}\n\nvoid TVPMainFileSelectorForm::ListHistory()\n{\n\tif (!_historyList) return;\n\t_historyList->removeAllChildren();\n\tHistoryCell *nullcell = new HistoryCell();\n\tnullcell->init();\n\tSize cellsize = _historyList->getContentSize();\n\tcellsize.height = 100;\n\tnullcell->setContentSize(cellsize);\n\t_historyList->pushBackCustomItem(nullcell);\n\tfor (auto it = _HistoryPath.begin(); it != _HistoryPath.end();) {\n\t\tconst std::string &fullpath = *it;\n\t\tHistoryCell *cell;\n\t\tif (TVPCheckExistentLocalFile(fullpath) || TVPCheckExistentLocalFolder(fullpath)) {\n\t\t\tstd::pair<std::string, std::string> split_path = PathSplit(fullpath);\n\t\t\tstd::string lastname = split_path.second;\n\t\t\tstd::string path = split_path.first;\n\t\t\tsplit_path = PathSplit(path);\n\t\t\tcell = HistoryCell::create(fullpath, split_path.first + \"/\", split_path.second, \"/\" + lastname);\n\t\t\tWidget::ccWidgetClickCallback funcConf;\n\t\t\tif (TVPCheckExistentLocalFile(path + \"/Kirikiroid2Preference.xml\"))\n\t\t\t\tfuncConf = [this, path](Ref*){ onShowPreferenceConfigAt(path); };\n\t\t\tcell->initFunction(std::bind(&TVPMainFileSelectorForm::RemoveHistoryCell, this, std::placeholders::_1, cell),\n\t\t\t\t[this, path](Ref*){ ListDir(path); }, funcConf, [this, fullpath](Ref*) { startup(fullpath); });\n\t\t\tSize cellsize = cell->getContentSize();\n\t\t\tcellsize.width = _historyList->getContentSize().width;\n\t\t\tcell->setContentSize(cellsize);\n\t\t\t_historyList->pushBackCustomItem(cell);\n\t\t\t++it;\n\t\t} else {\n\t\t\tit = _HistoryPath.erase(it);\n\t\t\tcontinue;\n\t\t}\n\t}\n\tnullcell = new HistoryCell();\n\tnullcell->init();\n\tnullcell->setContentSize(cellsize);\n\t_historyList->pushBackCustomItem(nullcell);\n}\n\nvoid TVPMainFileSelectorForm::RemoveHistoryCell(cocos2d::Ref* btn, HistoryCell* cell)\n{\n\tstatic_cast<Widget*>(btn)->setEnabled(false);\n\tcell->runAction(Sequence::createWithTwoActions(\n\t\tEaseQuadraticActionOut::create(MoveBy::create(0.25, Vec2(-cell->getContentSize().width, 0))),\n\t\tCallFuncN::create([this](Node* p){\n\t\tHistoryCell* cell = static_cast<HistoryCell*>(p);\n\t\tssize_t idx = _historyList->getIndex(cell);\n\t\tif (idx < 0) return;\n\t\t_historyList->removeItem(idx);\n\t})));\n\t_RemoveHistory(cell->getFullpath());\n\t_SaveHistory();\n}\n\nvoid TVPMainFileSelectorForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) {\n\tif (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) {\n\t\tif (isMenuShowed()) {\n\t\t\thideMenu(nullptr);\n\t\t} else {\n\t\t\t_AskExit();\n\t\t}\n\t} else if (keyCode == EventKeyboard::KeyCode::KEY_MENU) {\n\t\tif (isMenuShrinked()) {\n\t\t\tshowMenu(nullptr);\n\t\t}\n\t} else {\n\t\tinherit::onKeyPressed(keyCode, event);\n\t}\n}\n\nvoid TVPMainFileSelectorForm::HistoryCell::initInfo(const std::string &fullpath, const std::string &prefix, const std::string &pathname, const std::string &filename)\n{\n\t_fullpath = fullpath;\n\n\tCSBReader reader;\n\t_root = reader.Load(\"ui/RecentListItem.csb\");\n\t_scrollview = static_cast<cocos2d::ui::ScrollView*>(reader.findController(\"scrollview\"));\n\t_btn_delete = static_cast<cocos2d::ui::Widget*>(reader.findController(\"btn_delete\"));\n\t_btn_jump = static_cast<cocos2d::ui::Widget*>(reader.findController(\"btn_jump\"));\n\t_btn_conf = static_cast<cocos2d::ui::Widget*>(reader.findController(\"btn_conf\"));\n\t_btn_play = static_cast<cocos2d::ui::Widget*>(reader.findController(\"btn_play\"));\n\t_prefix = static_cast<cocos2d::ui::Text*>(reader.findController(\"prefix\"));\n\t_path = static_cast<cocos2d::ui::Text*>(reader.findController(\"path\"));\n\t_file = static_cast<cocos2d::ui::Text*>(reader.findController(\"file\"));\n\t_panel_delete = reader.findController(\"panel_delete\");\n\tif (!_panel_delete) _panel_delete = _btn_delete;\n\t_scrollview->setScrollBarEnabled(false);\n\t_scrollview->setPropagateTouchEvents(true);\n\n\t_prefix->setString(prefix);\n\t_path->setString(pathname);\n\t_file->setString(filename);\n\n\tsetContentSize(_root->getContentSize());\n\taddChild(_root);\n}\n\nvoid TVPMainFileSelectorForm::HistoryCell::rearrangeLayout()\n{\n\tif (!_root) return;\n\t_root->setContentSize(this->getContentSize());\n\tui::Helper::doLayout(_root);\n\tVec2 pt = Vec2::ZERO;\n\tpt.x = _file->getContentSize().width;\n\tVec2 ptWorld = _file->convertToWorldSpace(pt);\n\tSize viewSize = _scrollview->getContentSize();\n\tNode *container = _scrollview->getInnerContainer();\n\tpt = container->convertToNodeSpace(ptWorld);\n\tfloat btnw = _panel_delete->getContentSize().width;\n\tfloat offsetx = 0;\n\tif (pt.x > viewSize.width) {\n\t\tfloat neww = pt.x;\n\t\tpt.y = 0; pt.x = _path->getContentSize().width;\n\t\tptWorld = _path->convertToWorldSpace(pt);\n\t\tpt = container->convertToNodeSpace(ptWorld);\n\t\tif (pt.x > viewSize.width) {\n\t\t\toffsetx = viewSize.width - pt.x;\n\t\t}\n\t\tviewSize.width = neww;\n\t}\n\t_panel_delete->setPositionX(viewSize.width + btnw);\n\tviewSize.width += btnw + btnw;\n\t_scrollview->setInnerContainerSize(viewSize);\n\tcontainer->setPosition(offsetx, 0);\n}\n\nvoid TVPMainFileSelectorForm::HistoryCell::initFunction(const ccWidgetClickCallback &funcDel, const ccWidgetClickCallback &funcJump, const ccWidgetClickCallback &funcConf, const ccWidgetClickCallback &funcPlay)\n{\n\t_btn_delete->addClickEventListener(funcDel);\n\t_btn_play->addClickEventListener(funcPlay);\n\tif (funcConf) _btn_conf->addClickEventListener(funcConf);\n\telse _btn_conf->setVisible(false);\n\t_btn_jump->addClickEventListener(funcJump);\n}\n\nvoid TVPMainFileSelectorForm::HistoryCell::onSizeChanged()\n{\n\n}\n"
  },
  {
    "path": "src/core/environ/ui/MainFileSelectorForm.h",
    "content": "#pragma once\n#include \"FileSelectorForm.h\"\n\nnamespace cocos2d {\n\tclass LayerColor;\n}\n\nclass TVPMainFileSelectorForm : public TVPBaseFileSelectorForm {\n\ttypedef TVPBaseFileSelectorForm inherit;\npublic:\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\n\tvoid show();\n\n\tstatic TVPMainFileSelectorForm *create();\n\n\tvoid initFromFile();\n\n\tvirtual void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\nprotected:\n\tTVPMainFileSelectorForm();\n\tvirtual void onEnter() override;\n\tbool CheckDir(const std::string &path);\n\n\tvirtual void onCellClicked(int idx) override;\n\tvirtual void getShortCutDirList(std::vector<std::string> &pathlist) override;\n\n\tvoid startup(const std::string &path);\n\tvoid doStartup(const std::string &path);\n\n\tvoid showMenu(cocos2d::Ref*);\n\n\tvoid hideMenu(cocos2d::Ref*);\n\n\tbool isMenuShowed();\n\tbool isMenuShrinked();\n\n\tvoid onShowPreferenceConfigAt(const std::string &path);\n\n\tvoid ListHistory();\n\n\tclass HistoryCell : public cocos2d::ui::Widget {\n\tpublic:\n\t\tstatic HistoryCell *create(const std::string &fullpath, const std::string &prefix, const std::string &pathname,\n\t\t\tconst std::string &filename) {\n\t\t\tHistoryCell* ret = new HistoryCell();\n\t\t\tret->autorelease();\n\t\t\tret->init();\n\t\t\tret->initInfo(fullpath, prefix, pathname, filename);\n\t\t\treturn ret;\n\t\t}\n\n\t\tvoid initInfo(const std::string &fullpath, const std::string &prefix, const std::string &pathname, const std::string &filename);\n\t\tvoid initFunction(const ccWidgetClickCallback &funcDel, const ccWidgetClickCallback &funcJump,\n\t\t\tconst ccWidgetClickCallback &funcConf, const ccWidgetClickCallback &funcPlay);\n\n\t\tvoid rearrangeLayout();\n\t\tconst std::string &getFullpath() { return _fullpath; }\n\n\tprivate:\n\t\tvirtual void onSizeChanged() override;\n\n\t\tcocos2d::ui::ScrollView *_scrollview;\n\t\tcocos2d::ui::Widget *_btn_delete, *_btn_jump, *_btn_conf, *_btn_play;\n\t\tcocos2d::ui::Text* _prefix, *_path, *_file;\n\t\tcocos2d::Node *_panel_delete, *_root = nullptr;\n\t\tstd::string _fullpath;\n\t};\n\n\tvoid RemoveHistoryCell(cocos2d::Ref*, HistoryCell* cell);\n\n\tstd::string _lastpath;\n\tcocos2d::ui::Widget *_touchHideMenu;\n\tcocos2d::ui::ListView *_menuList, *_historyList = nullptr;\n\tcocos2d::LayerColor* _mask;\n\tcocos2d::Node *_menu, *_fileList = nullptr;\n\tcocos2d::Node *newLocalPref, *localPref;\n\tcocos2d::Size sizeNewLocalPref, sizeLocalPref;\n};\n"
  },
  {
    "path": "src/core/environ/ui/MessageBox.cpp",
    "content": "#include \"MessageBox.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIScrollView.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UILoadingBar.h\"\n#include \"2d/CCLabel.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nvoid TVPMessageBoxForm::show(const std::string &caption, const std::string &text, int nBtns, const std::string *btnText, const std::function<void(int)> &callback)\n{\n\tTVPMessageBoxForm *ret = new TVPMessageBoxForm;\n\tret->autorelease();\n\tret->init(caption, text, nBtns, btnText, callback);\n\tTVPMainScene::GetInstance()->pushUIForm(ret, TVPMainScene::eEnterAniNone);\n}\n\nvoid TVPMessageBoxForm::showYesNo(const std::string &caption, const std::string &text, const std::function<void(int)> &callback)\n{\n\tLocaleConfigManager *mgr = LocaleConfigManager::GetInstance();\n\tstd::string btns[2] = {\n\t\tmgr->GetText(\"msgbox_yes\"),\n\t\tmgr->GetText(\"msgbox_no\")\n\t};\n\treturn show(caption, text, 2, btns, callback);\n}\n\nvoid TVPMessageBoxForm::init(const std::string &caption, const std::string &text, int nBtns, const std::string *btnText, const std::function<void(int)> &callback)\n{\n\t_callback = callback;\n\n\tinitFromFile(nullptr, \"ui/MessageBox.csb\", nullptr);\n\n\tif (_title) _title->setString(caption);\n\tif (_textContent) {\n\t\t_textContent->setString(\"\");\n\t\t_textContent->ignoreContentAdaptWithSize(true);\n\t\t_textContent->setString(text);\n\t\tconst Size &textSize = _textContent->getContentSize();\n\t\tconst Size &viewSize = _textContainer->getInnerContainerSize();\n\t\tif (textSize.height > viewSize.height) {\n\t\t\t_textContainer->setInnerContainerSize(textSize);\n\t\t\t_textContent->setPosition(Vec2(0, textSize.height));\n\t\t}\n\t}\n\t_btnModel->retain();\n\t_btnModel->removeFromParentAndCleanup(false);\n\n\tstd::vector<Widget *> btns;\n\n\tfloat totalWidth = 0;\n\n\tSize origsize = _btnModel->getContentSize();\n\tSize btnSize = _btnBody->getContentSize();\n\n\tfor (int i = 0; i < nBtns; ++i) {\n\t\t_btnBody->setTitleText(btnText[i]);\n\t\tSize textSize = _btnBody->getTitleRenderer()->getContentSize();\n\t\tfloat fontSize = _btnBody->getTitleFontSize();\n\t\ttextSize.width += fontSize;\n\t\t_btnBody->addClickEventListener([this, i](Ref* node) {\n\t\t\tretain();\n\t\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniNone);\n\t\t\tif (_callback) _callback(i);\n\t\t\trelease();\n\t\t});\n\t\tSize size = _btnModel->getContentSize();\n\t\tif (btnSize.width < textSize.width) {\n\t\t\tSize size = origsize;\n\t\t\tsize.width += textSize.width - btnSize.width;\n\t\t\t_btnModel->setContentSize(size);\n\t\t\tui::Helper::doLayout(_btnModel);\n\t\t} else if (size.width != origsize.width) {\n\t\t\t_btnModel->setContentSize(origsize);\n\t\t\tui::Helper::doLayout(_btnModel);\n\t\t}\n\t\tWidget *btn = _btnModel->clone();\n\t\ttotalWidth += btn->getContentSize().width;\n\t\tbtns.emplace_back(btn);\n\t\t_btnList->addChild(btn);\n\t\tbtn->setTag(i);\n\t}\n\tfloat gap = _btnList->getContentSize().width - totalWidth;\n\tif (gap < 0) {\n\t\tgap /= nBtns + 1;\n\t} else {\n\t\tgap /= nBtns + 1;\n\t}\n\tfloat x = gap;\n\n\tfor (Widget *btn : btns) {\n\t\tVec2 pos = btn->getPosition();\n\t\tpos.x = x;\n\t\tbtn->setPosition(pos);\n\t\tx += btn->getContentSize().width + gap;\n\t}\n\t_btnModel->release();\n\t_btnModel = nullptr;\n}\n\nvoid TVPMessageBoxForm::bindBodyController(const NodeMap &allNodes)\n{\n\t_title = dynamic_cast<Text*>(allNodes.findController(\"title\"));\n\t_textContent = dynamic_cast<Text*>(allNodes.findController(\"content\"));\n\t_textContainer = dynamic_cast<ScrollView*>(allNodes.findController(\"text\"));\n\n\t_btnBody = dynamic_cast<Button*>(allNodes.findController(\"btnBody\"));\n\t_btnModel = allNodes.findWidget(\"btn\");\n\t_btnList = _btnModel->getParent();\n}\n\nvoid TVPMessageBoxForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event)\n{\n\tif (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) {\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniNone);\n\t}\n}\n\nTVPSimpleProgressForm* TVPSimpleProgressForm::create()\n{\n\tTVPSimpleProgressForm* form = new TVPSimpleProgressForm;\n\tform->autorelease();\n\tform->initFromFile(\"ui/ProgressBox.csb\");\n\treturn form;\n}\n\nvoid TVPSimpleProgressForm::initButtons(const std::vector<std::pair<std::string, std::function<void(cocos2d::Ref*)> > > &vec)\n{\n\tSize btnSize = _btnCell->getContentSize();\n\tfloat totalWidth = 0;\n\tfloat containerWidth = _btnContainer->getContentSize().width;\n\tfloat edge = _btnCell->getPosition().x;\n\tcontainerWidth -= edge * 2;\n\tstd::vector<Node *> buttons;\n\tfloat btnEdge = btnSize.width - _btnButton->getTitleRenderer()->getContentSize().width;\n\tfor (const auto &it : vec) {\n\t\t_btnButton->setTitleText(it.first);\n\t\t_btnButton->addClickEventListener(it.second);\n\t\tbtnSize.width = _btnButton->getTitleRenderer()->getContentSize().width + btnEdge;\n\t\t_btnCell->setContentSize(btnSize);\n\t\tui::Helper::doLayout(_btnCell);\n\t\ttotalWidth += btnSize.width;\n\t\tWidget *btn = _btnCell->clone();\n\t\tbuttons.push_back(btn);\n\t\t_btnContainer->addChild(btn);\n\t}\n\tfloat x = edge;\n\tfloat gap = (containerWidth - totalWidth) / buttons.size();\n\tfor (Node *btn : buttons) {\n\t\tbtn->setPositionX(x);\n\t\tx += btn->getContentSize().width;\n\t}\n}\n\nvoid TVPSimpleProgressForm::setTitle(const std::string &text)\n{\n\t_textTitle->setString(text);\n}\nvoid TVPSimpleProgressForm::setContent(const std::string &text)\n{\n\t_textContent->setString(text);\n}\n\nvoid TVPSimpleProgressForm::setPercentWithText(float percent)\n{\n\t_progressBar[0]->setPercent(percent);\n\tchar tmp[16];\n\tsprintf(tmp, \"%2.2f%%\", percent);\n\t_textProgress[0]->setString(tmp);\n}\nvoid TVPSimpleProgressForm::setPercentWithText2(float percent)\n{\n\t_progressBar[1]->setPercent(percent);\n\tchar tmp[16];\n\tsprintf(tmp, \"%2.2f%%\", percent);\n\t_textProgress[1]->setString(tmp);\n}\n\nvoid TVPSimpleProgressForm::setPercentOnly(float percent)\n{\n\t_progressBar[0]->setPercent(percent * 100);\n}\n\nvoid TVPSimpleProgressForm::setPercentOnly2(float percent)\n{\n\t_progressBar[1]->setPercent(percent * 100);\n}\n\nvoid TVPSimpleProgressForm::setPercentText(const std::string &text)\n{\n\t_textProgress[0]->setString(text);\n}\n\nvoid TVPSimpleProgressForm::setPercentText2(const std::string &text)\n{\n\t_textProgress[1]->setString(text);\n}\n\nvoid TVPSimpleProgressForm::setProgress2Visible(bool visible)\n{\n\t// TODO\n}\n\nvoid TVPSimpleProgressForm::bindBodyController(const NodeMap &allNodes)\n{\n\tLocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance();\n\t_progressBar[0] = allNodes.findController<LoadingBar>(\"progrss_1\");\n\t_progressBar[1] = allNodes.findController<LoadingBar>(\"progrss_2\");\n\t_textProgress[0] = allNodes.findController<Text>(\"progress_text_1\");\n\t_textProgress[1] = allNodes.findController<Text>(\"progress_text_2\");\n\t_textContent = allNodes.findController<Text>(\"text\");\n\t_textTitle = allNodes.findController<Text>(\"title\");\n\t_btnContainer = allNodes.findController(\"btnList\");\n\t_btnCell = allNodes.findWidget(\"btnCell\");\n\t_btnButton = allNodes.findController<Button>(\"btn\");\n\t_btnCell->removeFromParentAndCleanup(false);\n}\n"
  },
  {
    "path": "src/core/environ/ui/MessageBox.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n#include \"base/CCRefPtr.h\"\n\nclass TVPMessageBoxForm : public iTVPBaseForm {\npublic:\n\tstatic void show(const std::string &caption, const std::string &text, int nBtns,\n\t\tconst std::string *btnText, const std::function<void(int)> &callback);\n\n\tstatic void showYesNo(const std::string &caption, const std::string &text, const std::function<void(int)> &callback);\n\nprivate:\n\tvoid init(const std::string &caption, const std::string &text, int nBtns,\n\t\tconst std::string *btnText, const std::function<void(int)> &callback);\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvirtual void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\n\tcocos2d::ui::ScrollView *_textContainer; // \"text\"\n\tcocos2d::Node *_btnList; // parent of \"btn\"\n\tcocos2d::ui::Text* _title, *_textContent; // \"content\"\n\tcocos2d::ui::Widget *_btnModel; // \"btn\"\n\tcocos2d::ui::Button *_btnBody;\n\n\tstd::function<void(int)> _callback;\n};\n\nclass TVPSimpleProgressForm : public iTVPBaseForm {\npublic:\n\tstatic TVPSimpleProgressForm* create();\n\n\tvoid initButtons(const std::vector<std::pair<std::string, std::function<void(cocos2d::Ref*)> > > &vec);\n\n\tvoid setTitle(const std::string &text);\n\tvoid setContent(const std::string &text);\n\tvoid setPercentWithText(float percent);\n\tvoid setPercentWithText2(float percent);\n\tvoid setPercentOnly(float percent);\n\tvoid setPercentOnly2(float percent);\n\tvoid setPercentText(const std::string &text);\n\tvoid setPercentText2(const std::string &text);\n\tvoid setProgress2Visible(bool visible);\n\nprivate:\n\tvoid bindBodyController(const NodeMap &allNodes) override;\n\n\tcocos2d::ui::LoadingBar *_progressBar[2];\n\tcocos2d::ui::Text *_textTitle, *_textContent, *_textProgress[2];\n\tstd::vector<cocos2d::ui::Button *> _vecButtons;\n\tcocos2d::Node *_btnContainer;\n\t// button template\n\tcocos2d::RefPtr<cocos2d::ui::Widget> _btnCell;\n\tcocos2d::ui::Button *_btnButton;\n};\n"
  },
  {
    "path": "src/core/environ/ui/PreferenceConfig.h",
    "content": "extern void TVPInitTextureFormatList();\nextern bool TVPIsSupportTextureFormat(GLenum fmt);\n\nstatic bool PreferenceGetValueBool(const std::string &name, bool defval) {\n\treturn GetConfigManager()->GetValue<bool>(name, defval);\n}\nstatic void PreferenceSetValueBool(const std::string &name, bool v) {\n\tGetConfigManager()->SetValueInt(name, v);\n}\nstatic std::string PreferenceGetValueString(const std::string &name, const std::string& defval) {\n\treturn GetConfigManager()->GetValue<std::string>(name, defval);\n}\nstatic void PreferenceSetValueString(const std::string &name, const std::string& v) {\n\tGetConfigManager()->SetValue(name, v);\n}\nstatic float PreferenceGetValueFloat(const std::string &name, float defval) {\n\treturn GetConfigManager()->GetValue<float>(name, defval);\n}\nstatic void PreferenceSetValueFloat(const std::string &name, float v) {\n\tGetConfigManager()->SetValueFloat(name, v);\n}\n\nnamespace {\nstatic tPreferenceScreen RootPreference;\nstatic tPreferenceScreen OpenglOptPreference, SoftRendererOptPreference;\nstatic Size PrefListSize;\n\nclass tTVPPreferenceInfoConstant : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfoConstant(const std::string &cap) : iTVPPreferenceInfo(cap, \"\") {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\treturn CreatePreferenceItem<tPreferenceItemConstant>(idx, PrefListSize, locmgr->GetText(Caption));\n\t}\n};\n\nclass tTVPPreferenceInfoCheckBox : public tTVPPreferenceInfo<bool> {\npublic:\n\ttTVPPreferenceInfoCheckBox(const std::string &cap, const std::string &key, bool defval)\n\t\t: tTVPPreferenceInfo<bool>(cap, key, defval) {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\treturn CreatePreferenceItem<tPreferenceItemCheckBox>(idx, PrefListSize, locmgr->GetText(Caption),\n\t\t\t[this](tPreferenceItemCheckBox* item) {\n\t\t\titem->_getter = std::bind(&PreferenceGetValueBool, Key, DefaultValue);\n\t\t\titem->_setter = std::bind(&PreferenceSetValueBool, Key, std::placeholders::_1);\n\t\t});\n\t}\n};\n\nclass tTVPPreferenceInfoSelectList : public tTVPPreferenceInfo<std::string>, tPreferenceItemSelectListInfo {\npublic:\n\ttTVPPreferenceInfoSelectList(const std::string &cap, const std::string &key, const std::string &defval,\n\t\tconst std::initializer_list<std::pair<std::string, std::string> > &listinfo)\n\t\t: tTVPPreferenceInfo<std::string>(cap, key, defval), ListInfo(listinfo){}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\treturn CreatePreferenceItem<tPreferenceItemSelectList>(idx, PrefListSize, locmgr->GetText(Caption),\n\t\t\t[this](tPreferenceItemSelectList* item) {\n\t\t\titem->initInfo(this);\n\t\t\titem->_getter = std::bind(&PreferenceGetValueString, Key, DefaultValue);\n\t\t\titem->_setter = [this](std::string v){ onSetValue(v); };\n\t\t});\n\t}\n\tvirtual const std::vector<std::pair<std::string, std::string> >& getListInfo() override {\n\t\treturn ListInfo;\n\t}\n\tvirtual void onSetValue(const std::string &v) {\n\t\tPreferenceSetValueString(Key, v);\n\t}\n\tstd::vector<std::pair<std::string, std::string> > ListInfo;\n};\n\nclass tTVPPreferenceInfoTextureCompressionSelectList : public tTVPPreferenceInfoSelectList {\npublic:\n\ttTVPPreferenceInfoTextureCompressionSelectList(const std::string &cap, const std::string &key, const std::string &defval,\n\t\tconst std::initializer_list<std::tuple<std::string, std::string, unsigned int> > &listinfo)\n\t: tTVPPreferenceInfoSelectList(cap, key, defval, std::initializer_list<std::pair<std::string, std::string> >())\n\t, TextFmtList(listinfo)\n\t{}\n\n\tvirtual const std::vector<std::pair<std::string, std::string> >& getListInfo() override {\n\t\tif (!ListInited) {\n\t\t\tListInited = true;\n\t\t\tTVPInitTextureFormatList();\n\t\t\tfor (const auto &it : TextFmtList) {\n\t\t\t\tunsigned int fmt = std::get<2>(it);\n\t\t\t\tif (!fmt || TVPIsSupportTextureFormat(fmt)) {\n\t\t\t\t\tListInfo.emplace_back(std::get<0>(it), std::get<1>(it));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ListInfo;\n\t}\n\n\tbool ListInited = false;\n\tstd::vector<std::tuple<std::string, std::string, unsigned int> > TextFmtList;\n};\n\n// class tTVPPreferenceInfoSelectRenderer : public tTVPPreferenceInfoSelectList {\n// \ttypedef tTVPPreferenceInfoSelectList inherit;\n// public:\n// \ttTVPPreferenceInfoSelectRenderer(const std::string &cap, const std::string &key, const std::string &defval,\n// \t\tconst std::initializer_list<std::pair<std::string, std::string> > &listinfo) : inherit(cap, key, defval, listinfo) {}\n// \tvirtual void onSetValue(const std::string &v) {\n// \t\tinherit::onSetValue(v);\n// \t\tif (v == \"opengl\") {\n// \t\t\tTVPOnOpenGLRendererSelected(true);\n// \t\t}\n// \t}\n// };\n\nclass tTVPPreferenceInfoSelectFile : public tTVPPreferenceInfo<std::string> {\npublic:\n\ttTVPPreferenceInfoSelectFile(const std::string &cap, const std::string &key, const std::string &defval)\n\t\t: tTVPPreferenceInfo<std::string>(cap, key, defval) {}\n\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\treturn CreatePreferenceItem<tPreferenceItemFileSelect>(idx, PrefListSize, locmgr->GetText(Caption),\n\t\t\t[this](tPreferenceItemFileSelect* item) {\n\t\t\titem->_getter = std::bind(&PreferenceGetValueString, Key, DefaultValue);\n\t\t\titem->_setter = std::bind(&PreferenceSetValueString, Key, std::placeholders::_1);\n\t\t});\n\t}\n};\n\nclass tTVPPreferenceInfoRendererSubPref : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfoRendererSubPref(const std::string &cap) { Caption = cap; } // Key is useless\n\tstatic tPreferenceScreen* GetSubPreferenceInfo() {\n\t\tstd::string renderer = PreferenceGetValueString(\"renderer\", \"software\");\n\t\tif (renderer == \"opengl\")\n\t\t\treturn &OpenglOptPreference;\n\t\telse if (renderer == \"software\")\n\t\t\treturn &SoftRendererOptPreference;\n\t\treturn nullptr;\n\t}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\tiPreferenceItem *ret = CreatePreferenceItem<tPreferenceItemSubDir>(idx, PrefListSize, locmgr->GetText(Caption));\n\t\tret->addClickEventListener([](Ref*) {\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create(GetSubPreferenceInfo()));\n\t\t});\n\t\treturn ret;\n\t}\n\tvirtual tPreferenceScreen* GetSubScreenInfo() { return GetSubPreferenceInfo(); }\n};\n\nclass tTVPPreferenceInfoSubPref : public iTVPPreferenceInfo {\n\ttPreferenceScreen Preference;\npublic:\n\ttTVPPreferenceInfoSubPref(const std::string &title, const std::initializer_list<iTVPPreferenceInfo*> &elem)\n\t\t: Preference(title, elem)\n\t{\n\t\tCaption = title;\n\t}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\tiPreferenceItem *ret = CreatePreferenceItem<tPreferenceItemSubDir>(idx, PrefListSize, locmgr->GetText(Caption));\n\t\tret->addClickEventListener([this](Ref*){\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create(&Preference));\n\t\t});\n\t\treturn ret;\n\t}\n\tvirtual tPreferenceScreen* GetSubScreenInfo() { return &Preference; }\n};\n\nclass tTVPPreferenceInfoSliderIcon : public tTVPPreferenceInfo<float> {\npublic:\n\ttTVPPreferenceInfoSliderIcon(const std::string &cap, const std::string &key, float defval)\n\t\t: tTVPPreferenceInfo<float>(cap, key, defval) {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\n\t\ttPreferenceItemCursorSlider * ret = new tPreferenceItemCursorSlider(DefaultValue, TVPMainScene::convertCursorScale);\n\t\tret->autorelease();\n\t\tret->_getter = std::bind(&PreferenceGetValueFloat, Key, DefaultValue);\n\t\tret->_setter = std::bind(&PreferenceSetValueFloat, Key, std::placeholders::_1);\n\t\tret->initFromInfo(idx, PrefListSize, locmgr->GetText(Caption));\n\t\treturn ret;\n\t}\n};\n\nclass tTVPPreferenceInfoSliderText : public tTVPPreferenceInfo<float> {\npublic:\n\ttTVPPreferenceInfoSliderText(const std::string &cap, const std::string &key, float defval)\n\t\t: tTVPPreferenceInfo<float>(cap, key, defval) {}\n\n\tstatic std::string convertPercentScale(float scale) {\n\t\tchar buf[16];\n\t\tsprintf(buf, \"%d%%\", (int)(scale * 100));\n\t\treturn buf;\n\t}\n\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\ttPreferenceItemTextSlider * ret = new tPreferenceItemTextSlider(DefaultValue, convertPercentScale);\n\t\tret->autorelease();\n\t\tret->_getter = std::bind(&PreferenceGetValueFloat, Key, DefaultValue);\n\t\tret->_setter = std::bind(&PreferenceSetValueFloat, Key, std::placeholders::_1);\n\t\tret->initFromInfo(idx, PrefListSize, locmgr->GetText(Caption));\n\t\treturn ret;\n\t}\n};\n\nclass tTVPPreferenceInfoFetchSDCardPermission : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfoFetchSDCardPermission(const std::string &cap) : iTVPPreferenceInfo(cap, \"\") {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\ttPreferenceItemConstant* ret = CreatePreferenceItem<tPreferenceItemConstant>(idx, PrefListSize, locmgr->GetText(Caption));\n\t\tret->setTouchEnabled(true);\n\t\tret->addClickEventListener([](Ref*) {\n\t\t\tTVPFetchSDCardPermission();\n\t\t});\n\t\treturn ret;\n\t}\n};\n\nclass tTVPPreferenceInfoResetDefaultSkin : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfoResetDefaultSkin(const std::string &cap) : iTVPPreferenceInfo(cap, \"\") {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\ttPreferenceItemConstant* ret = CreatePreferenceItem<tPreferenceItemConstant>(idx, PrefListSize, locmgr->GetText(Caption));\n\t\tret->setTouchEnabled(true);\n\t\tret->addClickEventListener([](Ref*) {\n\t\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\t\tif (TVPShowSimpleMessageBoxYesNo(locmgr->GetText(\"preference_ensure_reset_skin\"), locmgr->GetText(\"notice\")) == 0) {\n\t\t\t\tPreferenceSetValueString(\"skin_path\", \"\");\n\t\t\t}\n\t\t});\n\t\treturn ret;\n\t}\n};\n\nclass tTVPPreferenceInfoKeyMap : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfoKeyMap(const std::string &cap) : iTVPPreferenceInfo(cap, \"\") {}\n\tvirtual iPreferenceItem *createItem(int idx) override {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\tiPreferenceItem *ret = CreatePreferenceItem<tPreferenceItemSubDir>(idx, PrefListSize, locmgr->GetText(Caption));\n\t\tret->addClickEventListener([this](Ref*) {\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(KeyMapPreferenceForm::create(GetConfigManager()));\n\t\t});\n\t\treturn ret;\n\t}\n};\n\nstatic void initAllConfig() {\n\tif (!RootPreference.Preferences.empty()) return;\n\tRootPreference.Title = \"preference_title\";\n\tRootPreference.Preferences = {\n\t\tnew tTVPPreferenceInfoCheckBox(\"preference_output_log\", \"outputlog\", true),\n\t\tnew tTVPPreferenceInfoCheckBox(\"preference_show_fps\", \"showfps\", false),\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_fps_limit\", \"fps_limit\", \"60\",{\n\t\t\t{ \"60\", \"60\" },\n\t\t\t{ \"45\", \"45\" },\n\t\t\t{ \"30\", \"30\" },\n\t\t\t{ \"15\", \"15\" }\n\t\t}),\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_select_renderer\", \"renderer\", \"software\", {\n\t\t\t{ \"preference_opengl\", \"opengl\" },\n\t\t\t{ \"preference_software\", \"software\" }\n\t\t}),\n\t\tnew tTVPPreferenceInfoRendererSubPref(\"preference_renderer_opt\"),\n\t\tnew tTVPPreferenceInfoSelectFile(\"preference_default_font\", \"default_font\", \"\"),\n\t\tnew tTVPPreferenceInfoCheckBox(\"preference_force_def_font\", \"force_default_font\", false),\n#ifdef CC_TARGET_OS_IPHONE\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_mem_limit\", \"memusage\", \"high\", {\n#else\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_mem_limit\", \"memusage\", \"unlimited\", {\n#endif\n\t\t\t{ \"preference_mem_unlimited\", \"unlimited\" },\n\t\t\t{ \"preference_mem_high\", \"high\" },\n\t\t\t{ \"preference_mem_medium\", \"medium\" },\n\t\t\t{ \"preference_mem_low\", \"low\" }\n\t\t\t}),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"preference_keep_screen_alive\", \"keep_screen_alive\", true),\n\t\t\tnew tTVPPreferenceInfoSliderIcon(\"preference_virtual_cursor_scale\", \"vcursor_scale\", 0.5f),\n\t\t\tnew tTVPPreferenceInfoSliderText(\"preference_menu_handler_opacity\", \"menu_handler_opa\", 0.15f),\n\t\t\tnew tTVPPreferenceInfoKeyMap(\"preference_keymap\"),\n#ifdef GLOBAL_PREFERENCE\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"preference_remember_last_path\", \"remember_last_path\", true),\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"preference_hide_android_sys_btn\", \"hide_android_sys_btn\", false),\n\t\t\t// new tTVPPreferenceInfoFetchSDCardPermission(\"preference_android_fetch_sdcard_permission\"),\n#endif\n\t\t\tnew tTVPPreferenceInfoResetDefaultSkin(\"preference_reset_def_skin\"),\n\n#endif\n#if 0\n\t\t\tnew tTVPPreferenceInfo(tTVPPreferenceInfo::eTypeSubPref, \"preference_custom_option\"),\n#endif\n//\t\t\tnullptr\n\t};\n\n\tSoftRendererOptPreference.Title = \"preference_soft_renderer_opt\";\n\tSoftRendererOptPreference.Preferences = {\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_multi_draw_thread\", \"software_draw_thread\", \"0\", {\n\t\t\t{ \"preference_draw_thread_auto\", \"0\" },\n\t\t\t{ \"preference_draw_thread_1\", \"1\" },\n\t\t\t{ \"preference_draw_thread_2\", \"2\" },\n\t\t\t{ \"preference_draw_thread_3\", \"3\" },\n\t\t\t{ \"preference_draw_thread_4\", \"4\" },\n\t\t\t{ \"preference_draw_thread_5\", \"5\" },\n\t\t\t{ \"preference_draw_thread_6\", \"6\" },\n\t\t\t{ \"preference_draw_thread_7\", \"7\" },\n\t\t\t{ \"preference_draw_thread_8\", \"8\" }\n\t\t}),\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_software_compress_tex\", \"software_compress_tex\", \"none\", {\n\t\t\t{ \"preference_soft_compress_tex_none\", \"none\" },\n\t\t\t{ \"preference_soft_compress_tex_halfline\", \"halfline\" },\n \t\t\t{ \"lz4\", \"lz4\" },\n \t\t\t{ \"lz4+TLG5\", \"lz4+tlg5\" }\n\t\t}),\n\t};\n\n\tOpenglOptPreference.Title = \"preference_opengl_renderer_opt\";\n\tOpenglOptPreference.Preferences = {\n\t\tnew tTVPPreferenceInfoSubPref(\"preference_opengl_extension_opt\", {\n\t\t\tnew tTVPPreferenceInfoConstant(\"preference_opengl_extension_desc\"),\n#ifdef CC_TARGET_OS_IPHONE\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_EXT_shader_framebuffer_fetch\", \"GL_EXT_shader_framebuffer_fetch\", true),\n#else\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_EXT_shader_framebuffer_fetch\", \"GL_EXT_shader_framebuffer_fetch\", false),\n#endif\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_ARM_shader_framebuffer_fetch\", \"GL_ARM_shader_framebuffer_fetch\", true),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_NV_shader_framebuffer_fetch\", \"GL_NV_shader_framebuffer_fetch\", true),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_EXT_copy_image\", \"GL_EXT_copy_image\", false),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_OES_copy_image\", \"GL_OES_copy_image\", false),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_ARB_copy_image\", \"GL_ARB_copy_image\", false),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_NV_copy_image\", \"GL_NV_copy_image\", false),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_EXT_clear_texture\", \"GL_EXT_clear_texture\", true),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_ARB_clear_texture\", \"GL_ARB_clear_texture\", true),\n\t\t\tnew tTVPPreferenceInfoCheckBox(\"GL_QCOM_alpha_test\", \"GL_QCOM_alpha_test\", true),\n\t\t}),\n\t\tnew tTVPPreferenceInfoCheckBox(\"preference_ogl_accurate_render\", \"ogl_accurate_render\", false),\n//\t\tnew tTVPPreferenceInfoCheckBox(\"preference_opengl_dup_target\", \"ogl_dup_target\", true),\n\t\tnew tTVPPreferenceInfoSelectList(\"preference_ogl_max_texsize\", \"ogl_max_texsize\", \"0\", {\n\t\t\t{ \"preference_ogl_texsize_auto\", \"0\" },\n\t\t\t{ \"preference_ogl_texsize_1024\", \"1024\" },\n\t\t\t{ \"preference_ogl_texsize_2048\", \"2048\" },\n\t\t\t{ \"preference_ogl_texsize_4096\", \"4096\" },\n\t\t\t{ \"preference_ogl_texsize_8192\", \"8192\" },\n\t\t\t{ \"preference_ogl_texsize_16384\", \"16384\" }\n\t\t}),\n\t\tnew tTVPPreferenceInfoTextureCompressionSelectList(\"preference_ogl_compress_tex\", \"ogl_compress_tex\", \"none\", {\n\t\t\tstd::make_tuple(\"preference_ogl_compress_tex_none\", \"none\", 0),\n\t\t\tstd::make_tuple(\"preference_ogl_compress_tex_half\", \"half\", 0),\n\t\t\tstd::make_tuple(\"ETC2\", \"etc2\", 0x9278), // GL_COMPRESSED_RGBA8_ETC2_EAC\n\t\t\tstd::make_tuple(\"PVRTC\", \"pvrtc\", 0x8C02), // GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n\t\t}),\n// \t\tnew tTVPPreferenceInfoSelectList(\"preference_ogl_render_tex_quality\", \"ogl_render_tex_quality\", \"1\", {\n// \t\t\t{ \"preference_ogl_render_tex_quality_100\", \"1\" },\n// \t\t\t{ \"preference_ogl_render_tex_quality_75\", \"0.75\" },\n// \t\t\t{ \"preference_ogl_render_tex_quality_50\", \"0.5\" }\n// \t\t}),\n\t};\n}\n};\n"
  },
  {
    "path": "src/core/environ/ui/PreferenceForm.cpp",
    "content": "#include \"PreferenceForm.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UICheckBox.h\"\n#include \"ui/UIListView.h\"\n#include \"ui/UISlider.h\"\n#include \"ui/UIButton.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n#include \"tinyxml2/tinyxml2.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"2d/CCSprite.h\"\n#include \"SeletListForm.h\"\n#include \"FileSelectorForm.h\"\n#include \"Platform.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nvoid TVPPreferenceForm::initPref(const tPreferenceScreen *config) {\n\tConfig = config;\n\tPrefList->removeAllItems();\n\tLocaleConfigManager::GetInstance()->initText(_title, config->Title);\n\tfor (int idx = 0; idx < config->Preferences.size(); ++idx) {\n\t\tauto info = config->Preferences[idx];\n\t\tif (info) {\n\t\t\tPrefList->pushBackCustomItem(info->createItem(idx));\n\t\t}\n\t}\n\tWidget *nullcell = new Widget();\n\tnullcell->setContentSize(Size(PrefList->getContentSize().width, 200));\n\tPrefList->pushBackCustomItem(nullcell);\n}\n\nvoid TVPPreferenceForm::bindBodyController(const NodeMap &allNodes) {\n\tPrefList = static_cast<ListView*>(allNodes.findController(\"list\"));\n\tif (NaviBar.Left) {\n\t\tNaviBar.Left->addClickEventListener([this](cocos2d::Ref*){\n\t\t\tTVPMainScene::GetInstance()->popUIForm(this);\n\t\t});\n\t}\n}\n\nvoid TVPPreferenceForm::bindHeaderController(const NodeMap &allNodes)\n{\n\t_title = static_cast<Button*>(allNodes.findController(\"title\"));\n\tif (_title) _title->setEnabled(false);\n}\n\nvoid tPreferenceScreen::clear() {\n\tfor (auto p : Preferences) delete p;\n\tPreferences.clear();\n}\n\nvoid iPreferenceItem::initFromInfo(int idx, Size size, const std::string& title) {\n\tinit();\n\tCSBReader reader;\n\tNode * root = reader.Load(getUIFileName());\n\tsize.height = root->getContentSize().height;\n\tsetContentSize(size);\n\troot->setContentSize(size);\n\tui::Helper::doLayout(root);\n\taddChild(root);\n\t_title = static_cast<Text*>(reader.findController(\"title\"));\n\tif (!title.empty()) _title->setString(title);\n\tBgOdd = reader.findController(\"bg_odd\", false);\n\tBgEven = reader.findController(\"bg_even\", false);\n\tif (BgOdd) BgOdd->setVisible((idx + 1) & 1);\n\tif (BgEven) BgEven->setVisible(idx & 1);\n\tinitController(reader);\n}\n\nclass HackCheckBox : public CheckBox {\npublic:\n\tvoid fireReleaseUpEvent() {\n\t\tbool newstat = !_isSelected;\n\t\tsetSelected(newstat);\n\t\tdispatchSelectChangedEvent(newstat);\n\t}\n};\n\ntPreferenceItemCheckBox::tPreferenceItemCheckBox()\n\t: highlight(nullptr)\n{\n\n}\n\nvoid tPreferenceItemCheckBox::initController(const NodeMap &allNodes) {\n\tcheckbox = static_cast<CheckBox*>(allNodes.findController(\"checkbox\"));\n\tcheckbox->setSelected(_getter());\n\tcheckbox->addEventListener([=](Ref*, CheckBox::EventType e) {\n\t\tthis->_setter(e == CheckBox::EventType::SELECTED);\n\t});\n\thighlight = allNodes.findController(\"highlight\");\n\tsetTouchEnabled(true);\n\taddClickEventListener([this](Ref*){\n\t\tstatic_cast<HackCheckBox*>(checkbox)->fireReleaseUpEvent();\n\t});\n}\n\nconst char* tPreferenceItemCheckBox::getUIFileName() const {\n\treturn \"ui/comctrl/CheckBoxItem.csb\";\n}\n\nvoid tPreferenceItemCheckBox::onPressStateChangedToNormal() {\n\tif (highlight) highlight->setVisible(false);\n}\n\nvoid tPreferenceItemCheckBox::onPressStateChangedToPressed() {\n\tif (highlight) highlight->setVisible(true);\n}\n\nvoid tPreferenceItemConstant::initController(const NodeMap &allNodes) {\n\thighlight = allNodes.findController(\"highlight\");\n\tallNodes.findController(\"dir_icon\")->setVisible(false);\n\tSize origSize = _title->getContentSize();\n\t_title->setTextAreaSize(Size::ZERO);\n\tstd::string s = _title->getString();\n\tSize sizeTmp = _title->getVirtualRendererSize();\n\tfloat addHeight = 0;\n\tif (sizeTmp.width < origSize.width) { // single line\n\t\tsizeTmp.width = origSize.width;;\n\t\tsizeTmp.height = 0;\n\t\t_title->setTextAreaSize(sizeTmp);\n\t\taddHeight = _title->getVirtualRendererSize().height - origSize.height;\n\t\tif (addHeight < 0) addHeight = 0;\n\t} else { // multi line\n\t\tsizeTmp.width = origSize.width;;\n\t\tsizeTmp.height = 0;\n\t\t_title->setTextAreaSize(sizeTmp);\n\t\tsizeTmp = _title->getVirtualRendererSize();\n\t\t_title->setContentSize(sizeTmp);\n\t\taddHeight = sizeTmp.height - origSize.height;\n\t}\n\tNode *root = getChildren().front();\n\tsizeTmp = root->getContentSize();\n\tsizeTmp.height += addHeight;\n\troot->setContentSize(sizeTmp);\n\tui::Helper::doLayout(root);\n\tsetContentSize(sizeTmp);\n}\n\nconst char* tPreferenceItemSubDir::getUIFileName() const  {\n\treturn \"ui/comctrl/SubDirItem.csb\";\n}\n\nvoid tPreferenceItemWithHighlight::initController(const NodeMap &allNodes) {\n\tsetTouchEnabled(true);\n\thighlight = allNodes.findController(\"highlight\");\n}\n\nvoid tPreferenceItemWithHighlight::onPressStateChangedToNormal() {\n\tif (highlight) highlight->setVisible(false);\n}\n\nvoid tPreferenceItemWithHighlight::onPressStateChangedToPressed() {\n\tif (highlight) highlight->setVisible(true);\n}\n\ntPreferenceItemSubDir::tPreferenceItemSubDir()\n{\n\n}\n\nvoid tPreferenceItemSelectList::initController(const NodeMap &allNodes) {\n\thighlight = allNodes.findController(\"highlight\");\n\tselected = static_cast<Text*>(allNodes.findController(\"selected\"));\n\tupdateHightlight();\n\tsetTouchEnabled(true);\n\taddClickEventListener(std::bind(&tPreferenceItemSelectList::showForm, this, std::placeholders::_1));\n}\n\nconst char* tPreferenceItemSelectList::getUIFileName() const  {\n\treturn \"ui/comctrl/SelectListItem.csb\";\n}\n\nvoid tPreferenceItemSelectList::showForm(cocos2d::Ref*) {\n\tstd::vector<std::string> lst;\n\tfor (const std::pair<std::string, std::string>& item : CurInfo->getListInfo()) {\n\t\tlst.emplace_back(item.first);\n\t}\n\tTVPSelectListForm *form = TVPSelectListForm::create(lst, highlightTid, [this](int idx){\n\t\tconst std::pair<std::string, std::string>& item = CurInfo->getListInfo()[idx];\n\t\thighlightTid = item.first;\n\t\tif (highlightTid.empty())\n\t\t\tselected->setString(item.second);\n\t\telse\n\t\t\tLocaleConfigManager::GetInstance()->initText(selected, highlightTid);\n\t\t_setter(item.second);\n\t});\n\tTVPMainScene::GetInstance()->pushUIForm(form, TVPMainScene::eEnterFromBottom);\n}\n\nvoid tPreferenceItemSelectList::onPressStateChangedToNormal() {\n\tif (highlight) highlight->setVisible(false);\n}\n\nvoid tPreferenceItemSelectList::onPressStateChangedToPressed() {\n\tif (highlight) highlight->setVisible(true);\n}\n\ntPreferenceItemSelectList::tPreferenceItemSelectList()\n\t: highlight(nullptr)\n{\n\n}\n\nvoid tPreferenceItemSelectList::updateHightlight() {\n\tstd::string val = _getter();\n\tfor (const std::pair<std::string, std::string>& item : CurInfo->getListInfo()) {\n\t\tif (item.second == val) {\n\t\t\thighlightTid = item.first;\n\t\t\tLocaleConfigManager::GetInstance()->initText(selected, item.first);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\ntPreferenceItemKeyValPair::tPreferenceItemKeyValPair() {\n\thighlight = nullptr;\n\tselected = nullptr;\n}\n\nvoid tPreferenceItemKeyValPair::initController(const NodeMap &allNodes) {\n\thighlight = allNodes.findController(\"highlight\");\n\tselected = static_cast<Text*>(allNodes.findController(\"selected\"));\n\tstd::pair<std::string, std::string> val = _getter();\n\t_title->setString(val.first);\n\tselected->setString(val.second);\n\tsetTouchEnabled(true);\n\taddClickEventListener(std::bind(&tPreferenceItemKeyValPair::showInput, this, std::placeholders::_1));\n}\n\nconst char* tPreferenceItemKeyValPair::getUIFileName() const  {\n\treturn \"ui/comctrl/SelectListItem.csb\";\n}\n\nvoid tPreferenceItemKeyValPair::onPressStateChangedToNormal() {\n\tif (highlight) highlight->setVisible(false);\n}\n\nvoid tPreferenceItemKeyValPair::onPressStateChangedToPressed() {\n\tif (highlight) highlight->setVisible(true);\n}\n\nvoid tPreferenceItemKeyValPair::showInput(cocos2d::Ref*) {\n\tstd::pair<std::string, std::string> val = _getter();\n\tTVPTextPairInputForm *form = TVPTextPairInputForm::create(val.first, val.second,\n\t\t[this](const std::string &t1, const std::string &t2){\n\t\t_title->setString(t1);\n\t\tselected->setString(t2);\n\t\t_setter(std::make_pair(t1, t2));\n\t});\n\tTVPMainScene::GetInstance()->pushUIForm(form, TVPMainScene::eEnterFromBottom);\n}\n\nvoid tPreferenceItemKeyValPair::updateText() {\n\tstd::pair<std::string, std::string> val = _getter();\n\tif (_title) _title->setString(val.first + \" =\");\n\tif (selected) selected->setString(val.second);\n}\n\nTVPCustomPreferenceForm * TVPCustomPreferenceForm::create(const std::string &tid_title, int count,\n\tconst std::function<std::pair<std::string, std::string>(int)> &getter,\n\tconst std::function<void(int, const std::pair<std::string, std::string>&)> &setter) {\n\tTVPCustomPreferenceForm *ret = new TVPCustomPreferenceForm;\n\tret->initFromFile(\"ui/NaviBar.csb\", \"ui/ListView.csb\", nullptr);\n\tret->initFromInfo(tid_title, count, getter, setter);\n\tret->autorelease();\n\treturn ret;\n}\n\nvoid TVPCustomPreferenceForm::bindBodyController(const NodeMap &allNodes) {\n\t_listview = static_cast<ListView*>(allNodes.findController(\"list\"));\n\tif (NaviBar.Left) {\n\t\tNaviBar.Left->addClickEventListener([this](cocos2d::Ref*){\n\t\t\tTVPMainScene::GetInstance()->popUIForm(this);\n\t\t});\n\t}\n}\n\nvoid TVPCustomPreferenceForm::bindHeaderController(const NodeMap &allNodes)\n{\n\t_title = static_cast<Button*>(allNodes.findController(\"title\"));\n\tif (_title) _title->setEnabled(false);\n}\n\nvoid TVPCustomPreferenceForm::initFromInfo(const std::string &tid_title, int count,\n\tconst std::function<std::pair<std::string, std::string>(int)> &getter,\n\tconst std::function<void(int, const std::pair<std::string, std::string>&)> &setter) {\n\t_getter = getter;\n\t_setter = setter;\n\tif (_title) LocaleConfigManager::GetInstance()->initText(_title, tid_title);\n\tif (!_listview) return;\n\t_listview->removeAllItems();\n\tSize size = _listview->getContentSize();\n\tCSBReader reader;\n\tfor (int i = 0; i < count; ++i) {\n\t\ttPreferenceItemKeyValPair *item = new tPreferenceItemKeyValPair;\n\t\titem->_getter = [=]()->std::pair<std::string, std::string>{return _getter(i); };\n\t\titem->_setter = [=](std::pair<std::string, std::string> val){\n\t\t\tif (val.first.empty() && val.second.empty()) return;\n\t\t\t_setter(i, val);\n\t\t};\n\t\titem->autorelease();\n\t\titem->initFromInfo(i, size, nullptr);\n\t\t_listview->pushBackCustomItem(item);\n\t}\n\tWidget *nullcell = new Widget();\n\tnullcell->setContentSize(Size(_listview->getContentSize().width, 200));\n\t_listview->pushBackCustomItem(nullcell);\n}\n\nvoid iPreferenceItemSlider::initController(const NodeMap &allNodes) {\n\t_slider = dynamic_cast<Slider*>(allNodes.findController(\"slider\"));\n\t_reset = dynamic_cast<Button*>(allNodes.findController(\"reset\"));\n\tif (_reset) {\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\t_reset->setTitleText(locmgr->GetText(_reset->getTitleText()));\n\t}\n\n\tfloat val = _getter();\n\t_slider->setPercent(val * 100.f);\n\t_slider->addTouchEventListener([this](Ref* p, Widget::TouchEventType e) {\n\t\tSlider* slider = static_cast<Slider*>(p);\n\t\tswitch (e) {\n\t\tcase Widget::TouchEventType::ENDED:\n\t\tcase Widget::TouchEventType::CANCELED:\n\t\t\t_setter(slider->getPercent() / 100.f);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t});\n}\n\nSprite *TVPCreateCUR();\nvoid tPreferenceItemCursorSlider::initController(const NodeMap &allNodes) {\n\tinherit::initController(allNodes);\n\tif (_reset) {\n\t\t_reset->addClickEventListener([this](Ref*){\n\t\t\t_slider->setPercent(_resetValue * 100.f);\n\t\t\t_icon->setScale(_curScaleConv(_resetValue));\n\t\t\t_setter(_resetValue);\n\t\t});\n\t}\n\t_icon = allNodes.findController(\"icon\");\n\t_cursor = TVPCreateCUR();\n\t_icon->addChild(_cursor);\n\t_icon->setScale(_curScaleConv(_slider->getPercent() / 100.f));\n\t_slider->addEventListener([this](Ref* p, Slider::EventType e) {\n\t\tif (e == Slider::EventType::ON_PERCENTAGE_CHANGED) {\n\t\t\tSlider* slider = static_cast<Slider*>(p);\n\t\t\t_icon->setScale(_curScaleConv(slider->getPercent() / 100.f));\n\t\t}\n\t});\n}\n\nconst char* tPreferenceItemCursorSlider::getUIFileName() const  {\n\treturn \"ui/comctrl/SliderIconItem.csb\";\n}\n\nvoid tPreferenceItemCursorSlider::onEnter() {\n\tinherit::onEnter();\n\tfloat scale = 1;\n\tfor (Node *p = _icon->getParent(); p; p = p->getParent()) {\n\t\tscale *= p->getScale();\n\t}\n\t_cursor->setScale(_cursor->getScale() / scale);\n}\n\nconst char* tPreferenceItemTextSlider::getUIFileName() const  {\n\treturn \"ui/comctrl/SliderTextItem.csb\";\n}\n\nvoid tPreferenceItemTextSlider::initController(const NodeMap &allNodes) {\n\tinherit::initController(allNodes);\n\t_text = dynamic_cast<Text*>(allNodes.findController(\"text\"));\n\tif (_reset) {\n\t\t_reset->addClickEventListener([this](Ref*){\n\t\t\t_slider->setPercent(_resetValue * 100.f);\n\t\t\t_text->setString(_strScaleConv(_resetValue));\n\t\t\t_setter(_resetValue);\n\t\t});\n\t}\n\t_text->setString(_strScaleConv(_slider->getPercent() / 100.f));\n\t_slider->addEventListener([this](Ref* p, Slider::EventType e) {\n\t\tif (e == Slider::EventType::ON_PERCENTAGE_CHANGED) {\n\t\t\tSlider* slider = static_cast<Slider*>(p);\n\t\t\t_text->setString(_strScaleConv(slider->getPercent() / 100.f));\n\t\t}\n\t});\n}\n\nvoid tPreferenceItemFileSelect::initController(const NodeMap &allNodes)\n{\n\thighlight = allNodes.findController(\"highlight\");\n\tselected = static_cast<Text*>(allNodes.findController(\"selected\"));\n\tupdateHightlight();\n\tsetTouchEnabled(true);\n\taddClickEventListener(std::bind(&tPreferenceItemFileSelect::showForm, this, std::placeholders::_1));\n}\n\nconst char* tPreferenceItemFileSelect::getUIFileName() const\n{\n\treturn \"ui/comctrl/SelectListItem.csb\";\n}\n\nvoid tPreferenceItemFileSelect::onPressStateChangedToNormal()\n{\n\tif (highlight) highlight->setVisible(false);\n}\n\nvoid tPreferenceItemFileSelect::onPressStateChangedToPressed()\n{\n\tif (highlight) highlight->setVisible(true);\n}\n\nvoid tPreferenceItemFileSelect::showForm(cocos2d::Ref*)\n{\n\tstd::string fullname = _getter();\n\tstd::string initname, initdir;\n\tif (!fullname.empty()) {\n\t\tstd::pair<std::string, std::string> path = TVPBaseFileSelectorForm::PathSplit(fullname);\n\t\tinitdir = path.first;\n\t\tinitname = path.second;\n\t}\n\tif (initdir.empty()) {\n\t\tinitdir = TVPGetDriverPath()[0];\n\t}\n\tTVPFileSelectorForm *form = TVPFileSelectorForm::create(initname, initdir, false);\n\tform->setOnClose([this](const std::string& result) {\n\t\t_setter(result);\n\t\tupdateHightlight();\n\t});\n\tTVPMainScene::GetInstance()->pushUIForm(form);\n}\n\nvoid tPreferenceItemFileSelect::updateHightlight()\n{\n\tif (selected) selected->setString(_getter());\n}\n\nKeyMapPreferenceForm::KeyMapPreferenceForm(iSysConfigManager* mgr)\n\t: _mgr(mgr)\n{\n\n}\n\nvoid KeyMapPreferenceForm::initData()\n{\n\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\tPrefList->removeAllItems();\n\tlocmgr->initText(_title, \"preference_keymap_title\");\n\n\tSize size = PrefList->getContentSize();\n#if 0\n\ttPreferenceItemConstant* celladd = CreatePreferenceItem<tPreferenceItemConstant>(0, size, locmgr->GetText(\"preference_keymap_add\"));\n\tcelladd->setTouchEnabled(true);\n\tcelladd->addClickEventListener([this](Ref*) {\n\t\tTVPKeyPairSelectForm *form = TVPKeyPairSelectForm::create([this](int k) {\n\t\t\tTVPKeyPairSelectForm *form = TVPKeyPairSelectForm::create([this, k](int v) {\n\t\t\t\t_mgr->SetKeyMap(k, v);\n\t\t\t\tinitData();\n\t\t\t});\n\t\t\tTVPMainScene::GetInstance()->pushUIForm(form, TVPMainScene::eEnterFromBottom);\n\t\t});\n\t\tTVPMainScene::GetInstance()->pushUIForm(form, TVPMainScene::eEnterFromBottom);\n\t});\n\tPrefList->pushBackCustomItem(celladd);\n\n\tconst auto& keymap = _mgr->GetKeyMap();\n\tint counter = 0;\n\tfor (const std::pair<int, int>& it : keymap) {\n\t\tif (it.first && it.second) {\n\t\t\ttPreferenceItemKeyMap *cell = new tPreferenceItemKeyMap;\n\t\t\tcell->initData(it.first, it.second, ++counter, size);\n\t\t\tcell->_onDelete = [this](tPreferenceItemDeletable* cell) {\n\t\t\t\tauto &keypair = static_cast<tPreferenceItemKeyMap*>(cell)->_keypair;\n\t\t\t\t_mgr->SetKeyMap(keypair.first, 0);\n\t\t\t};\n\t\t\tPrefList->pushBackCustomItem(cell);\n\t\t}\n\t}\n#endif\n\tWidget *nullcell = new Widget();\n\tnullcell->setContentSize(Size(PrefList->getContentSize().width, 200));\n\tPrefList->pushBackCustomItem(nullcell);\n}\n\nKeyMapPreferenceForm* KeyMapPreferenceForm::create(iSysConfigManager* mgr)\n{\n\tKeyMapPreferenceForm *ret = new KeyMapPreferenceForm(mgr);\n\tret->autorelease();\n\tret->initFromFile(\"ui/NaviBar.csb\", \"ui/ListView.csb\", nullptr);\n\tret->initData();\n\treturn ret;\n}\n\nvoid tPreferenceItemDeletable::initController(const NodeMap &allNodes)\n{\n\t_deleteIcon = allNodes.findWidget(\"delete\");\n\t_scrollview = allNodes.findController<cocos2d::ui::ScrollView>(\"scrollview\");\n\t_scrollview->setScrollBarEnabled(false);\n\tSize viewSize = _scrollview->getContentSize();\n\tfloat iconWidth = _deleteIcon->getContentSize().width;\n\tviewSize.width += iconWidth;\n\t_scrollview->setInnerContainerSize(viewSize);\n\twalkTouchEvent(_scrollview);\n\t_deleteIcon->addTouchEventListener(nullptr);\n\t_deleteIcon->addClickEventListener([this](Ref*) {\n\t\tif (_onDelete) _onDelete(this);\n\t});\n}\n\nconst char* tPreferenceItemDeletable::getUIFileName() const\n{\n\treturn \"ui/comctrl/DeletableItem.csb\";\n}\n\nvoid tPreferenceItemDeletable::onTouchEvent(cocos2d::Ref* p, cocos2d::ui::Widget::TouchEventType ev)\n{\n\n}\n\nvoid tPreferenceItemDeletable::walkTouchEvent(Widget* node)\n{\n\tnode->addTouchEventListener(std::bind(&tPreferenceItemDeletable::onTouchEvent,\n\t\tthis, std::placeholders::_1, std::placeholders::_2));\n\tauto &vecChildren = node->getChildren();\n\tfor (Node *child : vecChildren) {\n\t\tWidget *widget = dynamic_cast<Widget*>(child);\n\t\tif (widget) {\n\t\t\twalkTouchEvent(widget);\n\t\t}\n\t}\n}\n\nvoid tPreferenceItemKeyMap::initData(int k, int v, int idx, const cocos2d::Size &size)\n{\n\t_keypair.first = k; _keypair.second = v;\n\tchar buf[32];\n\tsprintf(buf, \"%d <=> %d\", k, v);\n\tinitFromInfo(idx, size, buf);\n}\n\n"
  },
  {
    "path": "src/core/environ/ui/PreferenceForm.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n#include \"ui/UIWidget.h\"\n#include \"ConfigManager/GlobalConfigManager.h\"\n\nnamespace tinyxml2 {\n\tclass XMLElement;\n}\n\nclass iTVPPreferenceInfo;\nstruct tPreferenceScreen {\n\ttPreferenceScreen() {}\n\ttPreferenceScreen(const std::string &title, const std::initializer_list<iTVPPreferenceInfo*> &elem)\n\t\t: Title(title), Preferences(elem) {}\n\t~tPreferenceScreen() { clear(); }\n\tvoid clear();\n\tvoid init(const std::initializer_list<iTVPPreferenceInfo*> &elem) {\n\t\tPreferences = elem;\n\t}\n\tstd::string Title; // as tid\n\tstd::vector<iTVPPreferenceInfo*> Preferences;\n};\n\nclass iPreferenceItem;\n\nclass iTVPPreferenceInfo {\npublic:\n\tvirtual iPreferenceItem *createItem(int idx) = 0;\n\tvirtual void InitDefaultConfig() {}\n\tvirtual tPreferenceScreen* GetSubScreenInfo() { return nullptr; }\n\n\tiTVPPreferenceInfo() {}\n\tiTVPPreferenceInfo(const std::string &cap, const std::string &key) : Caption(cap), Key(key) {}\n\tvirtual ~iTVPPreferenceInfo() {}\n\n\tstd::string Caption;\n\tstd::string Key; // in config\n};\n\ntemplate<typename T>\nstruct tTVPPreferenceInfo : public iTVPPreferenceInfo {\npublic:\n\ttTVPPreferenceInfo(const std::string &cap, const std::string &key, const T& defval)\n\t\t: iTVPPreferenceInfo(cap, key), DefaultValue(defval) {}\n\n\tT DefaultValue;\n\t// \tiTVPPreferenceInfo(const std::string &cap, const std::string &key, const std::string &defval)\n// \t\t: Caption(cap), Key(key), DefaultValue(defval), SubPrefScreen(nullptr) {}\n// \tiTVPPreferenceInfo(const std::string &cap, tPreferenceScreen* subscr = nullptr, bool hidden = false)\n// \t\t: Caption(cap), SubPrefScreen(subscr) {}\n// \t~iTVPPreferenceInfo() {\n// \t\tif (SubPrefScreen) delete SubPrefScreen;\n// \t}\n\n\tvirtual void InitDefaultConfig() {\n\t\tif (!Key.empty())\n\t\t\tGlobalConfigManager::GetInstance()->GetValue<T>(Key, DefaultValue);\n\t}\n\n//\ttPreferenceScreen *SubPrefScreen = nullptr; // eTypeSubPref\n};\n\nclass TVPPreferenceForm : public iTVPBaseForm {\nprotected:\n\tvoid initPref(const tPreferenceScreen *config);\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvirtual void bindHeaderController(const NodeMap &allNodes) override;\n\n\tconst tPreferenceScreen *Config = nullptr;\n\tcocos2d::ui::ListView *PrefList;\n\tcocos2d::ui::Button *_title;\n};\n\nclass iPreferenceItem : public cocos2d::ui::Widget {\npublic:\n\tvoid initFromInfo(int idx, cocos2d::Size size, const std::string& title); // not tid\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) = 0;\n\tvirtual const char *getUIFileName() const = 0;\n\tcocos2d::ui::Text *_title;\n\tcocos2d::Node *BgOdd, *BgEven;\n};\n\ntemplate<typename TArg>\nclass tPreferenceItem : public iPreferenceItem {\npublic:\n\ttypedef TArg ValueType;\n\tstd::function<TArg()> _getter;\n\tstd::function<void(TArg)> _setter;\n};\n\ntemplate<typename T> // factory function\nT* CreatePreferenceItem(int idx, const cocos2d::Size &size, const std::string &title, const std::function<void(T*)> &initer) {\n\tT *ret = new T;\n\tret->autorelease();\n\tiniter(ret);\n\tret->initFromInfo(idx, size, title);\n\treturn ret;\n}\n\ntemplate<typename T>\nT* CreatePreferenceItem(int idx, const cocos2d::Size &size, const std::string &title) {\n\tT *ret = new T;\n\tret->autorelease();\n\tret->initFromInfo(idx, size, title);\n\treturn ret;\n}\n\nclass tPreferenceItemCheckBox : public tPreferenceItem<bool> {\npublic:\n\ttPreferenceItemCheckBox();\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\tvirtual void onPressStateChangedToNormal() override;\n\tvirtual void onPressStateChangedToPressed() override;\n\tcocos2d::ui::CheckBox *checkbox;\n\tcocos2d::Node *highlight;\n};\n\nclass tPreferenceItemWithHighlight : public iPreferenceItem {\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\n\tvirtual void onPressStateChangedToNormal() override;\n\tvirtual void onPressStateChangedToPressed() override;\n\n\tcocos2d::Node *highlight = nullptr;\n};\n\nclass tPreferenceItemSubDir : public tPreferenceItemWithHighlight {\npublic:\n\ttPreferenceItemSubDir();\n\nprotected:\n\tvirtual const char* getUIFileName() const override;\n};\n\nclass tPreferenceItemConstant : public tPreferenceItemSubDir {\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n};\n\nclass tPreferenceItemSelectListInfo {\npublic:\n\tvirtual const std::vector<std::pair<std::string, std::string> >& getListInfo() = 0;\n};\n\nclass tPreferenceItemSelectList : public tPreferenceItem<std::string> {\npublic:\n\ttPreferenceItemSelectList();\n\n\tvoid initInfo(tPreferenceItemSelectListInfo* info) { CurInfo = info; }\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\n\tvirtual void onPressStateChangedToNormal() override;\n\tvirtual void onPressStateChangedToPressed() override;\n\n\tvoid showForm(cocos2d::Ref*);\n\tvoid updateHightlight();\n\n\tcocos2d::Node *highlight = nullptr;\n\tcocos2d::ui::Text *selected = nullptr;\n\ttPreferenceItemSelectListInfo* CurInfo;\n\tstd::string highlightTid;\n};\n\nclass tPreferenceItemFileSelect : public tPreferenceItem<std::string> {\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\n\tvirtual void onPressStateChangedToNormal() override;\n\tvirtual void onPressStateChangedToPressed() override;\n\n\tvoid showForm(cocos2d::Ref*);\n\tvoid updateHightlight();\n\n\tcocos2d::Node *highlight = nullptr;\n\tcocos2d::ui::Text *selected = nullptr;\n\tstd::string highlightTid;\n};\n\nclass tPreferenceItemKeyValPair : public tPreferenceItem<std::pair<std::string,std::string> > {\npublic:\n\ttPreferenceItemKeyValPair();\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\n\tvirtual void onPressStateChangedToNormal() override;\n\tvirtual void onPressStateChangedToPressed() override;\n\n\tvoid showInput(cocos2d::Ref*);\n\tvoid updateText();\n\n\tcocos2d::Node *highlight;\n\tcocos2d::ui::Text *selected;\n};\n\nclass TVPCustomPreferenceForm : public iTVPBaseForm {\npublic:\n\tstatic TVPCustomPreferenceForm *create(const std::string &tid_title, int count,\n\t\tconst std::function<std::pair<std::string, std::string>(int)> &getter,\n\t\tconst std::function<void(int, const std::pair<std::string, std::string>&)> &setter);\n\nprotected:\n\tvoid initFromInfo(const std::string &tid_title, int count,\n\t\tconst std::function<std::pair<std::string, std::string>(int)> &getter,\n\t\tconst std::function<void(int, const std::pair<std::string, std::string>&)> &setter);\n\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvirtual void bindHeaderController(const NodeMap &allNodes) override;\n\n\tstd::function<std::pair<std::string, std::string>(int)> _getter;\n\tstd::function<void(int, const std::pair<std::string, std::string>&)> _setter;\n\tcocos2d::ui::ListView *_listview;\n\tcocos2d::ui::Button *_title;\n};\n\nclass iPreferenceItemSlider : public tPreferenceItem<float> {\n\ttypedef tPreferenceItem<float> inherit;\n\npublic:\n\tiPreferenceItemSlider(float r) : _resetValue(r) {}\n\tvirtual void initController(const NodeMap &allNodes) override;\n\nprotected:\n\tcocos2d::ui::Slider* _slider;\n\tcocos2d::ui::Button *_reset;\n\tfloat _resetValue;\n};\n\nclass tPreferenceItemCursorSlider : public iPreferenceItemSlider {\n\ttypedef iPreferenceItemSlider inherit;\n\npublic:\n\ttPreferenceItemCursorSlider(float r, const std::function<float(float)> &f)\n\t\t: iPreferenceItemSlider(r), _curScaleConv(f) {}\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\n\tvirtual void onEnter() override;\n\n\tcocos2d::Node *_icon;\n\tcocos2d::Node *_cursor;\n\tstd::function<float(float)> _curScaleConv;\n};\n\nclass tPreferenceItemTextSlider : public iPreferenceItemSlider {\n\ttypedef iPreferenceItemSlider inherit;\n\npublic:\n\ttPreferenceItemTextSlider(float r, const std::function<std::string(float)> &f)\n\t\t: iPreferenceItemSlider(r), _strScaleConv(f) {}\n\nprotected:\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\n\tcocos2d::ui::Text *_text;\n\tstd::function<std::string(float)> _strScaleConv;\n};\n\nclass tPreferenceItemDeletable : public iPreferenceItem {\n\tvirtual void initController(const NodeMap &allNodes) override;\n\tvirtual const char* getUIFileName() const override;\n\tvoid onTouchEvent(cocos2d::Ref*, cocos2d::ui::Widget::TouchEventType);\n\tvoid walkTouchEvent(cocos2d::ui::Widget* node);\n\n\tcocos2d::ui::Widget *_deleteIcon;\n\tcocos2d::ui::ScrollView *_scrollview;\n\npublic:\n\tstd::function<void(tPreferenceItemDeletable*)> _onDelete;\n};\n\nclass tPreferenceItemKeyMap : public tPreferenceItemDeletable {\npublic:\n\tstd::pair<int, int> _keypair;\n\n\tvoid initData(int k, int v, int idx, const cocos2d::Size &size);\n};\n\nclass KeyMapPreferenceForm : public TVPPreferenceForm {\n\tiSysConfigManager* _mgr;\n\tKeyMapPreferenceForm(iSysConfigManager* mgr);\n\tvoid initData();\n\npublic:\n\tstatic KeyMapPreferenceForm* create(iSysConfigManager* mgr);\n};\n"
  },
  {
    "path": "src/core/environ/ui/SeletListForm.cpp",
    "content": "#include \"SeletListForm.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UIPageView.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UITextField.h\"\n#include \"platform/CCDevice.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"cocos2d/CCKeyCodeConv.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nconst char * const FileName_Body = \"ui/SelectList.csb\";\nconst char * const FileName_Cell = \"ui/SelectListItem.csb\";\n\nvoid iTVPHalfScreenForm::rearrangeLayout() {\n\tfloat scale = TVPMainScene::GetInstance()->getUIScale();\n\tSize sceneSize = TVPMainScene::GetInstance()->getUINodeSize();\n\tsceneSize.height *= 0.5f;\n\tsetContentSize(sceneSize);\n\tif (RootNode) {\n\t\tsceneSize.width /= scale;\n\t\tsceneSize.height /= scale;\n\t\tRootNode->setContentSize(sceneSize);\n\t\tui::Helper::doLayout(RootNode);\n\t\tRootNode->setScale(scale);\n    }\n}\n\nTVPSelectListForm * TVPSelectListForm::create(const std::vector<std::string> &info,\n\tconst std::string &highlight_tid, const std::function<void(int)> &funcok)\n{\n\tTVPSelectListForm *ret = new TVPSelectListForm();\n\tret->autorelease();\n\tret->FuncOK = funcok;\n\tret->initFromFile(nullptr, FileName_Body, nullptr);\n\tret->initWithInfo(info, highlight_tid);\n\treturn ret;\n}\n\nvoid TVPSelectListForm::bindBodyController(const NodeMap &allNodes) {\n\tNode *node = allNodes.findController(\"pageview\");\n\tSize nodesize = node->getContentSize();\n\tpageView = XKPageView::create(nodesize, nullptr);\n\tnode->addChild(pageView);\n\tpageView->setDirection(extension::ScrollView::Direction::VERTICAL);\n\tui::Button *btn = static_cast<ui::Button*>(allNodes.findController(\"ok\"));\n\tbtn->addClickEventListener([this](Ref*){\n\t\tFuncOK(pageView->getCurPageIndex());\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom);\n\t});\n\tbtn = static_cast<ui::Button*>(allNodes.findController(\"cancel\"));\n\tbtn->addClickEventListener([this](Ref*){\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom);\n\t});\n}\n\nvoid TVPSelectListForm::initWithInfo(const std::vector<std::string> &info, const std::string &highlight_tid) {\n\t//pageView->removeAllPages();\n\tSize size = pageView->getViewSize();\n\tbool size_set = false;\n\tint selectedIdx = 0;\n\tfor (int idx = 0; idx < info.size(); ++idx) {\n\t\tconst std::string &str = info[idx];\n\t\tCSBReader reader;\n\t\tWidget *cell = static_cast<Widget*>(reader.Load(FileName_Cell));\n\t\tif (!size_set) {\n\t\t\tsize.height = cell->getContentSize().height;\n\t\t\tpageView->setPageSize(size);\n\t\t\tsize_set = true;\n\t\t}\n\t\tText *text = static_cast<Text*>(reader.findController(\"text\"));\n\n\t\tNode *BgOdd = reader.findController(\"bg_odd\", false);\n\t\tNode *BgEven = reader.findController(\"bg_even\", false);\n\t\tif (BgOdd) BgOdd->setVisible((idx + 1) & 1);\n\t\tif (BgEven) BgEven->setVisible(idx & 1);\n\n\t\tcell->setContentSize(size);\n\t\tui::Helper::doLayout(cell);\n\t\tLocaleConfigManager::GetInstance()->initText(text, str);\n\t\t//text->addChild(LayerColor::create(cocos2d::Color4B(255, 255, 0, 255), text->getContentSize().width, text->getContentSize().height));\n\t\tLayout *lay = Layout::create();\n\t\tlay->setContentSize(size);\n\t\tlay->addChild(cell);\n\t\tif (str == highlight_tid) {\n\t\t\tselectedIdx = pageView->getPageCount();\n\t\t}\n\t\tpageView->addPage(lay);\n\t}\n\tpageView->setCurPageIndex(selectedIdx);\n}\n\nTVPTextPairInputForm * TVPTextPairInputForm::create(const std::string &text1, const std::string &text2,\n\tconst std::function<void(const std::string &, const std::string &)> &funcok) {\n\tTVPTextPairInputForm *ret = new TVPTextPairInputForm();\n\tret->autorelease();\n\tret->FuncOK = funcok;\n\tret->initFromFile(nullptr, \"ui/TextPairInput.csb\", nullptr);\n\tret->initWithInfo(text1, text2);\n\treturn ret;\n}\n\nvoid TVPTextPairInputForm::bindBodyController(const NodeMap &allNodes) {\n\tinput1 = static_cast<TextField*>(allNodes.findController(\"input1\"));\n\tinput2 = static_cast<TextField*>(allNodes.findController(\"input2\"));\n\n\tui::Button *btn = static_cast<ui::Button*>(allNodes.findController(\"ok\"));\n\tbtn->addClickEventListener([this](Ref*){\n\t\tFuncOK(input1->getString(), input2->getString());\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom);\n\t});\n\tbtn = static_cast<ui::Button*>(allNodes.findController(\"cancel\"));\n\tbtn->addClickEventListener([this](Ref*){\n\t\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom);\n\t});\n}\n\nvoid TVPTextPairInputForm::initWithInfo(const std::string &text1, const std::string &text2) {\n\tinput1->setString(text1);\n\tinput2->setString(text2);\n}\n\nTVPKeyPairSelectForm * TVPKeyPairSelectForm::create(const std::function<void(int)> &funcok)\n{\n\tTVPKeyPairSelectForm *ret = new TVPKeyPairSelectForm;\n\tret->autorelease();\n\tret->_funcok = funcok;\n\tret->initFromFile(FileName_Body);\n\tret->initWithInfo();\n\treturn ret;\n}\n\nTVPKeyPairSelectForm::~TVPKeyPairSelectForm()\n{\n\tif (_keylistener) {\n\t\t_eventDispatcher->removeEventListener(_keylistener);\n\t}\n}\n\nvoid TVPKeyPairSelectForm::initWithInfo()\n{\n\tFuncOK = [this](int idx) {\n\t\tauto &namemap = TVPGetVKCodeNameMap();\n\t\tauto it = namemap.find(_keyinfo[idx]);\n\t\tif (it == namemap.end()) {\n\t\t\treturn;\n\t\t}\n\t\t_funcok(it->second);\n\t};\n\tauto &namemap = TVPGetVKCodeNameMap();\n\t_keyinfo.clear();\n\t_keyinfo.reserve(namemap.size());\n\tfor (const auto &it : namemap) {\n\t\t_keyinfo.emplace_back(it.first);\n\t}\n\tinherit::initWithInfo(_keyinfo, \"0\");\n\t_keylistener = EventListenerKeyboard::create();\n\t_keylistener->onKeyPressed = CC_CALLBACK_2(TVPKeyPairSelectForm::onKeyPressed, this);\n\t_keylistener->onKeyReleased = CC_CALLBACK_2(TVPKeyPairSelectForm::onKeyReleased, this);\n\t_eventDispatcher->addEventListenerWithFixedPriority(_keylistener, 1);\n}\n\nvoid TVPKeyPairSelectForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event)\n{\n}\n\nvoid TVPKeyPairSelectForm::onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event)\n{\n\tunsigned int code = TVPConvertKeyCodeToVKCode(keyCode);\n\tif (!code || code >= 0x200) return;\n\n\t_funcok(code);\n}\n"
  },
  {
    "path": "src/core/environ/ui/SeletListForm.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n#include \"extension/UIExtension.h\"\n\nclass iTVPHalfScreenForm : public iTVPBaseForm {\npublic:\n\tvirtual void rearrangeLayout() override;\n};\n\nclass TVPSelectListForm : public iTVPHalfScreenForm {\npublic:\n\tstatic TVPSelectListForm *create(const std::vector<std::string> &info,\n\t\tconst std::string &highlight_tid, const std::function<void(int)> &funcok);\n\nprotected:\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvoid initWithInfo(const std::vector<std::string> &info, const std::string &highlight_tid);\n\n\tstd::function<void(int)> FuncOK;\n\n\tXKPageView *pageView;\n};\n\nclass TVPTextPairInputForm : public iTVPHalfScreenForm {\npublic:\n\tstatic TVPTextPairInputForm *create(const std::string &text1,\n\t\tconst std::string &text2, const std::function<void(const std::string &, const std::string &)> &funcok);\n\nprivate:\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tvoid initWithInfo(const std::string &text1, const std::string &text2);\n\n\tstd::function<void(const std::string &, const std::string &)> FuncOK;\n\n\tcocos2d::ui::TextField *input1, *input2;\n};\n\nclass TVPKeyPairSelectForm : public TVPSelectListForm {\n\ttypedef TVPSelectListForm inherit;\n\n\tcocos2d::EventListenerKeyboard* _keylistener = nullptr;\n\tstd::vector<std::string> _keyinfo;\n\tstd::function<void(int)> _funcok;\n\npublic:\n\tstatic TVPKeyPairSelectForm *create(const std::function<void(int/*keycode*/)> &funcok);\n\n\tvirtual ~TVPKeyPairSelectForm();\n\n\tvoid initWithInfo();\n\n\tvoid onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n\tvoid onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event);\n};"
  },
  {
    "path": "src/core/environ/ui/SimpleMediaFilePlayer.cpp",
    "content": "#include \"SimpleMediaFilePlayer.h\"\n#ifdef PixelFormat // libavcodec vs cocos2d\n#undef PixelFormat\n#endif\n#include \"cocos2d.h\"\n#include \"StorageIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UISlider.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"cocos/ui/UIHelper.h\"\n#include \"movie/ffmpeg/KRMoviePlayer.h\"\n#include \"StorageImpl.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\nvoid TVPControlAdDialog(int adType, int arg1, int arg2);\n\nclass SimplePlayerOverlay {\n\tKRMovie::VideoPresentOverlay2 *_overlay;\n\ttTVPRect _rect;\n\tconst tTVPRect &GetBounds() {\n\t\treturn _rect;\n\t}\npublic:\n\tSimplePlayerOverlay() {\n\t\t_overlay = KRMovie::VideoPresentOverlay2::create();\n\t\t_overlay->SetFuncGetBounds(std::bind(&SimplePlayerOverlay::GetBounds, this));\n\t}\n\t~SimplePlayerOverlay() {\n\t\t_overlay->Release();\n\t}\n\tvoid SetBounds(const tTVPRect& rect) { _rect = rect; }\n\tvoid OpenFromStream(IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size) {\n\t\t_overlay->GetPlayer()->OpenFromStream(stream, streamname, type, size);\n\t}\n\tvoid SetCallback(const std::function<void(KRMovieEvent, void*)>& func) {\n\t\t_overlay->GetPlayer()->SetCallback(func);\n\t}\n\tcocos2d::Node *GetRootNode() { return _overlay->GetRootNode(); }\n\tvoid InitRootNode(cocos2d::Node *parent) {\n\t\tcocos2d::Node *rootNode = cocos2d::Node::create();\n\t\t_overlay->SetRootNode(rootNode);\n\t\tparent->addChild(rootNode);\n\t\trootNode->setContentSize(cocos2d::Size::ZERO);\n\t\t_overlay->SetVisible(true);\n\t}\n\tKRMovie::VideoPresentOverlay2 &GetOverlay() { return *_overlay; }\n};\n\n// hh:mm:ss\nstatic std::string _formatTime(unsigned int t, char prefix = 0) {\n\tchar tmp[32];\n\ttmp[15] = 0;\n\tchar *p = &tmp[15];\n\n\tstatic const char numtbl[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };\n\n\t// second\n\t*--p = numtbl[t % 10]; t /= 10;\n\t*--p = numtbl[t % 6]; t /= 6;\n\t*--p = ':';\n\n\t// minute\n\t*--p = numtbl[t % 10]; t /= 10;\n\t*--p = numtbl[t % 6]; t /= 6;\n\t*--p = ':';\n\n\t// hour\n\tdo {\n\t\t*--p = numtbl[t % 10]; t /= 10;\n\t} while (t);\n\n\tif (prefix) *--p = prefix;\n\n\treturn p;\n}\n\nSimpleMediaFilePlayer::SimpleMediaFilePlayer()\n{\n\t_player = new SimplePlayerOverlay;\n\t_player->SetCallback(std::bind(&SimpleMediaFilePlayer::onPlayerEvent,\n\t\tthis, std::placeholders::_1, std::placeholders::_2));\n}\n\nSimpleMediaFilePlayer::~SimpleMediaFilePlayer()\n{\n\tif (_player) {\n\t\tdelete _player, _player = NULL;\n\t}\n\tTVPControlAdDialog(0x10002, 1, 0);\n}\n\nSimpleMediaFilePlayer * SimpleMediaFilePlayer::create()\n{\n\tSimpleMediaFilePlayer *ret = new SimpleMediaFilePlayer;\n\tret->autorelease();\n\tret->initFromFile(\n\t\t\"ui/MediaPlayerNavi.csb\",\n\t\t\"ui/MediaPlayerBody.csb\",\n\t\t\"ui/MediaPlayerFoot.csb\");\n\treturn ret;\n}\n\nvoid SimpleMediaFilePlayer::PlayFile(ttstr uri)\n{\n\tTVPControlAdDialog(0x10002, 0, 0);\n\ttTJSBinaryStream* stream = TVPCreateStream(uri, TJS_BS_READ);\n\tttstr ext = TVPExtractStorageExt(uri);\n\tttstr filename = TVPExtractStorageName(uri);\n\t_player->OpenFromStream(TVPCreateIStream(stream), uri.c_str(), ext.c_str(), stream->GetSize());\n\tint64_t totaltime;\n\t_player->GetOverlay().GetTotalTime(&totaltime);\n\t_totalTime = totaltime / 1000;\n\tTitle->setString(filename.AsStdString());\n\tPlayTime->setString(_formatTime(0));\n\tRemainTime->setString(_formatTime(_totalTime/*, '-'*/));\n\tlong w, h;\n\t_player->GetOverlay().GetVideoSize(&w, &h);\n\tSize size = Overlay->getContentSize();\n\tfloat scale = size.width / size.height;\n\tVec2 pos;\n\tif (float(w) / h > scale) {\n\t\tscale = size.width / w;\n\t\tpos.x = 0;\n\t\tpos.y = (size.height - h * scale) / 2;\n\t\tsize.height = h * scale;\n\t} else {\n\t\tscale = size.height / h;\n\t\tpos.x = (size.width - w * scale) / 2;\n\t\tpos.y = 0;\n\t\tsize.width = w * scale;\n\t}\n\t_player->SetBounds(tTVPRect(pos.x, pos.y, size.width, size.height));\n\n\tPlay();\n}\n\nvoid SimpleMediaFilePlayer::Play()\n{\n\thideRemain = 3;\n\tscheduleUpdate();\n\t_player->GetOverlay().Play();\n\trefreshPlayButtonStatus();\n}\n\nvoid SimpleMediaFilePlayer::onPlayerEvent(KRMovieEvent Msg, void* p)\n{\n\tswitch (Msg) {\n\tcase KRMovieEvent::Ended:\n\t\t_player->GetRootNode()->scheduleOnce([this](float dt) {\n\t\t\t//_player->Stop();\n\t\t\trefreshPlayButtonStatus();\n\t\t}, 0, \"onEnded\");\n \t\tbreak;\n\tdefault:\n\t\tbreak;\n \t}\n}\n\nvoid SimpleMediaFilePlayer::onSliderChanged()\n{\n\tif (_inupdate) return;\n\tfloat tscale = Timeline->getPercent() / 100;\n\tint curtime = _totalTime * tscale;\n\t_player->GetOverlay().SetPosition(curtime * 1000);\n\thideRemain = 4;\n\n\tOSD->setVisible(true);\n\tOSD->setOpacity(255);\n\tOSDText->setString(_formatTime(curtime));\n}\n\nvoid SimpleMediaFilePlayer::rearrangeLayout()\n{\n\tSize sceneSize = TVPMainScene::GetInstance()->getGameNodeSize();\n\tsetContentSize(sceneSize);\n\tRootNode->setContentSize(sceneSize);\n\tui::Helper::doLayout(RootNode);\n\n\tSize size = iTVPBaseForm::NaviBar.Root->getContentSize();\n\tfloat scale = sceneSize.width / size.width;\n\tiTVPBaseForm::NaviBar.Root->setAnchorPoint(Vec2(0, 1));\n\tiTVPBaseForm::NaviBar.Root->setScale(scale);\n\tiTVPBaseForm::NaviBar.Root->setPosition(Vec2(0, sceneSize.height));\n\n\tsize = BottomBar.Root->getContentSize();\n\tscale = sceneSize.width / size.width;\n\tBottomBar.Root->setScale(scale);\n}\n\nvoid SimpleMediaFilePlayer::bindBodyController(const NodeMap &allNodes)\n{\n\tOSD = allNodes.findController(\"OSD\");\n\tOSD->setVisible(false);\n\tOSDText = static_cast<Text*>(allNodes.findController(\"OSDText\"));\n\n\tWidget *overlay = allNodes.findWidget(\"Overlay\");\n\t_player->InitRootNode(overlay);\n\toverlay->addClickEventListener([this](Ref*) {\n\t\tif (!NaviBar->isVisible()) {\n\t\t\tNaviBar->setVisible(true);\n\t\t\tNaviBar->setOpacity(0);\n\t\t\tNaviBar->runAction(FadeIn::create(0.3));\n\n\t\t\tControlBar->setVisible(true);\n\t\t\tControlBar->setOpacity(0);\n\t\t\tControlBar->runAction(FadeIn::create(0.3));\n\t\t\thideRemain = 5;\n\t\t}\n\t});\n\tthis->Overlay = overlay;\n}\n\nvoid SimpleMediaFilePlayer::bindFooterController(const NodeMap &allNodes)\n{\n\tControlBar = allNodes.findController(\"ControlBar\");\n\n\tPlayBtn = allNodes.findWidget(\"PlayBtn\");\n\tPlayBtn->addClickEventListener([this](Ref*){\n\t\tTooglePlayOrPause();\n\t});\n\tPlayBtn->addTouchEventListener([this](Ref* _p, Widget::TouchEventType ev) {\n\t\tcocos2d::ui::Widget *p = static_cast<Widget*>(_p);\n\t\tswitch (ev) {\n\t\tcase Widget::TouchEventType::BEGAN:\n\t\t\tsetPlayButtonHighlight(true);\n\t\t\tbreak;\n\t\tcase Widget::TouchEventType::MOVED:\n\t\t\tsetPlayButtonHighlight(p->hitTest(p->getTouchMovePosition(), Camera::getVisitingCamera(), nullptr));\n\t\t\tbreak;\n\t\tcase Widget::TouchEventType::ENDED:\n\t\tcase Widget::TouchEventType::CANCELED:\n\t\t\tsetPlayButtonHighlight(false);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t});\n\tPlayBtnNormal = allNodes.findController(\"PlayBtnNormal\");\n\tPlayBtnPress = allNodes.findController(\"PlayBtnPress\");\n\tPlayIconNormal = allNodes.findController(\"PlayIconNormal\");\n\tPlayIconPress = allNodes.findController(\"PlayIconPress\");\n\tPauseIconNormal = allNodes.findController(\"PauseIconNormal\");\n\tPauseIconPress = allNodes.findController(\"PauseIconPress\");\n\tPlayBtnPress->setVisible(false);\n\tPlayIconPress->setVisible(false);\n\tPauseIconPress->setVisible(false);\n\t//PlayBtnNormal->setVisible(false);\n\t//PlayIconNormal->setVisible(false);\n\tPauseIconNormal->setVisible(false);\n}\n\nvoid SimpleMediaFilePlayer::bindHeaderController(const NodeMap &allNodes)\n{\n\tNaviBar = allNodes.findController(\"NaviBar\");\n\tcocos2d::ui::Button *Back = static_cast<Button*>(allNodes.findController(\"Back\"));\n\tBack->addClickEventListener([this](Ref*) {\n\t\tremoveFromParent();\n\t});\n\n\tTitle = static_cast<Text*>(allNodes.findController(\"Title\"));\n\tPlayTime = static_cast<Text*>(allNodes.findController(\"PlayTime\"));\n\tRemainTime = static_cast<Text*>(allNodes.findController(\"RemainTime\"));\n\tTimeline = static_cast<Slider*>(allNodes.findController(\"Timeline\"));\n\n\tTimeline->addEventListener([this](Ref*, Slider::EventType ev) {\n\t\tonSliderChanged();\n\t});\n}\n\nvoid SimpleMediaFilePlayer::Pause()\n{\n\t_player->GetOverlay().Pause();\n\tunscheduleUpdate();\n\trefreshPlayButtonStatus();\n}\n\nvoid SimpleMediaFilePlayer::TooglePlayOrPause()\n{\n\tif (_player->GetOverlay().IsPlaying()) {\n\t\tPause();\n\t} else {\n\t\tPlay();\n\t}\n}\n\nvoid SimpleMediaFilePlayer::update(float dt)\n{\n\t_inupdate = true;\n\tinherit::update(dt);\n\t_player->GetOverlay().PresentPicture(dt);\n\tuint64_t pos;\n\t_player->GetOverlay().GetPosition(&pos);\n\tint playtime = pos / 1000;\n\n\tfloat ratio = float(pos) / _totalTime / 1000;\n\tTimeline->setPercent(ratio * 100);\n\n\tPlayTime->setString(_formatTime(playtime));\n\t//RemainTime->setString(_formatTime(_totalTime - playtime, '-'));\n\n\tif (NaviBar->isVisible() && hideRemain > 0) {\n\t\thideRemain -= dt;\n\t\tif (hideRemain <= 0) {\n\t\t\tNaviBar->runAction(Sequence::createWithTwoActions(\n\t\t\t\tFadeOut::create(0.3),\n\t\t\t\tCallFuncN::create([](Node* p){\n\t\t\t\tp->setVisible(false);\n\t\t\t})));\n\t\t\tControlBar->runAction(Sequence::createWithTwoActions(\n\t\t\t\tFadeOut::create(0.3),\n\t\t\t\tCallFuncN::create([](Node* p){\n\t\t\t\tp->setVisible(false);\n\t\t\t})));\n\t\t\tif (OSD->isVisible()) {\n\t\t\t\tOSD->runAction(Sequence::createWithTwoActions(\n\t\t\t\t\tFadeOut::create(0.3),\n\t\t\t\t\tCallFuncN::create([](Node* p){\n\t\t\t\t\tp->setVisible(false);\n\t\t\t\t})));\n\t\t\t}\n\t\t\thideRemain = 5;\n\t\t}\n\n// \t\tif (OSD->isVisible()) {\n// \t\t\tOSD->runAction(Sequence::create(DelayTime::FadeOut::create(1))\n// \t\t\t\t;\n// \t\t} else if (NaviBar->isVisible()) {\n// \t\t\tNaviBar->\n// \t\t\tinProcAction = true;\n// \t\t}\n\t}\n\t_inupdate = false;\n}\n\nvoid SimpleMediaFilePlayer::setPlayButtonHighlight(bool highlight)\n{\n\ttTVPVideoStatus status;\n\t_player->GetOverlay().GetStatus(&status);\n\tif (highlight) {\n\t\tPlayBtnNormal->setVisible(false);\n\t\tPlayIconNormal->setVisible(false);\n\t\tPauseIconNormal->setVisible(false);\n\t\tPlayBtnPress->setVisible(true);\n\t\t(status == vsPlaying ? PauseIconPress : PlayIconPress)->setVisible(true);\n\t} else {\n\t\tPlayBtnPress->setVisible(false);\n\t\tPlayIconPress->setVisible(false);\n\t\tPauseIconPress->setVisible(false);\n\t\tPlayBtnNormal->setVisible(true);\n\t\t(status == vsPlaying ? PauseIconNormal : PlayIconNormal)->setVisible(true);\n\t}\n}\n\nvoid SimpleMediaFilePlayer::refreshPlayButtonStatus()\n{\n\ttTVPVideoStatus status;\n\t_player->GetOverlay().GetStatus(&status);\n\tif (PlayBtnPress->isVisible()) { // highlight\n\t\tPlayIconPress->setVisible(false);\n\t\tPauseIconPress->setVisible(false);\n\t\t(status == vsPlaying ? PauseIconPress : PlayIconPress)->setVisible(true);\n\t} else {\n\t\tPlayIconNormal->setVisible(false);\n\t\tPauseIconNormal->setVisible(false);\n\t\t(status == vsPlaying ? PauseIconNormal : PlayIconNormal)->setVisible(true);\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/ui/SimpleMediaFilePlayer.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n#include \"tjsCommHead.h\"\n#include \"movie/ffmpeg/VideoPlayer.h\"\n\nnamespace cocos2d {\n\tclass Sprite;\n}\n\nclass SimplePlayerOverlay;\n\nclass SimpleMediaFilePlayer : public iTVPBaseForm {\n\ttypedef cocos2d::Node inherit;\n\npublic:\n\tvirtual ~SimpleMediaFilePlayer();\n\tstatic SimpleMediaFilePlayer *create();\n\n\tvoid PlayFile(ttstr uri);\n\n\tvoid Play();\n\tvoid Pause();\n\tvoid TooglePlayOrPause();\n\nprivate:\n\tSimpleMediaFilePlayer();\n\tvoid onPlayerEvent(KRMovieEvent Msg, void* p);\n\tvoid onSliderChanged();\n\tvirtual void rearrangeLayout() override;\n\tvirtual void bindBodyController(const NodeMap &allNodes);\n\tvirtual void bindFooterController(const NodeMap &allNodes);\n\tvirtual void bindHeaderController(const NodeMap &allNodes);\n\n\tvirtual void update(float dt) override;\n\n\tSimplePlayerOverlay *_player;\n\tint _totalTime; // in sec\n\tfloat hideRemain = 0;\n\tbool _inupdate = false;\n\n\t// ui controllers\n\tcocos2d::ui::Text *Title, *PlayTime, *RemainTime, *OSDText;\n\tcocos2d::ui::Slider *Timeline;\n\tcocos2d::Node *NaviBar, *ControlBar, *OSD, *Overlay;\n\tcocos2d::ui::Widget *PlayBtn;\n\tcocos2d::Node *PlayBtnNormal, *PlayBtnPress, *PlayIconNormal, *PlayIconPress, *PauseIconNormal, *PauseIconPress;\n\tvoid setPlayButtonHighlight(bool highlight);\n\tvoid refreshPlayButtonStatus();\n};\n"
  },
  {
    "path": "src/core/environ/ui/TipsHelpForm.cpp",
    "content": "#include \"TipsHelpForm.h\"\n#include \"ui/UIHelper.h\"\n#include \"ui/UIListView.h\"\n#include \"cocos2d/MainScene.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\n\nTVPTipsHelpForm* TVPTipsHelpForm::create() {\n\tTVPTipsHelpForm *ret = new TVPTipsHelpForm;\n\tret->initFromFile(nullptr, \"ui/help/AllTips.csb\", nullptr);\n\tret->autorelease();\n\treturn ret;\n}\n\nTVPTipsHelpForm* TVPTipsHelpForm::show(const char *tipName) {\n\tTVPTipsHelpForm *ui = create();\n\tif (tipName) ui->setOneTip(tipName);\n\tTVPMainScene::GetInstance()->pushUIForm(ui, TVPMainScene::eEnterAniOverFromRight);\n\treturn ui;\n}\n\nvoid TVPTipsHelpForm::setOneTip(const std::string &tipName) {\n\tauto &allCell = _tipslist->getItems();\n\tint cellCount = allCell.size();\n\twhile (!_tipslist->getItems().empty()) {\n\t\tNode *cell = _tipslist->getItem(_tipslist->getItems().size() - 1);\n\t\tif (cell->getName() == tipName) {\n\t\t\tbreak;\n\t\t} else {\n\t\t\t_tipslist->removeLastItem();\n\t\t}\n\t}\n\twhile (!_tipslist->getItems().empty()) {\n\t\tNode *cell = _tipslist->getItem(0);\n\t\tif (cell->getName() == tipName) {\n\t\t\tbreak;\n\t\t} else {\n\t\t\t_tipslist->removeItem(0);\n\t\t}\n\t}\n}\n\nvoid TVPTipsHelpForm::rearrangeLayout() {\n\tSize sceneSize = TVPMainScene::GetInstance()->getUINodeSize();\n\tSize rootSize = RootNode->getContentSize();\n\tfloat scale = sceneSize.width / rootSize.width;\n\trootSize.height = rootSize.width * sceneSize.height / sceneSize.width;\n\tsetContentSize(rootSize);\n\tsetScale(scale);\n\tRootNode->setContentSize(rootSize);\n\tui::Helper::doLayout(RootNode);\n}\n\nvoid TVPTipsHelpForm::bindBodyController(const NodeMap &allNodes) {\n\t_tipslist = dynamic_cast<ListView*>(allNodes.findController(\"tipslist\"));\n\tWidget *btn_close = allNodes.findWidget(\"btn_close\");\n\tbtn_close->addClickEventListener([this](Ref* p){\n\t\tstatic_cast<Widget*>(p)->setEnabled(false);\n\t\tTVPMainScene::GetInstance()->popUIForm(this);\n\t});\n\tWidget *nullcell = new Widget();\n\tnullcell->setContentSize(Size(_tipslist->getContentSize().width, 200));\n\t_tipslist->pushBackCustomItem(nullcell);\n}\n\n"
  },
  {
    "path": "src/core/environ/ui/TipsHelpForm.h",
    "content": "#pragma once\n#include \"BaseForm.h\"\n\nclass TVPTipsHelpForm : public iTVPBaseForm {\n\tvirtual void bindBodyController(const NodeMap &allNodes) override;\n\tcocos2d::ui::ListView *_tipslist;\n\npublic:\n\tstatic TVPTipsHelpForm* create();\n\tstatic TVPTipsHelpForm* show(const char *tipName = nullptr);\n\n\tvoid setOneTip(const std::string &tipName);\n\tvirtual void rearrangeLayout() override;\n};"
  },
  {
    "path": "src/core/environ/ui/XP3RepackForm.cpp",
    "content": "#include \"XP3RepackForm.h\"\n#include \"StorageImpl.h\"\n#include \"cocos2d/MainScene.h\"\n#include \"PreferenceForm.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"XP3ArchiveRepack.h\"\n#include \"ui/UIListView.h\"\n#include \"ui/UILoadingBar.h\"\n#include \"ui/UIText.h\"\n#include \"ui/UIButton.h\"\n#include \"ui/UICheckBox.h\"\n#include \"Platform.h\"\n#include \"MessageBox.h\"\n#include \"base/CCDirector.h\"\n#include \"base/CCScheduler.h\"\n#include \"TickCount.h\"\n#include \"2d/CCLayer.h\"\n#include \"2d/CCActionInterval.h\"\n#include \"platform/CCFileUtils.h\"\n#include \"platform/CCDevice.h\"\n\nusing namespace cocos2d;\nusing namespace cocos2d::ui;\nbool TVPGetXP3ArchiveOffset(tTJSBinaryStream *st, const ttstr name, tjs_uint64 & offset, bool raise);\n\nstatic void WalkDir(const ttstr &dir, const std::function<void(const ttstr&, tjs_uint64)>& cb) {\n\tstd::vector<ttstr> subdirs;\n\tstd::vector<std::pair<std::string, tjs_uint64> > files;\n\tTVPGetLocalFileListAt(dir, [&](const ttstr& path, tTVPLocalFileInfo* info) {\n\t\tif (info->Mode & S_IFDIR) {\n\t\t\tsubdirs.emplace_back(path);\n\t\t} else {\n\t\t\tfiles.emplace_back(info->NativeName, info->Size);\n\t\t}\n\t});\n\tttstr prefix = dir + TJS_W(\"/\");\n\n\tfor (std::pair<std::string, tjs_uint64> &it : files) {\n\t\tcb(prefix + it.first, it.second);\n\t}\n\tfor (ttstr &path : subdirs) {\n\t\tWalkDir(prefix + path, cb);\n\t}\n}\n\nclass TVPXP3Repacker {\n\tconst int UpdateMS = 100; // update rate 10 fps\npublic:\n\tTVPXP3Repacker(const std::string &rootdir) : RootDir(rootdir) {}\n\t~TVPXP3Repacker();\n\tvoid Start(std::vector<std::string> &filelist, const std::string &xp3filter);\n\tvoid SetOption(const std::string &name, bool v) {\n\t\tArcRepacker.SetOption(name, v);\n\t}\n\nprivate:\n\tvoid OnNewFile(int idx, uint64_t size, const std::string &filename);\n\tvoid OnNewArchive(int idx, uint64_t size, const std::string &filename);\n\tvoid OnProgress(uint64_t total_size, uint64_t arc_size, uint64_t file_size);\n\tvoid OnError(int errcode, const std::string &errmsg);\n\tvoid OnEnded();\n\n\tTVPSimpleProgressForm *ProgressForm = nullptr;\n\tXP3ArchiveRepackAsync ArcRepacker;\n\n\tstd::string RootDir;\n\tstd::string CurrentFileName, CurrentArcName;\n\tuint64_t TotalSize, CurrentFileSize, CurrentArcSize;\n\tint CurrentFileIndex;\n\ttjs_uint32 LastUpdate = 0;\n};\n\nTVPXP3Repacker::~TVPXP3Repacker()\n{\n\tif (ProgressForm) {\n\t\tTVPMainScene::GetInstance()->popUIForm(ProgressForm, TVPMainScene::eLeaveAniNone);\n\t\tProgressForm = nullptr;\n\t}\n\tcocos2d::Device::setKeepScreenOn(false);\n}\n\nvoid TVPXP3Repacker::Start(std::vector<std::string> &filelist, const std::string &xp3filter)\n{\n\tif (!ProgressForm) {\n\t\tProgressForm = TVPSimpleProgressForm::create();\n\t\tTVPMainScene::GetInstance()->pushUIForm(ProgressForm, TVPMainScene::eEnterAniNone);\n\t\tstd::vector<std::pair<std::string, std::function<void(cocos2d::Ref*)> > > vecButtons;\n\t\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\t\tvecButtons.emplace_back(locmgr->GetText(\"stop\"), [this](Ref*) {\n\t\t\tArcRepacker.Stop();\n\t\t});\n\t\tProgressForm->initButtons(vecButtons);\n\t\tProgressForm->setTitle(locmgr->GetText(\"archive_repack_proc_title\"));\n\t\tProgressForm->setPercentOnly(0);\n\t\tProgressForm->setPercentOnly2(0);\n\t\tProgressForm->setPercentText(\"\");\n\t\tProgressForm->setPercentText2(\"\");\n\t\tProgressForm->setContent(\"\");\n\t}\n\tArcRepacker.SetCallback(\n\t\tstd::bind(&TVPXP3Repacker::OnNewFile, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),\n\t\tstd::bind(&TVPXP3Repacker::OnNewArchive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),\n\t\tstd::bind(&TVPXP3Repacker::OnProgress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),\n\t\tstd::bind(&TVPXP3Repacker::OnError, this, std::placeholders::_1, std::placeholders::_2),\n\t\tstd::bind(&TVPXP3Repacker::OnEnded, this));\n\tif (cocos2d::FileUtils::getInstance()->isFileExist(xp3filter)) {\n\t\tArcRepacker.SetXP3Filter(xp3filter);\n\t}\n\tTotalSize = 0;\n\tfor (const std::string &name : filelist) {\n\t\tTotalSize += ArcRepacker.AddTask(name);\n\t}\n\tcocos2d::Device::setKeepScreenOn(true);\n\tArcRepacker.Start();\n}\n\nvoid TVPXP3Repacker::OnNewFile(int idx, uint64_t size, const std::string &filename)\n{\n\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\tif ((int)(tick - LastUpdate) < UpdateMS && size < 1024 * 1024) {\n\t\treturn;\n\t}\n\tCurrentFileIndex = idx;\n\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, size, filename] {\n\t\tCurrentFileSize = size;\n\t\tProgressForm->setContent(CurrentArcName + \">\" + filename);\n\t});\n}\n\nvoid TVPXP3Repacker::OnNewArchive(int idx, uint64_t size, const std::string &filename)\n{\n\tint prefixlen = RootDir.length() + 1;\n\tstd::string name = filename.substr(prefixlen);\n\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, name, size] {\n\t\tCurrentArcSize = size;\n\t\tCurrentArcName = name;\n\t});\n}\n\nvoid TVPXP3Repacker::OnProgress(uint64_t total_size, uint64_t arc_size, uint64_t file_size)\n{\n\ttjs_uint32 tick = TVPGetRoughTickCount32();\n\tif ((int)(tick - LastUpdate) < UpdateMS) {\n\t\treturn;\n\t}\n\n\tLastUpdate = tick;\n\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, total_size, arc_size] {\n\t\tProgressForm->setPercentOnly2((float)total_size / TotalSize);\n\t\tProgressForm->setPercentOnly((float)arc_size / CurrentArcSize);\n\t\tchar buf[64];\n\t\tint sizeMB = static_cast<int>(total_size / (1024 * 1024)),\n\t\t\ttotalMB = static_cast<int>(TotalSize / (1024 * 1024));\n\t\tsprintf(buf, \"%d / %dMB\", sizeMB, totalMB);\n\t\tProgressForm->setPercentText2(buf);\n\t\tsizeMB = static_cast<int>(arc_size / (1024 * 1024));\n\t\ttotalMB = static_cast<int>(CurrentArcSize / (1024 * 1024));\n\t\tsprintf(buf, \"%d / %dMB\", sizeMB, totalMB);\n\t\tProgressForm->setPercentText(buf);\n\t});\n}\n\nvoid TVPXP3Repacker::OnError(int errcode, const std::string &errmsg)\n{\n\tif (errcode < 0) {\n\t\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this, errcode, errmsg] {\n\t\t\tchar buf[64];\n\t\t\tsprintf(buf, \"Error %d\\n\", errcode);\n\t\t\tttstr strmsg(buf);\n\t\t\tstrmsg += errmsg;\n\t\t\tTVPShowSimpleMessageBox(strmsg, TJS_W(\"XP3Repack Error\"));\n\t\t});\n\t}\n}\n\nvoid TVPXP3Repacker::OnEnded()\n{\n\tDirector::getInstance()->getScheduler()->performFunctionInCocosThread([this] {\n\t\tdelete this;\n\t});\n}\n\nclass TVPXP3RepackFileListForm : public iTVPBaseForm {\npublic:\n\tvirtual ~TVPXP3RepackFileListForm();\n\tvirtual void bindBodyController(const NodeMap &allNodes);\n\tstatic TVPXP3RepackFileListForm* show(std::vector<std::string> &filelist, const std::string &dir);\n\tvoid initData(std::vector<std::string> &filelist, const std::string &dir);\n\tvoid close();\n\nprivate:\n\tvoid onOkClicked(Ref*);\n\n\tcocos2d::ui::ListView *ListViewFiles, *ListViewPref;\n\n\tstd::string RootDir;\n\tstd::vector<std::string> FileList;\n\n\tTVPXP3Repacker *m_pRepacker = nullptr;\n};\n\nTVPXP3RepackFileListForm::~TVPXP3RepackFileListForm()\n{\n\tif (m_pRepacker)\n\t\tdelete m_pRepacker;\n}\n\nvoid TVPXP3RepackFileListForm::bindBodyController(const NodeMap &allNodes)\n{\n\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\tui::ScrollView *btnList = allNodes.findController<ui::ScrollView>(\"btn_list\");\n\tSize containerSize = btnList->getContentSize();\n\tbtnList->setInnerContainerSize(containerSize);\n\tWidget *btnCell = allNodes.findWidget(\"btn_cell\");\n\tButton *btn = allNodes.findController<Button>(\"btn\");\n\tint nButton = 2;\n\n\tlocmgr->initText(allNodes.findController<Text>(\"title\"), \"XP3 Repack\");\n\n\tbtn->setTitleText(locmgr->GetText(\"start\"));\n\tbtn->addClickEventListener(std::bind(&TVPXP3RepackFileListForm::onOkClicked, this, std::placeholders::_1));\n\tbtnCell->setPositionX(containerSize.width / (nButton + 1) * 1);\n\tbtnList->addChild(btnCell->clone());\n\n\tbtn->setTitleText(locmgr->GetText(\"cancel\"));\n\tbtn->addClickEventListener([this](Ref*) { close(); });\n\tbtnCell->setPositionX(containerSize.width / (nButton + 1) * 2);\n\tbtnList->addChild(btnCell->clone());\n\n\tbtn->removeFromParent();\n\n\tListViewFiles = allNodes.findController<ListView>(\"list_2\");\n\tListViewPref = allNodes.findController<ListView>(\"list_1\");\n}\n\nTVPXP3RepackFileListForm* TVPXP3RepackFileListForm::show(std::vector<std::string> &filelist, const std::string &dir)\n{\n\tTVPXP3RepackFileListForm *form = new TVPXP3RepackFileListForm;\n\tform->initFromFile(\"ui/CheckListDialog.csb\");\n\tform->initData(filelist, dir);\n\tTVPMainScene::GetInstance()->pushUIForm(form, TVPMainScene::eEnterAniNone);\n\treturn form;\n}\n\nvoid TVPXP3RepackFileListForm::initData(std::vector<std::string> &filelist, const std::string &dir)\n{\n\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\n\tRootDir = dir;\n\tFileList.swap(filelist);\n\tint tag = 256;\n\tSize size = ListViewFiles->getContentSize();\n\tint prefixlen = dir.length() + 1;\n\tfor (size_t i = 0; i < FileList.size(); ++i) {\n\t\tstd::string filename = FileList[i].substr(prefixlen);\n\t\ttPreferenceItemCheckBox *cell = CreatePreferenceItem<tPreferenceItemCheckBox>(i, size, filename,\n\t\t\t[](tPreferenceItemCheckBox* p) {\n\t\t\tp->_getter = []()->bool { return true; };\n\t\t\tp->_setter = [](bool v) {};\n\t\t});\n\t\tcell->setTag(tag++);\n\t\tListViewFiles->pushBackCustomItem(cell);\n\t}\n\n\tm_pRepacker = new TVPXP3Repacker(RootDir);\n\n\tsize = ListViewPref->getContentSize();\n\tListViewPref->pushBackCustomItem(CreatePreferenceItem\n\t\t<tPreferenceItemConstant>(0, size, locmgr->GetText(\"archive_repack_desc\")));\n\n\tListViewPref->pushBackCustomItem(CreatePreferenceItem\n\t\t<tPreferenceItemCheckBox>(1, size, locmgr->GetText(\"archive_repack_merge_img\"),\n\t\t\t[this](tPreferenceItemCheckBox* p) {\n\t\tp->_getter = []()->bool { return true; };\n\t\tp->_setter = [this](bool v) { m_pRepacker->SetOption(\"merge_mask_img\", v); };\n\t}));\n\n\tListViewPref->pushBackCustomItem(CreatePreferenceItem\n\t\t<tPreferenceItemCheckBox>(2, size, locmgr->GetText(\"archive_repack_conv_etc2\"),\n\t\t\t[this](tPreferenceItemCheckBox* p) {\n\t\tp->_getter = []()->bool { return false; };\n\t\tp->_setter = [this](bool v) { m_pRepacker->SetOption(\"conv_etc2\", v); };\n\t}));\n}\n\nvoid TVPXP3RepackFileListForm::close()\n{\n//\tTVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniNone);\n\tremoveFromParent();\n}\n\nvoid TVPXP3RepackFileListForm::onOkClicked(Ref*)\n{\n\tclass HackPreferenceItemCheckBox : public tPreferenceItemCheckBox {\n\tpublic:\n\t\tbool getCheckBoxState() {\n\t\t\treturn checkbox->isSelected();\n\t\t}\n\t};\n\tstd::vector<std::string> filelist; filelist.reserve(FileList.size());\n\tauto &allCell = ListViewFiles->getItems();\n\tfor (int i = 0; i < allCell.size(); ++i) {\n\t\tWidget *cell = allCell.at(i);\n\t\tif (static_cast<HackPreferenceItemCheckBox*>(cell)->getCheckBoxState()) {\n\t\t\tfilelist.push_back(FileList[cell->getTag() - 256]);\n\t\t}\n\t}\n\tif (filelist.empty())\n\t\treturn;\n\tm_pRepacker->Start(filelist, RootDir + \"/xp3filter.tjs\");\n\tm_pRepacker = nullptr;\n\tclose();\n}\n\nvoid TVPProcessXP3Repack(const std::string &dir)\n{\n\tstd::vector<std::string> filelist;\n\tbool hasXp3Filter = false;\n\tTVPGetLocalFileListAt(dir, [&](const ttstr& path, tTVPLocalFileInfo* info) {\n\t\tif (info->Mode & S_IFDIR) {\n\t\t} else if(path == TJS_W(\"xp3filter.tjs\")) {\n\t\t\thasXp3Filter = true;\n\t\t}\n\t});\n\tLocaleConfigManager *locmgr = LocaleConfigManager::GetInstance();\n\tif (!hasXp3Filter) {\n\t\tif (TVPShowSimpleMessageBoxYesNo(locmgr->GetText(\"archive_repack_no_xp3filter\"), locmgr->GetText(\"notice\")) != 0) {\n\t\t\treturn;\n\t\t}\n\t}\n\tWalkDir(dir, [&](const ttstr& strpath, tjs_uint64 size) {\n\t\tif (size < 32) return;\n\t\ttjs_uint64 offset;\n\t\ttTVPLocalFileStream *st = new tTVPLocalFileStream(strpath, strpath, TJS_BS_READ);\n\t\tif (TVPGetXP3ArchiveOffset(st, strpath, offset, false)) {\n\t\t\tfilelist.emplace_back(strpath.AsStdString());\n\t\t}\n\t\tdelete st;\n\t});\n\tif (filelist.empty()) {\n\t\tTVPShowSimpleMessageBox(locmgr->GetText(\"archive_repack_no_xp3\").c_str(), \"XP3Repack\", 0, nullptr);\n\t} else {\n\t\tTVPXP3RepackFileListForm::show(filelist, dir);\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/ui/XP3RepackForm.h",
    "content": "#pragma once\n#include <string>\n\nvoid TVPProcessXP3Repack(const std::string &dir);\n"
  },
  {
    "path": "src/core/environ/ui/extension/ActionExtension.cpp",
    "content": "#pragma once\n#include \"cocos2d.h\"\n#include \"cocos-ext.h\"\n\n"
  },
  {
    "path": "src/core/environ/ui/extension/ActionExtension.h",
    "content": "#pragma once\n#include \"cocos2d.h\"\n#include \"cocos-ext.h\"\n\n"
  },
  {
    "path": "src/core/environ/ui/extension/UIExtension.cpp",
    "content": "#include \"UIExtension.h\"\n#include \"base/ObjectFactory.h\"\n#include \"ui/UIWidget.h\"\n#include \"cocostudio/ActionTimeline/CSLoader.h\"\n#include \"cocostudio/WidgetReader/NodeReader/NodeReader.h\"\n#include \"base/CCEventDispatcher.h\"\n\nUSING_NS_CC;\nusing namespace cocos2d::ui;\n\n#define XKPAGEVIEW_TAG 10086\n\nXKPageView *XKPageView::create(Size size, XKPageViewDelegate *delegate)\n{\n\tXKPageView *page  = new XKPageView();\n\tif (page && page -> init(size, delegate)) {\n\t\tpage ->autorelease();\n\t}else {\n\t\tCC_SAFE_RELEASE(page);\n\t}\n\treturn  page;\n}\n\nbool XKPageView::init(Size size, XKPageViewDelegate *delegate)\n{\n\tif (!ScrollView::initWithViewSize(size)) {\n\t\treturn false;\n\t}\n\t//delegateϵ  \n\t//CCASSERT(delegate, \"delegate should not be NULL!\");\n\tsetClippingToBounds(false);\n\tsetDelegate(delegate);\n\tif (_delegate) {\n\t\t//ȡpageĴС  \n\t\tpageSize  = _delegate ->sizeForPerPage();\n\t}\n\t//init Data  \n\tpageCount  = 0;\n\tcurrent_index  = 0;\n\n\treturn true;\n}\n\n\nvoid XKPageView::adjust(float offset)\n{\n\tVec2 vec;\n\tfloat xOrY;\n\tconst Size &size = getViewSize();\n\tif (_direction == ScrollView::Direction::HORIZONTAL) {\n\t\tvec = Vec2((size.width - pageSize.width) / 2 - current_index * pageSize.width, 0);\n\t\txOrY  = pageSize.width;\n\t}else {\n\t\tvec = Vec2(0, (size.height - pageSize.height) / 2 - current_index * pageSize.height);\n\t\txOrY  = pageSize.height;\n\t}\n\n\tif (std::abs(offset) < xOrY / 2){\n\t\tthis->setContentOffsetInDuration(vec, 0.1f);\n\t\treturn;\n\t}\n\n\tint i  = std::abs(offset  / xOrY) + 1;\n\tif (offset  < 0) {\n\t\tcurrent_index += i;\n\t\tif (current_index >= pageCount){\n\t\t\tcurrent_index = pageCount - 1;\n\t\t}\n\t}else {\n\t\tcurrent_index  -= i;\n\t\tif (current_index < 0) {\n\t\t\tcurrent_index = 0;\n\t\t}\n\t}\n\n\tif (_direction  == ScrollView::Direction::HORIZONTAL) {\n\t\tvec = Vec2((size.width - pageSize.width) / 2 - current_index * pageSize.width, 0);\n\t}else {\n\t\tvec = Vec2(0, (size.height - pageSize.height) / 2 - current_index * pageSize.height);\n\t}\n\n\tthis ->setContentOffsetInDuration(vec, 0.15f);\n}\n\nvoid XKPageView::setContentOffset(Vec2 offset)\n{\n\tScrollView::setContentOffset(offset);\n\tif (_delegate  != nullptr)\n\t{\n\t\t_delegate ->pageViewDidScroll(this);\n\t}\n}\n\nvoid XKPageView::setContentOffsetInDuration(Vec2 offset, float dt)\n{\n\tScrollView::setContentOffsetInDuration(offset, dt);\n\tthis->schedule(CC_SCHEDULE_SELECTOR(XKPageView::performedAnimatedScroll));\n}\n\nvoid XKPageView::performedAnimatedScroll(float dt)\n{\n\tif (_dragging)\n\t{\n\t\tthis->unschedule(CC_SCHEDULE_SELECTOR(XKPageView::performedAnimatedScroll));\n\t\treturn;\n\t}\n\n\tif (_delegate  != nullptr)\n\t{\n\t\t_delegate ->pageViewDidScroll(this);\n\t}\n}\n\nvoid XKPageView::addPage(Node *node)\n{\n\tif (_direction  == ScrollView::Direction::HORIZONTAL) {\n\t\tnode ->setPosition(Point(pageCount * pageSize.width  + node ->getPositionX(), node ->getPositionY()));\n\t\tthis ->setContentSize(Size((pageCount  + 1) * pageSize.width, pageSize.height));\n\t}else {\n\t\tnode ->setPosition(Point(node ->getPositionX(), pageCount * pageSize.height  + node ->getPositionY()));\n\t\tthis ->setContentSize(Size(pageSize.width, (pageCount  + 1) *pageSize.height));\n\t}\n\tnode ->setTag(pageCount  + XKPAGEVIEW_TAG);\n\t_container ->addChild(node);\n\tpageCount ++;\n\n}\n\nNode *XKPageView::getPageAtIndex(int index)\n{\n\tif (index  < pageCount && index  >= 0) {\n\t\treturn _container ->getChildByTag(index  + XKPAGEVIEW_TAG);\n\t}\n\treturn  NULL;\n}\n\nvoid XKPageView::setTouchEnabled(bool enabled) {\n\t_eventDispatcher->removeEventListener(_touchListener);\n\t_touchListener = nullptr;\n\n\tif (enabled)\n\t{\n\t\t_touchListener = EventListenerTouchOneByOne::create();\n\t\t_touchListener->onTouchBegan = CC_CALLBACK_2(XKPageView::onTouchBegan, this);\n\t\t_touchListener->onTouchMoved = CC_CALLBACK_2(XKPageView::onTouchMoved, this);\n\t\t_touchListener->onTouchEnded = CC_CALLBACK_2(XKPageView::onTouchEnded, this);\n\t\t_touchListener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this);\n\n\t\t_eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this);\n\t} else\n\t{\n\t\t_dragging = false;\n\t\t_touchMoved = false;\n\t\t_touches.clear();\n\t}\n}\n\nbool XKPageView::onTouchBegan(Touch *touch, Event *unusedEvent) {\n\tif (!this->isVisible() || !this->hasVisibleParents())\n\t{\n\t\treturn false;\n\t}\n\n\tRect frame = getViewRect();\n\n\t//dispatcher does not know about clipping. reject touches outside visible bounds.\n\tVec2 nsp = convertToNodeSpace(touch->getLocation());\n\tRect bb;\n\tbb.size = _contentSize;\n\n\tif (_touches.size() > 1 ||\n\t\t_touchMoved ||\n\t\t!bb.containsPoint(nsp))\n\t{\n\t\treturn false;\n\t}\n\n\t_touches.push_back(touch);\n\n\t_touchPoint = nsp;\n\t_dragging = true; //dragging started\n\t_scrollDistance.setZero();\n\t_touchLength = 0.0f;\n\tif (_direction == ScrollView::Direction::HORIZONTAL) {\n\t\tcurrent_offset = this->getContentOffset().x;\n\t} else {\n\t\tcurrent_offset = this->getContentOffset().y;\n\t}\n\treturn true;\n}\n\nvoid XKPageView::onTouchMoved(Touch *touch, Event *unusedEvent) {\n\tVec2 moveDistance, newPoint;\n\tnewPoint = this->convertTouchToNodeSpace(_touches[0]);\n\tmoveDistance = newPoint - _touchPoint;\n\tif (_direction == ScrollView::Direction::HORIZONTAL)\n\t\tthis->setContentOffset(Vec2(current_offset + moveDistance.x, 0));\n\telse\n\t\tthis->setContentOffset(Vec2(0, current_offset + moveDistance.y));\n}\n\nvoid XKPageView::onTouchEnded(Touch *touch, Event *unusedEvent) {\n\tfloat start = current_offset, end;\n\tif (_direction == ScrollView::Direction::HORIZONTAL) {\n\t\tend = this->getContentOffset().x;\n\t} else {\n\t\tend = this->getContentOffset().y;\n\t}\n\tfloat offset = end - start;\n\tthis->adjust(offset);\n\t_dragging = true;\n\t_touches.clear();\n}\n\nvoid XKPageView::setCurPageIndex(ssize_t idx) {\n\tif (idx < 0) idx = 0;\n\tif (idx >= pageCount) idx = pageCount - 1;\n\tcurrent_index = idx;\n\n\tVec2 vec;\n\tconst Size &size = getViewSize();\n\tif (_direction == ScrollView::Direction::HORIZONTAL) {\n\t\tvec = Vec2((size.width - pageSize.width) / 2 - current_index * pageSize.width, 0);\n\t} else {\n\t\tvec = Vec2(0, (size.height - pageSize.height) / 2 - current_index * pageSize.height);\n\t}\n\n\tthis->setContentOffset(vec);\n}\n\nclass WidgetNodeReader : public cocostudio::NodeReader {\npublic:\n\tvirtual cocos2d::Node* createNodeWithFlatBuffers(const flatbuffers::Table* nodeOptions)\n\t{\n\t\tWidget* node = Widget::create();\n\n\t\tsetPropsWithFlatBuffers(node, nodeOptions);\n\n\t\treturn node;\n\t}\n\tstatic WidgetNodeReader *getInstance() {\n\t\tstatic WidgetNodeReader *instance = new WidgetNodeReader;\n\t\treturn instance;\n\t}\n\tstatic cocos2d::Ref *createInstance() {\n\t\treturn getInstance();\n\t}\n};\n\nvoid TVPInitUIExtension() {\n\tCSLoader::getInstance();\n\tstatic cocos2d::ObjectFactory::TInfo __Type(\"NodeReader\", WidgetNodeReader::createInstance);\n}\n"
  },
  {
    "path": "src/core/environ/ui/extension/UIExtension.h",
    "content": "﻿#pragma once\n#include \"extensions/GUI/CCScrollView/CCScrollView.h\"\n\nclass XKPageView;\nclass XKPageViewDelegate\n{\npublic:\n\tvirtual ~XKPageViewDelegate(){};\n\tXKPageViewDelegate(){};\n\tvirtual cocos2d::Size sizeForPerPage() = 0;\n\tvirtual void pageViewDidScroll(XKPageView *pageView){};\n};\n\nclass XKPageView : public cocos2d::extension::ScrollView\n{\npublic:\n\tstatic XKPageView *create(cocos2d::Size size, XKPageViewDelegate *delegate);\n\tvirtual bool init(cocos2d::Size size, XKPageViewDelegate *delegate);\n\tssize_t getCurPageIndex() const { return current_index; }\n\tvoid setCurPageIndex(ssize_t idx);\n\tssize_t getPageCount() const { return pageCount; }\npublic:\n\tvoid setPageSize(const cocos2d::Size &size) { pageSize = size; }\n\tvirtual void setContentOffsetInDuration(cocos2d::Vec2 offset, float dt);\n\tvirtual void setContentOffset(cocos2d::Vec2 offset);\n\tvoid setTouchEnabled(bool enabled);\n\nprivate:\n\tvirtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) override;\n\tvirtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) override;\n\tvirtual void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) override;\n\n\tvoid performedAnimatedScroll(float dt);\n\tint current_index;\n\tfloat current_offset;\n\n\tvoid adjust(float offset);\n\tcocos2d::Size pageSize;\n\tCC_SYNTHESIZE(XKPageViewDelegate *, _delegate, Delegate);\npublic:\n\tint pageCount;\n\tvoid addPage(Node *node);\n\tcocos2d::Node *getPageAtIndex(int index);\n};\n\nvoid TVPInitUIExtension();"
  },
  {
    "path": "src/core/environ/vkdefine.h",
    "content": "#pragma once\n#define VK_FALG_MOUSE       1\n#define VK_FLAG_SHIFT       2\n\n#define VK_LBUTTON 0x01\n#define VK_RBUTTON 0x02\n#define VK_CANCEL 0x03\n#define VK_MBUTTON 0x04\n#define VK_BACK 0x08\n#define VK_TAB 0x09\n#define VK_CLEAR 0x0C\n#define VK_RETURN 0x0D\n#define VK_SHIFT 0x10\n#define VK_CONTROL 0x11\n#define VK_MENU 0x12\n#define VK_PAUSE 0x13\n#define VK_CAPITAL 0x14\n#define VK_KANA 0x15\n#define VK_HANGEUL 0x15\n#define VK_HANGUL 0x15\n#define VK_JUNJA 0x17\n#define VK_FINAL 0x18\n#define VK_HANJA 0x19\n#define VK_KANJI 0x19\n#define VK_ESCAPE 0x1B\n#define VK_CONVERT 0x1C\n#define VK_NONCONVERT 0x1D\n#define VK_ACCEPT 0x1E\n#define VK_MODECHANGE 0x1F\n#define VK_SPACE 0x20\n#define VK_PRIOR 0x21\n#define VK_NEXT 0x22\n#define VK_END 0x23\n#define VK_HOME 0x24\n#define VK_LEFT 0x25\n#define VK_UP 0x26\n#define VK_RIGHT 0x27\n#define VK_DOWN 0x28\n#define VK_SELECT 0x29\n#define VK_PRINT 0x2A\n#define VK_EXECUTE 0x2B\n#define VK_SNAPSHOT 0x2C\n#define VK_INSERT 0x2D\n#define VK_DELETE 0x2E\n#define VK_HELP 0x2F\n#define VK_0 0x30\n#define VK_1 0x31\n#define VK_2 0x32\n#define VK_3 0x33\n#define VK_4 0x34\n#define VK_5 0x35\n#define VK_6 0x36\n#define VK_7 0x37\n#define VK_8 0x38\n#define VK_9 0x39\n#define VK_A 0x41\n#define VK_B 0x42\n#define VK_C 0x43\n#define VK_D 0x44\n#define VK_E 0x45\n#define VK_F 0x46\n#define VK_G 0x47\n#define VK_H 0x48\n#define VK_I 0x49\n#define VK_J 0x4A\n#define VK_K 0x4B\n#define VK_L 0x4C\n#define VK_M 0x4D\n#define VK_N 0x4E\n#define VK_O 0x4F\n#define VK_P 0x50\n#define VK_Q 0x51\n#define VK_R 0x52\n#define VK_S 0x53\n#define VK_T 0x54\n#define VK_U 0x55\n#define VK_V 0x56\n#define VK_W 0x57\n#define VK_X 0x58\n#define VK_Y 0x59\n#define VK_Z 0x5A\n#define VK_LWIN 0x5B\n#define VK_RWIN 0x5C\n#define VK_APPS 0x5D\n#define VK_NUMPAD0 0x60\n#define VK_NUMPAD1 0x61\n#define VK_NUMPAD2 0x62\n#define VK_NUMPAD3 0x63\n#define VK_NUMPAD4 0x64\n#define VK_NUMPAD5 0x65\n#define VK_NUMPAD6 0x66\n#define VK_NUMPAD7 0x67\n#define VK_NUMPAD8 0x68\n#define VK_NUMPAD9 0x69\n#define VK_MULTIPLY 0x6A\n#define VK_ADD 0x6B\n#define VK_SEPARATOR 0x6C\n#define VK_SUBTRACT 0x6D\n#define VK_DECIMAL 0x6E\n#define VK_DIVIDE 0x6F\n#define VK_F1 0x70\n#define VK_F2 0x71\n#define VK_F3 0x72\n#define VK_F4 0x73\n#define VK_F5 0x74\n#define VK_F6 0x75\n#define VK_F7 0x76\n#define VK_F8 0x77\n#define VK_F9 0x78\n#define VK_F10 0x79\n#define VK_F11 0x7A\n#define VK_F12 0x7B\n#define VK_F13 0x7C\n#define VK_F14 0x7D\n#define VK_F15 0x7E\n#define VK_F16 0x7F\n#define VK_F17 0x80\n#define VK_F18 0x81\n#define VK_F19 0x82\n#define VK_F20 0x83\n#define VK_F21 0x84\n#define VK_F22 0x85\n#define VK_F23 0x86\n#define VK_F24 0x87\n#define VK_NUMLOCK 0x90\n#define VK_SCROLL 0x91\n#define VK_LSHIFT 0xA0\n#define VK_RSHIFT 0xA1\n#define VK_LCONTROL 0xA2\n#define VK_RCONTROL 0xA3\n#define VK_LMENU 0xA4\n#define VK_RMENU 0xA5\n\n#define VK_PROCESSKEY 0xE5\n#define VK_ATTN 0xF6\n#define VK_CRSEL 0xF7\n#define VK_EXSEL 0xF8\n#define VK_EREOF 0xF9\n#define VK_PLAY 0xFA\n#define VK_ZOOM 0xFB\n#define VK_NONAME 0xFC\n#define VK_PA1 0xFD\n#define VK_OEM_CLEAR 0xFE\n\n#define VK_OEM_1          0xBA   // ';:' for US\n#define VK_OEM_PLUS       0xBB   // '+' any country\n#define VK_OEM_COMMA      0xBC   // ',' any country\n#define VK_OEM_MINUS      0xBD   // '-' any country\n#define VK_OEM_PERIOD     0xBE   // '.' any country\n#define VK_OEM_2          0xBF   // '/?' for US\n#define VK_OEM_3          0xC0   // '`~' for US\n#define VK_OEM_4          0xDB  //  '[{' for US\n#define VK_OEM_5          0xDC  //  '\\|' for US\n#define VK_OEM_6          0xDD  //  ']}' for US\n#define VK_OEM_7          0xDE  //  ''\"' for US\n#define VK_OEM_8          0xDF"
  },
  {
    "path": "src/core/environ/win32/ApplicationSpecialPath.h",
    "content": "\n#ifndef __APPLICATION_SPECIAL_PATH_H__\n#define __APPLICATION_SPECIAL_PATH_H__\n\n//#include <shlobj.h>\n#include \"FilePathUtil.h\"\n#include \"StorageIntf.h\"\n\nclass ApplicationSpecialPath {\npublic:\n#if 0\n\tstatic std::wstring GetSpecialFolderPath(int csidl) {\n\t\twchar_t path[MAX_PATH+1];\n\t\tif(!SHGetSpecialFolderPath(NULL, path, csidl, false))\n\t\t\treturn std::wstring();\n\t\treturn std::wstring(path);\n\t}\n\tstatic inline std::wstring GetPersonalPath() {\n\t\tstd::wstring path = GetSpecialFolderPath(CSIDL_PERSONAL);\n\t\tif( path.empty() ) path = GetSpecialFolderPath(CSIDL_APPDATA);\n\n\t\tif(path != L\"\") {\n\t\t\treturn path;\n\t\t}\n\t\treturn L\"\";\n\t}\n\tstatic inline std::wstring GetAppDataPath() {\n\t\tstd::wstring path = GetSpecialFolderPath(CSIDL_APPDATA);\n\t\tif(path != L\"\" ) {\n\t\t\treturn path;\n\t\t}\n\t\treturn L\"\";\n\t}\n\tstatic inline std::wstring GetSavedGamesPath() {\n\t\tstd::wstring result;\n\t\tPWSTR ppszPath = NULL;\n\t\tHRESULT hr = ::SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &ppszPath);\n\t\tif( hr == S_OK ) {\n\t\t\tresult = std::wstring(ppszPath);\n\t\t\t::CoTaskMemFree( ppszPath );\n\t\t}\n\t\treturn result;\n\t}\n#endif\n\tstatic inline ttstr ReplaceStringAll(ttstr src, const ttstr& target, const ttstr& dest) {\n\t\tsrc.Replace(target, dest);\n\t\treturn src;\n\t}\n\n#if 0\n\tstatic inline ttstr GetConfigFileName(const ttstr& exename) {\n\t\treturn ChangeFileExt(exename.AsNarrowStdString(), \".cf\");\n\t}\n#endif\n\tstatic ttstr GetDataPathDirectory(ttstr datapath, const ttstr& exename) {\n\t\tttstr nativeDataPath = TVPGetAppPath();\n\t\tTVPGetLocalName(nativeDataPath);\n\t\tnativeDataPath += \"/savedata/\";\n\t\treturn nativeDataPath;\n#if 0\n\t\tif(datapath == L\"\" ) datapath = std::wstring(L\"$(exepath)\\\\savedata\");\n\n\t\tstd::wstring exepath = ExcludeTrailingBackslash(ExtractFileDir(exename));\n\t\tstd::wstring personalpath = ExcludeTrailingBackslash(GetPersonalPath());\n\t\tstd::wstring appdatapath = ExcludeTrailingBackslash(GetAppDataPath());\n\t\tstd::wstring savedgamespath = ExcludeTrailingBackslash(GetSavedGamesPath());\n\t\tif(personalpath == L\"\") personalpath = exepath;\n\t\tif(appdatapath == L\"\") appdatapath = exepath;\n\t\tif(savedgamespath == L\"\") savedgamespath = exepath;\n\n\t\tOSVERSIONINFO osinfo;\n\t\tosinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\n\t\t::GetVersionEx(&osinfo);\n\n\t\tbool vista_or_later = osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && osinfo.dwMajorVersion >= 6;\n\n\t\tstd::wstring vistapath = vista_or_later ? appdatapath : exepath;\n\n\t\tdatapath = ReplaceStringAll(datapath, L\"$(exepath)\", exepath);\n\t\tdatapath = ReplaceStringAll(datapath, L\"$(personalpath)\", personalpath);\n\t\tdatapath = ReplaceStringAll(datapath, L\"$(appdatapath)\", appdatapath);\n\t\tdatapath = ReplaceStringAll(datapath, L\"$(vistapath)\", vistapath);\n\t\tdatapath = ReplaceStringAll(datapath, L\"$(savedgamespath)\", savedgamespath);\n\t\treturn IncludeTrailingBackslash(ExpandUNCFileName(datapath));\n#endif\n\t}\n#if 0\n\tstatic ttstr GetUserConfigFileName(const ttstr& datapath, const ttstr& exename) {\n\t\t// exepath, personalpath, appdatapath\n\t\treturn GetDataPathDirectory(datapath, exename) + ExtractFileName(ChangeFileExt(exename.AsNarrowStdString(), \".cfu\"));\n\t}\n#endif\n};\n\n\n#endif // __APPLICATION_SPECIAL_PATH_H__\n"
  },
  {
    "path": "src/core/environ/win32/CompatibleNativeFuncs.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// native functions support\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n\n#define TVP_WNF_A\n#include \"CompatibleNativeFuncs.h\"\n#undef TVP_WNF_A\n\n#undef CompatibleNativeFuncsH\n\n#define TVP_WNF_B\n#include \"CompatibleNativeFuncs.h\"\n#undef TVP_WNF_B\n\n//---------------------------------------------------------------------------\n// TVPInitCompatibleNativeFunctions\n//---------------------------------------------------------------------------\nvoid TVPInitCompatibleNativeFunctions()\n{\n\t// retrieve function pointer from each module\n\tconst tjs_int n = sizeof(TVPCompatibleNativeFuncs)/sizeof(tTVPCompatibleNativeFunc);\n\tfor( tjs_int i = 0; i<n; i++ ) \t{\n\t\ttTVPCompatibleNativeFunc * p = TVPCompatibleNativeFuncs + i;\n\t\tHMODULE module = GetModuleHandle(p->Module);\n\t\tif(module) *(p->Ptr) = (void*)GetProcAddress(module, p->Name);\n\t}\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/environ/win32/CompatibleNativeFuncs.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// native functions support\n//---------------------------------------------------------------------------\n#ifndef CompatibleNativeFuncsH\n#define CompatibleNativeFuncsH\n\n//---------------------------------------------------------------------------\n// macros\n//---------------------------------------------------------------------------\n#if !defined(TVP_WNF_A) && !defined(TVP_WNF_B)\n\t#define TVP_NATIVE_FUNC_REG(type, calltype, name, args, module) \\\n\t\textern type (calltype * proc##name)args;\n#endif\n\n#if defined(TVP_WNF_A)\n\t#define TVP_NATIVE_FUNC_REG(type, calltype, name, args, module) \\\n\t\ttype (calltype * proc##name)args = NULL;\n#endif\n\n#if defined(TVP_WNF_B)\n\t#define TVP_NATIVE_FUNC_REG(type, calltype, name, args, module) \\\n\t\t{ (void**)&proc##name, #name, module },\n\nstruct tTVPCompatibleNativeFunc\n{\n\tvoid ** Ptr;\n\tconst char * Name;\n\tconst wchar_t* Module;\n} static TVPCompatibleNativeFuncs[] = {\n#endif\n//---------------------------------------------------------------------------\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, GetTouchInputInfo,\n\t(HTOUCHINPUT hTouchInput,UINT cInputs,PTOUCHINPUT pInputs,int cbSize),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, CloseTouchInputHandle,\n\t(HTOUCHINPUT hTouchInput),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, GetGestureInfo,\n\t(HGESTUREINFO hGestureInfo,PGESTUREINFO pGestureInfo),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, CloseGestureInfoHandle,\n\t(HGESTUREINFO hGestureInfo),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, RegisterTouchWindow,\n\t(HWND hWnd, ULONG ulFlags),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, UnregisterTouchWindow,\n\t(HWND hWnd),\n\tL\"USER32.DLL\")\n\nTVP_NATIVE_FUNC_REG(\n\tBOOL, WINAPI, IsTouchWindow,\n\t(HWND hWnd, PULONG pulFlags),\n\tL\"USER32.DLL\")\n/////\n//---------------------------------------------------------------------------\n#if defined(TVP_WNF_B)\n};\n#endif\n\n#undef TVP_NATIVE_FUNC_REG\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/ConfigFormUnit.cpp",
    "content": "//---------------------------------------------------------------------------\n// Config dialog box\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"Resource.h\"\n\n#include \"MsgIntf.h\"\n#include \"ConfigFormUnit.h\"\n#include \"SystemControl.h\"\n#include \"WindowImpl.h\"\n\n#include \"DebugIntf.h\"\n#include \"ReadOptionDesc.h\"\n#include \"SysInitIntf.h\"\n#include <commctrl.h>\n#include <windowsx.h>\n#include \"Application.h\"\n#include \"FilePathUtil.h\"\n#include \"ApplicationSpecialPath.h\"\n#include \"BinaryStream.h\"\n/*\nIDC_DESCRIPTION_EDIT : eLXg\nIDC_DEFAULT_BUTTON : ftHg{^\nIDC_OPTION_COMBO\nIDC_OPTIONS_TREE\n*/\nstruct TreeItem {\n\tHTREEITEM    ItemHandle;\n\tstd::wstring Text; // ږ\n\tstd::wstring Caption; // p[^̖O + ݒl\n\tstd::wstring Parameter; // p[^̖O\n\ttjs_int Value; // p[^̐ݒlCfbNX\n\ttjs_int Defalut; // p[^̃ftHglCfbNX\n\tstd::wstring Description; // ڂ̐\n\tstd::vector<std::pair<std::wstring, std::wstring> > Select; // ݒ\\Ȓl̃Xg\n};\n\nclass ConfigFormUnit {\n\tHWND WindowHandle;\n\tHWND TreeControl;\n\tHWND DefaultButton;\n\tHWND OptionList;\n\tint OptionListWidth;\n\tint OptionListHeight;\n\n\tTreeItem* CurrentItem;\n\n\tstd::vector<TreeItem> TreeItems;\n\nprivate:\n\t// TreeControl ɃACeǉ\n\tHTREEITEM InsertTreeItem( HTREEITEM hParent, const std::wstring& text ) {\n\t\tTV_INSERTSTRUCT tvinsert;\n\t\tZeroMemory( &tvinsert, sizeof(tvinsert) );\n\t\ttvinsert.hInsertAfter = TVI_LAST;\n\t\ttvinsert.item.mask = TVIF_TEXT;\n\t\ttvinsert.hParent = hParent;\n\t\ttvinsert.item.pszText = (wchar_t*)text.c_str();\n\t\treturn TreeView_InsertItem( TreeControl, &tvinsert );\n\t}\n\tvoid SetTreeItem( HTREEITEM hItem, const std::wstring& text ) {\n\t\tTVITEM tvitem;\n\t\tZeroMemory( &tvitem, sizeof(tvitem) );\n\t\ttvitem.mask = TVIF_TEXT;\n\t\ttvitem.pszText = (wchar_t*)text.c_str();\n\t\ttvitem.hItem = hItem;\n\t\tTreeView_SetItem( TreeControl, &tvitem );\n\t}\n\t// ڂI\n\tvoid SelectItem( const TreeItem& item ) {\n\t\t// XV\n\t\t::SetDlgItemText( WindowHandle, IDC_DESCRIPTION_EDIT, item.Description.c_str() );\n\n\t\t// IXV\n\t\t::EnableWindow( OptionList, TRUE );\n\t\tUpdateItemList( item );\n\t\t\n\t\t// ftHg{^XV\n\t\tSetDefaultButtonEnable( item.Defalut != item.Value );\n\t}\n\tvoid ClearOptionList() {\n\t\tComboBox_ResetContent(OptionList);\n\t}\n\tvoid UpdateItemList( const TreeItem& item ) {\n\t\tClearOptionList();\n\t\ttjs_uint count = (tjs_uint)item.Select.size();\n\t\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\t\tstd::wstring itemstr = item.Select[i].second + std::wstring(L\" / \") + item.Select[i].first;\n\t\t\tComboBox_InsertString( OptionList, -1, itemstr.c_str() );\n\t\t}\n\t\tComboBox_SetCurSel( OptionList, item.Value );\n\t\tcount = count > 12 ? 12 : count;\n\t\tif( count <= 0 ) count = 1;\n\t\tint itemheight = ComboBox_GetItemHeight(OptionList);\n\t\t::SetWindowPos( OptionList, 0, 0, 0, OptionListWidth, itemheight * count + OptionListHeight + 2, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW|SWP_HIDEWINDOW);\n\t\t::SetWindowPos( OptionList, 0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);\n\t}\n\tvoid SelectNull() {\n\t\t::SetDlgItemText( WindowHandle, IDC_DESCRIPTION_EDIT, L\"\" );\n\t\tClearOptionList();\n\t\t::EnableWindow( OptionList, FALSE );\n\t\tSetDefaultButtonEnable( false );\n\t}\n\tvoid ChangeOptionValue() {\n\t\tif( CurrentItem ) {\n\t\t\tbool ischange = false;\n\t\t\tint sel = ComboBox_GetCurSel( OptionList );\n\t\t\tif( sel != CB_ERR ) {\n\t\t\t\tischange = CurrentItem->Value != sel;\n\t\t\t\tCurrentItem->Value = sel;\n\t\t\t}\n\t\t\tif( ischange ) {\n\t\t\t\tif( CurrentItem->Defalut != CurrentItem->Value ) {\n\t\t\t\t\tCurrentItem->Caption = std::wstring(L\"* \") + CurrentItem->Text + std::wstring(L\" : \") + CurrentItem->Select[CurrentItem->Value].second;\n\t\t\t\t} else {\n\t\t\t\t\tCurrentItem->Caption = CurrentItem->Text + std::wstring(L\" : \") + CurrentItem->Select[CurrentItem->Value].second;\n\t\t\t\t}\n\t\t\t\tif( CurrentItem->ItemHandle ) {\n\t\t\t\t\tSetTreeItem( CurrentItem->ItemHandle, CurrentItem->Caption );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// wtH_ɂwgq̃vOCݒǂݍ\n\tvoid LoadPluginOptionDesc( tTVPCommandOptionList* coreopt, const std::wstring& path, const std::wstring& ext ) {\n\t\tstd::wstring exename = ExePath();\n\t\texename = IncludeTrailingBackslash(ExtractFileDir(exename));\n\t\tstd::wstring filepath = exename + path;\n\t\tstd::wstring mask = filepath + L\"*.\" + ext;\n\n\t\tWIN32_FIND_DATA fd;\n\t\tHANDLE hSearch = ::FindFirstFile( mask.c_str(), &fd );\n\t\tif( hSearch != INVALID_HANDLE_VALUE ) {\n\t\t\tdo {\n\t\t\t\ttTVPCommandOptionList* options = TVPGetPluginCommandDesc( (filepath + std::wstring(fd.cFileName) ).c_str() );\n\t\t\t\tif( options ) {\n\t\t\t\t\tTVPMargeCommandDesc( *coreopt, *options );\n\t\t\t\t\tdelete options;\n\t\t\t\t}\n\t\t\t} while( FindNextFile( hSearch, &fd ) );\n\t\t\t::FindClose( hSearch );\n\t\t}\n\t}\npublic:\n\tConfigFormUnit( HWND hWnd ) : WindowHandle(hWnd), CurrentItem(NULL) {\n\t\tTreeControl = ::GetDlgItem( WindowHandle, IDC_OPTIONS_TREE );\n\t\tDefaultButton = ::GetDlgItem( WindowHandle, IDC_DEFAULT_BUTTON );\n\t\tOptionList = ::GetDlgItem( WindowHandle, IDC_OPTION_COMBO );\n\t\tRECT rc;\n\t\t::GetWindowRect( OptionList, &rc );\n\t\tOptionListWidth = rc.right - rc.left;\n\t\tOptionListHeight = rc.bottom - rc.top;\n\n\t\tSetDefaultButtonEnable( false );\n\t\tLoadOptionTree();\n\t}\n\t~ConfigFormUnit() {\n\t}\n\t\n\tstatic LRESULT WINAPI DlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\tLRESULT Dispatch( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\n\tvoid SetDefaultButtonEnable( bool enable ) {\n\t\t::EnableWindow( DefaultButton, enable ? TRUE : FALSE );\n\t}\n\n\tvoid SetDescriptionText( const std::wstring& text ) {\n\t\t::SetDlgItemText( WindowHandle, IDC_DESCRIPTION_EDIT, text.c_str() );\n\t}\n\tvoid LoadOptionTree();\n\t// ݂̃ACeݒ肵Aɏ]\\XV\n\tvoid SetCurrentItem( HTREEITEM hItem ) {\n\t\tif( CurrentItem != NULL && CurrentItem->ItemHandle == hItem ) return;\n\n\t\tCurrentItem = NULL;\n\t\tfor( std::vector<TreeItem>::iterator i = TreeItems.begin(); i != TreeItems.end(); i++ ) {\n\t\t\tif( (*i).ItemHandle == hItem ) {\n\t\t\t\tCurrentItem = &(*i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif( CurrentItem ) {\n\t\t\tSelectItem( *CurrentItem );\n\t\t} else {\n\t\t\tSelectNull();\n\t\t}\n\t}\n\tvoid ConvertReturnCode( std::wstring& text ) {\n\t\tstd::vector<wchar_t> buf;\n\t\tsize_t len = text.length();\n\t\tbuf.reserve( len * 2 );\n\t\tfor( size_t i = 0; i < len; i++ ) {\n\t\t\tif( text[i] != L'\\n' ) {\n\t\t\t\tbuf.push_back( text[i] );\n\t\t\t} else {\n\t\t\t\tbuf.push_back( L'\\r' );\n\t\t\t\tbuf.push_back( L'\\n' );\n\t\t\t}\n\t\t}\n\t\ttext.assign( &(buf[0]), buf.size() );\n\t}\n\tstd::string ToStringOption() {\n\t\tstd::string ret;\n\t\tfor( std::vector<TreeItem>::const_iterator i = TreeItems.begin() ; i != TreeItems.end(); i++ ) {\n\t\t\tconst TreeItem& item = *i;\n\t\t\tif( item.Value != item.Defalut ) {\n\t\t\t\tstd::string name;\n\t\t\t\tTVPUtf16ToUtf8( name, item.Parameter );\n\t\t\t\tret += name;\n\t\t\t\tret += \"=\";\n\t\t\t\tret += EncodeString( item.Select[item.Value].first );\n\t\t\t\tret += \"\\r\\n\";\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t}\n\t// ݒ肳ꂽeۑ\n\tvoid SaveSetting() {\n\t\ttTJSVariant val;\n\t\tstd::wstring path;\n\t\tif( TVPGetCommandLine( L\"-datapath\", &val) ) {\n\t\t\tttstr str(val);\n\t\t\tpath.assign( str.c_str(), str.length() );\n\t\t}\n\t\tstd::wstring exename = ExePath();\n\t\tstd::wstring filename = ChangeFileExt( ExtractFileName( exename ), L\".cfu\" );\n\t\tfilename = ApplicationSpecialPath::GetDataPathDirectory( path, exename ) + filename;\n\t\tconst char * warnings =\n\"; ============================================================================\\r\\n\"\n\"; *DO NOT EDIT* this file unless you are understanding what you are doing.\\r\\n\"\n\"; FYI:\\r\\n\"\n\";  Each line consists of NAME=\\\"VALUE\\\" pair, VALUE is a series of\\r\\n\"\n\";  \\\\xNN, where NN is hexadecimal representation of UNICODE codepoint.\\r\\n\"\n\";  For example, opt=\\\"\\\\x61\\\\x62\\\\x63\\\\x3042\\\\x3044\\\\x3046\\\" means that the\\r\\n\"\n\";  value of options \\\"opt\\\" is alphabets a, b, and c followed by Japanese\\r\\n\"\n\";  Hiraganas A, I, and U.\\r\\n\"\n\";  DO NOT PUT non-escaped value like opt=\\\"abc\\\". This doesn't work and should\\r\\n\"\n\";  be like opt=\\\"\\\\x61\\\\x62\\\\x63\\\".\\r\\n\"\n\"; ============================================================================\\r\\n\"\n\"\";\n\t\ttTJSBinaryStream *stream = TVPCreateBinaryStreamForWrite( ttstr(filename), L\"\" );\n\t\tif( stream ) {\n\t\t\ttry {\n\t\t\t\tstream->Write( warnings, (tjs_uint)strlen(warnings) );\n\t\t\t\tstd::string option = ToStringOption();\n\t\t\t\tstream->Write( option.c_str(), (tjs_uint)option.length() );\n\t\t\t} catch(...) {\n\t\t\t\tdelete stream;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete stream;\n\t\t}\n\n\t}\n\tstatic int HexNum(wchar_t ch) {\n\t\tif(ch>='a' && ch<='f')return ch-'a'+10;\n\t\tif(ch>='A' && ch<='F')return ch-'A'+10;\n\t\tif(ch>='0' && ch<='9')return ch-'0';\n\t\treturn -1;\n\t} \n\tstatic std::string DecodeString( const std::wstring& str ) {\n\t\tif( str.empty() ) return \"\";\n\t\tttstr ret;\n\t\tconst wchar_t *p = str.c_str();\n\t\tif(p[0] != '\\\"') return ttstr(str).AsNarrowStdString();\n\n\t\tp++;\n\t\twhile( *p ) {\n\t\t\tif(*p != '\\\\') break;\n\t\t\tp++;\n\t\t\tif(*p != 'x') break;\n\t\t\tp++;\n\t\t\twchar_t ch = 0;\n\t\t\twhile( true ) {\n\t\t\t\tint n = HexNum(*p);\n\t\t\t\tif(n == -1) break;\n\t\t\t\tch <<= 4;\n\t\t\t\tch += n;\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tret += ch;\n\t\t}\n\t\treturn ret.AsNarrowStdString();\n\t}\n\tstatic std::string EncodeString( const std::wstring& str ) {\n\t\tif( str.empty() ) return \"\\\"\\\"\";\n\t\tttstr ws(str.c_str());\n\t\tconst wchar_t *p = ws.c_str();\n\n\t\tstd::string ret = \"\\\"\";\n\t\twhile( *p ) {\n\t\t\tchar tmp[10];\n\t\t\tsprintf(tmp, \"\\\\x%X\", *p);\n\t\t\tret += tmp;\n\t\t\tp++;\n\t\t}\n\t\treturn ret + \"\\\"\";\n\t}\n};\nstatic ConfigFormUnit* DialogForm = NULL;\n\n// {̂ƃvOC̐ݒǍ݁Ac[ɔf\nvoid ConfigFormUnit::LoadOptionTree() {\n\ttTVPCommandOptionList* options = TVPGetEngineCommandDesc();\n\tif( options ) {\n\t\tLoadPluginOptionDesc( options, L\"\\\\\", L\"dll\" );\n\t\tLoadPluginOptionDesc( options, L\"\\\\\", L\"tpm\" );\n#ifdef TJS_64BIT_OS\n\t\tLoadPluginOptionDesc( options, L\"plugin64\\\\\", L\"dll\" );\n\t\tLoadPluginOptionDesc( options, L\"plugin64\\\\\", L\"tpm\" );\n#else\n\t\tLoadPluginOptionDesc( options, L\"plugin\\\\\", L\"dll\" );\n\t\tLoadPluginOptionDesc( options, L\"plugin\\\\\", L\"tpm\" );\n#endif\n\n\t\ttTJSVariant val;\n\t\tHTREEITEM hFirst = NULL;\n\t\t// LȃACeJEg\n\t\ttjs_uint itemcount = 0;\n\t\ttjs_uint count = (tjs_uint)options->Categories.size();\n\t\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\t\tconst tTVPCommandOptionCategory& category = options->Categories[i];\n\t\t\ttjs_uint optcount = (tjs_uint)category.Options.size();\n\t\t\tfor( tjs_uint j = 0; j < optcount; j++ ) {\n\t\t\t\tif( category.Options[j].User ) itemcount++;\n\t\t\t}\n\t\t}\n\t\tTreeItems.resize(itemcount);\n\n\t\ttjs_uint itemidx = 0;\n\t\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\t\tconst tTVPCommandOptionCategory& category = options->Categories[i];\n\t\t\ttjs_uint optcount = (tjs_uint)category.Options.size();\n\t\t\t// ܂̓JeSɗLȃACe邩`FbN\n\t\t\tbool hasitem = false;\n\t\t\tfor( tjs_uint j = 0; j < optcount; j++ ) {\n\t\t\t\tif( category.Options[j].User ) {\n\t\t\t\t\thasitem = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( hasitem == false ) continue;\n\t\t\tHTREEITEM hItem = InsertTreeItem( TVI_ROOT, category.Name );\n\t\t\tif( hFirst == NULL ) hFirst = hItem;\n\t\t\tfor( tjs_uint j = 0; j < optcount; j++ ) {\n\t\t\t\tconst tTVPCommandOption& option = category.Options[j];\n\t\t\t\tif( option.User ) {\n\t\t\t\t\tTreeItem& curitem = TreeItems[itemidx];\n\t\t\t\t\tcuritem.Text = option.Caption;\n\t\t\t\t\tcuritem.Parameter = option.Name;\n\t\t\t\t\tcuritem.Description = std::wstring(L\"-\")+option.Name+std::wstring(L\"\\n\")+option.Description;\n\t\t\t\t\tConvertReturnCode( curitem.Description );\n\t\t\t\t\ttjs_uint valcount = (tjs_uint)option.Values.size();\n\t\t\t\t\tcuritem.Select.resize( valcount );\n\t\t\t\t\tcuritem.Defalut = -1;\n\t\t\t\t\tstd::wstring argname( std::wstring(L\"-\") + option.Name );\n\t\t\t\t\tstd::wstring selectvalue;\n\t\t\t\t\tif( TVPGetCommandLine( argname.c_str(), &val) ) {\n\t\t\t\t\t\tttstr str(val);\n\t\t\t\t\t\tselectvalue.assign( str.c_str(), str.length() );\n\t\t\t\t\t}\n\t\t\t\t\ttjs_int selectindex = -1;\n\t\t\t\t\tfor( tjs_uint k = 0; k < valcount; k++ ) {\n\t\t\t\t\t\tstd::pair<std::wstring, std::wstring>& sel = curitem.Select[k];\n\t\t\t\t\t\tconst tTVPCommandOptionsValue& val = option.Values[k];\n\t\t\t\t\t\tsel.first = val.Value;\n\t\t\t\t\t\tsel.second = val.Description;\n\t\t\t\t\t\tif( val.IsDefault ) {\n\t\t\t\t\t\t\tcuritem.Defalut = k;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif( selectindex < 0 && !selectvalue.empty() && selectvalue == val.Value ) {\n\t\t\t\t\t\t\tselectindex = k;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif( selectindex >= 0 ) {\n\t\t\t\t\t\tcuritem.Value = selectindex;\n\t\t\t\t\t} else if( curitem.Defalut >= 0 ) {\n\t\t\t\t\t\tcuritem.Value = curitem.Defalut;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcuritem.Value = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tif( curitem.Defalut != curitem.Value ) {\n\t\t\t\t\t\tcuritem.Caption = std::wstring(L\"* \") + curitem.Text + std::wstring(L\" : \") + curitem.Select[curitem.Value].second;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcuritem.Caption = curitem.Text + std::wstring(L\" : \") + curitem.Select[curitem.Value].second;\n\t\t\t\t\t}\n\t\t\t\t\tcuritem.ItemHandle = InsertTreeItem( hItem, curitem.Caption );\n\t\t\t\t\titemidx++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tTreeView_Expand( TreeControl, hItem, TVE_EXPAND );\n\t\t}\n\t\tTreeView_SelectItem( TreeControl, hFirst );\n\t\tdelete options;\n\t}\n}\n\nLRESULT ConfigFormUnit::Dispatch( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\n\tswitch( msg ) {\n\tcase WM_COMMAND:\n\t\tif(LOWORD(wParam) == IDOK) {\n\t\t\t::EndDialog(hWnd, IDOK);\n\t\t\treturn TRUE;\n\t\t} else if( LOWORD(wParam) == IDCANCEL) {\n\t\t\t::EndDialog(hWnd, IDCANCEL);\n\t\t\treturn TRUE;\n\t\t} else if( LOWORD(wParam) == IDC_DEFAULT_BUTTON) {\n\t\t\treturn TRUE;\n\t\t} else if( HIWORD(wParam) == CBN_SELCHANGE ) {\n\t\t\tChangeOptionValue();\n\t\t}\n\t\tbreak;\n\tcase WM_CLOSE:\n\t\tEndDialog(hWnd, 0);\n\t\treturn TRUE;\n\t case WM_NOTIFY:\n\t\tif( wParam == IDC_OPTIONS_TREE ) {\n\t\t\t// c[Rg[̒ʒmŌݑIĂACeF\n\t\t\tNMHDR* hdr = (LPNMHDR)lParam;\n\t\t\tUINT code = hdr->code;\n\t\t\tif( code == NM_SETCURSOR || code == NM_CLICK || code == NM_SETFOCUS) {\n\t\t\t\tHTREEITEM hItem = TreeView_GetSelection( TreeControl );\n\t\t\t\tif( hItem ) SetCurrentItem( hItem );\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn FALSE;\n}\n\nLRESULT WINAPI ConfigFormUnit::DlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\n\tif( msg == WM_INITDIALOG ) {\n\t\tif( DialogForm ) delete DialogForm;\n\t\tDialogForm = new ConfigFormUnit(hWnd);\n\t\treturn TRUE;\n\t} else {\n\t\tif( DialogForm ) return DialogForm->Dispatch( hWnd, msg, wParam, lParam );\n\t}\n\treturn FALSE;\n}\n//---------------------------------------------------------------------------\nvoid TVPShowUserConfig()\n{\n\ttry {\n\t\tINT_PTR result = ::DialogBox( NULL, MAKEINTRESOURCE(IDD_CONFIG_DIALOG), NULL, (DLGPROC)ConfigFormUnit::DlgProc );\n\t\tif( result == IDOK ) {\n\t\t\tif( DialogForm ) {\n\t\t\t\tDialogForm->SaveSetting();\n\t\t\t\t::MessageBox( NULL, L\"ݒۑ܂\", L\"Save Option\", MB_OK );\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tif( DialogForm ) {\n\t\t\tdelete DialogForm;\n\t\t\tDialogForm = NULL;\n\t\t}\n\t\tthrow;\n\t}\n\tif( DialogForm ) {\n\t\tdelete DialogForm;\n\t\tDialogForm = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/environ/win32/ConfigFormUnit.h",
    "content": "//---------------------------------------------------------------------------\n// Config dialog box\n//---------------------------------------------------------------------------\n\n#ifndef ConfigFormUnitH\n#define ConfigFormUnitH\n\nextern void TVPShowUserConfig();\n//---------------------------------------------------------------------------\n\n#endif\n\n"
  },
  {
    "path": "src/core/environ/win32/DetectCPU.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CPU idetification / features detection routine\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <Windows.h>\n#include \"tvpgl_ia32_intf.h\"\n#include \"DebugIntf.h\"\n#include \"SysInitIntf.h\"\n\n#include \"ThreadIntf.h\"\n\n#include \"Exception.h\"\n#include <intrin.h>\n#include \"MsgIntf.h\"\n\n#pragma intrinsic(__rdtsc)\n\n/*\n\tNote: CPU clock measuring routine is in EmergencyExit.cpp, reusing\n\thot-key watching thread.\n*/\n\n//---------------------------------------------------------------------------\nextern \"C\"\n{\n\ttjs_uint32 TVPCPUType = 0; // CPU type\n}\n\nstatic bool TVPCPUChecked = false;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetCPUTypeForOne\n//---------------------------------------------------------------------------\nstatic void TVPGetCPUTypeForOne()\n{\n#if 1\n\tTVPCheckCPU(); // in detect_cpu.nas\n#else\n\t__try {\n\t\tTVPCheckCPU(); // in detect_cpu.nas\n\t} __except(EXCEPTION_EXECUTE_HANDLER) {\n\t\t// exception had been ocured\n\t\tthrow Exception( TVPCpuCheckFailure );\n\t}\n#endif\n\n\t// check OSFXSR WinXPȍ~ȂT|[gĂ̂ŁÃ`FbN͖Ӗ\n#ifndef TJS_64BIT_OS\n\tif(TVPCPUFeatures & TVP_CPU_HAS_SSE)\n\t{\n\t\t__try {\n\t\t\t//__emit__(0x0f, 0x57, 0xc0); // xorps xmm0, xmm0   (SSE)\n\t\t\t__asm xorps xmm0, xmm0\n\t\t} __except(EXCEPTION_EXECUTE_HANDLER) {\n\t\t\t// exception had been ocured\n\t\t\t// execution of 'xorps' is failed (XMM registers not available)\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE;\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE2;\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE3;\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSSE3;\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE41;\n\t\t\tTVPCPUFeatures &=~ TVP_CPU_HAS_SSE42;\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPCPUCheckThread\n//---------------------------------------------------------------------------\nclass tTVPCPUCheckThread : public tTVPThread\n{\n\tbool Succeeded;\npublic:\n\ttTVPCPUCheckThread(DWORD tam) : tTVPThread(true)\n\t{\n\t\t// set thread affinity mask\n\t\tSucceeded = true;\n\n\t\tSetThreadAffinityMask(GetHandle(), tam);\n\n\t\tResume();\n\t}\n\n\t~tTVPCPUCheckThread()\n\t{\n\t}\n\n\tvoid WaitEnd()\n\t{\n\t\tTerminate();\n\t\tWaitFor();\n\t}\n\n\tbool GetSucceeded() const { return Succeeded; }\n\n\tvoid Execute(void);\n} ;\n//---------------------------------------------------------------------------\nvoid tTVPCPUCheckThread::Execute(void)\n{\n\ttry\n\t{\n\t\tTVPGetCPUTypeForOne();\n\t}\n\tcatch(...)\n\t{\n\t\tSucceeded = false;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\nstatic ttstr TVPDumpCPUFeatures(tjs_uint32 features)\n{\n\tttstr ret;\n#define TVP_DUMP_CPU(x, n) { ret += TJS_W(\"  \") TJS_W(n);  \\\n\tif(features & x) ret += TJS_W(\":yes\"); else ret += TJS_W(\":no\"); }\n\n\tTVP_DUMP_CPU(TVP_CPU_HAS_FPU, \"FPU\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_MMX, \"MMX\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_3DN, \"3DN\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE, \"SSE\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_CMOV, \"CMOVcc\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_E3DN, \"E3DN\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_EMMX, \"EMMX\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE2, \"SSE2\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_TSC, \"TSC\");\n\n\tTVP_DUMP_CPU(TVP_CPU_HAS_TSCP, \"TSCP\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE3, \"SSE3\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSSE3, \"SSSE3\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE41, \"SSE41\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE42, \"SSE42\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_SSE4a, \"SSE4A\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_AVX, \"AVX\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_AVX2, \"AVX2\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_FMA3, \"FMA3\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_AES, \"AES\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_RDRAND, \"RDRAND\");\n\tTVP_DUMP_CPU(TVP_CPU_HAS_RDSEED, \"RDSEED\");\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nstatic ttstr TVPDumpCPUInfo(tjs_int cpu_num)\n{\n\t// dump detected cpu type\n\tttstr features( TVPFormatMessage(TVPInfoCpuNumber,ttstr(cpu_num)) );\n\n\tfeatures += TVPDumpCPUFeatures(TVPCPUFeatures);\n\n\ttjs_uint32 vendor = TVPCPUFeatures & TVP_CPU_VENDOR_MASK;\n\n#undef TVP_DUMP_CPU\n#define TVP_DUMP_CPU(x, n) { \\\n\tif(vendor == x) features += TJS_W(\"  \") TJS_W(n); }\n\n\tTVP_DUMP_CPU(TVP_CPU_IS_INTEL, \"Intel\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_AMD, \"AMD\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_IDT, \"IDT\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_CYRIX, \"Cyrix\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_NEXGEN, \"NexGen\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_RISE, \"Rise\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_UMC, \"UMC\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_TRANSMETA, \"Transmeta\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_NSC, \"NSC\");\n\tTVP_DUMP_CPU(TVP_CPU_IS_COMPAQ, \"Compaq\");\n\n\tTVP_DUMP_CPU(TVP_CPU_IS_UNKNOWN, \"Unknown\");\n\n#undef TVP_DUMP_CPU\n\n\tfeatures += TJS_W(\"(\") + ttstr((const tjs_nchar *)TVPCPUVendor) + TJS_W(\")\");\n\n\tif(TVPCPUName[0]!=0)\n\t\tfeatures += TJS_W(\" [\") + ttstr((const tjs_nchar *)TVPCPUName) + TJS_W(\"]\");\n\n\tfeatures += TJS_W(\"  CPUID(1)/EAX=\") + TJSInt32ToHex(TVPCPUID1_EAX);\n\tfeatures += TJS_W(\" CPUID(1)/EBX=\") + TJSInt32ToHex(TVPCPUID1_EBX);\n\n\tTVPAddImportantLog(features);\n\n\tif(((TVPCPUID1_EAX >> 8) & 0x0f) <= 4)\n\t\tthrow Exception( TVPFormatMessage( TVPCpuCheckFailureCpuFamilyOrLesserIsNotSupported, features).c_str() );\n\n\treturn features;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPDetectCPU\n//---------------------------------------------------------------------------\nstatic void TVPDisableCPU(tjs_uint32 featurebit, const tjs_char *name)\n{\n\ttTJSVariant val;\n\tttstr str;\n\tif(TVPGetCommandLine(name, &val))\n\t{\n\t\tstr = val;\n\t\tif(str == TJS_W(\"no\"))\n\t\t\tTVPCPUType &=~ featurebit;\n\t\telse if(str == TJS_W(\"force\"))\n\t\t\tTVPCPUType |= featurebit;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPDetectCPU()\n{\n\tif(TVPCPUChecked) return;\n\tTVPCPUChecked = true;\n\n#ifdef TJS_64BIT_OS\n\n\t// get process affinity mask\n\tULONGLONG pam = 1;\n\tHANDLE hp = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ::GetCurrentProcessId());\n\tif(hp)\n\t{\n\t\tULONGLONG sam = 1;\n\t\t::GetProcessAffinityMask(hp, (PDWORD_PTR)&pam, (PDWORD_PTR)&sam);\n\t\t::CloseHandle(hp);\n\t}\n\n\t// for each CPU...\n\tttstr cpuinfo;\n\tbool first = true;\n\ttjs_uint32 features = 0;\n\tfor(tjs_int cpu = 0; cpu < 64; cpu++)\n\t{\n\t\tif(pam & (1ULL<<cpu))\n\t\t{\n\t\t\ttTVPCPUCheckThread * thread = new tTVPCPUCheckThread(1<<cpu);\n\t\t\tthread->WaitEnd();\n\t\t\tbool succeeded = thread->GetSucceeded();\n\t\t\tdelete thread;\n\t\t\tif(!succeeded) throw Exception(L\"CPU check failure\");\n\t\t\tcpuinfo += TVPDumpCPUInfo(cpu) + TJS_W(\"\\r\\n\");\n\n\t\t\t// mask features\n\t\t\tif(first)\n\t\t\t{\n\t\t\t\tfeatures =  (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n\t\t\t\tTVPCPUType = TVPCPUFeatures;\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfeatures &= (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n\t\t\t}\n\t\t}\n\t}\n#else\n\t// get process affinity mask\n\tDWORD pam = 1;\n\tHANDLE hp = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ::GetCurrentProcessId());\n\tif(hp)\n\t{\n\t\tDWORD sam = 1;\n\t\t::GetProcessAffinityMask(hp, &pam, &sam);\n\t\t::CloseHandle(hp);\n\t}\n\n\t// for each CPU...\n\tttstr cpuinfo;\n\tbool first = true;\n\ttjs_uint32 features = 0;\n\tfor(tjs_int cpu = 0; cpu < 32; cpu++)\n\t{\n\t\tif(pam & (1<<cpu))\n\t\t{\n\t\t\ttTVPCPUCheckThread * thread = new tTVPCPUCheckThread(1<<cpu);\n\t\t\tthread->WaitEnd();\n\t\t\tbool succeeded = thread->GetSucceeded();\n\t\t\tdelete thread;\n\t\t\tif(!succeeded) throw Exception(L\"CPU check failure\");\n\t\t\tcpuinfo += TVPDumpCPUInfo(cpu) + TJS_W(\"\\r\\n\");\n\n\t\t\t// mask features\n\t\t\tif(first)\n\t\t\t{\n\t\t\t\tfeatures =  (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n\t\t\t\tTVPCPUType = TVPCPUFeatures;\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfeatures &= (TVPCPUFeatures & TVP_CPU_FEATURE_MASK);\n\t\t\t}\n\t\t}\n\t}\n#endif\n\tTVPCPUType &= ~ TVP_CPU_FEATURE_MASK;\n\tTVPCPUType |= features;\n\n\t// Disable or enable cpu features by option\n\tTVPDisableCPU(TVP_CPU_HAS_MMX,  TJS_W(\"-cpummx\"));\n\tTVPDisableCPU(TVP_CPU_HAS_3DN,  TJS_W(\"-cpu3dn\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSE,  TJS_W(\"-cpusse\"));\n\tTVPDisableCPU(TVP_CPU_HAS_CMOV, TJS_W(\"-cpucmov\"));\n\tTVPDisableCPU(TVP_CPU_HAS_E3DN, TJS_W(\"-cpue3dn\"));\n\tTVPDisableCPU(TVP_CPU_HAS_EMMX, TJS_W(\"-cpuemmx\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSE2, TJS_W(\"-cpusse2\"));\n\n\tTVPDisableCPU(TVP_CPU_HAS_SSE3, TJS_W(\"-cpusse3\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSSE3, TJS_W(\"-cpussse3\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSE41, TJS_W(\"-cpusse41\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSE42, TJS_W(\"-cpusse42\"));\n\tTVPDisableCPU(TVP_CPU_HAS_SSE4a, TJS_W(\"-cpusse4a\"));\n\tTVPDisableCPU(TVP_CPU_HAS_AVX, TJS_W(\"-cpuavx\"));\n\tTVPDisableCPU(TVP_CPU_HAS_AVX2, TJS_W(\"-cpuavx2\"));\n\tTVPDisableCPU(TVP_CPU_HAS_FMA3, TJS_W(\"-cpufma3\"));\n\tTVPDisableCPU(TVP_CPU_HAS_AES, TJS_W(\"-cpuaes\"));\n\n\tif(TVPCPUType == 0)\n\t\tthrow Exception( TVPFormatMessage(TVPCpuCheckFailureNotSupprtedCpu, cpuinfo).c_str() );\n\n\tTVPAddImportantLog( TVPFormatMessage(TVPInfoFinallyDetectedCpuFeatures,TVPDumpCPUFeatures(TVPCPUType)) );\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// jpeg and png loader support functions\n//---------------------------------------------------------------------------\nunsigned long MMXReady = 0;\nextern \"C\"\n{\n\tvoid __fastcall CheckMMX(void)\n\t{\n\t\tTVPDetectCPU();\n\t\tMMXReady = TVPCPUType & TVP_CPU_HAS_MMX;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetCPUType\n//---------------------------------------------------------------------------\ntjs_uint32 TVPGetCPUType()\n{\n\tTVPDetectCPU();\n\treturn TVPCPUType;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/environ/win32/DetectCPU.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CPU idetification / features detection routine\n//---------------------------------------------------------------------------\n#ifndef DetectCPUH\n#define DetectCPUH\n//---------------------------------------------------------------------------\nextern \"C\"\n{\n\textern tjs_uint32 TVPCPUType;\n}\n\nextern void TVPDetectCPU();\nTJS_EXP_FUNC_DEF(tjs_uint32, TVPGetCPUType, ());\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/EmergencyExit.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Emergency Exit Hotkey Handler\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"ThreadIntf.h\"\n\n#include \"EmergencyExit.h\"\n#include \"Random.h\"\n#include \"SystemControl.h\"\n\n#include \"tvpgl_ia32_intf.h\"\n\n#include <memory>\n\n#include \"Application.h\"\n#include \"UserEvent.h\"\n\ndouble TVPCPUClock = 0; // CPU clock, in MHz\ntTVPCPUClockAccuracy TVPCPUClockAccuracy = ccaNotSet;\n\n/*\n\ta pushing of Ctrl + Alt + F12 over than two seconds can\n\tcause TVP's force suicide.\n\n\tthis thread also measures CPU clock.\n*/\n\n//---------------------------------------------------------------------------\n// TTVPEmergencyExitThread\n//---------------------------------------------------------------------------\nclass tTVPEmergencyExitThread : public tTVPThread\n{\n\ttTVPThreadEvent Event;\n\npublic:\n\ttTVPEmergencyExitThread() : tTVPThread(true)\n\t{\n#ifdef TJS_64BIT_OS\n\t\t// get pam\n\t\tULONGLONG pam = 1;// process affinity mask\n\t\tHANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());\n\t\tif(hp)\n\t\t{\n\t\t\tULONGLONG sam = 1;\n\t\t\tGetProcessAffinityMask(hp, (PDWORD_PTR)&pam, (PDWORD_PTR)&sam);\n\t\t\tCloseHandle(hp);\n\n\t\t\t// set tam to run only upon one processor (for proper working with rdtsc)\n\t\t\tULONGLONG tam = pam;\n\t\t\ttjs_int bit;\n\t\t\tfor(bit = 0; bit <= 31; bit++)\n\t\t\t{\n\t\t\t\tif(tam & (1ULL<<bit)) break;\n\t\t\t}\n\t\t\tbit ++;\n\t\t\tfor(; bit <= 31; bit++)\n\t\t\t{\n\t\t\t\ttam &= ~(1ULL<<bit);\n\t\t\t}\n\n\t\t\tSetThreadAffinityMask(GetHandle(), tam);\n\t\t}\n#else\n\t\t// get pam\n\t\tDWORD pam = 1;// process affinity mask\n\t\tHANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());\n\t\tif(hp)\n\t\t{\n\t\t\tDWORD sam = 1;\n\t\t\tGetProcessAffinityMask(hp, &pam, &sam);\n\t\t\tCloseHandle(hp);\n\n\t\t\t// set tam to run only upon one processor (for proper working with rdtsc)\n\t\t\tDWORD tam = pam;\n\t\t\ttjs_int bit;\n\t\t\tfor(bit = 0; bit <= 31; bit++)\n\t\t\t{\n\t\t\t\tif(tam & (1<<bit)) break;\n\t\t\t}\n\t\t\tbit ++;\n\t\t\tfor(; bit <= 31; bit++)\n\t\t\t{\n\t\t\t\ttam &= ~(1<<bit);\n\t\t\t}\n\n\t\t\tSetThreadAffinityMask(GetHandle(), tam);\n\t\t}\n#endif\n\t\tResume();\n\t}\n\n\t~tTVPEmergencyExitThread()\n\t{\n\t\tTerminate();\n\t\tEvent.Set();\n\t\tWaitFor();\n\t}\n\n\tvoid Execute(void);\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\nvoid tTVPEmergencyExitThread::Execute(void)\n{\n\tDWORD pushstarttime;\n\n\tDWORD prevtime = GetTickCount();\n\ttjs_uint64 prevtsc = TVPGetTSC();\n\n\twhile(!GetTerminated())\n\t{\n\t\tbool status =\n\t\t\t(GetAsyncKeyState(VK_CONTROL)&0x8000)&&\n\t\t\t(GetAsyncKeyState(VK_MENU)&0x8000)&&\n\t\t\t(GetAsyncKeyState(VK_F12)&0x8000);\n\n\t\tDWORD curtime = GetTickCount();\n\t\ttjs_uint64 curtsc = TVPGetTSC();\n\t\tTVPPushEnvironNoise(&curtime, sizeof(curtime));\n\t\tTVPPushEnvironNoise(&curtsc, sizeof(curtsc));\n\n\t\tif(TVPCPUClockAccuracy == ccaNotSet)\n\t\t{\n\t\t\tif(curtime - prevtime > 200)\n\t\t\t{\n\t\t\t\tif(prevtsc != curtsc && prevtsc && curtsc)\n\t\t\t\t{\n\t\t\t\t\tTVPCPUClock = (double)((curtsc - prevtsc) / 100) / (double)(curtime - prevtime) *\n\t\t\t\t\t\t0.1f;\n\t\t\t\t\tTVPCPUClockAccuracy = ccaRough;\n\t\t\t\t}\n\n\t\t\t\tprevtime = curtime;\n\t\t\t\tprevtsc = curtsc;\n\t\t\t}\n\t\t}\n\t\telse if(TVPCPUClockAccuracy == ccaRough)\n\t\t{\n\t\t\tif(curtime - prevtime > 20000)\n\t\t\t{\n\t\t\t\tif(prevtsc != curtsc && prevtsc && curtsc)\n\t\t\t\t{\n\t\t\t\t\tTVPCPUClock = (double)((curtsc - prevtsc) / 10000) /\n\t\t\t\t\t\t(double)(curtime - prevtime) * 10.0f;\n\t\t\t\t\tTVPCPUClockAccuracy = ccaAccurate;\n\t\t\t\t}\n\n\t\t\t\tprevtime = curtime;\n\t\t\t\tprevtsc = curtsc;\n\t\t\t}\n\t\t}\n\n\n\n\t\tif(!status)\n\t\t{\n\t\t\tpushstarttime = curtime;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(curtime  - pushstarttime > 3000)\n\t\t\t{\n\t\t\t\t// force suicide\n\t\t\t\tDWORD pid;\n\t\t\t\tGetWindowThreadProcessId(Application->GetHandle(), &pid);\n\t\t\t\tHANDLE hp=OpenProcess(PROCESS_TERMINATE, FALSE, pid);\n\t\t\t\tif(hp)\n\t\t\t\t{\n\t\t\t\t\tTerminateProcess(hp, 0);\n\t\t\t\t\tCloseHandle(hp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tMEMORYSTATUS status;\n\t\t\tstatus.dwLength = sizeof(status);\n\t\t\tGlobalMemoryStatus(&status);\n\t\t\tTVPPushEnvironNoise(&status, sizeof(status));\n\t\t}\n\n\t\tif(TVPCPUClockAccuracy == ccaNotSet)\n\t\t\tEvent.WaitFor(200);\n\t\telse\n\t\t\tEvent.WaitFor(500);\n#ifdef TJS_SUPPORT_VCL\n\t\tif(TVPSystemControlAlive && Application != NULL && Application->GetHandle ()!= NULL)\n\t\t{\n\t\t\tPostMessage(Application->GetHandle(), TVP_EV_KEEP_ALIVE, 0, 0);\n\t\t\t// Send wakeup message to the main window.\n\t\t\t// VCL sometimes waits message that never come (so hangs up).\n\t\t\t// This message will wake the VCL up.\n\t\t}\n#endif\n\t}\n}\n//---------------------------------------------------------------------------\nstatic std::auto_ptr<tTVPEmergencyExitThread>\n\tTVPEmergencyExitThread(new tTVPEmergencyExitThread);\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/environ/win32/EmergencyExit.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Emergency Exit Hotkey Handler\n//---------------------------------------------------------------------------\n#ifndef EmergencyExitH\n#define EmergencyExitH\n\nextern double TVPCPUClock;\nenum tTVPCPUClockAccuracy { ccaNotSet, ccaRough, ccaAccurate };\nextern tTVPCPUClockAccuracy TVPCPUClockAccuracy;\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/HintWindow.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Half-transparent Hint Window Support\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"HintWindow.h\"\n#include \"WindowFormUnit.h\"\n#include \"tvpgl.h\"\n\n//---------------------------------------------------------------------------\n// TVP_TB_SetGrayscalePalette\n//---------------------------------------------------------------------------\nstatic void TVP_TB_SetGrayscalePalette(Graphics::TBitmap *bmp)\n{\n\tint psize;\n\tint icol;\n\n\tpsize=256;\n\n\ticol=255/(psize-1);\n\n\tint i;\n\tint c=0;\n\n#pragma pack(push,1)\n\tstruct tagpal\n\t{\n\t\tWORD palversion;\n\t\tWORD numentries;\n\t\tPALETTEENTRY entry[256];\n\t} pal;\n#pragma pack(pop)\n\tpal.palversion = 0x300;\n\tpal.numentries = psize;\n\n\tfor(i=0;i<psize;i++)\n\t{\n\t\tif(c>=256) c=255;\n\t\tpal.entry[i].peRed=pal.entry[i].peGreen=pal.entry[i].peBlue=(BYTE)c;\n\t\tpal.entry[i].peFlags=0;\n\t\tc+=icol;\n\t}\n\tbmp->Palette = CreatePalette((LOGPALETTE*)&pal);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPHintWindowRegister\n//---------------------------------------------------------------------------\nstatic void TVPHintWindowRegister(void)\n{\n\tHintWindowClass=__classid(TTVPHintWindow); // register hint window class\n}\n#ifdef __BORLANDC__\n#pragma startup TVPHintWindowRegister\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Most Recent Hint Window\n//---------------------------------------------------------------------------\nstatic TTVPHintWindow *TVPMostRecentHintWindow = NULL;\n//---------------------------------------------------------------------------\nHDWP TVPShowHintWindowTop(HDWP hdwp)\n{\n\tif(TVPFullScreenedWindow != NULL && TVPMostRecentHintWindow)\n\t\thdwp = TVPMostRecentHintWindow->ShowTop(hdwp);\n\treturn hdwp;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TTVPHintWindow\n//---------------------------------------------------------------------------\n__fastcall TTVPHintWindow::TTVPHintWindow(TComponent *AOwner):\n\tTHintWindow(AOwner)\n{\n\tInit();\n}\n//---------------------------------------------------------------------------\n__fastcall TTVPHintWindow::TTVPHintWindow(HWND ParentWindow):\n\tTHintWindow(ParentWindow)\n{\n\tInit();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::Init(void)\n{\n\tBackBMP=new Graphics::TBitmap();\n}\n//---------------------------------------------------------------------------\n__fastcall TTVPHintWindow::~TTVPHintWindow()\n{\n\tTVPMostRecentHintWindow = NULL;\n\tdelete BackBMP;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::ActivateHint(const TRect &ARect,const AnsiString\n\t\tAHint)\n{\n\tSetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0,\n\t\t0, SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);\n\n\t// change the window style\n\tSetWindowLong(Handle,GWL_STYLE,GetWindowLong(Handle,GWL_STYLE) & ~WS_BORDER);\n\n\t// adjust position\n\tTRect Rect=ARect;\n\n\tCaption=AHint;\n\tRect.Bottom+=4;\n\tUpdateBoundsRect(Rect);\n\n\tif(Rect.Top + Height > Screen->DesktopHeight)\n\t\tRect.Top = Screen->DesktopHeight - Height;\n\tif(Rect.Left + Width > Screen->DesktopWidth)\n\t\tRect.Left = Screen->DesktopWidth - Width;\n\tif(Rect.Left < Screen->DesktopLeft)\n\t\tRect.Left = Screen->DesktopLeft;\n\tif(Rect.Bottom < Screen->DesktopTop)\n\t\tRect.Bottom = Screen->DesktopTop;\n\n\t// save bitmap which to be laid under the window\n\tBackBMP->Width=Rect.Right-Rect.Left;\n\tBackBMP->Height=Rect.Bottom-Rect.Top;\n\tBackBMP->PixelFormat=pf24bit;\n\n\tHDC dc = GetDC(0);\n\n\tTRect destrect;\n\tdestrect.Left=0;\n\tdestrect.Top=0;\n\tdestrect.Right=BackBMP->Width;\n\tdestrect.Bottom=BackBMP->Height;\n\n\tBitBlt(BackBMP->Canvas->Handle,\n\t\t0, 0, BackBMP->Width, BackBMP->Height,\n\t\tdc, Rect.Left, Rect.Top, SRCCOPY);\n\n\tReleaseDC(0, dc);\n\n\tBackBMP->PixelFormat = pf32bit;\n\n\t// window reposition and showing\n\tSetWindowPos(Handle, HWND_TOPMOST, Rect.Left, Rect.Top, Width,\n\t\tHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE);\n\n\tTVPMostRecentHintWindow = this;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::ActivateHintData(const TRect &Rect,\n\tconst AnsiString AHint,void *AData)\n{\n\tActivateHint(Rect,AHint);\n}\n//---------------------------------------------------------------------------\nTRect __fastcall TTVPHintWindow::CalcHintRect(int MaxWidth,\n\tconst AnsiString AHint, void *AData)\n{\n\tRECT result;\n\tresult.left=0;\n\tresult.top=0;\n\tresult.right=MaxWidth;\n\tresult.bottom=0;\n\tDrawText(Canvas->Handle,AHint.c_str(), -1, &result,\n\t\tDT_CALCRECT | DT_LEFT | DT_WORDBREAK | DT_NOPREFIX);\n\tresult.right+=6;\n\tresult.bottom+=2;\n\treturn TRect(result);\n}\n//---------------------------------------------------------------------------\nbool __fastcall TTVPHintWindow::IsHintMsg(tagMSG &Msg)\n{\n\tbool b = THintWindow::IsHintMsg(Msg);\n\tif(b)\n\t{\n\t\t// to preventing disappering hint window by keys\n\t\tif((Msg.message >= WM_KEYFIRST) && (Msg.message <= WM_KEYLAST))\n\t\t\treturn false;\n\t}\n\treturn b;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::Paint(void)\n{\n\t// create bitmap to be piled with a mask bitmap\n\tGraphics::TBitmap *mask=new Graphics::TBitmap();\n\tGraphics::TBitmap *disp=new Graphics::TBitmap();\n\tGraphics::TBitmap *main=new Graphics::TBitmap();\n\n\t// set pixelformat and size\n\tmask->PixelFormat=pf8bit;\n\tTVP_TB_SetGrayscalePalette(mask);\n\tmask->Width=BackBMP->Width;\n\tmask->Height=BackBMP->Height;\n\tdisp->PixelFormat=pf32bit;\n\tdisp->Width=BackBMP->Width;\n\tdisp->Height=BackBMP->Height;\n\tmain->PixelFormat=pf32bit;\n\tmain->Width=BackBMP->Width;\n\tmain->Height=BackBMP->Height;\n\n\t// set up bmprect ...\n\tRECT bmprect;\n\tbmprect.left=0;\n\tbmprect.top=0;\n\tbmprect.right=BackBMP->Width;\n\tbmprect.bottom=BackBMP->Height;\n\n\t// fill mask with gray\n\tfor(int i = 0; i<mask->Height; i++)\n\t\tmemset(mask->ScanLine[i], 192, mask->Width);\n\n\t// fill main with clInfoBk\n\tmain->Canvas->Brush->Color=clInfoBk;\n\tmain->Canvas->Brush->Style=bsSolid;\n\tmain->Canvas->FillRect(TRect(bmprect)); \n\n\t// draw text\n\tmask->Canvas->Font=Canvas->Font;\n\tmain->Canvas->Font=Canvas->Font;\n\tmask->Canvas->Brush->Style=bsClear;\n\tmain->Canvas->Brush->Style=bsClear;\n\tmain->Canvas->Font->Color=clInfoBk;\n\tRECT r=RECT(ClientRect);\n\tr.left+=3;\n\tr.right+=3;\n\tr.top+=3;\n\tr.bottom+=3;\n\n\tmain->Canvas->Font->Color=clInfoBk;\n\tmask->Canvas->Font->Color=(TColor)0x00e0e0e0;\n\t{\n\t\tRECT r2=r;\n\t\tr2.left --;\n\t\tr2.top --;\n\t\tr2.right --;\n\t\tr2.bottom --;\n\t\tDrawText(mask->Canvas->Handle, Caption.c_str(), -1, &r2,\n\t\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\t}\n\n\t{\n\t\tRECT r2=r;\n\t\tr2.left ++;\n\t\tr2.top --;\n\t\tr2.right ++;\n\t\tr2.bottom --;\n\t\tDrawText(mask->Canvas->Handle, Caption.c_str(), -1, &r2,\n\t\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\t}\n\n\t{\n\t\tRECT r2=r;\n\t\tr2.left --;\n\t\tr2.top ++;\n\t\tr2.right --;\n\t\tr2.bottom ++;\n\t\tDrawText(mask->Canvas->Handle, Caption.c_str(), -1, &r2,\n\t\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\t}\n\n\t{\n\t\tRECT r2=r;\n\t\tr2.left ++;\n\t\tr2.top ++;\n\t\tr2.right ++;\n\t\tr2.bottom ++;\n\t\tDrawText(mask->Canvas->Handle, Caption.c_str(), -1, &r2,\n\t\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\t}\n\n\n\tmain->Canvas->Font->Color=clInfoText;\n\tDrawText(main->Canvas->Handle, Caption.c_str(), -1, &r,\n\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\n\tmask->Canvas->Font->Color=(TColor)0x00ffffff;\n\n\tDrawText(mask->Canvas->Handle, Caption.c_str(), -1, &r,\n\t\tDT_LEFT | DT_NOPREFIX | DT_WORDBREAK);\n\n\t// draw frame\n\tmask->Canvas->Pen->Width=1;\n\tmask->Canvas->Pen->Color=(TColor)0x00ffffff;\n\tmask->Canvas->MoveTo(0,0);\n\tmask->Canvas->LineTo(mask->Width-1,0);\n\tmask->Canvas->LineTo(mask->Width-1,mask->Height-1);\n\tmask->Canvas->LineTo(0,mask->Height-1);\n\tmask->Canvas->LineTo(0,0);\n\n\t// bind\n\tfor(int i = 0; i<mask->Height; i++)\n\t\tTVPBindMaskToMain((tjs_uint32*)main->ScanLine[i],\n\t\t\t(const tjs_uint8*)mask->ScanLine[i], mask->Width);\n\n\t// copy BackBMP to disp\n\tfor(int i = 0; i<mask->Height; i++)\n\t\tmemcpy(disp->ScanLine[i],\n\t\t\tBackBMP->ScanLine[i], BackBMP->Width * sizeof(tjs_uint32));\n\n\t// pile main to disp via pixel alpha blending\n\tfor(int i = 0; i<mask->Height; i++)\n\t\tTVPAlphaBlend((tjs_uint32*)disp->ScanLine[i],\n\t\t\t(const tjs_uint32*)main->ScanLine[i], mask->Width);\n\n\t// draw to the canvas\n\tCanvas->Draw(0, 0, disp);\n\n\t// delete bitmaps\n\tdelete disp;\n\tdelete mask;\n\tdelete main;\n\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::WMNCPaint(TMessage &message)\n{\n\t// nothing to do\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPHintWindow::NCPaint(HDC dc)\n{\n}\n//---------------------------------------------------------------------------\nHDWP __fastcall TTVPHintWindow::ShowTop(HDWP hdwp)\n{\n\tif(HandleAllocated() && Visible)\n\t{\n\t\thdwp = DeferWindowPos(hdwp, Handle, HWND_TOPMOST, 0, 0, 0, 0,\n\t\t\tSWP_NOSENDCHANGING|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREPOSITION|\n\t\t\tSWP_NOSIZE|WM_SHOWWINDOW);\n\t\tInvalidate();\n\t}\n\treturn hdwp;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/environ/win32/HintWindow.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Half-transparent Hint Window Support\n//---------------------------------------------------------------------------\n#ifndef HintWindowH\n#define HintWindowH\n#include <vcl.h>\n#include <controls.hpp>\n//---------------------------------------------------------------------------\nextern HDWP TVPShowHintWindowTop(HDWP hdwp);\n//---------------------------------------------------------------------------\nclass TTVPHintWindow : public THintWindow\n{\n\tvoid __fastcall Init();\n\nprotected:\n\n\tvoid __fastcall virtual WMNCPaint(TMessage &Message);\n\tvoid __fastcall NCPaint(HDC dc);\n\nBEGIN_MESSAGE_MAP\n\tVCL_MESSAGE_HANDLER(WM_NCPAINT, TMessage, WMNCPaint)\n\tVCL_MESSAGE_HANDLER(WM_ERASEBKGND,TMessage,WMNCPaint)\nEND_MESSAGE_MAP(THintWindow)\n\n\tGraphics::TBitmap *BackBMP;\n\npublic:\n#ifdef __BORLANDC__\n\t__fastcall virtual TTVPHintWindow(TComponent *AOwner);\n\t__fastcall virtual TTVPHintWindow(HWND ParentWindow);\n#else\n\tTTVPHintWindow(TComponent *AOwner);\n\tTTVPHintWindow(HWND ParentWindow);\n#endif\n\t__fastcall virtual ~TTVPHintWindow();\n\n\tvirtual void __fastcall ActivateHint(const TRect &Rect,const AnsiString\n\t\tAHint);\n\tvirtual void __fastcall ActivateHintData(const TRect &Rect,const AnsiString\n\t\tAHint,void *AData);\n\tvirtual TRect __fastcall CalcHintRect(int MaxWidth,const AnsiString AHint,\n\t\tvoid *AData);\n\tvirtual bool __fastcall IsHintMsg(tagMSG &Msg);\n\n\tvoid __fastcall Paint(void);\n\n\tHDWP __fastcall ShowTop(HDWP hdwp);\n};\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/ImeControl.h",
    "content": "\n\n#ifndef __IME_CONTROL_H__\n#define __IME_CONTROL_H__\n\n//#include <imm.h>\n#include \"TVPSysFont.h\"\n\nclass ImeControl {\npublic:\n\tenum {\n\t\tModeDisable,\n\t\tModeClose,\n\t\tModeOpen,\n\t\tModeDontCare,\n\t\tModeSAlpha,\n\t\tModeAlpha,\n\t\tModeHira,\n\t\tModeSKata,\n\t\tModeKata,\n\t\tModeChinese,\n\t\tModeSHanguel,\n\t\tModeHanguel,\n\t};\n\nprivate:\n\tHWND hWnd_;\n\tHIMC hOldImc_;\n\tbool default_open_;\n\tint mode_;\n\npublic:\n\tImeControl( HWND hWnd ) {\n\t\thWnd_ = hWnd;\n\t\thOldImc_ = INVALID_HANDLE_VALUE;\n\t\tmode_ = ModeDontCare;\n\t\tdefault_open_ = IsOpen();\n\t}\n\t~ImeControl() {\n\t}\n\tbool IsOpen() {\n\t\tif( hOldImc_ != INVALID_HANDLE_VALUE ) return false;\n\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\tBOOL result = ::ImmGetOpenStatus(hImc);\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t\treturn 0!=result;\n\t}\n\tvoid Open() {\n\t\tEnable();\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n\tvoid Close() {\n\t\tEnable();\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmSetOpenStatus(hImc,FALSE);\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n\tbool IsEnableThisLocale() {\n\t\tHKL hKl = ::GetKeyboardLayout(0);\n\t\treturn 0!=::ImmIsIME(hKl);\n\t}\n\t// ImmSetStatusWindowPos ֐ĂяoƁAAvP[V IMN_SETSTATUSWINDOWPOS bZ[WM܂B\n\tvoid SetStatusPosition( int x, int y ) {\n\t\tPOINT pt = {x,y};\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmSetStatusWindowPos( hImc, &pt );\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n\tvoid GetStatusPosition( int &x, int &y ) {\n\t\tPOINT pt = {0,0};\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmGetStatusWindowPos( hImc, &pt );\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t\tx = pt.x;\n\t\ty = pt.y;\n\t}\n\tvoid Reset() {\n\t\tif( mode_ == ModeDisable ) {\n\t\t\tOpen();\n\t\t}\n\t}\n\t/**\n\t ̃XbhIME𖳌ɂ\n\t */\n\tvoid Disable() {\n\t\tif( hOldImc_ == INVALID_HANDLE_VALUE ) {\n\t\t\thOldImc_ = ::ImmAssociateContext(hWnd_,0);\n\t\t}\n\t}\n\tvoid Enable() {\n\t\tif( hOldImc_ != INVALID_HANDLE_VALUE ) {\n\t\t\t::ImmAssociateContext(hWnd_,hOldImc_);\n\t\t\thOldImc_ = INVALID_HANDLE_VALUE;\n\t\t}\n\t}\n\t// ̊֐ĂяoƁAAvP[V IMN_SETCOMPOSITIONFONT bZ[WM܂B\n\tvoid SetCompositionFont( tTVPSysFont* font ) {\n\t\tLOGFONT logfont={0};\n\t\tfont->GetFont(&logfont);\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmSetCompositionFont( hImc, &logfont );\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n\tvoid SetCompositionWindow( int x, int y ) {\n\t\tCOMPOSITIONFORM pos;\n\t\tpos.dwStyle = CFS_POINT;\n\t\tpos.ptCurrentPos.x = x;\n\t\tpos.ptCurrentPos.y = y;\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmSetCompositionWindow( hImc, &pos );\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n\tvoid GetCompositionWindow( int &x, int &y ) {\n\t\tCOMPOSITIONFORM pos = {0};\n\t\tpos.dwStyle = CFS_POINT;\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\t::ImmGetCompositionWindow( hImc, &pos );\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t\tx = pos.ptCurrentPos.x;\n\t\ty = pos.ptCurrentPos.y;\n\t}\n\t/**\n\t * conversion : ̓[h̒lw肵܂B\n\t * \t\tIME_CMODE_ALPHANUMERIC(0x0000)\tp[h\n\t * \t\tIME_CMODE_NATIVE(0x0001)\t\tΉ(ON)Ep(OFF) [h\n\t * \t\tIME_CMODE_CHINESE\n\t * \t\tIME_CMODE_HANGEUL\n\t * \t\tIME_CMODE_JAPANESE ł`Ă\n\t * \t\tIME_CMODE_KATAKANA(0x0002)\t\tJ^Ji(ON)EЂ炪(OFF) [h\n\t * \t\tIME_CMODE_FULLSHAPE(0x0008)\t\tSp[h\n\t * \t\tIME_CMODE_ROMAN(0x0010)\t\t\t[}[h\n\t * \t\tIME_CMODE_CHARCODE(0x0020)\t\tLN^̓[h\n\t * \t\tIME_CMODE_HANJACONVERT(0x0040)\tnOϊ[h\n\t * \t\tIME_CMODE_SOFTKBD(0x0080)\t\t\\tgL[{[h[h\n\t * \t\tIME_CMODE_NOCONVERSION(0x0100)\tϊ[h\n\t * \t\tIME_CMODE_EUDC(0x0200)\t\t\tEUDϊ[h\n\t * \t\tIME_CMODE_SYMBOL(0x0400)\t\tV{[h\n\t * sentence : ϊ[h̒lw肵܂B\n\t * \t\tIME_SMODE_NONE(0x0000)\t\t\tϊ\n\t * \t\tIME_SMODE_PLURALCLAUSE(0x0001)\tD\n\t * \t\tIME_SMODE_SINGLECONVERT(0x0002)\tPϊ\n\t * \t\tIME_SMODE_AUTOMATIC(0x0004)\t\tϊ\n\t * \t\tIME_SMODE_PHRASEPREDICT(0x0008)\tAߕϊ\n\t */\n\t/*\n\tbool SetConversionStatus( int conversion, int sentence ) {\n\t\treturn 0!=::ImmSetConversionStatus( hImc_, conversion, sentence );\n\t}\n\t*/\n\t/**\n\t * @param mode : \nModeDisable w肷ƁAIME͖ɂȂ܂BIMEgp͂͂ł܂񂵁A[ȖłIMELɂ邱Ƃ͂ł܂B : Disable\nModeClose w肷ƁAIME͖ɂȂ܂BimDisableƈقȂA[ȖIMELɂ邱Ƃł܂B : Close\nModeOpen w肷ƁAIME͗LɂȂ܂B : Open\nModeDontCare w肷ƁAIME̗L/̏Ԃ́AȌԂp܂B[ȖɂIMELɂ薳ɂ肷邱Ƃł܂B{͂ɂẮAp/Sp[UɎRɓ͂ꍇ̈ʓIȃ[hłB\nModeSAlpha w肷ƁAIME͗LɂȂApAt@xbg̓[hɂȂ܂B : IME_CMODE_ALPHANUMERIC\nModeAlpha w肷ƁAIME͗LɂȂASpAt@xbg̓[hɂȂ܂B : IME_CMODE_FULLSHAPE\nModeHira w肷ƁAIME͗LɂȂAЂ炪ȓ̓[hɂȂ܂B\nModeSKata w肷ƁAIME͗LɂȂApJ^Ji̓[hɂȂ܂B : IME_CMODE_KATAKANA\nModeKata w肷ƁAIME͗LɂȂASpJ^Ji̓[hɂȂ܂B : IME_CMODE_KATAKANA IME_CMODE_NATIVE\nModeChinese w肷ƁAIME͗LɂȂA2oCg͂󂯕t郂[hɂȂ܂B{ł͎gpł܂B : IME_CMODE_CHINESE\nModeSHanguel w肷ƁAIME͗LɂȂA1oCg؍͂󂯕t郂[hɂȂ܂B{ł͎gpł܂B : IME_CMODE_HANJACONVERT\nModeHanguel w肷ƁAIME͗LɂȂA2oCg؍͂󂯕t郂[hɂȂ܂B{ł͎gpł܂B : IME_CMODE_HANGEUL\n\t */\n\tvoid SetIme( int mode ) {\n\t\tmode_ = mode;\n\t\tHIMC hImc = ::ImmGetContext(hWnd_);\n\t\tDWORD conversion, sentence;\n\t\t::ImmGetConversionStatus( hImc, &conversion, &sentence );\n\t\tswitch( mode ) {\n\t\tcase ModeDisable:\n\t\t\tif( hOldImc_ == INVALID_HANDLE_VALUE ) {\n\t\t\t\thOldImc_ = ::ImmAssociateContext(hWnd_,0);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ModeClose:\n\t\t\t::ImmSetOpenStatus(hImc,FALSE);\n\t\t\tbreak;\n\t\tcase ModeOpen:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\tbreak;\n\t\tcase ModeDontCare:\n\t\t\tbreak;\n\t\tcase ModeSAlpha:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_ALPHANUMERIC, sentence );\n\t\t\tbreak;\n\t\tcase ModeAlpha:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_ALPHANUMERIC | IME_CMODE_FULLSHAPE, sentence );\n\t\t\tbreak;\n\t\tcase ModeHira:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, sentence );\n\t\t\tbreak;\n\t\tcase ModeSKata:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE | IME_CMODE_KATAKANA, sentence );\n\t\t\tbreak;\n\t\tcase ModeKata:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE | IME_CMODE_KATAKANA | IME_CMODE_FULLSHAPE, sentence );\n\t\t\tbreak;\n\t\tcase ModeChinese:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, sentence );\n\t\t\tbreak;\n\t\tcase ModeSHanguel:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE, sentence );\n\t\t\tbreak;\n\t\tcase ModeHanguel:\n\t\t\t::ImmSetOpenStatus(hImc,TRUE);\n\t\t\t::ImmSetConversionStatus( hImc, IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, sentence );\n\t\t\tbreak;\n\t\t}\n\t\t::ImmReleaseContext(hWnd_,hImc);\n\t}\n};\n\n\n#endif // __IME_CONTROL_H__\n"
  },
  {
    "path": "src/core/environ/win32/MainFormUnit.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Main Window (Controller)\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n#include \"MainFormUnit.h\"\n#include \"PadFormUnit.h\"\n#include \"ConsoleFormUnit.h\"\n#include \"EventIntf.h\"\n#include \"MsgIntf.h\"\n#include \"WindowFormUnit.h\"\n#include \"SysInitIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"WatchFormUnit.h\"\n#include \"WindowIntf.h\"\n#include \"WindowImpl.h\"\n#include \"HaltWarnFormUnit.h\"\n#include \"StorageIntf.h\"\n#include \"Random.h\"\n#include \"EmergencyExit.h\" // for TVPCPUClock\n#include \"DebugIntf.h\"\n#include \"FontSelectFormUnit.h\"\n#include \"HintWindow.h\"\n#include \"VersionFormUnit.h\"\n#include \"WaveImpl.h\"\n#include \"SystemImpl.h\"\n\n//---------------------------------------------------------------------------\n#ifdef __BORLANDC__\n#pragma package(smart_init)\n#pragma resource \"*.dfm\"\n#else\n#include \"MainFormUnit_dfm.h\"\n#endif\n#include \"TickCount.h\"\nTTVPMainForm *TVPMainForm = NULL;\nbool TVPMainFormAlive = false;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Get whether debugging support windows can be shown\n//---------------------------------------------------------------------------\nstatic bool TVPDebugSupportShowableGot = false;\nstatic bool TVPDebugSupportShowable = true;\nstatic bool TVPGetDebugSupportShowable()\n{\n\tif(TVPDebugSupportShowableGot) return TVPDebugSupportShowable;\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-debugwin\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"no\"))\n\t\t\tTVPDebugSupportShowable = false;\n\t}\n\n\tTVPDebugSupportShowableGot = true;\n\n\treturn TVPDebugSupportShowable;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Get whether to control main thread priority or to insert wait\n//---------------------------------------------------------------------------\nstatic bool TVPMainThreadPriorityControlInit = false;\nstatic bool TVPMainThreadPriorityControl = false;\nstatic bool TVPGetMainThreadPriorityControl()\n{\n\tif(TVPMainThreadPriorityControlInit) return TVPMainThreadPriorityControl;\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-lowpri\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t\tTVPMainThreadPriorityControl = true;\n\t}\n\n\tTVPMainThreadPriorityControlInit = true;\n\n\treturn TVPMainThreadPriorityControl;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Get whether the modal windows are rearranged in full-screen\n// (to avoid the modal window hides behind the main window)\n//---------------------------------------------------------------------------\n//static bool TVPModalWindowRearrangeInFullScreenInit = false;\n//static bool TVPModalWindowRearrangeInFullScreen = false;\nstatic bool TVPGetModalWindowRearrangeInFullScreen()\n{\n\treturn true;\n/*\n\tif(TVPModalWindowRearrangeInFullScreenInit)\n\t\treturn TVPModalWindowRearrangeInFullScreen;\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-remodal\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t\tTVPModalWindowRearrangeInFullScreen = true;\n\t}\n\n\tTVPModalWindowRearrangeInFullScreenInit = true;\n\n\treturn TVPModalWindowRearrangeInFullScreen;\n*/\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Global Definitions\n//---------------------------------------------------------------------------\nTTVPPadForm *TVPMainPadForm = NULL;\nTTVPConsoleForm *TVPMainConsoleForm = NULL;\nTTVPWatchForm * TVPMainWatchForm = NULL;\n//---------------------------------------------------------------------------\nstatic void TVPUninitEnvironProfile();\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TTVPMainForm\n//---------------------------------------------------------------------------\n#include \"float.h\"\n__fastcall TTVPMainForm::TTVPMainForm(TComponent* Owner)\n\t: TForm(Owner)\n{\n#ifndef __BORLANDC__\n\tinit(this);\n#endif\n\tContinuousEventCalling = false;\n\tAutoShowConsoleOnError = false;\n\tApplicationStayOnTop = false;\n\tApplicationActivating = true;\n\tApplicationNotMinimizing = true;\n\tLastCloseClickedTick = 0;\n\tLastShowModalWindowSentTick = 0;\n\tLastRehashedTick = 0;\n#ifdef __BORLANDC__\n\tApplication->OnIdle = ApplicationIdle;\n\tApplication->OnActivate = ApplicationActivate;\n\tApplication->OnDeactivate = ApplicationDeactivate;\n\tApplication->OnMinimize = ApplicationMinimize;\n\tApplication->OnRestore = ApplicationRestore;\n#else\n\tApplication->OnIdle = EVENT_FUNC2(TTVPMainForm, ApplicationIdle);\n\tApplication->OnActivate = EVENT_FUNC1(TTVPMainForm, ApplicationActivate);\n\tApplication->OnDeactivate = EVENT_FUNC1(TTVPMainForm, ApplicationDeactivate);\n\tApplication->OnMinimize = EVENT_FUNC1(TTVPMainForm, ApplicationMinimize);\n\tApplication->OnRestore = EVENT_FUNC1(TTVPMainForm, ApplicationRestore);\n#endif\n\t// get command-line options which specifies global hot keys.\n\tSetHotKey(ShowControllerMenuItem, TJS_W(\"-hkcontroller\"));\n\tSetHotKey(ShowScriptEditorMenuItem, TJS_W(\"-hkeditor\"));\n\tSetHotKey(ShowWatchMenuItem, TJS_W(\"-hkwatch\"));\n\tSetHotKey(ShowConsoleMenuItem, TJS_W(\"-hkconsole\"));\n\tSetHotKey(ShowAboutMenuItem, TJS_W(\"-hkabout\"));\n\tSetHotKey(CopyImportantLogMenuItem, TJS_W(\"-hkclipenvinfo\"));\n\n\n\t// read previous state from environ profile\n\ttTVPProfileHolder *prof = TVPGetEnvironProfile();\n\tTVPEnvironProfileAddRef();\n\tstatic AnsiString section(\"controller\");\n\tint n;\n\tn = prof->ReadInteger(section, \"left\", -1);\n\tif(n != -1) Left = n;\n\tn = prof->ReadInteger(section, \"top\", -1);\n\tif(n != -1) Top = n;\n\tn = prof->ReadInteger(section, \"stayontop\", 0);\n\tFormStyle = n ? fsStayOnTop : fsNormal;\n\n\tif(Left > Screen->Width) Left = Screen->Width - Width;\n\tif(Top > Screen->Height) Top = Screen->Height - Height;\n\n\tsection = \"console\";\n\tn = prof->ReadInteger(section, \"autoshowonerror\", 0);\n\tAutoShowConsoleOnError = (bool)n;\n\n\tTVPMainFormAlive = true;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::FormDestroy(TObject *Sender)\n{\n\t// write to environ profile\n\tTVPMainFormAlive = false;\n\n\ttTVPProfileHolder *prof = TVPGetEnvironProfile();\n\tstatic AnsiString section(\"controller\");\n\tprof->WriteInteger(section, \"left\", Left);\n\tprof->WriteInteger(section, \"top\", Top);\n\tprof->WriteInteger(section, \"stayontop\", FormStyle == fsStayOnTop);\n\tsection = \"console\";\n\tprof->WriteInteger(section, \"autoshowonerror\", (int)AutoShowConsoleOnError);\n\tTVPEnvironProfileRelease(); // this may cause writing profile to disk\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::FormClose(TObject *Sender,\n\t  TCloseAction &Action)\n{\n\t//\n\tif(TVPGetWindowCount() == 0)\n\t{\n\t\t// no window\n\t\tAction = caFree;\n\t}\n\telse\n\t{\n\t\tAction = caNone;\n\t\tVisible = false;\n\t\tif(TVPMainWindow)\n\t\t\tTVPMainWindow->SendCloseMessage();\n\t}\n}\n//---------------------------------------------------------------------------\nTShortCut TTVPMainForm::GetHotKeyFromOption(TShortCut def, const tjs_char * optname)\n{\n\ttTJSVariant val;\n\tif(TVPGetCommandLine(optname, &val))\n\t{\n\t\tTShortCut sc;\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"\"))\n\t\t{\n\t\t\tsc = (TShortCut)0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsc = TextToShortCut(str.AsAnsiString());\n\t\t\tif(sc == 0)\n\t\t\t\tTVPThrowExceptionMessage(TVPInvalidCommandLineParam,\n\t\t\t\t\toptname, str);\n\t\t}\n\t\treturn sc;\n\t}\n\treturn def;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::SetHotKey(TMenuItem *item, const tjs_char * optname)\n{\n\titem->ShortCut = GetHotKeyFromOption(item->ShortCut, optname);\n}\n//---------------------------------------------------------------------------\nbool TTVPMainForm::CanHideAnyWindow()\n{\n\tint viscount = 0;\n\tfor(int i = 0; i < Screen->FormCount; i++)\n\t{\n\t\tif(Screen->Forms[i]->Visible) viscount++;\n\t}\n\treturn viscount >=2;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::ShowController()\n{\n\t// show self\n\tif(TVPGetDebugSupportShowable())\n\t{\n\t\tif(Visible)\n\t\t{\n\t\t\t if(CanHideAnyWindow()) Visible = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVisible = true;\n\t\t\tBringToFront();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowControllerMenuItemClick(TObject *Sender)\n{\n\tShowController();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowScriptEditorButtonClick(TObject *Sender)\n{\n\tif(TVPGetDebugSupportShowable())\n\t{\n\t\tif(TVPMainPadForm && TVPMainPadForm->Visible)\n\t\t{\n\t\t\tif(CanHideAnyWindow())\n\t\t\t{\n\t\t\t\tTVPMainPadForm->Visible = false;\n\t\t\t\tShowScriptEditorButton->Down = false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPMainPadForm)\n\t\t\t{\n\t\t\t\tTVPMainPadForm = new TTVPPadForm(Application, true);\n\t\t\t\tTVPMainPadForm->Caption = ttstr(TVPMainCDPName).AsAnsiString();\n\t\t\t}\n\t\t\tTVPMainPadForm->Visible = true;\n\t\t\tShowScriptEditorButton->Down = true;\n\t\t\tTVPMainPadForm->BringToFront();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowWatchButtonClick(TObject *Sender)\n{\n\tif(TVPGetDebugSupportShowable())\n\t{\n\t\tif(TVPMainWatchForm && TVPMainWatchForm->Visible)\n\t\t{\n\t\t\tif(CanHideAnyWindow())\n\t\t\t{\n\t\t\t\tTVPMainWatchForm->Visible = false;\n\t\t\t\tShowWatchButton->Down = false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPMainWatchForm)\n\t\t\t{\n\t\t\t\tTVPMainWatchForm = new TTVPWatchForm(Application);\n\t\t\t}\n\t\t\tTVPMainWatchForm->Visible = true;\n\t\t\tTVPMainWatchForm->BringToFront();\n\t\t\tShowWatchButton->Down = true;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowConsoleButtonClick(TObject *Sender)\n{\n\tif(TVPGetDebugSupportShowable())\n\t{\n\t\tif(TVPMainConsoleForm && TVPMainConsoleForm->Visible)\n\t\t{\n\t\t\tif(CanHideAnyWindow())\n\t\t\t{\n\t\t\t\tTVPMainConsoleForm->Visible = false;\n\t\t\t\tShowConsoleButton->Down = false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPMainConsoleForm)\n\t\t\t{\n\t\t\t\tTVPMainConsoleForm = new TTVPConsoleForm(Application);\n\t\t\t}\n\t\t\tTVPMainConsoleForm->Visible = true;\n\t\t\tTVPMainConsoleForm->BringToFront();\n\t\t\tShowConsoleButton->Down = true;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowOnTopMenuItemClick(TObject *Sender)\n{\n\tFormStyle = FormStyle == fsStayOnTop ? fsNormal : fsStayOnTop;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::SetConsoleVisible(bool b)\n{\n\tif(b)\n\t{\n\t\tif(!TVPMainConsoleForm)\n\t\t{\n\t\t\tTVPMainConsoleForm = new TTVPConsoleForm(Application);\n\t\t}\n\t\tTVPMainConsoleForm->Visible = true;\n\t\tShowConsoleButton->Down = true;\n\t}\n\telse\n\t{\n\t\tif(TVPMainConsoleForm)\n\t\t\tTVPMainConsoleForm->Visible = false;\n\t\tShowConsoleButton->Down = false;\n\t}\n}\n//---------------------------------------------------------------------------\nbool TTVPMainForm::GetConsoleVisible()\n{\n\tif(TVPMainConsoleForm)\n\t\treturn TVPMainConsoleForm->Visible;\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyConsoleHiding()\n{\n\tShowConsoleButton->Down = false;\n}\n//---------------------------------------------------------------------------\nbool TTVPMainForm::GetScriptEditorVisible()\n{\n\tif(TVPMainPadForm) return TVPMainPadForm->Visible;\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyScriptEditorHiding()\n{\n\tShowScriptEditorButton->Down = false;\n}\n//---------------------------------------------------------------------------\nbool TTVPMainForm::GetWatchVisible()\n{\n\tif(TVPMainWatchForm) return TVPMainWatchForm->Visible;\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyWatchHiding()\n{\n\tShowWatchButton->Down = false;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ExitButtonClick(TObject *Sender)\n{\n\tApplication->Terminate();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::PopupMenuPopup(TObject *Sender)\n{\n\tShowOnTopMenuItem->Checked = FormStyle == fsStayOnTop;\n\tShowScriptEditorMenuItem->Checked = GetScriptEditorVisible();\n\tShowWatchMenuItem->Checked = GetWatchVisible();\n\tShowConsoleMenuItem->Checked = GetConsoleVisible();\n\tEnableEventMenuItem->Checked = EventButton->Down;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::EnableEventMenuItemClick(TObject *Sender)\n{\n\tTVPSetSystemEventDisabledState(EventButton->Down);\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::EventButtonClick(TObject *Sender)\n{\n\tTVPSetSystemEventDisabledState(!EventButton->Down);\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ShowAboutMenuItemClick(TObject *Sender)\n{\n    TVPShowVersionForm();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::CopyImportantLogMenuItemClick(\n\t  TObject *Sender)\n{\n\tTVPCopyImportantLogToClipboard();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::DumpMenuItemClick(TObject *Sender)\n{\n\tTVPDumpScriptEngine();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::CreateMessageMapFileMenuItemClick(\n\t  TObject *Sender)\n{\n\ttry\n\t{\n\t\tttstr fn = TVPGetAppPath() + TJS_W(\"msgmap.tjs\");\n\t\tTVPGetLocalName(fn);\n\t\tMessageMapFileSaveDialog->FileName = fn.AsAnsiString();\n\t}\n\tcatch(...)\n\t{\n\t\tMessageMapFileSaveDialog->FileName = \"msgmap.tjs\";\n\t}\n\n\tif(MessageMapFileSaveDialog->Execute())\n\t{\n\t\tTVPCreateMessageMapFile(MessageMapFileSaveDialog->FileName);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::RestartScriptEngineMenuItemClick(TObject *Sender)\n{\n\tTVPRestartScriptEngine();\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::InvokeEvents()\n{\n\tCallDeliverAllEventsOnIdle();\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::CallDeliverAllEventsOnIdle()\n{\n\t::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0);\n//\tif(SystemWatchTimer->Interval != 50)\n//\t\tSystemWatchTimer->Interval = 50;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::BeginContinuousEvent()\n{\n\tif(!ContinuousEventCalling)\n\t{\n\t\tContinuousEventCalling = true;\n\t\tInvokeEvents();\n\t\tif(TVPGetMainThreadPriorityControl())\n\t\t{\n\t\t\t// make main thread priority lower\n\t\t\tSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::EndContinuousEvent()\n{\n\tif(ContinuousEventCalling)\n\t{\n\t\tContinuousEventCalling = false;\n\t\tif(TVPGetMainThreadPriorityControl())\n\t\t{\n\t\t\t// make main thread priority normal\n\t\t\tSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyCloseClicked()\n{\n\t// close Button is clicked\n\tLastCloseClickedTick = TVPGetRoughTickCount32();\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyEventDelivered()\n{\n\t// called from event system, notifying the event is delivered.\n\tLastCloseClickedTick = 0;\n\tif(TVPHaltWarnForm) delete TVPHaltWarnForm, TVPHaltWarnForm = NULL;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifyHaltWarnFormClosed()\n{\n\tLastCloseClickedTick = 0;\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::NotifySystemError()\n{\n\tif(AutoShowConsoleOnError) SetConsoleVisible(true);\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::SetApplicationStayOnTop(bool b)\n{\n\tApplicationStayOnTop = b;\n\tif(ApplicationStayOnTop)\n\t\tSetWindowPos(Application->Handle,HWND_TOPMOST ,0,0,0,0,\n\t\t\tSWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);\n\telse\n\t\tSetWindowPos(Application->Handle,HWND_NOTOPMOST ,0,0,0,0,\n\t\t\tSWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::WMInvokeEvents(TMessage &Msg)\n{\n\t// indirectly called by TVPInvokeEvents  *** currently not used ***\n\tif(EventButton->Down)\n\t{\n\t\tTVPDeliverAllEvents();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TTVPMainForm::DeliverEvents()\n{\n\tif(ContinuousEventCalling)\n\t\tTVPProcessContinuousHandlerEventFlag = true; // set flag\n\n\tif(EventButton->Down) TVPDeliverAllEvents();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ApplicationIdle(TObject *Sender, bool &Done)\n{\n\tDeliverEvents();\n\n\tbool cont = ContinuousEventCalling;\n\tDone = !cont;\n\n\tMixedIdleTick += TVPGetRoughTickCount32();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ApplicationActivate(TObject *Sender)\n{\n\tApplicationActivating = true;\n\n\tTVPRestoreFullScreenWindowAtActivation();\n\tTVPShowModalAtAppActivate();\n\tTVPShowFontSelectFormAtAppActivate();\n\tTVPResetVolumeToAllSoundBuffer();\n\n\t// trigger System.onActivate event\n\tTVPPostApplicationActivateEvent();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ApplicationDeactivate(TObject *Sender)\n{\n\tApplicationActivating = false;\n\n\tTVPHideModalAtAppDeactivate();\n\tTVPHideFontSelectFormAtAppDeactivate();\n\n\tTVPMinimizeFullScreenWindowAtInactivation();\n\n\n\t// fire compact event\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_DEACTIVATE);\n\n\t// set application-level stay-on-top state\n\tif(ApplicationStayOnTop)\n\t\tSetWindowPos(Application->Handle,HWND_TOPMOST ,0,0,0,0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);\n\telse\n\t\tSetWindowPos(Application->Handle,HWND_NOTOPMOST ,0,0,0,0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);\n\n\t// set sound volume\n\tTVPResetVolumeToAllSoundBuffer();\n\n\t// trigger System.onDeactivate event\n\tTVPPostApplicationDeactivateEvent();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ApplicationMinimize(TObject *Sender)\n{\n\t// fire compact event\n\tApplicationNotMinimizing = false;\n\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MINIMIZE);\n\n\t// set sound volume\n\tTVPResetVolumeToAllSoundBuffer();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::ApplicationRestore(TObject *Sender)\n{\n\tApplicationNotMinimizing = true;\n\n\t// set sound volume\n\tTVPResetVolumeToAllSoundBuffer();\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::SystemWatchTimerTimer(TObject *Sender)\n{\n\tif(TVPTerminated)\n\t{\n\t\t// this will ensure terminating the application.\n\t\t// the WM_QUIT message disappears in some unknown situations...\n\t\t::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0);\n\t\tApplication->Terminate();\n\t\t::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0);\n\t}\n\n\t// call events\n\tDWORD tick = TVPGetRoughTickCount32();\n\n\t// push environ noise\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tTVPPushEnvironNoise(&LastCompactedTick, sizeof(LastCompactedTick));\n\tTVPPushEnvironNoise(&LastShowModalWindowSentTick, sizeof(LastShowModalWindowSentTick));\n\tTVPPushEnvironNoise(&MixedIdleTick, sizeof(MixedIdleTick));\n\tPOINT pt;\n\tGetCursorPos(&pt);\n\tTVPPushEnvironNoise(&pt, sizeof(pt));\n\n\t// CPU clock monitoring\n\t{\n\t\tstatic bool clock_rough_printed = false;\n\t\tif(!clock_rough_printed && TVPCPUClockAccuracy == ccaRough)\n\t\t{\n\t\t\ttjs_char msg[80];\n\t\t\tTJS_sprintf(msg, TJS_W(\"(info) CPU clock (roughly) : %dMHz\"), (int)TVPCPUClock);\n\t\t\tTVPAddImportantLog(msg);\n\t\t\tclock_rough_printed = true;\n\t\t}\n\t\tstatic bool clock_printed = false;\n\t\tif(!clock_printed && TVPCPUClockAccuracy == ccaAccurate)\n\t\t{\n\t\t\ttjs_char msg[80];\n\t\t\tTJS_sprintf(msg, TJS_W(\"(info) CPU clock : %.1fMHz\"), (float)TVPCPUClock);\n\t\t\tTVPAddImportantLog(msg);\n\t\t\tclock_printed = true;\n\t\t}\n\t}\n\n\t// check status and deliver events\n\tDeliverEvents();\n\n\t// call TickBeat\n\ttjs_int count = TVPGetWindowCount();\n\tfor(tjs_int i = 0; i<count; i++)\n\t{\n\t\ttTJSNI_Window *win = TVPGetWindowListAt(i);\n\t\twin->TickBeat();\n\t}\n\n\tif(!ContinuousEventCalling && tick - LastCompactedTick > 4000)\n\t{\n\t\t// idle state over 4 sec.\n\t\tLastCompactedTick = tick;\n\n\t\t// fire compact event\n\t\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_IDLE);\n\t}\n\n\tif(!ContinuousEventCalling && tick > LastRehashedTick + 1500)\n\t{\n\t\t// TJS2 object rehash\n\t\tLastRehashedTick = tick;\n\t\tTJSDoRehash();\n\t}\n\n\tif(LastCloseClickedTick && tick - LastCloseClickedTick > 3100)\n\t{\n\t\t// display force suicide confirmation form\n\t\tif(TVPHaltWarnForm)\n\t\t{\n\t\t\tTVPHaltWarnForm->Visible = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPHaltWarnForm = new TTVPHaltWarnForm(Application);\n\t\t\tTVPHaltWarnForm->Visible = true;\n\t\t}\n\t}\n\n\t// ensure modal window visible\n\tif(tick > LastShowModalWindowSentTick + 4100)\n\t{\n\t\t//\t::PostMessage(Handle, WM_USER+0x32, 0, 0);\n\t\t// This is currently disabled because IME composition window\n\t\t// hides behind the window which is bringed top by the\n\t\t// window-rearrangement.\n\t\tLastShowModalWindowSentTick = tick;\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid __fastcall TTVPMainForm::WMRearrangeModalWindows(TMessage &Msg)\n{\n\tif(TVPFullScreenedWindow != NULL && TVPGetModalWindowRearrangeInFullScreen())\n\t{\n\t\tHDWP hdwp = BeginDeferWindowPos(1);\n\t\thdwp = TVPShowModalAtTimer(hdwp);\n\t\thdwp = TVPShowFontSelectFormTop(hdwp);\n\t\thdwp = TVPShowHintWindowTop(hdwp);\n\t\tEndDeferWindowPos(hdwp);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Environment Profiling Support\n//---------------------------------------------------------------------------\nstatic tTVPProfileHolder *TVPEnvironProfile = NULL;\ntjs_int TVPEnvironProfileRefCount = 0;\nstatic bool TVPProfileWrite = false;\n//---------------------------------------------------------------------------\nstatic void TVPInitEnvironProfile()\n{\n\t// initialize environ profile\n\tif(!TVPEnvironProfile)\n\t{\n\t\t// read profile from project directory or\n\t\t// current directory ( if projdir was not specified )\n\t\tif(strchr(TVPNativeDataPath.c_str(), TVPArchiveDelimiter))\n\t\t\tTVPProfileWrite = false; else TVPProfileWrite = true;\n\t\ttry\n\t\t{\n\t\t\tTVPEnvironProfile =\n\t\t\t\tnew tTVPProfileHolder(TVPNativeDataPath + \"krenvprf.kep\");\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPEnvironProfile = new tTVPProfileHolder(TVPGetTemporaryName().AsAnsiString());\n\t\t\tTVPProfileWrite = false;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPWriteEnvironProfile()\n{\n\t// write environ profile values\n\tif(TVPEnvironProfile)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif(TVPProfileWrite) TVPEnvironProfile->UpdateFile();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\t// suppress error\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPUninitEnvironProfile()\n{\n\t// clean up environ profile values\n\tTVPWriteEnvironProfile();\n\tif(TVPEnvironProfile)\n\t{\n\t\tdelete TVPEnvironProfile;\n\t\tTVPEnvironProfile = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPEnvironProfileAddRef()\n{\n\tTVPEnvironProfileRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid TVPEnvironProfileRelease()\n{\n\tTVPEnvironProfileRefCount --;\n\tif(TVPEnvironProfileRefCount == 0) TVPUninitEnvironProfile();\n}\n//---------------------------------------------------------------------------\ntTVPProfileHolder *TVPGetEnvironProfile()\n{\n\t// read value from section and name, return defstr if not found.\n\tTVPInitEnvironProfile();\n\treturn TVPEnvironProfile;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\nstatic AnsiString TVPEscapeAnsiString(const AnsiString & str)\n{\n\t// escape to harmless string\n\tchar *buf = new char [str.Length() * 2 + 1];  // enough to hold\n\tconst char *s = str.c_str();\n\tint i = 0;\n\twhile(*s)\n\t{\n\t\tif(*s == '@')\n\t\t{\n\t\t\tbuf[i++] = '@';\n\t\t\tbuf[i++] = '@';\n\t\t}\n\t\telse if((unsigned char)*s < 0x20)\n\t\t{\n\t\t\tbuf[i++] = '@';\n\t\t\tbuf[i++] = ' ' + *s;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbuf[i++] = *s;\n\t\t}\n\n\t\ts++;\n\t}\n\tbuf[i] = 0;\n\tAnsiString ret =  buf;\n\tdelete [] buf;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nstatic AnsiString TVPUnescapeAnsiString(const AnsiString & str)\n{\n\t// unescape\n\tint strlen = str.Length();\n\tchar *buf = new char [strlen + 1];\n\tconst char *s = str.c_str();\n\tconst char *slim = s + strlen;\n\tint i = 0;\n\twhile(s<slim)\n\t{\n\t\tif(*s == '@')\n\t\t{\n\t\t\tif(s[1] == '@')\n\t\t\t\tbuf[i++] = '@';\n\t\t\telse\n\t\t\t\tbuf[i++] = s[1] - ' ';\n\t\t\ts+=2;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbuf[i++] = *s;\n\t\t\ts++;\n\t\t}\n\t}\n\tbuf[i] = 0;\n\tAnsiString ret = buf;\n\tdelete [] buf;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nvoid __fastcall tTVPProfileHolder::WriteStrings(const AnsiString &section,\n\tconst AnsiString &ident, TStrings * strings)\n{\n\tWriteString(section, ident, TVPEscapeAnsiString(strings->Text));\n}\n//---------------------------------------------------------------------------\nvoid __fastcall tTVPProfileHolder::ReadStrings(const AnsiString &section,\n\tconst AnsiString &ident, TStrings * strings)\n{\n\tAnsiString str;\n\tstr = ReadString(section, ident, \"\");\n\tif(str != \"\") strings->Text = TVPUnescapeAnsiString(str);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/core/environ/win32/MainFormUnit.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Main Window (Controller)\n//---------------------------------------------------------------------------\n#ifndef MainFormUnitH\n#define MainFormUnitH\n//---------------------------------------------------------------------------\n#include <Classes.hpp>\n#include <Controls.hpp>\n#include <StdCtrls.hpp>\n#include <Forms.hpp>\n#include <ComCtrls.hpp>\n#include <ImgList.hpp>\n#include <ToolWin.hpp>\n#include <ExtCtrls.hpp>\n#include <Buttons.hpp>\n#include <Menus.hpp>\n#include <Dialogs.hpp>\n//---------------------------------------------------------------------------\nclass TTVPMainForm : public TForm\n{\n__published:\t// IDE Ǘ̃R|[lg\n\tTImageList *VerySmallIconImageList;\n\tTImageList *SmallIconImageList;\n\tTToolBar *ToolBar;\n\tTToolButton *ShowScriptEditorButton;\n\tTToolButton *ShowConsoleButton;\n\tTToolButton *ToolButton3;\n\tTToolButton *ExitButton;\n\tTToolButton *EventButton;\n\tTPopupMenu *PopupMenu;\n\tTMenuItem *ShowScriptEditorMenuItem;\n\tTMenuItem *ShowConsoleMenuItem;\n\tTMenuItem *N1;\n\tTMenuItem *EnableEventMenuItem;\n\tTMenuItem *N2;\n\tTMenuItem *ExitMenuItem;\n\tTMenuItem *ShowAboutMenuItem;\n\tTMenuItem *N3;\n\tTMenuItem *DumpMenuItem;\n\tTToolButton *ToolButton1;\n\tTToolButton *ShowWatchButton;\n\tTMenuItem *ShowWatchMenuItem;\n\tTTimer *SystemWatchTimer;\n\tTMenuItem *CopyImportantLogMenuItem;\n\tTMenuItem *CreateMessageMapFileMenuItem;\n\tTSaveDialog *MessageMapFileSaveDialog;\n\tTMenuItem *ShowOnTopMenuItem;\n\tTMenuItem *N4;\n\tTMenuItem *ShowControllerMenuItem;\n\tTMenuItem *RestartScriptEngineMenuItem;\n\tvoid __fastcall ShowScriptEditorButtonClick(TObject *Sender);\n\tvoid __fastcall ExitButtonClick(TObject *Sender);\n\tvoid __fastcall ShowConsoleButtonClick(TObject *Sender);\n\tvoid __fastcall PopupMenuPopup(TObject *Sender);\n\tvoid __fastcall EnableEventMenuItemClick(TObject *Sender);\n\tvoid __fastcall ShowAboutMenuItemClick(TObject *Sender);\n\tvoid __fastcall DumpMenuItemClick(TObject *Sender);\n\tvoid __fastcall EventButtonClick(TObject *Sender);\n\tvoid __fastcall ShowWatchButtonClick(TObject *Sender);\n\tvoid __fastcall SystemWatchTimerTimer(TObject *Sender);\n\tvoid __fastcall FormDestroy(TObject *Sender);\n\tvoid __fastcall FormClose(TObject *Sender, TCloseAction &Action);\n\tvoid __fastcall CopyImportantLogMenuItemClick(TObject *Sender);\n\tvoid __fastcall CreateMessageMapFileMenuItemClick(TObject *Sender);\n\tvoid __fastcall ShowOnTopMenuItemClick(TObject *Sender);\n\tvoid __fastcall ShowControllerMenuItemClick(TObject *Sender);\n\tvoid __fastcall RestartScriptEngineMenuItemClick(TObject *Sender);\n\nprivate:\t// [U[錾\n\tbool ContinuousEventCalling;\n\tbool AutoShowConsoleOnError;\n\tbool ApplicationStayOnTop;\n\tbool ApplicationActivating;\n\tbool ApplicationNotMinimizing;\n\npublic:\t\t// [U[錾\n\t__fastcall TTVPMainForm(TComponent* Owner);\n\n\tstatic TShortCut GetHotKeyFromOption(TShortCut def, const tjs_char * optname);\n\tstatic void SetHotKey(TMenuItem *item, const tjs_char * optname);\n\n\tbool CanHideAnyWindow();\n\n\tvoid SetConsoleVisible(bool b);\n\tbool GetConsoleVisible();\n\tvoid NotifyConsoleHiding();\n\n\tbool GetScriptEditorVisible();\n\tvoid NotifyScriptEditorHiding();\n\n\tbool GetWatchVisible();\n\tvoid NotifyWatchHiding();\n\n\tvoid SetAutoShowConsoleOnError(bool b) { AutoShowConsoleOnError = true; }\n\tbool GetAutoShowConsoleOnError() const { return AutoShowConsoleOnError; }\n\n\tvoid ShowController();\n\tvoid InvokeEvents();\n\tvoid CallDeliverAllEventsOnIdle();\n\n\tvoid BeginContinuousEvent();\n\tvoid EndContinuousEvent();\n\n\tvoid NotifyCloseClicked();\n\tvoid NotifyEventDelivered();\n\tvoid NotifyHaltWarnFormClosed();\n\n\tvoid NotifySystemError();\n\n\tvoid SetApplicationStayOnTop(bool b);\n\tbool GetApplicationStayOnTop() const { return ApplicationStayOnTop; }\n\n\tbool GetApplicationActivating() const { return ApplicationActivating; }\n\tbool GetApplicationNotMinimizing() const { return ApplicationNotMinimizing; }\n\nprotected:\nBEGIN_MESSAGE_MAP\n\tVCL_MESSAGE_HANDLER( WM_USER+0x30, TMessage, WMInvokeEvents)\n\tVCL_MESSAGE_HANDLER( WM_USER+0x32, TMessage, WMRearrangeModalWindows)\nEND_MESSAGE_MAP(TForm)\n\tvoid __fastcall WMInvokeEvents(TMessage &Msg);\n\tvoid __fastcall WMRearrangeModalWindows(TMessage &Msg);\nprivate:\n\tDWORD LastCompactedTick;\n\tDWORD LastContinuousTick;\n\tDWORD LastCloseClickedTick;\n\tDWORD LastShowModalWindowSentTick;\n\tDWORD LastRehashedTick;\n\n\tDWORD MixedIdleTick;\n\n\tvoid DeliverEvents();\n\n\tvoid __fastcall ApplicationIdle(TObject *Sender, bool &Done);\n\tvoid __fastcall ApplicationActivate(TObject *Sender);\n\tvoid __fastcall ApplicationDeactivate(TObject *Sender);\n\tvoid __fastcall ApplicationMinimize(TObject *Sender);\n\tvoid __fastcall ApplicationRestore(TObject *Sender);\n\npublic: // hotkey management\n\tTShortCut ShowUpdateRectShortCut;\n\tTShortCut DumpLayerStructureShortCut;\n\n};\n//---------------------------------------------------------------------------\nextern PACKAGE TTVPMainForm *TVPMainForm;\nextern bool TVPMainFormAlive;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Environment Profiling Support\n//---------------------------------------------------------------------------\n#include \"inifiles.hpp\"\nclass tTVPProfileHolder : public TMemIniFile\n{\npublic:\n\t__fastcall tTVPProfileHolder(const AnsiString &fn) : TMemIniFile(fn) {};\n\t__fastcall ~tTVPProfileHolder() {};\n\n\tvoid __fastcall WriteStrings(const AnsiString &section, const AnsiString &ident,\n\t\tTStrings * strings);\n\tvoid __fastcall ReadStrings(const AnsiString &section, const AnsiString &ident,\n\t\tTStrings * strings);\n};\nextern void TVPWriteEnvironProfile();\nextern void TVPEnvironProfileAddRef();\nextern void TVPEnvironProfileRelease();\nextern tTVPProfileHolder *TVPGetEnvironProfile();\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/MouseCursor.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"MouseCursor.h\"\n#include \"WindowFormUnit.h\"\n\nconst LPTSTR MouseCursor::CURSORS[CURSOR_EOT] = {\n\tIDC_APPSTARTING,\n\tIDC_ARROW,\n\tIDC_CROSS,\n\tIDC_HAND,\n\tIDC_IBEAM,\n\tIDC_HELP,\n\tIDC_NO,\n\tIDC_SIZEALL,\n\tIDC_SIZENESW,\n\tIDC_SIZENS,\n\tIDC_SIZENWSE,\n\tIDC_SIZEWE,\n\tIDC_UPARROW,\n\tIDC_WAIT,\n};\n\nconst int MouseCursor::CURSOR_INDEXES[MouseCursor::CURSOR_INDEXES_NUM] = {\n\tCURSOR_SIZEALL, // crSizeAll = -22,\n\tCURSOR_HAND, // crHandPoint = -21,\n\tCURSOR_HELP, // crHelp = -20,\n\tCURSOR_ARROW, // crAppStart = -19,\n\tCURSOR_NO, // crNo = -18,\n\tCURSOR_ARROW, // crSQLWait = -17,\n\tCURSOR_ARROW, // crMultiDrag = -16,\n\tCURSOR_ARROW, // crVSplit = -15,\n\tCURSOR_ARROW, // crHSplit = -14,\n\tCURSOR_ARROW, // crNoDrop = -13,\n\tCURSOR_ARROW, // crDrag = -12,\n\tCURSOR_WAIT, // crHourGlass = -11,\n\tCURSOR_UPARROW, // crUpArrow = -10,\n\tCURSOR_SIZEWE, // crSizeWE = -9,\n\tCURSOR_SIZENWSE, // crSizeNWSE = -8,\n\tCURSOR_SIZENS, // crSizeNS = -7,\n\tCURSOR_SIZENESW, // crSizeNESW = -6,\n\tCURSOR_SIZEALL, // crSize = -5,\n\tCURSOR_IBEAM, // crIBeam = -4,\n\tCURSOR_CROSS, // crCross = -3,\n\tCURSOR_ARROW, // crArrow = -2,\n\t-1, // crNone = -1,\n\tCURSOR_ARROW, // crDefault = 0,\n\tCURSOR_ARROW, // crHBeam = 1,\n};\nstd::vector<HCURSOR> MouseCursor::CURSOR_HANDLES_FOR_INDEXES;\nHCURSOR MouseCursor::CURSOR_HANDLES[CURSOR_EOT];\nbool MouseCursor::CURSOR_INITIALIZED = false;\n\nvoid MouseCursor::Initialize() {\n\tif( CURSOR_INITIALIZED ) return;\n\n\t// ftHgJ[\\ǂݍ\n\tfor( int i = 0; i < CURSOR_EOT; i++ ) {\n\t\tCURSOR_HANDLES[i] = ::LoadCursor( NULL, CURSORS[i] );\n\t}\n\n\t// JJ[\\IDƈv悤Ƀnhi[\n\tCURSOR_HANDLES_FOR_INDEXES.clear();\n\tCURSOR_HANDLES_FOR_INDEXES.reserve( CURSOR_INDEXES_NUM );\n\tfor( int i = 0; i < CURSOR_INDEXES_NUM; i++ ) {\n\t\tint index = CURSOR_INDEXES[i];\n\t\tif( index >= 0 ) {\n\t\t\tCURSOR_HANDLES_FOR_INDEXES.push_back( CURSOR_HANDLES[index] );\n\t\t} else {\n\t\t\tCURSOR_HANDLES_FOR_INDEXES.push_back( INVALID_HANDLE_VALUE );\n\t\t}\n\t}\n\tCURSOR_INITIALIZED = true;\n}\nvoid MouseCursor::Finalize() {\n\t// ǂݍ܂ꂽJ[\\폜\n\tif( CURSOR_HANDLES_FOR_INDEXES.size() > CURSOR_INDEXES_NUM ) {\n\t\tint numCursor = (int)CURSOR_HANDLES_FOR_INDEXES.size();\n\t\tfor( int i = CURSOR_INDEXES_NUM; i < numCursor; i++ ) {\n\t\t\t::DestroyCursor( CURSOR_HANDLES_FOR_INDEXES[i] );\n\t\t\tCURSOR_HANDLES_FOR_INDEXES[i] = INVALID_HANDLE_VALUE;\n\t\t}\n\t}\n}\nint MouseCursor::GetCurrentCursor() {\n\tHCURSOR hCursor = ::GetCursor();\n\t// \n\tif( hCursor == NULL ) return crNone;\n\n\tint size = (int)CURSOR_HANDLES_FOR_INDEXES.size();\n\tint handleIndex = cursor_index_ + CURSOR_OFFSET;\n\n\tif( handleIndex >= 0 && handleIndex < size && CURSOR_HANDLES_FOR_INDEXES[handleIndex] == hCursor ) {\n\t\t// ܂cursor_index_J[\\Ɣr\n\t\treturn cursor_index_;\n\t} else if( CURSOR_HANDLES[CURSOR_ARROW] == hCursor ) {\n\t\t// ɃftHgƔr\n\t\treturn crDefault;\n\t} else {\n\t\t// ȊÓASĂƔr\n\t\tfor( int i = 0; i < size; i++ ) {\n\t\t\tif( CURSOR_HANDLES_FOR_INDEXES[i] == hCursor ) {\n\t\t\t\treturn i - CURSOR_OFFSET;\n\t\t\t}\n\t\t}\n\t}\n\t// SĂɃ}b`Ȃꍇ\n\treturn INVALID_CURSOR_INDEX;\n}\nvoid MouseCursor::SetMouseCursor( int index ) {\n\tHCURSOR hCursor = NULL;\n\tif( index != crNone ) {\n\t\tint id = index + CURSOR_OFFSET; // crSizeAll = -22, Ȃ̂ŁA̕Z\n\t\tif( id >= 0 && id < (int)CURSOR_HANDLES_FOR_INDEXES.size() ) {\n\t\t\thCursor = CURSOR_HANDLES_FOR_INDEXES[id];\n\t\t} else {\n\t\t\thCursor = CURSOR_HANDLES[CURSOR_ARROW];\n\t\t}\n\t}\n\t::SetCursor( hCursor );\n}\nvoid MouseCursor::UpdateCursor() {\n\tif( cursor_index_ != INVALID_CURSOR_INDEX ) {\n\t\tint index = GetCurrentCursor();\n\t\tif( index == INVALID_CURSOR_INDEX || index != cursor_index_ ) {\n\t\t\tSetMouseCursor( cursor_index_ );\n\t\t}\n\t}\n}\nvoid MouseCursor::SetCursorIndex( int index, HWND hWnd ) {\n\tif( cursor_index_ != index ) {\n\t\tcursor_index_ = index;\n\n\t\tif( hWnd ) {\n\t\t\tPOINT p;\n\t\t\t::GetCursorPos(&p);\n\t\t\tHWND hTarget = ::WindowFromPoint(p);\n\t\t\tif ( hTarget && hTarget == hWnd ) {\n\t\t\t\tLRESULT hitTestCode = ::SendMessage( hWnd, WM_NCHITTEST, 0, MAKELPARAM(p.x, p.y) );\n\t\t\t\tif( index == crDefault ) {\n\t\t\t\t\t::SendMessage( hWnd, WM_SETCURSOR, WPARAM(hWnd), (LPARAM)MAKELONG(hitTestCode, WM_MOUSEMOVE) );\n\t\t\t\t} else if ( hitTestCode == HTCLIENT ) {\n\t\t\t\t\tSetMouseCursor( index );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/win32/MouseCursor.h",
    "content": "\n\n#ifndef __MOUSE_CURSOR_H__\n#define __MOUSE_CURSOR_H__\n\n#include <vector>\n\nclass MouseCursor {\n\tenum {\n\t\tCURSOR_APPSTARTING,\t// WJ[\\я^vJ[\\\n\t\tCURSOR_ARROW,\t\t// WJ[\\\n\t\tCURSOR_CROSS,\t\t// \\J[\\\n\t\tCURSOR_HAND,\t\t// nhJ[\\\n\t\tCURSOR_IBEAM,\t\t// ACr[ (c) J[\\\n\t\tCURSOR_HELP,\t\t// Ƌ^╄\n\t\tCURSOR_NO,\t\t\t// ֎~J[\\\n\t\tCURSOR_SIZEALL,\t\t// 4 J[\\\n\t\tCURSOR_SIZENESW,\t// ΂ߍ̗J[\\\n\t\tCURSOR_SIZENS,\t\t// ㉺J[\\\n\t\tCURSOR_SIZENWSE,\t// ΂߉E̗J[\\\n\t\tCURSOR_SIZEWE,\t\t// EJ[\\\n\t\tCURSOR_UPARROW,\t\t// ̖J[\\\n\t\tCURSOR_WAIT,\t\t// vJ[\\ \n\t\tCURSOR_EOT,\n\t};\n\tstatic const int CURSOR_OFFSET = 22;\n\tstatic const int CURSOR_INDEXES_NUM = 24;\n\tstatic const int CURSOR_INDEXES[CURSOR_INDEXES_NUM]; // ̃J[\\CfbNXƌJJ[\\CfbNX̕ϊe[u\n//\tstatic std::vector<HCURSOR> CURSOR_HANDLES_FOR_INDEXES;\t// SJ[\\̃nhAVKǍ݂ꂽ̂͒ǉ\n\n// \tstatic const LPTSTR CURSORS[CURSOR_EOT];\t// J[\\ƃ\\[XID̑Ήe[u\n// \tstatic HCURSOR CURSOR_HANDLES[CURSOR_EOT];\t// ftHgJ[\\̃nhe[u\n\tstatic const int INVALID_CURSOR_INDEX = 0x7FFFFFFF;\t// ȃJ[\\CfbNX\n\tstatic bool CURSOR_INITIALIZED;\t// J[\\ς݂ۂ\n\n\tstatic bool is_cursor_hide_;\t// J[\\crNoneŔ\\ɂȂĂ邩ǂ\n\npublic:\n\tstatic void Initialize();\n\tstatic void Finalize();\n\tstatic void SetMouseCursor( int index );\n// \tstatic int AddCursor( HCURSOR hCursor ) {\n// \t\tint index = (int)CURSOR_HANDLES_FOR_INDEXES.size();\n// \t\tCURSOR_HANDLES_FOR_INDEXES.push_back( hCursor );\n// \t\treturn index - CURSOR_OFFSET;\n// \t}\n\nprivate:\n\tint cursor_index_;\n\n\tint GetCurrentCursor();\n\npublic:\n\tMouseCursor() : cursor_index_(INVALID_CURSOR_INDEX) {}\n\tMouseCursor( int index ) : cursor_index_(index) {}\n\n\tvoid UpdateCursor();\n\n//\tvoid SetCursorIndex( int index, HWND hWnd );\n};\n\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/Platform.cpp",
    "content": "#include \"Platform.h\"\n#include \"cocos2d/MainScene.h\"\n//#undef WIN32\n#include <windows.h>\n#include <mmsystem.h>\n#include <Psapi.h>\n#include <codecvt>\n#include \"StorageImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"platform/CCFileUtils.h\"\n#include <sys/stat.h>\n#include \"Application.h\"\n#include \"EventIntf.h\"\n#include \"cocos/base/CCDirector.h\"\n#include <shellapi.h>\n#include \"XP3ArchiveRepack.h\"\n#include \"RenderManager.h\"\n#include <sys/utime.h>\n\n#pragma comment(lib,\"psapi.lib\")\n\ntjs_int TVPGetSystemFreeMemory()\n{\n\tMEMORYSTATUS info;\n\tGlobalMemoryStatus(&info);\n\treturn info.dwAvailPhys / (1024 * 1024);\n}\n\ntjs_int TVPGetSelfUsedMemory()\n{\n\tPROCESS_MEMORY_COUNTERS info;\n\tGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));\n\treturn info.WorkingSetSize / (1024 * 1024);\n}\n\nvoid TVPGetMemoryInfo(TVPMemoryInfo &m)\n{\n    MEMORYSTATUS status;\n    status.dwLength = sizeof(status);\n    GlobalMemoryStatus(&status);\n\n    m.MemTotal = status.dwTotalPhys / 1024;\n    m.MemFree = status.dwAvailPhys / 1024;\n    m.SwapTotal = status.dwTotalPageFile / 1024;\n    m.SwapFree = status.dwAvailPageFile / 1024;\n    m.VirtualTotal = status.dwTotalVirtual / 1024;\n    m.VirtualUsed = (status.dwTotalVirtual - status.dwAvailVirtual) / 1024;\n}\n\n// int gettimeofday(struct timeval * val, struct timezone *)\n// {\n// \tif (val)\n// \t{\n// \t\tLARGE_INTEGER liTime, liFreq;\n// \t\tQueryPerformanceFrequency(&liFreq);\n// \t\tQueryPerformanceCounter(&liTime);\n// \t\tval->tv_sec = (long)(liTime.QuadPart / liFreq.QuadPart);\n// \t\tval->tv_usec = (long)(liTime.QuadPart * 1000000.0 / liFreq.QuadPart - val->tv_sec * 1000000.0);\n// \t}\n// \treturn 0;\n// }\n\nvoid *dlopen(const char *filename, int flag) {\n\treturn (void*)LoadLibraryA(filename);\n}\n\nvoid *dlsym(void* handle, const char *funcname) {\n\treturn (void *)GetProcAddress((HMODULE)handle, funcname);\n}\n\nextern \"C\" int usleep(unsigned long us) {\n\tSleep(us / 1000);\n\treturn 0;\n}\n\n//extern \"C\" __declspec(dllimport) int __cdecl __wgetmainargs(int * _Argc, wchar_t *** _Argv, wchar_t *** _Env, int _DoWildCard, void * _StartInfo);\nstd::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;\nstd::string TVPGetDefaultFileDir() {\n\twchar_t buf[MAX_PATH];\n\t_wgetcwd(buf, sizeof(buf) / sizeof(buf[0]));\n\twchar_t *p = buf;\n\twhile (*p) {\n\t\tif (*p == '\\\\') *p = '/';\n\t\t++p;\n\t}\n\treturn converter.to_bytes(buf);\n}\n\nint TVPCheckArchive(const ttstr &localname);\nvoid TVPCheckAndSendDumps(const std::string &dumpdir, const std::string &packageName, const std::string &versionStr);\nbool TVPCheckStartupArg() {\n\tint argc;\n\twchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc);\n//\t__wgetmainargs(&argc, &argv, &env, 0, &info);\n\tTVPCheckAndSendDumps(TVPGetDefaultFileDir() + \"/dumps\", \"win32-test\", \"test\");\n\tif (argc > 1) {\n\t\tif (TVPCheckExistentLocalFile(argv[1])) {\n\t\t\tif (TVPCheckArchive(argv[1]) == 1) {\n\t\t\t\tTVPMainScene::GetInstance()->startupFrom(converter.to_bytes(argv[1]));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tbool bootable = false;\n\t\tTVPListDir(converter.to_bytes(argv[1]), [&](const std::string &_name, int mask) {\n\t\t\tif (mask & (S_IFREG)) {\n\t\t\t\tstd::string name(_name);\n\t\t\t\tstd::transform(name.begin(), name.end(), name.begin(), [](int c)->int {\n\t\t\t\t\tif (c <= 'Z' && c >= 'A')\n\t\t\t\t\t\treturn c - ('A' - 'a');\n\t\t\t\t\treturn c;\n\t\t\t\t});\n\t\t\t\tif (name == \"startup.tjs\") {\n\t\t\t\t\tbootable = true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tfor (int i = 2; i < argc; ++i) {\n\t\t\tstd::wstring str = argv[i];\n\t\t\tsize_t pos = str.find(L'=');\n\t\t\tif (pos == str.npos) {\n\t\t\t\tTVPSetCommandLine(argv[i], \"yes\");\n\t\t\t} else {\n\t\t\t\tttstr val = str.c_str() + pos + 1;\n\t\t\t\tTVPSetCommandLine(str.substr(0, pos).c_str(), val);\n\t\t\t}\n\t\t}\n\t\tif (bootable) {\n\t\t\tTVPMainScene::GetInstance()->startupFrom(converter.to_bytes(argv[1]));\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nint TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption, const std::vector<ttstr> &vecButtons)\n{\n\t// there has no implement under android\n\tswitch (vecButtons.size()) {\n\tcase 1:\n\t\tMessageBoxW(0, text.c_str(), caption.c_str(), /*MB_OK*/0);\n\t\treturn 0;\n\t\tbreak;\n\tcase 2:\n\t\tswitch (MessageBoxW(0, text.c_str(), caption.c_str(), /*MB_YESNO*/4)) {\n\t\tcase 6:\n\t\t\treturn 0;\n\t\tdefault:\n\t\t\treturn 1;\n\t\t}\n\t\tbreak;\n\t}\n\treturn -1;\n}\n\nextern \"C\" int TVPShowSimpleMessageBox(const char *pszText, const char *pszTitle, unsigned int nButton, const char **btnText) {\n\tstd::vector<ttstr> vecButtons;\n\tfor (unsigned int i = 0; i < nButton; ++i) {\n\t\tvecButtons.emplace_back(btnText[i]);\n\t}\n\treturn TVPShowSimpleMessageBox(pszText, pszTitle, vecButtons);\n}\n\nstd::vector<std::string> TVPGetDriverPath() {\n\tstd::vector<std::string> ret;\n\tchar drv[4] = { 'C', ':', '/', 0 };\n\tfor (char c = 'C'; c <= 'Z'; ++c) {\n\t\tdrv[0] = c;\n\t\tswitch (GetDriveTypeA(drv)) {\n\t\tcase DRIVE_REMOVABLE:\n\t\tcase DRIVE_FIXED:\n\t\tcase DRIVE_REMOTE:\n\t\t\tret.emplace_back(drv);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstd::vector<std::string> TVPGetAppStoragePath() {\n\tstd::vector<std::string> ret;\n\tret.emplace_back(TVPGetDefaultFileDir());\n\treturn ret;\n}\n\nbool TVPCheckStartupPath(const std::string &path) { return true; }\n\nstd::string TVPGetPackageVersionString() {\n\treturn \"win32\";\n}\n\nvoid TVPControlAdDialog(int adType, int arg1, int arg2) {}\nvoid TVPForceSwapBuffer() {}\n\n\n//---------------------------------------------------------------------------\n// TVPCreateFolders\n//---------------------------------------------------------------------------\nstatic bool _TVPCreateFolders(const ttstr &folder)\n{\n\t// create directories along with \"folder\"\n\tif (folder.IsEmpty()) return true;\n\n\tif (TVPCheckExistentLocalFolder(folder))\n\t\treturn true; // already created\n\n\tconst tjs_char *p = folder.c_str();\n\ttjs_int i = folder.GetLen() - 1;\n\n\tif (p[i] == TJS_W(':')) return true;\n\n\twhile (i >= 0 && (p[i] == TJS_W('/') || p[i] == TJS_W('\\\\'))) i--;\n\n\tif (i >= 0 && p[i] == TJS_W(':')) return true;\n\n\tfor (; i >= 0; i--)\n\t{\n\t\tif (p[i] == TJS_W(':') || p[i] == TJS_W('/') ||\n\t\t\tp[i] == TJS_W('\\\\'))\n\t\t\tbreak;\n\t}\n\n\tttstr parent(p, i + 1);\n\tif (!TVPCreateFolders(parent)) return false;\n\n\treturn !_wmkdir(folder.c_str());\n\n}\n//---------------------------------------------------------------------------\n\nbool TVPCreateFolders(const ttstr &folder)\n{\n\tif (folder.IsEmpty()) return true;\n\n\tconst tjs_char *p = folder.c_str();\n\ttjs_int i = folder.GetLen() - 1;\n\n\tif (p[i] == TJS_W(':')) return true;\n\n\tif (p[i] == TJS_W('/') || p[i] == TJS_W('\\\\')) i--;\n\n\treturn _TVPCreateFolders(ttstr(p, i + 1));\n}\n\nbool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int len) {\n\tFILE* handle = _wfopen(filepath.c_str(), L\"wb\");\n\tif (handle) {\n\t\tbool ret = fwrite(data, 1, len, handle) == len;\n\t\tfclose(handle);\n\t\treturn ret;\n\t}\n\treturn false;\n}\n\nstd::string TVPGetCurrentLanguage() {\n\tLANGID lid = GetUserDefaultUILanguage();\n\tconst LCID locale_id = MAKELCID(lid, SORT_DEFAULT);\n\tchar code[10] = { 0 };\n\tchar country[10] = { 0 };\n\tGetLocaleInfoA(locale_id, LOCALE_SISO639LANGNAME, code, sizeof(code));\n\tGetLocaleInfoA(locale_id, LOCALE_SISO3166CTRYNAME, country, sizeof(country));\n\tstd::string ret = code;\n\tif (country[0]) {\n\t\tfor (int i = 0; i < sizeof(country) && country[i]; ++i) {\n\t\t\tchar c = country[i];\n\t\t\tif (c <= 'Z' && c >= 'A') {\n\t\t\t\tcountry[i] += 'a' - 'A';\n\t\t\t}\n\t\t}\n\t\tret += \"_\";\n\t\tret += country;\n\t}\n\treturn ret;\n}\n\nextern tTJS *TVPScriptEngine;\nvoid TVPReleaseFontLibrary();\nvoid TVPExitApplication(int code) {\n\t// clear some static data for memory leak detect\n\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX);\n\tif (!TVPIsSoftwareRenderManager())\n\t\tiTVPTexture2D::RecycleProcess();\n\n// \tif (TVPScriptEngine) TVPScriptEngine->Cleanup();\n// \tTVPReleaseFontLibrary();\n// \tdelete ::Application;\n// \tTVPMainScene::GetInstance()->removeFromParent();\n\texit(code);\n}\n\n// const std::string &TVPGetInternalPreferencePath() {\n// \tstatic std::string ret(cocos2d::FileUtils::getInstance()->getWritablePath());\n// \treturn ret;\n// }\n\nbool TVPDeleteFile(const std::string &filename)\n{\n\treturn _wunlink(ttstr(filename).c_str()) == 0;\n}\n\nbool TVPRenameFile(const std::string &from, const std::string &to)\n{\n#ifdef WIN32\n\ttjs_int ret = _wrename(ttstr(from).c_str(), ttstr(to).c_str());\n#else\n\ttjs_int ret = rename(from.c_str(), to.c_str());\n#endif\n\treturn !ret;\n}\n\nvoid TVPProcessInputEvents() {}\nvoid TVPShowIME(int x, int y, int w, int h) {}\nvoid TVPHideIME() {}\n\nvoid TVPRelinquishCPU(){ Sleep(0); }\n\ntjs_uint32 TVPGetRoughTickCount32()\n{\n\treturn timeGetTime();\n}\n\nvoid TVPPrintLog(const char *str) {\n\tprintf(\"%s\", str);\n}\n\nbool TVP_stat(const tjs_char *name, tTVP_stat &s) {\n\tstruct _stat64 t;\n\tbool ret = !_wstat64(name, &t);\n\ts.st_mode = t.st_mode;\n\ts.st_size = t.st_size;\n\ts.st_atime = t.st_atime;\n\ts.st_mtime = t.st_mtime;\n\ts.st_ctime = t.st_ctime;\n\treturn ret;\n}\n\nbool TVP_stat(const char *name, tTVP_stat &s) {\n\tttstr filename(name);\n\treturn TVP_stat(filename.c_str(), s);\n}\n\nvoid TVP_utime(const char *name, time_t modtime) {\n\t_utimbuf utb;\n\tutb.modtime = modtime;\n\tutb.actime = modtime;\n\tttstr filename(name);\n\t_wutime(filename.c_str(), &utb);\n}\n"
  },
  {
    "path": "src/core/environ/win32/SystemControl.cpp",
    "content": "#include \"tjsCommHead.h\"\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#include \"SystemControl.h\"\n#include \"EventIntf.h\"\n#include \"MsgIntf.h\"\n//#include \"WindowFormUnit.h\"\n#include \"SysInitIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"WindowIntf.h\"\n#include \"WindowImpl.h\"\n#include \"StorageIntf.h\"\n#include \"EmergencyExit.h\" // for TVPCPUClock\n#include \"DebugIntf.h\"\n//#include \"VersionFormUnit.h\"\n#include \"WaveImpl.h\"\n#include \"SystemImpl.h\"\n#include \"UserEvent.h\"\n#include \"Application.h\"\n#include \"TickCount.h\"\n#include \"Random.h\"\n\ntTVPSystemControl *TVPSystemControl;\nbool TVPSystemControlAlive = false;\n\n//---------------------------------------------------------------------------\n// Get whether to control main thread priority or to insert wait\n//---------------------------------------------------------------------------\nstatic bool TVPMainThreadPriorityControlInit = false;\nstatic bool TVPMainThreadPriorityControl = false;\nstatic bool TVPGetMainThreadPriorityControl()\n{\n\tif(TVPMainThreadPriorityControlInit) return TVPMainThreadPriorityControl;\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-lowpri\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t\tTVPMainThreadPriorityControl = true;\n\t}\n\n\tTVPMainThreadPriorityControlInit = true;\n\n\treturn TVPMainThreadPriorityControl;\n}\n\n\ntTVPSystemControl::tTVPSystemControl() : EventEnable(true) {\n\tContinuousEventCalling = false;\n\tAutoShowConsoleOnError = false;\n\n\tLastCompactedTick = 0;\n\tLastCloseClickedTick = 0;\n\tLastShowModalWindowSentTick = 0;\n\tLastRehashedTick = 0;\n\n\tTVPSystemControlAlive = true;\n#if 0\n\tSystemWatchTimer.SetInterval(50);\n\tSystemWatchTimer.SetOnTimerHandler( this, &tTVPSystemControl::SystemWatchTimerTimer );\n\tSystemWatchTimer.SetEnabled( true );\n#endif\n}\nvoid tTVPSystemControl::InvokeEvents() {\n\tCallDeliverAllEventsOnIdle();\n}\nvoid tTVPSystemControl::CallDeliverAllEventsOnIdle() {\n//\tApplication->PostMessageToMainWindow( TVP_EV_DELIVER_EVENTS_DUMMY, 0, 0 );\n}\n\nvoid tTVPSystemControl::BeginContinuousEvent() {\n\tif(!ContinuousEventCalling)\n\t{\n\t\tContinuousEventCalling = true;\n\t\tInvokeEvents();\n\t\tif(TVPGetMainThreadPriorityControl())\n\t\t{\n\t\t\t// make main thread priority lower\n//\t\t\tSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);\n\t\t}\n\t}\n}\nvoid tTVPSystemControl::EndContinuousEvent() {\n\tif(ContinuousEventCalling)\n\t{\n\t\tContinuousEventCalling = false;\n\t\tif(TVPGetMainThreadPriorityControl())\n\t\t{\n\t\t\t// make main thread priority normal\n//\t\t\tSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPSystemControl::NotifyCloseClicked() {\n\t// close Button is clicked\n\tLastCloseClickedTick = TVPGetRoughTickCount32();\n}\n\nvoid tTVPSystemControl::NotifyEventDelivered() {\n\t// called from event system, notifying the event is delivered.\n\tLastCloseClickedTick = 0;\n\t// if(TVPHaltWarnForm) delete TVPHaltWarnForm, TVPHaltWarnForm = NULL;\n}\n\nbool tTVPSystemControl::ApplicationIdle() {\n\tDeliverEvents();\n\tbool cont = !ContinuousEventCalling;\n\tMixedIdleTick += TVPGetRoughTickCount32();\n\treturn cont;\n}\n\nvoid tTVPSystemControl::DeliverEvents() {\n\tif(ContinuousEventCalling)\n\t\tTVPProcessContinuousHandlerEventFlag = true; // set flag\n\n\tif (EventEnable) {\n\t\tTVPDeliverAllEvents();\n\t}\n}\n\nvoid tTVPSystemControl::SystemWatchTimerTimer() {\n\tif( TVPTerminated ) {\n\t\t// this will ensure terminating the application.\n\t\t// the WM_QUIT message disappears in some unknown situations...\n//\t\tApplication->PostMessageToMainWindow( TVP_EV_DELIVER_EVENTS_DUMMY, 0, 0 );\n\t\tApplication->Terminate();\n//\t\tApplication->PostMessageToMainWindow( TVP_EV_DELIVER_EVENTS_DUMMY, 0, 0 );\n\t}\n\n\t// call events\n\tuint32_t tick = TVPGetRoughTickCount32();\n\t// push environ noise\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tTVPPushEnvironNoise(&LastCompactedTick, sizeof(LastCompactedTick));\n\tTVPPushEnvironNoise(&LastShowModalWindowSentTick, sizeof(LastShowModalWindowSentTick));\n\tTVPPushEnvironNoise(&MixedIdleTick, sizeof(MixedIdleTick));\n#if 0\n\tPOINT pt;\n\t::GetCursorPos(&pt);\n\tTVPPushEnvironNoise(&pt, sizeof(pt));\n\n\t// CPU clock monitoring\n\t{\n\t\tstatic bool clock_rough_printed = false;\n\t\tif( !clock_rough_printed && TVPCPUClockAccuracy == ccaRough ) {\n\t\t\ttjs_char msg[80];\n\t\t\tTJS_snprintf(msg, 80, TVPInfoCpuClockRoughly, (int)TVPCPUClock);\n\t\t\tTVPAddImportantLog(msg);\n\t\t\tclock_rough_printed = true;\n\t\t}\n\t\tstatic bool clock_printed = false;\n\t\tif( !clock_printed && TVPCPUClockAccuracy == ccaAccurate ) {\n\t\t\ttjs_char msg[80];\n\t\t\tTJS_snprintf(msg, 80, TVPInfoCpuClock, (float)TVPCPUClock);\n\t\t\tTVPAddImportantLog(msg);\n\t\t\tclock_printed = true;\n\t\t}\n\t}\n#endif\n\t// check status and deliver events\n\tDeliverEvents();\n\n\t// call TickBeat\n\ttjs_int count = TVPGetWindowCount();\n\tfor( tjs_int i = 0; i<count; i++ ) {\n\t\ttTJSNI_Window *win = TVPGetWindowListAt(i);\n\t\twin->TickBeat();\n\t}\n\n\tif( !ContinuousEventCalling && tick - LastCompactedTick > 4000 ) {\n\t\t// idle state over 4 sec.\n\t\tLastCompactedTick = tick;\n\n\t\t// fire compact event\n\t\tTVPDeliverCompactEvent(TVP_COMPACT_LEVEL_IDLE);\n\t}\n\tif( !ContinuousEventCalling && tick > LastRehashedTick + 1500 ) {\n\t\t// TJS2 object rehash\n\t\tLastRehashedTick = tick;\n\t\tTJSDoRehash();\n\t}\n\t// ensure modal window visible\n\tif( tick > LastShowModalWindowSentTick + 4100 ) {\n\t\t//\t::PostMessage(Handle, WM_USER+0x32, 0, 0);\n\t\t// This is currently disabled because IME composition window\n\t\t// hides behind the window which is bringed top by the\n\t\t// window-rearrangement.\n\t\tLastShowModalWindowSentTick = tick;\n\t}\n}\n\n"
  },
  {
    "path": "src/core/environ/win32/SystemControl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// System Main Window (Controller)\n//---------------------------------------------------------------------------\n#ifndef SystemControlH\n#define SystemControlH\n//---------------------------------------------------------------------------\n#include <string>\n#include \"TVPTimer.h\"\n//---------------------------------------------------------------------------\nclass tTVPSystemControl\n{\nprivate:\t// [U[錾\n\tbool ContinuousEventCalling;\n\tbool AutoShowConsoleOnError;\n\n\tbool EventEnable;\n\n\tuint32_t LastCompactedTick;\n\tuint32_t LastCloseClickedTick;\n\tuint32_t LastShowModalWindowSentTick;\n\tuint32_t LastRehashedTick;\n\n\tuint32_t MixedIdleTick;\n\n\tTVPTimer SystemWatchTimer;\npublic:\n\ttTVPSystemControl();\n\n\tvoid InvokeEvents();\n\tvoid CallDeliverAllEventsOnIdle();\n\n\tvoid BeginContinuousEvent();\n\tvoid EndContinuousEvent();\n\n\tvoid NotifyCloseClicked();\n\tvoid NotifyEventDelivered();\n\n\tvoid SetEventEnabled( bool b ) {\n\t\tEventEnable = b;\n\t}\n\tbool GetEventEnabled() const { return EventEnable; }\n\n\tbool ApplicationIdle();\n\nprivate:\n\tvoid DeliverEvents();\npublic:\n\tvoid SystemWatchTimerTimer();\n};\nextern tTVPSystemControl *TVPSystemControl;\nextern bool TVPSystemControlAlive;\n\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/TVPWindow.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"WindowIntf.h\"\n#include \"ComplexRect.h\"\n#include \"TVPWindow.h\"\n#include <vector>\n#include <windowsx.h>\n#include \"SystemControl.h\"\n#include \"Exception.h\"\n#include \"Application.h\"\n#include \"Resource.h\"\n#include \"CompatibleNativeFuncs.h\"\n#include \"WindowsUtil.h\"\n#include \"MsgIntf.h\"\n#include \"UserEvent.h\"\n#include \"TickCount.h\"\n#include \"SysInitIntf.h\"\n\n#include <TCHAR.h>\n#include <tpcshrd.h> // for MICROSOFT_TABLETPENSERVICE_PROPERTY\n\n// touch mouse message extraInfo (cf. http://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx )\nconst DWORD tTVPWindow::MI_WP_SIGNATURE = 0xFF515780;\nconst DWORD tTVPWindow::SIGNATURE_MASK  = 0xFFFFFF80;\n\ntTVPWindow::~tTVPWindow() {\n\tif( ime_control_ ) delete ime_control_;\n\t::SetWindowLongPtr( window_handle_, GWLP_WNDPROC, (LONG_PTR)::DefWindowProc );\n\t::SetWindowLongPtr( window_handle_, GWLP_USERDATA, (LONG_PTR)NULL );\n}\nLRESULT WINAPI tTVPWindow::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )\n{\n\ttTVPWindow *win = reinterpret_cast<tTVPWindow*>(GetWindowLongPtr(hWnd,GWLP_USERDATA));\n\tif( win != NULL ) {\n\t\treturn win->Proc( hWnd, msg, wParam, lParam );\n\t}\n\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n}\n\nLRESULT WINAPI tTVPWindow::Proc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\n\t// }EXbZ[WAMouse Enter ̔s\n\tif( (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) && msg != WM_MOUSELEAVE ) {\n\t\tif( in_window_ == false ) {\n\t\t\tOnMouseEnter();\n\t\t\tin_window_ = true;\n\t\t\tTRACKMOUSEEVENT tme;\n            tme.cbSize = sizeof(TRACKMOUSEEVENT);\n            tme.dwFlags = TME_LEAVE;\n            tme.hwndTrack = hWnd;\n\t\t\ttme.dwHoverTime = HOVER_DEFAULT;\n            ::TrackMouseEvent( &tme ); // ŃG[nhOĂ܂Ӗ̂Ŗ\n\t\t}\n\t}\n\n\tswitch( msg ) {\n\tcase WM_PAINT: {\n\t\tPAINTSTRUCT ps;\n\t\tHDC hDC = BeginPaint( hWnd, &ps );\n\t\tEndPaint( hWnd, &ps );\n\t\tif( created_ ) OnPaint();\n\t\treturn 0;\n\t}\n\tcase WM_CLOSE: {\n\t\tClose();\n\t\treturn 0;\n\t}\n\n\tcase WM_MOUSELEAVE:\n\t\tif( in_window_ ) {\n\t\t\tOnMouseLeave();\n\t\t\tin_window_ = false;\n\t\t}\n\t\treturn 0;\n\n\tcase WM_MOUSEWHEEL:\n\t\tOnMouseWheel( GET_WHEEL_DELTA_WPARAM(wParam), GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\treturn 0;\n\n\tcase WM_MOUSEMOVE:\n\t\tif( ignore_touch_mouse_ == false || IsTouchEvent( ::GetMessageExtraInfo() ) == false ) {\n\t\t\tOnMouseMove( GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t}\n\t\treturn 0;\n\n\tcase WM_LBUTTONDOWN:\n\t\tif( ignore_touch_mouse_ == false || IsTouchEvent( ::GetMessageExtraInfo() ) == false ) {\n\t\t\tleft_double_click_ = false;\n\t\t\tOnMouseDown( mbLeft, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t}\n\t\treturn 0;\n\tcase WM_LBUTTONUP:\n\t\tif( ignore_touch_mouse_ == false || IsTouchEvent( ::GetMessageExtraInfo() ) == false ) {\n\t\t\tif( left_double_click_ == false ) {\n\t\t\t\tOnMouseClick( mbLeft, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\t}\n\t\t\tleft_double_click_ = false;\n\t\t\tOnMouseUp( mbLeft, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) ); \n\t\t}\n\t\treturn 0;\n\tcase WM_LBUTTONDBLCLK:\n\t\tif( ignore_touch_mouse_ == false || IsTouchEvent( ::GetMessageExtraInfo() ) == false ) {\n\t\t\tleft_double_click_ = true;\n\t\t\tOnMouseDoubleClick( mbLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\tOnMouseDown( mbLeft, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t}\n\t\treturn 0;\n\n\tcase WM_RBUTTONDOWN:\n\t\tOnMouseDown( mbRight, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\treturn 0;\n\tcase WM_RBUTTONUP:\n\t\tOnMouseUp( mbRight, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\treturn 0;\n\tcase WM_RBUTTONDBLCLK: // E_uNbN͖\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\n\tcase WM_MBUTTONDOWN:\n\t\tOnMouseDown( mbMiddle, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\treturn 0;\n\tcase WM_MBUTTONUP:\n\t\tOnMouseUp( mbMiddle, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\treturn 0;\n\tcase WM_MBUTTONDBLCLK: // _uNbN͖\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\n\tcase WM_XBUTTONDBLCLK: // X_uNbN͖\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_XBUTTONUP:\n\t    switch(GET_XBUTTON_WPARAM(wParam)){\n        case XBUTTON1: // TChL[1X{^\n            OnMouseUp( mbX1, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\treturn 0;\n        case XBUTTON2: // TChL[2X{^\n            OnMouseUp( mbX2, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\treturn 0;\n\t\t}\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_XBUTTONDOWN: // ߂iނ蓖Ă\n\t    switch(GET_XBUTTON_WPARAM(wParam)){\n        case XBUTTON1: // TChL[1X{^\n            OnMouseDown( mbX1, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\treturn 0;\n        case XBUTTON2: // TChL[2X{^\n            OnMouseDown( mbX2, GetShiftState(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\t\treturn 0;\n\t\t}\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_TOUCH: {\n\t\t// user32.dll  GetTouchInputInfo ȂǓǂݍ\n\t\tif( procGetTouchInputInfo && procCloseTouchInputHandle ) {\n\t\t\tUINT cInputs = LOWORD(wParam);\n\t\t\tPTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];\n\t\t\tif( NULL != pInputs ) {\n\t\t\t\tOnTouchSequenceStart();\n\t\t\t\ttry {\n\t\t\t\t\tDWORD basetick = TVPGetRoughTickCount32();\n\t\t\t\t\tif( procGetTouchInputInfo( (HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT)) ) {\n\t\t\t\t\t\t// process pInputs\n\t\t\t\t\t\tfor( UINT i = 0; i < cInputs; i++ ) {\n\t\t\t\t\t\t\tint x = pInputs[i].x / 100;\n\t\t\t\t\t\t\tint y = pInputs[i].y / 100;\n\t\t\t\t\t\t\tPOINT pt = {x,y};\n\t\t\t\t\t\t\t::ScreenToClient( GetHandle(), &pt );\n\t\t\t\t\t\t\tint lx = pInputs[i].x % 100;\n\t\t\t\t\t\t\tint ly = pInputs[i].y % 100;\n\t\t\t\t\t\t\tdouble vx = pt.x + static_cast<double>(lx)/100.0;\n\t\t\t\t\t\t\tdouble vy = pt.y + static_cast<double>(ly)/100.0;\n\t\t\t\t\t\t\tdouble cx = 1;\n\t\t\t\t\t\t\tdouble cy = 1;\n\t\t\t\t\t\t\tif( pInputs[i].dwMask & TOUCHINPUTMASKF_CONTACTAREA ) {\n\t\t\t\t\t\t\t\tcx = static_cast<double>(pInputs[i].cxContact) / 100.0;\n\t\t\t\t\t\t\t\tcy = static_cast<double>(pInputs[i].cyContact) / 100.0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tDWORD tick;\n\t\t\t\t\t\t\tif( pInputs[i].dwMask & TOUCHINPUTMASKF_TIMEFROMSYSTEM ) {\n\t\t\t\t\t\t\t\ttick = pInputs[i].dwTime;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttick = basetick;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif( pInputs[i].dwFlags & TOUCHEVENTF_DOWN ) {\n\t\t\t\t\t\t\t\tOnTouchDown( vx, vy, cx, cy, pInputs[i].dwID, tick );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif( pInputs[i].dwFlags & TOUCHEVENTF_MOVE ) {\n\t\t\t\t\t\t\t\tOnTouchMove( vx, vy, cx, cy, pInputs[i].dwID, tick );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif( pInputs[i].dwFlags & TOUCHEVENTF_UP ) {\n\t\t\t\t\t\t\t\tOnTouchUp( vx, vy, cx, cy, pInputs[i].dwID, tick );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif( !procCloseTouchInputHandle((HTOUCHINPUT)lParam) ) {\n\t\t\t\t\t\t\t// error handling\n\t\t\t\t\t\t\tTVPThrowWindowsErrorException();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tTVPThrowWindowsErrorException();\n\t\t\t\t\t}\n\t\t\t\t} catch(...) {\n\t\t\t\t\tOnTouchSequenceEnd();\n\t\t\t\t\tdelete[] pInputs;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tOnTouchSequenceEnd();\n\t\t\t\tdelete[] pInputs;\n\t\t\t} else {\n\t\t\t\t// error handling, presumably out of memory\n\t\t\t\tTVPThrowExceptionMessage( TVPInsufficientMemory );\n\t\t\t}\n\t\t}\n\t\treturn DefWindowProc(hWnd, msg, wParam, lParam);\n\t}\n\tcase WM_GESTURE:\n\t\tif( procGetGestureInfo && procCloseGestureInfoHandle ) {\n\t\t\tGESTUREINFO gi;\n\t\t\tZeroMemory(&gi, sizeof(GESTUREINFO));\n\t\t\tgi.cbSize = sizeof(gi);\n\t\t\tBOOL bResult = procGetGestureInfo((HGESTUREINFO)lParam, &gi);\n\t\t\tBOOL bHandled = FALSE;\n\t\t\tswitch (gi.dwID){\n\t\t\tcase GID_ZOOM:\n\t\t\t\t// Code for zooming goes here\n\t\t\t\t// gi.ullArguments distance\n\t\t\t\tbHandled = TRUE;\n\t\t\t\tbreak;\n\t\t\tcase GID_PAN:\n\t\t\t\t// gi.ullArguments distance\n\t\t\t\tbHandled = TRUE;\n\t\t\t\tbreak;\n\t\t\tcase GID_ROTATE: {\n\t\t\t\t// double rot = GID_ROTATE_ANGLE_FROM_ARGUMENT(gi.ullArguments)\n\t\t\t\t/*\n\t\t\t\tPOINT cpt;\n\t\t\t\tcpt.x = gi.ptsLocation.x;\n\t\t\t\tcpt.y = gi.ptsLocation.y;\n\t\t\t\t::ScreenToClient(gi.hwndTarget,&cpt);\n\t\t\t\t*/\n\t\t\t\tbHandled = TRUE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase GID_TWOFINGERTAP:\n\t\t\t\tbHandled = TRUE;\n\t\t\t\tbreak;\n\t\t\tcase GID_PRESSANDTAP:\n\t\t\t\tbHandled = TRUE;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// You have encountered an unknown gesture\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tprocCloseGestureInfoHandle((HGESTUREINFO)lParam);\n\t\t\tif( bHandled ) return 0;\n\t\t}\n\t\treturn DefWindowProc(hWnd, msg, wParam, lParam);\n\tcase WM_SYSKEYDOWN:\n\tcase WM_KEYDOWN:\n\t\tOnKeyDown( (WORD)wParam, GetShiftState(), lParam&0xffff, (lParam&(1<<30))?true:false );\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_SYSKEYUP:\n\tcase WM_KEYUP:\n\t\tOnKeyUp( (WORD)wParam, GetShiftState() );\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_SYSCHAR:\n\tcase WM_CHAR:\n\t\tOnKeyPress( (WORD)wParam, lParam&0xffff, (lParam&(1<<30))?true:false, (lParam&(1<<31))?true:false );\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\n\tcase WM_SETFOCUS:\n\t\tOnFocus( reinterpret_cast<HWND>(wParam) );\n\t\treturn 0;\n\tcase WM_KILLFOCUS:\n\t\tOnFocusLost( reinterpret_cast<HWND>(wParam) );\n\t\treturn 0;\n\tcase WM_GETMINMAXINFO:\n\t\t{\n\t\t\tMINMAXINFO* lpmmi = (LPMINMAXINFO)lParam;\n\t\t\t// lpmmi->ptMaxPosition ő剻̈ʒu\n\t\t\t// lpmmi->ptMaxSize ő剻̃TCY\n\t\t\t// ŏTCY\n\t\t\tif( min_size_.cx > 0 ) {\n\t\t\t\tlpmmi->ptMinTrackSize.x = min_size_.cx;\n\t\t\t}\n\t\t\tif( min_size_.cy > 0 ) {\n\t\t\t\tlpmmi->ptMinTrackSize.y = min_size_.cy;\n\t\t\t}\n\t\t\tif( max_size_.cx > 0 ) {\n\t\t\t\tlpmmi->ptMaxTrackSize.x = max_size_.cx; // TCYύX̍őTCY\n\t\t\t} else {\n\t\t\t\tlpmmi->ptMaxTrackSize.x = INT_MAX; // TCYύX̍őTCY\n\t\t\t}\n\t\t\tif( max_size_.cy > 0 ) {\n\t\t\t\tlpmmi->ptMaxTrackSize.y = max_size_.cy; // TCYύX̍őTCY\n\t\t\t} else {\n\t\t\t\tlpmmi->ptMaxTrackSize.y = INT_MAX; // TCYύX̍őTCY\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\tcase WM_ACTIVATE: {\n\t\tWPARAM fActive =  wParam & 0xFFFF;\n\t\tif( fActive == WA_INACTIVE ) {\n\t\t\tOnDeactive( (HWND)lParam );\n\t\t} else if( fActive == WA_ACTIVE || fActive == WA_CLICKACTIVE ) {\n\t\t\tOnActive( (HWND)lParam );\n\t\t}\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\t}\n\tcase WM_SYSCOMMAND:\n\t\tif( wParam == SC_CLOSE ) {\n\t\t\tif( in_mode_ ) modal_result_ = mrCancel;\n\t\t} else if( wParam == SC_KEYMENU ) {\n\t\t\tif( HasMenu( hWnd ) == false ) {\n\t\t\t\treturn 0; // j[Ȃ́AR}hāA}EXJ[\\͂̃Xgh\n\t\t\t}\n\t\t}\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\tcase WM_DESTROY:\n\t\tOnDestroy();\n\t\treturn 0;\n\tcase WM_MOVE:\n\t\tOnMove( GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\tbreak;\n\tcase WM_SIZE:\n\t\tOnResize( wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\tbreak;\n\tcase WM_DROPFILES:\n\t\tOnDropFile( reinterpret_cast<HDROP>(wParam) );\n\t\treturn 0;\n\tcase WM_MOUSEACTIVATE:\n\t\treturn OnMouseActivate( reinterpret_cast<HWND>(wParam), LOWORD(lParam), HIWORD(lParam) );\n\tcase WM_SETCURSOR:\n\t\tif( OnSetCursor( reinterpret_cast<HWND>(wParam), LOWORD(lParam), HIWORD(lParam) ) ) return 1;\n\t\tbreak;\n\tcase WM_ENABLE:\n\t\tOnEnable( wParam != 0 );\n\t\tbreak;\n\tcase WM_ENTERMENULOOP:\n\t\tOnEnterMenuLoop( wParam != 0 );\n\t\tbreak;\n\tcase WM_EXITMENULOOP:\n\t\tOnExitMenuLoop( wParam != 0 );\n\t\tbreak;\n\tcase WM_DEVICECHANGE:\n\t\tOnDeviceChange( wParam, reinterpret_cast<void*>(lParam) );\n\t\tbreak;\n\tcase WM_NCLBUTTONDOWN:\n\t\tOnNonClientMouseDown( mbLeft, wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\tbreak;\n\tcase WM_NCRBUTTONDOWN:\n\t\tOnNonClientMouseDown( mbRight, wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) );\n\t\tbreak;\n\tcase WM_SHOWWINDOW:\n\t\tif( wParam ) {\n\t\t\tOnShow( lParam );\n\t\t} else {\n\t\t\tOnHide( lParam );\n\t\t}\n\t\tbreak;\n\tcase TVP_EV_WINDOW_RELEASE:\n\t\t::DestroyWindow( GetHandle() );\n\t\tdelete this;\n\t\tbreak;\n\tcase WM_DISPLAYCHANGE:\n\t\t// bpp, h resolution, v resolution\n\t\tOnDisplayChange( wParam, LOWORD(lParam), HIWORD(lParam) );\n\t\tbreak;\n\tcase WM_ACTIVATEAPP:\n\t\tOnApplicationActivateChange( wParam != 0, (DWORD)lParam );\n\t\tbreak;\n\tdefault:\n\t\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n\t}\n\treturn ::DefWindowProc(hWnd,msg,wParam,lParam);\n}\nvoid tTVPWindow::OnPaint() {\n}\nconst DWORD tTVPWindow::DEFAULT_EX_STYLE = WS_EX_ACCEPTFILES | WS_EX_APPWINDOW;\nconst ULONG tTVPWindow::REGISTER_TOUCH_FLAG = TWF_WANTPALM|TWF_FINETOUCH;\nconst DWORD tTVPWindow::DEFAULT_TABLETPENSERVICE_PROPERTY = (\n\tTABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture\n\tTABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)\n\tTABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)\n\tTABLET_DISABLE_FLICKS // disables pen flicks (back, forward, drag down, drag up)\n\t);\n\nHRESULT tTVPWindow::CreateWnd( const std::wstring& classname, const std::wstring& title, int width, int height, HWND hParent )\n{\n\twindow_class_name_ = classname;\n\twindow_title_ = title;\n\twindow_client_size_.cx = width;\n\twindow_client_size_.cy = height;\n\n\tWNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC | CS_DBLCLKS, tTVPWindow::WndProc, 0L, 0L,\n\t\t\t\t\t\tGetModuleHandle(NULL), NULL, NULL, NULL, NULL,\n\t\t\t\t\t\twindow_class_name_.c_str(), NULL };\n\twc.hIcon = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_TVPWIN32));\n\twc.hIconSm = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_TVPWIN32));\n\n\tWNDCLASSEX tmpwc = { sizeof(WNDCLASSEX) };\n\tBOOL ClassRegistered = ::GetClassInfoEx( wc.hInstance, wc.lpszClassName, &tmpwc );\n\tif( ClassRegistered == 0 ) {\n\t\tif( ::RegisterClassEx( &wc ) == 0 ) {\n#ifdef _DEBUG\n\t\t\tTVPOutputWindowsErrorToDebugMessage();\n#endif\n\t\t\treturn HRESULT_FROM_WIN32(::GetLastError());\n\t\t}\n\t}\n\twc_ = wc;\n\n\tRECT\twinRc = { 0, 0, window_client_size_.cx, window_client_size_.cy };\n\t::AdjustWindowRectEx( &winRc, WS_OVERLAPPEDWINDOW, NULL, DEFAULT_EX_STYLE );\n\tDWORD exStyle = DEFAULT_EX_STYLE;\n\tif( hParent ) {\n\t\texStyle |= WS_EX_CONTROLPARENT;\n\t\thas_parent_ = true;\n\t}\n\twindow_handle_ = ::CreateWindowEx( exStyle, window_class_name_.c_str(), window_title_.c_str(),\n\t\t\t\t\t\tWS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, winRc.right-winRc.left, winRc.bottom-winRc.top,\n\t\t\t\t\t\thParent, NULL, wc.hInstance, NULL );\n\t\n\tif( window_handle_ == NULL ) {\n#ifdef _DEBUG\n\t\t\tTVPOutputWindowsErrorToDebugMessage();\n#endif\n\t\treturn HRESULT_FROM_WIN32(::GetLastError());\n\t}\n\tcreated_ = true;\n\time_control_ = new ImeControl(window_handle_);\n\tborder_style_ = bsSizeable;\n\t\n    ::SetWindowLongPtr( window_handle_, GWLP_WNDPROC, (LONG_PTR)tTVPWindow::WndProc );\n\t::SetWindowLongPtr( window_handle_, GWLP_USERDATA, (LONG_PTR)this );\n\n\t::ShowWindow(window_handle_,SW_HIDE);\n\tif( ::UpdateWindow(window_handle_) == 0 )\n\t\treturn HRESULT_FROM_WIN32(::GetLastError());\n\n\tbool ignore_touch = false;\n\ttTJSVariant touch;\n\tif(TVPGetCommandLine(TJS_W(\"-ignoretouch\"), &touch)) {\n\t\tttstr str = touch;\n\t\tif(str == TJS_W(\"true\")) ignore_touch = true;\n\t}\n\t// n[h}`^b`T|[gĂ邩ǂ\n\tif( procRegisterTouchWindow && ignore_touch == false ) {\n\t\tint value= ::GetSystemMetrics( SM_DIGITIZER );\n\t\tif( (value & (NID_MULTI_INPUT|NID_READY)) == (NID_MULTI_INPUT|NID_READY) ) {\n\t\t\t// }`^b`T|[g & łĂ\n#ifndef TVP_TOUCH_DISABLE\n\t\t\tprocRegisterTouchWindow( window_handle_, REGISTER_TOUCH_FLAG );\n\t\t\tignore_touch_mouse_ = true;\n#endif\n\t\t\t// MICROSOFT_TABLETPENSERVICE_PROPERTY vpeBύX\n\t\t\tATOM atom = ::GlobalAddAtom( MICROSOFT_TABLETPENSERVICE_PROPERTY );\n\t\t\t::SetProp( window_handle_, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast<HANDLE>( DEFAULT_TABLETPENSERVICE_PROPERTY ) );\n\t\t\t::GlobalDeleteAtom( atom );\n\t\t}\n\t}\n\treturn S_OK;\n}\nvoid tTVPWindow::UnregisterWindow() {\n\t::UnregisterClass( window_class_name_.c_str(), wc_.hInstance );\n}\n\nvoid tTVPWindow::SetWidnowTitle( const std::wstring& title ) {\n\tif( window_title_ != title ) {\n\t\twindow_title_ = title;\n\t\tif( window_handle_ ) {\n\t\t\t::SetWindowText( window_handle_, window_title_.c_str() );\n\t\t}\n\t}\n}\n\nvoid tTVPWindow::SetScreenSize( int width, int height ) {\n\tif( window_client_size_.cx != width || window_client_size_.cy != height ) {\n\t\twindow_client_size_.cx = width;\n\t\twindow_client_size_.cy = height;\n\t\tif( window_handle_ ) {\n\t\t\tRECT\twinRc = { 0, 0, window_client_size_.cx, window_client_size_.cy };\n\t\t\t::AdjustWindowRect( &winRc, WS_OVERLAPPEDWINDOW, NULL );\n\t\t\t::SetWindowPos( window_handle_, HWND_TOP, 0, 0, winRc.right-winRc.left, winRc.bottom-winRc.top,\n\t\t\t\tSWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER );\n\t\t}\n\t}\n}\n\nbool tTVPWindow::Initialize() {\n\treturn true;\n}\nvoid tTVPWindow::OnDestroy() {\n\t::SetWindowLongPtr( window_handle_, GWLP_WNDPROC, (LONG_PTR)::DefWindowProc );\n\t::SetWindowLongPtr( window_handle_, GWLP_USERDATA, (LONG_PTR)NULL );\n}\n\nbool tTVPWindow::HasMenu( HWND hWnd ) {\n\tHMENU hMenu = ::GetMenu( hWnd );\n\tif( hMenu ) {\n\t\tint count = ::GetMenuItemCount(hMenu);\n\t\tif( count <= 0 ) {\n\t\t\thMenu = NULL;\n\t\t}\n\t}\n\treturn hMenu != NULL;\n}\nvoid tTVPWindow::SetClientSize( HWND hWnd, SIZE& size ) {\n\tDWORD style = ::GetWindowLong( hWnd, GWL_STYLE );\n\tDWORD exStyle = ::GetWindowLong( hWnd, GWL_EXSTYLE );\n\tRECT rect;\n\t::SetRect( &rect, 0, 0, size.cx, size.cy );\n\tif( ::AdjustWindowRectEx( &rect, style, HasMenu( hWnd ) ? TRUE : FALSE, exStyle ) ) {\n\t\tRECT rect2;\n\t\tif( ::GetWindowRect( hWnd, &rect2 ) ) {\n\t\t\tif( ::SetWindowPos( hWnd, NULL, rect2.left, rect2.top, rect.right-rect.left, rect.bottom-rect.top, SIZE_CHANGE_FLAGS ) == 0 ) {\n\t\t\t\tTVPThrowWindowsErrorException();\n\t\t\t}\n\t\t} else {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\n\n\n// \\\nbool tTVPWindow::GetVisible() const {\n\treturn ::IsWindowVisible( GetHandle() ) ? true : false;\n}\nvoid tTVPWindow::SetVisible( bool s ) {\n\t::ShowWindow( GetHandle(), s ? SW_SHOW : SW_HIDE );\n}\n\nbool tTVPWindow::GetEnable() const {\n\treturn ::IsWindowEnabled( GetHandle() ) ? true : false;\n}\nvoid tTVPWindow::SetEnable( bool s ) {\n\t::EnableWindow( GetHandle(), s ? TRUE : FALSE );\n}\n\nvoid tTVPWindow::GetCaption( std::wstring& v ) const {\n\tv.clear();\n\tint len = ::GetWindowTextLength( GetHandle() );\n\tif( len > 0 ) {\n\t\tstd::vector<wchar_t> caption(len+1,0);\n\t\tint readlen = ::GetWindowText( GetHandle(), &(caption[0]), len+1 );\n\t\tif( readlen > 0 ) {\n\t\t\tv.assign( &(caption[0]) );\n\t\t}\n\t}\n}\nvoid tTVPWindow::SetCaption( const std::wstring& v ) {\n\tif( window_title_ != v ) {\n\t\twindow_title_ = v;\n\t\t::SetWindowText( GetHandle(), window_title_.c_str() );\n\t}\n}\n\nvoid tTVPWindow::SetBorderStyle(tTVPBorderStyle st) {\n\tconst DWORD notStyle = WS_POPUP | WS_CAPTION | WS_BORDER | WS_THICKFRAME | WS_DLGFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;\n\tDWORD style = ::GetWindowLong( GetHandle(), GWL_STYLE);\n\tstyle &= ~notStyle;\n\tDWORD exStyle = ::GetWindowLong( GetHandle(), GWL_EXSTYLE);\n\texStyle &= ~DEFAULT_EX_STYLE;\n\tif( has_parent_ ) {\n\t\texStyle |= WS_EX_CONTROLPARENT;\n\t}\n\tborder_style_ = static_cast<int>(st);\n\tswitch( st ) {\n\tcase bsDialog:\n\t\tstyle |= WS_DLGFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU;\n\t\texStyle |= WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;\n\t\tbreak;\n\tcase bsSingle:\n\t\tstyle |= WS_CAPTION | WS_BORDER;\n\t\tstyle |= WS_MINIMIZEBOX | WS_SYSMENU;\n\t\tbreak;\n\tcase bsNone:\n\t\tstyle |= WS_POPUP;\n\t\tstyle |= WS_MINIMIZEBOX;\n\t\tif( has_parent_ ) {\n\t\t\texStyle |= WS_EX_TOOLWINDOW; // taskbar unlist\n\t\t} else {\n\t\t\tstyle |= WS_SYSMENU; // taskbar right click menu\n\t\t}\n\t\tbreak;\n\tcase bsSizeable:\n\t\tstyle |= WS_CAPTION | WS_THICKFRAME;\n\t\tstyle |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;\n\t\tbreak;\n\tcase bsToolWindow:\n\t\tstyle |= WS_CAPTION | WS_BORDER;\n\t\tstyle |= WS_SYSMENU;\n\t\texStyle |= WS_EX_TOOLWINDOW;\n\t\tbreak;\n\tcase bsSizeToolWin:\n\t\tstyle |= WS_CAPTION | WS_THICKFRAME;\n\t\tstyle |= WS_SYSMENU;\n\t\texStyle |= WS_EX_TOOLWINDOW;\n\t\tbreak;\n\tdefault:\n\t\tstyle = ::GetWindowLong( GetHandle(), GWL_STYLE);\n\t\texStyle = ::GetWindowLong( GetHandle(), GWL_EXSTYLE);\n\t\tbreak;\n\t}\n\t::SetWindowLong( GetHandle(), GWL_STYLE, style );\n\t::SetWindowLong( GetHandle(), GWL_EXSTYLE, exStyle );\n\tif( st == bsDialog ) {\n\t\t::SendMessage( GetHandle(), WM_SETICON, ICON_BIG, LPARAM(GetBigIcon()));\n\t} else {\n\t\t::SendMessage( GetHandle(), WM_SETICON, ICON_BIG, 0 );\n\t}\n\t::GetSystemMenu( GetHandle(), TRUE );\n\t::SendMessage( GetHandle(), WM_NCCREATE, 0, 0 );\n\t::SetWindowPos( GetHandle(), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );\n\t::InvalidateRect( GetHandle(), NULL, TRUE );\n}\ntTVPBorderStyle tTVPWindow::GetBorderStyle() const {\n\treturn static_cast<tTVPBorderStyle>(border_style_);\n}\nHICON tTVPWindow::GetBigIcon() {\n\treturn (HICON)SendMessage( GetHandle(), WM_GETICON, ICON_BIG, 0 );\n}\n\nconst UINT tTVPWindow::SIZE_CHANGE_FLAGS = SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;\n\nvoid tTVPWindow::SetWidth( int w ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, rect.left, rect.top, w, rect.bottom-rect.top, SIZE_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\n\nint tTVPWindow::GetWidth() const {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\treturn rect.right - rect.left;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\n\nvoid tTVPWindow::SetHeight( int h ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, rect.left, rect.top, rect.right-rect.left, h, SIZE_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\n\nint tTVPWindow::GetHeight() const {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\treturn rect.bottom - rect.top;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\n\nvoid tTVPWindow::SetSize( int w, int h ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, rect.left, rect.top, w, h, SIZE_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nvoid tTVPWindow::GetSize( int &w, int &h ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\th = rect.bottom - rect.top;\n\t\tw = rect.right - rect.left;\n\t} else {\n\t\th = w = 0;\n\t}\n}\nconst UINT tTVPWindow::POS_CHANGE_FLAGS = SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER;\n\nvoid tTVPWindow::SetLeft( int l ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, l, rect.top, rect.right-rect.left, rect.bottom-rect.top, POS_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nint tTVPWindow::GetLeft() const {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\treturn rect.left;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\nvoid tTVPWindow::SetTop( int t ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, rect.left, t, rect.right-rect.left, rect.bottom-rect.top, POS_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nint tTVPWindow::GetTop() const {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\treturn rect.top;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\nvoid tTVPWindow::SetPosition( int l, int t ) {\n\tRECT rect;\n\tif( ::GetWindowRect( GetHandle(), &rect ) ) {\n\t\tif( ::SetWindowPos( GetHandle(), NULL, l, t, rect.right-rect.left, rect.bottom-rect.top, POS_CHANGE_FLAGS ) == 0 ) {\n\t\t\tTVPThrowWindowsErrorException();\n\t\t}\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nvoid tTVPWindow::SetBounds( int x, int y, int width, int height ) {\n\tif( ::SetWindowPos( GetHandle(), NULL, x, y, width, height, SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER ) == 0 ) {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nvoid tTVPWindow::SetInnerWidth( int w ) {\n\tRECT rect;\n\tif( ::GetClientRect( GetHandle(), &rect ) ) {\n\t\tSIZE size;\n\t\tsize.cx = w;\n\t\tsize.cy = rect.bottom - rect.top;\n\t\tSetClientSize( GetHandle(), size );\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\n\nint tTVPWindow::GetInnerWidth() const {\n\tRECT rect;\n\tif( ::GetClientRect( GetHandle(), &rect ) ) {\n\t\treturn rect.right - rect.left;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\nvoid tTVPWindow::SetInnerHeight( int h ) {\n\tRECT rect;\n\tif( ::GetClientRect( GetHandle(), &rect ) ) {\n\t\tSIZE size;\n\t\tsize.cx = rect.right - rect.left;\n\t\tsize.cy = h;\n\t\tSetClientSize( GetHandle(), size );\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\n\nint tTVPWindow::GetInnerHeight() const {\n\tRECT rect;\n\tif( ::GetClientRect( GetHandle(), &rect ) ) {\n\t\treturn rect.bottom - rect.top;\n\t} else {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn 0;\n\t}\n}\n\nvoid tTVPWindow::SetInnerSize( int w, int h ) {\n\tSIZE size;\n\tsize.cx = w;\n\tsize.cy = h;\n\tSetClientSize( GetHandle(), size );\n}\n\nvoid tTVPWindow::BringToFront() {\n\tif( ::SetWindowPos( GetHandle(), HWND_TOP, 0, 0, 0, 0, (SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE) ) == 0 ) {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nvoid tTVPWindow::SetStayOnTop( bool b ) {\n\tstatic const UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOSENDCHANGING;\n\tif( ::SetWindowPos( GetHandle(), b ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, flags ) == 0 ) {\n\t\tTVPThrowWindowsErrorException();\n\t}\n}\nbool tTVPWindow::GetStayOnTop() const {\n\tDWORD exStyle = ::GetWindowLong( GetHandle(), GWL_EXSTYLE );\n\tif( exStyle == 0 ) {\n\t\tTVPThrowWindowsErrorException();\n\t\treturn false;\n\t}\n\treturn (exStyle & WS_EX_TOPMOST) ? true : false;\n}\n\nvoid tTVPWindow::GetClientRect( struct tTVPRect& rt ) {\n\tRECT r;\n\tif( ::GetClientRect( GetHandle(), &r ) == 0 ) {\n\t\tTVPThrowWindowsErrorException();\n\t}\n\trt.top = r.top;\n\trt.left = r.left;\n\trt.bottom = r.bottom;\n\trt.right = r.right;\n}\n\nvoid tTVPWindow::Close() {\n\tif( in_mode_ ) {\n\t\tmodal_result_ = mrCancel;\n\t} else if( OnCloseQuery() ) {\n\t\tCloseAction action = caFree;\n\t\tOnClose(action);\n\t\tswitch( action ) {\n\t\tcase caNone:\n\t\t\tbreak;\n\t\tcase caHide:\n\t\t\tHide();\n\t\t\tbreak;\n\t\tcase caMinimize:\n\t\t\t::ShowWindow( GetHandle(), SW_MINIMIZE );\n\t\t\tbreak;\n\t\tcase caFree:\n\t\tdefault:\n\t\t\t::PostMessage( GetHandle(), TVP_EV_WINDOW_RELEASE, 0, 0 );\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid tTVPWindow::closeModal() {\n\ttry {\n\t\tCloseAction action = caNone;\n\t\tif( OnCloseQuery() ) {\n\t\t\taction = caHide;\n\t\t\tOnClose(action);\n\t\t}\n\t\tswitch( action ) {\n\t\tcase caNone:\n\t\t\tmodal_result_ = 0;\n\t\t\tbreak;\n\t\tcase caFree:\n\t\t\t::PostMessage( GetHandle(), TVP_EV_WINDOW_RELEASE, 0, 0 );\n\t\t\tbreak;\n\t\t}\n\t} catch(...) {\n\t\tmodal_result_ = 0;\n\t\tthrow;\n\t}\n}\nint tTVPWindow::ShowModal() {\n\tif( GetVisible() || !GetEnable() ) {\n\t\tthrow Exception( (const tjs_char*)TVPCannotShowModalAreadyShowed );\n\t}\n\tif( Application->GetWindowCount() == 1 ) {\n\t\t// 1 WindowȂModalӖȂ̂ƁAs̌Ȃ̂ŗO\n\t\tthrow Exception( (const tjs_char*)TVPCannotShowModalSingleWindow );\n\t}\n\tif( in_mode_ == false ) in_mode_ = true;\n\ttry {\n\t\tif( ::GetCapture() != 0 ) {\n\t\t\t::SendMessage( ::GetCapture(), WM_CANCELMODE, 0, 0 );\n\t\t}\n\t\t::ReleaseCapture();\n\t\tApplication->ModalStarted( this );\n\t\tstd::vector<class TTVPWindowForm*> enableWindows;\n\t\ttry {\n\t\t\tApplication->GetEnableWindowList( enableWindows, NULL );\n\t\t\tApplication->DisableWindows();\n\t\t\tSetEnable( true );\n\t\t\tShow();\n\t\t\t::SetActiveWindow( GetHandle() );\n\t\t\tmodal_result_ = 0;\n\t\t\twhile( modal_result_ == 0 ) {\n\t\t\t\tApplication->HandleMessage();\n\t\t\t\tif( Application->IsTarminate() ) {\n\t\t\t\t\tmodal_result_ = mrCancel;\n\t\t\t\t} else if( modal_result_ != 0 ) {\n\t\t\t\t\tcloseModal();\n\t\t\t\t}\n\t\t\t}\n\t\t\tApplication->EnableWindows( enableWindows );\n\t\t\tenableWindows.clear();\n\t\t} catch(...) {\n\t\t\tif( enableWindows.size() > 0 ) {\n\t\t\t\tApplication->EnableWindows( enableWindows );\n\t\t\t}\n\t\t\tenableWindows.clear();\n\t\t\tApplication->ModalFinished();\n\t\t\tin_mode_ = false;\n\t\t\tHide();\n\t\t\tthrow;\n\t\t}\n\t\tApplication->ModalFinished();\n\t\tin_mode_ = false;\n\t\tHide();\n\t\treturn modal_result_;\n\t} catch(...) {\n\t\tin_mode_ = false;\n\t\tthrow;\n\t}\n}\n"
  },
  {
    "path": "src/core/environ/win32/TVPWindow.h",
    "content": "\n#ifndef __TVP_WINDOW_H__\n#define __TVP_WINDOW_H__\n\n#include <string>\n#if 0\n#include <shellapi.h>\n#include <oleidl.h> // for MK_ALT\n#include \"tvpinputdefs.h\"\n#include \"SystemImpl.h\"\n#include \"ImeControl.h\"\n\n#ifndef MK_ALT \n#define MK_ALT (0x20)\n#endif\n#endif\nenum {\n\t ssShift = TVP_SS_SHIFT,\n\t ssAlt = TVP_SS_ALT,\n\t ssCtrl = TVP_SS_CTRL,\n\t ssLeft = TVP_SS_LEFT,\n\t ssRight = TVP_SS_RIGHT,\n\t ssMiddle = TVP_SS_MIDDLE,\n\t ssDouble = TVP_SS_DOUBLE,\n\t ssRepeat = TVP_SS_REPEAT,\n};\n#if 0\nclass tTVPWindow {\n\tWNDCLASSEX\twc_;\n\tbool\t\tcreated_;\n\nprotected:\n\tenum CloseAction {\n\t  caNone,\n\t  caHide,\n\t  caFree,\n\t  caMinimize\n\t};\n\tenum FormState {\n\t\tfsCreating,\n\t\tfsVisible,\n\t\tfsShowing,\n\t\tfsModal,\n\t\tfsCreatedMDIChild,\n\t\tfsActivated\n\t};\n\n\tHWND\t\t\t\twindow_handle_;\n\n\tstd::wstring\twindow_class_name_;\n\tstd::wstring\twindow_title_;\n\tSIZE\t\twindow_client_size_;\n\tSIZE\t\tmin_size_;\n\tSIZE\t\tmax_size_;\n\tint\t\t\tborder_style_;\n\tbool\t\tin_window_;\n\tbool\t\tignore_touch_mouse_;\n\n\tbool in_mode_;\n\tint modal_result_;\n\n\tbool has_parent_;\n\n\tstatic const UINT SIZE_CHANGE_FLAGS;\n\tstatic const UINT POS_CHANGE_FLAGS;\n\tstatic const DWORD DEFAULT_EX_STYLE;\n\tstatic const ULONG REGISTER_TOUCH_FLAG;\n\tstatic const DWORD DEFAULT_TABLETPENSERVICE_PROPERTY;\n\tstatic const DWORD MI_WP_SIGNATURE;\n\tstatic const DWORD SIGNATURE_MASK;\n\n\tbool left_double_click_;\n\n\tImeControl* ime_control_;\n\n\tenum ModeFlag {\n\t\tFALG_FULLSCREEN = 0x01,\n\t};\n\t\n\tunsigned long flags_;\n\tvoid SetFlag( unsigned long f ) {\n\t\tflags_ |= f;\n\t}\n\tvoid ResetFlag( unsigned long f ) {\n\t\tflags_ &= ~f;\n\t}\n\tbool GetFlag( unsigned long f ) {\n\t\treturn 0 != (flags_ & f);\n\t}\n\t\n\tvoid UnregisterWindow();\n\n\t// window procedure\n\tstatic LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\n\tvirtual LRESULT WINAPI Proc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\n\tHRESULT CreateWnd( const std::wstring& classname, const std::wstring& title, int width, int height, HWND hParent=NULL );\n\n\tvirtual void OnDestroy();\n\tvirtual void OnPaint();\n\n\tinline int GetAltKeyState() const {\n\t\tif( ::GetKeyState( VK_MENU  ) < 0 ) {\n\t\t\treturn MK_ALT;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\tinline int GetShiftState( WPARAM wParam ) const {\n\t\tint shift = GET_KEYSTATE_WPARAM(wParam) & (MK_SHIFT|MK_CONTROL);\n\t\tshift |= GetAltKeyState();\n\t\treturn shift;\n\t}\n\tinline int GetShiftState() const {\n\t\tint shift = 0;\n\t\tif( ::GetKeyState( VK_MENU  ) < 0 ) shift |= MK_ALT;\n\t\tif( ::GetKeyState( VK_SHIFT ) < 0 ) shift |= MK_SHIFT;\n\t\tif( ::GetKeyState( VK_CONTROL ) < 0 ) shift |= MK_CONTROL;\n\t\treturn shift;\n\t}\n\tinline int GetMouseButtonState() const {\n\t\tint s = 0;\n\t\tif(TVPGetAsyncKeyState(VK_LBUTTON)) s |= ssLeft;\n\t\tif(TVPGetAsyncKeyState(VK_RBUTTON)) s |= ssRight;\n\t\tif(TVPGetAsyncKeyState(VK_MBUTTON)) s |= ssMiddle;\n\t\treturn s;\n\t}\n\tinline bool IsTouchEvent(LPARAM extraInfo) const {\n\t\treturn (extraInfo & SIGNATURE_MASK) == MI_WP_SIGNATURE;\n\t}\n\n\tvoid SetMouseCapture() {\n\t\t::SetCapture( GetHandle() );\n\t}\n\tvoid ReleaseMouseCapture() {\n\t\t::ReleaseCapture();\n\t}\n\tHICON GetBigIcon();\n\n\tstatic bool HasMenu( HWND hWnd );\npublic:\n\ttTVPWindow()\n\t: window_handle_(NULL), created_(false), left_double_click_(false), ime_control_(NULL), border_style_(0), modal_result_(0),\n\t\tin_window_(false), ignore_touch_mouse_(false), in_mode_(false), has_parent_(false) {\n\t\tmin_size_.cx = min_size_.cy = 0;\n\t\tmax_size_.cx = max_size_.cy = 0;\n\t}\n\tvirtual ~tTVPWindow();\n\n\tbool HasFocus() const {\n\t\treturn window_handle_ == ::GetFocus();\n\t}\n\tbool IsValidHandle() const {\n\t\treturn ( window_handle_ != NULL && window_handle_ != INVALID_HANDLE_VALUE && ::IsWindow(window_handle_) );\n\t}\n\n\tvirtual bool Initialize();\n\n\tvoid SetWidnowTitle( const std::wstring& title );\n\tvoid SetScreenSize( int width, int height );\n\n\tHWND GetHandle() { return window_handle_; }\n\tHWND GetHandle() const { return window_handle_; }\n\n\tImeControl* GetIME() { return ime_control_; }\n\tconst ImeControl* GetIME() const { return ime_control_; }\n\n\tstatic void SetClientSize( HWND hWnd, SIZE& size );\n\n//-- properties\n\tbool GetVisible() const;\n\tvoid SetVisible(bool s);\n\tvoid Show() { SetVisible( true ); BringToFront(); }\n\tvoid Hide() { SetVisible( false ); }\n\n\tbool GetEnable() const;\n\tvoid SetEnable( bool s );\n\n\tvoid GetCaption( std::wstring& v ) const;\n\tvoid SetCaption( const std::wstring& v );\n\t\n\tvoid SetBorderStyle( enum tTVPBorderStyle st);\n\tenum tTVPBorderStyle GetBorderStyle() const;\n\n\tvoid SetWidth( int w );\n\tint GetWidth() const;\n\tvoid SetHeight( int h );\n\tint GetHeight() const;\n\tvoid SetSize( int w, int h );\n\tvoid GetSize( int &w, int &h );\n\n\tvoid SetLeft( int l );\n\tint GetLeft() const;\n\tvoid SetTop( int t );\n\tint GetTop() const;\n\tvoid SetPosition( int l, int t );\n\t\n\tvoid SetBounds( int x, int y, int width, int height );\n\n\tvoid SetMinWidth( int v ) {\n\t\tmin_size_.cx = v;\n\t\tCheckMinMaxSize();\n\t}\n\tint GetMinWidth() const{ return min_size_.cx; }\n\tvoid SetMinHeight( int v ) {\n\t\tmin_size_.cy = v;\n\t\tCheckMinMaxSize();\n\t}\n\tint GetMinHeight() const { return min_size_.cy; }\n\tvoid SetMinSize( int w, int h ) {\n\t\tmin_size_.cx = w;\n\t\tmin_size_.cy = h;\n\t\tCheckMinMaxSize();\n\t}\n\n\tvoid SetMaxWidth( int v ) {\n\t\tmax_size_.cx = v;\n\t\tCheckMinMaxSize();\n\t}\n\tint GetMaxWidth() const{ return max_size_.cx; }\n\tvoid SetMaxHeight( int v ) {\n\t\tmax_size_.cy = v;\n\t\tCheckMinMaxSize();\n\t}\n\tint GetMaxHeight() const{ return max_size_.cy; }\n\tvoid SetMaxSize( int w, int h ) {\n\t\tmax_size_.cx = w;\n\t\tmax_size_.cy = h;\n\t\tCheckMinMaxSize();\n\t}\n\tvoid CheckMinMaxSize() {\n\t\tint maxw = max_size_.cx;\n\t\tint maxh = max_size_.cy;\n\t\tint minw = min_size_.cx;\n\t\tint minh = min_size_.cy;\n\t\tint dw, dh;\n\t\tGetSize( dw, dh );\n\t\tint sw = dw;\n\t\tint sh = dh;\n\t\tif( maxw > 0 && dw > maxw ) dw = maxw;\n\t\tif( maxh > 0 && dh > maxh ) dh = maxh;\n\t\tif( minw > 0 && dw < minw ) dw = minw;\n\t\tif( minh > 0 && dh < minh ) dh = minh;\n\t\tif( sw != dw || sh != dh ) {\n\t\t\tSetSize( dw, dh );\n\t\t}\n\t}\n\n\tvoid SetInnerWidth( int w );\n\tint GetInnerWidth() const;\n\tvoid SetInnerHeight( int h );\n\tint GetInnerHeight() const;\n\tvoid SetInnerSize( int w, int h );\n\t\n\tvoid BringToFront();\n\tvoid SetStayOnTop( bool b );\n\tbool GetStayOnTop() const;\n\n\tint ShowModal();\n\tvoid closeModal();\n\tbool IsModal() const { return in_mode_; }\n\tvoid Close();\n\n\tvoid GetClientRect( struct tTVPRect& rt );\n\n\t// bZ[Wnh\n\tvirtual void OnActive( HWND preactive ) {}\n\tvirtual void OnDeactive( HWND postactive ) {}\n\tvirtual void OnClose( CloseAction& action ){}\n\tvirtual bool OnCloseQuery() { return true; }\n\tvirtual void OnFocus(HWND hFocusLostWnd) {}\n\tvirtual void OnFocusLost(HWND hFocusingWnd) {}\n\tvirtual void OnMouseDown( int button, int shift, int x, int y ){}\n\tvirtual void OnMouseUp( int button, int shift, int x, int y ){}\n\tvirtual void OnMouseMove( int shift, int x, int y ){}\n\tvirtual void OnMouseDoubleClick( int button, int x, int y ) {}\n\tvirtual void OnMouseClick( int button, int shift, int x, int y ){}\n\tvirtual void OnMouseWheel( int delta, int shift, int x, int y ){}\n\tvirtual void OnKeyUp( WORD vk, int shift ){}\n\tvirtual void OnKeyDown( WORD vk, int shift, int repeat, bool prevkeystate ){}\n\tvirtual void OnKeyPress( WORD vk, int repeat, bool prevkeystate, bool convertkey ){}\n\tvirtual void OnMove( int x, int y ) {}\n\tvirtual void OnResize( UINT_PTR state, int w, int h ) {}\n\tvirtual void OnDropFile( HDROP hDrop ) {}\n\tvirtual int OnMouseActivate( HWND hTopLevelParentWnd, WORD hitTestCode, WORD MouseMsg ) { return MA_ACTIVATE; }\n\tvirtual bool OnSetCursor( HWND hContainsCursorWnd, WORD hitTestCode, WORD MouseMsg ) { return false; }\n\tvirtual void OnEnable( bool enabled ) {}\n\tvirtual void OnEnterMenuLoop( bool entered ) {}\n\tvirtual void OnExitMenuLoop( bool isShortcutMenu ) {}\n\tvirtual void OnDeviceChange( UINT_PTR event, void *data ) {}\n\tvirtual void OnNonClientMouseDown( int button, UINT_PTR hittest, int x, int y ){}\n\tvirtual void OnMouseEnter() {}\n\tvirtual void OnMouseLeave() {}\n\tvirtual void OnShow( UINT_PTR status ) {}\n\tvirtual void OnHide( UINT_PTR status ) {}\n\n\tvirtual void OnTouchDown( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {}\n\tvirtual void OnTouchMove( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {}\n\tvirtual void OnTouchUp( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {}\n\tvirtual void OnTouchSequenceStart() {}\n\tvirtual void OnTouchSequenceEnd() {}\n\n\tvirtual void OnDisplayChange( UINT_PTR bpp, WORD hres, WORD vres ) {}\n\tvirtual void OnApplicationActivateChange( bool activated, DWORD thread_id ) {}\n};\n#endif\n\nenum tTVPWMRRegMode { wrmRegister = 0, wrmUnregister = 1 };\nenum {\n\torientUnknown,\n\torientPortrait,\n\torientLandscape,\n};\n\nnamespace cocos2d {\n\tclass Node;\n}\n\nclass iWindowLayer {\nprotected:\n\ttTVPMouseCursorState MouseCursorState = mcsVisible;\n\ttjs_int HintDelay = 500;\n\ttjs_int ZoomDenom = 1; // Zooming factor denominator (setting)\n\ttjs_int ZoomNumer = 1; // Zooming factor numerator (setting)\n\tdouble TouchScaleThreshold = 5, TouchRotateThreshold = 5;\n\npublic:\n\tvirtual void SetPaintBoxSize(tjs_int w, tjs_int h) = 0;\n\tvirtual bool GetFormEnabled() = 0;\n\tvirtual void SetDefaultMouseCursor() = 0;\n\tvirtual void GetCursorPos(tjs_int &x, tjs_int &y) = 0;\n\tvirtual void SetCursorPos(tjs_int x, tjs_int y) = 0;\n\tvirtual void SetHintText(const ttstr &text) = 0;\n\tvirtual void SetAttentionPoint(tjs_int left, tjs_int top, const struct tTVPFont * font) = 0;\n\tvirtual void ZoomRectangle(\n\t\ttjs_int & left, tjs_int & top,\n\t\ttjs_int & right, tjs_int & bottom) = 0;\n\tvirtual void BringToFront() = 0;\n\tvirtual void ShowWindowAsModal() = 0;\n\tvirtual bool GetVisible() = 0;\n\tvirtual void SetVisible(bool bVisible) = 0;\n\tvirtual const char *GetCaption() = 0;\n\tvirtual void SetCaption(const std::string &) = 0;\n\tvirtual void SetWidth(tjs_int w) = 0;\n\tvirtual void SetHeight(tjs_int h) = 0;\n\tvirtual void SetSize(tjs_int w, tjs_int h) = 0;\n\tvirtual void GetSize(tjs_int &w, tjs_int &h) = 0;\n\tvirtual tjs_int GetWidth() const = 0;\n\tvirtual tjs_int GetHeight() const = 0;\n\tvirtual void GetWinSize(tjs_int &w, tjs_int &h) = 0;\n\tvirtual void SetZoom(tjs_int numer, tjs_int denom) = 0;\n\tvirtual void UpdateDrawBuffer(iTVPTexture2D *tex) = 0;\n#if 0\n\tvirtual void AddOverlay(tTJSNI_BaseVideoOverlay *ovl) = 0;\n\tvirtual void RemoveOverlay(tTJSNI_BaseVideoOverlay *ovl) = 0;\n\tvirtual void UpdateOverlay() = 0;\n#endif\n\tvirtual void InvalidateClose() = 0;\n\tvirtual bool GetWindowActive() = 0;\n\tvirtual void Close() = 0;\n\tvirtual void OnCloseQueryCalled(bool b) = 0;\n\tvirtual void InternalKeyDown(tjs_uint16 key, tjs_uint32 shift) = 0;\n\tvirtual void OnKeyUp(tjs_uint16 vk, int shift) = 0;\n\tvirtual void OnKeyPress(tjs_uint16 vk, int repeat, bool prevkeystate, bool convertkey) = 0;\n\tvirtual tTVPImeMode GetDefaultImeMode() const = 0;\n\tvirtual void SetImeMode(tTVPImeMode mode) = 0;\n\tvirtual void ResetImeMode() = 0;\n\tvirtual void UpdateWindow(tTVPUpdateType type) = 0;\n\tvirtual void SetVisibleFromScript(bool b) = 0;\n\tvirtual void SetUseMouseKey(bool b) = 0;\n\tvirtual bool GetUseMouseKey() const = 0;\n\tvirtual void ResetMouseVelocity() = 0;\n\tvirtual void ResetTouchVelocity(tjs_int id) = 0;\n\tvirtual bool GetMouseVelocity(float& x, float& y, float& speed) const = 0;\n\tvirtual void TickBeat() = 0;\n\tvirtual cocos2d::Node *GetPrimaryArea() = 0;\n\n\tvoid SetZoomNumer(tjs_int n) { SetZoom(n, ZoomDenom); }\n\ttjs_int GetZoomNumer() const { return ZoomNumer; }\n\tvoid SetZoomDenom(tjs_int d) { SetZoom(ZoomNumer, d); }\n\ttjs_int GetZoomDenom() const { return ZoomDenom; }\n\n\t// dummy function\n\tvoid RegisterWindowMessageReceiver(tTVPWMRRegMode mode, void * proc, const void *userdata) {}\n\tvoid SetLeft(tjs_int) {}\n\tvoid SetTop(tjs_int) {}\n\tvoid SetMinWidth(tjs_int) {}\n\tvoid SetMaxWidth(tjs_int) {}\n\tvoid SetMinHeight(tjs_int) {}\n\tvoid SetMaxHeight(tjs_int) {}\n\tvoid SetInnerWidth(tjs_int v) { SetWidth(v); }\n\tvoid SetInnerHeight(tjs_int v) { SetHeight(v); }\n\tvoid SetInnerSize(tjs_int w, tjs_int h) { SetSize(w, h); }\n\tvoid SetMinSize(tjs_int, tjs_int) {}\n\tvoid SetMaxSize(tjs_int, tjs_int) {}\n\tvoid SetPosition(tjs_int, tjs_int) {}\n\tvoid SetBorderStyle(tTVPBorderStyle) {}\n\tvoid SetStayOnTop(bool) {}\n\tvoid SetFullScreenMode(bool) {}\n\ttjs_int GetLeft() { return 0; }\n\ttjs_int GetTop() { return 0; }\n\ttjs_int GetMinWidth() { return 0; }\n\ttjs_int GetMaxWidth() { return 1920; }\n\ttjs_int GetMinHeight() { return 0; }\n\ttjs_int GetMaxHeight() { return 1080; }\n\ttjs_int GetInnerWidth() { return GetWidth(); }\n\ttjs_int GetInnerHeight() { return GetHeight(); }\n\tbool GetStayOnTop() { return false; }\n\tbool GetFullScreenMode() { return false; }\n\ttTVPBorderStyle GetBorderStyle() const { return bsNone; }\n\tvoid SetTrapKey(bool b) {}\n\tbool GetTrapKey() const { return false; }\n\tvoid RemoveMaskRegion() {}\n\tvoid SetMouseCursorState(tTVPMouseCursorState mcs) { MouseCursorState = mcs; }\n\ttTVPMouseCursorState GetMouseCursorState() const { return MouseCursorState; }\n\tvoid HideMouseCursor() { }\n\tvoid SetFocusable(bool b) {}\n\tbool GetFocusable() const { return true; }\n\tint GetDisplayRotate() { return 0; }\n\tint GetDisplayOrientation() { return orientLandscape; }\n\tvoid SetEnableTouch(bool b) {}\n\tbool GetEnableTouch() const { return false; }\n\tvoid SetHintDelay(tjs_int delay) { HintDelay = delay; }\n\ttjs_int GetHintDelay() const { return HintDelay; }\n\tvoid SetInnerSunken(bool b) {}\n\tbool GetInnerSunken() const { return false; }\n\n\t// TODO\n\tvoid SetMouseCursor(tjs_int handle) {}\n\tvoid SetHintText(iTJSDispatch2* sender, const ttstr &text) {}\n\tvoid DisableAttentionPoint() {}\n\tvoid GetVideoOffset(tjs_int &ofsx, tjs_int &ofsy) { ofsx = 0; ofsy = 0; }\n\tvoid SetTouchScaleThreshold(double threshold) { TouchScaleThreshold = threshold; }\n\tdouble GetTouchScaleThreshold() { return TouchScaleThreshold; }\n\tvoid SetTouchRotateThreshold(double threshold) { TouchRotateThreshold = threshold; }\n\tdouble GetTouchRotateThreshold() { return TouchRotateThreshold; }\n\ttjs_real GetTouchPointStartX(tjs_int index) const { return 0; }\n\ttjs_real GetTouchPointStartY(tjs_int index) const { return 0; }\n\ttjs_real GetTouchPointX(tjs_int index) const { return 0; }\n\ttjs_real GetTouchPointY(tjs_int index) const { return 0; }\n\ttjs_int GetTouchPointID(tjs_int index) const { return 0; }\n\ttjs_int GetTouchPointCount() const { return 0; }\n\tbool GetTouchVelocity(tjs_int id, float& x, float& y, float& speed) const { return false; }\n\tvoid ResetDrawDevice() {}\n\tvoid SendCloseMessage() {}\n\tvoid BeginMove() {}\n\tvoid SetLayerLeft(tjs_int l) {}\n\ttjs_int GetLayerLeft() const { return 0; }\n\tvoid SetLayerTop(tjs_int t) {}\n\ttjs_int GetLayerTop() const { return 0; }\n\tvoid SetLayerPosition(tjs_int l, tjs_int t) {}\n\tvoid SetShowScrollBars(bool b) {}\n\tbool GetShowScrollBars() const { return true; }\n};\n\n#endif // __TVP_WINDOW_H__\n"
  },
  {
    "path": "src/core/environ/win32/TouchPoint.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"TouchPoint.h\"\n\nconst double TouchPointList::SCALE_THRESHOLD = 5;\nconst double TouchPointList::ROTATE_THRESHOLD = 5;\n\n"
  },
  {
    "path": "src/core/environ/win32/TouchPoint.h",
    "content": "// ˑł͂Ȃ񂱂\n\n#ifndef __TOUCH_POINT_H__\n#define __TOUCH_POINT_H__\n\n#include <cmath>\n\nclass TouchHandler {\npublic:\n\tstatic const int START_EVENT = 0x01 << 0;\n\n\tvirtual void OnTouchScaling( double startdist, double currentdist, double cx, double cy, int flag ) = 0;\n\tvirtual void OnTouchRotate( double startangle, double currentangle, double distance, double cx, double cy, int flag ) = 0;\n\tvirtual void OnMultiTouch() = 0;\n};\n\nstruct TouchPoint {\n\tstatic const int USE_POINT = 0x01 << 0;\n\tstatic const int START_SCALING = 0x01 << 1;\n\tstatic const int START_ROT = 0x01 << 2;\n\ttjs_uint32 id;\n\tdouble sx;\n\tdouble sy;\n\tdouble x;\n\tdouble y;\n\ttjs_uint32 flag;\n\ttjs_uint32 tick;\n\tTouchPoint() : id(0), sx(0), sy(0), x(0), y(0), flag(0), tick(0) {\n\t}\n};\n\n\nclass TouchPointList {\n\tstatic const double SCALE_THRESHOLD;\n\tstatic const double ROTATE_THRESHOLD;\n\tstatic const int INIT_COUNT = 4;\n\n\tTouchHandler* handler_;\n\tTouchPoint* touch_points_;\n\tint count_;\n\n\tdouble scale_threshold_;\n\tdouble rotate_threshold_;\n\nprivate:\n\tint FindEmptyEntry() {\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( (touch_points_[i].flag & TouchPoint::USE_POINT) == 0 ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\tint idx = count_;\n\t\tGrowPoints();\n\t\treturn idx;\n\t}\n\tint FindEntry( tjs_uint32 id ) {\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( (touch_points_[i].flag & TouchPoint::USE_POINT) && (touch_points_[i].id == id) ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\tint FindOtherEntry( tjs_uint32 id ) {\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( (touch_points_[i].flag & TouchPoint::USE_POINT) && (touch_points_[i].id != id) ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\tvoid ClearIndex( int index ) {\n\t\tmemset( &touch_points_[index], 0, sizeof(TouchPoint) );\n\t}\n\tvoid GrowPoints() {\n\t\tint count = count_ * 2;\n\t\tTouchPoint* points = new TouchPoint[count];\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tpoints[i] = touch_points_[i];\n\t\t}\n\t\tdelete[] touch_points_;\n\t\ttouch_points_ = points;\n\t\tcount_ = count;\n\t}\npublic:\n\tTouchPointList( TouchHandler* handler )\n\t: handler_(handler) {\n\t\tscale_threshold_ = SCALE_THRESHOLD;\n\t\trotate_threshold_ = ROTATE_THRESHOLD;\n\t\tcount_ = INIT_COUNT;\n\t\ttouch_points_ = new TouchPoint[count_];\n\t}\n\t~TouchPointList() {\n\t\tif( touch_points_ ) delete[] touch_points_;\n\t\ttouch_points_ = NULL;\n\t}\n\t\n\tvoid TouchDown( double x, double y, double cx, double cy, tjs_uint32 id, tjs_uint32 tick ) {\n\t\tint idx = FindEmptyEntry();\n\t\ttouch_points_[idx].sx = touch_points_[idx].x = x;\n\t\ttouch_points_[idx].sy = touch_points_[idx].y = y;\n\t\ttouch_points_[idx].flag = TouchPoint::USE_POINT;\n\t\ttouch_points_[idx].id = id;\n\t\ttouch_points_[idx].tick = tick;\n\t\tint num_of_points = CountUsePoint();\n\t\tif( num_of_points >= 2 ) {\n\t\t\thandler_->OnMultiTouch();\n\t\t}\n\t}\n\tvoid TouchMove( double x, double y, double cx, double cy, tjs_uint32 id, tjs_uint32 tick ) {\n\t\tint num_of_points = CountUsePoint();\n\t\t// 2_^b`̂ݔ\n\t\tif( num_of_points == 2 ) {\n\t\t\tint targetidx = FindOtherEntry(id);\n\t\t\tint selfidx = FindEntry( id );\n\t\t\tif( targetidx >= 0 && selfidx >= 0 ) {\n\t\t\t\tTouchPoint& target = touch_points_[targetidx];\n\t\t\t\tTouchPoint& self = touch_points_[selfidx];\n\n\t\t\t\tdouble dx = (target.sx - self.sx);\n\t\t\t\tdouble dy = (target.sy - self.sy);\n\t\t\t\tdouble startdistance = std::sqrt( dx*dx +dy*dy );\n\t\t\t\tdouble startangle = std::atan2( dy, dx );\n\t\t\t\tdx = (target.x - x);\n\t\t\t\tdy = (target.y - y);\n\t\t\t\tdouble currentdistance = std::sqrt( dx*dx +dy*dy );\n\t\t\t\tdouble curentangle = std::atan2( dy, dx );\n\t\t\t\tdouble cx = (target.x + x) * 0.5;\n\t\t\t\tdouble cy = (target.y + y) * 0.5;\n\n\t\t\t\tdouble distance = std::abs(currentdistance-startdistance);\n\t\t\t\tbool scale_started = (self.flag & TouchPoint::START_SCALING) != 0;\n\t\t\t\tif( scale_started || (distance > scale_threshold_) ) {\n\t\t\t\t\tif( (target.flag & TouchPoint::START_SCALING) == 0 ) {\n\t\t\t\t\t\tint flag = ( scale_started == false ) ? TouchHandler::START_EVENT : 0;\n\t\t\t\t\t\tself.flag |= TouchPoint::START_SCALING;\n\t\t\t\t\t\thandler_->OnTouchScaling( startdistance, currentdistance, cx, cy, flag );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdx = self.sx - x;\n\t\t\t\tdy = self.sy - y;\n\t\t\t\tdouble dist = std::sqrt( dx*dx +dy*dy );\n\t\t\t\tdx = target.sx - target.x;\n\t\t\t\tdy = target.sy - target.y;\n\t\t\t\tdist += std::sqrt( dx*dx +dy*dy );\n\t\t\t\tbool rotate_started = (self.flag & TouchPoint::START_ROT) != 0;\n\t\t\t\tif( rotate_started || (dist > rotate_threshold_) ) {\n\t\t\t\t\tif( (target.flag & TouchPoint::START_ROT) == 0 ) {\n\t\t\t\t\t\tint flag = ( rotate_started == false ) ? TouchHandler::START_EVENT : 0;\n\t\t\t\t\t\tself.flag |= TouchPoint::START_ROT;\n\t\t\t\t\t\thandler_->OnTouchRotate( startangle, curentangle, currentdistance, cx, cy, flag );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tint selfidx = FindEntry( id );\n\t\tif( selfidx >= 0 ) {\n\t\t\tTouchPoint& self = touch_points_[selfidx];\n\t\t\tself.x = x;\n\t\t\tself.y = y;\n\t\t\tself.tick = tick;\n\t\t}\n\t\tif( num_of_points >= 2 ) {\n\t\t\thandler_->OnMultiTouch();\n\t\t}\n\t}\n\tvoid TouchUp( double x, double y, double cx, double cy, tjs_uint32 id, tjs_uint32 tick ) {\n\t\tint num_of_points = CountUsePoint();\n\t\tif( num_of_points >= 2 ) {\n\t\t\thandler_->OnMultiTouch();\n\t\t}\n\n\t\tint idx = FindEntry(id);\n\t\tif( idx >= 0 ) {\n\t\t\tClearIndex(idx);\n\t\t}\n\t}\n\tvoid SetScaleThreshold( double threshold ) {\n\t\tscale_threshold_ = threshold;\n\t}\n\tdouble GetScaleThreshold() const {\n\t\treturn scale_threshold_;\n\t}\n\tvoid SetRotateThreshold( double threshold ) {\n\t\trotate_threshold_ = threshold;\n\t}\n\tdouble GetRotateThreshold() const {\n\t\treturn rotate_threshold_;\n\t}\n\tint CountUsePoint() const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn count;\n\t}\n\tdouble GetStartX( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].sx;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tdouble GetStartY( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].sy;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tdouble GetX( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].x;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tdouble GetY( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].y;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\ttjs_uint32 GetID( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].id;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\ttjs_uint32 GetTick( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn touch_points_[i].tick;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tbool Validate( int index ) const {\n\t\tint count = 0;\n\t\tfor( int i = 0; i < count_; i++ ) {\n\t\t\tif( touch_points_[i].flag & TouchPoint::USE_POINT ) {\n\t\t\t\tif( count == index ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n};\n\n#endif // __TOUCH_POINT_H__\n"
  },
  {
    "path": "src/core/environ/win32/VersionFormUnit.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Version information dialog box\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"Resource.h\"\n\n#include \"MsgIntf.h\"\n#include \"VersionFormUnit.h\"\n#include \"SystemControl.h\"\n#include \"WindowImpl.h\"\n\n#include \"VersionFormUnit.h\"\n#include \"DebugIntf.h\"\n#include \"ClipboardIntf.h\"\n\n//---------------------------------------------------------------------------\n// TVPCopyImportantLogToClipboard\n//---------------------------------------------------------------------------\nvoid TVPCopyImportantLogToClipboard()\n{\n\t// get Direct3D driver information\n\tTVPEnsureDirect3DObject();\n\tTVPDumpDirect3DDriverInformation();\n\n\t// copy\n\tTVPClipboardSetText(TVPGetImportantLog());\n}\n\nstatic LRESULT WINAPI DlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\n\tswitch( msg ) {\n\tcase WM_INITDIALOG: {\n\t\t::SetDlgItemText( hWnd, IDC_INFOMATION_EDIT, TVPGetAboutString().AsStdString().c_str() );\n\t\treturn TRUE;\n\t}\n\tcase WM_COMMAND:\n\t\tif(LOWORD(wParam) == IDOK) {\n\t\t\t//OK{^ꂽƂ̏\n\t\t\t::EndDialog(hWnd, IDOK);\n\t\t\treturn TRUE;\n\t\t} else if(LOWORD(wParam) == IDC_COPY_INFO_BUTTON) {\n\t\t\tTVPCopyImportantLogToClipboard();\n\t\t\treturn TRUE;\n\t\t}\n\t\tbreak;\n\tcase WM_CLOSE:\n\t\tEndDialog(hWnd, 0);\n\t\treturn TRUE;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn FALSE;\n}\n//---------------------------------------------------------------------------\nvoid TVPShowVersionForm()\n{\n\t// get Direct3D driver information\n\tTVPEnsureDirect3DObject();\n\tTVPDumpDirect3DDriverInformation();\n\t::DialogBox( NULL, MAKEINTRESOURCE(IDD_VERSION_DIALOG), NULL, (DLGPROC)DlgProc );\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/environ/win32/VersionFormUnit.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Version information dialog box\n//---------------------------------------------------------------------------\n\n#ifndef VersionFormUnitH\n#define VersionFormUnitH\n\nextern void TVPShowVersionForm();\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/environ/win32/WindowFormUnit.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#define DIRECTDRAW_VERSION 0x0300\n//#include <ddraw.h>\n\n//#include <dbt.h> // for WM_DEVICECHANGE\n\n#include <algorithm>\n#include \"WindowFormUnit.h\"\n#include \"WindowImpl.h\"\n#include \"EventIntf.h\"\n#include \"ComplexRect.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"tjsArray.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"SystemControl.h\"\n#include \"SysInitIntf.h\"\n#include \"PluginImpl.h\"\n#include \"Random.h\"\n#include \"SystemImpl.h\"\n#include \"DInputMgn.h\"\n#include \"tvpinputdefs.h\"\n\n#include \"Application.h\"\n#include \"TVPSysFont.h\"\n#include \"TickCount.h\"\n#include \"WindowsUtil.h\"\n#include \"vkdefine.h\"\n#if 0\n#include \"CompatibleNativeFuncs.h\"\n\n\ntjs_uint32 TVP_TShiftState_To_uint32(TShiftState state) {\n\ttjs_uint32 result = 0;\n\tif( state & MK_SHIFT ) {\n\t\tresult |= ssShift;\n\t}\n\tif( state & MK_CONTROL ) {\n\t\tresult |= ssCtrl;\n\t}\n\tif( state & MK_ALT ) {\n\t\tresult |= ssAlt;\n\t}\n\treturn result;\n}\nTShiftState TVP_TShiftState_From_uint32(tjs_uint32 state){\n\tTShiftState result = 0;\n\tif( state & ssShift ) {\n\t\tresult |= MK_SHIFT;\n\t}\n\tif( state & ssCtrl ) {\n\t\tresult |= MK_CONTROL;\n\t}\n\tif( state & ssAlt ) {\n\t\tresult |= MK_ALT;\n\t}\n\treturn result;\n}\ntTVPMouseButton TVP_TMouseButton_To_tTVPMouseButton(int button) {\n\treturn (tTVPMouseButton)button;\n}\n#endif\n\n//---------------------------------------------------------------------------\n// Modal Window List\n//---------------------------------------------------------------------------\n// modal window list is used to ensure modal window accessibility when\n// the system is full-screened,\nstd::vector<TTVPWindowForm *> TVPModalWindowList;\n//---------------------------------------------------------------------------\nstatic void TVPAddModalWindow(TTVPWindowForm * window)\n{\n\tstd::vector<TTVPWindowForm *>::iterator i;\n\ti = std::find(TVPModalWindowList.begin(), TVPModalWindowList.end(), window);\n\tif(i == TVPModalWindowList.end())\n\t\tTVPModalWindowList.push_back(window);\n}\n//---------------------------------------------------------------------------\nstatic void TVPRemoveModalWindow(TTVPWindowForm *window)\n{\n\tstd::vector<TTVPWindowForm *>::iterator i;\n\ti = std::find(TVPModalWindowList.begin(), TVPModalWindowList.end(), window);\n\tif(i != TVPModalWindowList.end())\n\t\tTVPModalWindowList.erase(i);\n}\n//---------------------------------------------------------------------------\n#include \"DebugIntf.h\"\n#if 0\nvoid TVPShowModalAtAppActivate()\n{\n\t// called when the application is activated\n\tif(TVPFullScreenedWindow != NULL)\n\t{\n\t\t// any window is full-screened\n\t\t::ShowWindow(TVPFullScreenedWindow->GetHandle(), SW_RESTORE); // restore the window\n\n\t\t// send message which brings modal windows to front\n\t\tstd::vector<TTVPWindowForm *>::iterator i;\n\t\tfor(i = TVPModalWindowList.begin(); i != TVPModalWindowList.end(); i++)\n\t\t\t(*i)->InvokeShowVisible();\n\t\tfor(i = TVPModalWindowList.begin(); i != TVPModalWindowList.end(); i++)\n\t\t\t(*i)->InvokeShowTop();\n\t}\n}\n//---------------------------------------------------------------------------\nHDWP TVPShowModalAtTimer(HDWP hdwp)\n{\n\t// called every 4 seconds, to ensure the modal window visible\n\tif(TVPFullScreenedWindow != NULL)\n\t{\n\t\t// send message which brings modal windows to front\n\t\tstd::vector<TTVPWindowForm *>::iterator i;\n\t\tfor(i = TVPModalWindowList.begin(); i != TVPModalWindowList.end(); i++)\n\t\t\thdwp = (*i)->ShowTop(hdwp);\n\t}\n\treturn hdwp;\n}\n//---------------------------------------------------------------------------\nvoid TVPHideModalAtAppDeactivate()\n{\n\t// called when the application is deactivated\n\tif(TVPFullScreenedWindow != NULL)\n\t{\n\t\t// any window is full-screened\n\n\t\t// hide modal windows\n\t\tstd::vector<TTVPWindowForm *>::iterator i;\n\t\tfor(i = TVPModalWindowList.begin(); i != TVPModalWindowList.end(); i++)\n\t\t\t(*i)->SetVisible( false );\n\t}\n\n\t// hide also popups\n\tTTVPWindowForm::DeliverPopupHide();\n}\n//---------------------------------------------------------------------------\n#endif\n\n//---------------------------------------------------------------------------\n// Window/Bitmap options\n//---------------------------------------------------------------------------\nstatic bool TVPWindowOptionsInit = false;\nstatic bool TVPControlImeState = true;\n//---------------------------------------------------------------------------\nvoid TVPInitWindowOptions()\n{\n\t// initialize various options around window/graphics\n\tif(TVPWindowOptionsInit) return;\n\n\ttTJSVariant val;\n\n\tif(TVPGetCommandLine(TJS_W(\"-wheel\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"dinput\"))\n\t\t\tTVPWheelDetectionType = wdtDirectInput;\n\t\telse if(str == TJS_W(\"message\"))\n\t\t\tTVPWheelDetectionType = wdtWindowMessage;\n\t\telse\n\t\t\tTVPWheelDetectionType = wdtNone;\n\t}\n\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif(TVPGetCommandLine(TJS_W(\"-joypad\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"dinput\"))\n\t\t\tTVPJoyPadDetectionType = jdtDirectInput;\n\t\telse\n\t\t\tTVPJoyPadDetectionType = jdtNone;\n\t}\n#endif\n\n\tif(TVPGetCommandLine(TJS_W(\"-controlime\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"no\"))\n\t\t\tTVPControlImeState = false;\n\t}\n\n\tTVPWindowOptionsInit = true;\n}\n//---------------------------------------------------------------------------\n\n\nTTVPWindowForm::TTVPWindowForm( tTVPApplication* app, tTJSNI_Window* ni, tTJSNI_Window* parent ) : tTVPWindow(), CurrentMouseCursor(crDefault), touch_points_(this),\n\tLayerLeft(0), LayerTop(0), LayerWidth(32), LayerHeight(32),\n\tLastMouseDownX(0), LastMouseDownY(0),\n\tHintTimer(NULL), HintDelay(TVP_TOOLTIP_SHOW_DELAY), LastHintSender(NULL),\n\tFullScreenDestRect(0,0,0,0) {\n\tCreateWnd(L\"TVPMainWindow\", Application->GetTitle(), 10, 10, parent);\n\tTVPInitWindowOptions();\n\t\n\t// initialize members\n\tTJSNativeInstance = ni;\n\tapp->AddWindow(this);\n\t\n\tNextSetWindowHandleToDrawDevice = true;\n\tLastSentDrawDeviceDestRect.clear();\n\n\tin_mode_ = false;\n\tFocusable = true;\n\tClosing = false;\n\tProgramClosing = false;\n\tmodal_result_ = 0;\n\tInnerWidthSave = GetInnerWidth();\n\tInnerHeightSave = GetInnerHeight();\n\n\n\tAttentionPointEnabled = false;\n\tAttentionPoint.x = 0;\n\tAttentionPoint.y = 0;\n\tAttentionFont = new tTVPSysFont();\n\n\tZoomDenom = ActualZoomDenom = 1;\n\tZoomNumer = ActualZoomNumer = 1;\n\n\tDefaultImeMode = imClose;\n\tLastSetImeMode = imClose;\n//\t::PostMessage( GetHandle(), TVP_WM_ACQUIREIMECONTROL, 0, 0);\n\n\n\tUseMouseKey = false;\n\tTrapKeys = false;\n\tCanReceiveTrappedKeys = false;\n\tInReceivingTrappedKeys = false;\n\tMouseKeyXAccel = 0;\n\tMouseKeyYAccel = 0;\n\tLastMouseMoved = false;\n\tMouseLeftButtonEmulatedPushed = false;\n\tMouseRightButtonEmulatedPushed = false;\n\tLastMouseMovedPos.x = 0;\n\tLastMouseMovedPos.y = 0;\n\n\tMouseCursorState = mcsVisible;\n\tForceMouseCursorVisible = false;\n\tCurrentMouseCursor = crDefault;\n\tMouseCursorManager.SetCursorIndex( CurrentMouseCursor, NULL );\n\n\tDIWheelDevice = NULL;\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tDIPadDevice = NULL;\n#endif\n\tReloadDevice = false;\n\tReloadDeviceTick = 0;\n\t\n\tLastRecheckInputStateSent = 0;\n\tSetBorderStyle( bsSizeable );\n\n\tDisplayOrientation = orientUnknown;\n\tDisplayRotate = -1;\n}\nTTVPWindowForm::~TTVPWindowForm() {\n\tif( HintTimer ) {\n\t\tdelete HintTimer;\n\t\tHintTimer = NULL;\n\t}\n\tif( AttentionFont ) {\n\t\tdelete AttentionFont;\n\t\tAttentionFont = NULL;\n\t}\n\tif( DIWheelDevice ) {\n\t\tdelete DIWheelDevice;\n\t\tDIWheelDevice = NULL;\n\t}\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif( DIPadDevice ) {\n\t\tdelete DIPadDevice;\n\t\tDIPadDevice = NULL;\n\t}\n#endif\n\tApplication->RemoveWindow( this );\n}\nvoid TTVPWindowForm::OnDestroy() {\n\tCallWindowDetach(true);\n\n\tCleanupFullScreen();\n\tTJSNativeInstance = NULL;\n\tTVPRemoveModalWindow(this);\n\n\tFreeDirectInputDevice();\n\n\tif( AttentionFont ) {\n\t\tdelete AttentionFont, AttentionFont = NULL;\n\t}\n\n\ttjs_int count = WindowMessageReceivers.GetCount();\n\tfor(tjs_int i = 0 ; i < count; i++)\n\t{\n\t\ttTVPMessageReceiverRecord * item = WindowMessageReceivers[i];\n\t\tif(!item) continue;\n\t\tdelete item;\n\t\tWindowMessageReceivers.Remove(i);\n\t}\n\t\n\tApplication->RemoveWindow(this);\n\ttTVPWindow::OnDestroy();\n}\nvoid TTVPWindowForm::CleanupFullScreen() {\n\t// called at destruction\n\tif(TVPFullScreenedWindow != this) return;\n\tTVPFullScreenedWindow = NULL;\n}\n\ntjs_uint32 TVPGetCurrentShiftKeyState() {\n\ttjs_uint32 f = 0;\n\n\tif(TVPGetAsyncKeyState(VK_SHIFT)) f += TVP_SS_SHIFT;\n\tif(TVPGetAsyncKeyState(VK_MENU)) f += TVP_SS_ALT;\n\tif(TVPGetAsyncKeyState(VK_CONTROL)) f += TVP_SS_CTRL;\n\tif(TVPGetAsyncKeyState(VK_LBUTTON)) f += TVP_SS_LEFT;\n\tif(TVPGetAsyncKeyState(VK_RBUTTON)) f += TVP_SS_RIGHT;\n\tif(TVPGetAsyncKeyState(VK_MBUTTON)) f += TVP_SS_MIDDLE;\n\n\treturn f;\n}\nTTVPWindowForm * TVPFullScreenedWindow;\n\nenum {\n\tCM_BASE = 0xB000,\n\tCM_MOUSEENTER = CM_BASE + 19,\n\tCM_MOUSELEAVE = CM_BASE + 20,\n};\n#if 0\nbool TTVPWindowForm::FindKeyTrapper(LRESULT &result, UINT msg, WPARAM wparam, LPARAM lparam) {\n\t// find most recent \"trapKeys = true\" window.\n\ttjs_int count = TVPGetWindowCount();\n\tfor( tjs_int i = count - 1; i >= 0; i-- ) {\n\t\ttTJSNI_Window * win = TVPGetWindowListAt(i);\n\t\tif( win ) {\n\t\t\tTTVPWindowForm * form = win->GetForm();\n\t\t\tif( form ) {\n\t\t\t\tif( form->TrapKeys && form->GetVisible() ) {\n\t\t\t\t\t// found\n\t\t\t\t\treturn form->ProcessTrappedKeyMessage(result, msg, wparam, lparam);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// not found\n\treturn false;\n}\nbool TTVPWindowForm::ProcessTrappedKeyMessage(LRESULT &result, UINT msg, WPARAM wparam, LPARAM lparam) {\n\t// perform key message\n\tif( msg == WM_KEYDOWN ) {\n\t\tCanReceiveTrappedKeys = true;\n\t\t\t// to prevent receiving a key, which is pushed when the window is just created\n\t}\n\n\tif( CanReceiveTrappedKeys ) {\n\t\tInReceivingTrappedKeys = true;\n\t\tresult = tTVPWindow::Proc( GetHandle(), msg, wparam, lparam );\n\t\tInReceivingTrappedKeys = false;\n\t}\n\tif( msg == WM_KEYUP ) \t{\n\t\tCanReceiveTrappedKeys = true;\n\t}\n\treturn true;\n}\nLRESULT WINAPI TTVPWindowForm::Proc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {\n\ttTVPWindowMessage Message;\n\tMessage.LParam = lParam;\n\tMessage.WParam = wParam;\n\tMessage.Msg = msg;\n\tMessage.Result = 0;\n\tif( DeliverMessageToReceiver( Message) ) return Message.Result;\n\n\tif( Message.Msg == WM_SYSCOMMAND ) {\n\t\tlong subcom = Message.WParam & 0xfff0;\n\t\tbool ismain = false;\n\t\tif( TJSNativeInstance ) ismain = TJSNativeInstance->IsMainWindow();\n\t\tif( ismain ) {\n\t\t\tif( subcom == SC_MINIMIZE && !Application->IsIconic() ) {\n\t\t\t\tApplication->Minimize();\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif(subcom == SC_RESTORE && Application->IsIconic() ) {\n\t\t\t\tApplication->Restore();\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t} else if(!InReceivingTrappedKeys // to prevent infinite recursive call\n\t\t&& Message.Msg >= WM_KEYFIRST && Message.Msg <= WM_KEYLAST ) {\n\t\t// hide popups when alt key is pressed\n\t\tif(Message.Msg == WM_SYSKEYDOWN && !CanSendPopupHide())\n\t\t\tDeliverPopupHide();\n\n\t\t// drain message to key trapping window\n\t\tLRESULT res;\n\t\tif(FindKeyTrapper(res, Message.Msg, Message.WParam, Message.LParam)) {\n\t\t\tMessage.Result = res;\n\t\t\treturn res;\n\t\t}\n\t}\n\tswitch( msg ) {\n\tcase TVP_WM_SHOWVISIBLE:\n\t\tWMShowVisible();\n\t\treturn 0;\n\tcase TVP_WM_SHOWTOP:\n\t\tWMShowTop(wParam);\n\t\treturn 0;\n\tcase TVP_WM_RETRIEVEFOCUS:\n\t\tWMRetrieveFocus();\n\t\treturn 0;\n\tcase TVP_WM_ACQUIREIMECONTROL:\n\t\tWMAcquireImeControl();\n\t\treturn 0;\n\tdefault:\n\t\treturn tTVPWindow::Proc( hWnd, msg, wParam, lParam );\n\t}\n}\nvoid TTVPWindowForm::WMShowVisible() {\n\tSetVisible(true);\n}\nvoid TTVPWindowForm::WMShowTop( WPARAM wParam ) {\n\tif( GetVisible() ) {\n\t\t::SetWindowPos( GetHandle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOSIZE|SWP_SHOWWINDOW);\n\t}\n}\nvoid TTVPWindowForm::WMRetrieveFocus() {\n\tApplication->BringToFront();\n\tSetFocus( GetHandle() );\n}\n\nvoid TTVPWindowForm::WMAcquireImeControl() {\n\tAcquireImeControl();\n}\n#endif\nbool TTVPWindowForm::GetFormEnabled() {\n\treturn TRUE == ::IsWindowEnabled(GetHandle());\n}\n\nvoid TTVPWindowForm::TickBeat(){\n\t// called every 50ms intervally\n\tDWORD tickcount = static_cast<DWORD>(TVPGetTickCount());\n\tbool focused = HasFocus();\n\n\t// mouse key\n\tif(UseMouseKey &&  focused) {\n\t\tGenerateMouseEvent(false, false, false, false);\n\t}\n#if 0\n\t// device reload\n\tif( ReloadDevice && (int)(tickcount - ReloadDeviceTick) > 0) {\n\t\tReloadDevice = false;\n\t\tFreeDirectInputDevice();\n\t\tCreateDirectInputDevice();\n\t}\n#endif\n\t// wheel rotation detection\n\ttjs_uint32 shift = TVPGetCurrentShiftKeyState();\n\tif( TVPWheelDetectionType == wdtDirectInput ) {\n\t\tCreateDirectInputDevice();\n\t\tif( focused && TJSNativeInstance && DIWheelDevice ) {\n\t\t\ttjs_int delta = DIWheelDevice->GetWheelDelta();\n\t\t\tif( delta ) {\n\t\t\t\tPOINT origin = {0,0};\n\t\t\t\t::ClientToScreen( GetHandle(), &origin );\n\n\t\t\t\tPOINT mp = {0, 0};\n\t\t\t\t::GetCursorPos(&mp);\n\t\t\t\ttjs_int x = mp.x - origin.x;\n\t\t\t\ttjs_int y = mp.y - origin.y;\n\t\t\t\tTranslateWindowToDrawArea( x, y);\n\t\t\t\tTVPPostInputEvent(new tTVPOnMouseWheelInputEvent(TJSNativeInstance, shift, delta, x, y));\n\t\t\t}\n\t\t}\n\t}\n\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\t// pad detection\n\tif( TVPJoyPadDetectionType == jdtDirectInput ) {\n\t\tCreateDirectInputDevice();\n\t\tif( DIPadDevice && TJSNativeInstance ) {\n\t\t\tif( focused )\n\t\t\t\tDIPadDevice->UpdateWithCurrentState();\n\t\t\telse\n\t\t\t\tDIPadDevice->UpdateWithSuspendedState();\n\n\t\t\tconst std::vector<WORD> & uppedkeys  = DIPadDevice->GetUppedKeys();\n\t\t\tconst std::vector<WORD> & downedkeys = DIPadDevice->GetDownedKeys();\n\t\t\tconst std::vector<WORD> & repeatkeys = DIPadDevice->GetRepeatKeys();\n\t\t\tstd::vector<WORD>::const_iterator i;\n\n\t\t\t// for upped pad buttons\n\t\t\tfor(i = uppedkeys.begin(); i != uppedkeys.end(); i++) {\n\t\t\t\tInternalKeyUp(*i, shift);\n\t\t\t}\n\t\t\t// for downed pad buttons\n\t\t\tfor(i = downedkeys.begin(); i != downedkeys.end(); i++) {\n\t\t\t\tInternalKeyDown(*i, shift);\n\t\t\t}\n\t\t\t// for repeated pad buttons\n\t\t\tfor(i = repeatkeys.begin(); i != repeatkeys.end(); i++) {\n\t\t\t\tInternalKeyDown(*i, shift|TVP_SS_REPEAT);\n\t\t\t}\n\t\t}\n\t}\n#endif\n\n\t// check RecheckInputState\n\tif( tickcount - LastRecheckInputStateSent > 1000 ) {\n\t\tLastRecheckInputStateSent = tickcount;\n\t\tif(TJSNativeInstance) TJSNativeInstance->RecheckInputState();\n\t}\n}\nbool TTVPWindowForm::GetWindowActive() {\n\treturn ::GetForegroundWindow() == GetHandle();\n}\nvoid TTVPWindowForm::SetDrawDeviceDestRect()\n{\n\ttTVPRect destrect;\n\ttjs_int w = MulDiv(LayerWidth,  ActualZoomNumer, ActualZoomDenom);\n\ttjs_int h = MulDiv(LayerHeight, ActualZoomNumer, ActualZoomDenom);\n\tif( w < 1 ) w = 1;\n\tif( h < 1 ) h = 1;\n\tif( GetFullScreenMode() ) {\n\t\tdestrect.left = FullScreenDestRect.left;\n\t\tdestrect.top = FullScreenDestRect.top;\n\t\tdestrect.right = destrect.left + w;\n\t\tdestrect.bottom = destrect.top + h;\n\t} else {\n\t\tdestrect.left = destrect.top = 0;\n\t\tdestrect.right = w;\n\t\tdestrect.bottom = h;\n\t}\n\n\tif( LastSentDrawDeviceDestRect != destrect ) {\n\t\tif( TJSNativeInstance ) {\n\t\t\tif( GetFullScreenMode() ) {\n\t\t\t\tTJSNativeInstance->GetDrawDevice()->SetClipRectangle(FullScreenDestRect);\n\t\t\t} else {\n\t\t\t\tTJSNativeInstance->GetDrawDevice()->SetClipRectangle(destrect);\n\t\t\t}\n\t\t\tTJSNativeInstance->GetDrawDevice()->SetDestRectangle(destrect);\n\t\t}\n\t\tLastSentDrawDeviceDestRect = destrect;\n\t}\n}\nvoid TTVPWindowForm::OnPaint() {\n\t// a painting event\n\tif( NextSetWindowHandleToDrawDevice ) {\n\t\tbool ismain = false;\n\t\tif( TJSNativeInstance ) ismain = TJSNativeInstance->IsMainWindow();\n\t\tif( TJSNativeInstance ) TJSNativeInstance->GetDrawDevice()->SetTargetWindow( GetHandle(), ismain);\n\t\tNextSetWindowHandleToDrawDevice = false;\n\t}\n\n\tSetDrawDeviceDestRect();\n\n\tif( TJSNativeInstance ) {\n\t\ttTVPRect r;\n\t\tGetClientRect( r );\n\t\tTJSNativeInstance->NotifyWindowExposureToLayer(r);\n\t}\n}\n\nvoid TTVPWindowForm::SetUseMouseKey( bool b ) {\n\tUseMouseKey = b;\n\tif( b ) {\n\t\tMouseLeftButtonEmulatedPushed = false;\n\t\tMouseRightButtonEmulatedPushed = false;\n\t\tLastMouseKeyTick = GetTickCount();\n\t} else {\n\t\tif(MouseLeftButtonEmulatedPushed) {\n\t\t\tMouseLeftButtonEmulatedPushed = false;\n\t\t\tOnMouseUp( mbLeft, 0, LastMouseMovedPos.x, LastMouseMovedPos.y);\n\t\t}\n\t\tif(MouseRightButtonEmulatedPushed) {\n\t\t\tMouseRightButtonEmulatedPushed = false;\n\t\t\tOnMouseUp( mbRight, 0, LastMouseMovedPos.x, LastMouseMovedPos.y);\n\t\t}\n\t}\n}\nbool TTVPWindowForm::GetUseMouseKey() const {\n\treturn UseMouseKey;\n}\n\nvoid TTVPWindowForm::SetTrapKey(bool b) {\n\tTrapKeys = b;\n\tif( TrapKeys ) {\n\t\t// reset CanReceiveTrappedKeys and InReceivingTrappedKeys\n\t\tCanReceiveTrappedKeys = false;\n\t\tInReceivingTrappedKeys = false;\n\t\t// note that SetTrapKey can be called while the key trapping is processing.\n\t}\n}\nbool TTVPWindowForm::GetTrapKey() const {\n\treturn TrapKeys;\n}\n\nvoid TTVPWindowForm::SetMaskRegion(HRGN threshold)\n{\n\t::SetWindowRgn(GetHandle(), threshold, GetVisible() ? TRUE : FALSE );\n}\nvoid TTVPWindowForm::RemoveMaskRegion()\n{\n\t::SetWindowRgn(GetHandle(), NULL, GetVisible() ? TRUE : FALSE );\n}\n\nvoid TTVPWindowForm::HideMouseCursor() {\n\t// hide mouse cursor temporarily\n    SetMouseCursorState(mcsTempHidden);\n}\nvoid TTVPWindowForm::SetMouseCursorState(tTVPMouseCursorState mcs) {\n\tif(MouseCursorState == mcsVisible && mcs != mcsVisible) {\n\t\t// formerly visible and newly invisible\n\t\tif(!ForceMouseCursorVisible) SetMouseCursorVisibleState(false);\n\t} else if(MouseCursorState != mcsVisible && mcs == mcsVisible) {\n\t\t// formerly invisible and newly visible\n\t\tif(!ForceMouseCursorVisible) SetMouseCursorVisibleState(true);\n\t}\n\n\tif(MouseCursorState != mcs && mcs == mcsTempHidden) {\n\t\tPOINT pt;\n\t\t::GetCursorPos(&pt);\n\t\tLastMouseScreenX = pt.x;\n\t\tLastMouseScreenY = pt.y;\n\t}\n\tMouseCursorState = mcs;\n}\n\nvoid TTVPWindowForm::RestoreMouseCursor() {\n\t// restore mouse cursor hidden by HideMouseCursor\n\tif( MouseCursorState == mcsTempHidden ) {\n\t\tPOINT pt;\n\t\t::GetCursorPos(&pt);\n\t\tif( LastMouseScreenX != pt.x || LastMouseScreenY != pt.y ) {\n\t\t\tSetMouseCursorState(mcsVisible);\n\t\t}\n\t}\n}\nvoid TTVPWindowForm::SetMouseCursorVisibleState(bool b) {\n\t// set mouse cursor visible state\n\t// this does not look MouseCursorState\n\tif(b)\n\t\tSetMouseCursorToWindow( CurrentMouseCursor );\n\telse\n\t\tSetMouseCursorToWindow( crNone );\n}\nvoid TTVPWindowForm::SetForceMouseCursorVisible(bool s) {\n\tif( ForceMouseCursorVisible != s ) {\n\t\tForceMouseCursorVisible = s;\n\t\tif(s) {\n\t\t\t// force visible mode\n\t\t\t// the cursor is to be fixed in crDefault\n\t\t\tSetMouseCursorToWindow( crDefault );\n\t\t} else {\n\t\t\t// normal mode\n\t\t\t// restore normal cursor\n\t\t\tSetMouseCursorVisibleState(MouseCursorState == mcsVisible);\n\t\t}\n\t}\n}\nvoid TTVPWindowForm::SetMouseCursorToWindow( tjs_int cursor ) {\n\tMouseCursorManager.SetCursorIndex( cursor, GetHandle() );\n}\n\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::SetFocusable(bool b)\n{\n\t// set focusable state to 'b'.\n\t// note that currently focused window does not automatically unfocus by\n\t// setting false to this flag.\n\tFocusable = b;\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::InternalSetPaintBoxSize() {\n\tSetDrawDeviceDestRect();\n}\nvoid TTVPWindowForm::AdjustNumerAndDenom(tjs_int &n, tjs_int &d){\n\ttjs_int a = n;\n\ttjs_int b = d;\n\twhile( b ) {\n\t\ttjs_int t = b;\n\t\tb = a % b;\n\t\ta = t;\n\t}\n\tn = n / a;\n\td = d / a;\n}\nvoid TTVPWindowForm::SetZoom( tjs_int numer, tjs_int denom, bool set_logical ) {\n\tbool ischanged = false;\n\t// set layer zooming factor;\n\t// the zooming factor is passed in numerator/denoiminator style.\n\t// we must find GCM to optimize numer/denium via Euclidean algorithm.\n\tAdjustNumerAndDenom(numer, denom);\n\tif( set_logical ) {\n\t\tif( ZoomNumer != numer || ZoomDenom != denom ) {\n\t\t\tischanged = true;\n\t\t}\n\t\tZoomNumer = numer;\n\t\tZoomDenom = denom;\n\t}\n\tif( !GetFullScreenMode() ) {\n\t\t// in fullscreen mode, zooming factor is controlled by the system\n\t\tActualZoomDenom = denom;\n\t\tActualZoomNumer = numer;\n\t}\n\tInternalSetPaintBoxSize();\n\tif( ischanged ) ::InvalidateRect( GetHandle(), NULL, FALSE );\n}\nvoid TTVPWindowForm::RelocateFullScreenMode() {\n\tif(TVPFullScreenedWindow != this) return;\n\n\tif(TJSNativeInstance) TJSNativeInstance->DetachVideoOverlay();\n\n\ttjs_int desired_fs_w = OrgClientWidth;\n\ttjs_int desired_fs_h = OrgClientHeight;\n\tTVPRecalcFullScreen( desired_fs_w, desired_fs_h );\n\t\n\t// get resulted screen size\n\ttjs_int fs_w = TVPFullScreenMode.Width;\n\ttjs_int fs_h = TVPFullScreenMode.Height;\n\n\t// determine fullscreen zoom factor and client size\n\tint sb_w, sb_h, zoom_d, zoom_n;\n\tzoom_d = TVPFullScreenMode.ZoomDenom;\n\tzoom_n = TVPFullScreenMode.ZoomNumer;\n\tsb_w = desired_fs_w * zoom_n / zoom_d;\n\tsb_h = desired_fs_h * zoom_n / zoom_d;\n\n\tFullScreenDestRect.set_size( sb_w, sb_h );\n\tFullScreenDestRect.set_offsets( (fs_w - sb_w)/2, (fs_h - sb_h)/2 );\n\n\t{\n\t\ttjs_int numer = zoom_n;\n\t\ttjs_int denom = zoom_d;\n\t\tAdjustNumerAndDenom(numer, denom);\n\t\tActualZoomDenom = denom;\n\t\tActualZoomNumer = numer;\n\t\tInternalSetPaintBoxSize();\n\t}\n\n\t// reset window size\n\tHMONITOR hMonitor = ::MonitorFromWindow( GetHandle(), MONITOR_DEFAULTTOPRIMARY );\n\tMONITORINFO mi = {sizeof(MONITORINFO)};\n\tint ml = 0, mt = 0;\n\tif( ::GetMonitorInfo( hMonitor, &mi ) ) {\n\t\tml = mi.rcMonitor.left;\n\t\tmt = mi.rcMonitor.top;\n\t}\n\tSetBounds( ml, mt, fs_w, fs_h );\n\tSetInnerSize( fs_w, fs_h );\n\n\t// re-adjust video rect\n\tif(TJSNativeInstance) TJSNativeInstance->ReadjustVideoRect();\n}\nvoid TTVPWindowForm::SetFullScreenMode( bool b ) {\n\t// note that we should not change the display mode when showing overlay videos.\n\tCallFullScreenChanging(); // notify to plugin\n\ttry {\n\t\tif(TJSNativeInstance) TJSNativeInstance->DetachVideoOverlay();\n\n\t\t// due to re-create window (but current implementation may not re-create the window)\n\n\t\tif( b ) {\n\t\t\tif(TVPFullScreenedWindow == this) return;\n\t\t\tif(TVPFullScreenedWindow) TVPFullScreenedWindow->SetFullScreenMode(false);\n\n\t\t\t// save position and size\n\t\t\tOrgLeft = GetLeft();\n\t\t\tOrgTop = GetTop();\n\t\t\tOrgWidth = GetWidth();\n\t\t\tOrgHeight = GetHeight();\n\n\t\t\t// determin desired full screen size\n\t\t\ttjs_int desired_fs_w = GetInnerWidth();\n\t\t\ttjs_int desired_fs_h = GetInnerHeight();\n\t\t\tOrgClientWidth = desired_fs_w;\n\t\t\tOrgClientHeight = desired_fs_h;\n\n\t\t\t// set BorderStyle\n\t\t\tOrgStyle = ::GetWindowLong(GetHandle(), GWL_STYLE);\n\t\t\tOrgExStyle = ::GetWindowLong(GetHandle(), GWL_EXSTYLE);\n\n\t\t\t::SetWindowLong( GetHandle(), GWL_STYLE, WS_POPUP | WS_VISIBLE);\n\n\t\t\t// try to switch to fullscreen\n\t\t\ttry {\n\t\t\t\tif(TJSNativeInstance) TVPSwitchToFullScreen( GetHandle(), desired_fs_w, desired_fs_h, TJSNativeInstance->GetDrawDevice() );\n\t\t\t} catch(...) {\n\t\t\t\tSetFullScreenMode(false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t::SetWindowLong( GetHandle(), GWL_STYLE, WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN);\n\n\t\t\t// get resulted screen size\n\t\t\ttjs_int fs_w = TVPFullScreenMode.Width;\n\t\t\ttjs_int fs_h = TVPFullScreenMode.Height;\n\n\n\t\t\t// determine fullscreen zoom factor and client size\n\t\t\tint sb_w, sb_h, zoom_d, zoom_n;\n\t\t\tzoom_d = TVPFullScreenMode.ZoomDenom;\n\t\t\tzoom_n = TVPFullScreenMode.ZoomNumer;\n\t\t\tsb_w = desired_fs_w * zoom_n / zoom_d;\n\t\t\tsb_h = desired_fs_h * zoom_n / zoom_d;\n\n\t\t\tFullScreenDestRect.set_size( sb_w, sb_h );\n\t\t\tFullScreenDestRect.set_offsets( (fs_w - sb_w)/2, (fs_h - sb_h)/2 );\n\n\t\t\tSetZoom(zoom_n, zoom_d, false);\n\n\t\t\t// indicate fullscreen state\n\t\t\tTVPFullScreenedWindow = this;\n\n\t\t\t// reset window size\n\t\t\tHMONITOR hMonitor = ::MonitorFromWindow( GetHandle(), MONITOR_DEFAULTTOPRIMARY );\n\t\t\tMONITORINFO mi = {sizeof(MONITORINFO)};\n\t\t\tint ml = 0, mt = 0;\n\t\t\tif( ::GetMonitorInfo( hMonitor, &mi ) ) {\n\t\t\t\tml = mi.rcMonitor.left;\n\t\t\t\tmt = mi.rcMonitor.top;\n\t\t\t}\n\t\t\tSetBounds( ml, mt, fs_w, fs_h );\n\t\t\tSetInnerSize( fs_w, fs_h );\n\n\t\t\t// re-adjust video rect\n\t\t\tif(TJSNativeInstance) TJSNativeInstance->ReadjustVideoRect();\n\n\t\t\t// activate self\n\t\t\tBringToFront();\n\t\t\t::SetFocus(GetHandle());\n\n\t\t\t// activate self (again)\n\t\t\t::SetWindowPos( GetHandle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOSIZE|SWP_SHOWWINDOW );\n\t\t} else {\n\t\t\tif(TVPFullScreenedWindow != this) return;\n\n\t\t\tSetBounds(OrgLeft, OrgTop, OrgWidth, OrgHeight);\n\n\t\t\t// revert from fullscreen\n\t\t\tif(TJSNativeInstance) TVPRevertFromFullScreen( GetHandle(), OrgClientWidth, OrgClientHeight, TJSNativeInstance->GetDrawDevice() );\n\t\t\tTVPFullScreenedWindow = NULL;\n\t\t\tFullScreenDestRect.set_offsets( 0, 0 );\n\n\t\t\t// revert zooming factor\n\t\t\tActualZoomDenom = ZoomDenom;\n\t\t\tActualZoomNumer = ZoomNumer;\n\n\t\t\tSetZoom(ZoomNumer, ZoomDenom);  // reset zoom factor\n\n\t\t\t// set BorderStyle\n\t\t\tSetWindowLong(GetHandle(), GWL_STYLE, OrgStyle);\n\t\t\tSetWindowLong(GetHandle(), GWL_EXSTYLE, OrgExStyle);\n\n\t\t\t// revert the position and size\n\t\t\tSetBounds(OrgLeft, OrgTop, OrgWidth, OrgHeight);\n\t\t\tSetInnerSize( OrgClientWidth, OrgClientHeight );\n\t\t\t::SetWindowPos( GetHandle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOSIZE|SWP_SHOWWINDOW );\n\n\t\t\t// re-adjust video rect\n\t\t\tif(TJSNativeInstance) TJSNativeInstance->ReadjustVideoRect();\n\t\t}\n\t} catch(...) {\n\t\tCallFullScreenChanged();\n\t\tthrow;\n\t}\n\tCallFullScreenChanged();\n\n\tMouseCursorManager.UpdateCursor();\n}\nbool TTVPWindowForm::GetFullScreenMode() const { \n\treturn TVPFullScreenedWindow == this;\n}\n\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::CallWindowDetach(bool close) {\n\tif( TJSNativeInstance ) TJSNativeInstance->GetDrawDevice()->SetTargetWindow( NULL, false );\n\n\ttTVPWindowMessage msg;\n\tmsg.Msg = TVP_WM_DETACH;\n\tmsg.LParam = 0;\n\tmsg.WParam = close ? 1 : 0;\n\tmsg.Result = 0;\n\tDeliverMessageToReceiver(msg);\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::CallWindowAttach() {\n\tNextSetWindowHandleToDrawDevice = true;\n\tLastSentDrawDeviceDestRect.clear();\n\n\ttTVPWindowMessage msg;\n\tmsg.Msg = TVP_WM_ATTACH;\n\tmsg.LParam = reinterpret_cast<LPARAM>(GetWindowHandleForPlugin());\n\tmsg.WParam = 0;\n\tmsg.Result = 0;\n\n\tDeliverMessageToReceiver(msg);\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::CallFullScreenChanged() {\n\tLastSentDrawDeviceDestRect.clear();\n\t::InvalidateRect( GetHandle(), NULL, FALSE );\n\n\ttTVPWindowMessage msg;\n\tmsg.Msg = TVP_WM_FULLSCREEN_CHANGED;\n\tmsg.LParam = 0;\n\tmsg.WParam = 0;\n\tmsg.Result = 0;\n\tDeliverMessageToReceiver(msg);\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::CallFullScreenChanging() {\n\ttTVPWindowMessage msg;\n\tmsg.Msg = TVP_WM_FULLSCREEN_CHANGING;\n\tmsg.LParam = reinterpret_cast<LPARAM>(GetWindowHandleForPlugin());\n\tmsg.WParam = 0;\n\tmsg.Result = 0;\n\tDeliverMessageToReceiver(msg);\n}\n\n\nbool TTVPWindowForm::InternalDeliverMessageToReceiver(tTVPWindowMessage &msg) {\n\tif( !TJSNativeInstance ) return false;\n\tif( TVPPluginUnloadedAtSystemExit ) return false;\n\n\ttObjectListSafeLockHolder<tTVPMessageReceiverRecord> holder(WindowMessageReceivers);\n\ttjs_int count = WindowMessageReceivers.GetSafeLockedObjectCount();\n\n\tbool block = false;\n\tfor( tjs_int i = 0; i < count; i++ ) {\n\t\ttTVPMessageReceiverRecord *item = WindowMessageReceivers.GetSafeLockedObjectAt(i);\n\t\tif(!item) continue;\n\t\tbool b = item->Deliver(&msg);\n\t\tblock = block || b;\n\t}\n\treturn block;\n}\n\nvoid TTVPWindowForm::UpdateWindow(tTVPUpdateType type ) {\n\tif( TJSNativeInstance ) {\n\t\ttTVPRect r;\n\t\tr.left = 0;\n\t\tr.top = 0;\n\t\tr.right = LayerWidth;\n\t\tr.bottom = LayerHeight;\n\t\tTJSNativeInstance->NotifyWindowExposureToLayer(r);\n\t\tTVPDeliverWindowUpdateEvents();\n\t}\n}\n\nvoid TTVPWindowForm::ShowWindowAsModal() {\n\t// TODO: what's modalwindowlist ?\n\tmodal_result_ = 0;\n\tTVPAddModalWindow(this); // add to modal window list\n\ttry {\n\t\tShowModal();\n\t} catch(...) {\n\t\tTVPRemoveModalWindow(this);\n\t\tthrow;\n\t}\n\tTVPRemoveModalWindow(this);\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::SetVisibleFromScript(bool b)\n{\n\tif(Focusable) {\n\t\tSetVisible( b );\n\t} else {\n\t\tif( !GetVisible() ) {\n\t\t\t// just show window, not activate\n\t\t\tSetWindowPos(GetHandle(), GetStayOnTop()?HWND_TOPMOST:HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);\n\t\t\tSetVisible( true );\n\t\t} else {\n\t\t\tSetVisible( false );\n\t\t}\n\t}\n}\n\n\nvoid TTVPWindowForm::RegisterWindowMessageReceiver(tTVPWMRRegMode mode, void * proc, const void *userdata) {\n\tif( mode == wrmRegister ) {\n\t\t// register\n\t\ttjs_int count = WindowMessageReceivers.GetCount();\n\t\ttjs_int i;\n\t\tfor(i = 0 ; i < count; i++) {\n\t\t\ttTVPMessageReceiverRecord *item = WindowMessageReceivers[i];\n\t\t\tif(!item) continue;\n\t\t\tif((void*)item->Proc == proc) break; // have already registered\n\t\t}\n\t\tif(i == count) {\n\t\t\t// not have registered\n\t\t\ttTVPMessageReceiverRecord *item = new tTVPMessageReceiverRecord();\n\t\t\titem->Proc = (tTVPWindowMessageReceiver)proc;\n\t\t\titem->UserData = userdata;\n\t\t\tWindowMessageReceivers.Add(item);\n\t\t}\n\t} else if(mode == wrmUnregister) {\n\t\t// unregister\n\t\ttjs_int count = WindowMessageReceivers.GetCount();\n\t\tfor(tjs_int i = 0 ; i < count; i++) {\n\t\t\ttTVPMessageReceiverRecord *item = WindowMessageReceivers[i];\n\t\t\tif(!item) continue;\n\t\t\tif((void*)item->Proc == proc) {\n\t\t\t\t// found\n\t\t\t\tWindowMessageReceivers.Remove(i);\n\t\t\t\tdelete item;\n\t\t\t}\n\t\t}\n\t\tWindowMessageReceivers.Compact();\n\t}\n}\nvoid TTVPWindowForm::OnClose( CloseAction& action ) {\n\tif(modal_result_ == 0)\n\t\taction = caNone;\n\telse\n\t\taction = caHide;\n\n\tif( ProgramClosing ) {\n\t\tif( TJSNativeInstance ) {\n\t\t\tif( TJSNativeInstance->IsMainWindow() ) {\n\t\t\t\t// this is the main window\n\t\t\t} else \t\t\t{\n\t\t\t\t// not the main window\n\t\t\t\taction = caFree;\n\t\t\t}\n\t\t\tif( TVPFullScreenedWindow != this ) {\n\t\t\t\t// if this is not a fullscreened window\n\t\t\t\tSetVisible( false );\n\t\t\t}\n\t\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\t\tTJSNativeInstance->NotifyWindowClose();\n\t\t\tobj->Invalidate(0, NULL, NULL, obj);\n\t\t\tTJSNativeInstance = NULL;\n\t\t}\n\t}\n}\nbool TTVPWindowForm::OnCloseQuery() {\n\t// closing actions are 3 patterns;\n\t// 1. closing action by the user\n\t// 2. \"close\" method\n\t// 3. object invalidation\n\n\tif( TVPGetBreathing() ) {\n\t\treturn false;\n\t}\n\n\t// the default event handler will invalidate this object when an onCloseQuery\n\t// event reaches the handler.\n\tif(TJSNativeInstance && (modal_result_ == 0 ||\n\t\tmodal_result_ == mrCancel/* mrCancel=when close button is pushed in modal window */  )) {\n\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\tif(obj) {\n\t\t\ttTJSVariant arg[1] = {true};\n\t\t\tstatic ttstr eventname(TJS_W(\"onCloseQuery\"));\n\n\t\t\tif(!ProgramClosing) {\n\t\t\t\t// close action does not happen immediately\n\t\t\t\tif(TJSNativeInstance) {\n\t\t\t\t\tTVPPostInputEvent( new tTVPOnCloseInputEvent(TJSNativeInstance) );\n\t\t\t\t}\n\n\t\t\t\tClosing = true; // waiting closing...\n\t\t\t\tTVPSystemControl->NotifyCloseClicked();\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tCanCloseWork = true;\n\t\t\t\tTVPPostEvent(obj, obj, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t\t\t\t\t// this event happens immediately\n\t\t\t\t\t// and does not return until done\n\t\t\t\treturn CanCloseWork; // CanCloseWork is set by the event handler\n\t\t\t}\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\treturn true;\n\t}\n}\nvoid TTVPWindowForm::Close() {\n\t// closing action by \"close\" method\n\tif( Closing ) return; // already waiting closing...\n\n\tProgramClosing = true;\n\ttry {\n\t\ttTVPWindow::Close();\n\t} catch(...) {\n\t\tProgramClosing = false;\n\t\tthrow;\n\t}\n\tProgramClosing = false;\n}\nvoid TTVPWindowForm::InvalidateClose() {\n\t// closing action by object invalidation;\n\t// this will not cause any user confirmation of closing the window.\n\tTJSNativeInstance = NULL;\n\tSetVisible( false );\n\tBOOL ret = ::DestroyWindow( GetHandle() );\n\tif( ret == FALSE ) {\n\t\tTVPThrowWindowsErrorException();\n\t}\n\tdelete this;\n}\nvoid TTVPWindowForm::OnCloseQueryCalled( bool b ) {\n\t// closing is allowed by onCloseQuery event handler\n\tif( !ProgramClosing ) {\n\t\t// closing action by the user\n\t\tif( b ) {\n\t\t\tif( in_mode_ )\n\t\t\t\tmodal_result_ = 1; // when modal\n\t\t\telse\n\t\t\t\tSetVisible( false );  // just hide\n\n\t\t\tClosing = false;\n\t\t\tif( TJSNativeInstance ) {\n\t\t\t\tif( TJSNativeInstance->IsMainWindow() ) {\n\t\t\t\t\t// this is the main window\n\t\t\t\t\tiTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef();\n\t\t\t\t\tobj->Invalidate(0, NULL, NULL, obj);\n\t\t\t\t\t// TJSNativeInstance = NULL; // ̒iKł͊this폜Ă邽߁Ao[փANZXĂ͂Ȃ\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete this;\n\t\t\t}\n\t\t} else {\n\t\t\tClosing = false;\n\t\t}\n\t} else {\n\t\t// closing action by the program\n\t\tCanCloseWork = b;\n\t}\n}\nvoid TTVPWindowForm::SendCloseMessage() {\n\t::PostMessage(GetHandle(), WM_CLOSE, 0, 0);\n}\n\nvoid TTVPWindowForm::ZoomRectangle( tjs_int& left, tjs_int& top, tjs_int& right, tjs_int& bottom) {\n\tleft =   MulDiv(left  ,  ActualZoomNumer, ActualZoomDenom);\n\ttop =    MulDiv(top   ,  ActualZoomNumer, ActualZoomDenom);\n\tright =  MulDiv(right ,  ActualZoomNumer, ActualZoomDenom);\n\tbottom = MulDiv(bottom,  ActualZoomNumer, ActualZoomDenom);\n}\nvoid TTVPWindowForm::GetVideoOffset(tjs_int &ofsx, tjs_int &ofsy) {\n\tif( GetFullScreenMode() ) {\n\t\tofsx = FullScreenDestRect.left;\n\t\tofsy = FullScreenDestRect.top;\n\t} else {\n\t\tofsx = 0;\n\t\tofsy = 0;\n\t}\n}\n/*\nHWND TTVPWindowForm::GetSurfaceWindowHandle() {\n\treturn GetHandle();\n}\nHWND TTVPWindowForm::GetWindowHandle(tjs_int &ofsx, tjs_int &ofsy) {\n\tRECT rt;\n\t::GetWindowRect( GetHandle(), &rt );\n\tPOINT pt = { rt.left, rt.top };\n\tScreenToClient( GetHandle(), &pt );\n\tofsx = -pt.x;\n\tofsy = -pt.y;\n\treturn GetHandle();\n}\nHWND TTVPWindowForm::GetWindowHandleForPlugin() {\n\treturn GetHandle();\n}\n*/\n\nvoid TTVPWindowForm::ResetDrawDevice() {\n\tNextSetWindowHandleToDrawDevice = true;\n\tLastSentDrawDeviceDestRect.clear();\n\t::InvalidateRect( GetHandle(), NULL, FALSE );\n}\n\nvoid TTVPWindowForm::InternalKeyUp(WORD key, tjs_uint32 shift) {\n\tDWORD tick = GetTickCount();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tTVPPushEnvironNoise(&key, sizeof(key));\n\tTVPPushEnvironNoise(&shift, sizeof(shift));\n\tif( TJSNativeInstance ) {\n\t\tif( UseMouseKey /*&& PaintBox*/ ) {\n\t\t\tif( key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) {\n\t\t\t\tPOINT p;\n\t\t\t\t::GetCursorPos(&p);\n\t\t\t\t::ScreenToClient( GetHandle(), &p );\n\t\t\t\tif( p.x >= 0 && p.y >= 0 && p.x < GetInnerWidth() && p.y < GetInnerHeight() ) {\n\t\t\t\t\tif( key == VK_RETURN || key == VK_SPACE || key == VK_PAD1 ) {\n\t\t\t\t\t\tOnMouseClick( mbLeft, 0, p.x, p.y );\n\t\t\t\t\t\tMouseLeftButtonEmulatedPushed = false;\n\t\t\t\t\t\tOnMouseUp( mbLeft, 0, p.x, p.y );\n\t\t\t\t\t}\n\n\t\t\t\t\tif( key == VK_ESCAPE || key == VK_PAD2 ) {\n\t\t\t\t\t\tMouseRightButtonEmulatedPushed = false;\n\t\t\t\t\t\tOnMouseUp( mbRight, 0, p.x, p.y );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tTVPPostInputEvent(new tTVPOnKeyUpInputEvent(TJSNativeInstance, key, shift));\n\t}\n}\nvoid TTVPWindowForm::InternalKeyDown(WORD key, tjs_uint32 shift) {\n\tDWORD tick = GetTickCount();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tTVPPushEnvironNoise(&key, sizeof(key));\n\tTVPPushEnvironNoise(&shift, sizeof(shift));\n\n\tif( TJSNativeInstance ) {\n\t\tif(UseMouseKey /*&& PaintBox*/ ) {\n\t\t\tif(key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) {\n\t\t\t\tPOINT p;\n\t\t\t\t::GetCursorPos(&p);\n\t\t\t\t::ScreenToClient( GetHandle(), &p );\n\t\t\t\tif( p.x >= 0 && p.y >= 0 && p.x < GetInnerWidth() && p.y < GetInnerHeight() ) {\n\t\t\t\t\tif( key == VK_RETURN || key == VK_SPACE || key == VK_PAD1 ) {\n\t\t\t\t\t\tMouseLeftButtonEmulatedPushed = true;\n\t\t\t\t\t\tOnMouseDown( mbLeft, 0, p.x, p.y );\n\t\t\t\t\t}\n\n\t\t\t\t\tif(key == VK_ESCAPE || key == VK_PAD2) {\n\t\t\t\t\t\tMouseRightButtonEmulatedPushed = true;\n\t\t\t\t\t\tOnMouseDown( mbLeft, 0, p.x, p.y );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tswitch(key) {\n\t\t\tcase VK_LEFT:\n\t\t\tcase VK_PADLEFT:\n\t\t\t\tif( MouseKeyXAccel == 0 && MouseKeyYAccel == 0 ) {\n\t\t\t\t\tGenerateMouseEvent(true, false, false, false);\n\t\t\t\t\tLastMouseKeyTick = GetTickCount() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_RIGHT:\n\t\t\tcase VK_PADRIGHT:\n\t\t\t\tif(MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, true, false, false);\n\t\t\t\t\tLastMouseKeyTick = GetTickCount() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_UP:\n\t\t\tcase VK_PADUP:\n\t\t\t\tif(MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, false, true, false);\n\t\t\t\t\tLastMouseKeyTick = GetTickCount() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase VK_DOWN:\n\t\t\tcase VK_PADDOWN:\n\t\t\t\tif(MouseKeyXAccel == 0 && MouseKeyYAccel == 0)\n\t\t\t\t{\n\t\t\t\t\tGenerateMouseEvent(false, false, false, true);\n\t\t\t\t\tLastMouseKeyTick = GetTickCount() + 100;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tTVPPostInputEvent(new tTVPOnKeyDownInputEvent(TJSNativeInstance, key, shift));\n\t}\n}\nvoid TTVPWindowForm::GenerateMouseEvent(bool fl, bool fr, bool fu, bool fd) {\n\tif( !fl && !fr && !fu && !fd ) {\n\t\tif(GetTickCount() - 45 < LastMouseKeyTick) return;\n\t}\n\n\tbool shift = 0!=(GetAsyncKeyState(VK_SHIFT) & 0x8000);\n\tbool left = fl || GetAsyncKeyState(VK_LEFT) & 0x8000 || TVPGetJoyPadAsyncState(VK_PADLEFT, true);\n\tbool right = fr || GetAsyncKeyState(VK_RIGHT) & 0x8000 || TVPGetJoyPadAsyncState(VK_PADRIGHT, true);\n\tbool up = fu || GetAsyncKeyState(VK_UP) & 0x8000 || TVPGetJoyPadAsyncState(VK_PADUP, true);\n\tbool down = fd || GetAsyncKeyState(VK_DOWN) & 0x8000 || TVPGetJoyPadAsyncState(VK_PADDOWN, true);\n\n\tDWORD flags = 0;\n\tif(left || right || up || down) flags |= MOUSEEVENTF_MOVE;\n\n\tif(!right && !left && !up && !down) {\n\t\tLastMouseMoved = false;\n\t\tMouseKeyXAccel = MouseKeyYAccel = 0;\n\t}\n\n\tif(!shift) {\n\t\tif(!right && left && MouseKeyXAccel > 0) MouseKeyXAccel = -0;\n\t\tif(!left && right && MouseKeyXAccel < 0) MouseKeyXAccel = 0;\n\t\tif(!down && up && MouseKeyYAccel > 0) MouseKeyYAccel = -0;\n\t\tif(!up && down && MouseKeyYAccel < 0) MouseKeyYAccel = 0;\n\t} else {\n\t\tif(left) MouseKeyXAccel = -TVP_MOUSE_SHIFT_ACCEL;\n\t\tif(right) MouseKeyXAccel = TVP_MOUSE_SHIFT_ACCEL;\n\t\tif(up) MouseKeyYAccel = -TVP_MOUSE_SHIFT_ACCEL;\n\t\tif(down) MouseKeyYAccel = TVP_MOUSE_SHIFT_ACCEL;\n\t}\n\n\tif(right || left || up || down) {\n\t\tif(left) if(MouseKeyXAccel > -TVP_MOUSE_MAX_ACCEL)\n\t\t\tMouseKeyXAccel = MouseKeyXAccel?MouseKeyXAccel - 2:-2;\n\t\tif(right) if(MouseKeyXAccel < TVP_MOUSE_MAX_ACCEL)\n\t\t\tMouseKeyXAccel = MouseKeyXAccel?MouseKeyXAccel + 2:+2;\n\t\tif(!left && !right) {\n\t\t\tif(MouseKeyXAccel > 0) MouseKeyXAccel--;\n\t\t\telse if(MouseKeyXAccel < 0) MouseKeyXAccel++;\n\t\t}\n\n\t\tif(up) if(MouseKeyYAccel > -TVP_MOUSE_MAX_ACCEL)\n\t\t\tMouseKeyYAccel = MouseKeyYAccel?MouseKeyYAccel - 2:-2;\n\t\tif(down) if(MouseKeyYAccel < TVP_MOUSE_MAX_ACCEL)\n\t\t\tMouseKeyYAccel = MouseKeyYAccel?MouseKeyYAccel + 2:+2;\n\t\tif(!up && !down) {\n\t\t\tif(MouseKeyYAccel > 0) MouseKeyYAccel--;\n\t\t\telse if(MouseKeyYAccel < 0) MouseKeyYAccel++;\n\t\t}\n\n\t}\n\n\tif(flags) {\n\t\tPOINT pt;\n\t\tif(::GetCursorPos(&pt)) {\n\t\t\t::SetCursorPos( pt.x + (MouseKeyXAccel>>1), pt.y + (MouseKeyYAccel>>1)); \n\t\t}\n\t\tLastMouseMoved = true;\n\t}\n\tLastMouseKeyTick = GetTickCount();\n}\n\nvoid TTVPWindowForm::SetPaintBoxSize(tjs_int w, tjs_int h) {\n\tLayerWidth  = w;\n\tLayerHeight = h;\n\tInternalSetPaintBoxSize();\n}\n\nvoid TTVPWindowForm::SetDefaultMouseCursor() {\n\tif( CurrentMouseCursor != crDefault ) {\n\t\tCurrentMouseCursor = crDefault;\n\t\tif( MouseCursorState == mcsVisible && !ForceMouseCursorVisible ) {\n\t\t\tSetMouseCursorToWindow( crDefault );\n\t\t}\n\t}\n}\nvoid TTVPWindowForm::SetMouseCursor( tjs_int handle ) {\n\tif( CurrentMouseCursor != handle ) {\n\t\tCurrentMouseCursor = handle;\n\t\tif(MouseCursorState == mcsVisible && !ForceMouseCursorVisible) {\n\t\t\tSetMouseCursorToWindow( handle );\n\t\t}\n\t}\n}\n/**\n * NCAg̈WEBhËW֕ϊ\n */\nvoid TTVPWindowForm::OffsetClientPoint( int &x, int &y ) {\n\tPOINT origin = {0,0};\n\t::ClientToScreen( GetHandle(), &origin );\n\tx = -origin.x;\n\ty = -origin.y;\n}\n// Layer.cursorX/cursorYŌĂ΂\nvoid TTVPWindowForm::GetCursorPos(tjs_int &x, tjs_int &y) {\n\t// get mouse cursor position in client\n\tPOINT origin = {0,0};\n\t::ClientToScreen( GetHandle(), &origin );\n\tPOINT mp = {0, 0};\n\t::GetCursorPos(&mp);\n\tx = mp.x - origin.x;\n\ty = mp.y - origin.y;\n\tTranslateWindowToDrawArea( x, y );\n}\nvoid TTVPWindowForm::SetCursorPos(tjs_int x, tjs_int y) {\n\tTranslateDrawAreaToWindow( x, y );\n\n\tPOINT pt = {x,y};\n\t::ClientToScreen( GetHandle(), &pt );\n\t::SetCursorPos(pt.x, pt.y);\n\tLastMouseScreenX = LastMouseScreenY = -1; // force to display mouse cursor\n\tRestoreMouseCursor();\n}\n\nvoid TTVPWindowForm::SetHintText(iTJSDispatch2* sender,  const ttstr &text ) {\n\tbool updatetext = HintMessage != text;\n\tif( updatetext && text.IsEmpty() != true ) {\n\t\tHintMessage.Clear();\n\t\tUpdateHint();\n\t}\n\tHintMessage = text;\n\n\tif( text.IsEmpty() ) {\n\t\tif( HintTimer ) HintTimer->SetEnabled(false);\n\t\tUpdateHint();\n\t} else {\n\t\tif( LastHintSender != sender || updatetext ) {\n\t\t\tif( HintTimer ) HintTimer->SetEnabled(false);\n\t\t\tif( HintDelay > 0 ) {\n\t\t\t\tif( HintTimer == NULL ) {\n\t\t\t\t\tHintTimer = new TVPTimer();\n\t\t\t\t\tHintTimer->SetOnTimerHandler( this, &TTVPWindowForm::UpdateHint );\n\t\t\t\t}\n\t\t\t\tHintTimer->SetEnabled(false);\n\t\t\t\tHintTimer->SetInterval( HintDelay );\n\t\t\t\tHintTimer->SetEnabled(true);\n\t\t\t} else if( HintDelay == 0 ) {\n\t\t\t\tUpdateHint();\n\t\t\t}\n\t\t}\n\t}\n\tLastHintSender = sender;\n}\nvoid TTVPWindowForm::UpdateHint() {\n\tif(TJSNativeInstance) {\n\t\tPOINT p;\n\t\t::GetCursorPos(&p);\n\t\t::ScreenToClient( GetHandle(), &p );\n\t\tTVPPostInputEvent( new tTVPOnHintChangeInputEvent(TJSNativeInstance, HintMessage, p.x, p.y, HintMessage.IsEmpty()==false ));\n\t}\n\tif( HintTimer ) HintTimer->SetEnabled(false);\n}\nvoid TTVPWindowForm::UnacquireImeControl() {\n\tif( TVPControlImeState ) {\n\t\tGetIME()->Reset();\n\t}\n}\n\nTTVPWindowForm * TTVPWindowForm::GetKeyTrapperWindow() {\n\t// find most recent \"trapKeys = true\" window and return it.\n\t// returnts \"this\" window if there is no trapping window.\n\ttjs_int count = TVPGetWindowCount();\n\tfor( tjs_int i = count - 1; i >= 0; i-- ) {\n\t\ttTJSNI_Window * win = TVPGetWindowListAt(i);\n\t\tif( win ) {\n\t\t\tTTVPWindowForm * form = win->GetForm();\n\t\t\tif( form && form != this ) {\n\t\t\t\tif( form->TrapKeys && form->GetVisible() ) {\n\t\t\t\t\t// found\n\t\t\t\t\treturn form;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn this;\n}\n#if 0\nint TTVPWindowForm::ConvertImeMode( tTVPImeMode mode ) {\n\tswitch( mode ) {\n\tcase ::imDisable   : return ImeControl::ModeClose   ; // (*)\n\tcase ::imClose     : return ImeControl::ModeClose   ;\n\tcase ::imOpen      : return ImeControl::ModeOpen    ;\n\tcase ::imDontCare  : return ImeControl::ModeDontCare;\n\tcase ::imSAlpha    : return ImeControl::ModeSAlpha  ;\n\tcase ::imAlpha     : return ImeControl::ModeAlpha   ;\n\tcase ::imHira      : return ImeControl::ModeHira    ;\n\tcase ::imSKata     : return ImeControl::ModeSKata   ;\n\tcase ::imKata      : return ImeControl::ModeKata    ;\n\tcase ::imChinese   : return ImeControl::ModeChinese ;\n\tcase ::imSHanguel  : return ImeControl::ModeSHanguel;\n\tcase ::imHanguel   : return ImeControl::ModeHanguel ;\n\t}\n\treturn ImeControl::ModeDontCare;\n}\nvoid TTVPWindowForm::AcquireImeControl() {\n\tif( HasFocus() ) {\n\t\t// find key trapper window ...\n\t\tTTVPWindowForm * trapper = GetKeyTrapperWindow();\n\n\t\t// force to access protected some methods.\n\t\t// much nasty way ...\n\t\tif( TVPControlImeState ) {\n\t\t\tGetIME()->Reset();\n\t\t\ttTVPImeMode newmode = trapper->LastSetImeMode;\n\t\t\tif( GetIME()->IsEnableThisLocale() )\n\t\t\t\tGetIME()->Enable();\n\t\t\tGetIME()->SetIme(ConvertImeMode(newmode));\n\t\t}\n\n\t\tif( trapper->AttentionPointEnabled ) {\n\t\t\t::SetCaretPos( trapper->AttentionPoint.x, trapper->AttentionPoint.y );\n\t\t\tif( trapper == this ) {\n\t\t\t\tGetIME()->SetCompositionWindow( AttentionPoint.x, AttentionPoint.y );\n\t\t\t\tGetIME()->SetCompositionFont( AttentionFont);\n\t\t\t} else \t\t\t{\n\t\t\t\t// disable IMM composition window\n\t\t\t\tGetIME()->Disable();\n\t\t\t}\n\t\t}\n\t}\n}\n#endif\nvoid TTVPWindowForm::SetImeMode(tTVPImeMode mode) {\n\tLastSetImeMode = mode;\n\tAcquireImeControl();\n}\nvoid TTVPWindowForm::SetDefaultImeMode(tTVPImeMode mode, bool reset) {\n\tDefaultImeMode = mode;\n\tif(reset) ResetImeMode();\n}\nvoid TTVPWindowForm::ResetImeMode() {\n\tSetImeMode(DefaultImeMode);\n}\n\nvoid TTVPWindowForm::SetAttentionPoint(tjs_int left, tjs_int top, const tTVPFont * font) {\n\tTranslateDrawAreaToWindow( left, top );\n\n\t// set attention point information\n\tAttentionPoint.x = left;\n\tAttentionPoint.y = top;\n\tAttentionPointEnabled = true;\n\tif( font ) {\n\t\tAttentionFont->Assign(*font);\n\t} else {\n\t\ttTVPSysFont * default_font = new tTVPSysFont();\n\t\tAttentionFont->Assign(default_font);\n\t\tdelete default_font;\n\t}\n\tAcquireImeControl();\n}\nvoid TTVPWindowForm::DisableAttentionPoint() {\n\tAttentionPointEnabled = false;\n}\nvoid TTVPWindowForm::CreateDirectInputDevice() {\n\tif( !DIWheelDevice ) DIWheelDevice = new tTVPWheelDirectInputDevice(GetHandle());\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif( !DIPadDevice ) DIPadDevice = new tTVPPadDirectInputDevice(GetHandle());\n#endif\n}\nvoid TTVPWindowForm::FreeDirectInputDevice() {\n\tif( DIWheelDevice ) {\n\t\tdelete DIWheelDevice;\n\t\tDIWheelDevice = NULL;\n\t}\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif( DIPadDevice ) {\n\t\tdelete DIPadDevice;\n\t\tDIPadDevice = NULL;\n\t}\n#endif\n}\n\nvoid TTVPWindowForm::OnKeyDown( WORD vk, int shift, int repeat, bool prevkeystate ) {\n\tif(TJSNativeInstance) {\n\t\ttjs_uint32 s = TVP_TShiftState_To_uint32( shift );\n\t\ts |= GetMouseButtonState();\n\t\tif( prevkeystate && repeat > 0 ) s |= TVP_SS_REPEAT;\n\t\tInternalKeyDown( vk, s );\n\t}\n}\nvoid TTVPWindowForm::OnKeyUp( WORD vk, int shift ) {\n\ttjs_uint32 s = TVP_TShiftState_To_uint32(shift);\n\ts |= GetMouseButtonState();\n\tInternalKeyUp(vk, s );\n}\nvoid TTVPWindowForm::OnKeyPress( WORD vk, int repeat, bool prevkeystate, bool convertkey ) {\n\tif( TJSNativeInstance && vk ) {\n\t\tif(UseMouseKey && (vk == 0x1b || vk == 13 || vk == 32)) return;\n\t\t// UNICODE Ȃ̂ł̂܂ܓnĂ܂\n\t\tTVPPostInputEvent(new tTVPOnKeyPressInputEvent(TJSNativeInstance, vk));\n\t}\n}\nvoid TTVPWindowForm::TranslateWindowToDrawArea(int &x, int &y) {\n\tif( GetFullScreenMode() ) {\n\t\tx -= FullScreenDestRect.left;\n\t\ty -= FullScreenDestRect.top;\n\t}\n}\n\nvoid TTVPWindowForm::TranslateWindowToDrawArea(double&x, double &y) {\n\tif( GetFullScreenMode() ) {\n\t\tx -= FullScreenDestRect.left;\n\t\ty -= FullScreenDestRect.top;\n\t}\n}\nvoid TTVPWindowForm::TranslateDrawAreaToWindow(int &x, int &y) {\n\tif( GetFullScreenMode() ) {\n\t\tx += FullScreenDestRect.left;\n\t\ty += FullScreenDestRect.top;\n\t}\n}\nvoid TTVPWindowForm::FirePopupHide() {\n\t// fire \"onPopupHide\" event\n\tif(!CanSendPopupHide()) return;\n\tif(!GetVisible()) return;\n\tTVPPostInputEvent( new tTVPOnPopupHideInputEvent(TJSNativeInstance) );\n}\n\nvoid TTVPWindowForm::DeliverPopupHide() {\n\t// deliver onPopupHide event to unfocusable windows\n\ttjs_int count = TVPGetWindowCount();\n\tfor( tjs_int i = count - 1; i >= 0; i-- ) {\n\t\ttTJSNI_Window * win = TVPGetWindowListAt(i);\n\t\tif( win ){\n\t\t\tTTVPWindowForm * form = win->GetForm();\n\t\t\tif( form ) {\n\t\t\t\tform->FirePopupHide();\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid TTVPWindowForm::SetEnableTouch( bool b ) {\n\tif( b != GetEnableTouch() ) {\n\t\tif( procRegisterTouchWindow && procUnregisterTouchWindow ) {\n\t\t\tint value= ::GetSystemMetrics( SM_DIGITIZER );\n\t\t\tif( (value & NID_READY ) == NID_READY ) {\n\t\t\t\tif( b ) {\n\t\t\t\t\tprocRegisterTouchWindow( GetHandle(), REGISTER_TOUCH_FLAG );\n\t\t\t\t} else {\n\t\t\t\t\tprocUnregisterTouchWindow( GetHandle() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tignore_touch_mouse_ = b;\n}\n\nbool TTVPWindowForm::GetEnableTouch() const {\n\tif( procIsTouchWindow ) {\n\t\tBOOL ret = procIsTouchWindow( GetHandle(), NULL );\n\t\treturn ret != 0;\n\t}\n\treturn false;\n}\nvoid TTVPWindowForm::InvokeShowVisible() {\n\t// this posts window message which invokes WMShowVisible\n\t::PostMessage( GetHandle(), TVP_WM_SHOWVISIBLE, 0, 0);\n}\n//---------------------------------------------------------------------------\nvoid TTVPWindowForm::InvokeShowTop(bool activate) {\n\t// this posts window message which invokes WMShowTop\n\t::PostMessage( GetHandle(), TVP_WM_SHOWTOP, activate ? 1:0, 0);\n}\n//---------------------------------------------------------------------------\nHDWP TTVPWindowForm::ShowTop(HDWP hdwp) {\n\tif( GetVisible() ) {\n\t\thdwp = ::DeferWindowPos(hdwp, GetHandle(), HWND_TOPMOST, 0, 0, 0, 0,\n\t\t\tSWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREPOSITION|\n\t\t\tSWP_NOSIZE|WM_SHOWWINDOW);\n\t}\n\treturn hdwp;\n}\nvoid TTVPWindowForm::OnMouseMove( int shift, int x, int y ) {\n\tTranslateWindowToDrawArea(x, y);\n\tMouseVelocityTracker.addMovement( TVPGetRoughTickCount32(), (float)x, (float)y );\n\tif( TJSNativeInstance ) {\n\t\ttjs_uint32 s = TVP_TShiftState_To_uint32(shift);\n\t\ts |= GetMouseButtonState();\n\t\tTVPPostInputEvent( new tTVPOnMouseMoveInputEvent(TJSNativeInstance, x, y, s), TVP_EPT_DISCARDABLE );\n\t}\n\n\tRestoreMouseCursor();\n\n\tint pos = (y << 16) + x;\n\tTVPPushEnvironNoise(&pos, sizeof(pos));\n\n\tLastMouseMovedPos.x = x;\n\tLastMouseMovedPos.y = y;\n}\nvoid TTVPWindowForm::OnMouseDown( int button, int shift, int x, int y ) {\n\tif( !CanSendPopupHide() ) DeliverPopupHide();\n\n\tTranslateWindowToDrawArea( x, y);\n\tSetMouseCapture();\n\tMouseVelocityTracker.addMovement( TVPGetRoughTickCount32(), (float)x, (float)y );\n\n\tLastMouseDownX = x;\n\tLastMouseDownY = y;\n\n\tif(TJSNativeInstance) {\n\t\ttjs_uint32 s = TVP_TShiftState_To_uint32(shift);\n\t\ts |= GetMouseButtonState();\n\t\ttTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button);\n\t\tTVPPostInputEvent( new tTVPOnMouseDownInputEvent(TJSNativeInstance, x, y, b, s));\n\t}\n}\nvoid TTVPWindowForm::OnMouseUp( int button, int shift, int x, int y ) {\n\tTranslateWindowToDrawArea(x, y);\n\tReleaseMouseCapture();\n\tMouseVelocityTracker.addMovement( TVPGetRoughTickCount32(), (float)x, (float)y );\n\tif(TJSNativeInstance) {\n\t\ttjs_uint32 s = TVP_TShiftState_To_uint32(shift);\n\t\ts |= GetMouseButtonState();\n\t\ttTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button);\n\t\tTVPPostInputEvent( new tTVPOnMouseUpInputEvent(TJSNativeInstance, x, y, b, s));\n\t}\n}\nvoid TTVPWindowForm::OnMouseDoubleClick( int button, int x, int y ) {\n\t// fire double click event\n\tif( TJSNativeInstance ) {\n\t\tTVPPostInputEvent( new tTVPOnDoubleClickInputEvent(TJSNativeInstance, LastMouseDownX, LastMouseDownY));\n\t}\n}\nvoid TTVPWindowForm::OnMouseClick( int button, int shift, int x, int y ) {\n\t// fire click event\n\tif( TJSNativeInstance ) {\n\t\tTVPPostInputEvent( new tTVPOnClickInputEvent(TJSNativeInstance, LastMouseDownX, LastMouseDownY));\n\t}\n}\nvoid TTVPWindowForm::OnMouseWheel( int delta, int shift, int x, int y ) {\n\tTranslateWindowToDrawArea( x, y);\n\tif( TVPWheelDetectionType == wdtWindowMessage ) {\n\t\t// wheel\n\t\tif( TJSNativeInstance ) {\n\t\t\ttjs_uint32 s = TVP_TShiftState_To_uint32(shift);\n\t\t\ts |= GetMouseButtonState();\n\t\t\tTVPPostInputEvent(new tTVPOnMouseWheelInputEvent(TJSNativeInstance, s, delta, x, y));\n\t\t}\n\t}\n}\n\nvoid TTVPWindowForm::OnTouchDown( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {\n\tTranslateWindowToDrawArea(x, y);\n\n\tTouchVelocityTracker.start( id );\n\tTouchVelocityTracker.update( id, tick, (float)x, (float)y );\n\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnTouchDownInputEvent(TJSNativeInstance, x, y, cx, cy, id));\n\t}\n\ttouch_points_.TouchDown( x, y ,cx, cy, id, tick );\n}\nvoid TTVPWindowForm::OnTouchMove( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {\n\tTranslateWindowToDrawArea( x, y);\n\n\tTouchVelocityTracker.update( id, tick, (float)x, (float)y );\n\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnTouchMoveInputEvent(TJSNativeInstance, x, y, cx, cy, id));\n\t}\n\ttouch_points_.TouchMove( x, y, cx, cy, id, tick );\n}\nvoid TTVPWindowForm::OnTouchUp( double x, double y, double cx, double cy, DWORD id, DWORD tick ) {\n\tTranslateWindowToDrawArea( x, y);\n\n\tTouchVelocityTracker.update( id, tick, (float)x, (float)y );\n\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnTouchUpInputEvent(TJSNativeInstance, x, y, cx, cy, id));\n\t}\n\ttouch_points_.TouchUp( x, y, cx, cy, id, tick );\n\n\t//TouchVelocityTracker.end( id );\n}\n\nvoid TTVPWindowForm::OnTouchScaling( double startdist, double currentdist, double cx, double cy, int flag ) {\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnTouchScalingInputEvent(TJSNativeInstance, startdist, currentdist, cx, cy, flag ));\n\t}\n}\nvoid TTVPWindowForm::OnTouchRotate( double startangle, double currentangle, double distance, double cx, double cy, int flag ) {\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnTouchRotateInputEvent(TJSNativeInstance, startangle, currentangle, distance, cx, cy, flag));\n\t}\n}\nvoid TTVPWindowForm::OnMultiTouch() {\n\tif( TJSNativeInstance ) {\n\t\tTVPPostInputEvent( new tTVPOnMultiTouchInputEvent(TJSNativeInstance) );\n\t}\n}\nvoid TTVPWindowForm::OnTouchSequenceStart() {\n\t// Ȃ\n}\nvoid TTVPWindowForm::OnTouchSequenceEnd() {\n}\nvoid TTVPWindowForm::OnActive( HWND preactive ) {\n\tif( TVPFullScreenedWindow == this )\n\t\tTVPShowModalAtAppActivate();\n\n\tApplication->OnActiveAnyWindow();\n}\nvoid TTVPWindowForm::OnDeactive( HWND postactive ) {\n\tif( TJSNativeInstance ) {\n\t\tTVPPostInputEvent( new tTVPOnReleaseCaptureInputEvent(TJSNativeInstance) );\n\t}\n}\nvoid TTVPWindowForm::OnApplicationActivateChange( bool activated, DWORD thread_id ) {\n\tif ( activated ) {\n\t\tApplication->OnActivate( GetHandle() );\n\t} else {\n\t\tApplication->OnDeactivate( GetHandle() );\n\t}\n}\n\n\nvoid TTVPWindowForm::OnMove( int x, int y ) {\n\tif(TJSNativeInstance) {\n\t\tTJSNativeInstance->WindowMoved();\n\t}\n}\nvoid TTVPWindowForm::OnResize( UINT_PTR state, int w, int h ) {\n\tif( state == SIZE_MINIMIZED || state == SIZE_MAXSHOW || state == SIZE_MAXHIDE ) return;\n\t// state == SIZE_RESTORED, SIZE_MAXIMIZED, \n\t// on resize\n\tif(TJSNativeInstance) {\n\t\t// here specifies TVP_EPT_REMOVE_POST, to remove redundant onResize events.\n\t\tTVPPostInputEvent( new tTVPOnResizeInputEvent(TJSNativeInstance), TVP_EPT_REMOVE_POST );\n\t}\n}\nvoid TTVPWindowForm::OnDropFile( HDROP hDrop ) {\n\twchar_t filename[MAX_PATH];\n\ttjs_int filecount= ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, MAX_PATH);\n\tiTJSDispatch2 * array = TJSCreateArrayObject();\n\ttry {\n\t\ttjs_int count = 0;\n\t\tfor( tjs_int i = filecount-1; i>=0; i-- ) {\n\t\t\t::DragQueryFile( hDrop, i, filename, MAX_PATH );\n\t\t\tWIN32_FIND_DATA fd;\n\t\t\tHANDLE h;\n\t\t\t// existence checking\n\t\t\tif((h = ::FindFirstFile(filename, &fd)) != INVALID_HANDLE_VALUE) {\n\t\t\t\t::FindClose(h);\n\t\t\t\ttTJSVariant val = TVPNormalizeStorageName(ttstr(filename));\n\t\t\t\t// push into array\n\t\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE|TJS_IGNOREPROP, count++, &val, array);\n\t\t\t}\n\t\t}\n\t\t::DragFinish(hDrop);\n\n\t\ttTJSVariant arg(array, array);\n\t\tTVPPostInputEvent(  new tTVPOnFileDropInputEvent(TJSNativeInstance, arg));\n\t} catch(...) {\n\t\tarray->Release();\n\t\tthrow;\n\t}\n\tarray->Release();\n}\n\nint TTVPWindowForm::OnMouseActivate( HWND hTopLevelParentWnd, WORD hitTestCode, WORD MouseMsg ) {\n\tif(!Focusable) {\n\t\t// override default action (which activates the window)\n\t\tif( hitTestCode == HTCLIENT )\n\t\t\treturn MA_NOACTIVATE;\n\t\telse\n\t\t\treturn MA_NOACTIVATEANDEAT;\n\t} else {\n\t\treturn MA_ACTIVATE;\n\t}\n}\n\nbool TTVPWindowForm::OnSetCursor( HWND hContainsCursorWnd, WORD hitTestCode, WORD MouseMsg ) {\n\tif( GetHandle() == hContainsCursorWnd && hitTestCode == HTCLIENT ) {\n\t\tMouseCursorManager.UpdateCursor();\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n\nvoid TTVPWindowForm::OnEnable( bool enabled ) {\n\t// enabled status has changed\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnReleaseCaptureInputEvent(TJSNativeInstance));\n\t}\n}\nvoid TTVPWindowForm::OnDeviceChange( UINT_PTR event, void *data ) {\n\tif( event == DBT_DEVNODES_CHANGED ) {\n\t\t// reload DInput device\n\t\tReloadDevice = true; // to reload device\n\t\tReloadDeviceTick = GetTickCount() + 4000; // reload at 4secs later\n\t}\n}\nvoid TTVPWindowForm::OnNonClientMouseDown( int button, UINT_PTR hittest, int x, int y ) {\n\tif(!CanSendPopupHide()) {\n\t\tDeliverPopupHide();\n\t}\n}\nvoid TTVPWindowForm::OnEnterMenuLoop( bool entered ) {\n\tSetForceMouseCursorVisible(true);\n}\nvoid TTVPWindowForm::OnExitMenuLoop( bool isShortcutMenu ) {\n\tSetForceMouseCursorVisible(false);\n}\nvoid TTVPWindowForm::OnMouseEnter() {\n\t// mouse entered in client area\n\tDWORD tick = GetTickCount();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tMouseVelocityTracker.clear();\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent(new tTVPOnMouseEnterInputEvent(TJSNativeInstance));\n\t}\n}\nvoid TTVPWindowForm::OnMouseLeave() {\n\t// mouse leaved from client area\n\tDWORD tick = GetTickCount();\n\tTVPPushEnvironNoise(&tick, sizeof(tick));\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnMouseOutOfWindowInputEvent(TJSNativeInstance));\n\t\tTVPPostInputEvent( new tTVPOnMouseLeaveInputEvent(TJSNativeInstance));\n\t}\n}\nvoid TTVPWindowForm::OnShow( UINT_PTR status ) {\n\t::DragAcceptFiles( GetHandle(), TRUE );\n\t::PostMessage( GetHandle(), TVP_WM_ACQUIREIMECONTROL, 0, 0);\n}\nvoid TTVPWindowForm::OnHide( UINT_PTR status ) {\n}\nvoid TTVPWindowForm::OnFocus(HWND hFocusLostWnd) {\n\t::PostMessage( GetHandle(), TVP_WM_ACQUIREIMECONTROL, 0, 0);\n\n\t::CreateCaret( GetHandle(), NULL, 1, 1);\n\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif(DIPadDevice && TJSNativeInstance ) DIPadDevice->WindowActivated();\n#endif\n\tif(TJSNativeInstance) TJSNativeInstance->FireOnActivate(true);\n}\nvoid TTVPWindowForm::OnFocusLost(HWND hFocusingWnd) {\n\tDestroyCaret();\n\tUnacquireImeControl();\n\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\tif(DIPadDevice && TJSNativeInstance ) DIPadDevice->WindowDeactivated();\n#endif\n\tif(TJSNativeInstance) TJSNativeInstance->FireOnActivate(false);\n}\nvoid TTVPWindowForm::UpdateOrientation() {\n\tif( DisplayOrientation == orientUnknown || DisplayRotate < 0 ) {\n\t\tint orient, rot;\n\t\tif( GetOrientation( orient, rot ) ) {\n\t\t\tif( DisplayOrientation != orient || DisplayRotate != rot ) {\n\t\t\t\tDisplayOrientation = orient;\n\t\t\t\tDisplayRotate = rot;\n\t\t\t}\n\t\t}\n\t}\n}\nbool TTVPWindowForm::GetOrientation( int& orientation, int& rotate ) const {\n\tDEVMODE mode = {0};\n\tmode.dmSize = sizeof(DEVMODE);\n\tmode.dmDriverExtra = 0;\n\tmode.dmFields |= DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;\n\n\tBOOL ret = ::EnumDisplaySettingsEx( NULL, ENUM_CURRENT_SETTINGS, &mode, EDS_ROTATEDMODE );\n\tif( ret ) {\n\t\tif( mode.dmPelsWidth > mode.dmPelsHeight ) {\n\t\t\torientation = orientLandscape;\n\t\t} else if( mode.dmPelsWidth < mode.dmPelsHeight ) {\n\t\t\torientation = orientPortrait;\n\t\t} else {\n\t\t\torientation = orientUnknown;\n\t\t}\n\t\t/* dmDisplayOrientation ƋL(unionȂ̂)Ă̂ŁAȉł͎擾łȂ\n\t\tif( mode.dmOrientation == DMORIENT_PORTRAIT ) {\t// \n\t\t\torientation = orientPortrait;\n\t\t} else if( mode.dmOrientation == DMORIENT_LANDSCAPE ) {\t// c\n\t\t\torientation = orientLandscape;\n\t\t} else {\t// unknown\n\t\t\torientation = orientUnknown;\n\t\t}\n\t\t*/\n\t\tswitch( mode.dmDisplayOrientation ) {\n\t\tcase DMDO_DEFAULT:\n\t\t\trotate = 0;\n\t\t\tbreak;\n\t\tcase DMDO_90:\n\t\t\trotate = 90;\n\t\t\tbreak;\n\t\tcase DMDO_180:\n\t\t\trotate = 180;\n\t\t\tbreak;\n\t\tcase DMDO_270:\n\t\t\trotate = 270;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\trotate = -1;\n\t\t}\n\t}\n\treturn ret != FALSE;\n}\nvoid TTVPWindowForm::OnDisplayChange( UINT_PTR bpp, WORD hres, WORD vres ) {\n\tif( GetFullScreenMode() )\n\t\tRelocateFullScreenMode();\n\n\tint orient;\n\tint rot;\n\tif( GetOrientation( orient, rot ) ) {\n\t\tif( DisplayOrientation != orient || DisplayRotate != rot ) {\n\t\t\tDisplayOrientation = orient;\n\t\t\tDisplayRotate = rot;\n\t\t\tOnDisplayRotate( orient, rot, (int)bpp, hres, vres );\n\t\t}\n\t}\n}\nvoid TTVPWindowForm::OnDisplayRotate( int orientation, int rotate, int bpp, int hresolution, int vresolution ) {\n\tif(TJSNativeInstance) {\n\t\tTVPPostInputEvent( new tTVPOnDisplayRotateInputEvent(TJSNativeInstance, orientation, rotate, bpp, hresolution, vresolution));\n\t}\n}\n\n\n"
  },
  {
    "path": "src/core/environ/win32/WindowFormUnit.h",
    "content": "\n#ifndef __WINDOW_FORM_UNIT_H__\n#define __WINDOW_FORM_UNIT_H__\n\n#include \"tjsCommHead.h\"\n#include \"tvpinputdefs.h\"\n#include \"WindowIntf.h\"\n\n#include \"TVPWindow.h\"\n#include \"MouseCursor.h\"\n#include \"TouchPoint.h\"\n#include \"TVPTimer.h\"\n#include \"VelocityTracker.h\"\n\nenum {\n\tcrDefault = 0x0,\n\tcrNone = -1,\n\tcrArrow = -2,\n\tcrCross = -3,\n\tcrIBeam = -4,\n\tcrSize = -5,\n\tcrSizeNESW = -6,\n\tcrSizeNS = -7,\n\tcrSizeNWSE = -8,\n\tcrSizeWE = -9,\n\tcrUpArrow = -10,\n\tcrHourGlass = -11,\n\tcrDrag = -12,\n\tcrNoDrop = -13,\n\tcrHSplit = -14,\n\tcrVSplit = -15,\n\tcrMultiDrag = -16,\n\tcrSQLWait = -17,\n\tcrNo = -18,\n\tcrAppStart = -19,\n\tcrHelp = -20,\n\tcrHandPoint = -21,\n\tcrSizeAll = -22,\n\tcrHBeam = 1,\n};\n\n//---------------------------------------------------------------------------\n// Options\n//---------------------------------------------------------------------------\nextern void TVPInitWindowOptions();\nextern int TVPFullScreenBPP; // = 0; // 0 for no-change\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// VCL-based constants to TVP-based constants conversion (and vice versa)\n//---------------------------------------------------------------------------\ntTVPMouseButton TVP_TMouseButton_To_tTVPMouseButton(int button);\ntjs_uint32 TVP_TShiftState_To_uint32(tjs_uint32 state);\ntjs_uint32 TVP_TShiftState_From_uint32(tjs_uint32 state);\ntjs_uint32 TVPGetCurrentShiftKeyState();\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TTVPWindowForm\n//---------------------------------------------------------------------------\n#define TVP_WM_SHOWVISIBLE (WM_USER + 2)\n#define TVP_WM_SHOWTOP     (WM_USER + 3)\n#define TVP_WM_RETRIEVEFOCUS     (WM_USER + 4)\n#define TVP_WM_ACQUIREIMECONTROL    (WM_USER + 5)\nextern void TVPShowModalAtAppActivate();\nextern void TVPHideModalAtAppDeactivate();\n//extern HDWP TVPShowModalAtTimer(HDWP);\nclass TTVPWindowForm;\nextern TTVPWindowForm * TVPFullScreenedWindow;\n//---------------------------------------------------------------------------\nstruct tTVPMessageReceiverRecord\n{\n//\ttTVPWindowMessageReceiver Proc;\n\tconst void *UserData;\n// \tbool Deliver(tTVPWindowMessage *Message)\n// \t{ return Proc(const_cast<void*>(UserData), Message); }\t\n};\nclass tTJSNI_Window;\nstruct tTVPRect;\nclass tTVPBaseBitmap;\nclass tTVPWheelDirectInputDevice; // class for DirectInputDevice management\nclass tTVPPadDirectInputDevice; // class for DirectInputDevice management\n\nclass TTVPWindowForm : public tTVPWindow, public TouchHandler {\n\tstatic const int TVP_MOUSE_MAX_ACCEL = 30;\n\tstatic const int TVP_MOUSE_SHIFT_ACCEL = 40;\n\tstatic const int TVP_TOOLTIP_SHOW_DELAY = 500;\nprivate:\n\tbool Focusable;\n\n\t//-- drawdevice related\n\tbool NextSetWindowHandleToDrawDevice;\n\ttTVPRect LastSentDrawDeviceDestRect;\n\t\n\t//-- interface to plugin\n\ttObjectList<tTVPMessageReceiverRecord> WindowMessageReceivers;\n\t\n\t//-- DirectInput related\n\ttTVPWheelDirectInputDevice *DIWheelDevice;\n#ifndef DISABLE_EMBEDDED_GAME_PAD\n\ttTVPPadDirectInputDevice *DIPadDevice;\n#endif\n\tbool ReloadDevice;\n\tDWORD ReloadDeviceTick;\n\n\t//-- TJS object related\n\ttTJSNI_Window * TJSNativeInstance;\n\tint LastMouseDownX, LastMouseDownY; // in Layer coodinates\n\t\n\tstruct{ int x, y; } LastMouseMovedPos;  // in Layer coodinates\n\t//-- full screen managemant related\n\tint InnerWidthSave;\n\tint InnerHeightSave;\n\tDWORD OrgStyle;\n\tDWORD OrgExStyle;\n\tint OrgLeft;\n\tint OrgTop;\n\tint OrgWidth;\n\tint OrgHeight;\n\tint OrgClientWidth;\n\tint OrgClientHeight;\n\ttTVPRect FullScreenDestRect;\n\n\t//-- keyboard input\n\tstd::string PendingKeyCodes;\n\t\n\ttTVPImeMode LastSetImeMode;\n\ttTVPImeMode DefaultImeMode;\n\n\tbool TrapKeys;\n\tbool CanReceiveTrappedKeys;\n\tbool InReceivingTrappedKeys;\n\tbool UseMouseKey; // whether using mouse key emulation\n\ttjs_int MouseKeyXAccel;\n\ttjs_int MouseKeyYAccel;\n\tbool LastMouseMoved;\n\tbool MouseLeftButtonEmulatedPushed;\n\tbool MouseRightButtonEmulatedPushed;\n\tDWORD LastMouseKeyTick;\n\t\n\tbool AttentionPointEnabled;\n\tstruct {\n\t\tint x, y;\n\t} AttentionPoint;\n\tclass tTVPSysFont *AttentionFont;\n\n\t//-- mouse cursor\n\ttTVPMouseCursorState MouseCursorState;\n\tbool ForceMouseCursorVisible; // true in menu select\n\tMouseCursor MouseCursorManager;\n\ttjs_int CurrentMouseCursor;\n\ttjs_int LastMouseScreenX; // managed by RestoreMouseCursor\n\ttjs_int LastMouseScreenY;\n\n\t//-- layer position / size\n\ttjs_int LayerLeft;\n\ttjs_int LayerTop;\n\ttjs_int LayerWidth;\n\ttjs_int LayerHeight;\n\ttjs_int ZoomDenom; // Zooming factor denominator (setting)\n\ttjs_int ZoomNumer; // Zooming factor numerator (setting)\n\ttjs_int ActualZoomDenom; // Zooming factor denominator (actual)\n\ttjs_int ActualZoomNumer; // Zooming factor numerator (actual)\n\n\tDWORD LastRecheckInputStateSent;\n\n\tTouchPointList touch_points_;\n\tttstr HintMessage;\n\tTVPTimer* HintTimer;\n\ttjs_int HintDelay;\n\tiTJSDispatch2* LastHintSender;\n\n\ttjs_int DisplayOrientation;\n\ttjs_int DisplayRotate;\n\n\tVelocityTrackers TouchVelocityTracker;\n\tVelocityTracker MouseVelocityTracker;\nprivate:\n\tvoid SetDrawDeviceDestRect();\n\tvoid TranslateWindowToDrawArea(int &x, int &y);\n\tvoid TranslateWindowToDrawArea(double&x, double &y);\n\tvoid TranslateDrawAreaToWindow(int &x, int &y);\n\n\tvoid FirePopupHide();\n\tbool CanSendPopupHide() const { return !Focusable && GetVisible() && GetStayOnTop(); }\n\t\n\tvoid RestoreMouseCursor();\n\tvoid SetMouseCursorVisibleState(bool b);\n\tvoid SetForceMouseCursorVisible(bool s);\n\t\n\tvoid InternalSetPaintBoxSize();\n\n\tvoid CallWindowDetach(bool close);\n\tvoid CallWindowAttach();\n\tvoid CallFullScreenChanged();\n\tvoid CallFullScreenChanging();\n\t\n// \tbool InternalDeliverMessageToReceiver(tTVPWindowMessage &msg);\n// \tbool DeliverMessageToReceiver(tTVPWindowMessage &msg) {\n// \t\tif( WindowMessageReceivers.GetCount() )\n// \t\t\treturn InternalDeliverMessageToReceiver(msg);\n// \t\telse\n// \t\t\treturn false;\n// \t}\n\tvoid GenerateMouseEvent(bool fl, bool fr, bool fu, bool fd);\n\n\tvoid UnacquireImeControl();\n\tvoid AcquireImeControl();\n\t\n\tTTVPWindowForm * GetKeyTrapperWindow();\n\n\tint ConvertImeMode( tTVPImeMode mode );\n\tvoid OffsetClientPoint( int &x, int &y );\n\t\n// \tstatic bool FindKeyTrapper(LRESULT &result, UINT msg, WPARAM wparam, LPARAM lparam);\n// \tbool ProcessTrappedKeyMessage(LRESULT &result, UINT msg, WPARAM wparam, LPARAM lparam);\n\nprotected:\n//\tLRESULT WINAPI Proc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\n\npublic:\n\tTTVPWindowForm( class tTVPApplication* app, tTJSNI_Window* ni, tTJSNI_Window* parent = NULL );\n\tvirtual ~TTVPWindowForm();\n\t\n\tstatic void DeliverPopupHide();\n\n\t//-- properties\n\tstd::wstring GetCaption() const {\n\t\tstd::wstring ret;\n\t\ttTVPWindow::GetCaption( ret );\n\t\treturn ret;\n\t}\n\n\tvoid CleanupFullScreen();\n\n\tvoid SetUseMouseKey(bool b);\n\tbool GetUseMouseKey() const;\n\n\tvoid SetTrapKey(bool b);\n\tbool GetTrapKey() const;\n\n\tvoid SetMaskRegion(HRGN threshold);\n\tvoid RemoveMaskRegion();\n\n\tvoid SetMouseCursorToWindow( tjs_int cursor );\n\n\tvoid HideMouseCursor();\n\tvoid SetMouseCursorState(tTVPMouseCursorState mcs);\n    tTVPMouseCursorState GetMouseCursorState() const { return MouseCursorState; }\n\n\tvoid SetFocusable(bool b);\n\tbool GetFocusable() const { return Focusable; }\n\n\tvoid AdjustNumerAndDenom(tjs_int &n, tjs_int &d);\n\tvoid SetZoom(tjs_int numer, tjs_int denom, bool set_logical = true);\n\tvoid SetZoomNumer( tjs_int n ) { SetZoom(n, ZoomDenom); }\n\ttjs_int GetZoomNumer() const { return ZoomNumer; }\n\tvoid SetZoomDenom(tjs_int d) { SetZoom(ZoomNumer, d); }\n\ttjs_int GetZoomDenom() const { return ZoomDenom; }\n\t\n\t//-- full screen management\n\tvoid SetFullScreenMode(bool b);\n\tbool GetFullScreenMode() const;\n\tvoid RelocateFullScreenMode();\n\n\t//-- methods/properties\n\tvoid UpdateWindow(tTVPUpdateType type = utNormal);\n\tvoid ShowWindowAsModal();\n\n\tvoid SetVisibleFromScript(bool b);\n\n\tvoid RegisterWindowMessageReceiver(tTVPWMRRegMode mode, void * proc, const void *userdata);\n\n\t//-- close action related\n\tbool Closing;\n\tbool ProgramClosing;\n\tbool CanCloseWork;\n\tvoid Close();\n\tvoid InvalidateClose();\n\tvoid OnCloseQueryCalled(bool b);\n\tvoid SendCloseMessage();\n\t\n\tvoid ZoomRectangle( tjs_int & left, tjs_int & top, tjs_int & right, tjs_int & bottom);\n\tvoid GetVideoOffset(tjs_int &ofsx, tjs_int &ofsy);\n\n\tHWND GetSurfaceWindowHandle() { return GetHandle(); }\n\tHWND GetWindowHandle() { return GetHandle(); }\n\tHWND GetWindowHandleForPlugin() { return GetHandle(); }\n\n\t//-- form mode\n\tbool GetFormEnabled();\n\tvoid TickBeat(); // called every 50ms intervally\n\tbool GetWindowActive();\n\n\t//-- draw device\n\tvoid ResetDrawDevice();\n\n\tvoid InternalKeyUp(WORD key, tjs_uint32 shift);\n\tvoid InternalKeyDown(WORD key, tjs_uint32 shift);\n\n\t\n\tvoid SetPaintBoxSize(tjs_int w, tjs_int h);\n\n\tvoid SetDefaultMouseCursor();\n\tvoid SetMouseCursor(tjs_int handle);\n\n\tvoid GetCursorPos(tjs_int &x, tjs_int &y);\n\tvoid SetCursorPos(tjs_int x, tjs_int y);\n\n\tvoid SetHintText(iTJSDispatch2* sender, const ttstr &text);\n\tvoid UpdateHint();\n\n\tvoid SetImeMode(tTVPImeMode mode);\n\tvoid SetDefaultImeMode(tTVPImeMode mode, bool reset);\n\ttTVPImeMode GetDefaultImeMode() const { return  DefaultImeMode; }\n\tvoid ResetImeMode();\n\t\n\tvoid SetAttentionPoint(tjs_int left, tjs_int top, const struct tTVPFont * font );\n\tvoid DisableAttentionPoint();\n\t\n\tvoid InvokeShowVisible();\n\tvoid InvokeShowTop(bool activate = true);\n//\tHDWP ShowTop(HDWP hdwp);\n\n\t//-- DirectInput related\n\tvoid CreateDirectInputDevice();\n\tvoid FreeDirectInputDevice();\n\n\tint GetDisplayOrientation() { UpdateOrientation(); return DisplayOrientation; }\n\tint GetDisplayRotate() { UpdateOrientation(); return DisplayRotate; }\n\n\t// message hander\n\tvirtual void OnActive( HWND preactive );\n\tvirtual void OnDeactive( HWND postactive );\n\n\tvirtual void OnKeyDown( WORD vk, int shift, int repeat, bool prevkeystate );\n\tvirtual void OnKeyUp( WORD vk, int shift );\n\tvirtual void OnKeyPress( WORD vk, int repeat, bool prevkeystate, bool convertkey );\n\n\tvirtual void OnPaint();\n\tvirtual void OnClose( CloseAction& action );\n\tvirtual bool OnCloseQuery();\n\tvirtual void OnMouseDown( int button, int shift, int x, int y );\n\tvirtual void OnMouseUp( int button, int shift, int x, int y );\n\tvirtual void OnMouseMove( int shift, int x, int y );\n\tvirtual void OnMouseDoubleClick( int button, int x, int y );\n\tvirtual void OnMouseClick( int button, int shift, int x, int y );\n\tvirtual void OnMouseWheel( int delta, int shift, int x, int y );\n\n\tvirtual void OnMove( int x, int y );\n\tvirtual void OnResize( UINT_PTR state, int w, int h );\n//\tvirtual void OnDropFile( HDROP hDrop );\n\tvirtual int OnMouseActivate( HWND hTopLevelParentWnd, WORD hitTestCode, WORD MouseMsg );\n\tvirtual bool OnSetCursor( HWND hContainsCursorWnd, WORD hitTestCode, WORD MouseMsg );\n\tvirtual void OnEnable( bool enabled );\n\tvirtual void OnDeviceChange( UINT_PTR event, void *data );\n\tvirtual void OnNonClientMouseDown( int button, UINT_PTR hittest, int x, int y );\n\tvirtual void OnMouseEnter();\n\tvirtual void OnMouseLeave();\n\tvirtual void OnEnterMenuLoop( bool entered );\n\tvirtual void OnExitMenuLoop( bool isShortcutMenu );\n\tvirtual void OnShow( UINT_PTR status );\n\tvirtual void OnHide( UINT_PTR status );\n\n\tvirtual void OnFocus(HWND hFocusLostWnd);\n\tvirtual void OnFocusLost(HWND hFocusingWnd);\n\t\n\tvirtual void OnTouchDown( double x, double y, double cx, double cy, DWORD id, DWORD tick );\n\tvirtual void OnTouchMove( double x, double y, double cx, double cy, DWORD id, DWORD tick );\n\tvirtual void OnTouchUp( double x, double y, double cx, double cy, DWORD id, DWORD tick );\n\tvirtual void OnTouchSequenceStart();\n\tvirtual void OnTouchSequenceEnd();\n\n\tvirtual void OnTouchScaling( double startdist, double currentdist, double cx, double cy, int flag );\n\tvirtual void OnTouchRotate( double startangle, double currentangle, double distance, double cx, double cy, int flag );\n\tvirtual void OnMultiTouch();\n\n\tvirtual void OnDisplayChange( UINT_PTR bpp, WORD hres, WORD vres );\n\tvirtual void OnDisplayRotate( int orientation, int rotate, int bpp, int hresolution, int vresolution );\n\n\tvirtual void OnApplicationActivateChange( bool activated, DWORD thread_id );\n\n\tvirtual void OnDestroy();\n#if 0\n\tvoid WMShowVisible();\n\tvoid WMShowTop( WPARAM wParam );\n\tvoid WMRetrieveFocus();\n\tvoid WMAcquireImeControl();\n#endif\n\tvoid SetTouchScaleThreshold( double threshold ) {\n\t\ttouch_points_.SetScaleThreshold( threshold );\n\t}\n\tdouble GetTouchScaleThreshold() const {\n\t\treturn touch_points_.GetScaleThreshold();\n\t}\n\tvoid SetTouchRotateThreshold( double threshold ) {\n\t\ttouch_points_.SetRotateThreshold( threshold );\n\t}\n\tdouble GetTouchRotateThreshold() const {\n\t\treturn touch_points_.GetRotateThreshold();\n\t}\n\ttjs_real GetTouchPointStartX( tjs_int index ) const { return touch_points_.GetStartX(index); }\n\ttjs_real GetTouchPointStartY( tjs_int index ) const { return touch_points_.GetStartY(index); }\n\ttjs_real GetTouchPointX( tjs_int index ) const { return touch_points_.GetX(index); }\n\ttjs_real GetTouchPointY( tjs_int index ) const { return touch_points_.GetY(index); }\n\ttjs_int GetTouchPointID( tjs_int index ) const { return touch_points_.GetID(index); }\n\ttjs_int GetTouchPointCount() const { return touch_points_.CountUsePoint(); }\n\tbool GetTouchVelocity( tjs_int id, float& x, float& y, float& speed ) const {\n\t\treturn TouchVelocityTracker.getVelocity( id, x, y, speed );\n\t}\n\tbool GetMouseVelocity( float& x, float& y, float& speed ) const {\n\t\tif( MouseVelocityTracker.getVelocity( x, y ) ) {\n\t\t\tspeed = hypotf(x, y);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tvoid ResetMouseVelocity() {\n\t\tMouseVelocityTracker.clear();\n\t}\n\tvoid ResetTouchVelocity( tjs_int id ) {\n\t\tTouchVelocityTracker.end( id );\n\t}\n\n\tvoid SetHintDelay( tjs_int delay ) { HintDelay = delay; }\n\ttjs_int GetHintDelay() const { return HintDelay; }\n\n\tvoid SetEnableTouch( bool b );\n\tbool GetEnableTouch() const;\n\n\tvoid UpdateOrientation();\n\tbool GetOrientation( int& orientation, int& rotate ) const;\n};\n\n#endif // __WINDOW_FORM_UNIT_H__\n"
  },
  {
    "path": "src/core/environ/win32/WindowsUtil.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"tjsError.h\"\n#include \"Application.h\"\n#include \"DebugIntf.h\"\n#include \"WindowsUtil.h\"\n\nvoid TVPThrowWindowsErrorException() {\n\tttstr mes;\n\tLPVOID lpMsgBuf;\n\t::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\tNULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );\n\tmes = ttstr( (LPCWSTR)lpMsgBuf );\n\t::LocalFree(lpMsgBuf);\n\tthrow new TJS::eTJSError( mes );\n}\n\nvoid TVPOutputWindowsErrorToDebugMessage() {\n\tLPVOID lpMsgBuf;\n\t::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\tNULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );\n\t::OutputDebugString( (LPCWSTR)lpMsgBuf );\n\t::LocalFree(lpMsgBuf);\n}\n\nvoid TVPOutputWindowsErrorToConsole( const char* file, int line ) {\n\tLPVOID lpMsgBuf;\n\tDWORD len = ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\tNULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );\n\tif( len > 0 ) {\n#ifdef _DEBUG\n\t\tttstr str(ttstr(L\"(error) Windows Error : \") + ttstr(L\"file : \") + ttstr(file) + ttstr(L\", line : \") + ttstr(line) + ttstr(L\", message : \") + ttstr((LPCWSTR)lpMsgBuf));\n#else\n\t\tttstr str(ttstr(L\"(error) Windows Error : \") + ttstr((LPCWSTR)lpMsgBuf));\n#endif\n\t\tTVPAddImportantLog( str );\n\t}\n\t::LocalFree(lpMsgBuf);\n}\n\n"
  },
  {
    "path": "src/core/environ/win32/WindowsUtil.h",
    "content": "\n#ifndef __WINDOWS_ERROR_EXCEPTION_H__\n#define __WINDOWS_ERROR_EXCEPTION_H__\n\nextern void TVPThrowWindowsErrorException();\nextern void TVPOutputWindowsErrorToDebugMessage();\nextern void TVPOutputWindowsErrorToConsole( const char* file=NULL, int line=0 );\n\n#define TVP_WINDOWS_ERROR_LOG TVPOutputWindowsErrorToConsole( __FILE__, __LINE__ );\n\n#endif\t// __WINDOWS_ERROR_EXCEPTION_H__\n"
  },
  {
    "path": "src/core/environ/win32/config.h",
    "content": "#ifndef __ConfigH\n#define __ConfigH\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/environ/win32/my_HintWindow.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"HintWindow.h\"\nHDWP TVPShowHintWindowTop(HDWP hdwp)\n{\n\treturn NULL;\n}\n"
  },
  {
    "path": "src/core/environ/win32type.h",
    "content": "#pragma once\n#if 0\ntypedef long HRESULT;\ntypedef void* HANDLE;\ntypedef HANDLE HWND;\n\ntypedef struct tagRGBQUAD {\n\tuint8_t    rgbBlue;\n\tuint8_t    rgbGreen;\n\tuint8_t    rgbRed;\n\tuint8_t    rgbReserved;\n} RGBQUAD;\n\ntypedef struct BITMAPINFOHEADER{\n\tuint32_t biSize;\n\tint32_t            biWidth;\n\tint32_t            biHeight;\n\tuint16_t  biPlanes;\n\tuint16_t  biBitCount;\n\tuint32_t   biCompression;\n\tuint32_t   biSizeImage;\n\tint32_t            biXPelsPerMeter;\n\tint32_t            biYPelsPerMeter;\n\tuint32_t   biClrUsed;\n\tuint32_t   biClrImportant;\n} *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;\n\ntypedef struct BITMAPINFO {\n\tBITMAPINFOHEADER    bmiHeader;\n\tRGBQUAD             bmiColors[1];\n} *LPBITMAPINFO, *PBITMAPINFO;\n\ntypedef struct {\n\tint\tleft;\n\tint\ttop;\n\tint\tright;\n\tint\tbottom;\n} RECT, RECTL;\n#endif"
  },
  {
    "path": "src/core/extension/Extension.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"Extension.h\"\n\n//---------------------------------------------------------------------------\n// TVPAddClassHandler related\n//---------------------------------------------------------------------------\nstruct tTVPAtClassInstallInfo {\n\ttTVPAtClassInstallInfo(const tjs_char* name, iTJSDispatch2* (*handler)(iTJSDispatch2*), const tjs_char* dependences ) {\n\t\tName = name, Handler = handler;\n\t\tif( dependences ) {\n\t\t\tttstr dep(dependences);\n\t\t\tconst tjs_char* start = dependences;\n\t\t\tconst tjs_char* cur = dependences;\n\t\t\twhile( *cur ) {\n\t\t\t\tif( (*cur) == TJS_W(',') ) {\n\t\t\t\t\tif( start != cur ) {\n\t\t\t\t\t\tDependences.push_back( ttstr(start, cur - start) );\n\t\t\t\t\t}\n\t\t\t\t\tstart = cur+1;\n\t\t\t\t}\n\t\t\t\tcur++;\n\t\t\t}\n\t\t\tif( start != cur ) {\n\t\t\t\tDependences.push_back(ttstr(start, cur - start));\n\t\t\t}\n\t\t}\n\t}\n\tconst tjs_char* Name;\n\tiTJSDispatch2* (*Handler)(iTJSDispatch2*);\n\tstd::vector<ttstr> Dependences;\t// ˑNXXg\n};\nstatic std::vector<tTVPAtClassInstallInfo> *TVPAtClassInstallInfos = NULL;\nstatic bool TVPAtInstallClass = false;\n//---------------------------------------------------------------------------\nvoid TVPAddClassHandler( const tjs_char* name, iTJSDispatch2* (*handler)(iTJSDispatch2*), const tjs_char* dependences ) {\n\tif(TVPAtInstallClass) return;\n\n\tif(!TVPAtClassInstallInfos) TVPAtClassInstallInfos = new std::vector<tTVPAtClassInstallInfo>();\n\tTVPAtClassInstallInfos->push_back(tTVPAtClassInstallInfo(name, handler, dependences));\n}\n//---------------------------------------------------------------------------\nvoid TVPCauseAtInstallExtensionClass( iTJSDispatch2 *global )\n{\n\tif(TVPAtInstallClass) return;\n\tTVPAtInstallClass = true;\n\n\tif( TVPAtClassInstallInfos ) {\n\t\tiTJSDispatch2* dsp;\n\t\ttTJSVariant val;\n\t\tstd::vector<tTVPAtClassInstallInfo>::iterator i;\n\t\tfor(i = TVPAtClassInstallInfos->begin(); i != TVPAtClassInstallInfos->end(); i++) {\n\t\t\tdsp = i->Handler(global);\n\t\t\tval = tTJSVariant( dsp/*, dsp*/);\n\t\t\tdsp->Release();\n\t\t\tglobal->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, i->Name, NULL, &val, global);\n\t\t}\n\t\tdelete TVPAtClassInstallInfos;\n\t\tTVPAtClassInstallInfos = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/extension/Extension.h",
    "content": "\n#ifndef __EXTENSION_H__\n#define __EXTENSION_H__\n\n//---------------------------------------------------------------------------\n// tTVPAtInstallClass\n//---------------------------------------------------------------------------\nextern void TVPAddClassHandler( const tjs_char* name, iTJSDispatch2* (*handler)(iTJSDispatch2*), const tjs_char* dependences );\nstruct tTVPAtInstallClass {\n\ttTVPAtInstallClass(const tjs_char* name, iTJSDispatch2* (*handler)(iTJSDispatch2*), const tjs_char* dependences) {\n\t\tTVPAddClassHandler(name, handler, dependences);\n\t}\n};\n\n/*\n\nȉ̂悤ȏŁAcpp ɓĂƁAVMANXǉiKŒǉĂ܂B\nÓINƃNXǉplugin̗lȋ@\\łB\nplugin͎sɃNXǉ܂Aextension̓rh鎞ɁANXI`łB\nstatic tTVPAtInstallClass TVPInstallClassFoo\n\t(TJS_W(\"ClassFoo\"), TVPCreateNativeClass_ClassFoo,TJS_W(\"Window,Layer\"));\nĂяo֐ɂglobaln̂ŁAKvł΂烁oȂǎ擾܂B\no^͌ĂяoԂliTJSDispatch2globalɓo^̂ŁAĂяoꂽ֐œo^Kv\n͂܂B\no^ˑNX3ԖڂɎw\\łÂ݂Ƃ떳Ă܂B\n*/\nextern void TVPCauseAtInstallExtensionClass( iTJSDispatch2 *global );\n\n\n#endif // __EXTENSION_H__\n"
  },
  {
    "path": "src/core/movie/ffmpeg/AE.h",
    "content": "#pragma once\n#include <map>\n#include <list>\n#include <vector>\n#include <utility>\n#include \"AEAudioFormat.h\"\n\nNS_KRMOVIE_BEGIN\ntypedef std::pair<std::string, std::string> AEDevice;\ntypedef std::vector<AEDevice> AEDeviceList;\n\n/* forward declarations */\nclass IAEStream;\nclass IAESound;\nclass IAEPacketizer;\nclass IAudioCallback;\nclass IAEClockCallback;\nclass CAEStreamInfo;\n\n/* sound options */\n#define AE_SOUND_OFF    0 /* disable sounds */\n#define AE_SOUND_IDLE   1 /* only play sounds while no streams are running */\n#define AE_SOUND_ALWAYS 2 /* always play sounds */\n\n/* config options */\n#define AE_CONFIG_FIXED 1\n#define AE_CONFIG_AUTO  2\n#define AE_CONFIG_MATCH 3\n\nenum AEQuality\n{\n  AE_QUALITY_UNKNOWN    = -1, /* Unset, unknown or incorrect quality level */\n  AE_QUALITY_DEFAULT    =  0, /* Engine's default quality level */\n\n  /* Basic quality levels */\n  AE_QUALITY_LOW        = 20, /* Low quality level */\n  AE_QUALITY_MID        = 30, /* Standard quality level */\n  AE_QUALITY_HIGH       = 50, /* Best sound processing quality */\n\n  /* Optional quality levels */\n  AE_QUALITY_REALLYHIGH = 100, /* Uncompromised optional quality level,\n                               usually with unmeasurable and unnoticeable improvement */ \n  AE_QUALITY_GPU        = 101, /* GPU acceleration */\n};\n\n/**\n * IAE Interface\n */\nclass IAE\n{\nprotected:\n  friend class CAEFactory;\n\n  IAE() {}\n  virtual ~IAE() {}\n\n  /**\n   * Returns true when it should be possible to initialize this engine, if it returns false\n   * CAEFactory can possibly fall back to a different one\n   */\n  virtual bool CanInit() { return true; }\n\n  /**\n   * Initializes the AudioEngine, called by CFactory when it is time to initialize the audio engine.\n   * Do not call this directly, CApplication will call this when it is ready\n   */\n  virtual bool Initialize() = 0;\npublic:\n  /**\n   * Called when the application needs to terminate the engine\n   */\n  virtual void Shutdown() { }\n\n  /**\n   * Suspends output and de-initializes sink\n   * Used to avoid conflicts with external players or to reduce power consumption\n   * @return True if successful\n   */\n  virtual bool Suspend() = 0;\n\n  /**\n   * Resumes output and re-initializes sink\n   * Used to resume output from Suspend() state above\n   * @return True if successful\n   */\n  virtual bool Resume() = 0;\n\n  /**\n   * Get the current Suspend() state\n   * Used by players to determine if audio is being processed\n   * Default is true so players drop audio or pause if engine unloaded\n   * @return True if processing suspended\n   */\n  virtual bool IsSuspended() {return true;}\n  \n  /**\n   * Callback to alert the AudioEngine of setting changes\n   * @param setting The name of the setting that was changed\n   */\n  virtual void OnSettingsChange(const std::string& setting) {}\n\n  /**\n   * Returns the current master volume level of the AudioEngine\n   * @return The volume level between 0.0 and 1.0\n   */\n  virtual float GetVolume() = 0;\n\n  /**\n   * Sets the master volume level of the AudioEngine\n   * @param volume The new volume level between 0.0 and 1.0\n   */\n  virtual void SetVolume(const float volume) = 0;\n\n  /**\n   * Set the mute state (does not affect volume level value)\n   * @param enabled The mute state\n   */\n  virtual void SetMute(const bool enabled) = 0;\n\n  /**\n   * Get the current mute state\n   * @return The current mute state\n   */\n  virtual bool IsMuted() = 0;\n\n  /**\n   * Sets the sound mode\n   * @param mode One of AE_SOUND_OFF, AE_SOUND_IDLE or AE_SOUND_ALWAYS\n   */\n  virtual void SetSoundMode(const int mode) = 0;\n\n  /**\n   * Creates and returns a new IAEStream in the format specified, this function should never fail\n   * @param audioFormat\n   * @param options A bit field of stream options (see: enum AEStreamOptions)\n   * @return a new IAEStream that will accept data in the requested format\n   */\n  virtual IAEStream *MakeStream(AEAudioFormat &audioFormat, unsigned int options = 0, IAEClockCallback *clock = NULL) = 0;\n\n  /**\n   * This method will remove the specifyed stream from the engine.\n   * For OSX/IOS this is essential to reconfigure the audio output.\n   * @param stream The stream to be altered\n   * @return NULL\n   */\n  virtual bool FreeStream(IAEStream *stream) = 0;\n\n  /**\n   * Creates a new IAESound that is ready to play the specified file\n   * @param file The WAV file to load, this supports XBMC's VFS\n   * @return A new IAESound if the file could be loaded, otherwise NULL\n   */\n  virtual IAESound *MakeSound(const std::string &file) = 0;\n\n  /**\n   * Free the supplied IAESound object\n   * @param sound The IAESound object to free\n   */\n  virtual void FreeSound(IAESound *sound) = 0;\n\n  /**\n   * Callback by CApplication for Garbage Collection. This method is called by CApplication every 500ms and can be used to clean up and free no-longer used resources.\n   */\n  virtual void GarbageCollect() = 0;\n\n  /**\n   * Enumerate the supported audio output devices\n   * @param devices The device list to append supported devices to\n   * @param passthrough True if only passthrough devices are wanted\n   */\n  virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough) = 0;\n\n  /**\n   * Returns the default audio device\n   * @param passthrough True if the default passthrough device is wanted\n   * @return the default audio device\n   */\n  virtual std::string GetDefaultDevice(bool passthrough) { return \"default\"; }\n\n  /**\n   * Returns true if the AudioEngine supports AE_FMT_RAW streams for use with formats such as IEC61937\n   * @see CAEPackIEC61937::CAEPackIEC61937()\n   * @returns true if the AudioEngine is capable of RAW output\n   */\n  virtual bool SupportsRaw(AEAudioFormat &format) { return false; }\n\n   /**\n   * Returns true if the AudioEngine supports drain mode which is not streaming silence when idle\n   * @returns true if the AudioEngine is capable of drain mode\n   */\n  virtual bool SupportsSilenceTimeout() { return false; }\n\n  /**\n   * Returns true if the AudioEngine is currently configured for stereo audio\n   * @returns true if the AudioEngine is currently configured for stereo audio\n   */\n  virtual bool HasStereoAudioChannelCount() { return false; }\n\n  /**\n   * Returns true if the AudioEngine is currently configured for HD audio (more than 5.1)\n   * @returns true if the AudioEngine is currently configured for HD audio (more than 5.1)\n   */\n  virtual bool HasHDAudioChannelCount() { return true; }\n\n  virtual void RegisterAudioCallback(IAudioCallback* pCallback) {}\n\n  virtual void UnregisterAudioCallback(IAudioCallback* pCallback) {}\n\n  /**\n   * Returns true if AudioEngine supports specified quality level\n   * @return true if specified quality level is supported, otherwise false\n   */\n  virtual bool SupportsQualityLevel(enum AEQuality level) { return false; }\n\n  /**\n   * AE decides whether this settings should be displayed\n   * @return true if AudioEngine wants to display this setting\n   */\n  virtual bool IsSettingVisible(const std::string &settingId) {return false; }\n\n  /**\n   * Instruct AE to keep configuration for a specified time\n   * @param millis time for which old configuration should be kept\n   */\n  virtual void KeepConfiguration(unsigned int millis) {return; }\n\n  /**\n   * Instruct AE to re-initialize, e.g. after ELD change event\n   */\n  virtual void DeviceChange() {return; }\n\n  /**\n   * Indicates if dsp addon system is active.\n   */\n  virtual bool HasDSP() { return false; };\n\n  /**\n   * Get the current sink data format\n   *\n   * @param Current sink data format. For more details see AEAudioFormat.\n   * @return Returns true on success, else false.\n   */\n  virtual bool GetCurrentSinkFormat(AEAudioFormat &SinkFormat) { return false; }\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEAudioFormat.h",
    "content": "#pragma once\n#include \"AEChannelInfo.h\"\n#include \"AEStreamInfo.h\"\n\n#define AE_IS_PLANAR(x) ((x) >= AE_FMT_U8P && (x) <= AE_FMT_FLOATP)\n\nNS_KRMOVIE_BEGIN\n/**\n * The audio format structure that fully defines a stream's audio information\n */\nstruct AEAudioFormat\n{\n  /**\n   * The stream's data format (eg, AE_FMT_S16LE)\n   */\n  enum AEDataFormat m_dataFormat;\n\n  /**\n   * The stream's sample rate (eg, 48000)\n   */\n  unsigned int m_sampleRate;\n\n  /**\n   * The stream's channel layout\n   */\n  CAEChannelInfo m_channelLayout;\n\n  /**\n   * The number of frames per period\n   */\n  unsigned int m_frames;\n\n  /**\n   * The size of one frame in bytes\n   */\n  unsigned int m_frameSize;\n\n  /**\n   * Stream info of raw passthrough\n   */\n  CAEStreamInfo m_streamInfo;\n\n  AEAudioFormat()\n  {\n    m_dataFormat = AE_FMT_INVALID;\n    m_sampleRate = 0;\n    m_frames = 0;\n    m_frameSize = 0;\n  }\n\n  bool operator==(const AEAudioFormat& fmt) const\n  {\n    return  m_dataFormat    ==  fmt.m_dataFormat    &&\n            m_sampleRate    ==  fmt.m_sampleRate    &&\n            m_channelLayout ==  fmt.m_channelLayout &&\n            m_frames        ==  fmt.m_frames        &&\n            m_frameSize     ==  fmt.m_frameSize     &&\n            m_streamInfo    ==  fmt.m_streamInfo;\n  }\n \n  AEAudioFormat& operator=(const AEAudioFormat& fmt)\n  {\n    m_dataFormat = fmt.m_dataFormat;\n    m_sampleRate = fmt.m_sampleRate;\n    m_channelLayout = fmt.m_channelLayout;\n    m_frames = fmt.m_frames;\n    m_frameSize = fmt.m_frameSize;\n    m_streamInfo = fmt.m_streamInfo;\n\n    return *this;\n  }\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEChannelData.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\nNS_KRMOVIE_BEGIN\n/**\n * The possible channels\n */\nenum AEChannel\n{\n  AE_CH_NULL = -1,\n  AE_CH_RAW ,\n\n  AE_CH_FL  , AE_CH_FR , AE_CH_FC , AE_CH_LFE, AE_CH_BL  , AE_CH_BR  , AE_CH_FLOC,\n  AE_CH_FROC, AE_CH_BC , AE_CH_SL , AE_CH_SR , AE_CH_TFL , AE_CH_TFR , AE_CH_TFC ,\n  AE_CH_TC  , AE_CH_TBL, AE_CH_TBR, AE_CH_TBC, AE_CH_BLOC, AE_CH_BROC,\n\n  /* p16v devices */\n  AE_CH_UNKNOWN1 , AE_CH_UNKNOWN2 , AE_CH_UNKNOWN3 , AE_CH_UNKNOWN4 ,\n  AE_CH_UNKNOWN5 , AE_CH_UNKNOWN6 , AE_CH_UNKNOWN7 , AE_CH_UNKNOWN8 ,\n  AE_CH_UNKNOWN9 , AE_CH_UNKNOWN10, AE_CH_UNKNOWN11, AE_CH_UNKNOWN12,\n  AE_CH_UNKNOWN13, AE_CH_UNKNOWN14, AE_CH_UNKNOWN15, AE_CH_UNKNOWN16,\n  AE_CH_UNKNOWN17, AE_CH_UNKNOWN18, AE_CH_UNKNOWN19, AE_CH_UNKNOWN20,\n  AE_CH_UNKNOWN21, AE_CH_UNKNOWN22, AE_CH_UNKNOWN23, AE_CH_UNKNOWN24,\n  AE_CH_UNKNOWN25, AE_CH_UNKNOWN26, AE_CH_UNKNOWN27, AE_CH_UNKNOWN28,\n  AE_CH_UNKNOWN29, AE_CH_UNKNOWN30, AE_CH_UNKNOWN31, AE_CH_UNKNOWN32,\n  AE_CH_UNKNOWN33, AE_CH_UNKNOWN34, AE_CH_UNKNOWN35, AE_CH_UNKNOWN36,\n  AE_CH_UNKNOWN37, AE_CH_UNKNOWN38, AE_CH_UNKNOWN39, AE_CH_UNKNOWN40,\n  AE_CH_UNKNOWN41, AE_CH_UNKNOWN42, AE_CH_UNKNOWN43, AE_CH_UNKNOWN44,\n  AE_CH_UNKNOWN45, AE_CH_UNKNOWN46, AE_CH_UNKNOWN47, AE_CH_UNKNOWN48,\n  AE_CH_UNKNOWN49, AE_CH_UNKNOWN50, AE_CH_UNKNOWN51, AE_CH_UNKNOWN52,\n  AE_CH_UNKNOWN53, AE_CH_UNKNOWN54, AE_CH_UNKNOWN55, AE_CH_UNKNOWN56,\n  AE_CH_UNKNOWN57, AE_CH_UNKNOWN58, AE_CH_UNKNOWN59, AE_CH_UNKNOWN60,\n  AE_CH_UNKNOWN61, AE_CH_UNKNOWN62, AE_CH_UNKNOWN63, AE_CH_UNKNOWN64,\n\n  AE_CH_MAX\n};\n\n/**\n * Standard channel layouts\n */\nenum AEStdChLayout\n{\n  AE_CH_LAYOUT_INVALID = -1,\n\n  AE_CH_LAYOUT_1_0 = 0,\n  AE_CH_LAYOUT_2_0,\n  AE_CH_LAYOUT_2_1,\n  AE_CH_LAYOUT_3_0,\n  AE_CH_LAYOUT_3_1,\n  AE_CH_LAYOUT_4_0,\n  AE_CH_LAYOUT_4_1,\n  AE_CH_LAYOUT_5_0,\n  AE_CH_LAYOUT_5_1,\n  AE_CH_LAYOUT_7_0,\n  AE_CH_LAYOUT_7_1,\n\n  AE_CH_LAYOUT_MAX\n};\n\n/**\n * The various data formats\n * LE = Little Endian, BE = Big Endian, NE = Native Endian\n * @note This is ordered from the worst to best preferred formats\n */\nenum AEDataFormat\n{\n  AE_FMT_INVALID = -1,\n\n  AE_FMT_U8,\n\n  AE_FMT_S16BE,\n  AE_FMT_S16LE,\n  AE_FMT_S16NE,\n\n  AE_FMT_S32BE,\n  AE_FMT_S32LE,\n  AE_FMT_S32NE,\n\n  AE_FMT_S24BE4,\n  AE_FMT_S24LE4,\n  AE_FMT_S24NE4,    // 24 bits in lower 3 bytes\n  AE_FMT_S24NE4MSB, // S32 with bits_per_sample < 32\n\n  AE_FMT_S24BE3,\n  AE_FMT_S24LE3,\n  AE_FMT_S24NE3, /* S24 in 3 bytes */\n\n  AE_FMT_DOUBLE,\n  AE_FMT_FLOAT,\n\n  // Bitstream\n  AE_FMT_RAW,\n\n  /* planar formats */\n  AE_FMT_U8P,\n  AE_FMT_S16NEP,\n  AE_FMT_S32NEP,\n  AE_FMT_S24NE4P,\n  AE_FMT_S24NE4MSBP,\n  AE_FMT_S24NE3P,\n  AE_FMT_DOUBLEP,\n  AE_FMT_FLOATP,\n\n  AE_FMT_MAX\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEChannelInfo.cpp",
    "content": "#include \"AEChannelInfo.h\"\n#include <algorithm>\n#include <limits>\n#include <string.h>\n#include <assert.h>\nNS_KRMOVIE_BEGIN\nCAEChannelInfo::CAEChannelInfo()\n{\n  Reset();\n}\n\nCAEChannelInfo::CAEChannelInfo(const enum AEChannel* rhs)\n{\n  *this = rhs;\n}\n\nCAEChannelInfo::CAEChannelInfo(const AEStdChLayout rhs)\n{\n  *this = rhs;\n}\n\nCAEChannelInfo::~CAEChannelInfo()\n{\n}\n\nvoid CAEChannelInfo::ResolveChannels(const CAEChannelInfo& rhs)\n{\n  /* mono gets upmixed to dual mono */\n  if (m_channelCount == 1 && m_channels[0] == AE_CH_FC)\n  {\n    Reset();\n    *this += AE_CH_FL;\n    *this += AE_CH_FR;\n    return;\n  }\n\n  bool srcHasSL = false;\n  bool srcHasSR = false;\n  bool srcHasRL = false;\n  bool srcHasRR = false;\n  bool srcHasBC = false;\n\n  bool dstHasSL = false;\n  bool dstHasSR = false;\n  bool dstHasRL = false;\n  bool dstHasRR = false;\n  bool dstHasBC = false;\n\n  for (unsigned int c = 0; c < rhs.m_channelCount; ++c)\n    switch(rhs.m_channels[c])\n    {\n      case AE_CH_SL: dstHasSL = true; break;\n      case AE_CH_SR: dstHasSR = true; break;\n      case AE_CH_BL: dstHasRL = true; break;\n      case AE_CH_BR: dstHasRR = true; break;\n      case AE_CH_BC: dstHasBC = true; break;\n      default:\n        break;\n    }\n\n  CAEChannelInfo newInfo;\n  for (unsigned int i = 0; i < m_channelCount; ++i)\n  {\n    switch (m_channels[i])\n    {\n      case AE_CH_SL: srcHasSL = true; break;\n      case AE_CH_SR: srcHasSR = true; break;\n      case AE_CH_BL: srcHasRL = true; break;\n      case AE_CH_BR: srcHasRR = true; break;\n      case AE_CH_BC: srcHasBC = true; break;\n      default:\n        break;\n    }\n\n    bool found = false;\n    for (unsigned int c = 0; c < rhs.m_channelCount; ++c)\n      if (m_channels[i] == rhs.m_channels[c])\n      {\n        found = true;\n        break;\n      }\n\n    if (found)\n      newInfo += m_channels[i];\n  }\n\n  /* we need to ensure we end up with rear or side channels for downmix to work */\n  if (srcHasSL && !dstHasSL && dstHasRL && !newInfo.HasChannel(AE_CH_BL))\n    newInfo += AE_CH_BL;\n  if (srcHasSR && !dstHasSR && dstHasRR && !newInfo.HasChannel(AE_CH_BR))\n    newInfo += AE_CH_BR;\n  if (srcHasRL && !dstHasRL && dstHasSL && !newInfo.HasChannel(AE_CH_SL))\n    newInfo += AE_CH_SL;\n  if (srcHasRR && !dstHasRR && dstHasSR && !newInfo.HasChannel(AE_CH_SR))\n    newInfo += AE_CH_SR;\n\n  // mix back center if not available in destination layout\n  // prefer mixing into backs if available\n  if (srcHasBC && !dstHasBC)\n  {\n    if (dstHasRL && !newInfo.HasChannel(AE_CH_BL))\n      newInfo += AE_CH_BL;\n    else if (dstHasSL && !newInfo.HasChannel(AE_CH_SL))\n      newInfo += AE_CH_SL;\n\n    if (dstHasRR && !newInfo.HasChannel(AE_CH_BR))\n      newInfo += AE_CH_BR;\n    else if (dstHasSR && !newInfo.HasChannel(AE_CH_SR))\n      newInfo += AE_CH_SR;\n  }\n\n  *this = newInfo;\n}\n\nvoid CAEChannelInfo::Reset()\n{\n  m_channelCount = 0;\n  for (unsigned int i = 0; i < AE_CH_MAX; ++i)\n    m_channels[i] = AE_CH_NULL;\n}\n\nCAEChannelInfo& CAEChannelInfo::operator=(const CAEChannelInfo& rhs)\n{\n  if (this == &rhs)\n    return *this;\n\n  /* clone the information */\n  m_channelCount = rhs.m_channelCount;\n  memcpy(m_channels, rhs.m_channels, sizeof(enum AEChannel) * rhs.m_channelCount);\n\n  return *this;\n}\n\nCAEChannelInfo& CAEChannelInfo::operator=(const enum AEChannel* rhs)\n{\n  Reset();\n  if (rhs == NULL)\n    return *this;\n\n  while (m_channelCount < AE_CH_MAX && rhs[m_channelCount] != AE_CH_NULL)\n  {\n    m_channels[m_channelCount] = rhs[m_channelCount];\n    ++m_channelCount;\n  }\n\n  /* the last entry should be NULL, if not we were passed a non null terminated list */\n  assert(rhs[m_channelCount] == AE_CH_NULL);\n\n  return *this;\n}\n\nCAEChannelInfo& CAEChannelInfo::operator=(const enum AEStdChLayout rhs)\n{\n  assert(rhs > AE_CH_LAYOUT_INVALID && rhs < AE_CH_LAYOUT_MAX);\n\n  static enum AEChannel layouts[AE_CH_LAYOUT_MAX][9] = {\n    {AE_CH_FC, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_LFE, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_LFE, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_BL , AE_CH_BR , AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_BL , AE_CH_BR , AE_CH_LFE, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_BL , AE_CH_BR , AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_LFE,  AE_CH_BL , AE_CH_BR , AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_BL , AE_CH_BR , AE_CH_SL , AE_CH_SR, AE_CH_NULL},\n    {AE_CH_FL, AE_CH_FR, AE_CH_FC , AE_CH_LFE, AE_CH_BL , AE_CH_BR , AE_CH_SL , AE_CH_SR, AE_CH_NULL}\n  };\n\n  *this = layouts[rhs];\n  return *this;\n}\n\nbool CAEChannelInfo::operator==(const CAEChannelInfo& rhs) const\n{\n  /* if the channel count doesnt match, no need to check further */\n  if (m_channelCount != rhs.m_channelCount)\n    return false;\n\n  /* make sure the channel order is the same */\n  for (unsigned int i = 0; i < m_channelCount; ++i)\n    if (m_channels[i] != rhs.m_channels[i])\n      return false;\n\n  return true;\n}\n\nbool CAEChannelInfo::operator!=(const CAEChannelInfo& rhs) const\n{\n  return !(*this == rhs);\n}\n\nCAEChannelInfo& CAEChannelInfo::operator+=(const enum AEChannel& rhs)\n{\n  assert(m_channelCount < AE_CH_MAX);\n  assert(rhs > AE_CH_NULL && rhs < AE_CH_MAX);\n\n  m_channels[m_channelCount++] = rhs;\n  return *this;\n}\n\nCAEChannelInfo& CAEChannelInfo::operator-=(const enum AEChannel& rhs)\n{\n  assert(rhs > AE_CH_NULL && rhs < AE_CH_MAX);\n\n  unsigned int i = 0;\n  while(i < m_channelCount && m_channels[i] != rhs)\n    i++;\n  if (i >= m_channelCount)\n    return *this; // Channel not found\n\n  for(; i < m_channelCount-1; i++)\n    m_channels[i] = m_channels[i+1];\n\n  m_channels[i] = AE_CH_NULL;\n  m_channelCount--;\n  return *this;\n}\n\nconst enum AEChannel CAEChannelInfo::operator[](unsigned int i) const\n{\n  assert(i < m_channelCount);\n  return m_channels[i];\n}\n\nCAEChannelInfo::operator std::string() const\n{\n  if (m_channelCount == 0)\n    return \"NULL\";\n\n  std::string s;\n  for (unsigned int i = 0; i < m_channelCount - 1; ++i)\n  {\n    s.append(GetChName(m_channels[i]));\n    s.append(\",\");\n  }\n  s.append(GetChName(m_channels[m_channelCount-1]));\n\n  return s;\n}\n\nconst char* CAEChannelInfo::GetChName(const enum AEChannel ch)\n{\n  assert(ch >= 0 && ch < AE_CH_MAX);\n\n  static const char* channels[AE_CH_MAX] =\n  {\n    \"RAW\" ,\n    \"FL\"  , \"FR\" , \"FC\" , \"LFE\", \"BL\"  , \"BR\"  , \"FLOC\",\n    \"FROC\", \"BC\" , \"SL\" , \"SR\" , \"TFL\" , \"TFR\" , \"TFC\" ,\n    \"TC\"  , \"TBL\", \"TBR\", \"TBC\", \"BLOC\", \"BROC\",\n\n    /* p16v devices */\n    \"UNKNOWN1\" , \"UNKNOWN2\" , \"UNKNOWN3\" , \"UNKNOWN4\" , \n    \"UNKNOWN5\" , \"UNKNOWN6\" , \"UNKNOWN7\" , \"UNKNOWN8\" ,\n    \"UNKNOWN9\" , \"UNKNOWN10\", \"UNKNOWN11\", \"UNKNOWN12\",\n    \"UNKNOWN13\", \"UNKNOWN14\", \"UNKNOWN15\", \"UNKNOWN16\",\n    \"UNKNOWN17\", \"UNKNOWN18\", \"UNKNOWN19\", \"UNKNOWN20\",\n    \"UNKNOWN21\", \"UNKNOWN22\", \"UNKNOWN23\", \"UNKNOWN24\",\n    \"UNKNOWN25\", \"UNKNOWN26\", \"UNKNOWN27\", \"UNKNOWN28\",\n    \"UNKNOWN29\", \"UNKNOWN30\", \"UNKNOWN31\", \"UNKNOWN32\",\n    \"UNKNOWN33\", \"UNKNOWN34\", \"UNKNOWN35\", \"UNKNOWN36\", \n    \"UNKNOWN37\", \"UNKNOWN38\", \"UNKNOWN39\", \"UNKNOWN40\",\n    \"UNKNOWN41\", \"UNKNOWN42\", \"UNKNOWN43\", \"UNKNOWN44\",\n    \"UNKNOWN45\", \"UNKNOWN46\", \"UNKNOWN47\", \"UNKNOWN48\",\n    \"UNKNOWN49\", \"UNKNOWN50\", \"UNKNOWN51\", \"UNKNOWN52\",\n    \"UNKNOWN53\", \"UNKNOWN54\", \"UNKNOWN55\", \"UNKNOWN56\",\n    \"UNKNOWN57\", \"UNKNOWN58\", \"UNKNOWN59\", \"UNKNOWN60\",\n    \"UNKNOWN61\", \"UNKNOWN62\", \"UNKNOWN63\", \"UNKNOWN64\"\n  };\n\n  return channels[ch];\n}\n\nbool CAEChannelInfo::HasChannel(const enum AEChannel ch) const\n{\n  for (unsigned int i = 0; i < m_channelCount; ++i)\n    if (m_channels[i] == ch)\n      return true;\n  return false;\n}\n\nbool CAEChannelInfo::ContainsChannels(const CAEChannelInfo& rhs) const\n{\n  for (unsigned int i = 0; i < rhs.m_channelCount; ++i)\n  {\n    if (!HasChannel(rhs.m_channels[i]))\n      return false;\n  }\n  return true;\n}\n\nvoid CAEChannelInfo::ReplaceChannel(const enum AEChannel from, const enum AEChannel to)\n{\n  for (unsigned int i = 0; i < m_channelCount; ++i)\n  {\n    if (m_channels[i] == from)\n    {\n      m_channels[i] = to;\n      break;\n    }\n  }\n}\n\nint CAEChannelInfo::BestMatch(const std::vector<CAEChannelInfo>& dsts, int* score) const\n{\n  CAEChannelInfo availableDstChannels;\n  for (unsigned int i = 0; i < dsts.size(); i++)\n    availableDstChannels.AddMissingChannels(dsts[i]);\n\n  /* if we have channels not existing in any destination layout but that\n   * are remappable (e.g. RC => RL+RR), do those remaps */\n  CAEChannelInfo src(*this);\n  src.ResolveChannels(availableDstChannels);\n\n  bool remapped = (src != *this);\n  /* good enough approximation (does not account for added channels) */\n  int dropped = std::max((int)src.Count() - (int)Count(), 0);\n\n  int bestScore = std::numeric_limits<int>::min();\n  int bestMatch = -1;\n\n  for (unsigned int i = 0; i < dsts.size(); i++)\n  {\n    const CAEChannelInfo& dst = dsts[i];\n    int okChannels = 0;\n\n    for (unsigned int j = 0; j < src.Count(); j++)\n      okChannels += dst.HasChannel(src[j]);\n\n    int missingChannels = src.Count() - okChannels;\n    int extraChannels = dst.Count() - okChannels;\n\n    int curScore = 0 - (missingChannels + dropped) * 1000 - extraChannels * 10 - (remapped ? 1 : 0);\n\n    if (curScore > bestScore)\n    {\n      bestScore = curScore;\n      bestMatch = i;\n      if (curScore == 0)\n        break;\n    }\n  }\n\n  if (score)\n    *score = bestScore;\n\n  return bestMatch;\n}\n\nvoid CAEChannelInfo::AddMissingChannels(const CAEChannelInfo& rhs)\n{\n  for (unsigned int i = 0; i < rhs.Count(); i++)\n    if (!HasChannel(rhs[i]))\n      *this += rhs[i];\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEChannelInfo.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include <string>\n\n#include \"AEChannelData.h\"\n\nNS_KRMOVIE_BEGIN\nclass CHelper_libKODI_audioengine;\n\nclass CAEChannelInfo {\n  friend class CHelper_libKODI_audioengine;\n\npublic:\n  CAEChannelInfo();\n  CAEChannelInfo(const enum AEChannel* rhs);\n  CAEChannelInfo(const enum AEStdChLayout rhs);\n  ~CAEChannelInfo();\n  CAEChannelInfo& operator=(const CAEChannelInfo& rhs);\n  CAEChannelInfo& operator=(const enum AEChannel* rhs);\n  CAEChannelInfo& operator=(const enum AEStdChLayout rhs);\n  bool operator==(const CAEChannelInfo& rhs) const;\n  bool operator!=(const CAEChannelInfo& rhs) const;\n  CAEChannelInfo& operator+=(const enum AEChannel& rhs);\n  CAEChannelInfo& operator-=(const enum AEChannel& rhs);\n  const enum AEChannel operator[](unsigned int i) const;\n  operator std::string() const;\n\n  /* remove any channels that dont exist in the provided info */\n  void ResolveChannels(const CAEChannelInfo& rhs);\n  void Reset();\n  inline unsigned int Count() const { return m_channelCount; }\n  static const char* GetChName(const enum AEChannel ch);\n  bool HasChannel(const enum AEChannel ch) const;\n  bool ContainsChannels(const CAEChannelInfo& rhs) const;\n  void ReplaceChannel(const enum AEChannel from, const enum AEChannel to);\n  int BestMatch(const std::vector<CAEChannelInfo>& dsts, int* score = NULL) const;\n  void AddMissingChannels(const CAEChannelInfo& rhs);\n\nprivate:\n  unsigned int   m_channelCount;\n  enum AEChannel m_channels[AE_CH_MAX];\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEFactory.cpp",
    "content": "#include \"AEFactory.h\"\n#include \"AEStream.h\"\n#include \"WaveMixer.h\"\n#include \"Clock.h\"\nextern \"C\" {\n#include <libswresample/swresample.h>\n}\n#include \"Timer.h\"\n#include <algorithm>\n#include <assert.h>\n\nNS_KRMOVIE_BEGIN\n\nstatic int64_t GetLayoutByChannels(int nChannel) {\n\tswitch (nChannel) {\n\tcase 1:\n\t\treturn AV_CH_LAYOUT_MONO;\n\tcase 2:\n\t\treturn AV_CH_LAYOUT_STEREO;\n\tcase 3:\n\t\treturn AV_CH_LAYOUT_2POINT1;\n\tcase 4:\n\t\treturn AV_CH_LAYOUT_QUAD;\n\tcase 5:\n\t\treturn AV_CH_LAYOUT_5POINT0;\n\tcase 6:\n\t\treturn AV_CH_LAYOUT_5POINT1;\n\tcase 7:\n\t\treturn AV_CH_LAYOUT_6POINT1;\n\tcase 8:\n\t\treturn AV_CH_LAYOUT_7POINT1;\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nclass CAEStreamAL : public IAEStream {\n\tiTVPSoundBuffer *m_impl = nullptr;\n\tAEAudioFormat m_format;\n\tIAEClockCallback *m_cbClock;\n\tdouble m_lastPts = 0;\n\tstruct SwrContext *swr_ctx = nullptr;\n\tAVSampleFormat swr_tgtFormat;\n\tunsigned int src_buffer_count = 0;\n\tunsigned int tgt_frameSize = 0;\n\tuint8_t *audio_buf = nullptr;\n\tunsigned int audio_buf_size = 0;\n\tstd::mutex _mutex;\n\tstd::condition_variable _cond;\n\tTimer _timer;\n\n\tint InitResample(AEAudioFormat &audioFormat) {\n\t\tuint64_t layout = GetLayoutByChannels(audioFormat.m_channelLayout.Count());\n\t\tAVSampleFormat srcFormat;\n\t\tswitch (audioFormat.m_dataFormat) {\n\t\tcase AE_FMT_U8: srcFormat = AV_SAMPLE_FMT_U8; break;\n\t\tcase AE_FMT_S16LE: srcFormat = AV_SAMPLE_FMT_S16; break;\n\t\tcase AE_FMT_S16NE: srcFormat = AV_SAMPLE_FMT_S16; break;\n\t\tcase AE_FMT_S32LE: srcFormat = AV_SAMPLE_FMT_S32; break;\n\t\tcase AE_FMT_S32NE: srcFormat = AV_SAMPLE_FMT_S32; break;\n\t\tcase AE_FMT_DOUBLE: srcFormat = AV_SAMPLE_FMT_DBL; break;\n\t\tcase AE_FMT_FLOAT: srcFormat = AV_SAMPLE_FMT_FLT; break;\n\t\tcase AE_FMT_U8P: srcFormat = AV_SAMPLE_FMT_U8P; break;\n\t\tcase AE_FMT_S16NEP: srcFormat = AV_SAMPLE_FMT_S16P; break;\n\t\tcase AE_FMT_S32NEP: srcFormat = AV_SAMPLE_FMT_S32P; break;\n\t\tcase AE_FMT_DOUBLEP: srcFormat = AV_SAMPLE_FMT_DBLP; break;\n\t\tcase AE_FMT_FLOATP: srcFormat = AV_SAMPLE_FMT_FLTP; break;\n\t\tdefault: throw new std::invalid_argument(\"unknown sample format\");\n\t\t}\n\t\tswitch (audioFormat.m_dataFormat) {\n\t\tcase AE_FMT_S16NEP: case AE_FMT_S32NEP: case AE_FMT_DOUBLEP: case AE_FMT_FLOATP:\n\t\t\tsrc_buffer_count = audioFormat.m_channelLayout.Count(); break;\n\t\tdefault: src_buffer_count = 1; break;\n\t\t}\n\t\tint bitsPerSample = 0;\n\t\tswitch (audioFormat.m_dataFormat) {\n\t\tcase AE_FMT_U8: case AE_FMT_U8P:\n\t\t\tswr_tgtFormat = AV_SAMPLE_FMT_U8;\n\t\t\tbitsPerSample = 8;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tswr_tgtFormat = AV_SAMPLE_FMT_S16;\n\t\t\tbitsPerSample = 16;\n\t\t\tbreak;\n\t\t}\n\t\tswr_ctx = swr_alloc_set_opts(NULL, layout, swr_tgtFormat, audioFormat.m_sampleRate,\n\t\t\tlayout, srcFormat, audioFormat.m_sampleRate, 0, NULL);\n\t\ttgt_frameSize = av_get_bytes_per_sample(swr_tgtFormat) * m_format.m_channelLayout.Count();\n\t\tint result = swr_init(swr_ctx);\n\t\tassert(swr_ctx && result >= 0);\n\t\treturn bitsPerSample;\n\t}\n\npublic:\n\tCAEStreamAL(AEAudioFormat &audioFormat, unsigned int options, IAEClockCallback *clock) {\n\t\tm_format = audioFormat;\n\t\tm_cbClock = clock;\n\t\ttTVPWaveFormat format;\n\t\tformat.SamplesPerSec = audioFormat.m_sampleRate;\n\t\tformat.Channels = audioFormat.m_channelLayout.Count();\n\t\tformat.BitsPerSample = 0;\n\t\tswitch (audioFormat.m_dataFormat) {\n\t\tcase AE_FMT_U8:\n\t\t\tformat.BitsPerSample = 8;\n\t\t\tbreak;\n\t\tcase AE_FMT_S16LE:\n\t\t\tformat.BitsPerSample = 16;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tformat.BitsPerSample = InitResample(audioFormat);\n\t\t\tbreak;\n\t\t}\n\t\tformat.BytesPerSample = format.BitsPerSample / 8;\n\t\tformat.TotalSamples = 0;\n\t\tformat.TotalTime = 0;\n\t\tformat.SpeakerConfig = 0;\n\t\tformat.IsFloat = false;\n\t\tformat.Seekable = false;\n\t\tm_impl = TVPCreateSoundBuffer(format, 8);\n\t}\n\n\tvirtual ~CAEStreamAL() {\n\t\t{\n//\t\t\tstd::unique_lock<std::mutex> lk(_mutex);\n\t\t\tif (swr_ctx) {\n\t\t\t\tswr_free(&swr_ctx);\n\t\t\t}\n\t\t\tif (audio_buf) {\n\t\t\t\tav_freep(&audio_buf);\n\t\t\t}\n\t\t\tif (m_impl) {\n\t\t\t\tdelete m_impl;\n\t\t\t\tm_impl = nullptr;\n\t\t\t}\n\t\t}\n\t\t_cond.notify_all();\n\t}\n\n\tvirtual unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, double pts) override {\n\t\t_timer.Set(1000);\n\t\twhile (/*m_impl &&*/ !m_impl->IsBufferValid()) {\n\t\t\tstd::unique_lock<std::mutex> lk(_mutex);\n\t\t\t_cond.wait_for(lk, std::chrono::milliseconds(10));\n\t\t\tif (_timer.IsTimePast()) return 0;\n\t\t}\n//\t\tif (!m_impl) return 0; // should not be\n#if 0\n\t\tif (m_lastPts != 0) {\n\t\t\tif (std::abs(m_lastPts - pts) > 1000) {\n\t\t\t\tassert(false && \"out of sync\");\n\t\t\t}\n\t\t}\n\n\t\tpts += (double)(frames) / m_format.m_sampleRate;\n\t\tm_lastPts = pts;\n#endif\n\n\t\tif (swr_ctx) {\n\t\t\tuint32_t srcoff = offset * (m_format.m_frameSize / src_buffer_count);\n\t\t\tconst uint8_t *in[8];\n\t\t\tfor (unsigned int i = 0; i < src_buffer_count; ++i) {\n\t\t\t\tin[i] = data[i] + srcoff;\n\t\t\t}\n\t\t\tint out_count = frames + 256;\n\t\t\tint out_size = av_samples_get_buffer_size(NULL, m_format.m_channelLayout.Count(),\n\t\t\t\tout_count, swr_tgtFormat, 0);\n\t\t\tav_fast_malloc(&audio_buf, &audio_buf_size, out_size);\n\t\t\tint len2 = swr_convert(swr_ctx, &audio_buf, out_count, in, frames);\n\t\t\tif (len2 == out_count) {\n\t\t\t\tav_log(NULL, AV_LOG_WARNING, \"audio buffer is probably too small\\n\");\n\t\t\t\tswr_init(swr_ctx);\n\t\t\t}\n\t\t\tm_impl->AppendBuffer(audio_buf, len2 * tgt_frameSize);\n\t\t} else {\n\t\t\tm_impl->AppendBuffer(data[0] + offset * m_format.m_frameSize, frames * m_format.m_frameSize);\n\t\t}\n\n\t\tif (!m_impl->IsPlaying()) { // out of buffer\n\t\t\tm_impl->Play();\n\t\t}\n\t\treturn frames;\n\t}\n\n\tvirtual double GetDelay() override {\n\t\treturn (double)m_impl->GetLatencySeconds();\n\t}\n\n\tvirtual CAESyncInfo GetSyncInfo() override {\n\t\tCAESyncInfo info; // TODO\n\t\tinfo.delay = 0;\n\t\tinfo.error = 0;\n\t\tinfo.rr = 0;\n\t\tinfo.errortime = 0;\n\t\tinfo.state = CAESyncInfo::SYNC_OFF;\n\t\treturn info;\n\t}\n\n\tvirtual double GetCacheTime() override {\n\t\treturn 1; // TODO\n\t}\n\n\tvirtual double GetCacheTotal() override {\n\t\t// return std::max(GetDelay(), (double)TVPAL_BUFFER_COUNT);\n\t\treturn GetDelay();\n\t}\n\n\tvirtual void Pause() override { m_impl->Pause(); }\n\tvirtual void Resume() override { m_impl->Play(); }\n\tvirtual bool IsSuspended() { return !m_impl->IsPlaying(); }\n\tvirtual void Drain(bool wait) {} // TODO\n\tvirtual void Flush() {\n\t\tm_impl->Reset();\n\t}\n\n\tvirtual iTVPSoundBuffer* GetNativeImpl() override { return m_impl; }\n};\n\n\nbool CAEFactory::SupportsRaw(AEAudioFormat &format)\n{\n  // check if passthrough is enabled\n//   if (!CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGH))\n//     return false;\n#if 0\n  // fixed config disabled passthrough\n  if (CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOOUTPUT_CONFIG) == AE_CONFIG_FIXED)\n    return false;\n\n  // check if the format is enabled in settings\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTS_512 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTS_1024 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTS_2048 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_EAC3PASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_TRUEHDPASSTHROUGH))\n    return false;\n  if (format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSHDPASSTHROUGH))\n    return false;\n  if(AE)\n    return AE->SupportsRaw(format);\n#endif\n  // refer to the format in TVPALSoundWrap::Init\n  switch (format.m_dataFormat) {\n  case AE_FMT_U8:\n  case AE_FMT_S16LE:\n\t  break;\n  default:\n\t  return false;\n  }\n\n  //if (format.m_channelLayout.Count() > 2) return false;\n  //if (format.m_sampleRate > 48000) return false;\n\n  return true;\n}\n\nIAEStream *CAEFactory::MakeStream(AEAudioFormat &audioFormat, unsigned int options, IAEClockCallback *clock)\n{\n//   if(AE)\n//     return AE->MakeStream(audioFormat, options, clock);\n\treturn new CAEStreamAL(audioFormat, options, clock);\n  return NULL;\n}\n\nbool CAEFactory::FreeStream(IAEStream *stream)\n{\n//   if(AE)\n//     return AE->FreeStream(stream);\n\tdelete static_cast<CAEStreamAL*>(stream);\n  return true;\n}\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEFactory.h",
    "content": "#pragma once\n#include <utility>\n#include <vector>\n#include \"AE.h\"\n\nNS_KRMOVIE_BEGIN\nclass CSetting;\nclass CAEStreamInfo;\n\nclass CAEFactory\n{\npublic:\n  static bool SupportsRaw(AEAudioFormat &format);\n  static IAEStream *MakeStream(AEAudioFormat &audioFormat, unsigned int options = 0, IAEClockCallback *clock = NULL);\n  static bool FreeStream(IAEStream *stream);\nprivate:\n  static IAE *AE;\n\n  static void SettingOptionsAudioDevicesFillerGeneral(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, bool passthrough);\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEStream.h",
    "content": "#pragma once\n#include \"AEAudioFormat.h\"\n#include <stdint.h>\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\nclass iTVPSoundBuffer;\n\nNS_KRMOVIE_BEGIN\n/**\n * Callback interafce for VideoPlayer clock needed by AE for sync\n */\nclass IAudioCallback;\nclass IAEClockCallback\n{\npublic:\n  virtual double GetClock() = 0;\n  virtual double GetClockSpeed() { return 1.0; };\n};\n\nclass CAESyncInfo\n{\npublic:\n  double delay;\n  double error;\n  double rr; // resample ratio\n  unsigned int errortime;\n  enum AESyncState\n  {\n    SYNC_OFF,\n    SYNC_INSYNC,\n    SYNC_START,\n    SYNC_MUTE,\n    SYNC_ADJUST\n  };\n  AESyncState state;\n};\n\n/**\n * IAEStream Stream Interface for streaming audio\n */\nclass IAEStream\n{\nprotected:\n  friend class IAE;\n  IAEStream() {}\n  virtual ~IAEStream() {}\n\npublic:\n  /**\n   * Returns the amount of space available in the stream\n   * @return The number of bytes AddData will consume\n   */\n//  virtual unsigned int GetSpace() = 0;\n\n  /**\n   * Add planar or interleaved PCM data to the stream\n   * @param data array of pointers to the planes\n   * @param offset to frame in frames\n   * @param frames number of frames\n   * @param pts timestamp\n   * @return The number of frames consumed\n   */\n  virtual unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, double pts = 0.0) = 0;\n\n  /**\n   * Returns the time in seconds that it will take\n   * for the next added packet to be heard from the speakers.\n   * @return seconds\n   */\n  virtual double GetDelay() = 0;\n\n  /**\n   * Returns info about audio to clock synchronization\n   * @return CAESyncInfo\n   */\n  virtual CAESyncInfo GetSyncInfo() = 0;\n\n  /**\n   * Returns if the stream is buffering\n   * @return True if the stream is buffering\n   */\n//  virtual bool IsBuffering() = 0;\n\n  /**\n   * Returns the time in seconds of the stream's\n   * cached audio samples. Engine buffers excluded.\n   * @return seconds\n   */\n  virtual double GetCacheTime() = 0;\n\n  /**\n   * Returns the total time in seconds of the cache\n   * @return seconds\n   */\n  virtual double GetCacheTotal() = 0;\n\n  /**\n   * Pauses the stream playback\n   */\n  virtual void Pause() = 0;\n\n  /**\n   * Resumes the stream after pausing\n   */\n  virtual void Resume() = 0;\n\n  virtual bool IsSuspended() = 0;\n\n  /**\n   * Start draining the stream\n   * @note Once called AddData will not consume more data.\n   */\n  virtual void Drain(bool wait) = 0;\n\n  /**\n   * Returns true if the is stream draining\n   */\n//  virtual bool IsDraining() = 0;\n\n  /**\n   * Returns true if the is stream has finished draining\n   */\n//  virtual bool IsDrained() = 0;\n  \n  /**\n   * Flush all buffers dropping the audio data\n   */\n  virtual void Flush() = 0;\n\n  /**\n   * Return the stream's current volume level\n   * @return The volume level between 0.0 and 1.0\n   */\n//  virtual float GetVolume() = 0;\n\n  /**\n   * Set the stream's volume level\n   * @param volume The new volume level between 0.0 and 1.0\n   */\n//  virtual void  SetVolume(float volume) = 0;\n\n  /**\n   * Returns the stream's current replay gain factor\n   * @return The replay gain factor between 0.0 and 1.0\n   */\n//  virtual float GetReplayGain() {}\n\n  /**\n   * Sets the stream's replay gain factor, this is used by formats such as MP3 that have attenuation information in their streams\n   * @param factor The replay gain factor\n   */\n//  virtual void SetReplayGain(float factor) {}\n\n  /**\n   * Gets the stream's volume amplification in linear units.\n   * @return The volume amplification factor between 1.0 and 1000.0\n   */\n//  virtual float GetAmplification() { return 1; }\n\n  /**\n   * Sets the stream's volume amplification in linear units.\n   * @param The volume amplification factor between 1.0 and 1000.0\n   */\n//  virtual void SetAmplification(float amplify) {}\n\n  /**\n   * Sets the stream ffmpeg informations if present.\n   + @param profile\n   * @param matrix_encoding\n   * @param audio_service_type\n   */\n//  virtual void SetFFmpegInfo(int profile, enum AVMatrixEncoding matrix_encoding, enum AVAudioServiceType audio_service_type) {}\n\n  /**\n   * Returns the size of one audio frame in bytes (channelCount * resolution)\n   * @return The size in bytes of one frame\n  */\n//  virtual const unsigned int GetFrameSize() const = 0;\n\n  /**\n   * Returns the number of channels the stream is configured to accept\n   * @return The channel count\n   */\n//  virtual const unsigned int GetChannelCount() const = 0;\n\n  /**\n   * Returns the stream's sample rate, if the stream is using a dynamic sample rate, this value will NOT reflect any changes made by calls to SetResampleRatio()\n   * @return The stream's sample rate (eg, 48000)\n   */\n//  virtual const unsigned int GetSampleRate() const = 0;\n\n  /**\n   * Return the data format the stream has been configured with\n   * @return The stream's data format (eg, AE_FMT_S16LE)\n   */\n//  virtual const enum AEDataFormat GetDataFormat() const = 0;\n\n  /**\n   * Return the resample ratio\n   * @note This will return an undefined value if the stream is not resampling\n   * @return the current resample ratio or undefined if the stream is not resampling\n   */\n//  virtual double GetResampleRatio() = 0;\n\n  /**\n   * Sets the resample ratio\n   * @note This function may return false if the stream is not resampling, if you wish to use this be sure to set the AESTREAM_FORCE_RESAMPLE option\n   * @param ratio the new sample rate ratio, calculated by ((double)desiredRate / (double)GetSampleRate())\n   */\n//  virtual void SetResampleRatio(double ratio) = 0;\n\n  /**\n   * Sets the resamplling on/ff\n   */\n  virtual void SetResampleMode(int mode) {}\n\n  /**\n   * Registers the audio callback to call with each block of data, this is used by Audio Visualizations\n   * @warning Currently the callbacks require stereo float data in blocks of 512 samples, any deviation from this may crash XBMC, or cause junk to be rendered\n   * @param pCallback The callback\n   */\n//  virtual void RegisterAudioCallback(IAudioCallback* pCallback) = 0;\n\n  /**\n   * Unregisters the current audio callback\n   */\n//  virtual void UnRegisterAudioCallback() = 0;\n\n  /**\n    * Fade the volume level over the specified time\n    * @param from The volume level to fade from (0.0f-1.0f) - See notes\n    * @param target The volume level to fade to (0.0f-1.0f)\n    * @param time The amount of time in milliseconds for the fade to occur\n    * @note The from parameter does not set the streams volume, it is only used to calculate the fade time properly \n    */\n//  virtual void FadeVolume(float from, float target, unsigned int time) {} /* FIXME: once all the engines have these new methods */\n\n  /**\n   * Returns if a fade is still running\n   * @return true if a fade is in progress, otherwise false\n   */\n//  virtual bool IsFading() { return false; }\n\n  /**\n   * Slave a stream to resume when this stream has drained\n   */\n//  virtual void RegisterSlave(IAEStream *stream) {}\n\n  /**\n   * Indicates if dsp addon system is active.\n   */\n  virtual bool HasDSP() { return false; }\n\n  virtual iTVPSoundBuffer* GetNativeImpl() { return nullptr; }\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEStreamData.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\nNS_KRMOVIE_BEGIN\n/**\n * Bit options to pass to IAE::MakeStream\n */\nenum AEStreamOptions\n{\n  AESTREAM_FORCE_RESAMPLE = 1 << 0,   /* force resample even if rates match */\n  AESTREAM_PAUSED         = 1 << 1,   /* create the stream paused */\n  AESTREAM_AUTOSTART      = 1 << 2,   /* autostart the stream when enough data is buffered */\n  AESTREAM_BYPASS_ADSP    = 1 << 3    /* if this option is set the ADSP-System is bypassed and the raw stream will be passed through IAESink */\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEStreamInfo.cpp",
    "content": "#include \"AEStreamInfo.h\"\n#include <algorithm>\n#include <string.h>\n\nNS_KRMOVIE_BEGIN\n#define DTS_PREAMBLE_14BE  0x1FFFE800\n#define DTS_PREAMBLE_14LE  0xFF1F00E8\n#define DTS_PREAMBLE_16BE  0x7FFE8001\n#define DTS_PREAMBLE_16LE  0xFE7F0180\n#define DTS_PREAMBLE_HD    0x64582025\n#define DTS_SFREQ_COUNT    16\n#define MAX_EAC3_BLOCKS    6\n\nstatic const uint16_t AC3Bitrates   [] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640};\nstatic const uint16_t AC3FSCod      [] = {48000, 44100, 32000, 0};\nstatic const uint8_t  AC3BlkCod     [] = {1, 2, 3, 6};\nstatic const uint8_t  AC3Channels   [] = {2, 1, 2, 3, 3, 4, 4, 5};\nstatic const uint8_t  DTSChannels   [] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8};\nstatic const uint8_t  THDChanMap    [] = {2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1};\n\nstatic const uint32_t DTSSampleRates[DTS_SFREQ_COUNT] =\n{\n  0     ,\n  8000  ,\n  16000 ,\n  32000 ,\n  64000 ,\n  128000,\n  11025 ,\n  22050 ,\n  44100 ,\n  88200 ,\n  176400,\n  12000 ,\n  24000 ,\n  48000 ,\n  96000 ,\n  192000\n};\n\nCAEStreamParser::CAEStreamParser() :\n  m_bufferSize    (0),\n  m_skipBytes     (0),\n  m_coreOnly      (false),\n  m_needBytes     (0),\n  m_syncFunc      (&CAEStreamParser::DetectType),\n  m_hasSync       (false),\n  m_coreSize      (0),\n  m_dtsBlocks     (0),\n  m_fsize         (0),\n  m_fsizeMain     (0),\n  m_substreams    (0)\n{\n  av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD));\n}\n\nCAEStreamInfo::CAEStreamInfo() :\n  m_type(STREAM_TYPE_NULL),\n  m_dataIsLE(true),\n  m_dtsPeriod(0),\n  m_repeat(0),\n  m_ac3FrameSize(0)\n{\n}\n\ndouble CAEStreamInfo::GetDuration()\n{\n  double duration = 0;\n  switch (m_type)\n  {\n    case STREAM_TYPE_AC3:\n      duration = 0.032;\n      break;\n    case STREAM_TYPE_EAC3:\n      duration = 6144.0 / m_sampleRate / 4;\n      break;\n    case STREAM_TYPE_TRUEHD:\n      int rate;\n      if (m_sampleRate == 48000 ||\n          m_sampleRate == 96000 ||\n          m_sampleRate == 192000)\n        rate = 192000;\n      else\n        rate = 176400;\n      duration = 3840.0 / rate;\n      break;\n    case STREAM_TYPE_DTS_512:\n    case STREAM_TYPE_DTSHD_CORE:\n    case STREAM_TYPE_DTSHD:\n      duration = 512.0 / m_sampleRate;\n      break;\n    case STREAM_TYPE_DTS_1024:\n      duration = 1024.0 / m_sampleRate;\n      break;\n    case STREAM_TYPE_DTS_2048:\n      duration = 2048.0 / m_sampleRate;\n      break;\n    default:\n//      CLog::Log(LOGERROR, \"CAEStreamInfo::GetDuration - invalid stream type\");\n      break;\n  }\n  return duration * 1000;\n}\n\nbool CAEStreamInfo::operator==(const CAEStreamInfo& info) const\n{\n  if (m_type != info.m_type)\n    return false;\n  if (m_dataIsLE != info.m_dataIsLE)\n    return false;\n  if (m_repeat != info.m_repeat)\n    return false;\n  return true;\n}\n\nCAEStreamParser::~CAEStreamParser()\n{\n}\n\nvoid CAEStreamParser::Reset()\n{\n  m_skipBytes = 0;\n  m_bufferSize = 0;\n  m_needBytes = 0;\n  m_hasSync = false;\n}\n\nint CAEStreamParser::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/* = NULL */, unsigned int *bufferSize/* = 0 */)\n{\n  if (size == 0)\n  {\n    if (bufferSize)\n      *bufferSize = 0;\n    return 0;\n  }\n\n  if (m_skipBytes)\n  {\n    unsigned int canSkip = std::min(size, m_skipBytes);\n    unsigned int room = sizeof(m_buffer) - m_bufferSize;\n    unsigned int copy = std::min(room, canSkip);\n\n    memcpy(m_buffer + m_bufferSize, data, copy);\n    m_bufferSize += copy;\n    m_skipBytes -= copy;\n\n    if (m_skipBytes)\n    {\n      if (bufferSize)\n        *bufferSize = 0;\n      return copy;\n    }\n\n    GetPacket(buffer, bufferSize);\n    return copy;\n  }\n  else\n  {\n    unsigned int consumed = 0;\n    unsigned int offset = 0;\n    unsigned int room = sizeof(m_buffer) - m_bufferSize;\n    while(1)\n    {\n      if (!size)\n      {\n        if (bufferSize)\n          *bufferSize = 0;\n        return consumed;\n      }\n\n      unsigned int copy = std::min(room, size);\n      memcpy(m_buffer + m_bufferSize, data, copy);\n      m_bufferSize += copy;\n      consumed += copy;\n      data += copy;\n      size -= copy;\n      room -= copy;\n\n      if (m_needBytes > m_bufferSize)\n        continue;\n\n      m_needBytes = 0;\n      offset = (this->*m_syncFunc)(m_buffer, m_bufferSize);\n\n      if (m_hasSync || m_needBytes)\n        break;\n      else\n      {\n        /* lost sync */\n        m_syncFunc = &CAEStreamParser::DetectType;\n        m_info.m_type = CAEStreamInfo::STREAM_TYPE_NULL;\n        m_info.m_repeat = 1;\n\n        /* if the buffer is full, or the offset < the buffer size */\n        if (m_bufferSize == sizeof(m_buffer) || offset < m_bufferSize)\n        {\n          m_bufferSize -= offset;\n          room += offset;\n          memmove(m_buffer, m_buffer + offset, m_bufferSize);\n        }\n      }\n    }\n\n    /* if we got here, we acquired sync on the buffer */\n\n    /* align the buffer */\n    if (offset)\n    {\n      m_bufferSize -= offset;\n      memmove(m_buffer, m_buffer + offset, m_bufferSize);\n    }\n\n    /* bytes to skip until the next packet */\n    m_skipBytes = std::max(0, (int)m_fsize - (int)m_bufferSize);\n    if (m_skipBytes)\n    {\n      if (bufferSize)\n        *bufferSize = 0;\n      return consumed;\n    }\n\n    if (!m_needBytes)\n      GetPacket(buffer, bufferSize);\n\n    return consumed;\n  }\n}\n\nvoid CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize)\n{\n  /* if the caller wants the packet */\n  if (buffer)\n  {\n    /* if it is dtsHD and we only want the core, just fetch that */\n    unsigned int size = m_fsize;\n    if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE)\n      size = m_coreSize;\n\n    /* make sure the buffer is allocated and big enough */\n    if (!*buffer || !bufferSize || *bufferSize < size)\n    {\n      delete[] *buffer;\n      *buffer = new uint8_t[size];\n    }\n\n    /* copy the data into the buffer and update the size */\n    memcpy(*buffer, m_buffer, size);\n    if (bufferSize)\n      *bufferSize = size;\n  }\n\n  /* remove the parsed data from the buffer */\n  m_bufferSize -= m_fsize;\n  memmove(m_buffer, m_buffer + m_fsize, m_bufferSize);\n  m_fsize = 0;\n  m_coreSize = 0;\n}\n\n/* SYNC FUNCTIONS */\n\n/*\n  This function looks for sync words across the types in paralell, and only does an exhaustive\n  test if it finds a syncword. Once sync has been established, the relevent sync function sets\n  m_syncFunc to itself. This function will only be called again if total sync is lost, which\n  allows is to switch stream types on the fly much like a real reicever does.\n*/\nunsigned int CAEStreamParser::DetectType(uint8_t *data, unsigned int size)\n{\n  unsigned int skipped  = 0;\n  unsigned int possible = 0;\n\n  while (size > 8)\n  {\n    /* if it could be DTS */\n    unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];\n    if (header == DTS_PREAMBLE_14LE ||\n        header == DTS_PREAMBLE_14BE ||\n        header == DTS_PREAMBLE_16LE ||\n        header == DTS_PREAMBLE_16BE)\n    {\n      unsigned int skip = SyncDTS(data, size);\n      if (m_hasSync || m_needBytes)\n        return skipped + skip;\n      else\n        possible = skipped;\n    }\n\n    /* if it could be AC3 */\n    if (data[0] == 0x0b && data[1] == 0x77)\n    {\n      unsigned int skip = SyncAC3(data, size);\n      if (m_hasSync)\n        return skipped + skip;\n      else\n        possible = skipped;\n    }\n\n    /* if it could be TrueHD */\n    if (data[4] == 0xf8 && data[5] == 0x72 && data[6] == 0x6f && data[7] == 0xba)\n    {\n      unsigned int skip = SyncTrueHD(data, size);\n      if (m_hasSync)\n        return skipped + skip;\n      else\n        possible = skipped;\n    }\n\n    /* move along one byte */\n    --size;\n    ++skipped;\n    ++data;\n  }\n\n  return possible ? possible : skipped;\n}\n\nunsigned int CAEStreamParser::SyncAC3(uint8_t *data, unsigned int size)\n{\n  unsigned int skip = 0;\n\n  // handle substreams\n  if (m_fsizeMain)\n  {\n    data += m_fsizeMain;\n  }\n\n  for (; size - skip > 7; ++skip, ++data)\n  {\n    /* search for an ac3 sync word */\n    if (data[0] != 0x0b || data[1] != 0x77)\n      continue;\n\n    uint8_t bsid  = data[5] >> 3;\n    uint8_t acmod = data[6] >> 5;\n    uint8_t lfeon;\n\n    int8_t pos = 4;\n    if ((acmod & 0x1) && (acmod != 0x1))\n      pos -= 2;\n    if (acmod & 0x4 )\n      pos -= 2;\n    if (acmod == 0x2)\n      pos -= 2;\n    if (pos < 0)\n      lfeon = (data[7] & 0x64) ? 1 : 0;\n    else\n      lfeon = ((data[6] >> pos) & 0x1) ? 1 : 0;\n\n    if (bsid > 0x11 || acmod > 7)\n      continue;\n\n    if (bsid <= 10)\n    {\n      /* Normal AC-3 */\n\n      uint8_t fscod = data[4] >> 6;\n      uint8_t frmsizecod = data[4] & 0x3F;\n      if (fscod == 3 || frmsizecod > 37)\n        continue;\n\n      /* get the details we need to check crc1 and framesize */\n      unsigned int bitRate = AC3Bitrates[frmsizecod >> 1];\n      unsigned int framesize = 0;\n      switch (fscod)\n      {\n        case 0: framesize = bitRate * 2; break;\n        case 1: framesize = (320 * bitRate / 147 + (frmsizecod & 1 ? 1 : 0)); break;\n        case 2: framesize = bitRate * 4; break;\n      }\n\n      m_fsize = framesize << 1;\n      m_info.m_sampleRate = AC3FSCod[fscod];\n\n      /* dont do extensive testing if we have not lost sync */\n      /* this may be the main stream of EAC3 */\n      if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && skip == 0)\n      {\n        m_fsizeMain = m_fsize;\n        m_fsize = 0;\n        return 0;\n      }\n      else if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && skip == 0)\n        return 0;\n\n      unsigned int crc_size;\n      /* if we have enough data, validate the entire packet, else try to validate crc2 (5/8 of the packet) */\n      if (framesize <= size - skip)\n        crc_size = framesize - 1;\n      else \n        crc_size = (framesize >> 1) + (framesize >> 3) - 1;\n\n      if (crc_size <= size - skip)\n        if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &data[2], crc_size * 2))\n          continue;\n\n      /* if we get here, we can sync */\n      m_hasSync = true;\n      m_info.m_channels = AC3Channels[acmod] + lfeon;\n      m_syncFunc = &CAEStreamParser::SyncAC3;\n      m_info.m_type = CAEStreamInfo::STREAM_TYPE_AC3;\n      m_info.m_ac3FrameSize = m_fsize;\n      m_info.m_repeat = 1;\n\n //     CLog::Log(LOGINFO, \"CAEStreamParser::SyncAC3 - AC3 stream detected (%d channels, %dHz)\", m_info.m_channels, m_info.m_sampleRate);\n      return skip;\n    }\n    else\n    {\n      // Enhanced AC-3\n      uint8_t strmtyp = data[2] >> 6;\n      if (strmtyp == 3)\n        continue;\n\n      unsigned int framesize = (((data[2] & 0x7) << 8) | data[3]) + 1;\n      uint8_t fscod = (data[4] >> 6) & 0x3;\n      uint8_t cod = (data[4] >> 4) & 0x3;\n      uint8_t acmod = (data[4] >> 1) & 0x7;\n      uint8_t lfeon = data[4] & 0x1;\n      uint8_t blocks;\n\n      if (fscod == 0x3)\n      {\n        if (cod == 0x3)\n          continue;\n\n        blocks = 6;\n        m_info.m_sampleRate = AC3FSCod[cod] >> 1;\n      }\n      else\n      {\n        blocks = AC3BlkCod[cod];\n        m_info.m_sampleRate = AC3FSCod[fscod];\n      }\n\n      m_fsize = framesize << 1;\n\n      // concatenate substream to independent stream\n      if (strmtyp == 1 && m_fsizeMain)\n      {\n        m_fsize += m_fsizeMain;\n      }\n      m_fsizeMain = 0;\n\n      m_info.m_repeat = MAX_EAC3_BLOCKS / blocks;\n\n      if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && m_hasSync && skip == 0)\n        return 0;\n\n      // if we get here, we can sync\n      m_hasSync = true;\n      m_info.m_channels = AC3Channels[acmod] + lfeon;\n      m_syncFunc = &CAEStreamParser::SyncAC3;\n      m_info.m_type = CAEStreamInfo::STREAM_TYPE_EAC3;\n      m_info.m_ac3FrameSize = m_fsize;\n      m_fsizeMain = 0;\n\n  //    CLog::Log(LOGINFO, \"CAEStreamParser::SyncAC3 - E-AC3 stream detected (%d channels, %dHz)\", m_info.m_channels, m_info.m_sampleRate);\n      return skip;\n    }\n  }\n\n  // if we get here, the entire packet is invalid and we have lost sync\n//  CLog::Log(LOGINFO, \"CAEStreamParser::SyncAC3 - AC3 sync lost\");\n  m_hasSync = false;\n  m_fsizeMain = 0;\n  return skip;\n}\n\nunsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size)\n{\n  if (size < 13)\n  {\n    if (m_needBytes < 13)\n      m_needBytes = 14;\n    return 0;\n  }\n\n  unsigned int skip = 0;\n  for (; size - skip > 13; ++skip, ++data)\n  {\n    unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];\n    unsigned int hd_sync = 0;\n    bool match = true;\n    unsigned int dtsBlocks;\n    unsigned int amode;\n    unsigned int sfreq;\n    unsigned int lfe;\n    int bits;\n\n    switch (header)\n    {\n      /* 14bit BE */\n      case DTS_PREAMBLE_14BE:\n        if (data[4] != 0x07 || (data[5] & 0xf0) != 0xf0)\n        {\n          match = false;\n          break;\n        }\n        dtsBlocks = (((data[5] & 0x7) << 4) | ((data[6] & 0x3C) >> 2)) + 1;\n        m_fsize = (((((data[6] & 0x3) << 8) | data[7]) << 4) | ((data[8] & 0x3C) >> 2)) + 1;\n        amode = ((data[8] & 0x3) << 4) | ((data[9] & 0xF0) >> 4);\n        sfreq = data[9] & 0xF;\n        lfe = (data[12] & 0x18) >> 3;\n        m_info.m_dataIsLE  = false;\n        bits = 14;\n        break;\n\n      /* 14bit LE */\n      case DTS_PREAMBLE_14LE:\n        if (data[5] != 0x07 || (data[4] & 0xf0) != 0xf0)\n        {\n          match = false;\n          break;\n        }\n        dtsBlocks = (((data[4] & 0x7) << 4) | ((data[7] & 0x3C) >> 2)) + 1;\n        m_fsize = (((((data[7] & 0x3) << 8) | data[6]) << 4) | ((data[9] & 0x3C) >> 2)) + 1;\n        amode = ((data[9] & 0x3) << 4) | ((data[8] & 0xF0) >> 4);\n        sfreq = data[8] & 0xF;\n        lfe = (data[13] & 0x18) >> 3;\n        m_info.m_dataIsLE = true;\n        bits = 14;\n        break;\n\n      /* 16bit BE */\n      case DTS_PREAMBLE_16BE:\n        dtsBlocks = (((data[4] & 0x1) << 7) | ((data[5] & 0xFC) >> 2)) + 1;\n        m_fsize = (((((data[5] & 0x3) << 8) | data[6]) << 4) | ((data[7] & 0xF0) >> 4)) + 1;\n        amode = ((data[7] & 0x0F) << 2) | ((data[8] & 0xC0) >> 6);\n        sfreq = (data[8] & 0x3C) >> 2;\n        lfe = (data[10] >> 1) & 0x3;\n        m_info.m_dataIsLE = false;\n        bits = 16;\n        break;\n\n      /* 16bit LE */\n      case DTS_PREAMBLE_16LE:\n        dtsBlocks = (((data[5] & 0x1) << 7) | ((data[4] & 0xFC) >> 2)) + 1;\n        m_fsize = (((((data[4] & 0x3) << 8) | data[7]) << 4) | ((data[6] & 0xF0) >> 4)) + 1;\n        amode = ((data[6] & 0x0F) << 2) | ((data[9] & 0xC0) >> 6);\n        sfreq = (data[9] & 0x3C) >> 2;\n        lfe = (data[11] >> 1) & 0x3;\n        m_info.m_dataIsLE = true;\n        bits = 16;\n        break;\n\n      default:\n        match = false;\n        break;\n    }\n\n    if (!match || sfreq == 0 || sfreq >= DTS_SFREQ_COUNT)\n      continue;\n\n    /* make sure the framesize is sane */\n    if (m_fsize < 96 || m_fsize > 16384)\n      continue;\n\n    bool invalid = false;\n    CAEStreamInfo::DataType dataType;\n    switch (dtsBlocks << 5)\n    {\n      case 512 : dataType = CAEStreamInfo::STREAM_TYPE_DTS_512 ; break;\n      case 1024: dataType = CAEStreamInfo::STREAM_TYPE_DTS_1024; break;\n      case 2048: dataType = CAEStreamInfo::STREAM_TYPE_DTS_2048; break;\n      default:\n        invalid = true;\n        break;\n    }\n\n    if (invalid)\n      continue;\n\n    /* adjust the fsize for 14 bit streams */\n    if (bits == 14)\n      m_fsize = m_fsize / 14 * 16;\n\n    /* we need enough data to check for DTS-HD */\n    if (size - skip < m_fsize + 10)\n    {\n      /* we can assume DTS sync at this point */\n      m_syncFunc  = &CAEStreamParser::SyncDTS;\n      m_needBytes = m_fsize + 10;\n      m_fsize     = 0;\n\n      return skip;\n    }\n\n    /* look for DTS-HD */\n    hd_sync = (data[m_fsize] << 24) | (data[m_fsize + 1] << 16) | (data[m_fsize + 2] << 8) | data[m_fsize + 3];\n    if (hd_sync == DTS_PREAMBLE_HD)\n    {\n      int hd_size;\n      bool blownup = (data[m_fsize + 5] & 0x20) != 0;\n      if (blownup)\n        hd_size = (((data[m_fsize + 6] & 0x01) << 19) | (data[m_fsize + 7] << 11) | (data[m_fsize + 8] << 3) | ((data[m_fsize + 9] & 0xe0) >> 5)) + 1;\n      else\n        hd_size = (((data[m_fsize + 6] & 0x1f) << 11) | (data[m_fsize + 7] << 3) | ((data[m_fsize + 8] & 0xe0) >> 5)) + 1;\n\n      /* set the type according to core or not */\n      if (m_coreOnly)\n        dataType = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE;\n      else\n        dataType = CAEStreamInfo::STREAM_TYPE_DTSHD;\n\n      m_coreSize = m_fsize;\n      m_fsize += hd_size;\n    }\n\n    unsigned int sampleRate = DTSSampleRates[sfreq];\n    if (!m_hasSync || skip || dataType != m_info.m_type || sampleRate != m_info.m_sampleRate || dtsBlocks != m_dtsBlocks)\n    {\n      m_hasSync = true;\n      m_info.m_type = dataType;\n      m_info.m_sampleRate = sampleRate;\n      m_dtsBlocks = dtsBlocks;\n      m_info.m_channels = DTSChannels[amode] + (lfe ? 1 : 0);\n      m_syncFunc = &CAEStreamParser::SyncDTS;\n      m_info.m_repeat = 1;\n\n      if (dataType == CAEStreamInfo::STREAM_TYPE_DTSHD)\n      {\n        m_info.m_channels += 2; /* FIXME: this needs to be read out, not sure how to do that yet */\n        m_info.m_dtsPeriod = (192000 * (8 >> 1)) * (m_dtsBlocks << 5) / m_info.m_sampleRate;\n      }\n      else\n      {\n        m_info.m_dtsPeriod = (m_info.m_sampleRate * (2 >> 1)) * (m_dtsBlocks << 5) / m_info.m_sampleRate;\n      }\n\n      std::string type;\n      switch (dataType)\n      {\n        case CAEStreamInfo::STREAM_TYPE_DTSHD:\n          type = \"dtsHD\";\n          break;\n        case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE:\n          type = \"dtsHD (core)\";\n          break;\n        default:\n          type = \"dts\";\n          break;\n      }\n\n//       CLog::Log(LOGINFO, \"CAEStreamParser::SyncDTS - %s stream detected (%d channels, %dHz, %dbit %s, period: %u)\",\n//                 type.c_str(), m_info.m_channels, m_info.m_sampleRate,\n//                 bits, m_info.m_dataIsLE ? \"LE\" : \"BE\",\n//                 m_info.m_dtsPeriod);\n    }\n\n    return skip;\n  }\n\n  /* lost sync */\n//  CLog::Log(LOGINFO, \"CAEStreamParser::SyncDTS - DTS sync lost\");\n  m_hasSync = false;\n  return skip;\n}\n\ninline unsigned int CAEStreamParser::GetTrueHDChannels(const uint16_t chanmap)\n{\n  int channels = 0;\n  for (int i = 0; i < 13; ++i)\n    channels += THDChanMap[i] * ((chanmap >> i) & 1);\n  return channels;\n}\n\nunsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size)\n{\n  unsigned int left = size;\n  unsigned int skip = 0;\n\n  /* if MLP */\n  for (; left; ++skip, ++data, --left)\n  {\n    /* if we dont have sync and there is less the 8 bytes, then break out */\n    if (!m_hasSync && left < 8)\n      return size;\n\n    /* if its a major audio unit */\n    uint16_t length   = ((data[0] & 0x0F) << 8 | data[1]) << 1;\n    uint32_t syncword = ((((data[4] << 8 | data[5]) << 8) | data[6]) << 8) | data[7];\n    if (syncword == 0xf8726fba)\n    {\n      /* we need 32 bytes to sync on a master audio unit */\n      if (left < 32)\n        return skip;\n\n      /* get the rate and ensure its valid */\n      int rate = (data[8] & 0xf0) >> 4;\n      if (rate == 0xF)\n        continue;\n\n      unsigned int major_sync_size = 28;\n      if (data[29] & 1)\n      {\n        /* extension(s) present, look up count */\n        int extension_count = data[30] >> 4;\n        major_sync_size += 2 + extension_count * 2;\n      }\n\n      if (left < 4 + major_sync_size)\n        return skip;\n\n      /* verify the crc of the audio unit */\n      uint16_t crc = av_crc(m_crcTrueHD, 0, data + 4, major_sync_size - 4);\n      crc ^= (data[4 + major_sync_size - 3] << 8) | data[4 + major_sync_size - 4];\n      if (((data[4 + major_sync_size - 1] << 8) | data[4 + major_sync_size - 2]) != crc)\n        continue;\n\n      /* get the sample rate and substreams, we have a valid master audio unit */\n      m_info.m_sampleRate = (rate & 0x8 ? 44100 : 48000) << (rate & 0x7);\n      m_substreams = (data[20] & 0xF0) >> 4;\n\n      /* get the number of encoded channels */\n      uint16_t channel_map = ((data[10] & 0x1F) << 8) | data[11];\n      if (!channel_map)\n        channel_map = (data[9] << 1) | (data[10] >> 7);\n      m_info.m_channels = CAEStreamParser::GetTrueHDChannels(channel_map);\n\n//       if (!m_hasSync)\n//         CLog::Log(LOGINFO, \"CAEStreamParser::SyncTrueHD - TrueHD stream detected (%d channels, %dHz)\", m_info.m_channels, m_info.m_sampleRate);\n\n      m_hasSync = true;\n      m_fsize = length;\n      m_info.m_type = CAEStreamInfo::STREAM_TYPE_TRUEHD;\n      m_syncFunc = &CAEStreamParser::SyncTrueHD;\n      m_info.m_repeat = 1;\n      return skip;\n    }\n    else\n    {\n      /* we cant sink to a subframe until we have the information from a master audio unit */\n      if (!m_hasSync)\n        continue;\n\n      /* if there is not enough data left to verify the packet, just return the skip amount */\n      if (left < (unsigned int)m_substreams * 4)\n        return skip;\n\n      /* verify the parity */\n      int     p     = 0;\n      uint8_t check = 0;\n      for (int i = -1; i < m_substreams; ++i)\n      {\n        check ^= data[p++];\n        check ^= data[p++];\n        if (i == -1 || data[p - 2] & 0x80)\n        {\n          check ^= data[p++];\n          check ^= data[p++];\n        }\n      }\n\n      /* if the parity nibble does not match */\n      if ((((check >> 4) ^ check) & 0xF) != 0xF)\n      {\n        /* lost sync */\n        m_hasSync  = false;\n  //      CLog::Log(LOGINFO, \"CAEStreamParser::SyncTrueHD - Sync Lost\");\n        continue;\n      }\n      else\n      {\n        m_fsize = length;\n        return skip;\n      }\n    }\n  }\n\n  /* lost sync */\n  m_hasSync  = false;\n  return skip;\n}\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEStreamInfo.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"AEChannelInfo.h\"\n#include <stdint.h>\n\n/* ffmpeg re-defines this, so undef it to squash the warning */\n#undef restrict\n\nextern \"C\" {\n#include \"libavutil/crc.h\"\n}\n\nNS_KRMOVIE_BEGIN\n#define MAX_IEC61937_PACKET  61440\nclass CAEStreamInfo\n{\npublic:\n  CAEStreamInfo();\n  double GetDuration();\n  bool operator==(const CAEStreamInfo& info) const;\n\n  enum DataType\n  {\n    STREAM_TYPE_NULL,\n    STREAM_TYPE_AC3,\n    STREAM_TYPE_DTS_512,\n    STREAM_TYPE_DTS_1024,\n    STREAM_TYPE_DTS_2048,\n    STREAM_TYPE_DTSHD,\n    STREAM_TYPE_DTSHD_CORE,\n    STREAM_TYPE_EAC3,\n    STREAM_TYPE_MLP,\n    STREAM_TYPE_TRUEHD\n  };\n  DataType m_type;\n  unsigned int m_sampleRate;\n  unsigned int m_channels;\n  bool m_dataIsLE;\n  unsigned int m_dtsPeriod;\n  unsigned int m_repeat;\n  unsigned int m_ac3FrameSize;\n};\n\nclass CAEStreamParser\n{\npublic:\n\n  CAEStreamParser();\n  ~CAEStreamParser();\n\n  int AddData(uint8_t *data, unsigned int size, uint8_t **buffer = NULL, unsigned int *bufferSize = 0);\n\n  void SetCoreOnly(bool value) { m_coreOnly = value; }\n  unsigned int IsValid() { return m_hasSync; }\n  unsigned int GetSampleRate() { return m_info.m_sampleRate; }\n  unsigned int GetChannels() { return m_info.m_channels; }\n  unsigned int GetFrameSize() { return m_fsize; }\n  // unsigned int GetDTSBlocks() { return m_dtsBlocks; }\n  unsigned int GetDTSPeriod() { return m_info.m_dtsPeriod; }\n  unsigned int GetEAC3BlocksDiv() { return m_info.m_repeat; }\n  enum CAEStreamInfo::DataType GetDataType() { return m_info.m_type; }\n  bool IsLittleEndian() { return m_info.m_dataIsLE; }\n  unsigned int GetBufferSize() { return m_bufferSize; }\n  CAEStreamInfo& GetStreamInfo() { return m_info; }\n  void Reset();\n\nprivate:\n  uint8_t m_buffer[MAX_IEC61937_PACKET];\n  unsigned int m_bufferSize;\n  unsigned int m_skipBytes;\n\n  typedef unsigned int (CAEStreamParser::*ParseFunc)(uint8_t *data, unsigned int size);\n\n  CAEStreamInfo m_info;\n  bool m_coreOnly;\n  unsigned int m_needBytes;\n  ParseFunc m_syncFunc;\n  bool m_hasSync;\n\n  unsigned int m_coreSize;         /* core size for dtsHD */\n  unsigned int m_dtsBlocks;\n  unsigned int m_fsize;\n  unsigned int m_fsizeMain;        /* used for EAC3 substreams */\n  int m_substreams;       /* used for TrueHD  */\n  AVCRC m_crcTrueHD[1024];  /* TrueHD crc table */\n\n  void GetPacket(uint8_t **buffer, unsigned int *bufferSize);\n  unsigned int DetectType(uint8_t *data, unsigned int size);\n  unsigned int SyncAC3(uint8_t *data, unsigned int size);\n  unsigned int SyncDTS(uint8_t *data, unsigned int size);\n  unsigned int SyncTrueHD(uint8_t *data, unsigned int size);\n\n  static unsigned int GetTrueHDChannels(const uint16_t chanmap);\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEUtil.cpp",
    "content": "#ifndef __STDC_LIMIT_MACROS\n  #define __STDC_LIMIT_MACROS\n#endif\n\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n#include \"config.h\"\n#endif\n\n#include \"AEUtil.h\"\n#include \"TimeUtils.h\"\n\n#include <cassert>\n\nextern \"C\" {\n#include \"libavutil/channel_layout.h\"\n}\nNS_KRMOVIE_BEGIN\n/* declare the rng seed and initialize it */\nunsigned int CAEUtil::m_seed = (unsigned int)(CurrentHostCounter() / 1000.0f);\n#if defined(HAVE_SSE2) && defined(__SSE2__)\n  /* declare the SSE seed and initialize it */\n  MEMALIGN(16, __m128i CAEUtil::m_sseSeed) = _mm_set_epi32(CAEUtil::m_seed, CAEUtil::m_seed+1, CAEUtil::m_seed, CAEUtil::m_seed+1);\n#endif\n\nvoid AEDelayStatus::SetDelay(double d)\n{\n  delay = d;\n  maxcorrection = d;\n  tick = CurrentHostCounter();\n}\n\ndouble AEDelayStatus::GetDelay()\n{\n  double d = 0;\n  if (tick)\n    d = (double)(CurrentHostCounter() - tick) / CurrentHostFrequency();\n  if (d > maxcorrection)\n    d = maxcorrection;\n\n  return delay - d;\n}\n#if 0\nCAEChannelInfo CAEUtil::GuessChLayout(const unsigned int channels)\n{\n  CLog::Log(LOGWARNING, \"CAEUtil::GuessChLayout - \"\n    \"This method should really never be used, please fix the code that called this\");\n\n  CAEChannelInfo result;\n  if (channels < 1 || channels > 8)\n    return result;\n\n  switch (channels)\n  {\n    case 1: result = AE_CH_LAYOUT_1_0; break;\n    case 2: result = AE_CH_LAYOUT_2_0; break;\n    case 3: result = AE_CH_LAYOUT_3_0; break;\n    case 4: result = AE_CH_LAYOUT_4_0; break;\n    case 5: result = AE_CH_LAYOUT_5_0; break;\n    case 6: result = AE_CH_LAYOUT_5_1; break;\n    case 7: result = AE_CH_LAYOUT_7_0; break;\n    case 8: result = AE_CH_LAYOUT_7_1; break;\n  }\n\n  return result;\n}\n#endif\nconst char* CAEUtil::GetStdChLayoutName(const enum AEStdChLayout layout)\n{\n  if (layout < 0 || layout >= AE_CH_LAYOUT_MAX)\n    return \"UNKNOWN\";\n\n  static const char* layouts[AE_CH_LAYOUT_MAX] =\n  {\n    \"1.0\",\n    \"2.0\", \"2.1\", \"3.0\", \"3.1\", \"4.0\",\n    \"4.1\", \"5.0\", \"5.1\", \"7.0\", \"7.1\"\n  };\n\n  return layouts[layout];\n}\n\nconst unsigned int CAEUtil::DataFormatToBits(const enum AEDataFormat dataFormat)\n{\n  if (dataFormat < 0 || dataFormat >= AE_FMT_MAX)\n    return 0;\n\n  static const unsigned int formats[AE_FMT_MAX] =\n  {\n    8,                   /* U8     */\n\n    16,                  /* S16BE  */\n    16,                  /* S16LE  */\n    16,                  /* S16NE  */\n    \n    32,                  /* S32BE  */\n    32,                  /* S32LE  */\n    32,                  /* S32NE  */\n    \n    32,                  /* S24BE  */\n    32,                  /* S24LE  */\n    32,                  /* S24NE  */\n    32,                  /* S24NER */\n    \n    24,                  /* S24BE3 */\n    24,                  /* S24LE3 */\n    24,                  /* S24NE3 */\n    \n    sizeof(double) << 3, /* DOUBLE */\n    sizeof(float ) << 3, /* FLOAT  */\n\n     8,                  /* RAW    */\n\n     8,                  /* U8P    */\n    16,                  /* S16NEP */\n    32,                  /* S32NEP */\n    32,                  /* S24NEP */\n    32,                  /* S24NERP*/\n    24,                  /* S24NE3P*/\n    sizeof(double) << 3, /* DOUBLEP */\n    sizeof(float ) << 3  /* FLOATP  */\n };\n\n  return formats[dataFormat];\n}\n\nconst unsigned int CAEUtil::DataFormatToUsedBits(const enum AEDataFormat dataFormat)\n{\n  if (dataFormat == AE_FMT_S24BE4 || dataFormat == AE_FMT_S24LE4 ||\n      dataFormat == AE_FMT_S24NE4 || dataFormat == AE_FMT_S24NE4MSB)\n    return 24;\n  else\n    return DataFormatToBits(dataFormat);\n}\n\nconst unsigned int CAEUtil::DataFormatToDitherBits(const enum AEDataFormat dataFormat)\n{\n  if (dataFormat == AE_FMT_S24NE4MSB)\n    return 8;\n  if (dataFormat == AE_FMT_S24NE3)\n    return -8;\n  else\n    return 0;\n}\n\nconst char* CAEUtil::StreamTypeToStr(const enum CAEStreamInfo::DataType dataType)\n{\n  switch (dataType)\n  {\n    case CAEStreamInfo::STREAM_TYPE_AC3:\n      return \"STREAM_TYPE_AC3\";\n    case CAEStreamInfo::STREAM_TYPE_DTSHD:\n      return \"STREAM_TYPE_DTSHD\";\n    case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE:\n      return \"STREAM_TYPE_DTSHD_CORE\";\n    case CAEStreamInfo::STREAM_TYPE_DTS_1024:\n      return \"STREAM_TYPE_DTS_1024\";\n    case CAEStreamInfo::STREAM_TYPE_DTS_2048:\n      return \"STREAM_TYPE_DTS_2048\";\n    case CAEStreamInfo::STREAM_TYPE_DTS_512:\n      return \"STREAM_TYPE_DTS_512\";\n    case CAEStreamInfo::STREAM_TYPE_EAC3:\n      return \"STREAM_TYPE_EAC3\";\n    case CAEStreamInfo::STREAM_TYPE_MLP:\n      return \"STREAM_TYPE_MLP\";\n    case CAEStreamInfo::STREAM_TYPE_TRUEHD:\n      return \"STREAM_TYPE_TRUEHD\";\n\n    default:\n      return \"STREAM_TYPE_NULL\";\n  }\n}\n\nconst char* CAEUtil::DataFormatToStr(const enum AEDataFormat dataFormat)\n{\n  if (dataFormat < 0 || dataFormat >= AE_FMT_MAX)\n    return \"UNKNOWN\";\n\n  static const char *formats[AE_FMT_MAX] =\n  {\n    \"AE_FMT_U8\",\n\n    \"AE_FMT_S16BE\",\n    \"AE_FMT_S16LE\",\n    \"AE_FMT_S16NE\",\n    \n    \"AE_FMT_S32BE\",\n    \"AE_FMT_S32LE\",\n    \"AE_FMT_S32NE\",\n    \n    \"AE_FMT_S24BE4\",\n    \"AE_FMT_S24LE4\",\n    \"AE_FMT_S24NE4\",  /* S24 in 4 bytes */\n    \"AE_FMT_S24NE4MSB\",\n    \n    \"AE_FMT_S24BE3\",\n    \"AE_FMT_S24LE3\",\n    \"AE_FMT_S24NE3\", /* S24 in 3 bytes */\n    \n    \"AE_FMT_DOUBLE\",\n    \"AE_FMT_FLOAT\",\n    \n    \"AE_FMT_RAW\",\n\n    /* planar formats */\n    \"AE_FMT_U8P\",\n    \"AE_FMT_S16NEP\",\n    \"AE_FMT_S32NEP\",\n    \"AE_FMT_S24NE4P\",\n    \"AE_FMT_S24NE4MSBP\",\n    \"AE_FMT_S24NE3P\",\n    \"AE_FMT_DOUBLEP\",\n    \"AE_FMT_FLOATP\"\n  };\n\n  return formats[dataFormat];\n}\n\n#if defined(HAVE_SSE) && defined(__SSE__)\nvoid CAEUtil::SSEMulArray(float *data, const float mul, uint32_t count)\n{\n  const __m128 m = _mm_set_ps1(mul);\n\n  /* work around invalid alignment */\n  while (((uintptr_t)data & 0xF) && count > 0)\n  {\n    data[0] *= mul;\n    ++data;\n    --count;\n  }\n\n  uint32_t even = count & ~0x3;\n  for (uint32_t i = 0; i < even; i+=4, data+=4)\n  {\n    __m128 to      = _mm_load_ps(data);\n    *(__m128*)data = _mm_mul_ps (to, m);\n  }\n\n  if (even != count)\n  {\n    uint32_t odd = count - even;\n    if (odd == 1)\n      data[0] *= mul;\n    else\n    {\n      __m128 to;\n      if (odd == 2)\n      {\n        to = _mm_setr_ps(data[0], data[1], 0, 0);\n        __m128 ou = _mm_mul_ps(to, m);\n        data[0] = ((float*)&ou)[0];\n        data[1] = ((float*)&ou)[1];\n      }\n      else\n      {\n        to = _mm_setr_ps(data[0], data[1], data[2], 0);\n        __m128 ou = _mm_mul_ps(to, m);\n        data[0] = ((float*)&ou)[0];\n        data[1] = ((float*)&ou)[1];\n        data[2] = ((float*)&ou)[2];\n      }\n    }\n  }\n}\n\nvoid CAEUtil::SSEMulAddArray(float *data, float *add, const float mul, uint32_t count)\n{\n  const __m128 m = _mm_set_ps1(mul);\n\n  /* work around invalid alignment */\n  while ((((uintptr_t)data & 0xF) || ((uintptr_t)add & 0xF)) && count > 0)\n  {\n    data[0] += add[0] * mul;\n    ++add;\n    ++data;\n    --count;\n  }\n\n  uint32_t even = count & ~0x3;\n  for (uint32_t i = 0; i < even; i+=4, data+=4, add+=4)\n  {\n    __m128 ad      = _mm_load_ps(add );\n    __m128 to      = _mm_load_ps(data);\n    *(__m128*)data = _mm_add_ps (to, _mm_mul_ps(ad, m));\n  }\n\n  if (even != count)\n  {\n    uint32_t odd = count - even;\n    if (odd == 1)\n      data[0] += add[0] * mul;\n    else\n    {\n      __m128 ad;\n      __m128 to;\n      if (odd == 2)\n      {\n        ad = _mm_setr_ps(add [0], add [1], 0, 0);\n        to = _mm_setr_ps(data[0], data[1], 0, 0);\n        __m128 ou = _mm_add_ps(to, _mm_mul_ps(ad, m));\n        data[0] = ((float*)&ou)[0];\n        data[1] = ((float*)&ou)[1];\n      }\n      else\n      {\n        ad = _mm_setr_ps(add [0], add [1], add [2], 0);\n        to = _mm_setr_ps(data[0], data[1], data[2], 0);\n        __m128 ou = _mm_add_ps(to, _mm_mul_ps(ad, m));\n        data[0] = ((float*)&ou)[0];\n        data[1] = ((float*)&ou)[1];\n        data[2] = ((float*)&ou)[2];\n      }\n    }\n  }\n}\n#endif\n\ninline float CAEUtil::SoftClamp(const float x)\n{\n#if 1\n    /*\n       This is a rational function to approximate a tanh-like soft clipper.\n       It is based on the pade-approximation of the tanh function with tweaked coefficients.\n       See: http://www.musicdsp.org/showone.php?id=238\n    */\n    if (x < -3.0f)\n      return -1.0f;\n    else if (x >  3.0f)\n      return 1.0f;\n    float y = x * x;\n    return x * (27.0f + y) / (27.0f + 9.0f * y);\n#else\n    /* slower method using tanh, but more accurate */\n\n    static const double k = 0.9f;\n    /* perform a soft clamp */\n    if (x >  k)\n      x = (float) (tanh((x - k) / (1 - k)) * (1 - k) + k);\n    else if (x < -k)\n      x = (float) (tanh((x + k) / (1 - k)) * (1 - k) - k);\n\n    /* hard clamp anything still outside the bounds */\n    if (x >  1.0f)\n      return  1.0f;\n    if (x < -1.0f)\n      return -1.0f;\n\n    /* return the final sample */\n    return x;\n#endif\n}\n\nvoid CAEUtil::ClampArray(float *data, uint32_t count)\n{\n#if !defined(HAVE_SSE) || !defined(__SSE__)\n  for (uint32_t i = 0; i < count; ++i)\n    data[i] = SoftClamp(data[i]);\n\n#else\n  const __m128 c1 = _mm_set_ps1(27.0f);\n  const __m128 c2 = _mm_set_ps1(27.0f + 9.0f);\n\n  /* work around invalid alignment */\n  while (((uintptr_t)data & 0xF) && count > 0)\n  {\n    data[0] = SoftClamp(data[0]);\n    ++data;\n    --count;\n  }\n\n  uint32_t even = count & ~0x3;\n  for (uint32_t i = 0; i < even; i+=4, data+=4)\n  {\n    /* tanh approx clamp */\n    __m128 dt = _mm_load_ps(data);\n    __m128 tmp     = _mm_mul_ps(dt, dt);\n    *(__m128*)data = _mm_div_ps(\n      _mm_mul_ps(\n        dt,\n        _mm_add_ps(c1, tmp)\n      ),\n      _mm_add_ps(c2, tmp)\n    );\n  }\n\n  if (even != count)\n  {\n    uint32_t odd = count - even;\n    if (odd == 1)\n      data[0] = SoftClamp(data[0]);\n    else\n    {\n      __m128 dt;\n      __m128 tmp;\n      __m128 out;\n      if (odd == 2)\n      {\n        /* tanh approx clamp */\n        dt  = _mm_setr_ps(data[0], data[1], 0, 0);\n        tmp = _mm_mul_ps(dt, dt);\n        out = _mm_div_ps(\n          _mm_mul_ps(\n            dt,\n            _mm_add_ps(c1, tmp)\n          ),\n          _mm_add_ps(c2, tmp)\n        );\n\n        data[0] = ((float*)&out)[0];\n        data[1] = ((float*)&out)[1];\n      }\n      else\n      {\n        /* tanh approx clamp */\n        dt  = _mm_setr_ps(data[0], data[1], data[2], 0);\n        tmp = _mm_mul_ps(dt, dt);\n        out = _mm_div_ps(\n          _mm_mul_ps(\n            dt,\n            _mm_add_ps(c1, tmp)\n          ),\n          _mm_add_ps(c2, tmp)\n        );\n\n        data[0] = ((float*)&out)[0];\n        data[1] = ((float*)&out)[1];\n        data[2] = ((float*)&out)[2];\n      }\n    }\n  }\n#endif\n}\n\n/*\n  Rand implementations based on:\n  http://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/\n  This is NOT safe for crypto work, but perfectly fine for audio usage (dithering)\n*/\nfloat CAEUtil::FloatRand1(const float min, const float max)\n{\n  const float delta  = (max - min) / 2;\n  const float factor = delta / (float)INT32_MAX;\n  return ((float)(m_seed = (214013 * m_seed + 2531011)) * factor) - delta;\n}\n\nvoid CAEUtil::FloatRand4(const float min, const float max, float result[4], __m128 *sseresult/* = NULL */)\n{\n  #if defined(HAVE_SSE2) && defined(__SSE2__)\n    /*\n      this method may be called from other SSE code, we need\n      to calculate the delta & factor using SSE as the FPU\n      state is unknown and _mm_clear() is expensive.\n    */\n    MEMALIGN(16, static const __m128 point5  ) = _mm_set_ps1(0.5f);\n    MEMALIGN(16, static const __m128 int32max) = _mm_set_ps1((const float)INT32_MAX);\n    MEMALIGN(16, __m128 f) = _mm_div_ps(\n      _mm_mul_ps(\n        _mm_sub_ps(\n          _mm_set_ps1(max),\n          _mm_set_ps1(min)\n        ),\n        point5\n      ),\n      int32max\n    );\n\n    MEMALIGN(16, __m128i cur_seed_split);\n    MEMALIGN(16, __m128i multiplier);\n    MEMALIGN(16, __m128i adder);\n    MEMALIGN(16, __m128i mod_mask);\n    MEMALIGN(16, __m128 res);\n    MEMALIGN(16, static const unsigned int mult  [4]) = {214013, 17405, 214013, 69069};\n    MEMALIGN(16, static const unsigned int gadd  [4]) = {2531011, 10395331, 13737667, 1};\n    MEMALIGN(16, static const unsigned int mask  [4]) = {0xFFFFFFFF, 0, 0xFFFFFFFF, 0};\n\n    adder          = _mm_load_si128((__m128i*)gadd);\n    multiplier     = _mm_load_si128((__m128i*)mult);\n    mod_mask       = _mm_load_si128((__m128i*)mask);\n    cur_seed_split = _mm_shuffle_epi32(m_sseSeed, _MM_SHUFFLE(2, 3, 0, 1));\n\n    m_sseSeed      = _mm_mul_epu32(m_sseSeed, multiplier);\n    multiplier     = _mm_shuffle_epi32(multiplier, _MM_SHUFFLE(2, 3, 0, 1));\n    cur_seed_split = _mm_mul_epu32(cur_seed_split, multiplier);\n\n    m_sseSeed      = _mm_and_si128(m_sseSeed, mod_mask);\n    cur_seed_split = _mm_and_si128(cur_seed_split, mod_mask);\n    cur_seed_split = _mm_shuffle_epi32(cur_seed_split, _MM_SHUFFLE(2, 3, 0, 1));\n    m_sseSeed      = _mm_or_si128(m_sseSeed, cur_seed_split);\n    m_sseSeed      = _mm_add_epi32(m_sseSeed, adder);\n\n    /* adjust the value to the range requested */\n    res = _mm_cvtepi32_ps(m_sseSeed);\n    if (sseresult)\n      *sseresult = _mm_mul_ps(res, f);\n    else\n    {\n      res = _mm_mul_ps(res, f);\n      _mm_storeu_ps(result, res);\n\n      /* returning a float array, so cleanup */\n      _mm_empty();\n    }\n\n  #else\n    const float delta  = (max - min) / 2.0f;\n    const float factor = delta / (float)INT32_MAX;\n\n    /* cant return sseresult if we are not using SSE intrinsics */\n    assert(result && !sseresult);\n\n    result[0] = ((float)(m_seed = (214013 * m_seed + 2531011)) * factor) - delta;\n    result[1] = ((float)(m_seed = (214013 * m_seed + 2531011)) * factor) - delta;\n    result[2] = ((float)(m_seed = (214013 * m_seed + 2531011)) * factor) - delta;\n    result[3] = ((float)(m_seed = (214013 * m_seed + 2531011)) * factor) - delta;\n  #endif\n}\n\nbool CAEUtil::S16NeedsByteSwap(AEDataFormat in, AEDataFormat out)\n{\n  const AEDataFormat nativeFormat =\n#ifdef WORDS_BIGENDIAN\n    AE_FMT_S16BE;\n#else\n    AE_FMT_S16LE;\n#endif\n\n  if (in == AE_FMT_S16NE || (in == AE_FMT_RAW))\n    in = nativeFormat;\n  if (out == AE_FMT_S16NE || (out == AE_FMT_RAW))\n    out = nativeFormat;\n\n  return in != out;\n}\n\nuint64_t CAEUtil::GetAVChannelLayout(const CAEChannelInfo &info)\n{\n  uint64_t channelLayout = 0;\n  if (info.HasChannel(AE_CH_FL))   channelLayout |= AV_CH_FRONT_LEFT;\n  if (info.HasChannel(AE_CH_FR))   channelLayout |= AV_CH_FRONT_RIGHT;\n  if (info.HasChannel(AE_CH_FC))   channelLayout |= AV_CH_FRONT_CENTER;\n  if (info.HasChannel(AE_CH_LFE))  channelLayout |= AV_CH_LOW_FREQUENCY;\n  if (info.HasChannel(AE_CH_BL))   channelLayout |= AV_CH_BACK_LEFT;\n  if (info.HasChannel(AE_CH_BR))   channelLayout |= AV_CH_BACK_RIGHT;\n  if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER;\n  if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER;\n  if (info.HasChannel(AE_CH_BC))   channelLayout |= AV_CH_BACK_CENTER;\n  if (info.HasChannel(AE_CH_SL))   channelLayout |= AV_CH_SIDE_LEFT;\n  if (info.HasChannel(AE_CH_SR))   channelLayout |= AV_CH_SIDE_RIGHT;\n  if (info.HasChannel(AE_CH_TC))   channelLayout |= AV_CH_TOP_CENTER;\n  if (info.HasChannel(AE_CH_TFL))  channelLayout |= AV_CH_TOP_FRONT_LEFT;\n  if (info.HasChannel(AE_CH_TFC))  channelLayout |= AV_CH_TOP_FRONT_CENTER;\n  if (info.HasChannel(AE_CH_TFR))  channelLayout |= AV_CH_TOP_FRONT_RIGHT;\n  if (info.HasChannel(AE_CH_TBL))   channelLayout |= AV_CH_TOP_BACK_LEFT;\n  if (info.HasChannel(AE_CH_TBC))   channelLayout |= AV_CH_TOP_BACK_CENTER;\n  if (info.HasChannel(AE_CH_TBR))   channelLayout |= AV_CH_TOP_BACK_RIGHT;\n\n  return channelLayout;\n}\n\nCAEChannelInfo CAEUtil::GetAEChannelLayout(uint64_t layout)\n{\n  CAEChannelInfo channelLayout;\n  channelLayout.Reset();\n\n  if (layout & AV_CH_FRONT_LEFT)       channelLayout += AE_CH_FL;\n  if (layout & AV_CH_FRONT_RIGHT)      channelLayout += AE_CH_FR;\n  if (layout & AV_CH_FRONT_CENTER)     channelLayout += AE_CH_FC;\n  if (layout & AV_CH_LOW_FREQUENCY)    channelLayout += AE_CH_LFE;\n  if (layout & AV_CH_BACK_LEFT)        channelLayout += AE_CH_BL;\n  if (layout & AV_CH_BACK_RIGHT)       channelLayout += AE_CH_BR;\n  if (layout & AV_CH_FRONT_LEFT_OF_CENTER)  channelLayout += AE_CH_FLOC;\n  if (layout & AV_CH_FRONT_RIGHT_OF_CENTER) channelLayout += AE_CH_FROC;\n  if (layout & AV_CH_BACK_CENTER)      channelLayout += AE_CH_BC;\n  if (layout & AV_CH_SIDE_LEFT)        channelLayout += AE_CH_SL;\n  if (layout & AV_CH_SIDE_RIGHT)       channelLayout += AE_CH_SR;\n  if (layout & AV_CH_TOP_CENTER)       channelLayout += AE_CH_TC;\n  if (layout & AV_CH_TOP_FRONT_LEFT)   channelLayout += AE_CH_TFL;\n  if (layout & AV_CH_TOP_FRONT_CENTER) channelLayout += AE_CH_TFC;\n  if (layout & AV_CH_TOP_FRONT_RIGHT)  channelLayout += AE_CH_TFR;\n  if (layout & AV_CH_TOP_BACK_LEFT)    channelLayout += AE_CH_BL;\n  if (layout & AV_CH_TOP_BACK_CENTER)  channelLayout += AE_CH_BC;\n  if (layout & AV_CH_TOP_BACK_RIGHT)   channelLayout += AE_CH_BR;\n\n  return channelLayout;\n}\n\nAVSampleFormat CAEUtil::GetAVSampleFormat(AEDataFormat format)\n{\n  switch (format)\n  {\n    case AEDataFormat::AE_FMT_U8:\n      return AV_SAMPLE_FMT_U8;\n    case AEDataFormat::AE_FMT_S16NE:\n      return AV_SAMPLE_FMT_S16;\n    case AEDataFormat::AE_FMT_S32NE:\n      return AV_SAMPLE_FMT_S32;\n    case AEDataFormat::AE_FMT_S24NE4:\n      return AV_SAMPLE_FMT_S32;\n    case AEDataFormat::AE_FMT_S24NE4MSB:\n      return AV_SAMPLE_FMT_S32;\n    case AEDataFormat::AE_FMT_S24NE3:\n      return AV_SAMPLE_FMT_S32;\n    case AEDataFormat::AE_FMT_FLOAT:\n      return AV_SAMPLE_FMT_FLT;\n    case AEDataFormat::AE_FMT_DOUBLE:\n      return AV_SAMPLE_FMT_DBL;\n    case AEDataFormat::AE_FMT_U8P:\n      return AV_SAMPLE_FMT_U8P;\n    case AEDataFormat::AE_FMT_S16NEP:\n      return AV_SAMPLE_FMT_S16P;\n    case AEDataFormat::AE_FMT_S32NEP:\n      return AV_SAMPLE_FMT_S32P;\n    case AEDataFormat::AE_FMT_S24NE4P:\n      return AV_SAMPLE_FMT_S32P;\n    case AEDataFormat::AE_FMT_S24NE4MSBP:\n      return AV_SAMPLE_FMT_S32P;\n    case AEDataFormat::AE_FMT_S24NE3P:\n      return AV_SAMPLE_FMT_S32P;\n    case AEDataFormat::AE_FMT_FLOATP:\n      return AV_SAMPLE_FMT_FLTP;\n    case AEDataFormat::AE_FMT_DOUBLEP:\n      return AV_SAMPLE_FMT_DBLP;\n    case AEDataFormat::AE_FMT_RAW:\n      return AV_SAMPLE_FMT_U8;\n    default:\n    {\n      if (AE_IS_PLANAR(format))\n        return AV_SAMPLE_FMT_FLTP;\n      else\n        return AV_SAMPLE_FMT_FLT;\n    }\n  }\n}\n\nuint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel)\n{\n  switch (aechannel)\n  {\n  case AE_CH_FL:   return AV_CH_FRONT_LEFT;\n  case AE_CH_FR:   return AV_CH_FRONT_RIGHT;\n  case AE_CH_FC:   return AV_CH_FRONT_CENTER;\n  case AE_CH_LFE:  return AV_CH_LOW_FREQUENCY;\n  case AE_CH_BL:   return AV_CH_BACK_LEFT;\n  case AE_CH_BR:   return AV_CH_BACK_RIGHT;\n  case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER;\n  case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER;\n  case AE_CH_BC:   return AV_CH_BACK_CENTER;\n  case AE_CH_SL:   return AV_CH_SIDE_LEFT;\n  case AE_CH_SR:   return AV_CH_SIDE_RIGHT;\n  case AE_CH_TC:   return AV_CH_TOP_CENTER;\n  case AE_CH_TFL:  return AV_CH_TOP_FRONT_LEFT;\n  case AE_CH_TFC:  return AV_CH_TOP_FRONT_CENTER;\n  case AE_CH_TFR:  return AV_CH_TOP_FRONT_RIGHT;\n  case AE_CH_TBL:  return AV_CH_TOP_BACK_LEFT;\n  case AE_CH_TBC:  return AV_CH_TOP_BACK_CENTER;\n  case AE_CH_TBR:  return AV_CH_TOP_BACK_RIGHT;\n  default:\n    return 0;\n  }\n}\n\nint CAEUtil::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout)\n{\n  return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel));\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AEUtil.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"AEAudioFormat.h\"\n#include <math.h>\n\nextern \"C\" {\n#include \"libavutil/samplefmt.h\"\n}\n\n#ifdef TARGET_WINDOWS\n#if _M_IX86_FP>0 && !defined(HAVE_SSE)\n#define HAVE_SSE\n#if _M_IX86_FP>1 && !defined(HAVE_SSE2)\n#define HAVE_SSE2\n#endif\n#endif\n#endif\n\n#if defined(HAVE_SSE) && defined(__SSE__)\n#include <xmmintrin.h>\n#else\n#define __m128 void\n#endif\n\n#if defined(HAVE_SSE2) && defined(__SSE2__)\n#include <emmintrin.h>\n#endif\n\n#ifdef __GNUC__\n  #define MEMALIGN(b, x) x __attribute__((aligned(b)))\n#else\n  #define MEMALIGN(b, x) __declspec(align(b)) x\n#endif\n\nNS_KRMOVIE_BEGIN\n// AV sync options\nenum AVSync\n{\n  SYNC_DISCON = 0,\n  SYNC_RESAMPLE\n};\n\nstruct AEDelayStatus\n{\n  AEDelayStatus()\n  : delay(0.0)\n  , maxcorrection(0.0)\n  , tick(0)\n  {}\n\n  void   SetDelay(double d);\n  double GetDelay();\n\n  double delay;  // delay in sink currently\n  double maxcorrection; // time correction must not be greater than sink delay\n  int64_t tick;  // timestamp when delay was calculated\n};\n\n/**\n * @brief lockless consistency guaranteeer\n *\n * Requires write to be a higher priority thread\n *\n * use in writer:\n *   m_locker.enter();\n *   update_stuff();\n *   m_locker.leave();\n *\n * use in reader:\n *   CAESpinLock lock(m_locker);\n *   do {\n *     get_stuff();\n *   } while(lock.retry());\n */\n\nclass CAESpinSection\n{\npublic:\n  CAESpinSection()\n  : m_enter(0)\n  , m_leave(0)\n  {}\n\n  void enter() { m_enter++; }\n  void leave() { m_leave = m_enter; }\n\nprotected:\n  friend class CAESpinLock;\n  volatile unsigned int m_enter;\n  volatile unsigned int m_leave;\n};\n\nclass CAESpinLock\n{\npublic:\n  CAESpinLock(CAESpinSection& section)\n  : m_section(section)\n  , m_begin(section.m_enter)\n  {}\n\n  bool retry()\n  {\n    if(m_section.m_enter != m_begin\n    || m_section.m_enter != m_section.m_leave)\n    {\n      m_begin = m_section.m_enter;\n      return true;\n    }\n    else\n      return false;\n  }\n\nprivate:\n  CAESpinSection& m_section;\n  unsigned int    m_begin;\n};\n\nclass CAEUtil\n{\nprivate:\n  static unsigned int m_seed;\n  #if defined(HAVE_SSE2) && defined(__SSE2__)\n    static __m128i m_sseSeed;\n  #endif\n\n  static float SoftClamp(const float x);\n\npublic:\n//  static CAEChannelInfo          GuessChLayout     (const unsigned int channels);\n  static const char*             GetStdChLayoutName(const enum AEStdChLayout layout);\n  static const unsigned int      DataFormatToBits  (const enum AEDataFormat dataFormat);\n  static const unsigned int      DataFormatToUsedBits (const enum AEDataFormat dataFormat);\n  static const unsigned int      DataFormatToDitherBits(const enum AEDataFormat dataFormat);\n  static const char*             DataFormatToStr   (const enum AEDataFormat dataFormat);\n  static const char* StreamTypeToStr(const enum CAEStreamInfo::DataType dataType);\n\n  /*! \\brief convert a volume percentage (as a proportion) to a dB gain\n   We assume a dB range of 60dB, i.e. assume that 0% volume corresponds\n   to a reduction of 60dB.\n   \\param value the volume from 0..1\n   \\return the corresponding gain in dB from -60dB .. 0dB.\n   \\sa GainToScale\n   */\n  static inline const float PercentToGain(const float value)\n  {\n    static const float db_range = 60.0f;\n    return (value - 1)*db_range;\n  }\n\n  /*! \\brief convert a dB gain to volume percentage (as a proportion)\n   We assume a dB range of 60dB, i.e. assume that 0% volume corresponds\n   to a reduction of 60dB.\n   \\param the corresponding gain in dB from -60dB .. 0dB.\n   \\return value the volume from 0..1\n   \\sa ScaleToGain\n   */\n  static inline const float GainToPercent(const float gain)\n  {\n    static const float db_range = 60.0f;\n    return 1+(gain/db_range);\n  }\n\n  /*! \\brief convert a dB gain to a scale factor for audio manipulation\n   Inverts gain = 20 log_10(scale)\n   \\param dB the gain in decibels.\n   \\return the scale factor (equivalent to a voltage multiplier).\n   \\sa PercentToGain\n   */\n  static inline const float GainToScale(const float dB)\n  {\n    float val = 0.0f; \n    // we need to make sure that our lowest db returns plain zero\n    if (dB > -60.0f) \n      val = pow(10.0f, dB/20); \n\n    // in order to not introduce computing overhead for nearly zero\n    // values of dB e.g. -0.01 or -0.001 we clamp to top\n    if (val >= 0.99f)\n      val = 1.0f;\n\n    return val;\n  }\n\n  /*! \\brief convert a scale factor to dB gain for audio manipulation\n   Inverts GainToScale result\n   \\param the scale factor (equivalent to a voltage multiplier).\n   \\return dB the gain in decibels.\n   \\sa GainToScale\n   */\n  static inline const float ScaleToGain(const float scale)\n  {\n    return 20*log10(scale);\n  }\n\n  #if defined(HAVE_SSE) && defined(__SSE__)\n  static void SSEMulArray     (float *data, const float mul, uint32_t count);\n  static void SSEMulAddArray  (float *data, float *add, const float mul, uint32_t count);\n  #endif\n  static void ClampArray(float *data, uint32_t count);\n\n  /*\n    Rand implementations based on:\n    http://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/\n    This is NOT safe for crypto work, but perfectly fine for audio usage (dithering)\n  */\n  static float FloatRand1(const float min, const float max);\n  static void  FloatRand4(const float min, const float max, float result[4], __m128 *sseresult = NULL);\n\n  static bool S16NeedsByteSwap(AEDataFormat in, AEDataFormat out);\n\n  static uint64_t GetAVChannelLayout(const CAEChannelInfo &info);\n  static CAEChannelInfo GetAEChannelLayout(uint64_t layout);\n  static AVSampleFormat GetAVSampleFormat(AEDataFormat format);\n  static uint64_t GetAVChannel(enum AEChannel aechannel);\n  static int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout);\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioCodec.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n  #include \"config.h\"\n#endif\n#include <vector>\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n#include \"AEAudioFormat.h\"\n#include \"ProcessInfo.h\"\n\nNS_KRMOVIE_BEGIN\nstruct AVStream;\n\nstruct CDVDStreamInfo;\nclass CDVDCodecOption;\nclass CDVDCodecOptions;\n\ntypedef struct stDVDAudioFrame\n{\n  uint8_t* data[16];\n  double pts;\n  bool hasTimestamp;\n  double duration;\n  unsigned int nb_frames;\n  unsigned int framesize;\n  unsigned int planes;\n\n  AEAudioFormat format;\n  int bits_per_sample;\n  bool passthrough;\n  AEAudioFormat audioFormat;\n  enum AVAudioServiceType audio_service_type;\n  enum AVMatrixEncoding matrix_encoding;\n  int               profile;\n} DVDAudioFrame;\n\nclass CDVDAudioCodec\n{\npublic:\n\n  CDVDAudioCodec(CProcessInfo &processInfo) : m_processInfo(processInfo) {}\n  virtual ~CDVDAudioCodec() {}\n\n  /*\n   * Open the decoder, returns true on success\n   */\n  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) = 0;\n\n  /*\n   * Dispose, Free all resources\n   */\n  virtual void Dispose() = 0;\n\n  /*\n   * returns bytes used or -1 on error\n   *\n   */\n  virtual int Decode(uint8_t* pData, int iSize, double dts, double pts) = 0;\n\n  /*\n   * returns nr of bytes in decode buffer\n   * the data is valid until the next Decode call\n   */\n  virtual int GetData(uint8_t** dst) = 0;\n\n  /*\n   * the data is valid until the next Decode call\n   */\n  virtual void GetData(DVDAudioFrame &frame) = 0;\n\n  /*\n   * resets the decoder\n   */\n  virtual void Reset() = 0;\n\n  /*\n   * returns the format for the audio stream\n   */\n  virtual AEAudioFormat GetFormat() = 0;\n\n  /*\n   * should return the average input bit rate\n   */\n  virtual int GetBitRate() { return 0; }\n\n  /*\n   * returns if the codec requests to use passtrough\n   */\n  virtual bool NeedPassthrough() { return false; }\n\n  /*\n   * should return codecs name\n   */\n  virtual const char* GetName() = 0;\n\n  /*\n   * should return amount of data decoded has buffered in preparation for next audio frame\n   */\n  virtual int GetBufferSize() { return 0; }\n\n  /*\n   * should return the ffmpeg matrix encoding type\n   */\n  virtual enum AVMatrixEncoding GetMatrixEncoding() { return AV_MATRIX_ENCODING_NONE; }\n\n  /*\n   * should return the ffmpeg audio service type\n   */\n  virtual enum AVAudioServiceType GetAudioServiceType() { return AV_AUDIO_SERVICE_TYPE_MAIN; }\n\n  /*\n   * should return the ffmpeg profile value\n   */\n  virtual int GetProfile() { return 0; }\n\nprotected:\n  CProcessInfo &m_processInfo;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioCodecFFmpeg.cpp",
    "content": "#include \"AudioCodecFFmpeg.h\"\n#ifdef TARGET_POSIX\n#include \"XMemUtils.h\"\n#endif\n#include \"StreamInfo.h\"\n#include \"Codecs.h\"\nextern \"C\" {\n#include \"libavutil/opt.h\"\n}\n\n#if defined(TARGET_DARWIN)\n#include \"cores/AudioEngine/Utils/AEUtil.h\"\n#endif\n#include \"Clock.h\"\n#include \"AEUtil.h\"\n#include \"AEAudioFormat.h\"\n\nNS_KRMOVIE_BEGIN\nCDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg(CProcessInfo &processInfo) : CDVDAudioCodec(processInfo)\n{\n  m_pCodecContext = NULL;\n\n  m_channels = 0;\n  m_layout = 0;\n  \n  m_pFrame1 = NULL;\n  m_iSampleFormat = AV_SAMPLE_FMT_NONE;\n  m_gotFrame = 0;\n}\n\nCDVDAudioCodecFFmpeg::~CDVDAudioCodecFFmpeg()\n{\n  Dispose();\n}\n\nbool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)\n{\n  AVCodec* pCodec = NULL;\n  bool allowdtshddecode = true;\n\n  // set any special options\n  for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it)\n    if (it->m_name == \"allowdtshddecode\")\n      allowdtshddecode = atoi(it->m_value.c_str());\n\n  if (hints.codec == AV_CODEC_ID_DTS && allowdtshddecode)\n    pCodec = avcodec_find_decoder_by_name(\"dcadec\");\n\n  if (!pCodec)\n    pCodec = avcodec_find_decoder(hints.codec);\n\n  if (!pCodec)\n  {\n//    CLog::Log(LOGDEBUG,\"CDVDAudioCodecFFmpeg::Open() Unable to find codec %d\", hints.codec);\n    return false;\n  }\n\n  m_pCodecContext = avcodec_alloc_context3(pCodec);\n  if (!m_pCodecContext)\n    return false;\n\n  m_pCodecContext->debug_mv = 0;\n  m_pCodecContext->debug = 0;\n  m_pCodecContext->workaround_bugs = 1;\n\n  if (pCodec->capabilities & CODEC_CAP_TRUNCATED)\n    m_pCodecContext->flags |= CODEC_FLAG_TRUNCATED;\n\n  m_matrixEncoding = AV_MATRIX_ENCODING_NONE;\n  m_channels = 0;\n  m_pCodecContext->channels = hints.channels;\n  m_pCodecContext->sample_rate = hints.samplerate;\n  m_pCodecContext->block_align = hints.blockalign;\n  m_pCodecContext->bit_rate = hints.bitrate;\n  m_pCodecContext->bits_per_coded_sample = hints.bitspersample;\n\n  if(m_pCodecContext->bits_per_coded_sample == 0)\n    m_pCodecContext->bits_per_coded_sample = 16;\n\n  if( hints.extradata && hints.extrasize > 0 )\n  {\n    m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);\n    if(m_pCodecContext->extradata)\n    {\n      m_pCodecContext->extradata_size = hints.extrasize;\n      memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);\n    }\n  }\n\n//   if (g_advancedSettings.m_audioApplyDrc >= 0.0)\n//     av_opt_set_double(m_pCodecContext, \"drc_scale\", g_advancedSettings.m_audioApplyDrc, AV_OPT_SEARCH_CHILDREN);\n\n  if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)\n  {\n//    CLog::Log(LOGDEBUG,\"CDVDAudioCodecFFmpeg::Open() Unable to open codec\");\n    Dispose();\n    return false;\n  }\n\n  m_pFrame1 = av_frame_alloc();\n  if (!m_pFrame1)\n  {\n    Dispose();\n    return false;\n  }\n\n  m_iSampleFormat = AV_SAMPLE_FMT_NONE;\n  m_matrixEncoding = AV_MATRIX_ENCODING_NONE;\n\n  m_processInfo.SetAudioDecoderName(m_pCodecContext->codec->name);\n  return true;\n}\n\nvoid CDVDAudioCodecFFmpeg::Dispose()\n{\n  av_frame_free(&m_pFrame1);\n  avcodec_free_context(&m_pCodecContext);\n}\n\nint CDVDAudioCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double pts)\n{\n  int iBytesUsed;\n  if (!m_pCodecContext)\n    return -1;\n\n  AVPacket avpkt;\n  av_init_packet(&avpkt);\n  avpkt.data = pData;\n  avpkt.size = iSize;\n  avpkt.dts = (dts == DVD_NOPTS_VALUE) ? AV_NOPTS_VALUE : dts / DVD_TIME_BASE * AV_TIME_BASE;\n  avpkt.pts = (pts == DVD_NOPTS_VALUE) ? AV_NOPTS_VALUE : pts / DVD_TIME_BASE * AV_TIME_BASE;\n  iBytesUsed = avcodec_decode_audio4( m_pCodecContext\n                                                 , m_pFrame1\n                                                 , &m_gotFrame\n                                                 , &avpkt);\n  if (iBytesUsed < 0 || !m_gotFrame)\n  {\n    return iBytesUsed;\n  } else if (m_pFrame1->channels == 0) { // fix channels issue\n\t  m_pFrame1->channels = av_frame_get_channels(m_pFrame1);\n  }\n\n  /* some codecs will attempt to consume more data than what we gave */\n  if (iBytesUsed > iSize)\n  {\n//    CLog::Log(LOGWARNING, \"CDVDAudioCodecFFmpeg::Decode - decoder attempted to consume more data than given\");\n    iBytesUsed = iSize;\n  }\n\n  if (m_pFrame1->nb_side_data)\n  {\n    for (int i = 0; i < m_pFrame1->nb_side_data; i++)\n    {\n      AVFrameSideData *sd = m_pFrame1->side_data[i];\n      if (sd->data)\n      {\n        if (sd->type == AV_FRAME_DATA_MATRIXENCODING)\n        {\n          m_matrixEncoding = *(enum AVMatrixEncoding*)sd->data;\n        }\n      }\n    }\n  }\n\n  m_format.m_dataFormat = GetDataFormat();\n  m_format.m_channelLayout = GetChannelMap();\n  m_format.m_sampleRate = GetSampleRate();\n  m_format.m_frameSize = m_format.m_channelLayout.Count() * CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3;\n  return iBytesUsed;\n}\n\nvoid CDVDAudioCodecFFmpeg::GetData(DVDAudioFrame &frame)\n{\n  frame.passthrough = false;\n  frame.nb_frames = 0;\n  frame.format.m_dataFormat = m_format.m_dataFormat;\n  frame.format.m_channelLayout = m_format.m_channelLayout;\n  frame.framesize = (CAEUtil::DataFormatToBits(frame.format.m_dataFormat) >> 3) * frame.format.m_channelLayout.Count();\n  if(frame.framesize == 0)\n    return;\n  frame.nb_frames = GetData(frame.data)/frame.framesize;\n  frame.planes = AE_IS_PLANAR(frame.format.m_dataFormat) ? frame.format.m_channelLayout.Count() : 1;\n  frame.bits_per_sample = CAEUtil::DataFormatToBits(frame.format.m_dataFormat);\n  frame.format.m_sampleRate = m_format.m_sampleRate;\n  frame.matrix_encoding = GetMatrixEncoding();\n  frame.audio_service_type = GetAudioServiceType();\n  frame.profile = GetProfile();\n  // compute duration.\n  if (frame.format.m_sampleRate)\n    frame.duration = ((double)frame.nb_frames * DVD_TIME_BASE) / frame.format.m_sampleRate;\n  else\n    frame.duration = 0.0;\n\n  int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame1);\n  if(bpts != AV_NOPTS_VALUE)\n    frame.pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;\n  else\n    frame.pts = DVD_NOPTS_VALUE;\n}\n\nint CDVDAudioCodecFFmpeg::GetData(uint8_t** dst)\n{\n  if(m_gotFrame)\n  {\n    int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? m_pFrame1->channels : 1;\n    for (int i=0; i<planes; i++)\n      dst[i] = m_pFrame1->extended_data[i];\n    m_gotFrame = 0;\n    return m_pFrame1->nb_samples * m_pFrame1->channels * av_get_bytes_per_sample(m_pCodecContext->sample_fmt);\n  }\n\n  return 0;\n}\n\nvoid CDVDAudioCodecFFmpeg::Reset()\n{\n  if (m_pCodecContext) avcodec_flush_buffers(m_pCodecContext);\n  m_gotFrame = 0;\n}\n\nint CDVDAudioCodecFFmpeg::GetChannels()\n{\n  return m_pCodecContext->channels;\n}\n\nint CDVDAudioCodecFFmpeg::GetSampleRate()\n{\n  if (m_pCodecContext)\n    return m_pCodecContext->sample_rate;\n  return 0;\n}\n\nenum AEDataFormat CDVDAudioCodecFFmpeg::GetDataFormat()\n{\n  switch(m_pCodecContext->sample_fmt)\n  {\n    case AV_SAMPLE_FMT_U8 : return AE_FMT_U8;\n    case AV_SAMPLE_FMT_U8P : return AE_FMT_U8P;\n    case AV_SAMPLE_FMT_S16: return AE_FMT_S16NE;\n    case AV_SAMPLE_FMT_S16P: return AE_FMT_S16NEP;\n    case AV_SAMPLE_FMT_S32: return AE_FMT_S32NE;\n    case AV_SAMPLE_FMT_S32P: return AE_FMT_S32NEP;\n    case AV_SAMPLE_FMT_FLT: return AE_FMT_FLOAT;\n    case AV_SAMPLE_FMT_FLTP: return AE_FMT_FLOATP;\n    case AV_SAMPLE_FMT_DBL: return AE_FMT_DOUBLE;\n    case AV_SAMPLE_FMT_DBLP: return AE_FMT_DOUBLEP;\n    case AV_SAMPLE_FMT_NONE:\n    default:\n//      CLog::Log(LOGERROR, \"CDVDAudioCodecFFmpeg::GetDataFormat - invalid data format\");\n      return AE_FMT_INVALID;\n  }\n}\n\nint CDVDAudioCodecFFmpeg::GetBitRate()\n{\n  if (m_pCodecContext)\n    return m_pCodecContext->bit_rate;\n  return 0;\n}\n\nenum AVMatrixEncoding CDVDAudioCodecFFmpeg::GetMatrixEncoding()\n{\n  return m_matrixEncoding;\n}\n\nenum AVAudioServiceType CDVDAudioCodecFFmpeg::GetAudioServiceType()\n{\n  if (m_pCodecContext)\n    return m_pCodecContext->audio_service_type;\n  return AV_AUDIO_SERVICE_TYPE_MAIN;\n}\n\nint CDVDAudioCodecFFmpeg::GetProfile()\n{\n  if (m_pCodecContext)\n    return m_pCodecContext->profile;\n  return 0;\n}\n\nstatic unsigned count_bits(int64_t value)\n{\n  unsigned bits = 0;\n  for(;value;++bits)\n    value &= value - 1;\n  return bits;\n}\n\nvoid CDVDAudioCodecFFmpeg::BuildChannelMap()\n{\n  if (m_channels == m_pCodecContext->channels && m_layout == m_pCodecContext->channel_layout)\n    return; //nothing to do here\n\n  m_channels = m_pCodecContext->channels;\n  m_layout   = m_pCodecContext->channel_layout;\n\n  int64_t layout;\n\n  int bits = count_bits(m_pCodecContext->channel_layout);\n  if (bits == m_pCodecContext->channels)\n    layout = m_pCodecContext->channel_layout;\n  else\n  {\n//    CLog::Log(LOGINFO, \"CDVDAudioCodecFFmpeg::GetChannelMap - FFmpeg reported %d channels, but the layout contains %d ignoring\", m_pCodecContext->channels, bits);\n    layout = av_get_default_channel_layout(m_pCodecContext->channels);\n  }\n\n  m_channelLayout.Reset();\n\n  if (layout & AV_CH_FRONT_LEFT           ) m_channelLayout += AE_CH_FL  ;\n  if (layout & AV_CH_FRONT_RIGHT          ) m_channelLayout += AE_CH_FR  ;\n  if (layout & AV_CH_FRONT_CENTER         ) m_channelLayout += AE_CH_FC  ;\n  if (layout & AV_CH_LOW_FREQUENCY        ) m_channelLayout += AE_CH_LFE ;\n  if (layout & AV_CH_BACK_LEFT            ) m_channelLayout += AE_CH_BL  ;\n  if (layout & AV_CH_BACK_RIGHT           ) m_channelLayout += AE_CH_BR  ;\n  if (layout & AV_CH_FRONT_LEFT_OF_CENTER ) m_channelLayout += AE_CH_FLOC;\n  if (layout & AV_CH_FRONT_RIGHT_OF_CENTER) m_channelLayout += AE_CH_FROC;\n  if (layout & AV_CH_BACK_CENTER          ) m_channelLayout += AE_CH_BC  ;\n  if (layout & AV_CH_SIDE_LEFT            ) m_channelLayout += AE_CH_SL  ;\n  if (layout & AV_CH_SIDE_RIGHT           ) m_channelLayout += AE_CH_SR  ;\n  if (layout & AV_CH_TOP_CENTER           ) m_channelLayout += AE_CH_TC  ;\n  if (layout & AV_CH_TOP_FRONT_LEFT       ) m_channelLayout += AE_CH_TFL ;\n  if (layout & AV_CH_TOP_FRONT_CENTER     ) m_channelLayout += AE_CH_TFC ;\n  if (layout & AV_CH_TOP_FRONT_RIGHT      ) m_channelLayout += AE_CH_TFR ;\n  if (layout & AV_CH_TOP_BACK_LEFT        ) m_channelLayout += AE_CH_BL  ;\n  if (layout & AV_CH_TOP_BACK_CENTER      ) m_channelLayout += AE_CH_BC  ;\n  if (layout & AV_CH_TOP_BACK_RIGHT       ) m_channelLayout += AE_CH_BR  ;\n\n  m_channels = m_pCodecContext->channels;\n}\n\nCAEChannelInfo CDVDAudioCodecFFmpeg::GetChannelMap()\n{\n  BuildChannelMap();\n  return m_channelLayout;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioCodecFFmpeg.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"AudioCodec.h\"\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n#include \"libavformat/avformat.h\"\n#include \"libavutil/avutil.h\"\n#include \"libswresample/swresample.h\"\n}\n\nNS_KRMOVIE_BEGIN\nclass CProcessInfo;\n\nclass CDVDAudioCodecFFmpeg : public CDVDAudioCodec\n{\npublic:\n  CDVDAudioCodecFFmpeg(CProcessInfo &processInfo);\n  virtual ~CDVDAudioCodecFFmpeg();\n  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);\n  virtual void Dispose();\n  virtual int Decode(uint8_t* pData, int iSize, double dts, double pts);\n  virtual void GetData(DVDAudioFrame &frame);\n  virtual int GetData(uint8_t** dst);\n  virtual void Reset();\n  virtual AEAudioFormat GetFormat() { return m_format; }\n  virtual const char* GetName() { return \"FFmpeg\"; }\n  virtual enum AVMatrixEncoding GetMatrixEncoding();\n  virtual enum AVAudioServiceType GetAudioServiceType();\n  virtual int GetProfile();\n\nprotected:\n  enum AEDataFormat GetDataFormat();\n  int GetSampleRate();\n  int GetChannels();\n  CAEChannelInfo GetChannelMap();\n  int GetBitRate();\n\n  AEAudioFormat m_format;\n  AVCodecContext* m_pCodecContext;\n  enum AVSampleFormat m_iSampleFormat;\n  CAEChannelInfo m_channelLayout;\n  enum AVMatrixEncoding m_matrixEncoding;\n\n  AVFrame* m_pFrame1;\n  int m_gotFrame;\n\n  int m_channels;\n  uint64_t m_layout;\n\n  void BuildChannelMap();\n  void ConvertToFloat();\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioCodecPassthrough.cpp",
    "content": "#include \"AudioCodecPassthrough.h\"\n#include \"Codecs.h\"\n#include \"StreamInfo.h\"\n#include <algorithm>\n#include \"AEFactory.h\"\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n\n#include \"ProcessInfo.h\"\n#include \"Clock.h\"\nNS_KRMOVIE_BEGIN\n\n#define TRUEHD_BUF_SIZE 61440\n\nCDVDAudioCodecPassthrough::CDVDAudioCodecPassthrough(CProcessInfo &processInfo) :\n  CDVDAudioCodec(processInfo),\n  m_buffer(NULL),\n  m_bufferSize(0),\n  m_trueHDoffset(0)\n{\n}\n\nCDVDAudioCodecPassthrough::~CDVDAudioCodecPassthrough(void)\n{\n  Dispose();\n}\n\nbool CDVDAudioCodecPassthrough::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)\n{\n  AEAudioFormat format;\n  format.m_dataFormat = AE_FMT_RAW;\n  format.m_sampleRate = hints.samplerate;\n  switch (hints.codec)\n  {\n    case AV_CODEC_ID_AC3:\n      format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_AC3;\n      format.m_streamInfo.m_sampleRate = hints.samplerate;\n      m_processInfo.SetAudioDecoderName(\"PT_AC3\");\n      break;\n\n    case AV_CODEC_ID_EAC3:\n      format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_EAC3;\n      format.m_streamInfo.m_sampleRate = hints.samplerate;\n      m_processInfo.SetAudioDecoderName(\"PT_EAC3\");\n      break;\n\n    case AV_CODEC_ID_DTS:\n      format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD;\n      format.m_streamInfo.m_sampleRate = hints.samplerate;\n      m_processInfo.SetAudioDecoderName(\"PT_DTSHD\");\n      break;\n\n    case AV_CODEC_ID_TRUEHD:\n      format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_TRUEHD;\n      format.m_streamInfo.m_sampleRate = hints.samplerate;\n      m_trueHDBuffer.reset(new uint8_t[TRUEHD_BUF_SIZE]);\n      m_processInfo.SetAudioDecoderName(\"PT_TRUEHD\");\n      break;\n\n    default:\n      format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_NULL;\n  }\n\n  bool ret = CAEFactory::SupportsRaw(format);\n\n  m_parser.SetCoreOnly(false);\n  if (!ret && hints.codec == AV_CODEC_ID_DTS)\n  {\n    format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE;\n    ret = CAEFactory::SupportsRaw(format);\n\n    // only get the dts core from the parser if we don't support dtsHD\n    m_parser.SetCoreOnly(true);\n\n    m_processInfo.SetAudioDecoderName(\"PT_DTS\");\n  }\n\n  m_dataSize = 0;\n  m_bufferSize = 0;\n  m_backlogSize = 0;\n  m_currentPts = DVD_NOPTS_VALUE;\n  m_nextPts = DVD_NOPTS_VALUE;\n  return ret;\n}\n\nvoid CDVDAudioCodecPassthrough::Dispose()\n{\n  if (m_buffer)\n  {\n    delete[] m_buffer;\n    m_buffer = NULL;\n  }\n\n  m_bufferSize = 0;\n}\n\nint CDVDAudioCodecPassthrough::Decode(uint8_t* pData, int iSize, double dts, double pts)\n{\n  int used = 0;\n  int skip = 0;\n  if (m_backlogSize)\n  {\n    m_dataSize = m_bufferSize;\n    unsigned int consumed = m_parser.AddData(m_backlogBuffer, m_backlogSize, &m_buffer, &m_dataSize);\n    m_bufferSize = std::max(m_bufferSize, m_dataSize);\n    if (consumed != m_backlogSize)\n    {\n      memmove(m_backlogBuffer, m_backlogBuffer+consumed, m_backlogSize-consumed);\n    }\n    m_backlogSize -= consumed;\n  }\n\n  // get rid of potential side data\n  if (pData)\n  {\n    AVPacket pkt;\n    av_init_packet(&pkt);\n    pkt.data = pData;\n    pkt.size = iSize;\n    int didSplit = av_packet_split_side_data(&pkt);\n    if (didSplit)\n    {\n      skip = iSize - pkt.size;\n      pData = pkt.data;\n      iSize = pkt.size;\n      av_packet_free_side_data(&pkt);\n    }\n  }\n\n  if (pData)\n  {\n    if (m_currentPts == DVD_NOPTS_VALUE)\n    {\n      if (m_nextPts != DVD_NOPTS_VALUE)\n      {\n        m_currentPts = m_nextPts;\n        m_nextPts = DVD_NOPTS_VALUE;\n      }\n      else if (pts != DVD_NOPTS_VALUE)\n      {\n        m_currentPts = pts;\n      }\n    }\n\n    m_nextPts = pts;\n  }\n\n  if (pData && !m_backlogSize)\n  {\n    if (iSize <= 0)\n      return used + skip;\n\n    m_dataSize = m_bufferSize;\n    used = m_parser.AddData(pData, iSize, &m_buffer, &m_dataSize);\n    m_bufferSize = std::max(m_bufferSize, m_dataSize);\n\n    if (used != iSize)\n    {\n      m_backlogSize = iSize - used;\n      memcpy(m_backlogBuffer, pData + used, m_backlogSize);\n      used = iSize;\n    }\n  }\n  else if (pData)\n  {\n    memcpy(m_backlogBuffer + m_backlogSize, pData, iSize);\n    m_backlogSize += iSize;\n    used = iSize;\n  }\n\n  if (!m_dataSize)\n    return used + skip;\n\n  if (m_dataSize)\n  {\n    m_format.m_dataFormat = AE_FMT_RAW;\n    m_format.m_streamInfo = m_parser.GetStreamInfo();\n    m_format.m_sampleRate = m_parser.GetSampleRate();\n    m_format.m_frameSize = 1;\n    CAEChannelInfo layout;\n    for (unsigned int i=0; i<m_parser.GetChannels(); i++)\n    {\n      layout += AE_CH_RAW;\n    }\n    m_format.m_channelLayout = layout;\n  }\n\n  if (m_format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD)\n  {\n    if (!m_trueHDoffset)\n      memset(m_trueHDBuffer.get(), 0, TRUEHD_BUF_SIZE);\n\n    memcpy(&(m_trueHDBuffer.get())[m_trueHDoffset], m_buffer, m_dataSize);\n    uint8_t highByte = (m_dataSize >> 8) & 0xFF;\n    uint8_t lowByte = m_dataSize & 0xFF;\n    m_trueHDBuffer[m_trueHDoffset+2560-2] = highByte;\n    m_trueHDBuffer[m_trueHDoffset+2560-1] = lowByte;\n    m_trueHDoffset += 2560;\n\n    if (m_trueHDoffset / 2560 == 24)\n    {\n      m_dataSize = m_trueHDoffset;\n      m_trueHDoffset = 0;\n    }\n    else\n      m_dataSize = 0;\n  }\n\n  return used + skip;\n}\n\nvoid CDVDAudioCodecPassthrough::GetData(DVDAudioFrame &frame)\n{\n  frame.nb_frames = GetData(frame.data);\n\n  if (frame.nb_frames == 0)\n    return;\n\n  frame.passthrough = true;\n  frame.format = m_format;\n  frame.planes = 1;\n  frame.bits_per_sample = 8;\n  frame.duration = DVD_MSEC_TO_TIME(frame.format.m_streamInfo.GetDuration());\n  frame.pts = m_currentPts;\n  m_currentPts = DVD_NOPTS_VALUE;\n  m_dataSize = 0;\n}\n\nint CDVDAudioCodecPassthrough::GetData(uint8_t** dst)\n{\n  if (m_format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD)\n    *dst = m_trueHDBuffer.get();\n  else\n    *dst = m_buffer;\n  return m_dataSize;\n}\n\nvoid CDVDAudioCodecPassthrough::Reset()\n{\n  m_trueHDoffset = 0;\n  m_dataSize = 0;\n  m_bufferSize = 0;\n  m_backlogSize = 0;\n  m_currentPts = DVD_NOPTS_VALUE;\n  m_nextPts = DVD_NOPTS_VALUE;\n  m_parser.Reset();\n}\n\nint CDVDAudioCodecPassthrough::GetBufferSize()\n{\n  return (int)m_parser.GetBufferSize();\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioCodecPassthrough.h",
    "content": "#pragma once\n#include \"AudioCodec.h\"\n#include \"AEAudioFormat.h\"\n#include \"AEStreamInfo.h\"\n#include <memory>\nNS_KRMOVIE_BEGIN\nclass CProcessInfo;\n\nclass CDVDAudioCodecPassthrough : public CDVDAudioCodec\n{\npublic:\n  CDVDAudioCodecPassthrough(CProcessInfo &processInfo);\n  virtual ~CDVDAudioCodecPassthrough();\n\n  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);\n  virtual void Dispose();\n  virtual int Decode(uint8_t* pData, int iSize, double dts, double pts);\n  virtual void GetData(DVDAudioFrame &frame);\n  virtual int GetData(uint8_t** dst);\n  virtual void Reset();\n  virtual AEAudioFormat GetFormat() { return m_format; }\n  virtual bool NeedPassthrough() { return true; }\n  virtual const char* GetName() { return \"passthrough\"; }\n  virtual int GetBufferSize();\nprivate:\n  CAEStreamParser m_parser;\n  uint8_t* m_buffer;\n  unsigned int m_bufferSize;\n  unsigned int m_dataSize;\n  AEAudioFormat m_format;\n  uint8_t m_backlogBuffer[61440];\n  unsigned int m_backlogSize;\n  double m_currentPts;\n  double m_nextPts;\n\n  // TrueHD specifics\n  std::unique_ptr<uint8_t[]> m_trueHDBuffer;\n  unsigned int m_trueHDoffset;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioDevice.cpp",
    "content": "#include \"AudioDevice.h\"\n#include \"Clock.h\"\n#include \"AudioCodec.h\"\n#include \"AEFactory.h\"\n#include \"AEAudioFormat.h\"\n#ifdef TARGET_POSIX\n#include \"linux/XTimeUtils.h\"\n#endif\n#include \"AEStreamData.h\"\n#include <thread>\nNS_KRMOVIE_BEGIN\nCDVDAudio::CDVDAudio(CDVDClock *clock) : m_pClock(clock)\n{\n  m_pAudioStream = NULL;\n  m_bPassthrough = false;\n  m_iBitsPerSample = 0;\n  m_sampeRate = 0;\n  m_bPaused = true;\n  m_playingPts = DVD_NOPTS_VALUE; //silence coverity uninitialized warning, is set elsewhere\n  m_timeOfPts = 0.0; //silence coverity uninitialized warning, is set elsewhere\n  m_syncError = 0.0;\n  m_syncErrorTime = 0;\n}\n\nCDVDAudio::~CDVDAudio()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if (m_pAudioStream)\n    CAEFactory::FreeStream(m_pAudioStream);\n}\n\nbool CDVDAudio::Create(const DVDAudioFrame &audioframe, AVCodecID codec, bool needresampler)\n{\n//   CLog::Log(LOGNOTICE,\n//     \"Creating audio stream (codec id: %i, channels: %i, sample rate: %i, %s)\",\n//     codec,\n//     audioframe.format.m_channelLayout.Count(),\n//     audioframe.format.m_sampleRate,\n//     audioframe.passthrough ? \"pass-through\" : \"no pass-through\"\n//   );\n\n  // if passthrough isset do something else\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  unsigned int options = needresampler && !audioframe.passthrough ? AESTREAM_FORCE_RESAMPLE : 0;\n  options |= AESTREAM_PAUSED;\n\n  AEAudioFormat format = audioframe.format;\n  m_pAudioStream = CAEFactory::MakeStream(\n    format,\n    options,\n    this\n  );\n  if (!m_pAudioStream)\n    return false;\n\n  m_sampeRate = audioframe.format.m_sampleRate;\n  m_iBitsPerSample = audioframe.bits_per_sample;\n  m_bPassthrough = audioframe.passthrough;\n  m_channelLayout = audioframe.format.m_channelLayout;\n\n//   if (m_pAudioStream->HasDSP())\n//     m_pAudioStream->SetFFmpegInfo(audioframe.profile, audioframe.matrix_encoding, audioframe.audio_service_type);\n\n  //SetDynamicRangeCompression((long)(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_VolumeAmplification * 100));\n\n  return true;\n}\n\nvoid CDVDAudio::Destroy()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n\n  if (m_pAudioStream)\n    CAEFactory::FreeStream(m_pAudioStream);\n\n  m_pAudioStream = NULL;\n  m_sampeRate = 0;\n  m_iBitsPerSample = 0;\n  m_bPassthrough = false;\n  m_bPaused = true;\n  m_playingPts = DVD_NOPTS_VALUE;\n}\n\nunsigned int CDVDAudio::AddPackets(const DVDAudioFrame &audioframe)\n{\n  m_bAbort = false;\n\n  std::unique_lock<std::recursive_mutex> lock(m_critSection);\n\n  if(!m_pAudioStream)\n    return 0;\n\n  CAESyncInfo info = m_pAudioStream->GetSyncInfo();\n  if (info.state == CAESyncInfo::SYNC_INSYNC)\n  {\n    unsigned int newTime = info.errortime;\n    if (newTime != m_syncErrorTime)\n    {\n      m_syncErrorTime = info.errortime;\n      m_syncError = info.error / 1000 * DVD_TIME_BASE;\n      m_resampleRatio = info.rr;\n    }\n  }\n  else\n  {\n    m_syncErrorTime = 0;\n    m_syncError = 0.0;\n  }\n\n  //Calculate a timeout when this definitely should be done\n  double timeout;\n  timeout  = DVD_SEC_TO_TIME(m_pAudioStream->GetDelay()) + audioframe.duration;\n  timeout += DVD_SEC_TO_TIME(1.0);\n  timeout += m_pClock->GetAbsoluteClock();\n\n  unsigned int total = audioframe.nb_frames;\n  unsigned int frames = audioframe.nb_frames;\n  unsigned int offset = 0;\n  do\n  {\n    double pts = (offset == 0) ? audioframe.pts / DVD_TIME_BASE * 1000 : 0.0;\n    unsigned int copied = m_pAudioStream->AddData(audioframe.data, offset, frames, pts);\n    offset += copied;\n    frames -= copied;\n    if (frames <= 0)\n      break;\n\n    if (copied == 0 && timeout < m_pClock->GetAbsoluteClock())\n    {\n  //    CLog::Log(LOGERROR, \"CDVDAudio::AddPacketsRenderer - timeout adding data to renderer\");\n      break;\n    }\n\n\tlock.unlock();\n\tstd::this_thread::sleep_for(std::chrono::milliseconds(1));\n    lock.lock();\n  } while (!m_bAbort);\n\n  m_playingPts = audioframe.pts + audioframe.duration - GetDelay();\n  m_timeOfPts = m_pClock->GetAbsoluteClock();\n\n  return total - frames;\n}\n\nvoid CDVDAudio::Drain()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if (m_pAudioStream)\n    m_pAudioStream->Drain(true);\n}\n\n// void CDVDAudio::SetVolume(float volume)\n// {\n//   CSingleLock lock (m_critSection);\n//   if (m_pAudioStream)\n//     m_pAudioStream->SetVolume(volume);\n// }\n\n// void CDVDAudio::SetDynamicRangeCompression(long drc)\n// {\n//   CSingleLock lock (m_critSection);\n//   if (m_pAudioStream)\n//     m_pAudioStream->SetAmplification(powf(10.0f, (float)drc / 2000.0f));\n//}\n\n// float CDVDAudio::GetCurrentAttenuation()\n// {\n//   CSingleLock lock (m_critSection);\n//   if (m_pAudioStream)\n//     return m_pAudioStream->GetVolume();\n//   else\n//     return 1.0f;\n// }\n\nvoid CDVDAudio::Pause()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if (m_pAudioStream)\n    m_pAudioStream->Pause();\n // CLog::Log(LOGDEBUG,\"CDVDAudio::Pause - pausing audio stream\");\n  m_playingPts = DVD_NOPTS_VALUE;\n}\n\nvoid CDVDAudio::Resume()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if (m_pAudioStream)\n    m_pAudioStream->Resume();\n // CLog::Log(LOGDEBUG,\"CDVDAudio::Resume - resume audio stream\");\n}\n\ndouble CDVDAudio::GetDelay()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n\n  double delay = 0.3;\n  if(m_pAudioStream)\n    delay = m_pAudioStream->GetDelay();\n\n  return delay * DVD_TIME_BASE;\n}\n\nvoid CDVDAudio::Flush()\n{\n  m_bAbort = true;\n\n  std::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if (m_pAudioStream)\n  {\n    m_pAudioStream->Flush();\n //   CLog::Log(LOGDEBUG,\"CDVDAudio::Flush - flush audio stream\");\n  }\n  m_playingPts = DVD_NOPTS_VALUE;\n  m_syncError = 0.0;\n  m_syncErrorTime = 0;\n}\n\nvoid CDVDAudio::AbortAddPackets()\n{\n  m_bAbort = true;\n}\n\nbool CDVDAudio::IsValidFormat(const DVDAudioFrame &audioframe)\n{\n  if(!m_pAudioStream)\n    return false;\n\n  if(audioframe.passthrough != m_bPassthrough)\n    return false;\n\n  if(m_sampeRate != audioframe.format.m_sampleRate ||\n     m_iBitsPerSample != audioframe.bits_per_sample ||\n     m_channelLayout != audioframe.format.m_channelLayout)\n    return false;\n\n  return true;\n}\n\ndouble CDVDAudio::GetCacheTime()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if(!m_pAudioStream)\n    return 0.0;\n\n  double delay = 0.0;\n  if(m_pAudioStream)\n    delay = m_pAudioStream->GetCacheTime();\n\n  return delay;\n}\n\ndouble CDVDAudio::GetCacheTotal()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if(!m_pAudioStream)\n    return 0.0;\n  return m_pAudioStream->GetCacheTotal();\n}\n\ndouble CDVDAudio::GetPlayingPts()\n{\n  if (m_playingPts == DVD_NOPTS_VALUE)\n    return 0.0;\n\n  double now = m_pClock->GetAbsoluteClock();\n  double diff = now - m_timeOfPts;\n  double cache = GetCacheTime();\n  double played = 0.0;\n\n  if (diff < cache)\n    played = diff;\n  else\n    played = cache;\n\n  m_timeOfPts = now;\n  m_playingPts += played;\n  return m_playingPts;\n}\n\ndouble CDVDAudio::GetSyncError()\n{\n  return m_syncError;\n}\n\nvoid CDVDAudio::SetSyncErrorCorrection(double correction)\n{\n  m_syncError += correction;\n}\n\ndouble CDVDAudio::GetResampleRatio()\n{\n  return m_resampleRatio;\n}\n\nvoid CDVDAudio::SetResampleMode(int mode)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_critSection);\n  if(m_pAudioStream)\n  {\n    m_pAudioStream->SetResampleMode(mode);\n  }\n}\n\ndouble CDVDAudio::GetClock()\n{\n  if (m_pClock)\n    return (m_pClock->GetClock() + m_pClock->GetVsyncAdjust()) / DVD_TIME_BASE * 1000;\n  else\n    return 0.0;\n}\n\ndouble CDVDAudio::GetClockSpeed()\n{\n  if (m_pClock)\n    return m_pClock->GetClockSpeed();\n  else\n    return 1.0;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/AudioDevice.h",
    "content": "#pragma once\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n  #include \"config.h\"\n#endif\n#include \"AEChannelInfo.h\"\n#include \"AEStream.h\"\n#include \"Thread.h\"\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n\nNS_KRMOVIE_BEGIN\n\ntypedef struct stDVDAudioFrame DVDAudioFrame;\n\nclass CDVDClock;\n\nclass CDVDAudio : IAEClockCallback\n{\npublic:\n  CDVDAudio(CDVDClock *clock);\n  ~CDVDAudio();\n\n // void SetVolume(float fVolume);\n // void SetDynamicRangeCompression(long drc);\n // float GetCurrentAttenuation();\n  void Pause();\n  void Resume();\n  bool Create(const DVDAudioFrame &audioframe, AVCodecID codec, bool needresampler);\n  bool IsValidFormat(const DVDAudioFrame &audioframe);\n  void Destroy();\n  unsigned int AddPackets(const DVDAudioFrame &audioframe);\n  double GetPlayingPts();\n  double GetCacheTime();\n  double GetCacheTotal(); // returns total amount the audio device can buffer\n  double GetDelay(); // returns the time it takes to play a packet if we add one at this time\n  double GetSyncError();\n  void SetSyncErrorCorrection(double correction);\n  double GetResampleRatio();\n  void SetResampleMode(int mode);\n  void Flush();\n  void Drain();\n  void AbortAddPackets();\n\n  double GetClock();\n  double GetClockSpeed();\n  IAEStream *m_pAudioStream;\n\nprotected:\n\n  double m_playingPts;\n  double m_timeOfPts;\n  double m_syncError;\n  unsigned int m_syncErrorTime;\n  double m_resampleRatio;\n  std::recursive_mutex m_critSection;\n\n  unsigned int m_sampeRate;\n  int m_iBitsPerSample;\n  bool m_bPassthrough;\n  CAEChannelInfo m_channelLayout;\n  bool m_bPaused;\n\n  std::atomic_bool m_bAbort;\n  CDVDClock *m_pClock;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/BaseRenderer.cpp",
    "content": "#include <cstdlib> // std::abs(int) prototype\n#include <algorithm>\n#include \"BaseRenderer.h\"\n#include \"MathUtils.h\"\n#include <string>\n\nNS_KRMOVIE_BEGIN\n\nCBaseRenderer::CBaseRenderer()\n{\n  m_sourceFrameRatio = 1.0f;\n  m_sourceWidth = 720;\n  m_sourceHeight = 480;\n  m_fps = 0.0f;\n  m_renderOrientation = 0;\n  m_oldRenderOrientation = 0;\n  m_oldDestRect.SetRect(0.0f, 0.0f, 0.0f, 0.0f);\n  m_iFlags = 0;\n\n  for(int i=0; i < 4; i++)\n  {\n    m_rotatedDestCoords[i].x = 0;\n    m_rotatedDestCoords[i].y = 0;\n    m_savedRotatedDestCoords[i].x = 0;\n    m_savedRotatedDestCoords[i].y = 0;    \n  }\n}\n\nCBaseRenderer::~CBaseRenderer()\n{\n}\n\nfloat CBaseRenderer::GetAspectRatio() const\n{\n  float width = (float)m_sourceWidth;\n  float height = (float)m_sourceHeight;\n  return m_sourceFrameRatio * width / height * m_sourceHeight / m_sourceWidth;\n}\n\nvoid CBaseRenderer::GetVideoRect(CRect &source, CRect &dest, CRect &view)\n{\n  source = m_sourceRect;\n  dest = m_destRect;\n  view = m_viewRect;\n}\n\ninline void CBaseRenderer::ReorderDrawPoints()\n{\n  // 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left\n  float origMat[4][2] = {{m_destRect.x1, m_destRect.y1},\n                         {m_destRect.x2, m_destRect.y1},\n                         {m_destRect.x2, m_destRect.y2},\n                         {m_destRect.x1, m_destRect.y2}};\n  bool changeAspect = false;\n  int pointOffset = 0;\n\n  switch (m_renderOrientation)\n  {\n    case 90:\n      pointOffset = 1;\n      changeAspect = true;\n      break;\n    case 180:\n      pointOffset = 2;\n      break;\n    case 270:\n      pointOffset = 3;\n      changeAspect = true;\n      break;\n  }\n\n  // if renderer doesn't support rotation\n  // treat orientation as 0 degree so that\n  // ffmpeg might handle it.\n//   if (!Supports(RENDERFEATURE_ROTATION))\n//   {\n//     pointOffset = 0;\n//     changeAspect = false;\n//   }\n\n\n  int diffX = 0;\n  int diffY = 0;\n  int centerX = 0;\n  int centerY = 0;\n  \n  if (changeAspect)// we are either rotating by 90 or 270 degrees which inverts aspect ratio\n  {\n    int newWidth = m_destRect.Height(); // new width is old height\n    int newHeight = m_destRect.Width(); // new height is old width\n    int diffWidth = newWidth - m_destRect.Width(); // difference between old and new width\n    int diffHeight = newHeight - m_destRect.Height(); // difference between old and new height\n\n    // if the new width is bigger then the old or\n    // the new height is bigger then the old - we need to scale down\n    if (diffWidth > 0 || diffHeight > 0 )\n    {\n      float aspectRatio = GetAspectRatio();\n      // scale to fit screen width because\n      // the difference in width is bigger then the\n      // difference in height\n      if (diffWidth > diffHeight)\n      {\n        newWidth = m_destRect.Width(); // clamp to the width of the old dest rect\n        newHeight *= aspectRatio;\n      }\n      else // scale to fit screen height\n      {\n        newHeight = m_destRect.Height(); // clamp to the height of the old dest rect\n        newWidth /= aspectRatio;\n      }\n    }\n    \n    // calculate the center point of the view\n    centerX = m_viewRect.x1 + m_viewRect.Width() / 2;\n    centerY = m_viewRect.y1 + m_viewRect.Height() / 2;\n\n    // calculate the number of pixels we need to go in each\n    // x direction from the center point\n    diffX = newWidth / 2;\n    // calculate the number of pixels we need to go in each\n    // y direction from the center point\n    diffY = newHeight / 2;\n    \n  }\n\n  for (int destIdx=0, srcIdx=pointOffset; destIdx < 4; destIdx++)\n  {\n    m_rotatedDestCoords[destIdx].x = origMat[srcIdx][0];\n    m_rotatedDestCoords[destIdx].y = origMat[srcIdx][1];\n\n    if (changeAspect)\n    {\n      switch (srcIdx)\n      {\n        case 0:// top left\n          m_rotatedDestCoords[destIdx].x = centerX - diffX;\n          m_rotatedDestCoords[destIdx].y = centerY - diffY;\n          break;\n        case 1:// top right\n          m_rotatedDestCoords[destIdx].x = centerX + diffX;\n          m_rotatedDestCoords[destIdx].y = centerY - diffY;\n          break;\n        case 2:// bottom right\n          m_rotatedDestCoords[destIdx].x = centerX + diffX;\n          m_rotatedDestCoords[destIdx].y = centerY + diffY;\n          break;\n        case 3:// bottom left\n          m_rotatedDestCoords[destIdx].x = centerX - diffX;\n          m_rotatedDestCoords[destIdx].y = centerY + diffY;\n          break;\n      }\n    }\n    srcIdx++;\n    srcIdx = srcIdx % 4;\n  }\n}\n\nvoid CBaseRenderer::saveRotatedCoords()\n{\n  for (int i = 0; i < 4; i++)\n    m_savedRotatedDestCoords[i] = m_rotatedDestCoords[i];\n}\n\nvoid CBaseRenderer::syncDestRectToRotatedPoints()\n{\n  m_rotatedDestCoords[0].x = m_destRect.x1;\n  m_rotatedDestCoords[0].y = m_destRect.y1;  \n  m_rotatedDestCoords[1].x = m_destRect.x2;\n  m_rotatedDestCoords[1].y = m_destRect.y1;\n  m_rotatedDestCoords[2].x = m_destRect.x2;\n  m_rotatedDestCoords[2].y = m_destRect.y2;  \n  m_rotatedDestCoords[3].x = m_destRect.x1;\n  m_rotatedDestCoords[3].y = m_destRect.y2; \n}\n\nvoid CBaseRenderer::restoreRotatedCoords()\n{\n  for (int i = 0; i < 4; i++)\n    m_rotatedDestCoords[i] = m_savedRotatedDestCoords[i];\n}\n\nvoid CBaseRenderer::CalcNormalRenderRect(float offsetX, float offsetY, float width, float height,\n                                         float inputFrameRatio, float zoomAmount, float verticalShift)\n{\n  // if view window is empty, set empty destination\n  if(height == 0 || width == 0)\n  {\n    m_destRect.SetRect(0.0f, 0.0f, 0.0f, 0.0f);\n    return;\n  }\n#if 0\n  // scale up image as much as possible\n  // and keep the aspect ratio (introduces with black bars)\n  // calculate the correct output frame ratio (using the users pixel ratio setting\n  // and the output pixel ratio setting)\n\n  float outputFrameRatio = inputFrameRatio / g_graphicsContext.GetResInfo().fPixelRatio;\n\n  // allow a certain error to maximize size of render area\n  float fCorrection = width / height / outputFrameRatio - 1.0f;\n  float fAllowed    = CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ERRORINASPECT) * 0.01f;\n  if(fCorrection >   fAllowed) fCorrection =   fAllowed;\n  if(fCorrection < - fAllowed) fCorrection = - fAllowed;\n\n  outputFrameRatio *= 1.0f + fCorrection;\n\n  // maximize the movie width\n  float newWidth = width;\n  float newHeight = newWidth / outputFrameRatio;\n\n  if (newHeight > height)\n  {\n    newHeight = height;\n    newWidth = newHeight * outputFrameRatio;\n  }\n\n  // Scale the movie up by set zoom amount\n  newWidth *= zoomAmount;\n  newHeight *= zoomAmount;\n\n  // if we are less than one pixel off use the complete screen instead\n  if (std::abs(newWidth - width) < 1.0f)\n    newWidth = width;\n  if (std::abs(newHeight - height) < 1.0f)\n    newHeight = height;\n\n  // Centre the movie\n  float posY = (height - newHeight) / 2;\n  float posX = (width - newWidth) / 2;\n\n  // vertical shift range -1 to 1 shifts within the top and bottom black bars\n  // if there are no top and bottom black bars, this range does nothing\n  float blackBarSize = std::max((height - newHeight) / 2.0f, 0.0f);\n  posY += blackBarSize * std::max(std::min(verticalShift, 1.0f), -1.0f);\n\n  // vertical shift ranges -2 to -1 and 1 to 2 will shift the image out of the screen\n  // if vertical shift is -2 it will be completely shifted out the top,\n  // if it's 2 it will be completely shifted out the bottom\n  float shiftRange = std::min(newHeight, newHeight - (newHeight - height) / 2.0f);\n  if (verticalShift > 1.0f)\n    posY += shiftRange * (verticalShift - 1.0f);\n  else if (verticalShift < -1.0f)\n    posY += shiftRange * (verticalShift + 1.0f);\n\n  m_destRect.x1 = (float)MathUtils::round_int(posX + offsetX);\n  m_destRect.x2 = m_destRect.x1 + MathUtils::round_int(newWidth);\n  m_destRect.y1 = (float)MathUtils::round_int(posY + offsetY);\n  m_destRect.y2 = m_destRect.y1 + MathUtils::round_int(newHeight);\n\n  // clip as needed\n  if (!(g_graphicsContext.IsFullScreenVideo() || g_graphicsContext.IsCalibrating()))\n  {\n    CRect original(m_destRect);\n    m_destRect.Intersect(CRect(offsetX, offsetY, offsetX + width, offsetY + height));\n    if (m_destRect != original)\n    {\n      float scaleX = m_sourceRect.Width() / original.Width();\n      float scaleY = m_sourceRect.Height() / original.Height();\n      m_sourceRect.x1 += (m_destRect.x1 - original.x1) * scaleX;\n      m_sourceRect.y1 += (m_destRect.y1 - original.y1) * scaleY;\n      m_sourceRect.x2 += (m_destRect.x2 - original.x2) * scaleX;\n      m_sourceRect.y2 += (m_destRect.y2 - original.y2) * scaleY;\n    }\n  }\n\n  if (m_oldDestRect != m_destRect || m_oldRenderOrientation != m_renderOrientation)\n  {\n    // adapt the drawing rect points if we have to rotate\n    // and either destrect or orientation changed\n    ReorderDrawPoints();\n    m_oldDestRect = m_destRect;\n    m_oldRenderOrientation = m_renderOrientation;\n  }\n#endif\n}\n\n//***************************************************************************************\n// CalculateFrameAspectRatio()\n//\n// Considers the source frame size and output frame size (as suggested by mplayer)\n// to determine if the pixels in the source are not square.  It calculates the aspect\n// ratio of the output frame.  We consider the cases of VCD, SVCD and DVD separately,\n// as these are intended to be viewed on a non-square pixel TV set, so the pixels are\n// defined to be the same ratio as the intended display pixels.\n// These formats are determined by frame size.\n//***************************************************************************************\nvoid CBaseRenderer::CalculateFrameAspectRatio(unsigned int desired_width, unsigned int desired_height)\n{\n  m_sourceFrameRatio = (float)desired_width / desired_height;\n\n  // Check whether mplayer has decided that the size of the video file should be changed\n  // This indicates either a scaling has taken place (which we didn't ask for) or it has\n  // found an aspect ratio parameter from the file, and is changing the frame size based\n  // on that.\n  if (m_sourceWidth == (unsigned int) desired_width && m_sourceHeight == (unsigned int) desired_height)\n    return ;\n\n  // mplayer is scaling in one or both directions.  We must alter our Source Pixel Ratio\n  float imageFrameRatio = (float)m_sourceWidth / m_sourceHeight;\n\n  // OK, most sources will be correct now, except those that are intended\n  // to be displayed on non-square pixel based output devices (ie PAL or NTSC TVs)\n  // This includes VCD, SVCD, and DVD (and possibly others that we are not doing yet)\n  // For this, we can base the pixel ratio on the pixel ratios of PAL and NTSC,\n  // though we will need to adjust for anamorphic sources (ie those whose\n  // output frame ratio is not 4:3) and for SVCDs which have 2/3rds the\n  // horizontal resolution of the default NTSC or PAL frame sizes\n\n  // The following are the defined standard ratios for PAL and NTSC pixels\n  // NOTE: These aren't technically (in terms of BT601) correct - the commented values are,\n  //       but it seems that many DVDs nowadays are mastered incorrectly, so two wrongs\n  //       may indeed make a right.  The \"wrong\" values here ensure the output frame is\n  //       4x3 (or 16x9)\n  const float PALPixelRatio = 16.0f / 15.0f;      // 128.0f / 117.0f;\n  const float NTSCPixelRatio = 8.0f / 9.0f;       // 4320.0f / 4739.0f;\n\n  // Calculate the correction needed for anamorphic sources\n  float Non4by3Correction = m_sourceFrameRatio / (4.0f / 3.0f);\n\n  // Finally, check for a VCD, SVCD or DVD frame size as these need special aspect ratios\n  if (m_sourceWidth == 352)\n  { // VCD?\n    if (m_sourceHeight == 240) // NTSC\n      m_sourceFrameRatio = imageFrameRatio * NTSCPixelRatio;\n    if (m_sourceHeight == 288) // PAL\n      m_sourceFrameRatio = imageFrameRatio * PALPixelRatio;\n  }\n  if (m_sourceWidth == 480)\n  { // SVCD?\n    if (m_sourceHeight == 480) // NTSC\n      m_sourceFrameRatio = imageFrameRatio * 3.0f / 2.0f * NTSCPixelRatio * Non4by3Correction;\n    if (m_sourceHeight == 576) // PAL\n      m_sourceFrameRatio = imageFrameRatio * 3.0f / 2.0f * PALPixelRatio * Non4by3Correction;\n  }\n  if (m_sourceWidth == 720)\n  { // DVD?\n    if (m_sourceHeight == 480) // NTSC\n      m_sourceFrameRatio = imageFrameRatio * NTSCPixelRatio * Non4by3Correction;\n    if (m_sourceHeight == 576) // PAL\n      m_sourceFrameRatio = imageFrameRatio * PALPixelRatio * Non4by3Correction;\n  }\n}\n\nvoid CBaseRenderer::ManageRenderArea()\n{\n#if 0\n  m_viewRect = g_graphicsContext.GetViewWindow();\n\n  m_sourceRect.x1 = 0.0f;\n  m_sourceRect.y1 = 0.0f;\n  m_sourceRect.x2 = (float)m_sourceWidth;\n  m_sourceRect.y2 = (float)m_sourceHeight;\n\n  unsigned int stereo_mode  = CONF_FLAGS_STEREO_MODE_MASK(m_iFlags);\n  int          stereo_view  = g_graphicsContext.GetStereoView();\n\n  if(CONF_FLAGS_STEREO_CADENCE(m_iFlags) == CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT)\n  {\n    if     (stereo_view == RENDER_STEREO_VIEW_LEFT)  stereo_view = RENDER_STEREO_VIEW_RIGHT;\n    else if(stereo_view == RENDER_STEREO_VIEW_RIGHT) stereo_view = RENDER_STEREO_VIEW_LEFT;\n  }\n\n  if (m_format != RENDER_FMT_BYPASS)\n  {\n    switch(stereo_mode)\n    {\n      case CONF_FLAGS_STEREO_MODE_TAB:\n        // Those are flipped in y\n        if (m_format == RENDER_FMT_CVBREF || m_format == RENDER_FMT_MEDIACODEC)\n        {\n          if (stereo_view == RENDER_STEREO_VIEW_LEFT)\n            m_sourceRect.y1 += m_sourceRect.y2*0.5f;\n          else if(stereo_view == RENDER_STEREO_VIEW_RIGHT)\n            m_sourceRect.y2 *= 0.5f;\n        }\n        else\n        {\n          if (stereo_view == RENDER_STEREO_VIEW_LEFT)\n            m_sourceRect.y2 *= 0.5f;\n          else if(stereo_view == RENDER_STEREO_VIEW_RIGHT)\n            m_sourceRect.y1 += m_sourceRect.y2*0.5f;\n        }\n        break;\n\n      case CONF_FLAGS_STEREO_MODE_SBS:\n        if     (stereo_view == RENDER_STEREO_VIEW_LEFT)\n          m_sourceRect.x2 *= 0.5f;\n        else if(stereo_view == RENDER_STEREO_VIEW_RIGHT)\n          m_sourceRect.x1 += m_sourceRect.x2*0.5f;\n        break;\n\n      default:\n        break;\n    }\n  }\n\n  CalcNormalRenderRect(m_viewRect.x1, m_viewRect.y1, m_viewRect.Width(), m_viewRect.Height(), GetAspectRatio() * CDisplaySettings::GetInstance().GetPixelRatio(), CDisplaySettings::GetInstance().GetZoomAmount(), CDisplaySettings::GetInstance().GetVerticalShift());\n#endif\n}\n\nvoid CBaseRenderer::SetViewMode(int viewMode)\n{\n#if 0\n  if (viewMode < ViewModeNormal || viewMode > ViewModeZoom110Width)\n    viewMode = ViewModeNormal;\n\n  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode = viewMode;\n\n  // get our calibrated full screen resolution\n  RESOLUTION res = g_graphicsContext.GetVideoResolution();\n  RESOLUTION_INFO info = g_graphicsContext.GetResInfo();\n  float screenWidth  = (float)(info.Overscan.right  - info.Overscan.left);\n  float screenHeight = (float)(info.Overscan.bottom - info.Overscan.top);\n\n  // and the source frame ratio\n  float sourceFrameRatio = GetAspectRatio();\n\n  bool is43 = (sourceFrameRatio < 8.f/(3.f*sqrt(3.f)) &&\n              CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeNormal);\n\n  // Splitres scaling factor\n  float xscale = (float)info.iScreenWidth  / (float)info.iWidth;\n  float yscale = (float)info.iScreenHeight / (float)info.iHeight;\n\n  screenWidth   *= xscale;\n  screenHeight  *= yscale;\n\n  CDisplaySettings::GetInstance().SetVerticalShift(0.0f);\n  CDisplaySettings::GetInstance().SetNonLinearStretched(false);\n\n  if ( CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeZoom ||\n       (is43 && CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_STRETCH43) == ViewModeZoom))\n  { // zoom image so no black bars\n    CDisplaySettings::GetInstance().SetPixelRatio(1.0);\n    // calculate the desired output ratio\n    float outputFrameRatio = sourceFrameRatio * CDisplaySettings::GetInstance().GetPixelRatio() / info.fPixelRatio;\n    // now calculate the correct zoom amount.  First zoom to full height.\n    float newHeight = screenHeight;\n    float newWidth = newHeight * outputFrameRatio;\n    CDisplaySettings::GetInstance().SetZoomAmount(newWidth / screenWidth);\n    if (newWidth < screenWidth)\n    { // zoom to full width\n      newWidth = screenWidth;\n      newHeight = newWidth / outputFrameRatio;\n      CDisplaySettings::GetInstance().SetZoomAmount(newHeight / screenHeight);\n    }\n  }\n  else if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeStretch4x3)\n  { // stretch image to 4:3 ratio\n    CDisplaySettings::GetInstance().SetZoomAmount(1.0);\n    if (res == RES_PAL_4x3 || res == RES_PAL60_4x3 || res == RES_NTSC_4x3 || res == RES_HDTV_480p_4x3)\n    { // stretch to the limits of the 4:3 screen.\n      // incorrect behaviour, but it's what the users want, so...\n      CDisplaySettings::GetInstance().SetPixelRatio((screenWidth / screenHeight) * info.fPixelRatio / sourceFrameRatio);\n    }\n    else\n    {\n      // now we need to set CDisplaySettings::GetInstance().GetPixelRatio() so that\n      // fOutputFrameRatio = 4:3.\n      CDisplaySettings::GetInstance().SetPixelRatio((4.0f / 3.0f) / sourceFrameRatio);\n    }\n  }\n  else if ( CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeWideZoom ||\n           (is43 && CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_STRETCH43) == ViewModeWideZoom))\n  { // super zoom\n    float stretchAmount = (screenWidth / screenHeight) * info.fPixelRatio / sourceFrameRatio;\n    CDisplaySettings::GetInstance().SetPixelRatio(pow(stretchAmount, float(2.0/3.0)));\n    CDisplaySettings::GetInstance().SetZoomAmount(pow(stretchAmount, float((stretchAmount < 1.0) ? -1.0/3.0 : 1.0/3.0)));\n    CDisplaySettings::GetInstance().SetNonLinearStretched(true);\n  }\n  else if ( CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeStretch16x9 ||\n            CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeStretch16x9Nonlin ||\n           (is43 && (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_STRETCH43) == ViewModeStretch16x9 ||\n                     CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_STRETCH43) == ViewModeStretch16x9Nonlin)))\n  { // stretch image to 16:9 ratio\n    CDisplaySettings::GetInstance().SetZoomAmount(1.0);\n    if (res == RES_PAL_4x3 || res == RES_PAL60_4x3 || res == RES_NTSC_4x3 || res == RES_HDTV_480p_4x3)\n    { // now we need to set CDisplaySettings::GetInstance().GetPixelRatio() so that\n      // outputFrameRatio = 16:9.\n      CDisplaySettings::GetInstance().SetPixelRatio((16.0f / 9.0f) / sourceFrameRatio);\n    }\n    else\n    { // stretch to the limits of the 16:9 screen.\n      // incorrect behaviour, but it's what the users want, so...\n      CDisplaySettings::GetInstance().SetPixelRatio((screenWidth / screenHeight) * info.fPixelRatio / sourceFrameRatio);\n    }\n    bool nonlin = (is43 && CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_STRETCH43) == ViewModeStretch16x9Nonlin) ||\n                  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeStretch16x9Nonlin;\n    CDisplaySettings::GetInstance().SetNonLinearStretched(nonlin);\n  }\n  else  if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeOriginal)\n  { // zoom image so that the height is the original size\n    CDisplaySettings::GetInstance().SetPixelRatio(1.0);\n    // get the size of the media file\n    // calculate the desired output ratio\n    float outputFrameRatio = sourceFrameRatio * CDisplaySettings::GetInstance().GetPixelRatio() / info.fPixelRatio;\n    // now calculate the correct zoom amount.  First zoom to full width.\n    float newHeight = screenWidth / outputFrameRatio;\n    if (newHeight > screenHeight)\n    { // zoom to full height\n      newHeight = screenHeight;\n    }\n    // now work out the zoom amount so that no zoom is done\n    CDisplaySettings::GetInstance().SetZoomAmount(m_sourceHeight / newHeight);\n  }\n  else if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeCustom)\n  {\n    CDisplaySettings::GetInstance().SetZoomAmount(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomZoomAmount);\n    CDisplaySettings::GetInstance().SetPixelRatio(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomPixelRatio);\n    CDisplaySettings::GetInstance().SetNonLinearStretched(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomNonLinStretch);\n    CDisplaySettings::GetInstance().SetVerticalShift(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomVerticalShift);\n  }\n  else if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeZoom120Width)\n  {\n    float fitHeightZoom = sourceFrameRatio * screenHeight / (info.fPixelRatio * screenWidth);\n    CDisplaySettings::GetInstance().SetPixelRatio(1.0f);\n    CDisplaySettings::GetInstance().SetZoomAmount(fitHeightZoom < 1.0f ? 1.0f : (fitHeightZoom > 1.2f ? 1.2f : fitHeightZoom));\n  }\n  else if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeZoom110Width)\n  {\n    float fitHeightZoom = sourceFrameRatio * screenHeight / (info.fPixelRatio * screenWidth);\n    CDisplaySettings::GetInstance().SetPixelRatio(1.0f);\n    CDisplaySettings::GetInstance().SetZoomAmount(fitHeightZoom < 1.0f ? 1.0f : (fitHeightZoom > 1.1f ? 1.1f : fitHeightZoom));\n  }\n  else // if (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode == ViewModeNormal)\n  {\n    CDisplaySettings::GetInstance().SetPixelRatio(1.0);\n    CDisplaySettings::GetInstance().SetZoomAmount(1.0);\n  }\n\n  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomZoomAmount = CDisplaySettings::GetInstance().GetZoomAmount();\n  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomPixelRatio = CDisplaySettings::GetInstance().GetPixelRatio();\n  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomNonLinStretch = CDisplaySettings::GetInstance().IsNonLinearStretched();\n  CMediaSettings::GetInstance().GetCurrentVideoSettings().m_CustomVerticalShift = CDisplaySettings::GetInstance().GetVerticalShift();\n#endif\n}\n\nvoid CBaseRenderer::MarkDirty()\n{\n // g_windowManager.MarkDirty(m_destRect);\n}\n\nvoid CBaseRenderer::SettingOptionsRenderMethodsFiller(/*const CSetting *setting,*/ std::vector< std::pair<std::string, int> > &list, int &current, void *data)\n{\n  list.emplace_back(\"rendermethod_auto\"/*g_localizeStrings.Get(13416)*/, RENDER_METHOD_AUTO);\n\n#ifdef HAS_DX\n  list.push_back(make_pair(g_localizeStrings.Get(16319), RENDER_METHOD_DXVA));\n  list.push_back(make_pair(g_localizeStrings.Get(13431), RENDER_METHOD_D3D_PS));\n  list.push_back(make_pair(g_localizeStrings.Get(13419), RENDER_METHOD_SOFTWARE));\n#endif\n\n#ifdef HAS_GL\n  list.push_back(make_pair(g_localizeStrings.Get(13417), RENDER_METHOD_ARB));\n  list.push_back(make_pair(g_localizeStrings.Get(13418), RENDER_METHOD_GLSL));\n#endif\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/BaseRenderer.h",
    "content": "#pragma once\n#include <utility>\n#include <vector>\n#include \"Geometry.h\"\n#include \"RenderFormats.h\"\n#include <cstdint>\n#include <atomic>\n\n#define MAX_PLANES 3\n#define MAX_FIELDS 3\n#define NUM_BUFFERS 6\n\nNS_KRMOVIE_BEGIN\n\ntypedef struct YV12Image\n{\n  uint8_t* plane[MAX_PLANES];\n  int      planesize[MAX_PLANES];\n  unsigned stride[MAX_PLANES];\n  unsigned width = 0;\n  unsigned height = 0;\n  unsigned flags;\n\n  unsigned cshift_x; /* this is the chroma shift used */\n  unsigned cshift_y;\n  unsigned bpp; /* bytes per pixel */\n} YV12Image;\n\nenum EFIELDSYNC\n{\n  FS_NONE,\n  FS_TOP,\n  FS_BOT\n};\n\n// Render Methods\nenum RenderMethods\n{\n  RENDER_METHOD_AUTO     = 0,\n  RENDER_METHOD_ARB,\n  RENDER_METHOD_GLSL,\n  RENDER_METHOD_SOFTWARE,\n  RENDER_METHOD_D3D_PS,\n  RENDER_METHOD_DXVA,\n  RENDER_OVERLAYS        = 99   // to retain compatibility\n};\n\nstruct DVDVideoPicture;\nclass CRenderCapture;\n\nclass CBaseRenderer\n{\npublic:\n  CBaseRenderer();\n  virtual ~CBaseRenderer();\n\n  // Player functions\n  virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation) { return true; }\n  virtual bool IsConfigured() { return true; }\n//  virtual int GetImage(YV12Image *image, int source = -1, bool readonly = false) {}\n//  virtual void ReleaseImage(int source, bool preserve = false) {}\n  virtual int AddVideoPicture(DVDVideoPicture &picture, int index) = 0;\n  virtual bool IsPictureHW(DVDVideoPicture &picture) { return false; }\n  virtual void FlipPage(int source) {}\n  virtual void PreInit() {}\n  virtual void UnInit() {}\n  virtual void Reset() {}\n  virtual void Flush() {}\n  virtual void SetBufferSize(int numBuffers) { }\n  virtual void ReleaseBuffer(int idx) { }\n  virtual bool NeedBuffer(int idx) { return false; }\n  virtual bool IsGuiLayer() { return true; }\n  // Render info, can be called before configure\n  virtual CRenderInfo GetRenderInfo() { return CRenderInfo(); }\n  virtual void Update() {}\n  virtual void RenderUpdate(bool clear, unsigned int flags = 0, unsigned int alpha = 255) {}\n  virtual bool RenderCapture(CRenderCapture* capture) { return false; }\n  virtual bool HandlesRenderFormat(ERenderFormat format) { return format == m_format; };\n  virtual int WaitForBuffer(volatile std::atomic_bool&bStop, int timeout = 0) { return -1; }\n\n  // Feature support\n//  virtual bool SupportsMultiPassRendering() { return false; }\n//   virtual bool Supports(ERENDERFEATURE feature) { return false; };\n//   virtual bool Supports(ESCALINGMETHOD method) {}\n\n  virtual bool WantsDoublePass() { return false; };\n\n  void SetViewMode(int viewMode);\n\n  /*! \\brief Get video rectangle and view window\n  \\param source is original size of the video\n  \\param dest is the target rendering area honoring aspect ratio of source\n  \\param view is the entire target rendering area for the video (including black bars)\n  */\n  void GetVideoRect(CRect &source, CRect &dest, CRect &view);\n  float GetAspectRatio() const;\n\n  static void SettingOptionsRenderMethodsFiller(/*const CSetting *setting,*/ std::vector< std::pair<std::string, int> > &list, int &current, void *data);\n\nprotected:\n  void CalcNormalRenderRect(float offsetX, float offsetY, float width, float height,\n                            float inputFrameRatio, float zoomAmount, float verticalShift);\n  void CalculateFrameAspectRatio(unsigned int desired_width, unsigned int desired_height);\n  void ManageRenderArea();\n  virtual void ReorderDrawPoints();//might be overwritten (by egl e.x.)\n  void saveRotatedCoords();//saves the current state of m_rotatedDestCoords\n  void syncDestRectToRotatedPoints();//sync any changes of m_destRect to m_rotatedDestCoords\n  void restoreRotatedCoords();//restore the current state of m_rotatedDestCoords from saveRotatedCoords\n  void MarkDirty();\n\n  unsigned int m_sourceWidth;\n  unsigned int m_sourceHeight;\n  float m_sourceFrameRatio;\n  float m_fps;\n\n  unsigned int m_renderOrientation; // orientation of the video in degress counter clockwise\n  unsigned int m_oldRenderOrientation; // orientation of the previous frame\n  // for drawing the texture with glVertex4f (holds all 4 corner points of the destination rect\n  // with correct orientation based on m_renderOrientation\n  // 0 - top left, 1 - top right, 2 - bottom right, 3 - bottom left\n  CPoint m_rotatedDestCoords[4];\n  CPoint m_savedRotatedDestCoords[4];//saved points from saveRotatedCoords call\n\n  CRect m_destRect;\n  CRect m_oldDestRect; // destrect of the previous frame\n  CRect m_sourceRect;\n  CRect m_viewRect;\n\n  // rendering flags\n  unsigned m_iFlags;\n  ERenderFormat m_format;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/BitstreamStats.cpp",
    "content": "#include \"BitstreamStats.h\"\n#include \"TimeUtils.h\"\n\nNS_KRMOVIE_BEGIN\nint64_t BitstreamStats::m_tmFreq;\n\nBitstreamStats::BitstreamStats(unsigned int nEstimatedBitrate)\n{\n  m_dBitrate = 0.0;\n  m_dMaxBitrate = 0.0;\n  m_dMinBitrate = -1.0;\n\n  m_nBitCount = 0;\n  m_nEstimatedBitrate = nEstimatedBitrate;\n  m_tmStart = 0LL;\n\n  if (m_tmFreq == 0LL)\n    m_tmFreq = CurrentHostFrequency();\n}\n\nBitstreamStats::~BitstreamStats()\n{\n}\n\nvoid BitstreamStats::AddSampleBytes(unsigned int nBytes)\n{\n  AddSampleBits(nBytes*8);\n}\n\nvoid BitstreamStats::AddSampleBits(unsigned int nBits)\n{\n  m_nBitCount += nBits;\n  if (m_nBitCount >= m_nEstimatedBitrate)\n    CalculateBitrate();\n}\n\nvoid BitstreamStats::Start()\n{\n  m_nBitCount = 0;\n  m_tmStart = CurrentHostCounter();\n}\n\nvoid BitstreamStats::CalculateBitrate()\n{\n  int64_t tmNow;\n  tmNow = CurrentHostCounter();\n\n  double elapsed = (double)(tmNow - m_tmStart) / (double)m_tmFreq;\n  // only update once every 2 seconds\n  if (elapsed >= 2)\n  {\n    m_dBitrate = (double)m_nBitCount / elapsed;\n\n    if (m_dBitrate > m_dMaxBitrate)\n      m_dMaxBitrate = m_dBitrate;\n\n    if (m_dBitrate < m_dMinBitrate || m_dMinBitrate == -1)\n      m_dMinBitrate = m_dBitrate;\n\n    Start();\n  }\n}\n\n\n\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/BitstreamStats.h",
    "content": "#ifndef BITSTREAM_STATS__H__\n#define BITSTREAM_STATS__H__\n#include \"KRMovieDef.h\"\n#include <string>\n#ifdef TARGET_POSIX\n#include \"linux/PlatformDefs.h\"\n#else\n#include <stdint.h>\n#endif\n\nNS_KRMOVIE_BEGIN\nclass BitstreamStats\n{\npublic:\n  // in order not to cause a performance hit, we should only check the clock when\n  // we reach m_nEstimatedBitrate bits.\n  // if this value is 1, we will calculate bitrate on every sample.\n  BitstreamStats(unsigned int nEstimatedBitrate=(10240*8) /*10Kbit*/);\n  virtual ~BitstreamStats();\n\n  void AddSampleBytes(unsigned int nBytes);\n  void AddSampleBits(unsigned int nBits);\n\n  inline double GetBitrate()    const { return m_dBitrate; }\n  inline double GetMaxBitrate() const { return m_dMaxBitrate; }\n  inline double GetMinBitrate() const { return m_dMinBitrate; }\n\n  void Start();\n  void CalculateBitrate();\n\nprivate:\n  double m_dBitrate;\n  double m_dMaxBitrate;\n  double m_dMinBitrate;\n  unsigned int m_nBitCount;\n  unsigned int m_nEstimatedBitrate; // when we reach this amount of bits we check current bitrate.\n  int64_t m_tmStart;\n  static int64_t m_tmFreq;\n};\nNS_KRMOVIE_END\n#endif\n\n"
  },
  {
    "path": "src/core/movie/ffmpeg/Clock.cpp",
    "content": "#include \"Clock.h\"\n#include \"MathUtils.h\"\n#include \"TimeUtils.h\"\n\nNS_KRMOVIE_BEGIN\n\nCDVDClock::CDVDClock()\n{\n\tCSingleLock lock(m_systemsection);\n\n\tm_pauseClock = 0;\n\tm_bReset = true;\n\tm_paused = false;\n\tm_iDisc = 0;\n\tm_maxspeedadjust = 0.0;\n\tm_systemAdjust = 0;\n\tm_speedAdjust = 0;\n\tm_startClock = 0;\n\tm_vSyncAdjust = 0;\n\tm_frameTime = DVD_TIME_BASE / 60.0;\n\n\tm_videoRefClock.reset(new CVideoReferenceClock());\n\tm_lastSystemTime = m_videoRefClock->GetTime();\n\tm_systemOffset = m_videoRefClock->GetTime();\n\tm_systemFrequency = (int64_t)CurrentHostFrequency();\n\tm_systemUsed = m_systemFrequency;\n}\n\nCDVDClock::~CDVDClock()\n{\n}\n\n// Returns the current absolute clock in units of DVD_TIME_BASE (usually microseconds).\ndouble CDVDClock::GetAbsoluteClock(bool interpolated /*= true*/)\n{\n\tCSingleLock lock(m_systemsection);\n\n\tint64_t current;\n\tcurrent = m_videoRefClock->GetTime(interpolated);\n\n\treturn SystemToAbsolute(current);\n}\n\ndouble CDVDClock::GetClock(bool interpolated /*= true*/)\n{\n\tCSingleLock lock(m_critSection);\n\n\tint64_t current = m_videoRefClock->GetTime(interpolated);\n\tm_systemAdjust += m_speedAdjust * (current - m_lastSystemTime);\n\tm_lastSystemTime = current;\n\n\treturn SystemToPlaying(current);\n}\n\ndouble CDVDClock::GetClock(double& absolute, bool interpolated /*= true*/)\n{\n\tint64_t current = m_videoRefClock->GetTime(interpolated);\n\n\tCSingleLock lock(m_systemsection);\n\tabsolute = SystemToAbsolute(current);\n\n\tm_systemAdjust += m_speedAdjust * (current - m_lastSystemTime);\n\tm_lastSystemTime = current;\n\n\treturn SystemToPlaying(current);\n}\n\nvoid CDVDClock::SetVsyncAdjust(double adjustment)\n{\n\tCSingleLock lock(m_critSection);\n\tm_vSyncAdjust = adjustment;\n}\n\ndouble CDVDClock::GetVsyncAdjust()\n{\n\tCSingleLock lock(m_critSection);\n\treturn m_vSyncAdjust;\n}\n\nvoid CDVDClock::Pause(bool pause)\n{\n\tCSingleLock lock(m_critSection);\n\n\tif (pause && !m_paused)\n\t{\n\t\tif (!m_pauseClock)\n\t\t\tm_speedAfterPause = m_systemFrequency * DVD_PLAYSPEED_NORMAL / m_systemUsed;\n\t\telse\n\t\t\tm_speedAfterPause = DVD_PLAYSPEED_PAUSE;\n\n\t\tSetSpeed(DVD_PLAYSPEED_PAUSE);\n\t\tm_paused = true;\n\t} else if (!pause && m_paused)\n\t{\n\t\tm_paused = false;\n\t\tSetSpeed(m_speedAfterPause);\n\t}\n}\n\nvoid CDVDClock::SetSpeed(int iSpeed)\n{\n\t// this will sometimes be a little bit of due to rounding errors, ie clock might jump abit when changing speed\n\tCSingleLock lock(m_critSection);\n\n\tif (m_paused)\n\t{\n\t\tm_speedAfterPause = iSpeed;\n\t\treturn;\n\t}\n\n\tif (iSpeed == DVD_PLAYSPEED_PAUSE)\n\t{\n\t\tif (!m_pauseClock)\n\t\t\tm_pauseClock = m_videoRefClock->GetTime();\n\t\treturn;\n\t}\n\n\tint64_t current;\n\tint64_t newfreq = m_systemFrequency * DVD_PLAYSPEED_NORMAL / iSpeed;\n\n\tcurrent = m_videoRefClock->GetTime();\n\tif (m_pauseClock)\n\t{\n\t\tm_startClock += current - m_pauseClock;\n\t\tm_pauseClock = 0;\n\t}\n\n\tm_startClock = current - (int64_t)((double)(current - m_startClock) * newfreq / m_systemUsed);\n\tm_systemUsed = newfreq;\n}\n\nvoid CDVDClock::SetSpeedAdjust(double adjust)\n{\n//\tCLog::Log(LOGDEBUG, \"CDVDClock::SetSpeedAdjust - adjusted:%f\", adjust);\n\n\tCSingleLock lock(m_critSection);\n\tm_speedAdjust = adjust;\n}\n\ndouble CDVDClock::GetSpeedAdjust()\n{\n\tCSingleLock lock(m_critSection);\n\treturn m_speedAdjust;\n}\n\ndouble CDVDClock::ErrorAdjust(double error, const char* log)\n{\n\tCSingleLock lock(m_critSection);\n\n\tdouble clock, absolute, adjustment;\n\tclock = GetClock(absolute);\n\n\t// skip minor updates while speed adjust is active\n\t// -> adjusting buffer levels\n\tif (m_speedAdjust != 0 && error < DVD_MSEC_TO_TIME(100))\n\t{\n\t\treturn 0;\n\t}\n\n\tadjustment = error;\n\n\tif (m_vSyncAdjust != 0)\n\t{\n\t\t// Audio ahead is more noticeable then audio behind video.\n\t\t// Correct if aufio is more than 20ms ahead or more then\n\t\t// 27ms behind. In a worst case scenario we switch from\n\t\t// 20ms ahead to 21ms behind (for fps of 23.976)\n\t\tif (error > 0.02 * DVD_TIME_BASE)\n\t\t\tadjustment = m_frameTime;\n\t\telse if (error < -0.027 * DVD_TIME_BASE)\n\t\t\tadjustment = -m_frameTime;\n\t\telse\n\t\t\tadjustment = 0;\n\t}\n\n\tif (adjustment == 0)\n\t\treturn 0;\n\n\tDiscontinuity(clock + adjustment, absolute);\n\n// \tCLog::Log(LOGDEBUG, \"CDVDClock::ErrorAdjust - %s - error:%f, adjusted:%f\",\n// \t\tlog, error, adjustment);\n\treturn adjustment;\n}\n\nvoid CDVDClock::Discontinuity(double clock, double absolute)\n{\n\tCSingleLock lock(m_critSection);\n\tm_startClock = AbsoluteToSystem(absolute);\n\tif (m_pauseClock)\n\t\tm_pauseClock = m_startClock;\n\tm_iDisc = clock;\n\tm_bReset = false;\n\tm_systemAdjust = 0;\n\tm_speedAdjust = 0;\n}\n\nvoid CDVDClock::SetMaxSpeedAdjust(double speed)\n{\n\tCSingleLock lock(m_speedsection);\n\n\tm_maxspeedadjust = speed;\n}\n\n//returns the refreshrate if the videoreferenceclock is running, -1 otherwise\nint CDVDClock::UpdateFramerate(double fps, double* interval /*= NULL*/)\n{\n\t//sent with fps of 0 means we are not playing video\n\tif (fps == 0.0)\n\t\treturn -1;\n\n\tm_frameTime = 1 / fps * DVD_TIME_BASE;\n\n\t//check if the videoreferenceclock is running, will return -1 if not\n\tdouble rate = m_videoRefClock->GetRefreshRate(interval);\n\n\tif (rate <= 0)\n\t\treturn -1;\n\t\n\tdouble speed;\n\t{\n\t\tCSingleLock lock(m_speedsection);\n\n\t\tdouble weight = MathUtils::round_int(rate) / (double)MathUtils::round_int(fps);\n\n\t\t//set the speed of the videoreferenceclock based on fps, refreshrate and maximum speed adjust set by user\n\t\tif (m_maxspeedadjust > 0.05)\n\t\t{\n\t\t\tif (weight / MathUtils::round_int(weight) < 1.0 + m_maxspeedadjust / 100.0\n\t\t\t\t&&  weight / MathUtils::round_int(weight) > 1.0 - m_maxspeedadjust / 100.0)\n\t\t\t\tweight = MathUtils::round_int(weight);\n\t\t}\n\t\tspeed = rate / (fps * weight);\n\t}\n\n\tm_videoRefClock->SetSpeed(speed);\n\n\treturn rate;\n}\n\nbool CDVDClock::GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate) const\n{\n\treturn m_videoRefClock->GetClockInfo(MissedVblanks, ClockSpeed, RefreshRate);\n}\n\ndouble CDVDClock::SystemToAbsolute(int64_t system)\n{\n\treturn DVD_TIME_BASE * (double)(system - m_systemOffset) / m_systemFrequency;\n}\n\nint64_t CDVDClock::AbsoluteToSystem(double absolute)\n{\n\treturn (int64_t)(absolute / DVD_TIME_BASE * m_systemFrequency) + m_systemOffset;\n}\n\ndouble CDVDClock::SystemToPlaying(int64_t system)\n{\n\tint64_t current;\n\n\tif (m_bReset)\n\t{\n\t\tm_startClock = system;\n\t\tm_systemUsed = m_systemFrequency;\n\t\tif (m_pauseClock)\n\t\t\tm_pauseClock = m_startClock;\n\t\tm_iDisc = 0;\n\t\tm_systemAdjust = 0;\n\t\tm_speedAdjust = 0;\n\t\tm_vSyncAdjust = 0;\n\t\tm_bReset = false;\n\t}\n\n\tif (m_pauseClock)\n\t\tcurrent = m_pauseClock;\n\telse\n\t\tcurrent = system;\n\n\treturn DVD_TIME_BASE * (double)(current - m_startClock + m_systemAdjust) / m_systemUsed + m_iDisc;\n}\n\ndouble CDVDClock::GetClockSpeed()\n{\n\tCSingleLock lock(m_critSection);\n\n\tdouble speed = (double)m_systemFrequency / m_systemUsed;\n\treturn m_videoRefClock->GetSpeed() * speed + m_speedAdjust;\n}\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Clock.h",
    "content": "#pragma once\n#include \"VideoReferenceClock.h\"\n#include <memory>\n\nNS_KRMOVIE_BEGIN\n\n#define DVD_TIME_BASE 1000000\n#define DVD_NOPTS_VALUE 0xFFF0000000000000\n\n#define DVD_TIME_TO_MSEC(x) ((int)((double)(x) * 1000 / DVD_TIME_BASE))\n#define DVD_SEC_TO_TIME(x)  ((double)(x) * DVD_TIME_BASE)\n#define DVD_MSEC_TO_TIME(x) ((double)(x) * DVD_TIME_BASE / 1000)\n\n#define DVD_PLAYSPEED_PAUSE       0       // frame stepping\n#define DVD_PLAYSPEED_NORMAL      1000\n\nclass CDVDClock {\npublic:\n\tCDVDClock();\n\t~CDVDClock();\n\n\tdouble GetClock(bool interpolated = true);\n\tdouble GetClock(double& absolute, bool interpolated = true);\n\n\tdouble ErrorAdjust(double error, const char* log);\n\tvoid Discontinuity(double clock, double absolute);\n\tvoid Discontinuity(double clock = 0LL)\n\t{\n\t\tDiscontinuity(clock, GetAbsoluteClock());\n\t}\n\n\tvoid Reset() { m_bReset = true; }\n\tvoid SetSpeed(int iSpeed);\n\tvoid SetSpeedAdjust(double adjust);\n\tdouble GetSpeedAdjust();\n\n\tdouble GetClockSpeed(); /**< get the current speed of the clock relative normal system time */\n\n  /* tells clock at what framerate video is, to  *\n   * allow it to adjust speed for a better match */\n\tint UpdateFramerate(double fps, double* interval = NULL);\n\n\tvoid SetMaxSpeedAdjust(double speed);\n\n\tdouble GetAbsoluteClock(bool interpolated = true);\n\tdouble GetFrequency() { return (double)m_systemFrequency; }\n\n\tbool GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate) const;\n\tvoid SetVsyncAdjust(double adjustment);\n\tdouble GetVsyncAdjust();\n\tvoid Pause(bool pause);\n\nprotected:\n\tdouble SystemToAbsolute(int64_t system);\n\tint64_t AbsoluteToSystem(double absolute);\n\tdouble SystemToPlaying(int64_t system);\n\n\tCCriticalSection m_critSection;\n\tint64_t m_systemUsed;\n\tint64_t m_startClock;\n\tint64_t m_pauseClock;\n\tdouble m_iDisc;\n\tbool m_bReset;\n\tbool m_paused;\n\tint m_speedAfterPause;\n\tstd::unique_ptr<CVideoReferenceClock> m_videoRefClock;\n\n\tint64_t m_systemFrequency;\n\tint64_t m_systemOffset;\n\tCCriticalSection m_systemsection;\n\n\tint64_t m_systemAdjust;\n\tint64_t m_lastSystemTime;\n\tdouble m_speedAdjust;\n\tdouble m_vSyncAdjust;\n\tdouble m_frameTime;\n\n\tdouble m_maxspeedadjust;\n\tCCriticalSection m_speedsection;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/CodecUtils.cpp",
    "content": "#include \"CodecUtils.h\"\n\n#ifdef TARGET_WINDOWS\n#pragma comment(lib, \"avcodec.lib\")\n#pragma comment(lib, \"avfilter.lib\")\n#pragma comment(lib, \"avformat.lib\")\n#pragma comment(lib, \"avutil.lib\")\n#pragma comment(lib, \"postproc.lib\")\n#pragma comment(lib, \"swresample.lib\")\n#pragma comment(lib, \"swscale.lib\")\n#endif\n\nextern \"C\" {\n#include \"libswscale/swscale.h\"\n}\n\n#include \"VideoCodec.h\"\n#include \"Clock.h\"\n#include \"BaseRenderer.h\"\n\n#define ARRAY_SIZE(X)         (sizeof(X)/sizeof((X)[0]))\n\nNS_KRMOVIE_BEGIN\n\n// allocate a new picture (AV_PIX_FMT_YUV420P)\nDVDVideoPicture* CDVDCodecUtils::AllocatePicture(int iWidth, int iHeight)\n{\n  DVDVideoPicture* pPicture = new DVDVideoPicture;\n  if (pPicture)\n  {\n    pPicture->iWidth = iWidth;\n    pPicture->iHeight = iHeight;\n\n    int w = iWidth / 2;\n    int h = iHeight / 2;\n    int size = w * h;\n    int totalsize = (iWidth * iHeight) + size * 2;\n    uint8_t* data = new uint8_t[totalsize];\n    if (data)\n    {\n      pPicture->data[0] = data;\n      pPicture->data[1] = pPicture->data[0] + (iWidth * iHeight);\n      pPicture->data[2] = pPicture->data[1] + size;\n      pPicture->data[3] = NULL;\n      pPicture->iLineSize[0] = iWidth;\n      pPicture->iLineSize[1] = w;\n      pPicture->iLineSize[2] = w;\n      pPicture->iLineSize[3] = 0;\n    }\n    else\n    {\n//      CLog::Log(LOGFATAL, \"CDVDCodecUtils::AllocatePicture, unable to allocate new video picture, out of memory.\");\n      delete pPicture;\n      pPicture = NULL;\n    }\n  }\n  return pPicture;\n}\n\nvoid CDVDCodecUtils::FreePicture(DVDVideoPicture* pPicture)\n{\n  av_free(pPicture->data[0]);\n  delete pPicture;\n}\n\nbool CDVDCodecUtils::CopyPicture(DVDVideoPicture* pDst, DVDVideoPicture* pSrc)\n{\n  uint8_t *s, *d;\n  int w = pSrc->iWidth;\n  int h = pSrc->iHeight;\n\n  s = pSrc->data[0];\n  d = pDst->data[0];\n\n  for (int y = 0; y < h; y++)\n  {\n    memcpy(d, s, w);\n    s += pSrc->iLineSize[0];\n    d += pDst->iLineSize[0];\n  }\n\n  w >>= 1;\n  h >>= 1;\n\n  s = pSrc->data[1];\n  d = pDst->data[1];\n  for (int y = 0; y < h; y++)\n  {\n    memcpy(d, s, w);\n    s += pSrc->iLineSize[1];\n    d += pDst->iLineSize[1];\n  }\n\n  s = pSrc->data[2];\n  d = pDst->data[2];\n  for (int y = 0; y < h; y++)\n  {\n    memcpy(d, s, w);\n    s += pSrc->iLineSize[2];\n    d += pDst->iLineSize[2];\n  }\n  return true;\n}\n\nbool CDVDCodecUtils::CopyPicture(YV12Image* pImage, DVDVideoPicture *pSrc)\n{\n  uint8_t *s = pSrc->data[0];\n  uint8_t *d = pImage->plane[0];\n  int w = pImage->width * pImage->bpp;\n  int h = pImage->height;\n  if ((w == pSrc->iLineSize[0]) && ((unsigned int) pSrc->iLineSize[0] == pImage->stride[0]))\n  {\n    memcpy(d, s, w*h);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w);\n      s += pSrc->iLineSize[0];\n      d += pImage->stride[0];\n    }\n  }\n  s = pSrc->data[1];\n  d = pImage->plane[1];\n  w =(pImage->width  >> pImage->cshift_x) * pImage->bpp;\n  h =(pImage->height >> pImage->cshift_y);\n  if ((w==pSrc->iLineSize[1]) && ((unsigned int) pSrc->iLineSize[1]==pImage->stride[1]))\n  {\n    memcpy(d, s, w*h);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w);\n      s += pSrc->iLineSize[1];\n      d += pImage->stride[1];\n    }\n  }\n  s = pSrc->data[2];\n  d = pImage->plane[2];\n  if ((w==pSrc->iLineSize[2]) && ((unsigned int) pSrc->iLineSize[2]==pImage->stride[2]))\n  {\n    memcpy(d, s, w*h);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w);\n      s += pSrc->iLineSize[2];\n      d += pImage->stride[2];\n    }\n  }\n  return true;\n}\n\nDVDVideoPicture* CDVDCodecUtils::ConvertToNV12Picture(DVDVideoPicture *pSrc)\n{\n  // Clone a YV12 picture to new NV12 picture.\n  DVDVideoPicture* pPicture = new DVDVideoPicture;\n  if (pPicture)\n  {\n    *pPicture = *pSrc;\n\n    int w = pPicture->iWidth / 2;\n    int h = pPicture->iHeight / 2;\n    int size = w * h;\n    int totalsize = (pPicture->iWidth * pPicture->iHeight) + size * 2;\n    uint8_t* data = (uint8_t*) av_malloc(totalsize);\n    if (data)\n    {\n      pPicture->data[0] = data;\n      pPicture->data[1] = pPicture->data[0] + (pPicture->iWidth * pPicture->iHeight);\n      pPicture->data[2] = NULL;\n      pPicture->data[3] = NULL;\n      pPicture->iLineSize[0] = pPicture->iWidth;\n      pPicture->iLineSize[1] = pPicture->iWidth;\n      pPicture->iLineSize[2] = 0;\n      pPicture->iLineSize[3] = 0;\n      pPicture->format = RENDER_FMT_NV12;\n      \n      // copy luma\n      uint8_t *s = pSrc->data[0];\n      uint8_t *d = pPicture->data[0];\n      for (int y = 0; y < (int)pSrc->iHeight; y++)\n      {\n        memcpy(d, s, pSrc->iWidth);\n        s += pSrc->iLineSize[0];\n        d += pPicture->iLineSize[0];\n      }\n\n      //copy chroma\n      for (int y = 0; y < (int)pSrc->iHeight/2; y++) {\n        uint8_t *s_u = pSrc->data[1] + (y * pSrc->iLineSize[1]);\n        uint8_t *s_v = pSrc->data[2] + (y * pSrc->iLineSize[2]);\n        uint8_t *d_uv = pPicture->data[1] + (y * pPicture->iLineSize[1]);\n        for (int x = 0; x < (int)pSrc->iWidth/2; x++) {\n          *d_uv++ = *s_u++;\n          *d_uv++ = *s_v++;\n        }\n      }\n      \n    }\n    else\n    {\n  //    CLog::Log(LOGFATAL, \"CDVDCodecUtils::AllocateNV12Picture, unable to allocate new video picture, out of memory.\");\n      delete pPicture;\n      pPicture = NULL;\n    }\n  }\n  return pPicture;\n}\n\nDVDVideoPicture* CDVDCodecUtils::ConvertToYUV422PackedPicture(DVDVideoPicture *pSrc, ERenderFormat format)\n{\n  // Clone a YV12 picture to new YUY2 or UYVY picture.\n  DVDVideoPicture* pPicture = new DVDVideoPicture;\n  if (pPicture)\n  {\n    *pPicture = *pSrc;\n\n    int totalsize = pPicture->iWidth * pPicture->iHeight * 2;\n    uint8_t* data = (uint8_t*) av_malloc(totalsize);\n\n    if (data)\n    {\n      pPicture->data[0] = data;\n      pPicture->data[1] = NULL;\n      pPicture->data[2] = NULL;\n      pPicture->data[3] = NULL;\n      pPicture->iLineSize[0] = pPicture->iWidth * 2;\n      pPicture->iLineSize[1] = 0;\n      pPicture->iLineSize[2] = 0;\n      pPicture->iLineSize[3] = 0;\n      pPicture->format = format;\n\n      //if this is going to be used for anything else than testing the renderer\n      //the library should not be loaded on every function call\n      {\n        // Perform the scaling.\n        uint8_t* src[] =       { pSrc->data[0],          pSrc->data[1],      pSrc->data[2],      NULL };\n        int      srcStride[] = { pSrc->iLineSize[0],     pSrc->iLineSize[1], pSrc->iLineSize[2], 0    };\n        uint8_t* dst[] =       { pPicture->data[0],      NULL,               NULL,               NULL };\n        int      dstStride[] = { pPicture->iLineSize[0], 0,                  0,                  0    };\n\n        int dstformat;\n        if (format == RENDER_FMT_UYVY422)\n          dstformat = AV_PIX_FMT_UYVY422;\n        else\n          dstformat = AV_PIX_FMT_YUYV422;\n\n        struct SwsContext *ctx = sws_getContext(pSrc->iWidth, pSrc->iHeight, AV_PIX_FMT_YUV420P,\n                                                           pPicture->iWidth, pPicture->iHeight, (AVPixelFormat)dstformat,\n                                                           SWS_BILINEAR, NULL, NULL, NULL);\n        sws_scale(ctx, src, srcStride, 0, pSrc->iHeight, dst, dstStride);\n        sws_freeContext(ctx);\n      }\n    }\n    else\n    {\n//      CLog::Log(LOGFATAL, \"CDVDCodecUtils::ConvertToYUY2Picture, unable to allocate new video picture, out of memory.\");\n      delete pPicture;\n      pPicture = NULL;\n    }\n  }\n  return pPicture;\n}\n\nbool CDVDCodecUtils::CopyNV12Picture(YV12Image* pImage, DVDVideoPicture *pSrc)\n{\n  uint8_t *s = pSrc->data[0];\n  uint8_t *d = pImage->plane[0];\n  int w = pSrc->iWidth;\n  int h = pSrc->iHeight;\n  // Copy Y\n  if ((w == pSrc->iLineSize[0]) && ((unsigned int) pSrc->iLineSize[0] == pImage->stride[0]))\n  {\n    memcpy(d, s, w*h);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w);\n      s += pSrc->iLineSize[0];\n      d += pImage->stride[0];\n    }\n  }\n  \n  s = pSrc->data[1];\n  d = pImage->plane[1];\n  w = pSrc->iWidth;\n  h = pSrc->iHeight >> 1;\n  // Copy packed UV (width is same as for Y as it's both U and V components)\n  if ((w==pSrc->iLineSize[1]) && ((unsigned int) pSrc->iLineSize[1]==pImage->stride[1]))\n  {\n    memcpy(d, s, w*h);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w);\n      s += pSrc->iLineSize[1];\n      d += pImage->stride[1];\n    }\n  }\n\n  return true;\n}\n\nbool CDVDCodecUtils::CopyYUV422PackedPicture(YV12Image* pImage, DVDVideoPicture *pSrc)\n{\n  uint8_t *s = pSrc->data[0];\n  uint8_t *d = pImage->plane[0];\n  int w = pSrc->iWidth;\n  int h = pSrc->iHeight;\n\n  // Copy YUYV\n  if ((w * 2 == pSrc->iLineSize[0]) && ((unsigned int) pSrc->iLineSize[0] == pImage->stride[0]))\n  {\n    memcpy(d, s, w*h*2);\n  }\n  else\n  {\n    for (int y = 0; y < h; y++)\n    {\n      memcpy(d, s, w*2);\n      s += pSrc->iLineSize[0];\n      d += pImage->stride[0];\n    }\n  }\n  \n  return true;\n}\n\nbool CDVDCodecUtils::IsVP3CompatibleWidth(int width)\n{\n  // known hardware limitation of purevideo 3 (VP3). (the Nvidia 9400 is a purevideo 3 chip)\n  // from nvidia's linux vdpau README: All current third generation PureVideo hardware\n  // (G98, MCP77, MCP78, MCP79, MCP7A) cannot decode H.264 for the following horizontal resolutions:\n  // 769-784, 849-864, 929-944, 1009–1024, 1793–1808, 1873–1888, 1953–1968 and 2033-2048 pixel.\n  // This relates to the following macroblock sizes.\n  int unsupported[] = {49, 54, 59, 64, 113, 118, 123, 128};\n  for (unsigned int i = 0; i < sizeof(unsupported) / sizeof(int); i++)\n  {\n    if (unsupported[i] == (width + 15) / 16)\n      return false;\n  }\n  return true;\n}\n\ndouble CDVDCodecUtils::NormalizeFrameduration(double frameduration, bool *match)\n{\n  //if the duration is within 20 microseconds of a common duration, use that\n  const double durations[] = {DVD_TIME_BASE * 1.001 / 24.0, DVD_TIME_BASE / 24.0, DVD_TIME_BASE / 25.0,\n                              DVD_TIME_BASE * 1.001 / 30.0, DVD_TIME_BASE / 30.0, DVD_TIME_BASE / 50.0,\n                              DVD_TIME_BASE * 1.001 / 60.0, DVD_TIME_BASE / 60.0};\n\n  double lowestdiff = DVD_TIME_BASE;\n  int    selected   = -1;\n  for (size_t i = 0; i < ARRAY_SIZE(durations); i++)\n  {\n    double diff = fabs(frameduration - durations[i]);\n    if (diff < DVD_MSEC_TO_TIME(0.02) && diff < lowestdiff)\n    {\n      selected = i;\n      lowestdiff = diff;\n    }\n  }\n\n  if (selected != -1)\n  {\n    if (match)\n      *match = true;\n    return durations[selected];\n  }\n  else\n  {\n    if (match)\n      *match = false;\n    return frameduration;\n  }\n}\n\nstruct EFormatMap {\n  AVPixelFormat   pix_fmt;\n  ERenderFormat format;\n};\n\nstatic const EFormatMap g_format_map[] = {\n   { AV_PIX_FMT_YUV420P,     RENDER_FMT_YUV420P    }\n,  { AV_PIX_FMT_YUVJ420P,    RENDER_FMT_YUV420P    }\n,  { AV_PIX_FMT_YUV420P10,   RENDER_FMT_YUV420P10  }\n,  { AV_PIX_FMT_YUV420P16,   RENDER_FMT_YUV420P16  }\n,  { AV_PIX_FMT_UYVY422,     RENDER_FMT_UYVY422    }\n,  { AV_PIX_FMT_YUYV422,     RENDER_FMT_YUYV422    }\n,  { AV_PIX_FMT_VAAPI_VLD,   RENDER_FMT_VAAPI      }\n,  { AV_PIX_FMT_D3D11VA_VLD, RENDER_FMT_DXVA       }\n,  { AV_PIX_FMT_NONE     ,   RENDER_FMT_NONE       }\n};\n\nERenderFormat CDVDCodecUtils::EFormatFromPixfmt(int fmt)\n{\n  for(const EFormatMap *p = g_format_map; p->pix_fmt != AV_PIX_FMT_NONE; ++p)\n  {\n    if(p->pix_fmt == fmt)\n      return p->format;\n  }\n  return RENDER_FMT_NONE;\n}\n\nAVPixelFormat CDVDCodecUtils::PixfmtFromEFormat(ERenderFormat fmt)\n{\n  for(const EFormatMap *p = g_format_map; p->pix_fmt != AV_PIX_FMT_NONE; ++p)\n  {\n    if(p->format == fmt)\n      return p->pix_fmt;\n  }\n  return AV_PIX_FMT_NONE;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/CodecUtils.h",
    "content": "#pragma once\n#include \"VideoCodec.h\"\n#include \"RenderFormats.h\"\n\nextern \"C\" {\n#include \"libavutil/pixfmt.h\"\n}\n\nNS_KRMOVIE_BEGIN\nstruct YV12Image;\n\nclass CDVDCodecUtils\n{\npublic:\n  static DVDVideoPicture* AllocatePicture(int iWidth, int iHeight);\n  static void FreePicture(DVDVideoPicture* pPicture);\n  static bool CopyPicture(DVDVideoPicture* pDst, DVDVideoPicture* pSrc);\n  static bool CopyPicture(YV12Image* pDst, DVDVideoPicture *pSrc);\n  \n  static DVDVideoPicture* ConvertToNV12Picture(DVDVideoPicture *pSrc);\n  static DVDVideoPicture* ConvertToYUV422PackedPicture(DVDVideoPicture *pSrc, ERenderFormat format);\n  static bool CopyNV12Picture(YV12Image* pImage, DVDVideoPicture *pSrc);\n  static bool CopyYUV422PackedPicture(YV12Image* pImage, DVDVideoPicture *pSrc);\n\n  static bool IsVP3CompatibleWidth(int width);\n\n  static double NormalizeFrameduration(double frameduration, bool *match = NULL);\n\n  static ERenderFormat EFormatFromPixfmt(int fmt);\n  static AVPixelFormat PixfmtFromEFormat(ERenderFormat format);\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Codecs.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n  #include \"config.h\"\n#endif\n\n#include \"RenderFormats.h\"\n#include <string>\n\nNS_KRMOVIE_BEGIN\n// 0x100000 is the video starting range\n\n// 0x200000 is the audio starting range\n\n// special options that can be passed to a codec\nclass CDVDCodecOption\n{\npublic:\n  CDVDCodecOption(const std::string& name, const std::string& value) : m_name(name), m_value(value) {}\n  std::string m_name;\n  std::string m_value;\n};\n\nclass CDVDCodecOptions\n{\npublic:\n  std::vector<CDVDCodecOption> m_keys;\n  std::vector<ERenderFormat> m_formats;\n  const void *m_opaque_pointer;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Demux.cpp",
    "content": "#include \"Demux.h\"\n\nNS_KRMOVIE_BEGIN\nint64_t IDemux::NewGuid()\n{\n\tstatic int64_t guid = 0;\n\treturn guid++;\n}\n\nstd::string CDemuxStreamAudio::GetStreamType()\n{\n\tswitch (iChannels) {\n\tcase 1: return \"Mono\";\n\tcase 2: return \"Stereo\";\n\tcase 6: return \"5.1\";\n\tcase 8: return \"7.1\";\n\tdefault: return \"\";\n\t}\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/Demux.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n#include <vector>\n#include <string>\n\nNS_KRMOVIE_BEGIN\nenum StreamType\n{\n\tSTREAM_NONE = 0,// if unknown\n\tSTREAM_AUDIO,   // audio stream\n\tSTREAM_VIDEO,   // video stream\n\tSTREAM_DATA,    // data stream\n// \tSTREAM_SUBTITLE,// subtitle stream\n// \tSTREAM_TELETEXT, // Teletext data stream\n// \tSTREAM_RADIO_RDS // Radio RDS data stream\n};\n\nenum StreamSource {\n\tSTREAM_SOURCE_NONE = 0x000,\n\tSTREAM_SOURCE_DEMUX = 0x100,\n// \tSTREAM_SOURCE_NAV = 0x200,\n// \tSTREAM_SOURCE_DEMUX_SUB = 0x300,\n\tSTREAM_SOURCE_TEXT = 0x400,\n\tSTREAM_SOURCE_VIDEOMUX = 0x500\n};\n\n#define STREAM_SOURCE_MASK(a) ((a) & 0xf00)\n\nclass CDemuxStream\n{\npublic:\n\tCDemuxStream()\n\t{\n\t\tuniqueId = 0;\n\t\tdvdNavId = 0;\n\t\tdemuxerId = -1;\n\t\tcodec = (AVCodecID)0; // AV_CODEC_ID_NONE\n\t\tcodec_fourcc = 0;\n\t\tprofile = FF_PROFILE_UNKNOWN;\n\t\tlevel = FF_LEVEL_UNKNOWN;\n\t\ttype = STREAM_NONE;\n\t\tsource = STREAM_SOURCE_NONE;\n\t\tiDuration = 0;\n\t\tpPrivate = NULL;\n\t\tExtraData = NULL;\n\t\tExtraSize = 0;\n\t\tmemset(language, 0, sizeof(language));\n\t\tdisabled = false;\n\t\tchanges = 0;\n\t\tflags = FLAG_NONE;\n\t\trealtime = false;\n\t\tbandwidth = 0;\n\t}\n\n\tvirtual ~CDemuxStream()\n\t{\n\t\tdelete[] ExtraData;\n\t}\n\n\tvirtual std::string GetStreamName() { return \"\"; }\n\n\tint uniqueId;          // unique stream id\n\tint dvdNavId;\n\tint64_t demuxerId; // id of the associated demuxer\n\tAVCodecID codec;\n\tunsigned int codec_fourcc; // if available\n\tint profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders.\n\tint level;   // encoder level of the stream reported by the decoder. used to qualify hw decoders.\n\tStreamType type;\n\tint source;\n\tbool realtime;\n\tunsigned int bandwidth;\n\n\tint iDuration; // in mseconds\n\tvoid* pPrivate; // private pointer for the demuxer\n\tuint8_t*     ExtraData; // extra data for codec to use\n\tunsigned int ExtraSize; // size of extra data\n\n\tchar language[4]; // ISO 639 3-letter language code (empty string if undefined)\n\tbool disabled; // set when stream is disabled. (when no decoder exists)\n\n\tstd::string codecName;\n\n\tint  changes; // increment on change which player may need to know about\n\n\tenum EFlags\n\t{\n\t\tFLAG_NONE = 0x0000\n\t\t, FLAG_DEFAULT = 0x0001\n\t\t, FLAG_DUB = 0x0002\n\t\t, FLAG_ORIGINAL = 0x0004\n\t\t, FLAG_COMMENT = 0x0008\n\t\t, FLAG_LYRICS = 0x0010\n\t\t, FLAG_KARAOKE = 0x0020\n\t\t, FLAG_FORCED = 0x0040\n\t\t, FLAG_HEARING_IMPAIRED = 0x0080\n\t\t, FLAG_VISUAL_IMPAIRED = 0x0100\n\t} flags;\n};\n\nclass CDemuxStreamVideo : public CDemuxStream\n{\npublic:\n\tCDemuxStreamVideo() : CDemuxStream()\n\t{\n\t\tiFpsScale = 0;\n\t\tiFpsRate = 0;\n\t\tiHeight = 0;\n\t\tiWidth = 0;\n\t\tfAspect = 0.0;\n\t\tbVFR = false;\n\t\tbPTSInvalid = false;\n\t\tbForcedAspect = false;\n\t\ttype = STREAM_VIDEO;\n\t\tiOrientation = 0;\n\t\tiBitsPerPixel = 0;\n\t}\n\n\tvirtual ~CDemuxStreamVideo() {}\n\tint iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps\n\tint iFpsRate;\n\tint iHeight; // height of the stream reported by the demuxer\n\tint iWidth; // width of the stream reported by the demuxer\n\tfloat fAspect; // display aspect of stream\n\tbool bVFR;  // variable framerate\n\tbool bPTSInvalid; // pts cannot be trusted (avi's).\n\tbool bForcedAspect; // aspect is forced from container\n\tint iOrientation; // orientation of the video in degress counter clockwise\n\tint iBitsPerPixel;\n\tstd::string stereo_mode; // expected stereo mode\n};\n\nclass CDemuxStreamAudio : public CDemuxStream\n{\npublic:\n\tCDemuxStreamAudio() : CDemuxStream()\n\t{\n\t\tiChannels = 0;\n\t\tiSampleRate = 0;\n\t\tiBlockAlign = 0;\n\t\tiBitRate = 0;\n\t\tiBitsPerSample = 0;\n\t\tiChannelLayout = 0;\n\t\ttype = STREAM_AUDIO;\n\t}\n\n\tvirtual ~CDemuxStreamAudio() {}\n\n\tstd::string GetStreamType();\n\n\tint iChannels;\n\tint iSampleRate;\n\tint iBlockAlign;\n\tint iBitRate;\n\tint iBitsPerSample;\n\tuint64_t iChannelLayout;\n};\n\nstruct DemuxPacket;\nclass IDemux {\npublic:\n\tIDemux() : m_demuxerId(NewGuid()) {}\n\tvirtual ~IDemux() {}\n\tvirtual void Reset() = 0;\n\t/*\n\t* Aborts any internal reading that might be stalling main thread\n\t* NOTICE - this can be called from another thread\n\t*/\n\tvirtual void Abort() = 0;\n\tvirtual void Flush() = 0;\n\tvirtual DemuxPacket* Read() = 0;\n\tvirtual bool SeekTime(int time, bool backwords = false, double* startpts = NULL) = 0;\n\tvirtual void SetSpeed(int iSpeed) = 0;\n\tvirtual int GetStreamLength() = 0;\n\tvirtual CDemuxStream* GetStream(int64_t demuxerId, int iStreamId) const { return GetStream(iStreamId); };\n\tvirtual std::vector<CDemuxStream*> GetStreams() const = 0;\n\tvirtual int GetNrOfStreams() const = 0;\n\tvirtual std::string GetStreamCodecName(int64_t demuxerId, int iStreamId) { return GetStreamCodecName(iStreamId); };\n\tvirtual void EnableStream(int64_t demuxerId, int id, bool enable) { EnableStream(id, enable); };\n\tvirtual void SetVideoResolution(int width, int height) {};\n\tint64_t GetDemuxerId() { return m_demuxerId; };\nprotected:\n\tvirtual void EnableStream(int id, bool enable) {};\n\tvirtual CDemuxStream* GetStream(int iStreamId) const = 0;\n\tvirtual std::string GetStreamCodecName(int iStreamId) { return \"\"; };\n\tint GetNrOfStreams(StreamType streamType);\n\tint64_t m_demuxerId;\nprivate:\n\tint64_t NewGuid();\n};\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/DemuxFFmpeg.cpp",
    "content": "#include \"DemuxFFmpeg.h\"\nextern \"C\" {\n#include \"libavutil/dict.h\"\n#include \"libavutil/opt.h\"\n}\n#include \"Clock.h\"\n#include \"DemuxPacket.h\"\n#include <algorithm>\n#include \"InputStream.h\"\nNS_KRMOVIE_BEGIN\n\nstruct StereoModeConversionMap\n{\n\tconst char*          name;\n\tconst char*          mode;\n};\n\n// we internally use the matroska string representation of stereoscopic modes.\n// This struct is a conversion map to convert stereoscopic mode values\n// from asf/wmv to the internally used matroska ones\nstatic const struct StereoModeConversionMap WmvToInternalStereoModeMap[] =\n{\n\t{ \"SideBySideRF\", \"right_left\" },\n\t{ \"SideBySideLF\", \"left_right\" },\n\t{ \"OverUnderRT\", \"bottom_top\" },\n\t{ \"OverUnderLT\", \"top_bottom\" },\n\t{}\n};\n\n#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE)\n#define FFMPEG_FILE_BUFFER_SIZE   32768 // default reading size for ffmpeg\n\nstd::string CDemuxStreamAudioFFmpeg::GetStreamName()\n{\n\tif (!m_stream)\n\t\treturn \"\";\n\tif (!m_description.empty())\n\t\treturn m_description;\n\telse\n\t\treturn CDemuxStream::GetStreamName();\n}\n\nstd::string CDemuxStreamVideoFFmpeg::GetStreamName()\n{\n\tif (!m_stream)\n\t\treturn \"\";\n\tif (!m_description.empty())\n\t\treturn m_description;\n\telse\n\t\treturn CDemuxStream::GetStreamName();\n}\n\nstatic int interrupt_cb(void* ctx)\n{\n\tCDVDDemuxFFmpeg* demuxer = static_cast<CDVDDemuxFFmpeg*>(ctx);\n\tif (demuxer && demuxer->Aborted())\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int dvd_file_read(void *h, uint8_t* buf, int size)\n{\n\tif (interrupt_cb(h))\n\t\treturn AVERROR_EXIT;\n\n\tInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;\n\treturn pInputStream->Read(buf, size);\n}\n\nstatic int64_t dvd_file_seek(void *h, int64_t pos, int whence)\n{\n\tif (interrupt_cb(h))\n\t\treturn AVERROR_EXIT;\n\n\tInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;\n\tif (whence == AVSEEK_SIZE) {\n\t\treturn pInputStream->GetLength();\n\t} else {\n\t\treturn pInputStream->Seek(pos, whence & ~AVSEEK_FORCE);\n\t}\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////////\n\nCDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : IDemux()\n{\n\tm_pFormatContext = NULL;\n\tm_ioContext = NULL;\n\tm_currentPts = DVD_NOPTS_VALUE;\n\tm_bMatroska = false;\n\tm_bAVI = false;\n\tm_speed = DVD_PLAYSPEED_NORMAL;\n\tm_program = UINT_MAX;\n\tm_pkt.result = -1;\n\tmemset(&m_pkt.pkt, 0, sizeof(AVPacket));\n\tm_streaminfo = true; /* set to true if we want to look for streams before playback */\n\tm_checkvideo = false;\n}\n\n\nCDVDDemuxFFmpeg::~CDVDDemuxFFmpeg()\n{\n\tDispose();\n//\tff_flush_avutil_log_buffers();\n}\n\nbool CDVDDemuxFFmpeg::Aborted()\n{\n\tif (m_timeout.IsTimePast())\n\t\treturn true;\n\n// \tCDVDInputStreamFFmpeg * input = dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput);\n// \tif (input && input->Aborted())\n// \t\treturn true;\n\n\treturn false;\n}\n\nbool CDVDDemuxFFmpeg::Open(InputStream* pInput, bool streaminfo, bool fileinfo)\n{\n\tAVInputFormat* iformat = NULL;\n\tm_streaminfo = streaminfo;\n\tm_currentPts = DVD_NOPTS_VALUE;\n\tm_speed = DVD_PLAYSPEED_NORMAL;\n\tm_program = UINT_MAX;\n\n\tconst AVIOInterruptCB int_cb = { interrupt_cb, this };\n\n\tif (!pInput) return false;\n\n\tm_pInput = pInput;\n\tm_pInput->AddRef();\n\tconst std::string & strFile = pInput->GetFileName();\n\t\n\t// open the demuxer\n\tm_pFormatContext = avformat_alloc_context();\n\tm_pFormatContext->interrupt_callback = int_cb;\n\n\t// try to abort after 30 seconds\n\tm_timeout.Set(30000);\n#if 0\n\tif (m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG))\n\t{\n\t\t// special stream type that makes avformat handle file opening\n\t\t// allows internal ffmpeg protocols to be used\n\t\tAVDictionary *options = GetFFMpegOptionsFromInput();\n\n\t\tCURL url = m_pInput->GetURL();\n\n\t\tint result = -1;\n\t\tif (url.IsProtocol(\"mms\"))\n\t\t{\n\t\t\t// try mmsh, then mmst\n\t\t\turl.SetProtocol(\"mmsh\");\n\t\t\turl.SetProtocolOptions(\"\");\n\t\t\tresult = avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options);\n\t\t\tif (result < 0)\n\t\t\t{\n\t\t\t\turl.SetProtocol(\"mmst\");\n\t\t\t\tstrFile = url.Get();\n\t\t\t}\n\t\t}\n\t\tif (result < 0 && avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0)\n\t\t{\n\t\t\tCLog::Log(LOGDEBUG, \"Error, could not open file %s\", CURL::GetRedacted(strFile).c_str());\n\t\t\tDispose();\n\t\t\tav_dict_free(&options);\n\t\t\treturn false;\n\t\t}\n\t\tav_dict_free(&options);\n\t} else\n#endif\n\t{\n\t\tunsigned char* buffer = (unsigned char*)av_malloc(FFMPEG_FILE_BUFFER_SIZE);\n\t\tm_ioContext = avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek);\n// \t\tm_ioContext->max_packet_size = m_pInput->GetBlockSize();\n// \t\tif (m_ioContext->max_packet_size)\n// \t\t\tm_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size;\n\n// \t\tif (!m_pInput->Seek(pos, SEEK_POSSIBLE))\n// \t\t\tm_ioContext->seekable = 0;\n\n\t\tif (iformat == NULL)\n\t\t{\n\t\t\t// let ffmpeg decide which demuxer we have to open\n\t\t\tav_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0);\n\n\t\t\t// Use the more low-level code in case we have been built against an old\n\t\t\t// FFmpeg without the above av_probe_input_buffer(), or in case we only\n\t\t\t// want to probe for spdif (DTS or IEC 61937) compressed audio\n\t\t\t// specifically, or in case the file is a wav which may contain DTS or\n\t\t\t// IEC 61937 (e.g. ac3-in-wav) and we want to check for those formats.\n\t\t\tif ((iformat && strcmp(iformat->name, \"wav\") == 0))\n\t\t\t{\n\t\t\t\tAVProbeData pd;\n\t\t\t\tuint8_t probe_buffer[FFMPEG_FILE_BUFFER_SIZE + AVPROBE_PADDING_SIZE];\n\n\t\t\t\t// init probe data\n\t\t\t\tpd.buf = probe_buffer;\n\t\t\t\tpd.filename = strFile.c_str();\n\n\t\t\t\t// av_probe_input_buffer might have changed the buffer_size beyond our allocated amount\n\t\t\t\tint buffer_size = std::min((int)FFMPEG_FILE_BUFFER_SIZE, m_ioContext->buffer_size);\n\t\t\t\tbuffer_size = m_ioContext->max_packet_size ? m_ioContext->max_packet_size : buffer_size;\n\t\t\t\t// read data using avformat's buffers\n\t\t\t\tpd.buf_size = avio_read(m_ioContext, pd.buf, buffer_size);\n\t\t\t\tif (pd.buf_size <= 0)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tmemset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);\n\n\t\t\t\t// restore position again\n\t\t\t\tavio_seek(m_ioContext, 0, SEEK_SET);\n\n\t\t\t\t// the advancedsetting is for allowing the user to force outputting the\n\t\t\t\t// 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode\n\t\t\t\t// it (this is temporary until we handle 44.1 kHz passthrough properly)\n\t\t\t\tif ( (iformat && strcmp(iformat->name, \"wav\") == 0 ))\n\t\t\t\t{\n\t\t\t\t\t// check for spdif and dts\n\t\t\t\t\t// This is used with wav files and audio CDs that may contain\n\t\t\t\t\t// a DTS or AC3 track padded for S/PDIF playback. If neither of those\n\t\t\t\t\t// is present, we assume it is PCM audio.\n\t\t\t\t\t// AC3 is always wrapped in iec61937 (ffmpeg \"spdif\"), while DTS\n\t\t\t\t\t// may be just padded.\n\t\t\t\t\tAVInputFormat *iformat2;\n\t\t\t\t\tiformat2 = av_find_input_format(\"spdif\");\n\n\t\t\t\t\tif (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)\n\t\t\t\t\t{\n\t\t\t\t\t\tiformat = iformat2;\n\t\t\t\t\t} else\n\t\t\t\t\t{\n\t\t\t\t\t\t// not spdif or no spdif demuxer, try dts\n\t\t\t\t\t\tiformat2 = av_find_input_format(\"dts\");\n\n\t\t\t\t\t\tif (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tiformat = iformat2;\n// \t\t\t\t\t\t} else if (trySPDIFonly)\n// \t\t\t\t\t\t{\n// \t\t\t\t\t\t\t// not dts either, return false in case we were explicitely\n// \t\t\t\t\t\t\t// requested to only check for S/PDIF padded compressed audio\n// \t\t\t\t\t\t\tCLog::Log(LOGDEBUG, \"%s - not spdif or dts file, fallbacking\", __FUNCTION__);\n// \t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!iformat)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGERROR, \"%s - error probing input format, %s\", __FUNCTION__, CURL::GetRedacted(strFile).c_str());\n\t\t\t\treturn false;\n\t\t\t} else\n\t\t\t{\n// \t\t\t\tif (iformat->name)\n// \t\t\t\t\tCLog::Log(LOGDEBUG, \"%s - probing detected format [%s]\", __FUNCTION__, iformat->name);\n// \t\t\t\telse\n// \t\t\t\t\tCLog::Log(LOGDEBUG, \"%s - probing detected unnamed format\", __FUNCTION__);\n\t\t\t}\n\t\t}\n\n\n\t\tm_pFormatContext->pb = m_ioContext;\n\n\t\tAVDictionary *options = NULL;\n\t\tif (iformat->name && (strcmp(iformat->name, \"mp3\") == 0 || strcmp(iformat->name, \"mp2\") == 0))\n\t\t{\n//\t\t\tCLog::Log(LOGDEBUG, \"%s - setting usetoc to 0 for accurate VBR MP3 seek\", __FUNCTION__);\n\t\t\tav_dict_set(&options, \"usetoc\", \"0\", 0);\n\t\t}\n\n// \t\tif (StringUtils::StartsWith(content, \"audio/l16\"))\n// \t\t{\n// \t\t\tint channels = 2;\n// \t\t\tint samplerate = 44100;\n// \t\t\tGetL16Parameters(channels, samplerate);\n// \t\t\tav_dict_set_int(&options, \"channels\", channels, 0);\n// \t\t\tav_dict_set_int(&options, \"sample_rate\", samplerate, 0);\n// \t\t}\n\n\t\tif (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0)\n\t\t{\n//\t\t\tCLog::Log(LOGERROR, \"%s - Error, could not open file %s\", __FUNCTION__, CURL::GetRedacted(strFile).c_str());\n\t\t\tDispose();\n\t\t\tav_dict_free(&options);\n\t\t\treturn false;\n\t\t}\n\t\tav_dict_free(&options);\n\t}\n\n\t// Avoid detecting framerate if advancedsettings.xml says so\n// \tif (g_advancedSettings.m_videoFpsDetect == 0)\n// \t\tm_pFormatContext->fps_probe_size = 0;\n\n\t// analyse very short to speed up mjpeg playback start\n\tif (iformat && (strcmp(iformat->name, \"mjpeg\") == 0) && m_ioContext->seekable == 0)\n\t\tav_opt_set_int(m_pFormatContext, \"analyzeduration\", 500000, 0);\n\n\tbool skipCreateStreams = false;\n//\tbool isBluray = pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY);\n\tif (iformat && (strcmp(iformat->name, \"mpegts\") == 0) && !fileinfo /*&& !isBluray*/)\n\t{\n\t\tav_opt_set_int(m_pFormatContext, \"analyzeduration\", 500000, 0);\n\t\tm_checkvideo = true;\n\t\tskipCreateStreams = true;\n\t} else if (!iformat || (strcmp(iformat->name, \"mpegts\") != 0))\n\t{\n\t\tm_streaminfo = true;\n\t}\n\n// \tif (iformat && (strcmp(iformat->name, \"mov,mp4,m4a,3gp,3g2,mj2\") == 0))\n// \t{\n// \t\tif (URIUtils::IsRemote(strFile))\n// \t\t\tm_pFormatContext->iformat->flags |= AVFMT_NOGENSEARCH;\n// \t}\n\n\t// we need to know if this is matroska or avi later\n\tm_bMatroska = strncmp(m_pFormatContext->iformat->name, \"matroska\", 8) == 0;\t// for \"matroska.webm\"\n\tm_bAVI = strcmp(m_pFormatContext->iformat->name, \"avi\") == 0;\n\n\tif (m_streaminfo)\n\t{\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t\t{\n\t\t\tAVStream *st = m_pFormatContext->streams[i];\n\t\t\tif (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_DTS)\n\t\t\t{\n\t\t\t\tAVCodec* pCodec = avcodec_find_decoder_by_name(\"dcadec\");\n\t\t\t\tif (pCodec)\n\t\t\t\t\tst->codec->codec = pCodec;\n\t\t\t}\n\t\t}\n\t\t/* to speed up dvd switches, only analyse very short */\n// \t\tif (m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD))\n// \t\t\tav_opt_set_int(m_pFormatContext, \"analyzeduration\", 500000, 0);\n\n\t//\tCLog::Log(LOGDEBUG, \"%s - avformat_find_stream_info starting\", __FUNCTION__);\n\t\tint iErr = avformat_find_stream_info(m_pFormatContext, NULL);\n\t\tif (iErr < 0)\n\t\t{\n\t\t//\tCLog::Log(LOGWARNING, \"could not find codec parameters for %s\", CURL::GetRedacted(strFile).c_str());\n\t\t\tif (\n// \t\t\t\tm_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)\n// \t\t\t\t|| m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) ||\n\t\t\t\t(m_pFormatContext->nb_streams == 1 && m_pFormatContext->streams[0]->codec->codec_id == AV_CODEC_ID_AC3)\n\t\t\t\t|| m_checkvideo)\n\t\t\t{\n\t\t\t\t// special case, our codecs can still handle it.\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDispose();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t//\tCLog::Log(LOGDEBUG, \"%s - av_find_stream_info finished\", __FUNCTION__);\n\n\t\tif (m_checkvideo)\n\t\t{\n\t\t\t// make sure we start video with an i-frame\n\t\t\tResetVideoStreams();\n\t\t}\n\t}\n\telse\n\t{\n\t\tm_program = 0;\n\t\tm_checkvideo = true;\n\t\tskipCreateStreams = true;\n\t}\n\n\t// reset any timeout\n\tm_timeout.SetInfinite();\n\n\t// if format can be nonblocking, let's use that\n\tm_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;\n\n\t// print some extra information\n\tav_dump_format(m_pFormatContext, 0, strFile.c_str(), 0);\n\n\tUpdateCurrentPTS();\n\n\t// in case of mpegts and we have not seen pat/pmt, defer creation of streams\n\tif (!skipCreateStreams || m_pFormatContext->nb_programs > 0)\n\t{\n\t\tunsigned int nProgram(~0);\n\t\tif (m_pFormatContext->nb_programs > 0)\n\t\t{\n\n\t\t\t// select the corrrect program if requested\n// \t\t\tCVariant programProp(pInput->GetProperty(\"program\"));\n// \t\t\tif (!programProp.isNull())\n// \t\t\t{\n// \t\t\t\tint programNumber = programProp.asInteger();\n// \n// \t\t\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_programs; ++i)\n// \t\t\t\t{\n// \t\t\t\t\tif (m_pFormatContext->programs[i]->program_num == programNumber)\n// \t\t\t\t\t{\n// \t\t\t\t\t\tnProgram = i;\n// \t\t\t\t\t\tbreak;\n// \t\t\t\t\t}\n// \t\t\t\t}\n// \t\t\t}\n\t\t}\n\t\tCreateStreams(nProgram);\n\t}\n\n\t// allow IsProgramChange to return true\n\tif (skipCreateStreams && GetNrOfStreams() == 0)\n\t\tm_program = 0;\n\n\tm_displayTime = 0;\n\tm_dtsAtDisplayTime = DVD_NOPTS_VALUE;\n\n\treturn true;\n}\n\nvoid CDVDDemuxFFmpeg::Dispose()\n{\n\tm_pkt.result = -1;\n\tav_packet_unref(&m_pkt.pkt);\n\n\tif (m_pFormatContext)\n\t{\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t\t{\n\t\t\tavcodec_close(m_pFormatContext->streams[i]->codec);\n\t\t}\n\n\t\tif (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext)\n\t\t{\n\t\t//\tCLog::Log(LOGWARNING, \"CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak\");\n\t\t\tm_ioContext = m_pFormatContext->pb;\n\t\t}\n\t\tavformat_close_input(&m_pFormatContext);\n\t}\n\n\tif (m_ioContext)\n\t{\n\t\tav_free(m_ioContext->buffer);\n\t\tav_free(m_ioContext);\n\t}\n\n\tm_ioContext = NULL;\n\tm_pFormatContext = NULL;\n\tm_speed = DVD_PLAYSPEED_NORMAL;\n\n\tDisposeStreams();\n\n\tSAFE_RELEASE(m_pInput);\n}\n\nvoid CDVDDemuxFFmpeg::Reset()\n{\n\tInputStream* pInputStream = m_pInput;\n\tpInputStream->AddRef();\n\tDispose();\n\tOpen(pInputStream, m_streaminfo);\n\tpInputStream->Release();\n}\n\nvoid CDVDDemuxFFmpeg::Flush()\n{\n\tif (m_pFormatContext)\n\t{\n\t\tif (m_pFormatContext->pb)\n\t\t\tavio_flush(m_pFormatContext->pb);\n\t\tavformat_flush(m_pFormatContext);\n\t}\n\n\tm_currentPts = DVD_NOPTS_VALUE;\n\n\tm_pkt.result = -1;\n\tav_packet_unref(&m_pkt.pkt);\n\n\tm_displayTime = 0;\n\tm_dtsAtDisplayTime = DVD_NOPTS_VALUE;\n}\n\nvoid CDVDDemuxFFmpeg::Abort()\n{\n\tm_timeout.SetExpired();\n}\n\nvoid CDVDDemuxFFmpeg::SetSpeed(int iSpeed)\n{\n\tif (!m_pFormatContext)\n\t\treturn;\n\n\tif (m_speed == iSpeed)\n\t\treturn;\n\n\tif (m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE)\n\t{\n//\t\tm_pInput->Pause(m_currentPts);\n\t\tav_read_pause(m_pFormatContext);\n\t} else if (m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE)\n\t{\n//\t\tm_pInput->Pause(m_currentPts);\n\t\tav_read_play(m_pFormatContext);\n\t}\n\tm_speed = iSpeed;\n\n\tAVDiscard discard = AVDISCARD_NONE;\n\tif (m_speed > 4 * DVD_PLAYSPEED_NORMAL)\n\t\tdiscard = AVDISCARD_NONKEY;\n\telse if (m_speed > 2 * DVD_PLAYSPEED_NORMAL)\n\t\tdiscard = AVDISCARD_BIDIR;\n\telse if (m_speed < DVD_PLAYSPEED_PAUSE)\n\t\tdiscard = AVDISCARD_NONKEY;\n\n\n\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t{\n\t\tif (m_pFormatContext->streams[i])\n\t\t{\n\t\t\tif (m_pFormatContext->streams[i]->discard != AVDISCARD_ALL)\n\t\t\t\tm_pFormatContext->streams[i]->discard = discard;\n\t\t}\n\t}\n}\n\nAVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput()\n{\n\tAVDictionary *options = nullptr;\n#if 0\n\tconst CDVDInputStreamFFmpeg *const input =\n\t\tdynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput);\n\n\tCURL url = m_pInput->GetURL();\n\n\tif (url.IsProtocol(\"http\") || url.IsProtocol(\"https\"))\n\t{\n\t\tstd::map<std::string, std::string> protocolOptions;\n\t\turl.GetProtocolOptions(protocolOptions);\n\t\tstd::string headers;\n\t\tbool hasUserAgent = false;\n\t\tbool hasCookies = false;\n\t\tfor (std::map<std::string, std::string>::const_iterator it = protocolOptions.begin(); it != protocolOptions.end(); ++it)\n\t\t{\n\t\t\tstd::string name = it->first;\n\t\t\tStringUtils::ToLower(name);\n\t\t\tconst std::string &value = it->second;\n\n\t\t\tif (name == \"seekable\")\n\t\t\t\tav_dict_set(&options, \"seekable\", value.c_str(), 0);\n\t\t\t// map some standard http headers to the ffmpeg related options\n\t\t\telse if (name == \"user-agent\")\n\t\t\t{\n\t\t\t\tav_dict_set(&options, \"user-agent\", value.c_str(), 0);\n\t\t\t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() adding ffmpeg option 'user-agent: %s'\", value.c_str());\n\t\t\t\thasUserAgent = true;\n\t\t\t} else if (name == \"cookie\")\n\t\t\t{\n\t\t\t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() adding ffmpeg option 'cookies: %s'\", value.c_str());\n\t\t\t\theaders.append(it->first).append(\": \").append(value).append(\"\\r\\n\");\n\t\t\t\thasCookies = true;\n\t\t\t}\n\t\t\t// other standard headers (see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) are appended as actual headers\n\t\t\telse if (name == \"accept\" || name == \"accept-language\" || name == \"accept-datetime\" ||\n\t\t\t\tname == \"authorization\" || name == \"cache-control\" || name == \"connection\" || name == \"content-md5\" ||\n\t\t\t\tname == \"date\" || name == \"expect\" || name == \"forwarded\" || name == \"from\" || name == \"if-match\" ||\n\t\t\t\tname == \"if-modified-since\" || name == \"if-none-match\" || name == \"if-range\" || name == \"if-unmodified-since\" ||\n\t\t\t\tname == \"max-forwards\" || name == \"origin\" || name == \"pragma\" || name == \"range\" || name == \"referer\" ||\n\t\t\t\tname == \"te\" || name == \"upgrade\" || name == \"via\" || name == \"warning\" || name == \"x-requested-with\" ||\n\t\t\t\tname == \"dnt\" || name == \"x-forwarded-for\" || name == \"x-forwarded-host\" || name == \"x-forwarded-proto\" ||\n\t\t\t\tname == \"front-end-https\" || name == \"x-http-method-override\" || name == \"x-att-deviceid\" ||\n\t\t\t\tname == \"x-wap-profile\" || name == \"x-uidh\" || name == \"x-csrf-token\" || name == \"x-request-id\" ||\n\t\t\t\tname == \"x-correlation-id\")\n\t\t\t{\n\t\t\t\tif (name == \"authorization\")\n\t\t\t\t{\n\t\t\t\t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() adding custom header option '%s: ***********'\", it->first.c_str());\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() adding custom header option '%s: %s'\", it->first.c_str(), value.c_str());\n\t\t\t\t}\n\t\t\t\theaders.append(it->first).append(\": \").append(value).append(\"\\r\\n\");\n\t\t\t}\n\t\t\t// we don't add blindly all options to headers anymore\n\t\t\t// if anybody wants to pass options to ffmpeg, explicitly prefix those\n\t\t\t// to be identified here\n\t\t\telse\n\t\t\t{\n\t\t\t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() ignoring header option '%s: %s'\", it->first.c_str(), value.c_str());\n\t\t\t}\n\t\t}\n\t\tif (!hasUserAgent)\n\t\t{\n\t\t\t// set default xbmc user-agent.\n\t\t\tav_dict_set(&options, \"user-agent\", g_advancedSettings.m_userAgent.c_str(), 0);\n\t\t}\n\n\t\tif (!headers.empty())\n\t\t\tav_dict_set(&options, \"headers\", headers.c_str(), 0);\n\n\t\tif (!hasCookies)\n\t\t{\n\t\t\tstd::string cookies;\n\t\t\tif (XFILE::CCurlFile::GetCookies(url, cookies))\n\t\t\t\tav_dict_set(&options, \"cookies\", cookies.c_str(), 0);\n\t\t}\n\t}\n\n\tif (input)\n\t{\n\t\tconst std::string host = input->GetProxyHost();\n\t\tif (!host.empty() && input->GetProxyType() == \"http\")\n\t\t{\n\t\t\tstd::ostringstream urlStream;\n\n\t\t\tconst uint16_t port = input->GetProxyPort();\n\t\t\tconst std::string user = input->GetProxyUser();\n\t\t\tconst std::string password = input->GetProxyPassword();\n\n\t\t\turlStream << \"http://\";\n\n\t\t\tif (!user.empty()) {\n\t\t\t\turlStream << user;\n\t\t\t\tif (!password.empty())\n\t\t\t\t\turlStream << \":\" << password;\n\t\t\t\turlStream << \"@\";\n\t\t\t}\n\n\t\t\turlStream << host << ':' << port;\n\n\t\t\tav_dict_set(&options, \"http_proxy\", urlStream.str().c_str(), 0);\n\t\t}\n\n\t\t// rtmp options\n\t\tif (url.IsProtocol(\"rtmp\") || url.IsProtocol(\"rtmpt\") ||\n\t\t\turl.IsProtocol(\"rtmpe\") || url.IsProtocol(\"rtmpte\") ||\n\t\t\turl.IsProtocol(\"rtmps\"))\n\t\t{\n\t\t\tstatic const std::map<std::string, std::string> optionmap =\n\t\t\t{ { { \"SWFPlayer\", \"rtmp_swfurl\" },\n\t\t\t{ \"PageURL\", \"rtmp_pageurl\" },\n\t\t\t{ \"PlayPath\", \"rtmp_playpath\" },\n\t\t\t{ \"TcUrl\", \"rtmp_tcurl\" },\n\t\t\t{ \"IsLive\", \"rtmp_live\" },\n\t\t\t{ \"playpath\", \"rtmp_playpath\" },\n\t\t\t{ \"swfurl\", \"rtmp_swfurl\" },\n\t\t\t{ \"swfvfy\", \"rtmp_swfverify\" },\n\t\t\t\t} };\n\n\t\t\tfor (const auto& it : optionmap)\n\t\t\t{\n\t\t\t\tif (input->GetItem().HasProperty(it.first))\n\t\t\t\t{\n\t\t\t\t\tav_dict_set(&options, it.second.c_str(),\n\t\t\t\t\t\tinput->GetItem().GetProperty(it.first).asString().c_str(), 0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tCURL tmpUrl = url;\n\t\t\tstd::vector<std::string> opts = StringUtils::Split(tmpUrl.Get(), \" \");\n\t\t\tif (opts.size() > 1) // inline rtmp options\n\t\t\t{\n\t\t\t\tstd::string swfurl;\n\t\t\t\tbool swfvfy = false;\n\t\t\t\tfor (size_t i = 1; i < opts.size(); ++i)\n\t\t\t\t{\n\t\t\t\t\tstd::vector<std::string> value = StringUtils::Split(opts[i], \"=\");\n\t\t\t\t\tauto it = optionmap.find(value[0]);\n\t\t\t\t\tif (it != optionmap.end())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value[0] == \"swfurl\" || value[0] == \"SWFPlayer\")\n\t\t\t\t\t\t\tswfurl = value[1];\n\t\t\t\t\t\tif (value[0] == \"swfvfy\" && value[1] == \"true\")\n\t\t\t\t\t\t\tswfvfy = true;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tav_dict_set(&options, it->second.c_str(), value[1].c_str(), 0);\n\t\t\t\t\t}\n\t\t\t\t\tif (swfvfy)\n\t\t\t\t\t\tav_dict_set(&options, \"rtmp_swfverify\", swfurl.c_str(), 0);\n\t\t\t\t}\n\t\t\t\ttmpUrl = CURL(opts.front());\n\t\t\t}\n\t\t}\n\t}\n#endif\n\treturn options;\n}\n\ndouble CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num)\n{\n\tif (pts == (int64_t)AV_NOPTS_VALUE)\n\t\treturn DVD_NOPTS_VALUE;\n\n\t// do calculations in floats as they can easily overflow otherwise\n\t// we don't care for having a completly exact timestamp anyway\n\tdouble timestamp = (double)pts * num / den;\n\tdouble starttime = 0.0f;\n\n//\tCDVDInputStream::IMenus* menu = dynamic_cast<CDVDInputStream::IMenus*>(m_pInput);\n// \tif (/*!menu &&*/ m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE)\n// \t\tstarttime = (double)m_pFormatContext->start_time / AV_TIME_BASE;\n\n\tif (timestamp > starttime)\n\t\ttimestamp -= starttime;\n\t// allow for largest possible difference in pts and dts for a single packet\n\telse if (timestamp + 0.5f > starttime)\n\t\ttimestamp = 0;\n\n\treturn timestamp*DVD_TIME_BASE;\n}\n\nDemuxPacket* CDVDDemuxFFmpeg::Read()\n{\n\tDemuxPacket* pPacket = NULL;\n\t// on some cases where the received packet is invalid we will need to return an empty packet (0 length) otherwise the main loop (in CVideoPlayer)\n\t// would consider this the end of stream and stop.\n\tbool bReturnEmpty = false;\n\t{ CSingleLock lock(m_critSection); // open lock scope\n\tif (m_pFormatContext)\n\t{\n\t\t// assume we are not eof\n\t\tif (m_pFormatContext->pb)\n\t\t\tm_pFormatContext->pb->eof_reached = 0;\n\n\t\t// check for saved packet after a program change\n\t\tif (m_pkt.result < 0)\n\t\t{\n\t\t\t// keep track if ffmpeg doesn't always set these\n\t\t\tm_pkt.pkt.size = 0;\n\t\t\tm_pkt.pkt.data = NULL;\n\n\t\t\t// timeout reads after 100ms\n\t\t\tm_timeout.Set(20000);\n\t\t\tm_pkt.result = av_read_frame(m_pFormatContext, &m_pkt.pkt);\n\t\t\tm_timeout.SetInfinite();\n\t\t}\n\n\t\tif (m_pkt.result == AVERROR(EINTR) || m_pkt.result == AVERROR(EAGAIN))\n\t\t{\n\t\t\t// timeout, probably no real error, return empty packet\n\t\t\tbReturnEmpty = true;\n\t\t} else if (m_pkt.result < 0)\n\t\t{\n\t\t\tFlush();\n\t\t} else if (IsProgramChange())\n\t\t{\n\t\t\t// update streams\n\t\t\tCreateStreams(m_program);\n\n\t\t\tpPacket = DemuxPacket::Allocate(0);\n\t\t\tpPacket->iStreamId = DMX_SPECIALID_STREAMCHANGE;\n\t\t\tpPacket->demuxerId = m_demuxerId;\n\n\t\t\treturn pPacket;\n\t\t}\n\t\t// check size and stream index for being in a valid range\n\t\telse if (m_pkt.pkt.size < 0 ||\n\t\t\tm_pkt.pkt.stream_index < 0 ||\n\t\t\tm_pkt.pkt.stream_index >= (int)m_pFormatContext->nb_streams)\n\t\t{\n\t\t\t// XXX, in some cases ffmpeg returns a negative packet size\n\t\t\tif (m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGERROR, \"CDVDDemuxFFmpeg::Read() no valid packet\");\n\t\t\t\tbReturnEmpty = true;\n\t\t\t\tFlush();\n\t\t\t}\n\t\t\t//else\n\t\t\t//\tCLog::Log(LOGERROR, \"CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached\");\n\n\t\t\tm_pkt.result = -1;\n\t\t\tav_packet_unref(&m_pkt.pkt);\n\t\t} else\n\t\t{\n\t\t\tParsePacket(&m_pkt.pkt);\n\n\t\t\tAVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index];\n\n\t\t\tif (IsVideoReady())\n\t\t\t{\n\t\t\t\tif (m_program != UINT_MAX)\n\t\t\t\t{\n\t\t\t\t\t/* check so packet belongs to selected program */\n\t\t\t\t\tfor (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpPacket = DemuxPacket::Allocate(m_pkt.pkt.size);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!pPacket)\n\t\t\t\t\t\tbReturnEmpty = true;\n\t\t\t\t} else\n\t\t\t\t\tpPacket = DemuxPacket::Allocate(m_pkt.pkt.size);\n\t\t\t} else\n\t\t\t\tbReturnEmpty = true;\n\n\t\t\tif (pPacket)\n\t\t\t{\n\t\t\t\tif (m_bMatroska && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)\n\t\t\t\t{ // matroska can store different timestamps\n\t\t\t\t\t// for different formats, for native stored\n\t\t\t\t\t// stuff it is pts, but for ms compatibility\n\t\t\t\t\t// tracks, it is really dts. sadly ffmpeg\n\t\t\t\t\t// sets these two timestamps equal all the\n\t\t\t\t\t// time, so we select it here instead\n\t\t\t\t\tif (stream->codec->codec_tag == 0)\n\t\t\t\t\t\tm_pkt.pkt.dts = AV_NOPTS_VALUE;\n\t\t\t\t\telse\n\t\t\t\t\t\tm_pkt.pkt.pts = AV_NOPTS_VALUE;\n\t\t\t\t}\n\n\t\t\t\tif (m_bAVI && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)\n\t\t\t\t{\n\t\t\t\t\t// AVI's always have borked pts, specially if m_pFormatContext->flags includes\n\t\t\t\t\t// AVFMT_FLAG_GENPTS so always use dts\n\t\t\t\t\tm_pkt.pkt.pts = AV_NOPTS_VALUE;\n\t\t\t\t}\n\n\t\t\t\t// copy contents into our own packet\n\t\t\t\tpPacket->iSize = m_pkt.pkt.size;\n\n\t\t\t\t// maybe we can avoid a memcpy here by detecting where pkt.destruct is pointing too?\n\t\t\t\tif (m_pkt.pkt.data)\n\t\t\t\t\tmemcpy(pPacket->pData, m_pkt.pkt.data, pPacket->iSize);\n\n\t\t\t\tpPacket->pts = ConvertTimestamp(m_pkt.pkt.pts, stream->time_base.den, stream->time_base.num);\n\t\t\t\tpPacket->dts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num);\n\t\t\t\tpPacket->duration = DVD_SEC_TO_TIME((double)m_pkt.pkt.duration * stream->time_base.num / stream->time_base.den);\n\n// \t\t\t\tCDVDInputStream::IDisplayTime *inputStream = m_pInput->GetIDisplayTime();\n// \t\t\t\tif (inputStream)\n// \t\t\t\t{\n// \t\t\t\t\tint dispTime = inputStream->GetTime();\n// \t\t\t\t\tif (m_displayTime != dispTime)\n// \t\t\t\t\t{\n// \t\t\t\t\t\tm_displayTime = dispTime;\n// \t\t\t\t\t\tif (pPacket->dts != DVD_NOPTS_VALUE)\n// \t\t\t\t\t\t{\n// \t\t\t\t\t\t\tm_dtsAtDisplayTime = pPacket->dts;\n// \t\t\t\t\t\t}\n// \t\t\t\t\t}\n// \t\t\t\t\tif (m_dtsAtDisplayTime != DVD_NOPTS_VALUE && pPacket->dts != DVD_NOPTS_VALUE)\n// \t\t\t\t\t{\n// \t\t\t\t\t\tpPacket->dispTime = m_displayTime;\n// \t\t\t\t\t\tpPacket->dispTime += DVD_TIME_TO_MSEC(pPacket->dts - m_dtsAtDisplayTime);\n// \t\t\t\t\t}\n// \t\t\t\t}\n\n\t\t\t\t// used to guess streamlength\n\t\t\t\tif (pPacket->dts != DVD_NOPTS_VALUE && (pPacket->dts > m_currentPts || m_currentPts == DVD_NOPTS_VALUE))\n\t\t\t\t\tm_currentPts = pPacket->dts;\n\n\n\t\t\t\t// check if stream has passed full duration, needed for live streams\n\t\t\t\tbool bAllowDurationExt = (stream->codec && (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO || stream->codec->codec_type == AVMEDIA_TYPE_AUDIO));\n\t\t\t\tif (bAllowDurationExt && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE)\n\t\t\t\t{\n\t\t\t\t\tint64_t duration;\n\t\t\t\t\tduration = m_pkt.pkt.dts;\n\t\t\t\t\tif (stream->start_time != (int64_t)AV_NOPTS_VALUE)\n\t\t\t\t\t\tduration -= stream->start_time;\n\n\t\t\t\t\tif (duration > stream->duration)\n\t\t\t\t\t{\n\t\t\t\t\t\tstream->duration = duration;\n\t\t\t\t\t\tduration = av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF);\n\t\t\t\t\t\tif ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE)\n\t\t\t\t\t\t\t|| (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration))\n\t\t\t\t\t\t\tm_pFormatContext->duration = duration;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// store internal id until we know the continuous id presented to player\n\t\t\t\t// the stream might not have been created yet\n\t\t\t\tpPacket->iStreamId = m_pkt.pkt.stream_index;\n\t\t\t}\n\t\t\tm_pkt.result = -1;\n\t\t\tav_packet_unref(&m_pkt.pkt);\n\t\t}\n\t}\n\t} // end of lock scope\n\tif (bReturnEmpty && !pPacket)\n\t\tpPacket = DemuxPacket::Allocate(0);\n\n\tif (!pPacket)\n\t\treturn nullptr;\n\n\t// check streams, can we make this a bit more simple?\n\tif (pPacket && pPacket->iStreamId >= 0)\n\t{\n\t\tCDemuxStream *stream = GetStream(pPacket->iStreamId);\n\t\tif (!stream ||\n\t\t\tstream->pPrivate != m_pFormatContext->streams[pPacket->iStreamId] ||\n\t\t\tstream->codec != m_pFormatContext->streams[pPacket->iStreamId]->codec->codec_id)\n\t\t{\n\t\t\t// content has changed, or stream did not yet exist\n\t\t\tstream = AddStream(pPacket->iStreamId);\n\t\t}\n\t\t// we already check for a valid m_streams[pPacket->iStreamId] above\n\t\telse if (stream->type == STREAM_AUDIO)\n\t\t{\n\t\t\tif (((CDemuxStreamAudio*)stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codec->channels ||\n\t\t\t\t((CDemuxStreamAudio*)stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codec->sample_rate)\n\t\t\t{\n\t\t\t\t// content has changed\n\t\t\t\tstream = AddStream(pPacket->iStreamId);\n\t\t\t}\n\t\t} else if (stream->type == STREAM_VIDEO)\n\t\t{\n\t\t\tif (((CDemuxStreamVideo*)stream)->iWidth != m_pFormatContext->streams[pPacket->iStreamId]->codec->width ||\n\t\t\t\t((CDemuxStreamVideo*)stream)->iHeight != m_pFormatContext->streams[pPacket->iStreamId]->codec->height)\n\t\t\t{\n\t\t\t\t// content has changed\n\t\t\t\tstream = AddStream(pPacket->iStreamId);\n\t\t\t}\n\t\t}\n\t\tif (!stream)\n\t\t{\n\t\t//\tCLog::Log(LOGERROR, \"CDVDDemuxFFmpeg::AddStream - internal error, stream is null\");\n\t\t\tDemuxPacket::Free(pPacket);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tpPacket->iStreamId = stream->uniqueId;\n\t\tpPacket->demuxerId = m_demuxerId;\n\t}\n\treturn pPacket;\n}\n\nbool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)\n{\n\tbool hitEnd = false;\n\n\tif (!m_pInput)\n\t\treturn false;\n\n\tif (time < 0)\n\t{\n\t\ttime = 0;\n\t\thitEnd = true;\n\t}\n\n\tm_pkt.result = -1;\n\tav_packet_unref(&m_pkt.pkt);\n\n// \tCDVDInputStream::IPosTime* ist = m_pInput->GetIPosTime();\n// \tif (ist)\n// \t{\n// \t\tif (!ist->PosTime(time))\n// \t\t\treturn false;\n// \n// \t\tif (startpts)\n// \t\t\t*startpts = DVD_NOPTS_VALUE;\n// \n// \t\tFlush();\n// \n// \t\treturn true;\n// \t}\n\n// \tif (!m_pInput->Seek(0, SEEK_POSSIBLE) &&\n// \t\t!m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG))\n// \t{\n// \t\tCLog::Log(LOGDEBUG, \"%s - input stream reports it is not seekable\", __FUNCTION__);\n// \t\treturn false;\n// \t}\n\n\tint64_t seek_pts = (int64_t)time * (AV_TIME_BASE / 1000);\n\t// most demuxer seek under dts\n//\tbool ismp3 = m_pFormatContext->iformat && (strcmp(m_pFormatContext->iformat->name, \"mp3\") == 0);\n// \tif (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE && !ismp3)\n// \t\tseek_pts += m_pFormatContext->start_time;\n\n\tint ret;\n\t{\n\t\tCSingleLock lock(m_critSection);\n\t\tret = av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0);\n\n\t\t// demuxer can return failure, if seeking behind eof\n\t\tif (ret < 0 && m_pFormatContext->duration &&\n\t\t\tseek_pts >= (m_pFormatContext->duration /*+ m_pFormatContext->start_time*/))\n\t\t{\n\t\t\t// force eof\n\t\t\t// files of realtime streams may grow\n// \t\t\tif (!m_pInput->IsRealtime())\n// \t\t\t\tm_pInput->Close();\n// \t\t\telse\n// \t\t\t\tret = 0;\n\t\t} else if (ret < 0 /*&& m_pInput->IsEOF()*/)\n\t\t\tret = 0;\n\n\t\tif (ret >= 0)\n\t\t\tUpdateCurrentPTS();\n\t}\n\n// \tif (m_currentPts == DVD_NOPTS_VALUE)\n// \t\tCLog::Log(LOGDEBUG, \"%s - unknown position after seek\", __FUNCTION__);\n// \telse\n// \t\tCLog::Log(LOGDEBUG, \"%s - seek ended up on time %d\", __FUNCTION__, (int)(m_currentPts / DVD_TIME_BASE * 1000));\n\n\t// in this case the start time is requested time\n\tif (startpts)\n\t\t*startpts = DVD_MSEC_TO_TIME(time);\n\n\tif (ret >= 0)\n\t{\n\t\tif (!hitEnd)\n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t} else\n\t\treturn false;\n}\n\nbool CDVDDemuxFFmpeg::SeekByte(int64_t pos)\n{\n\tCSingleLock lock(m_critSection);\n\tint ret = av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE);\n\n\tif (ret >= 0)\n\t\tUpdateCurrentPTS();\n\n\tm_pkt.result = -1;\n\tav_packet_unref(&m_pkt.pkt);\n\n\treturn (ret >= 0);\n}\n\nvoid CDVDDemuxFFmpeg::UpdateCurrentPTS()\n{\n\tm_currentPts = DVD_NOPTS_VALUE;\n\n\tint idx = av_find_default_stream_index(m_pFormatContext);\n\tif (idx >= 0)\n\t{\n\t\tAVStream *stream = m_pFormatContext->streams[idx];\n\t\tif (stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE)\n\t\t{\n\t\t\tdouble ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num);\n\t\t\tm_currentPts = ts;\n\t\t}\n\t}\n}\n\nint CDVDDemuxFFmpeg::GetStreamLength()\n{\n\tif (!m_pFormatContext)\n\t\treturn 0;\n\n\tif (m_pFormatContext->duration < 0)\n\t\treturn 0;\n\n\treturn (int)(m_pFormatContext->duration / (AV_TIME_BASE / 1000));\n}\n\n/**\n* @brief Finds stream based on unique id\n*/\nCDemuxStream* CDVDDemuxFFmpeg::GetStream(int iStreamId) const\n{\n\tauto it = m_streams.find(iStreamId);\n\tif (it != m_streams.end())\n\t\treturn it->second;\n\n\treturn nullptr;\n}\n\nstd::vector<CDemuxStream*> CDVDDemuxFFmpeg::GetStreams() const\n{\n\tstd::vector<CDemuxStream*> streams;\n\n\tfor (auto& iter : m_streams)\n\t\tstreams.push_back(iter.second);\n\n\treturn streams;\n}\n\nint CDVDDemuxFFmpeg::GetNrOfStreams() const\n{\n\treturn m_streams.size();\n}\n\ndouble CDVDDemuxFFmpeg::SelectAspect(AVStream* st, bool& forced)\n{\n\t// for stereo modes, use codec aspect ratio\n\tAVDictionaryEntry *entry = av_dict_get(st->metadata, \"stereo_mode\", NULL, 0);\n\tif (entry)\n\t{\n\t\tforced = false;\n\t\treturn av_q2d(st->codecpar->sample_aspect_ratio);\n\t}\n\n\t// trust matroshka container\n\tif (m_bMatroska && st->sample_aspect_ratio.num != 0)\n\t{\n\t\tforced = true;\n\t\treturn av_q2d(st->sample_aspect_ratio);\n\t}\n\n\tforced = false;\n\t/* if stream aspect is 1:1 or 0:0 use codec aspect */\n\tif ((st->sample_aspect_ratio.den == 1 || st->sample_aspect_ratio.den == 0) &&\n\t\t(st->sample_aspect_ratio.num == 1 || st->sample_aspect_ratio.num == 0) &&\n\t\tst->codec->sample_aspect_ratio.num != 0)\n\t{\n\t\treturn av_q2d(st->codec->sample_aspect_ratio);\n\t}\n\n\tforced = true;\n\tif (st->sample_aspect_ratio.num != 0)\n\t\treturn av_q2d(st->sample_aspect_ratio);\n\n\treturn 0.0;\n}\n\nvoid CDVDDemuxFFmpeg::CreateStreams(unsigned int program)\n{\n\tDisposeStreams();\n\n\t// add the ffmpeg streams to our own stream map\n\tif (m_pFormatContext->nb_programs)\n\t{\n\t\t// check if desired program is available\n\t\tif (program < m_pFormatContext->nb_programs && m_pFormatContext->programs[program]->nb_stream_indexes > 0)\n\t\t{\n\t\t\tm_program = program;\n\t\t} else\n\t\t\tm_program = UINT_MAX;\n\n\t\t// look for first non empty stream and discard nonselected programs\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++)\n\t\t{\n\t\t\tif (m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0)\n\t\t\t{\n\t\t\t\tm_program = i;\n\t\t\t}\n\n\t\t\tif (i != m_program)\n\t\t\t\tm_pFormatContext->programs[i]->discard = AVDISCARD_ALL;\n\t\t}\n\t\tif (m_program != UINT_MAX)\n\t\t{\n\t\t\t// add streams from selected program\n\t\t\tfor (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)\n\t\t\t{\n\t\t\t\tAddStream(m_pFormatContext->programs[m_program]->stream_index[i]);\n\t\t\t}\n\t\t}\n\t} else\n\t\tm_program = UINT_MAX;\n\n\t// if there were no programs or they were all empty, add all streams\n\tif (m_program == UINT_MAX)\n\t{\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t\t\tAddStream(i);\n\t}\n}\n\nvoid CDVDDemuxFFmpeg::DisposeStreams()\n{\n\tstd::map<int, CDemuxStream*>::iterator it;\n\tfor (it = m_streams.begin(); it != m_streams.end(); ++it)\n\t\tdelete it->second;\n\tm_streams.clear();\n}\n\nCDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)\n{\n\tAVStream* pStream = m_pFormatContext->streams[streamIdx];\n\tif (pStream)\n\t{\n\t\tCDemuxStream* stream = NULL;\n\n\t\tswitch (pStream->codec->codec_type)\n\t\t{\n\t\tcase AVMEDIA_TYPE_AUDIO:\n\t\t{\n\t\t\tCDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(this, pStream);\n\t\t\tstream = st;\n\t\t\tst->iChannels = pStream->codec->channels;\n\t\t\tst->iSampleRate = pStream->codec->sample_rate;\n\t\t\tst->iBlockAlign = pStream->codec->block_align;\n\t\t\tst->iBitRate = pStream->codec->bit_rate;\n\t\t\tst->iBitsPerSample = pStream->codec->bits_per_raw_sample;\n\t\t\tst->iChannelLayout = pStream->codec->channel_layout;\n\t\t\tif (st->iBitsPerSample == 0)\n\t\t\t\tst->iBitsPerSample = pStream->codec->bits_per_coded_sample;\n\n\t\t\tif (av_dict_get(pStream->metadata, \"title\", NULL, 0))\n\t\t\t\tst->m_description = av_dict_get(pStream->metadata, \"title\", NULL, 0)->value;\n\n\t\t\tbreak;\n\t\t}\n\t\tcase AVMEDIA_TYPE_VIDEO:\n\t\t{\n\t\t\tCDemuxStreamVideoFFmpeg* st = new CDemuxStreamVideoFFmpeg(this, pStream);\n\t\t\tstream = st;\n\t\t\tif (strcmp(m_pFormatContext->iformat->name, \"flv\") == 0)\n\t\t\t\tst->bVFR = true;\n\t\t\telse\n\t\t\t\tst->bVFR = false;\n\n\t\t\t// never trust pts in avi files with h264.\n\t\t\tif (m_bAVI && pStream->codec->codec_id == AV_CODEC_ID_H264)\n\t\t\t\tst->bPTSInvalid = true;\n\n\t\t\tAVRational r_frame_rate = av_stream_get_r_frame_rate(pStream);\n\n\t\t\t//average fps is more accurate for mkv files\n\t\t\tif (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num)\n\t\t\t{\n\t\t\t\tst->iFpsRate = pStream->avg_frame_rate.num;\n\t\t\t\tst->iFpsScale = pStream->avg_frame_rate.den;\n\t\t\t} else if (r_frame_rate.den && r_frame_rate.num)\n\t\t\t{\n\t\t\t\tst->iFpsRate = r_frame_rate.num;\n\t\t\t\tst->iFpsScale = r_frame_rate.den;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tst->iFpsRate = 0;\n\t\t\t\tst->iFpsScale = 0;\n\t\t\t}\n\t\t\t\n\t\t\tst->iWidth = pStream->codec->width;\n\t\t\tst->iHeight = pStream->codec->height;\n\t\t\tst->fAspect = SelectAspect(pStream, st->bForcedAspect) * pStream->codec->width / pStream->codec->height;\n\t\t\tst->iOrientation = 0;\n\t\t\tst->iBitsPerPixel = pStream->codec->bits_per_coded_sample;\n\n\t\t\tAVDictionaryEntry *rtag = av_dict_get(pStream->metadata, \"rotate\", NULL, 0);\n\t\t\tif (rtag)\n\t\t\t\tst->iOrientation = atoi(rtag->value);\n\n\t\t\t// detect stereoscopic mode\n\t\t\tstd::string stereoMode = GetStereoModeFromMetadata(pStream->metadata);\n\t\t\t// check for metadata in file if detection in stream failed\n\t\t\tif (stereoMode.empty())\n\t\t\t\tstereoMode = GetStereoModeFromMetadata(m_pFormatContext->metadata);\n\t\t\tif (!stereoMode.empty())\n\t\t\t\tst->stereo_mode = stereoMode;\n\t\t\t\n\t\t\tif (av_dict_get(pStream->metadata, \"title\", NULL, 0))\n\t\t\t\tst->m_description = av_dict_get(pStream->metadata, \"title\", NULL, 0)->value;\n\n\t\t\tbreak;\n\t\t}\n\t\tcase AVMEDIA_TYPE_DATA:\n\t\t{\n\t\t\tstream = new CDemuxStream();\n\t\t\tstream->type = STREAM_DATA;\n\t\t\tbreak;\n\t\t}\n#if 0\n\t\tcase AVMEDIA_TYPE_SUBTITLE:\n\t\t{\n\t\t\tif (pStream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_TELETEXTENABLED))\n\t\t\t{\n\t\t\t\tCDemuxStreamTeletext* st = new CDemuxStreamTeletext();\n\t\t\t\tstream = st;\n\t\t\t\tstream->type = STREAM_TELETEXT;\n\t\t\t\tbreak;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tCDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream);\n\t\t\t\tstream = st;\n\n\t\t\t\tif (av_dict_get(pStream->metadata, \"title\", NULL, 0))\n\t\t\t\t\tst->m_description = av_dict_get(pStream->metadata, \"title\", NULL, 0)->value;\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcase AVMEDIA_TYPE_ATTACHMENT:\n\t\t{ //mkv attachments. Only bothering with fonts for now.\n\t\t\tif (pStream->codec->codec_id == AV_CODEC_ID_TTF\n\t\t\t\t|| pStream->codec->codec_id == AV_CODEC_ID_OTF\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tstd::string fileName = \"special://temp/fonts/\";\n\t\t\t\tXFILE::CDirectory::Create(fileName);\n\t\t\t\tAVDictionaryEntry *nameTag = av_dict_get(pStream->metadata, \"filename\", NULL, 0);\n\t\t\t\tif (!nameTag)\n\t\t\t\t{\n\t\t\t\t\tCLog::Log(LOGERROR, \"%s: TTF attachment has no name\", __FUNCTION__);\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tfileName += nameTag->value;\n\t\t\t\t\tXFILE::CFile file;\n\t\t\t\t\tif (pStream->codec->extradata && file.OpenForWrite(fileName))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (file.Write(pStream->codec->extradata, pStream->codec->extradata_size) != pStream->codec->extradata_size)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfile.Close();\n\t\t\t\t\t\t\tXFILE::CFile::Delete(fileName);\n\t\t\t\t\t\t\tCLog::Log(LOGDEBUG, \"%s: Error saving font file \\\"%s\\\"\", __FUNCTION__, fileName.c_str());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tstream = new CDemuxStream();\n\t\t\tstream->type = STREAM_NONE;\n\t\t\tbreak;\n\t\t}\n#endif\n\t\tdefault:\n\t\t{\n\t\t\tstream = new CDemuxStream();\n\t\t\tstream->type = STREAM_NONE;\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\t// generic stuff\n\t\tif (pStream->duration != (int64_t)AV_NOPTS_VALUE)\n\t\t\tstream->iDuration = (int)((pStream->duration / AV_TIME_BASE) & 0xFFFFFFFF);\n\n\t\tstream->codec = pStream->codec->codec_id;\n\t\tstream->codec_fourcc = pStream->codec->codec_tag;\n\t\tstream->profile = pStream->codec->profile;\n\t\tstream->level = pStream->codec->level;\n\t\t//stream->realtime = m_pInput->IsRealtime();\n\t\tstream->realtime = false;\n\n\t\tstream->source = STREAM_SOURCE_DEMUX;\n\t\tstream->pPrivate = pStream;\n\t\tstream->flags = (CDemuxStream::EFlags)pStream->disposition;\n\n\t\tAVDictionaryEntry *langTag = av_dict_get(pStream->metadata, \"language\", NULL, 0);\n\t\tif (!langTag)\n\t\t{\n\t\t\t// only for avi audio streams\n\t\t\tif ((strcmp(m_pFormatContext->iformat->name, \"avi\") == 0) && (pStream->codecpar && pStream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))\n\t\t\t{\n\t\t\t\t// only defined for streams 1 to 9\n\t\t\t\tif ((streamIdx > 0) && (streamIdx < 10))\n\t\t\t\t{\n\t\t\t\t\t// search for language information in RIFF-Header (\"IAS1\": first language - \"IAS9\": ninth language)\n\t\t\t\t\tchar riff_tag_string[5] = { 'I', 'A', 'S', (char)(streamIdx + '0'), '\\0' };\n\t\t\t\t\tlangTag = av_dict_get(m_pFormatContext->metadata, riff_tag_string, NULL, 0);\n\t\t\t\t\tif (!langTag && (streamIdx == 1))\n\t\t\t\t\t{\n\t\t\t\t\t\t// search for language information in RIFF-Header (\"ILNG\": language)\n\t\t\t\t\t\tlangTag = av_dict_get(m_pFormatContext->metadata, \"language\", NULL, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (langTag)\n\t\t\tstrncpy(stream->language, langTag->value, 3);\n\n\t\tif (stream->type != STREAM_NONE && pStream->codec->extradata && pStream->codec->extradata_size > 0)\n\t\t{\n\t\t\tstream->ExtraSize = pStream->codec->extradata_size;\n\t\t\tstream->ExtraData = new uint8_t[pStream->codec->extradata_size];\n\t\t\tmemcpy(stream->ExtraData, pStream->codec->extradata, pStream->codec->extradata_size);\n\t\t}\n\n#ifdef HAVE_LIBBLURAY\n\t\tif (m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY))\n\t\t{\n\t\t\tstatic_cast<CDVDInputStreamBluray*>(m_pInput)->GetStreamInfo(pStream->id, stream->language);\n\t\t\tstream->dvdNavId = pStream->id;\n\t\t}\n#endif\n\n\t\tstream->uniqueId = pStream->index;\n\t\tstream->demuxerId = m_demuxerId;\n\n\t\tAddStream(stream->uniqueId, stream);\n\t\treturn stream;\n\t} else\n\t\treturn NULL;\n}\n\n/**\n* @brief Adds or updates a demux stream based in ffmpeg id\n*/\nvoid CDVDDemuxFFmpeg::AddStream(int streamIdx, CDemuxStream* stream)\n{\n\tstd::pair<std::map<int, CDemuxStream*>::iterator, bool> res;\n\n\tres = m_streams.insert(std::make_pair(streamIdx, stream));\n\tif (res.second)\n\t{\n\t\t/* was new stream */\n\t\tstream->uniqueId = streamIdx;\n\t} else\n\t{\n\t\tdelete res.first->second;\n\t\tres.first->second = stream;\n\t}\n// \tif (g_advancedSettings.m_logLevel > LOG_LEVEL_NORMAL)\n// \t\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::AddStream ID: %d\", streamIdx);\n}\n\nstd::string CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId)\n{\n\tCDemuxStream *stream = GetStream(iStreamId);\n\tstd::string strName;\n\tif (stream)\n\t{\n#ifdef FF_PROFILE_DTS_HD_MA\n\t\t/* use profile to determine the DTS type */\n\t\tif (stream->codec == AV_CODEC_ID_DTS)\n\t\t{\n\t\t\tif (stream->profile == FF_PROFILE_DTS_HD_MA)\n\t\t\t\tstrName = \"dtshd_ma\";\n\t\t\telse if (stream->profile == FF_PROFILE_DTS_HD_HRA)\n\t\t\t\tstrName = \"dtshd_hra\";\n\t\t\telse\n\t\t\t\tstrName = \"dca\";\n\n\t\t\treturn strName;\n\t\t}\n#endif\n\n\t\tAVCodec *codec = avcodec_find_decoder(stream->codec);\n\t\tif (codec)\n\t\t\tstrName = codec->name;\n\t}\n\treturn strName;\n}\n\nbool CDVDDemuxFFmpeg::IsProgramChange()\n{\n\tif (m_program == UINT_MAX)\n\t\treturn false;\n\n\tif (m_program == 0 && !m_pFormatContext->nb_programs)\n\t\treturn false;\n\n\tif (m_pFormatContext->programs[m_program]->nb_stream_indexes != m_streams.size())\n\t\treturn true;\n\n\tif (m_program >= m_pFormatContext->nb_programs)\n\t\treturn true;\n\n\tfor (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)\n\t{\n\t\tint idx = m_pFormatContext->programs[m_program]->stream_index[i];\n\t\tCDemuxStream *stream = GetStream(idx);\n\t\tif (!stream)\n\t\t\treturn true;\n\t\tif (m_pFormatContext->streams[idx]->codec->codec_id != stream->codec)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nstd::string CDVDDemuxFFmpeg::GetStereoModeFromMetadata(AVDictionary *pMetadata)\n{\n\tstd::string stereoMode;\n\tAVDictionaryEntry *tag = NULL;\n\n\t// matroska\n\ttag = av_dict_get(pMetadata, \"stereo_mode\", NULL, 0);\n\tif (tag && tag->value)\n\t\tstereoMode = tag->value;\n\n\t// asf / wmv\n\tif (stereoMode.empty())\n\t{\n\t\ttag = av_dict_get(pMetadata, \"Stereoscopic\", NULL, 0);\n\t\tif (tag && tag->value)\n\t\t{\n\t\t\ttag = av_dict_get(pMetadata, \"StereoscopicLayout\", NULL, 0);\n\t\t\tif (tag && tag->value)\n\t\t\t\tstereoMode = ConvertCodecToInternalStereoMode(tag->value, WmvToInternalStereoModeMap);\n\t\t}\n\t}\n\n\treturn stereoMode;\n}\n\nstd::string CDVDDemuxFFmpeg::ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap)\n{\n\tsize_t i = 0;\n\twhile (conversionMap[i].name)\n\t{\n\t\tif (mode == conversionMap[i].name)\n\t\t\treturn conversionMap[i].mode;\n\t\ti++;\n\t}\n\treturn \"\";\n}\n\nvoid CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt)\n{\n\tAVStream *st = m_pFormatContext->streams[pkt->stream_index];\n\tCDemuxStream *stream = GetStream(pkt->stream_index);\n\n\t// if the stream is new, tell ffmpeg to parse the stream\n\tif (!stream && !st->parser)\n\t{\n\t\tst->need_parsing = AVSTREAM_PARSE_FULL;\n\t}\n\n\t// split extradata\n\tif (st->parser && st->parser->parser->split && !st->codec->extradata)\n\t{\n\t\tint i = st->parser->parser->split(st->codec, pkt->data, pkt->size);\n\t\tif (i > 0 && i < FF_MAX_EXTRADATA_SIZE)\n\t\t{\n\t\t\t// Found extradata, fill it in. This will cause\n\t\t\t// a new stream to be created and used.\n\t\t\tst->codec->extradata_size = i;\n\t\t\tst->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);\n\t\t\tif (st->codec->extradata)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGDEBUG, \"CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)\", st->codec->extradata_size);\n\t\t\t\tmemcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);\n\t\t\t\tmemset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tst->codec->extradata_size = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t// for video we need a decoder to get desired information into codec context\n\tif (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata &&\n\t\t(!st->codec->width || st->codec->pix_fmt == AV_PIX_FMT_NONE))\n\t{\n\t\t// open a decoder, it will be cleared down by ffmpeg on closing the stream\n\t\tif (!st->codec->codec)\n\t\t{\n\t\t\tconst AVCodec* codec;\n\t\t\tAVDictionary *thread_opt = NULL;\n\t\t\tcodec = avcodec_find_decoder(st->codec->codec_id);\n\t\t\t// Force thread count to 1 since the h264 decoder will not extract\n\t\t\t// SPS and PPS to extradata during multi-threaded decoding\n\t\t\tav_dict_set(&thread_opt, \"threads\", \"1\", 0);\n\t\t\tint res = avcodec_open2(st->codec, codec, &thread_opt);\n// \t\t\tif (res < 0)\n// \t\t\t\tCLog::Log(LOGERROR, \"CDVDDemuxFFmpeg::ParsePacket() unable to open codec %d\", res);\n\t\t\tav_dict_free(&thread_opt);\n\t\t}\n\n\t\t// We don't need to actually decode here\n\t\t// we just want to transport SPS data into codec context\n\t\tst->codec->skip_idct = AVDISCARD_ALL;\n\t\t// extradata is not decoded if skip_frame >= AVDISCARD_NONREF\n\t\t//    st->codec->skip_frame = AVDISCARD_ALL;\n\t\tst->codec->skip_loop_filter = AVDISCARD_ALL;\n\n\t\t// We are looking for an IDR frame\n\t\tAVFrame picture;\n\t\tmemset(&picture, 0, sizeof(AVFrame));\n\t\tpicture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE;\n\t\tpicture.pkt_pos = -1;\n\t\tpicture.key_frame = 1;\n\t\tpicture.format = -1;\n\n\t\tint got_picture = 0;\n\t\tavcodec_decode_video2(st->codec, &picture, &got_picture, pkt);\n\t\tav_frame_unref(&picture);\n\t}\n}\n\nbool CDVDDemuxFFmpeg::IsVideoReady()\n{\n\tAVStream *st;\n\tbool hasVideo = false;\n\n\tif (!m_checkvideo)\n\t\treturn true;\n\n\tif (m_program == 0 && !m_pFormatContext->nb_programs)\n\t\treturn false;\n\n\tif (m_program != UINT_MAX)\n\t{\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)\n\t\t{\n\t\t\tint idx = m_pFormatContext->programs[m_program]->stream_index[i];\n\t\t\tst = m_pFormatContext->streams[idx];\n\t\t\tif (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)\n\t\t\t{\n\t\t\t\tif (st->codec->width && st->codec->pix_fmt != AV_PIX_FMT_NONE)\n\t\t\t\t\treturn true;\n\t\t\t\thasVideo = true;\n\t\t\t}\n\t\t}\n\t} else\n\t{\n\t\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t\t{\n\t\t\tst = m_pFormatContext->streams[i];\n\t\t\tif (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)\n\t\t\t{\n\t\t\t\tif (st->codec->width && st->codec->pix_fmt != AV_PIX_FMT_NONE)\n\t\t\t\t\treturn true;\n\t\t\t\thasVideo = true;\n\t\t\t}\n\t\t}\n\t}\n\treturn !hasVideo;\n}\n\nvoid CDVDDemuxFFmpeg::ResetVideoStreams()\n{\n\tAVStream *st;\n\tfor (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)\n\t{\n\t\tst = m_pFormatContext->streams[i];\n\t\tif (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)\n\t\t{\n\t\t\tav_freep(&st->codec->extradata);\n\t\t\tst->codec->extradata_size = 0;\n\t\t\tst->codec->width = 0;\n\t\t}\n\t}\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/DemuxFFmpeg.h",
    "content": "#pragma once\n#include \"Demux.h\"\n#include <map>\n#include <vector>\nextern \"C\" {\n#include \"libavformat/avformat.h\"\n}\n#include \"Thread.h\"\n#include \"Timer.h\"\n\nstruct IStream;\n\nNS_KRMOVIE_BEGIN\n\nclass CDVDDemuxFFmpeg;\nclass InputStream;\nclass CDemuxStreamVideoFFmpeg\n\t: public CDemuxStreamVideo\n{\n\tCDVDDemuxFFmpeg *m_parent;\n\tAVStream*        m_stream;\npublic:\n\tCDemuxStreamVideoFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream)\n\t\t: m_parent(parent)\n\t\t, m_stream(stream)\n\t{}\n\tstd::string      m_description;\n\n\tvirtual std::string GetStreamName() override;\n};\n\n\nclass CDemuxStreamAudioFFmpeg\n\t: public CDemuxStreamAudio\n{\n\tCDVDDemuxFFmpeg *m_parent;\n\tAVStream*        m_stream;\npublic:\n\tCDemuxStreamAudioFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream)\n\t\t: m_parent(parent)\n\t\t, m_stream(stream)\n\t{}\n\tstd::string m_description;\n\n\tvirtual std::string GetStreamName() override;\n};\n\nstruct StereoModeConversionMap;\nclass CDVDDemuxFFmpeg : public IDemux\n{\npublic:\n\tCDVDDemuxFFmpeg();\n\tvirtual ~CDVDDemuxFFmpeg();\n\n\tbool Open(InputStream* pInput, bool streaminfo = true, bool fileinfo = false);\n\tvoid Dispose();\n\tvoid Reset() override;\n\tvoid Flush() override;\n\tvoid Abort() override;\n\tvoid SetSpeed(int iSpeed) override;\n//\tvirtual std::string GetFileName() override;\n\n\tDemuxPacket* Read() override;\n\n\tbool SeekTime(int time, bool backwords = false, double* startpts = NULL) override;\n\tbool SeekByte(int64_t pos);\n\tint GetStreamLength() override;\n\tCDemuxStream* GetStream(int iStreamId) const override;\n\tstd::vector<CDemuxStream*> GetStreams() const override;\n\tint GetNrOfStreams() const override;\n\n\tvirtual std::string GetStreamCodecName(int iStreamId) override;\n\n\tbool Aborted();\n\n\tAVFormatContext* m_pFormatContext;\n\tInputStream* m_pInput = nullptr;\n\nprotected:\n\tfriend class CDemuxStreamAudioFFmpeg;\n\tfriend class CDemuxStreamVideoFFmpeg;\n\tfriend class CDemuxStreamSubtitleFFmpeg;\n\n\tint ReadFrame(AVPacket *packet);\n\tCDemuxStream* AddStream(int streamIdx);\n\tvoid AddStream(int streamIdx, CDemuxStream* stream);\n\tvoid CreateStreams(unsigned int program = UINT_MAX);\n\tvoid DisposeStreams();\n\tvoid ParsePacket(AVPacket *pkt);\n\tbool IsVideoReady();\n\tvoid ResetVideoStreams();\n\n\tAVDictionary *GetFFMpegOptionsFromInput();\n\tdouble ConvertTimestamp(int64_t pts, int den, int num);\n\tvoid UpdateCurrentPTS();\n\tbool IsProgramChange();\n\n\tstd::string GetStereoModeFromMetadata(AVDictionary *pMetadata);\n\tstd::string ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap);\n\n//\tvoid GetL16Parameters(int &channels, int &samplerate);\n\tdouble SelectAspect(AVStream* st, bool& forced);\n\n\tCCriticalSection m_critSection;\n\tstd::map<int, CDemuxStream*> m_streams;\n\n\tAVIOContext* m_ioContext;\n\n\tdouble   m_currentPts; // used for stream length estimation\n\tbool     m_bMatroska;\n\tbool     m_bAVI;\n\tint      m_speed;\n\tunsigned m_program;\n\tTimer  m_timeout;\n\n\t// Due to limitations of ffmpeg, we only can detect a program change\n\t// with a packet. This struct saves the packet for the next read and\n\t// signals STREAMCHANGE to player\n\tstruct\n\t{\n\t\tAVPacket pkt;       // packet ffmpeg returned\n\t\tint      result;    // result from av_read_packet\n\t}m_pkt;\n\n\tbool m_streaminfo;\n\tbool m_checkvideo;\n\tint m_displayTime;\n\tdouble m_dtsAtDisplayTime;\n};\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/DemuxPacket.cpp",
    "content": "#include \"DemuxPacket.h\"\n#include <memory>\n#include \"tp_stub.h\"\n#include \"Clock.h\"\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n\nNS_KRMOVIE_BEGIN\nvoid DemuxPacket::Free(DemuxPacket *pPacket)\n{\n\tif (pPacket)\n\t{\n\t\ttry {\n\t\t\tif (pPacket->pData) TJSAlignedDealloc(pPacket->pData);\n\t\t\tdelete pPacket;\n\t\t} catch (...) {\n//\t\t\tCLog::Log(LOGERROR, \"%s - Exception thrown while freeing packet\", __FUNCTION__);\n\t\t}\n\t}\n}\n\nDemuxPacket * DemuxPacket::Allocate(int iDataSize /*= 0*/)\n{\n\tDemuxPacket* pPacket = new DemuxPacket;\n\tif (!pPacket) return nullptr;\n\n\ttry\n\t{\n\t\tmemset(pPacket, 0, sizeof(DemuxPacket));\n\n\t\tif (iDataSize > 0)\n\t\t{\n\t\t\t// need to allocate a few bytes more.\n\t\t\t// From avcodec.h (ffmpeg)\n\t\t\t/**\n\t\t\t* Required number of additionally allocated bytes at the end of the input bitstream for decoding.\n\t\t\t* this is mainly needed because some optimized bitstream readers read\n\t\t\t* 32 or 64 bit at once and could read over the end<br>\n\t\t\t* Note, if the first 23 bits of the additional bytes are not 0 then damaged\n\t\t\t* MPEG bitstreams could cause overread and segfault\n\t\t\t*/\n\t\t\tpPacket->pData = (uint8_t*)TJSAlignedAlloc(iDataSize + FF_INPUT_BUFFER_PADDING_SIZE, 4);\n\t\t\tif (!pPacket->pData)\n\t\t\t{\n\t\t\t\tFree(pPacket);\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\t// reset the last 8 bytes to 0;\n\t\t\tmemset(pPacket->pData + iDataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);\n\t\t}\n\n\t\t// setup defaults\n\t\tpPacket->dts = DVD_NOPTS_VALUE;\n\t\tpPacket->pts = DVD_NOPTS_VALUE;\n\t\tpPacket->iStreamId = -1;\n\t\tpPacket->dispTime = 0;\n\t} catch (...) {\n//\t\tCLog::Log(LOGERROR, \"%s - Exception thrown\", __FUNCTION__);\n\t\tFree(pPacket);\n\t\tpPacket = nullptr;\n\t}\n\treturn pPacket;\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/DemuxPacket.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include <stdint.h>\n\nNS_KRMOVIE_BEGIN\n#define DMX_SPECIALID_STREAMINFO    -10\n#define DMX_SPECIALID_STREAMCHANGE  -11\n\nstruct DemuxPacket\n{\n\tunsigned char* pData;   // data\n\tint iSize;     // data size\n\tint iStreamId; // integer representing the stream index\n\tint64_t demuxerId; // id of the demuxer that created the packet\n\tint iGroupId;  // the group this data belongs to, used to group data from different streams together\n\n\tdouble pts; // pts in DVD_TIME_BASE\n\tdouble dts; // dts in DVD_TIME_BASE\n\tdouble duration; // duration in DVD_TIME_BASE if available\n\n\tint dispTime;\n\n\tstatic void Free(DemuxPacket *);\n\tstatic DemuxPacket *Allocate(int iDataSize = 0);\n};\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/FactoryCodec.cpp",
    "content": "#include \"FactoryCodec.h\"\n#include \"VideoCodec.h\"\n#include \"AudioCodec.h\"\n#include \"Codecs.h\"\n#include \"StreamInfo.h\"\n#include \"VideoCodecFFmpeg.h\"\n#include \"AudioCodecFFmpeg.h\"\n#include \"AudioCodecPassthrough.h\"\n\nNS_KRMOVIE_BEGIN\n\nCDVDVideoCodec* CDVDFactoryCodec::OpenCodec(CDVDVideoCodec* pCodec, CDVDStreamInfo &hints, CDVDCodecOptions &options )\n{\n  try\n  {\n//    CLog::Log(LOGDEBUG, \"FactoryCodec - Video: %s - Opening\", pCodec->GetName());\n    if( pCodec->Open( hints, options ) )\n    {\n//      CLog::Log(LOGDEBUG, \"FactoryCodec - Video: %s - Opened\", pCodec->GetName());\n      return pCodec;\n    }\n\n//    CLog::Log(LOGDEBUG, \"FactoryCodec - Video: %s - Failed\", pCodec->GetName());\n    delete pCodec;\n  }\n  catch(...)\n  {\n //   CLog::Log(LOGERROR, \"FactoryCodec - Video: Failed with exception\");\n  }\n  return nullptr;\n}\n\nCDVDAudioCodec* CDVDFactoryCodec::OpenCodec(CDVDAudioCodec* pCodec, CDVDStreamInfo &hints, CDVDCodecOptions &options )\n{\n  try\n  {\n //   CLog::Log(LOGDEBUG, \"FactoryCodec - Audio: %s - Opening\", pCodec->GetName());\n    if( pCodec->Open( hints, options ) )\n    {\n  //    CLog::Log(LOGDEBUG, \"FactoryCodec - Audio: %s - Opened\", pCodec->GetName());\n      return pCodec;\n    }\n\n  //  CLog::Log(LOGDEBUG, \"FactoryCodec - Audio: %s - Failed\", pCodec->GetName());\n    delete pCodec;\n  }\n  catch(...)\n  {\n  //  CLog::Log(LOGERROR, \"FactoryCodec - Audio: Failed with exception\");\n  }\n  return nullptr;\n}\n#if 0\nCDVDOverlayCodec* CDVDFactoryCodec::OpenCodec(CDVDOverlayCodec* pCodec, CDVDStreamInfo &hints, CDVDCodecOptions &options )\n{\n  try\n  {\n    CLog::Log(LOGDEBUG, \"FactoryCodec - Overlay: %s - Opening\", pCodec->GetName());\n    if( pCodec->Open( hints, options ) )\n    {\n      CLog::Log(LOGDEBUG, \"FactoryCodec - Overlay: %s - Opened\", pCodec->GetName());\n      return pCodec;\n    }\n\n    CLog::Log(LOGDEBUG, \"FactoryCodec - Overlay: %s - Failed\", pCodec->GetName());\n    delete pCodec;\n  }\n  catch(...)\n  {\n    CLog::Log(LOGERROR, \"FactoryCodec - Audio: Failed with exception\");\n  }\n  return nullptr;\n}\n#endif\n\nCDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, CProcessInfo &processInfo, const CRenderInfo &info)\n{\n  CDVDVideoCodec* pCodec = nullptr;\n  CDVDCodecOptions options;\n\n  if (info.formats.empty())\n    options.m_formats.push_back(RENDER_FMT_YUV420P);\n  else\n    options.m_formats = info.formats;\n\n  options.m_opaque_pointer = info.opaque_pointer;\n\n  if (!hint.software)\n  {\n#if defined(HAS_LIBAMCODEC)\n    // Amlogic can be present on multiple platforms (Linux, Android)\n    // try this first. if it does not open, we still try other hw decoders\n    pCodec = OpenCodec(new CDVDVideoCodecAmlogic(processInfo), hint, options);\n    if (pCodec)\n      return pCodec;\n#endif\n\n#if defined(HAS_IMXVPU)\n    pCodec = OpenCodec(new CDVDVideoCodecIMX(processInfo), hint, options);\n#elif defined(TARGET_ANDROID)\n    pCodec = OpenCodec(new CDVDVideoCodecAndroidMediaCodec(processInfo), hint, options);\n#elif defined(HAVE_LIBOPENMAX)\n    pCodec = OpenCodec(new CDVDVideoCodecOpenMax(processInfo), hint, options);\n#elif defined(HAS_MMAL)\n    pCodec = OpenCodec(new CMMALVideo(processInfo), hint, options);\n#endif\n    if (pCodec)\n      return pCodec;\n  }\n\n  // try to decide if we want to try halfres decoding\n#if !defined(TARGET_POSIX) && !defined(TARGET_WINDOWS)\n  float pixelrate = (float)hint.width*hint.height*hint.fpsrate/hint.fpsscale;\n  if (pixelrate > 1400.0f*720.0f*30.0f)\n  {\n//    CLog::Log(LOGINFO, \"CDVDFactoryCodec - High video resolution detected %dx%d, trying half resolution decoding \", hint.width, hint.height);\n    options.m_keys.push_back(CDVDCodecOption(\"lowres\",\"1\"));\n  }\n#endif\n\n  char value[32]; sprintf(value, \"%d\", info.max_buffer_size);\n  options.m_keys.push_back(CDVDCodecOption(\"surfaces\", value));\n  pCodec = OpenCodec(new CDVDVideoCodecFFmpeg(processInfo), hint, options);\n  if (pCodec)\n    return pCodec;\n\n  return nullptr;;\n}\n\nCDVDAudioCodec* CDVDFactoryCodec::CreateAudioCodec(CDVDStreamInfo &hint, CProcessInfo &processInfo, bool allowpassthrough, bool allowdtshddecode)\n{\n  CDVDAudioCodec* pCodec = NULL;\n  CDVDCodecOptions options;\n\n  if (!allowdtshddecode)\n    options.m_keys.push_back(CDVDCodecOption(\"allowdtshddecode\", \"0\"));\n\n  // we don't use passthrough if \"sync playback to display\" is enabled\n  if (allowpassthrough)\n  {\n    pCodec = OpenCodec(new CDVDAudioCodecPassthrough(processInfo), hint, options);\n    if (pCodec)\n      return pCodec;\n  }\n\n  pCodec = OpenCodec(new CDVDAudioCodecFFmpeg(processInfo), hint, options);\n  if (pCodec)\n    return pCodec;\n\n  return nullptr;\n}\n#if 0\nCDVDOverlayCodec* CDVDFactoryCodec::CreateOverlayCodec( CDVDStreamInfo &hint )\n{\n  CDVDOverlayCodec* pCodec = NULL;\n  CDVDCodecOptions options;\n\n  switch (hint.codec)\n  {\n    case AV_CODEC_ID_TEXT:\n    case AV_CODEC_ID_SUBRIP:\n      pCodec = OpenCodec(new CDVDOverlayCodecText(), hint, options);\n      if (pCodec)\n        return pCodec;\n      break;\n\n    case AV_CODEC_ID_SSA:\n    case AV_CODEC_ID_ASS:\n      pCodec = OpenCodec(new CDVDOverlayCodecSSA(), hint, options);\n      if (pCodec)\n        return pCodec;\n\n      pCodec = OpenCodec(new CDVDOverlayCodecText(), hint, options);\n      if (pCodec)\n        return pCodec;\n      break;\n\n    case AV_CODEC_ID_MOV_TEXT:\n      pCodec = OpenCodec(new CDVDOverlayCodecTX3G(), hint, options);\n      if (pCodec)\n        return pCodec;\n      break;\n\n    default:\n      pCodec = OpenCodec(new CDVDOverlayCodecFFmpeg(), hint, options);\n      if (pCodec)\n        return pCodec;\n      break;\n  }\n\n  return nullptr;\n}\n#endif\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/FactoryCodec.h",
    "content": "#pragma once\n#include <vector>\n#include \"ProcessInfo.h\"\n#include \"RenderFormats.h\"\n\nNS_KRMOVIE_BEGIN\n\nclass CDVDVideoCodec;\nclass CDVDAudioCodec;\nclass CDVDOverlayCodec;\n\nclass CDemuxStreamVideo;\nstruct CDVDStreamInfo;\nclass CDVDCodecOption;\nclass CDVDCodecOptions;\n\n\nclass CDVDFactoryCodec\n{\npublic:\n  static CDVDVideoCodec* CreateVideoCodec(CDVDStreamInfo &hint,\n                                          CProcessInfo &processInfo,\n                                          const CRenderInfo &info = CRenderInfo());\n  static CDVDAudioCodec* CreateAudioCodec(CDVDStreamInfo &hint, CProcessInfo &processInfo,\n                                          bool allowpassthrough = true, bool allowdtshddecode = true);\n//  static CDVDOverlayCodec* CreateOverlayCodec(CDVDStreamInfo &hint );\n\n  static CDVDAudioCodec* OpenCodec(CDVDAudioCodec* pCodec, CDVDStreamInfo &hint, CDVDCodecOptions &options );\n  static CDVDVideoCodec* OpenCodec(CDVDVideoCodec* pCodec, CDVDStreamInfo &hint, CDVDCodecOptions &options );\n//  static CDVDOverlayCodec* OpenCodec(CDVDOverlayCodec* pCodec, CDVDStreamInfo &hint, CDVDCodecOptions &options );\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Geometry.h",
    "content": "/*\n *      Copyright (C) 2005-2013 Team XBMC\n *      http://xbmc.org\n *\n *  This Program is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  This Program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with XBMC; see the file COPYING.  If not, see\n *  <http://www.gnu.org/licenses/>.\n *\n */\n\n#pragma once\n\n#ifdef __GNUC__\n// under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.\n#define XBMC_FORCE_INLINE __attribute__((always_inline))\n#else\n#define XBMC_FORCE_INLINE\n#endif\n\n#include <vector>\n#include <algorithm>\n\ntemplate <typename T> class CPointGen\n{\npublic:\n  typedef CPointGen<T> this_type;\n\n  CPointGen<T>()\n  {\n    x = 0; y = 0;\n  };\n\n  CPointGen<T>(T a, T b)\n  {\n    x = a;\n    y = b;\n  };\n\n  template <class U> CPointGen<T>(const CPointGen<U>& rhs)\n  {\n    x = rhs.x;\n    y = rhs.y;\n  }\n\n  this_type operator+(const this_type &point) const\n  {\n    this_type ans;\n    ans.x = x + point.x;\n    ans.y = y + point.y;\n    return ans;\n  };\n\n  const this_type &operator+=(const this_type &point)\n  {\n    x += point.x;\n    y += point.y;\n    return *this;\n  };\n\n  this_type operator-(const this_type &point) const\n  {\n    CPointGen<T> ans;\n    ans.x = x - point.x;\n    ans.y = y - point.y;\n    return ans;\n  };\n\n  const this_type &operator-=(const this_type &point)\n  {\n    x -= point.x;\n    y -= point.y;\n    return *this;\n  };\n\n  bool operator !=(const this_type &point) const\n  {\n    if (x != point.x) return true;\n    if (y != point.y) return true;\n    return false;\n  };\n\n  T x, y;\n};\n\ntemplate <typename T> class CRectGen\n{\npublic:\n  typedef CRectGen<T> this_type;\n\n  CRectGen<T>() { x1 = y1 = x2 = y2 = 0;};\n  CRectGen<T>(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };\n  CRectGen<T>(const CPointGen<T> &p1, const CPointGen<T> &p2)\n  {\n    x1 = p1.x;\n    y1 = p1.y;\n    x2 = p2.x;\n    y2 = p2.y;\n  }\n\n  template <class U> CRectGen<T>(const CRectGen<U>& rhs)\n  {\n    x1 = rhs.x1;\n    y1 = rhs.y1;\n    x2 = rhs.x2;\n    y2 = rhs.y2;\n  }\n\n  void SetRect(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };\n\n  bool PtInRect(const CPointGen<T> &point) const\n  {\n    if (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2)\n      return true;\n    return false;\n  };\n\n  inline const this_type &operator -=(const CPointGen<T> &point) XBMC_FORCE_INLINE\n  {\n    x1 -= point.x;\n    y1 -= point.y;\n    x2 -= point.x;\n    y2 -= point.y;\n    return *this;\n  };\n\n  inline const this_type &operator +=(const CPointGen<T> &point) XBMC_FORCE_INLINE\n  {\n    x1 += point.x;\n    y1 += point.y;\n    x2 += point.x;\n    y2 += point.y;\n    return *this;\n  };\n\n  const this_type &Intersect(const this_type &rect)\n  {\n    x1 = clamp_range(x1, rect.x1, rect.x2);\n    x2 = clamp_range(x2, rect.x1, rect.x2);\n    y1 = clamp_range(y1, rect.y1, rect.y2);\n    y2 = clamp_range(y2, rect.y1, rect.y2);\n    return *this;\n  };\n\n  const this_type &Union(const this_type &rect)\n  {\n    if (IsEmpty())\n      *this = rect;\n    else if (!rect.IsEmpty())\n    {\n      x1 = std::min(x1,rect.x1);\n      y1 = std::min(y1,rect.y1);\n\n      x2 = std::max(x2,rect.x2);\n      y2 = std::max(y2,rect.y2);\n    }\n\n    return *this;\n  };\n\n  inline bool IsEmpty() const XBMC_FORCE_INLINE\n  {\n    return (x2 - x1) * (y2 - y1) == 0;\n  };\n\n  inline CPointGen<T> P1() const XBMC_FORCE_INLINE\n  {\n    return CPointGen<T>(x1, y1);\n  }\n\n  inline CPointGen<T> P2() const XBMC_FORCE_INLINE\n  {\n    return CPointGen<T>(x2, y2);\n  }\n\n  inline T Width() const XBMC_FORCE_INLINE\n  {\n    return x2 - x1;\n  };\n\n  inline T Height() const XBMC_FORCE_INLINE\n  {\n    return y2 - y1;\n  };\n\n  inline T Area() const XBMC_FORCE_INLINE\n  {\n    return Width() * Height();\n  };\n\n  std::vector<this_type> SubtractRect(this_type splitterRect)\n  {\n    std::vector<this_type> newRectaglesList;\n    this_type intersection = splitterRect.Intersect(*this);\n\n    if (!intersection.IsEmpty())\n    {\n      this_type add;\n\n      // add rect above intersection if not empty\n      add = this_type(x1, y1, x2, intersection.y1);\n      if (!add.IsEmpty())\n        newRectaglesList.push_back(add);\n\n      // add rect below intersection if not empty\n      add = this_type(x1, intersection.y2, x2, y2);\n      if (!add.IsEmpty())\n        newRectaglesList.push_back(add);\n\n      // add rect left intersection if not empty\n      add = this_type(x1, intersection.y1, intersection.x1, intersection.y2);\n      if (!add.IsEmpty())\n        newRectaglesList.push_back(add);\n\n      // add rect right intersection if not empty\n      add = this_type(intersection.x2, intersection.y1, x2, intersection.y2);\n      if (!add.IsEmpty())\n        newRectaglesList.push_back(add);\n    }\n    else\n    {\n      newRectaglesList.push_back(*this);\n    }\n\n    return newRectaglesList;\n  }\n\n  std::vector<this_type> SubtractRects(std::vector<this_type > intersectionList)\n  {\n    std::vector<this_type> fragmentsList;\n    fragmentsList.push_back(*this);\n\n    for (typename std::vector<this_type>::iterator splitter = intersectionList.begin(); splitter != intersectionList.end(); ++splitter)\n    {\n      typename std::vector<this_type> toAddList;\n\n      for (typename std::vector<this_type>::iterator fragment = fragmentsList.begin(); fragment != fragmentsList.end(); ++fragment)\n      {\n        std::vector<this_type> newFragmentsList = fragment->SubtractRect(*splitter);\n        toAddList.insert(toAddList.end(), newFragmentsList.begin(), newFragmentsList.end());\n      }\n\n      fragmentsList.clear();\n      fragmentsList.insert(fragmentsList.end(), toAddList.begin(), toAddList.end());\n    }\n\n    return fragmentsList;\n  }\n\n  bool operator !=(const this_type &rect) const\n  {\n    if (x1 != rect.x1) return true;\n    if (x2 != rect.x2) return true;\n    if (y1 != rect.y1) return true;\n    if (y2 != rect.y2) return true;\n    return false;\n  };\n\n  T x1, y1, x2, y2;\nprivate:\n  inline static T clamp_range(T x, T l, T h) XBMC_FORCE_INLINE\n  {\n    return (x > h) ? h : ((x < l) ? l : x);\n  }\n};\n\ntypedef CPointGen<float> CPoint;\ntypedef CPointGen<int>   CPointInt;\n\ntypedef CRectGen<float>  CRect;\ntypedef CRectGen<int>    CRectInt;\n"
  },
  {
    "path": "src/core/movie/ffmpeg/IAudioCallback.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\nNS_KRMOVIE_BEGIN\nclass IAudioCallback\n{\npublic:\n  IAudioCallback() {};\n  virtual ~IAudioCallback() {};\n  virtual void OnInitialize(int iChannels, int iSamplesPerSec, int iBitsPerSample) = 0;\n  virtual void OnAudioData(const float* pAudioData, int iAudioDataLength) = 0;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/IVideoPlayer.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"ProcessInfo.h\"\n#include \"StreamInfo.h\"\n#include \"Message.h\"\n#include <string>\n\nNS_KRMOVIE_BEGIN\n\n#define VideoPlayer_AUDIO    1\n#define VideoPlayer_VIDEO    2\n// #define VideoPlayer_SUBTITLE 3\n// #define VideoPlayer_TELETEXT 4\n// #define VideoPlayer_RDS      5\n\nstruct SStartMsg\n{\n\tdouble timestamp;\n\tint player;\n\tdouble cachetime;\n\tdouble cachetotal;\n};\n\nclass IDVDStreamPlayer\n{\npublic:\n\tIDVDStreamPlayer(CProcessInfo &processInfo) : m_processInfo(processInfo) {};\n\tvirtual ~IDVDStreamPlayer() {}\n\tvirtual bool OpenStream(CDVDStreamInfo &hint) = 0;\n\tvirtual void CloseStream(bool bWaitForBuffers) = 0;\n\tvirtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;\n\tvirtual void FlushMessages() = 0;\n\tvirtual bool IsInited() const = 0;\n\tvirtual bool AcceptsData() = 0;\n\tvirtual bool IsStalled() const = 0;\n\n\tenum ESyncState\n\t{\n\t\tSYNC_STARTING,\n\t\tSYNC_WAITSYNC,\n\t\tSYNC_INSYNC\n\t};\nprotected:\n\tCProcessInfo &m_processInfo;\n};\n\nclass CDVDVideoCodec;\n\nclass IDVDStreamPlayerVideo : public IDVDStreamPlayer\n{\npublic:\n\tIDVDStreamPlayerVideo(CProcessInfo &processInfo) : IDVDStreamPlayer(processInfo) {};\n\t~IDVDStreamPlayerVideo() {}\n\tvirtual bool OpenStream(CDVDStreamInfo &hint) = 0;\n\tvirtual void CloseStream(bool bWaitForBuffers) = 0;\n\tvirtual void Flush(bool sync) = 0;\n\tvirtual bool AcceptsData() = 0;\n\tvirtual bool HasData() const = 0;\n\tvirtual int  GetLevel() = 0;\n\tvirtual bool IsInited() const = 0;\n\tvirtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;\n\tvirtual void EnableSubtitle(bool bEnable) = 0;\n\tvirtual bool IsSubtitleEnabled() = 0;\n//\tvirtual void EnableFullscreen(bool bEnable) = 0;\n\tvirtual double GetSubtitleDelay() = 0;\n\tvirtual void SetSubtitleDelay(double delay) = 0;\n\tvirtual bool IsStalled() const = 0;\n\tvirtual bool IsRewindStalled() const { return false; }\n\tvirtual double GetCurrentPts() = 0;\n\tvirtual double GetOutputDelay() = 0;\n\tvirtual std::string GetPlayerInfo() = 0;\n\tvirtual int GetVideoBitrate() = 0;\n\tvirtual std::string GetStereoMode() = 0;\n\tvirtual void SetSpeed(int iSpeed) = 0;\n\tvirtual int  GetDecoderBufferSize() { return 0; }\n\tvirtual int  GetDecoderFreeSpace() = 0;\n\tvirtual bool IsEOS() { return false; };\n};\n\nclass CDVDAudioCodec;\nclass IDVDStreamPlayerAudio : public IDVDStreamPlayer\n{\npublic:\n\tIDVDStreamPlayerAudio(CProcessInfo &processInfo) : IDVDStreamPlayer(processInfo) {};\n\t~IDVDStreamPlayerAudio() {}\n\tvirtual bool OpenStream(CDVDStreamInfo &hints) = 0;\n\tvirtual void CloseStream(bool bWaitForBuffers) = 0;\n\tvirtual void SetSpeed(int speed) = 0;\n\tvirtual void Flush(bool sync) = 0;\n\tvirtual bool AcceptsData() = 0;\n\tvirtual bool HasData() const = 0;\n\tvirtual int  GetLevel() = 0;\n\tvirtual bool IsInited() const = 0;\n\tvirtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;\n\tvirtual void SetVolume(float fVolume) {};\n\tvirtual void SetMute(bool bOnOff) {};\n//\tvirtual void SetDynamicRangeCompression(long drc) = 0;\n\tvirtual std::string GetPlayerInfo() = 0;\n\tvirtual int GetAudioBitrate() = 0;\n\tvirtual int GetAudioChannels() = 0;\n\tvirtual double GetCurrentPts() = 0;\n\tvirtual bool IsStalled() const = 0;\n\tvirtual bool IsPassthrough() = 0;\n\tvirtual float GetDynamicRangeAmplification() const = 0;\n\tvirtual bool IsEOS() { return false; };\n\tvirtual class CDVDAudio* GetOutputDevice() = 0;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/InputStream.cpp",
    "content": "#include \"InputStream.h\"\n#include \"combase.h\"\n\nNS_KRMOVIE_BEGIN\nInputStream::InputStream(IStream *s, const std::string &filename)\n\t: m_pSource(s)\n\t, m_strFileName(filename)\n{\n\ts->AddRef();\n\n\tSTATSTG stg;\n\ts->Stat(&stg, STATFLAG_NONAME);\n\tm_nFileSize = stg.cbSize.QuadPart;\n}\n\nInputStream::~InputStream() {\n\tm_pSource->Release();\n}\n\nint InputStream::Read(uint8_t* buf, int buf_size) {\n\tULONG readed;\n\tHRESULT ret = m_pSource->Read(buf, buf_size, &readed);\n\tif (ret != S_OK) return -1;\n\treturn readed;\n}\n\nint64_t InputStream::Seek(int64_t offset, int whence) {\n\tLARGE_INTEGER pos; pos.QuadPart = offset;\n\tULARGE_INTEGER newpos;\n\tHRESULT ret = m_pSource->Seek(pos, whence, &newpos);\n\tif (ret != S_OK) return -1;\n\treturn newpos.QuadPart;\n}\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/InputStream.h",
    "content": "#pragma once\n#include \"Ref.h\"\n#include <string>\n#include <cstdint>\n\nstruct IStream;\n\nNS_KRMOVIE_BEGIN\nclass InputStream : public IRef<InputStream> {\n\tIStream *m_pSource;\n\tuint64_t m_nFileSize;\n\tstd::string m_strFileName;\n\npublic:\n\tInputStream(IStream *s, const std::string &filename);\n\t~InputStream();\n\n\tuint64_t GetLength() { return m_nFileSize; }\n\tint Read(uint8_t* buf, int buf_size);\n\tint64_t Seek(int64_t offset, int whence);\n\tconst std::string &GetFileName() { return m_strFileName; }\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/KRMovieDef.h",
    "content": "#pragma once\n#define NS_KRMOVIE_BEGIN namespace KRMovie {\n#define NS_KRMOVIE_END }\n\n#define SAFE_DELETE(p)       do { delete (p);     (p)=NULL; } while (0)\n#define SAFE_RELEASE(p)      do { if(p) { (p)->Release(); (p)=NULL; } } while (0)\n\n#ifdef _MSC_VER\n#define NOMINMAX\n#endif"
  },
  {
    "path": "src/core/movie/ffmpeg/KRMovieLayer.cpp",
    "content": "#include \"KRMovieLayer.h\"\n#include \"VideoCodec.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"Application.h\"\n#include \"VideoOvlImpl.h\"\nextern \"C\" {\n#include \"libswscale/swscale.h\"\n}\n\nNS_KRMOVIE_BEGIN\n\nVideoPresentLayer::~VideoPresentLayer()\n{\n\tTVPRemoveContinuousEventHook(this);\n}\n\ntTVPBaseTexture* VideoPresentLayer::GetFrontBuffer()\n{\n\tBitmapPicture pic;\n\tif (!m_usedPicture) {\n\t\treturn nullptr;\n\t}\n\t{\n\t\tstd::lock_guard<std::mutex> lk(m_mtxPicture);\n\t\tBitmapPicture &picbuf = m_picture[m_curPicture];\n\t\tpicbuf.swap(pic);\n\t\tm_curPicture = (m_curPicture + 1) & (MAX_BUFFER_COUNT - 1);\n\t\t--m_usedPicture;\n\t\tassert(m_usedPicture >= 0);\n\t\tm_condPicture.notify_all();\n\t}\n\tFrameMove();\n\tint n = m_nCurBmpBuff;\n\tm_nCurBmpBuff = !m_nCurBmpBuff;\n\tm_BmpBits[n]->Update(pic.data[0], pic.width * 4, 0, 0, pic.width, pic.height);\n\treturn m_BmpBits[n];\n}\n\nvoid VideoPresentLayer::SetVideoBuffer(tTVPBaseTexture *buff1, tTVPBaseTexture *buff2, long size)\n{\n\tm_BmpBits[0] = buff1;\n\tm_BmpBits[1] = buff2;\n\tm_nCurBmpBuff = 0;\n//\tTVPAddContinuousEventHook(this);\n}\n\nvoid VideoPresentLayer::OnContinuousCallback(tjs_uint64 tick)\n{\n\tif (!m_usedPicture) return;\n\tdouble m_curpts = m_pPlayer->GetClock() / DVD_TIME_BASE;\n\t{\n\t\tstd::lock_guard<std::mutex> lk(m_mtxPicture);\n\t\tBitmapPicture &picbuf = m_picture[m_curPicture];\n\t\t// check pts\n\t\tif (picbuf.pts > m_curpts) { // present in future\n\t\t\treturn;\n\t\t}\n\t}\n#if 0\n\tdo { // skip frame\n\t\tpic.Clear();\n\t\tpicbuf.swap(pic);\n\t\tm_curPicture = (m_curPicture + 1) & (MAX_BUFFER_COUNT - 1);\n\t\t--m_usedPicture;\n\t} while (m_usedPicture > 0 && m_curpts >= m_picture[m_curPicture].pts);\n\tassert(m_usedPicture >= 0);\n#endif\n\tOnPlayEvent(KRMovieEvent::Update, nullptr);\n}\n\nint VideoPresentLayer::AddVideoPicture(DVDVideoPicture &pic, int index)\n{\n\t// from other thread\n\tif (pic.format != RENDER_FMT_YUV420P) return -2;\n\tif (pic.pts == DVD_NOPTS_VALUE) return 0;\n\n\tif (m_usedPicture >= MAX_BUFFER_COUNT) {\n\t\tstd::unique_lock<std::mutex> lk(m_mtxPicture);\n\t\tm_condPicture.wait(lk);\n\t}\n\tif (m_usedPicture >= MAX_BUFFER_COUNT) return -1;\n\n\tint width = pic.iWidth, height = pic.iHeight;\n\n\tuint8_t *data = (uint8_t*)TJSAlignedAlloc(width * height * 4, 4);\n\tint datasize = width * 4;\n\n\timg_convert_ctx = sws_getCachedContext(\n\t\timg_convert_ctx, width, height, AV_PIX_FMT_YUV420P, width, height,\n\t\tAV_PIX_FMT_RGBA, /*sws_flags*/SWS_FAST_BILINEAR, NULL, NULL, NULL);\n\tassert(img_convert_ctx);\n\tint processed = sws_scale(img_convert_ctx, pic.data, pic.iLineSize, 0, pic.iHeight, &data, &datasize);\n\n\t{\n\t\tstd::lock_guard<std::mutex> lk(m_mtxPicture);\n\t\tBitmapPicture &picbuf = m_picture[(m_curPicture + m_usedPicture) & (MAX_BUFFER_COUNT - 1)];\n\t\tpicbuf.Clear();\n\t\tpicbuf.width = width;\n\t\tpicbuf.height = height;\n\t\tpicbuf.data[0] = data;\n\t\tpicbuf.pts = pic.pts / DVD_TIME_BASE;\n\t\t++m_usedPicture;\n\t}\n\n\treturn MAX_BUFFER_COUNT - m_usedPicture;\n}\n\nvoid MoviePlayerLayer::BuildGraph(tTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size)\n{\n\tm_pCallbackWin = callbackwin;\n\tm_pPlayer->SetCallback(std::bind(&MoviePlayerLayer::OnPlayEvent, this, std::placeholders::_1, std::placeholders::_2));\n\tm_pPlayer->OpenFromStream(stream, streamname, type, size);\n}\n\nvoid MoviePlayerLayer::OnPlayEvent(KRMovieEvent msg, void *p)\n{\n\tif (msg == KRMovieEvent::Update) {\n\t\tNativeEvent ev(WM_GRAPHNOTIFY);\n\t\tev.WParam = EC_UPDATE;\n\t\tint frame; GetFrame(&frame);\n\t\tev.LParam = frame;\n\t\tm_pCallbackWin->WndProc(ev); // in the same thread\n\t} else if (msg == KRMovieEvent::Ended) {\n\t\tNativeEvent ev(WM_GRAPHNOTIFY);\n\t\tev.WParam = EC_COMPLETE;\n\t\tev.LParam = 0;\n\t\tm_pCallbackWin->PostEvent(ev);\n\t}\n}\n\nvoid MoviePlayerLayer::Play()\n{\n\tinherit::Play();\n\tTVPAddContinuousEventHook(this);\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/KRMovieLayer.h",
    "content": "#pragma once\n#include \"KRMoviePlayer.h\"\n#include \"EventIntf.h\"\n\nNS_KRMOVIE_BEGIN\n\nclass VideoPresentLayer : public TVPMoviePlayer, public tTVPContinuousEventCallbackIntf {\nprotected:\n\ttTVPBaseTexture *m_BmpBits[2];\n\tint             m_nCurBmpBuff = 0;\n\npublic:\n\t~VideoPresentLayer();\n\tvirtual tTVPBaseTexture* GetFrontBuffer() override;\n\tvirtual void SetVideoBuffer(tTVPBaseTexture *buff1, tTVPBaseTexture *buff2, long size) override;\n\n\tvirtual void OnContinuousCallback(tjs_uint64 tick) override;\n\tvirtual void OnPlayEvent(KRMovieEvent msg, void *p) = 0;\n\tvirtual int AddVideoPicture(DVDVideoPicture &pic, int index) override;\n};\n\nclass MoviePlayerLayer : public VideoPresentLayer {\n\ttypedef VideoPresentLayer inherit;\n\ttTJSNI_VideoOverlay* m_pCallbackWin = nullptr;\n\npublic:\n\tvoid BuildGraph(tTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size);\n\tvirtual void OnPlayEvent(KRMovieEvent msg, void *p) override;\n\tvirtual void Play() override;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/KRMoviePlayer.cpp",
    "content": "#include <thread>\nextern \"C\" {\n#include \"libswscale/swscale.h\"\n}\n#include \"cocos2d.h\"\n#include \"KRMoviePlayer.h\"\n#include \"VideoCodec.h\"\n#include \"CodecUtils.h\"\n#include \"AudioDevice.h\"\n#include \"WaveMixer.h\"\n#include \"WindowImpl.h\"\n#include \"VideoOvlImpl.h\"\n#include \"cocos2d/YUVSprite.h\"\n\nextern std::thread::id TVPMainThreadID;\n\nNS_KRMOVIE_BEGIN\n\nTVPMoviePlayer::TVPMoviePlayer()\n{\n\tm_pPlayer = new BasePlayer(this);\n}\n\nTVPMoviePlayer::~TVPMoviePlayer()\n{\n\tdelete m_pPlayer;\n\tif (img_convert_ctx) sws_freeContext(img_convert_ctx), img_convert_ctx = nullptr;\n}\n\nvoid TVPMoviePlayer::Release()\n{\n\tif (RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount--;\n}\n\nvoid TVPMoviePlayer::SetPosition(uint64_t tick)\n{\n\tm_pPlayer->SeekTime(tick);\n}\n\nvoid TVPMoviePlayer::GetPosition(uint64_t *tick)\n{\n\tif (tick) *tick = m_pPlayer->GetTime();\n}\n\nvoid TVPMoviePlayer::GetStatus(tTVPVideoStatus *status)\n{\n\tif (m_pPlayer->IsStop()) *status = vsStopped;\n\telse if (m_pPlayer->GetSpeed() == 0) *status = vsPaused;\n\telse *status = vsPlaying;\n\t//\telse *status = vsProcessing;\n}\n\nvoid TVPMoviePlayer::Rewind()\n{\n\tSetPosition(0);\n}\n\nvoid TVPMoviePlayer::SetFrame(int f)\n{\n\t// TODO seek accurately\n\tm_pPlayer->SeekTime(f / m_pPlayer->GetFPS() * DVD_PLAYSPEED_NORMAL);\n}\n\nvoid TVPMoviePlayer::GetFrame(int *f)\n{\n\t*f = m_pPlayer->GetCurrentFrame();\n}\n\nvoid TVPMoviePlayer::GetFPS(double *f)\n{\n\t*f = m_pPlayer->GetFPS();\n}\n\nvoid TVPMoviePlayer::GetNumberOfFrame(int *f)\n{\n\t*f = m_pPlayer->GetTotalTime() * m_pPlayer->GetFPS() / DVD_PLAYSPEED_NORMAL;\n}\n\nvoid TVPMoviePlayer::GetTotalTime(int64_t *t)\n{\n\t*t = m_pPlayer->GetTotalTime();\n}\n\nvoid TVPMoviePlayer::GetVideoSize(long *width, long *height)\n{\n\tm_pPlayer->GetVideoSize(width, height);\n}\n\nvoid TVPMoviePlayer::SetPlayRate(double rate) {\n\tm_pPlayer->SetSpeed(rate);\n}\n\nvoid TVPMoviePlayer::GetPlayRate(double *rate) {\n\t*rate = m_pPlayer->GetSpeed();\n}\n\niTVPSoundBuffer* TVPMoviePlayer::GetSoundDevice() {\n\tIDVDStreamPlayerAudio *audioplayer = m_pPlayer->GetAudioPlayer();\n\tif (!audioplayer) return nullptr;\n\tIAEStream *audiostream = audioplayer->GetOutputDevice()->m_pAudioStream;\n\tif (!audiostream) return nullptr;\n\treturn audiostream->GetNativeImpl();\n}\n\nvoid TVPMoviePlayer::GetAudioBalance(long *balance)\n{\n\tiTVPSoundBuffer* alsound = GetSoundDevice();\n\tif (alsound) {\n\t\t*balance = alsound->GetPan() * 100000;\n\t}\n}\n\nvoid TVPMoviePlayer::SetAudioBalance(long balance)\n{\n\tiTVPSoundBuffer* alsound = GetSoundDevice();\n\tif (alsound) {\n\t\talsound->SetPan(balance / 100000.0f);\n\t}\n}\n\nvoid TVPMoviePlayer::SetAudioVolume(long volume)\n{\n\tiTVPSoundBuffer* alsound = GetSoundDevice();\n\tif (alsound) alsound->SetVolume(volume / 100000.f);\n}\n\nvoid TVPMoviePlayer::GetAudioVolume(long *volume)\n{\n\tiTVPSoundBuffer* alsound = GetSoundDevice();\n\tif (alsound) *volume = alsound->GetVolume() * 100000;\n}\n\nvoid TVPMoviePlayer::GetNumberOfAudioStream(unsigned long *streamCount) {\n\t*streamCount = m_pPlayer->GetAudioStreamCount();\n}\n\nvoid TVPMoviePlayer::SelectAudioStream(unsigned long iStream) {\n\tm_pPlayer->GetMessageQueue().Put(new CDVDMsgPlayerSetAudioStream(iStream));\n\tm_pPlayer->SynchronizeDemuxer();\n}\n\nvoid TVPMoviePlayer::GetEnableAudioStreamNum(long *num) {\n\t*num = m_pPlayer->GetAudioStream();\n}\n\nvoid TVPMoviePlayer::DisableAudioStream(void) {\n\t// TODO\n}\n\nvoid TVPMoviePlayer::GetNumberOfVideoStream(unsigned long *streamCount) {\n\t*streamCount = m_pPlayer->GetVideoStreamCount();\n}\n\nvoid TVPMoviePlayer::SelectVideoStream(unsigned long iStream) {\n\tm_pPlayer->GetMessageQueue().Put(new CDVDMsgPlayerSetVideoStream(iStream));\n\tm_pPlayer->SynchronizeDemuxer();\n}\n\nvoid TVPMoviePlayer::GetEnableVideoStreamNum(long *num) {\n\t*num = m_pPlayer->GetVideoStream();\n}\n\nint TVPMoviePlayer::WaitForBuffer(volatile std::atomic_bool&bStop, int timeout)\n{\n\tint remainBuf = MAX_BUFFER_COUNT - m_usedPicture;\n\tif (remainBuf > 0) return remainBuf;\n\tstd::unique_lock<std::mutex> lk(m_mtxPicture);\n\twhile (!bStop && MAX_BUFFER_COUNT <= m_usedPicture && timeout > 0) {\n\t\ttimeout -= 10;\n\t\tm_condPicture.wait_for(lk, std::chrono::milliseconds(10));\n\t}\n\treturn MAX_BUFFER_COUNT - m_usedPicture - 1;\n}\n\nvoid TVPMoviePlayer::Flush()\n{\n\tstd::unique_lock<std::mutex> lk(m_mtxPicture);\n\tfor (int i = 0; i < MAX_BUFFER_COUNT; ++i) {\n\t\tm_picture[i].Clear();\n\t}\n\tm_curpts = 0.0;\n\tm_usedPicture = 0;\n}\n\nvoid TVPMoviePlayer::FrameMove()\n{\n\tm_pPlayer->FrameMove();\n}\n\nvoid TVPMoviePlayer::SetLoopSegement(int beginFrame, int endFrame)\n{\n\tm_pPlayer->SetLoopSegement(beginFrame, endFrame);\n}\n\nint TVPMoviePlayer::AddVideoPicture(DVDVideoPicture &pic, int index)\n{\n\t// from other thread\n\tif (pic.format != RENDER_FMT_YUV420P) return -2;\n\tif (pic.pts == DVD_NOPTS_VALUE) return 0;\n\n\tif (m_usedPicture >= MAX_BUFFER_COUNT) {\n\t\tstd::unique_lock<std::mutex> lk(m_mtxPicture);\n\t\tm_condPicture.wait(lk);\n\t}\n\tif (m_usedPicture >= MAX_BUFFER_COUNT) return -1;\n\n\tint width = pic.iWidth, height = pic.iHeight;\n\t// YUV data passthrough\n\tint yuvwidth[3] = { width, width / 2, width / 2 };\n\tint yuvheight[3] = { height, height / 2, height / 2 };\n\tuint8_t *yuvdata[3] = { nullptr };\n\tfor (int i = 0; i < sizeof(yuvdata) / sizeof(yuvdata[0]); ++i) {\n\t\tint size = yuvwidth[i] * yuvheight[i];\n\t\tyuvdata[i] = (uint8_t*)TJSAlignedAlloc(size, 4);\n\t\tif (yuvwidth[i] == pic.iLineSize[i]) {\n\t\t\tmemcpy(yuvdata[i], pic.data[i], size);\n\t\t} else {\n\t\t\tuint8_t *d = yuvdata[i], *s = pic.data[i];\n\t\t\tfor (int y = 0; y < yuvheight[i]; ++y) {\n\t\t\t\tmemcpy(d, s, yuvwidth[i]);\n\t\t\t\td += yuvwidth[i];\n\t\t\t\ts += pic.iLineSize[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t{\n\t\tstd::lock_guard<std::mutex> lk(m_mtxPicture);\n\t\tBitmapPicture &picbuf = m_picture[(m_curPicture + m_usedPicture) & (MAX_BUFFER_COUNT - 1)];\n\t\tpicbuf.Clear();\n\t\tpicbuf.width = width;\n\t\tpicbuf.height = height;\n\t\tfor (int i = 0; i < sizeof(yuvdata) / sizeof(yuvdata[0]); ++i) {\n\t\t\tpicbuf.yuv[i] = yuvdata[i];\n\t\t}\n\t\tpicbuf.pts = pic.pts / DVD_TIME_BASE;\n\t\t++m_usedPicture;\n\t\treturn MAX_BUFFER_COUNT - m_usedPicture;\n\t}\n\n\t// \tconst static std::string sckey(\"present\");\n\t// \tm_pRootNode->scheduleOnce(std::bind(&PlayerOverlay::PresentPicture, this, std::placeholders::_1), 0, sckey);\n}\n\n\nVideoPresentOverlay::~VideoPresentOverlay()\n{\n\tClearNode();\n}\n\nvoid VideoPresentOverlay::ClearNode()\n{\n\tif (m_pRootNode) {\n\t\tm_pRootNode->removeFromParent(), m_pRootNode = nullptr;\n\t\tm_pSprite = nullptr;\n\t}\n}\n\nvoid VideoPresentOverlay::PresentPicture(float dt)\n{\n\tBitmapPicture pic;\n\tif (!m_usedPicture) {\n\t\treturn;\n\t} else {\n\t\tstd::lock_guard<std::mutex> lk(m_mtxPicture);\n\t\tBitmapPicture &picbuf = m_picture[m_curPicture];\n\t\t// check pts\n\t\tif (m_curpts == 0.0) {\n\t\t\tm_curpts = picbuf.pts;\n\t\t} else {\n\t\t\tm_curpts += dt;\n\t\t\tif (picbuf.pts > m_curpts) { // present in future\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tdo { // skip frame\n\t\t\tpic.Clear();\n\t\t\tm_picture[m_curPicture].swap(pic);\n\t\t\tm_curPicture = (m_curPicture + 1) & (MAX_BUFFER_COUNT - 1);\n\t\t\t--m_usedPicture;\n\t\t} while (m_usedPicture > 0 && m_curpts >= m_picture[m_curPicture].pts);\n\t\tassert(m_usedPicture >= 0);\n\t\tm_condPicture.notify_all();\n\t}\n\tFrameMove();\n\tif (!pic.rgba) {\n\t\treturn;\n\t}\n\tif (!Visible) {\n\t\tm_pRootNode->setVisible(false);\n\t\treturn;\n\t} else {\n\t\tm_pRootNode->setVisible(true);\n\t}\n\tif (!m_pSprite) {\n\t\tm_pSprite = TVPYUVSprite::create();\n\t\tm_pSprite->setAnchorPoint(cocos2d::Vec2(0, 1));\n\t\tm_pRootNode->addChild(m_pSprite);\n\t}\n\tcocos2d::Size videoSize(pic.width, pic.height);\n\tm_pSprite->updateTextureData(\n\t\tpic.data[0], pic.width, pic.height,\n\t\tpic.data[1], pic.width / 2, pic.height / 2,\n\t\tpic.data[2], pic.width / 2, pic.height / 2\n\t\t);\n\tconst tTVPRect & rc = GetBounds();\n\tfloat scaleX = rc.get_width() / videoSize.width;\n\tfloat scaleY = rc.get_height() / videoSize.height;\n\tif (scaleX != m_pSprite->getScaleX())\n\t\tm_pSprite->setScaleX(scaleX);\n\tif (scaleY != m_pSprite->getScaleY())\n\t\tm_pSprite->setScaleY(scaleY);\n\tcocos2d::Vec2 pos = m_pSprite->getPosition();\n\tint top = m_pRootNode->getParent()->getContentSize().height - rc.top;\n\tif ((int)pos.x != rc.left || (int)pos.y != top) {\n\t\tm_pSprite->setPosition(rc.left, top);\n\t}\n}\n\nvoid KRMovie::VideoPresentOverlay::Play()\n{\n\tif (m_pSprite) m_pSprite->setVisible(true);\n\tTVPMoviePlayer::Play();\n}\n\nvoid KRMovie::VideoPresentOverlay::Stop()\n{\n\tif (m_pSprite) m_pSprite->setVisible(false);\n\tTVPMoviePlayer::Stop();\n}\n\nMoviePlayerOverlay::~MoviePlayerOverlay()\n{\n\tassert(std::this_thread::get_id() == TVPMainThreadID);\n\tdelete m_pPlayer; m_pPlayer = nullptr;\n}\n\nvoid MoviePlayerOverlay::SetWindow(tTJSNI_Window* window)\n{\n\tClearNode();\n\tm_pOwnerWindow = window;\n\tcocos2d::Node *parent = m_pOwnerWindow->GetForm()->GetPrimaryArea();\n\tparent->addChild((m_pRootNode = cocos2d::Node::create()));\n\tm_pRootNode->setContentSize(cocos2d::Size::ZERO);\n\tconst static std::string sckey(\"update video\");\n\tm_pRootNode->schedule([this](float dt){\n\t\tPresentPicture(dt);\n\t\t//\t\tm_renderManager.Render();\n\t}, sckey);\n}\n\nvoid MoviePlayerOverlay::BuildGraph(tTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size)\n{\n\tm_pCallbackWin = callbackwin;\n\tm_pPlayer->SetCallback(std::bind(&MoviePlayerOverlay::OnPlayEvent, this, std::placeholders::_1, std::placeholders::_2));\n\tm_pPlayer->OpenFromStream(stream, streamname, type, size);\n}\n\nconst tTVPRect & MoviePlayerOverlay::GetBounds()\n{\n\treturn m_pCallbackWin->GetBounds();\n}\n\nvoid KRMovie::MoviePlayerOverlay::SetVisible(bool b)\n{\n\tVideoPresentOverlay::SetVisible(b);\n\tif (m_pRootNode) {\n\t\tm_pRootNode->setVisible(b);\n\t}\n}\n\nvoid MoviePlayerOverlay::OnPlayEvent(KRMovieEvent msg, void *p)\n{\n\tif (msg == KRMovieEvent::Ended) {\n\t\tNativeEvent ev(WM_GRAPHNOTIFY);\n\t\tev.WParam = EC_COMPLETE;\n\t\tev.LParam = 0;\n\t\tm_pCallbackWin->PostEvent(ev);\n\t}\n}\n\nvoid VideoPresentOverlay::BitmapPicture::swap(BitmapPicture &r)\n{\n\tstd::swap(data, r.data);\n\tstd::swap(width, r.width);\n\tstd::swap(height, r.height);\n}\n\nvoid TVPMoviePlayer::BitmapPicture::Clear()\n{\n\tfor (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i)\n\t\tif (data[i]) TJSAlignedDealloc(data[i]), data[i] = nullptr;\n}\n\nvoid VideoPresentOverlay2::SetRootNode(cocos2d::Node *node)\n{\n\tClearNode();\n\tm_pRootNode = node;\n}\n\nVideoPresentOverlay2 * VideoPresentOverlay2::create()\n{\n\treturn new VideoPresentOverlay2;\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/KRMoviePlayer.h",
    "content": "#pragma once\n#define NOMINMAX\n#include \"VideoPlayer.h\"\n#include \"krmovie.h\"\n#include \"ComplexRect.h\"\nstruct SwsContext;\nclass iTVPSoundBuffer;\nclass TVPYUVSprite;\n\nnamespace cocos2d {\n\tclass Sprite;\n\tclass Node;\n}\n\nNS_KRMOVIE_BEGIN\n#define MAX_BUFFER_COUNT 4\n\nclass TVPMoviePlayer : public iTVPVideoOverlay, public CBaseRenderer {\npublic:\n\t~TVPMoviePlayer();\n\tvirtual void AddRef() override { RefCount++; }\n\tvirtual void Release() override;\n\n\tvirtual void SetVisible(bool b) override { Visible = b; }\n\tvirtual void Play() override { m_pPlayer->Play(); }\n\tvirtual void Stop() override { m_pPlayer->Stop(); }\n\tvirtual void Pause() override { m_pPlayer->Pause(); }\n\tvirtual void SetPosition(uint64_t tick) override;\n\tvirtual void GetPosition(uint64_t *tick) override;\n\tvirtual void GetStatus(tTVPVideoStatus *status) override;\n\n\tvirtual void Rewind() override;\n\tvirtual void SetFrame(int f) override;\n\tvirtual void GetFrame(int *f) override;\n\tvirtual void GetFPS(double *f) override;\n\tvirtual void GetNumberOfFrame(int *f) override;\n\tvirtual void GetTotalTime(int64_t *t) override;\n\n\tvirtual void GetVideoSize(long *width, long *height) override;\n\n\tvirtual void SetPlayRate(double rate) override;\n\tvirtual void GetPlayRate(double *rate) override;\n\n\tvirtual void SetAudioBalance(long balance) override;\n\tvirtual void GetAudioBalance(long *balance) override;\n\tvirtual void SetAudioVolume(long volume) override;\n\tvirtual void GetAudioVolume(long *volume) override;\n\n\tvirtual void GetNumberOfAudioStream(unsigned long *streamCount) override;\n\tvirtual void SelectAudioStream(unsigned long num) override;\n\tvirtual void GetEnableAudioStreamNum(long *num) override;\n\tvirtual void DisableAudioStream(void) override;\n\n\tvirtual void GetNumberOfVideoStream(unsigned long *streamCount) override;\n\tvirtual void SelectVideoStream(unsigned long num) override;\n\tvirtual void GetEnableVideoStreamNum(long *num) override;\n\n\t// TODO\n\tvirtual void SetStopFrame(int frame) override {}\n\tvirtual void GetStopFrame(int *frame) override {}\n\tvirtual void SetDefaultStopFrame() override {}\n\n\t// function for overlay mode\n\tvirtual void SetWindow(class tTJSNI_Window* window) override {}\n\tvirtual void SetMessageDrainWindow(void* window) override {}\n\tvirtual void SetRect(int l, int t, int r, int b) override {}\n\n\t// function for layer mode\n\tvirtual tTVPBaseTexture* GetFrontBuffer() override { return nullptr; }\n\tvirtual void SetVideoBuffer(tTVPBaseTexture *buff1, tTVPBaseTexture *buff2, long size) override {}\n\n\t// function for mixer mode\n\tvirtual void SetMixingBitmap(class tTVPBaseTexture *dest, float alpha) override {}\n\tvirtual void ResetMixingBitmap() override {}\n\n\tvirtual void SetMixingMovieAlpha(float a) override {}\n\tvirtual void GetMixingMovieAlpha(float *a) override { *a = 1.0f; }\n\tvirtual void SetMixingMovieBGColor(unsigned long col) override {}\n\tvirtual void GetMixingMovieBGColor(unsigned long *col) override { *col = 0xFF000000; }\n\n\tvirtual void PresentVideoImage() override {}\n\n\tvirtual void GetContrastRangeMin(float *v) override {}\n\tvirtual void GetContrastRangeMax(float *v) override {}\n\tvirtual void GetContrastDefaultValue(float *v) override {}\n\tvirtual void GetContrastStepSize(float *v) override {}\n\tvirtual void GetContrast(float *v) override {}\n\tvirtual void SetContrast(float v) override {}\n\n\tvirtual void GetBrightnessRangeMin(float *v) override {}\n\tvirtual void GetBrightnessRangeMax(float *v) override {}\n\tvirtual void GetBrightnessDefaultValue(float *v) override {}\n\tvirtual void GetBrightnessStepSize(float *v) override {}\n\tvirtual void GetBrightness(float *v) override {}\n\tvirtual void SetBrightness(float v) override {}\n\n\tvirtual void GetHueRangeMin(float *v) override {}\n\tvirtual void GetHueRangeMax(float *v) override {}\n\tvirtual void GetHueDefaultValue(float *v) override {}\n\tvirtual void GetHueStepSize(float *v) override {}\n\tvirtual void GetHue(float *v) override {}\n\tvirtual void SetHue(float v) override {}\n\n\tvirtual void GetSaturationRangeMin(float *v) override {}\n\tvirtual void GetSaturationRangeMax(float *v) override {}\n\tvirtual void GetSaturationDefaultValue(float *v) override {}\n\tvirtual void GetSaturationStepSize(float *v) override {}\n\tvirtual void GetSaturation(float *v) override {}\n\tvirtual void SetSaturation(float v) override {}\n\n\tvirtual void SetLoopSegement(int beginFrame, int endFrame) override;\n\n\tvirtual int AddVideoPicture(DVDVideoPicture &pic, int index) override;\n\tvirtual int WaitForBuffer(volatile std::atomic_bool&bStop, int timeout = 0) override;\n\tvirtual void Flush() override;\n\n\tbool IsPlaying() const { return m_pPlayer->IsPlaying(); }\n\tvoid FrameMove();\n\nprotected:\n\tTVPMoviePlayer();\n\tiTVPSoundBuffer* GetSoundDevice();\n\n\tuint32_t\tRefCount = 1;\n\tbool\t\tVisible = false;\n\n\tBasePlayer *m_pPlayer = nullptr;\n\n\tstruct BitmapPicture {\n\t\tERenderFormat fmt;\n\t\tunion {\n\t\t\tuint8_t *data[4];\n\t\t\tuint8_t *rgba;\n\t\t\tuint8_t *yuv[3];\n\t\t};\n\t\tint width = 0; // pitch = width * 4\n\t\tint height = 0;\n\t\tdouble pts;\n\t\tBitmapPicture() {\n\t\t\tfmt = RENDER_FMT_NONE;\n\t\t\tfor (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i)\n\t\t\t\tdata[i] = nullptr;\n\t\t}\n\t\t~BitmapPicture() { Clear(); }\n\t\tvoid swap(BitmapPicture &r);\n\t\tvoid Clear();\n\t};\n\tBitmapPicture m_picture[MAX_BUFFER_COUNT];\n\tint m_curPicture = 0, m_usedPicture = 0;\n\tstd::mutex m_mtxPicture;\n\tstd::condition_variable m_condPicture;\n\tstruct SwsContext *img_convert_ctx = nullptr;\n\tdouble m_curpts = 0;\n};\n\nclass VideoPresentOverlay : public TVPMoviePlayer // cocos2d compatible video display overlay\n{\nprotected:\n\tcocos2d::Node *m_pRootNode = nullptr;\n\tTVPYUVSprite *m_pSprite = nullptr;\n\n\t~VideoPresentOverlay();\n\tvoid ClearNode();\npublic:\n\tvoid PresentPicture(float dt);\n\tvirtual void Stop() override;\n\tvirtual void Play() override;\n\nprotected:\n\tvirtual const tTVPRect &GetBounds() = 0;\n};\n\nclass MoviePlayerOverlay : public VideoPresentOverlay {\n\ttTJSNI_VideoOverlay* m_pCallbackWin = nullptr;\n\ttTJSNI_Window *m_pOwnerWindow = nullptr;\n\n\tvoid OnPlayEvent(KRMovieEvent msg, void *p);\n\npublic:\n\t~MoviePlayerOverlay();\n\tvirtual void SetWindow(class tTJSNI_Window* window) override;\n\n\tvoid BuildGraph(tTJSNI_VideoOverlay* callbackwin, IStream *stream,\n\t\tconst tjs_char * streamname, const tjs_char *type, uint64_t size);\n\n\tvirtual const tTVPRect &GetBounds() override;\n\tvirtual void SetVisible(bool b) override;\n};\n\nclass VideoPresentOverlay2 : public VideoPresentOverlay {\n\tstd::function<const tTVPRect &()> m_funcGetBounds;\npublic:\n\tvirtual const tTVPRect &GetBounds() override { return m_funcGetBounds(); }\n\tvoid SetFuncGetBounds(const std::function<const tTVPRect &()>& func) { m_funcGetBounds = func; }\n\tBasePlayer *GetPlayer() { return m_pPlayer; }\n\tvoid SetRootNode(cocos2d::Node *node);\n\tcocos2d::Node *GetRootNode() { return m_pRootNode; }\n\tstatic VideoPresentOverlay2 *create();\n};\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/MathUtils.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include <stdint.h>\n#include <cassert>\n#include <climits>\n#include <cmath>\n\n// use real compiler defines in here as we want to\n// avoid including system.h or other magic includes.\n// use 'gcc -dM -E - < /dev/null' or similar to find them.\n\n#if defined(__ppc__) || \\\n    defined(__powerpc__) || \\\n    defined(__mips__) || \\\n    defined(__arm__) || \\\n    defined(__aarch64__)\n  #define DISABLE_MATHUTILS_ASM_ROUND_INT\n#endif\nNS_KRMOVIE_BEGIN\n/*! \\brief Math utility class.\n Note that the test() routine should return true for all implementations\n\n See http://ldesoras.free.fr/doc/articles/rounding_en.pdf for an explanation\n of the technique used on x86.\n */\nnamespace MathUtils\n{\n  // GCC does something stupid with optimization on release builds if we try\n  // to assert in these functions\n\n  /*! \\brief Round to nearest integer.\n   This routine does fast rounding to the nearest integer.\n   In the case (k + 0.5 for any integer k) we round up to k+1, and in all other\n   instances we should return the nearest integer.\n   Thus, { -1.5, -0.5, 0.5, 1.5 } is rounded to { -1, 0, 1, 2 }.\n   It preserves the property that round(k) - round(k-1) = 1 for all doubles k.\n\n   Make sure MathUtils::test() returns true for each implementation.\n   \\sa truncate_int, test\n  */\n  inline int round_int(double x)\n  {\n    assert(x > static_cast<double>((int) (INT_MIN / 2)) - 1.0);\n    assert(x < static_cast<double>((int) (INT_MAX / 2)) + 1.0);\n\n#if defined(DISABLE_MATHUTILS_ASM_ROUND_INT)\n    /* This implementation warrants some further explanation.\n     *\n     * First, a couple of notes on rounding:\n     * 1) C casts from float/double to integer round towards zero.\n     * 2) Float/double additions are rounded according to the normal rules,\n     *    in other words: on some architectures, it's fixed at compile-time,\n     *    and on others it can be set using fesetround()). The following\n     *    analysis assumes round-to-nearest with ties rounding to even. This\n     *    is a fairly sensible choice, and is the default with ARM VFP.\n     *\n     * What this function wants is round-to-nearest with ties rounding to\n     * +infinity. This isn't an IEEE rounding mode, even if we could guarantee\n     * that all architectures supported fesetround(), which they don't. Instead,\n     * this adds an offset of 2147483648.5 (= 0x80000000.8p0), then casts to\n     * an unsigned int (crucially, all possible inputs are now in a range where\n     * round to zero acts the same as round to -infinity) and then subtracts\n     * 0x80000000 in the integer domain. The 0.5 component of the offset\n     * converts what is effectively a round down into a round to nearest, with\n     * ties rounding up, as desired.\n     *\n     * There is a catch, that because there is a double rounding, there is a\n     * small region where the input falls just *below* a tie, where the addition\n     * of the offset causes a round *up* to an exact integer, due to the finite\n     * level of precision available in floating point. You need to be aware of\n     * this when calling this function, although at present it is not believed\n     * that XBMC ever attempts to round numbers in this window.\n     *\n     * It is worth proving the size of the affected window. Recall that double\n     * precision employs a mantissa of 52 bits.\n     * 1) For all inputs -0.5 <= x <= INT_MAX\n     *    Once the offset is applied, the most significant binary digit in the\n     *    floating-point representation is +2^31.\n     *    At this magnitude, the smallest step representable in double precision\n     *    is 2^31 / 2^52 = 0.000000476837158203125\n     *    So the size of the range which is rounded up due to the addition is\n     *    half the size of this step, or 0.0000002384185791015625\n     *\n     * 2) For all inputs INT_MIN/2 < x < -0.5\n     *    Once the offset is applied, the most significant binary digit in the\n     *    floating-point representation is +2^30.\n     *    At this magnitude, the smallest step representable in double precision\n     *    is 2^30 / 2^52 = 0.0000002384185791015625\n     *    So the size of the range which is rounded up due to the addition is\n     *    half the size of this step, or 0.00000011920928955078125\n     *\n     * 3) For all inputs INT_MIN <= x <= INT_MIN/2\n     *    The representation once the offset is applied has equal or greater\n     *    precision than the input, so the addition does not cause rounding.\n     */\n    return ((unsigned int) (x + 0x80000000.8p0)) - 0x80000000;\n\n#else\n    const float round_to_nearest = 0.5f;\n    int i;\n#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))\n    const float round_dn_to_nearest = 0.4999999f;\n    i = (x > 0) ? _mm_cvttsd_si32(_mm_set_sd(x + round_to_nearest)) : _mm_cvttsd_si32(_mm_set_sd(x - round_dn_to_nearest));\n\n// #elif defined(_MSC_VER)\n//     __asm\n//     {\n//       fld x\n//       fadd st, st (0)\n//       fadd round_to_nearest\n//       fistp i\n//       sar i, 1\n//     }\n\n#else\n    __asm__ __volatile__ (\n      \"fadd %%st\\n\\t\"\n      \"fadd %%st(1)\\n\\t\"\n      \"fistpl %0\\n\\t\"\n      \"sarl $1, %0\\n\"\n      : \"=m\"(i) : \"u\"(round_to_nearest), \"t\"(x) : \"st\"\n    );\n\n#endif\n    return i;\n#endif\n  }\n\n  /*! \\brief Truncate to nearest integer.\n   This routine does fast truncation to an integer.\n   It should simply drop the fractional portion of the floating point number.\n\n   Make sure MathUtils::test() returns true for each implementation.\n   \\sa round_int, test\n  */\n  inline int truncate_int(double x)\n  {\n    assert(x > static_cast<double>(INT_MIN / 2) - 1.0);\n    assert(x < static_cast<double>(INT_MAX / 2) + 1.0);\n    return static_cast<int>(x);\n  }\n\n  inline int64_t abs(int64_t a)\n  {\n    return (a < 0) ? -a : a;\n  }\n\n  inline unsigned bitcount(unsigned v)\n  {\n    unsigned c = 0;\n    for (c = 0; v; c++)\n      v &= v - 1; // clear the least significant bit set\n    return c;\n  }\n\n  inline void hack()\n  {\n    // stupid hack to keep compiler from dropping these\n    // functions as unused\n    MathUtils::round_int(0.0);\n    MathUtils::truncate_int(0.0);\n    MathUtils::abs(0);\n  }\n\n#if 0\n  /*! \\brief test routine for round_int and truncate_int\n   Must return true on all platforms.\n   */\n  inline bool test()\n  {\n    for (int i = -8; i < 8; ++i)\n    {\n      double d = 0.25*i;\n      int r = (i < 0) ? (i - 1) / 4 : (i + 2) / 4;\n      int t = i / 4;\n      if (round_int(d) != r || truncate_int(d) != t)\n        return false;\n    }\n    return true;\n  }\n#endif\n} // namespace MathUtils\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Message.cpp",
    "content": "#include \"Message.h\"\n#include <condition_variable>\n#include \"Timer.h\"\n#include \"Thread.h\"\n#include <algorithm>\n#include \"DemuxPacket.h\"\n\nNS_KRMOVIE_BEGIN\nclass CDVDMsgGeneralSynchronizePriv\n{\npublic:\n\tCDVDMsgGeneralSynchronizePriv(unsigned int timeout, unsigned int sources)\n\t\t: sources(sources)\n\t\t, reached(0)\n\t\t, timeout(timeout)\n\t{}\n\tunsigned int sources;\n\tunsigned int reached;\n\tCCriticalSection section;\n\tstd::condition_variable_any condition;\n\tTimer timeout;\n};\n\n/**\n* CDVDMsgGeneralSynchronize --- GENERAL_SYNCRONIZR\n*/\nCDVDMsgGeneralSynchronize::CDVDMsgGeneralSynchronize(unsigned int timeout, unsigned int sources) :\nCDVDMsg(GENERAL_SYNCHRONIZE),\nm_p(new CDVDMsgGeneralSynchronizePriv(timeout, sources))\n{\n}\n\nCDVDMsgGeneralSynchronize::~CDVDMsgGeneralSynchronize()\n{\n\tdelete m_p;\n}\n\nbool CDVDMsgGeneralSynchronize::Wait(unsigned int milliseconds, unsigned int source)\n{\n\tCSingleLock lock(m_p->section);\n\n\tTimer timeout(milliseconds);\n\n\tm_p->reached |= (source & m_p->sources);\n\tif ((m_p->sources & SYNCSOURCE_ANY) && source)\n\t\tm_p->reached |= SYNCSOURCE_ANY;\n\n\tm_p->condition.notify_all();\n\n\twhile (m_p->reached != m_p->sources)\n\t{\n\t\tmilliseconds = std::min(m_p->timeout.MillisLeft(), timeout.MillisLeft());\n\t\tif (!milliseconds) milliseconds = 1;\n\t\tif (m_p->condition.wait_for(lock, std::chrono::milliseconds(milliseconds)) != std::cv_status::timeout)\n\t\t\tcontinue;\n\n\t\tif (m_p->timeout.IsTimePast())\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"CDVDMsgGeneralSynchronize - global timeout\");\n\t\t\treturn true;  // global timeout, we are done\n\t\t}\n\t\tif (timeout.IsTimePast())\n\t\t{\n\t\t\treturn false; /* request timeout, should be retried */\n\t\t}\n\t}\n\treturn true;\n}\n\nvoid CDVDMsgGeneralSynchronize::Wait(std::atomic<bool>& abort, unsigned int source)\n{\n\twhile (!Wait(100, source) && !abort);\n}\n\nlong CDVDMsgGeneralSynchronize::Release()\n{\n\tm_p->section.lock();\n\tintptr_t count = --m_refs;\n\tm_p->condition.notify_all();\n\tm_p->section.unlock();\n\tif (count == 0)\n\t\tdelete this;\n\treturn count;\n}\n\n/**\n* CDVDMsgDemuxerPacket --- DEMUXER_PACKET\n*/\nCDVDMsgDemuxerPacket::CDVDMsgDemuxerPacket(DemuxPacket* packet, bool drop) : CDVDMsg(DEMUXER_PACKET)\n{\n\tm_packet = packet;\n\tm_drop = drop;\n}\n\nCDVDMsgDemuxerPacket::~CDVDMsgDemuxerPacket()\n{\n\tif (m_packet)\n\t\tDemuxPacket::Free(m_packet);\n}\n\nunsigned int CDVDMsgDemuxerPacket::GetPacketSize()\n{\n\tif (m_packet)\n\t\treturn m_packet->iSize;\n\telse\n\t\treturn 0;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Message.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"Ref.h\"\n\nNS_KRMOVIE_BEGIN\nclass CDVDMsg : public IRef<CDVDMsg> {\npublic:\n\tenum Message\n\t{\n\t\tNONE = 1000,\n\n\n\t\t// messages used in the whole system\n\n\t\tGENERAL_RESYNC,                 //\n\t\tGENERAL_FLUSH,                  // flush all buffers\n\t\tGENERAL_RESET,                  // reset codecs for new data\n\t\tGENERAL_PAUSE,\n\t\tGENERAL_STREAMCHANGE,           //\n\t\tGENERAL_SYNCHRONIZE,            //\n\t\tGENERAL_GUI_ACTION,             // gui action of some sort\n\t\tGENERAL_EOF,                    // eof of stream\n\n\t\t// player core related messages (cVideoPlayer.cpp)\n\n\t\tPLAYER_SET_AUDIOSTREAM,         //\n\t\tPLAYER_SET_VIDEOSTREAM,         //\n\t\tPLAYER_SET_SUBTITLESTREAM,      //\n\t\tPLAYER_SET_SUBTITLESTREAM_VISIBLE, //\n\t\tPLAYER_SET_STATE,               // restore the VideoPlayer to a certain state\n\t\tPLAYER_SET_RECORD,              // set record state\n\t\tPLAYER_SEEK,                    //\n\t\tPLAYER_SEEK_CHAPTER,            //\n\t\tPLAYER_SETSPEED,                // set the playback speed\n\n\t\tPLAYER_CHANNEL_NEXT,            // switches to next playback channel\n\t\tPLAYER_CHANNEL_PREV,            // switches to previous playback channel\n\t\tPLAYER_CHANNEL_PREVIEW_NEXT,    // switches to next channel preview (does not switch the channel)\n\t\tPLAYER_CHANNEL_PREVIEW_PREV,    // switches to previous channel preview (does not switch the channel)\n\t\tPLAYER_CHANNEL_SELECT_NUMBER,   // switches to the channel with the provided channel number\n\t\tPLAYER_CHANNEL_SELECT,          // switches to the provided channel\n\t\tPLAYER_STARTED,                 // sent whenever a sub player has finished it's first frame after open\n\t\tPLAYER_AVCHANGE,                // signal a change in audio or video parameters\n\n\t\t// demuxer related messages\n\n\t\tDEMUXER_PACKET,                 // data packet\n\t\tDEMUXER_RESET,                  // reset the demuxer\n\n\n\t\t// video related messages\n\n\t\tVIDEO_SET_ASPECT,               // set aspectratio of video\n\t\tVIDEO_DRAIN,                    // wait for decoder to output last frame\n\n\t\t// audio related messages\n\n\t\tAUDIO_SILENCE,\n\n\t\t// subtitle related messages\n\t\tSUBTITLE_CLUTCHANGE,\n\t\tSUBTITLE_ADDFILE\n\t};\n\n\tCDVDMsg(Message msg)\n\t{\n\t\tm_message = msg;\n\t}\n\n\tvirtual ~CDVDMsg()\n\t{\n\t}\n\n\t/**\n\t* checks for message type\n\t*/\n\tinline bool IsType(Message msg)\n\t{\n\t\treturn (m_message == msg);\n\t}\n\n\tinline Message GetMessageType()\n\t{\n\t\treturn m_message;\n\t}\n\n\tlong GetNrOfReferences()\n\t{\n\t\treturn m_refs;\n\t}\n\nprivate:\n\tMessage m_message;\n};\n\n#define SYNCSOURCE_AUDIO  0x01\n#define SYNCSOURCE_VIDEO  0x02\n#define SYNCSOURCE_PLAYER 0x04\n#define SYNCSOURCE_ANY    0x08\n\nclass CDVDMsgGeneralSynchronizePriv;\nclass CDVDMsgGeneralSynchronize : public CDVDMsg\n{\npublic:\n\tCDVDMsgGeneralSynchronize(unsigned int timeout, unsigned int sources);\n\t~CDVDMsgGeneralSynchronize();\n\tvirtual long Release();\n\n\t// waits until all threads waiting, released the object\n\t// if abort is set somehow\n\tbool Wait(unsigned int ms, unsigned int source);\n\tvoid Wait(std::atomic<bool>& abort, unsigned int source);\n\nprivate:\n\tclass CDVDMsgGeneralSynchronizePriv* m_p;\n};\n\ntemplate <typename T>\nclass CDVDMsgType : public CDVDMsg\n{\npublic:\n\tCDVDMsgType(Message type, const T &value)\n\t\t: CDVDMsg(type)\n\t\t, m_value(value)\n\t{}\n\toperator T() { return m_value; }\n\tT m_value;\n};\n\ntypedef CDVDMsgType<bool>   CDVDMsgBool;\ntypedef CDVDMsgType<int>    CDVDMsgInt;\ntypedef CDVDMsgType<double> CDVDMsgDouble;\n\nclass CDVDMsgPlayerSetAudioStream : public CDVDMsg\n{\npublic:\n\tCDVDMsgPlayerSetAudioStream(int streamId) : CDVDMsg(PLAYER_SET_AUDIOSTREAM) { m_streamId = streamId; }\n\tint GetStreamId()                     { return m_streamId; }\nprivate:\n\tint m_streamId;\n};\n\nclass CDVDMsgPlayerSetVideoStream : public CDVDMsg\n{\npublic:\n\tCDVDMsgPlayerSetVideoStream(int streamId) : CDVDMsg(PLAYER_SET_VIDEOSTREAM) { m_streamId = streamId; }\n\tint GetStreamId() const { return m_streamId; }\nprivate:\n\tint m_streamId;\n};\n\nclass CDVDMsgPlayerSeek : public CDVDMsg\n{\npublic:\n\tstruct CMode\n\t{\n\t\tint time = 0;\n\t\tbool relative = false;\n\t\tbool backward = false;\n\t\tbool flush = true;\n\t\tbool accurate = true;\n\t\tbool sync = true;\n\t\tbool restore = true;\n\t\tbool trickplay = false;\n\t};\n\n\tCDVDMsgPlayerSeek(CDVDMsgPlayerSeek::CMode mode) : CDVDMsg(PLAYER_SEEK),\n\t\tm_mode(mode)\n\t{}\n\tint GetTime() { return m_mode.time; }\n\tbool GetRelative() { return m_mode.relative; }\n\tbool GetBackward() { return m_mode.backward; }\n\tbool GetFlush() { return m_mode.flush; }\n\tbool GetAccurate() { return m_mode.accurate; }\n\tbool GetRestore() { return m_mode.restore; }\n\tbool GetTrickPlay() { return m_mode.trickplay; }\n\tbool GetSync() { return m_mode.sync; }\n\nprivate:\n\tCMode m_mode;\n};\nstruct DemuxPacket;\nclass CDVDMsgDemuxerPacket : public CDVDMsg\n{\npublic:\n\tCDVDMsgDemuxerPacket(DemuxPacket* packet, bool drop = false);\n\tvirtual ~CDVDMsgDemuxerPacket();\n\tDemuxPacket* GetPacket()      { return m_packet; }\n\tunsigned int GetPacketSize();\n\tbool         GetPacketDrop()  { return m_drop; }\n\tDemuxPacket* m_packet;\n\tbool         m_drop;\n};\n\nclass CDVDMsgDemuxerReset : public CDVDMsg\n{\npublic:\n\tCDVDMsgDemuxerReset() : CDVDMsg(DEMUXER_RESET)  {}\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/MessageQueue.cpp",
    "content": "#include \"MessageQueue.h\"\n#include \"Clock.h\"\n#include \"DemuxPacket.h\"\n#include <cmath>\n\nNS_KRMOVIE_BEGIN\nCDVDMessageQueue::CDVDMessageQueue(const std::string &owner) : /*m_hEvent(true),*/ m_owner(owner)\n{\n\tm_iDataSize = 0;\n\tm_bAbortRequest = false;\n\tm_bInitialized = false;\n\n\tm_TimeBack = DVD_NOPTS_VALUE;\n\tm_TimeFront = DVD_NOPTS_VALUE;\n\tm_TimeSize = 1.0 / 4.0; /* 4 seconds */\n\tm_iMaxDataSize = 0;\n}\n\nCDVDMessageQueue::~CDVDMessageQueue()\n{\n\t// remove all remaining messages\n\tFlush(CDVDMsg::NONE);\n}\n\nvoid CDVDMessageQueue::Init()\n{\n\tm_iDataSize = 0;\n\tm_bAbortRequest = false;\n\tm_bInitialized = true;\n\tm_TimeBack = DVD_NOPTS_VALUE;\n\tm_TimeFront = DVD_NOPTS_VALUE;\n\tm_drain = false;\n}\n\nvoid CDVDMessageQueue::Flush(CDVDMsg::Message type)\n{\n\tCSingleLock lock(m_section);\n\n\tm_messages.remove_if([type](const DVDMessageListItem &item){\n\t\treturn type == CDVDMsg::NONE || item.message->IsType(type);\n\t});\n\n\tm_prioMessages.remove_if([type](const DVDMessageListItem &item){\n\t\treturn type == CDVDMsg::NONE || item.message->IsType(type);\n\t});\n\n\tif (type == CDVDMsg::DEMUXER_PACKET || type == CDVDMsg::NONE)\n\t{\n\t\tm_iDataSize = 0;\n\t\tm_TimeBack = DVD_NOPTS_VALUE;\n\t\tm_TimeFront = DVD_NOPTS_VALUE;\n\t}\n}\n\nvoid CDVDMessageQueue::Abort()\n{\n\tCSingleLock lock(m_section);\n\n\tm_bAbortRequest = true;\n\n\t// inform waiter for abort action\n\tm_hEvent.notify_all();\n}\n\nvoid CDVDMessageQueue::End()\n{\n\tCSingleLock lock(m_section);\n\n\tFlush(CDVDMsg::NONE);\n\n\tm_bInitialized = false;\n\tm_iDataSize = 0;\n\tm_bAbortRequest = false;\n}\n\nMsgQueueReturnCode CDVDMessageQueue::Put(CDVDMsg* pMsg, int priority, bool front)\n{\n\tCSingleLock lock(m_section);\n\n\tif (!m_bInitialized)\n\t{\n\t//\tCLog::Log(LOGWARNING, \"CDVDMessageQueue(%s)::Put MSGQ_NOT_INITIALIZED\", m_owner.c_str());\n\t\tpMsg->Release();\n\t\treturn MSGQ_NOT_INITIALIZED;\n\t}\n\tif (!pMsg)\n\t{\n\t//\tCLog::Log(LOGFATAL, \"CDVDMessageQueue(%s)::Put MSGQ_INVALID_MSG\", m_owner.c_str());\n\t\treturn MSGQ_INVALID_MSG;\n\t}\n\n\tif (priority > 0)\n\t{\n\t\tint prio = priority;\n\t\tif (!front)\n\t\t\tprio++;\n\n\t\tauto it = std::find_if(m_prioMessages.begin(), m_prioMessages.end(),\n\t\t\t[prio](const DVDMessageListItem &item){\n\t\t\treturn prio <= item.priority;\n\t\t});\n\t\tm_prioMessages.emplace(it, pMsg, priority);\n\t} else\n\t{\n\t\tif (front)\n\t\t\tm_messages.emplace_front(pMsg, priority);\n\t\telse\n\t\t\tm_messages.emplace_back(pMsg, priority);\n\t}\n\n\tif (pMsg->IsType(CDVDMsg::DEMUXER_PACKET) && priority == 0)\n\t{\n\t\tDemuxPacket* packet = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket();\n\t\tif (packet)\n\t\t{\n\t\t\tm_iDataSize += packet->iSize;\n\t\t\tif (packet->dts != DVD_NOPTS_VALUE)\n\t\t\t\tm_TimeFront = packet->dts;\n\t\t\telse if (packet->pts != DVD_NOPTS_VALUE)\n\t\t\t\tm_TimeFront = packet->pts;\n\n\t\t\tif (m_TimeBack == DVD_NOPTS_VALUE)\n\t\t\t\tm_TimeBack = m_TimeFront;\n\t\t}\n\t}\n\n\tpMsg->Release();\n\n\t// inform waiter for new packet\n\tm_hEvent.notify_all();\n\n\treturn MSGQ_OK;\n}\n\nMsgQueueReturnCode CDVDMessageQueue::Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds, int &priority)\n{\n\tCSingleLock lock(m_section);\n\n\t*pMsg = NULL;\n\n\tint ret = 0;\n\n\tif (!m_bInitialized)\n\t{\n\t//\tCLog::Log(LOGFATAL, \"CDVDMessageQueue(%s)::Get MSGQ_NOT_INITIALIZED\", m_owner.c_str());\n\t\treturn MSGQ_NOT_INITIALIZED;\n\t}\n\n\twhile (!m_bAbortRequest)\n\t{\n\t\tstd::list<DVDMessageListItem> &msgs = (priority > 0 || !m_prioMessages.empty()) ? m_prioMessages : m_messages;\n\n\t\tif (!msgs.empty() && (msgs.back().priority >= priority || m_drain))\n\t\t{\n\t\t\tDVDMessageListItem& item(msgs.back());\n\t\t\tpriority = item.priority;\n\n\t\t\tif (item.message->IsType(CDVDMsg::DEMUXER_PACKET) && item.priority == 0)\n\t\t\t{\n\t\t\t\tDemuxPacket* packet = ((CDVDMsgDemuxerPacket*)item.message)->GetPacket();\n\t\t\t\tif (packet)\n\t\t\t\t{\n\t\t\t\t\tm_iDataSize -= packet->iSize;\n\t\t\t\t\tif (packet->dts != DVD_NOPTS_VALUE)\n\t\t\t\t\t\tm_TimeBack = packet->dts;\n\t\t\t\t\telse if (packet->pts != DVD_NOPTS_VALUE)\n\t\t\t\t\t\tm_TimeBack = packet->pts;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t*pMsg = item.message->AddRef();\n\t\t\tmsgs.pop_back();\n\n\t\t\tret = MSGQ_OK;\n\t\t\tbreak;\n\t\t} else if (!iTimeoutInMilliSeconds)\n\t\t{\n\t\t\tret = MSGQ_TIMEOUT;\n\t\t\tbreak;\n\t\t} else\n\t\t{\n//\t\t\tm_hEvent.Reset();\n\t\t\tm_section.unlock();\n\n\t\t\t// wait for a new message\n\t\t\tstd::unique_lock<std::mutex> eventLock(m_mtxEvent);\n\t\t\tif (m_hEvent.wait_for(eventLock, std::chrono::milliseconds(iTimeoutInMilliSeconds)) == std::cv_status::timeout) {\n\t\t\t\tm_section.lock();\n\t\t\t\treturn MSGQ_TIMEOUT;\n\t\t\t}\n\n\t\t\tm_section.lock();\n\t\t}\n\t}\n\n\tif (m_bAbortRequest)\n\t\treturn MSGQ_ABORT;\n\n\treturn (MsgQueueReturnCode)ret;\n}\n\nunsigned CDVDMessageQueue::GetPacketCount(CDVDMsg::Message type)\n{\n\tCSingleLock lock(m_section);\n\n\tif (!m_bInitialized)\n\t\treturn 0;\n\n\tunsigned count = 0;\n\tfor (const auto &item : m_messages)\n\t{\n\t\tif (item.message->IsType(type))\n\t\t\tcount++;\n\t}\n\tfor (const auto &item : m_prioMessages)\n\t{\n\t\tif (item.message->IsType(type))\n\t\t\tcount++;\n\t}\n\n\treturn count;\n}\n\nvoid CDVDMessageQueue::WaitUntilEmpty()\n{\n\t{\n\t\tCSingleLock lock(m_section);\n\t\tm_drain = true;\n\t}\n\n//\tCLog::Log(LOGNOTICE, \"CDVDMessageQueue(%s)::WaitUntilEmpty\", m_owner.c_str());\n\tCDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(40000, SYNCSOURCE_ANY);\n\tPut(msg->AddRef());\n\tmsg->Wait(m_bAbortRequest, 0);\n\tmsg->Release();\n\n\t{\n\t\tCSingleLock lock(m_section);\n\t\tm_drain = false;\n\t}\n}\n\nint CDVDMessageQueue::GetLevel()\n{\n\tCSingleLock lock(m_section);\n\n\tif (m_iDataSize > m_iMaxDataSize)\n\t\treturn 100;\n\tif (m_iDataSize == 0)\n\t\treturn 0;\n\n\tif (IsDataBased())\n\t\treturn std::min(100, 100 * m_iDataSize / m_iMaxDataSize);\n\n\tint level = std::min(100.0, std::ceil(100.0 * m_TimeSize * (m_TimeFront - m_TimeBack) / DVD_TIME_BASE));\n\n\t// if we added lots of packets with NOPTS, make sure that the queue is not signalled empty\n\tif (level == 0 && m_iDataSize != 0)\n\t{\n\t//\tCLog::Log(LOGDEBUG, \"CDVDMessageQueue::GetLevel() - can't determine level\");\n\t\treturn 1;\n\t}\n\n\treturn level;\n}\n\nvoid CDVDMessageQueue::SetMaxTimeSize(double sec)\n{\n\tm_TimeSize = 1.0 / std::max(1.0, sec);\n}\n\nint CDVDMessageQueue::GetTimeSize()\n{\n\tCSingleLock lock(m_section);\n\n\tif (IsDataBased())\n\t\treturn 0;\n\telse\n\t\treturn (int)((m_TimeFront - m_TimeBack) / DVD_TIME_BASE);\n}\n\nbool CDVDMessageQueue::IsDataBased() const\n{\n\treturn (m_TimeBack == DVD_NOPTS_VALUE ||\n\t\tm_TimeFront == DVD_NOPTS_VALUE ||\n\t\tm_TimeFront <= m_TimeBack);\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/MessageQueue.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"Message.h\"\n#include <condition_variable>\n#include <list>\n#include <algorithm>\n#include \"Thread.h\"\n#include <string>\n\nNS_KRMOVIE_BEGIN\n\nstruct DVDMessageListItem\n{\n\tDVDMessageListItem(CDVDMsg* msg, int prio)\n\t{\n\t\tmessage = msg->AddRef();\n\t\tpriority = prio;\n\t}\n\tDVDMessageListItem()\n\t{\n\t\tmessage = NULL;\n\t\tpriority = 0;\n\t}\n\tDVDMessageListItem(const DVDMessageListItem&) = delete;\n\t~DVDMessageListItem()\n\t{\n\t\tif (message)\n\t\t\tmessage->Release();\n\t}\n\n\tDVDMessageListItem& operator=(const DVDMessageListItem&) = delete;\n\n\tCDVDMsg* message;\n\tint priority;\n};\n\nenum MsgQueueReturnCode\n{\n\tMSGQ_OK = 1,\n\tMSGQ_TIMEOUT = 0,\n\tMSGQ_ABORT = -1, // negative for legacy, not an error actually\n\tMSGQ_NOT_INITIALIZED = -2,\n\tMSGQ_INVALID_MSG = -3,\n\tMSGQ_OUT_OF_MEMORY = -4\n};\n#define MSGQ_IS_ERROR(c)    (c < 0)\n\nclass CDVDMessageQueue\n{\npublic:\n\tCDVDMessageQueue(const std::string &owner);\n\tvirtual ~CDVDMessageQueue();\n\tvoid Init();\n\tvoid Flush(CDVDMsg::Message message = CDVDMsg::DEMUXER_PACKET);\n\tvoid Abort();\n\tvoid End();\n\n\tMsgQueueReturnCode Put(CDVDMsg* pMsg, int priority = 0, bool front = true);\n\n\tMsgQueueReturnCode Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds, int &priority);\n\tMsgQueueReturnCode Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds) {\n\t\tint priority = 0;\n\t\treturn Get(pMsg, iTimeoutInMilliSeconds, priority);\n\t}\n\n\tint GetDataSize() const { return m_iDataSize; }\n\tint GetTimeSize();\n\tunsigned GetPacketCount(CDVDMsg::Message type);\n\tbool ReceivedAbortRequest() { return m_bAbortRequest; }\n\tvoid WaitUntilEmpty();\n\n\t// non messagequeue related functions\n\tbool IsFull() { return GetLevel() == 100; }\n\tint GetLevel();\n\n\tvoid SetMaxDataSize(int iMaxDataSize) { m_iMaxDataSize = iMaxDataSize; }\n\tvoid SetMaxTimeSize(double sec);\n\tint GetMaxDataSize() const { return m_iMaxDataSize; }\n\tdouble GetMaxTimeSize() const { return m_TimeSize; }\n\tbool IsInited() const { return m_bInitialized; }\n\tbool IsDataBased() const;\n\nprivate:\n\tstd::mutex m_mtxEvent;\n\tstd::condition_variable m_hEvent;\n\tCCriticalSection m_section;\n\n\tstd::atomic<bool> m_bAbortRequest;\n\tbool m_bInitialized;\n\tbool m_drain;\n\n\tint m_iDataSize;\n\tdouble m_TimeFront;\n\tdouble m_TimeBack;\n\tdouble m_TimeSize;\n\n\tint m_iMaxDataSize;\n\tstd::string m_owner;\n\n\tstd::list<DVDMessageListItem> m_messages;\n\tstd::list<DVDMessageListItem> m_prioMessages;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/OptionInfo.h",
    "content": "//---------------------------------------------------------------------------\n// option information for kirikiri configurator\n//---------------------------------------------------------------------------\n\n#ifndef __OptionInfoH__\n#define __OptionInfoH__\n\n#include <windows.h>\n#include \"tp_stub.h\"\n#include <tchar.h>\n\n\n//---------------------------------------------------------------------------\n// GetOptionInfoString: returns option information string for kirikiri conf.\n//---------------------------------------------------------------------------\nstatic inline const wchar_t * GetOptionInfoString()\n{\n\t\treturn\n\t\t// for other languages; currently only English information is available.\nL\"Debug:ROT registration;Whether to register into ROT(Running Object Table) when \"\nL\"playbacking movies. Choosing 'Yes' enables you to inspect the trouble related with movies, \"\nL\"using GraphEdit(available from DirectX SDK). 'Pause' not only enables ROT registeration, \"\nL\"but makes the program also displaying message-box (this interrupts the program and makes a pause) \"\nL\"after the graph is built.|\"\nL\"movie_reg_rot|select,*no;No,yes;Yes,pause;Pause\\n\";\n}\n\n#endif\n"
  },
  {
    "path": "src/core/movie/ffmpeg/ProcessInfo.cpp",
    "content": "#include \"ProcessInfo.h\"\n\nNS_KRMOVIE_BEGIN\n// Override for platform ports\n#if !defined(PLATFORM_OVERRIDE)\n\nCProcessInfo* CProcessInfo::CreateInstance()\n{\n\treturn new CProcessInfo();\n}\n\n#endif\n\n\n// base class definitions\nCProcessInfo::CProcessInfo()\n{\n\n}\n\nCProcessInfo::~CProcessInfo()\n{\n\n}\n\nvoid CProcessInfo::ResetVideoCodecInfo()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoIsHWDecoder = false;\n\tm_videoDecoderName = \"unknown\";\n\tm_videoDeintMethod = \"unknown\";\n\tm_videoPixelFormat = \"unknown\";\n\tm_videoWidth = 0;\n\tm_videoHeight = 0;\n\tm_videoFPS = 0.0;\n// \tm_deintMethods.clear();\n// \tm_deintMethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE);\n// \tm_deintMethodDefault = EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE;\n\tm_renderInfo.Reset();\n\tm_stateSeeking = false;\n\n// \tCServiceBroker::GetDataCacheCore().SetVideoDecoderName(m_videoDecoderName, m_videoIsHWDecoder);\n// \tCServiceBroker::GetDataCacheCore().SetVideoDeintMethod(m_videoDeintMethod);\n// \tCServiceBroker::GetDataCacheCore().SetVideoPixelFormat(m_videoPixelFormat);\n// \tCServiceBroker::GetDataCacheCore().SetVideoDimensions(m_videoWidth, m_videoHeight);\n// \tCServiceBroker::GetDataCacheCore().SetVideoFps(m_videoFPS);\n// \tCServiceBroker::GetDataCacheCore().SetStateSeeking(m_stateSeeking);\n}\n\nvoid CProcessInfo::SetVideoDecoderName(std::string name, bool isHw)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoIsHWDecoder = isHw;\n\tm_videoDecoderName = name;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoDecoderName(m_videoDecoderName, m_videoIsHWDecoder);\n}\n\nstd::string CProcessInfo::GetVideoDecoderName()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoDecoderName;\n}\n\nbool CProcessInfo::IsVideoHwDecoder()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoIsHWDecoder;\n}\n\nvoid CProcessInfo::SetVideoDeintMethod(std::string method)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoDeintMethod = method;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoDeintMethod(m_videoDeintMethod);\n}\n\nstd::string CProcessInfo::GetVideoDeintMethod()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoDeintMethod;\n}\n\nvoid CProcessInfo::SetVideoPixelFormat(std::string pixFormat)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoPixelFormat = pixFormat;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoPixelFormat(m_videoPixelFormat);\n}\n\nstd::string CProcessInfo::GetVideoPixelFormat()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoPixelFormat;\n}\n\nvoid CProcessInfo::SetVideoDimensions(int width, int height)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoWidth = width;\n\tm_videoHeight = height;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoDimensions(m_videoWidth, m_videoHeight);\n}\n\nvoid CProcessInfo::GetVideoDimensions(int &width, int &height)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\twidth = m_videoWidth;\n\theight = m_videoHeight;\n}\n\nvoid CProcessInfo::SetVideoFps(float fps)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoFPS = fps;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoFps(m_videoFPS);\n}\n\nfloat CProcessInfo::GetVideoFps()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoFPS;\n}\n\nvoid CProcessInfo::SetVideoDAR(float dar)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_videoDAR = dar;\n\n//\tCServiceBroker::GetDataCacheCore().SetVideoDAR(m_videoDAR);\n}\n\nfloat CProcessInfo::GetVideoDAR()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_videoDAR;\n}\n#if 0\nEINTERLACEMETHOD CProcessInfo::GetFallbackDeintMethod()\n{\n\treturn VS_INTERLACEMETHOD_DEINTERLACE;\n}\n\nvoid CProcessInfo::SetSwDeinterlacingMethods()\n{\n\tstd::list<EINTERLACEMETHOD> methods;\n\tmethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE);\n\tmethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE);\n\tmethods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE_HALF);\n\n\tUpdateDeinterlacingMethods(methods);\n\tSetDeinterlacingMethodDefault(EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE);\n}\n\nvoid CProcessInfo::UpdateDeinterlacingMethods(std::list<EINTERLACEMETHOD> &methods)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_deintMethods = methods;\n\n\tfor (auto &deint : m_renderInfo.m_deintMethods)\n\t{\n\t\tif (!Supports(deint))\n\t\t\tm_deintMethods.push_back(deint);\n\t}\n\n\tif (!Supports(EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE))\n\t\tm_deintMethods.push_front(EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE);\n}\n\nbool CProcessInfo::Supports(EINTERLACEMETHOD method)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tauto it = std::find(m_deintMethods.begin(), m_deintMethods.end(), method);\n\tif (it != m_deintMethods.end())\n\t\treturn true;\n\n\treturn false;\n}\n\nvoid CProcessInfo::SetDeinterlacingMethodDefault(EINTERLACEMETHOD method)\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\tm_deintMethodDefault = method;\n}\n\nEINTERLACEMETHOD CProcessInfo::GetDeinterlacingMethodDefault()\n{\n\tCSingleLock lock(m_videoCodecSection);\n\n\treturn m_deintMethodDefault;\n}\n#endif\n// player audio info\nvoid CProcessInfo::ResetAudioCodecInfo()\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\tm_audioDecoderName = \"unknown\";\n\tm_audioChannels = \"unknown\";\n\tm_audioSampleRate = 0;;\n\tm_audioBitsPerSample = 0;\n\n// \tCServiceBroker::GetDataCacheCore().SetAudioDecoderName(m_audioDecoderName);\n// \tCServiceBroker::GetDataCacheCore().SetAudioChannels(m_audioChannels);\n// \tCServiceBroker::GetDataCacheCore().SetAudioSampleRate(m_audioSampleRate);\n// \tCServiceBroker::GetDataCacheCore().SetAudioBitsPerSample(m_audioBitsPerSample);\n}\n\nvoid CProcessInfo::SetAudioDecoderName(std::string name)\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\tm_audioDecoderName = name;\n\n//\tCServiceBroker::GetDataCacheCore().SetAudioDecoderName(m_audioDecoderName);\n}\n\nstd::string CProcessInfo::GetAudioDecoderName()\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\treturn m_audioDecoderName;\n}\n\nvoid CProcessInfo::SetAudioChannels(std::string channels)\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\tm_audioChannels = channels;\n\n//\tCServiceBroker::GetDataCacheCore().SetAudioChannels(m_audioChannels);\n}\n\nstd::string CProcessInfo::GetAudioChannels()\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\treturn m_audioChannels;\n}\n\nvoid CProcessInfo::SetAudioSampleRate(int sampleRate)\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\tm_audioSampleRate = sampleRate;\n\n//\tCServiceBroker::GetDataCacheCore().SetAudioSampleRate(m_audioSampleRate);\n}\n\nint CProcessInfo::GetAudioSampleRate()\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\treturn m_audioSampleRate;\n}\n\nvoid CProcessInfo::SetAudioBitsPerSample(int bitsPerSample)\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\tm_audioBitsPerSample = bitsPerSample;\n\n//\tCServiceBroker::GetDataCacheCore().SetAudioBitsPerSample(m_audioBitsPerSample);\n}\n\nint CProcessInfo::GetAudioBitsPerSample()\n{\n\tCSingleLock lock(m_audioCodecSection);\n\n\treturn m_audioBitsPerSample;\n}\n\nbool CProcessInfo::AllowDTSHDDecode()\n{\n\treturn true;\n}\n\nvoid CProcessInfo::SetRenderClockSync(bool enabled)\n{\n\tCSingleLock lock(m_renderSection);\n\n\tm_isClockSync = enabled;\n\n//\tCServiceBroker::GetDataCacheCore().SetRenderClockSync(enabled);\n}\n\nbool CProcessInfo::IsRenderClockSync()\n{\n\tCSingleLock lock(m_renderSection);\n\n\treturn m_isClockSync;\n}\n\nvoid CProcessInfo::UpdateRenderInfo(CRenderInfo &info)\n{\n\tCSingleLock lock(m_renderSection);\n\n\tm_renderInfo = info;\n\n// \tfor (auto &deint : m_renderInfo.m_deintMethods)\n// \t{\n// \t\tif (!Supports(deint))\n// \t\t\tm_deintMethods.push_back(deint);\n// \t}\n}\n\n// player states\nvoid CProcessInfo::SetStateSeeking(bool active)\n{\n\tCSingleLock lock(m_renderSection);\n\n\tm_stateSeeking = active;\n\n//\tCServiceBroker::GetDataCacheCore().SetStateSeeking(active);\n}\n\nbool CProcessInfo::IsSeeking()\n{\n\tCSingleLock lock(m_stateSection);\n\n\treturn m_stateSeeking;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/ProcessInfo.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"Thread.h\"\n#include \"RenderFormats.h\"\n#include <string>\n\nNS_KRMOVIE_BEGIN\nclass CProcessInfo\n{\npublic:\n\tstatic CProcessInfo* CreateInstance();\n\tvirtual ~CProcessInfo();\n\n\t// player video info\n\tvoid ResetVideoCodecInfo();\n\tvoid SetVideoDecoderName(std::string name, bool isHw);\n\tstd::string GetVideoDecoderName();\n\tbool IsVideoHwDecoder();\n\tvoid SetVideoDeintMethod(std::string method);\n\tstd::string GetVideoDeintMethod();\n\tvoid SetVideoPixelFormat(std::string pixFormat);\n\tstd::string GetVideoPixelFormat();\n\tvoid SetVideoDimensions(int width, int height);\n\tvoid GetVideoDimensions(int &width, int &height);\n\tvoid SetVideoFps(float fps);\n\tfloat GetVideoFps();\n\tvoid SetVideoDAR(float dar);\n\tfloat GetVideoDAR();\n//\tvirtual EINTERLACEMETHOD GetFallbackDeintMethod();\n//\tvirtual void SetSwDeinterlacingMethods();\n//\tvoid UpdateDeinterlacingMethods(std::list<EINTERLACEMETHOD> &methods);\n//\tbool Supports(EINTERLACEMETHOD method);\n//\tvoid SetDeinterlacingMethodDefault(EINTERLACEMETHOD method);\n//\tEINTERLACEMETHOD GetDeinterlacingMethodDefault();\n\n\t// player audio info\n\tvoid ResetAudioCodecInfo();\n\tvoid SetAudioDecoderName(std::string name);\n\tstd::string GetAudioDecoderName();\n\tvoid SetAudioChannels(std::string channels);\n\tstd::string GetAudioChannels();\n\tvoid SetAudioSampleRate(int sampleRate);\n\tint GetAudioSampleRate();\n\tvoid SetAudioBitsPerSample(int bitsPerSample);\n\tint GetAudioBitsPerSample();\n\tvirtual bool AllowDTSHDDecode();\n\n\t// render info\n\tvoid SetRenderClockSync(bool enabled);\n\tbool IsRenderClockSync();\n\tvoid UpdateRenderInfo(CRenderInfo &info);\n\n\t// player states\n\tvoid SetStateSeeking(bool active);\n\tbool IsSeeking();\n\nprotected:\n\tCProcessInfo();\n\n\t// player video info\n\tbool m_videoIsHWDecoder;\n\tstd::string m_videoDecoderName;\n\tstd::string m_videoDeintMethod;\n\tstd::string m_videoPixelFormat;\n\tint m_videoWidth;\n\tint m_videoHeight;\n\tfloat m_videoFPS;\n\tfloat m_videoDAR;\n// \tstd::list<EINTERLACEMETHOD> m_deintMethods;\n// \tEINTERLACEMETHOD m_deintMethodDefault;\n\tCCriticalSection m_videoCodecSection;\n\n\t// player audio info\n\tstd::string m_audioDecoderName;\n\tstd::string m_audioChannels;\n\tint m_audioSampleRate;\n\tint m_audioBitsPerSample;\n\tCCriticalSection m_audioCodecSection;\n\n\t// render info\n\tCCriticalSection m_renderSection;\n\tbool m_isClockSync;\n\tCRenderInfo m_renderInfo;\n\n\t// player states\n\tCCriticalSection m_stateSection;\n\tbool m_stateSeeking;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Ref.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include <atomic>\n#include <assert.h>\n\nNS_KRMOVIE_BEGIN\n\ntemplate<typename T> struct IRef\n{\n\tIRef() : m_refs(1) {}\n\tvirtual ~IRef() {}\n\n\tIRef(const IRef &) = delete;\n\tIRef &operator=(const IRef &) = delete;\n\n\tvirtual T* AddRef()\n\t{\n\t\tm_refs++;\n\t\treturn (T*)this;\n\t}\n\n\tvirtual long Release()\n\t{\n\t\tintptr_t count = --m_refs;\n\t\tassert(count >= 0);\n\t\tif (count == 0) delete (T*)this;\n\t\treturn count;\n\t}\n\tstd::atomic_intptr_t m_refs;\n};\n\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/RenderFlags.cpp",
    "content": "/*\n *      Copyright (C) 2005-2013 Team XBMC\n *      http://xbmc.org\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n */\n\n#include \"RenderFlags.h\"\n#include <string>\n#include <map>\n\nNS_KRMOVIE_BEGIN\nnamespace RenderManager {\n\n  unsigned int GetFlagsColorMatrix(unsigned int color_matrix, unsigned width, unsigned height)\n  {\n    switch(color_matrix)\n    {\n      case 7: // SMPTE 240M (1987)\n        return CONF_FLAGS_YUVCOEF_240M;\n      case 6: // SMPTE 170M\n      case 5: // ITU-R BT.470-2\n      case 4: // FCC\n        return CONF_FLAGS_YUVCOEF_BT601;\n      case 1: // ITU-R Rec.709 (1990) -- BT.709\n        return CONF_FLAGS_YUVCOEF_BT709;\n      case 3: // RESERVED\n      case 2: // UNSPECIFIED\n      default:\n        if(width > 1024 || height >= 600)\n          return CONF_FLAGS_YUVCOEF_BT709;\n        else\n          return CONF_FLAGS_YUVCOEF_BT601;\n        break;\n    }\n  }\n\n  unsigned int GetFlagsChromaPosition(unsigned int chroma_position)\n  {\n    switch(chroma_position)\n    {\n      case 1: return CONF_FLAGS_CHROMA_LEFT;\n      case 2: return CONF_FLAGS_CHROMA_CENTER;\n      case 3: return CONF_FLAGS_CHROMA_TOPLEFT;\n    }\n    return 0;\n  }\n\n  unsigned int GetFlagsColorPrimaries(unsigned int color_primaries)\n  {\n    switch(color_primaries)\n    {\n      case 1: return CONF_FLAGS_COLPRI_BT709;\n      case 4: return CONF_FLAGS_COLPRI_BT470M;\n      case 5: return CONF_FLAGS_COLPRI_BT470BG;\n      case 6: return CONF_FLAGS_COLPRI_170M;\n      case 7: return CONF_FLAGS_COLPRI_240M;\n    }\n    return 0;\n  }\n\n  unsigned int GetFlagsColorTransfer(unsigned int color_transfer)\n  {\n    switch(color_transfer)\n    {\n      case 1: return CONF_FLAGS_TRC_BT709;\n      case 4: return CONF_FLAGS_TRC_GAMMA22;\n      case 5: return CONF_FLAGS_TRC_GAMMA28;\n    }\n    return 0;\n  }\n\n  unsigned int GetStereoModeFlags(const std::string& mode)\n  {\n    static std::map<std::string, unsigned int> convert;\n    if(convert.empty())\n    {\n      convert[\"mono\"]                   = 0u;\n      convert[\"left_right\"]             = CONF_FLAGS_STEREO_MODE_SBS | CONF_FLAGS_STEREO_CADANCE_LEFT_RIGHT;\n      convert[\"bottom_top\"]             = CONF_FLAGS_STEREO_MODE_TAB | CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT;\n      convert[\"top_bottom\"]             = CONF_FLAGS_STEREO_MODE_TAB | CONF_FLAGS_STEREO_CADANCE_LEFT_RIGHT;\n      convert[\"checkerboard_rl\"]        = 0u;\n      convert[\"checkerboard_lr\"]        = 0u;\n      convert[\"row_interleaved_rl\"]     = 0u;\n      convert[\"row_interleaved_lr\"]     = 0u;\n      convert[\"col_interleaved_rl\"]     = 0u;\n      convert[\"col_interleaved_lr\"]     = 0u;\n      convert[\"anaglyph_cyan_red\"]      = 0u;\n      convert[\"right_left\"]             = CONF_FLAGS_STEREO_MODE_SBS | CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT;\n      convert[\"anaglyph_green_magenta\"] = 0u;\n      convert[\"anaglyph_yellow_blue\"]   = 0u;\n      convert[\"block_lr\"]               = 0u;\n      convert[\"block_rl\"]               = 0u;\n    }\n    return convert[mode];\n  }\n\n  std::string GetStereoModeInvert(const std::string& mode)\n  {\n    static std::map<std::string, std::string> convert;\n    if(convert.empty())\n    {\n      convert[\"left_right\"]             = \"right_left\";\n      convert[\"right_left\"]             = \"left_right\";\n      convert[\"bottom_top\"]             = \"top_bottom\";\n      convert[\"top_bottom\"]             = \"bottom_top\";\n      convert[\"checkerboard_rl\"]        = \"checkerboard_lr\";\n      convert[\"checkerboard_lr\"]        = \"checkerboard_rl\";\n      convert[\"row_interleaved_rl\"]     = \"row_interleaved_lr\";\n      convert[\"row_interleaved_lr\"]     = \"row_interleaved_rl\";\n      convert[\"col_interleaved_rl\"]     = \"col_interleaved_lr\";\n      convert[\"col_interleaved_lr\"]     = \"col_interleaved_rl\";\n      convert[\"block_lr\"]               = \"block_rl\";\n      convert[\"block_rl\"]               = \"block_lr\";\n    }\n    std::string res = convert[mode];\n    if(res.empty())\n      return mode;\n    else\n      return res;\n  }\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/RenderFlags.h",
    "content": "#pragma once\n#include <string>\n#include \"KRMovieDef.h\"\n\n#define RENDER_FLAG_BOT         0x01\n#define RENDER_FLAG_TOP         0x02\n#define RENDER_FLAG_BOTH (RENDER_FLAG_BOT | RENDER_FLAG_TOP)\n#define RENDER_FLAG_FIELDMASK   0x03\n\n#define RENDER_FLAG_FIELD0      0x80\n#define RENDER_FLAG_FIELD1      0x100\n#define RENDER_FLAG_WEAVE       0x200\n\n// #define RENDER_FLAG_LAST        0x40\n\n#define RENDER_FLAG_NOOSD       0x04 /* don't draw any osd */\n#define RENDER_FLAG_NOOSDALPHA  0x08 /* don't allow alpha when osd is drawn */\n\n/* these two flags will be used if we need to render same image twice (bob deinterlacing) */\n#define RENDER_FLAG_NOLOCK      0x10   /* don't attempt to lock texture before rendering */\n#define RENDER_FLAG_NOUNLOCK    0x20   /* don't unlock texture after rendering */\n\n/* this defines what color translation coefficients */\n#define CONF_FLAGS_YUVCOEF_MASK(a) ((a) & 0x07)\n#define CONF_FLAGS_YUVCOEF_BT709 0x01\n#define CONF_FLAGS_YUVCOEF_BT601 0x02\n#define CONF_FLAGS_YUVCOEF_240M  0x03\n#define CONF_FLAGS_YUVCOEF_EBU   0x04\n\n#define CONF_FLAGS_YUV_FULLRANGE 0x08\n#define CONF_FLAGS_FULLSCREEN    0x10\n\n/* defines color primaries */\n#define CONF_FLAGS_COLPRI_MASK(a) ((a) & 0xe0)\n#define CONF_FLAGS_COLPRI_BT709   0x20  // sRGB, HDTV (ITU-R BT.709)\n#define CONF_FLAGS_COLPRI_BT470M  0x40  // NTSC (1953) (FCC 1953, ITU-R BT.470 System M)\n#define CONF_FLAGS_COLPRI_BT470BG 0x60  // PAL/SECAM (1970) (EBU Tech. 3213, ITU-R BT.470 System B, G)\n#define CONF_FLAGS_COLPRI_170M    0x80  // NTSC (1987) (SMPTE RP 145 \"SMPTE C\", SMPTE 170M)\n#define CONF_FLAGS_COLPRI_240M    0xa0  // SMPTE-240M\n\n/* defines chroma subsampling sample location */\n#define CONF_FLAGS_CHROMA_MASK(a) ((a) & 0x0300)\n#define CONF_FLAGS_CHROMA_LEFT    0x0100\n#define CONF_FLAGS_CHROMA_CENTER  0x0200\n#define CONF_FLAGS_CHROMA_TOPLEFT 0x0300\n\n/* defines color transfer function */\n#define CONF_FLAGS_TRC_MASK(a) ((a) & 0x0c00)\n#define CONF_FLAGS_TRC_BT709      0x0400\n#define CONF_FLAGS_TRC_GAMMA22    0x0800\n#define CONF_FLAGS_TRC_GAMMA28    0x0c00\n\n/* defines 3d modes */\n#define CONF_FLAGS_STEREO_MODE_MASK(a) ((a) & 0x007000)\n#define CONF_FLAGS_STEREO_MODE_SBS     0x001000\n#define CONF_FLAGS_STEREO_MODE_TAB     0x002000\n\n#define CONF_FLAGS_STEREO_CADENCE(a) ((a) & 0x008000)\n#define CONF_FLAGS_STEREO_CADANCE_LEFT_RIGHT 0x000000\n#define CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT 0x008000\n\nNS_KRMOVIE_BEGIN\n\nnamespace RenderManager {\n\n  unsigned int GetFlagsColorMatrix(unsigned int color_matrix, unsigned width, unsigned height);\n  unsigned int GetFlagsChromaPosition(unsigned int chroma_position);\n  unsigned int GetFlagsColorPrimaries(unsigned int color_primaries);\n  unsigned int GetFlagsColorTransfer(unsigned int color_transfer);\n  unsigned int GetStereoModeFlags(const std::string& mode);\n  std::string  GetStereoModeInvert(const std::string& mode);\n\n}\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/RenderFormats.h",
    "content": "#pragma once\n\n/*\n *      Copyright (C) 2005-2015 Team Kodi\n *      http://kodi.tv\n *\n *  This Program is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation; either version 2, or (at your option)\n *  any later version.\n *\n *  This Program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with Kodi; see the file COPYING.  If not, see\n *  <http://www.gnu.org/licenses/>.\n *\n */\n\n#include \"KRMovieDef.h\"\n#include <cstddef>\n#include <vector>\n\nNS_KRMOVIE_BEGIN\n\nenum ERenderFormat {\n  RENDER_FMT_NONE = 0,\n  RENDER_FMT_YUV420P,\n  RENDER_FMT_YUV420P10,\n  RENDER_FMT_YUV420P16,\n  RENDER_FMT_VDPAU,\n  RENDER_FMT_VDPAU_420,\n  RENDER_FMT_NV12,\n  RENDER_FMT_UYVY422,\n  RENDER_FMT_YUYV422,\n  RENDER_FMT_DXVA,\n  RENDER_FMT_VAAPI,\n  RENDER_FMT_VAAPINV12,\n  RENDER_FMT_OMXEGL,\n  RENDER_FMT_CVBREF,\n  RENDER_FMT_BYPASS,\n  RENDER_FMT_MEDIACODEC,\n  RENDER_FMT_MEDIACODECSURFACE,\n  RENDER_FMT_IMXMAP,\n  RENDER_FMT_MMAL,\n  RENDER_FMT_AML,\n};\n\nstruct CRenderInfo\n{\n  CRenderInfo()\n  {\n    Reset();\n  }\n  void Reset()\n  {\n    optimal_buffer_size = 0;\n    max_buffer_size = 0;\n    opaque_pointer = nullptr;\n//    m_deintMethods.clear();\n    formats.clear();\n  }\n  unsigned int optimal_buffer_size;\n  unsigned int max_buffer_size;\n  // Supported pixel formats, can be called before configure\n  std::vector<ERenderFormat> formats;\n//  std::vector<EINTERLACEMETHOD> m_deintMethods;\n  // Can be used for initialising video codec with information from renderer (e.g. a shared image pool)\n  void *opaque_pointer;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/StreamInfo.cpp",
    "content": "#include \"StreamInfo.h\"\n\nNS_KRMOVIE_BEGIN\nCDVDStreamInfo::CDVDStreamInfo()                                                     { extradata = NULL; Clear(); }\nCDVDStreamInfo::CDVDStreamInfo(const CDVDStreamInfo &right, bool withextradata)     { extradata = NULL; Clear(); Assign(right, withextradata); }\nCDVDStreamInfo::CDVDStreamInfo(const CDemuxStream &right, bool withextradata)       { extradata = NULL; Clear(); Assign(right, withextradata); }\n\nCDVDStreamInfo::~CDVDStreamInfo()\n{\n\tif (extradata && extrasize) free(extradata);\n\n\textradata = NULL;\n\textrasize = 0;\n}\n\nvoid CDVDStreamInfo::Clear()\n{\n\tcodec = AV_CODEC_ID_NONE;\n//\ttype = STREAM_NONE;\n\tuniqueId = -1;\n\trealtime = false;\n\tsoftware = false;\n\tcodec_tag = 0;\n\tflags = 0;\n\tfilename.clear();\n//\tdvd = false;\n\n\tif (extradata && extrasize) free(extradata);\n\n\textradata = NULL;\n\textrasize = 0;\n\n\tfpsscale = 0;\n\tfpsrate = 0;\n\theight = 0;\n\twidth = 0;\n\taspect = 0.0;\n\tvfr = false;\n\tstills = false;\n\tlevel = 0;\n\tprofile = 0;\n\tptsinvalid = false;\n\tforced_aspect = false;\n\tbitsperpixel = 0;\n//\tstereo_mode.clear();\n\n\tchannels = 0;\n\tsamplerate = 0;\n\tblockalign = 0;\n\tbitrate = 0;\n\tbitspersample = 0;\n\tchannellayout = 0;\n\n\torientation = 0;\n}\n\nbool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, bool withextradata)\n{\n\tif (codec != right.codec\n\t//\t|| type != right.type\n\t\t|| uniqueId != right.uniqueId\n\t\t|| realtime != right.realtime\n\t\t|| codec_tag != right.codec_tag\n\t\t|| flags != right.flags)\n\t\treturn false;\n\n\tif (withextradata)\n\t{\n\t\tif (extrasize != right.extrasize) return false;\n\t\tif (extrasize)\n\t\t{\n\t\t\tif (memcmp(extradata, right.extradata, extrasize) != 0) return false;\n\t\t}\n\t}\n\n\t// VIDEO\n\tif (fpsscale != right.fpsscale\n\t\t|| fpsrate != right.fpsrate\n\t\t|| height != right.height\n\t\t|| width != right.width\n\t\t|| stills != right.stills\n\t\t|| level != right.level\n\t\t|| profile != right.profile\n\t\t|| ptsinvalid != right.ptsinvalid\n\t\t|| forced_aspect != right.forced_aspect\n\t\t|| bitsperpixel != right.bitsperpixel\n\t\t|| vfr != right.vfr\n\t//\t|| stereo_mode != right.stereo_mode\n\t\t) return false;\n\n\t// AUDIO\n\tif (channels != right.channels\n\t\t|| samplerate != right.samplerate\n\t\t|| blockalign != right.blockalign\n\t\t|| bitrate != right.bitrate\n\t\t|| bitspersample != right.bitspersample\n\t\t|| channellayout != right.channellayout)\n\t\treturn false;\n\n\t// SUBTITLE\n\n\treturn true;\n}\n\nbool CDVDStreamInfo::Equal(const CDemuxStream& right, bool withextradata)\n{\n\tCDVDStreamInfo info;\n\tinfo.Assign(right, withextradata);\n\treturn Equal(info, withextradata);\n}\n\n\n// ASSIGNMENT\nvoid CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata)\n{\n\tcodec = right.codec;\n//\ttype = right.type;\n\tuniqueId = right.uniqueId;\n\trealtime = right.realtime;\n\tcodec_tag = right.codec_tag;\n\tflags = right.flags;\n\tfilename = right.filename;\n//\tdvd = right.dvd;\n\n\tif (extradata && extrasize) free(extradata);\n\n\tif (withextradata && right.extrasize)\n\t{\n\t\textrasize = right.extrasize;\n\t\textradata = malloc(extrasize);\n\t\tif (!extradata)\n\t\t\treturn;\n\t\tmemcpy(extradata, right.extradata, extrasize);\n\t} else\n\t{\n\t\textrasize = 0;\n\t\textradata = 0;\n\t}\n\n\t// VIDEO\n\tfpsscale = right.fpsscale;\n\tfpsrate = right.fpsrate;\n\theight = right.height;\n\twidth = right.width;\n\taspect = right.aspect;\n\tstills = right.stills;\n\tlevel = right.level;\n\tprofile = right.profile;\n\tptsinvalid = right.ptsinvalid;\n\tforced_aspect = right.forced_aspect;\n\torientation = right.orientation;\n\tbitsperpixel = right.bitsperpixel;\n\tvfr = right.vfr;\n\tsoftware = right.software;\n//\tstereo_mode = right.stereo_mode;\n\n\t// AUDIO\n\tchannels = right.channels;\n\tsamplerate = right.samplerate;\n\tblockalign = right.blockalign;\n\tbitrate = right.bitrate;\n\tbitspersample = right.bitspersample;\n\tchannellayout = right.channellayout;\n\n\t// SUBTITLE\n}\n\nvoid CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata)\n{\n\tClear();\n\n\tcodec = right.codec;\n//\ttype = right.type;\n\tuniqueId = right.uniqueId;\n\trealtime = right.realtime;\n\tcodec_tag = right.codec_fourcc;\n\tprofile = right.profile;\n\tlevel = right.level;\n\tflags = right.flags;\n\n\tif (withextradata && right.ExtraSize)\n\t{\n\t\textrasize = right.ExtraSize;\n\t\textradata = malloc(extrasize);\n\t\tif (!extradata)\n\t\t\treturn;\n\t\tmemcpy(extradata, right.ExtraData, extrasize);\n\t}\n\n\tif (right.type == STREAM_AUDIO)\n\t{\n\t\tconst CDemuxStreamAudio *stream = static_cast<const CDemuxStreamAudio*>(&right);\n\t\tchannels = stream->iChannels;\n\t\tsamplerate = stream->iSampleRate;\n\t\tblockalign = stream->iBlockAlign;\n\t\tbitrate = stream->iBitRate;\n\t\tbitspersample = stream->iBitsPerSample;\n\t\tchannellayout = stream->iChannelLayout;\n\t} else if (right.type == STREAM_VIDEO)\n\t{\n\t\tconst CDemuxStreamVideo *stream = static_cast<const CDemuxStreamVideo*>(&right);\n\t\tfpsscale = stream->iFpsScale;\n\t\tfpsrate = stream->iFpsRate;\n\t\theight = stream->iHeight;\n\t\twidth = stream->iWidth;\n\t\taspect = stream->fAspect;\n\t\tvfr = stream->bVFR;\n\t\tptsinvalid = stream->bPTSInvalid;\n\t\tforced_aspect = stream->bForcedAspect;\n\t\torientation = stream->iOrientation;\n\t\tbitsperpixel = stream->iBitsPerPixel;\n//\t\tstereo_mode = stream->stereo_mode;\n// \t} else if (right.type == STREAM_SUBTITLE)\n// \t{\n\t}\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/StreamInfo.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"Demux.h\"\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n\nNS_KRMOVIE_BEGIN\nstruct CDVDStreamInfo {\n\tCDVDStreamInfo();\n\tCDVDStreamInfo(const CDVDStreamInfo &right, bool withextradata = true);\n\tCDVDStreamInfo(const CDemuxStream &right, bool withextradata = true);\n\n\t~CDVDStreamInfo();\n\n\tvoid Clear(); // clears current information\n\tbool Equal(const CDVDStreamInfo &right, bool withextradata);\n\tbool Equal(const CDemuxStream &right, bool withextradata);\n\n\tvoid Assign(const CDVDStreamInfo &right, bool withextradata);\n\tvoid Assign(const CDemuxStream &right, bool withextradata);\n\n\tAVCodecID codec;\n\t//StreamType type;\n\tint uniqueId;\n\tbool realtime;\n\tint flags;\n\tbool software;  //force software decoding\n\tstd::string filename;\n\t//bool dvd;\n\n\t// VIDEO\n\tint fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps\n\tint fpsrate;\n\tint height; // height of the stream reported by the demuxer\n\tint width; // width of the stream reported by the demuxer\n\tfloat aspect; // display aspect as reported by demuxer\n\tbool vfr; // variable framerate\n\tbool stills; // there may be odd still frames in video\n\tint level; // encoder level of the stream reported by the decoder. used to qualify hw decoders.\n\tint profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders.\n\tbool ptsinvalid;  // pts cannot be trusted (avi's).\n\tbool forced_aspect; // aspect is forced from container\n\tint orientation; // orientation of the video in degress counter clockwise\n\tint bitsperpixel;\n//\tstd::string stereo_mode; // stereoscopic 3d mode\n\n\t// AUDIO\n\tint channels;\n\tint samplerate;\n\tint bitrate;\n\tint blockalign;\n\tint bitspersample;\n\tuint64_t channellayout;\n\n\t// CODEC EXTRADATA\n\tvoid*        extradata; // extra data for codec to use\n\tunsigned int extrasize; // size of extra data\n\tunsigned int codec_tag; // extra identifier hints for decoding\n\n\tbool operator==(const CDVDStreamInfo& right)      { return Equal(right, true); }\n\tbool operator!=(const CDVDStreamInfo& right)      { return !Equal(right, true); }\n\n\tCDVDStreamInfo& operator=(const CDVDStreamInfo& right)\n\t{\n\t\tif (this != &right)\n\t\t\tAssign(right, true);\n\n\t\treturn *this;\n\t}\n\n\tbool operator==(const CDemuxStream& right)      { return Equal(CDVDStreamInfo(right, true), true); }\n\tbool operator!=(const CDemuxStream& right)      { return !Equal(CDVDStreamInfo(right, true), true); }\n\n\tCDVDStreamInfo& operator=(const CDemuxStream& right)\n\t{\n\t\tAssign(right, true);\n\t\treturn *this;\n\t}\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/TVPMediaDemux.cpp",
    "content": ""
  },
  {
    "path": "src/core/movie/ffmpeg/TVPMediaDemux.h",
    "content": ""
  },
  {
    "path": "src/core/movie/ffmpeg/Thread.cpp",
    "content": "#include \"Thread.h\"\n#include <thread>\n#include <stdexcept>\n#include \"MsgIntf.h\"\n#include \"ThreadImpl.h\"\n\nNS_KRMOVIE_BEGIN\n\nCThread::CThread()\n\t: m_bStop(false), m_bRunning(false)\n{\n\n}\n\nCThread::~CThread()\n{\n\tif (m_bRunning) {\n\t\tStopThread();\n\t}\n\tif (m_ThreadId) {\n\t\tm_ThreadId->join(); delete m_ThreadId;\n\t}\n}\n\nvoid CThread::Create()\n{\n\tif (m_bRunning.exchange(true)) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"thread already in running\"));\n\t}\n\tm_bStop = false;\n\tif (m_ThreadId) {\n\t\tm_ThreadId->join(); delete m_ThreadId;\n\t}\n\tm_ThreadId = new std::thread(&CThread::entry, this);\n}\n\nvoid CThread::StopThread(bool bWait /*= true*/)\n{\n\tm_bStop = true;\n\tm_StopEvent.notify_all();\n\tif (m_ThreadId && bWait) {\n\t\tm_ThreadId->join();\n\t\tdelete m_ThreadId;\n\t\tm_ThreadId = nullptr;\n\t}\n}\n\nvoid CThread::Sleep(unsigned int milliseconds)\n{\n\tif (IsCurrentThread()) {\n\t\tstd::unique_lock<std::mutex> lock(m_mtxStopEvent);\n\t\tm_StopEvent.wait_for(lock, std::chrono::milliseconds(milliseconds));\n\t} else {\n\t\tstd::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));\n\t}\n}\n\nbool CThread::IsCurrentThread()\n{\n\tif (!m_ThreadId) return false;\n\treturn m_ThreadId->get_id() == std::this_thread::get_id();\n}\n\nint CThread::entry()\n{\n\tOnStartup();\n\tProcess();\n\tOnExit();\n\tm_bRunning = false;\n\tTVPOnThreadExited();\n\treturn 0;\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/Thread.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include <atomic>\n#include <condition_variable>\n#include <thread>\n#include <mutex>\n\nNS_KRMOVIE_BEGIN\ntypedef std::recursive_mutex CCriticalSection;\ntypedef std::unique_lock<std::recursive_mutex> CSingleLock;\nclass CThread {\npublic:\n\tCThread();\n\tvirtual ~CThread();\n\tvoid Create();\n\tbool IsRunning() const { return m_bRunning; }\n\tvoid StopThread(bool bWait = true);\n\tvoid Sleep(unsigned int milliseconds);\n\tbool IsCurrentThread();\n\nprotected:\n\tint entry();\n\tvirtual void OnStartup() {}\n\tvirtual void Process() = 0;\n\tvirtual void OnExit() {}\n\n\tstd::thread *m_ThreadId = nullptr;\n\tstd::atomic<bool> m_bStop, m_bRunning;\n\tstd::mutex m_mtxStopEvent;\n\tstd::condition_variable m_StopEvent;\n\tCCriticalSection m_CriticalSection;\n};\n\nclass CEvent {\npublic:\n\tvoid Set() { m_cond.notify_all(); }\n\tvoid Reset() {}\n\tbool WaitMSec(unsigned int milliSeconds) {\n\t\tCSingleLock lock(mutex);\n\t\treturn m_cond.wait_for(lock, std::chrono::milliseconds(milliSeconds)) != std::cv_status::timeout;\n\t}\n\tvoid Wait() {\n\t\tCSingleLock lock(mutex);\n\t\tm_cond.wait(lock);\n\t}\n\nprotected:\n\tCCriticalSection mutex;\n\tstd::condition_variable_any m_cond;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/TimeUtils.cpp",
    "content": "#include \"TimeUtils.h\"\n\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n  #include \"config.h\"\n#endif\n\n#ifdef _MSC_VER\n#include <windows.h>\n#endif\n#include <time.h>\n#include \"tp_stub.h\"\n#include \"TickCount.h\"\n\nNS_KRMOVIE_BEGIN\nint64_t CurrentHostCounter(void)\n{\n\treturn TVPGetRoughTickCount32();\n#ifdef _MSC_VER\n\tLARGE_INTEGER PerformanceCount;\n\tQueryPerformanceCounter(&PerformanceCount);\n\treturn((int64_t)PerformanceCount.QuadPart);\n#elif defined(CLOCK_MONOTONIC_RAW)\n\tstruct timespec now;\n\tclock_gettime(CLOCK_MONOTONIC_RAW, &now);\n\treturn(((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec);\n#elif defined(CLOCK_MONOTONIC)\n\tstruct timespec now;\n\tclock_gettime(CLOCK_MONOTONIC, &now);\n\treturn(((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec);\n#else // xcode ?\n\treturn((int64_t)CVGetCurrentHostTime());\n#endif\n}\n\nint64_t CurrentHostFrequency(void)\n{\n\treturn 1000;\n#ifdef _MSC_VER\n\tLARGE_INTEGER Frequency;\n\tQueryPerformanceFrequency(&Frequency);\n\treturn((int64_t)Frequency.QuadPart);\n#elif defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)\n\treturn (int64_t)1000000000L;\n#else\n\treturn((int64_t)CVGetHostClockFrequency());\n#endif\n}\n\nunsigned int CTimeUtils::frameTime = 0;\n\nvoid CTimeUtils::UpdateFrameTime(bool flip)\n{\n\tunsigned int currentTime = TVPGetRoughTickCount32();\n  unsigned int last = frameTime;\n  while (frameTime < currentTime)\n  {\n\t  frameTime += (unsigned int)(1000 / 60/*g_graphicsContext.GetFPS()*/);\n    // observe wrap around\n    if (frameTime < last)\n      break;\n  }\n}\n\nunsigned int CTimeUtils::GetFrameTime()\n{\n  return frameTime;\n}\n#if 0\nCDateTime CTimeUtils::GetLocalTime(time_t time)\n{\n  CDateTime result;\n\n  tm *local;\n#ifdef HAVE_LOCALTIME_R\n  tm res = {};\n  local = localtime_r(&time, &res); // Conversion to local time\n#else\n  local = localtime(&time); // Conversion to local time\n#endif\n  /*\n   * Microsoft implementation of localtime returns NULL if on or before epoch.\n   * http://msdn.microsoft.com/en-us/library/bf12f0hc(VS.80).aspx\n   */\n  if (local)\n    result = *local;\n  else\n    result = time; // Use the original time as close enough.\n\n  return result;\n}\n#endif\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/TimeUtils.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include <stdint.h>\n#include <time.h>\nNS_KRMOVIE_BEGIN\nclass CDateTime;\n\nint64_t CurrentHostCounter(void);\nint64_t CurrentHostFrequency(void);\n\nclass CTimeUtils\n{\npublic:\n  static void UpdateFrameTime(bool flip); ///< update the frame time.  Not threadsafe\n  static unsigned int GetFrameTime(); ///< returns the frame time in MS.  Not threadsafe\n//  static CDateTime GetLocalTime(time_t time);\n\nprivate:\n  static unsigned int frameTime;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/Timer.cpp",
    "content": "#include <time.h>\n#include \"Timer.h\"\n#include <limits>\n\nNS_KRMOVIE_BEGIN\nconst unsigned int Timer::InfiniteValue = std::numeric_limits<unsigned int>::max();\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/Timer.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"TickCount.h\"\n\nNS_KRMOVIE_BEGIN\nclass Timer {\n\tunsigned int startTime;\n\tunsigned int totalWaitTime;\npublic:\n\tstatic const unsigned int InfiniteValue;\n\tinline Timer() : startTime(0), totalWaitTime(0) {}\n\tinline Timer(unsigned int millisecondsIntoTheFuture) : startTime(TVPGetRoughTickCount32()), totalWaitTime(millisecondsIntoTheFuture) {}\n\n\tinline void Set(unsigned int millisecondsIntoTheFuture) { startTime = TVPGetRoughTickCount32(); totalWaitTime = millisecondsIntoTheFuture; }\n\tinline bool IsTimePast() const { return totalWaitTime == InfiniteValue ? false : (totalWaitTime == 0 ? true : (TVPGetRoughTickCount32() - startTime) >= totalWaitTime); }\n\n\tinline unsigned int MillisLeft() const\n\t{\n\t\tif (totalWaitTime == InfiniteValue)\n\t\t\treturn InfiniteValue;\n\t\tif (totalWaitTime == 0)\n\t\t\treturn 0;\n\t\tunsigned int timeWaitedAlready = (TVPGetRoughTickCount32() - startTime);\n\t\treturn (timeWaitedAlready >= totalWaitTime) ? 0 : (totalWaitTime - timeWaitedAlready);\n\t}\n\t\n\tinline void SetExpired() { totalWaitTime = 0; }\n\tinline void SetInfinite() { totalWaitTime = InfiniteValue; }\n\tinline bool IsInfinite(void) const { return (totalWaitTime == InfiniteValue); }\n\tinline unsigned int GetInitialTimeoutValue(void) const { return totalWaitTime; }\n\tinline unsigned int GetStartTime(void) const { return startTime; }\n};\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoCodec.cpp",
    "content": "#include \"VideoCodec.h\"\nNS_KRMOVIE_BEGIN\nbool CDVDVideoCodec::IsSettingVisible(const std::string &condition, const std::string &value, const CSetting *setting, void *data)\n{\n  if (setting == NULL || value.empty())\n    return false;\n#if 0\n  const std::string &settingId = setting->GetId();\n\n  // check if we are running on nvidia hardware\n  std::string gpuvendor = g_Windowing.GetRenderVendor();\n  std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower);\n  bool isNvidia = (gpuvendor.compare(0, 6, \"nvidia\") == 0);\n  bool isIntel = (gpuvendor.compare(0, 5, \"intel\") == 0);\n\n  // nvidia does only need mpeg-4 setting\n  if (isNvidia)\n  {\n    if (settingId == CSettings::SETTING_VIDEOPLAYER_USEVDPAUMPEG4)\n      return true;\n\n    return false; // will also hide intel settings on nvidia hardware\n  }\n  else if (isIntel) // intel needs vc1, mpeg-2 and mpeg4 setting\n  {\n    if (settingId == CSettings::SETTING_VIDEOPLAYER_USEVAAPIMPEG4)\n      return true;\n    if (settingId == CSettings::SETTING_VIDEOPLAYER_USEVAAPIVC1)\n      return true;\n    if (settingId == CSettings::SETTING_VIDEOPLAYER_USEVAAPIMPEG2)\n      return true;\n\n    return false; // this will also hide nvidia settings on intel hardware\n  }\n#endif\n  // if we don't know the hardware we are running on e.g. amd oss vdpau \n  // or fglrx with xvba-driver we show everything\n  return true;\n}\n\nbool CDVDVideoCodec::IsCodecDisabled(const std::map<AVCodecID, std::string> &map, AVCodecID id)\n{\n  auto codec = map.find(id);\n  if (codec != map.end())\n  {\n\t  return false;\n//     return (!CSettings::GetInstance().GetBool(codec->second) ||\n//             !CDVDVideoCodec::IsSettingVisible(\"unused\", \"unused\",\n//                                               CSettings::GetInstance().GetSetting(codec->second),\n//                                               NULL));\n  }\n  return false; // don't disable what we don't have\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoCodec.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"ProcessInfo.h\"\n#include \"RenderFormats.h\"\n\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n}\n\n#include <vector>\n#include <string>\n#include <map>\n\nNS_KRMOVIE_BEGIN\nclass CSetting;\n\n// when modifying these structures, make sure you update all codecs accordingly\n#define FRAME_TYPE_UNDEF 0\n#define FRAME_TYPE_I     1\n#define FRAME_TYPE_P     2\n#define FRAME_TYPE_B     3\n#define FRAME_TYPE_D     4\n\nnamespace DXVA { class CRenderPicture; }\nnamespace VAAPI { class CVaapiRenderPicture; }\nnamespace VDPAU { class CVdpauRenderPicture; }\nclass COpenMax;\nclass COpenMaxVideo;\nstruct OpenMaxVideoBufferHolder;\nclass CDVDMediaCodecInfo;\nclass CDVDVideoCodecIMXBuffer;\nclass CMMALBuffer;\nclass CDVDAmlogicInfo;\n\n// should be entirely filled by all codecs\nstruct DVDVideoPicture\n{\n  double pts; // timestamp in seconds, used in the CVideoPlayer class to keep track of pts\n  double dts;\n\n  union\n  {\n    struct {\n      uint8_t* data[4];   // [4] = alpha channel, currently not used\n      int iLineSize[4];   // [4] = alpha channel, currently not used\n    };\n    struct {\n      DXVA::CRenderPicture* dxva;\n    };\n    struct {\n      VDPAU::CVdpauRenderPicture* vdpau;\n    };\n    struct {\n      VAAPI::CVaapiRenderPicture* vaapi;\n    };\n\n    struct {\n      COpenMax *openMax;\n      OpenMaxVideoBufferHolder *openMaxBufferHolder;\n    };\n\n    struct {\n      struct __CVBuffer *cvBufferRef;\n    };\n\n    struct {\n      CDVDMediaCodecInfo *mediacodec;\n    };\n\n    struct {\n      CDVDVideoCodecIMXBuffer *IMXBuffer;\n    };\n\n    struct {\n      CMMALBuffer *MMALBuffer;\n    };\n\n    struct {\n      CDVDAmlogicInfo *amlcodec;\n    };\n\n  };\n\n  unsigned int iFlags;\n\n  double       iRepeatPicture;\n  double       iDuration;\n  unsigned int iFrameType         : 4;  //< see defines above // 1->I, 2->P, 3->B, 0->Undef\n  unsigned int color_matrix       : 4;\n  unsigned int color_range        : 1;  //< 1 indicate if we have a full range of color\n  unsigned int chroma_position;\n  unsigned int color_primaries;\n  unsigned int color_transfer;\n  unsigned int extended_format;\n//  char         stereo_mode[32];\n\n  int8_t*      qp_table;                //< Quantization parameters, primarily used by filters\n  int          qstride;\n  int          qscale_type;\n\n  unsigned int iWidth;\n  unsigned int iHeight;\n  unsigned int iDisplayWidth;           //< width of the picture without black bars\n  unsigned int iDisplayHeight;          //< height of the picture without black bars\n\n  ERenderFormat format;\n};\n\nstruct DVDVideoUserData\n{\n  uint8_t* data;\n  int size;\n};\n\n#define DVP_FLAG_TOP_FIELD_FIRST    0x00000001\n#define DVP_FLAG_REPEAT_TOP_FIELD   0x00000002  //< Set to indicate that the top field should be repeated\n#define DVP_FLAG_ALLOCATED          0x00000004  //< Set to indicate that this has allocated data\n#define DVP_FLAG_INTERLACED         0x00000008  //< Set to indicate that this frame is interlaced\n\n#define DVP_FLAG_DROPPED            0x00000010  //< indicate that this picture has been dropped in decoder stage, will have no data\n\n#define DVD_CODEC_CTRL_SKIPDEINT    0x01000000  //< indicate that this picture was requested to have been dropped in deint stage\n#define DVD_CODEC_CTRL_NO_POSTPROC  0x02000000  //< see GetCodecStats\n#define DVD_CODEC_CTRL_HURRY        0x04000000  //< see GetCodecStats\n#define DVD_CODEC_CTRL_DROP         0x08000000  //< this frame is going to be dropped in output\n#define DVD_CODEC_CTRL_DRAIN        0x10000000  //< squeeze out pictured without feeding new packets\n#define DVD_CODEC_CTRL_ROTATE       0x20000000  //< rotate if renderer does not support it\n\n// DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2!\n\n#define DVP_QSCALE_UNKNOWN          0\n#define DVP_QSCALE_MPEG1            1\n#define DVP_QSCALE_MPEG2            2\n#define DVP_QSCALE_H264             3\n\nstruct CDVDStreamInfo;\nclass CDVDCodecOption;\nclass CDVDCodecOptions;\n\n// VC_ messages, messages can be combined\n#define VC_ERROR                    0x00000001  //< an error occured, no other messages will be returned\n#define VC_BUFFER                   0x00000002  //< the decoder needs more data\n#define VC_PICTURE                  0x00000004  //< the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data\n#define VC_USERDATA                 0x00000008  //< the decoder found some userdata,  call Decode(NULL, 0) again to parse the rest of the data\n#define VC_FLUSHED                  0x00000010  //< the decoder lost it's state, we need to restart decoding again\n#define VC_DROPPED                  0x00000020  //< needed to identify if a picture was dropped\n#define VC_NOBUFFER                 0x00000040  //< last FFmpeg GetBuffer failed\n#define VC_REOPEN                   0x00000080  //< decoder request to re-open\n\nclass CDVDVideoCodec\n{\npublic:\n  CDVDVideoCodec(CProcessInfo &processInfo) : m_processInfo(processInfo) {}\n  virtual ~CDVDVideoCodec() {}\n\n  /**\n   * Open the decoder, returns true on success\n   */\n  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) = 0;\n\n  /**\n   * returns one or a combination of VC_ messages\n   * pData and iSize can be NULL, this means we should flush the rest of the data.\n   */\n  virtual int Decode(uint8_t* pData, int iSize, double dts, double pts) = 0;\n\n  /**\n   * Reset the decoder.\n   * Should be the same as calling Dispose and Open after each other\n   */\n  virtual void Reset() = 0;\n\n  /**\n   * returns true if successfull\n   * the data is valid until the next Decode call\n   */\n  virtual bool GetPicture(DVDVideoPicture* pDvdVideoPicture) = 0;\n\n  /**\n   * returns true if successfull\n   * the data is cleared to zero\n   */\n  virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture)\n  {\n    memset(pDvdVideoPicture, 0, sizeof(DVDVideoPicture));\n    return true;\n  }\n\n  /**\n   * returns true if successfull\n   * the data is valid until the next Decode call\n   * userdata can be anything, for now we use it for closed captioning\n   */\n  virtual bool GetUserData(DVDVideoUserData* pDvdVideoUserData)\n  {\n    pDvdVideoUserData->data = NULL;\n    pDvdVideoUserData->size = 0;\n    return false;\n  }\n\n  /**\n   * will be called by video player indicating if a frame will eventually be dropped\n   * codec can then skip actually decoding the data, just consume the data set picture headers\n   */\n  virtual void SetDropState(bool bDrop) = 0;\n\n  /**\n   * will be called by video player indicating the playback speed. see DVD_PLAYSPEED_NORMAL,\n   * DVD_PLAYSPEED_PAUSE and friends.\n   */\n  virtual void SetSpeed(int iSpeed) {};\n\n  /**\n   * should return codecs name\n   */\n  virtual const char* GetName() = 0;\n\n  /**\n   * How many packets should player remember, so codec can recover should\n   * something cause it to flush outside of players control\n   */\n  virtual unsigned GetConvergeCount()\n  {\n    return 0;\n  }\n\n  /**\n   * Number of references to old pictures that are allowed to be retained when\n   * calling decode on the next demux packet\n   */\n  virtual unsigned GetAllowedReferences() { return 0; }\n\n  /**\n   * Hide or Show Settings depending on the currently running hardware\n   */\n  static bool IsSettingVisible(const std::string &condition, const std::string &value, const CSetting *setting, void *data);\n\n  /**\n   * Interact with user settings so that user disabled codecs are disabled\n   */\n  static bool IsCodecDisabled(const std::map<AVCodecID, std::string> &map, AVCodecID id);\n\n  /**\n   * For calculation of dropping requirements player asks for some information.\n   * - pts : right after decoder, used to detect gaps (dropped frames in decoder)\n   * - droppedFrames : indicates if decoder has dropped a frame\n   *                 -1 means that decoder has no info on this.\n   * - skippedPics : indicates if postproc has skipped a already decoded picture\n   *                 -1 means that decoder has no info on this.\n   *\n   * If codec does not implement this method, pts of decoded frame at input\n   * video player is used. In case decoder does post-proc and de-interlacing there\n   * may be quite some frames queued up between exit decoder and entry player.\n   */\n  virtual bool GetCodecStats(double &pts, int &droppedFrames, int &skippedPics)\n  {\n    droppedFrames = -1;\n    skippedPics = -1;\n    return false;\n  }\n\n  /**\n   * Codec can be informed by player with the following flags:\n   *\n   * DVD_CODEC_CTRL_NO_POSTPROC :\n   *                  if speed is not normal the codec can switch off\n   *                  postprocessing and de-interlacing\n   *\n   * DVD_CODEC_CTRL_HURRY :\n   *                  codecs may do postprocessing and de-interlacing.\n   *                  If video buffers in RenderManager are about to run dry,\n   *                  this is signaled to codec. Codec can wait for post-proc\n   *                  to be finished instead of returning empty and getting another\n   *                  packet.\n   *\n   * DVD_CODEC_CTRL_DRAIN :\n   *                  instruct decoder to deliver last pictures without requesting\n   *                  new packets\n   *\n   * DVD_CODEC_CTRL_DROP :\n   *                  this packet is going to be dropped. decoder is free to use it\n   *                  for decoding\n   *\n   */\n  virtual void SetCodecControl(int flags) {}\n\n  /**\n   * Re-open the decoder.\n   * Decoder request to re-open\n   */\n  virtual void Reopen() {};\n\nprotected:\n  CProcessInfo &m_processInfo;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoCodecFFmpeg.cpp",
    "content": "#include \"VideoCodecFFmpeg.h\"\n#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)\n#include \"config.h\"\n#endif\n\n#ifndef TARGET_POSIX\n#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))\n#else\n#include <math.h>\n#define RINT lrint\n#endif\n\n#include \"RenderFormats.h\"\n\n#ifdef HAVE_LIBVDPAU\n#include \"VDPAU.h\"\n#endif\n#ifdef HAS_DX\n#include \"DXVA.h\"\n#endif\n#ifdef HAVE_LIBVA\n#include \"VAAPI.h\"\n#endif\n#ifdef TARGET_DARWIN\n#include \"VTB.h\"\n#endif\n#ifdef HAS_MMAL\n#include \"MMALFFmpeg.h\"\n#endif\n\nextern \"C\" {\n#include \"libavutil/opt.h\"\n#include \"libavfilter/avfilter.h\"\n#include \"libavfilter/buffersink.h\"\n#include \"libavfilter/buffersrc.h\"\n#include \"libavutil/pixdesc.h\"\n}\n#include \"Clock.h\"\n#include \"CodecUtils.h\"\n#include \"tp_stub.h\"\n#include <cstdlib>\n#include <algorithm>\n\nNS_KRMOVIE_BEGIN\nenum DecoderState\n{\n  STATE_NONE,\n  STATE_SW_SINGLE,\n  STATE_HW_SINGLE,\n  STATE_HW_FAILED,\n  STATE_SW_MULTI\n};\n\nenum EFilterFlags {\n  FILTER_NONE                =  0x0,\n  FILTER_DEINTERLACE_YADIF   =  0x1,  //< use first deinterlace mode\n  FILTER_DEINTERLACE_ANY     =  0xf,  //< use any deinterlace mode\n  FILTER_DEINTERLACE_FLAGGED = 0x10,  //< only deinterlace flagged frames\n  FILTER_DEINTERLACE_HALFED  = 0x20,  //< do half rate deinterlacing\n  FILTER_ROTATE              = 0x40,  //< rotate image according to the codec hints\n};\n\nCDVDVideoCodecFFmpeg::CDropControl::CDropControl()\n{\n  Reset(true);\n}\n\nvoid CDVDVideoCodecFFmpeg::CDropControl::Reset(bool init)\n{\n  m_lastPTS = AV_NOPTS_VALUE;\n\n  if (init || m_state != VALID)\n  {\n    m_count = 0;\n    m_diffPTS = 0;\n    m_state = INIT;\n  }\n}\n\nvoid CDVDVideoCodecFFmpeg::CDropControl::Process(int64_t pts, bool drop)\n{\n  if (m_state == INIT)\n  {\n    if (pts != AV_NOPTS_VALUE && m_lastPTS != AV_NOPTS_VALUE)\n    {\n      m_diffPTS += pts - m_lastPTS;\n      m_count++;\n    }\n    if (m_count > 10)\n    {\n      m_diffPTS = m_diffPTS / m_count;\n      if (m_diffPTS > 0)\n      {\n//        CLog::Log(LOGNOTICE, \"CDVDVideoCodecFFmpeg::CDropControl: calculated diff time: %lld\", m_diffPTS);\n        m_state = CDropControl::VALID;\n        m_count = 0;\n      }\n    }\n  }\n  else if (m_state == VALID && !drop)\n  {\n    if (std::abs(pts - m_lastPTS - m_diffPTS) > m_diffPTS * 0.2)\n    {\n      m_count++;\n      if (m_count > 5)\n      {\n //       CLog::Log(LOGNOTICE, \"CDVDVideoCodecFFmpeg::CDropControl: lost diff\");\n        Reset(true);\n      }\n    }\n    else\n      m_count = 0;\n  }\n  m_lastPTS = pts;\n}\n\nenum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat(struct AVCodecContext * avctx, const AVPixelFormat * fmt)\n{\n  CDVDVideoCodecFFmpeg* ctx  = (CDVDVideoCodecFFmpeg*)avctx->opaque;\n\n  const char* pixFmtName = av_get_pix_fmt_name(*fmt);\n\n  ctx->m_processInfo.SetVideoDimensions(avctx->coded_width, avctx->coded_height);\n\n  // if frame threading is enabled hw accel is not allowed\n  // 2nd condition:\n  // fix an ffmpeg issue here, it calls us with an invalid profile\n  // then a 2nd call with a valid one\n  if(ctx->m_decoderState != STATE_HW_SINGLE ||\n     (avctx->codec_id == AV_CODEC_ID_VC1 && avctx->profile == FF_PROFILE_UNKNOWN))\n  {\n    AVPixelFormat defaultFmt = avcodec_default_get_format(avctx, fmt);\n    pixFmtName = av_get_pix_fmt_name(defaultFmt);\n    ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n//    ctx->m_processInfo.SetSwDeinterlacingMethods();\n    return defaultFmt;\n  }\n\n  // hardware decoder de-selected, restore standard ffmpeg\n  if (ctx->GetHardware())\n  {\n    ctx->SetHardware(NULL);\n    avctx->get_buffer2 = avcodec_default_get_buffer2;\n    avctx->slice_flags = 0;\n    avctx->hwaccel_context = 0;\n  }\n\n  const AVPixelFormat * cur = fmt;\n  while(*cur != AV_PIX_FMT_NONE)\n  {\n    pixFmtName = av_get_pix_fmt_name(*cur);\n\n#ifdef HAVE_LIBVDPAU\n    if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU))\n    {\n      CLog::Log(LOGNOTICE,\"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)\", avctx->width, avctx->height);\n      VDPAU::CDecoder* vdp = new VDPAU::CDecoder(ctx->m_processInfo);\n      if(vdp->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))\n      {\n        ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n        ctx->SetHardware(vdp);\n        return *cur;\n      }\n      else\n        vdp->Release();\n    }\n#endif\n#ifdef HAS_DX\n  if(DXVA::CDecoder::Supports(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2))\n  {\n    CLog::Log(LOGNOTICE, \"CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)\", avctx->width, avctx->height);\n    DXVA::CDecoder* dec = new DXVA::CDecoder(ctx->m_processInfo);\n    if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))\n    {\n      ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n      ctx->SetHardware(dec);\n      return *cur;\n    }\n    else\n      dec->Release();\n  }\n#endif\n#ifdef HAVE_LIBVA\n    // mpeg4 vaapi decoding is disabled\n    if(*cur == AV_PIX_FMT_VAAPI_VLD && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI))\n    {\n      VAAPI::CDecoder* dec = new VAAPI::CDecoder(ctx->m_processInfo);\n      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount) == true)\n      {\n        ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n        ctx->SetHardware(dec);\n        return *cur;\n      }\n      else\n        dec->Release();\n    }\n#endif\n\n#ifdef TARGET_DARWIN\n    if (*cur == AV_PIX_FMT_VIDEOTOOLBOX && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVTB))\n    {\n      VTB::CDecoder* dec = new VTB::CDecoder(ctx->m_processInfo);\n      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))\n      {\n        ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n        ctx->SetHardware(dec);\n        return *cur;\n      }\n      else\n        dec->Release();\n    }\n#endif\n\n#ifdef HAS_MMAL\n    if (*cur == AV_PIX_FMT_YUV420P)\n    {\n      MMAL::CDecoder* dec = new MMAL::CDecoder(ctx->m_processInfo);\n      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))\n      {\n        ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n        ctx->SetHardware(dec);\n        return *cur;\n      }\n      else\n        dec->Release();\n    }\n#endif\n    cur++;\n  }\n\n  ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : \"\");\n//  ctx->m_processInfo.SetSwDeinterlacingMethods();\n  ctx->m_decoderState = STATE_HW_FAILED;\n  return avcodec_default_get_format(avctx, fmt);\n}\n\nCDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg(CProcessInfo &processInfo) : CDVDVideoCodec(processInfo)\n{\n  m_pCodecContext = nullptr;\n  m_pFrame = nullptr;\n  m_pDecodedFrame = nullptr;\n  m_pFilterGraph = nullptr;\n  m_pFilterIn = nullptr;\n  m_pFilterOut = nullptr;\n  m_pFilterFrame = nullptr;\n\n  m_iPictureWidth = 0;\n  m_iPictureHeight = 0;\n\n  m_uSurfacesCount = 0;\n\n  m_iScreenWidth = 0;\n  m_iScreenHeight = 0;\n  m_iOrientation = 0;\n  m_decoderState = STATE_NONE;\n  m_pHardware = nullptr;\n  m_iLastKeyframe = 0;\n  m_dts = DVD_NOPTS_VALUE;\n  m_started = false;\n  m_decoderPts = DVD_NOPTS_VALUE;\n  m_codecControlFlags = 0;\n  m_requestSkipDeint = false;\n  m_skippedDeint = 0;\n  m_droppedFrames = 0;\n  m_interlaced = false;\n  m_DAR = 1.0;\n}\n\nCDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()\n{\n  Dispose();\n}\n\nbool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)\n{\n  m_hints = hints;\n  m_options = options;\n\n  AVCodec* pCodec;\n\n  m_iOrientation = hints.orientation;\n\n  m_formats.clear();\n  for(std::vector<ERenderFormat>::iterator it = options.m_formats.begin(); it != options.m_formats.end(); ++it)\n  {\n    AVPixelFormat pixFormat = CDVDCodecUtils::PixfmtFromEFormat(*it);\n    if (pixFormat != AV_PIX_FMT_NONE)\n      m_formats.push_back(pixFormat);\n\n    if(*it == RENDER_FMT_YUV420P)\n      m_formats.push_back(AV_PIX_FMT_YUVJ420P);\n  }\n  m_formats.push_back(AV_PIX_FMT_NONE); /* always add none to get a terminated list in ffmpeg world */\n\n  pCodec = avcodec_find_decoder(hints.codec);\n\n  if(pCodec == NULL)\n  {\n//    CLog::Log(LOGDEBUG,\"CDVDVideoCodecFFmpeg::Open() Unable to find codec %d\", hints.codec);\n    return false;\n  }\n\n//  CLog::Log(LOGNOTICE,\"CDVDVideoCodecFFmpeg::Open() Using codec: %s\",pCodec->long_name ? pCodec->long_name : pCodec->name);\n\n  m_pCodecContext = avcodec_alloc_context3(pCodec);\n  if (!m_pCodecContext)\n    return false;\n\n  m_pCodecContext->opaque = (void*)this;\n  m_pCodecContext->debug_mv = 0;\n  m_pCodecContext->debug = 0;\n  m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT;\n  m_pCodecContext->get_format = GetFormat;\n  m_pCodecContext->codec_tag = hints.codec_tag;\n\n  // setup threading model\n  if (!hints.software)\n  {\n    bool tryhw = false;\n#ifdef HAVE_LIBVDPAU\n    if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU))\n      tryhw = true;\n#endif\n#ifdef HAVE_LIBVA\n    if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI))\n      tryhw = true;\n#endif\n#ifdef HAS_DX\n    if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2))\n      tryhw = true;\n#endif\n#ifdef TARGET_DARWIN\n    if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVTB))\n      tryhw = true;\n#endif\n#ifdef HAS_MMAL\n    tryhw = true;\n#endif\n    if (tryhw && m_decoderState == STATE_NONE)\n    {\n      m_decoderState = STATE_HW_SINGLE;\n    }\n    else\n    {\n\t\tint num_threads = TVPGetProcessorNum() * 3 / 2;\n      num_threads = std::max(1, std::min(num_threads, 16));\n      m_pCodecContext->thread_count = num_threads;\n      m_pCodecContext->thread_safe_callbacks = 1;\n      m_decoderState = STATE_SW_MULTI;\n//      CLog::Log(LOGDEBUG, \"CDVDVideoCodecFFmpeg - open frame threaded with %d threads\", num_threads);\n    }\n  }\n  else\n    m_decoderState = STATE_SW_SINGLE;\n\n#if defined(TARGET_DARWIN_IOS)\n  // ffmpeg with enabled neon will crash and burn if this is enabled\n  m_pCodecContext->flags &= CODEC_FLAG_EMU_EDGE;\n#else\n  if (pCodec->id != AV_CODEC_ID_H264 && pCodec->capabilities & CODEC_CAP_DR1\n      && pCodec->id != AV_CODEC_ID_VP8\n     )\n    m_pCodecContext->flags |= CODEC_FLAG_EMU_EDGE;\n#endif\n\n  // if we don't do this, then some codecs seem to fail.\n  m_pCodecContext->coded_height = hints.height;\n  m_pCodecContext->coded_width = hints.width;\n  m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;\n\n  if( hints.extradata && hints.extrasize > 0 )\n  {\n    m_pCodecContext->extradata_size = hints.extrasize;\n    m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);\n    memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);\n  }\n\n  // advanced setting override for skip loop filter (see avcodec.h for valid options)\n  //! @todo allow per video setting?\n#if 0\n  if (g_advancedSettings.m_iSkipLoopFilter != 0)\n  {\n    m_pCodecContext->skip_loop_filter = (AVDiscard)g_advancedSettings.m_iSkipLoopFilter;\n  }\n#endif\n\n  // set any special options\n  for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it)\n  {\n    if (it->m_name == \"surfaces\")\n      m_uSurfacesCount = atoi(it->m_value.c_str());\n    else\n      av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0);\n  }\n\n  // If non-zero, the decoded audio and video frames returned from avcodec_decode_video2() are reference-counted and are valid indefinitely.\n  // Without this frames will get (deep) copied when deinterlace is set to automatic, but file is not deinterlaced.\n  m_pCodecContext->refcounted_frames = 1;\n\n  while (avcodec_open2(m_pCodecContext, pCodec, nullptr) < 0)\n  {\n\t  // trying set lowres to 0\n\t  if (pCodec->max_lowres < m_pCodecContext->lowres) {\n\t\t  m_pCodecContext->lowres = pCodec->max_lowres;\n\t\t  if (avcodec_open2(m_pCodecContext, pCodec, nullptr) >= 0)\n\t\t\t  break;\n\t  }\n//    CLog::Log(LOGDEBUG,\"CDVDVideoCodecFFmpeg::Open() Unable to open codec\");\n    avcodec_free_context(&m_pCodecContext);\n    return false;\n  }\n\n  m_pFrame = av_frame_alloc();\n  if (!m_pFrame)\n  {\n    avcodec_free_context(&m_pCodecContext);\n    return false;\n  }\n\n  m_pDecodedFrame = av_frame_alloc();\n  if (!m_pDecodedFrame)\n  {\n    av_frame_free(&m_pFrame);\n    avcodec_free_context(&m_pCodecContext);\n    return false;\n  }\n\n  m_pFilterFrame = av_frame_alloc();\n  if (!m_pFilterFrame)\n  {\n    av_frame_free(&m_pFrame);\n    av_frame_free(&m_pDecodedFrame);\n    avcodec_free_context(&m_pCodecContext);\n    return false;\n  }\n\n  UpdateName();\n\n  m_dropCtrl.Reset(true);\n  return true;\n}\n\nvoid CDVDVideoCodecFFmpeg::Dispose()\n{\n  av_frame_free(&m_pFrame);\n  av_frame_free(&m_pDecodedFrame);\n  av_frame_free(&m_pFilterFrame);\n  avcodec_free_context(&m_pCodecContext);\n  SAFE_RELEASE(m_pHardware);\n\n  FilterClose();\n}\n\nvoid CDVDVideoCodecFFmpeg::SetDropState(bool bDrop)\n{\n  if( m_pCodecContext )\n  {\n    if (bDrop && m_pHardware && m_pHardware->CanSkipDeint())\n    {\n      m_requestSkipDeint = true;\n      bDrop = false;\n    }\n    else\n      m_requestSkipDeint = false;\n\n    // i don't know exactly how high this should be set\n    // couldn't find any good docs on it. think it varies\n    // from codec to codec on what it does\n\n    //  2 seem to be to high.. it causes video to be ruined on following images\n    if( bDrop )\n    {\n      m_pCodecContext->skip_frame = AVDISCARD_NONREF;\n      m_pCodecContext->skip_idct = AVDISCARD_NONREF;\n      m_pCodecContext->skip_loop_filter = AVDISCARD_NONREF;\n    }\n    else\n    {\n      m_pCodecContext->skip_frame = AVDISCARD_DEFAULT;\n      m_pCodecContext->skip_idct = AVDISCARD_DEFAULT;\n      m_pCodecContext->skip_loop_filter = AVDISCARD_DEFAULT;\n    }\n  }\n}\n\nvoid CDVDVideoCodecFFmpeg::SetFilters()\n{\n\treturn;\n\n  // ask codec to do deinterlacing if possible\n//   EINTERLACEMETHOD mInt = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_InterlaceMethod;\n// \n//   if (!m_processInfo.Supports(mInt))\n//     mInt = m_processInfo.GetFallbackDeintMethod();\n\n  unsigned int filters = 0;\n\n//   if (mInt != VS_INTERLACEMETHOD_NONE)\n//   {\n//     if (mInt == VS_INTERLACEMETHOD_DEINTERLACE)\n//       filters = FILTER_DEINTERLACE_ANY;\n//     else if (mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)\n//       filters = FILTER_DEINTERLACE_ANY | FILTER_DEINTERLACE_HALFED;\n// \n//     if (filters)\n//       filters |= FILTER_DEINTERLACE_FLAGGED;\n//   }\n\n  if (m_codecControlFlags & DVD_CODEC_CTRL_ROTATE)\n    filters |= FILTER_ROTATE;\n\n  m_filters_next.clear();\n\n  if (filters & FILTER_ROTATE)\n  {\n    switch(m_iOrientation)\n    {\n      case 90:\n        m_filters_next += \"transpose=1\";\n        break;\n      case 180:\n        m_filters_next += \"vflip,hflip\";\n        break;\n      case 270:  \n        m_filters_next += \"transpose=2\";\n        break;\n      default:\n        break;\n      }\n  }\n\n  if (filters & FILTER_DEINTERLACE_YADIF)\n  {\n    if (filters & FILTER_DEINTERLACE_HALFED)\n      m_filters_next = \"yadif=0:-1\";\n    else\n      m_filters_next = \"yadif=1:-1\";\n\n    if (filters & FILTER_DEINTERLACE_FLAGGED)\n      m_filters_next += \":1\";\n  }\n}\n\nvoid CDVDVideoCodecFFmpeg::UpdateName()\n{\n  if(m_pCodecContext->codec->name)\n    m_name = std::string(\"ff-\") + m_pCodecContext->codec->name;\n  else\n    m_name = \"ffmpeg\";\n\n  if(m_pHardware)\n    m_name += \"-\" + m_pHardware->Name();\n\n  m_processInfo.SetVideoDecoderName(m_name, m_pHardware ? true : false);\n\n // CLog::Log(LOGDEBUG, \"CDVDVideoCodecFFmpeg - Updated codec: %s\", m_name.c_str());\n}\n\nunion pts_union\n{\n  double  pts_d;\n  int64_t pts_i;\n};\n\nstatic int64_t pts_dtoi(double pts)\n{\n  pts_union u;\n  u.pts_d = pts;\n  return u.pts_i;\n}\n\nint CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double pts)\n{\n  int iGotPicture = 0, len = 0;\n\n  if (!m_pCodecContext)\n    return VC_ERROR;\n\n  if (pData)\n    m_iLastKeyframe++;\n\n  if (m_pHardware)\n  {\n    int result;\n    if (pData || (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN))\n    {\n      result = m_pHardware->Check(m_pCodecContext);\n      result &= ~VC_NOBUFFER;\n    }\n    else\n    {\n      result = m_pHardware->Decode(m_pCodecContext, nullptr);\n    }\n\n    if (result)\n      return result;\n  }\n\n  if (!m_pHardware && pData)\n    SetFilters();\n\n  if (m_pFilterGraph && !m_filterEof)\n  {\n    int result = 0;\n    if (pData == NULL)\n      result = FilterProcess(nullptr);\n    if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN)\n    {\n      result &= VC_PICTURE;\n    }\n    if (result)\n      return result;\n  }\n\n  m_dts = dts;\n  m_pCodecContext->reordered_opaque = pts_dtoi(pts);\n\n  AVPacket avpkt;\n  av_init_packet(&avpkt);\n  avpkt.data = pData;\n  avpkt.size = iSize;\n  avpkt.dts = (dts == DVD_NOPTS_VALUE) ? AV_NOPTS_VALUE : dts / DVD_TIME_BASE * AV_TIME_BASE;\n  avpkt.pts = (pts == DVD_NOPTS_VALUE) ? AV_NOPTS_VALUE : pts / DVD_TIME_BASE * AV_TIME_BASE;\n\n  /* We lie, but this flag is only used by pngdec.c.\n   * Setting it correctly would allow CorePNG decoding. */\n  avpkt.flags = AV_PKT_FLAG_KEY;\n  len = avcodec_decode_video2(m_pCodecContext, m_pDecodedFrame, &iGotPicture, &avpkt);\n\n  if (m_decoderState == STATE_HW_FAILED && !m_pHardware)\n    return VC_REOPEN;\n\n  if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2)\n    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;\n\n  if (len < 0)\n  {\n    if(m_pHardware)\n    {\n      int result = m_pHardware->Check(m_pCodecContext);\n      if (result & VC_NOBUFFER)\n      {\n        result = m_pHardware->Decode(m_pCodecContext, NULL);\n        return result;\n      }\n    }\n//    CLog::Log(LOGERROR, \"%s - avcodec_decode_video returned failure\", __FUNCTION__);\n    return VC_ERROR;\n  }\n\n  if (!iGotPicture)\n  {\n    if (m_pHardware && (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN))\n    {\n      int result;\n      result = m_pHardware->Decode(m_pCodecContext, NULL);\n      return result;\n    }\n    else\n      return VC_BUFFER;\n  }\n\n  int64_t framePTS = av_frame_get_best_effort_timestamp(m_pDecodedFrame);\n\n  if (m_pCodecContext->skip_frame > AVDISCARD_DEFAULT)\n  {\n    if (m_dropCtrl.m_state == CDropControl::VALID &&\n        m_dropCtrl.m_lastPTS != AV_NOPTS_VALUE &&\n        framePTS != AV_NOPTS_VALUE &&\n        framePTS > (m_dropCtrl.m_lastPTS + m_dropCtrl.m_diffPTS * 1.5))\n    {\n      m_droppedFrames++;\n      if (m_interlaced)\n        m_droppedFrames++;\n    }\n  }\n  m_dropCtrl.Process(framePTS, m_pCodecContext->skip_frame > AVDISCARD_DEFAULT);\n\n  if (m_pDecodedFrame->key_frame)\n  {\n    m_started = true;\n    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;\n  }\n\n  if (!m_started)\n  {\n    av_frame_unref(m_pDecodedFrame);\n    return VC_BUFFER;\n  }\n\n  if (m_pDecodedFrame->interlaced_frame)\n    m_interlaced = true;\n  else\n    m_interlaced = false;\n\n  // put a limit on convergence count to avoid huge mem usage on streams without keyframes\n  if (m_iLastKeyframe > 300)\n    m_iLastKeyframe = 300;\n\n  //! @todo check if this work-around is still required\n  if(m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3)\n    m_started = true;\n\n  if (m_pHardware == nullptr)\n  {\n    bool need_scale = std::find( m_formats.begin()\n                               , m_formats.end()\n                               , m_pCodecContext->pix_fmt) == m_formats.end();\n\n    bool need_reopen  = false;\n    if (m_filters != m_filters_next)\n      need_reopen = true;\n\n    if (!m_filters_next.empty() && m_filterEof)\n      need_reopen = true;\n\n    if (m_pFilterIn)\n    {\n      if (m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt ||\n          m_pFilterIn->outputs[0]->w != m_pCodecContext->width ||\n          m_pFilterIn->outputs[0]->h != m_pCodecContext->height)\n        need_reopen = true;\n    }\n\n    // try to setup new filters\n    if (need_reopen || (need_scale && m_pFilterGraph == nullptr))\n    {\n      m_filters = m_filters_next;\n\n      if (FilterOpen(m_filters, need_scale) < 0)\n        FilterClose();\n    }\n  }\n\n  int result;\n  if (m_pHardware)\n  {\n    av_frame_unref(m_pFrame);\n    av_frame_move_ref(m_pFrame, m_pDecodedFrame);\n    result = m_pHardware->Decode(m_pCodecContext, m_pFrame);\n  }\n  else if (m_pFilterGraph && !m_filterEof)\n  {\n    result = FilterProcess(m_pDecodedFrame);\n  }\n  else\n  {\n    av_frame_unref(m_pFrame);\n    av_frame_move_ref(m_pFrame, m_pDecodedFrame);\n    result = VC_PICTURE | VC_BUFFER;\n  }\n\n  if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN)\n    result &= ~VC_BUFFER;\n\n  if (result & VC_FLUSHED)\n    Reset();\n\n  return result;\n}\n\nvoid CDVDVideoCodecFFmpeg::Reset()\n{\n  m_started = false;\n  m_interlaced = false;\n  m_decoderPts = DVD_NOPTS_VALUE;\n  m_skippedDeint = 0;\n  m_droppedFrames = 0;\n  m_iLastKeyframe = m_pCodecContext->has_b_frames;\n  avcodec_flush_buffers(m_pCodecContext);\n\n  if (m_pHardware)\n    m_pHardware->Reset();\n\n  m_filters = \"\";\n  FilterClose();\n  m_dropCtrl.Reset(false);\n}\n\nvoid CDVDVideoCodecFFmpeg::Reopen()\n{\n  Dispose();\n  if (!Open(m_hints, m_options))\n  {\n    Dispose();\n  }\n}\n\nbool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)\n{\n  if (!m_pFrame)\n    return false;\n\n  pDvdVideoPicture->iWidth = m_pFrame->width;\n  pDvdVideoPicture->iHeight = m_pFrame->height;\n#if 0\n  /* crop of 10 pixels if demuxer asked it */\n  if(m_pCodecContext->coded_width  && m_pCodecContext->coded_width  < (int)pDvdVideoPicture->iWidth\n                                   && m_pCodecContext->coded_width  > (int)pDvdVideoPicture->iWidth  - 10)\n    pDvdVideoPicture->iWidth = m_pCodecContext->coded_width;\n\n  if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pDvdVideoPicture->iHeight\n                                   && m_pCodecContext->coded_height > (int)pDvdVideoPicture->iHeight - 10)\n    pDvdVideoPicture->iHeight = m_pCodecContext->coded_height;\n#endif\n  double aspect_ratio;\n\n  /* use variable in the frame */\n  AVRational pixel_aspect = m_pFrame->sample_aspect_ratio;\n\n  if (pixel_aspect.num == 0)\n    aspect_ratio = 0;\n  else\n    aspect_ratio = av_q2d(pixel_aspect) * pDvdVideoPicture->iWidth / pDvdVideoPicture->iHeight;\n\n  if (aspect_ratio <= 0.0)\n    aspect_ratio = (float)pDvdVideoPicture->iWidth / (float)pDvdVideoPicture->iHeight;\n\n  if (m_DAR != aspect_ratio)\n  {\n    m_DAR = aspect_ratio;\n    m_processInfo.SetVideoDAR(m_DAR);\n  }\n\n  /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it.\n  pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;\n  pDvdVideoPicture->iDisplayWidth  = ((int)RINT(pDvdVideoPicture->iHeight * aspect_ratio)) & -3;\n  if (pDvdVideoPicture->iDisplayWidth > pDvdVideoPicture->iWidth)\n  {\n    pDvdVideoPicture->iDisplayWidth  = pDvdVideoPicture->iWidth;\n    pDvdVideoPicture->iDisplayHeight = ((int)RINT(pDvdVideoPicture->iWidth / aspect_ratio)) & -3;\n  }\n\n\n  pDvdVideoPicture->pts = DVD_NOPTS_VALUE;\n#if 0\n  AVDictionaryEntry * entry = av_dict_get(av_frame_get_metadata(m_pFrame), \"stereo_mode\", NULL, 0);\n  if(entry && entry->value)\n  {\n    strncpy(pDvdVideoPicture->stereo_mode, (const char*)entry->value, sizeof(pDvdVideoPicture->stereo_mode));\n    pDvdVideoPicture->stereo_mode[sizeof(pDvdVideoPicture->stereo_mode)-1] = '\\0';\n  }\n#endif\n  pDvdVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict;\n  pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;\n  pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0;\n  pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0;\n\n  if (m_codecControlFlags & DVD_CODEC_CTRL_DROP)\n    pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;\n\n  pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;\n  pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;\n  pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;\n  pDvdVideoPicture->color_matrix = m_pCodecContext->colorspace;\n  if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG\n  || m_pCodecContext->pix_fmt     == AV_PIX_FMT_YUVJ420P)\n    pDvdVideoPicture->color_range = 1;\n  else\n    pDvdVideoPicture->color_range = 0;\n\n  int qscale_type;\n  pDvdVideoPicture->qp_table = av_frame_get_qp_table(m_pFrame, &pDvdVideoPicture->qstride, &qscale_type);\n\n  switch (qscale_type)\n  {\n  case FF_QSCALE_TYPE_MPEG1:\n    pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1;\n    break;\n  case FF_QSCALE_TYPE_MPEG2:\n    pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG2;\n    break;\n  case FF_QSCALE_TYPE_H264:\n    pDvdVideoPicture->qscale_type = DVP_QSCALE_H264;\n    break;\n  default:\n    pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN;\n  }\n\n  if (pDvdVideoPicture->iRepeatPicture)\n    pDvdVideoPicture->dts = DVD_NOPTS_VALUE;\n  else\n    pDvdVideoPicture->dts = m_dts;\n\n  m_dts = DVD_NOPTS_VALUE;\n\n  int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame);\n  if (bpts != AV_NOPTS_VALUE)\n  {\n    pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;\n    if (pDvdVideoPicture->pts == m_decoderPts)\n    {\n      pDvdVideoPicture->iRepeatPicture = -0.5;\n      pDvdVideoPicture->pts = DVD_NOPTS_VALUE;\n      pDvdVideoPicture->dts = DVD_NOPTS_VALUE;\n    }\n  }\n  else\n    pDvdVideoPicture->pts = DVD_NOPTS_VALUE;\n\n  if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE)\n    m_decoderPts = pDvdVideoPicture->pts;\n\n  if (m_requestSkipDeint)\n  {\n    pDvdVideoPicture->iFlags |= DVD_CODEC_CTRL_SKIPDEINT;\n    m_skippedDeint++;\n  }\n\n  m_requestSkipDeint = false;\n  pDvdVideoPicture->iFlags |= m_codecControlFlags;\n\n  return true;\n}\n\nbool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)\n{\n\tif (m_pHardware)\n\t\treturn m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture);\n\n\tAVPixelFormat pix_fmt;\n\tpix_fmt = (AVPixelFormat)m_pFrame->format;\n\tpDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);\n\n\twhile (m_pCodecContext->coded_width > 0 && m_pCodecContext->coded_height > 0) {\n\t\tif (pDvdVideoPicture->format == RENDER_FMT_YUV420P) {\n\t\t\tint pitch = m_pFrame->linesize[0];\n\t\t\tif (pitch < m_pCodecContext->coded_width || pitch > m_pCodecContext->coded_width + 16)\n\t\t\t\tbreak;\n\t\t}\n\t\tm_pFrame->width = m_pCodecContext->coded_width;\n\t\tm_pFrame->height = m_pCodecContext->coded_height;\n\t\tbreak;\n\t}\n\n\tif (!GetPictureCommon(pDvdVideoPicture))\n\t\treturn false;\n\n\tfor (int i = 0; i < 4; i++)\n\t\tpDvdVideoPicture->data[i] = m_pFrame->data[i];\n\tfor (int i = 0; i < 4; i++)\n\t\tpDvdVideoPicture->iLineSize[i] = m_pFrame->linesize[i];\n\n\tpDvdVideoPicture->iFlags |= pDvdVideoPicture->data[0] ? 0 : DVP_FLAG_DROPPED;\n\tpDvdVideoPicture->extended_format = 0;\n\n\treturn true;\n}\n\nint CDVDVideoCodecFFmpeg::FilterOpen(const std::string& filters, bool scale)\n{\n  int result;\n\n  if (m_pFilterGraph)\n    FilterClose();\n\n  if (filters.empty() && !scale)\n    return 0;\n\n  if (m_pHardware)\n  {\n //   CLog::Log(LOGWARNING, \"CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode\");\n    return 0;\n  }\n\n  if (!(m_pFilterGraph = avfilter_graph_alloc()))\n  {\n//    CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph\");\n    return -1;\n  }\n\n  AVFilter* srcFilter = avfilter_get_by_name(\"buffer\");\n  AVFilter* outFilter = avfilter_get_by_name(\"buffersink\"); // should be last filter in the graph for now\n\n  char args[128];\n  sprintf(args, \"%d:%d:%d:%d:%d:%d:%d\",\n                                        m_pCodecContext->width,\n                                        m_pCodecContext->height,\n                                        m_pCodecContext->pix_fmt,\n                                        m_pCodecContext->time_base.num ? m_pCodecContext->time_base.num : 1,\n                                        m_pCodecContext->time_base.num ? m_pCodecContext->time_base.den : 1,\n                                        m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.num : 1,\n                                        m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.den : 1);\n\n  if ((result = avfilter_graph_create_filter(&m_pFilterIn, srcFilter, \"src\", args, NULL, m_pFilterGraph)) < 0)\n  {\n //   CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: src\");\n    return result;\n  }\n\n  if ((result = avfilter_graph_create_filter(&m_pFilterOut, outFilter, \"out\", NULL, NULL, m_pFilterGraph)) < 0)\n  {\n //   CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out\");\n    return result;\n  }\n  if ((result = av_opt_set_int_list(m_pFilterOut, \"pix_fmts\", &m_formats[0],  AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)\n  {\n //   CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - failed settings pix formats\");\n    return result;\n  }\n\n  if (!filters.empty())\n  {\n    AVFilterInOut* outputs = avfilter_inout_alloc();\n    AVFilterInOut* inputs  = avfilter_inout_alloc();\n\n    outputs->name = av_strdup(\"in\");\n    outputs->filter_ctx = m_pFilterIn;\n    outputs->pad_idx = 0;\n    outputs->next = nullptr;\n\n    inputs->name = av_strdup(\"out\");\n    inputs->filter_ctx = m_pFilterOut;\n    inputs->pad_idx = 0;\n    inputs->next = nullptr;\n\n    if ((result = avfilter_graph_parse_ptr(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0)\n    {\n  //    CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_parse\");\n      return result;\n    }\n\n    avfilter_inout_free(&outputs);\n    avfilter_inout_free(&inputs);\n\n    if (filters.compare(0,5,\"yadif\") == 0)\n    {\n      m_processInfo.SetVideoDeintMethod(filters);\n    }\n  }\n  else\n  {\n    if ((result = avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)\n    {\n //     CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - avfilter_link\");\n      return result;\n    }\n\n    m_processInfo.SetVideoDeintMethod(\"none\");\n  }\n\n  if ((result = avfilter_graph_config(m_pFilterGraph,  nullptr)) < 0)\n  {\n //   CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_config\");\n    return result;\n  }\n\n  m_filterEof = false;\n  return result;\n}\n\nvoid CDVDVideoCodecFFmpeg::FilterClose()\n{\n  if (m_pFilterGraph)\n  {\n    avfilter_graph_free(&m_pFilterGraph);\n\n    // Disposed by above code\n    m_pFilterIn = nullptr;\n    m_pFilterOut = nullptr;\n  }\n}\n\nint CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)\n{\n  int result;\n\n  if (frame || (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN))\n  {\n    result = av_buffersrc_add_frame(m_pFilterIn, frame);\n    if (result < 0)\n    {\n  //    CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterProcess - av_buffersrc_add_frame\");\n      return VC_ERROR;\n    }\n  }\n\n  result = av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame);\n\n  if (result  == AVERROR(EAGAIN))\n    return VC_BUFFER;\n  else if (result == AVERROR_EOF)\n  {\n    result = av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame);\n    m_filterEof = true;\n    if (result < 0)\n      return VC_BUFFER;\n  }\n  else if (result < 0)\n  {\n //   CLog::Log(LOGERROR, \"CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_get_frame\");\n    return VC_ERROR;\n  }\n\n  av_frame_unref(m_pFrame);\n  av_frame_move_ref(m_pFrame, m_pFilterFrame);\n\n  return VC_PICTURE;\n}\n\nunsigned CDVDVideoCodecFFmpeg::GetConvergeCount()\n{\n  return m_iLastKeyframe;\n}\n\nunsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()\n{\n  if(m_pHardware)\n    return m_pHardware->GetAllowedReferences();\n  else\n    return 0;\n}\n\nbool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &droppedFrames, int &skippedPics)\n{\n  if (m_decoderPts != DVD_NOPTS_VALUE)\n    pts = m_decoderPts;\n  else\n    pts = m_dts;\n\n  if (m_droppedFrames)\n    droppedFrames = m_droppedFrames;\n  else\n    droppedFrames = -1;\n  m_droppedFrames = 0;\n\n  if (m_skippedDeint)\n    skippedPics = m_skippedDeint;\n  else\n    skippedPics = -1;\n  m_skippedDeint = 0;\n\n  return true;\n}\n\nvoid CDVDVideoCodecFFmpeg::SetCodecControl(int flags)\n{\n  m_codecControlFlags = flags;\n  if (m_pHardware)\n    m_pHardware->SetCodecControl(flags);\n}\n\nvoid CDVDVideoCodecFFmpeg::SetHardware(IHardwareDecoder* hardware)\n{\n  SAFE_RELEASE(m_pHardware);\n  m_pHardware = hardware;\n  UpdateName();\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoCodecFFmpeg.h",
    "content": "#pragma once\n#include \"Codecs.h\"\n#include \"StreamInfo.h\"\n#include \"VideoCodec.h\"\n#include \"Ref.h\"\n\nextern \"C\" {\n#include \"libavfilter/avfilter.h\"\n#include \"libavcodec/avcodec.h\"\n#include \"libavformat/avformat.h\"\n#include \"libavutil/avutil.h\"\n#include \"libswscale/swscale.h\"\n}\n\nNS_KRMOVIE_BEGIN\n\nclass CDVDVideoCodecFFmpeg : public CDVDVideoCodec\n{\npublic:\n  class IHardwareDecoder : public IRef<IHardwareDecoder>\n  {\n    public:\n    IHardwareDecoder() {}\n    virtual ~IHardwareDecoder() {};\n    virtual bool Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum AVPixelFormat, unsigned int surfaces) = 0;\n    virtual int  Decode(AVCodecContext* avctx, AVFrame* frame) = 0;\n    virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) = 0;\n    virtual int  Check(AVCodecContext* avctx) = 0;\n    virtual void Reset() {}\n    virtual unsigned GetAllowedReferences() { return 0; }\n    virtual bool CanSkipDeint() {return false; }\n    virtual const std::string Name() = 0;\n    virtual void SetCodecControl(int flags) {};\n  };\n\n  CDVDVideoCodecFFmpeg(CProcessInfo &processInfo);\n  virtual ~CDVDVideoCodecFFmpeg();\n  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) override;\n  virtual int Decode(uint8_t* pData, int iSize, double dts, double pts) override;\n  virtual void Reset() override;\n  virtual void Reopen() override;\n  bool GetPictureCommon(DVDVideoPicture* pDvdVideoPicture);\n  virtual bool GetPicture(DVDVideoPicture* pDvdVideoPicture) override;\n  virtual void SetDropState(bool bDrop) override;\n  virtual const char* GetName() override { return m_name.c_str(); }; // m_name is never changed after open\n  virtual unsigned GetConvergeCount() override;\n  virtual unsigned GetAllowedReferences() override;\n  virtual bool GetCodecStats(double &pts, int &droppedFrames, int &skippedPics) override;\n  virtual void SetCodecControl(int flags) override;\n\n  IHardwareDecoder * GetHardware() { return m_pHardware; };\n  void SetHardware(IHardwareDecoder* hardware);\n\nprotected:\n  void Dispose();\n  static enum AVPixelFormat GetFormat(struct AVCodecContext * avctx, const AVPixelFormat * fmt);\n\n  int  FilterOpen(const std::string& filters, bool scale);\n  void FilterClose();\n  int  FilterProcess(AVFrame* frame);\n  void SetFilters();\n  void UpdateName();\n\n  AVFrame* m_pFrame;\n  AVFrame* m_pDecodedFrame;\n  AVCodecContext* m_pCodecContext;\n\n  std::string       m_filters;\n  std::string       m_filters_next;\n  AVFilterGraph*   m_pFilterGraph;\n  AVFilterContext* m_pFilterIn;\n  AVFilterContext* m_pFilterOut;\n  AVFrame*         m_pFilterFrame;\n  bool m_filterEof;\n\n  int m_iPictureWidth;\n  int m_iPictureHeight;\n\n  int m_iScreenWidth;\n  int m_iScreenHeight;\n  int m_iOrientation;// orientation of the video in degress counter clockwise\n\n  unsigned int m_uSurfacesCount;\n\n  std::string m_name;\n  int m_decoderState;\n  IHardwareDecoder *m_pHardware;\n  int m_iLastKeyframe;\n  double m_dts;\n  bool   m_started;\n  std::vector<AVPixelFormat> m_formats;\n  double m_decoderPts;\n  int    m_skippedDeint;\n  int    m_droppedFrames;\n  bool   m_requestSkipDeint;\n  int    m_codecControlFlags;\n  bool m_interlaced;\n  double m_DAR;\n  CDVDStreamInfo m_hints;\n  CDVDCodecOptions m_options;\n\n  struct CDropControl\n  {\n    CDropControl();\n    void Reset(bool init);\n    void Process(int64_t pts, bool drop);\n\n    int64_t m_lastPTS;\n    int64_t m_diffPTS;\n    int m_count;\n    enum\n    {\n      INIT,\n      VALID\n    } m_state;\n  } m_dropCtrl;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayer.cpp",
    "content": "#include \"VideoPlayer.h\"\n#include <cmath>\n#include <algorithm>\n#include \"DemuxFFmpeg.h\"\n#include \"VideoPlayerVideo.h\"\n#include \"VideoPlayerAudio.h\"\n#include \"DemuxPacket.h\"\n#include \"InputStream.h\"\n#include \"krmovie.h\"\n#include \"TimeUtils.h\"\n#include \"tjsConfig.h\"\n#include \"Application.h\"\n#include <cstdlib>\n#include <iterator>\n#include \"platform/CCPlatformConfig.h\"\n#include \"AEStream.h\"\n#include \"WaveMixer.h\"\n\n#ifdef HAS_OMXPLAYER\n#include \"../omxplayer/OMXPlayerAudio.h\"\n#include \"../omxplayer/OMXPlayerVideo.h\"\n#include \"../omxplayer/OMXHelper.h\"\n#endif\n\nvoid TVPInitLibAVCodec();\n\nNS_KRMOVIE_BEGIN\n\nvoid CSelectionStreams::Clear(StreamType type, StreamSource source)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tauto new_end = std::remove_if(m_Streams.begin(), m_Streams.end(),\n\t\t[type, source](const SelectionStream &stream)\n\t{\n\t\treturn (type == STREAM_NONE || stream.type == type) &&\n\t\t\t(source == 0 || stream.source == source);\n\t});\n\tm_Streams.erase(new_end, m_Streams.end());\n}\n\nint CSelectionStreams::IndexOf(StreamType type, int source, int64_t demuxerId, int id)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tint count = -1;\n\tfor (size_t i = 0; i < m_Streams.size(); i++)\n\t{\n\t\tif (type && m_Streams[i].type != type)\n\t\t\tcontinue;\n\t\tcount++;\n\t\tif (source && m_Streams[i].source != source)\n\t\t\tcontinue;\n\t\tif (id < 0)\n\t\t\tcontinue;\n\t\tif (m_Streams[i].id == id && m_Streams[i].demuxerId == demuxerId)\n\t\t\treturn count;\n\t}\n\tif (id < 0)\n\t\treturn count;\n\telse\n\t\treturn -1;\n}\n\nSelectionStream& CSelectionStreams::Get(StreamType type, int index)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tint count = -1;\n\tfor (size_t i = 0; i < m_Streams.size(); i++)\n\t{\n\t\tif (m_Streams[i].type != type)\n\t\t\tcontinue;\n\t\tcount++;\n\t\tif (count == index)\n\t\t\treturn m_Streams[i];\n\t}\n\treturn m_invalid;\n}\n\nstd::vector<SelectionStream> CSelectionStreams::Get(StreamType type)\n{\n\tstd::vector<SelectionStream> streams;\n\tstd::copy_if(m_Streams.begin(), m_Streams.end(), std::back_inserter(streams),\n\t\t[type](const SelectionStream &stream)\n\t{\n\t\treturn stream.type == type;\n\t});\n\treturn streams;\n}\n\nbool CSelectionStreams::Get(StreamType type, CDemuxStream::EFlags flag, SelectionStream& out)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tfor (size_t i = 0; i < m_Streams.size(); i++)\n\t{\n\t\tif (m_Streams[i].type != type)\n\t\t\tcontinue;\n\t\tif ((m_Streams[i].flags & flag) != flag)\n\t\t\tcontinue;\n\t\tout = m_Streams[i];\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nint CSelectionStreams::Source(StreamSource source, const std::string & filename)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tint index = source - 1;\n\tfor (size_t i = 0; i < m_Streams.size(); i++)\n\t{\n\t\tSelectionStream &s = m_Streams[i];\n\t\tif (STREAM_SOURCE_MASK(s.source) != source)\n\t\t\tcontinue;\n\t\t// if it already exists, return same\n\t\tif (s.filename == filename)\n\t\t\treturn s.source;\n\t\tif (index < s.source)\n\t\t\tindex = s.source;\n\t}\n\t// return next index\n\treturn index + 1;\n}\n\nvoid CSelectionStreams::Update(SelectionStream& s)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_section);\n\tint index = IndexOf(s.type, s.source, s.demuxerId, s.id);\n\tif (index >= 0)\n\t{\n\t\tSelectionStream& o = Get(s.type, index);\n\t\ts.type_index = o.type_index;\n\t\to = s;\n\t} else\n\t{\n\t\ts.type_index = Count(s.type);\n\t\tm_Streams.push_back(s);\n\t}\n}\n\nvoid CSelectionStreams::Update(InputStream* input, IDemux* demuxer, const std::string &filename2)\n{\n\tif (demuxer)\n\t{\n\t\tint source;\n\t\tconst std::string& filename = input->GetFileName();\n\t\tif (input) /* hack to know this is sub decoder */\n\t\t\tsource = Source(STREAM_SOURCE_DEMUX, filename);\n// \t\telse if (!filename2.empty())\n// \t\t\tsource = Source(STREAM_SOURCE_DEMUX_SUB, filename);\n\t\telse\n\t\t\tsource = Source(STREAM_SOURCE_VIDEOMUX, filename);\n\n\t\tfor (auto stream : demuxer->GetStreams())\n\t\t{\n\t\t\t/* skip streams with no type */\n\t\t\tif (stream->type == STREAM_NONE)\n\t\t\t\tcontinue;\n\t\t\t/* make sure stream is marked with right source */\n\t\t\tstream->source = source;\n\n\t\t\tSelectionStream s;\n\t\t\ts.source = source;\n\t\t\ts.type = stream->type;\n\t\t\ts.id = stream->uniqueId;\n\t\t\ts.demuxerId = stream->demuxerId;\n//\t\t\ts.language = g_LangCodeExpander.ConvertToISO6392T(stream->language);\n\t\t\ts.flags = stream->flags;\n\t\t\ts.filename = filename;\n//\t\t\ts.filename2 = filename2;\n\t\t\ts.name = stream->GetStreamName();\n\t\t\ts.codec = demuxer->GetStreamCodecName(stream->demuxerId, stream->uniqueId);\n\t\t\ts.channels = 0; // Default to 0. Overwrite if STREAM_AUDIO below.\n\t\t\tif (stream->type == STREAM_VIDEO)\n\t\t\t{\n\t\t\t\ts.width = ((CDemuxStreamVideo*)stream)->iWidth;\n\t\t\t\ts.height = ((CDemuxStreamVideo*)stream)->iHeight;\n\t\t\t\ts.stereo_mode = ((CDemuxStreamVideo*)stream)->stereo_mode;\n\t\t\t}\n\t\t\tif (stream->type == STREAM_AUDIO)\n\t\t\t{\n\t\t\t\tstd::string type;\n\t\t\t\ttype = ((CDemuxStreamAudio*)stream)->GetStreamType();\n\t\t\t\tif (type.length() > 0)\n\t\t\t\t{\n\t\t\t\t\tif (s.name.length() > 0)\n\t\t\t\t\t\ts.name += \" - \";\n\t\t\t\t\ts.name += type;\n\t\t\t\t}\n\t\t\t\ts.channels = ((CDemuxStreamAudio*)stream)->iChannels;\n\t\t\t}\n\t\t\tUpdate(s);\n\t\t}\n\t}\n// \tCServiceBroker::GetDataCacheCore().SignalAudioInfoChange();\n// \tCServiceBroker::GetDataCacheCore().SignalVideoInfoChange();\n}\n\nBasePlayer::BasePlayer(CBaseRenderer *renderer)\n\t: m_CurrentAudio(STREAM_AUDIO, VideoPlayer_AUDIO)\n\t, m_CurrentVideo(STREAM_VIDEO, VideoPlayer_VIDEO)\n\t, m_messenger(\"player\")\n\t, m_renderManager(m_clock, this)\n\t, m_processInfo(CProcessInfo::CreateInstance())\n\t, m_pRenderer(renderer)\n{\n\tTVPInitDirectSound(); // to avoid initialize in other thread\n\tTVPInitLibAVCodec();\n\tm_playSpeed = DVD_PLAYSPEED_NORMAL;\n\tm_newPlaySpeed = DVD_PLAYSPEED_NORMAL;\n\tm_streamPlayerSpeed = DVD_PLAYSPEED_NORMAL;\n\tm_caching = CACHESTATE_DONE;\n\tmemset(&m_SpeedState, 0, sizeof(m_SpeedState));\n#if 0\n\t::Application->RegisterActiveEvent(this, [](void* p, eTVPActiveEvent ev){\n\t\tswitch (ev) {\n\t\tcase eTVPActiveEvent::onActive:\n\t\t\tstatic_cast<BasePlayer*>(p)->OnActive();\n\t\t\tbreak;\n\t\tcase eTVPActiveEvent::onDeactive:\n\t\t\tstatic_cast<BasePlayer*>(p)->OnDeactive();\n\t\t\tbreak;\n\t\t}\n\t});\n#endif\n}\n\nBasePlayer::~BasePlayer() {\n\tCloseInputStream();\n\tDestroyPlayers();\n\t::Application->RegisterActiveEvent(this, nullptr);\n}\n\nvoid BasePlayer::Play()\n{\n\tm_bStopStatus = false;\n\n\tif (!m_ThreadId)\n\t\tCreate();\n\t\n\tif (GetSpeed() == 0)\n\t\tSetSpeed(1/*m_newPlaySpeed*/);\n}\n\nvoid BasePlayer::Stop()\n{\n\tm_bStopStatus = true;\n\t// pause and rewind\n\tSetSpeed(0);\n\tSeekTime(0);\n}\n\nvoid BasePlayer::Pause()\n{\n\tif (GetSpeed() != 0)\n\t\tSetSpeed(0);\n}\n\nvoid BasePlayer::GetVideoSize(long *width, long *height)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(m_SelectionStreams.m_section);\n\tint streamId = GetVideoStream();\n\n\tif (streamId < 0) {\n\t\t*width = 0;\n\t\t*height = 0;\n\t\treturn;\n\t}\n\n\tSelectionStream& s = m_SelectionStreams.Get(STREAM_VIDEO, streamId);\n\n\t*width = s.width;\n\t*height = s.height;\n}\n\nvoid BasePlayer::SetLoopSegement(int beginFrame, unsigned int endFrame)\n{\n\tm_iLoopSegmentBegin = beginFrame;\n\tm_iLoopSegmentEnd = endFrame;\n}\n\nvoid BasePlayer::OnDeactive()\n{\n\tm_origSpeed = GetSpeed();\n\tm_clock.Pause(true);\n}\n\nvoid BasePlayer::OnActive()\n{\n\tm_clock.Pause(false);\n\tSetSpeed(m_origSpeed);\n}\n\nvoid BasePlayer::VideoParamsChange()\n{\n\tm_messenger.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE));\n}\n\nvoid BasePlayer::GetDebugInfo(std::string &audio, std::string &video, std::string &general)\n{\n// \taudio = m_VideoPlayerAudio->GetPlayerInfo();\n// \tvideo = m_VideoPlayerVideo->GetPlayerInfo();\n// \tGetGeneralInfo(general);\n}\n\nvoid BasePlayer::UpdateClockSync(bool enabled)\n{\n\tm_processInfo->SetRenderClockSync(enabled);\n}\n\nvoid BasePlayer::UpdateRenderInfo(CRenderInfo &info)\n{\n\tm_processInfo->UpdateRenderInfo(info);\n}\n\nbool BasePlayer::OpenFromStream(IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size)\n{\n\tif (IsRunning())\n\t\tCloseInputStream();\n\n\tTJS::tTJSNarrowStringHolder holder(streamname);\n\tstd::string filename = holder.operator const tjs_nchar *();\n\n\tm_bAbortRequest = false;\n\tSetPlaySpeed(DVD_PLAYSPEED_NORMAL);\n\n\tm_State.Clear();\n\tmemset(&m_SpeedState, 0, sizeof(m_SpeedState));\n//\tm_UpdateApplication = 0;\n\tm_offset_pts = 0;\n\tm_CurrentAudio.lastdts = DVD_NOPTS_VALUE;\n\tm_CurrentVideo.lastdts = DVD_NOPTS_VALUE;\n\n//\tm_PlayerOptions = options;\n//\tm_item = file;\n\t// Try to resolve the correct mime type\n//\tm_item.SetMimeTypeForInternetFile();\n\n//\tm_ready.Reset();\n\n//\tm_renderManager.PreInit();\n\n\tm_CurrentVideo.Clear();\n\tm_CurrentAudio.Clear();\n// \tm_CurrentSubtitle.Clear();\n// \tm_CurrentTeletext.Clear();\n// \tm_CurrentRadioRDS.Clear();\n\n\tm_messenger.Init();\n\n//\tCUtil::ClearTempFonts();\n\tm_playSpeed = DVD_PLAYSPEED_PAUSE; // pause at begin\n\tm_newPlaySpeed = DVD_PLAYSPEED_PAUSE;\n\tm_streamPlayerSpeed = DVD_PLAYSPEED_PAUSE;\n\n\tOpenInputStream(stream, filename);\n\tOpenDemuxStream();\n\tCreatePlayers();\n#if HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t{\n\t\tif (!m_OmxPlayerState.av_clock.OMXInitialize(&m_clock))\n\t\t\tm_bAbortRequest = true;\n#if 0\n\t\tif (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF)\n\t\t\tm_OmxPlayerState.av_clock.HDMIClockSync();\n#endif\n\t\tm_OmxPlayerState.av_clock.OMXStateIdle();\n\t\tm_OmxPlayerState.av_clock.OMXStateExecute();\n\t\tm_OmxPlayerState.av_clock.OMXStop();\n\t\tm_OmxPlayerState.av_clock.OMXPause();\n\t}\n#endif\n\tOpenDefaultStreams();\n\n\tUpdatePlayState(0);\n\n\tSetCaching(CACHESTATE_FLUSH);\n\n\t// Playback might have been stopped due to some error\n\tif (m_bStop || m_bAbortRequest)\n\t\treturn false;\n\n\t// ready to play\n\tm_renderManager.Configure();\n\treturn true;\n}\n\nbool BasePlayer::CloseInputStream()\n{\n//\tCLog::Log(LOGNOTICE, \"CVideoPlayer::CloseFile()\");\n\n\t// set the abort request so that other threads can finish up\n\tm_bAbortRequest = true;\n\n\t// tell demuxer to abort\n\tif (m_pDemuxer)\n\t\tm_pDemuxer->Abort();\n\n// \tif (m_pSubtitleDemuxer)\n// \t\tm_pSubtitleDemuxer->Abort();\n\n\tSAFE_RELEASE(m_pInputStream);\n\n// \tif (m_pInputStream)\n// \t\tm_pInputStream->Abort();\n\n//\tCLog::Log(LOGNOTICE, \"VideoPlayer: waiting for threads to exit\");\n\n\t// wait for the main thread to finish up\n\t// since this main thread cleans up all other resources and threads\n\t// we are done after the StopThread call\n\tStopThread();\n\n\tm_HasVideo = false;\n\tm_HasAudio = false;\n//\tm_canTempo = false;\n\n//\tCLog::Log(LOGNOTICE, \"VideoPlayer: finished waiting\");\n//\tm_renderManager.UnInit();\n\treturn true;\n}\n\nbool BasePlayer::IsPlaying() const\n{\n\treturn !m_bStop;\n}\n\nbool BasePlayer::CanSeek()\n{\n\tCSingleLock lock(m_StateSection);\n\treturn m_State.canseek;\n}\n\nvoid BasePlayer::OnExit()\n{\n//\tCLog::Log(LOGNOTICE, \"CVideoPlayer::OnExit()\");\n\n\t// set event to inform openfile something went wrong in case openfile is still waiting for this event\n\tSetCaching(CACHESTATE_DONE);\n\n\t// close each stream\n//\tif (!m_bAbortRequest) CLog::Log(LOGNOTICE, \"VideoPlayer: eof, waiting for queues to empty\");\n\tCloseStream(m_CurrentAudio, !m_bAbortRequest);\n\tCloseStream(m_CurrentVideo, !m_bAbortRequest);\n\n\t// the generalization principle was abused for subtitle player. actually it is not a stream player like\n\t// video and audio. subtitle player does not run on its own thread, hence waitForBuffers makes\n\t// no sense here. waitForBuffers is abused to clear overlay container (false clears container)\n\t// subtitles are added from video player. after video player has finished, overlays have to be cleared.\n//\tCloseStream(m_CurrentSubtitle, false);  // clear overlay container\n\n// \tCloseStream(m_CurrentTeletext, !m_bAbortRequest);\n// \tCloseStream(m_CurrentRadioRDS, !m_bAbortRequest);\n\n\t// destroy objects\n\tSAFE_DELETE(m_pDemuxer);\n// \tSAFE_DELETE(m_pSubtitleDemuxer);\n// \tSAFE_DELETE(m_pCCDemuxer);\n\tSAFE_RELEASE(m_pInputStream);\n\n\t// clean up all selection streams\n\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NONE);\n\n\tm_messenger.End();\n#ifdef HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t{\n\t\tm_OmxPlayerState.av_clock.OMXStop();\n\t\tm_OmxPlayerState.av_clock.OMXStateIdle();\n\t\tm_OmxPlayerState.av_clock.OMXDeinitialize();\n\t}\n#endif\n\tm_bStop = true;\n\tm_bStopStatus = true;\n\t// if we didn't stop playing, advance to the next item in xbmc's playlist\n//\tif (m_PlayerOptions.identify == false)\n\t{\n\t\t// already ended, don't send message\n//\t\tif (m_callback) m_callback(KRMovieEvent::Stopped, nullptr);\n\t}\n\n\t// set event to inform openfile something went wrong in case openfile is still waiting for this event\n\tm_ready.notify_all();\n\n//\tCFFmpegLog::ClearLogLevel();\n}\n\nbool BasePlayer::IsValidStream(CCurrentStream& stream)\n{\n\tif (stream.id < 0)\n\t\treturn true; // we consider non selected as valid\n\n\tint source = STREAM_SOURCE_MASK(stream.source);\n\tif (source == STREAM_SOURCE_TEXT)\n\t\treturn true;\n#if 0\n\tif (source == STREAM_SOURCE_DEMUX_SUB)\n\t{\n\t\tCDemuxStream* st = m_pSubtitleDemuxer->GetStream(stream.demuxerId, stream.id);\n\t\tif (st == NULL || st->disabled)\n\t\t\treturn false;\n\t\tif (st->type != stream.type)\n\t\t\treturn false;\n\t\treturn true;\n\t}\n#endif\n\tif (source == STREAM_SOURCE_DEMUX)\n\t{\n\t\tCDemuxStream* st = m_pDemuxer->GetStream(stream.demuxerId, stream.id);\n\t\tif (st == NULL || st->disabled)\n\t\t\treturn false;\n\t\tif (st->type != stream.type)\n\t\t\treturn false;\n\t\t\n\t\treturn true;\n\t}\n#if 0\n\tif (source == STREAM_SOURCE_VIDEOMUX)\n\t{\n\t\tCDemuxStream* st = m_pCCDemuxer->GetStream(stream.id);\n\t\tif (st == NULL || st->disabled)\n\t\t\treturn false;\n\t\tif (st->type != stream.type)\n\t\t\treturn false;\n\t\treturn true;\n\t}\n#endif\n\n\treturn false;\n}\n\nbool BasePlayer::IsBetterStream(CCurrentStream& current, CDemuxStream* stream)\n{\n\tif (stream->disabled)\n\t\treturn false;\n\tif (stream->source == current.source &&\n\t\tstream->uniqueId == current.id &&\n\t\tstream->demuxerId == current.demuxerId)\n\t\treturn false;\n\n\tif (stream->type != current.type)\n\t\treturn false;\n#if 0\n\tif (current.type == STREAM_SUBTITLE)\n\t\treturn false;\n#endif\n\tif (current.id < 0)\n\t\treturn true;\n\n\treturn false;\n}\n\nvoid BasePlayer::CheckBetterStream(CCurrentStream& current, CDemuxStream* stream)\n{\n\tIDVDStreamPlayer* player = GetStreamPlayer(current.player);\n\tif (!IsValidStream(current) && (player == NULL || player->IsStalled()))\n\t\tCloseStream(current, true);\n\n\tif (IsBetterStream(current, stream))\n\t\tOpenStream(current, stream->demuxerId, stream->uniqueId, stream->source);\n}\n\nvoid BasePlayer::CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream)\n{\n\tif (current.stream != (void*)stream\n\t\t|| current.changes != stream->changes)\n\t{\n\t\t/* check so that dmuxer hints or extra data hasn't changed */\n\t\t/* if they have, reopen stream */\n\n\t\tif (current.hint != CDVDStreamInfo(*stream, true))\n\t\t{\n\t\t\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);\n\t\t\tm_SelectionStreams.Update(m_pInputStream, m_pDemuxer);\n\t\t\tOpenDefaultStreams(false);\n\t\t}\n\n\t\tcurrent.stream = (void*)stream;\n\t\tcurrent.changes = stream->changes;\n\t}\n}\n\nvoid BasePlayer::Process()\n{\n\twhile (!m_bAbortRequest)\n\t{\n#ifdef HAS_OMXPLAYER\n\t\tif (m_omxplayer_mode && OMXDoProcessing(m_OmxPlayerState, m_playSpeed, m_VideoPlayerVideo, m_VideoPlayerAudio, m_CurrentAudio, m_CurrentVideo, m_HasVideo, m_HasAudio, m_renderManager))\n\t\t{\n\t\t\tCloseStream(m_CurrentVideo, false);\n\t\t\tOpenStream(m_CurrentVideo, m_CurrentVideo.demuxerId, m_CurrentVideo.id, m_CurrentVideo.source);\n\t\t\tif (m_State.canseek)\n\t\t\t{\n\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\tmode.time = (int)GetTime();\n\t\t\t\tmode.backward = true;\n\t\t\t\tmode.flush = true;\n\t\t\t\tmode.accurate = true;\n\t\t\t\tmode.sync = true;\n\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t}\n\t\t}\n#endif\n\n\t\t// handle messages send to this thread, like seek or demuxer reset requests\n\t\tHandleMessages();\n\n\t\tif (m_bAbortRequest)\n\t\t\tbreak;\n\n\t\t// should we open a new demuxer?\n\t\tif (!m_pDemuxer)\n\t\t{\n\t\t\tif (OpenDemuxStream() == false)\n\t\t\t{\n\t\t\t\tm_bAbortRequest = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// on channel switch we don't want to close stream players at this\n\t\t\t// time. we'll get the stream change event later\n\t\t\tOpenDefaultStreams();\n\n//\t\t\tUpdateApplication(0);\n\t\t\tUpdatePlayState(0);\n\t\t}\n\n\t\t// handle eventual seeks due to playspeed\n\t\tHandlePlaySpeed();\n\n\t\t// update player state\n\t\tUpdatePlayState(200);\n\n\t\t// update application with our state\n//\t\tUpdateApplication(1000);\n\n\t\t// make sure we run subtitle process here\n//\t\tm_VideoPlayerSubtitle->Process(m_clock.GetClock() + m_State.time_offset - m_VideoPlayerVideo->GetSubtitleDelay(), m_State.time_offset);\n\n// \t\tif (CheckDelayedChannelEntry())\n// \t\t\tcontinue;\n\n\t\t// if the queues are full, no need to read more\n\t\tif ((!m_VideoPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||\n\t\t\t(!m_VideoPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))\n\t\t{\n\t\t\tSleep(10);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// always yield to players if they have data levels > 50 percent\n\t\tif ((m_VideoPlayerAudio->GetLevel() > 50 || m_CurrentAudio.id < 0)\n\t\t\t&& (m_VideoPlayerVideo->GetLevel() > 50 || m_CurrentVideo.id < 0))\n\t\t\tSleep(0);\n\n\t\tDemuxPacket* pPacket = NULL;\n\t\tCDemuxStream *pStream = NULL;\n\t\tReadPacket(pPacket, pStream);\n\t\tif (pPacket && !pStream)\n\t\t{\n\t\t\t/* probably a empty packet, just free it and move on */\n\t\t\tDemuxPacket::Free(pPacket);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!pPacket)\n\t\t{\n\t\t\t// when paused, demuxer could be be returning empty\n\t\t\tif (m_playSpeed == DVD_PLAYSPEED_PAUSE)\n\t\t\t\tcontinue;\n\n#ifdef HAS_OMXPLAYER\n\t\t\t// make sure we tell all players to finish it's data\n\t\t\tif (m_omxplayer_mode && !m_OmxPlayerState.bOmxSentEOFs)\n\t\t\t{\n\t\t\t\tif (m_CurrentAudio.inited)\n\t\t\t\t\tm_OmxPlayerState.bOmxWaitAudio = true;\n\n\t\t\t\tif (m_CurrentVideo.inited)\n\t\t\t\t\tm_OmxPlayerState.bOmxWaitVideo = true;\n\n\t\t\t\tm_OmxPlayerState.bOmxSentEOFs = true;\n\t\t\t}\n#endif\n\n\t\t\tif (m_iLoopSegmentBegin != -1) { // process loop info\n\t\t\t\tdouble start = DVD_NOPTS_VALUE;\n\t\t\t\tif (m_pDemuxer && m_pDemuxer->SeekTime(m_iLoopSegmentBegin / GetFPS() * DVD_PLAYSPEED_NORMAL, true, &start)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m_CurrentAudio.inited)\n\t\t\t\tm_VideoPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));\n\t\t\tif (m_CurrentVideo.inited)\n\t\t\t\tm_VideoPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));\n// \t\t\tif (m_CurrentSubtitle.inited)\n// \t\t\t\tm_VideoPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));\n// \t\t\tif (m_CurrentTeletext.inited)\n// \t\t\t\tm_VideoPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));\n// \t\t\tif (m_CurrentRadioRDS.inited)\n// \t\t\t\tm_VideoPlayerRadioRDS->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));\n\n\t\t\tm_CurrentAudio.inited = false;\n\t\t\tm_CurrentVideo.inited = false;\n// \t\t\tm_CurrentSubtitle.inited = false;\n// \t\t\tm_CurrentTeletext.inited = false;\n// \t\t\tm_CurrentRadioRDS.inited = false;\n\n\t\t\t// if we are caching, start playing it again\n\t\t\tSetCaching(CACHESTATE_DONE);\n\n\t\t\t// while players are still playing, keep going to allow seekbacks\n\t\t\tif (m_VideoPlayerAudio->HasData()\n\t\t\t\t|| m_VideoPlayerVideo->HasData())\n\t\t\t{\n\t\t\t\tSleep(100);\n\t\t\t\tcontinue;\n\t\t\t}\n#ifdef HAS_OMXPLAYER\n\t\t\tif (m_omxplayer_mode && OMXStillPlaying(m_OmxPlayerState.bOmxWaitVideo, m_OmxPlayerState.bOmxWaitAudio, m_VideoPlayerVideo->IsEOS(), m_VideoPlayerAudio->IsEOS()))\n\t\t\t{\n\t\t\t\tSleep(100);\n\t\t\t\tcontinue;\n\t\t\t}\n#endif\n\t\t\t\n\t\t\t// TODO process loop info\n\t\t\tSetSpeed(0);\n\t\t\tSeekTime(0); // rewind\n\t\t\tif (m_callback) m_callback(KRMovieEvent::Ended, nullptr);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// it's a valid data packet, reset error counter\n\t\tm_errorCount = 0;\n\n\t\t// see if we can find something better to play\n\t\tCheckBetterStream(m_CurrentAudio, pStream);\n\t\tCheckBetterStream(m_CurrentVideo, pStream);\n// \t\tCheckBetterStream(m_CurrentSubtitle, pStream);\n// \t\tCheckBetterStream(m_CurrentTeletext, pStream);\n// \t\tCheckBetterStream(m_CurrentRadioRDS, pStream);\n\n\t\t// demux video stream\n#if 0\n\t\tif (CSettings::GetInstance().GetBool(CSettings::SETTING_SUBTITLES_PARSECAPTIONS) && CheckIsCurrent(m_CurrentVideo, pStream, pPacket))\n\t\t{\n\t\t\tif (m_pCCDemuxer)\n\t\t\t{\n\t\t\t\tbool first = true;\n\t\t\t\twhile (!m_bAbortRequest)\n\t\t\t\t{\n\t\t\t\t\tDemuxPacket *pkt = m_pCCDemuxer->Read(first ? pPacket : NULL);\n\t\t\t\t\tif (!pkt)\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t\tif (m_pCCDemuxer->GetNrOfStreams() != m_SelectionStreams.CountSource(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX))\n\t\t\t\t\t{\n\t\t\t\t\t\tm_SelectionStreams.Clear(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX);\n\t\t\t\t\t\tm_SelectionStreams.Update(NULL, m_pCCDemuxer, \"\");\n\t\t\t\t\t\tOpenDefaultStreams(false);\n\t\t\t\t\t}\n\t\t\t\t\tCDemuxStream *pSubStream = m_pCCDemuxer->GetStream(pkt->iStreamId);\n\t\t\t\t\tif (pSubStream && m_CurrentSubtitle.id == pkt->iStreamId && m_CurrentSubtitle.source == STREAM_SOURCE_VIDEOMUX)\n\t\t\t\t\t\tProcessSubData(pSubStream, pkt);\n\t\t\t\t\telse\n\t\t\t\t\t\tCDVDDemuxUtils::FreeDemuxPacket(pkt);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (IsInMenuInternal())\n\t\t{\n\t\t\tif (CDVDInputStream::IMenus* menu = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))\n\t\t\t{\n\t\t\t\tdouble correction = menu->GetTimeStampCorrection();\n\t\t\t\tif (pPacket->dts > correction)\n\t\t\t\t\tpPacket->dts -= correction;\n\t\t\t\tif (pPacket->pts > correction)\n\t\t\t\t\tpPacket->pts -= correction;\n\t\t\t}\n\t\t\tif (m_dvd.syncClock)\n\t\t\t{\n\t\t\t\tm_clock.Discontinuity(pPacket->dts);\n\t\t\t\tm_dvd.syncClock = false;\n\t\t\t}\n\t\t}\n#endif\n\t\t// process the packet\n\t\tProcessPacket(pStream, pPacket);\n\n\t\t// check if in a cut or commercial break that should be automatically skipped\n//\t\tCheckAutoSceneSkip();\n#if 0\n\t\t// update the player info for streams\n\t\tif (m_player_status_timer.IsTimePast())\n\t\t{\n\t\t\tm_player_status_timer.Set(500);\n\t\t\tUpdateStreamInfos();\n\t\t}\n#endif\n\t}\n}\n\nvoid BasePlayer::CreatePlayers()\n{\n#ifdef HAS_OMXPLAYER\n\tbool omx_suitable = !OMXPlayerUnsuitable(m_HasVideo, m_HasAudio, m_pDemuxer, m_pInputStream, m_SelectionStreams);\n\tif (m_omxplayer_mode != omx_suitable)\n\t{\n\t\tDestroyPlayers();\n\t\tm_omxplayer_mode = omx_suitable;\n\t}\n#endif\n\tif (m_players_created)\n\t\treturn;\n\n#ifdef HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t{\n\t\tm_VideoPlayerVideo = new OMXPlayerVideo(&m_OmxPlayerState.av_clock, &m_overlayContainer, m_messenger, m_renderManager, *m_processInfo);\n\t\tm_VideoPlayerAudio = new OMXPlayerAudio(&m_OmxPlayerState.av_clock, m_messenger, *m_processInfo);\n\t} else\n#endif\n\t{\n\t\tm_VideoPlayerVideo = new CVideoPlayerVideo(&m_clock, /*&m_overlayContainer,*/ m_messenger, m_renderManager, *m_processInfo);\n\t\tm_VideoPlayerAudio = new CVideoPlayerAudio(&m_clock, m_messenger, *m_processInfo);\n\t}\n\t// \tm_VideoPlayerSubtitle = new CVideoPlayerSubtitle(&m_overlayContainer, *m_processInfo);\n\t// \tm_VideoPlayerTeletext = new CDVDTeletextData(*m_processInfo);\n\t// \tm_VideoPlayerRadioRDS = new CDVDRadioRDSData(*m_processInfo);\n\tm_players_created = true;\n}\n\nvoid BasePlayer::DestroyPlayers()\n{\n\tif (!m_players_created)\n\t\treturn;\n\n\tdelete m_VideoPlayerVideo;\n\tdelete m_VideoPlayerAudio;\n// \tdelete m_VideoPlayerSubtitle;\n// \tdelete m_VideoPlayerTeletext;\n// \tdelete m_VideoPlayerRadioRDS;\n\n\tm_players_created = false;\n}\n\nbool BasePlayer::OpenStream(CCurrentStream& current, int64_t demuxerId, int iStream, int source, bool reset /*= true*/)\n{\n\tCDemuxStream* stream = NULL;\n\tCDVDStreamInfo hint;\n\n//\tCLog::Log(LOGNOTICE, \"Opening stream: %i source: %i\", iStream, source);\n#if 0\n\tif (STREAM_SOURCE_MASK(source) == STREAM_SOURCE_DEMUX_SUB)\n\t{\n\t\tint index = m_SelectionStreams.IndexOf(current.type, source, demuxerId, iStream);\n\t\tif (index < 0)\n\t\t\treturn false;\n\t\tSelectionStream st = m_SelectionStreams.Get(current.type, index);\n\n\t\tif (!m_pSubtitleDemuxer || m_pSubtitleDemuxer->GetFileName() != st.filename)\n\t\t{\n\t\t\tCLog::Log(LOGNOTICE, \"Opening Subtitle file: %s\", st.filename.c_str());\n\t\t\tstd::unique_ptr<CDVDDemuxVobsub> demux(new CDVDDemuxVobsub());\n\t\t\tif (!demux->Open(st.filename, source, st.filename2))\n\t\t\t\treturn false;\n\t\t\tm_pSubtitleDemuxer = demux.release();\n\t\t}\n\n\t\tdouble pts = m_VideoPlayerVideo->GetCurrentPts();\n\t\tif (pts == DVD_NOPTS_VALUE)\n\t\t\tpts = m_CurrentVideo.dts;\n\t\tif (pts == DVD_NOPTS_VALUE)\n\t\t\tpts = 0;\n\t\tpts += m_offset_pts;\n\t\tif (!m_pSubtitleDemuxer->SeekTime((int)(1000.0 * pts / (double)DVD_TIME_BASE)))\n\t\t\tCLog::Log(LOGDEBUG, \"%s - failed to start subtitle demuxing from: %f\", __FUNCTION__, pts);\n\t\tstream = m_pSubtitleDemuxer->GetStream(demuxerId, iStream);\n\t\tif (!stream || stream->disabled)\n\t\t\treturn false;\n\n\t\tm_pSubtitleDemuxer->EnableStream(demuxerId, iStream, true);\n\n\t\thint.Assign(*stream, true);\n\t} else\n#endif\n\t\tif (STREAM_SOURCE_MASK(source) == STREAM_SOURCE_TEXT)\n\t{\n\t\tint index = m_SelectionStreams.IndexOf(current.type, source, demuxerId, iStream);\n\t\tif (index < 0)\n\t\t\treturn false;\n\n\t\thint.Clear();\n\t\thint.filename = m_SelectionStreams.Get(current.type, index).filename;\n\t\thint.fpsscale = m_CurrentVideo.hint.fpsscale;\n\t\thint.fpsrate = m_CurrentVideo.hint.fpsrate;\n\t} else if (STREAM_SOURCE_MASK(source) == STREAM_SOURCE_DEMUX)\n\t{\n\t\tif (!m_pDemuxer)\n\t\t\treturn false;\n\n\t\tstream = m_pDemuxer->GetStream(demuxerId, iStream);\n\t\tif (!stream || stream->disabled)\n\t\t\treturn false;\n\n\t\tm_pDemuxer->EnableStream(demuxerId, iStream, true);\n\n\t\thint.Assign(*stream, true);\n#if 0\n\t} else if (STREAM_SOURCE_MASK(source) == STREAM_SOURCE_VIDEOMUX)\n\t{\n\t\tif (!m_pCCDemuxer)\n\t\t\treturn false;\n\n\t\tstream = m_pCCDemuxer->GetStream(iStream);\n\t\tif (!stream || stream->disabled)\n\t\t\treturn false;\n\n\t\thint.Assign(*stream, false);\n#endif\n\t}\n\n\tbool res;\n\tswitch (current.type)\n\t{\n\tcase STREAM_AUDIO:\n\t\tres = OpenAudioStream(hint, reset);\n\t\tbreak;\n\tcase STREAM_VIDEO:\n\t\tres = OpenVideoStream(hint, reset);\n\t\tbreak;\n#if 0\n\tcase STREAM_SUBTITLE:\n\t\tres = OpenSubtitleStream(hint);\n\t\tbreak;\n\tcase STREAM_TELETEXT:\n\t\tres = OpenTeletextStream(hint);\n\t\tbreak;\n\tcase STREAM_RADIO_RDS:\n\t\tres = OpenRadioRDSStream(hint);\n\t\tbreak;\n#endif\n\tdefault:\n\t\tres = false;\n\t\tbreak;\n\t}\n\n\tif (res)\n\t{\n\t\tcurrent.id = iStream;\n\t\tcurrent.demuxerId = demuxerId;\n\t\tcurrent.source = source;\n\t\tcurrent.hint = hint;\n\t\tcurrent.stream = (void*)stream;\n\t\tcurrent.lastdts = DVD_NOPTS_VALUE;\n\t\tif (current.avsync != CCurrentStream::AV_SYNC_FORCE)\n\t\t\tcurrent.avsync = CCurrentStream::AV_SYNC_CHECK;\n\t\tif (stream)\n\t\t\tcurrent.changes = stream->changes;\n\t} else\n\t{\n\t\tif (stream)\n\t\t{\n\t\t\t/* mark stream as disabled, to disallaw further attempts*/\n//\t\t\tCLog::Log(LOGWARNING, \"%s - Unsupported stream %d. Stream disabled.\", __FUNCTION__, stream->uniqueId);\n\t\t\tstream->disabled = true;\n\t\t}\n\t}\n\n// \tCServiceBroker::GetDataCacheCore().SignalAudioInfoChange();\n// \tCServiceBroker::GetDataCacheCore().SignalVideoInfoChange();\n\n\treturn res;\n}\n\nbool BasePlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset)\n{\n\tIDVDStreamPlayer* player = GetStreamPlayer(m_CurrentAudio.player);\n\tif (player == nullptr)\n\t\treturn false;\n\n\tif (m_CurrentAudio.id < 0 ||\n\t\tm_CurrentAudio.hint != hint)\n\t{\n\t\tif (!player->OpenStream(hint))\n\t\t\treturn false;\n\n\t\tstatic_cast<IDVDStreamPlayerAudio*>(player)->SetSpeed(m_streamPlayerSpeed);\n\t\tm_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\tm_CurrentAudio.packets = 0;\n\t} else if (reset)\n\t\tplayer->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET), 0);\n\n\tm_HasAudio = true;\n\n\treturn true;\n}\n\nbool BasePlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset)\n{\n// \tif (hint.stereo_mode.empty())\n// \t\thint.stereo_mode = CStereoscopicsManager::GetInstance().DetectStereoModeByString(m_item.GetPath());\n\n\tSelectionStream& s = m_SelectionStreams.Get(STREAM_VIDEO, 0);\n\n// \tif (hint.flags & AV_DISPOSITION_ATTACHED_PIC)\n// \t\treturn false;\n\t\n\tIDVDStreamPlayer* player = GetStreamPlayer(m_CurrentVideo.player);\n\tif (player == nullptr)\n\t\treturn false;\n\n\tif (m_CurrentVideo.id < 0 ||\n\t\tm_CurrentVideo.hint != hint)\n\t{\n// \t\tif (hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_H264)\n// \t\t\tSAFE_DELETE(m_pCCDemuxer);\n\n\t\tif (!player->OpenStream(hint))\n\t\t\treturn false;\n\n\t\ts.stereo_mode = static_cast<IDVDStreamPlayerVideo*>(player)->GetStereoMode();\n\t\tif (s.stereo_mode == \"mono\")\n\t\t\ts.stereo_mode = \"\";\n\n\t\tstatic_cast<IDVDStreamPlayerVideo*>(player)->SetSpeed(m_streamPlayerSpeed);\n\t\tm_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\tm_CurrentVideo.packets = 0;\n\t} else if (reset)\n\t\tplayer->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET), 0);\n\n\tm_HasVideo = true;\n\n\t// open CC demuxer if video is mpeg2\n// \tif ((hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_H264) && !m_pCCDemuxer)\n// \t{\n// \t\tm_pCCDemuxer = new CDVDDemuxCC(hint.codec);\n// \t\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_VIDEOMUX);\n// \t}\n\n\treturn true;\n}\n\nbool BasePlayer::CloseStream(CCurrentStream& current, bool bWaitForBuffers)\n{\n\tif (current.id < 0)\n\t\treturn false;\n\n//\tCLog::Log(LOGNOTICE, \"Closing stream player %d\", current.player);\n\n\tif (bWaitForBuffers)\n\t\tSetCaching(CACHESTATE_DONE);\n\n\tif (m_pDemuxer && STREAM_SOURCE_MASK(current.source) == STREAM_SOURCE_DEMUX)\n\t\tm_pDemuxer->EnableStream(current.demuxerId, current.id, false);\n\n\tIDVDStreamPlayer* player = GetStreamPlayer(current.player);\n\tif (player)\n\t{\n\t\tif ((current.type == STREAM_AUDIO && current.syncState != IDVDStreamPlayer::SYNC_INSYNC) ||\n\t\t\t(current.type == STREAM_VIDEO && current.syncState != IDVDStreamPlayer::SYNC_INSYNC))\n\t\t\tbWaitForBuffers = false;\n\t\tplayer->CloseStream(bWaitForBuffers);\n\t}\n\n\tcurrent.Clear();\n\treturn true;\n}\n\nbool BasePlayer::CheckIsCurrent(CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg)\n{\n\tif (current.id == pkg->iStreamId\n\t\t&& current.demuxerId == stream->demuxerId\n\t\t&& current.source == stream->source\n\t\t&& current.type == stream->type)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nvoid BasePlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket)\n{\n\t// process packet if it belongs to selected stream.\n\t// for dvd's don't allow automatic opening of streams*/\n\n\tif (CheckIsCurrent(m_CurrentAudio, pStream, pPacket))\n\t\tProcessAudioData(pStream, pPacket);\n\telse if (CheckIsCurrent(m_CurrentVideo, pStream, pPacket))\n\t\tProcessVideoData(pStream, pPacket);\n// \telse if (CheckIsCurrent(m_CurrentSubtitle, pStream, pPacket))\n// \t\tProcessSubData(pStream, pPacket);\n// \telse if (CheckIsCurrent(m_CurrentTeletext, pStream, pPacket))\n// \t\tProcessTeletextData(pStream, pPacket);\n// \telse if (CheckIsCurrent(m_CurrentRadioRDS, pStream, pPacket))\n// \t\tProcessRadioRDSData(pStream, pPacket);\n\telse\n\t{\n\t\tDemuxPacket::Free(pPacket); // free it since we won't do anything with it\n\t}\n}\n\nvoid BasePlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)\n{\n\tCheckStreamChanges(m_CurrentAudio, pStream);\n\n\tbool checkcont = CheckContinuity(m_CurrentAudio, pPacket);\n\tUpdateTimestamps(m_CurrentAudio, pPacket);\n\n\tif (checkcont && (m_CurrentAudio.avsync == CCurrentStream::AV_SYNC_CHECK))\n\t\tm_CurrentAudio.avsync = CCurrentStream::AV_SYNC_NONE;\n\n\tbool drop = false;\n\tif (CheckPlayerInit(m_CurrentAudio))\n\t\tdrop = true;\n\t\n\tm_VideoPlayerAudio->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));\n\tm_CurrentAudio.packets++;\n}\n\nvoid BasePlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)\n{\n\tCheckStreamChanges(m_CurrentVideo, pStream);\n\tbool checkcont = false;\n\n\tif (pPacket->iSize != 4) //don't check the EOF_SEQUENCE of stillframes\n\t{\n\t\tcheckcont = CheckContinuity(m_CurrentVideo, pPacket);\n\t\tUpdateTimestamps(m_CurrentVideo, pPacket);\n\t}\n\tif (checkcont && (m_CurrentVideo.avsync == CCurrentStream::AV_SYNC_CHECK))\n\t\tm_CurrentVideo.avsync = CCurrentStream::AV_SYNC_NONE;\n\n\tbool drop = false;\n\tif (CheckPlayerInit(m_CurrentVideo))\n\t\tdrop = true;\n\n\tif (CheckSceneSkip(m_CurrentVideo))\n\t\tdrop = true;\n\n\tm_VideoPlayerVideo->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));\n\tm_CurrentVideo.packets++;\n}\n\nvoid BasePlayer::SetPlaySpeed(int speed)\n{\n\tif (IsPlaying())\n\t\tm_messenger.Put(new CDVDMsgInt(CDVDMsg::PLAYER_SETSPEED, speed));\n\telse\n\t{\n\t\tm_playSpeed = speed;\n\t\tm_newPlaySpeed = speed;\n\t\tm_streamPlayerSpeed = speed;\n\t}\n}\n\nvoid BasePlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync)\n{\n//\tCLog::Log(LOGDEBUG, \"CVideoPlayer::FlushBuffers - flushing buffers\");\n\n\tdouble startpts;\n\tif (accurate\n#ifdef HAS_OMXPLAYER\n\t\t&& !m_omxplayer_mode\n#endif\n\t\t)\n\t\tstartpts = pts;\n\telse\n\t\tstartpts = DVD_NOPTS_VALUE;\n\n\tif (sync)\n\t{\n\t\tm_CurrentAudio.inited = false;\n\t\tm_CurrentAudio.avsync = CCurrentStream::AV_SYNC_FORCE;\n\t\tm_CurrentVideo.inited = false;\n\t\tm_CurrentVideo.avsync = CCurrentStream::AV_SYNC_FORCE;\n// \t\tm_CurrentSubtitle.inited = false;\n// \t\tm_CurrentTeletext.inited = false;\n// \t\tm_CurrentRadioRDS.inited = false;\n\t}\n\n\tm_CurrentAudio.dts = DVD_NOPTS_VALUE;\n\tm_CurrentAudio.startpts = startpts;\n\tm_CurrentAudio.packets = 0;\n\n\tm_CurrentVideo.dts = DVD_NOPTS_VALUE;\n\tm_CurrentVideo.startpts = startpts;\n\tm_CurrentVideo.packets = 0;\n\n// \tm_CurrentSubtitle.dts = DVD_NOPTS_VALUE;\n// \tm_CurrentSubtitle.startpts = startpts;\n// \tm_CurrentSubtitle.packets = 0;\n// \n// \tm_CurrentTeletext.dts = DVD_NOPTS_VALUE;\n// \tm_CurrentTeletext.startpts = startpts;\n// \tm_CurrentTeletext.packets = 0;\n// \n// \tm_CurrentRadioRDS.dts = DVD_NOPTS_VALUE;\n// \tm_CurrentRadioRDS.startpts = startpts;\n// \tm_CurrentRadioRDS.packets = 0;\n\n\tif (queued)\n\t{\n\t\tm_VideoPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));\n\t\tm_VideoPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));\n// \t\tm_VideoPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));\n// \t\tm_VideoPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));\n// \t\tm_VideoPlayerRadioRDS->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));\n\n\t\tint sources = 0;\n\t\tif (m_VideoPlayerVideo->IsInited()) sources |= SYNCSOURCE_VIDEO;\n\t\tif (m_VideoPlayerAudio->IsInited()) sources |= SYNCSOURCE_AUDIO;\n\n\t\tCDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(10 * 1000, sources);\n\t\tm_VideoPlayerAudio->SendMessage(msg->AddRef(), 1);\n\t\tm_VideoPlayerVideo->SendMessage(msg->AddRef(), 1);\n\t\tmsg->Wait(m_bStop, 0);\n\t\tmsg->Release();\n\t} else\n\t{\n\t\tm_VideoPlayerAudio->Flush(sync);\n\t\tm_VideoPlayerVideo->Flush(sync);\n// \t\tm_VideoPlayerSubtitle->Flush();\n// \t\tm_VideoPlayerTeletext->Flush();\n// \t\tm_VideoPlayerRadioRDS->Flush();\n\n\t\t// clear subtitle and menu overlays\n\t//\tm_overlayContainer.Clear();\n\n\t\tif (m_playSpeed == DVD_PLAYSPEED_NORMAL\n\t\t\t|| m_playSpeed == DVD_PLAYSPEED_PAUSE)\n\t\t{\n\t\t\t// make sure players are properly flushed, should put them in stalled state\n\t\t\tint sources = 0;\n\t\t\tif (m_VideoPlayerVideo->IsInited()) sources |= SYNCSOURCE_VIDEO;\n\t\t\tif (m_VideoPlayerAudio->IsInited()) sources |= SYNCSOURCE_AUDIO;\n\t\t\tCDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, sources);\n\t\t\tm_VideoPlayerAudio->SendMessage(msg->AddRef(), 1);\n\t\t\tm_VideoPlayerVideo->SendMessage(msg->AddRef(), 1);\n\t\t\tmsg->Wait(m_bStop, 0);\n\t\t\tmsg->Release();\n\n\t\t\t// purge any pending PLAYER_STARTED messages\n\t\t\tm_messenger.Flush(CDVDMsg::PLAYER_STARTED);\n\n\t\t\t// we should now wait for init cache\n\t\t\tSetCaching(CACHESTATE_FLUSH);\n\t\t\tif (sync)\n\t\t\t{\n\t\t\t\tm_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\t\t\tm_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\t\t}\n\t\t}\n\n\t\tif (pts != DVD_NOPTS_VALUE && sync)\n\t\t\tm_clock.Discontinuity(pts);\n\t\tUpdatePlayState(0);\n\t}\n#ifdef HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t{\n\t\tm_OmxPlayerState.av_clock.OMXFlush();\n\t\tif (!queued)\n\t\t\tm_OmxPlayerState.av_clock.OMXStop();\n\t\tm_OmxPlayerState.av_clock.OMXPause();\n\t\tm_OmxPlayerState.av_clock.OMXMediaTime(0.0);\n\t}\n#endif\n}\n\nvoid BasePlayer::HandleMessages()\n{\n\tCDVDMsg* pMsg;\n\n\twhile (m_messenger.Get(&pMsg, 0) == MSGQ_OK)\n\t{\n\n\t\tif (pMsg->IsType(CDVDMsg::PLAYER_SEEK) &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK) == 0 &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK_CHAPTER) == 0)\n\t\t{\n\t\t\tCDVDMsgPlayerSeek &msg(*((CDVDMsgPlayerSeek*)pMsg));\n\n\t\t\tif (!m_State.canseek)\n\t\t\t{\n\t\t\t\tm_processInfo->SetStateSeeking(false);\n\t\t\t\tpMsg->Release();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// skip seeks if player has not finished the last seek\n\t\t\tif (m_CurrentVideo.id >= 0 &&\n\t\t\t\tm_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t{\n\t\t\t\tdouble now = m_clock.GetAbsoluteClock();\n\t\t\t\tif (m_playSpeed == DVD_PLAYSPEED_NORMAL &&\n\t\t\t\t\tDVD_TIME_TO_MSEC(now - m_State.lastSeek) < 2000 &&\n\t\t\t\t\t!msg.GetAccurate())\n\t\t\t\t{\n\t\t\t\t\tm_processInfo->SetStateSeeking(false);\n\t\t\t\t\tpMsg->Release();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!msg.GetTrickPlay())\n\t\t\t{\n//\t\t\t\tg_infoManager.SetDisplayAfterSeek(100000);\n\t\t\t\tif (msg.GetFlush())\n\t\t\t\t\tSetCaching(CACHESTATE_FLUSH);\n\t\t\t}\n\n\t\t\tdouble start = DVD_NOPTS_VALUE;\n\n\t\t\tint time = msg.GetTime();\n\t\t\tif (msg.GetRelative())\n\t\t\t\ttime = GetTime() + time;\n\n//\t\t\ttime = msg.GetRestore() ? m_Edl.RestoreCutTime(time) : time;\n\n\t\t\t// if input stream doesn't support ISeekTime, convert back to pts\n\t\t\t//! @todo\n\t\t\t//! After demuxer we add an offset to input pts so that displayed time and clock are\n\t\t\t//! increasing steadily. For seeking we need to determine the boundaries and offset\n\t\t\t//! of the desired segment. With the current approach calculated time may point\n\t\t\t//! to nirvana\n//\t\t\tif (m_pInputStream->GetIPosTime() == nullptr)\n\t\t\t\ttime -= DVD_TIME_TO_MSEC(m_State.time_offset);\n\n//\t\t\tCLog::Log(LOGDEBUG, \"demuxer seek to: %d\", time);\n\t\t\tif (m_pDemuxer && m_pDemuxer->SeekTime(time, msg.GetBackward(), &start)) {\n// \t\t\t\tCLog::Log(LOGDEBUG, \"demuxer seek to: %d, success\", time);\n// \t\t\t\tif (m_pSubtitleDemuxer)\n// \t\t\t\t{\n// \t\t\t\t\tif (!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward()))\n// \t\t\t\t\t\tCLog::Log(LOGDEBUG, \"failed to seek subtitle demuxer: %d, success\", time);\n// \t\t\t\t}\n\t\t\t\t// dts after successful seek\n\t\t\t\tif (start == DVD_NOPTS_VALUE)\n\t\t\t\t\tstart = DVD_MSEC_TO_TIME(time) - m_State.time_offset;\n\n\t\t\t\tm_State.dts = start;\n\t\t\t\tm_State.lastSeek = m_clock.GetAbsoluteClock();\n\n\t\t\t\tFlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync());\n\t\t\t} else if (m_pDemuxer) {\n//\t\t\t\tCLog::Log(LOGDEBUG, \"VideoPlayer: seek failed or hit end of stream\");\n\t\t\t\t// dts after successful seek\n\t\t\t\tif (start == DVD_NOPTS_VALUE)\n\t\t\t\t\tstart = DVD_MSEC_TO_TIME(time) - m_State.time_offset;\n\n\t\t\t\tm_State.dts = start;\n\n\t\t\t\tFlushBuffers(false, start, false, true);\n\t\t\t\tif (m_playSpeed != DVD_PLAYSPEED_PAUSE)\n\t\t\t\t{\n\t\t\t\t\tSetPlaySpeed(DVD_PLAYSPEED_NORMAL);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// set flag to indicate we have finished a seeking request\n// \t\t\tif (!msg.GetTrickPlay())\n// \t\t\t\tg_infoManager.SetDisplayAfterSeek();\n\n\t\t\t// dvd's will issue a HOP_CHANNEL that we need to skip\n// \t\t\tif (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))\n// \t\t\t\tm_dvd.state = DVDSTATE_SEEK;\n\n\t\t\tm_processInfo->SetStateSeeking(false);\n#if 0\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SEEK_CHAPTER) &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK) == 0 &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK_CHAPTER) == 0) {\n\t\t\tg_infoManager.SetDisplayAfterSeek(100000);\n\t\t\tSetCaching(CACHESTATE_FLUSH);\n\n\t\t\tCDVDMsgPlayerSeekChapter &msg(*((CDVDMsgPlayerSeekChapter*)pMsg));\n\t\t\tdouble start = DVD_NOPTS_VALUE;\n\t\t\tdouble offset = 0;\n\t\t\tint64_t beforeSeek = GetTime();\n\n\t\t\t// This should always be the case.\n\t\t\tif (m_pDemuxer && m_pDemuxer->SeekChapter(msg.GetChapter(), &start))\n\t\t\t{\n\t\t\t\tFlushBuffers(false, start, true);\n\t\t\t\toffset = DVD_TIME_TO_MSEC(start) - beforeSeek;\n\t\t\t\tm_callback.OnPlayBackSeekChapter(msg.GetChapter());\n\t\t\t}\n\n\t\t\tg_infoManager.SetDisplayAfterSeek(2500, offset);\n#endif\n\t\t} else if (pMsg->IsType(CDVDMsg::DEMUXER_RESET)) {\n\t\t\tm_CurrentAudio.stream = NULL;\n\t\t\tm_CurrentVideo.stream = NULL;\n//\t\t\tm_CurrentSubtitle.stream = NULL;\n\n\t\t\t// we need to reset the demuxer, probably because the streams have changed\n\t\t\tif (m_pDemuxer)\n\t\t\t\tm_pDemuxer->Reset();\n// \t\t\tif (m_pSubtitleDemuxer)\n// \t\t\t\tm_pSubtitleDemuxer->Reset();\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_AUDIOSTREAM)) {\n\t\t\tCDVDMsgPlayerSetAudioStream* pMsg2 = (CDVDMsgPlayerSetAudioStream*)pMsg;\n\n\t\t\tSelectionStream& st = m_SelectionStreams.Get(STREAM_AUDIO, pMsg2->GetStreamId());\n\t\t\tif (st.source != STREAM_SOURCE_NONE)\n\t\t\t{\n\t\t\t\t{\n\t\t\t\t\tCloseStream(m_CurrentAudio, false);\n\t\t\t\t\tOpenStream(m_CurrentAudio, st.demuxerId, st.id, st.source);\n//\t\t\t\t\tAdaptForcedSubtitles();\n\n\t\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\t\tmode.time = (int)GetTime();\n\t\t\t\t\tmode.backward = true;\n\t\t\t\t\tmode.flush = true;\n\t\t\t\t\tmode.accurate = true;\n\t\t\t\t\tmode.trickplay = true;\n\t\t\t\t\tmode.sync = true;\n\t\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_VIDEOSTREAM)){\n\t\t\tCDVDMsgPlayerSetVideoStream* pMsg2 = (CDVDMsgPlayerSetVideoStream*)pMsg;\n\n\t\t\tSelectionStream& st = m_SelectionStreams.Get(STREAM_VIDEO, pMsg2->GetStreamId());\n\t\t\tif (st.source != STREAM_SOURCE_NONE)\n\t\t\t{\n\t\t\t\t{\n\t\t\t\t\tCloseStream(m_CurrentVideo, false);\n\t\t\t\t\tOpenStream(m_CurrentVideo, st.demuxerId, st.id, st.source);\n\t\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\t\tmode.time = (int)GetTime();\n\t\t\t\t\tmode.backward = true;\n\t\t\t\t\tmode.flush = true;\n\t\t\t\t\tmode.accurate = true;\n\t\t\t\t\tmode.trickplay = true;\n\t\t\t\t\tmode.sync = true;\n\t\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t\t}\n\t\t\t}\n#if 0\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM)) {\n\t\t\tCDVDMsgPlayerSetSubtitleStream* pMsg2 = (CDVDMsgPlayerSetSubtitleStream*)pMsg;\n\n\t\t\tSelectionStream& st = m_SelectionStreams.Get(STREAM_SUBTITLE, pMsg2->GetStreamId());\n\t\t\tif (st.source != STREAM_SOURCE_NONE)\n\t\t\t{\n\t\t\t\tif (st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))\n\t\t\t\t{\n\t\t\t\t\tCDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;\n\t\t\t\t\tif (pStream->SetActiveSubtitleStream(st.id))\n\t\t\t\t\t{\n\t\t\t\t\t\tm_dvd.iSelectedSPUStream = -1;\n\t\t\t\t\t\tCloseStream(m_CurrentSubtitle, false);\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tCloseStream(m_CurrentSubtitle, false);\n\t\t\t\t\tOpenStream(m_CurrentSubtitle, st.demuxerId, st.id, st.source);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE))\n\t\t{\n\t\t\tCDVDMsgBool* pValue = (CDVDMsgBool*)pMsg;\n\t\t\tSetSubtitleVisibleInternal(pValue->m_value);\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_STATE)) {\n\t\t\tg_infoManager.SetDisplayAfterSeek(100000);\n\t\t\tSetCaching(CACHESTATE_FLUSH);\n\n\t\t\tCDVDMsgPlayerSetState* pMsgPlayerSetState = (CDVDMsgPlayerSetState*)pMsg;\n\n\t\t\tif (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))\n\t\t\t{\n\t\t\t\tif (ptr->SetState(pMsgPlayerSetState->GetState()))\n\t\t\t\t{\n\t\t\t\t\tm_dvd.state = DVDSTATE_NORMAL;\n\t\t\t\t\tm_dvd.iDVDStillStartTime = 0;\n\t\t\t\t\tm_dvd.iDVDStillTime = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tg_infoManager.SetDisplayAfterSeek();\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SET_RECORD))\n\t\t{\n\t\t\tCDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);\n\t\t\tif (input)\n\t\t\t\tinput->Record(*(CDVDMsgBool*)pMsg);\n#endif\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) {\n\t\t\tFlushBuffers(false);\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) {\n\t\t\tint speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;\n\n\t\t\t// correct our current clock, as it would start going wrong otherwise\n\t\t\tif (m_State.timestamp > 0)\n\t\t\t{\n\t\t\t\tdouble offset;\n\t\t\t\toffset = m_clock.GetAbsoluteClock() - m_State.timestamp;\n\t\t\t\toffset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;\n\t\t\t\toffset = DVD_TIME_TO_MSEC(offset);\n\t\t\t\tif (offset > 1000)\n\t\t\t\t\toffset = 1000;\n\t\t\t\tif (offset < -1000)\n\t\t\t\t\toffset = -1000;\n\t\t\t\tm_State.time += offset;\n\t\t\t\tm_State.timestamp = m_clock.GetAbsoluteClock();\n\t\t\t}\n\n\t\t\t// \t\t\tif (speed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_PAUSE && speed != m_playSpeed)\n\t\t\t// \t\t\t\tm_callback.OnPlayBackSpeedChanged(speed / DVD_PLAYSPEED_NORMAL);\n\n\t\t\t// notifiy GUI, skins may want to show the seekbar\n\t\t\t//\t\t\tg_infoManager.SetDisplayAfterSeek();\n\n\t\t\t// do a seek after rewind, clock is not in sync with current pts\n\t\t\tif ((speed == DVD_PLAYSPEED_NORMAL) &&\n\t\t\t\t(m_playSpeed != DVD_PLAYSPEED_NORMAL) &&\n\t\t\t\t(m_playSpeed != DVD_PLAYSPEED_PAUSE)\n\t\t\t\t/* && !m_omxplayer_mode*/)\n\t\t\t{\n\t\t\t\tint64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset);\n\t\t\t\tif (m_State.time != DVD_NOPTS_VALUE)\n\t\t\t\t\tiTime = m_State.time;\n\n\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\tmode.time = iTime;\n\t\t\t\tmode.backward = m_playSpeed < 0;\n\t\t\t\tmode.flush = true;\n\t\t\t\tmode.accurate = false;\n\t\t\t\tmode.trickplay = true;\n\t\t\t\tmode.sync = true;\n\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t}\n#ifdef HAS_OMXPLAYER\n\t\t\t// !!! omx alterative code path !!!\n\t\t\t// should be done differently\n\t\t\tif (m_omxplayer_mode)\n\t\t\t{\n\t\t\t\t// when switching from trickplay to normal, we may not have a full set of reference frames\n\t\t\t\t// in decoder and we may get corrupt frames out. Seeking to current time will avoid this.\n\t\t\t\tif ((speed != DVD_PLAYSPEED_PAUSE && speed != DVD_PLAYSPEED_NORMAL) ||\n\t\t\t\t\t(m_playSpeed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_NORMAL))\n\t\t\t\t{\n\t\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\t\tmode.time = (int)GetTime();\n\t\t\t\t\tmode.backward = (speed < 0);\n\t\t\t\t\tmode.flush = true;\n\t\t\t\t\tmode.accurate = true;\n\t\t\t\t\tmode.restore = false;\n\t\t\t\t\tmode.trickplay = true;\n\t\t\t\t\tmode.sync = true;\n\t\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tm_OmxPlayerState.av_clock.OMXPause();\n\t\t\t\t}\n\n\t\t\t\tm_OmxPlayerState.av_clock.OMXSetSpeed(speed);\n\t\t\t\tCLog::Log(LOGDEBUG, \"%s::%s CDVDMsg::PLAYER_SETSPEED speed : %d (%d)\", \"CVideoPlayer\", __FUNCTION__, speed, static_cast<int>(m_playSpeed));\n\t\t\t}\n#endif\n\t\t\tm_playSpeed = speed;\n\t\t\tm_newPlaySpeed = speed;\n\t\t\tm_caching = CACHESTATE_DONE;\n\t\t\tm_clock.SetSpeed(speed);\n\t\t\tm_VideoPlayerAudio->SetSpeed(speed);\n\t\t\tm_VideoPlayerVideo->SetSpeed(speed);\n\t\t\tm_streamPlayerSpeed = speed;\n\t\t\tif (m_pDemuxer)\n\t\t\t\tm_pDemuxer->SetSpeed(speed);\n#if 0\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) == 0)\n\t\t{\n\t\t\tFlushBuffers(false);\n\t\t\tCDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);\n\t\t\t//! @todo find a better solution for the \"otherStreaHack\"\n\t\t\t//! a stream is not sopposed to be terminated before demuxer\n\t\t\tif (input && input->IsOtherStreamHack())\n\t\t\t{\n\t\t\t\tCloseDemuxer();\n\t\t\t}\n\t\t\tif (input && input->SelectChannelByNumber(static_cast<CDVDMsgInt*>(pMsg)->m_value))\n\t\t\t{\n\t\t\t\tCloseDemuxer();\n\t\t\t\tm_playSpeed = DVD_PLAYSPEED_NORMAL;\n\n\t\t\t\t// when using fast channel switching some shortcuts are taken which\n\t\t\t\t// means we'll have to update the view mode manually\n\t\t\t\tm_renderManager.SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tCLog::Log(LOGWARNING, \"%s - failed to switch channel. playback stopped\", __FUNCTION__);\n\t\t\t\tCApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_STOP);\n\t\t\t}\n\t\t\tShowPVRChannelInfo();\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT) &&\n\t\t\tm_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT) == 0)\n\t\t{\n\t\t\tFlushBuffers(false);\n\t\t\tCDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);\n\t\t\tif (input && input->IsOtherStreamHack())\n\t\t\t{\n\t\t\t\tCloseDemuxer();\n\t\t\t}\n\t\t\tif (input && input->SelectChannel(static_cast<CDVDMsgType <CPVRChannelPtr> *>(pMsg)->m_value))\n\t\t\t{\n\t\t\t\tCloseDemuxer();\n\t\t\t\tm_playSpeed = DVD_PLAYSPEED_NORMAL;\n\t\t\t} else\n\t\t\t{\n\t\t\t\tCLog::Log(LOGWARNING, \"%s - failed to switch channel. playback stopped\", __FUNCTION__);\n\t\t\t\tCApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_STOP);\n\t\t\t}\n\t\t\tg_PVRManager.SetChannelPreview(false);\n\t\t\tShowPVRChannelInfo();\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_NEXT) || pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREV) ||\n\t\t\tpMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_NEXT) || pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_PREV))\n\t\t{\n\t\t\tCDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);\n\t\t\tif (input)\n\t\t\t{\n\t\t\t\tbool bSwitchSuccessful(false);\n\t\t\t\tbool bShowPreview(pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_NEXT) ||\n\t\t\t\t\tpMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_PREV) ||\n\t\t\t\t\tCSettings::GetInstance().GetInt(CSettings::SETTING_PVRPLAYBACK_CHANNELENTRYTIMEOUT) > 0);\n\n\t\t\t\tif (!bShowPreview)\n\t\t\t\t{\n\t\t\t\t\tg_infoManager.SetDisplayAfterSeek(100000);\n\t\t\t\t\tFlushBuffers(false);\n\t\t\t\t\tif (input->IsOtherStreamHack())\n\t\t\t\t\t{\n\t\t\t\t\t\tCloseDemuxer();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_NEXT) || pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_NEXT))\n\t\t\t\t\tbSwitchSuccessful = input->NextChannel(bShowPreview);\n\t\t\t\telse\n\t\t\t\t\tbSwitchSuccessful = input->PrevChannel(bShowPreview);\n\n\t\t\t\tif (bSwitchSuccessful)\n\t\t\t\t{\n\t\t\t\t\tif (bShowPreview)\n\t\t\t\t\t{\n\t\t\t\t\t\tUpdateApplication(0);\n\n\t\t\t\t\t\tif (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_NEXT) || pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREVIEW_PREV))\n\t\t\t\t\t\t\tm_ChannelEntryTimeOut.SetInfinite();\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tm_ChannelEntryTimeOut.Set(CSettings::GetInstance().GetInt(CSettings::SETTING_PVRPLAYBACK_CHANNELENTRYTIMEOUT));\n\t\t\t\t\t} else\n\t\t\t\t\t{\n\t\t\t\t\t\tm_ChannelEntryTimeOut.SetInfinite();\n\t\t\t\t\t\tCloseDemuxer();\n\t\t\t\t\t\tm_playSpeed = DVD_PLAYSPEED_NORMAL;\n\n\t\t\t\t\t\tg_infoManager.SetDisplayAfterSeek();\n\t\t\t\t\t\tg_PVRManager.SetChannelPreview(false);\n\n\t\t\t\t\t\t// when using fast channel switching some shortcuts are taken which\n\t\t\t\t\t\t// means we'll have to update the view mode manually\n\t\t\t\t\t\tm_renderManager.SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode);\n\t\t\t\t\t}\n\t\t\t\t\tShowPVRChannelInfo();\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tCLog::Log(LOGWARNING, \"%s - failed to switch channel. playback stopped\", __FUNCTION__);\n\t\t\t\t\tCApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_STOP);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_GUI_ACTION))\n\t\t\tOnAction(((CDVDMsgType<CAction>*)pMsg)->m_value);\n#endif\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) {\n\t\t\tSStartMsg& msg = ((CDVDMsgType<SStartMsg>*)pMsg)->m_value;\n\t\t\tif (msg.player == VideoPlayer_AUDIO)\n\t\t\t{\n\t\t\t\tm_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_WAITSYNC;\n\t\t\t\tm_CurrentAudio.cachetime = msg.cachetime;\n\t\t\t\tm_CurrentAudio.cachetotal = msg.cachetotal;\n\t\t\t\tm_CurrentAudio.starttime = msg.timestamp;\n\t\t\t}\n\t\t\tif (msg.player == VideoPlayer_VIDEO)\n\t\t\t{\n\t\t\t\tm_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_WAITSYNC;\n\t\t\t\tm_CurrentVideo.cachetime = msg.cachetime;\n\t\t\t\tm_CurrentVideo.cachetotal = msg.cachetotal;\n\t\t\t\tm_CurrentVideo.starttime = msg.timestamp;\n\t\t\t}\n//\t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayer::HandleMessages - player started %d\", msg.player);\n#if 0\n\t\t} else if (pMsg->IsType(CDVDMsg::SUBTITLE_ADDFILE))\n\t\t{\n\t\t\tint id = AddSubtitleFile(((CDVDMsgType<std::string>*) pMsg)->m_value);\n\t\t\tif (id >= 0)\n\t\t\t{\n\t\t\t\tSetSubtitle(id);\n\t\t\t\tSetSubtitleVisibleInternal(true);\n\t\t\t}\n#endif\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) {\n\t\t\t((CDVDMsgGeneralSynchronize*)pMsg)->Wait(100, SYNCSOURCE_PLAYER);\n// \t\t\tif ()\n// \t\t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayer - CDVDMsg::GENERAL_SYNCHRONIZE\");\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_AVCHANGE)) {\n\t\t\tUpdateStreamInfos();\n// \t\t\tCServiceBroker::GetDataCacheCore().SignalAudioInfoChange();\n// \t\t\tCServiceBroker::GetDataCacheCore().SignalVideoInfoChange();\n\t\t}\n\n\t\tpMsg->Release();\n\t}\n}\n\nvoid BasePlayer::SetCaching(ECacheState state)\n{\n\tif (state == CACHESTATE_FLUSH)\n\t{\n\t\tdouble level, delay, offset;\n\t\tif (GetCachingTimes(level, delay, offset))\n\t\t\tstate = CACHESTATE_FULL;\n\t\telse\n\t\t\tstate = CACHESTATE_INIT;\n\t}\n\n\tif (m_caching == state)\n\t\treturn;\n\n//\tCLog::Log(LOGDEBUG, \"CVideoPlayer::SetCaching - caching state %d\", state);\n\tif (state == CACHESTATE_FULL ||\n\t\tstate == CACHESTATE_INIT)\n\t{\n\t\tm_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);\n#ifdef HAS_OMXPLAYER\n\t\tif (m_omxplayer_mode)\n\t\t\tm_OmxPlayerState.av_clock.OMXPause();\n#endif\n\t\tm_VideoPlayerAudio->SetSpeed(DVD_PLAYSPEED_PAUSE);\n\t\tm_VideoPlayerVideo->SetSpeed(DVD_PLAYSPEED_PAUSE);\n\t\tm_streamPlayerSpeed = DVD_PLAYSPEED_PAUSE;\n\n//\t\tm_pInputStream->ResetScanTimeout((unsigned int)CSettings::GetInstance().GetInt(CSettings::SETTING_PVRPLAYBACK_SCANTIME) * 1000);\n\n\t\tm_cachingTimer.Set(5000);\n\t}\n\n\tif (state == CACHESTATE_PLAY ||\n\t\t(state == CACHESTATE_DONE && m_caching != CACHESTATE_PLAY))\n\t{\n\t\tm_clock.SetSpeed(m_playSpeed);\n\t\tm_VideoPlayerAudio->SetSpeed(m_playSpeed);\n\t\tm_VideoPlayerVideo->SetSpeed(m_playSpeed);\n\t\tm_streamPlayerSpeed = m_playSpeed;\n//\t\tm_pInputStream->ResetScanTimeout(0);\n\t}\n\tm_caching = state;\n\n\tm_clock.SetSpeedAdjust(0);\n#ifdef HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t\tm_OmxPlayerState.av_clock.OMXSetSpeedAdjust(0);\n#endif\n}\n\ndouble BasePlayer::GetQueueTime()\n{\n\tint a = m_VideoPlayerAudio->GetLevel();\n\tint v = m_VideoPlayerVideo->GetLevel();\n\treturn std::max(a, v) * 8000.0 / 100;\n}\n\nbool BasePlayer::GetCachingTimes(double& level, double& delay, double& offset)\n{\n\treturn false;\n#if 0\n\tif (!m_pInputStream || !m_pDemuxer)\n\t\treturn false;\n\n\tSCacheStatus status;\n\tif (!m_pInputStream->GetCacheStatus(&status))\n\t\treturn false;\n\n\tuint64_t &cached = status.forward;\n\tunsigned &currate = status.currate;\n\tunsigned &maxrate = status.maxrate;\n\tfloat &cache_level = status.level;\n\n\tint64_t length = m_pInputStream->GetLength();\n\tint64_t remain = length - m_pInputStream->Seek(0, SEEK_CUR);\n\n\tif (length <= 0 || remain < 0)\n\t\treturn false;\n\n\tdouble play_sbp = DVD_MSEC_TO_TIME(m_pDemuxer->GetStreamLength()) / length;\n\tdouble queued = 1000.0 * GetQueueTime() / play_sbp;\n\n\tdelay = 0.0;\n\tlevel = 0.0;\n\toffset = (double)(cached + queued) / length;\n\n\tif (currate == 0)\n\t\treturn true;\n\n\tdouble cache_sbp = 1.1 * (double)DVD_TIME_BASE / currate;          /* underestimate by 10 % */\n\tdouble play_left = play_sbp  * (remain + queued);                  /* time to play out all remaining bytes */\n\tdouble cache_left = cache_sbp * (remain - cached);                 /* time to cache the remaining bytes */\n\tdouble cache_need = std::max(0.0, remain - play_left / cache_sbp); /* bytes needed until play_left == cache_left */\n\n\tdelay = cache_left - play_left;\n\n\t/* NOTE: We can only reliably test for low readrate, when the cache is not\n\t* already *near* full. This is because as soon as it's full the average-\n\t* rate will become approximately the current-rate which can flag false\n\t* low read-rate conditions. To work around this we don't check the currate at 100%\n\t* but between 80% and 90%\n\t*/\n\tif (cache_level > 0.8 && cache_level < 0.9 && currate < maxrate)\n\t{\n//\t\tCLog::Log(LOGDEBUG, \"Readrate %u is too low with %u required\", currate, maxrate);\n\t\tlevel = -1.0;                          /* buffer is full & our read rate is too low  */\n\t} else\n\t\tlevel = (cached + queued) / (cache_need + queued);\n\n\treturn true;\n#endif\n}\n\nvoid BasePlayer::SetSpeed(double speed)\n{\n\tif (!CanSeek())\n\t\treturn;\n\n\tm_newPlaySpeed = speed * DVD_PLAYSPEED_NORMAL;\n\tSetPlaySpeed(speed * DVD_PLAYSPEED_NORMAL);\n}\n\ndouble BasePlayer::GetSpeed()\n{\n\tif (m_playSpeed != m_newPlaySpeed)\n\t\treturn (double)m_newPlaySpeed / DVD_PLAYSPEED_NORMAL;\n\n\treturn (double)m_playSpeed / DVD_PLAYSPEED_NORMAL;\n}\n\nvoid BasePlayer::SeekTime(int64_t iTime)\n{\n\tint seekOffset = (int)(iTime - GetTime());\n\n\tCDVDMsgPlayerSeek::CMode mode;\n\tmode.time = (int)iTime;\n\tmode.backward = true;\n\tmode.flush = true;\n\tmode.accurate = true;\n\tmode.trickplay = false;\n\tmode.sync = true;\n\n\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\tSynchronizeDemuxer();\n\tOnPlayBackSeek((int)iTime, seekOffset);\n}\n\n// return the time in milliseconds\nint64_t BasePlayer::GetTime()\n{\n#if 0 // TODO delay tunning ?\n\tif (m_VideoPlayerAudio) {\n\t\tCDVDAudio *audioDev = m_VideoPlayerAudio->GetOutputDevice();\n\t\tif (audioDev && audioDev->m_pAudioStream) {\n\t\t\tiTVPSoundBuffer *alsound = audioDev->m_pAudioStream->GetNativeImpl();\n\t\t\tint remainSamples = alsound->GetUnprocessedSamples();\n// \t\t\tdouble audio_clk = is->audio_clock - (double)remainSamples / is->audio_tgt.freq;\n// \t\t\tset_clock_at(&is->audclk, audio_clk, is->audio_clock_serial, av_gettime() / 1000000.0);\n// \t\t\tsync_clock_to_slave(&is->extclk, &is->audclk);\n\t\t}\n\t}\n#endif\n\tCSingleLock lock(m_StateSection);\n\tdouble offset = 0;\n\tconst double limit = DVD_MSEC_TO_TIME(500);\n\tif (m_State.timestamp > 0)\n\t{\n\t\toffset = m_clock.GetAbsoluteClock() - m_State.timestamp;\n\t\toffset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;\n\t\tif (offset > limit)\n\t\t\toffset = limit;\n\t\tif (offset < -limit)\n\t\t\toffset = -limit;\n\t}\n\treturn llrint(m_State.time + DVD_TIME_TO_MSEC(offset));\n}\n\nint BasePlayer::GetCurrentFrame()\n{\n\t// TODO accuracy\n\treturn GetTime() * GetFPS() / DVD_PLAYSPEED_NORMAL;\n}\n\nint BasePlayer::GetVideoStream()\n{\n\treturn m_SelectionStreams.IndexOf(STREAM_VIDEO, m_CurrentVideo.source, m_CurrentVideo.demuxerId, m_CurrentVideo.id);\n}\n\nint BasePlayer::GetVideoStreamCount()\n{\n\treturn m_SelectionStreams.Count(STREAM_VIDEO);\n}\n\nint BasePlayer::GetAudioStreamCount()\n{\n\treturn m_SelectionStreams.Count(STREAM_AUDIO);\n}\n\nint BasePlayer::GetAudioStream()\n{\n\treturn m_SelectionStreams.IndexOf(STREAM_AUDIO, m_CurrentAudio.source, m_CurrentAudio.demuxerId, m_CurrentAudio.id);\n}\n\nvoid BasePlayer::HandlePlaySpeed()\n{\n// \tbool isInMenu = IsInMenuInternal();\n// \n// \tif (isInMenu && m_caching != CACHESTATE_DONE)\n// \t\tSetCaching(CACHESTATE_DONE);\n\n\tif (m_caching == CACHESTATE_FULL)\n\t{\n\t\tdouble level, delay, offset;\n\t\tif (GetCachingTimes(level, delay, offset))\n\t\t{\n\t\t\tif (level < 0.0)\n\t\t\t{\n\t\t\t//\tCGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(21454), g_localizeStrings.Get(21455));\n\t\t\t\tSetCaching(CACHESTATE_INIT);\n\t\t\t}\n\t\t\tif (level >= 1.0)\n\t\t\t\tSetCaching(CACHESTATE_INIT);\n\t\t} else\n\t\t{\n\t\t\tif ((!m_VideoPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||\n\t\t\t\t(!m_VideoPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))\n\t\t\t\tSetCaching(CACHESTATE_INIT);\n\t\t}\n\t}\n\n\tif (m_caching == CACHESTATE_INIT)\n\t{\n\t\t// if all enabled streams have been inited we are done\n\t\tif ((m_CurrentVideo.id >= 0 || m_CurrentAudio.id >= 0) &&\n\t\t\t(m_CurrentVideo.id < 0 || m_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_STARTING) &&\n\t\t\t(m_CurrentAudio.id < 0 || m_CurrentAudio.syncState != IDVDStreamPlayer::SYNC_STARTING))\n\t\t\tSetCaching(CACHESTATE_PLAY);\n\n\t\t// handle exceptions\n\t\tif (m_CurrentAudio.id >= 0 && m_CurrentVideo.id >= 0)\n\t\t{\n\t\t\tif ((!m_VideoPlayerAudio->AcceptsData() || !m_VideoPlayerVideo->AcceptsData()) &&\n\t\t\t\tm_cachingTimer.IsTimePast())\n\t\t\t{\n\t\t\t\tSetCaching(CACHESTATE_DONE);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (m_caching == CACHESTATE_PLAY)\n\t{\n\t\t// if all enabled streams have started playing we are done\n\t\tif ((m_CurrentVideo.id < 0 || !m_VideoPlayerVideo->IsStalled()) &&\n\t\t\t(m_CurrentAudio.id < 0 || !m_VideoPlayerAudio->IsStalled()))\n\t\t\tSetCaching(CACHESTATE_DONE);\n\t}\n\n\tif (m_caching == CACHESTATE_DONE)\n\t{\n\t\tif (m_playSpeed == DVD_PLAYSPEED_NORMAL /*&& !isInMenu*/)\n\t\t{\n\t\t\t// take action is audio or video stream is stalled\n\t\t\tif (((m_VideoPlayerAudio->IsStalled() && m_CurrentAudio.inited) ||\n\t\t\t\t(m_VideoPlayerVideo->IsStalled() && m_CurrentVideo.inited)) &&\n\t\t\t\tm_syncTimer.IsTimePast())\n\t\t\t{\n// \t\t\t\tif (m_pInputStream->IsRealtime())\n// \t\t\t\t{\n// \t\t\t\t\tif ((m_CurrentAudio.id >= 0 && m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_INSYNC && m_VideoPlayerAudio->IsStalled()) ||\n// \t\t\t\t\t\t(m_CurrentVideo.id >= 0 && m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_INSYNC && m_VideoPlayerVideo->GetLevel() == 0))\n// \t\t\t\t\t{\n// \t\t\t\t\t\tCLog::Log(LOGDEBUG, \"Stream stalled, start buffering. Audio: %d - Video: %d\",\n// \t\t\t\t\t\t\tm_VideoPlayerAudio->GetLevel(), m_VideoPlayerVideo->GetLevel());\n// \t\t\t\t\t\tFlushBuffers(false);\n// \t\t\t\t\t}\n// \t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\t// start caching if audio and video have run dry\n\t\t\t\t\tif (m_VideoPlayerAudio->GetLevel() <= 50 &&\n\t\t\t\t\t\tm_VideoPlayerVideo->GetLevel() <= 50)\n\t\t\t\t\t{\n\t\t\t\t\t\tSetCaching(CACHESTATE_FULL);\n\t\t\t\t\t} else if (m_CurrentAudio.id >= 0 && m_CurrentAudio.inited &&\n\t\t\t\t\t\tm_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_INSYNC &&\n\t\t\t\t\t\tm_VideoPlayerAudio->GetLevel() == 0)\n\t\t\t\t\t{\n\t\t\t\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayer::HandlePlaySpeed - audio stream stalled, triggering re-sync\");\n\t\t\t\t\t\tFlushBuffers(false);\n\t\t\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\t\t\tmode.time = (int)GetTime();\n\t\t\t\t\t\tmode.backward = false;\n\t\t\t\t\t\tmode.flush = true;\n\t\t\t\t\t\tmode.accurate = true;\n\t\t\t\t\t\tmode.sync = true;\n\t\t\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// care for live streams\n// \t\t\telse if (m_pInputStream->IsRealtime())\n// \t\t\t{\n// \t\t\t\tif (m_CurrentAudio.id >= 0)\n// \t\t\t\t{\n// \t\t\t\t\tdouble adjust = -1.0; // a unique value\n// \t\t\t\t\tif (m_clock.GetSpeedAdjust() >= 0 && m_VideoPlayerAudio->GetLevel() < 5)\n// \t\t\t\t\t\tadjust = -0.05;\n// \n// \t\t\t\t\tif (m_clock.GetSpeedAdjust() < 0 && m_VideoPlayerAudio->GetLevel() > 10)\n// \t\t\t\t\t\tadjust = 0.0;\n// \n// \t\t\t\t\tif (adjust != -1.0)\n// \t\t\t\t\t{\n// \t\t\t\t\t\tm_clock.SetSpeedAdjust(adjust);\n// \t\t\t\t\t\tif (m_omxplayer_mode)\n// \t\t\t\t\t\t\tm_OmxPlayerState.av_clock.OMXSetSpeedAdjust(adjust);\n// \t\t\t\t\t}\n// \t\t\t\t}\n// \t\t\t}\n\t\t}\n\t}\n\n\t// sync streams to clock\n\tif ((m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_WAITSYNC) ||\n\t\t(m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC))\n\t{\n\t\tunsigned int threshold = 20;\n// \t\tif (m_pInputStream->IsRealtime())\n// \t\t\tthreshold = 40;\n\n\t\tbool video = m_CurrentVideo.id < 0 || (m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_WAITSYNC) ||\n\t\t\t(m_CurrentVideo.packets == 0 && m_CurrentAudio.packets > threshold);\n\t\tbool audio = m_CurrentAudio.id < 0 || (m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC) ||\n\t\t\t(m_CurrentAudio.packets == 0 && m_CurrentVideo.packets > threshold);\n\n\t\tif (m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC &&\n\t\t\tm_CurrentAudio.avsync == CCurrentStream::AV_SYNC_CONT)\n\t\t{\n\t\t\tm_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_CurrentAudio.avsync = CCurrentStream::AV_SYNC_NONE;\n\t\t\tm_VideoPlayerAudio->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, m_clock.GetClock()), 1);\n\t\t} else if (m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_WAITSYNC &&\n\t\t\tm_CurrentVideo.avsync == CCurrentStream::AV_SYNC_CONT)\n\t\t{\n\t\t\tm_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_CurrentVideo.avsync = CCurrentStream::AV_SYNC_NONE;\n\t\t\tm_VideoPlayerVideo->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, m_clock.GetClock()), 1);\n\t\t} else if (video && audio)\n\t\t{\n\t\t\tdouble clock = 0;\n// \t\t\tif (m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC)\n// \t\t\t\tCLog::Log(LOGDEBUG, \"VideoPlayer::Sync - Audio - pts: %f, cache: %f, totalcache: %f\",\n// \t\t\t\tm_CurrentAudio.starttime, m_CurrentAudio.cachetime, m_CurrentAudio.cachetotal);\n// \t\t\tif (m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_WAITSYNC)\n// \t\t\t\tCLog::Log(LOGDEBUG, \"VideoPlayer::Sync - Video - pts: %f, cache: %f, totalcache: %f\",\n// \t\t\t\tm_CurrentVideo.starttime, m_CurrentVideo.cachetime, m_CurrentVideo.cachetotal);\n\n\t\t\tif (m_CurrentVideo.starttime != DVD_NOPTS_VALUE && m_CurrentVideo.packets > 0 &&\n\t\t\t\tm_playSpeed == DVD_PLAYSPEED_PAUSE)\n\t\t\t{\n\t\t\t\tclock = m_CurrentVideo.starttime;\n\t\t\t} else if (m_CurrentAudio.starttime != DVD_NOPTS_VALUE && m_CurrentAudio.packets > 0)\n\t\t\t{\n// \t\t\t\tif (m_pInputStream->IsRealtime())\n// \t\t\t\t\tclock = m_CurrentAudio.starttime - m_CurrentAudio.cachetotal - DVD_MSEC_TO_TIME(400);\n// \t\t\t\telse\n\t\t\t\t\tclock = m_CurrentAudio.starttime - m_CurrentAudio.cachetime;\n\t\t\t\tif (m_CurrentVideo.starttime != DVD_NOPTS_VALUE &&\n\t\t\t\t\t(m_CurrentVideo.packets > 0) &&\n\t\t\t\t\tm_CurrentVideo.starttime - m_CurrentVideo.cachetotal < clock)\n\t\t\t\t{\n\t\t\t\t\tclock = m_CurrentVideo.starttime - m_CurrentVideo.cachetotal;\n\t\t\t\t}\n\t\t\t} else if (m_CurrentVideo.starttime != DVD_NOPTS_VALUE && m_CurrentVideo.packets > 0)\n\t\t\t{\n\t\t\t\tclock = m_CurrentVideo.starttime - m_CurrentVideo.cachetotal;\n\t\t\t}\n#ifdef HAS_OMXPLAYER\n\t\t\tif (m_omxplayer_mode)\n\t\t\t{\n\t\t\t\tCLog::Log(LOGDEBUG, \"%s::%s player started RESET\", \"CVideoPlayer\", __FUNCTION__);\n\t\t\t\tm_OmxPlayerState.av_clock.OMXReset(m_CurrentVideo.id >= 0, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false : (m_CurrentAudio.id >= 0));\n\t\t\t}\n#endif\n\t\t\tm_clock.Discontinuity(clock);\n\t\t\tm_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_CurrentAudio.avsync = CCurrentStream::AV_SYNC_NONE;\n\t\t\tm_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_CurrentVideo.avsync = CCurrentStream::AV_SYNC_NONE;\n\t\t\tm_VideoPlayerAudio->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1);\n\t\t\tm_VideoPlayerVideo->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1);\n\t\t\tSetCaching(CACHESTATE_DONE);\n\n\t\t\tm_syncTimer.Set(3000);\n\t\t} else\n\t\t{\n\t\t\t// exceptions for which stream players won't start properly\n\t\t\t// 1. videoplayer has not detected a keyframe within lenght of demux buffers\n\t\t\tif (m_CurrentAudio.id >= 0 && m_CurrentVideo.id >= 0 &&\n\t\t\t\t!m_VideoPlayerAudio->AcceptsData() &&\n\t\t\t\tm_VideoPlayerVideo->IsStalled())\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGWARNING, \"VideoPlayer::Sync - stream player video does not start, flushing buffers\");\n\t\t\t\tFlushBuffers(false);\n\t\t\t}\n\t\t}\n\t}\n\n\t// handle ff/rw\n\tif (m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE)\n\t{\n// \t\tif (isInMenu)\n// \t\t{\n// \t\t\t// this can't be done in menu\n// \t\t\tSetPlaySpeed(DVD_PLAYSPEED_NORMAL);\n// \n// \t\t} else\n\t\t{\n\t\t\tbool check = true;\n\n\t\t\t// only check if we have video\n\t\t\tif (m_CurrentVideo.id < 0 || m_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t\tcheck = false;\n\t\t\t// video message queue either initiated or already seen eof\n\t\t\telse if (m_CurrentVideo.inited == false && m_playSpeed >= 0)\n\t\t\t\tcheck = false;\n\t\t\t// don't check if time has not advanced since last check\n\t\t\telse if (m_SpeedState.lasttime == GetTime())\n\t\t\t\tcheck = false;\n\t\t\t// skip if frame at screen has no valid timestamp\n\t\t\telse if (m_VideoPlayerVideo->GetCurrentPts() == DVD_NOPTS_VALUE)\n\t\t\t\tcheck = false;\n\t\t\t// skip if frame on screen has not changed\n\t\t\telse if (m_SpeedState.lastpts == m_VideoPlayerVideo->GetCurrentPts() &&\n\t\t\t\t(m_SpeedState.lastpts > m_State.dts || m_playSpeed > 0))\n\t\t\t\tcheck = false;\n\n\t\t\tif (check)\n\t\t\t{\n\t\t\t\tm_SpeedState.lastpts = m_VideoPlayerVideo->GetCurrentPts();\n\t\t\t\tm_SpeedState.lasttime = GetTime();\n\t\t\t\tm_SpeedState.lastabstime = m_clock.GetAbsoluteClock();\n\t\t\t\t// check how much off clock video is when ff/rw:ing\n\t\t\t\t// a problem here is that seeking isn't very accurate\n\t\t\t\t// and since the clock will be resynced after seek\n\t\t\t\t// we might actually not really be playing at the wanted\n\t\t\t\t// speed. we'd need to have some way to not resync the clock\n\t\t\t\t// after a seek to remember timing. still need to handle\n\t\t\t\t// discontinuities somehow\n\n\t\t\t\tdouble error;\n\t\t\t\terror = m_clock.GetClock() - m_SpeedState.lastpts;\n\t\t\t\terror *= m_playSpeed / abs(m_playSpeed);\n\n\t\t\t\t// allow a bigger error when going ff, the faster we go\n\t\t\t\t// the the bigger is the error we allow\n\t\t\t\tif (m_playSpeed > DVD_PLAYSPEED_NORMAL)\n\t\t\t\t{\n\t\t\t\t\tint errorwin = m_playSpeed / DVD_PLAYSPEED_NORMAL;\n\t\t\t\t\tif (errorwin > 8)\n\t\t\t\t\t\terrorwin = 8;\n\t\t\t\t\terror /= errorwin;\n\t\t\t\t}\n\n\t\t\t\tif (error > DVD_MSEC_TO_TIME(1000))\n\t\t\t\t{\n\t\t\t\t\terror = (int)DVD_TIME_TO_MSEC(m_clock.GetClock()) - m_SpeedState.lastseekpts;\n\n\t\t\t\t\tif (std::abs(error) > 1000 || (m_VideoPlayerVideo->IsRewindStalled() && std::abs(error) > 100))\n\t\t\t\t\t{\n\t\t\t\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayer::Process - Seeking to catch up, error was: %f\", error);\n\t\t\t\t\t\tm_SpeedState.lastseekpts = (int)DVD_TIME_TO_MSEC(m_clock.GetClock());\n\t\t\t\t\t\tint direction = (m_playSpeed > 0) ? 1 : -1;\n\t\t\t\t\t\tint iTime = DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 1000000.0 * direction);\n\t\t\t\t\t\tCDVDMsgPlayerSeek::CMode mode;\n\t\t\t\t\t\tmode.time = iTime;\n\t\t\t\t\t\tmode.backward = (GetPlaySpeed() < 0);\n\t\t\t\t\t\tmode.flush = true;\n\t\t\t\t\t\tmode.accurate = false;\n\t\t\t\t\t\tmode.restore = false;\n\t\t\t\t\t\tmode.trickplay = true;\n\t\t\t\t\t\tmode.sync = false;\n\t\t\t\t\t\tm_messenger.Put(new CDVDMsgPlayerSeek(mode));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid BasePlayer::SynchronizeDemuxer()\n{\n\tif (IsCurrentThread())\n\t\treturn;\n\tif (!m_messenger.IsInited())\n\t\treturn;\n\n\tCDVDMsgGeneralSynchronize* message = new CDVDMsgGeneralSynchronize(500, SYNCSOURCE_PLAYER);\n\tm_messenger.Put(message->AddRef());\n\tmessage->Wait(m_bStop, 0);\n\tmessage->Release();\n}\n\nstatic void UpdateLimits(double& minimum, double& maximum, double dts)\n{\n\tif (dts == DVD_NOPTS_VALUE)\n\t\treturn;\n\tif (minimum == DVD_NOPTS_VALUE || minimum > dts) minimum = dts;\n\tif (maximum == DVD_NOPTS_VALUE || maximum < dts) maximum = dts;\n}\n\nbool BasePlayer::CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket)\n{\n\tif (m_playSpeed < DVD_PLAYSPEED_PAUSE)\n\t\treturn false;\n\n\tif (pPacket->dts == DVD_NOPTS_VALUE || current.dts == DVD_NOPTS_VALUE)\n\t\treturn false;\n\n\tdouble mindts = DVD_NOPTS_VALUE, maxdts = DVD_NOPTS_VALUE;\n\tUpdateLimits(mindts, maxdts, m_CurrentAudio.dts);\n\tUpdateLimits(mindts, maxdts, m_CurrentVideo.dts);\n\tUpdateLimits(mindts, maxdts, m_CurrentAudio.dts_end());\n\tUpdateLimits(mindts, maxdts, m_CurrentVideo.dts_end());\n\n\t/* if we don't have max and min, we can't do anything more */\n\tif (mindts == DVD_NOPTS_VALUE || maxdts == DVD_NOPTS_VALUE)\n\t\treturn false;\n\n\tdouble correction = 0.0;\n\tif (pPacket->dts > maxdts + DVD_MSEC_TO_TIME(1000))\n\t{\n// \t\tCLog::Log(LOGDEBUG, \"CVideoPlayer::CheckContinuity - resync forward :%d, prev:%f, curr:%f, diff:%f\"\n// \t\t\t, current.type, current.dts, pPacket->dts, pPacket->dts - maxdts);\n\t\tcorrection = pPacket->dts - maxdts;\n\t}\n\n\t/* if it's large scale jump, correct for it after having confirmed the jump */\n\tif (pPacket->dts + DVD_MSEC_TO_TIME(500) < current.dts_end())\n\t{\n// \t\tCLog::Log(LOGDEBUG, \"CVideoPlayer::CheckContinuity - resync backward :%d, prev:%f, curr:%f, diff:%f\"\n// \t\t\t, current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);\n\t\tcorrection = pPacket->dts - current.dts_end();\n\t} else if (pPacket->dts < current.dts)\n\t{\n// \t\tCLog::Log(LOGDEBUG, \"CVideoPlayer::CheckContinuity - wrapback :%d, prev:%f, curr:%f, diff:%f\"\n// \t\t\t, current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);\n\t}\n\n\tdouble lastdts = pPacket->dts;\n\tif (correction != 0.0)\n\t{\n\t\t// we want the dts values of two streams to close, or for one to be invalid (e.g. from a missing audio stream)\n\t\tdouble this_dts = pPacket->dts;\n\t\tdouble that_dts = current.type == STREAM_AUDIO ? m_CurrentVideo.lastdts : m_CurrentAudio.lastdts;\n\n\t\tif (m_CurrentAudio.id == -1 || m_CurrentVideo.id == -1 ||\n\t\t\tcurrent.lastdts == DVD_NOPTS_VALUE ||\n\t\t\tfabs(this_dts - that_dts) < DVD_MSEC_TO_TIME(1000))\n\t\t{\n\t\t\tm_offset_pts += correction;\n\t\t\tUpdateCorrection(pPacket, correction);\n\t\t\tlastdts = pPacket->dts;\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayer::CheckContinuity - update correction: %f\", correction);\n\t\t} else\n\t\t{\n\t\t\t// not sure yet - flags the packets as unknown until we get confirmation on another audio/video packet\n\t\t\tpPacket->dts = DVD_NOPTS_VALUE;\n\t\t\tpPacket->pts = DVD_NOPTS_VALUE;\n\t\t}\n\t} else\n\t{\n\t\tif (current.avsync == CCurrentStream::AV_SYNC_CHECK)\n\t\t\tcurrent.avsync = CCurrentStream::AV_SYNC_CONT;\n\t}\n\tcurrent.lastdts = lastdts;\n\treturn true;\n}\n\n\nbool BasePlayer::CheckSceneSkip(CCurrentStream& current)\n{\n\treturn false;\n#if 0\n\tif (!m_Edl.HasCut())\n\t\treturn false;\n\n\tif (current.dts == DVD_NOPTS_VALUE)\n\t\treturn false;\n\n\tif (current.inited == false)\n\t\treturn false;\n\n\tCEdl::Cut cut;\n\treturn m_Edl.InCut(DVD_TIME_TO_MSEC(current.dts + m_offset_pts), &cut) && cut.action == CEdl::CUT;\n#endif\n}\n\nbool BasePlayer::CheckPlayerInit(CCurrentStream& current)\n{\n\tif (current.inited)\n\t\treturn false;\n\n\tif (current.startpts != DVD_NOPTS_VALUE)\n\t{\n\t\tif (current.dts == DVD_NOPTS_VALUE)\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"%s - dropping packet type:%d dts:%f to get to start point at %f\", __FUNCTION__, current.player, current.dts, current.startpts);\n\t\t\treturn true;\n\t\t}\n\n\t\tif ((current.startpts - current.dts) > DVD_SEC_TO_TIME(20))\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"%s - too far to decode before finishing seek\", __FUNCTION__);\n\t\t\tif (m_CurrentAudio.startpts != DVD_NOPTS_VALUE)\n\t\t\t\tm_CurrentAudio.startpts = current.dts;\n\t\t\tif (m_CurrentVideo.startpts != DVD_NOPTS_VALUE)\n\t\t\t\tm_CurrentVideo.startpts = current.dts;\n// \t\t\tif (m_CurrentSubtitle.startpts != DVD_NOPTS_VALUE)\n// \t\t\t\tm_CurrentSubtitle.startpts = current.dts;\n// \t\t\tif (m_CurrentTeletext.startpts != DVD_NOPTS_VALUE)\n// \t\t\t\tm_CurrentTeletext.startpts = current.dts;\n// \t\t\tif (m_CurrentRadioRDS.startpts != DVD_NOPTS_VALUE)\n// \t\t\t\tm_CurrentRadioRDS.startpts = current.dts;\n\t\t}\n\n\t\tif (current.dts < current.startpts)\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"%s - dropping packet type:%d dts:%f to get to start point at %f\", __FUNCTION__, current.player, current.dts, current.startpts);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (current.dts != DVD_NOPTS_VALUE)\n\t{\n\t\tcurrent.inited = true;\n\t\tcurrent.startpts = current.dts;\n\t}\n\treturn false;\n}\n\nvoid BasePlayer::UpdateCorrection(DemuxPacket* pkt, double correction)\n{\n\tif (pkt->dts != DVD_NOPTS_VALUE)\n\t\tpkt->dts -= correction;\n\tif(pkt->pts != DVD_NOPTS_VALUE)\n\t\tpkt->pts -= correction;\n}\n\nvoid BasePlayer::UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket)\n{\n\tdouble dts = current.dts;\n\t/* update stored values */\n\tif (pPacket->dts != DVD_NOPTS_VALUE)\n\t\tdts = pPacket->dts;\n\telse if (pPacket->pts != DVD_NOPTS_VALUE)\n\t\tdts = pPacket->pts;\n\n\t/* calculate some average duration */\n\tif (pPacket->duration != DVD_NOPTS_VALUE)\n\t\tcurrent.dur = pPacket->duration;\n\telse if (dts != DVD_NOPTS_VALUE && current.dts != DVD_NOPTS_VALUE)\n\t\tcurrent.dur = 0.1 * (current.dur * 9 + (dts - current.dts));\n\n\tcurrent.dts = dts;\n\n\tcurrent.dispTime = pPacket->dispTime;\n}\n\nIDVDStreamPlayer* BasePlayer::GetStreamPlayer(unsigned int target)\n{\n\tif (target == VideoPlayer_AUDIO)\n\t\treturn m_VideoPlayerAudio;\n\tif (target == VideoPlayer_VIDEO)\n\t\treturn m_VideoPlayerVideo;\n// \tif (target == VideoPlayer_SUBTITLE)\n// \t\treturn m_VideoPlayerSubtitle;\n// \tif (target == VideoPlayer_TELETEXT)\n// \t\treturn m_VideoPlayerTeletext;\n// \tif (target == VideoPlayer_RDS)\n// \t\treturn m_VideoPlayerRadioRDS;\n\treturn NULL;\n}\n\nvoid BasePlayer::SendPlayerMessage(CDVDMsg* pMsg, unsigned int target)\n{\n\tIDVDStreamPlayer* player = GetStreamPlayer(target);\n\tif(player)\n\t\tplayer->SendMessage(pMsg, 0);\n}\n\nbool BasePlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)\n{\n\t// check if we should read from subtitle demuxer\n#if 0\n\tif (m_pSubtitleDemuxer && m_VideoPlayerSubtitle->AcceptsData())\n\t{\n\t\tpacket = m_pSubtitleDemuxer->Read();\n\n\t\tif (packet)\n\t\t{\n\t\t\tUpdateCorrection(packet, m_offset_pts);\n\t\t\tif (packet->iStreamId < 0)\n\t\t\t\treturn true;\n\n\t\t\tstream = m_pSubtitleDemuxer->GetStream(packet->demuxerId, packet->iStreamId);\n\t\t\tif (!stream)\n\t\t\t{\n\t\t\t\tCLog::Log(LOGERROR, \"%s - Error demux packet doesn't belong to a valid stream\", __FUNCTION__);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (stream->source == STREAM_SOURCE_NONE)\n\t\t\t{\n\t\t\t\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX_SUB);\n\t\t\t\tm_SelectionStreams.Update(NULL, m_pSubtitleDemuxer);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n#endif\n#ifdef HAS_OMXPLAYER\n\tif (m_omxplayer_mode)\n\t{\n\t\t// reset eos state when we get a packet (e.g. for case of seek after eos)\n\t\tif (packet && stream)\n\t\t{\n\t\t\tm_OmxPlayerState.bOmxWaitVideo = false;\n\t\t\tm_OmxPlayerState.bOmxWaitAudio = false;\n\t\t\tm_OmxPlayerState.bOmxSentEOFs = false;\n\t\t}\n\t}\n#endif\n\t// read a data frame from stream.\n\tif (m_pDemuxer)\n\t\tpacket = m_pDemuxer->Read();\n\n\tif (packet)\n\t{\n\t\t// stream changed, update and open defaults\n\t\tif (packet->iStreamId == DMX_SPECIALID_STREAMCHANGE)\n\t\t{\n\t\t\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);\n\t\t\tm_SelectionStreams.Update(m_pInputStream, m_pDemuxer);\n\t\t\tOpenDefaultStreams(false);\n\n\t\t\t// reevaluate HasVideo/Audio, we may have switched from/to a radio channel\n\t\t\tif (m_CurrentVideo.id < 0)\n\t\t\t\tm_HasVideo = false;\n\t\t\tif (m_CurrentAudio.id < 0)\n\t\t\t\tm_HasAudio = false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tUpdateCorrection(packet, m_offset_pts);\n\n\t\tif (packet->iStreamId < 0)\n\t\t\treturn true;\n\n\t\tif (m_pDemuxer)\n\t\t{\n\t\t\tstream = m_pDemuxer->GetStream(packet->demuxerId, packet->iStreamId);\n\t\t\tif (!stream)\n\t\t\t{\n//\t\t\t\tCLog::Log(LOGERROR, \"%s - Error demux packet doesn't belong to a valid stream\", __FUNCTION__);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (stream->source == STREAM_SOURCE_NONE)\n\t\t\t{\n\t\t\t\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);\n\t\t\t\tm_SelectionStreams.Update(m_pInputStream, m_pDemuxer);\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nvoid BasePlayer::OpenInputStream(IStream *stream, const std::string& filename)\n{\n\tSAFE_RELEASE(m_pInputStream);\n// \tif (m_pInputStream)\n// \t\tdelete m_pInputStream;\n\n//\tCLog::Log(LOGNOTICE, \"Creating InputStream\");\n\n\t// correct the filename if needed\n//\tstd::string filename(m_item.GetPath());\n\n\tm_pInputStream = new InputStream(stream, filename);\n\t\n//\tSetAVDelay(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_AudioDelay);\n//\tSetSubTitleDelay(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleDelay);\n\tm_clock.Reset();\n//\tm_dvd.Clear();\n\tm_errorCount = 0;\n\tm_ChannelEntryTimeOut.SetInfinite();\n}\n\nbool BasePlayer::OpenDemuxStream()\n{\n\tCloseDemuxer();\n\n//\tCLog::Log(LOGNOTICE, \"Creating Demuxer\");\n\n//\tm_pDemuxer = DemuxerFactory::CreateDemuxer(m_pInputStream);\n\tCDVDDemuxFFmpeg *demuxer = new CDVDDemuxFFmpeg;\n\tdemuxer->Open(m_pInputStream);\n\tm_pDemuxer = demuxer;\n\n// \tif (!m_pDemuxer)\n// \t{\n//\t\tCLog::Log(LOGERROR, \"%s - Error creating demuxer\", __FUNCTION__);\n// \t\treturn false;\n// \t}\n\n\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);\n//\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NAV);\n\tm_SelectionStreams.Update(m_pInputStream, m_pDemuxer);\n\n// \tSTATSTG strstat;\n// \tm_pInputStream->Stat(&strstat, STATFLAG_NONAME);\n// \n// \tint64_t len = strstat.cbSize.QuadPart;\n// \tint64_t tim = m_pDemuxer->GetStreamLength();\n// \tif (len > 0 && tim > 0)\n// \t\tm_pInputStream->SetReadRate((unsigned int)(len * 1000 / tim));\n\n\tm_offset_pts = 0;\n\n\treturn true;\n}\n\nvoid BasePlayer::CloseDemuxer()\n{\n\tdelete m_pDemuxer;\n\tm_pDemuxer = nullptr;\n\tm_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);\n\n//\tCServiceBroker::GetDataCacheCore().SignalAudioInfoChange();\n//\tCServiceBroker::GetDataCacheCore().SignalVideoInfoChange();\n}\n\nstatic int GetCodecPriority(const std::string &codec)\n{\n\t/*\n\t* Technically flac, truehd, and dtshd_ma are equivalently good as they're all lossless. However,\n\t* ffmpeg can't decode dtshd_ma losslessy yet.\n\t*/\n\tif (codec == \"flac\") // Lossless FLAC\n\t\treturn 7;\n\tif (codec == \"truehd\") // Dolby TrueHD\n\t\treturn 6;\n\tif (codec == \"dtshd_ma\") // DTS-HD Master Audio (previously known as DTS++)\n\t\treturn 5;\n\tif (codec == \"dtshd_hra\") // DTS-HD High Resolution Audio\n\t\treturn 4;\n\tif (codec == \"eac3\") // Dolby Digital Plus\n\t\treturn 3;\n\tif (codec == \"dca\") // DTS\n\t\treturn 2;\n\tif (codec == \"ac3\") // Dolby Digital\n\t\treturn 1;\n\treturn 0;\n}\n\n#define PREDICATE_RETURN(lh, rh) \\\n  do { \\\n    if((lh) != (rh)) \\\n      return (lh) > (rh); \\\n  } while(0)\n\nstatic bool PredicateAudioPriority(const SelectionStream& lh, const SelectionStream& rh)\n{\n// \tPREDICATE_RETURN(lh.type_index == CMediaSettings::GetInstance().GetCurrentVideoSettings().m_AudioStream\n// \t\t, rh.type_index == CMediaSettings::GetInstance().GetCurrentVideoSettings().m_AudioStream);\n\n// \tif (!StringUtils::EqualsNoCase(CSettings::GetInstance().GetString(CSettings::SETTING_LOCALE_AUDIOLANGUAGE), \"original\"))\n// \t{\n// \t\tstd::string audio_language = g_langInfo.GetAudioLanguage();\n// \t\tPREDICATE_RETURN(g_LangCodeExpander.CompareISO639Codes(audio_language, lh.language)\n// \t\t\t, g_LangCodeExpander.CompareISO639Codes(audio_language, rh.language));\n// \n// \t\tbool hearingimp = CSettings::GetInstance().GetBool(CSettings::SETTING_ACCESSIBILITY_AUDIOHEARING);\n// \t\tPREDICATE_RETURN(!hearingimp ? !(lh.flags & CDemuxStream::FLAG_HEARING_IMPAIRED) : lh.flags & CDemuxStream::FLAG_HEARING_IMPAIRED\n// \t\t\t, !hearingimp ? !(rh.flags & CDemuxStream::FLAG_HEARING_IMPAIRED) : rh.flags & CDemuxStream::FLAG_HEARING_IMPAIRED);\n// \n// \t\tbool visualimp = CSettings::GetInstance().GetBool(CSettings::SETTING_ACCESSIBILITY_AUDIOVISUAL);\n// \t\tPREDICATE_RETURN(!visualimp ? !(lh.flags & CDemuxStream::FLAG_VISUAL_IMPAIRED) : lh.flags & CDemuxStream::FLAG_VISUAL_IMPAIRED\n// \t\t\t, !visualimp ? !(rh.flags & CDemuxStream::FLAG_VISUAL_IMPAIRED) : rh.flags & CDemuxStream::FLAG_VISUAL_IMPAIRED);\n// \t}\n\n// \tif (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_PREFERDEFAULTFLAG))\n// \t{\n// \t\tPREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT\n// \t\t\t, rh.flags & CDemuxStream::FLAG_DEFAULT);\n// \t}\n\n\tPREDICATE_RETURN(lh.channels\n\t\t, rh.channels);\n\n\tPREDICATE_RETURN(GetCodecPriority(lh.codec)\n\t\t, GetCodecPriority(rh.codec));\n\n\tPREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT\n\t\t, rh.flags & CDemuxStream::FLAG_DEFAULT);\n\n\treturn false;\n}\n\nstatic bool PredicateVideoPriority(const SelectionStream& lh, const SelectionStream& rh)\n{\n// \tPREDICATE_RETURN(lh.type_index == CMediaSettings::GetInstance().GetCurrentVideoSettings().m_VideoStream\n// \t\t, rh.type_index == CMediaSettings::GetInstance().GetCurrentVideoSettings().m_VideoStream);\n\n\tPREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT\n\t\t, rh.flags & CDemuxStream::FLAG_DEFAULT);\n\treturn false;\n}\n\nvoid BasePlayer::OpenDefaultStreams(bool reset)\n{\n\tbool valid;\n\n\t// open video stream\n\tvalid = false;\n\n\tfor (const auto &stream : m_SelectionStreams.Get(STREAM_VIDEO, PredicateVideoPriority))\n\t{\n\t\tif (OpenStream(m_CurrentVideo, stream.demuxerId, stream.id, stream.source, reset))\n\t\t{\n\t\t\tvalid = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!valid)\n\t{\n\t\tCloseStream(m_CurrentVideo, true);\n\t\tm_processInfo->ResetVideoCodecInfo();\n\t}\n\n\t// open audio stream\n\tvalid = false;\n//\tif (!m_PlayerOptions.video_only)\n\t{\n\t\tfor (const auto &stream : m_SelectionStreams.Get(STREAM_AUDIO, PredicateAudioPriority))\n\t\t{\n\t\t\tif (OpenStream(m_CurrentAudio, stream.demuxerId, stream.id, stream.source, reset))\n\t\t\t{\n\t\t\t\tvalid = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!valid)\n\t{\n\t\tCloseStream(m_CurrentAudio, true);\n\t\tm_processInfo->ResetAudioCodecInfo();\n\t}\n#if 0\n\t// enable  or disable subtitles\n\tbool visible = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleOn;\n\n\t// open subtitle stream\n\tSelectionStream as = m_SelectionStreams.Get(STREAM_AUDIO, GetAudioStream());\n\tPredicateSubtitlePriority psp(as.language);\n\tvalid = false;\n\tCloseStream(m_CurrentSubtitle, false);\n\tfor (const auto &stream : m_SelectionStreams.Get(STREAM_SUBTITLE, psp))\n\t{\n\t\tif (OpenStream(m_CurrentSubtitle, stream.demuxerId, stream.id, stream.source))\n\t\t{\n\t\t\tvalid = true;\n\t\t\tif (!psp.relevant(stream))\n\t\t\t\tvisible = false;\n\t\t\telse if (stream.flags & CDemuxStream::FLAG_FORCED)\n\t\t\t\tvisible = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!valid)\n\t\tCloseStream(m_CurrentSubtitle, false);\n\n\tif (!dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream) || m_PlayerOptions.state.empty())\n\t\tSetSubtitleVisibleInternal(visible); // only set subtitle visibility if state not stored by dvd navigator, because navigator will restore it (if visible)\n\n\t// open teletext stream\n\tvalid = false;\n\tfor (const auto &stream : m_SelectionStreams.Get(STREAM_TELETEXT))\n\t{\n\t\tif (OpenStream(m_CurrentTeletext, stream.demuxerId, stream.id, stream.source))\n\t\t{\n\t\t\tvalid = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!valid)\n\t\tCloseStream(m_CurrentTeletext, false);\n\n\t// open RDS stream\n\tvalid = false;\n\tfor (const auto &stream : m_SelectionStreams.Get(STREAM_RADIO_RDS))\n\t{\n\t\tif (OpenStream(m_CurrentRadioRDS, stream.demuxerId, stream.id, stream.source))\n\t\t{\n\t\t\tvalid = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!valid)\n\t\tCloseStream(m_CurrentRadioRDS, false);\n\n\t// disable demux streams\n\tif (m_item.IsRemote() && m_pDemuxer)\n\t{\n\t\tfor (auto &stream : m_SelectionStreams.m_Streams)\n\t\t{\n\t\t\tif (STREAM_SOURCE_MASK(stream.source) == STREAM_SOURCE_DEMUX)\n\t\t\t{\n\t\t\t\tif (stream.id != m_CurrentVideo.id &&\n\t\t\t\t\tstream.id != m_CurrentAudio.id &&\n\t\t\t\t\tstream.id != m_CurrentSubtitle.id &&\n\t\t\t\t\tstream.id != m_CurrentTeletext.id &&\n\t\t\t\t\tstream.id != m_CurrentRadioRDS.id)\n\t\t\t\t{\n\t\t\t\t\tm_pDemuxer->EnableStream(stream.demuxerId, stream.id, false);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n\nvoid BasePlayer::UpdatePlayState(double timeout)\n{\n\tif (m_State.timestamp != 0 &&\n\t\tm_State.timestamp + DVD_MSEC_TO_TIME(timeout) > m_clock.GetAbsoluteClock())\n\t\treturn;\n\n\tSPlayerState state(m_State);\n\n\tstate.dts = DVD_NOPTS_VALUE;\n\tif (m_CurrentVideo.dts != DVD_NOPTS_VALUE)\n\t\tstate.dts = m_CurrentVideo.dts;\n\telse if (m_CurrentAudio.dts != DVD_NOPTS_VALUE)\n\t\tstate.dts = m_CurrentAudio.dts;\n\telse if (m_CurrentVideo.startpts != DVD_NOPTS_VALUE)\n\t\tstate.dts = m_CurrentVideo.startpts;\n\telse if (m_CurrentAudio.startpts != DVD_NOPTS_VALUE)\n\t\tstate.dts = m_CurrentAudio.startpts;\n\n\tif (m_pDemuxer)\n\t{\n// \t\tif (IsInMenuInternal())\n// \t\t\tstate.chapter = 0;\n// \t\telse\n// \t\t\tstate.chapter = m_pDemuxer->GetChapter();\n\n//\t\tstate.chapters.clear();\n//\t\tif (m_pDemuxer->GetChapterCount() > 0)\n// \t\t{\n// \t\t\tfor (int i = 0; i < m_pDemuxer->GetChapterCount(); ++i)\n// \t\t\t{\n// \t\t\t\tstd::string name;\n// \t\t\t\tm_pDemuxer->GetChapterName(name, i + 1);\n// \t\t\t\tstate.chapters.push_back(make_pair(name, m_pDemuxer->GetChapterPos(i + 1)));\n// \t\t\t}\n// \t\t}\n\n\t\tstate.time = DVD_TIME_TO_MSEC(m_clock.GetClock(false));\n\t\tstate.time_total = m_pDemuxer->GetStreamLength();\n\t}\n\n\tstate.canpause = true;\n\tstate.canseek = true;\n\tstate.isInMenu = false;\n\tstate.hasMenu = false;\n\n\tif (m_pInputStream)\n\t{\n\t\t// override from input stream if needed\n\n// \t\tCDVDInputStream::IDisplayTime* pDisplayTime = m_pInputStream->GetIDisplayTime();\n// \t\tif (pDisplayTime && pDisplayTime->GetTotalTime() > 0)\n// \t\t{\n// \t\t\tif (state.dts != DVD_NOPTS_VALUE)\n// \t\t\t{\n// \t\t\t\tint dispTime = 0;\n// \t\t\t\tif (m_CurrentVideo.dispTime)\n// \t\t\t\t\tdispTime = m_CurrentVideo.dispTime;\n// \t\t\t\telse if (m_CurrentAudio.dispTime)\n// \t\t\t\t\tdispTime = m_CurrentAudio.dispTime;\n// \n// \t\t\t\tstate.time_offset = DVD_MSEC_TO_TIME(dispTime) - state.dts;\n// \t\t\t}\n// \t\t\tstate.time += DVD_TIME_TO_MSEC(state.time_offset);\n// \t\t\tstate.time_total = pDisplayTime->GetTotalTime();\n// \t\t} else\n\t\t{\n\t\t\tstate.time_offset = 0;\n\t\t}\n\t\t\n\t\tstate.canpause = true;\n\t\tstate.canseek = true;\n\t}\n\n\tif (state.time_total <= 0)\n\t\tstate.canseek = false;\n\n\tif (m_caching > CACHESTATE_DONE && m_caching < CACHESTATE_PLAY)\n\t\tstate.caching = true;\n\telse\n\t\tstate.caching = false;\n\n\tdouble level, delay, offset;\n\tif (GetCachingTimes(level, delay, offset))\n\t{\n\t\tstate.cache_delay = std::max(0.0, delay);\n\t\tstate.cache_level = std::max(0.0, std::min(1.0, level));\n\t\tstate.cache_offset = offset;\n\t} else\n\t{\n\t\tstate.cache_delay = 0.0;\n\t\tstate.cache_level = std::min(1.0, GetQueueTime() / 8000.0);\n\t\tstate.cache_offset = GetQueueTime() / state.time_total;\n\t}\n#if 0\n\tSCacheStatus status;\n\tif (m_pInputStream && m_pInputStream->GetCacheStatus(&status))\n\t{\n\t\tstate.cache_bytes = status.forward;\n\t\tif (state.time_total)\n\t\t\tstate.cache_bytes += m_pInputStream->GetLength() * (int64_t)(GetQueueTime() / state.time_total);\n\t} else\n#endif\n\t\tstate.cache_bytes = 0;\n\n\tstate.timestamp = m_clock.GetAbsoluteClock();\n\n\tCSingleLock lock(m_StateSection);\n\tm_State = state;\n}\n\nvoid BasePlayer::UpdateStreamInfos()\n{\n\tif (!m_pDemuxer)\n\t\treturn;\n\n\tstd::lock_guard<std::recursive_mutex> lock(m_SelectionStreams.m_section);\n\tint streamId;\n\tstd::string retVal;\n\n\t// video\n\tstreamId = GetVideoStream();\n\n\tif (streamId >= 0 && streamId < GetVideoStreamCount())\n\t{\n\t\tSelectionStream& s = m_SelectionStreams.Get(STREAM_VIDEO, streamId);\n\t\ts.bitrate = m_VideoPlayerVideo->GetVideoBitrate();\n\t\ts.aspect_ratio = m_renderManager.GetAspectRatio();\n\t\tCRect viewRect;\n\t\tm_renderManager.GetVideoRect(s.SrcRect, s.DestRect, viewRect);\n\t\tCDemuxStream* stream = m_pDemuxer->GetStream(m_CurrentVideo.demuxerId, m_CurrentVideo.id);\n\t\tif (stream && stream->type == STREAM_VIDEO)\n\t\t{\n\t\t\t{\n\t\t\t\ts.width = static_cast<CDemuxStreamVideo*>(stream)->iWidth;\n\t\t\t\ts.height = static_cast<CDemuxStreamVideo*>(stream)->iHeight;\n\t\t\t}\n\t\t\ts.stereo_mode = m_VideoPlayerVideo->GetStereoMode();\n\t\t\tif (s.stereo_mode == \"mono\")\n\t\t\t\ts.stereo_mode = \"\";\n\t\t}\n\t}\n\n\t// audio\n\tstreamId = GetAudioStream();\n\n\tif (streamId >= 0 && streamId < GetAudioStreamCount())\n\t{\n\t\tSelectionStream& s = m_SelectionStreams.Get(STREAM_AUDIO, streamId);\n\t\ts.bitrate = m_VideoPlayerAudio->GetAudioBitrate();\n\t\ts.channels = m_VideoPlayerAudio->GetAudioChannels();\n\n\t\tCDemuxStream* stream = m_pDemuxer->GetStream(m_CurrentAudio.demuxerId, m_CurrentAudio.id);\n\t\tif (stream && stream->type == STREAM_AUDIO)\n\t\t{\n\t\t\ts.codec = m_pDemuxer->GetStreamCodecName(stream->demuxerId, stream->uniqueId);\n\t\t}\n\t}\n}\n\nNS_KRMOVIE_END\n"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayer.h",
    "content": "#pragma once\n#include \"Clock.h\"\n#include \"Thread.h\"\n#include \"StreamInfo.h\"\n#include \"Demux.h\"\n#include \"Timer.h\"\n#include \"Geometry.h\"\n#include \"MessageQueue.h\"\n#include \"ProcessInfo.h\"\n#include \"IVideoPlayer.h\"\n#include <mutex>\n#include <vector>\n#include <memory>\n#include \"VideoRenderer.h\"\n\n#ifdef ANDROID\n//#define HAS_OMXPLAYER 1\n#endif\n#ifdef HAS_OMXPLAYER\n#include \"../omxplayer/OMXCore.h\"\n#include \"../omxplayer/OMXClock.h\"\n#else\n\n// dummy class to avoid ifdefs where calls are made\nclass OMXClock\n{\npublic:\n\tbool OMXInitialize(KRMovie::CDVDClock *clock) { return false; }\n\tvoid OMXDeinitialize() {}\n\tbool OMXIsPaused() { return false; }\n\tbool OMXStop(bool lock = true) { return false; }\n\tbool OMXStep(int steps = 1, bool lock = true) { return false; }\n\tbool OMXReset(bool has_video, bool has_audio, bool lock = true) { return false; }\n\tdouble OMXMediaTime(bool lock = true) { return 0.0; }\n\tdouble OMXClockAdjustment(bool lock = true) { return 0.0; }\n\tbool OMXMediaTime(double pts, bool lock = true) { return false; }\n\tbool OMXPause(bool lock = true) { return false; }\n\tbool OMXResume(bool lock = true) { return false; }\n\tbool OMXSetSpeed(int speed, bool lock = true, bool pause_resume = false) { return false; }\n\tbool OMXFlush(bool lock = true) { return false; }\n\tbool OMXStateExecute(bool lock = true) { return false; }\n\tvoid OMXStateIdle(bool lock = true) {}\n\tbool HDMIClockSync(bool lock = true) { return false; }\n\tvoid OMXSetSpeedAdjust(double adjust, bool lock = true) {}\n};\n#endif\n\nstruct SOmxPlayerState\n{\n\tOMXClock av_clock;              // openmax clock component\n//\tEINTERLACEMETHOD interlace_method; // current deinterlace method\n\tbool bOmxWaitVideo;             // whether we need to wait for video to play out on EOS\n\tbool bOmxWaitAudio;             // whether we need to wait for audio to play out on EOS\n\tbool bOmxSentEOFs;              // flag if we've send EOFs to audio/video players\n\tfloat threshold;                // current fifo threshold required to come out of buffering\n\tunsigned int last_check_time;   // we periodically check for gpu underrun\n\tdouble stamp;                   // last media timestamp\n};\n\nclass tTJSNI_Window;\nclass tTJSNI_VideoOverlay;\nstruct IStream;\n\nenum class KRMovieEvent {\n\tNone,\n\tAborted,\n\tStopped,\n\tEnded,\n\tUpdate,\n};\n\nNS_KRMOVIE_BEGIN\n\nstruct CCurrentStream\n{\n\tint64_t demuxerId; // demuxer's id of current playing stream\n\tint id;     // id of current playing stream\n\tint source;\n\tdouble dts;    // last dts from demuxer, used to find disncontinuities\n\tdouble dur;    // last frame expected duration\n\tint dispTime; // display time from input stream\n\tCDVDStreamInfo hint;   // stream hints, used to notice stream changes\n\tvoid* stream; // pointer or integer, identifying stream playing. if it changes stream changed\n\tint changes; // remembered counter from stream to track codec changes\n\tbool inited;\n\tunsigned int packets;\n\tIDVDStreamPlayer::ESyncState syncState;\n\tdouble starttime;\n\tdouble cachetime;\n\tdouble cachetotal;\n\tconst StreamType type;\n\tconst int player;\n\t// stuff to handle starting after seek\n\tdouble startpts;\n\tdouble lastdts;\n\n\tenum\n\t{\n\t\tAV_SYNC_NONE,\n\t\tAV_SYNC_CHECK,\n\t\tAV_SYNC_CONT,\n\t\tAV_SYNC_FORCE\n\t} avsync;\n\n\tCCurrentStream(StreamType t, int i)\n\t\t: type(t)\n\t\t, player(i)\n\t{\n\t\tClear();\n\t}\n\n\tvoid Clear()\n\t{\n\t\tid = -1;\n\t\tdemuxerId = -1;\n\t\tsource = STREAM_SOURCE_NONE;\n\t\tdts = DVD_NOPTS_VALUE;\n\t\tdur = DVD_NOPTS_VALUE;\n\t\thint.Clear();\n\t\tstream = NULL;\n\t\tchanges = 0;\n\t\tinited = false;\n\t\tpackets = 0;\n\t\tsyncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\tstarttime = DVD_NOPTS_VALUE;\n\t\tstartpts = DVD_NOPTS_VALUE;\n\t\tlastdts = DVD_NOPTS_VALUE;\n\t\tavsync = AV_SYNC_FORCE;\n\t}\n\n\tdouble dts_end()\n\t{\n\t\tif (dts == DVD_NOPTS_VALUE)\n\t\t\treturn DVD_NOPTS_VALUE;\n\t\tif (dur == DVD_NOPTS_VALUE)\n\t\t\treturn dts;\n\t\treturn dts + dur;\n\t}\n};\n\nstruct SPlayerState\n{\n\tSPlayerState() { Clear(); }\n\tvoid Clear()\n\t{\n\t\ttimestamp = 0;\n\t\ttime = 0;\n\t\ttime_total = 0;\n\t\ttime_offset = 0;\n\t\tdts = DVD_NOPTS_VALUE;\n\t\tplayer_state = \"\";\n\t\tisInMenu = false;\n\t\thasMenu = false;\n\t\tcanrecord = false;\n\t\trecording = false;\n\t\tcanpause = false;\n\t\tcanseek = false;\n\t\tcaching = false;\n\t\tcache_bytes = 0;\n\t\tcache_level = 0.0;\n\t\tcache_delay = 0.0;\n\t\tcache_offset = 0.0;\n\t\tlastSeek = 0;\n\t}\n\n\tdouble timestamp;         // last time of update\n\tdouble lastSeek;          // time of last seek\n\tdouble time_offset;       // difference between time and pts\n\n\tdouble time;              // current playback time\n\tdouble time_total;        // total playback time\n\tdouble dts;               // last known dts\n\n\tstd::string player_state; // full player state\n\tbool isInMenu;\n\tbool hasMenu;\n\n\tbool canrecord;           // can input stream record\n\tbool recording;           // are we currently recording\n\tbool canpause;            // pvr: can pause the current playing item\n\tbool canseek;             // pvr: can seek in the current playing item\n\tbool caching;\n\n\tint64_t cache_bytes;   // number of bytes current's cached\n\tdouble cache_level;   // current estimated required cache level\n\tdouble cache_delay;   // time until cache is expected to reach estimated level\n\tdouble cache_offset;  // percentage of file ahead of current position\n};\n\nstruct SelectionStream {\n\tStreamType   type = STREAM_NONE;\n\tint          type_index = 0;\n\tstd::string  filename;\n//\tstd::string  filename2;  // for vobsub subtitles, 2 files are necessary (idx/sub)\n//\tstd::string  language;\n\tstd::string  name;\n\tCDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE;\n\tint          source = 0;\n\tint          id = 0;\n\tint64_t      demuxerId = -1;\n\tstd::string  codec;\n\tint          channels = 0;\n\tint          bitrate = 0;\n\tint          width = 0;\n\tint          height = 0;\n\tCRect        SrcRect;\n\tCRect        DestRect;\n\tstd::string  stereo_mode;\n\tfloat        aspect_ratio = 0.0f;\n};\n\ntypedef std::vector<SelectionStream> SelectionStreams;\n\nclass IDemux;\nclass BasePlayer;\nclass InputStream;\nclass CSelectionStreams\n{\n\tSelectionStream  m_invalid;\npublic:\n\tCSelectionStreams()\n\t{\n\t\tm_invalid.id = -1;\n\t\tm_invalid.source = STREAM_SOURCE_NONE;\n\t\tm_invalid.type = STREAM_NONE;\n\t}\n\tstd::vector<SelectionStream> m_Streams;\n\tstd::recursive_mutex m_section;\n\n\tint              IndexOf(StreamType type, int source, int64_t demuxerId, int id);\n//\tint              IndexOf(StreamType type, const Player& p);\n\tint              Count(StreamType type) { return IndexOf(type, STREAM_SOURCE_NONE, -1, -1) + 1; }\n\tint              CountSource(StreamType type, StreamSource source) const;\n\tSelectionStream& Get(StreamType type, int index);\n\tbool             Get(StreamType type, CDemuxStream::EFlags flag, SelectionStream& out);\n\n\tSelectionStreams Get(StreamType type);\n\ttemplate<typename Compare> SelectionStreams Get(StreamType type, Compare compare)\n\t{\n\t\tSelectionStreams streams = Get(type);\n\t\tstd::stable_sort(streams.begin(), streams.end(), compare);\n\t\treturn streams;\n\t}\n\n\tvoid             Clear(StreamType type, StreamSource source);\n\tint              Source(StreamSource source, const std::string & filename);\n\n\tvoid             Update(SelectionStream& s);\n\tvoid             Update(InputStream* input, IDemux* demuxer, const std::string & filename2 = \"\");\n};\n\nclass IDVDStreamPlayerVideo;\nclass IDVDStreamPlayerAudio;\nclass BasePlayer : public CThread, public IRenderMsg\n{\npublic:\n\tvoid Play();\n\tvoid Stop();\n\tvoid Pause();\n\n\t// IRenderMsg\n\tvirtual void VideoParamsChange() override;\n\tvirtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) override;\n\tvirtual void UpdateClockSync(bool enabled) override;\n\tvirtual void UpdateRenderInfo(CRenderInfo &info) override;\n\tvirtual CBaseRenderer* CreateRenderer() override { return m_pRenderer; }\n\npublic:\n\tBasePlayer(CBaseRenderer *renderer);\n\tvirtual ~BasePlayer();\n\tbool OpenFromStream(IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size);\n\tbool CloseInputStream();\n\tbool IsPlaying() const;\n\tbool CanSeek();\n\n\tvirtual void OnPlayBackSeek(int iTime, int iOffset) {}\n\n//\tvirtual void OnStartup() {}\n\tvirtual void OnExit();\n\tvirtual void Process();\n\n\tvoid CreatePlayers();\n\tvoid DestroyPlayers();\n\n\tbool OpenStream(CCurrentStream& current, int64_t demuxerId, int iStream, int source, bool reset = true);\n\tbool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);\n\tbool OpenVideoStream(CDVDStreamInfo& hint, bool reset = true);\n\n\tbool CloseStream(CCurrentStream& current, bool bWaitForBuffers);\n\n\tbool CheckIsCurrent(CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg);\n\tvoid ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);\n\tvoid ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);\n\tvoid ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);\n\n\tvoid SetPlaySpeed(int iSpeed);\n\tint GetPlaySpeed() { return m_playSpeed; }\n\n\tenum ECacheState\n\t{\n\t\tCACHESTATE_DONE = 0,\n\t\tCACHESTATE_FULL,     // player is filling up the demux queue\n\t\tCACHESTATE_INIT,     // player is waiting for first packet of each stream\n\t\tCACHESTATE_PLAY,     // player is waiting for players to not be stalled\n\t\tCACHESTATE_FLUSH,    // temporary state player will choose startup between init or full\n\t};\n\tvoid SetCaching(ECacheState state);\n\tdouble GetQueueTime();\n\tbool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);\n\n\tvoid SetSpeed(double speed);\n\tdouble GetSpeed();\n\tvoid FrameMove() { m_renderManager.FrameMove(); }\n\tbool IsStopped() { return m_bStop; }\n\tvoid SeekTime(int64_t iTimeMS);\n\tint64_t GetTime();\n\tint GetCurrentFrame();\n\tint GetVideoStreamCount();\n\tint GetVideoStream();\n\tint GetAudioStreamCount();\n\tint GetAudioStream();\n\n\tvoid FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true);\n\n\tvoid HandleMessages();\n\tvoid HandlePlaySpeed();\n\tvoid SynchronizeDemuxer();\n\tbool CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket);\n\tbool CheckSceneSkip(CCurrentStream& current);\n\tbool CheckPlayerInit(CCurrentStream& current);\n\tvoid UpdateCorrection(DemuxPacket* pkt, double correction);\n\tvoid UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket);\n\tIDVDStreamPlayer* GetStreamPlayer(unsigned int player);\n\tvoid SendPlayerMessage(CDVDMsg* pMsg, unsigned int target);\n\n\tbool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);\n\tbool IsValidStream(CCurrentStream& stream);\n\tbool IsBetterStream(CCurrentStream& current, CDemuxStream* stream);\n\tvoid CheckBetterStream(CCurrentStream& current, CDemuxStream* stream);\n\tvoid CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream);\n\t//\tbool CheckDelayedChannelEntry(void);\n\n\tvoid OpenInputStream(IStream *stream, const std::string& filename);\n\tbool OpenDemuxStream();\n\tvoid CloseDemuxer();\n\tvoid OpenDefaultStreams(bool reset = true);\n\n\tvoid UpdatePlayState(double timeout);\n\tvoid UpdateStreamInfos();\n\n\tbool IsStop() { return m_bStopStatus; }\n\tdouble GetFPS() { return (double)m_CurrentVideo.hint.fpsrate / m_CurrentVideo.hint.fpsscale; }\n\tint64_t GetTotalTime() { return llrint(m_State.time_total); }\n\tvoid GetVideoSize(long *width, long *height);\n\tCDVDMessageQueue& GetMessageQueue() { return m_messenger; }\n\tvoid SetCallback(const std::function<void(KRMovieEvent, void*)>& func) { m_callback = func; }\n\tIDVDStreamPlayerAudio *GetAudioPlayer() { return m_VideoPlayerAudio; }\n\tdouble GetClock() { return m_clock.GetClock(); }\n\n\tvoid SetLoopSegement(int beginFrame, unsigned int endFrame);\n\nprivate:\n\tvoid OnActive();\n\tvoid OnDeactive();\n//\tbool\t\tShutdown = false;\n\tbool\t\tm_bStopStatus = true;\n\tstd::string m_strFileName;\n\n\tbool m_players_created = false;\n\tbool m_bAbortRequest = false;\n\n\tECacheState  m_caching;\n\tTimer m_cachingTimer;\n\tTimer m_ChannelEntryTimeOut;\n\tstd::unique_ptr<CProcessInfo> m_processInfo;\n\n\tCCurrentStream m_CurrentAudio;\n\tCCurrentStream m_CurrentVideo;\n\n\tCSelectionStreams m_SelectionStreams;\n\n\tstd::atomic_int m_playSpeed;\n\tstd::atomic_int m_newPlaySpeed;\n\tdouble m_origSpeed = 0;\n\tint m_streamPlayerSpeed = DVD_PLAYSPEED_NORMAL;\n\tstruct SSpeedState\n\t{\n\t\tdouble  lastpts;  // holds last display pts during ff/rw operations\n\t\tint64_t lasttime;\n\t\tint lastseekpts;\n\t\tdouble  lastabstime;\n\t} m_SpeedState;\n\n\tint m_errorCount = 0;\n\tdouble m_offset_pts = 0.0;\n\n\tCDVDMessageQueue m_messenger;     // thread messenger\n\n\tIDVDStreamPlayerVideo *m_VideoPlayerVideo = nullptr;\n\tIDVDStreamPlayerAudio *m_VideoPlayerAudio = nullptr;\n\n\tCDVDClock m_clock;\n//\tCDVDOverlayContainer m_overlayContainer;\n\n\tInputStream* m_pInputStream = nullptr;  // input stream for current playing file\n\tIDemux* m_pDemuxer = nullptr;            // demuxer for current playing file\n\n\tCRenderManager m_renderManager;\n\n\tSPlayerState m_State;\n\tCCriticalSection m_StateSection;\n\tTimer m_syncTimer;\n\n\tstd::condition_variable m_ready;\n\n\tbool m_HasVideo = false;\n\tbool m_HasAudio = false;\n\n\tstruct SOmxPlayerState m_OmxPlayerState;\n\tbool m_omxplayer_mode = false;            // using omxplayer acceleration\n\n\tTimer m_player_status_timer;\n\tCBaseRenderer *m_pRenderer;\n\tstd::function<void(KRMovieEvent, void*)> m_callback;\n\n\tint m_iLoopSegmentBegin = -1;\n\tunsigned int m_iLoopSegmentEnd = -1;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayerAudio.cpp",
    "content": "#include \"VideoPlayerAudio.h\"\n#include \"AEUtil.h\"\n#include \"FactoryCodec.h\"\n#include \"DemuxPacket.h\"\n#include \"AEFactory.h\"\n\nNS_KRMOVIE_BEGIN\n// allow audio for slow and fast speeds (but not rewind/fastforward)\n#define ALLOW_AUDIO(speed) ((speed) > 5*DVD_PLAYSPEED_NORMAL/10 && (speed) <= 15*DVD_PLAYSPEED_NORMAL/10)\n\nclass CDVDMsgAudioCodecChange : public CDVDMsg\n{\npublic:\n\tCDVDMsgAudioCodecChange(const CDVDStreamInfo &hints, CDVDAudioCodec* codec)\n\t\t: CDVDMsg(GENERAL_STREAMCHANGE)\n\t\t, m_codec(codec)\n\t\t, m_hints(hints)\n\t{}\n\t~CDVDMsgAudioCodecChange()\n\t{\n\t\tdelete m_codec;\n\t}\n\tCDVDAudioCodec* m_codec;\n\tCDVDStreamInfo  m_hints;\n};\n\n\nCVideoPlayerAudio::CVideoPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent, CProcessInfo &processInfo)\n: CThread(), IDVDStreamPlayerAudio(processInfo)\n, m_messageQueue(\"audio\")\n, m_messageParent(parent)\n, m_dvdAudio(pClock)\n{\n\tm_pClock = pClock;\n\tm_pAudioCodec = NULL;\n\tm_audioClock = 0;\n\tm_speed = DVD_PLAYSPEED_NORMAL;\n\tm_stalled = true;\n\tm_paused = false;\n\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\tm_silence = false;\n\tm_synctype = SYNC_DISCON;\n\tm_setsynctype = SYNC_DISCON;\n\tm_prevsynctype = -1;\n\tm_prevskipped = false;\n\tm_maxspeedadjust = 0.0;\n\n\tm_messageQueue.SetMaxDataSize(6 * 1024 * 1024);\n\tm_messageQueue.SetMaxTimeSize(8.0);\n}\n\nCVideoPlayerAudio::~CVideoPlayerAudio()\n{\n\tStopThread();\n\n\t// close the stream, and don't wait for the audio to be finished\n\t// CloseStream(true);\n}\n\nbool CVideoPlayerAudio::OpenStream(CDVDStreamInfo &hints)\n{\n\tm_processInfo.ResetAudioCodecInfo();\n\n//\tCLog::Log(LOGNOTICE, \"Finding audio codec for: %i\", hints.codec);\n\tbool allowpassthrough = true;// !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK);\n\tif (hints.realtime)\n\t\tallowpassthrough = false;\n\tCDVDAudioCodec* codec = CDVDFactoryCodec::CreateAudioCodec(hints, m_processInfo, allowpassthrough, m_processInfo.AllowDTSHDDecode());\n\tif (!codec)\n\t{\n//\t\tCLog::Log(LOGERROR, \"Unsupported audio codec\");\n\t\treturn false;\n\t}\n\n\tif (m_messageQueue.IsInited())\n\t\tm_messageQueue.Put(new CDVDMsgAudioCodecChange(hints, codec), 0);\n\telse\n\t{\n\t\tOpenStream(hints, codec);\n\t\tm_messageQueue.Init();\n//\t\tCLog::Log(LOGNOTICE, \"Creating audio thread\");\n\t\tCreate();\n\t}\n\treturn true;\n}\n\nvoid CVideoPlayerAudio::OpenStream(CDVDStreamInfo &hints, CDVDAudioCodec* codec)\n{\n\tSAFE_DELETE(m_pAudioCodec);\n\tm_pAudioCodec = codec;\n\n\t/* store our stream hints */\n\tm_streaminfo = hints;\n\n\t/* update codec information from what codec gave out, if any */\n\tint channelsFromCodec = m_pAudioCodec->GetFormat().m_channelLayout.Count();\n\tint samplerateFromCodec = m_pAudioCodec->GetFormat().m_sampleRate;\n\n\tif (channelsFromCodec > 0)\n\t\tm_streaminfo.channels = channelsFromCodec;\n\tif (samplerateFromCodec > 0)\n\t\tm_streaminfo.samplerate = samplerateFromCodec;\n\n\t/* check if we only just got sample rate, in which case the previous call\n\t* to CreateAudioCodec() couldn't have started passthrough */\n\tif (hints.samplerate != m_streaminfo.samplerate)\n\t\tSwitchCodecIfNeeded();\n\n\tm_audioClock = 0;\n\tm_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;\n\n\tm_synctype = SYNC_DISCON;\n\tm_setsynctype = SYNC_DISCON;\n// \tif (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK))\n// \t\tm_setsynctype = SYNC_RESAMPLE;\n// \telse \n\tif (hints.realtime)\n\t\tm_setsynctype = SYNC_RESAMPLE;\n\n\tm_prevsynctype = -1;\n\n\tm_prevskipped = false;\n\tm_silence = false;\n\n\tm_maxspeedadjust = 5.0;\n\n\tm_messageParent.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE));\n\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n}\n\nvoid CVideoPlayerAudio::CloseStream(bool bWaitForBuffers)\n{\n\tbool bWait = bWaitForBuffers && m_speed > 0 && !m_dvdAudio.m_pAudioStream->IsSuspended();\n\n\t// wait until buffers are empty\n\tif (bWait)\n\t\tm_messageQueue.WaitUntilEmpty();\n\n\t// send abort message to the audio queue\n\tm_messageQueue.Abort();\n\n//\tCLog::Log(LOGNOTICE, \"Waiting for audio thread to exit\");\n\n\t// shut down the adio_decode thread and wait for it\n\tStopThread(); // will set this->m_bStop to true\n\n\t// destroy audio device\n//\tCLog::Log(LOGNOTICE, \"Closing audio device\");\n\tif (bWait)\n\t{\n\t\tm_bStop = false;\n\t\tm_dvdAudio.Drain();\n\t\tm_bStop = true;\n\t} else\n\t{\n\t\tm_dvdAudio.Flush();\n\t}\n\n\tm_dvdAudio.Destroy();\n\n\t// uninit queue\n\tm_messageQueue.End();\n\n//\tCLog::Log(LOGNOTICE, \"Deleting audio codec\");\n\tif (m_pAudioCodec)\n\t{\n\t\tm_pAudioCodec->Dispose();\n\t\tdelete m_pAudioCodec;\n\t\tm_pAudioCodec = NULL;\n\t}\n}\n\nvoid CVideoPlayerAudio::OnStartup()\n{\n}\n\nvoid CVideoPlayerAudio::UpdatePlayerInfo()\n{\n#if 0\n\tstd::ostringstream s;\n\ts << \"aq:\" << std::setw(2) << std::min(99, m_messageQueue.GetLevel()) << \"%\";\n\ts << \", Kb/s:\" << std::fixed << std::setprecision(2) << (double)GetAudioBitrate() / 1024.0;\n\n\t//print the inverse of the resample ratio, since that makes more sense\n\t//if the resample ratio is 0.5, then we're playing twice as fast\n\tif (m_synctype == SYNC_RESAMPLE)\n\t\ts << \", rr:\" << std::fixed << std::setprecision(5) << 1.0 / m_dvdAudio.GetResampleRatio();\n\n\ts << \", att:\" << std::fixed << std::setprecision(1) << log(GetCurrentAttenuation()) * 20.0f << \" dB\";\n#endif\n\tSInfo info;\n//\tinfo.info = s.str();\n\tinfo.pts = m_dvdAudio.GetPlayingPts();\n\tinfo.passthrough = m_pAudioCodec && m_pAudioCodec->NeedPassthrough();\n\n\t{ CSingleLock lock(m_info_section);\n\tm_info = info;\n\t}\n}\n\nvoid CVideoPlayerAudio::Process()\n{\n//\tCLog::Log(LOGNOTICE, \"running thread: CVideoPlayerAudio::Process()\");\n\n\tDVDAudioFrame audioframe;\n\tm_audioStats.Start();\n\n\twhile (!m_bStop)\n\t{\n\t\tCDVDMsg* pMsg;\n\t\tint timeout = (int)(1000 * m_dvdAudio.GetCacheTime());\n\n\t\t// read next packet and return -1 on error\n\t\tint priority = 1;\n\t\t//Do we want a new audio frame?\n\t\tif (m_syncState == IDVDStreamPlayer::SYNC_STARTING ||              /* when not started */\n\t\t\tALLOW_AUDIO(m_speed) || /* when playing normally */\n\t\t\tm_speed <  DVD_PLAYSPEED_PAUSE || /* when rewinding */\n\t\t\t(m_speed >  DVD_PLAYSPEED_NORMAL && m_audioClock < m_pClock->GetClock())) /* when behind clock in ff */\n\t\t\tpriority = 0;\n\n\t\tif (m_syncState == IDVDStreamPlayer::SYNC_WAITSYNC)\n\t\t\tpriority = 1;\n\n\t\tif (m_paused)\n\t\t\tpriority = 1;\n\n\t\tMsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority);\n\n\t\tif (MSGQ_IS_ERROR(ret))\n\t\t{\n\t//\t\tCLog::Log(LOGERROR, \"Got MSGQ_ABORT or MSGO_IS_ERROR return true\");\n\t\t\tbreak;\n\t\t} else if (ret == MSGQ_TIMEOUT)\n\t\t{\n\t\t\t// Flush as the audio output may keep looping if we don't\n\t\t\tif (ALLOW_AUDIO(m_speed) && !m_stalled && m_syncState == IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t{\n\t\t\t\t// while AE sync is active, we still have time to fill buffers\n\t\t\t\tif (m_syncTimer.IsTimePast())\n\t\t\t\t{\n\t\t//\t\t\tCLog::Log(LOGNOTICE, \"CVideoPlayerAudio::Process - stream stalled\");\n\t\t\t\t\tm_stalled = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (timeout == 0)\n\t\t\t\tSleep(10);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle messages\n\t\tif (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE))\n\t\t{\n\t\t\tif (((CDVDMsgGeneralSynchronize*)pMsg)->Wait(100, SYNCSOURCE_AUDIO))\n\t\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio - CDVDMsg::GENERAL_SYNCHRONIZE\")\n\t\t\t\t;\n\t\t\telse\n\t\t\t\tm_messageQueue.Put(pMsg->AddRef(), 1);  // push back as prio message, to process other prio messages\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))\n\t\t{ //player asked us to set internal clock\n\t\t\tdouble pts = static_cast<CDVDMsgDouble*>(pMsg)->m_value;\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f)\", pts);\n\n\t\t\tm_audioClock = pts + m_dvdAudio.GetDelay();\n\t\t\tif (m_speed != DVD_PLAYSPEED_PAUSE)\n\t\t\t\tm_dvdAudio.Resume();\n\t\t\tm_syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_syncTimer.Set(3000);\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))\n\t\t{\n\t\t\tif (m_pAudioCodec)\n\t\t\t\tm_pAudioCodec->Reset();\n\t\t\tm_dvdAudio.Flush();\n\t\t\tm_stalled = true;\n\t\t\tm_audioClock = 0;\n\t\t\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH))\n\t\t{\n\t\t\tbool sync = static_cast<CDVDMsgBool*>(pMsg)->m_value;\n\t\t\tm_dvdAudio.Flush();\n\t\t\tm_stalled = true;\n\t\t\tm_audioClock = 0;\n\n\t\t\tif (sync)\n\t\t\t{\n\t\t\t\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\t\t\tm_dvdAudio.Pause();\n\t\t\t}\n\n\t\t\tif (m_pAudioCodec)\n\t\t\t\tm_pAudioCodec->Reset();\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_EOF))\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio - CDVDMsg::GENERAL_EOF\");\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))\n\t\t{\n\t\t\tdouble speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;\n\n\t\t\tif (ALLOW_AUDIO(speed))\n\t\t\t{\n\t\t\t\tif (speed != m_speed)\n\t\t\t\t{\n\t\t\t\t\tif (m_syncState == IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t\t\t\tm_dvdAudio.Resume();\n\t\t\t\t}\n\t\t\t} else\n\t\t\t{\n\t\t\t\tm_dvdAudio.Pause();\n\t\t\t}\n\t\t\tm_speed = speed;\n\t\t} else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE))\n\t\t{\n\t\t\tm_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value;\n// \t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, %d)\"\n// \t\t\t\t, m_audioClock, m_silence);\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))\n\t\t{\n\t\t\tCDVDMsgAudioCodecChange* msg(static_cast<CDVDMsgAudioCodecChange*>(pMsg));\n\t\t\tOpenStream(msg->m_hints, msg->m_codec);\n\t\t\tmsg->m_codec = NULL;\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_PAUSE))\n\t\t{\n\t\t\tm_paused = static_cast<CDVDMsgBool*>(pMsg)->m_value;\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio - CDVDMsg::GENERAL_PAUSE: %d\", m_paused);\n\t\t} else if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))\n\t\t{\n\t\t\tDemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket();\n\t\t\tbool bPacketDrop = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop();\n\n\t\t\tint consumed = m_pAudioCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts);\n\t\t\tif (consumed < 0)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGERROR, \"CVideoPlayerAudio::DecodeFrame - Decode Error. Skipping audio packet (%d)\", consumed);\n\t\t\t\tm_pAudioCodec->Reset();\n\t\t\t\tpMsg->Release();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tm_audioStats.AddSampleBytes(pPacket->iSize);\n\t\t\tUpdatePlayerInfo();\n\n\t\t\t// loop while no error and decoder produces output\n\t\t\twhile (!m_bStop)\n\t\t\t{\n\t\t\t\t// get decoded data and the size of it\n\t\t\t\tm_pAudioCodec->GetData(audioframe);\n\n\t\t\t\tif (audioframe.nb_frames == 0)\n\t\t\t\t{\n\t\t\t\t\tif (consumed >= pPacket->iSize)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tint ret = m_pAudioCodec->Decode(pPacket->pData + consumed, pPacket->iSize - consumed, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\t\t\t\t\tif (ret < 0)\n\t\t\t\t\t{\n\t\t\t\t\t//\tCLog::Log(LOGERROR, \"CVideoPlayerAudio::DecodeFrame - Decode Error. Skipping audio packet (%d)\", ret);\n\t\t\t\t\t\tm_pAudioCodec->Reset();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconsumed += ret;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\taudioframe.hasTimestamp = true;\n\t\t\t\tif (audioframe.pts == DVD_NOPTS_VALUE)\n\t\t\t\t{\n\t\t\t\t\taudioframe.pts = m_audioClock;\n\t\t\t\t\taudioframe.hasTimestamp = false;\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tm_audioClock = audioframe.pts;\n\t\t\t\t}\n\n\t\t\t\t//Drop when not playing normally\n\t\t\t\tif (!ALLOW_AUDIO(m_speed) && m_syncState == IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (audioframe.format.m_sampleRate && m_streaminfo.samplerate != (int)audioframe.format.m_sampleRate)\n\t\t\t\t{\n\t\t\t\t\t// The sample rate has changed or we just got it for the first time\n\t\t\t\t\t// for this stream. See if we should enable/disable passthrough due\n\t\t\t\t\t// to it.\n\t\t\t\t\tm_streaminfo.samplerate = audioframe.format.m_sampleRate;\n\t\t\t\t\tif (SwitchCodecIfNeeded())\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// demuxer reads metatags that influence channel layout\n\t\t\t\tif (m_streaminfo.codec == AV_CODEC_ID_FLAC && m_streaminfo.channellayout)\n\t\t\t\t\taudioframe.format.m_channelLayout = CAEUtil::GetAEChannelLayout(m_streaminfo.channellayout);\n\n\t\t\t\t// we have succesfully decoded an audio frame, setup renderer to match\n\t\t\t\tif (!m_dvdAudio.IsValidFormat(audioframe))\n\t\t\t\t{\n\t\t\t\t\tif (m_speed)\n\t\t\t\t\t\tm_dvdAudio.Drain();\n\n\t\t\t\t\tm_dvdAudio.Destroy();\n\n\t\t\t\t\tif (!m_dvdAudio.Create(audioframe, m_streaminfo.codec, m_setsynctype == SYNC_RESAMPLE))\n\t\t\t\t\t//\tCLog::Log(LOGERROR, \"%s - failed to create audio renderer\", __FUNCTION__)\n\t\t\t\t\t\t;\n\n\t\t\t\t\tif (m_syncState == IDVDStreamPlayer::SYNC_INSYNC)\n\t\t\t\t\t\tm_dvdAudio.Resume();\n\n\t\t\t\t\tm_streaminfo.channels = audioframe.format.m_channelLayout.Count();\n\n\n\t\t\t\t\tm_processInfo.SetAudioChannels(audioframe.format.m_channelLayout);\n\t\t\t\t\tm_processInfo.SetAudioSampleRate(audioframe.format.m_sampleRate);\n\t\t\t\t\tm_processInfo.SetAudioBitsPerSample(audioframe.bits_per_sample);\n\n\t\t\t\t\tm_messageParent.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE));\n\t\t\t\t}\n\n\t\t\t\t// Zero out the frame data if we are supposed to silence the audio\n\t\t\t\tif (m_silence)\n\t\t\t\t{\n\t\t\t\t\tint size = audioframe.nb_frames * audioframe.framesize / audioframe.planes;\n\t\t\t\t\tfor (unsigned int i = 0; i<audioframe.planes; i++)\n\t\t\t\t\t\tmemset(audioframe.data[i], 0, size);\n\t\t\t\t}\n\n\t\t\t\tSetSyncType(audioframe.passthrough);\n\n\t\t\t\tif (!bPacketDrop)\n\t\t\t\t{\n\t\t\t\t\tOutputPacket(audioframe);\n\n\t\t\t\t\t// signal to our parent that we have initialized\n\t\t\t\t\tif (m_syncState == IDVDStreamPlayer::SYNC_STARTING)\n\t\t\t\t\t{\n\t\t\t\t\t\tdouble cachetotal = DVD_SEC_TO_TIME(m_dvdAudio.GetCacheTotal());\n\t\t\t\t\t\tdouble cachetime = m_dvdAudio.GetDelay();\n//\t\t\t\t\t\tif (cachetime >= cachetotal * 0.5)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_syncState = IDVDStreamPlayer::SYNC_WAITSYNC;\n\n\t\t\t\t\t\t\tm_stalled = false;\n\t\t\t\t\t\t\tSStartMsg msg;\n\t\t\t\t\t\t\tmsg.player = VideoPlayer_AUDIO;\n\t\t\t\t\t\t\tmsg.cachetotal = cachetotal;\n\t\t\t\t\t\t\tmsg.cachetime = cachetime;\n\t\t\t\t\t\t\tmsg.timestamp = audioframe.hasTimestamp ? audioframe.pts : DVD_NOPTS_VALUE;\n\t\t\t\t\t\t\tm_messageParent.Put(new CDVDMsgType<SStartMsg>(CDVDMsg::PLAYER_STARTED, msg));\n#if 0\n\t\t\t\t\t\t\tif (consumed < pPacket->iSize)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpPacket->iSize -= consumed;\n\t\t\t\t\t\t\t\tmemmove(pPacket->pData, pPacket->pData + consumed, pPacket->iSize);\n\t\t\t\t\t\t\t\tm_messageQueue.Put(pMsg->AddRef(), 0, false);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// guess next pts\n\t\t\t\tm_audioClock += audioframe.duration;\n\n\t\t\t\tif (consumed >= pPacket->iSize)\n\t\t\t\t\tbreak;\n\t\t\t\tint ret = m_pAudioCodec->Decode(pPacket->pData + consumed, pPacket->iSize - consumed, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\t\t\t\tif (ret < 0)\n\t\t\t\t{\n\t\t\t\t//\tCLog::Log(LOGERROR, \"CVideoPlayerAudio::DecodeFrame - Decode Error. Skipping audio packet (%d)\", ret);\n\t\t\t\t\tm_pAudioCodec->Reset();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsumed += ret;\n\t\t\t\t}\n\t\t\t} // while decoder produces output\n\n\t\t} // demuxer packet\n\n\t\tpMsg->Release();\n\t}\n}\n\nvoid CVideoPlayerAudio::SetSyncType(bool passthrough)\n{\n\t//set the synctype from the gui\n\tm_synctype = m_setsynctype;\n\tif (passthrough && m_synctype == SYNC_RESAMPLE)\n\t\tm_synctype = SYNC_DISCON;\n\n\t//if SetMaxSpeedAdjust returns false, it means no video is played and we need to use clock feedback\n\tdouble maxspeedadjust = 0.0;\n\tif (m_synctype == SYNC_RESAMPLE)\n\t\tmaxspeedadjust = m_maxspeedadjust;\n\n\tm_pClock->SetMaxSpeedAdjust(maxspeedadjust);\n\n\tif (m_synctype != m_prevsynctype)\n\t{\n\t\tconst char *synctypes[] = { \"clock feedback\", \"resample\", \"invalid\" };\n\t\tint synctype = (m_synctype >= 0 && m_synctype <= 1) ? m_synctype : 2;\n\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio:: synctype set to %i: %s\", m_synctype, synctypes[synctype]);\n\t\tm_prevsynctype = m_synctype;\n\t\tif (m_synctype == SYNC_RESAMPLE)\n\t\t\tm_dvdAudio.SetResampleMode(1);\n\t\telse\n\t\t\tm_dvdAudio.SetResampleMode(0);\n\t}\n}\n\nbool CVideoPlayerAudio::OutputPacket(DVDAudioFrame &audioframe)\n{\n\tdouble syncerror = m_dvdAudio.GetSyncError();\n\n\tif (m_synctype == SYNC_DISCON && fabs(syncerror) > DVD_MSEC_TO_TIME(10))\n\t{\n\t\tdouble correction = m_pClock->ErrorAdjust(syncerror, \"CVideoPlayerAudio::OutputPacket\");\n\t\tif (correction != 0)\n\t\t{\n\t\t\tm_dvdAudio.SetSyncErrorCorrection(-correction);\n\t\t}\n\t}\n\tm_dvdAudio.AddPackets(audioframe);\n\n\treturn true;\n}\n\nvoid CVideoPlayerAudio::OnExit()\n{\n#ifdef TARGET_WINDOWS\n\tCoUninitialize();\n#endif\n\n//\tCLog::Log(LOGNOTICE, \"thread end: CVideoPlayerAudio::OnExit()\");\n}\n\nvoid CVideoPlayerAudio::SetSpeed(int speed)\n{\n\tif (m_messageQueue.IsInited())\n\t\tm_messageQueue.Put(new CDVDMsgInt(CDVDMsg::PLAYER_SETSPEED, speed), 1);\n\telse\n\t\tm_speed = speed;\n}\n\nvoid CVideoPlayerAudio::Flush(bool sync)\n{\n\tm_messageQueue.Flush();\n\tm_messageQueue.Put(new CDVDMsgBool(CDVDMsg::GENERAL_FLUSH, sync), 1);\n\n\tm_dvdAudio.AbortAddPackets();\n}\n\nbool CVideoPlayerAudio::AcceptsData()\n{\n\tbool full = m_messageQueue.IsFull();\n\treturn !full;\n}\n\nbool CVideoPlayerAudio::SwitchCodecIfNeeded()\n{\n//\tCLog::Log(LOGDEBUG, \"CVideoPlayerAudio: Sample rate changed, checking for passthrough\");\n\tbool allowpassthrough = true;\n\t\t//!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK);\n\tif (m_streaminfo.realtime)\n\t\tallowpassthrough = false;\n\tCDVDAudioCodec *codec = CDVDFactoryCodec::CreateAudioCodec(m_streaminfo, m_processInfo, allowpassthrough, m_processInfo.AllowDTSHDDecode());\n\tif (!codec || codec->NeedPassthrough() == m_pAudioCodec->NeedPassthrough()) {\n\t\t// passthrough state has not changed\n\t\tdelete codec;\n\t\treturn false;\n\t}\n\n\tdelete m_pAudioCodec;\n\tm_pAudioCodec = codec;\n\n\treturn true;\n}\n\nstd::string CVideoPlayerAudio::GetPlayerInfo()\n{\n\tCSingleLock lock(m_info_section);\n\treturn m_info.info;\n}\n\nint CVideoPlayerAudio::GetAudioBitrate()\n{\n\treturn (int)m_audioStats.GetBitrate();\n}\n\nint CVideoPlayerAudio::GetAudioChannels()\n{\n\treturn m_streaminfo.channels;\n}\n\nbool CVideoPlayerAudio::IsPassthrough()\n{\n\tCSingleLock lock(m_info_section);\n\treturn m_info.passthrough;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayerAudio.h",
    "content": "#pragma once\n#include \"Thread.h\"\n#include \"IVideoPlayer.h\"\n#include \"AudioCodec.h\"\n#include \"BitstreamStats.h\"\n#include \"MessageQueue.h\"\n#include \"Timer.h\"\n#include \"Clock.h\"\n#include \"AudioDevice.h\"\n\nNS_KRMOVIE_BEGIN\nclass CDVDClock;\nclass CVideoPlayerAudio : public CThread, public IDVDStreamPlayerAudio\n{\npublic:\n\tCVideoPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent, CProcessInfo &processInfo);\n\tvirtual ~CVideoPlayerAudio();\n\n\tbool OpenStream(CDVDStreamInfo &hints);\n\tvoid CloseStream(bool bWaitForBuffers);\n\n\tvoid SetSpeed(int speed);\n\tvoid Flush(bool sync);\n\n\t// waits until all available data has been rendered\n\tbool AcceptsData() ;\n\tbool HasData() const                                  { return m_messageQueue.GetDataSize() > 0; }\n\tint  GetLevel()                                  { return m_messageQueue.GetLevel(); }\n\tbool IsInited() const                                 { return m_messageQueue.IsInited(); }\n\tvoid SendMessage(CDVDMsg* pMsg, int priority = 0)     { m_messageQueue.Put(pMsg, priority); }\n\tvoid FlushMessages()                                  { m_messageQueue.Flush(); }\n\n//\tvoid SetDynamicRangeCompression(long drc)             { m_dvdAudio.SetDynamicRangeCompression(drc); }\n\tfloat GetDynamicRangeAmplification() const            { return 0.0f; }\n\n\n\tstd::string GetPlayerInfo();\n\tint GetAudioBitrate();\n\tint GetAudioChannels();\n\n\t// holds stream information for current playing stream\n\tCDVDStreamInfo m_streaminfo;\n\n\tdouble GetCurrentPts()                            { CSingleLock lock(m_info_section); return m_info.pts; }\n\n\tbool IsStalled() const                            { return m_stalled; }\n\tbool IsPassthrough() override;\n\tvirtual CDVDAudio* GetOutputDevice() override { return &m_dvdAudio; }\n\nprotected:\n\n\tvirtual void OnStartup();\n\tvirtual void OnExit();\n\tvirtual void Process();\n\n\tvoid UpdatePlayerInfo();\n\tvoid OpenStream(CDVDStreamInfo &hints, CDVDAudioCodec* codec);\n\t//! Switch codec if needed. Called when the sample rate gotten from the\n\t//! codec changes, in which case we may want to switch passthrough on/off.\n\tbool SwitchCodecIfNeeded();\n//\tfloat GetCurrentAttenuation()                         { return m_dvdAudio.GetCurrentAttenuation(); }\n\n\tCDVDMessageQueue m_messageQueue;\n\tCDVDMessageQueue& m_messageParent;\n\n\tdouble m_audioClock;\n\n\tCDVDAudio m_dvdAudio; // audio output device\n\tCDVDClock* m_pClock; // dvd master clock\n\tCDVDAudioCodec* m_pAudioCodec; // audio codec\n\tBitstreamStats m_audioStats;\n\n\tint m_speed;\n\tbool m_stalled;\n\tbool m_silence;\n\tbool m_paused;\n\tIDVDStreamPlayer::ESyncState m_syncState;\n\tTimer m_syncTimer;\n\n\tbool OutputPacket(DVDAudioFrame &audioframe);\n\n\t//SYNC_DISCON, SYNC_SKIPDUP, SYNC_RESAMPLE\n\tint    m_synctype;\n\tint    m_setsynctype;\n\tint    m_prevsynctype; //so we can print to the log\n\n\tvoid   SetSyncType(bool passthrough);\n\n\tbool   m_prevskipped;\n\tdouble m_maxspeedadjust;\n\n\tstruct SInfo\n\t{\n\t\tSInfo()\n\t\t: pts(DVD_NOPTS_VALUE)\n\t\t, passthrough(false)\n\t\t{}\n\n\t\tstd::string      info;\n\t\tdouble           pts;\n\t\tbool             passthrough;\n\t};\n\n\tCCriticalSection m_info_section;\n\tSInfo            m_info;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayerVideo.cpp",
    "content": "#include \"VideoPlayerVideo.h\"\n#include \"Clock.h\"\nextern \"C\" {\n#include \"libavformat/avformat.h\"\n}\n#include \"FactoryCodec.h\"\n#include \"CodecUtils.h\"\n#include \"MessageQueue.h\"\n#include \"DemuxPacket.h\"\n#include <algorithm>\n#include \"VideoRenderer.h\"\n#include \"RenderFlags.h\"\n\nNS_KRMOVIE_BEGIN\nusing namespace RenderManager;\n\nclass CDVDMsgVideoCodecChange : public CDVDMsg\n{\npublic:\n\tCDVDMsgVideoCodecChange(const CDVDStreamInfo &hints, CDVDVideoCodec* codec)\n\t\t: CDVDMsg(GENERAL_STREAMCHANGE)\n\t\t, m_codec(codec)\n\t\t, m_hints(hints)\n\t{}\n\t~CDVDMsgVideoCodecChange()\n\t{\n\t\tdelete m_codec;\n\t}\n\tCDVDVideoCodec* m_codec;\n\tCDVDStreamInfo  m_hints;\n};\n\n\nCVideoPlayerVideo::CVideoPlayerVideo(CDVDClock* pClock\n//\t, CDVDOverlayContainer* pOverlayContainer\n\t, CDVDMessageQueue& parent\n\t, CRenderManager& renderManager\n\t, CProcessInfo &processInfo)\n\t: CThread()\n\t, IDVDStreamPlayerVideo(processInfo)\n\t, m_messageQueue(\"video\")\n\t, m_messageParent(parent)\n\t, m_renderManager(renderManager)\n{\n\tm_pClock = pClock;\n//\tm_pOverlayContainer = pOverlayContainer;\n\tm_pTempOverlayPicture = NULL;\n\tm_pVideoCodec = NULL;\n\tm_speed = DVD_PLAYSPEED_NORMAL;\n\n\tm_bRenderSubs = false;\n\tm_stalled = false;\n\tm_paused = false;\n\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\tm_iSubtitleDelay = 0;\n\tm_iLateFrames = 0;\n\tm_iDroppedRequest = 0;\n\tm_fForcedAspectRatio = 0;\n\tm_messageQueue.SetMaxDataSize(40 * 1024 * 1024);\n\tm_messageQueue.SetMaxTimeSize(8.0);\n\n\tm_iDroppedFrames = 0;\n// \tm_fFrameRate = 25;\n// \tm_bCalcFrameRate = false;\n// \tm_fStableFrameRate = 0.0;\n// \tm_iFrameRateCount = 0;\n\tm_bAllowDrop = false;\n// \tm_iFrameRateErr = 0;\n// \tm_iFrameRateLength = 0;\n\tm_bFpsInvalid = false;\n//\tm_bAllowFullscreen = false;\n}\n\nCVideoPlayerVideo::~CVideoPlayerVideo()\n{\n\tm_bAbortOutput = true;\n\tStopThread();\n}\n\ndouble CVideoPlayerVideo::GetOutputDelay()\n{\n\tdouble time = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET);\n\tif (m_fFrameRate)\n\t\ttime = (time * DVD_TIME_BASE) / m_fFrameRate;\n\telse\n\t\ttime = 0.0;\n\n\tif (m_speed != 0)\n\t\ttime = time * DVD_PLAYSPEED_NORMAL / abs(m_speed);\n\n\treturn time;\n}\n\nbool CVideoPlayerVideo::OpenStream(CDVDStreamInfo &hint)\n{\n\tm_processInfo.ResetVideoCodecInfo();\n\n\tCRenderInfo info;\n\tinfo = m_renderManager.GetRenderInfo();\n\n//\tm_pullupCorrection.ResetVFRDetection();\n\tif (hint.flags & AV_DISPOSITION_ATTACHED_PIC)\n\t\treturn false;\n\n//\tCLog::Log(LOGNOTICE, \"Creating video codec with codec id: %i\", hint.codec);\n\tCDVDVideoCodec* codec = CDVDFactoryCodec::CreateVideoCodec(hint, m_processInfo, info);\n\tif (!codec)\n\t{\n//\t\tCLog::Log(LOGERROR, \"Unsupported video codec\");\n\t\treturn false;\n\t}\n\n\tif (m_messageQueue.IsInited())\n\t\tm_messageQueue.Put(new CDVDMsgVideoCodecChange(hint, codec), 0);\n\telse\n\t{\n\t\tOpenStream(hint, codec);\n//\t\tCLog::Log(LOGNOTICE, \"Creating video thread\");\n\t\tm_messageQueue.Init();\n\t\tCreate();\n\t}\n\treturn true;\n}\n\nvoid CVideoPlayerVideo::OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec)\n{\n//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo::OpenStream - open stream with codec id: %i\", hint.codec);\n\n\t//reported fps is usually not completely correct\n\tif (hint.fpsrate && hint.fpsscale)\n\t{\n\t\tm_fFrameRate = DVD_TIME_BASE / CDVDCodecUtils::NormalizeFrameduration((double)DVD_TIME_BASE * hint.fpsscale / hint.fpsrate);\n\t\tm_bFpsInvalid = false;\n\t\tm_processInfo.SetVideoFps(m_fFrameRate);\n\t} else\n\t{\n\t\tm_fFrameRate = 25;\n\t\tm_bFpsInvalid = true;\n\t\tm_processInfo.SetVideoFps(0);\n\t}\n\n//\tm_pullupCorrection.ResetVFRDetection();\n// \tm_bCalcFrameRate = CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK) ||\n// \t\tCSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF;\n//\tm_bCalcFrameRate = false;\n\tResetFrameRateCalc();\n\n\tm_iDroppedRequest = 0;\n\tm_iLateFrames = 0;\n\n\tif (m_fFrameRate > 120 || m_fFrameRate < 5)\n\t{\n//\t\tCLog::Log(LOGERROR, \"CVideoPlayerVideo::OpenStream - Invalid framerate %d, using forced 25fps and just trust timestamps\", (int)m_fFrameRate);\n\t\tm_fFrameRate = 25;\n\t}\n\n\t// use aspect in stream if available\n\tif (hint.forced_aspect)\n\t\tm_fForcedAspectRatio = hint.aspect;\n\telse\n\t\tm_fForcedAspectRatio = 0.0;\n\n\tif (m_pVideoCodec)\n\t{\n\t\tm_pVideoCodec->ClearPicture(&m_picture);\n\t\tdelete m_pVideoCodec;\n\t}\n\tm_pVideoCodec = codec;\n\tm_hints = hint;\n\tm_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;\n\tm_rewindStalled = false;\n\tm_packets.clear();\n\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n}\n\nvoid CVideoPlayerVideo::CloseStream(bool bWaitForBuffers)\n{\n\t// wait until buffers are empty\n\tif (bWaitForBuffers && m_speed > 0)\n\t{\n\t\tm_messageQueue.Put(new CDVDMsg(CDVDMsg::VIDEO_DRAIN), 0);\n\t\tm_messageQueue.WaitUntilEmpty();\n\t}\n\n\tm_messageQueue.Abort();\n\n\t// wait for decode_video thread to end\n//\tCLog::Log(LOGNOTICE, \"waiting for video thread to exit\");\n\n\tm_bAbortOutput = true;\n\tStopThread();\n\n\tm_messageQueue.End();\n\n//\tCLog::Log(LOGNOTICE, \"deleting video codec\");\n\tif (m_pVideoCodec)\n\t{\n\t\tm_pVideoCodec->ClearPicture(&m_picture);\n\t\tdelete m_pVideoCodec;\n\t\tm_pVideoCodec = NULL;\n\t}\n\n\tif (m_pTempOverlayPicture)\n\t{\n\t\tCDVDCodecUtils::FreePicture(m_pTempOverlayPicture);\n\t\tm_pTempOverlayPicture = NULL;\n\t}\n}\n\nbool CVideoPlayerVideo::AcceptsData()\n{\n\tbool full = m_messageQueue.IsFull();\n\treturn !full;\n}\n\nvoid CVideoPlayerVideo::Process()\n{\n//\tCLog::Log(LOGNOTICE, \"running thread: video_thread\");\n\n\tmemset(&m_picture, 0, sizeof(DVDVideoPicture));\n\n\tdouble pts = 0;\n\tdouble frametime = (double)DVD_TIME_BASE / m_fFrameRate;\n\n\tint iDropped = 0; //frames dropped in a row\n\tbool bRequestDrop = false;\n\tint iDropDirective;\n\n\tm_videoStats.Start();\n\tm_droppingStats.Reset();\n\tm_iDroppedFrames = 0;\n\tm_rewindStalled = false;\n\n\twhile (!m_bStop)\n\t{\n\t\tint iQueueTimeOut = (int)(m_stalled ? frametime : frametime * 10) / 1000;\n\t\tint iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_syncState == IDVDStreamPlayer::SYNC_INSYNC) ? 1 : 0;\n\n\t\tif (m_syncState == IDVDStreamPlayer::SYNC_WAITSYNC)\n\t\t\tiPriority = 1;\n\n\t\tif (m_paused)\n\t\t\tiPriority = 1;\n\n\t\tCDVDMsg* pMsg;\n\t\tMsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, iQueueTimeOut, iPriority);\n\n\t\tif (MSGQ_IS_ERROR(ret))\n\t\t{\n\t\t//\tCLog::Log(LOGERROR, \"Got MSGQ_ABORT or MSGO_IS_ERROR return true\");\n\t\t\tbreak;\n\t\t} else if (ret == MSGQ_TIMEOUT)\n\t\t{\n\t\t\t// if we only wanted priority messages, this isn't a stall\n\t\t\tif (iPriority)\n\t\t\t\tcontinue;\n\n\t\t\t// check if decoder has produced some output\n\t\t\tm_pVideoCodec->SetCodecControl(DVD_CODEC_CTRL_DRAIN);\n\t\t\tint decoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\t\t\tProcessDecoderOutput(decoderState, frametime, pts);\n\n\t\t\t//Okey, start rendering at stream fps now instead, we are likely in a stillframe\n\t\t\tif (!m_stalled)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGINFO, \"CVideoPlayerVideo - Stillframe detected, switching to forced %f fps\", m_fFrameRate);\n\t\t\t\tm_stalled = true;\n\t\t\t\tpts += frametime * 4;\n\t\t\t}\n\n\t\t\t//Waiting timed out, output last picture\n\t\t\tif (m_picture.iFlags & DVP_FLAG_ALLOCATED)\n\t\t\t{\n\t\t\t\tOutputPicture(&m_picture, pts);\n\t\t\t\tpts += frametime;\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE))\n\t\t{\n\t\t\tif (((CDVDMsgGeneralSynchronize*)pMsg)->Wait(100, SYNCSOURCE_VIDEO))\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo - CDVDMsg::GENERAL_SYNCHRONIZE\");\n\t\t\t} else\n\t\t\t\tm_messageQueue.Put(pMsg->AddRef(), 1); /* push back as prio message, to process other prio messages */\n\t\t\tm_droppingStats.Reset();\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))\n\t\t{\n\t\t\tpts = static_cast<CDVDMsgDouble*>(pMsg)->m_value;\n\n\t\t\tm_syncState = IDVDStreamPlayer::SYNC_INSYNC;\n\t\t\tm_droppingStats.Reset();\n\t\t\tm_rewindStalled = false;\n\n\t\t\t//CLog::Log(LOGDEBUG, \"CVideoPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f)\", pts);\n\t\t} else if (pMsg->IsType(CDVDMsg::VIDEO_SET_ASPECT))\n\t\t{\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo - CDVDMsg::VIDEO_SET_ASPECT\");\n\t\t\tm_fForcedAspectRatio = *((CDVDMsgDouble*)pMsg);\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))\n\t\t{\n\t\t\tif (m_pVideoCodec)\n\t\t\t\tm_pVideoCodec->Reset();\n\t\t\tm_picture.iFlags &= ~DVP_FLAG_ALLOCATED;\n\t\t\tm_packets.clear();\n\t\t\tm_droppingStats.Reset();\n\t\t\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\t\t\tm_rewindStalled = false;\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CVideoPlayerVideo::Flush())\n\t\t{\n\t\t\tbool sync = static_cast<CDVDMsgBool*>(pMsg)->m_value;\n\t\t\tif (m_pVideoCodec)\n\t\t\t\tm_pVideoCodec->Reset();\n\t\t\tm_picture.iFlags &= ~DVP_FLAG_ALLOCATED;\n\t\t\tm_packets.clear();\n\t\t\tpts = 0;\n\t\t\tm_rewindStalled = false;\n\n\t\t//\tm_pullupCorrection.Flush();\n\t\t\t//we need to recalculate the framerate\n\t\t\t//! @todo this needs to be set on a streamchange instead\n\t\t\tResetFrameRateCalc();\n\t\t\tm_droppingStats.Reset();\n\n\t\t\tm_stalled = true;\n\t\t\tif (sync)\n\t\t\t\tm_syncState = IDVDStreamPlayer::SYNC_STARTING;\n\n\t\t\tm_renderManager.DiscardBuffer();\n\t\t} else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))\n\t\t{\n\t\t\tm_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;\n\t\t\tif (m_pVideoCodec)\n\t\t\t\tm_pVideoCodec->SetSpeed(m_speed);\n\t\t\tm_droppingStats.Reset();\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))\n\t\t{\n\t\t\tCDVDMsgVideoCodecChange* msg(static_cast<CDVDMsgVideoCodecChange*>(pMsg));\n\n\t\t\twhile (!m_bStop && m_pVideoCodec)\n\t\t\t{\n\t\t\t\tm_pVideoCodec->SetCodecControl(DVD_CODEC_CTRL_DRAIN);\n\t\t\t\tint decoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\n\t\t\t\tbool cont = ProcessDecoderOutput(decoderState, frametime, pts);\n\n\t\t\t\tif (!cont)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (decoderState & VC_BUFFER)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tOpenStream(msg->m_hints, msg->m_codec);\n\t\t\tmsg->m_codec = NULL;\n\t\t\tm_picture.iFlags &= ~DVP_FLAG_ALLOCATED;\n\t\t} else if (pMsg->IsType(CDVDMsg::VIDEO_DRAIN))\n\t\t{\n\t\t\twhile (!m_bStop && m_pVideoCodec)\n\t\t\t{\n\t\t\t\tm_pVideoCodec->SetCodecControl(DVD_CODEC_CTRL_DRAIN);\n\t\t\t\tint decoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\n\t\t\t\tbool cont = ProcessDecoderOutput(decoderState, frametime, pts);\n\n\t\t\t\tif (!cont)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (decoderState & VC_BUFFER)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (pMsg->IsType(CDVDMsg::GENERAL_PAUSE))\n\t\t{\n\t\t\tm_paused = static_cast<CDVDMsgBool*>(pMsg)->m_value;\n\t\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo - CDVDMsg::GENERAL_PAUSE: %d\", m_paused);\n\t\t} else if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))\n\t\t{\n\t\t\tDemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket();\n\t\t\tbool bPacketDrop = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop();\n\n\t\t\tif (m_stalled)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGINFO, \"CVideoPlayerVideo - Stillframe left, switching to normal playback\");\n\t\t\t\tm_stalled = false;\n\t\t\t}\n\n\t\t\tbRequestDrop = false;\n\t\t\tiDropDirective = CalcDropRequirement(pts);\n\t\t\tif (iDropDirective & EOS_VERYLATE)\n\t\t\t{\n\t\t\t\tif (m_bAllowDrop)\n\t\t\t\t{\n\t\t\t\t\tbRequestDrop = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tint codecControl = 0;\n\t\t\tif (iDropDirective & EOS_BUFFER_LEVEL)\n\t\t\t\tcodecControl |= DVD_CODEC_CTRL_HURRY;\n\t\t\tif (m_speed > DVD_PLAYSPEED_NORMAL)\n\t\t\t\tcodecControl |= DVD_CODEC_CTRL_NO_POSTPROC;\n\t\t\tif (bPacketDrop)\n\t\t\t\tcodecControl |= DVD_CODEC_CTRL_DROP;\n// \t\t\tif (!m_renderManager.Supports(RENDERFEATURE_ROTATION))\n// \t\t\t\tcodecControl |= DVD_CODEC_CTRL_ROTATE;\n\t\t\tm_pVideoCodec->SetCodecControl(codecControl);\n\t\t\tif (iDropDirective & EOS_DROPPED)\n\t\t\t{\n\t\t\t\tm_iDroppedFrames++;\n\t\t\t\tiDropped++;\n\t\t\t//\tm_pullupCorrection.Flush();\n\t\t\t}\n\n\t\t\tif (m_messageQueue.GetDataSize() == 0\n\t\t\t\t|| m_speed < 0)\n\t\t\t{\n\t\t\t\tbRequestDrop = false;\n\t\t\t\tm_iDroppedRequest = 0;\n\t\t\t\tm_iLateFrames = 0;\n\t\t\t}\n\n\t\t\t// if player want's us to drop this packet, do so nomatter what\n\t\t\tif (bPacketDrop)\n\t\t\t\tbRequestDrop = true;\n\n\t\t\t// tell codec if next frame should be dropped\n\t\t\t// problem here, if one packet contains more than one frame\n\t\t\t// both frames will be dropped in that case instead of just the first\n\t\t\t// decoder still needs to provide an empty image structure, with correct flags\n\t\t\tm_pVideoCodec->SetDropState(bRequestDrop);\n\n\t\t\tint iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts);\n\n\t\t\t// buffer packets so we can recover should decoder flush for some reason\n\t\t\tif (m_pVideoCodec->GetConvergeCount() > 0)\n\t\t\t{\n\t\t\t\tm_packets.emplace_back(pMsg, 0);\n\t\t\t\tif (m_packets.size() > m_pVideoCodec->GetConvergeCount()\n\t\t\t\t\t|| m_packets.size() * frametime > DVD_SEC_TO_TIME(10))\n\t\t\t\t\tm_packets.pop_front();\n\t\t\t}\n\n\t\t\tm_videoStats.AddSampleBytes(pPacket->iSize);\n\n\t\t\t// reset the request, the following while loop may break before\n\t\t\t// setting the flag to a new value\n\t\t\tbRequestDrop = false;\n\n\t\t\t// loop while no error and decoder produces pics\n\t\t\twhile (!m_bStop)\n\t\t\t{\n\t\t\t\tint dropped = m_iDroppedFrames;\n\t\t\t\tbool cont = ProcessDecoderOutput(iDecoderState, frametime, pts);\n\t\t\t\tiDropped += m_iDroppedFrames - dropped;\n\n\t\t\t\tif (!cont)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (iDecoderState & VC_BUFFER)\n\t\t\t\t\tbreak;\n\n\t\t\t\t// the decoder didn't need more data, flush the remaning buffer\n\t\t\t\tiDecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\t\t\t}\n\t\t}\n\n\t\t// all data is used by the decoder, we can safely free it now\n\t\tpMsg->Release();\n\t}\n\n\t// we need to let decoder release any picture retained resources.\n\tm_pVideoCodec->ClearPicture(&m_picture);\n}\n\nbool CVideoPlayerVideo::ProcessDecoderOutput(int &decoderState, double &frametime, double &pts)\n{\n\tstd::string sPostProcessType;\n\tbool bPostProcessDeint = false;\n//\tCDVDVideoPPFFmpeg mPostProcess(\"\");\n\n\t// if decoder was flushed, we need to seek back again to resume rendering\n\tif (decoderState & VC_FLUSHED)\n\t{\n\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo - video decoder was flushed\");\n\t\twhile (!m_packets.empty())\n\t\t{\n\t\t\tCDVDMsgDemuxerPacket* msg = (CDVDMsgDemuxerPacket*)m_packets.front().message->AddRef();\n\t\t\tm_packets.pop_front();\n\n\t\t\tm_messageQueue.Put(msg, 10);\n\t\t}\n\n\t\tm_pVideoCodec->Reset();\n\t\tm_packets.clear();\n\t\t//picture.iFlags &= ~DVP_FLAG_ALLOCATED;\n\t\tm_renderManager.DiscardBuffer();\n\t\treturn false;\n\t}\n\n\tif (decoderState & VC_REOPEN)\n\t{\n\t\twhile (!m_packets.empty())\n\t\t{\n\t\t\tCDVDMsgDemuxerPacket* msg = (CDVDMsgDemuxerPacket*)m_packets.front().message->AddRef();\n\t\t\tm_packets.pop_front();\n\t\t\tm_messageQueue.Put(msg, 10);\n\t\t}\n\n\t\tm_pVideoCodec->Reopen();\n\t\tm_packets.clear();\n\t\t//picture.iFlags &= ~DVP_FLAG_ALLOCATED;\n\t\tm_renderManager.DiscardBuffer();\n\t\treturn false;\n\t}\n\n\t// if decoder had an error, tell it to reset to avoid more problems\n\tif (decoderState & VC_ERROR)\n\t{\n\t//\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo - video decoder returned error\");\n\t\treturn false;\n\t}\n\n\t// check for a new picture\n\tif (decoderState & VC_PICTURE)\n\t{\n\t\t// try to retrieve the picture (should never fail!), unless there is a demuxer bug ofcours\n\t\tm_pVideoCodec->ClearPicture(&m_picture);\n\t\tif (m_pVideoCodec->GetPicture(&m_picture))\n\t\t{\n\t\t\tbool hasTimestamp = true;\n\n\t\t\tsPostProcessType.clear();\n\n\t\t\tif (m_picture.iDuration == 0.0)\n\t\t\t\tm_picture.iDuration = frametime;\n\n\t\t\t// validate picture timing,\n\t\t\t// if both dts/pts invalid, use pts calulated from picture.iDuration\n\t\t\t// if pts invalid use dts, else use picture.pts as passed\n\t\t\tif (m_picture.dts == DVD_NOPTS_VALUE && m_picture.pts == DVD_NOPTS_VALUE)\n\t\t\t{\n\t\t\t\tm_picture.pts = pts;\n\t\t\t\thasTimestamp = false;\n\t\t\t} else if (m_picture.pts == DVD_NOPTS_VALUE)\n\t\t\t\tm_picture.pts = m_picture.dts;\n\n\t\t\t/* use forced aspect if any */\n\t\t\tif (m_fForcedAspectRatio != 0.0f)\n\t\t\t\tm_picture.iDisplayWidth = (int)(m_picture.iDisplayHeight * m_fForcedAspectRatio);\n#if 0\n\t\t\tif (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_PostProcess)\n\t\t\t{\n\t\t\t\tif (!sPostProcessType.empty())\n\t\t\t\t\tsPostProcessType += \",\";\n\t\t\t\t// This is what mplayer uses for its \"high-quality filter combination\"\n\t\t\t\tsPostProcessType += g_advancedSettings.m_videoPPFFmpegPostProc;\n\t\t\t}\n\n\t\t\tif (!sPostProcessType.empty())\n\t\t\t{\n\t\t\t\tmPostProcess.SetType(sPostProcessType, bPostProcessDeint);\n\t\t\t\tif (mPostProcess.Process(&m_picture))\n\t\t\t\t\tmPostProcess.GetPicture(&m_picture);\n\t\t\t}\n#endif\n\t\t\t/* if frame has a pts (usually originiating from demux packet), use that */\n\t\t\tif (m_picture.pts != DVD_NOPTS_VALUE)\n\t\t\t{\n\t\t\t\tpts = m_picture.pts;\n\t\t\t}\n\n\t\t\tdouble extraDelay = 0.0;\n\t\t\tif (m_picture.iRepeatPicture)\n\t\t\t{\n\t\t\t\textraDelay = m_picture.iRepeatPicture * m_picture.iDuration;\n\t\t\t\tm_picture.iDuration += extraDelay;\n\t\t\t}\n\n\t\t\tint iResult = OutputPicture(&m_picture, pts + extraDelay);\n\n\t\t\tframetime = (double)DVD_TIME_BASE / m_fFrameRate;\n\n\t\t\tif (m_syncState == IDVDStreamPlayer::SYNC_STARTING &&\n\t\t\t\t!(iResult & EOS_DROPPED) &&\n\t\t\t\t!(m_picture.iFlags & DVP_FLAG_DROPPED))\n\t\t\t{\n\t\t\t\tm_syncState = IDVDStreamPlayer::SYNC_WAITSYNC;\n\t\t\t\tSStartMsg msg;\n\t\t\t\tmsg.player = VideoPlayer_VIDEO;\n\t\t\t\tmsg.cachetime = DVD_MSEC_TO_TIME(50); //! @todo implement\n\t\t\t\tmsg.cachetotal = DVD_MSEC_TO_TIME(100); //! @todo implement\n\t\t\t\tmsg.timestamp = hasTimestamp ? pts : DVD_NOPTS_VALUE;\n\t\t\t\tm_messageParent.Put(new CDVDMsgType<SStartMsg>(CDVDMsg::PLAYER_STARTED, msg));\n\t\t\t}\n\n\t\t\t// guess next frame pts. iDuration is always valid\n\t\t\tif (m_speed != 0)\n\t\t\t\tpts += m_picture.iDuration * m_speed / abs(m_speed);\n\n\t\t\tif (iResult & EOS_ABORT)\n\t\t\t{\n\t\t\t\t//if we break here and we directly try to decode again wihout\n\t\t\t\t//flushing the video codec things break for some reason\n\t\t\t\t//i think the decoder (libmpeg2 atleast) still has a pointer\n\t\t\t\t//to the data, and when the packet is freed that will fail.\n\t\t\t\tdecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ((iResult & EOS_DROPPED) && !(m_picture.iFlags & DVP_FLAG_DROPPED))\n\t\t\t{\n\t\t\t\tm_iDroppedFrames++;\n\t\t\t//\tm_pullupCorrection.Flush();\n\t\t\t}\n\t\t} else\n\t\t{\n\t\t//\tCLog::Log(LOGWARNING, \"Decoder Error getting videoPicture.\");\n\t\t\tm_pVideoCodec->Reset();\n\t\t}\n\t}\n\n\treturn true;\n}\n\nvoid CVideoPlayerVideo::OnExit()\n{\n//\tCLog::Log(LOGNOTICE, \"thread end: video_thread\");\n}\n\nvoid CVideoPlayerVideo::SetSpeed(int speed)\n{\n\tif (m_messageQueue.IsInited())\n\t\tm_messageQueue.Put(new CDVDMsgInt(CDVDMsg::PLAYER_SETSPEED, speed), 1);\n\telse\n\t\tm_speed = speed;\n}\n\nvoid CVideoPlayerVideo::Flush(bool sync)\n{\n\t/* flush using message as this get's called from VideoPlayer thread */\n\t/* and any demux packet that has been taken out of queue need to */\n\t/* be disposed of before we flush */\n\tm_messageQueue.Flush();\n\tm_messageQueue.Put(new CDVDMsgBool(CDVDMsg::GENERAL_FLUSH, sync), 1);\n\tm_bAbortOutput = true;\n}\n\n#ifdef HAS_VIDEO_PLAYBACK\nvoid CVideoPlayerVideo::ProcessOverlays(DVDVideoPicture* pSource, double pts)\n{\n\t// remove any overlays that are out of time\n\tif (m_syncState == IDVDStreamPlayer::SYNC_INSYNC)\n\t\tm_pOverlayContainer->CleanUp(pts - m_iSubtitleDelay);\n\n\tVecOverlays overlays;\n\n\t{\n\t\tCSingleLock lock(*m_pOverlayContainer);\n\n\t\tVecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays();\n\t\tVecOverlaysIter it = pVecOverlays->begin();\n\n\t\t//Check all overlays and render those that should be rendered, based on time and forced\n\t\t//Both forced and subs should check timing\n\t\twhile (it != pVecOverlays->end())\n\t\t{\n\t\t\tCDVDOverlay* pOverlay = *it++;\n\t\t\tif (!pOverlay->bForced && !m_bRenderSubs)\n\t\t\t\tcontinue;\n\n\t\t\tdouble pts2 = pOverlay->bForced ? pts : pts - m_iSubtitleDelay;\n\n\t\t\tif ((pOverlay->iPTSStartTime <= pts2 && (pOverlay->iPTSStopTime > pts2 || pOverlay->iPTSStopTime == 0LL)))\n\t\t\t{\n\t\t\t\tif (pOverlay->IsOverlayType(DVDOVERLAY_TYPE_GROUP))\n\t\t\t\t\toverlays.insert(overlays.end(), static_cast<CDVDOverlayGroup*>(pOverlay)->m_overlays.begin()\n\t\t\t\t\t, static_cast<CDVDOverlayGroup*>(pOverlay)->m_overlays.end());\n\t\t\t\telse\n\t\t\t\t\toverlays.push_back(pOverlay);\n\n\t\t\t}\n\t\t}\n\n\t\tfor (it = overlays.begin(); it != overlays.end(); ++it)\n\t\t{\n\t\t\tdouble pts2 = (*it)->bForced ? pts : pts - m_iSubtitleDelay;\n\n\t\t\tm_renderManager.AddOverlay(*it, pts2);\n\t\t}\n\t}\n\n\n}\n#endif\n\nstd::string CVideoPlayerVideo::GetStereoMode()\n{\n\tstd::string  stereo_mode;\n#if 0\n\tswitch (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_StereoMode)\n\t{\n\tcase RENDER_STEREO_MODE_SPLIT_VERTICAL:   stereo_mode = \"left_right\"; break;\n\tcase RENDER_STEREO_MODE_SPLIT_HORIZONTAL: stereo_mode = \"top_bottom\"; break;\n\tdefault:                                  stereo_mode = m_hints.stereo_mode; break;\n\t}\n\n\tif (CMediaSettings::GetInstance().GetCurrentVideoSettings().m_StereoInvert)\n\t\tstereo_mode = GetStereoModeInvert(stereo_mode);\n#endif\n\treturn stereo_mode;\n}\n\nint CVideoPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)\n{\n\tm_bAbortOutput = false;\n\n\t/* picture buffer is not allowed to be modified in this call */\n\tDVDVideoPicture picture(*src);\n\tDVDVideoPicture* pPicture = &picture;\n#if 0\n\t/* grab stereo mode from image if available */\n\tif (src->stereo_mode[0] && m_hints.stereo_mode.compare(src->stereo_mode) != 0)\n\t{\n\t\tm_hints.stereo_mode = src->stereo_mode;\n\t\t// signal about changes in video parameters\n\t\tm_messageParent.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE));\n\t}\n\n\t/* figure out steremode expected based on user settings and hints */\n\tunsigned int stereo_flags = GetStereoModeFlags(GetStereoMode());\n\n\tdouble config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate;\n#endif\n\tunsigned flags = 0;\n\tif (pPicture->color_range == 1)\n\t\tflags |= CONF_FLAGS_YUV_FULLRANGE;\n\n\tflags |= GetFlagsChromaPosition(pPicture->chroma_position)\n\t\t| GetFlagsColorMatrix(pPicture->color_matrix, pPicture->iWidth, pPicture->iHeight)\n\t\t| GetFlagsColorPrimaries(pPicture->color_primaries)\n\t\t| GetFlagsColorTransfer(pPicture->color_transfer);\n\n\n// \tif (m_bAllowFullscreen)\n// \t{\n// \t\tflags |= CONF_FLAGS_FULLSCREEN;\n// \t\tm_bAllowFullscreen = false; // only allow on first configure\n// \t}\n\n//\tflags |= stereo_flags;\n\n\tif (!m_renderManager.Configure(picture,\n\t\t0.0/*config_framerate*/,\n\t\tflags,\n\t\tm_hints.orientation,\n\t\tm_pVideoCodec->GetAllowedReferences()))\n\t{\n\t//\tCLog::Log(LOGERROR, \"%s - failed to configure renderer\", __FUNCTION__);\n\t\treturn EOS_ABORT;\n\t}\n\n\tint result = 0;\n\n\t//try to calculate the framerate\n//\tm_pullupCorrection.Add(pts);\n\tif (!m_stalled)\n\t\tCalcFrameRate();\n\n\t// signal to clock what our framerate is, it may want to adjust it's\n\t// speed to better match with our video renderer's output speed\n\tm_pClock->UpdateFramerate(m_fFrameRate);\n\n\t// calculate the time we need to delay this picture before displaying\n\tdouble iPlayingClock, iCurrentClock;\n\n\tiPlayingClock = m_pClock->GetClock(iCurrentClock, false); // snapshot current clock\n\n\tif (m_speed < 0)\n\t{\n\t\tdouble renderPts;\n\t\tint queued, discard;\n\t\tint lateframes;\n\t\tdouble inputPts = m_droppingStats.m_lastPts;\n\t\tm_renderManager.GetStats(lateframes, renderPts, queued, discard);\n\t\tif (pts > renderPts || queued > 0)\n\t\t{\n\t\t\tif (inputPts >= renderPts)\n\t\t\t{\n\t\t\t\tm_rewindStalled = true;\n\t\t\t\tSleep(50);\n\t\t\t}\n\t\t\treturn result | EOS_DROPPED;\n\t\t} else if (pts < iPlayingClock)\n\t\t{\n\t\t\treturn result | EOS_DROPPED;\n\t\t}\n\t} else if (m_speed > DVD_PLAYSPEED_NORMAL)\n\t{\n\t\tdouble renderPts;\n\t\tint lateframes;\n\t\tint bufferLevel, queued, discard;\n\t\tm_renderManager.GetStats(lateframes, renderPts, queued, discard);\n\t\tbufferLevel = queued + discard;\n\n\t\t// estimate the time it will take for the next frame to get rendered\n\t\t// drop the frame if it's late in regard to this estimation\n\t\tdouble diff = pts - renderPts;\n\t\tdouble mindiff = DVD_SEC_TO_TIME(1 / m_fFrameRate) * (bufferLevel + 1);\n\t\tif (diff < mindiff)\n\t\t{\n\t\t\tm_droppingStats.AddOutputDropGain(pts, 1);\n\t\t\treturn result | EOS_DROPPED;\n\t\t}\n\t}\n\n\tif ((pPicture->iFlags & DVP_FLAG_DROPPED))\n\t{\n\t\tm_droppingStats.AddOutputDropGain(pts, 1);\n\t//\tCLog::Log(LOGDEBUG, \"%s - dropped in output\", __FUNCTION__);\n\t\treturn result | EOS_DROPPED;\n\t}\n\n\t// set fieldsync if picture is interlaced\n//\tEINTERLACEMETHOD deintMethod = EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE;\n// \tEFIELDSYNC mDisplayField = FS_NONE;\n// \tif (pPicture->iFlags & DVP_FLAG_INTERLACED)\n// \t{\n// \t\tdeintMethod = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_InterlaceMethod;\n// \t\tif (m_processInfo.Supports(deintMethod))\n// \t\t{\n// \t\t\tif (pPicture->iFlags & DVP_FLAG_TOP_FIELD_FIRST)\n// \t\t\t\tmDisplayField = FS_TOP;\n// \t\t\telse\n// \t\t\t\tmDisplayField = FS_BOT;\n// \t\t} else\n// \t\t\tdeintMethod = EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE;\n// \t}\n\n\tint timeToDisplay = DVD_TIME_TO_MSEC(pts - iPlayingClock);\n\t// make sure waiting time is not negative\n\tint maxWaitTime = std::min(std::max(timeToDisplay + 500, 50), 500);\n\t// don't wait when going ff\n\tif (m_speed > DVD_PLAYSPEED_NORMAL)\n\t\tmaxWaitTime = std::max(timeToDisplay, 0);\n\tint buffer = m_renderManager.WaitForBuffer(m_bAbortOutput, maxWaitTime);\n\tif (buffer < 0)\n\t{\n\t\tm_droppingStats.AddOutputDropGain(pts, 1);\n\t\treturn EOS_DROPPED;\n\t}\n\n//\tProcessOverlays(pPicture, pts);\n\n\tint index = m_renderManager.AddVideoPicture(*pPicture);\n\n\t// video device might not be done yet\n\twhile (index < 0 && !m_bAbortOutput &&\n\t\tm_pClock->GetAbsoluteClock(false) < iCurrentClock + DVD_MSEC_TO_TIME(500))\n\t{\n\t\tSleep(1);\n\t\tindex = m_renderManager.AddVideoPicture(*pPicture);\n\t}\n\n\tif (index < 0)\n\t{\n\t\tm_droppingStats.AddOutputDropGain(pts, 1);\n\t\treturn EOS_DROPPED;\n\t}\n\n\tm_renderManager.FlipPage(m_bAbortOutput, pts, (m_syncState == ESyncState::SYNC_STARTING));\n\n\treturn result;\n}\n\nstd::string CVideoPlayerVideo::GetPlayerInfo()\n{\n\treturn \"\";\n#if 0\n\tstd::ostringstream s;\n\ts << \"vq:\" << std::setw(2) << std::min(99, GetLevel()) << \"%\";\n\ts << \", Mb/s:\" << std::fixed << std::setprecision(2) << (double)GetVideoBitrate() / (1024.0*1024.0);\n\ts << \", fr:\" << std::fixed << std::setprecision(3) << m_fFrameRate;\n\ts << \", drop:\" << m_iDroppedFrames;\n\ts << \", skip:\" << m_renderManager.GetSkippedFrames();\n\n\tint pc = m_pullupCorrection.GetPatternLength();\n\tif (pc > 0)\n\t\ts << \", pc:\" << pc;\n\telse\n\t\ts << \", pc:none\";\n\n\treturn s.str();\n#endif\n}\n\nint CVideoPlayerVideo::GetVideoBitrate()\n{\n\treturn (int)m_videoStats.GetBitrate();\n}\n\nvoid CVideoPlayerVideo::ResetFrameRateCalc()\n{\n#if 0\n\tm_fStableFrameRate = 0.0;\n\tm_iFrameRateCount = 0;\n\tm_iFrameRateLength = 1;\n\tm_iFrameRateErr = 0;\n\n\tm_bAllowDrop = (!m_bCalcFrameRate && CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ScalingMethod != VS_SCALINGMETHOD_AUTO) ||\n\t\tg_advancedSettings.m_videoFpsDetect == 0;\n#endif\n}\n\ndouble CVideoPlayerVideo::GetCurrentPts()\n{\n\tdouble renderPts;\n\tint sleepTime;\n\tint queued, discard;\n\n\t// get render stats\n\tm_renderManager.GetStats(sleepTime, renderPts, queued, discard);\n\n\tif (renderPts == DVD_NOPTS_VALUE)\n\t\treturn DVD_NOPTS_VALUE;\n\telse if (m_stalled)\n\t\treturn DVD_NOPTS_VALUE;\n\telse if (m_speed == DVD_PLAYSPEED_NORMAL)\n\t{\n\t\tif (renderPts < 0)\n\t\t\trenderPts = 0;\n\t}\n\treturn renderPts;\n}\n\n#define MAXFRAMERATEDIFF   0.01\n#define MAXFRAMESERR    1000\n\nvoid CVideoPlayerVideo::CalcFrameRate()\n{\n#if 0\n\tif (m_iFrameRateLength >= 128 || g_advancedSettings.m_videoFpsDetect == 0)\n\t\treturn; //don't calculate the fps\n\n\t//only calculate the framerate if sync playback to display is on, adjust refreshrate is on,\n\t//or scaling method is set to auto\n\tif (!m_bCalcFrameRate && CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ScalingMethod != VS_SCALINGMETHOD_AUTO)\n\t{\n\t\tResetFrameRateCalc();\n\t\treturn;\n\t}\n\n\tif (!m_pullupCorrection.HasFullBuffer())\n\t\treturn; //we can only calculate the frameduration if m_pullupCorrection has a full buffer\n\n\t//see if m_pullupCorrection was able to detect a pattern in the timestamps\n\t//and is able to calculate the correct frame duration from it\n\tdouble frameduration = m_pullupCorrection.GetFrameDuration();\n\tif (m_pullupCorrection.VFRDetection())\n\t\tframeduration = m_pullupCorrection.GetMinFrameDuration();\n\n\tif ((frameduration == DVD_NOPTS_VALUE) ||\n\t\t((g_advancedSettings.m_videoFpsDetect == 1) && ((m_pullupCorrection.GetPatternLength() > 1) && !m_pullupCorrection.VFRDetection())))\n\t{\n\t\t//reset the stored framerates if no good framerate was detected\n\t\tm_fStableFrameRate = 0.0;\n\t\tm_iFrameRateCount = 0;\n\t\tm_iFrameRateErr++;\n\n\t\tif (m_iFrameRateErr == MAXFRAMESERR && m_iFrameRateLength == 1)\n\t\t{\n\t\t\tCLog::Log(LOGDEBUG, \"%s counted %i frames without being able to calculate the framerate, giving up\", __FUNCTION__, m_iFrameRateErr);\n\t\t\tm_bAllowDrop = true;\n\t\t\tm_iFrameRateLength = 128;\n\t\t}\n\t\treturn;\n\t}\n\n\tdouble framerate = DVD_TIME_BASE / frameduration;\n\n\t//store the current calculated framerate if we don't have any yet\n\tif (m_iFrameRateCount == 0)\n\t{\n\t\tm_fStableFrameRate = framerate;\n\t\tm_iFrameRateCount++;\n\t}\n\t//check if the current detected framerate matches with the stored ones\n\telse if (fabs(m_fStableFrameRate / m_iFrameRateCount - framerate) <= MAXFRAMERATEDIFF)\n\t{\n\t\tm_fStableFrameRate += framerate; //store the calculated framerate\n\t\tm_iFrameRateCount++;\n\n\t\t//if we've measured m_iFrameRateLength seconds of framerates,\n\t\tif (m_iFrameRateCount >= MathUtils::round_int(framerate) * m_iFrameRateLength)\n\t\t{\n\t\t\t//store the calculated framerate if it differs too much from m_fFrameRate\n\t\t\tif (fabs(m_fFrameRate - (m_fStableFrameRate / m_iFrameRateCount)) > MAXFRAMERATEDIFF || m_bFpsInvalid)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGDEBUG, \"%s framerate was:%f calculated:%f\", __FUNCTION__, m_fFrameRate, m_fStableFrameRate / m_iFrameRateCount);\n\t\t\t\tm_fFrameRate = m_fStableFrameRate / m_iFrameRateCount;\n\t\t\t\tm_bFpsInvalid = false;\n\t\t\t\tm_processInfo.SetVideoFps(m_fFrameRate);\n\t\t\t}\n\n\t\t\t//reset the stored framerates\n\t\t\tm_fStableFrameRate = 0.0;\n\t\t\tm_iFrameRateCount = 0;\n\t\t\tm_iFrameRateLength *= 2; //double the length we should measure framerates\n\n\t\t\t//we're allowed to drop frames because we calculated a good framerate\n\t\t\tm_bAllowDrop = true;\n\t\t}\n\t} else //the calculated framerate didn't match, reset the stored ones\n\t{\n\t\tm_fStableFrameRate = 0.0;\n\t\tm_iFrameRateCount = 0;\n\t}\n#endif\n}\n\nint CVideoPlayerVideo::CalcDropRequirement(double pts)\n{\n\tint result = 0;\n\tint lateframes;\n\tdouble iDecoderPts, iRenderPts;\n\tint iSkippedPicture = -1;\n\tint iDroppedFrames = -1;\n\tint    iBufferLevel;\n\tint    queued, discard;\n\n\tm_droppingStats.m_lastPts = pts;\n\n\t// get decoder stats\n\tif (!m_pVideoCodec->GetCodecStats(iDecoderPts, iDroppedFrames, iSkippedPicture))\n\t\tiDecoderPts = pts;\n\tif (iDecoderPts == DVD_NOPTS_VALUE)\n\t\tiDecoderPts = pts;\n\n\t// get render stats\n\tm_renderManager.GetStats(lateframes, iRenderPts, queued, discard);\n\tiBufferLevel = queued + discard;\n\n\tif (iBufferLevel < 0)\n\t\tresult |= EOS_BUFFER_LEVEL;\n\telse if (iBufferLevel < 2)\n\t{\n\t\tresult |= EOS_BUFFER_LEVEL;\n// \t\tif (g_advancedSettings.CanLogComponent(LOGVIDEO))\n// \t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo::CalcDropRequirement - hurry: %d\", iBufferLevel);\n\t}\n\n\tif (m_bAllowDrop)\n\t{\n\t\tif (iSkippedPicture > 0)\n\t\t{\n\t\t\tCDroppingStats::CGain gain;\n\t\t\tgain.frames = iSkippedPicture;\n\t\t\tgain.pts = iDecoderPts;\n\t\t\tm_droppingStats.m_gain.push_back(gain);\n\t\t\tm_droppingStats.m_totalGain += gain.frames;\n\t\t\tresult |= EOS_DROPPED;\n// \t\t\tif (g_advancedSettings.CanLogComponent(LOGVIDEO))\n// \t\t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo::CalcDropRequirement - dropped pictures, lateframes: %d, Bufferlevel: %d, dropped: %d\", lateframes, iBufferLevel, iSkippedPicture);\n\t\t}\n\t\tif (iDroppedFrames > 0)\n\t\t{\n\t\t\tCDroppingStats::CGain gain;\n\t\t\tgain.frames = iDroppedFrames;\n\t\t\tgain.pts = iDecoderPts;\n\t\t\tm_droppingStats.m_gain.push_back(gain);\n\t\t\tm_droppingStats.m_totalGain += iDroppedFrames;\n\t\t\tresult |= EOS_DROPPED;\n// \t\t\tif (g_advancedSettings.CanLogComponent(LOGVIDEO))\n// \t\t\t\tCLog::Log(LOGDEBUG, \"CVideoPlayerVideo::CalcDropRequirement - dropped in decoder, lateframes: %d, Bufferlevel: %d, dropped: %d\", lateframes, iBufferLevel, iDroppedFrames);\n\t\t}\n\t}\n\n\t// subtract gains\n\twhile (!m_droppingStats.m_gain.empty() &&\n\t\tiRenderPts >= m_droppingStats.m_gain.front().pts)\n\t{\n\t\tm_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().frames;\n\t\tm_droppingStats.m_gain.pop_front();\n\t}\n\n\t// calculate lateness\n\tint lateness = lateframes - m_droppingStats.m_totalGain;\n\n\tif (lateness > 0 && m_speed)\n\t{\n\t\tresult |= EOS_VERYLATE;\n\t}\n\treturn result;\n}\n\nvoid CDroppingStats::Reset()\n{\n\tm_gain.clear();\n\tm_totalGain = 0;\n}\n\nvoid CDroppingStats::AddOutputDropGain(double pts, int frames)\n{\n\tCDroppingStats::CGain gain;\n\tgain.frames = frames;\n\tgain.pts = pts;\n\tm_gain.push_back(gain);\n\tm_totalGain += frames;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoPlayerVideo.h",
    "content": "#pragma once\n#include \"Thread.h\"\n#include \"IVideoPlayer.h\"\n#include \"VideoCodec.h\"\n#include \"BitstreamStats.h\"\n#include <deque>\n#include <list>\n#include \"MessageQueue.h\"\n\nNS_KRMOVIE_BEGIN\n\nclass CDemuxStreamVideo;\nclass CRenderManager;\n#define VIDEO_PICTURE_QUEUE_SIZE 1\n\n#define EOS_ABORT 1\n#define EOS_DROPPED 2\n#define EOS_VERYLATE 4\n#define EOS_BUFFER_LEVEL 8\n\nclass CDroppingStats\n{\npublic:\n\tvoid Reset();\n\tvoid AddOutputDropGain(double pts, int frames);\n\tstruct CGain\n\t{\n\t\tint frames;\n\t\tdouble pts;\n\t};\n\tstd::deque<CGain> m_gain;\n\tdouble m_totalGain;\n\tdouble m_lastPts;\n};\n\nclass CDVDClock;\nclass CVideoPlayerVideo : public CThread, public IDVDStreamPlayerVideo\n{\npublic:\n\tCVideoPlayerVideo(CDVDClock* pClock\n\t//\t, CDVDOverlayContainer* pOverlayContainer\n\t\t, CDVDMessageQueue& parent\n\t\t, CRenderManager& renderManager,\n\t\tCProcessInfo &processInfo);\n\tvirtual ~CVideoPlayerVideo();\n\n\tbool OpenStream(CDVDStreamInfo &hint);\n\tvoid CloseStream(bool bWaitForBuffers);\n\n\tvoid Flush(bool sync);\n\tbool AcceptsData();\n\tbool HasData() const { return m_messageQueue.GetDataSize() > 0; }\n\tint  GetLevel() { return m_messageQueue.GetLevel(); }\n\tbool IsInited() const { return m_messageQueue.IsInited(); }\n\tvoid SendMessage(CDVDMsg* pMsg, int priority = 0) { m_messageQueue.Put(pMsg, priority); }\n\tvoid FlushMessages() { m_messageQueue.Flush(); }\n\n\tvoid EnableSubtitle(bool bEnable) { m_bRenderSubs = bEnable; }\n\tbool IsSubtitleEnabled() { return m_bRenderSubs; }\n//\tvoid EnableFullscreen(bool bEnable) { m_bAllowFullscreen = bEnable; }\n\tdouble GetSubtitleDelay() { return m_iSubtitleDelay; }\n\tvoid SetSubtitleDelay(double delay) { m_iSubtitleDelay = delay; }\n\tbool IsStalled() const override { return m_stalled; }\n\tbool IsRewindStalled() const override { return m_rewindStalled; }\n\tdouble GetCurrentPts();\n\tdouble GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */\n\tint GetDecoderFreeSpace() { return 0; }\n\tstd::string GetPlayerInfo();\n\tint GetVideoBitrate();\n\tstd::string GetStereoMode();\n\tvoid SetSpeed(int iSpeed);\n\n\t// classes\n//\tCDVDOverlayContainer* m_pOverlayContainer;\n\tCDVDClock* m_pClock;\n\nprotected:\n\n\tvirtual void OnExit();\n\tvirtual void Process();\n\tbool ProcessDecoderOutput(int &decoderState, double &frametime, double &pts);\n\n\tint OutputPicture(const DVDVideoPicture* src, double pts);\n//\tvoid ProcessOverlays(DVDVideoPicture* pSource, double pts);\n\tvoid OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec);\n\n\tvoid ResetFrameRateCalc();\n\tvoid CalcFrameRate();\n\tint CalcDropRequirement(double pts);\n\n\tdouble m_iSubtitleDelay;\n\n\tint m_iLateFrames;\n\tint m_iDroppedFrames;\n\tint m_iDroppedRequest;\n\n\tdouble m_fFrameRate = 25;       //framerate of the video currently playing\n//\tbool m_bCalcFrameRate;     //if we should calculate the framerate from the timestamps\n//\tdouble m_fStableFrameRate; //place to store calculated framerates\n//\tint m_iFrameRateCount;     //how many calculated framerates we stored in m_fStableFrameRate\n\tbool m_bAllowDrop;         //we can't drop frames until we've calculated the framerate\n//\tint m_iFrameRateErr;       //how many frames we couldn't calculate the framerate, we give up after a while\n//\tint m_iFrameRateLength;    //how many seconds we should measure the framerate\n\t//this is increased exponentially from CVideoPlayerVideo::CalcFrameRate()\n\n\tbool m_bFpsInvalid;        // needed to ignore fps (e.g. dvd stills)\n//\tbool m_bAllowFullscreen;\n\tbool m_bRenderSubs;\n\tfloat m_fForcedAspectRatio;\n\tint m_speed;\n\tstd::atomic_bool m_stalled;\n\tstd::atomic_bool m_rewindStalled;\n\tbool m_paused;\n\tIDVDStreamPlayer::ESyncState m_syncState;\n\tstd::atomic_bool m_bAbortOutput;\n\n\tBitstreamStats m_videoStats;\n\n\tCDVDMessageQueue m_messageQueue;\n\tCDVDMessageQueue& m_messageParent;\n\tCDVDStreamInfo m_hints;\n\tCDVDVideoCodec* m_pVideoCodec;\n\tDVDVideoPicture* m_pTempOverlayPicture;\n//\tCPullupCorrection m_pullupCorrection;\n\tstd::list<DVDMessageListItem> m_packets;\n\tCDroppingStats m_droppingStats;\n\tCRenderManager& m_renderManager;\n\tDVDVideoPicture m_picture;\n};\n\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoReferenceClock.cpp",
    "content": "#include \"VideoReferenceClock.h\"\n// #ifdef _MSC_VER\n// #include \"videosync/VideoSyncD3D.h\"\n// #endif\n\n#include \"MathUtils.h\"\n#include \"TimeUtils.h\"\n#include <algorithm>\n\nNS_KRMOVIE_BEGIN\nCVideoReferenceClock::CVideoReferenceClock() //: CThread()\n{\n\tm_SystemFrequency = CurrentHostFrequency();\n  m_ClockSpeed = 1.0;\n  m_ClockOffset = 0;\n  m_TotalMissedVblanks = 0;\n  m_UseVblank = false;\n\n  m_CurrTime = 0;\n  m_LastIntTime = 0;\n  m_CurrTimeFract = 0.0;\n  m_RefreshRate = 0.0;\n  m_MissedVblanks = 0;\n  m_VblankTime = 0;\n\n//  m_pVideoSync = nullptr;\n\n  Start();\n}\n\nCVideoReferenceClock::~CVideoReferenceClock()\n{\n  //StopThread();\n}\n\nvoid CVideoReferenceClock::Start()\n{\n#if 0\n\tm_ClockOffset = CurrentHostCounter();\n  if(CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK) && !IsRunning())\n    Create();\n#endif\n}\n\nvoid CVideoReferenceClock::CBUpdateClock(int NrVBlanks, uint64_t time, CVideoReferenceClock *clock)\n{\n  {\n    CSingleLock lock(clock->m_CritSection);\n    clock->m_VblankTime = time;\n    clock->UpdateClock(NrVBlanks, true);\n  }\n}\n#if 0\nvoid CVideoReferenceClock::Process()\n{\n  bool SetupSuccess = false;\n  int64_t Now;\n\n  while(!m_bStop)\n  {\n    //set up the vblank clock\n\n#ifdef _MSC_VER\n\t  m_pVideoSync = new CVideoSyncD3D(this);\n#endif\n#if defined(HAVE_X11)\n  std::string gpuvendor = g_Windowing.GetRenderVendor();\n  std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower);\n  if ((gpuvendor.compare(0, 5, \"intel\") == 0 ||\n       gpuvendor.compare(0, 5, \"x.org\") == 0)) // AMD\n    m_pVideoSync = new CVideoSyncDRM(this);\n#if defined(HAS_GLX)\n  else\n    m_pVideoSync = new CVideoSyncGLX(this);\n#endif\n#elif defined(TARGET_WINDOWS)\n    m_pVideoSync = new CVideoSyncD3D(this);\n#elif defined(TARGET_DARWIN_OSX)\n    m_pVideoSync = new CVideoSyncOsx(this);\n#elif defined(TARGET_DARWIN_IOS)\n    m_pVideoSync = new CVideoSyncIos(this);\n#elif defined(TARGET_RASPBERRY_PI)\n    m_pVideoSync = new CVideoSyncPi(this);\n#elif defined(HAS_IMXVPU)\n    m_pVideoSync = new CVideoSyncIMX(this);\n#elif defined(TARGET_ANDROID)\n    m_pVideoSync = new CVideoSyncAndroid(this);\n#endif\n\n    if (m_pVideoSync)\n    {\n      SetupSuccess = m_pVideoSync->Setup(CBUpdateClock);\n      UpdateRefreshrate();\n    }\n\n\tm_CritSection.lock();\n\tNow = CurrentHostCounter();\n    m_CurrTime = Now + m_ClockOffset; //add the clock offset from the previous time we stopped\n    m_LastIntTime = m_CurrTime;\n    m_CurrTimeFract = 0.0;\n    m_ClockSpeed = 1.0;\n    m_TotalMissedVblanks = 0;\n    m_MissedVblanks = 0;\n\n    if (SetupSuccess)\n    {\n      m_UseVblank = true;          //tell other threads we're using vblank as clock\n      m_VblankTime = Now;          //initialize the timestamp of the last vblank\n\t  m_CritSection.unlock();\n\n      //run the clock\n      m_pVideoSync->Run(m_bStop);\n    }\n    else\n    {\n\t\tm_CritSection.unlock();\n//      CLog::Log(LOGDEBUG, \"CVideoReferenceClock: Setup failed, falling back to CurrentHostCounter()\");\n    }\n\n\t{\n\t\tCSingleLock SingleLock(m_CritSection);\n\t\tm_UseVblank = false;                       //we're back to using the systemclock\n\t\tNow = CurrentHostCounter();                //set the clockoffset between the vblank clock and systemclock\n\t\tm_ClockOffset = m_CurrTime - Now;\n\t}\n\n    //clean up the vblank clock\n    if (m_pVideoSync)\n    {\n      m_pVideoSync->Cleanup();\n      delete m_pVideoSync;\n      m_pVideoSync = nullptr;\n    }\n\n    if (!SetupSuccess)\n      break;\n  }\n}\n#endif\n//this is called from the vblank run function and from CVideoReferenceClock::Wait in case of a late update\nvoid CVideoReferenceClock::UpdateClock(int NrVBlanks, bool CheckMissed)\n{\n  if (CheckMissed) //set to true from the vblank run function, set to false from Wait and GetTime\n  {\n    if (NrVBlanks < m_MissedVblanks) //if this is true the vblank detection in the run function is wrong\n//       CLog::Log(LOGDEBUG, \"CVideoReferenceClock: detected %i vblanks, missed %i, refreshrate might have changed\",\n//                 NrVBlanks, m_MissedVblanks);\n\n    NrVBlanks -= m_MissedVblanks; //subtract the vblanks we missed\n    m_MissedVblanks = 0;\n  }\n  else\n  {\n    m_MissedVblanks += NrVBlanks;      //tell the vblank clock how many vblanks it missed\n    m_TotalMissedVblanks += NrVBlanks; //for the codec information screen\n    m_VblankTime += m_SystemFrequency * static_cast<int64_t>(NrVBlanks) / MathUtils::round_int(m_RefreshRate); //set the vblank time forward\n  }\n\n  if (NrVBlanks > 0) //update the clock with the adjusted frequency if we have any vblanks\n  {\n    double increment = UpdateInterval() * NrVBlanks;\n    double integer   = floor(increment);\n    m_CurrTime      += static_cast<int64_t>(integer + 0.5); //make sure it gets correctly converted to int\n\n    //accumulate what we lost due to rounding in m_CurrTimeFract, then add the integer part of that to m_CurrTime\n    m_CurrTimeFract += increment - integer;\n    integer          = floor(m_CurrTimeFract);\n    m_CurrTime      += static_cast<int64_t>(integer + 0.5);\n    m_CurrTimeFract -= integer;\n  }\n}\n\ndouble CVideoReferenceClock::UpdateInterval() const\n{\n  return m_ClockSpeed / m_RefreshRate * static_cast<double>(m_SystemFrequency);\n}\n\n//called from dvdclock to get the time\nint64_t CVideoReferenceClock::GetTime(bool interpolated /* = true*/)\n{\n  CSingleLock SingleLock(m_CritSection);\n\n  //when using vblank, get the time from that, otherwise use the systemclock\n  if (m_UseVblank)\n  {\n    int64_t  NextVblank;\n    int64_t  Now;\n\n    Now = CurrentHostCounter();        //get current system time\n    NextVblank = TimeOfNextVblank();   //get time when the next vblank should happen\n\n    while(Now >= NextVblank)  //keep looping until the next vblank is in the future\n    {\n      UpdateClock(1, false);           //update clock when next vblank should have happened already\n      NextVblank = TimeOfNextVblank(); //get time when the next vblank should happen\n    }\n\n    if (interpolated)\n    {\n      //interpolate from the last time the clock was updated\n      double elapsed = static_cast<double>(Now - m_VblankTime) * m_ClockSpeed;\n      //don't interpolate more than 2 vblank periods\n      elapsed = std::min(elapsed, UpdateInterval() * 2.0);\n\n      //make sure the clock doesn't go backwards\n      int64_t intTime = m_CurrTime + static_cast<int64_t>(elapsed);\n      if (intTime > m_LastIntTime)\n        m_LastIntTime = intTime;\n\n      return m_LastIntTime;\n    }\n    else\n    {\n      return m_CurrTime;\n    }\n  }\n  else\n  {\n    return CurrentHostCounter() + m_ClockOffset;\n  }\n}\n\nvoid CVideoReferenceClock::SetSpeed(double Speed)\n{\n  CSingleLock SingleLock(m_CritSection);\n  //VideoPlayer can change the speed to fit the rereshrate\n  if (m_UseVblank)\n  {\n    if (Speed != m_ClockSpeed)\n    {\n      m_ClockSpeed = Speed;\n //     CLog::Log(LOGDEBUG, \"CVideoReferenceClock: Clock speed %f%%\", m_ClockSpeed * 100.0);\n    }\n  }\n}\n\ndouble CVideoReferenceClock::GetSpeed()\n{\n  CSingleLock SingleLock(m_CritSection);\n\n  //VideoPlayer needs to know the speed for the resampler\n  if (m_UseVblank)\n    return m_ClockSpeed;\n  else\n    return 1.0;\n}\n\nvoid CVideoReferenceClock::UpdateRefreshrate()\n{\n  CSingleLock SingleLock(m_CritSection);\n  m_RefreshRate = 60/*m_pVideoSync->GetFps()*/;\n  m_ClockSpeed = 1.0;\n\n//  CLog::Log(LOGDEBUG, \"CVideoReferenceClock: Detected refreshrate: %.3f hertz\", m_RefreshRate);\n}\n\n//VideoPlayer needs to know the refreshrate for matching the fps of the video playing to it\ndouble CVideoReferenceClock::GetRefreshRate(double* interval /*= NULL*/)\n{\n  CSingleLock SingleLock(m_CritSection);\n\n  if (m_UseVblank)\n  {\n    if (interval)\n      *interval = m_ClockSpeed / m_RefreshRate;\n\n    return m_RefreshRate;\n  }\n  else\n    return -1;\n}\n\n#define MAXVBLANKDELAY 13LL\n//guess when the next vblank should happen,\n//based on the refreshrate and when the previous one happened\n//increase that by 30% to allow for errors\nint64_t CVideoReferenceClock::TimeOfNextVblank() const\n{\n  return m_VblankTime + (m_SystemFrequency / MathUtils::round_int(m_RefreshRate) * MAXVBLANKDELAY / 10LL);\n}\n\n//for the codec information screen\nbool CVideoReferenceClock::GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate)\n{\n  CSingleLock SingleLock(m_CritSection);\n\n  if (m_UseVblank)\n  {\n    MissedVblanks = m_TotalMissedVblanks;\n    ClockSpeed = m_ClockSpeed;\n    RefreshRate = m_RefreshRate;\n    return true;\n  }\n  return false;\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoReferenceClock.h",
    "content": "#pragma once\n#include \"Thread.h\"\n\nNS_KRMOVIE_BEGIN\nclass CVideoSync;\n\nclass CVideoReferenceClock /*: public CThread*/\n{\n  public:\n    CVideoReferenceClock();\n    virtual ~CVideoReferenceClock();\n\n    int64_t GetTime(bool interpolated = true);\n    void    SetSpeed(double Speed);\n    double  GetSpeed();\n    double  GetRefreshRate(double* interval = nullptr);\n    bool    GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate);\n\n  private:\n  //  void    Process() override;\n    void Start();\n    void    UpdateRefreshrate();\n    void    UpdateClock(int NrVBlanks, bool CheckMissed);\n    double  UpdateInterval() const;\n    int64_t TimeOfNextVblank() const;\n    static void CBUpdateClock(int NrVBlanks, uint64_t time, CVideoReferenceClock *clock);\n\n    int64_t m_CurrTime;          //the current time of the clock when using vblank as clock source\n    int64_t m_LastIntTime;       //last interpolated clock value, to make sure the clock doesn't go backwards\n    double  m_CurrTimeFract;     //fractional part that is lost due to rounding when updating the clock\n    double  m_ClockSpeed;        //the frequency of the clock set by VideoPlayer\n    int64_t m_ClockOffset;       //the difference between the vblank clock and systemclock, set when vblank clock is stopped\n    int64_t m_SystemFrequency;   //frequency of the systemclock\n\n    bool    m_UseVblank;         //set to true when vblank is used as clock source\n    double  m_RefreshRate;       //current refreshrate\n    int     m_MissedVblanks;     //number of clock updates missed by the vblank clock\n    int     m_TotalMissedVblanks;//total number of clock updates missed, used by codec information screen\n    int64_t m_VblankTime;        //last time the clock was updated when using vblank as clock\n\n    CCriticalSection m_CritSection;\n\n//    CVideoSync *m_pVideoSync;\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoRenderer.cpp",
    "content": "#include \"VideoRenderer.h\"\n#include \"RenderFlags.h\"\n#include \"MathUtils.h\"\n\n/* to use the same as player */\n#include \"Clock.h\"\n#include \"VideoCodec.h\"\n#include \"CodecUtils.h\"\n\n#include <deque>\n#include <thread>\n\nextern std::thread::id TVPMainThreadID;\nNS_KRMOVIE_BEGIN\n\nDispDeviceDesc g_graphicsContext;\nAppliactionDesc g_application;\nbool AppliactionDesc::IsCurrentThread() {\n\treturn std::this_thread::get_id() == TVPMainThreadID;\n}\n\nstatic void requeue(std::deque<int> &trg, std::deque<int> &src)\n{\n\ttrg.push_back(src.front());\n\tsrc.pop_front();\n}\n\nstatic std::string GetRenderFormatName(ERenderFormat format)\n{\n\tswitch (format)\n\t{\n\tcase RENDER_FMT_YUV420P:   return \"YV12\";\n\tcase RENDER_FMT_YUV420P16: return \"YV12P16\";\n\tcase RENDER_FMT_YUV420P10: return \"YV12P10\";\n\tcase RENDER_FMT_NV12:      return \"NV12\";\n\tcase RENDER_FMT_UYVY422:   return \"UYVY\";\n\tcase RENDER_FMT_YUYV422:   return \"YUY2\";\n\tcase RENDER_FMT_VDPAU:     return \"VDPAU\";\n\tcase RENDER_FMT_VDPAU_420: return \"VDPAU_420\";\n\tcase RENDER_FMT_DXVA:      return \"DXVA\";\n\tcase RENDER_FMT_VAAPI:     return \"VAAPI\";\n\tcase RENDER_FMT_VAAPINV12: return \"VAAPI_NV12\";\n\tcase RENDER_FMT_OMXEGL:    return \"OMXEGL\";\n\tcase RENDER_FMT_CVBREF:    return \"BGRA\";\n\tcase RENDER_FMT_BYPASS:    return \"BYPASS\";\n\tcase RENDER_FMT_MEDIACODEC:return \"MEDIACODEC\";\n\tcase RENDER_FMT_MEDIACODECSURFACE:return \"MEDIACODECSURFACE\";\n\tcase RENDER_FMT_IMXMAP:    return \"IMXMAP\";\n\tcase RENDER_FMT_MMAL:      return \"MMAL\";\n\tcase RENDER_FMT_AML:       return \"AMLCODEC\";\n\tcase RENDER_FMT_NONE:      return \"NONE\";\n\t}\n\treturn \"UNKNOWN\";\n}\n\nvoid CRenderManager::CClockSync::Reset()\n{\n\tm_error = 0;\n\tm_errCount = 0;\n\tm_syncOffset = 0;\n\tm_enabled = false;\n}\n\n//unsigned int CRenderManager::m_nextCaptureId = 0;\n\nCRenderManager::CRenderManager(CDVDClock &clock, IRenderMsg *player) :\nm_pRenderer(nullptr),\nm_bTriggerUpdateResolution(false),\nm_bRenderGUI(true),\nm_waitForBufferCount(0),\nm_rendermethod(0),\n//m_renderedOverlay(false),\nm_renderDebug(false),\nm_renderState(STATE_UNCONFIGURED),\nm_displayLatency(0.0),\nm_QueueSize(2),\nm_QueueSkip(0),\nm_format(RENDER_FMT_NONE),\nm_width(0),\nm_height(0),\nm_dwidth(0),\nm_dheight(0),\nm_fps(0.0f),\nm_extended_format(0),\nm_orientation(0),\nm_NumberBuffers(0),\nm_lateframes(-1),\nm_presentpts(0.0),\nm_presentstep(PRESENT_IDLE),\nm_forceNext(false),\nm_presentsource(0),\nm_dvdClock(clock),\nm_playerPort(player)//,\n// m_captureWaitCounter(0),\n// m_hasCaptures(false)\n{\n\tm_videoDelay = 0;\n}\n\nCRenderManager::~CRenderManager()\n{\n//\tdelete m_pRenderer;\n}\n\nvoid CRenderManager::GetVideoRect(CRect &source, CRect &dest, CRect &view)\n{\n\tCSingleLock lock(m_statelock);\n\tif (m_pRenderer)\n\t\tm_pRenderer->GetVideoRect(source, dest, view);\n}\n\nfloat CRenderManager::GetAspectRatio()\n{\n\tCSingleLock lock(m_statelock);\n\tif (m_pRenderer)\n\t\treturn m_pRenderer->GetAspectRatio();\n\telse\n\t\treturn 1.0f;\n}\n\nbool CRenderManager::Configure(DVDVideoPicture& picture, float fps, unsigned flags, unsigned int orientation, int buffers)\n{\n\n\t// check if something has changed\n\t{\n\t\tCSingleLock lock(m_statelock);\n\n\t\tif (m_width == picture.iWidth &&\n\t\t\tm_height == picture.iHeight &&\n\t\t\tm_dwidth == picture.iDisplayWidth &&\n\t\t\tm_dheight == picture.iDisplayHeight &&\n\t\t\tm_fps == fps &&\n\t\t\t(m_flags & ~CONF_FLAGS_FULLSCREEN) == (flags & ~CONF_FLAGS_FULLSCREEN) &&\n\t\t\tm_format == picture.format &&\n\t\t\tm_extended_format == picture.extended_format &&\n\t\t\tm_orientation == orientation &&\n\t\t\tm_NumberBuffers == buffers &&\n\t\t\tm_pRenderer != NULL)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tstd::string formatstr = GetRenderFormatName(picture.format);\n//\tCLog::Log(LOGDEBUG, \"CRenderManager::Configure - change configuration. %dx%d. display: %dx%d. framerate: %4.2f. format: %s\", picture.iWidth, picture.iHeight, picture.iDisplayWidth, picture.iDisplayHeight, fps, formatstr.c_str());\n\n\t// make sure any queued frame was fully presented\n\t{\n\t\tCSingleLock lock(m_presentlock);\n\t\tTimer endtime(5000);\n\t\twhile (m_presentstep != PRESENT_IDLE)\n\t\t{\n\t\t\tif (endtime.IsTimePast())\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGWARNING, \"CRenderManager::Configure - timeout waiting for state\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tm_presentevent.wait_for(lock, std::chrono::milliseconds(endtime.MillisLeft()));\n\t\t}\n\t}\n\n\t{\n\t\tCSingleLock lock(m_statelock);\n\t\tm_width = picture.iWidth;\n\t\tm_height = picture.iHeight,\n\t\t\tm_dwidth = picture.iDisplayWidth;\n\t\tm_dheight = picture.iDisplayHeight;\n\t\tm_fps = fps;\n\t\tm_flags = flags;\n\t\tm_format = picture.format;\n\t\tm_extended_format = picture.extended_format;\n\t\tm_orientation = orientation;\n\t\tm_NumberBuffers = buffers;\n\t\tm_renderState = STATE_CONFIGURING;\n\t//\tm_stateEvent.Reset();\n\n\t\tCheckEnableClockSync();\n\n\t\tCSingleLock lock2(m_presentlock);\n\t\tm_presentstep = PRESENT_READY;\n\t\tm_presentevent.notify_all();\n\t}\n\n\treturn true;\n\n\tCSingleLock stateLock(m_stateMutex);\n\tif (m_stateEvent.wait_for(stateLock, std::chrono::milliseconds(1000)) == std::cv_status::timeout)\n\t{\n\t//\tCLog::Log(LOGWARNING, \"CRenderManager::Configure - timeout waiting for configure\");\n\t\treturn false;\n\t}\n\n\tCSingleLock lock(m_statelock);\n\tif (m_renderState != STATE_CONFIGURED)\n\t{\n\t//\tCLog::Log(LOGWARNING, \"CRenderManager::Configure - failed to configure\");\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool CRenderManager::Configure()\n{\n\t// lock all interfaces\n\tCSingleLock lock(m_statelock);\n\tCSingleLock lock2(m_presentlock);\n\tCSingleLock lock3(m_datalock);\n\n\tif (m_pRenderer && !m_pRenderer->HandlesRenderFormat(m_format))\n\t{\n\t\t//DeleteRenderer();\n\t}\n\n\tif (!m_pRenderer)\n\t{\n\t\tCreateRenderer();\n\t\tif (!m_pRenderer)\n\t\t\treturn false;\n\t}\n\n\tbool result = m_pRenderer->Configure(m_width, m_height, m_dwidth, m_dheight, m_fps, m_flags, m_format, m_extended_format, m_orientation);\n\tif (result)\n\t{\n\t\tCRenderInfo info = m_pRenderer->GetRenderInfo();\n\t\tint renderbuffers = info.optimal_buffer_size;\n\t\tm_QueueSize = renderbuffers;\n\t\tif (m_NumberBuffers > 0)\n\t\t\tm_QueueSize = std::min(m_NumberBuffers, renderbuffers);\n\n\t\tm_QueueSize = std::min(m_QueueSize, (int)info.max_buffer_size);\n\t\tm_QueueSize = std::min(m_QueueSize, NUM_BUFFERS);\n\t\tif (m_QueueSize < 2)\n\t\t{\n\t\t\tm_QueueSize = 2;\n\t\t//\tCLog::Log(LOGWARNING, \"CRenderManager::Configure - queue size too small (%d, %d, %d)\", m_QueueSize, renderbuffers, m_NumberBuffers);\n\t\t}\n\n\t\tm_pRenderer->SetBufferSize(m_QueueSize);\n\t\tm_pRenderer->Update();\n\n\t\tm_playerPort->UpdateRenderInfo(info);\n\n\t\tm_queued.clear();\n\t\tm_discard.clear();\n\t\tm_free.clear();\n\t\tm_presentsource = 0;\n\t\tfor (int i = 1; i < m_QueueSize; i++)\n\t\t\tm_free.push_back(i);\n\n\t\tm_bRenderGUI = true;\n\t\tm_waitForBufferCount = 0;\n\t\tm_bTriggerUpdateResolution = true;\n\t\tm_presentstep = PRESENT_IDLE;\n\t\tm_presentpts = DVD_NOPTS_VALUE;\n\t\tm_lateframes = -1.0;\n\t\tm_presentevent.notify_all();\n\t//\tm_renderedOverlay = false;\n\t\tm_renderDebug = false;\n\t\tm_clockSync.Reset();\n\n\t\tm_renderState = STATE_CONFIGURED;\n\n\t//\tCLog::Log(LOGDEBUG, \"CRenderManager::Configure - %d\", m_QueueSize);\n\t} else\n\t\tm_renderState = STATE_UNCONFIGURED;\n\n\tm_stateEvent.notify_all();\n\tm_playerPort->VideoParamsChange();\n\treturn result;\n}\n\nbool CRenderManager::IsConfigured() \n{\n\tCSingleLock lock(m_statelock);\n\tif (m_renderState == STATE_CONFIGURED)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nvoid CRenderManager::FrameWait(int ms)\n{\n\tTimer timeout(ms);\n\tCSingleLock lock(m_presentlock);\n\twhile (m_presentstep == PRESENT_IDLE && !timeout.IsTimePast())\n\t\tm_presentevent.wait_for(lock, std::chrono::milliseconds(timeout.MillisLeft()));\n}\n\nbool CRenderManager::HasFrame()\n{\n\tif (!IsConfigured())\n\t\treturn false;\n\n\tCSingleLock lock(m_presentlock);\n\tif (m_presentstep == PRESENT_READY ||\n\t\tm_presentstep == PRESENT_FRAME || m_presentstep == PRESENT_FRAME2)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nvoid CRenderManager::FrameMove()\n{\n\tUpdateResolution();\n\n\t{\n\t\tCSingleLock lock(m_statelock);\n\n\t\tif (m_renderState == STATE_UNCONFIGURED)\n\t\t\treturn;\n\t\telse if (m_renderState == STATE_CONFIGURING)\n\t\t{\n\t\t\tlock.unlock();\n\t\t\tif (!Configure())\n\t\t\t\treturn;\n\n\t\t\tFrameWait(50);\n\n// \t\t\tif (m_flags & CONF_FLAGS_FULLSCREEN)\n// \t\t\t{\n// \t\t\t\tCApplicationMessenger::GetInstance().PostMsg(TMSG_SWITCHTOFULLSCREEN);\n// \t\t\t}\n\t\t}\n\t}\n\t{\n\t\tCSingleLock lock2(m_presentlock);\n\n\t\tif (m_queued.empty())\n\t\t{\n\t\t\tm_presentstep = PRESENT_IDLE;\n\t\t}\n\n\t\tif (m_presentstep == PRESENT_READY)\n\t\t\tPrepareNextRender();\n\n\t\tif (m_presentstep == PRESENT_FLIP)\n\t\t{\n\t\t\tm_pRenderer->FlipPage(m_presentsource);\n\t\t\tm_presentstep = PRESENT_FRAME;\n\t\t\tm_presentevent.notify_all();\n\t\t}\n\n\t\t// release all previous\n\t\tfor (std::deque<int>::iterator it = m_discard.begin(); it != m_discard.end();)\n\t\t{\n\t\t\t// renderer may want to keep the frame for postprocessing\n\t\t\tif (!m_pRenderer->NeedBuffer(*it) || !m_bRenderGUI)\n\t\t\t{\n\t\t\t\tm_pRenderer->ReleaseBuffer(*it);\n\t\t\t//\tm_overlays.Release(*it);\n\t\t\t\tm_free.push_back(*it);\n\t\t\t\tit = m_discard.erase(it);\n\t\t\t} else\n\t\t\t\t++it;\n\t\t}\n\n\t\tm_bRenderGUI = true;\n\t}\n\n//\tManageCaptures();\n}\n\nvoid CRenderManager::PreInit()\n{\n\tif (!g_application.IsCurrentThread())\n\t{\n\t//\tCLog::Log(LOGERROR, \"CRenderManager::PreInit - not called from render thread\");\n\t\treturn;\n\t}\n\n\tCSingleLock lock(m_statelock);\n\n\tif (!m_pRenderer)\n\t{\n\t\tm_format = RENDER_FMT_YUV420P;\n\t\tCreateRenderer();\n\t}\n\n\tUpdateDisplayLatency();\n\n\tm_QueueSize = 2;\n\tm_QueueSkip = 0;\n\tm_presentstep = PRESENT_IDLE;\n\tm_format = RENDER_FMT_NONE;\n}\n\nvoid CRenderManager::UnInit()\n{\n\tif (!g_application.IsCurrentThread())\n\t{\n\t//\tCLog::Log(LOGERROR, \"CRenderManager::UnInit - not called from render thread\");\n\t\treturn;\n\t}\n\n\tCSingleLock lock(m_statelock);\n\n// \tm_overlays.Flush();\n// \tm_debugRenderer.Flush();\n\n\tDeleteRenderer();\n\n\tm_renderState = STATE_UNCONFIGURED;\n//\tRemoveCaptures();\n}\n\nbool CRenderManager::Flush()\n{\n\tif (!m_pRenderer)\n\t\treturn true;\n\n\tif (g_application.IsCurrentThread())\n\t{\n\t//\tCLog::Log(LOGDEBUG, \"%s - flushing renderer\", __FUNCTION__);\n\n//\t\tCSingleExit exitlock(g_graphicsContext);\n\n\t\tCSingleLock lock(m_statelock);\n\t\tCSingleLock lock2(m_presentlock);\n\t\tCSingleLock lock3(m_datalock);\n\n\t\tif (m_pRenderer)\n\t\t{\n\t\t\tm_pRenderer->Flush();\n// \t\t\tm_overlays.Flush();\n// \t\t\tm_debugRenderer.Flush();\n\n\t\t\tm_queued.clear();\n\t\t\tm_discard.clear();\n\t\t\tm_free.clear();\n\t\t\tm_presentsource = 0;\n\t\t\tm_presentstep = PRESENT_IDLE;\n\t\t\tfor (int i = 1; i < m_QueueSize; i++)\n\t\t\t\tm_free.push_back(i);\n\n\t\t\tm_flushEvent.Set();\n\t\t}\n\t} else {\n\t\tassert(false);\n\t\tm_flushEvent.Reset();\n//\t\tCApplicationMessenger::GetInstance().PostMsg(TMSG_RENDERER_FLUSH);\n\t\tif (!m_flushEvent.WaitMSec(1000))\n\t\t{\n\t\t//\tCLog::Log(LOGERROR, \"%s - timed out waiting for renderer to flush\", __FUNCTION__);\n\t\t\treturn false;\n\t\t} else\n\t\t\treturn true;\n\t}\n\treturn true;\n}\n\nvoid CRenderManager::CreateRenderer()\n{\n\tif (!m_pRenderer)\n\t{\n#if 0\n\t\tif (m_format == RENDER_FMT_VAAPI || m_format == RENDER_FMT_VAAPINV12)\n\t\t{\n#if defined(HAVE_LIBVA)\n\t\t\tm_pRenderer = new CRendererVAAPI;\n#endif\n\t\t} else if (m_format == RENDER_FMT_VDPAU || m_format == RENDER_FMT_VDPAU_420)\n\t\t{\n#if defined(HAVE_LIBVDPAU)\n\t\t\tm_pRenderer = new CRendererVDPAU;\n#endif\n\t\t} else if (m_format == RENDER_FMT_CVBREF)\n\t\t{\n#if defined(TARGET_DARWIN)\n\t\t\tm_pRenderer = new CRendererVTB;\n#endif\n\t\t} else if (m_format == RENDER_FMT_MEDIACODEC)\n\t\t{\n#if defined(TARGET_ANDROID)\n\t\t\tm_pRenderer = new CRendererMediaCodec;\n#endif\n\t\t} else if (m_format == RENDER_FMT_MEDIACODECSURFACE)\n\t\t{\n#if defined(TARGET_ANDROID)\n\t\t\tm_pRenderer = new CRendererMediaCodecSurface;\n#endif\n\t\t} else if (m_format == RENDER_FMT_MMAL)\n\t\t{\n#if defined(HAS_MMAL)\n\t\t\tm_pRenderer = new CMMALRenderer;\n#endif\n\t\t} else if (m_format == RENDER_FMT_IMXMAP)\n\t\t{\n#if defined(HAS_IMXVPU)\n\t\t\tm_pRenderer = new CRendererIMX;\n#endif\n\t\t} else if (m_format == RENDER_FMT_OMXEGL)\n\t\t{\n#if defined(HAVE_LIBOPENMAX)\n\t\t\tm_pRenderer = new CRendererOMX;\n#endif\n\t\t} else if (m_format == RENDER_FMT_DXVA)\n\t\t{\n#if defined(HAS_DX)\n\t\t\tm_pRenderer = new CWinRenderer();\n#endif\n\t\t} else if (m_format == RENDER_FMT_AML)\n\t\t{\n#if defined(HAS_LIBAMCODEC)\n\t\t\tm_pRenderer = new CRendererAML;\n#endif\n\t\t} else if (m_format != RENDER_FMT_NONE)\n\t\t{\n#if defined(HAS_MMAL)\n\t\t\tm_pRenderer = new CMMALRenderer;\n#elif defined(HAS_GL)\n\t\t\tm_pRenderer = new CLinuxRendererGL;\n#elif HAS_GLES == 2\n\t\t\tm_pRenderer = new CLinuxRendererGLES;\n#elif defined(HAS_DX)\n\t\t\tm_pRenderer = new CWinRenderer();\n#endif\n\t\t}\n#if defined(HAS_MMAL)\n\t\tif (!m_pRenderer)\n\t\t\tm_pRenderer = new CMMALRenderer;\n#endif\n#endif\n\t\tm_pRenderer = m_playerPort->CreateRenderer();\n\t\tif (m_pRenderer)\n\t\t\tm_pRenderer->PreInit();\n// \t\telse\n// \t\t\tCLog::Log(LOGERROR, \"RenderManager::CreateRenderer: failed to create renderer\");\n\t}\n}\n\nvoid CRenderManager::DeleteRenderer()\n{\n\tif (m_pRenderer)\n\t{\n\t//\tCLog::Log(LOGDEBUG, \"%s - deleting renderer\", __FUNCTION__);\n\n\t//\tdelete m_pRenderer;\n\t\tm_pRenderer = NULL;\n\t}\n}\n#if 0\nunsigned int CRenderManager::AllocRenderCapture()\n{\n\tCRenderCapture *capture = new CRenderCapture;\n\tm_captures[m_nextCaptureId] = capture;\n\treturn m_nextCaptureId++;\n}\n\nvoid CRenderManager::ReleaseRenderCapture(unsigned int captureId)\n{\n\tCSingleLock lock(m_captCritSect);\n\n\tstd::map<unsigned int, CRenderCapture*>::iterator it;\n\tit = m_captures.find(captureId);\n\n\tif (it != m_captures.end())\n\t\tit->second->SetState(CAPTURESTATE_NEEDSDELETE);\n}\n\nvoid CRenderManager::StartRenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags)\n{\n\tCSingleLock lock(m_captCritSect);\n\n\tstd::map<unsigned int, CRenderCapture*>::iterator it;\n\tit = m_captures.find(captureId);\n\tif (it == m_captures.end())\n\t{\n\t\tCLog::Log(LOGERROR, \"CRenderManager::Capture - unknown capture id: %d\", captureId);\n\t\treturn;\n\t}\n\n\tCRenderCapture *capture = it->second;\n\n\tcapture->SetState(CAPTURESTATE_NEEDSRENDER);\n\tcapture->SetUserState(CAPTURESTATE_WORKING);\n\tcapture->SetWidth(width);\n\tcapture->SetHeight(height);\n\tcapture->SetFlags(flags);\n\tcapture->GetEvent().Reset();\n\n\tif (g_application.IsCurrentThread())\n\t{\n\t\tif (flags & CAPTUREFLAG_IMMEDIATELY)\n\t\t{\n\t\t\t//render capture and read out immediately\n\t\t\tRenderCapture(capture);\n\t\t\tcapture->SetUserState(capture->GetState());\n\t\t\tcapture->GetEvent().Set();\n\t\t}\n\t}\n\n\tif (!m_captures.empty())\n\t\tm_hasCaptures = true;\n}\n\nbool CRenderManager::RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size)\n{\n\tCSingleLock lock(m_captCritSect);\n\n\tstd::map<unsigned int, CRenderCapture*>::iterator it;\n\tit = m_captures.find(captureId);\n\tif (it == m_captures.end())\n\t\treturn false;\n\n\tm_captureWaitCounter++;\n\n\t{\n\t\tif (!millis)\n\t\t\tmillis = 1000;\n\n\t\tCSingleExit exitlock(m_captCritSect);\n\t\tif (!it->second->GetEvent().WaitMSec(millis))\n\t\t{\n\t\t\tm_captureWaitCounter--;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tm_captureWaitCounter--;\n\n\tif (it->second->GetUserState() != CAPTURESTATE_DONE)\n\t\treturn false;\n\n\tunsigned int srcSize = it->second->GetWidth() * it->second->GetHeight() * 4;\n\tunsigned int bytes = std::min(srcSize, size);\n\n\tmemcpy(buffer, it->second->GetPixels(), bytes);\n\treturn true;\n}\n\nvoid CRenderManager::ManageCaptures()\n{\n\t//no captures, return here so we don't do an unnecessary lock\n\tif (!m_hasCaptures)\n\t\treturn;\n\n\tCSingleLock lock(m_captCritSect);\n\n\tstd::map<unsigned int, CRenderCapture*>::iterator it = m_captures.begin();\n\twhile (it != m_captures.end())\n\t{\n\t\tCRenderCapture* capture = it->second;\n\n\t\tif (capture->GetState() == CAPTURESTATE_NEEDSDELETE)\n\t\t{\n\t\t\tdelete capture;\n\t\t\tit = m_captures.erase(it);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (capture->GetState() == CAPTURESTATE_NEEDSRENDER)\n\t\t\tRenderCapture(capture);\n\t\telse if (capture->GetState() == CAPTURESTATE_NEEDSREADOUT)\n\t\t\tcapture->ReadOut();\n\n\t\tif (capture->GetState() == CAPTURESTATE_DONE || capture->GetState() == CAPTURESTATE_FAILED)\n\t\t{\n\t\t\t//tell the thread that the capture is done or has failed\n\t\t\tcapture->SetUserState(capture->GetState());\n\t\t\tcapture->GetEvent().Set();\n\n\t\t\tif (capture->GetFlags() & CAPTUREFLAG_CONTINUOUS)\n\t\t\t{\n\t\t\t\tcapture->SetState(CAPTURESTATE_NEEDSRENDER);\n\n\t\t\t\t//if rendering this capture continuously, and readout is async, render a new capture immediately\n\t\t\t\tif (capture->IsAsync() && !(capture->GetFlags() & CAPTUREFLAG_IMMEDIATELY))\n\t\t\t\t\tRenderCapture(capture);\n\t\t\t}\n\t\t\t++it;\n\t\t} else\n\t\t{\n\t\t\t++it;\n\t\t}\n\t}\n\n\tif (m_captures.empty())\n\t\tm_hasCaptures = false;\n}\n\nvoid CRenderManager::RenderCapture(CRenderCapture* capture)\n{\n\tif (!m_pRenderer || !m_pRenderer->RenderCapture(capture))\n\t\tcapture->SetState(CAPTURESTATE_FAILED);\n}\n\nvoid CRenderManager::RemoveCaptures()\n{\n\tCSingleLock lock(m_captCritSect);\n\n\twhile (m_captureWaitCounter > 0)\n\t{\n\t\tfor (auto entry : m_captures)\n\t\t{\n\t\t\tentry.second->GetEvent().Set();\n\t\t}\n\t\tCSingleExit lockexit(m_captCritSect);\n\t\tSleep(10);\n\t}\n\n\tfor (auto entry : m_captures)\n\t{\n\t\tdelete entry.second;\n\t}\n\tm_captures.clear();\n}\n#endif\nvoid CRenderManager::SetViewMode(int iViewMode)\n{\n\tCSingleLock lock(m_statelock);\n\tif (m_pRenderer)\n\t\tm_pRenderer->SetViewMode(iViewMode);\n\tm_playerPort->VideoParamsChange();\n}\n\nvoid CRenderManager::FlipPage(volatile std::atomic_bool& bStop, double pts,\n\t/*EINTERLACEMETHOD deintMethod, EFIELDSYNC sync,*/ bool wait)\n{\n\t{ CSingleLock lock(m_statelock);\n\n\tif (bStop)\n\t\treturn;\n\n\tif (!m_pRenderer)\n\t\treturn;\n\t}\n\n\tEPRESENTMETHOD presentmethod;\n#if 0\n\tEINTERLACEMETHOD interlacemethod = deintMethod;\n\n\tif (interlacemethod == VS_INTERLACEMETHOD_NONE)\n\t{\n\t\tpresentmethod = PRESENT_METHOD_SINGLE;\n\t\tsync = FS_NONE;\n\t} else\n\t{\n\t\tif (sync == FS_NONE)\n\t\t\tpresentmethod = PRESENT_METHOD_SINGLE;\n\t\telse\n\t\t{\n\t\t\tif (interlacemethod == VS_INTERLACEMETHOD_RENDER_BLEND)\n\t\t\t\tpresentmethod = PRESENT_METHOD_BLEND;\n\t\t\telse if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE)\n\t\t\t\tpresentmethod = PRESENT_METHOD_WEAVE;\n\t\t\telse if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB)\n\t\t\t\tpresentmethod = PRESENT_METHOD_BOB;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!m_pRenderer->WantsDoublePass())\n\t\t\t\t\tpresentmethod = PRESENT_METHOD_SINGLE;\n\t\t\t\telse\n\t\t\t\t\tpresentmethod = PRESENT_METHOD_BOB;\n\t\t\t}\n\t\t}\n\t}\n#endif\n\tCSingleLock lock(m_presentlock);\n\n\tif (m_free.empty())\n\t\treturn;\n\n\tint source = m_free.front();\n\n\tSPresent& m = m_Queue[source];\n//\tm.presentfield = sync;\n\tm.presentmethod = presentmethod;\n\tm.pts = pts;\n\trequeue(m_queued, m_free);\n\n\t// signal to any waiters to check state\n\tif (m_presentstep == PRESENT_IDLE)\n\t{\n\t\tm_presentstep = PRESENT_READY;\n\t\tm_presentevent.notify_all();\n\t}\n\n\tif (wait)\n\t{\n\t\tm_forceNext = true;\n\t\tTimer endtime(200);\n\t\twhile (m_presentstep == PRESENT_READY)\n\t\t{\n\t\t\tm_presentevent.wait_for(lock, std::chrono::milliseconds(20));\n\t\t\tif (endtime.IsTimePast() || bStop)\n\t\t\t{\n\t\t\t\tif (!bStop)\n\t\t\t\t{\n\t\t\t\t//\tCLog::Log(LOGWARNING, \"CRenderManager::FlipPage - timeout waiting for render\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tm_forceNext = false;\n\t}\n}\n#if 0\nRESOLUTION CRenderManager::GetResolution()\n{\n\tRESOLUTION res = g_graphicsContext.GetVideoResolution();\n\n\tCSingleLock lock(m_statelock);\n\tif (m_renderState == STATE_UNCONFIGURED)\n\t\treturn res;\n\n\tif (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF)\n\t\tres = CResolutionUtils::ChooseBestResolution(m_fps, m_width, CONF_FLAGS_STEREO_MODE_MASK(m_flags));\n\n\treturn res;\n}\n#endif\nvoid CRenderManager::Render(bool clear, uint32_t flags, uint32_t alpha, bool gui)\n{\n//\tCSingleExit exitLock(g_graphicsContext);\n\n\t{\n\t\tCSingleLock lock(m_statelock);\n\t\tif (m_renderState != STATE_CONFIGURED)\n\t\t\treturn;\n\t}\n\n\tif (!gui && m_pRenderer->IsGuiLayer())\n\t\treturn;\n\n\tif (!gui || m_pRenderer->IsGuiLayer())\n\t{\n\t\tSPresent& m = m_Queue[m_presentsource];\n\n\t\tif (m.presentmethod == PRESENT_METHOD_BOB)\n\t\t\tPresentFields(clear, flags, alpha);\n\t\telse if (m.presentmethod == PRESENT_METHOD_WEAVE)\n\t\t\tPresentFields(clear, flags | RENDER_FLAG_WEAVE, alpha);\n\t\telse if (m.presentmethod == PRESENT_METHOD_BLEND)\n\t\t\tPresentBlend(clear, flags, alpha);\n\t\telse\n\t\t\tPresentSingle(clear, flags, alpha);\n\t}\n\n\tif (gui)\n\t{\n\t\tif (!m_pRenderer->IsGuiLayer())\n\t\t\tm_pRenderer->Update();\n\n\t//\tm_renderedOverlay = m_overlays.HasOverlay(m_presentsource);\n\t\tCRect src, dst, view;\n\t\tm_pRenderer->GetVideoRect(src, dst, view);\n// \t\tm_overlays.SetVideoRect(src, dst, view);\n// \t\tm_overlays.Render(m_presentsource);\n\n\t\tif (m_renderDebug)\n\t\t{\n\t\t\tstd::string audio, video, player, vsync;\n\n\t\t\tm_playerPort->GetDebugInfo(audio, video, player);\n\n\t\t\tdouble refreshrate, clockspeed;\n\t\t\tint missedvblanks;\n// \t\t\tvsync = StringUtils::Format(\"VSyncOff: %.1f  \", m_clockSync.m_syncOffset / 1000);\n// \t\t\tif (m_dvdClock.GetClockInfo(missedvblanks, clockspeed, refreshrate))\n// \t\t\t{\n// \t\t\t\tvsync += StringUtils::Format(\"VSync: refresh:%.3f missed:%i speed:%.3f%%\",\n// \t\t\t\t\trefreshrate,\n// \t\t\t\t\tmissedvblanks,\n// \t\t\t\t\tclockspeed * 100);\n// \t\t\t}\n\n// \t\t\tm_debugRenderer.SetInfo(audio, video, player, vsync);\n// \t\t\tm_debugRenderer.Render(src, dst, view);\n\n\t\t\tm_debugTimer.Set(1000);\n\t\t//\tm_renderedOverlay = true;\n\t\t}\n\t}\n\n\n\tSPresent& m = m_Queue[m_presentsource];\n\n\t{ CSingleLock lock(m_presentlock);\n\n\tif (m_presentstep == PRESENT_FRAME)\n\t{\n\t\tif (m.presentmethod == PRESENT_METHOD_BOB ||\n\t\t\tm.presentmethod == PRESENT_METHOD_WEAVE)\n\t\t\tm_presentstep = PRESENT_FRAME2;\n\t\telse\n\t\t\tm_presentstep = PRESENT_IDLE;\n\t} else if (m_presentstep == PRESENT_FRAME2)\n\t\tm_presentstep = PRESENT_IDLE;\n\n\tif (m_presentstep == PRESENT_IDLE)\n\t{\n\t\tif (!m_queued.empty())\n\t\t\tm_presentstep = PRESENT_READY;\n\t}\n\n\tm_presentevent.notify_all();\n\t}\n}\n\nbool CRenderManager::IsGuiLayer()\n{\n\t{ CSingleLock lock(m_statelock);\n\n\tif (!m_pRenderer)\n\t\treturn false;\n\n\tif ((m_pRenderer->IsGuiLayer() && HasFrame()) /*||\n\t\tm_renderedOverlay || m_overlays.HasOverlay(m_presentsource)*/)\n\t\treturn true;\n\n\tif (m_renderDebug && m_debugTimer.IsTimePast())\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nbool CRenderManager::IsVideoLayer()\n{\n\t{ CSingleLock lock(m_statelock);\n\n\tif (!m_pRenderer)\n\t\treturn false;\n\n\tif (!m_pRenderer->IsGuiLayer())\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/* simple present method */\nvoid CRenderManager::PresentSingle(bool clear, uint32_t flags, uint32_t alpha)\n{\n\tSPresent& m = m_Queue[m_presentsource];\n\n// \tif (m.presentfield == FS_BOT)\n// \t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_BOT, alpha);\n// \telse if (m.presentfield == FS_TOP)\n// \t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_TOP, alpha);\n// \telse\n\t\tm_pRenderer->RenderUpdate(clear, flags, alpha);\n}\n\n/* new simpler method of handling interlaced material, *\n* we just render the two fields right after eachother */\nvoid CRenderManager::PresentFields(bool clear, uint32_t flags, uint32_t alpha)\n{\n\tSPresent& m = m_Queue[m_presentsource];\n\n\tif (m_presentstep == PRESENT_FRAME)\n\t{\n// \t\tif (m.presentfield == FS_BOT)\n// \t\t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_BOT | RENDER_FLAG_FIELD0, alpha);\n// \t\telse\n\t\t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_TOP | RENDER_FLAG_FIELD0, alpha);\n\t} else\n\t{\n// \t\tif (m.presentfield == FS_TOP)\n// \t\t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_BOT | RENDER_FLAG_FIELD1, alpha);\n// \t\telse\n\t\t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_TOP | RENDER_FLAG_FIELD1, alpha);\n\t}\n}\n\nvoid CRenderManager::PresentBlend(bool clear, uint32_t flags, uint32_t alpha)\n{\n\tSPresent& m = m_Queue[m_presentsource];\n\n// \tif (m.presentfield == FS_BOT)\n// \t{\n// \t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_BOT | RENDER_FLAG_NOOSD, alpha);\n// \t\tm_pRenderer->RenderUpdate(false, flags | RENDER_FLAG_TOP, alpha / 2);\n// \t} else\n\t{\n\t\tm_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_TOP | RENDER_FLAG_NOOSD, alpha);\n\t\tm_pRenderer->RenderUpdate(false, flags | RENDER_FLAG_BOT, alpha / 2);\n\t}\n}\n\nvoid CRenderManager::UpdateDisplayLatency()\n{\n\tfloat fps = g_graphicsContext.GetFPS();\n\tfloat refresh = fps;\n// \tif (g_graphicsContext.GetVideoResolution() == RES_WINDOW)\n// \t\trefresh = 0; // No idea about refresh rate when windowed, just get the default latency\n\tm_displayLatency = 0;// (double)g_advancedSettings.GetDisplayLatency(refresh);\n\n\tint buffers = 2/*g_Windowing.NoOfBuffers()*/;\n\tm_displayLatency += (buffers - 1) / fps;\n\n}\n\nvoid CRenderManager::UpdateResolution()\n{\n#if 0\n\tif (m_bTriggerUpdateResolution)\n\t{\n\t\tif (g_graphicsContext.IsFullScreenVideo() && g_graphicsContext.IsFullScreenRoot())\n\t\t{\n\t\t\tif (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF && m_fps > 0.0f)\n\t\t\t{\n\t\t\t\tRESOLUTION res = CResolutionUtils::ChooseBestResolution(m_fps, m_width, CONF_FLAGS_STEREO_MODE_MASK(m_flags));\n\t\t\t\tg_graphicsContext.SetVideoResolution(res);\n\t\t\t\tUpdateDisplayLatency();\n\n\t\t\t\tCheckEnableClockSync();\n\t\t\t}\n\t\t\tm_bTriggerUpdateResolution = false;\n\t\t\tm_playerPort->VideoParamsChange();\n\t\t}\n\t}\n#endif\n}\n\nvoid CRenderManager::TriggerUpdateResolution(float fps, int width, int flags)\n{\n\tif (width)\n\t{\n\t\tm_fps = fps;\n\t\tm_width = width;\n\t\tm_flags = flags;\n\t}\n\tm_bTriggerUpdateResolution = true;\n}\n\nvoid CRenderManager::ToggleDebug()\n{\n\tm_renderDebug = !m_renderDebug;\n\tm_debugTimer.SetExpired();\n}\n\n// Get renderer info, can be called before configure\nCRenderInfo CRenderManager::GetRenderInfo()\n{\n\tCSingleLock lock(m_statelock);\n\tCRenderInfo info;\n\tif (!m_pRenderer)\n\t{\n\t\tinfo.max_buffer_size = NUM_BUFFERS;\n\t\treturn info;;\n\t}\n\treturn m_pRenderer->GetRenderInfo();\n}\n\nint CRenderManager::AddVideoPicture(DVDVideoPicture& pic)\n{\n\treturn m_pRenderer->AddVideoPicture(pic, 0);\n\n\tint index;\n\t{\n\t\tCSingleLock lock(m_presentlock);\n\t\tif (m_free.empty())\n\t\t\treturn -1;\n\t\tindex = m_free.front();\n\t}\n\n\tCSingleLock lock(m_datalock);\n\tif (!m_pRenderer)\n\t\treturn -1;\n\n\tm_pRenderer->AddVideoPicture(pic, index);\n\n#if 0\n\tYV12Image image;\n\tif (m_pRenderer->GetImage(&image, index) < 0)\n\t\treturn -1;\n\n\tif (pic.format == RENDER_FMT_VDPAU\n\t\t|| pic.format == RENDER_FMT_VDPAU_420\n\t\t|| pic.format == RENDER_FMT_OMXEGL\n\t\t|| pic.format == RENDER_FMT_CVBREF\n\t\t|| pic.format == RENDER_FMT_VAAPI\n\t\t|| pic.format == RENDER_FMT_VAAPINV12\n\t\t|| pic.format == RENDER_FMT_MEDIACODEC\n\t\t|| pic.format == RENDER_FMT_MEDIACODECSURFACE\n\t\t|| pic.format == RENDER_FMT_AML\n\t\t|| pic.format == RENDER_FMT_IMXMAP\n\t\t|| pic.format == RENDER_FMT_MMAL\n\t\t|| m_pRenderer->IsPictureHW(pic))\n\t{\n\t\tm_pRenderer->AddVideoPictureHW(pic, index);\n\t} else if (pic.format == RENDER_FMT_YUV420P\n\t\t|| pic.format == RENDER_FMT_YUV420P10\n\t\t|| pic.format == RENDER_FMT_YUV420P16)\n\t{\n\t\tCDVDCodecUtils::CopyPicture(&image, &pic);\n\t} else if (pic.format == RENDER_FMT_NV12)\n\t{\n\t\tCDVDCodecUtils::CopyNV12Picture(&image, &pic);\n\t} else if (pic.format == RENDER_FMT_YUYV422\n\t\t|| pic.format == RENDER_FMT_UYVY422)\n\t{\n\t\tCDVDCodecUtils::CopyYUV422PackedPicture(&image, &pic);\n\t}\n\n\tm_pRenderer->ReleaseImage(index, false);\n#endif\n\treturn index;\n}\n#if 0\nvoid CRenderManager::AddOverlay(CDVDOverlay* o, double pts)\n{\n\tint idx;\n\t{ CSingleLock lock(m_presentlock);\n\tif (m_free.empty())\n\t\treturn;\n\tidx = m_free.front();\n\t}\n\tCSingleLock lock(m_datalock);\n\tm_overlays.AddOverlay(o, pts, idx);\n}\n\nbool CRenderManager::Supports(ERENDERFEATURE feature)\n{\n\tCSingleLock lock(m_statelock);\n\tif (m_pRenderer)\n\t\treturn m_pRenderer->Supports(feature);\n\telse\n\t\treturn false;\n}\n\nbool CRenderManager::Supports(ESCALINGMETHOD method)\n{\n\tCSingleLock lock(m_statelock);\n\tif (m_pRenderer)\n\t\treturn m_pRenderer->Supports(method);\n\telse\n\t\treturn false;\n}\n#endif\nint CRenderManager::WaitForBuffer(volatile std::atomic_bool&bStop, int timeout)\n{\n\treturn m_pRenderer->WaitForBuffer(bStop, timeout);\n\n\tCSingleLock lock(m_presentlock);\n\n\t// check if gui is active and discard buffer if not\n\t// this keeps videoplayer going\n\tif (!m_bRenderGUI /*|| !g_application.GetRenderGUI()*/)\n\t{\n\t\tm_bRenderGUI = false;\n\t\tdouble presenttime = 0;\n\t\tdouble clock = m_dvdClock.GetClock();\n\t\tif (!m_queued.empty())\n\t\t{\n\t\t\tint idx = m_queued.front();\n\t\t\tpresenttime = m_Queue[idx].pts;\n\t\t} else\n\t\t\tpresenttime = clock + 0.02;\n\n\t\tint sleeptime = (presenttime - clock) * 1000;\n\t\tif (sleeptime < 0)\n\t\t\tsleeptime = 0;\n\t\tsleeptime = std::min(sleeptime, 20);\n\t\tm_presentevent.wait_for(lock, std::chrono::milliseconds(sleeptime));\n\t\tDiscardBuffer();\n\t\treturn 0;\n\t}\n\n\tTimer endtime(timeout);\n\twhile (m_free.empty())\n\t{\n\t\tm_presentevent.wait_for(lock, std::chrono::milliseconds(std::min(50, timeout)));\n\t\tif (endtime.IsTimePast() || bStop)\n\t\t{\n\t\t\tif (timeout != 0 && !bStop)\n\t\t\t{\n\t\t\t//\tCLog::Log(LOGWARNING, \"CRenderManager::WaitForBuffer - timeout waiting for buffer\");\n\t\t\t\tm_waitForBufferCount++;\n\t\t\t\tif (m_waitForBufferCount > 2)\n\t\t\t\t{\n\t\t\t\t\tm_bRenderGUI = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tm_waitForBufferCount = 0;\n\n\t// make sure overlay buffer is released, this won't happen on AddOverlay\n//\tm_overlays.Release(m_free.front());\n\n\t// return buffer level\n\treturn m_queued.size() + m_discard.size();\n}\n\nvoid CRenderManager::PrepareNextRender()\n{\n\tif (m_queued.empty())\n\t{\n\t//\tCLog::Log(LOGERROR, \"CRenderManager::PrepareNextRender - asked to prepare with nothing available\");\n\t\tm_presentstep = PRESENT_IDLE;\n\t\tm_presentevent.notify_all();\n\t\treturn;\n\t}\n\n\tdouble frameOnScreen = m_dvdClock.GetClock();\n\tdouble frametime = 1.0 / g_graphicsContext.GetFPS() * DVD_TIME_BASE;\n\n\t// correct display latency\n\t// internal buffers of driver, assume that driver lets us go one frame in advance\n\tdouble totalLatency = DVD_SEC_TO_TIME(m_displayLatency) - DVD_MSEC_TO_TIME(m_videoDelay) + 2 * frametime;\n\n\tdouble renderPts = frameOnScreen + totalLatency;\n\n\tdouble nextFramePts = m_Queue[m_queued.front()].pts;\n\tif (m_dvdClock.GetClockSpeed() < 0)\n\t\tnextFramePts = renderPts;\n\n\tif (m_clockSync.m_enabled)\n\t{\n\t\tdouble err = fmod(renderPts - nextFramePts, frametime);\n\t\tm_clockSync.m_error += err;\n\t\tm_clockSync.m_errCount++;\n\t\tif (m_clockSync.m_errCount > 30)\n\t\t{\n\t\t\tdouble average = m_clockSync.m_error / m_clockSync.m_errCount;\n\t\t\tm_clockSync.m_syncOffset = average;\n\t\t\tm_clockSync.m_error = 0;\n\t\t\tm_clockSync.m_errCount = 0;\n\n\t\t\tm_dvdClock.SetVsyncAdjust(-average);\n\t\t}\n\t\trenderPts += frametime / 2 - m_clockSync.m_syncOffset;\n\t} else\n\t{\n\t\tm_dvdClock.SetVsyncAdjust(0);\n\t}\n\n\tif (renderPts >= nextFramePts || m_forceNext)\n\t{\n\t\t// see if any future queued frames are already due\n\t\tauto iter = m_queued.begin();\n\t\tint idx = *iter;\n\t\t++iter;\n\t\twhile (iter != m_queued.end())\n\t\t{\n\t\t\t// the slot for rendering in time is [pts .. (pts +  x * frametime)]\n\t\t\t// renderer/drivers have internal queues, being slightliy late here does not mean that\n\t\t\t// we are really late. The likelihood that we recover decreases the greater m_lateframes\n\t\t\t// get. Skipping a frame is easier than having decoder dropping one (lateframes > 10)\n\t\t\tdouble x = (m_lateframes <= 6) ? 0.98 : 0;\n\t\t\tif (renderPts < m_Queue[*iter].pts + x * frametime)\n\t\t\t\tbreak;\n\t\t\tidx = *iter;\n\t\t\t++iter;\n\t\t}\n\n\t\t// skip late frames\n\t\twhile (m_queued.front() != idx)\n\t\t{\n\t\t\trequeue(m_discard, m_queued);\n\t\t\tm_QueueSkip++;\n\t\t}\n\n\t\tint lateframes = (renderPts - m_Queue[idx].pts) * m_fps / DVD_TIME_BASE;\n\t\tif (lateframes)\n\t\t\tm_lateframes += lateframes;\n\t\telse\n\t\t\tm_lateframes = 0;\n\n\t\tm_presentstep = PRESENT_FLIP;\n\t\tm_discard.push_back(m_presentsource);\n\t\tm_presentsource = idx;\n\t\tm_queued.pop_front();\n\t\tm_presentpts = m_Queue[idx].pts - totalLatency;\n\t\tm_presentevent.notify_all();\n\t}\n}\n\nvoid CRenderManager::DiscardBuffer()\n{\n\tm_pRenderer->Flush();\n\tCSingleLock lock2(m_presentlock);\n\n\twhile (!m_queued.empty())\n\t\trequeue(m_discard, m_queued);\n\n\tif (m_presentstep == PRESENT_READY)\n\t\tm_presentstep = PRESENT_IDLE;\n\tm_presentevent.notify_all();\n}\n\nbool CRenderManager::GetStats(int &lateframes, double &pts, int &queued, int &discard)\n{\n\tCSingleLock lock(m_presentlock);\n\tlateframes = m_lateframes / 10;\n\t//pts = m_presentpts;\n\tpts = m_dvdClock.GetClock();\n\tqueued = m_queued.size();\n\tdiscard = m_discard.size();\n\treturn true;\n}\n\nvoid CRenderManager::CheckEnableClockSync()\n{\n\t// refresh rate can be a multiple of video fps\n\tdouble diff = 1.0;\n\n\tif (m_fps != 0)\n\t{\n\t\tfloat fps = m_fps;\n\t\tdouble refreshrate, clockspeed;\n\t\tint missedvblanks;\n\t\tif (m_dvdClock.GetClockInfo(missedvblanks, clockspeed, refreshrate))\n\t\t{\n\t\t\tfps *= clockspeed;\n\t\t}\n\n\t\tif (g_graphicsContext.GetFPS() >= fps)\n\t\t\tdiff = fmod(g_graphicsContext.GetFPS(), fps);\n\t\telse\n\t\t\tdiff = fps - g_graphicsContext.GetFPS();\n\t}\n\n\tif (diff < 0.01)\n\t{\n\t\tm_clockSync.m_enabled = true;\n\t} else\n\t{\n\t\tm_clockSync.m_enabled = false;\n\t\tm_dvdClock.SetVsyncAdjust(0);\n\t}\n\n\tm_playerPort->UpdateClockSync(m_clockSync.m_enabled);\n}\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/VideoRenderer.h",
    "content": "#pragma once\n#include \"KRMovieDef.h\"\n#include \"Geometry.h\"\n#include \"RenderFormats.h\"\n#include \"Timer.h\"\n#include \"BaseRenderer.h\"\n#include \"Clock.h\"\n#include <deque>\n\nNS_KRMOVIE_BEGIN\nstruct DVDVideoPicture;\nclass CBaseRenderer;\n\nclass AppliactionDesc {\npublic:\n\tstatic bool IsCurrentThread();\n};\nextern AppliactionDesc g_application;\n\nclass DispDeviceDesc {\npublic:\n\tstatic int GetFPS() { return 60; }\n};\nextern DispDeviceDesc g_graphicsContext;\n\nclass IRenderMsg\n{\n\tfriend class CRenderManager;\nprotected:\n\tvirtual void VideoParamsChange() = 0;\n\tvirtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) = 0;\n\tvirtual void UpdateClockSync(bool enabled) = 0;\n\tvirtual void UpdateRenderInfo(CRenderInfo &info) = 0;\n\n\tvirtual CBaseRenderer* CreateRenderer() = 0;\n};\n\nclass CRenderManager {\npublic:\n\tCRenderManager(CDVDClock &clock, IRenderMsg *player);\n\t~CRenderManager();\n\n\t// Functions called from render thread\n\tvoid GetVideoRect(CRect &source, CRect &dest, CRect &view);\n\tfloat GetAspectRatio();\n\tvoid FrameMove();\n\tvoid FrameWait(int ms);\n\tbool HasFrame();\n\tvoid Render(bool clear, uint32_t flags = 0, uint32_t alpha = 255, bool gui = true);\n\tbool IsGuiLayer();\n\tbool IsVideoLayer();\n//\tRESOLUTION GetResolution();\n\tvoid UpdateResolution();\n\tvoid TriggerUpdateResolution(float fps, int width, int flags);\n\tvoid SetViewMode(int iViewMode);\n\tvoid PreInit();\n\tvoid UnInit();\n\tbool Flush();\n\tbool IsConfigured() ;\n\tvoid ToggleDebug();\n#if 0\n\tunsigned int AllocRenderCapture();\n\tvoid ReleaseRenderCapture(unsigned int captureId);\n\tvoid StartRenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags);\n\tbool RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size);\n#endif\n\t// Functions called from GUI\n// \tbool Supports(ERENDERFEATURE feature);\n// \tbool Supports(ESCALINGMETHOD method);\n\n\tint GetSkippedFrames()  { return m_QueueSkip; }\n\n\t// Functions called from mplayer\n\t/**\n\t* Called by video player to configure renderer\n\t* @param picture\n\t* @param fps frames per second of video\n\t* @param flags see RenderFlags.h\n\t* @param orientation\n\t* @param numbers of kept buffer references\n\t*/\n\tbool Configure(DVDVideoPicture& picture, float fps, unsigned flags, unsigned int orientation, int buffers = 0);\n\n\tint AddVideoPicture(DVDVideoPicture& picture);\n\n\t/**\n\t* Called by video player to flip render buffers\n\t* If buffering is enabled this method does not block. In case of disabled buffering\n\t* this method blocks waiting for the render thread to pass by.\n\t* When buffering is used there might be no free buffer available after the call to\n\t* this method. Player has to call WaitForBuffer. A free buffer will become\n\t* available after the main thread has flipped front / back buffers.\n\t*\n\t* @param bStop reference to stop flag of calling thread\n\t* @param timestamp of frame delivered with AddVideoPicture\n\t* @param pts used for lateness detection\n\t* @param method for deinterlacing\n\t* @param sync signals frame, top, or bottom field\n\t* @param wait: block until pic has been rendered\n\t*/\n\tvoid FlipPage(volatile std::atomic_bool& bStop, double pts/*, EINTERLACEMETHOD deintMethod, EFIELDSYNC sync*/, bool wait);\n\n//\tvoid AddOverlay(CDVDOverlay* o, double pts);\n\n\t// Get renderer info, can be called before configure\n\tCRenderInfo GetRenderInfo();\n\n\t/**\n\t* If player uses buffering it has to wait for a buffer before it calls\n\t* AddVideoPicture and AddOverlay. It waits for max 50 ms before it returns -1\n\t* in case no buffer is available. Player may call this in a loop and decides\n\t* by itself when it wants to drop a frame.\n\t* If no buffering is requested in Configure, player does not need to call this,\n\t* because FlipPage will block.\n\t*/\n\tint WaitForBuffer(volatile std::atomic_bool& bStop, int timeout = 100);\n\n\t/**\n\t* Can be called by player for lateness detection. This is done best by\n\t* looking at the end of the queue.\n\t*/\n\tbool GetStats(int &lateframes, double &pts, int &queued, int &discard);\n\n\t/**\n\t* Video player call this on flush in oder to discard any queued frames\n\t*/\n\tvoid DiscardBuffer();\n\n\tvoid SetDelay(int delay) { m_videoDelay = delay; };\n\tint GetDelay() { return m_videoDelay; };\n\n\tCBaseRenderer* GetRenderer() {\n\t\treturn m_pRenderer;\n\t}\n\n\tbool Configure();\n\nprotected:\n\n\tvoid PresentSingle(bool clear, uint32_t flags, uint32_t alpha);\n\tvoid PresentFields(bool clear, uint32_t flags, uint32_t alpha);\n\tvoid PresentBlend(bool clear, uint32_t flags, uint32_t alpha);\n\n\tvoid PrepareNextRender();\n\n\tvoid CreateRenderer();\n\tvoid DeleteRenderer();\n//\tvoid ManageCaptures();\n\n\tvoid UpdateDisplayLatency();\n\tvoid CheckEnableClockSync();\n\n\tCBaseRenderer *m_pRenderer;\n//\tOVERLAY::CRenderer m_overlays;\n//\tCDebugRenderer m_debugRenderer;\n\tCCriticalSection m_statelock;\n\tCCriticalSection m_presentlock;\n\tCCriticalSection m_datalock;\n\tbool m_bTriggerUpdateResolution;\n\tbool m_bRenderGUI;\n\tint m_waitForBufferCount;\n\tint m_rendermethod;\n//\tbool m_renderedOverlay;\n\tbool m_renderDebug;\n\tTimer m_debugTimer;\n\n\n\tenum EPRESENTSTEP\n\t{\n\t\tPRESENT_IDLE = 0\n\t\t, PRESENT_FLIP\n\t\t, PRESENT_FRAME\n\t\t, PRESENT_FRAME2\n\t\t, PRESENT_READY\n\t};\n\n\tenum EPRESENTMETHOD\n\t{\n\t\tPRESENT_METHOD_SINGLE = 0,\n\t\tPRESENT_METHOD_BLEND,\n\t\tPRESENT_METHOD_WEAVE,\n\t\tPRESENT_METHOD_BOB,\n\t};\n\n\tenum ERENDERSTATE\n\t{\n\t\tSTATE_UNCONFIGURED = 0,\n\t\tSTATE_CONFIGURING,\n\t\tSTATE_CONFIGURED,\n\t};\n\tERENDERSTATE m_renderState;\n\tCCriticalSection m_stateMutex;\n\tstd::condition_variable_any m_stateEvent;\n\n\tdouble m_displayLatency;\n\tstd::atomic_int m_videoDelay;\n\n\tint m_QueueSize;\n\tint m_QueueSkip;\n\n\tstruct SPresent\n\t{\n\t\tdouble         pts;\n//\t\tEFIELDSYNC     presentfield;\n\t\tEPRESENTMETHOD presentmethod;\n\t} m_Queue[NUM_BUFFERS];\n\n\tstd::deque<int> m_free;\n\tstd::deque<int> m_queued;\n\tstd::deque<int> m_discard;\n\n\tERenderFormat m_format;\n\tunsigned int m_width, m_height, m_dwidth, m_dheight;\n\tunsigned int m_flags;\n\tfloat m_fps;\n\tunsigned int m_extended_format;\n\tunsigned int m_orientation;\n\tint m_NumberBuffers;\n\n\tint m_lateframes;\n\tdouble m_presentpts;\n\tEPRESENTSTEP m_presentstep;\n\tbool m_forceNext;\n\tint m_presentsource;\n\tstd::condition_variable_any  m_presentevent;\n\tCEvent m_flushEvent;\n\tCDVDClock &m_dvdClock;\n\tIRenderMsg *m_playerPort;\n\n\tstruct CClockSync\n\t{\n\t\tvoid Reset();\n\t\tdouble m_error;\n\t\tint m_errCount;\n\t\tdouble m_syncOffset;\n\t\tbool m_enabled;\n\t} m_clockSync;\n#if 0\n\tvoid RenderCapture(CRenderCapture* capture);\n\tvoid RemoveCaptures();\n\tCCriticalSection m_captCritSect;\n\tstd::map<unsigned int, CRenderCapture*> m_captures;\n\tstatic unsigned int m_nextCaptureId;\n\tunsigned int m_captureWaitCounter;\n\t//set to true when adding something to m_captures, set to false when m_captures is made empty\n\t//std::list::empty() isn't thread safe, using an extra bool will save a lock per render when no captures are requested\n\tbool m_hasCaptures;\n#endif\n};\nNS_KRMOVIE_END"
  },
  {
    "path": "src/core/movie/ffmpeg/config.h",
    "content": "#pragma once\n#include \"ffplay_util.h\""
  },
  {
    "path": "src/core/movie/ffmpeg/krffmpeg.cpp",
    "content": "#ifdef _MSC_VER\n#include <windows.h>\n#endif\n#include <thread>\n#include \"krmovie.h\"\nextern \"C\" {\n#include \"libavcodec/avcodec.h\"\n#include \"libavformat/avformat.h\"\n#include \"libavfilter/avfilter.h\"\n}\n#include <mutex>\n#include \"MsgIntf.h\"\n#include \"StorageIntf.h\"\n#include \"VideoOvlImpl.h\"\n#include \"KRMoviePlayer.h\"\n#include \"KRMovieLayer.h\"\n\nextern std::thread::id TVPMainThreadID;\n\nstatic int lockmgr(void **arg, enum AVLockOp op)\n{\n\tstd::mutex **mtx = (std::mutex**)arg;\n\tswitch (op) {\n\tcase AV_LOCK_CREATE:\n\t\t*mtx = new std::mutex();\n\t\tif (!*mtx)\n\t\t\treturn 1;\n\t\tbreak;\n\tcase AV_LOCK_OBTAIN:\n\t\t(*mtx)->lock();\n\t\tbreak;\n\tcase AV_LOCK_RELEASE:\n\t\t(*mtx)->unlock();\n\t\tbreak;\n\tcase AV_LOCK_DESTROY:\n\t\tdelete *mtx;\n\t\tbreak;\n\tdefault:\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic bool FFInitilalized = false;\nvoid TVPInitLibAVCodec() {\n\tif (!FFInitilalized) {\n\t\t/* register all codecs, demux and protocols */\n\t\tif (av_lockmgr_register(lockmgr)) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Could not initialize lock manager!\"));\n\t\t}\n\t\tavcodec_register_all();\n\t\tav_register_all();\n\t\tavfilter_register_all();\n\t\tavformat_network_init();\n\t//\tav_log_set_callback(ff_avutil_log);\n\t\tFFInitilalized = true;\n\t}\n}\n\nvoid GetVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, iTVPVideoOverlay **out)\n{\n\t*out = new KRMovie::MoviePlayerOverlay;\n\n\tif (*out)\n\t\tstatic_cast<KRMovie::MoviePlayerOverlay*>(*out)->BuildGraph(callbackwin, stream, streamname, type, size);\n}\n\nvoid GetVideoLayerObject(\n\ttTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, iTVPVideoOverlay **out)\n{\n\t*out = new KRMovie::MoviePlayerLayer;\n\n\tif (*out)\n\t\tstatic_cast<KRMovie::MoviePlayerLayer*>(*out)->BuildGraph(callbackwin, stream, streamname, type, size);\n}\n\nvoid GetMixingVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, iTVPVideoOverlay **out)\n{\n\t*out = new KRMovie::MoviePlayerOverlay;\n\n\tif (*out)\n\t\tstatic_cast<KRMovie::MoviePlayerOverlay*>(*out)->BuildGraph(callbackwin, stream, streamname, type, size);\n}\n\nvoid GetMFVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, iTVPVideoOverlay **out)\n{\n\t*out = new KRMovie::MoviePlayerOverlay;\n\n\tif (*out)\n\t\tstatic_cast<KRMovie::MoviePlayerOverlay*>(*out)->BuildGraph(callbackwin, stream, streamname, type, size);\n}\n\nstatic int AVReadFunc(void *opaque, uint8_t *buf, int buf_size)\n{\n\tTJS::tTJSBinaryStream *stream = (TJS::tTJSBinaryStream *)opaque;\n\treturn stream->Read(buf, buf_size);\n}\n\nstatic int64_t AVSeekFunc(void *opaque, int64_t offset, int whence)\n{\n\tTJS::tTJSBinaryStream *stream = (TJS::tTJSBinaryStream *)opaque;\n\tswitch (whence)\n\t{\n\tcase AVSEEK_SIZE:\n\t\treturn stream->GetSize();\n\tdefault:\n\t\treturn stream->Seek(offset, whence & 0xFF);\n\t}\n}\n\nbool TVPCheckIsVideoFile(const char *uri) {\n\tTVPInitLibAVCodec();\n\ttTJSBinaryStream* stream = TVPCreateStream(uri, TJS_BS_READ);\n\tint bufSize = 32 * 1024;\n\tif (stream->GetSize() < bufSize) {\n\t\tdelete stream;\n\t\treturn false;\n\t}\n\tAVIOContext *pIOCtx = avio_alloc_context(\n\t\t(unsigned char *)av_malloc(bufSize + AVPROBE_PADDING_SIZE),\n\t\tbufSize,  // internal Buffer and its size\n\t\tfalse,                  // bWriteable (1=true,0=false) \n\t\tstream,             // user data ; will be passed to our callback functions\n\t\tAVReadFunc,\n\t\tnullptr,                  // Write callback function (not used in this example) \n\t\tAVSeekFunc);\n\tif (!pIOCtx) {\n\t\treturn false;\n\t}\n\tAVInputFormat *fmt = NULL;\n\tav_probe_input_buffer2(pIOCtx, &fmt, uri, NULL, 0, 0);\n\tbool ret = false;\n\tif (fmt) {\n\t\tAVFormatContext *ic = avformat_alloc_context();\n\t\tic->interrupt_callback.callback = nullptr;\n\t\tic->interrupt_callback.opaque = nullptr;\n\t\tic->pb = pIOCtx;\n\t\tif (avformat_open_input(&ic, \"\", fmt, nullptr) == 0) {\n\t\t\tif (avformat_find_stream_info(ic, nullptr) == 0) {\n\t\t\t\tint vid = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);\n\t\t\t\tif (vid >= 0)\n\t\t\t\t\tret = true;\n\t\t\t}\n\t\t}\n\t\tavformat_free_context(ic);\n\t}\n\tav_free(pIOCtx);\n\tdelete stream;\n\treturn ret;\n}"
  },
  {
    "path": "src/core/movie/krmovie.cpp",
    "content": "//---------------------------------------------------------------------------\n// krmovie.cpp ( part of KRMOVIE.DLL )\n// (c)2001-2009, W.Dee <dee@kikyou.info> and contributors\n//---------------------------------------------------------------------------\n\n/*\n\tWe must separate this module because sucking MS library has a lack of\n\tcompiler portability.\n\n\tThis requires DirectX7 or later or Windows Media Player 6.4 or later for\n\tplaybacking MPEG streams.\n\n\tModified by T.Imoto <http://www.kaede-software.com>\n*/\n\n//---------------------------------------------------------------------------\n\n\n#include \"tjsCommHead.h\"\n#include \"SysInitIntf.h\"\n#include \"PluginImpl.h\"\n#include \"krmovie.h\"\n"
  },
  {
    "path": "src/core/msg/MsgIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Definition of Messages and Message Related Utilities\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsError.h\"\n//---------------------------------------------------------------------------\n// import message strings\n//---------------------------------------------------------------------------\n\n#define TVP_MSG_DECL(name, msg) tTJSMessageHolder name(TJS_W(#name), msg);\n#define TVP_MSG_DECL_CONST(name, msg) tTJSMessageHolder name(TJS_W(#name), msg, false);\n#define TVP_MSG_DECL_NULL(name) tTJSMessageHolder name(TJS_W(#name), NULL, false);\n\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"ApplicationSpecialPath.h\"\n\n//---------------------------------------------------------------------------\n// TVPFormatMessage\n//---------------------------------------------------------------------------\n/*\n\tthese functions do :\n\treplace each %%, %1, %2 into %, p1, p2.\n\t%1 must appear only once in the message string, otherwise internal\n\tbuffer will overflow. ( %2 must also so )\n*/\nttstr TVPFormatMessage(const tjs_char *msg, const ttstr & p1)\n{\n\ttjs_char *p;\n\ttjs_char * buf = new tjs_char[TJS_strlen(msg) + p1.GetLen() + 1];\n\tp = buf;\n\tfor(;*msg;msg++,p++)\n\t{\n\t\tif(*msg == TJS_W('%'))\n\t\t{\n\t\t\tif(msg[1] == TJS_W('%'))\n\t\t\t{\n\t\t\t\t// %%\n\t\t\t\t*p = TJS_W('%');\n\t\t\t\tmsg++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if(msg[1] == TJS_W('1'))\n\t\t\t{\n\t\t\t\t// %1\n\t\t\t\tTJS_strcpy(p, p1.c_str());\n\t\t\t\tp += p1.GetLen();\n\t\t\t\tp--;\n\t\t\t\tmsg++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t*p = *msg;\n\t}\n\n\t*p = 0;\n\n\tttstr ret(buf);\n\tdelete [] buf;\n\treturn ret;\n}\nttstr TVPFormatMessage(const tjs_char *msg, const ttstr & p1, const ttstr & p2)\n{\n\ttjs_char *p;\n\ttjs_char * buf =\n\t\tnew tjs_char[TJS_strlen(msg) + p1.GetLen() + p2.GetLen() + 1];\n\tp = buf;\n\tfor(;*msg;msg++,p++)\n\t{\n\t\tif(*msg == TJS_W('%'))\n\t\t{\n\t\t\tif(msg[1] == TJS_W('%'))\n\t\t\t{\n\t\t\t\t// %%\n\t\t\t\t*p = TJS_W('%');\n\t\t\t\tmsg++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if(msg[1] == TJS_W('1'))\n\t\t\t{\n\t\t\t\t// %1\n\t\t\t\tTJS_strcpy(p, p1.c_str());\n\t\t\t\tp += p1.GetLen();\n\t\t\t\tp--;\n\t\t\t\tmsg++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if(msg[1] == TJS_W('2'))\n\t\t\t{\n\t\t\t\t// %2\n\t\t\t\tTJS_strcpy(p, p2.c_str());\n\t\t\t\tp += p2.GetLen();\n\t\t\t\tp--;\n\t\t\t\tmsg++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t*p = *msg;\n\t}\n\n\t*p = 0;\n\n\tttstr ret(buf);\n\tdelete [] buf;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPThrowExceptionMessage\n//---------------------------------------------------------------------------\nvoid TVPThrowExceptionMessage(const tjs_char *msg)\n{\n\tthrow eTJSError(msg);\n}\nvoid TVPThrowExceptionMessage(const tjs_char *msg, const ttstr & p1, tjs_int num)\n{\n\tthrow eTJSError(TVPFormatMessage(msg, p1, ttstr(num)));\n}\nvoid TVPThrowExceptionMessage(const tjs_char *msg, const ttstr & p1)\n{\n\tthrow eTJSError(TVPFormatMessage(msg, p1));\n}\nvoid TVPThrowExceptionMessage(const tjs_char *msg, const ttstr & p1,\n\tconst ttstr & p2)\n{\n\tthrow eTJSError(TVPFormatMessage(msg, p1, p2));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// version retrieving\n//---------------------------------------------------------------------------\ntjs_int TVPVersionMajor;\ntjs_int TVPVersionMinor;\ntjs_int TVPVersionRelease;\ntjs_int TVPVersionBuild;\n//---------------------------------------------------------------------------\n\n#ifndef WIDEN2\n#define WIDEN2(x) TJS_W(x)\n#define WIDEN(x) WIDEN2(x)\n#endif\nconst tjs_char* TVPCompileDate = WIDEN(__DATE__);\nconst tjs_char* TVPCompileTime = WIDEN(__TIME__);\n\n//---------------------------------------------------------------------------\n// version information related functions\n//---------------------------------------------------------------------------\nextern ttstr TVPReadAboutStringFromResource();\nttstr TVPGetAboutString(void)\n{\n\tTVPGetVersion();\n\ttjs_char verstr[100];\n\tTJS_snprintf(verstr, sizeof(verstr)/sizeof(tjs_char), TJS_W(\"%d.%d.%d.%d\"),\n\t\tTVPVersionMajor, TVPVersionMinor,\n\t\tTVPVersionRelease, TVPVersionBuild);\n\n\ttjs_char tjsverstr[100];\n\tTJS_snprintf(tjsverstr, sizeof(tjsverstr)/sizeof(tjs_char), TJS_W(\"%d.%d.%d\"),\n\t\tTJSVersionMajor, TJSVersionMinor, TJSVersionRelease);\n\n\treturn TVPFormatMessage(TVPReadAboutStringFromResource().c_str(), verstr, tjsverstr) + TVPGetImportantLog();\n}\n//---------------------------------------------------------------------------\nttstr TVPGetVersionInformation(void)\n{\n\tTVPGetVersion();\n\ttjs_char verstr[100];\n\tTJS_snprintf(verstr, sizeof(verstr)/sizeof(tjs_char), TJS_W(\"%d.%d.%d.%d\"),\n\t\tTVPVersionMajor, TVPVersionMinor,\n\t\tTVPVersionRelease, TVPVersionBuild);\n\n\ttjs_char tjsverstr[100];\n\tTJS_snprintf(tjsverstr, sizeof(tjsverstr)/sizeof(tjs_char), TJS_W(\"%d.%d.%d\"),\n\t\tTJSVersionMajor, TJSVersionMinor, TJSVersionRelease);\n\n\tttstr version = TVPFormatMessage(TVPVersionInformation, verstr, tjsverstr);\n\tttstr str = ApplicationSpecialPath::ReplaceStringAll(version.AsStdString(), TJS_W(\"%DATE%\"), ttstr(TVPCompileDate));\n\tstr = ApplicationSpecialPath::ReplaceStringAll(str, TJS_W(\"%TIME%\"), ttstr(TVPCompileTime));\n\treturn ttstr(str);\n}\n//---------------------------------------------------------------------------\nttstr TVPGetVersionString()\n{\n\tTVPGetVersion();\n\ttjs_char verstr[100];\n\tTJS_snprintf(verstr, sizeof(verstr)/sizeof(tjs_char), TJS_W(\"%d.%d.%d.%d\"),\n\t\tTVPVersionMajor, TVPVersionMinor,\n\t\tTVPVersionRelease, TVPVersionBuild);\n\treturn ttstr(verstr);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Versoin retriving\n//---------------------------------------------------------------------------\nvoid TVPGetSystemVersion(tjs_int &major, tjs_int &minor,\n\ttjs_int &release, tjs_int &build)\n{\n\tTVPGetVersion();\n\tmajor = TVPVersionMajor;\n\tminor = TVPVersionMinor;\n\trelease = TVPVersionRelease;\n\tbuild = TVPVersionBuild;\n}\n//---------------------------------------------------------------------------\nvoid TVPGetTJSVersion(tjs_int &major, tjs_int &minor,\n\ttjs_int &release)\n{\n\tmajor = TJSVersionMajor;\n\tminor = TJSVersionMinor;\n\trelease = TJSVersionRelease;\n}\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/msg/MsgIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Definition of Messages and Message Related Utilities\n//---------------------------------------------------------------------------\n#ifndef MsgIntfH\n#define MsgIntfH\n\n#include \"tjs.h\"\n#include \"tjsMessage.h\"\n\n#ifndef TVP_MSG_DECL\n\t#define TVP_MSG_DECL(name, msg) extern tTJSMessageHolder name;\n\t#define TVP_MSG_DECL_CONST(name, msg) extern tTJSMessageHolder name;\n\t#define TVP_MSG_DECL_NULL(name) extern tTJSMessageHolder name;\n#endif\n\n#include \"MsgImpl.h\"\n\n#define WIDEN2(x) TJS_W(x)\n#define WIDEN(x) WIDEN2(x)\n\n\n//---------------------------------------------------------------------------\n// Message Strings\n//---------------------------------------------------------------------------\n#include \"MsgIntfInc.h\"\n\n//---------------------------------------------------------------------------\n// Utility Functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(ttstr, TVPFormatMessage, (const tjs_char *msg, const ttstr & p1));\nTJS_EXP_FUNC_DEF(ttstr, TVPFormatMessage, (const tjs_char *msg, const ttstr & p1,\n\tconst ttstr & p2));\nTJS_EXP_FUNC_DEF(void, TVPThrowExceptionMessage, (const tjs_char *msg));\nTJS_EXP_FUNC_DEF(void, TVPThrowExceptionMessage, (const tjs_char *msg,\n\tconst ttstr &p1, tjs_int num));\nTJS_EXP_FUNC_DEF(void, TVPThrowExceptionMessage, (const tjs_char *msg, const ttstr &p1));\nTJS_EXP_FUNC_DEF(void, TVPThrowExceptionMessage, (const tjs_char *msg,\n\tconst ttstr & p1, const ttstr & p2));\n\nTJS_EXP_FUNC_DEF(ttstr, TVPGetAboutString, ());\nTJS_EXP_FUNC_DEF(ttstr, TVPGetVersionInformation, ());\nTJS_EXP_FUNC_DEF(ttstr, TVPGetVersionString, ());\n\n#define TVPThrowInternalError \\\n\tTVPThrowExceptionMessage(TVPInternalError, __FILE__,  __LINE__)\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// version retrieving\n//---------------------------------------------------------------------------\nextern tjs_int TVPVersionMajor;\nextern tjs_int TVPVersionMinor;\nextern tjs_int TVPVersionRelease;\nextern tjs_int TVPVersionBuild;\n//---------------------------------------------------------------------------\nextern void TVPGetVersion();\n/*\n\timplement in each platforms;\n\tfill these four version field.\n*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPGetSystemVersion, (tjs_int &major, tjs_int &minor,\n\ttjs_int &release, tjs_int &build));\nTJS_EXP_FUNC_DEF(void, TVPGetTJSVersion, (tjs_int &major, tjs_int &minor,\n\ttjs_int &release));\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/msg/MsgIntfInc.h",
    "content": "// generated from gentext.pl Messages.xlsx\n#ifndef __MSG_INTF_INC_H__\n#define __MSG_INTF_INC_H__\n#define TVP_MSG_DEFINE(name,msg) TVP_MSG_DECL_CONST(name,TJS_W(msg))\nTVP_MSG_DEFINE(TVPVersionInformation,\"Kirikiri 2 Executable core /%1 (Compiled on %DATE% %TIME%) TJS2/%2 Copyright (C) 1997-2013 W.Dee and contributors All rights reserved.\")\nTVP_MSG_DEFINE(TVPVersionInformation2,\"The details of version information can be perused if -about is attached and started. \")\nTVP_MSG_DEFINE(TVPDownloadPageURL,\"\")\nTVP_MSG_DEFINE(TVPInternalError,\"Internal error\")\nTVP_MSG_DEFINE(TVPInvalidParam,\"Invalid argument\")\nTVP_MSG_DEFINE(TVPWarnDebugOptionEnabled, \"Debug option enabled\")\nTVP_MSG_DEFINE(TVPCommandLineParamIgnoredAndDefaultUsed, \"Command line parameter %1 = %2 is invalid. It's used default.\")\nTVP_MSG_DEFINE(TVPInvalidCommandLineParam, \"Command line parameter %1 = %2 is invalid.\")\nTVP_MSG_DEFINE(TVPNotImplemented, \"Called method is not implemented\")\nTVP_MSG_DEFINE(TVPCannotOpenStorage, \"Cannot open storage %1\")\nTVP_MSG_DEFINE(TVPCannotFindStorage, \"Cannot find storage %1\")\nTVP_MSG_DEFINE(TVPCannotOpenStorageForWrite, \"Cannot open storage %1 for writing\")\nTVP_MSG_DEFINE(TVPStorageInArchiveNotFound, \"Cannot find storage %1 in archive %2\")\nTVP_MSG_DEFINE(TVPInvalidPathName, \"Invalid path name %1\")\nTVP_MSG_DEFINE(TVPUnsupportedMediaName, \"Not supported media type \\\"%1\\\"\")\nTVP_MSG_DEFINE(TVPCannotUnbindXP3EXE, \"Cannot unbind XP3 exe %1\")\nTVP_MSG_DEFINE(TVPCannotFindXP3Mark, \"%1 is not XP3 archive or unsupported\")\nTVP_MSG_DEFINE(TVPMissingPathDelimiterAtLast, \"Use path delimiter '>' or '/'\")\nTVP_MSG_DEFINE(TVPFilenameContainsSharpWarn, \"(Attention) Filename \\\"%1\\\" contains '#'\")\nTVP_MSG_DEFINE(TVPCannotGetLocalName, \"Cannot get local name from %1\")\nTVP_MSG_DEFINE(TVPReadError, \"Read error\")\nTVP_MSG_DEFINE(TVPWriteError, \"Write error\")\nTVP_MSG_DEFINE(TVPSeekError, \"Seek error\")\nTVP_MSG_DEFINE(TVPTruncateError, \"Truncate error\")\nTVP_MSG_DEFINE(TVPInsufficientMemory, \"Insufficient memory\")\nTVP_MSG_DEFINE(TVPUncompressionFailed,\"Uncompression failed\")\nTVP_MSG_DEFINE(TVPCompressionFailed, \"Compression failed\")\nTVP_MSG_DEFINE(TVPCannotWriteToArchive, \"Cannot write to archive\")\nTVP_MSG_DEFINE(TVPUnsupportedCipherMode, \"%1 is unsupported cipher mode\")\nTVP_MSG_DEFINE(TVPUnsupportedEncoding, \"%1 is unsupported encoding\")\nTVP_MSG_DEFINE(TVPUnsupportedModeString, \"%1 is unsupported mode string\")\nTVP_MSG_DEFINE(TVPUnknownGraphicFormat, \"Unknown graphic format %1\")\nTVP_MSG_DEFINE(TVPCannotSuggestGraphicExtension, \"Cannot suggest graphics extension for %1\")\nTVP_MSG_DEFINE(TVPMaskSizeMismatch, \"Mask size mismath\")\nTVP_MSG_DEFINE(TVPProvinceSizeMismatch, \"Province image %1 size mismatch\")\nTVP_MSG_DEFINE(TVPImageLoadError, \"Image Load Error /%1\")\nTVP_MSG_DEFINE(TVPJPEGLoadError, \"JPEG Read Error /%1\")\nTVP_MSG_DEFINE(TVPPNGLoadError, \"PNG Read Error /%1\")\nTVP_MSG_DEFINE(TVPERILoadError, \"ERI Read Error /%1\")\nTVP_MSG_DEFINE(TVPTLGLoadError, \"TLG Read Error /%1\")\nTVP_MSG_DEFINE(TVPInvalidImageSaveType, \"Invalid image save type (%1)\")\nTVP_MSG_DEFINE(TVPInvalidOperationFor8BPP, \"Invalid operation for 8bpp\")\nTVP_MSG_DEFINE(TVPInvalidOperationFor32BPP, \"Invalid operation for 32bpp\")\nTVP_MSG_DEFINE(TVPSpecifyWindow, \"Specify Window class object\")\nTVP_MSG_DEFINE(TVPSpecifyLayer, \"Specify Layer class object\")\nTVP_MSG_DEFINE(TVPSpecifyLayerOrBitmap, \"Specify Layer or Bitmap class object\")\nTVP_MSG_DEFINE(TVPCannotAcceptModeAuto, \"Cannot accept omAuto mode\")\nTVP_MSG_DEFINE(TVPCannotCreateEmptyLayerImage, \"Cannot create empty layer image\")\nTVP_MSG_DEFINE(TVPCannotSetPrimaryInvisible, \"Cannot set primary layer invisible\")\nTVP_MSG_DEFINE(TVPCannotMovePrimary, \"Cannot move primary layer\")\nTVP_MSG_DEFINE(TVPCannotSetParentSelf, \"Cannot set parent self\")\nTVP_MSG_DEFINE(TVPCannotMoveNextToSelfOrNotSiblings, \"Cannot move next to self or not siblings\")\nTVP_MSG_DEFINE(TVPCannotMovePrimaryOrSiblingless, \"Cannot move primary or siblingless\")\nTVP_MSG_DEFINE(TVPCannotMoveToUnderOtherPrimaryLayer, \"Cannot move to under Other primary layer\")\nTVP_MSG_DEFINE(TVPInvalidImagePosition, \"Invalid Image position\")\nTVP_MSG_DEFINE(TVPCannotSetModeToDisabledOrModal, \"Cannot set Mode to disabled or modal\")\nTVP_MSG_DEFINE(TVPNotDrawableLayerType, \"Not drawable layer type\")\nTVP_MSG_DEFINE(TVPSourceLayerHasNoImage, \"Source layer has no image\")\nTVP_MSG_DEFINE(TVPUnsupportedLayerType, \"Unsupported layer type %1\")\nTVP_MSG_DEFINE(TVPNotDrawableFaceType, \"Not drawble face type %1\")\nTVP_MSG_DEFINE(TVPCannotConvertLayerTypeUsingGivenDirection, \"Cannot convert layer type using given direction\")\nTVP_MSG_DEFINE(TVPNegativeOpacityNotSupportedOnThisFace, \"Negative opacity not supported on this face\")\nTVP_MSG_DEFINE(TVPSrcRectOutOfBitmap, \"Source rectangle out of bitmap\")\nTVP_MSG_DEFINE(TVPBoxBlurAreaMustContainCenterPixel, \"Box blur area must contain center pixel\")\nTVP_MSG_DEFINE(TVPBoxBlurAreaMustBeSmallerThan16Million, \"Box blur area must be smaller than 16 million\")\nTVP_MSG_DEFINE(TVPCannotChangeFocusInProcessingFocus, \"Cannot change focus in processing focus\")\nTVP_MSG_DEFINE(TVPWindowHasNoLayer, \"Window has no layer\")\nTVP_MSG_DEFINE(TVPWindowHasAlreadyPrimaryLayer, \"Window has already primary layer\")\nTVP_MSG_DEFINE(TVPSpecifiedEventNeedsParameter, \"Specified event %1 needs parameter\")\nTVP_MSG_DEFINE(TVPSpecifiedEventNeedsParameter2, \"Specified event %1 needs parameter %2\")\nTVP_MSG_DEFINE(TVPSpecifiedEventNameIsUnknown, \"Specified event name %1 is unknown\")\nTVP_MSG_DEFINE(TVPOutOfRectangle, \"Out of Rectangle\")\nTVP_MSG_DEFINE(TVPInvalidMethodInUpdating, \"Invalid method in updating\")\nTVP_MSG_DEFINE(TVPCannotCreateInstance, \"Cannot create instance\")\nTVP_MSG_DEFINE(TVPUnknownWaveFormat, \"Unknown wave format %1\")\nTVP_MSG_DEFINE(TVPCurrentTransitionMustBeStopping, \"Current transition must be stopping\")\nTVP_MSG_DEFINE(TVPTransHandlerError, \"Transition handler error %1\")\nTVP_MSG_DEFINE(TVPTransAlreadyRegistered, \"Transition %1 already registerd\")\nTVP_MSG_DEFINE(TVPCannotFindTransHander, \"Cannot find transition handler %1\")\nTVP_MSG_DEFINE(TVPSpecifyTransitionSource, \"Specify transition source\")\nTVP_MSG_DEFINE(TVPLayerCannotHaveImage, \"This layer cannot have image\")\nTVP_MSG_DEFINE(TVPTransitionSourceAndDestinationMustHaveImage, \"Transition source and destination must have image\")\nTVP_MSG_DEFINE(TVPCannotLoadRuleGraphic, \"Cannot load rule graphics %1\")\nTVP_MSG_DEFINE(TVPSpecifyOption, \"Specify option %1\")\nTVP_MSG_DEFINE(TVPTransitionLayerSizeMismatch, \"Transition layer size mismatch %1 and %2\")\nTVP_MSG_DEFINE(TVPTransitionMutualSource, \"Transition mutual source\")\nTVP_MSG_DEFINE(TVPHoldDestinationAlphaParameterIsNowDeprecated, \"Warring : Method %1 %2th parameter had is ignore. Hold destination alpha parameter is now deprecated.\")\nTVP_MSG_DEFINE(TVPCannotConnectMultipleWaveSoundBufferAtOnce, \"Cannot connect multiple wave sound buffer at once\")\nTVP_MSG_DEFINE(TVPInvalidWindowSizeMustBeIn64to32768, \"Invalid window size must be in 64 to 32768\")\nTVP_MSG_DEFINE(TVPInvalidOverlapCountMustBeIn2to32, \"Invalid overlap count must be in 2 to 32\")\nTVP_MSG_DEFINE(TVPCurrentlyAsyncLoadBitmap, \"Currently async load bitmap\")\nTVP_MSG_DEFINE(TVPFaildClipboardCopy, \"copying to clipboard failed.\")\nTVP_MSG_DEFINE(TVPInvalidUTF16ToUTF8, \"Invalid UTF-16 to UTF-8\")\nTVP_MSG_DEFINE(TVPInfoLoadingStartupScript, \"(info) Loading startup script : \")\nTVP_MSG_DEFINE(TVPInfoStartupScriptEnded, \"(info) Startup script ended.\")\nTVP_MSG_DEFINE(TVPTjsCharMustBeTwoOrFour, \"sizeof(tjs_char) must be 2 or 4.\")\nTVP_MSG_DEFINE(TVPMediaNameHadAlreadyBeenRegistered, \"Media name \\\"%1\\\" had already been registered\")\nTVP_MSG_DEFINE(TVPMediaNameIsNotRegistered, \"Media name \\\"%1\\\" is not registered\")\nTVP_MSG_DEFINE(TVPInfoRebuildingAutoPath, \"(info) Rebuilding Auto Path Table ...\")\nTVP_MSG_DEFINE(TVPInfoTotalFileFoundAndActivated, \"(info) Total %1 file(s) found, %2 file(s) activated. (%3ms)\")\nTVP_MSG_DEFINE(TVPErrorInRetrievingSystemOnActivateOnDeactivate, \"Error in retrieving System.onActivate/onDeactivate : %1\")\nTVP_MSG_DEFINE(TVPTheHostIsNotA16BitUnicodeSystem, \"The host is not a 16-bit unicode system.\")\nTVP_MSG_DEFINE(TVPInfoTryingToReadXp3VirtualFileSystemInformationFrom, \"(info) Trying to read XP3 virtual file system information from : %1\")\nTVP_MSG_DEFINE(TVPSpecifiedStorageHadBeenProtected, \"Specified storage had been protected!\")\nTVP_MSG_DEFINE(TVPInfoFailed, \"(info) Failed.\")\nTVP_MSG_DEFINE(TVPInfoDoneWithContains, \"(info) Done. (contains %1 file(s), %2 segment(s))\")\nTVP_MSG_DEFINE(TVPSeparatorCRLF, \"\\r\\n\\r\\n\\r\\n==============================================================================\\r\\n==============================================================================\\r\\n\")\nTVP_MSG_DEFINE(TVPSeparatorCR, \"\\n\\n\\n==============================================================================\\n==============================================================================\\n\")\n// TVP_MSG_DEFINE(TVPDefaultFontName, \"DEFAULT_GUI_FONT\")\nTVP_MSG_DEFINE(TVPCannotOpenFontFile, \"Can't open font file '%1$s'\")\nTVP_MSG_DEFINE(TVPFontCannotBeUsed, \"Font '%1$s' cannot be used\")\nTVP_MSG_DEFINE(TVPFontRasterizeError, \"Font Rasterize error.\")\nTVP_MSG_DEFINE(TVPBitFieldsNotSupported, \"BITFIELDS not supported.\")\nTVP_MSG_DEFINE(TVPCompressedBmpNotSupported, \"Compressed BMP not supported.\")\nTVP_MSG_DEFINE(TVPUnsupportedColorModeForPalettImage, \"Unsupported color mode for palettized image.\")\nTVP_MSG_DEFINE(TVPNotWindowsBmp, \"This is not a Windows BMP file or an OS/2 BMP file.\")\nTVP_MSG_DEFINE(TVPUnsupportedHeaderVersion, \"Non-supported header version.\")\nTVP_MSG_DEFINE(TVPInfoTouching, \"(info) Touching \")\nTVP_MSG_DEFINE(TVPAbortedTimeOut, \" ... aborted [timed out]\")\nTVP_MSG_DEFINE(TVPAbortedLimitByte, \" ... aborted [limit bytes exceeded]\")\nTVP_MSG_DEFINE(TVPFaildGlyphForDrawGlyph, \"Faild glyph for DrawGlyph.\")\nTVP_MSG_DEFINE(TVPLayerObjectIsNotProperlyConstructed, \"Panic! Layer object is not properly constructed. The constructor was not called??\")\nTVP_MSG_DEFINE(TVPUnknownUpdateType, \"Unknown update type\")\nTVP_MSG_DEFINE(TVPUnknownTransitionType, \"Unknown transition type\")\nTVP_MSG_DEFINE(TVPUnsupportedUpdateTypeTutGiveUpdate, \"Update type of tutGiveUpdate is not yet supported\")\nTVP_MSG_DEFINE(TVPErrorCode, \"error code : \")\nTVP_MSG_DEFINE(TVPUnsupportedJpegPalette, \"JPEG does not support palettized image\")\nTVP_MSG_DEFINE(TVPLibpngError, \"libpng error.\")\nTVP_MSG_DEFINE(TVPUnsupportedColorTypePalette, \"Unsupported color type for palattized image\")\nTVP_MSG_DEFINE(TVPUnsupportedColorType, \"Unsupported color type\")\nTVP_MSG_DEFINE(TVPTooLargeImage, \"Too large image\")\nTVP_MSG_DEFINE(TVPPngSaveError, \"PNG save error.\")\nTVP_MSG_DEFINE(TVPTlgUnsupportedUniversalTransitionRule, \"TLG cannot be used as universal transition rule, province(_p) or mask(_m) images.\")\nTVP_MSG_DEFINE(TVPUnsupportedColorCount, \"Unsupported color count : \")\nTVP_MSG_DEFINE(TVPDataFlagMustBeZero, \"Data flag must be 0 (any flags are not yet supported)\")\nTVP_MSG_DEFINE(TVPUnsupportedColorTypeColon, \"Unsupported color type : \")\nTVP_MSG_DEFINE(TVPUnsupportedExternalGolombBitLengthTable, \"External golomb bit length table is not yet supported.\")\nTVP_MSG_DEFINE(TVPUnsupportedEntropyCodingMethod, \"Unsupported entropy coding method\")\nTVP_MSG_DEFINE(TVPInvalidTlgHeaderOrVersion, \"Invalid TLG header or unsupported TLG version.\")\nTVP_MSG_DEFINE(TVPTlgMalformedTagMissionColonAfterNameLength, \"Malformed TLG SDS tag structure, missing colon after name length\")\nTVP_MSG_DEFINE(TVPTlgMalformedTagMissionEqualsAfterName, \"Malformed TLG SDS tag structure, missing equals after name\")\nTVP_MSG_DEFINE(TVPTlgMalformedTagMissionColonAfterVaueLength, \"Malformed TLG SDS tag structure, missing colon after value length\")\nTVP_MSG_DEFINE(TVPTlgMalformedTagMissionCommaAfterTag, \"Malformed TLG SDS tag structure, missing comma after a tag\")\nTVP_MSG_DEFINE(TVPFileSizeIsZero, \"File size is zero.\")\nTVP_MSG_DEFINE(TVPMemoryAllocationError, \"Memory allocation error.\")\nTVP_MSG_DEFINE(TVPFileReadError, \"File read error.\")\nTVP_MSG_DEFINE(TVPInvalidPrerenderedFontFile, \"Signature not found or invalid pre-rendered font file.\")\nTVP_MSG_DEFINE(TVPNot16BitUnicodeFontFile, \"Not a 16-bit UNICODE font file.\")\nTVP_MSG_DEFINE(TVPInvalidHeaderVersion, \"Invalid header version.\")\nTVP_MSG_DEFINE(TVPTlgInsufficientMemory, \"SaveTLG6: Insufficient memory\")\nTVP_MSG_DEFINE(TVPTlgTooLargeBitLength, \"SaveTLG6: Too large bit length (given image may be too large)\")\nTVP_MSG_DEFINE(TVPCannotRetriveInterfaceFromDrawDevice, \"Could not retrive interface from given draw device\")\n#endif"
  },
  {
    "path": "src/core/msg/win32/MsgImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Definition of Messages and Message Related Utilities\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"MsgIntf.h\"\n#include \"MsgImpl.h\"\n#include \"PluginImpl.h\"\n\n#include \"Application.h\"\n#include \"CharacterSet.h\"\n//#include \"resource.h\"\n\n//---------------------------------------------------------------------------\n// version retrieving\n//---------------------------------------------------------------------------\nvoid TVPGetVersion(void)\n{\n\tstatic bool DoGet=true;\n\tif(DoGet)\n\t{\n\t\tDoGet = false;\n\n\t\tTVPVersionMajor = 2;\n\t\tTVPVersionMinor = 32;\n\t\tTVPVersionRelease = 2;\n\t\tTVPVersionBuild = 426;\n#if 0\n\t\tTVPGetFileVersionOf(ExePath().c_str(), TVPVersionMajor, TVPVersionMinor,\n\t\t\tTVPVersionRelease, TVPVersionBuild);\n#endif\n\t}\n}\n//---------------------------------------------------------------------------\n// about string retrieving\n//---------------------------------------------------------------------------\nextern const tjs_char* TVPCompileDate;\nextern const tjs_char* TVPCompileTime;\nttstr TVPReadAboutStringFromResource() {\n\treturn TJS_W(\"Kirikiri2 Runtime Core version %1(TJS version %2)\");\n#if 0\n\tHMODULE hModule = ::GetModuleHandle(NULL);\n\tconst char *buf = NULL;\n\tunsigned int size = 0;\n\tHRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(IDR_LICENSE_TEXT), TEXT(\"TEXT\"));\n\tif( hRsrc != NULL ) {\n\t\tsize = ::SizeofResource( hModule, hRsrc );\n\t\tHGLOBAL hGlobal = ::LoadResource( hModule, hRsrc );\n\t\tif( hGlobal != NULL ) {\n\t\t\tbuf = reinterpret_cast<const char*>(::LockResource(hGlobal));\n\t\t}\n\t}\n\tif( buf == NULL ) ttstr(L\"Resource Read Error.\");\n\n\t// UTF-8 to UTF-16\n\tsize_t len = TVPUtf8ToWideCharString( buf, size, NULL );\n\tif( len < 0 ) return ttstr(L\"Resource Read Error.\");\n\twchar_t* tmp = new wchar_t[len+1];\n\tttstr ret;\n\tif( tmp ) {\n\t\ttry {\n\t\t\tlen = TVPUtf8ToWideCharString( buf, size, tmp );\n\t\t} catch(...) {\n\t\t\tdelete[] tmp;\n\t\t\tthrow;\n\t\t}\n\t\ttmp[len] = 0;\n\n\t\tsize_t datelen = TJS_strlen( TVPCompileDate );\n\t\tsize_t timelen = TJS_strlen( TVPCompileTime );\n\n\t\t// CR to CR-LF, %DATE% and %TIME% to compile data and time\n\t\tstd::vector<wchar_t> tmp2;\n\t\ttmp2.reserve( len * 2 + datelen + timelen );\n\t\tfor( size_t i = 0; i < len; i++ ) {\n\t\t\tif( tmp[i] == '%' && (i+6) < len && tmp[i+1] == 'D' && tmp[i+2] == 'A' && tmp[i+3] == 'T' && tmp[i+4] == 'E' && tmp[i+5] == '%' ) {\n\t\t\t\tfor( size_t j = 0; j < datelen; j++ ) {\n\t\t\t\t\ttmp2.push_back( TVPCompileDate[j] );\n\t\t\t\t}\n\t\t\t\ti += 5;\n\t\t\t} else if( tmp[i] == '%' && (i+6) < len && tmp[i+1] == 'T' && tmp[i+2] == 'I' && tmp[i+3] == 'M' && tmp[i+4] == 'E' && tmp[i+5] == '%' ) {\n\t\t\t\tfor( size_t j = 0; j < timelen; j++ ) {\n\t\t\t\t\ttmp2.push_back( TVPCompileTime[j] );\n\t\t\t\t}\n\t\t\t\ti += 5;\n\t\t\t} else if( tmp[i] != L'\\n' ) {\n\t\t\t\ttmp2.push_back( tmp[i] );\n\t\t\t} else {\n\t\t\t\ttmp2.push_back( L'\\r' );\n\t\t\t\ttmp2.push_back( L'\\n' );\n\t\t\t}\n\t\t}\n\t\ttmp2.push_back( 0 );\n\t\tret = ttstr( &(tmp2[0]) );\n\t\tdelete[] tmp;\n\t}\n\treturn ret;\n#endif\n}\n\n"
  },
  {
    "path": "src/core/msg/win32/MsgImpl.h",
    "content": "// generated from gentext.pl Messages.xlsx\n#ifndef MsgImplH\n#define MsgImplH\n\n#include \"tjsMessage.h\"\n#include \"MsgIntf.h\"\n\n#ifndef TVP_MSG_DECL\n\t#define TVP_MSG_DECL(name, msg) extern tTJSMessageHolder name;\n\t#define TVP_MSG_DECL_CONST(name) extern tTJSMessageHolder name;\n#endif\n//---------------------------------------------------------------------------\n// Message Strings\n//---------------------------------------------------------------------------\n#define TVP_MSG_DEFINE(name,msg) TVP_MSG_DECL_CONST(name,TJS_W(msg))\nTVP_MSG_DEFINE(TVPScriptExceptionRaised, \"Script exception raised\")\nTVP_MSG_DEFINE(TVPHardwareExceptionRaised, \"Hardware exception raised\")\nTVP_MSG_DEFINE(TVPMainCDPName, \"Script Editor (Main)\")\nTVP_MSG_DEFINE(TVPExceptionCDPName, \"Script Editor (Exception)\")\nTVP_MSG_DEFINE(TVPCannnotLocateUIDLLForFolderSelection, \"Not found krdevui.dll\")\nTVP_MSG_DEFINE(TVPInvalidUIDLL, \"Invalid krdevui.dll\")\nTVP_MSG_DEFINE(TVPInvalidBPP, \"Invalid bpp\")\nTVP_MSG_DEFINE(TVPCannotLoadPlugin, \"Cannot load Plugin %1\")\nTVP_MSG_DEFINE(TVPNotValidPlugin, \"Not valid plugin %1\")\nTVP_MSG_DEFINE(TVPPluginUninitFailed, \"Faild to release plugin\")\nTVP_MSG_DEFINE(TVPCannnotLinkPluginWhilePluginLinking, \"Cannot link plugin while plugin linking\")\nTVP_MSG_DEFINE(TVPNotSusiePlugin, \"Not Susie Plugin\")\nTVP_MSG_DEFINE(TVPSusiePluginError, \"Susie Plugin error : %1\")\nTVP_MSG_DEFINE(TVPCannotReleasePlugin, \"Cannot release plugin\")\nTVP_MSG_DEFINE(TVPNotLoadedPlugin, \"Not loaded plugin %1\")\nTVP_MSG_DEFINE(TVPCannotAllocateBitmapBits, \"Cannot allocate memory for Bitmap : %1 (size=%2)\")\nTVP_MSG_DEFINE(TVPScanLineRangeOver, \"Scan line %1 is range over (0 to %2)\")\nTVP_MSG_DEFINE(TVPPluginError, \"Plugin Error : %1\")\nTVP_MSG_DEFINE(TVPInvalidCDDADrive, \"Invalid CD-DA Drive\")\nTVP_MSG_DEFINE(TVPCDDADriveNotFound, \"CD-DA Drive not found\")\nTVP_MSG_DEFINE(TVPMCIError, \"MCI Error : %1\")\nTVP_MSG_DEFINE(TVPInvalidSMF, \"Invalid SMF : %1\")\nTVP_MSG_DEFINE(TVPMalformedMIDIMessage, \"Malformed MIDI Message\")\nTVP_MSG_DEFINE(TVPCannotInitDirectSound, \"DirectSound Initialize file : %1\")\nTVP_MSG_DEFINE(TVPCannotCreateDSSecondaryBuffer, \"Cannot create DirectSound secondary buffer : %1/%2\")\nTVP_MSG_DEFINE(TVPInvalidLoopInformation, \"Invalid loop information %1\")\nTVP_MSG_DEFINE(TVPNotChildMenuItem, \"Not child menu Item\")\nTVP_MSG_DEFINE(TVPCannotInitDirect3D, \"Cannot initialize Direct3D : %1\")\nTVP_MSG_DEFINE(TVPCannotFindDisplayMode, \"Cannot find display mode : %1\")\nTVP_MSG_DEFINE(TVPCannotSwitchToFullScreen, \"Cannot switch to fullscreen : %1\")\nTVP_MSG_DEFINE(TVPInvalidPropertyInFullScreen, \"Invalid property in fullscreen : %1\")\nTVP_MSG_DEFINE(TVPInvalidMethodInFullScreen, \"Invalid method in fullscreen : %1\")\nTVP_MSG_DEFINE(TVPCannotLoadCursor, \"Cannot load mouse cursor : %1\")\nTVP_MSG_DEFINE(TVPCannotLoadKrMovieDLL, \"Cannot load krmovie.dll\")\nTVP_MSG_DEFINE(TVPInvalidKrMovieDLL, \"Invalid krmovie.dll\")\nTVP_MSG_DEFINE(TVPErrorInKrMovieDLL, \"Error in krmovie.dll : %1\")\nTVP_MSG_DEFINE(TVPWindowAlreadyMissing, \"Window already missing\")\nTVP_MSG_DEFINE(TVPPrerenderedFontMappingFailed, \"Prerendered font mapping failed : %1\")\nTVP_MSG_DEFINE(TVPConfigFailOriginalFileCannotBeRewritten, \"Cannot write %1.\")\nTVP_MSG_DEFINE(TVPConfigFailTempExeNotErased, \"Did not exit %1. Cannot delete file.\")\nTVP_MSG_DEFINE(TVPExecutionFail, \"Cannot execute %1.\")\nTVP_MSG_DEFINE(TVPPluginUnboundFunctionError, \"Plugin require %1 funcion. Bat not found function in this file.\")\nTVP_MSG_DEFINE(TVPExceptionHadBeenOccured, \" = (Exception)\")\nTVP_MSG_DEFINE(TVPConsoleResult, \"Console : \")\nTVP_MSG_DEFINE(TVPInfoListingFiles, \"(info) Listing files in %1\")\nTVP_MSG_DEFINE(TVPInfoTotalPhysicalMemory, \"(info) Total physical memory : %1\")\nTVP_MSG_DEFINE(TVPInfoSelectedProjectDirectory, \"(info) Selected project directory : %1\")\nTVP_MSG_DEFINE(TVPTooSmallExecutableSize, \"too small executable size.\")\nTVP_MSG_DEFINE(TVPInfoLoadingExecutableEmbeddedOptionsFailed, \"(info) Loading executable embedded options failed (ignoring) : %1\")\nTVP_MSG_DEFINE(TVPInfoLoadingExecutableEmbeddedOptionsSucceeded, \"(info) Loading executable embedded options succeeded.\")\nTVP_MSG_DEFINE(TVPFileNotFound, \"file not found.\")\nTVP_MSG_DEFINE(TVPInfoLoadingConfigurationFileFailed, \"(info) Loading configuration file \\\"%1\\\" failed (ignoring) : %2\")\nTVP_MSG_DEFINE(TVPInfoLoadingConfigurationFileSucceeded, \"(info) Loading configuration file \\\"%1\\\" succeeded.\")\nTVP_MSG_DEFINE(TVPInfoDataPathDoesNotExistTryingToMakeIt, \"(info) Data path does not exist, trying to make it ... %1\")\nTVP_MSG_DEFINE(TVPOk, \"ok.\")\nTVP_MSG_DEFINE(TVPFaild, \"failed.\")\nTVP_MSG_DEFINE(TVPInfoDataPath, \"(info) Data path : %1\")\nTVP_MSG_DEFINE(TVPInfoSpecifiedOptionEarlierItemHasMorePriority, \"(info) Specified option(s) (earlier item has more priority) :\")\nTVP_MSG_DEFINE(TVPNone, \" (none)\")\nTVP_MSG_DEFINE(TVPInfoCpuClockRoughly, \"(info) CPU clock (roughly) : %dMHz\")\nTVP_MSG_DEFINE(TVPProgramStartedOn, \"Program started on %1 (%2)\")\nTVP_MSG_DEFINE(TVPKirikiri, \"Kirikiri\")\nTVP_MSG_DEFINE(TVPUnknownError, \"Unknown error!\")\nTVP_MSG_DEFINE(TVPExitCode, \"Exit code: %d\\n\")\nTVP_MSG_DEFINE(TVPFatalError, \"Fatal Error\")\nTVP_MSG_DEFINE(TVPEnableDigitizer, \"Enable Digitizer\")\nTVP_MSG_DEFINE(TVPTouchIntegratedTouch, \"The device has an integrated touch digitizer. \")\nTVP_MSG_DEFINE(TVPTouchExternalTouch, \"The device has an external touch digitizer. \")\nTVP_MSG_DEFINE(TVPTouchIntegratedPen, \"The device has an integrated pen digitizer.\")\nTVP_MSG_DEFINE(TVPTouchExternalPen, \"The device has an external pen digitizer.\")\nTVP_MSG_DEFINE(TVPTouchMultiInput, \"The device supports multiple sources of digitizer input. \")\nTVP_MSG_DEFINE(TVPTouchReady, \"The device is ready to receive digitizer input.\")\nTVP_MSG_DEFINE(TVPCpuCheckFailure, \"CPU check failure.\")\nTVP_MSG_DEFINE(TVPCpuCheckFailureCpuFamilyOrLesserIsNotSupported, \"CPU check failure: CPU family 4 or lesser is not supported\\r\\n%1\")\nTVP_MSG_DEFINE(TVPInfoCpuNumber, \"(info) CPU #%1 : \")\nTVP_MSG_DEFINE(TVPCpuCheckFailureNotSupprtedCpu, \"CPU check failure: Not supported CPU\\r\\n%1\")\nTVP_MSG_DEFINE(TVPInfoFinallyDetectedCpuFeatures, \"(info) finally detected CPU features : %1\")\nTVP_MSG_DEFINE(TVPCpuCheckFailureNotSupportedCpu, \"CPU check failure: Not supported CPU\\r\\n%1\")\nTVP_MSG_DEFINE(TVPInfoCpuClock, \"(info) CPU clock : %.1fMHz\")\nTVP_MSG_DEFINE(TVPLayerBitmapBufferUnderrunDetectedCheckYourDrawingCode, \"Layer bitmap: Buffer underrun detected. Check your drawing code!\")\nTVP_MSG_DEFINE(TVPLayerBitmapBufferOverrunDetectedCheckYourDrawingCode, \"Layer bitmap: Buffer overrun detected. Check your drawing code!\")\nTVP_MSG_DEFINE(TVPFaildToCreateDirect3D, \"Faild to create Direct3D9.\")\nTVP_MSG_DEFINE(TVPFaildToDecideBackbufferFormat, \"Faild to decide backbuffer format.\")\nTVP_MSG_DEFINE(TVPFaildToCreateDirect3DDevice, \"Faild to create Direct3D9 Device.\")\nTVP_MSG_DEFINE(TVPFaildToSetViewport, \"Faild to set viewport.\")\nTVP_MSG_DEFINE(TVPFaildToSetRenderState, \"Faild to set render state.\")\nTVP_MSG_DEFINE(TVPWarningImageSizeTooLargeMayBeCannotCreateTexture, \"warning : Image size too large. May be cannot create texture.\")\nTVP_MSG_DEFINE(TVPUsePowerOfTwoSurface, \"Use power of two surface.\")\nTVP_MSG_DEFINE(TVPCannotAllocateD3DOffScreenSurface, \"Cannot allocate D3D off-screen surface/HR=%1\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceFailedToCreateDirect3DDevices, \"BasicDrawDevice: Failed to create Direct3D devices: %1\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceFailedToCreateDirect3DDevicesUnknownReason, \"BasicDrawDevice: Failed to create Direct3D devices: unknown reason\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceTextureHasAlreadyBeenLocked, \"BasicDrawDevice: Texture has already been locked (StartBitmapCompletion() has been called twice without EndBitmapCompletion()),) unlocking the texture.\")\nTVP_MSG_DEFINE(TVPInternalErrorResult, \"Internal error/HR=%1\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceInfPolygonDrawingFailed, \"BasicDrawDevice: (inf) Polygon drawing failed/HR=%1\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceInfDirect3DDevicePresentFailed, \"BasicDrawDevice: (inf) IDirect3DDevice::Present failed/HR=%1\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeRestart, \"ChangeDisplaySettings failed: DISP_CHANGE_RESTART\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeBadFlags, \"ChangeDisplaySettings failed: DISP_CHANGE_BADFLAGS\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeBadParam, \"ChangeDisplaySettings failed: DISP_CHANGE_BADPARAM\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeFailed, \"ChangeDisplaySettings failed: DISP_CHANGE_FAILED\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeBadMode, \"ChangeDisplaySettings failed: DISP_CHANGE_BADMODE\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedDispChangeNotUpdated, \"ChangeDisplaySettings failed: DISP_CHANGE_NOTUPDATED\")\nTVP_MSG_DEFINE(TVPChangeDisplaySettingsFailedUnknownReason, \"ChangeDisplaySettings failed: unknown reason (%1)\")\nTVP_MSG_DEFINE(TVPFailedToCreateScreenDC, \"Failed to create screen DC\")\nTVP_MSG_DEFINE(TVPFailedToCreateOffscreenBitmap, \"Failed to create offscreen bitmap\")\nTVP_MSG_DEFINE(TVPFailedToCreateOffscreenDC, \"Failed to create offscreen DC\")\nTVP_MSG_DEFINE(TVPInfoSusiePluginInfo, \"(info) Susie plugin info : %1\")\nTVP_MSG_DEFINE(TVPSusiePluginUnsupportedBitmapHeader, \"Non-supported bitmap header was given from susie plug-in.\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceFailedToCreateDirect3DDevice, \"BasicDrawDevice: Failed to create Direct3D Device: %1\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceFailedToCreateDirect3DDeviceUnknownReason, \"BasicDrawDevice: Failed to create Direct3D Device: unknown reason\")\nTVP_MSG_DEFINE(TVPCouldNotCreateAnyDrawDevice, \"Fatal: Could not create any drawer objects.\")\nTVP_MSG_DEFINE(TVPBasicDrawDeviceDoesNotSupporteLayerManagerMoreThanOne, \"\\\"basic draw\\\" device does not support layer manager more than 1\")\nTVP_MSG_DEFINE(TVPInvalidVideoSize, \"Invalid video size\")\nTVP_MSG_DEFINE(TVPRoughVsyncIntervalReadFromApi, \"Rough VSync interval read from API : %1\")\nTVP_MSG_DEFINE(TVPRoughVsyncIntervalStillSeemsWrong, \"Rough VSync interval still seems wrong, assuming default value (16)\")\nTVP_MSG_DEFINE(TVPInfoFoundDirect3DInterface, \"(info) IDirect3D9 or higher detected. Retrieving current Direct3D driver information...\")\nTVP_MSG_DEFINE(TVPInfoFaild, \"(info) Failed.\")\nTVP_MSG_DEFINE(TVPInfoDirect3D, \"(info) Loading Direct3D ...\")\nTVP_MSG_DEFINE(TVPCannotLoadD3DDLL, \"Cannot load d3d9.dll\")\nTVP_MSG_DEFINE(TVPNotFoundDirect3DCreate, \"Missing Direct3DCreate9 in d3d9.dll\")\nTVP_MSG_DEFINE(TVPInfoEnvironmentUsing, \"(info) environment: using %1\")\nTVP_MSG_DEFINE(TVPInfoSearchBestFullscreenResolution, \"(info) Searching best fullscreen resolution ...\")\nTVP_MSG_DEFINE(TVPInfoConditionPreferredScreenMode, \"(info) condition: preferred screen mode: %1\")\nTVP_MSG_DEFINE(TVPInfoConditionMode, \"(info) condition: mode: %1\")\nTVP_MSG_DEFINE(TVPInfoConditionZoomMode, \"(info) condition: zoom mode: %1\")\nTVP_MSG_DEFINE(TVPInfoEnvironmentDefaultScreenMode, \"(info) environment: default screen mode: %1\")\nTVP_MSG_DEFINE(TVPInfoEnvironmentDefaultScreenAspectRatio, \"(info) environment: default screen aspect ratio: %1 : %2\")\nTVP_MSG_DEFINE(TVPInfoEnvironmentAvailableDisplayModes, \"(info) environment: available display modes:\")\nTVP_MSG_DEFINE(TVPInfoNotFoundScreenModeFromDriver, \"(info) Panic! There is no reasonable candidate screen mode provided from the driver ... trying to use the default screen size and color depth ...\")\nTVP_MSG_DEFINE(TVPInfoResultCandidates, \"(info) result: candidates:\")\nTVP_MSG_DEFINE(TVPInfoTryScreenMode, \"(info) Trying screen mode: %1\")\nTVP_MSG_DEFINE(TVPAllScreenModeError, \"All screen mode has been tested, but no modes available at all.\")\nTVP_MSG_DEFINE(TVPInfoChangeScreenModeSuccess, \"(info) Changing screen mode succeeded\")\nTVP_MSG_DEFINE(TVPSelectXP3FileOrFolder, \"Select XP3 file or folder\")\nTVP_MSG_DEFINE(TVPD3dErrDeviceLost, \"D3D : The device has been lost but cannot be reset at this time.\")\nTVP_MSG_DEFINE(TVPD3dErrDriverIinternalError, \"D3D : Internal driver error. Applications should destroy and recreate the device when receiving this error. \")\nTVP_MSG_DEFINE(TVPD3dErrInvalidCall, \"D3D : The method call is invalid. For example, a method's parameter may not be a valid pointer.\")\nTVP_MSG_DEFINE(TVPD3dErrOutOfVideoMemory, \"D3D : Direct3D does not have enough display memory to perform the operation. \")\nTVP_MSG_DEFINE(TVPD3dErrOutOfMemory, \"D3D : Direct3D could not allocate sufficient memory to complete the call.\")\nTVP_MSG_DEFINE(TVPD3dErrWrongTextureFormat, \"D3D : The pixel format of the texture surface is not valid.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsuportedColorOperation, \"D3D : The device does not support a specified texture-blending operation for color values.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsuportedColorArg, \"D3D : The device does not support a specified texture-blending argument for color values.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsuportedAalphtOperation, \"D3D : The device does not support a specified texture-blending operation for the alpha channel.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsuportedAlphaArg, \"D3D : The device does not support a specified texture-blending argument for the alpha channel.\")\nTVP_MSG_DEFINE(TVPD3dErrTooManyOperations, \"D3D : The application is requesting more texture-filtering operations than the device supports.\")\nTVP_MSG_DEFINE(TVPD3dErrConflictioningTextureFilter, \"D3D : The current texture filters cannot be used together.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsuportedFactorValue, \"D3D : The device does not support the specified texture factor value. Not used; provided only to support older drivers.\")\nTVP_MSG_DEFINE(TVPD3dErrConflictioningRenderState, \"D3D : The currently set render states cannot be used together.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsupportedTextureFilter, \"D3D : The device does not support the specified texture filter.\")\nTVP_MSG_DEFINE(TVPD3dErrConflictioningTexturePalette, \"D3D : The current textures cannot be used simultaneously.\")\nTVP_MSG_DEFINE(TVPD3dErrNotFound, \"D3D : The requested item was not found.\")\nTVP_MSG_DEFINE(TVPD3dErrMoreData, \"D3D : There is more data available than the specified buffer size can hold.\")\nTVP_MSG_DEFINE(TVPD3dErrDeviceNotReset, \"D3D : The device has been lost but can be reset at this time.\")\nTVP_MSG_DEFINE(TVPD3dErrNotAvailable, \"D3D : This device does not support the queried technique.\")\nTVP_MSG_DEFINE(TVPD3dErrInvalidDevice, \"D3D : The requested device type is not valid.\")\nTVP_MSG_DEFINE(TVPD3dErrDriverInvalidCall, \"D3D : Not used.\")\nTVP_MSG_DEFINE(TVPD3dErrWasStillDrawing, \"D3D : The previous blit operation that is transferring information to or from this surface is incomplete.\")\nTVP_MSG_DEFINE(TVPD3dErrDeviceHung, \"D3D : The device that returned this code caused the hardware adapter to be reset by the OS.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsupportedOverlay, \"D3D : The device does not support overlay for the specified size or display mode. \")\nTVP_MSG_DEFINE(TVPD3dErrUnsupportedOverlayFormat, \"D3D : The device does not support overlay for the specified surface format. \")\nTVP_MSG_DEFINE(TVPD3dErrCannotProtectContent, \"D3D : The specified content cannot be protected.\")\nTVP_MSG_DEFINE(TVPD3dErrUnsupportedCrypto, \"D3D : The specified cryptographic algorithm is not supported.\")\nTVP_MSG_DEFINE(TVPD3dErrPresentStatisticsDisJoint, \"D3D : The present statistics have no orderly sequence.\")\nTVP_MSG_DEFINE(TVPD3dErrDeviceRemoved, \"D3D : The hardware adapter has been removed.\")\nTVP_MSG_DEFINE(TVPD3dOkNoAutoGen, \"D3D : This is a success code. However,) the autogeneration of mipmaps is not supported for this format.\")\nTVP_MSG_DEFINE(TVPD3dErrFail, \"D3D : An undetermined error occurred inside the Direct3D subsystem.\")\nTVP_MSG_DEFINE(TVPD3dErrInvalidArg, \"D3D : An invalid parameter was passed to the returning function.\")\nTVP_MSG_DEFINE(TVPD3dUnknownError, \"D3D : Unknown error.\")\nTVP_MSG_DEFINE(TVPExceptionAccessViolation, \"Access Violation: The thread attempts to read from or write to a virtual address for which it does not have access.\")\nTVP_MSG_DEFINE(TVPExceptionBreakpoint, \"Break Point: A breakpoint is encountered.\")\nTVP_MSG_DEFINE(TVPExceptionDatatypeMisalignment, \"Data Type Misalignment: The thread attempts to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries,) 32-bit values on 4-byte boundaries,) and so on.\")\nTVP_MSG_DEFINE(TVPExceptionSingleStep, \"Single Step: A trace trap or other single instruction mechanism signals that one instruction is executed.\")\nTVP_MSG_DEFINE(TVPExceptionArrayBoundsExceeded, \"Array Bounds Exceede: The thread attempts to access an array element that is out of bounds, and the underlying hardware supports bounds checking.\")\nTVP_MSG_DEFINE(TVPExceptionFltDenormalOperand, \"Denormal Operand: One of the operands in a floating point operation is denormal. A denormal value is one that is too small to represent as a standard floating point value.\")\nTVP_MSG_DEFINE(TVPExceptionFltDivideByZero, \"Divide By Zero: The thread attempts to divide a floating point value by a floating point divisor of 0 (zero).\")\nTVP_MSG_DEFINE(TVPExceptionFltInexactResult, \"Inexact Result: The result of a floating point operation cannot be represented exactly as a decimal fraction.\")\nTVP_MSG_DEFINE(TVPExceptionFltInvalidOperation, \"Invalid Operation: A floating point exception that is not included in this list.\")\nTVP_MSG_DEFINE(TVPExceptionFltOverflow, \"Overflow: The exponent of a floating point operation is greater than the magnitude allowed by the corresponding type.\")\nTVP_MSG_DEFINE(TVPExceptionFltStackCheck, \"Stack Check: The stack has overflowed or underflowed, because of a floating point operation.\")\nTVP_MSG_DEFINE(TVPExceptionFltUnderflow, \"Underflow: The exponent of a floating point operation is less than the magnitude allowed by the corresponding type.\")\nTVP_MSG_DEFINE(TVPExceptionIntDivideByZero, \"Divide By Zero: The thread attempts to divide an integer value by an integer divisor of 0 (zero).\")\nTVP_MSG_DEFINE(TVPExceptionIntOverflow, \"Overflow: The result of an integer operation creates a value that is too large to be held by the destination register. In some cases, this will result in a carry out of the most significant bit of the result. Some operations do not set the carry flag.\")\nTVP_MSG_DEFINE(TVPExceptionPrivInstruction, \"Priv Instruction: The thread attempts to execute an instruction with an operation that is not allowed in the current computer mode.\")\nTVP_MSG_DEFINE(TVPExceptionNoncontinuableException, \"Noncontinuable Exception: The thread attempts to continue execution after a non-continuable exception occurs.\")\nTVP_MSG_DEFINE(TVPExceptionGuardPage, \"Guard Page: The thread accessed memory allocated with the PAGE_GUARD modifier.\")\nTVP_MSG_DEFINE(TVPExceptionIllegalInstruction, \"Illegal Instruction: The thread tries to execute an invalid instruction.\")\nTVP_MSG_DEFINE(TVPExceptionInPageError, \"In Page Error: The thread tries to access a page that is not present, and the system is unable to load the page. For example, this exception might occur if a network connection is lost while running a program over a network.\")\nTVP_MSG_DEFINE(TVPExceptionInvalidDisposition, \"Invalid Disposition: An exception handler returns an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception.\")\nTVP_MSG_DEFINE(TVPExceptionInvalidHandle, \"Invalid Handle: The thread used a handle to a kernel object that was invalid (probably because it had been closed.)\")\nTVP_MSG_DEFINE(TVPExceptionStackOverflow, \"Stack Overflow: The thread uses up its stack.\")\nTVP_MSG_DEFINE(TVPExceptionUnwindCconsolidate, \"Unwind Consolidate: A frame consolidation has been executed.\")\nTVP_MSG_DEFINE(TVPCannotShowModalAreadyShowed, \"Cannot Show Modal.\")\nTVP_MSG_DEFINE(TVPCannotShowModalSingleWindow, \"Cannot Show Modal. When it is single window.\")\n#endif\n"
  },
  {
    "path": "src/core/msg/win32/MsgLoad.cpp",
    "content": "// generated from gentext.pl Messages.xlsx\n#include \"tjsCommHead.h\"\n#include \"tjsError.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"string_table_resource.h\"\n\nstatic bool IS_LOAD_MESSAGE = false;\nstatic const int MAX_MESSAGE_LENGTH = 1024;\nenum {\n\tNUM_TJS_INTERNAL_ERROR,\n\tNUM_TJS_WARNING,\n\tNUM_TJS_WARN_EVAL_OPERATOR,\n\tNUM_TJS_NARROW_TO_WIDE_CONVERSION_ERROR,\n\tNUM_TJS_VARIANT_CONVERT_ERROR,\n\tNUM_TJS_VARIANT_CONVERT_ERROR_TO_OBJECT,\n\tNUM_TJS_IDEXPECTED,\n\tNUM_TJS_SUBSTITUTION_IN_BOOLEAN_CONTEXT,\n\tNUM_TJS_CANNOT_MODIFY_LHS,\n\tNUM_TJS_INSUFFICIENT_MEM,\n\tNUM_TJS_CANNOT_GET_RESULT,\n\tNUM_TJS_NULL_ACCESS,\n\tNUM_TJS_MEMBER_NOT_FOUND,\n\tNUM_TJS_MEMBER_NOT_FOUND_NO_NAME_GIVEN,\n\tNUM_TJS_NOT_IMPLEMENTED,\n\tNUM_TJS_INVALID_PARAM,\n\tNUM_TJS_BAD_PARAM_COUNT,\n\tNUM_TJS_INVALID_TYPE,\n\tNUM_TJS_SPECIFY_DIC_OR_ARRAY,\n\tNUM_TJS_SPECIFY_ARRAY,\n\tNUM_TJS_STRING_DEALLOC_ERROR,\n\tNUM_TJS_STRING_ALLOC_ERROR,\n\tNUM_TJS_MISPLACED_BREAK_CONTINUE,\n\tNUM_TJS_MISPLACED_CASE,\n\tNUM_TJS_MISPLACED_RETURN,\n\tNUM_TJS_STRING_PARSE_ERROR,\n\tNUM_TJS_NUMBER_ERROR,\n\tNUM_TJS_UNCLOSED_COMMENT,\n\tNUM_TJS_INVALID_CHAR,\n\tNUM_TJS_EXPECTED,\n\tNUM_TJS_SYNTAX_ERROR,\n\tNUM_TJS_PPERROR,\n\tNUM_TJS_CANNOT_GET_SUPER,\n\tNUM_TJS_INVALID_OPECODE,\n\tNUM_TJS_RANGE_ERROR,\n\tNUM_TJS_ACCESS_DENYED,\n\tNUM_TJS_NATIVE_CLASS_CRASH,\n\tNUM_TJS_INVALID_OBJECT,\n\tNUM_TJS_CANNOT_OMIT,\n\tNUM_TJS_CANNOT_PARSE_DATE,\n\tNUM_TJS_INVALID_VALUE_FOR_TIMESTAMP,\n\tNUM_TJS_EXCEPTION_NOT_FOUND,\n\tNUM_TJS_INVALID_FORMAT_STRING,\n\tNUM_TJS_DIVIDE_BY_ZERO,\n\tNUM_TJS_NOT_RECONSTRUCTIVE_RANDOMIZE_DATA,\n\tNUM_TJS_SYMBOL,\n\tNUM_TJS_CALL_HISTORY_IS_FROM_OUT_OF_TJS2SCRIPT,\n\tNUM_TJS_NOBJECTS_WAS_NOT_FREED,\n\tNUM_TJS_OBJECT_CREATION_HISTORY_DELIMITER_CRLF,\n\tNUM_TJS_OBJECT_CREATION_HISTORY_DELIMITER,\n\tNUM_TJS_OBJECT_WAS_NOT_FREED_CRLF,\n\tNUM_TJS_OBJECT_WAS_NOT_FREED,\n\tNUM_TJS_GROUP_BY_OBJECT_TYPE_AND_HISTORY,\n\tNUM_TJS_GROUP_BY_OBJECT_TYPE,\n\tNUM_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY_CRLF,\n\tNUM_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY,\n\tNUM_TJS_OBJECT_COUNTING_MESSAGE_TJSGROUP_BY_OBJECT_TYPE,\n\tNUM_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT_CRLF,\n\tNUM_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT,\n\tNUM_TJS_WRITE_ERROR,\n\tNUM_TJS_READ_ERROR,\n\tNUM_TJS_SEEK_ERROR,\n\tNUM_TJS_BYTE_CODE_BROKEN,\n\tNUM_TJS_OBJECT_HASH_MAP_LOG_VERSION_MISMATCH,\n\tNUM_TJS_CURRUPTED_OBJECT_HASH_MAP_LOG,\n\tNUM_TJS_UNKNOWN_FAILURE,\n\tNUM_TJS_UNKNOWN_PACK_UNPACK_TEMPLATE_CHARCTER,\n\tNUM_TJS_UNKNOWN_BIT_STRING_CHARACTER,\n\tNUM_TJS_UNKNOWN_HEX_STRING_CHARACTER,\n\tNUM_TJS_NOT_SUPPORTED_UUENCODE,\n\tNUM_TJS_NOT_SUPPORTED_BER,\n\tNUM_TJS_NOT_SUPPORTED_UNPACK_LP,\n\tNUM_TJS_NOT_SUPPORTED_UNPACK_P,\n\tNUM_TVP_VERSION_INFORMATION,\n\tNUM_TVP_VERSION_INFORMATION2,\n\tNUM_TVP_DOWNLOAD_PAGE_URL,\n\tNUM_TVP_INTERNAL_ERROR,\n\tNUM_TVP_INVALID_PARAM,\n\tNUM_TVP_WARN_DEBUG_OPTION_ENABLED,\n\tNUM_TVP_COMMAND_LINE_PARAM_IGNORED_AND_DEFAULT_USED,\n\tNUM_TVP_INVALID_COMMAND_LINE_PARAM,\n\tNUM_TVP_NOT_IMPLEMENTED,\n\tNUM_TVP_CANNOT_OPEN_STORAGE,\n\tNUM_TVP_CANNOT_FIND_STORAGE,\n\tNUM_TVP_CANNOT_OPEN_STORAGE_FOR_WRITE,\n\tNUM_TVP_STORAGE_IN_ARCHIVE_NOT_FOUND,\n\tNUM_TVP_INVALID_PATH_NAME,\n\tNUM_TVP_UNSUPPORTED_MEDIA_NAME,\n\tNUM_TVP_CANNOT_UNBIND_XP3EXE,\n\tNUM_TVP_CANNOT_FIND_XP3MARK,\n\tNUM_TVP_MISSING_PATH_DELIMITER_AT_LAST,\n\tNUM_TVP_FILENAME_CONTAINS_SHARP_WARN,\n\tNUM_TVP_CANNOT_GET_LOCAL_NAME,\n\tNUM_TVP_READ_ERROR,\n\tNUM_TVP_WRITE_ERROR,\n\tNUM_TVP_SEEK_ERROR,\n\tNUM_TVP_TRUNCATE_ERROR,\n\tNUM_TVP_INSUFFICIENT_MEMORY,\n\tNUM_TVP_UNCOMPRESSION_FAILED,\n\tNUM_TVP_COMPRESSION_FAILED,\n\tNUM_TVP_CANNOT_WRITE_TO_ARCHIVE,\n\tNUM_TVP_UNSUPPORTED_CIPHER_MODE,\n\tNUM_TVP_UNSUPPORTED_ENCODING,\n\tNUM_TVP_UNSUPPORTED_MODE_STRING,\n\tNUM_TVP_UNKNOWN_GRAPHIC_FORMAT,\n\tNUM_TVP_CANNOT_SUGGEST_GRAPHIC_EXTENSION,\n\tNUM_TVP_MASK_SIZE_MISMATCH,\n\tNUM_TVP_PROVINCE_SIZE_MISMATCH,\n\tNUM_TVP_IMAGE_LOAD_ERROR,\n\tNUM_TVP_JPEGLOAD_ERROR,\n\tNUM_TVP_PNGLOAD_ERROR,\n\tNUM_TVP_ERILOAD_ERROR,\n\tNUM_TVP_TLGLOAD_ERROR,\n\tNUM_TVP_INVALID_IMAGE_SAVE_TYPE,\n\tNUM_TVP_INVALID_OPERATION_FOR8BPP,\n\tNUM_TVP_INVALID_OPERATION_FOR32BPP,\n\tNUM_TVP_SPECIFY_WINDOW,\n\tNUM_TVP_SPECIFY_LAYER,\n\tNUM_TVP_SPECIFY_LAYER_OR_BITMAP,\n\tNUM_TVP_CANNOT_ACCEPT_MODE_AUTO,\n\tNUM_TVP_CANNOT_CREATE_EMPTY_LAYER_IMAGE,\n\tNUM_TVP_CANNOT_SET_PRIMARY_INVISIBLE,\n\tNUM_TVP_CANNOT_MOVE_PRIMARY,\n\tNUM_TVP_CANNOT_SET_PARENT_SELF,\n\tNUM_TVP_CANNOT_MOVE_NEXT_TO_SELF_OR_NOT_SIBLINGS,\n\tNUM_TVP_CANNOT_MOVE_PRIMARY_OR_SIBLINGLESS,\n\tNUM_TVP_CANNOT_MOVE_TO_UNDER_OTHER_PRIMARY_LAYER,\n\tNUM_TVP_INVALID_IMAGE_POSITION,\n\tNUM_TVP_CANNOT_SET_MODE_TO_DISABLED_OR_MODAL,\n\tNUM_TVP_NOT_DRAWABLE_LAYER_TYPE,\n\tNUM_TVP_SOURCE_LAYER_HAS_NO_IMAGE,\n\tNUM_TVP_UNSUPPORTED_LAYER_TYPE,\n\tNUM_TVP_NOT_DRAWABLE_FACE_TYPE,\n\tNUM_TVP_CANNOT_CONVERT_LAYER_TYPE_USING_GIVEN_DIRECTION,\n\tNUM_TVP_NEGATIVE_OPACITY_NOT_SUPPORTED_ON_THIS_FACE,\n\tNUM_TVP_SRC_RECT_OUT_OF_BITMAP,\n\tNUM_TVP_BOX_BLUR_AREA_MUST_CONTAIN_CENTER_PIXEL,\n\tNUM_TVP_BOX_BLUR_AREA_MUST_BE_SMALLER_THAN16MILLION,\n\tNUM_TVP_CANNOT_CHANGE_FOCUS_IN_PROCESSING_FOCUS,\n\tNUM_TVP_WINDOW_HAS_NO_LAYER,\n\tNUM_TVP_WINDOW_HAS_ALREADY_PRIMARY_LAYER,\n\tNUM_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER,\n\tNUM_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER2,\n\tNUM_TVP_SPECIFIED_EVENT_NAME_IS_UNKNOWN,\n\tNUM_TVP_OUT_OF_RECTANGLE,\n\tNUM_TVP_INVALID_METHOD_IN_UPDATING,\n\tNUM_TVP_CANNOT_CREATE_INSTANCE,\n\tNUM_TVP_UNKNOWN_WAVE_FORMAT,\n\tNUM_TVP_CURRENT_TRANSITION_MUST_BE_STOPPING,\n\tNUM_TVP_TRANS_HANDLER_ERROR,\n\tNUM_TVP_TRANS_ALREADY_REGISTERED,\n\tNUM_TVP_CANNOT_FIND_TRANS_HANDER,\n\tNUM_TVP_SPECIFY_TRANSITION_SOURCE,\n\tNUM_TVP_LAYER_CANNOT_HAVE_IMAGE,\n\tNUM_TVP_TRANSITION_SOURCE_AND_DESTINATION_MUST_HAVE_IMAGE,\n\tNUM_TVP_CANNOT_LOAD_RULE_GRAPHIC,\n\tNUM_TVP_SPECIFY_OPTION,\n\tNUM_TVP_TRANSITION_LAYER_SIZE_MISMATCH,\n\tNUM_TVP_TRANSITION_MUTUAL_SOURCE,\n\tNUM_TVP_HOLD_DESTINATION_ALPHA_PARAMETER_IS_NOW_DEPRECATED,\n\tNUM_TVP_CANNOT_CONNECT_MULTIPLE_WAVE_SOUND_BUFFER_AT_ONCE,\n\tNUM_TVP_INVALID_WINDOW_SIZE_MUST_BE_IN64TO32768,\n\tNUM_TVP_INVALID_OVERLAP_COUNT_MUST_BE_IN2TO32,\n\tNUM_TVP_CURRENTLY_ASYNC_LOAD_BITMAP,\n\tNUM_TVP_FAILD_CLIPBOARD_COPY,\n\tNUM_TVP_INVALID_UTF16TO_UTF8,\n\tNUM_TVP_INFO_LOADING_STARTUP_SCRIPT,\n\tNUM_TVP_INFO_STARTUP_SCRIPT_ENDED,\n\tNUM_TVP_TJS_CHAR_MUST_BE_TWO_OR_FOUR,\n\tNUM_TVP_MEDIA_NAME_HAD_ALREADY_BEEN_REGISTERED,\n\tNUM_TVP_MEDIA_NAME_IS_NOT_REGISTERED,\n\tNUM_TVP_INFO_REBUILDING_AUTO_PATH,\n\tNUM_TVP_INFO_TOTAL_FILE_FOUND_AND_ACTIVATED,\n\tNUM_TVP_ERROR_IN_RETRIEVING_SYSTEM_ON_ACTIVATE_ON_DEACTIVATE,\n\tNUM_TVP_THE_HOST_IS_NOT_A16BIT_UNICODE_SYSTEM,\n\tNUM_TVP_INFO_TRYING_TO_READ_XP3VIRTUAL_FILE_SYSTEM_INFORMATION_FROM,\n\tNUM_TVP_SPECIFIED_STORAGE_HAD_BEEN_PROTECTED,\n\tNUM_TVP_INFO_FAILED,\n\tNUM_TVP_INFO_DONE_WITH_CONTAINS,\n\tNUM_TVP_SEPARATOR_CRLF,\n\tNUM_TVP_SEPARATOR_CR,\n\tNUM_TVP_DEFAULT_FONT_NAME,\n\tNUM_TVP_CANNOT_OPEN_FONT_FILE,\n\tNUM_TVP_FONT_CANNOT_BE_USED,\n\tNUM_TVP_FONT_RASTERIZE_ERROR,\n\tNUM_TVP_BIT_FIELDS_NOT_SUPPORTED,\n\tNUM_TVP_COMPRESSED_BMP_NOT_SUPPORTED,\n\tNUM_TVP_UNSUPPORTED_COLOR_MODE_FOR_PALETT_IMAGE,\n\tNUM_TVP_NOT_WINDOWS_BMP,\n\tNUM_TVP_UNSUPPORTED_HEADER_VERSION,\n\tNUM_TVP_INFO_TOUCHING,\n\tNUM_TVP_ABORTED_TIME_OUT,\n\tNUM_TVP_ABORTED_LIMIT_BYTE,\n\tNUM_TVP_FAILD_GLYPH_FOR_DRAW_GLYPH,\n\tNUM_TVP_LAYER_OBJECT_IS_NOT_PROPERLY_CONSTRUCTED,\n\tNUM_TVP_UNKNOWN_UPDATE_TYPE,\n\tNUM_TVP_UNKNOWN_TRANSITION_TYPE,\n\tNUM_TVP_UNSUPPORTED_UPDATE_TYPE_TUT_GIVE_UPDATE,\n\tNUM_TVP_ERROR_CODE,\n\tNUM_TVP_UNSUPPORTED_JPEG_PALETTE,\n\tNUM_TVP_LIBPNG_ERROR,\n\tNUM_TVP_UNSUPPORTED_COLOR_TYPE_PALETTE,\n\tNUM_TVP_UNSUPPORTED_COLOR_TYPE,\n\tNUM_TVP_TOO_LARGE_IMAGE,\n\tNUM_TVP_PNG_SAVE_ERROR,\n\tNUM_TVP_TLG_UNSUPPORTED_UNIVERSAL_TRANSITION_RULE,\n\tNUM_TVP_UNSUPPORTED_COLOR_COUNT,\n\tNUM_TVP_DATA_FLAG_MUST_BE_ZERO,\n\tNUM_TVP_UNSUPPORTED_COLOR_TYPE_COLON,\n\tNUM_TVP_UNSUPPORTED_EXTERNAL_GOLOMB_BIT_LENGTH_TABLE,\n\tNUM_TVP_UNSUPPORTED_ENTROPY_CODING_METHOD,\n\tNUM_TVP_INVALID_TLG_HEADER_OR_VERSION,\n\tNUM_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_NAME_LENGTH,\n\tNUM_TVP_TLG_MALFORMED_TAG_MISSION_EQUALS_AFTER_NAME,\n\tNUM_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_VAUE_LENGTH,\n\tNUM_TVP_TLG_MALFORMED_TAG_MISSION_COMMA_AFTER_TAG,\n\tNUM_TVP_FILE_SIZE_IS_ZERO,\n\tNUM_TVP_MEMORY_ALLOCATION_ERROR,\n\tNUM_TVP_FILE_READ_ERROR,\n\tNUM_TVP_INVALID_PRERENDERED_FONT_FILE,\n\tNUM_TVP_NOT16BIT_UNICODE_FONT_FILE,\n\tNUM_TVP_INVALID_HEADER_VERSION,\n\tNUM_TVP_TLG_INSUFFICIENT_MEMORY,\n\tNUM_TVP_TLG_TOO_LARGE_BIT_LENGTH,\n\tNUM_TVP_CANNOT_RETRIVE_INTERFACE_FROM_DRAW_DEVICE,\n\tNUM_TVP_SCRIPT_EXCEPTION_RAISED,\n\tNUM_TVP_HARDWARE_EXCEPTION_RAISED,\n\tNUM_TVP_MAIN_CDPNAME,\n\tNUM_TVP_EXCEPTION_CDPNAME,\n\tNUM_TVP_CANNNOT_LOCATE_UIDLLFOR_FOLDER_SELECTION,\n\tNUM_TVP_INVALID_UIDLL,\n\tNUM_TVP_INVALID_BPP,\n\tNUM_TVP_CANNOT_LOAD_PLUGIN,\n\tNUM_TVP_NOT_VALID_PLUGIN,\n\tNUM_TVP_PLUGIN_UNINIT_FAILED,\n\tNUM_TVP_CANNNOT_LINK_PLUGIN_WHILE_PLUGIN_LINKING,\n\tNUM_TVP_NOT_SUSIE_PLUGIN,\n\tNUM_TVP_SUSIE_PLUGIN_ERROR,\n\tNUM_TVP_CANNOT_RELEASE_PLUGIN,\n\tNUM_TVP_NOT_LOADED_PLUGIN,\n\tNUM_TVP_CANNOT_ALLOCATE_BITMAP_BITS,\n\tNUM_TVP_SCAN_LINE_RANGE_OVER,\n\tNUM_TVP_PLUGIN_ERROR,\n\tNUM_TVP_INVALID_CDDADRIVE,\n\tNUM_TVP_CDDADRIVE_NOT_FOUND,\n\tNUM_TVP_MCIERROR,\n\tNUM_TVP_INVALID_SMF,\n\tNUM_TVP_MALFORMED_MIDIMESSAGE,\n\tNUM_TVP_CANNOT_INIT_DIRECT_SOUND,\n\tNUM_TVP_CANNOT_CREATE_DSSECONDARY_BUFFER,\n\tNUM_TVP_INVALID_LOOP_INFORMATION,\n\tNUM_TVP_NOT_CHILD_MENU_ITEM,\n\tNUM_TVP_CANNOT_INIT_DIRECT3D,\n\tNUM_TVP_CANNOT_FIND_DISPLAY_MODE,\n\tNUM_TVP_CANNOT_SWITCH_TO_FULL_SCREEN,\n\tNUM_TVP_INVALID_PROPERTY_IN_FULL_SCREEN,\n\tNUM_TVP_INVALID_METHOD_IN_FULL_SCREEN,\n\tNUM_TVP_CANNOT_LOAD_CURSOR,\n\tNUM_TVP_CANNOT_LOAD_KR_MOVIE_DLL,\n\tNUM_TVP_INVALID_KR_MOVIE_DLL,\n\tNUM_TVP_ERROR_IN_KR_MOVIE_DLL,\n\tNUM_TVP_WINDOW_ALREADY_MISSING,\n\tNUM_TVP_PRERENDERED_FONT_MAPPING_FAILED,\n\tNUM_TVP_CONFIG_FAIL_ORIGINAL_FILE_CANNOT_BE_REWRITTEN,\n\tNUM_TVP_CONFIG_FAIL_TEMP_EXE_NOT_ERASED,\n\tNUM_TVP_EXECUTION_FAIL,\n\tNUM_TVP_PLUGIN_UNBOUND_FUNCTION_ERROR,\n\tNUM_TVP_EXCEPTION_HAD_BEEN_OCCURED,\n\tNUM_TVP_CONSOLE_RESULT,\n\tNUM_TVP_INFO_LISTING_FILES,\n\tNUM_TVP_INFO_TOTAL_PHYSICAL_MEMORY,\n\tNUM_TVP_INFO_SELECTED_PROJECT_DIRECTORY,\n\tNUM_TVP_TOO_SMALL_EXECUTABLE_SIZE,\n\tNUM_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_FAILED,\n\tNUM_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_SUCCEEDED,\n\tNUM_TVP_FILE_NOT_FOUND,\n\tNUM_TVP_INFO_LOADING_CONFIGURATION_FILE_FAILED,\n\tNUM_TVP_INFO_LOADING_CONFIGURATION_FILE_SUCCEEDED,\n\tNUM_TVP_INFO_DATA_PATH_DOES_NOT_EXIST_TRYING_TO_MAKE_IT,\n\tNUM_TVP_OK,\n\tNUM_TVP_FAILD,\n\tNUM_TVP_INFO_DATA_PATH,\n\tNUM_TVP_INFO_SPECIFIED_OPTION_EARLIER_ITEM_HAS_MORE_PRIORITY,\n\tNUM_TVP_NONE,\n\tNUM_TVP_INFO_CPU_CLOCK_ROUGHLY,\n\tNUM_TVP_PROGRAM_STARTED_ON,\n\tNUM_TVP_KIRIKIRI,\n\tNUM_TVP_UNKNOWN_ERROR,\n\tNUM_TVP_EXIT_CODE,\n\tNUM_TVP_FATAL_ERROR,\n\tNUM_TVP_ENABLE_DIGITIZER,\n\tNUM_TVP_TOUCH_INTEGRATED_TOUCH,\n\tNUM_TVP_TOUCH_EXTERNAL_TOUCH,\n\tNUM_TVP_TOUCH_INTEGRATED_PEN,\n\tNUM_TVP_TOUCH_EXTERNAL_PEN,\n\tNUM_TVP_TOUCH_MULTI_INPUT,\n\tNUM_TVP_TOUCH_READY,\n\tNUM_TVP_CPU_CHECK_FAILURE,\n\tNUM_TVP_CPU_CHECK_FAILURE_CPU_FAMILY_OR_LESSER_IS_NOT_SUPPORTED,\n\tNUM_TVP_INFO_CPU_NUMBER,\n\tNUM_TVP_CPU_CHECK_FAILURE_NOT_SUPPRTED_CPU,\n\tNUM_TVP_INFO_FINALLY_DETECTED_CPU_FEATURES,\n\tNUM_TVP_CPU_CHECK_FAILURE_NOT_SUPPORTED_CPU,\n\tNUM_TVP_INFO_CPU_CLOCK,\n\tNUM_TVP_LAYER_BITMAP_BUFFER_UNDERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE,\n\tNUM_TVP_LAYER_BITMAP_BUFFER_OVERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE,\n\tNUM_TVP_FAILD_TO_CREATE_DIRECT3D,\n\tNUM_TVP_FAILD_TO_DECIDE_BACKBUFFER_FORMAT,\n\tNUM_TVP_FAILD_TO_CREATE_DIRECT3DDEVICE,\n\tNUM_TVP_FAILD_TO_SET_VIEWPORT,\n\tNUM_TVP_FAILD_TO_SET_RENDER_STATE,\n\tNUM_TVP_WARNING_IMAGE_SIZE_TOO_LARGE_MAY_BE_CANNOT_CREATE_TEXTURE,\n\tNUM_TVP_USE_POWER_OF_TWO_SURFACE,\n\tNUM_TVP_CANNOT_ALLOCATE_D3DOFF_SCREEN_SURFACE,\n\tNUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES,\n\tNUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES_UNKNOWN_REASON,\n\tNUM_TVP_BASIC_DRAW_DEVICE_TEXTURE_HAS_ALREADY_BEEN_LOCKED,\n\tNUM_TVP_INTERNAL_ERROR_RESULT,\n\tNUM_TVP_BASIC_DRAW_DEVICE_INF_POLYGON_DRAWING_FAILED,\n\tNUM_TVP_BASIC_DRAW_DEVICE_INF_DIRECT3DDEVICE_PRESENT_FAILED,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_RESTART,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_FLAGS,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_PARAM,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_FAILED,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_MODE,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_NOT_UPDATED,\n\tNUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_UNKNOWN_REASON,\n\tNUM_TVP_FAILED_TO_CREATE_SCREEN_DC,\n\tNUM_TVP_FAILED_TO_CREATE_OFFSCREEN_BITMAP,\n\tNUM_TVP_FAILED_TO_CREATE_OFFSCREEN_DC,\n\tNUM_TVP_INFO_SUSIE_PLUGIN_INFO,\n\tNUM_TVP_SUSIE_PLUGIN_UNSUPPORTED_BITMAP_HEADER,\n\tNUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE,\n\tNUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE_UNKNOWN_REASON,\n\tNUM_TVP_COULD_NOT_CREATE_ANY_DRAW_DEVICE,\n\tNUM_TVP_BASIC_DRAW_DEVICE_DOES_NOT_SUPPORTE_LAYER_MANAGER_MORE_THAN_ONE,\n\tNUM_TVP_INVALID_VIDEO_SIZE,\n\tNUM_TVP_ROUGH_VSYNC_INTERVAL_READ_FROM_API,\n\tNUM_TVP_ROUGH_VSYNC_INTERVAL_STILL_SEEMS_WRONG,\n\tNUM_TVP_INFO_FOUND_DIRECT3DINTERFACE,\n\tNUM_TVP_INFO_FAILD,\n\tNUM_TVP_INFO_DIRECT3D,\n\tNUM_TVP_CANNOT_LOAD_D3DDLL,\n\tNUM_TVP_NOT_FOUND_DIRECT3DCREATE,\n\tNUM_TVP_INFO_ENVIRONMENT_USING,\n\tNUM_TVP_INFO_SEARCH_BEST_FULLSCREEN_RESOLUTION,\n\tNUM_TVP_INFO_CONDITION_PREFERRED_SCREEN_MODE,\n\tNUM_TVP_INFO_CONDITION_MODE,\n\tNUM_TVP_INFO_CONDITION_ZOOM_MODE,\n\tNUM_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_MODE,\n\tNUM_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_ASPECT_RATIO,\n\tNUM_TVP_INFO_ENVIRONMENT_AVAILABLE_DISPLAY_MODES,\n\tNUM_TVP_INFO_NOT_FOUND_SCREEN_MODE_FROM_DRIVER,\n\tNUM_TVP_INFO_RESULT_CANDIDATES,\n\tNUM_TVP_INFO_TRY_SCREEN_MODE,\n\tNUM_TVP_ALL_SCREEN_MODE_ERROR,\n\tNUM_TVP_INFO_CHANGE_SCREEN_MODE_SUCCESS,\n\tNUM_TVP_SELECT_XP3FILE_OR_FOLDER,\n\tNUM_TVP_D3D_ERR_DEVICE_LOST,\n\tNUM_TVP_D3D_ERR_DRIVER_IINTERNAL_ERROR,\n\tNUM_TVP_D3D_ERR_INVALID_CALL,\n\tNUM_TVP_D3D_ERR_OUT_OF_VIDEO_MEMORY,\n\tNUM_TVP_D3D_ERR_OUT_OF_MEMORY,\n\tNUM_TVP_D3D_ERR_WRONG_TEXTURE_FORMAT,\n\tNUM_TVP_D3D_ERR_UNSUPORTED_COLOR_OPERATION,\n\tNUM_TVP_D3D_ERR_UNSUPORTED_COLOR_ARG,\n\tNUM_TVP_D3D_ERR_UNSUPORTED_AALPHT_OPERATION,\n\tNUM_TVP_D3D_ERR_UNSUPORTED_ALPHA_ARG,\n\tNUM_TVP_D3D_ERR_TOO_MANY_OPERATIONS,\n\tNUM_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_FILTER,\n\tNUM_TVP_D3D_ERR_UNSUPORTED_FACTOR_VALUE,\n\tNUM_TVP_D3D_ERR_CONFLICTIONING_RENDER_STATE,\n\tNUM_TVP_D3D_ERR_UNSUPPORTED_TEXTURE_FILTER,\n\tNUM_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_PALETTE,\n\tNUM_TVP_D3D_ERR_NOT_FOUND,\n\tNUM_TVP_D3D_ERR_MORE_DATA,\n\tNUM_TVP_D3D_ERR_DEVICE_NOT_RESET,\n\tNUM_TVP_D3D_ERR_NOT_AVAILABLE,\n\tNUM_TVP_D3D_ERR_INVALID_DEVICE,\n\tNUM_TVP_D3D_ERR_DRIVER_INVALID_CALL,\n\tNUM_TVP_D3D_ERR_WAS_STILL_DRAWING,\n\tNUM_TVP_D3D_ERR_DEVICE_HUNG,\n\tNUM_TVP_D3D_ERR_UNSUPPORTED_OVERLAY,\n\tNUM_TVP_D3D_ERR_UNSUPPORTED_OVERLAY_FORMAT,\n\tNUM_TVP_D3D_ERR_CANNOT_PROTECT_CONTENT,\n\tNUM_TVP_D3D_ERR_UNSUPPORTED_CRYPTO,\n\tNUM_TVP_D3D_ERR_PRESENT_STATISTICS_DIS_JOINT,\n\tNUM_TVP_D3D_ERR_DEVICE_REMOVED,\n\tNUM_TVP_D3D_OK_NO_AUTO_GEN,\n\tNUM_TVP_D3D_ERR_FAIL,\n\tNUM_TVP_D3D_ERR_INVALID_ARG,\n\tNUM_TVP_D3D_UNKNOWN_ERROR,\n\tNUM_TVP_EXCEPTION_ACCESS_VIOLATION,\n\tNUM_TVP_EXCEPTION_BREAKPOINT,\n\tNUM_TVP_EXCEPTION_DATATYPE_MISALIGNMENT,\n\tNUM_TVP_EXCEPTION_SINGLE_STEP,\n\tNUM_TVP_EXCEPTION_ARRAY_BOUNDS_EXCEEDED,\n\tNUM_TVP_EXCEPTION_FLT_DENORMAL_OPERAND,\n\tNUM_TVP_EXCEPTION_FLT_DIVIDE_BY_ZERO,\n\tNUM_TVP_EXCEPTION_FLT_INEXACT_RESULT,\n\tNUM_TVP_EXCEPTION_FLT_INVALID_OPERATION,\n\tNUM_TVP_EXCEPTION_FLT_OVERFLOW,\n\tNUM_TVP_EXCEPTION_FLT_STACK_CHECK,\n\tNUM_TVP_EXCEPTION_FLT_UNDERFLOW,\n\tNUM_TVP_EXCEPTION_INT_DIVIDE_BY_ZERO,\n\tNUM_TVP_EXCEPTION_INT_OVERFLOW,\n\tNUM_TVP_EXCEPTION_PRIV_INSTRUCTION,\n\tNUM_TVP_EXCEPTION_NONCONTINUABLE_EXCEPTION,\n\tNUM_TVP_EXCEPTION_GUARD_PAGE,\n\tNUM_TVP_EXCEPTION_ILLEGAL_INSTRUCTION,\n\tNUM_TVP_EXCEPTION_IN_PAGE_ERROR,\n\tNUM_TVP_EXCEPTION_INVALID_DISPOSITION,\n\tNUM_TVP_EXCEPTION_INVALID_HANDLE,\n\tNUM_TVP_EXCEPTION_STACK_OVERFLOW,\n\tNUM_TVP_EXCEPTION_UNWIND_CCONSOLIDATE,\n\tNUM_TVP_CANNOT_SHOW_MODAL_AREADY_SHOWED,\n\tNUM_TVP_CANNOT_SHOW_MODAL_SINGLE_WINDOW,\n\tNUM_MESSAGE_MAX\n};\nconst tjs_char* RESOURCE_MESSAGE[NUM_MESSAGE_MAX];\nconst int RESOURCE_IDS[NUM_MESSAGE_MAX] = {\n\tIDS_TJS_INTERNAL_ERROR,\n\tIDS_TJS_WARNING,\n\tIDS_TJS_WARN_EVAL_OPERATOR,\n\tIDS_TJS_NARROW_TO_WIDE_CONVERSION_ERROR,\n\tIDS_TJS_VARIANT_CONVERT_ERROR,\n\tIDS_TJS_VARIANT_CONVERT_ERROR_TO_OBJECT,\n\tIDS_TJS_IDEXPECTED,\n\tIDS_TJS_SUBSTITUTION_IN_BOOLEAN_CONTEXT,\n\tIDS_TJS_CANNOT_MODIFY_LHS,\n\tIDS_TJS_INSUFFICIENT_MEM,\n\tIDS_TJS_CANNOT_GET_RESULT,\n\tIDS_TJS_NULL_ACCESS,\n\tIDS_TJS_MEMBER_NOT_FOUND,\n\tIDS_TJS_MEMBER_NOT_FOUND_NO_NAME_GIVEN,\n\tIDS_TJS_NOT_IMPLEMENTED,\n\tIDS_TJS_INVALID_PARAM,\n\tIDS_TJS_BAD_PARAM_COUNT,\n\tIDS_TJS_INVALID_TYPE,\n\tIDS_TJS_SPECIFY_DIC_OR_ARRAY,\n\tIDS_TJS_SPECIFY_ARRAY,\n\tIDS_TJS_STRING_DEALLOC_ERROR,\n\tIDS_TJS_STRING_ALLOC_ERROR,\n\tIDS_TJS_MISPLACED_BREAK_CONTINUE,\n\tIDS_TJS_MISPLACED_CASE,\n\tIDS_TJS_MISPLACED_RETURN,\n\tIDS_TJS_STRING_PARSE_ERROR,\n\tIDS_TJS_NUMBER_ERROR,\n\tIDS_TJS_UNCLOSED_COMMENT,\n\tIDS_TJS_INVALID_CHAR,\n\tIDS_TJS_EXPECTED,\n\tIDS_TJS_SYNTAX_ERROR,\n\tIDS_TJS_PPERROR,\n\tIDS_TJS_CANNOT_GET_SUPER,\n\tIDS_TJS_INVALID_OPECODE,\n\tIDS_TJS_RANGE_ERROR,\n\tIDS_TJS_ACCESS_DENYED,\n\tIDS_TJS_NATIVE_CLASS_CRASH,\n\tIDS_TJS_INVALID_OBJECT,\n\tIDS_TJS_CANNOT_OMIT,\n\tIDS_TJS_CANNOT_PARSE_DATE,\n\tIDS_TJS_INVALID_VALUE_FOR_TIMESTAMP,\n\tIDS_TJS_EXCEPTION_NOT_FOUND,\n\tIDS_TJS_INVALID_FORMAT_STRING,\n\tIDS_TJS_DIVIDE_BY_ZERO,\n\tIDS_TJS_NOT_RECONSTRUCTIVE_RANDOMIZE_DATA,\n\tIDS_TJS_SYMBOL,\n\tIDS_TJS_CALL_HISTORY_IS_FROM_OUT_OF_TJS2SCRIPT,\n\tIDS_TJS_NOBJECTS_WAS_NOT_FREED,\n\tIDS_TJS_OBJECT_CREATION_HISTORY_DELIMITER_CRLF,\n\tIDS_TJS_OBJECT_CREATION_HISTORY_DELIMITER,\n\tIDS_TJS_OBJECT_WAS_NOT_FREED_CRLF,\n\tIDS_TJS_OBJECT_WAS_NOT_FREED,\n\tIDS_TJS_GROUP_BY_OBJECT_TYPE_AND_HISTORY,\n\tIDS_TJS_GROUP_BY_OBJECT_TYPE,\n\tIDS_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY_CRLF,\n\tIDS_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY,\n\tIDS_TJS_OBJECT_COUNTING_MESSAGE_TJSGROUP_BY_OBJECT_TYPE,\n\tIDS_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT_CRLF,\n\tIDS_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT,\n\tIDS_TJS_WRITE_ERROR,\n\tIDS_TJS_READ_ERROR,\n\tIDS_TJS_SEEK_ERROR,\n\tIDS_TJS_BYTE_CODE_BROKEN,\n\tIDS_TJS_OBJECT_HASH_MAP_LOG_VERSION_MISMATCH,\n\tIDS_TJS_CURRUPTED_OBJECT_HASH_MAP_LOG,\n\tIDS_TJS_UNKNOWN_FAILURE,\n\tIDS_TJS_UNKNOWN_PACK_UNPACK_TEMPLATE_CHARCTER,\n\tIDS_TJS_UNKNOWN_BIT_STRING_CHARACTER,\n\tIDS_TJS_UNKNOWN_HEX_STRING_CHARACTER,\n\tIDS_TJS_NOT_SUPPORTED_UUENCODE,\n\tIDS_TJS_NOT_SUPPORTED_BER,\n\tIDS_TJS_NOT_SUPPORTED_UNPACK_LP,\n\tIDS_TJS_NOT_SUPPORTED_UNPACK_P,\n\tIDS_TVP_VERSION_INFORMATION,\n\tIDS_TVP_VERSION_INFORMATION2,\n\tIDS_TVP_DOWNLOAD_PAGE_URL,\n\tIDS_TVP_INTERNAL_ERROR,\n\tIDS_TVP_INVALID_PARAM,\n\tIDS_TVP_WARN_DEBUG_OPTION_ENABLED,\n\tIDS_TVP_COMMAND_LINE_PARAM_IGNORED_AND_DEFAULT_USED,\n\tIDS_TVP_INVALID_COMMAND_LINE_PARAM,\n\tIDS_TVP_NOT_IMPLEMENTED,\n\tIDS_TVP_CANNOT_OPEN_STORAGE,\n\tIDS_TVP_CANNOT_FIND_STORAGE,\n\tIDS_TVP_CANNOT_OPEN_STORAGE_FOR_WRITE,\n\tIDS_TVP_STORAGE_IN_ARCHIVE_NOT_FOUND,\n\tIDS_TVP_INVALID_PATH_NAME,\n\tIDS_TVP_UNSUPPORTED_MEDIA_NAME,\n\tIDS_TVP_CANNOT_UNBIND_XP3EXE,\n\tIDS_TVP_CANNOT_FIND_XP3MARK,\n\tIDS_TVP_MISSING_PATH_DELIMITER_AT_LAST,\n\tIDS_TVP_FILENAME_CONTAINS_SHARP_WARN,\n\tIDS_TVP_CANNOT_GET_LOCAL_NAME,\n\tIDS_TVP_READ_ERROR,\n\tIDS_TVP_WRITE_ERROR,\n\tIDS_TVP_SEEK_ERROR,\n\tIDS_TVP_TRUNCATE_ERROR,\n\tIDS_TVP_INSUFFICIENT_MEMORY,\n\tIDS_TVP_UNCOMPRESSION_FAILED,\n\tIDS_TVP_COMPRESSION_FAILED,\n\tIDS_TVP_CANNOT_WRITE_TO_ARCHIVE,\n\tIDS_TVP_UNSUPPORTED_CIPHER_MODE,\n\tIDS_TVP_UNSUPPORTED_ENCODING,\n\tIDS_TVP_UNSUPPORTED_MODE_STRING,\n\tIDS_TVP_UNKNOWN_GRAPHIC_FORMAT,\n\tIDS_TVP_CANNOT_SUGGEST_GRAPHIC_EXTENSION,\n\tIDS_TVP_MASK_SIZE_MISMATCH,\n\tIDS_TVP_PROVINCE_SIZE_MISMATCH,\n\tIDS_TVP_IMAGE_LOAD_ERROR,\n\tIDS_TVP_JPEGLOAD_ERROR,\n\tIDS_TVP_PNGLOAD_ERROR,\n\tIDS_TVP_ERILOAD_ERROR,\n\tIDS_TVP_TLGLOAD_ERROR,\n\tIDS_TVP_INVALID_IMAGE_SAVE_TYPE,\n\tIDS_TVP_INVALID_OPERATION_FOR8BPP,\n\tIDS_TVP_INVALID_OPERATION_FOR32BPP,\n\tIDS_TVP_SPECIFY_WINDOW,\n\tIDS_TVP_SPECIFY_LAYER,\n\tIDS_TVP_SPECIFY_LAYER_OR_BITMAP,\n\tIDS_TVP_CANNOT_ACCEPT_MODE_AUTO,\n\tIDS_TVP_CANNOT_CREATE_EMPTY_LAYER_IMAGE,\n\tIDS_TVP_CANNOT_SET_PRIMARY_INVISIBLE,\n\tIDS_TVP_CANNOT_MOVE_PRIMARY,\n\tIDS_TVP_CANNOT_SET_PARENT_SELF,\n\tIDS_TVP_CANNOT_MOVE_NEXT_TO_SELF_OR_NOT_SIBLINGS,\n\tIDS_TVP_CANNOT_MOVE_PRIMARY_OR_SIBLINGLESS,\n\tIDS_TVP_CANNOT_MOVE_TO_UNDER_OTHER_PRIMARY_LAYER,\n\tIDS_TVP_INVALID_IMAGE_POSITION,\n\tIDS_TVP_CANNOT_SET_MODE_TO_DISABLED_OR_MODAL,\n\tIDS_TVP_NOT_DRAWABLE_LAYER_TYPE,\n\tIDS_TVP_SOURCE_LAYER_HAS_NO_IMAGE,\n\tIDS_TVP_UNSUPPORTED_LAYER_TYPE,\n\tIDS_TVP_NOT_DRAWABLE_FACE_TYPE,\n\tIDS_TVP_CANNOT_CONVERT_LAYER_TYPE_USING_GIVEN_DIRECTION,\n\tIDS_TVP_NEGATIVE_OPACITY_NOT_SUPPORTED_ON_THIS_FACE,\n\tIDS_TVP_SRC_RECT_OUT_OF_BITMAP,\n\tIDS_TVP_BOX_BLUR_AREA_MUST_CONTAIN_CENTER_PIXEL,\n\tIDS_TVP_BOX_BLUR_AREA_MUST_BE_SMALLER_THAN16MILLION,\n\tIDS_TVP_CANNOT_CHANGE_FOCUS_IN_PROCESSING_FOCUS,\n\tIDS_TVP_WINDOW_HAS_NO_LAYER,\n\tIDS_TVP_WINDOW_HAS_ALREADY_PRIMARY_LAYER,\n\tIDS_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER,\n\tIDS_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER2,\n\tIDS_TVP_SPECIFIED_EVENT_NAME_IS_UNKNOWN,\n\tIDS_TVP_OUT_OF_RECTANGLE,\n\tIDS_TVP_INVALID_METHOD_IN_UPDATING,\n\tIDS_TVP_CANNOT_CREATE_INSTANCE,\n\tIDS_TVP_UNKNOWN_WAVE_FORMAT,\n\tIDS_TVP_CURRENT_TRANSITION_MUST_BE_STOPPING,\n\tIDS_TVP_TRANS_HANDLER_ERROR,\n\tIDS_TVP_TRANS_ALREADY_REGISTERED,\n\tIDS_TVP_CANNOT_FIND_TRANS_HANDER,\n\tIDS_TVP_SPECIFY_TRANSITION_SOURCE,\n\tIDS_TVP_LAYER_CANNOT_HAVE_IMAGE,\n\tIDS_TVP_TRANSITION_SOURCE_AND_DESTINATION_MUST_HAVE_IMAGE,\n\tIDS_TVP_CANNOT_LOAD_RULE_GRAPHIC,\n\tIDS_TVP_SPECIFY_OPTION,\n\tIDS_TVP_TRANSITION_LAYER_SIZE_MISMATCH,\n\tIDS_TVP_TRANSITION_MUTUAL_SOURCE,\n\tIDS_TVP_HOLD_DESTINATION_ALPHA_PARAMETER_IS_NOW_DEPRECATED,\n\tIDS_TVP_CANNOT_CONNECT_MULTIPLE_WAVE_SOUND_BUFFER_AT_ONCE,\n\tIDS_TVP_INVALID_WINDOW_SIZE_MUST_BE_IN64TO32768,\n\tIDS_TVP_INVALID_OVERLAP_COUNT_MUST_BE_IN2TO32,\n\tIDS_TVP_CURRENTLY_ASYNC_LOAD_BITMAP,\n\tIDS_TVP_FAILD_CLIPBOARD_COPY,\n\tIDS_TVP_INVALID_UTF16TO_UTF8,\n\tIDS_TVP_INFO_LOADING_STARTUP_SCRIPT,\n\tIDS_TVP_INFO_STARTUP_SCRIPT_ENDED,\n\tIDS_TVP_TJS_CHAR_MUST_BE_TWO_OR_FOUR,\n\tIDS_TVP_MEDIA_NAME_HAD_ALREADY_BEEN_REGISTERED,\n\tIDS_TVP_MEDIA_NAME_IS_NOT_REGISTERED,\n\tIDS_TVP_INFO_REBUILDING_AUTO_PATH,\n\tIDS_TVP_INFO_TOTAL_FILE_FOUND_AND_ACTIVATED,\n\tIDS_TVP_ERROR_IN_RETRIEVING_SYSTEM_ON_ACTIVATE_ON_DEACTIVATE,\n\tIDS_TVP_THE_HOST_IS_NOT_A16BIT_UNICODE_SYSTEM,\n\tIDS_TVP_INFO_TRYING_TO_READ_XP3VIRTUAL_FILE_SYSTEM_INFORMATION_FROM,\n\tIDS_TVP_SPECIFIED_STORAGE_HAD_BEEN_PROTECTED,\n\tIDS_TVP_INFO_FAILED,\n\tIDS_TVP_INFO_DONE_WITH_CONTAINS,\n\tIDS_TVP_SEPARATOR_CRLF,\n\tIDS_TVP_SEPARATOR_CR,\n\tIDS_TVP_DEFAULT_FONT_NAME,\n\tIDS_TVP_CANNOT_OPEN_FONT_FILE,\n\tIDS_TVP_FONT_CANNOT_BE_USED,\n\tIDS_TVP_FONT_RASTERIZE_ERROR,\n\tIDS_TVP_BIT_FIELDS_NOT_SUPPORTED,\n\tIDS_TVP_COMPRESSED_BMP_NOT_SUPPORTED,\n\tIDS_TVP_UNSUPPORTED_COLOR_MODE_FOR_PALETT_IMAGE,\n\tIDS_TVP_NOT_WINDOWS_BMP,\n\tIDS_TVP_UNSUPPORTED_HEADER_VERSION,\n\tIDS_TVP_INFO_TOUCHING,\n\tIDS_TVP_ABORTED_TIME_OUT,\n\tIDS_TVP_ABORTED_LIMIT_BYTE,\n\tIDS_TVP_FAILD_GLYPH_FOR_DRAW_GLYPH,\n\tIDS_TVP_LAYER_OBJECT_IS_NOT_PROPERLY_CONSTRUCTED,\n\tIDS_TVP_UNKNOWN_UPDATE_TYPE,\n\tIDS_TVP_UNKNOWN_TRANSITION_TYPE,\n\tIDS_TVP_UNSUPPORTED_UPDATE_TYPE_TUT_GIVE_UPDATE,\n\tIDS_TVP_ERROR_CODE,\n\tIDS_TVP_UNSUPPORTED_JPEG_PALETTE,\n\tIDS_TVP_LIBPNG_ERROR,\n\tIDS_TVP_UNSUPPORTED_COLOR_TYPE_PALETTE,\n\tIDS_TVP_UNSUPPORTED_COLOR_TYPE,\n\tIDS_TVP_TOO_LARGE_IMAGE,\n\tIDS_TVP_PNG_SAVE_ERROR,\n\tIDS_TVP_TLG_UNSUPPORTED_UNIVERSAL_TRANSITION_RULE,\n\tIDS_TVP_UNSUPPORTED_COLOR_COUNT,\n\tIDS_TVP_DATA_FLAG_MUST_BE_ZERO,\n\tIDS_TVP_UNSUPPORTED_COLOR_TYPE_COLON,\n\tIDS_TVP_UNSUPPORTED_EXTERNAL_GOLOMB_BIT_LENGTH_TABLE,\n\tIDS_TVP_UNSUPPORTED_ENTROPY_CODING_METHOD,\n\tIDS_TVP_INVALID_TLG_HEADER_OR_VERSION,\n\tIDS_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_NAME_LENGTH,\n\tIDS_TVP_TLG_MALFORMED_TAG_MISSION_EQUALS_AFTER_NAME,\n\tIDS_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_VAUE_LENGTH,\n\tIDS_TVP_TLG_MALFORMED_TAG_MISSION_COMMA_AFTER_TAG,\n\tIDS_TVP_FILE_SIZE_IS_ZERO,\n\tIDS_TVP_MEMORY_ALLOCATION_ERROR,\n\tIDS_TVP_FILE_READ_ERROR,\n\tIDS_TVP_INVALID_PRERENDERED_FONT_FILE,\n\tIDS_TVP_NOT16BIT_UNICODE_FONT_FILE,\n\tIDS_TVP_INVALID_HEADER_VERSION,\n\tIDS_TVP_TLG_INSUFFICIENT_MEMORY,\n\tIDS_TVP_TLG_TOO_LARGE_BIT_LENGTH,\n\tIDS_TVP_CANNOT_RETRIVE_INTERFACE_FROM_DRAW_DEVICE,\n\tIDS_TVP_SCRIPT_EXCEPTION_RAISED,\n\tIDS_TVP_HARDWARE_EXCEPTION_RAISED,\n\tIDS_TVP_MAIN_CDPNAME,\n\tIDS_TVP_EXCEPTION_CDPNAME,\n\tIDS_TVP_CANNNOT_LOCATE_UIDLLFOR_FOLDER_SELECTION,\n\tIDS_TVP_INVALID_UIDLL,\n\tIDS_TVP_INVALID_BPP,\n\tIDS_TVP_CANNOT_LOAD_PLUGIN,\n\tIDS_TVP_NOT_VALID_PLUGIN,\n\tIDS_TVP_PLUGIN_UNINIT_FAILED,\n\tIDS_TVP_CANNNOT_LINK_PLUGIN_WHILE_PLUGIN_LINKING,\n\tIDS_TVP_NOT_SUSIE_PLUGIN,\n\tIDS_TVP_SUSIE_PLUGIN_ERROR,\n\tIDS_TVP_CANNOT_RELEASE_PLUGIN,\n\tIDS_TVP_NOT_LOADED_PLUGIN,\n\tIDS_TVP_CANNOT_ALLOCATE_BITMAP_BITS,\n\tIDS_TVP_SCAN_LINE_RANGE_OVER,\n\tIDS_TVP_PLUGIN_ERROR,\n\tIDS_TVP_INVALID_CDDADRIVE,\n\tIDS_TVP_CDDADRIVE_NOT_FOUND,\n\tIDS_TVP_MCIERROR,\n\tIDS_TVP_INVALID_SMF,\n\tIDS_TVP_MALFORMED_MIDIMESSAGE,\n\tIDS_TVP_CANNOT_INIT_DIRECT_SOUND,\n\tIDS_TVP_CANNOT_CREATE_DSSECONDARY_BUFFER,\n\tIDS_TVP_INVALID_LOOP_INFORMATION,\n\tIDS_TVP_NOT_CHILD_MENU_ITEM,\n\tIDS_TVP_CANNOT_INIT_DIRECT3D,\n\tIDS_TVP_CANNOT_FIND_DISPLAY_MODE,\n\tIDS_TVP_CANNOT_SWITCH_TO_FULL_SCREEN,\n\tIDS_TVP_INVALID_PROPERTY_IN_FULL_SCREEN,\n\tIDS_TVP_INVALID_METHOD_IN_FULL_SCREEN,\n\tIDS_TVP_CANNOT_LOAD_CURSOR,\n\tIDS_TVP_CANNOT_LOAD_KR_MOVIE_DLL,\n\tIDS_TVP_INVALID_KR_MOVIE_DLL,\n\tIDS_TVP_ERROR_IN_KR_MOVIE_DLL,\n\tIDS_TVP_WINDOW_ALREADY_MISSING,\n\tIDS_TVP_PRERENDERED_FONT_MAPPING_FAILED,\n\tIDS_TVP_CONFIG_FAIL_ORIGINAL_FILE_CANNOT_BE_REWRITTEN,\n\tIDS_TVP_CONFIG_FAIL_TEMP_EXE_NOT_ERASED,\n\tIDS_TVP_EXECUTION_FAIL,\n\tIDS_TVP_PLUGIN_UNBOUND_FUNCTION_ERROR,\n\tIDS_TVP_EXCEPTION_HAD_BEEN_OCCURED,\n\tIDS_TVP_CONSOLE_RESULT,\n\tIDS_TVP_INFO_LISTING_FILES,\n\tIDS_TVP_INFO_TOTAL_PHYSICAL_MEMORY,\n\tIDS_TVP_INFO_SELECTED_PROJECT_DIRECTORY,\n\tIDS_TVP_TOO_SMALL_EXECUTABLE_SIZE,\n\tIDS_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_FAILED,\n\tIDS_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_SUCCEEDED,\n\tIDS_TVP_FILE_NOT_FOUND,\n\tIDS_TVP_INFO_LOADING_CONFIGURATION_FILE_FAILED,\n\tIDS_TVP_INFO_LOADING_CONFIGURATION_FILE_SUCCEEDED,\n\tIDS_TVP_INFO_DATA_PATH_DOES_NOT_EXIST_TRYING_TO_MAKE_IT,\n\tIDS_TVP_OK,\n\tIDS_TVP_FAILD,\n\tIDS_TVP_INFO_DATA_PATH,\n\tIDS_TVP_INFO_SPECIFIED_OPTION_EARLIER_ITEM_HAS_MORE_PRIORITY,\n\tIDS_TVP_NONE,\n\tIDS_TVP_INFO_CPU_CLOCK_ROUGHLY,\n\tIDS_TVP_PROGRAM_STARTED_ON,\n\tIDS_TVP_KIRIKIRI,\n\tIDS_TVP_UNKNOWN_ERROR,\n\tIDS_TVP_EXIT_CODE,\n\tIDS_TVP_FATAL_ERROR,\n\tIDS_TVP_ENABLE_DIGITIZER,\n\tIDS_TVP_TOUCH_INTEGRATED_TOUCH,\n\tIDS_TVP_TOUCH_EXTERNAL_TOUCH,\n\tIDS_TVP_TOUCH_INTEGRATED_PEN,\n\tIDS_TVP_TOUCH_EXTERNAL_PEN,\n\tIDS_TVP_TOUCH_MULTI_INPUT,\n\tIDS_TVP_TOUCH_READY,\n\tIDS_TVP_CPU_CHECK_FAILURE,\n\tIDS_TVP_CPU_CHECK_FAILURE_CPU_FAMILY_OR_LESSER_IS_NOT_SUPPORTED,\n\tIDS_TVP_INFO_CPU_NUMBER,\n\tIDS_TVP_CPU_CHECK_FAILURE_NOT_SUPPRTED_CPU,\n\tIDS_TVP_INFO_FINALLY_DETECTED_CPU_FEATURES,\n\tIDS_TVP_CPU_CHECK_FAILURE_NOT_SUPPORTED_CPU,\n\tIDS_TVP_INFO_CPU_CLOCK,\n\tIDS_TVP_LAYER_BITMAP_BUFFER_UNDERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE,\n\tIDS_TVP_LAYER_BITMAP_BUFFER_OVERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE,\n\tIDS_TVP_FAILD_TO_CREATE_DIRECT3D,\n\tIDS_TVP_FAILD_TO_DECIDE_BACKBUFFER_FORMAT,\n\tIDS_TVP_FAILD_TO_CREATE_DIRECT3DDEVICE,\n\tIDS_TVP_FAILD_TO_SET_VIEWPORT,\n\tIDS_TVP_FAILD_TO_SET_RENDER_STATE,\n\tIDS_TVP_WARNING_IMAGE_SIZE_TOO_LARGE_MAY_BE_CANNOT_CREATE_TEXTURE,\n\tIDS_TVP_USE_POWER_OF_TWO_SURFACE,\n\tIDS_TVP_CANNOT_ALLOCATE_D3DOFF_SCREEN_SURFACE,\n\tIDS_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES,\n\tIDS_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES_UNKNOWN_REASON,\n\tIDS_TVP_BASIC_DRAW_DEVICE_TEXTURE_HAS_ALREADY_BEEN_LOCKED,\n\tIDS_TVP_INTERNAL_ERROR_RESULT,\n\tIDS_TVP_BASIC_DRAW_DEVICE_INF_POLYGON_DRAWING_FAILED,\n\tIDS_TVP_BASIC_DRAW_DEVICE_INF_DIRECT3DDEVICE_PRESENT_FAILED,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_RESTART,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_FLAGS,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_PARAM,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_FAILED,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_MODE,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_NOT_UPDATED,\n\tIDS_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_UNKNOWN_REASON,\n\tIDS_TVP_FAILED_TO_CREATE_SCREEN_DC,\n\tIDS_TVP_FAILED_TO_CREATE_OFFSCREEN_BITMAP,\n\tIDS_TVP_FAILED_TO_CREATE_OFFSCREEN_DC,\n\tIDS_TVP_INFO_SUSIE_PLUGIN_INFO,\n\tIDS_TVP_SUSIE_PLUGIN_UNSUPPORTED_BITMAP_HEADER,\n\tIDS_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE,\n\tIDS_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE_UNKNOWN_REASON,\n\tIDS_TVP_COULD_NOT_CREATE_ANY_DRAW_DEVICE,\n\tIDS_TVP_BASIC_DRAW_DEVICE_DOES_NOT_SUPPORTE_LAYER_MANAGER_MORE_THAN_ONE,\n\tIDS_TVP_INVALID_VIDEO_SIZE,\n\tIDS_TVP_ROUGH_VSYNC_INTERVAL_READ_FROM_API,\n\tIDS_TVP_ROUGH_VSYNC_INTERVAL_STILL_SEEMS_WRONG,\n\tIDS_TVP_INFO_FOUND_DIRECT3DINTERFACE,\n\tIDS_TVP_INFO_FAILD,\n\tIDS_TVP_INFO_DIRECT3D,\n\tIDS_TVP_CANNOT_LOAD_D3DDLL,\n\tIDS_TVP_NOT_FOUND_DIRECT3DCREATE,\n\tIDS_TVP_INFO_ENVIRONMENT_USING,\n\tIDS_TVP_INFO_SEARCH_BEST_FULLSCREEN_RESOLUTION,\n\tIDS_TVP_INFO_CONDITION_PREFERRED_SCREEN_MODE,\n\tIDS_TVP_INFO_CONDITION_MODE,\n\tIDS_TVP_INFO_CONDITION_ZOOM_MODE,\n\tIDS_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_MODE,\n\tIDS_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_ASPECT_RATIO,\n\tIDS_TVP_INFO_ENVIRONMENT_AVAILABLE_DISPLAY_MODES,\n\tIDS_TVP_INFO_NOT_FOUND_SCREEN_MODE_FROM_DRIVER,\n\tIDS_TVP_INFO_RESULT_CANDIDATES,\n\tIDS_TVP_INFO_TRY_SCREEN_MODE,\n\tIDS_TVP_ALL_SCREEN_MODE_ERROR,\n\tIDS_TVP_INFO_CHANGE_SCREEN_MODE_SUCCESS,\n\tIDS_TVP_SELECT_XP3FILE_OR_FOLDER,\n\tIDS_TVP_D3D_ERR_DEVICE_LOST,\n\tIDS_TVP_D3D_ERR_DRIVER_IINTERNAL_ERROR,\n\tIDS_TVP_D3D_ERR_INVALID_CALL,\n\tIDS_TVP_D3D_ERR_OUT_OF_VIDEO_MEMORY,\n\tIDS_TVP_D3D_ERR_OUT_OF_MEMORY,\n\tIDS_TVP_D3D_ERR_WRONG_TEXTURE_FORMAT,\n\tIDS_TVP_D3D_ERR_UNSUPORTED_COLOR_OPERATION,\n\tIDS_TVP_D3D_ERR_UNSUPORTED_COLOR_ARG,\n\tIDS_TVP_D3D_ERR_UNSUPORTED_AALPHT_OPERATION,\n\tIDS_TVP_D3D_ERR_UNSUPORTED_ALPHA_ARG,\n\tIDS_TVP_D3D_ERR_TOO_MANY_OPERATIONS,\n\tIDS_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_FILTER,\n\tIDS_TVP_D3D_ERR_UNSUPORTED_FACTOR_VALUE,\n\tIDS_TVP_D3D_ERR_CONFLICTIONING_RENDER_STATE,\n\tIDS_TVP_D3D_ERR_UNSUPPORTED_TEXTURE_FILTER,\n\tIDS_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_PALETTE,\n\tIDS_TVP_D3D_ERR_NOT_FOUND,\n\tIDS_TVP_D3D_ERR_MORE_DATA,\n\tIDS_TVP_D3D_ERR_DEVICE_NOT_RESET,\n\tIDS_TVP_D3D_ERR_NOT_AVAILABLE,\n\tIDS_TVP_D3D_ERR_INVALID_DEVICE,\n\tIDS_TVP_D3D_ERR_DRIVER_INVALID_CALL,\n\tIDS_TVP_D3D_ERR_WAS_STILL_DRAWING,\n\tIDS_TVP_D3D_ERR_DEVICE_HUNG,\n\tIDS_TVP_D3D_ERR_UNSUPPORTED_OVERLAY,\n\tIDS_TVP_D3D_ERR_UNSUPPORTED_OVERLAY_FORMAT,\n\tIDS_TVP_D3D_ERR_CANNOT_PROTECT_CONTENT,\n\tIDS_TVP_D3D_ERR_UNSUPPORTED_CRYPTO,\n\tIDS_TVP_D3D_ERR_PRESENT_STATISTICS_DIS_JOINT,\n\tIDS_TVP_D3D_ERR_DEVICE_REMOVED,\n\tIDS_TVP_D3D_OK_NO_AUTO_GEN,\n\tIDS_TVP_D3D_ERR_FAIL,\n\tIDS_TVP_D3D_ERR_INVALID_ARG,\n\tIDS_TVP_D3D_UNKNOWN_ERROR,\n\tIDS_TVP_EXCEPTION_ACCESS_VIOLATION,\n\tIDS_TVP_EXCEPTION_BREAKPOINT,\n\tIDS_TVP_EXCEPTION_DATATYPE_MISALIGNMENT,\n\tIDS_TVP_EXCEPTION_SINGLE_STEP,\n\tIDS_TVP_EXCEPTION_ARRAY_BOUNDS_EXCEEDED,\n\tIDS_TVP_EXCEPTION_FLT_DENORMAL_OPERAND,\n\tIDS_TVP_EXCEPTION_FLT_DIVIDE_BY_ZERO,\n\tIDS_TVP_EXCEPTION_FLT_INEXACT_RESULT,\n\tIDS_TVP_EXCEPTION_FLT_INVALID_OPERATION,\n\tIDS_TVP_EXCEPTION_FLT_OVERFLOW,\n\tIDS_TVP_EXCEPTION_FLT_STACK_CHECK,\n\tIDS_TVP_EXCEPTION_FLT_UNDERFLOW,\n\tIDS_TVP_EXCEPTION_INT_DIVIDE_BY_ZERO,\n\tIDS_TVP_EXCEPTION_INT_OVERFLOW,\n\tIDS_TVP_EXCEPTION_PRIV_INSTRUCTION,\n\tIDS_TVP_EXCEPTION_NONCONTINUABLE_EXCEPTION,\n\tIDS_TVP_EXCEPTION_GUARD_PAGE,\n\tIDS_TVP_EXCEPTION_ILLEGAL_INSTRUCTION,\n\tIDS_TVP_EXCEPTION_IN_PAGE_ERROR,\n\tIDS_TVP_EXCEPTION_INVALID_DISPOSITION,\n\tIDS_TVP_EXCEPTION_INVALID_HANDLE,\n\tIDS_TVP_EXCEPTION_STACK_OVERFLOW,\n\tIDS_TVP_EXCEPTION_UNWIND_CCONSOLIDATE,\n\tIDS_TVP_CANNOT_SHOW_MODAL_AREADY_SHOWED,\n\tIDS_TVP_CANNOT_SHOW_MODAL_SINGLE_WINDOW,\n};\nvoid TVPLoadMessage() {\n\tif( IS_LOAD_MESSAGE ) return;\n\tIS_LOAD_MESSAGE = true;\n\ttjs_char buffer[MAX_MESSAGE_LENGTH];\n\tHINSTANCE hInstance = ::GetModuleHandle(0);\n\tfor( int i = 0; i < NUM_MESSAGE_MAX; i++ ) {\n\t\tint len = ::LoadString( hInstance, RESOURCE_IDS[i], buffer, MAX_MESSAGE_LENGTH );\n\t\tif( len <= 0 ) {\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"Message Load Error!\") );\n\t\t}\n\t\ttjs_char* work = new tjs_char[len+1];\n\t\twcscpy_s( work, len+1, buffer );\n\t\tRESOURCE_MESSAGE[i] = work;\n\t}\n\tTJSInternalError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INTERNAL_ERROR] );\n\tTJSWarning.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_WARNING] );\n\tTJSWarnEvalOperator.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_WARN_EVAL_OPERATOR] );\n\tTJSNarrowToWideConversionError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NARROW_TO_WIDE_CONVERSION_ERROR] );\n\tTJSVariantConvertError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_VARIANT_CONVERT_ERROR] );\n\tTJSVariantConvertErrorToObject.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_VARIANT_CONVERT_ERROR_TO_OBJECT] );\n\tTJSIDExpected.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_IDEXPECTED] );\n\tTJSSubstitutionInBooleanContext.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SUBSTITUTION_IN_BOOLEAN_CONTEXT] );\n\tTJSCannotModifyLHS.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CANNOT_MODIFY_LHS] );\n\tTJSInsufficientMem.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INSUFFICIENT_MEM] );\n\tTJSCannotGetResult.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CANNOT_GET_RESULT] );\n\tTJSNullAccess.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NULL_ACCESS] );\n\tTJSMemberNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_MEMBER_NOT_FOUND] );\n\tTJSMemberNotFoundNoNameGiven.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_MEMBER_NOT_FOUND_NO_NAME_GIVEN] );\n\tTJSNotImplemented.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_IMPLEMENTED] );\n\tTJSInvalidParam.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_PARAM] );\n\tTJSBadParamCount.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_BAD_PARAM_COUNT] );\n\tTJSInvalidType.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_TYPE] );\n\tTJSSpecifyDicOrArray.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SPECIFY_DIC_OR_ARRAY] );\n\tTJSSpecifyArray.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SPECIFY_ARRAY] );\n\tTJSStringDeallocError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_STRING_DEALLOC_ERROR] );\n\tTJSStringAllocError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_STRING_ALLOC_ERROR] );\n\tTJSMisplacedBreakContinue.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_MISPLACED_BREAK_CONTINUE] );\n\tTJSMisplacedCase.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_MISPLACED_CASE] );\n\tTJSMisplacedReturn.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_MISPLACED_RETURN] );\n\tTJSStringParseError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_STRING_PARSE_ERROR] );\n\tTJSNumberError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NUMBER_ERROR] );\n\tTJSUnclosedComment.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_UNCLOSED_COMMENT] );\n\tTJSInvalidChar.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_CHAR] );\n\tTJSExpected.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_EXPECTED] );\n\tTJSSyntaxError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SYNTAX_ERROR] );\n\tTJSPPError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_PPERROR] );\n\tTJSCannotGetSuper.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CANNOT_GET_SUPER] );\n\tTJSInvalidOpecode.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_OPECODE] );\n\tTJSRangeError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_RANGE_ERROR] );\n\tTJSAccessDenyed.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_ACCESS_DENYED] );\n\tTJSNativeClassCrash.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NATIVE_CLASS_CRASH] );\n\tTJSInvalidObject.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_OBJECT] );\n\tTJSCannotOmit.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CANNOT_OMIT] );\n\tTJSCannotParseDate.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CANNOT_PARSE_DATE] );\n\tTJSInvalidValueForTimestamp.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_VALUE_FOR_TIMESTAMP] );\n\tTJSExceptionNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_EXCEPTION_NOT_FOUND] );\n\tTJSInvalidFormatString.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_INVALID_FORMAT_STRING] );\n\tTJSDivideByZero.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_DIVIDE_BY_ZERO] );\n\tTJSNotReconstructiveRandomizeData.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_RECONSTRUCTIVE_RANDOMIZE_DATA] );\n\tTJSSymbol.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SYMBOL] );\n\tTJSCallHistoryIsFromOutOfTJS2Script.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CALL_HISTORY_IS_FROM_OUT_OF_TJS2SCRIPT] );\n\tTJSNObjectsWasNotFreed.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOBJECTS_WAS_NOT_FREED] );\n#ifdef TJS_TEXT_OUT_CRLF\n\tTJSObjectCreationHistoryDelimiter.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_CREATION_HISTORY_DELIMITER_CRLF] );\n#else\n\tTJSObjectCreationHistoryDelimiter.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_CREATION_HISTORY_DELIMITER] );\n#endif\n#ifdef TJS_TEXT_OUT_CRLF\n\tTJSObjectWasNotFreed.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_WAS_NOT_FREED_CRLF] );\n#else\n\tTJSObjectWasNotFreed.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_WAS_NOT_FREED] );\n#endif\n\tTJSGroupByObjectTypeAndHistory.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_GROUP_BY_OBJECT_TYPE_AND_HISTORY] );\n\tTJSGroupByObjectType.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_GROUP_BY_OBJECT_TYPE] );\n#ifdef TJS_TEXT_OUT_CRLF\n\tTJSObjectCountingMessageGroupByObjectTypeAndHistory.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY_CRLF] );\n#else\n\tTJSObjectCountingMessageGroupByObjectTypeAndHistory.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_COUNTING_MESSAGE_GROUP_BY_OBJECT_TYPE_AND_HISTORY] );\n#endif\n\tTJSObjectCountingMessageTJSGroupByObjectType.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_COUNTING_MESSAGE_TJSGROUP_BY_OBJECT_TYPE] );\n#ifdef TJS_TEXT_OUT_CRLF\n\tTJSWarnRunningCodeOnDeletingObject.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT_CRLF] );\n#else\n\tTJSWarnRunningCodeOnDeletingObject.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_WARN_RUNNING_CODE_ON_DELETING_OBJECT] );\n#endif\n\tTJSWriteError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_WRITE_ERROR] );\n\tTJSReadError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_READ_ERROR] );\n\tTJSSeekError.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_SEEK_ERROR] );\n\tTJSByteCodeBroken.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_BYTE_CODE_BROKEN] );\n\tTJSObjectHashMapLogVersionMismatch.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_OBJECT_HASH_MAP_LOG_VERSION_MISMATCH] );\n\tTJSCurruptedObjectHashMapLog.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_CURRUPTED_OBJECT_HASH_MAP_LOG] );\n\tTJSUnknownFailure.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_UNKNOWN_FAILURE] );\n\tTJSUnknownPackUnpackTemplateCharcter.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_UNKNOWN_PACK_UNPACK_TEMPLATE_CHARCTER] );\n\tTJSUnknownBitStringCharacter.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_UNKNOWN_BIT_STRING_CHARACTER] );\n\tTJSUnknownHexStringCharacter.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_UNKNOWN_HEX_STRING_CHARACTER] );\n\tTJSNotSupportedUuencode.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_SUPPORTED_UUENCODE] );\n\tTJSNotSupportedBER.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_SUPPORTED_BER] );\n\tTJSNotSupportedUnpackLP.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_SUPPORTED_UNPACK_LP] );\n\tTJSNotSupportedUnpackP.AssignMessage( RESOURCE_MESSAGE[NUM_TJS_NOT_SUPPORTED_UNPACK_P] );\n\tTVPVersionInformation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_VERSION_INFORMATION] );\n\tTVPVersionInformation2.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_VERSION_INFORMATION2] );\n\tTVPDownloadPageURL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_DOWNLOAD_PAGE_URL] );\n\tTVPInternalError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INTERNAL_ERROR] );\n\tTVPInvalidParam.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_PARAM] );\n\tTVPWarnDebugOptionEnabled.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WARN_DEBUG_OPTION_ENABLED] );\n\tTVPCommandLineParamIgnoredAndDefaultUsed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_COMMAND_LINE_PARAM_IGNORED_AND_DEFAULT_USED] );\n\tTVPInvalidCommandLineParam.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_COMMAND_LINE_PARAM] );\n\tTVPNotImplemented.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_IMPLEMENTED] );\n\tTVPCannotOpenStorage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_OPEN_STORAGE] );\n\tTVPCannotFindStorage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_FIND_STORAGE] );\n\tTVPCannotOpenStorageForWrite.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_OPEN_STORAGE_FOR_WRITE] );\n\tTVPStorageInArchiveNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_STORAGE_IN_ARCHIVE_NOT_FOUND] );\n\tTVPInvalidPathName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_PATH_NAME] );\n\tTVPUnsupportedMediaName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_MEDIA_NAME] );\n\tTVPCannotUnbindXP3EXE.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_UNBIND_XP3EXE] );\n\tTVPCannotFindXP3Mark.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_FIND_XP3MARK] );\n\tTVPMissingPathDelimiterAtLast.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MISSING_PATH_DELIMITER_AT_LAST] );\n\tTVPFilenameContainsSharpWarn.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FILENAME_CONTAINS_SHARP_WARN] );\n\tTVPCannotGetLocalName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_GET_LOCAL_NAME] );\n\tTVPReadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_READ_ERROR] );\n\tTVPWriteError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WRITE_ERROR] );\n\tTVPSeekError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SEEK_ERROR] );\n\tTVPTruncateError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRUNCATE_ERROR] );\n\tTVPInsufficientMemory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INSUFFICIENT_MEMORY] );\n\tTVPUncompressionFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNCOMPRESSION_FAILED] );\n\tTVPCompressionFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_COMPRESSION_FAILED] );\n\tTVPCannotWriteToArchive.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_WRITE_TO_ARCHIVE] );\n\tTVPUnsupportedCipherMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_CIPHER_MODE] );\n\tTVPUnsupportedEncoding.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_ENCODING] );\n\tTVPUnsupportedModeString.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_MODE_STRING] );\n\tTVPUnknownGraphicFormat.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNKNOWN_GRAPHIC_FORMAT] );\n\tTVPCannotSuggestGraphicExtension.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SUGGEST_GRAPHIC_EXTENSION] );\n\tTVPMaskSizeMismatch.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MASK_SIZE_MISMATCH] );\n\tTVPProvinceSizeMismatch.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PROVINCE_SIZE_MISMATCH] );\n\tTVPImageLoadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_IMAGE_LOAD_ERROR] );\n\tTVPJPEGLoadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_JPEGLOAD_ERROR] );\n\tTVPPNGLoadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PNGLOAD_ERROR] );\n\tTVPERILoadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ERILOAD_ERROR] );\n\tTVPTLGLoadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLGLOAD_ERROR] );\n\tTVPInvalidImageSaveType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_IMAGE_SAVE_TYPE] );\n\tTVPInvalidOperationFor8BPP.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_OPERATION_FOR8BPP] );\n\tTVPInvalidOperationFor32BPP.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_OPERATION_FOR32BPP] );\n\tTVPSpecifyWindow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFY_WINDOW] );\n\tTVPSpecifyLayer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFY_LAYER] );\n\tTVPSpecifyLayerOrBitmap.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFY_LAYER_OR_BITMAP] );\n\tTVPCannotAcceptModeAuto.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_ACCEPT_MODE_AUTO] );\n\tTVPCannotCreateEmptyLayerImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CREATE_EMPTY_LAYER_IMAGE] );\n\tTVPCannotSetPrimaryInvisible.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SET_PRIMARY_INVISIBLE] );\n\tTVPCannotMovePrimary.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_MOVE_PRIMARY] );\n\tTVPCannotSetParentSelf.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SET_PARENT_SELF] );\n\tTVPCannotMoveNextToSelfOrNotSiblings.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_MOVE_NEXT_TO_SELF_OR_NOT_SIBLINGS] );\n\tTVPCannotMovePrimaryOrSiblingless.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_MOVE_PRIMARY_OR_SIBLINGLESS] );\n\tTVPCannotMoveToUnderOtherPrimaryLayer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_MOVE_TO_UNDER_OTHER_PRIMARY_LAYER] );\n\tTVPInvalidImagePosition.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_IMAGE_POSITION] );\n\tTVPCannotSetModeToDisabledOrModal.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SET_MODE_TO_DISABLED_OR_MODAL] );\n\tTVPNotDrawableLayerType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_DRAWABLE_LAYER_TYPE] );\n\tTVPSourceLayerHasNoImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SOURCE_LAYER_HAS_NO_IMAGE] );\n\tTVPUnsupportedLayerType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_LAYER_TYPE] );\n\tTVPNotDrawableFaceType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_DRAWABLE_FACE_TYPE] );\n\tTVPCannotConvertLayerTypeUsingGivenDirection.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CONVERT_LAYER_TYPE_USING_GIVEN_DIRECTION] );\n\tTVPNegativeOpacityNotSupportedOnThisFace.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NEGATIVE_OPACITY_NOT_SUPPORTED_ON_THIS_FACE] );\n\tTVPSrcRectOutOfBitmap.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SRC_RECT_OUT_OF_BITMAP] );\n\tTVPBoxBlurAreaMustContainCenterPixel.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BOX_BLUR_AREA_MUST_CONTAIN_CENTER_PIXEL] );\n\tTVPBoxBlurAreaMustBeSmallerThan16Million.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BOX_BLUR_AREA_MUST_BE_SMALLER_THAN16MILLION] );\n\tTVPCannotChangeFocusInProcessingFocus.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CHANGE_FOCUS_IN_PROCESSING_FOCUS] );\n\tTVPWindowHasNoLayer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WINDOW_HAS_NO_LAYER] );\n\tTVPWindowHasAlreadyPrimaryLayer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WINDOW_HAS_ALREADY_PRIMARY_LAYER] );\n\tTVPSpecifiedEventNeedsParameter.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER] );\n\tTVPSpecifiedEventNeedsParameter2.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFIED_EVENT_NEEDS_PARAMETER2] );\n\tTVPSpecifiedEventNameIsUnknown.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFIED_EVENT_NAME_IS_UNKNOWN] );\n\tTVPOutOfRectangle.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_OUT_OF_RECTANGLE] );\n\tTVPInvalidMethodInUpdating.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_METHOD_IN_UPDATING] );\n\tTVPCannotCreateInstance.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CREATE_INSTANCE] );\n\tTVPUnknownWaveFormat.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNKNOWN_WAVE_FORMAT] );\n\tTVPCurrentTransitionMustBeStopping.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CURRENT_TRANSITION_MUST_BE_STOPPING] );\n\tTVPTransHandlerError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRANS_HANDLER_ERROR] );\n\tTVPTransAlreadyRegistered.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRANS_ALREADY_REGISTERED] );\n\tTVPCannotFindTransHander.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_FIND_TRANS_HANDER] );\n\tTVPSpecifyTransitionSource.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFY_TRANSITION_SOURCE] );\n\tTVPLayerCannotHaveImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_LAYER_CANNOT_HAVE_IMAGE] );\n\tTVPTransitionSourceAndDestinationMustHaveImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRANSITION_SOURCE_AND_DESTINATION_MUST_HAVE_IMAGE] );\n\tTVPCannotLoadRuleGraphic.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_LOAD_RULE_GRAPHIC] );\n\tTVPSpecifyOption.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFY_OPTION] );\n\tTVPTransitionLayerSizeMismatch.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRANSITION_LAYER_SIZE_MISMATCH] );\n\tTVPTransitionMutualSource.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TRANSITION_MUTUAL_SOURCE] );\n\tTVPHoldDestinationAlphaParameterIsNowDeprecated.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_HOLD_DESTINATION_ALPHA_PARAMETER_IS_NOW_DEPRECATED] );\n\tTVPCannotConnectMultipleWaveSoundBufferAtOnce.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CONNECT_MULTIPLE_WAVE_SOUND_BUFFER_AT_ONCE] );\n\tTVPInvalidWindowSizeMustBeIn64to32768.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_WINDOW_SIZE_MUST_BE_IN64TO32768] );\n\tTVPInvalidOverlapCountMustBeIn2to32.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_OVERLAP_COUNT_MUST_BE_IN2TO32] );\n\tTVPCurrentlyAsyncLoadBitmap.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CURRENTLY_ASYNC_LOAD_BITMAP] );\n\tTVPFaildClipboardCopy.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_CLIPBOARD_COPY] );\n\tTVPInvalidUTF16ToUTF8.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_UTF16TO_UTF8] );\n\tTVPInfoLoadingStartupScript.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LOADING_STARTUP_SCRIPT] );\n\tTVPInfoStartupScriptEnded.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_STARTUP_SCRIPT_ENDED] );\n\tTVPTjsCharMustBeTwoOrFour.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TJS_CHAR_MUST_BE_TWO_OR_FOUR] );\n\tTVPMediaNameHadAlreadyBeenRegistered.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MEDIA_NAME_HAD_ALREADY_BEEN_REGISTERED] );\n\tTVPMediaNameIsNotRegistered.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MEDIA_NAME_IS_NOT_REGISTERED] );\n\tTVPInfoRebuildingAutoPath.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_REBUILDING_AUTO_PATH] );\n\tTVPInfoTotalFileFoundAndActivated.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_TOTAL_FILE_FOUND_AND_ACTIVATED] );\n\tTVPErrorInRetrievingSystemOnActivateOnDeactivate.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ERROR_IN_RETRIEVING_SYSTEM_ON_ACTIVATE_ON_DEACTIVATE] );\n\tTVPTheHostIsNotA16BitUnicodeSystem.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_THE_HOST_IS_NOT_A16BIT_UNICODE_SYSTEM] );\n\tTVPInfoTryingToReadXp3VirtualFileSystemInformationFrom.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_TRYING_TO_READ_XP3VIRTUAL_FILE_SYSTEM_INFORMATION_FROM] );\n\tTVPSpecifiedStorageHadBeenProtected.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SPECIFIED_STORAGE_HAD_BEEN_PROTECTED] );\n\tTVPInfoFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_FAILED] );\n\tTVPInfoDoneWithContains.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_DONE_WITH_CONTAINS] );\n\tTVPSeparatorCRLF.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SEPARATOR_CRLF] );\n\tTVPSeparatorCR.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SEPARATOR_CR] );\n\tTVPDefaultFontName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_DEFAULT_FONT_NAME] );\n\tTVPCannotOpenFontFile.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_OPEN_FONT_FILE] );\n\tTVPFontCannotBeUsed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FONT_CANNOT_BE_USED] );\n\tTVPFontRasterizeError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FONT_RASTERIZE_ERROR] );\n\tTVPBitFieldsNotSupported.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BIT_FIELDS_NOT_SUPPORTED] );\n\tTVPCompressedBmpNotSupported.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_COMPRESSED_BMP_NOT_SUPPORTED] );\n\tTVPUnsupportedColorModeForPalettImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_COLOR_MODE_FOR_PALETT_IMAGE] );\n\tTVPNotWindowsBmp.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_WINDOWS_BMP] );\n\tTVPUnsupportedHeaderVersion.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_HEADER_VERSION] );\n\tTVPInfoTouching.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_TOUCHING] );\n\tTVPAbortedTimeOut.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ABORTED_TIME_OUT] );\n\tTVPAbortedLimitByte.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ABORTED_LIMIT_BYTE] );\n\tTVPFaildGlyphForDrawGlyph.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_GLYPH_FOR_DRAW_GLYPH] );\n\tTVPLayerObjectIsNotProperlyConstructed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_LAYER_OBJECT_IS_NOT_PROPERLY_CONSTRUCTED] );\n\tTVPUnknownUpdateType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNKNOWN_UPDATE_TYPE] );\n\tTVPUnknownTransitionType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNKNOWN_TRANSITION_TYPE] );\n\tTVPUnsupportedUpdateTypeTutGiveUpdate.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_UPDATE_TYPE_TUT_GIVE_UPDATE] );\n\tTVPErrorCode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ERROR_CODE] );\n\tTVPUnsupportedJpegPalette.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_JPEG_PALETTE] );\n\tTVPLibpngError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_LIBPNG_ERROR] );\n\tTVPUnsupportedColorTypePalette.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_COLOR_TYPE_PALETTE] );\n\tTVPUnsupportedColorType.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_COLOR_TYPE] );\n\tTVPTooLargeImage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOO_LARGE_IMAGE] );\n\tTVPPngSaveError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PNG_SAVE_ERROR] );\n\tTVPTlgUnsupportedUniversalTransitionRule.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_UNSUPPORTED_UNIVERSAL_TRANSITION_RULE] );\n\tTVPUnsupportedColorCount.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_COLOR_COUNT] );\n\tTVPDataFlagMustBeZero.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_DATA_FLAG_MUST_BE_ZERO] );\n\tTVPUnsupportedColorTypeColon.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_COLOR_TYPE_COLON] );\n\tTVPUnsupportedExternalGolombBitLengthTable.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_EXTERNAL_GOLOMB_BIT_LENGTH_TABLE] );\n\tTVPUnsupportedEntropyCodingMethod.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNSUPPORTED_ENTROPY_CODING_METHOD] );\n\tTVPInvalidTlgHeaderOrVersion.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_TLG_HEADER_OR_VERSION] );\n\tTVPTlgMalformedTagMissionColonAfterNameLength.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_NAME_LENGTH] );\n\tTVPTlgMalformedTagMissionEqualsAfterName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_MALFORMED_TAG_MISSION_EQUALS_AFTER_NAME] );\n\tTVPTlgMalformedTagMissionColonAfterVaueLength.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_MALFORMED_TAG_MISSION_COLON_AFTER_VAUE_LENGTH] );\n\tTVPTlgMalformedTagMissionCommaAfterTag.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_MALFORMED_TAG_MISSION_COMMA_AFTER_TAG] );\n\tTVPFileSizeIsZero.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FILE_SIZE_IS_ZERO] );\n\tTVPMemoryAllocationError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MEMORY_ALLOCATION_ERROR] );\n\tTVPFileReadError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FILE_READ_ERROR] );\n\tTVPInvalidPrerenderedFontFile.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_PRERENDERED_FONT_FILE] );\n\tTVPNot16BitUnicodeFontFile.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT16BIT_UNICODE_FONT_FILE] );\n\tTVPInvalidHeaderVersion.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_HEADER_VERSION] );\n\tTVPTlgInsufficientMemory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_INSUFFICIENT_MEMORY] );\n\tTVPTlgTooLargeBitLength.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TLG_TOO_LARGE_BIT_LENGTH] );\n\tTVPCannotRetriveInterfaceFromDrawDevice.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_RETRIVE_INTERFACE_FROM_DRAW_DEVICE] );\n\tTVPScriptExceptionRaised.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SCRIPT_EXCEPTION_RAISED] );\n\tTVPHardwareExceptionRaised.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_HARDWARE_EXCEPTION_RAISED] );\n\tTVPMainCDPName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MAIN_CDPNAME] );\n\tTVPExceptionCDPName.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_CDPNAME] );\n\tTVPCannnotLocateUIDLLForFolderSelection.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNNOT_LOCATE_UIDLLFOR_FOLDER_SELECTION] );\n\tTVPInvalidUIDLL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_UIDLL] );\n\tTVPInvalidBPP.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_BPP] );\n\tTVPCannotLoadPlugin.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_LOAD_PLUGIN] );\n\tTVPNotValidPlugin.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_VALID_PLUGIN] );\n\tTVPPluginUninitFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PLUGIN_UNINIT_FAILED] );\n\tTVPCannnotLinkPluginWhilePluginLinking.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNNOT_LINK_PLUGIN_WHILE_PLUGIN_LINKING] );\n\tTVPNotSusiePlugin.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_SUSIE_PLUGIN] );\n\tTVPSusiePluginError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SUSIE_PLUGIN_ERROR] );\n\tTVPCannotReleasePlugin.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_RELEASE_PLUGIN] );\n\tTVPNotLoadedPlugin.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_LOADED_PLUGIN] );\n\tTVPCannotAllocateBitmapBits.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_ALLOCATE_BITMAP_BITS] );\n\tTVPScanLineRangeOver.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SCAN_LINE_RANGE_OVER] );\n\tTVPPluginError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PLUGIN_ERROR] );\n\tTVPInvalidCDDADrive.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_CDDADRIVE] );\n\tTVPCDDADriveNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CDDADRIVE_NOT_FOUND] );\n\tTVPMCIError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MCIERROR] );\n\tTVPInvalidSMF.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_SMF] );\n\tTVPMalformedMIDIMessage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_MALFORMED_MIDIMESSAGE] );\n\tTVPCannotInitDirectSound.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_INIT_DIRECT_SOUND] );\n\tTVPCannotCreateDSSecondaryBuffer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_CREATE_DSSECONDARY_BUFFER] );\n\tTVPInvalidLoopInformation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_LOOP_INFORMATION] );\n\tTVPNotChildMenuItem.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_CHILD_MENU_ITEM] );\n\tTVPCannotInitDirect3D.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_INIT_DIRECT3D] );\n\tTVPCannotFindDisplayMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_FIND_DISPLAY_MODE] );\n\tTVPCannotSwitchToFullScreen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SWITCH_TO_FULL_SCREEN] );\n\tTVPInvalidPropertyInFullScreen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_PROPERTY_IN_FULL_SCREEN] );\n\tTVPInvalidMethodInFullScreen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_METHOD_IN_FULL_SCREEN] );\n\tTVPCannotLoadCursor.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_LOAD_CURSOR] );\n\tTVPCannotLoadKrMovieDLL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_LOAD_KR_MOVIE_DLL] );\n\tTVPInvalidKrMovieDLL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_KR_MOVIE_DLL] );\n\tTVPErrorInKrMovieDLL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ERROR_IN_KR_MOVIE_DLL] );\n\tTVPWindowAlreadyMissing.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WINDOW_ALREADY_MISSING] );\n\tTVPPrerenderedFontMappingFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PRERENDERED_FONT_MAPPING_FAILED] );\n\tTVPConfigFailOriginalFileCannotBeRewritten.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CONFIG_FAIL_ORIGINAL_FILE_CANNOT_BE_REWRITTEN] );\n\tTVPConfigFailTempExeNotErased.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CONFIG_FAIL_TEMP_EXE_NOT_ERASED] );\n\tTVPExecutionFail.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXECUTION_FAIL] );\n\tTVPPluginUnboundFunctionError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PLUGIN_UNBOUND_FUNCTION_ERROR] );\n\tTVPExceptionHadBeenOccured.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_HAD_BEEN_OCCURED] );\n\tTVPConsoleResult.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CONSOLE_RESULT] );\n\tTVPInfoListingFiles.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LISTING_FILES] );\n\tTVPInfoTotalPhysicalMemory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_TOTAL_PHYSICAL_MEMORY] );\n\tTVPInfoSelectedProjectDirectory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_SELECTED_PROJECT_DIRECTORY] );\n\tTVPTooSmallExecutableSize.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOO_SMALL_EXECUTABLE_SIZE] );\n\tTVPInfoLoadingExecutableEmbeddedOptionsFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_FAILED] );\n\tTVPInfoLoadingExecutableEmbeddedOptionsSucceeded.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LOADING_EXECUTABLE_EMBEDDED_OPTIONS_SUCCEEDED] );\n\tTVPFileNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FILE_NOT_FOUND] );\n\tTVPInfoLoadingConfigurationFileFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LOADING_CONFIGURATION_FILE_FAILED] );\n\tTVPInfoLoadingConfigurationFileSucceeded.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_LOADING_CONFIGURATION_FILE_SUCCEEDED] );\n\tTVPInfoDataPathDoesNotExistTryingToMakeIt.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_DATA_PATH_DOES_NOT_EXIST_TRYING_TO_MAKE_IT] );\n\tTVPOk.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_OK] );\n\tTVPFaild.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD] );\n\tTVPInfoDataPath.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_DATA_PATH] );\n\tTVPInfoSpecifiedOptionEarlierItemHasMorePriority.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_SPECIFIED_OPTION_EARLIER_ITEM_HAS_MORE_PRIORITY] );\n\tTVPNone.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NONE] );\n\tTVPInfoCpuClockRoughly.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CPU_CLOCK_ROUGHLY] );\n\tTVPProgramStartedOn.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_PROGRAM_STARTED_ON] );\n\tTVPKirikiri.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_KIRIKIRI] );\n\tTVPUnknownError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_UNKNOWN_ERROR] );\n\tTVPExitCode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXIT_CODE] );\n\tTVPFatalError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FATAL_ERROR] );\n\tTVPEnableDigitizer.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ENABLE_DIGITIZER] );\n\tTVPTouchIntegratedTouch.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_INTEGRATED_TOUCH] );\n\tTVPTouchExternalTouch.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_EXTERNAL_TOUCH] );\n\tTVPTouchIntegratedPen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_INTEGRATED_PEN] );\n\tTVPTouchExternalPen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_EXTERNAL_PEN] );\n\tTVPTouchMultiInput.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_MULTI_INPUT] );\n\tTVPTouchReady.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_TOUCH_READY] );\n\tTVPCpuCheckFailure.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CPU_CHECK_FAILURE] );\n\tTVPCpuCheckFailureCpuFamilyOrLesserIsNotSupported.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CPU_CHECK_FAILURE_CPU_FAMILY_OR_LESSER_IS_NOT_SUPPORTED] );\n\tTVPInfoCpuNumber.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CPU_NUMBER] );\n\tTVPCpuCheckFailureNotSupprtedCpu.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CPU_CHECK_FAILURE_NOT_SUPPRTED_CPU] );\n\tTVPInfoFinallyDetectedCpuFeatures.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_FINALLY_DETECTED_CPU_FEATURES] );\n\tTVPCpuCheckFailureNotSupportedCpu.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CPU_CHECK_FAILURE_NOT_SUPPORTED_CPU] );\n\tTVPInfoCpuClock.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CPU_CLOCK] );\n\tTVPLayerBitmapBufferUnderrunDetectedCheckYourDrawingCode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_LAYER_BITMAP_BUFFER_UNDERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE] );\n\tTVPLayerBitmapBufferOverrunDetectedCheckYourDrawingCode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_LAYER_BITMAP_BUFFER_OVERRUN_DETECTED_CHECK_YOUR_DRAWING_CODE] );\n\tTVPFaildToCreateDirect3D.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_TO_CREATE_DIRECT3D] );\n\tTVPFaildToDecideBackbufferFormat.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_TO_DECIDE_BACKBUFFER_FORMAT] );\n\tTVPFaildToCreateDirect3DDevice.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_TO_CREATE_DIRECT3DDEVICE] );\n\tTVPFaildToSetViewport.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_TO_SET_VIEWPORT] );\n\tTVPFaildToSetRenderState.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILD_TO_SET_RENDER_STATE] );\n\tTVPWarningImageSizeTooLargeMayBeCannotCreateTexture.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_WARNING_IMAGE_SIZE_TOO_LARGE_MAY_BE_CANNOT_CREATE_TEXTURE] );\n\tTVPUsePowerOfTwoSurface.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_USE_POWER_OF_TWO_SURFACE] );\n\tTVPCannotAllocateD3DOffScreenSurface.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_ALLOCATE_D3DOFF_SCREEN_SURFACE] );\n\tTVPBasicDrawDeviceFailedToCreateDirect3DDevices.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES] );\n\tTVPBasicDrawDeviceFailedToCreateDirect3DDevicesUnknownReason.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICES_UNKNOWN_REASON] );\n\tTVPBasicDrawDeviceTextureHasAlreadyBeenLocked.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_TEXTURE_HAS_ALREADY_BEEN_LOCKED] );\n\tTVPInternalErrorResult.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INTERNAL_ERROR_RESULT] );\n\tTVPBasicDrawDeviceInfPolygonDrawingFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_INF_POLYGON_DRAWING_FAILED] );\n\tTVPBasicDrawDeviceInfDirect3DDevicePresentFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_INF_DIRECT3DDEVICE_PRESENT_FAILED] );\n\tTVPChangeDisplaySettingsFailedDispChangeRestart.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_RESTART] );\n\tTVPChangeDisplaySettingsFailedDispChangeBadFlags.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_FLAGS] );\n\tTVPChangeDisplaySettingsFailedDispChangeBadParam.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_PARAM] );\n\tTVPChangeDisplaySettingsFailedDispChangeFailed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_FAILED] );\n\tTVPChangeDisplaySettingsFailedDispChangeBadMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_BAD_MODE] );\n\tTVPChangeDisplaySettingsFailedDispChangeNotUpdated.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_DISP_CHANGE_NOT_UPDATED] );\n\tTVPChangeDisplaySettingsFailedUnknownReason.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CHANGE_DISPLAY_SETTINGS_FAILED_UNKNOWN_REASON] );\n\tTVPFailedToCreateScreenDC.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILED_TO_CREATE_SCREEN_DC] );\n\tTVPFailedToCreateOffscreenBitmap.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILED_TO_CREATE_OFFSCREEN_BITMAP] );\n\tTVPFailedToCreateOffscreenDC.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_FAILED_TO_CREATE_OFFSCREEN_DC] );\n\tTVPInfoSusiePluginInfo.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_SUSIE_PLUGIN_INFO] );\n\tTVPSusiePluginUnsupportedBitmapHeader.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SUSIE_PLUGIN_UNSUPPORTED_BITMAP_HEADER] );\n\tTVPBasicDrawDeviceFailedToCreateDirect3DDevice.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE] );\n\tTVPBasicDrawDeviceFailedToCreateDirect3DDeviceUnknownReason.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_FAILED_TO_CREATE_DIRECT3DDEVICE_UNKNOWN_REASON] );\n\tTVPCouldNotCreateAnyDrawDevice.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_COULD_NOT_CREATE_ANY_DRAW_DEVICE] );\n\tTVPBasicDrawDeviceDoesNotSupporteLayerManagerMoreThanOne.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_BASIC_DRAW_DEVICE_DOES_NOT_SUPPORTE_LAYER_MANAGER_MORE_THAN_ONE] );\n\tTVPInvalidVideoSize.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INVALID_VIDEO_SIZE] );\n\tTVPRoughVsyncIntervalReadFromApi.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ROUGH_VSYNC_INTERVAL_READ_FROM_API] );\n\tTVPRoughVsyncIntervalStillSeemsWrong.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ROUGH_VSYNC_INTERVAL_STILL_SEEMS_WRONG] );\n\tTVPInfoFoundDirect3DInterface.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_FOUND_DIRECT3DINTERFACE] );\n\tTVPInfoFaild.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_FAILD] );\n\tTVPInfoDirect3D.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_DIRECT3D] );\n\tTVPCannotLoadD3DDLL.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_LOAD_D3DDLL] );\n\tTVPNotFoundDirect3DCreate.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_NOT_FOUND_DIRECT3DCREATE] );\n\tTVPInfoEnvironmentUsing.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_ENVIRONMENT_USING] );\n\tTVPInfoSearchBestFullscreenResolution.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_SEARCH_BEST_FULLSCREEN_RESOLUTION] );\n\tTVPInfoConditionPreferredScreenMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CONDITION_PREFERRED_SCREEN_MODE] );\n\tTVPInfoConditionMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CONDITION_MODE] );\n\tTVPInfoConditionZoomMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CONDITION_ZOOM_MODE] );\n\tTVPInfoEnvironmentDefaultScreenMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_MODE] );\n\tTVPInfoEnvironmentDefaultScreenAspectRatio.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_ENVIRONMENT_DEFAULT_SCREEN_ASPECT_RATIO] );\n\tTVPInfoEnvironmentAvailableDisplayModes.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_ENVIRONMENT_AVAILABLE_DISPLAY_MODES] );\n\tTVPInfoNotFoundScreenModeFromDriver.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_NOT_FOUND_SCREEN_MODE_FROM_DRIVER] );\n\tTVPInfoResultCandidates.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_RESULT_CANDIDATES] );\n\tTVPInfoTryScreenMode.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_TRY_SCREEN_MODE] );\n\tTVPAllScreenModeError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_ALL_SCREEN_MODE_ERROR] );\n\tTVPInfoChangeScreenModeSuccess.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_INFO_CHANGE_SCREEN_MODE_SUCCESS] );\n\tTVPSelectXP3FileOrFolder.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_SELECT_XP3FILE_OR_FOLDER] );\n\tTVPD3dErrDeviceLost.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DEVICE_LOST] );\n\tTVPD3dErrDriverIinternalError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DRIVER_IINTERNAL_ERROR] );\n\tTVPD3dErrInvalidCall.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_INVALID_CALL] );\n\tTVPD3dErrOutOfVideoMemory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_OUT_OF_VIDEO_MEMORY] );\n\tTVPD3dErrOutOfMemory.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_OUT_OF_MEMORY] );\n\tTVPD3dErrWrongTextureFormat.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_WRONG_TEXTURE_FORMAT] );\n\tTVPD3dErrUnsuportedColorOperation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPORTED_COLOR_OPERATION] );\n\tTVPD3dErrUnsuportedColorArg.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPORTED_COLOR_ARG] );\n\tTVPD3dErrUnsuportedAalphtOperation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPORTED_AALPHT_OPERATION] );\n\tTVPD3dErrUnsuportedAlphaArg.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPORTED_ALPHA_ARG] );\n\tTVPD3dErrTooManyOperations.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_TOO_MANY_OPERATIONS] );\n\tTVPD3dErrConflictioningTextureFilter.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_FILTER] );\n\tTVPD3dErrUnsuportedFactorValue.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPORTED_FACTOR_VALUE] );\n\tTVPD3dErrConflictioningRenderState.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_CONFLICTIONING_RENDER_STATE] );\n\tTVPD3dErrUnsupportedTextureFilter.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPPORTED_TEXTURE_FILTER] );\n\tTVPD3dErrConflictioningTexturePalette.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_CONFLICTIONING_TEXTURE_PALETTE] );\n\tTVPD3dErrNotFound.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_NOT_FOUND] );\n\tTVPD3dErrMoreData.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_MORE_DATA] );\n\tTVPD3dErrDeviceNotReset.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DEVICE_NOT_RESET] );\n\tTVPD3dErrNotAvailable.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_NOT_AVAILABLE] );\n\tTVPD3dErrInvalidDevice.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_INVALID_DEVICE] );\n\tTVPD3dErrDriverInvalidCall.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DRIVER_INVALID_CALL] );\n\tTVPD3dErrWasStillDrawing.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_WAS_STILL_DRAWING] );\n\tTVPD3dErrDeviceHung.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DEVICE_HUNG] );\n\tTVPD3dErrUnsupportedOverlay.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPPORTED_OVERLAY] );\n\tTVPD3dErrUnsupportedOverlayFormat.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPPORTED_OVERLAY_FORMAT] );\n\tTVPD3dErrCannotProtectContent.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_CANNOT_PROTECT_CONTENT] );\n\tTVPD3dErrUnsupportedCrypto.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_UNSUPPORTED_CRYPTO] );\n\tTVPD3dErrPresentStatisticsDisJoint.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_PRESENT_STATISTICS_DIS_JOINT] );\n\tTVPD3dErrDeviceRemoved.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_DEVICE_REMOVED] );\n\tTVPD3dOkNoAutoGen.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_OK_NO_AUTO_GEN] );\n\tTVPD3dErrFail.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_FAIL] );\n\tTVPD3dErrInvalidArg.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_ERR_INVALID_ARG] );\n\tTVPD3dUnknownError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_D3D_UNKNOWN_ERROR] );\n\tTVPExceptionAccessViolation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_ACCESS_VIOLATION] );\n\tTVPExceptionBreakpoint.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_BREAKPOINT] );\n\tTVPExceptionDatatypeMisalignment.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_DATATYPE_MISALIGNMENT] );\n\tTVPExceptionSingleStep.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_SINGLE_STEP] );\n\tTVPExceptionArrayBoundsExceeded.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_ARRAY_BOUNDS_EXCEEDED] );\n\tTVPExceptionFltDenormalOperand.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_DENORMAL_OPERAND] );\n\tTVPExceptionFltDivideByZero.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_DIVIDE_BY_ZERO] );\n\tTVPExceptionFltInexactResult.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_INEXACT_RESULT] );\n\tTVPExceptionFltInvalidOperation.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_INVALID_OPERATION] );\n\tTVPExceptionFltOverflow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_OVERFLOW] );\n\tTVPExceptionFltStackCheck.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_STACK_CHECK] );\n\tTVPExceptionFltUnderflow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_FLT_UNDERFLOW] );\n\tTVPExceptionIntDivideByZero.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_INT_DIVIDE_BY_ZERO] );\n\tTVPExceptionIntOverflow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_INT_OVERFLOW] );\n\tTVPExceptionPrivInstruction.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_PRIV_INSTRUCTION] );\n\tTVPExceptionNoncontinuableException.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_NONCONTINUABLE_EXCEPTION] );\n\tTVPExceptionGuardPage.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_GUARD_PAGE] );\n\tTVPExceptionIllegalInstruction.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_ILLEGAL_INSTRUCTION] );\n\tTVPExceptionInPageError.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_IN_PAGE_ERROR] );\n\tTVPExceptionInvalidDisposition.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_INVALID_DISPOSITION] );\n\tTVPExceptionInvalidHandle.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_INVALID_HANDLE] );\n\tTVPExceptionStackOverflow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_STACK_OVERFLOW] );\n\tTVPExceptionUnwindCconsolidate.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_EXCEPTION_UNWIND_CCONSOLIDATE] );\n\tTVPCannotShowModalAreadyShowed.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SHOW_MODAL_AREADY_SHOWED] );\n\tTVPCannotShowModalSingleWindow.AssignMessage( RESOURCE_MESSAGE[NUM_TVP_CANNOT_SHOW_MODAL_SINGLE_WINDOW] );\n}\nconst tjs_char* TVPGetMessage( tjs_int id ) {\n\tif( id >= 0 && id < NUM_MESSAGE_MAX ) {\n\t\treturn RESOURCE_MESSAGE[id];\n\t} else {\n\t\treturn NULL;\n\t}\n}\nstatic void TVPFreeMessages() {\n\tfor( int i = 0; i < NUM_MESSAGE_MAX; i++ ) {\n\t\tdelete[] RESOURCE_MESSAGE[i];\n\t}\n}\nstatic tTVPAtExit\n\tTVPUninitMessageLoad(TVP_ATEXIT_PRI_RELEASE, TVPFreeMessages);\n"
  },
  {
    "path": "src/core/msg/win32/OptionsDesc.cpp",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/* This file is always generated by gen_optdesc_res.pl and option_desc(_ja).txt . */\n/* Modification by hand will be lost. */\n\n#include \"tjsCommHead.h\"\n\n#include \"MsgIntf.h\"\n#include <zlib.h>\n\n/* option description string (compressed) */\n\nstatic tjs_uint8 compressed_option_desc_string[] =\n{\n\t0x78, 0x9c, 0xed, 0x3c, 0xfd, 0x73, 0x53, 0xd7, 0x95, 0xbf, 0x77, 0xa6, 0xff, 0x83, 0x3a, 0xdd,\n\t0x2e, 0x36, 0xab, 0x10, 0xbd, 0x27, 0xc9, 0x96, 0x79, 0x33, 0x9d, 0xca, 0xc6, 0x80, 0x09, 0x60,\n\t0x16, 0x1b, 0xf0, 0xa6, 0x84, 0x44, 0x58, 0xcf, 0xb2, 0x5a, 0x59, 0x72, 0xf5, 0x61, 0x03, 0x25,\n\t0x4c, 0x74, 0x5f, 0xda, 0x20, 0xd9, 0xd6, 0x87, 0x6d, 0xd9, 0xdd, 0x9d, 0x96, 0x6d, 0x5d, 0x26,\n\t0x2d, 0x4a, 0x20, 0xdb, 0xcd, 0x12, 0x92, 0x06, 0x9a, 0x92, 0xc5, 0x80, 0x19, 0x39, 0x9d, 0x76,\n\t0x3b, 0x69, 0x77, 0x93, 0x34, 0x84, 0xb4, 0x04, 0x98, 0xa6, 0x15, 0xdb, 0x99, 0x9d, 0x4e, 0x93,\n\t0x1f, 0xf6, 0x9c, 0x73, 0xdf, 0xb7, 0x9e, 0x6c, 0xe3, 0x6e, 0x33, 0xb3, 0x33, 0x1d, 0xc6, 0xe8,\n\t0xdd, 0xaf, 0x73, 0xcf, 0xd7, 0x3d, 0xf7, 0xdc, 0x73, 0xcf, 0x7b, 0xca, 0x7e, 0x65, 0x40, 0x91,\n\t0x95, 0xa7, 0xca, 0x7d, 0xb3, 0x37, 0x36, 0x2b, 0x43, 0xd9, 0x2f, 0x2a, 0x87, 0x2a, 0x6f, 0x95,\n\t0x5f, 0x2a, 0xde, 0x2b, 0xe6, 0xa5, 0x89, 0xc8, 0xfc, 0x02, 0xfe, 0xb1, 0xea, 0x7c, 0x2c, 0x3b,\n\t0xc0, 0xae, 0xf3, 0x66, 0x56, 0xc7, 0x0e, 0xec, 0x02, 0xbb, 0x8b, 0x9d, 0x58, 0xbd, 0x30, 0x3e,\n\t0x7d, 0x87, 0x9d, 0x67, 0x6f, 0xb3, 0x0b, 0xd9, 0xce, 0x2f, 0x0e, 0x26, 0x1f, 0xc3, 0x3f, 0xaa,\n\t0x83, 0x1e, 0x95, 0x97, 0x0a, 0xff, 0x34, 0x7f, 0x7f, 0xfa, 0xeb, 0x6c, 0x89, 0x2d, 0x9f, 0xbc,\n\t0x9e, 0xfb, 0x21, 0xab, 0xcd, 0x5c, 0x2e, 0xdc, 0x63, 0xd7, 0x79, 0x3d, 0xab, 0xcf, 0x3d, 0xcd,\n\t0xde, 0x9d, 0x3a, 0xc5, 0x7e, 0x55, 0x98, 0x63, 0x55, 0xb6, 0xc8, 0x9e, 0xb3, 0x42, 0xf9, 0x9b,\n\t0x16, 0xf9, 0x88, 0x3c, 0x1a, 0x4a, 0x0f, 0xb7, 0xba, 0x5c, 0xec, 0x07, 0xac, 0xa6, 0x8e, 0x5a,\n\t0xee, 0x3b, 0x9a, 0x4a, 0xcb, 0x23, 0x9b, 0xa0, 0x71, 0x0f, 0x34, 0xb2, 0xa5, 0xe9, 0x0c, 0x7b,\n\t0x2e, 0x7f, 0x81, 0x3d, 0xcb, 0x3e, 0x60, 0xf7, 0xec, 0x10, 0x42, 0xa3, 0xa3, 0xe1, 0x50, 0x3a,\n\t0xd4, 0x1c, 0x0a, 0x74, 0xd8, 0x02, 0x1d, 0x56, 0x87, 0x34, 0x2a, 0x27, 0x53, 0x89, 0x78, 0x28,\n\t0xd6, 0x1c, 0x94, 0xd6, 0xc3, 0x06, 0xab, 0x01, 0xd2, 0x58, 0x34, 0xe5, 0x88, 0x51, 0x36, 0xd8,\n\t0xdb, 0xc7, 0xaa, 0xfb, 0xb1, 0xf5, 0xe4, 0xf5, 0xa9, 0x13, 0xac, 0x56, 0xbc, 0x37, 0xf5, 0x0c,\n\t0xb2, 0xce, 0x4a, 0x06, 0x30, 0xf1, 0xe6, 0xbc, 0xcc, 0x96, 0xb2, 0x41, 0xea, 0x3a, 0xb7, 0x30,\n\t0x77, 0x4a, 0xed, 0xba, 0x6c, 0x70, 0x4c, 0xeb, 0xd4, 0x9c, 0x22, 0x9c, 0x59, 0xe9, 0x51, 0xc6,\n\t0x94, 0xfd, 0xca, 0x33, 0xca, 0x0c, 0xab, 0x4d, 0xc7, 0x10, 0x03, 0x95, 0x94, 0xb0, 0xca, 0x12,\n\t0x17, 0xb4, 0x4f, 0x29, 0xa3, 0xa0, 0x21, 0x9d, 0x6c, 0xb1, 0x70, 0x7b, 0xe6, 0x47, 0x28, 0x55,\n\t0x18, 0x79, 0xd5, 0x2c, 0xaf, 0xe3, 0x1a, 0x6a, 0xc7, 0x53, 0xe9, 0x64, 0x34, 0x1e, 0x69, 0x11,\n\t0xfd, 0xfe, 0x56, 0xf7, 0x46, 0x03, 0x99, 0x83, 0xa9, 0xd0, 0x98, 0x8c, 0x9d, 0x3e, 0xfd, 0x29,\n\t0xc5, 0xac, 0x6f, 0xc5, 0x93, 0xf3, 0xdf, 0x52, 0xba, 0x95, 0xad, 0x4a, 0x97, 0x12, 0x91, 0x94,\n\t0x88, 0x92, 0x53, 0x66, 0x94, 0x03, 0x1c, 0x9f, 0x96, 0xdc, 0xed, 0xb9, 0x1b, 0xa5, 0x5f, 0xb2,\n\t0x3b, 0xe5, 0x37, 0xd9, 0xb3, 0xad, 0x85, 0x53, 0xec, 0x3a, 0xbb, 0x86, 0x24, 0xe7, 0x65, 0x1c,\n\t0xc4, 0xea, 0xda, 0x30, 0x56, 0x67, 0x67, 0xd8, 0x0b, 0xd0, 0x5a, 0x65, 0x1f, 0xcc, 0x5c, 0x06,\n\t0xad, 0xab, 0x15, 0x4e, 0xe5, 0x7f, 0x0e, 0xff, 0x32, 0x6c, 0x71, 0xf2, 0x0a, 0xfb, 0x69, 0x31,\n\t0x01, 0x18, 0x23, 0xbe, 0x4b, 0xec, 0x36, 0xbb, 0xc3, 0x96, 0xba, 0xf6, 0xec, 0x83, 0x2e, 0x91,\n\t0xf9, 0x51, 0x56, 0x2f, 0x7d, 0x6f, 0xf2, 0xc7, 0xec, 0x7c, 0x36, 0x08, 0x55, 0x58, 0x31, 0xff,\n\t0x2c, 0xab, 0x4f, 0xbf, 0x37, 0xf9, 0x32, 0x7b, 0x91, 0xbd, 0x02, 0x34, 0x9e, 0x81, 0xf9, 0x4e,\n\t0xc3, 0xff, 0xb5, 0xd2, 0x3b, 0x00, 0x75, 0xd1, 0xcc, 0xb9, 0x6c, 0xa6, 0x61, 0xf6, 0x85, 0xec,\n\t0x98, 0xba, 0x12, 0x90, 0x3f, 0x57, 0x6d, 0xed, 0x2f, 0xb3, 0xa5, 0xc2, 0x8f, 0xa7, 0x52, 0xd4,\n\t0x76, 0x89, 0xbd, 0x9b, 0x0d, 0xae, 0x42, 0x2b, 0x61, 0x59, 0x17, 0x3c, 0x9e, 0xcf, 0x15, 0x22,\n\t0x6c, 0x01, 0x5a, 0xee, 0xc2, 0x02, 0x59, 0x82, 0x69, 0xee, 0x58, 0x45, 0x28, 0x88, 0xd9, 0x27,\n\t0x04, 0xd1, 0xd3, 0xb2, 0xfd, 0x18, 0xc8, 0x3b, 0x2f, 0x97, 0x66, 0x41, 0x86, 0x75, 0xc2, 0x97,\n\t0xb0, 0xc8, 0x06, 0xd9, 0xab, 0x40, 0xec, 0xc7, 0xf9, 0x3f, 0xb1, 0x45, 0xce, 0x35, 0xc0, 0x61,\n\t0x81, 0x83, 0xa0, 0xbe, 0xd5, 0xe2, 0xf3, 0x40, 0xed, 0x0b, 0xa0, 0x19, 0x6f, 0xd0, 0xd3, 0x02,\n\t0xfb, 0x4f, 0x76, 0x0d, 0xe7, 0x7e, 0x13, 0x94, 0x32, 0x37, 0xdd, 0xc7, 0x96, 0xa9, 0xfa, 0xac,\n\t0x36, 0x33, 0xab, 0x66, 0x83, 0x33, 0xe7, 0xa6, 0x7e, 0x0b, 0xcc, 0xbe, 0xce, 0xde, 0x05, 0x95,\n\t0x3a, 0xc3, 0x16, 0xe7, 0x78, 0xfb, 0xdd, 0xdc, 0xeb, 0xb3, 0x07, 0x4b, 0xcf, 0x41, 0xcb, 0xb7,\n\t0x35, 0x2c, 0xf3, 0xaf, 0x4f, 0x3c, 0x47, 0x6c, 0xbf, 0xcc, 0xae, 0xb0, 0x65, 0xa8, 0x7f, 0x9b,\n\t0xdd, 0x99, 0xfc, 0x63, 0xee, 0x06, 0x8d, 0x5e, 0x20, 0xa1, 0xdc, 0xa4, 0xde, 0xcf, 0x36, 0x2a,\n\t0x26, 0x11, 0x01, 0xea, 0xa8, 0xf4, 0x02, 0xa3, 0xd2, 0x4a, 0xa7, 0x72, 0x58, 0xd9, 0xfd, 0x50,\n\t0x89, 0x4d, 0x5f, 0x9c, 0x79, 0x21, 0xff, 0xa7, 0xf2, 0xcf, 0xd8, 0x6b, 0x80, 0x4a, 0x86, 0xc4,\n\t0x08, 0x94, 0x02, 0xef, 0xf9, 0x00, 0x75, 0x15, 0xcc, 0xbd, 0x58, 0x98, 0x00, 0xb4, 0x55, 0x7d,\n\t0x3f, 0x3e, 0x98, 0x88, 0xa7, 0x87, 0x92, 0xf2, 0x57, 0x8e, 0xa7, 0xe4, 0x98, 0x3c, 0x98, 0x76,\n\t0x6f, 0xf4, 0x48, 0x8d, 0xf2, 0x73, 0x0b, 0xa2, 0x24, 0x88, 0xdb, 0x8f, 0xb9, 0x05, 0xbf, 0x24,\n\t0xf8, 0xe1, 0x57, 0xf4, 0x4b, 0x22, 0xfe, 0x7a, 0x3d, 0x92, 0xd7, 0x03, 0xbf, 0x3e, 0xbf, 0xe4,\n\t0xc3, 0xb2, 0xdf, 0x23, 0xf9, 0xb1, 0xdc, 0xe6, 0x91, 0xda, 0xf0, 0xb7, 0xdd, 0x23, 0xb5, 0xd3,\n\t0xaf, 0x5f, 0x6a, 0xc7, 0xf6, 0x80, 0x47, 0x0a, 0x60, 0x39, 0xe0, 0x95, 0x02, 0x5e, 0xf8, 0xed,\n\t0xf0, 0x48, 0x1d, 0x58, 0xee, 0xf0, 0x4a, 0x1d, 0x58, 0x06, 0xa9, 0x4a, 0xf0, 0x47, 0x4f, 0xed,\n\t0xf0, 0xd4, 0x8e, 0x4f, 0x22, 0xd4, 0x89, 0x50, 0x67, 0x5b, 0x1f, 0x4a, 0x56, 0x61, 0x4a, 0x9e,\n\t0x94, 0xf3, 0x86, 0xa4, 0x51, 0xcb, 0x2b, 0xb9, 0x12, 0xcf, 0xdf, 0x70, 0xd6, 0xcf, 0xe9, 0xf7,\n\t0xb8, 0x46, 0x96, 0x7b, 0xca, 0x75, 0x55, 0x17, 0x32, 0xd3, 0x37, 0x8a, 0x1f, 0xea, 0x75, 0xe7,\n\t0x41, 0x0f, 0xaf, 0xc2, 0xfa, 0xc5, 0x35, 0x71, 0x53, 0x85, 0x58, 0x2f, 0xbd, 0x3b, 0x77, 0x1f,\n\t0x5a, 0xae, 0x68, 0x33, 0x41, 0xeb, 0x69, 0x43, 0xed, 0x50, 0xf8, 0x60, 0x09, 0xd2, 0xca, 0x76,\n\t0xd8, 0x05, 0x9e, 0x04, 0xed, 0x1d, 0x60, 0xcb, 0xd3, 0xef, 0x81, 0x4d, 0x57, 0x6d, 0xbf, 0xe3,\n\t0xac, 0x41, 0x58, 0x2b, 0x66, 0x11, 0xe6, 0x6e, 0x97, 0xbf, 0xa9, 0xec, 0x54, 0x14, 0x28, 0xec,\n\t0x57, 0xbe, 0x86, 0x2b, 0x10, 0x06, 0x2c, 0x4f, 0x9c, 0x2d, 0x7d, 0x6f, 0xa6, 0x07, 0x96, 0x77,\n\t0xc6, 0x68, 0x23, 0x65, 0xfd, 0x50, 0x5d, 0x5a, 0x1a, 0x91, 0xdf, 0x46, 0xa0, 0x93, 0x67, 0xa0,\n\t0xd6, 0x10, 0xef, 0x88, 0x3c, 0x92, 0x49, 0x85, 0x22, 0xb2, 0x2e, 0xde, 0x78, 0x22, 0x39, 0x12,\n\t0x8a, 0x49, 0x48, 0xaf, 0x3b, 0x96, 0x18, 0x97, 0x10, 0x2d, 0x3b, 0x63, 0x0f, 0x81, 0xf4, 0x9f,\n\t0x04, 0xb0, 0x2f, 0xcf, 0x1c, 0x91, 0xcc, 0x05, 0x67, 0x76, 0x4e, 0x31, 0xfb, 0x02, 0xa7, 0x55,\n\t0x50, 0x03, 0xfd, 0xbd, 0xc4, 0x5e, 0x07, 0x36, 0x56, 0x73, 0x1f, 0x97, 0xf7, 0x10, 0x4e, 0x77,\n\t0x49, 0x05, 0xf5, 0x55, 0xe0, 0xc0, 0xb4, 0x2a, 0x31, 0xed, 0x82, 0xda, 0xf3, 0xa6, 0xb1, 0x5e,\n\t0x6c, 0x06, 0x19, 0xb4, 0x7f, 0x77, 0xbf, 0x6b, 0x32, 0xee, 0xea, 0xed, 0x73, 0xb5, 0xec, 0xee,\n\t0x7f, 0x58, 0xf4, 0x78, 0x3c, 0x0f, 0x0f, 0xec, 0x79, 0x58, 0xdf, 0x1f, 0x5a, 0x5d, 0x20, 0x9c,\n\t0xef, 0xc3, 0x4a, 0xba, 0x02, 0x98, 0xbc, 0x73, 0xf2, 0x3f, 0xe6, 0xbe, 0x03, 0x18, 0x7e, 0x0b,\n\t0x96, 0x06, 0xe7, 0x4b, 0x3a, 0x3a, 0x22, 0x27, 0x47, 0x93, 0xf2, 0xa0, 0x23, 0x63, 0x86, 0xa3,\n\t0x91, 0x61, 0x39, 0x29, 0xb1, 0x5b, 0xec, 0x16, 0x52, 0x47, 0x65, 0x09, 0x9f, 0x1c, 0x39, 0x05,\n\t0x7f, 0x47, 0x00, 0xf9, 0xc8, 0xc4, 0xdc, 0xbc, 0x3c, 0x7f, 0x03, 0xc5, 0x26, 0x59, 0x1b, 0x58,\n\t0x8d, 0x37, 0xa9, 0x56, 0xf5, 0xc2, 0x6a, 0x06, 0x54, 0x5d, 0xb6, 0x26, 0x8e, 0x66, 0x83, 0x64,\n\t0xa2, 0x6a, 0xd3, 0x47, 0xd8, 0x82, 0xb2, 0x17, 0x60, 0xa6, 0x94, 0xaf, 0xa1, 0xbb, 0x51, 0x7c,\n\t0x9f, 0x2d, 0x6a, 0x18, 0xc1, 0x02, 0xc7, 0x3e, 0xd5, 0xe9, 0x6b, 0x40, 0xf5, 0xeb, 0x00, 0xfb,\n\t0x65, 0xe0, 0xee, 0xd7, 0xa1, 0x17, 0xd8, 0xf4, 0xf2, 0x53, 0x64, 0x97, 0xce, 0xb3, 0x7f, 0x07,\n\t0xbb, 0x44, 0x16, 0xa9, 0xf8, 0x87, 0x89, 0xf3, 0xac, 0x9e, 0xbb, 0x3f, 0x5b, 0xa7, 0xad, 0xca,\n\t0x26, 0x19, 0xe0, 0x50, 0x2c, 0x74, 0x84, 0x98, 0x64, 0x62, 0x90, 0x04, 0x00, 0xd0, 0x1a, 0x1c,\n\t0x95, 0x53, 0x12, 0xe2, 0x65, 0xe3, 0xc6, 0xf4, 0x7b, 0xf3, 0x5b, 0x4a, 0xb7, 0x51, 0x67, 0xd6,\n\t0xb0, 0x59, 0x91, 0xc9, 0xaf, 0xf1, 0x01, 0xb8, 0xb5, 0x00, 0x56, 0xeb, 0xe0, 0x8b, 0x75, 0x26,\n\t0x80, 0x5d, 0xcb, 0xbd, 0x32, 0xfb, 0xdf, 0xec, 0xa7, 0x34, 0x47, 0x53, 0xbd, 0x43, 0xea, 0x12,\n\t0xe3, 0xa3, 0xc9, 0xe8, 0x8a, 0xb4, 0xcd, 0x7c, 0x3c, 0xbf, 0xbc, 0x19, 0x84, 0xd8, 0x0d, 0x24,\n\t0x1e, 0x53, 0xba, 0x80, 0x91, 0x13, 0xb9, 0xfb, 0x33, 0x8f, 0x4d, 0xfe, 0x73, 0x31, 0x51, 0xf9,\n\t0x68, 0xee, 0x0b, 0x92, 0xb5, 0x09, 0x66, 0x86, 0x46, 0x30, 0x99, 0xd7, 0x40, 0xdf, 0xc8, 0x34,\n\t0x60, 0x47, 0x95, 0x26, 0x47, 0x6a, 0x60, 0xf7, 0xd2, 0x56, 0xb0, 0xc9, 0x28, 0xd8, 0xa0, 0x2e,\n\t0xa3, 0xb9, 0xa9, 0xa4, 0x70, 0xff, 0x70, 0xda, 0xe3, 0xb2, 0x99, 0x2d, 0x51, 0x50, 0xe2, 0x74,\n\t0x4f, 0x7c, 0x34, 0x93, 0xb6, 0x02, 0x32, 0x35, 0x00, 0xc7, 0x1c, 0x8d, 0x96, 0x6d, 0xd3, 0xee,\n\t0x04, 0x4e, 0x0e, 0xc3, 0x6f, 0x16, 0x6c, 0xcc, 0xa3, 0x30, 0xfb, 0x81, 0xd5, 0x00, 0xbe, 0x82,\n\t0x7b, 0xb7, 0x33, 0x1b, 0x74, 0xe2, 0x9b, 0x4c, 0x48, 0x0c, 0xa9, 0x57, 0x7e, 0x02, 0xdb, 0x5b,\n\t0x03, 0xd1, 0xf9, 0x37, 0xbf, 0x11, 0x84, 0x2d, 0x36, 0x35, 0xf1, 0x7b, 0x14, 0x9a, 0x21, 0xc4,\n\t0xc6, 0x4d, 0xf4, 0xf8, 0xf8, 0xb0, 0x2c, 0xc7, 0x34, 0x29, 0x82, 0x10, 0x35, 0x9e, 0xba, 0x37,\n\t0x86, 0xa3, 0x88, 0xa8, 0x64, 0x42, 0xda, 0x3d, 0x22, 0xa7, 0xd0, 0x14, 0x4a, 0x4e, 0xa4, 0x6a,\n\t0xe2, 0x1e, 0x85, 0x8a, 0x61, 0x24, 0x0e, 0x26, 0x7b, 0x4b, 0xe2, 0xc5, 0x16, 0xd0, 0xaf, 0x67,\n\t0x60, 0x2d, 0xa3, 0xa6, 0x93, 0xa1, 0x6e, 0x35, 0x31, 0x74, 0x45, 0x85, 0x6d, 0x22, 0x62, 0x82,\n\t0xda, 0x4c, 0xb4, 0x6a, 0x6b, 0xbd, 0xf4, 0x62, 0xf1, 0x43, 0x55, 0x89, 0x70, 0x81, 0x02, 0x14,\n\t0x54, 0x62, 0xf0, 0x5a, 0xd0, 0xcc, 0x2f, 0xb0, 0x65, 0x6b, 0x3f, 0xc2, 0xc7, 0xd4, 0x0f, 0xb7,\n\t0x0b, 0xd3, 0xec, 0x1c, 0xbb, 0x25, 0xdc, 0xbf, 0x60, 0xa1, 0xfd, 0x08, 0xbd, 0x19, 0xe0, 0xde,\n\t0x97, 0x12, 0x47, 0x47, 0x43, 0xe1, 0x95, 0xd8, 0x07, 0x15, 0xa7, 0x2d, 0xac, 0x51, 0x76, 0x02,\n\t0xb7, 0xf2, 0x4a, 0x0a, 0xfe, 0x8f, 0x28, 0x43, 0xc0, 0x8e, 0x49, 0xa5, 0xab, 0x39, 0x9b, 0x6a,\n\t0xe6, 0xee, 0x40, 0xde, 0x22, 0x77, 0x40, 0xc1, 0x41, 0x3d, 0xa1, 0xe4, 0x2b, 0x87, 0xa7, 0xf7,\n\t0x9c, 0xbc, 0x01, 0x8e, 0xb3, 0xe9, 0x88, 0x74, 0x1c, 0xf0, 0x09, 0xcb, 0xb1, 0xd0, 0x51, 0x0d,\n\t0x29, 0xd5, 0x21, 0xe0, 0xfd, 0xdd, 0x60, 0xe5, 0x25, 0x51, 0x2f, 0x79, 0x3d, 0xe8, 0x7d, 0x68,\n\t0x25, 0x1f, 0x94, 0x7c, 0x7a, 0x69, 0xa3, 0xdf, 0x83, 0xae, 0x88, 0x56, 0x6c, 0xf3, 0xa0, 0x43,\n\t0xa2, 0x95, 0xda, 0x3d, 0xe8, 0x96, 0x68, 0xa5, 0x80, 0x07, 0x9d, 0x12, 0xad, 0xd4, 0xe1, 0x41,\n\t0x97, 0x44, 0x2b, 0xc1, 0xd4, 0x34, 0xbf, 0x56, 0x7e, 0x48, 0x90, 0x2c, 0x24, 0x91, 0xcd, 0x68,\n\t0xca, 0x20, 0x74, 0xb4, 0xd7, 0xca, 0x9c, 0x1a, 0x79, 0xe5, 0x4d, 0x19, 0xa3, 0xfb, 0xa3, 0xe4,\n\t0x85, 0xea, 0xa3, 0xaa, 0x53, 0xac, 0xfc, 0xbc, 0x59, 0x7b, 0x90, 0x81, 0xd1, 0x78, 0x5a, 0x4e,\n\t0x8e, 0x85, 0x62, 0x06, 0x0f, 0x81, 0x04, 0x9d, 0x83, 0xc0, 0x40, 0x8d, 0x47, 0xe4, 0xbd, 0xe9,\n\t0xec, 0x03, 0xee, 0xa9, 0xcf, 0xe4, 0xc5, 0xe9, 0x9c, 0x03, 0xc6, 0xe9, 0x7c, 0x03, 0xb6, 0xe9,\n\t0x5c, 0x03, 0xa6, 0xe9, 0x3c, 0x03, 0x96, 0x19, 0x1c, 0x5b, 0x97, 0xc0, 0xac, 0xf2, 0xb2, 0x4a,\n\t0xc8, 0x26, 0x05, 0x95, 0xdf, 0x3d, 0xbb, 0xba, 0x8b, 0x7f, 0x28, 0xff, 0x1c, 0xb6, 0xd4, 0x5f,\n\t0x4b, 0xf0, 0xdc, 0x32, 0xf3, 0xa7, 0xb9, 0xaf, 0x4e, 0xde, 0x23, 0xcb, 0x5f, 0xab, 0xfc, 0x24,\n\t0x7f, 0x01, 0x3b, 0x29, 0x07, 0xc1, 0xbb, 0x88, 0x00, 0xaf, 0xb5, 0x9e, 0xe4, 0x38, 0x9d, 0x5e,\n\t0x79, 0xd5, 0x9a, 0x5c, 0x2b, 0x8b, 0xb7, 0x66, 0x9e, 0x00, 0x81, 0xab, 0xa7, 0x3c, 0xe8, 0xa9,\n\t0xda, 0x2a, 0xd3, 0x76, 0xea, 0x60, 0xab, 0xd0, 0xd3, 0x4e, 0x26, 0x62, 0xb0, 0xa7, 0xea, 0xdb,\n\t0x0e, 0x6e, 0x36, 0x88, 0x0f, 0xae, 0x3d, 0x6d, 0x56, 0xd8, 0x54, 0xfb, 0xc1, 0x32, 0x81, 0x7d,\n\t0xda, 0xdc, 0xb5, 0xe5, 0xa1, 0x2d, 0x41, 0x57, 0xee, 0x15, 0x72, 0x2a, 0x7e, 0x4d, 0x9b, 0x8e,\n\t0xbd, 0xaa, 0x70, 0xce, 0x89, 0x06, 0x20, 0x7a, 0x2b, 0xe8, 0xc7, 0xb0, 0x12, 0x04, 0x48, 0x11,\n\t0xc4, 0x18, 0x0e, 0x72, 0x5b, 0x5c, 0xb8, 0x3b, 0xf2, 0x81, 0x80, 0xd8, 0x69, 0x40, 0xeb, 0x2c,\n\t0xa8, 0xd3, 0x19, 0xdd, 0x64, 0x2c, 0x57, 0x6e, 0x58, 0x0c, 0xc5, 0x3b, 0x16, 0x63, 0x31, 0x18,\n\t0x1e, 0x4b, 0xe8, 0x2a, 0xb5, 0x71, 0x24, 0x7a, 0x04, 0x1c, 0x24, 0x0d, 0x53, 0x65, 0x07, 0xcd,\n\t0x76, 0x02, 0x1c, 0xd4, 0x7e, 0x77, 0x98, 0x4c, 0x2e, 0x62, 0xba, 0xb7, 0x77, 0x17, 0xd4, 0xe6,\n\t0x40, 0xed, 0x33, 0xd3, 0x17, 0x4b, 0xff, 0x85, 0x13, 0x9b, 0xa8, 0xdb, 0xd3, 0xb5, 0xcb, 0x05,\n\t0x26, 0x64, 0x2f, 0x0d, 0x1d, 0x00, 0x43, 0x02, 0xcb, 0x04, 0xfd, 0x81, 0xe2, 0x33, 0x27, 0x6f,\n\t0x48, 0xd0, 0x08, 0x0b, 0x44, 0x6d, 0xe5, 0x42, 0xd3, 0xfa, 0x80, 0x0d, 0x01, 0xdf, 0x41, 0xeb,\n\t0x69, 0x25, 0x7c, 0xea, 0x4a, 0xe9, 0x25, 0x0c, 0xa8, 0xa8, 0x5e, 0x40, 0x5d, 0xf7, 0x24, 0x97,\n\t0xf4, 0xfe, 0x75, 0xf0, 0xe3, 0xce, 0x3a, 0xd0, 0x37, 0x9e, 0x0a, 0xcb, 0x83, 0x26, 0x9f, 0x00,\n\t0xce, 0x41, 0x41, 0xc0, 0x7c, 0x58, 0x99, 0x68, 0x99, 0x5a, 0x9c, 0x7e, 0x0f, 0x8e, 0xec, 0x02,\n\t0x39, 0xcb, 0x6e, 0x91, 0x7c, 0x44, 0x0c, 0xd8, 0xb8, 0xbd, 0xdc, 0x5d, 0xf4, 0xa9, 0x35, 0xc5,\n\t0xf7, 0xdd, 0x7e, 0xcd, 0x4d, 0xd4, 0xa8, 0xe4, 0x1b, 0x50, 0x5f, 0x22, 0x13, 0x0f, 0xbb, 0xb8,\n\t0x36, 0xd2, 0xf1, 0x2a, 0x48, 0xcc, 0xda, 0x0f, 0x5d, 0x7a, 0x25, 0x53, 0x17, 0xf0, 0xe6, 0x4c,\n\t0x7d, 0x70, 0x9b, 0xc1, 0xf3, 0xa1, 0xd1, 0x77, 0x75, 0xf5, 0xd5, 0x36, 0xd6, 0xa9, 0x01, 0xae,\n\t0xb6, 0xa0, 0x2b, 0xe0, 0x7b, 0xdd, 0x63, 0xb7, 0x54, 0x96, 0xac, 0xe4, 0x14, 0x8d, 0xa7, 0x52,\n\t0x89, 0xa1, 0xb4, 0x45, 0x3b, 0x2d, 0xe8, 0x80, 0x23, 0x8d, 0x9a, 0xaa, 0xc4, 0x49, 0x64, 0x54,\n\t0x87, 0x6c, 0x6d, 0x46, 0xed, 0xa3, 0xca, 0x0e, 0xa8, 0x7c, 0x1c, 0x8c, 0x55, 0x02, 0xe4, 0x96,\n\t0x56, 0xbe, 0x80, 0xd2, 0x29, 0x3d, 0x6f, 0xa3, 0xb7, 0xa1, 0x17, 0xab, 0xe3, 0x86, 0xc6, 0xfb,\n\t0xae, 0xb6, 0xc5, 0x36, 0x50, 0x8b, 0xc3, 0xf2, 0x3b, 0x0a, 0x71, 0xee, 0x0a, 0x3e, 0x00, 0xe5,\n\t0x80, 0x52, 0x52, 0x0e, 0xa5, 0xf5, 0xb5, 0x89, 0xc4, 0x1b, 0x78, 0x90, 0x87, 0x58, 0x79, 0x64,\n\t0x7e, 0x0c, 0x54, 0xeb, 0x14, 0x7b, 0x89, 0x5d, 0xe1, 0xd5, 0x6b, 0xa6, 0x7c, 0xfa, 0x02, 0x7b,\n\t0xd1, 0x4c, 0xb7, 0x03, 0xd5, 0x35, 0xec, 0xe3, 0x1c, 0x30, 0x3c, 0x79, 0x6f, 0xf6, 0x06, 0x5b,\n\t0x82, 0xf6, 0xb3, 0x70, 0x2c, 0x05, 0x2a, 0x71, 0x72, 0x56, 0x3d, 0xf9, 0x63, 0xad, 0x27, 0x9d,\n\t0xa3, 0xd4, 0x63, 0x6a, 0xf1, 0xf2, 0xec, 0xef, 0xf5, 0xdd, 0x74, 0x3c, 0x15, 0x13, 0x62, 0x72,\n\t0x5c, 0xa3, 0x49, 0x04, 0xc3, 0x0e, 0x7f, 0x23, 0x29, 0xb7, 0x17, 0x0e, 0xe4, 0xf0, 0x07, 0x4f,\n\t0xaa, 0xdd, 0x85, 0xa7, 0x36, 0x38, 0xd4, 0xc3, 0x1f, 0x3c, 0xb5, 0x43, 0xbf, 0x76, 0xea, 0x17,\n\t0x80, 0x7e, 0x01, 0xea, 0xb7, 0x51, 0x37, 0xc2, 0x50, 0x10, 0x04, 0xe8, 0x8b, 0xff, 0xe1, 0x33,\n\t0x42, 0x15, 0x38, 0x58, 0x01, 0xe1, 0x0a, 0x1c, 0xb0, 0x80, 0x90, 0x05, 0x0e, 0x5a, 0x40, 0xd8,\n\t0x02, 0x07, 0x2e, 0x20, 0x74, 0x81, 0x83, 0x17, 0x10, 0xbe, 0xc0, 0x27, 0xc0, 0x13, 0x1c, 0xee,\n\t0x15, 0x58, 0x2f, 0x22, 0x7c, 0x91, 0xc3, 0x17, 0x09, 0x6b, 0x0e, 0x5f, 0x44, 0xf8, 0x22, 0x87,\n\t0x2f, 0x22, 0x7c, 0x91, 0xc3, 0x17, 0x11, 0xbe, 0xc8, 0xe1, 0x8b, 0x08, 0x5f, 0xe4, 0xf0, 0x45,\n\t0x84, 0x2f, 0x72, 0xf8, 0x5e, 0x0f, 0xdf, 0x7d, 0x88, 0x7c, 0x84, 0xef, 0xe5, 0xf0, 0xbd, 0x08,\n\t0xdf, 0xab, 0xb2, 0x85, 0xf8, 0xc2, 0xe1, 0x7b, 0x11, 0xbe, 0x97, 0xc3, 0xf7, 0x22, 0x7c, 0x2f,\n\t0x87, 0xef, 0x45, 0xf8, 0x5e, 0x0e, 0xdf, 0x8b, 0xf0, 0xbd, 0x1c, 0xbe, 0xcf, 0xc3, 0xf7, 0x33,\n\t0xac, 0xf7, 0xe1, 0x58, 0x1f, 0x1f, 0xeb, 0xf7, 0x70, 0x0e, 0xd3, 0x33, 0x71, 0x5b, 0x65, 0xb7,\n\t0x87, 0xfb, 0x24, 0xf4, 0x8c, 0xf5, 0x6d, 0xbc, 0xbe, 0xdd, 0xc3, 0xf7, 0x3e, 0x0f, 0x17, 0x04,\n\t0x49, 0x82, 0x44, 0xe1, 0xe1, 0x7e, 0x0a, 0x3d, 0x63, 0x7d, 0x80, 0xd7, 0x77, 0x78, 0xb8, 0xc7,\n\t0x42, 0xcf, 0x58, 0xdf, 0xa1, 0xf2, 0xdc, 0xa3, 0x09, 0x0c, 0x4a, 0xab, 0x2a, 0x6a, 0xe5, 0x56,\n\t0xb1, 0xb2, 0x76, 0x65, 0x05, 0x5f, 0xb3, 0x66, 0x1e, 0xf1, 0x97, 0x52, 0x5e, 0xf1, 0xaf, 0xca,\n\t0xfb, 0x57, 0xe5, 0x6d, 0xaa, 0xbc, 0x27, 0x28, 0x06, 0x12, 0x31, 0xab, 0xaa, 0x0b, 0x36, 0x94,\n\t0xa0, 0x32, 0x06, 0x9a, 0xba, 0x07, 0x9a, 0x78, 0xa8, 0xa8, 0x3a, 0x7b, 0x1f, 0xea, 0x76, 0x93,\n\t0xe3, 0x9d, 0xd1, 0x4e, 0x4f, 0x53, 0x8b, 0xc5, 0xe7, 0x73, 0xaf, 0x62, 0xa4, 0x6f, 0xea, 0x2d,\n\t0x38, 0xc3, 0xaa, 0xa0, 0xf8, 0x76, 0xd3, 0x82, 0x5e, 0x12, 0x38, 0x73, 0x3f, 0x64, 0xff, 0x82,\n\t0xc5, 0xd6, 0x15, 0x63, 0xdd, 0xda, 0xc8, 0xf3, 0x0e, 0xe7, 0x3c, 0xad, 0x6d, 0x99, 0x7c, 0x3b,\n\t0x0c, 0xc9, 0xbd, 0xc2, 0xee, 0x5b, 0x3c, 0x4d, 0xc2, 0xa2, 0x70, 0x0a, 0xc6, 0xdd, 0xca, 0x66,\n\t0xcc, 0x78, 0x42, 0xcd, 0x22, 0x06, 0xb9, 0xd8, 0xab, 0x30, 0xee, 0x22, 0xbb, 0xd7, 0x48, 0x95,\n\t0x41, 0x01, 0xc6, 0x2a, 0xb3, 0x41, 0x0b, 0x95, 0x78, 0x22, 0xb8, 0xac, 0x46, 0x31, 0x0d, 0xea,\n\t0x8c, 0xb0, 0xe0, 0x78, 0x6a, 0x24, 0x93, 0x36, 0x05, 0x05, 0xe5, 0x31, 0xf4, 0xe6, 0x2c, 0xb4,\n\t0xb8, 0x47, 0xa2, 0xf1, 0xe8, 0x48, 0xf4, 0x98, 0x2c, 0x69, 0x58, 0xba, 0xc3, 0x72, 0x68, 0x30,\n\t0x1d, 0x1d, 0x93, 0x25, 0xf3, 0x5c, 0x85, 0x53, 0xab, 0xc8, 0x07, 0xb9, 0x29, 0x69, 0x81, 0x0a,\n\t0x6b, 0x13, 0x51, 0x59, 0xd3, 0x4a, 0x7c, 0xcf, 0x6e, 0x16, 0xb5, 0xf5, 0x7c, 0xce, 0x1a, 0xfa,\n\t0xc9, 0x9f, 0x2b, 0xf7, 0xb1, 0xa5, 0xb9, 0x17, 0x73, 0xaf, 0x00, 0x95, 0x70, 0xfe, 0xc1, 0x68,\n\t0xaa, 0xdf, 0xde, 0x69, 0xf6, 0x62, 0xa5, 0xca, 0x81, 0xb6, 0xcc, 0xdd, 0x7f, 0xa8, 0x2d, 0xdc,\n\t0xd9, 0xca, 0x3b, 0x5b, 0xd8, 0x60, 0xf6, 0x6b, 0x3d, 0x92, 0xe7, 0x73, 0x2d, 0x0f, 0x65, 0x9f,\n\t0x81, 0x9e, 0xe0, 0xcb, 0xf9, 0xe1, 0x59, 0x6c, 0xdb, 0xe4, 0xc1, 0x12, 0x9d, 0xa2, 0xb0, 0xec,\n\t0x51, 0xcb, 0x18, 0x0a, 0x87, 0xb2, 0xd0, 0xb6, 0xc9, 0x8f, 0x65, 0x3a, 0x59, 0x61, 0xd9, 0xc7,\n\t0xdb, 0x29, 0x44, 0x8e, 0x65, 0x91, 0x97, 0xe9, 0xb0, 0x85, 0x65, 0x0f, 0xef, 0xef, 0x85, 0xc5,\n\t0x87, 0xed, 0x1d, 0x9b, 0x04, 0x2c, 0xd2, 0xf9, 0x0b, 0x8a, 0x01, 0xde, 0x9b, 0x02, 0xea, 0x50,\n\t0x6c, 0xdb, 0xd4, 0x41, 0xa8, 0xe0, 0x2a, 0xa4, 0x22, 0xb5, 0xfa, 0x01, 0x35, 0x6c, 0xf5, 0x6f,\n\t0x12, 0xb1, 0x48, 0x67, 0x34, 0x28, 0xfa, 0x36, 0xf9, 0xa8, 0x08, 0xa6, 0x10, 0x5b, 0xbd, 0x9b,\n\t0xda, 0xb1, 0x48, 0xa7, 0x36, 0x2a, 0xd2, 0x44, 0x14, 0x8a, 0x47, 0x3a, 0x38, 0x1a, 0x74, 0x8e,\n\t0x43, 0xb4, 0xf8, 0x44, 0x01, 0x30, 0x99, 0x84, 0x35, 0x07, 0x45, 0x27, 0x3b, 0x28, 0x7a, 0x78,\n\t0x6b, 0x87, 0x1f, 0x16, 0x28, 0x15, 0xb1, 0xb5, 0x89, 0xdc, 0x31, 0x5e, 0xad, 0xc7, 0x74, 0x0f,\n\t0x2b, 0x11, 0x3c, 0x8b, 0x59, 0x7c, 0x3e, 0xf2, 0xa9, 0xf8, 0x45, 0x12, 0xb8, 0xf9, 0xda, 0xbd,\n\t0x69, 0x36, 0x48, 0x62, 0xab, 0x4d, 0x3e, 0x01, 0x67, 0x9a, 0x25, 0x2d, 0xe8, 0x8d, 0x83, 0x1f,\n\t0xd4, 0x09, 0x44, 0xf0, 0xa8, 0x4b, 0xc5, 0xf7, 0xf2, 0x7f, 0xaf, 0x7a, 0x7d, 0x17, 0x1a, 0x7d,\n\t0x3e, 0x43, 0xb3, 0x84, 0xb6, 0xc3, 0xd1, 0x74, 0xe9, 0x5c, 0x69, 0x16, 0x36, 0xa1, 0x11, 0x38,\n\t0xae, 0x4c, 0xf0, 0x69, 0xed, 0x57, 0x04, 0x76, 0x1a, 0x7d, 0x83, 0xc3, 0x38, 0x93, 0x1e, 0x5d,\n\t0xb1, 0xdf, 0xac, 0x8c, 0xa7, 0x86, 0x12, 0xc9, 0x41, 0x79, 0x30, 0x3e, 0x66, 0x0a, 0x33, 0xc6,\n\t0x65, 0x89, 0x48, 0xe2, 0x4b, 0x2c, 0x2a, 0xb4, 0x49, 0xfa, 0xec, 0x7c, 0x56, 0xac, 0x1b, 0x91,\n\t0x9a, 0xa0, 0xd4, 0x84, 0xe3, 0xde, 0x2d, 0x74, 0x08, 0xb6, 0xf8, 0xd5, 0xbc, 0x6e, 0x2d, 0xc7,\n\t0x5d, 0x2d, 0xaa, 0x6a, 0x3e, 0xea, 0x6a, 0xd3, 0xb0, 0x9a, 0x0a, 0xa7, 0x3a, 0xbf, 0x73, 0xf2,\n\t0x8f, 0x46, 0xa0, 0xa1, 0xa5, 0xc1, 0x1e, 0xe9, 0x57, 0x59, 0xea, 0x25, 0x16, 0xe7, 0x33, 0xd8,\n\t0xbb, 0xd6, 0x6c, 0x27, 0x3c, 0x5c, 0xca, 0x06, 0xcb, 0x97, 0xc0, 0x05, 0xa8, 0xd1, 0xbd, 0x17,\n\t0x99, 0x36, 0x8a, 0x85, 0x4c, 0x2a, 0x3d, 0xec, 0x96, 0x4e, 0x64, 0x4d, 0x9f, 0xb7, 0x4a, 0x38,\n\t0xe4, 0xd4, 0xe3, 0xe5, 0x00, 0x85, 0x3b, 0xe0, 0x90, 0x69, 0x8f, 0x64, 0xe6, 0x23, 0xd3, 0xdf,\n\t0x25, 0x96, 0x5f, 0x51, 0x75, 0xea, 0x9e, 0x76, 0xdd, 0xe2, 0x40, 0xd5, 0x3a, 0x24, 0x98, 0x49,\n\t0xc9, 0xde, 0xf0, 0xca, 0x11, 0xf0, 0x66, 0x4b, 0x40, 0x05, 0x6e, 0x3b, 0xed, 0xac, 0x44, 0x73,\n\t0x9d, 0x68, 0xd0, 0x4f, 0xac, 0xd9, 0xa0, 0xb6, 0x08, 0x80, 0xd1, 0x41, 0x33, 0x0f, 0xf2, 0x6f,\n\t0xb3, 0x5f, 0x01, 0x78, 0xb6, 0x68, 0x2c, 0xa4, 0xb5, 0x89, 0xd8, 0x7c, 0xfb, 0xb9, 0x32, 0xfb,\n\t0x61, 0x01, 0x4f, 0xe1, 0xd5, 0x85, 0x69, 0xda, 0x45, 0xa0, 0xfd, 0x8c, 0xce, 0x66, 0xe0, 0x82,\n\t0x2a, 0xca, 0x9b, 0x00, 0xab, 0xb1, 0xf7, 0x55, 0x1b, 0xd2, 0xb5, 0xf9, 0x8b, 0x95, 0x8f, 0x80,\n\t0x01, 0x56, 0x62, 0x39, 0xee, 0xf6, 0x1b, 0xf3, 0xf1, 0x94, 0x7c, 0x64, 0x34, 0x14, 0x0f, 0x7f,\n\t0x25, 0x13, 0x5a, 0x07, 0xf3, 0x41, 0x31, 0x73, 0x74, 0xfb, 0xa2, 0xbb, 0xab, 0x85, 0x8f, 0x67,\n\t0x23, 0xa5, 0x59, 0x8b, 0x24, 0x6a, 0x8d, 0xbd, 0x58, 0x8d, 0x0c, 0x07, 0xf5, 0x5d, 0xc5, 0xcc,\n\t0x60, 0xf4, 0xe0, 0x26, 0xf6, 0xc6, 0xb0, 0x12, 0x2e, 0x4d, 0xd8, 0x88, 0xab, 0x7a, 0x1c, 0xe5,\n\t0xa6, 0xe5, 0x60, 0x69, 0xbe, 0x5c, 0xe5, 0x6e, 0xd0, 0x97, 0xf1, 0x52, 0x53, 0xf0, 0x90, 0x17,\n\t0xfa, 0x65, 0x7e, 0xc1, 0x89, 0xce, 0x8e, 0x48, 0xcf, 0xe4, 0x59, 0x09, 0x6d, 0xf8, 0x2c, 0x8a,\n\t0x1e, 0xf2, 0x1e, 0xe9, 0x99, 0x3c, 0x34, 0xd1, 0x87, 0xcf, 0x5e, 0xea, 0xef, 0xa5, 0xfa, 0x8d,\n\t0x3e, 0x1f, 0x46, 0xdc, 0x7c, 0xbe, 0x4d, 0x04, 0xca, 0x47, 0x33, 0xf8, 0x68, 0x8a, 0x36, 0x1a,\n\t0xd2, 0x46, 0x43, 0x02, 0x01, 0x8c, 0xc4, 0x05, 0x02, 0x9b, 0x68, 0x50, 0x07, 0x4d, 0xd2, 0x81,\n\t0x93, 0xac, 0x99, 0x87, 0x4a, 0x12, 0x6d, 0xf9, 0x5a, 0xb9, 0xa8, 0xf5, 0xfe, 0x3f, 0xe4, 0x23,\n\t0x18, 0xc4, 0x94, 0xc6, 0xc7, 0x68, 0x40, 0x0a, 0xa8, 0x06, 0xd2, 0xbd, 0xd1, 0x62, 0x44, 0xdd,\n\t0x51, 0xd1, 0x07, 0x6c, 0xd2, 0x4b, 0x5e, 0x11, 0x18, 0xa5, 0x95, 0x86, 0xb4, 0x52, 0x85, 0xcd,\n\t0x9c, 0x2b, 0x3e, 0x5f, 0x9a, 0x9d, 0x79, 0xbc, 0x34, 0xbb, 0x66, 0x0e, 0xd0, 0x91, 0xdf, 0x6e,\n\t0x67, 0x9d, 0x38, 0xb0, 0x54, 0x7e, 0x03, 0x29, 0xc3, 0xfe, 0x0f, 0x4f, 0xdf, 0x2a, 0x9c, 0x00,\n\t0x26, 0xac, 0xc9, 0x14, 0xff, 0x79, 0xa1, 0x1b, 0x35, 0xbc, 0x68, 0xbe, 0xd5, 0xc2, 0x85, 0x62,\n\t0x4c, 0x8d, 0xa1, 0x1b, 0xbd, 0x64, 0x0f, 0x35, 0xae, 0x4c, 0x3a, 0x62, 0x56, 0x28, 0x4c, 0xa5,\n\t0xc0, 0x5e, 0x1c, 0x51, 0x26, 0x2c, 0x67, 0x43, 0x07, 0x05, 0x30, 0x6f, 0xfe, 0x86, 0x33, 0x86,\n\t0x7e, 0x36, 0xd0, 0x7e, 0x0f, 0xe3, 0xd7, 0x7c, 0x2b, 0xe0, 0xf4, 0x16, 0x0a, 0xd0, 0xea, 0xc8,\n\t0x0f, 0x3e, 0x9b, 0xcb, 0xe3, 0xb2, 0xde, 0x84, 0x6a, 0x86, 0xcb, 0x65, 0xec, 0x9c, 0xd6, 0x29,\n\t0x75, 0xc0, 0x40, 0xa7, 0xed, 0x30, 0xaa, 0x82, 0x14, 0x2c, 0x20, 0x5d, 0xe6, 0x89, 0x0a, 0x3c,\n\t0x13, 0xa5, 0xdc, 0x8b, 0x06, 0xd8, 0xb8, 0x5a, 0x35, 0x2c, 0x19, 0x0f, 0x90, 0x16, 0x1f, 0x43,\n\t0xff, 0x5a, 0x79, 0x42, 0x51, 0x80, 0x7d, 0x31, 0x65, 0xa2, 0x34, 0x9b, 0x0d, 0x1a, 0xf8, 0x2c,\n\t0x3e, 0x30, 0x46, 0xa2, 0x23, 0x46, 0x42, 0x03, 0x46, 0x36, 0x3f, 0xba, 0xe9, 0x32, 0x45, 0xcf,\n\t0x9a, 0xe0, 0xa1, 0xba, 0x5c, 0xd2, 0x6b, 0x1f, 0x90, 0xa2, 0x03, 0xc1, 0xfd, 0xdd, 0x5b, 0x7b,\n\t0xf7, 0xee, 0x0a, 0xf6, 0x77, 0x0f, 0xb8, 0xa6, 0x0e, 0x96, 0x17, 0xca, 0x35, 0xda, 0xe8, 0xef,\n\t0xae, 0x95, 0x3a, 0xda, 0x7a, 0x7e, 0xc1, 0xae, 0x58, 0xbd, 0x72, 0x97, 0x99, 0x68, 0x2b, 0xc3,\n\t0xf5, 0x86, 0xab, 0x33, 0x2f, 0xcc, 0xc7, 0x34, 0xad, 0x70, 0x99, 0x11, 0xe9, 0xef, 0xde, 0xdd,\n\t0xd7, 0xd3, 0xb9, 0xb3, 0x7b, 0x05, 0x84, 0x68, 0x2a, 0x0b, 0x42, 0xb0, 0x40, 0x60, 0x65, 0xa4,\n\t0x93, 0x47, 0x4d, 0xe1, 0x5d, 0x9a, 0xcb, 0xe3, 0x16, 0xd4, 0x27, 0xc1, 0x2d, 0xaa, 0x4f, 0xa2,\n\t0x7b, 0x63, 0x28, 0x16, 0x93, 0x38, 0xea, 0xb0, 0x48, 0x4c, 0x39, 0x1a, 0x9b, 0x1b, 0x73, 0x34,\n\t0x24, 0x6b, 0x95, 0x7a, 0x17, 0x67, 0xca, 0x45, 0x99, 0x5a, 0x2c, 0xff, 0x66, 0x3a, 0xe6, 0xa4,\n\t0xe1, 0x18, 0xc8, 0xc6, 0x70, 0x75, 0x65, 0x74, 0x76, 0x09, 0xb6, 0xf9, 0x01, 0xa5, 0x08, 0x30,\n\t0xc6, 0x58, 0x75, 0x62, 0x37, 0xec, 0x89, 0x7c, 0x91, 0x2f, 0x37, 0x4d, 0xfb, 0x58, 0x32, 0x76,\n\t0xf3, 0x15, 0x0c, 0x43, 0x64, 0x30, 0x16, 0x1d, 0xd1, 0x2d, 0x42, 0x28, 0x93, 0x4e, 0x48, 0x85,\n\t0x33, 0x33, 0xe7, 0x5a, 0x4a, 0x4f, 0x17, 0xbf, 0xd7, 0x8a, 0x5c, 0x70, 0x00, 0xee, 0xf6, 0x49,\n\t0xbe, 0x5d, 0x9d, 0x6e, 0x30, 0xb2, 0xf0, 0x3f, 0xa5, 0xfe, 0xe0, 0x2f, 0x5a, 0x59, 0xf8, 0xa5,\n\t0x73, 0x0e, 0xfe, 0xa2, 0x9d, 0xc5, 0xdf, 0x80, 0x24, 0x62, 0x3f, 0xb2, 0xad, 0xf8, 0xdb, 0x26,\n\t0x79, 0xb1, 0x1f, 0x1d, 0x68, 0xf0, 0x17, 0x80, 0x61, 0x3f, 0x5f, 0x00, 0xf6, 0x25, 0xf8, 0xf5,\n\t0x8b, 0x92, 0x1f, 0xfb, 0xf9, 0xdb, 0x24, 0x3f, 0xf6, 0xa3, 0xc3, 0x0b, 0xfe, 0xfa, 0x60, 0xaf,\n\t0xc2, 0xdf, 0x80, 0xd4, 0x86, 0xfd, 0xda, 0x45, 0xa9, 0x1d, 0xfb, 0xb5, 0xb7, 0x49, 0xed, 0xd8,\n\t0x8f, 0x0e, 0x2a, 0xf8, 0xeb, 0x93, 0x02, 0x84, 0x1d, 0xa0, 0x87, 0xfd, 0x3a, 0x44, 0xa9, 0x03,\n\t0xfb, 0x75, 0xb4, 0xc1, 0x8e, 0x86, 0x78, 0xf2, 0xc0, 0x01, 0x3d, 0xf9, 0xe0, 0xc9, 0x47, 0x4f,\n\t0x01, 0x78, 0x22, 0x6a, 0x90, 0x1c, 0x4e, 0x0f, 0x12, 0x44, 0x14, 0xa9, 0x09, 0x46, 0xf4, 0x04,\n\t0x23, 0x88, 0x2a, 0x01, 0xc8, 0x12, 0x88, 0x2e, 0x01, 0x08, 0x13, 0x88, 0x32, 0x01, 0x48, 0x13,\n\t0x88, 0x36, 0x01, 0x88, 0x13, 0x88, 0x3a, 0x01, 0xc8, 0x13, 0x88, 0x3e, 0x01, 0x08, 0x14, 0x88,\n\t0x42, 0x01, 0x48, 0x14, 0x88, 0x46, 0x01, 0x88, 0x14, 0x88, 0x4a, 0xd8, 0xd7, 0x81, 0x7d, 0x34,\n\t0x02, 0x08, 0x15, 0x88, 0x52, 0x01, 0x48, 0x15, 0x88, 0x56, 0x01, 0x88, 0x15, 0x88, 0x5a, 0x01,\n\t0xc8, 0x15, 0x88, 0x5e, 0x01, 0x08, 0x16, 0x88, 0x62, 0x01, 0x48, 0x16, 0x88, 0x66, 0x01, 0x88,\n\t0x16, 0x88, 0x6a, 0x01, 0xc8, 0x16, 0x88, 0x6e, 0x01, 0x08, 0x17, 0x3a, 0xb8, 0x64, 0x28, 0x06,\n\t0x45, 0x4f, 0x20, 0x1c, 0xa2, 0x5c, 0x04, 0xca, 0x45, 0xa2, 0x5c, 0x04, 0xca, 0x45, 0xa2, 0x5c,\n\t0x04, 0xca, 0x45, 0x2e, 0x4b, 0x14, 0x26, 0x97, 0x26, 0x8a, 0x93, 0xcb, 0x13, 0x05, 0x4a, 0x94,\n\t0x8b, 0x40, 0xb9, 0x48, 0x94, 0x8b, 0x40, 0xb9, 0x48, 0x94, 0x83, 0x1f, 0x02, 0x62, 0xe7, 0xf2,\n\t0x47, 0x05, 0xa0, 0x11, 0x40, 0xb9, 0x48, 0x94, 0x8b, 0x40, 0xb9, 0x48, 0x94, 0x8b, 0x40, 0xb9,\n\t0x88, 0x94, 0xdb, 0x96, 0x0f, 0x3c, 0x4c, 0x80, 0x9e, 0xef, 0x56, 0xf2, 0xb0, 0x5a, 0x67, 0xb4,\n\t0xac, 0x10, 0x9e, 0x4f, 0xe1, 0xd8, 0xc4, 0x96, 0x60, 0x31, 0x2d, 0xb0, 0xbb, 0xd8, 0x65, 0xa5,\n\t0x4d, 0x53, 0x4d, 0x24, 0x68, 0x02, 0x23, 0xff, 0x26, 0x2e, 0x94, 0xb9, 0x5b, 0xe5, 0x3b, 0x2b,\n\t0xee, 0xa2, 0x43, 0xa9, 0x11, 0x39, 0x3d, 0x9c, 0x30, 0x9c, 0xce, 0x70, 0x38, 0x19, 0x1a, 0x57,\n\t0xf7, 0xbb, 0x2d, 0xf0, 0xe8, 0x1e, 0x0c, 0xa7, 0xa4, 0xae, 0xe1, 0x50, 0x3c, 0x22, 0x6f, 0x89,\n\t0xa6, 0x46, 0x63, 0xa1, 0xa3, 0x7d, 0x72, 0x3a, 0x1d, 0x8d, 0x47, 0x52, 0xae, 0xe0, 0x9e, 0x9e,\n\t0x15, 0x69, 0xc5, 0x13, 0xa9, 0xb2, 0x43, 0xc9, 0xc1, 0x33, 0xc3, 0xfb, 0x13, 0x69, 0xe5, 0x66,\n\t0x67, 0x47, 0x9e, 0xe8, 0x6c, 0x08, 0x34, 0xcd, 0xde, 0x5f, 0x05, 0x16, 0x18, 0x53, 0xf6, 0x92,\n\t0xe5, 0x9a, 0x78, 0x28, 0x75, 0x78, 0x74, 0xd4, 0xe4, 0x5b, 0x0f, 0x12, 0x4d, 0x92, 0x06, 0xdf,\n\t0xad, 0xf9, 0x54, 0x1c, 0x8c, 0x5b, 0x73, 0xaa, 0xd4, 0xa2, 0xe6, 0x47, 0xf1, 0xe2, 0xaa, 0x64,\n\t0x63, 0x02, 0x50, 0xae, 0x5e, 0xfe, 0x26, 0xa6, 0x06, 0xad, 0xd0, 0xd8, 0x24, 0x87, 0x02, 0xac,\n\t0x95, 0xfd, 0x78, 0x3a, 0x05, 0xa7, 0x8e, 0x99, 0x47, 0xc8, 0x7d, 0x04, 0xd5, 0x30, 0x41, 0xa8,\n\t0x63, 0x6f, 0x3c, 0x32, 0xa9, 0x79, 0x7c, 0x3c, 0x5b, 0xef, 0xbc, 0x91, 0x42, 0xa6, 0xda, 0xd4,\n\t0x60, 0x71, 0x30, 0xf7, 0x9d, 0x59, 0x38, 0xd6, 0x22, 0x63, 0xb4, 0xd9, 0xc1, 0x2f, 0x7b, 0x2d,\n\t0x1b, 0xa4, 0x9c, 0x5e, 0xa4, 0xe7, 0xa9, 0x99, 0x9b, 0xa6, 0x3d, 0x94, 0xcf, 0xc4, 0x7b, 0x2e,\n\t0xa9, 0xb4, 0x52, 0xbc, 0x50, 0xad, 0x43, 0x35, 0xba, 0xc7, 0xde, 0xa0, 0x78, 0x9d, 0x96, 0x45,\n\t0xa8, 0x46, 0xb7, 0x31, 0xcf, 0x94, 0x8e, 0xab, 0xd7, 0xf5, 0xbe, 0xfa, 0x95, 0xab, 0x86, 0x37,\n\t0x31, 0x1e, 0xb3, 0x69, 0xb6, 0x51, 0x3a, 0xd3, 0x4c, 0xf9, 0x34, 0x5b, 0xcc, 0x47, 0xca, 0xbf,\n\t0xa9, 0x1c, 0x2c, 0x3c, 0xcb, 0xea, 0x66, 0x0a, 0xcc, 0xb9, 0x9c, 0x94, 0x41, 0xd8, 0x28, 0x7a,\n\t0x15, 0x06, 0xdf, 0x19, 0x35, 0x28, 0xb8, 0x63, 0xc0, 0x76, 0xac, 0xc5, 0x29, 0xab, 0x16, 0xca,\n\t0xae, 0xe0, 0x29, 0x0e, 0xaf, 0xbb, 0x00, 0x1e, 0x53, 0xbe, 0xa4, 0x1c, 0x02, 0xda, 0x0d, 0x2a,\n\t0xe9, 0x94, 0x46, 0xb1, 0x3a, 0x4a, 0x31, 0x64, 0xef, 0x98, 0x53, 0x0c, 0x0d, 0x49, 0x35, 0xf2,\n\t0xd4, 0x2e, 0x37, 0x94, 0x14, 0xe0, 0xae, 0xf6, 0x73, 0x50, 0xdb, 0xab, 0x8d, 0xf2, 0x80, 0x63,\n\t0xc0, 0x65, 0x4c, 0x86, 0x9d, 0x78, 0x97, 0x2d, 0x68, 0xfc, 0x23, 0x98, 0x0e, 0x18, 0xa0, 0x5e,\n\t0x18, 0xfd, 0x1a, 0x82, 0x1a, 0x6b, 0x90, 0xac, 0x15, 0x82, 0x75, 0x26, 0x94, 0x65, 0x33, 0x9c,\n\t0x55, 0x9a, 0x6a, 0x0d, 0xe3, 0xee, 0x56, 0xde, 0x2a, 0xfe, 0x92, 0x12, 0x7c, 0xef, 0x68, 0xf1,\n\t0x5f, 0x25, 0xc3, 0x03, 0x1b, 0xf9, 0x6b, 0x9c, 0xd7, 0xec, 0x96, 0xc6, 0x19, 0x3a, 0x31, 0x1f,\n\t0x05, 0xd8, 0x11, 0x80, 0x55, 0xaf, 0xbc, 0x45, 0x31, 0xdc, 0xb7, 0x79, 0xe2, 0x8c, 0xae, 0x0d,\n\t0x70, 0xbc, 0xc8, 0x9d, 0xd2, 0x75, 0x3f, 0x5d, 0x7c, 0x55, 0x85, 0x82, 0x79, 0x09, 0x3c, 0x66,\n\t0xac, 0x69, 0x49, 0xd5, 0x58, 0x23, 0xcd, 0xa3, 0x5f, 0x16, 0x0d, 0x74, 0xc8, 0x7a, 0x70, 0x32,\n\t0x2e, 0xba, 0x84, 0x00, 0x37, 0xc0, 0x5d, 0x87, 0x40, 0x47, 0xba, 0xeb, 0x46, 0x4a, 0x34, 0x19,\n\t0x9a, 0xa4, 0x9c, 0x6a, 0xf4, 0x3f, 0xdc, 0xa3, 0xc9, 0xc4, 0x68, 0x22, 0x99, 0x8e, 0xe2, 0x2b,\n\t0x01, 0x52, 0xa3, 0xe6, 0xb8, 0xe3, 0x72, 0x08, 0x06, 0xa6, 0x25, 0xab, 0x40, 0xdc, 0xba, 0xa5,\n\t0xb2, 0xa3, 0xbd, 0xba, 0xed, 0x75, 0x5c, 0x15, 0x8d, 0x06, 0x09, 0xbd, 0x50, 0x63, 0x11, 0x52,\n\t0x67, 0x2e, 0x1c, 0x1c, 0x62, 0xce, 0xef, 0xb3, 0x1c, 0xe7, 0x1c, 0xaf, 0xbe, 0x56, 0x5c, 0x4c,\n\t0x26, 0x26, 0x9b, 0x2f, 0x96, 0xad, 0x68, 0x9a, 0x67, 0x36, 0xd2, 0xd3, 0x51, 0xc0, 0x53, 0x6f,\n\t0xa9, 0x4a, 0xb3, 0x6c, 0xcc, 0x41, 0x86, 0x86, 0x9c, 0x56, 0x58, 0xde, 0x1f, 0x41, 0x5f, 0x3d,\n\t0x4a, 0x06, 0xe3, 0xf5, 0xe5, 0xc2, 0x61, 0xea, 0x8b, 0xeb, 0x7c, 0xf1, 0xfd, 0xdc, 0x0f, 0xd9,\n\t0xad, 0xa9, 0x97, 0x72, 0xdd, 0x6c, 0x69, 0xf2, 0xe9, 0xfc, 0xcf, 0xd5, 0x50, 0x8c, 0xea, 0x7e,\n\t0x02, 0xcc, 0x1f, 0xb0, 0xe5, 0xd2, 0x21, 0x76, 0x79, 0xaa, 0xd2, 0x24, 0x73, 0x90, 0xab, 0xdf,\n\t0x02, 0x28, 0xeb, 0x4f, 0xe0, 0x7f, 0x3e, 0x5b, 0x43, 0xf4, 0x6d, 0x75, 0xba, 0x70, 0x79, 0x99,\n\t0xe6, 0xc7, 0x2c, 0x78, 0x9e, 0x3c, 0x08, 0xd2, 0xd7, 0xa1, 0xbf, 0xcd, 0xcd, 0x22, 0xab, 0xea,\n\t0x57, 0x2a, 0x2a, 0x3f, 0xd4, 0x57, 0x07, 0x08, 0x97, 0x7c, 0x2f, 0xbe, 0x17, 0xc2, 0xde, 0x29,\n\t0x26, 0xd8, 0xdd, 0xf9, 0xda, 0xc9, 0xdb, 0x60, 0x6a, 0xce, 0xf2, 0xc8, 0x5a, 0x63, 0x5a, 0x8e,\n\t0xe9, 0xa4, 0xe2, 0x74, 0x85, 0xd3, 0x0c, 0xeb, 0x65, 0xca, 0x0d, 0x68, 0x72, 0xad, 0xb3, 0xd2,\n\t0x26, 0x87, 0xa6, 0x57, 0xdf, 0xd4, 0x74, 0x33, 0xae, 0x2f, 0xd9, 0xba, 0x09, 0x0f, 0x9e, 0x85,\n\t0x73, 0x73, 0xad, 0x66, 0xd9, 0x96, 0xf9, 0x3d, 0x94, 0x3a, 0x96, 0x48, 0x18, 0x9e, 0x7f, 0x34,\n\t0x1e, 0xc7, 0x2b, 0x9e, 0x26, 0x50, 0xdc, 0x89, 0x4c, 0x5a, 0x6f, 0x6e, 0x14, 0xa5, 0x5b, 0x0f,\n\t0xbe, 0x39, 0x9c, 0x86, 0x72, 0xb9, 0xc2, 0xa3, 0xac, 0x56, 0xa9, 0xe6, 0x9f, 0xc6, 0xfc, 0x63,\n\t0x49, 0xaf, 0xaa, 0x4f, 0xfd, 0x02, 0x16, 0xc6, 0x59, 0x6c, 0xa0, 0x70, 0xc8, 0x1a, 0xa3, 0x1f,\n\t0xdc, 0x91, 0xd3, 0x2c, 0x22, 0x7b, 0x8d, 0x7d, 0x40, 0x49, 0xe4, 0xf5, 0xf9, 0x27, 0xd5, 0xf7,\n\t0x74, 0x1c, 0x92, 0xc8, 0x2b, 0x4f, 0xe4, 0x6e, 0xc3, 0x0a, 0x5f, 0x63, 0x2a, 0xb9, 0x49, 0x50,\n\t0x8f, 0x83, 0x2d, 0x9e, 0xd0, 0xcf, 0xce, 0x79, 0x4c, 0xb1, 0xa1, 0xa3, 0xaa, 0x7a, 0x82, 0xd3,\n\t0x93, 0xa1, 0x2e, 0x35, 0x08, 0x6a, 0xd9, 0x10, 0xd4, 0xc9, 0xeb, 0xa8, 0x70, 0xfa, 0x69, 0x0c,\n\t0xa3, 0x99, 0x75, 0xf6, 0xfd, 0xfc, 0x19, 0x50, 0x5c, 0xed, 0xf4, 0x19, 0x01, 0x5f, 0x31, 0x6a,\n\t0xcd, 0xac, 0x21, 0xbe, 0x46, 0xe3, 0x69, 0x09, 0x0e, 0xf0, 0x33, 0xca, 0x21, 0x40, 0x7b, 0x12,\n\t0xfe, 0x06, 0x90, 0x5d, 0xee, 0xc3, 0xd1, 0x70, 0x54, 0x2a, 0x27, 0x2a, 0x1f, 0x4d, 0x7e, 0x4c,\n\t0xe5, 0x66, 0xec, 0x77, 0xc2, 0x5f, 0x72, 0xaa, 0x5c, 0x63, 0xda, 0xdb, 0x69, 0x7b, 0xd6, 0xf9,\n\t0x9f, 0x2d, 0x04, 0xcb, 0x4b, 0x10, 0xc7, 0x33, 0x29, 0x39, 0x7c, 0xd8, 0x1c, 0xd1, 0x55, 0xdd,\n\t0x33, 0x2d, 0xaa, 0x8b, 0x28, 0xac, 0x81, 0x44, 0x4c, 0x7b, 0x5b, 0x37, 0x99, 0x4e, 0xfe, 0xa4,\n\t0xe1, 0xe0, 0x6b, 0xf7, 0xc3, 0xbc, 0xc6, 0xbb, 0x05, 0x88, 0xbf, 0x46, 0xe4, 0x9f, 0xb1, 0x11,\n\t0x56, 0x9b, 0xbf, 0xc6, 0x16, 0x2a, 0x1f, 0x35, 0x78, 0x9c, 0x36, 0x0d, 0xdb, 0xb6, 0xa5, 0x87,\n\t0xab, 0x13, 0xbf, 0xe2, 0x35, 0x4d, 0xd4, 0x50, 0x0b, 0x93, 0x69, 0x75, 0xa0, 0x68, 0xe5, 0x8b,\n\t0x3a, 0xfa, 0xcb, 0xfc, 0xdc, 0xa2, 0xd9, 0x30, 0x7e, 0x3b, 0xa0, 0x39, 0xb8, 0xa6, 0x0c, 0xb6,\n\t0xf0, 0xe1, 0x54, 0xfa, 0x68, 0x4c, 0x76, 0xd8, 0x6c, 0x23, 0xa0, 0x4e, 0x3a, 0x26, 0x6e, 0xfb,\n\t0xa1, 0x46, 0xab, 0xf6, 0x86, 0x25, 0x2b, 0x26, 0x36, 0x51, 0x68, 0x7b, 0x26, 0xed, 0xa6, 0x03,\n\t0xca, 0x53, 0x98, 0x37, 0x4d, 0x1a, 0xd7, 0xac, 0x61, 0x75, 0x71, 0xc0, 0x62, 0xf9, 0x01, 0x5b,\n\t0x9c, 0xfc, 0x11, 0x65, 0xf7, 0x19, 0xe3, 0xae, 0x36, 0x73, 0x6d, 0x2d, 0x76, 0x54, 0xcb, 0x55,\n\t0x54, 0x2f, 0x9e, 0x74, 0x5b, 0x5d, 0x25, 0xad, 0xad, 0x93, 0xf1, 0x32, 0x9c, 0x70, 0xda, 0x33,\n\t0xc9, 0x05, 0xd6, 0xde, 0xce, 0x5a, 0xca, 0x8e, 0xe9, 0x3b, 0x90, 0x69, 0x27, 0xaf, 0x1c, 0xd4,\n\t0xc4, 0xd8, 0x40, 0xcb, 0x87, 0x86, 0xe3, 0xde, 0xd4, 0x78, 0x2c, 0x91, 0xd0, 0x55, 0x41, 0x1a,\n\t0x7e, 0xe0, 0xa5, 0xca, 0xf7, 0x1b, 0x4c, 0x74, 0x6a, 0x24, 0x91, 0x48, 0x0f, 0x5b, 0xcc, 0xb4,\n\t0x6e, 0x19, 0x9a, 0x2d, 0x79, 0xf3, 0x6b, 0x5e, 0x2b, 0xbe, 0x68, 0xc1, 0xfd, 0x41, 0xca, 0xd1,\n\t0x1e, 0x00, 0xcf, 0x77, 0x52, 0xe9, 0x02, 0x86, 0xa9, 0x83, 0x41, 0xfb, 0x7f, 0x46, 0x4c, 0x3b,\n\t0xc3, 0x3e, 0xa0, 0x65, 0xbb, 0xc6, 0x1b, 0xd6, 0xbf, 0xbc, 0x6d, 0x3e, 0x3e, 0x1e, 0x8a, 0xa6,\n\t0xc7, 0x52, 0x47, 0xe3, 0x83, 0xe6, 0x44, 0x3c, 0xcd, 0x1e, 0xdb, 0x6c, 0x86, 0xdd, 0x54, 0x04,\n\t0x01, 0xf6, 0x13, 0xa0, 0x06, 0x5d, 0xfc, 0xee, 0x09, 0xdf, 0x1c, 0xc5, 0xd9, 0xb9, 0xb9, 0x68,\n\t0xda, 0xb8, 0x96, 0xb8, 0x02, 0x90, 0x01, 0xfd, 0x59, 0x95, 0x1c, 0x70, 0xf5, 0xfa, 0x4b, 0xaf,\n\t0xfb, 0x1f, 0x24, 0x9c, 0xa7, 0x05, 0xaf, 0x16, 0x61, 0xd0, 0xa3, 0xbe, 0x79, 0xa5, 0x1f, 0xf0,\n\t0x19, 0xe3, 0x5a, 0xd3, 0xe2, 0xcb, 0x9e, 0xf0, 0xb5, 0xba, 0xd8, 0xb2, 0xcb, 0x56, 0x1f, 0xc8,\n\t0x9e, 0x08, 0x40, 0x3d, 0xbd, 0x87, 0x46, 0x99, 0xde, 0x8b, 0x9c, 0xa7, 0xf4, 0x32, 0xd6, 0x32,\n\t0xbd, 0x34, 0x63, 0x78, 0xda, 0xa1, 0x90, 0x2d, 0x78, 0x61, 0xac, 0x7f, 0xf0, 0xa4, 0x03, 0x92,\n\t0x13, 0x6c, 0x6c, 0xf1, 0xd9, 0x5b, 0x08, 0x1b, 0x77, 0x68, 0x34, 0x2a, 0x1d, 0x88, 0xc6, 0xc3,\n\t0x89, 0x71, 0xa7, 0xd8, 0xc6, 0x8e, 0x3d, 0xdd, 0xdb, 0x28, 0xee, 0xa9, 0xa6, 0xe8, 0xd2, 0xbb,\n\t0x62, 0x5a, 0xa5, 0x91, 0xb9, 0xdb, 0x32, 0x73, 0x20, 0xbf, 0xa3, 0x75, 0x2d, 0x6f, 0x8f, 0x19,\n\t0xe6, 0x98, 0x13, 0x47, 0x59, 0xba, 0xe6, 0x97, 0xeb, 0xb4, 0x5c, 0x60, 0x20, 0xdb, 0x9a, 0xf2,\n\t0xbe, 0xd2, 0x8b, 0x7d, 0x8d, 0x8c, 0xb2, 0xc2, 0x6a, 0x48, 0x9f, 0xff, 0xd2, 0xa8, 0x1c, 0x09,\n\t0x1b, 0x6f, 0x85, 0xe9, 0x2f, 0x7e, 0xe9, 0xef, 0x87, 0x55, 0x0e, 0x14, 0x9f, 0x32, 0xbf, 0x38,\n\t0x67, 0x66, 0x0a, 0xea, 0x93, 0x96, 0xa5, 0x5c, 0x9a, 0x95, 0xb0, 0x88, 0x2e, 0x11, 0x3f, 0x54,\n\t0xe8, 0x51, 0x61, 0x3d, 0x8d, 0xd9, 0xf9, 0x7a, 0xcc, 0x0c, 0x04, 0x14, 0xf0, 0x3b, 0xa5, 0x59,\n\t0x8b, 0x67, 0xb1, 0x08, 0xe8, 0x3f, 0x09, 0x66, 0xe7, 0x09, 0x65, 0xaf, 0x12, 0x54, 0x6f, 0x60,\n\t0x6b, 0x34, 0xc6, 0xba, 0xc2, 0xea, 0x93, 0x1f, 0x17, 0xdf, 0x27, 0xe7, 0xee, 0x03, 0xa7, 0x77,\n\t0x67, 0x90, 0x0d, 0x13, 0x69, 0x70, 0x03, 0xd7, 0xba, 0x2e, 0x71, 0xcf, 0x48, 0x0f, 0x27, 0x65,\n\t0xe3, 0x46, 0xd6, 0x88, 0x25, 0xd3, 0xc1, 0xfa, 0x51, 0x40, 0xb8, 0x1f, 0xb3, 0x18, 0x66, 0xfe,\n\t0x11, 0x56, 0xe7, 0x82, 0x46, 0x02, 0xe5, 0x4d, 0x0b, 0x5a, 0xc9, 0x2d, 0x4a, 0xa2, 0xfe, 0xec,\n\t0x93, 0x7c, 0xfa, 0x73, 0x40, 0x0a, 0x68, 0xcf, 0x8d, 0x27, 0xb9, 0xed, 0x74, 0xb7, 0x8c, 0x81,\n\t0xea, 0x1c, 0x4d, 0x13, 0x91, 0xb4, 0x4a, 0x56, 0xd7, 0xb2, 0x84, 0xd1, 0xb6, 0xeb, 0x47, 0xfa,\n\t0xbb, 0xe6, 0xce, 0x8e, 0x57, 0x4b, 0x43, 0x04, 0x61, 0x02, 0x5a, 0x61, 0x7f, 0xed, 0xdb, 0xde,\n\t0xb3, 0xb5, 0x7f, 0x47, 0x4f, 0xdf, 0xe3, 0x5d, 0xdb, 0x83, 0x7b, 0xfb, 0xba, 0xfb, 0x59, 0x95,\n\t0x46, 0x68, 0xc1, 0x01, 0xbe, 0x17, 0xe4, 0x14, 0x59, 0x99, 0xa1, 0x15, 0x5f, 0xd3, 0x67, 0xaf,\n\t0xf2, 0x97, 0x6f, 0xcc, 0x56, 0x81, 0x18, 0x47, 0x09, 0xf7, 0x5b, 0xba, 0xb7, 0x06, 0xf7, 0xed,\n\t0xec, 0xd7, 0x81, 0x72, 0x0f, 0xb1, 0xae, 0x07, 0x25, 0x55, 0x79, 0xd2, 0xe0, 0xaa, 0xfe, 0x16,\n\t0x90, 0x76, 0x1b, 0x6e, 0x0a, 0x4a, 0x26, 0xe2, 0x69, 0x38, 0xf4, 0x26, 0x53, 0x72, 0xda, 0xb8,\n\t0xbc, 0x08, 0xee, 0xee, 0xeb, 0xd1, 0x20, 0xbb, 0x05, 0xc9, 0x36, 0x17, 0xb0, 0xb9, 0xef, 0x1f,\n\t0x76, 0x75, 0xf6, 0xee, 0xd4, 0x2b, 0xda, 0xdb, 0xa5, 0x5d, 0xc1, 0x2e, 0xbd, 0xb8, 0x11, 0xe3,\n\t0xdb, 0x76, 0xb2, 0xdd, 0x82, 0xd8, 0x21, 0x6d, 0x0f, 0xee, 0xde, 0xd6, 0xbd, 0xcf, 0x18, 0x28,\n\t0x78, 0x3d, 0xd2, 0x8e, 0xde, 0xed, 0xc1, 0x4e, 0x53, 0x8d, 0x4f, 0xda, 0xd6, 0x29, 0x7a, 0x05,\n\t0xaf, 0xa9, 0xaa, 0x4d, 0xea, 0xda, 0xde, 0xb3, 0xbb, 0xbb, 0xaf, 0xbb, 0xb3, 0x67, 0x9b, 0xdf,\n\t0xa8, 0x6f, 0x13, 0xa4, 0x6d, 0x7b, 0xbb, 0xbb, 0x1f, 0x31, 0xd5, 0x88, 0x52, 0xff, 0xbe, 0xbd,\n\t0x8f, 0xf4, 0xf4, 0x6d, 0x37, 0xea, 0x00, 0xb9, 0xed, 0xdd, 0x9d, 0x7b, 0xbb, 0x0f, 0x98, 0xaa,\n\t0x02, 0x52, 0x70, 0x6f, 0xb0, 0xb3, 0xa7, 0xcb, 0x65, 0xd4, 0x05, 0xda, 0xa4, 0xce, 0xe0, 0xce,\n\t0xfe, 0x1e, 0x83, 0x0c, 0x8c, 0x73, 0xef, 0xdd, 0xd7, 0xd7, 0xd7, 0x13, 0xdc, 0x6d, 0xd4, 0x89,\n\t0x30, 0xc3, 0xf6, 0xa0, 0xc1, 0x1d, 0xd1, 0x1b, 0x90, 0xba, 0xbb, 0x8d, 0xa2, 0xdf, 0x2f, 0xf5,\n\t0x76, 0xef, 0xd2, 0xca, 0x9f, 0xfe, 0x54, 0xd7, 0x9e, 0x7d, 0xae, 0x89, 0x2f, 0xcc, 0x1e, 0xdc,\n\t0xbc, 0x6b, 0xd7, 0x80, 0x84, 0x85, 0xd9, 0xad, 0x85, 0x17, 0x68, 0x67, 0x85, 0xed, 0x5d, 0xbd,\n\t0x8b, 0xd1, 0x73, 0xe9, 0xa6, 0xff, 0xb5, 0x74, 0xce, 0xe6, 0x76, 0x0d, 0x8e, 0x66, 0x46, 0x46,\n\t0x8e, 0x58, 0x76, 0x70, 0xf5, 0x05, 0xb2, 0x83, 0x74, 0x34, 0xbb, 0xc7, 0xde, 0xd0, 0xf7, 0x2f,\n\t0x75, 0xfb, 0xd2, 0xdb, 0x70, 0x0f, 0xbe, 0x69, 0x72, 0x82, 0x29, 0x63, 0x48, 0xd2, 0xf2, 0x3e,\n\t0xb4, 0x61, 0x26, 0x1c, 0xbd, 0x5b, 0x76, 0x27, 0xc6, 0x3f, 0xb3, 0x4e, 0x34, 0xbd, 0xe1, 0xf8,\n\t0x27, 0x84, 0x66, 0x5f, 0x5f, 0xf7, 0x3a, 0x71, 0x4c, 0xa5, 0xe4, 0x4f, 0x08, 0xc7, 0xae, 0x5d,\n\t0xbd, 0xfb, 0x07, 0x07, 0xd7, 0x89, 0xe6, 0xe0, 0x48, 0x62, 0xec, 0x13, 0xc2, 0xb3, 0x3b, 0x3e,\n\t0x1c, 0x8a, 0x0f, 0xca, 0x98, 0xe6, 0xf5, 0x67, 0xc8, 0x5e, 0xfe, 0xe4, 0x84, 0xdf, 0x0d, 0x0b,\n\t0xc9, 0xd5, 0x02, 0xff, 0x89, 0xad, 0xeb, 0x45, 0xf6, 0x93, 0x5b, 0x50, 0xa0, 0xa9, 0xe2, 0xfa,\n\t0x55, 0x55, 0xfc, 0xcb, 0x62, 0x09, 0xdb, 0x14, 0x1e, 0x2f, 0x7a, 0x37, 0x6b, 0x0f, 0xda, 0xd5,\n\t0x91, 0xa5, 0x08, 0xfe, 0x37, 0x4f, 0xce, 0x5b, 0xf5, 0x7d, 0x54, 0xec, 0x67, 0x75, 0x90, 0xf4,\n\t0xaf, 0xd8, 0x2c, 0xdb, 0x60, 0x2e, 0xd2, 0x4b, 0xfc, 0xe7, 0xe1, 0xe0, 0xb4, 0x00, 0x54, 0xe3,\n\t0xeb, 0xe4, 0x35, 0xad, 0x47, 0xe1, 0x48, 0xee, 0x19, 0xe4, 0x9d, 0x3d, 0x29, 0x10, 0x7d, 0x0a,\n\t0xbc, 0xd1, 0x2e, 0x3f, 0xcf, 0x9d, 0x2e, 0xd3, 0xc1, 0x3f, 0x2c, 0x1f, 0xce, 0x44, 0xcc, 0x07,\n\t0xff, 0xb9, 0x17, 0x27, 0xff, 0x48, 0xae, 0x3d, 0x82, 0x30, 0x13, 0x8a, 0x47, 0xa9, 0x2e, 0x90,\n\t0xc0, 0x9b, 0x30, 0xdf, 0x14, 0x46, 0x33, 0xf0, 0x6d, 0xf7, 0x83, 0xfc, 0xd5, 0x62, 0xac, 0x60,\n\t0x75, 0xbd, 0xcb, 0x52, 0x31, 0x31, 0xbf, 0xbc, 0x3a, 0xd1, 0x5a, 0x2f, 0x5b, 0x64, 0x4f, 0x87,\n\t0x32, 0x7d, 0x2d, 0x77, 0x99, 0xe4, 0x50, 0x65, 0x1f, 0xf0, 0x19, 0x68, 0x44, 0x63, 0x2c, 0x77,\n\t0x37, 0x9e, 0x1c, 0x9a, 0x40, 0xe1, 0x1f, 0x94, 0xa9, 0xf3, 0x3e, 0xa4, 0x2a, 0x67, 0x34, 0x68,\n\t0xf8, 0x3a, 0x92, 0xce, 0x08, 0x92, 0x74, 0x2c, 0x61, 0xe1, 0x85, 0x3a, 0x9d, 0x16, 0x04, 0xd1,\n\t0xf0, 0x75, 0x0f, 0xc6, 0xe4, 0x50, 0x52, 0xe2, 0x20, 0xcd, 0x2c, 0xda, 0x86, 0x97, 0x6e, 0x74,\n\t0xd6, 0x6e, 0x60, 0x16, 0x35, 0xa9, 0xa1, 0x02, 0xed, 0x2b, 0x16, 0xe8, 0x7b, 0xaa, 0x31, 0x8a,\n\t0x15, 0x98, 0xf9, 0xe6, 0xff, 0x43, 0x66, 0x02, 0x1f, 0xe5, 0x64, 0x32, 0xa1, 0x7f, 0xa2, 0xc0,\n\t0xca, 0xcb, 0x8d, 0x6b, 0x62, 0xa6, 0x49, 0xa7, 0x8d, 0xf7, 0xc2, 0x25, 0xe7, 0xea, 0x16, 0x83,\n\t0x7f, 0xd9, 0x60, 0xfe, 0x4a, 0x61, 0xa2, 0x70, 0x0e, 0x5d, 0xbd, 0xd6, 0xd5, 0x16, 0x20, 0x57,\n\t0xff, 0xf1, 0xa8, 0xd5, 0x00, 0xe3, 0x18, 0xb7, 0xba, 0x14, 0x00, 0xa3, 0x63, 0xe8, 0xab, 0xe2,\n\t0x2b, 0xc1, 0x9b, 0x69, 0x96, 0x88, 0x32, 0x05, 0xf3, 0xe4, 0x24, 0x60, 0x95, 0xa9, 0x88, 0x0c,\n\t0x23, 0x87, 0x51, 0xfd, 0x58, 0x0e, 0x88, 0x51, 0x1f, 0xa7, 0xdf, 0x41, 0x98, 0xcd, 0xd4, 0xf0,\n\t0x97, 0xd5, 0xbc, 0xb0, 0x18, 0x7e, 0xc9, 0x81, 0x7f, 0x80, 0xc8, 0xeb, 0x01, 0xa7, 0xbc, 0x6f,\n\t0x38, 0x3a, 0x94, 0xfe, 0xbb, 0xad, 0x82, 0x75, 0x66, 0x0a, 0xb6, 0x80, 0x3b, 0x1f, 0x01, 0x4d,\n\t0xc2, 0xc8, 0xc1, 0x21, 0x9c, 0xbf, 0xa1, 0x72, 0x1d, 0x58, 0xc8, 0xe1, 0x68, 0x3a, 0xe1, 0x88,\n\t0x81, 0x68, 0xc1, 0x80, 0x73, 0x15, 0x66, 0xe5, 0x0f, 0xeb, 0x98, 0x69, 0x3c, 0x04, 0xde, 0xb2,\n\t0xd3, 0x44, 0xde, 0x46, 0x26, 0x93, 0x28, 0x35, 0x16, 0x73, 0xb9, 0xae, 0x8b, 0xc1, 0xa9, 0x04,\n\t0x86, 0xdd, 0x1a, 0xa7, 0xf4, 0x59, 0x69, 0x83, 0xd3, 0x5a, 0xf1, 0x77, 0x95, 0xfb, 0x00, 0x73,\n\t0x2f, 0xe6, 0x5e, 0x49, 0x7a, 0x05, 0x57, 0xf5, 0xc3, 0xc0, 0xe3, 0xaf, 0x92, 0xf1, 0x5d, 0xe2,\n\t0x1d, 0x1e, 0x04, 0x89, 0x58, 0x74, 0x54, 0x8e, 0x8f, 0x45, 0xe3, 0x43, 0x09, 0x0b, 0x22, 0x5d,\n\t0xe9, 0x64, 0x0c, 0xa4, 0x6c, 0x15, 0xf3, 0xf4, 0x37, 0xa6, 0x7e, 0x3b, 0xf9, 0x6d, 0x8e, 0x0a,\n\t0x5d, 0x82, 0x99, 0x2a, 0x1e, 0x94, 0xfa, 0xd0, 0xe1, 0x44, 0x26, 0xed, 0x34, 0xa5, 0x55, 0xae,\n\t0x53, 0x03, 0xa5, 0xfd, 0x13, 0x77, 0x27, 0x9f, 0x50, 0x27, 0xc4, 0x70, 0x94, 0xf2, 0x34, 0xab,\n\t0xe9, 0xd5, 0x0f, 0x3a, 0x6d, 0x06, 0xbf, 0xf8, 0x25, 0x63, 0xb0, 0xd2, 0x51, 0xab, 0x6d, 0x6a,\n\t0x4d, 0xb3, 0x61, 0xba, 0x18, 0x40, 0x7e, 0x1c, 0x23, 0x1d, 0x92, 0xa9, 0xaa, 0x6e, 0xb2, 0x8a,\n\t0x4b, 0xbc, 0xf9, 0x01, 0x10, 0x09, 0x67, 0x46, 0x30, 0x0d, 0xa4, 0xc9, 0xea, 0x12, 0x8d, 0x4f,\n\t0xa4, 0x4c, 0xbe, 0x93, 0xbf, 0x50, 0x7a, 0x6e, 0x33, 0x18, 0xbd, 0x2f, 0x2a, 0x3b, 0xf0, 0x95,\n\t0x68, 0x58, 0x4b, 0x79, 0xe5, 0x04, 0x2c, 0x31, 0xa3, 0x6a, 0xee, 0x22, 0x58, 0x41, 0xbd, 0x34,\n\t0x73, 0x13, 0x46, 0x46, 0xe8, 0x5a, 0xe0, 0x00, 0xb4, 0xd4, 0x27, 0x6e, 0xe3, 0xc7, 0xae, 0xf8,\n\t0x11, 0xb4, 0xd1, 0x36, 0x8b, 0x9b, 0x84, 0x0e, 0xd7, 0x61, 0x39, 0x1d, 0x72, 0x09, 0x3e, 0x0a,\n\t0x19, 0x51, 0x9c, 0x43, 0x3b, 0xe5, 0x56, 0x5d, 0x1b, 0x3e, 0xbb, 0xc1, 0x85, 0x76, 0xd4, 0xb5,\n\t0xe1, 0xf3, 0xf0, 0xb0, 0x44, 0x97, 0xb5, 0xda, 0xd6, 0x0d, 0x5b, 0x45, 0xb6, 0xd3, 0x02, 0x80,\n\t0xbe, 0x9b, 0x56, 0x2f, 0x1f, 0x53, 0x29, 0x5e, 0x80, 0x23, 0xb5, 0x3d, 0xe3, 0xdf, 0x7a, 0xd7,\n\t0x5c, 0xe7, 0x13, 0x2c, 0x71, 0xe3, 0xab, 0x7e, 0x03, 0x88, 0x9e, 0x1d, 0x5e, 0x85, 0x0f, 0x25,\n\t0x07, 0xc3, 0xb2, 0x39, 0x2f, 0xed, 0xf3, 0x12, 0x60, 0x45, 0xaf, 0x3b, 0x9f, 0x76, 0x7f, 0x56,\n\t0x02, 0x48, 0xfc, 0xb9, 0x81, 0x7b, 0x93, 0xef, 0x4f, 0x67, 0x36, 0x7c, 0x66, 0x03, 0xde, 0x2f,\n\t0x15, 0xbe, 0x02, 0xfb, 0x04, 0x4c, 0x22, 0x59, 0xea, 0x5a, 0xe4, 0xb1, 0x50, 0xac, 0x95, 0xb7,\n\t0x38, 0x71, 0xa9, 0x7f, 0x47, 0x9f, 0xc8, 0x6a, 0x56, 0x30, 0xcb, 0x60, 0xc6, 0xeb, 0x91, 0x58,\n\t0xe2, 0x70, 0x28, 0x46, 0xaa, 0x20, 0x2b, 0x3b, 0x91, 0xf1, 0xf8, 0x6d, 0x1d, 0xfa, 0x4a, 0xcd,\n\t0x79, 0x35, 0x0a, 0x80, 0x1b, 0x2a, 0xb8, 0x38, 0xe2, 0x26, 0x51, 0xe0, 0x7c, 0xea, 0x50, 0xf9,\n\t0x9c, 0x1e, 0x8e, 0xa6, 0x5c, 0x8e, 0x43, 0xed, 0x5f, 0x40, 0x51, 0x19, 0x6d, 0x00, 0x78, 0x70,\n\t0x3e, 0x67, 0x33, 0x1c, 0x55, 0x9a, 0x03, 0x10, 0xaf, 0x3c, 0x96, 0x7b, 0x4d, 0xbd, 0x2c, 0x5c,\n\t0x9d, 0xf1, 0xc8, 0x1d, 0xdc, 0x10, 0xe4, 0x23, 0xc6, 0x65, 0x14, 0x62, 0x2f, 0xe1, 0x7f, 0x66,\n\t0x88, 0x6e, 0x3e, 0x89, 0xd4, 0x38, 0x57, 0x83, 0x4c, 0x76, 0xa2, 0xf6, 0x6f, 0x1a, 0x4e, 0xc4,\n\t0xc2, 0xc1, 0xd8, 0xe8, 0x70, 0x88, 0xfc, 0x44, 0x55, 0xed, 0x24, 0x5b, 0x9b, 0xe9, 0x83, 0x79,\n\t0xf8, 0x06, 0xc9, 0x04, 0xed, 0xf8, 0x7a, 0xc6, 0x29, 0x66, 0x3c, 0x4c, 0xfe, 0x96, 0x6f, 0xa2,\n\t0xad, 0x66, 0x30, 0xf4, 0xf9, 0x3d, 0x9b, 0xb2, 0x8b, 0x5e, 0xce, 0x42, 0xff, 0xba, 0x58, 0x58,\n\t0x3a, 0x64, 0x66, 0x19, 0x8f, 0xe2, 0xac, 0xc8, 0x38, 0x24, 0x21, 0x84, 0x24, 0xe8, 0x6c, 0x1b,\n\t0x0a, 0xc5, 0x52, 0xe0, 0xb3, 0xef, 0x73, 0xa7, 0x93, 0x19, 0x59, 0x2a, 0x1d, 0x6a, 0xe0, 0x4b,\n\t0xb9, 0x17, 0x94, 0x6c, 0xa3, 0x55, 0x57, 0x2d, 0x75, 0x2d, 0x06, 0x37, 0xe8, 0x75, 0xba, 0x47,\n\t0x95, 0x81, 0x5c, 0x4f, 0xee, 0x7e, 0x6b, 0x73, 0xbd, 0xb5, 0x82, 0x5c, 0x56, 0x53, 0x5a, 0x38,\n\t0x84, 0x1e, 0xb0, 0x28, 0x07, 0x94, 0xad, 0x98, 0x3c, 0x42, 0x79, 0x00, 0x37, 0xe1, 0xaf, 0x6e,\n\t0xe9, 0x11, 0x27, 0x2f, 0x26, 0xc7, 0xea, 0xb9, 0xdf, 0x81, 0xf9, 0xc2, 0xcf, 0xee, 0x81, 0xf6,\n\t0xe2, 0x67, 0x7a, 0x54, 0x78, 0x8b, 0x26, 0x0d, 0xf7, 0xab, 0x96, 0x40, 0xd5, 0x70, 0xe4, 0x1d,\n\t0xb9, 0xfc, 0xf8, 0x0d, 0xad, 0xd7, 0xb5, 0xf9, 0x11, 0x1d, 0x56, 0xdb, 0xf0, 0xb7, 0x1b, 0xb4,\n\t0x37, 0xf0, 0x6c, 0xf8, 0x35, 0xc1, 0xae, 0xe6, 0x84, 0x13, 0x71, 0x9f, 0xbf, 0x0e, 0x42, 0x86,\n\t0x57, 0x85, 0x71, 0xd5, 0xb6, 0x70, 0x74, 0xbc, 0xd6, 0x23, 0x75, 0x1c, 0x4f, 0xe3, 0xae, 0xa2,\n\t0x88, 0x1e, 0x50, 0x03, 0x32, 0xf1, 0x50, 0xf2, 0x68, 0x28, 0x95, 0x36, 0x7d, 0x11, 0x2b, 0x2c,\n\t0x0f, 0x85, 0x32, 0xb1, 0xb4, 0x84, 0x70, 0xf9, 0x37, 0x29, 0x11, 0x82, 0x7b, 0x30, 0x31, 0x32,\n\t0x1a, 0xe2, 0xb5, 0xc6, 0x6c, 0x0d, 0xea, 0x61, 0x4e, 0xa2, 0xff, 0x2a, 0xe0, 0x8d, 0xaf, 0x40,\n\t0x3e, 0x45, 0x1f, 0xd2, 0xc8, 0xd8, 0xde, 0x30, 0xb0, 0xb5, 0x5a, 0x15, 0x63, 0xe5, 0xae, 0xcb,\n\t0x28, 0x4c, 0xaf, 0xe0, 0x12, 0x3d, 0x82, 0xf0, 0x70, 0xdb, 0xc3, 0xfa, 0xce, 0x80, 0xff, 0x4f,\n\t0x5f, 0xcc, 0xff, 0x1b, 0x1c, 0x0a, 0xae, 0xab, 0x5d, 0x2d, 0x26, 0xea, 0x78, 0x38, 0x35, 0x96,\n\t0x88, 0x0d, 0x85, 0x06, 0xd3, 0x86, 0x77, 0xbd, 0xd1, 0xeb, 0x15, 0x45, 0x89, 0xc0, 0x99, 0x88,\n\t0xa5, 0x37, 0x84, 0xa9, 0xd2, 0x4c, 0xeb, 0xff, 0x02, 0x9a, 0x8e, 0x5c, 0x4a,\n\n};\n\nstatic const unsigned long compressed_size = 7229;\nstatic const unsigned long decompressed_size = 21817;\n\nttstr TVPGetCommandDesc()\n{\n\tunsigned char * dest = new unsigned char [decompressed_size + 1];\n\n\tttstr ret;\n\n\ttry\n\t{\n\t\tunsigned long dest_size = decompressed_size;\n\n\t\tint result = uncompress(dest, &dest_size,\n\t\t\t(unsigned char*)compressed_option_desc_string, compressed_size);\n\t\tif(result != Z_OK || dest_size != decompressed_size) { TVPThrowInternalError; }\n\n\t\tdest[decompressed_size] = 0;\n\n\t\tret = (const char *)dest;\n\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] dest;\n\t\tthrow;\n\t}\n\tdelete [] dest;\n\n\treturn ret;\n}\n\n"
  },
  {
    "path": "src/core/msg/win32/OptionsDesc.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n#ifndef OptionsDescH\n#define OptionsDescH\n\nextern ttstr TVPGetCommandDesc();\n\n#endif\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/msg/win32/ReadOptionDesc.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"picojson.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"resource.h\"\n#include \"CharacterSet.h\"\n#include \"ReadOptionDesc.h\"\n#include \"WindowsUtil.h\"\n\nclass OptionDescReader {\n\tstatic const char* CATEGORY;\n\tstatic const char* OPTIONS;\n\tstatic const char* CAPTION;\n\tstatic const char* DESCRIPTION;\n\tstatic const char* NAME;\n\tstatic const char* TYPE;\n\tstatic const char* LENGTH;\n\tstatic const char* VALUE;\n\tstatic const char* VALUES;\n\tstatic const char* DESC;\n\tstatic const char* DEFAULT;\n\tstatic const char* USER;\n\n\tstatic bool GetBoolean( const char* name, const picojson::object& obj ) {\n\t\tstd::map<std::string, picojson::value>::const_iterator v = obj.find(std::string(name));\n\t\tif( v != obj.end() ) {\n\t\t\tconst picojson::value& val = v->second;\n\t\t\tif( val.is<bool>() ) {\n\t\t\t\treturn val.get<bool>();\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\tstatic int GetInteger( const char* name, const picojson::object& obj ) {\n\t\tstd::map<std::string, picojson::value>::const_iterator v = obj.find(std::string(name));\n\t\tif( v != obj.end() ) {\n\t\t\tconst picojson::value& val = v->second;\n\t\t\tif( val.is<int>() ) {\n\t\t\t\treturn (int)val.get<double>();\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tstatic void RetriveString( std::wstring& out, const picojson::object& obj, const char* name ) {\n\t\tstd::map<std::string, picojson::value>::const_iterator v = obj.find(std::string(name));\n\t\tif( v != obj.end() ) {\n\t\t\tconst picojson::value& val = v->second;\n\t\t\tif( val.is<std::string>() ) {\n\t\t\t\tTVPUtf8ToUtf16( out,  val.get<std::string>() );\n\t\t\t} else if( val.is<double>() ) {\n\t\t\t\tint vi = (int)val.get<double>();\n\t\t\t\tout = std::to_wstring(vi);\n\t\t\t} else if( val.is<bool>() ) {\n\t\t\t\tbool b = val.get<bool>();\n\t\t\t\tif( b ) out = L\"true\";\n\t\t\t\telse out = L\"false\";\n\t\t\t}\n\t\t}\n\t}\n\tvoid ParseOption( tTVPCommandOption& opt, const picojson::object& option );\n\tvoid ParseValue( tTVPCommandOptionsValue& val, const picojson::object& value );\npublic:\n\ttTVPCommandOptionList* Parse( const picojson::value& v );\n};\n\nconst char* OptionDescReader::CATEGORY = \"category\";\nconst char* OptionDescReader::OPTIONS = \"options\";\nconst char* OptionDescReader::CAPTION = \"caption\";\nconst char* OptionDescReader::DESCRIPTION = \"description\";\nconst char* OptionDescReader::NAME = \"name\";\nconst char* OptionDescReader::TYPE = \"type\";\nconst char* OptionDescReader::LENGTH = \"length\";\nconst char* OptionDescReader::VALUE = \"value\";\nconst char* OptionDescReader::VALUES = \"values\";\nconst char* OptionDescReader::DESC = \"desc\";\nconst char* OptionDescReader::DEFAULT = \"default\";\nconst char* OptionDescReader::USER = \"user\";\n\nvoid OptionDescReader::ParseValue( tTVPCommandOptionsValue& val, const picojson::object& value ) {\n\tRetriveString( val.Value, value, VALUE );\n\tRetriveString( val.Description, value, DESC );\n\tval.IsDefault = GetBoolean( DEFAULT, value );\n}\nvoid OptionDescReader::ParseOption( tTVPCommandOption& opt, const picojson::object& option ) {\n\tRetriveString( opt.Caption, option, CAPTION );\n\tRetriveString( opt.Description, option, DESCRIPTION );\n\tRetriveString( opt.Name, option, NAME );\n\tstd::wstring type;\n\tRetriveString( type, option, TYPE );\n\topt.Length = 0;\n\tif( type == std::wstring(L\"select\") ) {\n\t\topt.Type = tTVPCommandOption::VT_Select;\n\t} else if( type == std::wstring(L\"string\") ) {\n\t\topt.Type = tTVPCommandOption::VT_String;\n\t\topt.Length = GetInteger( LENGTH, option );\n\t\tRetriveString( opt.Value, option, VALUE );\n\t} else {\n\t\topt.Type = tTVPCommandOption::VT_Unknown;\n\t}\n\topt.User = GetBoolean( USER, option );\n\tstd::map<std::string, picojson::value>::const_iterator v = option.find(std::string(VALUES));\n\tif( v != option.end() ) {\n\t\tconst picojson::value& val = v->second;\n\t\tif( val.is<picojson::array>() ) {\n\t\t\tconst picojson::array& values = val.get<picojson::array>();\n\t\t\tsize_t count = values.size();\n\t\t\topt.Values.resize( count );\n\t\t\tfor( size_t i = 0; i < count; i++ ) {\n\t\t\t\ttTVPCommandOptionsValue& value = opt.Values[i];\n\t\t\t\tconst picojson::value& jval = values[i];\n\t\t\t\tif( jval.is<picojson::object>() ) {\n\t\t\t\t\tParseValue( value, jval.get<picojson::object>() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\ntTVPCommandOptionList* OptionDescReader::Parse( const picojson::value& v ) {\n\ttTVPCommandOptionList* result = NULL;\n\tif( v.is<picojson::array>() ) {\n\t\tresult = new tTVPCommandOptionList();\n\t\tconst picojson::array& categories = v.get<picojson::array>();\n\t\tsize_t count = categories.size();\n\t\tresult->Categories.resize( count );\n\t\tfor( size_t i = 0; i < count; i++ ) {\n\t\t\ttTVPCommandOptionCategory& optioncat = result->Categories[i];\n\t\t\tconst picojson::value& category = categories[i];\n\t\t\tif( category.is<picojson::object>() ) {\n\t\t\t\tconst picojson::object& cat = category.get<picojson::object>();\n\t\t\t\tRetriveString( optioncat.Name, cat, CATEGORY );\n\n\t\t\t\tstd::map<std::string, picojson::value>::const_iterator opt = cat.find(OPTIONS);\n\t\t\t\tif( opt != cat.end() ) {\n\t\t\t\t\tconst picojson::value& options = opt->second;\n\t\t\t\t\tif( options.is<picojson::array>() ) {\n\t\t\t\t\t\tconst picojson::array& optionarray = options.get<picojson::array>();\n\t\t\t\t\t\tsize_t optcount = optionarray.size();\n\t\t\t\t\t\toptioncat.Options.resize( optcount );\n\t\t\t\t\t\tfor( size_t j = 0; j < optcount; j++ ) {\n\t\t\t\t\t\t\ttTVPCommandOption& toption = optioncat.Options[j];\n\t\t\t\t\t\t\tconst picojson::value& option = optionarray[j];\n\t\t\t\t\t\t\tif( option.is<picojson::object>() ) {\n\t\t\t\t\t\t\t\tParseOption( toption, option.get<picojson::object>() );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nbool TVPUtf8ToUtf16( std::wstring& out, const std::string& in ) {\n\ttjs_int len = TVPUtf8ToWideCharString( in.c_str(), NULL );\n\tif( len < 0 ) return false;\n\twchar_t* buf = new wchar_t[len];\n\tif( buf ) {\n\t\ttry {\n\t\t\tlen = TVPUtf8ToWideCharString( in.c_str(), buf );\n\t\t\tif( len > 0 ) out.assign( buf, len );\n\t\t\tdelete[] buf;\n\t\t} catch(...) {\n\t\t\tdelete[] buf;\n\t\t\tthrow;\n\t\t}\n\t}\n\treturn len > 0;\n}\nbool TVPUtf16ToUtf8( std::string& out, const std::wstring& in ) {\n\ttjs_int len = TVPWideCharToUtf8String( in.c_str(), NULL );\n\tif( len < 0 ) return false;\n\tchar* buf = new char[len];\n\tif( buf ) {\n\t\ttry {\n\t\t\tlen = TVPWideCharToUtf8String( in.c_str(), buf );\n\t\t\tif( len > 0 ) out.assign( buf, len );\n\t\t\tdelete[] buf;\n\t\t} catch(...) {\n\t\t\tdelete[] buf;\n\t\t\tthrow;\n\t\t}\n\t}\n\treturn len > 0;\n}\ntTVPCommandOptionList* ParseCommandDesc( const char *buf, unsigned int size ) {\n\tif( buf == NULL || size <= 0 ) return NULL;\n\n\tpicojson::value v;\n\tstd::string errorstr;\n\tpicojson::parse( v, buf, buf+size, &errorstr );\n\tif( errorstr.empty() != true ) {\n\t\tstd::wstring errmessage;\n\t\tif( TVPUtf8ToUtf16( errmessage, errorstr ) ) \t\n\t\t\tTVPAddImportantLog( errmessage.c_str() );\n\t\treturn NULL;\n\t}\n\tOptionDescReader reader;\n\ttTVPCommandOptionList* opt = reader.Parse( v );\n\treturn opt;\n}\nextern \"C\" {\nstatic BOOL CALLBACK EnumResTypeProc( HMODULE hModule, LPTSTR lpszType, LONG_PTR lParam ) {\n\tif( !IS_INTRESOURCE(lpszType) ) {\n\t\tOutputDebugString( lpszType );\n\t}\n\treturn TRUE;\n}\nstatic BOOL CALLBACK TVPEnumResNameProc( HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam ) {\n\tif( !IS_INTRESOURCE(lpszName) ) {\n\t\tOutputDebugString( lpszName );\n\t}\n\treturn TRUE;\n}\n};\ntTVPCommandOptionList* TVPGetPluginCommandDesc( const wchar_t* name ) {\n\tHMODULE hModule = ::LoadLibraryEx( name, NULL, LOAD_LIBRARY_AS_DATAFILE );\n\tif( hModule == NULL ) return NULL;\n\tconst char *buf = NULL;\n\tunsigned int size = 0;\n\ttTVPCommandOptionList* ret = NULL;\n\ttry {\n\t\t//BOOL typeret = ::EnumResourceTypes( hModule, (ENUMRESTYPEPROC)EnumResTypeProc,  NULL );\n\t\t//BOOL resret = ::EnumResourceNames( hModule, L\"TEXT\", (ENUMRESNAMEPROC)TVPEnumResNameProc, NULL );\n\n\t\tHRSRC hRsrc = ::FindResource(hModule, L\"IDR_OPTION_DESC_JSON\", L\"TEXT\" );\n\t\tif( hRsrc != NULL ) {\n\t\t\tsize = ::SizeofResource( hModule, hRsrc );\n\t\t\tHGLOBAL hGlobal = ::LoadResource( hModule, hRsrc );\n\t\t\tif( hGlobal != NULL ) {\n\t\t\t\tbuf = reinterpret_cast<const char*>(::LockResource(hGlobal));\n\t\t\t}\n\t\t}\n\t\tret = ParseCommandDesc( buf, size );\n\t} catch(...) {\n\t\t::FreeLibrary( hModule );\n\t\tthrow;\n\t}\n\t::FreeLibrary( hModule );\n\treturn ret;\n}\ntTVPCommandOptionList* TVPGetEngineCommandDesc() {\n\tHMODULE hModule = ::GetModuleHandle(NULL);\n\tif( hModule == NULL ) return NULL;\n\tconst char *buf = NULL;\n\tunsigned int size = 0;\n\tHRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(IDR_OPTION_DESC_JSON), TEXT(\"TEXT\"));\n\tif( hRsrc != NULL ) {\n\t\tsize = ::SizeofResource( hModule, hRsrc );\n\t\tHGLOBAL hGlobal = ::LoadResource( hModule, hRsrc );\n\t\tif( hGlobal != NULL ) {\n\t\t\tbuf = reinterpret_cast<const char*>(::LockResource(hGlobal));\n\t\t}\n\t}\n\treturn ParseCommandDesc( buf, size );\n}\n\nvoid TVPMargeCommandDesc( tTVPCommandOptionList& dest, const tTVPCommandOptionList& src ) {\n\ttjs_uint count = (tjs_uint)src.Categories.size();\n\tstd::vector<tjs_uint> addcat;\n\taddcat.reserve( count );\n\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\tconst tTVPCommandOptionCategory& srccat = src.Categories[i];\n\t\ttjs_uint dcnt = (tjs_uint)dest.Categories.size();\n\t\tbool found = false;\n\t\tfor( tjs_uint j = 0; j < dcnt; j++ ) {\n\t\t\ttTVPCommandOptionCategory& dstcat = dest.Categories[j];\n\t\t\tif( dstcat.Name == srccat.Name ) {\n\t\t\t\tfound = true;\n\t\t\t\ttjs_uint optcount = (tjs_uint)srccat.Options.size();\n\t\t\t\tdstcat.Options.reserve( dstcat.Options.size() + optcount );\n\t\t\t\tfor( tjs_uint k = 0; k < optcount; k++ ) {\n\t\t\t\t\tdstcat.Options.push_back( srccat.Options[k] );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif( found == false ) {\n\t\t\taddcat.push_back( i );\n\t\t}\n\t}\n\tfor( std::vector<tjs_uint>::const_iterator i = addcat.begin(); i != addcat.end(); i++ ) {\n\t\ttjs_uint idx = *i;\n\t\tdest.Categories.push_back( src.Categories[idx] );\n\t}\n}\n"
  },
  {
    "path": "src/core/msg/win32/ReadOptionDesc.h",
    "content": "\n#ifndef __READ_OPTION_DESC_H__\n#define __READ_OPTION_DESC_H__\n\nstruct tTVPCommandOptionsValue {\n\tstd::wstring Value;\n\tstd::wstring Description;\n\tbool IsDefault;\n};\nstruct tTVPCommandOption {\n\tenum ValueType {\n\t\tVT_Select,\n\t\tVT_String,\n\t\tVT_Unknown\n\t};\n\tstd::wstring Caption;\n\tstd::wstring Description;\n\tstd::wstring Name;\n\tValueType Type;\n\ttjs_int Length;\n\tstd::wstring Value;\n\tstd::vector<tTVPCommandOptionsValue> Values;\n\tbool User;\n};\nstruct tTVPCommandOptionCategory {\n\tstd::wstring Name;\n\tstd::vector<tTVPCommandOption> Options;\n};\nstruct tTVPCommandOptionList {\n\tstd::vector<tTVPCommandOptionCategory> Categories;\n};\n\nextern bool TVPUtf8ToUtf16( std::wstring& out, const std::string& in );\nextern bool TVPUtf16ToUtf8( std::string& out, const std::wstring& in );\nextern tTVPCommandOptionList* TVPGetPluginCommandDesc( const wchar_t* name );\nextern tTVPCommandOptionList* TVPGetEngineCommandDesc();\nvoid TVPMargeCommandDesc( tTVPCommandOptionList& dest, const tTVPCommandOptionList& src );\n\n#endif // __READ_OPTION_DESC_H__\n"
  },
  {
    "path": "src/core/sound/ARM/WaveFunctionARM.cpp",
    "content": ""
  },
  {
    "path": "src/core/sound/ARM/wavemix_arm.c",
    "content": "#include <arm_neon.h>\n#include \"cpu_types.h\"\n#include <assert.h>\n// #include \"Protect.h\"\n#include \"tjsTypes.h\"\n\nextern tjs_uint32 TVPCPUFeatures;\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nextern const int MAX_VOLUME;\ntypedef void(FAudioMix)(void *dst, const void *src, int samples, int16_t *volume);\nstatic FAudioMix* _VolumeMix_CPP_S16_CH2;\n\nstatic void VolumeMix_NEON_S16_CH2(void *dst, const void *src, int len, int16_t *vol) {\n\tint16_t *dst16 = (int16_t *)dst;\n\tconst int16_t *src16 = (const int16_t *)src;\n\n\tconst int addr_mask = ~(8 - 1);\n\tsigned short* pEndDst = dst16 + len * 2;\n\t// Pre Frag\n\t{\n\t\tint PreFragLen = ((int16_t*)((((intptr_t)dst16) + 7)&~7) - dst16) / 4;\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\t_VolumeMix_CPP_S16_CH2(dst16, src16, PreFragLen, vol);\n\t\t\tdst16 += PreFragLen * 2;\n\t\t\tsrc16 += PreFragLen * 2;\n\t\t}\n\t}\n\n\tint16_t* pVecEndDst = (int16_t*)(((intptr_t)pEndDst)&addr_mask) - 7;\n\tint16x4_t volume = vld1_s16(vol);\n\tint16x4_t sign_mask = vdup_n_s16(0x8000);\n\n\twhile (dst16 < pVecEndDst) {\n\t\tint16x4_t src_sample = vld1_s16(src16);\n\t\tint16x4_t dest_sample = vld1_s16(dst16);\n\t\tint16x4_t src_sign = vreinterpret_s16_u16(vtst_s16(src_sample, sign_mask));\n\t\tint16x4_t dst_sign = vreinterpret_s16_u16(vtst_s16(dest_sample, sign_mask));\n\t\tint16x4_t src_sign_n = vmvn_s16(src_sign);\n\t\tsrc_sample = vshrn_n_s32(vmull_s16(src_sample, volume), 14);\n\t\tint16x4_t error = vshrn_n_s32(vmull_s16(src_sample, dest_sample), 15);\n\t\tint16x4_t same_sign = veor_s16(src_sign_n, dst_sign); // -1 = same sign\n\t\terror = vand_s16(error, same_sign);\n\t\tint16x4_t errneg = vneg_s16(error);\n\t\terrneg = vand_s16(errneg, src_sign);\n\t\terror = vand_s16(error, src_sign_n);\n\t\tint16x4_t result = vadd_s16(src_sample, dest_sample);\n\t\tresult = vadd_s16(result, error);\n\t\tresult = vadd_s16(result, errneg);\n\t\tvst1_s16(dst16, result);\n\t\tsrc16 += 4;\n\t\tdst16 += 4;\n\t}\n\n\tif (dst16 < pEndDst) {\n\t\t_VolumeMix_CPP_S16_CH2(dst16, src16, (pEndDst - dst16) / 2, vol);\n\t}\n}\n\nstatic FAudioMix* _VolumeMix_CPP_F32_CH2;\nstatic void VolumeMix_NEON_F32_CH2(void *dst, const void *src, int len, int16_t *vol) {\n\tfloat *dst32 = (float *)dst;\n\tconst float *src32 = (const float *)src;\n\tconst int addr_mask = ~(16 - 1);\n\tfloat* pEndDst = dst32 + len;\n\t// Pre Frag\n\t{\n\t\tint PreFragLen = ((float*)((((int)dst32) + 15)&~15) - dst32) / 8;\n\t\tif (PreFragLen > len) PreFragLen = len / 2;\n\t\tif (PreFragLen) {\n\t\t\t_VolumeMix_CPP_S16_CH2(dst32, src32, PreFragLen, vol);\n\t\t\tdst32 += PreFragLen * 2;\n\t\t\tsrc32 += PreFragLen * 2;\n\t\t}\n\t}\n\n\tfloat* pVecEndDst = (float*)(((int)pEndDst)&addr_mask) - 15;\n\tfloat32x4_t volume = vcvtq_f32_s32(vmovl_s16(vld1_s16(vol)));\n\tint32x4_t sign_mask = vdupq_n_s32((int32_t)0x80000000);\n\n\twhile (dst32 < pVecEndDst) {\n\t\tfloat32x4_t src_sample = vmulq_f32(vld1q_f32(src32), volume);\n\t\tfloat32x4_t dest_sample = vld1q_f32(dst32);\n\t\tint32x4_t src_sign = vreinterpretq_s32_u32(vtstq_s32(vreinterpretq_s32_f32(src_sample), sign_mask));\n\t\tint32x4_t dst_sign = vreinterpretq_s32_u32(vtstq_s32(vreinterpretq_s32_f32(dest_sample), sign_mask));\n\t\tfloat32x4_t error = vmulq_f32(src_sample, dest_sample);\n\t\tfloat32x4_t result = vaddq_f32(src_sample, dest_sample);\n\t\tresult = vsubq_f32(result, error);\n\t\tvst1q_f32(dst32, result);\n\t\tsrc32 += 4;\n\t\tdst32 += 4;\n\t}\n\n\tif (dst32 < pEndDst) {\n\t\t_VolumeMix_CPP_F32_CH2(dst32, src32, (pEndDst - dst32) / 2, vol);\n\t}\n}\n\nvoid TVPWaveMixer_ASM_Init(FAudioMix **func16, FAudioMix **func32)\n{\n\tif ((TVPCPUFeatures & TVP_CPU_FAMILY_MASK) == TVP_CPU_FAMILY_ARM && (TVPCPUFeatures & TVP_CPU_HAS_NEON)) {\n\t\t_VolumeMix_CPP_S16_CH2 = func16[1];\n\t\t_VolumeMix_CPP_F32_CH2 = func32[1];\n\t\tfunc16[1] = VolumeMix_NEON_S16_CH2;\n#if defined( DEBUG_ARM_NEON) && 1\n\t\tstatic const signed short testsrc_s16[12] = {\n\t\t\t-1,0,0x7FFF,-0x8000,\n\t\t\t0x7000, 0x7000, -0x7000, -0x7000,\n\t\t};\n\t\tstatic const signed short testdest_s16_c[12] = {\n\t\t\t-1,0,0x7FFF,-0x8000,\n\t\t\t0x7000, -0x7000, -0x7000, 0x7000,\n\t\t};\n\n\t\tsigned short testdest_s16_1[12];\n\t\tshort vol16[] = { 16384 , 16384 , 16384 , 16384 };\n\t\tmemcpy(testdest_s16_1, testdest_s16_c, sizeof(testdest_s16_c));\n\t\t_VolumeMix_CPP_S16_CH2(testdest_s16_1, testsrc_s16, 4, vol16);\n\t\tsigned short testdest_s16_2[12];\n\t\tmemcpy(testdest_s16_2, testdest_s16_c, sizeof(testdest_s16_c));\n\t\tVolumeMix_NEON_S16_CH2(testdest_s16_2, testsrc_s16, 4, vol16);\n\t\tassert(!memcmp(testdest_s16_1, testdest_s16_2, sizeof(testdest_s16_1)));\n\n\t\tstatic const float testsrc_f32[12] = {\n\t\t\t0,0,0,0,\n\t\t\t0.99, 0.99, -0.99, -0.99,\n\t\t};\n\t\tstatic const float testdest_f32_c[12] = {\n\t\t\t0,0,0,0,\n\t\t\t0.99, -0.99, -0.99, 0.99,\n\t\t};\n\n\t\tfloat testdest_f32_1[12];\n\t\tmemcpy(testdest_f32_1, testdest_f32_c, sizeof(testdest_f32_c));\n\t\t_VolumeMix_CPP_F32_CH2(testdest_f32_1, testsrc_f32, 4, vol16);\n\t\tfloat testdest_f32_2[12];\n\t\tmemcpy(testdest_f32_2, testdest_f32_c, sizeof(testdest_f32_c));\n\t\tVolumeMix_NEON_F32_CH2(testdest_f32_2, testsrc_f32, 4, vol16);\n\t\tassert(!memcmp(testdest_f32_1, testdest_f32_2, sizeof(testdest_f32_1)));\n#endif\n\t\t//VolumeMix = VolumeMix_NEON;\n\t}\n}\n#ifdef __cplusplus\n}\n#endif"
  },
  {
    "path": "src/core/sound/CDDAIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CD-DA access interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"CDDAIntf.h\"\n#include \"EventIntf.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseCDDASoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_BaseCDDASoundBuffer::tTJSNI_BaseCDDASoundBuffer()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BaseCDDASoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseCDDASoundBuffer::Invalidate()\n{\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_CDDASoundBuffer : TJS CDDASoundBuffer class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_CDDASoundBuffer::ClassID = -1;\ntTJSNC_CDDASoundBuffer::tTJSNC_CDDASoundBuffer()  :\n\ttTJSNativeClass(TJS_W(\"CDDASoundBuffer\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(CDDASoundBuffer) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this,\n\t/*var.type*/tTJSNI_CDDASoundBuffer,\n\t/*TJS class name*/CDDASoundBuffer)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/CDDASoundBuffer)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/open)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n#ifdef ENABLE_CDDA\n\t_this->Open(*param[0]);\n#endif\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/open)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/play)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n#ifdef ENABLE_CDDA\n\n\t_this->Play();\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/play)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n    _this->Stop();\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n#ifdef ENABLE_CDDA\n    tjs_int to;\n\ttjs_int time;\n\ttjs_int delay = 0;\n\tto = (tjs_int)(*param[0]);\n\ttime = (tjs_int)(*param[1]);\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tdelay = (tjs_int)(*param[2]);\n\n\t_this->Fade(to, time, delay);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fade)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n    _this->StopFade(false, true);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onStatusChanged\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"status\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_CDDASoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onFadeCompleted\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(position)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(position)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(paused)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(paused)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(totalTime)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(totalTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(looping)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        *result = _this->GetLooping();\n#endif\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        _this->SetLooping(*param);\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(looping)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        *result = _this->GetVolume();\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        _this->SetVolume(*param);\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        *result = _this->GetVolume2();\n#else\n        *result = 0;\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n#ifdef ENABLE_CDDA\n        _this->SetVolume2(*param);\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(status)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_CDDASoundBuffer);\n\n        *result = _this->GetStatusString();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(status)\n//---------------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n//----------------------------------------------------------------------\n\n\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/CDDAIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CD-DA access interface\n//---------------------------------------------------------------------------\n#ifndef CDDAIntfH\n#define CDDAIntfH\n\n#include \"tjsNative.h\"\n#include \"SoundBufferBaseIntf.h\"\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseCDDASoundBuffer\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseCDDASoundBuffer : public tTJSNI_SoundBuffer\n{\n\ttypedef tTJSNI_SoundBuffer inherited;\n\npublic:\n\ttTJSNI_BaseCDDASoundBuffer();\n\ttjs_error TJS_INTF_METHOD\n\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\npublic:\n};\n//---------------------------------------------------------------------------\n\n#include \"CDDAImpl.h\" // must define tTJSNI_CDDASoundBuffer class\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_CDDASoundBuffer : TJS CDDASoundBuffer class\n//---------------------------------------------------------------------------\nclass tTJSNC_CDDASoundBuffer : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_CDDASoundBuffer();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_CDDASoundBuffer();\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/sound/FFWaveDecoder.cpp",
    "content": "#include \"FFWaveDecoder.h\"\n#include \"WaveIntf.h\"\n#include \"StorageIntf.h\"\n#include \"DebugIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"BinaryStream.h\"\nextern \"C\" {\n#ifndef __STDC_CONSTANT_MACROS\n#define __STDC_CONSTANT_MACROS\n#endif\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS\n#endif\n#ifndef UINT64_C\n#define UINT64_C(x)  (x ## ULL)\n#endif\n#include \"libavutil/avutil.h\"\n#include \"libavutil/opt.h\"\n#include \"libavcodec/avcodec.h\"\n#include \"libavformat/avformat.h\"\n};\n\nclass FFWaveDecoder : public tTVPWaveDecoder // decoder interface\n{\n    bool IsPlanar;\n\n    int StreamIdx;\n    int audio_buf_index;\n    int audio_buf_samples;\n    int64_t audio_frame_next_pts;\n    int64_t stream_start_time;\n    tTVPWaveFormat Format; // output PCM format\n    AVSampleFormat AVFmt;\n    AVPacket pkt_temp;\n    AVStream *AudioStream;\n\n    // release in Clear()\n    AVPacket Packet;\n    tTJSBinaryStream *InputStream; // input stream\n    AVFormatContext *FormatCtx;\n    AVFrame *frame;\n\n    int audio_decode_frame();\n    void Clear() {\n        if (Packet.data)\n\t\t\tav_packet_unref(&Packet);\n        if(frame) av_frame_free(&frame), frame = nullptr;\n\t\tif (FormatCtx) {\n\t\t\tfor (unsigned int i = 0; i < FormatCtx->nb_streams; ++i) {\n\t\t\t\tavcodec_close(FormatCtx->streams[i]->codec);\n\t\t\t}\n\t\t\tav_free(FormatCtx->pb->buffer);\n\t\t\tav_free(FormatCtx->pb);\n\t\t\tavformat_close_input(&FormatCtx), FormatCtx = nullptr;\n\t\t}\n        if(InputStream) delete InputStream, InputStream = nullptr;\n    }\n    bool ReadPacket();\n\npublic:\n    FFWaveDecoder()\n        : InputStream(nullptr)\n        , FormatCtx(nullptr)\n        , frame(nullptr)\n    {\n        memset(&Packet, 0, sizeof(Packet));\n    }\n    ~FFWaveDecoder() {\n        Clear();\n    }\n\npublic:\n    // ITSSWaveDecoder\n    virtual void GetFormat(tTVPWaveFormat & format) { format = Format; }\n    virtual bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered);\n    virtual bool SetPosition(tjs_uint64 samplepos);\n\n    // others\n    bool SetStream(const ttstr & storagename);\n};\n\nstatic int AVReadFunc(void *opaque, uint8_t *buf, int buf_size)\n{\n    TJS::tTJSBinaryStream *stream = (TJS::tTJSBinaryStream *)opaque;\n    return stream->Read(buf, buf_size);\n}\n\nstatic int64_t AVSeekFunc(void *opaque, int64_t offset, int whence)\n{\n    TJS::tTJSBinaryStream *stream = (TJS::tTJSBinaryStream *)opaque;\n    switch (whence)\n    {\n    case AVSEEK_SIZE:\n        return stream->GetSize();\n    default:\n        return stream->Seek(offset, whence & 0xFF);\n    }\n}\nvoid TVPInitLibAVCodec();\ntTVPWaveDecoder * FFWaveDecoderCreator::Create(const ttstr & storagename, const ttstr & extension) {\n\tTVPInitLibAVCodec();\n\n    FFWaveDecoder * decoder = new FFWaveDecoder();\n    if(!decoder->SetStream(storagename)) {\n        delete decoder;\n        decoder = nullptr;\n    }\n    return decoder;\n}\n\ntemplate <typename T>\nstatic unsigned char* _CopySmaples(unsigned char *dst, AVFrame *frame, int samples, int buf_index)\n{\n    int buf_pos = buf_index * sizeof(T);\n    T* pDst = (T*)dst;\n    for(int i = 0; i < samples; ++i, buf_pos += sizeof(T)) {\n        for(int j = 0; j < frame->channels; ++j) {\n            *pDst++ = *(T*)(frame->data[j] + buf_pos);\n        }\n    }\n    return (unsigned char*)pDst;\n}\n\n// optimized for stereo\ntemplate <typename T>\nstatic unsigned char* _CopySmaples2(unsigned char *dst, AVFrame *frame, int samples, int buf_index)\n{\n    int buf_pos = buf_index * sizeof(T);\n    T* pDst = (T*)dst;\n    for(int i = 0; i < samples; ++i, buf_pos += sizeof(T)) {\n        *pDst++ = *(T*)(frame->data[0] + buf_pos);\n        *pDst++ = *(T*)(frame->data[1] + buf_pos);\n    }\n    return (unsigned char*)pDst;\n}\n\nstatic unsigned char* CopySmaples(unsigned char *dst, AVFrame *frame, int samples, int buf_index)\n{\n    switch(frame->format) {\n    case AV_SAMPLE_FMT_FLTP:\n    case AV_SAMPLE_FMT_S32P:\n        if(frame->channels == 2)\n            return _CopySmaples2<tjs_uint32>(dst, frame, samples, buf_index);\n        else\n\t\t\treturn _CopySmaples<tjs_uint32>(dst, frame, samples, buf_index);\n        break;\n    case AV_SAMPLE_FMT_S16P:\n        if(frame->channels == 2)\n\t\t\treturn _CopySmaples2<tjs_uint16>(dst, frame, samples, buf_index);\n        else\n\t\t\treturn _CopySmaples<tjs_uint16>(dst, frame, samples, buf_index);\n        break;\n    }\n    return nullptr;\n}\n\nbool FFWaveDecoder::Render( void *buf, tjs_uint bufsamplelen, tjs_uint& rendered )\n{\n\t// render output PCM\n    if(!InputStream) return false; // InputFile is yet not inited\n    int remain = bufsamplelen; // remaining PCM (in sample)\n    int sample_size = av_samples_get_buffer_size(NULL, Format.Channels, 1, AVFmt, 1);\n    unsigned char *stream = (unsigned char*)buf;\n    while(remain)\n    {\n        if (audio_buf_index >= audio_buf_samples) {\n            int decoded_samples = audio_decode_frame();\n            if (decoded_samples < 0) {\n                break;\n            }\n            audio_buf_samples = decoded_samples;\n            audio_buf_index = 0;\n        }\n        int samples = audio_buf_samples - audio_buf_index;\n        if (samples > remain)\n            samples = remain;\n\n        if(!IsPlanar || Format.Channels == 1) {\n            memcpy(stream, (frame->data[0] + audio_buf_index * sample_size), samples * sample_size);\n            stream += samples * sample_size;\n        } else {\n            stream = CopySmaples(stream, frame, samples, audio_buf_index);\n        }\n        remain -= samples;\n        audio_buf_index += samples;\n    }\n\n    rendered = bufsamplelen - remain; // return rendered PCM samples\n\n    return !remain; //if the decoding is ended\n}\n\nbool FFWaveDecoder::SetPosition( tjs_uint64 samplepos )\n{\n    // set PCM position (seek)\n    if(!InputStream) return false;\n    if(samplepos && !Format.Seekable) return false;\n\n\tint64_t seek_target = samplepos / av_q2d(AudioStream->time_base) / Format.SamplesPerSec;\n\tif (AudioStream->start_time != AV_NOPTS_VALUE) {\n\t\tseek_target += AudioStream->start_time;\n\t}\n    if (Packet.duration <= 0) {\n        if (Packet.data)\n            av_free_packet(&Packet);\n        if(!ReadPacket()) {\n            int ret = avformat_seek_file(FormatCtx, StreamIdx, 0, 0, 0, AVSEEK_FLAG_BACKWARD);\n            if(ret < 0) return false;\n            if(!ReadPacket()) return false;\n        }\n    }\n    int64_t seek_temp = seek_target - Packet.duration;\n    for(; ; ) {\n        if(seek_temp < 0) seek_temp = 0;\n        int ret = avformat_seek_file(FormatCtx, StreamIdx, seek_temp, seek_temp, seek_temp, AVSEEK_FLAG_BACKWARD);\n        if(ret < 0) return false;\n        if (Packet.data)\n            av_free_packet(&Packet);\n        if(!ReadPacket()) return false;\n        if(seek_target < Packet.dts) {\n            seek_temp -= Packet.duration;\n            continue;\n        }\n        pkt_temp = Packet;\n        do {\n            audio_buf_samples = audio_decode_frame();\n            if (audio_buf_samples < 0) {\n                return false;\n            }\n\t\t} while (samplepos > audio_frame_next_pts);\n\t\taudio_buf_index = (samplepos - frame->pts) /*/ av_q2d(AudioStream->time_base) / Format.SamplesPerSec*/;\n        if(audio_buf_index < 0) audio_buf_index = 0;\n        return true;\n    }\n    return false;\n}\n\nbool FFWaveDecoder::SetStream( const ttstr & url )\n{\n    Clear();\n    InputStream = TVPCreateBinaryStreamForRead(url, TJS_W(\"\"));\n    if(!InputStream) return false;\n    int bufSize = 32 * 1024;\n    AVIOContext *pIOCtx = avio_alloc_context(\n        (unsigned char *)av_malloc(bufSize + AVPROBE_PADDING_SIZE),\n        bufSize,  // internal Buffer and its size\n        0,                  // bWriteable (1=true,0=false) \n        InputStream,        // user data ; will be passed to our callback functions\n        AVReadFunc, \n        0,                  // Write callback function (not used in this example) \n        AVSeekFunc);\n\n    AVInputFormat *fmt = NULL;\n    tTJSNarrowStringHolder holder(url.c_str());\n    av_probe_input_buffer2(pIOCtx, &fmt, holder, NULL, 0, 0);\n    AVFormatContext *ic = FormatCtx = avformat_alloc_context();\n    ic->pb = pIOCtx;\n\tif (avformat_open_input(&ic, \"\", fmt, nullptr) < 0) {\n        FormatCtx = nullptr;\n        return false;\n    }\n    if (avformat_find_stream_info(ic, nullptr) < 0) {\n        return false;\n    }\n\n    if (ic->pb)\n        ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end\n\n    float max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;\n\n    StreamIdx = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);\n\n    if(StreamIdx < 0) {\n        return false;\n    }\n    \n    AVCodecContext *avctx = ic->streams[StreamIdx]->codec;\n    if(avctx->codec_type != AVMEDIA_TYPE_AUDIO) {\n        return false;\n    }\n\n    AVCodec *codec = avcodec_find_decoder(avctx->codec_id);\n    if (!codec) {\n        return false;\n    }\n\n    avctx->codec_id = codec->id;\n    avctx->workaround_bugs = /*workaround_bugs*/1;\n    avctx->error_concealment = 3;\n    if (codec->capabilities & CODEC_CAP_DR1)\n        avctx->flags |= CODEC_FLAG_EMU_EDGE;\n\n    if (avcodec_open2(avctx, codec, nullptr) < 0)\n    {\n        return false;\n    }\n\n    Format.SamplesPerSec = avctx->sample_rate;\n    Format.Channels = avctx->channels;\n    Format.Seekable = \n\t\t(FormatCtx->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK))\n\t\t!= (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK);\n\tFormat.IsFloat = false;\n// \tFormat.BigEndian = false;\n// \tFormat.Signed = true;\n\tswitch (AVFmt = avctx->sample_fmt) {\n    case AV_SAMPLE_FMT_S16P:\n    case AV_SAMPLE_FMT_S16:\n        Format.BitsPerSample = 16;\n        break;\n    case AV_SAMPLE_FMT_FLTP:\n    case AV_SAMPLE_FMT_FLT:\n        Format.BitsPerSample = 32;\n\t\tFormat.IsFloat = true;\n        break;\n    case AV_SAMPLE_FMT_S32P:\n    case AV_SAMPLE_FMT_S32:\n        Format.BitsPerSample = 32;\n        break;\n    default:\n        return false;\n    }\n    IsPlanar = false;\n    if( AVFmt == AV_SAMPLE_FMT_S16P ||\n        AVFmt == AV_SAMPLE_FMT_FLTP ||\n        AVFmt == AV_SAMPLE_FMT_S32P )\n        IsPlanar = true;\n    Format.BytesPerSample = Format.BitsPerSample / 8;\n    Format.IsFloat = AVFmt == AV_SAMPLE_FMT_FLTP;\n    Format.SpeakerConfig = 0;\n    AudioStream = FormatCtx->streams[StreamIdx];\n    Format.TotalTime = av_q2d(AudioStream->time_base) * AudioStream->duration * 1000;\n    Format.TotalSamples = av_q2d(AudioStream->time_base) * AudioStream->duration * Format.SamplesPerSec;\n\n    audio_buf_index = 0;\n    audio_buf_samples = 0;\n    audio_frame_next_pts = 0;\n    pkt_temp.stream_index = -1;\n\n    return true;\n}\n\nint FFWaveDecoder::audio_decode_frame() {\n    AVStream *audio_st = AudioStream;\n    AVCodecContext *dec = audio_st->codec;\n    for (;;) {\n        /* NOTE: the audio packet can contain several frames */\n        while (pkt_temp.stream_index != -1) {\n            if(!frame) {\n                frame = av_frame_alloc();\n            } else {\n                av_frame_unref(frame);\n            }\n\n            int got_frame;\n            int len1 = avcodec_decode_audio4(dec, frame, &got_frame, &pkt_temp);\n            if(len1 < 0) {\n                /* if error, we skip the frame */\n                pkt_temp.size = 0;\n                break;\n            }\n            pkt_temp.dts = pkt_temp.pts = AV_NOPTS_VALUE;\n            pkt_temp.data += len1;\n            pkt_temp.size -= len1;\n            if ((pkt_temp.data && pkt_temp.size <= 0) || (!pkt_temp.data && !got_frame))\n                pkt_temp.stream_index = -1;\n            if (!pkt_temp.data && !got_frame)\n                ; //is->audio_finished = is->audio_pkt_temp_serial;\n\n            if (!got_frame)\n                continue;\n\n            AVRational tb = {1, frame->sample_rate};\n\n            if (frame->pts != AV_NOPTS_VALUE)\n                frame->pts = av_rescale_q(frame->pts, dec->time_base, tb);\n            else if (frame->pkt_pts != AV_NOPTS_VALUE)\n                frame->pts = av_rescale_q(frame->pkt_pts, audio_st->time_base, tb);\n            else if (audio_frame_next_pts != AV_NOPTS_VALUE) {\n                AVRational a = { 1, (int)Format.SamplesPerSec };\n                frame->pts = av_rescale_q(audio_frame_next_pts, a, tb);\n            }\n\n            if (frame->pts != AV_NOPTS_VALUE)\n                audio_frame_next_pts = frame->pts + frame->nb_samples;\n\n//             int data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(frame),\n//                 frame->nb_samples, (AVSampleFormat)frame->format, 1);\n\n            int wanted_nb_samples = frame->nb_samples;\n\n            return frame->nb_samples;\n        }\n\n        /* free the current packet */\n        if (Packet.data)\n            av_free_packet(&Packet);\n\n        pkt_temp.stream_index = -1;\n\n        /* read next packet */\n        if(!ReadPacket()) return -1;\n        //packet_queue_get(&is->audioq, Packet, 1, &is->audio_pkt_temp_serial);\n        \n        pkt_temp = Packet;\n    }\n    return -1;\n}\n\nbool FFWaveDecoder::ReadPacket() {\n    for(;;) {\n        int ret = av_read_frame(FormatCtx, &Packet);\n        if (ret < 0) {\n            return false;\n        }\n        if(Packet.stream_index == StreamIdx) {\n            stream_start_time = AudioStream->start_time;\n            return true;\n        }\n        av_free_packet(&Packet);\n    }\n    return false;\n}\n"
  },
  {
    "path": "src/core/sound/FFWaveDecoder.h",
    "content": "#pragma once\n#include \"WaveIntf.h\"\n\nclass FFWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n    //VorbisWaveDecoderCreator() { TVPRegisterWaveDecoderCreator(this); }\n    tTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension);\n};\n"
  },
  {
    "path": "src/core/sound/MIDIIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// MIDI sequencer interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"MIDIIntf.h\"\n#include \"EventIntf.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseMIDISoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_BaseMIDISoundBuffer::tTJSNI_BaseMIDISoundBuffer()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BaseMIDISoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseMIDISoundBuffer::Invalidate()\n{\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_MIDISoundBuffer : TJS MIDISoundBuffer class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_MIDISoundBuffer::ClassID = -1;\ntTJSNC_MIDISoundBuffer::tTJSNC_MIDISoundBuffer()  :\n\ttTJSNativeClass(TJS_W(\"MIDISoundBuffer\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(MIDISoundBuffer) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this,\n\t/*var.type*/tTJSNI_MIDISoundBuffer,\n\t/*TJS class name*/MIDISoundBuffer)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/MIDISoundBuffer)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/open)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n#ifdef TVP_ENABLE_MIDI\n    _this->Open(*param[0]);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/open)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/play)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n    _this->Play();\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/play)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n    _this->Stop();\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n#ifdef TVP_ENABLE_MIDI\n\n\ttjs_int to;\n\ttjs_int time;\n\ttjs_int delay = 0;\n\tto = (tjs_int)(*param[0]);\n\ttime = (tjs_int)(*param[1]);\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tdelay = (tjs_int)(*param[2]);\n\n\t_this->Fade(to, time, delay);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fade)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n    _this->StopFade(false, true);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onStatusChanged\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"status\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MIDISoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onFadeCompleted\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(position)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(position)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(paused)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(paused)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(totalTime)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(totalTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(looping)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n        *result = _this->GetLooping();\n#endif\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n        _this->SetLooping(*param);\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(looping)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t*result = _this->GetVolume();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t_this->SetVolume(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n        *result = _this->GetVolume2();\n#else\n        *result = 0;\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n#ifdef TVP_ENABLE_MIDI\n        _this->SetVolume2(*param);\n#endif\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(status)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MIDISoundBuffer);\n\n\t\t*result = _this->GetStatusString();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(status)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n//----------------------------------------------------------------------\n\n\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/MIDIIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// MIDI sequencer interface\n//---------------------------------------------------------------------------\n#ifndef MIDIIntfH\n#define MIDIIntfH\n\n\n#include \"tjsNative.h\"\n#include \"SoundBufferBaseIntf.h\"\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseMIDISoundBuffer\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseMIDISoundBuffer : public tTJSNI_SoundBuffer\n{\n\ttypedef tTJSNI_SoundBuffer inherited;\n\npublic:\n\ttTJSNI_BaseMIDISoundBuffer();\n\ttjs_error TJS_INTF_METHOD\n\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\npublic:\n};\n//---------------------------------------------------------------------------\n\n#include \"MIDIImpl.h\" // must define tTJSNI_MIDISoundBuffer class\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_MIDISoundBuffer : TJS MIDISoundBuffer class\n//---------------------------------------------------------------------------\nclass tTJSNC_MIDISoundBuffer : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_MIDISoundBuffer();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_MIDISoundBuffer();\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/sound/MathAlgorithms.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief w֐Q\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n#include <stdlib.h>\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid DeinterleaveApplyingWindow(float * __restrict dest[], const float * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t destofs, size_t len)\n{\n\tsize_t n;\n\tswitch(numch)\n\t{\n\tcase 1: // mono\n\t\t{\n\t\t\tfloat * dest0 = dest[0] + destofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest0[n] = src[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase 2: // stereo\n\t\t{\n\t\t\tfloat * dest0 = dest[0] + destofs;\n\t\t\tfloat * dest1 = dest[1] + destofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest0[n] = src[n*2 + 0] * win[n];\n\t\t\t\tdest1[n] = src[n*2 + 1] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tdefault: // generic\n\t\tfor(n = 0; n < len; n++)\n\t\t{\n\t\t\tfor(int ch = 0; ch < numch; ch++)\n\t\t\t{\n\t\t\t\tdest[ch][n + destofs] = *src * win[n];\n\t\t\t\tsrc ++;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nvoid  InterleaveOverlappingWindow(float * __restrict dest,\n\tconst float * __restrict const * __restrict src,\n\tfloat * __restrict win, int numch, size_t srcofs, size_t len)\n{\n\tsize_t n;\n\tswitch(numch)\n\t{\n\tcase 1: // mono\n\t\t{\n\t\t\tconst float * src0 = src[0] + srcofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest[n] += src0[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase 2: // stereo\n\t\t{\n\t\t\tconst float * src0 = src[0] + srcofs;\n\t\t\tconst float * src1 = src[1] + srcofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest[n*2 + 0] += src0[n] * win[n];\n\t\t\t\tdest[n*2 + 1] += src1[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tdefault: // generic\n\t\tfor(n = 0; n < len; n++)\n\t\t{\n\t\t\tfor(int ch = 0; ch < numch; ch++)\n\t\t\t{\n\t\t\t\t*dest += src[ch][n + srcofs] * win[n];\n\t\t\t\tdest ++;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/MathAlgorithms.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief w֐Q\n//---------------------------------------------------------------------------\n\n#ifndef TVP_MATHALGOLITHMS_H\n#define TVP_MATHALGOLITHMS_H\n\n#define _USE_MATH_DEFINES\n#include <math.h>\n#include \"xmmlib.h\"\n\n\n//---------------------------------------------------------------------------\n\n// \n\n//---------------------------------------------------------------------------\n/**\n * atan2 ̍ (1x float, C)\n * @note\tx͂܂ǂȂB10bit炢B @r\n *\t\t\tT: http://www.dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm\n */\nstatic inline float VFast_arctan2(float y, float x)\n{\n   static const float coeff_1 = (float)(M_PI/4);\n   static const float coeff_2 = 3*coeff_1;\n   float angle;\n   float abs_y = fabs(y)+(float)1e-10;     // kludge to prevent 0/0 condition\n   if (x>=0)\n   {\n      float r = (x - abs_y) / (x + abs_y);\n      angle = coeff_1 - coeff_1 * r;\n   }\n   else\n   {\n      float r = (x + abs_y) / (abs_y - x);\n      angle = coeff_2 - coeff_1 * r;\n   }\n   if (y < 0)\n     return(-angle);     // negate if in quad III or IV\n   else\n     return(angle);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic inline float VFast_atan2_madd(float a, float b, float c) { return a*b+c; }\nstatic inline float VFast_atan2_nmsub(float a, float b, float c) { return -(a*b-c); }\nstatic inline float VFast_atan2_round(float a) { return (float)((a>0)?(int)(a+0.5):(int)(a-0.5)); }\n\n/**\n * sincos ̍ (1x float, C)\n * @note\tT: http://arxiv.org/PS_cache/cs/pdf/0406/0406049.pdf\n */\nstatic inline void VFast_sincos(float v, float &sin, float &cos)\n{\n\tconst float  ss1 =  1.5707963235f  ;\n\tconst float  ss2 =  -0.645963615f  ;\n\tconst float  ss3 =  0.0796819754f  ;\n\tconst float  ss4 =  -0.0046075748f ;\n\tconst float  cc1 =  -1.2336977925f ;\n\tconst float  cc2 =  0.2536086171f  ;\n\tconst float  cc3 =  -0.0204391631f ;\n\n\tfloat s1, s2, c1, c2, fixmag1;\n\tfloat x1=VFast_atan2_madd(v, (float)(1.0/(2.0*3.1415926536)), (float)(0.0));\n\t/* q1=x/2pi reduced onto (-0.5,0.5), q2=q1**2 */\n\tfloat q1=VFast_atan2_nmsub(VFast_atan2_round(x1), (float)(1.0), x1);\n\tfloat q2=VFast_atan2_madd(q1, q1, (float)(0.0));\n\ts1= VFast_atan2_madd(q1,\n\t\t\tVFast_atan2_madd(q2,\n\t\t\t\tVFast_atan2_madd(q2,\n\t\t\t\t\tVFast_atan2_madd(q2, (float)(ss4),\n\t\t\t\t\t\t\t\t(float)(ss3)),\n\t\t\t\t\t\t\t\t\t(float)( ss2)),\n\t\t\t\t\t\t\t(float)(ss1)),\n\t\t\t\t\t\t(float)(0.0));\n\tc1= VFast_atan2_madd(q2,\n\t\t\tVFast_atan2_madd(q2,\n\t\t\t\tVFast_atan2_madd(q2, (float)(cc3),\n\t\t\t\t(float)(cc2)),\n\t\t\t(float)(cc1)),\n\t\t(float)(1.0));\n\n\t/* now, do one out of two angle-doublings to get sin & cos theta/2 */\n\tc2=VFast_atan2_nmsub(s1, s1, VFast_atan2_madd(c1, c1, (float)(0.0)));\n\ts2=VFast_atan2_madd((float)(2.0), VFast_atan2_madd(s1, c1, (float)(0.0)), (float)(0.0));\n\n\t/* now, cheat on the correction for magnitude drift...\n\tif the pair has drifted to (1+e)*(cos, sin),\n\tthe next iteration will be (1+e)**2*(cos, sin)\n\twhich is, for small e, (1+2e)*(cos,sin).\n\tHowever, on the (1+e) error iteration,\n\tsin**2+cos**2=(1+e)**2=1+2e also,\n\tso the error in the square of this term\n\twill be exactly the error in the magnitude of the next term.\n\tThen, multiply final result by (1-e) to correct */\n\n\t/* this works with properly normalized sine-cosine functions, but un-normalized is more */\n\tfixmag1=VFast_atan2_nmsub(s2,s2, VFast_atan2_nmsub(c2, c2, (float)(2.0)));\n\n\tc1=VFast_atan2_nmsub(s2, s2, VFast_atan2_madd(c2, c2, (float)(0.0)));\n\ts1=VFast_atan2_madd((float)(2.0), VFast_atan2_madd(s2, c2, (float)(0.0)), (float)(0.0));\n\tcos=VFast_atan2_madd(c1, fixmag1, (float)(0.0));\n\tsin=VFast_atan2_madd(s1, fixmag1, (float)(0.0));\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * Phase Wrapping(radian-PI`PIɃbv) (1x float, C)\n */\nstatic inline float WrapPi_F1(float v)\n{\n\tint rad_unit = static_cast<int>(v*(1.0/M_PI));\n\tif (rad_unit >= 0) rad_unit += rad_unit&1;\n\telse rad_unit -= rad_unit&1;\n\tv -= (float)(M_PI*(double)rad_unit);\n\treturn v;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * ֐KpȂ̃C^[[u\n * @param dest\t\ti[()\n * @param src\t\t\\[X\n * @param win\t\t֐\n * @param numch\t\t`l\n * @param destofs\tdest̏Jnʒu\n * @param len\t\tTv\n *\t\t\t\t\t(e`lƂ̐; ۂɏTv\n *\t\t\t\t\t̑vlen*numchɂȂ)\n */\nvoid DeinterleaveApplyingWindow(float * __restrict dest[], const float * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t destofs, size_t len);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * ֐KpȂ̃C^[[u+I[o[bsO\n * @param dest\t\ti[\n * @param src\t\t\\[X()\n * @param win\t\t֐\n * @param numch\t\t`l\n * @param srcofs\tsrc̏Jnʒu\n * @param len\t\tTv\n *\t\t\t\t\t(e`lƂ̐; ۂɏTv\n *\t\t\t\t\t̑vlen*numchɂȂ)\n */\nvoid  InterleaveOverlappingWindow(float * __restrict dest,\n\tconst float * __restrict const * __restrict src,\n\tfloat * __restrict win, int numch, size_t srcofs, size_t len);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n#if defined(_M_IX86)||defined(_M_X64)\n//---------------------------------------------------------------------------\n// 萔Ȃ\n//---------------------------------------------------------------------------\nextern _ALIGN16(const tjs_uint32) TVP_VFASTATAN2_C1[4] ;\nextern _ALIGN16(const tjs_uint32) TVP_VFASTATAN2_C1_XOR_C2[4] ;\nextern _ALIGN16(const float) TVP_VFASTATAN2_E [4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_SS1[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_SS2[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_SS3[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_SS4[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_CC1[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_CC2[4] ;\nextern _ALIGN16(const float) TVP_VFASTSINCOS_CC3[4] ;\nextern _ALIGN16(const float) TVP_V_R_PI[4] ;\nextern _ALIGN16(const float) TVP_V_R_2PI[4] ;\nextern _ALIGN16(const float) TVP_V_PI[4] ;\nextern _ALIGN16(const float) TVP_V_2PI[4] ;\nextern _ALIGN16(const tjs_uint32) TVP_V_I32_1[4];\n\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * atan2 ̍ (4x float, SSE)\n * @note\tx͂܂ǂȂB10bit炢B @r\n *\t\t\tT: http://www.dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm\n */\nstatic inline __m128 VFast_arctan2_F4_SSE(__m128 y, __m128 x)\n{\n\t__m128 abs_y = _mm_add_ps(_mm_and_ps(y, PM128(PABSMASK)), PM128(TVP_VFASTATAN2_E));\n//   float abs_y = fabs(y)+1e-10;     // kludge to prevent 0/0 condition\n\n\t__m128 x_sign = _mm_and_ps(x, PM128(PCS_RRRR));// 0x80000000 if x < 0\n\t__m128 x_mask = _mm_cmple_ps(x, PM128(PFV_0)); // 0xffffffff if x <= 0\n\t__m128 abs_y2 = _mm_xor_ps(abs_y , x_sign);\n\t__m128 abs_y1 = _mm_xor_ps(abs_y2, PM128(PCS_RRRR));\n\t__m128 r      = _mm_div_ps(_mm_add_ps(x, abs_y1), _mm_add_ps(x, abs_y2));\n\tr             = _mm_xor_ps(r, x_sign);\n\t__m128 coeff_1_or_2 = _mm_xor_ps(\n\t\t\t\t\t\t\t_mm_and_ps(x_mask, PM128(TVP_VFASTATAN2_C1_XOR_C2)),\n\t\t\t\t\t\t\tPM128(TVP_VFASTATAN2_C1)); // x<=0?coeff_2:coeff_1\n/*\n\t__m128 coeff_1_or_2 = _mm_or_ps(\n\t\t_mm_and_ps   (x_mask, PM128(TVP_VFASTATAN2_C1)),\n\t\t_mm_andnot_ps(x_mask, PM128(TVP_VFASTATAN2_C2))); // x>=0?coeff_1:coeff_2\n*/\n\t__m128 angle  = _mm_sub_ps(coeff_1_or_2, _mm_mul_ps(PM128(TVP_VFASTATAN2_C1), r));\n/*\n   if (x>=0)\n   {\n      float r =    (x - abs_y) / (x + abs_y)  ;\n      angle = coeff_1 - coeff_1 * r;\n   }\n   else\n   {\n      float r = -( (x + abs_y) / (x - abs_y)  );\n      angle = coeff_2 - coeff_1 * r;\n   }\n*/\n\t__m128 y_sign = _mm_and_ps(y, PM128(PCS_RRRR));\n\treturn _mm_xor_ps(angle, y_sign);\n/*\n   if (y < 0)\n     return(-angle);     // negate if in quad III or IV\n   else\n     return(angle);\n*/\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * SSE̊ۂ߃[hŋߒlɐݒ肷\n * @note\t̃\\bh SSE Ŏgpۂ߃[h\n *\t\t\tݒ肷BKvƂeِĂяoOɂPĂяoƁB\n *\t\t\tSSEgpĂ֐Ԃɋ܂Ɗۂ߃[hς\\\n *\t\t\t̂Œӂ邱ƁB̂悤ȏꍇ͍ĂтĂяo\n *\t\t\tۂ߃[hĐݒ肷邱ƁB\n */\nstatic inline void SetRoundingModeToNearest_SSE()\n{\n\t_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * sincos ̍ (4x float, SSE)\n * @note\tT: http://arxiv.org/PS_cache/cs/pdf/0406/0406049.pdf  @r\n *\t\t\tĂяoɐ旧 Risa_SetRoundingModeToNearest_SSE ĂԂƁB\n */\nstatic inline void VFast_sincos_F4_SSE2(__m128 v, __m128 &sin, __m128 &cos)\n{\n\t__m128 s1, s2, c1, c2, fixmag1;\n\n\t__m128 x1 = _mm_mul_ps(v, PM128(TVP_V_R_2PI));\n//\tfloat x1=madd(v, (float)(1.0/(2.0*3.1415926536)), (float)(0.0));\n\n\t/* q1=x/2pi reduced onto (-0.5,0.5), q2=q1**2 */\n\t__m128i r0 = _mm_cvtps_epi32(x1);\n\t__m128 q1, q2;\n\tq1 = _mm_cvtepi32_ps(r0);\n\tq1 = _mm_sub_ps(x1, q1);\n\n\tq2 = _mm_mul_ps(q1, q1);\n\n//\tfloat q1=nmsub(round(x1), (float)(1.0), x1); // q1 = x1 - round(x1)\n//\tfloat q2=madd(q1, q1, (float)(0.0));\n\n\ts1 = _mm_add_ps(_mm_mul_ps(q2, PM128(TVP_VFASTSINCOS_SS4)), PM128(TVP_VFASTSINCOS_SS3));\n\t\t// s1 = (q2 * ss4 + ss3)\n\ts1 = _mm_add_ps(_mm_mul_ps(s1, q2), PM128(TVP_VFASTSINCOS_SS2));\n\t\t// s1 = (q2 * (q2 * ss4 + ss3) + ss2)\n\ts1 = _mm_add_ps(_mm_mul_ps(s1, q2), PM128(TVP_VFASTSINCOS_SS1));\n\t\t// s1 = (q2 * (q2 * (q2 * ss4 + ss3) + ss2) + ss1)\n\ts1 = _mm_mul_ps(s1, q1);\n\n//\ts1 = q1 * (q2 * (q2 * (q2 * ss4 + ss3) + ss2) + ss1);\n//\ts1= madd(q1,\n//\t\t\tmadd(q2,\n//\t\t\t\tmadd(q2,\n//\t\t\t\t\tmadd(q2, (float)(ss4),\n//\t\t\t\t\t\t\t\t(float)(ss3)),\n//\t\t\t\t\t\t\t\t\t(float)( ss2)),\n//\t\t\t\t\t\t\t(float)(ss1)),\n//\t\t\t\t\t\t(float)(0.0));\n\n\n\tc1 = _mm_add_ps(_mm_mul_ps(q2, PM128(TVP_VFASTSINCOS_CC3)), PM128(TVP_VFASTSINCOS_CC2));\n\t\t// c1 = (q2 * cc3 + cc2)\n\tc1 = _mm_add_ps(_mm_mul_ps(c1, q2), PM128(TVP_VFASTSINCOS_CC1));\n\t\t// c1 =  (q2 * (q2 * cc3 + cc2) + cc1 )\n\tc1 = _mm_add_ps(_mm_mul_ps(c1, q2), PM128(PFV_1));\n//\tc1= (q2 *  (q2 * (q2 * cc3 + cc2) + cc1 ) + 1.0);\n//\tc1= madd(q2,\n//\t\t\tmadd(q2,\n//\t\t\t\tmadd(q2, (float)(cc3),\n//\t\t\t\t(float)(cc2)),\n//\t\t\t(float)(cc1)),\n//\t\t(float)(1.0));\n\n\t/* now, do one out of two angle-doublings to get sin & cos theta/2 */\n\tc2 = _mm_sub_ps( _mm_mul_ps(c1, c1), _mm_mul_ps(s1, s1));\n//\tc2=nmsub(s1, s1, madd(c1, c1, (float)(0.0))); // c2 = (c1*c1) - (s1*s1)\n\ts2 = _mm_mul_ps(_mm_mul_ps(s1, c1), PM128(PFV_2));\n//\ts2=madd((float)(2.0), madd(s1, c1, (float)(0.0)), (float)(0.0)); // s2=2*s1*c1\n\n\t/* now, cheat on the correction for magnitude drift...\n\tif the pair has drifted to (1+e)*(cos, sin),\n\tthe next iteration will be (1+e)**2*(cos, sin)\n\twhich is, for small e, (1+2e)*(cos,sin).\n\tHowever, on the (1+e) error iteration,\n\tsin**2+cos**2=(1+e)**2=1+2e also,\n\tso the error in the square of this term\n\twill be exactly the error in the magnitude of the next term.\n\tThen, multiply final result by (1-e) to correct */\n\n\t/* this works with properly normalized sine-cosine functions, but un-normalized is more */\n\t__m128 c2_c2 = _mm_mul_ps(c2, c2);\n\t__m128 s2_s2 = _mm_mul_ps(s2, s2);\n\tfixmag1 = _mm_sub_ps(_mm_sub_ps(PM128(PFV_2), c2_c2), s2_s2);\n//\tfixmag1=nmsub(s2,s2, nmsub(c2, c2, (float)(2.0))); // fixmag1 = ( 2.0 - c2*c2 ) - s2*s2\n\n\tc1 = _mm_sub_ps(c2_c2, s2_s2);\n//\tc1=nmsub(s2, s2, madd(c2, c2, (float)(0.0))); // c1 = c2*c2 - s2*s2\n\ts1 = _mm_mul_ps(_mm_mul_ps(s2, c2), PM128(PFV_2));\n//\ts1=madd((float)(2.0), madd(s2, c2, (float)(0.0)), (float)(0.0));\n\tcos = _mm_mul_ps(c1, fixmag1);\n//\tcos=madd(c1, fixmag1, (float)(0.0));\n\tsin = _mm_mul_ps(s1, fixmag1);\n//\tsin=madd(s1, fixmag1, (float)(0.0));\n}\n#if defined(_M_IX86)\nstatic inline void VFast_sincos_F4_SSE(__m128 v, __m128 &sin, __m128 &cos)\n{\n\t__m128 s1, s2, c1, c2, fixmag1;\n\n\t__m128 x1 = _mm_mul_ps(v, PM128(TVP_V_R_2PI));\n//\tfloat x1=madd(v, (float)(1.0/(2.0*3.1415926536)), (float)(0.0));\n\n\t/* q1=x/2pi reduced onto (-0.5,0.5), q2=q1**2 */\n\t__m64 r0 = _mm_cvt_ps2pi(x1);\n\t__m64 r1 = _mm_cvt_ps2pi(_mm_movehl_ps(x1, x1));\n\t__m128 q1, q2;\n\tq1 = _mm_movelh_ps(_mm_cvtpi32_ps(q1, r0), _mm_cvtpi32_ps(q1, r1));\n\tq1 = _mm_sub_ps(x1, q1);\n\n\tq2 = _mm_mul_ps(q1, q1);\n\n//\tfloat q1=nmsub(round(x1), (float)(1.0), x1); // q1 = x1 - round(x1)\n//\tfloat q2=madd(q1, q1, (float)(0.0));\n\n\ts1 = _mm_add_ps(_mm_mul_ps(q2, PM128(TVP_VFASTSINCOS_SS4)), PM128(TVP_VFASTSINCOS_SS3));\n\t\t// s1 = (q2 * ss4 + ss3)\n\ts1 = _mm_add_ps(_mm_mul_ps(s1, q2), PM128(TVP_VFASTSINCOS_SS2));\n\t\t// s1 = (q2 * (q2 * ss4 + ss3) + ss2)\n\ts1 = _mm_add_ps(_mm_mul_ps(s1, q2), PM128(TVP_VFASTSINCOS_SS1));\n\t\t// s1 = (q2 * (q2 * (q2 * ss4 + ss3) + ss2) + ss1)\n\ts1 = _mm_mul_ps(s1, q1);\n\n//\ts1 = q1 * (q2 * (q2 * (q2 * ss4 + ss3) + ss2) + ss1);\n//\ts1= madd(q1,\n//\t\t\tmadd(q2,\n//\t\t\t\tmadd(q2,\n//\t\t\t\t\tmadd(q2, (float)(ss4),\n//\t\t\t\t\t\t\t\t(float)(ss3)),\n//\t\t\t\t\t\t\t\t\t(float)( ss2)),\n//\t\t\t\t\t\t\t(float)(ss1)),\n//\t\t\t\t\t\t(float)(0.0));\n\n\n\tc1 = _mm_add_ps(_mm_mul_ps(q2, PM128(TVP_VFASTSINCOS_CC3)), PM128(TVP_VFASTSINCOS_CC2));\n\t\t// c1 = (q2 * cc3 + cc2)\n\tc1 = _mm_add_ps(_mm_mul_ps(c1, q2), PM128(TVP_VFASTSINCOS_CC1));\n\t\t// c1 =  (q2 * (q2 * cc3 + cc2) + cc1 )\n\tc1 = _mm_add_ps(_mm_mul_ps(c1, q2), PM128(PFV_1));\n//\tc1= (q2 *  (q2 * (q2 * cc3 + cc2) + cc1 ) + 1.0);\n//\tc1= madd(q2,\n//\t\t\tmadd(q2,\n//\t\t\t\tmadd(q2, (float)(cc3),\n//\t\t\t\t(float)(cc2)),\n//\t\t\t(float)(cc1)),\n//\t\t(float)(1.0));\n\n\t/* now, do one out of two angle-doublings to get sin & cos theta/2 */\n\tc2 = _mm_sub_ps( _mm_mul_ps(c1, c1), _mm_mul_ps(s1, s1));\n//\tc2=nmsub(s1, s1, madd(c1, c1, (float)(0.0))); // c2 = (c1*c1) - (s1*s1)\n\ts2 = _mm_mul_ps(_mm_mul_ps(s1, c1), PM128(PFV_2));\n//\ts2=madd((float)(2.0), madd(s1, c1, (float)(0.0)), (float)(0.0)); // s2=2*s1*c1\n\n\t/* now, cheat on the correction for magnitude drift...\n\tif the pair has drifted to (1+e)*(cos, sin),\n\tthe next iteration will be (1+e)**2*(cos, sin)\n\twhich is, for small e, (1+2e)*(cos,sin).\n\tHowever, on the (1+e) error iteration,\n\tsin**2+cos**2=(1+e)**2=1+2e also,\n\tso the error in the square of this term\n\twill be exactly the error in the magnitude of the next term.\n\tThen, multiply final result by (1-e) to correct */\n\n\t/* this works with properly normalized sine-cosine functions, but un-normalized is more */\n\t__m128 c2_c2 = _mm_mul_ps(c2, c2);\n\t__m128 s2_s2 = _mm_mul_ps(s2, s2);\n\tfixmag1 = _mm_sub_ps(_mm_sub_ps(PM128(PFV_2), c2_c2), s2_s2);\n//\tfixmag1=nmsub(s2,s2, nmsub(c2, c2, (float)(2.0))); // fixmag1 = ( 2.0 - c2*c2 ) - s2*s2\n\n\tc1 = _mm_sub_ps(c2_c2, s2_s2);\n//\tc1=nmsub(s2, s2, madd(c2, c2, (float)(0.0))); // c1 = c2*c2 - s2*s2\n\ts1 = _mm_mul_ps(_mm_mul_ps(s2, c2), PM128(PFV_2));\n//\ts1=madd((float)(2.0), madd(s2, c2, (float)(0.0)), (float)(0.0));\n\tcos = _mm_mul_ps(c1, fixmag1);\n//\tcos=madd(c1, fixmag1, (float)(0.0));\n\tsin = _mm_mul_ps(s1, fixmag1);\n//\tsin=madd(s1, fixmag1, (float)(0.0));\n\n\t_mm_empty();\n}\n#elif defined(_M_X64)\n#define VFast_sincos_F4_SSE VFast_sincos_F4_SSE2\n#endif\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * Phase Wrapping(radian-PI`PIɃbv) (4x float, SSE)\n */\nstatic inline __m128 Wrap_Pi_F4_SSE2(__m128 v)\n{\n\t// v  M_PI Ŋ\n\t__m128 v_quant = _mm_mul_ps(v, PM128(TVP_V_R_PI)); // v_quant = v/M_PI\n\n\t// v_quant_ȉ؂̂ĂĐɕϊ\n\t__m128i q = _mm_cvttps_epi32(v_quant);\n\t// ̏ꍇv_quant&1𑫂Ȁꍇ͈\n\t// a = v_quant,    v_quant = a + ( (0 - (a&1)) & ((a>>31)|1) )\n\tq =\n\t\t_mm_add_epi32(\n\t\t\tq,\n\t\t\t_mm_and_si128(\n\t\t\t\t_mm_sub_epi32(\n\t\t\t\t\t_mm_setzero_si128(),\n\t\t\t\t\t_mm_and_si128(q, PM128I(TVP_V_I32_1))\n\t\t\t\t),\n\t\t\t\t_mm_or_si128(\n\t\t\t\t\t_mm_srai_epi32(q, 31),\n\t\t\t\t\tPM128I(TVP_V_I32_1)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t// ɖ߂AM_PI \n\tv_quant = _mm_cvtepi32_ps(q);\n\tv_quant = _mm_mul_ps(v_quant, PM128(TVP_V_PI));\n\n\t//  v \n\tv = _mm_sub_ps(v, v_quant);\n\n\t// ߂\n\treturn v;\n}\n#if defined(_M_IX86)\nstatic inline __m128 Wrap_Pi_F4_SSE(__m128 v)\n{\n\t// v  M_PI Ŋ\n\t__m128 v_quant = _mm_mul_ps(v, PM128(TVP_V_R_PI)); // v_quant = v/M_PI\n\n\t// v_quant_ȉ؂̂ĂĐɕϊ\n\t__m64 q0 = _mm_cvtt_ps2pi(v_quant); \n\t__m64 q1 = _mm_cvtt_ps2pi(_mm_movehl_ps(v_quant, v_quant));\n\n\t// ̏ꍇv_quant&1𑫂Ȁꍇ͈\n\t// a = v_quant,    v_quant = a + ( (0 - (a&1)) & ((a>>31)|1) )\n\n\tq0 =\n\t\t_mm_add_pi32(\n\t\t\tq0,\n\t\t\t_mm_and_si64(\n\t\t\t\t_mm_sub_pi32(\n\t\t\t\t\t_mm_setzero_si64(),\n\t\t\t\t\t_mm_and_si64(q0, PM64(TVP_V_I32_1))\n\t\t\t\t),\n\t\t\t\t_mm_or_si64(\n\t\t\t\t\t_mm_srai_pi32(q0, 31),\n\t\t\t\t\tPM64(TVP_V_I32_1)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\tq1 =\n\t\t_mm_add_pi32(\n\t\t\tq1,\n\t\t\t_mm_and_si64(\n\t\t\t\t_mm_sub_pi32(\n\t\t\t\t\t_mm_setzero_si64(),\n\t\t\t\t\t_mm_and_si64(q1, PM64(TVP_V_I32_1))\n\t\t\t\t),\n\t\t\t\t_mm_or_si64(\n\t\t\t\t\t_mm_srai_pi32(q1, 31),\n\t\t\t\t\tPM64(TVP_V_I32_1)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t// ɖ߂AM_PI \n\tv_quant = _mm_movelh_ps(_mm_cvtpi32_ps(v, q0), _mm_cvtpi32_ps(v, q1));\n\tv_quant = _mm_mul_ps(v_quant, PM128(TVP_V_PI));\n\n\t//  v \n\tv = _mm_sub_ps(v, v_quant);\n\n\t// MMXgI\n\t_mm_empty();\n\n\t// ߂\n\treturn v;\n}\n#elif defined(_M_X64)\n// x64 ̎SSE2g\n#define Wrap_Pi_F4_SSE Wrap_Pi_F4_SSE2\n#endif\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/**\n * ֐KpȂ̃C^[[u\n * @param dest\t\ti[()\n * @param src\t\t\\[X\n * @param win\t\t֐\n * @param numch\t\t`l\n * @param destofs\tdest̏Jnʒu\n * @param len\t\tTv\n *\t\t\t\t\t(e`lƂ̐; ۂɏTv\n *\t\t\t\t\t̑vlen*numchɂȂ)\n */\nvoid DeinterleaveApplyingWindow_sse(float * __restrict dest[], const float * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t destofs, size_t len);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * ֐KpȂ̃C^[[u+I[o[bsO\n * @param dest\t\ti[\n * @param src\t\t\\[X()\n * @param win\t\t֐\n * @param numch\t\t`l\n * @param srcofs\tsrc̏Jnʒu\n * @param len\t\tTv\n *\t\t\t\t\t(e`lƂ̐; ۂɏTv\n *\t\t\t\t\t̑vlen*numchɂȂ)\n */\nvoid  InterleaveOverlappingWindow_sse(float * __restrict dest, const float * __restrict const * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t srcofs, size_t len);\n//---------------------------------------------------------------------------\n#endif\n\n\n#endif\n"
  },
  {
    "path": "src/core/sound/PhaseVocoderDSP.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Phase Vocoder ̎\n//---------------------------------------------------------------------------\n\n/*\n\tPhase Vocoder (tF[Y {R[_ ; ʑ{R[_)̎\n\n\tQl:\n\n\t\thttp://www.panix.com/~jens/pvoc-dolson.par\n\t\t\tPhase Vocoder ̃`[gABu~[WVɂ킩悤Ɂv\n\t\t\tĂAwsth[B\n\n\t\thttp://www.dspdimension.com/\n\t\t\t(I[v\\[Xł͂Ȃ) Time Stretcher/Pitch Shifter\n\t\t\tDIRACAeASY̐A\n\t\t\tPitch Shifter ̐Iȃ\\[XR[hȂǁB\n\n\t\thttp://soundlab.cs.princeton.edu/software/rt_pvc/\n\t\t\treal-time phase vocoder analysis/synthesis library + visualization\n\t\t\t\\[XB\n*/\n\n#include \"tjsCommHead.h\"\n\n#define _USE_MATH_DEFINES\n#include <math.h>\n#include \"MathAlgorithms.h\"\n#include \"PhaseVocoderDSP.h\"\n#include \"RealFFT.h\"\n#include <string.h>\n\n#include \"tjsUtils.h\"\n\n//#include \"tvpgl_ia32_intf.h\"\n#include \"DetectCPU.h\"\n\nextern void InterleaveOverlappingWindow(float * __restrict dest, const float * __restrict const * __restrict src,\n\tfloat * __restrict win, int numch, size_t srcofs, size_t len);\nextern void DeinterleaveApplyingWindow(float * __restrict dest[], const float * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t destofs, size_t len);\n#if 0\nextern void InterleaveOverlappingWindow_sse(float * __restrict dest, const float * __restrict const * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t srcofs, size_t len);\nextern void DeinterleaveApplyingWindow_sse(float * __restrict dest[], const float * __restrict src,\n\t\t\t\t\tfloat * __restrict win, int numch, size_t destofs, size_t len);\n#endif\n\n\n//---------------------------------------------------------------------------\ntRisaPhaseVocoderDSP::tRisaPhaseVocoderDSP(\n\t\t\t\tunsigned int framesize,\n\t\t\t\tunsigned int frequency, unsigned int channels) :\n\t\t\t\t\tInputBuffer(framesize * 4 * channels),\n\t\t\t\t\tOutputBuffer(framesize * 4 * channels)\n\t\t// InputBuffer ͍Œł\n\t\t// channels * (framesize + (framesize/oversamp)) KvŁA\n\t\t// OutputBuffer ͍Œł\n\t\t// channels * (framesize + (framesize/oversamp)*MAX_TIME_SCALE) Kv\n{\n\t// tB[h̏\n\tFFTWorkIp = NULL;\n\tFFTWorkW = NULL;\n\tInputWindow = NULL;\n\tOutputWindow = NULL;\n\tAnalWork = NULL;\n\tSynthWork = NULL;\n\tLastAnalPhase = NULL;\n\tLastSynthPhase = NULL;\n\n\tFrameSize = framesize;\n\tOverSampling = 8;\n\tFrequency = frequency;\n\tChannels = channels;\n\tInputHopSize = OutputHopSize = FrameSize / OverSampling;\n\n\tTimeScale = 1.0;\n\tFrequencyScale = 1.0;\n\tRebuildParams = true; // KɃp[^č\\z悤ɐ^\n\n\tLastSynthPhaseAdjustCounter = 0;\n\n\ttry\n\t{\n\t\t// [NȂǂ̊m\n\t\tAnalWork  = (float **)TJSAlignedAlloc(sizeof(float *) * Channels, 4);\n\t\tSynthWork = (float **)TJSAlignedAlloc(sizeof(float *) * Channels, 4);\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tAnalWork[ch] = NULL, SynthWork[ch] = NULL;\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t{\n\t\t\tAnalWork[ch]  = (float *)TJSAlignedAlloc(sizeof(float) * (FrameSize), 4);\n\t\t\tSynthWork[ch] = (float *)TJSAlignedAlloc(sizeof(float) * (FrameSize), 4);\n\t\t}\n\n\t\tLastAnalPhase = (float **)TJSAlignedAlloc(sizeof(float *) * Channels, 4);\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tLastAnalPhase[ch] = NULL;\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t{\n\t\t\tLastAnalPhase[ch] = (float *)TJSAlignedAlloc(sizeof(float) * (FrameSize/2), 4);\n\t\t\tmemset(LastAnalPhase[ch], 0, FrameSize/2 * sizeof(float)); // 0 ŃNA\n\t\t}\n\n\t\tLastSynthPhase = (float **)TJSAlignedAlloc(sizeof(float *) * Channels, 4);\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tLastSynthPhase[ch] = NULL;\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t{\n\t\t\tLastSynthPhase[ch] = (float *)TJSAlignedAlloc(sizeof(float) * (FrameSize/2), 4);\n\t\t\tmemset(LastSynthPhase[ch], 0, FrameSize/2 * sizeof(float)); // 0 ŃNA\n\t\t}\n\n\t\tFFTWorkIp = (int *)TJSAlignedAlloc(sizeof(int) * (static_cast<int>(2+sqrt((double)FrameSize/4))), 4);\n\t\tFFTWorkIp[0] = FFTWorkIp[1] = 0;\n\t\tFFTWorkW = (float *)TJSAlignedAlloc(sizeof(float) * (FrameSize/2), 4);\n\t\tInputWindow = (float *)TJSAlignedAlloc(sizeof(float) * FrameSize, 4);\n\t\tOutputWindow = (float *)TJSAlignedAlloc(sizeof(float) * FrameSize, 4);\n\t}\n\tcatch(...)\n\t{\n\t\tClear();\n\t\tthrow;\n\t}\n\n\t// o̓obt@̓eNA\n\tfloat *bufp1;\n\tsize_t buflen1;\n\tfloat *bufp2;\n\tsize_t buflen2;\n\n\tInputBuffer.GetWritePointer(InputBuffer.GetSize(),\n\t\t\t\t\t\t\tbufp1, buflen1, bufp2, buflen2);\n\tif(bufp1) memset(bufp1, 0, sizeof(float)*buflen1);\n\tif(bufp2) memset(bufp2, 0, sizeof(float)*buflen2);\n\n\tOutputBuffer.GetWritePointer(OutputBuffer.GetSize(),\n\t\t\t\t\t\t\tbufp1, buflen1, bufp2, buflen2);\n\tif(bufp1) memset(bufp1, 0, sizeof(float)*buflen1);\n\tif(bufp2) memset(bufp2, 0, sizeof(float)*buflen2);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntRisaPhaseVocoderDSP::~tRisaPhaseVocoderDSP()\n{\n\tClear();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::SetTimeScale(float v)\n{\n\tif(TimeScale != v)\n\t{\n\t\tTimeScale = v;\n\t\tRebuildParams = true;\n\t\tInputHopSize = OutputHopSize = FrameSize / OverSampling;\n\t\tOutputHopSize = static_cast<unsigned int>(InputHopSize * TimeScale) & ~1;\n\t\t\t//  ɃAC(dv)\n\t\t\t// f re,im, re,im, ... ̔z񂪋tFFTɂ蓯(f̌~2)\n\t\t\t// PCMTvɕϊ邽߁APCMTvQňȂƂȂȂ.\n\t\t\t// ̎ۂ OutputHopSize ɏ] ExactTimeScale vZ.\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::SetFrequencyScale(float v)\n{\n\tif(FrequencyScale != v)\n\t{\n\t\tFrequencyScale = v;\n\t\tRebuildParams = true;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::SetOverSampling(unsigned int v)\n{\n\tif(v == 0)\n\t{\n\t\t// TimeScale ɏ]Ēlݒ\n\t\t// 臒l͎ۂ̃XjOɂ茈肳ꂽlłA\n\t\t// _Iȍ͂ȂB\n\t\tif(TimeScale <= 0.2) v = 2;\n\t\telse if(TimeScale <= 1.2) v = 4;\n\t\telse v = 8;\n\t}\n\n\tif(OverSampling != v)\n\t{\n\t\tOverSampling = v;\n\t\tInputHopSize = OutputHopSize = FrameSize / OverSampling;\n\t\tOutputHopSize = static_cast<unsigned int>(InputHopSize * TimeScale) & ~1;\n\t\t// OutputHopSizěvZɂĂ tRisaPhaseVocoderDSP::SetTimeScale\n\t\t// QƂ̂\n\t\tRebuildParams = true;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::Clear()\n{\n\t// SẴobt@Ȃǂ\n\tif(AnalWork)\n\t{\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tTJSAlignedDealloc(AnalWork[ch]), AnalWork[ch] = NULL;\n\t\tTJSAlignedDealloc(AnalWork), AnalWork = NULL;\n\t}\n\tif(SynthWork)\n\t{\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tTJSAlignedDealloc(SynthWork[ch]), SynthWork[ch] = NULL;\n\t\tTJSAlignedDealloc(SynthWork), SynthWork = NULL;\n\t}\n\tif(LastAnalPhase)\n\t{\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tTJSAlignedDealloc(LastAnalPhase[ch]), LastAnalPhase[ch] = NULL;\n\t\tTJSAlignedDealloc(LastAnalPhase), LastAnalPhase = NULL;\n\t}\n\tif(LastSynthPhase)\n\t{\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t\tTJSAlignedDealloc(LastSynthPhase[ch]), LastSynthPhase[ch] = NULL;\n\t\tTJSAlignedDealloc(LastSynthPhase), LastSynthPhase = NULL;\n\t}\n\tTJSAlignedDealloc(FFTWorkIp), FFTWorkIp = NULL;\n\tTJSAlignedDealloc(FFTWorkW), FFTWorkW = NULL;\n\tTJSAlignedDealloc(InputWindow), InputWindow = NULL;\n\tTJSAlignedDealloc(OutputWindow), OutputWindow = NULL;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nsize_t tRisaPhaseVocoderDSP::GetInputFreeSize()\n{\n\treturn InputBuffer.GetFreeSize() / Channels;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nbool tRisaPhaseVocoderDSP::GetInputBuffer(\n\tsize_t numsamplegranules,\n\tfloat * & p1, size_t & p1size,\n\tfloat * & p2, size_t & p2size)\n{\n\tsize_t numsamples = numsamplegranules * Channels;\n\n\tif(InputBuffer.GetFreeSize() < numsamples) return false; // \\ȋ󂫗eʂȂ\n\n\tInputBuffer.GetWritePointer(numsamples, p1, p1size, p2, p2size);\n\n\tp1size /= Channels;\n\tp2size /= Channels;\n\n\tInputBuffer.AdvanceWritePos(numsamples);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nsize_t tRisaPhaseVocoderDSP::GetOutputReadySize()\n{\n\treturn OutputBuffer.GetDataSize() / Channels;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nbool tRisaPhaseVocoderDSP::GetOutputBuffer(\n\tsize_t numsamplegranules,\n\tconst float * & p1, size_t & p1size,\n\tconst float * & p2, size_t & p2size)\n{\n\tsize_t numsamples = numsamplegranules * Channels;\n\n\tif(OutputBuffer.GetDataSize() < numsamples) return false; // \\ȏς݃TvȂ\n\n\tOutputBuffer.GetReadPointer(numsamples, p1, p1size, p2, p2size);\n\n\tp1size /= Channels;\n\tp2size /= Channels;\n\n\tOutputBuffer.AdvanceReadPos(numsamples);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntRisaPhaseVocoderDSP::tStatus tRisaPhaseVocoderDSP::Process()\n{\n\tconst static bool use_sse = false;\n#if 0\n\t\t\t(TVPCPUType & TVP_CPU_HAS_MMX) &&\n\t\t\t(TVPCPUType & TVP_CPU_HAS_SSE) &&\n\t\t\t(TVPCPUType & TVP_CPU_HAS_CMOV);\n#endif\n\n\t// p[^̍ČvZ̕Kvꍇ͍ČvZ\n\tif(RebuildParams)\n\t{\n\t\t// ֐̌vZ(łVorbis I )\n\t\tfloat recovery_of_loss_of_vorbis_window = 2.0;\n\t\t\t\t//         1            1         2\n\t\t\t\t//  2  =    1dx  /      vorbis (x) dx\n\t\t\t\t//         0            0\n\t\t\t\t// where vobis = vorbis I window function\n\t\tfloat output_volume =\n\t\t\tTimeScale / FrameSize  / sqrt(FrequencyScale) / OverSampling * 2 *\n\t\t\t\t\t\t\t\t\t\t\trecovery_of_loss_of_vorbis_window;\n\t\tfor(unsigned int i = 0; i < FrameSize; i++)\n\t\t{\n\t\t\tdouble x = ((double)i+0.5)/FrameSize;\n\t\t\tdouble window = sin(M_PI/2*sin(M_PI*x)*sin(M_PI*x));\n\t\t\tInputWindow[i]  = (float)(window);\n\t\t\tOutputWindow[i] = (float)(window *output_volume);\n\t\t}\n\n\t\t// ̂ق̃p[^̍ČvZ\n\t\tOverSamplingRadian = (float)((2.0*M_PI)/OverSampling);\n\t\tOverSamplingRadianRecp = (float)(1.0/OverSamplingRadian);\n\t\tFrequencyPerFilterBand = (float)((double)Frequency/FrameSize);\n\t\tFrequencyPerFilterBandRecp = (float)(1.0/FrequencyPerFilterBand);\n\t\tExactTimeScale = (float)OutputHopSize / InputHopSize;\n\n\t\t// tO|\n\t\tRebuildParams = false;\n\t}\n\n\t// ̓obt@̃f[^͏\\H\n\tif(InputBuffer.GetDataSize() < FrameSize * Channels)\n\t\treturn psInputNotEnough; // Ȃ\n\n\t// o̓obt@̋󂫂͏\\H\n\tif(OutputBuffer.GetFreeSize() < FrameSize * Channels)\n\t\treturn psOutputFull; // Ȃ\n\n\t// ꂩ珑Ƃ OutputBuffer ̗̈̍Ō OutputHopSize Tv\n\t// Oj[ 0 Ŗ߂ (I[o[bvɂ͂ݏoȂ̂)\n\t{\n\t\tfloat *p1, *p2;\n\t\tsize_t p1len, p2len;\n\n\t\tOutputBuffer.GetWritePointer(OutputHopSize*Channels,\n\t\t\t\tp1, p1len, p2, p2len, (FrameSize - OutputHopSize)*Channels);\n\t\tmemset(p1, 0, p1len * sizeof(float));\n\t\tif(p2) memset(p2, 0, p2len * sizeof(float));\n\t}\n\n\t// ֐KpA̓obt@ AnalWork ɓǂݍ\n\t{\n\t\tconst float *p1, *p2;\n\t\tsize_t p1len, p2len;\n\t\tInputBuffer.GetReadPointer(FrameSize*Channels, p1, p1len, p2, p2len);\n\t\tp1len /= Channels;\n\t\tp2len /= Channels;\n#if 0\n\t\tif( use_sse ) {\n\t\t\tDeinterleaveApplyingWindow_sse(AnalWork, p1, InputWindow, Channels, 0, p1len);\n\t\t\tif(p2)\n\t\t\t\tDeinterleaveApplyingWindow_sse(AnalWork, p2, InputWindow + p1len, Channels, p1len, p2len);\n\t\t} else {\n\t\t\tDeinterleaveApplyingWindow(AnalWork, p1, InputWindow, Channels, 0, p1len);\n\t\t\tif(p2)\n\t\t\t\tDeinterleaveApplyingWindow(AnalWork, p2, InputWindow + p1len, Channels, p1len, p2len);\n\t\t}\n#else\n\t\tDeinterleaveApplyingWindow(AnalWork, p1, InputWindow, Channels, 0, p1len);\n\t\tif(p2)\n\t\t\tDeinterleaveApplyingWindow(AnalWork, p2, InputWindow + p1len, Channels, p1len, p2len);\n#endif\n\t}\n\n\t// `lƂɏ\n\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t{\n\t\t//------------------------------------------------\n\t\t// \n\t\t//------------------------------------------------\n\n\t\t// Z̍s\n#if 0\n\t\tif(use_sse) ProcessCore_sse(ch);\n\t\telse ProcessCore(ch);\n#else\n\t\tProcessCore(ch);\n#endif\n\t}\n\n\t// ֐KpASynthWork o̓obt@ɏ\n\t{\n\t\tfloat *p1, *p2;\n\t\tsize_t p1len, p2len;\n\n\t\tOutputBuffer.GetWritePointer(FrameSize*Channels, p1, p1len, p2, p2len);\n\t\tp1len /= Channels;\n\t\tp2len /= Channels;\n#if 0\n\t\tif( use_sse ) {\n\t\t\tInterleaveOverlappingWindow_sse(p1, SynthWork, OutputWindow, Channels, 0, p1len);\n\t\t\tif(p2)\n\t\t\t\tInterleaveOverlappingWindow_sse(p2, SynthWork, OutputWindow + p1len, Channels, p1len, p2len);\n\t\t} else {\n\t\t\tInterleaveOverlappingWindow(p1, SynthWork, OutputWindow, Channels, 0, p1len);\n\t\t\tif(p2)\n\t\t\t\tInterleaveOverlappingWindow(p2, SynthWork, OutputWindow + p1len, Channels, p1len, p2len);\n\t\t}\n#else\n\t\tInterleaveOverlappingWindow(p1, SynthWork, OutputWindow, Channels, 0, p1len);\n\t\tif(p2)\n\t\t\tInterleaveOverlappingWindow(p2, SynthWork, OutputWindow + p1len, Channels, p1len, p2len);\n#endif\n\t}\n\n\t// LastSynthPhase Ē邩\n\tLastSynthPhaseAdjustCounter += LastSynthPhaseAdjustIncrement;\n\tif(LastSynthPhaseAdjustCounter >= LastSynthPhaseAdjustInterval)\n\t{\n\t\t// LastSynthPhase ĒJEgɂȂ\n\t\tLastSynthPhaseAdjustCounter = 0;\n\n\t\t// ōs LastSynthPhase  unwrapping łB\n\t\t// LastSynthPhase ͈ʑ̍ݐς̂ő傫ȐlɂȂĂA\n\t\t// KȊԊuł unwrapping ȂƁA(l傫)x\n\t\t// AɍoȂȂĂ܂B\n\t\t// Axۂ΂悢߁A񂱂 unwrapping sKv͂ȂB\n\t\t// ł LastSynthPhaseAdjustInterval/LastSynthPhaseAdjustIncrement 񂲂ƂɒsB\n\t\tfor(unsigned int ch = 0; ch < Channels; ch++)\n\t\t{\n\t\t\tunsigned int framesize_d2 = FrameSize / 2;\n\t\t\tfor(unsigned int i = 0; i < framesize_d2; i++)\n\t\t\t{\n\t\t\t\tlong int n = static_cast<long int>(LastSynthPhase[ch][i] / (2.0*M_PI));\n\t\t\t\tLastSynthPhase[ch][i] -= static_cast<float>(n * (2.0*M_PI));\n\t\t\t}\n\t\t}\n\t}\n\n\t// o̓obt@̃|C^i߂\n\tOutputBuffer.AdvanceWritePos(OutputHopSize * Channels);\n\tInputBuffer.AdvanceReadPos(InputHopSize * Channels);\n\n\t// Xe[^X = no error\n\treturn psNoError;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::ProcessCore(int ch)\n{\n\tunsigned int framesize_d2 = FrameSize / 2;\n\tfloat * analwork = AnalWork[ch];\n\tfloat * synthwork = SynthWork[ch];\n\n\t// FFT s\n\trdft(FrameSize, 1, analwork, FFTWorkIp, FFTWorkW); // Real DFT\n\tanalwork[1] = 0.0; // analwork[1] = nyquist freq. power (ǂ݂gȂ̂0)\n\n\tif(FrequencyScale != 1.0)\n\t{\n\t\t// etB^ohƂɕϊ\n\t\t//-- etB^ohƂ̉ʂƎg߂B\n\t\t//-- FFT sƊetB^ohƂ̒loĂ邪A\n\t\t//-- tB^ohƂohpXtB^̒̕\n\t\t//-- g̃s[N{͂ǂɂ̂́AOvZ\n\t\t//-- ʑƂ̍ƂĂ݂ȂƂ킩ȂB\n\t\tfor(unsigned int i = 0; i < framesize_d2; i ++)\n\t\t{\n\t\t\t// WnɍWn\n\t\t\tfloat re = analwork[i*2  ];\n\t\t\tfloat im = analwork[i*2+1];\n\n\t\t\tfloat mag = sqrt(re*re + im*im); // mag = (re^2+im^2)\n\t\t\tfloat ang = VFast_arctan2(im, re); // ang = atan(im/re)\n\n\t\t\t// ÖʑƂ̍Ƃ\n\t\t\t// --: ŎgpĂFFTpbP[ẂA\n\t\t\t// --      \\[X擪̎QlȂǂŎĂFFT\n\t\t\t// --      o͂镡f̋̕tȂ̂\n\t\t\t// --      (łĂ̂)ӂKvBł\n\t\t\t// --      t̕ƂĈB\n\t\t\tfloat tmp = LastAnalPhase[ch][i] - ang;\n\t\t\tLastAnalPhase[ch][i] = ang; // ̒lۑ\n\n\t\t\t// over sampling ̉el\n\t\t\t// -- ʏAFrameSize  FFT ̂PłƂA\n\t\t\t// -- x₤߁AOverSampling {̎ŉZĂB\n\t\t\t// -- ̂߂ɐʑ̂CB\n\t\t\ttmp -= i * OverSamplingRadian;\n\n\t\t\t// unwrapping \n\t\t\t// -- tmp  -M_PI ` +M_PI ͈̔͂Ɏ܂悤ɂ\n\t\t\ttmp = WrapPi_F1(tmp);\n\n\t\t\t// -M_PI`+M_PI-1.0`+1.0̕ψʂɕϊ\n\t\t\ttmp =  tmp * OverSamplingRadianRecp;\n\n\t\t\t// tmp tB^oh̎g̕ψʂɕϊA\n\t\t\t// ɃtB^oh̒gZ\n\t\t\t// -- i * FrequencyPerFilterBand ̓tB^oh̒g\n\t\t\t// -- \\Atmp * FrequencyPerFilterBand  tB^oh\n\t\t\t// -- ̎g̕ψʂ\\B킹ÃtB^\n\t\t\t// -- ohł́u^v̎głB\n\t\t\tfloat freq = (i + tmp) *FrequencyPerFilterBand;\n\n\t\t\t// analwork ɒli[\n\t\t\tanalwork[i*2  ] = mag;\n\t\t\tanalwork[i*2+1] = freq;\n\t\t}\n\n\n\t\t//------------------------------------------------\n\t\t// ϊ\n\t\t//------------------------------------------------\n\n\t\t// g̃TvOs\n\t\tfloat FrequencyScale_rcp = 1.0f / FrequencyScale;\n\t\tfor(unsigned int i = 0; i < framesize_d2; i ++)\n\t\t{\n\t\t\t// i ɑΉCfbNX𓾂\n\t\t\tfloat fi = i * FrequencyScale_rcp;\n\n\t\t\t// floor(x)  floor(x) + 1 ̊ԂŃoCjAԂs\n\t\t\tunsigned int index = static_cast<unsigned int>(fi); // floor\n\t\t\tfloat frac = fi - index;\n\n\t\t\tif(index + 1 < framesize_d2)\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] =\n\t\t\t\t\tanalwork[index*2  ] +\n\t\t\t\t\tfrac * (analwork[index*2+2]-analwork[index*2  ]);\n\t\t\t\tsynthwork[i*2+1] =\n\t\t\t\t\tFrequencyScale * (\n\t\t\t\t\tanalwork[index*2+1] +\n\t\t\t\t\tfrac * (analwork[index*2+3]-analwork[index*2+1]) );\n\t\t\t}\n\t\t\telse if(index < framesize_d2)\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] = analwork[index*2  ];\n\t\t\t\tsynthwork[i*2+1] = analwork[index*2+1] * FrequencyScale;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] = 0.0;\n\t\t\t\tsynthwork[i*2+1] = 0.0;\n\t\t\t}\n\t\t}\n\n\n\t\t//------------------------------------------------\n\t\t// \n\t\t//------------------------------------------------\n\n\t\t// etB^ohƂɕϊ\n\t\t// {Iɂ͉͂̋tϊł\n\t\tfor(unsigned int i = 0; i < framesize_d2; i ++)\n\t\t{\n\t\t\tfloat mag  = synthwork[i*2  ];\n\t\t\tfloat freq = synthwork[i*2+1];\n\n\t\t\t// getB^oh̒gZA\n\t\t\t// tB^oh̒g-1.0`+1.0̕ψ\n\t\t\t// ɕϊ\n\t\t\tfloat tmp = freq * FrequencyPerFilterBandRecp - (float)i;\n\n\t\t\t// -1.0`+1.0̕ψʂ-M_PI`+M_PÏʑɕϊ\n\t\t\ttmp =  tmp * OverSamplingRadian;\n\n\t\t\t// OverSampling ɂʑ̕␳\n\t\t\ttmp += i   * OverSamplingRadian;\n\n\t\t\t// TimeScale ɂʑ̕␳\n\t\t\t// TimeScale ŏo͂Ԏɂ̂т(邢͏k߂)A\n\t\t\t// ʑ̍ɔĂ̂т(k)\n\t\t\ttmp *= ExactTimeScale;\n\n\t\t\t// ÖʑƉZ\n\t\t\t// ł̕tɂȂ̂Œ\n\t\t\tLastSynthPhase[ch][i] -= tmp;\n\t\t\tfloat ang = LastSynthPhase[ch][i];\n\n\t\t\t// ɍWnWn\n\t\t\tfloat c, s;\n\t\t\tVFast_sincos(ang, s, c);\n\t\t\tsynthwork[i*2  ] = mag * c;\n\t\t\tsynthwork[i*2+1] = mag * s;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// gɃVtgȂꍇ\n\n\t\t// etB^ohƂɕϊ\n\t\t//-- etB^ohƂ̉ʂƎg߂B\n\t\t//-- FFT sƊetB^ohƂ̒loĂ邪A\n\t\t//-- tB^ohƂohpXtB^̒̕\n\t\t//-- g̃s[N{͂ǂɂ̂́AOvZ\n\t\t//-- ʑƂ̍ƂĂ݂ȂƂ킩ȂB\n\t\tfor(unsigned int i = 0; i < framesize_d2; i ++)\n\t\t{\n\t\t\t// WnɍWn\n\t\t\tfloat re = analwork[i*2  ];\n\t\t\tfloat im = analwork[i*2+1];\n\n\t\t\tfloat mag = sqrt(re*re + im*im); // mag = (re^2+im^2)\n\t\t\tfloat ang = VFast_arctan2(im, re); // ang = atan(im/re)\n\n\t\t\t// ÖʑƂ̍Ƃ\n\t\t\t// --: ŎgpĂFFTpbP[ẂA\n\t\t\t// --      \\[X擪̎QlȂǂŎĂFFT\n\t\t\t// --      o͂镡f̋̕tȂ̂\n\t\t\t// --      (łĂ̂)ӂKvBł\n\t\t\t// --      t̕ƂĈB\n\t\t\tfloat tmp = LastAnalPhase[ch][i] - ang;\n\t\t\tLastAnalPhase[ch][i] = ang; // ̒lۑ\n\n\t\t\t// phase shift\n\t\t\tfloat phase_shift = i * OverSamplingRadian;\n\n\t\t\t// over sampling ̉el\n\t\t\t// -- ʏAFrameSize  FFT ̂PłƂA\n\t\t\t// -- x₤߁AOverSampling {̎ŉZĂB\n\t\t\t// -- ̂߂ɐʑ̂CB\n\t\t\ttmp -= phase_shift;\n\n\t\t\t// unwrapping \n\t\t\t// -- tmp  -M_PI ` +M_PI ͈̔͂Ɏ܂悤ɂ\n\t\t\ttmp = WrapPi_F1(tmp);\n\n//--\n\t\t\t// OverSampling ɂʑ̕␳\n\t\t\ttmp += phase_shift;\n\n\t\t\t// TimeScale ɂʑ̕␳\n\t\t\t// TimeScale ŏo͂Ԏɂ̂т(邢͏k߂)A\n\t\t\t// ʑ̍ɔĂ̂т(k)\n\t\t\ttmp *= ExactTimeScale;\n\n\t\t\t// ÖʑƉZ\n\t\t\t// ł̕tɂȂ̂Œ\n\t\t\tLastSynthPhase[ch][i] -= tmp;\n\t\t\tang = LastSynthPhase[ch][i];\n\n\t\t\t// ɍWnWn\n\t\t\tfloat c, s;\n\t\t\tVFast_sincos(ang, s, c);\n\t\t\tsynthwork[i*2  ] = mag * c;\n\t\t\tsynthwork[i*2+1] = mag * s;\n\t\t}\n\t}\n\n\t// FFT s\n\tsynthwork[1] = 0.0; // synthwork[1] = nyquist freq. power (ǂ݂gȂ̂0)\n\trdft(FrameSize, -1, SynthWork[ch], FFTWorkIp, FFTWorkW); // Inverse Real DFT\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n/*\n\t̃\\[XR[hł͏ڂASY͍̐sȂB\n\t{Iȗ̓v[CłƕςȂ̂ŁA\n\t../opt_default/PhaseVocoderDSP_default.cpp QƂ̂ƁB\n*/\n\n//---------------------------------------------------------------------------\n#if 0\n//---------------------------------------------------------------------------\nvoid tRisaPhaseVocoderDSP::ProcessCore_sse(int ch)\n{\n\tunsigned int framesize_d2 = FrameSize / 2;\n\tfloat * analwork = AnalWork[ch];\n\tfloat * synthwork = SynthWork[ch];\n\n\t// ۂ߃[hݒ\n\tSetRoundingModeToNearest_SSE();\n\n\t// FFT s\n\trdft(FrameSize, 1, analwork, FFTWorkIp, FFTWorkW); // Real DFT\n\tanalwork[1] = 0.0; // analwork[1] = nyquist freq. power (ǂ݂gȂ̂0)\n\n\t__m128 exact_time_scale = _mm_load1_ps(&ExactTimeScale);\n\t__m128 over_sampling_radian_v = _mm_load1_ps(&OverSamplingRadian);\n\n\tif(FrequencyScale != 1.0)\n\t{\n\t\t// ł 4 f (8) ƂɏsB\n\t\t__m128 over_sampling_radian_recp = _mm_load1_ps(&OverSamplingRadianRecp);\n\t\t__m128 frequency_per_filter_band = _mm_load1_ps(&FrequencyPerFilterBand);\n\t\t__m128 frequency_per_filter_band_recp = _mm_load1_ps(&FrequencyPerFilterBandRecp);\n\n\t\tfor(unsigned int i = 0; i < framesize_d2; i += 4)\n\t\t{\n\t\t\t// C^[[u +  WnɍWn\n\t\t\t__m128 aw3120 = *(__m128*)(analwork + i*2    );\n\t\t\t__m128 aw7654 = *(__m128*)(analwork + i*2 + 4);\n\n\t\t\t__m128 re3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(2,0,2,0));\n\t\t\t__m128 im3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(3,1,3,1));\n\n\t\t\t__m128 mag = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(re3210,re3210), _mm_mul_ps(im3210,im3210)));\n\t\t\t__m128 ang = VFast_arctan2_F4_SSE(im3210, re3210);\n\n\t\t\t// ÖʑƂ̍Ƃ\n\t\t\t__m128 lastp = *(__m128*)(LastAnalPhase[ch] + i);\n\t\t\t*(__m128*)(LastAnalPhase[ch] + i) = ang;\n\t\t\tang = _mm_sub_ps(lastp, ang);\n\n\t\t\t// over sampling ̉el\n\t\t\t__m128 i_3210;\n\t\t\ti_3210 = _mm_cvtsi32_ss(i_3210, i);\n\t\t\ti_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));\n\t\t\ti_3210 = _mm_add_ps( i_3210, PM128(PFV_INIT) );\n\n\t\t\t__m128 phase_shift = _mm_mul_ps(i_3210, over_sampling_radian_v);\n\t\t\tang = _mm_sub_ps( ang, phase_shift );\n\n\t\t\t// unwrapping \n\t\t\tang = Wrap_Pi_F4_SSE(ang);\n\n\t\t\t// -M_PI`+M_PI-1.0`+1.0̕ψʂɕϊ\n\t\t\tang = _mm_mul_ps( ang, over_sampling_radian_recp );\n\n\t\t\t// tmp tB^oh̎g̕ψʂɕϊA\n\t\t\t// ɃtB^oh̒gZ\n\t\t\t__m128 freq = _mm_mul_ps( _mm_add_ps(ang, i_3210), frequency_per_filter_band );\n\n\t\t\t// analwork ɒli[\n\t\t\tre3210 = mag;\n\t\t\tim3210 = freq;\n\t\t\t__m128 im10re10 = _mm_movelh_ps(re3210, im3210);\n\t\t\t__m128 im32re32 = _mm_movehl_ps(im3210, re3210);\n\t\t\t__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));\n\t\t\t__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));\n\t\t\t*(__m128*)(analwork + i*2    ) = im1re1im0re0;\n\t\t\t*(__m128*)(analwork + i*2 + 4) = im3re3im2re2;\n\t\t}\n\n\n\t\t//------------------------------------------------\n\t\t// ϊ\n\t\t//------------------------------------------------\n\t\t// g̃TvOs\n\t\tfloat FrequencyScale_rcp = 1.0f / FrequencyScale;\n\t\tfor(unsigned int i = 0; i < framesize_d2; i ++)\n\t\t{\n\t\t\t// i ɑΉCfbNX𓾂\n\t\t\tfloat fi = i * FrequencyScale_rcp;\n\n\t\t\t// floor(x)  floor(x) + 1 ̊ԂŃoCjAԂs\n\t\t\tunsigned int index = static_cast<unsigned int>(fi); // floor\n\t\t\tfloat frac = fi - index;\n\n\t\t\tif(index + 1 < framesize_d2)\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] =\n\t\t\t\t\tanalwork[index*2  ] +\n\t\t\t\t\tfrac * (analwork[index*2+2]-analwork[index*2  ]);\n\t\t\t\tsynthwork[i*2+1] =\n\t\t\t\t\tFrequencyScale * (\n\t\t\t\t\tanalwork[index*2+1] +\n\t\t\t\t\tfrac * (analwork[index*2+3]-analwork[index*2+1]) );\n\t\t\t}\n\t\t\telse if(index < framesize_d2)\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] = analwork[index*2  ];\n\t\t\t\tsynthwork[i*2+1] = analwork[index*2+1] * FrequencyScale;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsynthwork[i*2  ] = 0.0;\n\t\t\t\tsynthwork[i*2+1] = 0.0;\n\t\t\t}\n\t\t}\n\n\t\t//------------------------------------------------\n\t\t// \n\t\t//------------------------------------------------\n\n\t\t// etB^ohƂɕϊ\n\t\t// {Iɂ͉͂̋tϊł\n\t\tfor(unsigned int i = 0; i < framesize_d2; i += 4)\n\t\t{\n\t\t\t// C^[[u\n\t\t\t__m128 sw3120 = *(__m128*)(synthwork + i*2    );\n\t\t\t__m128 sw7654 = *(__m128*)(synthwork + i*2 + 4);\n\n\t\t\t__m128 mag  = _mm_shuffle_ps(sw3120, sw7654, _MM_SHUFFLE(2,0,2,0));\n\t\t\t__m128 freq = _mm_shuffle_ps(sw3120, sw7654, _MM_SHUFFLE(3,1,3,1));\n\n\t\t\t// i+3 i+2 i+1 i+0 \n\t\t\t__m128 i_3210;\n\t\t\ti_3210 = _mm_cvtsi32_ss(i_3210, i);\n\t\t\ti_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));\n\t\t\ti_3210 = _mm_add_ps(i_3210, PM128(PFV_INIT));\n\n\t\t\t// getB^oh̒gZA\n\t\t\t// tB^oh̒g-1.0`+1.0̕ψ\n\t\t\t// ɕϊ\n\t\t\t__m128 ang = _mm_sub_ps(_mm_mul_ps(freq, frequency_per_filter_band_recp), i_3210);\n\n\t\t\t// -1.0`+1.0̕ψʂ-M_PI`+M_PÏʑɕϊ\n\t\t\tang = _mm_mul_ps( ang, over_sampling_radian_v );\n\n\t\t\t// OverSampling ɂʑ̕␳\n\t\t\tang = _mm_add_ps( ang, _mm_mul_ps( i_3210, over_sampling_radian_v ) );\n\n\t\t\t// TimeScale ɂʑ̕␳\n\t\t\tang = _mm_mul_ps( ang, exact_time_scale );\n\n\t\t\t// ÖʑƉZ\n\t\t\t// ł̕tɂȂ̂Œ\n\t\t\tang = _mm_sub_ps( *(__m128*)(LastSynthPhase[ch] + i), ang );\n\t\t\t*(__m128*)(LastSynthPhase[ch] + i) = ang;\n\n\t\t\t// ɍWnWn\n\t\t\t__m128 sin, cos;\n\t\t\tVFast_sincos_F4_SSE(ang, sin, cos);\n\t\t\t__m128 re3210 = _mm_mul_ps( mag, cos );\n\t\t\t__m128 im3210 = _mm_mul_ps( mag, sin );\n\n\t\t\t// C^[[u\n\t\t\t__m128 im10re10 = _mm_movelh_ps(re3210, im3210);\n\t\t\t__m128 im32re32 = _mm_movehl_ps(im3210, re3210);\n\t\t\t__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));\n\t\t\t__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));\n\t\t\t*(__m128*)(synthwork + i*2    ) = im1re1im0re0;\n\t\t\t*(__m128*)(synthwork + i*2 + 4) = im3re3im2re2;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// gɃVtgȂꍇ\n\t\t// ł 4 f (8) ƂɏsB\n\t\tfor(unsigned int i = 0; i < framesize_d2; i += 4)\n\t\t{\n\t\t\t// C^[[u +  WnɍWn\n\t\t\t__m128 aw3120 = *(__m128*)(analwork + i*2    );\n\t\t\t__m128 aw7654 = *(__m128*)(analwork + i*2 + 4);\n\n\t\t\t__m128 re3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(2,0,2,0));\n\t\t\t__m128 im3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(3,1,3,1));\n\n\t\t\t__m128 mag = _mm_sqrt_ps( _mm_add_ps(_mm_mul_ps(re3210,re3210), _mm_mul_ps(im3210,im3210)) );\n\t\t\t__m128 ang = VFast_arctan2_F4_SSE(im3210, re3210);\n\n\t\t\t// ÖʑƂ̍Ƃ\n\t\t\t__m128 lastp = *(__m128*)(LastAnalPhase[ch] + i);\n\t\t\t*(__m128*)(LastAnalPhase[ch] + i) = ang;\n\t\t\tang = _mm_sub_ps( lastp, ang );\n\n\t\t\t// over sampling ̉el\n\t\t\t__m128 i_3210;\n\t\t\ti_3210 = _mm_cvtsi32_ss(i_3210, i);\n\t\t\ti_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));\n\t\t\ti_3210 = _mm_add_ps( i_3210, PM128(PFV_INIT) );\n\n\t\t\t__m128 phase_shift = _mm_mul_ps( i_3210, over_sampling_radian_v );\n\t\t\tang = _mm_sub_ps( ang, phase_shift );\n\n\t\t\t// unwrapping \n\t\t\tang = Wrap_Pi_F4_SSE(ang);\n\n\t\t\t// OverSampling ɂʑ̕␳\n\t\t\tang = _mm_add_ps( ang, phase_shift );\n\n\t\t\t// TimeScale ɂʑ̕␳\n\t\t\tang = _mm_mul_ps( ang, exact_time_scale );\n\n\t\t\t// ÖʑƉZ\n\t\t\t// ł̕tɂȂ̂Œ\n\t\t\tang = _mm_sub_ps( *(__m128*)(LastSynthPhase[ch] + i), ang );\n\t\t\t*(__m128*)(LastSynthPhase[ch] + i) = ang;\n\n\t\t\t// ɍWnWn\n\t\t\t__m128 sin, cos;\n\t\t\tVFast_sincos_F4_SSE(ang, sin, cos);\n\t\t\tre3210 = _mm_mul_ps( mag, cos );\n\t\t\tim3210 = _mm_mul_ps( mag, sin );\n\n\t\t\t// C^[[u\n\t\t\t__m128 im10re10 = _mm_movelh_ps(re3210, im3210);\n\t\t\t__m128 im32re32 = _mm_movehl_ps(im3210, re3210);\n\t\t\t__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));\n\t\t\t__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));\n\t\t\t*(__m128*)(synthwork + i*2    ) = im1re1im0re0;\n\t\t\t*(__m128*)(synthwork + i*2 + 4) = im3re3im2re2;\n\t\t}\n\t}\n\n\t// FFT s\n\tsynthwork[1] = 0.0; // synthwork[1] = nyquist freq. power (ǂ݂gȂ̂0)\n\trdft_sse(FrameSize, -1, synthwork, FFTWorkIp, FFTWorkW); // Inverse Real DFT\n}\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/sound/PhaseVocoderDSP.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Phase Vocoder ̎\n//---------------------------------------------------------------------------\n#ifndef RisaPhaseVocoderH\n#define RisaPhaseVocoderH\n\n#include \"RingBuffer.h\"\n\n//---------------------------------------------------------------------------\n//! @brief Phase Vocoder DSP NX\n//---------------------------------------------------------------------------\nclass tRisaPhaseVocoderDSP\n{\nprotected:\n\tfloat ** AnalWork; //!< (Analyze)pobt@(FrameSize) Oŏ΂Ȃ悤\n\tfloat ** SynthWork; //!< pƃobt@(FrameSize)\n\tfloat ** LastAnalPhase; //!< O͎̊etB^oḧʑ (e`lƂFrameSize/2)\n\tfloat ** LastSynthPhase; //!< O񍇐̊etB^oḧʑ (e`lƂFrameSize/2)\n\n\tint * FFTWorkIp; //!< rdft ɓn ip p[^\n\tfloat * FFTWorkW; //!< rdft ɓn w p[^\n\tfloat * InputWindow; //!< ͗p֐\n\tfloat * OutputWindow; //!< o͗p֐\n\n\tunsigned int FrameSize; //!< FFTTCY\n\tunsigned int OverSampling; //!< I[o[ETvOW\n\tunsigned int Frequency; //!< PCM TvOg\n\tunsigned int Channels; //!< PCM `l\n\tunsigned int InputHopSize; //!< FrameSize/OverSampling\n\tunsigned int OutputHopSize; //!< InputHopSize * TimeScale (SetTimeScaleɍČvZ)\n\n\tfloat\tTimeScale; //!< Ԏ̃XP[(o/)\n\tfloat\tFrequencyScale; //!< g̃XP[(o/)\n\n\t// ȉARebuildParams ^̎ɍč\\zp[^\n\t// ɂ郁oȊOł́AInputWindow  OutputWindow č\\z\n\tfloat OverSamplingRadian; //!< (2.0*M_PI)/OverSampling\n\tfloat OverSamplingRadianRecp; //!< OverSamplingRadian ̋t\n\tfloat FrequencyPerFilterBand; //!< Frequency/FrameSize\n\tfloat FrequencyPerFilterBandRecp; //!< FrequencyPerFilterBand ̋t\n\tfloat ExactTimeScale; //!< TimeScale = OutputHopSize / InputHopSize\n\t// č\\zp[^A܂\n\n\ttRisaRingBuffer<float> InputBuffer; //!< ͗pOobt@\n\ttRisaRingBuffer<float> OutputBuffer; //!< o͗pOobt@\n\n\tbool\tRebuildParams; //!< Iȃp[^Ȃǂč\\zȂ΂ȂȂƂɐ^\n\n\tunsigned long LastSynthPhaseAdjustCounter; //!< LastSynthPhase ␳͂邽߂̃JE^\n\tconst static unsigned long LastSynthPhaseAdjustIncrement = 0x03e8a444; //!< LastSynthPhaseAdjustCounterɉZl\n\tconst static unsigned long LastSynthPhaseAdjustInterval  = 0xfa2911fe; //!< LastSynthPhase ␳\n\n\npublic:\n\t//! @brief Process ԂXe[^X\n\tenum tStatus\n\t{\n\t\tpsNoError, //!< Ȃ\n\t\tpsInputNotEnough, //!< ͂Ȃ (GetInputBufferœ|C^ɏĂĎs)\n\t\tpsOutputFull //!< o̓obt@ς (GetOutputBufferœ|C^ǂݏoĂĎs)\n\t};\n\npublic:\n\t//! @brief\t\tRXgN^\n\t//! @param\t\tframesize\t\tt[TCY(2̗ݏ, 16`)\n\t//! @param\t\tfrequency\t\tPCM̃TvO[g\n\t//! @param\t\tchannels\t\tPCM̃`l\n\t//! @note\t\typłframesize=4096,oversamp=16炢悭A\n\t//! @note\t\t{CXpłframesize=256,oversamp=8炢悢B\n\ttRisaPhaseVocoderDSP(unsigned int framesize,\n\t\t\t\t\tunsigned int frequency, unsigned int channels);\n\n\t//! @brief\t\tfXgN^\n\t~tRisaPhaseVocoderDSP();\n\n\tfloat GetTimeScale() const { return TimeScale; } //!< Ԏ̃XP[𓾂\n\n\t//! @brief\t\tԎ̃XP[ݒ肷\n\t//! @param\t\tv     XP[\n\tvoid SetTimeScale(float v);\n\n\tfloat GetFrequencyScale() const { return FrequencyScale; } //!< g̃XP[𓾂\n\n\t//! @brief\t\tg̃XP[ݒ肷\n\t//! @param\t\tv     XP[\n\tvoid SetFrequencyScale(float v);\n\n\t//! @brief\t\tI[o[TvOW擾\n\t//! @return\t\tI[o[TvOW\n\tunsigned int GetOverSampling() const { return OverSampling; }\n\n\t//! @brief\t\tI[o[TvOWݒ肷\n\t//! @param\t\tv\t\tW ( 0 = Ԏ̃XP[ɏ]ĎIɐݒ )\n\tvoid SetOverSampling(unsigned int v);\n\n\tunsigned int GetInputHopSize() const { return InputHopSize; } //!< InputHopSize𓾂\n\tunsigned int GetOutputHopSize() const { return OutputHopSize; } //!< OutputHopSize 𓾂\n\nprivate:\n\t//! @brief\t\tNA\n\tvoid Clear();\n\npublic:\n\t//! @brief\t\t̓obt@̋󂫃TvOj[𓾂\n\t//! @return\t\t̓obt@̋󂫃TvOj[\n\tsize_t GetInputFreeSize();\n\n\t//! @brief\t\t̓obt@̏݃|C^𓾂\n\t//! @param\t\tnumsamplegranules ݂TvOj[\n\t//! @param\t\tp1\t\tubN1̐擪ւ̃|C^i[邽߂̕ϐ\n\t//! @param\t\tp1size\tp1̕\\ubÑTvOj[\n\t//! @param\t\tp2\t\tubN2̐擪ւ̃|C^i[邽߂̕ϐ(NULL蓾)\n\t//! @param\t\tp2size\tp2̕\\ubÑTvOj[(0蓾)\n\t//! @return\t\t󂫗eʂȂ΋UA󂫗eʂA|C^Ԃΐ^\n\t//! @note\t\tp1  p2 ̂悤ɂQ̃|C^Ƃ̃TCYԂ̂́A\n\t//!\t\t\t\t̃obt@ۂ̓Oobt@ŁAOobt@̃jAȃobt@\n\t//!\t\t\t\t̏I[܂\\邽߁B܂Ȃꍇp2NULLɂȂ邪A܂\n\t//!\t\t\t\tꍇ p1 ̂Ƃ p2 ɑď܂Ȃ΂ȂȂB\n\tbool GetInputBuffer(size_t numsamplegranules,\n\t\tfloat * & p1, size_t & p1size,\n\t\tfloat * & p2, size_t & p2size);\n\n\t//! @brief\t\to̓obt@̏ς݃TvOj[𓾂\n\t//! @return\t\to̓obt@̏ς݃TvOj[\n\tsize_t GetOutputReadySize();\n\n\t//! @brief\t\to̓obt@̓ǂݍ݃|C^𓾂\n\t//! @param\t\tnumsamplegranules ǂݍ݂TvOj[\n\t//! @param\t\tp1\t\tubN1̐擪ւ̃|C^i[邽߂̕ϐ\n\t//! @param\t\tp1size\tp1̕\\ubÑTvOj[\n\t//! @param\t\tp2\t\tubN2̐擪ւ̃|C^i[邽߂̕ϐ(NULL蓾)\n\t//! @param\t\tp2size\tp2̕\\ubÑTvOj[(0蓾)\n\t//! @return\t\tꂽTvȂ΋UATvA|C^Ԃΐ^\n\t//! @note\t\tp1  p2 ̂悤ɂQ̃|C^Ƃ̃TCYԂ̂́A\n\t//!\t\t\t\t̃obt@ۂ̓Oobt@ŁAOobt@̃jAȃobt@\n\t//!\t\t\t\t̏I[܂\\邽߁B܂Ȃꍇp2NULLɂȂ邪A܂\n\t//!\t\t\t\tꍇ p1 ̂Ƃ p2 𑱂ēǂݏoȂ΂ȂȂB\n\tbool GetOutputBuffer(size_t numsamplegranules,\n\t\tconst float * & p1, size_t & p1size,\n\t\tconst float * & p2, size_t & p2size);\n\n\t//! @brief\t\t1Xebvs\n\t//! @return\t\tʂ\\enum\n\ttStatus Process();\n\n\t//! @brief\t\tZ̍\n\t//! @param\t\tch\t\t\ts`l\n\t//! @note\t\t͊̕eCPUƂɍœK邽߁A\n\t//!\t\t\t\t opt_default fBNgȂǂɒuB\n\t//!\t\t\t\t(PhaseVocoderDSP.cppɂ͂̎͂Ȃ)\n\tvoid ProcessCore(int ch);\n#if defined(_M_IX86)||defined(_M_X64)\n\tvoid ProcessCore_sse(int ch);\n#endif\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/sound/PhaseVocoderFilter.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Phase Vocoder Filter\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n#include \"PhaseVocoderDSP.h\"\n#include \"PhaseVocoderFilter.h\"\n#include \"WaveIntf.h\"\n#include \"MsgIntf.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_PhaseVocoder : PhaseVocoder TJS native class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_PhaseVocoder::ClassID = (tjs_uint32)-1;\ntTJSNC_PhaseVocoder::tTJSNC_PhaseVocoder() :\n\ttTJSNativeClass(TJS_W(\"PhaseVocoder\"))\n{\n\t// register native methods/properties\n\n\tTJS_BEGIN_NATIVE_MEMBERS(PhaseVocoder)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n// constructor/methods\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_PhaseVocoder,\n\t/*TJS class name*/PhaseVocoder)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/PhaseVocoder)\n//----------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n\n\n\n//----------------------------------------------------------------------\n// properties\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(interface)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t*result = reinterpret_cast<tjs_int64>((iTVPBasicWaveFilter*)_this);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(interface)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(window)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t*result = (tjs_int64)(_this->GetWindow());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t_this->SetWindow(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(window)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(overlap)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t*result = (tjs_int64)(_this->GetOverlap());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t_this->SetOverlap(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(overlap)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(pitch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t*result = (double)_this->GetPitch();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t_this->SetPitch((float)(double)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(pitch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(time)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t*result = (double)_this->GetTime();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PhaseVocoder);\n\t\t_this->SetTime((float)(double)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(time)\n//---------------------------------------------------------------------------\n\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\niTJSNativeInstance *tTJSNC_PhaseVocoder::CreateNativeInstance()\n{\n\treturn new tTJSNI_PhaseVocoder();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\ntTJSNI_PhaseVocoder::tTJSNI_PhaseVocoder()\n{\n\tWindow = 4096;\n\tOverlap = 0;\n\tPitch = 1.0;\n\tTime = 1.0;\n\n\tSource = NULL;\n\tPhaseVocoder = NULL;\n\tFormatConvertBuffer = NULL;\n\tFormatConvertBufferSize = 0;\n\n}\n//---------------------------------------------------------------------------\ntTJSNI_PhaseVocoder::~tTJSNI_PhaseVocoder()\n{\n\tif(PhaseVocoder) delete PhaseVocoder, PhaseVocoder = NULL;\n\tif(FormatConvertBuffer) delete [] FormatConvertBuffer, FormatConvertBuffer = NULL, FormatConvertBufferSize = 0;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_PhaseVocoder::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_PhaseVocoder::Invalidate()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::SetWindow(int window)\n{\n\t// l`FbN\n\tswitch(window)\n\t{\n\tcase 64: case 128: case 256: case 512: case 1024: case 2048: case 4096: case 8192:\n\tcase 16384: case 32768:\n\t\tbreak;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPInvalidWindowSizeMustBeIn64to32768);\n\t}\n\tWindow = window;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::SetOverlap(int overlap)\n{\n\t// l`FbN\n\tswitch(overlap)\n\t{\n\tcase 0:\n\tcase 2: case 4: case 8: case 16: case 32:\n\t\tbreak;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPInvalidOverlapCountMustBeIn2to32);\n\t}\n\tOverlap = overlap;\n}\n//---------------------------------------------------------------------------\ntTVPSampleAndLabelSource * tTJSNI_PhaseVocoder::Recreate(tTVPSampleAndLabelSource * source)\n{\n\tif(Source)\n\t\tTVPThrowExceptionMessage(TVPCannotConnectMultipleWaveSoundBufferAtOnce);\n\n\tif(PhaseVocoder) delete PhaseVocoder, PhaseVocoder = NULL;\n\n\tSource = source;\n\tInputFormat = Source->GetFormat();\n\tOutputFormat = InputFormat;\n\tOutputFormat.IsFloat = true; // o͂ float\n\tOutputFormat.BitsPerSample = 32; // rbg 32 rbg\n\tOutputFormat.BytesPerSample = 4;\n\n\treturn this;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::Reset(void)\n{\n\tInputSegments.Clear();\n\tOutputSegments.Clear();\n\tif(PhaseVocoder) delete PhaseVocoder, PhaseVocoder = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::Clear(void)\n{\n\tSource = NULL;\n\tInputSegments.Clear();\n\tOutputSegments.Clear();\n\tif(PhaseVocoder) delete PhaseVocoder, PhaseVocoder = NULL;\n\tif(FormatConvertBuffer) delete [] FormatConvertBuffer, FormatConvertBuffer = NULL, FormatConvertBufferSize = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::Update(void)\n{\n\t// Update filter internal state.\n\t// Note that this method may be called by non-main thread (decoding thread)\n\t// and setting Pitch and Time may be called from main thread, and these may\n\t// be simultaneous.\n\t// We do not care about that because typically writing size of float is atomic\n\t// on most platform. (I don't know any platform which does not guarantee that).\n\tif(PhaseVocoder)\n\t{\n\t\tPhaseVocoder->SetFrequencyScale(Pitch);\n\t\tPhaseVocoder->SetTimeScale(Time);\n\t\tPhaseVocoder->SetOverSampling(Overlap);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::Fill(float * dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue & segments)\n{\n\tif(InputFormat.IsFloat && InputFormat.BitsPerSample == 32 && InputFormat.BytesPerSample == 4)\n\t{\n\t\t// ͂32bitt[gȂ̂ŕϊ̕Kv͂Ȃ\n\t\tSource->Decode(dest, samples, written, segments);\n\t}\n\telse\n\t{\n\t\t// ͂32bitt[gł͂Ȃ̂ŕϊ̕Kv\n\t\t// ϊobt@ɂ߂\n\t\ttjs_uint buf_size = samples * InputFormat.BytesPerSample * InputFormat.Channels;\n\t\tif(FormatConvertBufferSize < buf_size)\n\t\t{\n\t\t\t// obt@Ċm\n\t\t\tif(FormatConvertBuffer) delete [] FormatConvertBuffer, FormatConvertBuffer = NULL;\n\t\t\tFormatConvertBuffer = new char[buf_size];\n\t\t\tFormatConvertBufferSize = buf_size;\n\t\t}\n\t\t// obt@ɃfR[hs\n\t\tSource->Decode(FormatConvertBuffer, samples, written, segments);\n\t\t// ϊs\n\t\tTVPConvertPCMToFloat(dest, FormatConvertBuffer, InputFormat, written);\n\t}\n\tif(written < samples)\n\t{\n\t\t// fR[hꂽTvvꂽTvɖȂꍇ\n\t\t// c 0 Ŗ߂\n\t\tmemset(dest + written * InputFormat.Channels, 0,\n\t\t\t(samples - written) * sizeof(float) * InputFormat.Channels);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_PhaseVocoder::Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\ttTVPWaveSegmentQueue & segments)\n{\n\tif(!PhaseVocoder)\n\t{\n\t\t// PhaseVocoder 쐬\n\t\ttRisaPhaseVocoderDSP * pv = new tRisaPhaseVocoderDSP(Window,\n\t\t\t\t\tInputFormat.SamplesPerSec, InputFormat.Channels);\n\t\tpv->SetFrequencyScale(Pitch);\n\t\tpv->SetTimeScale(Time);\n\t\tpv->SetOverSampling(Overlap);\n\t\tPhaseVocoder = pv; // now visible from other function\n\t}\n\n\tsize_t inputhopsize = PhaseVocoder->GetInputHopSize();\n\tsize_t outputhopsize = PhaseVocoder->GetOutputHopSize();\n\ttTVPWaveSegmentQueue queue;\n\n\tfloat * dest_buf = (float*) dest;\n\twritten = 0;\n\twhile(samples > 0)\n\t{\n\t\ttRisaPhaseVocoderDSP::tStatus status;\n\t\tdo\n\t\t{\n\t\t\tsize_t inputfree = PhaseVocoder->GetInputFreeSize();\n\t\t\tif(inputfree >= inputhopsize)\n\t\t\t{\n\t\t\t\t// ͂Ƀf[^𗬂\n\t\t\t\tfloat *p1, *p2;\n\t\t\t\tsize_t p1len, p2len;\n\t\t\t\tPhaseVocoder->GetInputBuffer(inputhopsize, p1, p1len, p2, p2len);\n\t\t\t\ttjs_uint filled = 0;\n\t\t\t\ttjs_uint total = 0;\n\t\t\t\tFill       (p1, (tjs_uint)p1len, filled, InputSegments), total += filled;\n\t\t\t\tif(p2) Fill(p2, (tjs_uint)p2len, filled, InputSegments), total += filled;\n\t\t\t\tif(total == 0) { break ; } // f[^Ȃ\n\t\t\t}\n\n\t\t\t// PhaseVocodeȑs\n\t\t\t// ̏ł́A͂inputhopsizeAo͂\n\t\t\t// outputhopsizeo͂B\n\t\t\tstatus = PhaseVocoder->Process();\n\t\t\tif(status == tRisaPhaseVocoderDSP::psNoError)\n\t\t\t{\n\t\t\t\t// ɐBinputhopsize ̃L[ InputSegments ǂݏoA\n\t\t\t\t// outputhopsize ɃXP[AOutputSegments ɏށB\n\t\t\t\tInputSegments.Dequeue(queue, inputhopsize);\n\t\t\t\tqueue.Scale(outputhopsize);\n\t\t\t\tOutputSegments.Enqueue(queue);\n\t\t\t}\n\t\t} while(status == tRisaPhaseVocoderDSP::psInputNotEnough);\n\n\t\t// ͂Ƀf[^𗬂łďo͂Ƃ͂Ȃ\n\t\t// vTCYꍇ͂\n\t\tsize_t output_ready = PhaseVocoder->GetOutputReadySize();\n\t\tif(output_ready >= outputhopsize)\n\t\t{\n\t\t\t// PhaseVocoder ̏o͂ dest ɃRs[\n\t\t\tsize_t copy_size = outputhopsize > samples ? samples : outputhopsize;\n\t\t\tconst float *p1, *p2;\n\t\t\tsize_t p1len, p2len;\n\t\t\tPhaseVocoder->GetOutputBuffer(copy_size, p1, p1len, p2, p2len);\n\t\t\tmemcpy(dest_buf, p1, p1len * sizeof(float)*OutputFormat.Channels);\n\t\t\tif(p2) memcpy(dest_buf + p1len * OutputFormat.Channels, p2,\n\t\t\t\t\t\t\tp2len * sizeof(float)*OutputFormat.Channels);\n\n\t\t\tsamples  -= (tjs_uint)copy_size;\n\t\t\twritten  += (tjs_uint)copy_size;\n\t\t\tdest_buf += copy_size * OutputFormat.Channels;\n\n\t\t\t// segment queue ̏o\n\t\t\tOutputSegments.Dequeue(queue, copy_size);\n\t\t\tsegments.Enqueue(queue);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn; // ̓f[^Ώo̓f[^Ȃ\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/sound/PhaseVocoderFilter.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Phase Vocoder Filter\n//---------------------------------------------------------------------------\n\n#ifndef PhaseVocoderFilterH\n#define PhaseVocoderFilterH\n\n#include \"WaveLoopManager.h\"\n#include \"WaveIntf.h\"\n\n\n\n\n\nclass tRisaPhaseVocoderDSP;\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_PhaseVocoder\n//---------------------------------------------------------------------------\nclass tTJSNI_PhaseVocoder :\n\tpublic tTJSNativeInstance, public iTVPBasicWaveFilter, public tTVPSampleAndLabelSource\n{\n\ttypedef tTJSNativeInstance inherited;\n\npublic:\n\ttTJSNI_PhaseVocoder();\n\t~tTJSNI_PhaseVocoder();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprivate:\n\tint Window; // window size\n\tint Overlap; // overlap scale\n\tfloat Pitch; // pitch scale\n\tfloat Time; // time scale\n\npublic:\n\tint GetWindow() const { return Window; }\n\tvoid SetWindow(int window);\n\tint GetOverlap() const { return Overlap; }\n\tvoid SetOverlap(int overlap);\n\tfloat GetPitch() const { return Pitch; }\n\tvoid SetPitch(float pitch) { Pitch = pitch; }\n\tfloat GetTime() const { return Time; }\n\tvoid SetTime(float time) { Time = time; }\n\n\nprivate:\n\ttTVPSampleAndLabelSource * Recreate(tTVPSampleAndLabelSource * source);\n\t\t // from iTVPBasicWaveFilter\n\tvoid Clear(void); // from iTVPBasicWaveFilter\n\tvoid Reset(void); // from iTVPBasicWaveFilter\n\tvoid Update(void); // from iTVPBasicWaveFilter\n\nprivate:\n\ttTVPSampleAndLabelSource * Source; // source filter\n\n\ttRisaPhaseVocoderDSP * PhaseVocoder; // Phase Vocoder DSP instance\n\tchar * FormatConvertBuffer; // buffer for converting PCM formats internally\n\tsize_t FormatConvertBufferSize;\n\n\ttTVPWaveFormat InputFormat;\n\ttTVPWaveFormat OutputFormat;\n\n\ttTVPWaveSegmentQueue InputSegments;\n\ttTVPWaveSegmentQueue OutputSegments;\n\n\tvoid Fill(float * dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue & segments);\n\n\tvoid Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue & segments); // from tTVPSampleAndLabelSource\n\n\tconst tTVPWaveFormat & GetFormat() const { return OutputFormat; }\n\t\t\t// from tTVPSampleAndLabelSource\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_PhaseVocoder\n//---------------------------------------------------------------------------\nclass tTJSNC_PhaseVocoder : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_PhaseVocoder();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\tiTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n\n#endif\n\n"
  },
  {
    "path": "src/core/sound/RingBuffer.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Oobt@鎩Ɛev[gNX\n//---------------------------------------------------------------------------\n#ifndef RingBufferH\n#define RingBufferH\n\n#include <stddef.h>\n/*\n\tOobt@, ring buffer, circular buffer, obt@\n*/\n\n//---------------------------------------------------------------------------\n//! @brief\t\tŒ蒷Oobt@̎\n//---------------------------------------------------------------------------\ntemplate <typename T>\nclass tRisaRingBuffer\n{\n\tT * Buffer; //!< obt@\n\tsize_t Size; //!< obt@̃TCY\n\tsize_t WritePos; //!< ݈ʒu\n\tsize_t ReadPos; //!< ǂݍ݈ʒu\n\tsize_t DataSize; //!< obt@ɓĂf[^̃TCY\n\npublic:\n\t//! @brief RXgN^\n\ttRisaRingBuffer(size_t size)\n\t{\n\t\tSize = size;\n\t\tBuffer = new T[Size];\n\t\tWritePos = ReadPos = 0;\n\t\tDataSize = 0;\n\t}\n\n\t//! @brief fXgN^\n\t~tRisaRingBuffer()\n\t{\n\t\tdelete [] Buffer;\n\t}\n\n\t//! @brief\tTCY𓾂\n\tsize_t GetSize() { return Size; }\n\n\t//! @brief\t݈ʒu𓾂\n\tsize_t GetWritePos() { return WritePos; }\n\n\t//! @brief\tǂݍ݈ʒu𓾂\n\tsize_t GetReadPos() { return ReadPos; }\n\n\t//! @brief\tobt@ɓĂf[^̃TCY𓾂\n\tsize_t GetDataSize() { return DataSize; }\n\n\t//! @brief\tobt@̋󂫗eʂ𓾂\n\tsize_t GetFreeSize() { return Size - DataSize; }\n\n\t//! @brief\tobt@ǂݍނ߂̃|C^𓾂\n\t//! @param\treadsize ǂݍ݂f[^ ( 1 ȏ̐; 0 nȂ )\n\t//! @param\tp1\t\tubN1̐擪ւ̃|C^i[邽߂̕ϐ\n\t//! @param\tp1size\tp1̕\\ubÑTCY\n\t//! @param\tp2\t\tubN2̐擪ւ̃|C^i[邽߂̕ϐ(NULL蓾)\n\t//! @param\tp2size\tp2̕\\ubÑTCY(0蓾)\n\t//! @param\toffset\tReadPos ɉZItZbg\n\t//! @note\tobt@ƂĂAۂ̓jAȗ̈Ƀobt@mۂĂB\n\t//!\t\t\t̂߁A ReadPos + readsize obt@̏I[𒴂ĂꍇA\n\t//!\t\t\tubN͂Qɕf邱ƂɂȂB\n\t//!\t\t\t̃\\bh́AreadsizeۂɃobt@ɓĂf[^̃TCYȉł邩\n\t//!\t\t\tȂǂ̃`FbN͂sȂBO GetDataSize 𒲂ׁAǂݍ݂\n\t//!\t\t\tTCYۂɃobt@ɂ邩ǂ`FbN邱ƁB\n\tvoid GetReadPointer(size_t readsize,\n\t\t\t\t\t\tconst T * & p1, size_t &p1size,\n\t\t\t\t\t\tconst T * & p2, size_t &p2size,\n\t\t\t\t\t\tptrdiff_t offset = 0)\n\t{\n\t\tsize_t pos = ReadPos + offset;\n\t\twhile(pos >= Size) pos -= Size;\n\t\tif(readsize + pos > Size)\n\t\t{\n\t\t\t// readsize + pos obt@̏I[𒴂Ă\n\t\t\t//   ԂubN2\n\t\t\tp1 = pos + Buffer;\n\t\t\tp1size = Size - pos;\n\t\t\tp2 = Buffer;\n\t\t\tp2size = readsize - p1size;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// readsize + pos obt@̏I[𒴂ĂȂ\n\t\t\t//   ԂubN1\n\t\t\tp1 = pos + Buffer;\n\t\t\tp1size = readsize;\n\t\t\tp2 = NULL;\n\t\t\tp2size = 0;\n\t\t}\n\t}\n\n\t//! @brief\tǂݍ݃|C^i߂\n\t//! @param\tadvance\t\ti߂vf\n\t//! @note\t̃\\bh͎ۂ advance < GetDataSize() ł邱ƂmFȂB\n\t//!\t\t\tKvȂΌĂяoŃ`FbN邱ƁB\n\tvoid AdvanceReadPos(size_t advance = 1)\n\t{\n\t\tReadPos += advance;\n\t\tif(ReadPos >= Size) ReadPos -= Size;\n\t\tDataSize -= advance;\n\t}\n\n\t//! @brief\tŏ̗vfԂ\n\t//! @return\tŏ̗vfւ̎Q\n\t//! @note\tŏ̗vfւ̎QƂAĂBvfobt@ɖƂ͖ȗvf\n\t//!\t\t\t(ANZXłȂvf)AĂ̂ŁAOɃobt@ɗvf1ȏ\n\t//!\t\t\t݂邱ƂmF邱ƁB̃\\bh͓ǂݍ݃|C^ړȂB\n\tconst T & GetFirst() const\n\t{\n\t\tsize_t pos = ReadPos;\n\t\treturn Buffer[pos];\n\t}\n\n\t//! @brief\tnԖڂ̗vfԂ\n\t//! @return\tnԖڂ̗vfւ̎Q\n\t//! @note\tnԖڂ̗vfւ̎QƂAĂBvfobt@ɖƂ͈͊O̎\n\t//!\t\t\t͖̓`łB̃\\bh͓ǂݍ݃|C^ړȂB\n\tconst T & GetAt(size_t n) const\n\t{\n\t\tsize_t pos = ReadPos + n;\n\t\twhile(pos >= Size) pos -= Size;\n\t\treturn Buffer[pos];\n\t}\n\n\t//! @brief\tobt@ɏނ߂̃|C^𓾂\n\t//! @param\twritesize ݂f[^ ( 1 ȏ̐; 0 nȂ )\n\t//! @param\tp1\t\tubN1̐擪ւ̃|C^i[邽߂̕ϐ\n\t//! @param\tp1size\tp1̕\\ubÑTCY\n\t//! @param\tp2\t\tubN2̐擪ւ̃|C^i[邽߂̕ϐ(NULL蓾)\n\t//! @param\tp2size\tp2̕\\ubÑTCY(0蓾)\n\t//! @param\toffset\tWritePos ɉZItZbg\n\t//! @note\tGetReadPointer̐QƂ̂\n\tvoid GetWritePointer(size_t writesize,\n\t\t\t\t\t\tT * & p1, size_t &p1size,\n\t\t\t\t\t\tT * & p2, size_t &p2size,\n\t\t\t\t\t\tptrdiff_t offset = 0)\n\t{\n\t\tsize_t pos = WritePos + offset;\n\t\twhile(pos >= Size) pos -= Size;\n\t\tif(writesize + pos > Size)\n\t\t{\n\t\t\t// writesize + pos obt@̏I[𒴂Ă\n\t\t\t//   ԂubN2\n\t\t\tp1 = pos + Buffer;\n\t\t\tp1size = Size - pos;\n\t\t\tp2 = Buffer;\n\t\t\tp2size = writesize - p1size;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// writesize + pos obt@̏I[𒴂ĂȂ\n\t\t\t//   ԂubN1\n\t\t\tp1 = pos + Buffer;\n\t\t\tp1size = writesize;\n\t\t\tp2 = NULL;\n\t\t\tp2size = 0;\n\t\t}\n\t}\n\n\t//! @brief\t݃|C^i߂\n\t//! @param\tadvance\t\ti߂vf\n\t//! @note\t̃\\bh͎ۂ advance < GetFreeSize() ł邱ƂmFȂB\n\t//!\t\t\tKvȂΌĂяoŃ`FbN邱ƁB\n\tvoid AdvanceWritePos(size_t advance = 1)\n\t{\n\t\tWritePos += advance;\n\t\tif(WritePos >= Size) WritePos -= Size;\n\t\tDataSize += advance;\n\t}\n\n\t//! @brief\t݃|C^i߁Aobt@ӂꂽ擪̂Ă\n\t//! @param\tadvance\t\ti߂vf\n\t//! @note\tAdvanceWritePos ƈقȂAobt@ӂꂽAf[^̐擪̂ĂB\n\tvoid AdvanceWritePosWithDiscard(size_t advance = 1)\n\t{\n\t\tWritePos += advance;\n\t\tif(WritePos >= Size) WritePos -= Size;\n\t\tDataSize += advance;\n\t\tif(DataSize > Size)\n\t\t{\n\t\t\tAdvanceReadPos(DataSize - Size);\n\t\t}\n\t}\n\n\t//! @brief\t݈ʒu̗vfԂ\n\t//! @return\t݈ʒu̗vfւ̎Q\n\t//! @note\t݈ʒu̗vfւ̎QƂAĂB̃\\bh̓obt@ɋ\n\t//!\t\t\t邩ǂ̃`FbN͍sȂ̂Œӂ邱ƁB\n\t//!\t\t\t̃\\bh̓obt@݈̏ʒuړȂB\n\tT & GetLast()\n\t{\n\t\treturn Buffer[WritePos];\n\t}\n};\n\n#endif\n"
  },
  {
    "path": "src/core/sound/SoundBufferBaseIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Sound Buffer Base interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"SoundBufferBaseIntf.h\"\n#include \"MsgIntf.h\"\n#include \"EventIntf.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_SoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_BaseSoundBuffer::tTJSNI_BaseSoundBuffer()\n{\n\tInFading = false;\n\tCanDeliverEvents = true;\n\tOwner = NULL;\n\tActionOwner.Object = ActionOwner.ObjThis = NULL;\n\tStatus = ssUnload;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BaseSoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tActionOwner = param[0]->AsObjectClosure();\n\tOwner = tjs_obj;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseSoundBuffer::Invalidate()\n{\n\tCanDeliverEvents = false;\n\tTVPCancelSourceEvents(Owner);\n\tOwner = NULL;\n\n\tActionOwner.Release();\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_BaseSoundBuffer::GetStatusString() const\n{\n\tstatic ttstr unload(TJS_W(\"unload\"));\n\tstatic ttstr play(TJS_W(\"play\"));\n\tstatic ttstr stop(TJS_W(\"stop\"));\n\tstatic ttstr unknown(TJS_W(\"unknown\"));\n\n\tswitch(Status)\n\t{\n\tcase ssUnload:\treturn unload;\n\tcase ssPlay:\treturn play;\n\tcase ssStop:\treturn stop;\n\tdefault:\t\treturn unknown;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseSoundBuffer::SetStatus(tTVPSoundStatus s)\n{\n\tif(Status != s)\n\t{\n\t\tStatus = s;\n\n\t\tif(Owner)\n\t\t{\n\t\t\t// Cancel Previous un-delivered Events\n\t\t\tTVPCancelSourceEvents(Owner);\n\n\t\t\t// fire\n\t\t\tif(CanDeliverEvents)\n\t\t\t{\n\t\t\t\t// fire onStatusChanged event\n\t\t\t\ttTJSVariant param(GetStatusString());\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onStatusChanged\"));\n\t\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE,\n\t\t\t\t\t1, &param);\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseSoundBuffer::SetStatusAsync(tTVPSoundStatus s)\n{\n\t// asynchronous version of SetStatus\n\t// the event may not be delivered immediately.\n\n\tif(Status != s)\n\t{\n\t\tStatus = s;\n\n\t\tif(CanDeliverEvents)\n\t\t{\n\t\t\t// fire onStatusChanged event\n\t\t\tif(Owner)\n\t\t\t{\n\t\t\t\ttTJSVariant param(GetStatusString());\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onStatusChanged\"));\n\t\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_POST,\n\t\t\t\t\t1, &param);\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseSoundBuffer::TimerBeatHandler()\n{\n\t// fade handling\n\n\tif(!Owner) return;   // \"Owner\" indicates the owner object is valid\n\n\tif(!InFading) return;\n\n\tif(BlankLeft)\n\t{\n\t\tBlankLeft -= TVP_SB_BEAT_INTERVAL;\n\t\tif(BlankLeft < 0) BlankLeft = 0;\n\t}\n\telse if(FadeCount)\n\t{\n\t\tif(FadeCount == 1)\n\t\t{\n\t\t\tStopFade(true, true);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tFadeCount--;\n\t\t\ttjs_int v;\n\t\t\tv = GetVolume();\n\t\t\tv += DeltaVolume;\n\t\t\tif(v<0) v = 0;\n\t\t\tif(v>100000) v = 100000;\n\t\t\tSetVolume(v);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseSoundBuffer::Fade(tjs_int to, tjs_int time, tjs_int blanktime)\n{\n\t// start fading\n\n\tif(!Owner) return;\n\n\tif(time<=0 || blanktime <0)\n\t{\n\t\tTVPThrowExceptionMessage(TVPInvalidParam);\n\t}\n\n\t// stop current fade\n\tif(InFading) StopFade(false, false);\n\n\t// set some parameters\n\tDeltaVolume = (to - GetVolume()) * TVP_SB_BEAT_INTERVAL / time;\n\tTargetVolume = to;\n\tFadeCount = time / TVP_SB_BEAT_INTERVAL;\n\tBlankLeft = blanktime;\n\tInFading = true;\n\tif(FadeCount == 0 && BlankLeft == 0) StopFade(false, true);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseSoundBuffer::StopFade(bool async, bool settargetvol)\n{\n\t// stop fading\n\n\tif(!Owner) return;\n\n\tif(InFading)\n\t{\n\t\tInFading = false;\n\n\t\tif(settargetvol) SetVolume(TargetVolume);\n\n\t\t// post \"onFadeCompleted\" event to the owner\n\t\tif(CanDeliverEvents)\n\t\t{\n\t\t\tstatic ttstr eventname(TJS_W(\"onFadeCompleted\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\t\tasync?TVP_EPT_POST:TVP_EPT_IMMEDIATE, 0, NULL);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/sound/SoundBufferBaseIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Sound Buffer Base interface\n//---------------------------------------------------------------------------\n#ifndef SoundBufferBaseIntfH\n#define SoundBufferBaseIntfH\n\n#include \"tjsNative.h\"\n\n\n//---------------------------------------------------------------------------\n// tTVPSoundStatus\n//---------------------------------------------------------------------------\nenum tTVPSoundStatus\n{\n\tssUnload, // data is not specified\n\tssStop, // stop\n\tssPlay, // play\n\tssPause, // pause\n\tssReady, // ready\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseSoundBuffer\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseSoundBuffer : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\tfriend class tTVPSoundBufferTimerDispatcher;\n\npublic:\n\ttTJSNI_BaseSoundBuffer();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\n\tiTJSDispatch2 *Owner; // owner object\n\ttTJSVariantClosure ActionOwner; // object to send action\n\ttTVPSoundStatus Status; // status\n\n\t// volume functions ( implement this in child classes )\n\t// tTJSNI_BaseSoundBuffer/tTJSNI_SoundBuffer manage this when fading the\n\t// volume.\n\tvirtual void SetVolume(tjs_int i) = 0;\n\tvirtual tjs_int GetVolume() const = 0;\n\npublic:\n\tttstr GetStatusString() const;\n\nprotected:\n\tbool CanDeliverEvents;\n\tvoid SetStatus(tTVPSoundStatus s);\n\tvoid SetStatusAsync(tTVPSoundStatus s);\n\npublic:\n\ttTVPSoundStatus GetStatus() const { return Status; }\n\n\npublic:\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n\n\t//-- fading stuff -----------------------------------------------------\nprotected:\n\tvirtual void TimerBeatHandler();\n\t\t// call this in tTJSNI_SoundBuffer periodically.\n\t\t// interval time must be declered as TVP_SB_BEAT_INTERVAL in ms.\n\t\t// accuracy is so not be required.\n\nprivate:\n\tbool InFading;\n\ttjs_int TargetVolume; // distination volume\n\ttjs_int DeltaVolume; // delta volume for each interval\n\ttjs_int FadeCount; // beat count over fading\n\ttjs_int BlankLeft; // blank time until fading\n\npublic:\n\tvoid Fade(tjs_int to, tjs_int time, tjs_int blanktime);\n\tvoid StopFade(bool async, bool settargetvol);\n\n};\n\n//---------------------------------------------------------------------------\n\n#include \"SoundBufferBaseImpl.h\"\n\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/sound/VorbisWaveDecoder.cpp",
    "content": "#include \"vorbis/vorbisfile.h\"\n#include \"VorbisWaveDecoder.h\"\n\n#include <math.h>\n#include <string.h>\n#include <stdlib.h>\n#include \"WaveIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"StorageIntf.h\"\n#include \"DebugIntf.h\"\n#include <algorithm>\n\nstatic const bool FloatExtraction = false; // true if output format is IEEE 32-bit float\n\n#define WARN_OLD_VORBIS_DATE 20020717\n// warn if the stream is generated by old vorbis encoder earlier than this\n#define WARN_PREFER_ENCODER_VERSION \"Vorbis encoder 1.0 (dated 2002/07/17) or later is recommended.\"\nstatic bool OldEncoderWarned = false;\n//static LONG AllocCount = 0; // memory block allocation count for decoder\n\n//static bool Look_Replay_Gain = false; // whether to look replay gain information\n//static bool Use_Album_Gain = false; // whether to use album gain, otherwise use track gain\n\nclass VorbisWaveDecoder : public tTVPWaveDecoder // decoder interface\n{\n    bool InputFileInit; // whether InputFile is inited\n    OggVorbis_File InputFile; // OggVorbis_File instance\n    tTJSBinaryStream *InputStream; // input stream\n    tTVPWaveFormat Format; // output PCM format\n    int CurrentSection; // current section in vorbis stream\n\tint pcmsize;\n\npublic:\n    VorbisWaveDecoder() : InputFileInit(false), InputStream(nullptr), CurrentSection(-1) {\n\t\tpcmsize = FloatExtraction ? 4 : 2;\n\t}\n    ~VorbisWaveDecoder() {\n        if(InputFileInit)\n        {\n            ov_clear(&InputFile);\n            InputFileInit = false;\n        }\n        if(InputStream)\n        {\n            delete InputStream;\n        }\n    }\n\npublic:\n    // ITSSWaveDecoder\n    virtual void GetFormat(tTVPWaveFormat & format) { format = Format; }\n    virtual bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered);\n    virtual bool SetPosition(tjs_uint64 samplepos);\n\tvirtual bool DesiredFormat(const tTVPWaveFormat & format) {\n\t\tif (format.IsFloat == Format.IsFloat) return false;\n\t\tif (format.IsFloat) {\n\t\t\tpcmsize = 4;\n\t\t\tFormat.IsFloat = true;\n\t\t\tFormat.BitsPerSample = 32;\n\t\t\tFormat.BytesPerSample = 4;\n\t\t} else {\n\t\t\tpcmsize = 2;\n\t\t\tFormat.IsFloat = false;\n\t\t\tFormat.BitsPerSample = 16;\n\t\t\tFormat.BytesPerSample = 2;\n\t\t}\n\t\treturn true;\n\t}\n\n    // others\n    bool SetStream(const ttstr & storagename);\n\nprivate:\n    size_t static read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {\n        VorbisWaveDecoder * decoder = (VorbisWaveDecoder*)datasource;\n        if(!decoder->InputStream) return 0;\n        return decoder->InputStream->Read(ptr, size * nmemb) / size;\n    }\n    int static seek_func(void *datasource, ogg_int64_t offset, int whence){\n        VorbisWaveDecoder * decoder = (VorbisWaveDecoder*)datasource;\n        if(!decoder->InputStream) return -1;\n\n        tjs_uint64 result;\n        int seek_type = TJS_BS_SEEK_SET;\n\n        switch(whence)\n        {\n        case SEEK_SET:\n            seek_type = TJS_BS_SEEK_SET;\n            break;\n        case SEEK_CUR:\n            seek_type = TJS_BS_SEEK_CUR;\n            break;\n        case SEEK_END:\n            seek_type = TJS_BS_SEEK_END;\n            break;\n        }\n\n        result = decoder->InputStream->Seek(offset, seek_type);\n        return 0;\n    }\n    int static close_func(void *datasource) {\n        VorbisWaveDecoder * decoder = (VorbisWaveDecoder*)datasource;\n        if(!decoder->InputStream) return EOF;\n        delete decoder->InputStream;\n        decoder->InputStream = NULL;\n        return 0;\n    }\n    long static tell_func(void *datasource) {\n        VorbisWaveDecoder * decoder = (VorbisWaveDecoder*)datasource;\n        if(!decoder->InputStream) return EOF;\n        return decoder->InputStream->Seek(0, TJS_BS_SEEK_CUR);\n    }\n};\n\ntTVPWaveDecoder * VorbisWaveDecoderCreator::Create(const ttstr & storagename, const ttstr & extension) {\n    static ttstr strext = TJS_W(\".ogg\");\n    VorbisWaveDecoder * decoder = nullptr;\n\tif (extension == strext) {\n        decoder = new VorbisWaveDecoder();\n        if(!decoder->SetStream(storagename)) {\n\t\t\tdelete decoder;\n            decoder = nullptr;\n        }\n    }\n    return decoder;\n}\n\nbool VorbisWaveDecoder::Render( void *buf, tjs_uint bufsamplelen, tjs_uint& rendered )\n{\n    // render output PCM\n    if(!InputFileInit) return false; // InputFile is yet not inited\n\n    int pos = 0; // decoded PCM (in bytes)\n\tif (Format.IsFloat) {\n\t\tint remain = bufsamplelen;\n\t\tfloat *p = (float*)buf;\n\t\twhile (remain)\n\t\t{\n\t\t\t//float *p = (float*)buf;\n\t\t\tint samples;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tfloat **pcm; int current_section;\n\t\t\t\tsamples = ov_read_float(&InputFile, &pcm, remain, &current_section);\n\t\t\t\tfor (int j = 0; j < samples; j++)\n\t\t\t\t\tfor (int i = 0; i < Format.Channels; i++){\n\t\t\t\t\t\t*p ++ = pcm[i][j];\n\t\t\t\t\t}\n\t\t\t} while (samples < 0); // ov_read would return a negative number\n\t\t\t// if the decoding is not ready\n\t\t\tif (samples == 0) break;\n\t\t\tpos += samples;\n\t\t\tremain -= samples;\n\t\t}\n\t} else {\n\t\tint remain = bufsamplelen * Format.Channels * pcmsize; // remaining PCM (in bytes)\n\t\twhile (remain)\n\t\t{\n\t\t\tint res;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tres = ov_read(&InputFile, ((char*)buf + pos), remain,\n\t\t\t\t\t0, pcmsize, 1, &CurrentSection); // decode via ov_read\n\t\t\t} while (res < 0); // ov_read would return a negative number\n\t\t\t// if the decoding is not ready\n\t\t\tif (res == 0) break;\n\t\t\tpos += res;\n\t\t\tremain -= res;\n\t\t}\n\t\tpos /= (Format.Channels * pcmsize); // convert to PCM position\n\t}\n\n    rendered = pos; // return rendered PCM samples\n\n    return (unsigned int)pos >= bufsamplelen; //if the decoding is ended\n}\n\nbool VorbisWaveDecoder::SetPosition( tjs_uint64 samplepos )\n{\n    // set PCM position (seek)\n    if(!InputFileInit) return false;\n\n    if(0 != ov_pcm_seek(&InputFile, samplepos))\n    {\n        return false;\n    }\n\n    return true;\n}\n\nbool VorbisWaveDecoder::SetStream( const ttstr & url )\n{\n    // set input stream\n    InputStream = TVPCreateStream(url, TJS_BS_READ);\n    if(!InputStream) return false;\n\n    ov_callbacks callbacks = {read_func, seek_func, close_func, tell_func};\n    // callback functions\n\n    // open input stream via ov_open_callbacks\n    if(ov_open_callbacks(this, &InputFile, NULL, 0, callbacks) < 0)\n    {\n        // error!\n        delete InputStream;\n        InputStream = NULL;\n        return false;\n    }\n\n    InputFileInit = true;\n\n    // retrieve PCM information\n    vorbis_info *vi;\n    vi = ov_info(&InputFile, -1);\n    if(!vi)\n    {\n        return false;\n    }\n\n    // set Format up\n    Format.BitsPerSample = FloatExtraction ? 32 :  16;\n    Format.BytesPerSample = Format.BitsPerSample / 8;\n    Format.Channels = vi->channels;\n    Format.IsFloat = FloatExtraction;\n    Format.SamplesPerSec = vi->rate;\n    Format.Seekable = 2;\n    Format.SpeakerConfig = 0;\n//\tFormat.Signed = true;\n//\tFormat.BigEndian = false;\n\n    ogg_int64_t pcmtotal = ov_pcm_total(&InputFile, -1); // PCM total samples\n    if(pcmtotal<0) pcmtotal = 0;\n    Format.TotalSamples = pcmtotal;\n\n    double timetotal = ov_time_total(&InputFile, -1); // total time in sec.\n    if(timetotal<0) Format.TotalTime = 0; else Format.TotalTime = timetotal * 1000.0;\n\n    // check old vorbis stream, which is generated by old encoder.\n    if(!OldEncoderWarned)\n    {\n        vorbis_comment *vc = ov_comment(&InputFile, -1);\n        if(vc->vendor)\n        {\n            const char * vorbis_date = strstr(vc->vendor, \"libVorbis I \");\n            if(vorbis_date)\n            {\n                int date = atoi(vorbis_date + 12);\n                if(date < WARN_OLD_VORBIS_DATE)\n                {\n                    OldEncoderWarned = true;\n                    TVPAddLog(TJS_W(\"wuvorbis: warning: The Vorbis stream \\\"\") + ttstr(url) + TJS_W(\"\\\" seems to be generated by old Vorbis encoder [\") + \n                        ttstr(vc->vendor) + TJS_W(\"]. Check that your encoder is new enough, unless you prefer the old encoder. The old stream can still be decoded, but \") + ttstr(WARN_PREFER_ENCODER_VERSION) );\n                }\n            }\n        }\n    }\n\n//     if(Look_Replay_Gain)\n//     {\n//         for(int i = 0; i < InputFile.links; i++)\n//         {\n//             // for each stream\n//             float gain = 1.0;\n//             vorbis_comment *vc = ov_comment(&InputFile, i);\n//             const char * track = vorbis_comment_query(vc, \"replaygain_track_gain\", 0);\n//             const char * album = vorbis_comment_query(vc, \"replaygain_album_gain\", 0);\n// \n//             const char * sel = Use_Album_Gain ? ( album ? album : track ) : track;\n//             if(sel)\n//             {\n//                 float db = (float)atof(sel); // in db\n//                 gain *= (float)pow(10.0, db / 20); // convert db to multiplier\n//             }\n// \n//             vorbis_info_set_global_gain(ov_info(&InputFile, i)->, gain);\n//         }\n//     }\n\n    return true;\n}\n\n#include \"opus/opusfile.h\"\n\nclass OpusWaveDecoder : public tTVPWaveDecoder // decoder interface\n{\n    OggOpusFile *InputFile; // OggOpusFile instance\n    tTJSBinaryStream *InputStream; // input stream\n    tTVPWaveFormat Format; // output PCM format\n\topus_int16 *Buffer, *pBuffer;\n\tint BufferRemain; // in samples\n\nprivate:\n    int static read_func(void *datasource, unsigned char *ptr, int size) {\n        OpusWaveDecoder * decoder = (OpusWaveDecoder*)datasource;\n        if(!decoder->InputStream) return -1;\n        return decoder->InputStream->Read(ptr, size);\n    }\n\tint static seek_func(void *datasource, opus_int64 offset, int whence){\n        OpusWaveDecoder * decoder = (OpusWaveDecoder*)datasource;\n        if(!decoder->InputStream) return -1;\n\n        tjs_uint64 result;\n        int seek_type = TJS_BS_SEEK_SET;\n\n        switch(whence)\n        {\n        case SEEK_SET:\n            seek_type = TJS_BS_SEEK_SET;\n            break;\n        case SEEK_CUR:\n            seek_type = TJS_BS_SEEK_CUR;\n            break;\n        case SEEK_END:\n            seek_type = TJS_BS_SEEK_END;\n            break;\n        }\n\n        result = decoder->InputStream->Seek(offset, seek_type);\n        return 0;\n    }\n    int static close_func(void *datasource) {\n        OpusWaveDecoder * decoder = (OpusWaveDecoder*)datasource;\n        if(!decoder->InputStream) return EOF;\n        delete decoder->InputStream;\n        decoder->InputStream = NULL;\n        return 0;\n    }\n    opus_int64 static tell_func(void *datasource) {\n        OpusWaveDecoder * decoder = (OpusWaveDecoder*)datasource;\n        if(!decoder->InputStream) return EOF;\n        return decoder->InputStream->GetPosition();\n    }\n\npublic:\n\tOpusWaveDecoder() : InputFile(nullptr), InputStream(nullptr), Buffer(nullptr) {}\n    ~OpusWaveDecoder() {\n        if(InputFile)\n        {\n            op_free(InputFile);\n            InputFile = nullptr;\n        }\n        if(InputStream)\n        {\n            delete InputStream;\n        }\n\t\tif (Buffer) {\n\t\t\tdelete[]Buffer;\n\t\t}\n    }\n\n\tint BufferRead(opus_int16 *buf, int samples_to_read)\n\t{\n\t\tint res = std::min(BufferRemain, samples_to_read);\n\t\tmemcpy(buf, pBuffer, res * Format.Channels * sizeof(opus_int16));\n\t\tpBuffer += res * Format.Channels;\n\t\tBufferRemain -= res;\n\t\tif (BufferRemain <= 0) pBuffer = nullptr;\n\t\treturn res;\n\t}\n\npublic:\n    // ITSSWaveDecoder\n    virtual void GetFormat(tTVPWaveFormat & format) { format = Format; }\n\tvirtual bool Render(void *_buf, tjs_uint bufsamplelen, tjs_uint& rendered) {\n\t\t// render output PCM\n\t\tif (!InputFile) return false; // InputFile is yet not inited\n\t\topus_int16 *buf = (opus_int16*)_buf;\n\t\tint res;\n\t\tint pos = 0; // decoded PCM (in sample)\n\t\tint remain = bufsamplelen; // remaining PCM (in sample)\n\n\t\twhile (remain)\n\t\t{\n\t\t\tif (pBuffer) {\n\t\t\t\tres = BufferRead(buf, remain);\n\t\t\t} else if (remain >= 5760) {\n\t\t\t\tres = op_read(InputFile, buf, remain * Format.Channels, nullptr); // decode via ov_read\n\t\t\t} else {\n\t\t\t\tres = op_read(InputFile, Buffer, 5760 * Format.Channels, nullptr);\n\t\t\t\tif (res > remain) {\n\t\t\t\t\tmemcpy(buf, Buffer, remain * Format.Channels * sizeof(opus_int16));\n\t\t\t\t\tBufferRemain = res - remain;\n\t\t\t\t\tpBuffer = Buffer + remain * Format.Channels;\n\t\t\t\t\tres = remain;\n\t\t\t\t} else {\n\t\t\t\t\tmemcpy(buf, Buffer, res * Format.Channels * sizeof(opus_int16));\n\t\t\t\t}\n\t\t\t}\n\t\t\t// if the decoding is not ready\n\t\t\tif (res <= 0) break;\n\t\t\tpos += res;\n\t\t\tremain -= res;\n\t\t\tbuf += res * Format.Channels;\n\t\t}\n\n\t\trendered = pos; // return rendered PCM samples\n\n\t\treturn !remain; //if the decoding is ended\n    }\n    virtual bool SetPosition(tjs_uint64 samplepos) {\n        // set PCM position (seek)\n        if(!InputFile) return false;\n\n        if(0 != op_pcm_seek(InputFile, samplepos))\n        {\n            return false;\n        }\n\n        return true;\n    }\n\n    // others\n    bool SetStream(const ttstr & url) {\n        // set input stream\n        InputStream = TVPCreateStream(url, TJS_BS_READ);\n\t\tif (!InputStream) return false;\n\n        OpusFileCallbacks callbacks = {read_func, seek_func, tell_func, close_func};\n        // callback functions\n\n        // open input stream via ov_open_callbacks\n        int ret;\n\t\tInputFile = op_open_callbacks(this, &callbacks, NULL, 0, &ret);\n\t\tif (!InputFile)\n        {\n            // error!\n            delete InputStream;\n            InputStream = NULL;\n\t\t\treturn false;\n        }\n\n        // set Format up\n        Format.BitsPerSample = 16;\n        Format.BytesPerSample = Format.BitsPerSample / 8;\n        Format.Channels = op_channel_count(InputFile, -1);\n        Format.IsFloat = false;\n        Format.SamplesPerSec = 48000;\n        Format.Seekable = op_seekable(InputFile) ? 0 : 2;\n        Format.SpeakerConfig = 0;\n// \t\tFormat.Signed = true;\n// \t\tFormat.BigEndian = false;\n\n        ogg_int64_t pcmtotal = op_pcm_total(InputFile, -1); // PCM total samples\n        if(pcmtotal<0) pcmtotal = 0;\n        Format.TotalSamples = pcmtotal;\n        Format.TotalTime = pcmtotal * (1000.0 / 48000);\n\n\t\tBuffer = new opus_int16[Format.Channels * 5760]; // 120 ms in 48kHz\n\t\tBufferRemain = 0; pBuffer = nullptr;\n\n        return true;\n    }\n};\n\ntTVPWaveDecoder * OpusWaveDecoderCreator::Create(const ttstr & storagename, const ttstr & extension) {\n    OpusWaveDecoder * decoder = nullptr;\n\tdecoder = new OpusWaveDecoder();\n\tif (!decoder->SetStream(storagename)) {\n        delete decoder;\n        decoder = nullptr;\n    }\n    return decoder;\n}\n"
  },
  {
    "path": "src/core/sound/VorbisWaveDecoder.h",
    "content": "#pragma once\n#include \"WaveIntf.h\"\n\nclass VorbisWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n    //VorbisWaveDecoderCreator() { TVPRegisterWaveDecoderCreator(this); }\n    tTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension);\n};\n\nclass OpusWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n    //VorbisWaveDecoderCreator() { TVPRegisterWaveDecoderCreator(this); }\n    tTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension);\n};"
  },
  {
    "path": "src/core/sound/WaveFormatConverter.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief WavetH[}bgRo[^̃RA֐\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * int16float32ϊ\n */\nstatic void PCMConvertLoopInt16ToFloat32_c(void * dest, const void * src, size_t numsamples)\n{\n\tfloat * d = static_cast<float*>(dest);\n\tconst tjs_int16 * s = static_cast<const tjs_int16*>(src);\n\tconst tjs_int16 * s_lim = s + numsamples;\n\n\twhile(s < s_lim)\n\t{\n\t\t*d = *s * (1.0f/32768.0f);\n\t\td += 1; s += 1;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * float32int16ϊ\n */\nstatic void PCMConvertLoopFloat32ToInt16_c(void * dest, const void * src, size_t numsamples)\n{\n\ttjs_uint16 * d = static_cast<tjs_uint16*>(dest);\n\tconst float * s = static_cast<const float*>(src);\n\tconst float * s_lim = s + numsamples;\n\n\twhile(s < s_lim)\n\t{\n\t\tfloat v = *s * 32767.0f;\n\t\t*d = \n\t\t\t v > (float) 32767 ?  32767 :\n\t\t\t v < (float)-32768 ? -32768 :\n\t\t\t \tv < 0 ? (tjs_int16)(v - 0.5) : (tjs_int16)(v + 0.5);\n\t\td += 1; s += 1;\n\t}\n}\n//---------------------------------------------------------------------------\n\nvoid(*PCMConvertLoopInt16ToFloat32)(void * dest, const void * src, size_t numsamples) = PCMConvertLoopInt16ToFloat32_c;\nvoid(*PCMConvertLoopFloat32ToInt16)(void * dest, const void * src, size_t numsamples) = PCMConvertLoopFloat32ToInt16_c;\n\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/WaveFormatConverter_SSE.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief WavetH[}bgRo[^̃RA֐\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n#include \"MathAlgorithms.h\"\n#if defined(_M_IX86)||defined(_M_X64)\n//---------------------------------------------------------------------------\n\n_ALIGN16(const float) TJS_V_VEC_REDUCE[4] =\n\t{ 1.0f/32767.0f, 1.0f/32767.0f, 1.0f/32767.0f, 1.0f/32767.0f };\n_ALIGN16(const float) TJS_V_VEC_MAGNIFY[4] =\n\t{ 32767.0f, 32767.0f, 32767.0f, 32767.0f };\n\nstatic inline void Int16ToFloat32_sse2( float * d, const tjs_int16 * s ) {\n\t__m128i src = _mm_loadu_si128((__m128i const*)s);\n\t__m128i ext_val = _mm_cmpgt_epi16(_mm_setzero_si128(), src);\n\t__m128 mlo = _mm_cvtepi32_ps(_mm_unpacklo_epi16(src, ext_val) );\n\t__m128 mhi = _mm_cvtepi32_ps(_mm_unpackhi_epi16(src, ext_val) );\n\t_mm_store_ps(d+0, _mm_mul_ps(mlo,PM128(TJS_V_VEC_REDUCE)) );\n\t_mm_store_ps(d+4, _mm_mul_ps(mhi,PM128(TJS_V_VEC_REDUCE)) );\n}\nstatic inline void Int16ToFloat32_sse41( float * d, const tjs_int16 * s ) {\n\t__m128 mlo = _mm_cvtepi32_ps(_mm_cvtepi16_epi32( _mm_loadl_epi64( (__m128i const*)(s+0) ) ) );\n\t__m128 mhi = _mm_cvtepi32_ps(_mm_cvtepi16_epi32( _mm_loadl_epi64( (__m128i const*)(s+4) ) ));\n\t_mm_store_ps(d+0, _mm_mul_ps(mlo,PM128(TJS_V_VEC_REDUCE)) );\n\t_mm_store_ps(d+4, _mm_mul_ps(mhi,PM128(TJS_V_VEC_REDUCE)) );\n}\nstatic inline void Float32ToInt16_sse2( tjs_uint16 * d, const float * s ) {\n\t__m128i mlo = _mm_cvtps_epi32( _mm_mul_ps( *(__m128*)(s + 0), PM128(TJS_V_VEC_MAGNIFY) ) );\n\t__m128i mhi = _mm_cvtps_epi32( _mm_mul_ps( *(__m128*)(s + 4), PM128(TJS_V_VEC_MAGNIFY) ) );\n\t_mm_store_si128( (__m128i *)d, _mm_packs_epi32(mlo, mlo) );\n}\n#ifdef TJS_64BIT_OS\n// 64bit ̎ MMX g킸ASSE2/SSE ŏ\n#define Int16ToFloat32_sse Int16ToFloat32_sse2\n#define Float32ToInt16_sse Float32ToInt16_sse2\n#else\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4799)\t// ignore _mm_empty request.\n#endif\nstatic inline __m128 _mm64_cvtpi16_ps(__m64 a) {\n  __m128 tmp;\n  __m64  ext_val = _mm_cmpgt_pi16(_mm_setzero_si64(), a);\n  tmp = _mm_cvtpi32_ps(_mm_setzero_ps(), _mm_unpackhi_pi16(a, ext_val));\n  return(_mm_cvtpi32_ps(_mm_movelh_ps(tmp, tmp), \n                        _mm_unpacklo_pi16(a, ext_val)));\n}\nstatic inline void Int16ToFloat32_sse( float * d, const tjs_int16 * s ) {\n\t*(__m128*)(d + 0) = _mm_mul_ps(_mm64_cvtpi16_ps(*(__m64*)(s+0)), PM128(TJS_V_VEC_REDUCE));\n\t*(__m128*)(d + 4) = _mm_mul_ps(_mm64_cvtpi16_ps(*(__m64*)(s+4)), PM128(TJS_V_VEC_REDUCE));\n}\nstatic inline void Float32ToInt16_sse( tjs_uint16 * d, const float * s ) {\n\t*(__m64*)(d + 0) = _mm_cvtps_pi16( _mm_mul_ps(*(__m128*)(s + 0), PM128(TJS_V_VEC_MAGNIFY)) );\n\t*(__m64*)(d + 4) = _mm_cvtps_pi16( _mm_mul_ps(*(__m128*)(s + 4), PM128(TJS_V_VEC_MAGNIFY)) );\n}\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n#endif\n\n//---------------------------------------------------------------------------\n/**\n * int16float32ϊ\n */\nvoid PCMConvertLoopInt16ToFloat32_sse(void * __restrict dest, const void * __restrict src, size_t numsamples)\n{\n\tfloat * d = static_cast<float*>(dest);\n\tconst tjs_int16 * s = static_cast<const tjs_int16*>(src);\n\tsize_t n;\n\n\t// d ACg܂ň\n\tfor(n = 0  ; n < numsamples && !IsAlignedTo128bits(d+n); n ++)\n\t{\n\t\td[n] = s[n] * (1.0f/32767.0f);\n\t}\n\n\t// C̕\n\tif(numsamples >= 8)\n\t{\n\t\tfor(       ; n < numsamples - 7; n += 8)\n\t\t{\n\t\t\tInt16ToFloat32_sse( d+n, s+n );\n\t\t}\n#ifndef _M_X64\n\t\t_mm_empty();\n#endif\n\t}\n\n\t// ̂\n\tfor(       ; n < numsamples; n ++)\n\t{\n\t\td[n] = s[n] * (1.0f/32767.0f);\n\t}\n}\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * float32int16ϊ\n */\nvoid PCMConvertLoopFloat32ToInt16_sse(void * __restrict dest, const void * __restrict src, size_t numsamples)\n{\n\ttjs_uint16 * d = reinterpret_cast<tjs_uint16*>(dest);\n\tconst float * s = reinterpret_cast<const float*>(src);\n\tsize_t n;\n\n\t// s ACg܂ň\n\tfor(n = 0; n < numsamples && !IsAlignedTo128bits(s+n); n ++)\n\t{\n\t\tfloat v = (float)(s[n] * 32767.0);\n\t\td[n] = \n\t\t\t v > (float) 32767 ?  32767 :\n\t\t\t v < (float)-32768 ? -32768 :\n\t\t\t \tv < 0 ? (tjs_int16)(v - 0.5) : (tjs_int16)(v + 0.5);\n\t}\n\n\t// C̕\n\tif(numsamples >= 8)\n\t{\n\t\tSetRoundingModeToNearest_SSE();\n\t\tfor(     ; n < numsamples - 7; n += 8)\n\t\t{\n\t\t\tFloat32ToInt16_sse( d+n, s+n );\n\t\t}\n#ifndef _M_X64\n\t\t_mm_empty();\n#endif\n\t}\n\n\t// ̂\n\tfor(     ; n < numsamples; n ++)\n\t{\n\t\tfloat v = (float)(s[n] * 32767.0);\n\t\td[n] = \n\t\t\t v > (float) 32767 ?  32767 :\n\t\t\t v < (float)-32768 ? -32768 :\n\t\t\t \tv < 0 ? (tjs_int16)(v - 0.5) : (tjs_int16)(v + 0.5);\n\t}\n}\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/sound/WaveIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Player interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"WaveIntf.h\"\n#include \"EventIntf.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"UtilStreams.h\"\n#include \"WaveLoopManager.h\"\n#include \"tjsDictionary.h\"\n#include \"VorbisWaveDecoder.h\"\n#include \"FFWaveDecoder.h\"\n\n\n//---------------------------------------------------------------------------\n// PCM related constants / definitions\n//---------------------------------------------------------------------------\n\n#ifndef WAVE_FORMAT_PCM\n\t#define WAVE_FORMAT_PCM 0x0001\n#endif\n#ifndef WAVE_FORMAT_IEEE_FLOAT\n\t#define WAVE_FORMAT_IEEE_FLOAT 0x0003\n#endif\n#ifndef WAVE_FORMAT_EXTENSIBLE\n\t#define WAVE_FORMAT_EXTENSIBLE 0xFFFE\n#endif\n\n#ifndef SPEAKER_FRONT_LEFT\n// from Windows ksmedia.h\n// speaker config\n\n#define     SPEAKER_FRONT_LEFT              0x1\n#define     SPEAKER_FRONT_RIGHT             0x2\n#define     SPEAKER_FRONT_CENTER            0x4\n#define     SPEAKER_LOW_FREQUENCY           0x8\n#define     SPEAKER_BACK_LEFT               0x10\n#define     SPEAKER_BACK_RIGHT              0x20\n#define     SPEAKER_FRONT_LEFT_OF_CENTER    0x40\n#define     SPEAKER_FRONT_RIGHT_OF_CENTER   0x80\n#define     SPEAKER_BACK_CENTER             0x100\n#define     SPEAKER_SIDE_LEFT               0x200\n#define     SPEAKER_SIDE_RIGHT              0x400\n#define     SPEAKER_TOP_CENTER              0x800\n#define     SPEAKER_TOP_FRONT_LEFT          0x1000\n#define     SPEAKER_TOP_FRONT_CENTER        0x2000\n#define     SPEAKER_TOP_FRONT_RIGHT         0x4000\n#define     SPEAKER_TOP_BACK_LEFT           0x8000\n#define     SPEAKER_TOP_BACK_CENTER         0x10000\n#define     SPEAKER_TOP_BACK_RIGHT          0x20000\n\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// GUIDs used in WAVRFORMATEXTENSIBLE\n//---------------------------------------------------------------------------\ntjs_uint8 TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM[16] =\n{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\n  0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };\ntjs_uint8 TVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT[16] =\n{ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\n  0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };\n//---------------------------------------------------------------------------\n\n\n#include \"DetectCPU.h\"\n//#include \"tvpgl_ia32_intf.h\"\n\n//---------------------------------------------------------------------------\n// CPU specific optimized routine prototypes\n//---------------------------------------------------------------------------\nextern void (*PCMConvertLoopInt16ToFloat32)(void * dest, const void * src, size_t numsamples);\nextern void (*PCMConvertLoopFloat32ToInt16)(void * dest, const void * src, size_t numsamples);\n#if 0\nextern void PCMConvertLoopInt16ToFloat32_sse(void * __restrict dest, const void * __restrict src, size_t numsamples);\nextern void PCMConvertLoopFloat32ToInt16_sse(void * __restrict dest, const void * __restrict src, size_t numsamples);\n#endif\n\n\n//---------------------------------------------------------------------------\n// Wave format convertion routines\n//---------------------------------------------------------------------------\nstatic void TVPConvertFloatPCMTo16bits(tjs_int16 *output, const float *input,\n\ttjs_int channels, tjs_int count, bool downmix)\n{\n\t// convert 32bit float to 16bit integer\n\n\t// float PCM is in range of +1.0 ... 0 ... -1.0\n\t// clip sample which is out of the range.\n\n\tif(!downmix)\n\t{\n\t\ttjs_int total = channels * count;\n#if 0\n\t\tbool use_sse =\n\t\t\t\t(TVPCPUType & TVP_CPU_HAS_MMX) &&\n\t\t\t\t(TVPCPUType & TVP_CPU_HAS_SSE) &&\n\t\t\t\t(TVPCPUType & TVP_CPU_HAS_CMOV);\n\n\t\tif(use_sse)\n\t\t\tPCMConvertLoopFloat32ToInt16_sse(output, input, total);\n\t\telse\n\t\t\tPCMConvertLoopFloat32ToInt16(output, input, total);\n#else\n\t\tPCMConvertLoopFloat32ToInt16(output, input, total);\n#endif\n\t}\n\telse\n\t{\n\t\tfloat nc = 32768.0f / (float)channels;\n\t\twhile(count--)\n\t\t{\n\t\t\ttjs_int n = channels;\n\t\t\tfloat t = 0;\n\t\t\twhile(n--) t += *(input++) * nc;\n\t\t\tif(t > 0)\n\t\t\t{\n\t\t\t\tint i = (int)(t + 0.5);\n\t\t\t\tif(i > 32767) i = 32767;\n\t\t\t\t*(output++) = (tjs_int16)i;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tint i = (int)(t - 0.5);\n\t\t\t\tif(i < -32768) i = -32768;\n\t\t\t\t*(output++) = (tjs_int16)i;\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPConvertIntegerPCMTo16bits(tjs_int16 *output, const void *input,\n\ttjs_int bytespersample,\n\ttjs_int validbits, tjs_int channels, tjs_int count, bool downmix)\n{\n\t// convert integer PCMs to 16bit integer PCM\n#define PROCESS_BY_CHANNELS \\\n\tswitch(channels) \\\n\t{ \\\n\tcase 2: PROCESS(2); break; \\\n\tcase 4: PROCESS(4); break; \\\n\tcase 8: PROCESS(8); break; \\\n\tdefault: PROCESS(channels); break; \\\n\t}\n\n\n#if TJS_HOST_IS_BIG_ENDIAN\n\t#define GET_24BIT(p) (p[2] + (p[1] << 8) + (p[0] << 16))\n#else\n\t#define GET_24BIT(p) (p[0] + (p[1] << 8) + (p[2] << 16))\n#endif\n\n\tif(bytespersample == 1)\n\t{\n\t\t// here assumes that the input 8bit PCM has always 8bit valid data\n\t\tconst tjs_int8 *p = (tjs_int8 *)input;\n\t\tif(!downmix || channels == 1)\n\t\t{\n\t\t\ttjs_int total = channels * count;\n\t\t\twhile(total--)\n\t\t\t\t*(output++) = (tjs_int16)( ((tjs_int)*(p++)-0x80) * 0x100);\n\t\t}\n\t\telse\n\t\t{\n\t\t#define PROCESS(channels) \\\n\t\t\twhile(count--) \\\n\t\t\t{ \\\n\t\t\t\ttjs_int v = 0; \\\n\t\t\t\ttjs_int n = channels; \\\n\t\t\t\twhile(n--) \\\n\t\t\t\t\tv += (tjs_int16)( ((tjs_int)*(p++)-0x80) * 0x100); \\\n\t\t\t\tv = v / channels; \\\n\t\t\t\t*(output++) = (tjs_int16)v; \\\n\t\t\t}\n\t\tPROCESS_BY_CHANNELS\n\t\t#undef PROCESS\n\t\t}\n\t}\n\telse if(bytespersample == 2)\n\t{\n\t\ttjs_uint16 mask =  ~( (1 << (16 - validbits)) - 1);\n\t\tconst tjs_int16 *p = (const tjs_int16 *)input;\n\t\tif(!downmix || channels == 1)\n\t\t{\n\t\t\ttjs_int total = channels * count;\n\t\t\twhile(total--) *(output++) = (tjs_int16)(*(p++) & mask);\n\t\t}\n\t\telse\n\t\t{\n\t\t#define PROCESS(channels) \\\n\t\t\twhile(count--) \\\n\t\t\t{ \\\n\t\t\t\ttjs_int v = 0; \\\n\t\t\t\ttjs_int n = channels; \\\n\t\t\t\twhile(n--) \\\n\t\t\t\t\tv += (tjs_int16)(*(p++) & mask); \\\n\t\t\t\tv = v / channels; \\\n\t\t\t\t*(output++) = (tjs_int16)v; \\\n\t\t\t}\n\t\tPROCESS_BY_CHANNELS\n\t\t#undef PROCESS\n\t\t}\n\t}\n\telse if(bytespersample == 3)\n\t{\n\t\ttjs_uint32 mask = ~( (1 << (24 - validbits)) - 1);\n\t\tconst tjs_uint8 *p = (const tjs_uint8 *)input;\n\n\t\tif(!downmix || channels == 1)\n\t\t{\n\t\t\ttjs_int total = channels * count;\n\t\t\twhile(total--)\n\t\t\t{\n\t\t\t\ttjs_int32 t = GET_24BIT(p);\n\t\t\t\tp += 3;\n\t\t\t\tt |= -(t&0x800000); // extend sign\n\t\t\t\tt &= mask; // apply mask\n\t\t\t\tt >>= 8;\n\t\t\t\t*(output++) = (tjs_int16)t;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t#define PROCESS(channels) \\\n\t\t\twhile(count--) \\\n\t\t\t{ \\\n\t\t\t\ttjs_int v = 0; \\\n\t\t\t\ttjs_int n = channels; \\\n\t\t\t\twhile(n--) \\\n\t\t\t\t{ \\\n\t\t\t\t\ttjs_int32 t = GET_24BIT(p); \\\n\t\t\t\t\tp += 3; \\\n\t\t\t\t\tt |= -(t&0x800000); \\\n\t\t\t\t\tt &= mask; \\\n\t\t\t\t\tt >>= 8; \\\n\t\t\t\t\tv += t; \\\n\t\t\t\t} \\\n\t\t\t\tv = v / channels; \\\n\t\t\t\t*(output++) = (tjs_int16)v; \\\n\t\t\t}\n\t\tPROCESS_BY_CHANNELS\n\t\t#undef PROCESS\n\t\t}\n\t}\n\telse if(bytespersample == 4)\n\t{\n\t\ttjs_int32 mask = ~( (1 << (32 - validbits)) - 1);\n\t\tconst tjs_int32 *p = (const tjs_int32 *)input;\n\t\tif(!downmix || channels == 1)\n\t\t{\n\t\t\ttjs_int total = channels * count;\n\t\t\twhile(total--)\n\t\t\t\t*(output++) = (tjs_int16)((*(p++) & mask) >> 16);\n\t\t}\n\t\telse\n\t\t{\n\t\t#define PROCESS(channels) \\\n\t\t\twhile(count--) \\\n\t\t\t{ \\\n\t\t\t\ttjs_int v = 0; \\\n\t\t\t\ttjs_int n = channels; \\\n\t\t\t\twhile(n--) \\\n\t\t\t\t\tv += (tjs_int16)((*(p++) & mask) >> 16); \\\n\t\t\t\tv = v / channels; \\\n\t\t\t\t*(output++) = (tjs_int16)v; \\\n\t\t\t}\n\t\tPROCESS_BY_CHANNELS\n\t\t#undef PROCESS\n\t\t}\n\t}\n\n#undef PROCESS_BY_CHANNELS\n#undef GET_24BIT\n}\n//---------------------------------------------------------------------------\nvoid TVPConvertPCMTo16bits(tjs_int16 *output, const void *input,\n\ttjs_int channels, tjs_int bytespersample, tjs_int bitspersample, bool isfloat,\n\ttjs_int count, bool downmix)\n{\n\t// cconvert specified format to 16bit PCM\n\n\tif(isfloat)\n\t\tTVPConvertFloatPCMTo16bits(output, (const float *)input, channels, count, downmix);\n\telse\n\t\tTVPConvertIntegerPCMTo16bits(output, input,\n\t\t\tbytespersample, bitspersample, channels, count, downmix);\n}\n//---------------------------------------------------------------------------\nvoid TVPConvertPCMTo16bits(tjs_int16 *output, const void *input,\n\tconst tTVPWaveFormat &format, tjs_int count, bool downmix)\n{\n\t// cconvert specified format to 16bit PCM\n\tTVPConvertPCMTo16bits(output, input, format.Channels, format.BytesPerSample,\n\t\tformat.BitsPerSample, format.IsFloat, count, downmix);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic void TVPConvertFloatPCMToFloat(float *output, const float *input,\n\ttjs_int channels, tjs_int count)\n{\n\t// convert 32bit float to float\n\n\t// yes, acctually, this does nothing.\n\tmemcpy(output, input, sizeof(float)*channels * count);\n}\n//---------------------------------------------------------------------------\nstatic void TVPConvertIntegerPCMToFloat(float *output, const void *input,\n\ttjs_int bytespersample,\n\ttjs_int validbits, tjs_int channels, tjs_int count)\n{\n\t// convert integer PCMs to float PCM\n\n#ifdef TJS_HOST_IS_BIG_ENDIAN\n\t#undef TJS_HOST_IS_BIG_ENDIAN\n#endif\n#if TJS_HOST_IS_BIG_ENDIAN\n\t#define GET_24BIT(p) (p[2] + (p[1] << 8) + (p[0] << 16))\n#else\n\t#define GET_24BIT(p) (p[0] + (p[1] << 8) + (p[2] << 16))\n#endif\n\n\tif(bytespersample == 1)\n\t{\n\t\t// here assumes that the input 8bit PCM has always 8bit valid data\n\t\tconst tjs_int8 *p = (tjs_int8 *)input;\n\t\ttjs_int total = channels * count;\n\t\twhile(total--)\n\t\t\t*(output++) = (float)( ((tjs_int)*(p++)- 0x80) * (1.0 / 128) );\n\t}\n\telse if(bytespersample == 2)\n\t{\n\t\tconst tjs_int16 *p = (const tjs_int16 *)input;\n\t\ttjs_int total = channels * count;\n\n\t\tif(validbits == 16)\n\t\t{\n#if 0\n\t\t\t// most popular\n\t\t\tbool use_sse =\n\t\t\t\t\t(TVPCPUType & TVP_CPU_HAS_MMX) &&\n\t\t\t\t\t(TVPCPUType & TVP_CPU_HAS_SSE) &&\n\t\t\t\t\t(TVPCPUType & TVP_CPU_HAS_CMOV);\n\n\t\t\tif(use_sse)\n\t\t\t\tPCMConvertLoopInt16ToFloat32_sse(output, p, total);\n\t\t\telse\n\t\t\t\tPCMConvertLoopInt16ToFloat32(output, p, total);\n#else\n\t\t\tPCMConvertLoopInt16ToFloat32(output, p, total);\n#endif\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// generic\n\t\t\ttjs_uint16 mask =  ~( (1 << (16 - validbits)) - 1);\n\n\t\t\twhile(total--) *(output++) = (float)((*(p++) & mask) * (1.0 / 32768));\n\t\t}\n\t}\n\telse if(bytespersample == 3)\n\t{\n\t\ttjs_uint32 mask = ~( (1 << (24 - validbits)) - 1);\n\t\tconst tjs_uint8 *p = (const tjs_uint8 *)input;\n\n\t\ttjs_int total = channels * count;\n\t\twhile(total--)\n\t\t{\n\t\t\ttjs_int32 t = GET_24BIT(p);\n\t\t\tp += 3;\n\t\t\tt |= -(t&0x800000); // extend sign\n\t\t\tt &= mask; // apply mask\n\t\t\t*(output++) = (float)(t * (1.0 / (1<<23)));\n\t\t}\n\t}\n\telse if(bytespersample == 4)\n\t{\n\t\ttjs_int32 mask = ~( (1 << (32 - validbits)) - 1);\n\t\tconst tjs_int32 *p = (const tjs_int32 *)input;\n\t\ttjs_int total = channels * count;\n\t\twhile(total--)\n\t\t\t*(output++) = (float)(((*(p++) & mask) >> 0) * (1.0 / (1<<31)));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPConvertPCMToFloat(float *output, const void *input,\n\ttjs_int channels, tjs_int bytespersample, tjs_int bitspersample, bool isfloat,\n\ttjs_int count)\n{\n\t// cconvert specified format to 16bit PCM\n\n\tif(isfloat)\n\t\tTVPConvertFloatPCMToFloat(output, (const float *)input, channels, count);\n\telse\n\t\tTVPConvertIntegerPCMToFloat(output, input,\n\t\t\tbytespersample, bitspersample, channels, count);\n}\n//---------------------------------------------------------------------------\nvoid TVPConvertPCMToFloat(float *output, const void *input,\n\tconst tTVPWaveFormat &format, tjs_int count)\n{\n\t// cconvert specified format to 16bit PCM\n\tTVPConvertPCMToFloat(output, input, format.Channels, format.BytesPerSample,\n\t\tformat.BitsPerSample, format.IsFloat, count);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWD_RIFFWave\n//---------------------------------------------------------------------------\nclass tTVPWD_RIFFWave : public tTVPWaveDecoder\n{\n\ttTJSBinaryStream *Stream;\n\ttTVPWaveFormat Format;\n\ttjs_uint64 DataStart;\n\ttjs_uint64 CurrentPos;\n\ttjs_uint SampleSize;\n\npublic:\n\ttTVPWD_RIFFWave(tTJSBinaryStream *stream, tjs_uint64 datastart,\n\t\tconst tTVPWaveFormat & format);\n\t~tTVPWD_RIFFWave();\n\tvoid GetFormat(tTVPWaveFormat & format);\n\tbool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered);\n\tbool SetPosition(tjs_uint64 samplepos);\n};\n//---------------------------------------------------------------------------\ntTVPWD_RIFFWave::tTVPWD_RIFFWave(tTJSBinaryStream *stream, tjs_uint64 datastart,\n\tconst tTVPWaveFormat & format)\n{\n\tStream = stream;\n\tDataStart = datastart;\n\tFormat = format;\n\tSampleSize = format.BytesPerSample * format.Channels;\n\tCurrentPos = 0;\n\tStream->SetPosition(DataStart);\n}\n//---------------------------------------------------------------------------\ntTVPWD_RIFFWave::~tTVPWD_RIFFWave()\n{\n\tdelete Stream;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWD_RIFFWave::GetFormat(tTVPWaveFormat & format)\n{\n\tformat = Format;\n}\n//---------------------------------------------------------------------------\nbool tTVPWD_RIFFWave::Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered)\n{\n\ttjs_uint64 remain = Format.TotalSamples - CurrentPos;\n\ttjs_uint writesamples = bufsamplelen < remain ? bufsamplelen : (tjs_uint)remain;\n\tif(writesamples == 0)\n\t{\n\t\t// already finished stream or bufsamplelen is zero\n\t\trendered = 0;\n\t\treturn false;\n\t}\n\n\ttjs_uint readsize = writesamples * SampleSize;\n\ttjs_uint read = Stream->Read(buf, readsize);\n\n#if TJS_HOST_IS_BIG_ENDIAN\n\t// endian-ness conversion\n\tif(Format.BytesPerSample == 2)\n\t{\n\t\ttjs_uint16 *p = (tjs_uint16 *)buf;\n\t\ttjs_uint16 *plim = (tjs_uint16 *)( (tjs_uint8*)buf + read);\n\t\twhile(p < plim)\n\t\t{\n\t\t\t*p = (*p>>8) + (*p<<8);\n\t\t\tp++;\n\t\t}\n\t}\n\telse if(Format.BytesPerSample == 3)\n\t{\n\t\ttjs_uint8 *p = (tjs_uint8 *)buf;\n\t\ttjs_uint8 *plim = (tjs_uint8 *)( (tjs_uint8*)buf + read);\n\t\twhile(p < plim)\n\t\t{\n\t\t\ttjs_uint8 tmp = p[0];\n\t\t\tp[0] = p[2];\n\t\t\tp[2] = tmp;\n\t\t\tp += 3;\n\t\t}\n\t}\n\telse if(Format.BytesPerSample == 4)\n\t{\n\t\ttjs_uint32 *p = (tjs_uint32 *)buf;\n\t\ttjs_uint32 *plim = (tjs_uint32 *)( (tjs_uint8*)buf + read);\n\t\twhile(p < plim)\n\t\t{\n\t\t\t*p =\n\t\t\t\t(*p &0xff000000) >> 24 +\n\t\t\t\t(*p &0x00ff0000) >> 8 +\n\t\t\t\t(*p &0x0000ff00) << 8 +\n\t\t\t\t(*p &0x000000ff) << 24;\n\t\t\tp ++;\n\t\t}\n\t}\n#endif\n\n\n\trendered = read / SampleSize;\n\tCurrentPos += rendered;\n\n\tif(read < readsize || writesamples < bufsamplelen)\n\t\treturn false; // read error or end of stream\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWD_RIFFWave::SetPosition(tjs_uint64 samplepos)\n{\n\tif(Format.TotalSamples <= samplepos) return false;\n\n\ttjs_uint64 streampos = DataStart + samplepos * SampleSize;\n\ttjs_uint64 possave = Stream->GetPosition();\n\n\tif(streampos != Stream->Seek(streampos, TJS_BS_SEEK_SET))\n\t{\n\t\t// seek failed\n\t\tStream->Seek(possave, TJS_BS_SEEK_SET);\n\t\treturn false;\n\t}\n\n\tCurrentPos = samplepos;\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// default RIFF Wave Decoder creator\n//---------------------------------------------------------------------------\nclass tTVPWDC_RIFFWave : public tTVPWaveDecoderCreator\n{\npublic:\n\ttTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension);\n};\n//---------------------------------------------------------------------------\nstatic bool TVPFindRIFFChunk(tTVPStreamHolder & stream, const tjs_uint8 *chunk)\n{\n\ttjs_uint8 buf[4];\n\twhile(true)\n\t{\n\t\tif(4 != stream->Read(buf, 4)) return false;\n\t\tif(memcmp(buf, chunk, 4))\n\t\t{\n\t\t\t// skip to next chunk\n\t\t\ttjs_uint32 chunksize = stream->ReadI32LE();\n\t\t\ttjs_int64 next = stream->GetPosition() + chunksize;\n\t\t\tif(next != stream->Seek(next, TJS_BS_SEEK_SET)) return false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPWaveDecoder * tTVPWDC_RIFFWave::Create(const ttstr & storagename,\n\tconst ttstr &extension)\n{\n\tif(extension != TJS_W(\".wav\")) return NULL;\n\n\ttTVPStreamHolder stream(storagename);\n\n\tstatic const tjs_uint8 riff_mark[] =\n\t\t{ /*R*/0x52, /*I*/0x49, /*F*/0x46, /*F*/0x46 };\n\tstatic const tjs_uint8 wave_mark[] =\n\t\t{ /*W*/0x57, /*A*/0x41, /*V*/0x56, /*E*/0x45 };\n\tstatic const tjs_uint8 fmt_mark[] =\n\t\t{ /*f*/0x66, /*m*/0x6d, /*t*/0x74, /* */0x20 };\n\tstatic const tjs_uint8 data_mark[] =\n\t\t{ /*d*/0x64, /*a*/0x61, /*t*/0x74, /*a*/0x61 };\n\n\ttry\n\t{\n\t\ttjs_uint32 size;\n\t\ttjs_int64 next;\n\n\t\t// check RIFF mark\n\t\ttjs_uint8 buf[4];\n\t\tif(4 != stream->Read(buf, 4)) return NULL;\n\t\tif(memcmp(buf, riff_mark, 4)) return NULL;\n\n\t\tif(4 != stream->Read(buf, 4)) return NULL; // RIFF chunk size; discard\n\n\t\t// check WAVE subid\n\t\tif(4 != stream->Read(buf, 4)) return NULL;\n\t\tif(memcmp(buf, wave_mark, 4)) return NULL;\n\n\t\t// find fmt chunk\n\t\tif(!TVPFindRIFFChunk(stream, fmt_mark)) return NULL;\n\n\t\tsize = stream->ReadI32LE();\n\t\tnext = stream->GetPosition() + size;\n\n\t\t// read format\n\t\ttTVPWaveFormat format;\n//\t\tbool do_reorder_5poiont1ch = false;\n\t\t\t// whether to reorder 5.1ch channel samples\n\t\t\t// (AC3 order to WAVEFORMATEXTENSIBLE order)\n\n\t\ttjs_uint16 format_tag = stream->ReadI16LE(); // wFormatTag\n\t\tif(format_tag != WAVE_FORMAT_PCM &&\n\t\t\tformat_tag != WAVE_FORMAT_IEEE_FLOAT &&\n\t\t\tformat_tag != WAVE_FORMAT_EXTENSIBLE) return NULL;\n\n\n\t\tformat.Channels = stream->ReadI16LE(); // nChannels\n\t\tformat.SamplesPerSec = stream->ReadI32LE(); // nSamplesPerSec\n\n\t\tif(4 != stream->Read(buf, 4)) return NULL; // nAvgBytesPerSec; discard\n\n\t\ttjs_uint16 block_align = stream->ReadI16LE(); // nBlockAlign\n\n\t\tformat.BitsPerSample = stream->ReadI16LE(); // wBitsPerSample\n\n\t\ttjs_uint16 ext_size = stream->ReadI16LE(); // cbSize\n\t\tif(format_tag == WAVE_FORMAT_EXTENSIBLE)\n\t\t{\n\t\t\tif(ext_size != 22) return NULL; // invalid extension length\n\t\t\tif(format.BitsPerSample & 0x07) return NULL;  // not integer multiply by 8\n\t\t\tformat.BytesPerSample = format.BitsPerSample / 8;\n\t\t\tformat.BitsPerSample = stream->ReadI16LE(); // wValidBitsPerSample\n\t\t\tformat.SpeakerConfig = stream->ReadI32LE(); // dwChannelMask\n\n\t\t\ttjs_uint8 guid[16];\n\t\t\tif(16 != stream->Read(guid, 16)) return NULL;\n\t\t\tif(!memcmp(guid, TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16))\n\t\t\t\tformat.IsFloat = false;\n\t\t\telse if(!memcmp(guid, TVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 16))\n\t\t\t\tformat.IsFloat = true;\n\t\t\telse\n\t\t\t\treturn NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(format.BitsPerSample & 0x07) return NULL; // not integer multiplyed by 8\n\t\t\tformat.BytesPerSample = format.BitsPerSample / 8;\n\n\t\t\tif(format.Channels == 4)\n\t\t\t{\n\t\t\t\tformat.SpeakerConfig = 0;\n//\t\t\t\tformat.SpeakerConfig =\n//\t\t\t\t\tSPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |\n//\t\t\t\t\tSPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;\n\n\t\t\t}\n\t\t\telse if(format.Channels == 6)\n\t\t\t{\n\t\t\t\tformat.SpeakerConfig = 0;\n//\t\t\t\tdo_reorder_5poiont1ch = true;\n//\t\t\t\tformat.SpeakerConfig =\n//\t\t\t\t\tSPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tformat.SpeakerConfig = 0;\n\t\t\t}\n\n\t\t\tformat.IsFloat = format_tag == WAVE_FORMAT_IEEE_FLOAT;\n\t\t}\n\n\n\t\tif(format.BitsPerSample > 32) return NULL; // too large bits\n\t\tif(format.BitsPerSample < 8) return NULL; // too less bits\n\t\tif(format.BitsPerSample > format.BytesPerSample * 8)\n\t\t\treturn NULL; // bits per sample is larger than bytes per sample\n\t\tif(format.IsFloat)\n\t\t{\n\t\t\tif(format.BitsPerSample != 32) return NULL; // not a 32-bit IEEE float\n\t\t\tif(format.BytesPerSample != 4) return NULL;\n\t\t}\n\n\t\tif((tjs_int) block_align != (tjs_int)(format.BytesPerSample * format.Channels))\n\t\t\treturn NULL; // invalid align\n\n\t\tif(next != stream->Seek(next, TJS_BS_SEEK_SET)) return NULL;\n\n\t\t// find data chunk\n\t\tif(!TVPFindRIFFChunk(stream, data_mark)) return NULL;\n\n\t\tsize = stream->ReadI32LE();\n\n\t\ttjs_int64 datastart;\n\n\t\ttjs_int64 remain_size = stream->GetSize() -\n\t\t\t(datastart = stream->GetPosition());\n\t\tif(size > remain_size) return NULL;\n\t\t\t// data ends before \"size\" described in the header\n\n\t\t// compute total sample count and total length in time\n\t\tformat.TotalSamples = size / (format.Channels * format.BitsPerSample / 8);\n\t\tformat.TotalTime = format.TotalSamples * 1000 / format.SamplesPerSec;\n\n\t\t// create tTVPWD_RIFFWave instance\n\t\tformat.Seekable = true;\n\t\ttTVPWD_RIFFWave * decoder = new tTVPWD_RIFFWave(stream.Get(), datastart,\n\t\t\tformat);\n\t\tstream.Disown();\n\n\t\treturn decoder;\n\t}\n\tcatch(...)\n\t{\n\t\t// this function must be a silent one unless file open error...\n\t\treturn NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveDecoder interface management\n//---------------------------------------------------------------------------\nbool TVPWaveDecoderManagerAvail = false;\nstruct tTVPWaveDecoderManager\n{\n\tstd::vector<tTVPWaveDecoderCreator *> Creators;\n\ttTVPWDC_RIFFWave RIFFWaveDecoderCreator;\n    VorbisWaveDecoderCreator vorbisWaveDecoderCreator;\n    FFWaveDecoderCreator ffWaveDecoderCreator;\n    OpusWaveDecoderCreator opusWaveDecoderCreator;\n\n\ttTVPWaveDecoderManager()\n\t{\n\t\tTVPWaveDecoderManagerAvail = true;\n        TVPRegisterWaveDecoderCreator(&ffWaveDecoderCreator);\n        TVPRegisterWaveDecoderCreator(&opusWaveDecoderCreator);\n\t\tTVPRegisterWaveDecoderCreator(&RIFFWaveDecoderCreator);\n        TVPRegisterWaveDecoderCreator(&vorbisWaveDecoderCreator);\n\t}\n\n\t~tTVPWaveDecoderManager()\n\t{\n\t\tTVPWaveDecoderManagerAvail = false;\n\t}\n\n} static TVPWaveDecoderManager;\n//---------------------------------------------------------------------------\nvoid TVPRegisterWaveDecoderCreator(tTVPWaveDecoderCreator *d)\n{\n\tif(TVPWaveDecoderManagerAvail)\n\t\tTVPWaveDecoderManager.Creators.push_back(d);\n}\n//---------------------------------------------------------------------------\nvoid TVPUnregisterWaveDecoderCreator(tTVPWaveDecoderCreator *d)\n{\n\tif(TVPWaveDecoderManagerAvail)\n\t{\n\t\tstd::vector<tTVPWaveDecoderCreator *>::iterator i;\n\t\ti = std::find(TVPWaveDecoderManager.Creators.begin(),\n\t\t\tTVPWaveDecoderManager.Creators.end(), d);\n\t\tif(i != TVPWaveDecoderManager.Creators.end())\n\t\t{\n\t\t\tTVPWaveDecoderManager.Creators.erase(i);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPWaveDecoder *  TVPCreateWaveDecoder(const ttstr & storagename)\n{\n\t// find a decoder and create its instance.\n\t// throws an exception when the decodable decoder is not found.\n\tif(!TVPWaveDecoderManagerAvail) return NULL;\n\n\tttstr ext(TVPExtractStorageExt(storagename));\n\text.ToLowerCase();\n\n\ttjs_int i = (tjs_int)(TVPWaveDecoderManager.Creators.size()-1);\n\tfor(; i>=0; i--)\n\t{\n\t\ttTVPWaveDecoder * decoder;\n\t\tdecoder = TVPWaveDecoderManager.Creators[i]->Create(storagename, ext);\n\t\tif(decoder) return decoder;\n\t}\n\n\tTVPThrowExceptionMessage(TVPUnknownWaveFormat, storagename);\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// sound format convert filter\n//---------------------------------------------------------------------------\nclass iSoundBufferConvertToPCM16 : public tTJSDispatch, // could be hold by tFilterObjectAndInterface\n\tpublic iTVPBasicWaveFilter, public tTVPSampleAndLabelSource\n{\nprotected:\n\ttTVPSampleAndLabelSource * Source; // source filter\n\ttTVPWaveFormat OutputFormat;\n\npublic:\n\tvirtual tTVPSampleAndLabelSource * Recreate(tTVPSampleAndLabelSource * source) {\n\t\tSource = source;\n\t\tOutputFormat = source->GetFormat();\n\t\tOutputFormat.IsFloat = false;\n\t\tOutputFormat.BitsPerSample = 16;\n\t\tOutputFormat.BytesPerSample = 2;\n\t\treturn this;\n\t}\n\tvirtual ~iSoundBufferConvertToPCM16() {}\n\tvirtual void Clear(void) { Source = nullptr; }\n\tvirtual void Update(void) {};\n\tvirtual void Reset(void) {};\n\n\tvirtual const tTVPWaveFormat & GetFormat() const { return OutputFormat; }\n};\n//---------------------------------------------------------------------------\nclass SoundBufferConvertFloatToPCM16 : public iSoundBufferConvertToPCM16 {\n\tstd::vector<float> buffer;\n\tvirtual void Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue &segments) {\n\t\ttjs_uint numsamples = samples * OutputFormat.Channels;\n\t\tif (buffer.size() < numsamples) buffer.resize(numsamples);\n\t\tfloat *p = &buffer[0];\n\t\tSource->Decode(p, samples, written, segments);\n\t\tnumsamples = written * OutputFormat.Channels;\n\t\tPCMConvertLoopFloat32ToInt16(dest, p, numsamples);\n\t}\n};\n//---------------------------------------------------------------------------\nclass SoundBufferConvertPCM24ToPCM16 : public iSoundBufferConvertToPCM16 {\n\tstd::vector<char> buffer;\n\tvirtual void Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue &segments) {\n\t\ttjs_uint numsamples = samples * OutputFormat.Channels;\n\t\tif (buffer.size() < numsamples * 3) buffer.resize(numsamples * 3);\n\t\tchar *p = &buffer[0]; int16_t *d = (int16_t *)dest;\n\t\tSource->Decode(p, samples, written, segments);\n\t\tnumsamples = written * OutputFormat.Channels;\n\t\tfor (int i = 0; i < numsamples; ++i) {\n\t\t\td[i] = *(int16_t*)(p + 1);\n\t\t\tp += 3;\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\nclass SoundBufferConvertPCM32ToPCM16 : public iSoundBufferConvertToPCM16 {\n\tstd::vector<int32_t> buffer;\n\tvirtual void Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue &segments) {\n\t\ttjs_uint numsamples = samples * OutputFormat.Channels;\n\t\tif (buffer.size() < numsamples) buffer.resize(numsamples);\n\t\tchar *p = (char *)&buffer[0]; int16_t *d = (int16_t *)dest;\n\t\tSource->Decode(p, samples, written, segments);\n\t\tnumsamples = written * OutputFormat.Channels;\n\t\tfor (int i = 0; i < numsamples; ++i) {\n\t\t\td[i] = *(int16_t*)(p + 2);\n\t\t\tp += 4;\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseWaveSoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_BaseWaveSoundBuffer::tTJSNI_BaseWaveSoundBuffer()\n{\n\tLoopManager = NULL;\n\tWaveFlagsObject = NULL;\n\tWaveLabelsObject = NULL;\n\tFilters = TJSCreateArrayObject();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BaseWaveSoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseWaveSoundBuffer::Invalidate()\n{\n\t// invalidate wave flags object\n\tRecreateWaveLabelsObject();\n\n\t// release filter arrays\n\tif(Filters) Filters->Release(), Filters = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::InvokeLabelEvent(const ttstr & name)\n{\n\t// the invoked event is to be delivered asynchronously.\n\t// the event is to be erased when the SetStatus is called, but it's ok.\n\t// ( SetStatus calls TVPCancelSourceEvents(Owner); )\n\n\tif(Owner && CanDeliverEvents)\n\t{\n\t\ttTJSVariant param(name);\n\t\tstatic ttstr eventname(TJS_W(\"onLabel\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_POST,\n\t\t\t1, &param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::RecreateWaveLabelsObject()\n{\n\t// indicate recreating WaveLabelsObject\n\tif(WaveLabelsObject)\n\t{\n\t\tWaveLabelsObject->Invalidate(0, NULL, NULL, WaveLabelsObject);\n\t\tWaveLabelsObject->Release();\n\t\tWaveLabelsObject = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::RebuildFilterChain()\n{\n\t// rebuild filter array\n\tFilterInterfaces.clear();\n\n\t// get filter count\n\ttTJSVariant v;\n\ttjs_int count = 0;\n\tFilters->PropGet(0, TJS_W(\"count\"), NULL, &v, Filters);\n\tcount = v;\n\n\t// reset filter output\n\tFilterOutput = LoopManager;\n\n\t// for each filter ...\n\tfor(int i = 0; i < count; i++)\n\t{\n\t\tFilters->PropGetByNum(0, i, &v, Filters);\n\n\t\t// get iTVPBasicWaveFilter interface\n\t\ttTJSVariantClosure clo = v.AsObjectClosureNoAddRef();\n\t\ttTJSVariant iface_v;\n\t\tif(TJS_FAILED(clo.PropGet(0, TJS_W(\"interface\"), NULL, &iface_v, NULL))) continue;\n\t\tiTVPBasicWaveFilter * filter =\n\t\t\treinterpret_cast<iTVPBasicWaveFilter *>((tjs_intptr_t)(tjs_int64)iface_v);\n\t\t// save to the backupped array\n\t\tFilterInterfaces.emplace_back(v, filter);\n\t}\n\n\t// reset filter output\n\tFilterOutput = LoopManager;\n\n\t// for each filter ...\n\tfor(std::vector<tFilterObjectAndInterface>::iterator i = FilterInterfaces.begin();\n\t\ti != FilterInterfaces.end(); i++)\n\t{\n\t\t// recreate filter\n\t\tFilterOutput = i->Interface->Recreate(FilterOutput);\n\t}\n\n\tconst tTVPWaveFormat &filteredFormat = FilterOutput->GetFormat();\n\tif (filteredFormat.IsFloat) {\n\t\tSoundBufferConvertFloatToPCM16 *filter = new SoundBufferConvertFloatToPCM16;\n\t\tFilterInterfaces.emplace_back(filter, filter);\n\t\tFilterOutput = filter->Recreate(FilterOutput);\n\t\tfilter->Release();\n\t} else if (filteredFormat.BitsPerSample == 24) {\n\t\tSoundBufferConvertPCM24ToPCM16 *filter = new SoundBufferConvertPCM24ToPCM16;\n\t\tFilterInterfaces.emplace_back(filter, filter);\n\t\tFilterOutput = filter->Recreate(FilterOutput);\n\t\tfilter->Release();\n\t} else if (filteredFormat.BitsPerSample == 32) {\n\t\tSoundBufferConvertPCM32ToPCM16 *filter = new SoundBufferConvertPCM32ToPCM16;\n\t\tFilterInterfaces.emplace_back(filter, filter);\n\t\tFilterOutput = filter->Recreate(FilterOutput);\n\t\tfilter->Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::ClearFilterChain()\n{\n\t// delete object which is created from this filter array\n\n\t// reset filter output\n\tFilterOutput = NULL;\n\n\tfor(std::vector<tFilterObjectAndInterface>::iterator i = FilterInterfaces.begin();\n\t\ti != FilterInterfaces.end(); i++)\n\t{\n\t\t// recreate filter\n\t\ti->Interface->Clear();\n\t}\n\n\t// clear backupped filter array\n\tFilterInterfaces.clear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::ResetFilterChain()\n{\n\t// Reset filter chain.\n\tfor(std::vector<tFilterObjectAndInterface>::iterator i = FilterInterfaces.begin();\n\t\ti != FilterInterfaces.end(); i++)\n\t\ti->Interface->Reset();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWaveSoundBuffer::UpdateFilterChain()\n{\n\t// Update filter chain.\n\t// This method is called before that the player is about to decode a small \n\t// PCM unit (typically piece of 125ms of sound).\n\t// Note that this method may be called by decoding thread,\n\t// but it's guaranteed that the call is never overlapped with\n\t// UpdateFilterChain self and ClearFilterChain and RebuildFilterChain.\n\t// so we does not need to protect this call by CriticalSection.\n\tfor(std::vector<tFilterObjectAndInterface>::iterator i = FilterInterfaces.begin();\n\t\ti != FilterInterfaces.end(); i++)\n\t\ti->Interface->Update();\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseWaveSoundBuffer::GetWaveFlagsObjectNoAddRef()\n{\n\tif(WaveFlagsObject) return WaveFlagsObject;\n\n\tif(!Owner) TVPThrowInternalError;\n\n\tWaveFlagsObject = TVPCreateWaveFlagsObject(Owner);\n\n\treturn WaveFlagsObject;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseWaveSoundBuffer::GetWaveLabelsObjectNoAddRef()\n{\n\tif(WaveLabelsObject) return WaveLabelsObject;\n\n\t// build label dictionay from WaveLoopManager\n\tWaveLabelsObject = TJSCreateDictionaryObject();\n\n\tif(LoopManager)\n\t{\n\t\tconst std::vector<tTVPWaveLabel> & labels = LoopManager->GetLabels();\n\n\t\tint freq = FilterOutput->GetFormat().SamplesPerSec;\n\n\t\tint count = 0;\n\t\tfor(std::vector<tTVPWaveLabel>::const_iterator i = labels.begin();\n\t\t\ti != labels.end(); i++, count++)\n\t\t{\n\t\t\tiTJSDispatch2 * item_dic = TJSCreateDictionaryObject();\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttTJSVariant val;\n\t\t\t\tval = i->Name.c_str(); // c_str() to avoid race condition for ttstr\n\t\t\t\titem_dic->PropSet(TJS_MEMBERENSURE, TJS_W(\"name\"), NULL, &val, item_dic);\n\t\t\t\tval = i->Position;\n\t\t\t\titem_dic->PropSet(TJS_MEMBERENSURE, TJS_W(\"samplePosition\"), NULL, &val, item_dic);\n\t\t\t\tval = freq ? i->Position * 1000 / freq : 0;\n\t\t\t\titem_dic->PropSet(TJS_MEMBERENSURE, TJS_W(\"position\"), NULL, &val, item_dic);\n\n\t\t\t\ttTJSVariant item_dic_var(item_dic, item_dic);\n\n\t\t\t\tif(!i->Name.IsEmpty())\n\t\t\t\t\tWaveLabelsObject->PropSet(TJS_MEMBERENSURE, i->Name.c_str(), NULL,\n\t\t\t\t\t\t&item_dic_var, WaveLabelsObject);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\titem_dic->Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\titem_dic->Release();\n\t\t}\n\t}\n\n\treturn WaveLabelsObject;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_WaveSoundBuffer : TJS WaveSoundBuffer class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_WaveSoundBuffer::ClassID = -1;\ntTJSNC_WaveSoundBuffer::tTJSNC_WaveSoundBuffer()  :\n\ttTJSNativeClass(TJS_W(\"WaveSoundBuffer\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(WaveSoundBuffer) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this,\n\t/*var.type*/tTJSNI_WaveSoundBuffer,\n\t/*TJS class name*/WaveSoundBuffer)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/WaveSoundBuffer)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/open)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->Open(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/open)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/play)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t_this->Play();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/play)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t_this->Stop();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_int to;\n\ttjs_int time;\n\ttjs_int delay = 0;\n\tto = (tjs_int)(*param[0]);\n\ttime = (tjs_int)(*param[1]);\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tdelay = (tjs_int)(*param[2]);\n\n\t_this->Fade(to, time, delay);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fade)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t_this->StopFade(false, true);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stopFade)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPos) // not setPosition\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\ttTVReal x, y, z;\n\tx = (*param[0]);\n\ty = (*param[1]);\n\tz = (*param[2]);\n\n\t_this->SetPos( static_cast<D3DVALUE>(x), static_cast<D3DVALUE>(y), static_cast<D3DVALUE>(z) );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPos)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onStatusChanged\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"status\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onFadeCompleted\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFadeCompleted)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onLabel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onLabel\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"name\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onLabel)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(position)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tjs_int64)_this->GetPosition();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPosition((tjs_uint64)(tjs_int64)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(position)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(samplePosition)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tjs_int64)_this->GetSamplePosition();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetSamplePosition((tjs_uint64)(tjs_int64)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(samplePosition)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(paused)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetPaused();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPaused(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(paused)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(totalTime)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tjs_int64)_this->GetTotalTime();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t// not yet implemented\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(totalTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(looping)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetLooping();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetLooping(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(looping)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetVolume();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetVolume(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(volume2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetVolume2();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetVolume2(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(volume2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(pan)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetPan();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPan(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(pan)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(posX)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tTVReal)_this->GetPosX();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPosX( static_cast<D3DVALUE>( (tTVReal)*param ));\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(posX)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(posY)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tTVReal)_this->GetPosY();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPosY( static_cast<D3DVALUE>( (tTVReal)*param ) );\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(posY)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(posZ)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = (tTVReal)_this->GetPosZ();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetPosZ( static_cast<D3DVALUE>((tTVReal)*param) );\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(posZ)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(status)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetStatusString();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(status)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(frequency)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetFrequency();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetFrequency((tjs_int)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(frequency)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bits) // not bitsPerSample\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetBitsPerSample();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bits)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(channels)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetChannels();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(channels)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(flags)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\tiTJSDispatch2 * dsp = _this->GetWaveFlagsObjectNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(flags)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(labels)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\tiTJSDispatch2 * dsp = _this->GetWaveLabelsObjectNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(labels)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(filters)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\tiTJSDispatch2 * dsp = _this->GetFiltersNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(filters)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(globalVolume)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTJSNI_WaveSoundBuffer::GetGlobalVolume();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\ttTJSNI_WaveSoundBuffer::SetGlobalVolume(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(globalVolume)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(globalFocusMode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)tTJSNI_WaveSoundBuffer::GetGlobalFocusMode();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\ttTJSNI_WaveSoundBuffer::SetGlobalFocusMode(\n\t\t\t(tTVPSoundGlobalFocusMode)(tjs_int)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(globalFocusMode)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n//----------------------------------------------------------------------\n\n\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_WaveFlags : Wave Flags object\n//---------------------------------------------------------------------------\ntTJSNI_WaveFlags::tTJSNI_WaveFlags()\n{\n\tBuffer = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_WaveFlags::~tTJSNI_WaveFlags()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNI_WaveFlags::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tiTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef();\n\n\ttTJSNI_WaveSoundBuffer *buffer = NULL;\n\tif(TJS_FAILED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\ttTJSNC_WaveSoundBuffer::ClassID, (iTJSNativeInstance**)&buffer)))\n\t\tTVPThrowInternalError;\n\n\tBuffer = buffer;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_WaveFlags::Invalidate()\n{\n\tBuffer = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_WaveFlags : Wave Flags class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_WaveFlags::ClassID = -1;\ntTJSNC_WaveFlags::tTJSNC_WaveFlags() : tTJSNativeClass(TJS_W(\"WaveFlags\"))\n{\n\tTJS_BEGIN_NATIVE_MEMBERS(WaveFlags) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_WaveFlags,\n\t/*TJS class name*/WaveFlags)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/WaveFlags)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/reset)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveFlags);\n\n\ttTVPWaveLoopManager * manager =\n\t\t_this->GetBuffer()->GetWaveLoopManager(); /* note that the manager can be null */\n\n\tif(manager) manager->ClearFlags();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/reset)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(count)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveFlags);\n\t\t*result = TVP_WL_MAX_FLAGS; // always this value\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(count)\n//----------------------------------------------------------------------\n#define TVP_DEFINE_FLAG_PROP(N) \\\n\tTJS_BEGIN_NATIVE_PROP_DECL(N)                                                                    \\\n\t{                                                                                                \\\n\t\tTJS_BEGIN_NATIVE_PROP_GETTER                                                                 \\\n\t\t{                                                                                            \\\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveFlags);              \\\n\t\t\ttTVPWaveLoopManager * manager =                                                          \\\n\t\t\t\t_this->GetBuffer()->GetWaveLoopManager(); /* note that the manager can be null */    \\\n\t\t\tif(manager) *result = manager->GetFlag(N); else *result = (tjs_int)0;                    \\\n\t\t\treturn TJS_S_OK;                                                                         \\\n\t\t}                                                                                            \\\n\t\tTJS_END_NATIVE_PROP_GETTER                                                                   \\\n                                                                                                     \\\n\t\tTJS_BEGIN_NATIVE_PROP_SETTER                                                                 \\\n\t\t{                                                                                            \\\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_WaveFlags);              \\\n\t\t\ttTVPWaveLoopManager * manager =                                                          \\\n\t\t\t\t_this->GetBuffer()->GetWaveLoopManager(); /* note that the manager can be null */    \\\n\t\t\tif(manager) manager->SetFlag(N, (tjs_int)*param);                                        \\\n\t\t\treturn TJS_S_OK;                                                                         \\\n\t\t}                                                                                            \\\n\t\tTJS_END_NATIVE_PROP_SETTER                                                                   \\\n\t}                                                                                                \\\n\tTJS_END_NATIVE_PROP_DECL(N)                                                                      \n\nTVP_DEFINE_FLAG_PROP(0)\nTVP_DEFINE_FLAG_PROP(1)\nTVP_DEFINE_FLAG_PROP(2)\nTVP_DEFINE_FLAG_PROP(3)\nTVP_DEFINE_FLAG_PROP(4)\nTVP_DEFINE_FLAG_PROP(5)\nTVP_DEFINE_FLAG_PROP(6)\nTVP_DEFINE_FLAG_PROP(7)\nTVP_DEFINE_FLAG_PROP(8)\nTVP_DEFINE_FLAG_PROP(9)\nTVP_DEFINE_FLAG_PROP(10)\nTVP_DEFINE_FLAG_PROP(11)\nTVP_DEFINE_FLAG_PROP(12)\nTVP_DEFINE_FLAG_PROP(13)\nTVP_DEFINE_FLAG_PROP(14)\nTVP_DEFINE_FLAG_PROP(15)\n\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateWaveFlagsObject(iTJSDispatch2 * buffer)\n{\n\tstruct tHolder\n\t{\n\t\tiTJSDispatch2 * Obj;\n\t\ttHolder() { Obj = new tTJSNC_WaveFlags(); }\n\t\t~tHolder() { Obj->Release(); }\n\t} static waveflagsclass;\n\n\tiTJSDispatch2 *out;\n\ttTJSVariant param(buffer);\n\ttTJSVariant *pparam = &param;\n\tif(TJS_FAILED(waveflagsclass.Obj->CreateNew(0, NULL, NULL, &out, 1, &pparam,\n\t\twaveflagsclass.Obj)))\n\t\tTVPThrowInternalError;\n\n\treturn out;\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/WaveIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Player interface\n//---------------------------------------------------------------------------\n#ifndef WaveIntfH\n#define WaveIntfH\n\n#include \"tjsCommHead.h\"\n#include \"tjsNative.h\"\n#include \"SoundBufferBaseIntf.h\"\n#include \"tjsUtils.h\"\ntypedef tTVReal D3DVALUE;\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// Sound Global Focus Mode\n//---------------------------------------------------------------------------\nenum tTVPSoundGlobalFocusMode\n{\n\t/*0*/ sgfmNeverMute,\t\t\t// never mutes\n\t/*1*/ sgfmMuteOnMinimize,\t\t// will mute on the application minimize\n\t/*2*/ sgfmMuteOnDeactivate\t\t// will mute on the application deactivation\n};\n//---------------------------------------------------------------------------\n\n\n\n/*]*/\n//---------------------------------------------------------------------------\n// GUID identifying WAVEFORMATEXTENSIBLE sub format\n//---------------------------------------------------------------------------\nextern tjs_uint8 TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM[16];\nextern tjs_uint8 TVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT[16];\n//---------------------------------------------------------------------------\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// PCM data format (internal use)\n//---------------------------------------------------------------------------\nstruct tTVPWaveFormat\n{\n\ttjs_uint SamplesPerSec; // sample granule per sec\n\ttjs_uint Channels;\n\ttjs_uint BitsPerSample; // per one sample\n\ttjs_uint BytesPerSample; // per one sample\n\ttjs_uint64 TotalSamples; // in sample granule; unknown for zero\n\ttjs_uint64 TotalTime; // in ms; unknown for zero\n\ttjs_uint32 SpeakerConfig; // bitwise OR of SPEAKER_* constants\n\tbool IsFloat; // true if the data is IEEE floating point\n\tbool Seekable;\n};\n//---------------------------------------------------------------------------\n\n\n\n/*]*/\n//---------------------------------------------------------------------------\n// PCM bit depth converter\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPConvertPCMTo16bits, (tjs_int16 *output, const void *input, const tTVPWaveFormat &format, tjs_int count, bool downmix));\nTJS_EXP_FUNC_DEF(void, TVPConvertPCMTo16bits, (tjs_int16 *output, const void *input, tjs_int channels, tjs_int bytespersample, tjs_int bitspersample, bool isfloat, tjs_int count, bool downmix));\nTJS_EXP_FUNC_DEF(void, TVPConvertPCMToFloat, (float *output, const void *input, tjs_int channels, tjs_int bytespersample, tjs_int bitspersample, bool isfloat, tjs_int count));\nTJS_EXP_FUNC_DEF(void, TVPConvertPCMToFloat, (float *output, const void *input, const tTVPWaveFormat &format, tjs_int count));\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveDecoder interface\n//---------------------------------------------------------------------------\nclass tTVPWaveDecoder\n{\npublic:\n\tvirtual ~tTVPWaveDecoder() {};\n\n\tvirtual void GetFormat(tTVPWaveFormat & format) = 0;\n\t\t/* Retrieve PCM format, etc. */\n\n\tvirtual bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered) = 0;\n\t\t/*\n\t\t\tRender PCM from current position.\n\t\t\twhere \"buf\" is a destination buffer, \"bufsamplelen\" is the buffer's\n\t\t\tlength in sample granule, \"rendered\" is to be an actual number of\n\t\t\twritten sample granule.\n\t\t\treturns whether the decoding is to be continued.\n\t\t\tbecause \"redered\" can be lesser than \"bufsamplelen\", the player\n\t\t\tshould not end until the returned value becomes false.\n\t\t*/\n\n\tvirtual bool SetPosition(tjs_uint64 samplepos) = 0;\n\t\t/*\n\t\t\tSeek to \"samplepos\". \"samplepos\" must be given in unit of sample granule.\n\t\t\treturns whether the seeking is succeeded.\n\t\t*/\n\n\tvirtual bool DesiredFormat(const tTVPWaveFormat & format) { return false; }\n};\n//---------------------------------------------------------------------------\nclass tTVPWaveDecoderCreator\n{\npublic:\n\tvirtual tTVPWaveDecoder * Create(const ttstr & storagename,\n\t\tconst ttstr &extension) = 0;\n\t\t/*\n\t\t\tCreate tTVPWaveDecoder instance. returns NULL if failed.\n\t\t*/\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveDecoder interface management\n//---------------------------------------------------------------------------\nextern void TVPRegisterWaveDecoderCreator(tTVPWaveDecoderCreator *d);\nextern void TVPUnregisterWaveDecoderCreator(tTVPWaveDecoderCreator *d);\nextern tTVPWaveDecoder *  TVPCreateWaveDecoder(const ttstr & storagename);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// interface for basic filter management\n//---------------------------------------------------------------------------\nclass tTVPSampleAndLabelSource;\nclass iTVPBasicWaveFilter\n{\npublic:\n\t// recreate filter. filter will remain owned by the each filter instance.\n\tvirtual tTVPSampleAndLabelSource * Recreate(tTVPSampleAndLabelSource * source) = 0;\n\tvirtual void Clear(void) = 0;\n\tvirtual void Update(void) = 0;\n\tvirtual void Reset(void) = 0;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseWaveSoundBuffer\n//---------------------------------------------------------------------------\nclass tTVPWaveLoopManager;\nclass tTJSNI_BaseWaveSoundBuffer : public tTJSNI_SoundBuffer\n{\n\ttypedef tTJSNI_SoundBuffer inherited;\n\n\tiTJSDispatch2 * WaveFlagsObject;\n\tiTJSDispatch2 * WaveLabelsObject;\n\n\tstruct tFilterObjectAndInterface\n\t{\n\t\ttTJSVariant Filter; // filter object\n\t\tiTVPBasicWaveFilter * Interface; // filter interface\n\t\ttFilterObjectAndInterface(\n\t\t\tconst tTJSVariant & filter,\n\t\t\tiTVPBasicWaveFilter * interf) :\n\t\t\tFilter(filter), Interface(interf) {;}\n\t};\n\tstd::vector<tFilterObjectAndInterface> FilterInterfaces; // backupped filter interface array\n\nprotected:\n\ttTVPWaveLoopManager * LoopManager; // will be set by tTJSNI_WaveSoundBuffer\n\ttTVPSampleAndLabelSource * FilterOutput; // filter output\n\tiTJSDispatch2 * Filters; // wave filters array (TJS2 array object)\npublic:\n\ttTJSNI_BaseWaveSoundBuffer();\n\ttjs_error TJS_INTF_METHOD\n\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\n\tvoid InvokeLabelEvent(const ttstr & name);\n\tvoid RecreateWaveLabelsObject();\n\tvoid RebuildFilterChain();\n\tvoid ClearFilterChain();\n\tvoid ResetFilterChain();\n\tvoid UpdateFilterChain();\n\npublic:\n\tiTJSDispatch2 * GetWaveFlagsObjectNoAddRef();\n\tiTJSDispatch2 * GetWaveLabelsObjectNoAddRef();\n\ttTVPWaveLoopManager * GetWaveLoopManager() const { return LoopManager; }\n\tiTJSDispatch2 * GetFiltersNoAddRef() { return Filters; }\n};\n//---------------------------------------------------------------------------\n\n#include \"WaveImpl.h\" // must define tTJSNI_WaveSoundBuffer class\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_WaveSoundBuffer : TJS WaveSoundBuffer class\n//---------------------------------------------------------------------------\nclass tTJSNC_WaveSoundBuffer : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_WaveSoundBuffer();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_WaveSoundBuffer();\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_WaveFlags : Wave Flags object\n//---------------------------------------------------------------------------\nclass tTJSNI_WaveSoundBuffer;\nclass tTJSNI_WaveFlags : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\n\ttTJSNI_WaveSoundBuffer * Buffer;\n\npublic:\n\ttTJSNI_WaveFlags();\n\t~tTJSNI_WaveFlags();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\ttTJSNI_WaveSoundBuffer * GetBuffer() const { return Buffer; }\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_WaveFlags : Wave Flags class\n//---------------------------------------------------------------------------\nclass tTJSNC_WaveFlags : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_WaveFlags();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance() { return new tTJSNI_WaveFlags(); }\n};\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateWaveFlagsObject(iTJSDispatch2 * buffer);\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/sound/WaveLoopManager.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Loop Manager\n//---------------------------------------------------------------------------\n/*\n\tThis module will be shared between TVP2 and\n\tLoop Tuner 2 (a GUI loop-point editor)\n*/\n\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include <string.h>\n#include \"tjsTypes.h\"\n#include \"WaveLoopManager.h\"\n#include \"CharacterSet.h\"\n\n#ifdef TVP_IN_LOOP_TUNER\n\t#include \"WaveReader.h\"\n#else\n\t#include \"WaveIntf.h\"\n#endif\n\n\n#ifdef __BORLANDC__\n\t#define strcasecmp strcmpi\n\t#define strncasecmp strncmpi\n#endif\n\n#ifdef _MSC_VER\n\t#define strcasecmp _stricmp\n\t#define strncasecmp _strnicmp\n#endif\n\n//---------------------------------------------------------------------------\nconst int TVPWaveLoopLinkGiveUpCount = 10;\n\t// This is for preventing infinite loop caused by recursive links.\n\t// If the decoding point does not change when the loop manager follows the\n\t// links, after 'TVPWaveLoopLinkGiveUpCount' times the loop manager\n\t// will give up the decoding.\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Wave Sample Types\n//---------------------------------------------------------------------------\n#ifndef TJS_HOST_IS_BIG_ENDIAN\n\t#define TJS_HOST_IS_BIG_ENDIAN 0\n#endif\n\n#ifdef __WIN32__\n\t// for assembler compatibility\n\t#pragma pack(push,1)\n#endif\nstruct tTVPPCM8\n{\n\ttjs_uint8 value;\n\ttTVPPCM8(tjs_int v) { value = (tjs_uint8)(v + 0x80); }\n\tvoid operator = (tjs_int v) { value = (tjs_uint8)(v + 0x80); }\n\toperator tjs_int () const { return (tjs_int)value - 0x80; }\n};\nstruct tTVPPCM24\n{\n\ttjs_uint8 value[3];\n\ttTVPPCM24(tjs_int v)\n\t{\n\t\toperator = (v);\n\t}\n\tvoid operator =(tjs_int v)\n\t{\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\tvalue[0] = (v & 0xff0000) >> 16;\n\t\tvalue[1] = (v & 0x00ff00) >> 8;\n\t\tvalue[2] = (v & 0x0000ff);\n#else\n\t\tvalue[0] = (v & 0x0000ff);\n\t\tvalue[1] = (v & 0x00ff00) >> 8;\n\t\tvalue[2] = (v & 0xff0000) >> 16;\n#endif\n\t}\n\toperator tjs_int () const\n\t{\n\t\ttjs_int t;\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\tt = ((tjs_int)value[0] << 16) + ((tjs_int)value[1] << 8) + ((tjs_int)value[2]);\n#else\n\t\tt = ((tjs_int)value[2] << 16) + ((tjs_int)value[1] << 8) + ((tjs_int)value[0]);\n#endif\n\t\tt |= -(t&0x800000); // extend sign\n\t\treturn t;\n\t}\n};\n#ifdef __WIN32__\n\t#pragma pack(pop)\n#endif\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Crossfade Template function\n//---------------------------------------------------------------------------\ntemplate <typename T>\nstatic void TVPCrossFadeIntegerBlend(void *dest, void *src1, void *src2,\n\ttjs_int ratiostart, tjs_int ratioend,\n\ttjs_int samples, tjs_int channels)\n{\n\ttjs_uint blend_step = (tjs_int)(\n\t\t(\n\t\t\t(ratioend - ratiostart) * ((tjs_int64)1<<32) / 100\n\t\t) / samples);\n\tconst T *s1 = (const T *)src1;\n\tconst T *s2 = (const T *)src2;\n\tT *out = (T *)dest;\n\ttjs_uint ratio = (tjs_int)(ratiostart * ((tjs_int64)1<<32) / 100);\n\tfor(tjs_int i = 0; i < samples; i++)\n\t{\n\t\tfor(tjs_int j = channels - 1; j >= 0; j--)\n\t\t{\n\t\t\ttjs_int si1 = (tjs_int)*s1;\n\t\t\ttjs_int si2 = (tjs_int)*s2;\n\t\t\ttjs_int o = (tjs_int) (\n\t\t\t\t\t\t(((tjs_int64)si2 * (tjs_uint64)ratio) >> 32) +\n\t\t\t\t\t\t(((tjs_int64)si1 * (0x100000000ull - (tjs_uint64)ratio) ) >> 32) );\n\t\t\t*out = o;\n\t\t\ts1 ++;\n\t\t\ts2 ++;\n\t\t\tout ++;\n\t\t}\n\t\tratio += blend_step;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveLoopManager\n//---------------------------------------------------------------------------\ntTVPWaveLoopManager::tTVPWaveLoopManager()\n{\n\tPosition = 0;\n\tIsLinksSorted = false;\n\tIsLabelsSorted = false;\n\tCrossFadeSamples = NULL;\n\tCrossFadeLen = 0;\n\tCrossFadePosition = 0;\n\tDecoder = NULL;\n\tIgnoreLinks = false;\n\tLooping = false;\n\n\tFormat = new tTVPWaveFormat;\n\tmemset(Format, 0, sizeof(*Format));\n\n\tClearFlags();\n\tFlagsModifiedByLabelExpression = false;\n}\n//---------------------------------------------------------------------------\ntTVPWaveLoopManager::~tTVPWaveLoopManager()\n{\n\tClearCrossFadeInformation();\n\tdelete Format;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetDecoder(tTVPWaveDecoder * decoder)\n{\n\t// set decoder and compute ShortCrossFadeHalfSamples\n\tDecoder = decoder;\n\tif(decoder)\n\t\tdecoder->GetFormat(*Format);\n\telse\n\t\tmemset(Format, 0, sizeof(*Format));\n\tShortCrossFadeHalfSamples =\n\t\tFormat->SamplesPerSec * TVP_WL_SMOOTH_TIME_HALF / 1000;\n}\n//---------------------------------------------------------------------------\nint tTVPWaveLoopManager::GetFlag(tjs_int index)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\treturn Flags[index];\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::CopyFlags(tjs_int *dest)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\t// copy flags into dest, and clear FlagsModifiedByLabelExpression\n\tmemcpy(dest, Flags, sizeof(Flags));\n\tFlagsModifiedByLabelExpression = false;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetFlagsModifiedByLabelExpression()\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\treturn FlagsModifiedByLabelExpression;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetFlag(tjs_int index, tjs_int f)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\tif(f < 0) f = 0;\n\tif(f > TVP_WL_MAX_FLAG_VALUE) f = TVP_WL_MAX_FLAG_VALUE;\n\tFlags[index] = f;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::ClearFlags()\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\tfor(tjs_int i = 0; i < TVP_WL_MAX_FLAGS; i++) Flags[i] = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::ClearLinksAndLabels()\n{\n\t// clear links and labels\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\tLabels.clear();\n\tLinks.clear();\n\tIsLinksSorted = false;\n\tIsLabelsSorted = false;\n}\n//---------------------------------------------------------------------------\nconst std::vector<tTVPWaveLoopLink> & tTVPWaveLoopManager::GetLinks() const\n{\n\tvolatile tTJSCriticalSectionHolder\n\t\tCS(const_cast<tTVPWaveLoopManager*>(this)->FlagsCS);\n\treturn Links;\n}\n//---------------------------------------------------------------------------\nconst std::vector<tTVPWaveLabel> & tTVPWaveLoopManager::GetLabels() const\n{\n\tvolatile tTJSCriticalSectionHolder\n\t\tCS(const_cast<tTVPWaveLoopManager*>(this)->FlagsCS);\n\treturn Labels;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetLinks(const std::vector<tTVPWaveLoopLink> & links)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\tLinks = links;\n\tIsLinksSorted = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetLabels(const std::vector<tTVPWaveLabel> & labels)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\tLabels = labels;\n\tIsLabelsSorted = false;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetIgnoreLinks() const\n{\n\tvolatile tTJSCriticalSectionHolder\n\t\tCS(const_cast<tTVPWaveLoopManager*>(this)->DataCS);\n\treturn IgnoreLinks;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetIgnoreLinks(bool b)\n{\n\tvolatile tTJSCriticalSectionHolder CS(DataCS);\n\tIgnoreLinks = b;\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTVPWaveLoopManager::GetPosition() const\n{\n\t// we cannot assume that the 64bit data access is truely atomic on 32bit machines.\n\tvolatile tTJSCriticalSectionHolder\n\t\tCS(const_cast<tTVPWaveLoopManager*>(this)->FlagsCS);\n\treturn Position;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::SetPosition(tjs_int64 pos)\n{\n\tvolatile tTJSCriticalSectionHolder CS(DataCS);\n\tPosition = pos;\n\tClearCrossFadeInformation();\n\tDecoder->SetPosition(pos);\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue & segments)\n{\n\t// decode from current position\n\t// note that segements will not be cleared\n\tvolatile tTJSCriticalSectionHolder CS(DataCS);\n\n//\tsegments.clear();  ///!!! NOT CLEARED !!!!\n\twritten = 0;\n\ttjs_uint8 *d = (tjs_uint8*)dest;\n\n\ttjs_int give_up_count = 0;\n\n\tstd::deque<tTVPWaveLabel> labels;\n\n\twhile(written != samples/* && Position < Format->TotalSamples*/)\n\t{\n\t\t// clear labels\n\t\tlabels.clear();\n\n\t\t// decide next operation\n\t\ttjs_int64 next_event_pos;\n\t\tbool next_not_found = false;\n\t\ttjs_int before_count;\n\n\t\t// check nearest link\n\t\ttTVPWaveLoopLink link;\n\t\tif(!IgnoreLinks && GetNearestEvent(Position, link, false))\n\t\t{\n\t\t\t// nearest event found ...\n\t\t\tif(link.From == Position)\n\t\t\t{\n\t\t\t\t// do jump\n\t\t\t\tgive_up_count ++;\n\t\t\t\tif(give_up_count >= TVPWaveLoopLinkGiveUpCount)\n\t\t\t\t\tbreak; // give up decoding\n\n\t\t\t\tPosition = link.To;\n\t\t\t\tif(!CrossFadeSamples)\n\t\t\t\t\tDecoder->SetPosition(Position);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(link.Smooth)\n\t\t\t{\n\t\t\t\t// the nearest event is a smooth link\n\t\t\t\t// bofore_count is sample count before 50%-50% blend\n\t\t\t\t// after_count  is sample count after  50%-50% blend\n\t\t\t\tbefore_count = ShortCrossFadeHalfSamples;\n\t\t\t\t// adjust before count\n\t\t\t\tif(link.From - before_count < 0)\n\t\t\t\t\tbefore_count = (tjs_int)link.From;\n\t\t\t\tif(link.To - before_count < 0)\n\t\t\t\t\tbefore_count = (tjs_int)link.To;\n\t\t\t\tif(link.From - before_count > Position)\n\t\t\t\t{\n\t\t\t\t\t// Starting crossfade is the nearest next event,\n\t\t\t\t\t// but some samples must be decoded before the event comes.\n\t\t\t\t\tnext_event_pos = link.From - before_count;\n\t\t\t\t}\n\t\t\t\telse if(!CrossFadeSamples)\n\t\t\t\t{\n\t\t\t\t\t// just position to start crossfade\n\t\t\t\t\t// or crossfade must already start\n\t\t\t\t\tnext_event_pos = link.From;\n\t\t\t\t\t// adjust before_count\n\t\t\t\t\tbefore_count = static_cast<tjs_int>(link.From - Position);\n\t\t\t\t\t// adjust after count\n\t\t\t\t\ttjs_int after_count = ShortCrossFadeHalfSamples;\n\t\t\t\t\tif(Format->TotalSamples - link.From < after_count)\n\t\t\t\t\t\tafter_count =\n\t\t\t\t\t\t\t(tjs_int)(Format->TotalSamples - link.From);\n\t\t\t\t\tif(Format->TotalSamples - link.To < after_count)\n\t\t\t\t\t\tafter_count =\n\t\t\t\t\t\t\t(tjs_int)(Format->TotalSamples - link.To);\n\t\t\t\t\ttTVPWaveLoopLink over_to_link;\n\t\t\t\t\tif(GetNearestEvent(link.To, over_to_link, true))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(over_to_link.From - link.To < after_count)\n\t\t\t\t\t\t\tafter_count =\n\t\t\t\t\t\t\t\t(tjs_int)(over_to_link.From - link.To);\n\t\t\t\t\t}\n\t\t\t\t\t// prepare crossfade\n\t\t\t\t\t// allocate memory\n\t\t\t\t\ttjs_uint8 *src1 = NULL;\n\t\t\t\t\ttjs_uint8 *src2 = NULL;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_int alloc_size =\n\t\t\t\t\t\t\t(before_count + after_count) * \n\t\t\t\t\t\t\t\tFormat->BytesPerSample * Format->Channels;\n\t\t\t\t\t\tCrossFadeSamples = new tjs_uint8[alloc_size];\n\t\t\t\t\t\tsrc1 = new tjs_uint8[alloc_size];\n\t\t\t\t\t\tsrc2 = new tjs_uint8[alloc_size];\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\t// memory allocation failed. perform normal link.\n\t\t\t\t\t\tif(CrossFadeSamples)\n\t\t\t\t\t\t\tdelete [] CrossFadeSamples,\n\t\t\t\t\t\t\t\tCrossFadeSamples = NULL;\n\t\t\t\t\t\tif(src1) delete [] src1;\n\t\t\t\t\t\tif(src2) delete [] src2;\n\t\t\t\t\t\tnext_event_pos = link.From;\n\t\t\t\t\t}\n\t\t\t\t\tif(CrossFadeSamples)\n\t\t\t\t\t{\n\t\t\t\t\t\t// decode samples\n\t\t\t\t\t\ttjs_uint decoded1 = 0, decoded2 = 0;\n\n\t\t\t\t\t\tDecoder->Render((void*)src1,\n\t\t\t\t\t\t\tbefore_count + after_count, decoded1);\n\n\t\t\t\t\t\tDecoder->SetPosition(\n\t\t\t\t\t\t\tlink.To - before_count);\n\n\t\t\t\t\t\tDecoder->Render((void*)src2,\n\t\t\t\t\t\t\tbefore_count + after_count, decoded2);\n\n\t\t\t\t\t\t// perform crossfade\n\t\t\t\t\t\ttjs_int after_offset =\n\t\t\t\t\t\t\tbefore_count * Format->BytesPerSample * Format->Channels;\n\t\t\t\t\t\tDoCrossFade(CrossFadeSamples,\n\t\t\t\t\t\t\tsrc1, src2, before_count, 0, 50);\n\t\t\t\t\t\tDoCrossFade(CrossFadeSamples + after_offset,\n\t\t\t\t\t\t\tsrc1 + after_offset, src2 + after_offset,\n\t\t\t\t\t\t\t\tafter_count, 50, 100);\n\t\t\t\t\t\tdelete [] src1;\n\t\t\t\t\t\tdelete [] src2;\n\t\t\t\t\t\t// reset CrossFadePosition and CrossFadeLen\n\t\t\t\t\t\tCrossFadePosition = 0;\n\t\t\t\t\t\tCrossFadeLen = before_count + after_count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnext_event_pos = link.From;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// normal jump\n\t\t\t\tnext_event_pos = link.From;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// event not found\n\t\t\tnext_not_found = true;\n\t\t}\n\n\t\ttjs_int one_unit;\n\n\t\tif(next_not_found || next_event_pos - Position > (samples - written))\n\t\t\tone_unit = samples - written;\n\t\telse\n\t\t\tone_unit = (tjs_int) (next_event_pos - Position);\n\n\t\tif(CrossFadeSamples)\n\t\t{\n\t\t\tif(one_unit > CrossFadeLen - CrossFadePosition)\n\t\t\t\tone_unit = CrossFadeLen - CrossFadePosition;\n\t\t}\n\n\t\tif(one_unit > 0) give_up_count = 0; // reset give up count\n\n\t\t// evaluate each label\n\t\tGetLabelAt(Position, Position + one_unit, labels);\n\t\tfor(std::deque<tTVPWaveLabel>::iterator i = labels.begin();\n\t\t\ti != labels.end(); i++)\n\t\t{\n\t\t\tif(i->Name.c_str()[0] == ':')\n\t\t\t{\n\t\t\t\t// for each label\n\t\t\t\tEvalLabelExpression(i->Name);\n\t\t\t}\n\t\t}\n\n\t\t// calculate each label offset\n\t\tfor(std::deque<tTVPWaveLabel>::iterator i = labels.begin();\n\t\t\ti != labels.end(); i++)\n\t\t\ti->Offset = (tjs_int)(i->Position - Position) + written;\n\n\t\t// enqueue labels\n\t\tsegments.Enqueue(labels);\n\n\t\t// enqueue segment\n\t\tsegments.Enqueue(tTVPWaveSegment(Position, one_unit));\n\n\t\t// decode or copy\n\t\tif(!CrossFadeSamples)\n\t\t{\n\t\t\t// not crossfade\n\t\t\t// decode direct into destination buffer\n\t\t\ttjs_uint decoded;\n\t\t\tDecoder->Render((void *)d, one_unit, decoded);\n\t\t\tPosition += decoded;\n\t\t\twritten += decoded;\n\t\t\tif(decoded != (tjs_uint)one_unit)\n\t\t\t{\n\t\t\t\t// must be the end of the decode\n\t\t\t\tif(!Looping) break; // end decoding\n\t\t\t\t// rewind and continue\n\t\t\t\tif(Position == 0)\n\t\t\t\t{\n\t\t\t\t\t// already rewinded; must be an error\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tPosition = 0;\n\t\t\t\tDecoder->SetPosition(0);\n\t\t\t}\n\t\t\td += decoded * Format->BytesPerSample * Format->Channels;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// in cross fade\n\t\t\t// copy prepared samples\n\t\t\tmemcpy((void *)d,\n\t\t\t\tCrossFadeSamples +\n\t\t\t\t\tCrossFadePosition * Format->BytesPerSample * Format->Channels,\n\t\t\t\tone_unit * Format->BytesPerSample * Format->Channels);\n\t\t\tCrossFadePosition += one_unit;\n\t\t\tPosition += one_unit;\n\t\t\twritten += one_unit;\n\t\t\td += one_unit * Format->BytesPerSample * Format->Channels;\n\t\t\tif(CrossFadePosition == CrossFadeLen)\n\t\t\t{\n\t\t\t\t// crossfade has finished\n\t\t\t\tClearCrossFadeInformation();\n\t\t\t}\n\t\t}\n\t}\t// while \n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetNearestEvent(tjs_int64 current,\n\t\ttTVPWaveLoopLink & link, bool ignore_conditions)\n{\n\t// search nearest event in future, from current.\n\t// this checks conditions unless ignore_conditions is true.\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\n\tif(Links.size() == 0) return false; // there are no event\n\n\tif(!IsLinksSorted)\n\t{\n\t\tstd::sort(Links.begin(), Links.end());\n\t\tIsLinksSorted = true;\n\t}\n\n\t// search nearest next event using binary search\n\ttjs_int s = 0, e = (tjs_int)Links.size();\n\twhile(e - s > 1)\n\t{\n\t\ttjs_int m = (s+e)/2;\n\t\tif(Links[m].From <= current)\n\t\t\ts = m;\n\t\telse\n\t\t\te = m;\n\t}\n\n\tif(s < (int)Links.size()-1 && Links[s].From < current) s++;\n\n\tif((tjs_uint)s >= Links.size() || Links[s].From < current)\n\t{\n\t\t// no links available\n\t\treturn false;\n\t}\n\n\t// rewind while the link 'from' is the same\n\ttjs_int64 from = Links[s].From;\n\twhile(true)\n\t{\n\t\tif(s >= 1 && Links[s-1].From == from)\n\t\t\ts--;\n\t\telse\n\t\t\tbreak;\n\t}\n\n\t// check conditions\n\tif(!ignore_conditions)\n\t{\n\t\tdo\n\t\t{\n\t\t\t// check condition\n\t\t\tif(Links[s].CondVar != -1)\n\t\t\t{\n\t\t\t\tbool match = false;\n\t\t\t\tswitch(Links[s].Condition)\n\t\t\t\t{\n\t\t\t\tcase llcNone:\n\t\t\t\t\tmatch = true; break;\n\t\t\t\tcase llcEqual:\n\t\t\t\t\tif(Links[s].RefValue == Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase llcNotEqual:\n\t\t\t\t\tif(Links[s].RefValue != Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase llcGreater:\n\t\t\t\t\tif(Links[s].RefValue <  Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase llcGreaterOrEqual:\n\t\t\t\t\tif(Links[s].RefValue <= Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase llcLesser:\n\t\t\t\t\tif(Links[s].RefValue >  Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase llcLesserOrEqual:\n\t\t\t\t\tif(Links[s].RefValue >= Flags[Links[s].CondVar]) match = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tmatch = false;\n\t\t\t\t}\n\t\t\t\tif(match) break; // condition matched\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ts++;\n\t\t} while((tjs_uint)s < Links.size());\n\n\t\tif((tjs_uint)s >= Links.size() || Links[s].From < current)\n\t\t{\n\t\t\t// no links available\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tlink = Links[s];\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::GetLabelAt(tjs_int64 from, tjs_int64 to,\n\t\tstd::deque<tTVPWaveLabel> & labels)\n{\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\n\tif(Labels.size() == 0) return; // no labels found\n\tif(!IsLabelsSorted)\n\t{\n\t\tstd::sort(Labels.begin(), Labels.end());\n\t\tIsLabelsSorted = true;\n\t}\n\n\t// search nearest label using binary search\n\ttjs_int s = 0, e = (tjs_int)Labels.size();\n\twhile(e - s > 1)\n\t{\n\t\ttjs_int m = (s+e)/2;\n\t\tif(Labels[m].Position <= from)\n\t\t\ts = m;\n\t\telse\n\t\t\te = m;\n\t}\n\n\tif(s < (int)Labels.size()-1 && Labels[s].Position < from) s++;\n\n\tif((tjs_uint)s >= Labels.size() || Labels[s].Position < from)\n\t{\n\t\t// no labels available\n\t\treturn;\n\t}\n\n\t// rewind while the label position is the same\n\ttjs_int64 pos = Labels[s].Position;\n\twhile(true)\n\t{\n\t\tif(s >= 1 && Labels[s-1].Position == pos)\n\t\t\ts--;\n\t\telse\n\t\t\tbreak;\n\t}\n\n\t// search labels\n\tfor(; s < (int)Labels.size(); s++)\n\t{\n\t\tif(Labels[s].Position >= from && Labels[s].Position < to)\n\t\t\tlabels.emplace_back(Labels[s]);\n\t\telse\n\t\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::DoCrossFade(void *dest, void *src1,\n\tvoid *src2, tjs_int samples, tjs_int ratiostart, tjs_int ratioend)\n{\n\t// do on-memory wave crossfade\n\t// using src1 (fading out) and src2 (fading in).\n\tif(samples == 0) return; // nothing to do\n\n\tif(Format->IsFloat)\n\t{\n\t\tfloat blend_step =\n\t\t\t(float)((ratioend - ratiostart) / 100.0 / samples);\n\t\tconst float *s1 = (const float *)src1;\n\t\tconst float *s2 = (const float *)src2;\n\t\tfloat *out = (float *)dest;\n\t\tfloat ratio = static_cast<float>(ratiostart / 100.0);\n\t\tfor(tjs_int i = 0; i < samples; i++)\n\t\t{\n\t\t\tfor(tjs_int j = Format->Channels - 1; j >= 0; j--)\n\t\t\t{\n\t\t\t\t*out = *s1 + (*s2 - *s1) * ratio;\n\t\t\t\ts1 ++;\n\t\t\t\ts2 ++;\n\t\t\t\tout ++;\n\t\t\t}\n\t\t\tratio += blend_step;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(Format->BytesPerSample == 1)\n\t\t{\n\t\t\tTVPCrossFadeIntegerBlend<tTVPPCM8>(dest, src1, src2,\n\t\t\t\tratiostart, ratioend, samples, Format->Channels);\n\t\t}\n\t\telse if(Format->BytesPerSample == 2)\n\t\t{\n\t\t\tTVPCrossFadeIntegerBlend<tjs_int16>(dest, src1, src2,\n\t\t\t\tratiostart, ratioend, samples, Format->Channels);\n\t\t}\n\t\telse if(Format->BytesPerSample == 3)\n\t\t{\n\t\t\tTVPCrossFadeIntegerBlend<tTVPPCM24>(dest, src1, src2,\n\t\t\t\tratiostart, ratioend, samples, Format->Channels);\n\t\t}\n\t\telse if(Format->BytesPerSample == 4)\n\t\t{\n\t\t\tTVPCrossFadeIntegerBlend<tjs_int32>(dest, src1, src2,\n\t\t\t\tratiostart, ratioend, samples, Format->Channels);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::ClearCrossFadeInformation()\n{\n\tif(CrossFadeSamples) delete [] CrossFadeSamples, CrossFadeSamples = NULL;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetLabelExpression(const tTVPLabelStringType &label,\n\ttTVPWaveLoopManager::tExpressionToken * ope,\n\ttjs_int *lv,\n\ttjs_int *rv, bool *is_rv_indirect)\n{\n\tconst tTVPLabelCharType * p = label.c_str();\n\ttExpressionToken token;\n\ttExpressionToken operation;\n\ttjs_int value  = 0;\n\ttjs_int lvalue = 0;\n\ttjs_int rvalue = 0;\n\tbool rv_indirect = false;\n\n\tif(*p != ':') return false; // not expression\n\tp++;\n\n\ttoken = GetExpressionToken(p, &value);\n\tif(token != etLBracket) return false; // lvalue must form of '[' integer ']'\n\ttoken = GetExpressionToken(p, &value);\n\tif(token != etInteger) return false; // lvalue must form of '[' integer ']'\n\tlvalue = value;\n\tif(lvalue < 0 || lvalue >= TVP_WL_MAX_FLAGS) return false; // out of the range\n\ttoken = GetExpressionToken(p, &value);\n\tif(token != etRBracket) return false; // lvalue must form of '[' integer ']'\n\n\ttoken = GetExpressionToken(p, &value);\n\tswitch(token)\n\t{\n\tcase etEqual:\n\tcase etPlusEqual:  case etIncrement:\n\tcase etMinusEqual: case etDecrement:\n\t\tbreak;\n\tdefault:\n\t\treturn false; // unknown operation\n\t}\n\toperation = token;\n\n\ttoken = GetExpressionToken(p, &value);\n\tif(token == etLBracket)\n\t{\n\t\t// indirect value\n\t\ttoken = GetExpressionToken(p, &value);\n\t\tif(token != etInteger) return false; // rvalue does not have form of '[' integer ']'\n\t\trvalue = value;\n\t\tif(rvalue < 0 || rvalue >= TVP_WL_MAX_FLAGS) return false; // out of the range\n\t\ttoken = GetExpressionToken(p, &value);\n\t\tif(token != etRBracket) return false; // rvalue does not have form of '[' integer ']'\n\t\trv_indirect = true;\n\t}\n\telse if(token == etInteger)\n\t{\n\t\t// direct value\n\t\trv_indirect = false;\n\t\trvalue = value;\n\t}\n\telse if(token == etEOE)\n\t{\n\t\tif(!(operation == etIncrement || operation == etDecrement))\n\t\t\treturn false; // increment or decrement cannot have operand\n\t}\n\telse\n\t{\n\t\treturn false; // syntax error\n\t}\n\n\ttoken = GetExpressionToken(p, &value);\n\tif(token != etEOE) return false; // excess characters\n\n\tif(ope) *ope = operation;\n\tif(lv)  *lv = lvalue;\n\tif(rv)  *rv = rvalue;\n\tif(is_rv_indirect) * is_rv_indirect = rv_indirect;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::EvalLabelExpression(const tTVPLabelStringType &label)\n{\n\t// eval expression specified by 'label'\n\t// commit the result when 'commit' is true.\n\t// returns whether the label syntax is correct.\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\n\ttExpressionToken operation;\n\ttjs_int lvalue;\n\ttjs_int rvalue;\n\tbool is_rv_indirect;\n\n\tif(!GetLabelExpression(label, &operation, &lvalue, &rvalue, &is_rv_indirect)) return false;\n\n\tif(is_rv_indirect) rvalue = Flags[rvalue];\n\n\tswitch(operation)\n\t{\n\tcase etEqual:\n\t\tFlagsModifiedByLabelExpression = true;\n\t\tFlags[lvalue] = rvalue;\n\t\tbreak;\n\tcase etPlusEqual:\n\t\tFlagsModifiedByLabelExpression = true;\n\t\tFlags[lvalue] += rvalue;\n\t\tbreak;\n\tcase etMinusEqual:\n\t\tFlagsModifiedByLabelExpression = true;\n\t\tFlags[lvalue] -= rvalue;\n\t\tbreak;\n\tcase etIncrement:\n\t\tFlagsModifiedByLabelExpression = true;\n\t\tFlags[lvalue] ++;\n\t\tbreak;\n\tcase etDecrement:\n\t\tFlagsModifiedByLabelExpression = true;\n\t\tFlags[lvalue] --;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif(Flags[lvalue] < 0) Flags[lvalue] = 0;\n\tif(Flags[lvalue] > TVP_WL_MAX_FLAG_VALUE) Flags[lvalue] = TVP_WL_MAX_FLAG_VALUE;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\ntTVPWaveLoopManager::tExpressionToken\n\ttTVPWaveLoopManager::GetExpressionToken(const tTVPLabelCharType *  & p, tjs_int * value)\n{\n\t// get token at pointer 'p'\n\n\twhile(*p && *p <= 0x20) p++; // skip spaces\n\tif(!*p) return etEOE;\n\n\tswitch(*p)\n\t{\n\tcase '0': case '1': case '2': case '3': case '4':\n\tcase '5': case '6': case '7': case '8': case '9':\n\t\t// numbers\n\t\tif(value) GetLabelCharInt(p, *value);\n\t\twhile(*p && *p >= '0' && *p <= '9') p++;\n\t\treturn etInteger;\n\n\tcase '[':\n\t\tp++;\n\t\treturn etLBracket;\n\tcase ']':\n\t\tp++;\n\t\treturn etRBracket;\n\n\tcase '=':\n\t\tp++;\n\t\treturn etEqual;\n\n\tcase '+':\n\t\tp++;\n\t\tif(*p == '=') { p++; return etPlusEqual; }\n\t\tif(*p == '+') { p++; return etIncrement; }\n\t\treturn etPlus;\n\tcase '-':\n\t\tp++;\n\t\tif(*p == '=') { p++; return etMinusEqual; }\n\t\tif(*p == '-') { p++; return etDecrement; }\n\t\treturn etPlus;\n\n\tdefault:\n\t\t;\n\t}\n\n\tp++;\n\treturn etUnknown;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetLabelCharInt(const tTVPLabelCharType *s, tjs_int &v)\n{\n\t// convert string to integer\n\ttjs_int r = 0;\n\tbool sign = false;\n\twhile(*s && *s <= 0x20) s++; // skip spaces\n\tif(!*s) return false;\n\tif(*s == '-')\n\t{\n\t\tsign = true;\n\t\ts++;\n\t\twhile(*s && *s <= 0x20) s++; // skip spaces\n\t\tif(!*s) return false;\n\t}\n\n\twhile(*s >= '0' && *s <= '9')\n\t{\n\t\tr *= 10;\n\t\tr += *s - '0';\n\t\ts++;\n\t}\n\tif(sign) r = -r;\n\tv = r;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetInt(char *s, tjs_int &v)\n{\n\t// convert string to integer\n\ttjs_int r = 0;\n\tbool sign = false;\n\twhile(*s && *s <= 0x20) s++; // skip spaces\n\tif(!*s) return false;\n\tif(*s == '-')\n\t{\n\t\tsign = true;\n\t\ts++;\n\t\twhile(*s && *s <= 0x20) s++; // skip spaces\n\t\tif(!*s) return false;\n\t}\n\n\twhile(*s >= '0' && *s <= '9')\n\t{\n\t\tr *= 10;\n\t\tr += *s - '0';\n\t\ts++;\n\t}\n\tif(sign) r = -r;\n\tv = r;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetInt64(char *s, tjs_int64 &v)\n{\n\t// convert string to integer\n\ttjs_int64 r = 0;\n\tbool sign = false;\n\twhile(*s && *s <= 0x20) s++; // skip spaces\n\tif(!*s) return false;\n\tif(*s == '-')\n\t{\n\t\tsign = true;\n\t\ts++;\n\t\twhile(*s && *s <= 0x20) s++; // skip spaces\n\t\tif(!*s) return false;\n\t}\n\n\twhile(*s >= '0' && *s <= '9')\n\t{\n\t\tr *= 10;\n\t\tr += *s - '0';\n\t\ts++;\n\t}\n\tif(sign) r = -r;\n\tv = r;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetBool(char *s, bool &v)\n{\n\t// convert string to boolean\n\tif(!strcasecmp(s, \"True\"))\t\t{\tv = true;\treturn true;\t}\n\tif(!strcasecmp(s, \"False\"))\t\t{\tv = false;\treturn true;\t}\n\tif(!strcasecmp(s, \"Yes\"))\t\t{\tv = true;\treturn true;\t}\n\tif(!strcasecmp(s, \"No\"))\t\t{\tv = false;\treturn true;\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetCondition(char *s, tTVPWaveLoopLinkCondition &v)\n{\n\t// get condition value\n\tif(!strcasecmp(s, \"no\"))\t\t{ v = llcNone;\t\t\t\treturn true;\t}\n\tif(!strcasecmp(s, \"eq\"))\t\t{ v = llcEqual;\t\t\t\treturn true;\t}\n\tif(!strcasecmp(s, \"ne\"))\t\t{ v = llcNotEqual;\t\t\treturn true;\t}\n\tif(!strcasecmp(s, \"gt\"))\t\t{ v = llcGreater;\t\t\treturn true;\t}\n\tif(!strcasecmp(s, \"ge\"))\t\t{ v = llcGreaterOrEqual;\treturn true;\t}\n\tif(!strcasecmp(s, \"lt\"))\t\t{ v = llcLesser;\t\t\treturn true;\t}\n\tif(!strcasecmp(s, \"le\"))\t\t{ v = llcLesserOrEqual;\t\treturn true;\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetString(char *s, tTVPLabelStringType &v)\n{\n\t// convert utf-8 string s to v\n\n\t// compute output (unicode) size\n\ttjs_int size = TVPUtf8ToWideCharString(s, NULL);\n\tif(size == -1) return false; // not able to convert the string\n\n\t// allocate output buffer\n\ttjs_char *us = new tjs_char[size + 1];\n\ttry\n\t{\n\t\tTVPUtf8ToWideCharString(s, us);\n\t\tus[size] = TJS_W('\\0');\n\n#ifdef TVP_IN_LOOP_TUNER\n\t\t// convert us (an array of wchar_t) to AnsiString\n\t\tv = AnsiString(us);\n#else\n\t\t// convert us (an array of wchar_t) to ttstr\n\t\tv = ttstr(us);\n#endif\n\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] us;\n\t\tthrow;\n\t}\n\tdelete [] us;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::GetEntityToken(char * & p, char **name, char **value)\n{\n\t// get name=value string at 'p'.\n\t// returns whether the token can be got or not.\n\t// on success, *id will point start of the name, and value will point\n\t// start of the value. the buffer given by 'start' will be destroied.\n\n\tchar * namelast;\n\tchar * valuelast;\n\tchar delimiter = '\\0';\n\n\t// skip preceeding white spaces\n\twhile(isspace(*p)) p++;\n\tif(!*p) return false;\n\n\t// p will now be a name\n\t*name = p;\n\n\t// find white space or '='\n\twhile(!isspace(*p) && *p != '=' && *p) p++;\n\tif(!*p) return false;\n\n\tnamelast = p;\n\n\t// skip white space\n\twhile(isspace(*p)) p++;\n\tif(!*p) return false;\n\n\t// is current pointer pointing '='  ?\n\tif(*p != '=') return false;\n\n\t// step pointer\n\tp ++;\n\tif(!*p) return false;\n\n\t// skip white space\n\twhile(isspace(*p)) p++;\n\tif(!*p) return false;\n\n\t// find delimiter\n\tif(*p == '\\'') delimiter = *p, p++;\n\tif(!*p) return false;\n\n\t// now p will be start of value\n\t*value = p;\n\n\t// find delimiter or white space or ';'\n\tif(delimiter == '\\0')\n\t{\n\t\twhile((!isspace(*p) && *p != ';') && *p) p++;\n\t}\n\telse\n\t{\n\t\twhile((*p != delimiter) && *p) p++;\n\t}\n\n\t// remember value last point\n\tvaluelast = p;\n\n\t// skip last delimiter\n\tif(*p == delimiter) p++;\n\n\t// put null terminator\n\t*namelast = '\\0';\n\t*valuelast = '\\0';\n\n\t// finish\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::ReadLinkInformation(char * & p, tTVPWaveLoopLink &link)\n{\n\t// read link information from 'p'.\n\t// p must point '{' , which indicates start of the block.\n\tif(*p != '{') return false;\n\n\tp++;\n\tif(!*p) return false;\n\n\tdo\n\t{\n\t\t// get one token from 'p'\n\t\tchar * name;\n\t\tchar * value;\n\t\tif(!GetEntityToken(p, &name, &value))\n\t\t\treturn false;\n\n\t\tif(!strcasecmp(name, \"From\"))\n\t\t{\tif(!GetInt64(value, link.From))\t\t\t\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"To\"))\n\t\t{\tif(!GetInt64(value, link.To))\t\t\t\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"Smooth\"))\n\t\t{\tif(!GetBool(value, link.Smooth))\t\t\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"Condition\"))\n\t\t{\tif(!GetCondition(value, link.Condition))\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"RefValue\"))\n\t\t{\tif(!GetInt(value, link.RefValue))\t\t\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"CondVar\"))\n\t\t{\tif(!GetInt(value, link.CondVar))\t\t\t\treturn false;}\n\t\telse\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\treturn false;}\n\n\t\t// skip space\n\t\twhile(isspace(*p)) p++;\n\n\t\t// check ';'. note that this will also be a null, if no delimiters are used\n\t\tif(*p != ';' && *p != '\\0') return false;\n\t\tp++;\n\t\tif(!*p) return false;\n\n\t\t// skip space\n\t\twhile(isspace(*p)) p++;\n\t\tif(!*p) return false;\n\n\t\t// check '}'\n\t\tif(*p == '}') break;\n\t} while(true);\n\n\tp++;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::ReadLabelInformation(char * & p, tTVPWaveLabel &label)\n{\n\t// read label information from 'p'.\n\t// p must point '{' , which indicates start of the block.\n\tif(*p != '{') return false;\n\n\tp++;\n\tif(!*p) return false;\n\n\tdo\n\t{\n\t\t// get one token from 'p'\n\t\tchar * name;\n\t\tchar * value;\n\t\tif(!GetEntityToken(p, &name, &value))\n\t\t\treturn false;\n\n\t\tif(!strcasecmp(name, \"Position\"))\n\t\t{\tif(!GetInt64(value, label.Position))\t\t\treturn false;}\n\t\telse if(!strcasecmp(name, \"Name\"))\n\t\t{\tif(!GetString(value, label.Name))\t\t\t\treturn false;}\n\t\telse\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\treturn false;}\n\n\t\t// skip space\n\t\twhile(isspace(*p)) p++;\n\n\t\t// check ';'. note that this will also be a null, if no delimiters are used\n\t\tif(*p != ';' && *p != '\\0') return false;\n\t\tp++;\n\t\tif(!*p) return false;\n\n\t\t// skip space\n\t\twhile(isspace(*p)) p++;\n\t\tif(!*p) return false;\n\n\t\t// check '}'\n\t\tif(*p == '}') break;\n\t} while(true);\n\n\tp++;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPWaveLoopManager::ReadInformation(char * p)\n{\n\t// read information from 'p'\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\n\tchar *p_org = p;\n\tLinks.clear();\n\tLabels.clear();\n\n\t// check version\n\tif(*p != '#')\n\t{\n\t\t// old sli format\n\t\tchar *p_length = strstr(p, \"LoopLength=\");\n\t\tchar *p_start  = strstr(p, \"LoopStart=\");\n\t\tif(!p_length || !p_start) return false; // read error\n\t\ttTVPWaveLoopLink link;\n\t\tlink.Smooth = false;\n\t\tlink.Condition = llcNone;\n\t\tlink.RefValue = 0;\n\t\tlink.CondVar = 0;\n\t\ttjs_int64 start;\n\t\ttjs_int64 length;\n\t\tif(!GetInt64(p_length + 11, length)) return false;\n\t\tif(!GetInt64(p_start  + 10, start )) return false;\n\t\tlink.From = start + length;\n\t\tlink.To = start;\n\t\tLinks.emplace_back(link);\n\t}\n\telse\n\t{\n\t\t// sli v2.0+\n\t\tif(strncmp(p, \"#2.00\", 5) > 0)\n\t\t\treturn false; // version mismatch \n\n\t\twhile(true)\n\t\t{\n\t\t\tif((p == p_org || p[-1] == '\\n') && *p == '#')\n\t\t\t{\n\t\t\t\t// line starts with '#' is a comment\n\t\t\t\t// skip the comment\n\t\t\t\twhile(*p != '\\n' && *p) p++;\n\t\t\t\tif(!*p) break;\n\n\t\t\t\tp ++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// skip white space\n\t\t\twhile(isspace(*p)) p++;\n\t\t\tif(!*p) break;\n\n\t\t\t// read id (Link or Label)\n\t\t\tif(!strncasecmp(p, \"Link\", 4) && !isalpha(p[4]))\n\t\t\t{\n\t\t\t\tp += 4;\n\t\t\t\twhile(isspace(*p)) p++;\n\t\t\t\tif(!*p) return false;\n\t\t\t\ttTVPWaveLoopLink link;\n\t\t\t\tif(!ReadLinkInformation(p, link)) return false;\n\t\t\t\tLinks.emplace_back(link);\n\t\t\t}\n\t\t\telse if(!strncasecmp(p, \"Label\", 5) && !isalpha(p[5]))\n\t\t\t{\n\t\t\t\tp += 5;\n\t\t\t\twhile(isspace(*p)) p++;\n\t\t\t\tif(!*p) return false;\n\t\t\t\ttTVPWaveLabel label;\n\t\t\t\tif(!ReadLabelInformation(p, label)) return false;\n\t\t\t\tLabels.emplace_back(label);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false; // read error\n\t\t\t}\n\n\t\t\t// skip white space\n\t\t\twhile(isspace(*p)) p++;\n\t\t\tif(!*p) break;\n\t\t}\n\t}\n\n\treturn true; // done\n}\n\nbool tTVPWaveLoopManager::DesiredFormat(const tTVPWaveFormat & format) {\n\tif (!Decoder->DesiredFormat(format)) return false;\n\tSetDecoder(Decoder);\n\treturn true;\n}\n//---------------------------------------------------------------------------\n#ifdef TVP_IN_LOOP_TUNER\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::PutInt(AnsiString &s, tjs_int v)\n{\n\ts += AnsiString((int)v);\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::PutInt64(AnsiString &s, tjs_int64 v)\n{\n\ts += AnsiString((__int64)v);\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::PutBool(AnsiString &s, bool v)\n{\n\ts += v ? \"True\" : \"False\";\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::PutCondition(AnsiString &s, tTVPWaveLoopLinkCondition v)\n{\n\tswitch(v)\n\t{\n\t\tcase llcNone:             s += \"no\" ; break;\n\t\tcase llcEqual:            s += \"eq\" ; break;\n\t\tcase llcNotEqual:         s += \"ne\" ; break;\n\t\tcase llcGreater:          s += \"gt\" ; break;\n\t\tcase llcGreaterOrEqual:   s += \"ge\" ; break;\n\t\tcase llcLesser:           s += \"lt\" ; break;\n\t\tcase llcLesserOrEqual:    s += \"le\" ; break;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::PutString(AnsiString &s, tTVPLabelStringType v)\n{\n\t// convert v to a utf-8 string\n\tconst tjs_char *pi;\n\n#ifdef TVP_IN_LOOP_TUNER\n\tWideString wstr = v;\n\tpi = wstr.c_bstr();\n#else\n\tpi = v.c_str();\n#endif\n\n\t// count output bytes\n\tint size = TVPWideCharToUtf8String(pi, NULL);\n\n\tchar * out = new char [size + 1];\n\ttry\n\t{\n\t\t// convert the string\n\t\tTVPWideCharToUtf8String(pi, out);\n\t\tout[size] = '\\0';\n\n\t\t// append the string with quotation\n\t\ts += \"\\'\" + AnsiString(out) + \"\\'\";\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] out;\n\t\tthrow;\n\t}\n\tdelete [] out;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::DoSpacing(AnsiString &l, int col)\n{\n\t// fill space until the string becomes specified length\n\tstatic const char * spaces16 = \"                \";\n\tint length = l.Length();\n\tif(length < col)\n\t{\n\t\tint remain = col - length;\n\t\twhile(remain)\n\t\t{\n\t\t\tint one_size = remain > 16 ? 16 : remain;\n\t\t\tl += ((16 - one_size) + spaces16);\n\t\t\tremain -= one_size;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveLoopManager::WriteInformation(AnsiString &s)\n{\n\t// write current link/label information into s\n\tvolatile tTJSCriticalSectionHolder CS(FlagsCS);\n\n\t// write banner\n\ts = \"#2.00\\n# Sound Loop Information (utf-8)\\n\"\n\t\t\"# Generated by WaveLoopManager.cpp\\n\";\n\n\t// write links\n/*\nLink { From=0000000000000000; To=0000000000000000; Smooth=False; Condition=ne; RefValue=444444444; CondVar=99; }\n*/\n\tfor(std::vector<tTVPWaveLoopLink>::iterator i = Links.begin();\n\t\ti != Links.end(); i++)\n\t{\n\t\tAnsiString l;\n\t\tl = \"Link { \";\n\n\t\tl += \"From=\";\n\t\tPutInt64(l, i->From);\n\t\tl += \";\";\n\t\tDoSpacing(l, 30);\n\n\t\tl += \"To=\";\n\t\tPutInt64(l, i->To);\n\t\tl += \";\";\n\t\tDoSpacing(l, 51);\n\n\t\tl += \"Smooth=\";\n\t\tPutBool(l, i->Smooth);\n\t\tl += \";\";\n\t\tDoSpacing(l, 65);\n\n\t\tl += \"Condition=\";\n\t\tPutCondition(l, i->Condition);\n\t\tl += \";\";\n\t\tDoSpacing(l, 79);\n\n\t\tl += \"RefValue=\";\n\t\tPutInt(l, i->RefValue);\n\t\tl += \";\";\n\t\tDoSpacing(l, 100);\n\n\t\tl += \"CondVar=\";\n\t\tPutInt(l, i->CondVar);\n\t\tl += \";\";\n\t\tDoSpacing(l, 112);\n\n\t\tl += \"}\\n\";\n\t\ts += l;\n\t}\n\n\n\t// write labels\n/*\nLabel { Position=0000000000000000; name=\"                                         \"; }\n*/\n\tfor(std::vector<tTVPWaveLabel>::iterator i = Labels.begin();\n\t\ti != Labels.end(); i++)\n\t{\n\t\tAnsiString l;\n\t\tl = \"Label { \";\n\n\t\tl += \"Position=\";\n\t\tPutInt64(l, i->Position);\n\t\tl += \";\";\n\t\tDoSpacing(l, 35);\n\n\t\tl += \"Name=\";\n\t\tPutString(l, i->Name);\n\t\tl += \"; \";\n\t\tDoSpacing(l, 85);\n\n\t\tl += \"}\\n\";\n\t\ts += l;\n\t}\n\n}\n//---------------------------------------------------------------------------\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n\n"
  },
  {
    "path": "src/core/sound/WaveLoopManager.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Loop Manager\n//---------------------------------------------------------------------------\n\n#ifndef WaveLoopManagerH\n#define WaveLoopManagerH\n//---------------------------------------------------------------------------\n\n#include \"tjsTypes.h\"\n#include <vector>\n#include <string>\n#include \"WaveSegmentQueue.h\"\n\n#define TVP_WL_MAX_FLAGS 16\n\n#define TVP_WL_MAX_FLAG_VALUE 9999\n\n#define TVP_WL_SMOOTH_TIME 50\n#define TVP_WL_SMOOTH_TIME_HALF (TVP_WL_SMOOTH_TIME/2)\n\n#define TVP_WL_MAX_ID_LEN 16\n\n#ifdef TVP_IN_LOOP_TUNER\n\t#include \"WaveReader.h\"\n#endif\n\n//---------------------------------------------------------------------------\n#ifdef TVP_IN_LOOP_TUNER\n\ttypedef AnsiString tTVPLabelStringType;\n\ttypedef char   tTVPLabelCharType;\n#else\n\ttypedef ttstr tTVPLabelStringType;\n\ttypedef tjs_char tTVPLabelCharType;\n#endif\n//---------------------------------------------------------------------------\n\n\n#ifdef TVP_IN_LOOP_TUNER\n\t//---------------------------------------------------------------------------\n\t// tTJSCriticalSection ( taken from tjsUtils.h )\n\t//---------------------------------------------------------------------------\n\tclass tTJSCriticalSection\n\t{\n\t\tCRITICAL_SECTION CS;\n\tpublic:\n\t\ttTJSCriticalSection() { InitializeCriticalSection(&CS); }\n\t\t~tTJSCriticalSection() { DeleteCriticalSection(&CS); }\n\n\t\tvoid Enter() { EnterCriticalSection(&CS); }\n\t\tvoid Leave() { LeaveCriticalSection(&CS); }\n\t};\n\t//---------------------------------------------------------------------------\n\t// tTJSCriticalSectionHolder ( taken from tjsUtils.h )\n\t//---------------------------------------------------------------------------\n\tclass tTJSCriticalSectionHolder\n\t{\n\t\ttTJSCriticalSection *Section;\n\tpublic:\n\t\ttTJSCriticalSectionHolder(tTJSCriticalSection &cs)\n\t\t{\n\t\t\tSection = &cs;\n\t\t\tSection->Enter();\n\t\t}\n\n\t\t~tTJSCriticalSectionHolder()\n\t\t{\n\t\t\tSection->Leave();\n\t\t}\n\t};\n#else\n\t#include \"tjsUtils.h\"\n#endif\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveLoopLink : link structure\n//---------------------------------------------------------------------------\nenum tTVPWaveLoopLinkCondition\n{\n\tllcNone,\n\tllcEqual,\n\tllcNotEqual,\n\tllcGreater,\n\tllcGreaterOrEqual,\n\tllcLesser,\n\tllcLesserOrEqual\n};\n//---------------------------------------------------------------------------\nstruct tTVPWaveLoopLink\n{\n\ttjs_int64 From;\t\t// 'From' in sample position\n\ttjs_int64 To;\t\t// 'To' in sample position\n\tbool Smooth;\t\t// Smooth transition (uses short 50ms crossfade)\n\ttTVPWaveLoopLinkCondition Condition;\t// Condition\n\ttjs_int RefValue;\n\ttjs_int CondVar;\t// Condition variable index\n#ifdef TVP_IN_LOOP_TUNER\n\t// these are only used by the loop tuner\n\ttjs_int FromTier;\t// display tier of vertical 'from' line\n\ttjs_int LinkTier;\t// display tier of horizontal link\n\ttjs_int ToTier;\t\t// display tier of vertical 'to' allow line\n\ttjs_int Index;\t\t// link index\n\n\tstruct tSortByDistanceFuncObj\n\t{\n\t\tbool operator()(\n\t\t\tconst tTVPWaveLoopLink &lhs,\n\t\t\tconst tTVPWaveLoopLink &rhs) const\n\t\t{\n\t\t\ttjs_int64 lhs_dist = lhs.From - lhs.To;\n\t\t\tif(lhs_dist < 0) lhs_dist = -lhs_dist;\n\t\t\ttjs_int64 rhs_dist = rhs.From - rhs.To;\n\t\t\tif(rhs_dist < 0) rhs_dist = -rhs_dist;\n\t\t\treturn lhs_dist < rhs_dist;\n\t\t}\n\t};\n\n\tstruct tSortByIndexFuncObj\n\t{\n\t\tbool operator()(\n\t\t\tconst tTVPWaveLoopLink &lhs,\n\t\t\tconst tTVPWaveLoopLink &rhs) const\n\t\t{\n\t\t\treturn lhs.Index < rhs.Index;\n\t\t}\n\t};\n#endif\n\n\ttTVPWaveLoopLink()\n\t{\n\t\tFrom = To = 0;\n\t\tSmooth = false;\n\t\tCondition = llcNone;\n\t\tRefValue = CondVar = 0;\n\n#ifdef TVP_IN_LOOP_TUNER\n\t\tFromTier = LinkTier = ToTier = 0;\n\t\tIndex = 0;\n#endif\n\t}\n};\n//---------------------------------------------------------------------------\nbool inline operator < (const tTVPWaveLoopLink & lhs, const tTVPWaveLoopLink & rhs)\n{\n\tif(lhs.From < rhs.From) return true;\n\tif(lhs.From == rhs.From)\n\t{\n\t\t// give priority to conditional link\n\t\tif(lhs.Condition != rhs.Condition)\n\t\t\treturn lhs.Condition > rhs.Condition;\n\t\t// give priority to conditional expression\n\t\treturn lhs.CondVar > rhs.CondVar;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPSampleAndLabelSource : source interface for sound sample and its label info\n//---------------------------------------------------------------------------\nclass tTVPWaveDecoder;\nstruct tTVPWaveFormat;\nclass tTVPSampleAndLabelSource\n{\npublic:\n\tvirtual void Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue &segments) = 0;\n\n\tvirtual const tTVPWaveFormat & GetFormat() const  = 0;\n\n\tvirtual ~ tTVPSampleAndLabelSource() { }\n\tvirtual bool DesiredFormat(const tTVPWaveFormat & format) { return false; }\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveLoopManager : wave loop manager\n//---------------------------------------------------------------------------\nclass tTVPWaveLoopManager : public tTVPSampleAndLabelSource\n{\n\ttTJSCriticalSection FlagsCS; // CS to protect flags/links/labels\n\tint Flags[TVP_WL_MAX_FLAGS];\n\tbool FlagsModifiedByLabelExpression; // true if the flags are modified by EvalLabelExpression\n\tstd::vector<tTVPWaveLoopLink> Links;\n\tstd::vector<tTVPWaveLabel> Labels;\n\ttTJSCriticalSection DataCS; // CS to protect other members\n\ttTVPWaveFormat * Format;\n\ttTVPWaveDecoder * Decoder;\n\n\ttjs_int ShortCrossFadeHalfSamples;\n\t\t// TVP_WL_SMOOTH_TIME_HALF in sample unit\n\n\tbool Looping;\n\n\ttjs_int64 Position; // decoding position\n\n\ttjs_uint8 *CrossFadeSamples; // sample buffer for crossfading\n\ttjs_int CrossFadeLen;\n\ttjs_int CrossFadePosition;\n\n\tbool IsLinksSorted; // false if links are not yet sorted\n\tbool IsLabelsSorted; // false if labels are not yet sorted\n\n\tbool IgnoreLinks; // decode the samples with ignoring links\n\npublic:\n\ttTVPWaveLoopManager();\n\tvirtual ~tTVPWaveLoopManager();\n\n\tvoid SetDecoder(tTVPWaveDecoder * decoder);\n\n\tint GetFlag(tjs_int index);\n\tvoid CopyFlags(tjs_int *dest);\n\tbool GetFlagsModifiedByLabelExpression();\n\tvoid SetFlag(tjs_int index, tjs_int f);\n\tvoid ClearFlags();\n\tvoid ClearLinksAndLabels();\n\n\tconst std::vector<tTVPWaveLoopLink> & GetLinks() const;\n\tconst std::vector<tTVPWaveLabel> & GetLabels() const;\n\n\tvoid SetLinks(const std::vector<tTVPWaveLoopLink> & links);\n\tvoid SetLabels(const std::vector<tTVPWaveLabel> & labels);\n\n\tbool GetIgnoreLinks() const;\n\tvoid SetIgnoreLinks(bool b);\n\n\ttjs_int64 GetPosition() const;\n\tvoid SetPosition(tjs_int64 pos);\n\n\tbool GetLooping() const { return Looping; }\n\tvoid SetLooping(bool b) { Looping = b; }\n\n\tvoid Decode(void *dest, tjs_uint samples, tjs_uint &written,\n\t\ttTVPWaveSegmentQueue & segments); // from tTVPSampleAndLabelSource\n\n\tconst tTVPWaveFormat & GetFormat() const { return *Format; }\n\t\t\t// from tTVPSampleAndLabelSource\n\tvirtual bool DesiredFormat(const tTVPWaveFormat & format);\n\nprivate:\n\tbool GetNearestEvent(tjs_int64 current,\n\t\ttTVPWaveLoopLink & link, bool ignore_conditions);\n\n\tvoid GetLabelAt(tjs_int64 from, tjs_int64 to,\n\t\tstd::deque<tTVPWaveLabel> & labels);\n\n\tvoid DoCrossFade(void *dest, void *src1, void *src2, tjs_int samples,\n\t\ttjs_int ratiostart, tjs_int ratioend);\n\n\tvoid ClearCrossFadeInformation();\n\n//--- flag manupulation by label expression\n\tenum tExpressionToken {\n\t\tetUnknown,\n\t\tetEOE,\t\t\t// End of the expression\n\t\tetLBracket,\t\t// '['\n\t\tetRBracket,\t\t// ']'\n\t\tetInteger,\t\t// integer number\n\t\tetEqual,\t\t// '='\n\t\tetPlus,\t\t\t// '+'\n\t\tetMinus,\t\t// '-'\n\t\tetPlusEqual,\t// '+='\n\t\tetMinusEqual,\t// '-='\n\t\tetIncrement,\t// '++'\n\t\tetDecrement\t\t// '--'\n\t};\npublic:\n\tstatic bool GetLabelExpression(const tTVPLabelStringType &label,\n\t\ttExpressionToken * ope = NULL,\n\t\ttjs_int *lv = NULL,\n\t\ttjs_int *rv = NULL, bool *is_rv_indirect = NULL);\nprivate:\n\tbool EvalLabelExpression(const tTVPLabelStringType &label);\n\n\tstatic tExpressionToken GetExpressionToken(const tTVPLabelCharType * &  p , tjs_int * value);\n\tstatic bool GetLabelCharInt(const tTVPLabelCharType *s, tjs_int &v);\n\n\n//--- loop information input/output stuff\nprivate:\n\tstatic bool GetInt(char *s, tjs_int &v);\n\tstatic bool GetInt64(char *s, tjs_int64 &v);\n\tstatic bool GetBool(char *s, bool &v);\n\tstatic bool GetCondition(char *s, tTVPWaveLoopLinkCondition &v);\n\tstatic bool GetString(char *s, tTVPLabelStringType &v);\n\n\tstatic bool GetEntityToken(char * & p, char **name, char **value);\n\n\tstatic bool ReadLinkInformation(char * & p, tTVPWaveLoopLink &link);\n\tstatic bool ReadLabelInformation(char * & p, tTVPWaveLabel &label);\npublic:\n\tbool ReadInformation(char * p);\n\n#ifdef TVP_IN_LOOP_TUNER\n\t// output facility (currently only available with VCL interface)\nprivate:\n\tstatic void PutInt(AnsiString &s, tjs_int v);\n\tstatic void PutInt64(AnsiString &s, tjs_int64 v);\n\tstatic void PutBool(AnsiString &s, bool v);\n\tstatic void PutCondition(AnsiString &s, tTVPWaveLoopLinkCondition v);\n\tstatic void PutString(AnsiString &s, tTVPLabelStringType v);\n\tstatic void DoSpacing(AnsiString &l, int col);\npublic:\n\tvoid WriteInformation(AnsiString &s);\n#endif\n\n\npublic:\n};\n//---------------------------------------------------------------------------\n#endif\n\n\n"
  },
  {
    "path": "src/core/sound/WaveSegmentQueue.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Waveセグメント/ラベルキュー管理\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"WaveSegmentQueue.h\"\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Clear()\n{\n\tLabels.clear();\n\tSegments.clear();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Enqueue(const tTVPWaveSegmentQueue & queue)\n{\n\tEnqueue(queue.Labels); // Labels をエンキュー(こっちを先にしないとだめ)\n\tEnqueue(queue.Segments); // segments をキュー(こっちは後)\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Enqueue(const tTVPWaveSegment & segment)\n{\n\tif(Segments.size() > 0)\n\t{\n\t\t// 既存のセグメントが 1 個以上ある\n\t\ttTVPWaveSegment & last = Segments.back();\n\t\t// 最後のセグメントとこれから追加しようとするセグメントが連続してるか？\n\t\tif(last.Start + last.Length == segment.Start &&\n\t\t\t(double)last.FilteredLength / last.Length ==\n\t\t\t(double)segment.FilteredLength / segment.Length)\n\t\t{\n\t\t\t// 連続していて、かつ、比率も完全に同じなので\n\t\t\t// 既存の最後のセグメントを延長する\n\t\t\t// (ちなみにここで比率の比較の際に誤差が生じたとしても\n\t\t\t//  大きな問題とはならない)\n\t\t\tlast.FilteredLength += segment.FilteredLength;\n\t\t\tlast.Length += segment.Length;\n\t\t\treturn ; // おわり\n\t\t}\n\t}\n\n\t// 単純に最後に要素を追加\n\tSegments.push_back(segment);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Enqueue(const tTVPWaveLabel & Label)\n{\n\tLabels.push_back(Label);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Enqueue(const std::deque<tTVPWaveSegment> & segments)\n{\n\t// segment の追加\n\tfor(std::deque<tTVPWaveSegment>::const_iterator i = segments.begin();\n\t\ti != segments.end(); i++)\n\t\tEnqueue(*i);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Enqueue(const std::deque<tTVPWaveLabel> & Labels)\n{\n\t// オフセットに加算する値を得る\n\ttjs_int64 Label_offset = GetFilteredLength();\n\n\t// Label の追加\n\tfor(std::deque<tTVPWaveLabel>::const_iterator i = Labels.begin();\n\t\ti != Labels.end(); i++)\n\t{\n\t\ttTVPWaveLabel one_Label(*i);\n\t\tone_Label.Offset += static_cast<tjs_int>(Label_offset); // offset の修正\n\t\tEnqueue(one_Label);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Dequeue(tTVPWaveSegmentQueue & dest, tjs_int64 length)\n{\n\ttjs_int64 remain;\n\t// dest をクリア\n\tdest.Clear();\n\n\t// Segments を切り出す\n\tremain = length;\n\twhile(Segments.size() > 0 && remain > 0)\n\t{\n\t\tif(Segments.front().FilteredLength <= remain)\n\t\t{\n\t\t\t// Segments.front().FilteredLength が remain 以下\n\t\t\t// → この要素を dest にエンキューして this から削除\n\t\t\tremain -= Segments.front().FilteredLength;\n\t\t\tdest.Enqueue(Segments.front());\n\t\t\tSegments.pop_front();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Segments.front().FilteredLength が remain よりも大きい\n\t\t\t// → 要素を途中でぶったぎって dest にエンキュー\n\t\t\t// FilteredLength を元に切り出しを行ってるので\n\t\t\t// Length は 線形補間を行う\n\t\t\ttjs_int64 newlength =\n\t\t\t\tstatic_cast<tjs_int64>(\n\t\t\t\t\t(double)Segments.front().Length / (double)Segments.front().FilteredLength * remain);\n\t\t\tif(newlength > 0)\n\t\t\t\tdest.Enqueue(tTVPWaveSegment(Segments.front().Start, newlength, remain));\n\n\t\t\t// Segments.front() の Start, Length と FilteredLength を修正\n\t\t\tSegments.front().Start += newlength;\n\t\t\tSegments.front().Length -= newlength;\n\t\t\tSegments.front().FilteredLength -= remain;\n\t\t\tif(Segments.front().Length == 0 || Segments.front().FilteredLength == 0)\n\t\t\t{\n\t\t\t\t// ぶった切った結果 (線形補完した結果の誤差で)\n\t\t\t\t// 長さが0になってしまった\n\t\t\t\tSegments.pop_front(); // セグメントを捨てる\n\t\t\t}\n\t\t\tremain = 0; // ループを抜ける\n\t\t}\n\t}\n\n\t// Labels を切り出す\n\tsize_t Labels_to_dequeue = 0;\n\tfor(std::deque<tTVPWaveLabel>::iterator i = Labels.begin();\n\t\ti != Labels.end(); i++)\n\t{\n\t\ttjs_int64 newoffset = i->Offset - length;\n\t\tif(newoffset < 0)\n\t\t{\n\t\t\t// newoffset が負 なので dest に入れる\n\t\t\tdest.Enqueue(*i);\n\t\t\tLabels_to_dequeue ++; // あとで dequeue\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// *i のオフセットを修正\n\t\t\ti->Offset = static_cast<tjs_int>(newoffset);\n\t\t}\n\t}\n\n\twhile(Labels_to_dequeue--) Labels.pop_front(); // コピーしたLabels を削除\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntjs_int64 tTVPWaveSegmentQueue::GetFilteredLength() const\n{\n\t// キューの長さは すべての Segments のFilteredLengthの合計\n\ttjs_int64 length = 0;\n\tfor(std::deque<tTVPWaveSegment>::const_iterator i = Segments.begin();\n\t\ti != Segments.end(); i++)\n\t\tlength += i->FilteredLength;\n\n\treturn length;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPWaveSegmentQueue::Scale(tjs_int64 new_total_filtered_length)\n{\n\t// キューの FilteredLength を変化させる\n\ttjs_int64 total_length_was = GetFilteredLength(); // 変化前の長さ\n\n\tif(total_length_was == 0) return; // 元の長さがないのでスケール出来ない\n\n\t// Segments の修正\n\ttjs_int64 offset_was = 0; // 変化前のオフセット\n\ttjs_int64 offset_is = 0; // 変化後のオフセット\n\n\tfor(std::deque<tTVPWaveSegment>::iterator i = Segments.begin();\n\t\ti != Segments.end(); i++)\n\t{\n\t\ttjs_int64 old_end = offset_was + i->FilteredLength;\n\t\toffset_was += i->FilteredLength;\n\n\t\t// old_end は全体から見てどの位置にある？\n\t\tdouble ratio = static_cast<double>(old_end) /\n\t\t\t\t\t\tstatic_cast<double>(total_length_was);\n\n\t\t// 新しい old_end はどの位置にあるべき？\n\t\ttjs_int64 new_end = static_cast<tjs_int64>(ratio * new_total_filtered_length);\n\n\t\t// FilteredLength の修正\n\t\ti->FilteredLength = new_end - offset_is;\n\n\t\toffset_is += i->FilteredLength;\n\t}\n\n\t// からっぽのSegments の除去\n\tfor(std::deque<tTVPWaveSegment>::iterator i = Segments.begin();\n\t\ti != Segments.end() ; )\n\t{\n\t\tif(i->FilteredLength == 0 || i->Length == 0)\n\t\t\ti = Segments.erase(i);\n\t\telse\n\t\t\ti++;\n\t}\n\n\t// Labels の修正\n\tdouble ratio = (double)new_total_filtered_length / (double)total_length_was;\n\tfor(std::deque<tTVPWaveLabel>::iterator i = Labels.begin();\n\t\ti != Labels.end(); i++)\n\t{\n\t\ti->Offset = static_cast<tjs_int64>(i->Offset * ratio);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntjs_int64 tTVPWaveSegmentQueue::FilteredPositionToDecodePosition(tjs_int64 pos) const\n{\n\t// Segments の修正\n\ttjs_int64 offset_filtered = 0;\n\n\tfor(std::deque<tTVPWaveSegment>::const_iterator i = Segments.begin();\n\t\ti != Segments.end(); i++)\n\t{\n\t\tif(offset_filtered <= pos && pos < offset_filtered + i->FilteredLength)\n\t\t{\n\t\t\t// 対応する区間が見つかったので線形で補完して返す\n\t\t\treturn (tjs_int64)(i->Start + (pos - offset_filtered) *\n\t\t\t\t(double)i->Length / (double)i->FilteredLength );\n\t\t}\n\n\t\toffset_filtered += i->FilteredLength;\n\t}\n\n\t// 対応する区間が見つからないので、明らかに負であれば 0 を、\n\t// そうでなければ最後の位置を返す\n\tif(pos<0) return 0;\n\tif(Segments.size() == 0) return 0;\n\treturn Segments[Segments.size()-1].Start + Segments[Segments.size()-1].Length;\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/WaveSegmentQueue.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Waveセグメント/ラベルキュー管理\n//---------------------------------------------------------------------------\n#ifndef WAVESEGMENTH\n#define WAVESEGMENTH\n\n\n#include <deque>\n\n\n//---------------------------------------------------------------------------\n//! @brief 再生セグメント情報\n//---------------------------------------------------------------------------\nstruct tTVPWaveSegment\n{\n\t//! @brief コンストラクタ\n\ttTVPWaveSegment(tjs_int64 start, tjs_int64 length)\n\t\t{ Start = start; Length = FilteredLength = length; }\n\ttTVPWaveSegment(tjs_int64 start, tjs_int64 length, tjs_int64 filteredlength)\n\t\t{ Start = start; Length = length; FilteredLength = filteredlength; }\n\ttjs_int64 Start; //!< オリジナルデコーダ上でのセグメントのスタート位置 (PCM サンプルグラニュール数単位)\n\ttjs_int64 Length; //!< オリジナルデコーダ上でのセグメントの長さ (PCM サンプルグラニュール数単位)\n\ttjs_int64 FilteredLength; //!< フィルタ後の長さ (PCM サンプルグラニュール数単位)\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n//! @brief 再生ラベル情報\n//---------------------------------------------------------------------------\nstruct tTVPWaveLabel\n{\n\t//! @brief コンストラクタ\n\ttjs_int64 Position; //!< オリジナルデコーダ上でのラベル位置 (PCM サンプルグラニュール数単位)\n\tttstr Name; //!< ラベル名\n\ttjs_int Offset;\n\t\t/*!< オフセット\n\t\t\t@note\n\t\t\tThis member will be set in tTVPWaveLoopManager::Render,\n\t\t\tand will contain the sample granule offset from first decoding\n\t\t\tpoint at call of tTVPWaveLoopManager::Render().\n\t\t*/\n\n#ifdef TVP_IN_LOOP_TUNER\n\t// these are only used by the loop tuner\n\ttjs_int NameWidth; // display name width\n\ttjs_int Index; // index\n#endif\n\n\tstruct tSortByPositionFuncObj\n\t{\n\t\tbool operator()(\n\t\t\tconst tTVPWaveLabel &lhs,\n\t\t\tconst tTVPWaveLabel &rhs) const\n\t\t{\n\t\t\treturn lhs.Position < rhs.Position;\n\t\t}\n\t};\n\n\tstruct tSortByOffsetFuncObj\n\t{\n\t\tbool operator()(\n\t\t\tconst tTVPWaveLabel &lhs,\n\t\t\tconst tTVPWaveLabel &rhs) const\n\t\t{\n\t\t\treturn lhs.Offset < rhs.Offset;\n\t\t}\n\t};\n\n#ifdef TVP_IN_LOOP_TUNER\n\tstruct tSortByIndexFuncObj\n\t{\n\t\tbool operator()(\n\t\t\tconst tTVPWaveLabel &lhs,\n\t\t\tconst tTVPWaveLabel &rhs) const\n\t\t{\n\t\t\treturn lhs.Index < rhs.Index;\n\t\t}\n\t};\n#endif\n\n\t//! @brief コンストラクタ\n\ttTVPWaveLabel()\n\t{\n\t\tPosition = 0;\n\t\tOffset = 0;\n#ifdef TVP_IN_LOOP_TUNER\n\t\tNameWidth = 0;\n\t\tIndex = 0;\n#endif\n\t}\n\n\t//! @brief コンストラクタ\n\ttTVPWaveLabel(tjs_int64 position, const ttstr & name, tjs_int offset)\n\t\t: Position(position), Name(name), Offset(offset)\n\t{\n#ifdef TVP_IN_LOOP_TUNER\n\t\tNameWidth = 0;\n\t\tIndex = 0;\n#endif\n\t}\n};\n//---------------------------------------------------------------------------\nbool inline operator < (const tTVPWaveLabel & lhs, const tTVPWaveLabel & rhs)\n{\n\treturn lhs.Position < rhs.Position;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n//! @brief Waveのセグメント・ラベルのキューを管理するクラス\n//---------------------------------------------------------------------------\nclass tTVPWaveSegmentQueue\n{\n\t// deque による Segments と Labels の配列。\n\t// 実用上は、これらの配列に大量のデータが入ることはまずないので\n\t// vector で十分なのかもしれないが ...\n\tstd::deque<tTVPWaveSegment> Segments; //!< セグメントの配列\n\tstd::deque<tTVPWaveLabel> Labels; //!< ラベルの配列\n\npublic:\n\t//! @brief\t\t内容をクリアする\n\tvoid Clear();\n\n\t//! @brief\t\tセグメントの配列を得る\n\t//! @return\t\tセグメントの配列\n\tconst std::deque<tTVPWaveSegment> & GetSegments() const { return Segments; }\n\n\t//! @brief\t\tラベルの配列を得る\n\t//! @return\t\tラベルの配列\n\tconst std::deque<tTVPWaveLabel> & GetLabels() const { return Labels; }\n\n\t//! @brief\t\ttTVPWaveSegmentQueueをエンキューする\n\t//! @param\t\tqueue\t\tエンキューしたいtTVPWaveSegmentQueueオブジェクト\n\tvoid Enqueue(const tTVPWaveSegmentQueue & queue);\n\n\t//! @brief\t\ttTVPWaveSegmentをエンキューする\n\t//! @param\t\tqueue\t\tエンキューしたいtTVPWaveSegmentオブジェクト\n\tvoid Enqueue(const tTVPWaveSegment & segment);\n\n\t//! @brief\t\ttTVPWaveLabelをエンキューする\n\t//! @param\t\tqueue\t\tエンキューしたいtTVPWaveLabelオブジェクト\n\t//! @note\t\tOffset は修正されないので注意\n\tvoid Enqueue(const tTVPWaveLabel & Label);\n\n\t//! @brief\t\ttTVPWaveSegmentの配列をエンキューする\n\t//! @param\t\tqueue\t\tエンキューしたい std::dequeue<tTVPWaveSegment>オブジェクト\n\tvoid Enqueue(const std::deque<tTVPWaveSegment> & segments);\n\n\t//! @brief\t\ttTVPWaveLabelの配列をエンキューする\n\t//! @param\t\tqueue\t\tエンキューしたい std::dequeue<tTVPWaveLabel>オブジェクト\n\tvoid Enqueue(const std::deque<tTVPWaveLabel> & Labels);\n\n\t//! @brief\t\t先頭から指定長さ分をデキューする\n\t//! @param\t\tdest\t\t格納先キュー(内容はクリアされる)\n\t//! @param\t\tlength\t\t切り出す長さ(サンプルグラニュール単位)\n\tvoid Dequeue(tTVPWaveSegmentQueue & dest, tjs_int64 length);\n\n\t//! @brief\t\tこのキューの全体の長さを得る\n\t//! @return\t\tこのキューの長さ (サンプルグラニュール単位)\n\ttjs_int64 GetFilteredLength() const;\n\n\t//! @brief\t\tこのキューの長さを変化させる\n\t//! @param\t\tnew_total_filtered_length 新しいキューの長さ (サンプルグラニュール単位)\n\t//! @note\t\tキュー中のSegments などの長さや Labelsの位置は線形補間される\n\tvoid Scale(tjs_int64 new_total_length);\n\n\t//! @brief\t\tフィルタされた位置からデコード位置へ変換を行う\n\t//! @param\t\tpos フィルタされた位置\n\t//! @note\t\tデコード位置\n\ttjs_int64 FilteredPositionToDecodePosition(tjs_int64 pos) const;\n};\n//---------------------------------------------------------------------------\n\n#endif\n\n"
  },
  {
    "path": "src/core/sound/win32/CDDAImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CD-DA access implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n//#include <registry.hpp> // VCL\n#include <math.h>\n#include \"MsgIntf.h\"\n#include \"CDDAImpl.h\"\n#include \"SysInitIntf.h\"\n\n#ifdef ENABLE_CDDA\n\n//---------------------------------------------------------------------------\n// CD-DA volume controling functions ( by mixer )\n//---------------------------------------------------------------------------\ntTVPCDDAVolumeControlType TVPCDDAVolumeControlType = cvctMixer;\n\t// method for controling CD-DA volume\nstatic bool TVPCDDAVolumeControlTypeInit = false;\nvoid TVPInitCDDAVolumeControlType()\n{\n\t// retrieve command line option \"-cdvol\"\n\tif(TVPCDDAVolumeControlTypeInit) return;\n\n\t// -cdvol=mixer  : use mixer (default)\n\t// -cdvol=direct : use direct volume control\n\n\ttTJSVariant val;\n\tif(TVPGetCommandLine(TJS_W(\"-cdvol\"), &val))\n\t{\n\t\tttstr str(val);\n\t\t\t if(str == TJS_W(\"mixer\")) TVPCDDAVolumeControlType = cvctMixer;\n\t\telse if(str == TJS_W(\"direct\")) TVPCDDAVolumeControlType = cvctDirect;\n\t\telse TVPThrowExceptionMessage(TVPCommandLineParamIgnoredAndDefaultUsed,\n\t\t\t\t\tTJS_W(\"-cdvol\"), str);\n\t}\n\n\tTVPCDDAVolumeControlTypeInit = true;\n}\n//---------------------------------------------------------------------------\n#define NUMVOLUMEFADERS_MAX 0x40\nstatic UINT TVPMixerIDs[NUMVOLUMEFADERS_MAX];\nstatic MIXERCONTROL TVPMixerControls[NUMVOLUMEFADERS_MAX];\nstatic MIXERCONTROLDETAILS TVPMixerControlDetails[NUMVOLUMEFADERS_MAX];\nstatic MIXERCONTROLDETAILS_UNSIGNED TVPOriginalVolumes[NUMVOLUMEFADERS_MAX];\nstatic tjs_int TVPNumMixerControls = 0;\nstatic bool TVPMixerInit = false;\n//---------------------------------------------------------------------------\nstatic void TVPGetMixerControls(void)\n{\n\t// list up all of volume feders connected to CD\n\tif(TVPMixerInit) return;\n\n\ttjs_int i;\n\ttjs_int nummixers = mixerGetNumDevs(); // count of mixers implemented in system\n\tfor(i=0; i<nummixers; i++) // for each mixer\n\t{\n\t\tHMIXER hmx;\n\t\tif(MMSYSERR_NOERROR != mixerOpen(&hmx, i, 0, 0, 0)) continue;\n\n\t\tMIXERCAPS mxcaps;\n\t\tif(MMSYSERR_NOERROR != mixerGetDevCaps((UINT)hmx, &mxcaps, sizeof(mxcaps)))\n\t\t{\n\t\t\tmixerClose(hmx);\n\t\t\tcontinue;\n\t\t}\n\n\t\ttjs_int j;\n\t\tfor(j=0; j<(tjs_int)mxcaps.cDestinations; j++) // for each destination\n\t\t{\n\t\t\tMIXERLINE mxl;\n\t\t\tmxl.cbStruct = sizeof(mxl);\n\t\t\tmxl.dwDestination = j;\n\n\t\t\tif(MMSYSERR_NOERROR !=\n\t\t\t\tmixerGetLineInfo((HMIXEROBJ)hmx, &mxl,\n\t\t\t\t\tMIXER_GETLINEINFOF_DESTINATION))\n\t\t\t\tcontinue;\n\n\t\t\ttjs_int numcon = mxl.cConnections;\n\t\t\ttjs_int k;\n\t\t\tfor(k=0; k<numcon; k++) // for each source\n\t\t\t{\n\t\t\t\tmxl.cbStruct = sizeof(mxl);\n\t\t\t\tmxl.dwDestination = j;\n\t\t\t\tmxl.dwSource = k;\n\n\t\t\t\tif(MMSYSERR_NOERROR != mixerGetLineInfo((HMIXEROBJ)hmx, &mxl,\n\t\t\t\t\tMIXER_GETLINEINFOF_SOURCE))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif(mxl.fdwLine & MIXERLINE_LINEF_SOURCE)\n\t\t\t\t{\n\t\t\t\t\t// the line is source\n\t\t\t\t\tuint32_t componenttype = mxl.dwComponentType;\n\n\t\t\t\t\tmxl.cbStruct = sizeof(mxl);\n\t\t\t\t\tmxl.dwLineID = mxl.dwLineID;\n\n\t\t\t\t\tif(MMSYSERR_NOERROR != mixerGetLineInfo((HMIXEROBJ)hmx,\n\t\t\t\t\t\t&mxl, MIXER_GETLINEINFOF_LINEID))\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif(mxl.cControls == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// no controls found\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tMIXERCONTROL *pmxc;\n\t\t\t\t\tpmxc = new MIXERCONTROL[mxl.cControls];\n\n\t\t\t\t\tMIXERLINECONTROLS mxlc;\n\t\t\t\t\tmxlc.cbStruct = sizeof(mxlc);\n\t\t\t\t\tmxlc.dwLineID = mxl.dwLineID;\n\t\t\t\t\tmxlc.cControls = mxl.cControls;\n\t\t\t\t\tmxlc.cbmxctrl = sizeof(MIXERCONTROL);\n\t\t\t\t\tmxlc.pamxctrl = pmxc;\n\n\t\t\t\t\tif(MMSYSERR_NOERROR !=\n\t\t\t\t\t\tmixerGetLineControls((HMIXEROBJ)hmx, &mxlc,\n\t\t\t\t\t\t\tMIXER_GETLINECONTROLSF_ALL))\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] pmxc;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\ttjs_int l;\n\t\t\t\t\tfor(l=0; l<(int)mxlc.cControls; l++) // for all controls\n\t\t\t\t\t{\n\t\t\t\t\t\tif(pmxc[l].dwControlType ==\n\t\t\t\t\t\t\tMIXERCONTROL_CONTROLTYPE_VOLUME &&\n\t\t\t\t\t\t\t(componenttype==\n\t\t\t\t\t\t\t\tMIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC ||\n\t\t\t(pmxc[l].szShortName[0] == 'C' && pmxc[l].szShortName[1] == 'D')) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// the control is a volume fader, and\n\t\t\t\t\t\t\t// 1. its component type is COMPACTDISC\n\t\t\t\t\t\t\t// 2. or its name starts with \"CD\"\n\n\t\t\t\t\t\t\tTVPMixerIDs[TVPNumMixerControls] = i;\n\n\t\t\t\t\t\t\tMIXERCONTROLDETAILS *pmxcd =\n\t\t\t\t\t\t\t\tTVPMixerControlDetails + TVPNumMixerControls;\n\n\t\t\t\t\t\t\tZeroMemory(pmxcd, sizeof(MIXERCONTROLDETAILS));\n\t\t\t\t\t\t\tpmxcd->cbStruct = sizeof(MIXERCONTROLDETAILS);\n\t\t\t\t\t\t\tpmxcd->dwControlID = pmxc[l].dwControlID;\n\t\t\t\t\t\t\tpmxcd->cChannels = 1;\n\t\t\t\t\t\t\tpmxcd->cMultipleItems = pmxc[l].cMultipleItems;\n\t\t\t\t\t\t\tpmxcd->cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);\n\t\t\t\t\t\t\tpmxcd->paDetails =\n\t\t\t\t\t\t\t\tTVPOriginalVolumes + TVPNumMixerControls;\n\n\t\t\t\t\t\t\tTVPMixerControls[TVPNumMixerControls] = pmxc[l];\n\n\t\t\t\t\t\t\tif(MMSYSERR_NOERROR ==\n\t\t\t\t\t\t\t\tmixerGetControlDetails((HMIXEROBJ)hmx, pmxcd,\n\t\t\t\t\t\t\t\t\t0L)) // get initial volume\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tTVPNumMixerControls ++;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tdelete [] pmxc;\n\t\t\t\t\tif(TVPNumMixerControls >= NUMVOLUMEFADERS_MAX) break;\n\t\t\t\t}\n\t\t\t\tif(TVPNumMixerControls >= NUMVOLUMEFADERS_MAX) break;\n\t\t\t}\n\t\t\tif(TVPNumMixerControls >= NUMVOLUMEFADERS_MAX) break;\n\t\t}\n\t\tmixerClose(hmx);\n\t\tif(TVPNumMixerControls >= NUMVOLUMEFADERS_MAX) break;\n\t}\n\n\tTVPMixerInit = true;\n}\n\n//---------------------------------------------------------------------------\nvoid TVPRestoreCDVolume(void)\n{\n\tif(!TVPMixerInit) return;\n\ttjs_int i;\n\tfor(i=0;i<TVPNumMixerControls;i++)\n\t{\n\t\tHMIXER hmx;\n\t\tif(MMSYSERR_NOERROR == mixerOpen(&hmx, TVPMixerIDs[i], 0, 0, 0))\n\t\t{\n\t\t\tmixerSetControlDetails((HMIXEROBJ)hmx, TVPMixerControlDetails + i, 0L);\n\t\t\tmixerClose(hmx);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPRestoreCDVolumeAtExit\n\t(TVP_ATEXIT_PRI_RELEASE, TVPRestoreCDVolume);\n//---------------------------------------------------------------------------\nstatic void TVPSetCDVolume(int v)\n{\n\tif(!TVPMixerInit) TVPGetMixerControls();\n\ttjs_int i;\n\tfor(i=0;i<TVPNumMixerControls;i++)\n\t{\n\t\tHMIXER hmx;\n\t\tif(MMSYSERR_NOERROR == mixerOpen(&hmx, TVPMixerIDs[i], 0, 0, 0))\n\t\t{\n\t\t\tMIXERCONTROLDETAILS mxcd = TVPMixerControlDetails[i];\n\t\t\tMIXERCONTROLDETAILS_UNSIGNED mxcd_u = TVPOriginalVolumes[i];\n\t\t\tmxcd.paDetails = &mxcd_u;\n\n\t\t\tfloat vd = mxcd_u.dwValue;\n\t\t\tvd *= (float)v / 100000.0;\n\t\t\tif(vd < 0) vd = 0;\n\t\t\tuint32_t vdd = vd;\n\t\t\tif(vdd >= mxcd_u.dwValue) vdd = mxcd_u.dwValue;\n\n\t\t\tmxcd_u.dwValue = vdd;\n\n\t\t\tmixerSetControlDetails((HMIXEROBJ)hmx, &mxcd, 0L);\n\n\t\t\tmixerClose(hmx);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// MCI error string retrieval function\n//---------------------------------------------------------------------------\nttstr TVPGetMCIErrorString(MCIERROR err)\n{\n\tchar msg[1024];\n\tmciGetErrorString(err, msg, sizeof(msg));\n\treturn ttstr(msg);\n}\nvoid TVPThrowMCIErrorString(MCIERROR err)\n{\n\tTVPThrowExceptionMessage(TVPMCIError, TVPGetMCIErrorString(err));\n}\n//---------------------------------------------------------------------------\n#endif //ENABLE_CDDA\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_CDDASoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_CDDASoundBuffer::tTJSNI_CDDASoundBuffer()\n{\n#ifdef ENABLE_CDDA\n    TVPInitCDDAVolumeControlType();\n\tVolume =  100000;\n\tVolume2 = 100000;\n\tDrive = -1;\n\tMaxTrackNum = 0;\n\tTimerBeatPhase = false;\n\tLooping = false;\n#endif\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_CDDASoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_CDDASoundBuffer::Invalidate()\n{\n\tinherited::Invalidate();\n\n#ifdef ENABLE_CDDA\n    StopPlay();\n\tClose();\n#endif\n}\n//---------------------------------------------------------------------------\n#ifdef ENABLE_CDDA\nvoid tTJSNI_CDDASoundBuffer::Open(const ttstr &storage)\n{\n\ttjs_int drv = 0;\n\tconst tjs_char *c = storage.c_str();\n\tchar drive[4] = { ' ', ':', 0, 0 };\n\n\tif(storage.GetLen() >= 2 && storage[1] == TJS_W(':'))\n\t{\n\t\t// drive is specified\n\n\t\t// search the drive connected to the system\n\t\tbool found = false;\n\t\tchar dr[4];\n\t\tdr[1] = ':'; dr[2] = '\\\\'; dr[3] = 0;\n\t\tfor(dr[0] = 'A'; dr[0] <= 'Z'; dr[0] ++)\n\t\t{\n\t\t\tif(GetDriveType(dr ) == DRIVE_CDROM)\n\t\t\t{\n\t\t\t\tif((dr[0]&0x1f) == (storage[0]&0x1f))\n\t\t\t\t{\n\t\t\t\t\tfound = true;\n\t\t\t\t\tdrive[0] = dr[0];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdrv ++;\n\t\t\t}\n\t\t}\n\n\t\tif(!found)\n\t\t{\n\t\t\tSetStatus(ssUnload);\n\t\t\tTVPThrowExceptionMessage(TVPInvalidCDDADrive);\n\t\t}\n\n\t\tc += 2;\n\t}\n\telse\n\t{\n\t\t// drive is not specified\n\n\t\t// read the system registry to determine default CD-DA drive\n\t\tTRegistry * reg = new TRegistry();\n\t\treg->RootKey = HKEY_LOCAL_MACHINE;\n\t\tuint32_t defdrive = 0;\n\t\tif(!reg ->OpenKey(\n\t\t\"System\\\\CurrentControlSet\\\\Control\\\\MediaResources\\\\mci\\\\cdaudio\",false))\n\t\t{\n\t\t\t// cannot open the key\n\t\t\tdelete reg;\n\t\t\treg = NULL;\n\t\t\tdefdrive = 0;\n\t\t}\n\n\t\tif(reg)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// read value of \"Default Drive\"\n\t\t\t\tif(sizeof(defdrive)!=\n\t\t\t\t\treg->ReadBinaryData(\"Default Drive\",(void*)(&defdrive),\n\t\t\t\t\t\tsizeof(defdrive)) )\n\t\t\t\t{\n\t\t\t\t\tdefdrive = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tdefdrive = 0;\n\t\t\t}\n\n\t\t\treg->CloseKey();\n\t\t\tdelete reg;\n\t\t}\n\n\t\tchar dr[4];\n\t\tdr[1] = ':';\n\t\tdr[2] = '\\\\';\n\t\tdr[3] = 0;\n\t\tchar firstdr = ' ';\n\t\tbool found = false;\n\t\ttjs_int i = 0;\n\t\tfor(dr[0]='A'; dr[0]<='Z'; dr[0]++)\n\t\t{\n\t\t\tif(GetDriveType(dr) == DRIVE_CDROM)\n\t\t\t{\n\t\t\t\tif(i == 0) firstdr=dr[0];\n\n\t\t\t\tif(i==(int)defdrive)\n\t\t\t\t{\n\t\t\t\t\tdrive[0] = dr[0];\n\t\t\t\t\tdrv = i;\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tif(!found)\n\t\t{\n\t\t\tif(firstdr == ' ') TVPThrowExceptionMessage(TVPCDDADriveNotFound);\n\n\t\t\t// use default drive\n\t\t\tdrive[0] = firstdr;\n\t\t\tdrv = 0;\n\t\t}\n\t}\n\n\ttjs_int track = (tjs_int)TJS_atoi(c);\n\n\tStopPlay();\n\tSetStatus(ssStop);\n\n\tif(Drive != drv)\n\t{\n\t\t// re-open MCI device\n\t\tClose();\n\n\t\tDrive = drv;\n\t\tstrcpy(DriveLetter, drive);\n\n\t\t// open with MCI\n\t\tBeforeOpenMedia();\n\n\t\tMCI_OPEN_PARMS openparams;\n\t\tZeroMemory(&openparams,  sizeof(openparams));\n\t\topenparams.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;\n\t\topenparams.lpstrElementName = drive;\n\n\t\tMCIERROR err;\n\t\terr = mciSendCommand(0, MCI_OPEN,\n\t\t\tMCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_TYPE | MCI_OPEN_ELEMENT |\n\t\t\tMCI_OPEN_SHAREABLE,\n\t\t\t(uint32_t) &openparams);\n\n\t\tif(err == 0)\n\t\t{\n\t\t\t// if no error\n\n\t\t\tDeviceID = openparams.wDeviceID;\n\n\t\t\t// set time format to TMSF\n\t\t\tMCI_SET_PARMS setparams;\n\t\t\tsetparams.dwCallback = NULL;\n\t\t\tsetparams.dwTimeFormat = MCI_FORMAT_TMSF;\n\t\t\tsetparams.dwAudio = 0;\n\n\t\t\terr = mciSendCommand(DeviceID, MCI_SET, MCI_WAIT | MCI_SET_TIME_FORMAT,\n\t\t\t\t(uint32_t)&setparams);\n\n\t\t\tif(err)\n\t\t\t{\n\t\t\t\tMCI_GENERIC_PARMS params;\n\t\t\t\tZeroMemory(&params, sizeof(params));\n\t\t\t\tmciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, (uint32_t)&params);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// get maximum number of tracks\n\t\t\t\tMCI_STATUS_PARMS statusparams;\n\t\t\t\tZeroMemory(&statusparams, sizeof(statusparams));\n\t\t\t\tstatusparams.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;\n\t\t\t\tMCIERROR err;\n\t\t\t\terr = mciSendCommand(DeviceID, MCI_STATUS,\n\t\t\t\t\t MCI_STATUS_ITEM | MCI_WAIT, (uint32_t)&statusparams);\n\n\t\t\t\tif(err)\n\t\t\t\t{\n\t\t\t\t\tMCI_GENERIC_PARMS params;\n\t\t\t\t\tZeroMemory(&params, sizeof(params));\n\t\t\t\t\tmciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, (uint32_t)&params);\n\t\t\t\t}\n\n\t\t\t\tMaxTrackNum = (tjs_int)statusparams.dwReturn;\n\t\t\t}\n\t\t}\n\n\t\tif(err)\n\t\t{\n\t\t\tSetStatus(ssUnload);\n\t\t\tAfterOpenMedia();\n\t\t\tTVPThrowMCIErrorString(err);\n\t\t}\n\n\t\tAfterOpenMedia();\n\t\tSetStatus(ssStop);\n\t}\n\n\tTrack = track;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::Close()\n{\n\tif(Status != ssUnload && Drive != -1)\n\t{\n\t\t// close MCI\n\t\tMCI_GENERIC_PARMS params;\n\t\tZeroMemory(&params, sizeof(params));\n\t\tmciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, (uint32_t)&params);\n\t\tSetStatus(ssUnload);\n\t}\n\tMaxTrackNum = 0;\n\tDrive = -1;\n}\n//---------------------------------------------------------------------------\nMCIERROR tTJSNI_CDDASoundBuffer::StartPlay()\n{\n\t// start playing with MCI\n\tMCIERROR err;\n\tMCI_PLAY_PARMS playparams;\n\tZeroMemory(&playparams, sizeof(playparams));\n\tplayparams.dwFrom = MCI_MAKE_TMSF(Track, 0, 0, 0);\n\tplayparams.dwTo = MCI_MAKE_TMSF(Track+1, 0, 0, 0);\n\n\tuint32_t flags = MCI_FROM;\n\tif((int)MaxTrackNum != Track) // if the track is not last track\n\t\tflags |= MCI_TO;\n\n\t_SetVolume(Volume);\n\terr = mciSendCommand(DeviceID, MCI_PLAY, flags , (uint32_t)&playparams);\n\treturn err;\n}\n//---------------------------------------------------------------------------\nMCIERROR tTJSNI_CDDASoundBuffer::StopPlay()\n{\n\t// stop playing\n\tif(Drive!=-1 && Status != ssUnload)\n\t{\n\n\t\tMCI_GENERIC_PARMS genparams;\n\t\tgenparams.dwCallback = 0;\n\t\tMCIERROR err;\n\t\terr = mciSendCommand(DeviceID, MCI_STOP, MCI_WAIT, (uint32_t)&genparams);\n\t\treturn err;\n\t}\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::Play()\n{\n\t// play\n\n\tif(Status != ssPlay && Drive!=-1 && Status != ssUnload)\n\t{\n\t\tMCIERROR err;\n\t\terr = StartPlay();\n\t\tif(err) TVPThrowMCIErrorString(err);\n\t\tSetStatus(ssPlay);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::Stop()\n{\n\tif(Status == ssPlay)\n\t{\n\t\tMCIERROR err;\n\t\terr = StopPlay();\n\t\tif(err) TVPThrowMCIErrorString(err);\n\t\tSetStatus(ssStop);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::TimerBeatHandler()\n{\n\tTimerBeatPhase = !TimerBeatPhase;\n\tif(!TimerBeatPhase)  // thin-out\n\t{\n\t\t// look MCI status to check the stopping\n\n\t\tif(Status == ssPlay)\n\t\t{\n\t\t\tMCI_STATUS_PARMS statusparams;\n\t\t\tZeroMemory(&statusparams, sizeof(MCI_STATUS_PARMS));\n\t\t\tstatusparams.dwItem = MCI_STATUS_MODE;\n\t\t\tif(!mciSendCommand(DeviceID, MCI_STATUS,\n\t\t\t\tMCI_WAIT | MCI_STATUS_ITEM, (uint32_t)&statusparams))\n\t\t\t{\n\t\t\t\tif(statusparams.dwReturn  == MCI_MODE_STOP)\n\t\t\t\t{\n\t\t\t\t\tif(Looping)\n\t\t\t\t\t\tStartPlay();\n\t\t\t\t\telse\n\t\t\t\t\t\tSetStatusAsync(ssStop);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tinherited::TimerBeatHandler();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_CDDASoundBuffer::ReadOrgVolumeData()\n{\n\t// read current CD-DA volume from the system registry\n\n\tif(TVPCDDAVolumeControlType != cvctDirect) return false;\n\n\tchar key[256];\n\tsprintf(key,\n\t\"System\\\\CurrentControlSet\\\\Control\\\\MediaResources\\\\mci\\\\cdaudio\\\\unit %d\",\n\t\tDrive);\n\n\tTRegistry *reg = new TRegistry();\n\treg->RootKey = HKEY_LOCAL_MACHINE;\n\tif(!reg->OpenKey(key, true))\n\t{\n\t\t// can not open the key\n\t\tdelete reg;\n\t\treturn false;\n\t}\n\n\t// read current volume data\n\tif(sizeof(OrgVolumeData) != reg->ReadBinaryData(\"Volume Settings\", (void*)\n\t\t&OrgVolumeData, sizeof(OrgVolumeData)) )\n\t{\n\t\treg->CloseKey();\n\t\tdelete reg;\n\t\t// generate orgvolumedata\n\t\tOrgVolumeData.dwUnitNo = Drive;\n\t\tOrgVolumeData.dwVolume = 0xff;\n\t\treturn false;\n\t}\n\n\treg->CloseKey();\n\tdelete reg;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::WriteVolumeRegistry(tjs_int vol)\n{\n\t// write new CD-DA volume information to the system registry\n\n\tif(TVPCDDAVolumeControlType != cvctDirect) return;\n\n\tchar key[256];\n\tsprintf(key,\n\t\"System\\\\CurrentControlSet\\\\Control\\\\MediaResources\\\\mci\\\\cdaudio\\\\unit %d\",\n\t\tDrive);\n\n\tTRegistry *reg=new TRegistry();\n\treg ->RootKey = HKEY_LOCAL_MACHINE;\n\tif(!reg ->OpenKey(key, true))\n\t{\n\t\t// cannot open the key\n\t\tdelete reg;\n\t\treturn; // fail\n\t}\n\n\tCD_AUDIO_VOLUME_DATA cavd=OrgVolumeData;\n\tif(vol!=-1) cavd.dwVolume=vol;\n\n\ttry\n\t{\n\t\treg->WriteBinaryData(\"Volume Settings\",(void*)(&cavd),\n\t\t\t\tsizeof(cavd));\n\t}\n\tcatch(...)\n\t{\n\t\treg->CloseKey();\n\t\tdelete reg;\n\t\treturn;\n\t}\n\n\treg->CloseKey();\n\tdelete reg;\n\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_CDDASoundBuffer::BeforeOpenMedia()\n{\n\t// called before opening MCI device\n\n\ttjs_int v = (Volume / 10) * (Volume2 / 10) / 1000;\n\n\tif(TVPCDDAVolumeControlType == cvctMixer || !ReadOrgVolumeData())\n\t{\n\t\t// mixer or cannot open the key;\n\t\t// use mixer\n\t\tTVPSetCDVolume(v);\n\t\treturn false;\n\t}\n\n\t// compute new volume\n\tfloat vl = (float) v / 100000;\n\tvl = vl*vl;\n\tvl *= OrgVolumeData.dwVolume;\n\tv = vl;\n\tif(v<0) v = 0;\n\tif(v>255) v = 255;\n\n\t// write new volume registry\n\tWriteVolumeRegistry(v);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::AfterOpenMedia()\n{\n\t// called after opening MCI device\n\n\t// write original volume information to the system registry\n\tWriteVolumeRegistry(-1);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::_SetVolume(tjs_int v)\n{\n\tVolume = v;\n\n\tif(Drive == -1) return;\n\n\tif(!BeforeOpenMedia()) return; // no need to direct access\n\n\t// open MCI device to update CD-ROM's volume register and immediately\n\t// close it .\n\n\tchar elmname[30];\n\tstrcpy(elmname, DriveLetter);\n\tchar alias[30];\n\tsprintf(alias, \"__%lu\", GetTickCount()); // unique alias\n\n\tMCI_OPEN_PARMS params;\n\tZeroMemory(&params,  sizeof(params));\n\tparams.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;\n\tparams.lpstrElementName = elmname;\n\tparams.lpstrAlias = alias;\n\n\tMCIERROR err = mciSendCommand(0, MCI_OPEN,\n\t\tMCI_WAIT | MCI_OPEN_SHAREABLE | MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS |\n\t\tMCI_OPEN_TYPE_ID | MCI_OPEN_TYPE,\n\t\t(uint32_t) &params);\n\n\tif(err == 0)\n\t{\n\t\tMCI_GENERIC_PARMS genparams;\n\t\tZeroMemory(&genparams, sizeof(genparams));\n\t\tgenparams.dwCallback = 0;\n\n\t\tmciSendCommand(params.wDeviceID, MCI_CLOSE, MCI_WAIT, (uint32_t)&genparams);\n\t}\n\n\tAfterOpenMedia();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::SetVolume(tjs_int v)\n{\n\t// set new volume\n\tif(v<0) v = 0;\n\tif(v>100000) v= 100000;\n\n\tif(Volume != v)\n\t{\n\t\t_SetVolume(v);\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_CDDASoundBuffer::SetVolume2(tjs_int v)\n{\n\t// set new alternative volume\n\tif(v<0) v = 0;\n\tif(v>100000) v= 100000;\n\n\tif(Volume2 != v)\n\t{\n\t\tVolume2 = v;\n\t\t_SetVolume(Volume);\n\t}\n\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_CDDASoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_CDDASoundBuffer::CreateNativeInstance()\n{\n\treturn new tTJSNI_CDDASoundBuffer();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_CDDASoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_CDDASoundBuffer()\n{\n\treturn new tTJSNC_CDDASoundBuffer();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/sound/win32/CDDAImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// CD-DA access implementation\n//---------------------------------------------------------------------------\n#ifndef CDDAImplH\n#define CDDAImplH\n\n\n#include \"CDDAIntf.h\"\n\n//---------------------------------------------------------------------------\n// tTVPCDDAVolumeControlType\n//---------------------------------------------------------------------------\nenum tTVPCDDAVolumeControlType\n{\n\tcvctMixer,  // use sound card's mixer\n\tcvctDirect  // direct control for CD-ROM drive\n};\nextern tTVPCDDAVolumeControlType TVPCDDAVolumeControlType;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// CD_AUDIO_VOLUME_DATA\n//---------------------------------------------------------------------------\n#pragma pack(push,1)\nstruct CD_AUDIO_VOLUME_DATA\n{\n\tunsigned long dwUnitNo;\n\tunsigned long dwVolume;\n};\n#pragma pack(pop)\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_CDDASoundBuffer : CDDA Native Instance\n//---------------------------------------------------------------------------\nclass tTJSNI_CDDASoundBuffer : public tTJSNI_BaseCDDASoundBuffer\n{\n\ttypedef  tTJSNI_BaseCDDASoundBuffer inherited;\n\npublic:\n\ttTJSNI_CDDASoundBuffer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n#ifdef ENABLE_CDDA\n    //-- playing stuff ----------------------------------------------------\nprivate:\n\ttjs_int Drive;\n\ttjs_int MaxTrackNum;\n\tchar DriveLetter[4];\n\ttjs_int Track;\n    MCIDEVICEID DeviceID;\n\tbool TimerBeatPhase;\n\tbool Looping;\n\npublic:\n\tvoid Open(const ttstr &storage);\n\tvoid Close();\n    MCIERROR StartPlay();\n\tMCIERROR StopPlay();\n    void Play();\n\tvoid Stop();\n\n\tbool GetLooping() const { return Looping; };\n\tvoid SetLooping(bool b) { Looping = b; };\n\nprotected:\n\tvoid TimerBeatHandler(); // override\n\n\n\t//-- volume stuff -----------------------------------------------------\nprivate:\n\ttjs_int Volume;\n\ttjs_int Volume2;\n\tCD_AUDIO_VOLUME_DATA OrgVolumeData;\n\tbool ReadOrgVolumeData();\n\tvoid WriteVolumeRegistry(tjs_int vol);\n\tbool BeforeOpenMedia();\n\tvoid AfterOpenMedia();\n\n\tvoid _SetVolume(tjs_int v);\npublic:\n\tvoid SetVolume(tjs_int v);\n\ttjs_int GetVolume() const { return Volume; }\n\tvoid SetVolume2(tjs_int v);\n\ttjs_int GetVolume2() const { return Volume2; }\n\nprotected:\n#else\n    void SetVolume(tjs_int v){}\n    tjs_int GetVolume() const { return 0; }\n#endif\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/MIDIImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// MIDI sequencer implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"MIDIImpl.h\"\n\n#include <algorithm>\n#include \"TickCount.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"ThreadIntf.h\"\n#include \"UtilStreams.h\"\n\n\n#ifdef TVP_ENABLE_MIDI\n//---------------------------------------------------------------------------\n// MIDI output routines\n//---------------------------------------------------------------------------\nstatic HMIDIOUT TVPMIDIOutHandle = NULL;\nstatic tTJSStaticCriticalSection TVPMIDIOutCS;\nstatic std::vector<tTJSNI_MIDISoundBuffer*> TVPMIDIBuffers;\nstatic bool TVPMIDIDelayAlive = false;\nstatic uint32_t TVPMIDIDelayTick = 0;\n//---------------------------------------------------------------------------\nstatic void TVPInitMIDIOut(void)\n{\n    if(!TVPMIDIOutHandle)\n\t\tmidiOutOpen(&TVPMIDIOutHandle, (UINT)MIDI_MAPPER, NULL, 0, CALLBACK_NULL);\n}\n//---------------------------------------------------------------------------\nstatic void TVPUninitMIDIOut(void)\n{\n    if(TVPMIDIOutHandle) midiOutClose(TVPMIDIOutHandle), TVPMIDIOutHandle=NULL;\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit\n\tTVPUninitMIDIOutAtExit(TVP_ATEXIT_PRI_RELEASE, TVPUninitMIDIOut);\n//---------------------------------------------------------------------------\nstatic void TVPCheckMIDIDelay()\n{\n\tif(!TVPMIDIDelayAlive) return;\n\n\tint delay = TVPMIDIDelayTick - TVPGetTickTime();\n\tif(delay > 0) Sleep(delay);\n\n\tTVPMIDIDelayAlive = false;\n}\n//---------------------------------------------------------------------------\nstatic void TVPMIDIOut(tjs_uint8 *data,int len)\n{\n    if(!TVPMIDIOutHandle) return;\n\tTVPCheckMIDIDelay();\n\tMIDIHDR hdr;\n\thdr.lpData = (char*)data;\n\thdr.dwFlags = 0;\n\thdr.dwBufferLength = len;\n\tmidiOutPrepareHeader(TVPMIDIOutHandle, &hdr, sizeof(MIDIHDR));\n\tmidiOutLongMsg(TVPMIDIOutHandle, &hdr, sizeof(MIDIHDR));\n\tmidiOutUnprepareHeader(TVPMIDIOutHandle, &hdr, sizeof(MIDIHDR));\n}\n//---------------------------------------------------------------------------\nstatic void inline TVPMIDIOut(tjs_uint8 d1, tjs_uint8 d2, tjs_uint8 d3)\n{\n    if(!TVPMIDIOutHandle) return;\n\n\tTVPCheckMIDIDelay();\n\tmidiOutShortMsg(TVPMIDIOutHandle, d1 + (d2<<8) + (d3<<16));\n}\n//---------------------------------------------------------------------------\nstatic void TVPSetMIDIDelay(int ms)\n{\n\tTVPMIDIDelayAlive = true;\n\tTVPMIDIDelayTick = TVPGetTickTime() + ms;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid TVPMIDIOutData(const tjs_uint8 *data, int len)\n{\n#ifdef TVP_ENABLE_MIDI\n    // output MIDI messages ( can be multiple messages more than one )\n\tTVPInitMIDIOut();\n\tif(!TVPMIDIOutHandle) return;\n\tif(len == 0 || !data) return;\n\n\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\ttjs_uint8 prevevent = 0;\n\n\tfor(int i = 0; i < len; )\n\t{\n\t\ttjs_uint8 ev;\n\t\tif(!(data[i] & 0x80))\n\t\t{\n\t\t\t// running status\n\t\t\tif(!prevevent)\n\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\tev = prevevent;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tev = data[i++];\n\t\t}\n\n\t\tif(ev < 0xf0)\n\t\t{\n\t\t\ttjs_uint8 b1, b2=0;\n\t\t\tswitch(ev >> 4)\n\t\t\t{\n\t\t\tcase 0x9:\n\t\t\tcase 0x8:\n\t\t\tcase 0xa:\n\t\t\tcase 0xe:\n\t\t\tcase 0xb:\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb1 = data[i++];\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb2 = data[i++];\n\t\t\t\tbreak;\n\n\t\t\tcase 0xc:\n\t\t\tcase 0xd:\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb1 = data[i++];\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tTVPMIDIOut(ev, b1, b2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttjs_uint8 b1, b2;\n\t\t\tint cmd = ev&0xf;\n\t\t\tswitch(cmd)\n\t\t\t{\n\t\t\tcase 0x1: // f1\n\t\t\tcase 0x3: // f3\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb1 = data[i++];\n\t\t\t\tTVPMIDIOut(ev, b1, 0);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x2: // f2\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb1 = data[i++];\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb2 = data[i++];\n\t\t\t\tTVPMIDIOut(ev, b1, b2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0xf: // ff\n\t\t\t\tif(i >= len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage);\n\t\t\t\tb1 = data[i++];\n\t\t\t\tif(b1 == 0x00)\n\t\t\t\t{\n\t\t\t\t\t// 50ms wait\n\t\t\t\t\tTVPSetMIDIDelay(50);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 0x7: // f7\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0: // f0\n\t\t\t  {\n\t\t\t\t// sysex\n\t\t\t\tint count;\n\t\t\t\tcount = 1;\n\t\t\t\tint j;\n\t\t\t\tfor(j = i; j < len; j++)\n\t\t\t\t{\n\t\t\t\t\tcount++;\n\t\t\t\t\tif(data[j] == 0xf7) break;\n\t\t\t\t}\n\t\t\t\tif(j == len)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPMalformedMIDIMessage); // EOX not found\n\t\t\t\ttjs_uint8 * sex = new tjs_uint8[count];\n\t\t\t\tmemcpy(sex, data + i - 1, count);\n\t\t\t\tTVPMIDIOut(sex, count);\n\t\t\t\tdelete [] sex;\n\t\t\t\ti += count -1;\n\t\t\t\tbreak;\n\t\t\t  }\n\n\t\t\tdefault:\n\t\t\t\tTVPMIDIOut(ev, 0, 0);\n\t\t\t\tbreak;\n\n\t\t\t}\n\t\t}\n\n\t\tprevevent = ev;\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n#ifdef TVP_ENABLE_MIDI\n//---------------------------------------------------------------------------\n// MIDI sequencer thread and buffer management\n//---------------------------------------------------------------------------\nclass tTVPMIDIThread : public tTVPThread\n{\npublic:\n\ttTVPMIDIThread() : tTVPThread(true)\n\t{\n\t\tSetPriority(ttpTimeCritical);\n\t};\n\n\t~tTVPMIDIThread()\n\t{\n\t\tTerminate();\n\t\tResume();\n\t\tWaitFor();\n\t}\n\n\tvoid Execute(void) // \"Execute\" override\n\t{\n\t\twhile(!GetTerminated())\n\t\t{\n\t\t\t// fire OnTimer to process MIDI events.\n\n\t\t\ttjs_int sleepcount = 0;\n\t\t\ttjs_int buffercount;\n\n\t\t\t{ // critical section protected area\n\t\t\t\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\t\t\t\tbuffercount = TVPMIDIBuffers.size();\n\n\t\t\t\tstd::vector<tTJSNI_MIDISoundBuffer*>::iterator i;\n\n\t\t\t\tfor(i = TVPMIDIBuffers.begin(); i != TVPMIDIBuffers.end(); i++)\n\t\t\t\t{\n\t\t\t\t\tif(!(*i)->OnTimer()) sleepcount++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(sleepcount == buffercount) Suspend(); // all buffers are sleeping\n\n\t\t\tSleep(5); // but 10ms is sufficient to play MIDIs I think ...\n\t\t}\n\n\t}\n\n} static *TVPMIDIThread = NULL;\n//---------------------------------------------------------------------------\nstatic void TVPDeleteMIDIThread()\n{\n\tif(TVPMIDIThread) delete TVPMIDIThread, TVPMIDIThread = NULL;\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPDeleteMIDIThreadAtExit(TVP_ATEXIT_PRI_SHUTDOWN,\n\tTVPDeleteMIDIThread);\n//---------------------------------------------------------------------------\nstatic void TVPAddMIDIBuffer(tTJSNI_MIDISoundBuffer *buf)\n{\n\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\tTVPMIDIBuffers.push_back(buf);\n\n\tif(TVPMIDIBuffers.size() == 1)\n\t{\n\t\t// first buffer\n\t\t//TVPStartTickCount(); // in TickCount.cpp\n\t\tTVPInitMIDIOut();\n\t\tif(!TVPMIDIThread) TVPMIDIThread = new tTVPMIDIThread();\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPRemoveMIDIBuffer(tTJSNI_MIDISoundBuffer *buf)\n{\n\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\tstd::vector<tTJSNI_MIDISoundBuffer *>::iterator i;\n\ti = std::find(TVPMIDIBuffers.begin(), TVPMIDIBuffers.end(), buf);\n\tif(i != TVPMIDIBuffers.end()) TVPMIDIBuffers.erase(i);\n\n\tif(TVPMIDIBuffers.size() == 0)\n\t{\n\t\t// all buffers are removed\n\t\tTVPDeleteMIDIThread();\n\t\tTVPUninitMIDIOut();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// SMF access utility functions\n//---------------------------------------------------------------------------\nstatic tjs_uint16 TVPGetSMFInt16(const tjs_uint8 *&p)\n{\n\ttjs_uint16 r;\n\t*(((tjs_uint8*)&r)+1)= p[0];\n\t*(((tjs_uint8*)&r)+0)= p[1];\n\tp += 2;\n\treturn r;\n}\n//---------------------------------------------------------------------------\nstatic tjs_uint32 TVPGetSMFInt32(const tjs_uint8 *&p)\n{\n\ttjs_uint32 r;\n\t*(((tjs_uint8*)&r)+3)= p[0];\n\t*(((tjs_uint8*)&r)+2)= p[1];\n\t*(((tjs_uint8*)&r)+1)= p[2];\n\t*(((tjs_uint8*)&r)+0)= p[3];\n\tp += 4;\n\treturn r;\n}\n//---------------------------------------------------------------------------\nstatic tjs_int64 TVPGetSMFValue(const tjs_uint8 *&p)\n{\n\ttjs_int64 r;\n\ttjs_uint8 d;\n\tr=0;\n\n\tdo\n\t{\n\t\td = *p;\n\t\tp++;\n\t\tr = (r<<7) + (d&0x7f);\n\n\t} while(d & 0x80);\n\n\treturn r;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPSMFTrack : SMF Track Class\n//---------------------------------------------------------------------------\nclass tTVPSMFTrack\n{\n\ttjs_uint8 *Data; // track data\n\tconst tjs_uint8 *Position; // current position\n\ttjs_int TrackSize; // track data size\n\ttjs_int64 Count; // current counter time\n\ttjs_uint8 PrevEvent; // previous event\n\tbool Ended; // is ended?\n\n\ttTJSNI_MIDISoundBuffer *Owner;\n\npublic:\n\ttTVPSMFTrack(tTJSNI_MIDISoundBuffer *owner, tTJSBinaryStream *instream, tjs_int n);\n\n\t~tTVPSMFTrack();\n\n\tvoid Rewind(void);\n\tvoid ProcessEvent();\n\n\tbool GetEnded() const { return Ended; }\n\tconst tjs_int64 & GetCount() const { return Count; }\n};\n//---------------------------------------------------------------------------\ntTVPSMFTrack::tTVPSMFTrack(tTJSNI_MIDISoundBuffer *owner, tTJSBinaryStream *instream,\n\ttjs_int n)\n{\n\tTrackSize = n;\n\tData = new tjs_uint8[n];\n\ttry\n\t{\n\t\tinstream->ReadBuffer(Data, n);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] Data;\n\t\tthrow;\n\t}\n\tOwner = owner;\n\n\tRewind();\n}\n//---------------------------------------------------------------------------\ntTVPSMFTrack::~tTVPSMFTrack()\n{\n\tdelete [] Data;\n}\n//---------------------------------------------------------------------------\nvoid tTVPSMFTrack::Rewind(void)\n{\n\tPosition = Data;\n\tEnded = false;\n\tPrevEvent = 0;\n\tCount= TVPGetSMFValue(Position);\n}\n//---------------------------------------------------------------------------\nvoid tTVPSMFTrack::ProcessEvent()\n{\n\t// process one track event\n\n\t// some reset message data\n\tstatic tjs_uint8 sysex_gsreset[]=\n\t\t{0xf0,0x41,0x10,0x42, 0x12,0x40,0x00,0x7f, 0x00,0x41,0xf7};\n\tstatic tjs_uint8 sysex_modeset[]=\n\t\t{0xf0,0x41,0x10,0x42, 0x12,0x00,0x00,0x7f}; // followed by initialize data\n\tstatic tjs_uint8 sysex_gmon[]=\n\t\t{0xf0,0x7e,0x7f,0x09, 0x01,0xf7};\n\tstatic tjs_uint8 sysex_xgon[]=\n\t\t{0xf0,0x43,0x10,0x4c, 0x00,0x00,0x7e,0x00, 0xf7};\n\n\n\t// check playing status\n\tif(Ended) return;\n\n\ttjs_uint8 ev;\n\tev = *Position;\n\tif(ev & 0x80)\n\t{\n\t\t// not a running status\n\t\tPosition++;\n\t}\n\telse\n\t{\n\t\t// a running status\n\t\tev = PrevEvent;\n\t}\n\n\tif(ev < 0xf0)\n\t{\n\t\ttjs_uint8 b1, b2=0;\n\t\tbool svflag = false;\n\t\tbool send = true;\n\t\tswitch(ev >> 4)\n\t\t{\n\t\tcase 0x9:\n\t\t\tif(!Owner->UsingChannel[ev&0x0f])\n\t\t\t{\n\t\t\t\t// first chance to set volume\n\t\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+(ev&0x0f)), 0x07,\n\t\t\t\t\t(tjs_uint8)(Owner->Volumes[ev&0x0f] * Owner->BufferVolume/127));\n\t\t\t}\n\t\t\tOwner->UsingChannel[ev&0x0f] = true; // note on\n\t\t\tif(*Position < 128)\n\t\t\t{\n\t\t\t\t// check \"on\" notes\n\t\t\t\tif(Position[1]!=0)\n\t\t\t\t\tOwner->UsingNote[ev&0x0f][*Position/32] |=\n\t\t\t\t\t\t(tjs_uint32)1<<(*Position%32);\n\t\t\t\telse\n\t\t\t\t\tOwner->UsingNote[ev&0x0f][*Position/32] &=\n\t\t\t\t\t\t~((tjs_uint32)1<<(*Position%32));\n\t\t\t}\n\t\t\tb1 = *(Position++);\n\t\t\tb2 = *(Position++);\n\t\t\tbreak;\n\n\t\tcase 0x8:\n\t\t\tif(*Position < 128)\n\t\t\t\tOwner->UsingNote[ev&0x0f][*Position/32] &=\n\t\t\t\t\t~((tjs_uint32)1<<(*Position%32));\n\t\t\t// no \"break\" here\n\t\tcase 0xa:\n\t\tcase 0xe:\n\t\t\tb1 = *(Position++);\n\t\t\tb2 = *(Position++);\n\t\t\tbreak;\n\n\t\tcase 0xc:\n\t\tcase 0xd:\n\t\t\tb1 = *(Position++);\n\t\t\tbreak;\n\n\t\tcase 0xb:  // control change\n\t\t\tb1 = *(Position++);\n\t\t\tb2 = *(Position++);\n\t\t\tif(b1 == 0x07) // channel volume\n\t\t\t{\n\t\t\t\tOwner->UsingChannel[ev&0x0f] = true;\n\t\t\t\tOwner->Volumes[ev&0x0f] = b2;\n\t\t\t\tb2=(tjs_uint8)(b2 * Owner->BufferVolume/127);\n\t\t\t\t\t// new volume\n\t\t\t}\n\t\t\telse if(b1 == 0x79) // reset all controllers\n\t\t\t{\n\t\t\t\tOwner->UsingChannel[ev&0x0f] = true;\n\t\t\t\tOwner->Volumes[ev&0x0f] = 100;\n\t\t\t\tsvflag = true;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tsend = false;\n\t\t}\n\n\t\tif(send) TVPMIDIOut(ev,b1,b2);\n\n\t\tif(svflag)\n\t\t{\n\t\t\t// re-send volume\n\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+(ev&0x0f)), 0x07,\n\t\t\t\t(tjs_uint8)(Owner->Volumes[ev&0x0f] * Owner->BufferVolume/127));\n\t\t}\n\t}\n\telse\n\t{\n\t\tint cmd = ev&0xf;\n\t\tif(cmd == 0x00)\n\t\t{\n\t\t\ttjs_uint32 dlen = TVPGetSMFValue(Position);\n\t\t\ttjs_uint8 *data = new tjs_uint8[dlen+1];\n\t\t\tdata[0] = 0xf0;\n\t\t\tmemcpy(data+1, Position, dlen);\n\t\t\tPosition += dlen;\n\n\t\t\tTVPMIDIOut(data, dlen+1);\n\n\t\t\tif((dlen>=10 && !memcmp(data, sysex_gsreset, 11)) ||\n\t\t\t   (dlen>=7  && !memcmp(data, sysex_modeset, 8)) ||\n\t\t\t   (dlen>=5  && !memcmp(data, sysex_gmon, 6)) ||\n\t\t\t   (dlen>=8  && !memcmp(data, sysex_xgon, 9)) )\n\t\t\t{\n\t\t\t\t// these are MIDI module reset messages;\n\t\t\t\t// clear volume information\n\n\t\t\t\t// sleep while the MIDI module is resetting...\n\t\t\t\tTVPSetMIDIDelay(50);\n\n\t\t\t\t// re-send track volumes\n\t\t\t\ttjs_int i;\n\t\t\t\tfor(i=0; i<16; i++)\n\t\t\t\t{\n\t\t\t\t\tOwner->Volumes[i] = 100;\n\n\t\t\t\t\tOwner->UsingChannel[i] = true;\n\n\t\t\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i),\n\t\t\t\t\t\t0x07,\n\t\t\t\t\t\t(tjs_uint8)(Owner->Volumes[i]*\n\t\t\t\t\t\tOwner->BufferVolume/127));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdelete [] data;\n\t\t}\n\t\telse if(cmd == 0x07)\n\t\t{\n\t\t\ttjs_uint32 dlen = TVPGetSMFValue(Position);\n\t\t\ttjs_uint8 *data = new tjs_uint8[dlen];\n\t\t\tmemcpy(data, Position, dlen);\n\t\t\tPosition += dlen;\n\t\t\tTVPMIDIOut(data, dlen);\n\t\t\tdelete [] data;\n\t\t}\n\t\telse if(cmd == 0x0f)\n\t\t{\n\t\t\t// meta events\n\t\t\ttjs_uint8 meta=*(Position++);\n\t\t\ttjs_uint32 dlen=TVPGetSMFValue(Position);\n\n\t\t\tswitch(meta)\n\t\t\t{\n\t\t\tcase 0x2f: // track end\n\t\t\t\tEnded=true;\n\t\t\t\treturn;\n\n\t\t\tcase 0x51: // tempo\n\t\t\t  {\n\t\t\t\ttjs_uint32 tempo=0;\n\t\t\t\twhile(dlen--)\n\t\t\t\t{\n\t\t\t\t\ttempo=(tempo<<8)+ *(Position++);\n\t\t\t\t}\n\n\t\t\t\tOwner->SetTempo(tempo);\n\t\t\t\t\t// note: this does not perform accurate tempo\n\t\t\t\t\t// changing; just a simple implementation\n\t\t\t\t\t// but enough.\n\t\t\t\tbreak;\n\t\t\t  }\n\t\t\t\t  \n\t\t\tdefault:\n\t\t\t\tPosition += dlen; // others; discard\n\t\t\t}\n\t\t}\n\t\telse if(cmd == 0x01 || cmd == 0x03)\n\t\t{\n\t\t\tTVPMIDIOut(ev, *(Position++), 0);\n\t\t}\n\t\telse if(cmd == 2)\n\t\t{\n\t\t\ttjs_uint8 b1, b2;\n\t\t\tb1 = *(Position++);\n\t\t\tb2 = *(Position++);\n\t\t\tTVPMIDIOut(ev, b1, b2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPMIDIOut(ev, 0, 0);\n\t\t}\n\n\t}\n\n\tPrevEvent = ev;\n\n\tif(Position-Data >= TrackSize) { Ended = true; return; }\n\tCount += TVPGetSMFValue(Position);\n\tif(Position-Data >= TrackSize) { Ended = true; return; }\n\n\treturn;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_MIDISoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_MIDISoundBuffer::tTJSNI_MIDISoundBuffer()\n{\n#ifdef TVP_ENABLE_MIDI\n    Playing = false;\n\tLoaded = false;\n\tVolume =  100000;\n\tVolume2 = 100000;\n\tBufferVolume = 127;\n\tNextSetVolume = false;\n\tUtilWindow = NULL;\n\tfor(tjs_int i = 0; i<16; i++)\n\t{\n\t\tUsingChannel[i] = false;\n\t\tUsingNote[i][0] = UsingNote[i][1] = UsingNote[i][2] = UsingNote[i][3] =0;\n\t\tVolumes[i] = 100;\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_MIDISoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n#ifdef TVP_ENABLE_MIDI\n\n#ifdef __BORLANDC__\n\tUtilWindow = AllocateHWnd(WndProc);\n#else\n\tUtilWindow = AllocateHWnd( EVENT_FUNC1(tTJSNI_MIDISoundBuffer, WndProc) );\n#endif\n\n\tTVPAddMIDIBuffer(this);\n#endif\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_MIDISoundBuffer::Invalidate()\n{\n\tinherited::Invalidate();\n#ifdef TVP_ENABLE_MIDI\n\n\tStopPlay();\n\n\tTVPRemoveMIDIBuffer(this);\n\n\tstd::vector<tTVPSMFTrack*>::iterator i;\n\tfor(i = Tracks.begin(); i != Tracks.end(); i++)\n\t{\n\t\tdelete *i;\n\t}\n\n\tif(UtilWindow) DeallocateHWnd(UtilWindow);\n#endif\n}\n#ifdef TVP_ENABLE_MIDI\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::WndProc(Messages::TMessage &Msg)\n{\n\t// called by OS, caused by posting of status message from playing thread.\n\tif(Msg.Msg == WM_USER+1)\n\t{\n\t\tSetStatusAsync((tTVPSoundStatus)Msg.LParam);\n\t\treturn;\n\t}\n\tMsg.Result =  DefWindowProc(UtilWindow, Msg.Msg, Msg.WParam, Msg.LParam);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::AllNoteOff()\n{\n\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\ttjs_int i;\n\n\tfor(i = 0; i<16; i++)\n\t{\n\t\tif(UsingChannel[i])\n\t\t{\n\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i),0x7B,0x00); // All Note Off\n\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i),0x40,0x00); // Sus. Off\n\t\t}\n\t}\n\n\tfor(i = 0; i<16; i++)\n\t{\n\t\tif(UsingChannel[i])\n\t\t{\n\t\t\tint j;\n\t\t\tfor(j=0; j<128; j++)\n\t\t\t{\n\t\t\t\tif(UsingNote[i][j/32] & (1<<(j%32)))\n\t\t\t\t{\n\t\t\t\t\tTVPMIDIOut((tjs_uint8)(0x90+i), (tjs_uint8)j, (tjs_uint8)0x00);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::SetTempo(tjs_uint tempo)\n{\n\t// set tempo count\n\tif(tempo == 0) tempo = 500000;\n\n\tTickCountDelta = ((__int64)(Division * 1000)<<16)/tempo;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MIDISoundBuffer::OnTimer()\n{\n\tif(!Playing) return false;\n\n\ttjs_int p;\n\t__int64 curcount = TickCount >> 16;\n\n\twhile(true)\n\t{\n\t\tp = 0;\n\n\t\t// find a track which has least tick count\n\t\t__int64 least_tick = -1;\n\t\tbool do_tick = false;\n\t\tstd::vector<tTVPSMFTrack*>::iterator least;\n\t\tfor(std::vector<tTVPSMFTrack*>::iterator i = Tracks.begin();\n\t\t\ti != Tracks.end(); i++)\n\t\t{\n\t\t\tif(!(*i)->GetEnded())\n\t\t\t{\n\t\t\t\tp++;\n\t\t\t\t__int64 tt = (*i)->GetCount();\n\t\t\t\tif(tt < curcount)\n\t\t\t\t{\n\t\t\t\t\tif(least_tick == -1 || tt < least_tick)\n\t\t\t\t\t{\n\t\t\t\t\t\tleast_tick = tt;\n\t\t\t\t\t\tleast = i;\n\t\t\t\t\t\tdo_tick = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(!p) break;\n\t\tif(!do_tick) break;\n\n\t\t// process event\n\t\t__int64 curtick = (*least)->GetCount();\n\t\tdo\n\t\t{\n\t\t\t(*least)->ProcessEvent();\n\t\t} while(!(*least)->GetEnded() && curtick == (*least)->GetCount());\n\t}\n\n\tif(p==0)\n\t{\n\t\t// all tracks are ended\n\n\t\tif(Looping)\n\t\t{\n\t\t\tStopPlay();\n\t\t\tPlay();\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tStopPlay();\n\t\t\t::PostMessage(UtilWindow, WM_USER+1, 0, ssStop);\n\t\t}\n\t\treturn false;\n\t}\n\n\tif(NextSetVolume)\n\t{\n\t\t// set buffer volume\n\n\t\tNextSetVolume = false;\n\n\t\ttjs_int i;\n\n\t\tfor(i=0; i<16; i++)\n\t\t{\n\t\t\tif(UsingChannel[i])\n\t\t\t{\n\t\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i), 0x07,\n\t\t\t\t\t(tjs_uint8)(Volumes[i]*BufferVolume/127));\n\t\t\t}\n\t\t}\n\n\t}\n\n\ttjs_uint64 curtick = TVPGetTickCount();\n\ttjs_uint64 d = curtick - LastTickTime;\n\tLastTickTime = curtick;\n\n\tif(d > 500) d = 0;\n\t\t// may be stopped by an unexpected event.\n\t\t// this may avoid unpleasant flushing of MIDI messages.\n\n\tPosition += d;\n\tTickCount += TickCountDelta * d;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::Open(const ttstr &name)\n{\n\t// open a stream\n\ttTVPStreamHolder stream(name);\n\n\tStop();\n\n\ttry\n\t{\n\t\t// check header\n\t\ttjs_uint8 buf[16];\n\t\tstream->ReadBuffer(buf, 4);\n\t\tif(memcmp(buf, \"MThd\", 4))\n\t\t\tTVPThrowExceptionMessage(TVPInvalidSMF, TJS_W(\"MThd not found\"));\n\n\t\ttjs_uint32 headerlen;\n\t\ttjs_int format;\n\n\t\tstream->ReadBuffer(buf, 10);\n\t\tconst tjs_uint8 *pb = buf;\n\t\theaderlen = TVPGetSMFInt32(pb);\n\n\t\tformat = TVPGetSMFInt16(pb);\n\t\tif(format != 0 && format != 1)\n\t\t\tTVPThrowExceptionMessage(TVPInvalidSMF, TJS_W(\"Format must be 0 or 1\"));\n\n\n\t\t// clear tracks\n\t\t{\n\t\t\tstd::vector<tTVPSMFTrack*>::iterator i;\n\t\t\tfor(i = Tracks.begin(); i != Tracks.end(); i++)\n\t\t\t{\n\t\t\t\tdelete *i;\n\t\t\t}\n\t\t\tTracks.clear();\n\t\t}\n\n\n\t\t// get some information\n\t\ttjs_int trackcount;\n\t\ttrackcount = TVPGetSMFInt16(pb);\n\n\t\tDivision = TVPGetSMFInt16(pb);\n\t\tif(Division < 0)\n\t\t\tTVPThrowExceptionMessage(TVPInvalidSMF, TJS_W(\"Invalid division\"));\n\n\t\t// read each track\n\t\tstream->SetPosition(headerlen + 8);\n\n\t\tfor(tjs_int i = 0; i<trackcount; i++)\n\t\t{\n\t\t\tstream->ReadBuffer(buf, 8);\n\t\t\tif(memcmp(buf, \"MTrk\", 4))\n\t\t\t\tTVPThrowExceptionMessage(TVPInvalidSMF, TJS_W(\"MTrk not found\"));\n\t\t\tpb = buf + 4;\n\t\t\ttjs_uint32 len = TVPGetSMFInt32(pb);\n\t\t\ttTVPSMFTrack *trk = new tTVPSMFTrack(this, stream.Get(), len);\n\t\t\tTracks.push_back(trk);\n\t\t}\n\n\t\tPosition = 0;\n\t\tTickCount = 0;\n\t\tSetTempo(500000);\n\n\t\tfor(tjs_int i = 0; i<16; i++)\n\t\t{\n//\t\t\tUsingChannel[i] = false;\n\t\t\tUsingNote[i][0] = UsingNote[i][1] = UsingNote[i][2] = UsingNote[i][3] =0;\n\t\t\tVolumes[i] = 100;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tLoaded = false;\n\t\tSetStatus(ssUnload);\n\t\tthrow;\n\t}\n\n\tLoaded = true;\n\tSetStatus(ssStop);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MIDISoundBuffer::StopPlay()\n{\n\tif(Playing)\n\t{\n\t\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\t\tPlaying = false;\n\t\tAllNoteOff();\n\t\tPosition = 0;\n\t\tTickCount = 0;\n\t\tSetTempo(500000);\n\n\t\tstd::vector<tTVPSMFTrack*>::iterator i;\n\t\tfor(i = Tracks.begin(); i != Tracks.end(); i++)\n\t\t{\n\t\t\t(*i)->Rewind();\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MIDISoundBuffer::StartPlay()\n{\n\tif(!Loaded) return false;\n\tif(Playing) return false;\n\n\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\n\tif(TVPMIDIThread) TVPMIDIThread->Resume();\n\n\ttjs_int i;\n\tfor(i = 0; i<16; i++)\n\t{\n\t\tif(UsingChannel[i])\n\t\t{\n\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i), 0x79, 0x00); // Reset All Controler\n\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i), 0x40, 0x00); // Sus. Off\n\t\t}\n\t}\n\n\tfor(i = 0; i<16; i++)\n\t{\n\t\tUsingChannel[i]=false;\n\t\tUsingNote[i][0] = UsingNote[i][1] = UsingNote[i][2] = UsingNote[i][3] =0;\n\t\tVolumes[i]=100;\n\t}\n\n\tLastTickTime = TVPGetTickCount();\n\tPlaying = true;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::Play()\n{\n\tif(StartPlay()) SetStatus(ssPlay);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::Stop()\n{\n\tif(StopPlay()) SetStatus(ssStop);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::SetBufferVolume(tjs_int nv)\n{\n\tif(BufferVolume != nv)\n\t{\n\t\tBufferVolume = nv;\n\t\tif(Playing)\n\t\t{\n\t\t\tNextSetVolume = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTJSCriticalSectionHolder holder(TVPMIDIOutCS);\n\t\t\ttjs_int i;\n\n\t\t\tfor(i=0; i<16; i++)\n\t\t\t{\n\t\t\t\tif(UsingChannel[i])\n\t\t\t\t{\n\t\t\t\t\tTVPMIDIOut((tjs_uint8)(0xb0+i), 0x07,\n\t\t\t\t\t\t(tjs_uint8)(Volumes[i]*BufferVolume/127));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::SetVolume(tjs_int v)\n{\n\t// set buffer volume\n\n\tif(v<0) v=0;\n\tif(v>100000) v=100000;\n\tVolume = v;\n\n\tv = (Volume / 10) * (Volume2 / 10) / 1000;\n\n\ttjs_int nv = v * 127 / 100000;\n\tif(nv<0) nv = 0;\n\tif(nv>127) nv = 127;\n\n\tSetBufferVolume(nv);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MIDISoundBuffer::SetVolume2(tjs_int v)\n{\n\t// set alternative buffer volume\n\n\tif(v<0) v=0;\n\tif(v>100000) v=100000;\n\tVolume2 = v;\n\n\tv = (Volume / 10) * (Volume2 / 10) / 1000;\n\n\ttjs_int nv = v * 127 / 100000;\n\tif(nv<0) nv = 0;\n\tif(nv>127) nv = 127;\n\n\tSetBufferVolume(nv);\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_MIDISoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_MIDISoundBuffer::CreateNativeInstance()\n{\n\treturn new tTJSNI_MIDISoundBuffer();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_MIDISoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_MIDISoundBuffer()\n{\n\ttTJSNativeClass *cls = new tTJSNC_MIDISoundBuffer();\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/midiOut)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n#ifdef TVP_ENABLE_MIDI\n\ttTJSVariantOctet *octet = param[0]->AsOctetNoAddRef();\n\n\tif(octet)\n\t\tTVPMIDIOutData(octet->GetData(), octet->GetLength());\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/midiOut)\n//----------------------------------------------------------------------\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/sound/win32/MIDIImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// MIDI sequencer implementation\n//---------------------------------------------------------------------------\n\n#ifndef MIDIImplH\n#define MIDIImplH\n\n#include \"MIDIIntf.h\"\n//#include \"Messages.hpp\"\n\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPMIDIOutData, (const tjs_uint8 *data, int len));\n\t/* output MIDI data (can be multiple data at once) */\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_MIDISoundBuffer : MIDI Native Instance\n//---------------------------------------------------------------------------\nclass tTVPSMFTrack;\nclass tTJSNI_MIDISoundBuffer : public tTJSNI_BaseMIDISoundBuffer\n{\n\tfriend class tTVPSMFTrack;\n\ttypedef  tTJSNI_BaseMIDISoundBuffer inherited;\n\npublic:\n\ttTJSNI_MIDISoundBuffer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n#ifdef TVP_ENABLE_MIDI\nprivate:\n\tstd::vector<tTVPSMFTrack *> Tracks;\n\ttjs_int Division;\n\n\ttjs_int64 Position;\n\n\ttjs_int64 TickCount;  // TickCount << 16\n\n\ttjs_int64 TickCountDelta; //\n\n\tbool UsingChannel[16]; // using channel is true\n\ttjs_uint32 UsingNote[16][4]; // using notes\n\n\tint Volumes[16]; // track volumes\n\ttjs_int Volume;\n\ttjs_int Volume2;\n\ttjs_int BufferVolume;\n\n\tbool Looping;\n\n\tbool Playing;\n\tbool Loaded;\n\n\tbool NextSetVolume;\n\n\ttjs_uint64 LastTickTime; // tick count of last OnTimer()\n\n\tHWND UtilWindow; // a dummy window for receiving status from playing thread\n\tvoid WndProc(Messages::TMessage &Msg); // its window procedure\n\nprivate:\n\tvoid AllNoteOff();\n\n\tvoid SetTempo(tjs_uint tempo);\n\npublic:\n\tbool OnTimer();\n\tvoid Open(const ttstr &name);\n\nprivate:\n\tbool StopPlay();\n\tbool StartPlay();\n\npublic:\n\tvoid Play();\n\tvoid Stop();\n\nprivate:\n\tvoid SetBufferVolume(tjs_int nv);\n\npublic:\n\ttjs_int GetVolume() const { return Volume; } // GetVolume override\n\tvoid SetVolume(tjs_int v); // SetVolume override\n\n\ttjs_int GetVolume2() const { return Volume2; }\n\tvoid SetVolume2(tjs_int v);\n\n\tbool GetLooping() const { return Looping; }\n\tvoid SetLooping(bool b) { Looping = b; }\n\nprotected:\n#else\n    void SetVolume(tjs_int v){}\n    tjs_int GetVolume() const { return 0; }\n#endif\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/SoundBufferBaseImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Sound Buffer Base implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"SoundBufferBaseImpl.h\"\n#include \"WaveImpl.h\"\n\n#include \"TVPTimer.h\"\n\n//---------------------------------------------------------------------------\n// Sound Buffer Timer Dispatcher ( for fading or commiting defered settings )\n//---------------------------------------------------------------------------\nstatic class TVPTimer * TVPSoundBufferTimer = NULL;\nstatic std::vector<tTJSNI_SoundBuffer *> TVPSoundBufferVector;\n//---------------------------------------------------------------------------\nclass tTVPSoundBufferTimerDispatcher\n{\npublic:\n\tvoid Handler()\n\t{\n\t\tstd::vector<tTJSNI_SoundBuffer *>::iterator i;\n\t\tfor(i = TVPSoundBufferVector.begin(); i != TVPSoundBufferVector.end();\n\t\t\ti++)\n\t\t{\n\t\t\t(*i)->TimerBeatHandler();\n\t\t}\n\t\tTVPWaveSoundBufferCommitSettings();\n\t}\n} static TVPSoundBufferTimerDispatcher;\n//---------------------------------------------------------------------------\nvoid TVPAddSoundBuffer(tTJSNI_SoundBuffer * buf)\n{\n\tif(TVPSoundBufferVector.size() == 0)\n\t{\n\t\t// first buffer\n\t\tTVPSoundBufferTimer = new TVPTimer(); // Create Timer Object\n\t\tTVPSoundBufferTimer->SetInterval( TVP_SB_BEAT_INTERVAL );\n\t\tTVPSoundBufferTimer->SetOnTimerHandler( &TVPSoundBufferTimerDispatcher, &tTVPSoundBufferTimerDispatcher::Handler );\n\t}\n\n\tTVPSoundBufferVector.push_back(buf);\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveSoundBuffer(tTJSNI_SoundBuffer *buf)\n{\n\tif(TVPSoundBufferVector.size() != 0)\n\t{\n\t\tstd::vector<tTJSNI_SoundBuffer *>::iterator i;\n\t\ti = std::find(TVPSoundBufferVector.begin(), TVPSoundBufferVector.end(),\n\t\t\tbuf);\n\t\tif(i != TVPSoundBufferVector.end())\n\t\t{\n\t\t\tTVPSoundBufferVector.erase(i);\n\t\t}\n\t}\n\n\tif(TVPSoundBufferVector.size() == 0)\n\t{\n\t\t// all buffer was removed\n\t\tdelete TVPSoundBufferTimer;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_SoundBuffer\n//---------------------------------------------------------------------------\ntTJSNI_SoundBuffer::tTJSNI_SoundBuffer()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNI_SoundBuffer::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tTVPAddSoundBuffer(this);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_SoundBuffer::Invalidate()\n{\n\tTVPRemoveSoundBuffer(this);\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/sound/win32/SoundBufferBaseImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Sound Buffer Base implementation\n//---------------------------------------------------------------------------\n\n#ifndef SoundBufferBaseImplH\n#define SoundBufferBaseImplH\n\n#define TVP_SB_BEAT_INTERVAL 60\n\n#include \"SoundBufferBaseIntf.h\"\n\n\n//---------------------------------------------------------------------------\nclass tTJSNI_SoundBuffer : public tTJSNI_BaseSoundBuffer\n{\n\ttypedef tTJSNI_BaseSoundBuffer inherited;\n\npublic:\n\ttTJSNI_SoundBuffer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\nprotected:\n};\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/WaveImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Player implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n#if 0\n#include <mmsystem.h>\n#include <mmreg.h>\n#endif\n#include <math.h>\n#include <algorithm>\n#include \"SystemControl.h\"\n#include \"DebugIntf.h\"\n#include \"MsgIntf.h\"\n#include \"StorageIntf.h\"\n#include \"WaveImpl.h\"\n#include \"PluginImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"ThreadIntf.h\"\n#include \"Random.h\"\n#include \"UtilStreams.h\"\n#include \"TickCount.h\"\n#include \"WaveMixer.h\"\n\n#define DWORD uint32_t\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\t#include \"oldwaveunpacker.h\"\n#endif\n\n#pragma pack(push, 8)\n\t//#include \"tvpsnd.h\"\n#pragma pack(pop)\n\n#ifdef TVP_SUPPORT_KPI\n\t#include \"kmp_pi.h\"\n#endif\n\n#include \"TVPTimer.h\"\n#include \"Application.h\"\n#include \"UserEvent.h\"\n#include \"NativeEventQueue.h\"\n#include \"Platform.h\"\n\n//---------------------------------------------------------------------------\n// Options management\n//---------------------------------------------------------------------------\nstatic tTVPThreadPriority TVPDecodeThreadHighPriority = ttpHigher;\nstatic tTVPThreadPriority TVPDecodeThreadLowPriority = ttpLowest;\nstatic bool TVPSoundOptionsInit = false;\nstatic bool TVPControlPrimaryBufferRun = true;\nstatic bool TVPUseSoftwareBuffer = true;\nstatic bool TVPAlwaysRecreateSoundBuffer = false;\nstatic bool TVPPrimaryFloat = false;\nstatic tjs_int TVPPriamrySBFrequency = 44100;\nstatic tjs_int TVPPrimarySBBits = 16;\nstatic tTVPSoundGlobalFocusMode TVPSoundGlobalFocusModeByOption = sgfmNeverMute;\nstatic tjs_int TVPSoundGlobalFocusMuteVolume = 0;\nstatic enum tTVPForceConvertMode { fcmNone, fcm16bit, fcm16bitMono }\n\tTVPForceConvertMode = fcm16bit;\nstatic tjs_int TVPPrimarySBCreateTryLevel = -1;\nstatic bool TVPExpandToQuad = false;\nstatic tjs_int TVPL1BufferLength = 1000; // in ms\nstatic tjs_int TVPL2BufferLength = 1000; // in ms\nstatic bool TVPDirectSoundUse3D = false;\nstatic tjs_int TVPVolumeLogFactor = 3322;\nstatic bool TVPPrimarySoundBufferPlaying = false;\n//---------------------------------------------------------------------------\nstatic void TVPInitSoundOptions()\n{\n\tif(TVPSoundOptionsInit) return;\n\n\t// retrieve options from commandline\n/*\n ttpIdle = 0\n ttpLowest = 1\n ttpLower = 2\n ttpNormal = 3\n ttpHigher = 4\n ttpHighest = 5\n ttpTimeCritical = 6\n*/\n\n\ttTJSVariant val;\n\tif(TVPGetCommandLine(TJS_W(\"-wsdecpri\"), &val))\n\t{\n\t\ttjs_int v = val;\n\t\tif(v < 0) v = 0;\n\t\tif(v > 5) v = 5; // tpTimeCritical is dangerous...\n\t\tTVPDecodeThreadLowPriority = (tTVPThreadPriority)v;\n\t\tif(TVPDecodeThreadHighPriority<TVPDecodeThreadLowPriority)\n\t\t\tTVPDecodeThreadHighPriority = TVPDecodeThreadLowPriority;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wscontrolpri\"), &val))\n\t{\n\t\tif(ttstr(val) == TJS_W(\"yes\"))\n\t\t\tTVPControlPrimaryBufferRun = true;\n\t\telse\n\t\t\tTVPControlPrimaryBufferRun = false;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wssoft\"), &val))\n\t{\n\t\tif(ttstr(val) == TJS_W(\"no\"))\n\t\t\tTVPUseSoftwareBuffer = false;\n\t\telse\n\t\t\tTVPUseSoftwareBuffer = true;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsrecreate\"), &val))\n\t{\n\t\tif(ttstr(val) == TJS_W(\"yes\"))\n\t\t\tTVPAlwaysRecreateSoundBuffer = true;\n\t\telse\n\t\t\tTVPAlwaysRecreateSoundBuffer = false;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsfreq\"), &val))\n\t{\n\t\tTVPPriamrySBFrequency = val;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsbits\"), &val))\n\t{\n\t\tttstr sval(val);\n\t\tif(sval == TJS_W(\"f32\"))\n\t\t{\n\t\t\tTVPPrimaryFloat = true;\n\t\t\tTVPPrimarySBBits = 32;\n\t\t}\n\t\telse if(sval[0] == TJS_W('i'))\n\t\t{\n\t\t\tTVPPrimaryFloat = false;\n\t\t\tTVPPrimarySBBits = TJS_atoi(sval.c_str() + 1);\n\t\t}\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wspritry\"), &val))\n\t{\n\t\tttstr sval(val);\n\t\tif(sval == TJS_W(\"all\"))\n\t\t\tTVPPrimarySBCreateTryLevel = -1;\n\t\telse\n\t\t\tTVPPrimarySBCreateTryLevel = val;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsuse3d\"), &val))\n\t{\n\t\tttstr sval(val);\n\t\tif(sval == TJS_W(\"no\"))\n\t\t\tTVPDirectSoundUse3D = false;\n\t\telse\n\t\t\tTVPDirectSoundUse3D = true;\n\t}\n#if 0\n\tif(TVPGetCommandLine(TJS_W(\"-wsforcecnv\"), &val))\n\t{\n\t\tttstr sval(val);\n\t\tif(sval == TJS_W(\"i16\"))\n\t\t\tTVPForceConvertMode = fcm16bit;\n\t\telse if(sval == TJS_W(\"i16m\"))\n\t\t\tTVPForceConvertMode = fcm16bitMono;\n\t\telse\n\t\t\tTVPForceConvertMode = fcmNone;\n\t}\n#endif\n\tif(TVPGetCommandLine(TJS_W(\"-wsexpandquad\"), &val))\n\t{\n\t\tif(ttstr(val) == TJS_W(\"yes\"))\n\t\t\tTVPExpandToQuad = true;\n\t\telse\n\t\t\tTVPExpandToQuad = false;\n\t}\n\tif(TVPDirectSoundUse3D) TVPExpandToQuad = false;\n\t\t// quad expansion is disabled when using 3D sounds\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsmute\"), &val))\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"no\") || str == TJS_W(\"never\"))\n\t\t\tTVPSoundGlobalFocusModeByOption = sgfmNeverMute;\n\t\telse if(str == TJS_W(\"minimize\"))\n\t\t\tTVPSoundGlobalFocusModeByOption = sgfmMuteOnMinimize;\n\t\telse if(str == TJS_W(\"yes\") || str == TJS_W(\"deactive\"))\n\t\t\tTVPSoundGlobalFocusModeByOption = sgfmMuteOnDeactivate;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsmutevol\"), &val))\n\t{\n\t\ttjs_int n = (tjs_int)val;\n\t\tif(n >= 0 && n <= 100) TVPSoundGlobalFocusMuteVolume = n * 1000;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsl1len\"), &val))\n\t{\n\t\ttjs_int n = (tjs_int)val;\n\t\tif(n > 0 && n < 600000) TVPL1BufferLength = n;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsl2len\"), &val))\n\t{\n\t\ttjs_int n = (tjs_int)val;\n\t\tif(n > 0 && n < 600000) TVPL2BufferLength = n;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-wsvolfactor\"), &val))\n\t{\n\t\ttjs_int n = (tjs_int)val;\n\t\tif(n > 0 && n < 200000) TVPVolumeLogFactor = n;\n\t}\n\n\tTVPSoundOptionsInit = true;\n}\n//---------------------------------------------------------------------------\n\n#if 0\n//---------------------------------------------------------------------------\n// TSS plug-in interface\n//---------------------------------------------------------------------------\nclass tTVPTSSWaveDecoder : public tTVPWaveDecoder\n{\n\tITSSWaveDecoder *Decoder;\n\npublic:\n\n\ttTVPTSSWaveDecoder(ITSSWaveDecoder *decoder) { Decoder = decoder; }\n\t~tTVPTSSWaveDecoder() { Decoder->Release(); };\n\n\tvoid GetFormat(tTVPWaveFormat & format)\n\t{\n\t\tTSSWaveFormat f;\n\t\tif(FAILED(Decoder->GetFormat(&f)))\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPPluginError,\n\t\t\t\tTJS_W(\"ITSSWaveDecoder::GetFormat failed.\"));\n\t\t}\n\t\tformat.SamplesPerSec = f.dwSamplesPerSec;\n\t\tformat.Channels = f.dwChannels;\n\t\tif(f.dwBitsPerSample >= 0x10000)\n\t\t{\n\t\t\t// floating-point format since 2.17 beta 5\n\t\t\tformat.IsFloat = true;\n\t\t\tformat.BitsPerSample = f.dwBitsPerSample - 0x10000;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tformat.IsFloat = false;\n\t\t\tformat.BitsPerSample = f.dwBitsPerSample;\n\t\t}\n\t\tformat.BytesPerSample = format.BitsPerSample / 8;\n\t\tformat.TotalSamples = f.ui64TotalSamples;\n\t\tformat.TotalTime = f.dwTotalTime;\n\t\tformat.Seekable = 0!=f.dwSeekable;\n\t\tformat.SpeakerConfig = 0;\n\t}\n\n\tbool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered)\n\t{\n\t\tHRESULT hr;\n\t\tunsigned long rend;\n\t\tunsigned long st;\n\t\thr = Decoder->Render(buf, bufsamplelen, &rend, &st);\n\t\trendered = rend; // count of rendered samples\n\t\tif(FAILED(hr)) return false;\n\t\treturn 0!=st;\n\t}\n\n\tbool SetPosition(tjs_uint64 samplepos)\n\t{\n\t\tHRESULT hr;\n\t\thr = Decoder->SetPosition(samplepos);\n\t\tif(FAILED(hr)) return false;\n\t\treturn true;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPTSSWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n\ttTVPWaveDecoder * Create(const ttstr & storagename,\tconst ttstr &extension)\n\t{\n\t\tITSSWaveDecoder * dec = TVPSearchAvailTSSWaveDecoder(storagename, extension);\n\t\tif(!dec) return NULL;\n\n\t\treturn new tTVPTSSWaveDecoder(dec);\n\t}\n} static TVPTSSWaveDecoderCreator;\n//---------------------------------------------------------------------------\nstatic bool TVPTSSWaveDecoderCreatorRegistered = false;\nvoid TVPRegisterTSSWaveDecoderCreator()\n{\n\tif(!TVPTSSWaveDecoderCreatorRegistered)\n\t{\n\t\tTVPRegisterWaveDecoderCreator(&TVPTSSWaveDecoderCreator);\n\t\tTVPTSSWaveDecoderCreatorRegistered = true;\n\t}\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n//---------------------------------------------------------------------------\n// old WaveUnpacker plug-in\n//---------------------------------------------------------------------------\nclass tTVPWaveUnpacker : public tTVPWaveDecoder\n{\n\tIWaveUnpacker *Unpacker;\n\tIStream *Stream;\n\ttjs_uint SampleSize;\n\npublic:\n\n\ttTVPWaveUnpacker(IWaveUnpacker *unpacker, IStream *stream)\n\t\t{ Unpacker = unpacker; Stream = stream; }\n\t~tTVPWaveUnpacker() { Unpacker->Release(); Stream->Release();};\n\n\tvoid GetFormat(tTVPWaveFormat & format)\n\t{\n\t\tlong samplespersec, channels, bitspersample;\n\n\t\tif(FAILED(Unpacker->GetWaveFormat(&samplespersec, &channels, &bitspersample)))\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPPluginError,\n\t\t\t\tTJS_W(\"IWaveUnpacker::GetWaveFormat failed.\"));\n\t\t}\n\t\tSampleSize = channels * (format.BytesPerSample = bitspersample / 8);\n\t\tformat.SamplesPerSec = samplespersec;\n\t\tformat.Channels = channels;\n\t\tformat.BitsPerSample = bitspersample;\n\t\tformat.TotalSamples = 0;\n\t\tformat.TotalTime = 0;\n\t\tformat.Seekable = false;\n\t\tformat.SpeakerConfig = 0;\n\t\tformat.IsFloat = false;\n\t}\n\n\tbool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered)\n\t{\n\t\tHRESULT hr;\n\t\tlong samples = bufsamplelen * SampleSize;\n\t\tlong rend;\n\t\thr = Unpacker->Render(buf, samples, &rend);\n\t\trendered = rend / SampleSize;\n\t\tif(FAILED(hr)) return false;\n\t\treturn !(rendered < bufsamplelen);\n\t}\n\n\tbool SetPosition(tjs_uint64 samplepos)\n\t{\n\t\tif(samplepos == 0)\n\t\t{\n\t\t\tUnpacker->SetCurrentPosition(0);\n\t\t\treturn true;\n\t\t}\n\t\treturn false; // does not support\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPWaveUnpackerCreator : public tTVPWaveDecoderCreator\n{\npublic:\n\ttTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension)\n\t{\n\t\tIStream *stream;\n\t\tIWaveUnpacker * dec = TVPSearchAvailWaveUnpacker(storagename, &stream);\n\t\tif(!dec) return NULL;\n\n\t\treturn new tTVPWaveUnpacker(dec, stream);\n\t}\n} static TVPWaveUnpackerCreator;\n//---------------------------------------------------------------------------\nstatic bool TVPWaveUnpackerCreatorRegistered = false;\nvoid TVPRegisterWaveUnpackerCreator()\n{\n\tif(!TVPWaveUnpackerCreatorRegistered)\n\t{\n\t\tTVPRegisterWaveDecoderCreator(&TVPWaveUnpackerCreator);\n\t\tTVPWaveUnpackerCreatorRegistered = true;\n\t}\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n#ifdef TVP_SUPPORT_KPI\n//---------------------------------------------------------------------------\n// KMP plug-in interface\n//---------------------------------------------------------------------------\nclass tTVPKMPWaveDecoder : public tTVPWaveDecoder\n{\n\tHKMP Handle;\n\tKMPMODULE *Module;\n\tSOUNDINFO Info;\n\ttjs_int SampleSize;\n\ttjs_uint8 *RenderBuffer;\n\ttjs_uint RenderBufferRemain;\n\tbool Ended;\n\npublic:\n\n\ttTVPKMPWaveDecoder(HKMP handle, KMPMODULE *module, const SOUNDINFO &info)\n\t{\n\t\tHandle = handle, Module = module, Info = info;\n\t\tSampleSize = Info.dwChannels * Info.dwBitsPerSample / 8;\n\t\tRenderBufferRemain = 0;\n\t\tEnded = false;\n\t\tRenderBuffer = new tjs_uint8[Info.dwUnitRender];\n\t}\n\n\t~tTVPKMPWaveDecoder()\n\t{\n\t\tdelete [] RenderBuffer;\n\t\tModule->Close(Handle);\n\t}\n\n\tvoid GetFormat(tTVPWaveFormat & format)\n\t{\n\t\tformat.SamplesPerSec = Info.dwSamplesPerSec;\n\t\tformat.Channels = Info.dwChannels;\n\t\tformat.BitsPerSample = Info.dwBitsPerSample;\n\t\tformat.BytesPerSample = format.BitsPerSample / 8;\n\t\tformat.TotalSamples = 0; // unknown\n\t\tformat.TotalTime = Info.dwLength;\n\t\tformat.Seekable = Info.dwSeekable;\n\t\tformat.SpeakerConfig = 0;\n\t\tformat.IsFloat = false;\n\t}\n\n\tbool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rend_ret)\n\t{\n\t\ttjs_uint8 *buffer = (tjs_uint8*)buf;\n\t\ttjs_uint bufsize = bufsamplelen * SampleSize;\n\t\ttjs_uint rendered = 0;\n\n\t\twhile(bufsize)\n\t\t{\n\t\t\tif(RenderBufferRemain)\n\t\t\t{\n\t\t\t\t// previous decoded samples are in RenderBuffer\n\t\t\t\ttjs_uint remain =\n\t\t\t\t\tbufsize < RenderBufferRemain ? bufsize : RenderBufferRemain;\n\t\t\t\tmemcpy(buffer + rendered,\n\t\t\t\t\tRenderBuffer + (Info.dwUnitRender - RenderBufferRemain),\n\t\t\t\t\tremain);\n\t\t\t\tbufsize -= remain;\n\t\t\t\tRenderBufferRemain -= remain;\n\t\t\t\trendered += remain;\n\t\t\t}\n\t\t\telse if(bufsize >= Info.dwUnitRender)\n\t\t\t{\n\t\t\t\t// directly decode to destination buffer\n\t\t\t\tif(Ended) break;\n\t\t\t\tDWORD one_rend =\n\t\t\t\t\tModule->Render(Handle, buffer + rendered, Info.dwUnitRender);\n\t\t\t\tbufsize -= one_rend;\n\t\t\t\trendered += one_rend;\n\t\t\t\tif(one_rend < Info.dwUnitRender) { Ended = true; break; } // decode ended\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// render to RenderBuffer\n\t\t\t\tif(Ended) break;\n\t\t\t\tDWORD one_rend =\n\t\t\t\t\tModule->Render(Handle, RenderBuffer, Info.dwUnitRender);\n\t\t\t\t// copy to destination buffer\n\t\t\t\ttjs_uint copy_bytes = one_rend < bufsize ? one_rend:bufsize;\n\t\t\t\tmemcpy(buffer + rendered, RenderBuffer, copy_bytes);\n\t\t\t\tRenderBufferRemain = one_rend - copy_bytes;\n\t\t\t\tbufsize -= copy_bytes;\n\t\t\t\trendered += copy_bytes;\n\t\t\t\tif(one_rend < Info.dwUnitRender && one_rend < bufsize)\n\t\t\t\t\t{ Ended = true; break; }\n\t\t\t\tif(RenderBufferRemain == 0) { Ended = true; break; }\n\t\t\t}\n\t\t}\n\n\t\trend_ret = rendered / SampleSize;\n\t\treturn !(rend_ret < bufsamplelen);\n\t}\n\n\tbool SetPosition(tjs_uint64 samplepos)\n\t{\n\t\tif(samplepos == 0)\n\t\t{\n\t\t\tModule->SetPosition(Handle, 0);\n\t\t\tEnded = false;\n\t\t\treturn true;\n\t\t}\n\t\treturn false; // does not support\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPKMPWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n\ttTVPWaveDecoder * Create(const ttstr & storagename, const ttstr &extension)\n\t{\n\t\tSOUNDINFO info;\n\t\tKMPMODULE *module;\n\t\tHKMP handle = TVPSearchAvailKMPWaveDecoder(storagename,\n\t\t\t &module, &info);\n\t\tif(!handle) return NULL;\n\n\t\treturn new tTVPKMPWaveDecoder(handle, module, info);\n\t}\n} static TVPKMPWaveDecoderCreator;\n//---------------------------------------------------------------------------\nstatic bool TVPKMPWaveDecoderCreatorRegistered = false;\nvoid TVPRegisterKMPWaveDecoderCreator()\n{\n\tif(!TVPKMPWaveDecoderCreatorRegistered)\n\t{\n\t\tTVPRegisterWaveDecoderCreator(&TVPKMPWaveDecoderCreator);\n\t\tTVPKMPWaveDecoderCreatorRegistered = true;\n\t}\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n//---------------------------------------------------------------------------\n// Log Table for DirectSound volume\n//---------------------------------------------------------------------------\nstatic bool TVPLogTableInit = false;\nstatic tjs_int TVPLogTable[101];\nstatic void TVPInitLogTable()\n{\n\tif(TVPLogTableInit) return;\n\tTVPLogTableInit = true;\n\ttjs_int i;\n\tTVPLogTable[0] = -10000;\n\tfor(i = 1; i <= 100; i++)\n\t{\n\t\tTVPLogTable[i] = static_cast<tjs_int>( log10((double)i/100.0)*TVPVolumeLogFactor );\n\t}\n}\n//---------------------------------------------------------------------------\n#if 0\ntjs_int TVPVolumeToDSAttenuate(tjs_int volume)\n{\n\tTVPInitLogTable();\n\tvolume = volume / 1000;\n\tif(volume > 100) volume = 100;\n\tif(volume < 0 ) volume = 0;\n\treturn TVPLogTable[volume];\n}\n//---------------------------------------------------------------------------\ntjs_int TVPDSAttenuateToVolume(tjs_int att)\n{\n\tif(att <= -10000) return 0;\n\treturn (tjs_int)(pow(10, (double)att / TVPVolumeLogFactor) * 100.0) * 1000;\n}\n//---------------------------------------------------------------------------\ntjs_int TVPPanToDSAttenuate(tjs_int volume)\n{\n\tTVPInitLogTable();\n\tvolume = volume / 1000;\n\tif(volume > 100) volume = 100;\n\tif(volume < -100 ) volume = -100;\n\tif(volume < 0)\n\t\treturn TVPLogTable[100 - (-volume)];\n\telse\n\t\treturn -TVPLogTable[100 - volume];\n}\n//---------------------------------------------------------------------------\ntjs_int TVPDSAttenuateToPan(tjs_int att)\n{\n\tif(att <= -10000) return -100000;\n\tif(att >=  10000) return  100000;\n\tif(att < 0)\n\t\treturn (100 - (tjs_int)(pow(10, (double)att /  TVPVolumeLogFactor) * 100.0)) * -1000;\n\telse\n\t\treturn (100 - (tjs_int)(pow(10, (double)att / -TVPVolumeLogFactor) * 100.0)) *  1000;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// DirectSound management\n//---------------------------------------------------------------------------\n#if 0\nstatic LPDIRECTSOUND TVPDirectSound = NULL;\nstatic LPDIRECTSOUNDBUFFER TVPPrimaryBuffer = NULL;\nstatic LPDIRECTSOUND3DLISTENER TVPDirectSound3DListener = NULL;\nstatic bool TVPPrimaryBufferPlayingByProgram = false;\nstatic HMODULE TVPDirectSoundDLL = NULL;\n#endif\nstatic bool TVPPrimaryBufferPlayingByProgram = false;\nstatic TVPTimer *TVPPrimaryDelayedStopperTimer = NULL;\nstatic bool TVPDirectSoundShutdown = false;\nstatic bool TVPDeferedSettingAvailable = false;\n//---------------------------------------------------------------------------\nstatic void TVPEnsurePrimaryBufferPlay()\n{\n\tif (!TVPControlPrimaryBufferRun) return;\n\tTVPInitDirectSound();\n\tif (!TVPPrimaryBufferPlayingByProgram) {\n\t\tTVPPrimaryBufferPlayingByProgram = true;\n\t}\n#if 0\n\tif (TVPPrimaryBuffer)\n\t{\n\t\tif (TVPPrimaryDelayedStopperTimer)\n\t\t\tTVPPrimaryDelayedStopperTimer->SetEnabled(false);\n\t\tif (!TVPPrimaryBufferPlayingByProgram)\n\t\t{\n\t\t\tTVPPrimaryBuffer->Play(0, 0, DSBPLAY_LOOPING);\n\t\t\tTVPPrimaryBufferPlayingByProgram = true;\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nstatic void TVPStopPrimaryBuffer()\n{\n#if 0 // never stop sound\n\t// this will not immediately stop the buffer\n\tif(!TVPControlPrimaryBufferRun) return;\n\n\tif(TVPPrimaryBuffer)\n\t{\n\t\tif(TVPPrimaryDelayedStopperTimer)\n\t\t{\n\t\t\tTVPPrimaryDelayedStopperTimer->SetEnabled( false ); // once disable the timer\n\t\t\tTVPPrimaryDelayedStopperTimer->SetEnabled( true );\n\t\t}\n\t}\n#endif\n}\n#if 0\n//---------------------------------------------------------------------------\nclass tTVPPrimaryDelayedStopper\n{\npublic:\n\tvoid OnTimer()\n\t{\n\t\tif(TVPPrimaryDelayedStopperTimer)\n\t\t\tTVPPrimaryDelayedStopperTimer->SetEnabled( false );\n\t\tif(TVPPrimaryBuffer)\n\t\t{\n\t\t\tif(TVPPrimaryBufferPlayingByProgram)\n\t\t\t{\n\t\t\t\tTVPPrimaryBuffer->Stop();\n\t\t\t\tTVPPrimaryBufferPlayingByProgram = false;\n\t\t\t}\n\t\t}\n\t}\n} TVPPrimaryDelayedStopper;\n//---------------------------------------------------------------------------\nstatic ttstr TVPGetSoundBufferFormatString(const WAVEFORMATEXTENSIBLE &wfx)\n{\n\tttstr debuglog(TJS_W(\"format container = \"));\n\n\tif(wfx.Format.wFormatTag == WAVE_FORMAT_PCM)\n\t\tdebuglog += TJS_W(\"WAVE_FORMAT_PCM, \");\n\telse if(wfx.Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)\n\t\tdebuglog += TJS_W(\"WAVE_FORMAT_IEEE_FLOAT, \");\n\telse if(wfx.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)\n\t\tdebuglog += TJS_W(\"WAVE_FORMAT_EXTENSIBLE, \");\n\telse\n\t\tdebuglog += TJS_W(\"unknown format tag 0x\") +\n\t\t\tTJSInt32ToHex(wfx.Format.wFormatTag) + TJS_W(\", \");\n\n\tdebuglog +=\n\t\tTJS_W(\"frequency = \") + ttstr((tjs_int)wfx.Format.nSamplesPerSec) + TJS_W(\"Hz, \") +\n\t\tTJS_W(\"bits = \") + ttstr((tjs_int)wfx.Format.wBitsPerSample) + TJS_W(\"bits, \") +\n\t\tTJS_W(\"channels = \") + ttstr((tjs_int)wfx.Format.nChannels);\n\n\tif(wfx.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)\n\t{\n\t\tdebuglog += TJS_W(\", \");\n\t\tdebuglog += TJS_W(\"valid bits = \") +\n\t\t\tttstr((tjs_int)wfx.Samples.wValidBitsPerSample) +\n\t\t\t\tTJS_W(\"bits, \");\n\t\tdebuglog += TJS_W(\"channel mask = 0x\") +\n\t\t\tTJSInt32ToHex((tjs_uint32)wfx.dwChannelMask) +\n\t\t\t\tTJS_W(\", \");\n\n\t\tif(!memcmp(&wfx.SubFormat,\n\t\t\t&TVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 16))\n\t\t\tdebuglog += TJS_W(\"sub type = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT\");\n\t\telse if(!memcmp(&wfx.SubFormat,\n\t\t\t&TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16))\n\t\t\tdebuglog += TJS_W(\"sub type = KSDATAFORMAT_SUBTYPE_PCM\");\n\t\telse\n\t\t{\n\t\t\twchar_t buf[101];\n\t\t\tStringFromGUID2((const _GUID &)wfx.SubFormat,\n\t\t\t\tbuf, 100);\n\t\t\tdebuglog += TJS_W(\"unknown sub type \") + ttstr(buf);\n\t\t}\n\t}\n\n\treturn debuglog;\n}\n#endif\nstatic ttstr TVPGetSoundBufferFormatString(const tTVPWaveFormat &wfx)\n{\n\tttstr debuglog(TJS_W(\"format container = \"));\n\tdebuglog += TJS_W(\"WAVE_PCM_\");\n\tdebuglog += wfx.IsFloat ? TJS_W(\"F\") : TJS_W(\"S\");\n\tdebuglog += ttstr((tjs_int)wfx.BitsPerSample);\n\tdebuglog += TJS_W(\"LE\");\n\tdebuglog += TJS_W(\", \");\n\n\tdebuglog +=\n\t\tTJS_W(\"frequency = \") + ttstr((tjs_int)wfx.SamplesPerSec) + TJS_W(\"Hz, \") +\n\t\tTJS_W(\"bits = \") + ttstr((tjs_int)wfx.BitsPerSample) + TJS_W(\"bits, \") +\n\t\tTJS_W(\"channels = \") + ttstr((tjs_int)wfx.Channels);\n\n\treturn debuglog;\n}\n//---------------------------------------------------------------------------\nvoid TVPWaveSoundBufferCommitSettings() {}\n#if 0\nstatic BOOL CALLBACK DSoundEnumCallback( GUID* pGUID, const wchar_t * strDesc,\n\tconst wchar_t * strDrvName,  VOID* pContext )\n{\n\tttstr log(TJS_W(\"(info) DirectSound Driver/Device found : \"));\n\tif(strDesc) log += ttstr(strDesc);\n\tif(strDrvName && strDrvName[0])\n\t{\n\t\tlog += TJS_W(\" [\");\n\n\t\twchar_t driverpath[1024];\n\t\twchar_t* driverpath_filename = NULL;\n\t\tbool success = 0!=SearchPath(NULL, strDrvName, NULL, 1023, driverpath, &driverpath_filename);\n\t\tif(!success)\n\t\t{\n\t\t\twchar_t syspath[1024];\n\t\t\tGetSystemDirectory(syspath, 1023);\n\t\t\tTJS_strcat(syspath, TJS_W(\"\\\\drivers\")); // SystemDir\\drivers\n\t\t\tsuccess = 0!=SearchPath(syspath, strDrvName, NULL, 1023, driverpath, &driverpath_filename);\n\t\t}\n\n\t\tif(!success)\n\t\t{\n\t\t\twchar_t syspath[1024];\n\t\t\tGetWindowsDirectory(syspath, 1023);\n\t\t\tTJS_strcat(syspath, TJS_W(\"\\\\system32\")); // WinDir\\system32\n\t\t\tsuccess = 0!=SearchPath(syspath, strDrvName, NULL, 1023, driverpath, &driverpath_filename);\n\t\t}\n\n\t\tif(!success)\n\t\t{\n\t\t\twchar_t syspath[1024];\n\t\t\tGetWindowsDirectory(syspath, 1023);\n\t\t\tTJS_strcat(syspath, TJS_W(\"\\\\system32\\\\drivers\")); // WinDir\\system32\\drivers\n\t\t\tsuccess = 0!=SearchPath(syspath, strDrvName, NULL, 1023, driverpath, &driverpath_filename);\n\t\t}\n\n\t\tif(success)\n\t\t{\n\t\t\tlog += ttstr(driverpath);\n\t\t\ttjs_int major, minor, release, build;\n\t\t\tif(TVPGetFileVersionOf(driverpath, major, minor, release, build))\n\t\t\t{\n\t\t\t\twchar_t tmp[256];\n\t\t\t\tTJS_snprintf(tmp, 256, TJS_W(\" version %d.%d.%d.%d\"), (int)major, (int)minor, (int)release, (int)build);\n\t\t\t\tlog += tmp;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlog += TJS_W(\" version unknown\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlog += ttstr(strDrvName);\n\t\t\tlog += TJS_W(\" ... is not found in search path\");\n\t\t}\n\n\t\tlog += TJS_W(\"]\");\n\t}\n\n\tTVPAddImportantLog(log);\n\n\treturn TRUE;\n}\n//---------------------------------------------------------------------------\nstatic void TVPInitDirectSound()\n{\n\tTVPInitSoundOptions();\n\n\tif(TVPDirectSound) return;\n\tif(TVPDirectSoundShutdown) return;\n\n\tif(TVPDirectSoundDLL == NULL)\n\t{\n\t\t// map dsound.dll\n\t\tTVPDirectSoundDLL = ::LoadLibrary(TJS_W(\"dsound.dll\"));\n\t\tif(!TVPDirectSoundDLL)\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\tTJS_W(\"Cannot load dsound.dll.\"));\n\t\t}\n\n\t\t// Enum DirectSound devices\n\t\ttry\n\t\t{\n\t\t\tHRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);\n\t\t\tDirectSoundEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress(TVPDirectSoundDLL, \"DirectSoundEnumerateW\");\n\t\t\tif(DirectSoundEnumerateW)\n\t\t\t\tDirectSoundEnumerateW(DSoundEnumCallback, NULL);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\t// ignore errors\n\t\t}\n\t}\n\n\ttry\n\t{\n\t\tif(TVPControlPrimaryBufferRun)\n\t\t{\n\t\t\tif(!TVPPrimaryDelayedStopperTimer)\n\t\t\t{\n\t\t\t\t// create timer to stop primary buffer playing at delayed timing\n\t\t\t\tTVPPrimaryDelayedStopperTimer = new TVPTimer();\n\t\t\t\tTVPPrimaryDelayedStopperTimer->SetInterval( 4000 );\n\t\t\t\tTVPPrimaryDelayedStopperTimer->SetEnabled( false );\n\t\t\t\tTVPPrimaryDelayedStopperTimer->SetOnTimerHandler( &TVPPrimaryDelayedStopper, &tTVPPrimaryDelayedStopper::OnTimer );\n\t\t\t}\n\t\t}\n\n\t\t// get procDirectSoundCreate's address\n\t\tHRESULT (WINAPI *procDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);\n\t\tprocDirectSoundCreate = (HRESULT (WINAPI *)(_GUID *,IDirectSound **,IUnknown*))\n\t\t\tGetProcAddress(TVPDirectSoundDLL, \"DirectSoundCreate\");\n\t\tif(!procDirectSoundCreate)\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\tTJS_W(\"Missing DirectSoundCreate in dsound.dll.\"));\n\t\t}\n\n\t\t// create DirectSound Object\n\t\tHRESULT hr;\n\t\thr = procDirectSoundCreate(NULL, &TVPDirectSound, NULL);\n\t\tif(FAILED(hr))\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\tttstr(TJS_W(\"DirectSoundCreate failed./HR=\")) +\n\t\t\t\tTJSInt32ToHex((tjs_uint32)hr));\n\t\t}\n\n\t\t// set cooperative level\n\t\thr = TVPDirectSound->SetCooperativeLevel(Application->GetHandle(),\n\t\t\tDSSCL_PRIORITY);\n\t\tif(FAILED(hr))\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\tttstr(TJS_W(\"IDirectSound::SetCooperativeLevel failed./HR=\"))+\n\t\t\t\tTJSInt32ToHex((tjs_uint32)hr));\n\t\t}\n\n\t\t// create primary buffer\n\t\tTVPPrimaryBufferPlayingByProgram = false;\n\n\t\tDSBUFFERDESC dsbd;\n\n\t\tZeroMemory(&dsbd, sizeof(dsbd));\n\t\tdsbd.dwSize = sizeof(dsbd);\n\t\tdsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;\n\t\tif(TVPUseSoftwareBuffer)\n\t\t\tdsbd.dwFlags |= DSBCAPS_LOCSOFTWARE;\n\t\tif(TVPDirectSoundUse3D)\n\t\t\tdsbd.dwFlags |= DSBCAPS_CTRL3D;\n\n\t\thr = TVPDirectSound->CreateSoundBuffer(&dsbd, &TVPPrimaryBuffer, NULL);\n\n\t\tbool pri_normal = false;\n\t\tif((FAILED(hr) || TVPPrimaryBuffer == NULL) && TVPDirectSoundUse3D)\n\t\t{\n\t\t\t// cannot create DirectSound primary buffer.\n\t\t\t// try to not set 3D mode\n\t\t\tTVPAddLog(TJS_W(\"Warning: Cannot create DirectSound primary buffer with 3D sound mode. \")\n\t\t\t\tTJS_W(\"Force not to use it.\"));\n\t\t\tdsbd.dwFlags &= ~DSBCAPS_CTRL3D;\n\t\t\thr = TVPDirectSound->CreateSoundBuffer(&dsbd, &TVPPrimaryBuffer, NULL);\n\t\t\tif(SUCCEEDED(hr)) TVPDirectSoundUse3D = false;\n\t\t}\n\n\t\tif(FAILED(hr) || TVPPrimaryBuffer == NULL)\n\t\t{\n\t\t\t// cannot create DirectSound primary buffer.\n\t\t\t// try to set cooperative level to DSSCL_NORMAL.\n\t\t\tTVPPrimaryBuffer = NULL;\n\t\t\thr = TVPDirectSound->SetCooperativeLevel(Application->GetHandle(),\n\t\t\t\tDSSCL_NORMAL);\n\t\t\tif(FAILED(hr))\n\t\t\t{\n\t\t\t\t// failed... here assumes this a failure.\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\t\tttstr(TJS_W(\"IDirectSound::SetCooperativeLevel failed. \")\n\t\t\t\t\t\tTJS_W(\"(after creation of primary buffer failed)/HR=\"))+\n\t\t\t\t\tTJSInt32ToHex((tjs_uint32)hr));\n\t\t\t}\n\t\t\tTVPAddLog(TJS_W(\"Warning: Cannot create DirectSound primary buffer. \")\n\t\t\t\tTJS_W(\"Force not to use it.\"));\n\t\t\tpri_normal = true;\n\t\t}\n\n\t\tif(TVPDirectSoundUse3D)\n\t\t{\n\t\t\tif(!TVPPrimaryBuffer)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\t\tTJS_W(\"Cannot use 3D sounds because the primary buffer is not available.\"));\n\n\t\t\thr = TVPPrimaryBuffer->QueryInterface(IID_IDirectSound3DListener,\n                                          (void **)&TVPDirectSound3DListener);\n\t\t\tif(FAILED(hr))\n\t\t\t{\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirectSound,\n\t\t\t\t\tttstr(TJS_W(\"Querying interface IDirectSound3DListener failed./HR=\") +\n\t\t\t\t\t\tTJSInt32ToHex((tjs_uint32)hr)));\n\t\t\t}\n\t\t}\n\n\t\t// set primary buffer 's sound format\n\t\tif(!pri_normal && TVPPrimaryBuffer)\n\t\t{\n\t\t\tWAVEFORMATEXTENSIBLE wfx;\n\n\t\t\t// number of channels is decided using GetSpeakerConfig\n\t\t\tDWORD sp_config;\n\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_STEREO;\n\t\t\twfx.Format.nChannels = 2;\n\n\t\t\tif(SUCCEEDED(TVPDirectSound->GetSpeakerConfig(&sp_config)))\n\t\t\t{\n\t\t\t\tswitch(DSSPEAKER_CONFIG(sp_config))\n\t\t\t\t{\n\t\t\t\tcase DSSPEAKER_HEADPHONE:\n\t\t\t\t\twfx.Format.nChannels = 2;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_STEREO;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DSSPEAKER_MONO:\n\t\t\t\t\twfx.Format.nChannels = 1;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_MONO;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DSSPEAKER_QUAD:\n\t\t\t\t\twfx.Format.nChannels = 4;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_QUAD;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DSSPEAKER_STEREO:\n\t\t\t\t\twfx.Format.nChannels = 2;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_STEREO;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DSSPEAKER_SURROUND:\n\t\t\t\t\twfx.Format.nChannels = 4;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_SURROUND;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DSSPEAKER_5POINT1:\n\t\t\t\t\twfx.Format.nChannels = 6;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00000007:  // DSSPEAKER_7POINT1\n\t\t\t\t\twfx.Format.nChannels = 8;\n\t\t\t\t\twfx.dwChannelMask = KSAUDIO_SPEAKER_7POINT1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twfx.Format.cbSize = 22;\n\t\t\twfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\twfx.Format.nSamplesPerSec = TVPPriamrySBFrequency;\n\t\t\twfx.Format.wBitsPerSample = TVPPrimarySBBits;\n\t\t\twfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;\n\t\t\twfx.Format.nBlockAlign = (WORD)(wfx.Format.wBitsPerSample/8 * wfx.Format.nChannels);\n\t\t\twfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;\n\n\t\t\tmemcpy(&wfx.SubFormat, TVPPrimaryFloat ?\n\t\t\t\tTVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT:\n\t\t\t\tTVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16);\n\n\t\t\tswitch(TVPPrimarySBCreateTryLevel)\n\t\t\t{\n\t\t\tcase 2: goto level2;\n\t\t\tcase 1: goto level1;\n\t\t\tcase 0: goto level0;\n\t\t\t}\n\n\t\t\t// first try using WAVEFORMATEXTENSIBLE\n\t\t\thr = TVPPrimaryBuffer->SetFormat((const WAVEFORMATEX*)&wfx);\n\n\t\t\tif(FAILED(hr))\n\t\t\t{\n\t\tlevel2:\n\t\t\t\t// second try using WAVEFORMATEX\n\t\t\t\twfx.Format.cbSize = 0;\n\t\t\t\twfx.Format.wFormatTag =\n\t\t\t\t\tTVPPrimaryFloat ? WAVE_FORMAT_IEEE_FLOAT :\n\t\t\t\t\t\tWAVE_FORMAT_PCM;\n\t\t\t\twfx.Format.nBlockAlign = (WORD)(wfx.Format.wBitsPerSample/8 * wfx.Format.nChannels);\n\t\t\t\twfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;\n\t\t\t\thr = TVPPrimaryBuffer->SetFormat((const WAVEFORMATEX*)&wfx);\n\t\t\t}\n\n\t\t\tif(FAILED(hr))\n\t\t\t{\n\t\tlevel1:\n\t\t\t\t// third try using 16bit pcm\n\t\t\t\twfx.Format.cbSize = 0;\n\t\t\t\twfx.Format.wBitsPerSample = 16;\n\t\t\t\twfx.Samples.wValidBitsPerSample = 16;\n\t\t\t\twfx.Format.wFormatTag = WAVE_FORMAT_PCM;\n\t\t\t\twfx.Format.nBlockAlign = (WORD)(wfx.Format.wBitsPerSample/8 * wfx.Format.nChannels);\n\t\t\t\twfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;\n\t\t\t\thr = TVPPrimaryBuffer->SetFormat((const WAVEFORMATEX*)&wfx);\n\t\t\t}\n\n\t\t\tif(FAILED(hr))\n\t\t\t{\n\t\t\t\t// specified parameter is denied\n\t\t\t\tTVPAddImportantLog(ttstr(TJS_W(\"Warning: IDirectSoundBuffer::SetFormat failed. \")\n\t\t\t\t\t\tTJS_W(\"(\") + ttstr(TVPPriamrySBFrequency) + TJS_W(\"Hz, \") +\n\t\t\t\t\t\tttstr(TVPPrimarySBBits) + TJS_W(\"bits, \") +\n\t\t\t\t\t\tttstr((tjs_int)wfx.Format.nChannels) + TJS_W(\"channels)/HR=\"))+\n\t\t\t\t\t\tTJSInt32ToHex((tjs_uint32)hr));\n\t\t\t\tTVPAddImportantLog(TJS_W(\"Retrying with 44100Hz, \")\n\t\t\t\t\t\tTJS_W(\"16bits, 2channels\"));\n\n\t\tlevel0:\n\t\t\t\t// fourth very basic buffer format\n\t\t\t\tWAVEFORMATEX wfx;\n\t\t\t\twfx.cbSize = 0;\n\t\t\t\twfx.wFormatTag = WAVE_FORMAT_PCM;\n\t\t\t\twfx.nChannels = 2;\n\t\t\t\twfx.nSamplesPerSec = 44100;\n\t\t\t\twfx.wBitsPerSample = 16;\n\t\t\t\twfx.nBlockAlign = (WORD)(wfx.wBitsPerSample/8*wfx.nChannels);\n\t\t\t\twfx.nAvgBytesPerSec = wfx.nSamplesPerSec*wfx.nBlockAlign;\n\t\t\t\tTVPPrimaryBuffer->SetFormat(&wfx); // here does not check errors\n\t\t\t}\n\n\n\t\t\thr = TVPPrimaryBuffer->GetFormat((WAVEFORMATEX*)&wfx, sizeof(WAVEFORMATEX), NULL);\n\t\t\tif(FAILED(hr))\n\t\t\t\thr = TVPPrimaryBuffer->GetFormat((WAVEFORMATEX*)&wfx, sizeof(WAVEFORMATEXTENSIBLE), NULL);\n\n\t\t\tif(SUCCEEDED(hr))\n\t\t\t{\n\t\t\t\tttstr debuglog(TJS_W(\"(info) Accepted DirectSound primary buffer format : \"));\n\t\t\t\tdebuglog += TVPGetSoundBufferFormatString(wfx);\n\t\t\t\tTVPAddImportantLog(debuglog);\n\t\t\t}\n\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(TVPPrimaryBuffer) TVPPrimaryBuffer->Release(), TVPPrimaryBuffer = NULL;\n\t\tif(TVPDirectSound3DListener) TVPDirectSound3DListener->Release(), TVPDirectSound3DListener = NULL;\n\t\tif(TVPDirectSound) TVPDirectSound->Release(), TVPDirectSound = NULL;\n\t\tif(TVPDirectSoundDLL) FreeLibrary(TVPDirectSoundDLL), TVPDirectSoundDLL = NULL;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPUninitDirectSound()\n{\n\t// release all objects except for secondary buffers.\n\tif(TVPPrimaryBuffer) TVPPrimaryBuffer->Release(), TVPPrimaryBuffer = NULL;\n\tif(TVPDirectSound3DListener) TVPDirectSound3DListener->Release(), TVPDirectSound3DListener = NULL;\n\tif(TVPDirectSound) TVPDirectSound->Release(), TVPDirectSound = NULL;\n\tif(TVPDirectSoundDLL) FreeLibrary(TVPDirectSoundDLL), TVPDirectSoundDLL = NULL;\n}\nstatic void TVPUninitDirectSoundAtExitProc()\n{\n\tTVPUninitDirectSound();\n\tif( TVPPrimaryDelayedStopperTimer ) delete TVPPrimaryDelayedStopperTimer, TVPPrimaryDelayedStopperTimer = NULL;\n\tTVPDirectSoundShutdown = true;\n}\nstatic tTVPAtExit TVPUninitDirectSoundAtExit\n\t(TVP_ATEXIT_PRI_RELEASE, TVPUninitDirectSoundAtExitProc);\n//---------------------------------------------------------------------------\nIDirectSound * TVPGetDirectSound()\n{\n\ttry\n\t{\n\t\tTVPInitDirectSound();\n\t}\n\tcatch(...)\n\t{\n\t\treturn NULL;\n\t}\n\tif(TVPDirectSound) TVPDirectSound->AddRef();\n\treturn TVPDirectSound; // note that returned TVPDirectSound is AddRefed\n}\n//---------------------------------------------------------------------------\nvoid TVPWaveSoundBufferCommitSettings()\n{\n\t// commit all defered sound buffer settings\n\tif(TVPDeferedSettingAvailable)\n\t{\n\t\tif(TVPDirectSound3DListener)\n\t\t\tTVPDirectSound3DListener->CommitDeferredSettings();\n\t\tTVPDeferedSettingAvailable = false;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Format related functions\n//---------------------------------------------------------------------------\nstatic void TVPWaveFormatToWAVEFORMATEXTENSIBLE(const tTVPWaveFormat *in,\n\tWAVEFORMATEXTENSIBLE *out, bool use3d)\n{\n\t// convert tTVPWaveFormat structure to WAVEFORMATEXTENSIBLE structure.\n\n\tZeroMemory(out, sizeof(WAVEFORMATEXTENSIBLE));\n\tout->Format.nChannels = in->Channels;\n\tout->Format.nSamplesPerSec = in->SamplesPerSec;\n\tout->Format.wBitsPerSample = in->BytesPerSample * 8;\n\tout->Samples.wValidBitsPerSample = out->Format.wBitsPerSample;\n\n\tbool fraction_found = in->BitsPerSample != in->BytesPerSample * 8;\n\n\tconst WORD cbextsize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);\n\n\tif(in->SpeakerConfig == 0)\n\t{\n\t\tif(in->Channels == 1)\n\t\t{\n\t\t\t// mono\n\t\t\tif(TVPExpandToQuad && !use3d)\n\t\t\t{\n\t\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\t\tout->Format.cbSize = cbextsize;\n\t\t\t\tout->dwChannelMask =\n\t\t\t\t\tSPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT |\n\t\t\t\t\tSPEAKER_BACK_RIGHT;\n\t\t\t\tout->Format.nChannels = 4;\n\t\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(in->BytesPerSample >= 3 || fraction_found)\n\t\t\t\t{\n\t\t\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\t\t\tout->Format.cbSize = cbextsize;\n\t\t\t\t\tout->dwChannelMask = KSAUDIO_SPEAKER_MONO;\n\t\t\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tout->Format.wFormatTag =\n\t\t\t\t\t\tin->IsFloat ? WAVE_FORMAT_IEEE_FLOAT:WAVE_FORMAT_PCM;\n\t\t\t\t\tout->Format.cbSize = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(in->Channels == 2)\n\t\t{\n\t\t\t// stereo\n\t\t\tif(TVPExpandToQuad)\n\t\t\t{\n\t\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\t\tout->Format.cbSize = cbextsize;\n\t\t\t\tout->dwChannelMask =\n\t\t\t\t\tSPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT |\n\t\t\t\t\tSPEAKER_BACK_RIGHT;\n\t\t\t\tout->Format.nChannels = 4;\n\t\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(in->BytesPerSample >= 3 || fraction_found)\n\t\t\t\t{\n\t\t\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\t\t\tout->Format.cbSize = cbextsize;\n\t\t\t\t\tout->dwChannelMask = KSAUDIO_SPEAKER_STEREO;\n\t\t\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tout->Format.wFormatTag =\n\t\t\t\t\t\tin->IsFloat ? WAVE_FORMAT_IEEE_FLOAT:WAVE_FORMAT_PCM;\n\t\t\t\t\tout->Format.cbSize = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(in->Channels == 4)\n\t\t{\n\t\t\t// assumed as FL, FR, BL, BR\n\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\tout->Format.cbSize = cbextsize;\n\t\t\tout->dwChannelMask =\n\t\t\t\tSPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT |\n\t\t\t\tSPEAKER_BACK_RIGHT;\n\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t}\n\t\telse if(in->Channels == 6)\n\t\t{\n\t\t\t// assumed as 5 point 1\n\t\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\t\tout->Format.cbSize = cbextsize;\n\t\t\tout->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;\n\t\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthrow ttstr(TJS_W(\"Unsupported channel count : \"))+\n\t\t\t\tttstr((tjs_int)(in->Channels));\n\t\t}\n\t}\n\telse\n\t{\n\t\tout->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n\t\tout->Format.cbSize = cbextsize;\n\t\tout->dwChannelMask = in->SpeakerConfig;\n\t\tout->Samples.wValidBitsPerSample = in->BitsPerSample;\n\t}\n\n\tmemcpy(&out->SubFormat, in->IsFloat ?\n\t\tTVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT:TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16);\n\n\tout->Format.nBlockAlign =\n\t\tout->Format.wBitsPerSample * out->Format.nChannels / 8;\n\tout->Format.nAvgBytesPerSec =\n\t\tout->Format.nSamplesPerSec * out->Format.nBlockAlign;\n}\n//---------------------------------------------------------------------------\nstatic void TVPWaveFormatToWAVEFORMATEXTENSIBLE2(const tTVPWaveFormat *in,\n\tWAVEFORMATEXTENSIBLE *out, bool use3d)\n{\n\t// suggest 2nd expression of WAVEFORMATEXTENSIBLE.\n\tTVPWaveFormatToWAVEFORMATEXTENSIBLE(in, out, use3d);\n\n\tbool fraction_found = in->BitsPerSample != in->BytesPerSample * 8;\n\n\tif(in->SpeakerConfig == 0)\n\t{\n\t\tif(in->Channels == 1)\n\t\t{\n\t\t\t// mono\n\t\t\tout->Format.nChannels = 1;\n\t\t\tif(in->BytesPerSample >= 3 && !fraction_found)\n\t\t\t{\n\t\t\t\tout->Format.wFormatTag =\n\t\t\t\t\tin->IsFloat ? WAVE_FORMAT_IEEE_FLOAT:WAVE_FORMAT_PCM;\n\t\t\t\tout->Format.cbSize = 0;\n\t\t\t}\n\t\t}\n\t\telse if(in->Channels == 2)\n\t\t{\n\t\t\t// stereo\n\t\t\tout->Format.nChannels = 2;\n\t\t\tif(in->BytesPerSample >= 3 && !fraction_found)\n\t\t\t{\n\t\t\t\tout->Format.wFormatTag =\n\t\t\t\t\tin->IsFloat ? WAVE_FORMAT_IEEE_FLOAT:WAVE_FORMAT_PCM;\n\t\t\t\tout->Format.cbSize = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tout->Format.nBlockAlign =\n\t\tout->Format.wBitsPerSample * out->Format.nChannels / 8;\n\tout->Format.nAvgBytesPerSec =\n\t\tout->Format.nSamplesPerSec * out->Format.nBlockAlign;\n}\n//---------------------------------------------------------------------------\nstatic void TVPWaveFormatToWAVEFORMATEXTENSIBLE16bits(const tTVPWaveFormat *in,\n\tWAVEFORMATEXTENSIBLE *out, bool use3d)\n{\n\t// suggest 16bit output format.\n\tTVPWaveFormatToWAVEFORMATEXTENSIBLE(in, out, use3d);\n\n\tout->Format.wBitsPerSample = 16;\n\tout->Samples.wValidBitsPerSample = 16;\n\n\tif(out->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)\n\t{\n\t\tmemcpy(&out->SubFormat, TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16);\n\t}\n\telse\n\t{\n\t\tout->Format.wFormatTag = WAVE_FORMAT_PCM;\n\t}\n\n\tout->Format.nBlockAlign =\n\t\tout->Format.wBitsPerSample * out->Format.nChannels / 8;\n\tout->Format.nAvgBytesPerSec =\n\t\tout->Format.nSamplesPerSec * out->Format.nBlockAlign;\n}\n//---------------------------------------------------------------------------\nstatic void TVPWaveFormatToWAVEFORMATEXTENSIBLE16bitsMono(const tTVPWaveFormat *in,\n\tWAVEFORMATEXTENSIBLE *out, bool use3d)\n{\n\t// suggest 16bit output format.\n\tTVPWaveFormatToWAVEFORMATEXTENSIBLE(in, out, use3d);\n\n\tout->Format.wBitsPerSample = 16;\n\tout->Samples.wValidBitsPerSample = 16;\n\tout->Format.nChannels = 1;\n\tmemcpy(&out->SubFormat, TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16);\n\tout->Format.wFormatTag = WAVE_FORMAT_PCM;\n\tout->Format.cbSize = 0;\n\n\tout->Format.nBlockAlign =\n\t\tout->Format.wBitsPerSample * out->Format.nChannels / 8;\n\tout->Format.nAvgBytesPerSec =\n\t\tout->Format.nSamplesPerSec * out->Format.nBlockAlign;\n}\n//---------------------------------------------------------------------------\n#pragma pack(push, 1)\nstatic void TVPConvertWaveFormatToDestinationFormat(void *dest, const void *src,\n\ttjs_int count, const WAVEFORMATEXTENSIBLE *df, const  tTVPWaveFormat*sf)\n{\n\t// convert PCM format descripted in \"sf\" to the destination format \"df\"\n\n\t// check whether to convert to 16bit integer\n\tbool convert_to_16 = false;\n\tif(df->Format.wBitsPerSample == 16)\n\t{\n\t\tif(df->Format.wFormatTag == WAVE_FORMAT_PCM)\n\t\t{\n\t\t\tconvert_to_16 = true;\n\t\t}\n\t\telse if(df->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)\n\t\t{\n\t\t\tif(!memcmp(&df->SubFormat, TVP_GUID_KSDATAFORMAT_SUBTYPE_PCM, 16))\n\t\t\t\tconvert_to_16 = true;\n\t\t}\n\t}\n\n\tif(convert_to_16)\n\t{\n\t\t// convert to 16bit sample\n\t\tif(df->Format.nChannels == 1 && sf->Channels != 1)\n\t\t\tTVPConvertPCMTo16bits((tjs_int16*)dest, src, *sf, count, true);\n\t\telse\n\t\t\tTVPConvertPCMTo16bits((tjs_int16*)dest, src, *sf, count, false);\n\t}\n\telse\n\t{\n\t\t// intact copy\n\t\tmemcpy(dest, src, count * sf->BytesPerSample * sf->Channels);\n\t}\n\n\n\tstruct type_24bit { tjs_uint8 data[3]; };\n\n\t#define PROCESS_BY_SAMPLESIZE \\\n\t\tif(df->Format.wBitsPerSample == 8) \\\n\t\t{ \\\n\t\t\ttypedef tjs_int8 type; \\\n\t\t\tPROCESS; \\\n\t\t} \\\n\t\telse if(df->Format.wBitsPerSample == 16) \\\n\t\t{ \\\n\t\t\ttypedef tjs_int16 type; \\\n\t\t\tPROCESS;\\\n\t\t} \\\n\t\telse if(df->Format.wBitsPerSample == 24) \\\n\t\t{ \\\n\t\t\ttypedef type_24bit type; \\\n\t\t\tPROCESS; \\\n\t\t} \\\n\t\telse if(df->Format.wBitsPerSample == 32) \\\n\t\t{ \\\n\t\t\ttypedef tjs_int32 type; \\\n\t\t\tPROCESS; \\\n\t\t} \\\n\n\tif(df->Format.nChannels == 4 && sf->Channels == 1)\n\t{\n\t\t// expand mono to quadphone\n\t\t#define PROCESS \\\n\t\t\ttype *ps = (type *)dest + (count-1); \\\n\t\t\ttype *pd = (type *)dest + (count-1) * 4; \\\n\t\t\tfor(tjs_int i = 0; i < count; i++) \\\n\t\t\t{ \\\n\t\t\t\tpd[0] = pd[1] = pd[2] = pd[3] = ps[0]; \\\n\t\t\t\tpd -= 4; \\\n\t\t\t\tps -= 1; \\\n\t\t\t}\n\n\t\tPROCESS_BY_SAMPLESIZE\n\n\t\t#undef PROCESS\n\t}\n\n\tif(df->Format.nChannels == 4 && sf->Channels == 2)\n\t{\n\t\t// expand stereo to quadphone\n\t\t#define PROCESS \\\n\t\t\ttype *ps = (type *)dest + (count-1) * 2; \\\n\t\t\ttype *pd = (type *)dest + (count-1) * 4; \\\n\t\t\tfor(tjs_int i = 0; i < count; i++) \\\n\t\t\t{ \\\n\t\t\t\tpd[0] = pd[2] = ps[0]; \\\n\t\t\t\tpd[1] = pd[3] = ps[1]; \\\n\t\t\t\tpd -= 4; \\\n\t\t\t\tps -= 2; \\\n\t\t\t}\n\n\t\tPROCESS_BY_SAMPLESIZE\n\n\t\t#undef PROCESS\n\t}\n\n\tif(sf->SpeakerConfig == 0 && sf->Channels == 6 && df->Format.nChannels == 6)\n\t{\n\t\t// if the \"channels\" is 6 and speaker configuration is not specified,\n\t\t// input data is assumued that the order is :\n\t\t// FL FC FR BL BR LF\n\t\t// is to be reordered as :\n\t\t// FL FR FC LF BL BR (which WAVEFORMATEXTENSIBLE expects)\n\n\t\t#define PROCESS \\\n\t\t\ttype *op = (type *)dest; \\\n\t\t\tfor(tjs_int i = 0; i < count; i++) \\\n\t\t\t{ \\\n\t\t\t\ttype fc = op[1]; \\\n\t\t\t\ttype bl = op[3]; \\\n\t\t\t\ttype br = op[4]; \\\n\t\t\t\top[1] = op[2]; \\\n\t\t\t\top[2] = fc; \\\n\t\t\t\top[3] = op[5]; \\\n\t\t\t\top[4] = bl; \\\n\t\t\t\top[5] = br; \\\n\t\t\t\top += 6; \\\n\t\t\t}\n\n\t\tPROCESS_BY_SAMPLESIZE\n\n\n\t\t#undef PROCESS\n\t}\n}\n#pragma pack(pop)\n//---------------------------------------------------------------------------\nstatic void TVPMakeSilentWaveBytes(void *dest, tjs_int bytes, const tTVPWaveFormat *format)\n{\n\tif(format->Format.wBitsPerSample == 8)\n\t{\n\t\t// 0x80\n\t\tmemset(dest, 0x80, bytes);\n\t}\n\telse\n\t{\n\t\t// 0x00\n\t\tmemset(dest, 0x00, bytes);\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nstatic void TVPMakeSilentWave(void *dest, tjs_int count, const tTVPWaveFormat *format)\n{\n\ttjs_int bytes = count * format->Channels * format->BytesPerSample;\n\tmemset(dest, 0x00, bytes);\n\t//TVPMakeSilentWaveBytes(dest, bytes, format);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Buffer management\n//---------------------------------------------------------------------------\nstd::vector<tTJSNI_WaveSoundBuffer *> &TVPWaveSoundBufferVector = *(new std::vector<tTJSNI_WaveSoundBuffer *>); // to avoid release order in shutdown\ntTJSCriticalSection TVPWaveSoundBufferVectorCS;\n\n//---------------------------------------------------------------------------\n// tTVPWaveSoundBufferThread : playing thread\n//---------------------------------------------------------------------------\n/*\n\tThe system has one playing thread.\n\tThe playing thread fills each sound buffer's L1 (DirectSound) buffer, and\n\talso manages timing for label events.\n\tThe technique used in this algorithm is similar to Timer claass implementation.\n*/\nclass tTVPWaveSoundBufferThread : public tTVPThread\n{\n\ttTVPThreadEvent Event;\n\n\t//HWND UtilWindow; // utility window to notify the pending events occur\n\tbool PendingLabelEventExists;\n\tbool WndProcToBeCalled;\n\tDWORD NextLabelEventTick;\n\tDWORD LastFilledTick;\n\n\tNativeEventQueue<tTVPWaveSoundBufferThread> EventQueue;\npublic:\n\ttTVPWaveSoundBufferThread();\n\t~tTVPWaveSoundBufferThread();\n\nprivate:\n\t//void __fastcall UtilWndProc(Messages::TMessage &Msg);\n\tvoid UtilWndProc( NativeEvent& ev );\n\npublic:\n\tvoid ReschedulePendingLabelEvent(tjs_int tick);\n\nprotected:\n\tvoid Execute(void);\n\npublic:\n\tvoid Start(void);\n\tvoid CheckBufferSleep();\n} static *TVPWaveSoundBufferThread = NULL;\n//---------------------------------------------------------------------------\nvoid TVPLockSoundMixer() {\n\tTVPPrimaryBufferPlayingByProgram = false;\n}\nvoid TVPUnlockSoundMixer() {\n\tif (TVPWaveSoundBufferThread) TVPEnsurePrimaryBufferPlay();\n}\n//---------------------------------------------------------------------------\ntTVPWaveSoundBufferThread::tTVPWaveSoundBufferThread()\n\t: tTVPThread(true), EventQueue(this,&tTVPWaveSoundBufferThread::UtilWndProc)\n{\n\tEventQueue.Allocate();\n\tPendingLabelEventExists = false;\n\tNextLabelEventTick = 0;\n\tLastFilledTick = 0;\n\tWndProcToBeCalled = false;\n\tSetPriority(ttpHighest);\n\tResume();\n}\n//---------------------------------------------------------------------------\ntTVPWaveSoundBufferThread::~tTVPWaveSoundBufferThread()\n{\n\tSetPriority(ttpNormal);\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n\tEventQueue.Deallocate();\n}\n//---------------------------------------------------------------------------\n//void __fastcall tTVPWaveSoundBufferThread::UtilWndProc(Messages::TMessage &Msg)\nvoid tTVPWaveSoundBufferThread::UtilWndProc( NativeEvent& ev )\n{\n\t// Window procedure of UtilWindow\n\tif( ev.Message == TVP_EV_WAVE_SND_BUF_THREAD && !GetTerminated())\n\t{\n\t\t// pending events occur\n\t\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS); // protect the object\n\n\t\tWndProcToBeCalled = false;\n\n\t\ttjs_int64 tick = TVPGetTickCount();\n\n\t\tint nearest_next = TVP_TIMEOFS_INVALID_VALUE;\n\n\t\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\t\tfor(i = TVPWaveSoundBufferVector.begin();\n\t\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t\t{\n\t\t\tint next = (*i)->FireLabelEventsAndGetNearestLabelEventStep(tick);\n\t\t\t\t// fire label events and get nearest label event step\n\t\t\tif(next != TVP_TIMEOFS_INVALID_VALUE)\n\t\t\t{\n\t\t\t\tif(nearest_next == TVP_TIMEOFS_INVALID_VALUE || nearest_next > next)\n\t\t\t\t\tnearest_next = next;\n\t\t\t}\n\t\t}\n\n\t\tif(nearest_next != TVP_TIMEOFS_INVALID_VALUE)\n\t\t{\n\t\t\tPendingLabelEventExists = true;\n\t\t\tNextLabelEventTick = TVPGetRoughTickCount32() + nearest_next;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tPendingLabelEventExists = false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tEventQueue.HandlerDefault(ev);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveSoundBufferThread::ReschedulePendingLabelEvent(tjs_int tick)\n{\n\tif(tick == TVP_TIMEOFS_INVALID_VALUE) return; // no need to reschedule\n\tDWORD eventtick = TVPGetRoughTickCount32() + tick;\n\n\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\n\tif(PendingLabelEventExists)\n\t{\n\t\tif((tjs_int32)NextLabelEventTick - (tjs_int32)eventtick > 0)\n\t\t\tNextLabelEventTick = eventtick;\n\t}\n\telse\n\t{\n\t\tPendingLabelEventExists = true;\n\t\tNextLabelEventTick = eventtick;\n\t}\n}\n//---------------------------------------------------------------------------\n#define TVP_WSB_THREAD_SLEEP_TIME 60\nvoid tTVPWaveSoundBufferThread::Execute(void)\n{\n\twhile(!GetTerminated())\n\t{\n\t\t// thread loop for playing thread\n\t\tDWORD time = TVPGetRoughTickCount32();\n\t\tTVPPushEnvironNoise(&time, sizeof(time));\n\n\t\t{\t// thread-protected\n\t\t\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\n\t\t\tif (TVPPrimaryBufferPlayingByProgram != TVPPrimarySoundBufferPlaying) {\n\t\t\t\tTVPPrimarySoundBufferPlaying = TVPPrimaryBufferPlayingByProgram;\n\t\t\t\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\t\t\t\tfor (i = TVPWaveSoundBufferVector.begin();\n\t\t\t\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t\t\t\t{\n\t\t\t\t\tif ((*i)->ThreadCallbackEnabled)\n\t\t\t\t\t\t(*i)->SetBufferPaused(!TVPPrimaryBufferPlayingByProgram); // for preventing buffer runs out on iOS' OpenAL implement\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// check PendingLabelEventExists\n\t\t\tif(PendingLabelEventExists)\n\t\t\t{\n\t\t\t\tif(!WndProcToBeCalled)\n\t\t\t\t{\n\t\t\t\t\tWndProcToBeCalled = true;\n\t\t\t\t\tEventQueue.PostEvent( NativeEvent(TVP_EV_WAVE_SND_BUF_THREAD) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (TVPPrimarySoundBufferPlaying && time - LastFilledTick >= TVP_WSB_THREAD_SLEEP_TIME)\n\t\t\t{\n\t\t\t\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\t\t\t\tfor(i = TVPWaveSoundBufferVector.begin();\n\t\t\t\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t\t\t\t{\n\t\t\t\t\tif((*i)->ThreadCallbackEnabled)\n\t\t\t\t\t\t(*i)->FillBuffer(); // fill sound buffer\n\t\t\t\t}\n\t\t\t\tLastFilledTick = time;\n\t\t\t}\n\t\t}\t// end-of-thread-protected\n\n\t\tDWORD time2;\n\t\ttime2 = TVPGetRoughTickCount32();\n\t\ttime = time2 - time;\n\n\t\tif(time < TVP_WSB_THREAD_SLEEP_TIME)\n\t\t{\n\t\t\ttjs_int sleep_time = TVP_WSB_THREAD_SLEEP_TIME - time;\n\t\t\tif(PendingLabelEventExists)\n\t\t\t{\n\t\t\t\ttjs_int step_to_next = (tjs_int32)NextLabelEventTick - (tjs_int32)time2;\n\t\t\t\tif(step_to_next < sleep_time)\n\t\t\t\t\tsleep_time = step_to_next;\n\t\t\t\tif(sleep_time < 1) sleep_time = 1;\n\t\t\t}\n\t\t\tEvent.WaitFor(sleep_time);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tEvent.WaitFor(1);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveSoundBufferThread::Start()\n{\n\tTVPPrimaryBufferPlayingByProgram = true;\n\tEvent.Set();\n\tResume();\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveSoundBufferThread::CheckBufferSleep()\n{\n#if 0\n\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\ttjs_uint size, nonwork_count;\n\tnonwork_count = 0;\n\tsize = (tjs_uint)TVPWaveSoundBufferVector.size();\n\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\tfor(i = TVPWaveSoundBufferVector.begin();\n\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t{\n\t\tif(!(*i)->ThreadCallbackEnabled)\n\t\t\tnonwork_count ++;\n\t}\n\tif(nonwork_count == size)\n\t{\n\t\tSuspend(); // all buffers are sleeping...\n\t\tTVPStopPrimaryBuffer();\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic void TVPReleaseSoundBuffers(bool disableevent = true)\n{\n\t// release all secondary buffers.\n\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\tfor(i = TVPWaveSoundBufferVector.begin();\n\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t{\n\t\t(*i)->FreeDirectSoundBuffer(disableevent);\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPShutdownWaveSoundBuffers()\n{\n\t// clean up soundbuffers at exit\n\tif(TVPWaveSoundBufferThread)\n\t\tdelete TVPWaveSoundBufferThread, TVPWaveSoundBufferThread = NULL;\n\tTVPReleaseSoundBuffers();\n}\nstatic tTVPAtExit TVPShutdownWaveSoundBuffersAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPShutdownWaveSoundBuffers);\n//---------------------------------------------------------------------------\nstatic void TVPEnsureWaveSoundBufferWorking()\n{\n\tif(!TVPWaveSoundBufferThread)\n\t\tTVPWaveSoundBufferThread = new tTVPWaveSoundBufferThread();\n\tTVPWaveSoundBufferThread->Start();\n}\n//---------------------------------------------------------------------------\nstatic void TVPCheckSoundBufferAllSleep()\n{\n\tif(TVPWaveSoundBufferThread)\n\t\tTVPWaveSoundBufferThread->CheckBufferSleep();\n}\n//---------------------------------------------------------------------------\nstatic void TVPAddWaveSoundBuffer(tTJSNI_WaveSoundBuffer * buffer)\n{\n\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\tTVPWaveSoundBufferVector.push_back(buffer);\n}\n//---------------------------------------------------------------------------\nstatic void TVPRemoveWaveSoundBuffer(tTJSNI_WaveSoundBuffer * buffer)\n{\n\tbool bufferempty;\n\n\t{\n\t\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\t\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\t\ti = std::find(TVPWaveSoundBufferVector.begin(),\n\t\t\tTVPWaveSoundBufferVector.end(),\n\t\t\tbuffer);\n\t\tif(i != TVPWaveSoundBufferVector.end())\n\t\t\tTVPWaveSoundBufferVector.erase(i);\n\t\tbufferempty = TVPWaveSoundBufferVector.size() == 0;\n\t}\n\n\tif(bufferempty)\n\t{\n\t\tif(TVPWaveSoundBufferThread)\n\t\t\tdelete TVPWaveSoundBufferThread, TVPWaveSoundBufferThread = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPReschedulePendingLabelEvent(tjs_int tick)\n{\n\tif(TVPWaveSoundBufferThread)\n\t\tTVPWaveSoundBufferThread->ReschedulePendingLabelEvent(tick);\n}\n//---------------------------------------------------------------------------\nvoid TVPResetVolumeToAllSoundBuffer()\n{\n\t// call each SoundBuffer's SetVolumeToSoundBuffer\n\ttTJSCriticalSectionHolder holder(TVPWaveSoundBufferVectorCS);\n\tstd::vector<tTJSNI_WaveSoundBuffer *>::iterator i;\n\tfor(i = TVPWaveSoundBufferVector.begin();\n\t\ti != TVPWaveSoundBufferVector.end(); i++)\n\t{\n\t\t(*i)->SetVolumeToSoundBuffer();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPReleaseDirectSound()\n{\n\tTVPReleaseSoundBuffers(false);\n\tTVPUninitDirectSound();\n}\n//---------------------------------------------------------------------------\nvoid TVPSetWaveSoundBufferUse3DMode(bool b)\n{\n\t// changing the 3D mode will stop all the buffers.\n\tif(b != TVPDirectSoundUse3D)\n\t{\n\t\tTVPReleaseDirectSound();\n\t\tTVPDirectSoundUse3D = b;\n\t}\n}\n//---------------------------------------------------------------------------\nbool TVPGetWaveSoundBufferUse3DMode()\n{\n\treturn TVPDirectSoundUse3D;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWaveSoundBufferDcodeThread : decoding thread\n//---------------------------------------------------------------------------\nclass tTVPWaveSoundBufferDecodeThread : public tTVPThread\n{\n\ttTJSNI_WaveSoundBuffer * Owner;\n\ttTVPThreadEvent Event;\n\ttTJSCriticalSection OneLoopCS;\n\tvolatile bool Running;\n\npublic:\n\ttTVPWaveSoundBufferDecodeThread(tTJSNI_WaveSoundBuffer * owner);\n\t~tTVPWaveSoundBufferDecodeThread();\n\n\tvoid Execute(void);\n\n\tvoid Interrupt();\n\tvoid Continue();\n\n\tbool GetRunning() const { return Running; }\n};\n//---------------------------------------------------------------------------\ntTVPWaveSoundBufferDecodeThread::tTVPWaveSoundBufferDecodeThread(\n\ttTJSNI_WaveSoundBuffer * owner)\n\t: tTVPThread(true)\n{\n\tTVPInitSoundOptions();\n\n\tOwner = owner;\n\tSetPriority(TVPDecodeThreadHighPriority);\n\tRunning = false;\n\tResume();\n}\n//---------------------------------------------------------------------------\ntTVPWaveSoundBufferDecodeThread::~tTVPWaveSoundBufferDecodeThread()\n{\n\tSetPriority(TVPDecodeThreadHighPriority);\n\tRunning = false;\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n}\n//---------------------------------------------------------------------------\n#define TVP_WSB_DECODE_THREAD_SLEEP_TIME 110\nvoid tTVPWaveSoundBufferDecodeThread::Execute(void)\n{\n\twhile(!GetTerminated())\n\t{\n\t\t// decoder thread main loop\n\t\tDWORD st = TVPGetTickCount();\n\t\twhile(Running)\n\t\t{\n\t\t\tbool wait;\n\t\t\tDWORD et;\n\n\t\t\tif(Running)\n\t\t\t{\n\t\t\t\tvolatile tTJSCriticalSectionHolder cs_holder(OneLoopCS);\n\t\t\t\twait = !Owner->FillL2Buffer(false, true); // fill\n\t\t\t}\n\n\t\t\tif(GetTerminated()) break;\n\n\t\t\tif(Running)\n\t\t\t{\n\t\t\t\tet = TVPGetTickCount();\n\t\t\t\tTVPPushEnvironNoise(&et, sizeof(et));\n\t\t\t\tif(wait)\n\t\t\t\t{\n\t\t\t\t\t// buffer is full; sleep longer\n\t\t\t\t\tDWORD elapsed = et -st;\n\t\t\t\t\tif(elapsed < TVP_WSB_DECODE_THREAD_SLEEP_TIME)\n\t\t\t\t\t{\n\t\t\t\t\t\tEvent.WaitFor(\n\t\t\t\t\t\t\tTVP_WSB_DECODE_THREAD_SLEEP_TIME - elapsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// buffer is not full; sleep shorter\n\t\t\t\t\tTVPRelinquishCPU();\n\t\t\t\t\tif(!GetTerminated()) SetPriority(TVPDecodeThreadLowPriority);\n\t\t\t\t}\n\t\t\t\tst = et;\n\t\t\t}\n\t\t}\n\t\tif(GetTerminated()) break;\n\t\t// sleep while running\n\t\tEvent.WaitFor(/*INFINITE*/0);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveSoundBufferDecodeThread::Interrupt()\n{\n\t// interrupt the thread\n\tif(!Running) return;\n\tSetPriority(TVPDecodeThreadHighPriority);\n\tEvent.Set();\n\ttTJSCriticalSectionHolder cs_holder(OneLoopCS);\n\t\t// this ensures that this function stops the decoding\n\tRunning = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPWaveSoundBufferDecodeThread::Continue()\n{\n\tSetPriority(TVPDecodeThreadHighPriority);\n\tRunning = true;\n\tEvent.Set();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_WaveSoundBuffer\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_WaveSoundBuffer::GlobalVolume = 100000;\ntTVPSoundGlobalFocusMode tTJSNI_WaveSoundBuffer::GlobalFocusMode = sgfmNeverMute;\n//---------------------------------------------------------------------------\ntTJSNI_WaveSoundBuffer::tTJSNI_WaveSoundBuffer()\n{\n\tTVPInitSoundOptions();\n//\tTVPRegisterTSSWaveDecoderCreator();\n#ifdef TVP_SUPPORT_OLD_WAVEUNPACKER\n\tTVPRegisterWaveUnpackerCreator();\n#endif\n#ifdef TVP_SUPPORT_KPI\n\tTVPRegisterKMPWaveDecoderCreator();\n#endif\n\tTVPInitLogTable();\n\tDecoder = NULL;\n\tLoopManager = NULL;\n\tThread = NULL;\n\tUseVisBuffer = false;\n\tVisBuffer = NULL;\n\tThreadCallbackEnabled = false;\n\tLevel2Buffer = NULL;\n\tLevel2BufferSize = 0;\n\tVolume =  100000;\n\tVolume2 = 100000;\n\tBufferCanControlPan = false;\n\tPan = 0;\n\tPosX = PosY = PosZ = (D3DVALUE)0.0;\n\tSoundBuffer = NULL;\n//\tSound3DBuffer = NULL;\n\tL2BufferDecodedSamplesInUnit = NULL;\n\tL1BufferSegmentQueues = NULL;\n\tL2BufferSegmentQueues = NULL;\n\tL1BufferDecodeSamplePos = NULL;\n\tDecodePos = 0;\n\tL1BufferUnits = 0;\n\tL2BufferUnits = 0;\n\tTVPAddWaveSoundBuffer(this);\n\tThread = new tTVPWaveSoundBufferDecodeThread(this);\n\tmemset(&C_InputFormat, 0, sizeof(C_InputFormat));\n\tmemset(&InputFormat, 0, sizeof(InputFormat));\n\tLooping = false;\n\tDSBufferPlaying = false;\n\tBufferPlaying = false;\n\tPaused = false;\n\tBufferBytes = 0;\n\tAccessUnitBytes = 0;\n\tAccessUnitSamples = 0;\n\tL2AccessUnitBytes = 0;\n\tSoundBufferPrevReadPos = 0;\n\tSoundBufferWritePos = 0;\n\tPlayStopPos = 0;\n\tL2BufferReadPos = 0;\n\tL2BufferWritePos = 0;\n\tL2BufferRemain = 0;\n\tL2BufferEnded = false;\n\tLastCheckedDecodePos = -1;\n\tLastCheckedTick = 0;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_WaveSoundBuffer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_WaveSoundBuffer::Invalidate()\n{\n\tinherited::Invalidate();\n\n\tClear();\n\n\tDestroySoundBuffer();\n\n\tif(Thread) delete Thread, Thread = NULL;\n\n\tTVPRemoveWaveSoundBuffer(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::ThrowSoundBufferException(const ttstr &reason)\n{\n\tTVPThrowExceptionMessage(TVPCannotCreateDSSecondaryBuffer,\n\t\treason, ttstr().printf(TJS_W(\"frequency=%d/channels=%d/bits=%d\"),\n\t\tInputFormat.SamplesPerSec, InputFormat.Channels,\n\t\tInputFormat.BitsPerSample));\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::TryCreateSoundBuffer(bool use3d)\n{\n\t// release previous sound buffer\n\tif(SoundBuffer) SoundBuffer->Release(), SoundBuffer = NULL;\n\n\t// compute buffer bytes\n\tAccessUnitSamples = InputFormat.SamplesPerSec / TVP_WSB_ACCESS_FREQ;\n\tAccessUnitBytes = AccessUnitSamples * InputFormat.Channels * InputFormat.BytesPerSample;\n\n\tL1BufferUnits = TVPAL_BUFFER_COUNT/*TVPL1BufferLength / (1000 / TVP_WSB_ACCESS_FREQ)*/;\n\tif(L1BufferUnits <= 1) L1BufferUnits = 2;\n\tif(L1BufferSegmentQueues) delete [] L1BufferSegmentQueues, L1BufferSegmentQueues = NULL;\n\tL1BufferSegmentQueues = new tTVPWaveSegmentQueue[L1BufferUnits];\n\tLabelEventQueue.clear();\n\tif(L1BufferDecodeSamplePos) delete [] L1BufferDecodeSamplePos, L1BufferDecodeSamplePos = NULL;\n\tL1BufferDecodeSamplePos = new tjs_int64[L1BufferUnits];\n\tBufferBytes = AccessUnitBytes * L1BufferUnits;\n\t\t// l1 buffer bytes\n\n\tif(BufferBytes <= 0)\n\t\tThrowSoundBufferException(TJS_W(\"Invalid format.\"));\n\n\t// allocate visualization buffer\n\tif(UseVisBuffer) ResetVisBuffer();\n\n\t// allocate level2 buffer ( 4sec. buffer )\n\tL2BufferUnits = TVPL2BufferLength / (1000 / TVP_WSB_ACCESS_FREQ);\n\tif(L2BufferUnits <= 1) L2BufferUnits = 2;\n\n\tif(L2BufferDecodedSamplesInUnit) delete [] L2BufferDecodedSamplesInUnit, L2BufferDecodedSamplesInUnit = NULL;\n\tif(L2BufferSegmentQueues) delete [] L2BufferSegmentQueues, L2BufferSegmentQueues = NULL;\n\tL2BufferDecodedSamplesInUnit = new tjs_int[L2BufferUnits];\n\tL2BufferSegmentQueues = new tTVPWaveSegmentQueue[L2BufferUnits];\n\n\tL2AccessUnitBytes = AccessUnitSamples * InputFormat.BytesPerSample * InputFormat.Channels;\n\tLevel2BufferSize = L2AccessUnitBytes * L2BufferUnits;\n\tif(Level2Buffer) delete [] Level2Buffer, Level2Buffer = NULL;\n\tLevel2Buffer = new tjs_uint8[Level2BufferSize];\n\n\tSoundBuffer = TVPCreateSoundBuffer(InputFormat, L1BufferUnits);\n#if 0\n\t// setup parameters\n\tDSBUFFERDESC dsbd;\n\tZeroMemory(&dsbd, sizeof(dsbd));\n\tdsbd.dwSize = sizeof(dsbd);\n\tdsbd.dwFlags = \tDSBCAPS_GETCURRENTPOSITION2 |\n\t\tDSBCAPS_CTRLVOLUME;\n\tBufferCanControlFrequency = true;\n\tif(!(TVPDirectSoundUse3D && use3d))\n\t\tdsbd.dwFlags |= DSBCAPS_CTRLPAN, BufferCanControlPan = true;\n\telse\n\t\tdsbd.dwFlags |= DSBCAPS_CTRL3D, BufferCanControlPan = false;\n\tdsbd.dwFlags |= DSBCAPS_CTRLFREQUENCY;\n\tif(!(TVPSoundGlobalFocusMuteVolume == 0 &&\n\t\tTVPSoundGlobalFocusModeByOption >= sgfmMuteOnDeactivate))\n\t\tdsbd.dwFlags |= DSBCAPS_GLOBALFOCUS;\n\tif(TVPUseSoftwareBuffer)\n\t\tdsbd.dwFlags |= DSBCAPS_LOCSOFTWARE;\n\n\tdsbd.dwBufferBytes = BufferBytes;\n\n\tdsbd.lpwfxFormat = (WAVEFORMATEX*)&Format;\n\n\t// create sound buffer\n\tHRESULT hr;\n\thr = TVPDirectSound->CreateSoundBuffer(&dsbd, &SoundBuffer, NULL);\n\tif(FAILED(hr))\n\t{\n\t\tif(BufferCanControlPan)\n\t\t{\n\t\t\tdsbd.dwFlags &= ~ DSBCAPS_CTRLPAN;\n\t\t\tBufferCanControlPan = false;\n\t\t\thr = TVPDirectSound->CreateSoundBuffer(&dsbd, &SoundBuffer, NULL);\n\t\t}\n\t}\n\n\tif(FAILED(hr))\n\t{\n\t\tif(BufferCanControlFrequency)\n\t\t{\n\t\t\tdsbd.dwFlags &= ~ DSBCAPS_CTRLFREQUENCY;\n\t\t\tBufferCanControlFrequency = false;\n\t\t\thr = TVPDirectSound->CreateSoundBuffer(&dsbd, &SoundBuffer, NULL);\n\t\t}\n\t}\n\n\tif(FAILED(hr)) SoundBuffer = NULL;\n\n\tif((TVPDirectSoundUse3D && use3d) && SUCCEEDED(hr))\n\t{\n\t\t// retrieve DirectSound3DBuffer interface\n\t\thr = SoundBuffer->QueryInterface(IID_IDirectSound3DBuffer,\n\t\t\t(void**)&Sound3DBuffer);\n\t\tif(FAILED(hr)) Sound3DBuffer = NULL;\n\t}\n\n\t// report failure\n\tif(FAILED(hr))\n\t{\n\t\tif(SoundBuffer) SoundBuffer->Release();\n\t\tSoundBuffer = NULL;\n\t\tdelete [] Level2Buffer;\n\t\tLevel2Buffer = NULL;\n\t\tThrowSoundBufferException(\n\t\t\tttstr(TJS_W(\"IDirectSound::CreateSoundBuffer \")\n\t\t\t\tTJS_W(\"(on to create a secondary buffer) failed./HR=\") +\n\t\t\t\tTJSInt32ToHex(hr)));\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::CreateSoundBuffer()\n{\n\t// create a direct sound secondary buffer which has given format.\n\n\tTVPInitDirectSound(); // ensure DirectSound object\n\n\tbool format_is_not_identical = TVPAlwaysRecreateSoundBuffer ||\n\t\tC_InputFormat.SamplesPerSec\t\t!= InputFormat.SamplesPerSec ||\n\t\tC_InputFormat.Channels\t\t\t!= InputFormat.Channels ||\n\t\tC_InputFormat.BitsPerSample\t\t!= InputFormat.BitsPerSample ||\n\t\tC_InputFormat.BytesPerSample\t!= InputFormat.BytesPerSample ||\n\t\tC_InputFormat.SpeakerConfig\t\t!= InputFormat.SpeakerConfig ||\n\t\tC_InputFormat.IsFloat\t\t\t!= InputFormat.IsFloat;\n\n\tif(format_is_not_identical)\n\t{\n\t\ttry\n\t\t{\n\t\t\tttstr msg;\n\t\t\tbool failed;\n\t\t\tbool firstfailed = false;\n\t\t\tttstr firstformat;\n\t\t\tbool use3d = (InputFormat.Channels >= 3 || InputFormat.SpeakerConfig != 0) ?\n\t\t\t\tfalse : TVPDirectSoundUse3D;\n\t\t\t\t// currently DirectSound3D cannot handle multiple speaker configuration\n\t\t\t\t// other than stereo.\n\t\t\tint forcemode = 0;\n\n\t\t\tif(TVPForceConvertMode == fcm16bit) goto try16bits;\n\t\t\tif(TVPForceConvertMode == fcm16bitMono) goto try16bits_mono;\n\n\t\t\tfailed = false;\n\t\t\t//TVPWaveFormatToWAVEFORMATEXTENSIBLE(&InputFormat, &Format, use3d);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tTryCreateSoundBuffer(use3d);\n\t\t\t}\n\t\t\tcatch(eTJSError &e)\n\t\t\t{\n\t\t\t\tfailed = true;\n\t\t\t\tmsg = e.GetMessage();\n\t\t\t}\n\n\n\t\t\tif(failed || !SoundBuffer)\n\t\t\t{\n\t\t\t\tfailed = false;\n\t\t\t\t//TVPWaveFormatToWAVEFORMATEXTENSIBLE2(&InputFormat, &Format, use3d);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tTryCreateSoundBuffer(use3d);\n\t\t\t\t}\n\t\t\t\tcatch(eTJSError &e)\n\t\t\t\t{\n\t\t\t\t\tfirstformat = TVPGetSoundBufferFormatString(InputFormat);\n\t\t\t\t\tfailed = true;\n\t\t\t\t\tfirstfailed = true;\n\t\t\t\t\tmsg = e.GetMessage();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(failed || !SoundBuffer)\n\t\t\t{\n\t\ttry16bits:\n\t\t\t\tfailed = false;\n\t\t\t\t//TVPWaveFormatToWAVEFORMATEXTENSIBLE16bits(&InputFormat, &Format, use3d);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tTryCreateSoundBuffer(use3d);\n\t\t\t\t}\n\t\t\t\tcatch(eTJSError &e)\n\t\t\t\t{\n\t\t\t\t\tfailed = true;\n\t\t\t\t\tmsg = e.GetMessage();\n\t\t\t\t}\n\t\t\t\tif(!failed) forcemode = 1;\n\t\t\t}\n\n\t\t\tif(failed)\n\t\t\t{\n\t\ttry16bits_mono:\n\t\t\t\tfailed = false;\n\t\t\t\t//TVPWaveFormatToWAVEFORMATEXTENSIBLE16bitsMono(&InputFormat, &Format, use3d);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tTryCreateSoundBuffer(use3d);\n\t\t\t\t}\n\t\t\t\tcatch(eTJSError &e)\n\t\t\t\t{\n\t\t\t\t\tfailed = true;\n\t\t\t\t\tmsg = e.GetMessage();\n\t\t\t\t}\n\t\t\t\tif(!failed) forcemode = 2;\n\t\t\t}\n\n\t\t\tif(failed)\n\t\t\t\tTVPThrowExceptionMessage(msg.c_str());\n\n#if 0\n\t\t\t// log\n\t\t\tif(SoundBuffer && firstfailed)\n\t\t\t{\n\t\t\t\tWAVEFORMATEXTENSIBLE wfx;\n\t\t\t\tHRESULT hr = SoundBuffer->GetFormat(\n\t\t\t\t\t(WAVEFORMATEX*)&wfx, sizeof(WAVEFORMATEX), NULL);\n\t\t\t\tif(FAILED(hr))\n\t\t\t\t\thr = SoundBuffer->GetFormat(\n\t\t\t\t\t\t(WAVEFORMATEX*)&wfx, sizeof(WAVEFORMATEXTENSIBLE), NULL);\n\n\t\t\t\tttstr log;\n\t\t\t\tif(!use3d)\n\t\t\t\t\tlog = TJS_W(\"(info) Accepted DirectSound secondary buffer format : \");\n\t\t\t\telse\n\t\t\t\t\tlog = TJS_W(\"(info) Accepted DirectSound3D secondary buffer format : \");\n\t\t\t\tif(SUCCEEDED(hr))\n\t\t\t\t\tlog += TVPGetSoundBufferFormatString(wfx);\n\t\t\t\telse\n\t\t\t\t\tlog += TJS_W(\"unknown format\");\n\t\t\t\tif(firstfailed)\n\t\t\t\t{\n\t\t\t\t\tlog += TJS_W(\" (\") + firstformat +\n\t\t\t\t\t\tTJS_W(\" was requested but denied. Continuing operation with \");\n\t\t\t\t\tif(forcemode == 1)\n\t\t\t\t\t\tlog += TJS_W(\"16bit mode\");\n\t\t\t\t\telse if(forcemode == 2)\n\t\t\t\t\t\tlog += TJS_W(\"16bit mono mode\");\n\t\t\t\t\tlog += TJS_W(\".)\");\n\t\t\t\t}\n\n\t\t\t\tif(firstfailed)\n\t\t\t\t\tTVPAddImportantLog(log);\n\t\t\t}\n#endif\n\t\t}\n\t\tcatch(ttstr & e)\n\t\t{\n\t\t\tThrowSoundBufferException(e);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tthrow;\n\t\t}\n\n\t}\n\n\t// reset volume, sound position and frequency\n\tSetVolumeToSoundBuffer();\n\tSet3DPositionToBuffer();\n\tSetFrequencyToBuffer();\n\n\t// reset sound buffer\n\tResetSoundBuffer();\n\n\tC_InputFormat = InputFormat;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::DestroySoundBuffer()\n{\n#if 0\n\tif(Sound3DBuffer)\n\t{\n\t\tSound3DBuffer->Release();\n\t\tSound3DBuffer = NULL;\n\t}\n#endif\n\tif(SoundBuffer)\n\t{\n\t\tSoundBuffer->Stop();\n\t\tSoundBuffer->Release();\n\t\tSoundBuffer = NULL;\n\t}\n\n\tDSBufferPlaying = false;\n\tBufferPlaying = false;\n\n\tif(L1BufferSegmentQueues) delete [] L1BufferSegmentQueues, L1BufferSegmentQueues = NULL;\n\tLabelEventQueue.clear();\n\tif(L1BufferDecodeSamplePos) delete [] L1BufferDecodeSamplePos, L1BufferDecodeSamplePos = NULL;\n\tif(L2BufferDecodedSamplesInUnit) delete [] L2BufferDecodedSamplesInUnit, L2BufferDecodedSamplesInUnit = NULL;\n\tif(L2BufferSegmentQueues) delete [] L2BufferSegmentQueues, L2BufferSegmentQueues = NULL;\n\tif(Level2Buffer) delete [] Level2Buffer, Level2Buffer = NULL;\n\tL1BufferUnits = 0;\n\tL2BufferUnits = 0;\n\n\tmemset(&C_InputFormat, 0x00, sizeof(C_InputFormat));\n\n\tLevel2BufferSize = 0;\n\n\tDeallocateVisBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::ResetSoundBuffer()\n{\n\tif(SoundBuffer)\n\t{\n\t\tSoundBuffer->Reset();\n#if 0\n\t\t// fill the buffer with silence\n\n\t\tSoundBuffer->SetCurrentPosition(0);\n\t\tBYTE *p1,*p2;\n\t\tDWORD b1,b2;\n\t\tHRESULT hr;\n\t\thr = SoundBuffer->Lock(0, BufferBytes, (void**)&p1,\n\t\t\t&b1, (void**)&p2, &b2, 0);\n\t\tif(hr == DSERR_BUFFERLOST)\n\t\t{\n\t\t\t// retry after restoring lost buffer memory\n\t\t\tSoundBuffer->Restore();\n\t\t\thr = SoundBuffer->Lock(0, BufferBytes, (void**)&p1,\n\t\t\t\t&b1, (void**)&p2, &b2, 0);\n\t\t}\n\n\t\tif(SUCCEEDED(hr))\n\t\t{\n\t\t\tTVPMakeSilentWaveBytes(p1, BufferBytes, &Format);\n\n\t\t\tSoundBuffer->Unlock((void*)p1, b1, (void*)p2, b2);\n\t\t}\n\n\t\tSoundBuffer->SetCurrentPosition(0);\n\n\t\t// fill level2 buffer with silence\n\t\tTVPMakeSilentWaveBytes(Level2Buffer, Level2BufferSize, &Format);\n#endif\n\t}\n\n\tResetSamplePositions();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::ResetSamplePositions()\n{\n\t// reset L1BufferSegmentQueues and L2BufferSegmentQueues, and labels\n\tif(L1BufferSegmentQueues)\n\t{\n\t\tfor(int i = 0; i < L1BufferUnits; i++)\n\t\t\tL1BufferSegmentQueues[i].Clear();\n\t}\n\tif(L2BufferSegmentQueues)\n\t{\n\t\tfor(int i = 0; i < L2BufferUnits; i++)\n\t\t\tL2BufferSegmentQueues[i].Clear();\n\t}\n\tif(L1BufferDecodeSamplePos)\n\t{\n\t\tfor(int i = 0; i < L1BufferUnits; i++)\n\t\t\tL1BufferDecodeSamplePos[i] = -1;\n\t}\n\tLabelEventQueue.clear();\n\tDecodePos = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::Clear()\n{\n\t// clear all status and unload current decoder\n\tStop();\n\tThreadCallbackEnabled = false;\n\tTVPCheckSoundBufferAllSleep();\n\tThread->Interrupt();\n\tif(LoopManager) delete LoopManager, LoopManager = NULL;\n\tClearFilterChain();\n\tif(Decoder) delete Decoder, Decoder = NULL;\n\tBufferPlaying = false;\n\tDSBufferPlaying = false;\n\tPaused = false;\n\n\tResetSamplePositions();\n\n\tSetStatus(ssUnload);\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_WaveSoundBuffer::Decode(void *buffer, tjs_uint bufsamplelen,\n\t\ttTVPWaveSegmentQueue & segments)\n{\n\t// decode one buffer unit\n\ttjs_uint w = 0;\n\n\ttry\n\t{\n\t\t// decode\n\t\tFilterOutput->Decode((tjs_uint8*)buffer, bufsamplelen, w, segments);\n\t}\n\tcatch(...)\n\t{\n\t\t// ignore errors\n\t\tw = 0;\n\t}\n\n\treturn w;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_WaveSoundBuffer::FillL2Buffer(bool firstwrite, bool fromdecodethread)\n{\n\tif(!fromdecodethread && Thread->GetRunning())\n\t\tThread->SetPriority(ttpHighest);\n\t\t\t// make decoder thread priority high, before entering critical section\n\n\ttTJSCriticalSectionHolder holder(L2BufferCS);\n\n\tif(firstwrite)\n\t{\n\t\t// only main thread runs here\n\t\tL2BufferReadPos = L2BufferWritePos = L2BufferRemain = 0;\n\t\tL2BufferEnded = false;\n\t\tfor(tjs_int i = 0; i<L2BufferUnits; i++)\n\t\t\tL2BufferDecodedSamplesInUnit[i] = 0;\n\t}\n\n\t{\n\t\ttTVPThreadPriority ttpbefore = TVPDecodeThreadHighPriority;\n\t\tbool retflag = false;\n\t\tif(Thread->GetRunning())\n\t\t{\n\t\t\tttpbefore = Thread->GetPriority();\n\t\t\tThread->SetPriority(TVPDecodeThreadHighPriority);\n\t\t}\n\t\t{\n\t\t\ttTJSCriticalSectionHolder holder(L2BufferRemainCS);\n\t\t\tif(L2BufferRemain == L2BufferUnits) retflag = true;\n\t\t}\n\t\tif(!retflag) UpdateFilterChain(); // if the buffer is not full, update filter internal state\n\t\tif(Thread->GetRunning()) Thread->SetPriority(ttpbefore);\n\t\tif(retflag) return false; // buffer is full\n\t}\n\n\tif(L2BufferEnded)\n\t{\n\t\tL2BufferSegmentQueues[L2BufferWritePos].Clear();\n\t\tL2BufferDecodedSamplesInUnit[L2BufferWritePos] = 0;\n\t}\n\telse\n\t{\n\t\tL2BufferSegmentQueues[L2BufferWritePos].Clear();\n\t\ttjs_uint decoded = Decode(\n\t\t\tL2BufferWritePos * L2AccessUnitBytes + Level2Buffer,\n\t\t\tAccessUnitSamples,\n\t\t\tL2BufferSegmentQueues[L2BufferWritePos]);\n\n\t\tif(decoded < (tjs_uint) AccessUnitSamples) L2BufferEnded = true;\n\n\t\tL2BufferDecodedSamplesInUnit[L2BufferWritePos] = decoded;\n\t}\n\n\tL2BufferWritePos++;\n\tif(L2BufferWritePos >= L2BufferUnits) L2BufferWritePos = 0;\n\n\t{\n\t\ttTVPThreadPriority ttpbefore = TVPDecodeThreadHighPriority;\n\t\tif(Thread->GetRunning())\n\t\t{\n\t\t\tttpbefore = Thread->GetPriority();\n\t\t\tThread->SetPriority(TVPDecodeThreadHighPriority);\n\t\t}\n\t\t{\n\t\t\ttTJSCriticalSectionHolder holder(L2BufferRemainCS);\n\t\t\tL2BufferRemain++;\n\t\t}\n\t\tif(Thread->GetRunning()) Thread->SetPriority(ttpbefore);\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::PrepareToReadL2Buffer(bool firstread)\n{\n\tif(L2BufferRemain == 0 && !L2BufferEnded)\n\t\tFillL2Buffer(firstread, false);\n\n\tif(Thread->GetRunning()) Thread->SetPriority(TVPDecodeThreadHighPriority);\n\t\t\t// make decoder thread priority higher than usual,\n\t\t\t// before entering critical section\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_WaveSoundBuffer::ReadL2Buffer(void *buffer,\n\t\ttTVPWaveSegmentQueue & segments)\n{\n\t// This routine is protected by BufferCS, not L2BufferCS, while\n\t// this routine reads L2 buffer.\n\t// But It's ok because this function will never read currently writing L2\n\t// buffer. L2 buffer having at least one rendered unit is\n\t// guaranteed at this point.\n\n\ttjs_uint decoded = L2BufferDecodedSamplesInUnit[L2BufferReadPos];\n\n\tsegments = L2BufferSegmentQueues[L2BufferReadPos];\n\tif (decoded) {\n\t\tSoundBuffer->AppendBuffer(L2BufferReadPos * L2AccessUnitBytes + Level2Buffer,\n\t\t\tdecoded * InputFormat.BytesPerSample * InputFormat.Channels/*, SoundBufferWritePos*/);\n\t\tif (buffer) { // for VisBuffer\n\t\t\tmemcpy(buffer, L2BufferReadPos * L2AccessUnitBytes + Level2Buffer, decoded * InputFormat.BytesPerSample * InputFormat.Channels);\n\t\t}\n\t}\n#if 0\n\tTVPConvertWaveFormatToDestinationFormat(buffer,\n\t\tL2BufferReadPos * L2AccessUnitBytes + Level2Buffer, decoded,\n\t\t&Format, &InputFormat);\n#endif\n\tif (buffer && decoded < (tjs_uint)AccessUnitSamples)\n\t{\n\t\t// fill rest with silence\n\t\tTVPMakeSilentWave((tjs_uint8*)buffer + decoded * InputFormat.Channels * InputFormat.BytesPerSample,\n\t\t\tAccessUnitSamples - decoded, &InputFormat);\n\t}\n\n\tL2BufferReadPos++;\n\tif(L2BufferReadPos >= L2BufferUnits) L2BufferReadPos = 0;\n\n\t{\n\t\ttTJSCriticalSectionHolder holder(L2BufferRemainCS);\n\t\tL2BufferRemain--;\n\t}\n\n\treturn decoded;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::FillDSBuffer(tjs_int writepos,\n\t\ttTVPWaveSegmentQueue & segments)\n{\n#if 0\n\tBYTE *p1, *p2;\n\tDWORD b1, b2;\n#endif\n\tsegments.Clear();\n\n\tif (SoundBuffer->IsBufferValid())\n\t{\n\t\ttjs_uint decoded = ReadL2Buffer(UseVisBuffer ? VisBuffer + writepos : nullptr, segments);\n\t}\n#if 0\n\tHRESULT hr;\n\thr = SoundBuffer->Lock(writepos, AccessUnitBytes,\n\t\t(void**)&p1, &b1, (void**)&p2, &b2, 0);\n\tif(hr == DSERR_BUFFERLOST)\n\t{\n\t\t// retry after restoring lost buffer memory\n\t\tSoundBuffer->Restore();\n\t\thr = SoundBuffer->Lock(writepos, AccessUnitBytes,\n\t\t\t(void**)&p1, &b1, (void**)&p2, &b2, 0);\n\t}\n\n\tif(SUCCEEDED(hr))\n\t{\n\t\ttjs_uint decoded;\n\n\t\tif(UseVisBuffer)\n\t\t{\n\t\t\tdecoded = ReadL2Buffer(VisBuffer + writepos, segments);\n\t\t\tmemcpy(p1, VisBuffer + writepos, AccessUnitBytes);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdecoded = ReadL2Buffer(p1, segments);\n\t\t}\n\n\t\tif(PlayStopPos == -1 && decoded < (tjs_uint)AccessUnitSamples)\n\t\t{\n\t\t\t// decoding was finished\n\t\t\tPlayStopPos = writepos + decoded*Format.Format.nBlockAlign;\n\t\t\t\t// set stop position\n\t\t}\n\n\t\tSoundBuffer->Unlock((void*)p1, b1, (void*)p2, b2);\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_WaveSoundBuffer::FillBuffer(bool firstwrite, bool allowpause)\n{\n\t// fill DirectSound secondary buffer with one render unit.\n\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tif(!SoundBuffer) return true;\n\tif(!Decoder) return true;\n\tif(!BufferPlaying) return true;\n\tif (!TVPPrimarySoundBufferPlaying) return true;\n\n\t// check paused state\n\tif(allowpause)\n\t{\n\t\tif(Paused)\n\t\t{\n\t\t\tif(DSBufferPlaying)\n\t\t\t{\n\t\t\t\tSoundBuffer->Pause();\n\t\t\t\tDSBufferPlaying = false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!DSBufferPlaying)\n\t\t\t{\n\t\t\t\tSoundBuffer->Play(/*0, 0, DSBPLAY_LOOPING*/);\n\t\t\t\tDSBufferPlaying = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// check decoder thread status\n\ttjs_int bufferremain;\n\t{\n\t\ttTJSCriticalSectionHolder holder(L2BufferRemainCS);\n\t\tbufferremain = L2BufferRemain;\n\t}\n\n\tif(Thread->GetRunning() && bufferremain < TVP_WSB_ACCESS_FREQ )\n\t\tThread->SetPriority(ttpNormal); // buffer remains under 1 sec \n\n\t// check buffer playing position\n\ttjs_int writepos;\n#if 0\n\tDWORD pp = 0, wp = 0; // write pos and read pos\n\tif(FAILED(SoundBuffer->GetCurrentPosition(&pp, &wp))) return true;\n\n\tTVPPushEnvironNoise(&pp, sizeof(pp));\n\tTVPPushEnvironNoise(&wp, sizeof(wp));\n\t\t// drift between main clock and clocks which come from other sources\n\t\t// is a good environ noise.\n#endif\n\t// SoundBufferWritePos = SoundBuffer->GetNextBufferIndex();\n\n\t// check position\n\ttTVPWaveSegmentQueue * segment;\n\ttjs_int64 * bufferdecodesamplepos;\n\n\tif(firstwrite)\n\t{\n\t\twritepos = 0;\n\t\tsegment = L1BufferSegmentQueues + 0;\n\t\tbufferdecodesamplepos = L1BufferDecodeSamplePos + 0;\n#if 1\n\t\tPlayStopPos = -1;\n\t\tSoundBufferWritePos = 1;\n\t\tSoundBufferPrevReadPos = 0;\n#endif\n\t\t// SoundBuffer->SetSampleOffset(0);\n\t}\n\telse\n\t{\n\t\tResetLastCheckedDecodePos(/*pp*/);\n#if 0\n\t\tif(PlayStopPos != -1)\n\t\t{\n\t\t\t// check whether the buffer playing position passes over PlayStopPos\n\t\t\tif(SoundBufferPrevReadPos > (tjs_int)pp)\n\t\t\t{\n\t\t\t\tif(PlayStopPos >= SoundBufferPrevReadPos ||\n\t\t\t\t\tPlayStopPos < (tjs_int)pp)\n\t\t\t\t{\n#else\n\t\tif (L2BufferEnded) {\n\t\t\tif (SoundBuffer->GetRemainBuffers() == 0) {\n#endif\n\t\t\t\t\tFlushAllLabelEvents();\n\t\t\t\t\tSoundBuffer->Pause();\n\t\t\t\t\tResetSamplePositions();\n\t\t\t\t\tDSBufferPlaying = false;\n\t\t\t\t\tBufferPlaying = false;\n\t\t\t\t\tif(LoopManager) LoopManager->SetPosition(0);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n#if 0\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(PlayStopPos >= SoundBufferPrevReadPos &&\n\t\t\t\t\tPlayStopPos < (tjs_int)pp)\n\t\t\t\t{\n\t\t\t\t\tFlushAllLabelEvents();\n\t\t\t\t\tSoundBuffer->Stop();\n\t\t\t\t\tResetSamplePositions();\n\t\t\t\t\tDSBufferPlaying = false;\n\t\t\t\t\tBufferPlaying = false;\n\t\t\t\t\tif(LoopManager) LoopManager->SetPosition(0);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttjs_int wpb = wp / AccessUnitBytes;\n\t\ttjs_int ppb = pp / AccessUnitBytes;\n\n\t\ttjs_int d = wpb - SoundBufferWritePos;\n\t\tif(d < 0) d += L1BufferUnits;\n\n\t\twpb -= ppb;\n\t\tif(wpb < 0) wpb += L1BufferUnits;\n\n\t\tif(d <= wpb)\n\t\t{\n\t\t\t// pp thru wp is currently playing position; cannot write there\n\t\t\treturn true;\n\t\t}\n#endif\n\t\twritepos = SoundBufferWritePos * AccessUnitBytes;\n\t\tif (SoundBuffer->GetRemainBuffers() >= TVPAL_BUFFER_COUNT)\n\t\t{\n// \t\t\tif (!SoundBuffer->IsPlaying()) { // run out of buffer\n// \t\t\t\tSoundBuffer->Play();\n// \t\t\t\t// reset offset\n// \t\t\t\tSoundBuffer->SetSampleOffset(writepos / InputFormat.BytesPerSample / InputFormat.Channels);\n// \t\t\t}\n// \t\t\telse\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tsegment = L1BufferSegmentQueues + SoundBufferWritePos;\n\t\tbufferdecodesamplepos = L1BufferDecodeSamplePos + SoundBufferWritePos;\n\t\tSoundBufferWritePos ++;\n\t\tif(SoundBufferWritePos >= L1BufferUnits)\n\t\t\tSoundBufferWritePos = 0;\n\t}\n\n\t//SoundBufferPrevReadPos = pp;\n\n\t// decode\n\tif(bufferremain > 1) // buffer is ready\n\t{\n\t\t// with no locking operations\n\t\tFillDSBuffer(writepos, *segment);\n\t}\n\telse\n\t{\n\t\tPrepareToReadL2Buffer(false); // complete decoding before reading from L2\n\n\t\t{\n\t\t\ttTJSCriticalSectionHolder l2holder(L2BufferCS);\n\t\t\tFillDSBuffer(writepos, *segment);\n\t\t}\n\t}\n\n\t// insert labels into LabelEventQueue and sort\n\tconst std::deque<tTVPWaveLabel> & labels = segment->GetLabels();\n\tif(labels.size() != 0)\n\t{\n\t\t// add DecodePos offset to each item->Offset\n\t\t// and insert into LabelEventQueue\n\t\tfor(std::deque<tTVPWaveLabel>::const_iterator i = labels.begin();\n\t\t\ti != labels.end(); i++)\n\t\t{\n\t\t\tLabelEventQueue.emplace_back(\n\t\t\t\ti->Position,\n\t\t\t\t\t\ti->Name, static_cast<tjs_int>(i->Offset + DecodePos));\n\t\t}\n\n\t\t// sort\n\t\tstd::sort(LabelEventQueue.begin(), LabelEventQueue.end(),\n\t\t\ttTVPWaveLabel::tSortByOffsetFuncObj());\n\n\t\t// re-schedule label events\n\t\tTVPReschedulePendingLabelEvent(GetNearestEventStep());\n\t}\n\n\t// write bufferdecodesamplepos\n\t*bufferdecodesamplepos = DecodePos;\n\tDecodePos += AccessUnitSamples;\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::ResetLastCheckedDecodePos(DWORD pp)\n{\n\t// set LastCheckedDecodePos and  LastCheckedTick\n\t// we shoud reset these values because the clock sources are usually\n\t// not identical.\n\ttTJSCriticalSectionHolder holder(BufferCS);\n#if 0\n\tif(pp == (DWORD)-1)\n\t{\n\t\tif(!SoundBuffer) return;\n\t\tDWORD wp = 0;\n\t\tif(FAILED(SoundBuffer->GetCurrentPosition(&pp, &wp)))\n\t\t\treturn; // must not be an error ...\n\t}\n\n\ttjs_int ppb = pp / AccessUnitBytes;\n\ttjs_int ppm = pp % AccessUnitBytes;\n\tif(L1BufferDecodeSamplePos[ppb] != -1)\n\t{\n\t\tLastCheckedDecodePos = L1BufferDecodeSamplePos[ppb] + ppm / Format.Format.nBlockAlign;\n\t\tLastCheckedTick = TVPGetTickCount();\n\t}\n#else\n\tif (!SoundBuffer) return;\n\n\tint offset, rblock;\n\tif (SoundBuffer->GetRemainBuffers() == 0) {\n\t\trblock = SoundBufferWritePos;\n\t\toffset = 0;\n\t} else {\n\t\toffset = SoundBuffer->GetCurrentPlaySamples();\n\t\trblock = offset / AccessUnitSamples;\n\t\toffset %= AccessUnitSamples;\n\t\trblock %= L1BufferUnits;\n\t}\n\tif (L1BufferDecodeSamplePos[rblock] != -1)\n\t{\n\t\tLastCheckedDecodePos = L1BufferDecodeSamplePos[rblock] + offset;\n\t\tLastCheckedTick = TVPGetTickCount();\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_WaveSoundBuffer::FireLabelEventsAndGetNearestLabelEventStep(tjs_int64 tick)\n{\n\t// fire events, event.EventTick <= tick, and return relative time to\n\t// next nearest event (return TVP_TIMEOFS_INVALID_VALUE for no events).\n\n\t// the vector LabelEventQueue must be sorted by the position.\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tif(!BufferPlaying) return TVP_TIMEOFS_INVALID_VALUE; // buffer is not currently playing\n\tif(!DSBufferPlaying) return TVP_TIMEOFS_INVALID_VALUE; // direct sound buffer is not currently playing\n\n\tif(LabelEventQueue.size() == 0) return TVP_TIMEOFS_INVALID_VALUE; // no more events\n\n\t// calculate current playing decodepos\n\t// at this point, LastCheckedDecodePos must not be -1\n\tif(LastCheckedDecodePos == -1) ResetLastCheckedDecodePos();\n\ttjs_int64 decodepos = (tick - LastCheckedTick) * Frequency / 1000 +\n\t\tLastCheckedDecodePos;\n\n\twhile(true)\n\t{\n\t\tif(LabelEventQueue.size() == 0) break;\n\t\tstd::vector<tTVPWaveLabel>::iterator i = LabelEventQueue.begin();\n\t\tint diff = (tjs_int32)i->Offset - (tjs_int32)decodepos;\n\t\tif(diff <= 0)\n\t\t\tInvokeLabelEvent(i->Name);\n\t\telse\n\t\t\tbreak;\n\t\tLabelEventQueue.erase(i);\n\t}\n\n\tif(LabelEventQueue.size() == 0) return TVP_TIMEOFS_INVALID_VALUE; // no more events\n\n\treturn (tjs_int)(\n\t\t(LabelEventQueue[0].Offset - (tjs_int32)decodepos) * 1000 / Frequency);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_WaveSoundBuffer::GetNearestEventStep()\n{\n\t// get nearest event stop from current tick\n\t// (current tick is taken from TVPGetTickCount)\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tif(LabelEventQueue.size() == 0) return TVP_TIMEOFS_INVALID_VALUE; // no more events\n\n\t// calculate current playing decodepos\n\t// at this point, LastCheckedDecodePos must not be -1\n\tif(LastCheckedDecodePos == -1) ResetLastCheckedDecodePos();\n\ttjs_int64 decodepos = (TVPGetTickCount() - LastCheckedTick) * Frequency / 1000 +\n\t\tLastCheckedDecodePos;\n\n\treturn (tjs_int)(\n\t\t(LabelEventQueue[0].Offset - (tjs_int32)decodepos) * 1000 / Frequency);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::FlushAllLabelEvents()\n{\n\t// called at the end of the decode.\n\t// flush all undelivered events.\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tfor(std::vector<tTVPWaveLabel>::iterator i = LabelEventQueue.begin();\n\t\ti != LabelEventQueue.end(); i++)\n\t\tInvokeLabelEvent(i->Name);\n\n\tLabelEventQueue.clear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::StartPlay()\n{\n\tif(!Decoder) return;\n\n\t// let primary buffer to start running\n\tTVPEnsurePrimaryBufferPlay();\n\n\t// ensure playing thread\n\tTVPEnsureWaveSoundBufferWorking();\n\n\t// play from first\n\n\t{\t// thread protected block\n\t\tif(Thread->GetRunning()) { Thread->SetPriority(TVPDecodeThreadHighPriority); }\n\t\ttTJSCriticalSectionHolder holder(BufferCS);\n\t\ttTJSCriticalSectionHolder l2holder(L2BufferCS);\n\n\t\tCreateSoundBuffer();\n\n\t\t// reset filter chain\n\t\tResetFilterChain();\n\n\t\t// fill sound buffer with some first samples\n\t\tBufferPlaying = true;\n\t\tFillL2Buffer(true, false);\n\t\tFillBuffer(true, false);\n\t\tFillBuffer(false, false);\n\t\tFillBuffer(false, false);\n\t\tFillBuffer(false, false);\n\n\t\t// start playing\n\t\tif(!Paused)\n\t\t{\n\t\t\tSoundBuffer->Play(/*0, 0, DSBPLAY_LOOPING*/);\n\t\t\tDSBufferPlaying = true;\n\t\t}\n\n\t\t// re-schedule label events\n\t\tResetLastCheckedDecodePos();\n\t\tTVPReschedulePendingLabelEvent(GetNearestEventStep());\n\t}\t// end of thread protected block\n\n\t// ensure thread\n\tTVPEnsureWaveSoundBufferWorking(); // wake the playing thread up again\n\tThreadCallbackEnabled = true;\n\tThread->Continue();\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::StopPlay()\n{\n\tif(!Decoder) return;\n\tif(!SoundBuffer) return;\n\n\tif(Thread->GetRunning()) { Thread->SetPriority(TVPDecodeThreadHighPriority);}\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\ttTJSCriticalSectionHolder l2holder(L2BufferCS);\n\n\tSoundBuffer->Stop();\n\tDSBufferPlaying = false;\n\tBufferPlaying = false;\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::Play()\n{\n\t// play from first or current position\n\tif(!Decoder) return;\n\tif(BufferPlaying) return;\n\n\tStopPlay();\n\n\tTVPEnsurePrimaryBufferPlay(); // let primary buffer to start running\n\n\tif(Thread->GetRunning()) { Thread->SetPriority(TVPDecodeThreadHighPriority);}\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\ttTJSCriticalSectionHolder l2holder(L2BufferCS);\n\n\tStartPlay();\n\tSetStatus(ssPlay);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::Stop()\n{\n\t// stop playing\n\tStopPlay();\n\n\t// delete thread\n\tThreadCallbackEnabled = false;\n\tTVPCheckSoundBufferAllSleep();\n\tThread->Interrupt();\n\n\t// set status\n\tif(Status != ssUnload) SetStatus(ssStop);\n\n\t// rewind\n\tif(LoopManager) LoopManager->SetPosition(0);\n}\n\nvoid tTJSNI_WaveSoundBuffer::SetBufferPaused(bool bPaused) {\n\tif (!Decoder || !SoundBuffer) return;\n\n\tif (bPaused)\n\t\tSoundBuffer->Pause();\n\telse { // restore\n\t\tif (!Paused && DSBufferPlaying && BufferPlaying) {\n\t\t\tSoundBuffer->Play();\n\t\t}\n\t}\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPaused(bool b)\n{\n\tif(Thread->GetRunning())\n\t\t{/*orgpri = Thread->Priority;*/\n\t\t\tThread->SetPriority(TVPDecodeThreadHighPriority); }\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\ttTJSCriticalSectionHolder l2holder(L2BufferCS);\n\n\tPaused = b;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::TimerBeatHandler()\n{\n\tinherited::TimerBeatHandler();\n\n\t// check buffer stopping\n\tif(Status == ssPlay && !BufferPlaying)\n\t{\n\t\t// buffer was stopped\n\t\tThreadCallbackEnabled = false;\n\t\tTVPCheckSoundBufferAllSleep();\n\t\tThread->Interrupt();\n\t\tSetStatusAsync(ssStop);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::Open(const ttstr & storagename)\n{\n\t// open a storage and prepare to play\n\tTVPEnsurePrimaryBufferPlay(); // let primary buffer to start running\n\n\tClear();\n\n\tDecoder = TVPCreateWaveDecoder(storagename);\n\n\ttry\n\t{\n\t\t// make manager\n\t\tLoopManager = new tTVPWaveLoopManager();\n\t\tLoopManager->SetDecoder(Decoder);\n\t\tLoopManager->SetLooping(Looping);\n\n\t\t// build filter chain\n\t\tRebuildFilterChain();\n\n\t\t// retrieve format\n\t\tInputFormat = FilterOutput->GetFormat();\n\t\tFrequency = InputFormat.SamplesPerSec;\n\t}\n\tcatch(...)\n\t{\n\t\tClear();\n\t\tthrow;\n\t}\n\n\t// open loop information file\n\tttstr sliname = storagename + TJS_W(\".sli\");\n\tif(TVPIsExistentStorage(sliname))\n\t{\n\t\ttTVPStreamHolder slistream(sliname);\n\t\tchar *buffer;\n\t\ttjs_uint size;\n\t\tbuffer = new char [ (size = static_cast<tjs_uint>(slistream->GetSize())) +1];\n\t\ttry\n\t\t{\n\t\t\tslistream->ReadBuffer(buffer, size);\n\t\t\tbuffer[size] = 0;\n\n\t\t\tif(!LoopManager->ReadInformation(buffer))\n\t\t\t\tTVPThrowExceptionMessage(TVPInvalidLoopInformation, sliname);\n\t\t\tRecreateWaveLabelsObject();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete [] buffer;\n\t\t\tClear();\n\t\t\tthrow;\n\t\t}\n\t\tdelete [] buffer;\n\t}\n\n\t// set status to stop\n\tSetStatus(ssStop);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetLooping(bool b)\n{\n\tLooping = b;\n\tif(LoopManager) LoopManager->SetLooping(Looping);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_WaveSoundBuffer::GetSamplePosition()\n{\n\tif(!Decoder) return 0L;\n\tif(!SoundBuffer) return 0L;\n\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\t/*\n\tDWORD wp, pp;\n\tif(FAILED(SoundBuffer->GetCurrentPosition(&pp, &wp))) return 0L;\n\t*/\n\n\tint offset, rblock;\n\tif (SoundBuffer->GetRemainBuffers() == 0) {\n\t\trblock = SoundBufferWritePos;\n\t\toffset = 0;\n\t} else {\n\t\toffset = SoundBuffer->GetCurrentPlaySamples();\n\t\trblock = offset / AccessUnitSamples;\n\t\toffset %= AccessUnitSamples;\n\t\trblock %= L1BufferUnits;\n\t}\n\t//tjs_int rblock = pp / AccessUnitBytes;\n\n\ttTVPWaveSegmentQueue & segs = L1BufferSegmentQueues[rblock];\n\n\t//tjs_int offset = pp % AccessUnitBytes;\n\n\t//offset /= Format.Format.nBlockAlign;\n\n\treturn segs.FilteredPositionToDecodePosition(offset);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetSamplePosition(tjs_uint64 pos)\n{\n\ttjs_uint64 possamples = pos; // in samples\n\n\tif(InputFormat.TotalSamples && InputFormat.TotalSamples <= possamples) return;\n\n\tif(BufferPlaying && DSBufferPlaying)\n\t{\n\t\tStopPlay();\n\t\tLoopManager->SetPosition(possamples);\n\t\tStartPlay();\n\t}\n\telse\n\t{\n\t\tLoopManager->SetPosition(possamples);\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_WaveSoundBuffer::GetPosition()\n{\n\tif(!Decoder) return 0L;\n\tif(!SoundBuffer) return 0L;\n\n\treturn GetSamplePosition() * 1000 / InputFormat.SamplesPerSec;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPosition(tjs_uint64 pos)\n{\n\tSetSamplePosition(pos * InputFormat.SamplesPerSec / 1000); // in samples\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_WaveSoundBuffer::GetTotalTime()\n{\n\treturn InputFormat.TotalSamples * 1000 / InputFormat.SamplesPerSec;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetVolumeToSoundBuffer()\n{\n\t// set current volume/pan to DirectSound buffer\n\tif(SoundBuffer)\n\t{\n\t\ttjs_int v;\n\t\ttjs_int mutevol = 100000;\n\t\tif(TVPSoundGlobalFocusModeByOption >= sgfmMuteOnDeactivate &&\n\t\t\tTVPSoundGlobalFocusMuteVolume == 0)\n\t\t{\n\t\t\t// no mute needed here;\n\t\t\t// muting will be processed in DirectSound framework.\n\t\t\t;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// mute mode is choosen from GlobalFocusMode or\n\t\t\t// TVPSoundGlobalFocusModeByOption which is more restrictive.\n\t\t\ttTVPSoundGlobalFocusMode mode =\n\t\t\t\tGlobalFocusMode > TVPSoundGlobalFocusModeByOption ?\n\t\t\t\tGlobalFocusMode : TVPSoundGlobalFocusModeByOption;\n#if 0 // useless on mobile device\n\t\t\tswitch(mode)\n\t\t\t{\n\t\t\tcase sgfmNeverMute:\n\t\t\t\t;\n\t\t\t\tbreak;\n\t\t\tcase sgfmMuteOnMinimize:\n\t\t\t\tif(!  Application->GetNotMinimizing())\n\t\t\t\t\tmutevol = TVPSoundGlobalFocusMuteVolume;\n\t\t\t\tbreak;\n\t\t\tcase sgfmMuteOnDeactivate:\n\t\t\t\tif(! (  Application->GetActivating() && Application->GetNotMinimizing()))\n\t\t\t\t\tmutevol = TVPSoundGlobalFocusMuteVolume;\n\t\t\t\tbreak;\n\t\t\t}\n#endif\n\t\t}\n\n\t\t// compute volume for each buffer\n\t\tv = (Volume / 10) * (Volume2 / 10) / 1000;\n\t\tv = (v / 10) * (GlobalVolume / 10) / 1000;\n\t\tv = (v / 10) * (mutevol / 10) / 1000;\n\t\tSoundBuffer->SetVolume(/*TVPVolumeToDSAttenuate*/(v / 100000.0f));\n\n\t\tif(BufferCanControlPan)\n\t\t{\n\t\t\t// set pan\n\t\t\tSoundBuffer->SetPan(/*TVPPanToDSAttenuate*/(Pan / 100000.0f));\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetVolume(tjs_int v)\n{\n\tif(v < 0) v = 0;\n\tif(v > 100000) v = 100000;\n\n\tif(Volume != v)\n\t{\n\t\tVolume = v;\n\t\tSetVolumeToSoundBuffer();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetVolume2(tjs_int v)\n{\n\tif(v < 0) v = 0;\n\tif(v > 100000) v = 100000;\n\n\tif(Volume2 != v)\n\t{\n\t\tVolume2 = v;\n\t\tSetVolumeToSoundBuffer();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPan(tjs_int v)\n{\n\tif(v < -100000) v = -100000;\n\tif(v > 100000) v = 100000;\n\tif(Pan != v)\n\t{\n\t\tPan = v;\n\t\tif(BufferCanControlPan)\n\t\t{\n\t\t\t// set pan with SetPan\n\t\t\tSetVolumeToSoundBuffer();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// set pan with 3D sound facility\n\t\t\t// note that setting pan can reset 3D position.\n\t\t\tPosZ = (D3DVALUE)0.0;\n\t\t\tPosY = (D3DVALUE)0.001;\n\t\t\t// PosX = -0.003 .. -0.0001 = 0 = +0.0001 ... +0.003\n\t\t\tfloat t;\n\t\t\tt = static_cast<float>( ((float)v / 100000.0) );\n\t\t\tt *= static_cast<float>( t * 0.003 );\n\t\t\tif(v < 0) t = - t;\n\t\t\tPosX = t;\n\t\t\tSet3DPositionToBuffer();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetGlobalVolume(tjs_int v)\n{\n\tif(v < 0) v = 0;\n\tif(v > 100000) v = 100000;\n\n\tif(GlobalVolume != v)\n\t{\n\t\tGlobalVolume = v;\n\t\tTVPResetVolumeToAllSoundBuffer();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetGlobalFocusMode(tTVPSoundGlobalFocusMode b)\n{\n\tif(GlobalFocusMode != b)\n\t{\n\t\tGlobalFocusMode = b;\n\t\tTVPResetVolumeToAllSoundBuffer();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::Set3DPositionToBuffer()\n{\n\tif(SoundBuffer)\n\t{\n\t\tSoundBuffer->SetPosition(PosX, PosY, PosZ/*, DS3D_DEFERRED*/);\n\t\t// defered settings are to be commited at next tickbeat event.\n\t\tTVPDeferedSettingAvailable = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPos(D3DVALUE x, D3DVALUE y, D3DVALUE z)\n{\n\tPosX = x;\n\tPosY = y;\n\tPosZ = z;\n\tSet3DPositionToBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPosX(D3DVALUE v)\n{\n\tPosX = v;\n\tSet3DPositionToBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPosY(D3DVALUE v)\n{\n\tPosY = v;\n\tSet3DPositionToBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetPosZ(D3DVALUE v)\n{\n\tPosZ = v;\n\tSet3DPositionToBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetFrequencyToBuffer()\n{\n\tif(BufferCanControlFrequency)\n\t{\n\t\t//if(SoundBuffer) SoundBuffer->SetFrequency(Frequency);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetFrequency(tjs_int freq)\n{\n\t// set frequency\n\tFrequency = freq;\n\tSetFrequencyToBuffer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::SetUseVisBuffer(bool b)\n{\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tif(b)\n\t{\n\t\tUseVisBuffer = true;\n\n\t\tif(SoundBuffer) ResetVisBuffer();\n\t}\n\telse\n\t{\n\t\tDeallocateVisBuffer();\n\t\tUseVisBuffer = false;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::ResetVisBuffer()\n{\n\t// reset or recreate visualication buffer\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tDeallocateVisBuffer();\n\n\tVisBuffer = new tjs_uint8 [BufferBytes];\n\tUseVisBuffer = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::DeallocateVisBuffer()\n{\n\ttTJSCriticalSectionHolder holder(BufferCS);\n\n\tif(VisBuffer) delete [] VisBuffer, VisBuffer = NULL;\n\tUseVisBuffer = false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_WaveSoundBuffer::CopyVisBuffer(tjs_int16 *dest, const tjs_uint8 *src,\n\ttjs_int numsamples, tjs_int channels)\n{\n#if 0\n\tbool isfloat = Format.Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||\n\t\t(Format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&\n\t\t\t!memcmp(&Format.SubFormat, &TVP_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 16));\n#endif\n\tif(channels == 1)\n\t{\n\t\tTVPConvertPCMTo16bits(dest, (const void*)src, InputFormat.Channels,\n\t\t\tInputFormat.BytesPerSample, InputFormat.BitsPerSample,\n\t\t\tInputFormat.IsFloat, numsamples, true);\n\t}\n\telse if (channels == InputFormat.Channels)\n\t{\n\t\tTVPConvertPCMTo16bits(dest, (const void*)src, InputFormat.Channels,\n\t\t\tInputFormat.BytesPerSample, InputFormat.BitsPerSample,\n\t\t\tInputFormat.IsFloat, numsamples, false);\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_WaveSoundBuffer::GetVisBuffer(tjs_int16 *dest, tjs_int numsamples,\n\ttjs_int channels, tjs_int aheadsamples)\n{\n\t// read visualization buffer samples\n\tif(!UseVisBuffer) return 0;\n\tif(!VisBuffer) return 0;\n\tif(!Decoder) return 0;\n\tif(!SoundBuffer) return 0;\n\tif(!DSBufferPlaying || !BufferPlaying) return 0;\n\n\tif (channels != InputFormat.Channels && channels != 1) return 0;\n\n\t// retrieve current playing position\n\n\ttjs_int buffersamples = BufferBytes / (InputFormat.Channels * InputFormat.BytesPerSample);\n\tint offset;\n\t//DWORD wp, pp;\n\t{\n\t\ttTJSCriticalSectionHolder holder(BufferCS);\n\t\t// the critical section protects only here;\n\t\t// the rest is not important code (does anyone care about that the retrieved\n\t\t// visualization becomes wrong a little ?)\n\t\toffset = SoundBuffer->GetCurrentPlaySamples() + aheadsamples;\n\t\tint rblock = offset / AccessUnitSamples;\n\t\toffset %= buffersamples;\n\t\tif (L1BufferSegmentQueues[rblock % L1BufferUnits].GetFilteredLength() == 0)\n\t\t\treturn 0;\n#if 0\n\t\tif(FAILED(SoundBuffer->GetCurrentPosition(&pp, &wp))) return 0;\n\n\t\tpp += aheadsamples * Format.Format.nBlockAlign;\n\t\tpp = pp % BufferBytes;\n\n\t\tif(L1BufferSegmentQueues[pp/AccessUnitBytes].GetFilteredLength() == 0)\n\t\t\treturn 0;\n#endif\n\t}\n#if 0\n\tpp /= Format.Format.nBlockAlign;\n\n\ttjs_int buffersamples = BufferBytes / Format.Format.nBlockAlign;\n#endif\n\t// copy to distination buffer\n\ttjs_int writtensamples = 0;\n\tif(numsamples > 0)\n\t{\n\t\twhile(true)\n\t\t{\n\t\t\ttjs_int bufrest = buffersamples - offset;\n\t\t\ttjs_int copysamples = (bufrest > numsamples ? numsamples : bufrest);\n\n\t\t\tCopyVisBuffer(dest, VisBuffer + offset * InputFormat.Channels * InputFormat.BytesPerSample,\n\t\t\t\tcopysamples, channels);\n\n\t\t\tnumsamples -= copysamples;\n\t\t\twrittensamples += copysamples;\n\t\t\tif(numsamples <= 0) break;\n\n\t\t\tdest += channels * copysamples;\n\t\t\toffset += copysamples;\n\t\t\toffset = offset % buffersamples;\n\t\t}\n\t}\n\n\treturn writtensamples;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_WaveSoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_WaveSoundBuffer::CreateNativeInstance()\n{\n\treturn new tTJSNI_WaveSoundBuffer();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_WaveSoundBuffer\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_WaveSoundBuffer()\n{\n\ttTJSNativeClass *cls = new tTJSNC_WaveSoundBuffer();\n\tstatic tjs_uint32 TJS_NCM_CLASSID;\n\tTJS_NCM_CLASSID = tTJSNC_WaveSoundBuffer::ClassID;\n\n//----------------------------------------------------------------------\n// methods\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/freeDirectSound)  /* static */\n{\n\t// release directsound\n\tTVPReleaseDirectSound();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/freeDirectSound)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getVisBuffer)\n{\n\t// get samples for visualization \n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\ttjs_int16 *dest = (tjs_int16*)(tjs_int64)(*param[0]);\n\n\ttjs_int ahead = 0;\n\tif(numparams >= 4) ahead = (tjs_int)*param[3];\n\n\ttjs_int res = _this->GetVisBuffer(dest, *param[1], *param[2], ahead);\n\n\tif(result) *result = res;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(/*object to register*/cls,\n\t/*func. name*/getVisBuffer)\n//----------------------------------------------------------------------\n\n\n\n//----------------------------------------------------------------------\n// properties\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(useVisBuffer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t*result = _this->GetUseVisBuffer();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t\t/*var. type*/tTJSNI_WaveSoundBuffer);\n\n\t\t_this->SetUseVisBuffer(0!=(tjs_int)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, useVisBuffer)\n//----------------------------------------------------------------------\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/sound/win32/WaveImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Wave Player implementation\n//---------------------------------------------------------------------------\n#ifndef WaveImplH\n#define WaveImplH\n\n#define DIRECTSOUND_VERSION 0x0300\n#if 0\n#include <mmsystem.h>\n#include <dsound.h>\n#include <ks.h>\n#include <ksmedia.h>\n#endif\n#include \"WaveIntf.h\"\n#include \"WaveLoopManager.h\"\n\n/*[*/\n//---------------------------------------------------------------------------\n// IDirectSound former declaration\n//---------------------------------------------------------------------------\n#ifndef __DSOUND_INCLUDED__\nstruct IDirectSound;\n#endif\nclass iTVPSoundBuffer;\n\n\n/*]*/\n\n//---------------------------------------------------------------------------\n// Constants\n//---------------------------------------------------------------------------\n\n#define TVP_WSB_ACCESS_FREQ (8)  // wave sound buffer access frequency (hz)\n\n#define TVP_TIMEOFS_INVALID_VALUE ((tjs_int)(- 2147483648LL)) // invalid value for 32bit time offset\n\n//---------------------------------------------------------------------------\n\nTJS_EXP_FUNC_DEF(void, TVPReleaseDirectSound, ());\nTJS_EXP_FUNC_DEF(IDirectSound *, TVPGetDirectSound, ());\nextern void TVPResetVolumeToAllSoundBuffer();\nextern void TVPSetWaveSoundBufferUse3DMode(bool b);\nextern bool TVPGetWaveSoundBufferUse3DMode();\nextern void TVPWaveSoundBufferCommitSettings();\n#if 0\nextern tjs_int TVPVolumeToDSAttenuate(tjs_int volume);\nextern tjs_int TVPDSAttenuateToVolume(tjs_int att);\nextern tjs_int TVPPanToDSAttenuate(tjs_int volume);\nextern tjs_int TVPDSAttenuateToPan(tjs_int att);\n#endif\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_WaveSoundBuffer : Wave Native Instance\n//---------------------------------------------------------------------------\nclass tTVPWaveLoopManager;\nclass tTVPWaveSoundBufferDecodeThread;\nclass tTJSNI_WaveSoundBuffer : public tTJSNI_BaseWaveSoundBuffer\n{\n\ttypedef  tTJSNI_BaseWaveSoundBuffer inherited;\n\npublic:\n\ttTJSNI_WaveSoundBuffer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\t//-- buffer management ------------------------------------------------\nprivate:\n\tiTVPSoundBuffer* SoundBuffer;\n#if 0\n\tLPDIRECTSOUND3DBUFFER Sound3DBuffer;\n#endif\n\tvoid ThrowSoundBufferException(const ttstr &reason);\n\tvoid TryCreateSoundBuffer(bool use3d);\n\tvoid CreateSoundBuffer();\n\tvoid DestroySoundBuffer();\n\tvoid ResetSoundBuffer();\n\tvoid ResetSamplePositions();\n\n#if 0\n\tWAVEFORMATEXTENSIBLE Format;\n#endif\n\ttTVPWaveFormat C_InputFormat;\n\ttTVPWaveFormat InputFormat;\n\n\ttjs_int BufferBytes;\n\ttjs_int AccessUnitBytes;\n\ttjs_int AccessUnitSamples;\n\ttjs_int L2AccessUnitBytes;\n\n\ttjs_int L2BufferUnits;\n\ttjs_int L1BufferUnits;\n\n\ttjs_int Level2BufferSize;\n\ttjs_uint8 *Level2Buffer;\npublic:\n\tvoid FreeDirectSoundBuffer(bool disableevent = true)\n\t{\n\t\t// called at exit ( system uninitialization )\n\t\tbool b = CanDeliverEvents;\n\t\tif(disableevent)\n\t\t\tCanDeliverEvents = false; // temporarily disables event derivering\n\t\tStop();\n\t\tDestroySoundBuffer();\n\t\tCanDeliverEvents = b;\n\t}\n\n\n\t//-- playing stuff ----------------------------------------------------\nprivate:\n\ttTJSCriticalSection BufferCS;\n\ttTJSCriticalSection L2BufferCS;\n\ttTJSCriticalSection L2BufferRemainCS;\n\npublic:\n\ttTJSCriticalSection & GetBufferCS() { return BufferCS; }\n\nprivate:\n\ttTVPWaveDecoder * Decoder;\n\ttTVPWaveSoundBufferDecodeThread * Thread;\npublic:\n\tbool ThreadCallbackEnabled;\nprivate:\n\tbool BufferPlaying; // whether this sound buffer is playing\n\tbool DSBufferPlaying; // whether the DS buffer is 'actually' playing\n\tbool Paused;\n\n\tbool UseVisBuffer;\n\n\ttjs_int SoundBufferPrevReadPos;\n\ttjs_int SoundBufferWritePos;\n\ttjs_int PlayStopPos; // in bytes\n\n\ttjs_int L2BufferReadPos; // in unit\n\ttjs_int L2BufferWritePos;\n\ttjs_int L2BufferRemain;\n\tbool L2BufferEnded;\n\ttjs_uint8 *VisBuffer; // buffer for visualization\n\ttjs_int *L2BufferDecodedSamplesInUnit;\n\ttTVPWaveSegmentQueue *L1BufferSegmentQueues;\n\tstd::vector<tTVPWaveLabel> LabelEventQueue;\n\ttjs_int64 *L1BufferDecodeSamplePos;\n\ttTVPWaveSegmentQueue *L2BufferSegmentQueues;\n\n\ttjs_int64 DecodePos; // decoded samples from directsound buffer play\n\ttjs_int64 LastCheckedDecodePos; // last sured position (-1 for not checked) and \n\ttjs_uint64 LastCheckedTick; // last sured tick time\n\n\tbool Looping;\n\n\tvoid Clear();\n\n\ttjs_uint Decode(void *buffer, tjs_uint bufsamplelen,\n\t\ttTVPWaveSegmentQueue & segments);\n\npublic:\n\tbool FillL2Buffer(bool firstwrite, bool fromdecodethread);\n\nprivate:\n\tvoid PrepareToReadL2Buffer(bool firstread);\n\ttjs_uint ReadL2Buffer(void *buffer,\n\t\ttTVPWaveSegmentQueue & segments);\n\n\tvoid FillDSBuffer(tjs_int writepos,\n\t\ttTVPWaveSegmentQueue & segments);\npublic:\n\tbool FillBuffer(bool firstwrite = false, bool allowpause = true);\n\nprivate:\n\tvoid ResetLastCheckedDecodePos(uint32_t pp = (uint32_t) - 1);\n\npublic:\n\ttjs_int FireLabelEventsAndGetNearestLabelEventStep(tjs_int64 tick);\n\ttjs_int GetNearestEventStep();\n\tvoid FlushAllLabelEvents();\n\nprivate:\n\tvoid StartPlay();\n\tvoid StopPlay();\n\npublic:\n\tvoid Play();\n\tvoid Stop();\n\tvoid SetBufferPaused(bool bPaused);\n\n\tbool GetPaused() const { return Paused; }\n\tvoid SetPaused(bool b);\n\n\ttjs_int GetBitsPerSample() const {\n\t\treturn InputFormat.BitsPerSample;\n#if 0\n\t\tif(Format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)\n\t\t\treturn Format.Samples.wValidBitsPerSample;\n\t\telse\n\t\t\treturn Format.Format.wBitsPerSample;\n#endif\n\t}\n\ttjs_int GetChannels() const { return InputFormat.Channels; }\n\nprotected:\n\tvoid TimerBeatHandler(); // override\n\npublic:\n\tvoid Open(const ttstr & storagename);\n\npublic:\n\tvoid SetLooping(bool b);\n\tbool GetLooping() const { return Looping; }\n\n    tjs_uint64 GetSamplePosition();\n\tvoid SetSamplePosition(tjs_uint64 pos);\n\n    tjs_uint64 GetPosition();\n\tvoid SetPosition(tjs_uint64 pos);\n\n\ttjs_uint64 GetTotalTime();\n\n\t//-- volume/pan/3D position/freq stuff -------------------------------------\nprivate:\n\ttjs_int Volume;\n\ttjs_int Volume2;\n\ttjs_int Frequency;\n\tstatic tjs_int GlobalVolume;\n\tstatic tTVPSoundGlobalFocusMode GlobalFocusMode;\n\n\tbool BufferCanControlPan;\n\tbool BufferCanControlFrequency;\n\ttjs_int Pan; // -100000 .. 0 .. 100000\n\tD3DVALUE PosX, PosY, PosZ; // 3D position\n\npublic:\n\tvoid SetVolumeToSoundBuffer();\n\npublic:\n\tvoid SetVolume(tjs_int v);\n\ttjs_int GetVolume() const { return Volume; }\n\tvoid SetVolume2(tjs_int v);\n\ttjs_int GetVolume2() const { return Volume2; }\n\tvoid SetPan(tjs_int v);\n\ttjs_int GetPan() const { return Pan; }\n\tstatic void SetGlobalVolume(tjs_int v);\n\tstatic tjs_int GetGlobalVolume() { return GlobalVolume; }\n\tstatic void SetGlobalFocusMode(tTVPSoundGlobalFocusMode b);\n\tstatic tTVPSoundGlobalFocusMode GetGlobalFocusMode()\n\t\t{ return GlobalFocusMode; }\n\nprivate:\n\tvoid Set3DPositionToBuffer();\npublic:\n\tvoid SetPos(D3DVALUE x, D3DVALUE y, D3DVALUE z);\n\tvoid SetPosX(D3DVALUE v);\n\tD3DVALUE GetPosX() const {return PosX;}\n\tvoid SetPosY(D3DVALUE v);\n\tD3DVALUE GetPosY() const {return PosY;}\n\tvoid SetPosZ(D3DVALUE v);\n\tD3DVALUE GetPosZ() const {return PosZ;}\n\nprivate:\n\tvoid SetFrequencyToBuffer();\npublic:\n\ttjs_int GetFrequency() const { return Frequency; }\n\tvoid SetFrequency(tjs_int freq);\n\n\t//-- visualization stuff ----------------------------------------------\npublic:\n\tvoid SetUseVisBuffer(bool b);\n\tbool GetUseVisBuffer() const { return UseVisBuffer; }\n\nprotected:\n\tvoid ResetVisBuffer(); // reset or recreate visualication buffer\n\tvoid DeallocateVisBuffer();\n\n\tvoid CopyVisBuffer(tjs_int16 *dest, const tjs_uint8 *src,\n\t\ttjs_int numsamples, tjs_int channels);\npublic:\n\ttjs_int GetVisBuffer(tjs_int16 *dest, tjs_int numsamples, tjs_int channels,\n\t\ttjs_int aheadsamples);\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/WaveMixer.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"WaveMixer.h\"\n#ifdef __APPLE__\n#include <OpenAL/al.h>\n#include <OpenAL/alc.h>\n#else\n#include \"AL/alc.h\"\n#include \"AL/alext.h\"\n#endif\n#ifdef __ANDROID__\n#include \"oboe/Oboe.h\"\n#endif\n#include <string.h>\n#include <math.h>\n#include \"WaveImpl.h\"\n#include <assert.h>\n#include \"SysInitIntf.h\"\n#include \"TickCount.h\"\n#include <sstream>\n#include <iomanip>\n#include \"DebugIntf.h\"\n#include \"SDL2/SDL.h\"\n#include <unordered_set>\n#include <algorithm>\n\nclass iTVPAudioRenderer;\nstatic iTVPAudioRenderer *TVPAudioRenderer;\n\ntemplate<int ch>\nvoid MixAudioS16CPP(void *dst, const void *src, int samples, int16_t *volume) {\n\tint16_t *dst16 = (int16_t *)dst;\n\tconst int16_t *src16 = (const int16_t *)src;\n\twhile (samples--) {\n\t\tfor (int i = 0; i < ch; ++i) {\n\t\t\tint src_sample = *src16++;\n\t\t\tsrc_sample = (src_sample * volume[i]) >> 14;\n\t\t\tint dest_sample = *dst16;\n\t\t\tif (src_sample > 0 && dest_sample > 0) {\n\t\t\t\tdest_sample = src_sample + dest_sample - ((dest_sample * src_sample + 0x8000) >> 15);\n\t\t\t} else if (src_sample < 0 && dest_sample < 0) {\n\t\t\t\tdest_sample = src_sample + dest_sample + ((dest_sample * src_sample) >> 15);\n\t\t\t} else {\n\t\t\t\tdest_sample += src_sample;\n\t\t\t}\n\t\t\t*dst16++ = dest_sample;\n\t\t}\n\t}\n}\n\ntemplate<int ch>\nvoid MixAudioF32CPP(void *dst, const void *src, int samples, int16_t *volume) {\n\tfloat *dst32 = (float *)dst;\n\tconst float *src32 = (const float *)src;\n\tconst float fmaxvolume = 1.0f / 16384/*tTVPSoundBuffer::MAX_VOLUME*/;\n\tfloat fvolume[ch];\n\tfor (int i = 0; i < ch; ++i)\n\t\tfvolume[i] = volume[i] * fmaxvolume;\n\twhile (samples--) {\n\t\tfor (int i = 0; i < ch; ++i) {\n\t\t\tfloat src_sample = SDL_SwapFloatLE(*src32++) * fvolume[i];\n\t\t\tfloat dest_sample = SDL_SwapFloatLE(*dst32);\n\t\t\tif (src_sample > 0 && dest_sample > 0) {\n\t\t\t\tdest_sample = src_sample + dest_sample - dest_sample * src_sample;\n\t\t\t} else if (src_sample < 0 && dest_sample < 0) {\n\t\t\t\tdest_sample = src_sample + dest_sample + dest_sample * src_sample;\n\t\t\t} else {\n\t\t\t\tdest_sample += src_sample;\n\t\t\t}\n\t\t\t*(dst32++) = SDL_SwapFloatLE(dest_sample);\n\t\t}\n\t}\n}\n\ntypedef void(FAudioMix)(void *dst, const void *src, int samples, int16_t *volume);\nstatic FAudioMix *_AudioMixS16[8] = { // 7.1 max\n\t&MixAudioS16CPP<1>,\n\t&MixAudioS16CPP<2>,\n\t&MixAudioS16CPP<3>,\n\t&MixAudioS16CPP<4>,\n\t&MixAudioS16CPP<5>,\n\t&MixAudioS16CPP<6>,\n\t&MixAudioS16CPP<7>,\n\t&MixAudioS16CPP<8>\n};\nstatic FAudioMix *_AudioMixF32[8] = { // 7.1 max\n\t&MixAudioF32CPP<1>,\n\t&MixAudioF32CPP<2>,\n\t&MixAudioF32CPP<3>,\n\t&MixAudioF32CPP<4>,\n\t&MixAudioF32CPP<5>,\n\t&MixAudioF32CPP<6>,\n\t&MixAudioF32CPP<7>,\n\t&MixAudioF32CPP<8>\n};\n\nextern \"C\" void TVPWaveMixer_ASM_Init(FAudioMix **func16, FAudioMix **func32);\n\nclass tTVPSoundBuffer : public iTVPSoundBuffer {\npublic:\n\tbool _playing = false;\n\tfloat _volume = 1;\n\tfloat _pan = 0;\n\tconst signed int MAX_VOLUME = 16384; // limit in signed 16bit\n\tint16_t _volume_raw[8];\n\tSDL_AudioCVT *_cvt = nullptr;\n\tstd::vector<uint8_t> _cvtbuf;\n\tint _frame_size = 0;\n\n\tvoid RecalcVolume() {\n\t\tif (_pan > 0) {\n\t\t\t_volume_raw[0] = (1.0f - _pan) * _volume * MAX_VOLUME;\n\t\t} else {\n\t\t\t_volume_raw[0] = _volume * MAX_VOLUME;\n\t\t}\n\t\tif (_pan < 0) {\n\t\t\t_volume_raw[1] = (_pan + 1.0f) * _volume * MAX_VOLUME;\n\t\t} else {\n\t\t\t_volume_raw[1] = _volume * MAX_VOLUME;\n\t\t}\n\t\t_volume_raw[2] = _volume_raw[0]; // for SIMD\n\t\t_volume_raw[3] = _volume_raw[1];\n\t}\n\tstd::mutex _buffer_mtx;\n\tstd::deque<std::vector<uint8_t> > _buffers;\n\ttjs_uint _sendedFrontBuffer = 0;\n\ttjs_uint _sendedSamples = 0, _inCachedSamples = 0;\n\n\ttTVPSoundBuffer(int framesize, SDL_AudioCVT *cvt) : _frame_size(framesize), _cvt(cvt) {\n\t\tRecalcVolume();\n\t\tif (cvt) {\n\t\t\t_cvtbuf.resize(/*2352*/ 2400 * 2 * 4 * _cvt->len_mult); // IEEE f.32 stereo 48000kHz\n\t\t\t_cvt->buf = &_cvtbuf.front();\n\t\t}\n\t}\n\tvirtual ~tTVPSoundBuffer();\n\tvirtual void Release() override { delete this; }\n\tvirtual void Play() override {\n\t\t_playing = true;\n\t}\n\tvirtual void Pause() override {\n\t\t_playing = false;\n\t}\n\tvirtual void Stop() override {\n\t\t_playing = false;\n\t\tReset();\n\t}\n\tvirtual void Reset() override {\n\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\t\t_buffers.clear();\n\t\t_inCachedSamples = 0;\n\t\t_sendedFrontBuffer = 0;\n\t\t_sendedSamples = 0;\n\t}\n\tvirtual bool IsPlaying() override {\n\t\treturn _playing;\n\t}\n\tvirtual void SetVolume(float v) override {\n\t\t_volume = v;\n\t\tRecalcVolume();\n\t}\n\tvirtual float GetVolume() override { return _volume; }\n\tvirtual void SetPan(float v) override {\n\t\t_pan = v;\n\t\tRecalcVolume();\n\t}\n\tvirtual float GetPan() override { return _pan; }\n\tvirtual void AppendBuffer(const void *_inbuf, unsigned int inlen/*, int tag = 0*/) override {\n\t\tif (_cvt) {\n\t\t\tstd::vector<uint8_t> buffer;\n\t\t\tuint8_t* inbuf = (uint8_t*)_inbuf;\n\t\t\tint buflen = _frame_size * 2352;\n\t\t\t_cvt->len = buflen;\n\t\t\twhile (inlen > buflen) { // fill 2352 samples to fit 48k/44.1k\n\t\t\t\tmemcpy(_cvt->buf, inbuf, buflen);\n\t\t\t\tSDL_ConvertAudio(_cvt);\n\t\t\t\tbuffer.insert(buffer.end(), _cvt->buf, _cvt->buf + _cvt->len_cvt);\n\t\t\t\tinlen -= buflen;\n\t\t\t\tinbuf += buflen;\n\t\t\t}\n\t\t\tif (inlen > 0) {\n\t\t\t\tint buflen = inlen;\n\t\t\t\tmemcpy(_cvt->buf, inbuf, buflen);\n\t\t\t\t_cvt->len = buflen;\n\t\t\t\tSDL_ConvertAudio(_cvt);\n\t\t\t\tbuffer.insert(buffer.end(), _cvt->buf, _cvt->buf + _cvt->len_cvt);\n\t\t\t}\n\t\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\t\t\t_inCachedSamples += buffer.size() / _frame_size;\n\t\t\t_buffers.emplace_back();\n\t\t\t_buffers.back().swap(buffer);\n\t\t} else {\n\t\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\t\t\t_buffers.emplace_back((uint8_t*)_inbuf, ((uint8_t*)_inbuf) + inlen);\n\t\t\t_inCachedSamples += inlen / _frame_size;\n\t\t}\n\t}\n\tvirtual bool IsBufferValid() override {\n\t\treturn true; // unlimited buffer size\n\t\t//return !_buffers.empty(); // thread safe if read only\n\t}\n\tvirtual tjs_uint GetLatencySamples() override;\n// \tvirtual void SetSampleOffset(tjs_uint n) override {\n// \t\t_sendedSamples = n;\n// \t}\n\tvirtual int GetRemainBuffers() override {\n\t\treturn _buffers.size();\n\t}\n\tvirtual tjs_uint GetCurrentPlaySamples() override;\n\tvirtual float GetLatencySeconds() override;\n\n\tvoid FillBuffer(uint8_t *out, int len);\n};\n\nclass iTVPAudioRenderer {\nprotected:\n\tSDL_AudioSpec _spec;\n\tstd::mutex _streams_mtx;\n\tstd::unordered_set<tTVPSoundBuffer*> _streams;\n\tint _frame_size = 0;\n\npublic:\n\tiTVPAudioRenderer() {\n\t\tmemset(&_spec, 0, sizeof(_spec));\n\t\t_spec.freq = 48000;\n\t\t_spec.format = AUDIO_S16;\n\t\t_spec.channels = 2;\n\t\t_spec.callback = [](void *p, Uint8 *s, int l) {\n\t\t\tmemset(s, 0, l);\n\t\t\t((iTVPAudioRenderer*)p)->FillBuffer(s, l);\n\t\t};\n\t\t_spec.userdata = this;\n\t\t_spec.size = 4;\n\t\t_frame_size = 4;\n\t}\n\tvoid InitMixer() {\n\t\tif (SDL_Init(SDL_INIT_AUDIO) < 0) { // for format converter\n\t\t\tSDL_Log(\"Fail to initialize audio.\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tFAudioMix *DoMixAudio;\n\tvoid SetupMixer() {\n\t\tTVPWaveMixer_ASM_Init(_AudioMixS16, _AudioMixF32);\n\t\tif (_spec.format == AUDIO_S16LSB) {\n\t\t\tDoMixAudio = _AudioMixS16[_spec.channels - 1];\n\t\t} else if (_spec.format == AUDIO_F32LSB) {\n\t\t\tDoMixAudio = _AudioMixF32[_spec.channels - 1];\n\t\t} else {\n\t\t\tDoMixAudio = [](void *dst, const void *src, int samples, int16_t *volume) {};\n\t\t}\n\t}\n\n\tvirtual bool Init() = 0;\n\n\tvirtual tTVPSoundBuffer* CreateStream(tTVPWaveFormat &fmt, int bufcount) {\n\t\tSDL_AudioSpec spec;\n\t\tmemset(&spec, 0, sizeof(spec));\n\t\tspec.freq = fmt.SamplesPerSec;\n\t\tspec.channels = fmt.Channels;\n\t\tif (fmt.IsFloat) {\n\t\t\tspec.format = AUDIO_F32LSB;\n\t\t} else {\n\t\t\tswitch (fmt.BitsPerSample) {\n\t\t\tcase 8: spec.format = AUDIO_S8; break;\n\t\t\tcase 16: spec.format = AUDIO_S16LSB; break;\n\t\t\tcase 32: spec.format = AUDIO_S32LSB; break;\n\t\t\tdefault: return nullptr;\n\t\t\t}\n\t\t}\n\t\tSDL_AudioCVT *cvt = nullptr;\n\t\tif (spec.freq != _spec.freq ||\n\t\t\tspec.channels != _spec.channels ||\n\t\t\tspec.format != _spec.format) {\n\t\t\tcvt = new SDL_AudioCVT;\n\t\t\tint err = SDL_BuildAudioCVT(cvt,\n\t\t\t\tspec.format, spec.channels, spec.freq,\n\t\t\t\t_spec.format, _spec.channels, _spec.freq);\n\t\t\tif (err != 1) {\n\t\t\t\tdelete cvt; return nullptr;\n\t\t\t}\n\t\t}\n\n\t\ttTVPSoundBuffer* s = new tTVPSoundBuffer(fmt.BytesPerSample * fmt.Channels, cvt);\n\t\tstd::lock_guard<std::mutex> lk(_streams_mtx);\n\t\t_streams.emplace(s);\n\t\treturn s;\n\t}\n\n\tvoid ReleaseStream(tTVPSoundBuffer* s) {\n\t\tstd::lock_guard<std::mutex> lk(_streams_mtx);\n\t\t_streams.erase(s);\n\t}\n\n\tvoid FillBuffer(Uint8 *buf, int len) {\n\t\t// memset(buf, 0, len);\n\t\tstd::lock_guard<std::mutex> lk(_streams_mtx);\n\t\tfor (tTVPSoundBuffer* s : _streams) {\n\t\t\ts->FillBuffer(buf, len);\n\t\t}\n\t}\n\n\tint MixAudio(uint8_t *dst, uint8_t *src, int len, int16_t *vol) {\n\t\tint samples = len / _frame_size;\n\t\tDoMixAudio(dst, src, samples, vol);\n\t\treturn samples;\n\t}\n\n\tconst SDL_AudioSpec& GetSpec() {\n\t\treturn _spec;\n\t}\n\n\tvirtual int32_t GetUnprocessedSamples() { return 0; }\n};\n\ntTVPSoundBuffer::~tTVPSoundBuffer()\n{\n\tStop();\n\tTVPAudioRenderer->ReleaseStream(this);\n\tif (_cvt) delete _cvt;\n}\n\ntjs_uint tTVPSoundBuffer::GetLatencySamples()\n{\n\tint32_t samples = TVPAudioRenderer->GetUnprocessedSamples();\n\treturn samples + _inCachedSamples;\n}\n\ntjs_uint tTVPSoundBuffer::GetCurrentPlaySamples()\n{\n\tint32_t samples = TVPAudioRenderer->GetUnprocessedSamples();\n\tif (samples > _sendedSamples) return 0;\n\treturn _sendedSamples - samples; // -GetLatencySamples();\n}\n\nfloat tTVPSoundBuffer::GetLatencySeconds()\n{\n\treturn GetLatencySamples() / TVPAudioRenderer->GetSpec().freq;\n}\n\nvoid tTVPSoundBuffer::FillBuffer(uint8_t *out, int len)\n{\n\tif (!_playing) return;\n\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\twhile (len > 0 && !_buffers.empty()) {\n\t\tstd::vector<uint8_t> &buf = _buffers.front();\n\t\tif (buf.size() > _sendedFrontBuffer) {\n\t\t\tint n = std::min((size_t)len, buf.size() - _sendedFrontBuffer);\n\t\t\tint samples = TVPAudioRenderer->MixAudio(out, &buf.front() + _sendedFrontBuffer, n, _volume_raw);\n\t\t\t_sendedSamples += samples;\n\t\t\t_inCachedSamples -= samples;\n\t\t\t_sendedFrontBuffer += n;\n\t\t\tout += n;\n\t\t\tlen -= n;\n\t\t}\n\t\tif (_sendedFrontBuffer >= buf.size()) {\n\t\t\t_sendedFrontBuffer = 0;\n\t\t\t_buffers.pop_front();\n\t\t}\n\t}\n}\n\nclass tTVPAudioRendererSDL : public iTVPAudioRenderer {\n\tSDL_AudioDeviceID _playback_id;\n\npublic:\n\tbool Init() override {\n\t\tInitMixer();\n\t\t_playback_id = SDL_OpenAudioDevice(nullptr, false, &_spec, &_spec, SDL_AUDIO_ALLOW_ANY_CHANGE);\n\t\tif (_playback_id <= 0) {\n\t\t\tSDL_Log(\"Fail to open audio @%dHz.\", _spec.freq);\n\t\t\treturn false;\n\t\t}\n\t\t_frame_size = SDL_AUDIO_BITSIZE(_spec.format) / 8 * _spec.channels;\n\t\tSDL_Log(\"Audio Device: %s\", SDL_GetCurrentAudioDriver());\n\t\tSDL_PauseAudioDevice(_playback_id, false);\n\t\tSetupMixer();\n\t\treturn true;\n\t}\n};\n\n#ifdef __ANDROID__\nclass tTVPAudioRendererOboe : public iTVPAudioRenderer, public oboe::AudioStreamCallback {\n\toboe::AudioStream *_oboeAudioStream = nullptr;\n\npublic:\n\tvirtual ~tTVPAudioRendererOboe() {\n\t\tif (_oboeAudioStream) delete _oboeAudioStream;\n\t}\n\n\tbool Init() override {\n\t\tInitMixer();\n\t\t// Create a builder\n\t\toboe::AudioStreamBuilder builder;\n\t\t//builder.setFormat(oboe::AudioFormat::I16);\n\t\tbuilder.setChannelCount(2);\n\t\t//builder.setSampleRate(oboe::kUnspecified);\n\t\tbuilder.setCallback(this);\n\t\t// \tbuilder.setPerformanceMode(PerformanceMode::None);\n\t\t// \tbuilder.setSharingMode(SharingMode::Shared);\n\t\toboe::Result result = builder.openStream(&_oboeAudioStream);\n// \t\tif (result != oboe::Result::OK) {\n// \t\t\t// try down sample rate\n// \t\t\t_spec.freq = 44100;\n// \t\t\tbuilder.setSampleRate(_spec.freq);\n// \t\t\tresult = builder.openStream(&_oboeAudioStream);\n// \t\t}\n\t\tif (result == oboe::Result::OK) {\n\t\t\t_spec.freq = _oboeAudioStream->getSampleRate();\n\t\t\tswitch (_oboeAudioStream->getFormat()) {\n\t\t\tcase oboe::AudioFormat::I16: _spec.format = AUDIO_S16LSB; break;\n\t\t\tcase oboe::AudioFormat::Float: _spec.format = AUDIO_F32LSB; break;\n\t\t\t}\n\t\t\t_frame_size = SDL_AUDIO_BITSIZE(_spec.format) / 8 * _spec.channels;\n\t\t\t_oboeAudioStream->requestStart();\n\t\t\tSDL_Log(\"Audio Device: Oboe @%dHz\", _spec.freq);\n\t\t\tSetupMixer();\n\t\t\treturn true;\n\t\t}\n\t\tSDL_Log(\"Fail to open Oboe audio\");\n\t\t// SetupSDL();\n\t\treturn false;\n\t}\n\n\tvirtual oboe::DataCallbackResult onAudioReady(\n\t\toboe::AudioStream *oboeStream,\n\t\tvoid *audioData,\n\t\tint32_t numFrames) override {\n\t\tint len = _frame_size * numFrames;\n\t\tmemset(audioData, 0, _frame_size * numFrames);\n\t\t//if (oboeStream == _oboeAudioStream)\n\t\t\tFillBuffer((uint8_t*)audioData, len);\n// \t\telse\n// \t\t\tfillCaptureBuffer((uint8_t*)audioData, /*Mono*/2 * numFrames);\n\t\treturn oboe::DataCallbackResult::Continue;\n\t}\n\n\tvirtual int32_t GetUnprocessedSamples() {\n\t\tint64_t hardwareFrameIndex;\n\t\tint64_t timeNanoseconds;\n\t\toboe::Result result = _oboeAudioStream->getTimestamp(CLOCK_MONOTONIC, &hardwareFrameIndex, &timeNanoseconds);\n\t\tif (result != oboe::Result::OK) { // OpenSL TODO accumulate calc\n\t\t\treturn 0;\n\t\t}\n\t\tint64_t appFrameIndex = _oboeAudioStream->getFramesWritten();\n\t\treturn appFrameIndex - hardwareFrameIndex;\n\t}\n};\n#endif\n\nclass tTVPSoundBufferAL : public tTVPSoundBuffer {\n\ttypedef tTVPSoundBuffer inherit;\n\n\tALuint _alSource;\n\tALenum _alFormat;\n\tALuint *_bufferIds, *_bufferIds2;\n\ttjs_uint *_bufferSize;\n\ttjs_uint _bufferCount;\n\tint _bufferIdx = -1;\n\ttTVPWaveFormat _format;\npublic:\n\ttTVPSoundBufferAL(tTVPWaveFormat &desired, int bufcount)\n\t\t: tTVPSoundBuffer(desired.BytesPerSample * desired.Channels, nullptr), _bufferCount(bufcount)\n\t{\n\t\t_bufferIds = new ALuint[bufcount];\n\t\t_bufferIds2 = new ALuint[bufcount];\n\t\t_bufferSize = new tjs_uint[bufcount];\n\t\t_format = desired;\n\t\talGenSources(1, &_alSource);\n\t\talGenBuffers(_bufferCount, _bufferIds);\n\t\talSourcef(_alSource, AL_GAIN, 1.0f);\n\t\tif (desired.Channels == 1) {\n\t\t\tswitch (desired.BitsPerSample) {\n\t\t\tcase 8:\n\t\t\t\t_alFormat = AL_FORMAT_MONO8;\n\t\t\t\tbreak;\n\t\t\tcase 16:\n\t\t\t\t_alFormat = AL_FORMAT_MONO16;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tassert(false);\n\t\t\t}\n\t\t} else if (desired.Channels == 2) {\n\t\t\tswitch (desired.BitsPerSample) {\n\t\t\tcase 8:\n\t\t\t\t_alFormat = AL_FORMAT_STEREO8;\n\t\t\t\tbreak;\n\t\t\tcase 16:\n\t\t\t\t_alFormat = AL_FORMAT_STEREO16;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tassert(false);\n\t\t\t}\n\t\t} else {\n\t\t\tassert(false);\n\t\t}\n\t}\n\n\tvirtual ~tTVPSoundBufferAL() {\n\t\talDeleteBuffers(_bufferCount, _bufferIds);\n\t\talDeleteSources(1, &_alSource);\n\t\tdelete[]_bufferIds;\n\t\tdelete[]_bufferIds2;\n\t\tdelete[]_bufferSize;\n\t}\n\n\tbool IsBufferValid() override {\n\t\tALint processed = 0;\n\t\talGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &processed);\n\t\tif (processed > 0) return true;\n\t\tALint queued = 0;\n\t\talGetSourcei(_alSource, AL_BUFFERS_QUEUED, &queued);\n\t\treturn queued < _bufferCount;\n\t}\n\n\tvirtual void AppendBuffer(const void *buf, unsigned int len/*, int tag = 0*/) override {\n\t\tif (len <= 0) return;\n\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\n\t\t/* First remove any processed buffers. */\n\t\tALint processed = 0;\n\t\talGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &processed);\n\t\tif (processed > 0) {\n\t\t\talSourceUnqueueBuffers(_alSource, processed, _bufferIds2);\n            checkerr(\"alSourceUnqueueBuffers\");\n\t\t\tfor (int i = 0; i < processed; ++i) {\n\t\t\t\tfor (int j = 0; j < _bufferCount; ++j) {\n\t\t\t\t\tif (_bufferIds[j] == _bufferIds2[i])\n\t\t\t\t\t{\n\t\t\t\t\t\t_sendedSamples += _bufferSize[j] / _frame_size;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* Refill the buffer queue. */\n\t\tALint queued = 0;\n\t\talGetSourcei(_alSource, AL_BUFFERS_QUEUED, &queued);\n\n\t\tif (queued >= _bufferCount)\n\t\t\treturn;\n\t\t++_bufferIdx;\n\t\tif (_bufferIdx >= _bufferCount) _bufferIdx = 0;\n\t\tALuint bufid = _bufferIds[_bufferIdx];\n\t\talBufferData(bufid, _alFormat, buf, len, _format.SamplesPerSec);\n        checkerr(\"alBufferData\");\n\t\talSourceQueueBuffers(_alSource, 1, &bufid);\n        checkerr(\"alSourceQueueBuffers\");\n\t\t//_tags[_bufferIdx] = tag;\n\t\t_bufferSize[_bufferIdx] = len;\n\t}\n\n\tvoid Reset() override {\n\t\tinherit::Reset();\n\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\t\talSourceRewind(_alSource);\n\t\talSourcei(_alSource, AL_BUFFER, 0);\n\t}\n\n\tvoid Pause() override {\n\t\talSourcePause(_alSource);\n        checkerr(\"Pause\");\n\t\t_playing = false;\n\t}\n    \n    static void checkerr(const char *funcname);\n\n\tvoid Play() override {\n\t\tALenum state;\n\t\talGetSourcei(_alSource, AL_SOURCE_STATE, &state);\n        checkerr(\"Play\");\n\t\tif (state != AL_PLAYING) {\n\t\t\talSourcePlay(_alSource);\n            checkerr(\"Play\");\n\t\t}\n\n\t\t_playing = true;\n\t}\n\n\tvoid Stop() override {\n\t\talSourceStop(_alSource);\n        checkerr(\"Stop\");\n\t\tReset();\n\t\t_bufferIdx = -1;\n\t\t_playing = false;\n\t}\n\n\tvoid SetVolume(float volume) override {\n\t\talSourcef(_alSource, AL_GAIN, volume);\n        checkerr(\"SetVolume\");\n\t}\n\n\tfloat GetVolume() override {\n\t\tfloat volume = 0;\n\t\talGetSourcef(_alSource, AL_GAIN, &volume);\n\t\treturn volume;\n\t}\n\n\tvoid SetPan(float pan) override {\n\t\tfloat sourcePosAL[] = { pan, 0.0f, 0.0f };\n\t\talSourcefv(_alSource, AL_POSITION, sourcePosAL);\n\t}\n\n\tfloat GetPan() override {\n\t\tfloat sourcePosAL[3];\n\t\talGetSourcefv(_alSource, AL_POSITION, sourcePosAL);\n\t\treturn sourcePosAL[0];\n\t}\n\n\tbool IsPlaying() override {\n\t\tALenum state;\n\t\talGetSourcei(_alSource, AL_SOURCE_STATE, &state);\n\t\treturn state == AL_PLAYING;\n\t}\n\n\tvoid SetPosition(float x, float y, float z) override {\n\t\tfloat sourcePosAL[] = { x, y, z };\n\t\talSourcefv(_alSource, AL_POSITION, sourcePosAL);\n        checkerr(\"SetPosition\");\n\t}\n\n\tint GetRemainBuffers() override {\n\t\tALint processed, queued = 0;\n\t\talGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &processed);\n\t\talGetSourcei(_alSource, AL_BUFFERS_QUEUED, &queued);\n\t\treturn queued - processed;\n\t}\n\n\ttjs_uint GetLatencySamples() override {\n\t\tstd::lock_guard<std::mutex> lk(_buffer_mtx);\n\t\tALint offset = 0, queued = 0;\n\t\talGetSourcei(_alSource, AL_BYTE_OFFSET, &offset);\n\t\talGetSourcei(_alSource, AL_BUFFERS_QUEUED, &queued);\n\t\tint remainBuffers = queued;\n\t\tif (remainBuffers == 0) return 0;\n\t\ttjs_int total = -offset;\n\t\tfor (int i = 0; i < remainBuffers; ++i) {\n\t\t\tint idx = _bufferIdx + 1 - remainBuffers + i;\n\t\t\tif (idx >= _bufferCount) idx -= _bufferCount;\n\t\t\telse if (idx < 0) idx += _bufferCount;\n\t\t\ttotal += _bufferSize[idx];\n\t\t}\n\t\treturn total / _frame_size;\n\t}\n\n\tvirtual float GetLatencySeconds() override {\n\t\treturn (float)GetLatencySamples() / _format.SamplesPerSec;\n\t}\n\n\tvirtual tjs_uint GetCurrentPlaySamples() override {\n\t\tALint offset = 0;\n\t\talGetSourcei(_alSource, AL_SAMPLE_OFFSET, &offset);\n\t\treturn _sendedSamples + offset;\n\t}\n};\n\nclass tTVPAudioRendererAL : public iTVPAudioRenderer {\n\tALCdevice *_device = nullptr;\n\tALCcontext *_context = nullptr;\npublic:\n\tvirtual ~tTVPAudioRendererAL() {\n\t\tif (_context) {\n\t\t\t//alDeleteSources(TVP_MAX_AUDIO_COUNT, _alSources);\n\t\t\talcMakeContextCurrent(nullptr);\n\t\t\talcDestroyContext(_context);\n\t\t}\n\t\tif (_device)\n\t\t\talcCloseDevice(_device);\n\t}\n\tbool Init() override {\n\t\tALboolean enumeration = alcIsExtensionPresent(NULL, \"ALC_ENUMERATION_EXT\");\n\t\tif (enumeration == AL_FALSE) {\n\t\t\t// enumeration not supported\n\t\t\t_device = alcOpenDevice(NULL);\n\t\t} else {\n\t\t\t// enumeration supported\n\t\t\tconst ALCchar *devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);\n\t\t\tstd::vector<std::string> alldev;\n\t\t\tttstr log(TJS_W(\"(info) Sound Driver/Device found : \"));\n\t\t\twhile (*devices) {\n\t\t\t\tTVPAddImportantLog(log + devices);\n\t\t\t\talldev.emplace_back(devices);\n\t\t\t\tdevices += alldev.back().length();\n\t\t\t}\n\t\t\t_device = alcOpenDevice(alldev[0].c_str());\n\t\t}\n\t\tif (!_device) return false;\n\n\t\t_context = alcCreateContext(_device, NULL);\n\t\talcMakeContextCurrent(_context);\n\n\t\treturn true;\n\t}\n\n\tvirtual tTVPSoundBuffer* CreateStream(tTVPWaveFormat &fmt, int bufcount) override {\n\t\ttTVPSoundBuffer* s = new tTVPSoundBufferAL(fmt, bufcount);\n\t\t_streams.emplace(s);\n\t\treturn s;\n\t}\n    \n    ALCcontext *GetContext() {\n        return _context;\n    }\n};\n\nvoid tTVPSoundBufferAL::checkerr(const char *funcname) {\n#if _DEBUG\n    ALCcontext *ctx = static_cast<tTVPAudioRendererAL*> (TVPAudioRenderer)->GetContext();\n    if (alcGetCurrentContext() != ctx) {\n        alcMakeContextCurrent(ctx);\n    }\n    ALenum err = alGetError();\n    if (AL_NO_ERROR == err) return;\n    SDL_Log(\"%s OpenAL Error %X\", funcname, err);\n#endif\n}\n\nstatic iTVPAudioRenderer *CreateAudioRenderer() {\n\tiTVPAudioRenderer *renderer = nullptr;\n#ifdef __ANDROID__\n\trenderer = new tTVPAudioRendererOboe;\n\tif (renderer->Init()) return renderer;\n\tdelete renderer;\n#elif defined(_MSC_VER) && 0\n\trenderer = new tTVPAudioRendererSDL;\n\trenderer->Init();\n\treturn renderer;\n#endif\n\trenderer = new tTVPAudioRendererAL;\n\trenderer->Init();\n\treturn renderer;\n}\n\nvoid TVPInitDirectSound(int freq)\n{\n\tif (!TVPAudioRenderer) {\n\t\tTVPAudioRenderer = CreateAudioRenderer();\n\t}\n\t//TVPInitSoundOptions();\n}\n\nvoid TVPUninitDirectSound()\n{\n\t// nothing to do\n}\n\niTVPSoundBuffer* TVPCreateSoundBuffer(tTVPWaveFormat &fmt, int bufcount)\n{\n\treturn TVPAudioRenderer->CreateStream(fmt, bufcount);\n}\n#if 0\nint TVPALSoundWrap::GetNextBufferIndex() {\n\tint n = _bufferIdx + 1;\n\tif (n >= TVPAL_BUFFER_COUNT) n = 0;\n\treturn n;\n}\n\nvoid TVPALSoundWrap::SetSampleOffset(tjs_uint n /*= 0*/) {\n\t_samplesProcessed = n;\n}\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/WaveMixer.h",
    "content": "#pragma once\n#include \"WaveIntf.h\"\n#include <list>\n#include <mutex>\n\n#define TVPAL_BUFFER_COUNT 4\n\nstruct ALSoundImpl;\nvoid TVPInitDirectSound(int freq = 48000);\nvoid TVPUninitDirectSound();\n\nclass iTVPSoundBuffer {\npublic:\n\tvirtual ~iTVPSoundBuffer() {}\n\tvirtual void Release() = 0;\n\tvirtual void Play() = 0;\n\tvirtual void Pause() = 0;\n\tvirtual void Stop() = 0;\n\tvirtual void Reset() = 0;\n\tvirtual bool IsPlaying() = 0;\n\tvirtual void SetVolume(float v) = 0;\n\tvirtual float GetVolume() = 0;\n\tvirtual void SetPan(float v) = 0;\n\tvirtual float GetPan() = 0;\n\tvirtual void AppendBuffer(const void *buf, unsigned int len/*, int tag = 0*/) = 0;\n\tvirtual bool IsBufferValid() = 0;\n\tvirtual tjs_uint GetCurrentPlaySamples() = 0;\n\tvirtual tjs_uint GetLatencySamples() = 0;\n\tvirtual float GetLatencySeconds() { return 0; }\n//\tvirtual void SetSampleOffset(tjs_uint n) = 0;\n\tvirtual int GetRemainBuffers() = 0;\n//\tvirtual int GetNextBufferIndex() = 0;\n\tvirtual void SetPosition(float x, float y, float z) {\n\t\t// not implemented\n\t}\n};\niTVPSoundBuffer* TVPCreateSoundBuffer(tTVPWaveFormat &fmt, int bufcount);\n#if 0\nclass TVPALSoundWrap : public iTVPSoundBuffer {\nprivate:\n\tALSoundImpl *_impl;\n\ttjs_uint _bufferSize[TVPAL_BUFFER_COUNT];\n\t//int _tags[TVPAL_BUFFER_COUNT];\n\tint _bufferIdx;\n\t//int _tagPoint;\n\ttjs_uint _samplesProcessed;\n\ttTVPWaveFormat SoundFormat;\n\tbool _inPlaying;\n\n\tstd::mutex _mutex;\nprotected:\n\tTVPALSoundWrap();\n\npublic:\n\tvirtual ~TVPALSoundWrap();\n\tstatic TVPALSoundWrap * Create(const tTVPWaveFormat &desired);\n\tvoid Release();\n\tvoid Update(); // callback from TVPSoundMixerList\n\tvirtual bool DoFillBuffer();\n\tvoid Init(const tTVPWaveFormat &desired);\n\n\tint GetNextBufferIndex();\n\tint GetRemainBuffers();\n\tint GetValidBuffers();\n\n\tvoid Reset();\n\tvoid Rewind();\n\tvoid Pause();\n\tvoid Play();\n\tvoid Stop();\n\tbool IsBufferValid();\n\tvoid AppendBuffer(const void *buf, unsigned int len/*, int tag = 0*/);\n\tvoid SetVolume(float vol); // 0 ~ 1\n\tfloat GetVolume();\n\tvoid SetPan(float pan); // -1 ~ 1\n\tfloat GetPan();\n\ttjs_uint GetCurrentSampleOffset();\n\tvoid SetSampleOffset(tjs_uint n = 0);\n\ttjs_uint GetUnprocessedSamples();\n\tbool IsPlaying();\n\tvoid SetPosition(float x, float y, float z);\n};\n#endif"
  },
  {
    "path": "src/core/sound/win32/kmp_pi.h",
    "content": "#ifndef KMP_PI_H\n#define KMP_PI_H\n\n/*\n\n     KbMedia Player Plugin wb_t@CieXgŁj\n\n*/\n\n#define KMPMODULE_VERSION 100 //KMPMODULE ̃o[W\n#define KMP_GETMODULE     kmp_GetTestModule  //܂eXg...\n#define SZ_KMP_GETMODULE \"kmp_GetTestModule\" //܂eXg...\n\ntypedef void* HKMP;//'K'b'M'edia 'P'layer Plugin  Handle\n\ntypedef struct\n{//I[vTEhf[^̏\n    DWORD dwSamplesPerSec;//TvOg(44100, 22050 Ȃ)\n    DWORD dwChannels;     //`l( mono = 1, stereo = 2)\n    DWORD dwBitsPerSample;//ʎqrbg( 8 or 16)\n    DWORD dwLength;       //Ȃ̒iSPC ̂悤ɌvZs\\ȏꍇ 0xFFFFFFFFj\n    DWORD dwSeekable;     //V[NT|[gĂꍇ 1AȂꍇ 0\n                          //iGcɃV[NłĂAV[N̍Đʒu\n                          // smȏꍇ 0 Ƃj\n    DWORD dwUnitRender;   //Render ֐̑R͂̒l̔{niǂȒlłǂꍇ 0j\n    DWORD dwReserved1;    // 0\n    DWORD dwReserved2;    // 0\n}SOUNDINFO;\n\n\ntypedef struct\n{\n    DWORD dwVersion;\n    //W[̃o[WBDLL ̃o[Wł͂ȂBK KMPMODULE_VERSION(=100) ɂ邱ƁB\n    //̒l KbMedia Player ҂lƈvȂꍇ́AKbMedia Player\n    //ɂĒ FreeLibrary Ă΂B\n    //̏ꍇAInitDll()  DeinitDll() Ă΂ȂƂɒӁB\n\n    DWORD dwPluginVersion;\n    //vOC̃o[W\n    //t@C̃vOCꍇ́A傫̂DIɎg\n\n\n    const char  *pszCopyright;\n    //쌠\n    //o[Wł̕̕\\\\\n    //NULL ɂĂ悢\n\n\n    const char  *pszDescription;\n    //\n    //o[Wł̕̕\\\\\n    //NULL ɂĂ悢\n\n\n    const char  **ppszSupportExts;\n    //T|[ggq̔̕z(sIh܂)\n    //NULL ŏI悤ɂ\n    //FppszSupportExts = {\".mp1\", \".mp2\", \".mp3\", \"rmp\", NULL};\n    //\n    //gqPȂꍇ́AKbMedia Player ɂĒ FreeLibrary \n    //΂B̏ꍇ InitDll()  DeinitDll() Ă΂ȂƂɒӁB\n\n\n    DWORD dwReentrant;\n    //vOCĐ\\Ȏdlȏꍇ 1, s\\ȏꍇ 0\n    //̊gqT|[gĂāÅgq͕Đ\\ł\n    //APłĐs\\Ȃ̂ꍇ 0 ɂ邱ƁB\n    //̒l 0 łĂAOpen ֐Ŗ߂nhLȊԂ Open Ă\n    //oĂA݉ťʂɉeyڂȂ悤ɂ邱ƁB\n    //IɃNXtF[hɑΉƂɂ̒lQƂ\\\n\n\n    void  (WINAPI *Init)(void);\n    //DLLBOpen ĂяoO KbMedia Player ɂĈxĂ΂B\n    //KvȂꍇ NULL ɂĂǂB\n    //o邾 DllMain  PROCESS_ATTACH 肱ŏiN̍̂߁j\n\n\n    void  (WINAPI *Deinit)(void);\n    //DLĽnBFreeLibrary ̒OɈxĂ΂B\n    //KvȂꍇ NULL ɂĂǂB\n    //InitDll() xĂ΂ DeinitDll() Ăԉ\\邱Ƃɒ\n\n\n    HKMP (WINAPI *Open)(const char *cszFileName, SOUNDINFO *pInfo);\n    //t@CJBK邱ƁB\n    //G[̏ꍇ NULL ԂB\n    //G[łȂꍇ pInfo ɓK؂ȏ邱ƁBK؂ȏ񂪓\n    //ȂꍇidwBits  0 Ȃǁj KbMedia Player ɂĒ Close\n    //Ă΂B\n    //pInfo  NULL ̏ꍇ͉Ȃ NULL Ԃ\n\n\n    HKMP (WINAPI *OpenFromBuffer)(const BYTE *Buffer, DWORD dwSize, SOUNDINFO *pInfo);\n    //JBT|[gȂꍇ NULL ɂ邱ƁB\n    //T|[gȂƂāA NULL Ԃ悤ɎĂ͂ȂȂB\n    //̊gqɑΉĂĂAPłT|[gȂgqꍇ\n    //NULL ɂȂ΂ȂȂB\n    //pInfo  NULL ̏ꍇ͉Ȃ NULL Ԃ\n    //̂ƂAKbMedia Player {̂ɑΉĂ܂B(^_^;\n\n    void   (WINAPI *Close)(HKMP hKMP);\n    //nhBK邱ƁB\n    //hKMP  NULL nĂvȂ悤ɂ邱ƁB\n\n\n    DWORD  (WINAPI *Render)(HKMP hKMP, BYTE* Buffer, DWORD dwSize);\n    //Buffer  PCM BK邱ƁB\n    //dwSize ̓obt@̃TCỸoCgBiTvł͂Ȃj\n    //߂l Buffer ɏ񂾃oCgBiTvł͂Ȃj\n    //dwSize 菬lԂ牉tIB\n    //dwSize  SOUNDINFO::dwUnitRender ̔{nB\n    //idwUnitRender ̒l̂̂ł͂ȂA{̉\\邱ƂɒӁj\n    //\n    //Buffer  NULL  dwSize  0 łȂꍇ́AdwSize tʒu\n    //i߂邱ƁBIĂ͂ȂB\n    //V[NT|[gȂꍇɁA_~[ Render JԂs\n    //ɃV[N鏈邽߁BƂĂA܂{̂̕\n    //Buffer  NULL nƂ͂ȂǁB(^^;\n    //\n    //hKMP  NULL nꍇ͉Ȃ 0 Ԃ悤ɂ邱ƁB\n\n\n    DWORD  (WINAPI *SetPosition)(HKMP hKMP, DWORD dwPos);\n    //V[NBK邱ƁB\n    //dwPos ̓V[N̍ĐʒuB߂l̓V[N̍ĐʒuBPʂ̓~bB\n    //dwPos Ɩ߂l͊SɈvKv͂ȂB߂lƖ{̍Đʒu\n    //덷傫Ȃi̎Ƃ̓ĐɎxjꍇ Open \n    //SOUNDINFO  dwSeekable  0 ɂĂƁB덷ȂAĂ\n    //ɏꍇ dwSeekable  1 ɂĂƁB߂lmȂ\n    //΁AdwPos Ɩ߂l̍傫Ă dwSeekable=1 ƂėǂB\n    //̂ƂAKbMeida Player {̂ dwSeekable ̒lĂ܂B(^_^;\n    //dwSeekable ̒lɂāA̎f[^ƓĐƂƂȂƂ\n    //V[Nς\\B\n    //\n    //V[NST|[gȂꍇ́A擪ʒuɖ߂ 0 ԂƁB\n    //hKMP  NULL nꍇ 0 Ԃ悤ɂ邱ƁB\n\n\n}KMPMODULE;\n\ntypedef KMPMODULE* (WINAPI *pfnGetKMPModule)(void);\n\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/oldwaveunpacker.h",
    "content": "#ifndef TVP_IWAVEUNPACKER_DEFINED\n#define TVP_IWAVEUNPACKER_DEFINED\nclass IWaveUnpacker\n{\npublic:\n// IUnknown hNXł͂Ȃ̂Œ\n\tvirtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;\n\tvirtual ULONG STDMETHODCALLTYPE Release(void) = 0;\n\n// IWaveUnpacker\n\tvirtual HRESULT STDMETHODCALLTYPE GetTypeName(char *buf,long buflen)=0;\n\t\t/*\n\t\t\tbuf ɁA Wave `\\ *buf ɐݒ肵ĂB\n\t\t\tbuflen ́Abuf ɊmۂꂽŁAnull terminater ܂ނ̂\n\t\t\tӁB\n\t\t*/\n\n\tvirtual HRESULT STDMETHODCALLTYPE GetWaveFormat(long *samplepersec,\n\t\tlong *channels,long *bitspersample)=0;\n\t\t/*\n\t\t\to͂ Wave ̌` *samplepersec, *channels, *bitspersample \n\t\t\tԂĂB\n\t\t*/\n\n\tvirtual HRESULT STDMETHODCALLTYPE Render(void *buffer,long bufsize,\n\t\tlong *numwrite) =0;\n\t\t/*\n\t\t\tfR[hĂB\n\t\t\tbufsize ɂ buffer ̃TCYoCgPʂŎw肳܂B\n\t\t\tnumwrite ɂ́Aobt@ɏꂽf[^̐oCgPʂŕԂ܂B\n\t\t\tAWaveUnpacker ́Anumwrite<bufsize ̏ꍇ́Ac\n\t\t\t0 Ŗ߂ĂB\n\t\t*/\n\t\n\tvirtual HRESULT STDMETHODCALLTYPE GetLength(long *length)=0;\n\t\t/*\n\t\t\tf[^ ms Pʂ *length ɕԂĂB\n\t\t\tΉłȂꍇ E_NOTIMPL ԂĂB̏ꍇ\n\t\t\tWaveSoundBuffer  totalTime vpeB 0 \\悤ɂȂ܂B\n\t\t*/\n\n\tvirtual HRESULT STDMETHODCALLTYPE GetCurrentPosition(long *pos)=0;\n\t\t/*\n\t\t\t݂̃fR[hʒu *pos ɕԂĂB\n\t\t\tΉłȂꍇ E_NOTIMPL ԂĂB̏ꍇ\n\t\t\tWaveSoundBuffer  position vpeB͈Ӗ̂Ȃl\n\t\t\t悤ɂȂ܂B\n\t\t*/\n\n\tvirtual HRESULT STDMETHODCALLTYPE SetCurrentPosition(long pos)=0;\n\t\t/*\n\t\t\t݂̃fR[hʒuݒ肵ĂBpos  ms Pʂł\n\t\t\tʒułB\n\t\t\tŒł pos=0 ƂČĂ΂ꂽƂɁA擪ւ̊߂\n\t\t\to悤ɂĂB\n\n\t\t\t̂ق̏ꍇAΉłȂꍇ E_NOTIMPL ԂĂB\n\t\t\t̏ꍇWaveSoundBuffer  position vpeBւ͖̑܂B\n\t\t*/\n\n\tvirtual HRESULT STDMETHODCALLTYPE Invoke(); // reserved\n};\n\n#endif\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/sound/win32/tvpsnd.c",
    "content": "/* this file contains the actual definitions of */\n/* the IIDs and CLSIDs */\n\n/* link this file in with the server and any clients */\n\n\n/* File created by MIDL compiler version 5.01.0164 */\n/* at Tue Oct 03 00:37:04 2000\n */\n/* Compiler settings for tvpsnd.idl:\n    Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext\n    error checks: allocation ref bounds_check enum stub_data \n*/\n//@@MIDL_FILE_HEADING(  )\n#ifdef __cplusplus\nextern \"C\"{\n#endif \n\n\n#ifndef __IID_DEFINED__\n#define __IID_DEFINED__\n\ntypedef struct _IID\n{\n    unsigned long x;\n    unsigned short s1;\n    unsigned short s2;\n    unsigned char  c[8];\n} IID;\n\n#endif // __IID_DEFINED__\n\n#ifndef CLSID_DEFINED\n#define CLSID_DEFINED\ntypedef IID CLSID;\n#endif // CLSID_DEFINED\n\nconst IID LIBID_TVPSndSysLib = {0xF09B2E87,0x740A,0x4AEA,{0x90,0xCB,0xAE,0x1C,0x4E,0xFD,0x35,0xF1}};\n\n\nconst IID IID_ITSSMediaBaseInfo = {0xB4C4239B,0x7D27,0x43CC,{0x85,0x23,0x66,0x95,0x5B,0xDF,0x59,0xDF}};\n\n\nconst IID IID_ITSSStorageProvider = {0x7DD61993,0x615D,0x481D,{0xB0,0x60,0xA9,0xFD,0x48,0x39,0x44,0x30}};\n\n\nconst IID IID_ITSSModule = {0xA938D1A5,0x2980,0x498B,{0xB0,0x51,0x99,0x93,0x1D,0x41,0x89,0x5D}};\n\n\nconst IID IID_ITSSWaveDecoder = {0x313864E2,0x910E,0x496F,{0x8A,0x6D,0x43,0x46,0x5C,0x10,0x5B,0x58}};\n\n\n#ifdef __cplusplus\n}\n#endif\n\n"
  },
  {
    "path": "src/core/sound/win32/tvpsnd.cpp",
    "content": "/* this file contains the actual definitions of */\n/* the IIDs and CLSIDs */\n\n/* link this file in with the server and any clients */\n\n\n/* File created by MIDL compiler version 5.01.0164 */\n/* at Tue Oct 03 00:37:04 2000\n */\n/* Compiler settings for tvpsnd.idl:\n    Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext\n    error checks: allocation ref bounds_check enum stub_data \n*/\n//@@MIDL_FILE_HEADING(  )\n#include \"combase.h\"\n#ifdef __cplusplus\nextern \"C\"{\n#endif \n\n\textern const IID LIBID_TVPSndSysLib = { 0xF09B2E87, 0x740A, 0x4AEA, { 0x90, 0xCB, 0xAE, 0x1C, 0x4E, 0xFD, 0x35, 0xF1 } };\n\n\textern const IID IID_ITSSMediaBaseInfo = { 0xB4C4239B, 0x7D27, 0x43CC, { 0x85, 0x23, 0x66, 0x95, 0x5B, 0xDF, 0x59, 0xDF } };\n\n\textern const IID IID_ITSSStorageProvider = { 0x7DD61993, 0x615D, 0x481D, { 0xB0, 0x60, 0xA9, 0xFD, 0x48, 0x39, 0x44, 0x30 } };\n\n\textern const IID IID_ITSSModule = { 0xA938D1A5, 0x2980, 0x498B, { 0xB0, 0x51, 0x99, 0x93, 0x1D, 0x41, 0x89, 0x5D } };\n\n\textern const IID IID_ITSSWaveDecoder = { 0x313864E2, 0x910E, 0x496F, { 0x8A, 0x6D, 0x43, 0x46, 0x5C, 0x10, 0x5B, 0x58 } };\n\n    extern const IID IID_IUnknown = {0,0,0,{0, 0xc0, 0, 0, 0, 0x46}};//00000000-0000-0000-C000-000000000046\n    extern const IID IID_IStream = {0xC,0,0,{0, 0xc0, 0, 0, 0, 0x46}};//0000000C-0000-0000-C000-000000000046\n    extern const IID IID_ISequentialStream = {0x0c733a30,0x2a1c,0x11ce,{0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d}};\n#ifdef __cplusplus\n}\n#endif\n\n"
  },
  {
    "path": "src/core/sound/win32/tvpsnd.h",
    "content": "/* this ALWAYS GENERATED file contains the definitions for the interfaces */\n\n\n/* File created by MIDL compiler version 5.01.0164 */\n/* at Tue Oct 03 00:37:04 2000\n */\n/* Compiler settings for tvpsnd.idl:\n    Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext\n    error checks: allocation ref bounds_check enum stub_data \n*/\n//@@MIDL_FILE_HEADING(  )\n\n\n/* verify that the <rpcndr.h> version is high enough to compile this file*/\n#ifndef __REQUIRED_RPCNDR_H_VERSION__\n#define __REQUIRED_RPCNDR_H_VERSION__ 440\n#endif\n\n//#include \"rpc.h\"\n//#include \"rpcndr.h\"\n\n#ifndef __tvpsnd_h__\n#define __tvpsnd_h__\n\n#ifdef __cplusplus\nextern \"C\"{\n#endif \n\n/* Forward Declarations */ \n\n#ifndef __ITSSMediaBaseInfo_FWD_DEFINED__\n#define __ITSSMediaBaseInfo_FWD_DEFINED__\ntypedef interface ITSSMediaBaseInfo ITSSMediaBaseInfo;\n#endif \t/* __ITSSMediaBaseInfo_FWD_DEFINED__ */\n\n\n#ifndef __ITSSStorageProvider_FWD_DEFINED__\n#define __ITSSStorageProvider_FWD_DEFINED__\ntypedef interface ITSSStorageProvider ITSSStorageProvider;\n#endif \t/* __ITSSStorageProvider_FWD_DEFINED__ */\n\n\n#ifndef __ITSSModule_FWD_DEFINED__\n#define __ITSSModule_FWD_DEFINED__\ntypedef interface ITSSModule ITSSModule;\n#endif \t/* __ITSSModule_FWD_DEFINED__ */\n\n\n#ifndef __ITSSWaveDecoder_FWD_DEFINED__\n#define __ITSSWaveDecoder_FWD_DEFINED__\ntypedef interface ITSSWaveDecoder ITSSWaveDecoder;\n#endif \t/* __ITSSWaveDecoder_FWD_DEFINED__ */\n\n\nvoid __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);\nvoid __RPC_USER MIDL_user_free( void __RPC_FAR * ); \n\n\n#ifndef __TVPSndSysLib_LIBRARY_DEFINED__\n#define __TVPSndSysLib_LIBRARY_DEFINED__\n\n/* library TVPSndSysLib */\n/* [helpstring][version][uuid] */ \n\ntypedef /* [helpstring][version][uuid] */ struct  tagTSSWaveFormat\n    {\n    /* [helpstring] */ unsigned long dwSamplesPerSec;\n    /* [helpstring] */ unsigned long dwChannels;\n    /* [helpstring] */ unsigned long dwBitsPerSample;\n    /* [helpstring] */ unsigned long dwSeekable;\n    /* [helpstring] */ unsigned __int64 ui64TotalSamples;\n    /* [helpstring] */ unsigned long dwTotalTime;\n    long dwReserved1;\n    long dwReserved2;\n    }\tTSSWaveFormat;\n\n\nEXTERN_C const IID LIBID_TVPSndSysLib;\n\n#ifndef __ITSSMediaBaseInfo_INTERFACE_DEFINED__\n#define __ITSSMediaBaseInfo_INTERFACE_DEFINED__\n\n/* interface ITSSMediaBaseInfo */\n/* [object][helpstring][version][uuid] */ \n\n\nEXTERN_C const IID IID_ITSSMediaBaseInfo;\n\n#if defined(__cplusplus) && !defined(CINTERFACE)\n    \n    MIDL_INTERFACE(\"B4C4239B-7D27-43CC-8523-66955BDF59DF\")\n    ITSSMediaBaseInfo : public IUnknown\n    {\n    public:\n        virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaType( \n            /* [in] */ LPWSTR shortname,\n            /* [in] */ LPWSTR descbuf,\n            /* [in] */ unsigned long descbuflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetLength( \n            /* [retval][out] */ unsigned long __RPC_FAR *length) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetTitle( \n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetCopyright( \n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetComment( \n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetArtist( \n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen) = 0;\n        \n    };\n    \n#else \t/* C style interface */\n\n    typedef struct ITSSMediaBaseInfoVtbl\n    {\n        BEGIN_INTERFACE\n        \n        HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ REFIID riid,\n            /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( \n            ITSSMediaBaseInfo __RPC_FAR * This);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( \n            ITSSMediaBaseInfo __RPC_FAR * This);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaType )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ LPWSTR shortname,\n            /* [in] */ LPWSTR descbuf,\n            /* [in] */ unsigned long descbuflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetLength )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [retval][out] */ unsigned long __RPC_FAR *length);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetTitle )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetCopyright )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetComment )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetArtist )( \n            ITSSMediaBaseInfo __RPC_FAR * This,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen);\n        \n        END_INTERFACE\n    } ITSSMediaBaseInfoVtbl;\n\n    interface ITSSMediaBaseInfo\n    {\n        CONST_VTBL struct ITSSMediaBaseInfoVtbl __RPC_FAR *lpVtbl;\n    };\n\n    \n\n#ifdef COBJMACROS\n\n\n#define ITSSMediaBaseInfo_QueryInterface(This,riid,ppvObject)\t\\\n    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\n\n#define ITSSMediaBaseInfo_AddRef(This)\t\\\n    (This)->lpVtbl -> AddRef(This)\n\n#define ITSSMediaBaseInfo_Release(This)\t\\\n    (This)->lpVtbl -> Release(This)\n\n\n#define ITSSMediaBaseInfo_GetMediaType(This,shortname,descbuf,descbuflen)\t\\\n    (This)->lpVtbl -> GetMediaType(This,shortname,descbuf,descbuflen)\n\n#define ITSSMediaBaseInfo_GetLength(This,length)\t\\\n    (This)->lpVtbl -> GetLength(This,length)\n\n#define ITSSMediaBaseInfo_GetTitle(This,buf,buflen)\t\\\n    (This)->lpVtbl -> GetTitle(This,buf,buflen)\n\n#define ITSSMediaBaseInfo_GetCopyright(This,buf,buflen)\t\\\n    (This)->lpVtbl -> GetCopyright(This,buf,buflen)\n\n#define ITSSMediaBaseInfo_GetComment(This,buf,buflen)\t\\\n    (This)->lpVtbl -> GetComment(This,buf,buflen)\n\n#define ITSSMediaBaseInfo_GetArtist(This,buf,buflen)\t\\\n    (This)->lpVtbl -> GetArtist(This,buf,buflen)\n\n#endif /* COBJMACROS */\n\n\n#endif \t/* C style interface */\n\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetMediaType_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [in] */ LPWSTR shortname,\n    /* [in] */ LPWSTR descbuf,\n    /* [in] */ unsigned long descbuflen);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetMediaType_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetLength_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [retval][out] */ unsigned long __RPC_FAR *length);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetLength_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetTitle_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [in] */ LPWSTR buf,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetTitle_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetCopyright_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [in] */ LPWSTR buf,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetCopyright_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetComment_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [in] */ LPWSTR buf,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetComment_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetArtist_Proxy( \n    ITSSMediaBaseInfo __RPC_FAR * This,\n    /* [in] */ LPWSTR buf,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSMediaBaseInfo_GetArtist_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n\n#endif \t/* __ITSSMediaBaseInfo_INTERFACE_DEFINED__ */\n\n\n#ifndef __ITSSStorageProvider_INTERFACE_DEFINED__\n#define __ITSSStorageProvider_INTERFACE_DEFINED__\n\n/* interface ITSSStorageProvider */\n/* [object][helpstring][version][uuid] */ \n\n\nEXTERN_C const IID IID_ITSSStorageProvider;\n\n#if defined(__cplusplus) && !defined(CINTERFACE)\n    \n    MIDL_INTERFACE(\"7DD61993-615D-481D-B060-A9FD48394430\")\n    ITSSStorageProvider : public IUnknown\n    {\n    public:\n        virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForRead( \n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForWrite( \n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForUpdate( \n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0;\n        \n    };\n    \n#else \t/* C style interface */\n\n    typedef struct ITSSStorageProviderVtbl\n    {\n        BEGIN_INTERFACE\n        \n        HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( \n            ITSSStorageProvider __RPC_FAR * This,\n            /* [in] */ REFIID riid,\n            /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( \n            ITSSStorageProvider __RPC_FAR * This);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( \n            ITSSStorageProvider __RPC_FAR * This);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForRead )( \n            ITSSStorageProvider __RPC_FAR * This,\n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForWrite )( \n            ITSSStorageProvider __RPC_FAR * This,\n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForUpdate )( \n            ITSSStorageProvider __RPC_FAR * This,\n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n        \n        END_INTERFACE\n    } ITSSStorageProviderVtbl;\n\n    interface ITSSStorageProvider\n    {\n        CONST_VTBL struct ITSSStorageProviderVtbl __RPC_FAR *lpVtbl;\n    };\n\n    \n\n#ifdef COBJMACROS\n\n\n#define ITSSStorageProvider_QueryInterface(This,riid,ppvObject)\t\\\n    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\n\n#define ITSSStorageProvider_AddRef(This)\t\\\n    (This)->lpVtbl -> AddRef(This)\n\n#define ITSSStorageProvider_Release(This)\t\\\n    (This)->lpVtbl -> Release(This)\n\n\n#define ITSSStorageProvider_GetStreamForRead(This,url,stream)\t\\\n    (This)->lpVtbl -> GetStreamForRead(This,url,stream)\n\n#define ITSSStorageProvider_GetStreamForWrite(This,url,stream)\t\\\n    (This)->lpVtbl -> GetStreamForWrite(This,url,stream)\n\n#define ITSSStorageProvider_GetStreamForUpdate(This,url,stream)\t\\\n    (This)->lpVtbl -> GetStreamForUpdate(This,url,stream)\n\n#endif /* COBJMACROS */\n\n\n#endif \t/* C style interface */\n\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForRead_Proxy( \n    ITSSStorageProvider __RPC_FAR * This,\n    /* [in] */ LPWSTR url,\n    /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n\n\nvoid __RPC_STUB ITSSStorageProvider_GetStreamForRead_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForWrite_Proxy( \n    ITSSStorageProvider __RPC_FAR * This,\n    /* [in] */ LPWSTR url,\n    /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n\n\nvoid __RPC_STUB ITSSStorageProvider_GetStreamForWrite_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForUpdate_Proxy( \n    ITSSStorageProvider __RPC_FAR * This,\n    /* [in] */ LPWSTR url,\n    /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream);\n\n\nvoid __RPC_STUB ITSSStorageProvider_GetStreamForUpdate_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n\n#endif \t/* __ITSSStorageProvider_INTERFACE_DEFINED__ */\n\n\n#ifndef __ITSSModule_INTERFACE_DEFINED__\n#define __ITSSModule_INTERFACE_DEFINED__\n\n/* interface ITSSModule */\n/* [object][helpstring][version][uuid] */ \n\n\nEXTERN_C const IID IID_ITSSModule;\n\n#if defined(__cplusplus) && !defined(CINTERFACE)\n    \n    MIDL_INTERFACE(\"A938D1A5-2980-498B-B051-99931D41895D\")\n    ITSSModule : public IUnknown\n    {\n    public:\n        virtual /* [helpstring][id] */ HRESULT __stdcall GetModuleCopyright( \n            /* [in] */ LPWSTR buffer,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetModuleDescription( \n            /* [in] */ LPWSTR buffer,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetSupportExts( \n            /* [in] */ unsigned long index,\n            /* [in] */ LPWSTR mediashortname,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaInfo( \n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaSupport( \n            /* [in] */ LPWSTR url) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaInstance( \n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance) = 0;\n        \n    };\n    \n#else \t/* C style interface */\n\n    typedef struct ITSSModuleVtbl\n    {\n        BEGIN_INTERFACE\n        \n        HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ REFIID riid,\n            /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( \n            ITSSModule __RPC_FAR * This);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( \n            ITSSModule __RPC_FAR * This);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetModuleCopyright )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ LPWSTR buffer,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetModuleDescription )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ LPWSTR buffer,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetSupportExts )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ unsigned long index,\n            /* [in] */ LPWSTR mediashortname,\n            /* [in] */ LPWSTR buf,\n            /* [in] */ unsigned long buflen);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaInfo )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaSupport )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ LPWSTR url);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaInstance )( \n            ITSSModule __RPC_FAR * This,\n            /* [in] */ LPWSTR url,\n            /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance);\n        \n        END_INTERFACE\n    } ITSSModuleVtbl;\n\n    interface ITSSModule\n    {\n        CONST_VTBL struct ITSSModuleVtbl __RPC_FAR *lpVtbl;\n    };\n\n    \n\n#ifdef COBJMACROS\n\n\n#define ITSSModule_QueryInterface(This,riid,ppvObject)\t\\\n    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\n\n#define ITSSModule_AddRef(This)\t\\\n    (This)->lpVtbl -> AddRef(This)\n\n#define ITSSModule_Release(This)\t\\\n    (This)->lpVtbl -> Release(This)\n\n\n#define ITSSModule_GetModuleCopyright(This,buffer,buflen)\t\\\n    (This)->lpVtbl -> GetModuleCopyright(This,buffer,buflen)\n\n#define ITSSModule_GetModuleDescription(This,buffer,buflen)\t\\\n    (This)->lpVtbl -> GetModuleDescription(This,buffer,buflen)\n\n#define ITSSModule_GetSupportExts(This,index,mediashortname,buf,buflen)\t\\\n    (This)->lpVtbl -> GetSupportExts(This,index,mediashortname,buf,buflen)\n\n#define ITSSModule_GetMediaInfo(This,url,info)\t\\\n    (This)->lpVtbl -> GetMediaInfo(This,url,info)\n\n#define ITSSModule_GetMediaSupport(This,url)\t\\\n    (This)->lpVtbl -> GetMediaSupport(This,url)\n\n#define ITSSModule_GetMediaInstance(This,url,instance)\t\\\n    (This)->lpVtbl -> GetMediaInstance(This,url,instance)\n\n#endif /* COBJMACROS */\n\n\n#endif \t/* C style interface */\n\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetModuleCopyright_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ LPWSTR buffer,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSModule_GetModuleCopyright_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetModuleDescription_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ LPWSTR buffer,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSModule_GetModuleDescription_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetSupportExts_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ unsigned long index,\n    /* [in] */ LPWSTR mediashortname,\n    /* [in] */ LPWSTR buf,\n    /* [in] */ unsigned long buflen);\n\n\nvoid __RPC_STUB ITSSModule_GetSupportExts_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaInfo_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ LPWSTR url,\n    /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info);\n\n\nvoid __RPC_STUB ITSSModule_GetMediaInfo_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaSupport_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ LPWSTR url);\n\n\nvoid __RPC_STUB ITSSModule_GetMediaSupport_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaInstance_Proxy( \n    ITSSModule __RPC_FAR * This,\n    /* [in] */ LPWSTR url,\n    /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance);\n\n\nvoid __RPC_STUB ITSSModule_GetMediaInstance_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n\n#endif \t/* __ITSSModule_INTERFACE_DEFINED__ */\n\n\n#ifndef __ITSSWaveDecoder_INTERFACE_DEFINED__\n#define __ITSSWaveDecoder_INTERFACE_DEFINED__\n\n/* interface ITSSWaveDecoder */\n/* [object][helpstring][version][uuid] */ \n\n\nEXTERN_C const IID IID_ITSSWaveDecoder;\n\n#if defined(__cplusplus) && !defined(CINTERFACE)\n    \n    MIDL_INTERFACE(\"313864E2-910E-496F-8A6D-43465C105B58\")\n    ITSSWaveDecoder : public IUnknown\n    {\n    public:\n        virtual /* [helpstring][id] */ HRESULT __stdcall GetFormat( \n            /* [in] */ TSSWaveFormat __RPC_FAR *format) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall Render( \n            /* [in] */ void __RPC_FAR *buf,\n            /* [in] */ unsigned long bufsamplelen,\n            /* [out] */ unsigned long __RPC_FAR *rendered,\n            /* [retval][out] */ unsigned long __RPC_FAR *status) = 0;\n        \n        virtual /* [helpstring][id] */ HRESULT __stdcall SetPosition( \n            /* [in] */ unsigned __int64 samplepos) = 0;\n        \n    };\n    \n#else \t/* C style interface */\n\n    typedef struct ITSSWaveDecoderVtbl\n    {\n        BEGIN_INTERFACE\n        \n        HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( \n            ITSSWaveDecoder __RPC_FAR * This,\n            /* [in] */ REFIID riid,\n            /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( \n            ITSSWaveDecoder __RPC_FAR * This);\n        \n        ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( \n            ITSSWaveDecoder __RPC_FAR * This);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetFormat )( \n            ITSSWaveDecoder __RPC_FAR * This,\n            /* [in] */ TSSWaveFormat __RPC_FAR *format);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *Render )( \n            ITSSWaveDecoder __RPC_FAR * This,\n            /* [in] */ void __RPC_FAR *buf,\n            /* [in] */ unsigned long bufsamplelen,\n            /* [out] */ unsigned long __RPC_FAR *rendered,\n            /* [retval][out] */ unsigned long __RPC_FAR *status);\n        \n        /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *SetPosition )( \n            ITSSWaveDecoder __RPC_FAR * This,\n            /* [in] */ unsigned __int64 samplepos);\n        \n        END_INTERFACE\n    } ITSSWaveDecoderVtbl;\n\n    interface ITSSWaveDecoder\n    {\n        CONST_VTBL struct ITSSWaveDecoderVtbl __RPC_FAR *lpVtbl;\n    };\n\n    \n\n#ifdef COBJMACROS\n\n\n#define ITSSWaveDecoder_QueryInterface(This,riid,ppvObject)\t\\\n    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)\n\n#define ITSSWaveDecoder_AddRef(This)\t\\\n    (This)->lpVtbl -> AddRef(This)\n\n#define ITSSWaveDecoder_Release(This)\t\\\n    (This)->lpVtbl -> Release(This)\n\n\n#define ITSSWaveDecoder_GetFormat(This,format)\t\\\n    (This)->lpVtbl -> GetFormat(This,format)\n\n#define ITSSWaveDecoder_Render(This,buf,bufsamplelen,rendered,status)\t\\\n    (This)->lpVtbl -> Render(This,buf,bufsamplelen,rendered,status)\n\n#define ITSSWaveDecoder_SetPosition(This,samplepos)\t\\\n    (This)->lpVtbl -> SetPosition(This,samplepos)\n\n#endif /* COBJMACROS */\n\n\n#endif \t/* C style interface */\n\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_GetFormat_Proxy( \n    ITSSWaveDecoder __RPC_FAR * This,\n    /* [in] */ TSSWaveFormat __RPC_FAR *format);\n\n\nvoid __RPC_STUB ITSSWaveDecoder_GetFormat_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_Render_Proxy( \n    ITSSWaveDecoder __RPC_FAR * This,\n    /* [in] */ void __RPC_FAR *buf,\n    /* [in] */ unsigned long bufsamplelen,\n    /* [out] */ unsigned long __RPC_FAR *rendered,\n    /* [retval][out] */ unsigned long __RPC_FAR *status);\n\n\nvoid __RPC_STUB ITSSWaveDecoder_Render_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_SetPosition_Proxy( \n    ITSSWaveDecoder __RPC_FAR * This,\n    /* [in] */ unsigned __int64 samplepos);\n\n\nvoid __RPC_STUB ITSSWaveDecoder_SetPosition_Stub(\n    IRpcStubBuffer *This,\n    IRpcChannelBuffer *_pRpcChannelBuffer,\n    PRPC_MESSAGE _pRpcMessage,\n    DWORD *_pdwStubPhase);\n\n\n\n#endif \t/* __ITSSWaveDecoder_INTERFACE_DEFINED__ */\n\n#endif /* __TVPSndSysLib_LIBRARY_DEFINED__ */\n\n/* Additional Prototypes for ALL interfaces */\n\n/* end of Additional Prototypes */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/core/sound/win32/tvpsnd.idl",
    "content": "[\n  uuid(F09B2E87-740A-4AEA-90CB-AE1C4EFD35F1), \n  version(1.0), \n  helpstring(\"TVP Sound System Library\")\n    \n]\nlibrary TVPSndSysLib\n{\n\n  importlib(\"stdole2.tlb\");\n\n  [\n    uuid(B4C4239B-7D27-43CC-8523-66955BDF59DF), \n    version(1.9), \n    helpstring(\"TVP Sound System Media Base Information Interface\")\n  ]\n   interface ITSSMediaBaseInfo: IUnknown\n  {\n    [\n    id(0x00000001), \n    helpstring(\"fBA̎ޕ̎擾\")\n    ]\n    HRESULT _stdcall GetMediaType([in] LPWSTR shortname, [in] LPWSTR descbuf, [in] unsigned long descbuflen );\n    [\n    id(0x00000002), \n    helpstring(\"Ȓ̎擾\")\n    ]\n    HRESULT _stdcall GetLength([out, retval] unsigned long * length );\n    [\n    id(0x00000003), \n    helpstring(\"fBA^Cg̎擾\")\n    ]\n    HRESULT _stdcall GetTitle([in] LPWSTR buf, [in] unsigned long buflen );\n    [\n    id(0x00000004), \n    helpstring(\"fBA쌠̎擾\")\n    ]\n    HRESULT _stdcall GetCopyright([in] LPWSTR buf, [in] unsigned long buflen );\n    [\n    id(0x00000005), \n    helpstring(\"fBARg̎擾\")\n    ]\n    HRESULT _stdcall GetComment([in] LPWSTR buf, [in] unsigned long buflen );\n    [\n    id(0x00000006), \n    helpstring(\"fBAA[eBXg̎擾\")\n    ]\n    HRESULT _stdcall GetArtist([in] LPWSTR buf, [in] unsigned long buflen );\n  };\n\n  [\n    uuid(76CA2F83-6E9F-4687-9E2D-5C898E5DB2A7), \n    version(1.0), \n    helpstring(\"TVP Sound System Wave Format Record\")\n  ]\n  typedef struct tagTSSWaveFormat\n  {\n    [\n    helpstring(\"TvOg\")\n    ]\n    unsigned long dwSamplesPerSec;\n    [\n    helpstring(\"`l\")\n    ]\n    unsigned long dwChannels;\n    [\n    helpstring(\"rbg\")\n    ]\n    unsigned long dwBitsPerSample;\n    [\n    helpstring(\"V[N\\\")\n    ]\n    unsigned long dwSeekable;\n    [\n    helpstring(\"STv\")\n    ]\n    unsigned __int64 ui64TotalSamples;\n    [\n    helpstring(\"S\")\n    ]\n    unsigned long dwTotalTime;\n    long dwReserved1;\n    long dwReserved2;\n  } TSSWaveFormat;\n\n  [\n    uuid(7DD61993-615D-481D-B060-A9FD48394430), \n    version(1.6), \n    helpstring(\"TVP Sound System Storage Stream Provider\")\n  ]\n   interface ITSSStorageProvider: IUnknown\n  {\n    [\n    id(0x00000001), \n    helpstring(\"Xg[W̓ǂݍݗpIStream̎擾\")\n    ]\n    HRESULT _stdcall GetStreamForRead([in] LPWSTR url, [out, retval]  IUnknown ** stream );\n    [\n    id(0x00000002), \n    helpstring(\"Xg[W̏ݗpIStream̎擾\")\n    ]\n    HRESULT _stdcall GetStreamForWrite([in] LPWSTR url, [out, retval]  IUnknown ** stream );\n    [\n    id(0x00000003), \n    helpstring(\"Xg[W̍XVpIStream̎擾\")\n    ]\n    HRESULT _stdcall GetStreamForUpdate([in] LPWSTR url, [out, retval]  IUnknown ** stream );\n  };\n\n  [\n    uuid(A938D1A5-2980-498B-B051-99931D41895D), \n    version(1.9), \n    helpstring(\"TVP Sound System Module Interface\")\n  ]\n   interface ITSSModule: IUnknown\n  {\n    [\n    id(0x00000001), \n    helpstring(\"W[̒쌠̎擾\")\n    ]\n    HRESULT _stdcall GetModuleCopyright([in] LPWSTR buffer, [in] unsigned long buflen );\n    [\n    id(0x00000002), \n    helpstring(\"W[̒ǉ̎擾\")\n    ]\n    HRESULT _stdcall GetModuleDescription([in] LPWSTR buffer, [in] unsigned long buflen );\n    [\n    id(0x00000003), \n    helpstring(\"Ήt@Cgq̎擾\")\n    ]\n    HRESULT _stdcall GetSupportExts([in] unsigned long index, [in] LPWSTR mediashortname, [in] LPWSTR buf, [in] unsigned long buflen );\n    [\n    id(0x00000004), \n    helpstring(\"w胁fBȀ擾\")\n    ]\n    HRESULT _stdcall GetMediaInfo([in] LPWSTR url, [out, retval] ITSSMediaBaseInfo ** info );\n    [\n    id(0x00000005), \n    helpstring(\"w胁fBÃvOCň邩\")\n    ]\n    HRESULT _stdcall GetMediaSupport([in] LPWSTR url );\n    [\n    id(0x00000006), \n    helpstring(\"fBAĐpIuWFNg̎擾\")\n    ]\n    HRESULT _stdcall GetMediaInstance([in] LPWSTR url, [out, retval]  IUnknown ** instance );\n  };\n\n  [\n    uuid(313864E2-910E-496F-8A6D-43465C105B58), \n    version(1.6), \n    helpstring(\"TVP Sound System Wave Decoder Interface\")\n  ]\n   interface ITSSWaveDecoder: IUnknown\n  {\n    [\n    id(0x00000001), \n    helpstring(\"ĐtH[}bg̎擾\")\n    ]\n    HRESULT _stdcall GetFormat([in] TSSWaveFormat * format );\n    [\n    id(0x00000002), \n    helpstring(\"݈ʒufR[h\")\n    ]\n    HRESULT _stdcall Render([in] void * buf, [in] unsigned long bufsamplelen, [out] unsigned long * rendered, [out, retval] unsigned long * status );\n    [\n    id(0x00000003), \n    helpstring(\"wʒuւ̃fR[hʒüړ\")\n    ]\n    HRESULT _stdcall SetPosition([in] unsigned __int64 samplepos );\n  };\n\n}; "
  },
  {
    "path": "src/core/sound/xmmlib.h",
    "content": " \n//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief XMMユーティリティ\n//---------------------------------------------------------------------------\n\n/*\n\tand\n\tthe original copyright:\n*/\n\n\n/********************************************************************\n *                                                                  *\n * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *\n * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *\n * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *\n * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *\n *                                                                  *\n * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *\n * by the XIPHOPHORUS Company http://www.xiph.org/                  *\n *                                                                  *\n ********************************************************************\n function: Header of SSE Function Library\n last mod: $Id: xmmlib.h,v 1.3 2005-07-08 15:00:00+09 blacksword Exp $\n ********************************************************************/\n\n/*\n\tBased on a file from Ogg Vorbis Optimization Project:\n\t http://homepage3.nifty.com/blacksword/\n*/\n\n#ifndef _XMMLIB_H_INCLUDED\n#define _XMMLIB_H_INCLUDED\n\n#include \"tjsCommHead.h\"\n#include <malloc.h>\n#if defined(_M_IX86)||defined(_M_X64)\n\n//---------------------------------------------------------------------------\n\n\n#if\tdefined(__GNUC__)||defined(_MSC_VER)\n#else\n#error \"Not supported System.\"\n#endif\n\n\n#if\t(defined(__SSE__)&&defined(__GNUC__))||defined(_MSC_VER)\n\n/* We need type definitions from the XMM header file.  */\n#include <xmmintrin.h>\n#ifdef\t_MSC_VER\n#include <emmintrin.h>\t// if gcc is 3.4, this file need to include.\n#endif\n\n#ifdef __GNUC__\n#define _SALIGN16(x) static x __attribute__((aligned(16)))\n#define _ALIGN16(x) x __attribute__((aligned(16)))\n#else\n#define _SALIGN16(x) __declspec(align(16)) static x\n#define _ALIGN16(x) __declspec(align(16)) x\n#endif\n#define PM64(x)\t\t(*(__m64*)(x))\n#define PM128(x)\t(*(__m128*)(x))\n#define PM128I(x)\t(*(__m128i*)(x))\n\ntypedef union {\n\tunsigned char\tsi8[8];\n\tunsigned short\tsi16[4];\n\tunsigned long\tsi32[2];\n\tchar\t\t\tssi8[8];\n\tshort\t\t\tssi16[4];\n\tlong\t\t\tssi32[2];\n\t__m64\t\t\tpi64;\n} __m64x;\n\n#if\t\tdefined(_MSC_VER)\ntypedef union __declspec(intrin_type) __declspec(align(16)) __m128x{\n\tunsigned long\tsi32[4];\n\tfloat\t\t\tsf[4];\n\t__m64\t\t\tpi64[2];\n\t__m128\t\t\tps;\n#ifdef\t__SSE2__\n\t__m128i\t\t\tpi;\n\t__m128d\t\t\tpd;\n#endif\n} __m128x;\n\n#elif\tdefined(__GNUC__)\ntypedef union {\n\tunsigned long\tsi32[4];\n\tfloat\t\t\tsf[4];\n\t__m64\t\t\tpi64[2];\n\t__m128\t\t\tps;\n#ifdef\t__SSE2__\n\t__m128i\t\t\tpi;\n\t__m128d\t\t\tpd;\n#endif\n} __m128x __attribute__((aligned(16)));\n\n#endif\n\nextern _ALIGN16(const tjs_uint32) PCS_NNRN[4];\nextern _ALIGN16(const tjs_uint32) PCS_NNRR[4];\nextern _ALIGN16(const tjs_uint32) PCS_NRNN[4];\nextern _ALIGN16(const tjs_uint32) PCS_NRNR[4];\nextern _ALIGN16(const tjs_uint32) PCS_NRRN[4];\nextern _ALIGN16(const tjs_uint32) PCS_NRRR[4];\nextern _ALIGN16(const tjs_uint32) PCS_RNNN[4];\nextern _ALIGN16(const tjs_uint32) PCS_RNRN[4];\nextern _ALIGN16(const tjs_uint32) PCS_RNRR[4];\nextern _ALIGN16(const tjs_uint32) PCS_RRNN[4];\nextern _ALIGN16(const tjs_uint32) PCS_RNNR[4];\nextern _ALIGN16(const tjs_uint32) PCS_RRRR[4];\nextern _ALIGN16(const tjs_uint32) PCS_NNNR[4];\nextern _ALIGN16(const tjs_uint32) PABSMASK[4];\nextern _ALIGN16(const tjs_uint32) PSTARTEDGEM1[4];\nextern _ALIGN16(const tjs_uint32) PSTARTEDGEM2[4];\nextern _ALIGN16(const tjs_uint32) PSTARTEDGEM3[4];\nextern _ALIGN16(const tjs_uint32) PENDEDGEM1[4];\nextern _ALIGN16(const tjs_uint32) PENDEDGEM2[4];\nextern _ALIGN16(const tjs_uint32) PENDEDGEM3[4];\nextern _ALIGN16(const tjs_uint32) PMASKTABLE[16*4];\n\nextern _ALIGN16(const float) PFV_0[4];\nextern _ALIGN16(const float) PFV_1[4];\nextern _ALIGN16(const float) PFV_2[4];\nextern _ALIGN16(const float) PFV_4[4];\nextern _ALIGN16(const float) PFV_8[4];\nextern _ALIGN16(const float) PFV_INIT[4];\nextern _ALIGN16(const float) PFV_0P5[4];\n\ninline __m128 _mm_untnorm_ps(__m128 x)\n{\n\t_SALIGN16(const tjs_uint32)\tPIV0[4]\t = {\n\t\t0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000\n\t};\n\tregister __m128 r;\n\tr\t = _mm_and_ps(x, PM128(PCS_RRRR));\n\tr\t = _mm_or_ps(x, PM128(PIV0));\n\treturn\tr;\n}\n\ninline float _mm_add_horz(__m128 x)\n{\n\t__m128\ty;\n\ty\t = _mm_movehl_ps(y, x);\n\tx\t = _mm_add_ps(x, y);\n\ty\t = x;\n\ty\t = _mm_shuffle_ps(y, y, _MM_SHUFFLE(1,1,1,1));\n\tx\t = _mm_add_ss(x, y);\n\treturn _mm_cvtss_f32(x);\n}\n\ninline __m128 _mm_add_horz_ss(__m128 x)\n{\n\t__m128\ty;\n\ty\t = _mm_movehl_ps(y, x);\n\tx\t = _mm_add_ps(x, y);\n\ty\t = x;\n\ty\t = _mm_shuffle_ps(y, y, _MM_SHUFFLE(1,1,1,1));\n\tx\t = _mm_add_ss(x, y);\n\treturn x;\n}\n\ninline float _mm_max_horz(__m128 x)\n{\n\t__m128\ty;\n\ty\t = _mm_movehl_ps(y, x);\n\tx\t = _mm_max_ps(x, y);\n\ty\t = x;\n\ty\t = _mm_shuffle_ps(y, y, _MM_SHUFFLE(1,1,1,1));\n\tx\t = _mm_max_ss(x, y);\n\treturn _mm_cvtss_f32(x);\n}\n\ninline float _mm_min_horz(__m128 x)\n{\n\t__m128\ty;\n\ty\t = _mm_movehl_ps(y, x);\n\tx\t = _mm_min_ps(x, y);\n\ty\t = x;\n\ty\t = _mm_shuffle_ps(y, y, _MM_SHUFFLE(1,1,1,1));\n\tx\t = _mm_min_ss(x, y);\n\treturn _mm_cvtss_f32(x);\n}\n\n#endif /* (defined(__SSE__)&&defined(__GNUC__))||defined(_MSC_VER) */\n\n\n/**\n * 128ビット境界にポインタがアラインメントされているかどうか\n * @param p\tポインタ\n * @return\t128ビット境界にポインタがアラインメントされているかどうか\n */\ninline bool IsAlignedTo128bits(const void * p)\n{\n\treturn !(reinterpret_cast<tjs_offset>(p) & 0xf);\n}\n\n\n//---------------------------------------------------------------------------\n\n#endif\n#endif /* _XMMLIB_H_INCLUDED */\n"
  },
  {
    "path": "src/core/tjs2/tjs.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"tTJS\" script language API class implementation\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include <map>\n#include <assert.h>\n#include \"tjs.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"tjsDate.h\"\n#include \"tjsMath.h\"\n#include \"tjsException.h\"\n#include \"tjsInterCodeExec.h\"\n#include \"tjsScriptCache.h\"\n#include \"tjsLex.h\"\n#include \"tjsHashSearch.h\"\n#include \"tjsRandomGenerator.h\"\n#include \"tjsGlobalStringMap.h\"\n#include \"tjsDebug.h\"\n#include \"tjsByteCodeLoader.h\"\n#include \"tjsBinarySerializer.h\"\n#include \"tjsRegExp.h\"\n\nnamespace TJS\n{\n#ifndef TJS_NO_REGEXP\nextern iTJSDispatch2 * TJSCreateRegExpClass();\n\t// to avoid to include large regexp library header\n#endif\n//---------------------------------------------------------------------------\n// TJS Version\n//---------------------------------------------------------------------------\nconst tjs_int TJSVersionMajor   = 2;\nconst tjs_int TJSVersionMinor   = 4;\nconst tjs_int TJSVersionRelease = 28;\nconst tjs_int TJSVersionHex =\n\tTJSVersionMajor * 0x1000000 + TJSVersionMinor * 0x10000 + TJSVersionRelease;\n\n#ifdef _MSC_VER\n #define WIDEN2(x) L ## x\n #define WIDEN(x) WIDEN2(x)\ntjs_char TJSCompiledDate[] = WIDEN(__DATE__) WIDEN(\" \") WIDEN(__TIME__);\n#else\ntjs_char TJSCompiledDate[] = TJS_W(\"\" __DATE__ \" \" __TIME__);\n#endif\n\t// first empty literal string is to avoid a compile error with bcc which can not\n\t// process directly L __DATE__ as a pre-processer wide literal string.\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// global options\n//---------------------------------------------------------------------------\nbool TJSEvalOperatorIsOnGlobal = false;\n\t// Post-! operator (evaluate expression) is to be executed on \"this\" context\n\t// since TJS2 version 2.4.1\nbool TJSWarnOnNonGlobalEvalOperator = false;\n\t// Output warning against non-local post-! operator.\nbool TJSEnableDebugMode = false;\n\t// Enable TJS2 Debugging support. Enabling this may make the\n\t// program somewhat slower and using more memory.\n\t// Do not use this mode unless you want to debug the program.\nbool TJSWarnOnExecutionOnDeletingObject = false;\n\t// Output warning against running code on context of\n\t// deleting-in-progress object. This is available only the Debug mode is\n\t// enabled.\nbool TJSUnaryAsteriskIgnoresPropAccess = false;\n\t// Unary '*' operator means accessing property object directly without\n\t// normal property access, if this options is set true.\n\t// This is replaced with '&' operator since TJS2 2.4.15. Turn true for\n\t// gaining old compatibility.\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSPPMap : value container for pre-processor\n//---------------------------------------------------------------------------\nclass tTJSPPMap\n{\npublic:\n\ttTJSHashTable<ttstr, tjs_int32> Values;\n};\n//---------------------------------------------------------------------------\n\n\n\n\n#define TJS_GLOBAL_HASH_BITS 7\n\n//---------------------------------------------------------------------------\n// tTJS\n//---------------------------------------------------------------------------\ntTJS::tTJS()\n{\n\t// tTJS constructor\n\tRefCount = 1;\n\tConsoleOutput = NULL;\n\tPPValues = NULL;\n\n\t// ensure variant array stack for function stack\n//\tTJSVariantArrayStackAddRef();\n\tVariantArrayStack = new tTJSVariantArrayStack;\n\n\t// ensure hash table for reserved words\n\tTJSReservedWordsHashAddRef();\n\n\t// AddRef create global string map object\n\tTJSAddRefGlobalStringMap();\n\n\t// Create debugging-related objects\n\tif(TJSEnableDebugMode)\n\t{\n\t\tTJSAddRefObjectHashMap();\n\t\tTJSAddRefStackTracer();\n\t}\n\n\t// create script cache object\n\tCache = new tTJSScriptCache(this);\n\n\n\ttry\n\t{\n\n\t\t// push version value to pp value\n\t\tPPValues = new tTJSPPMap();\n\t\tPPValues->Values.Add(ttstr(TJS_W(\"version\")), TJSVersionHex);\n\n\t\t// create the GLOBAL object\n\t\tGlobal = new tTJSCustomObject(TJS_GLOBAL_HASH_BITS);\n\n\t\tif(TJSObjectHashMapEnabled())\n\t\t\tTJSObjectHashSetType(Global, TJS_W(\"the global object\"));\n\n\t\t// register some default classes to the GLOBAL\n\t\tiTJSDispatch2 *dsp;\n\t\ttTJSVariant val;\n\n\t\t// Array\n\t\tdsp = new tTJSArrayClass(); //TJSCreateArrayClass();\n\t\tval = tTJSVariant(dsp, NULL);\n\t\tdsp->Release();\n\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"Array\"), NULL, &val, Global);\n\n\t\t// Dictionary\n\t\tdsp = new tTJSDictionaryClass();\n\t\tval = tTJSVariant(dsp, NULL);\n\t\tdsp->Release();\n\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"Dictionary\"), NULL, &val, Global);\n\n\t\t// Date\n\t\tdsp = new tTJSNC_Date();\n\t\tval = tTJSVariant(dsp, NULL);\n\t\tdsp->Release();\n\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"Date\"), NULL, &val, Global);\n\n\t\t// Math\n\t\t{\n\t\t\tiTJSDispatch2 * math;\n\n\t\t\tdsp = math = new tTJSNC_Math();\n\t\t\tval = tTJSVariant(dsp, NULL);\n\t\t\tdsp->Release();\n\t\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"Math\"), NULL, &val, Global);\n\n\t\t\t// Math.RandomGenerator\n\t\t\tdsp = new tTJSNC_RandomGenerator();\n\t\t\tval = tTJSVariant(dsp, NULL);\n\t\t\tdsp->Release();\n\t\t\tmath->PropSet(TJS_MEMBERENSURE, TJS_W(\"RandomGenerator\"), NULL, &val, math);\n\t\t}\n\n\t\t// Exception\n\t\tdsp = new tTJSNC_Exception();\n\t\tval = tTJSVariant(dsp, NULL);\n\t\tdsp->Release();\n\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"Exception\"), NULL, &val, Global);\n#ifndef TJS_NO_REGEXP\n\t\t// RegExp\n\t\tdsp = TJSCreateRegExpClass(); // the body is implemented in tjsRegExp.cpp\n\t\tval = tTJSVariant(dsp, NULL);\n\t\tdsp->Release();\n\t\tGlobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"RegExp\"), NULL, &val, Global);\n#endif\n\t}\n\tcatch(...)\n\t{\n\t\tCleanup();\n\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTJS::~tTJS()\n{\n\t// tTJS destructor\n\tCleanup();\n}\n//---------------------------------------------------------------------------\nvoid tTJS::Cleanup()\n{\n\tTJSVariantArrayStackCompactNow();\n//\tTJSVariantArrayStackRelease();\n\tdelete VariantArrayStack; VariantArrayStack = nullptr;\n\n\tif(Global) Global->Release(), Global = NULL;\n\n\tif(PPValues) delete PPValues;\n\tif(Cache) delete Cache;\n\n\tTJSReservedWordsHashRelease();\n\n\tTJSReleaseGlobalStringMap();\n\n\tTJSReleaseRegex();\n\n\tif(TJSEnableDebugMode)\n\t{\n\t\tTJSReleaseStackTracer();\n\t\tTJSReleaseObjectHashMap();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::AddRef()\n{\n\tRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::Release()\n{\n\tif(RefCount == 1)\n\t{\n\t\tdelete this;\n\t}\n\telse\n\t{\n\t\tRefCount --;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::Shutdown()\n{\n\tTJSVariantArrayStackCompactNow();\n\tGlobal->Clear();\n\tif(Global) Global->Release(), Global = NULL;\n\tif(Cache) delete Cache, Cache = NULL;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJS::GetGlobal()\n{\n\tGlobal->AddRef();\n\treturn Global;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJS::GetGlobalNoAddRef() const\n{\n\treturn Global;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::AddScriptBlock(tTJSScriptBlock *block)\n{\n\tScriptBlocks.push_back(block);\n}\n//---------------------------------------------------------------------------\nvoid tTJS::RemoveScriptBlock(tTJSScriptBlock *block)\n{\n\tstd::vector<tTJSScriptBlock*>::iterator i = ScriptBlocks.begin();\n\twhile(i != ScriptBlocks.end())\n\t{\n\t\tif(*i == block)\n\t\t{\n\t\t\tScriptBlocks.erase(i);\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::SetConsoleOutput(iTJSConsoleOutput* console)\n{\n\t// set a console output callback routine\n\tConsoleOutput = console;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::OutputToConsole(const tjs_char *msg) const\n{\n\tif(ConsoleOutput)\n\t{\n\t\tConsoleOutput->Print(msg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::OutputExceptionToConsole(const tjs_char *msg) const\n{\n\tif(ConsoleOutput)\n\t{\n\t\tConsoleOutput->Print(msg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::OutputToConsoleWithCentering(const tjs_char *msg, tjs_uint width) const\n{\n\t// this function does not matter whether msg includes ZENKAKU characters ...\n\tif(!msg) return;\n\ttjs_int len = (tjs_int)TJS_strlen(msg);\n\ttjs_int ns = ((tjs_int)width - len)/2;\n\tif(ns<=0)\n\t{\n\t\tOutputToConsole(msg);\n\t}\n\telse\n\t{\n\t\ttjs_char *outbuf = new tjs_char[ns + len +1];\n\t\ttjs_char *p = outbuf;\n\t\twhile(ns--) *(p++)= TJS_W(' ');\n\t\tTJS_strcpy(p, msg);\n\t\ttry\n\t\t{\n\t\t\tOutputToConsole(outbuf);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdelete [] outbuf;\n\t\t\tthrow;\n\t\t}\n\n\t\tdelete [] outbuf;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::OutputToConsoleSeparator(const tjs_char *text, tjs_uint count) const\n{\n\ttjs_int len = (tjs_int)TJS_strlen(text);\n\ttjs_char *outbuf = new tjs_char [ len * count + 1];\n\ttjs_char *p = outbuf;\n\twhile(count--)\n\t{\n\t\tTJS_strcpy(p, text);\n\t\tp += len;\n\t}\n\n\ttry\n\t{\n\t\tOutputToConsole(outbuf);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] outbuf;\n\t\tthrow;\n\t}\n\n\tdelete [] outbuf;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::Dump(tjs_uint width) const\n{\n\t// dumps all existing script block\n\ttjs_char version[100];\n\tTJS_snprintf(version, sizeof(version)/sizeof(tjs_char), TJS_W(\"TJS version %d.%d.%d (%s)\"), TJSVersionMajor,\n\t\tTJSVersionMinor, TJSVersionRelease, TJSCompiledDate);\n\n\tOutputToConsoleSeparator(TJS_W(\"#\"), width);\n\tOutputToConsoleWithCentering(TJS_W(\"TJS Context Dump\"), width);\n\tOutputToConsoleSeparator(TJS_W(\"#\"), width);\n\tOutputToConsole(version);\n\tOutputToConsole(TJS_W(\"\"));\n\n\tif(ScriptBlocks.size())\n\t{\n\t\tstd::vector<tTJSScriptBlock*>::const_iterator i;\n\n\t\ttjs_char buf[1024];\n\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"Total %d script block(s)\"), ScriptBlocks.size());\n\t\tOutputToConsole(buf);\n\t\tOutputToConsole(TJS_W(\"\"));\n\n\t\ttjs_uint totalcontexts = 0;\n\t\ttjs_uint totalcodesize = 0;\n\t\ttjs_uint totaldatasize = 0;\n\n\t\tfor(i = ScriptBlocks.begin(); i != ScriptBlocks.end(); i++)\n\t\t{\n\t\t\ttjs_uint n;\n\t\t\tconst tjs_char * name = (*i)-> GetName();\n\n\t\t\tttstr title;\n\t\t\tif(name)\n\t\t\t\ttitle = (*i)-> GetNameInfo();\n\t\t\telse\n\t\t\t\ttitle = TJS_W(\"(no-named script block)\");\n\n\t\t\ttjs_char ptr[256];\n\t\t\tTJS_snprintf(ptr, sizeof(ptr)/sizeof(tjs_char), TJS_W(\" 0x%p\"), (*i));\n\n\t\t\ttitle += ptr;\n\n\t\t\tOutputToConsole(title.c_str());\n\n\t\t\tn = (*i)->GetContextCount();\n\t\t\ttotalcontexts += n;\n\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"\\tCount of contexts      : %d\"), n);\n\t\t\tOutputToConsole(buf);\n\n\t\t\tn = (*i)->GetTotalVMCodeSize();\n\t\t\ttotalcodesize += n;\n\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"\\tVM code area size      : %d words\"), n);\n\t\t\tOutputToConsole(buf);\n\n\t\t\tn = (*i)->GetTotalVMDataSize();\n\t\t\ttotaldatasize += n;\n\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"\\tVM constant data count : %d\"), n);\n\t\t\tOutputToConsole(buf);\n\n\t\t\tOutputToConsole(TJS_W(\"\"));\n\t\t}\n\n\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"Total count of contexts      : %d\"), totalcontexts);\n\t\tOutputToConsole(buf);\n\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"Total VM code area size      : %d words\"), totalcodesize);\n\t\tOutputToConsole(buf);\n\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"Total VM constant data count : %d\"), totaldatasize);\n\t\tOutputToConsole(buf);\n\n\t\tOutputToConsole(TJS_W(\"\"));\n\n\n\t\tfor(i = ScriptBlocks.begin(); i != ScriptBlocks.end(); i++)\n\t\t{\n\n\t\t\tOutputToConsoleSeparator(TJS_W(\"-\"), width);\n\t\t\tconst tjs_char * name = (*i)-> GetName();\n\n\t\t\tttstr title;\n\t\t\tif(name)\n\t\t\t\ttitle = (*i)-> GetNameInfo();\n\t\t\telse\n\t\t\t\ttitle = TJS_W(\"(no-named script block)\");\n\n\t\t\ttjs_char ptr[256];\n\t\t\tTJS_snprintf(ptr, sizeof(ptr)/sizeof(tjs_char), TJS_W(\" 0x%p\"), (*i));\n\n\t\t\ttitle += ptr;\n\n\t\t\tOutputToConsoleWithCentering(title.c_str(), width);\n\n\t\t\tOutputToConsoleSeparator(TJS_W(\"-\"), width);\n\n\t\t\t(*i)->Dump();\n\n\t\t\tOutputToConsole(TJS_W(\"\"));\n\t\t\tOutputToConsole(TJS_W(\"\"));\n\t\t}\n\t}\n\telse\n\t{\n\t\tOutputToConsole(TJS_W(\"\"));\n\t\tOutputToConsole(TJS_W(\"There are no script blocks in the system.\"));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJS::ExecScript(const tjs_char *script, tTJSVariant *result,\n\tiTJSDispatch2 *context,\n\tconst tjs_char *name, tjs_int lineofs)\n{\n\tTJS_F_TRACE(\"tTJS::ExecScript\");\n\tTJSSetFPUE();\n\tif(Cache) Cache->ExecScript(script, result, context, name, lineofs);\n}\n//---------------------------------------------------------------------------\nvoid tTJS::ExecScript(const ttstr &script, tTJSVariant *result,\n\tiTJSDispatch2 *context,\n\tconst ttstr *name, tjs_int lineofs)\n{\n\tTJSSetFPUE();\n\tif(Cache) Cache->ExecScript(script, result, context, name, lineofs);\n}\n//---------------------------------------------------------------------------\nvoid tTJS::EvalExpression(const tjs_char *expression, tTJSVariant *result,\n\tiTJSDispatch2 *context,\n\tconst tjs_char *name, tjs_int lineofs)\n{\n\tTJSSetFPUE();\n\tif(Cache) Cache->EvalExpression(expression, result, context, name, lineofs);\n}\n//---------------------------------------------------------------------------\nvoid tTJS::EvalExpression(const ttstr &expression, tTJSVariant *result,\n\tiTJSDispatch2 *context,\n\tconst ttstr *name, tjs_int lineofs)\n{\n\tTJSSetFPUE();\n\tif(Cache) Cache->EvalExpression(expression, result, context, name, lineofs);\n}\n//---------------------------------------------------------------------------\nvoid tTJS::SetPPValue(const tjs_char *name, tjs_int32 value)\n{\n\tPPValues->Values.Add(ttstr(name), value);\n}\n//---------------------------------------------------------------------------\ntjs_int32 tTJS::GetPPValue(const tjs_char *name)\n{\n\ttjs_int32 *f = PPValues->Values.Find(ttstr(name));\n\tif(!f) return 0;\n\treturn *f;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::DoGarbageCollection()\n{\n\t// do garbage collection\n\tTJSVariantArrayStackCompactNow();\n\tTJSCompactStringHeap();\n}\n//---------------------------------------------------------------------------\n// for Bytecode\nvoid tTJS::LoadByteCode( const tjs_uint8* buff, size_t len, tTJSVariant *result,\n\tiTJSDispatch2 *context, const tjs_char *name )\n{\n\tTJS_F_TRACE(\"tTJS::LoadByteCode\");\n\tTJSSetFPUE();\n\tif(Cache) Cache->LoadByteCode(buff, len, result, context, name);\n}\n//---------------------------------------------------------------------------\nbool tTJS::LoadByteCode( class tTJSBinaryStream* stream, tTJSVariant *result,\n\tiTJSDispatch2 *context, const tjs_char *name )  {\n\tbool ret = false;\n\ttjs_uint8* buff = NULL;\n\ttry {\n\t\ttjs_uint64 streamlen = stream->GetSize();\n\t\tif( streamlen >= tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE ) {\n\t\t\ttjs_uint8 header[tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE];\n\t\t\tstream->Read( header, tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE );\n\t\t\tif( tTJSByteCodeLoader::IsTJS2ByteCode( header ) ) {\n\t\t\t\tstream->Seek( 0, TJS_BS_SEEK_SET );\n\t\t\t\tbuff = new tjs_uint8[static_cast<unsigned int>(streamlen)];\n\t\t\t\tstream->Read( buff, static_cast<tjs_uint>(streamlen) );\n\t\t\t\tLoadByteCode( buff, static_cast<size_t>(streamlen), result, context, name );\n\t\t\t\tret = true;\n\t\t\t} else {\n\t\t\t\tassert( tTJSScriptBlock::BYTECODE_FILE_TAG_SIZE == tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\t\tif( result != NULL && tTJSBinarySerializer::IsBinary( header ) ) {\n\t\t\t\t\ttTJSBinarySerializer binload;\n\t\t\t\t\ttTJSVariant* var = binload.Read( stream );;\n\t\t\t\t\tif( var ) {\n\t\t\t\t\t*result = *var;\n\t\t\t\t\tdelete var;\n\t\t\t\tret = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tdelete[] buff;\n\t\tthrow;\n\t}\n\tdelete[] buff;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nbool tTJS::LoadBinaryDictionayArray( class tTJSBinaryStream* stream, tTJSVariant *result )\n{\n\tif( result == NULL ) return false;\n\n\tbool ret = false;\n\ttry {\n\t\ttjs_uint64 streamlen = stream->GetSize();\n\t\tif( streamlen >= tTJSBinarySerializer::HEADER_LENGTH ) {\n\t\t\ttjs_uint8 header[tTJSBinarySerializer::HEADER_LENGTH];\n\t\t\tstream->Read( header, tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\tif( tTJSBinarySerializer::IsBinary( header ) ) {\n\t\t\t\ttTJSBinarySerializer binload;\n\t\t\t\ttTJSVariant* var = binload.Read( stream );\n\t\t\t\tif( var ) {\n\t\t\t\t\t*result = *var;\n\t\t\t\t\tdelete var;\n\t\t\t\t\tret = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tthrow;\n\t}\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nvoid tTJS::CompileScript( const tjs_char *script, class tTJSBinaryStream* output, bool isresultneeded, bool outputdebug, bool isexpression, const tjs_char *name, tjs_int lineofs )\n{\n\ttTJSScriptBlock *blk = new tTJSScriptBlock(this);\n\ttry {\n\t\tif( name ) blk->SetName( name, lineofs );\n\t\tblk->Compile( script, isexpression, isresultneeded, outputdebug, output );\n\t} catch(...) {\n\t\tblk->Release();\n\t\tthrow;\n\t}\n\tblk->Release();\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// TextStream Creation\n//---------------------------------------------------------------------------\niTJSTextReadStream * TJSDefCreateTextStreamForRead(const tTJSString &name,\n\tconst tTJSString &mode)\n{ return NULL; }\niTJSTextWriteStream * TJSDefCreateTextStreamForWrite(const tTJSString &name,\n\tconst tTJSString &mode)\n{ return NULL; }\ntTJSBinaryStream * TJSDefCreateBinaryStreamForRead(const tTJSString &name,\n\tconst tTJSString &mode)\n{ return NULL; }\ntTJSBinaryStream * TJSDefCreateBinaryStreamForWrite(const tTJSString &name,\n\tconst tTJSString &mode)\n{ return NULL; }\n//---------------------------------------------------------------------------\niTJSTextReadStream * (*TJSCreateTextStreamForRead)(const tTJSString &name,\n\tconst tTJSString &mode) =\n\tTJSDefCreateTextStreamForRead;\niTJSTextWriteStream * (*TJSCreateTextStreamForWrite)(const tTJSString &name,\n\tconst tTJSString &mode) =\n\tTJSDefCreateTextStreamForWrite;\ntTJSBinaryStream * (*TJSCreateBinaryStreamForRead)(const tTJSString &name,\n\tconst tTJSString &mode) =\n\tTJSDefCreateBinaryStreamForRead;\ntTJSBinaryStream * (*TJSCreateBinaryStreamForWrite)(const tTJSString &name,\n\tconst tTJSString &mode) =\n\tTJSDefCreateBinaryStreamForWrite;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSBinaryStream\n//---------------------------------------------------------------------------\n\nvoid TJS_INTF_METHOD tTJSBinaryStream::SetEndOfStorage()\n{\n\tTJS_eTJSError(TJSWriteError);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TJS_INTF_METHOD tTJSBinaryStream::GetSize()\n{\n\ttjs_uint64 orgpos = GetPosition();\n\ttjs_uint64 size = Seek(0, TJS_BS_SEEK_END);\n\tSeek(orgpos, SEEK_SET);\n\treturn size;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSBinaryStream::GetPosition()\n{\n\treturn Seek(0, SEEK_CUR);\n}\n//---------------------------------------------------------------------------\nvoid tTJSBinaryStream::SetPosition(tjs_uint64 pos)\n{\n\tif(pos != Seek(pos, TJS_BS_SEEK_SET))\n\t\tTJS_eTJSError(TJSSeekError);\n}\n//---------------------------------------------------------------------------\nvoid tTJSBinaryStream::ReadBuffer(void *buffer, tjs_uint read_size)\n{\n\tif(Read(buffer, read_size) != read_size)\n\t\tTJS_eTJSError(TVPGetMessageByLocale(\"err_read_error\"));\n}\n//---------------------------------------------------------------------------\nvoid tTJSBinaryStream::WriteBuffer(const void *buffer, tjs_uint write_size)\n{\n\tif(Write(buffer, write_size) != write_size)\n\t\tTJS_eTJSError(TJSWriteError);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSBinaryStream::ReadI64LE()\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint8 buffer[8];\n\tReadBuffer(buffer, 8);\n\ttjs_uint64 ret = 0;\n\tfor(tjs_int i=0; i<8; i++)\n\t\tret += (tjs_uint64)buffer[i]<<(i*8);\n\treturn ret;\n#else\n\ttjs_uint64 temp;\n\tReadBuffer(&temp, 8);\n\treturn temp;\n#endif\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSBinaryStream::ReadI32LE()\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint8 buffer[4];\n\tReadBuffer(buffer, 4);\n\ttjs_uint32 ret = 0;\n\tfor(tjs_int i=0; i<4; i++)\n\t\tret += (tjs_uint32)buffer[i]<<(i*8);\n\treturn ret;\n#else\n\ttjs_uint32 temp;\n\tReadBuffer(&temp, 4);\n\treturn temp;\n#endif\n}\n//---------------------------------------------------------------------------\ntjs_uint16 tTJSBinaryStream::ReadI16LE()\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint8 buffer[2];\n\tReadBuffer(buffer, 2);\n\ttjs_uint16 ret = 0;\n\tfor(tjs_int i=0; i<2; i++)\n\t\tret += (tjs_uint16)buffer[i]<<(i*8);\n\treturn ret;\n#else\n\ttjs_uint16 temp;\n\tReadBuffer(&temp, 2);\n\treturn temp;\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n"
  },
  {
    "path": "src/core/tjs2/tjs.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"tTJS\" script language API class implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsH\n#define tjsH\n\n#include <vector>\n#include \"tjsConfig.h\"\n#include \"tjsVariant.h\"\n#include \"tjsInterface.h\"\n#include \"tjsString.h\"\n#include \"tjsMessage.h\"\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// TJS version\n//---------------------------------------------------------------------------\nextern const tjs_int TJSVersionMajor;\nextern const tjs_int TJSVersionMinor;\nextern const tjs_int TJSVersionRelease;\nextern const tjs_int TJSVersionHex;\n\nextern tjs_char TJSCompiledDate[];\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Console output callback interface\n//---------------------------------------------------------------------------\nclass iTJSConsoleOutput\n{\npublic:\n\tvirtual void ExceptionPrint(const tjs_char *msg) = 0;\n\tvirtual void Print(const tjs_char *msg) = 0;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Object Hash Size Limit ( must be larger than or equal to 0 )\n//---------------------------------------------------------------------------\nextern tjs_int TJSObjectHashBitsLimit;\n\n\n\n//---------------------------------------------------------------------------\n// global options\n//---------------------------------------------------------------------------\nextern bool TJSEvalOperatorIsOnGlobal;\n\t// Post-! operator (evaluate expression) is to be executed on \"this\" context\n\t// since TJS2 2.4.1.\n\t// Turn this switch true makes post-! operator running on global context,\n\t// like TJS2 before 2.4.1.\nextern bool TJSWarnOnNonGlobalEvalOperator;\n\t// Output warning against non-local post-! operator.\n\t// (For checking where the post-! operators are used)\nextern bool TJSEnableDebugMode;\n\t// Enable TJS2 Debugging support. Enabling this may make the\n\t// program somewhat slower and using more memory.\n\t// Do not use this mode unless you want to debug the program.\nextern bool TJSWarnOnExecutionOnDeletingObject;\n\t// Output warning against running code on context of\n\t// deleting-in-progress object. This is available only the Debug mode is\n\t// enabled.\nextern bool TJSUnaryAsteriskIgnoresPropAccess;\n\t// Unary '*' operator means accessing property object directly without\n\t// normal property access, if this options is set true.\n\t// This is replaced with '&' operator since TJS2 2.4.15. Turn true for\n\t// gaining old compatibility.\n\n\n//---------------------------------------------------------------------------\n// tTJS class - \"tTJS\" TJS API Class\n//---------------------------------------------------------------------------\nclass tTJSScriptBlock;\nclass tTJSPPMap;\nclass tTJSCustomObject;\nclass tTJSScriptCache;\nclass tTJS\n{\n\tfriend class tTJSScriptBlock;\nprivate:\n\ttjs_uint RefCount; // reference count\n\npublic:\n\ttTJS();\n\nprotected:\n\tvirtual ~tTJS();\n\npublic:\n\tvoid Cleanup();\n\n\tvoid AddRef();\n\tvoid Release();\n\n\tvoid Shutdown();\n\nprivate:\n\ttTJSPPMap * PPValues;\n\n\tstd::vector<tTJSScriptBlock*> ScriptBlocks;\n\n\tiTJSConsoleOutput *ConsoleOutput;\n\n\ttTJSCustomObject * Global;\n\n\ttTJSScriptCache * Cache;\n\tclass tTJSVariantArrayStack *VariantArrayStack = nullptr;\n\npublic:\n\tiTJSDispatch2 * GetGlobal();\n\tiTJSDispatch2 * GetGlobalNoAddRef() const;\n\n\ttTJSVariantArrayStack* GetVariantArrayStack() { return VariantArrayStack; }\n\nprivate:\n\tvoid AddScriptBlock(tTJSScriptBlock *block);\n\tvoid RemoveScriptBlock(tTJSScriptBlock *block);\n\npublic:\n\tvoid SetConsoleOutput(iTJSConsoleOutput *console);\n\tiTJSConsoleOutput * GetConsoleOutput() const { return ConsoleOutput; };\n\tvoid OutputToConsole(const tjs_char *msg) const;\n\tvoid OutputExceptionToConsole(const tjs_char *msg) const;\n\tvoid OutputToConsoleWithCentering(const tjs_char *msg, tjs_uint width) const;\n\tvoid OutputToConsoleSeparator(const tjs_char *text, tjs_uint count) const;\n\n\tvoid Dump(tjs_uint width = 80) const; // dumps all existing script block\n\n\tvoid ExecScript(const tjs_char *script, tTJSVariant *result = NULL,\n\t\tiTJSDispatch2 *context = NULL,\n\t\tconst tjs_char *name = NULL, tjs_int lineofs = 0);\n\n\tvoid ExecScript(const ttstr &script, tTJSVariant *result = NULL,\n\t\tiTJSDispatch2 *context = NULL,\n\t\tconst ttstr *name = NULL, tjs_int lineofs = 0);\n\n\tvoid EvalExpression(const tjs_char *expression, tTJSVariant *result,\n\t\tiTJSDispatch2 *context = NULL,\n\t\tconst tjs_char *name = NULL, tjs_int lineofs = 0);\n\n\tvoid EvalExpression(const ttstr &expression, tTJSVariant *result,\n\t\tiTJSDispatch2 *context = NULL,\n\t\tconst ttstr *name = NULL, tjs_int lineofs = 0);\n\n\tvoid SetPPValue(const tjs_char *name, const tjs_int32 value);\n\ttjs_int32 GetPPValue(const tjs_char *name);\n\n\tvoid DoGarbageCollection();\n\n\t// for Bytecode\n\tvoid LoadByteCode( const tjs_uint8* buff, size_t len, tTJSVariant *result = NULL,\n\t\tiTJSDispatch2 *context = NULL, const tjs_char *name = NULL);\n\n\tbool LoadByteCode( class tTJSBinaryStream* stream, tTJSVariant *result = NULL,\n\t\tiTJSDispatch2 *context = NULL, const tjs_char *name = NULL);\n\n\t// for Binary Dictionay Array\n\tstatic bool LoadBinaryDictionayArray( class tTJSBinaryStream* stream, tTJSVariant *result );\n\n\tvoid CompileScript( const tjs_char *script, class tTJSBinaryStream* output, bool isresultneeded = false, bool outputdebug = false, bool isexpression = false, const tjs_char *name = NULL, tjs_int lineofs = 0 );\n};\n//---------------------------------------------------------------------------\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// iTJSTextStream - used by Array.save/load Dictionaty.save/load\n//---------------------------------------------------------------------------\nclass tTJSString;\nclass iTJSTextReadStream\n{\npublic:\n\tvirtual tjs_uint TJS_INTF_METHOD Read(tTJSString & targ, tjs_uint size) = 0;\n\tvirtual void TJS_INTF_METHOD Destruct() = 0; // must delete itself\n};\n//---------------------------------------------------------------------------\nclass iTJSTextWriteStream\n{\npublic:\n\tvirtual void TJS_INTF_METHOD Write(const tTJSString & targ) = 0;\n\tvirtual void TJS_INTF_METHOD Destruct() = 0; // must delete itself\n};\n//---------------------------------------------------------------------------\nextern iTJSTextReadStream * (*TJSCreateTextStreamForRead)(const tTJSString &name,\n\tconst tTJSString &modestr);\nextern iTJSTextWriteStream * (*TJSCreateTextStreamForWrite)(const tTJSString &name,\n\tconst tTJSString &modestr);\nextern class tTJSBinaryStream * (*TJSCreateBinaryStreamForRead)(const tTJSString &name,\n\tconst tTJSString &modestr);\nextern class tTJSBinaryStream * (*TJSCreateBinaryStreamForWrite)(const tTJSString &name,\n\tconst tTJSString &modestr);\n//---------------------------------------------------------------------------\n\n\n\n\n/*]*/\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSBinaryStream constants\n//---------------------------------------------------------------------------\n#define TJS_BS_READ 0\n#define TJS_BS_WRITE 1\n#define TJS_BS_APPEND 2\n#define TJS_BS_UPDATE 3\n\n#define TJS_BS_DELETE_ON_CLOSE\t0x10\n\n#define TJS_BS_ACCESS_MASK 0x0f\n#define TJS_BS_OPTION_MASK 0xf0\n\n#define TJS_BS_SEEK_SET 0\n#define TJS_BS_SEEK_CUR 1\n#define TJS_BS_SEEK_END 2\n//---------------------------------------------------------------------------\n\n\n\n\n/*]*/\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSBinaryStream base stream class\n//---------------------------------------------------------------------------\nclass tTJSBinaryStream\n{\nprivate:\npublic:\n\t//-- must implement\n\tvirtual tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence) = 0;\n\t\t/* if error, position is not changed */\n\n\t//-- optionally to implement\n\tvirtual tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size) = 0;\n\t\t/* returns actually read size */\n\n\tvirtual tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size) = 0;\n\t\t/* returns actually written size */\n\n\tvirtual void TJS_INTF_METHOD SetEndOfStorage();\n\t\t// the default behavior is raising a exception\n\t\t/* if error, raises exception */\n\n\t//-- should re-implement for higher performance\n\tvirtual tjs_uint64 TJS_INTF_METHOD GetSize() = 0;\n\n\tvirtual ~tTJSBinaryStream() {;}\n\n\ttjs_uint64 GetPosition();\n\n\tvoid SetPosition(tjs_uint64 pos);\n\n\tvoid ReadBuffer(void *buffer, tjs_uint read_size);\n\tvoid WriteBuffer(const void *buffer, tjs_uint write_size);\n\n\ttjs_uint64 ReadI64LE(); // reads little-endian integers\n\ttjs_uint32 ReadI32LE();\n\ttjs_uint16 ReadI16LE();\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n\n}\n#endif\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjs.tab.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton implementation for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n/* C LALR(1) parser skeleton written by Richard Stallman, by\n   simplifying the original so-called \"semantic\" parser.  */\n\n/* All symbols defined below should begin with yy or YY, to avoid\n   infringing on user name space.  This should be done even for local\n   variables, as they might otherwise be expanded by user macros.\n   There are some unavoidable exceptions within include files to\n   define necessary library symbols; they are noted \"INFRINGES ON\n   USER NAME SPACE\" below.  */\n\n/* Identify Bison output.  */\n#define YYBISON 1\n\n/* Bison version.  */\n#define YYBISON_VERSION \"2.4.1\"\n\n/* Skeleton name.  */\n#define YYSKELETON_NAME \"yacc.c\"\n\n/* Pure parsers.  */\n#define YYPURE 1\n\n/* Push parsers.  */\n#define YYPUSH 0\n\n/* Pull parsers.  */\n#define YYPULL 1\n\n/* Using locations.  */\n#define YYLSP_NEEDED 0\n\n\n\n/* Copy the first part of user declarations.  */\n\n/* Line 189 of yacc.c  */\n#line 1 \"syntax/tjs.y\"\n\n/*---------------------------------------------------------------------------*/\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/*---------------------------------------------------------------------------*/\n/* tjs.y */\n/* TJS2 bison input file */\n\n\n#include <memory>\n\n\n#include \"tjsInterCodeGen.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsError.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n\n#define YYMALLOC\t::malloc\n#define YYREALLOC\t::realloc\n#define YYFREE\t\t::free\n\n/* param */\n#define YYPARSE_PARAM pm\n#define YYLEX_PARAM pm\n\n/* script block */\n#define sb ((tTJSScriptBlock*)pm)\n\n/* current context */\n#define cc (sb->GetCurrentContext())\n\n/* current node */\n#define cn (cc->GetCurrentNode())\n\n/* lexical analyzer */\n#define lx (sb->GetLexicalAnalyzer())\n\n\nnamespace TJS {\n\n/* yylex/yyerror prototype decl */\n#define YYLEX_PROTO_DECL int yylex(YYSTYPE *yylex, void *pm);\n\nint __yyerror(char * msg, void *pm);\n\n\n#define yyerror(msg) __yyerror(msg, pm);\n\n\n\n/* Line 189 of yacc.c  */\n#line 129 \"tjs.tab.cpp\"\n\n/* Enabling traces.  */\n#ifndef YYDEBUG\n# define YYDEBUG 0\n#endif\n\n/* Enabling verbose error messages.  */\n#ifdef YYERROR_VERBOSE\n# undef YYERROR_VERBOSE\n# define YYERROR_VERBOSE 1\n#else\n# define YYERROR_VERBOSE 0\n#endif\n\n/* Enabling the token table.  */\n#ifndef YYTOKEN_TABLE\n# define YYTOKEN_TABLE 0\n#endif\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     T_COMMA = 258,\n     T_EQUAL = 259,\n     T_AMPERSANDEQUAL = 260,\n     T_VERTLINEEQUAL = 261,\n     T_CHEVRONEQUAL = 262,\n     T_MINUSEQUAL = 263,\n     T_PLUSEQUAL = 264,\n     T_PERCENTEQUAL = 265,\n     T_SLASHEQUAL = 266,\n     T_BACKSLASHEQUAL = 267,\n     T_ASTERISKEQUAL = 268,\n     T_LOGICALOREQUAL = 269,\n     T_LOGICALANDEQUAL = 270,\n     T_RBITSHIFTEQUAL = 271,\n     T_LARITHSHIFTEQUAL = 272,\n     T_RARITHSHIFTEQUAL = 273,\n     T_QUESTION = 274,\n     T_LOGICALOR = 275,\n     T_LOGICALAND = 276,\n     T_VERTLINE = 277,\n     T_CHEVRON = 278,\n     T_AMPERSAND = 279,\n     T_NOTEQUAL = 280,\n     T_EQUALEQUAL = 281,\n     T_DISCNOTEQUAL = 282,\n     T_DISCEQUAL = 283,\n     T_SWAP = 284,\n     T_LT = 285,\n     T_GT = 286,\n     T_LTOREQUAL = 287,\n     T_GTOREQUAL = 288,\n     T_RARITHSHIFT = 289,\n     T_LARITHSHIFT = 290,\n     T_RBITSHIFT = 291,\n     T_PERCENT = 292,\n     T_SLASH = 293,\n     T_BACKSLASH = 294,\n     T_ASTERISK = 295,\n     T_EXCRAMATION = 296,\n     T_TILDE = 297,\n     T_DECREMENT = 298,\n     T_INCREMENT = 299,\n     T_NEW = 300,\n     T_DELETE = 301,\n     T_TYPEOF = 302,\n     T_PLUS = 303,\n     T_MINUS = 304,\n     T_SHARP = 305,\n     T_DOLLAR = 306,\n     T_ISVALID = 307,\n     T_INVALIDATE = 308,\n     T_INSTANCEOF = 309,\n     T_LPARENTHESIS = 310,\n     T_DOT = 311,\n     T_LBRACKET = 312,\n     T_THIS = 313,\n     T_SUPER = 314,\n     T_GLOBAL = 315,\n     T_RBRACKET = 316,\n     T_CLASS = 317,\n     T_RPARENTHESIS = 318,\n     T_COLON = 319,\n     T_SEMICOLON = 320,\n     T_LBRACE = 321,\n     T_RBRACE = 322,\n     T_CONTINUE = 323,\n     T_FUNCTION = 324,\n     T_DEBUGGER = 325,\n     T_DEFAULT = 326,\n     T_CASE = 327,\n     T_EXTENDS = 328,\n     T_FINALLY = 329,\n     T_PROPERTY = 330,\n     T_PRIVATE = 331,\n     T_PUBLIC = 332,\n     T_PROTECTED = 333,\n     T_STATIC = 334,\n     T_RETURN = 335,\n     T_BREAK = 336,\n     T_EXPORT = 337,\n     T_IMPORT = 338,\n     T_SWITCH = 339,\n     T_IN = 340,\n     T_INCONTEXTOF = 341,\n     T_FOR = 342,\n     T_WHILE = 343,\n     T_DO = 344,\n     T_IF = 345,\n     T_VAR = 346,\n     T_CONST = 347,\n     T_ENUM = 348,\n     T_GOTO = 349,\n     T_THROW = 350,\n     T_TRY = 351,\n     T_SETTER = 352,\n     T_GETTER = 353,\n     T_ELSE = 354,\n     T_CATCH = 355,\n     T_OMIT = 356,\n     T_SYNCHRONIZED = 357,\n     T_WITH = 358,\n     T_INT = 359,\n     T_REAL = 360,\n     T_STRING = 361,\n     T_OCTET = 362,\n     T_FALSE = 363,\n     T_NULL = 364,\n     T_TRUE = 365,\n     T_VOID = 366,\n     T_NAN = 367,\n     T_INFINITY = 368,\n     T_UPLUS = 369,\n     T_UMINUS = 370,\n     T_EVAL = 371,\n     T_POSTDECREMENT = 372,\n     T_POSTINCREMENT = 373,\n     T_IGNOREPROP = 374,\n     T_PROPACCESS = 375,\n     T_ARG = 376,\n     T_EXPANDARG = 377,\n     T_INLINEARRAY = 378,\n     T_ARRAYARG = 379,\n     T_INLINEDIC = 380,\n     T_DICELM = 381,\n     T_WITHDOT = 382,\n     T_THIS_PROXY = 383,\n     T_WITHDOT_PROXY = 384,\n     T_CONSTVAL = 385,\n     T_SYMBOL = 386,\n     T_REGEXP = 387,\n     T_VARIANT = 388\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 214 of yacc.c  */\n#line 60 \"syntax/tjs.y\"\n\n\ttjs_int\t\t\tnum;\n\ttTJSExprNode *\t\tnp;\n\n\n\n/* Line 214 of yacc.c  */\n#line 305 \"tjs.tab.cpp\"\n} YYSTYPE;\nYYLEX_PROTO_DECL\n\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n/* Copy the second part of user declarations.  */\n\n\n/* Line 264 of yacc.c  */\n#line 317 \"tjs.tab.cpp\"\n\n#ifdef short\n# undef short\n#endif\n\n#ifdef YYTYPE_UINT8\ntypedef YYTYPE_UINT8 yytype_uint8;\n#else\ntypedef unsigned char yytype_uint8;\n#endif\n\n#ifdef YYTYPE_INT8\ntypedef YYTYPE_INT8 yytype_int8;\n#elif (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\ntypedef signed char yytype_int8;\n#else\ntypedef short int yytype_int8;\n#endif\n\n#ifdef YYTYPE_UINT16\ntypedef YYTYPE_UINT16 yytype_uint16;\n#else\ntypedef unsigned short int yytype_uint16;\n#endif\n\n#ifdef YYTYPE_INT16\ntypedef YYTYPE_INT16 yytype_int16;\n#else\ntypedef short int yytype_int16;\n#endif\n\n#ifndef YYSIZE_T\n# ifdef __SIZE_TYPE__\n#  define YYSIZE_T __SIZE_TYPE__\n# elif defined size_t\n#  define YYSIZE_T size_t\n# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYSIZE_T size_t\n# else\n#  define YYSIZE_T unsigned int\n# endif\n#endif\n\n#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)\n\n#ifndef YY_\n# if YYENABLE_NLS\n#  if ENABLE_NLS\n#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */\n#   define YY_(msgid) dgettext (\"bison-runtime\", msgid)\n#  endif\n# endif\n# ifndef YY_\n#  define YY_(msgid) msgid\n# endif\n#endif\n\n/* Suppress unused-variable warnings by \"using\" E.  */\n#if ! defined lint || defined __GNUC__\n# define YYUSE(e) ((void) (e))\n#else\n# define YYUSE(e) /* empty */\n#endif\n\n/* Identity function, used to suppress warnings about constant conditions.  */\n#ifndef lint\n# define YYID(n) (n)\n#else\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic int\nYYID (int yyi)\n#else\nstatic int\nYYID (yyi)\n    int yyi;\n#endif\n{\n  return yyi;\n}\n#endif\n\n#if ! defined yyoverflow || YYERROR_VERBOSE\n\n/* The parser invokes alloca or malloc; define the necessary symbols.  */\n\n# ifdef YYSTACK_USE_ALLOCA\n#  if YYSTACK_USE_ALLOCA\n#   ifdef __GNUC__\n#    define YYSTACK_ALLOC __builtin_alloca\n#   elif defined __BUILTIN_VA_ARG_INCR\n#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */\n#   elif defined _AIX\n#    define YYSTACK_ALLOC __alloca\n#   elif defined _MSC_VER\n#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */\n#    define alloca _alloca\n#   else\n#    define YYSTACK_ALLOC alloca\n#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#     ifndef _STDLIB_H\n#      define _STDLIB_H 1\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n\n# ifdef YYSTACK_ALLOC\n   /* Pacify GCC's `empty if-body' warning.  */\n#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n    /* The OS might guarantee only one guard page at the bottom of the stack,\n       and a page size can be as small as 4096 bytes.  So we cannot safely\n       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number\n       to allow for a few compiler-allocated temporary stack slots.  */\n#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */\n#  endif\n# else\n#  define YYSTACK_ALLOC YYMALLOC\n#  define YYSTACK_FREE YYFREE\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM\n#  endif\n#  if (defined __cplusplus && ! defined _STDLIB_H \\\n       && ! ((defined YYMALLOC || defined malloc) \\\n\t     && (defined YYFREE || defined free)))\n#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#   ifndef _STDLIB_H\n#    define _STDLIB_H 1\n#   endif\n#  endif\n#  ifndef YYMALLOC\n#   define YYMALLOC malloc\n#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n#  ifndef YYFREE\n#   define YYFREE free\n#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid free (void *); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n# endif\n#endif /* ! defined yyoverflow || YYERROR_VERBOSE */\n\n\n#if (! defined yyoverflow \\\n     && (! defined __cplusplus \\\n\t || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))\n\n/* A type that is properly aligned for any stack member.  */\nunion yyalloc\n{\n  yytype_int16 yyss_alloc;\n  YYSTYPE yyvs_alloc;\n};\n\n/* The size of the maximum gap between one aligned stack and the next.  */\n# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\n\n/* The size of an array large to enough to hold all stacks, each with\n   N elements.  */\n# define YYSTACK_BYTES(N) \\\n     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \\\n      + YYSTACK_GAP_MAXIMUM)\n\n/* Copy COUNT objects from FROM to TO.  The source and destination do\n   not overlap.  */\n# ifndef YYCOPY\n#  if defined __GNUC__ && 1 < __GNUC__\n#   define YYCOPY(To, From, Count) \\\n      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))\n#  else\n#   define YYCOPY(To, From, Count)\t\t\\\n      do\t\t\t\t\t\\\n\t{\t\t\t\t\t\\\n\t  YYSIZE_T yyi;\t\t\t\t\\\n\t  for (yyi = 0; yyi < (Count); yyi++)\t\\\n\t    (To)[yyi] = (From)[yyi];\t\t\\\n\t}\t\t\t\t\t\\\n      while (YYID (0))\n#  endif\n# endif\n\n/* Relocate STACK from its old location to the new one.  The\n   local variables YYSIZE and YYSTACKSIZE give the old and new number of\n   elements in the stack, and YYPTR gives the new location of the\n   stack.  Advance YYPTR to a properly aligned location for the next\n   stack.  */\n# define YYSTACK_RELOCATE(Stack_alloc, Stack)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      {\t\t\t\t\t\t\t\t\t\\\n\tYYSIZE_T yynewbytes;\t\t\t\t\t\t\\\n\tYYCOPY (&yyptr->Stack_alloc, Stack, yysize);\t\t\t\\\n\tStack = &yyptr->Stack_alloc;\t\t\t\t\t\\\n\tyynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\\n\tyyptr += yynewbytes / sizeof (*yyptr);\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n\n#endif\n\n/* YYFINAL -- State number of the termination state.  */\n#define YYFINAL  4\n/* YYLAST -- Last index in YYTABLE.  */\n#define YYLAST   1527\n\n/* YYNTOKENS -- Number of terminals.  */\n#define YYNTOKENS  134\n/* YYNNTS -- Number of nonterminals.  */\n#define YYNNTS  108\n/* YYNRULES -- Number of rules.  */\n#define YYNRULES  271\n/* YYNRULES -- Number of states.  */\n#define YYNSTATES  458\n\n/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */\n#define YYUNDEFTOK  2\n#define YYMAXUTOK   388\n\n#define YYTRANSLATE(YYX)\t\t\t\t\t\t\\\n  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\n\n/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */\nstatic const yytype_uint8 yytranslate[] =\n{\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,\n      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,\n      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,\n      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,\n      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,\n      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,\n      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,\n     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,\n     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,\n     125,   126,   127,   128,   129,   130,   131,   132,   133\n};\n\n#if YYDEBUG\n/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in\n   YYRHS.  */\nstatic const yytype_uint16 yyprhs[] =\n{\n       0,     0,     3,     5,     6,     9,    10,    13,    17,    19,\n      21,    23,    26,    28,    30,    32,    34,    36,    39,    42,\n      45,    47,    49,    51,    53,    55,    57,    59,    61,    63,\n      65,    66,    71,    72,    73,    81,    82,    83,    93,    94,\n      95,   103,   104,   109,   119,   120,   121,   124,   126,   127,\n     129,   130,   132,   135,   138,   141,   143,   147,   150,   155,\n     156,   159,   162,   165,   168,   171,   174,   175,   182,   183,\n     189,   190,   194,   198,   204,   205,   207,   209,   213,   216,\n     221,   223,   227,   228,   235,   237,   239,   242,   245,   246,\n     254,   255,   259,   264,   267,   268,   274,   275,   278,   279,\n     285,   287,   291,   293,   296,   300,   301,   308,   309,   316,\n     320,   323,   324,   330,   332,   336,   341,   345,   347,   349,\n     353,   355,   359,   361,   365,   369,   373,   377,   381,   385,\n     389,   393,   397,   401,   405,   409,   413,   417,   421,   425,\n     427,   433,   435,   439,   441,   445,   447,   451,   453,   457,\n     459,   463,   465,   469,   473,   477,   481,   483,   487,   491,\n     495,   499,   501,   505,   509,   513,   515,   519,   523,   525,\n     529,   533,   537,   540,   543,   545,   548,   551,   554,   557,\n     560,   563,   566,   569,   572,   575,   578,   581,   584,   587,\n     590,   593,   597,   602,   605,   610,   613,   618,   621,   623,\n     627,   629,   633,   638,   640,   641,   646,   649,   652,   655,\n     656,   660,   662,   664,   666,   668,   670,   672,   674,   676,\n     678,   680,   682,   683,   687,   688,   692,   697,   699,   701,\n     705,   706,   708,   710,   712,   713,   718,   720,   724,   725,\n     727,   728,   735,   736,   738,   742,   746,   750,   751,   753,\n     754,   762,   763,   765,   767,   771,   774,   777,   779,   781,\n     783,   785,   786,   795,   796,   798,   802,   807,   812,   816,\n     820,   824\n};\n\n/* YYRHS -- A `-1'-separated list of the rules' RHS.  */\nstatic const yytype_int16 yyrhs[] =\n{\n     135,     0,    -1,   136,    -1,    -1,   137,   138,    -1,    -1,\n     138,   139,    -1,   138,     1,    65,    -1,   140,    -1,   141,\n      -1,    65,    -1,   198,    65,    -1,   149,    -1,   152,    -1,\n     143,    -1,   146,    -1,   154,    -1,    81,    65,    -1,    68,\n      65,    -1,    70,    65,    -1,   159,    -1,   164,    -1,   173,\n      -1,   181,    -1,   187,    -1,   188,    -1,   190,    -1,   192,\n      -1,   193,    -1,   196,    -1,    -1,    66,   142,   138,    67,\n      -1,    -1,    -1,    88,   144,    55,   198,    63,   145,   139,\n      -1,    -1,    -1,    89,   147,   139,    88,    55,   198,    63,\n     148,    65,    -1,    -1,    -1,    90,    55,   150,   198,   151,\n      63,   139,    -1,    -1,   149,    99,   153,   139,    -1,    87,\n      55,   155,    65,   157,    65,   158,    63,   139,    -1,    -1,\n      -1,   156,   160,    -1,   198,    -1,    -1,   198,    -1,    -1,\n     198,    -1,   160,    65,    -1,    91,   161,    -1,    92,   161,\n      -1,   162,    -1,   161,     3,   162,    -1,   131,   163,    -1,\n     131,   163,     4,   197,    -1,    -1,    64,   131,    -1,    64,\n     111,    -1,    64,   104,    -1,    64,   105,    -1,    64,   106,\n      -1,    64,   107,    -1,    -1,    69,   131,   165,   168,   163,\n     141,    -1,    -1,    69,   167,   168,   163,   141,    -1,    -1,\n      55,   172,    63,    -1,    55,   169,    63,    -1,    55,   170,\n       3,   172,    63,    -1,    -1,   170,    -1,   171,    -1,   170,\n       3,   171,    -1,   131,   163,    -1,   131,   163,     4,   197,\n      -1,    40,    -1,   131,   163,    40,    -1,    -1,    75,   131,\n      66,   174,   175,    67,    -1,   176,    -1,   178,    -1,   176,\n     178,    -1,   178,   176,    -1,    -1,    97,    55,   131,   163,\n      63,   177,   141,    -1,    -1,   180,   179,   141,    -1,    98,\n      55,    63,   163,    -1,    98,   163,    -1,    -1,    62,   131,\n     182,   183,   141,    -1,    -1,    73,   197,    -1,    -1,    73,\n     197,     3,   184,   185,    -1,   186,    -1,   185,     3,   186,\n      -1,   197,    -1,    80,    65,    -1,    80,   198,    65,    -1,\n      -1,    84,    55,   198,    63,   189,   141,    -1,    -1,   103,\n      55,   198,    63,   191,   139,    -1,    72,   198,    64,    -1,\n      71,    64,    -1,    -1,    96,   194,   139,   195,   139,    -1,\n     100,    -1,   100,    55,    63,    -1,   100,    55,   131,    63,\n      -1,    95,   198,    65,    -1,   200,    -1,   199,    -1,   199,\n      90,   198,    -1,   200,    -1,   199,     3,   200,    -1,   201,\n      -1,   201,    29,   200,    -1,   201,     4,   200,    -1,   201,\n       5,   200,    -1,   201,     6,   200,    -1,   201,     7,   200,\n      -1,   201,     8,   200,    -1,   201,     9,   200,    -1,   201,\n      10,   200,    -1,   201,    11,   200,    -1,   201,    12,   200,\n      -1,   201,    13,   200,    -1,   201,    14,   200,    -1,   201,\n      15,   200,    -1,   201,    18,   200,    -1,   201,    17,   200,\n      -1,   201,    16,   200,    -1,   202,    -1,   202,    19,   201,\n      64,   201,    -1,   203,    -1,   202,    20,   203,    -1,   204,\n      -1,   203,    21,   204,    -1,   205,    -1,   204,    22,   205,\n      -1,   206,    -1,   205,    23,   206,    -1,   207,    -1,   206,\n      24,   207,    -1,   208,    -1,   207,    25,   208,    -1,   207,\n      26,   208,    -1,   207,    27,   208,    -1,   207,    28,   208,\n      -1,   209,    -1,   208,    30,   209,    -1,   208,    31,   209,\n      -1,   208,    32,   209,    -1,   208,    33,   209,    -1,   210,\n      -1,   209,    34,   210,    -1,   209,    35,   210,    -1,   209,\n      36,   210,    -1,   211,    -1,   210,    48,   211,    -1,   210,\n      49,   211,    -1,   213,    -1,   211,    37,   213,    -1,   211,\n      38,   213,    -1,   211,    39,   213,    -1,   212,   213,    -1,\n     211,    40,    -1,   214,    -1,    41,   213,    -1,    42,   213,\n      -1,    43,   213,    -1,    44,   213,    -1,    45,   221,    -1,\n      53,   213,    -1,    52,   213,    -1,   214,    52,    -1,    46,\n     213,    -1,    47,   213,    -1,    50,   213,    -1,    51,   213,\n      -1,    48,   213,    -1,    49,   213,    -1,    24,   213,    -1,\n      40,   213,    -1,   214,    54,   213,    -1,    55,   104,    63,\n     213,    -1,   104,   213,    -1,    55,   105,    63,   213,    -1,\n     105,   213,    -1,    55,   106,    63,   213,    -1,   106,   213,\n      -1,   215,    -1,   215,    86,   214,    -1,   218,    -1,    55,\n     198,    63,    -1,   215,    57,   198,    61,    -1,   221,    -1,\n      -1,   215,    56,   216,   131,    -1,   215,    44,    -1,   215,\n      43,    -1,   215,    41,    -1,    -1,    56,   217,   131,    -1,\n     130,    -1,   131,    -1,    58,    -1,    59,    -1,   166,    -1,\n      60,    -1,   111,    -1,   224,    -1,   228,    -1,   233,    -1,\n     238,    -1,    -1,    11,   219,   132,    -1,    -1,    38,   220,\n     132,    -1,   215,    55,   222,    63,    -1,   101,    -1,   223,\n      -1,   222,     3,   223,    -1,    -1,    40,    -1,   212,    -1,\n     197,    -1,    -1,    57,   225,   226,    61,    -1,   227,    -1,\n     226,     3,   227,    -1,    -1,   197,    -1,    -1,    37,    57,\n     229,   230,   232,    61,    -1,    -1,   231,    -1,   230,     3,\n     231,    -1,   197,     3,   197,    -1,   131,    64,   197,    -1,\n      -1,     3,    -1,    -1,    55,    92,    63,    57,   234,   235,\n      61,    -1,    -1,   236,    -1,   237,    -1,   236,     3,   237,\n      -1,    49,   130,    -1,    48,   130,    -1,   130,    -1,   111,\n      -1,   233,    -1,   238,    -1,    -1,    55,    92,    63,    37,\n      57,   239,   240,    61,    -1,    -1,   241,    -1,   240,     3,\n     241,    -1,   130,     3,    49,   130,    -1,   130,     3,    48,\n     130,    -1,   130,     3,   130,    -1,   130,     3,   111,    -1,\n     130,     3,   233,    -1,   130,     3,   238,    -1\n};\n\n/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\nstatic const yytype_uint16 yyrline[] =\n{\n       0,   217,   217,   222,   222,   228,   230,   231,   238,   239,\n     244,   245,   246,   247,   248,   249,   250,   251,   252,   253,\n     254,   255,   256,   257,   258,   259,   260,   261,   262,   263,\n     268,   268,   275,   276,   275,   282,   285,   282,   291,   292,\n     291,   298,   298,   304,   314,   315,   315,   317,   323,   324,\n     329,   330,   335,   339,   340,   347,   348,   353,   355,   360,\n     362,   363,   364,   365,   366,   367,   372,   372,   382,   382,\n     395,   397,   398,   399,   403,   405,   409,   410,   414,   416,\n     421,   423,   435,   434,   443,   444,   445,   446,   450,   450,\n     461,   461,   470,   471,   477,   477,   484,   486,   487,   487,\n     492,   493,   497,   502,   503,   510,   509,   517,   516,   523,\n     524,   529,   529,   536,   537,   538,   544,   549,   553,   554,\n     559,   560,   565,   566,   567,   568,   569,   570,   571,   572,\n     573,   574,   575,   576,   577,   578,   579,   580,   581,   586,\n     587,   595,   596,   600,   601,   606,   607,   611,   612,   616,\n     617,   621,   622,   623,   624,   625,   629,   630,   631,   632,\n     633,   637,   638,   639,   640,   645,   646,   647,   651,   652,\n     653,   654,   655,   659,   663,   664,   665,   666,   667,   668,\n     669,   670,   671,   672,   673,   674,   675,   676,   677,   678,\n     679,   680,   681,   682,   683,   684,   685,   686,   690,   691,\n     696,   697,   698,   699,   700,   700,   704,   705,   706,   707,\n     707,   715,   717,   720,   721,   722,   723,   724,   725,   726,\n     727,   728,   729,   729,   732,   732,   740,   745,   746,   747,\n     751,   752,   753,   754,   760,   760,   769,   770,   775,   776,\n     781,   781,   791,   793,   794,   799,   800,   807,   809,   816,\n     816,   826,   828,   834,   835,   841,   842,   843,   844,   845,\n     846,   851,   851,   863,   865,   866,   871,   872,   873,   874,\n     875,   876\n};\n#endif\n\n#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE\n/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */\nstatic const char *const yytname[] =\n{\n  \"$end\", \"error\", \"$undefined\", \"\\\",\\\"\", \"\\\"=\\\"\", \"\\\"&=\\\"\", \"\\\"|=\\\"\",\n  \"\\\"^=\\\"\", \"\\\"-=\\\"\", \"\\\"+=\\\"\", \"\\\"%=\\\"\", \"\\\"/=\\\"\", \"\\\"\\\\\\\\=\\\"\", \"\\\"*=\\\"\",\n  \"\\\"||=\\\"\", \"\\\"&&=\\\"\", \"\\\">>>=\\\"\", \"\\\"<<=\\\"\", \"\\\">>=\\\"\", \"\\\"?\\\"\",\n  \"\\\"||\\\"\", \"\\\"&&\\\"\", \"\\\"|\\\"\", \"\\\"^\\\"\", \"\\\"&\\\"\", \"\\\"!=\\\"\", \"\\\"==\\\"\",\n  \"\\\"!==\\\"\", \"\\\"===\\\"\", \"\\\"<->\\\"\", \"\\\"<\\\"\", \"\\\">\\\"\", \"\\\"<=\\\"\", \"\\\">=\\\"\",\n  \"\\\">>\\\"\", \"\\\"<<\\\"\", \"\\\">>>\\\"\", \"\\\"%\\\"\", \"\\\"/\\\"\", \"\\\"\\\\\\\\\\\"\", \"\\\"*\\\"\",\n  \"\\\"!\\\"\", \"\\\"~\\\"\", \"\\\"--\\\"\", \"\\\"++\\\"\", \"\\\"new\\\"\", \"\\\"delete\\\"\",\n  \"\\\"typeof\\\"\", \"\\\"+\\\"\", \"\\\"-\\\"\", \"\\\"#\\\"\", \"\\\"$\\\"\", \"\\\"isvalid\\\"\",\n  \"\\\"invalidate\\\"\", \"\\\"instanceof\\\"\", \"\\\"(\\\"\", \"\\\".\\\"\", \"\\\"[\\\"\",\n  \"\\\"this\\\"\", \"\\\"super\\\"\", \"\\\"global\\\"\", \"\\\"]\\\"\", \"\\\"class\\\"\", \"\\\")\\\"\",\n  \"\\\":\\\"\", \"\\\";\\\"\", \"\\\"{\\\"\", \"\\\"}\\\"\", \"\\\"continue\\\"\", \"\\\"function\\\"\",\n  \"\\\"debugger\\\"\", \"\\\"default\\\"\", \"\\\"case\\\"\", \"\\\"extends\\\"\", \"\\\"finally\\\"\",\n  \"\\\"property\\\"\", \"\\\"private\\\"\", \"\\\"public\\\"\", \"\\\"protected\\\"\",\n  \"\\\"static\\\"\", \"\\\"return\\\"\", \"\\\"break\\\"\", \"\\\"export\\\"\", \"\\\"import\\\"\",\n  \"\\\"switch\\\"\", \"\\\"in\\\"\", \"\\\"incontextof\\\"\", \"\\\"for\\\"\", \"\\\"while\\\"\",\n  \"\\\"do\\\"\", \"\\\"if\\\"\", \"\\\"var\\\"\", \"\\\"const\\\"\", \"\\\"enum\\\"\", \"\\\"goto\\\"\",\n  \"\\\"throw\\\"\", \"\\\"try\\\"\", \"\\\"setter\\\"\", \"\\\"getter\\\"\", \"\\\"else\\\"\",\n  \"\\\"catch\\\"\", \"\\\"...\\\"\", \"\\\"synchronized\\\"\", \"\\\"with\\\"\", \"\\\"int\\\"\",\n  \"\\\"real\\\"\", \"\\\"string\\\"\", \"\\\"octet\\\"\", \"\\\"false\\\"\", \"\\\"null\\\"\",\n  \"\\\"true\\\"\", \"\\\"void\\\"\", \"\\\"NaN\\\"\", \"\\\"Infinity\\\"\", \"T_UPLUS\", \"T_UMINUS\",\n  \"T_EVAL\", \"T_POSTDECREMENT\", \"T_POSTINCREMENT\", \"T_IGNOREPROP\",\n  \"T_PROPACCESS\", \"T_ARG\", \"T_EXPANDARG\", \"T_INLINEARRAY\", \"T_ARRAYARG\",\n  \"T_INLINEDIC\", \"T_DICELM\", \"T_WITHDOT\", \"T_THIS_PROXY\",\n  \"T_WITHDOT_PROXY\", \"T_CONSTVAL\", \"T_SYMBOL\", \"T_REGEXP\", \"T_VARIANT\",\n  \"$accept\", \"program\", \"global_list\", \"$@1\", \"def_list\",\n  \"block_or_statement\", \"statement\", \"block\", \"$@2\", \"while\", \"$@3\", \"$@4\",\n  \"do_while\", \"$@5\", \"$@6\", \"if\", \"$@7\", \"$@8\", \"if_else\", \"$@9\", \"for\",\n  \"for_first_clause\", \"$@10\", \"for_second_clause\", \"for_third_clause\",\n  \"variable_def\", \"variable_def_inner\", \"variable_id_list\", \"variable_id\",\n  \"variable_type\", \"func_def\", \"$@11\", \"func_expr_def\", \"$@12\",\n  \"func_decl_arg_opt\", \"func_decl_arg_list\", \"func_decl_arg_at_least_one\",\n  \"func_decl_arg\", \"func_decl_arg_collapse\", \"property_def\", \"$@13\",\n  \"property_handler_def_list\", \"property_handler_setter\", \"$@14\",\n  \"property_handler_getter\", \"$@15\", \"property_getter_handler_head\",\n  \"class_def\", \"$@16\", \"class_extender\", \"$@17\", \"extends_list\",\n  \"extends_name\", \"return\", \"switch\", \"$@18\", \"with\", \"$@19\", \"case\",\n  \"try\", \"$@20\", \"catch\", \"throw\", \"expr_no_comma\", \"expr\", \"comma_expr\",\n  \"assign_expr\", \"cond_expr\", \"logical_or_expr\", \"logical_and_expr\",\n  \"inclusive_or_expr\", \"exclusive_or_expr\", \"and_expr\", \"identical_expr\",\n  \"compare_expr\", \"shift_expr\", \"add_sub_expr\", \"mul_div_expr\",\n  \"mul_div_expr_and_asterisk\", \"unary_expr\", \"incontextof_expr\",\n  \"priority_expr\", \"$@21\", \"$@22\", \"factor_expr\", \"$@23\", \"$@24\",\n  \"func_call_expr\", \"call_arg_list\", \"call_arg\", \"inline_array\", \"$@25\",\n  \"array_elm_list\", \"array_elm\", \"inline_dic\", \"$@26\", \"dic_elm_list\",\n  \"dic_elm\", \"dic_dummy_elm_opt\", \"const_inline_array\", \"$@27\",\n  \"const_array_elm_list_opt\", \"const_array_elm_list\", \"const_array_elm\",\n  \"const_inline_dic\", \"$@28\", \"const_dic_elm_list\", \"const_dic_elm\", 0\n};\n#endif\n\n# ifdef YYPRINT\n/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to\n   token YYLEX-NUM.  */\nstatic const yytype_uint16 yytoknum[] =\n{\n       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\n     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,\n     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,\n     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,\n     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,\n     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,\n     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,\n     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,\n     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,\n     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,\n     365,   366,   367,   368,   369,   370,   371,   372,   373,   374,\n     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,\n     385,   386,   387,   388\n};\n# endif\n\n/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\nstatic const yytype_uint8 yyr1[] =\n{\n       0,   134,   135,   137,   136,   138,   138,   138,   139,   139,\n     140,   140,   140,   140,   140,   140,   140,   140,   140,   140,\n     140,   140,   140,   140,   140,   140,   140,   140,   140,   140,\n     142,   141,   144,   145,   143,   147,   148,   146,   150,   151,\n     149,   153,   152,   154,   155,   156,   155,   155,   157,   157,\n     158,   158,   159,   160,   160,   161,   161,   162,   162,   163,\n     163,   163,   163,   163,   163,   163,   165,   164,   167,   166,\n     168,   168,   168,   168,   169,   169,   170,   170,   171,   171,\n     172,   172,   174,   173,   175,   175,   175,   175,   177,   176,\n     179,   178,   180,   180,   182,   181,   183,   183,   184,   183,\n     185,   185,   186,   187,   187,   189,   188,   191,   190,   192,\n     192,   194,   193,   195,   195,   195,   196,   197,   198,   198,\n     199,   199,   200,   200,   200,   200,   200,   200,   200,   200,\n     200,   200,   200,   200,   200,   200,   200,   200,   200,   201,\n     201,   202,   202,   203,   203,   204,   204,   205,   205,   206,\n     206,   207,   207,   207,   207,   207,   208,   208,   208,   208,\n     208,   209,   209,   209,   209,   210,   210,   210,   211,   211,\n     211,   211,   211,   212,   213,   213,   213,   213,   213,   213,\n     213,   213,   213,   213,   213,   213,   213,   213,   213,   213,\n     213,   213,   213,   213,   213,   213,   213,   213,   214,   214,\n     215,   215,   215,   215,   216,   215,   215,   215,   215,   217,\n     215,   218,   218,   218,   218,   218,   218,   218,   218,   218,\n     218,   218,   219,   218,   220,   218,   221,   222,   222,   222,\n     223,   223,   223,   223,   225,   224,   226,   226,   227,   227,\n     229,   228,   230,   230,   230,   231,   231,   232,   232,   234,\n     233,   235,   235,   236,   236,   237,   237,   237,   237,   237,\n     237,   239,   238,   240,   240,   240,   241,   241,   241,   241,\n     241,   241\n};\n\n/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */\nstatic const yytype_uint8 yyr2[] =\n{\n       0,     2,     1,     0,     2,     0,     2,     3,     1,     1,\n       1,     2,     1,     1,     1,     1,     1,     2,     2,     2,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       0,     4,     0,     0,     7,     0,     0,     9,     0,     0,\n       7,     0,     4,     9,     0,     0,     2,     1,     0,     1,\n       0,     1,     2,     2,     2,     1,     3,     2,     4,     0,\n       2,     2,     2,     2,     2,     2,     0,     6,     0,     5,\n       0,     3,     3,     5,     0,     1,     1,     3,     2,     4,\n       1,     3,     0,     6,     1,     1,     2,     2,     0,     7,\n       0,     3,     4,     2,     0,     5,     0,     2,     0,     5,\n       1,     3,     1,     2,     3,     0,     6,     0,     6,     3,\n       2,     0,     5,     1,     3,     4,     3,     1,     1,     3,\n       1,     3,     1,     3,     3,     3,     3,     3,     3,     3,\n       3,     3,     3,     3,     3,     3,     3,     3,     3,     1,\n       5,     1,     3,     1,     3,     1,     3,     1,     3,     1,\n       3,     1,     3,     3,     3,     3,     1,     3,     3,     3,\n       3,     1,     3,     3,     3,     1,     3,     3,     1,     3,\n       3,     3,     2,     2,     1,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     3,     4,     2,     4,     2,     4,     2,     1,     3,\n       1,     3,     4,     1,     0,     4,     2,     2,     2,     0,\n       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     0,     3,     0,     3,     4,     1,     1,     3,\n       0,     1,     1,     1,     0,     4,     1,     3,     0,     1,\n       0,     6,     0,     1,     3,     3,     3,     0,     1,     0,\n       7,     0,     1,     1,     3,     2,     2,     1,     1,     1,\n       1,     0,     8,     0,     1,     3,     4,     4,     3,     3,\n       3,     3\n};\n\n/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state\n   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero\n   means the default is an error.  */\nstatic const yytype_uint16 yydefact[] =\n{\n       3,     0,     2,     5,     1,     0,     0,   222,     0,     0,\n     224,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,   209,   234,   213,   214,\n     216,     0,    10,    30,     0,    68,     0,     0,     0,     0,\n       0,     0,     0,     0,    32,    35,     0,     0,     0,     0,\n     111,     0,     0,     0,     0,   217,   211,   212,     6,     8,\n       9,    14,    15,    12,    13,    16,    20,     0,    21,   215,\n      22,    23,    24,    25,    26,    27,    28,    29,     0,   118,\n     120,   122,   139,   141,   143,   145,   147,   149,   151,   156,\n     161,   165,     0,   168,   174,   198,   200,   203,   218,   219,\n     220,   221,     7,     0,    68,   189,   240,     0,   190,   175,\n     176,   177,   178,     0,     0,   179,   183,   184,   187,   188,\n     185,   186,   181,   180,     0,     0,     0,     0,     0,     0,\n     238,    94,     5,    18,    66,    70,    19,   110,     0,     0,\n     103,     0,    17,     0,    45,     0,     0,    38,    59,    53,\n      55,    54,     0,     0,     0,   193,   195,   197,    41,    52,\n      11,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,   173,   172,   182,     0,   208,   207,   206,   230,   204,\n       0,     0,   223,   242,   225,     0,     0,     0,     0,   201,\n     210,   239,   117,     0,   236,    96,     0,    70,    74,    59,\n     109,    82,   104,     0,     0,     0,    47,     0,     0,     0,\n       0,    57,     0,   116,     0,     0,     0,   121,   119,   124,\n     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,\n     135,   138,   137,   136,   123,     0,   142,   144,   146,   148,\n     150,   152,   153,   154,   155,   157,   158,   159,   160,   162,\n     163,   164,   166,   167,   169,   170,   171,   191,   231,   227,\n     233,   232,     0,   228,     0,     0,   199,   212,     0,   247,\n     243,     0,   249,   192,   194,   196,   238,   235,     0,     0,\n      31,    59,    80,    59,     0,    75,    76,     0,     0,     0,\n     105,    48,    46,     0,     0,    39,    62,    63,    64,    65,\n      61,    60,     0,    56,   113,     0,   107,    42,     0,   230,\n     226,   205,   202,     0,     0,   248,     0,   261,   251,   237,\n      97,    95,     0,    78,    72,     0,    71,    69,     0,    59,\n       0,    84,    85,    90,     0,     0,    49,    33,     0,     0,\n      58,     0,   112,     0,   140,   229,   246,   245,   244,   241,\n     263,     0,     0,     0,   258,   257,   259,     0,   252,   253,\n     260,    98,    67,     0,    81,    77,     0,     0,     0,    93,\n      83,    86,    87,     0,   106,    50,     0,     0,     0,   114,\n       0,   108,     0,     0,   264,   256,   255,   250,     0,     0,\n      79,    73,    59,    59,    91,     0,    51,    34,    36,    40,\n     115,     0,     0,   262,   254,    99,   100,   102,     0,    92,\n       0,     0,     0,     0,   269,   268,   270,   271,   265,     0,\n      88,    43,    37,   267,   266,   101,     0,    89\n};\n\n/* YYDEFGOTO[NTERM-NUM].  */\nstatic const yytype_int16 yydefgoto[] =\n{\n      -1,     1,     2,     3,     5,    58,    59,    60,   132,    61,\n     145,   406,    62,   146,   441,    63,   239,   369,    64,   246,\n      65,   234,   235,   365,   425,    66,    67,   149,   150,   241,\n      68,   227,    69,   135,   229,   314,   315,   316,   317,    70,\n     319,   360,   361,   456,   362,   403,   363,    71,   225,   309,\n     419,   435,   436,    72,    73,   364,    74,   373,    75,    76,\n     153,   335,    77,   221,    78,    79,    80,    81,    82,    83,\n      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,\n      94,    95,   294,   129,    96,   103,   107,    97,   292,   293,\n      98,   130,   223,   224,    99,   213,   299,   300,   346,   100,\n     348,   387,   388,   389,   101,   380,   413,   414\n};\n\n/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n   STATE-NUM.  */\n#define YYPACT_NINF -340\nstatic const yytype_int16 yypact[] =\n{\n    -340,    22,  -340,  -340,  -340,   307,    -5,  -340,  1257,   -23,\n    -340,  1257,  1257,  1257,  1257,  1257,    40,  1257,  1257,  1257,\n    1257,  1257,  1257,  1257,  1257,   595,  -340,  -340,  -340,  -340,\n    -340,   -56,  -340,  -340,    66,     2,    85,    97,  1257,    32,\n     691,    99,   117,   118,  -340,  -340,   119,    52,    52,  1257,\n    -340,   132,  1257,  1257,  1257,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,    92,  -340,  -340,  -340,   127,  -340,  -340,\n    -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,   131,     1,\n    -340,   226,    94,   163,   181,   186,   189,   129,    -1,   105,\n      68,   168,  1257,  -340,   -27,    67,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,    78,  -340,  -340,  -340,    93,  -340,  -340,\n    -340,  -340,  -340,   734,   138,   145,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,  -340,   159,   830,   926,  1022,   161,    95,\n    1257,  -340,  -340,  -340,  -340,   172,  -340,  -340,   165,   179,\n    -340,   182,  -340,  1257,  1065,   191,   499,  -340,   187,   249,\n    -340,   249,   192,   499,  1257,  -340,  -340,  -340,  -340,  -340,\n    -340,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,\n    1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,\n    1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,\n    1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,  1257,\n    1257,  -340,  -340,  -340,  1257,  -340,  -340,  -340,  1161,  -340,\n    1257,    40,  -340,  1300,  -340,   -31,  1257,  1257,  1257,  -340,\n    -340,  -340,  -340,    15,  -340,   183,   403,   172,   -24,   187,\n    -340,  -340,  -340,   195,   194,    53,  -340,  1257,   174,  1257,\n      21,   256,    52,  -340,   164,   206,   499,  -340,  -340,  -340,\n    -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,  -340,  -340,   207,   163,   181,   186,   189,\n     129,    -1,    -1,    -1,    -1,   105,   105,   105,   105,    68,\n      68,    68,   168,   168,  -340,  -340,  -340,  -340,  1257,  -340,\n    -340,  1257,    18,  -340,   139,   211,  -340,   209,   271,   272,\n    -340,   219,  -340,  -340,  -340,  -340,  1257,  -340,  1257,   212,\n    -340,   187,  -340,   187,   214,   276,  -340,   217,   212,    23,\n    -340,  1257,  -340,   218,   227,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  1257,  -340,   228,   499,  -340,  -340,  1257,  1396,\n    -340,  -340,  -340,  1257,  1257,  1300,   223,  -340,     4,  -340,\n     282,  -340,   212,    90,  -340,   -24,  -340,  -340,   231,   -45,\n     220,   190,   193,  -340,   212,   224,  -340,  -340,  1257,   229,\n    -340,   -49,  -340,   499,  -340,  -340,  -340,  -340,  -340,  -340,\n     167,   169,   170,   201,  -340,  -340,  -340,   233,   295,  -340,\n    -340,  -340,  -340,  1257,  -340,  -340,   238,   171,   240,  -340,\n    -340,  -340,  -340,   212,  -340,  1257,   499,   241,   499,  -340,\n     242,  -340,   303,    25,  -340,  -340,  -340,  -340,     4,  1257,\n    -340,  -340,   187,   187,  -340,   246,  -340,  -340,  -340,  -340,\n    -340,    35,   167,  -340,  -340,   308,  -340,  -340,   247,  -340,\n     499,   248,   184,   185,  -340,  -340,  -340,  -340,  -340,  1257,\n    -340,  -340,  -340,  -340,  -340,  -340,   212,  -340\n};\n\n/* YYPGOTO[NTERM-NUM].  */\nstatic const yytype_int16 yypgoto[] =\n{\n    -340,  -340,  -340,  -340,   180,  -145,  -340,  -298,  -340,  -340,\n    -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,  -340,  -340,  -340,    81,   269,    77,  -224,\n    -340,  -340,  -340,  -340,    96,  -340,  -340,   -35,   -33,  -340,\n    -340,  -340,   -38,  -340,   -36,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  -123,  -340,  -340,  -340,  -340,  -340,  -340,  -340,\n    -340,  -340,  -340,  -196,   -25,  -340,  -128,  -176,  -340,   147,\n     148,   146,   149,   150,   -19,    29,  -138,   -37,  -201,    50,\n     122,   314,  -340,  -340,  -340,  -340,  -340,   319,  -340,    -3,\n    -340,  -340,  -340,    31,  -340,  -340,  -340,    -6,  -340,  -339,\n    -340,  -340,  -340,   -78,  -325,  -340,  -340,   -90\n};\n\n/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If\n   positive, shift that token.  If negative, reduce the rule which\n   number is the opposite.  If zero, do what YYDEFACT says.\n   If YYTABLE_NINF, syntax error.  */\n#define YYTABLE_NINF -204\nstatic const yytype_int16 yytable[] =\n{\n     128,   238,   222,   265,   161,   318,   301,   291,   244,   386,\n     398,   351,   290,   138,   409,   141,   312,   298,   306,   240,\n     357,   339,     4,   390,   152,   203,   302,   204,   432,   189,\n     190,   191,   192,   247,   106,   249,   250,   251,   252,   253,\n     254,   255,   256,   257,   258,   259,   260,   261,   262,   263,\n     264,     7,   381,   382,   392,   279,   280,   281,   105,   383,\n     102,   108,   109,   110,   111,   112,   404,   116,   117,   118,\n     119,   120,   121,   122,   123,   131,   307,     9,    10,   386,\n     222,   340,   410,   442,   443,   222,   433,   352,   128,   353,\n     383,   162,   446,   390,   393,   113,    26,    27,    28,    29,\n      30,   337,   155,   156,   157,   424,   447,   313,   205,   104,\n     206,   207,   350,   179,   180,   384,   196,   197,   233,   236,\n     358,   359,   208,   209,   210,   326,   327,   328,   329,   245,\n     394,   133,   330,   134,   385,   399,   370,   248,   291,   193,\n     194,   195,   202,   290,    47,    48,   444,   376,   377,   298,\n     136,    55,   331,   211,   185,   186,   187,   188,   457,   282,\n     283,   137,   374,   139,   142,   445,   271,   272,   273,   274,\n      56,    57,   143,   144,   147,   155,   156,   157,   222,   205,\n     222,   206,   207,   148,   181,   295,  -203,   154,  -203,  -203,\n     372,   158,   159,   208,   209,   210,   160,   420,   438,   439,\n    -203,  -203,  -203,   182,   222,   198,   199,   200,   201,   183,\n     212,   222,   323,   184,   325,   222,   222,   222,   275,   276,\n     277,   278,   215,   437,   219,   214,   220,   228,   411,   230,\n     163,   164,   165,   166,   167,   168,   169,   170,   171,   172,\n     173,   174,   175,   176,   177,   231,   237,   232,   284,   285,\n     286,   240,   242,   437,   287,   178,   308,   243,   320,   321,\n     332,   427,   324,   429,   334,   222,   303,   304,   305,   336,\n     341,   338,   342,   343,   344,   345,   347,   354,    33,   355,\n     356,   367,   368,   371,   379,   391,   397,   400,   359,   405,\n     358,   222,   408,   124,   417,   451,   366,   412,   418,   415,\n     416,   421,   422,   423,   428,   430,   431,    -4,     6,   440,\n     450,   449,   226,   452,   453,   454,   322,   151,     7,   333,\n     395,   222,   396,   311,   402,   401,   455,   266,   268,   267,\n     114,     8,   269,   296,   270,   115,   375,   349,   108,   378,\n     434,   202,   448,   407,     9,    10,     0,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n      24,     0,    25,    26,    27,    28,    29,    30,     0,    31,\n       0,     0,    32,    33,     0,    34,    35,    36,    37,    38,\n     426,     0,    39,     0,     0,     0,     0,    40,    41,     0,\n       0,    42,     0,     0,    43,    44,    45,    46,    47,    48,\n       0,     0,    49,    50,     6,     0,     0,     0,     0,     0,\n      51,    52,    53,    54,     7,     0,     0,     0,    55,     0,\n       0,     0,     0,     0,     0,     0,     0,     8,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,    56,    57,     0,\n       9,    10,     0,    11,    12,    13,    14,    15,    16,    17,\n      18,    19,    20,    21,    22,    23,    24,     0,    25,    26,\n      27,    28,    29,    30,     0,    31,     0,     0,    32,    33,\n     310,    34,    35,    36,    37,    38,     0,     0,    39,     0,\n       0,     0,     0,    40,    41,     0,     0,    42,     0,     0,\n      43,    44,    45,    46,    47,    48,     0,     0,    49,    50,\n       0,     0,     0,     0,     0,     0,    51,    52,    53,    54,\n       7,     0,     0,     0,    55,     0,     0,     0,     0,     0,\n       0,     0,     0,     8,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,    56,    57,     0,     9,    10,     0,    11,\n      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,\n      22,    23,    24,     0,    25,    26,    27,    28,    29,    30,\n       0,    31,     0,     0,    32,    33,     0,    34,    35,    36,\n      37,    38,     0,     0,    39,     0,     0,     0,     0,    40,\n      41,     0,     0,    42,     0,     0,    43,    44,    45,    46,\n      47,    48,     0,     0,    49,    50,     0,     0,     0,     0,\n       0,     0,    51,    52,    53,    54,     7,     0,     0,     0,\n      55,     0,     0,     0,     0,     0,     0,     0,     0,     8,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,    56,\n      57,     0,     9,    10,     0,    11,    12,    13,    14,    15,\n      16,    17,    18,    19,    20,    21,    22,    23,    24,     0,\n      25,    26,    27,    28,    29,    30,     0,     0,     0,     0,\n       0,     0,     0,     0,   104,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,   124,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,   125,\n     126,   127,     7,     0,     0,     0,    55,     0,     0,     0,\n       0,     0,     0,     0,     0,     8,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,    56,    57,     0,     9,    10,\n       0,    11,    12,    13,    14,    15,    16,    17,    18,    19,\n      20,    21,    22,    23,    24,     7,    25,    26,    27,    28,\n      29,    30,     0,     0,     0,     0,   140,     0,     8,     0,\n     104,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     9,    10,     0,    11,    12,    13,    14,    15,    16,\n      17,    18,    19,    20,    21,    22,    23,    24,     0,    25,\n      26,    27,    28,    29,    30,    52,    53,    54,     0,     0,\n       0,     0,    55,   104,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,    56,    57,     0,     0,     0,   124,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,    52,    53,\n      54,     7,     0,     0,     0,    55,     0,     0,     0,     0,\n       0,     0,     0,     0,     8,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,    56,    57,     0,     9,    10,     0,\n      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,     0,    25,    26,    27,    28,    29,\n      30,     0,     0,   216,     0,     0,     0,     0,     0,   104,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,    52,    53,    54,     7,     0,     0,\n       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,\n       8,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n      56,    57,     0,     9,    10,     0,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n       0,    25,    26,    27,    28,    29,    30,     0,     0,   217,\n       0,     0,     0,     0,     0,   104,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n      52,    53,    54,     7,     0,     0,     0,    55,     0,     0,\n       0,     0,     0,     0,     0,     0,     8,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,    56,    57,     0,     9,\n      10,     0,    11,    12,    13,    14,    15,    16,    17,    18,\n      19,    20,    21,    22,    23,    24,     7,    25,    26,    27,\n      28,    29,    30,     0,     0,   218,     0,     0,     0,     8,\n       0,   104,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     9,    10,     0,    11,    12,    13,    14,    15,\n      16,    17,    18,    19,    20,    21,    22,    23,    24,     0,\n      25,    26,    27,    28,    29,    30,    52,    53,    54,     0,\n     -44,     0,     0,    55,   104,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,    56,    57,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,    52,\n      53,    54,     7,     0,     0,     0,    55,     0,     0,     0,\n       0,     0,     0,     0,     0,     8,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,    56,    57,     0,     9,    10,\n       0,   288,    12,    13,    14,    15,    16,    17,    18,    19,\n      20,    21,    22,    23,    24,     0,    25,    26,    27,    28,\n      29,    30,     0,     0,     0,     0,     0,     0,     0,     0,\n     104,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,   289,     0,     0,    52,    53,    54,     7,     0,\n       0,     0,    55,     0,     0,     0,     0,     0,     0,     0,\n       0,     8,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,    56,    57,     0,     9,    10,     0,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n      24,     7,    25,    26,    27,    28,    29,    30,     0,     0,\n       0,     0,     0,     0,     8,     0,   104,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     9,    10,     0,\n      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,     0,    25,    26,    27,    28,    29,\n      30,    52,    53,    54,     0,     0,     0,     0,    55,   104,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,    56,    57,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,    52,    53,    54,     7,     0,     0,\n       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,\n       8,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n      56,   297,     0,     9,    10,     0,   288,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n       0,    25,    26,    27,    28,    29,    30,     0,     0,     0,\n       0,     0,     0,     0,     0,   104,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n      52,    53,    54,     0,     0,     0,     0,    55,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,    56,    57\n};\n\nstatic const yytype_int16 yycheck[] =\n{\n      25,   146,   130,   179,     3,   229,    37,   208,   153,   348,\n      55,   309,   208,    38,    63,    40,    40,   213,     3,    64,\n     318,     3,     0,   348,    49,    52,    57,    54,     3,    30,\n      31,    32,    33,   161,    57,   163,   164,   165,   166,   167,\n     168,   169,   170,   171,   172,   173,   174,   175,   176,   177,\n     178,    11,    48,    49,   352,   193,   194,   195,     8,    55,\n      65,    11,    12,    13,    14,    15,   364,    17,    18,    19,\n      20,    21,    22,    23,    24,   131,    61,    37,    38,   418,\n     208,    63,   131,    48,    49,   213,    61,   311,   113,   313,\n      55,    90,   431,   418,     4,    55,    56,    57,    58,    59,\n      60,   246,    52,    53,    54,   403,   431,   131,    41,    69,\n      43,    44,   308,    19,    20,   111,    48,    49,   143,   144,\n      97,    98,    55,    56,    57,   104,   105,   106,   107,   154,\n      40,    65,   111,   131,   130,   359,   332,   162,   339,    34,\n      35,    36,    92,   339,    91,    92,   111,   343,   344,   345,\n      65,   111,   131,    86,    25,    26,    27,    28,   456,   196,\n     197,    64,   338,   131,    65,   130,   185,   186,   187,   188,\n     130,   131,    55,    55,    55,   125,   126,   127,   306,    41,\n     308,    43,    44,   131,    21,   210,    41,    55,    43,    44,\n     335,    99,    65,    55,    56,    57,    65,   393,   422,   423,\n      55,    56,    57,    22,   332,    37,    38,    39,    40,    23,\n     132,   339,   237,    24,   239,   343,   344,   345,   189,   190,\n     191,   192,    63,   419,    63,   132,   131,    55,   373,    64,\n       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,\n      14,    15,    16,    17,    18,    66,    55,    65,   198,   199,\n     200,    64,     3,   449,   204,    29,    73,    65,    63,    65,\n       4,   406,    88,   408,   100,   393,   216,   217,   218,    63,\n     131,    64,    61,    64,     3,     3,    57,    63,    66,     3,\n      63,    63,    55,    55,    61,     3,    55,    67,    98,    65,\n      97,   419,    63,    92,    61,   440,   321,   130,     3,   130,\n     130,    63,   131,    63,    63,    63,     3,     0,     1,    63,\n      63,     3,   132,    65,   130,   130,   235,    48,    11,   242,\n     355,   449,   355,   227,   362,   361,   449,   180,   182,   181,\n      16,    24,   183,   211,   184,    16,   339,   306,   288,   345,\n     418,   291,   432,   368,    37,    38,    -1,    40,    41,    42,\n      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,\n      53,    -1,    55,    56,    57,    58,    59,    60,    -1,    62,\n      -1,    -1,    65,    66,    -1,    68,    69,    70,    71,    72,\n     405,    -1,    75,    -1,    -1,    -1,    -1,    80,    81,    -1,\n      -1,    84,    -1,    -1,    87,    88,    89,    90,    91,    92,\n      -1,    -1,    95,    96,     1,    -1,    -1,    -1,    -1,    -1,\n     103,   104,   105,   106,    11,    -1,    -1,    -1,   111,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    24,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,   130,   131,    -1,\n      37,    38,    -1,    40,    41,    42,    43,    44,    45,    46,\n      47,    48,    49,    50,    51,    52,    53,    -1,    55,    56,\n      57,    58,    59,    60,    -1,    62,    -1,    -1,    65,    66,\n      67,    68,    69,    70,    71,    72,    -1,    -1,    75,    -1,\n      -1,    -1,    -1,    80,    81,    -1,    -1,    84,    -1,    -1,\n      87,    88,    89,    90,    91,    92,    -1,    -1,    95,    96,\n      -1,    -1,    -1,    -1,    -1,    -1,   103,   104,   105,   106,\n      11,    -1,    -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    24,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,   130,   131,    -1,    37,    38,    -1,    40,\n      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,\n      51,    52,    53,    -1,    55,    56,    57,    58,    59,    60,\n      -1,    62,    -1,    -1,    65,    66,    -1,    68,    69,    70,\n      71,    72,    -1,    -1,    75,    -1,    -1,    -1,    -1,    80,\n      81,    -1,    -1,    84,    -1,    -1,    87,    88,    89,    90,\n      91,    92,    -1,    -1,    95,    96,    -1,    -1,    -1,    -1,\n      -1,    -1,   103,   104,   105,   106,    11,    -1,    -1,    -1,\n     111,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    24,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   130,\n     131,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    -1,\n      55,    56,    57,    58,    59,    60,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    69,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    92,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,\n     105,   106,    11,    -1,    -1,    -1,   111,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    24,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,   130,   131,    -1,    37,    38,\n      -1,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    11,    55,    56,    57,    58,\n      59,    60,    -1,    -1,    -1,    -1,    65,    -1,    24,    -1,\n      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    37,    38,    -1,    40,    41,    42,    43,    44,    45,\n      46,    47,    48,    49,    50,    51,    52,    53,    -1,    55,\n      56,    57,    58,    59,    60,   104,   105,   106,    -1,    -1,\n      -1,    -1,   111,    69,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,   130,   131,    -1,    -1,    -1,    92,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,   105,\n     106,    11,    -1,    -1,    -1,   111,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    24,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   130,   131,    -1,    37,    38,    -1,\n      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,\n      50,    51,    52,    53,    -1,    55,    56,    57,    58,    59,\n      60,    -1,    -1,    63,    -1,    -1,    -1,    -1,    -1,    69,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   104,   105,   106,    11,    -1,    -1,\n      -1,   111,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      24,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     130,   131,    -1,    37,    38,    -1,    40,    41,    42,    43,\n      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,\n      -1,    55,    56,    57,    58,    59,    60,    -1,    -1,    63,\n      -1,    -1,    -1,    -1,    -1,    69,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     104,   105,   106,    11,    -1,    -1,    -1,   111,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    24,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,   130,   131,    -1,    37,\n      38,    -1,    40,    41,    42,    43,    44,    45,    46,    47,\n      48,    49,    50,    51,    52,    53,    11,    55,    56,    57,\n      58,    59,    60,    -1,    -1,    63,    -1,    -1,    -1,    24,\n      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    -1,\n      55,    56,    57,    58,    59,    60,   104,   105,   106,    -1,\n      65,    -1,    -1,   111,    69,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,   130,   131,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,\n     105,   106,    11,    -1,    -1,    -1,   111,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    24,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,   130,   131,    -1,    37,    38,\n      -1,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    -1,    55,    56,    57,    58,\n      59,    60,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,   101,    -1,    -1,   104,   105,   106,    11,    -1,\n      -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    24,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,   130,   131,    -1,    37,    38,    -1,    40,    41,    42,\n      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,\n      53,    11,    55,    56,    57,    58,    59,    60,    -1,    -1,\n      -1,    -1,    -1,    -1,    24,    -1,    69,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,\n      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,\n      50,    51,    52,    53,    -1,    55,    56,    57,    58,    59,\n      60,   104,   105,   106,    -1,    -1,    -1,    -1,   111,    69,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,   130,   131,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   104,   105,   106,    11,    -1,    -1,\n      -1,   111,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      24,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     130,   131,    -1,    37,    38,    -1,    40,    41,    42,    43,\n      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,\n      -1,    55,    56,    57,    58,    59,    60,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    69,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     104,   105,   106,    -1,    -1,    -1,    -1,   111,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,   130,   131\n};\n\n/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\n   symbol of state STATE-NUM.  */\nstatic const yytype_uint8 yystos[] =\n{\n       0,   135,   136,   137,     0,   138,     1,    11,    24,    37,\n      38,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    55,    56,    57,    58,    59,\n      60,    62,    65,    66,    68,    69,    70,    71,    72,    75,\n      80,    81,    84,    87,    88,    89,    90,    91,    92,    95,\n      96,   103,   104,   105,   106,   111,   130,   131,   139,   140,\n     141,   143,   146,   149,   152,   154,   159,   160,   164,   166,\n     173,   181,   187,   188,   190,   192,   193,   196,   198,   199,\n     200,   201,   202,   203,   204,   205,   206,   207,   208,   209,\n     210,   211,   212,   213,   214,   215,   218,   221,   224,   228,\n     233,   238,    65,   219,    69,   213,    57,   220,   213,   213,\n     213,   213,   213,    55,   215,   221,   213,   213,   213,   213,\n     213,   213,   213,   213,    92,   104,   105,   106,   198,   217,\n     225,   131,   142,    65,   131,   167,    65,    64,   198,   131,\n      65,   198,    65,    55,    55,   144,   147,    55,   131,   161,\n     162,   161,   198,   194,    55,   213,   213,   213,    99,    65,\n      65,     3,    90,     4,     5,     6,     7,     8,     9,    10,\n      11,    12,    13,    14,    15,    16,    17,    18,    29,    19,\n      20,    21,    22,    23,    24,    25,    26,    27,    28,    30,\n      31,    32,    33,    34,    35,    36,    48,    49,    37,    38,\n      39,    40,   213,    52,    54,    41,    43,    44,    55,    56,\n      57,    86,   132,   229,   132,    63,    63,    63,    63,    63,\n     131,   197,   200,   226,   227,   182,   138,   165,    55,   168,\n      64,    66,    65,   198,   155,   156,   198,    55,   139,   150,\n      64,   163,     3,    65,   139,   198,   153,   200,   198,   200,\n     200,   200,   200,   200,   200,   200,   200,   200,   200,   200,\n     200,   200,   200,   200,   200,   201,   203,   204,   205,   206,\n     207,   208,   208,   208,   208,   209,   209,   209,   209,   210,\n     210,   210,   211,   211,   213,   213,   213,   213,    40,   101,\n     197,   212,   222,   223,   216,   198,   214,   131,   197,   230,\n     231,    37,    57,   213,   213,   213,     3,    61,    73,   183,\n      67,   168,    40,   131,   169,   170,   171,   172,   163,   174,\n      63,    65,   160,   198,    88,   198,   104,   105,   106,   107,\n     111,   131,     4,   162,   100,   195,    63,   139,    64,     3,\n      63,   131,    61,    64,     3,     3,   232,    57,   234,   227,\n     197,   141,   163,   163,    63,     3,    63,   141,    97,    98,\n     175,   176,   178,   180,   189,   157,   198,    63,    55,   151,\n     197,    55,   139,   191,   201,   223,   197,   197,   231,    61,\n     239,    48,    49,    55,   111,   130,   233,   235,   236,   237,\n     238,     3,   141,     4,    40,   171,   172,    55,    55,   163,\n      67,   178,   176,   179,   141,    65,   145,   198,    63,    63,\n     131,   139,   130,   240,   241,   130,   130,    61,     3,   184,\n     197,    63,   131,    63,   141,   158,   198,   139,    63,   139,\n      63,     3,     3,    61,   237,   185,   186,   197,   163,   163,\n      63,   148,    48,    49,   111,   130,   233,   238,   241,     3,\n      63,   139,    65,   130,   130,   186,   177,   141\n};\n\n#define yyerrok\t\t(yyerrstatus = 0)\n#define yyclearin\t(yychar = YYEMPTY)\n#define YYEMPTY\t\t(-2)\n#define YYEOF\t\t0\n\n#define YYACCEPT\tgoto yyacceptlab\n#define YYABORT\t\tgoto yyabortlab\n#define YYERROR\t\tgoto yyerrorlab\n\n\n/* Like YYERROR except do call yyerror.  This remains here temporarily\n   to ease the transition to the new meaning of YYERROR, for GCC.\n   Once GCC version 2 has supplanted version 1, this can go.  */\n\n#define YYFAIL\t\tgoto yyerrlab\n\n#define YYRECOVERING()  (!!yyerrstatus)\n\n#define YYBACKUP(Token, Value)\t\t\t\t\t\\\ndo\t\t\t\t\t\t\t\t\\\n  if (yychar == YYEMPTY && yylen == 1)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yychar = (Token);\t\t\t\t\t\t\\\n      yylval = (Value);\t\t\t\t\t\t\\\n      yytoken = YYTRANSLATE (yychar);\t\t\t\t\\\n      YYPOPSTACK (1);\t\t\t\t\t\t\\\n      goto yybackup;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n  else\t\t\t\t\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yyerror (YY_(\"syntax error: cannot back up\")); \\\n      YYERROR;\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\nwhile (YYID (0))\n\n\n#define YYTERROR\t1\n#define YYERRCODE\t256\n\n\n/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\n   If N is 0, then set CURRENT to the empty location which ends\n   the previous symbol: RHS[0] (always defined).  */\n\n#define YYRHSLOC(Rhs, K) ((Rhs)[K])\n#ifndef YYLLOC_DEFAULT\n# define YYLLOC_DEFAULT(Current, Rhs, N)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      if (YYID (N))                                                    \\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;\t\\\n\t  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;\t\\\n\t  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;\t\t\\\n\t  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;\t\\\n\t}\t\t\t\t\t\t\t\t\\\n      else\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = (Current).last_line   =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_line;\t\t\t\t\\\n\t  (Current).first_column = (Current).last_column =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_column;\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n#endif\n\n\n/* YY_LOCATION_PRINT -- Print the location on the stream.\n   This macro was not mandated originally: define only if we know\n   we won't break user code: when these are the locations we know.  */\n\n#ifndef YY_LOCATION_PRINT\n# if YYLTYPE_IS_TRIVIAL\n#  define YY_LOCATION_PRINT(File, Loc)\t\t\t\\\n     fprintf (File, \"%d.%d-%d.%d\",\t\t\t\\\n\t      (Loc).first_line, (Loc).first_column,\t\\\n\t      (Loc).last_line,  (Loc).last_column)\n# else\n#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)\n# endif\n#endif\n\n\n/* YYLEX -- calling `yylex' with the right arguments.  */\n\n#ifdef YYLEX_PARAM\n# define YYLEX yylex (&yylval, YYLEX_PARAM)\n#else\n# define YYLEX yylex (&yylval)\n#endif\n\n/* Enable debugging if requested.  */\n#if YYDEBUG\n\n# ifndef YYFPRINTF\n#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYFPRINTF fprintf\n# endif\n\n# define YYDPRINTF(Args)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\\\n    YYFPRINTF Args;\t\t\t\t\\\n} while (YYID (0))\n\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\t\t\t  \\\ndo {\t\t\t\t\t\t\t\t\t  \\\n  if (yydebug)\t\t\t\t\t\t\t\t  \\\n    {\t\t\t\t\t\t\t\t\t  \\\n      YYFPRINTF (stderr, \"%s \", Title);\t\t\t\t\t  \\\n      yy_symbol_print (stderr,\t\t\t\t\t\t  \\\n\t\t  Type, Value); \\\n      YYFPRINTF (stderr, \"\\n\");\t\t\t\t\t\t  \\\n    }\t\t\t\t\t\t\t\t\t  \\\n} while (YYID (0))\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_value_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (!yyvaluep)\n    return;\n# ifdef YYPRINT\n  if (yytype < YYNTOKENS)\n    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\n# else\n  YYUSE (yyoutput);\n# endif\n  switch (yytype)\n    {\n      default:\n\tbreak;\n    }\n}\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (yytype < YYNTOKENS)\n    YYFPRINTF (yyoutput, \"token %s (\", yytname[yytype]);\n  else\n    YYFPRINTF (yyoutput, \"nterm %s (\", yytname[yytype]);\n\n  yy_symbol_value_print (yyoutput, yytype, yyvaluep);\n  YYFPRINTF (yyoutput, \")\");\n}\n\n/*------------------------------------------------------------------.\n| yy_stack_print -- Print the state stack from its BOTTOM up to its |\n| TOP (included).                                                   |\n`------------------------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)\n#else\nstatic void\nyy_stack_print (yybottom, yytop)\n    yytype_int16 *yybottom;\n    yytype_int16 *yytop;\n#endif\n{\n  YYFPRINTF (stderr, \"Stack now\");\n  for (; yybottom <= yytop; yybottom++)\n    {\n      int yybot = *yybottom;\n      YYFPRINTF (stderr, \" %d\", yybot);\n    }\n  YYFPRINTF (stderr, \"\\n\");\n}\n\n# define YY_STACK_PRINT(Bottom, Top)\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\t\t\\\n    yy_stack_print ((Bottom), (Top));\t\t\t\t\\\n} while (YYID (0))\n\n\n/*------------------------------------------------.\n| Report that the YYRULE is going to be reduced.  |\n`------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_reduce_print (YYSTYPE *yyvsp, int yyrule)\n#else\nstatic void\nyy_reduce_print (yyvsp, yyrule)\n    YYSTYPE *yyvsp;\n    int yyrule;\n#endif\n{\n  int yynrhs = yyr2[yyrule];\n  int yyi;\n  unsigned long int yylno = yyrline[yyrule];\n  YYFPRINTF (stderr, \"Reducing stack by rule %d (line %lu):\\n\",\n\t     yyrule - 1, yylno);\n  /* The symbols being reduced.  */\n  for (yyi = 0; yyi < yynrhs; yyi++)\n    {\n      YYFPRINTF (stderr, \"   $%d = \", yyi + 1);\n      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],\n\t\t       &(yyvsp[(yyi + 1) - (yynrhs)])\n\t\t       \t\t       );\n      YYFPRINTF (stderr, \"\\n\");\n    }\n}\n\n# define YY_REDUCE_PRINT(Rule)\t\t\\\ndo {\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\\\n    yy_reduce_print (yyvsp, Rule); \\\n} while (YYID (0))\n\n/* Nonzero means print parse trace.  It is left uninitialized so that\n   multiple parsers can coexist.  */\nint yydebug;\n#else /* !YYDEBUG */\n# define YYDPRINTF(Args)\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\n# define YY_STACK_PRINT(Bottom, Top)\n# define YY_REDUCE_PRINT(Rule)\n#endif /* !YYDEBUG */\n\n\n/* YYINITDEPTH -- initial size of the parser's stacks.  */\n#ifndef\tYYINITDEPTH\n# define YYINITDEPTH 200\n#endif\n\n/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\n   if the built-in stack extension method is used).\n\n   Do not make this value too large; the results are undefined if\n   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)\n   evaluated with infinite-precision integer arithmetic.  */\n\n#ifndef YYMAXDEPTH\n# define YYMAXDEPTH 10000\n#endif\n\n\f\n\n#if YYERROR_VERBOSE\n\n# ifndef yystrlen\n#  if defined __GLIBC__ && defined _STRING_H\n#   define yystrlen strlen\n#  else\n/* Return the length of YYSTR.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic YYSIZE_T\nyystrlen (const char *yystr)\n#else\nstatic YYSIZE_T\nyystrlen (yystr)\n    const char *yystr;\n#endif\n{\n  YYSIZE_T yylen;\n  for (yylen = 0; yystr[yylen]; yylen++)\n    continue;\n  return yylen;\n}\n#  endif\n# endif\n\n# ifndef yystpcpy\n#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE\n#   define yystpcpy stpcpy\n#  else\n/* Copy YYSRC to YYDEST, returning the address of the terminating '\\0' in\n   YYDEST.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic char *\nyystpcpy (char *yydest, const char *yysrc)\n#else\nstatic char *\nyystpcpy (yydest, yysrc)\n    char *yydest;\n    const char *yysrc;\n#endif\n{\n  char *yyd = yydest;\n  const char *yys = yysrc;\n\n  while ((*yyd++ = *yys++) != '\\0')\n    continue;\n\n  return yyd - 1;\n}\n#  endif\n# endif\n\n# ifndef yytnamerr\n/* Copy to YYRES the contents of YYSTR after stripping away unnecessary\n   quotes and backslashes, so that it's suitable for yyerror.  The\n   heuristic is that double-quoting is unnecessary unless the string\n   contains an apostrophe, a comma, or backslash (other than\n   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is\n   null, do not copy; instead, return the length of what the result\n   would have been.  */\nstatic YYSIZE_T\nyytnamerr (char *yyres, const char *yystr)\n{\n  if (*yystr == '\"')\n    {\n      YYSIZE_T yyn = 0;\n      char const *yyp = yystr;\n\n      for (;;)\n\tswitch (*++yyp)\n\t  {\n\t  case '\\'':\n\t  case ',':\n\t    goto do_not_strip_quotes;\n\n\t  case '\\\\':\n\t    if (*++yyp != '\\\\')\n\t      goto do_not_strip_quotes;\n\t    /* Fall through.  */\n\t  default:\n\t    if (yyres)\n\t      yyres[yyn] = *yyp;\n\t    yyn++;\n\t    break;\n\n\t  case '\"':\n\t    if (yyres)\n\t      yyres[yyn] = '\\0';\n\t    return yyn;\n\t  }\n    do_not_strip_quotes: ;\n    }\n\n  if (! yyres)\n    return yystrlen (yystr);\n\n  return yystpcpy (yyres, yystr) - yyres;\n}\n# endif\n\n/* Copy into YYRESULT an error message about the unexpected token\n   YYCHAR while in state YYSTATE.  Return the number of bytes copied,\n   including the terminating null byte.  If YYRESULT is null, do not\n   copy anything; just return the number of bytes that would be\n   copied.  As a special case, return 0 if an ordinary \"syntax error\"\n   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during\n   size calculation.  */\nstatic YYSIZE_T\nyysyntax_error (char *yyresult, int yystate, int yychar)\n{\n  int yyn = yypact[yystate];\n\n  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))\n    return 0;\n  else\n    {\n      int yytype = YYTRANSLATE (yychar);\n      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);\n      YYSIZE_T yysize = yysize0;\n      YYSIZE_T yysize1;\n      int yysize_overflow = 0;\n      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };\n      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];\n      int yyx;\n\n# if 0\n      /* This is so xgettext sees the translatable formats that are\n\t constructed on the fly.  */\n      YY_(\"syntax error, unexpected %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s or %s\");\n# endif\n      char *yyfmt;\n      char const *yyf;\n      static char const yyunexpected[] = \"syntax error, unexpected %s\";\n      static char const yyexpecting[] = \", expecting %s\";\n      static char const yyor[] = \" or %s\";\n      char yyformat[sizeof yyunexpected\n\t\t    + sizeof yyexpecting - 1\n\t\t    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)\n\t\t       * (sizeof yyor - 1))];\n      char const *yyprefix = yyexpecting;\n\n      /* Start YYX at -YYN if negative to avoid negative indexes in\n\t YYCHECK.  */\n      int yyxbegin = yyn < 0 ? -yyn : 0;\n\n      /* Stay within bounds of both yycheck and yytname.  */\n      int yychecklim = YYLAST - yyn + 1;\n      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n      int yycount = 1;\n\n      yyarg[0] = yytname[yytype];\n      yyfmt = yystpcpy (yyformat, yyunexpected);\n\n      for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n\tif (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\n\t  {\n\t    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)\n\t      {\n\t\tyycount = 1;\n\t\tyysize = yysize0;\n\t\tyyformat[sizeof yyunexpected - 1] = '\\0';\n\t\tbreak;\n\t      }\n\t    yyarg[yycount++] = yytname[yyx];\n\t    yysize1 = yysize + yytnamerr (0, yytname[yyx]);\n\t    yysize_overflow |= (yysize1 < yysize);\n\t    yysize = yysize1;\n\t    yyfmt = yystpcpy (yyfmt, yyprefix);\n\t    yyprefix = yyor;\n\t  }\n\n      yyf = YY_(yyformat);\n      yysize1 = yysize + yystrlen (yyf);\n      yysize_overflow |= (yysize1 < yysize);\n      yysize = yysize1;\n\n      if (yysize_overflow)\n\treturn YYSIZE_MAXIMUM;\n\n      if (yyresult)\n\t{\n\t  /* Avoid sprintf, as that infringes on the user's name space.\n\t     Don't have undefined behavior even if the translation\n\t     produced a string with the wrong number of \"%s\"s.  */\n\t  char *yyp = yyresult;\n\t  int yyi = 0;\n\t  while ((*yyp = *yyf) != '\\0')\n\t    {\n\t      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)\n\t\t{\n\t\t  yyp += yytnamerr (yyp, yyarg[yyi++]);\n\t\t  yyf += 2;\n\t\t}\n\t      else\n\t\t{\n\t\t  yyp++;\n\t\t  yyf++;\n\t\t}\n\t    }\n\t}\n      return yysize;\n    }\n}\n#endif /* YYERROR_VERBOSE */\n\f\n\n/*-----------------------------------------------.\n| Release the memory associated to this symbol.  |\n`-----------------------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)\n#else\nstatic void\nyydestruct (yymsg, yytype, yyvaluep)\n    const char *yymsg;\n    int yytype;\n    YYSTYPE *yyvaluep;\n#endif\n{\n  YYUSE (yyvaluep);\n\n  if (!yymsg)\n    yymsg = \"Deleting\";\n  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);\n\n  /*switch (yytype)\n    {\n\n      default:\n\tbreak;\n    }*/\n}\n\n/* Prevent warnings from -Wmissing-prototypes.  */\n#ifdef YYPARSE_PARAM\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void *YYPARSE_PARAM);\n#else\nint yyparse ();\n#endif\n#else /* ! YYPARSE_PARAM */\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void);\n#else\nint yyparse ();\n#endif\n#endif /* ! YYPARSE_PARAM */\n\n\n\n\n\n/*-------------------------.\n| yyparse or yypush_parse.  |\n`-------------------------*/\n\n#ifdef YYPARSE_PARAM\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void *YYPARSE_PARAM)\n#else\nint\nyyparse (YYPARSE_PARAM)\n    void *YYPARSE_PARAM;\n#endif\n#else /* ! YYPARSE_PARAM */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void)\n#else\nint\nyyparse ()\n\n#endif\n#endif\n{\n/* The lookahead symbol.  */\nint yychar;\n\n/* The semantic value of the lookahead symbol.  */\nYYSTYPE yylval;\n\n    /* Number of syntax errors so far.  */\n    int yynerrs;\n\n    int yystate;\n    /* Number of tokens to shift before error messages enabled.  */\n    int yyerrstatus;\n\n    /* The stacks and their tools:\n       `yyss': related to states.\n       `yyvs': related to semantic values.\n\n       Refer to the stacks thru separate pointers, to allow yyoverflow\n       to reallocate them elsewhere.  */\n\n    /* The state stack.  */\n    yytype_int16 yyssa[YYINITDEPTH];\n    yytype_int16 *yyss;\n    yytype_int16 *yyssp;\n\n    /* The semantic value stack.  */\n    YYSTYPE yyvsa[YYINITDEPTH];\n    YYSTYPE *yyvs;\n    YYSTYPE *yyvsp;\n\n    YYSIZE_T yystacksize;\n\n  int yyn;\n  int yyresult;\n  /* Lookahead token as an internal (translated) token number.  */\n  int yytoken;\n  /* The variables used to return semantic value and location from the\n     action routines.  */\n  YYSTYPE yyval;\n\n#if YYERROR_VERBOSE\n  /* Buffer for error messages, and its allocated size.  */\n  char yymsgbuf[128];\n  char *yymsg = yymsgbuf;\n  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;\n#endif\n\n#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))\n\n  /* The number of symbols on the RHS of the reduced rule.\n     Keep to zero when no symbol should be popped.  */\n  int yylen = 0;\n\n  yytoken = 0;\n  yyss = yyssa;\n  yyvs = yyvsa;\n  yystacksize = YYINITDEPTH;\n\n  YYDPRINTF ((stderr, \"Starting parse\\n\"));\n\n  yystate = 0;\n  yyerrstatus = 0;\n  yynerrs = 0;\n  yychar = YYEMPTY; /* Cause a token to be read.  */\n\n  /* Initialize stack pointers.\n     Waste one element of value and location stack\n     so that they stay on the same level as the state stack.\n     The wasted elements are never initialized.  */\n  yyssp = yyss;\n  yyvsp = yyvs;\n\n  goto yysetstate;\n\n/*------------------------------------------------------------.\n| yynewstate -- Push a new state, which is found in yystate.  |\n`------------------------------------------------------------*/\n yynewstate:\n  /* In all cases, when you get here, the value and location stacks\n     have just been pushed.  So pushing a state here evens the stacks.  */\n  yyssp++;\n\n yysetstate:\n  *yyssp = yystate;\n\n  if (yyss + yystacksize - 1 <= yyssp)\n    {\n      /* Get the current used size of the three stacks, in elements.  */\n      YYSIZE_T yysize = yyssp - yyss + 1;\n\n#ifdef yyoverflow\n      {\n\t/* Give user a chance to reallocate the stack.  Use copies of\n\t   these so that the &'s don't force the real ones into\n\t   memory.  */\n\tYYSTYPE *yyvs1 = yyvs;\n\tyytype_int16 *yyss1 = yyss;\n\n\t/* Each stack pointer address is followed by the size of the\n\t   data in use in that stack, in bytes.  This used to be a\n\t   conditional around just the two extra args, but that might\n\t   be undefined if yyoverflow is a macro.  */\n\tyyoverflow (YY_(\"memory exhausted\"),\n\t\t    &yyss1, yysize * sizeof (*yyssp),\n\t\t    &yyvs1, yysize * sizeof (*yyvsp),\n\t\t    &yystacksize);\n\n\tyyss = yyss1;\n\tyyvs = yyvs1;\n      }\n#else /* no yyoverflow */\n# ifndef YYSTACK_RELOCATE\n      goto yyexhaustedlab;\n# else\n      /* Extend the stack our own way.  */\n      if (YYMAXDEPTH <= yystacksize)\n\tgoto yyexhaustedlab;\n      yystacksize *= 2;\n      if (YYMAXDEPTH < yystacksize)\n\tyystacksize = YYMAXDEPTH;\n\n      {\n\tyytype_int16 *yyss1 = yyss;\n\tunion yyalloc *yyptr =\n\t  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\n\tif (! yyptr)\n\t  goto yyexhaustedlab;\n\tYYSTACK_RELOCATE (yyss_alloc, yyss);\n\tYYSTACK_RELOCATE (yyvs_alloc, yyvs);\n#  undef YYSTACK_RELOCATE\n\tif (yyss1 != yyssa)\n\t  YYSTACK_FREE (yyss1);\n      }\n# endif\n#endif /* no yyoverflow */\n\n      yyssp = yyss + yysize - 1;\n      yyvsp = yyvs + yysize - 1;\n\n      YYDPRINTF ((stderr, \"Stack size increased to %lu\\n\",\n\t\t  (unsigned long int) yystacksize));\n\n      if (yyss + yystacksize - 1 <= yyssp)\n\tYYABORT;\n    }\n\n  YYDPRINTF ((stderr, \"Entering state %d\\n\", yystate));\n\n  if (yystate == YYFINAL)\n    YYACCEPT;\n\n  goto yybackup;\n\n/*-----------.\n| yybackup.  |\n`-----------*/\nyybackup:\n\n  /* Do appropriate processing given the current state.  Read a\n     lookahead token if we need one and don't already have one.  */\n\n  /* First try to decide what to do without reference to lookahead token.  */\n  yyn = yypact[yystate];\n  if (yyn == YYPACT_NINF)\n    goto yydefault;\n\n  /* Not known => get a lookahead token if don't already have one.  */\n\n  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\n  if (yychar == YYEMPTY)\n    {\n      YYDPRINTF ((stderr, \"Reading a token: \"));\n      yychar = YYLEX;\n    }\n\n  if (yychar <= YYEOF)\n    {\n      yychar = yytoken = YYEOF;\n      YYDPRINTF ((stderr, \"Now at end of input.\\n\"));\n    }\n  else\n    {\n      yytoken = YYTRANSLATE (yychar);\n      YY_SYMBOL_PRINT (\"Next token is\", yytoken, &yylval, &yylloc);\n    }\n\n  /* If the proper action on seeing token YYTOKEN is to reduce or to\n     detect an error, take that action.  */\n  yyn += yytoken;\n  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\n    goto yydefault;\n  yyn = yytable[yyn];\n  if (yyn <= 0)\n    {\n      if (yyn == 0 || yyn == YYTABLE_NINF)\n\tgoto yyerrlab;\n      yyn = -yyn;\n      goto yyreduce;\n    }\n\n  /* Count tokens shifted since error; after three, turn off error\n     status.  */\n  if (yyerrstatus)\n    yyerrstatus--;\n\n  /* Shift the lookahead token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yytoken, &yylval, &yylloc);\n\n  /* Discard the shifted token.  */\n  yychar = YYEMPTY;\n\n  yystate = yyn;\n  *++yyvsp = yylval;\n\n  goto yynewstate;\n\n\n/*-----------------------------------------------------------.\n| yydefault -- do the default action for the current state.  |\n`-----------------------------------------------------------*/\nyydefault:\n  yyn = yydefact[yystate];\n  if (yyn == 0)\n    goto yyerrlab;\n  goto yyreduce;\n\n\n/*-----------------------------.\n| yyreduce -- Do a reduction.  |\n`-----------------------------*/\nyyreduce:\n  /* yyn is the number of a rule to reduce with.  */\n  yylen = yyr2[yyn];\n\n  /* If YYLEN is nonzero, implement the default value of the action:\n     `$$ = $1'.\n\n     Otherwise, the following line sets YYVAL to garbage.\n     This behavior is undocumented and Bison\n     users should not rely upon it.  Assigning to YYVAL\n     unconditionally makes the parser a bit smaller, and it avoids a\n     GCC warning that YYVAL may be used uninitialized.  */\n  yyval = yyvsp[1-yylen];\n\n\n  YY_REDUCE_PRINT (yyn);\n  switch (yyn)\n    {\n        case 3:\n\n/* Line 1455 of yacc.c  */\n#line 222 \"syntax/tjs.y\"\n    { sb->PushContextStack(TJS_W(\"global\"),\n\t\t\t\t\t\t\t\t\t\t\t\tctTopLevel); ;}\n    break;\n\n  case 4:\n\n/* Line 1455 of yacc.c  */\n#line 224 \"syntax/tjs.y\"\n    { sb->PopContextStack(); ;}\n    break;\n\n  case 7:\n\n/* Line 1455 of yacc.c  */\n#line 231 \"syntax/tjs.y\"\n    { if(sb->CompileErrorCount>20)\n\t\t\t\t\t\t\t\t\t\t\t\tYYABORT;\n\t\t\t\t\t\t\t\t\t\t\t  else yyerrok; ;}\n    break;\n\n  case 11:\n\n/* Line 1455 of yacc.c  */\n#line 245 \"syntax/tjs.y\"\n    { cc->CreateExprCode((yyvsp[(1) - (2)].np)); ;}\n    break;\n\n  case 17:\n\n/* Line 1455 of yacc.c  */\n#line 251 \"syntax/tjs.y\"\n    { cc->DoBreak(); ;}\n    break;\n\n  case 18:\n\n/* Line 1455 of yacc.c  */\n#line 252 \"syntax/tjs.y\"\n    { cc->DoContinue(); ;}\n    break;\n\n  case 19:\n\n/* Line 1455 of yacc.c  */\n#line 253 \"syntax/tjs.y\"\n    { cc->DoDebugger(); ;}\n    break;\n\n  case 30:\n\n/* Line 1455 of yacc.c  */\n#line 268 \"syntax/tjs.y\"\n    { cc->EnterBlock(); ;}\n    break;\n\n  case 31:\n\n/* Line 1455 of yacc.c  */\n#line 270 \"syntax/tjs.y\"\n    { cc->ExitBlock(); ;}\n    break;\n\n  case 32:\n\n/* Line 1455 of yacc.c  */\n#line 275 \"syntax/tjs.y\"\n    { cc->EnterWhileCode(false); ;}\n    break;\n\n  case 33:\n\n/* Line 1455 of yacc.c  */\n#line 276 \"syntax/tjs.y\"\n    { cc->CreateWhileExprCode((yyvsp[(4) - (5)].np), false); ;}\n    break;\n\n  case 34:\n\n/* Line 1455 of yacc.c  */\n#line 277 \"syntax/tjs.y\"\n    { cc->ExitWhileCode(false); ;}\n    break;\n\n  case 35:\n\n/* Line 1455 of yacc.c  */\n#line 282 \"syntax/tjs.y\"\n    { cc->EnterWhileCode(true); ;}\n    break;\n\n  case 36:\n\n/* Line 1455 of yacc.c  */\n#line 285 \"syntax/tjs.y\"\n    { cc->CreateWhileExprCode((yyvsp[(6) - (7)].np), true); ;}\n    break;\n\n  case 37:\n\n/* Line 1455 of yacc.c  */\n#line 286 \"syntax/tjs.y\"\n    { cc->ExitWhileCode(true); ;}\n    break;\n\n  case 38:\n\n/* Line 1455 of yacc.c  */\n#line 291 \"syntax/tjs.y\"\n    { cc->EnterIfCode(); ;}\n    break;\n\n  case 39:\n\n/* Line 1455 of yacc.c  */\n#line 292 \"syntax/tjs.y\"\n    { cc->CreateIfExprCode((yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 40:\n\n/* Line 1455 of yacc.c  */\n#line 293 \"syntax/tjs.y\"\n    { cc->ExitIfCode(); ;}\n    break;\n\n  case 41:\n\n/* Line 1455 of yacc.c  */\n#line 298 \"syntax/tjs.y\"\n    { cc->EnterElseCode(); ;}\n    break;\n\n  case 42:\n\n/* Line 1455 of yacc.c  */\n#line 299 \"syntax/tjs.y\"\n    { cc->ExitElseCode(); ;}\n    break;\n\n  case 43:\n\n/* Line 1455 of yacc.c  */\n#line 308 \"syntax/tjs.y\"\n    { cc->ExitForCode(); ;}\n    break;\n\n  case 44:\n\n/* Line 1455 of yacc.c  */\n#line 314 \"syntax/tjs.y\"\n    { cc->EnterForCode(); ;}\n    break;\n\n  case 45:\n\n/* Line 1455 of yacc.c  */\n#line 315 \"syntax/tjs.y\"\n    { cc->EnterForCode(); ;}\n    break;\n\n  case 47:\n\n/* Line 1455 of yacc.c  */\n#line 317 \"syntax/tjs.y\"\n    { cc->EnterForCode();\n\t\t\t\t\t\t\t\t\t\t\t  cc->CreateExprCode((yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 48:\n\n/* Line 1455 of yacc.c  */\n#line 323 \"syntax/tjs.y\"\n    { cc->CreateForExprCode(NULL); ;}\n    break;\n\n  case 49:\n\n/* Line 1455 of yacc.c  */\n#line 324 \"syntax/tjs.y\"\n    { cc->CreateForExprCode((yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 50:\n\n/* Line 1455 of yacc.c  */\n#line 329 \"syntax/tjs.y\"\n    { cc->SetForThirdExprCode(NULL); ;}\n    break;\n\n  case 51:\n\n/* Line 1455 of yacc.c  */\n#line 330 \"syntax/tjs.y\"\n    { cc->SetForThirdExprCode((yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 57:\n\n/* Line 1455 of yacc.c  */\n#line 353 \"syntax/tjs.y\"\n    { cc->AddLocalVariable(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(1) - (2)].num))); ;}\n    break;\n\n  case 58:\n\n/* Line 1455 of yacc.c  */\n#line 355 \"syntax/tjs.y\"\n    { cc->InitLocalVariable(\n\t\t\t\t\t\t\t\t\t\t\t  lx->GetString((yyvsp[(1) - (4)].num)), (yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 66:\n\n/* Line 1455 of yacc.c  */\n#line 372 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(2) - (2)].num)),\n\t\t\t\t\t\t\t\t\t\t\t  ctFunction);\n\t\t\t\t\t\t\t\t\t\t\t  cc->EnterBlock();;}\n    break;\n\n  case 67:\n\n/* Line 1455 of yacc.c  */\n#line 377 \"syntax/tjs.y\"\n    { cc->ExitBlock(); sb->PopContextStack(); ;}\n    break;\n\n  case 68:\n\n/* Line 1455 of yacc.c  */\n#line 382 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tTJS_W(\"(anonymous)\"),\n\t\t\t\t\t\t\t\t\t\t\t  ctExprFunction);\n\t\t\t\t\t\t\t\t\t\t\t  cc->EnterBlock(); ;}\n    break;\n\n  case 69:\n\n/* Line 1455 of yacc.c  */\n#line 387 \"syntax/tjs.y\"\n    { cc->ExitBlock();\n\t\t\t\t\t\t\t\t\t\t\t  tTJSVariant v(cc);\n\t\t\t\t\t\t\t\t\t\t\t  sb->PopContextStack();\n\t\t\t\t\t\t\t\t\t\t\t  (yyval.np) = cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t\t  (yyval.np)->SetValue(v); ;}\n    break;\n\n  case 78:\n\n/* Line 1455 of yacc.c  */\n#line 414 \"syntax/tjs.y\"\n    { cc->AddFunctionDeclArg(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(1) - (2)].num)), NULL); ;}\n    break;\n\n  case 79:\n\n/* Line 1455 of yacc.c  */\n#line 416 \"syntax/tjs.y\"\n    { cc->AddFunctionDeclArg(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(1) - (4)].num)), (yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 80:\n\n/* Line 1455 of yacc.c  */\n#line 421 \"syntax/tjs.y\"\n    { cc->AddFunctionDeclArgCollapse(\n\t\t\t\t\t\t\t\t\t\t\t\tNULL); ;}\n    break;\n\n  case 81:\n\n/* Line 1455 of yacc.c  */\n#line 423 \"syntax/tjs.y\"\n    { cc->AddFunctionDeclArgCollapse(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(1) - (3)].num))); ;}\n    break;\n\n  case 82:\n\n/* Line 1455 of yacc.c  */\n#line 435 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(2) - (3)].num)),\n\t\t\t\t\t\t\t\t\t\t\t\tctProperty); ;}\n    break;\n\n  case 83:\n\n/* Line 1455 of yacc.c  */\n#line 439 \"syntax/tjs.y\"\n    { sb->PopContextStack(); ;}\n    break;\n\n  case 88:\n\n/* Line 1455 of yacc.c  */\n#line 450 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tTJS_W(\"(setter)\"),\n\t\t\t\t\t\t\t\t\t\t\t\tctPropertySetter);\n\t\t\t\t\t\t\t\t\t\t\t  cc->EnterBlock();\n\t\t\t\t\t\t\t\t\t\t\t  cc->SetPropertyDeclArg(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(3) - (5)].num))); ;}\n    break;\n\n  case 89:\n\n/* Line 1455 of yacc.c  */\n#line 456 \"syntax/tjs.y\"\n    { cc->ExitBlock();\n\t\t\t\t\t\t\t\t\t\t\t  sb->PopContextStack(); ;}\n    break;\n\n  case 90:\n\n/* Line 1455 of yacc.c  */\n#line 461 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tTJS_W(\"(getter)\"),\n\t\t\t\t\t\t\t\t\t\t\t\tctPropertyGetter);\n\t\t\t\t\t\t\t\t\t\t\t  cc->EnterBlock(); ;}\n    break;\n\n  case 91:\n\n/* Line 1455 of yacc.c  */\n#line 465 \"syntax/tjs.y\"\n    { cc->ExitBlock();\n\t\t\t\t\t\t\t\t\t\t\t  sb->PopContextStack(); ;}\n    break;\n\n  case 94:\n\n/* Line 1455 of yacc.c  */\n#line 477 \"syntax/tjs.y\"\n    { sb->PushContextStack(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(2) - (2)].num)),\n\t\t\t\t\t\t\t\t\t\t\t\tctClass); ;}\n    break;\n\n  case 95:\n\n/* Line 1455 of yacc.c  */\n#line 481 \"syntax/tjs.y\"\n    { sb->PopContextStack(); ;}\n    break;\n\n  case 97:\n\n/* Line 1455 of yacc.c  */\n#line 486 \"syntax/tjs.y\"\n    { cc->CreateExtendsExprCode((yyvsp[(2) - (2)].np), true); ;}\n    break;\n\n  case 98:\n\n/* Line 1455 of yacc.c  */\n#line 487 \"syntax/tjs.y\"\n    { cc->CreateExtendsExprCode((yyvsp[(2) - (3)].np), false); ;}\n    break;\n\n  case 102:\n\n/* Line 1455 of yacc.c  */\n#line 497 \"syntax/tjs.y\"\n    { cc->CreateExtendsExprCode((yyvsp[(1) - (1)].np), false); ;}\n    break;\n\n  case 103:\n\n/* Line 1455 of yacc.c  */\n#line 502 \"syntax/tjs.y\"\n    { cc->ReturnFromFunc(NULL); ;}\n    break;\n\n  case 104:\n\n/* Line 1455 of yacc.c  */\n#line 503 \"syntax/tjs.y\"\n    { cc->ReturnFromFunc((yyvsp[(2) - (3)].np)); ;}\n    break;\n\n  case 105:\n\n/* Line 1455 of yacc.c  */\n#line 510 \"syntax/tjs.y\"\n    { cc->EnterSwitchCode((yyvsp[(3) - (4)].np)); ;}\n    break;\n\n  case 106:\n\n/* Line 1455 of yacc.c  */\n#line 511 \"syntax/tjs.y\"\n    { cc->ExitSwitchCode(); ;}\n    break;\n\n  case 107:\n\n/* Line 1455 of yacc.c  */\n#line 517 \"syntax/tjs.y\"\n    { cc->EnterWithCode((yyvsp[(3) - (4)].np)); ;}\n    break;\n\n  case 108:\n\n/* Line 1455 of yacc.c  */\n#line 518 \"syntax/tjs.y\"\n    { cc->ExitWithCode(); ;}\n    break;\n\n  case 109:\n\n/* Line 1455 of yacc.c  */\n#line 523 \"syntax/tjs.y\"\n    { cc->ProcessCaseCode((yyvsp[(2) - (3)].np)); ;}\n    break;\n\n  case 110:\n\n/* Line 1455 of yacc.c  */\n#line 524 \"syntax/tjs.y\"\n    { cc->ProcessCaseCode(NULL); ;}\n    break;\n\n  case 111:\n\n/* Line 1455 of yacc.c  */\n#line 529 \"syntax/tjs.y\"\n    { cc->EnterTryCode(); ;}\n    break;\n\n  case 112:\n\n/* Line 1455 of yacc.c  */\n#line 532 \"syntax/tjs.y\"\n    { cc->ExitTryCode(); ;}\n    break;\n\n  case 113:\n\n/* Line 1455 of yacc.c  */\n#line 536 \"syntax/tjs.y\"\n    { cc->EnterCatchCode(NULL); ;}\n    break;\n\n  case 114:\n\n/* Line 1455 of yacc.c  */\n#line 537 \"syntax/tjs.y\"\n    { cc->EnterCatchCode(NULL); ;}\n    break;\n\n  case 115:\n\n/* Line 1455 of yacc.c  */\n#line 538 \"syntax/tjs.y\"\n    { cc->EnterCatchCode(\n\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(3) - (4)].num))); ;}\n    break;\n\n  case 116:\n\n/* Line 1455 of yacc.c  */\n#line 544 \"syntax/tjs.y\"\n    { cc->ProcessThrowCode((yyvsp[(2) - (3)].np)); ;}\n    break;\n\n  case 117:\n\n/* Line 1455 of yacc.c  */\n#line 549 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 118:\n\n/* Line 1455 of yacc.c  */\n#line 553 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 119:\n\n/* Line 1455 of yacc.c  */\n#line 554 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_IF, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 120:\n\n/* Line 1455 of yacc.c  */\n#line 559 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 121:\n\n/* Line 1455 of yacc.c  */\n#line 560 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_COMMA, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 122:\n\n/* Line 1455 of yacc.c  */\n#line 565 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 123:\n\n/* Line 1455 of yacc.c  */\n#line 566 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_SWAP, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 124:\n\n/* Line 1455 of yacc.c  */\n#line 567 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_EQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 125:\n\n/* Line 1455 of yacc.c  */\n#line 568 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_AMPERSANDEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 126:\n\n/* Line 1455 of yacc.c  */\n#line 569 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_VERTLINEEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 127:\n\n/* Line 1455 of yacc.c  */\n#line 570 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_CHEVRONEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 128:\n\n/* Line 1455 of yacc.c  */\n#line 571 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_MINUSEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 129:\n\n/* Line 1455 of yacc.c  */\n#line 572 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_PLUSEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 130:\n\n/* Line 1455 of yacc.c  */\n#line 573 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_PERCENTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 131:\n\n/* Line 1455 of yacc.c  */\n#line 574 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_SLASHEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 132:\n\n/* Line 1455 of yacc.c  */\n#line 575 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_BACKSLASHEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 133:\n\n/* Line 1455 of yacc.c  */\n#line 576 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_ASTERISKEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 134:\n\n/* Line 1455 of yacc.c  */\n#line 577 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LOGICALOREQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 135:\n\n/* Line 1455 of yacc.c  */\n#line 578 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LOGICALANDEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 136:\n\n/* Line 1455 of yacc.c  */\n#line 579 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_RARITHSHIFTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 137:\n\n/* Line 1455 of yacc.c  */\n#line 580 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LARITHSHIFTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 138:\n\n/* Line 1455 of yacc.c  */\n#line 581 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_RBITSHIFTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 139:\n\n/* Line 1455 of yacc.c  */\n#line 586 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 140:\n\n/* Line 1455 of yacc.c  */\n#line 589 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP3(T_QUESTION, (yyvsp[(1) - (5)].np), (yyvsp[(3) - (5)].np), (yyvsp[(5) - (5)].np)); ;}\n    break;\n\n  case 141:\n\n/* Line 1455 of yacc.c  */\n#line 595 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 142:\n\n/* Line 1455 of yacc.c  */\n#line 596 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LOGICALOR, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 143:\n\n/* Line 1455 of yacc.c  */\n#line 600 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 144:\n\n/* Line 1455 of yacc.c  */\n#line 602 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LOGICALAND, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 145:\n\n/* Line 1455 of yacc.c  */\n#line 606 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 146:\n\n/* Line 1455 of yacc.c  */\n#line 607 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_VERTLINE, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 147:\n\n/* Line 1455 of yacc.c  */\n#line 611 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 148:\n\n/* Line 1455 of yacc.c  */\n#line 612 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_CHEVRON, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 149:\n\n/* Line 1455 of yacc.c  */\n#line 616 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 150:\n\n/* Line 1455 of yacc.c  */\n#line 617 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_AMPERSAND, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 151:\n\n/* Line 1455 of yacc.c  */\n#line 621 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 152:\n\n/* Line 1455 of yacc.c  */\n#line 622 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_NOTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 153:\n\n/* Line 1455 of yacc.c  */\n#line 623 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_EQUALEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 154:\n\n/* Line 1455 of yacc.c  */\n#line 624 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_DISCNOTEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 155:\n\n/* Line 1455 of yacc.c  */\n#line 625 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_DISCEQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 156:\n\n/* Line 1455 of yacc.c  */\n#line 629 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 157:\n\n/* Line 1455 of yacc.c  */\n#line 630 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 158:\n\n/* Line 1455 of yacc.c  */\n#line 631 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_GT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 159:\n\n/* Line 1455 of yacc.c  */\n#line 632 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LTOREQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 160:\n\n/* Line 1455 of yacc.c  */\n#line 633 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_GTOREQUAL, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 161:\n\n/* Line 1455 of yacc.c  */\n#line 637 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 162:\n\n/* Line 1455 of yacc.c  */\n#line 638 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_RARITHSHIFT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 163:\n\n/* Line 1455 of yacc.c  */\n#line 639 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LARITHSHIFT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 164:\n\n/* Line 1455 of yacc.c  */\n#line 640 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_RBITSHIFT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 165:\n\n/* Line 1455 of yacc.c  */\n#line 645 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 166:\n\n/* Line 1455 of yacc.c  */\n#line 646 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_PLUS, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 167:\n\n/* Line 1455 of yacc.c  */\n#line 647 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_MINUS, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 168:\n\n/* Line 1455 of yacc.c  */\n#line 651 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 169:\n\n/* Line 1455 of yacc.c  */\n#line 652 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_PERCENT, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 170:\n\n/* Line 1455 of yacc.c  */\n#line 653 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_SLASH, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 171:\n\n/* Line 1455 of yacc.c  */\n#line 654 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_BACKSLASH, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 172:\n\n/* Line 1455 of yacc.c  */\n#line 655 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_ASTERISK, (yyvsp[(1) - (2)].np), (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 173:\n\n/* Line 1455 of yacc.c  */\n#line 659 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (2)].np); ;}\n    break;\n\n  case 174:\n\n/* Line 1455 of yacc.c  */\n#line 663 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 175:\n\n/* Line 1455 of yacc.c  */\n#line 664 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_EXCRAMATION, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 176:\n\n/* Line 1455 of yacc.c  */\n#line 665 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_TILDE, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 177:\n\n/* Line 1455 of yacc.c  */\n#line 666 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_DECREMENT, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 178:\n\n/* Line 1455 of yacc.c  */\n#line 667 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_INCREMENT, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 179:\n\n/* Line 1455 of yacc.c  */\n#line 668 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(2) - (2)].np); (yyval.np)->SetOpecode(T_NEW); ;}\n    break;\n\n  case 180:\n\n/* Line 1455 of yacc.c  */\n#line 669 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_INVALIDATE, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 181:\n\n/* Line 1455 of yacc.c  */\n#line 670 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_ISVALID, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 182:\n\n/* Line 1455 of yacc.c  */\n#line 671 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_ISVALID, (yyvsp[(1) - (2)].np)); ;}\n    break;\n\n  case 183:\n\n/* Line 1455 of yacc.c  */\n#line 672 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_DELETE, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 184:\n\n/* Line 1455 of yacc.c  */\n#line 673 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_TYPEOF, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 185:\n\n/* Line 1455 of yacc.c  */\n#line 674 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_SHARP, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 186:\n\n/* Line 1455 of yacc.c  */\n#line 675 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_DOLLAR, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 187:\n\n/* Line 1455 of yacc.c  */\n#line 676 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_UPLUS, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 188:\n\n/* Line 1455 of yacc.c  */\n#line 677 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_UMINUS, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 189:\n\n/* Line 1455 of yacc.c  */\n#line 678 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_IGNOREPROP, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 190:\n\n/* Line 1455 of yacc.c  */\n#line 679 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_PROPACCESS, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 191:\n\n/* Line 1455 of yacc.c  */\n#line 680 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_INSTANCEOF, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 192:\n\n/* Line 1455 of yacc.c  */\n#line 681 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_INT, (yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 193:\n\n/* Line 1455 of yacc.c  */\n#line 682 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_INT, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 194:\n\n/* Line 1455 of yacc.c  */\n#line 683 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_REAL, (yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 195:\n\n/* Line 1455 of yacc.c  */\n#line 684 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_REAL, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 196:\n\n/* Line 1455 of yacc.c  */\n#line 685 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_STRING, (yyvsp[(4) - (4)].np)); ;}\n    break;\n\n  case 197:\n\n/* Line 1455 of yacc.c  */\n#line 686 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_STRING, (yyvsp[(2) - (2)].np)); ;}\n    break;\n\n  case 198:\n\n/* Line 1455 of yacc.c  */\n#line 690 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 199:\n\n/* Line 1455 of yacc.c  */\n#line 692 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_INCONTEXTOF, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 200:\n\n/* Line 1455 of yacc.c  */\n#line 696 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 201:\n\n/* Line 1455 of yacc.c  */\n#line 697 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(2) - (3)].np); ;}\n    break;\n\n  case 202:\n\n/* Line 1455 of yacc.c  */\n#line 698 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LBRACKET, (yyvsp[(1) - (4)].np), (yyvsp[(3) - (4)].np)); ;}\n    break;\n\n  case 203:\n\n/* Line 1455 of yacc.c  */\n#line 699 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 204:\n\n/* Line 1455 of yacc.c  */\n#line 700 \"syntax/tjs.y\"\n    { lx->SetNextIsBareWord(); ;}\n    break;\n\n  case 205:\n\n/* Line 1455 of yacc.c  */\n#line 701 \"syntax/tjs.y\"\n    { tTJSExprNode * node = cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t\t\t  node->SetValue(lx->GetValue((yyvsp[(4) - (4)].num)));\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np) = cc->MakeNP2(T_DOT, (yyvsp[(1) - (4)].np), node); ;}\n    break;\n\n  case 206:\n\n/* Line 1455 of yacc.c  */\n#line 704 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_POSTINCREMENT, (yyvsp[(1) - (2)].np)); ;}\n    break;\n\n  case 207:\n\n/* Line 1455 of yacc.c  */\n#line 705 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_POSTDECREMENT, (yyvsp[(1) - (2)].np)); ;}\n    break;\n\n  case 208:\n\n/* Line 1455 of yacc.c  */\n#line 706 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_EVAL, (yyvsp[(1) - (2)].np)); ;}\n    break;\n\n  case 209:\n\n/* Line 1455 of yacc.c  */\n#line 707 \"syntax/tjs.y\"\n    { lx->SetNextIsBareWord(); ;}\n    break;\n\n  case 210:\n\n/* Line 1455 of yacc.c  */\n#line 708 \"syntax/tjs.y\"\n    { tTJSExprNode * node = cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t\t\t  node->SetValue(lx->GetValue((yyvsp[(3) - (3)].num)));\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np) = cc->MakeNP1(T_WITHDOT, node); ;}\n    break;\n\n  case 211:\n\n/* Line 1455 of yacc.c  */\n#line 715 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np)->SetValue(lx->GetValue((yyvsp[(1) - (1)].num))); ;}\n    break;\n\n  case 212:\n\n/* Line 1455 of yacc.c  */\n#line 717 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_SYMBOL);\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np)->SetValue(tTJSVariant(\n\t\t\t\t\t\t\t\t\t\t\t\t\tlx->GetString((yyvsp[(1) - (1)].num)))); ;}\n    break;\n\n  case 213:\n\n/* Line 1455 of yacc.c  */\n#line 720 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_THIS); ;}\n    break;\n\n  case 214:\n\n/* Line 1455 of yacc.c  */\n#line 721 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_SUPER); ;}\n    break;\n\n  case 215:\n\n/* Line 1455 of yacc.c  */\n#line 722 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 216:\n\n/* Line 1455 of yacc.c  */\n#line 723 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_GLOBAL); ;}\n    break;\n\n  case 217:\n\n/* Line 1455 of yacc.c  */\n#line 724 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_VOID); ;}\n    break;\n\n  case 218:\n\n/* Line 1455 of yacc.c  */\n#line 725 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 219:\n\n/* Line 1455 of yacc.c  */\n#line 726 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 220:\n\n/* Line 1455 of yacc.c  */\n#line 727 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 221:\n\n/* Line 1455 of yacc.c  */\n#line 728 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 222:\n\n/* Line 1455 of yacc.c  */\n#line 729 \"syntax/tjs.y\"\n    { lx->SetStartOfRegExp(); ;}\n    break;\n\n  case 223:\n\n/* Line 1455 of yacc.c  */\n#line 730 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_REGEXP);\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np)->SetValue(lx->GetValue((yyvsp[(3) - (3)].num))); ;}\n    break;\n\n  case 224:\n\n/* Line 1455 of yacc.c  */\n#line 732 \"syntax/tjs.y\"\n    { lx->SetStartOfRegExp(); ;}\n    break;\n\n  case 225:\n\n/* Line 1455 of yacc.c  */\n#line 733 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_REGEXP);\n\t\t\t\t\t\t\t\t\t\t\t\t  (yyval.np)->SetValue(lx->GetValue((yyvsp[(3) - (3)].num))); ;}\n    break;\n\n  case 226:\n\n/* Line 1455 of yacc.c  */\n#line 740 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_LPARENTHESIS, (yyvsp[(1) - (4)].np), (yyvsp[(3) - (4)].np)); ;}\n    break;\n\n  case 227:\n\n/* Line 1455 of yacc.c  */\n#line 745 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP0(T_OMIT); ;}\n    break;\n\n  case 228:\n\n/* Line 1455 of yacc.c  */\n#line 746 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_ARG, (yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 229:\n\n/* Line 1455 of yacc.c  */\n#line 747 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_ARG, (yyvsp[(3) - (3)].np), (yyvsp[(1) - (3)].np)); ;}\n    break;\n\n  case 230:\n\n/* Line 1455 of yacc.c  */\n#line 751 \"syntax/tjs.y\"\n    { (yyval.np) = NULL; ;}\n    break;\n\n  case 231:\n\n/* Line 1455 of yacc.c  */\n#line 752 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_EXPANDARG, NULL); ;}\n    break;\n\n  case 232:\n\n/* Line 1455 of yacc.c  */\n#line 753 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_EXPANDARG, (yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 233:\n\n/* Line 1455 of yacc.c  */\n#line 754 \"syntax/tjs.y\"\n    { (yyval.np) = (yyvsp[(1) - (1)].np); ;}\n    break;\n\n  case 234:\n\n/* Line 1455 of yacc.c  */\n#line 760 \"syntax/tjs.y\"\n    { tTJSExprNode *node =\n\t\t\t\t\t\t\t\t\t\t  cc->MakeNP0(T_INLINEARRAY);\n\t\t\t\t\t\t\t\t\t\t  cc->PushCurrentNode(node); ;}\n    break;\n\n  case 235:\n\n/* Line 1455 of yacc.c  */\n#line 764 \"syntax/tjs.y\"\n    { (yyval.np) = cn; cc->PopCurrentNode(); ;}\n    break;\n\n  case 236:\n\n/* Line 1455 of yacc.c  */\n#line 769 \"syntax/tjs.y\"\n    { cn->Add((yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 237:\n\n/* Line 1455 of yacc.c  */\n#line 770 \"syntax/tjs.y\"\n    { cn->Add((yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 238:\n\n/* Line 1455 of yacc.c  */\n#line 775 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_ARRAYARG, NULL); ;}\n    break;\n\n  case 239:\n\n/* Line 1455 of yacc.c  */\n#line 776 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP1(T_ARRAYARG, (yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 240:\n\n/* Line 1455 of yacc.c  */\n#line 781 \"syntax/tjs.y\"\n    { tTJSExprNode *node =\n\t\t\t\t\t\t\t\t\t\t  cc->MakeNP0(T_INLINEDIC);\n\t\t\t\t\t\t\t\t\t\t  cc->PushCurrentNode(node); ;}\n    break;\n\n  case 241:\n\n/* Line 1455 of yacc.c  */\n#line 786 \"syntax/tjs.y\"\n    { (yyval.np) = cn; cc->PopCurrentNode(); ;}\n    break;\n\n  case 243:\n\n/* Line 1455 of yacc.c  */\n#line 793 \"syntax/tjs.y\"\n    { cn->Add((yyvsp[(1) - (1)].np)); ;}\n    break;\n\n  case 244:\n\n/* Line 1455 of yacc.c  */\n#line 794 \"syntax/tjs.y\"\n    { cn->Add((yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 245:\n\n/* Line 1455 of yacc.c  */\n#line 799 \"syntax/tjs.y\"\n    { (yyval.np) = cc->MakeNP2(T_DICELM, (yyvsp[(1) - (3)].np), (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 246:\n\n/* Line 1455 of yacc.c  */\n#line 800 \"syntax/tjs.y\"\n    { tTJSVariant val(lx->GetString((yyvsp[(1) - (3)].num)));\n\t\t\t\t\t\t\t\t\t\t  tTJSExprNode *node0 = cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t  node0->SetValue(val);\n\t\t\t\t\t\t\t\t\t\t  (yyval.np) = cc->MakeNP2(T_DICELM, node0, (yyvsp[(3) - (3)].np)); ;}\n    break;\n\n  case 249:\n\n/* Line 1455 of yacc.c  */\n#line 816 \"syntax/tjs.y\"\n    { tTJSExprNode *node =\n\t\t\t\t\t\t\t\t\t\t  cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t  iTJSDispatch2 * dsp = TJSCreateArrayObject();\n\t\t\t\t\t\t\t\t\t\t  node->SetValue(tTJSVariant(dsp, dsp));\n\t\t\t\t\t\t\t\t\t\t  dsp->Release();\n\t\t\t\t\t\t\t\t\t\t  cc->PushCurrentNode(node); ;}\n    break;\n\n  case 250:\n\n/* Line 1455 of yacc.c  */\n#line 823 \"syntax/tjs.y\"\n    { (yyval.np) = cn; cc->PopCurrentNode(); ;}\n    break;\n\n  case 255:\n\n/* Line 1455 of yacc.c  */\n#line 841 \"syntax/tjs.y\"\n    { cn->AddArrayElement(- lx->GetValue((yyvsp[(2) - (2)].num))); ;}\n    break;\n\n  case 256:\n\n/* Line 1455 of yacc.c  */\n#line 842 \"syntax/tjs.y\"\n    { cn->AddArrayElement(+ lx->GetValue((yyvsp[(2) - (2)].num))); ;}\n    break;\n\n  case 257:\n\n/* Line 1455 of yacc.c  */\n#line 843 \"syntax/tjs.y\"\n    { cn->AddArrayElement(lx->GetValue((yyvsp[(1) - (1)].num))); ;}\n    break;\n\n  case 258:\n\n/* Line 1455 of yacc.c  */\n#line 844 \"syntax/tjs.y\"\n    { cn->AddArrayElement(tTJSVariant());  ;}\n    break;\n\n  case 259:\n\n/* Line 1455 of yacc.c  */\n#line 845 \"syntax/tjs.y\"\n    { cn->AddArrayElement((yyvsp[(1) - (1)].np)->GetValue()); ;}\n    break;\n\n  case 260:\n\n/* Line 1455 of yacc.c  */\n#line 846 \"syntax/tjs.y\"\n    { cn->AddArrayElement((yyvsp[(1) - (1)].np)->GetValue()); ;}\n    break;\n\n  case 261:\n\n/* Line 1455 of yacc.c  */\n#line 851 \"syntax/tjs.y\"\n    { tTJSExprNode *node =\n\t\t\t\t\t\t\t\t\t\t  cc->MakeNP0(T_CONSTVAL);\n\t\t\t\t\t\t\t\t\t\t  iTJSDispatch2 * dsp = TJSCreateDictionaryObject();\n\t\t\t\t\t\t\t\t\t\t  node->SetValue(tTJSVariant(dsp, dsp));\n\t\t\t\t\t\t\t\t\t\t  dsp->Release();\n\t\t\t\t\t\t\t\t\t\t  cc->PushCurrentNode(node); ;}\n    break;\n\n  case 262:\n\n/* Line 1455 of yacc.c  */\n#line 858 \"syntax/tjs.y\"\n    { (yyval.np) = cn; cc->PopCurrentNode(); ;}\n    break;\n\n  case 266:\n\n/* Line 1455 of yacc.c  */\n#line 871 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (4)].num)), - lx->GetValue((yyvsp[(4) - (4)].num))); ;}\n    break;\n\n  case 267:\n\n/* Line 1455 of yacc.c  */\n#line 872 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (4)].num)), + lx->GetValue((yyvsp[(4) - (4)].num))); ;}\n    break;\n\n  case 268:\n\n/* Line 1455 of yacc.c  */\n#line 873 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (3)].num)), lx->GetValue((yyvsp[(3) - (3)].num))); ;}\n    break;\n\n  case 269:\n\n/* Line 1455 of yacc.c  */\n#line 874 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (3)].num)), tTJSVariant()); ;}\n    break;\n\n  case 270:\n\n/* Line 1455 of yacc.c  */\n#line 875 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (3)].num)), (yyvsp[(3) - (3)].np)->GetValue()); ;}\n    break;\n\n  case 271:\n\n/* Line 1455 of yacc.c  */\n#line 876 \"syntax/tjs.y\"\n    { cn->AddDictionaryElement(lx->GetValue((yyvsp[(1) - (3)].num)), (yyvsp[(3) - (3)].np)->GetValue()); ;}\n    break;\n\n\n\n/* Line 1455 of yacc.c  */\n#line 3730 \"tjs.tab.cpp\"\n      default: break;\n    }\n  YY_SYMBOL_PRINT (\"-> $$ =\", yyr1[yyn], &yyval, &yyloc);\n\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n\n  *++yyvsp = yyval;\n\n  /* Now `shift' the result of the reduction.  Determine what state\n     that goes to, based on the state we popped back to and the rule\n     number reduced by.  */\n\n  yyn = yyr1[yyn];\n\n  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\n  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\n    yystate = yytable[yystate];\n  else\n    yystate = yydefgoto[yyn - YYNTOKENS];\n\n  goto yynewstate;\n\n\n/*------------------------------------.\n| yyerrlab -- here on detecting error |\n`------------------------------------*/\nyyerrlab:\n  /* If not already recovering from an error, report this error.  */\n  if (!yyerrstatus)\n    {\n      ++yynerrs;\n#if ! YYERROR_VERBOSE\n      yyerror (YY_(\"syntax error\"));\n#else\n      {\n\tYYSIZE_T yysize = yysyntax_error (0, yystate, yychar);\n\tif (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)\n\t  {\n\t    YYSIZE_T yyalloc = 2 * yysize;\n\t    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))\n\t      yyalloc = YYSTACK_ALLOC_MAXIMUM;\n\t    if (yymsg != yymsgbuf)\n\t      YYSTACK_FREE (yymsg);\n\t    yymsg = (char *) YYSTACK_ALLOC (yyalloc);\n\t    if (yymsg)\n\t      yymsg_alloc = yyalloc;\n\t    else\n\t      {\n\t\tyymsg = yymsgbuf;\n\t\tyymsg_alloc = sizeof yymsgbuf;\n\t      }\n\t  }\n\n\tif (0 < yysize && yysize <= yymsg_alloc)\n\t  {\n\t    (void) yysyntax_error (yymsg, yystate, yychar);\n\t    yyerror (yymsg);\n\t  }\n\telse\n\t  {\n\t    yyerror (YY_(\"syntax error\"));\n\t    if (yysize != 0)\n\t      goto yyexhaustedlab;\n\t  }\n      }\n#endif\n    }\n\n\n\n  if (yyerrstatus == 3)\n    {\n      /* If just tried and failed to reuse lookahead token after an\n\t error, discard it.  */\n\n      if (yychar <= YYEOF)\n\t{\n\t  /* Return failure if at end of input.  */\n\t  if (yychar == YYEOF)\n\t    YYABORT;\n\t}\n      else\n\t{\n\t  yydestruct (\"Error: discarding\",\n\t\t      yytoken, &yylval);\n\t  yychar = YYEMPTY;\n\t}\n    }\n\n  /* Else will try to reuse lookahead token after shifting the error\n     token.  */\n  goto yyerrlab1;\n\n\n/*---------------------------------------------------.\n| yyerrorlab -- error raised explicitly by YYERROR.  |\n`---------------------------------------------------*/\nyyerrorlab:\n\n  /* Pacify compilers like GCC when the user code never invokes\n     YYERROR and the label yyerrorlab therefore never appears in user\n     code.  */\n  if (/*CONSTCOND*/ 0)\n     goto yyerrorlab;\n\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYERROR.  */\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n  yystate = *yyssp;\n  goto yyerrlab1;\n\n\n/*-------------------------------------------------------------.\n| yyerrlab1 -- common code for both syntax error and YYERROR.  |\n`-------------------------------------------------------------*/\nyyerrlab1:\n  yyerrstatus = 3;\t/* Each real token shifted decrements this.  */\n\n  for (;;)\n    {\n      yyn = yypact[yystate];\n      if (yyn != YYPACT_NINF)\n\t{\n\t  yyn += YYTERROR;\n\t  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\n\t    {\n\t      yyn = yytable[yyn];\n\t      if (0 < yyn)\n\t\tbreak;\n\t    }\n\t}\n\n      /* Pop the current state because it cannot handle the error token.  */\n      if (yyssp == yyss)\n\tYYABORT;\n\n\n      yydestruct (\"Error: popping\",\n\t\t  yystos[yystate], yyvsp);\n      YYPOPSTACK (1);\n      yystate = *yyssp;\n      YY_STACK_PRINT (yyss, yyssp);\n    }\n\n  *++yyvsp = yylval;\n\n\n  /* Shift the error token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yystos[yyn], yyvsp, yylsp);\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-------------------------------------.\n| yyacceptlab -- YYACCEPT comes here.  |\n`-------------------------------------*/\nyyacceptlab:\n  yyresult = 0;\n  goto yyreturn;\n\n/*-----------------------------------.\n| yyabortlab -- YYABORT comes here.  |\n`-----------------------------------*/\nyyabortlab:\n  yyresult = 1;\n  goto yyreturn;\n\n#if !defined(yyoverflow) || YYERROR_VERBOSE\n/*-------------------------------------------------.\n| yyexhaustedlab -- memory exhaustion comes here.  |\n`-------------------------------------------------*/\nyyexhaustedlab:\n  yyerror (YY_(\"memory exhausted\"));\n  yyresult = 2;\n  /* Fall through.  */\n#endif\n\nyyreturn:\n  if (yychar != YYEMPTY)\n     yydestruct (\"Cleanup: discarding lookahead\",\n\t\t yytoken, &yylval);\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYABORT or YYACCEPT.  */\n  YYPOPSTACK (yylen);\n  YY_STACK_PRINT (yyss, yyssp);\n  while (yyssp != yyss)\n    {\n      yydestruct (\"Cleanup: popping\",\n\t\t  yystos[*yyssp], yyvsp);\n      YYPOPSTACK (1);\n    }\n#ifndef yyoverflow\n  if (yyss != yyssa)\n    YYSTACK_FREE (yyss);\n#endif\n#if YYERROR_VERBOSE\n  if (yymsg != yymsgbuf)\n    YYSTACK_FREE (yymsg);\n#endif\n  /* Make sure YYID is used.  */\n  return YYID (yyresult);\n}\n\n\n\n/* Line 1675 of yacc.c  */\n#line 881 \"syntax/tjs.y\"\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjs.tab.h",
    "content": "namespace TJS {\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton interface for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     T_COMMA = 258,\n     T_EQUAL = 259,\n     T_AMPERSANDEQUAL = 260,\n     T_VERTLINEEQUAL = 261,\n     T_CHEVRONEQUAL = 262,\n     T_MINUSEQUAL = 263,\n     T_PLUSEQUAL = 264,\n     T_PERCENTEQUAL = 265,\n     T_SLASHEQUAL = 266,\n     T_BACKSLASHEQUAL = 267,\n     T_ASTERISKEQUAL = 268,\n     T_LOGICALOREQUAL = 269,\n     T_LOGICALANDEQUAL = 270,\n     T_RBITSHIFTEQUAL = 271,\n     T_LARITHSHIFTEQUAL = 272,\n     T_RARITHSHIFTEQUAL = 273,\n     T_QUESTION = 274,\n     T_LOGICALOR = 275,\n     T_LOGICALAND = 276,\n     T_VERTLINE = 277,\n     T_CHEVRON = 278,\n     T_AMPERSAND = 279,\n     T_NOTEQUAL = 280,\n     T_EQUALEQUAL = 281,\n     T_DISCNOTEQUAL = 282,\n     T_DISCEQUAL = 283,\n     T_SWAP = 284,\n     T_LT = 285,\n     T_GT = 286,\n     T_LTOREQUAL = 287,\n     T_GTOREQUAL = 288,\n     T_RARITHSHIFT = 289,\n     T_LARITHSHIFT = 290,\n     T_RBITSHIFT = 291,\n     T_PERCENT = 292,\n     T_SLASH = 293,\n     T_BACKSLASH = 294,\n     T_ASTERISK = 295,\n     T_EXCRAMATION = 296,\n     T_TILDE = 297,\n     T_DECREMENT = 298,\n     T_INCREMENT = 299,\n     T_NEW = 300,\n     T_DELETE = 301,\n     T_TYPEOF = 302,\n     T_PLUS = 303,\n     T_MINUS = 304,\n     T_SHARP = 305,\n     T_DOLLAR = 306,\n     T_ISVALID = 307,\n     T_INVALIDATE = 308,\n     T_INSTANCEOF = 309,\n     T_LPARENTHESIS = 310,\n     T_DOT = 311,\n     T_LBRACKET = 312,\n     T_THIS = 313,\n     T_SUPER = 314,\n     T_GLOBAL = 315,\n     T_RBRACKET = 316,\n     T_CLASS = 317,\n     T_RPARENTHESIS = 318,\n     T_COLON = 319,\n     T_SEMICOLON = 320,\n     T_LBRACE = 321,\n     T_RBRACE = 322,\n     T_CONTINUE = 323,\n     T_FUNCTION = 324,\n     T_DEBUGGER = 325,\n     T_DEFAULT = 326,\n     T_CASE = 327,\n     T_EXTENDS = 328,\n     T_FINALLY = 329,\n     T_PROPERTY = 330,\n     T_PRIVATE = 331,\n     T_PUBLIC = 332,\n     T_PROTECTED = 333,\n     T_STATIC = 334,\n     T_RETURN = 335,\n     T_BREAK = 336,\n     T_EXPORT = 337,\n     T_IMPORT = 338,\n     T_SWITCH = 339,\n     T_IN = 340,\n     T_INCONTEXTOF = 341,\n     T_FOR = 342,\n     T_WHILE = 343,\n     T_DO = 344,\n     T_IF = 345,\n     T_VAR = 346,\n     T_CONST = 347,\n     T_ENUM = 348,\n     T_GOTO = 349,\n     T_THROW = 350,\n     T_TRY = 351,\n     T_SETTER = 352,\n     T_GETTER = 353,\n     T_ELSE = 354,\n     T_CATCH = 355,\n     T_OMIT = 356,\n     T_SYNCHRONIZED = 357,\n     T_WITH = 358,\n     T_INT = 359,\n     T_REAL = 360,\n     T_STRING = 361,\n     T_OCTET = 362,\n     T_FALSE = 363,\n     T_NULL = 364,\n     T_TRUE = 365,\n     T_VOID = 366,\n     T_NAN = 367,\n     T_INFINITY = 368,\n     T_UPLUS = 369,\n     T_UMINUS = 370,\n     T_EVAL = 371,\n     T_POSTDECREMENT = 372,\n     T_POSTINCREMENT = 373,\n     T_IGNOREPROP = 374,\n     T_PROPACCESS = 375,\n     T_ARG = 376,\n     T_EXPANDARG = 377,\n     T_INLINEARRAY = 378,\n     T_ARRAYARG = 379,\n     T_INLINEDIC = 380,\n     T_DICELM = 381,\n     T_WITHDOT = 382,\n     T_THIS_PROXY = 383,\n     T_WITHDOT_PROXY = 384,\n     T_CONSTVAL = 385,\n     T_SYMBOL = 386,\n     T_REGEXP = 387\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 1676 of yacc.c  */\n//#line 60 \"tjs.y\"\n\n\ttjs_int\t\t\tnum;\n\ttTJSExprNode *\t\tnp;\n\n\n\n/* Line 1676 of yacc.c  */\n//#line 191 \"tjs.tab.h\"\n} YYSTYPE;\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjs.tab.hpp",
    "content": "namespace TJS {\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton interface for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     T_COMMA = 258,\n     T_EQUAL = 259,\n     T_AMPERSANDEQUAL = 260,\n     T_VERTLINEEQUAL = 261,\n     T_CHEVRONEQUAL = 262,\n     T_MINUSEQUAL = 263,\n     T_PLUSEQUAL = 264,\n     T_PERCENTEQUAL = 265,\n     T_SLASHEQUAL = 266,\n     T_BACKSLASHEQUAL = 267,\n     T_ASTERISKEQUAL = 268,\n     T_LOGICALOREQUAL = 269,\n     T_LOGICALANDEQUAL = 270,\n     T_RBITSHIFTEQUAL = 271,\n     T_LARITHSHIFTEQUAL = 272,\n     T_RARITHSHIFTEQUAL = 273,\n     T_QUESTION = 274,\n     T_LOGICALOR = 275,\n     T_LOGICALAND = 276,\n     T_VERTLINE = 277,\n     T_CHEVRON = 278,\n     T_AMPERSAND = 279,\n     T_NOTEQUAL = 280,\n     T_EQUALEQUAL = 281,\n     T_DISCNOTEQUAL = 282,\n     T_DISCEQUAL = 283,\n     T_SWAP = 284,\n     T_LT = 285,\n     T_GT = 286,\n     T_LTOREQUAL = 287,\n     T_GTOREQUAL = 288,\n     T_RARITHSHIFT = 289,\n     T_LARITHSHIFT = 290,\n     T_RBITSHIFT = 291,\n     T_PERCENT = 292,\n     T_SLASH = 293,\n     T_BACKSLASH = 294,\n     T_ASTERISK = 295,\n     T_EXCRAMATION = 296,\n     T_TILDE = 297,\n     T_DECREMENT = 298,\n     T_INCREMENT = 299,\n     T_NEW = 300,\n     T_DELETE = 301,\n     T_TYPEOF = 302,\n     T_PLUS = 303,\n     T_MINUS = 304,\n     T_SHARP = 305,\n     T_DOLLAR = 306,\n     T_ISVALID = 307,\n     T_INVALIDATE = 308,\n     T_INSTANCEOF = 309,\n     T_LPARENTHESIS = 310,\n     T_DOT = 311,\n     T_LBRACKET = 312,\n     T_THIS = 313,\n     T_SUPER = 314,\n     T_GLOBAL = 315,\n     T_RBRACKET = 316,\n     T_CLASS = 317,\n     T_RPARENTHESIS = 318,\n     T_COLON = 319,\n     T_SEMICOLON = 320,\n     T_LBRACE = 321,\n     T_RBRACE = 322,\n     T_CONTINUE = 323,\n     T_FUNCTION = 324,\n     T_DEBUGGER = 325,\n     T_DEFAULT = 326,\n     T_CASE = 327,\n     T_EXTENDS = 328,\n     T_FINALLY = 329,\n     T_PROPERTY = 330,\n     T_PRIVATE = 331,\n     T_PUBLIC = 332,\n     T_PROTECTED = 333,\n     T_STATIC = 334,\n     T_RETURN = 335,\n     T_BREAK = 336,\n     T_EXPORT = 337,\n     T_IMPORT = 338,\n     T_SWITCH = 339,\n     T_IN = 340,\n     T_INCONTEXTOF = 341,\n     T_FOR = 342,\n     T_WHILE = 343,\n     T_DO = 344,\n     T_IF = 345,\n     T_VAR = 346,\n     T_CONST = 347,\n     T_ENUM = 348,\n     T_GOTO = 349,\n     T_THROW = 350,\n     T_TRY = 351,\n     T_SETTER = 352,\n     T_GETTER = 353,\n     T_ELSE = 354,\n     T_CATCH = 355,\n     T_OMIT = 356,\n     T_SYNCHRONIZED = 357,\n     T_WITH = 358,\n     T_INT = 359,\n     T_REAL = 360,\n     T_STRING = 361,\n     T_OCTET = 362,\n     T_FALSE = 363,\n     T_NULL = 364,\n     T_TRUE = 365,\n     T_VOID = 366,\n     T_NAN = 367,\n     T_INFINITY = 368,\n     T_UPLUS = 369,\n     T_UMINUS = 370,\n     T_EVAL = 371,\n     T_POSTDECREMENT = 372,\n     T_POSTINCREMENT = 373,\n     T_IGNOREPROP = 374,\n     T_PROPACCESS = 375,\n     T_ARG = 376,\n     T_EXPANDARG = 377,\n     T_INLINEARRAY = 378,\n     T_ARRAYARG = 379,\n     T_INLINEDIC = 380,\n     T_DICELM = 381,\n     T_WITHDOT = 382,\n     T_THIS_PROXY = 383,\n     T_WITHDOT_PROXY = 384,\n     T_CONSTVAL = 385,\n     T_SYMBOL = 386,\n     T_REGEXP = 387,\n     T_VARIANT = 388\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 1676 of yacc.c  */\n#line 60 \"tjs.y\"\n\n\ttjs_int\t\t\tnum;\n\ttTJSExprNode *\t\tnp;\n\n\n\n/* Line 1676 of yacc.c  */\n#line 192 \"tjs.tab.hpp\"\n} YYSTYPE;\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsArray.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Array class implementation\n//---------------------------------------------------------------------------\n\n\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include <functional>\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"tjsUtils.h\"\n#include \"tjsBinarySerializer.h\"\n#include \"tjsOctPack.h\"\n\n#ifndef TJS_NO_REGEXP\n#include \"tjsRegExp.h\"\n#endif\n\n// TODO: Check the deque's exception handling on deleting\n\n\n#define TJS_ARRAY_BASE_HASH_BITS 3\n\t/* hash bits for base \"Object\" hash */\n\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nstatic tjs_int32 ClassID_Array;\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswspace(tjs_char ch)\n{\n\t// the standard iswspace misses when non-zero page code\n\tif(ch&0xff00) return false; else return 0!=isspace(ch);\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswdigit(tjs_char ch)\n{\n\t// the standard iswdigit misses when non-zero page code\n\tif(ch&0xff00) return false; else return 0!=isdigit(ch);\n}\n//---------------------------------------------------------------------------\n// Utility Function(s)\n//---------------------------------------------------------------------------\nstatic bool IsNumber(const tjs_char *str, tjs_int &result)\n{\n\t// when str indicates a number, this function converts it to\n\t// number and put to result, and returns true.\n\t// otherwise returns false.\n\tif(!str) return false;\n\tconst tjs_char *orgstr = str;\n\n\tif(!*str) return false;\n\twhile(*str && TJS_iswspace(*str)) str++;\n\tif(!*str) return false;\n\tif(*str == TJS_W('-')) str++; // sign\n\telse if(*str == TJS_W('+')) str++, orgstr = str; // sign, but skip\n\tif(!*str) return false;\n\twhile(*str && TJS_iswspace(*str)) str++;\n\tif(!*str) return false;\n\tif(!TJS_iswdigit(*str)) return false;\n\twhile(*str && (TJS_iswdigit(*str) || *str == '.')) str++;\n\twhile(*str && TJS_iswspace(*str)) str++;\n\tif(*str == 0)\n\t{\n\t\tresult = TJS_atoi(orgstr);\n\t\treturn true;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSStringAppender\n//---------------------------------------------------------------------------\n#define TJS_STRINGAPPENDER_DATA_INC 8192\ntTJSStringAppender::tTJSStringAppender()\n{\n\tData = NULL;\n\tDataLen = 0;\n\tDataCapacity = 0;\n}\n//---------------------------------------------------------------------------\ntTJSStringAppender::~tTJSStringAppender()\n{\n\tif(Data) TJSVS_free(Data);\n}\n//---------------------------------------------------------------------------\nvoid tTJSStringAppender::Append(const tjs_char *string, tjs_int len)\n{\n\tif(!Data)\n\t{\n\t\tif(len > 0)\n\t\t{\n\t\t\tData = TJSVS_malloc(DataCapacity = len * sizeof(tjs_char));\n\t\t\tmemcpy(Data, string, DataCapacity);\n\t\t\tDataLen = len;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(DataLen + len > DataCapacity)\n\t\t{\n\t\t\tDataCapacity = DataLen + len + TJS_STRINGAPPENDER_DATA_INC;\n\t\t\tData = TJSVS_realloc(Data, DataCapacity * sizeof(tjs_char));\n\t\t}\n\t\tmemcpy(Data + DataLen, string, len * sizeof(tjs_char));\n\t\tDataLen += len;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSArraySortCompare  : a class for comarison operator\n//---------------------------------------------------------------------------\nclass tTJSArraySortCompare_NormalAscending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\treturn (lhs < rhs).operator bool();\n\t}\n};\nclass tTJSArraySortCompare_NormalDescending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\treturn (lhs > rhs).operator bool();\n\t}\n};\nclass tTJSArraySortCompare_NumericAscending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\tif(lhs.Type() == tvtString && rhs.Type() == tvtString)\n\t\t{\n\t\t\ttTJSVariant ltmp(lhs), rtmp(rhs);\n\t\t\tltmp.tonumber();\n\t\t\trtmp.tonumber();\n\t\t\treturn (ltmp < rtmp).operator bool();\n\t\t}\n\t\treturn (lhs < rhs).operator bool();\n\t}\n};\nclass tTJSArraySortCompare_NumericDescending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\tif(lhs.Type() == tvtString && rhs.Type() == tvtString)\n\t\t{\n\t\t\ttTJSVariant ltmp(lhs), rtmp(rhs);\n\t\t\tltmp.tonumber();\n\t\t\trtmp.tonumber();\n\t\t\treturn (ltmp > rtmp).operator bool();\n\t\t}\n\t\treturn (lhs > rhs).operator bool();\n\t}\n};\nclass tTJSArraySortCompare_StringAscending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\tif(lhs.Type() == tvtString && rhs.Type() == tvtString)\n\t\t\treturn (lhs < rhs).operator bool();\n\t\treturn (ttstr)lhs < (ttstr)rhs;\n\t}\n};\nclass tTJSArraySortCompare_StringDescending :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\npublic:\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\t\tif(lhs.Type() == tvtString && rhs.Type() == tvtString)\n\t\t\treturn (lhs > rhs).operator bool();\n\t\treturn (ttstr)lhs > (ttstr)rhs;\n\t}\n};\nclass tTJSArraySortCompare_Functional :\n\tpublic std::binary_function<const tTJSVariant &, const tTJSVariant &, bool>\n{\n\ttTJSVariantClosure Closure;\npublic:\n\ttTJSArraySortCompare_Functional(const tTJSVariantClosure &clo) :\n\t\tClosure(clo)\n\t{\n\t}\n\n\tresult_type operator () (first_argument_type lhs, second_argument_type rhs) const\n\t{\n\n\t\ttTJSVariant result;\n\n\t\ttjs_error hr;\n\t\ttTJSVariant *param[] = {\n\t\t\tconst_cast<tTJSVariant *>(&lhs), // note that doing cast to non-const pointer\n\t\t\tconst_cast<tTJSVariant *>(&rhs) };\n\n\t\thr = Closure.FuncCall(0, NULL, NULL, &result, 2, param, NULL);\n\n\t\tif(TJS_FAILED(hr))\n\t\t\tTJSThrowFrom_tjs_error(hr);\n\n\t\treturn result.operator bool();\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSArrayClass : tTJSArray class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSArrayClass::ClassID = (tjs_uint32)-1;\ntTJSArrayClass::tTJSArrayClass() :\n\ttTJSNativeClass(TJS_W(\"Array\"))\n{\n\t// class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/* TJS class name */Array)\n\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/* var. name */_this, /* var. type */tTJSArrayNI,\n\t/* TJS class name */ Array)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Array)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func. name */load)\n{\n\t// loads a file into this array.\n\t// each a line becomes an array element.\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode =*param[1];\n\n\tiTJSTextReadStream * stream = TJSCreateTextStreamForRead(name, mode);\n\ttry\n\t{\n\t\tni->Items.clear();\n\t\tttstr content;\n\t\tstream->Read(content, 0);\n\t\tconst tjs_char * p = content.c_str();\n\t\tconst tjs_char * sp = p;\n\t\ttjs_uint l;\n\n\t\t// count lines\n\t\ttjs_uint lines = 0;\n\t\twhile(*p)\n\t\t{\n\t\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n'))\n\t\t\t{\n\t\t\t\ttjs_uint l = (tjs_uint)(p - sp);\n\n\t\t\t\tp++;\n\t\t\t\tif(p[-1] == TJS_W('\\r') && p[0] == TJS_W('\\n')) p++;\n\n\t\t\t\tlines++;\n\n\t\t\t\tsp = p;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\n\t\tl = (tjs_uint)(p - sp);\n\t\tif(l)\n\t\t{\n\t\t\tlines++;\n\t\t}\n\n\t\tni->Items.resize(lines);\n\n\t\t// split to each line\n\t\tp = content.c_str();\n\t\tsp = p;\n\t\tlines = 0;\n\n\t\ttTJSVariantString *vs;\n\n\t\ttry\n\t\t{\n\t\t\twhile(*p)\n\t\t\t{\n\t\t\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n'))\n\t\t\t\t{\n\t\t\t\t\ttjs_uint l = (tjs_uint)(p - sp);\n\n\t\t\t\t\tp++;\n\t\t\t\t\tif(p[-1] == TJS_W('\\r') && p[0] == TJS_W('\\n')) p++;\n\n\t\t\t\t\tvs = TJSAllocVariantString(sp, l);\n\t\t\t\t\tni->Items[lines++] = vs;\n\t\t\t\t\tif(vs) vs->Release(), vs = NULL;\n\n\t\t\t\t\tsp = p;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t\tl = (tjs_uint)(p - sp);\n\t\t\tif(l)\n\t\t\t{\n\t\t\t\tvs = TJSAllocVariantString(sp, l);\n\t\t\t\tni->Items[lines] = vs;\n\t\t\t\tif(vs) vs->Release(), vs = NULL;\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(vs) vs->Release();\n\t\t\tthrow;\n\t\t}\n\n\n\t}\n\tcatch(...)\n\t{\n\t\tstream->Destruct();\n\t\tthrow;\n\t}\n\tstream->Destruct();\n\n\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */load)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadStruct)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode =*param[1];\n\n\tni->Items.clear();\n\n\ttTJSBinaryStream* stream = TJSCreateBinaryStreamForRead(name, mode);\n\tif( !stream ) return TJS_E_INVALIDPARAM;\n\n\tbool isbin = false;\n\ttry {\n\t\ttjs_uint64 streamlen = stream->GetSize();\n\t\tif( streamlen >= tTJSBinarySerializer::HEADER_LENGTH ) {\n\t\t\ttjs_uint8 header[tTJSBinarySerializer::HEADER_LENGTH];\n\t\t\tstream->Read( header, tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\tif( tTJSBinarySerializer::IsBinary( header ) ) {\n\t\t\t\ttTJSBinarySerializer binload((tTJSArrayObject*)objthis);\n\t\t\t\ttTJSVariant* var = binload.Read( stream );\n\t\t\t\tif( var ) {\n\t\t\t\t\tif( result ) *result = *var;\n\t\t\t\t\tdelete var;\n\t\t\t\t\tisbin = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tdelete stream;\n\t\tthrow;\n\t}\n\tdelete stream;\n\tif( isbin ) return TJS_S_OK;\n\treturn TJS_E_INVALIDPARAM;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/loadStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func. name */save)\n{\n\t// saves the array into a file.\n\t// only string and number stuffs are stored.\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode = *param[1];\n\tiTJSTextWriteStream * stream = TJSCreateTextStreamForWrite(name, mode);\n\ttry\n\t{\n\t\ttTJSArrayNI::tArrayItemIterator i = ni->Items.begin();\n#ifdef TJS_TEXT_OUT_CRLF\n\t\tconst static ttstr cr(TJS_W(\"\\r\\n\"));\n#else\n\t\tconst static ttstr cr(TJS_W(\"\\n\"));\n#endif\n\n\t\twhile( i != ni->Items.end())\n\t\t{\n\t\t\ttTJSVariantType type = i->Type();\n\t\t\tif(type == tvtString || type == tvtInteger || type == tvtReal)\n\t\t\t{\n\t\t\t\tstream->Write(*i);\n\t\t\t}\n\t\t\tstream->Write(cr);\n\t\t\ti++;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tstream->Destruct();\n\t\tthrow;\n\t}\n\tstream->Destruct();\n\n\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */save)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func. name */saveStruct)\n{\n\t// saves the array into a file, that can be interpret as an expression.\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode = *param[1];\n\n\tif( TJS_strchr(mode.c_str(), TJS_W('b')) != NULL ) {\n\t\ttTJSBinaryStream* stream = TJSCreateBinaryStreamForWrite(name, mode);\n\t\ttry {\n\t\t\tstream->Write( tTJSBinarySerializer::HEADER, tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\tstd::vector<iTJSDispatch2 *> stack;\n\t\t\tstack.push_back(objthis);\n\t\t\tni->SaveStructuredBinary(stack, *stream);\n\t\t} catch(...) {\n\t\t\tdelete stream;\n\t\t\tthrow;\n\t\t}\n\t\tdelete stream;\n\t} else {\n\t\tiTJSTextWriteStream * stream = TJSCreateTextStreamForWrite(name, mode);\n\t\ttry\n\t\t{\n\t\t\tstd::vector<iTJSDispatch2 *> stack;\n\t\t\tstack.push_back(objthis);\n\t\t\tni->SaveStructuredData(stack, *stream, TJS_W(\"\"));\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tstream->Destruct();\n\t\t\tthrow;\n\t\t}\n\t\tstream->Destruct();\n\t}\n\n\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */saveStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */split)\n{\n\t// split string with given delimiters.\n\n\t// arguments are : <pattern/delimiter>, <string>, [<reserved>],\n\t// [<whether ignore empty element>]\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tni->Items.resize(0);\n\ttTJSString string = *param[1];\n\tbool purgeempty = false;\n\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\tpurgeempty = param[3]->operator bool();\n\n#ifndef TJS_NO_REGEXP\n\tif(param[0]->Type() == tvtObject)\n\t{\n\t\ttTJSNI_RegExp * re = NULL;\n\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\tif(TJS_SUCCEEDED(clo.Object->NativeInstanceSupport(\n\t\t\t\tTJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_RegExp::ClassID, (iTJSNativeInstance**)&re)))\n\t\t\t{\n\t\t\t\t// param[0] is regexp\n\t\t\t\tiTJSDispatch2 *array = objthis;\n\t\t\t\tre->Split(&array, string, purgeempty);\n\n\t\t\t\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t}\n\t}\n#endif\n\n\ttTJSString pattern = *param[0];\n\n\n\t// split with delimiter\n\tconst tjs_char *s = string.c_str();\n\tconst tjs_char *delim = pattern.c_str();\n\tconst tjs_char *sstart = s;\n\twhile(*s)\n\t{\n\t\tif(TJS_strchr(delim, *s) != NULL)\n\t\t{\n\t\t\t// delimiter found\n\t\t\tif(!purgeempty || (purgeempty && (s-sstart)!=0) )\n\t\t\t{\n\t\t\t\tni->Items.push_back(tTJSString(sstart, (int)(s-sstart)));\n\t\t\t}\n\t\t\ts++;\n\t\t\tsstart = s;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ts++;\n\t\t}\n\t}\n\n\tif(!purgeempty || (purgeempty && (s-sstart)!=0) )\n\t{\n\t\tni->Items.push_back(tTJSString(sstart, (int)(s-sstart)));\n\t}\n\n\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */split)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */join)\n{\n\t// join string with given delimiters.\n\n\t// arguments are : <delimiter>, [<reserved>],\n\t// [<whether ignore empty element>]\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSString delimiter = *param[0];\n\n\tbool purgeempty = false;\n\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tpurgeempty = param[2]->operator bool();\n\n\t// join with delimiter\n\tbool first = true;\n\ttTJSString out;\n\ttTJSArrayNI::tArrayItemIterator i;\n\tfor(i = ni->Items.begin(); i != ni->Items.end(); i++)\n\t{\n\t\tif(purgeempty && i->Type() == tvtVoid) continue;\n\n\t\tif(!first) out += delimiter;\n\t\tfirst = false;\n\t\tout += (tTJSString)(*i);\n\t}\n\n\tif(result) *result = out;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */join)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */sort)\n{\n\t// sort array items.\n\n\t// arguments are : [<sort order/comparison function>], [<whether to do stable sort>]\n\n\t// sort order is one of:\n\t// '+' (default)   :  Normal ascending  (comparison by tTJSVariant::operator < )\n\t// '-'             :  Normal descending (comparison by tTJSVariant::operator < )\n\t// '0'             :  Numeric value ascending\n\t// '9'             :  Numeric value descending\n\t// 'a'             :  String ascending\n\t// 'z'             :  String descending\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\ttjs_nchar method = TJS_N('+');\n\tbool do_stable_sort = false;\n\ttTJSVariantClosure closure;\n\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t{\n\t\t// check first argument\n\t\tif(param[0]->Type() == tvtObject)\n\t\t{\n\t\t\t// comarison function object\n\t\t\tclosure = param[0]->AsObjectClosureNoAddRef();\n\t\t\tmethod = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// sort order letter\n\t\t\tttstr me = *param[0];\n\t\t\tmethod = (tjs_nchar)(me.c_str()[0]);\n\n\t\t\tswitch(method)\n\t\t\t{\n\t\t\tcase TJS_N('+'):\n\t\t\tcase TJS_N('-'):\n\t\t\tcase TJS_N('0'):\n\t\t\tcase TJS_N('9'):\n\t\t\tcase TJS_N('a'):\n\t\t\tcase TJS_N('z'):\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tmethod = TJS_N('+');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t{\n\t\t// whether to do a stable sort\n\t\tdo_stable_sort = param[1]->operator bool();\n\t}\n\n\n\t// sort\n\tswitch(method)\n\t{\n\tcase TJS_N('+'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NormalAscending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NormalAscending());\n\t\tbreak;\n\tcase TJS_N('-'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NormalDescending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NormalDescending());\n\t\tbreak;\n\tcase TJS_N('0'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NumericAscending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NumericAscending());\n\t\tbreak;\n\tcase TJS_N('9'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NumericDescending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_NumericDescending());\n\t\tbreak;\n\tcase TJS_N('a'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_StringAscending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_StringAscending());\n\t\tbreak;\n\tcase TJS_N('z'):\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_StringDescending());\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_StringDescending());\n\t\tbreak;\n\tcase 0:\n\t\tif(do_stable_sort)\n\t\t\tstd::stable_sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_Functional(closure));\n\t\telse\n\t\t\tstd::sort(ni->Items.begin(), ni->Items.end(),\n\t\t\t\ttTJSArraySortCompare_Functional(closure));\n\t\tbreak;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */sort)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */reverse)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\t// reverse array\n\tstd::reverse(ni->Items.begin(), ni->Items.end());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */reverse)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */assign)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t((tTJSArrayObject*)objthis)->Clear(ni);\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.ObjThis)\n\t\tni->Assign(clo.ObjThis);\n\telse if(clo.Object)\n\t\tni->Assign(clo.Object);\n\telse TJS_eTJSError(TJSNullAccess);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */assign)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */assignStruct)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t((tTJSArrayObject*)objthis)->Clear(ni);\n\tstd::vector<iTJSDispatch2 *> stack;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.ObjThis)\n\t\tni->AssignStructure(clo.ObjThis, stack);\n\telse if(clo.Object)\n\t\tni->AssignStructure(clo.Object, stack);\n\telse TJS_eTJSError(TJSNullAccess);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */assignStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */clear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\t((tTJSArrayObject*)objthis)->Clear(ni);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */clear)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */erase)\n{\n\t// remove specified item number from the array\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_int num = *param[0];\n\n\t((tTJSArrayObject*)objthis)->Erase(ni, num);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */erase)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */remove)\n{\n\t// remove specified item from the array wchich appears first or all\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tbool eraseall;\n\tif(numparams >= 2)\n\t\teraseall = param[1]->operator bool();\n\telse\n\t\teraseall = true;\n\n\ttTJSVariant & val = *param[0];\n\n\ttjs_int count = ((tTJSArrayObject*)objthis)->Remove(ni, val, eraseall);\n\n\tif(result) *result = count;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */remove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */insert)\n{\n\t// insert item at specified position\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_int num = *param[0];\n\n\t((tTJSArrayObject*)objthis)->Insert(ni, *param[1], num);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */insert)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */add)\n{\n\t// add item at last\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t((tTJSArrayObject*)objthis)->Add(ni, *param[0]);\n\n\tif(result) *result = (signed)ni->Items.size() -1;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */add)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */push)\n{\n\t// add item(s) at last\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\t((tTJSArrayObject*)objthis)->Insert(ni, param, numparams, (tjs_int)ni->Items.size());\n\n\tif(result) *result = (tTVInteger)(ni->Items.size());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */push)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */pop)\n{\n\t// pop item from last\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(ni->Items.empty())\n\t{\n\t\tif(result) result->Clear();\n\t}\n\telse\n\t{\n\t\tif(result) *result = ni->Items[ni->Items.size() - 1];\n\t\t((tTJSArrayObject*)objthis)->Erase(ni, (tjs_int)(ni->Items.size() - 1));\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */pop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */shift)\n{\n\t// shift item at head\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(ni->Items.empty())\n\t{\n\t\tif(result) result->Clear();\n\t}\n\telse\n\t{\n\t\tif(result) *result = ni->Items[0];\n\t\t((tTJSArrayObject*)objthis)->Erase(ni, 0);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */shift)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */unshift)\n{\n\t// add item(s) at head\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\t((tTJSArrayObject*)objthis)->Insert(ni, param, numparams, 0);\n\n\tif(result) *result = (tTVInteger)(ni->Items.size());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */unshift)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */find)\n{\n\t// find item in the array,\n\t// return an index which points the item that appears first.\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif(result)\n\t{\n\t\ttTJSVariant & val = *param[0];\n\t\ttjs_int start = 0;\n\t\tif(numparams >= 2) start = *param[1];\n\t\tif(start < 0) start += (tjs_int)ni->Items.size();\n\t\tif(start < 0) start = 0;\n\t\tif(start >= (tjs_int)ni->Items.size()) { *result = -1; return TJS_S_OK; }\n\n\t\ttTJSArrayNI::tArrayItemIterator i;\n\t\tfor(i = ni->Items.begin() + start; i != ni->Items.end(); i++)\n\t\t{\n\t\t\tif(val.DiscernCompare(*i)) break;\n\t\t}\n\t\tif(i == ni->Items.end())\n\t\t\t*result = -1;\n\t\telse\n\t\t\tresult->operator=((tjs_int)(i - ni->Items.begin()));\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */find)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */pack)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif(result) return TJSOctetPack( param, numparams, ni->Items, result );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/* func.name */pack)\n//----------------------------------------------------------------------\n\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(count)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\t\tif(result) *result = (tTVInteger)(ni->Items.size());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\t\tni->Items.resize((tjs_uint)(tTVInteger)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(count)\n//----------------------------------------------------------------------\n// same as count\nTJS_BEGIN_NATIVE_PROP_DECL(length)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\t\tif(result) *result = (tTVInteger)(ni->Items.size());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSArrayNI);\n\t\tni->Items.resize((tjs_uint)(tTVInteger)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(length)\n//----------------------------------------------------------------------\n\n\tClassID_Array = TJS_NCM_CLASSID;\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSArrayClass::~tTJSArrayClass()\n{\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSArrayClass::CreateNativeInstance()\n{\n\treturn new tTJSArrayNI(); // return a native object instance.\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 *tTJSArrayClass::CreateBaseTJSObject()\n{\n\treturn new tTJSArrayObject();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSArrayNI\n//---------------------------------------------------------------------------\ntTJSArrayNI::tTJSArrayNI()\n{\n\t// constructor\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSArrayNI::Construct(tjs_int numparams, tTJSVariant **params,\n\tiTJSDispatch2 * tjsobj)\n{\n\t// called by TJS constructor\n\tif(numparams!=0) return TJS_E_BADPARAMCOUNT;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::Assign(iTJSDispatch2 * dsp)\n{\n\t// copy members from \"dsp\" to \"Owner\"\n\n\t// determin dsp's object type\n\ttTJSArrayNI *arrayni = NULL;\n\tif(TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&arrayni)) )\n\t{\n\t\t// copy from array\n\t\tItems.clear();\n\n\t\tItems.assign(arrayni->Items.begin(), arrayni->Items.end());\n\t}\n\telse\n\t{\n\t\t// convert from dictionary or others\n\t\tItems.clear();\n\t\ttDictionaryEnumCallback callback;\n\t\tcallback.Items = &Items;\n        tTJSVariantClosure clo(&callback, NULL);\n\t\tdsp->EnumMembers(TJS_IGNOREPROP, &clo, dsp);\n\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSArrayNI::tDictionaryEnumCallback::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// called from tTJSCustomObject::EnumMembers\n\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t// hidden members are not processed\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER)\n\t{\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\n\t// push items\n\n\tItems->push_back(*param[0]);\n\tItems->push_back(*param[2]);\n\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::SaveStructuredData(std::vector<iTJSDispatch2 *> &stack,\n                                     iTJSTextWriteStream &stream, const ttstr &indentstr)\n{\n#ifdef TJS_TEXT_OUT_CRLF\n\tstream.Write(TJS_W(\"(const) [\\r\\n\"));\n#else\n\tstream>Write(TJS_W(\"(const) [\\n\"));\n#endif\n\n\tttstr indentstr2 = indentstr + TJS_W(\" \");\n\n\ttArrayItemIterator i;\n\ttjs_uint c = 0;\n\tfor(i = Items.begin(); i != Items.end(); i++)\n\t{\n\t\tstream.Write(indentstr2);\n\t\ttTJSVariantType type = i->Type();\n\t\tif(type == tvtObject)\n\t\t{\n\t\t\t// object\n\t\t\ttTJSVariantClosure clo = i->AsObjectClosureNoAddRef();\n\t\t\tSaveStructuredDataForObject(clo.SelectObjectNoAddRef(),\n\t\t\t\tstack, stream, indentstr2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstream.Write(TJSVariantToExpressionString(*i));\n\t\t}\n#ifdef TJS_TEXT_OUT_CRLF\n\t\tif(c != Items.size() -1) // unless last\n\t\t\tstream.Write(TJS_W(\",\\r\\n\"));\n\t\telse\n\t\t\tstream.Write(TJS_W(\"\\r\\n\"));\n#else\n\t\tif(c != Items.size() -1) // unless last\n\t\t\tstream.Write(TJS_W(\",\\n\"));\n\t\telse\n\t\t\tstream.Write(TJS_W(\"\\n\"));\n#endif\n\n\t\tc++;\n\t}\n\n\tstream.Write(indentstr);\n\tstream.Write(TJS_W(\"]\"));\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::SaveStructuredDataForObject(iTJSDispatch2 *dsp,\n\t\tstd::vector<iTJSDispatch2 *> &stack, iTJSTextWriteStream &stream,\n\t\tconst ttstr &indentstr)\n{\n\t// check object recursion\n\tstd::vector<iTJSDispatch2 *>::iterator i;\n\tfor(i = stack.begin(); i!=stack.end(); i++)\n\t{\n\t\tif(*i == dsp)\n\t\t{\n\t\t\t// object recursion detected\n                        stream.Write(TJS_W(\"null /* object recursion detected */\"));\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// determin dsp's object type\n\ttTJSDictionaryNI *dicni = NULL;\n\ttTJSArrayNI *arrayni = NULL;\n\tif(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&dicni)) )\n\t{\n\t\t// dictionary\n\t\tstack.push_back(dsp);\n\t\tdicni->SaveStructuredData(stack, stream, indentstr);\n\t\tstack.pop_back();\n\t}\n\telse if(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&arrayni)) )\n\t{\n\t\t// array\n\t\tstack.push_back(dsp);\n\t\tarrayni->SaveStructuredData(stack, stream, indentstr);\n\t\tstack.pop_back();\n\t}\n\telse if(dsp != NULL)\n\t{\n\t\t// other objects\n\t\tstream.Write(TJS_W(\"null /* (object) \\\"\")); // stored as a null\n\t\ttTJSVariant val(dsp,dsp);\n\t\tstream.Write(ttstr(val).EscapeC());\n\t\tstream.Write(TJS_W(\"\\\" */\"));\n\t}\n\telse\n\t{\n\t\t// null\n\t\tstream.Write(TJS_W(\"null\"));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::SaveStructuredBinary(std::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream )\n{\n\ttjs_uint count = (tjs_uint)Items.size();\n\ttTJSBinarySerializer::PutStartArray( &stream, count );\n\n\ttArrayItemIterator i;\n\tfor( i = Items.begin(); i != Items.end(); i++ ) {\n\t\ttTJSVariantType type = i->Type();\n\t\tif( type == tvtObject ){\n\t\t\t// object\n\t\t\ttTJSVariantClosure clo = i->AsObjectClosureNoAddRef();\n\t\t\tSaveStructuredBinaryForObject( clo.SelectObjectNoAddRef(), stack, stream );\n\t\t} else {\n\t\t\ttTJSBinarySerializer::PutVariant( &stream, *i );\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::SaveStructuredBinaryForObject(iTJSDispatch2 *dsp,\n\t\tstd::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream )\n{\n\t// check object recursion\n\tstd::vector<iTJSDispatch2 *>::iterator i;\n\tfor( i = stack.begin(); i != stack.end(); i++ ) {\n\t\tif( *i == dsp ) {\n\t\t\t// object recursion detected\n\t\t\ttTJSBinarySerializer::PutNull( &stream );\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// determin dsp's object type\n\ttTJSDictionaryNI *dicni = NULL;\n\ttTJSArrayNI *arrayni = NULL;\n\tif(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&dicni)) ) {\n\t\t// dictionary\n\t\tstack.push_back(dsp);\n\t\tdicni->SaveStructuredBinary( stack, stream );\n\t\tstack.pop_back();\n\t} else if(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&arrayni)) ) {\n\t\t// array\n\t\tstack.push_back(dsp);\n\t\tarrayni->SaveStructuredBinary( stack, stream );\n\t\tstack.pop_back();\n\t} else if(dsp != NULL) {\n\t\t// other objects\n\t\ttTJSBinarySerializer::PutNull( &stream );\n\t} else {\n\t\t// null\n\t\ttTJSBinarySerializer::PutNull( &stream );\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayNI::AssignStructure(iTJSDispatch2 * dsp,\n\tstd::vector<iTJSDispatch2 *> &stack)\n{\n\t// assign structured data from dsp\n\ttTJSArrayNI *arrayni = NULL;\n\tif(TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&arrayni)) )\n\t{\n\t\t// copy from array\n\t\tstack.push_back(dsp);\n\t\ttry\n\t\t{\n\t\t\tItems.clear();\n\n\t\t\ttArrayItemIterator i;\n\t\t\tfor(i = arrayni->Items.begin(); i != arrayni->Items.end(); i++)\n\t\t\t{\n\t\t\t\ttTJSVariantType type = i->Type();\n\t\t\t\tif(type == tvtObject)\n\t\t\t\t{\n\t\t\t\t\t// object\n\t\t\t\t\tiTJSDispatch2 *dsp = i->AsObjectNoAddRef();\n\t\t\t\t\t// determin dsp's object type\n\n\t\t\t\t\ttTJSDictionaryNI *dicni = NULL;\n\t\t\t\t\ttTJSArrayNI *arrayni = NULL;\n\n\t\t\t\t\tif(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&dicni)) )\n\t\t\t\t\t{\n\t\t\t\t\t\t// dictionary\n\t\t\t\t\t\tbool objrec = false;\n\t\t\t\t\t\tstd::vector<iTJSDispatch2 *>::iterator i;\n\t\t\t\t\t\tfor(i = stack.begin(); i!=stack.end(); i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(*i == dsp)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// object recursion detected\n\t\t\t\t\t\t\t\tobjrec = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(objrec)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tItems.push_back(tTJSVariant((iTJSDispatch2*)NULL)); // becomes null\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tiTJSDispatch2 * newobj = TJSCreateDictionaryObject();\n\t\t\t\t\t\t\tItems.push_back(tTJSVariant(newobj, newobj));\n\t\t\t\t\t\t\tnewobj->Release();\n\t\t\t\t\t\t\ttTJSDictionaryNI * newni = NULL;\n\t\t\t\t\t\t\tif(TJS_SUCCEEDED(newobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\t\t\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&newni)) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewni->AssignStructure(dsp, stack);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\t\tTJSGetArrayClassID(), (iTJSNativeInstance**)&arrayni)) )\n\t\t\t\t\t{\n\t\t\t\t\t\t// array\n\t\t\t\t\t\tbool objrec = false;\n\t\t\t\t\t\tstd::vector<iTJSDispatch2 *>::iterator i;\n\t\t\t\t\t\tfor(i = stack.begin(); i!=stack.end(); i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(*i == dsp)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// object recursion detected\n\t\t\t\t\t\t\t\tobjrec = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(objrec)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tItems.push_back(tTJSVariant((iTJSDispatch2*)NULL)); // becomes null\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tiTJSDispatch2 * newobj = TJSCreateArrayObject();\n\t\t\t\t\t\t\tItems.push_back(tTJSVariant(newobj, newobj));\n\t\t\t\t\t\t\tnewobj->Release();\n\t\t\t\t\t\t\ttTJSArrayNI * newni = NULL;\n\t\t\t\t\t\t\tif(TJS_SUCCEEDED(newobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\t\t\t\tTJSGetArrayClassID(), (iTJSNativeInstance**)&newni)) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewni->AssignStructure(dsp, stack);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// other object types\n\t\t\t\t\t\tItems.push_back(*i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// others\n\t\t\t\t\tItems.push_back(*i);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tstack.pop_back();\n\t\t\tthrow;\n\t\t}\n\t\tstack.pop_back();\n\t}\n\telse\n\t{\n\t\tTJS_eTJSError(TJSSpecifyDicOrArray);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSArrayObject\n//---------------------------------------------------------------------------\ntTJSArrayObject::tTJSArrayObject() : tTJSCustomObject(TJS_ARRAY_BASE_HASH_BITS)\n{\n\tCallFinalize = false;\n}\n//---------------------------------------------------------------------------\ntTJSArrayObject::~tTJSArrayObject()\n{\n}\n//---------------------------------------------------------------------------\n\n#define ARRAY_GET_NI \\\n\ttTJSArrayNI *ni; \\\n\tif(TJS_FAILED(objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \\\n\t\tClassID_Array, (iTJSNativeInstance**)&ni))) \\\n\t\t\treturn TJS_E_NATIVECLASSCRASH;\nstatic tTJSVariant VoidValue;\n#define ARRAY_GET_VAL \\\n\ttjs_int membercount = (tjs_int)(ni->Items.size()); \\\n\tif(num < 0) num = membercount + num; \\\n\tif((flag & TJS_MEMBERMUSTEXIST) && (num < 0 || membercount <= num)) \\\n\t\treturn TJS_E_MEMBERNOTFOUND; \\\n\ttTJSVariant val ( (membercount<=num || num < 0) ?VoidValue:ni->Items[num]);\n\t\t// Do not take reference of the element (because the element *might*\n\t\t// disappear in function call, property handler etc.) So here must be\n\t\t// an object copy, not reference.\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Finalize()\n{\n\ttTJSArrayNI *ni;\n\tif(TJS_FAILED(NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&ni)))\n\t\t\tTJS_eTJSError(TJSNativeClassCrash);\n\tClear(ni);\n\n\tinherited::Finalize();\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Clear(tTJSArrayNI * ni)\n{\n\t// clear members\n\n\tstd::vector<iTJSDispatch2*> vector;\n\ttry\n\t{\n\t\ttjs_uint i;\n\t\tfor(i=0; i<ni->Items.size(); i++)\n\t\t{\n\t\t\tif(ni->Items[i].Type() == tvtObject)\n\t\t\t{\n\t\t\t\tCheckObjectClosureRemove(ni->Items[i]);\n\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\tni->Items[i].AsObjectClosureNoAddRef();\n\t\t\t\tclo.AddRef();\n\t\t\t\tif(clo.Object) vector.push_back(clo.Object);\n\t\t\t\tif(clo.ObjThis) vector.push_back(clo.ObjThis);\n\t\t\t\tni->Items[i].Clear();\n\t\t\t}\n\t\t}\n\t\tni->Items.clear();\n\t}\n\tcatch(...)\n\t{\n\t\tstd::vector<iTJSDispatch2*>::iterator i;\n\t\tfor(i = vector.begin(); i != vector.end(); i++)\n\t\t{\n\t\t\t(*i)->Release();\n\t\t}\n\n\t\tthrow;\n\t}\n\n\t// release all objects\n\tstd::vector<iTJSDispatch2*>::iterator i;\n\tfor(i = vector.begin(); i != vector.end(); i++)\n\t{\n\t\t(*i)->Release();\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Add(tTJSArrayNI * ni, const tTJSVariant &val)\n{\n\tni->Items.push_back(val);\n\tCheckObjectClosureAdd(ni->Items[ni->Items.size() -1]);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSArrayObject::Remove(tTJSArrayNI * ni, const tTJSVariant &ref, bool removeall)\n{\n\ttjs_int count = 0;\n\tstd::vector<tjs_int> todelete;\n\ttjs_int num = 0;\n\tfor(tTJSArrayNI::tArrayItemIterator i = ni->Items.begin();\n\t\ti != ni->Items.end(); i++)\n\t{\n\t\tif(ref.DiscernCompare(*i))\n\t\t{\n\t\t\tcount ++;\n\t\t\ttodelete.push_back(num);\n\t\t\tif(!removeall) break;\n\t\t}\n\t\tnum++;\n\t}\n\n\tstd::vector<iTJSDispatch2*> vector;\n\ttry\n\t{\n\t\t// list objects up\n\t\tfor(std::vector<tjs_int>::iterator i = todelete.begin();\n\t\t\ti != todelete.end(); i++)\n\t\t{\n\t\t\tif(ni->Items[*i].Type() == tvtObject)\n\t\t\t{\n\t\t\t\tCheckObjectClosureRemove(ni->Items[*i]);\n\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\tni->Items[*i].AsObjectClosureNoAddRef();\n\t\t\t\tclo.AddRef();\n\t\t\t\tif(clo.Object) vector.push_back(clo.Object);\n\t\t\t\tif(clo.ObjThis) vector.push_back(clo.ObjThis);\n\t\t\t\tni->Items[*i].Clear();\n\t\t\t}\n\t\t}\n\n\t\t// remove items found\n\t\tfor(tjs_int i = (tjs_int)todelete.size() -1; i>=0; i--)\n\t\t{\n\t\t\tni->Items.erase(ni->Items.begin() + todelete[i]);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tstd::vector<iTJSDispatch2*>::iterator i;\n\t\tfor(i = vector.begin(); i != vector.end(); i++)\n\t\t{\n\t\t\t(*i)->Release();\n\t\t}\n\n\t\tthrow;\n\t}\n\n\t// release all objects\n\tstd::vector<iTJSDispatch2*>::iterator i;\n\tfor(i = vector.begin(); i != vector.end(); i++)\n\t{\n\t\t(*i)->Release();\n\t}\n\n\treturn count;\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Erase(tTJSArrayNI * ni, tjs_int num)\n{\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num < 0) TJS_eTJSError(TJSRangeError);\n\tif((unsigned)num >= ni->Items.size()) TJS_eTJSError(TJSRangeError);\n\n\tCheckObjectClosureRemove(ni->Items[num]);\n\tni->Items.erase(ni->Items.begin() + num);\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Insert(tTJSArrayNI *ni, const tTJSVariant &val, tjs_int num)\n{\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num < 0) TJS_eTJSError(TJSRangeError);\n\ttjs_int count = (tjs_int)ni->Items.size();\n\tif(num > count) TJS_eTJSError(TJSRangeError);\n\n\tni->Items.insert(ni->Items.begin() + num, val);\n\tCheckObjectClosureAdd(val);\n}\n//---------------------------------------------------------------------------\nvoid tTJSArrayObject::Insert(tTJSArrayNI *ni, tTJSVariant *const *val, tjs_int numvals, tjs_int num)\n{\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num < 0) TJS_eTJSError(TJSRangeError);\n\ttjs_int count = (tjs_int)ni->Items.size();\n\tif(num > count) TJS_eTJSError(TJSRangeError);\n\n\t// first initialize specified position as void, then\n\t// overwrite items.\n\tni->Items.insert(ni->Items.begin() + num, numvals, tTJSVariant());\n\tfor(tjs_int i = 0; i < numvals; i++)\n\t{\n\t\tni->Items[num + i] = *val[i];\n\t\tCheckObjectClosureAdd(*val[i]);\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn FuncCallByNum(flag, idx, result, numparams, param, objthis);\n\n\treturn inherited::FuncCall(flag, membername, hint, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::FuncCallByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultFuncCall(flag, val, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::PropGet(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32*hint, tTJSVariant *result, iTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn PropGetByNum(flag, idx, result, objthis);\n\treturn inherited::PropGet(flag, membername, hint, result, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::PropGetByNum(tjs_uint32 flag, tjs_int num,\n\t\ttTJSVariant *result, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultPropGet(flag, val, result, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::PropSet(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn PropSetByNum(flag, idx, param, objthis);\n\treturn inherited::PropSet(flag, membername, hint, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::PropSetByNum(tjs_uint32 flag, tjs_int num,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num >= (tjs_int)ni->Items.size())\n\t{\n\t\tif(flag & TJS_MEMBERMUSTEXIST) return TJS_E_MEMBERNOTFOUND;\n\t\tni->Items.resize(num+1);\n\t}\n\tif(num < 0) return TJS_E_MEMBERNOTFOUND;\n\ttTJSVariant &val = ni->Items[num];\n\ttjs_error hr;\n\tCheckObjectClosureRemove(val);\n\ttry\n\t{\n\t\thr = TJSDefaultPropSet(flag, val, param, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tCheckObjectClosureAdd(val);\n\t\tthrow;\n\t}\n\tCheckObjectClosureAdd(val);\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::PropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber((const tjs_char*)(*membername), idx))\n\t\treturn PropSetByNum(flag, idx, param, objthis);\n\treturn inherited::PropSetByVS(flag, membername, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::DeleteMember(tjs_uint32 flag, const tjs_char *membername,\n\ttjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn DeleteMemberByNum(flag, idx, objthis);\n\treturn inherited::DeleteMember(flag, membername, hint, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::DeleteMemberByNum(tjs_uint32 flag, tjs_int num,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num < 0 || (tjs_uint)num>=ni->Items.size()) return TJS_E_MEMBERNOTFOUND;\n\tCheckObjectClosureRemove(ni->Items[num]);\n\tstd::deque<tTJSVariant>::iterator i;\n\tni->Items.erase(ni->Items.begin() + num);\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::Invalidate(tjs_uint32 flag, const tjs_char *membername,\n\ttjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn InvalidateByNum(flag, idx, objthis);\n\treturn inherited::Invalidate(flag, membername, hint, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::InvalidateByNum(tjs_uint32 flag, tjs_int num,\n\t\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultInvalidate(flag, val, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::IsValid(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn IsValidByNum(flag, idx, objthis);\n\treturn inherited::IsValid(flag, membername, hint, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::IsValidByNum(tjs_uint32 flag, tjs_int num,\n\t\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultIsValid(flag, val, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::CreateNew(tjs_uint32 flag, const tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn CreateNewByNum(flag, idx, result, numparams, param, objthis);\n\treturn inherited::CreateNew(flag, membername, hint, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::CreateNewByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultCreateNew(flag, val, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::IsInstanceOf(tjs_uint32 flag,const  tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn IsInstanceOfByNum(flag, idx, classname, objthis);\n\treturn inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::IsInstanceOfByNum(tjs_uint32 flag, tjs_int num,\n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tARRAY_GET_VAL;\n\treturn TJSDefaultIsInstanceOf(flag, val, classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSArrayObject::Operation(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_int idx;\n\tif(membername && IsNumber(membername, idx))\n\t\treturn OperationByNum(flag, idx, result, param, objthis);\n\treturn inherited::Operation(flag, membername, hint, result, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD \n\ttTJSArrayObject::OperationByNum(tjs_uint32 flag, tjs_int num,\n\t\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tARRAY_GET_NI;\n\tif(num < 0) num += (tjs_int)ni->Items.size();\n\tif(num >= (tjs_int)ni->Items.size())\n\t{\n\t\tif(flag & TJS_MEMBERMUSTEXIST) return TJS_E_MEMBERNOTFOUND;\n\t\tni->Items.resize(num+1);\n\t}\n\tif(num < 0) return TJS_E_MEMBERNOTFOUND;\n\ttjs_error hr;\n\ttTJSVariant &val = ni->Items[num];\n\tCheckObjectClosureRemove(val);\n\ttry\n\t{\n\t\thr=TJSDefaultOperation(flag, val, result, param, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tCheckObjectClosureAdd(val);\n\t\tthrow;\n\t}\n\tCheckObjectClosureAdd(val);\n\treturn hr;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSGetArrayClassID\n//---------------------------------------------------------------------------\ntjs_int32 TJSGetArrayClassID()\n{\n\treturn ClassID_Array;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TJSCreateArrayObject\n//---------------------------------------------------------------------------\niTJSDispatch2 * TJSCreateArrayObject(iTJSDispatch2 **classout)\n{\n\t// create an Array object\n\tstruct tHolder\n\t{\n\t\tiTJSDispatch2 * Obj;\n\t\ttHolder() { Obj = new tTJSArrayClass(); }\n\t\t~tHolder() { Obj->Release(); }\n\t} static arrayclass;\n\n\tif(classout) *classout = arrayclass.Obj, arrayclass.Obj->AddRef();\n\n\ttTJSArrayObject *arrayobj;\n\t(arrayclass.Obj)->CreateNew(0, NULL, NULL, \n\t\t(iTJSDispatch2**)&arrayobj, 0, NULL, arrayclass.Obj);\n\treturn arrayobj;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Utility functions\n//---------------------------------------------------------------------------\ntjs_int TJSGetArrayElementCount(iTJSDispatch2 * dsp)\n{\n\t// returns array element count\n\ttTJSArrayNI *ni;\n\tif(TJS_FAILED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&ni)))\n\t\t\tTJS_eTJSError(TJSSpecifyArray);\n\treturn (tjs_int)ni->Items.size();\n}\n//---------------------------------------------------------------------------\ntjs_int TJSCopyArrayElementTo(iTJSDispatch2 * dsp,\n\ttTJSVariant *dest, tjs_uint start, tjs_int count)\n{\n\t// copy array elements to specified variant array.\n\t// returns copied element count.\n\ttTJSArrayNI *ni;\n\tif(TJS_FAILED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Array, (iTJSNativeInstance**)&ni)))\n\t\t\tTJS_eTJSError(TJSSpecifyArray);\n\n\tif(count < 0) count = (tjs_int)ni->Items.size();\n\n\tif(start >= ni->Items.size()) return 0;\n\n\ttjs_uint limit = start + count;\n\n\tfor(tjs_uint i = start; i < limit; i++)\n\t\t*(dest++) = ni->Items[i];\n\n\treturn limit - start;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n} // namespace TJS\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsArray.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Array class implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsArrayH\n#define tjsArrayH\n\n\n#include <deque>\n#include \"tjsNative.h\"\n\n\n// note: this TJS class cannot be inherited\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSStringAppender\n//---------------------------------------------------------------------------\nclass tTJSStringAppender\n{\n\t// fast operation for string concat\n\n\ttjs_char * Data;\n\ttjs_int DataLen;\n\ttjs_int DataCapacity; // in characters, not in bytes\n\npublic:\n\ttTJSStringAppender();\n\t~tTJSStringAppender();\n\n\ttjs_int GetLen() const { return DataLen; }\n\tconst tjs_char * GetData() const { return Data; }\n\tvoid Append(const tjs_char *string, tjs_int len);\n\n\tvoid operator += (const tjs_char * string)\n\t\t{ Append(string, (tjs_int)TJS_strlen(string)); }\n\n\tvoid operator += (const ttstr & string)\n\t\t{ Append(string.c_str(), string.GetLen()); }\n};\n//---------------------------------------------------------------------------\n// tTJSSaveStructuredDataCallback\n//---------------------------------------------------------------------------\nstruct tTJSSaveStructuredDataCallback\n{\n\tvirtual void SaveStructuredData(std::vector<iTJSDispatch2 *> &stack,\n                                        iTJSTextWriteStream &stream, const ttstr&indentstr) = 0;\n\n\tvirtual void SaveStructuredBinary(std::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream ) = 0;\n\n};\n//---------------------------------------------------------------------------\n// tTJSArrayClass : tTJSArray TJS class\n//---------------------------------------------------------------------------\nclass tTJSArrayClass : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSArrayClass();\n\t~tTJSArrayClass();\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\tiTJSDispatch2 *CreateBaseTJSObject();\n\nprivate:\n\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n};\n//---------------------------------------------------------------------------\n// tTJSArrayNI : TJS Array native C++ instance\n//---------------------------------------------------------------------------\nclass tTJSArrayNI : public tTJSNativeInstance,\n\t\t\t\t\tpublic tTJSSaveStructuredDataCallback\n{\n\ttypedef tTJSNativeInstance inherited;\npublic:\n\ttypedef std::vector<tTJSVariant>::iterator tArrayItemIterator;\n\tstd::vector<tTJSVariant> Items;\n\ttTJSArrayNI();\n\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **params,\n\t\tiTJSDispatch2 *tjsobj);\n\n\tvoid Assign(iTJSDispatch2 *dsp);\n\nprivate:\n\tstruct tDictionaryEnumCallback : public tTJSDispatch\n\t{\n\t\tstd::vector<tTJSVariant> * Items;\n\t\t\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t};\n\tfriend struct tDictionaryEnumCallback;\n\npublic:\n\tvoid SaveStructuredData(std::vector<iTJSDispatch2 *> &stack,\n\t\tiTJSTextWriteStream &stream, const ttstr&indentstr);\n\tvoid SaveStructuredBinary(std::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream );\n\t\t// method from tTJSSaveStructuredDataCallback\n\tstatic void SaveStructuredDataForObject(iTJSDispatch2 *dsp,\n\t\tstd::vector<iTJSDispatch2 *> &stack, iTJSTextWriteStream &stream, const ttstr&indentstr);\n\tstatic void SaveStructuredBinaryForObject(iTJSDispatch2 *dsp,\n\t\tstd::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream );\n\n\tvoid AssignStructure(iTJSDispatch2 * dsp, std::vector<iTJSDispatch2 *> &stack);\n//---------------------------------------------------------------------------\n};\n\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\nclass tTJSArrayObject : public tTJSCustomObject\n{\n\ttypedef tTJSCustomObject inherited;\n\n\tvoid CheckObjectClosureAdd(const tTJSVariant &val)\n\t{\n\t\t// member's object closure often points the container,\n\t\t// so we must adjust the reference counter to avoid\n\t\t// mutual reference lock.\n\t\tif(val.Type() == tvtObject)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = val.AsObjectClosureNoAddRef().ObjThis;\n\t\t\tif(dsp == (iTJSDispatch2*)this) this->Release();\n\t\t}\n\t}\n\n\tvoid CheckObjectClosureRemove(const tTJSVariant &val)\n\t{\n\t\tif(val.Type() == tvtObject)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = val.AsObjectClosureNoAddRef().ObjThis;\n\t\t\tif(dsp == (iTJSDispatch2*)this) this->AddRef();\n\t\t}\n\t}\n\n\n\npublic:\n\ttTJSArrayObject();\n\t~tTJSArrayObject();\n\nprotected:\n\tvoid Finalize(); // Finalize override\n\npublic:\n\tvoid Clear(tTJSArrayNI *ni);\n\n\tvoid Add(tTJSArrayNI *ni, const tTJSVariant &val);\n\ttjs_int Remove(tTJSArrayNI *ni, const tTJSVariant &ref, bool removeall);\n\tvoid Erase(tTJSArrayNI *ni, tjs_int num);\n\tvoid Insert(tTJSArrayNI *ni, const tTJSVariant &val, tjs_int num);\n\tvoid Insert(tTJSArrayNI *ni, tTJSVariant *const *val, tjs_int numvals, tjs_int num);\n\npublic:\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCallByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGetByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByNum(tjs_uint32 flag, tjs_int num, const tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis);\n\n/*\n\tGetCount\n\tGetCountByNum\n*/\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tEnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback, iTJSDispatch2 *objthis)\n\t{\n\t\treturn TJS_E_NOTIMPL; // currently not implemented\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMemberByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidateByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValidByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNewByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n/*\n\ttjs_error\n\tGetSuperClass(tjs_uint32 flag, iTJSDispatch2 **result, iTJSDispatch2 *objthis);\n*/\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOfByNum(tjs_uint32 flag, tjs_int num, const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperationByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis);\n/*\n\ttjs_error\n\tNativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid,\n\t\ttTJSNativeInstance **pointer);\n*/\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSGetArrayClassID\n//---------------------------------------------------------------------------\nextern tjs_int32 TJSGetArrayClassID();\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSCreateArrayObject\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TJSCreateArrayObject, (iTJSDispatch2 **classout = NULL));\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Utility functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_int, TJSGetArrayElementCount, (iTJSDispatch2 * dsp));\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_int, TJSCopyArrayElementTo, (iTJSDispatch2 * dsp, tTJSVariant *dest, tjs_uint start, tjs_int count));\n//---------------------------------------------------------------------------\n\n\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsBinarySerializer.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjs.h\"\n#include \"tjsBinarySerializer.h\"\n#include \"tjsDictionary.h\"\n#include \"tjsArray.h\"\n\nnamespace TJS\n{\n\nconst tjs_uint8 tTJSBinarySerializer::HEADER[tTJSBinarySerializer::HEADER_LENGTH] = {\n\t'K','B','A','D', '1','0','0', 0\n};\nbool tTJSBinarySerializer::IsBinary( const tjs_uint8 header[tTJSBinarySerializer::HEADER_LENGTH] ) {\n\treturn memcmp( HEADER, header, tTJSBinarySerializer::HEADER_LENGTH) == 0;\n}\n/**\n * oCAgli[\n */\nvoid tTJSBinarySerializer::PutVariant( tTJSBinaryStream* stream, tTJSVariant& v )\n{\n\ttTJSVariantType type = v.Type();\n\tswitch( type ) {\n\tcase tvtVoid: {\n\t\ttjs_uint8 tmp[1];\n\t\ttmp[0] = TYPE_VOID;\n\t\tstream->Write( tmp, sizeof(tmp) );\n\t\tbreak;\n\t}\n\tcase tvtObject:\n\t\tbreak;\n/*\n\t\t{\n\t\tiTJSDispatch2* obj = v.AsObjectNoAddRef();\n\t\tiTJSDispatch2* objthis = v.AsObjectThisNoAddRef();\n\t\tif( obj == NULL && objthis == NULL ) {\n\t\t\tPut( TYPE_NIL );\n\t\t} else {\n\t\t\tSaveStructured\n\t\t}\n\t\tbreak;\n\t}\n*/\n\tcase tvtString:\n\t\tPutString( stream, v.AsStringNoAddRef() );\n\t\tbreak;\n\tcase tvtOctet:\n\t\tPutOctet( stream, v.AsOctetNoAddRef() );\n\t\tbreak;\n\tcase tvtInteger:\n\t\tPutInteger( stream, v.AsInteger() );\n\t\tbreak;\n\tcase tvtReal:\n\t\tPutDouble( stream, v.AsReal() );\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\ntTJSBinarySerializer::tTJSBinarySerializer() : DicClass(NULL), RootDictionary(NULL), RootArray(NULL) {\n}\ntTJSBinarySerializer::tTJSBinarySerializer( class tTJSDictionaryObject* root ) : DicClass(NULL), RootDictionary(root), RootArray(NULL) {\n}\ntTJSBinarySerializer::tTJSBinarySerializer( class tTJSArrayObject* root ) : DicClass(NULL), RootDictionary(NULL), RootArray(root) {\n}\ntTJSBinarySerializer::~tTJSBinarySerializer() {\n\tif( DicClass ) DicClass->Release();\n\tDicClass = NULL;\n}\n\ntTJSDictionaryObject* tTJSBinarySerializer::CreateDictionary( tjs_uint count ) {\n\tif( RootDictionary ) {\n\t\ttTJSDictionaryObject* ret = RootDictionary;\n\t\tRootDictionary = NULL;\n\t\tret->RebuildHash( (tjs_int)count );\n\t\tret->AddRef();\n\t\treturn ret;\n\t}\n\tif( RootArray ) {\n\t\tTJSThrowFrom_tjs_error(TJS_E_INVALIDPARAM);\t// ^Ⴄ\n\t}\n\tif( DicClass == NULL ) {\n\t\tiTJSDispatch2* dsp = TJSCreateDictionaryObject(&DicClass);\n\t\tdsp->Release();\n\t}\n\ttTJSDictionaryObject* dic;\n\ttTJSVariant param[1] = { (tjs_int)count };\n\ttTJSVariant *pparam[1] = { param };\n\tDicClass->CreateNew( 0, NULL,  NULL, (iTJSDispatch2**)&dic, 1, pparam, DicClass );\n\treturn dic;\n}\ntTJSArrayObject* tTJSBinarySerializer::CreateArray( tjs_uint count ) {\n\tif( RootArray ) {\n\t\ttTJSArrayObject* ret = RootArray;\n\t\tRootArray = NULL;\n\t\tret->AddRef();\n\t\treturn ret;\n\t}\n\tif( RootDictionary ) {\n\t\tTJSThrowFrom_tjs_error(TJS_E_INVALIDPARAM);\t// ^Ⴄ\n\t}\n\ttTJSArrayObject* array = (tTJSArrayObject*)TJSCreateArrayObject();\n\treturn array;\n}\nvoid tTJSBinarySerializer::AddDictionary( tTJSDictionaryObject* dic, tTJSVariantString* name, tTJSVariant* value ) {\n\tif( name == NULL || value == NULL ) TJS_eTJSError( TJSReadError );\n\tdic->PropSetByVS( TJS_MEMBERENSURE, name, value, dic );\n}\nvoid tTJSBinarySerializer::InsertArray( tTJSArrayObject* array, tjs_uint index, tTJSVariant* value ) {\n\tif( value == NULL ) TJS_eTJSError( TJSReadError );\n\ttTJSArrayNI* ni = NULL;\n\ttjs_error hr = array->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJSGetArrayClassID(), (iTJSNativeInstance**)&ni );\n\tif( TJS_SUCCEEDED(hr) ) {\n\t\t// array->Insert( ni, *value, index );\n\t\tarray->Add( ni, *value );\n\t}\n}\ntTJSVariant* tTJSBinarySerializer::ReadBasicType( const tjs_uint8* buff, const tjs_uint size, tjs_uint& index ) {\n\tif( index > size ) return NULL;\n\ttjs_uint8 type = buff[index];\n\tindex++;\n\tswitch( type  ) {\n\tcase TYPE_NIL:\n\t\treturn new tTJSVariant((iTJSDispatch2*)NULL);\n\tcase TYPE_VOID:\n\t\treturn new tTJSVariant();\n\tcase TYPE_TRUE:\n\t\treturn new tTJSVariant((tjs_int)1);\n\tcase TYPE_FALSE:\n\t\treturn new tTJSVariant((tjs_int)0);\n\tcase TYPE_STRING8: {\n\t\tif( (index+sizeof(tjs_uint8)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint8 len = buff[index]; index++;\n\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\treturn ReadStringVarint( buff, len, index );\n\t}\n\tcase TYPE_STRING16: {\n\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint16 len = Read16( buff, index );\n\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\treturn ReadStringVarint( buff, len, index );\n\t}\n\tcase TYPE_STRING32: {\n\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint32 len = Read32( buff, index );\n\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\treturn ReadStringVarint( buff, len, index );\n\t}\n\tcase TYPE_FLOAT: {\n\t\t\tif( (index+sizeof(float)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint32 t = Read32( buff, index );\n\t\t\treturn new tTJSVariant(*(float*)&t);\n\t\t}\n\tcase TYPE_DOUBLE: {\n\t\t\tif( (index+sizeof(double)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint64 t = Read64( buff, index );\n\t\t\treturn new tTJSVariant(*(double*)&t);\n\t\t}\n\tcase TYPE_UINT8: {\n\t\t\tif( (index+sizeof(tjs_uint8)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint8 t = buff[index]; index++;\n\t\t\treturn new tTJSVariant( t );\n\t\t}\n\tcase TYPE_UINT16: {\n\t\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint16 t = Read16( buff, index );\n\t\t\treturn new tTJSVariant( t );\n\t\t}\n\tcase TYPE_UINT32: {\n\t\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint32 t = Read32( buff, index );\n\t\t\treturn new tTJSVariant( (tjs_int64)t );\n\t\t}\n\tcase TYPE_UINT64: {\n\t\t\tif( (index+sizeof(tjs_uint64)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint64 t = Read64( buff, index );\n\t\t\treturn new tTJSVariant( (tjs_int64)t );\n\t\t}\n\tcase TYPE_INT8: {\n\t\t\tif( (index+sizeof(tjs_uint8)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint8 t = buff[index]; index++;\n\t\t\treturn new tTJSVariant( (tjs_int8)t );\n\t\t}\n\tcase TYPE_INT16: {\n\t\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint16 t = Read16( buff, index );\n\t\t\treturn new tTJSVariant( (tjs_int16)t );\n\t\t}\n\tcase TYPE_INT32: {\n\t\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint32 t = Read32( buff, index );\n\t\t\treturn new tTJSVariant( (tjs_int32)t );\n\t\t}\n\tcase TYPE_INT64: {\n\t\t\tif( (index+sizeof(tjs_uint64)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint64 t = Read64( buff, index );\n\t\t\treturn new tTJSVariant( (tjs_int64)t );\n\t\t}\n\tcase TYPE_RAW16: {\n\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint16 len = Read16( buff, index );\n\t\tif( (index+len) > size ) TJS_eTJSError( TJSReadError );\n\t\treturn ReadOctetVarint( buff, len, index );\n\t}\n\tcase TYPE_RAW32: {\n\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint32 len = Read32( buff, index );\n\t\tif( (index+len) > size ) TJS_eTJSError( TJSReadError );\n\t\treturn ReadOctetVarint( buff, len, index );\n\t}\n\tcase TYPE_ARRAY16: {\n\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint16 count = Read16( buff, index );\n\t\treturn ReadArray( buff, size, count, index );\n\t}\n\tcase TYPE_ARRAY32: {\n\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint32 count = Read32( buff, index );\n\t\treturn ReadArray( buff, size, count, index );\n\t}\n\tcase TYPE_MAP16: {\n\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint16 count = Read16( buff, index );\n\t\treturn ReadDictionary( buff, size, count, index );\n\t}\n\tcase TYPE_MAP32: {\n\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\ttjs_uint32 count = Read32( buff, index );\n\t\treturn ReadDictionary( buff, size, count, index );\n\t}\n\tdefault: {\n\t\tif( type >= TYPE_POSITIVE_FIX_NUM_MIN && type <= TYPE_POSITIVE_FIX_NUM_MAX ) {\n\t\t\ttjs_int value = type;\n\t\t\treturn new tTJSVariant(value);\n\t\t} else if( type >= TYPE_NEGATIVE_FIX_NUM_MIN && type <= TYPE_NEGATIVE_FIX_NUM_MAX ) {\n\t\t\ttjs_int value = type;\n\t\t\treturn new tTJSVariant(value);\n\t\t} else if( type >= TYPE_FIX_RAW_MIN && type <= TYPE_FIX_RAW_MAX ) { // octet\n\t\t\ttjs_int len = type - TYPE_FIX_RAW_MIN;\n\t\t\tif( (len*sizeof(tjs_uint8)+index) > size ) TJS_eTJSError( TJSReadError );\n\t\t\treturn ReadOctetVarint( buff, len, index );\n\t\t} else if( type >= TYPE_FIX_STRING_MIN && type <= TYPE_FIX_STRING_MAX ) {\n\t\t\ttjs_int len = type - TYPE_FIX_STRING_MIN;\n\t\t\tif( (len*sizeof(tjs_char)+index) > size ) TJS_eTJSError( TJSReadError );\n\t\t\treturn ReadStringVarint( buff, len, index );\n\t\t} else if( type >= TYPE_FIX_ARRAY_MIN && type <= TYPE_FIX_ARRAY_MAX ) {\n\t\t\ttjs_int count = type - TYPE_FIX_ARRAY_MIN;\n\t\t\treturn ReadArray( buff, size, count, index );\n\t\t} else if( type >= TYPE_FIX_MAP_MIN && type <= TYPE_FIX_MAP_MAX ) {\n\t\t\ttjs_int count = type - TYPE_FIX_MAP_MIN;\n\t\t\treturn ReadDictionary( buff, size, count, index );\n\t\t} else {\n\t\t\tTJS_eTJSError( TJSReadError );\n\t\t\treturn NULL;\n\t\t}\n\t}\n\t}\n}\ntTJSVariant* tTJSBinarySerializer::ReadArray( const tjs_uint8* buff, const tjs_uint size, const tjs_uint count, tjs_uint& index ) {\n\tif( index > size ) return NULL;\n\n\ttTJSArrayObject* array = CreateArray( count );\n\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\ttTJSVariant* value = ReadBasicType( buff, size, index );\n\t\tInsertArray( array, i, value );\n\t\tdelete value;\n\t}\n\ttTJSVariant* ret = new tTJSVariant( array, array );\n\tarray->Release();\n\treturn ret;\n}\ntTJSVariant* tTJSBinarySerializer::ReadDictionary( const tjs_uint8* buff, const tjs_uint size, const tjs_uint count, tjs_uint& index ) {\n\tif( index > size ) return NULL;\n\n\ttTJSDictionaryObject* dic = CreateDictionary( count );\n\tfor( tjs_uint i = 0; i < count; i++ ) {\n\t\ttjs_uint8 type = buff[index];\n\t\tindex++;\n\t\t// ŏɕǂ\n\t\ttTJSVariantString* name = NULL;\n\t\tswitch( type ) {\n\t\tcase TYPE_STRING8: {\n\t\t\tif( (index+sizeof(tjs_uint8)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint8 len = buff[index]; index++;\n\t\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\t\tname = ReadString( buff, len, index );\n\t\t\tbreak;\n\t\t}\n\t\tcase TYPE_STRING16: {\n\t\t\tif( (index+sizeof(tjs_uint16)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint16 len = Read16( buff, index );\n\t\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\t\tname = ReadString( buff, len, index );\n\t\t\tbreak;\n\t\t}\n\t\tcase TYPE_STRING32: {\n\t\t\tif( (index+sizeof(tjs_uint32)) > size ) TJS_eTJSError( TJSReadError );\n\t\t\ttjs_uint32 len = Read32( buff, index );\n\t\t\tif( (index+(len*sizeof(tjs_char))) > size ) TJS_eTJSError( TJSReadError );\n\t\t\tname = ReadString( buff, len, index );\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tif( type >= TYPE_FIX_STRING_MIN && type <= TYPE_FIX_STRING_MAX ) {\n\t\t\t\ttjs_int len = type - TYPE_FIX_STRING_MIN;\n\t\t\t\tif( (len*sizeof(tjs_char)+index) > size ) TJS_eTJSError( TJSReadError );\n\t\t\t\tname = ReadString( buff, len, index );\n\t\t\t} else { // Dictionary`̏ꍇAŏɕ񂪂ȂƂȂ\n\t\t\t\t TJS_eTJSError( TJSReadError );\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// ɗvfǂ\n\t\ttTJSVariant* value = ReadBasicType( buff, size, index );\n\t\tAddDictionary( dic, name, value );\n\t\tdelete value;\n\t\tif( name ) name->Release();\n\t}\n\ttTJSVariant* ret = new tTJSVariant( dic, dic );\n\tdic->Release();\n\treturn ret;\n}\ntTJSVariant* tTJSBinarySerializer::Read( tTJSBinaryStream* stream )\n{\n\ttjs_uint64 pos = stream->GetPosition();\n\ttjs_uint size = (tjs_uint)( stream->GetSize() - pos );\n\ttjs_uint8* buffstart = new tjs_uint8[size];\n\tif( size != stream->Read( buffstart, size ) ) {\n\t\tTJS_eTJSError( TJSReadError );\n\t}\n\ttjs_uint index = 0;\n\ttTJSVariant* ret = ReadBasicType( buffstart, size, index );\n\tdelete[] buffstart;\n\treturn ret;\n}\n\n} // namespace\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsBinarySerializer.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n\n#ifndef tjsBinarySerializerH\n#define tjsBinarySerializerH\n\n#include \"tjsTypes.h\"\n#include \"tjsVariant.h\"\n#include \"tjsError.h\"\n#include \"tjsGlobalStringMap.h\"\n#include <vector>\n#include <limits.h>\n\nnamespace TJS\n{\n/**\n * oCi`Ńf[^Xg[o邽߂̃NX\n * `́AMessagePack ɋ߂̂ōוTJS2pɒĂ\n * ́AUTF-16̂܂܊i[\n * GfBA̓gGfBAɂȂĂ\n * wb_[ǉ\n */\nclass tTJSBinarySerializer {\npublic:\n\tenum {\n\t\tTYPE_POSITIVE_FIX_NUM_MIN = 0x00,\n\t\tTYPE_POSITIVE_FIX_NUM_MAX = 0x7F,\n\t\tTYPE_NEGATIVE_FIX_NUM_MIN = 0xE0,\n\t\tTYPE_NEGATIVE_FIX_NUM_MAX = 0xFF,\n\t\tTYPE_NIL = 0xC0,\n\t\tTYPE_VOID = 0xC1,\n\t\tTYPE_TRUE = 0xC2,\n\t\tTYPE_FALSE = 0xC3,\n\t\t\n\t\tTYPE_STRING8 = 0xC4,\n\t\tTYPE_STRING16 = 0xC5,\n\t\tTYPE_STRING32 = 0xC6,\n\n\t\tTYPE_FLOAT = 0xCA,\n\t\tTYPE_DOUBLE = 0xCB,\n\n\t\tTYPE_UINT8 = 0xCC,\n\t\tTYPE_UINT16 = 0xCD,\n\t\tTYPE_UINT32 = 0xCE,\n\t\tTYPE_UINT64 = 0xCF,\n\t\tTYPE_INT8 = 0xD0,\n\t\tTYPE_INT16 = 0xD1,\n\t\tTYPE_INT32 = 0xD2,\n\t\tTYPE_INT64 = 0xD3,\n\t\t\n\t\tTYPE_FIX_RAW_MIN = 0xD4,\n\t\tTYPE_FIX_RAW_MAX = 0xD9,\n\t\tTYPE_FIX_RAW_LEN = TYPE_FIX_RAW_MAX - TYPE_FIX_RAW_MIN, // 5byte܂łʏȂA̕px̂ŕRAWGA蓖Ă\n\n\t\tTYPE_RAW16 = 0xDA,\n\t\tTYPE_RAW32 = 0xDB,\n\t\tTYPE_ARRAY16 = 0xDC,\n\t\tTYPE_ARRAY32 = 0xDD,\n\t\tTYPE_MAP16 = 0xDE,\n\t\tTYPE_MAP32 = 0xDF,\n\n\t\tTYPE_FIX_STRING_MIN = 0xA0,\n\t\tTYPE_FIX_STRING_MAX = 0xBF,\n\t\tTYPE_FIX_STRING_LEN = TYPE_FIX_STRING_MAX - TYPE_FIX_STRING_MIN,\n\t\tTYPE_FIX_ARRAY_MIN = 0x90,\n\t\tTYPE_FIX_ARRAY_MAX = 0x9F,\n\t\tTYPE_FIX_ARRAY_LEN = TYPE_FIX_ARRAY_MAX - TYPE_FIX_ARRAY_MIN,\n\t\tTYPE_FIX_MAP_MIN = 0x80,\n\t\tTYPE_FIX_MAP_MAX = 0x8F,\n\t\tTYPE_FIX_MAP_LEN = TYPE_FIX_MAP_MAX - TYPE_FIX_MAP_MIN,\n\t};\n\tstatic const tjs_int HEADER_LENGTH = 8;\n\tstatic const tjs_uint8 HEADER[HEADER_LENGTH];\n\tstatic bool IsBinary( const tjs_uint8 header[HEADER_LENGTH] );\n\n\t/*\n\tstruct BinaryPack {\n\t\tstatic const tjs_int DATA_CAPACITY = 0x4000; // 16KB\n\n\t\ttjs_uint8* Data; // f[^\n\t\ttjs_int32 Size; // ݖ܂Ăʒu\n\t\ttjs_int32 Capacity; // f[^̍őTCY\n\n\t\tBinaryPack() : Size(0), Capacity(DATA_CAPACITY) {\n\t\t\tData = new tjs_uint8[DATA_CAPACITY];\n\t\t}\n\t\t~BinaryPack() {\n\t\t\tdelete[] Data;\n\t\t}\n\t\tinline bool Put( tjs_uint8 b ) {\n\t\t\tif( Size < Capacity ) {\n\t\t\t\tData[Size] = b;\n\t\t\t\tSize++;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t};\n\tstd::vector<BinaryPack*> OutputData;\n\ttjs_int32 OutputIndex;\n\n\tinline void Put( tjs_uint8 b ) {\n\t\tif( OutputData[OutputIndex].Put( b ) == false ) {\n\t\t\tOutputData.push_back( new BinaryPack() );\n\t\t\tOuputIndex++;\n\t\t\tOutputData[OutputIndex].Put( b );\n\t\t}\n\t}\n\t*/\n\n\tstatic inline void PutInteger( tTJSBinaryStream* stream, tjs_int64 b ) {\n\t\tif( b < 0 ) {\n\t\t\tif( b >= TYPE_NEGATIVE_FIX_NUM_MIN ) {\n\t\t\t\ttjs_uint8 tmp[1];\n\t\t\t\ttmp[0] = (tjs_uint8)b;\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b >= SCHAR_MIN ) {\n\t\t\t\ttjs_uint8 tmp[2];\n\t\t\t\ttmp[0] = TYPE_INT8;\n\t\t\t\ttmp[1] = (tjs_uint8)b;\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b >= SHRT_MIN ) {\n\t\t\t\ttjs_int16 v = (tjs_int16)b;\n\t\t\t\ttjs_uint8 tmp[3];\n\t\t\t\ttmp[0] = TYPE_INT16;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b >= LONG_MIN ) {\n\t\t\t\ttjs_int32 v = (tjs_int32)b;\n\t\t\t\ttjs_uint8 tmp[5];\n\t\t\t\ttmp[0] = TYPE_INT32;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\ttmp[3] = (tjs_uint8)( (v>>16)&0xff );\n\t\t\t\ttmp[4] = (tjs_uint8)( (v>>24)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else {\n\t\t\t\ttjs_int64 v = b;\n\t\t\t\ttjs_uint8 tmp[9];\n\t\t\t\ttmp[0] = TYPE_INT64;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\ttmp[3] = (tjs_uint8)( (v>>16)&0xff );\n\t\t\t\ttmp[4] = (tjs_uint8)( (v>>24)&0xff );\n\t\t\t\ttmp[5] = (tjs_uint8)( (v>>32)&0xff );\n\t\t\t\ttmp[6] = (tjs_uint8)( (v>>40)&0xff );\n\t\t\t\ttmp[7] = (tjs_uint8)( (v>>48)&0xff );\n\t\t\t\ttmp[8] = (tjs_uint8)( (v>>56)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t}\n\t\t} else {\n\t\t\tif( b <= TYPE_POSITIVE_FIX_NUM_MAX ) {\n\t\t\t\ttjs_uint8 tmp[1];\n\t\t\t\ttmp[0] = (tjs_uint8)( b );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b <= UCHAR_MAX ) {\n\t\t\t\ttjs_uint8 tmp[2];\n\t\t\t\ttmp[0] = TYPE_UINT8;\n\t\t\t\ttmp[1] = (tjs_uint8)( b );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b <= USHRT_MAX ) {\n\t\t\t\ttjs_uint16 v = (tjs_uint16)b;\n\t\t\t\ttjs_uint8 tmp[3];\n\t\t\t\ttmp[0] = TYPE_UINT16;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else if( b <= UINT_MAX ) {\n\t\t\t\ttjs_uint32 v = (tjs_uint32)b;\n\t\t\t\ttjs_uint8 tmp[5];\n\t\t\t\ttmp[0] = TYPE_UINT32;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\ttmp[3] = (tjs_uint8)( (v>>16)&0xff );\n\t\t\t\ttmp[4] = (tjs_uint8)( (v>>24)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t} else {\n\t\t\t\ttjs_uint64 v = b;\n\t\t\t\ttjs_uint8 tmp[9];\n\t\t\t\ttmp[0] = TYPE_UINT64;\n\t\t\t\ttmp[1] = (tjs_uint8)( v&0xff );\n\t\t\t\ttmp[2] = (tjs_uint8)( (v>>8)&0xff );\n\t\t\t\ttmp[3] = (tjs_uint8)( (v>>16)&0xff );\n\t\t\t\ttmp[4] = (tjs_uint8)( (v>>24)&0xff );\n\t\t\t\ttmp[5] = (tjs_uint8)( (v>>32)&0xff );\n\t\t\t\ttmp[6] = (tjs_uint8)( (v>>40)&0xff );\n\t\t\t\ttmp[7] = (tjs_uint8)( (v>>48)&0xff );\n\t\t\t\ttmp[8] = (tjs_uint8)( (v>>56)&0xff );\n\t\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t\t}\n\t\t}\n\t}\n\tstatic inline void PutString( tTJSBinaryStream* stream, const tjs_char* val, tjs_uint len ) {\n\t\tif( len <= TYPE_FIX_STRING_LEN ) {\n\t\t\ttjs_uint8 tmp[1];\n\t\t\ttmp[0] = TYPE_FIX_STRING_MIN+len;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( len <= UCHAR_MAX ) {\n\t\t\ttjs_uint8 tmp[2];\n\t\t\ttmp[0] = TYPE_STRING8;\n\t\t\ttmp[1] = len;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( len <= USHRT_MAX ) {\n\t\t\ttjs_uint16 v = len;\n\t\t\ttjs_uint8 tmp[3];\n\t\t\ttmp[0] = TYPE_STRING16;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( len <= ULONG_MAX ) {\n\t\t\ttjs_uint32 v = len;\n\t\t\ttjs_uint8 tmp[5];\n\t\t\ttmp[0] = TYPE_STRING32;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\ttmp[3] = (v>>16)&0xff;\n\t\t\ttmp[4] = (v>>24)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else {\n\t\t\tTJS_eTJSError(TJSWriteError);\n\t\t}\n#if TJS_HOST_IS_LITTLE_ENDIAN\n\t\tif( len ) {\n\t\t\tstream->Write( val, sizeof(tjs_char)*len );\n\t\t}\n#else\n\t\tif( len ) {\n\t\t\tstd::vector<tjs_uint8> tmp;\n\t\t\ttmp.reserve( sizeof(tjs_char)*len );\n\t\t\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\t\t\ttjs_char c = val[i];\n\t\t\t\ttmp.push_back( c&0xff );\n\t\t\t\ttmp.push_back( (c>>8)&0xff );\n\t\t\t}\n\t\t\tstream->Write( &(tmp[0]), sizeof(tjs_char)*len );\n\t\t}\n#endif\n\t}\n\t/**\n\t * _li[\n\t */\n\tstatic inline void PutDouble( tTJSBinaryStream* stream, double b ) {\n\t\ttjs_uint64 v = *(tjs_uint64*)&b;\n\t\ttjs_uint8 tmp[9];\n\t\ttmp[0] = TYPE_DOUBLE;\n\t\ttmp[1] = v&0xff;\n\t\ttmp[2] = (v>>8)&0xff;\n\t\ttmp[3] = (v>>16)&0xff;\n\t\ttmp[4] = (v>>24)&0xff;\n\t\ttmp[5] = (v>>32)&0xff;\n\t\ttmp[6] = (v>>40)&0xff;\n\t\ttmp[7] = (v>>48)&0xff;\n\t\ttmp[8] = (v>>56)&0xff;\n\t\tstream->Write( tmp, sizeof(tmp) );\n\t}\n\tstatic inline void PutBytes( tTJSBinaryStream* stream, const tjs_uint8* val, tjs_uint len ) {\n\t\tif( len <= TYPE_FIX_RAW_LEN ) {\n\t\t\ttjs_uint8 tmp[1];\n\t\t\ttmp[0] = TYPE_FIX_RAW_MIN + len;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( len <= USHRT_MAX ) {\n\t\t\ttjs_uint16 v = len;\n\t\t\ttjs_uint8 tmp[3];\n\t\t\ttmp[0] = TYPE_RAW16;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( len <= ULONG_MAX ) {\n\t\t\ttjs_uint32 v = len;\n\t\t\ttjs_uint8 tmp[5];\n\t\t\ttmp[0] = TYPE_RAW32;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\ttmp[3] = (v>>16)&0xff;\n\t\t\ttmp[4] = (v>>24)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else {\n\t\t\tTJS_eTJSError(TJSWriteError);\n\t\t}\n\t\tstream->Write( val, len );\n\t}\n\t/**\n\t * INebg^̒li[\n\t */\n\tstatic inline void PutOctet( tTJSBinaryStream* stream, tTJSVariantOctet* val ) {\n\t\ttjs_uint len = 0;\n\t\tconst tjs_uint8* data = NULL;\n\t\tif( val ) {\n\t\t\tlen = val->GetLength();\n\t\t\tdata =  val->GetData();\n\t\t}\n\t\tPutBytes( stream, data, len );\n\t}\n\n\t/**\n\t * i[\n\t */\n\tstatic inline void PutString( tTJSBinaryStream* stream, const tTJSVariantString* val ) {\n\t\tconst tjs_char* data = NULL;\n\t\ttjs_int len = 0;\n\t\tif( val ) {\n\t\t\tlen = val->GetLength();\n\t\t\tif( val->LongString ) {\n\t\t\t\tdata = val->LongString;\n\t\t\t} else {\n\t\t\t\tdata = val->ShortString;\n\t\t\t}\n\t\t}\n\t\tPutString( stream, data, len );\n\t}\n\tstatic inline void PutStartMap( tTJSBinaryStream* stream, tjs_uint count ) {\n\t\tif( count <= TYPE_FIX_MAP_LEN ) {\n\t\t\ttjs_uint8 tmp[1];\n\t\t\ttmp[0] = TYPE_FIX_MAP_MIN + count;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( count <= USHRT_MAX ) {\n\t\t\ttjs_uint16 v = count;\n\t\t\ttjs_uint8 tmp[3];\n\t\t\ttmp[0] = TYPE_MAP16;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( count <= ULONG_MAX ) {\n\t\t\ttjs_uint32 v = count;\n\t\t\ttjs_uint8 tmp[5];\n\t\t\ttmp[0] = TYPE_MAP32;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\ttmp[3] = (v>>16)&0xff;\n\t\t\ttmp[4] = (v>>24)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else {\n\t\t\tTJS_eTJSError(TJSWriteError);\n\t\t}\n\t}\n\tstatic inline void PutStartArray( tTJSBinaryStream* stream, tjs_uint count ) {\n\t\tif( count <= TYPE_FIX_ARRAY_LEN ) {\n\t\t\ttjs_uint8 tmp[1];\n\t\t\ttmp[0] = TYPE_FIX_ARRAY_MIN + count;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( count <= USHRT_MAX ) {\n\t\t\ttjs_uint16 v = count;\n\t\t\ttjs_uint8 tmp[3];\n\t\t\ttmp[0] = TYPE_ARRAY16;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else if( count <= ULONG_MAX ) {\n\t\t\ttjs_uint32 v = count;\n\t\t\ttjs_uint8 tmp[5];\n\t\t\ttmp[0] = TYPE_ARRAY32;\n\t\t\ttmp[1] = v&0xff;\n\t\t\ttmp[2] = (v>>8)&0xff;\n\t\t\ttmp[3] = (v>>16)&0xff;\n\t\t\ttmp[4] = (v>>24)&0xff;\n\t\t\tstream->Write( tmp, sizeof(tmp) );\n\t\t} else {\n\t\t\tTJS_eTJSError(TJSWriteError);\n\t\t}\n\t}\n\tstatic inline void PutNull( tTJSBinaryStream* stream ) {\n\t\ttjs_uint8 tmp[1];\n\t\ttmp[0] = TYPE_NIL;\n\t\tstream->Write( tmp, sizeof(tmp) );\n\t}\n\n\t\n\tstatic inline tjs_uint16 Read16( const tjs_uint8* buff, tjs_uint& index ) {\n\t\ttjs_uint16 ret = buff[index] | (buff[index+1]<<8);\n\t\tindex+=sizeof(tjs_uint16);\n\t\treturn ret;\n\t}\n\tstatic inline tjs_uint32 Read32( const tjs_uint8* buff, tjs_uint& index ) {\n\t\ttjs_uint32 ret = buff[index] | (buff[index+1]<<8) | (buff[index+2]<<16) | (buff[index+3]<<24);\n\t\tindex+=sizeof(tjs_uint32);\n\t\treturn ret;\n\t}\n\tstatic inline tjs_uint64 Read64( const tjs_uint8* buff, tjs_uint& index ) {\n\t\ttjs_uint64 ret = (tjs_uint64)buff[index] | ((tjs_uint64)buff[index+1]<<8) |\n\t\t\t((tjs_uint64)buff[index+2]<<16) | ((tjs_uint64)buff[index+3]<<24) |\n\t\t\t((tjs_uint64)buff[index+4]<<32) | ((tjs_uint64)buff[index+5]<<40) |\n\t\t\t((tjs_uint64)buff[index+6]<<48) | ((tjs_uint64)buff[index+7]<<56);\n\t\tindex+=sizeof(tjs_uint64);\n\t\treturn ret;\n\t}\n\tstatic inline tjs_char* ReadChars( const tjs_uint8* buff, tjs_uint len, tjs_uint& index ) {\n\t\tif( len > 0 ) {\n\t\t\ttjs_char* str = new tjs_char[len];\n\t\t\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\t\t\tstr[i] = buff[index];\n\t\t\t\tindex++;\n\t\t\t\tstr[i] |= buff[index] << 8;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treturn str;\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\tstatic inline tTJSVariantString* ReadString( const tjs_uint8* buff, tjs_uint len, tjs_uint& index ) {\n\t\ttTJSVariantString* ret = NULL;\n\t\tif( len > 0 ) {\n\t\t\ttjs_char* str = new tjs_char[len];\n\t\t\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\t\t\tstr[i] = buff[index];\n\t\t\t\tindex++;\n\t\t\t\tstr[i] |= buff[index] << 8;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tret = TJSAllocVariantString( str, len );\n\t\t\tdelete []str;\n\t\t}\n\t\treturn ret;\n\t}\n\tstatic inline tTJSVariant* ReadStringVarint( const tjs_uint8* buff, tjs_uint len, tjs_uint& index ) {\n\t\ttTJSVariantString* ret = ReadString( buff, len, index );\n\t\tif( !ret ) {\n\t\t\ttTJSVariant* var = new tTJSVariant(TJSMapGlobalStringMap(ttstr()));\n\t\t\treturn var;\n\t\t} else {\n\t\t\tttstr str(ret);\n\t\t\ttTJSVariant* var = new tTJSVariant(TJSMapGlobalStringMap(str));\n\t\t\tret->Release();\n\t\t\treturn var;\n\t\t}\n\t}\n\tstatic inline tTJSVariant* ReadOctetVarint( const tjs_uint8* buff, tjs_uint len, tjs_uint& index ) {\n\t\ttTJSVariantOctet* oct = TJSAllocVariantOctet( &buff[index], len );\n\t\tindex+=len;\n\t\ttTJSVariant* var = new tTJSVariant();\n\t\t*var = oct;\n\t\toct->Release();\n\t\treturn var;\n\t}\n\n\t/**\n\t * oCAgli[\n\t * IuWFNg^͖Ă\n\t */\n\tstatic void PutVariant( tTJSBinaryStream* stream, tTJSVariant& v );\n\t\n\ttTJSBinarySerializer();\n\ttTJSBinarySerializer( class tTJSDictionaryObject* root );\n\ttTJSBinarySerializer( class tTJSArrayObject* root );\n\t~tTJSBinarySerializer();\n\ttTJSVariant* Read( tTJSBinaryStream* stream );\n\nprivate:\n\tiTJSDispatch2* DicClass;\n\tclass tTJSDictionaryObject* RootDictionary;\n\tclass tTJSArrayObject* RootArray;\n\n\tclass tTJSDictionaryObject* CreateDictionary( tjs_uint count );\n\tclass tTJSArrayObject* CreateArray( tjs_uint count );\n\tvoid AddDictionary( class tTJSDictionaryObject* dic, tTJSVariantString* name, tTJSVariant* value );\n\tvoid InsertArray( class tTJSArrayObject* array, tjs_uint index, tTJSVariant* value );\n\ttTJSVariant* ReadBasicType( const tjs_uint8* buff, const tjs_uint size, tjs_uint& index );\n\ttTJSVariant* ReadArray( const tjs_uint8* buff, const tjs_uint size, const tjs_uint count, tjs_uint& index );\n\ttTJSVariant* ReadDictionary( const tjs_uint8* buff, const tjs_uint size, const tjs_uint count, tjs_uint& index );\n};\n\n} // namespace\n#endif // tjsBinarySerializerH\n\n"
  },
  {
    "path": "src/core/tjs2/tjsByteCodeLoader.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjs.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsByteCodeLoader.h\"\n#include \"tjsGlobalStringMap.h\"\n\nnamespace TJS\n{\n\nbool tTJSByteCodeLoader::IsTJS2ByteCode( const tjs_uint8* buff )\n{\n\t// TJS2\n\tint tag = read4byte( buff );\n\tif( tag != FILE_TAG_LE ) return false;\n\t// 100'\\0'\n\tint ver = read4byte( &(buff[4]) );\n\tif( ver != VER_TAG_LE ) return false;\n\treturn true;\n}\ntTJSScriptBlock* tTJSByteCodeLoader::ReadByteCode( tTJS* owner, const tjs_char* name, const tjs_uint8* buf, size_t size ) {\n\tReadBuffer = buf;\n\tReadIndex = 0;\n\tReadSize = (tjs_uint32)size;\n\n\tconst tjs_uint8* databuff = ReadBuffer;\n\n\t// TJS2\n\tint tag = read4byte( databuff );\n\tif( tag != FILE_TAG_LE ) return NULL;\n\t// 100'\\0'\n\tint ver = read4byte( &(databuff[4]) );\n\tif( ver != VER_TAG_LE ) return NULL;\n\n\tint filesize = read4byte( &(databuff[8]) );\n\tif( filesize != size ) return NULL;\n\n\t//// DATA\n\ttag = read4byte( &(databuff[12]) );\n\tif( tag != DATA_TAG_LE ) return NULL;\n\tsize = read4byte( &(databuff[16]) );\n\tReadDataArea( databuff, 20, size );\n\n\tint offset = (int)(12 + size); // ꂪf[^GÄʒu\n\t// OBJS\n\ttag = read4byte( &(databuff[offset]) );\n\toffset+=4;\n\tif( tag != OBJ_TAG_LE ) return NULL;\n\t//int objsize = ibuff.get();\n\tint objsize = read4byte( &(databuff[offset]) );\n\toffset+=4;\n\ttTJSScriptBlock* block = new tTJSScriptBlock(owner, name, 0 );\n\tReadObjects( block, databuff, offset, objsize );\n\treturn block;\n}\n\nvoid tTJSByteCodeLoader::ReadDataArea( const tjs_uint8* buff, int offset, size_t size ) {\n\tint count = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\n\t\tByteArray.set( (tjs_int8*)&buff[offset], count );\n\t\tint stride = ( count + 3 ) >> 2;\n\t\toffset += stride << 2;\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\t// load short\n\t\tShortArray.clear();\n\t\tShortArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tShortArray.push_back( read2byte( &(buff[offset]) ) );\n\t\t\toffset += 2;\n\t\t}\n\t\toffset += (count & 1) << 1;\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\n\t\tLongArray.clear();\n\t\tLongArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tLongArray.push_back( read4byte( &(buff[offset]) ) );\n\t\t\toffset += 4;\n\t\t}\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\t// load long\n\t\tLongLongArray.clear();\n\t\tLongLongArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tLongLongArray.push_back( read8byte( &(buff[offset]) ) );\n\t\t\toffset += 8;\n\t\t}\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\t// load double\n\t\tDoubleArray.clear();\n\t\tDoubleArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\ttjs_uint64 tmp = read8byte( &(buff[offset]) );\n\t\t\tDoubleArray.push_back( *(double*)&tmp );\n\t\t\toffset += 8;\n\t\t}\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\n\t\tStringArray.clear();\n\t\tStringArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tint len = read4byte( &(buff[offset]) );\n\t\t\toffset += 4;\n\t\t\tstd::vector<tjs_uint16> ch(len+1);\n\t\t\tch[len] = 0;\n\t\t\tfor( int j = 0; j < len; j++ ) {\n\t\t\t\tch[j] = read2byte( &(buff[offset]) );\n\t\t\t\toffset += 2;\n\t\t\t}\n\t\t\tStringArray.push_back( TJSMapGlobalStringMap( (const tjs_char *)&(ch[0]) ) );\n\t\t\toffset += (len & 1) << 1;\n\t\t}\n\t}\n\tcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tif( count > 0 ) {\n\t\tOctetArray.clear();\n\t\tOctetArray.reserve( count );\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tint len = read4byte( &(buff[offset]) );\n\t\t\toffset += 4;\n\t\t\ttTJSVariantOctet* octet = new tTJSVariantOctet( &(buff[offset]), len ); // f[^̓Rs[\n\t\t\tOctetArray.push_back( octet );\n\t\t\toffset += (( len + 3 ) >> 2) << 2;\n\t\t}\n\t}\n}\n\nvoid tTJSByteCodeLoader::ReadObjects( tTJSScriptBlock* block, const tjs_uint8* buff, int offset, int size ) {\n\tint toplevel = read4byte( &(buff[offset]) );\n\toffset += 4;\n\tint objcount = read4byte( &(buff[offset]) );\n\toffset += 4;\n\n\t//tTJSInterCodeContext** objs = new tTJSInterCodeContext*[objcount];\n\tstd::vector<tTJSInterCodeContext*> objs(objcount);\n\tstd::vector<VariantRepalace> work;\n\tstd::vector<int> parent(objcount);\n\tstd::vector<int> propSetter(objcount);\n\tstd::vector<int> propGetter(objcount);\n\tstd::vector<int> superClassGetter(objcount);\n\tstd::vector<std::vector<int> > properties(objcount);\n\tfor( int o = 0; o < objcount; o++ ) {\n\t\tint tag = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tif( tag != FILE_TAG_LE ) {\n\t\t\t//throw new TJSException(Error.ByteCodeBroken);\n\t\t\tTJS_eTJSScriptError( TJSByteCodeBroken, block, 0 );\n\t\t}\n\t\t//int objsize = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tparent[o]  = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint name  = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint contextType = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint maxVariableCount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint variableReserveCount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint maxFrameCount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint funcDeclArgCount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint funcDeclUnnamedArgArrayBase = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint funcDeclCollapseBase = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tpropSetter[o] = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tpropGetter[o] = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tsuperClassGetter[o] = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\n\t\tint count = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\n\t\t// fobOp̃\\[Xʒuǂݍ\n\t\ttTJSInterCodeContext::tSourcePos* srcPos = NULL;\n\t\ttjs_int srcPosArraySize = 0;\n\t\tif( count > 0 ) {\n\t\t\tsrcPos = new tTJSInterCodeContext::tSourcePos[count];\n\t\t\tsrcPosArraySize = count;\n\t\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\t\tsrcPos[i].CodePos = read4byte( &(buff[offset]) );\n\t\t\t\toffset += 4;\n\t\t\t}\n\t\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\t\tsrcPos[i].SourcePos = read4byte( &(buff[offset]) );\n\t\t\t\toffset += 4;\n\t\t\t}\n\t\t} else {\n\t\t\toffset += count << 3;\n\t\t}\n\n\t\tcount = read4byte( &(buff[offset]) );\n\t\tconst tjs_int codeSize = count;\n\t\toffset += 4;\n\t\ttjs_int32* code = (tjs_int32*)TJS_malloc(count * sizeof(tjs_int32));\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\ttjs_int16 c = (tjs_int16)read2byte( &(buff[offset]) );\n\t\t\tcode[i] = c;\n\t\t\toffset += 2;\n\t\t}\n\t\tTranslateCodeAddress( block, code, codeSize );\n\t\toffset += (count & 1) << 1;\n\n\t\tcount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tint vcount = count<<1;\n\t\tstd::vector<short> data(vcount);\n\t\tfor( int i = 0; i < vcount; i++ ) {\n\t\t\tdata[i] = read2byte( &(buff[offset]) );\n\t\t\toffset += 2;\n\t\t}\n\n\t\ttTJSVariant* vdata = new tTJSVariant[count];\n\t\tconst tjs_int datacount = count;\n\t\tfor( int i = 0; i < datacount; i++ ) {\n\t\t\tint pos = i << 1;\n\t\t\tint type = data[pos];\n\t\t\tint index = data[pos+1];\n\t\t\tswitch( type ) {\n\t\t\tcase TYPE_VOID:\n\t\t\t\tvdata[i].Clear();\n\t\t\t\tbreak;\n\t\t\tcase TYPE_OBJECT:\n\t\t\t\tvdata[i] = (iTJSDispatch2*)NULL;\n\t\t\t\tbreak;\n\t\t\tcase TYPE_INTER_OBJECT:\n\t\t\t\twork.push_back( VariantRepalace( &(vdata[i]), index ) );\n\t\t\t\tbreak;\n\t\t\tcase TYPE_INTER_GENERATOR:\n\t\t\t\twork.push_back( VariantRepalace( &(vdata[i]), index ) );\n\t\t\t\tbreak;\n\t\t\tcase TYPE_STRING:\n\t\t\t\tvdata[i] = StringArray[index].c_str(); // tTJSString\n\t\t\t\tbreak;\n\t\t\tcase TYPE_OCTET:\n\t\t\t\tvdata[i] = OctetArray[index]; // tTJSVariantOctet\n\t\t\t\tbreak;\n\t\t\tcase TYPE_REAL:\n\t\t\t\tvdata[i] = (tjs_real)DoubleArray[index];\n\t\t\t\tbreak;\n\t\t\tcase TYPE_BYTE:\n\t\t\t\tvdata[i] = (tjs_int)ByteArray[index];\n\t\t\t\tbreak;\n\t\t\tcase TYPE_SHORT:\n\t\t\t\tvdata[i] = (tjs_int)ShortArray[index];\n\t\t\t\tbreak;\n\t\t\tcase TYPE_INTEGER:\n\t\t\t\tvdata[i] = (tjs_int)LongArray[index];\n\t\t\t\tbreak;\n\t\t\tcase TYPE_LONG:\n\t\t\t\tvdata[i] = (tjs_int64)LongLongArray[index];\n\t\t\t\tbreak;\n\t\t\tcase TYPE_UNKNOWN:\n\t\t\tdefault:\n\t\t\t\tvdata[i].Clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\t//int* scgetterps = new int[count];\n\t\tstd::vector<tjs_int> scgetterps(count);\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tscgetterps[i] = read4byte( &(buff[offset]) );\n\t\t\toffset += 4;\n\t\t}\n\t\t// properties\n\t\tcount = read4byte( &(buff[offset]) );\n\t\toffset += 4;\n\t\tif( count > 0 ) {\n\t\t\tint pcount = count << 1;\n\t\t\tstd::vector<int>& props = properties[o];\n\t\t\tprops.resize(pcount);\n\t\t\tfor( int i = 0; i < pcount; i++ ) {\n\t\t\t\tprops[i] = read4byte( &(buff[offset]) );\n\t\t\t\toffset += 4;\n\t\t\t}\n\t\t}\n\n\t\ttTJSInterCodeContext* obj = new tTJSInterCodeContext( block, StringArray[name].c_str(), (tTJSContextType)contextType,\n\t\t\tcode, codeSize, vdata, datacount, maxVariableCount, variableReserveCount, maxFrameCount, funcDeclArgCount, funcDeclUnnamedArgArrayBase,\n\t\t\tfuncDeclCollapseBase, true, srcPos, srcPosArraySize, scgetterps );\n\t\tobjs[o] = obj;\n\t}\n\ttTJSVariant val;\n\tfor( int o = 0; o < objcount; o++ ) {\n\t\ttTJSInterCodeContext* parentObj = NULL;\n\t\ttTJSInterCodeContext* propSetterObj = NULL;\n\t\ttTJSInterCodeContext* propGetterObj = NULL;\n\t\ttTJSInterCodeContext* superClassGetterObj = NULL;\n\n\t\tif( parent[o] >= 0 ) {\n\t\t\tparentObj = objs[parent[o]];\n\t\t}\n\t\tif( propSetter[o] >= 0 ) {\n\t\t\tpropSetterObj = objs[propSetter[o]];\n\t\t}\n\t\tif( propGetter[o] >= 0 ) {\n\t\t\tpropGetterObj = objs[propGetter[o]];\n\t\t}\n\t\tif( superClassGetter[o] >= 0 ) {\n\t\t\tsuperClassGetterObj = objs[superClassGetter[o]];\n\t\t}\n\t\tobjs[o]->SetCodeObject(parentObj, propSetterObj, propGetterObj, superClassGetterObj );\n\n\t\tif( properties[o].size() > 0 ) {\n\t\t\ttTJSInterCodeContext* obj = parentObj;\n\t\t\tstd::vector<int>& prop = properties[o];\n\t\t\tint length = (int)(prop.size() >> 1);\n\t\t\tfor( int i = 0; i < length; i++ ) {\n\t\t\t\tint pos = i << 1;\n\t\t\t\tint pname = prop[pos];\n\t\t\t\tint pobj = prop[pos+1];\n\t\t\t\t// register members to the parent object\n\t\t\t\tval = objs[pobj];\n\t\t\t\tobj->PropSet( TJS_MEMBERENSURE|TJS_IGNOREPROP, StringArray[pname].c_str(), NULL, &val, obj );\n\t\t\t}\n\t\t}\n\t}\n\tint count = (int)work.size();\n\tfor( int i = 0; i < count; i++ ) {\n\t\tVariantRepalace& w = work[i];\n\t\t(*w.Work) = objs[w.Index];\n\t}\n\twork.clear();\n\ttTJSInterCodeContext* top = NULL;\n\tif( toplevel >= 0 ) {\n\t\ttop = objs[toplevel];\n\t}\n\tblock->SetObjects( top, objs, objcount );\n\t//delete[] objs;\n}\n#define TJS_OFFSET_VM_REG_ADDR( x ) ( (x) = TJS_TO_VM_REG_ADDR(x) )\n#define TJS_OFFSET_VM_CODE_ADDR( x ) ( (x) = TJS_TO_VM_CODE_ADDR(x) )\n/**\n * oCgR[h̃AhX͔z̃CfbNXwĂ̂ŁAAhXɕϊ\n */\nvoid tTJSByteCodeLoader::TranslateCodeAddress( tTJSScriptBlock* block, tjs_int32* code, const tjs_int32 codeSize )\n{\n\ttjs_int i = 0;\n\tfor( ; i < codeSize; ) {\n\t\ttjs_int size;\n\t\tswitch( code[i] ) {\n\t\tcase VM_NOP: size = 1; break;\n\t\tcase VM_NF: size = 1; break;\n\t\tcase VM_CONST:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n#define OP2_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak\n\n\t\tOP2_DISASM(VM_CP);\n\t\tOP2_DISASM(VM_CEQ);\n\t\tOP2_DISASM(VM_CDEQ);\n\t\tOP2_DISASM(VM_CLT);\n\t\tOP2_DISASM(VM_CGT);\n\t\tOP2_DISASM(VM_CHKINS);\n#undef OP2_DISASM\n\n#define OP2_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+4]); \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+4]); \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak\n\n\t\tOP2_DISASM(VM_LOR);\n\t\tOP2_DISASM(VM_LAND);\n\t\tOP2_DISASM(VM_BOR);\n\t\tOP2_DISASM(VM_BXOR);\n\t\tOP2_DISASM(VM_BAND);\n\t\tOP2_DISASM(VM_SAR);\n\t\tOP2_DISASM(VM_SAL);\n\t\tOP2_DISASM(VM_SR);\n\t\tOP2_DISASM(VM_ADD);\n\t\tOP2_DISASM(VM_SUB);\n\t\tOP2_DISASM(VM_MOD);\n\t\tOP2_DISASM(VM_DIV);\n\t\tOP2_DISASM(VM_IDIV);\n\t\tOP2_DISASM(VM_MUL);\n#undef OP2_DISASM\n\n#define OP1_DISASM TJS_OFFSET_VM_REG_ADDR(code[i+1]); size = 2;\n\t\tcase VM_TT:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_TF:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_SETF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_SETNF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_LNOT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_BNOT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_ASC:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHR:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_NUM:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHS:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CL:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_INV:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHKINV:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_TYPEOF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_EVAL:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_EEXP:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_INT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_REAL:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_STR:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_OCTET:\t\tOP1_DISASM;\tbreak;\n#undef OP1_DISASM\n\n\t\tcase VM_CCL:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n#define OP1_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tsize = 2; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak\n\n\t\tOP1_DISASM(VM_INC);\n\t\tOP1_DISASM(VM_DEC);\n#undef OP1_DISASM\n\n#define OP1A_DISASM TJS_OFFSET_VM_CODE_ADDR(code[i+1]); size = 2;\n\t\tcase VM_JF:\tOP1A_DISASM; break;\n\t\tcase VM_JNF:OP1A_DISASM; break;\n\t\tcase VM_JMP:OP1A_DISASM; break;\n#undef OP1A_DISASM\n\n\t\tcase VM_CALL:\n\t\tcase VM_CALLD:\n\t\tcase VM_CALLI:\n\t\tcase VM_NEW:\n\t\t  {\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\n\t\t\ttjs_int st; // start of arguments\n\t\t\tif(code[i] == VM_CALLD || code[i] == VM_CALLI) {\n\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\t\tst = 5;\n\t\t\t} else {\n\t\t\t\tst = 4;\n\t\t\t}\n\t\t\ttjs_int num = code[i+st-1];     // st-1 = argument count\n\t\t\ttjs_int c = 0;\n\t\t\tif(num == -1) {\n\t\t\t\tsize = st;\n\t\t\t} else if(num == -2) {\n\t\t\t\tst++;\n\t\t\t\tnum = code[i+st-1];\n\t\t\t\tsize = st + num * 2;\n\t\t\t\tfor(tjs_int j = 0; j < num; j++) {\n\t\t\t\t\tswitch(code[i+st+j*2]) {\n\t\t\t\t\tcase fatNormal:\n\t\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+st+j*2+1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatExpand:\n\t\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+st+j*2+1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatUnnamedExpand:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// normal operation\n\t\t\t\tsize = st + num;\n\t\t\t\twhile(num--) {\n\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+c+st]);\n\t\t\t\t\tc++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t  }\n\n\t\tcase VM_GPD:\n\t\tcase VM_GPDS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SPD:\n\t\tcase VM_SPDE:\n\t\tcase VM_SPDEH:\n\t\tcase VM_SPDS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_GPI:\n\t\tcase VM_GPIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SPI:\n\t\tcase VM_SPIE:\n\t\tcase VM_SPIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SETP:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GETP:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_DELD:\n\t\tcase VM_TYPEOFD:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_DELI:\n\t\tcase VM_TYPEOFI:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SRV:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_RET: size = 1; break;\n\n\t\tcase VM_ENTRY:\n\t\t\tTJS_OFFSET_VM_CODE_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_EXTRY: size = 1; break;\n\n\t\tcase VM_THROW:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_CHGTHIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GLOBAL:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_ADDCI:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_REGMEMBER: size = 1; break;\n\t\tcase VM_DEBUGGER: size = 1; break;\n\t\tdefault: size = 1; break;\n\t\t} /* switch */\n\t\ti+=size;\n\t}\n\tif( codeSize != i ) {\n\t\tTJS_eTJSScriptError( TJSByteCodeBroken, block, 0 );\n\t}\n}\n\n} // namespace\n"
  },
  {
    "path": "src/core/tjs2/tjsByteCodeLoader.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n\n#ifndef tjsByteCodeLoaderH\n#define tjsByteCodeLoaderH\n\n#include \"tjsTypes.h\"\n#include <vector>\n#include \"tjsVariant.h\"\n#include \"tjsScriptBlock.h\"\n\nnamespace TJS\n{\n/**\n * TJS2 oCgR[hǂݍŁAScriptBlock Ԃ\n *\n */\nclass tTJSByteCodeLoader {\npublic:\n\tstatic const tjs_uint32 FILE_TAG_LE = ('T') | ('J'<<8) | ('S'<<16) | ('2'<<24);\n\tstatic const tjs_uint32 VER_TAG_LE = ('1') | ('0'<<8) | ('0'<<16) | (0<<24);\n\nprivate:\n\ttemplate<typename T> struct array_wrap {\n\t\tT* array_;\n\t\tsize_t length_;\n\t\tarray_wrap() : array_(NULL), length_(0) {}\n\t\tT operator[]( int index ) const { return array_[index]; }\n\t\tsize_t size() const { return length_; }\n\t\tvoid set( T* array, size_t length ) {\n\t\t\tarray_ = array;\n\t\t\tlength_ = length;\n\t\t}\n\t};\n\t/**\n\t * InterCodeObject ֒u邽߂ɈꎞIɊoĂNX\n\t */\n\tstruct VariantRepalace {\n\t\ttTJSVariant* Work;\n\t\tint Index;\n\t\tVariantRepalace( tTJSVariant* w, int i ) {\n\t\t\tWork = w;\n\t\t\tIndex = i;\n\t\t}\n\t\tVariantRepalace() : Work(NULL), Index(0) {}\n\t\tvoid set( tTJSVariant* w, int i ) {\n\t\t\tWork = w;\n\t\t\tIndex = i;\n\t\t}\n\t};\n\n\tstatic const tjs_uint32 OBJ_TAG_LE = ('O') | ('B'<<8) | ('J'<<16) | ('S'<<24);\n\tstatic const tjs_uint32 DATA_TAG_LE = ('D') | ('A'<<8) | ('T'<<16) | ('A'<<24);\n\n\tstatic const tjs_int32 TYPE_VOID = 0;\n\tstatic const tjs_int32 TYPE_OBJECT = 1;\n\tstatic const tjs_int32 TYPE_INTER_OBJECT = 2;\n\tstatic const tjs_int32 TYPE_STRING = 3;\n\tstatic const tjs_int32 TYPE_OCTET = 4;\n\tstatic const tjs_int32 TYPE_REAL = 5;\n\tstatic const tjs_int32 TYPE_BYTE = 6;\n\tstatic const tjs_int32 TYPE_SHORT = 7;\n\tstatic const tjs_int32 TYPE_INTEGER = 8;\n\tstatic const tjs_int32 TYPE_LONG = 9;\n\tstatic const tjs_int32 TYPE_INTER_GENERATOR = 10; // temporary\n\tstatic const tjs_int32 TYPE_UNKNOWN = -1;\n\n\tarray_wrap<tjs_int8> ByteArray;\n\tstd::vector<tjs_int16> ShortArray;\n\tstd::vector<tjs_int32> LongArray;\n\tstd::vector<tjs_int64> LongLongArray;\n\tstd::vector<double> DoubleArray;\n\tstd::vector<ttstr> StringArray; // typedef tTJSString ttstr\n\tstd::vector<tTJSVariantOctet*> OctetArray;\n\n\tconst tjs_uint8* ReadBuffer;\n\ttjs_uint32 ReadIndex;\n\ttjs_uint32 ReadSize;\n\n\tstatic inline tjs_uint16 read2byte( const tjs_uint8* x ) {\n\t\treturn  ( (tjs_uint16)(x[0]) | ((tjs_uint16)(x[1])<<8) );\n\t}\n\tstatic inline int read4byte( const tjs_uint8* x ) {\n\t\treturn  ( ((x)[0]) | (((x)[1])<<8) | (((x)[2])<<16) | (((x)[3])<<24) );\n\t}\n\tstatic inline tjs_uint64 read8byte( const tjs_uint8* x ) {\n\t\treturn  ( (tjs_uint64)(x[0]) | ((tjs_uint64)(x[1])<<8) | ((tjs_uint64)(x[2])<<16) | ((tjs_uint64)(x[3])<<24)\n\t\t\t| ((tjs_uint64)(x[4])<<32) | ((tjs_uint64)(x[5])<<40) | ((tjs_uint64)(x[6])<<48) | ((tjs_uint64)(x[7])<<56) );\n\t}\n\npublic:\n\ttTJSByteCodeLoader() : ReadBuffer(NULL), ReadIndex(0), ReadSize(0) {}\n\t~tTJSByteCodeLoader() {\n\t\tsize_t len = OctetArray.size();\n\t\tfor( size_t i = 0; i < len; i++ ) {\n\t\t\ttTJSVariantOctet* o = OctetArray[i];\n\t\t\to->Release();\n\t\t\tOctetArray[i] = NULL;\n\t\t}\n\t}\n\ttTJSScriptBlock* ReadByteCode( tTJS* owner, const tjs_char* name, const tjs_uint8* buf, size_t size );\n\n\t/**\n\t * @param buff : 8oCgȏ̃TCY\n\t */\n\tstatic bool IsTJS2ByteCode( const tjs_uint8* buff );\n\nprivate:\n\tvoid ReadDataArea( const tjs_uint8* buff, int offset, size_t size );\n\tvoid ReadObjects( tTJSScriptBlock* block, const tjs_uint8* buff, int offset, int size );\n\tvoid TranslateCodeAddress( tTJSScriptBlock* block, tjs_int32* code, const tjs_int32 size );\n};\n\n} // namespace\n#endif // tjsByteCodeLoaderH\n\n"
  },
  {
    "path": "src/core/tjs2/tjsCommHead.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// tjs common header\n//---------------------------------------------------------------------------\n\n\n/*\n\tAdd headers that would not be frequently changed.\n*/\n#ifndef tjsCommHeadH\n#define tjsCommHeadH\n\n#ifdef __WIN32__\n#define _CRT_SECURE_NO_WARNINGS\n#define WIN32_LEAN_AND_MEAN\n//#include \"targetver.h\"\n//#include <windows.h>\n\n#include <vector>\n\n#ifdef  _DEBUG\n#define _CRTDBG_MAP_ALLOC\n#include <cstdlib>\n#include <crtdbg.h>\n#define TJS_CRTDBG_MAP_ALLOC\n#endif  // _DEBUG\n\n/*\n#ifndef DEBUG_NEW\n#ifdef  _DEBUG\n#define DEBUG_NEW   ::new(_NORMAL_BLOCK, __FILE__, __LINE__)\n#else   // _DEBUG\n#define DEBUG_NEW   new\n#endif  // _DEBUG\n#endif  // DEBUG_NEW\n#define new DEBUG_NEW\n*/\n\n#endif\n\n\n#include <string.h>\n#ifndef __USE_UNIX98\n#define __USE_UNIX98\n#endif\n#include <wchar.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <memory>\n\n#include <vector>\n#include <string>\n#include <stdexcept>\n\n#include \"tjsConfig.h\"\n#include \"tjs.h\"\n\n//---------------------------------------------------------------------------\n#endif\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsCompileControl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Conditional Compile Control\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsCompileControl.h\"\n#include \"tjsLex.h\"\n#include \"tjsVariant.h\"\n#include \"tjspp.tab.hpp\"\n#include \"tjsError.h\"\n\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n\nint ppparse(void*);\n//---------------------------------------------------------------------------\n// TJS_iswspace\nstatic bool inline TJS_iswspace(tjs_char ch)\n{\n\t// the standard iswspace misses when non-zero page code\n\n\tif(ch&0xff00)\n\t{\n\t\treturn false;\n\t}\n\telse\n\t{\n\t\treturn 0!=isspace(ch);\n\t}\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswdigit(tjs_char ch)\n{\n\t// the standard iswdigit misses when non-zero page code\n\n\tif(ch&0xff00)\n\t{\n\t\treturn false;\n\t}\n\telse\n\t{\n\t\treturn 0!=isdigit(ch);\n\t}\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswalpha(tjs_char ch)\n{\n\t// the standard iswalpha misses when non-zero page code\n\n\tif(ch&0xff00)\n\t{\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn 0!=isalpha(ch);\n\t}\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n// tTJSPPExprParser\n//---------------------------------------------------------------------------\ntTJSPPExprParser::tTJSPPExprParser(tTJS * tjs, const tjs_char *script)\n{\n\t// script pointed by \"script\" argument will be released by this class\n\t// via delete[]\n\tTJS = tjs;\n\tScript = script;\n}\n//---------------------------------------------------------------------------\ntTJSPPExprParser::~tTJSPPExprParser()\n{\n\tdelete [] Script;\n}\n//---------------------------------------------------------------------------\ntjs_int32 tTJSPPExprParser::Parse()\n{\n\tCurrent = Script;\n\tResult = 0;\n\tif(ppparse(this))\n\t{\n\t\tTJS_eTJSError(TJSPPError);\n\t}\n\treturn Result;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSPPExprParser::GetNext(tjs_int32 &value)\n{\n\t// get next token\n\n\twhile(TJS_iswspace(*Current) && *Current) Current++;\n\tif(!*Current) return 0;\n\n\tswitch(*Current)\n\t{\n\tcase TJS_W('('):\n\t\tCurrent++;\n\t\treturn PT_LPARENTHESIS;\n\n\tcase TJS_W(')'):\n\t\tCurrent++;\n\t\treturn PT_RPARENTHESIS;\n\n\tcase TJS_W(','):\n\t\tCurrent++;\n\t\treturn PT_COMMA;\n\n\tcase TJS_W('='):\n\t\tif(*(Current+1) == TJS_W('=')) { Current+=2; return PT_EQUALEQUAL; }\n\t\tCurrent++;\n\t\treturn PT_EQUAL;\n\n\tcase TJS_W('!'):\n\t\tif(*(Current+1) == TJS_W('=')) { Current+=2; return PT_NOTEQUAL; }\n\t\tCurrent++;\n\t\treturn PT_EXCLAMATION;\n\n\tcase TJS_W('|'):\n\t\tif(*(Current+1) == TJS_W('|')) { Current+=2; return PT_LOGICALOR; }\n\t\tCurrent++;\n\t\treturn PT_VERTLINE;\n\n\tcase TJS_W('&'):\n\t\tif(*(Current+1) == TJS_W('&')) { Current+=2; return PT_LOGICALAND; }\n\t\tCurrent++;\n\t\treturn PT_AMPERSAND;\n\n\tcase TJS_W('^'):\n\t\tCurrent++;\n\t\treturn PT_CHEVRON;\n\n\tcase TJS_W('+'):\n\t\tCurrent++;\n\t\treturn PT_PLUS;\n\n\tcase TJS_W('-'):\n\t\tCurrent++;\n\t\treturn PT_MINUS;\n\n\tcase TJS_W('*'):\n\t\tCurrent++;\n\t\treturn PT_ASTERISK;\n\n\tcase TJS_W('/'):\n\t\tCurrent++;\n\t\treturn PT_SLASH;\n\n\tcase TJS_W('%'):\n\t\tCurrent++;\n\t\treturn PT_PERCENT;\n\n\tcase TJS_W('<'):\n\t\tif(*(Current+1) == TJS_W('=')) { Current+=2; return PT_LTOREQUAL; }\n\t\tCurrent++;\n\t\treturn PT_LT;\n\n\tcase TJS_W('>'):\n\t\tif(*(Current+1) == TJS_W('=')) { Current+=2; return PT_GTOREQUAL; }\n\t\tCurrent++;\n\t\treturn PT_GT;\n\n\tcase TJS_W('0'):\n\tcase TJS_W('1'):\n\tcase TJS_W('2'):\n\tcase TJS_W('3'):\n\tcase TJS_W('4'):\n\tcase TJS_W('5'):\n\tcase TJS_W('6'):\n\tcase TJS_W('7'):\n\tcase TJS_W('8'):\n\tcase TJS_W('9'):\n\t  {\n\t\t// number\n\t\ttTJSVariant val;\n\t\ttry\n\t\t{\n\t\t\tif(!TJSParseNumber(val, &Current)) return PT_ERROR;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\treturn PT_ERROR;\n\t\t}\n\t\tvalue = (tjs_int32)(tTVInteger)val;\n\t\treturn PT_NUM;\n\t  }\n\n\t}\n\n\tif(!TJS_iswalpha(*Current) && *Current!=TJS_W('_'))\n\t{\n\t\treturn PT_ERROR;\n\t}\n\n\tconst tjs_char *st = Current;\n\twhile((TJS_iswalpha(*Current) || TJS_iswdigit(*Current) ||\n\t\t*Current==TJS_W('_')) && *Current)\n\t\tCurrent++;\n\n\tttstr str(st, (int)(Current-st));\n\n\tIDs.push_back(str);\n    value = (tjs_int32)(IDs.size() -1);\n\n\treturn PT_SYMBOL;\n}\n//---------------------------------------------------------------------------\nconst tjs_char * tTJSPPExprParser::GetString(tjs_int idx) const\n{\n\treturn IDs[idx].c_str();\n}\n//---------------------------------------------------------------------------\nint pplex(YYSTYPE *yylex, void *pm)\n{\n\ttjs_int32 val;\n\ttjs_int n;\n\tn = ((tTJSPPExprParser*)pm)->GetNext(val);\n\tif(n == PT_NUM) yylex->val = val;\n\tif(n == PT_SYMBOL) yylex->nv = val;\n\treturn n;\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsCompileControl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Conditional Compile Control\n//---------------------------------------------------------------------------\n\n#ifndef tjsCompileControlH\n#define tjsCompileControlH\n\n#include \"tjsString.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nclass tTJS;\nclass tTJSPPExprParser\n{\npublic:\n\ttTJSPPExprParser(tTJS *tjs, const tjs_char *script);\n\t~tTJSPPExprParser();\n\n\ttjs_int32 Parse();\n\n\ttTJS * TJS;\n\ttjs_int GetNext (tjs_int &value);\n\n\ttTJS * GetTJS() { return TJS; }\n\n\tconst tjs_char * GetString(tjs_int idx) const ;\n\n\ttjs_int32 Result;\n\nprivate:\n\tstd::vector<ttstr > IDs;\n\n\tconst tjs_char *Script;\n\tconst tjs_char *Current;\n\n};\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n}\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsConfig.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// configuration\n//---------------------------------------------------------------------------\n\n\n#include \"tjsCommHead.h\"\n#include <errno.h>\n#include <clocale>\n#include <algorithm>\n#ifdef __WIN32__\n#include <float.h>\n#define isfinite _finite\n#else\n#define isfinite std::isfinite\n#endif\n#define INTMAX_MAX\t\t0x7fffffffffffffff\n#include <assert.h>\n\n/*\n * core/utils/cp932_uni.cpp\n * core/utils/uni_cp932.cpp\n * ���ꏏ�Ƀ����N���Ă��������B\n * CP932(ShiftJIS) �� Unicode �ϊ��Ɏg�p���Ă��܂��B\n * Win32 API�̓����̊֐��͌݊������̖�肪���邱�Ƃ�}���`�v���b�g�t�H�[���̑������ƂȂ�\n * ���ߎg�p�����~����܂����B\n */\n#if 0\nextern tjs_size SJISToUnicodeString(const char * in, tjs_char *out);\nextern tjs_size SJISToUnicodeString(const char * in, tjs_char *out, tjs_size limit );\nextern bool IsSJISLeadByte( tjs_nchar b );\nextern tjs_uint UnicodeToSJIS(tjs_char in);\nextern tjs_size UnicodeToSJISString(const tjs_char *in, tjs_nchar* out );\nextern tjs_size UnicodeToSJISString(const tjs_char *in, tjs_nchar* out, tjs_size limit );\n#endif\n\nstatic int\nutf8_mbtowc(/*conv_t conv,*/ tjs_char *pwc, const unsigned char *s, int n)\n{\n\tunsigned char c = s[0];\n\n\tif (c < 0x80) {\n\t\t*pwc = c;\n\t\treturn 1;\n\t} else if (c < 0xc2) {\n\t\treturn -1;\n\t} else if (c < 0xe0) {\n\t\tif (n < 2)\n\t\t\treturn -1;\n\t\tif (!((s[1] ^ 0x80) < 0x40))\n\t\t\treturn -1;\n\t\t*pwc = ((tjs_char)(c & 0x1f) << 6)\n\t\t\t| (tjs_char)(s[1] ^ 0x80);\n\t\treturn 2;\n\t} else if (c < 0xf0) {\n\t\tif (n < 3)\n\t\t\treturn -1;\n\t\tif (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n\t\t\t&& (c >= 0xe1 || s[1] >= 0xa0)))\n\t\t\treturn -1;\n\t\t*pwc = ((tjs_char)(c & 0x0f) << 12)\n\t\t\t| ((tjs_char)(s[1] ^ 0x80) << 6)\n\t\t\t| (tjs_char)(s[2] ^ 0x80);\n\t\treturn 3;\n\t} else\n\t\treturn -1;\n}\n\nstatic int\nutf8_wctomb(/*conv_t conv,*/ unsigned char *r, tjs_char wc, int n) /* n == 0 is acceptable */\n{\n\tint count;\n\tif (wc < 0x80)\n\t\tcount = 1;\n\telse if (wc < 0x800)\n\t\tcount = 2;\n\telse if (wc < 0x10000)\n\t\tcount = 3;\n// \telse if (wc < 0x200000)\n// \t\tcount = 4;\n// \telse if (wc < 0x4000000)\n// \t\tcount = 5;\n// \telse if (wc <= 0x7fffffff)\n// \t\tcount = 6;\n\telse\n\t\treturn -1;\n\tif (n < count)\n\t\treturn -2;\n\tswitch (count) { /* note: code falls through cases! */\n// \tcase 6: r[5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000;\n// \tcase 5: r[4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000;\n// \tcase 4: r[3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000;\n\tcase 3: r[2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800;\n\tcase 2: r[1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0;\n\tcase 1: r[0] = wc;\n\t}\n\treturn count;\n}\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// debug support\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint TJSGetTickCount()\n{\n\treturn GetTickCount();\n}\n#endif\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// some wchar_t support functions\n//---------------------------------------------------------------------------\ntjs_int TJS_atoi(const tjs_char *s)\n{\n\tint r = 0;\n\tbool sign = false;\n\twhile(*s && *s <= 0x20) s++; // skip spaces\n\tif(!*s) return 0;\n\tif(*s == TJS_W('-'))\n\t{\n\t\tsign = true;\n\t\ts++;\n\t\twhile(*s && *s <= 0x20) s++; // skip spaces\n\t\tif(!*s) return 0;\n\t}\n\n\twhile(*s >= TJS_W('0') && *s <= TJS_W('9'))\n\t{\n\t\tr *= 10;\n\t\tr += *s - TJS_W('0');\n\t\ts++;\n\t}\n\tif(sign) r = -r;\n\treturn r;\n}\n\ntjs_int64 TJS_atoll(const tjs_char *s)\n{\n\ttjs_int64 r = 0;\n\tbool sign = false;\n\twhile (*s && *s <= 0x20) s++; // skip spaces\n\tif (!*s) return 0;\n\tif (*s == TJS_W('-'))\n\t{\n\t\tsign = true;\n\t\ts++;\n\t\twhile (*s && *s <= 0x20) s++; // skip spaces\n\t\tif (!*s) return 0;\n\t}\n\n\twhile (*s >= TJS_W('0') && *s <= TJS_W('9'))\n\t{\n\t\tr *= 10;\n\t\tr += *s - TJS_W('0');\n\t\ts++;\n\t}\n\tif (sign) r = -r;\n\treturn r;\n}\n//---------------------------------------------------------------------------\ntjs_char * TJS_int_to_str(tjs_int value, tjs_char *string)\n{\n\ttjs_char *ostring = string;\n\n\tif(value<0) *(string++) = TJS_W('-'), value = -value;\n\n\ttjs_char buf[40];\n\n\ttjs_char *p = buf;\n\n\tdo\n\t{\n\t\t*(p++) = (value % 10) + TJS_W('0');\n\t\tvalue /= 10;\n\t} while(value);\n\n\tp--;\n\twhile(buf <= p) *(string++) = *(p--);\n\t*string = 0;\n\n\treturn ostring;\n}\n//---------------------------------------------------------------------------\ntjs_char * TJS_tTVInt_to_str(tjs_int64 value, tjs_char *string)\n{\n\tif(value == TJS_UI64_VAL(0x8000000000000000))\n\t{\n\t\t// this is a special number which we must avoid normal conversion\n\t\tTJS_strcpy(string, TJS_W(\"-9223372036854775808\"));\n\t\treturn string;\n\t}\n\n\ttjs_char *ostring = string;\n\n\tif(value<0) *(string++) = TJS_W('-'), value = -value;\n\n\ttjs_char buf[40];\n\n\ttjs_char *p = buf;\n\n\tdo\n\t{\n\t\t*(p++) = (value % 10) + TJS_W('0');\n\t\tvalue /= 10;\n\t} while(value);\n\n\tp--;\n\twhile(buf <= p) *(string++) = *(p--);\n\t*string = 0;\n\n\treturn ostring;\n}\n//---------------------------------------------------------------------------\ntjs_int TJS_strnicmp(const tjs_char *s1, const tjs_char *s2,\n\tsize_t maxlen)\n{\n\twhile(maxlen--)\n\t{\n\t\tif(*s1 == TJS_W('\\0')) return (*s2 == TJS_W('\\0')) ? 0 : -1;\n\t\tif(*s2 == TJS_W('\\0')) return (*s1 == TJS_W('\\0')) ? 0 : 1;\n\t\tif(*s1 < *s2) return -1;\n\t\tif(*s1 > *s2) return 1;\n\t\ts1++;\n\t\ts2++;\n\t}\n\n\treturn 0;\n}\n//---------------------------------------------------------------------------\ntjs_int TJS_stricmp(const tjs_char *s1, const tjs_char *s2)\n{\n\t// we only support basic alphabets\n\t// fixme: complete alphabets support\n\n\tfor(;;)\n\t{\n\t\ttjs_char c1 = *s1, c2 = *s2;\n\t\tif(c1 >= TJS_W('a') && c1 <= TJS_W('z')) c1 += TJS_W('Z')-TJS_W('z');\n\t\tif(c2 >= TJS_W('a') && c2 <= TJS_W('z')) c2 += TJS_W('Z')-TJS_W('z');\n\t\tif(c1 == TJS_W('\\0')) return (c2 == TJS_W('\\0')) ? 0 : -1;\n\t\tif(c2 == TJS_W('\\0')) return (c1 == TJS_W('\\0')) ? 0 : 1;\n\t\tif(c1 < c2) return -1;\n\t\tif(c1 > c2) return 1;\n\t\ts1++;\n\t\ts2++;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_strcpy_maxlen(tjs_char *d, const tjs_char *s, size_t len)\n{\n\ttjs_char ch;\n\tlen++;\n\twhile((ch=*s)!=0 && --len) *(d++) = ch, s++;\n\t*d = 0;\n}\n//---------------------------------------------------------------------------\nvoid TJS_strcpy(tjs_char *d, const tjs_char *s)\n{\n\ttjs_char ch;\n\twhile((ch=*s)!=0) *(d++) = ch, s++;\n\t*d = 0;\n}\n//---------------------------------------------------------------------------\nsize_t TJS_strlen(const tjs_char *d)\n{\n\tconst tjs_char *p = d;\n\twhile(*d) d++;\n\treturn d-p;\n}\n//---------------------------------------------------------------------------\ntjs_int TJS_sprintf(tjs_char *s, const tjs_char *format, ...)\n{\n\ttjs_int r;\n\tva_list param;\n\tva_start(param, format);\n\tr = TJS_vsnprintf(s, INT_MAX, format, param);\n\tva_end(param);\n\treturn r;\n}\n//---------------------------------------------------------------------------\n\nvoid TVPConsoleLog(const tjs_char *l);\nvoid TJS_debug_out(const tjs_char *format, ...)\n{\n\ttjs_int r;\n\tva_list param;\n\tva_start(param, format);\n\ttjs_char buf[256];\n\tr = TJS_vsnprintf(buf, 256, format, param);\n\tva_end(param);\n\tTVPConsoleLog(buf);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n#define TJS_MB_MAX_CHARLEN 2\n//---------------------------------------------------------------------------\nsize_t TJS_mbstowcs(tjs_char *pwcs, const tjs_nchar *s, size_t n)\n{\n#if 0\n    if(pwcs && n == 0) return 0;\n\n\tif(pwcs)\n\t{\n\t\tsize_t count = SJISToUnicodeString( s, pwcs, n );\n\t\tif( n > count )\n\t\t{\n\t\t\tpwcs[count] = TJS_W('\\0');\n\t\t}\n\t\treturn count;\n\t}\n\telse\n\t{\t// count length\n\t\treturn SJISToUnicodeString( s, NULL );\n\t}\n#endif\n\tif (!s) return -1;\n\tif (pwcs && n == 0) return 0;\n\n\ttjs_char wc;\n    size_t count = 0;\n    int cl;\n\tif (!pwcs) {\n        n = strlen(s);\n\t\twhile (*s) {\n            cl = utf8_mbtowc(&wc, (const unsigned char*)s, n);\n\t\t\tif (cl <= 0)\n                break;\n            s += cl;\n            n -= cl;\n            ++count;\n        }\n    } else {\n        tjs_char *pwcsend = pwcs + n;\n        n = strlen(s);\n\t\twhile (*s && pwcs < pwcsend) {\n            cl = utf8_mbtowc(&wc, (const unsigned char*)s, n);\n\t\t\tif (cl <= 0)\n                return -1;\n            s += cl;\n            n -= cl;\n            *pwcs++ = wc;\n            ++count;\n        }\n    }\n    return count;\n}\n//---------------------------------------------------------------------------\nsize_t TJS_wcstombs(tjs_nchar *s, const tjs_char *pwcs, size_t n)\n{\n#if 0\n    if(s && !n) return 0;\n\n\tif(s)\n\t{\n\t\ttjs_size count = UnicodeToSJISString( pwcs, s, n );\n\t\tif( n > count )\n\t\t{\n\t\t\ts[count] = '\\0';\n\t\t}\n\t\treturn count;\n\t}\n\telse\n\t{\n\t\t// Returns the buffer size to store the result\n\t\treturn UnicodeToSJISString(pwcs,NULL);\n\t}\n#endif\n\tif (!pwcs) return -1;\n\tif (s && !n) return 0;\n\n    int cl;\n\tif (!s) {\n        unsigned char tmp[6];\n        size_t count = 0;\n\t\twhile (*pwcs) {\n            cl = utf8_wctomb(tmp, *pwcs, 6);\n\t\t\tif (cl <= 0)\n                return -1;\n\t\t\tpwcs++;\n            count += cl;\n        }\n        return count;\n    } else {\n        tjs_nchar *d = s;\n\t\twhile (*pwcs && n > 0) {\n            cl = utf8_wctomb((unsigned char*)d, *pwcs, n);\n\t\t\tif (cl <= 0)\n                return -1;\n            n -= cl;\n            d += cl;\n\t\t\tpwcs++;\n        }\n        return d - s;\n    }\n}\n//---------------------------------------------------------------------------\n// �g���Ă��Ȃ��悤�Ȃ̂Ŗ��m�F����\nint TJS_mbtowc(tjs_char *pwc, const tjs_nchar *s, size_t n)\n{\n#if 0\n\tif(!s || !n) return 0;\n\n\tif(*s == 0)\n\t{\n\t\tif(pwc) *pwc = 0;\n\t\treturn 0;\n\t}\n\n\t/* Borland's RTL seems to assume always MB_MAX_CHARLEN = 2. */\n\t/* This may true while we use Win32 platforms ... */\n\tif( IsSJISLeadByte( *s ) )\n\t{\n\t\t// multi(double) byte character\n\t\tif((int)n < TJS_MB_MAX_CHARLEN) return -1;\n\t\ttjs_size count = SJISToUnicodeString( s, pwc, 1 );\n\t\tif( count <= 0 )\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\treturn TJS_MB_MAX_CHARLEN;\n\t}\n\telse\n\t{\n\t\t// single byte character\n\t\treturn (int)SJISToUnicodeString( s, pwc, 1 );\n\t}\n#endif\n\tif (!s || !n) return 0;\n\n\tif (*s == 0)\n\t{\n\t\tif (pwc) *pwc = 0;\n\t\treturn 0;\n\t}\n\ttjs_char wc;\n    int ret = utf8_mbtowc(&wc, (const unsigned char *)s, n);\n\tif (ret >= 0) {\n        *pwc = wc;\n    }\n    return ret;\n}\n//---------------------------------------------------------------------------\n// �g���Ă��Ȃ��悤�Ȃ̂Ŗ��m�F����\nint TJS_wctomb(tjs_nchar *s, tjs_char wc)\n{\n#if 0\n    if(!s) return 0;\n\ttjs_uint c = UnicodeToSJIS(wc);\n\tif( c == 0 ) return -1;\n\tint size = 0;\n\tif( c & 0xff00 )\n\t{\n\t\t*s = static_cast<tjs_nchar>((c>>8)&0xff);\n\t\ts++;\n\t\tsize++;\n\t}\n\t*s = static_cast<tjs_nchar>( c&0xff );\n\tsize++;\n\treturn size;\n#endif\n\tif (!s) return 0;\n\ttjs_char tmp[2] = { wc, 0 };\n    return utf8_wctomb((unsigned char*)s, wc, 2);\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNarrowStringHolder\n//---------------------------------------------------------------------------\ntTJSNarrowStringHolder::tTJSNarrowStringHolder(const tjs_char * wide)\n{\n\tint n;\n\tif(!wide)\n\t\tn = -1;\n\telse\n\t\tn = (int)TJS_wcstombs(NULL, wide, 0);\n\n\tif( n == -1 )\n\t{\n\t\tBuf = TJS_N(\"\");\n\t\tAllocated = false;\n\t\treturn;\n\t}\n\tBuf = new tjs_nchar[n+1];\n\t\tAllocated = true;\n\tBuf[TJS_wcstombs(Buf, wide, n)] = 0;\n}\n//---------------------------------------------------------------------------\ntTJSNarrowStringHolder::~tTJSNarrowStringHolder()\n{\n\tif(Allocated) delete [] Buf;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// native debugger break point\n//---------------------------------------------------------------------------\nvoid TJSNativeDebuggerBreak()\n{\n\t// This function is to be called mostly when the \"debugger\" TJS statement is\n\t// executed.\n\t// Step you debbuger back to the the caller, and continue debugging.\n\t// Do not use \"debugger\" statement unless you run the program under the native\n\t// debugger, or the program may cause an unhandled debugger breakpoint\n\t// exception.\n\n#if defined(__WIN32__)\n\t#if defined(_M_IX86)\n\t\t#ifdef __BORLANDC__\n\t\t\t\t__emit__ (0xcc); // int 3 (Raise debugger breakpoint exception)\n\t\t#else\n\t\t\t\t_asm _emit 0xcc; // int 3 (Raise debugger breakpoint exception)\n\t\t#endif\n\t#else\n\t\t__debugbreak();\n\t#endif\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// FPU control\n//---------------------------------------------------------------------------\n#if defined(__WIN32__) && !defined(__GNUC__)\nstatic unsigned int TJSDefaultFPUCW = 0;\nstatic unsigned int TJSNewFPUCW = 0;\nstatic unsigned int TJSDefaultMMCW = 0;\nstatic bool TJSFPUInit = false;\n#endif\n// FPU��O���}�X�N\nvoid TJSSetFPUE()\n{\n#if defined(__WIN32__) && !defined(__GNUC__)\n\tif(!TJSFPUInit)\n\t{\n\t\tTJSFPUInit = true;\n#if defined(_M_X64)\n\t\tTJSDefaultMMCW = _MM_GET_EXCEPTION_MASK();\n#else\n\t\tTJSDefaultFPUCW = _control87(0, 0);\n\n#ifdef _MSC_VER\n\t\tTJSNewFPUCW = _control87(MCW_EM, MCW_EM);\n#else\n\t\t_default87 = TJSNewFPUCW = _control87(MCW_EM, MCW_EM);\n#endif\t// _MSC_VER\n#ifdef TJS_SUPPORT_VCL\n\t\tDefault8087CW = TJSNewFPUCW;\n#endif\t// TJS_SUPPORT_VCL\n#endif\t// _M_X64\n\t}\n\n#if defined(_M_X64)\n\t_MM_SET_EXCEPTION_MASK(_MM_MASK_INVALID|_MM_MASK_DIV_ZERO|_MM_MASK_DENORM|_MM_MASK_OVERFLOW|_MM_MASK_UNDERFLOW|_MM_MASK_INEXACT);\n#else\n//\t_fpreset();\n\t_control87(TJSNewFPUCW, 0xffff);\n#endif\n#endif\t// defined(__WIN32__) && !defined(__GNUC__)\n\n}\n// ��O�}�X�N�����������ɖ߂�\nvoid TJSRestoreFPUE()\n{\n#if defined(__WIN32__) && !defined(__GNUC__)\n\tif (!TJSFPUInit) return;\n#if defined(_M_X64)\n\t_MM_SET_EXCEPTION_MASK(TJSDefaultMMCW);\n#else\n\t_control87(TJSDefaultFPUCW, 0xffff);\n#endif\n#endif\n}\n\nint TJS_strcmp (\n    const tjs_char * src,\n    const tjs_char * dst\n    )\n{\n    int ret = 0 ;\n\n    while( ! (ret = (int)(*src - *dst)) && *dst)\n        ++src, ++dst;\n\n    if ( ret < 0 )\n        ret = -1 ;\n    else if ( ret > 0 )\n        ret = 1 ;\n\n    return( ret );\n}\n\nint TJS_strncmp (\n    const tjs_char * first,\n    const tjs_char * last,\n    size_t count\n    )\n{\n    if (!count)\n        return(0);\n\n    while (--count && *first && *first == *last)\n    {\n        first++;\n        last++;\n    }\n\n    return((int)(*first - *last));\n}\n\ntjs_char * TJS_strncpy (\n    tjs_char * dest,\n    const tjs_char * source,\n    size_t count\n    )\n{\n    tjs_char *start = dest;\n\n    while (count && (*dest++ = *source++))    /* copy string */\n        count--;\n\n    if (count)                              /* pad out with zeroes */\n        while (--count)\n            *dest++ = L'\\0';\n\n    return(start);\n}\n\ntjs_char * TJS_strcat (\n    tjs_char * dst,\n    const tjs_char * src\n    )\n{\n    tjs_char * cp = dst;\n\n    while( *cp )\n        cp++;                   /* find end of dst */\n\n    while( (*cp++ = *src++) ) ;       /* Copy src to end of dst */\n\n    return( dst );                  /* return dst */\n\n}\n\ntjs_char * TJS_strstr (\n    const tjs_char * wcs1,\n    const tjs_char * wcs2\n    )\n{\n    tjs_char *cp = (tjs_char *) wcs1;\n    tjs_char *s1, *s2;\n\n    if ( !*wcs2)\n        return (tjs_char *)wcs1;\n\n    while (*cp)\n    {\n        s1 = cp;\n        s2 = (tjs_char *) wcs2;\n\n        while ( *s1 && *s2 && !(*s1-*s2) )\n            s1++, s2++;\n\n        if (!*s2)\n            return(cp);\n\n        cp++;\n    }\n\n    return(NULL);\n}\ntjs_char * TJS_strchr (\n    const tjs_char * string,\n    tjs_char ch\n    )\n{\n    while (*string && *string != (tjs_char)ch)\n        string++;\n\n    if (*string == (tjs_char)ch)\n        return((tjs_char *)string);\n    return(NULL);\n}\n\nvoid * TJS_malloc(size_t len)\n{\n\tchar *ret = (char*)malloc(len+sizeof(size_t));\n\tif (!ret) return nullptr;\n\t*(size_t*)ret = len; // embed size\n\treturn ret + sizeof(size_t);\n}\n\nvoid * TJS_realloc(void* buf, size_t len)\n{\n\tif (!buf) return TJS_malloc(len);\n\t// compare embeded size\n\tsize_t * ptr = (size_t *)((char*)buf - sizeof(size_t));\n\tif (*ptr >= len) return buf; // still adequate\n\tchar *ret = (char*)TJS_malloc(len);\n\tif (!ret) return nullptr;\n\tmemcpy(ret, ptr + 1, *ptr);\n\tTJS_free(buf);\n\treturn ret;\n}\n\nvoid TJS_free(void *buf)\n{\n\tfree((char*)buf - sizeof(size_t));\n}\n\ntjs_char *TJS_strrchr(const tjs_char *s, int c)\n{\n\ttjs_char* ret = 0;\n\tdo {\n\t\tif (*s == (char)c)\n\t\t\tret = (tjs_char *)s;\n\t} while (*s++);\n\treturn ret;\n}\n\n#include <ctype.h>\n#include <limits.h>\n#include <string.h>\n#include <stdarg.h>\n//#include <inttypes.h>\n#include <stdint.h>\n#include <math.h>\n#include <float.h>\n\n/* Some useful macros */\n\n#define MAX(a,b) ((a)>(b) ? (a) : (b))\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n#define CONCAT2(x,y) x ## y\n#define CONCAT(x,y) CONCAT2(x,y)\n#define NL_ARGMAX 9\n\n/* Convenient bit representation for modifier flags, which all fall\n * within 31 codepoints of the space character. */\n\n#define ALT_FORM   (1U<<('#'-' '))\n#define ZERO_PAD   (1U<<('0'-' '))\n#define LEFT_ADJ   (1U<<('-'-' '))\n#define PAD_POS    (1U<<(' '-' '))\n#define MARK_POS   (1U<<('+'-' '))\n#define GROUPED    (1U<<('\\''-' '))\n\n#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)\n\n#if UINT_MAX == ULONG_MAX\n#define LONG_IS_INT\n#endif\n\n#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX\n#define ODD_TYPES\n#endif\n\n/* State machine to accept length modifiers + conversion specifiers.\n * Result is 0 on failure, or an argument type to pop on success. */\n\nenum {\n\tBARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,\n\tZTPRE, JPRE,\n\tSTOP,\n\tPTR, INT, UINT, ULLONG,\n#ifndef LONG_IS_INT\n\tLONG, ULONG,\n#else\n#define LONG INT\n#define ULONG UINT\n#endif\n\tSHORT, USHORT, CHAR, UCHAR,\n#ifdef ODD_TYPES\n\tLLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,\n#else\n#define LLONG ULLONG\n#define SIZET ULONG\n#define IMAX LLONG\n#define UMAX ULLONG\n#define PDIFF LONG\n#define UIPTR ULONG\n#endif\n\tDBL, LDBL,\n\tNOARG,\n\tMAXSTATE\n};\n#define S(x) [(x)-'A']\n\nstatic const unsigned char states[]['z'-'A'+1] = \n{{DBL,\nBARE,\nINT,\nBARE,\nDBL,\nDBL,\nDBL,\nBARE,\nBARE,\nBARE,\nBARE,\nBIGLPRE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nBARE,\nBARE,\nBARE,\nBARE,\nUINT,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nDBL,\nBARE,\nCHAR,\nINT,\nDBL,\nDBL,\nDBL,\nHPRE,\nINT,\nJPRE,\nBARE,\nLPRE,\nNOARG,\nPTR,\nUINT,\nUIPTR,\nBARE,\nBARE,\nPTR,\nZTPRE,\nUINT,\nBARE,\nBARE,\nUINT,\nBARE,\nZTPRE},\n{DBL,\nBARE,\nBARE,\nBARE,\nDBL,\nDBL,\nDBL,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nULONG,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nDBL,\nBARE,\nINT,\nLONG,\nDBL,\nDBL,\nDBL,\nBARE,\nLONG,\nBARE,\nBARE,\nLLPRE,\nBARE,\nPTR,\nULONG,\nBARE,\nBARE,\nBARE,\nPTR,\nBARE,\nULONG,\nBARE,\nBARE,\nULONG,\nBARE,\nBARE},\n{BARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nULLONG,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nLLONG,\nBARE,\nBARE,\nBARE,\nBARE,\nLLONG,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nULLONG,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nULLONG,\nBARE,\nBARE,\nULLONG,\nBARE,\nBARE},\n{BARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUSHORT,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nSHORT,\nBARE,\nBARE,\nBARE,\nHHPRE,\nSHORT,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nUSHORT,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUSHORT,\nBARE,\nBARE,\nUSHORT,\nBARE,\nBARE},\n{BARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUCHAR,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nCHAR,\nBARE,\nBARE,\nBARE,\nBARE,\nCHAR,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nUCHAR,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUCHAR,\nBARE,\nBARE,\nUCHAR,\nBARE,\nBARE},\n{LDBL,\nBARE,\nBARE,\nBARE,\nLDBL,\nLDBL,\nLDBL,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nLDBL,\nBARE,\nBARE,\nBARE,\nLDBL,\nLDBL,\nLDBL,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE},\n{BARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nSIZET,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nPDIFF,\nBARE,\nBARE,\nBARE,\nBARE,\nPDIFF,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nSIZET,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nSIZET,\nBARE,\nBARE,\nSIZET,\nBARE,\nBARE},\n{BARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUMAX,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nIMAX,\nBARE,\nBARE,\nBARE,\nBARE,\nIMAX,\nBARE,\nBARE,\nBARE,\nBARE,\nPTR,\nUMAX,\nBARE,\nBARE,\nBARE,\nBARE,\nBARE,\nUMAX,\nBARE,\nBARE,\nUMAX,\nBARE,\nBARE}};\n// {\n// \t{ /* 0: bare types */\n// \t\tS('d') = INT, S('i') = INT,\n// \t\tS('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,\n// \t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n// \t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n// \t\tS('c') = CHAR, S('C') = INT,\n// \t\tS('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,\n// \t\tS('m') = NOARG,\n// \t\tS('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,\n// \t\tS('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,\n// \t}, { /* 1: l-prefixed */\n// \t\tS('d') = LONG, S('i') = LONG,\n// \t\tS('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,\n// \t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n// \t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n// \t\tS('c') = INT, S('s') = PTR, S('n') = PTR,\n// \t\tS('l') = LLPRE,\n// \t}, { /* 2: ll-prefixed */\n// \t\tS('d') = LLONG, S('i') = LLONG,\n// \t\tS('o') = ULLONG, S('u') = ULLONG,\n// \t\tS('x') = ULLONG, S('X') = ULLONG,\n// \t\tS('n') = PTR,\n// \t}, { /* 3: h-prefixed */\n// \t\tS('d') = SHORT, S('i') = SHORT,\n// \t\tS('o') = USHORT, S('u') = USHORT,\n// \t\tS('x') = USHORT, S('X') = USHORT,\n// \t\tS('n') = PTR,\n// \t\tS('h') = HHPRE,\n// \t}, { /* 4: hh-prefixed */\n// \t\tS('d') = CHAR, S('i') = CHAR,\n// \t\tS('o') = UCHAR, S('u') = UCHAR,\n// \t\tS('x') = UCHAR, S('X') = UCHAR,\n// \t\tS('n') = PTR,\n// \t}, { /* 5: L-prefixed */\n// \t\tS('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,\n// \t\tS('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,\n// \t\tS('n') = PTR,\n// \t}, { /* 6: z- or t-prefixed (assumed to be same size) */\n// \t\tS('d') = PDIFF, S('i') = PDIFF,\n// \t\tS('o') = SIZET, S('u') = SIZET,\n// \t\tS('x') = SIZET, S('X') = SIZET,\n// \t\tS('n') = PTR,\n// \t}, { /* 7: j-prefixed */\n// \t\tS('d') = IMAX, S('i') = IMAX,\n// \t\tS('o') = UMAX, S('u') = UMAX,\n// \t\tS('x') = UMAX, S('X') = UMAX,\n// \t\tS('n') = PTR,\n// \t}\n// };\n#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')\n\n// typedef long long          intmax_t;\n// typedef unsigned long long uintmax_t;\n// typedef unsigned short     uint16_t;\n// typedef unsigned long      uint32_t;\n// typedef unsigned long long uint64_t;\nunion arg\n{\n\tuintmax_t i;\n\tlong double f;\n\tvoid *p;\n};\n\nstatic void pop_arg(union arg *arg, int type, va_list *ap)\n{\n\t/* Give the compiler a hint for optimizing the switch. */\n\tif ((unsigned)type > MAXSTATE) return;\n\tswitch (type) {\n\t       case PTR:\targ->p = va_arg(*ap, void *);\n\tbreak; case INT:\targ->i = va_arg(*ap, int);\n\tbreak; case UINT:\targ->i = va_arg(*ap, unsigned int);\n#ifndef LONG_IS_INT\n\tbreak; case LONG:\targ->i = va_arg(*ap, long);\n\tbreak; case ULONG:\targ->i = va_arg(*ap, unsigned long);\n#endif\n\tbreak; case ULLONG:\targ->i = va_arg(*ap, unsigned long long);\n\tbreak; case SHORT:\targ->i = (short)va_arg(*ap, int);\n\tbreak; case USHORT:\targ->i = (unsigned short)va_arg(*ap, int);\n\tbreak; case CHAR:\targ->i = (signed char)va_arg(*ap, int);\n\tbreak; case UCHAR:\targ->i = (unsigned char)va_arg(*ap, int);\n#ifdef ODD_TYPES\n\tbreak; case LLONG:\targ->i = va_arg(*ap, long long);\n\tbreak; case SIZET:\targ->i = va_arg(*ap, size_t);\n\tbreak; case IMAX:\targ->i = va_arg(*ap, intmax_t);\n\tbreak; case UMAX:\targ->i = va_arg(*ap, uintmax_t);\n\tbreak; case PDIFF:\targ->i = va_arg(*ap, ptrdiff_t);\n\tbreak; case UIPTR:\targ->i = (uintptr_t)va_arg(*ap, void *);\n#endif\n\tbreak; case DBL:\targ->f = va_arg(*ap, double);\n\tbreak; case LDBL:\targ->f = va_arg(*ap, long double);\n\t}\n}\n\nstruct _tFILE\n{\n    tjs_char *p;\n};\n\nstatic void out(_tFILE *f, const tjs_char *s, size_t l)\n{\n    memcpy(f->p, s, l * sizeof(*f->p));\n    f->p += l;\n}\n\nstatic void pad(_tFILE *f, tjs_char c, int w, int l, int fl)\n{\n\ttjs_char pad[256];\n\tif (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;\n\tl = w - l;\n    int n = l >sizeof pad / sizeof(pad[0])? sizeof pad / sizeof(pad[0]): l;\n    while(n--) pad[n] = c;\n\tfor (; l >= sizeof pad; l -= sizeof pad)\n\t\tout(f, pad, sizeof pad / sizeof(pad[0]));\n\tout(f, pad, l);\n}\n\nstatic const char xdigits[] = \n\t\"0123456789ABCDEF\";\n\n\nstatic tjs_char *fmt_x(uintmax_t x, tjs_char *s, int lower)\n{\n\tfor (; x; x>>=4) *--s = xdigits[(x&15)]|lower;\n\treturn s;\n}\n\nstatic tjs_char *fmt_o(uintmax_t x, tjs_char *s)\n{\n\tfor (; x; x>>=3) *--s = '0' + (x&7);\n\treturn s;\n}\n\nstatic tjs_char *fmt_u(uintmax_t x, tjs_char *s)\n{\n\tunsigned long y;\n\tfor (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;\n\tfor (y=x;           y; y/=10) *--s = '0' + y%10;\n\treturn s;\n}\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nunion ldshape {\n    long double f;\n    struct {\n        uint64_t m;\n        uint16_t se;\n    } i;\n};\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 /*&& __BYTE_ORDER == __LITTLE_ENDIAN*/\nunion ldshape {\n    long double f;\n    struct {\n        uint64_t m;\n        uint16_t se;\n    } i;\n};\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 /*&& __BYTE_ORDER == __LITTLE_ENDIAN*/\nunion ldshape {\n    long double f;\n    struct {\n        uint64_t lo;\n        uint32_t mid;\n        uint16_t top;\n        uint16_t se;\n    } i;\n    struct {\n        uint64_t lo;\n        uint64_t hi;\n    } i2;\n};\n#else\n#error Unsupported long double representation\n#endif\nstatic unsigned __FLOAT_BITS(float __f)\n{\n    union {float __f; unsigned __i;} __u = {__f};\n    return __u.__i;\n}\nstatic __inline unsigned long long __DOUBLE_BITS(double __f)\n{\n    union {double __f; unsigned long long __i;} __u = {__f};\n    return __u.__i;\n}\n#ifdef signbit\n#undef signbit\n#endif\nint signbit(long double x)\n{\n    if(sizeof(x) == sizeof(float))\n        return (int)(__FLOAT_BITS(x)>>31);\n    if(sizeof(x) == sizeof(double))\n        return (int)(__DOUBLE_BITS(x)>>63);\n    ldshape u = {x};\n    return u.i.se >> 15;\n}\n    \n#ifndef FP_NAN\n#define FP_NAN       0\n#define FP_INFINITE  1\n#define FP_ZERO      2\n#define FP_SUBNORMAL 3\n#define FP_NORMAL    4\n#endif\n// #define isfinite(x) \\\n//         (sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \\\n//     sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \\\n//     __fpclassifyl(x) > FP_INFINITE)\n\nstatic int fmt_fp(_tFILE *f, long double y, int w, int p, int fl, int t)\n{\n    uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];\n    uint32_t *a, *d, *r, *z;\n    int e2=0, e, i, j, l;\n    tjs_char buf[9+LDBL_MANT_DIG/4], *s;\n    const tjs_char *prefix=TJS_W(\"-0X+0X 0X-0x+0x 0x\");\n    int pl;\n    tjs_char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;\n\n    pl=1;\n    if (signbit(y)) {\n        y=-y;\n    } else if (fl & MARK_POS) {\n        prefix+=3;\n    } else if (fl & PAD_POS) {\n        prefix+=6;\n    } else prefix++, pl=0;\n\n    if (!finite(y)) { // ## fix no member named 'isfinite' in namespace 'std'\n        const tjs_char *s = (t&32)?TJS_W(\"inf\"):TJS_W(\"INF\");\n        if (y!=y) s=(t&32)?TJS_W(\"nan\"):TJS_W(\"NAN\"), pl=0;\n        pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);\n        out(f, prefix, pl);\n        out(f, s, 3);\n        pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);\n        return MAX(w, 3+pl);\n    }\n\n    y = frexpl(y, &e2) * 2;\n    if (y) e2--;\n\n    if ((t|32)=='a') {\n        long double round = 8.0;\n        int re;\n\n        if (t&32) prefix += 9;\n        pl += 2;\n\n        if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;\n        else re=LDBL_MANT_DIG/4-1-p;\n\n        if (re) {\n            while (re--) round*=16;\n            if (*prefix=='-') {\n                y=-y;\n                y-=round;\n                y+=round;\n                y=-y;\n            } else {\n                y+=round;\n                y-=round;\n            }\n        }\n\n        estr=fmt_u(e2<0 ? -e2 : e2, ebuf);\n        if (estr==ebuf) *--estr='0';\n        *--estr = (e2<0 ? '-' : '+');\n        *--estr = t+('p'-'a');\n\n        s=buf;\n        do {\n            int x=y;\n            *s++=xdigits[x]|(t&32);\n            y=16*(y-x);\n            if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';\n        } while (y);\n\n        if (p && s-buf-2 < p)\n            l = (p+2) + (ebuf-estr);\n        else\n            l = (s-buf) + (ebuf-estr);\n\n        pad(f, ' ', w, pl+l, fl);\n        out(f, prefix, pl);\n        pad(f, '0', w, pl+l, fl^ZERO_PAD);\n        out(f, buf, s-buf);\n        pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);\n        out(f, estr, ebuf-estr);\n        pad(f, ' ', w, pl+l, fl^LEFT_ADJ);\n        return MAX(w, pl+l);\n    }\n    if (p<0) p=6;\n\n    if (y) y *= 0x1<<28, e2-=28;\n\n    if (e2<0) a=r=z=big;\n    else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;\n\n    do {\n        *z = y;\n        y = 1000000000*(y-*z++);\n    } while (y);\n\n    while (e2>0) {\n        uint32_t carry=0;\n        int sh=MIN(29,e2);\n        for (d=z-1; d>=a; d--) {\n            uint64_t x = ((uint64_t)*d<<sh)+carry;\n            *d = x % 1000000000;\n            carry = x / 1000000000;\n        }\n        if (!z[-1] && z>a) z--;\n        if (carry) *--a = carry;\n        e2-=sh;\n    }\n    while (e2<0) {\n        uint32_t carry=0, *b;\n        int sh=MIN(9,-e2);\n        for (d=a; d<z; d++) {\n            uint32_t rm = *d & (1<<sh)-1;\n            *d = (*d>>sh) + carry;\n            carry = (1000000000>>sh) * rm;\n        }\n        if (!*a) a++;\n        if (carry) *z++ = carry;\n        /* Avoid (slow!) computation past requested precision */\n        b = (t|32)=='f' ? r : a;\n        if (z-b > 2+p/9) z = b+2+p/9;\n        e2+=sh;\n    }\n\n    if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);\n    else e=0;\n\n    /* Perform rounding: j is precision after the radix (possibly neg) */\n    j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);\n    if (j < 9*(z-r-1)) {\n        uint32_t x;\n        /* We avoid C's broken division of negative numbers */\n        d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);\n        j += 9*LDBL_MAX_EXP;\n        j %= 9;\n        for (i=10, j++; j<9; i*=10, j++);\n        x = *d % i;\n        /* Are there any significant digits past j? */\n        if (x || d+1!=z) {\n            long double round = 0x1<<LDBL_MANT_DIG;\n            long double small;\n            if (*d/i & 1) round += 2;\n            if (x<i/2) small=0.5;\n            else if (x==i/2 && d+1==z) small=1.0;\n            else small=1.5;\n            if (pl && *prefix=='-') round*=-1, small*=-1;\n            *d -= x;\n            /* Decide whether to round by probing round+small */\n            if (round+small != round) {\n                *d = *d + i;\n                while (*d > 999999999) {\n                    *d--=0;\n                    (*d)++;\n                }\n                if (d<a) a=d;\n                for (i=10, e=9*(r-a); *a>=i; i*=10, e++);\n            }\n        }\n        if (z>d+1) z=d+1;\n        for (; !z[-1] && z>a; z--);\n    }\n\n    if ((t|32)=='g') {\n        if (!p) p++;\n        if (p>e && e>=-4) {\n            t--;\n            p-=e+1;\n        } else {\n            t-=2;\n            p--;\n        }\n        if (!(fl&ALT_FORM)) {\n            /* Count trailing zeros in last place */\n            if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);\n            else j=9;\n            if ((t|32)=='f')\n                p = MIN(p,MAX(0,9*(z-r-1)-j));\n            else\n                p = MIN(p,MAX(0,9*(z-r-1)+e-j));\n        }\n    }\n    l = 1 + p + (p || (fl&ALT_FORM));\n    if ((t|32)=='f') {\n        if (e>0) l+=e;\n    } else {\n        estr=fmt_u(e<0 ? -e : e, ebuf);\n        while(ebuf-estr<2) *--estr='0';\n        *--estr = (e<0 ? '-' : '+');\n        *--estr = t;\n        l += ebuf-estr;\n    }\n\n    pad(f, ' ', w, pl+l, fl);\n    out(f, prefix, pl);\n    pad(f, '0', w, pl+l, fl^ZERO_PAD);\n\n    if ((t|32)=='f') {\n        if (a>r) a=r;\n        for (d=a; d<=r; d++) {\n            tjs_char *s = fmt_u(*d, buf+9);\n            if (d!=a) while (s>buf) *--s='0';\n            else if (s==buf+9) *--s='0';\n            out(f, s, buf+9-s);\n        }\n        if (p || (fl&ALT_FORM)) out(f, TJS_W(\".\"), 1);\n        for (; d<z && p>0; d++, p-=9) {\n            tjs_char *s = fmt_u(*d, buf+9);\n            while (s>buf) *--s='0';\n            out(f, s, MIN(9,p));\n        }\n        pad(f, '0', p+9, 9, 0);\n    } else {\n        if (z<=a) z=a+1;\n        for (d=a; d<z && p>=0; d++) {\n            tjs_char *s = fmt_u(*d, buf+9);\n            if (s==buf+9) *--s='0';\n            if (d!=a) while (s>buf) *--s='0';\n            else {\n                out(f, s++, 1);\n                if (p>0||(fl&ALT_FORM)) out(f, TJS_W(\".\"), 1);\n            }\n            out(f, s, MIN(buf+9-s, p));\n            p -= buf+9-s;\n        }\n        pad(f, '0', p+18, 18, 0);\n        out(f, estr, ebuf-estr);\n    }\n\n    pad(f, ' ', w, pl+l, fl^LEFT_ADJ);\n\n    return MAX(w, pl+l);\n}\n\nstatic int getint(tjs_char **s) {\n    int i;\n    for (i=0; isdigit(**s); (*s)++)\n        i = 10*i + (**s-'0');\n    return i;\n}\n\nstatic int printf_core(_tFILE *f, const tjs_char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)\n{\n    tjs_char *a, *z, *s=(tjs_char *)fmt;\n    unsigned l10n=0, fl;\n    int w, p;\n    union arg arg;\n    int argpos;\n    unsigned st, ps;\n    int cnt=0, l=0;\n    int i;\n    tjs_char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];\n    const tjs_char *prefix;\n    int t, pl;\n    tjs_char wc[2], *ws;\n    tjs_char mb[4];\n\n    for (;;) {\n        /* Update output count, end loop when fmt is exhausted */\n        if (cnt >= 0) {\n            if (l > INT_MAX - cnt) {\n                errno = EOVERFLOW;\n                cnt = -1;\n            } else cnt += l;\n        }\n        if (!*s) break;\n\n        /* Handle literal text and %% format specifiers */\n        for (a=s; *s && *s!='%'; s++);\n        for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);\n        l = z-a;\n        if (f) out(f, a, l);\n        if (l) continue;\n\n        if (isdigit(s[1]) && s[2]=='$') {\n            l10n=1;\n            argpos = s[1]-'0';\n            s+=3;\n        } else {\n            argpos = -1;\n            s++;\n        }\n\n        /* Read modifier flags */\n        for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<(*s-' '))); s++)\n            fl |= 1U<<(*s-' ');\n\n        /* Read field width */\n        if (*s=='*') {\n            if (isdigit(s[1]) && s[2]=='$') {\n                l10n=1;\n                nl_type[s[1]-'0'] = INT;\n                w = nl_arg[s[1]-'0'].i;\n                s+=3;\n            } else if (!l10n) {\n                w = f ? va_arg(*ap, int) : 0;\n                s++;\n            } else return -1;\n            if (w<0) fl|=LEFT_ADJ, w=-w;\n        } else if ((w=getint(&s))<0) return -1;\n\n        /* Read precision */\n        if (*s=='.' && s[1]=='*') {\n            if (isdigit(s[2]) && s[3]=='$') {\n                nl_type[s[2]-'0'] = INT;\n                p = nl_arg[s[2]-'0'].i;\n                s+=4;\n            } else if (!l10n) {\n                p = f ? va_arg(*ap, int) : 0;\n                s+=2;\n            } else return -1;\n        } else if (*s=='.') {\n            s++;\n            p = getint(&s);\n        } else p = -1;\n\n        /* Format specifier state machine */\n        st=0;\n        do {\n            if (OOB(*s)) return -1;\n            ps=st;\n            st=states[st]S(*s++);\n        } while (st-1<STOP);\n        if (!st) return -1;\n\n        /* Check validity of argument type (nl/normal) */\n        if (st==NOARG) {\n            if (argpos>=0) return -1;\n            else if (!f) continue;\n        } else {\n            if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];\n            else if (f) pop_arg(&arg, st, ap);\n            else return 0;\n        }\n\n        if (!f) continue;\n\n        z = buf + sizeof(buf) / sizeof(buf[0]);\n        prefix = TJS_W(\"-+   0X0x\");\n        pl = 0;\n        t = s[-1];\n\n        /* Transform ls,lc -> S,C */\n        if (ps && (t&15)==3) t&=~32;\n\n        /* - and 0 flags are mutually exclusive */\n        if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;\n\n        switch(t) {\n        case 'n':\n            switch(ps) {\n            case BARE: *(int *)arg.p = cnt; break;\n            case LPRE: *(long *)arg.p = cnt; break;\n            case LLPRE: *(long long *)arg.p = cnt; break;\n            case HPRE: *(unsigned short *)arg.p = cnt; break;\n            case HHPRE: *(unsigned char *)arg.p = cnt; break;\n            case ZTPRE: *(size_t *)arg.p = cnt; break;\n            case JPRE: *(uintmax_t *)arg.p = cnt; break;\n            }\n            continue;\n        case 'p':\n            p = MAX(p, 2*sizeof(void*));\n            t = 'x';\n            fl |= ALT_FORM;\n        case 'x': case 'X':\n            a = fmt_x(arg.i, z, t&32);\n            if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;\n            if (0) {\n        case 'o':\n            a = fmt_o(arg.i, z);\n            if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;\n            } if (0) {\n        case 'd': case 'i':\n            pl=1;\n            if (arg.i>INTMAX_MAX) {\n                arg.i=-arg.i;\n            } else if (fl & MARK_POS) {\n                prefix++;\n            } else if (fl & PAD_POS) {\n                prefix+=2;\n            } else pl=0;\n        case 'u':\n            a = fmt_u(arg.i, z);\n            }\n            if (p>=0) fl &= ~ZERO_PAD;\n            if (!arg.i && !p) {\n                a=z;\n                break;\n            }\n            p = MAX(p, z-a + !arg.i);\n            break;\n        case 'c':\n            *(a=z-(p=1))=arg.i;\n            fl &= ~ZERO_PAD;\n            break;\n//         case 'm':\n//             if (1) a = strerror(errno); else\n        case 's':\n        case 'S':\n            z = a = arg.p ? (tjs_char*)arg.p : (tjs_char*)TJS_W(\"(null)\");\n            while(*z) z++;\n            //z = (tjs_char*)memchr(a, 0, p);\n            if (!z) z=a+p;\n            else p=z-a;\n            fl &= ~ZERO_PAD;\n            break;\n        case 'C':\n            wc[0] = arg.i;\n            wc[1] = 0;\n            arg.p = wc;\n            p = -1;\n//         case 'S':\n//             ws = (wchar_t*)arg.p;\n//             for (i=l=0; i<0U+p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=0U+p-i; i+=l);\n//             if (l<0) return -1;\n//             p = i;\n//             pad(f, ' ', w, p, fl);\n//             ws = (wchar_t*)arg.p;\n//             for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)\n//                 out(f, mb, l);\n//             pad(f, ' ', w, p, fl^LEFT_ADJ);\n//             l = w>p ? w : p;\n//             continue;\n        case 'e': case 'f': case 'g': case 'a':\n        case 'E': case 'F': case 'G': case 'A':\n            l = fmt_fp(f, arg.f, w, p, fl, t);\n            continue;\n        }\n\n        if (p < z-a) p = z-a;\n        if (w < pl+p) w = pl+p;\n\n        pad(f, ' ', w, pl+p, fl);\n        out(f, prefix, pl);\n        pad(f, '0', w, pl+p, fl^ZERO_PAD);\n        pad(f, '0', p, z-a, 0);\n        out(f, a, z-a);\n        pad(f, ' ', w, pl+p, fl^LEFT_ADJ);\n\n        l = w;\n    }\n\n    out(f, TJS_W(\"\"), 1);\n    if (f) return cnt;\n    if (!l10n) return 0;\n\n    for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)\n        pop_arg(nl_arg+i, nl_type[i], ap);\n    for (; i<=NL_ARGMAX && !nl_type[i]; i++);\n    if (i<=NL_ARGMAX) return -1;\n    return 1;\n}\n\nint _vsnprintf(tjs_char * s, size_t n, const tjs_char * fmt, va_list ap)\n{\n    int r;\n    _tFILE f = {s };\n    \n    int nl_type[NL_ARGMAX+1] = {0};\n    union arg nl_arg[NL_ARGMAX+1];\n    unsigned char internal_buf[80], *saved_buf = 0;\n    va_list *pap = (va_list *)&ap;\n    r = printf_core(&f, fmt, pap, nl_arg, nl_type);\n\n    /* Null-terminate, overwriting last char if dest buffer is full */\n    return r;\n}\n\nstatic int snprintf(tjs_char *s, size_t n, const tjs_char *fmt, ...)\n{\n    int ret;\n    va_list ap;\n    va_start(ap, fmt);\n    ret = _vsnprintf(s, n, fmt, ap);\n    va_end(ap);\n    return ret;\n}\n\nstatic int is_leap(int y)\n{\n    /* Avoid overflow */\n    if (y>INT_MAX-1900) y -= 2000;\n    y += 1900;\n    return !(y%4) && ((y%100) || !(y%400));\n}\n\nstatic int week_num(const tm *tm)\n{\n\tint val = (tm->tm_yday + 7 - (tm->tm_wday+6)%7) / 7;\n\t/* If 1 Jan is just 1-3 days past Monday,\n\t * the previous week is also in this year. */\n\tif ((tm->tm_wday - tm->tm_yday - 2 + 371) % 7 <= 2)\n\t\tval++;\n\tif (!val) {\n\t\tval = 52;\n\t\t/* If 31 December of prev year a Thursday,\n\t\t * or Friday of a leap year, then the\n\t\t * prev year has 53 weeks. */\n\t\tint dec31 = (tm->tm_wday - tm->tm_yday - 1 + 7) % 7;\n\t\tif (dec31 == 4 || (dec31 == 5 && is_leap(tm->tm_year%400-1)))\n\t\t\tval++;\n\t} else if (val == 53) {\n\t\t/* If 1 January is not a Thursday, and not\n\t\t * a Wednesday of a leap year, then this\n\t\t * year has only 52 weeks. */\n\t\tint jan1 = (tm->tm_wday - tm->tm_yday + 371) % 7;\n\t\tif (jan1 != 4 && (jan1 != 3 || !is_leap(tm->tm_year)))\n\t\t\tval = 1;\n\t}\n\treturn val;\n}\n#define ABDAY_1 0x20000\n#define ABDAY_2 0x20001\n#define ABDAY_3 0x20002\n#define ABDAY_4 0x20003\n#define ABDAY_5 0x20004\n#define ABDAY_6 0x20005\n#define ABDAY_7 0x20006\n\n#define DAY_1 0x20007\n#define DAY_2 0x20008\n#define DAY_3 0x20009\n#define DAY_4 0x2000A\n#define DAY_5 0x2000B\n#define DAY_6 0x2000C\n#define DAY_7 0x2000D\n\n#define ABMON_1 0x2000E\n#define ABMON_2 0x2000F\n#define ABMON_3 0x20010\n#define ABMON_4 0x20011\n#define ABMON_5 0x20012\n#define ABMON_6 0x20013\n#define ABMON_7 0x20014\n#define ABMON_8 0x20015\n#define ABMON_9 0x20016\n#define ABMON_10 0x20017\n#define ABMON_11 0x20018\n#define ABMON_12 0x20019\n\n#define MON_1 0x2001A\n#define MON_2 0x2001B\n#define MON_3 0x2001C\n#define MON_4 0x2001D\n#define MON_5 0x2001E\n#define MON_6 0x2001F\n#define MON_7 0x20020\n#define MON_8 0x20021\n#define MON_9 0x20022\n#define MON_10 0x20023\n#define MON_11 0x20024\n#define MON_12 0x20025\n\n#define AM_STR 0x20026\n#define PM_STR 0x20027\n\n#define D_T_FMT 0x20028\n#define D_FMT 0x20029\n#define T_FMT 0x2002A\n#define T_FMT_AMPM 0x2002B\n\n#define ERA 0x2002C\n#define ERA_D_FMT 0x2002E\n#define ALT_DIGITS 0x2002F\n#define ERA_D_T_FMT 0x20030\n#define ERA_T_FMT 0x20031\n\n#define CODESET 14\n\n#define CRNCYSTR 0x4000F\n\n#define RADIXCHAR 0x10000\n#define THOUSEP 0x10001\n#define YESEXPR 0x50000\n#define NOEXPR 0x50001\n#define YESSTR 0x50002\n#define NOSTR 0x50003\nlong long __year_to_secs(long long year, int *is_leap)\n{\n    if (year-2ULL <= 136) {\n        int y = year;\n        int leaps = (y-68)>>2;\n        if (!((y-68)&3)) {\n            leaps--;\n            if (is_leap) *is_leap = 1;\n        } else if (is_leap) *is_leap = 0;\n        return 31536000*(y-70) + 86400*leaps;\n    }\n\n    int cycles, centuries, leaps, rem;\n    int z = 0;\n    if (!is_leap) is_leap = &z;\n    cycles = (year-100) / 400;\n    rem = (year-100) % 400;\n    if (rem < 0) {\n        cycles--;\n        rem += 400;\n    }\n    if (!rem) {\n        *is_leap = 1;\n        centuries = 0;\n        leaps = 0;\n    } else {\n        if (rem >= 200) {\n            if (rem >= 300) centuries = 3, rem -= 300;\n            else centuries = 2, rem -= 200;\n        } else {\n            if (rem >= 100) centuries = 1, rem -= 100;\n            else centuries = 0;\n        }\n        if (!rem) {\n            *is_leap = 0;\n            leaps = 0;\n        } else {\n            leaps = rem / 4U;\n            rem %= 4U;\n            *is_leap = !rem;\n        }\n    }\n\n    leaps += 97*cycles + 24*centuries - *is_leap;\n\n    return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;\n}\n\nint __month_to_secs(int month, int is_leap)\n{\n    static const int secs_through_month[] = {\n        0, 31*86400, 59*86400, 90*86400,\n        120*86400, 151*86400, 181*86400, 212*86400,\n        243*86400, 273*86400, 304*86400, 334*86400 };\n    int t = secs_through_month[month];\n    if (is_leap && month >= 2) t+=86400;\n    return t;\n}\n\nlong long __tm_to_secs(const tm *tm)\n{\n    int is_leap;\n    long long year = tm->tm_year;\n    int month = tm->tm_mon;\n    if (month >= 12 || month < 0) {\n        int adj = month / 12;\n        month %= 12;\n        if (month < 0) {\n            adj--;\n            month += 12;\n        }\n        year += adj;\n    }\n    long long t = __year_to_secs(year, &is_leap);\n    t += __month_to_secs(month, is_leap);\n    t += 86400LL * (tm->tm_mday-1);\n    t += 3600LL * tm->tm_hour;\n    t += 60LL * tm->tm_min;\n    t += tm->tm_sec;\n    return t;\n}\n\nstatic const tjs_char c_time[] = \n    TJS_W(\"Sun\\0\" ) TJS_W(\"Mon\\0\") TJS_W( \"Tue\\0\" ) TJS_W(\"Wed\\0\" ) TJS_W(\"Thu\\0\" ) TJS_W(\"Fri\\0\" ) TJS_W(\"Sat\\0\")\n    TJS_W(\"Sunday\\0\") TJS_W( \"Monday\\0\") TJS_W( \"Tuesday\\0\" ) TJS_W(\"Wednesday\\0\")\n    TJS_W(\"Thursday\\0\") TJS_W( \"Friday\\0\") TJS_W(\"Saturday\\0\")\n    TJS_W(\"Jan\\0\") TJS_W( \"Feb\\0\") TJS_W( \"Mar\\0\") TJS_W(\"Apr\\0\" ) TJS_W(\"May\\0\" ) TJS_W(\"Jun\\0\")\n    TJS_W(\"Jul\\0\") TJS_W( \"Aug\\0\") TJS_W( \"Sep\\0\") TJS_W(\"Oct\\0\" ) TJS_W(\"Nov\\0\" ) TJS_W(\"Dec\\0\")\n    TJS_W(\"January\\0\" ) TJS_W(  \"February\\0\") TJS_W( \"March\\0\"    ) TJS_W(\"April\\0\"     )\n    TJS_W(\"May\\0\"   ) TJS_W(    \"June\\0\"    ) TJS_W( \"July\\0\"     ) TJS_W(\"August\\0\"    )\n    TJS_W(\"September\\0\" ) TJS_W(\"October\\0\" ) TJS_W( \"November\\0\" ) TJS_W(\"December\\0\"  )\n    TJS_W(\"AM\\0\") TJS_W(\"PM\\0\")\n    TJS_W(\"%a %b %e %T %Y\\0\")\n    TJS_W(\"%m/%d/%y\\0\"      )\n    TJS_W(\"%H:%M:%S\\0\"      )\n    TJS_W(\"%I:%M:%S %p\\0\"   )\n    TJS_W(\"\\0\"              )\n    TJS_W(\"%m/%d/%y\\0\"      )\n    TJS_W(\"0123456789\"      )\n    TJS_W(\"%a %b %e %T %Y\\0\")\n    TJS_W(\"%H:%M:%S\"        );\n\nstatic const tjs_char c_messages[] = TJS_W(\"^[yY]\\0\") TJS_W( \"^[nN]\");\nstatic const tjs_char c_numeric[] = TJS_W(\".\\0\") TJS_W( \"\");\n\nconst tjs_char *__nl_langinfo_l(int item/*, locale_t loc*/)\n{\n    int cat = item >> 16;\n    int idx = item & 65535;\n    const tjs_char *str;\n\n    if (item == CODESET) return TJS_W(\"UTF-8\");\n\n    switch (cat) {\n    case LC_NUMERIC:\n        if (idx > 1) return NULL;\n        str = c_numeric;\n        break;\n    case 2:\n        if (idx > 0x31) return NULL;\n        str = c_time;\n        break;\n    case LC_MONETARY:\n        if (idx > 0) return NULL;\n        str = TJS_W(\"\");\n        break;\n//     case LC_MESSAGES:\n//         if (idx > 1) return NULL;\n//         str = c_messages;\n//         break;\n    default:\n        return NULL;\n    }\n\n    for (; idx; idx--, str++) for (; *str; str++);\n    return (tjs_char *)str;\n}\n\nsize_t __strftime_l(tjs_char *s, size_t n, const tjs_char *f, const tm *tm);\nconst tjs_char *__strftime_fmt_1(tjs_char (*s)[100], size_t *l, int f, const tm *tm)\n{\n    int item;\n    long long val;\n    const tjs_char *fmt;\n    int width = 2;\n\n    switch (f) {\n    case 'a':\n        item = ABDAY_1 + tm->tm_wday;\n        goto nl_strcat;\n    case 'A':\n        item = DAY_1 + tm->tm_wday;\n        goto nl_strcat;\n    case 'h':\n    case 'b':\n        item = ABMON_1 + tm->tm_mon;\n        goto nl_strcat;\n    case 'B':\n        item = MON_1 + tm->tm_mon;\n        goto nl_strcat;\n    case 'c':\n        item = D_T_FMT;\n        goto nl_strftime;\n    case 'C':\n        val = (1900LL+tm->tm_year) / 100;\n        goto number;\n    case 'd':\n        val = tm->tm_mday;\n        goto number;\n    case 'D':\n        fmt = TJS_W(\"%m/%d/%y\");\n        goto recu_strftime;\n    case 'e':\n        *l = snprintf(*s, sizeof *s, TJS_W(\"%2d\"), tm->tm_mday);\n        return *s;\n    case 'F':\n        fmt = TJS_W(\"%Y-%m-%d\");\n        goto recu_strftime;\n    case 'g':\n    case 'G':\n        val = tm->tm_year + 1900LL;\n        if (tm->tm_yday < 3 && week_num(tm) != 1) val--;\n        else if (tm->tm_yday > 360 && week_num(tm) == 1) val++;\n        if (f=='g') val %= 100;\n        else width = 4;\n        goto number;\n    case 'H':\n        val = tm->tm_hour;\n        goto number;\n    case 'I':\n        val = tm->tm_hour;\n        if (!val) val = 12;\n        else if (val > 12) val -= 12;\n        goto number;\n    case 'j':\n        val = tm->tm_yday+1;\n        width = 3;\n        goto number;\n    case 'm':\n        val = tm->tm_mon+1;\n        goto number;\n    case 'M':\n        val = tm->tm_min;\n        goto number;\n    case 'n':\n        *l = 1;\n        return TJS_W(\"\\n\");\n    case 'p':\n        item = tm->tm_hour >= 12 ? PM_STR : AM_STR;\n        goto nl_strcat;\n    case 'r':\n        item = T_FMT_AMPM;\n        goto nl_strftime;\n    case 'R':\n        fmt = TJS_W(\"%H:%M\");\n        goto recu_strftime;\n    case 's':\n        val = __tm_to_secs(tm) /*+ tm->__tm_gmtoff*/;\n        goto number;\n    case 'S':\n        val = tm->tm_sec;\n        goto number;\n    case 't':\n        *l = 1;\n        return TJS_W(\"\\t\");\n    case 'T':\n        fmt = TJS_W(\"%H:%M:%S\");\n        goto recu_strftime;\n    case 'u':\n        val = tm->tm_wday ? tm->tm_wday : 7;\n        width = 1;\n        goto number;\n    case 'U':\n        val = (tm->tm_yday + 7 - tm->tm_wday) / 7;\n        goto number;\n    case 'W':\n        val = (tm->tm_yday + 7 - (tm->tm_wday+6)%7) / 7;\n        goto number;\n    case 'V':\n        val = week_num(tm);\n        goto number;\n    case 'w':\n        val = tm->tm_wday;\n        width = 1;\n        goto number;\n    case 'x':\n        item = D_FMT;\n        goto nl_strftime;\n    case 'X':\n        item = T_FMT;\n        goto nl_strftime;\n    case 'y':\n        val = tm->tm_year % 100;\n        goto number;\n    case 'Y':\n        val = tm->tm_year + 1900;\n        if (val >= 10000) {\n            *l = snprintf(*s, sizeof *s, TJS_W(\"+%lld\"), val);\n            return *s;\n        }\n        width = 4;\n        goto number;\n//     case 'z':\n//         if (tm->tm_isdst < 0) {\n//             *l = 0;\n//             return \"\";\n//         }\n//         *l = snprintf(*s, sizeof *s, \"%+.2d%.2d\",\n//             (-tm->__tm_gmtoff)/3600,\n//             abs(tm->__tm_gmtoff%3600)/60);\n//         return *s;\n//     case 'Z':\n//         if (tm->tm_isdst < 0) {\n//             *l = 0;\n//             return \"\";\n//         }\n//         fmt = __tm_to_tzname(tm);\n//         goto string;\n    case '%':\n        *l = 1;\n        return TJS_W(\"%\");\n    default:\n        return 0;\n    }\nnumber:\n    *l = snprintf(*s, sizeof *s, TJS_W(\"%0*lld\"), width, val);\n    return *s;\nnl_strcat:\n    fmt = __nl_langinfo_l(item);\nstring:\n    *l = TJS_strlen(fmt);\n    return fmt;\nnl_strftime:\n    fmt = __nl_langinfo_l(item);\nrecu_strftime:\n    *l = __strftime_l(*s, sizeof *s, fmt, tm);\n    if (!*l) return 0;\n    return *s;\n}\n/* Lookup table for digit values. -1==255>=36 -> invalid */\nstatic const unsigned char table[] = { 255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255,\n    255,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\n    25,26,27,28,29,30,31,32,33,34,35,255,255,255,255,255,\n    255,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\n    25,26,27,28,29,30,31,32,33,34,35,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n};\nint shgetc(_tFILE *f) {return *f->p++;}\nvoid shunget(_tFILE *f) {f->p--;}\nunsigned long long __intscan(_tFILE *f, unsigned base, int pok, unsigned long long lim)\n{\n    const unsigned char *val = table+1;\n    int c, neg=0;\n    unsigned x;\n    unsigned long long y;\n    if (base > 36) {\n        errno = EINVAL;\n        return 0;\n    }\n    while (isspace((c=shgetc(f))));\n    if (c=='+' || c=='-') {\n        neg = -(c=='-');\n        c = shgetc(f);\n    }\n    if ((base == 0 || base == 16) && c=='0') {\n        c = shgetc(f);\n        if ((c|32)=='x') {\n            c = shgetc(f);\n            if (val[c]>=16) {\n                shunget(f);\n                if (pok) shunget(f);\n//                else shlim(f, 0);\n                return 0;\n            }\n            base = 16;\n        } else if (base == 0) {\n            base = 8;\n        }\n    } else {\n        if (base == 0) base = 10;\n        if (val[c] >= base) {\n            shunget(f);\n//            shlim(f, 0);\n            errno = EINVAL;\n            return 0;\n        }\n    }\n    if (base == 10) {\n        for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))\n            x = x*10 + (c-'0');\n        for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))\n            y = y*10 + (c-'0');\n        if (c-'0'>=10U) goto done;\n    } else if (!(base & base-1)) {\n        int bs = \"\\0\\1\\2\\4\\7\\3\\6\\5\"[(0x17*base)>>5&7];\n        for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))\n            x = x<<bs | val[c];\n        for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))\n            y = y<<bs | val[c];\n    } else {\n        for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))\n            x = x*base + val[c];\n        for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))\n            y = y*base + val[c];\n    }\n    if (val[c]<base) {\n        for (; val[c]<base; c=shgetc(f));\n        errno = ERANGE;\n        y = lim;\n    }\ndone:\n    shunget(f);\n    if (y>=lim) {\n        if (!(lim&1) && !neg) {\n            errno = ERANGE;\n            return lim-1;\n        } else if (y>lim) {\n            errno = ERANGE;\n            return lim;\n        }\n    }\n    return (y^neg)-neg;\n}\n\nstatic unsigned long long strtox(const tjs_char *s, tjs_char **p, int base, unsigned long long lim)\n{\n    /* FIXME: use a helper function or macro to setup the FILE */\n    _tFILE f = {(tjs_char*)s};\n    unsigned long long ret = __intscan(&f, base, 1, lim);\n    if(p) *p = f.p;\n    return ret;\n}\nsize_t __strftime_l(tjs_char *s, size_t n, const tjs_char *f, const tm *tm)\n{\n    size_t l, k;\n    tjs_char buf[100];\n    tjs_char *p;\n    const tjs_char *t;\n    int plus;\n    unsigned long width;\n    for (l=0; l+1<n; f++) {\n        if (!*f) {\n            s[l] = 0;\n            return l;\n        }\n        if (*f != '%') {\n            s[l++] = *f;\n            continue;\n        }\n        f++;\n        if ((plus = (*f == '+'))) f++;\n        width = strtox(f, &p, 10, -999);\n        if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {\n            if (!width && p!=f) width = 1;\n            if (width >= n-l) return 0;\n        } else {\n            width = 0;\n        }\n        f = p;\n        if (*f == 'E' || *f == 'O') f++;\n        t = __strftime_fmt_1(&buf, &k, *f, tm);\n        if (!t) return 0;\n        if (width) {\n            for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);\n            width--;\n            if (plus && tm->tm_year >= 10000-1900)\n                s[l++] = '+';\n            else if (tm->tm_year < -1900)\n                s[l++] = '-';\n            else\n                width++;\n            if (width >= n-l) return 0;\n            for (; width > k; width--)\n                s[l++] = '0';\n        }\n        if (k >= n-l) return 0;\n        memcpy(s+l, t, k * sizeof(*t));\n        l += k;\n    }\n    return 0;\n}\n\ndouble TJS_strtod(const tjs_char* string, tjs_char** endPtr)\n{\n#if defined (_MSC_VER) && defined(_DEBUG)\n\tdouble testret = wcstod(string, endPtr);\n#endif\n\tint sign, expSign = false;\n\tdouble fraction, dblExp;\n\tconst double *d;\n\tconst tjs_char *p;\n\tint c;\n\tint exp = 0;\t\t/* Exponent read from \"EX\" field. */\n\tint fracExp = 0;\t\t/* Exponent that derives from the fractional\n\t\t\t\t\t\t\t* part.  Under normal circumstatnces, it is\n\t\t\t\t\t\t\t* the negative of the number of digits in F.\n\t\t\t\t\t\t\t* However, if I is very long, the last digits\n\t\t\t\t\t\t\t* of I get dropped (otherwise a long I with a\n\t\t\t\t\t\t\t* large negative exponent could cause an\n\t\t\t\t\t\t\t* unnecessary overflow on I alone).  In this\n\t\t\t\t\t\t\t* case, fracExp is incremented one for each\n\t\t\t\t\t\t\t* dropped digit. */\n\tint mantSize;\t\t/* Number of digits in mantissa. */\n\tint decPt;\t\t\t/* Number of mantissa digits BEFORE decimal\n\t\t\t\t\t\t* point. */\n\tconst tjs_char *pExp;\t\t/* Temporarily holds location of exponent\n\t\t\t\t\t\t\t* in string. */\n\tstatic const int maxExponent = 511;\n\tstatic const double powersOf10[] = {\t/* Table giving binary powers of 10.  Entry */\n\t\t10.,\t\t\t/* is 10^2^i.  Used to convert decimal */\n\t\t100.,\t\t\t/* exponents into floating-point numbers. */\n\t\t1.0e4,\n\t\t1.0e8,\n\t\t1.0e16,\n\t\t1.0e32,\n\t\t1.0e64,\n\t\t1.0e128,\n\t\t1.0e256\n\t};\n\t/*\n\t* Strip off leading blanks and check for a sign.\n\t*/\n\n\tp = string;\n\twhile (isspace((*p))) {\n\t\tp += 1;\n\t}\n\tif (*p == '-') {\n\t\tsign = true;\n\t\tp += 1;\n\t} else {\n\t\tif (*p == '+') {\n\t\t\tp += 1;\n\t\t}\n\t\tsign = false;\n\t}\n\n\t/*\n\t* Count the number of digits in the mantissa (including the decimal\n\t* point), and also locate the decimal point.\n\t*/\n\n\tdecPt = -1;\n\tfor (mantSize = 0;; mantSize += 1)\n\t{\n\t\tc = *p;\n\t\tif (!isdigit(c)) {\n\t\t\tif ((c != '.') || (decPt >= 0)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdecPt = mantSize;\n\t\t}\n\t\tp += 1;\n\t}\n\n\t/*\n\t* Now suck up the digits in the mantissa.  Use two integers to\n\t* collect 9 digits each (this is faster than using floating-point).\n\t* If the mantissa has more than 18 digits, ignore the extras, since\n\t* they can't affect the value anyway.\n\t*/\n\n\tpExp = p;\n\tp -= mantSize;\n\tif (decPt < 0) {\n\t\tdecPt = mantSize;\n\t} else {\n\t\tmantSize -= 1;\t\t\t/* One of the digits was the point. */\n\t}\n\tif (mantSize > 48) {\n\t\tfracExp = decPt - 48;\n\t\tmantSize = 48;\n\t} else {\n\t\tfracExp = decPt - mantSize;\n\t}\n\tif (mantSize == 0) {\n\t\tfraction = 0.0;\n\t\tp = string;\n\t\tgoto done;\n\t} else {\n\t\tint frac1, frac2;\n\t\tfrac1 = 0;\n\t\tfor (; mantSize > 9; mantSize -= 1)\n\t\t{\n\t\t\tc = *p;\n\t\t\tp += 1;\n\t\t\tif (c == '.') {\n\t\t\t\tc = *p;\n\t\t\t\tp += 1;\n\t\t\t}\n\t\t\tfrac1 = 10 * frac1 + (c - '0');\n\t\t}\n\t\tfrac2 = 0;\n\t\tfor (; mantSize > 0; mantSize -= 1)\n\t\t{\n\t\t\tc = *p;\n\t\t\tp += 1;\n\t\t\tif (c == '.') {\n\t\t\t\tc = *p;\n\t\t\t\tp += 1;\n\t\t\t}\n\t\t\tfrac2 = 10 * frac2 + (c - '0');\n\t\t}\n\t\tfraction = (1.0e9 * frac1) + frac2;\n\t}\n\n\t/*\n\t* Skim off the exponent.\n\t*/\n\n\tp = pExp;\n\tif ((*p == 'E') || (*p == 'e')) {\n\t\tp += 1;\n\t\tif (*p == '-') {\n\t\t\texpSign = true;\n\t\t\tp += 1;\n\t\t} else {\n\t\t\tif (*p == '+') {\n\t\t\t\tp += 1;\n\t\t\t}\n\t\t\texpSign = false;\n\t\t}\n\t\tif (!isdigit((*p))) {\n\t\t\tp = pExp;\n\t\t\tgoto done;\n\t\t}\n\t\twhile (isdigit((*p))) {\n\t\t\texp = exp * 10 + (*p - '0');\n\t\t\tp += 1;\n\t\t}\n\t}\n\tif (expSign) {\n\t\texp = fracExp - exp;\n\t} else {\n\t\texp = fracExp + exp;\n\t}\n\n\t/*\n\t* Generate a floating-point number that represents the exponent.\n\t* Do this by processing the exponent one bit at a time to combine\n\t* many powers of 2 of 10. Then combine the exponent with the\n\t* fraction.\n\t*/\n\n\tif (exp < 0) {\n\t\texpSign = true;\n\t\texp = -exp;\n\t} else {\n\t\texpSign = false;\n\t}\n\tif (exp > maxExponent) {\n\t\texp = maxExponent;\n\t\terrno = ERANGE;\n\t}\n\tdblExp = 1.0;\n\tfor (d = powersOf10; exp != 0; exp >>= 1, d += 1) {\n\t\tif (exp & 01) {\n\t\t\tdblExp *= *d;\n\t\t}\n\t}\n\tif (expSign) {\n\t\tfraction /= dblExp;\n\t} else {\n\t\tfraction *= dblExp;\n\t}\n\ndone:\n\tif (endPtr != NULL) {\n\t\t*endPtr = (tjs_char*)p;\n\t}\n\n\tif (sign) {\n\t\treturn -fraction;\n\t}\n#if defined (_MSC_VER) && defined(_DEBUG)\n\tassert(fraction == testret);\n#endif\n\treturn fraction;\n}\n\nsize_t TJS_strftime( tjs_char *wstring, size_t maxsize, const tjs_char *wformat, const tm *timeptr )\n{\n    return __strftime_l(wstring, maxsize, wformat, (tm*)timeptr);\n}\n\nint TJS_vsnprintf( tjs_char *string, size_t count, const tjs_char *format, va_list ap )\n{\n    \n    return _vsnprintf(string, count, format, ap);\n}\n\ntjs_int TJS_snprintf(tjs_char *s, size_t count, const tjs_char *format, ...)\n{\n\ttjs_int r;\n\tva_list param;\n\tva_start(param, format);\n\tr = TJS_vsnprintf(s, count, format, param);\n\tva_end(param);\n\treturn r;\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsConfig.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// configuration\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n\n#ifndef tjsConfigH\n#define tjsConfigH\n#include \"stdarg.h\"\n#include <wchar.h>\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n\n\n/*\n\tmany settings can be changed here.\n\n\ttjsCommHead.h includes most common headers that will be needed to\n\tcompile the entire TJS program.\n\n\tconfiguration about Critical Section for multithreading support is there in\n\ttjsUtils.cpp/h.\n*/\n\n// TODO: autoconf integration\n\n#include \"tjsTypes.h\"\n\n\n// #define TJS_NO_AVOID_ISWDIGIT\n// #define TJS_SUPPORT_VCL\n// #define TJS_MSG_EMPTY\n// #define TJS_DEBUG_TRACE\n// #define TJS_JP_LOCALIZED\n// #define TJS_TEXT_OUT_CRLF\n// #define TJS_WITH_IS_NOT_RESERVED_WORD\n\nTJS_EXP_FUNC_DEF(tjs_int, TJS_atoi, (const tjs_char *s));\nTJS_EXP_FUNC_DEF(tjs_char *, TJS_int_to_str, (tjs_int value, tjs_char *string));\nTJS_EXP_FUNC_DEF(tjs_char *, TJS_tTVInt_to_str, (tjs_int64 value, tjs_char *string));\nTJS_EXP_FUNC_DEF(tjs_int, TJS_strnicmp, (const tjs_char *s1, const tjs_char *s2, size_t maxlen));\nTJS_EXP_FUNC_DEF(tjs_int, TJS_stricmp, (const tjs_char *s1, const tjs_char *s2));\nTJS_EXP_FUNC_DEF(void, TJS_strcpy_maxlen, (tjs_char *d, const tjs_char *s, size_t len));\nTJS_EXP_FUNC_DEF(void, TJS_strcpy, (tjs_char *d, const tjs_char *s));\nTJS_EXP_FUNC_DEF(size_t, TJS_strlen, (const tjs_char *d));\nint TJS_strcmp (const tjs_char * src, const tjs_char * dst);\nint TJS_strncmp (const tjs_char * first, const tjs_char * last, size_t count);\ntjs_char * TJS_strncpy (tjs_char * dest, const tjs_char * source, size_t count);\ntjs_char *  TJS_strcat (tjs_char * dst, const tjs_char * src);\ntjs_char * TJS_strstr (const tjs_char * wcs1, const tjs_char * wcs2);\ntjs_char * TJS_strchr (const tjs_char * string, tjs_char ch);\nvoid *TJS_malloc(size_t n);\nvoid *TJS_realloc(void* orig, size_t n);\nvoid TJS_free(void *p);\n#define TJS_nsprintf\t\tsprintf\n#define TJS_nstrcpy\t\t\tstrcpy\n#define TJS_nstrcat\t\t\tstrcat\n#define TJS_nstrlen\t\t\tstrlen\n#define TJS_nstrstr\t\t\tstrstr\nsize_t TJS_strftime (tjs_char *wstring, size_t maxsize, const tjs_char *wformat, const tm *timeptr);\nint TJS_vsnprintf (tjs_char *string, size_t count, const tjs_char *format, va_list ap);\n#define TJS_vfprintf\t\tvfwprintf\n#define TJS_octetcpy\t\tmemcpy\n#define TJS_octetcmp\t\tmemcmp\ndouble TJS_strtod(const tjs_char* pString, tjs_char** ppEnd);\nTJS_EXP_FUNC_DEF(tjs_int64, TJS_atoll, (const tjs_char *s));\ntjs_char *TJS_strrchr(const tjs_char *s, int c);\n\nextern size_t TJS_mbstowcs(tjs_char *pwcs, const tjs_nchar *s, size_t n);\nextern size_t TJS_wcstombs(tjs_nchar *s, const tjs_char *pwcs, size_t n);\nextern int TJS_mbtowc(tjs_char *pwc, const tjs_nchar *s, size_t n);\nextern int TJS_wctomb(tjs_nchar *s, tjs_char wc);\nextern tjs_int TJS_sprintf(tjs_char *s, const tjs_char *format, ...);\n\n#define TJS_strncpy_s(d, dl, s, sl)\t\tTJS_strncpy(d, s, sl)\n#if defined(_MSC_VER)\n\t#define TJS_cdecl __cdecl\n\t#define TJS_timezone _timezone\n#else\n\t#define TJS_cdecl\n\t#define TJS_timezone timezone\n#endif\nextern tjs_int TJS_snprintf(tjs_char *s, size_t count, const tjs_char *format, ...);\n\n#define TJS_narrowtowidelen(X) TJS_mbstowcs(NULL, (X),0) // narrow->wide (if) converted length\n#define TJS_narrowtowide TJS_mbstowcs\n\nvoid TJS_debug_out(const tjs_char *format, ...);\n\n#ifdef TJS_DEBUG_TRACE\n#define TJS_D(x)\tTJS_debug_out x;\n#define TJS_F_TRACE(x) tTJSFuncTrace ___trace(TJS_W(x));\n#else\n#define TJS_D(x)\n#define TJS_F_TRACE(x)\n#endif\n\n\n#ifdef _MSC_VER\n#define __STR2__(x) #x\n#define __STR1__(x) __STR2__(x)\n#define __LOC__ __FILE__ \"(\"__STR1__(__LINE__)\") : Warning Msg: \"\n#endif\n\nextern void TJSNativeDebuggerBreak();\n\n\nextern void TJSSetFPUE();\nextern void TJSRestoreFPUE();\n\n\n//---------------------------------------------------------------------------\n// elapsed time profiler\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\nextern tjs_uint TJSGetTickCount();\nclass tTJSTimeProfiler\n{\n\ttjs_uint & timevar;\n\ttjs_uint start;\npublic:\n\ttTJSTimeProfiler(tjs_uint & tv) : timevar(tv)\n\t{\n\t\tstart = TJSGetTickCount();\n\t}\n\n\t~tTJSTimeProfiler()\n\t{\n\t\ttimevar += TJSGetTickCount() - start;\n\t}\n};\n#endif\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// function tracer\n//---------------------------------------------------------------------------\nclass tTJSFuncTrace\n{\n\ttjs_char *funcname;\npublic:\n\ttTJSFuncTrace(tjs_char *p)\n\t{\n\t\tfuncname = p;\n\t\tTJS_debug_out(TJS_W(\"enter: %ls\\n\"), funcname);\n\t}\n\t~tTJSFuncTrace()\n\t{\n\t\tTJS_debug_out(TJS_W(\"exit: %ls\\n\"), funcname);\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNarrowStringHolder : converts wide -> narrow, and holds it until be destroyed\n//---------------------------------------------------------------------------\nstruct tTJSNarrowStringHolder\n{\n\tbool Allocated;\n\ttjs_nchar *Buf;\npublic:\n\ttTJSNarrowStringHolder(const tjs_char *wide);\n\n\t~tTJSNarrowStringHolder(void);\n\n\toperator const tjs_nchar *()\n\t{\n\t\treturn Buf;\n\t}\n};\n//---------------------------------------------------------------------------\n\n}\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/tjs2/tjsConstArrayData.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjs.h\"\n#include \"tjsConstArrayData.h\"\n#include <limits.h>\n\nnamespace TJS\n{\n\ntjsConstArrayData::~tjsConstArrayData() {\n\tfor( std::vector<std::vector<tjs_uint8>* >::iterator i = ByteBuffer.begin(); i != ByteBuffer.end(); ++i ) {\n\t\tdelete (*i);\n\t}\n}\n\nint tjsConstArrayData::PutByteBuffer( tTJSVariantOctet* val ) {\n\t// INebg̎͑S`FbN\n\ttjs_uint len = 0;\n\tconst tjs_uint8* data = NULL;\n\tif( val ) {\n\t\tlen = val->GetLength();\n\t\tdata =  val->GetData();\n\t}\n\ttjs_uint size = (tjs_uint)ByteBuffer.size();\n\tint index = -1;\n\tfor( tjs_uint i = 0; i < size; i++ ) {\n\t\ttjs_uint datalen = (tjs_uint)ByteBuffer[i]->size();\n\t\tif( len == datalen ) {\n\t\t\tif( len == 0 ) {\n\t\t\t\tindex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tstd::vector<tjs_uint8>* buf = ByteBuffer[i];\n\t\t\tif( TJS_octetcmp( data, &((*buf)[0]), len ) == 0 ) {\n\t\t\t\tindex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif( index >= 0 ) return index;\n\tindex = (int)ByteBuffer.size();\n\tstd::vector<tjs_uint8>* buf = new std::vector<tjs_uint8>();\n\tbuf->reserve( len );\n\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\tbuf->push_back( data[i] );\n\t}\n\tByteBuffer.push_back( buf );\n\treturn index;\n}\nint tjsConstArrayData::PutByte( tjs_int8 b ) {\n\tstd::map<tjs_int8,int>::const_iterator index = ByteHash.find( b );\n\tif( index == ByteHash.end() ) {\n\t\tint idx = (int)Byte.size();\n\t\tByte.push_back( b );\n\t\tByteHash.insert( std::pair<tjs_int8,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\nint tjsConstArrayData::PutShort( tjs_int16 b ) {\n\tstd::map<tjs_int16,int>::const_iterator index = ShortHash.find( b );\n\tif( index == ShortHash.end() ) {\n\t\tint idx = (int)Short.size();\n\t\tShort.push_back( b );\n\t\tShortHash.insert( std::pair<tjs_int16,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\nint tjsConstArrayData::PutInteger( tjs_int32 b ) {\n\tstd::map<tjs_int32,int>::const_iterator index = IntegerHash.find( b );\n\tif( index == IntegerHash.end() ) {\n\t\tint idx = (int)Integer.size();\n\t\tInteger.push_back( b );\n\t\tIntegerHash.insert( std::pair<tjs_int32,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\nint tjsConstArrayData::PutLong( tjs_int64 b ) {\n\tstd::map<tjs_int64,int>::const_iterator index = LongHash.find( b );\n\tif( index == LongHash.end() ) {\n\t\tint idx = (int)Long.size();\n\t\tLong.push_back( b );\n\t\tLongHash.insert( std::pair<tjs_int64,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\nint tjsConstArrayData::PutDouble( double b ) {\n\tstd::map<double,int>::const_iterator index = DoubleHash.find( b );\n\tif( index == DoubleHash.end() ) {\n\t\tint idx = (int)Double.size();\n\t\tDouble.push_back( b );\n\t\tDoubleHash.insert( std::pair<double,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\n\n\nint tjsConstArrayData::PutString( const tjs_char* val ) {\n\tstd::basic_string<tjs_char> b;\n\tif( val ) b = std::basic_string<tjs_char>(val);\n\tstd::map<std::basic_string<tjs_char>,int>::const_iterator index = StringHash.find( b );\n\tif( index == StringHash.end() ) {\n\t\tint idx = (int)String.size();\n\t\tString.push_back( b );\n\t\tStringHash.insert( std::pair<std::basic_string<tjs_char>,int>(b,idx) );\n\t\treturn idx;\n\t} else {\n\t\treturn index->second;\n\t}\n}\nint tjsConstArrayData::GetType( tTJSVariant& v, tTJSScriptBlock* block ) {\n\ttTJSVariantType type = v.Type();\n\tswitch( type ) {\n\tcase tvtVoid:\n\t\treturn TYPE_VOID;\n\tcase tvtObject: {\n\t\tiTJSDispatch2* obj = v.AsObjectNoAddRef();\n\t\tint index = block->GetCodeIndex( (const tTJSInterCodeContext*)obj );\n\t\tif( index >= 0 ) {\n\t\t\treturn TYPE_INTER_OBJECT;\n\t\t} else {\n\t\t\treturn TYPE_OBJECT;\n\t\t}\n\t}\n\tcase tvtString:\n\t\treturn TYPE_STRING;\n\tcase tvtOctet:\n\t\treturn TYPE_OCTET;\n\tcase tvtInteger: {\n\t\ttjs_int64 val = v.AsInteger();\n\t\tif( val >= SCHAR_MIN && val <= SCHAR_MAX ) {\n\t\t\treturn TYPE_BYTE;\n\t\t} else if( val >= SHRT_MIN && val <= SHRT_MAX ) {\n\t\t\treturn TYPE_SHORT;\n\t\t} else if( val >= LONG_MIN && val <= LONG_MAX ) {\n\t\t\treturn TYPE_INTEGER;\n\t\t} else {\n\t\t\treturn TYPE_LONG;\n\t\t}\n\t}\n\tcase tvtReal:\n\t\treturn TYPE_REAL;\n\tdefault:\n\t\treturn TYPE_UNKNOWN;\n\t}\n}\nint tjsConstArrayData::PutVariant( tTJSVariant& v, tTJSScriptBlock* block ) {\n\tint type = GetType( v, block );\n\tswitch( type ) {\n\tcase TYPE_VOID:\n\t\treturn 0; // 0\n\tcase TYPE_OBJECT: {\n\t\tiTJSDispatch2* obj = v.AsObjectNoAddRef();\n\t\tiTJSDispatch2* objthis = v.AsObjectThisNoAddRef();\n\t\tif( obj == NULL && objthis == NULL ) {\n\t\t\treturn 0; // null  VariantClosure ͎󂯓\n\t\t} else {\n\t\t\treturn -1; // ͓̑ȂB\n\t\t}\n\t}\n\tcase TYPE_INTER_OBJECT: {\n\t\tiTJSDispatch2* obj = v.AsObjectNoAddRef();\n\t\treturn block->GetCodeIndex( (const tTJSInterCodeContext*)obj );\n\t}\n\tcase TYPE_STRING:\n\t\treturn PutString( v.GetString() );\n\tcase TYPE_OCTET:\n\t\treturn PutByteBuffer( v.AsOctet() );\n\tcase TYPE_REAL:\n\t\treturn PutDouble( v.AsReal() );\n\tcase TYPE_BYTE:\n\t\treturn PutByte( static_cast<tjs_int8>(v.AsInteger()) );\n\tcase TYPE_SHORT:\n\t\treturn PutShort( static_cast<tjs_int16>(v.AsInteger()) );\n\tcase TYPE_INTEGER:\n\t\treturn PutInteger( static_cast<tjs_int32>(v.AsInteger()) );\n\tcase TYPE_LONG:\n\t\treturn PutLong( v.AsInteger() );\n\tcase TYPE_UNKNOWN:\n\t\treturn -1;\n\t}\n\treturn -1;\n}\nstd::vector<tjs_uint8>* tjsConstArrayData::ExportBuffer() {\n\tint size = 0;\n\tint stralllen = 0;\n\t// string\n\tint count = (int)String.size();\n\tfor( int i = 0; i < count; i++ ) {\n\t\tint len = (int)String[i].length();\n\t\tlen = ((len + 1) / 2) * 2;\n\t\tstralllen += len * 2;\n\t}\n\tstralllen = ((stralllen+3) / 4) * 4; // ACg\n\tsize += stralllen + count*4 + 4;\n\n\t// byte buffer\n\tint bytealllen = 0;\n\tcount = (int)ByteBuffer.size();\n\tfor( int i = 0; i < count; i++ ) {\n\t\tint len = (int)ByteBuffer[i]->size();\n\t\tlen = ((len+3)/4)*4;\n\t\tbytealllen += len;\n\t}\n\tbytealllen = ((bytealllen+3) / 4) * 4; // ACg\n\tsize += bytealllen + count*4 + 4;\n\n\t// byte\n\tcount = (int)Byte.size();\n\tcount = ((count+3) / 4) * 4; // ACg\n\tsize += count + 4;\n\n\t// short\n\tcount = (int)(Short.size() * 2);\n\tcount = ((count+3) / 4) * 4; // ACg\n\tsize += count + 4;\n\n\t// int\n\tsize += (int)(Integer.size()*4 + 4);\n\n\t// long\n\tsize += (int)(Long.size()*8 + 4);\n\n\t// double\n\tsize += (int)(Double.size()*8 + 4);\n\n\tstd::vector<tjs_uint8>* buf = new std::vector<tjs_uint8>();\n\tbuf->reserve( size );\n\n\t// byte write\n\tcount = (int)Byte.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tbuf->push_back( Byte[i] );\n\t}\n\tcount = (((count+3) / 4) * 4) - count; // ACg\n\tfor( int i = 0; i < count; i++ ) {\n\t\tbuf->push_back( 0 );\n\t}\n\n\t// short write\n\tcount = (int)Short.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tAdd2ByteToVector( buf, Short[i] );\n\t}\n\tcount *= 2;\n\tcount = (((count+3) / 4) * 4) - count; // ACg\n\tfor( int i = 0; i < count; i++ ) {\n\t\tbuf->push_back( 0 );\n\t}\n\n\t// int write\n\tcount = (int)Integer.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tAdd4ByteToVector( buf, Integer[i] );\n\t}\n\n\t// long write\n\tcount = (int)Long.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tAdd8ByteToVector( buf, Long[i] );\n\t}\n\n\t// double write\n\tcount = (int)Double.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tdouble dval = Double[i];\n\t\tAdd8ByteToVector( buf, *(tjs_int64*)&dval );\n\t}\n\n\t// string write\n\tcount = (int)String.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tstd::basic_string<tjs_char>& str = String[i];\n\t\tint len = (int)str.length();\n\t\tAdd4ByteToVector( buf, len );\n\t\tfor( int s = 0; s < len; s++ ) {\n\t\t\tAdd2ByteToVector( buf, str[s] );\n\t\t}\n\t\tif( (len % 2) == 1 ) { // ACg\n\t\t\tAdd2ByteToVector( buf, 0 );\n\t\t}\n\t}\n\n\t// byte buffer write\n\tcount = (int)ByteBuffer.size();\n\tAdd4ByteToVector( buf, count );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tstd::vector<tjs_uint8>* by = ByteBuffer[i];\n\t\tint cap = (int)by->size();\n\t\tAdd4ByteToVector( buf, cap );\n\t\tfor( int b = 0; b < cap; b++ ) {\n\t\t\tbuf->push_back( (*by)[b] );\n\t\t}\n\t\tcap = ((cap+3)/4)*4 - cap; // ACg\n\t\tfor( int b = 0; b < cap; b++ ) {\n\t\t\tbuf->push_back( 0 );\n\t\t}\n\t}\n\treturn buf;\n}\n\n} // namespace\n"
  },
  {
    "path": "src/core/tjs2/tjsConstArrayData.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine( Byte Code )\n\tCopyright (c), Takenori Imoto\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n\n#ifndef tjsConstArrayDataH\n#define tjsConstArrayDataH\n\n#include \"tjsTypes.h\"\n#include <vector>\n#include \"tjsVariant.h\"\n#include \"tjsScriptBlock.h\"\n#include <map>\n#include <string>\n\nnamespace TJS\n{\n/**\n * TJS2 oCgR[ho Variant ^𕪗AŗL^ŕێ邽߂̃NX\n */\nclass tjsConstArrayData {\nprivate:\n\tstd::vector<tjs_int8> Byte;\n\tstd::vector<tjs_int16> Short;\n\tstd::vector<tjs_int32> Integer;\n\tstd::vector<tjs_int64> Long;\n\tstd::vector<double> Double;\n\tstd::vector<std::basic_string<tjs_char> > String;\n\tstd::vector<std::vector<tjs_uint8>* > ByteBuffer;\n\n\t// ێǂ肷邽߂̃nbV\n\tstd::map<tjs_int8,int> ByteHash;\n\tstd::map<tjs_int16,int> ShortHash;\n\tstd::map<tjs_int32,int> IntegerHash;\n\tstd::map<tjs_int64,int> LongHash;\n\tstd::map<double,int> DoubleHash;\n\tstd::map<std::basic_string<tjs_char>,int> StringHash;\n\t// INebg^̎̓nbVgĂȂ\n\n\tstatic const tjs_uint8 TYPE_VOID = 0;\n\tstatic const tjs_uint8 TYPE_OBJECT = 1;\n\tstatic const tjs_uint8 TYPE_INTER_OBJECT = 2;\n\tstatic const tjs_uint8 TYPE_STRING = 3;\n\tstatic const tjs_uint8 TYPE_OCTET = 4;\n\tstatic const tjs_uint8 TYPE_REAL = 5;\n\tstatic const tjs_uint8 TYPE_BYTE = 6;\n\tstatic const tjs_uint8 TYPE_SHORT = 7;\n\tstatic const tjs_uint8 TYPE_INTEGER = 8;\n\tstatic const tjs_uint8 TYPE_LONG = 9;\n\tstatic const tjs_uint8 TYPE_UNKNOWN = -1;\n\n\t/**\n\t * INebg^̒li[\n\t */\n\tint PutByteBuffer( tTJSVariantOctet* val );\n\n\t/**\n\t * 1oCg̒li[\n\t */\n\tint PutByte( tjs_int8 b );\n\t\n\t/**\n\t * 2oCg̒li[\n\t */\n\tint PutShort( tjs_int16 b );\n\t\n\t/**\n\t * 4oCg̒li[\n\t */\n\tint PutInteger( tjs_int32 b );\n\t\n\t/**\n\t * 8oCg̒li[\n\t */\n\tint PutLong( tjs_int64 b );\n\t\n\t/**\n\t * _li[\n\t */\n\tint PutDouble( double b );\n\n\tstatic inline void Add8ByteToVector( std::vector<tjs_uint8>* array, tjs_int64 value ) {\n\t\tarray->push_back( (tjs_uint8)((value>>0)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>8)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>16)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>24)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>32)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>40)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>48)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>56)&0xff) );\n\t}\n\tstatic inline void Add4ByteToVector( std::vector<tjs_uint8>* array, int value ) {\n\t\tarray->push_back( (tjs_uint8)((value>>0)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>8)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>16)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>24)&0xff) );\n\t}\n\tstatic inline void Add2ByteToVector( std::vector<tjs_uint8>* array, tjs_int16 value ) {\n\t\tarray->push_back( (tjs_uint8)((value>>0)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>8)&0xff) );\n\t}\npublic:\n\ttjsConstArrayData() {}\n\t~tjsConstArrayData();\n\n\t/**\n\t * i[\n\t */\n\tint PutString( const tjs_char* val );\n\n\t/**\n\t * oCAg^i[Ă^𓾂\n\t */\n\tint GetType( tTJSVariant& v, tTJSScriptBlock* block );\n\n\t/**\n\t * oCAgli[\n\t */\n\tint PutVariant( tTJSVariant& v, tTJSScriptBlock* block );\n\n\t/**\n\t * ێĂloCgɂĎo\n\t */\n\tstd::vector<tjs_uint8>* ExportBuffer();\n};\n\n} // namespace\n#endif // tjsConstArrayDataH\n\n"
  },
  {
    "path": "src/core/tjs2/tjsDate.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Date class implementation\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsError.h\"\n#include \"tjsDate.h\"\n#include \"tjsDateParser.h\"\n\n/*\nnote:\n\tTo ensure portability, TJS uses time_t as a date/time representation.\n\tif compiler's time_t holds only 32bits, it will cause the year 2038 problem.\n\tThe author assumes that it is a compiler dependented problem, so any remedies\n\tare not given here.\n*/\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nstatic time_t TJSParseDateString(const tjs_char *str)\n{\n\ttTJSDateParser parser(str);\n\treturn (time_t)(parser.GetTime() / 1000);\n}\n//---------------------------------------------------------------------------\n// tTJSNI_Date : TJS Native Instance : Date\n//---------------------------------------------------------------------------\ntTJSNI_Date::tTJSNI_Date()\n{\n\t// C++ constructor\n}\n//---------------------------------------------------------------------------\n// tTJSNC_Date : TJS Native Class : Date\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Date::ClassID = (tjs_uint32)-1;\ntTJSNC_Date::tTJSNC_Date() :\n\ttTJSNativeClass(TJS_W(\"Date\"))\n{\n\t// class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/Date)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var. name*/_this, /*var. type*/tTJSNI_Date,\n\t/*TJS class name*/ Date)\n{\n\tif(numparams == 0)\n\t{\n\t\ttime_t curtime;\n\t\t_this->DateTime = time(&curtime); // GMT current date/time\n\t}\n\telse if(numparams >= 1)\n\t{\n\t\tif(param[0]->Type() == tvtString)\n\t\t{\n\t\t\t// formatted string -> date/time\n\t\t\t_this->DateTime = TJSParseDateString(param[0]->GetString());\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttjs_int y, mon=0, day=1, h=0, m=0, s=0;\n\t\t\ty = (tjs_int)param[0]->AsInteger();\n\t\t\tif(TJS_PARAM_EXIST(1)) mon = (tjs_int)param[1]->AsInteger();\n\t\t\tif(TJS_PARAM_EXIST(2)) day = (tjs_int)param[2]->AsInteger();\n\t\t\tif(TJS_PARAM_EXIST(3)) h = (tjs_int)param[3]->AsInteger();\n\t\t\tif(TJS_PARAM_EXIST(4)) m = (tjs_int)param[4]->AsInteger();\n\t\t\tif(TJS_PARAM_EXIST(5)) s = (tjs_int)param[5]->AsInteger();\n\t\t\ttm t;\n\t\t\tmemset(&t, 0, sizeof(tm));\n\t\t\tt.tm_year = y - 1900;\n\t\t\tt.tm_mon = mon;\n\t\t\tt.tm_mday = day;\n\t\t\tt.tm_hour = h;\n\t\t\tt.tm_min = m;\n\t\t\tt.tm_sec = s;\n\t\t\t_this->DateTime = mktime(&t);\n\t\t\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n//\t\t\t_this->DateTime -= TJS_timezone;\n\t\t}\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Date)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setYear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_year = (tjs_int)param[0]->AsInteger() - 1900;\n\t_this->DateTime = mktime(&t);\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setYear)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMonth)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_mon = (tjs_int)param[0]->AsInteger();\n\t_this->DateTime = mktime(&t);\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMonth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setDate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_mday = (tjs_int)param[0]->AsInteger();\n\t_this->DateTime = mktime(&t);\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setDate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setHours)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_hour = (tjs_int)param[0]->AsInteger();\n\t_this->DateTime = mktime(&t) ;\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setHours)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMinutes)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_min = (tjs_int)param[0]->AsInteger();\n\t_this->DateTime = mktime(&t);\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMinutes)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSeconds)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttm *te = localtime(&_this->DateTime);\n\ttm t;\n\tmemcpy(&t, te, sizeof(tm));\n\tt.tm_sec = (tjs_int)param[0]->AsInteger();\n\t_this->DateTime = mktime(&t);\n\tif(_this->DateTime == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSeconds)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setTime)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t_this->DateTime = (time_t)(param[0]->AsInteger()/1000L);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getDate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_mday));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getDate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getDay)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_wday));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getDay)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getHours)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_hour));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getHours)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getMinutes)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_min));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getMinutes)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getMonth)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_mon));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getMonth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getSeconds)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_sec));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getSeconds)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTime)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(result) result->CopyRef(tTJSVariant(\n\t\t\t(tjs_int64)(_this->DateTime)*1000L));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTimezoneOffset) // static\n{\n\tif(result) result->CopyRef(tTJSVariant((tjs_int)(TJS_timezone/60)));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getTimezoneOffset)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getYear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\ttm *t = localtime(&_this->DateTime);\n\n\tif(result) result->CopyRef(tTJSVariant(t->tm_year+1900));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getYear)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/parse)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Date);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t_this->DateTime = TJSParseDateString(param[0]->GetString());\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/parse)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Date::CreateNativeInstance()\n{\n\treturn new tTJSNI_Date(); \n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/tjs2/tjsDate.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Date class implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsDateH\n#define tjsDateH\n\n#include <time.h>\n#include \"tjsNative.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nclass tTJSNI_Date : public tTJSNativeInstance\n{\npublic:\n\ttTJSNI_Date();\n\ttime_t DateTime;\nprivate:\n};\n\n//---------------------------------------------------------------------------\nclass tTJSNC_Date : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Date();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsDateParser.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Date/time string parser\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <time.h>\n\n#include \"tjsDateParser.h\"\n#include \"tjsdate.tab.hpp\"\n\n#include \"tjsError.h\"\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// interface to bison generated parser\n//---------------------------------------------------------------------------\nint dplex(YYSTYPE *yylex, void *pm)\n{\n\ttTJSDateParser *parser = (tTJSDateParser*)pm;\n\tint tok =  parser->Lex(yylex);\n\treturn tok;\n}\nint dpparse (void *YYPARSE_PARAM);\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Character component classifications\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswspace(tjs_char ch)\n{\n\tif(ch&0xff00) return false; else return 0!=isspace(ch);\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswdigit(tjs_char ch)\n{\n\tif(ch&0xff00) return false; else return 0!=isdigit(ch);\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswalpha(tjs_char ch)\n{\n\tif(ch&0xff00) return true; else return 0!=isalpha(ch);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSDateParser : A date/time parser class\n//---------------------------------------------------------------------------\ntTJSDateParser::tTJSDateParser(const tjs_char *in)\n{\n\tInput = InputPointer = in;\n\n\tYearSet = MonthSet = MDaySet = HourSet = MinSet = SecSet = TimeZoneSet =\n\tTimeZoneOffsetSet = AMPMSet = false;\n\n\tif(dpparse(this)) TJS_eTJSError(TJSCannotParseDate);\n\n\t// currently no omissions is allowed except for Secs\n\tif(!YearSet || !MonthSet || !MDaySet || !HourSet || !MinSet)\n\t\tTJS_eTJSError(TJSCannotParseDate);\n\tif(!SecSet) SecSet = true, Sec = 0;\n\n\t// convert Timezone/TimezoneOffset to time_t representation\n\tif(TimeZoneSet)\n\t{\n\t\t// input timezone is [+/-]hhmm\n\t\tbool sign = TimeZone < 0 ? true : false;\n\t\tif(sign) TimeZone = -TimeZone;\n\t\tTimeZone = (int)(TimeZone / 100) * 60*60 + (TimeZone % 100) * 60;\n\t\tif(sign) TimeZone = -TimeZone;\n\t}\n\tif(TimeZoneOffsetSet)\n\t{\n\t\t// input timezone is [+/-]hhmm\n\t\tbool sign = TimeZoneOffset < 0 ? true : false;\n\t\tif(sign) TimeZoneOffset = -TimeZoneOffset;\n\t\tTimeZoneOffset = (int)(TimeZoneOffset / 100) * 60*60 + (TimeZoneOffset % 100) * 60;\n\t\tif(sign) TimeZoneOffset = -TimeZoneOffset;\n\t}\n\n\t// Timezone is default system timezone when timezone is omitted.\n\tif(!TimeZoneSet && !TimeZoneOffsetSet)\n\t{\n\t\tTimeZoneSet = true;\n\t\tTimeZone = -TJS_timezone;\n\t}\n\n\t// Adjust AM/PM\n\tif(AMPMSet && AMPM) Hour += 12;\n\n\t// build tm structure\n\tstruct tm stm;\n\tmemset(&stm, 0, sizeof(stm));\n\tstm.tm_year = Year - 1900;\n\tstm.tm_mon = Month;\n\tstm.tm_mday = MDay;\n\tstm.tm_hour = Hour;\n\tstm.tm_min = Min;\n\tstm.tm_sec = Sec;\n\n\ttime_t tmv = mktime(&stm);\n\tif(tmv == -1) TJS_eTJSError(TJSInvalidValueForTimestamp);\n\n\t// adjust time zone\n\ttmv -= TJS_timezone;\n\ttjs_int tz = 0;\n\tif(TimeZoneSet) tz += TimeZone;\n\tif(TimeZoneOffsetSet) tz += TimeZoneOffset;\n\ttmv -= tz;\n\n\t// store result\n\tTime = (tjs_int64)tmv * 1000;\n}\n//---------------------------------------------------------------------------\ntTJSDateParser::~tTJSDateParser()\n{\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTJSDateParser::GetTime()\n{\n\treturn Time;\n}\n//---------------------------------------------------------------------------\nint tTJSDateParser::Lex(YYSTYPE *yylex)\n{\n\tif(*InputPointer == 0) return -1;\n\n\twhile( *InputPointer && TJS_iswspace(*InputPointer)) InputPointer++;\n\n\tif(*InputPointer == 0) return -1;\n\n\tif(TJS_iswdigit(*InputPointer))\n\t{\n\t\ttjs_int32 val = *InputPointer - TJS_W('0');\n\t\tInputPointer ++;\n\t\twhile(TJS_iswdigit(*InputPointer))\n\t\t{\n\t\t\tval *= 10;\n\t\t\tval += *InputPointer - TJS_W('0');\n\t\t\tInputPointer++;\n\t\t}\n\t\tyylex->val = val;\n\t\treturn DP_NUMBER;\n\t}\n\n\t#include \"tjsDateWordMap.cc\"\n\n\tint n =  (int)*(InputPointer++);\n\tif(n >= TJS_W('A') && n <= TJS_W('Z')) n += TJS_W('a') - TJS_W('A');\n\treturn n;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SkipToRightParenthesis()\n{\n\t// skip InputPointer to ')'\n\twhile(*InputPointer && *InputPointer != ')') InputPointer ++;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetMDay(int v)\n{\n\tMDaySet = true;\n\tMDay = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetMonth(int v)\n{\n\tMonthSet = true;\n\tMonth = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetYear(int v)\n{\n\tif(v < 100)\n\t{\n\t\tif(v <= 50)\n\t\t\tv = 2000 + v;\n\t\telse\n\t\t\tv = 1900 + v;\n\t}\n\tYearSet = true;\n\tYear = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetHours(int v)\n{\n\tHourSet = true;\n\tHour = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetMin(int v)\n{\n\tMinSet = true;\n\tMin = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetSec(int v)\n{\n\tSecSet = true;\n\tSec = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetAMPM(bool is_pm)\n{\n\tAMPMSet = true;\n\tAMPM = is_pm;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetTimeZone(int v)\n{\n\tTimeZoneSet = true;\n\tTimeZone = v;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDateParser::SetTimeZoneOffset(int v)\n{\n\tTimeZoneOffsetSet = true;\n\tTimeZoneOffset = v;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsDateParser.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Date/time string parser\n//---------------------------------------------------------------------------\n#ifndef tjsDateParserH\n#define tjsDateParserH\n\n#include \"tjsTypes.h\"\n#include \"tjsdate.tab.hpp\"\n\n\nnamespace TJS\n{\n\n\n//---------------------------------------------------------------------------\n// tTJSDateParser : A date/time parser class\n//---------------------------------------------------------------------------\nclass tTJSDateParser\n{\n\tbool YearSet;\n\tint Year;\n\n\tbool MonthSet;\n\tint Month;\n\n\tbool MDaySet;\n\tint MDay;\n\n\tbool HourSet;\n\tint Hour;\n\n\tbool MinSet;\n\tint Min;\n\n\tbool SecSet;\n\tint Sec;\n\n\tbool AMPMSet;\n\tbool AMPM; // pm:true am:false\n\n\tbool TimeZoneSet;\n\tint TimeZone;\n\n\tbool TimeZoneOffsetSet;\n\tint TimeZoneOffset;\n\n\tconst tjs_char *Input;\n\tconst tjs_char *InputPointer;\n\n\ttjs_int64 Time; // time from 1970-01-01 00:00:00.00 GMT\n\n\n\tfriend int dplex(YYSTYPE *yylex, void *pm);\n\tfriend int dpparse (void *YYPARSE_PARAM);\n\npublic:\n\ttTJSDateParser(const tjs_char *in);\n\t~tTJSDateParser();\n\n\ttjs_int64 GetTime();\n\nprivate:\n\tint Lex(YYSTYPE *yylex);\n\n\tvoid SkipToRightParenthesis();\n\n\tvoid SetMDay(int v);\n\tvoid SetMonth(int v);\n\tvoid SetYear(int v);\n\tvoid SetHours(int v);\n\tvoid SetMin(int v);\n\tvoid SetSec(int v);\n\tvoid SetAMPM(bool is_pm);\n\tvoid SetTimeZone(int v);\n\tvoid SetTimeZoneOffset(int v);\n\n\n};\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsDateWordMap.cc",
    "content": "/*---------------------------------------------------------------------------*/\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/*---------------------------------------------------------------------------*/\n/*\n\tDate/time string parser lexical analyzer word cutter.\n\n\tThis file is always generated from syntax/dp_wordtable.txt by\n\tsyntax/create_word_map.pl. Modification by hand will be lost.\n\n*/\n\nswitch(InputPointer[0])\n{\ncase TJS_W('a'):\ncase TJS_W('A'):\n switch(InputPointer[1])\n {\n case TJS_W('c'):\n case TJS_W('C'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('s'):\n   case TJS_W('S'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('t'):\n    case TJS_W('T'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 1030; return DP_TZ; }\n     break;\n    }\n    break;\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 930; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -300; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('s'):\n   case TJS_W('S'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('t'):\n    case TJS_W('T'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 1100; return DP_TZ; }\n     break;\n    }\n    break;\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1000; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n case TJS_W('h'):\n case TJS_W('H'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = -1000; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n case TJS_W('m'):\n case TJS_W('M'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 0; return DP_AM; }\n  break;\n case TJS_W('p'):\n case TJS_W('P'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('r'):\n  case TJS_W('R'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 3; return DP_MONTH; }\n    break;\n   case TJS_W('i'):\n   case TJS_W('I'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('l'):\n    case TJS_W('L'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 3; return DP_MONTH; }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 3; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -400; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('u'):\n case TJS_W('U'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('g'):\n  case TJS_W('G'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 7; return DP_MONTH; }\n    break;\n   case TJS_W('u'):\n   case TJS_W('U'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('t'):\n     case TJS_W('T'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 7; return DP_MONTH; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 7; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('w'):\n case TJS_W('W'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('s'):\n   case TJS_W('S'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('t'):\n    case TJS_W('T'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 900; return DP_TZ; }\n     break;\n    }\n    break;\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 800; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n default:\n  if(!TJS_iswalpha(InputPointer[1])) { InputPointer += 1; yylex->val = -100; return DP_TZ; }\n }\n break;\ncase TJS_W('b'):\ncase TJS_W('B'):\n switch(InputPointer[1])\n {\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('t'):\n case TJS_W('T'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 300; return DP_TZ; }\n  break;\n }\n break;\ncase TJS_W('c'):\ncase TJS_W('C'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('d'):\n  case TJS_W('D'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1030; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 930; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -1000; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('c'):\n case TJS_W('C'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 800; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -500; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('t'):\n     case TJS_W('T'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 200; return DP_TZ; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -600; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('d'):\ncase TJS_W('D'):\n switch(InputPointer[1])\n {\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('c'):\n  case TJS_W('C'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 11; return DP_MONTH; }\n    break;\n   case TJS_W('e'):\n   case TJS_W('E'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('m'):\n    case TJS_W('M'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('b'):\n     case TJS_W('B'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('e'):\n      case TJS_W('E'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('r'):\n       case TJS_W('R'):\n         if(!TJS_iswalpha(InputPointer[8])) { InputPointer += 8; yylex->val = 11; return DP_MONTH; }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 11; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('n'):\n case TJS_W('N'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('e'):\ncase TJS_W('E'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1000; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -400; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('t'):\n     case TJS_W('T'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 300; return DP_TZ; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 200; return DP_TZ; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -500; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('f'):\ncase TJS_W('F'):\n switch(InputPointer[1])\n {\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('b'):\n  case TJS_W('B'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1; return DP_MONTH; }\n    break;\n   case TJS_W('r'):\n   case TJS_W('R'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('u'):\n    case TJS_W('U'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('a'):\n     case TJS_W('A'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('r'):\n      case TJS_W('R'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('y'):\n       case TJS_W('Y'):\n         if(!TJS_iswalpha(InputPointer[8])) { InputPointer += 8; yylex->val = 1; return DP_MONTH; }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 1; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('r'):\n case TJS_W('R'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('i'):\n  case TJS_W('I'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 5; return DP_WDAY; }\n    break;\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('a'):\n    case TJS_W('A'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('y'):\n     case TJS_W('Y'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 5; return DP_WDAY; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 5; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('w'):\n case TJS_W('W'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 200; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('g'):\ncase TJS_W('G'):\n switch(InputPointer[1])\n {\n case TJS_W('m'):\n case TJS_W('M'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 0; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 1000; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('h'):\ncase TJS_W('H'):\n switch(InputPointer[1])\n {\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -900; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('i'):\ncase TJS_W('I'):\n switch(InputPointer[1])\n {\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('l'):\n  case TJS_W('L'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('e'):\n   case TJS_W('E'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1200; return DP_TZ; }\n    break;\n   case TJS_W('w'):\n   case TJS_W('W'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = -1200; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 200; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('t'):\n case TJS_W('T'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 330; return DP_TZ; }\n  break;\n }\n break;\ncase TJS_W('j'):\ncase TJS_W('J'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('n'):\n  case TJS_W('N'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 0; return DP_MONTH; }\n    break;\n   case TJS_W('u'):\n   case TJS_W('U'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('a'):\n    case TJS_W('A'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('r'):\n     case TJS_W('R'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('y'):\n      case TJS_W('Y'):\n        if(!TJS_iswalpha(InputPointer[7])) { InputPointer += 7; yylex->val = 0; return DP_MONTH; }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 0; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 900; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('t'):\n case TJS_W('T'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 730; return DP_TZ; }\n  break;\n case TJS_W('u'):\n case TJS_W('U'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('.'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 5; return DP_MONTH; }\n   break;\n  case TJS_W('l'):\n  case TJS_W('L'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 6; return DP_MONTH; }\n    break;\n   case TJS_W('y'):\n   case TJS_W('Y'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 6; return DP_MONTH; }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 6; return DP_MONTH; }\n   }\n   break;\n  case TJS_W('n'):\n  case TJS_W('N'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 5; return DP_MONTH; }\n    break;\n   case TJS_W('e'):\n   case TJS_W('E'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 5; return DP_MONTH; }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 5; return DP_MONTH; }\n   }\n   break;\n  default:\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 5; return DP_MONTH; }\n  }\n  break;\n }\n break;\ncase TJS_W('k'):\ncase TJS_W('K'):\n switch(InputPointer[1])\n {\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 900; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('l'):\ncase TJS_W('L'):\n switch(InputPointer[1])\n {\n case TJS_W('i'):\n case TJS_W('I'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('g'):\n  case TJS_W('G'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1000; return DP_TZ; }\n    break;\n   }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('m'):\ncase TJS_W('M'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('r'):\n  case TJS_W('R'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 2; return DP_MONTH; }\n    break;\n   case TJS_W('c'):\n   case TJS_W('C'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('h'):\n    case TJS_W('H'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 2; return DP_MONTH; }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 2; return DP_MONTH; }\n   }\n   break;\n  case TJS_W('y'):\n  case TJS_W('Y'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 4; return DP_MONTH; }\n   break;\n  }\n  break;\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -600; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 200; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('t'):\n     case TJS_W('T'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 200; return DP_TZ; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   }\n   break;\n  case TJS_W('w'):\n  case TJS_W('W'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 100; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('z'):\n  case TJS_W('Z'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('o'):\n case TJS_W('O'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('n'):\n  case TJS_W('N'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1; return DP_WDAY; }\n    break;\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('a'):\n    case TJS_W('A'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('y'):\n     case TJS_W('Y'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 1; return DP_WDAY; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 1; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -700; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('t'):\n case TJS_W('T'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 830; return DP_TZ; }\n  break;\n default:\n  if(!TJS_iswalpha(InputPointer[1])) { InputPointer += 1; yylex->val = -1200; return DP_TZ; }\n }\n break;\ncase TJS_W('n'):\ncase TJS_W('N'):\n switch(InputPointer[1])\n {\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -230; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('f'):\n case TJS_W('F'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -330; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('o'):\n case TJS_W('O'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('r'):\n  case TJS_W('R'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  case TJS_W('v'):\n  case TJS_W('V'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 10; return DP_MONTH; }\n    break;\n   case TJS_W('e'):\n   case TJS_W('E'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('m'):\n    case TJS_W('M'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('b'):\n     case TJS_W('B'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('e'):\n      case TJS_W('E'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('r'):\n       case TJS_W('R'):\n         if(!TJS_iswalpha(InputPointer[8])) { InputPointer += 8; yylex->val = 10; return DP_MONTH; }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 10; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -330; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('t'):\n case TJS_W('T'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = -1100; return DP_TZ; }\n  break;\n case TJS_W('z'):\n case TJS_W('Z'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('d'):\n  case TJS_W('D'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1300; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1200; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 1200; return DP_TZ; }\n   break;\n  }\n  break;\n default:\n  if(!TJS_iswalpha(InputPointer[1])) { InputPointer += 1; yylex->val = 100; return DP_TZ; }\n }\n break;\ncase TJS_W('o'):\ncase TJS_W('O'):\n switch(InputPointer[1])\n {\n case TJS_W('c'):\n case TJS_W('C'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 9; return DP_MONTH; }\n    break;\n   case TJS_W('o'):\n   case TJS_W('O'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('b'):\n    case TJS_W('B'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('e'):\n     case TJS_W('E'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('r'):\n      case TJS_W('R'):\n        if(!TJS_iswalpha(InputPointer[7])) { InputPointer += 7; yylex->val = 9; return DP_MONTH; }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 9; return DP_MONTH; }\n   }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('p'):\ncase TJS_W('P'):\n switch(InputPointer[1])\n {\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -700; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('m'):\n case TJS_W('M'):\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 0; return DP_PM; }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -800; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('s'):\ncase TJS_W('S'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('d'):\n  case TJS_W('D'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 1030; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 930; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 6; return DP_WDAY; }\n    break;\n   case TJS_W('u'):\n   case TJS_W('U'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('r'):\n    case TJS_W('R'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('d'):\n     case TJS_W('D'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('a'):\n      case TJS_W('A'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('y'):\n       case TJS_W('Y'):\n         if(!TJS_iswalpha(InputPointer[8])) { InputPointer += 8; yylex->val = 6; return DP_WDAY; }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 6; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('p'):\n  case TJS_W('P'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 8; return DP_MONTH; }\n    break;\n   case TJS_W('t'):\n   case TJS_W('T'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('.'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 8; return DP_MONTH; }\n     break;\n    case TJS_W('e'):\n    case TJS_W('E'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('m'):\n     case TJS_W('M'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('b'):\n      case TJS_W('B'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('e'):\n       case TJS_W('E'):\n        switch(InputPointer[8])\n        {\n        case TJS_W('r'):\n        case TJS_W('R'):\n          if(!TJS_iswalpha(InputPointer[9])) { InputPointer += 9; yylex->val = 8; return DP_MONTH; }\n         break;\n        }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    default:\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 8; return DP_MONTH; }\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 8; return DP_MONTH; }\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 200; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('u'):\n case TJS_W('U'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('n'):\n  case TJS_W('N'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 0; return DP_WDAY; }\n    break;\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('a'):\n    case TJS_W('A'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('y'):\n     case TJS_W('Y'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 0; return DP_WDAY; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 0; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n case TJS_W('w'):\n case TJS_W('W'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 100; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('t'):\ncase TJS_W('T'):\n switch(InputPointer[1])\n {\n case TJS_W('h'):\n case TJS_W('H'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('u'):\n  case TJS_W('U'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 4; return DP_WDAY; }\n    break;\n   case TJS_W('r'):\n   case TJS_W('R'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('.'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 4; return DP_WDAY; }\n      break;\n     case TJS_W('d'):\n     case TJS_W('D'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('a'):\n      case TJS_W('A'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('y'):\n       case TJS_W('Y'):\n         if(!TJS_iswalpha(InputPointer[8])) { InputPointer += 8; yylex->val = 4; return DP_WDAY; }\n        break;\n       }\n       break;\n      }\n      break;\n     default:\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 4; return DP_WDAY; }\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 4; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n case TJS_W('u'):\n case TJS_W('U'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('e'):\n  case TJS_W('E'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 2; return DP_WDAY; }\n    break;\n   case TJS_W('s'):\n   case TJS_W('S'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('.'):\n      if(!TJS_iswalpha(InputPointer[5])) { InputPointer += 5; yylex->val = 2; return DP_WDAY; }\n     break;\n    case TJS_W('d'):\n    case TJS_W('D'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('a'):\n     case TJS_W('A'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('y'):\n      case TJS_W('Y'):\n        if(!TJS_iswalpha(InputPointer[7])) { InputPointer += 7; yylex->val = 2; return DP_WDAY; }\n       break;\n      }\n      break;\n     }\n     break;\n    default:\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 2; return DP_WDAY; }\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 2; return DP_WDAY; }\n   }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('u'):\ncase TJS_W('U'):\n switch(InputPointer[1])\n {\n case TJS_W('t'):\n case TJS_W('T'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('c'):\n  case TJS_W('C'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 0; return DP_TZ; }\n   break;\n  default:\n   if(!TJS_iswalpha(InputPointer[2])) { InputPointer += 2; yylex->val = 0; return DP_TZ; }\n  }\n  break;\n }\n break;\ncase TJS_W('w'):\ncase TJS_W('W'):\n switch(InputPointer[1])\n {\n case TJS_W('a'):\n case TJS_W('A'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('d'):\n  case TJS_W('D'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 800; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('s'):\n  case TJS_W('S'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('t'):\n   case TJS_W('T'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 700; return DP_TZ; }\n    break;\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -100; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 900; return DP_TZ; }\n   break;\n  }\n  break;\n case TJS_W('e'):\n case TJS_W('E'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('d'):\n  case TJS_W('D'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('.'):\n     if(!TJS_iswalpha(InputPointer[4])) { InputPointer += 4; yylex->val = 3; return DP_WDAY; }\n    break;\n   case TJS_W('n'):\n   case TJS_W('N'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('e'):\n    case TJS_W('E'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('s'):\n     case TJS_W('S'):\n      switch(InputPointer[6])\n      {\n      case TJS_W('d'):\n      case TJS_W('D'):\n       switch(InputPointer[7])\n       {\n       case TJS_W('a'):\n       case TJS_W('A'):\n        switch(InputPointer[8])\n        {\n        case TJS_W('y'):\n        case TJS_W('Y'):\n          if(!TJS_iswalpha(InputPointer[9])) { InputPointer += 9; yylex->val = 3; return DP_WDAY; }\n         break;\n        }\n        break;\n       }\n       break;\n      }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 3; return DP_WDAY; }\n   }\n   break;\n  case TJS_W('t'):\n  case TJS_W('T'):\n   switch(InputPointer[3])\n   {\n   case TJS_W('d'):\n   case TJS_W('D'):\n    switch(InputPointer[4])\n    {\n    case TJS_W('s'):\n    case TJS_W('S'):\n     switch(InputPointer[5])\n     {\n     case TJS_W('t'):\n     case TJS_W('T'):\n       if(!TJS_iswalpha(InputPointer[6])) { InputPointer += 6; yylex->val = 100; return DP_TZ; }\n      break;\n     }\n     break;\n    }\n    break;\n   default:\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 0; return DP_TZ; }\n   }\n   break;\n  }\n  break;\n case TJS_W('s'):\n case TJS_W('S'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = 800; return DP_TZ; }\n   break;\n  }\n  break;\n }\n break;\ncase TJS_W('y'):\ncase TJS_W('Y'):\n switch(InputPointer[1])\n {\n case TJS_W('d'):\n case TJS_W('D'):\n  switch(InputPointer[2])\n  {\n  case TJS_W('t'):\n  case TJS_W('T'):\n    if(!TJS_iswalpha(InputPointer[3])) { InputPointer += 3; yylex->val = -800; return DP_TZ; }\n   break;\n  }\n  break;\n default:\n  if(!TJS_iswalpha(InputPointer[1])) { InputPointer += 1; yylex->val = 1200; return DP_TZ; }\n }\n break;\ncase TJS_W('z'):\ncase TJS_W('Z'):\n  if(!TJS_iswalpha(InputPointer[1])) { InputPointer += 1; yylex->val = 0; return DP_TZ; }\n break;\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsDebug.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Debugging support\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"tjsDebug.h\"\n#include \"tjsHashSearch.h\"\n#include \"tjsInterCodeGen.h\"\n#include \"tjsGlobalStringMap.h\"\n\n#ifdef ENABLE_DEBUGGER\n#include <map>\n#include <list>\n#include \"Debugger.h\"\n#include \"Application.h\"\n#include \"NativeEventQueue.h\"\n#endif // ENABLE_DEBUGGER\n\nnamespace TJS\n{\n\n\n//---------------------------------------------------------------------------\n// ObjectHashMap : hash map to track object construction/destruction\n//--------------------------------------------------------------------------\ntTJSBinaryStream * TJSObjectHashMapLog = NULL;  // log file object\n//---------------------------------------------------------------------------\nenum tTJSObjectHashMapLogItemId\n{\n\tliiEnd,     // 00 end of the log\n\tliiVersion, // 01 identify log structure version\n\tliiAdd,     // 02 add a object\n\tliiRemove,  // 03 remove a object\n\tliiSetType, // 04 set object type information\n\tliiSetFlag, // 05 set object flag\n};\n//---------------------------------------------------------------------------\ntemplate <typename T>\nvoid TJSStoreLog(const T &object)\n{\n\tTJSObjectHashMapLog->Write(&object, sizeof(object));\n}\n//---------------------------------------------------------------------------\ntemplate <typename T>\nT TJSRestoreLog()\n{\n\tT object;\n\tTJSObjectHashMapLog->Read(&object, sizeof(object));\n\treturn object;\n}\n//---------------------------------------------------------------------------\ntemplate <>\nvoid TJSStoreLog<ttstr>(const ttstr & which)\n{\n\t// store a string into log stream\n\ttjs_int length = which.GetLen();\n\tTJSObjectHashMapLog->Write(&length, sizeof(length));\n\t\t// Note that this function does not care what the endian is.\n\tTJSObjectHashMapLog->Write(which.c_str(), length * sizeof(tjs_char));\n}\n//---------------------------------------------------------------------------\ntemplate <>\nttstr TJSRestoreLog<ttstr>()\n{\n\t// restore a string from log stream\n\ttjs_int length;\n\tTJSObjectHashMapLog->Read(&length, sizeof(length));\n\tttstr ret((tTJSStringBufferLength)(length));\n\ttjs_char *buf = ret.Independ();\n\tTJSObjectHashMapLog->Read(buf, length * sizeof(tjs_char));\n\tbuf[length] = 0;\n\tret.FixLen();\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntemplate <>\nvoid TJSStoreLog<tTJSObjectHashMapLogItemId>(const tTJSObjectHashMapLogItemId & id)\n{\n\t// log item id\n\tchar cid = id;\n\tTJSObjectHashMapLog->Write(&cid, sizeof(char));\n}\n//---------------------------------------------------------------------------\ntemplate <>\ntTJSObjectHashMapLogItemId TJSRestoreLog<tTJSObjectHashMapLogItemId>()\n{\n\t// restore item id\n\tchar cid;\n\tif(TJSObjectHashMapLog->Read(&cid, sizeof(char)) != sizeof(char))\n\t\treturn liiEnd;\n\treturn (tTJSObjectHashMapLogItemId)(cid);\n}\n//---------------------------------------------------------------------------\nstruct tTJSObjectHashMapRecord\n{\n\tttstr History; // call history where the object was created\n\tttstr Where; // a label which indicates where the object was created\n\tttstr Type; // object type (\"class Array\" etc)\n\ttjs_uint32 Flags;\n\n\ttTJSObjectHashMapRecord() : Flags(TJS_OHMF_EXIST) {;}\n\n\tvoid StoreLog()\n\t{\n\t\t// store the object into log stream\n\t\tTJSStoreLog(History);\n\t\tTJSStoreLog(Where);\n\t\tTJSStoreLog(Type);\n\t\tTJSStoreLog(Flags);\n\t}\n\n\tvoid RestoreLog()\n\t{\n\t\t// restore the object from log stream\n\t\tHistory = TJSRestoreLog<ttstr>();\n\t\tWhere   = TJSRestoreLog<ttstr>();\n\t\tType    = TJSRestoreLog<ttstr>();\n\t\tFlags   = TJSRestoreLog<tjs_uint32>();\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTJSObjectHashMapRecordComparator_HistoryAndType\n{\npublic:\n\tbool operator () (const tTJSObjectHashMapRecord & lhs,\n\t\tconst tTJSObjectHashMapRecord & rhs) const\n\t{\n\t\tif(lhs.Where == rhs.Where)\n\t\t\treturn lhs.Type < rhs.Type;\n\t\treturn lhs.History < rhs.History;\n\t}\n};\n\nclass tTJSObjectHashMapRecordComparator_Type\n{\npublic:\n\tbool operator () (const tTJSObjectHashMapRecord & lhs,\n\t\tconst tTJSObjectHashMapRecord & rhs) const\n\t{\n\t\treturn lhs.Type < rhs.Type;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTJSObjectHashMap;\ntTJSObjectHashMap * TJSObjectHashMap;\nclass tTJSObjectHashMap\n{\n\ttypedef\n\t\ttTJSHashTable<void *, tTJSObjectHashMapRecord,\n\t\t\ttTJSHashFunc<void *>, 1024>\n\t\ttHash;\n\ttHash Hash;\n\n\ttjs_int RefCount;\n\n\npublic:\n\ttTJSObjectHashMap()\n\t{\n\t\tRefCount = 1;\n\t\tTJSObjectHashMap = this;\n\t}\n\nprotected:\n\t~tTJSObjectHashMap()\n\t{\n\t\tTJSObjectHashMap = NULL;\n\t}\n\nprotected:\n\tvoid _AddRef() { RefCount ++; }\n\tvoid _Release() { if(RefCount == 1) delete this; else RefCount --; }\n\n\npublic:\n\tstatic void AddRef()\n\t{\n\t\tif(TJSObjectHashMap)\n\t\t\tTJSObjectHashMap->_AddRef();\n\t\telse\n\t\t\tnew tTJSObjectHashMap();\n\t}\n\n\tstatic void Release()\n\t{\n\t\tif(TJSObjectHashMap)\n\t\t\tTJSObjectHashMap->_Release();\n\t}\n\n\n\tvoid Add(void * object,\n\t\tconst tTJSObjectHashMapRecord & record)\n\t{\n\t\tHash.Add(object, record);\n\t}\n\n\tvoid SetType(void * object, const ttstr & info)\n\t{\n\t\ttTJSObjectHashMapRecord * rec;\n\t\trec = Hash.Find(object);\n\t\tif(!rec) return;\n\t\trec->Type = TJSMapGlobalStringMap(info);\n\t}\n\n\tttstr GetType(void * object)\n\t{\n\t\ttTJSObjectHashMapRecord * rec;\n\t\trec = Hash.Find(object);\n\t\tif(!rec) return ttstr();\n\t\treturn rec->Type;\n\t}\n\n\tvoid SetFlag(void * object, tjs_uint32 flags_to_change, tjs_uint32 bits)\n\t{\n\t\ttTJSObjectHashMapRecord * rec;\n\t\trec = Hash.Find(object);\n\t\tif(!rec) return;\n\t\trec->Flags &=  (~flags_to_change);\n\t\trec->Flags |=  (bits & flags_to_change);\n\t}\n\n\ttjs_uint32 GetFlag(void * object)\n\t{\n\t\ttTJSObjectHashMapRecord * rec;\n\t\trec = Hash.Find(object);\n\t\tif(!rec) return 0;\n\t\treturn rec->Flags;\n\t}\n\n\tvoid Remove(void * object)\n\t{\n\t\tHash.Delete(object);\n\t}\n\n\tvoid WarnIfObjectIsDeleting(iTJSConsoleOutput * output, void * object)\n\t{\n\t\ttTJSObjectHashMapRecord * rec;\n\t\trec = Hash.Find(object);\n\t\tif(!rec) return;\n\n\t\tif(rec->Flags & TJS_OHMF_DELETING)\n\t\t{\n\t\t\t// warn running code on deleting-in-progress object\n\t\t\tttstr warn(TJSWarning);\n\t\t\ttjs_char tmp[64];\n\t\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"0x%p\"), object);\n\n\t\t\tttstr info(TJSWarnRunningCodeOnDeletingObject);\n\t\t\tinfo.Replace(TJS_W(\"%1\"), tmp);\n\t\t\tinfo.Replace(TJS_W(\"%2\"), rec->Type);\n\t\t\tinfo.Replace(TJS_W(\"%3\"), rec->Where);\n\t\t\tinfo.Replace(TJS_W(\"%4\"), TJSGetStackTraceString(1));\n\n\t\t\toutput->Print((warn + info).c_str());\n\t\t}\n\t}\n\n\tvoid ReportAllUnfreedObjects(iTJSConsoleOutput * output)\n\t{\n\t\t{\n\t\t\tttstr msg = (const tjs_char *)TJSNObjectsWasNotFreed;\n\t\t\tmsg.Replace(TJS_W(\"%1\"), ttstr((tjs_int)Hash.GetCount()));\n\t\t\toutput->Print(msg.c_str());\n\t\t}\n\n\t\t// list all unfreed objects\n\t\ttHash::tIterator i;\n\t\tfor(i = Hash.GetFirst(); !i.IsNull(); i++)\n\t\t{\n\t\t\ttjs_char addr[65];\n\t\t\tTJS_snprintf(addr, sizeof(addr)/sizeof(tjs_char), TJS_W(\"0x%p\"), i.GetKey());\n\t\t\tttstr info = (const tjs_char *)TJSObjectWasNotFreed;\n\t\t\tinfo.Replace(TJS_W(\"%1\"), addr);\n\t\t\tinfo.Replace(TJS_W(\"%2\"), i.GetValue().Type);\n\t\t\tinfo.Replace(TJS_W(\"%3\"), i.GetValue().History);\n\t\t\toutput->Print(info.c_str());\n\t\t}\n\n\t\t// group by the history and object type\n\t\toutput->Print(TJS_W(\"---\"));\n\t\toutput->Print((const tjs_char *)TJSGroupByObjectTypeAndHistory);\n\t\tstd::vector<tTJSObjectHashMapRecord> items;\n\t\tfor(i = Hash.GetFirst(); !i.IsNull(); i++)\n\t\t\titems.push_back(i.GetValue());\n\n\t\tstd::stable_sort(items.begin(), items.end(),\n\t\t\ttTJSObjectHashMapRecordComparator_HistoryAndType());\n\n\t\tttstr history, type;\n\t\ttjs_int count = 0;\n\t\tif(items.size() > 0)\n\t\t{\n\t\t\tfor(std::vector<tTJSObjectHashMapRecord>::iterator i = items.begin();\n\t\t\t\t; i++)\n\t\t\t{\n\t\t\t\tif(i != items.begin() &&\n\t\t\t\t\t(i == items.end() || history != i->History || type != i->Type))\n\t\t\t\t{\n\t\t\t\t\ttjs_char tmp[64];\n\t\t\t\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"%6d\"), (int)count);\n\t\t\t\t\tttstr info = (const tjs_char *)TJSObjectCountingMessageGroupByObjectTypeAndHistory;\n\t\t\t\t\tinfo.Replace(TJS_W(\"%1\"), tmp);\n\t\t\t\t\tinfo.Replace(TJS_W(\"%2\"), type);\n\t\t\t\t\tinfo.Replace(TJS_W(\"%3\"), history);\n\t\t\t\t\toutput->Print(info.c_str());\n\n\t\t\t\t\tif(i == items.end()) break;\n\n\t\t\t\t\tcount = 0;\n\t\t\t\t}\n\n\t\t\t\thistory = i->History;\n\t\t\t\ttype = i->Type;\n\t\t\t\tcount ++;\n\t\t\t}\n\t\t}\n\n\t\t// group by object type\n\t\toutput->Print(TJS_W(\"---\"));\n\t\toutput->Print((const tjs_char *)TJSGroupByObjectType);\n\t\tstd::stable_sort(items.begin(), items.end(),\n\t\t\ttTJSObjectHashMapRecordComparator_Type());\n\n\t\ttype.Clear();\n\t\tcount = 0;\n\t\tif(items.size() > 0)\n\t\t{\n\t\t\tfor(std::vector<tTJSObjectHashMapRecord>::iterator i = items.begin();\n\t\t\t\t; i++)\n\t\t\t{\n\t\t\t\tif(i != items.begin() &&\n\t\t\t\t\t(i == items.end() || type != i->Type))\n\t\t\t\t{\n\t\t\t\t\ttjs_char tmp[64];\n\t\t\t\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"%6d\"), (int)count);\n\t\t\t\t\tttstr info = (const tjs_char *)TJSObjectCountingMessageTJSGroupByObjectType;\n\t\t\t\t\tinfo.Replace(TJS_W(\"%1\"), tmp);\n\t\t\t\t\tinfo.Replace(TJS_W(\"%2\"), type);\n\t\t\t\t\toutput->Print(info.c_str());\n\n\t\t\t\t\tif(i == items.end()) break;\n\n\t\t\t\t\tcount = 0;\n\t\t\t\t}\n\n\t\t\t\ttype = i->Type;\n\t\t\t\tcount ++;\n\t\t\t}\n\t\t}\n\t}\n\n\tbool AnyUnfreed()\n\t{\n\t\treturn Hash.GetCount() != 0;\n\t}\n\n\tvoid WriteAllUnfreedObjectsToLog()\n\t{\n\t\tif(!TJSObjectHashMapLog) return;\n\t\t\t\n\t\ttHash::tIterator i;\n\t\tfor(i = Hash.GetFirst(); !i.IsNull(); i++)\n\t\t{\n\t\t\tTJSStoreLog(liiAdd);\n\t\t\tTJSStoreLog(i.GetKey());\n\t\t\ti.GetValue().StoreLog();\n\t\t}\n\t}\n\n\tvoid ReplayLog()\n\t{\n\t\t// replay recorded log\n\t\twhile(true)\n\t\t{\n\t\t\ttTJSObjectHashMapLogItemId id = TJSRestoreLog<tTJSObjectHashMapLogItemId>();\n\t\t\tif(id == liiEnd)          // 00 end of the log\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if(id == liiVersion) // 01 identify log structure version\n\t\t\t{\n\t\t\t\ttjs_int v = TJSRestoreLog<tjs_int>();\n\t\t\t\tif(v != TJSVersionHex)\n\t\t\t\t\tTJS_eTJSError( TJSObjectHashMapLogVersionMismatch );\n\t\t\t}\n\t\t\telse if(id == liiAdd)     // 02 add a object\n\t\t\t{\n\t\t\t\tvoid * object = TJSRestoreLog<void*>();\n\t\t\t\ttTJSObjectHashMapRecord rec;\n\t\t\t\trec.RestoreLog();\n\t\t\t\tAdd(object, rec);\n\t\t\t}\n\t\t\telse if(id == liiRemove)  // 03 remove a object\n\t\t\t{\n\t\t\t\tvoid * object = TJSRestoreLog<void*>();\n\t\t\t\tRemove(object);\n\t\t\t}\n\t\t\telse if(id == liiSetType) // 04 set object type information\n\t\t\t{\n\t\t\t\tvoid * object = TJSRestoreLog<void*>();\n\t\t\t\tttstr type = TJSRestoreLog<ttstr>();\n\t\t\t\tSetType(object, type);\n\t\t\t}\n\t\t\telse if(id == liiSetFlag) // 05 set object flag\n\t\t\t{\n\t\t\t\tvoid * object = TJSRestoreLog<void*>();\n\t\t\t\ttjs_uint32 flags_to_change = TJSRestoreLog<tjs_uint32>();\n\t\t\t\ttjs_uint32 bits = TJSRestoreLog<tjs_uint32>();\n\t\t\t\tSetFlag(object, flags_to_change, bits);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTJS_eTJSError( TJSCurruptedObjectHashMapLog );\n\t\t\t}\n\t\t}\n\t}\n\n};\n//---------------------------------------------------------------------------\nvoid TJSAddRefObjectHashMap()\n{\n\ttTJSObjectHashMap::AddRef();\n}\n//---------------------------------------------------------------------------\nvoid TJSReleaseObjectHashMap()\n{\n\ttTJSObjectHashMap::Release();\n}\n//---------------------------------------------------------------------------\nvoid TJSAddObjectHashRecord(void * object)\n{\n\tif(!TJSObjectHashMap && !TJSObjectHashMapLog) return;\n\n\t// create object record and log\n\ttTJSObjectHashMapRecord rec;\n\tttstr hist(TJSGetStackTraceString(4, (const tjs_char *)(TJSObjectCreationHistoryDelimiter)));\n\tif(hist.IsEmpty())\n\t\thist = TJSMapGlobalStringMap((const tjs_char *)TJSCallHistoryIsFromOutOfTJS2Script);\n\trec.History = hist;\n\tttstr where(TJSGetStackTraceString(1));\n\tif(where.IsEmpty())\n\t\twhere = TJSMapGlobalStringMap((const tjs_char *)TJSCallHistoryIsFromOutOfTJS2Script);\n\trec.Where = where;\n\tstatic ttstr InitialType(TJS_W(\"unknown type\"));\n\trec.Type = InitialType;\n\n\tif(TJSObjectHashMap)\n\t{\n\t\tTJSObjectHashMap->Add(object, rec);\n\t}\n\telse if(TJSObjectHashMapLog)\n\t{\n\t\tTJSStoreLog(liiAdd);\n\t\tTJSStoreLog(object);\n\t\trec.StoreLog();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSRemoveObjectHashRecord(void * object)\n{\n\tif(TJSObjectHashMap)\n\t{\n\t\tTJSObjectHashMap->Remove(object);\n\t}\n\telse if(TJSObjectHashMapLog)\n\t{\n\t\tTJSStoreLog(liiRemove);\n\t\tTJSStoreLog(object);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSObjectHashSetType(void * object, const ttstr &type)\n{\n\tif(TJSObjectHashMap)\n\t{\n\t\tTJSObjectHashMap->SetType(object, type);\n\t}\n\telse if(TJSObjectHashMapLog)\n\t{\n\t\tTJSStoreLog(liiSetType);\n\t\tTJSStoreLog(object);\n\t\tTJSStoreLog(type);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSSetObjectHashFlag(void *object, tjs_uint32 flags_to_change, tjs_uint32 bits)\n{\n\tif(TJSObjectHashMap)\n\t{\n\t\tTJSObjectHashMap->SetFlag(object, flags_to_change, bits);\n\t}\n\telse if(TJSObjectHashMapLog)\n\t{\n\t\tTJSStoreLog(liiSetFlag);\n\t\tTJSStoreLog(object);\n\t\tTJSStoreLog(flags_to_change);\n\t\tTJSStoreLog(bits);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSReportAllUnfreedObjects(iTJSConsoleOutput * output)\n{\n\tif(TJSObjectHashMap) TJSObjectHashMap->ReportAllUnfreedObjects(output);\n}\n//---------------------------------------------------------------------------\nbool TJSObjectHashAnyUnfreed()\n{\n\tif(TJSObjectHashMap) return TJSObjectHashMap->AnyUnfreed();\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid TJSObjectHashMapSetLog(tTJSBinaryStream * stream)\n{\n\t// Set log object. The log file object should not freed until\n\t// the program (the program is the Process, not RTL nor TJS2 framework).\n\tTJSObjectHashMapLog = stream;\n\tTJSStoreLog(liiVersion);\n\tTJSStoreLog(TJSVersionHex);\n}\n//---------------------------------------------------------------------------\nvoid TJSWriteAllUnfreedObjectsToLog()\n{\n\tif(TJSObjectHashMap && TJSObjectHashMapLog) TJSObjectHashMap->WriteAllUnfreedObjectsToLog();\n}\n//---------------------------------------------------------------------------\nvoid TJSWarnIfObjectIsDeleting(iTJSConsoleOutput * output, void * object)\n{\n\tif(TJSObjectHashMap) TJSObjectHashMap->WarnIfObjectIsDeleting(output, object);\n}\n//---------------------------------------------------------------------------\nvoid TJSReplayObjectHashMapLog()\n{\n\tif(TJSObjectHashMap && TJSObjectHashMapLog) TJSObjectHashMap->ReplayLog();\n}\n//---------------------------------------------------------------------------\nttstr TJSGetObjectTypeInfo(void * object)\n{\n\tif(TJSObjectHashMap) return TJSObjectHashMap->GetType(object);\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\ntjs_uint32 TJSGetObjectHashCheckFlag(void * object)\n{\n\tif(TJSObjectHashMap) return TJSObjectHashMap->GetFlag(object);\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// StackTracer : stack to trace function call trace\n//---------------------------------------------------------------------------\nclass tTJSStackTracer;\ntTJSStackTracer * TJSStackTracer;\n//---------------------------------------------------------------------------\nstruct tTJSStackRecord\n{\n\ttTJSInterCodeContext * Context;\n\tconst tjs_int * CodeBase;\n\ttjs_int * const * CodePtr;\n\tbool InTry;\n\n\ttTJSStackRecord(tTJSInterCodeContext * context, bool in_try)\n\t{\n\t\tCodeBase = NULL;\n\t\tCodePtr = NULL;\n\t\tInTry = in_try;\n\t\tContext = context;\n\t\tif(Context) Context->AddRef();\n\t}\n\n\t~tTJSStackRecord()\n\t{\n\t\tif(Context) Context->Release();\n\t}\n\n\ttTJSStackRecord(const tTJSStackRecord & rhs)\n\t{\n\t\tContext = NULL;\n\t\t*this = rhs;\n\t}\n\n\tvoid operator = (const tTJSStackRecord & rhs)\n\t{\n\t\tif(Context != rhs.Context)\n\t\t{\n\t\t\tif(Context) Context->Release(), Context = NULL;\n\t\t\tContext = rhs.Context;\n\t\t\tif(Context) Context->AddRef();\n\t\t}\n\t\tCodeBase = rhs.CodeBase;\n\t\tCodePtr = rhs.CodePtr;\n\t\tInTry = rhs.InTry;\n\t}\n};\n\n//---------------------------------------------------------------------------\nclass tTJSStackTracer\n{\n\tstd::vector<tTJSStackRecord> Stack;\n\n\ttjs_int RefCount;\n\npublic:\n\ttTJSStackTracer()\n\t{\n\t\tRefCount = 1;\n\t\tTJSStackTracer = this;\n\t}\n\nprotected:\n\t~tTJSStackTracer()\n\t{\n\t\tTJSStackTracer = NULL;\n\t}\n\nprotected:\n\tvoid _AddRef() { RefCount ++; }\n\tvoid _Release() { if(RefCount == 1) delete this; else RefCount --; }\n\npublic:\n\tstatic void AddRef()\n\t{\n\t\tif(TJSStackTracer)\n\t\t\tTJSStackTracer->_AddRef();\n\t\telse\n\t\t\tnew tTJSStackTracer();\n\t}\n\n\tstatic void Release()\n\t{\n\t\tif(TJSStackTracer)\n\t\t\tTJSStackTracer->_Release();\n\t}\n\n\tvoid Push(tTJSInterCodeContext *context, bool in_try)\n\t{\n\t\tStack.push_back(tTJSStackRecord(context, in_try));\n\t}\n\n\tvoid Pop()\n\t{\n\t\tStack.pop_back();\n\t}\n\n\tvoid SetCodePointer(const tjs_int32 * codebase, tjs_int32 * const * codeptr)\n\t{\n\t\ttjs_uint size = (tjs_uint)Stack.size();\n\t\tif(size < 1) return;\n\t\ttjs_uint top = size - 1;\n\t\tStack[top].CodeBase = codebase;\n\t\tStack[top].CodePtr = codeptr;\n\t}\n\n\tttstr GetTraceString(tjs_int limit, const tjs_char * delimiter)\n\t{\n\t\t// get stack trace string\n\t\tif(delimiter == NULL) delimiter = TJS_W(\" <-- \");\n\n\t\tttstr ret;\n\t\ttjs_int top = (tjs_int)(Stack.size() - 1);\n\t\twhile(top >= 0)\n\t\t{\n\t\t\tif(!ret.IsEmpty()) ret += delimiter;\n\n\t\t\tconst tTJSStackRecord & rec = Stack[top];\n\t\t\tttstr str;\n\t\t\tif(rec.CodeBase && rec.CodePtr)\n\t\t\t{\n\t\t\t\tstr = rec.Context->GetPositionDescriptionString(\n\t\t\t\t\t(tjs_int)(*rec.CodePtr - rec.CodeBase));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstr = rec.Context->GetPositionDescriptionString(0);\n\t\t\t}\n\n\t\t\tret += str;\n\n\t\t\t// skip try block stack.\n\t\t\t// 'try { } catch' blocks are implemented as sub-functions\n\t\t\t// in a parent function.\n\t\t\twhile(top >= 0 && Stack[top].InTry) top--;\n\n\t\t\t// check limit\n\t\t\tif(limit)\n\t\t\t{\n\t\t\t\tlimit --;\n\t\t\t\tif(limit <= 0) break;\n\t\t\t}\n\n\t\t\ttop --;\n\t\t}\n\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\nvoid TJSAddRefStackTracer()\n{\n\ttTJSStackTracer::AddRef();\n}\n//---------------------------------------------------------------------------\nvoid TJSReleaseStackTracer()\n{\n\ttTJSStackTracer::Release();\n}\n//---------------------------------------------------------------------------\nvoid TJSStackTracerPush(tTJSInterCodeContext *context, bool in_try)\n{\n\tif(TJSStackTracer)\n\t\tTJSStackTracer->Push(context, in_try);\n}\n//---------------------------------------------------------------------------\nvoid TJSStackTracerSetCodePointer(const tjs_int32 * codebase,\n\ttjs_int32 * const * codeptr)\n{\n\tif(TJSStackTracer)\n\t\tTJSStackTracer->SetCodePointer(codebase, codeptr);\n}\n//---------------------------------------------------------------------------\nvoid TJSStackTracerPop()\n{\n\tif(TJSStackTracer)\n\t\tTJSStackTracer->Pop();\n}\n//---------------------------------------------------------------------------\nttstr TJSGetStackTraceString(tjs_int limit, const tjs_char *delimiter)\n{\n\tif(TJSStackTracer)\n\t\treturn TJSStackTracer->GetTraceString(limit, delimiter);\n\telse\n\t\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n\n#if ENABLE_DEBUGGER\n#if 0\nclass DebuggerMessage : public COPYDATASTRUCT\n{\npublic:\n\tDebuggerMessage( int messageType, void* data, size_t length ) {\n\t\tdwData = messageType;\n\t\tcbData = length;\n\t\tlpData = data;\n\t}\n};\n\nclass Debugger {\npublic:\n\t//! 1MBʐM̈ƂĊmۂA܂Ȃ\n\t//! {ł΁AV{e[üĂƂ\n\tstatic const int DEBUGGER_COMM_AREA_MAX = 1024 * 1024;\n\nprivate:\n\tHWND\t\t\tDebuggerHwnd;\t//!< fobKEBhEnh\n\tstd::wstring\tLastScriptFileName;\n\ttjs_int\t\t\tLastLineNo;\n\n\tstd::wstring\tBreakScriptFileName;\n\tint\t\t\t\tBreakLineNo;\n\n\tBreakpoints\t\tBreakPoints;\n\n\tint\t\t\t\tStepNest;\n\n\tint\t\tTypeOfExec;\n\tbool\tIsInitialConnect;\t//!< ڑς݂ǂ\n\tbool\tIsHandleException;\t//!< Oɒ~āAfobK̍Ďsv҂ǂ\n\tint\t\tStackTraceDepth;\n\n\tNativeEventQueue<Debugger> DummyWindow;\n\n\t// ݂̎s\n\tenum {\n\t\tEXEC_STOP,\t//!< sĂȂ(braek)\n\t\tEXEC_STEP,\t//!< Xebvs\n\t\tEXEC_TRACE,\t//!< g[Xs\n\t\tEXEC_RETURN,//!< ^[s\n\t\tEXEC_RUN,\t//!< ʏs\n\t};\n\n\tchar DubuggerCommArea[DEBUGGER_COMM_AREA_MAX];\n\t// ȉ̂悤ȍ\\ŁAu[N畜AɃfobK̗̈ɏ܂B\n\t// ̈𒴂Ȃ悤ɂ̂̓fobK̐ӔC\n\tstruct DebuggerCommand {\n\t\tint\t\tCommand;\n\t\tint\t\tNextOffset;\t//!< ̃R}h̐擪玟̃f[^܂ł̃ItZbg(ACgĂ)\n\t\tint\t\tSize;\t\t\t//!< data ̃TCY\n\t\tchar\tData[1];\n\t};\n\tstruct DebuggerHeader {\n\t\tint\t\t\t\tNumOfCommand;\n\t\tDebuggerCommand\tCommands;\n\t};\n\t\n\tvoid Proc( NativeEvent& ev ) {\n\t\tDummyWindow.HandlerDefault(ev);\n\t\treturn;\n\t}\npublic:\n\tDebugger()\n\t : DebuggerHwnd(INVALID_HANDLE_VALUE), LastLineNo(-1), TypeOfExec(EXEC_RUN)\n\t , IsInitialConnect(false), StackTraceDepth(10)\n\t , DummyWindow(this,&Debugger::Proc)\n\t{\n\t\tInitialize();\n\t\tDummyWindow.Allocate();\n\t}\n\t~Debugger() {\n\t\tDummyWindow.Deallocate();\n\t}\n\tvoid Initialize() {\n\t\tDebuggerHwnd = ::FindWindow(L\"TScriptDebuggerForm\",NULL);\t//!< Oߑł\n\t\tif( DebuggerHwnd == 0 ) {\n\t\t\tDebuggerHwnd = INVALID_HANDLE_VALUE;\n\t\t}\n\t}\n\tvoid PrintLog( const tjs_char* mes, bool important ) {\n\t\tif( DebuggerHwnd != INVALID_HANDLE_VALUE ) {\n\t\t\tHWND hwnd = DummyWindow.GetOwner();\n\t\t\tDebuggerMessage\tmessage( DBGEV_GEE_LOG, (void*)mes, (TJS_strlen(mes) + 1) * sizeof(tjs_char) );\n\t\t\t::SendMessage( DebuggerHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&message );\n\t\t}\n\t}\n\tvoid DebugHook( tjs_int evtype, const tjs_char *filename, tjs_int lineno, tTJSInterCodeContext* ctx ) {\n\t\tif( evtype == DBGHOOK_PREV_EXCEPT ) {\n\t\t\tStepNest = 0;\n\t\t\treturn;\t// Ƃ肠O͖Ă\n\t\t}\n\n\t\tif( filename == NULL ) return;\n\t\tif( CheckDebuggerInit() == false ) return;\n\n\t\tHandleBreakCommand();\t// u[NvĂĂ邩ׂ\n\n\t\tBreakScriptFileName = std::wstring(filename);\n\t\tBreakLineNo = lineno;\n\n\t\tbool is_change_line = false;\n\t\tif( LastLineNo != lineno ) {\n\t\t\tis_change_line = true;\n\t\t} else if( LastScriptFileName != BreakScriptFileName ) {\n\t\t\t// XNvgt@Cς\n\t\t\tis_change_line = true;\n\t\t}\n\t\tLastScriptFileName = BreakScriptFileName;\n\t\tLastLineNo = BreakLineNo;\n\n\t\tif( evtype == DBGHOOK_PREV_BREAK ) {\n\t\t\tWaitExec(ctx);\t// uCNŎ~߂\n\t\t} else {\n\t\t\tswitch( TypeOfExec ) {\n\t\t\t\tcase EXEC_RUN:\n\t\t\t\t\tif( is_change_line && IsBreakPoint( filename, lineno ) ) {\n\t\t\t\t\t\tWaitExec(ctx);\t// uCNŎ~߂\n\t\t\t\t\t}\n\t\t\t\t\t// uCN|CgłȂ͖\n\t\t\t\t\tbreak;\n\t\t\t\tcase EXEC_TRACE:\n\t\t\t\t\tif( is_change_line ) {;\n\t\t\t\t\t\tWaitExec(ctx);\t// uCNŎ~߂\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase EXEC_RETURN:\n\t\t\t\t\tif( evtype == DBGHOOK_PREV_RETURN ) {\n\t\t\t\t\t\t// ̃XebvŎ~߂\n\t\t\t\t\t\tTypeOfExec = EXEC_STEP;\n\t\t\t\t\t\tStepNest = 0;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase EXEC_STEP:\n\t\t\t\t\tif( evtype == DBGHOOK_PREV_CALL ) StepNest++;\n\t\t\t\t\telse if( evtype == DBGHOOK_PREV_RETURN ) StepNest--;\n\t\t\t\t\telse if( evtype == DBGHOOK_PREV_EXE_LINE ) {\n\t\t\t\t\t\tif( StepNest <= 0 ) {;\n\t\t\t\t\t\t\tWaitExec(ctx);\t// uCNŎ~߂\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase EXEC_STOP:\n\t\t\t\t\tWaitExec(ctx);\t// uCNŎ~߂\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tbool CheckDebuggerInit() {\n\t\tif( IsInitialConnect == false ) {\n\t\t\t// fobKɃbZ[WėOʒmLAu[N|CgȂǂ擾\n\t\t\tInitializeConnection();\n\t\t}\n\t\treturn IsInitialConnect;\n\t}\nprivate:\n\t//! v[N|CgƂƂĐݒ肳Ă邩ǂ\n\tbool IsBreakPoint( const tjs_char *filename, tjs_int lineno ) {\n\t\treturn BreakPoints.IsBreakPoint( filename, lineno );\n\t}\n\tvoid SendBreak() {\n\t\tif( DebuggerHwnd != INVALID_HANDLE_VALUE ) {\n\t\t\tHWND hwnd = DummyWindow.GetOwner();\n\t\t\tsize_t len = sizeof(int) + (BreakScriptFileName.size() + 1) * sizeof(wchar_t);\n\t\t\tstd::vector<char>\tbuff(len);\n\t\t\t(*(int*)&(buff[0])) = BreakLineNo;\n\t\t\tmemcpy( &(buff[sizeof(int)]), BreakScriptFileName.c_str(), (BreakScriptFileName.size()+1) * sizeof(wchar_t) );\n\t\t\tDebuggerMessage\tmessage( DBGEV_GEE_BREAK, &(buff[0]), len );\n\t\t\t::SendMessage( DebuggerHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&message );\n\t\t}\n\t}\n\tvoid SendStackTrace() {\n\t\tif( DebuggerHwnd != INVALID_HANDLE_VALUE && StackTraceDepth > 0 ) {\n\t\t\tHWND hwnd = DummyWindow.GetOwner();\n\t\t\tttstr result = TJSGetStackTraceString( StackTraceDepth );\n\t\t\tDebuggerMessage\tmessage( DBGEV_GEE_STACK_TRACE, (void*)result.c_str(), (result.GetLen()+1) * sizeof(tjs_char) );\n\t\t\t::SendMessage( DebuggerHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&message );\n\t\t}\n\t}\n\tvoid SendLocalValue( tTJSInterCodeContext* ctx ) {\n\t\tif( ctx == NULL ) return;\n\t\tstd::list<std::wstring> values;\n\t\tTJSDebuggerGetLocalVariableString( ctx->GetDebuggerScopeKey(), ctx->GetDebuggerRegisterArea(), values );\n\t\tSendValues( values, DBGEV_GEE_LOCAL_VALUE );\n\t}\n\tvoid SendClassValue( tTJSInterCodeContext* ctx ) {\n\t\tif( ctx == NULL ) return;\n\t\tstd::list<std::wstring> values;\n\t\tTJSDebuggerGetClassVariableString( ctx->GetSelfClassName().c_str(), ctx->GetDebuggerRegisterArea(), ctx->GetDebuggerDataArea(), values );\n\t\tSendValues( values, DBGEV_GEE_CLASS_VALUE );\n\t}\n\n\tvoid SendValues( const std::list<std::wstring>& values, int command ) {\n\t\tif( values.size() > 0 ) {\n\t\t\tsize_t bufflen = 0;\n\t\t\tbufflen += sizeof(int);\t// counts\n\t\t\tfor( std::list<std::wstring>::const_iterator i = values.begin(); i != values.end(); ++i ) {\n\t\t\t\tbufflen += ((*i).size() + 1) * sizeof(wchar_t);\n\t\t\t}\n\t\t\tint count = values.size() / 2;\n\t\t\tstd::vector<char>\tbuff(bufflen);\n\t\t\t(*(int*)&(buff[0])) = count;\n\t\t\twchar_t* strbuff = (wchar_t*)&buff[sizeof(int)];\n\t\t\tfor( std::list<std::wstring>::const_iterator i = values.begin(); i != values.end(); ++i ) {\n\t\t\t\tint wstr_len = ((*i).size() + 1);\n\t\t\t\tmemcpy( strbuff, (*i).c_str(), wstr_len * sizeof(wchar_t) );\n\t\t\t\tstrbuff += wstr_len;\n\t\t\t}\n\t\t\tif( DebuggerHwnd != INVALID_HANDLE_VALUE ) {\n\t\t\t\tHWND hwnd = DummyWindow.GetOwner();\n\t\t\t\tDebuggerMessage\tmessage( command, &(buff[0]), bufflen );\n\t\t\t\t::SendMessage( DebuggerHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&message );\n\t\t\t}\n\t\t}\n\t}\n\t/*\n\tHWND GetSelfWindowHandle() {\n\t\treturn Application->GetHandle();\n\t}\n\t*/\n\t//! u[N\n\tvoid BreakOccur( tTJSInterCodeContext* ctx ) {\n\t\tSendBreak();\n\t\tSendStackTrace();\n\t\tSendLocalValue( ctx );\n\t\tSendClassValue( ctx );\n\t}\n\t// 𑗂Ă悤ɗvƓɏݑΏۃAhXʒm\n\tvoid RequestSetting() {\n\t\tif( DebuggerHwnd != INVALID_HANDLE_VALUE ) {\n\t\t\tHWND hwnd = DummyWindow.GetOwner();\n\t\t\tint buff[2] = { (int)&DubuggerCommArea, DEBUGGER_COMM_AREA_MAX };\n\t\t\tDebuggerMessage\tmessage( DBGEV_GEE_REQUEST_SETTINGS, buff, sizeof(int)*2 );\n\t\t\t::SendMessage( DebuggerHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&message );\n\t\t}\n\t}\n\tvoid InitializeConnection() {\n\t\tif( IsInitialConnect ) return;\n\t\tif( DebuggerHwnd == INVALID_HANDLE_VALUE ) return;\n\t\tif( !::IsDebuggerPresent() ) return;\n\n\t\tRequestSetting();\n\t\twhile(true) {\n\t\t\tClearCommand();\n\t\t\t::DebugBreak();\t// Break!\n\t\t\tif( HandleDebuggerMessage() ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tIsInitialConnect = true;\n\t}\n\tvoid WaitExec( tTJSInterCodeContext* ctx ) {\n\t\tif( IsInitialConnect == false ) return;\n\t\tif( DebuggerHwnd == INVALID_HANDLE_VALUE ) return;\n\t\tif( !::IsDebuggerPresent() ) return;\n\n\t\tBreakOccur( ctx );\t// u[NʒuƃX^bNg[X𑗂BŃ[Jϐ\n\t\twhile(true) {\n\t\t\tClearCommand();\n\t\t\t::DebugBreak();\t// Break!\n\t\t\tif( HandleDebuggerMessage() ) {\n\t\t\t\t// {Iɂ́A1̃u[NőSf[^炦̂ǁA\n\t\t\t\t// 1MBɂ܂ȂƂ͎dȂB\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tClearCommand();\n\t\tStepNest = 0;\n\t}\n\t//! @return sJn邩ǂ\n\t//! @retval true : R}hǂݎ芮\n\t//! @retval false : ̃R}h͂Ȃ̂ŁAēxu[NăR}h𓾂\n\tbool HandleDebuggerMessage() {\n\t\tint count = GetNumOfCommands();\n\t\tconst DebuggerCommand* cmd = GetFirstCommand();\n\t\tfor( int i = 0; cmd && (i < count); i++ ) {\n\t\t\tswitch( GetCommand(cmd) ) {\n\t\t\t\tcase DBGEV_GER_EXEC:\tTypeOfExec = EXEC_RUN; return true;\n\t\t\t\tcase DBGEV_GER_BREAK:\tTypeOfExec = EXEC_STOP; break;\n\t\t\t\tcase DBGEV_GER_STEP:\tTypeOfExec = EXEC_STEP; return true;\n\t\t\t\tcase DBGEV_GER_TRACE:\tTypeOfExec = EXEC_TRACE; return true;\n\t\t\t\tcase DBGEV_GER_RETURN:\tTypeOfExec = EXEC_RETURN; return true;\n\n\t\t\t\tcase DBGEV_GER_BREAKPOINT_START:\n\t\t\t\t\tBreakPoints.ClearAll();\n\t\t\t\t\tbreak;\n\t\t\t\tcase DBGEV_GER_BREAKPOINT:\n\t\t\t\t\tHandleBreakpoint(cmd);\n\t\t\t\t\tbreak;\n\t\t\t\tcase DBGEV_GER_BREAKPOINT_END:\n\t\t\t\t\tbreak;\n\t\t\t\tcase DBGEV_GER_EXCEPTION_FLG:\n\t\t\t\t\tHandleExceptionFlag(cmd);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tassert(0);\n\t\t\t\t\t// ɂ͗Ȃ͂\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcmd = GetNextCommand(cmd);\n\t\t}\n\t\treturn false;\n\t}\n\t// ~vĂ邩ǂׂ\n\tvoid HandleBreakCommand() {\n\t\tint count = GetNumOfCommands();\n\t\tif( count ) {\n\t\t\tconst DebuggerCommand* cmd = GetFirstCommand();\n\t\t\tif( GetCommand(cmd) == DBGEV_GER_BREAK ) {\n\t\t\t\t// u[Nv\n\t\t\t\tTypeOfExec = EXEC_STOP;\n\t\t\t\tClearCommand();\n\t\t\t}\n\t\t}\n\t}\n\tvoid HandleBreakpoint( const DebuggerCommand* cmd ) {\n\t\tint length = GetCommandSize( cmd );\n\t\tif( length > sizeof(int) ) {\n\t\t\tint* points = (int*)GetCommandData( cmd );\n\t\t\tint count = *points;\n\t\t\tpoints++;\n\t\t\tlength -= sizeof(int);\n\t\t\tstd::vector<int>\tbreakpoints(count);\n\t\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\t\tbreakpoints[i] = *points;\n\t\t\t\tlength -= sizeof(int);\n\t\t\t\tpoints++;\n\t\t\t}\n\t\t\tif( count > 0 && length > 1 ) {\n\t\t\t\twchar_t* filename = (wchar_t*)points;\n\t\t\t\tstd::vector<wchar_t> name(length );\n\t\t\t\tmemcpy( &(name[0]), filename, length );\n\t\t\t\tlength /= sizeof(wchar_t);\n\t\t\t\tname[length-1] = 0;\n\t\t\t\tstd::wstring wfilename( &(name[0]) );\n\t\t\t\tBreakPoints.SetBreakPoint( wfilename, breakpoints[0] );\n\t\t\t\tBreakpointLine* lines = BreakPoints.GetBreakPointLines( wfilename );\n\t\t\t\tif( lines ) {\n\t\t\t\t\tfor( int i = 1; i < count; i++ ) {\n\t\t\t\t\t\tlines->SetBreakPoint( breakpoints[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvoid HandleExceptionFlag( const DebuggerCommand* cmd ) {\n\t\tif( GetCommandSize(cmd) > sizeof(int) ) {\n\t\t\tint* flag = (int*)GetCommandData(cmd);\n\t\t}\n\t}\n\tvoid ClearCommand() {\n\t\t((DebuggerHeader*)DubuggerCommArea)->NumOfCommand = 0;\n\t}\n\tint GetCommand( const DebuggerCommand* cmd ) const { return cmd->Command; }\n\tint GetCommandSize( const DebuggerCommand* cmd ) const { return cmd->Size; }\n\tconst char* GetCommandData( const DebuggerCommand* cmd ) const { return cmd->Data; }\n\tconst DebuggerCommand* GetNextCommand( const DebuggerCommand* cmd ) {\n\t\tif( cmd->NextOffset ) {\n\t\t\treturn (const DebuggerCommand*)(((const char*)cmd) + cmd->NextOffset);\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\tint GetNumOfCommands() const {\n\t\treturn ((DebuggerHeader*)DubuggerCommArea)->NumOfCommand;\n\t}\n\tconst DebuggerCommand* GetFirstCommand() const {\n\t\treturn &(((DebuggerHeader*)DubuggerCommArea)->Commands);\n\t}\n\n};\n#endif\n// ORNV\n// t@CƂNXƂ֐ƂϐāACfbNXɕϊĊǗ\nclass NameIndexCollection\n{\nprotected:\n\tstd::map<std::wstring,int> NameWithID;\t//!< OID̃yA\n\tstd::vector<const std::wstring*> Names;\t//!< wCfbNX̖O\n\npublic:\n\tint GetID( const std::wstring& name ) {\n\t\tstd::map<std::wstring,int>::const_iterator i = NameWithID.find( name );\n\t\tif( i != NameWithID.end() ) {\n\t\t\treturn i->second;\n\t\t}\n\t\t// tȂ̂Œǉ\n\t\tint index = Names.size();\t// z̍Ō̗vfԍ𓾂\n\t\ttypedef std::pair<std::map<std::wstring,int>::iterator, bool> name_result_t;\n\t\tname_result_t ret = NameWithID.insert( std::make_pair( name, index ) );\t// vfԍő}\n\t\tassert( ret.second );\n\t\tconst std::wstring* name_ref = &((*(ret.first)).first);\t// }Õ|Cg𓾂\n\t\tNames.push_back( name_ref );\t// ̃|C^zɕۑ\n\t\treturn index;\n\t}\n\tconst std::wstring* GetName( int id ) const {\n\t\tif( id < static_cast<int>(Names.size()) ) {\n\t\t\treturn Names[id];\n\t\t}\n\t\treturn NULL;\n\t}\n};\nstatic NameIndexCollection NameIndexCollectionData;\nint TJSGetIDFromName( const tjs_char* name ) { return NameIndexCollectionData.GetID( std::wstring(name) ); }\nconst std::wstring* TJSGetNameFormID( int id ) { return NameIndexCollectionData.GetName( id ); }\n\nvoid TJSDebuggerGetScopeKey( ScopeKey& scope, const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset ) {\n\tint classindex = -1;\n\tif( classname && classname[0] ) classindex = TJSGetIDFromName(classname);\n\n\tint funcindex = -1;\n\tif( funcname && funcname[0] ) funcindex = TJSGetIDFromName(funcname);\n\n\tint fileindex = -1;\n\tif( filename && filename[0] ) fileindex = TJSGetIDFromName(filename);\n\n\tscope.Set(classindex,funcindex,fileindex,codeoffset);\n}\n\n\nstruct LocalVariableKey {\n\tint VarIndex;\t//!< ϐCfbNX\n\tint RegAddr;\t//!< WX^AhX\n\n\tLocalVariableKey( int var, int reg )\n\t: VarIndex(var), RegAddr(reg)\n\t{}\n\tLocalVariableKey()\n\t: VarIndex(-1), RegAddr(-1)\n\t{}\n\tLocalVariableKey( const LocalVariableKey& rhs ) {\n\t\tVarIndex = rhs.VarIndex;\n\t\tRegAddr = rhs.RegAddr;\n\t}\n\tvoid Set( int var, int reg ) {\n\t\tVarIndex = var;\n\t\tRegAddr = reg;\n\t}\n};\n\nclass ClassVariableCollection {\n\ttypedef LocalVariableKey ClassVariableKey;\n\n\ttypedef std::map<int,std::list<ClassVariableKey> > variable_map_t;\n\ttypedef variable_map_t::iterator\t\titerator;\n\ttypedef variable_map_t::const_iterator\tconst_iterator;\n\tvariable_map_t\tVariables;\n\npublic:\n\tvoid ClearVar( const tjs_char* classname ) {\n\t\tint classindex = -1;\n\t\tif( classname && classname[0] ) classindex = TJSGetIDFromName(classname);\n\n\t\tvariable_map_t::iterator i = Variables.find( classindex );\n\t\tif( i != Variables.end() ) {\n\t\t\ti->second.clear();\n\t\t}\n\t}\n\n\tvoid SetVar( const tjs_char* classname, const tjs_char* varname, int regaddr ) {\n\t\tint classindex = -1;\n\t\tif( classname && classname[0] ) classindex = TJSGetIDFromName(classname);\n\n\t\tint varindex = -1;\n\t\tif( varname && varname[0] ) varindex = TJSGetIDFromName(varname);\n\n\t\tvariable_map_t::iterator i = Variables.find( classindex );\n\t\tif( i != Variables.end() ) {\n\t\t\ti->second.push_back( ClassVariableKey( varindex, regaddr ) );\n\t\t\treturn;\n\t\t}\n\t\t// tȂ̂Œǉ\n\t\ttypedef std::pair<iterator, bool> result_t;\n\t\tresult_t ret = Variables.insert( std::make_pair( classindex, std::list<ClassVariableKey>() ) );\n\t\tassert( ret.second );\n\t\tret.first->second.push_back( LocalVariableKey( varindex, regaddr ) );\n\t}\n\t// ϐƒl̃Xg𓾂\n\tvoid GetVars( const tjs_char* classname, tTJSVariant* ra, tTJSVariant* da, std::list<std::wstring>& values ) {\n\t\tvalues.clear();\n\t\tif( ra == NULL || da == NULL ) return;\n\n\t\tint classindex = -1;\n\t\tif( classname && classname[0] ) classindex = TJSGetIDFromName(classname);\n\n\t\titerator i = Variables.find( classindex );\n\t\tif( i != Variables.end() ) {\n\t\t\tstd::wstring selfclass(L\"this.\");\n\t\t\tif( classindex < 0 ) selfclass = std::wstring(L\"global.\");\n\t\t\tconst std::list<ClassVariableKey>& vars = i->second;\n\t\t\tfor( std::list<ClassVariableKey>::const_iterator j = vars.begin(); j != vars.end(); ++j ) {\n\t\t\t\tconst std::wstring* varname = TJSGetNameFormID( (*j).VarIndex );\n\t\t\t\tstd::wstring memname;\n\t\t\t\tif( varname ) {\n\t\t\t\t\tmemname = selfclass + *varname;\n\t\t\t\t} else {\n\t\t\t\t\tmemname = selfclass + std::wstring(L\"(unknown)\");\n\t\t\t\t}\n\t\t\t\ttTJSVariant* ra_code1 = TJS_GET_VM_REG_ADDR( ra, TJS_TO_VM_REG_ADDR(-1) );\n\t\t\t\ttjs_error hr = -1;\n\t\t\t\ttTJSVariant result;\n\t\t\t\tif( varname && ra_code1->Type() == tvtObject && ra_code1->AsObjectNoAddRef() ) {\n\t\t\t\t\ttTJSVariantClosure clo = ra_code1->AsObjectClosureNoAddRef();\n\t\t\t\t\tif( clo.Object ) {\n\t\t\t\t\t\thr = clo.PropGet( 0, varname->c_str(), NULL, &result, clo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\t\t\t} else {\n\t\t\t\t\t\thr = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstd::wstring value;\n\t\t\t\tif( TJS_FAILED(hr) ) {\n\t\t\t\t\tvalue = std::wstring(L\"error\");\n\t\t\t\t} else {\n\t\t\t\t\tvalue = std::wstring( TJSVariantToReadableString( result ).c_str() );\n\t\t\t\t}\n\n\t\t\t\tvalues.push_back( memname );\n\t\t\t\tvalues.push_back( value );\n\t\t\t}\n\t\t}\n\t}\n};\n\nclass LocalVariableCollection {\n\ttypedef std::map<ScopeKey,std::list<LocalVariableKey> > variable_map_t;\n\ttypedef variable_map_t::iterator\t\titerator;\n\ttypedef variable_map_t::const_iterator\tconst_iterator;\n\tvariable_map_t\tVariables;\npublic:\n\tvoid SetVar( const ScopeKey& scope, const tjs_char* varname, int regaddr ) {\n\t\tint varindex = -1;\n\t\tif( varname && varname[0] ) varindex = TJSGetIDFromName(varname);\n\n\t\titerator i = Variables.find( scope );\n\t\tif( i != Variables.end() ) {\n\t\t\t// ɃL[݂̂ŁAɒǉ\n\t\t\ti->second.push_back( LocalVariableKey(varindex,regaddr) );\n\t\t\treturn;\n\t\t}\n\t\t// tȂ̂Œǉ\n\t\ttypedef std::pair<iterator, bool> result_t;\n\t\tresult_t ret = Variables.insert( std::make_pair( scope, std::list<LocalVariableKey>() ) );\n\t\tassert( ret.second );\n\t\tret.first->second.push_back( LocalVariableKey( varindex, regaddr ) );\n\t}\n\n\tvoid SetVar( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset, const tjs_char* varname, int regaddr ) {\n\t\tScopeKey scope;\n\t\tTJSDebuggerGetScopeKey( scope, classname, funcname, filename, codeoffset );\n\t\tSetVar( scope, varname, regaddr );\n\t}\n\tvoid ClearVar( const ScopeKey& scope ) {\n\t\titerator i = Variables.find( scope );\n\t\tif( i != Variables.end() ) {\n\t\t\ti->second.clear();\n\t\t}\n\t}\n\tvoid ClearVar( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset ) {\n\t\tScopeKey scope;\n\t\tTJSDebuggerGetScopeKey( scope, classname, funcname, filename, codeoffset );\n\t\tClearVar( scope );\n\t}\n\n\t// ϐƒl̃Xg𓾂\n\tvoid GetVars( const ScopeKey& scope, tTJSVariant* ra, std::list<std::wstring>& values ) {\n\t\tvalues.clear();\n\t\tif( ra == NULL ) return;\n\t\titerator i = Variables.find( scope );\n\t\tif( i != Variables.end() ) {\n\t\t\tconst std::list<LocalVariableKey>& vars = i->second;\n\t\t\tfor( std::list<LocalVariableKey>::const_iterator j = vars.begin(); j != vars.end(); ++j ) {\n\t\t\t\tconst std::wstring* varname = TJSGetNameFormID( (*j).VarIndex );\n\t\t\t\tstd::wstring name;\n\t\t\t\tif( varname ) {\n\t\t\t\t\tname = *varname;\n\t\t\t\t} else {\n\t\t\t\t\tname = std::wstring(L\"(unknown)\");\n\t\t\t\t}\n\t\t\t\tstd::wstring value( TJSVariantToReadableString( TJS_GET_VM_REG( ra, (*j).RegAddr ) ).c_str() );\n\n\t\t\t\tvalues.push_back( name );\n\t\t\t\tvalues.push_back( value );\n\t\t\t}\n\t\t}\n\t}\n\t// ϐƒl̃Xg𓾂\n\tvoid GetVars( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset, tTJSVariant* ra, std::list<std::wstring>& values ) {\n\t\tScopeKey scope;\n\t\tTJSDebuggerGetScopeKey( scope, classname, funcname, filename, codeoffset );\n\t\tGetVars( scope, ra, values );\n\t}\n};\nstatic LocalVariableCollection LocalVariableCollectionData;\nstatic ClassVariableCollection ClassVariableCollectionData;\n\n// codeoffset ֐R[ÕR[h̃ItZbg\nvoid TJSDebuggerAddLocalVariable( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset, const tjs_char* varname, int regaddr ) {\n\tLocalVariableCollectionData.SetVar( classname, funcname, filename, codeoffset, varname, regaddr );\n}\nvoid TJSDebuggerGetLocalVariableString( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset, tTJSVariant* ra, std::list<std::wstring>& values ) {\n\tLocalVariableCollectionData.GetVars( classname, funcname, filename, codeoffset, ra, values );\n}\n\nvoid TJSDebuggerAddLocalVariable( const ScopeKey& key, const tjs_char* varname, int regaddr ) {\n\tLocalVariableCollectionData.SetVar( key, varname, regaddr );\n}\nvoid TJSDebuggerGetLocalVariableString( const ScopeKey& key, tTJSVariant* ra, std::list<std::wstring>& values ) {\n\tLocalVariableCollectionData.GetVars( key, ra, values );\n}\nvoid TJSDebuggerClearLocalVariable( const ScopeKey& key ) {\n\tLocalVariableCollectionData.ClearVar( key );\n}\nvoid TJSDebuggerClearLocalVariable( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset ) {\n\tLocalVariableCollectionData.ClearVar( classname, funcname, filename, codeoffset );\n}\n\n// NXoϐ̏\nvoid TJSDebuggerAddClassVariable( const tjs_char* classname, const tjs_char* varname, int regaddr ) {\n\tClassVariableCollectionData.SetVar( classname, varname, regaddr );\n}\nvoid TJSDebuggerGetClassVariableString( const tjs_char* classname, tTJSVariant* ra, tTJSVariant* da, std::list<std::wstring>& values ) {\n\tClassVariableCollectionData.GetVars( classname, ra, da, values );\n}\nvoid TJSDebuggerClearLocalVariable( const tjs_char* classname ) {\n\tClassVariableCollectionData.ClearVar( classname );\n}\n#if 0\nstatic Debugger DebuggerData;\t//!< X^eBbNɂĂ邯ǁAfobKLȂƂɓIɊmۂB\n\n//---------------------------------------------------------------------------\nvoid TJSDebuggerHook( tjs_int evtype, const tjs_char *filename, tjs_int lineno, tTJSInterCodeContext* ctx )\n{\n\tDebuggerData.DebugHook( evtype, filename, lineno, ctx );\n}\n//---------------------------------------------------------------------------\nvoid TJSDebuggerLog( const ttstr &line, bool impotant )\n{\n\tDebuggerData.PrintLog( line.c_str(), impotant );\n}\n#endif\nvoid TJSDebuggerLog(const ttstr &line, bool impotant) {}\nvoid TJSDebuggerHook(tjs_int evtype, const tjs_char *filename, tjs_int lineno, tTJSInterCodeContext* ctx) {}\n#endif\t// ENABLE_DEBUGGER\n\n//---------------------------------------------------------------------------\n\n\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsDebug.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Debugging support\n//---------------------------------------------------------------------------\n#ifndef tjsDebugH\n#define tjsDebugH\n\n#include \"tjsString.h\"\n\n#ifdef ENABLE_DEBUGGER\n#include <list>\n#include <string>\n#endif //ENABLE_DEBUGGER\n\nnamespace TJS\n{\n\n#ifdef ENABLE_DEBUGGER\nstruct ScopeKey {\n\tint ClassIndex;\t//!< NXCfbNX\n\tint FuncIndex;\t//!< ֐CfbNX\n\tint FileIndex;\t//!< t@CCfbNX\n\tint CodeOffset;\t//!< VM R[hItZbg\n\n\tScopeKey()\n\t: ClassIndex(-1), FuncIndex(-1), FileIndex(-1), CodeOffset(-1)\n\t{}\n\tScopeKey( int classidx, int func, int file, int codeoffset )\n\t: ClassIndex(classidx), FuncIndex(func), FileIndex(file), CodeOffset(codeoffset)\n\t{}\n\tvoid Set( int classidx, int func, int file, int codeoffset ) {\n\t\tClassIndex = classidx;\n\t\tFuncIndex = func;\n\t\tFileIndex = file;\n\t\tCodeOffset = codeoffset;\n\t}\n\n\tbool operator ==( const ScopeKey& rhs ) const {\n\t\treturn( ClassIndex == rhs.ClassIndex && FuncIndex == rhs.FuncIndex && FileIndex == rhs.FileIndex && CodeOffset == rhs.CodeOffset );\n\t}\n\tbool operator !=( const ScopeKey& rhs ) const {\n\t\treturn( ClassIndex != rhs.ClassIndex || FuncIndex != rhs.FuncIndex || FileIndex != rhs.FileIndex || CodeOffset != rhs.CodeOffset );\n\t}\n\tbool operator < ( const ScopeKey& rhs ) const {\n\t\t// NXA֐\n\t\tif( ClassIndex == rhs.ClassIndex ) {\n\t\t\tif( FuncIndex == rhs.FuncIndex ) {\n\t\t\t\tif( FileIndex == rhs.FileIndex ) {\n\t\t\t\t\treturn CodeOffset < rhs.CodeOffset;\n\t\t\t\t} else {\n\t\t\t\t\treturn FileIndex < rhs.FileIndex;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn FuncIndex < rhs.FuncIndex;\n\t\t\t}\n\t\t} else {\n\t\t\treturn ClassIndex < rhs.ClassIndex;\n\t\t}\n\t}\n};\n#endif // ENABLE_DEBUGGER\n\n//---------------------------------------------------------------------------\n// ObjectHashMap : hash map to track object construction/destruction\n//---------------------------------------------------------------------------\n// object hash map flags\n#define TJS_OHMF_EXIST        1  // The object is in object hash map\n#define TJS_OHMF_INVALIDATED  2  // The object had been invalidated  // currently not used\n#define TJS_OHMF_DELETING     4  // The object is now being deleted\n#define TJS_OHMF_SET          (~0)\n#define TJS_OHMF_UNSET        (0)\n//---------------------------------------------------------------------------\nclass tTJSScriptBlock;\nstruct tTJSObjectHashMapRecord;\n\nclass tTJSObjectHashMap;\nextern tTJSObjectHashMap * TJSObjectHashMap;\nextern tTJSBinaryStream * TJSObjectHashMapLog;\nextern void TJSAddRefObjectHashMap();\nextern void TJSReleaseObjectHashMap();\nextern void TJSAddObjectHashRecord(void * object);\nextern void TJSRemoveObjectHashRecord(void * object);\nextern void TJSObjectHashSetType(void * object, const ttstr &type);\nextern void TJSSetObjectHashFlag(void * object, tjs_uint32 flags_to_change, tjs_uint32 bits);\nextern void TJSReportAllUnfreedObjects(iTJSConsoleOutput * output);\nextern bool TJSObjectHashAnyUnfreed();\nextern void TJSObjectHashMapSetLog(tTJSBinaryStream * stream);\nextern void TJSWriteAllUnfreedObjectsToLog();\nextern void TJSWarnIfObjectIsDeleting(iTJSConsoleOutput * output, void * object);\nextern void TJSReplayObjectHashMapLog();\nstatic inline bool TJSObjectHashMapEnabled() { return TJSObjectHashMap || TJSObjectHashMapLog; }\nextern inline bool TJSObjectTypeInfoEnabled() { return 0!=TJSObjectHashMap; }\nextern inline bool TJSObjectFlagEnabled() { return 0!=TJSObjectHashMap; }\nextern ttstr TJSGetObjectTypeInfo(void * object);\nextern tjs_uint32 TJSGetObjectHashCheckFlag(void * object);\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// StackTracer : stack to trace function call trace\n//---------------------------------------------------------------------------\nclass tTJSStackTracer;\nclass tTJSInterCodeContext;\nextern tTJSStackTracer * TJSStackTracer;\nextern void TJSAddRefStackTracer();\nextern void TJSReleaseStackTracer();\nextern void TJSStackTracerPush(tTJSInterCodeContext *context, bool in_try);\nextern void TJSStackTracerSetCodePointer(const tjs_int32 * codebase, tjs_int32 * const * codeptr);\nextern void TJSStackTracerPop();\nextern ttstr TJSGetStackTraceString(tjs_int limit = 0, const tjs_char *delimiter = NULL);\nstatic inline bool TJSStackTracerEnabled() { return 0!=TJSStackTracer; }\n//---------------------------------------------------------------------------\n\n#ifdef ENABLE_DEBUGGER\nextern void TJSDebuggerHook( tjs_int evtype, const tjs_char *filename, tjs_int lineno, tTJSInterCodeContext* ctx = NULL );\nextern void TJSDebuggerLog( const ttstr &line, bool impotant );\n\nextern void TJSDebuggerGetScopeKey( struct ScopeKey& scope,  const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset );\nextern void TJSDebuggerAddLocalVariable( const struct ScopeKey& key, const tjs_char* varname, int regaddr );\nextern void TJSDebuggerAddLocalVariable( const tjs_char* filename, const tjs_char* classname, const tjs_char* funcname, int codeoffset, const tjs_char* varname, int regaddr );\nextern void TJSDebuggerGetLocalVariableString( const struct ScopeKey& key, tTJSVariant* ra, std::list<std::wstring>& values );\nextern void TJSDebuggerGetLocalVariableString( const tjs_char* filename, const tjs_char* classname, const tjs_char* funcname, int codeoffset, tTJSVariant* ra, std::list<std::wstring>& values );\nextern void TJSDebuggerClearLocalVariable( const ScopeKey& key );\nextern void TJSDebuggerClearLocalVariable( const tjs_char* classname, const tjs_char* funcname, const tjs_char* filename, int codeoffset );\n\nextern void TJSDebuggerAddClassVariable( const tjs_char* classname, const tjs_char* varname, int regaddr );\nextern void TJSDebuggerGetClassVariableString( const tjs_char* classname, tTJSVariant* ra, tTJSVariant* da, std::list<std::wstring>& values );\nextern void TJSDebuggerClearLocalVariable( const tjs_char* classname );\n#endif\t// ENABLE_DEBUGGER\n\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsDictionary.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Dictionary class implementation\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsDictionary.h\"\n#include \"tjsArray.h\"\n#include \"tjsBinarySerializer.h\"\n#include \"tjsDebug.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nstatic tjs_int32 ClassID_Dictionary;\n//---------------------------------------------------------------------------\n// tTJSDictionaryClass : tTJSDictionary class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSDictionaryClass::ClassID = (tjs_uint32)-1;\ntTJSDictionaryClass::tTJSDictionaryClass() :\n\ttTJSNativeClass(TJS_W(\"Dictionary\"))\n{\n\t// TJS class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/Dictionary)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/* var. name */_this,\n\t/* var. type */tTJSDictionaryNI, /* TJS class name */ Dictionary)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_CONSTRUCTOR_DECL(/*TJS class name*/Dictionary)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/load)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\t// TODO: implement Dictionary.load()\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/load)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadStruct)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tbool dicfree = true;\n\ttTJSDictionaryObject* dic = NULL;\n\tif( objthis ) {\n\t\ttTJSDictionaryNI* ni;\n\t\ttjs_error hr = objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJS_NATIVE_CLASSID_NAME, (iTJSNativeInstance**)&ni);\n\t\tif( TJS_SUCCEEDED(hr) ) {\n\t\t\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\t\t\tni->Clear();\n\t\t\tdic = (tTJSDictionaryObject*)objthis;\n\t\t\tdicfree = false;\n\t\t}\n\t}\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode =*param[1];\n\n\ttTJSBinaryStream* stream = TJSCreateBinaryStreamForRead(name, mode);\n\tif( !stream ) return TJS_E_INVALIDPARAM;\n\n\tbool isbin = false;\n\ttry {\n\t\ttjs_uint64 streamlen = stream->GetSize();\n\t\tif( streamlen >= tTJSBinarySerializer::HEADER_LENGTH ) {\n\t\t\ttjs_uint8 header[tTJSBinarySerializer::HEADER_LENGTH];\n\t\t\tstream->Read( header, tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\tif( tTJSBinarySerializer::IsBinary( header ) ) {\n\t\t\t\tif( !dic ) dic = (tTJSDictionaryObject*)TJSCreateDictionaryObject();\n\t\t\t\ttTJSBinarySerializer binload(dic);\n\t\t\t\ttTJSVariant* var = binload.Read( stream );\n\t\t\t\tif( var ) {\n\t\t\t\t\tif( result ) *result = *var;\n\t\t\t\t\tdelete var;\n\t\t\t\t\tisbin = true;\n\t\t\t\t}\n\t\t\t\tif( dicfree ) {\n\t\t\t\t\tif( dic ) dic->Release();\n\t\t\t\t\tdic = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tdelete stream;\n\t\tif( dicfree ) {\n\t\t\tif( dic ) dic->Release();\n\t\t\tdic = NULL;\n\t\t}\n\t\tthrow;\n\t}\n\tdelete stream;\n\tif( isbin ) return TJS_S_OK;\n\treturn TJS_E_INVALIDPARAM;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/loadStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func.name*/save)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\t// TODO: implement Dictionary.save();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func.name*/save)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func.name*/saveStruct)\n{\n\t// Structured output for flie;\n\t// the content can be interpret as an expression to re-construct the object.\n\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr name(*param[0]);\n\tttstr mode;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid) mode = *param[1];\n\n\tif( TJS_strchr(mode.c_str(), TJS_W('b')) != NULL ) {\n\t\ttTJSBinaryStream* stream = TJSCreateBinaryStreamForWrite(name, mode);\n\t\ttry {\n\t\t\tstream->Write( tTJSBinarySerializer::HEADER, tTJSBinarySerializer::HEADER_LENGTH );\n\t\t\tstd::vector<iTJSDispatch2 *> stack;\n\t\t\tstack.push_back(objthis);\n\t\t\tni->SaveStructuredBinary(stack, *stream);\n\t\t} catch(...) {\n\t\t\tdelete stream;\n\t\t\tthrow;\n\t\t}\n\t\tdelete stream;\n\t} else {\n\t\tiTJSTextWriteStream * stream = TJSCreateTextStreamForWrite(name, mode);\n\t\ttry\n\t\t{\n\t\t\tstd::vector<iTJSDispatch2 *> stack;\n\t\t\tstack.push_back(objthis);\n\t\t\tni->SaveStructuredData(stack, *stream, TJS_W(\"\"));\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tstream->Destruct();\n\t\t\tthrow;\n\t\t}\n\t\tstream->Destruct();\n\t}\n\n\tif(result) *result = tTJSVariant(objthis, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func.name*/saveStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func.name*/assign)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tbool clear = true;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tclear = 0!=(tjs_int)*param[1];\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.ObjThis)\n\t\tni->Assign(clo.ObjThis, clear);\n\telse if(clo.Object)\n\t\tni->Assign(clo.Object, clear);\n\telse TJS_eTJSError(TJSNullAccess);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func.name*/assign)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/* func.name */assignStruct)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tstd::vector<iTJSDispatch2 *> stack;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.ObjThis)\n\t\tni->AssignStructure(clo.ObjThis, stack);\n\telse if(clo.Object)\n\t\tni->AssignStructure(clo.Object, stack);\n\telse TJS_eTJSError(TJSNullAccess);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/* func.name */assignStruct)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func.name*/clear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/* var. name */ni, /* var. type */tTJSDictionaryNI);\n\tif(!ni->IsValid()) return TJS_E_INVALIDOBJECT;\n\n\tni->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func.name*/clear)\n//----------------------------------------------------------------------\n\n\tClassID_Dictionary = TJS_NCM_CLASSID;\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSDictionaryClass::~tTJSDictionaryClass()\n{\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSDictionaryClass::CreateNativeInstance()\n{\n\treturn new tTJSDictionaryNI();\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 *tTJSDictionaryClass::CreateBaseTJSObject()\n{\n\treturn new tTJSDictionaryObject();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSDictionaryClass::CreateNew(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// CreateNew\n\tif( numparams < 1 || param[0]->Type() != tvtInteger || (tjs_int)(*param[0]) < 8 ) {\n\t\treturn inherited::CreateNew( flag, membername, hint, result, numparams, param, objthis );\n\t}\n\ttjs_int v = (tjs_int)(*param[0]);\n\ttjs_int r;\n\tif(v & 0xffff0000) r = 16, v >>= 16; else r = 0;\n\tif(v & 0xff00) r += 8, v >>= 8;\n\tif(v & 0xf0) r += 4, v >>= 4;\n\tv<<=1;\n\ttjs_int hashbits = r + ((0xffffaa50 >> v) &0x03) + 2;\n\tiTJSDispatch2 *dsp = new tTJSDictionaryObject(hashbits);\n\n\t// same as tTJSNativeClass\n\ttjs_error hr;\n\ttry \n\t{\n\t\t// set object type for debugging\n\t\tif(TJSObjectHashMapEnabled())\n\t\t\tTJSObjectHashSetType(dsp, TJS_W(\"instance of class \") + ClassName);\n\n\t\t// instance initialization\n\t\thr = FuncCall(0, NULL, NULL, NULL, 0, NULL, dsp); // add member to dsp\n\n\t\tif(TJS_FAILED(hr)) return hr;\n\n\t\thr = FuncCall(0, ClassName.c_str(), ClassName.GetHint(), NULL, numparams, param, dsp);\n\t\t\t// call the constructor\n\t\tif(hr == TJS_E_MEMBERNOTFOUND) hr = TJS_S_OK;\n\t\t\t// missing constructor is OK ( is this ugly ? )\n\t}\n\tcatch(...)\n\t{\n\t\tdsp->Release();\n\t\tthrow;\n\t}\n\n\tif(TJS_SUCCEEDED(hr)) *result = dsp;\n\treturn hr;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSDictionaryNI\n//---------------------------------------------------------------------------\ntTJSDictionaryNI::tTJSDictionaryNI()\n{\n\tOwner = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSDictionaryNI::~tTJSDictionaryNI()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSDictionaryNI::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjsobj)\n{\n\t// called from TJS constructor\n\t//if(numparams != 0) return TJS_E_BADPARAMCOUNT;\n\tif(numparams > 1) return TJS_E_BADPARAMCOUNT;\n\tOwner = static_cast<tTJSCustomObject*>(tjsobj);\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSDictionaryNI::Invalidate() // Invalidate override\n{\n\t// put here something on invalidation\n\tOwner = NULL;\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSDictionaryNI::Assign(iTJSDispatch2 * dsp, bool clear)\n{\n\t// copy members from \"dsp\" to \"Owner\"\n\n\t// determin dsp's object type\n\ttTJSArrayNI *arrayni = NULL;\n\tif(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tTJSGetArrayClassID(), (iTJSNativeInstance**)&arrayni)) )\n\t{\n\t\t// convert from array\n\t\tif(clear) Owner->Clear();\n\n\t\t// reserve area\n\t\ttjs_int reqcount = (tjs_int)(Owner->Count + arrayni->Items.size());\n\t\tOwner->RebuildHash( reqcount );\n\n\t\ttTJSArrayNI::tArrayItemIterator i;\n\t\tfor(i = arrayni->Items.begin(); i != arrayni->Items.end(); i++)\n\t\t{\n\t\t\ttTJSVariantString *name = i->AsStringNoAddRef();\n\t\t\ti++;\n\t\t\tif(arrayni->Items.end() == i) break;\n\t\t\tOwner->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP, name,\n\t\t\t\t&(*i),\n\t\t\t\tOwner);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// otherwise\n\t\tif(clear) Owner->Clear();\n\t\t\n\t\ttSaveMemberCountCallback countCallback;\n\t\ttTJSVariantClosure clo1(&countCallback, NULL);\n\t\tdsp->EnumMembers(TJS_IGNOREPROP, &clo1, dsp);\n\t\ttjs_int reqcount = countCallback.Count + Owner->Count;\n\t\tOwner->RebuildHash( reqcount );\n\n\t\ttAssignCallback callback;\n\t\tcallback.Owner = Owner;\n\n\t\ttTJSVariantClosure clo2(&callback, NULL);\n\t\tdsp->EnumMembers(TJS_IGNOREPROP, &clo2, dsp);\n\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSDictionaryNI::Clear()\n{\n\tOwner->Clear();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSDictionaryNI::tAssignCallback::FuncCall(tjs_uint32 flag,\n\tconst tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result,\n\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\t// called from iTJSDispatch2::EnumMembers\n\t// (tTJSDictionaryNI::Assign calls iTJSDispatch2::EnumMembers)\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t// hidden members are not copied\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER)\n\t{\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\n\tOwner->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP|flags,\n\t\tparam[0]->AsStringNoAddRef(), param[2], Owner);\n\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDictionaryNI::SaveStructuredData(std::vector<iTJSDispatch2 *> &stack,\n\tiTJSTextWriteStream & stream, const ttstr &indentstr)\n{\n#ifdef TJS_TEXT_OUT_CRLF\n\tstream.Write(TJS_W(\"(const) %[\\r\\n\"));\n#else\n\tstream.Write(TJS_W(\"(const) %[\\n\"));\n#endif\n\tttstr indentstr2 = indentstr + TJS_W(\" \");\n\n\ttSaveStructCallback callback;\n\tcallback.Stack = &stack;\n\tcallback.Stream = &stream;\n\tcallback.IndentStr = &indentstr2;\n\tcallback.First = true;\n    tTJSVariantClosure clo(&callback, NULL);\n\tOwner->EnumMembers(TJS_IGNOREPROP, &clo, Owner);\n\n#ifdef TJS_TEXT_OUT_CRLF\n\tif(!callback.First) stream.Write(TJS_W(\"\\r\\n\"));\n#else\n\tif(!callback.First) stream.Write(TJS_W(\"\\n\"));\n#endif\n\tstream.Write(indentstr);\n\tstream.Write(TJS_W(\"]\"));\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSDictionaryNI::tSaveStructCallback::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// called indirectly from tTJSDictionaryNI::SaveStructuredData\n\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t// hidden members are not processed\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER)\n\t{\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\n#ifdef TJS_TEXT_OUT_CRLF\n\tif(!First) Stream->Write(TJS_W(\",\\r\\n\"));\n#else\n\tif(!First) Stream->Write(TJS_W(\",\\n\"));\n#endif\n\n\tFirst = false;\n\n\tStream->Write(*IndentStr);\n\n\tStream->Write(TJS_W(\"\\\"\"));\n\tStream->Write(ttstr(*param[0]).EscapeC());\n\tStream->Write(TJS_W(\"\\\" => \"));\n\n\ttTJSVariantType type = param[2]->Type();\n\tif(type == tvtObject)\n\t{\n\t\t// object\n\t\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\t\ttTJSArrayNI::SaveStructuredDataForObject(clo.SelectObjectNoAddRef(),\n\t\t\t*Stack, *Stream, *IndentStr);\n\t}\n\telse\n\t{\n\t\tStream->Write(TJSVariantToExpressionString(*param[2]));\n\t}\n\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDictionaryNI::SaveStructuredBinary(std::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream )\n{\n\ttSaveMemberCountCallback countCallback;\n    tTJSVariantClosure cclo(&countCallback, NULL);\n\tOwner->EnumMembers(TJS_IGNOREPROP, &cclo, Owner);\n\n\ttjs_int count = countCallback.Count;\n\ttTJSBinarySerializer::PutStartMap( &stream, count );\n\n\ttSaveStructBinayCallback callback;\n\tcallback.Stack = &stack;\n\tcallback.Stream = &stream;\n    tTJSVariantClosure clo(&callback, NULL);\n\tOwner->EnumMembers(TJS_IGNOREPROP, &clo, Owner);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSDictionaryNI::tSaveStructBinayCallback::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// called indirectly from tTJSDictionaryNI::SaveStructuredBinary\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t// hidden members are not processed\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER) {\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\n\ttTJSBinarySerializer::PutString( Stream, param[0]->AsStringNoAddRef() );\n\n\ttTJSVariantType type = param[2]->Type();\n\tif( type == tvtObject ) {\n\t\t// object\n\t\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\t\ttTJSArrayNI::SaveStructuredBinaryForObject( clo.SelectObjectNoAddRef(), *Stack, *Stream );\n\t} else {\n\t\ttTJSBinarySerializer::PutVariant( Stream, *param[2] );\n\t}\n\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSDictionaryNI::tSaveMemberCountCallback::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// called indirectly from tTJSDictionaryNI::SaveStructuredBinary\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t// hidden members are not processed\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER) {\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\tCount++;\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTJSDictionaryNI::AssignStructure(iTJSDispatch2 * dsp,\n\tstd::vector<iTJSDispatch2 *> &stack)\n{\n\t// assign structured data from dsp\n\ttTJSArrayNI *dicni = NULL;\n\tif(TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\tClassID_Dictionary, (iTJSNativeInstance**)&dicni)) )\n\t{\n\t\t// copy from dictionary\n\t\tstack.push_back(dsp);\n\t\ttry\n\t\t{\n\t\t\tOwner->Clear();\n\t\t\t\n\t\t\t// reserve area\n\t\t\ttSaveMemberCountCallback countCallback;\n            tTJSVariantClosure cclo(&countCallback, NULL);\n\t\t\tdsp->EnumMembers(TJS_IGNOREPROP, &cclo, dsp);\n\t\t\ttjs_int reqcount = countCallback.Count + Owner->Count;\n\t\t\tOwner->RebuildHash( reqcount );\n\n\t\t\ttAssignStructCallback callback;\n\t\t\tcallback.Dest = Owner;\n\t\t\tcallback.Stack = &stack;\n            tTJSVariantClosure clo(&callback, NULL);\n\t\t\tdsp->EnumMembers(TJS_IGNOREPROP, &clo, dsp);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tstack.pop_back();\n\t\t\tthrow;\n\t\t}\n\t\tstack.pop_back();\n\t}\n\telse\n\t{\n\t\tTJS_eTJSError(TJSSpecifyDicOrArray);\n\t}\n\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSDictionaryNI::tAssignStructCallback::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// called indirectly from tTJSDictionaryNI::AssignStructure or\n\t// tTJSArrayNI::AssignStructure\n\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t// hidden members are not processed\n\ttjs_uint32 flags = (tjs_int)*param[1];\n\tif(flags & TJS_HIDDENMEMBER)\n\t{\n\t\tif(result) *result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\n\ttTJSVariant &value = *param[2];\n\n\ttTJSVariantType type = value.Type();\n\tif(type == tvtObject)\n\t{\n\t\t// object\n\n\t\tiTJSDispatch2 *dsp = value.AsObjectNoAddRef();\n\t\t// determin dsp's object type\n\n\t\ttTJSVariant val;\n\n\t\ttTJSDictionaryNI *dicni = NULL;\n\t\ttTJSArrayNI *arrayni = NULL;\n\n\t\tif(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&dicni)) )\n\t\t{\n\t\t\t// dictionary\n\t\t\tbool objrec = false;\n\t\t\tstd::vector<iTJSDispatch2 *>::iterator i;\n\t\t\tfor(i = Stack->begin(); i != Stack->end(); i++)\n\t\t\t{\n\t\t\t\tif(*i == dsp)\n\t\t\t\t{\n\t\t\t\t\t// object recursion detected\n\t\t\t\t\tobjrec = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(objrec)\n\t\t\t{\n\t\t\t\tval.SetObject(NULL); // becomes null\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tiTJSDispatch2 * newobj = TJSCreateDictionaryObject();\n\t\t\t\tval.SetObject(newobj, newobj);\n\t\t\t\tnewobj->Release();\n\t\t\t\ttTJSDictionaryNI * newni = NULL;\n\t\t\t\tif(TJS_SUCCEEDED(newobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\tTJSGetDictionaryClassID(), (iTJSNativeInstance**)&newni)) )\n\t\t\t\t{\n\t\t\t\t\tnewni->AssignStructure(dsp, *Stack);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(dsp && TJS_SUCCEEDED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\tTJSGetArrayClassID(), (iTJSNativeInstance**)&arrayni)) )\n\t\t{\n\t\t\t// array\n\t\t\tbool objrec = false;\n\t\t\tstd::vector<iTJSDispatch2 *>::iterator i;\n\t\t\tfor(i = Stack->begin(); i != Stack->end(); i++)\n\t\t\t{\n\t\t\t\tif(*i == dsp)\n\t\t\t\t{\n\t\t\t\t\t// object recursion detected\n\t\t\t\t\tobjrec = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(objrec)\n\t\t\t{\n\t\t\t\tval.SetObject(NULL); // becomes null\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tiTJSDispatch2 * newobj = TJSCreateArrayObject();\n\t\t\t\tval.SetObject(newobj, newobj);\n\t\t\t\tnewobj->Release();\n\t\t\t\ttTJSArrayNI * newni = NULL;\n\t\t\t\tif(TJS_SUCCEEDED(newobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\tTJSGetArrayClassID(), (iTJSNativeInstance**)&newni)) )\n\t\t\t\t{\n\t\t\t\t\tnewni->AssignStructure(dsp, *Stack);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// other object types\n\t\t\tval = value;\n\t\t}\n\n\t\tDest->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP, param[0]->AsStringNoAddRef(), &val, Dest);\n\t}\n\telse\n\t{\n\t\t// other types\n\t\tDest->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP, param[0]->AsStringNoAddRef(), &value, Dest);\n\t}\n\n\tif(result) *result = (tjs_int)1;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSDictionaryObject\n//---------------------------------------------------------------------------\ntTJSDictionaryObject::tTJSDictionaryObject() : tTJSCustomObject()\n{\n\tCallFinalize = false;\n}\n//---------------------------------------------------------------------------\ntTJSDictionaryObject::tTJSDictionaryObject(tjs_int hashbits) : tTJSCustomObject(hashbits)\n{\n\tCallFinalize = false;\n}\n//---------------------------------------------------------------------------\ntTJSDictionaryObject::~tTJSDictionaryObject()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDictionaryObject::FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::FuncCall(flag, membername, hint, result, numparams,\n\t\tparam, objthis);\n//\tif(hr == TJS_E_MEMBERNOTFOUND)\n//\t\treturn TJS_E_INVALIDTYPE; // call operation for void\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDictionaryObject::PropGet(tjs_uint32 flag, const tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr;\n\thr = inherited::PropGet(flag, membername, hint, result, objthis);\n\tif(hr == TJS_E_MEMBERNOTFOUND && !(flag & TJS_MEMBERMUSTEXIST))\n\t{\n\t\tif(result) result->Clear(); // returns void\n\t\treturn TJS_S_OK;\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDictionaryObject::CreateNew(tjs_uint32 flag, const tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::CreateNew(flag, membername, hint, result, numparams,\n\t\tparam, objthis);\n\tif(hr == TJS_E_MEMBERNOTFOUND && !(flag & TJS_MEMBERMUSTEXIST))\n\t\treturn TJS_E_INVALIDTYPE; // call operation for void\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD \n\ttTJSDictionaryObject::Operation(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::Operation(flag, membername, hint, result, param, objthis);\n\tif(hr == TJS_E_MEMBERNOTFOUND && !(flag & TJS_MEMBERMUSTEXIST))\n\t{\n\t\t// value not found -> create a value, do the operation once more\n\t\tstatic tTJSVariant VoidVal;\n\t\thr = inherited::PropSet(TJS_MEMBERENSURE, membername, hint, &VoidVal, objthis);\n\t\tif(TJS_FAILED(hr)) return hr;\n\t\thr = inherited::Operation(flag, membername, hint, result, param, objthis);\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSGetDictionaryClassID\n//---------------------------------------------------------------------------\ntjs_int32 TJSGetDictionaryClassID()\n{\n\treturn ClassID_Dictionary;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSCreateDictionaryObject\n//---------------------------------------------------------------------------\niTJSDispatch2 * TJSCreateDictionaryObject(iTJSDispatch2 **classout)\n{\n\t// create a Dictionary object\n\tstruct tHolder\n\t{\n\t\tiTJSDispatch2 * Obj;\n\t\ttHolder() { Obj = new tTJSDictionaryClass(); }\n\t\t~tHolder() { Obj->Release(); }\n\t} static dictionaryclass;\n\n\tif(classout) *classout = dictionaryclass.Obj, dictionaryclass.Obj->AddRef();\n\n\ttTJSDictionaryObject *dictionaryobj;\n\t(dictionaryclass.Obj)->CreateNew(0, NULL,  NULL,\n\t\t(iTJSDispatch2**)&dictionaryobj, 0, NULL, dictionaryclass.Obj);\n\treturn dictionaryobj;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsDictionary.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Dictionary class implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsDictionaryH\n#define tjsDictionaryH\n\n#include \"tjsObject.h\"\n#include \"tjsNative.h\"\n#include \"tjsArray.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSDictionaryClass : Dictoinary Class\n//---------------------------------------------------------------------------\nclass tTJSDictionaryClass : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSDictionaryClass();\n\t~tTJSDictionaryClass();\n\npublic:\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t iTJSDispatch2 **result,\n\t\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\tiTJSDispatch2 *CreateBaseTJSObject();\n\n\tstatic tjs_uint32 ClassID;\nprivate:\n\nprotected:\n};\n//---------------------------------------------------------------------------\n// tTJSDictionaryNI : TJS Dictionary Native C++ instance\n//---------------------------------------------------------------------------\nclass tTJSDictionaryNI : public tTJSNativeInstance,\n\t\t\t\t\t\t\tpublic tTJSSaveStructuredDataCallback\n{\n\ttypedef tTJSNativeInstance inherited;\n\n\ttTJSCustomObject * Owner;\npublic:\n\n\ttTJSDictionaryNI();\n\t~tTJSDictionaryNI();\n\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *obj);\n\nprivate:\n\tvoid TJS_INTF_METHOD Invalidate(); // Invalidate override\n\npublic:\n\tbool IsValid() const { return Owner != NULL; } // check validation\n\n\tvoid Assign(iTJSDispatch2 *dsp, bool clear = true);\n\n\tvoid Clear();\n\nprivate:\n\tstruct tAssignCallback : public tTJSDispatch\n\t{\n\t\ttTJSCustomObject * Owner;\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t\t\t// method from iTJSDispatch2, for enumeration callback\n\t};\n\tfriend class tSaveStructCallback;\n\npublic:\n\tvoid SaveStructuredData(std::vector<iTJSDispatch2 *> &stack,\n                                iTJSTextWriteStream & stream, const ttstr&indentstr);\n\tvoid SaveStructuredBinary(std::vector<iTJSDispatch2 *> &stack, tTJSBinaryStream &stream );\n\t\t// method from tTJSSaveStructuredDataCallback\nprivate:\n\tstruct tSaveStructCallback : public tTJSDispatch\n\t{\n\t\tstd::vector<iTJSDispatch2 *> * Stack;\n\t\tiTJSTextWriteStream *Stream;\n\t\tconst ttstr * IndentStr;\n\t\tbool First;\n\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t};\n\tfriend struct tSaveStructCallback;\n\n\tstruct tSaveStructBinayCallback : public tTJSDispatch {\n\t\tstd::vector<iTJSDispatch2 *> * Stack;\n\t\ttTJSBinaryStream *Stream;\n\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t};\n\tfriend struct tSaveStructBinayCallback;\n\n\tstruct tSaveMemberCountCallback : public tTJSDispatch {\n\t\ttjs_uint Count;\n\t\ttSaveMemberCountCallback() : Count(0) {}\n\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t};\n\tfriend struct tSaveMemberCountCallback;\n\npublic:\n\tvoid AssignStructure(iTJSDispatch2 * dsp, std::vector<iTJSDispatch2 *> &stack);\n\n\tstruct tAssignStructCallback : public tTJSDispatch\n\t{\n\t\tstd::vector<iTJSDispatch2 *> * Stack;\n\t\tiTJSDispatch2 * Dest;\n\n\t\ttjs_error TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\t};\n\tfriend struct tAssignStructCallback;\n};\n//---------------------------------------------------------------------------\nclass tTJSDictionaryObject : public tTJSCustomObject\n{\n\ttypedef tTJSCustomObject inherited;\n\npublic:\n\ttTJSDictionaryObject();\n\ttTJSDictionaryObject(tjs_int hashbits);\n\t~tTJSDictionaryObject();\n\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis);\n\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSGetDictionaryClassID\n//---------------------------------------------------------------------------\nextern tjs_int32 TJSGetDictionaryClassID();\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSCreateDictionaryObject\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TJSCreateDictionaryObject, (\n\tiTJSDispatch2 **classout = NULL));\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsDisassemble.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// VM code disassembler\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsInterCodeGen.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsUtils.h\"\n\n//---------------------------------------------------------------------------\nnamespace TJS  // following is in the namespace\n{\n//---------------------------------------------------------------------------\ntTJSString tTJSInterCodeContext::GetValueComment(const tTJSVariant &val)\n{\n\t// make val a human readable string and return it\n\treturn TJSVariantToReadableString(val);\n}\n//---------------------------------------------------------------------------\nstatic tjs_uint32 dummy = (tjs_uint32)-1; // for data alignment\nvoid tTJSInterCodeContext::Disassemble(\n\tvoid (*output_func)(const tjs_char *msg, const tjs_char *comment, tjs_int addr,\n\tconst tjs_int32 *codestart, tjs_int size, void *data),\n\tvoid (*output_func_src)(const tjs_char *msg, const tjs_char *name, tjs_int line,\n\tvoid *data), void *data, tjs_int start, tjs_int end)\n{\n\t// dis-assemble the intermediate code.\n\t// \"output_func\" points a line output function.\n\n//\ttTJSVariantString * s;\n\n\ttTJSString msg;\n\ttTJSString com;\n\n\ttjs_int prevline = -1;\n\ttjs_int curline = -1;\n\n\tif(end <= 0) end = CodeAreaSize;\n\tif(end > CodeAreaSize) end = CodeAreaSize;\n\n\tfor(tjs_int i = start; i < end; )\n\t{\n\t\tmsg.Clear();\n\t\tcom.Clear();\n\t\ttjs_int size;\n\t\ttjs_int srcpos = CodePosToSrcPos(i);\n\t\ttjs_int line = Block->SrcPosToLine(srcpos);\n\n\t\t// output source lines as comment\n\t\tif(curline == -1 || curline <= line)\n\t\t{\n\t\t\tif(curline == -1) curline = line;\n\t\t\ttjs_int nl = line - curline;\n\t\t\twhile(curline <= line)\n\t\t\t{\n\t\t\t\tif(nl<3 || (nl >= 3 && line-curline <= 2))\n\t\t\t\t{\n\t\t\t\t\ttjs_int len;\n\t\t\t\t\tconst tjs_char *src = Block->GetLine(curline, &len);\n\t\t\t\t\ttjs_char * buf = new tjs_char[len + 1];\n\t\t\t\t\tTJS_strcpy_maxlen(buf, src, len);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\toutput_func_src(buf, TJS_W(\"\"), curline, data);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelete [] buf;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tdelete [] buf;\n\t\t\t\t\tcurline++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcurline = line - 2;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(prevline != line)\n\t\t{\n\t\t\ttjs_int len;\n\t\t\tconst tjs_char *src = Block->GetLine(line, &len);\n\t\t\ttjs_char * buf = new tjs_char[len + 1];\n\t\t\tTJS_strcpy_maxlen(buf, src, len);\n\t\t\ttry\n\t\t\t{\n\t\t\t\toutput_func_src((const tjs_char*)buf, TJS_W(\"\"), line, data);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tdelete [] buf;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete [] buf;\n\t\t}\n\n\t\tprevline = line;\n\n\t\t// decode each instructions\n\t\tswitch(CodeArea[i])\n\t\t{\n\t\tcase VM_NOP:\n\t\t\tmsg.printf(TJS_W(\"nop\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tcase VM_NF:\n\t\t\tmsg.printf(TJS_W(\"nf\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tcase VM_CONST:\n\t\t\tmsg.printf(TJS_W(\"const %%%d, *%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tif(DataArea)\n\t\t\t{\n\t\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+2])).c_str());\n\t\t\t}\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\n#define OP2_DISASM(c, x) \\\n\tcase c: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\" %%%d, %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\t\t\t\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2])); \\\n\t\tsize = 3; \\\n\t\tbreak\n\t\t// instructions that\n\t\t// 1. have two operands that represent registers.\n\t\t// 2. do not have property access variants.\n\t\tOP2_DISASM(VM_CP,\t\t\"cp\");\n\t\tOP2_DISASM(VM_CEQ,\t\t\"ceq\");\n\t\tOP2_DISASM(VM_CDEQ,\t\t\"cdeq\");\n\t\tOP2_DISASM(VM_CLT,\t\t\"clt\");\n\t\tOP2_DISASM(VM_CGT,\t\t\"cgt\");\n\t\tOP2_DISASM(VM_CHKINS,\t\"chkins\");\n#undef OP2_DISASM\n\n\n#define OP2_DISASM(c, x) \\\n\tcase c: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\" %%%d, %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\t\t\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2])); \\\n\t\tsize = 3; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"pd\") TJS_W(\" %%%d, %%%d.*%d, %%%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+4])); \\\n\t\tif(DataArea) \\\n\t\t{ \\\n\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+3]), \\\n\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+3])).c_str()); \\\n\t\t} \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"pi\") TJS_W(\" %%%d, %%%d.%%%d, %%%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+4])); \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"p\") TJS_W(\" %%%d, %%%d, %%%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3])); \\\n\t\tsize = 4; \\\n\t\tbreak\n\t\t// instructions that\n\t\t// 1. have two operands that represent registers.\n\t\t// 2. have property access variants\n\t\tOP2_DISASM(VM_LOR,\t\t\"lor\");\n\t\tOP2_DISASM(VM_LAND,\t\t\"land\");\n\t\tOP2_DISASM(VM_BOR,\t\t\"bor\");\n\t\tOP2_DISASM(VM_BXOR,\t\t\"bxor\");\n\t\tOP2_DISASM(VM_BAND,\t\t\"band\");\n\t\tOP2_DISASM(VM_SAR,\t\t\"sar\");\n\t\tOP2_DISASM(VM_SAL,\t\t\"sal\");\n\t\tOP2_DISASM(VM_SR,\t\t\"sr\");\n\t\tOP2_DISASM(VM_ADD,\t\t\"add\");\n\t\tOP2_DISASM(VM_SUB,\t\t\"sub\");\n\t\tOP2_DISASM(VM_MOD,\t\t\"mod\");\n\t\tOP2_DISASM(VM_DIV,\t\t\"div\");\n\t\tOP2_DISASM(VM_IDIV,\t\t\"idiv\");\n\t\tOP2_DISASM(VM_MUL,\t\t\"mul\");\n#undef OP2_DISASM\n\n#define OP1_DISASM(x) \\\n\tmsg.printf(TJS_W(x) TJS_W(\" %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1])); \\\n\tsize = 2\n\t\t// instructions that have one operand which represent a register,\n\t\t// except for inc, dec\n\t\tcase VM_TT:\t\t\tOP1_DISASM(\"tt\");\t\tbreak;\n\t\tcase VM_TF:\t\t\tOP1_DISASM(\"tf\");\t\tbreak;\n\t\tcase VM_SETF:\t\tOP1_DISASM(\"setf\");\t\tbreak;\n\t\tcase VM_SETNF:\t\tOP1_DISASM(\"setnf\");\tbreak;\n\t\tcase VM_LNOT:\t\tOP1_DISASM(\"lnot\");\t\tbreak;\n\t\tcase VM_BNOT:\t\tOP1_DISASM(\"bnot\");\t\tbreak;\n\t\tcase VM_ASC:\t\tOP1_DISASM(\"asc\");\t\tbreak;\n\t\tcase VM_CHR:\t\tOP1_DISASM(\"chr\");\t\tbreak;\n\t\tcase VM_NUM:\t\tOP1_DISASM(\"num\");\t\tbreak;\n\t\tcase VM_CHS:\t\tOP1_DISASM(\"chs\");\t\tbreak;\n\t\tcase VM_CL:\t\t\tOP1_DISASM(\"cl\");\t\tbreak;\n\t\tcase VM_INV:\t\tOP1_DISASM(\"inv\");\t\tbreak;\n\t\tcase VM_CHKINV:\t\tOP1_DISASM(\"chkinv\");\tbreak;\n\t\tcase VM_TYPEOF:\t\tOP1_DISASM(\"typeof\");\tbreak;\n\t\tcase VM_EVAL:\t\tOP1_DISASM(\"eval\");\t\tbreak;\n\t\tcase VM_EEXP:\t\tOP1_DISASM(\"eexp\");\t\tbreak;\n\t\tcase VM_INT:\t\tOP1_DISASM(\"int\");\t\tbreak;\n\t\tcase VM_REAL:\t\tOP1_DISASM(\"real\");\t\tbreak;\n\t\tcase VM_STR:\t\tOP1_DISASM(\"str\");\t\tbreak;\n\t\tcase VM_OCTET:\t\tOP1_DISASM(\"octet\");\tbreak;\n#undef OP1_DISASM\n\n\t\tcase VM_CCL:\n\t\t\tmsg.printf(TJS_W(\"ccl %%%d-%%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]) + CodeArea[i+2] -1);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n#define OP1_DISASM(c, x) \\\n\tcase c: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\" %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1])); \\\n\t\tsize = 2; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"pd\") TJS_W(\" %%%d, %%%d.*%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3])); \\\n\t\tif(DataArea) \\\n\t\t{ \\\n\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), \\\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]), \\\n\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+3])).c_str()); \\\n\t\t} \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"pi\") TJS_W(\" %%%d, %%%d.%%%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3])); \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tmsg.printf(TJS_W(x) TJS_W(\"p\") TJS_W(\" %%%d, %%%d\"), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]), \\\n\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2])); \\\n\t\tsize = 3; \\\n\t\tbreak\n\n\t\t// inc and dec\n\t\tOP1_DISASM(VM_INC,\t\"inc\");\n\t\tOP1_DISASM(VM_DEC,\t\"dec\");\n#undef OP1_DISASM\n\n\n\n#define OP1A_DISASM(x) \\\n\tmsg.printf(TJS_W(x) TJS_W(\" %09d\"), TJS_FROM_VM_CODE_ADDR(CodeArea[i+1]) + i); \\\n\tsize = 2\n\t\t// instructions that have one operand which represents code area\n\t\tcase VM_JF:\t\tOP1A_DISASM(\"jf\");\t\tbreak;\n\t\tcase VM_JNF:\tOP1A_DISASM(\"jnf\");\t\tbreak;\n\t\tcase VM_JMP:\tOP1A_DISASM(\"jmp\");\t\tbreak;\n#undef OP1A_DISASM\n\n\t\tcase VM_CALL:\n\t\tcase VM_CALLD:\n\t\tcase VM_CALLI:\n\t\tcase VM_NEW:\n\t\t  {\n\t\t\t// function call variants\n\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_CALL  ?TJS_W(\"call %%%d, %%%d(\"):\n\t\t\t\tCodeArea[i] == VM_CALLD ?TJS_W(\"calld %%%d, %%%d.*%d(\"):\n\t\t\t\tCodeArea[i] == VM_CALLI ?TJS_W(\"calli %%%d, %%%d.%%%d(\"):\n\t\t\t\t\t\t\t\t\t\t TJS_W(\"new %%%d, %%%d(\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\ttjs_int st; // start of arguments\n\t\t\tif(CodeArea[i] == VM_CALLD || CodeArea[i] == VM_CALLI)\n\t\t\t\tst = 5;\n\t\t\telse\n\t\t\t\tst = 4;\n\t\t\ttjs_int num = CodeArea[i+st-1];     // st-1 = argument count\n\t\t\tbool first = true;\n\t\t\ttjs_char buf[256];\n\t\t\ttjs_int c = 0;\n\t\t\tif(num == -1)\n\t\t\t{\n\t\t\t\t// omit arg\n\t\t\t\tsize = st;\n\t\t\t\tmsg += TJS_W(\"...\");\n\t\t\t}\n\t\t\telse if(num == -2)\n\t\t\t{\n\t\t\t\t// expand arg\n\t\t\t\tst ++;\n\t\t\t\tnum = CodeArea[i+st-1];\n\t\t\t\tsize = st + num * 2;\n\t\t\t\tfor(tjs_int j = 0; j < num; j++)\n\t\t\t\t{\n\t\t\t\t\tif(!first) msg += TJS_W(\", \");\n\t\t\t\t\tfirst = false;\n\t\t\t\t\tswitch(CodeArea[i+st+j*2])\n\t\t\t\t\t{\n\t\t\t\t\tcase fatNormal:\n\t\t\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"%%%d\"),\n\t\t\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+st+j*2+1]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatExpand:\n\t\t\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"%%%d*\"),\n\t\t\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+st+j*2+1]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatUnnamedExpand:\n\t\t\t\t\t\tTJS_strcpy(buf, TJS_W(\"*\"));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmsg += buf;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// normal operation\n\t\t\t\tsize = st + num;\n\t\t\t\twhile(num--)\n\t\t\t\t{\n\t\t\t\t\tif(!first) msg += TJS_W(\", \");\n\t\t\t\t\tfirst = false;\n\t\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"%%%d\"),\n\t\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+c+st]));\n\t\t\t\t\tc++;\n\t\t\t\t\tmsg += buf;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmsg += TJS_W(\")\");\n\t\t\tif(DataArea && CodeArea[i] == VM_CALLD)\n\t\t\t{\n\t\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+3]),\n\t\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+3])).c_str());\n\t\t\t}\n\n\t\t\tbreak;\n\t\t  }\n\n\t\tcase VM_GPD:\n\t\tcase VM_GPDS:\n\t\t\t// property get direct\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_GPD?TJS_W(\"gpd %%%d, %%%d.*%d\"):\n\t\t\t\t\t\t\t\t\t  TJS_W(\"gpds %%%d, %%%d.*%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tif(DataArea)\n\t\t\t{\n\t\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+3]),\n\t\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+3])).c_str());\n\t\t\t}\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\n\t\tcase VM_SPD:\n\t\tcase VM_SPDE:\n\t\tcase VM_SPDEH:\n\t\tcase VM_SPDS:\n\t\t\t// property set direct\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_SPD ? TJS_W(\"spd %%%d.*%d, %%%d\"):\n\t\t\t\tCodeArea[i] == VM_SPDE? TJS_W(\"spde %%%d.*%d, %%%d\"):\n\t\t\t\tCodeArea[i] == VM_SPDEH?TJS_W(\"spdeh %%%d.*%d, %%%d\"):\n\t\t\t\t\t\t\t\t\t\tTJS_W(\"spds %%%d.*%d, %%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tif(DataArea)\n\t\t\t{\n\t\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+2])).c_str());\n\t\t\t}\n\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\n\t\tcase VM_GPI:\n\t\tcase VM_GPIS:\n\t\t\t// property get indirect\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_GPI ?  TJS_W(\"gpi %%%d, %%%d.%%%d\"):\n\t\t\t\t\t\t\t\t\t\t TJS_W(\"gpis %%%d, %%%d.%%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\n\t\tcase VM_SPI:\n\t\tcase VM_SPIE:\n\t\tcase VM_SPIS:\n\t\t\t// property set indirect\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_SPI  ?TJS_W(\"spi %%%d.%%%d, %%%d\"):\n\t\t\t\tCodeArea[i] == VM_SPIE ?TJS_W(\"spie %%%d.%%%d, %%%d\"):\n\t\t\t\t\t\t\t\t\t\tTJS_W(\"spis %%%d.%%%d, %%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\n\t\tcase VM_SETP:\n\t\t\t// property set\n\t\t\tmsg.printf(\n\t\t\t\tTJS_W(\"setp %%%d, %%%d\"),\n\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GETP:\n\t\t\t// property get\n\t\t\tmsg.printf(\n\t\t\t\tTJS_W(\"getp %%%d, %%%d\"),\n\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\n\t\tcase VM_DELD:\n\t\tcase VM_TYPEOFD:\n\t\t\t// member delete direct / typeof direct\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_DELD   ?TJS_W(\"deld %%%d, %%%d.*%d\"):\n\t\t\t\t\t\t\t\t\t\t  TJS_W(\"typeofd %%%d, %%%d.*%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tif(DataArea)\n\t\t\t{\n\t\t\t\tcom.printf(TJS_W(\"*%d = %ls\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+3]),\n\t\t\t\t\tGetValueComment(TJS_GET_VM_REG(DataArea, CodeArea[i+3])).c_str());\n\t\t\t}\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_DELI:\n\t\tcase VM_TYPEOFI:\n\t\t\t// member delete indirect / typeof indirect\n\t\t\tmsg.printf(\n\t\t\t\tCodeArea[i] == VM_DELI   ?TJS_W(\"deli %%%d, %%%d.%%%d\"):\n\t\t\t\t\t\t\t\t\t\t  TJS_W(\"typeofi %%%d, %%%d.%%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+3]));\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SRV:\n\t\t\t// set return value\n\t\t\tmsg.printf(TJS_W(\"srv %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1]));\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_RET:\n\t\t\t// return\n\t\t\tmsg.printf(TJS_W(\"ret\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tcase VM_ENTRY:\n\t\t\t// enter try-protected block\n\t\t\tmsg.printf(TJS_W(\"entry %09d, %%%d\"),\n\t\t\t\tTJS_FROM_VM_CODE_ADDR(CodeArea[i+1]) + i,\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\n\t\tcase VM_EXTRY:\n\t\t\t// exit from try-protected block\n\t\t\tmsg.printf(TJS_W(\"extry\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tcase VM_THROW:\n\t\t\tmsg.printf(TJS_W(\"throw %%%d\"), TJS_FROM_VM_REG_ADDR(CodeArea[i+1]));\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_CHGTHIS:\n\t\t\tmsg.printf(TJS_W(\"chgthis %%%d, %%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GLOBAL:\n\t\t\tmsg.printf(TJS_W(\"global %%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]));\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_ADDCI:\n\t\t\tmsg.printf(TJS_W(\"addci %%%d, %%%d\"),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+1]),\n\t\t\t\tTJS_FROM_VM_REG_ADDR(CodeArea[i+2]));\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_REGMEMBER:\n\t\t\tmsg.printf(TJS_W(\"regmember\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tcase VM_DEBUGGER:\n\t\t\tmsg.printf(TJS_W(\"debugger\"));\n\t\t\tsize = 1;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tmsg.printf(TJS_W(\"unknown instruction %d\"), CodeArea[i]);\n\t\t\tsize = 1;\n\t\t\tbreak;\n\t\t} /* switch */\n\n\t\toutput_func(msg.c_str(), com.c_str(), i,\n\t\t\tCodeArea + i, size, data);  // call the callback\n\n\t\ti+=size;\n\t}\n\n}\n//---------------------------------------------------------------------------\nstruct of_data\n{\n\tvoid (*func)(const tjs_char*, void *);\n\tvoid *funcdata;\n};\n\nvoid tTJSInterCodeContext::_output_func(const tjs_char *msg,\n\tconst tjs_char *comment, tjs_int addr, const tjs_int32 *codestart,\n\t\ttjs_int size, void *data)\n\n{\n\ttjs_int buflen = (tjs_int)(TJS_strlen(msg) + TJS_strlen(comment) + 20);\n\ttjs_char *buf = new tjs_char[buflen];\n\n\tTJS_snprintf(buf, buflen, TJS_W(\"%08d %ls\"), addr, msg);\n\tif(comment[0])\n\t{\n\t\tTJS_strcat(buf, TJS_W(\"\\t// \"));\n\t\tTJS_strcat(buf, comment);\n\t}\n\n\ttry\n\t{\n\t\tof_data *dat = (of_data *)(data);\n\t\tdat->func(buf, dat->funcdata);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] buf;\n\t\tthrow;\n\t}\n\n\tdelete [] buf;\n}\nvoid tTJSInterCodeContext::_output_func_src(const tjs_char *msg,\n\tconst tjs_char *name, tjs_int line, void *data)\n{\n\ttjs_int buflen = (tjs_int)(TJS_strlen(msg) + TJS_strlen(name) + 20);\n\ttjs_char *buf = new tjs_char[buflen];\n\tif(line >= 0)\n\t\tTJS_snprintf(buf, buflen, TJS_W(\"#%ls(%d) %ls\"), name, line+1, msg);\n\telse\n\t\tTJS_snprintf(buf, buflen, TJS_W(\"#%ls %ls\"), name, msg);\n\ttry\n\t{\n\t\tof_data *dat = (of_data *)(data);\n\t\tdat->func(buf, dat->funcdata);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] buf;\n\t\tthrow;\n\t}\n\n\tdelete [] buf;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::Disassemble(\n\tvoid (*output_func)(const tjs_char *msg,void *data), void *data, tjs_int start,\n\t\ttjs_int end)\n\n{\n\t// dis-assemble\n\tof_data dat;\n\tdat.func =  output_func;\n\tdat.funcdata = data;\n\tDisassemble(_output_func, _output_func_src, (void*)&dat, start, end);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::Disassemble(tjs_int start, tjs_int end)\n{\n\tDisassemble(tTJSScriptBlock::GetConsoleOutput(), Block, start, end);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DisassembleSrcLine(tjs_int codepos)\n{\n\ttjs_int start = FindSrcLineStartCodePos(codepos);\n\tDisassemble(start, codepos + 1);\n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsError.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2's C++ exception class and exception message\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include \"tjsScriptBlock.h\"\n#include \"tjsError.h\"\n#include \"tjs.h\"\n\n#define TJS_MAX_TRACE_TEXT_LEN 1500\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// TJSGetExceptionObject : retrieves TJS 'Exception' object\n//---------------------------------------------------------------------------\nvoid TJSGetExceptionObject(tTJS *tjs, tTJSVariant *res, tTJSVariant &msg,\n\ttTJSVariant *trace/* trace is optional */)\n{\n\tif(!res) return; // not prcess\n\n\t// retrieve class \"Exception\" from global\n\tiTJSDispatch2 *global = tjs->GetGlobalNoAddRef();\n\ttTJSVariant val;\n\tstatic tTJSString Exception_name(TJS_W(\"Exception\"));\n\ttjs_error hr = global->PropGet(0, Exception_name.c_str(),\n\t\tException_name.GetHint(), &val, global);\n\tif(TJS_FAILED(hr)) TJS_eTJSError(TJSExceptionNotFound);\n\t// create an Exception object\n\tiTJSDispatch2 *excpobj;\n\ttTJSVariantClosure clo = val.AsObjectClosureNoAddRef();\n\ttTJSVariant *pmsg = &msg;\n\thr = clo.CreateNew(0, NULL, NULL, &excpobj, 1, &pmsg, clo.ObjThis);\n\tif(TJS_FAILED(hr)) TJS_eTJSError(TJSExceptionNotFound);\n\tif(trace)\n\t{\n\t\tstatic tTJSString trace_name(TJS_W(\"trace\"));\n\t\texcpobj->PropSet(TJS_MEMBERENSURE, trace_name.c_str(), trace_name.GetHint(),\n\t\t\ttrace, excpobj);\n\t}\n\t*res = tTJSVariant(excpobj, excpobj);\n\texcpobj->Release();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// eTJSScriptException\n//---------------------------------------------------------------------------\neTJSScriptError::tScriptBlockHolder::tScriptBlockHolder(tTJSScriptBlock *block)\n{\n\tBlock = block;\n\tBlock->AddRef();\n}\n//---------------------------------------------------------------------------\neTJSScriptError::tScriptBlockHolder::~tScriptBlockHolder()\n{\n\tBlock->Release();\n}\n//---------------------------------------------------------------------------\neTJSScriptError::tScriptBlockHolder::tScriptBlockHolder(\n\t\tconst tScriptBlockHolder &Holder)\n{\n\tBlock = Holder.Block;\n\tBlock->AddRef();\n}\n//---------------------------------------------------------------------------\neTJSScriptError::eTJSScriptError(const ttstr &  Msg,\n\ttTJSScriptBlock *block, tjs_int pos) :\n\t\teTJSError(Msg), Block(block), Position(pos)\n{\n}\n//---------------------------------------------------------------------------\ntjs_int eTJSScriptError::GetSourceLine() const\n{\n\treturn Block.Block->SrcPosToLine(Position) +1;\n}\n//---------------------------------------------------------------------------\nconst tjs_char * eTJSScriptError::GetBlockName() const\n{\n\tconst tjs_char * name = Block.Block->GetName() ;\n\treturn name ? name : TJS_W(\"\");\n}\n//---------------------------------------------------------------------------\nbool eTJSScriptError::AddTrace(tTJSScriptBlock *block, tjs_int srcpos)\n{\n\ttjs_int len = Trace.GetLen();\n\tif(len >= TJS_MAX_TRACE_TEXT_LEN) return false;\n\n\tif(len != 0) Trace += TJS_W(\"\\n<-- \");\n\tTrace += block->GetLineDescriptionString(srcpos);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool eTJSScriptError::AddTrace(tTJSInterCodeContext *context, tjs_int codepos)\n{\n\ttjs_int len = Trace.GetLen();\n\tif(len >= TJS_MAX_TRACE_TEXT_LEN) return false;\n\n\tif(len != 0) Trace += TJS_W(\" <-- \");\n\tTrace += context->GetPositionDescriptionString(codepos);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool eTJSScriptError::AddTrace(const ttstr & data)\n{\n\ttjs_int len = Trace.GetLen();\n\tif(len >= TJS_MAX_TRACE_TEXT_LEN) return false;\n\tif(len != 0) Trace += TJS_W(\" <-- \");\n\tTrace += data;\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// throw helper functions\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\nstatic void TJSReportExceptionSource(const ttstr &msg, tTJSScriptBlock *block,\n\ttjs_int srcpos)\n{\n\tif(TJSEnableDebugMode)\n\t{\n\t\ttTJS *tjs = block->GetTJS();\n\t\ttjs->OutputExceptionToConsole((msg + TJS_W(\" at \") +\n\t\t\tblock->GetLineDescriptionString(srcpos)).c_str());\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TJSReportExceptionSource(const ttstr &msg,\n\ttTJSInterCodeContext *context, tjs_int codepos)\n{\n\tif(TJSEnableDebugMode)\n\t{\n\t\ttTJS *tjs = context->GetBlock()->GetTJS();\n\t\ttjs->OutputExceptionToConsole((msg + TJS_W(\" at \") +\n\t\t\tcontext->GetPositionDescriptionString(codepos)).c_str());\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJS() { throw eTJS(); }\n//---------------------------------------------------------------------------\nvoid TJS_eTJSError(const ttstr & msg) { throw eTJSError(msg); }\nvoid TJS_eTJSError(const tjs_char* msg) { throw eTJSError(msg); }\n//---------------------------------------------------------------------------\nvoid TJS_eTJSVariantError(const ttstr & msg) { throw eTJSVariantError(msg); }\nvoid TJS_eTJSVariantError(const tjs_char * msg) { throw eTJSVariantError(msg); }\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptError(const ttstr &msg, tTJSScriptBlock *block, tjs_int srcpos)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSScriptError(msg, block, srcpos);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptError(const tjs_char *msg, tTJSScriptBlock *block, tjs_int srcpos)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSScriptError(msg, block, srcpos);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptError(const ttstr &msg, tTJSInterCodeContext *context, tjs_int codepos)\n{\n\tTJSReportExceptionSource(msg, context, codepos);\n\tthrow eTJSScriptError(msg, context->GetBlock(), context->CodePosToSrcPos(codepos));\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptError(const tjs_char *msg, tTJSInterCodeContext *context, tjs_int codepos)\n{\n\tTJSReportExceptionSource(msg, context, codepos);\n\tthrow eTJSScriptError(msg, context->GetBlock(), context->CodePosToSrcPos(codepos));\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptException(const ttstr &msg, tTJSScriptBlock *block,\n\ttjs_int srcpos, tTJSVariant &val)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSScriptException(msg, block, srcpos, val);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptException(const tjs_char *msg, tTJSScriptBlock *block,\n\ttjs_int srcpos, tTJSVariant &val)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSScriptException(msg, block, srcpos, val);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptException(const ttstr &msg, tTJSInterCodeContext *context,\n\ttjs_int codepos, tTJSVariant &val)\n{\n\tTJSReportExceptionSource(msg, context, codepos);\n\tthrow eTJSScriptException(msg, context->GetBlock(), context->CodePosToSrcPos(codepos), val);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptException(const tjs_char *msg, tTJSInterCodeContext *context,\n\ttjs_int codepos, tTJSVariant &val)\n{\n\tTJSReportExceptionSource(msg, context, codepos);\n\tthrow eTJSScriptException(msg, context->GetBlock(), context->CodePosToSrcPos(codepos), val);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSCompileError(const ttstr & msg, tTJSScriptBlock *block, tjs_int srcpos)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSCompileError(msg, block, srcpos);\n}\n//---------------------------------------------------------------------------\nvoid TJS_eTJSCompileError(const tjs_char *msg, tTJSScriptBlock *block, tjs_int srcpos)\n{\n\tTJSReportExceptionSource(msg, block, srcpos);\n\tthrow eTJSCompileError(msg, block, srcpos);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJSThrowFrom_tjs_error(tjs_error hr, const tjs_char *name)\n{\n\t// raise an exception descripted as tjs_error\n\t// name = variable name ( otherwide it can be NULL )\n\n\tswitch(hr)\n\t{\n\tcase TJS_E_MEMBERNOTFOUND:\n\t  {\n\t\tif(name)\n\t\t{\n\t\t\tttstr str(TJSMemberNotFound);\n\t\t\tstr.Replace(TJS_W(\"%1\"), name);\n\t\t\tTJS_eTJSError(str);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTJS_eTJSError(TJSMemberNotFoundNoNameGiven);\n\t\t}\n\t  }\n\tcase TJS_E_NOTIMPL:\n\t\tTJS_eTJSError(TJSNotImplemented);\n\tcase TJS_E_INVALIDPARAM:\n\t\tTJS_eTJSError(TJSInvalidParam);\n\tcase TJS_E_BADPARAMCOUNT:\n\t\tTJS_eTJSError(TJSBadParamCount);\n\tcase TJS_E_INVALIDTYPE:\n\t\tTJS_eTJSError(TJSInvalidType);\n\tcase TJS_E_ACCESSDENYED:\n\t\tTJS_eTJSError(TJSAccessDenyed);\n\tcase TJS_E_INVALIDOBJECT:\n\t\tTJS_eTJSError(TJSInvalidObject);\n\tcase TJS_E_NATIVECLASSCRASH:\n\t\tTJS_eTJSError(TJSNativeClassCrash);\n\tdefault:\n\t\tif(TJS_FAILED(hr))\n\t\t{\n\t\t\ttjs_char buf[256];\n\t\t\tTJS_snprintf(buf, 256, TJSUnknownFailure, hr);\n\t\t\tTJS_eTJSError(buf);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// error messages  ( can be localized )\n//---------------------------------------------------------------------------\nttstr TJSNonamedException = TJS_W(\"No-named exception\");\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n#define TJS_DECL_MESSAGE_BODY\n#undef tjsErrorH\n#undef __TJS_ERROR_INC_H__\n#include \"tjsError.h\"\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/tjs2/tjsError.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2's C++ exception class and exception message\n//---------------------------------------------------------------------------\n\n\n#ifndef tjsErrorH\n#define tjsErrorH\n\n#ifndef TJS_DECL_MESSAGE_BODY\n\n#include <stdexcept>\n#include <string>\n#include \"tjsVariant.h\"\n#include \"tjsString.h\"\n#include \"tjsMessage.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nextern ttstr TJSNonamedException;\n\n//---------------------------------------------------------------------------\n// macro\n//---------------------------------------------------------------------------\n#ifdef TJS_SUPPORT_VCL\n\t#define TJS_CONVERT_TO_TJS_EXCEPTION_ADDITIONAL \\\n\t\tcatch(const Exception &e) \\\n\t\t{ \\\n\t\t\tTJS_eTJSError(e.Message.c_str()); \\\n\t\t}\n#else\n\t#define TJS_CONVERT_TO_TJS_EXCEPTION_ADDITIONAL\n#endif\n\n\n#define TJS_CONVERT_TO_TJS_EXCEPTION \\\n\tcatch(const eTJSSilent &e) \\\n\t{ \\\n\t\tthrow e; \\\n\t} \\\n\tcatch(const eTJSScriptException &e) \\\n\t{ \\\n\t\tthrow e; \\\n\t} \\\n\tcatch(const eTJSScriptError &e) \\\n\t{ \\\n\t\tthrow e; \\\n\t} \\\n\tcatch(const eTJSError &e) \\\n\t{ \\\n\t\tthrow e; \\\n\t} \\\n\tcatch(const eTJS &e) \\\n\t{ \\\n\t\tTJS_eTJSError(e.GetMessage()); \\\n\t} \\\n\tcatch(const std::exception &e) \\\n\t{ \\\n\t\tTJS_eTJSError(e.what()); \\\n\t} \\\n\tcatch(const tjs_char *text) \\\n\t{ \\\n\t\tTJS_eTJSError(text); \\\n\t} \\\n\tcatch(const char *text) \\\n\t{ \\\n\t\tTJS_eTJSError(text); \\\n\t} \\\n\tTJS_CONVERT_TO_TJS_EXCEPTION_ADDITIONAL\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSGetExceptionObject : retrieves TJS 'Exception' object\n//---------------------------------------------------------------------------\nextern void TJSGetExceptionObject(class tTJS *tjs, tTJSVariant *res, tTJSVariant &msg,\n\ttTJSVariant *trace/* trace is optional */ = NULL);\n//---------------------------------------------------------------------------\n\n#ifdef TJS_SUPPORT_VCL\n\t#define TJS_CONVERT_TO_TJS_EXCEPTION_OBJECT_ADDITIONAL(_tjs, _result_condition, _result_addr, _before_catched, _when_catched) \\\n\tcatch(EAccessViolation &e) \\\n\t{ \\\n\t\t_before_catched; \\\n\t\tif(_result_condition) \\\n\t\t{ \\\n\t\t\ttTJSVariant msg(e.Message.c_str()); \\\n\t\t\tTJSGetExceptionObject((_tjs), (_result_addr), msg, NULL); \\\n\t\t} \\\n\t\t_when_catched; \\\n\t} \\\n\tcatch(Exception &e) \\\n\t{ \\\n\t\t_before_catched; \\\n\t\tif(_result_condition) \\\n\t\t{ \\\n\t\t\ttTJSVariant msg(e.Message.c_str()); \\\n\t\t\tTJSGetExceptionObject((_tjs), (_result_addr), msg, NULL); \\\n\t\t} \\\n\t\t_when_catched; \\\n\t}\n#else\n\t#define TJS_CONVERT_TO_TJS_EXCEPTION_OBJECT_ADDITIONAL(_tjs, _result_condition, _result_addr, _before_catched, _when_catched)\n#endif\n\n\n#define TJS_CONVERT_TO_TJS_EXCEPTION_OBJECT(tjs, result_condition, result_addr, before_catched, when_catched) \\\n\tcatch(eTJSSilent &e) \\\n\t{ \\\n\t\tthrow e; \\\n\t} \\\n\tcatch(eTJSScriptException &e) \\\n\t{ \\\n\t\tbefore_catched \\\n\t\tif(result_condition) *(result_addr) = e.GetValue(); \\\n\t\twhen_catched; \\\n\t} \\\n\tcatch(eTJSScriptError &e) \\\n\t{ \\\n\t\tbefore_catched \\\n\t\tif(result_condition) \\\n\t\t{ \\\n\t\t\ttTJSVariant msg(e.GetMessage()); \\\n\t\t\ttTJSVariant trace(e.GetTrace()); \\\n\t\t\tTJSGetExceptionObject((tjs), (result_addr), msg, &trace); \\\n\t\t} \\\n\t\twhen_catched; \\\n\t} \\\n\tcatch(eTJS &e)  \\\n\t{  \\\n\t\tbefore_catched \\\n\t\tif(result_condition) \\\n\t\t{ \\\n\t\t\ttTJSVariant msg(e.GetMessage()); \\\n\t\t\tTJSGetExceptionObject((tjs), (result_addr), msg, NULL); \\\n\t\t} \\\n\t\twhen_catched; \\\n\t} \\\n\tcatch(exception &e) \\\n\t{ \\\n\t\tbefore_catched \\\n\t\tif(result_condition) \\\n\t\t{ \\\n\t\t\ttTJSVariant msg(e.what()); \\\n\t\t\tTJSGetExceptionObject((tjs), (result_addr), msg, NULL); \\\n\t\t} \\\n\t\twhen_catched; \\\n\t} \\\n\tTJS_CONVERT_TO_TJS_EXCEPTION_OBJECT_ADDITIONAL(tjs, result_condition, result_addr, before_catched, when_catched) \\\n\tcatch(...) \\\n\t{ \\\n\t\tbefore_catched \\\n\t\tif(result_condition) (result_addr)->Clear(); \\\n\t\twhen_catched; \\\n\t}\n\n\n\n\n//---------------------------------------------------------------------------\n// eTJSxxxxx\n//---------------------------------------------------------------------------\nclass eTJSSilent\n{\n\t// silent exception\n};\n//---------------------------------------------------------------------------\nclass eTJS\n{\npublic:\n\teTJS() {;}\n\teTJS(const eTJS&) {;}\n\teTJS& operator= (const eTJS& e) { return *this; }\n\tvirtual ~eTJS() {;}\n\tvirtual const ttstr & GetMessage() const \n\t{ return TJSNonamedException; }\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJS();\n//---------------------------------------------------------------------------\nclass eTJSError : public eTJS\n{\npublic:\n\teTJSError(const ttstr & Msg) :\n\t\tMessage(Msg) {;}\n\tconst ttstr & GetMessage() const { return Message; }\n\n\tvoid AppendMessage(const ttstr & msg) { Message += msg; }\n\nprivate:\n\tttstr Message;\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJSError(const ttstr & msg);\nvoid TJS_eTJSError(const tjs_char* msg);\n//---------------------------------------------------------------------------\nclass eTJSVariantError : public eTJSError\n{\npublic:\n\teTJSVariantError(const ttstr & Msg) :\n\t\teTJSError(Msg) {;}\n\n\teTJSVariantError(const eTJSVariantError &ref) :\n\t\teTJSError(ref) {;}\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJSVariantError(const ttstr & msg);\nvoid TJS_eTJSVariantError(const tjs_char * msg);\n//---------------------------------------------------------------------------\nclass tTJSScriptBlock;\nclass tTJSInterCodeContext;\nclass eTJSScriptError : public eTJSError\n{\n\tclass tScriptBlockHolder\n\t{\n\tpublic:\n\t\ttScriptBlockHolder(tTJSScriptBlock *block);\n\t\t~tScriptBlockHolder();\n\t\ttScriptBlockHolder(const tScriptBlockHolder &holder);\n\t\ttTJSScriptBlock *Block;\n\t} Block;\n\n\ttjs_int Position;\n\n\tttstr Trace;\n\npublic:\n\ttTJSScriptBlock * GetBlockNoAddRef() { return Block.Block; }\n\n\ttjs_int GetPosition() const { return Position; }\n\n\ttjs_int GetSourceLine() const;\n\n\tconst tjs_char * GetBlockName() const;\n\n\tconst ttstr & GetTrace() const { return Trace; }\n\n\tbool AddTrace(tTJSScriptBlock *block, tjs_int srcpos);\n\tbool AddTrace(tTJSInterCodeContext *context, tjs_int codepos);\n\tbool AddTrace(const ttstr & data);\n\n\teTJSScriptError(const ttstr &  Msg,\n\t\ttTJSScriptBlock *block, tjs_int pos);\n\n\teTJSScriptError(const eTJSScriptError &ref) :\n\t\teTJSError(ref), Block(ref.Block), Position(ref.Position), Trace(ref.Trace) {;}\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptError(const ttstr &msg, tTJSScriptBlock *block, tjs_int srcpos);\nvoid TJS_eTJSScriptError(const tjs_char *msg, tTJSScriptBlock *block, tjs_int srcpos);\nvoid TJS_eTJSScriptError(const ttstr &msg, tTJSInterCodeContext *context, tjs_int codepos);\nvoid TJS_eTJSScriptError(const tjs_char *msg, tTJSInterCodeContext *context, tjs_int codepos);\n//---------------------------------------------------------------------------\nclass eTJSScriptException : public eTJSScriptError\n{\n\ttTJSVariant Value;\npublic:\n\ttTJSVariant & GetValue() { return Value; }\n\n\teTJSScriptException(const ttstr & Msg,\n\t\ttTJSScriptBlock *block, tjs_int pos, tTJSVariant &val)\n\t\t\t: eTJSScriptError(Msg, block, pos), Value(val) {}\n\n\teTJSScriptException(const eTJSScriptException &ref) :\n\t\teTJSScriptError(ref), Value(ref.Value) {;}\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJSScriptException(const ttstr &msg, tTJSScriptBlock *block,\n\ttjs_int srcpos, tTJSVariant &val);\nvoid TJS_eTJSScriptException(const tjs_char *msg, tTJSScriptBlock *block,\n\ttjs_int srcpos, tTJSVariant &val);\nvoid TJS_eTJSScriptException(const ttstr &msg, tTJSInterCodeContext *context,\n\ttjs_int codepos, tTJSVariant &val);\nvoid TJS_eTJSScriptException(const tjs_char *msg, tTJSInterCodeContext *context,\n\ttjs_int codepos, tTJSVariant &val);\n//---------------------------------------------------------------------------\nclass eTJSCompileError : public eTJSScriptError\n{\npublic:\n\teTJSCompileError(const ttstr &  Msg, tTJSScriptBlock *block, tjs_int pos) :\n\t\teTJSScriptError(Msg, block, pos) {;}\n\n\teTJSCompileError(const eTJSCompileError &ref) : eTJSScriptError(ref) {;}\n\n};\n//---------------------------------------------------------------------------\nvoid TJS_eTJSCompileError(const ttstr & msg, tTJSScriptBlock *block, tjs_int srcpos);\nvoid TJS_eTJSCompileError(const tjs_char * msg, tTJSScriptBlock *block, tjs_int srcpos);\n//---------------------------------------------------------------------------\nvoid TJSThrowFrom_tjs_error(tjs_error hr, const tjs_char *name = NULL);\n#define TJS_THROW_IF_ERROR(x) { \\\n\ttjs_error ____er; ____er = (x); if(TJS_FAILED(____er)) TJSThrowFrom_tjs_error(____er); }\n//---------------------------------------------------------------------------\n} // namespace TJS\n//---------------------------------------------------------------------------\n#endif // #ifndef TJS_DECL_MESSAGE_BODY\n\n\n\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// messages\n//---------------------------------------------------------------------------\nnamespace TJS\n{\n#ifdef TJS_DECL_MESSAGE_BODY\n\t#define TJS_MSG_DECL(name, msg) tTJSMessageHolder name(TJS_W(#name), msg);\n\t#define TJS_MSG_DECL_NULL(name) tTJSMessageHolder name(TJS_W(#name), NULL);\n#else\n\t#define TJS_MSG_DECL(name, msg) extern tTJSMessageHolder name;\n\t#define TJS_MSG_DECL_NULL(name) extern tTJSMessageHolder name;\n#endif\n//---------------------------------------------------------------------------\n#include \"tjsErrorInc.h\"\n\n#undef TJS_MSG_DECL\n#undef TJS_MSG_DECL_NULL\n//---------------------------------------------------------------------------\n\n}\n//---------------------------------------------------------------------------\n\n\n#endif // #ifndef tjsErrorH\n\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsErrorDefs.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// return values as tjs_error\n//---------------------------------------------------------------------------\n\n#ifndef tjsErrorDefsH\n#define tjsErrorDefsH\n\nnamespace TJS\n{\n\n// #define TJS_STRICT_ERROR_CODE_CHECK\n\t// defining this enables strict error code checking,\n\t// for debugging.\n\n/*[*/\n//---------------------------------------------------------------------------\n// return values as tjs_error\n//---------------------------------------------------------------------------\n#define TJS_E_MEMBERNOTFOUND\t\t(-1001)\n#define TJS_E_NOTIMPL\t\t\t\t(-1002)\n#define TJS_E_INVALIDPARAM\t\t\t(-1003)\n#define TJS_E_BADPARAMCOUNT\t\t\t(-1004)\n#define TJS_E_INVALIDTYPE\t\t\t(-1005)\n#define TJS_E_INVALIDOBJECT\t\t\t(-1006)\n#define TJS_E_ACCESSDENYED\t\t\t(-1007)\n#define TJS_E_NATIVECLASSCRASH\t\t(-1008)\n\n#define TJS_S_TRUE\t\t\t\t\t(1)\n#define TJS_S_FALSE\t\t\t\t\t(2)\n\n#define TJS_S_OK                    (0)\n#define TJS_E_FAIL\t\t\t\t\t(-1)\n\n#define TJS_S_MAX (2)\n\t// maximum possible number of success status.\n\t// numbers over this may be regarded as a failure in\n\t// strict-checking mode.\n\n#ifdef TJS_STRICT_ERROR_CODE_CHECK\n\tstatic inline bool TJS_FAILED(tjs_error hr)\n\t{\n\t\tif(hr < 0) return true;\n\t\tif(hr > TJS_S_MAX) return true;\n\t\treturn false;\n\t}\n#else\n\t#define TJS_FAILED(x)\t\t\t\t((x)<0)\n#endif\n#define TJS_SUCCEEDED(x)\t\t\t(!TJS_FAILED(x))\n\nstatic inline bool TJSIsObjectValid(tjs_error hr)\n{\n\t// checks object validity by returning value of iTJSDispatch2::IsValid\n\n\tif(hr == TJS_S_TRUE) return true;  // mostly expected value for valid object\n\tif(hr == TJS_E_NOTIMPL) return true; // also valid for object which does not implement IsValid\n\n\treturn false; // otherwise the object is not valid\n}\n\n/*]*/\n\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsErrorInc.h",
    "content": "// generated from gentext.pl Messages.xlsx\n#ifndef __TJS_ERROR_INC_H__\n#define __TJS_ERROR_INC_H__\nTJS_MSG_DECL(TJSInternalError, TJS_W(\"Internal error\"))\nTJS_MSG_DECL(TJSWarning, TJS_W(\"Warning: \"))\nTJS_MSG_DECL(TJSWarnEvalOperator, TJS_W(\"Non-global post-! operator is used (note that the post-! operator behavior is changed on TJS2 version 2.4.1)\"))\nTJS_MSG_DECL(TJSNarrowToWideConversionError, TJS_W(\"Cannot convert given narrow string to wide string\"))\nTJS_MSG_DECL(TJSVariantConvertError, TJS_W(\"Cannot convert the variable type (%1 to %2)\"))\nTJS_MSG_DECL(TJSVariantConvertErrorToObject, TJS_W(\"Cannot convert the variable type (%1 to Object)\"))\nTJS_MSG_DECL(TJSIDExpected, TJS_W(\"Specify an ID\"))\nTJS_MSG_DECL(TJSSubstitutionInBooleanContext, TJS_W(\"Substitution in boolean context (use form of '(A=B)!=0' to compare to zero)\"));\nTJS_MSG_DECL(TJSCannotModifyLHS, TJS_W(\"This expression cannot be used as a lvalue\"))\nTJS_MSG_DECL(TJSInsufficientMem, TJS_W(\"Insufficient memory\"))\nTJS_MSG_DECL(TJSCannotGetResult, TJS_W(\"Cannot get the value of this expression\"))\nTJS_MSG_DECL(TJSNullAccess, TJS_W(\"Accessing to null object\"))\nTJS_MSG_DECL(TJSMemberNotFound, TJS_W(\"Member \\\"%1\\\" does not exist\"))\nTJS_MSG_DECL(TJSMemberNotFoundNoNameGiven, TJS_W(\"Member does not exist\"))\nTJS_MSG_DECL(TJSNotImplemented, TJS_W(\"Called method is not implemented\"))\nTJS_MSG_DECL(TJSInvalidParam, TJS_W(\"Invalid argument\"))\nTJS_MSG_DECL(TJSBadParamCount, TJS_W(\"Invalid argument count\"))\nTJS_MSG_DECL(TJSInvalidType, TJS_W(\"Not a function or invalid method/property type\"))\nTJS_MSG_DECL(TJSSpecifyDicOrArray, TJS_W(\"Specify a Dictionary object or an Array object\"));\nTJS_MSG_DECL(TJSSpecifyArray, TJS_W(\"Specify an Array object\"));\nTJS_MSG_DECL(TJSStringDeallocError, TJS_W(\"Cannot free the string memory block\"))\nTJS_MSG_DECL(TJSStringAllocError, TJS_W(\"Cannot allocate the string memory block\"))\nTJS_MSG_DECL(TJSMisplacedBreakContinue, TJS_W(\"Cannot place \\\"break\\\" or \\\"continue\\\" here\"))\nTJS_MSG_DECL(TJSMisplacedCase, TJS_W(\"Cannot place \\\"case\\\" here\"))\nTJS_MSG_DECL(TJSMisplacedReturn, TJS_W(\"Cannot place \\\"return\\\" here\"))\nTJS_MSG_DECL(TJSStringParseError, TJS_W(\"Un-terminated string/regexp/octet literal\"))\nTJS_MSG_DECL(TJSNumberError, TJS_W(\"Cannot be parsed as a number\"))\nTJS_MSG_DECL(TJSUnclosedComment, TJS_W(\"Un-terminated comment\"))\nTJS_MSG_DECL(TJSInvalidChar, TJS_W(\"Invalid character \\'%1\\'\"))\nTJS_MSG_DECL(TJSExpected, TJS_W(\"Expected %1\"))\nTJS_MSG_DECL(TJSSyntaxError, TJS_W(\"Syntax error (%1)\"))\nTJS_MSG_DECL(TJSPPError, TJS_W(\"Error in conditional compiling expression\"))\nTJS_MSG_DECL(TJSCannotGetSuper, TJS_W(\"Super class does not exist or cannot specify the super class\"))\nTJS_MSG_DECL(TJSInvalidOpecode, TJS_W(\"Invalid VM code\"))\nTJS_MSG_DECL(TJSRangeError, TJS_W(\"The value is out of the range\"))\nTJS_MSG_DECL(TJSAccessDenyed, TJS_W(\"Invalid operation for Read-only or Write-only property\"))\nTJS_MSG_DECL(TJSNativeClassCrash, TJS_W(\"Invalid object context\"))\nTJS_MSG_DECL(TJSInvalidObject, TJS_W(\"The object is already invalidated\"))\nTJS_MSG_DECL(TJSDuplicatedPropHandler, TJS_W(\"Duplicated \\\"setter\\\" or \\\"getter\\\"\"))\nTJS_MSG_DECL(TJSCannotOmit, TJS_W(\"\\\"...\\\" is used out of functions\"))\nTJS_MSG_DECL(TJSCannotParseDate, TJS_W(\"Invalid date format\"))\nTJS_MSG_DECL(TJSInvalidValueForTimestamp, TJS_W(\"Invalid value for date/time\"))\nTJS_MSG_DECL(TJSExceptionNotFound, TJS_W(\"Cannot convert exception because \\\"Exception\\\" does not exist\"))\nTJS_MSG_DECL(TJSInvalidFormatString, TJS_W(\"Invalid format string\"))\nTJS_MSG_DECL(TJSDivideByZero, TJS_W(\"Division by zero\"))\nTJS_MSG_DECL(TJSNotReconstructiveRandomizeData, TJS_W(\"Cannot reconstruct random seeds\"))\nTJS_MSG_DECL(TJSSymbol, TJS_W(\"ID\"))\nTJS_MSG_DECL(TJSCallHistoryIsFromOutOfTJS2Script, TJS_W(\"[out of TJS2 script]\"))\nTJS_MSG_DECL(TJSNObjectsWasNotFreed, TJS_W(\"Total %1 Object(s) was not freed\"))\nTJS_MSG_DECL(TJSObjectCreationHistoryDelimiter, TJS_W(\" <-- \"));\nTJS_MSG_DECL(TJSObjectWasNotFreed, TJS_W(\"Object %1 [%2] wes not freed / The object was created at : %2\"))\nTJS_MSG_DECL(TJSGroupByObjectTypeAndHistory, TJS_W(\"Group by object type and location where the object was created\"))\nTJS_MSG_DECL(TJSGroupByObjectType, TJS_W(\"Group by object type\"))\nTJS_MSG_DECL(TJSObjectCountingMessageGroupByObjectTypeAndHistory, TJS_W(\"%1 time(s) : [%2] %3\"))\nTJS_MSG_DECL(TJSObjectCountingMessageTJSGroupByObjectType, TJS_W(\"%1 time(s) : [%2]\"))\nTJS_MSG_DECL(TJSWarnRunningCodeOnDeletingObject, TJS_W(\"%4: Running code on deleting-in-progress object %1[%2] / The object was created at : %3\"))\nTJS_MSG_DECL(TJSWriteError, TJS_W(\"Write error\"))\nTJS_MSG_DECL(TJSReadError, TJS_W(\"Read error\"))\nTJS_MSG_DECL(TJSSeekError, TJS_W(\"Seek error\"))\nTJS_MSG_DECL(TJSByteCodeBroken, TJS_W(\"Bytecode read error. File is broken or it's not bytecode file.\"))\nTJS_MSG_DECL(TJSObjectHashMapLogVersionMismatch, TJS_W(\"Object Hash Map log version mismatch\"))\nTJS_MSG_DECL(TJSCurruptedObjectHashMapLog, TJS_W(\"Currupted Object Hash Map log\"))\nTJS_MSG_DECL(TJSUnknownFailure, TJS_W(\"Unknown failure : %08X\"))\nTJS_MSG_DECL(TJSUnknownPackUnpackTemplateCharcter, TJS_W(\"Unknown pack/unpack TEMPLATE charcter\"))\nTJS_MSG_DECL(TJSUnknownBitStringCharacter, TJS_W(\"Unknown bit string charcter\"))\nTJS_MSG_DECL(TJSUnknownHexStringCharacter, TJS_W(\"Unknown Hex string charcter\"))\nTJS_MSG_DECL(TJSNotSupportedUuencode, TJS_W(\"Not supported uuencode\"))\nTJS_MSG_DECL(TJSNotSupportedBER, TJS_W(\"Not supported BER\"))\nTJS_MSG_DECL(TJSNotSupportedUnpackLP, TJS_W(\"Not supported unpack 'lp'\"))\nTJS_MSG_DECL(TJSNotSupportedUnpackP, TJS_W(\"Not supported unpack 'p'\"))\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsError_jp.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Japanese localized messages\n//---------------------------------------------------------------------------\n\nTJS_MSG_DECL(TJSInternalError, TJS_W(\"G[܂\"))\nTJS_MSG_DECL(TJSWarning, TJS_W(\"x: \"))\nTJS_MSG_DECL(TJSWarnEvalOperator, TJS_W(\"O[ołȂꏊŌu ! ZqgĂ܂(̉Zq̋TJS2 version 2.4.1 ŕς܂̂łӂ)\"))\nTJS_MSG_DECL(TJSNarrowToWideConversionError, TJS_W(\"ANSI  UNICODE ɕϊł܂B݂̃R[hy[Wŉ߂łȂ܂܂Ă܂Bf[^w肳Ă邩mFĂBf[^jĂ\\܂\"))\nTJS_MSG_DECL(TJSVariantConvertError, TJS_W(\"%1  %2 ֌^ϊł܂\"))\nTJS_MSG_DECL(TJSVariantConvertErrorToObject, TJS_W(\"%1  Object ֌^ϊł܂BObject ^v镶 Object ^ȊO̒lnƂ̃G[܂\"))\nTJS_MSG_DECL(TJSIDExpected, TJS_W(\"ʎqw肵Ă\"))\nTJS_MSG_DECL(TJSSubstitutionInBooleanContext, TJS_W(\"_l߂Ăꏊ = ZqgpĂ܂(== Zq̊ԈႢłHŃ[ƒlrꍇ́A(A=B) != 0 ̌`gƂ߂܂)\"));\nTJS_MSG_DECL(TJSCannotModifyLHS, TJS_W(\"sȑsȎ̑ł\"))\nTJS_MSG_DECL(TJSInsufficientMem, TJS_W(\"܂\"))\nTJS_MSG_DECL(TJSCannotGetResult, TJS_W(\"̎͒l𓾂邱Ƃł܂\"))\nTJS_MSG_DECL(TJSNullAccess, TJS_W(\"null IuWFNgɃANZX悤Ƃ܂\"))\nTJS_MSG_DECL(TJSMemberNotFound, TJS_W(\"o \\\"%1\\\" ܂\"))\nTJS_MSG_DECL(TJSMemberNotFoundNoNameGiven, TJS_W(\"o܂\"))\nTJS_MSG_DECL(TJSNotImplemented, TJS_W(\"ĂяoƂ@\\͖ł\"))\nTJS_MSG_DECL(TJSInvalidParam, TJS_W(\"sȈł\"))\nTJS_MSG_DECL(TJSBadParamCount, TJS_W(\"̐sł\"))\nTJS_MSG_DECL(TJSInvalidType, TJS_W(\"֐ł͂ȂvpeB̎ނႢ܂\"))\nTJS_MSG_DECL(TJSSpecifyDicOrArray, TJS_W(\"Dictionary ܂ Array NX̃IuWFNgw肵Ă\"))\nTJS_MSG_DECL(TJSSpecifyArray, TJS_W(\"Array NX̃IuWFNgw肵Ă\"))\nTJS_MSG_DECL(TJSStringDeallocError, TJS_W(\"񃁃ubNł܂\"))\nTJS_MSG_DECL(TJSStringAllocError, TJS_W(\"񃁃ubNmۂł܂\"))\nTJS_MSG_DECL(TJSMisplacedBreakContinue, TJS_W(\"\\\"break\\\" ܂ \\\"continue\\\" ͂ɏƂ͂ł܂\"))\nTJS_MSG_DECL(TJSMisplacedCase, TJS_W(\"\\\"case\\\" ͂ɏƂ͂ł܂\"))\nTJS_MSG_DECL(TJSMisplacedReturn, TJS_W(\"\\\"return\\\" ͂ɏƂ͂ł܂\"))\nTJS_MSG_DECL(TJSStringParseError, TJS_W(\"萔/K\\/INebglIȂ܂܃XNvg̏I[ɒB܂\"))\nTJS_MSG_DECL(TJSNumberError, TJS_W(\"lƂĉ߂ł܂\"))\nTJS_MSG_DECL(TJSUnclosedComment, TJS_W(\"RgIȂ܂܃XNvg̏I[ɒB܂\"))\nTJS_MSG_DECL(TJSInvalidChar, TJS_W(\"sȕł : \\'%1\\'\"))\nTJS_MSG_DECL(TJSExpected, TJS_W(\"%1 ܂\"))\nTJS_MSG_DECL(TJSSyntaxError, TJS_W(\"@G[ł(%1)\"))\nTJS_MSG_DECL(TJSPPError, TJS_W(\"RpCɃG[܂\"))\nTJS_MSG_DECL(TJSCannotGetSuper, TJS_W(\"X[p[NX݂ȂX[p[NXł܂\"))\nTJS_MSG_DECL(TJSInvalidOpecode, TJS_W(\"s VM R[hł\"))\nTJS_MSG_DECL(TJSRangeError, TJS_W(\"l͈͊Oł\"))\nTJS_MSG_DECL(TJSAccessDenyed, TJS_W(\"ǂݍݐp邢͏ݐpvpeBɑ΂čsȂ悤Ƃ܂\"))\nTJS_MSG_DECL(TJSNativeClassCrash, TJS_W(\"sReLXgႢ܂\"))\nTJS_MSG_DECL(TJSInvalidObject, TJS_W(\"IuWFNg͂łɖĂ܂\"))\nTJS_MSG_DECL(TJSCannotOmit, TJS_W(\"\\\"...\\\" ͊֐Oł͎g܂\"))\nTJS_MSG_DECL(TJSCannotParseDate, TJS_W(\"sȓť`ł\"))\nTJS_MSG_DECL(TJSInvalidValueForTimestamp, TJS_W(\"sȓtEł\"))\nTJS_MSG_DECL(TJSExceptionNotFound, TJS_W(\"\\\"Exception\\\" ݂ȂߗOIuWFNg쐬ł܂\"))\nTJS_MSG_DECL(TJSInvalidFormatString, TJS_W(\"sȏł\"))\nTJS_MSG_DECL(TJSDivideByZero, TJS_W(\"0 ŏZ悤Ƃ܂\"))\nTJS_MSG_DECL(TJSNotReconstructiveRandomizeData, TJS_W(\"nł܂(炭sȃf[^n܂)\"))\nTJS_MSG_DECL(TJSSymbol, TJS_W(\"ʎq\"))\nTJS_MSG_DECL(TJSCallHistoryIsFromOutOfTJS2Script, TJS_W(\"[TJSXNvgǗO]\"))\nTJS_MSG_DECL(TJSNObjectsWasNotFreed, TJS_W(\"v %1 ̃IuWFNgĂ܂\"))\n#ifdef TJS_TEXT_OUT_CRLF\nTJS_MSG_DECL(TJSObjectCreationHistoryDelimiter, TJS_W(\"\\r\\n                     \"))\n#else\nTJS_MSG_DECL(TJSObjectCreationHistoryDelimiter, TJS_W(\"\\n                     \"))\n#endif\n#ifdef TJS_TEXT_OUT_CRLF\nTJS_MSG_DECL(TJSObjectWasNotFreed,\n\t\t\t\t TJS_W(\"IuWFNg %1 [%2] Ă܂BIuWFNg쐬̌Ăяo͈ȉ̒ʂł:\\r\\n                     %3\"))\n#else\nTJS_MSG_DECL(TJSObjectWasNotFreed,\n\t\t\t\t TJS_W(\"IuWFNg %1 [%2] Ă܂BIuWFNg쐬̌Ăяo͈ȉ̒ʂł:\\n                     %3\"))\n#endif\nTJS_MSG_DECL(TJSGroupByObjectTypeAndHistory, TJS_W(\"IuWFNg̃^CvƃIuWFNg쐬̗ɂ镪\"))\nTJS_MSG_DECL(TJSGroupByObjectType, TJS_W(\"IuWFNg̃^Cvɂ镪\"))\n#ifdef TJS_TEXT_OUT_CRLF\nTJS_MSG_DECL(TJSObjectCountingMessageGroupByObjectTypeAndHistory,\n\t\t\t\t TJS_W(\"%1  : [%2]\\r\\n                     %3\"))\n#else\nTJS_MSG_DECL(TJSObjectCountingMessageGroupByObjectTypeAndHistory,\n\t\t\t\t TJS_W(\"%1  : [%2]\\n                     %3\"))\n#endif\nTJS_MSG_DECL(TJSObjectCountingMessageTJSGroupByObjectType, TJS_W(\"%1  : [%2]\"))\n#ifdef TJS_TEXT_OUT_CRLF\nTJS_MSG_DECL(TJSWarnRunningCodeOnDeletingObject, TJS_W(\"%4: 폜̃IuWFNg %1[%2] ŃR[hsĂ܂B̃IuWFNg̍쐬̌Ăяo͈ȉ̒ʂł:\\r\\n                     %3\"))\n#else\nTJS_MSG_DECL(TJSWarnRunningCodeOnDeletingObject, TJS_W(\"%4: 폜̃IuWFNg %1[%2] ŃR[hsĂ܂B̃IuWFNg̍쐬̌Ăяo͈ȉ̒ʂł:\\n                     %3\"))\n#endif\nTJS_MSG_DECL(TJSWriteError, TJS_W(\"݃G[܂\"))\nTJS_MSG_DECL(TJSReadError, TJS_W(\"ǂݍ݃G[܂Bt@CjĂ\\AfoCX̓ǂݍ݂Ɏs\\܂\"))\nTJS_MSG_DECL(TJSSeekError, TJS_W(\"V[NG[܂Bt@CjĂ\\AfoCX̓ǂݍ݂Ɏs\\܂\"))\n\nTJS_MSG_DECL(TJSByteCodeBroken, TJS_W(\"oCgR[ht@Cǂݍ݃G[Bt@CĂ邩oCgR[hƂ͈قȂt@Cł\"))\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/tjs2/tjsException.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Exception Class\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsException.h\"\n\nnamespace TJS\n{\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Exception : TJS Native Class : Exception\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Exception::ClassID = (tjs_uint32)-1;\ntTJSNC_Exception::tTJSNC_Exception() :\n\ttTJSNativeClass(TJS_W(\"Exception\"))\n{\n\t// class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/Exception)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Exception)\n{\n\ttTJSVariant val = TJS_W(\"\");\n\tif(TJS_PARAM_EXIST(0)) val.CopyRef(*param[0]);\n\n\tstatic tTJSString message_name(TJS_W(\"message\"));\n\tobjthis->PropSet(TJS_MEMBERENSURE, message_name.c_str(), message_name.GetHint(),\n\t\t&val, objthis);\n\n\tif(TJS_PARAM_EXIST(1)) val.CopyRef(*param[1]); else val = TJS_W(\"\");\n\n\tstatic tTJSString trace_name(TJS_W(\"trace\"));\n\tobjthis->PropSet(TJS_MEMBERENSURE, trace_name.c_str(), trace_name.GetHint(),\n\t\t&val, objthis);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Exception)\n//---------------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n} // tTJSNC_Exception::tTJSNC_Exception()\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsException.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Exception Class\n//---------------------------------------------------------------------------\n#ifndef tjsExceptionH\n#define tjsExceptionH\n\n#include \"tjsNative.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSNC_Exception\n//---------------------------------------------------------------------------\nclass tTJSNC_Exception : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Exception();\nprivate:\n\tstatic tjs_uint32 ClassID;\n};\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsGlobalStringMap.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Global String Map\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsGlobalStringMap.h\"\n#include \"tjsHashSearch.h\"\n#include <mutex>\n\n/*\n\tGlobal String Map is a large string hash table, to share the string\n\twhich is already 'known' by the hash table, using TJS2 string heap\n\tmanagement mechanism. This will dramatically decrease string heap\n\tsize which is used for constant strings (member names, string literals,\n\tetc ...).\n*/\n\n#define TJS_GLOBAL_STRING_MAP_SIZE 5000\n\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// tTJSGlobalStringMap - hash map to keep constant strings shared\n//---------------------------------------------------------------------------\nclass tTJSGlobalStringMap;\nstatic tTJSGlobalStringMap * TJSGlobalStringMap = NULL;\nstruct tTJSEmptyClass {};\nclass tTJSGlobalStringMap\n{\n\ttTJSHashCache<tTJSString, tTJSEmptyClass, tTJSHashFunc<ttstr>, 1024> Hash;\n\n\ttjs_int RefCount;\n\npublic:\n\ttTJSGlobalStringMap()  : Hash (TJS_GLOBAL_STRING_MAP_SIZE)\n\t{\n\t\tRefCount = 1;\n\t\tTJSGlobalStringMap = this;\n\t}\n\nprotected:\n\t~tTJSGlobalStringMap()\n\t{\n\t\tTJSGlobalStringMap = NULL;\n\t}\n\npublic:\n\ttTJSString _Map(const tTJSString & string)\n\t{\n\t\t// Search Hash, and return the string which to be shared\n\n\t\tconst tTJSString * key;\n\t\ttTJSEmptyClass * v;\n\n\t\ttjs_uint32 hash = tTJSHashFunc<ttstr>::Make(string);\n\n\t\tif(Hash.FindAndTouchWithHash(string, hash, key, v))\n\t\t{\n\t\t\tttstr ret(*key);\n\t\t\tif(ret.GetHint()) *(ret.GetHint()) = hash;\n\t\t\treturn ret;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tHash.AddWithHash(string, hash, tTJSEmptyClass());\n\t\t\tttstr ret(string);\n\t\t\tif(ret.GetHint()) *(ret.GetHint()) = hash;\n\t\t\treturn ret;\n\t\t}\n\t}\n\nprotected:\n\tvoid _AddRef() { RefCount ++; }\n\tvoid _Release() { if(RefCount == 1) delete this; else RefCount --; }\n\npublic:\n\tstatic void AddRef()\n\t{\n\t\tif(TJSGlobalStringMap)\n\t\t\tTJSGlobalStringMap->_AddRef();\n\t\telse\n\t\t\tnew tTJSGlobalStringMap();\n\t}\n\n\tstatic void Release()\n\t{\n\t\tif(TJSGlobalStringMap)\n\t\t\tTJSGlobalStringMap->_Release();\n\t}\n\n\tstatic ttstr Map(const ttstr & string)\n\t{\n\t\tif(TJSGlobalStringMap)\n\t\t\treturn TJSGlobalStringMap->_Map(string);\n\t\telse\n\t\t\treturn string;\n\t}\n};\n//---------------------------------------------------------------------------\nvoid TJSAddRefGlobalStringMap()\n{\n\ttTJSGlobalStringMap::AddRef();\n}\n//---------------------------------------------------------------------------\nvoid TJSReleaseGlobalStringMap()\n{\n\ttTJSGlobalStringMap::Release();\n}\n//---------------------------------------------------------------------------\nstatic std::mutex _mutex;\nttstr TJSMapGlobalStringMap(const ttstr & string)\n{\n\t// for multi-thread\n\tstd::lock_guard<std::mutex> lk(_mutex);\n\treturn tTJSGlobalStringMap::Map(string);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsGlobalStringMap.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Global String Map\n//---------------------------------------------------------------------------\n#ifndef tjsGlobalStringMapH\n#define tjsGlobalStringMapH\n\n#include \"tjsString.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSGlobalStringMap - hash map to keep constant strings shared\n//---------------------------------------------------------------------------\nextern void TJSAddRefGlobalStringMap();\nextern void TJSReleaseGlobalStringMap();\nTJS_EXP_FUNC_DEF(ttstr, TJSMapGlobalStringMap, (const ttstr & string));\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsHashSearch.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// An Implementation of Hash Searching\n//---------------------------------------------------------------------------\n#ifndef HashSearchH\n#define HashSearchH\n\n#include \"tjs.h\"\n\n#define TJS_HS_DEFAULT_HASH_SIZE 64\n#define TJS_HS_HASH_USING\t0x1\n#define TJS_HS_HASH_LV1\t0x2\n\n// #define TJS_HS_DEBUG_CHAIN  // to debug chain algorithm\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSHashFunc : Hash function object\n//---------------------------------------------------------------------------\n// the hash function used here is similar to one which used in perl 5.8,\n// see also http://burtleburtle.net/bob/hash/doobs.html (One-at-a-Time Hash)\ntemplate <typename T>\nclass tTJSHashFunc\n{\npublic:\n\tstatic tjs_uint32 Make(const T &val)\n\t{\n\t\tconst char *p = (const char*)&val;\n\t\tconst char *plim = (const char*)&val + sizeof(T);\n\t\ttjs_uint32 ret = 0;\n\t\twhile(p<plim)\n\t\t{\n\t\t\tret += *p;\n\t\t\tret += (ret << 10);\n\t\t\tret ^= (ret >> 6);\n\t\t\tp++;\n\t\t}\n\t\tret += (ret << 3);\n\t\tret ^= (ret >> 11);\n\t\tret += (ret << 15);\n\t\tif(!ret) ret = (tjs_uint32)-1;\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\ntemplate <>\nclass tTJSHashFunc<ttstr> // a specialized template of tTJSHashFunc for ttstr\n{\npublic:\n\tstatic tjs_uint32 Make(const ttstr &val)\n\t{\n\t\tif(val.IsEmpty()) return 0;\n\t\tconst tjs_char *str = val.c_str();\n\t\ttjs_uint32 ret = 0;\n\t\twhile(*str)\n\t\t{\n\t\t\tret += *str;\n\t\t\tret += (ret << 10);\n\t\t\tret ^= (ret >> 6);\n\t\t\tstr++;\n\t\t}\n\t\tret += (ret << 3);\n\t\tret ^= (ret >> 11);\n\t\tret += (ret << 15);\n\t\tif(!ret) ret = (tjs_uint32)-1;\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\ntemplate <>\nclass tTJSHashFunc<tjs_char *> // a specialized template of tTJSHashFunc for tjs_char\n{\npublic:\n\tstatic tjs_uint32 Make(const tjs_char *str)\n\t{\n\t\tif(!str) return 0;\n\t\ttjs_uint32 ret = 0;\n\t\twhile(*str)\n\t\t{\n\t\t\tret += *str;\n\t\t\tret += (ret << 10);\n\t\t\tret ^= (ret >> 6);\n\t\t\tstr++;\n\t\t}\n\t\tret += (ret << 3);\n\t\tret ^= (ret >> 11);\n\t\tret += (ret << 15);\n\t\tif(!ret) ret = (tjs_uint32)-1;\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\ntemplate <>\nclass tTJSHashFunc<tjs_nchar *> // a specialized template of tTJSHashFunc for tjs_nchar\n{\npublic:\n\tstatic tjs_uint32 Make(const tjs_nchar *str)\n\t{\n\t\tif(!str) return 0;\n\t\ttjs_uint32 ret = 0;\n\t\twhile(*str)\n\t\t{\n\t\t\tret += *str;\n\t\t\tret += (ret << 10);\n\t\t\tret ^= (ret >> 6);\n\t\t\tstr++;\n\t\t}\n\t\tret += (ret << 3);\n\t\tret ^= (ret >> 11);\n\t\tret += (ret << 15);\n\t\tif(!ret) ret = (tjs_uint32)-1;\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\n// tTJSHashTable : a simple implementation of Chain Hash algorithm\n//---------------------------------------------------------------------------\n/*\n\tNot that ValueT must implement both \"operator =\" and a copy constructor.\n*/\ntemplate <typename KeyT, typename ValueT, typename HashFuncT = tTJSHashFunc<KeyT>,\n\ttjs_int HashSize = TJS_HS_DEFAULT_HASH_SIZE>\nclass tTJSHashTable\n{\nprivate:\n\tstruct element\n\t{\n\t\ttjs_uint32 Hash;\n\t\ttjs_uint32 Flags; // management flag\n\t\tchar Key[sizeof(KeyT)];\n\t\tchar Value[sizeof(ValueT)];\n\t\telement *Prev; // previous chain item\n\t\telement *Next; // next chain item\n\t\telement *NPrev; // previous item in the additional order\n\t\telement *NNext; // next item in the additional order\n\t} Elms[HashSize];\n\n\ttjs_uint Count;\n\n\telement *NFirst; // first item in the additional order\n\telement *NLast;  // last item in the additional order\n\npublic:\n\n\tclass tIterator // this differs a bit from STL's iterator\n\t{\n\t\telement * elm;\n\tpublic:\n\t\ttIterator() { elm = NULL; }\n\n//\t\ttIterator(const tIterator &ref)\n//\t\t{ elm = ref.elm; }\n\n\t\ttIterator(element *r_elm)\n\t\t{ elm = r_elm; }\n\n\t\ttIterator operator ++()\n\t\t{ elm = elm->NNext; return elm;}\n\n\t\ttIterator operator --()\n\t\t{ elm = elm->NPrev; return elm;}\n\n\t\ttIterator operator ++(int dummy)\n\t\t{ element *b_elm = elm; elm = elm->NNext; return b_elm; }\n\n\t\ttIterator operator --(int dummy)\n\t\t{ element *b_elm = elm; elm = elm->NPrev; return b_elm; }\n\n\t\tvoid operator +(tjs_int n)\n\t\t{ while(n--) elm = elm->NNext; }\n\n\t\tvoid operator -(tjs_int n)\n\t\t{ while(n--) elm = elm->NPrev; }\n\n\t\tbool operator ==(const tIterator & ref) const\n\t\t{ return elm == ref.elm; }\n\n\t\tbool operator !=(const tIterator & ref) const\n\t\t{ return elm != ref.elm; }\n\n\t\tKeyT & GetKey()\n\t\t{ return *(KeyT*)elm->Key; }\n\n\t\tValueT & GetValue()\n\t\t{ return *(ValueT*)elm->Value; }\n\n\t\tbool IsNull() const { return elm == NULL; }\n\t};\n\n\tstatic tjs_uint32 MakeHash(const KeyT &key)\n\t\t{ return HashFuncT::Make(key); }\n\n\ttTJSHashTable()\n\t{\n\t\tInternalInit();\n\t}\n\n\t~tTJSHashTable()\n\t{\n\t\tInternalClear();\n\t}\n\n\tvoid Clear()\n\t{\n\t\tInternalClear();\n\t}\n\n\ttIterator GetFirst() const\n\t{\n\t\treturn tIterator(NFirst);\n\t}\n\n\ttIterator GetLast() const\n\t{\n\t\treturn tIterator(NLast);\n\t}\n\n\n\tvoid Add(const KeyT &key, const ValueT &value)\n\t{\n\t\t// add Key and Value\n\t\tAddWithHash(key, HashFuncT::Make(key), value);\n\t}\n\n\tvoid AddWithHash(const KeyT &key, tjs_uint32 hash, const ValueT &value)\n\t{\n\t\t// add Key ( hash ) and Value\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\telement *lv1 = Elms + hash % HashSize;\n\t\telement *elm = lv1->Next;\n\t\twhile(elm)\n\t\t{\n\t\t\tif(hash == elm->Hash)\n\t\t\t{\n\t\t\t\t// same ?\n\t\t\t\tif(key == *(KeyT*)elm->Key)\n\t\t\t\t{\n\t\t\t\t\t// do copying instead of inserting if these are same\n\t\t\t\t\tCheckUpdateElementOrder(elm);\n\t\t\t\t\t*(ValueT*)elm->Value = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telm = elm->Next;\n\t\t}\n\n\t\t// lv1 used ?\n\t\tif(!(lv1->Flags & TJS_HS_HASH_USING))\n\t\t{\n\t\t\t// lv1 is unused\n\t\t\tConstruct(*lv1, key, value);\n\t\t\tlv1->Hash = hash;\n\t\t\tlv1->Prev = NULL;\n\t\t\t// not initialize lv1->Next here\n\t\t\tCheckAddingElementOrder(lv1);\n\t\t\treturn;\n\t\t}\n\n\t\t// lv1 is used\n\t\tif(hash == lv1->Hash)\n\t\t{\n\t\t\t// same?\n\t\t\tif(key == *(KeyT*)lv1->Key)\n\t\t\t{\n\t\t\t\t// do copying instead of inserting if these are same\n\t\t\t\tCheckUpdateElementOrder(lv1);\n\t\t\t\t*(ValueT*)lv1->Value = value;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// insert after lv1\n\t\telement *newelm = new element;\n\t\tnewelm->Flags = 0;\n\t\tConstruct(*newelm, key, value);\n\t\tnewelm->Hash = hash;\n\t\tif(lv1->Next) lv1->Next->Prev = newelm;\n\t\tnewelm->Next = lv1->Next;\n\t\tnewelm->Prev = lv1;\n\t\tlv1->Next = newelm;\n\t\tCheckAddingElementOrder(newelm);\n\t}\n\n\n\tValueT * Find(const KeyT &key) const\n\t{\n\t\t// find key\n\t\t// return   NULL  if not found\n\t\tconst element * elm = InternalFindWithHash(key, HashFuncT::Make(key));\n\t\tif(!elm) return NULL;\n\t\treturn (ValueT*)elm->Value;\n\t}\n\n\tbool Find(const KeyT &key, const KeyT *& keyout, ValueT *& value) const\n\t{\n\t\t// find key\n\t\t// return   false  if not found\n\t\treturn FindWithHash(key, HashFuncT::Make(key), keyout, value);\n\t}\n\n\tValueT * FindWithHash(const KeyT &key, tjs_uint32 hash) const\n\t{\n\t\t// find key ( hash )\n\t\t// return   NULL  if not found\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\tconst element * elm = InternalFindWithHash(key, hash);\n\t\tif(!elm) return NULL;\n\t\treturn (ValueT*)elm->Value;\n\t}\n\n\tbool FindWithHash(const KeyT &key, tjs_uint32 hash, const KeyT *& keyout, ValueT *& value) const\n\t{\n\t\t// find key\n\t\t// return   false  if not found\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\tconst element * elm = InternalFindWithHash(key, hash);\n\t\tif(elm)\n\t\t{\n\t\t\tvalue = (ValueT*)elm->Value;\n\t\t\tkeyout = (const KeyT*)elm->Key;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tValueT * FindAndTouch(const KeyT &key)\n\t{\n\t\t// find key and move it first if found\n\t\tconst element * elm = InternalFindWithHash(key, HashFuncT::Make(key));\n\t\tif(!elm) return NULL;\n\t\tCheckUpdateElementOrder((element *)elm);\n\t\treturn (ValueT*)elm->Value;\n\t}\n\n\tbool FindAndTouch(const KeyT &key, const KeyT *& keyout, ValueT *& value)\n\t{\n\t\t// find key ( hash )\n\t\t// return   false  if not found\n\t\treturn FindAndTouchWithHash(key, HashFuncT::Make(key), keyout, value);\n\t}\n\n\n\tValueT * FindAndTouchWithHash(const KeyT &key, tjs_uint32 hash)\n\t{\n\t\t// find key ( hash ) and move it first if found\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\tconst element * elm = InternalFindWithHash(key, hash);\n\t\tif(!elm) return NULL;\n\t\tCheckUpdateElementOrder((element *)elm); // force casting\n\t\treturn (ValueT*)elm->Value;\n\t}\n\n\tbool FindAndTouchWithHash(const KeyT &key, tjs_uint32 hash, const KeyT *& keyout, ValueT *& value)\n\t{\n\t\t// find key\n\t\t// return   false  if not found\n\t\tconst element * elm = InternalFindWithHash(key, hash);\n\t\tif(elm)\n\t\t{\n\t\t\tCheckUpdateElementOrder((element *)elm);\n\t\t\tvalue = (ValueT*)elm->Value;\n\t\t\tkeyout = (const KeyT*)elm->Key;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tbool Delete(const KeyT &key)\n\t{\n\t\t// delete key and return true if successed\n\t\treturn DeleteWithHash(key, HashFuncT::Make(key));\n\t}\n\n\tbool DeleteWithHash(const KeyT &key, tjs_uint32 hash)\n\t{\n\t\t// delete key ( hash ) and return true if succeeded\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\telement *lv1 = Elms + hash % HashSize;\n\t\tif(lv1->Flags & TJS_HS_HASH_USING && hash == lv1->Hash)\n\t\t{\n\t\t\tif(key == *(KeyT*)lv1->Key)\n\t\t\t{\n\t\t\t\t// delete lv1\n\t\t\t\tCheckDeletingElementOrder(lv1);\n\t\t\t\tDestruct(*lv1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\telement *prev = lv1;\n\t\telement *elm = lv1->Next;\n\t\twhile(elm)\n\t\t{\n\t\t\tif(hash == elm->Hash)\n\t\t\t{\n\t\t\t\tif(key == *(KeyT*)elm->Key)\n\t\t\t\t{\n\t\t\t\t\tCheckDeletingElementOrder(elm);\n\t\t\t\t\tDestruct(*elm);\n\t\t\t\t\tprev->Next = elm->Next; // sever from the chain\n\t\t\t\t\tif(elm->Next) elm->Next->Prev = prev;\n\t\t\t\t\tdelete elm;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprev = elm;\n\t\t\telm = elm->Next;\n\t\t}\n\t\treturn false; // not found\n\t}\n\n\ttjs_int ChopLast(tjs_int count)\n\t{\n\t\t// chop items from last of additional order\n\t\ttjs_int ret = 0;\n\t\twhile(count--)\n\t\t{\n\t\t\tif(!NLast) break;\n\t\t\tDeleteByElement(NLast);\n\t\t\tret++;\n\t\t}\n\t\treturn ret;\n\t}\n\n\ttjs_uint GetCount() { return Count; }\n\nprivate:\n\tvoid InternalClear()\n\t{\n\t\tfor(tjs_int i = 0; i < HashSize; i++)\n\t\t{\n\t\t\t// delete all items\n\t\t\telement *elm = Elms[i].Next;\n\t\t\twhile(elm)\n\t\t\t{\n\t\t\t\tDestruct(*elm);\n\t\t\t\telement *elmnext = elm->Next;\n\t\t\t\tdelete elm;\n\t\t\t\telm = elmnext;\n\t\t\t}\n\t\t\tif(Elms[i].Flags & TJS_HS_HASH_USING)\n\t\t\t{\n\t\t\t\tDestruct(Elms[i]);\n\t\t\t}\n\t\t}\n\t\tInternalInit();\n\t}\n\n\tvoid InternalInit()\n\t{\n\t\tCount = 0;\n\t\tNFirst = NULL;\n\t\tNLast = NULL;\n\t\tfor(tjs_int i = 0; i < HashSize; i++)\n\t\t{\n\t\t\tElms[i].Flags = TJS_HS_HASH_LV1;\n\t\t\tElms[i].Prev = NULL;\n\t\t\tElms[i].Next = NULL;\n\t\t}\n\t}\n\n\n\tvoid DeleteByElement(element *elm)\n\t{\n\t\tCheckDeletingElementOrder(elm);\n\t\tDestruct(*elm);\n\t\tif(elm->Flags & TJS_HS_HASH_LV1)\n\t\t{\n\t\t\t// lv1 element\n\t\t\t// nothing to do\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// other elements\n\t\t\tif(elm->Prev) elm->Prev->Next = elm->Next;\n\t\t\tif(elm->Next) elm->Next->Prev = elm->Prev;\n\t\t}\n\t\tif(!(elm->Flags & TJS_HS_HASH_LV1)) delete elm;\n\t}\n\n\tconst element * InternalFindWithHash(const KeyT &key, tjs_uint32 hash) const\n\t{\n\t\t// find key ( hash )\n#ifdef TJS_HS_DEBUG_CHAIN\n\t\thash = 0;\n#endif\n\t\tconst element *lv1 = Elms + hash % HashSize;\n\t\tif(hash == lv1->Hash && lv1->Flags & TJS_HS_HASH_USING)\n\t\t{\n\t\t\tif(key == *(KeyT*)lv1->Key) return lv1;\n\t\t}\n\n\t\telement *elm = lv1->Next;\n\t\twhile(elm)\n\t\t{\n\t\t\tif(hash == elm->Hash)\n\t\t\t{\n\t\t\t\tif(key == *(KeyT*)elm->Key) return elm;\n\t\t\t}\n\t\t\telm = elm->Next;\n\t\t}\n\t\treturn NULL; // not found\n\t}\n\n\n\tvoid CheckAddingElementOrder(element *elm)\n\t{\n\t\tif(Count==0)\n\t\t{\n\t\t\tNLast = elm; // first addition\n\t\t\telm->NNext = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tNFirst->NPrev = elm;\n\t\t\telm->NNext = NFirst;\n\t\t}\n\t\tNFirst = elm;\n\t\telm->NPrev = NULL;\n\t\tCount ++;\n\t}\n\n\tvoid CheckDeletingElementOrder(element *elm)\n\t{\n\t\tCount --;\n\t\tif(Count > 0)\n\t\t{\n\t\t\tif(elm == NFirst)\n\t\t\t{\n\t\t\t\t// deletion of first item\n\t\t\t\tNFirst = elm->NNext;\n\t\t\t\tNFirst->NPrev = NULL;\n\t\t\t}\n\t\t\telse if(elm == NLast)\n\t\t\t{\n\t\t\t\t// deletion of last item\n\t\t\t\tNLast = elm->NPrev;\n\t\t\t\tNLast->NNext = NULL;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// deletion of intermediate item\n\t\t\t\telm->NPrev->NNext = elm->NNext;\n\t\t\t\telm->NNext->NPrev = elm->NPrev;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// when the count becomes zero...\n\t\t\tNFirst = NLast = NULL;\n\t\t}\n\t}\n\n\tvoid CheckUpdateElementOrder(element *elm)\n\t{\n\t\t// move elm to the front of addtional order\n\t\tif(elm != NFirst)\n\t\t{\n\t\t\tif(NLast == elm) NLast = elm->NPrev;\n\t\t\telm->NPrev->NNext = elm->NNext;\n\t\t\tif(elm->NNext) elm->NNext->NPrev = elm->NPrev;\n\t\t\telm->NNext = NFirst;\n\t\t\telm->NPrev = NULL;\n\t\t\tNFirst->NPrev = elm;\n\t\t\tNFirst = elm;\n\t\t}\n\t}\n\n\tstatic void Construct(element &elm, const KeyT &key, const ValueT &value)\n\t{\n\t\t::new (&elm.Key) KeyT(key);\n\t\t::new (&elm.Value) ValueT(value);\n\t\telm.Flags |= TJS_HS_HASH_USING;\n\t}\n\n\tstatic void Destruct(element &elm)\n\t{\n\t\t((KeyT*)(&elm.Key)) -> ~KeyT();\n\t\t((ValueT*)(&elm.Value)) -> ~ValueT();\n\t\telm.Flags &= ~TJS_HS_HASH_USING;\n\t}\n};\n//---------------------------------------------------------------------------\n// tTJSHashCache : cache algorithm via tTJSHashTable\n//---------------------------------------------------------------------------\ntemplate <typename KeyT, typename ValueT, typename HashFuncT = tTJSHashFunc<KeyT>,\n\ttjs_int HashSize = TJS_HS_DEFAULT_HASH_SIZE >\nclass tTJSHashCache : public tTJSHashTable<KeyT, ValueT, HashFuncT, HashSize>\n{\n\ttypedef tTJSHashTable<KeyT, ValueT, HashFuncT, HashSize> inherited;\n\n\ttjs_uint MaxCount;\n\npublic:\n\ttTJSHashCache(tjs_uint maxcount) { MaxCount = maxcount; }\n\n\tvoid Add(const KeyT &key, const ValueT &value)\n\t{\n\t\tinherited::Add(key, value);\n\t\tif (this->GetCount() > MaxCount)\n\t\t{\n\t\t\tthis->ChopLast(this->GetCount() - MaxCount);\n\t\t}\n\t}\n\n\tvoid AddWithHash(const KeyT &key, tjs_uint32 hash, const ValueT &value)\n\t{\n\t\tinherited::AddWithHash(key, hash, value);\n\t\tif (this->GetCount() > MaxCount)\n\t\t{\n\t\t\tthis->ChopLast(this->GetCount() - MaxCount);\n\t\t}\n\t}\n\n\tvoid SetMaxCount(tjs_uint maxcount)\n\t{\n\t\tMaxCount = maxcount;\n\t\tif (this->GetCount() > MaxCount)\n\t\t{\n\t\t\tthis->ChopLast(this->GetCount() - MaxCount);\n\t\t}\n\t}\n\n\ttjs_uint GetMaxCount() { return MaxCount; }\n};\n\n// for std::hash\nstruct ttstr_hasher {\n\ttjs_uint32 operator ()(const ttstr &str) const {\n\t\ttjs_uint32 *hint = const_cast<ttstr*>(&str)->GetHint();\n\t\tif (!hint) return 0;\n\t\tif (*hint) return *hint;\n\t\treturn (*hint = tTJSHashFunc<ttstr>::Make(str));\n\t}\n};\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n//---------------------------------------------------------------------------\n\n#endif\n\n"
  },
  {
    "path": "src/core/tjs2/tjsInterCodeExec.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Intermediate Code Execution\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsInterCodeExec.h\"\n#include \"tjsInterCodeGen.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsError.h\"\n#include \"tjs.h\"\n#include \"tjsUtils.h\"\n#include \"tjsNative.h\"\n#include \"tjsArray.h\"\n#include \"tjsDebug.h\"\n#include \"tjsOctPack.h\"\n#include \"tjsGlobalStringMap.h\"\n#include <set>\n#include <mutex>\n\n#ifdef ENABLE_DEBUGGER\n#include \"debugger.h\"\nstatic bool isDebuggerPresent() {\n\treturn true;\n}\n#define IsDebuggerPresent isDebuggerPresent\n#endif // ENABLE_DEBUGGER\n#include <thread>\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// utility functions\n//---------------------------------------------------------------------------\nstatic void ThrowFrom_tjs_error_num(tjs_error hr, tjs_int num)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\tTJSThrowFrom_tjs_error(hr, buf);\n}\n//---------------------------------------------------------------------------\nstatic void ThrowInvalidVMCode()\n{\n\tTJS_eTJSError(TJSInvalidOpecode);\n}\n//---------------------------------------------------------------------------\nstatic void GetStringProperty(tTJSVariant *result, const tTJSVariant *str,\n\tconst tTJSVariant &member)\n{\n\t// processes properties toward strings.\n\tif(member.Type() != tvtInteger && member.Type() != tvtReal)\n\t{\n\t\tconst tjs_char *name = member.GetString();\n\t\tif(!name) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\n\t\tif(!TJS_strcmp(name, TJS_W(\"length\")))\n\t\t{\n\t\t\t// get string length\n\t\t\tconst tTJSVariantString * s = str->AsStringNoAddRef();\n#ifdef __CODEGUARD__\n\t\t\tif(!s)\n\t\t\t\t*result = tTVInteger(0); // tTJSVariantString::GetLength can return zero if 'this' is NULL\n\t\t\telse\n#endif\n\t\t\t*result = tTVInteger(s->GetLength());\n\t\t\treturn;\n\t\t}\n\t\telse if(name[0] >= TJS_W('0') && name[0] <= TJS_W('9'))\n\t\t{\n\t\t\tconst tTJSVariantString * valstr = str->AsStringNoAddRef();\n\t\t\tconst tjs_char *s = str->GetString();\n\t\t\ttjs_int n = TJS_atoi(name);\n\t\t\ttjs_int len = valstr->GetLength();\n\t\t\tif(n == len) { *result = tTJSVariant(TJS_W(\"\")); return; }\n\t\t\tif(n<0 || n>len)\n\t\t\t\tTJS_eTJSError(TJSRangeError);\n\t\t\ttjs_char bf[2];\n\t\t\tbf[1] = 0;\n\t\t\tbf[0] = s[n];\n\t\t\t*result = tTJSVariant(bf);\n\t\t\treturn;\n\t\t}\n\n\t\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, name);\n\t}\n\telse // member.Type() == tvtInteger || member.Type() == tvtReal\n\t{\n\t\tconst tTJSVariantString * valstr = str->AsStringNoAddRef();\n\t\tconst tjs_char *s = str->GetString();\n\t\ttjs_int n = (tjs_int)member.AsInteger();\n\t\ttjs_int len = valstr->GetLength();\n\t\tif(n == len) { *result = tTJSVariant(TJS_W(\"\")); return; }\n\t\tif(n<0 || n>len)\n\t\t\tTJS_eTJSError(TJSRangeError);\n\t\ttjs_char bf[2];\n\t\tbf[1] = 0;\n\t\tbf[0] = s[n];\n\t\t*result = tTJSVariant(bf);\n\t\treturn;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void SetStringProperty(tTJSVariant *param, const tTJSVariant *str,\n\tconst tTJSVariant &member)\n{\n\t// processes properties toward strings.\n\tif(member.Type() != tvtInteger && member.Type() != tvtReal)\n\t{\n\t\tconst tjs_char *name = member.GetString();\n\t\tif(!name) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\n\t\tif(!TJS_strcmp(name, TJS_W(\"length\")))\n\t\t{\n\t\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t\t}\n\t\telse if(name[0] >= TJS_W('0') && name[0] <= TJS_W('9'))\n\t\t{\n\t\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t\t}\n\n\t\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, name);\n\t}\n\telse // member.Type() == tvtInteger || member.Type() == tvtReal\n\t{\n\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void GetOctetProperty(tTJSVariant *result, const tTJSVariant *octet,\n\tconst tTJSVariant &member)\n{\n\t// processes properties toward octets.\n\tif(member.Type() != tvtInteger && member.Type() != tvtReal)\n\t{\n\t\tconst tjs_char *name = member.GetString();\n\t\tif(!name) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\n\t\tif(!TJS_strcmp(name, TJS_W(\"length\")))\n\t\t{\n\t\t\t// get string length\n\t\t\ttTJSVariantOctet *o = octet->AsOctetNoAddRef();\n\t\t\tif(o)\n\t\t\t\t*result = tTVInteger(o->GetLength());\n\t\t\telse\n\t\t\t\t*result = tTVInteger(0);\n\t\t\treturn;\n\t\t}\n\t\telse if(name[0] >= TJS_W('0') && name[0] <= TJS_W('9'))\n\t\t{\n\t\t\ttTJSVariantOctet *o = octet->AsOctetNoAddRef();\n\t\t\ttjs_int n = TJS_atoi(name);\n\t\t\ttjs_int len = o?o->GetLength():0;\n\t\t\tif(n<0 || n>=len)\n\t\t\t\tTJS_eTJSError(TJSRangeError);\n\t\t\t*result = tTVInteger(o->GetData()[n]);\n\t\t\treturn;\n\t\t}\n\n\t\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, name);\n\t}\n\telse // member.Type() == tvtInteger || member.Type() == tvtReal\n\t{\n\t\ttTJSVariantOctet *o = octet->AsOctetNoAddRef();\n\t\ttjs_int n = (tjs_int)member.AsInteger();\n\t\ttjs_int len = o?o->GetLength():0;\n\t\tif(n<0 || n>=len)\n\t\t\tTJS_eTJSError(TJSRangeError);\n\t\t*result = tTVInteger(o->GetData()[n]);\n\t\treturn;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void SetOctetProperty(tTJSVariant *param, const tTJSVariant *octet,\n\tconst tTJSVariant &member)\n{\n\t// processes properties toward octets.\n\tif(member.Type() != tvtInteger && member.Type() != tvtReal)\n\t{\n\t\tconst tjs_char *name = member.GetString();\n\t\tif(!name) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\n\t\tif(!TJS_strcmp(name, TJS_W(\"length\")))\n\t\t{\n\t\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t\t}\n\t\telse if(name[0] >= TJS_W('0') && name[0] <= TJS_W('9'))\n\t\t{\n\t\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t\t}\n\n\t\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, name);\n\t}\n\telse // member.Type() == tvtInteger || member.Type() == tvtReal\n\t{\n\t\tTJSThrowFrom_tjs_error(TJS_E_ACCESSDENYED, TJS_W(\"\"));\n\t}\n}\n\n//---------------------------------------------------------------------------\n// tTJSObjectProxy\n//---------------------------------------------------------------------------\nclass tTJSObjectProxy : public iTJSDispatch2\n{\n/*\n\ta class that do:\n\t1. first access to the Dispatch1\n\t2. if failed, then access to the Dispatch2\n*/\n//\ttjs_uint RefCount;\n\npublic:\n\ttTJSObjectProxy()\n\t{\n//\t\tRefCount = 1;\n//\t\tDispatch1 = NULL;\n//\t\tDispatch2 = NULL;\n\t\t// Dispatch1 and Dispatch2 are to be set by subsequent call of SetObjects\n\t};\n\n\tvirtual ~tTJSObjectProxy()\n\t{\n\t\tif(Dispatch1) Dispatch1->Release();\n\t\tif(Dispatch2) Dispatch2->Release();\n\t};\n\n\tvoid SetObjects(iTJSDispatch2 *dsp1, iTJSDispatch2 *dsp2)\n\t{\n\t\tDispatch1 = dsp1;\n\t\tDispatch2 = dsp2;\n\t\tif(dsp1) dsp1->AddRef();\n\t\tif(dsp2) dsp2->AddRef();\n\t}\n\nprivate:\n\tiTJSDispatch2 *Dispatch1;\n\tiTJSDispatch2 *Dispatch2;\n\npublic:\n\n\ttjs_uint TJS_INTF_METHOD  AddRef(void)\n\t{\n\t\treturn 1;\n//\t\treturn ++RefCount;\n\t}\n\n\ttjs_uint TJS_INTF_METHOD  Release(void)\n\t{\n\t\treturn 1;\n/*\n\t\tif(RefCount == 1)\n\t\t{\n\t\t\tdelete this;\n\t\t\treturn 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tRefCount--;\n\t\t}\n\t\treturn RefCount;\n*/\n\t}\n\n//--\n#define OBJ1 ((objthis)?(objthis):(Dispatch1))\n#define OBJ2 ((objthis)?(objthis):(Dispatch2))\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->FuncCall(flag, membername, hint, result, numparams, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->FuncCall(flag, membername, hint, result, numparams, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCallByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->FuncCallByNum(flag, num, result, numparams, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->FuncCallByNum(flag, num, result, numparams, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->PropGet(flag, membername, hint, result, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->PropGet(flag, membername, hint, result, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGetByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->PropGetByNum(flag, num, result, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->PropGetByNum(flag, num, result, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->PropSet(flag, membername, hint, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->PropSet(flag, membername, hint, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByNum(tjs_uint32 flag, tjs_int num, const tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->PropSetByNum(flag, num, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->PropSetByNum(flag, num, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tGetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->GetCount(result, membername, hint, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->GetCount(result, membername, hint, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tGetCountByNum(tjs_int *result, tjs_int num, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->GetCountByNum(result, num, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->GetCountByNum(result, num, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->PropSetByVS(flag, membername, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->PropSetByVS(flag, membername, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tEnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback, iTJSDispatch2 *objthis)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->DeleteMember(flag, membername, hint, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->DeleteMember(flag, membername, hint, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMemberByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->DeleteMemberByNum(flag, num, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->DeleteMemberByNum(flag, num, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->Invalidate(flag, membername, hint, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->Invalidate(flag, membername, hint, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidateByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->InvalidateByNum(flag, num, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->InvalidateByNum(flag, num, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->IsValid(flag, membername, hint, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->IsValid(flag, membername, hint, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValidByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->IsValidByNum(flag, num, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->IsValidByNum(flag, num, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\tiTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->CreateNew(flag, membername, hint, result, numparams, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->CreateNew(flag, membername, hint, result, numparams, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNewByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->CreateNewByNum(flag, num, result, numparams, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->CreateNewByNum(flag, num, result, numparams, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved1()\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->IsInstanceOf(flag, membername, hint, classname, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->IsInstanceOf(flag, membername, hint, classname, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOfByNum(tjs_uint32 flag, tjs_int num, const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->IsInstanceOfByNum(flag, num, classname, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->IsInstanceOfByNum(flag, num, classname, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->Operation(flag, membername, hint, result, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->Operation(flag, membername, hint, result, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tOperationByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis)\n\t{\n\t\ttjs_error hr =\n\t\t\tDispatch1->OperationByNum(flag, num, result, param, OBJ1);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && Dispatch1 != Dispatch2)\n\t\t\treturn Dispatch2->OperationByNum(flag, num, result, param, OBJ2);\n\t\treturn hr;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tNativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid,\n\t\tiTJSNativeInstance **pointer)  { return TJS_E_NOTIMPL; }\n\n\ttjs_error TJS_INTF_METHOD\n\tClassInstanceInfo(tjs_uint32 flag, tjs_uint num, tTJSVariant *value)\n\t\t{ return TJS_E_NOTIMPL;\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved2()\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved3()\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n};\n#undef OBJ1\n#undef OBJ2\n\n//---------------------------------------------------------------------------\n// tTJSVariantArrayStack\n//---------------------------------------------------------------------------\n// TODO: adjust TJS_VA_ONE_ALLOC_MIN\n#define TJS_VA_ONE_ALLOC_MAX 1024\n#define TJS_COMPACT_FREQ 10000\nstatic tjs_int TJSCompactVariantArrayMagic = 0;\nstatic std::mutex TJSVariantArrayStackMutex;\nstatic std::set<tTJSVariantArrayStack*> TJSVariantArrayStacks;\n//---------------------------------------------------------------------------\ntTJSVariantArrayStack::tTJSVariantArrayStack()\n{\n\tNumArraysAllocated = NumArraysUsing = 0;\n\tArrays = NULL;\n\tCurrent = NULL;\n\tOperationDisabledCount = 0;\n\tCompactVariantArrayMagic = TJSCompactVariantArrayMagic;\n\tstd::lock_guard<std::mutex> lk(TJSVariantArrayStackMutex);\n\tTJSVariantArrayStacks.insert(this);\n}\n//---------------------------------------------------------------------------\ntTJSVariantArrayStack::~tTJSVariantArrayStack()\n{\n\tOperationDisabledCount++;\n\ttjs_int i;\n\tfor(i = 0; i<NumArraysAllocated; i++)\n\t{\n\t\tdelete [] Arrays[i].Array;\n\t}\n\tTJS_free(Arrays), Arrays = NULL;\n\tstd::lock_guard<std::mutex> lk(TJSVariantArrayStackMutex);\n\tTJSVariantArrayStacks.erase(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariantArrayStack::IncreaseVariantArray(tjs_int num)\n{\n\t// increase array block\n\tNumArraysUsing++;\n\tif(NumArraysUsing > NumArraysAllocated)\n\t{\n\t\tArrays = (tVariantArray*)\n\t\t\tTJS_realloc(Arrays, sizeof(tVariantArray)*(NumArraysUsing));\n\t\tNumArraysAllocated = NumArraysUsing;\n\t\tCurrent = Arrays + NumArraysUsing -1;\n\t\tCurrent->Array = new tTJSVariant[num];\n\t}\n\telse\n\t{\n\t\tCurrent = Arrays + NumArraysUsing -1;\n\t}\n\n\tCurrent->Allocated = num;\n\tCurrent->Using = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariantArrayStack::DecreaseVariantArray(void)\n{\n\t// decrease array block\n\tNumArraysUsing--;\n\tif(NumArraysUsing == 0)\n\t\tCurrent = NULL;\n\telse\n\t\tCurrent = Arrays + NumArraysUsing-1;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariantArrayStack::InternalCompact(void)\n{\n\t// minimize variant array block\n\tOperationDisabledCount++;\n\ttry\n\t{\n\t\twhile(NumArraysAllocated > NumArraysUsing)\n\t\t{\n\t\t\tNumArraysAllocated --;\n\t\t\tdelete [] Arrays[NumArraysAllocated].Array;\n\t\t}\n\n\t\tif(Current)\n\t\t{\n\t\t\tfor(tjs_int i = Current->Using; i < Current->Allocated; i++)\n\t\t\t\tCurrent->Array[i].Clear();\n\t\t}\n\n\t\tif(NumArraysUsing == 0)\n\t\t{\n\t\t\tif(Arrays) TJS_free(Arrays), Arrays = NULL;\n\t\t\tCurrent = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool availableoffset = false;\n\t\t\tsize_t offset = 0;\n\t\t\tif( Current != NULL && Arrays != NULL ) {\n\t\t\t\toffset = (size_t)Current - (size_t)Arrays;\n\t\t\t\tavailableoffset = true;\n\t\t\t}\n\n\t\t\ttVariantArray* arraytmp = (tVariantArray*)\n\t\t\t\tTJS_realloc(Arrays, sizeof(tVariantArray)*(NumArraysUsing));\n\t\t\tif( arraytmp != NULL ) {\n\t\t\t\tArrays = arraytmp;\n\t\t\t} else if( NumArraysUsing > 0 ) {\n\t\t\t\tTJS_eTJSError(TJSInternalError);\n\t\t\t}\n\n\t\t\tif( availableoffset && Arrays != NULL ) {\n\t\t\t\tCurrent = Arrays + offset;\n\t\t\t} else {\n\t\t\t\tCurrent = NULL;\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tOperationDisabledCount--;\n\t\tthrow;\n\t}\n\tOperationDisabledCount--;\n}\n//---------------------------------------------------------------------------\ninline tTJSVariant * tTJSVariantArrayStack::Allocate(tjs_int num)\n{\n//\t\ttTJSCSH csh(CS);\n\n\tif(!OperationDisabledCount && num < TJS_VA_ONE_ALLOC_MAX)\n\t{\n\t\tif(!Current || Current->Using + num > Current->Allocated)\n\t\t{\n\t\t\tIncreaseVariantArray( TJS_VA_ONE_ALLOC_MAX );\n\t\t}\n\t\ttTJSVariant *ret = Current->Array + Current->Using;\n\t\tCurrent->Using += num;\n\t\treturn ret;\n\t}\n\telse\n\t{\n\t\treturn new tTJSVariant[num];\n\t}\n}\n//---------------------------------------------------------------------------\ninline void tTJSVariantArrayStack::Deallocate(tjs_int num, tTJSVariant *ptr)\n{\n//\t\ttTJSCSH csh(CS);\n\n\tif(!OperationDisabledCount && num < TJS_VA_ONE_ALLOC_MAX)\n\t{\n\t\tCurrent->Using -= num;\n\t\tif(Current->Using == 0)\n\t\t{\n\t\t\tDecreaseVariantArray();\n\t\t}\n\t}\n\telse\n\t{\n\t\tdelete [] ptr;\n\t}\n\n\tif(!OperationDisabledCount)\n\t{\n\t\tif(CompactVariantArrayMagic != TJSCompactVariantArrayMagic)\n\t\t{\n\t\t\tCompact();\n\t\t\tCompactVariantArrayMagic = TJSCompactVariantArrayMagic;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n//static tjs_int TJSVariantArrayStackRefCount = 0;\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::TJSVariantArrayStackAddRef()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::TJSVariantArrayStackRelease()\n{\n}\n//---------------------------------------------------------------------------\nvoid TJSVariantArrayStackCompact()\n{\n\tTJSCompactVariantArrayMagic++;\n}\n//---------------------------------------------------------------------------\nvoid TJSVariantArrayStackCompactNow()\n{\n#if 0 // due to multi-thread\n\tfor (tTJSVariantArrayStack* stk : TJSVariantArrayStacks) {\n\t\tstk->Compact();\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSInterCodeContext ( class definitions are in tjsInterCodeGen.h )\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExecuteAsFunction(iTJSDispatch2 *objthis,\n\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result, tjs_int start_ip)\n{\n\ttjs_int num_alloc = MaxVariableCount + VariableReserveCount + 1 + MaxFrameCount;\n\tTJSVariantArrayStackAddRef();\n//\tAddRef();\n//\tif(objthis) objthis->AddRef();\n\ttry\n\t{\n\t\ttTJSVariant *regs =\n\t\t\tTJSVariantArrayStack->Allocate(num_alloc);\n\t\ttTJSVariant *ra = regs + MaxVariableCount + VariableReserveCount; // register area\n\n\t\t// objthis-proxy\n\n\t\ttTJSObjectProxy proxy;\n\t\tif(objthis)\n\t\t{\n\t\t\tproxy.SetObjects(objthis, Block->GetTJS()->GetGlobalNoAddRef());\n\t\t\t// TODO: caching of objthis-proxy\n\n\t\t\tra[-2] = &proxy;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tproxy.SetObjects(NULL, NULL);\n\n\t\t\tiTJSDispatch2 *global = Block->GetTJS()->GetGlobalNoAddRef();\n\n\t\t\tra[-2].SetObject(global, global);\n\t\t}\n\n/*\n\t\tif(objthis)\n\t\t{\n\t\t\t// TODO: caching of objthis-proxy\n\t\t\ttTJSObjectProxy *proxy = new tTJSObjectProxy();\n\t\t\tproxy->SetObjects(objthis, Block->GetTJS()->GetGlobalNoAddRef());\n\n\t\t\tra[-2] = proxy;\n\n\t\t\tproxy->Release();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tiTJSDispatch2 *global = Block->GetTJS()->GetGlobalNoAddRef();\n\n\t\t\tra[-2].SetObject(global, global);\n\t\t}\n*/\n\t\tif(TJSStackTracerEnabled()) TJSStackTracerPush(this, false);\n\n\t\t// check whether the objthis is deleting\n\t\tif(TJSWarnOnExecutionOnDeletingObject && TJSObjectFlagEnabled() &&\n\t\t\tBlock->GetTJS()->GetConsoleOutput())\n\t\t\tTJSWarnIfObjectIsDeleting(Block->GetTJS()->GetConsoleOutput(), objthis);\n\n#ifdef ENABLE_DEBUGGER\n\t\tScopeKey oldkey;\n\t\ttTJSVariant* oldra = NULL;\n#endif\t// ENABLE_DEBUGGER\n\t\ttry\n\t\t{\n\t\t\tra[-1].SetObject(objthis, objthis);\n\t\t\tra[0].Clear();\n\n\t\t\t// transfer arguments\n\t\t\tif(numargs >= FuncDeclArgCount)\n\t\t\t{\n\t\t\t\t// given arguments are greater than or equal to desired arguments\n\t\t\t\tif(FuncDeclArgCount)\n\t\t\t\t{\n\t\t\t\t\ttTJSVariant *r = ra - 3;\n\t\t\t\t\ttTJSVariant **a = args;\n\t\t\t\t\ttjs_int n = FuncDeclArgCount;\n\t\t\t\t\twhile(true)\n\t\t\t\t\t{\n\t\t\t\t\t\t*r = **(a++);\n\t\t\t\t\t\tn--;\n\t\t\t\t\t\tif(!n) break;\n\t\t\t\t\t\tr--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// given arguments are less than desired arguments\n\t\t\t\ttTJSVariant *r = ra - 3;\n\t\t\t\ttTJSVariant **a = args;\n\t\t\t\ttjs_int i;\n\t\t\t\tfor(i = 0; i<numargs; i++) *(r--) = **(a++);\n\t\t\t\tfor(; i<FuncDeclArgCount; i++) (r--)->Clear();\n\t\t\t}\n\n\t\t\t// collapse into array when FuncDeclCollapseBase >= 0\n\t\t\tif(FuncDeclCollapseBase >= 0)\n\t\t\t{\n\t\t\t\ttTJSVariant *r = ra - 3 - FuncDeclCollapseBase; // target variant\n\t\t\t\tiTJSDispatch2 * dsp = TJSCreateArrayObject();\n\t\t\t\t*r = tTJSVariant(dsp, dsp);\n\t\t\t\tdsp->Release();\n\n\t\t\t\tif(numargs > FuncDeclCollapseBase)\n\t\t\t\t{\n\t\t\t\t\t// there are arguments to store\n\t\t\t\t\tfor(tjs_int c = 0, i = FuncDeclCollapseBase; i < numargs; i++, c++)\n\t\t\t\t\t\tdsp->PropSetByNum(0, c, args[i], dsp);\n\t\t\t\t}\n\t\t\t}\n\n#ifdef ENABLE_DEBUGGER\n\t\t\tif( TJSEnableDebugMode && ::IsDebuggerPresent() ) {\n\t\t\t\ttjs_int ine_no = Block->SrcPosToLine( CodePosToSrcPos(start_ip) );\n\t\t\t\tTJSDebuggerHook( DBGHOOK_PREV_CALL, Block->GetName(), ine_no );\n\t\t\t}\n\t\t\toldkey = DebuggerScopeKey;\n\t\t\toldra = DebuggerRegisterArea;\n\t\t\tTJSDebuggerGetScopeKey( DebuggerScopeKey, GetClassName().c_str(), GetName(), Block->GetName(), start_ip );\n\t\t\tDebuggerRegisterArea = ra;\n#endif\t// ENABLE_DEBUGGER\n\t\t\t// execute\n\t\t\tExecuteCode(ra, start_ip, args, numargs, result);\n\t\t}\n\t\tcatch(...)\n\t\t{\n#ifdef ENABLE_DEBUGGER\n\t\t\t// ɖ߂\n\t\t\tDebuggerScopeKey = oldkey;\n\t\t\tDebuggerRegisterArea = oldra;\n#endif\t// ENABLE_DEBUGGER\n#if 0\n\t\t\tfor(tjs_int i=0; i<num_alloc; i++) regs[i].Clear();\n#endif\n\t\t\tra[-2].Clear(); // at least we must clear the object placed at local stack\n\t\t\tTJSVariantArrayStack->Deallocate(num_alloc, regs);\n\t\t\tif(TJSStackTracerEnabled()) TJSStackTracerPop();\n\t\t\tthrow;\n\t\t}\n\n#ifdef ENABLE_DEBUGGER\n\t\t// ɖ߂\n\t\tDebuggerScopeKey = oldkey;\n\t\tDebuggerRegisterArea = oldra;\n#endif\t// ENABLE_DEBUGGER\n#if 0\n\t\tfor(tjs_int i=0; i<MaxVariableCount + VariableReserveCount; i++)\n\t\t\tregs[i].Clear();\n#endif\n\t\tra[-2].Clear(); // at least we must clear the object placed at local stack\n\n\t\tTJSVariantArrayStack->Deallocate(num_alloc, regs);\n\n\t\tif(TJSStackTracerEnabled()) TJSStackTracerPop();\n\t}\n\tcatch(...)\n\t{\n//\t\tif(objthis) objthis->Release();\n//\t\tRelease();\n\t\tTJSVariantArrayStackRelease();\n\t\tthrow;\n\t}\n//\tif(objthis) objthis->Release();\n//\tRelease();\n\tTJSVariantArrayStackRelease();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DisplayExceptionGeneratedCode(tjs_int codepos,\n\tconst tTJSVariant *ra)\n{\n\ttTJS *tjs = Block->GetTJS();\n\tttstr info(\n\t\tTJS_W(\"==== An exception occured at \") +\n\t\tGetPositionDescriptionString(codepos) +\n\t\tTJS_W(\", VM ip = \") + ttstr(codepos) + TJS_W(\" ====\"));\n\ttjs_int info_len = info.GetLen();\n\n\ttjs->OutputToConsole(info.c_str());\n\ttjs->OutputToConsole(TJS_W(\"-- Disassembled VM code --\"));\n\tDisassembleSrcLine(codepos);\n\n\ttjs->OutputToConsole(TJS_W(\"-- Register dump --\"));\n\n\tconst tTJSVariant *ra_start = ra - (MaxVariableCount + VariableReserveCount);\n\ttjs_int ra_count = MaxVariableCount + VariableReserveCount + 1 + MaxFrameCount;\n\tttstr line;\n\tfor(tjs_int i = 0; i < ra_count; i ++)\n\t{\n\t\tttstr reg_info = TJS_W(\"%\") + ttstr(i - (MaxVariableCount + VariableReserveCount))\n\t\t\t+ TJS_W(\"=\") + TJSVariantToReadableString(ra_start[i]);\n\t\tif(line.GetLen() + reg_info.GetLen() + 2 > info_len)\n\t\t{\n\t\t\ttjs->OutputToConsole(line.c_str());\n\t\t\tline = reg_info;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!line.IsEmpty()) line += TJS_W(\"  \");\n\t\t\tline += reg_info;\n\t\t}\n\t}\n\n\tif(!line.IsEmpty())\n\t{\n\t\ttjs->OutputToConsole(line.c_str());\n\t}\n\n\ttjs->OutputToConsoleSeparator(TJS_W(\"-\"), info_len);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ThrowScriptException(tTJSVariant &val,\n\ttTJSScriptBlock *block, tjs_int srcpos)\n{\n\ttTJSString msg;\n\tif(val.Type() == tvtObject)\n\t{\n\t\ttry\n\t\t{\n\t\t\ttTJSVariantClosure clo = val.AsObjectClosureNoAddRef();\n\t\t\tif(clo.Object != NULL)\n\t\t\t{\n\t\t\t\ttTJSVariant v2;\n\t\t\t\tstatic tTJSString message_name(TJS_W(\"message\"));\n\t\t\t\ttjs_error hr = clo.PropGet(0, message_name.c_str(),\n\t\t\t\t\tmessage_name.GetHint(), &v2, NULL);\n\t\t\t\tif(TJS_SUCCEEDED(hr))\n\t\t\t\t{\n\t\t\t\t\tmsg = ttstr(TJS_W(\"script exception : \")) + ttstr(v2);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t}\n\t}\n\n\tif(msg.IsEmpty())\n\t{\n\t\tmsg = TJS_W(\"script exception\");\n\t}\n\n\tTJS_eTJSScriptException(msg, this, srcpos, val);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::ExecuteCode(tTJSVariant *ra_org, tjs_int startip,\n\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result)\n{\n\t// execute VM codes\n\ttjs_int32 *codesave;\n\ttry\n\t{\n\t\ttjs_int32 *code = codesave = CodeArea + startip;\n\n\t\tif(TJSStackTracerEnabled()) TJSStackTracerSetCodePointer(CodeArea, &codesave);\n#ifdef ENABLE_DEBUGGER\n\t\tbool is_enable_debugger = false;\n\t\tif( TJSEnableDebugMode && ::IsDebuggerPresent() ) {\n\t\t\tis_enable_debugger = true;\n\t\t}\n#endif\t// ENABLE_DEBUGGER\n\n\t\ttTJSVariant *ra = ra_org;\n\t\ttTJSVariant *da = DataArea;\n\n\t\tbool flag = false;\n\n#ifdef ENABLE_DEBUGGER\n\t\ttjs_int cur_line_no = -1;\n#endif\t// ENABLE_DEBUGGER\n\t\twhile(true)\n\t\t{\n#ifdef ENABLE_DEBUGGER\n\t\t\tif( is_enable_debugger ) {\n\t\t\t\ttjs_int next_line_no = Block->SrcPosToLine( CodePosToSrcPos(code-CodeArea) );\n\t\t\t\tif( cur_line_no != next_line_no ) {\n\t\t\t\t\tcur_line_no = next_line_no;\n\t\t\t\t\tTJSDebuggerHook( DBGHOOK_PREV_EXE_LINE, Block->GetName(), cur_line_no, this );\n\t\t\t\t}\n\t\t\t}\n#endif\t// ENABLE_DEBUGGER\n\t\t\tcodesave = code;\n\t\t\tswitch(*code)\n\t\t\t{\n\t\t\tcase VM_NOP:\n\t\t\t\tcode ++;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CONST:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).CopyRef(TJS_GET_VM_REG(da, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CP:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).CopyRef(TJS_GET_VM_REG(ra, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CL:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).Clear();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CCL:\n\t\t\t\tContinuousClear(ra, code);\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_TT:\n\t\t\t\tflag = TJS_GET_VM_REG(ra, code[1]).operator bool();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_TF:\n\t\t\t\tflag = !(TJS_GET_VM_REG(ra, code[1]).operator bool());\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CEQ:\n\t\t\t\tflag = TJS_GET_VM_REG(ra, code[1]).NormalCompare(\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CDEQ:\n\t\t\t\tflag = TJS_GET_VM_REG(ra, code[1]).DiscernCompare(\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CLT:\n\t\t\t\tflag = TJS_GET_VM_REG(ra, code[1]).GreaterThan(\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CGT:\n\t\t\t\tflag = TJS_GET_VM_REG(ra, code[1]).LittlerThan(\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[2]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SETF:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = flag;\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SETNF:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = !flag;\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_LNOT:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).logicalnot();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_NF:\n\t\t\t\tflag = !flag;\n\t\t\t\tcode ++;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_JF:\n\t\t\t\tif(flag)\n\t\t\t\t\tTJS_ADD_VM_CODE_ADDR(code, code[1]);\n\t\t\t\telse\n\t\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_JNF:\n\t\t\t\tif(!flag)\n\t\t\t\t\tTJS_ADD_VM_CODE_ADDR(code, code[1]);\n\t\t\t\telse\n\t\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_JMP:\n\t\t\t\tTJS_ADD_VM_CODE_ADDR(code, code[1]);\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INC:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).increment();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INCPD:\n\t\t\t\tOperatePropertyDirect0(ra, code, TJS_OP_INC);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INCPI:\n\t\t\t\tOperatePropertyIndirect0(ra, code, TJS_OP_INC);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INCP:\n\t\t\t\tOperateProperty0(ra, code, TJS_OP_INC);\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DEC:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).decrement();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DECPD:\n\t\t\t\tOperatePropertyDirect0(ra, code, TJS_OP_DEC);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DECPI:\n\t\t\t\tOperatePropertyIndirect0(ra, code, TJS_OP_DEC);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DECP:\n\t\t\t\tOperateProperty0(ra, code, TJS_OP_DEC);\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n#define TJS_DEF_VM_P(vmcode, rope) \\\n\t\t\tcase VM_##vmcode: \\\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).rope(TJS_GET_VM_REG(ra, code[2])); \\\n\t\t\t\tcode += 3; \\\n\t\t\t\tbreak; \\\n\t\t\tcase VM_##vmcode##PD: \\\n\t\t\t\tOperatePropertyDirect(ra, code, TJS_OP_##vmcode); \\\n\t\t\t\tcode += 5; \\\n\t\t\t\tbreak; \\\n\t\t\tcase VM_##vmcode##PI: \\\n\t\t\t\tOperatePropertyIndirect(ra, code, TJS_OP_##vmcode); \\\n\t\t\t\tcode += 5; \\\n\t\t\t\tbreak; \\\n\t\t\tcase VM_##vmcode##P: \\\n\t\t\t\tOperateProperty(ra, code, TJS_OP_##vmcode); \\\n\t\t\t\tcode += 4; \\\n\t\t\t\tbreak\n\n\t\t\t\tTJS_DEF_VM_P(LOR, logicalorequal);\n\t\t\t\tTJS_DEF_VM_P(LAND, logicalandequal);\n\t\t\t\tTJS_DEF_VM_P(BOR, operator |=);\n\t\t\t\tTJS_DEF_VM_P(BXOR, operator ^=);\n\t\t\t\tTJS_DEF_VM_P(BAND, operator &=);\n\t\t\t\tTJS_DEF_VM_P(SAR, operator >>=);\n\t\t\t\tTJS_DEF_VM_P(SAL, operator <<=);\n\t\t\t\tTJS_DEF_VM_P(SR, rbitshiftequal);\n\t\t\t\tTJS_DEF_VM_P(ADD, operator +=);\n\t\t\t\tTJS_DEF_VM_P(SUB, operator -=);\n\t\t\t\tTJS_DEF_VM_P(MOD, operator %=);\n\t\t\t\tTJS_DEF_VM_P(DIV, operator /=);\n\t\t\t\tTJS_DEF_VM_P(IDIV, idivequal);\n\t\t\t\tTJS_DEF_VM_P(MUL, operator *=);\n\n#undef TJS_DEF_VM_P\n\n\t\t\tcase VM_BNOT:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).bitnot();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_ASC:\n\t\t\t\tCharacterCodeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CHR:\n\t\t\t\tCharacterCodeFrom(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_NUM:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).tonumber();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CHS:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).changesign();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INV:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) =\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[1]).Type() != tvtObject ? false :\n\t\t\t\t\t(TJS_GET_VM_REG(ra, code[1]).AsObjectClosureNoAddRef().Invalidate(0,\n\t\t\t\t\tNULL, NULL, ra[-1].AsObjectNoAddRef()) == TJS_S_TRUE);\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CHKINV:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) =\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[1]).Type() != tvtObject ? true :\n\t\t\t\t\tTJSIsObjectValid(TJS_GET_VM_REG(ra, code[1]).AsObjectClosureNoAddRef().IsValid(0,\n\t\t\t\t\tNULL, NULL, ra[-1].AsObjectNoAddRef()));\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_INT:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).ToInteger();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_REAL:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).ToReal();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_STR:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).ToString();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_OCTET:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).ToOctet();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_TYPEOF:\n\t\t\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_TYPEOFD:\n\t\t\t\tTypeOfMemberDirect(ra, code, TJS_MEMBERMUSTEXIST);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_TYPEOFI:\n\t\t\t\tTypeOfMemberIndirect(ra, code, TJS_MEMBERMUSTEXIST);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_EVAL:\n\t\t\t\tEval(TJS_GET_VM_REG(ra, code[1]),\n\t\t\t\t\tTJSEvalOperatorIsOnGlobal ? NULL : ra[-1].AsObjectNoAddRef(),\n\t\t\t\t\ttrue);\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_EEXP:\n\t\t\t\tEval(TJS_GET_VM_REG(ra, code[1]),\n\t\t\t\t\tTJSEvalOperatorIsOnGlobal ? NULL : ra[-1].AsObjectNoAddRef(),\n\t\t\t\t\tfalse);\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CHKINS:\n\t\t\t\tInstanceOf(TJS_GET_VM_REG(ra, code[2]),\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[1]));\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CALL:\n\t\t\tcase VM_NEW:\n\t\t\t\tcode += CallFunction(ra, code, args, numargs);\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CALLD:\n\t\t\t\tcode += CallFunctionDirect(ra, code, args, numargs);\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CALLI:\n\t\t\t\tcode += CallFunctionIndirect(ra, code, args, numargs);\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GPD:\n\t\t\t\tGetPropertyDirect(ra, code, 0);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GPDS:\n\t\t\t\tGetPropertyDirect(ra, code, TJS_IGNOREPROP);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPD:\n\t\t\t\tSetPropertyDirect(ra, code, 0);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPDE:\n\t\t\t\tSetPropertyDirect(ra, code, TJS_MEMBERENSURE);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPDEH:\n\t\t\t\tSetPropertyDirect(ra, code, TJS_MEMBERENSURE|TJS_HIDDENMEMBER);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPDS:\n\t\t\t\tSetPropertyDirect(ra, code, TJS_MEMBERENSURE|TJS_IGNOREPROP);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GPI:\n\t\t\t\tGetPropertyIndirect(ra, code, 0);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GPIS:\n\t\t\t\tGetPropertyIndirect(ra, code, TJS_IGNOREPROP);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPI:\n\t\t\t\tSetPropertyIndirect(ra, code, 0);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPIE:\n\t\t\t\tSetPropertyIndirect(ra, code, TJS_MEMBERENSURE);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SPIS:\n\t\t\t\tSetPropertyIndirect(ra, code, TJS_MEMBERENSURE|TJS_IGNOREPROP);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GETP:\n\t\t\t\tGetProperty(ra, code);\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SETP:\n\t\t\t\tSetProperty(ra, code);\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DELD:\n\t\t\t\tDeleteMemberDirect(ra, code);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DELI:\n\t\t\t\tDeleteMemberIndirect(ra, code);\n\t\t\t\tcode += 4;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_SRV:\n\t\t\t\tif(result) result->CopyRef(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_RET:\n#ifdef ENABLE_DEBUGGER\n\t\t\t\tif( is_enable_debugger ) {\n\t\t\t\t\tTJSDebuggerHook( DBGHOOK_PREV_RETURN, Block->GetName(), cur_line_no, this );\n\t\t\t\t\tcur_line_no = -1;\n\t\t\t\t}\n#endif\t// ENABLE_DEBUGGER\n\t\t\t\treturn (tjs_int)(code+1-CodeArea);\n\n\t\t\tcase VM_ENTRY:\n\t\t\t\tcode = CodeArea + ExecuteCodeInTryBlock(ra, (tjs_int)(code-CodeArea + 3), args,\n\t\t\t\t\tnumargs, result, (tjs_int)(TJS_FROM_VM_CODE_ADDR(code[1])+code-CodeArea),\n\t\t\t\t\tTJS_FROM_VM_REG_ADDR(code[2]));\n\t\t\t\tbreak;\n\n\t\t\tcase VM_EXTRY:\n\t\t\t\treturn (tjs_int)(code+1-CodeArea);  // same as ret\n\n\t\t\tcase VM_THROW:\n#ifdef ENABLE_DEBUGGER\n\t\t\t\tif( is_enable_debugger ) {\n\t\t\t\t\tTJSDebuggerHook( DBGHOOK_PREV_EXCEPT, Block->GetName(), cur_line_no, this );\n\t\t\t\t\tcur_line_no = -1;\n\t\t\t\t}\n#endif\t// ENABLE_DEBUGGER\n\t\t\t\tThrowScriptException(TJS_GET_VM_REG(ra, code[1]),\n\t\t\t\t\tBlock, CodePosToSrcPos((tjs_int)(code-CodeArea)));\n\t\t\t\tcode += 2; // actually here not proceed...\n\t\t\t\tbreak;\n\n\t\t\tcase VM_CHGTHIS:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]).ChangeClosureObjThis(\n\t\t\t\t\tTJS_GET_VM_REG(ra, code[2]).AsObjectNoAddRef());\n\t\t\t\tcode += 3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_GLOBAL:\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = Block->GetTJS()->GetGlobalNoAddRef();\n\t\t\t\tcode += 2;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_ADDCI:\n\t\t\t\tAddClassInstanceInfo(ra, code);\n\t\t\t\tcode+=3;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_REGMEMBER:\n\t\t\t\tRegisterObjectMember(ra[-1].AsObjectNoAddRef());\n\t\t\t\tcode ++;\n\t\t\t\tbreak;\n\n\t\t\tcase VM_DEBUGGER:\n#ifdef ENABLE_DEBUGGER\n\t\t\t\tif( is_enable_debugger ) {\n\t\t\t\t\tTJSDebuggerHook( DBGHOOK_PREV_BREAK, Block->GetName(), cur_line_no, this );\n\t\t\t\t\tcur_line_no = -1;\n\t\t\t\t}\n#else\t// ENABLE_DEBUGGER\n\t\t\t\tTJSNativeDebuggerBreak();\n#endif\t// ENABLE_DEBUGGER\n\t\t\t\tcode ++;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tThrowInvalidVMCode();\n\t\t\t}\n\t\t}\n\t}\n\tcatch(eTJSSilent &e)\n\t{\n\t\tthrow e;\n\t}\n#ifdef ENABLE_DEBUGGER\n#define DEBUGGER_EXCEPTION_HOOK\tif( TJSEnableDebugMode && ::IsDebuggerPresent() ) TJSDebuggerHook( DBGHOOK_PREV_EXCEPT, NULL, -1, this );\n#else\t// ENABLE_DEBUGGER\n#define DEBUGGER_EXCEPTION_HOOK\n#endif\t// ENABLE_DEBUGGER\n\tcatch(eTJSScriptException &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\te.AddTrace(this, (tjs_int)(codesave-CodeArea));\n\t\tthrow e;\n\t}\n\tcatch(eTJSScriptError &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\te.AddTrace(this, (tjs_int)(codesave-CodeArea));\n\t\tthrow e;\n\t}\n\tcatch(eTJS &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode((tjs_int)(codesave - CodeArea), ra_org);\n\t\tTJS_eTJSScriptError(e.GetMessage(), this, (tjs_int)(codesave-CodeArea));\n\t}\n\tcatch(exception &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode((tjs_int)(codesave - CodeArea), ra_org);\n\t\tTJS_eTJSScriptError(e.what(), this, (tjs_int)(codesave-CodeArea));\n\t}\n#if 0\n\tcatch(const wchar_t *text)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode((tjs_int)(codesave - CodeArea), ra_org);\n\t\tTJS_eTJSScriptError(text, this, (tjs_int)(codesave-CodeArea));\n\t}\n#endif\n\tcatch(const char *text)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode((tjs_int)(codesave - CodeArea), ra_org);\n\t\tTJS_eTJSScriptError(text, this, (tjs_int)(codesave-CodeArea));\n\t}\n#ifdef TJS_SUPPORT_VCL\n\tcatch(const EAccessViolation &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode(codesave - CodeArea, ra_org);\n\t\tTJS_eTJSScriptError(e.Message.c_str(), this, codesave-CodeArea);\n\t}\n\tcatch(const Exception &e)\n\t{\n\t\tDEBUGGER_EXCEPTION_HOOK;\n\t\tDisplayExceptionGeneratedCode(codesave - CodeArea, ra_org);\n\t\tTJS_eTJSScriptError(e.Message.c_str(), this, codesave-CodeArea);\n\t}\n#endif\n#undef DEBUGGER_EXCEPTION_HOOK\n\n\treturn (tjs_int)(codesave-CodeArea);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::ExecuteCodeInTryBlock(tTJSVariant *ra, tjs_int startip,\n\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result, tjs_int catchip,\n\ttjs_int exobjreg)\n{\n\t// execute codes in a try-protected block\n\n\ttry\n\t{\n\t\tif(TJSStackTracerEnabled()) TJSStackTracerPush(this, true);\n\t\ttjs_int ret;\n\t\ttry\n\t\t{\n\t\t\tret = ExecuteCode(ra, startip, args, numargs, result);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(TJSStackTracerEnabled()) TJSStackTracerPop();\n\t\t\tthrow;\n\t\t}\n\t\tif(TJSStackTracerEnabled()) TJSStackTracerPop();\n\t\treturn ret;\n\t}\n\tTJS_CONVERT_TO_TJS_EXCEPTION_OBJECT(\n\t\t\tBlock->GetTJS(),\n\t\t\texobjreg,\n\t\t\tra + exobjreg,\n\t\t\t{\n\t\t\t\t;\n\t\t\t},\n\t\t\t{\n\t\t\t\treturn catchip;\n\t\t\t}\n\t\t)\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ContinuousClear(\n\ttTJSVariant *ra, const tjs_int32 *code)\n{\n\ttTJSVariant *r = TJS_GET_VM_REG_ADDR(ra, code[1]);\n\ttTJSVariant *rl = r + code[2]; // code[2] is count ( not reg offset )\n\twhile(r<rl) (r++)->Clear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::GetPropertyDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]] = ra[code[2]][DataArea[ra[code[3]]]];\n\n\ttTJSVariant * ra_code2 = TJS_GET_VM_REG_ADDR(ra, code[2]);\n\ttTJSVariantType type = ra_code2->Type();\n\tif(type == tvtString)\n\t{\n\t\tGetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[1]), ra_code2,\n\t\t\tTJS_GET_VM_REG(DataArea, code[3]));\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tGetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[1]), ra_code2,\n\t\t\tTJS_GET_VM_REG(DataArea, code[3]));\n\t\treturn;\n\t}\n\n\n\ttjs_error hr;\n\ttTJSVariantClosure clo = ra_code2->AsObjectClosureNoAddRef();\n\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\thr = clo.PropGet(flags,\n\t\tname->GetString(), name->GetHint(), TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, TJS_GET_VM_REG(DataArea, code[3]).GetString());\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SetPropertyDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]][DataArea[ra[code[2]]]] = ra[code[3]]]\n\n\ttTJSVariant * ra_code1 = TJS_GET_VM_REG_ADDR(ra, code[1]);\n\ttTJSVariantType type = ra_code1->Type();\n\tif(type == tvtString)\n\t{\n\t\tSetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[3]), ra_code1,\n\t\t\tTJS_GET_VM_REG(DataArea, code[2]));\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tSetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[3]), ra_code1,\n\t\t\tTJS_GET_VM_REG(DataArea, code[2]));\n\t\treturn;\n\t}\n\n\ttjs_error hr;\n\ttTJSVariantClosure clo = ra_code1->AsObjectClosureNoAddRef();\n\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[2]);\n\thr = clo.PropSetByVS(flags,\n\t\tname->AsStringNoAddRef(), TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\tif(hr == TJS_E_NOTIMPL)\n\t\thr = clo.PropSet(flags,\n\t\t\tname->GetString(), name->GetHint(), TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, TJS_GET_VM_REG(DataArea, code[2]).GetString());\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::GetProperty(tTJSVariant *ra, const tjs_int32 *code)\n{\n\t// ra[code[1]] = * ra[code[2]]\n\ttTJSVariantClosure clo =\n\t\tTJS_GET_VM_REG_ADDR(ra, code[2])->AsObjectClosureNoAddRef();\n\ttjs_error hr;\n\thr = clo.PropGet(0, NULL, NULL, TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, NULL);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SetProperty(tTJSVariant *ra, const tjs_int32 *code)\n{\n\t// * ra[code[1]] = ra[code[2]]\n\ttTJSVariantClosure clo =\n\t\tTJS_GET_VM_REG_ADDR(ra, code[1])->AsObjectClosureNoAddRef();\n\ttjs_error hr;\n\thr = clo.PropSet(0, NULL, NULL, TJS_GET_VM_REG_ADDR(ra, code[2]),\n\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, NULL);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::GetPropertyIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]] = ra[code[2]][ra[code[3]]];\n\n\ttTJSVariant * ra_code2 = TJS_GET_VM_REG_ADDR(ra, code[2]);\n\ttTJSVariantType type = ra_code2->Type();\n\tif(type == tvtString)\n\t{\n\t\tGetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[1]), ra_code2,\n\t\t\tTJS_GET_VM_REG(ra, code[3]));\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tGetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[1]), ra_code2,\n\t\t\tTJS_GET_VM_REG(ra, code[3]));\n\t\treturn;\n\t}\n\n\ttjs_error hr;\n\ttTJSVariantClosure clo = ra_code2->AsObjectClosureNoAddRef();\n\ttTJSVariant * ra_code3 = TJS_GET_VM_REG_ADDR(ra, code[3]);\n\tif(ra_code3->Type() != tvtInteger)\n\t{\n\t\ttTJSVariantString *str;\n\t\tstr = ra_code3->AsString();\n\n\t\ttry\n\t\t{\n\t\t\t// TODO: verify here needs hint holding\n\t\t\thr = clo.PropGet(flags, *str, NULL, TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, *str);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(str) str->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(str) str->Release();\n\t}\n\telse\n\t{\n\t\thr = clo.PropGetByNum(flags, (tjs_int)ra_code3->AsInteger(),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\tif(TJS_FAILED(hr)) ThrowFrom_tjs_error_num(hr, (tjs_int)ra_code3->AsInteger());\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SetPropertyIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]][ra[code[2]]] = ra[code[3]]]\n\n\ttTJSVariant *ra_code1 = TJS_GET_VM_REG_ADDR(ra, code[1]);\n\ttTJSVariantType type = ra_code1->Type();\n\tif(type == tvtString)\n\t{\n\t\tSetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[1]), TJS_GET_VM_REG(ra, code[2]));\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tSetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[1]), TJS_GET_VM_REG(ra, code[2]));\n\t\treturn;\n\t}\n\n\ttTJSVariantClosure clo = ra_code1->AsObjectClosure();\n\ttTJSVariant *ra_code2 = TJS_GET_VM_REG_ADDR(ra, code[2]);\n\tif(ra_code2->Type() != tvtInteger)\n\t{\n\t\ttTJSVariantString *str;\n\t\ttry\n\t\t{\n\t\t\tstr = ra_code2->AsString();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\ttjs_error hr;\n\n\t\ttry\n\t\t{\n\t\t\thr = clo.PropSetByVS(flags,\n\t\t\t\tstr, TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(hr == TJS_E_NOTIMPL)\n\t\t\t\thr = clo.PropSet(flags,\n\t\t\t\t\t*str, NULL, TJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, *str);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(str) str->Release();\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(str) str->Release();\n\t\tclo.Release();\n\t}\n\telse\n\t{\n\t\ttjs_error hr;\n\n\t\ttry\n\t\t{\n\t\t\thr = clo.PropSetByNum(flags,\n\t\t\t\t(tjs_int)ra_code2->AsInteger(),\n\t\t\t\t\tTJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr))\n\t\t\t\tThrowFrom_tjs_error_num(hr, (tjs_int)ra_code2->AsInteger());\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tclo.Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperatePropertyDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]][DataArea[ra[code[3]]]], /*param=*/ra[code[4]]);\n\n\ttTJSVariantClosure clo =  TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttjs_error hr;\n\ttry\n\t{\n\t\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\t\thr = clo.Operation(ope,\n\t\t\tname->GetString(), name->GetHint(),\n\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[4]),\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, TJS_GET_VM_REG(DataArea, code[3]).GetString());\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperatePropertyIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]][ra[code[3]]], /*param=*/ra[code[4]]);\n\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttTJSVariant *ra_code3 = TJS_GET_VM_REG_ADDR(ra, code[3]);\n\tif(ra_code3->Type() != tvtInteger)\n\t{\n\t\ttTJSVariantString *str;\n\t\ttry\n\t\t{\n\t\t\tstr = ra_code3->AsString();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\ttjs_error hr;\n\t\ttry\n\t\t{\n\t\t\thr = clo.Operation(ope, *str, NULL,\n\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\t\tTJS_GET_VM_REG_ADDR(ra, code[4]),\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, *str);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(str) str->Release();\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(str) str->Release();\n\t\tclo.Release();\n\t}\n\telse\n\t{\n\t\ttjs_error hr;\n\t\ttry\n\t\t{\n\t\t\thr = clo.OperationByNum(ope, (tjs_int)ra_code3->AsInteger(),\n\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\t\tTJS_GET_VM_REG_ADDR(ra, code[4]),\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr))\n\t\t\t\tThrowFrom_tjs_error_num(hr,\n\t\t\t\t\t(tjs_int)TJS_GET_VM_REG(ra, code[3]).AsInteger());\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tclo.Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperateProperty(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]], /*param=*/ra[code[3]]);\n\ttTJSVariantClosure clo =  TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttjs_error hr;\n\ttry\n\t{\n\t\thr = clo.Operation(ope,\n\t\t\tNULL, NULL,\n\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[3]),\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, NULL);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperatePropertyDirect0(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]][DataArea[ra[code[3]]]]);\n\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttjs_error hr;\n\ttry\n\t{\n\t\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\t\thr = clo.Operation(ope,\n\t\t\tname->GetString(), name->GetHint(),\n\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL, NULL,\n\t\t\tra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, TJS_GET_VM_REG(DataArea, code[3]).GetString());\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperatePropertyIndirect0(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]][ra[code[3]]]);\n\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttTJSVariant *ra_code3 = TJS_GET_VM_REG_ADDR(ra, code[3]);\n\tif(ra_code3->Type() != tvtInteger)\n\t{\n\t\ttTJSVariantString *str;\n\t\ttry\n\t\t{\n\t\t\tstr = ra_code3->AsString();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\ttjs_error hr;\n\t\ttry\n\t\t{\n\t\t\thr = clo.Operation(ope, *str, NULL,\n\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL, NULL,\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, *str);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(str) str->Release();\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(str) str->Release();\n\t\tclo.Release();\n\t}\n\telse\n\t{\n\t\ttjs_error hr;\n\t\ttry\n\t\t{\n\t\t\thr = clo.OperationByNum(ope, (tjs_int)TJS_GET_VM_REG(ra, code[3]).AsInteger(),\n\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL, NULL,\n\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(TJS_FAILED(hr))\n\t\t\t\tThrowFrom_tjs_error_num(hr,\n\t\t\t\t\t(tjs_int)TJS_GET_VM_REG(ra, code[3]).AsInteger());\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tclo.Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OperateProperty0(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 ope)\n{\n\t// ra[code[1]] = ope(ra[code[2]]);\n\ttTJSVariantClosure clo =  TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttjs_error hr;\n\ttry\n\t{\n\t\thr = clo.Operation(ope,\n\t\t\tNULL, NULL,\n\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL, NULL,\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, NULL);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DeleteMemberDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code)\n{\n\t// ra[code[1]] = delete ra[code[2]][DataArea[ra[code[3]]]];\n\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttjs_error hr;\n\ttry\n\t{\n\t\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\t\thr = clo.DeleteMember(0,\n\t\t\tname->GetString(), name->GetHint(), ra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(code[1])\n\t{\n\t\tif(TJS_FAILED(hr))\n\t\t\tTJS_GET_VM_REG(ra, code[1]) = false;\n\t\telse\n\t\t\tTJS_GET_VM_REG(ra, code[1]) = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DeleteMemberIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code)\n{\n\t// ra[code[1]] = delete ra[code[2]][ra[code[3]]];\n\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttTJSVariantString *str;\n\ttry\n\t{\n\t\tstr = TJS_GET_VM_REG(ra, code[3]).AsString();\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\ttjs_error hr;\n\n\ttry\n\t{\n\t\thr = clo.DeleteMember(0, *str, NULL,\n\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\tif(code[1])\n\t\t{\n\t\t\tif(TJS_FAILED(hr))\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = false;\n\t\t\telse\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = true;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(str) str->Release();\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tif(str) str->Release();\n\tclo.Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::TypeOfMemberDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]] = typeof ra[code[2]][DataArea[ra[code[3]]]];\n\ttTJSVariantType type = TJS_GET_VM_REG(ra, code[2]).Type();\n\tif(type == tvtString)\n\t{\n\t\tGetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[2]),\n\t\t\tTJS_GET_VM_REG(DataArea,code[3]));\n\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tGetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[2]),\n\t\t\tTJS_GET_VM_REG(DataArea, code[3]));\n\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\treturn;\n\t}\n\n\ttjs_error hr;\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\ttry\n\t{\n\t\ttTJSVariant *name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\t\thr = clo.PropGet(flags,\n\t\t\tname->GetString(), name->GetHint(), TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t}\n\tcatch(...)\n\t{\n\t\tclo.Release();\n\t\tthrow;\n\t}\n\tclo.Release();\n\tif(hr == TJS_S_OK)\n\t{\n\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t}\n\telse if(hr == TJS_E_MEMBERNOTFOUND)\n\t{\n\t\tstatic tTJSString undefined_name(TJSMapGlobalStringMap(TJS_W(\"undefined\")));\n\t\tTJS_GET_VM_REG(ra, code[1]) = undefined_name;\n\t}\n\telse if(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, TJS_GET_VM_REG(DataArea, code[3]).GetString());\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::TypeOfMemberIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tjs_uint32 flags)\n{\n\t// ra[code[1]] = typeof ra[code[2]][ra[code[3]]];\n\n\ttTJSVariantType type = TJS_GET_VM_REG(ra, code[2]).Type();\n\tif(type == tvtString)\n\t{\n\t\tGetStringProperty(TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[2]),\n\t\t\tTJS_GET_VM_REG(ra, code[3]));\n\t\tTypeOf(ra[code[1]]);\n\t\treturn;\n\t}\n\tif(type == tvtOctet)\n\t{\n\t\tGetOctetProperty(TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\tTJS_GET_VM_REG_ADDR(ra, code[2]),\n\t\t\tTJS_GET_VM_REG(ra, code[3]));\n\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\treturn;\n\t}\n\n\ttjs_error hr;\n\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\tif(TJS_GET_VM_REG(ra, code[3]).Type() != tvtInteger)\n\t{\n\t\ttTJSVariantString *str;\n\t\ttry\n\t\t{\n\t\t\tstr = TJS_GET_VM_REG(ra, code[3]).AsString();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\n\t\ttry\n\t\t{\n\t\t\t// TODO: verify here needs hint holding\n\t\t\thr = clo.PropGet(flags, *str, NULL, TJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(hr == TJS_S_OK)\n\t\t\t{\n\t\t\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t}\n\t\t\telse if(hr == TJS_E_MEMBERNOTFOUND)\n\t\t\t{\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = TJS_W(\"undefined\");\n\t\t\t}\n\t\t\telse if(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, *str);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(str) str->Release();\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(str) str->Release();\n\t\tclo.Release();\n\t}\n\telse\n\t{\n\t\ttry\n\t\t{\n\t\t\thr = clo.PropGetByNum(flags,\n\t\t\t\t(tjs_int)TJS_GET_VM_REG(ra, code[3]).AsInteger(),\n\t\t\t\tTJS_GET_VM_REG_ADDR(ra, code[1]),\n\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\tif(hr == TJS_S_OK)\n\t\t\t{\n\t\t\t\tTypeOf(TJS_GET_VM_REG(ra, code[1]));\n\t\t\t}\n\t\t\telse if(hr == TJS_E_MEMBERNOTFOUND)\n\t\t\t{\n\t\t\t\tTJS_GET_VM_REG(ra, code[1]) = TJS_W(\"undefined\");\n\t\t\t}\n\t\t\telse if(TJS_FAILED(hr))\n\t\t\t\tThrowFrom_tjs_error_num(hr,\n\t\t\t\t\t(tjs_int)TJS_GET_VM_REG(ra, code[3]).AsInteger());\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tclo.Release();\n\t}\n}\n//---------------------------------------------------------------------------\n// Macros for preparing function argument pointer array.\n// code[0] is an argument count;\n// -1 for omitting ('...') argument to passing unmodified args from the caller.\n// -2 for expanding array to argument\n#define TJS_PASS_ARGS_PREPARED_ARRAY_COUNT 20\n\n#define TJS_BEGIN_FUNC_CALL_ARGS(_code)                                   \\\n\ttTJSVariant ** pass_args;                                             \\\n\ttTJSVariant *pass_args_p[TJS_PASS_ARGS_PREPARED_ARRAY_COUNT];         \\\n\ttTJSVariant * pass_args_v = NULL;                                     \\\n\ttjs_int code_size;                                                    \\\n\tbool alloc_args = false;                                              \\\n\ttry                                                                   \\\n\t{                                                                     \\\n\t\ttjs_int pass_args_count = (_code)[0];                             \\\n\t\tif(pass_args_count == -1)                                         \\\n\t\t{                                                                 \\\n\t\t\t/* omitting args; pass intact aguments from the caller */     \\\n\t\t\tpass_args = args;                                             \\\n\t\t\tpass_args_count = numargs;                                    \\\n\t\t\tcode_size = 1;                                                \\\n\t\t}                                                                 \\\n\t\telse if(pass_args_count == -2)                                    \\\n\t\t{                                                                 \\\n\t\t\ttjs_int args_v_count = 0;                                     \\\n\t\t\t/* count total argument count */                              \\\n\t\t\tpass_args_count = 0;                                          \\\n\t\t\ttjs_int arg_written_count = (_code)[1];                       \\\n\t\t\tcode_size = arg_written_count * 2 + 2;                        \\\n\t\t\tfor(tjs_int i = 0; i < arg_written_count; i++)                \\\n\t\t\t{                                                             \\\n\t\t\t\tswitch((_code)[i*2+2])                                    \\\n\t\t\t\t{                                                         \\\n\t\t\t\tcase fatNormal:                                           \\\n\t\t\t\t\tpass_args_count ++;                                   \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\tcase fatExpand:                                           \\\n\t\t\t\t\targs_v_count +=                                       \\\n\t\t\t\t\t\tTJSGetArrayElementCount(                          \\\n\t\t\t\t\t\t\tTJS_GET_VM_REG(ra, (_code)[i*2+1+2]).         \\\n\t\t\t\t\t\t\t\tAsObjectNoAddRef());                      \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\tcase fatUnnamedExpand:                                    \\\n\t\t\t\t\tpass_args_count +=                                    \\\n\t\t\t\t\t\t(numargs > FuncDeclUnnamedArgArrayBase)?          \\\n\t\t\t\t\t\t\t(numargs - FuncDeclUnnamedArgArrayBase) : 0;  \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\t}                                                         \\\n\t\t\t}                                                             \\\n\t\t\tpass_args_count += args_v_count;                              \\\n\t\t\t/* allocate temporary variant array for Array object */       \\\n\t\t\tpass_args_v = new tTJSVariant[args_v_count];                  \\\n\t\t\t/* allocate pointer array */                                  \\\n\t\t\tif(pass_args_count < TJS_PASS_ARGS_PREPARED_ARRAY_COUNT)      \\\n\t\t\t\tpass_args = pass_args_p;                                  \\\n\t\t\telse                                                          \\\n\t\t\t\tpass_args = new tTJSVariant * [pass_args_count],          \\\n\t\t\t\t\talloc_args = true;                                    \\\n\t\t\t/* create pointer array to pass to callee function */         \\\n\t\t\targs_v_count = 0;                                             \\\n\t\t\tpass_args_count = 0;                                          \\\n\t\t\tfor(tjs_int i = 0; i < arg_written_count; i++)                \\\n\t\t\t{                                                             \\\n\t\t\t\tswitch((_code)[i*2+2])                                    \\\n\t\t\t\t{                                                         \\\n\t\t\t\tcase fatNormal:                                           \\\n\t\t\t\t\tpass_args[pass_args_count++] =                        \\\n\t\t\t\t\t\tTJS_GET_VM_REG_ADDR(ra, (_code)[i*2+1+2]);        \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\tcase fatExpand:                                           \\\n\t\t\t\t  {                                                       \\\n\t\t\t\t\ttjs_int count = TJSCopyArrayElementTo(                \\\n\t\t\t\t\t\tTJS_GET_VM_REG(ra, (_code)[i*2+1+2]).             \\\n\t\t\t\t\t\t\t\tAsObjectNoAddRef(),                       \\\n\t\t\t\t\t\t\t\tpass_args_v + args_v_count, 0, -1);       \\\n\t\t\t\t\tfor(tjs_int j = 0; j < count; j++)                    \\\n\t\t\t\t\t\tpass_args[pass_args_count++] =                    \\\n\t\t\t\t\t\t\tpass_args_v + j + args_v_count;               \\\n\t                                                                      \\\n\t\t\t\t\targs_v_count += count;                                \\\n\t                                                                      \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\t  }                                                       \\\n\t\t\t\tcase fatUnnamedExpand:                                    \\\n\t\t\t\t  {                                                       \\\n\t\t\t\t\ttjs_int count =                                       \\\n\t\t\t\t\t\t(numargs > FuncDeclUnnamedArgArrayBase)?          \\\n\t\t\t\t\t\t\t(numargs - FuncDeclUnnamedArgArrayBase) : 0;  \\\n\t\t\t\t\tfor(tjs_int j = 0; j < count; j++)                    \\\n\t\t\t\t\t\tpass_args[pass_args_count++] =                    \\\n\t\t\t\t\t\t\targs[FuncDeclUnnamedArgArrayBase + j];        \\\n\t\t\t\t\tbreak;                                                \\\n\t\t\t\t  }                                                       \\\n\t\t\t\t}                                                         \\\n\t\t\t}                                                             \\\n\t\t}                                                                 \\\n\t\telse if(pass_args_count <= TJS_PASS_ARGS_PREPARED_ARRAY_COUNT)    \\\n\t\t{                                                                 \\\n\t\t\tcode_size = pass_args_count + 1;                              \\\n\t\t\tpass_args = pass_args_p;                                      \\\n\t\t\tfor(tjs_int i = 0; i < pass_args_count; i++)                  \\\n\t\t\t\tpass_args[i] = TJS_GET_VM_REG_ADDR(ra, (_code)[1+i]);     \\\n\t\t}                                                                 \\\n\t\telse                                                              \\\n\t\t{                                                                 \\\n\t\t\tcode_size = pass_args_count + 1;                              \\\n\t\t\tpass_args = new tTJSVariant * [pass_args_count];              \\\n\t\t\talloc_args = true;                                            \\\n\t\t\tfor(tjs_int i = 0; i < pass_args_count; i++)                  \\\n\t\t\t\tpass_args[i] = TJS_GET_VM_REG_ADDR(ra, (_code)[1+i]);     \\\n\t\t}\n\n\n#define TJS_END_FUNC_CALL_ARGS                                            \\\n\t}                                                                     \\\n\tcatch(...)                                                            \\\n\t{                                                                     \\\n\t\tif(alloc_args) delete [] pass_args;                               \\\n\t\tif(pass_args_v) delete [] pass_args_v;                            \\\n\t\tthrow;                                                            \\\n\t}                                                                     \\\n\tif(alloc_args) delete [] pass_args;                                   \\\n\tif(pass_args_v) delete [] pass_args_v;\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::CallFunction(tTJSVariant *ra,\n\tconst tjs_int32 *code, tTJSVariant **args, tjs_int numargs)\n{\n\t// function calling / create new object\n\ttjs_error hr;\n\n\tTJS_BEGIN_FUNC_CALL_ARGS(code + 3)\n\n\t\ttTJSVariantClosure clo = TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\t\ttry\n\t\t{\n\t\t\tif(code[0] == VM_CALL)\n\t\t\t{\n\t\t\t\thr = clo.FuncCall(0, NULL, NULL,\n\t\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL, pass_args_count, pass_args,\n\t\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tiTJSDispatch2 *dsp;\n\t\t\t\thr = clo.CreateNew(0, NULL, NULL,\n\t\t\t\t\t&dsp, pass_args_count, pass_args,\n\t\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\t\tif(TJS_SUCCEEDED(hr))\n\t\t\t\t{\n\t\t\t\t\tif(dsp)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(code[1]) TJS_GET_VM_REG(ra, code[1]) = tTJSVariant(dsp, dsp);\n\t\t\t\t\t\tdsp->Release();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} \n\t\t}\n\t\tcatch(...)\n\t\t{ \n\t\t\tclo.Release();\n\t\t\tthrow;\n\t\t}\n\t\tclo.Release();\n\t\t// TODO: Null Check\n\n\tTJS_END_FUNC_CALL_ARGS\n\n\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr, TJS_W(\"\"));\n\n\treturn code_size + 3;\n}\n#undef _code\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::CallFunctionDirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tTJSVariant **args, tjs_int numargs)\n{\n\ttjs_error hr;\n\n\tTJS_BEGIN_FUNC_CALL_ARGS(code + 4)\n\n\t\ttTJSVariantType type = TJS_GET_VM_REG(ra, code[2]).Type();\n\t\ttTJSVariant * name = TJS_GET_VM_REG_ADDR(DataArea, code[3]);\n\t\tif(type == tvtString)\n\t\t{\n\t\t\tProcessStringFunction(name->GetString(),\n\t\t\t\tTJS_GET_VM_REG(ra, code[2]),\n\t\t\t\tpass_args, pass_args_count, code[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL);\n\t\t\thr = TJS_S_OK;\n\t\t}\n\t\telse if(type == tvtOctet)\n\t\t{\n\t\t\tProcessOctetFunction(name->GetString(),\n\t\t\t\tTJS_GET_VM_REG(ra, code[2]).AsOctetNoAddRef(),\n\t\t\t\tpass_args, pass_args_count, code[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL);\n\t\t\thr = TJS_S_OK;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTJSVariantClosure clo =  TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\t\t\ttry\n\t\t\t{\n\t\t\t\thr = clo.FuncCall(0,\n\t\t\t\t\tname->GetString(), name->GetHint(),\n\t\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\t\t\t\tpass_args_count, pass_args,\n\t\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tclo.Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tclo.Release();\n\t\t}\n\n\tTJS_END_FUNC_CALL_ARGS\n\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr,\n\t\t\tttstr(TJS_GET_VM_REG(DataArea, code[3])).c_str());\n\n\treturn code_size + 4;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::CallFunctionIndirect(tTJSVariant *ra,\n\tconst tjs_int32 *code, tTJSVariant **args, tjs_int numargs)\n{\n\ttjs_error hr;\n\n\tttstr name = TJS_GET_VM_REG(ra, code[3]);\n\n\tTJS_BEGIN_FUNC_CALL_ARGS(code + 4)\n\n\t\ttTJSVariantType type = TJS_GET_VM_REG(ra, code[2]).Type();\n\t\tif(type == tvtString)\n\t\t{\n\t\t\tProcessStringFunction(name.c_str(),\n\t\t\t\tTJS_GET_VM_REG(ra, code[2]),\n\t\t\t\tpass_args, pass_args_count, code[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL);\n\t\t\thr = TJS_S_OK;\n\t\t}\n\t\telse if(type == tvtOctet)\n\t\t{\n\t\t\tProcessOctetFunction(name.c_str(),\n\t\t\t\tTJS_GET_VM_REG(ra, code[2]).AsOctetNoAddRef(),\n\t\t\t\tpass_args, pass_args_count, code[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL);\n\t\t\thr = TJS_S_OK;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTJSVariantClosure clo =  TJS_GET_VM_REG(ra, code[2]).AsObjectClosure();\n\t\t\ttry\n\t\t\t{\n\t\t\t\thr = clo.FuncCall(0,\n\t\t\t\t\tname.c_str(), name.GetHint(),\n\t\t\t\t\tcode[1]?TJS_GET_VM_REG_ADDR(ra, code[1]):NULL,\n\t\t\t\t\t\tpass_args_count, pass_args,\n\t\t\t\t\t\tclo.ObjThis?clo.ObjThis:ra[-1].AsObjectNoAddRef());\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tclo.Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tclo.Release();\n\t\t}\n\n\tTJS_END_FUNC_CALL_ARGS\n\n\tif(TJS_FAILED(hr))\n\t\tTJSThrowFrom_tjs_error(hr, name.c_str());\n\n\treturn code_size + 4;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::AddClassInstanceInfo(tTJSVariant *ra,\n\tconst tjs_int32 *code)\n{\n\tiTJSDispatch2 *dsp;\n\tdsp = TJS_GET_VM_REG(ra, code[1]).AsObjectNoAddRef();\n\tif(dsp)\n\t{\n\t\tdsp->ClassInstanceInfo(TJS_CII_ADD, 0, TJS_GET_VM_REG_ADDR(ra, code[2]));\n\t}\n\telse\n\t{\n\t\t// ?? must be an error\n\t}\n}\n//---------------------------------------------------------------------------\nstatic const tjs_char *StrFuncs[] =\n{ \n\tTJS_W(\"charAt\"), \n\tTJS_W(\"indexOf\"), \n\tTJS_W(\"toUpperCase\"),\n\tTJS_W(\"toLowerCase\"), \n\tTJS_W(\"substring\"), \n\tTJS_W(\"substr\"), \n\tTJS_W(\"sprintf\"),\n\tTJS_W(\"replace\"), \n\tTJS_W(\"escape\"), \n\tTJS_W(\"split\"),\n\tTJS_W(\"trim\"),\n\tTJS_W(\"reverse\"),\n\tTJS_W(\"repeat\") \n};\n\nenum tTJSStringMethodNameIndex\n{\n\tTJSStrMethod_charAt = 0,\n\tTJSStrMethod_indexOf,\n\tTJSStrMethod_toUpperCase,\n\tTJSStrMethod_toLowerCase,\n\tTJSStrMethod_substring, \n\tTJSStrMethod_substr, \n\tTJSStrMethod_sprintf,\n\tTJSStrMethod_replace, \n\tTJSStrMethod_escape, \n\tTJSStrMethod_split,\n\tTJSStrMethod_trim,\n\tTJSStrMethod_reverse,\n\tTJSStrMethod_repeat\n};\n\n#define TJS_STRFUNC_MAX (sizeof(StrFuncs) / sizeof(StrFuncs[0]))\nstatic tjs_int32 StrFuncHash[TJS_STRFUNC_MAX];\nstatic bool TJSStrFuncInit = false;\nstatic void InitTJSStrFunc()\n{\n\tTJSStrFuncInit = true;\n\tfor(tjs_int i=0; i<TJS_STRFUNC_MAX; i++)\n\t{\n\t\tconst tjs_char *p = StrFuncs[i];\n\t\ttjs_int32 hash = 0;\n\t\twhile(*p) hash += *p, p++;\n\t\tStrFuncHash[i] = hash;\n\t}\n}\n\nvoid tTJSInterCodeContext::ProcessStringFunction(const tjs_char *member,\n\tconst ttstr & target, tTJSVariant **args, tjs_int numargs, tTJSVariant *result)\n{\n\tif(!TJSStrFuncInit) InitTJSStrFunc();\n\n\ttjs_int32 hash;\n\n\tif(!member) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\n\tconst tjs_char *m = member;\n\thash = 0;\n\twhile(*m) hash += *m, m++;\n\n\tconst tjs_char *s = target.c_str(); // target string\n\tconst tjs_int s_len = target.GetLen();\n\n#define TJS_STR_METHOD_IS(_name) (hash == StrFuncHash[TJSStrMethod_##_name] && !TJS_strcmp(StrFuncs[TJSStrMethod_##_name], member))\n\n\tif(TJS_STR_METHOD_IS(charAt))\n\t{\n\t\tif(numargs != 1) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\tif(s_len == 0)\n\t\t{\n\t\t\tif(result) *result = TJS_W(\"\");\n\t\t\treturn;\n\t\t}\n\t\ttjs_int i = (tjs_int)*args[0];\n\t\tif(i<0 || i>=s_len)\n\t\t{\n\t\t\tif(result) *result = TJS_W(\"\");\n\t\t\treturn;\n\t\t}\n\t\ttjs_char bt[2];\n\t\tbt[1] = 0;\n\t\tbt[0] = s[i];\n\t\tif(result) *result = bt;\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(indexOf))\n\t{\n\t\tif(numargs != 1 && numargs != 2) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\ttTJSVariantString *pstr = args[0]->AsString(); // sub string\n\n\t\tif(!s || !pstr)\n\t\t{\n\t\t\tif(result) *result = (tjs_int)-1;\n\t\t\tif(pstr) pstr->Release();\n\t\t\treturn;\n\t\t}\n\t\ttjs_int start;\n\t\tif(numargs == 1)\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttry // integer convertion may raise an exception\n\t\t\t{\n\t\t\t\tstart = (tjs_int)*args[1];\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tpstr->Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t\tif(start >= s_len)\n\t\t{\n\t\t\tif(result) *result = (tjs_int)-1;\n\t\t\tif(pstr) pstr->Release();\n\t\t\treturn;\n\t\t}\n\t\tconst tjs_char *p;\n\t\tp = TJS_strstr(s + start, (const tjs_char*)*pstr);\n\t\tif(!p)\n\t\t{\n\t\t\tif(result) *result = (tjs_int)-1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(result) *result = (tjs_int)(p-s);\n\t\t}\n\t\tif(pstr) pstr->Release();\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(toUpperCase))\n\t{\n\t\tif(numargs != 0) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\tif(result)\n\t\t{\n\t\t\t*result = s; // here s is copyed to *result ( not reference )\n\t\t\tconst tjs_char *pstr = result->GetString();  // buffer in *result\n\t\t\tif(pstr)\n\t\t\t{\n\t\t\t\ttjs_char *p = (tjs_char*)pstr;    // WARNING!! modification of const\n\t\t\t\twhile(*p)\n\t\t\t\t{\n\t\t\t\t\tif(*p>=TJS_W('a') && *p<=TJS_W('z')) *p += TJS_W('Z')-TJS_W('z');\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(toLowerCase))\n\t{\n\t\tif(numargs != 0) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\tif(result)\n\t\t{\n\t\t\t*result = s;\n\t\t\tconst tjs_char *pstr = result->GetString();\n\t\t\tif(pstr)\n\t\t\t{\n\t\t\t\ttjs_char *p = (tjs_char*)pstr;    // WARNING!! modification of const\n\t\t\t\twhile(*p)\n\t\t\t\t{\n\t\t\t\t\tif(*p>=TJS_W('A') && *p<=TJS_W('Z')) *p += TJS_W('z')-TJS_W('Z');\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(substring) || TJS_STR_METHOD_IS(substr))\n\t{\n\t\tif(numargs != 1 && numargs != 2) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\ttjs_int start = (tjs_int)*args[0];\n\t\tif(start < 0 || start >= s_len)\n\t\t{\n\t\t\tif(result) *result=TJS_W(\"\");\n\t\t\treturn;\n\t\t}\n\t\ttjs_int count;\n\t\tif(numargs == 2)\n\t\t{\n\t\t\tcount = (tjs_int)*args[1];\n\t\t\tif(count<0)\n\t\t\t{\n\t\t\t\tif(result) *result = TJS_W(\"\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(start + count > s_len) count = s_len - start;\n\t\t\tif(result)\n\t\t\t\t*result = ttstr(s+start, count);\n\t\t\treturn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(result) *result = s + start;\n\t\t}\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(sprintf))\n\t{\n\t\tif(result)\n\t\t{\n\t\t\ttTJSVariantString *res;\n\t\t\tres = TJSFormatString(s, numargs, args);\n\t\t\t*result = res;\n\t\t\tif(res) res->Release();\n\t\t}\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(replace))\n\t{\n\t\t// string.replace(pattern, replacement-string)  -->\n\t\t// pattern.replace(string, replacement-string)\n\t\tif(numargs < 2) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\n\t\ttTJSVariantClosure clo = args[0]->AsObjectClosureNoAddRef();\n\t\ttTJSVariant str = target;\n\t\ttTJSVariant *params[] = { &str, args[1] };\n\t\tstatic tTJSString replace_name(TJS_W(\"replace\"));\n\t\tclo.FuncCall(0, replace_name.c_str(), replace_name.GetHint(),\n\t\t\tresult, 2, params, NULL);\n\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(escape))\n\t{\n\t\tif(result)\n\t\t\t*result = target.EscapeC();\n\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(split))\n\t{\n\t\t// string.split(pattern, reserved, purgeempty) -->\n\t\t// Array.split(pattern, string, reserved, purgeempty)\n\t\tif(numargs < 1) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\n\t\tiTJSDispatch2 * array = TJSCreateArrayObject();\n\t\ttry\n\t\t{\n\t\t\ttTJSVariant str = target;\n\t\t\ttjs_int arg_count = 2;\n\t\t\ttTJSVariant *params[4] = {\n\t\t\t\targs[0],\n\t\t\t\t&str };\n\t\t\tif(numargs >= 2)\n\t\t\t{\n\t\t\t\targ_count ++;\n\t\t\t\tparams[2] = args[1];\n\t\t\t}\n\t\t\tif(numargs >= 3)\n\t\t\t{\n\t\t\t\targ_count ++;\n\t\t\t\tparams[3] = args[2];\n\t\t\t}\n\t\t\tstatic tTJSString split_name(TJS_W(\"split\"));\n\t\t\tarray->FuncCall(0, split_name.c_str(), split_name.GetHint(),\n\t\t\t\tNULL, arg_count, params, array);\n\n\t\t\tif(result) *result = tTJSVariant(array, array);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tarray->Release();\n\t\t\tthrow;\n\t\t}\n\t\tarray->Release();\n\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(trim))\n\t{\n\t\tif(numargs != 0) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\tif(!result) return;\n\n\t\ttjs_int w_len = s_len;\n\t\tconst tjs_char *src = s + s_len - 1;\n\t\t/*  s/\\s+$//;  */\n\t\twhile (w_len > 0 && *src > 0x00 && *src <= 0x20)\n\t\t{\n\t\t\tw_len--;\n\t\t\tsrc--;\n\t\t}\n\t\tsrc = s;\n\t\t/*  s/^\\s+//;  */\n\t\twhile (w_len > 0 && *src > 0x00 && *src <= 0x20)\n\t\t{\n\t\t\tw_len--;\n\t\t\tsrc++;\n\t\t}\n\n\t\t*result = tTJSString(src, w_len);\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(reverse))\n\t{\n\t\tif(numargs != 0) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n \t\tif(!result) return;\n\t\tif(result)\n\t\t{\n\t\t\t*result = s;\n\t\t\tconst tjs_char *pstr = result->GetString();\n\t\t\tif(pstr)\n\t\t\t{\n\t\t\t\ttjs_int w_len = s_len;\n\t\t\t\ttjs_char *dest = (tjs_char*)pstr;    // WARNING!! modification of const\n\t\t\t\tconst tjs_char *src = s + s_len - 1;\n\n\t\t\t\twhile (w_len--)\n\t\t\t\t{\n\t\t\t\t\t*dest++ = *src--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\telse if(TJS_STR_METHOD_IS(repeat))\n\t{\n\t\tif(numargs != 1) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\tif(!result) return;\n\t\ttjs_int count = (tjs_int)*args[0];\n\n\t\tif(count <= 0 || s_len <= 0)\n\t\t{\n\t\t\t*result = TJS_W(\"\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst int destLength = s_len * count;\n\t\ttTJSString new_str = tTJSString(tTJSStringBufferLength(destLength));\n\t\ttjs_char * dest = new_str.Independ();\n\t\twhile(count--)\n\t\t{\n\t\t\tTJS_strcpy(dest, s);\n\t\t\tdest += s_len;\n\t\t}\n\t\t*result = new_str;\n\n\t\treturn;\n\t}\n\n#undef TJS_STR_METHOD_IS\n\n\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, member);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ProcessOctetFunction(const tjs_char *member, const tTJSVariantOctet * target,\n\t\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result)\n{\n\tif(!member) TJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, TJS_W(\"\"));\n\tswitch( member[0] ) {\n\tcase L'u':\n\t\tif( !TJS_strcmp( TJS_W(\"unpack\"), member) ) {\n\t\t\ttjs_error err = TJSOctetUnpack( target, args, numargs, result );\n\t\t\tif( err != TJS_S_OK ) {\n\t\t\t\tTJSThrowFrom_tjs_error( err );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tbreak;\n#if 0\n\tcase L'p':\n\t\tif( !TJS_strcmp( TJS_W(\"pack\"), member) ) {\n\t\t\tif(numargs < 2) TJSThrowFrom_tjs_error(TJS_E_BADPARAMCOUNT);\n\t\t\tttstr templ = *args[0];\n\t\t}\n\t\tbreak;\n#endif\n\t}\n\n\tTJSThrowFrom_tjs_error(TJS_E_MEMBERNOTFOUND, member);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::TypeOf(tTJSVariant &val)\n{\n\t// processes TJS2's typeof operator.\n\tstatic tTJSString void_name(TJSMapGlobalStringMap(TJS_W(\"void\")));\n\tstatic tTJSString Object_name(TJSMapGlobalStringMap(TJS_W(\"Object\")));\n\tstatic tTJSString String_name(TJSMapGlobalStringMap(TJS_W(\"String\")));\n\tstatic tTJSString Integer_name(TJSMapGlobalStringMap(TJS_W(\"Integer\")));\n\tstatic tTJSString Real_name(TJSMapGlobalStringMap(TJS_W(\"Real\")));\n\tstatic tTJSString Octet_name(TJSMapGlobalStringMap(TJS_W(\"Octet\")));\n\n\tswitch(val.Type())\n\t{\n\tcase tvtVoid:\n\t\tval = void_name;   // differs from TJS1\n\t\tbreak;\n\n\tcase tvtObject:\n\t\tval = Object_name;\n\t\tbreak;\n\n\tcase tvtString:\n\t\tval = String_name;\n\t\tbreak;\n\n\tcase tvtInteger:\n\t\tval = Integer_name; // differs from TJS1\n\t\tbreak;\n\n\tcase tvtReal:\n\t\tval = Real_name; // differs from TJS1\n\t\tbreak;\n\n\tcase tvtOctet:\n\t\tval = Octet_name;\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::Eval(tTJSVariant &val,\n\tiTJSDispatch2 * objthis, bool resneed)\n{\n\tif(objthis) objthis->AddRef();\n\ttry\n\t{\n\t\ttTJSVariant res;\n\t\tttstr str(val);\n\t\tif(!str.IsEmpty())\n\t\t{\n\t\t\tif(resneed)\n\t\t\t\tBlock->GetTJS()->EvalExpression(str, &res, objthis);\n\t\t\telse\n\t\t\t\tBlock->GetTJS()->EvalExpression(str, NULL, objthis);\n\t\t}\n\t\tif(resneed) val = res;\n\t}\n\tcatch(...)\n\t{\n\t\tif(objthis) objthis->Release();\n\t\tthrow;\n\t}\n\tif(objthis) objthis->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CharacterCodeOf(tTJSVariant &val)\n{\n\t// puts val's character code on val\n\ttTJSVariantString * str = val.AsString();\n\tif(str)\n\t{\n\t\tconst tjs_char *ch = (const tjs_char*)*str;\n\t\tval = tTVInteger(ch[0]);\n\t\tstr->Release();\n\t\treturn;\n\t}\n\tval = tTVInteger(0);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CharacterCodeFrom(tTJSVariant &val)\n{\n\ttjs_char ch[2];\n\tch[0] = static_cast<tjs_char>(val.AsInteger());\n\tch[1] = 0;\n\tval = ch;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::InstanceOf(const tTJSVariant &name, tTJSVariant &targ)\n{\n\t// checks instance inheritance.\n\ttTJSVariantString *str = name.AsString();\n\tif(str)\n\t{\n\t\ttjs_error hr;\n\t\ttry\n\t\t{\n\t\t\thr = TJSDefaultIsInstanceOf(0, targ, (const tjs_char*)*str, NULL);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tstr->Release();\n\t\t\tthrow;\n\t\t}\n\t\tstr->Release();\n\t\tif(TJS_FAILED(hr)) TJSThrowFrom_tjs_error(hr);\n\n\t\ttarg = (hr == TJS_S_TRUE);\n\t\treturn;\n\t}\n\ttarg = false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::RegisterObjectMember(iTJSDispatch2 * dest)\n{\n\t// register this object member to 'dest' (destination object).\n\t// called when new object is to be created.\n\t// a class to receive member callback from class\n\n\tclass tCallback : public tTJSDispatch\n\t{\n\tpublic:\n\t\tiTJSDispatch2 * Dest; // destination object\n\t\ttjs_error TJS_INTF_METHOD FuncCall(\n\t\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *objthis)\n\t\t{\n\t\t\t// *param[0] = name   *param[1] = flags   *param[2] = value\n\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\tif(!(flags & TJS_STATICMEMBER))\n\t\t\t{\n\t\t\t\ttTJSVariant val = *param[2];\n\t\t\t\tif(val.Type() == tvtObject)\n\t\t\t\t{\n\t\t\t\t\t// change object's objthis if the object's objthis is null\n//\t\t\t\t\tif(val.AsObjectThisNoAddRef() == NULL)\n\t\t\t\t\t\tval.ChangeClosureObjThis(Dest);\n\t\t\t\t}\n\n\t\t\t\tif(Dest->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP|flags,\n\t\t\t\t\tparam[0]->AsStringNoAddRef(), &val, Dest) == TJS_E_NOTIMPL)\n\t\t\t\t\tDest->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|flags,\n\t\t\t\t\tparam[0]->GetString(), NULL, &val, Dest);\n\t\t\t}\n\t\t\tif(result) *result = (tjs_int)(1); // returns true\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t};\n\n\ttCallback callback;\n\tcallback.Dest = dest;\n\n\t// enumerate members\n    tTJSVariantClosure clo(&callback, (iTJSDispatch2*)NULL);\n\tEnumMembers(TJS_IGNOREPROP, &clo, this);\n}\n//---------------------------------------------------------------------------\n#define TJS_DO_SUPERCLASS_PROXY_BEGIN \\\n\t\tstd::vector<tjs_int> &pointer = SuperClassGetter->SuperClassGetterPointer; \\\n\t\tif(pointer.size() != 0) \\\n\t\t{ \\\n\t\t\tstd::vector<tjs_int>::reverse_iterator i; \\\n\t\t\tfor(i = pointer.rbegin(); \\\n\t\t\t\ti != pointer.rend(); i++) \\\n\t\t\t{ \\\n\t\t\t\ttTJSVariant res; \\\n\t\t\t\tSuperClassGetter->ExecuteAsFunction(NULL, NULL, 0, &res, *i); \\\n\t\t\t\ttTJSVariantClosure clo = res.AsObjectClosureNoAddRef();\n\n#define TJS_DO_SUPERCLASS_PROXY_END \\\n\t\t\t\tif(hr != TJS_E_MEMBERNOTFOUND) break; \\\n\t\t\t} \\\n\t\t}\n\ntjs_error TJS_INTF_METHOD  tTJSInterCodeContext::FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tswitch(ContextType)\n\t\t{\n\t\tcase ctTopLevel:\n\t\t\tExecuteAsFunction(\n\t\t\t\tobjthis?objthis:Block->GetTJS()->GetGlobalNoAddRef(),\n\t\t\t\tNULL, 0, result, 0);\n\t\t\tbreak;\n\n\t\tcase ctFunction:\n\t\tcase ctExprFunction:\n\t\tcase ctPropertyGetter:\n\t\tcase ctPropertySetter:\n\t\t\tExecuteAsFunction(objthis, param, numparams, result, 0);\n\t\t\tbreak;\n\n\t\tcase ctClass: // on super class' initialization\n\t\t\tExecuteAsFunction(objthis, param, numparams, result, 0);\n\t\t\tbreak;\n\n\t\tcase ctProperty:\n\t\t\treturn TJS_E_INVALIDTYPE;\n\n\t\tcase ctSuperClassGetter:\n\t\t\tbreak;\n\t\t}\n\n\t\treturn TJS_S_OK;\n\t}\n\n\ttjs_error hr = inherited::FuncCall(flag, membername, hint, result,\n\t\tnumparams, param, objthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.FuncCall(flag, membername, hint, result,\n\t\t\t\tnumparams, param, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD  tTJSInterCodeContext::PropGet(tjs_uint32 flag,\n\tconst tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tif(ContextType == ctProperty)\n\t\t{\n\t\t\t// executed as a property getter\n\t\t\tif(PropGetter)\n\t\t\t\treturn PropGetter->FuncCall(0, NULL, NULL, result, 0, NULL,\n\t\t\t\t\tobjthis);\n\t\t\telse\n\t\t\t\treturn TJS_E_ACCESSDENYED;\n\t\t}\n\t}\n\n\ttjs_error hr = inherited::PropGet(flag, membername, hint, result, objthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.PropGet(flag, membername, hint, result, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD  tTJSInterCodeContext::PropSet(tjs_uint32 flag,\n\tconst tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tif(ContextType == ctProperty)\n\t\t{\n\t\t\t// executed as a property setter\n\t\t\tif(PropSetter)\n\t\t\t\treturn PropSetter->FuncCall(0, NULL, NULL, NULL, 1,\n\t\t\t\t\tconst_cast<tTJSVariant **>(&param), objthis);\n\t\t\telse\n\t\t\t\treturn TJS_E_ACCESSDENYED;\n\n\t\t\t\t// WARNING!! const tTJSVariant ** -> tTJSVariant** force casting\n\t\t}\n\t}\n\n\ttjs_error hr;\n\tif(membername != NULL && ContextType == ctClass && SuperClassGetter)\n\t{\n\t\ttjs_uint32 pseudo_flag =\n\t\t\t(flag & TJS_IGNOREPROP) ? flag : (flag &~ TJS_MEMBERENSURE);\n\t\t\t// member ensuring is temporarily disabled unless TJS_IGNOREPROP\n\n\t\thr = inherited::PropSet(pseudo_flag, membername, hint, param,\n\t\t\tobjthis);\n\t\tif(hr == TJS_E_MEMBERNOTFOUND)\n\t\t{\n\t\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\t\thr = clo.PropSet(pseudo_flag, membername, hint, param,\n\t\t\t\t\tobjthis);\n\t\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t\t}\n\t\t\n\t\tif(hr == TJS_E_MEMBERNOTFOUND && (flag & TJS_MEMBERENSURE))\n\t\t{\n\t\t\t// re-ensure the member for \"this\" object\n\t\t\thr = inherited::PropSet(flag, membername, hint, param,\n\t\t\t\tobjthis);\n\t\t}\n\t}\n\telse\n\t{\n\t\thr = inherited::PropSet(flag, membername, hint, param,\n\t\t\tobjthis);\n\t}\n\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD  tTJSInterCodeContext::CreateNew(tjs_uint32 flag,\n\tconst tjs_char * membername, tjs_uint32 *hint,\n\tiTJSDispatch2 **result, tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tif(ContextType != ctClass) return TJS_E_INVALIDTYPE;\n\n\t\tiTJSDispatch2 *dsp = new inherited();\n\n\t\ttry\n\t\t{\n\t\t\tExecuteAsFunction(dsp, NULL, 0, NULL, 0);\n\t\t\tFuncCall(0, Name, NULL, NULL, numparams, param, dsp);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdsp->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\t*result = dsp;\n\t\treturn TJS_S_OK;\n\t}\n\n\ttjs_error hr = inherited::CreateNew(flag, membername, hint,\n\t\tresult, numparams, param,\n\t\tobjthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.CreateNew(flag, membername, hint, result, numparams, param,\n\t\t\t\tobjthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD  tTJSInterCodeContext::IsInstanceOf(tjs_uint32 flag,\n\tconst tjs_char *membername, tjs_uint32 *hint, const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tswitch(ContextType)\n\t\t{\n\t\tcase ctTopLevel:\n\t\tcase ctPropertySetter:\n\t\tcase ctPropertyGetter:\n\t\tcase ctSuperClassGetter:\n\t\t\tbreak;\n\n\t\tcase ctFunction:\n\t\tcase ctExprFunction:\n\t\t\tif(!TJS_strcmp(classname, TJS_W(\"Function\"))) return TJS_S_TRUE;\n\t\t\tbreak;\n\n\t\tcase ctProperty:\n\t\t\tif(!TJS_strcmp(classname, TJS_W(\"Property\"))) return TJS_S_TRUE;\n\t\t\tbreak;\n\t\t\t\n\t\tcase ctClass:\n\t\t\tif(!TJS_strcmp(classname, TJS_W(\"Class\"))) return TJS_S_TRUE;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\ttjs_error hr = inherited::IsInstanceOf(flag, membername, hint,\n\t\tclassname, objthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.IsInstanceOf(flag, membername, hint, classname, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSInterCodeContext::GetCount(tjs_int *result, const tjs_char *membername,\n\t\ttjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::GetCount(result, membername, hint,\n\t\tobjthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.GetCount(result, membername, hint, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSInterCodeContext::DeleteMember(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint,  iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::DeleteMember(flag, membername, hint,\n\t\tobjthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.DeleteMember(flag, membername, hint, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSInterCodeContext::Invalidate(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::Invalidate(flag, membername, hint,\n\t\tobjthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.Invalidate(flag, membername, hint, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSInterCodeContext::IsValid(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::IsValid(flag, membername, hint,\n\t\tobjthis);\n\n\tif(membername != NULL && hr == TJS_E_MEMBERNOTFOUND &&\n\t\tContextType == ctClass && SuperClassGetter)\n\t{\n\t\t// look up super class\n\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\thr = clo.IsValid(flag, membername, hint, objthis);\n\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSInterCodeContext::Operation(tjs_uint32 flag, const tjs_char *membername,\n\t\ttjs_uint32 *hint, tTJSVariant *result,\n\t\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(ContextType == ctProperty)\n\t\t{\n\t\t\t// operation for property object\n\t\t\treturn tTJSDispatch::Operation(flag, membername, hint, result, param,\n\t\t\t\tobjthis);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn inherited::Operation(flag, membername, hint, result, param,\n\t\t\t\tobjthis);\n\t\t}\n\t}\n\n\t//tjs_error hr;\n\n\tif(membername != NULL && ContextType == ctClass && SuperClassGetter)\n\t{\n\t\ttjs_uint32 pseudo_flag =\n\t\t\t(flag & TJS_IGNOREPROP) ? flag : (flag &~ TJS_MEMBERENSURE);\n\n\t\ttjs_error hr = inherited::Operation(pseudo_flag, membername, hint,\n\t\t\tresult, param, objthis);\n\n\t\tif(hr == TJS_E_MEMBERNOTFOUND)\n\t\t{\n\t\t\t// look up super class\n\t\t\tTJS_DO_SUPERCLASS_PROXY_BEGIN\n\t\t\t\thr = clo.Operation(pseudo_flag, membername, hint, result, param,\n\t\t\t\t\tobjthis);\n\t\t\tTJS_DO_SUPERCLASS_PROXY_END\n\t\t}\n\n\t\tif(hr == TJS_E_MEMBERNOTFOUND)\n\t\t\thr = inherited::Operation(flag, membername, hint, result,\n\t\t\t\tparam, objthis);\n\n\t\treturn hr;\n\t}\n\telse\n\t{\n\t\treturn inherited::Operation(flag, membername, hint, result, param,\n\t\t\tobjthis);\n\t}\n}\n//---------------------------------------------------------------------------\n\n}\n\n"
  },
  {
    "path": "src/core/tjs2/tjsInterCodeExec.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Intermediate Code Execution\n//---------------------------------------------------------------------------\n\n#ifndef tjsInterCodeExecH\n#define tjsInterCodeExecH\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n#if 0\nextern void TJSVariantArrayStackAddRef();\nextern void TJSVariantArrayStackRelease();\n#endif\nextern void TJSVariantArrayStackCompact();\nextern void TJSVariantArrayStackCompactNow();\n\nclass tTJSVariantArrayStack\n{\n\t//\ttTJSCriticalSection CS;\n\n\tstruct tVariantArray\n\t{\n\t\ttTJSVariant *Array;\n\t\ttjs_int Using;\n\t\ttjs_int Allocated;\n\t};\n\n\ttVariantArray * Arrays; // array of array\n\ttjs_int NumArraysAllocated;\n\ttjs_int NumArraysUsing;\n\ttVariantArray * Current;\n\ttjs_int CompactVariantArrayMagic;\n\ttjs_int OperationDisabledCount;\n\n\tvoid IncreaseVariantArray(tjs_int num);\n\n\tvoid DecreaseVariantArray(void);\n\n\tvoid InternalCompact(void);\n\n\npublic:\n\ttTJSVariantArrayStack();\n\t~tTJSVariantArrayStack();\n\n\ttTJSVariant * Allocate(tjs_int num);\n\n\tvoid Deallocate(tjs_int num, tTJSVariant *ptr);\n\n\tvoid Compact() { InternalCompact(); }\n\n}/* *TJSVariantArrayStack = NULL*/;\n//---------------------------------------------------------------------------\n}\n\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsInterCodeGen.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Intermediate Code Context\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n\n#include \"tjsInterCodeGen.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsGlobalStringMap.h\"\n\n#include \"tjs.tab.hpp\"\n#include \"tjsError.h\"\n#include \"tjsUtils.h\"\n#include \"tjsDebug.h\"\n#include \"tjsConstArrayData.h\"\n\n#define LEX_POS (Block->GetLexicalAnalyzer() -> GetCurrentPosition())\n#define NODE_POS (node?node->GetPosition():-1)\n\n\n/*\n\t'intermediate code' means that it is not a final code, yes.\n\tI thought this should be converted to native machine code before execute,\n\tat early phase of developping TJS2.\n\tBut TJS2 intermediate VM code has functions that are too abstract to\n\tbe converted to native machine code, so I decided that I write a code\n\twhich directly drives intermediate VM code.\n*/\n\n\n//---------------------------------------------------------------------------\nnamespace TJS  // following is in the namespace\n{\n//---------------------------------------------------------------------------\n\n\nint __yyerror(char *, void*);\n\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_yylex = 0;\n#endif\n\n//---------------------------------------------------------------------------\nint yylex(YYSTYPE *yylex, void *pm)\n{\n\t// yylex ( is called from bison parser, returns lexical analyzer's return value )\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_yylex);\n#endif\n\n\ttjs_int n;\n\ttjs_int t;\n\tt = ((tTJSScriptBlock *)pm)->GetLexicalAnalyzer()->GetNext(n);\n\tyylex->num = n;\n\treturn t;\n}\n//---------------------------------------------------------------------------\nint _yyerror(const tjs_char * msg, void *pm, tjs_int pos)\n{\n\t// handles errors that happen in the compilation\n\n\ttTJSScriptBlock *sb = (tTJSScriptBlock*)pm;\n\n\t// message conversion\n\tttstr str;\n\t/*if(!TJS_strncmp(msg, TJS_W(\"parse error, expecting \"), 23))\n\t{\n\t\tstr = TJSExpected;\n\t\tif(!TJS_strncmp(msg+23, TJS_W(\"T_SYMBOL\"), 8))\n\t\t\tstr.Replace(TJS_W(\"%1\"), ttstr(TJSSymbol), false);\n\t\telse\n\t\t\tstr.Replace(TJS_W(\"%1\"), msg+23, false);\n\n\t}\n\telse */if(!TJS_strncmp(msg, TJS_W(\"syntax error\"), 11))\n\t{\n\t\tstr = TJSSyntaxError;\n\t\tstr.Replace(TJS_W(\"%1\"), ttstr(msg), false);\n\t}\n\telse\n\t{\n\t\tstr = msg;\n\t}\n\n\ttjs_int errpos =\n\t\tpos == -1 ? sb->GetLexicalAnalyzer()->GetCurrentPosition(): pos;\n\n\tif(sb->CompileErrorCount == 0)\n\t{\n\t\tsb->SetFirstError(str.c_str(), errpos);\n\t}\n\n\tsb->CompileErrorCount++;\n\n\ttjs_char buf[43];\n\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\" at line %d\"), 1+sb->SrcPosToLine(errpos));\n\tstr += buf;\n\n\tsb->GetTJS()->OutputToConsole(str.c_str());\n\n\treturn 0;\n}\n\n//---------------------------------------------------------------------------\nint __yyerror(char * msg, void * pm)\n{\n\t// yyerror ( for bison )\n\tttstr str(msg);\n\treturn _yyerror(str.c_str(), pm);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSExprNode -- expression node\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\ntTJSExprNode::tTJSExprNode()\n{\n\tOp = 0;\n\tNodes = NULL;\n\tVal = NULL;\n\tPosition = -1;\n}\n//---------------------------------------------------------------------------\nvoid tTJSExprNode::Clear()\n{\n\tif(Nodes) delete Nodes;\n\tif(Val) delete Val;\n\tNodes = NULL;\n\tVal = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSExprNode::Add(tTJSExprNode *n)\n{\n\tif(!Nodes)\n\t\tNodes = new std::vector<tTJSExprNode*>;\n\tNodes->push_back(n);\n}\n//---------------------------------------------------------------------------\nvoid tTJSExprNode::AddArrayElement(const tTJSVariant & val)\n{\n\tstatic tTJSString ss_add(TJS_W(\"add\"));\n\ttTJSVariant arg(val);\n\ttTJSVariant *args[1] = {&arg};\n\tVal->AsObjectClosureNoAddRef().FuncCall(0, ss_add.c_str(), ss_add.GetHint(),\n\t\tNULL, 1, args, NULL);\n}\n//---------------------------------------------------------------------------\nvoid tTJSExprNode::AddDictionaryElement(const tTJSString & name, const tTJSVariant & val)\n{\n\ttTJSString membername(name);\n\tVal->AsObjectClosureNoAddRef().PropSet(TJS_MEMBERENSURE, membername.c_str(),\n\t\tmembername.GetHint(), &val, NULL);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSInterCodeContext -- intermediate context\n//---------------------------------------------------------------------------\nstatic tjs_int TJSGetContextHashSize(tTJSContextType type)\n{\n\tswitch(type)\n\t{\n\tcase ctTopLevel:\t\treturn 0;\n\tcase ctFunction:\t\treturn 1;\n\tcase ctExprFunction: \treturn 1;\n\tcase ctProperty:\t\treturn 1;\n\tcase ctPropertySetter:\treturn 0;\n\tcase ctPropertyGetter:\treturn 0;\n\tcase ctClass:\t\t\treturn TJS_NAMESPACE_DEFAULT_HASH_BITS;\n\tcase ctSuperClassGetter:return 0;\n\tdefault:\t\t\t\treturn TJS_NAMESPACE_DEFAULT_HASH_BITS;\n\t}\n}\n//---------------------------------------------------------------------------\n// is bytecode export\nbool tTJSInterCodeContext::IsBytecodeCompile = false;\n//---------------------------------------------------------------------------\ntTJSInterCodeContext::tTJSInterCodeContext(tTJSInterCodeContext *parent,\n\tconst tjs_char *name, tTJSScriptBlock *block, tTJSContextType type) :\n\t\tinherited(TJSGetContextHashSize(type)), Properties(NULL)\n{\n\tinherited::CallFinalize = false;\n\t\t// this notifies to the class ancestor - \"tTJSCustomObject\", not to\n\t\t// call \"finalize\" TJS method at the invalidation.\n\n\tParent = parent;\n\n\tPropGetter = PropSetter = SuperClassGetter = NULL;\n\n\tCodeArea = NULL;\n\tCodeAreaCapa = 0;\n\tCodeAreaSize = 0;\n\n\t_DataArea = NULL;\n\t_DataAreaCapa = 0;\n\t_DataAreaSize = 0;\n\tDataArea = NULL;\n\tDataAreaSize = 0;\n\n\tFrameBase = 1;\n\n\tSuperClassExpr = NULL;\n\n\tMaxFrameCount = 0;\n\tMaxVariableCount = 0;\n\n\tFuncDeclArgCount = 0;\n\tFuncDeclUnnamedArgArrayBase = 0;\n\tFuncDeclCollapseBase = -1;\n\n\tFunctionRegisterCodePoint = 0;\n\n\n\tPrevSourcePos = -1;\n\tSourcePosArraySorted = false;\n\tSourcePosArray = NULL;\n\tSourcePosArrayCapa = 0;\n\tSourcePosArraySize = 0;\n\n#ifdef ENABLE_DEBUGGER\n\tDebuggerRegisterArea = NULL;\n\tif( Parent ) Parent->AddRef();\n#endif\t// ENABLE_DEBUGGER\n\n\tif(name)\n\t{\n\t\tName = new tjs_char[TJS_strlen(name)+1];\n\t\tTJS_strcpy(Name, name);\n\t}\n\telse\n\t{\n\t\tName = NULL;\n\t}\n\n\ttry\n\t{\n\t\tAsGlobalContextMode = false;\n\n\t\tContextType = type;\n\n\t\tswitch(ContextType) // decide variable reservation count with context type\n\t\t{\n\t\t\tcase ctTopLevel:\t\tVariableReserveCount = 2; break;\n\t\t\tcase ctFunction:\t\tVariableReserveCount = 2; break;\n\t\t\tcase ctExprFunction: \tVariableReserveCount = 2; break;\n\t\t\tcase ctProperty:\t\tVariableReserveCount = 0; break;\n\t\t\tcase ctPropertySetter:\tVariableReserveCount = 2; break;\n\t\t\tcase ctPropertyGetter:\tVariableReserveCount = 2; break;\n\t\t\tcase ctClass:\t\t\tVariableReserveCount = 2; break;\n\t\t\tcase ctSuperClassGetter:VariableReserveCount = 2; break;\n\t\t}\n\n\n\t\tBlock = block;\n\t\tblock->Add(this);\n\t\tTJSVariantArrayStack = block->GetTJS()->GetVariantArrayStack();\n\t\tif(ContextType != ctTopLevel) Block->AddRef();\n\t\t\t// owner ScriptBlock hooks global object, so to avoid mutual reference lock.\n\n\n\t\tif(ContextType == ctClass)\n\t\t{\n\t\t\t// add class information to the class instance information\n\t\t\tif(MaxFrameCount < 1) MaxFrameCount = 1;\n\n\t\t\ttjs_int dp = PutData(tTJSVariant(Name));\n\t\t\t// const %1, name\n\t\t\t// addci %-1, %1\n\t\t\t// cl %1\n\t\t\tPutCode(VM_CONST, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(1));\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp));\n\t\t\tPutCode(VM_ADDCI);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-1));\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(1));\n\t\t\tPutCode(VM_CL);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(1));\n\n\t\t\t// update FunctionRegisterCodePoint\n\t\t\tFunctionRegisterCodePoint = CodeAreaSize; // update FunctionRegisterCodePoint\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] Name;\n\t\tthrow;\n\t}\n#ifdef ENABLE_DEBUGGER\n\t// Â[Jϐ͍폜Ă܂\n\tTJSDebuggerClearLocalVariable( GetClassName().c_str(), GetName(), Block->GetName(), FunctionRegisterCodePoint );\n#endif\t// ENABLE_DEBUGGER\n}\n\n//---------------------------------------------------------------------------\n// for Byte code\ntTJSInterCodeContext::tTJSInterCodeContext( tTJSScriptBlock *block, const tjs_char *name, tTJSContextType type,\n\ttjs_int32* code, tjs_int codeSize, tTJSVariant* data, tjs_int dataSize,\n\ttjs_int varcount, tjs_int verrescount, tjs_int maxframe, tjs_int argcount, tjs_int arraybase, tjs_int colbase, bool srcsorted,\n\ttSourcePos* srcPos, tjs_int srcPosSize, std::vector<tjs_int>& superpointer ) :\n\tinherited(TJSGetContextHashSize(type)), Properties(NULL)\n{\n\tinherited::CallFinalize = false;\n\tParent = NULL;\n\tPropGetter = PropSetter = SuperClassGetter = NULL;\n\n\tCodeArea = code;\n\tCodeAreaCapa = codeSize;\n\tCodeAreaSize = codeSize;\n\n\t_DataArea = NULL;\n\t_DataAreaCapa = 0;\n\t_DataAreaSize = 0;\n\tDataArea = data;\n\tDataAreaSize = dataSize;\n\n\t// copy\n\tsize_t size = superpointer.size();\n\tSuperClassGetterPointer.reserve(size);\n\tfor( size_t i = 0; i < size; i++ ) {\n\t\tSuperClassGetterPointer.push_back( superpointer[i] );\n\t}\n\n\tFrameBase = 1; // for code generate\n\tSuperClassExpr = NULL; // for code generate\n\n\tMaxFrameCount = maxframe;\n\tMaxVariableCount = varcount;\n\tVariableReserveCount = verrescount; //\n\n\tFuncDeclArgCount = argcount;\n\tFuncDeclUnnamedArgArrayBase = arraybase;\n\tFuncDeclCollapseBase = colbase;\n\n\tFunctionRegisterCodePoint = 0;\n\n\n\tPrevSourcePos = -1;\n\tSourcePosArraySorted = true;\n\tSourcePosArray = srcPos;\n\tSourcePosArrayCapa = srcPosSize;\n\tSourcePosArraySize = srcPosSize;\n\n#ifdef ENABLE_DEBUGGER\n\tDebuggerRegisterArea = NULL;\n#endif\t// ENABLE_DEBUGGER\n\n\tif( name ) {\n\t\tName = new tjs_char[TJS_strlen(name)+1];\n\t\tTJS_strcpy(Name, name);\n\t} else {\n\t\tName = NULL;\n\t}\n\n\ttry {\n\t\tAsGlobalContextMode = false;\n\t\tContextType = type;\n\t\tBlock = block;\n\t\tTJSVariantArrayStack = block->GetTJS()->GetVariantArrayStack();\n\t} catch(...) {\n\t\tdelete [] Name;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSInterCodeContext::~tTJSInterCodeContext()\n{\n\tif(Name) delete [] Name;\n\tName = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::Finalize(void)\n{\n\tif(PropSetter) PropSetter->Release(), PropSetter = NULL;\n\tif(PropGetter) PropGetter->Release(), PropGetter = NULL;\n\tif(SuperClassGetter) SuperClassGetter->Release(), SuperClassGetter = NULL;\n\n\tif(CodeArea) TJS_free(CodeArea), CodeArea = NULL;\n\tif(_DataArea)\n\t{\n\t\tfor(tjs_int i=0; i<_DataAreaSize; i++) delete _DataArea[i];\n\t\tTJS_free(_DataArea);\n\t\t_DataArea = NULL;\n\t}\n\tif(DataArea)\n\t{\n\t\tdelete [] DataArea;\n\t\tDataArea = NULL;\n\t}\n\n\tBlock->Remove(this);\n\n\tif(ContextType!=ctTopLevel && Block) Block->Release();\n\n\tNamespace.Clear();\n\n\tClearNodesToDelete();\n\n\tif(SourcePosArray) TJS_free(SourcePosArray), SourcePosArray = NULL;\n\t\n#ifdef ENABLE_DEBUGGER\n\tif( Parent ) {\n\t\tParent->Release();\n\t\tParent = NULL;\n\t}\n#endif\t// ENABLE_DEBUGGER\n\tinherited::Finalize();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ClearNodesToDelete(void)\n{\n\tif(NodeToDeleteVector.size())\n\t{\n\t\tfor(tjs_int i=(tjs_int)(NodeToDeleteVector.size()-1); i>=0; i--)\n\t\t{\n\t\t\tdelete NodeToDeleteVector[i];\n\t\t}\n\t}\n\n\tNodeToDeleteVector.clear();\n}\n//---------------------------------------------------------------------------\nconst tjs_char* tTJSInterCodeContext::GetContextTypeName() const\n{\n\tswitch(ContextType)\n\t{\n\tcase ctTopLevel:\t\treturn TJS_W(\"top level script\");\n\tcase ctFunction:\t\treturn TJS_W(\"function\");\n\tcase ctExprFunction:\treturn TJS_W(\"function expression\");\n\tcase ctProperty:\t\treturn TJS_W(\"property\");\n\tcase ctPropertySetter:\treturn TJS_W(\"property setter\");\n\tcase ctPropertyGetter:\treturn TJS_W(\"property getter\");\n\tcase ctClass:\t\t\treturn TJS_W(\"class\");\n\tcase ctSuperClassGetter:return TJS_W(\"super class getter proxy\");\n\tdefault:\t\t\t\treturn TJS_W(\"unknown\");\n\t}\n}\n//---------------------------------------------------------------------------\nttstr tTJSInterCodeContext::GetShortDescription() const\n{\n\tttstr ret(TJS_W(\"(\") + ttstr(GetContextTypeName()) + TJS_W(\")\"));\n\n\tconst tjs_char *name;\n\tif(ContextType == ctPropertySetter || ContextType == ctPropertyGetter)\n\t{\n\t\tif(Parent)\n\t\t\tname = Parent->Name;\n\t\telse\n\t\t\tname = NULL;\n\t}\n\telse\n\t{\n\t\tname = Name;\n\t}\n\n\tif(name) ret += TJS_W(\" \") + ttstr(name);\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nttstr tTJSInterCodeContext::GetShortDescriptionWithClassName() const\n{\n\tttstr ret(TJS_W(\"(\") + ttstr(GetContextTypeName()) + TJS_W(\")\"));\n\n\ttTJSInterCodeContext * parent;\n\n\tconst tjs_char *classname;\n\tconst tjs_char *name;\n\n\tif(ContextType == ctPropertySetter || ContextType == ctPropertyGetter)\n\t\tparent = Parent ? Parent->Parent : NULL;\n\telse\n\t\tparent = Parent;\n\n\tif(parent)\n\t\tclassname = parent->Name;\n\telse\n\t\tclassname = NULL;\n\n\tif(ContextType == ctPropertySetter || ContextType == ctPropertyGetter)\n\t{\n\t\tif(Parent)\n\t\t\tname = Parent->Name;\n\t\telse\n\t\t\tname = NULL;\n\t}\n\telse\n\t{\n\t\tname = Name;\n\t}\n\n\tif(name)\n\t{\n\t\tret += TJS_W(\" \");\n\t\tif(classname) ret += ttstr(classname) + TJS_W(\".\");\n\t\tret += ttstr(name);\n\t}\n\n\treturn ret;\n}\n#ifdef ENABLE_DEBUGGER\n//---------------------------------------------------------------------------\nttstr tTJSInterCodeContext::GetClassName() const\n{\n\tttstr ret;\n\n\ttTJSInterCodeContext * parent;\n\n\tconst tjs_char *classname;\n\n\tif(ContextType == ctPropertySetter || ContextType == ctPropertyGetter)\n\t\tparent = Parent ? Parent->Parent : NULL;\n\telse\n\t\tparent = Parent;\n\n\tif(parent)\n\t\tclassname = parent->Name;\n\telse\n\t\tclassname = NULL;\n\n\tif( classname ) ret = ttstr(classname);\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nttstr tTJSInterCodeContext::GetSelfClassName() const\n{\n\tttstr ret;\n\n\tconst tTJSInterCodeContext* parent;\n\n\tconst tjs_char *classname;\n\n\tif(ContextType == ctPropertySetter || ContextType == ctPropertyGetter)\n\t\tparent = Parent ? Parent->Parent : NULL;\n\telse if( ContextType == ctClass )\n\t\tparent = this;\n\telse\n\t\tparent = Parent;\n\n\tif(parent)\n\t\tclassname = parent->Name;\n\telse\n\t\tclassname = NULL;\n\n\tif( classname ) ret = ttstr(classname);\n\n\treturn ret;\n}\n#endif\t// ENABLE_DEBUGGER\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::OutputWarning(const tjs_char *msg, tjs_int pos)\n{\n\tttstr str(TJSWarning);\n\n\tstr += msg;\n\n\ttjs_int errpos =\n\t\tpos == -1 ? Block->GetLexicalAnalyzer()->GetCurrentPosition(): pos;\n\n\tstr += TJS_W(\" at \");\n\tstr += Block->GetName();\n\n\ttjs_char buf[43];\n\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\" line %d\"), 1+Block->SrcPosToLine(errpos));\n\tstr += buf;\n\n\tBlock->GetTJS()->OutputToConsole(str.c_str());\n}\n//---------------------------------------------------------------------------\n\n#define TJS_INC_SIZE 256\n\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_PutCode = 0;\n#endif\n\ntjs_int tTJSInterCodeContext::PutCode(tjs_int32 num, tjs_int32 pos)\n{\n\t// puts code\n\t// num = operation code\n\t// pos = position in the script\n\t// this returns code address of newly put code\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_PutCode);\n#endif\n\n\tif(CodeAreaSize >= CodeAreaCapa)\n\t{\n\t\t// must inflate the code area\n\t\tCodeArea = (tjs_int32*)TJS_realloc(CodeArea,\n\t\t\tsizeof(tjs_int32)*(CodeAreaCapa + TJS_INC_SIZE));\n\t\tif(!CodeArea) TJS_eTJSScriptError(TJSInsufficientMem, Block, pos);\n\t\tCodeAreaCapa += TJS_INC_SIZE;\n\t}\n\n\tif(pos!=-1)\n\t{\n\t\tif(PrevSourcePos != pos)\n\t\t{\n\t\t\tPrevSourcePos = pos;\n\t\t\tSourcePosArraySorted = false;\n\t\t\tif(!SourcePosArray)\n\t\t\t{\n\t\t\t\tSourcePosArray = (tSourcePos*)TJS_malloc(TJS_INC_SIZE *\n\t\t\t\t\tsizeof(tSourcePos));\n\t\t\t\tif(!SourcePosArray) _yyerror(TJSInsufficientMem, Block);\n\t\t\t\tSourcePosArrayCapa = TJS_INC_SIZE;\n\t\t\t\tSourcePosArraySize = 0;\n\t\t\t}\n\t\t\tif(SourcePosArraySize >= SourcePosArrayCapa)\n\t\t\t{\n\t\t\t\tSourcePosArray = (tSourcePos*)TJS_realloc(SourcePosArray,\n\t\t\t\t\t(SourcePosArrayCapa + TJS_INC_SIZE) * sizeof(tSourcePos));\n\t\t\t\tif(!SourcePosArray) TJS_eTJSScriptError(TJSInsufficientMem, Block, pos);\n\t\t\t\tSourcePosArrayCapa += TJS_INC_SIZE;\n\t\t\t}\n\t\t\tSourcePosArray[SourcePosArraySize].CodePos = CodeAreaSize;\n\t\t\tSourcePosArray[SourcePosArraySize].SourcePos = pos;\n\t\t\tSourcePosArraySize++;\n\t\t}\n\t}\n\n\tCodeArea[CodeAreaSize] = num;\n\n\treturn CodeAreaSize++;\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_PutData = 0;\n#endif\n\ntjs_int tTJSInterCodeContext::PutData(const tTJSVariant &val)\n{\n\t// puts data\n\t// val = data\n\t// return the data address\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_PutData);\n#endif\n\n\tif(_DataAreaSize >= _DataAreaCapa)\n\t{\n\t\t// inflation of data area\n\t\t_DataArea = (tTJSVariant**)TJS_realloc(_DataArea,\n\t\t\tsizeof(tTJSVariant*)*(_DataAreaCapa + TJS_INC_SIZE));\n\t\tif(!_DataArea) TJS_eTJSScriptError(TJSInsufficientMem, Block, LEX_POS);\n\t\t_DataAreaCapa += TJS_INC_SIZE;\n\t}\n\n\t// search same data in the area\n\tif(_DataAreaSize)\n\t{\n\t\ttTJSVariant **ptr = _DataArea + _DataAreaSize-1;\n\t\ttjs_int count = 0;\n\t\twhile(count < 20 // is waste of time if it exceeds 20 limit?\n\t\t\t)\n\t\t{\n\t\t\tif((*ptr)->DiscernCompareStrictReal(val))\n\t\t\t{\n\t\t\t\treturn (tjs_int)(ptr - _DataArea); // re-use this\n\t\t\t}\n\t\t\tcount ++;\n\t\t\tif(ptr == _DataArea) break;\n\t\t\tptr --;\n\t\t}\n\t}\n\n\ttTJSVariant *v;\n\tif(val.Type() == tvtString)\n\t{\n\t\t// check whether the string can be shared\n\t\tv = new tTJSVariant(TJSMapGlobalStringMap(val));\n\t}\n\telse\n\t{\n\t\tv = new tTJSVariant(val);\n\t}\n\t_DataArea[_DataAreaSize] = v;\n\n\treturn _DataAreaSize++;\n}\n//---------------------------------------------------------------------------\nint TJS_USERENTRY tTJSInterCodeContext::tSourcePos::\n\tSortFunction(const void *a, const void *b)\n{\n\tconst tSourcePos *aa = (const tSourcePos*)a;\n\tconst tSourcePos *bb = (const tSourcePos*)b;\n\treturn aa->CodePos - bb->CodePos;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SortSourcePos()\n{\n\tif(!SourcePosArraySorted)\n\t{\n\t\tqsort(SourcePosArray, SourcePosArraySize, sizeof(tSourcePos),\n\t\t\ttSourcePos::SortFunction);\n\t\tSourcePosArraySorted = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::FixCode(void)\n{\n\t// code re-positioning and patch processing\n\t// TODO: tTJSInterCodeContext::FixCode fasten the algorithm\n\n\t// create 'regmember' instruction to register class members to \n\t// newly created object\n\tif(ContextType == ctClass)\n\t{\n\t\t// generate a code\n\t\ttjs_int32 * code = new tjs_int32[1];\n\t\tcode[0] = VM_REGMEMBER;\n\n\t\t// make a patch information\n\t\t// use FunctionRegisterCodePoint for insertion point\n\t\tFixList.push_back(tFixData(FunctionRegisterCodePoint, 0, 1, code, true));\n\t}\n\n\t// process funtion reservation to enable backward reference of\n\t// global/method functions\n\tif(NonLocalFunctionDeclVector.size() >= 1)\n\t{\n\t\tif(MaxFrameCount < 1) MaxFrameCount = 1;\n\n\t\tstd::vector<tNonLocalFunctionDecl>::iterator func;\n\n\t\t// make function registration code to objthis\n\n\t\t// compute codesize\n\t\ttjs_int codesize = 2;\n\t\tfor(func = NonLocalFunctionDeclVector.begin();\n\t\t\tfunc!= NonLocalFunctionDeclVector.end();\n\t\t\tfunc++)\n\t\t{\n\t\t\tif(func->ChangeThis) codesize += 10; else codesize += 7;\n\t\t}\n\n\t\ttjs_int32 *code = new tjs_int32[codesize];\n\n\t\t// generate code\n\t\ttjs_int32 *codep = code;\n\t\tfor(func = NonLocalFunctionDeclVector.begin();\n\t\t\tfunc!= NonLocalFunctionDeclVector.end();\n\t\t\tfunc++)\n\t\t{\n\t\t\t// const %1, #funcdata\n\t\t\t*(codep++) = VM_CONST;\n\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(1);\n\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(func->DataPos);\n\n\t\t\t// chgthis %1, %-1\n\t\t\tif(func->ChangeThis)\n\t\t\t{\n\t\t\t\t*(codep++) = VM_CHGTHIS;\n\t\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(1);\n\t\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(-1);\n\t\t\t}\n\n\t\t\t// spds %-1.#funcname, %1\n\t\t\t*(codep++) = VM_SPDS;\n\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(-1); // -1 =  objthis\n\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(func->NameDataPos);\n\t\t\t*(codep++) = TJS_TO_VM_REG_ADDR(1);\n\t\t}\n\n\t\t// cl %1\n\t\t*(codep++) = VM_CL;\n\t\t*(codep++) = TJS_TO_VM_REG_ADDR(1);\n\n\t\t// make a patch information\n\t\tFixList.push_back(tFixData(FunctionRegisterCodePoint, 0, codesize, code, true));\n\n\t\tNonLocalFunctionDeclVector.clear();\n\t}\n\n\t// sort SourcePosVector\n\tSortSourcePos();\n\n\t// re-position patch\n\tstd::list<tFixData>::iterator fix;\n\n\tfor(fix = FixList.begin(); fix!=FixList.end(); fix++)\n\t{\n\t\tstd::list<tjs_int>::iterator jmp;\n\t\tfor(jmp = JumpList.begin(); jmp!=JumpList.end(); jmp++)\n\t\t{\n\t\t\ttjs_int jmptarget = CodeArea[*jmp + 1] + *jmp;\n\t\t\tif(*jmp >= fix->StartIP && *jmp < fix->Size + fix->StartIP)\n\t\t\t{\n\t\t\t\t// jmp is in the re-positioning target -> delete\n\t\t\t\tjmp = JumpList.erase(jmp);\n\t\t\t}\n\t\t\telse if((fix->BeforeInsertion?\n\t\t\t\t(jmptarget < fix->StartIP):(jmptarget <= fix->StartIP)\n\t\t\t\t&& *jmp > fix->StartIP + fix->Size) ||\n\t\t\t\t(*jmp < fix->StartIP && jmptarget >= fix->StartIP + fix->Size))\n\t\t\t{\n\t\t\t\t// jmp and its jumping-target is in the re-positioning target\n\t\t\t\tCodeArea[*jmp + 1] += fix->NewSize - fix->Size;\n\t\t\t}\n\n\t\t\tif(*jmp >= fix->StartIP + fix->Size)\n\t\t\t{\n\t\t\t\t// fix up jmp\n\t\t\t\t*jmp += fix->NewSize - fix->Size;\n\t\t\t}\n\t\t}\n\n\t\t// move the code\n\t\tif(fix->NewSize > fix->Size)\n\t\t{\n\t\t\t// when code inflates on fixing\n\t\t\tCodeArea = (tjs_int32*)TJS_realloc(CodeArea,\n\t\t\t\tsizeof(tjs_int32)*(CodeAreaSize + (fix->NewSize - fix->Size)));\n\t\t\tif(!CodeArea) TJS_eTJSScriptError(TJSInsufficientMem, Block, 0);\n\t\t}\n\n\t\tif(CodeAreaSize - (fix->StartIP + fix->Size) > 0)\n\t\t{\n\t\t\t// move the existing code\n\t\t\tmemmove(CodeArea + fix->StartIP + fix->NewSize,\n\t\t\t\tCodeArea + fix->StartIP + fix->Size,\n\t\t\t\tsizeof(tjs_int32)* (CodeAreaSize - (fix->StartIP + fix->Size)));\n\n\t\t\t// move sourcepos\n\t\t\tfor(tjs_int i = 0; i < SourcePosArraySize; i++)\n\t\t\t{\n\t\t\t\tif(SourcePosArray[i].CodePos >= fix->StartIP + fix->Size)\n\t\t\t\t\tSourcePosArray[i].CodePos += fix->NewSize - fix->Size;\n\t\t\t}\n\t\t}\n\n\t\tif(fix->NewSize && fix->Code)\n\t\t{\n\t\t\t// copy the new code\n\t\t\tmemcpy(CodeArea + fix->StartIP, fix->Code, sizeof(tjs_int32)*fix->NewSize);\n\t\t}\n\n\t\tCodeAreaSize += fix->NewSize - fix->Size;\n\t}\n\n\t// eliminate redundant jump codes\n\tfor(std::list<tjs_int>::iterator jmp = JumpList.begin();\n\t\tjmp!=JumpList.end(); jmp++)\n\t{\n\t\ttjs_int32 jumptarget = CodeArea[*jmp + 1] + *jmp;\n\t\ttjs_int32 jumpcode = CodeArea[*jmp];\n\t\ttjs_int addr = *jmp;\n\t\taddr += CodeArea[addr + 1];\n\t\tfor(;;)\n\t\t{\n\t\t\tif(CodeArea[addr] == VM_JMP ||\n\t\t\t\t(CodeArea[addr] == jumpcode && (jumpcode == VM_JF || jumpcode == VM_JNF)))\n\t\t\t{\n\t\t\t\t// simple jump code or\n\t\t\t\t// JF after JF or JNF after JNF\n\t\t\t\tjumptarget = CodeArea[addr + 1] + addr; // skip jump after jump\n\t\t\t\tif(CodeArea[addr + 1] != 0)\n\t\t\t\t\taddr += CodeArea[addr + 1];\n\t\t\t\telse\n\t\t\t\t\tbreak; // must be an error\n\t\t\t}\n\t\t\telse if((CodeArea[addr] == VM_JF && jumpcode == VM_JNF) ||\n\t\t\t\t(CodeArea[addr] == VM_JNF && jumpcode == VM_JF))\n\t\t\t{\n\t\t\t\t// JF after JNF or JNF after JF\n\t\t\t\tjumptarget = addr + 2;\n\t\t\t\t\t// jump code after jump will not jump\n\t\t\t\taddr += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// other codes\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tCodeArea[*jmp + 1] = jumptarget - *jmp;\n\t}\n\n\t// convert jump addresses to VM address\n\tfor(std::list<tjs_int>::iterator jmp = JumpList.begin();\n\t\tjmp!=JumpList.end(); jmp++)\n\t{\n\t\tCodeArea[*jmp + 1] = TJS_TO_VM_CODE_ADDR(CodeArea[*jmp + 1]);\n\t}\n\n\tJumpList.clear();\n\tFixList.clear();\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::RegisterFunction()\n{\n\t// registration of function to the parent's context\n\n\tif(!Parent) return;\n\n\tif(ContextType == ctPropertySetter)\n\t{\n\t\tParent->PropSetter = this; AddRef();\n\t\treturn;\n\t}\n\tif(ContextType == ctPropertyGetter)\n\t{\n\t\tParent->PropGetter = this; AddRef();\n\t\treturn;\n\t}\n\n\tif(ContextType == ctSuperClassGetter)\n\t{\n\t\treturn; // these are already registered to parent context\n\t}\n\n\n\tif( ContextType != ctFunction &&  // ctExprFunction is not concerned here\n\t\tContextType != ctProperty &&\n\t\tContextType != ctClass)\n\t{\n\t\treturn;\n\t}\n\n\n\ttjs_int data = -1;\n\n\tif(Parent->ContextType == ctTopLevel)\n\t{\n\t\ttTJSVariant val;\n\t\tval = this;\n\t\tdata = Parent->PutData(val);\n\t\tval = Name;\n\t\ttjs_int name = Parent->PutData(val);\n\t\tbool changethis = ContextType == ctFunction ||\n\t\t\t\t\t\t\tContextType == ctProperty;\n\t\tParent->NonLocalFunctionDeclVector.push_back(\n\t\t\ttNonLocalFunctionDecl(data, name, changethis));\n\t}\n\n\tif(ContextType == ctFunction && Parent->ContextType == ctFunction)\n\t{\n\t\t// local functions\n\t\t// adds the function as a parent's local variable\n\t\tif(data == -1)\n\t\t{\n\t\t\ttTJSVariant val;\n\t\t\tval = this;\n\t\t\tdata = Parent->PutData(val);\n\t\t}\n\n\t\tParent->InitLocalFunction(Name, data);\n\n\t}\n\n\tif( Parent->ContextType == ctFunction ||\n\t\tParent->ContextType == ctClass)\n\t{\n\t\tif( IsBytecodeCompile ) { // for bytecode export\n\t\t\tif( Properties == NULL ) Properties = new std::vector<tProperty*>();\n\t\t\tProperties->push_back( new tProperty( Name, this ) );\n\t\t}\n\n\t\t// register members to the parent object\n\t\ttTJSVariant val = this;\n\t\tParent->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, Name, NULL, &val, Parent);\n\t}\n\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_Commit = 0;\n#endif\n\nvoid tTJSInterCodeContext::Commit()\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_Commit);\n#endif\n\n\t// some context-related processing at final, and commits it\n\tif(ContextType == ctClass)\n\t{\n\t\t// clean up super class proxy\n\t\tif(SuperClassGetter) SuperClassGetter->Commit();\n\t}\n\n\tif(ContextType != ctProperty && ContextType != ctSuperClassGetter)\n\t{\n\t\tPutCode(VM_SRV, LEX_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(0));\n\t\tPutCode(VM_RET);\n\t}\n\n\tRegisterFunction();\n\n\tif(ContextType != ctProperty && ContextType != ctSuperClassGetter) FixCode();\n\n\tif(!DataArea)\n\t{\n\t\tDataArea = new tTJSVariant[_DataAreaSize];\n\t\tDataAreaSize = _DataAreaSize;\n\n\t\tfor(tjs_int i = 0; i<_DataAreaSize; i++)\n\t\t{\n\t\t\tDataArea[i].CopyRef( *_DataArea[i]);\n\t\t}\n\n\t\tif(_DataArea)\n\t\t{\n\t\t\tfor(tjs_int i = 0; i<_DataAreaSize; i++) delete _DataArea[i];\n\t\t\tTJS_free(_DataArea);\n\t\t\t_DataArea = NULL;\n\t\t}\n\t}\n\n\tif(ContextType == ctSuperClassGetter)\n\t\tMaxVariableCount = 2; // always 2\n\telse\n\t\tMaxVariableCount = Namespace.GetMaxCount();\n\n\tSuperClassExpr = NULL;\n\n\tClearNodesToDelete();\n\n\t// compact SourcePosArray to just size\n\tif(SourcePosArraySize && SourcePosArray)\n\t{\n\t\tSourcePosArray = (tSourcePos*)TJS_realloc(SourcePosArray,\n\t\t\tSourcePosArraySize * sizeof(tSourcePos));\n\t\tif(!SourcePosArray) TJS_eTJSScriptError(TJSInsufficientMem, Block, 0);\n\t\tSourcePosArrayCapa = SourcePosArraySize;\n\t}\n\n\t// compact CodeArea to just size\n\tif(CodeAreaSize && CodeArea)\n\t{\n\t\t// must inflate the code area\n\t\tCodeArea = (tjs_int32*)TJS_realloc(CodeArea,\n\t\t\tsizeof(tjs_int32)*CodeAreaSize);\n\t\tif(!CodeArea) TJS_eTJSScriptError(TJSInsufficientMem, Block, 0);\n\t\tCodeAreaCapa = CodeAreaSize;\n\t}\n\n\n\t// set object type info for debugging\n\tif(TJSObjectHashMapEnabled())\n\t\tTJSObjectHashSetType(this, GetShortDescriptionWithClassName());\n\n\n\t// we do thus nasty thing because the std::vector does not free its storage\n\t// even we call 'clear' method...\n#define RE_CREATE(place, type, classname) (&place)->type::~classname(); \\\n\tnew (&place) type ();\n\n\tRE_CREATE(NodeToDeleteVector, std::vector<tTJSExprNode *>, vector);\n\tRE_CREATE(CurrentNodeVector, std::vector<tTJSExprNode *>, vector);\n\tRE_CREATE(FuncArgStack, std::stack<tFuncArg>, stack);\n\tRE_CREATE(ArrayArgStack, std::stack<tArrayArg>, stack);\n\tRE_CREATE(NestVector, std::vector<tNestData>, vector);\n\tRE_CREATE(JumpList, std::list<tjs_int>, list);\n\tRE_CREATE(FixList, std::list<tFixData>, list);\n\tRE_CREATE(NonLocalFunctionDeclVector, std::vector<tNonLocalFunctionDecl>, vector);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::CodePosToSrcPos(tjs_int codepos) const\n{\n\t// converts from\n\t// CodeArea oriented position to source oriented position\n\tif(!SourcePosArray) return 0;\n\n\tconst_cast<tTJSInterCodeContext*>(this)->SortSourcePos();\n\n\ttjs_uint s = 0;\n\ttjs_uint e = SourcePosArraySize;\n\tif(e==0) return 0;\n\twhile(true)\n\t{\n\t\tif(e-s <= 1) return SourcePosArray[s].SourcePos;\n\t\ttjs_uint m = s + (e-s)/2;\n\t\tif(SourcePosArray[m].CodePos > codepos)\n\t\t\te = m;\n\t\telse\n\t\t\ts = m;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSInterCodeContext::FindSrcLineStartCodePos(tjs_int codepos) const\n{\n\t// find code address which is the first instruction of the source line\n\tif(!SourcePosArray) return 0;\n\n\ttjs_int srcpos = CodePosToSrcPos(codepos);\n\ttjs_int line = Block->SrcPosToLine(srcpos);\n\tsrcpos = Block->LineToSrcPos(line);\n\n\ttjs_int codeposmin = -1;\n\tfor(tjs_int i = 0; i < SourcePosArraySize; i++)\n\t{\n\t\tif(SourcePosArray[i].SourcePos >= srcpos)\n\t\t{\n\t\t\tif(codeposmin == -1 || SourcePosArray[i].CodePos< codeposmin)\n\t\t\t\tcodeposmin = SourcePosArray[i].CodePos;\n\t\t}\n\t}\n\tif(codeposmin < 0) codeposmin = 0;\n\treturn codeposmin;\n}\n//---------------------------------------------------------------------------\nttstr tTJSInterCodeContext::GetPositionDescriptionString(tjs_int codepos) const\n{\n\treturn Block->GetLineDescriptionString(CodePosToSrcPos(codepos)) +\n\t\tTJS_W(\"[\") + GetShortDescription() + TJS_W(\"]\");\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJSIsModifySubType(tTJSSubType type)\n\t{ return type != stNone; }\nstatic bool inline TJSIsCondFlagRetValue(tjs_int r)\n\t{ return r == TJS_GNC_CFLAG || r == TJS_GNC_CFLAG_I; }\nstatic bool inline TJSIsFrame(tjs_int r)\n\t{ return r > 0; }\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_this_proxy = 0;\n#endif\n\ntjs_int tTJSInterCodeContext::GenNodeCode(tjs_int & frame, tTJSExprNode *node,\n\ttjs_uint32 restype, tjs_int reqresaddr, const tSubParam  & param)\n{\n\t// code generation of a given node\n\n\t// frame = register stack frame\n\t// node = target node\n\t// restype = required result type\n\t// reqresaddr = variable address which should receives the result\n\t//              ( currently not used )\n\t// param = additional parameters\n\t// returns: a register address that contains the result ( TJS_GNC_CFLAG\n\t//          for condition flags )\n\n\ttjs_int resaddr;\n\n\ttjs_int node_pos = NODE_POS;\n\n\tswitch(node->GetOpecode())\n\t{\n\tcase T_CONSTVAL: // constant value\n\t  {\n\t\t// a code that refers the constant value\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tif(!(restype & TJS_RT_NEEDED)) return 0; // why here is called without a result necessity? ;-)\n\t\ttjs_int dp = PutData(node->GetValue());\n\t\tPutCode(VM_CONST, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\treturn frame++;\n\t  }\n\n\tcase T_IF: // 'if' operator\n\t  {\n\t\t// \"if\" operator\n\t\t// evaluate right node. then evaluate left node if the right results true.\n\t\tif(restype & TJS_RT_NEEDED) _yyerror(TJSCannotGetResult, Block);\n//\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\ttjs_int resaddr = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED|TJS_RT_CFLAG,\n\t\t\t0, tSubParam());\n\t\tbool inv = false;\n\t\tif(!TJSIsCondFlagRetValue(resaddr))\n\t\t{\n\t\t\tPutCode(VM_TT, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(resaddr == TJS_GNC_CFLAG_I) inv = true;\n\t\t}\n\t\ttjs_int addr = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(inv?VM_JF:VM_JNF, node_pos);\n\t\tPutCode(0, node_pos); // *\n\t\t_GenNodeCode(frame, (*node)[0], 0, 0, param);\n\t\tCodeArea[addr + 1] = CodeAreaSize - addr; //  patch \"*\"\n\t\treturn 0;\n\t  }\n\n\tcase T_INCONTEXTOF: // 'incontextof' operator\n\t  {\n\t\t// \"incontextof\" operator\n\t\t// a special operator that changes objeect closure's context\n\t\tif(!(restype & TJS_RT_NEEDED)) return 0;\n\t\ttjs_int resaddr1, resaddr2;\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, param);\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\tif(!TJSIsFrame(resaddr1))\n\t\t{\n\t\t\tPutCode(VM_CP, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\tresaddr1 = frame;\n\t\t\tframe++;\n\t\t}\n\t\tPutCode(VM_CHGTHIS, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n\n\t\treturn resaddr1;\n\t  }\n\n\tcase T_COMMA: // ',' operator\n\t\t// comma operator\n\t\t_GenNodeCode(frame, (*node)[0], 0, 0, tSubParam());\n\t\treturn _GenNodeCode(frame, (*node)[1], restype, reqresaddr, param);\n\n\n\tcase T_SWAP: // '<->' operator\n\t  {\n\t\t// swap operator\n\t\tif(restype & TJS_RT_NEEDED) _yyerror(TJSCannotGetResult, Block);\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\n\t\ttjs_int resaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0,\n\t\t\ttSubParam());\n\n\t\tif(!TJSIsFrame(resaddr1))\n\t\t{\n\t\t\tPutCode(VM_CP, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\tresaddr1 = frame;\n\t\t\tframe++;\n\t\t}\n\n\t\ttjs_int resaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0,\n\t\t\ttSubParam());\n\n\t\t// create substitutions\n\t\ttSubParam param2;\n\t\tparam2.SubType = stEqual;\n\t\tparam2.SubAddress = resaddr2;\n\t\t_GenNodeCode(frame, (*node)[0], 0, 0, param2);\n\n\t\tparam2.SubType = stEqual;\n\t\tparam2.SubAddress = resaddr1;\n\t\t_GenNodeCode(frame, (*node)[1], 0, 0, param2);\n\n\t\treturn 0;\n\t  }\n\n\tcase T_EQUAL: // '=' operator\n\t  {\n\t\t// simple substitution\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\n\t\tif(restype & TJS_RT_CFLAG)\n\t\t{\n\t\t\t// '=' operator in boolean context\n\t\t\tOutputWarning(TJSSubstitutionInBooleanContext, node_pos);\n\t\t}\n\n\t\tresaddr = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, param);\n\n\t\ttSubParam param2;\n\t\tparam2.SubType = stEqual;\n\t\tparam2.SubAddress = resaddr;\n\t\t_GenNodeCode(frame, (*node)[0], 0, 0, param2);\n\t\treturn resaddr;\n\t  }\n\n\tcase T_AMPERSANDEQUAL:\t\t// '&=' operator\n\tcase T_VERTLINEEQUAL:\t\t// '|=' operator\n\tcase T_CHEVRONEQUAL:\t\t// '^=' operator\n\tcase T_MINUSEQUAL:\t\t\t// ^-=' operator\n\tcase T_PLUSEQUAL:\t\t\t// '+=' operator\n\tcase T_PERCENTEQUAL:\t\t// '%=' operator\n\tcase T_SLASHEQUAL:\t\t\t// '/=' operator\n\tcase T_BACKSLASHEQUAL:\t\t// '\\=' operator\n\tcase T_ASTERISKEQUAL:\t\t// '*=' operator\n\tcase T_LOGICALOREQUAL:\t\t// '||=' operator\n\tcase T_LOGICALANDEQUAL:\t\t// '&&=' operator\n\tcase T_RARITHSHIFTEQUAL:\t// '>>=' operator\n\tcase T_LARITHSHIFTEQUAL:\t// '<<=' operator\n\tcase T_RBITSHIFTEQUAL:\t\t// '>>>=' operator\n\t  {\n\t\t// operation and substitution operators like \"&=\"\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\t\tresaddr = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\n\t\ttSubParam param2;\n\t\tswitch(node->GetOpecode()) // this may be sucking...\n\t\t{\n\t\tcase T_AMPERSANDEQUAL:\t\tparam2.SubType = stBitAND;\t\tbreak;\n\t\tcase T_VERTLINEEQUAL:\t\tparam2.SubType = stBitOR;\t\tbreak;\n\t\tcase T_CHEVRONEQUAL:\t\tparam2.SubType = stBitXOR;\t\tbreak;\n\t\tcase T_MINUSEQUAL:\t\t\tparam2.SubType = stSub;\t\t\tbreak;\n\t\tcase T_PLUSEQUAL:\t\t\tparam2.SubType = stAdd;\t\t\tbreak;\n\t\tcase T_PERCENTEQUAL:\t\tparam2.SubType = stMod;\t\t\tbreak;\n\t\tcase T_SLASHEQUAL:\t\t\tparam2.SubType = stDiv;\t\t\tbreak;\n\t\tcase T_BACKSLASHEQUAL:\t\tparam2.SubType = stIDiv;\t\tbreak;\n\t\tcase T_ASTERISKEQUAL:\t\tparam2.SubType = stMul;\t\t\tbreak;\n\t\tcase T_LOGICALOREQUAL:\t\tparam2.SubType = stLogOR;\t\tbreak;\n\t\tcase T_LOGICALANDEQUAL:\t\tparam2.SubType = stLogAND;\t\tbreak;\n\t\tcase T_RARITHSHIFTEQUAL:\tparam2.SubType = stSAR;\t\t\tbreak;\n\t\tcase T_LARITHSHIFTEQUAL:\tparam2.SubType = stSAL;\t\t\tbreak;\n\t\tcase T_RBITSHIFTEQUAL:\t\tparam2.SubType = stSR;\t\t\tbreak;\n\t\t}\n\t\tparam2.SubAddress = resaddr;\n\t\treturn _GenNodeCode(frame, (*node)[0], restype, reqresaddr, param2);\n\t  }\n\n\tcase T_QUESTION: // '?' ':' operator\n\t  {\n\t\t// three-term operator ( ?  :  )\n\t\ttjs_int resaddr1, resaddr2;\n\t\tint frame1, frame2;\n\t\tresaddr = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED|TJS_RT_CFLAG, 0, tSubParam());\n\t\tbool inv = false;\n\t\tif(!TJSIsCondFlagRetValue(resaddr))\n\t\t{\n\t\t\tPutCode(VM_TT, node_pos);    // tt resaddr\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(resaddr == TJS_GNC_CFLAG_I) inv = true;\n\t\t}\n\n\t\ttjs_int cur_frame = frame;\n\t\ttjs_int addr1 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(inv?VM_JF:VM_JNF, node_pos);\n\t\tPutCode(0, node_pos); // patch\n\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[1], restype, reqresaddr, param);\n\n\t\tif(restype & TJS_RT_CFLAG)\n\t\t{\n\t\t\t// condition flag required\n\t\t\tif(!TJSIsCondFlagRetValue(resaddr1))\n\t\t\t{\n\t\t\t\tPutCode(VM_TT, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(resaddr1 == TJS_GNC_CFLAG_I)\n\t\t\t\t\tPutCode(VM_NF, node_pos); // invert flag\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif((restype & TJS_RT_NEEDED) &&\n\t\t\t\t\t!TJSIsCondFlagRetValue(resaddr1) && !TJSIsFrame(resaddr1))\n\t\t\t{\n\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\t\tresaddr1 = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t}\n\t\tframe1 = frame;\n\n\t\ttjs_int addr2 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JMP, node_pos);\n\t\tPutCode(0, node_pos); // patch\n\t\tCodeArea[addr1+1] = CodeAreaSize - addr1;\n\t\tframe = cur_frame;\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[2], restype, reqresaddr, param);\n\n\t\tif(restype & TJS_RT_CFLAG)\n\t\t{\n\t\t\t// condition flag required\n\t\t\tif(!TJSIsCondFlagRetValue(resaddr2))\n\t\t\t{\n\t\t\t\tPutCode(VM_TT, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(resaddr2 == TJS_GNC_CFLAG_I)\n\t\t\t\t\tPutCode(VM_NF, node_pos); // invert flag\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif((restype & TJS_RT_NEEDED) &&\n\t\t\t\t\t!TJSIsCondFlagRetValue(resaddr1) && resaddr1 != resaddr2)\n\t\t\t{\n\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n\t\t\t\tframe++;\n\t\t\t}\n\t\t}\n\t\tframe2 = frame;\n\n\t  \tCodeArea[addr2+1] = CodeAreaSize - addr2;\n\t\tframe = frame2 < frame1 ? frame1 : frame2;\n\t\treturn (restype & TJS_RT_CFLAG)?TJS_GNC_CFLAG: resaddr1;\n\t  }\n\n\tcase T_LOGICALOR: // '||' operator\n\tcase T_LOGICALAND: // '&&' operator\n\t  {\n\t\t// \"logical or\" and \"logical and\"\n\t\t// these process with the \"shortcut\" :\n\t\t// OR  : does not evaluate right when left results true\n\t\t// AND : does not evaluate right when left results false\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\t\ttjs_int resaddr1, resaddr2;\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED|TJS_RT_CFLAG,\n\t\t\t0, tSubParam());\n\t\tbool inv = false;\n\t\tif(!TJSIsCondFlagRetValue(resaddr1))\n\t\t{\n\t\t\tPutCode(VM_TT, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t}\n\t\tif(resaddr1 == TJS_GNC_CFLAG_I) inv = true;\n\t\ttjs_int addr1 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(node->GetOpecode() == T_LOGICALOR ?\n\t\t\t(inv?VM_JNF:VM_JF) : (inv?VM_JF:VM_JNF), node_pos);\n\t\tPutCode(0, node_pos); // *A\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED|TJS_RT_CFLAG,\n\t\t\t0, tSubParam());\n\t\tif(!TJSIsCondFlagRetValue(resaddr2))\n\t\t{\n\t\t\tPutCode(inv?VM_TF:VM_TT, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif((inv != false) != (resaddr2==TJS_GNC_CFLAG_I))\n\t\t\t\tPutCode(VM_NF, node_pos); // invert flag\n\t\t}\n\t\tCodeArea[addr1 + 1] = CodeAreaSize - addr1; // patch *A\n\t\tif(!(restype & TJS_RT_CFLAG))\n\t\t{\n\t\t\t// requested result type is not condition flag\n\t\t\tif(TJSIsCondFlagRetValue(resaddr1) || !TJSIsFrame(resaddr1))\n\t\t\t{\n\t\t\t\tPutCode(inv?VM_SETNF:VM_SETF, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tresaddr1 = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tPutCode(inv?VM_SETNF:VM_SETF, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\t}\n\t\t}\n\t\treturn (restype & TJS_RT_CFLAG) ?\n\t\t\t(inv?TJS_GNC_CFLAG_I:TJS_GNC_CFLAG) : resaddr1;\n\t  }\n\n\tcase T_INSTANCEOF: // 'instanceof' operator\n\t  {\n\t\t// instanceof operator\n\t\ttjs_int resaddr1, resaddr2;\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\tif(!TJSIsFrame(resaddr1))\n\t\t{\n\t\t\tPutCode(VM_CP, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\tresaddr1 = frame;\n\t\t\tframe++;\n\t\t}\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\tPutCode(VM_CHKINS, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n        return resaddr1;\n\t  }\n\n\tcase T_VERTLINE:\t// '|' operator\n\tcase T_CHEVRON:\t\t// '^' operator\n\tcase T_AMPERSAND:\t// binary '&' operator\n\tcase T_RARITHSHIFT:\t// '>>' operator\n\tcase T_LARITHSHIFT:\t// '<<' operator\n\tcase T_RBITSHIFT:\t// '>>>' operator\n\tcase T_PLUS:\t\t// binary '+' operator\n\tcase T_MINUS:\t\t// '-' operator\n\tcase T_PERCENT:\t\t// '%' operator\n\tcase T_SLASH:\t\t// '/' operator\n\tcase T_BACKSLASH:\t// '\\' operator\n\tcase T_ASTERISK:\t// binary '*' operator\n\t  {\n\t\t// general two-term operators\n\t\ttjs_int resaddr1, resaddr2;\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\tif(!TJSIsFrame(resaddr1))\n\t\t{\n\t\t\tPutCode(VM_CP, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\tresaddr1 = frame;\n\t\t\tframe++;\n\t\t}\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\ttjs_int32 code;\n\t\tswitch(node->GetOpecode())  // sucking....\n\t\t{\n\t\tcase T_VERTLINE:\t\tcode = VM_BOR;\t\tbreak;\n\t\tcase T_CHEVRON:\t\t\tcode = VM_BXOR;\t\tbreak;\n\t\tcase T_AMPERSAND:\t\tcode = VM_BAND;\t\tbreak;\n\t\tcase T_RARITHSHIFT:\t\tcode = VM_SAR;\t\tbreak;\n\t\tcase T_LARITHSHIFT:\t\tcode = VM_SAL;\t\tbreak;\n\t\tcase T_RBITSHIFT:\t\tcode = VM_SR;\t\tbreak;\n\t\tcase T_PLUS:\t\t\tcode = VM_ADD;\t\tbreak;\n\t\tcase T_MINUS:\t\t\tcode = VM_SUB;\t\tbreak;\n\t\tcase T_PERCENT:\t\t\tcode = VM_MOD;\t\tbreak;\n\t\tcase T_SLASH:\t\t\tcode = VM_DIV;\t\tbreak;\n\t\tcase T_BACKSLASH:\t\tcode = VM_IDIV;\t\tbreak;\n\t\tcase T_ASTERISK:\t\tcode = VM_MUL;\t\tbreak;\n\t\t}\n\n\t\tPutCode(code, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n\t\treturn resaddr1;\n\t  }\n\n\tcase T_NOTEQUAL:\t\t// '!=' operator\n\tcase T_EQUALEQUAL:\t\t// '==' operator\n\tcase T_DISCNOTEQUAL:\t// '!==' operator\n\tcase T_DISCEQUAL:\t\t// '===' operator\n\tcase T_LT:\t\t\t\t// '<' operator\n\tcase T_GT:\t\t\t\t// '>' operator\n\tcase T_LTOREQUAL:\t\t// '<=' operator\n\tcase T_GTOREQUAL:\t\t// '>=' operator\n\t  {\n\t\t// comparison operators\n\t\ttjs_int resaddr1, resaddr2;\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tresaddr1 = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\tif(!(restype & TJS_RT_CFLAG))\n\t\t{\n\t\t\tif(!TJSIsFrame(resaddr1))\n\t\t\t{\n\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t\t\tresaddr1 = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t}\n\t\tresaddr2 = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\ttjs_int32 code1, code2;\n\t\tswitch(node->GetOpecode())  // ...\n\t\t{\n\t\tcase T_NOTEQUAL:\t\tcode1 = VM_CEQ;\t\tcode2 = VM_SETNF; \tbreak;\n\t\tcase T_EQUALEQUAL:\t\tcode1 = VM_CEQ;\t\tcode2 = VM_SETF;\tbreak;\n\t\tcase T_DISCNOTEQUAL:\tcode1 = VM_CDEQ;\tcode2 = VM_SETNF;\tbreak;\n\t\tcase T_DISCEQUAL:\t\tcode1 = VM_CDEQ;\tcode2 = VM_SETF;\tbreak;\n\t\tcase T_LT:\t\t\t\tcode1 = VM_CLT;\t\tcode2 = VM_SETF;\tbreak;\n\t\tcase T_GT:\t\t\t\tcode1 = VM_CGT;\t\tcode2 = VM_SETF;\tbreak;\n\t\tcase T_LTOREQUAL:\t\tcode1 = VM_CGT;\t\tcode2 = VM_SETNF;\tbreak;\n\t\tcase T_GTOREQUAL:\t\tcode1 = VM_CLT;\t\tcode2 = VM_SETNF;\tbreak;\n\t\t}\n\n\t\tPutCode(code1, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr2), node_pos);\n\n\t\tif(!(restype & TJS_RT_CFLAG))\n\t\t{\n\t\t\tPutCode(code2, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr1), node_pos);\n\t\t}\n\n\t\treturn (restype & TJS_RT_CFLAG) ?\n\t\t\t(code2 == VM_SETNF?TJS_GNC_CFLAG_I:TJS_GNC_CFLAG):resaddr1;\n\t  }\n\n\tcase T_EXCRAMATION: // pre-positioned '!' operator\n\t  {\n\t\t// logical not\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tresaddr = _GenNodeCode(frame, (*node)[0], restype, reqresaddr, tSubParam());\n\t\tif(!(restype & TJS_RT_CFLAG))\n\t\t{\n\t\t\t// value as return value required\n\t\t\tif(!TJSIsFrame(resaddr))\n\t\t\t{\n\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tresaddr = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t\tPutCode(VM_LNOT, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\treturn resaddr;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// condifion flag required\n\t\t\tif(!TJSIsCondFlagRetValue(resaddr))\n\t\t\t{\n\t\t\t\tPutCode(VM_TF, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr));\n\t\t\t\treturn TJS_GNC_CFLAG;\n\t\t\t}\n\n\t\t\treturn resaddr == TJS_GNC_CFLAG_I ? TJS_GNC_CFLAG : TJS_GNC_CFLAG_I;\n\t\t\t\t// invert flag\n\t\t}\n\n\t  }\n\n\tcase T_TILDE:\t\t// '~' operator\n\tcase T_SHARP:\t\t// '#' operator\n\tcase T_DOLLAR:\t\t// '$' operator\n\tcase T_UPLUS:\t\t// unary '+' operator\n\tcase T_UMINUS:\t\t// unary '-' operator\n\tcase T_INVALIDATE:\t// 'invalidate' operator\n\tcase T_ISVALID:\t\t// 'isvalid' operator\n\tcase T_EVAL:\t\t// post-positioned '!' operator\n\tcase T_INT:\t\t\t// 'int' operator\n\tcase T_REAL:\t\t// 'real' operator\n\tcase T_STRING:\t\t// 'string' operator\n\tcase T_OCTET:\t\t// 'octet' operator\n\t  {\n\t\t// general unary operators\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tresaddr = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\tif(!TJSIsFrame(resaddr))\n\t\t{\n\t\t\tPutCode(VM_CP, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tresaddr = frame;\n\t\t\tframe++;\n\t\t}\n\t\ttjs_int32 code;\n\t\tswitch(node->GetOpecode())\n\t\t{\n//\t\t\tcase T_EXCRAMATION:\t\tcode = VM_LNOT;\t\t\tbreak;\n\t\t\tcase T_TILDE:\t\t\tcode = VM_BNOT;\t\t\tbreak;\n\t\t\tcase T_SHARP:\t\t\tcode = VM_ASC;\t\t\tbreak;\n\t\t\tcase T_DOLLAR:\t\t\tcode = VM_CHR;\t\t\tbreak;\n\t\t\tcase T_UPLUS:\t\t\tcode = VM_NUM;\t\t\tbreak;\n\t\t\tcase T_UMINUS:\t\t\tcode = VM_CHS;\t\t\tbreak;\n\t\t\tcase T_INVALIDATE:\t\tcode = VM_INV;\t\t\tbreak;\n\t\t\tcase T_ISVALID:\t\t\tcode = VM_CHKINV;\t\tbreak;\n\t\t\tcase T_TYPEOF:\t\t\tcode = VM_TYPEOF;\t\tbreak;\n\t\t\tcase T_EVAL:\t\t\tcode = (restype & TJS_RT_NEEDED)?\n\t\t\t\t\t\t\t\t\t\t   VM_EVAL:VM_EEXP;\n\n\t\t\t\t\t\t\t// warn if T_EVAL is used in non-global position\n\t\t\t\t\t\t\tif(TJSWarnOnNonGlobalEvalOperator &&\n\t\t\t\t\t\t\t\tContextType != ctTopLevel)\n\t\t\t\t\t\t\t\tOutputWarning(TJSWarnEvalOperator);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\tcase T_INT:\t\t\t\tcode = VM_INT;\t\t\tbreak;\n\t\t\tcase T_REAL:\t\t\tcode = VM_REAL;\t\t\tbreak;\n\t\t\tcase T_STRING:\t\t\tcode = VM_STR;\t\t\tbreak;\n\t\t\tcase T_OCTET:\t\t\tcode = VM_OCTET;\t\tbreak;\n\t\t}\n\t\tPutCode(code, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\n\n\t\treturn resaddr;\n\t  }\n\n\n\tcase T_TYPEOF:  // 'typeof' operator\n\t  {\n\t\t// typeof\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\tbool haspropnode;\n\t\ttTJSExprNode *cnode = (*node)[0];\n\t\tif(cnode->GetOpecode() == T_DOT || cnode->GetOpecode() == T_LBRACKET ||\n\t\t\tcnode->GetOpecode() == T_WITHDOT)\n\t\t\thaspropnode = true;\n\t\telse\n\t\t\thaspropnode = false;\n\n\t\tif(haspropnode)\n\t\t{\n\t\t\t// has property access node\n\t\t\ttSubParam param2;\n\t\t\tparam2.SubType = stTypeOf;\n\t\t\treturn _GenNodeCode(frame, cnode, TJS_RT_NEEDED, 0, param2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// normal operation\n\t\t\tresaddr = _GenNodeCode(frame, cnode, TJS_RT_NEEDED, 0, tSubParam());\n\n\t\t\tif(!TJSIsFrame(resaddr))\n\t\t\t{\n\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tresaddr = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t\tPutCode(VM_TYPEOF, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\treturn resaddr;\n\n\t\t}\n\t  }\n\n\tcase T_DELETE:\t\t\t// 'delete' operator\n\tcase T_INCREMENT:\t\t// pre-positioned '++' operator\n\tcase T_DECREMENT:\t\t// pre-positioned '--' operator\n\tcase T_POSTINCREMENT:\t// post-positioned '++' operator\n\tcase T_POSTDECREMENT:\t// post-positioned '--' operator\n\t  {\n\t\t// delete, typeof, increment and decrement\n\t\tif(TJSIsModifySubType(param.SubType)) _yyerror(TJSCannotModifyLHS, Block);\n\t\ttSubParam param2;\n\t\tswitch(node->GetOpecode())\n\t\t{\n\t\tcase T_TYPEOF:\t\t\tparam2.SubType = stTypeOf;\t\tbreak;\n\t\tcase T_DELETE:\t\t\tparam2.SubType = stDelete;\t\tbreak;\n\t\tcase T_INCREMENT:\t\tparam2.SubType = stPreInc;\t\tbreak;\n\t\tcase T_DECREMENT:\t\tparam2.SubType = stPreDec;\t\tbreak;\n\t\tcase T_POSTINCREMENT:\tparam2.SubType = stPostInc;\t\tbreak;\n\t\tcase T_POSTDECREMENT:\tparam2.SubType = stPostDec;\t\tbreak;\n\t\t}\n//\t\tparam2.SubAddress = frame-1;\n\t\treturn _GenNodeCode(frame, (*node)[0], restype, reqresaddr, param2);\n\t  }\n\n\tcase T_LPARENTHESIS:\t// '( )' operator\n\tcase T_NEW:\t\t\t\t// 'new' operator\n\t  {\n\t\t// function call or create-new object\n\n\t\t// does (*node)[0] have a node that acceesses any properties ?\n\t\tbool haspropnode, hasnonlocalsymbol;\n\t\ttTJSExprNode *cnode = (*node)[0];\n\t\tif(node->GetOpecode() == T_LPARENTHESIS &&\n\t\t\t(cnode->GetOpecode() == T_DOT || cnode->GetOpecode() == T_LBRACKET))\n\t\t\thaspropnode = true;\n\t\telse\n\t\t\thaspropnode = false;\n\n\t\t// does (*node)[0] have a node that accesses non-local functions ?\n\t\tif(node->GetOpecode() == T_LPARENTHESIS && cnode->GetOpecode() == T_SYMBOL)\n\t\t{\n\t\t\tif(AsGlobalContextMode)\n\t\t\t{\n\t\t\t\thasnonlocalsymbol = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttTJSVariantString *str = cnode->GetValue().AsString();\n\t\t\t\tif(Namespace.Find(str->operator const tjs_char *()) == -1)\n\t\t\t\t\thasnonlocalsymbol = true;\n\t\t\t\telse\n\t\t\t\t\thasnonlocalsymbol = false;\n\t\t\t\tstr->Release();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\thasnonlocalsymbol = false;\n\t\t}\n\n\t\t// flag which indicates whether to do direct or indirect call access\n\t\tbool do_direct_access = haspropnode || hasnonlocalsymbol;\n\n\t\t// reserve frame\n\t\tif(!do_direct_access && (restype & TJS_RT_NEEDED) )\n\t\t\tframe++; // reserve the frame for a result value\n\n\t\t// generate function call codes\n\t\tStartFuncArg();\n\t\ttjs_int framestart = frame;\n\t\ttjs_int res;\n\t\ttry\n\t\t{\n\t\t\t// arguments is\n\t\t\tif((*node)[1]->GetSize() == 1 && (*(*node)[1])[0] == NULL)\n\t\t\t{\n\t\t\t\t// empty\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// exist\n\t\t\t\t_GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\t\t}\n\n\t\t\t// compilation of expression that represents the function\n\t\t\ttSubParam param2;\n\n\n\t\t\tif(do_direct_access)\n\t\t\t{\n\t\t\t\tparam2.SubType = stFuncCall; // creates code with stFuncCall\n\t\t\t\tres = _GenNodeCode(frame, (*node)[0], restype, reqresaddr, param2);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparam2.SubType = stNone;\n\t\t\t\tresaddr = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, param2);\n\n\t\t\t\t// code generatio of function calling\n\t\t\t\tPutCode(node->GetOpecode() == T_NEW ? VM_NEW: VM_CALL, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(\n\t\t\t\t\tres = (restype & TJS_RT_NEEDED)?(framestart-1):0),\n\t\t\t\t\tnode_pos); // result target\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr),\n\t\t\t\t\tnode_pos); // iTJSDispatch2 that points the function\n\n\t\t\t\t// generate argument code\n\t\t\t\tGenerateFuncCallArgCode();\n\n\t\t\t\t// clears the frame\n\t\t\t\tClearFrame(frame, framestart);\n\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tEndFuncArg();\n\t\t\tthrow;\n\t\t}\n\n\t\tEndFuncArg();\n\n\t\treturn res;\n\t  }\n\n\tcase T_ARG:\n\t\t// a function argument\n\t\tif(node->GetSize() >= 2)\n\t\t{\n\t\t\tif((*node)[1]) _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\t}\n\t\tif((*node)[0])\n\t\t{\n\t\t\ttTJSExprNode *n = (*node)[0];\n\t\t\tif(n->GetOpecode() == T_EXPANDARG)\n\t\t\t{\n\t\t\t\t// expanding argument\n\t\t\t\tif((*n)[0])\n\t\t\t\t\tAddFuncArg(_GenNodeCode(\n\t\t\t\t\t\tframe, (*n)[0], TJS_RT_NEEDED, 0, tSubParam()), fatExpand);\n\t\t\t\telse\n\t\t\t\t\tAddFuncArg(0, fatUnnamedExpand);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAddFuncArg(_GenNodeCode(\n\t\t\t\t\tframe, (*node)[0], TJS_RT_NEEDED, 0, tSubParam()), fatNormal);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tAddFuncArg(0, fatNormal);\n\t\t}\n\t\treturn 0;\n\n\tcase T_OMIT:\n\t\t// omitting of the function arguments\n\t\tAddOmitArg();\n        return 0;\n\n\tcase T_DOT:\t\t\t// '.' operator\n\tcase T_LBRACKET:\t// '[ ]' operator\n\t  {\n\t\t// member access ( direct or indirect )\n\t\tbool direct = node->GetOpecode() == T_DOT;\n\t\ttjs_int dp;\n\n\t\ttSubParam param2;\n\t\tparam2.SubType = stNone;\n\t\tresaddr = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, param2);\n\n\t\tif(direct)\n\t\t\tdp = PutData((*node)[1]->GetValue());\n\t\telse\n\t\t\tdp = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\n\t\tswitch(param.SubType)\n\t\t{\n\t\tcase stNone:\n\t\tcase stIgnorePropGet:\n\t\t\tif(param.SubType == stNone)\n\t\t\t\tPutCode(direct ? VM_GPD : VM_GPI, node_pos);\n\t\t\telse\n\t\t\t\tPutCode(direct ? VM_GPDS : VM_GPIS, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tframe++;\n\t\t\treturn frame-1;\n\n\t\tcase stEqual:\n\t\tcase stIgnorePropSet:\n\t\t\tif(param.SubType == stEqual)\n\t\t\t{\n\t\t\t\tif((*node)[0]->GetOpecode() == T_THIS_PROXY)\n\t\t\t\t\tPutCode(direct ? VM_SPD : VM_SPI, node_pos);\n\t\t\t\telse\n\t\t\t\t\tPutCode(direct ? VM_SPDE : VM_SPIE, node_pos);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tPutCode(direct ? VM_SPDS : VM_SPIS, node_pos);\n\t\t\t}\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\treturn param.SubAddress;\n\n\t\tcase stBitAND:\n\t\tcase stBitOR:\n\t\tcase stBitXOR:\n\t\tcase stSub:\n\t\tcase stAdd:\n\t\tcase stMod:\n\t\tcase stDiv:\n\t\tcase stIDiv:\n\t\tcase stMul:\n\t\tcase stLogOR:\n\t\tcase stLogAND:\n\t\tcase stSAR:\n\t\tcase stSAL:\n\t\tcase stSR:\n\t\t\tPutCode((tjs_int32)param.SubType + (direct?1:2), node_pos);\n\t\t\t\t// here adds 1 or 2 to the ope-code\n\t\t\t\t// ( see the ope-code's positioning order )\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame: 0), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\tif(restype & TJS_RT_NEEDED) frame++;\n\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\tcase stPreInc:\n\t\tcase stPreDec:\n\t\t\tPutCode((param.SubType == stPreInc ? VM_INC : VM_DEC) +\n\t\t\t\t(direct? 1:2), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame: 0), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tif((restype & TJS_RT_NEEDED)) frame++;\n\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\tcase stPostInc:\n\t\tcase stPostDec:\n\t\t  {\n\t\t\ttjs_int retresaddr = 0;\n\t\t\tif(restype & TJS_RT_NEEDED)\n\t\t\t{\n\t\t\t\t// need result ...\n\t\t\t\tPutCode(direct ? VM_GPD : VM_GPI, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\t\tretresaddr = frame;\n\t\t\t\tframe++;\n\t\t\t}\n\t\t\tPutCode((param.SubType == stPostInc ? VM_INC : VM_DEC) +\n\t\t\t\t(direct? 1:2), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(0), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\treturn retresaddr;\n\t\t  }\n\t\tcase stTypeOf:\n\t\t  {\n\t\t\t// typeof\n\t\t\tPutCode(direct? VM_TYPEOFD:VM_TYPEOFI, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame:0), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tif(restype & TJS_RT_NEEDED) frame++;\n\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\t\t  }\n\t\tcase stDelete:\n\t\t  {\n\t\t\t// deletion\n\t\t\tPutCode(direct? VM_DELD:VM_DELI, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame:0), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\tif(restype & TJS_RT_NEEDED) frame++;\n\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\t\t  }\n\t\tcase stFuncCall:\n\t\t  {\n\t\t\t// function call\n\t\t\tPutCode(direct ? VM_CALLD:VM_CALLI, node_pos);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame:0),\n\t\t\t\tnode_pos); // result target\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos); // the object\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos); // function name\n\n\t\t\t// generate argument code\n\t\t\tGenerateFuncCallArgCode();\n\n\t\t\t// extend frame and return\n\t\t\tif(restype & TJS_RT_NEEDED) frame++;\n\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\t\t  }\n\n\t\tdefault:\n\t\t\t_yyerror(TJSCannotModifyLHS, Block);\n\t\t\treturn 0;\n\t\t}\n\t  }\n\n\n\tcase T_SYMBOL:\t// symbol\n\t  {\n\t\t// accessing to a variable\n\t\ttjs_int n;\n\t\tif(AsGlobalContextMode)\n\t\t{\n\t\t\tn = -1; // global mode cannot access local variables\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTJSVariantString *str = node->GetValue().AsString();\n\t\t\tn = Namespace.Find(str->operator const tjs_char *());\n\t\t\tstr->Release();\n\t\t}\n\n\t\tif(n!=-1)\n\t\t{\n\t\t\tbool isstnone = !TJSIsModifySubType(param.SubType);\n\n\t\t\tif(!isstnone)\n\t\t\t{\n\t\t\t\t// substitution, or like it\n\t\t\t\tswitch(param.SubType)\n\t\t\t\t{\n\t\t\t\tcase stEqual:\n\t\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase stBitAND:\n\t\t\t\tcase stBitOR:\n\t\t\t\tcase stBitXOR:\n\t\t\t\tcase stSub:\n\t\t\t\tcase stAdd:\n\t\t\t\tcase stMod:\n\t\t\t\tcase stDiv:\n\t\t\t\tcase stIDiv:\n\t\t\t\tcase stMul:\n\t\t\t\tcase stLogOR:\n\t\t\t\tcase stLogAND:\n\t\t\t\tcase stSAR:\n\t\t\t\tcase stSAL:\n\t\t\t\tcase stSR:\n\t\t\t\t\tPutCode(param.SubType, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\t\t\treturn (restype & TJS_RT_NEEDED)?-n-VariableReserveCount-1:0;\n\n\t\t\t\tcase stPreInc: // pre-positioning\n\t\t\t\t\tPutCode(VM_INC, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\treturn (restype & TJS_RT_NEEDED)?-n-VariableReserveCount-1:0;\n\n\t\t\t\tcase stPreDec: // pre-\n\t\t\t\t\tPutCode(VM_DEC, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\treturn (restype & TJS_RT_NEEDED)?-n-VariableReserveCount-1:0;\n\n\t\t\t\tcase stPostInc: // post-\n\t\t\t\t\tif(restype & TJS_RT_NEEDED)\n\t\t\t\t\t{\n\t\t\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\t\tframe++;\n\t\t\t\t\t}\n\t\t\t\t\tPutCode(VM_INC, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\t\t\tcase stPostDec: // post-\n\t\t\t\t\tif(restype & TJS_RT_NEEDED)\n\t\t\t\t\t{\n\t\t\t\t\t\tPutCode(VM_CP, node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\t\tframe++;\n\t\t\t\t\t}\n\t\t\t\t\tPutCode(VM_DEC, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n\t\t\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\t\t\tcase stDelete: // deletion\n\t\t\t\t  {\n#if 0\n\t\t\t\t\tPutCode(VM_CL, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), node_pos);\n#endif\n\t\t\t\t\ttTJSVariantString *str = node->GetValue().AsString();\n\t\t\t\t\tNamespace.Remove(*str);\n\t\t\t\t\tstr->Release();\n\t\t\t\t\tif(restype & TJS_RT_NEEDED)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_int dp = PutData(tTJSVariant(tTVInteger(true)));\n\t\t\t\t\t\tPutCode(VM_CONST, node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), node_pos);\n\t\t\t\t\t\treturn frame-1;\n\t\t\t\t\t}\n\t\t\t\t\treturn 0;\n\t\t\t\t  }\n\t\t\t\tdefault:\n\t\t\t\t\t_yyerror(TJSCannotModifyLHS, Block);\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// read\n\t\t\t\ttTJSVariantString *str = node->GetValue().AsString();\n//\t\t\t\tNamespace.Add(str->operator tjs_char *());\n\t\t\t\ttjs_int n = Namespace.Find(str->operator const tjs_char *());\n\t\t\t\tstr->Release();\n\t\t\t\treturn -n-VariableReserveCount-1;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// n==-1 ( indicates the variable is not found in the local  )\n\t\t\t// assume the variable is in \"this\".\n\t\t\t// make nodes that refer \"this\" and process it\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_this_proxy);\n#endif\n\t\t\ttTJSExprNode nodep;\n\t\t\tnodep.SetOpecode(T_DOT);\n\t\t\tnodep.SetPosition(node_pos);\n\t\t\ttTJSExprNode *node1 = new tTJSExprNode;\n\t\t\tNodeToDeleteVector.push_back(node1);\n\t\t\tnodep.Add(node1);\n\t\t\tnode1->SetOpecode(AsGlobalContextMode?T_GLOBAL:T_THIS_PROXY);\n\t\t\tnode1->SetPosition(node_pos);\n\t\t\ttTJSExprNode *node2 = new tTJSExprNode;\n\t\t\tNodeToDeleteVector.push_back(node2);\n\t\t\tnodep.Add(node2);\n\t\t\tnode2->SetOpecode(T_SYMBOL);\n\t\t\tnode2->SetPosition(node_pos);\n\t\t\tnode2->SetValue(node->GetValue());\n\t\t\treturn _GenNodeCode(frame, &nodep, restype, reqresaddr, param);\n\t\t}\n\t  }\n\n\tcase T_IGNOREPROP: // unary '&' operator\n\tcase T_PROPACCESS: // unary '*' operator\n\t\tif(node->GetOpecode() ==\n\t\t\t(TJSUnaryAsteriskIgnoresPropAccess?T_PROPACCESS:T_IGNOREPROP))\n\t\t{\n\t\t\t// unary '&' operator\n\t\t\t// substance accessing (ignores property operation)\n\t\t  \ttSubParam sp = param;\n\t\t\tif(sp.SubType == stNone) sp.SubType = stIgnorePropGet;\n\t\t\telse if(sp.SubType == stEqual) sp.SubType = stIgnorePropSet;\n\t\t\telse _yyerror(TJSCannotModifyLHS, Block);\n\t\t\treturn _GenNodeCode(frame, (*node)[0], restype, reqresaddr, sp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// unary '*' operator\n\t\t\t// force property access\n\t\t\tresaddr = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\t\tswitch(param.SubType)\n\t\t\t{\n\t\t\tcase stNone: // read from property object\n\t\t\t\tPutCode(VM_GETP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tframe ++;\n\t\t\t\treturn frame - 1;\n\n\t\t\tcase stEqual: // write to property object\n\t\t\t\tPutCode(VM_SETP, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\t\treturn param.SubAddress;\n\n\t\t\tcase stBitAND:\n\t\t\tcase stBitOR:\n\t\t\tcase stBitXOR:\n\t\t\tcase stSub:\n\t\t\tcase stAdd:\n\t\t\tcase stMod:\n\t\t\tcase stDiv:\n\t\t\tcase stIDiv:\n\t\t\tcase stMul:\n\t\t\tcase stLogOR:\n\t\t\tcase stLogAND:\n\t\t\tcase stSAR:\n\t\t\tcase stSAL:\n\t\t\tcase stSR:\n\t\t\t\tPutCode((tjs_int32)param.SubType + 3, node_pos);\n\t\t\t\t\t// +3 : property access\n\t\t\t\t\t// ( see the ope-code's positioning order )\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame: 0), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(param.SubAddress), node_pos);\n\t\t\t\tif(restype & TJS_RT_NEEDED) frame++;\n\t\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\t\tcase stPreInc:\n\t\t\tcase stPreDec:\n\t\t\t\tPutCode((param.SubType == stPreInc ? VM_INC : VM_DEC) + 3, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR((restype & TJS_RT_NEEDED) ? frame: 0), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\tif((restype & TJS_RT_NEEDED)) frame++;\n\t\t\t\treturn (restype & TJS_RT_NEEDED)?frame-1:0;\n\n\t\t\tcase stPostInc:\n\t\t\tcase stPostDec:\n\t\t\t  {\n\t\t\t\ttjs_int retresaddr = 0;\n\t\t\t\tif(restype & TJS_RT_NEEDED)\n\t\t\t\t{\n\t\t\t\t\t// need result ...\n\t\t\t\t\tPutCode(VM_GETP, node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\t\tretresaddr = frame;\n\t\t\t\t\tframe++;\n\t\t\t\t}\n\t\t\t\tPutCode((param.SubType == stPostInc ? VM_INC : VM_DEC) + 3, node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(0), node_pos);\n\t\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), node_pos);\n\t\t\t\treturn retresaddr;\n\t\t\t  }\n\n\t\t\tdefault:\n\t\t\t\t_yyerror(TJSCannotModifyLHS, Block);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\n\tcase T_SUPER: // 'super'\n\t  {\n\t\t// refer super class\n\n\t\t//tjs_int dp;\n\t\ttTJSExprNode * node;\n\t\tif(Parent && Parent->ContextType == ctProperty)\n\t\t{\n\t\t\tif((node = Parent->Parent->SuperClassExpr) == NULL)\n\t\t\t{\n\t\t\t\t_yyerror(TJSCannotGetSuper, Block);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!Parent || (node = Parent->SuperClassExpr) == NULL)\n\t\t\t{\n\t\t\t\t_yyerror(TJSCannotGetSuper, Block);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tAsGlobalContextMode = true;\n\t\t\t// the code must be generated in global context\n\t\t\t\n\t\ttry\n\t\t{\n\t\t\tresaddr = _GenNodeCode(frame, node, restype, reqresaddr, param);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tAsGlobalContextMode = false;\n\t\t\tthrow;\n\t\t}\n\n   \t\tAsGlobalContextMode = false;\n\n\t\treturn resaddr;\n\t  }\n\n\tcase T_THIS:\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\t\treturn -1;\n\n\tcase T_THIS_PROXY:\n\t\t// this-proxy is a special register that points\n\t\t// both \"objthis\" and \"global\"\n\t\t// if refering member is not in \"objthis\", this-proxy\n\t\t// refers \"global\".\n\t\treturn -VariableReserveCount;\n\n\tcase T_WITHDOT: // unary '.' operator\n\t  {\n\t\t// dot operator omitting object name\n\t\ttTJSExprNode nodep;\n\t\tnodep.SetOpecode(T_DOT);\n\t\tnodep.SetPosition(node_pos);\n\t\ttTJSExprNode *node1 = new tTJSExprNode;\n\t\tNodeToDeleteVector.push_back(node1);\n\t\tnodep.Add(node1);\n\t\tnode1->SetOpecode(T_WITHDOT_PROXY);\n\t\tnode1->SetPosition(node_pos);\n\t\tnodep.Add((*node)[0]);\n\t\treturn _GenNodeCode(frame, &nodep, restype, reqresaddr, param);\n \t  }\n\n\tcase T_WITHDOT_PROXY:\n\t  {\n\t\t// virtual left side of \".\" operator which omits object\n\n\t\t// search in NestVector\n\t\ttjs_int i = (tjs_int)(NestVector.size() -1);\n\t\tfor(; i>=0; i--)\n\t\t{\n\t\t\ttNestData &data = NestVector[i];\n\t\t\tif(data.Type == ntWith)\n\t\t\t{\n\t\t\t\t// found\n\t\t\t\treturn data.RefRegister;\n\t\t\t}\n\t\t}\n\n\t\t// not found in NestVector ...\n\t  }\n\n\t\t// NO \"break\" HERE!!!!!! (pass thru to global)\n\n\tcase T_GLOBAL:\n\t  {\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\t\tif(!(restype & TJS_RT_NEEDED)) return 0;\n\t\tPutCode(VM_GLOBAL, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame), node_pos);\n\t\tframe++;\n\t\treturn frame-1;\n\t  }\n\n\tcase T_INLINEARRAY:\n\t  {\n\t\t// inline array\n\n\t\ttjs_int arraydp = PutData(tTJSVariant(TJS_W(\"Array\")));\n\t\t//\tglobal %frame0\n\t\t//\tgpd %frame1, %frame0 . #arraydp // #arraydp = Array\n\t\ttjs_int frame0 = frame;\n\t\tPutCode(VM_GLOBAL, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(VM_GPD, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(arraydp), node_pos);\n\t\t//\tnew %frame0, %frame1()\n\t\tPutCode(VM_NEW, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1), node_pos);\n\t\tPutCode(0);  // argument count for \"new Array\"\n\t\t//\tconst %frame1, #zerodp\n\t\ttjs_int zerodp = PutData(tTJSVariant(tTVInteger(0)));\n\t\tPutCode(VM_CONST, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(zerodp), node_pos);\n\t\tframe += 2;\n\n\t\tArrayArgStack.push(tArrayArg());\n\t\tArrayArgStack.top().Object = frame0;\n\t\tArrayArgStack.top().Counter = frame0 + 1;\n\n\t\ttjs_int nodesize = node->GetSize();\n\t\tif(node->GetSize() == 1 && (*(*node)[0])[0] == NULL)\n\t\t{\n\t\t\t// the element is empty\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor(tjs_int i = 0; i<nodesize; i++)\n\t\t\t{\n\t\t\t\t_GenNodeCode(frame, (*node)[i], TJS_RT_NEEDED, 0, tSubParam()); // elements\n\t\t\t}\n\t\t}\n\n\t\tArrayArgStack.pop();\n\t\treturn (restype & TJS_RT_NEEDED)?(frame0):0;\n\t  }\n\n\tcase T_ARRAYARG:\n\t  {\n\t\t// an element of inline array\n\t\ttjs_int framestart = frame;\n\n\t\tresaddr = (*node)[0]?_GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam()):0;\n\n\t\t// spis %object.%count, %resaddr\n\t\tPutCode(VM_SPIS, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(ArrayArgStack.top().Object));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(ArrayArgStack.top().Counter));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr));\n\t\t// inc %count\n\t\tPutCode(VM_INC);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(ArrayArgStack.top().Counter));\n\n\t\tClearFrame(frame, framestart);\n\n\t\treturn 0;\n\t  }\n\n\n\tcase T_INLINEDIC:\n\t  {\n\t\t// inline dictionary\n\t\ttjs_int dicdp = PutData(tTJSVariant(TJS_W(\"Dictionary\")));\n\t\t//\tglobal %frame0\n\t\t//\tgpd %frame1, %frame0 . #dicdp // #dicdp = Dictionary\n\t\ttjs_int frame0 = frame;\n\t\tPutCode(VM_GLOBAL, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(VM_GPD, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(dicdp), node_pos);\n\t\t//\tnew %frame0, %frame1()\n\t\tPutCode(VM_NEW, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+0), node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1), node_pos);\n\t\tPutCode(0);  // argument count for \"Dictionary\" class\n\t\tframe += 2;\n\t\tClearFrame(frame, frame0 + 1);  // clear register at frame+1\n\n\t\tArrayArgStack.push(tArrayArg());\n\t\tArrayArgStack.top().Object = frame0;\n\n\t\ttjs_int nodesize = node->GetSize();\n\t\tfor(tjs_int i = 0; i < nodesize; i++)\n\t\t{\n\t\t\t_GenNodeCode(frame, (*node)[i], TJS_RT_NEEDED, 0, tSubParam()); // element\n\t\t}\n\n\t\tArrayArgStack.pop();\n\t\treturn (restype & TJS_RT_NEEDED) ? (frame0): 0;\n\t  }\n\n\tcase T_DICELM:\n\t  {\n\t\t// an element of inline dictionary\n\t\ttjs_int framestart = frame;\n\t\ttjs_int name;\n\t\ttjs_int value;\n\t\tname = _GenNodeCode(frame, (*node)[0], TJS_RT_NEEDED, 0, tSubParam());\n\t\tvalue = _GenNodeCode(frame, (*node)[1], TJS_RT_NEEDED, 0, tSubParam());\n\t\t// spis %object.%name, %value\n\t\tPutCode(VM_SPIS, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(ArrayArgStack.top().Object));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(name));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(value));\n\n\t\tClearFrame(frame, framestart);\n\n\t\treturn 0;\n\t  }\n\n\tcase T_REGEXP:\n\t  {\n\t\t// constant regular expression\n\t\tif(!(restype & TJS_RT_NEEDED)) return 0;\n\t\ttjs_int regexpdp = PutData(tTJSVariant(TJS_W(\"RegExp\")));\n\t\ttjs_int patdp = PutData(node->GetValue());\n\t\ttjs_int compiledp = PutData(tTJSVariant(TJS_W(\"_compile\")));\n\t\t// global %frame0\n\t\t//\tgpd %frame1, %frame0 . #regexpdp // #regexpdp = RegExp\n\t\ttjs_int frame0 = frame;\n\t\tPutCode(VM_GLOBAL, node_pos);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame));\n\t\tPutCode(VM_GPD);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame + 1));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(regexpdp));\n\t\t// const frame2, patdp;\n\t\tPutCode(VM_CONST);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame + 2));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(patdp));\n\t\t// new frame0 , frame1();\n\t\tPutCode(VM_NEW);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+1));\n\t\tPutCode(0);\n\t\t// calld 0, frame0 . #compiledp(frame2)\n\t\tPutCode(VM_CALLD);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(0));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame0));\n\t\tPutCode(TJS_TO_VM_REG_ADDR(compiledp));\n\t\tPutCode(1);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(frame+2));\n\t\tframe+=3;\n\t\tClearFrame(frame, frame0 + 1);\n\n\t\treturn frame0;\n\t  }\n\n\tcase T_VOID:\n\t\tif(param.SubType) _yyerror(TJSCannotModifyLHS, Block);\n\t\tif(!(restype & TJS_RT_NEEDED)) return 0;\n\t\treturn 0; // 0 is always void\n\t}\n\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_GenNodeCode = 0;\n#endif\n\ntjs_int tTJSInterCodeContext::_GenNodeCode(tjs_int & frame, tTJSExprNode *node,\n\ttjs_uint32 restype, tjs_int reqresaddr,\n\tconst tSubParam & param)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_GenNodeCode);\n#endif\n\ttjs_int res = GenNodeCode(frame, node, restype, reqresaddr, param);\n\treturn res;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::StartFuncArg()\n{\n\t// notify the start of function arguments\n\t// create a stack for function arguments\n\ttFuncArg arg;\n\tFuncArgStack.push(arg);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::AddFuncArg(const tjs_int addr, tTJSFuncArgType type)\n{\n\t// add a function argument\n\t// addr = register address to add\n\tFuncArgStack.top().ArgVector.push_back(tFuncArgItem(addr, type));\n\tif(type == fatExpand || type == fatUnnamedExpand)\n\t\tFuncArgStack.top().HasExpand = true; // has expanding node\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EndFuncArg()\n{\n\t// notify the end of function arguments\n\tFuncArgStack.pop();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::AddOmitArg()\n{\n\t// omit of the function arguments\n\tif(ContextType != ctFunction && ContextType != ctExprFunction)\n\t{\n\t\t_yyerror(TJSCannotOmit, Block);\n\t}\n\tFuncArgStack.top().IsOmit = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DoNestTopExitPatch(void)\n{\n\t// process the ExitPatchList which must be in the top of NextVector\n\tstd::vector<tjs_int> & vector = NestVector.back().ExitPatchVector;\n\tstd::vector<tjs_int>::iterator i;\n\tfor(i = vector.begin(); i != vector.end(); i++)\n\t{\n\t\tCodeArea[*i +1] = CodeAreaSize - *i;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DoContinuePatch(tNestData & nestdata)\n{\n\t// process the ContinuePatchList which must be in the top of NextVector\n\n\tstd::vector<tjs_int> & vector = nestdata.ContinuePatchVector;\n\tstd::vector<tjs_int>::iterator i;\n\tfor(i = vector.begin(); i != vector.end(); i++)\n\t{\n\t\tCodeArea[*i +1] = CodeAreaSize - *i;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ClearLocalVariable(tjs_int top, tjs_int bottom)\n{\n\t// clear local variable registers from top-1 to bottom\n#if 0\n\tif(top - bottom >= 3)\n\t{\n\t\tPutCode(VM_CCL); // successive clear instruction\n\t\tPutCode(TJS_TO_VM_REG_ADDR(-(top-1)-VariableReserveCount-1));\n\t\tPutCode(top-bottom);\n\t}\n\telse\n\t{\n\t\tfor(tjs_int i = bottom; i<top; i++)\n\t\t{\n\t\t\tPutCode(VM_CL);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-i-VariableReserveCount-1));\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ClearFrame(tjs_int &frame, tjs_int base)\n{\n\t// clear frame registers from \"frame-1\" to \"base\"\n\t// \"base\" is regaeded as \"FrameBase\" when \"base\" had been omitted.\n\t// \"frame\" may be changed.\n\n\tif(base == -1) base = FrameBase;\n\n\tif(frame-1 > MaxFrameCount) MaxFrameCount = frame-1;\n\n\tif(frame - base >= 3)\n\t{\n#if 0\n\t\tPutCode(VM_CCL);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(base));\n\t\tPutCode(frame-base);\n#endif\n\t\tframe = base;\n\t}\n\telse\n\t{\n\t\twhile(frame > base)\n\t\t{\n\t\t\tframe--;\n#if 0\n\t\t\tPutCode(VM_CL);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(frame));\n#endif\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n\nvoid tTJSInterCodeContext::AddLocalVariable(const tjs_char *name, tjs_int init)\n{\n\t// create a local variable\n\t// ( however create it in \"this\" when the variable is defined at global )\n\t// name = variable name\n\n\t// init = register address that points initial value ( 0 = no initial value )\n\n\ttjs_int base = ContextType == ctClass ? 2: 1;\n\tif(Namespace.GetLevel() >= base)\n\t{\n\t\t// create on local\n//\t\ttjs_int ff = Namespace.Find(name);\n\t\tNamespace.Add(name);\n\t\tif(init != 0)\n\t\t{\n\t\t\t// initial value is given\n\t\t\ttjs_int n = Namespace.Find(name);\n#ifdef ENABLE_DEBUGGER\n\t\t\tint regoffset = TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1);\n\t\t\t// class name, func name, file name, code offset, var name, reg offset\n\t\t\tTJSDebuggerAddLocalVariable( GetClassName().c_str(), GetName(), Block->GetName(), FunctionRegisterCodePoint, name, regoffset );\n#endif // ENABLE_DEBUGGER\n\t\t\tPutCode(VM_CP, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(init), LEX_POS);\n\t\t}\n\t\telse/* if(ff==-1) */\n\t\t{\n\t\t\t// first initialization\n\t\t\ttjs_int n = Namespace.Find(name);\n#ifdef ENABLE_DEBUGGER\n\t\t\tint regoffset = TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1);\n\t\t\t// class name, func name, file name, code offset, var name, reg offset\n\t\t\tTJSDebuggerAddLocalVariable( GetClassName().c_str(), GetName(), Block->GetName(), FunctionRegisterCodePoint, name, regoffset );\n#endif // ENABLE_DEBUGGER\n\t\t\tPutCode(VM_CL, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(-n-VariableReserveCount-1), LEX_POS);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// create member on this\n\t\ttjs_int\tdp = PutData(tTJSVariant(name));\n#ifdef ENABLE_DEBUGGER\n\t\tTJSDebuggerAddClassVariable( GetSelfClassName().c_str(), name, TJS_TO_VM_REG_ADDR(dp) );\n#endif // ENABLE_DEBUGGER\n\t\tPutCode(VM_SPDS, LEX_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(-1), LEX_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(dp), LEX_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(init), LEX_POS);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::InitLocalVariable(const tjs_char *name, tTJSExprNode *node)\n{\n\t// create a local variable named \"name\", with inial value of the\n\t// expression node of \"node\".\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\tAddLocalVariable(name, resaddr);\n\tClearFrame(fr);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::InitLocalFunction(const tjs_char *name, tjs_int data)\n{\n\t// create a local function variable pointer by data ( in DataArea ),\n\t// named \"name\".\n\n\ttjs_int fr = FrameBase;\n\tPutCode(VM_CONST, LEX_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(fr), LEX_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(data));\n\tfr++;\n\tAddLocalVariable(name, fr-1);\n\tClearFrame(fr);\n}\n//---------------------------------------------------------------------------\n\nvoid tTJSInterCodeContext::CreateExprCode(tTJSExprNode *node)\n{\n\t// create code of node\n\ttjs_int fr = FrameBase;\n\tGenNodeCode(fr, node, 0, 0, tSubParam());\n\tClearFrame(fr);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterWhileCode(bool do_while)\n{\n\t// enter to \"while\"\n\t// ( do_while = true indicates do-while syntax )\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = do_while?ntDoWhile:ntWhile;\n\tNestVector.back().LoopStartIP = CodeAreaSize;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CreateWhileExprCode(tTJSExprNode *node, bool do_while)\n{\n\t// process the condition expression \"node\"\n\n\tif(do_while)\n\t{\n\t\tDoContinuePatch(NestVector.back());\n\t}\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED|TJS_RT_CFLAG, 0, tSubParam());\n\tbool inv = false;\n\tif(!TJSIsCondFlagRetValue(resaddr))\n\t{\n\t\tPutCode(VM_TT, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t}\n\telse\n\t{\n\t\tif(resaddr == TJS_GNC_CFLAG_I) inv = true;\n\t}\n\tClearFrame(fr);\n\n\tif(!do_while)\n\t{\n\t\tNestVector.back().ExitPatchVector.push_back(CodeAreaSize);\n\t\tAddJumpList();\n\t\tPutCode(inv?VM_JF:VM_JNF, NODE_POS);\n\t\tPutCode(0, NODE_POS);\n\t}\n\telse\n\t{\n\t\ttjs_int jmp_ip = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(inv?VM_JNF:VM_JF, NODE_POS);\n\t\tPutCode(NestVector.back().LoopStartIP - jmp_ip, NODE_POS);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitWhileCode(bool do_while)\n{\n\t// exit from \"while\"\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(do_while)\n\t{\n\t\tif(NestVector.back().Type != ntDoWhile)\n\t\t{\n\t\t\t_yyerror(TJSSyntaxError, Block);\n\t\t\treturn;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(NestVector.back().Type != ntWhile)\n\t\t{\n\t\t\t_yyerror(TJSSyntaxError, Block);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif(!do_while)\n\t{\n\t\ttjs_int jmp_ip = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JMP, LEX_POS);\n\t\tPutCode(NestVector.back().LoopStartIP - jmp_ip, LEX_POS);\n\t}\n\tDoNestTopExitPatch();\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterIfCode()\n{\n\t// enter to \"if\"\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntIf;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CreateIfExprCode(tTJSExprNode *node)\n{\n\t// process condition expression \"node\"\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED|TJS_RT_CFLAG, 0, tSubParam());\n\tbool inv = false;\n\tif(!TJSIsCondFlagRetValue(resaddr))\n\t{\n\t\tPutCode(VM_TT, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t}\n\telse\n\t{\n\t\tif(resaddr == TJS_GNC_CFLAG_I) inv = true;\n\t}\n\tClearFrame(fr);\n\tNestVector.back().Patch1 = CodeAreaSize;\n\tAddJumpList();\n\tPutCode(inv?VM_JF:VM_JNF, NODE_POS);\n\tPutCode(0, NODE_POS);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitIfCode()\n{\n\t// exit from if\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntIf)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\tCodeArea[NestVector.back().Patch1 + 1] = CodeAreaSize - NestVector.back().Patch1;\n\tPrevIfExitPatch = NestVector.back().Patch1;\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterElseCode()\n{\n\t// enter to \"else\".\n\t// before is \"if\", is clear from syntax definition.\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntElse;\n\tNestVector.back().Patch2 = CodeAreaSize;\n\tAddJumpList();\n\tPutCode(VM_JMP, LEX_POS);\n\tPutCode(0, LEX_POS);\n\tCodeArea[PrevIfExitPatch + 1] = CodeAreaSize - PrevIfExitPatch;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitElseCode()\n{\n\t// exit from else\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntElse)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\tCodeArea[NestVector.back().Patch2 + 1] = CodeAreaSize - NestVector.back().Patch2;\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterForCode()\n{\n\t// enter to \"for\".\n\t// ( varcreate = true, indicates that the variable is to be created in the\n\t//\tfirst clause )\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntFor;\n\tEnterBlock();\n\t// create a scope for \"for\" initializing clause even it does not introduce\n\t//   local variables, due to brevity of semantics\n\t//NestVector.back().VariableCreated = false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CreateForExprCode(tTJSExprNode *node)\n{\n\t// process the \"for\"'s second clause; a condition expression\n\n\tNestVector.back().LoopStartIP = CodeAreaSize;\n\tif(node)\n\t{\n\t\ttjs_int fr = FrameBase;\n\t\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED|TJS_RT_CFLAG,\n\t\t\t0, tSubParam());\n\t\tbool inv = false;\n\t\tif(!TJSIsCondFlagRetValue(resaddr))\n\t\t{\n\t\t\tPutCode(VM_TT, NODE_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(resaddr == TJS_GNC_CFLAG_I) inv = true;\n\t\t}\n\t\tClearFrame(fr);\n\t\tNestVector.back().ExitPatchVector.push_back(CodeAreaSize);\n\t\tAddJumpList();\n\t\tPutCode(inv?VM_JF:VM_JNF, NODE_POS);\n\t\tPutCode(0, NODE_POS);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SetForThirdExprCode(tTJSExprNode *node)\n{\n\t// process the \"for\"'s third clause; a post-loop expression\n\n\tNestVector.back().PostLoopExpr = node;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitForCode()\n{\n\t// exit from \"for\"\n\ttjs_int nestsize = (tjs_int)NestVector.size();\n\tif(nestsize == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntFor && NestVector.back().Type != ntBlock)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\tif(NestVector.back().Type == ntFor)\n\t\tDoContinuePatch(NestVector.back());\n\tif(nestsize >= 2 && NestVector[nestsize-2].Type == ntFor)\n\t\tDoContinuePatch(NestVector[nestsize-2]);\n\n\n\tif(NestVector.back().PostLoopExpr)\n\t{\n\t\ttjs_int fr = FrameBase;\n\t\tGenNodeCode(fr, NestVector.back().PostLoopExpr, false, 0, tSubParam());\n\t\tClearFrame(fr);\n\t}\n\ttjs_int jmp_ip = CodeAreaSize;\n\tAddJumpList();\n\tPutCode(VM_JMP, LEX_POS);\n\tPutCode(NestVector.back().LoopStartIP - jmp_ip, LEX_POS);\n\tDoNestTopExitPatch();\n\tExitBlock();\n\tDoNestTopExitPatch();\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterSwitchCode(tTJSExprNode *node)\n{\n\t// enter to \"switch\"\n\t// \"node\" indicates a reference expression\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntSwitch;\n\tNestVector.back().Patch1 = -1;\n\tNestVector.back().Patch2 = -1;\n\tNestVector.back().IsFirstCase = true;\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\n\tif(FrameBase != resaddr)\n\t{\n\t\tPutCode(VM_CP, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(FrameBase), NODE_POS); // FrameBase points the reference value\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t}\n\n\tNestVector.back().RefRegister = FrameBase;\n\n\tif(fr-1 > MaxFrameCount) MaxFrameCount = fr-1;\n\n\tFrameBase ++; // increment FrameBase\n\tif(FrameBase-1 > MaxFrameCount) MaxFrameCount = FrameBase-1;\n\n\tClearFrame(fr);\n\n\tEnterBlock();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitSwitchCode()\n{\n\t// exit from switch\n\n\tExitBlock();\n\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntSwitch)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\ttjs_int patch3;\n\tif(!NestVector.back().IsFirstCase)\n\t{\n\t\tpatch3 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JMP, LEX_POS);\n\t\tPutCode(0, LEX_POS);\n\t}\n\n\n\tif(NestVector.back().Patch1 != -1)\n\t{\n\t\tCodeArea[NestVector.back().Patch1 +1] = CodeAreaSize - NestVector.back().Patch1;\n\t}\n\n\tif(NestVector.back().Patch2 != -1)\n\t{\n\t\tAddJumpList();\n\t\ttjs_int jmp_start = CodeAreaSize;\n\t\tPutCode(VM_JMP, LEX_POS);\n\t\tPutCode(NestVector.back().Patch2 - jmp_start, LEX_POS);\n\t}\n\n\tif(!NestVector.back().IsFirstCase)\n\t{\n\t\tCodeArea[patch3 +1] = CodeAreaSize - patch3;\n\t}\n\n\n\tDoNestTopExitPatch();\n#if 0\n\tPutCode(VM_CL, LEX_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(NestVector.back().RefRegister), LEX_POS);\n#endif\n\tFrameBase--;\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ProcessCaseCode(tTJSExprNode *node)\n{\n\t// process \"case expression :\".\n\t// process \"default :\" if node == NULL.\n\n\ttjs_int nestsize = (tjs_int)NestVector.size();\n\n\tif(nestsize < 3)\n\t{\n\t\t_yyerror(TJSMisplacedCase, Block);\n\t\treturn;\n\t}\n\tif(NestVector[nestsize-1].Type != ntBlock ||\n\t\tNestVector[nestsize-2].Type != ntBlock ||\n\t\tNestVector[nestsize-3].Type != ntSwitch)\n\t{\n\t\t// the stack layout must be ( from top )\n\t\t// ntBlock, ntBlock, ntSwitch\n\t\t_yyerror(TJSMisplacedCase, Block);\n\t\treturn;\n\t}\n\n\ttNestData &data = NestVector[NestVector.size()-3];\n\n\ttjs_int patch3;\n\tif(!data.IsFirstCase)\n\t{\n\t\tpatch3 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JMP, NODE_POS);\n\t\tPutCode(0, NODE_POS);\n\t}\n\n\tExitBlock();\n\tif(data.Patch1 != -1)\n\t{\n\t\tCodeArea[data.Patch1 +1] = CodeAreaSize -data.Patch1;\n\t}\n\n\tif(node)\n\t{\n\t\ttjs_int fr = FrameBase;\n\t\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\t\tPutCode(VM_CEQ, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(data.RefRegister), NODE_POS);\n\t\t\t// compare to reference value with normal comparison\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t\tClearFrame(fr);\n\t\tdata.Patch1 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JNF, NODE_POS);\n\t\tPutCode(0, NODE_POS);\n\t}\n\telse\n\t{\n\t\tdata.Patch1 = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JMP, NODE_POS);\n\t\tPutCode(0, NODE_POS);\n\n\t\tdata.Patch2 = CodeAreaSize; // Patch2 = \"default:\"'s position\n\t}\n\n\n\tif(!data.IsFirstCase)\n\t{\n\t\tCodeArea[patch3 +1] = CodeAreaSize - patch3;\n\t}\n\tdata.IsFirstCase = false;\n\n\tEnterBlock();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterWithCode(tTJSExprNode *node)\n{\n\t// enter to \"with\"\n\t// \"node\" indicates a reference expression\n\n\t// this method and ExitWithCode are very similar to switch's code.\n\t// (those are more simple than that...)\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\n\tif(FrameBase != resaddr)\n\t{\n\t\t// bring the reference variable to frame base top\n\t\tPutCode(VM_CP, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(FrameBase), NODE_POS); // FrameBase points the reference value\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t}\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntWith;\n\n\tNestVector.back().RefRegister = FrameBase;\n\n\tif(fr-1 > MaxFrameCount) MaxFrameCount = fr-1;\n\n\tFrameBase ++; // increment FrameBase\n\tif(FrameBase-1 > MaxFrameCount) MaxFrameCount = FrameBase-1;\n\n\tClearFrame(fr);\n\n\tEnterBlock();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitWithCode()\n{\n\t// exit from switch\n\tExitBlock();\n\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntWith)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n#if 0\n\tPutCode(VM_CL, LEX_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(NestVector.back().RefRegister), LEX_POS);\n#endif\n\tFrameBase--;\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DoBreak(void)\n{\n\t// process \"break\".\n\n\t// search in NestVector backwards\n\ttjs_int vc = Namespace.GetCount();\n\ttjs_int pvc = vc;\n\n\ttjs_int i = (tjs_int)(NestVector.size() -1);\n\tfor(; i>=0; i--)\n\t{\n\t\ttNestData &data = NestVector[i];\n\t\tif(data.Type == ntSwitch ||\n\t\t\tdata.Type == ntWhile || data.Type == ntDoWhile ||\n\t\t\tdata.Type == ntFor)\n\t\t{\n\t\t\t// \"break\" can apply on this syntax\n\t\t\tClearLocalVariable(vc, pvc); // clear local variables\n\t\t\tdata.ExitPatchVector.push_back(CodeAreaSize);\n\t\t\tAddJumpList();\n\t\t\tPutCode(VM_JMP, LEX_POS);\n\t\t\tPutCode(0, LEX_POS); // later patches here\n\t\t\treturn;\n\t\t}\n\t\telse if(data.Type == ntBlock)\n\t\t{\n\t\t\tpvc = data.VariableCount;\n\t\t}\n\t\telse if(data.Type == ntTry)\n\t\t{\n\t\t\tPutCode(VM_EXTRY);\n\t\t}\n\t\telse if(data.Type == ntSwitch || data.Type == ntWith)\n\t\t{\n\t\t\t// clear reference register of \"switch\" or \"with\" syntax\n#if 0\n\t\t\tPutCode(VM_CL, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(data.RefRegister), LEX_POS);\n#endif\n\t\t}\n\t}\n\n\t_yyerror(TJSMisplacedBreakContinue, Block);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DoContinue(void)\n{\n\t// process \"continue\".\n\n\t// generate code that jumps before '}' ( the end of the loop ).\n\t// for \"while\" loop, the jump code immediately jumps to the condition check code.\n\n\t// search in NestVector backwards\n\ttjs_int vc = Namespace.GetCount();\n\ttjs_int pvc = vc;\n\n\ttjs_int i = (tjs_int)(NestVector.size() -1);\n\tfor(; i>=0; i--)\n\t{\n\t\ttNestData &data = NestVector[i];\n\t\tif(data.Type == ntWhile)\n\t\t{\n\t\t\t// for \"while\" loop\n\t\t\tClearLocalVariable(vc, pvc); // clear local variables\n\t\t\ttjs_int jmpstart = CodeAreaSize;\n\t\t\tAddJumpList();\n\t\t\tPutCode(VM_JMP, LEX_POS);\n\t\t\tPutCode(data.LoopStartIP - jmpstart, LEX_POS);\n\t\t\treturn;\n\t\t}\n\t\telse if(data.Type == ntDoWhile || data.Type == ntFor)\n\t\t{\n\t\t\t// \"do-while\" or \"for\" loop needs forward jump\n\t\t\tClearLocalVariable(vc, pvc); // clears local variables\n\t\t\tdata.ContinuePatchVector.push_back(CodeAreaSize);\n\t\t\tAddJumpList();\n\t\t\tPutCode(VM_JMP, LEX_POS);\n\t\t\tPutCode(0, LEX_POS); // later patch this\n\t\t\treturn;\n\t\t}\n\t\telse if(data.Type == ntBlock)\n\t\t{\n\t\t\t// does not count variables which created at for loop's\n\t\t\t// first clause\n\t\t\tif(i < 1 || NestVector[i-1].Type != ntFor ||\n\t\t\t\t!NestVector[i].VariableCreated)\n\t\t\t\tpvc = data.VariableCount;\n\t\t}\n\t\telse if(data.Type == ntTry)\n\t\t{\n\t\t\tPutCode(VM_EXTRY, LEX_POS);\n\t\t}\n\t\telse if(data.Type == ntSwitch || data.Type == ntWith)\n\t\t{\n\t\t\t// clear reference register of \"switch\" or \"with\" syntax\n#if 0\n\t\t\tPutCode(VM_CL, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(data.RefRegister), LEX_POS);\n#endif\n\t\t}\n\t}\n\n\t_yyerror(TJSMisplacedBreakContinue, Block);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::DoDebugger()\n{\n\t// process \"debugger\" statement.\n\tPutCode(VM_DEBUGGER, LEX_POS);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ReturnFromFunc(tTJSExprNode *node)\n{\n\t// precess \"return\"\n\t// note: the \"return\" positioned in global immediately returns without\n\t// execution of the remainder code.\n\n\tif(!node)\n\t{\n\t\t// no return value\n\t\tPutCode(VM_SRV, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(0), NODE_POS);  // returns register #0 = void\n\t}\n\telse\n\t{\n\t\t// generates return expression\n\t\ttjs_int fr = FrameBase;\n\t\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\n\t\tPutCode(VM_SRV, NODE_POS);\n\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\n\t\tClearFrame(fr);\n\n\t}\n\n\t// clear the frame\n\ttjs_int org_framebase = FrameBase;\n\tClearFrame(FrameBase, 1);\n\tFrameBase = org_framebase;\n\n\t// clear local variables\n\tClearLocalVariable(Namespace.GetCount(), 0);\n\n\t// check try block\n\ttjs_int i = (tjs_int)(NestVector.size() -1);\n\tfor(; i>=0; i--)\n\t{\n\t\ttNestData &data = NestVector[i];\n\t\tif(data.Type == ntTry)\n\t\t{\n\t\t\tPutCode(VM_EXTRY, LEX_POS); // exit from try-protected block\n\t\t}\n\t}\n\n\n\tPutCode(VM_RET, LEX_POS);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterTryCode()\n{\n\t// enter to \"try\"\n\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntTry;\n\tNestVector.back().VariableCreated = false;\n\n\tNestVector.back().Patch1 = CodeAreaSize;\n\tAddJumpList();\n\tPutCode(VM_ENTRY, LEX_POS);\n\tPutCode(0, LEX_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(FrameBase), LEX_POS); // an exception object will be held here\n\n\tif(FrameBase > MaxFrameCount) MaxFrameCount = FrameBase;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterCatchCode(const tjs_char *name)\n{\n\t// enter to \"catch\"\n\n\tPutCode(VM_EXTRY, LEX_POS);\n\tNestVector.back().Patch2 = CodeAreaSize;\n\tAddJumpList();\n\tPutCode(VM_JMP, LEX_POS);\n\tPutCode(0, LEX_POS);\n\n\tCodeArea[NestVector.back().Patch1 + 1] = CodeAreaSize - NestVector.back().Patch1;\n\n\t// clear local variables\n\tClearLocalVariable(Namespace.GetMaxCount(), Namespace.GetCount());\n\n\t// clear frame\n\ttjs_int fr = MaxFrameCount + 1;\n\ttjs_int base = name ? FrameBase+1 : FrameBase;\n\tClearFrame(fr, base);\n\n\t// change nest type to ntCatch\n\tNestVector.back().Type = ntCatch;\n\n\t// create variable if the catch clause has a receiver variable name\n\tif(name)\n\t{\n\t\tNestVector.back().VariableCreated = true;\n\t\tEnterBlock();\n\t\tAddLocalVariable(name, FrameBase);\n\t\t\t// cleate a variable that receives the exception object\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitTryCode()\n{\n\t// exit from \"try\"\n\tif(NestVector.size() >= 2)\n\t{\n\t\tif(NestVector[NestVector.size()-2].Type == ntCatch)\n\t\t{\n\t\t\tif(NestVector[NestVector.size()-2].VariableCreated)\n\t\t\t{\n\t\t\t\tExitBlock();\n\t\t\t}\n\t\t}\n\t}\n\t\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntCatch)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\n\ttjs_int p2addr = NestVector.back().Patch2;\n\n\tCodeArea[p2addr + 1] = CodeAreaSize - p2addr;\n\tNestVector.pop_back();\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ProcessThrowCode(tTJSExprNode *node)\n{\n\t// process \"throw\".\n\t// node = expressoin to throw\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\tPutCode(VM_THROW, NODE_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\tif(fr-1 > MaxFrameCount) MaxFrameCount = fr-1;\n#if 0\n\twhile(fr-->FrameBase)\n\t{\n\t\tPutCode(VM_CL);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(fr));\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CreateExtendsExprCode(tTJSExprNode *node, bool hold)\n{\n\t// process class extender\n\n\t//tjs_int num;\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\n\tPutCode(VM_CHGTHIS, NODE_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(-1), NODE_POS);\n\n\tPutCode(VM_CALL, NODE_POS);\n\tPutCode(0, NODE_POS);\n\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\tPutCode(0, NODE_POS);\n\n\tif(hold)\n\t{\n\t\tSuperClassExpr = node;\n\t}\n\n\tFunctionRegisterCodePoint = CodeAreaSize; // update FunctionRegisterCodePoint\n\n\t// create a Super Class Proxy context\n\tif(!SuperClassGetter)\n\t{\n\t\tSuperClassGetter =\n\t\t\tnew tTJSInterCodeContext(this, Name, Block, ctSuperClassGetter);\n\t}\n\n\tSuperClassGetter->CreateExtendsExprProxyCode(node);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::CreateExtendsExprProxyCode(tTJSExprNode *node)\n{\n\t// create super class proxy to retrieve super class\n\tSuperClassGetterPointer.push_back(CodeAreaSize);\n\n\ttjs_int fr = FrameBase;\n\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\n\tPutCode(VM_SRV);\n\tPutCode(TJS_TO_VM_REG_ADDR(resaddr));\n\tClearFrame(fr);\n\n\tPutCode(VM_RET);\n\n\tPutCode(VM_NOP, NODE_POS);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::EnterBlock()\n{\n\t// enter to block\n\n\tNamespace.Push();\n\ttjs_int varcount = Namespace.GetCount();\n\tNestVector.push_back(tNestData());\n\tNestVector.back().Type = ntBlock;\n\tNestVector.back().VariableCount = varcount;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::ExitBlock()\n{\n\t// exit from block\n\tif(NestVector.size() == 0)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\tif(NestVector.back().Type != ntBlock)\n\t{\n\t\t_yyerror(TJSSyntaxError, Block);\n\t\treturn;\n\t}\n\n\tNestVector.pop_back();\n\ttjs_int prevcount = Namespace.GetCount();\n\tNamespace.Pop();\n\ttjs_int curcount = Namespace.GetCount();\n\tClearLocalVariable(prevcount, curcount);\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::GenerateFuncCallArgCode()\n{\n\tif(FuncArgStack.top().IsOmit)\n\t{\n\t\tPutCode(-1, LEX_POS); // omit (...) is specified\n\t}\n\telse if(FuncArgStack.top().HasExpand)\n\t{\n\t\tPutCode(-2, LEX_POS); // arguments have argument expanding node\n\t\tstd::vector<tFuncArgItem> & vec = FuncArgStack.top().ArgVector;\n\t\tPutCode((tjs_int)vec.size(), LEX_POS); // count of the arguments\n\t\ttjs_uint i;\n\t\tfor(i=0; i<vec.size(); i++)\n\t\t{\n\t\t\tPutCode((tjs_int32)vec[i].Type, LEX_POS);\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(vec[i].Register), LEX_POS);\n\t\t}\n\t}\n\telse\n\t{\n\t\tstd::vector<tFuncArgItem> & vec = FuncArgStack.top().ArgVector;\n\t\tPutCode((tjs_int)vec.size(), LEX_POS); // count of arguments\n\t\ttjs_uint i;\n\t\tfor(i=0; i<vec.size(); i++)\n\t\t\tPutCode(TJS_TO_VM_REG_ADDR(vec[i].Register), LEX_POS);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::AddFunctionDeclArg(const tjs_char *varname, tTJSExprNode *node)\n{\n\t// process the function argument of declaration\n\t// varname = argument name\n\t// init = initial expression\n\n\tNamespace.Add(varname);\n//\tAddLocalVariable(varname);\n\n\tif(node)\n\t{\n\t\tPutCode(VM_CDEQ, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(-3 - FuncDeclArgCount), NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(0), NODE_POS);\n\t\ttjs_int jmp_ip = CodeAreaSize;\n\t\tAddJumpList();\n\t\tPutCode(VM_JNF), NODE_POS;\n\t\tPutCode(0, NODE_POS);\n\n\t\ttjs_int fr = FrameBase;\n\t\ttjs_int resaddr = GenNodeCode(fr, node, TJS_RT_NEEDED, 0, tSubParam());\n\t\tPutCode(VM_CP, NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(-3 - FuncDeclArgCount), NODE_POS);\n\t\tPutCode(TJS_TO_VM_REG_ADDR(resaddr), NODE_POS);\n\t\tClearFrame(fr);\n\n\t\tCodeArea[jmp_ip+1] = CodeAreaSize - jmp_ip;\n\n\t}\n\tFuncDeclArgCount++;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::AddFunctionDeclArgCollapse(const tjs_char *varname)\n{\n\t// process the function \"collapse\" argument of declaration.\n\t// collapse argument is available to receive arguments in array object form.\n\n\tif(varname == NULL)\n\t{\n\t\t// receive arguments in unnamed array\n\t\tFuncDeclUnnamedArgArrayBase = FuncDeclArgCount;\n\t}\n\telse\n\t{\n\t\t// receive arguments in named array\n\t\tFuncDeclCollapseBase = FuncDeclArgCount;\n\t\tNamespace.Add(varname);\t\t\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::SetPropertyDeclArg(const tjs_char *varname)\n{\n\t// process the setter argument\n\n\tNamespace.Add(varname);\n\tFuncDeclArgCount = 1;\n}\n//---------------------------------------------------------------------------\nconst tjs_char * tTJSInterCodeContext::GetName() const\n{\n\treturn Name;\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::PushCurrentNode(tTJSExprNode *node)\n{\n\tCurrentNodeVector.push_back(node);\n}\n//---------------------------------------------------------------------------\ntTJSExprNode * tTJSInterCodeContext::GetCurrentNode()\n{\n\ttjs_uint size = (tjs_uint)CurrentNodeVector.size();\n\tif(size == 0) return NULL;\n\treturn CurrentNodeVector[size-1];\n}\n//---------------------------------------------------------------------------\nvoid tTJSInterCodeContext::PopCurrentNode()\n{\n\tCurrentNodeVector.pop_back();\n}\n//---------------------------------------------------------------------------\ntTJSExprNode * tTJSInterCodeContext::MakeConstValNode(const tTJSVariant &val)\n{\n\ttTJSExprNode * n = new tTJSExprNode;\n\tNodeToDeleteVector.push_back(n);\n\tn->SetOpecode(T_CONSTVAL);\n\tn->SetValue(val);\n\tn->SetPosition(LEX_POS);\n\treturn n;\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_make_np = 0;\n#endif\n\ntTJSExprNode * tTJSInterCodeContext::MakeNP0(tjs_int opecode)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_make_np);\n#endif\n\ttTJSExprNode * n = new tTJSExprNode;\n\tNodeToDeleteVector.push_back(n);\n\tn->SetOpecode(opecode);\n\tn->SetPosition(LEX_POS);\n\treturn n;\n}\n//---------------------------------------------------------------------------\ntTJSExprNode * tTJSInterCodeContext::MakeNP1(tjs_int opecode, tTJSExprNode * node1)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_make_np);\n#endif\n\n#ifndef TJS_NO_CONSTANT_FOLDING\n\tif(node1 && node1->GetOpecode() == T_CONSTVAL)\n\t{\n\t\t// constant folding\n\t\ttTJSExprNode * ret = NULL;\n\n\t\tswitch(opecode)\n\t\t{\n\t\tcase T_EXCRAMATION:\n\t\t\tret = MakeConstValNode(!node1->GetValue());\n\t\t\tbreak;\n\t\tcase T_TILDE:\n\t\t\tret = MakeConstValNode(~node1->GetValue());\n\t\t\tbreak;\n\t\tcase T_SHARP:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tCharacterCodeOf(val);\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_DOLLAR:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tCharacterCodeFrom(val);\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_UPLUS:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.tonumber();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_UMINUS:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.changesign();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_INT:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.ToInteger();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_REAL:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.ToReal();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_STRING:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.ToString();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tcase T_OCTET:\n\t\t  {\n\t\t\ttTJSVariant val(node1->GetValue());\n\t\t\tval.ToOctet();\n\t\t\tret = MakeConstValNode(val);\n\t\t  }\n\t\t\tbreak;\n\t\tdefault: ;\n\t\t}\n\t\tif(ret)\n\t\t{\n\t\t\tnode1->Clear(); // not to have data no longer\n\t\t\treturn ret;\n\t\t}\n\t}\n#endif\n\n\ttTJSExprNode * n = new tTJSExprNode;\n\tNodeToDeleteVector.push_back(n);\n\tn->SetOpecode(opecode);\n\tn->SetPosition(LEX_POS);\n\tn->Add(node1);\n\treturn n;\n}\n//---------------------------------------------------------------------------\ntTJSExprNode * tTJSInterCodeContext::MakeNP2(tjs_int opecode, tTJSExprNode * node1, tTJSExprNode * node2)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_make_np);\n#endif\n\n#ifndef TJS_NO_CONSTANT_FOLDING\n\tif(node1 && node1->GetOpecode() == T_CONSTVAL &&\n\t\tnode2 && node2->GetOpecode() == T_CONSTVAL)\n\t{\n\t\t// constant folding\n\t\tswitch(opecode)\n\t\t{\n\t\tcase T_COMMA:\n\t\t\treturn MakeConstValNode(node2->GetValue());\n\t\tcase T_LOGICALOR:\n\t\t\treturn MakeConstValNode(node1->GetValue() || node2->GetValue());\n\t\tcase T_LOGICALAND:\n\t\t\treturn MakeConstValNode(node1->GetValue() && node2->GetValue());\n\t\tcase T_VERTLINE:\n\t\t\treturn MakeConstValNode(node1->GetValue() | node2->GetValue());\n\t\tcase T_CHEVRON:\n\t\t\treturn MakeConstValNode(node1->GetValue() ^ node2->GetValue());\n\t\tcase T_AMPERSAND:\n\t\t\treturn MakeConstValNode(node1->GetValue() & node2->GetValue());\n\t\tcase T_NOTEQUAL:\n\t\t\treturn MakeConstValNode(node1->GetValue() != node2->GetValue());\n\t\tcase T_EQUALEQUAL:\n\t\t\treturn MakeConstValNode(node1->GetValue() == node2->GetValue());\n\t\tcase T_DISCNOTEQUAL:\n\t\t\treturn MakeConstValNode(!(node1->GetValue().DiscernCompare(node2->GetValue())));\n\t\tcase T_DISCEQUAL:\n\t\t\treturn MakeConstValNode( (node1->GetValue().DiscernCompare(node2->GetValue())));\n\t\tcase T_LT:\n\t\t\treturn MakeConstValNode(node1->GetValue() < node2->GetValue());\n\t\tcase T_GT:\n\t\t\treturn MakeConstValNode(node1->GetValue() > node2->GetValue());\n\t\tcase T_LTOREQUAL:\n\t\t\treturn MakeConstValNode(node1->GetValue() <= node2->GetValue());\n\t\tcase T_GTOREQUAL:\n\t\t\treturn MakeConstValNode(node1->GetValue() >= node2->GetValue());\n\t\tcase T_RARITHSHIFT:\n\t\t\treturn MakeConstValNode(node1->GetValue() >> node2->GetValue());\n\t\tcase T_LARITHSHIFT:\n\t\t\treturn MakeConstValNode(node1->GetValue() << node2->GetValue());\n\t\tcase T_RBITSHIFT:\n\t\t\treturn MakeConstValNode( (node1->GetValue().rbitshift(node2->GetValue())));\n\t\tcase T_PLUS:\n\t\t\treturn MakeConstValNode(node1->GetValue() + node2->GetValue());\n\t\tcase T_MINUS:\n\t\t\treturn MakeConstValNode(node1->GetValue() - node2->GetValue());\n\t\tcase T_PERCENT:\n\t\t\treturn MakeConstValNode(node1->GetValue() % node2->GetValue());\n\t\tcase T_SLASH:\n\t\t\treturn MakeConstValNode(node1->GetValue() / node2->GetValue());\n\t\tcase T_BACKSLASH:\n\t\t\treturn MakeConstValNode( (node1->GetValue().idiv(node2->GetValue())));\n\t\tcase T_ASTERISK:\n\t\t\treturn MakeConstValNode(node1->GetValue() * node2->GetValue());\n\t\tdefault: ;\n\t\t}\n\t}\n#endif\n\n\n\ttTJSExprNode * n = new tTJSExprNode;\n\tNodeToDeleteVector.push_back(n);\n\tn->SetOpecode(opecode);\n\tn->SetPosition(LEX_POS);\n\tn->Add(node1);\n\tn->Add(node2);\n\treturn n;\n}\n//---------------------------------------------------------------------------\ntTJSExprNode * tTJSInterCodeContext::MakeNP3(tjs_int opecode, tTJSExprNode * node1, tTJSExprNode * node2,\n\ttTJSExprNode * node3)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_make_np);\n#endif\n\ttTJSExprNode * n = new tTJSExprNode;\n\tNodeToDeleteVector.push_back(n);\n\tn->SetOpecode(opecode);\n\tn->SetPosition(LEX_POS);\n\tn->Add(node1);\n\tn->Add(node2);\n\tn->Add(node3);\n\treturn n;\n}\n//---------------------------------------------------------------------------\n\n/**\n * oCgR[ho͂\n * @return\n */\nstd::vector<tjs_uint8>* tTJSInterCodeContext::ExportByteCode( bool outputdebug, tTJSScriptBlock *block, tjsConstArrayData& constarray )\n{\n\tint parent = -1;\n\tif( Parent != NULL ) {\n\t\tparent = block->GetCodeIndex(Parent);\n\t}\n\tint propSetter = -1;\n\tif( PropSetter != NULL ) {\n\t\tpropSetter = block->GetCodeIndex(PropSetter);\n\t}\n\tint propGetter = -1;\n\tif( PropGetter != NULL ) {\n\t\tpropGetter = block->GetCodeIndex(PropGetter);\n\t}\n\tint superClassGetter = -1;\n\tif( SuperClassGetter != NULL ) {\n\t\tsuperClassGetter = block->GetCodeIndex(SuperClassGetter);\n\t}\n\tint name = -1;\n\tif( Name != NULL ) {\n\t\tname = constarray.PutString(Name);\n\t}\n\t// 13 * 4 f[^̃TCY\n\tint count = 0;\n\tif (outputdebug) {\n\t\tcount = SourcePosArraySize;\n\t}\n\tint srcpossize = count * 8;\n\tint codesize = (CodeAreaSize % 2) == 1 ? CodeAreaSize * 2 + 2 : CodeAreaSize * 2;\n\tint datasize = DataAreaSize * 4;\n\tint scgpsize = (int)(SuperClassGetterPointer.size() * 4);\n\tint propsize = (int)((Properties != NULL ? Properties->size() * 8 : 0)+4);\n\tint size = 12*4 + srcpossize + codesize + datasize + scgpsize + propsize + 4*4;\n\tstd::vector<tjs_uint8>* result = new std::vector<tjs_uint8>();\n\tresult->reserve( size );\n\n\tAdd4ByteToVector( result, parent );\n\tAdd4ByteToVector( result, name );\n\tAdd4ByteToVector( result, ContextType );\n\tAdd4ByteToVector( result, MaxVariableCount );\n\tAdd4ByteToVector( result, VariableReserveCount );\n\tAdd4ByteToVector( result, MaxFrameCount );\n\tAdd4ByteToVector( result, FuncDeclArgCount );\n\tAdd4ByteToVector( result, FuncDeclUnnamedArgArrayBase );\n\tAdd4ByteToVector( result, FuncDeclCollapseBase );\n\tAdd4ByteToVector( result, propSetter );\n\tAdd4ByteToVector( result, propGetter );\n\tAdd4ByteToVector( result, superClassGetter );\n\n\tAdd4ByteToVector( result, count);\n\tif( outputdebug ) {\n\t\tfor( int i = 0; i < count ; i++ ) {\n\t\t\tAdd4ByteToVector( result, SourcePosArray[i].CodePos );\n\t\t}\n\t\tfor( int i = 0; i < count ; i++ ) {\n\t\t\tAdd4ByteToVector( result, SourcePosArray[i].SourcePos );\n\t\t}\n\t}\n\n\tcount = CodeAreaSize;\n\tAdd4ByteToVector( result, count);\n\n\tblock->TranslateCodeAddress( CodeArea, CodeAreaSize );\n\tfor( int i = 0; i < CodeAreaSize; i++ ) {\n\t\tAdd2ByteToVector( result, CodeArea[i] );\n\t}\n\tif( (count%2) == 1 ) { // alignment\n\t\tAdd2ByteToVector( result, 0 );\n\t}\n\n\tcount = DataAreaSize;\n\tAdd4ByteToVector( result, count);\n\tfor( int i = 0; i < count ; i++ ) {\n\t\ttjs_int16 type = constarray.GetType( DataArea[i], block );\n\t\ttjs_int16 v = (tjs_int16)constarray.PutVariant( DataArea[i], block );\n\t\tAdd2ByteToVector( result, type );\n\t\tAdd2ByteToVector( result, v );\n\t}\n\tcount = (int)SuperClassGetterPointer.size();\n\tAdd4ByteToVector( result, count);\n\tfor( int i = 0; i < count ; i++ ) {\n\t\tint v = SuperClassGetterPointer.at(i);\n\t\tAdd4ByteToVector( result, v);\n\t}\n\tcount = 0;\n\tif( Properties != NULL ) {\n\t\tcount = (int)Properties->size();\n\t\tAdd4ByteToVector( result, count);\n\t\tif( count > 0 ) {\n\t\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\t\ttProperty* prop = (*Properties).at(i);\n\t\t\t\tint propname = constarray.PutString(prop->Name);\n\t\t\t\tint propobj = -1;\n\t\t\t\tif( prop->Value != NULL ) {\n\t\t\t\t\tpropobj = block->GetCodeIndex(prop->Value);\n\t\t\t\t}\n\t\t\t\tAdd4ByteToVector( result, propname );\n\t\t\t\tAdd4ByteToVector( result, propobj );\n\t\t\t\tdelete prop;\n\t\t\t}\n\t\t}\n\t\tdelete Properties;\n\t} else {\n\t\tAdd4ByteToVector( result, count);\n\t}\n\treturn result;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsInterCodeGen.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Intermediate Code Context\n//---------------------------------------------------------------------------\n#ifndef tjsInterCodeGenH\n#define tjsInterCodeGenH\n\n\n#include <vector>\n#include <stack>\n#include <list>\n#include \"tjsVariant.h\"\n#include \"tjsInterface.h\"\n#include \"tjsNamespace.h\"\n#include \"tjsError.h\"\n#include \"tjsObject.h\"\n\n#ifdef ENABLE_DEBUGGER\n#include \"tjsDebug.h\"\n#endif // ENABLE_DEBUGGER\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n//\n#define TJS_TO_VM_CODE_ADDR(x)  ((x) * (tjs_int)sizeof(tjs_uint32))\n#define TJS_TO_VM_REG_ADDR(x) ((x) * (tjs_int)sizeof(tTJSVariant))\n#define TJS_FROM_VM_CODE_ADDR(x)  ((tjs_int)(x) / (tjs_int)sizeof(tjs_uint32))\n#define TJS_FROM_VM_REG_ADDR(x) ((tjs_int)(x) / (tjs_int)sizeof(tTJSVariant))\n#define TJS_ADD_VM_CODE_ADDR(dest, x)  ((*(char **)&(dest)) += (x))\n#define TJS_GET_VM_REG_ADDR(base, x) ((tTJSVariant*)((char *)(base) + (tjs_int)(x)))\n#define TJS_GET_VM_REG(base, x) (*(TJS_GET_VM_REG_ADDR(base, x)))\n\n//---------------------------------------------------------------------------\nextern int _yyerror(const tjs_char * msg, void *pm, tjs_int pos = -1);\n//---------------------------------------------------------------------------\n#define TJS_NORMAL_AND_PROPERTY_ACCESSER(x) x, x##PD, x##PI, x##P\n\nenum tTJSVMCodes{\n\n\tVM_NOP, VM_CONST, VM_CP, VM_CL, VM_CCL, VM_TT, VM_TF, VM_CEQ, VM_CDEQ, VM_CLT,\n\tVM_CGT, VM_SETF, VM_SETNF, VM_LNOT, VM_NF, VM_JF, VM_JNF, VM_JMP,\n\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_INC),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_DEC),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_LOR),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_LAND),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_BOR),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_BXOR),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_BAND),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_SAR),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_SAL),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_SR),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_ADD),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_SUB),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_MOD),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_DIV),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_IDIV),\n\tTJS_NORMAL_AND_PROPERTY_ACCESSER(VM_MUL),\n\n\tVM_BNOT, VM_TYPEOF, VM_TYPEOFD, VM_TYPEOFI, VM_EVAL, VM_EEXP, VM_CHKINS,\n\tVM_ASC, VM_CHR, VM_NUM, VM_CHS, VM_INV, VM_CHKINV,\n\tVM_INT, VM_REAL, VM_STR, VM_OCTET,\n\tVM_CALL, VM_CALLD, VM_CALLI, VM_NEW,\n\tVM_GPD, VM_SPD, VM_SPDE, VM_SPDEH, VM_GPI, VM_SPI, VM_SPIE,\n\tVM_GPDS, VM_SPDS, VM_GPIS, VM_SPIS,  VM_SETP, VM_GETP,\n\tVM_DELD, VM_DELI, VM_SRV, VM_RET, VM_ENTRY, VM_EXTRY, VM_THROW,\n\tVM_CHGTHIS, VM_GLOBAL, VM_ADDCI, VM_REGMEMBER, VM_DEBUGGER,\n\n\t__VM_LAST /* = last mark ; this is not a real operation code */} ;\n\n#undef TJS_NORMAL_AND_PROPERTY_ACCESSER\n//---------------------------------------------------------------------------\nenum tTJSSubType{ stNone=VM_NOP, stEqual=VM_CP, stBitAND=VM_BAND, stBitOR=VM_BOR,\n\tstBitXOR=VM_BXOR, stSub=VM_SUB, stAdd=VM_ADD, stMod=VM_MOD, stDiv=VM_DIV,\n\tstIDiv = VM_IDIV,\n\tstMul=VM_MUL, stLogOR=VM_LOR, stLogAND=VM_LAND, stSAR=VM_SAR, stSAL=VM_SAL,\n\tstSR=VM_SR,\n\n\tstPreInc = __VM_LAST, stPreDec, stPostInc, stPostDec, stDelete, stFuncCall,\n\t\tstIgnorePropGet, stIgnorePropSet, stTypeOf} ;\n//---------------------------------------------------------------------------\nenum tTJSFuncArgType { fatNormal, fatExpand, fatUnnamedExpand };\n//---------------------------------------------------------------------------\nenum tTJSContextType\n{\n\tctTopLevel,\n\tctFunction,\n\tctExprFunction,\n\tctProperty,\n\tctPropertySetter,\n\tctPropertyGetter,\n\tctClass,\n\tctSuperClassGetter,\n};\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n// tTJSExprNode\n//---------------------------------------------------------------------------\nclass tTJSExprNode\n{\n\ttjs_int Op;\n\ttjs_int Position;\n\tstd::vector<tTJSExprNode*> *Nodes;\n\ttTJSVariant *Val;\n\npublic:\n\ttTJSExprNode();\n\t~tTJSExprNode() { Clear(); }\n\n\tvoid Clear();\n\n\tvoid SetOpecode(tjs_int op) { Op = op; }\n\tvoid SetPosition(tjs_int pos) { Position = pos; }\n\tvoid SetValue(const tTJSVariant &val)\n\t{\n\t\tif(!Val)\n\t\t\tVal = new tTJSVariant(val);\n\t\telse\n\t\t\tVal->CopyRef(val);\n\t}\n\tvoid Add(tTJSExprNode *n);\n\n\ttjs_int GetOpecode() const { return Op; }\n\ttjs_int GetPosition() const { return Position; }\n\ttTJSVariant & GetValue() { if(!Val) return *(tTJSVariant*)NULL; else return *Val; }\n\ttTJSExprNode * operator [] (tjs_int i) const { if(!Nodes) return NULL; else return (*Nodes)[i]; }\n\tunsigned int GetSize() const { if(Nodes) return (unsigned int)Nodes->size(); else return 0;}\n\n\t// for array and dictionary constant value\n\tvoid AddArrayElement(const tTJSVariant & val);\n\tvoid AddDictionaryElement(const tTJSString & name, const tTJSVariant & val);\n};\n//---------------------------------------------------------------------------\n// tTJSInterCodeContext - Intermediate Code Context\n//---------------------------------------------------------------------------\n/*\n\tthis class implements iTJSDispatch2;\n\tthe object can be directly treated as function, class, property handlers.\n*/\n\nclass tTJSScriptBlock;\nclass tTJSInterCodeContext : public tTJSCustomObject\n{\n\ttypedef tTJSCustomObject inherited;\n\npublic:\n\ttTJSInterCodeContext(tTJSInterCodeContext *parant,\n\t\tconst tjs_char *name, tTJSScriptBlock *block, tTJSContextType type);\n\tvirtual ~tTJSInterCodeContext();\n\n\t// is bytecode export\n\tstatic bool IsBytecodeCompile;\nprotected:\n\tvoid Finalize(void);\n\t//------------------------------------------------------- compiling stuff\n\npublic:\n\tvoid ClearNodesToDelete(void);\n\npublic:\n\tstruct tSubParam\n\t{\n\t\ttTJSSubType SubType;\n\t\ttjs_int SubFlag;\n\t\ttjs_int SubAddress; \n\n\t\ttSubParam()\n\t\t\t{ SubType = stNone, SubFlag = 0, SubAddress = 0; }\n\t};\n\tstruct tSourcePos\n\t{\n\t\ttjs_int CodePos;\n\t\ttjs_int SourcePos;\n\t\tstatic int TJS_USERENTRY\n\t\t\tSortFunction(const void *a, const void *b);\n\t};\n\nprivate:\n\n\tenum tNestType { ntBlock, ntWhile, ntDoWhile, ntFor,\n\t\tntSwitch, ntIf, ntElse, ntTry, ntCatch, ntWith };\n\n\tstruct tNestData\n\t{\n\t\ttNestType Type;\n\t\ttjs_int VariableCount;\n\t\tunion\n\t\t{\n\t\t\tbool VariableCreated;\n\t\t\tbool IsFirstCase;\n\t\t};\n\t\ttjs_int RefRegister;\n\t\ttjs_int StartIP;\n\t\ttjs_int LoopStartIP;\n\t\tstd::vector<tjs_int> ContinuePatchVector;\n\t\tstd::vector<tjs_int> ExitPatchVector;\n\t\ttjs_int Patch1;\n\t\ttjs_int Patch2;\n\t\ttTJSExprNode *PostLoopExpr;\n\t};\n\n\tstruct tFixData\n\t{\n\t\ttjs_int StartIP;\n\t\ttjs_int Size;\n\t\ttjs_int NewSize;\n\t\tbool BeforeInsertion;\n\t\ttjs_int32 *Code;\n\n\t\ttFixData(tjs_int startip, tjs_int size, tjs_int newsize,\n\t\t\ttjs_int32 *code, bool beforeinsertion)\n\t\t\t{ StartIP =startip, Size = size, NewSize = newsize,\n\t\t\t\tCode = code, BeforeInsertion = beforeinsertion; }\n\t\ttFixData(const tFixData &fixdata)\n\t\t\t{\n\t\t\t\tCode = NULL;\n\t\t\t\toperator =(fixdata);\n\t\t\t}\n\t\ttFixData & operator = (const tFixData &fixdata)\n\t\t\t{\n\t\t\t\tif(Code) delete [] Code;\n\t\t\t\tStartIP = fixdata.StartIP;\n\t\t\t\tSize = fixdata.Size;\n\t\t\t\tNewSize = fixdata.NewSize;\n\t\t\t\tBeforeInsertion = fixdata.BeforeInsertion;\n\t\t\t\tCode = new tjs_int32[NewSize];\n\t\t\t\tmemcpy(Code, fixdata.Code, sizeof(tjs_int32)*NewSize);\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t~tFixData() { if(Code) delete [] Code; }\n\t};\n\n\tstruct tNonLocalFunctionDecl\n\t{\n\t\ttjs_int DataPos;\n\t\ttjs_int NameDataPos;\n\t\tbool ChangeThis;\n\t\ttNonLocalFunctionDecl(tjs_int datapos, tjs_int namedatapos, bool changethis)\n\t\t\t{ DataPos = datapos, NameDataPos = namedatapos; ChangeThis = changethis; }\n\t};\n\n\tstruct tFuncArgItem\n\t{\n\t\ttjs_int Register;\n\t\ttTJSFuncArgType Type;\n\t\ttFuncArgItem(tjs_int reg, tTJSFuncArgType type = fatNormal)\n\t\t{\n\t\t\tRegister = reg;\n\t\t\tType = type;\n\t\t}\n\t};\n\n\tstruct tFuncArg\n\t{\n\t\tbool IsOmit;\n\t\tbool HasExpand;\n\t\tstd::vector <tFuncArgItem> ArgVector;\n\t\ttFuncArg() { IsOmit = HasExpand = false; }\n\t};\n\n\tstruct tArrayArg\n\t{\n\t\ttjs_int Object;\n\t\ttjs_int Counter;\n\t};\n\t\n\t// for Bytecode\n\tstruct tProperty {\n\t\tconst tjs_char* Name;\n\t\tconst tTJSInterCodeContext* Value;\n\t\ttProperty( const tjs_char* name, const tTJSInterCodeContext* val ) {\n\t\t\tName = name;\n\t\t\tValue = val;\n\t\t}\n\t};\n\tstd::vector<tProperty*>* Properties;\n\n\ttjs_int FrameBase;\n\n\ttjs_int32 * CodeArea;\n\ttjs_int CodeAreaCapa;\n\ttjs_int CodeAreaSize;\n\n\ttTJSVariant ** _DataArea;\n\ttjs_int _DataAreaSize;\n\ttjs_int _DataAreaCapa;\n\ttTJSVariant * DataArea;\n\ttjs_int DataAreaSize;\n\n\ttTJSLocalNamespace Namespace;\n\n\tstd::vector<tTJSExprNode *> NodeToDeleteVector;\n\n\tstd::vector<tTJSExprNode *> CurrentNodeVector;\n\n\tstd::stack<tFuncArg> FuncArgStack;\n\n\tstd::stack<tArrayArg> ArrayArgStack;\n\n\ttjs_int PrevIfExitPatch;\n\tstd::vector<tNestData> NestVector;\n\n\n\tstd::list<tjs_int> JumpList;\n\tstd::list<tFixData> FixList;\n\n\tstd::vector<tNonLocalFunctionDecl> NonLocalFunctionDeclVector;\n\n\ttjs_int FunctionRegisterCodePoint;\n\n\ttjs_int PrevSourcePos;\n\tbool SourcePosArraySorted;\n//\tstd::vector<tSourcePos> SourcePosVector;\n\ttSourcePos *SourcePosArray;\n\ttjs_int SourcePosArraySize;\n\ttjs_int SourcePosArrayCapa;\n\n\ttTJSExprNode *SuperClassExpr;\n\n\ttjs_int VariableReserveCount;\n\n\tbool AsGlobalContextMode;\n\n\ttjs_int MaxFrameCount;\n\ttjs_int MaxVariableCount;\n\n\ttjs_int FuncDeclArgCount;\n\ttjs_int FuncDeclUnnamedArgArrayBase;\n\ttjs_int FuncDeclCollapseBase;\n\n\tstd::vector<tjs_int> SuperClassGetterPointer;\n\n\ttjs_char *Name;\n\ttTJSInterCodeContext *Parent;\n\ttTJSScriptBlock *Block;\n\ttTJSContextType ContextType;\n\ttTJSInterCodeContext *PropSetter;\n\ttTJSInterCodeContext *PropGetter;\n\ttTJSInterCodeContext *SuperClassGetter;\n\n#ifdef ENABLE_DEBUGGER\n\tScopeKey\t\tDebuggerScopeKey;\t\t//!< for exec\n\ttTJSVariant*\tDebuggerRegisterArea;\t//!< for exec\n#endif\t// ENABLE_DEBUGGER\n\npublic:\n\ttTJSContextType GetContextType() const { return ContextType; }\n\tconst tjs_char *GetContextTypeName() const;\n\n\tttstr GetShortDescription() const;\n\tttstr GetShortDescriptionWithClassName() const;\n\n\ttTJSScriptBlock * GetBlock() const { return Block; }\n\n#ifdef ENABLE_DEBUGGER\n\tttstr GetClassName() const;\n\tttstr GetSelfClassName() const;\n\n\tconst ScopeKey& GetDebuggerScopeKey() { return DebuggerScopeKey; }\n\ttTJSVariant* GetDebuggerRegisterArea() { return DebuggerRegisterArea; }\n\ttTJSVariant* GetDebuggerDataArea() { return DataArea; }\n#endif\t// ENABLE_DEBUGGER\nprivate:\n\tvoid OutputWarning(const tjs_char *msg, tjs_int pos = -1);\n\nprivate:\n\ttjs_int PutCode(tjs_int32 num, tjs_int32 pos=-1);\n\ttjs_int PutData(const tTJSVariant &val);\n\n\tvoid AddJumpList(void) { JumpList.push_back(CodeAreaSize); }\n\n\tvoid SortSourcePos();\n\n\tvoid FixCode(void);\n\tvoid RegisterFunction();\n\n\ttjs_int _GenNodeCode(tjs_int & frame, tTJSExprNode *node, tjs_uint32 restype,\n\t\ttjs_int reqresaddr, const tSubParam & param);\n\ttjs_int GenNodeCode(tjs_int & frame, tTJSExprNode *node, tjs_uint32 restype,\n\t\ttjs_int reqresaddr, const tSubParam & param);\n\n\t// restypes\n\t#define TJS_RT_NEEDED 0x0001   // result needed\n\t#define TJS_RT_CFLAG  0x0002   // condition flag needed\n\t// result value\n\t#define TJS_GNC_CFLAG (1<<(sizeof(tjs_int)*8-1)) // true logic\n\t#define TJS_GNC_CFLAG_I (TJS_GNC_CFLAG+1) // inverted logic\n\n\n\tvoid StartFuncArg();\n\tvoid AddFuncArg(tjs_int addr, tTJSFuncArgType type = fatNormal);\n\tvoid EndFuncArg();\n\tvoid AddOmitArg();\n\n\tvoid DoNestTopExitPatch(void);\n\tvoid DoContinuePatch(tNestData & nestdata);\n\n\tvoid ClearLocalVariable(tjs_int top, tjs_int bottom);\n\n\tvoid ClearFrame(tjs_int &frame, tjs_int base = -1);\n\n\tstatic void _output_func(const tjs_char *msg, const tjs_char *comment,\n\t\ttjs_int addr, const tjs_int32 *codestart, tjs_int size, void *data);\n\tstatic void _output_func_src(const tjs_char *msg, const tjs_char *name,\n\t\ttjs_int line, void *data);\n\npublic:\n\tvoid Commit();\n\n\ttjs_uint GetCodeSize() const { return CodeAreaSize; }\n\ttjs_uint GetDataSize() const { return DataAreaSize; }\n\n\ttjs_int CodePosToSrcPos(tjs_int codepos) const;\n\ttjs_int FindSrcLineStartCodePos(tjs_int codepos) const;\n\n\tttstr GetPositionDescriptionString(tjs_int codepos) const;\n\n\tvoid AddLocalVariable(const tjs_char *name, tjs_int init=0);\n\tvoid InitLocalVariable(const tjs_char *name, tTJSExprNode *node);\n\tvoid InitLocalFunction(const tjs_char *name, tjs_int data);\n\n\tvoid CreateExprCode(tTJSExprNode *node);\n\n\tvoid EnterWhileCode(bool do_while);\n\tvoid CreateWhileExprCode(tTJSExprNode *node, bool do_while);\n\tvoid ExitWhileCode(bool do_while);\n\n\tvoid EnterIfCode();\n\tvoid CreateIfExprCode(tTJSExprNode *node);\n\tvoid ExitIfCode();\n\tvoid EnterElseCode();\n\tvoid ExitElseCode();\n\n\tvoid EnterForCode();\n\tvoid CreateForExprCode(tTJSExprNode *node);\n\tvoid SetForThirdExprCode(tTJSExprNode *node);\n\tvoid ExitForCode();\n\n\tvoid EnterSwitchCode(tTJSExprNode *node);\n\tvoid ExitSwitchCode();\n\tvoid ProcessCaseCode(tTJSExprNode *node);\n\n\tvoid EnterWithCode(tTJSExprNode *node);\n\tvoid ExitWithCode();\n\n\tvoid DoBreak();\n\tvoid DoContinue();\n\n\tvoid DoDebugger();\n\n\tvoid ReturnFromFunc(tTJSExprNode *node);\n\n\tvoid EnterTryCode();\n\tvoid EnterCatchCode(const tjs_char *name);\n\tvoid ExitTryCode();\n\n\tvoid ProcessThrowCode(tTJSExprNode *node);\n\n\tvoid CreateExtendsExprCode(tTJSExprNode *node, bool hold);\n\tvoid CreateExtendsExprProxyCode(tTJSExprNode *node);\n\n\tvoid EnterBlock();\n\tvoid ExitBlock();\n\n\tvoid GenerateFuncCallArgCode();\n\n\tvoid AddFunctionDeclArg(const tjs_char *varname, tTJSExprNode *init);\n\tvoid AddFunctionDeclArgCollapse(const tjs_char *varname);\n\n\tvoid SetPropertyDeclArg(const tjs_char *varname);\n\n\tconst tjs_char * GetName() const ;\n\n\tvoid PushCurrentNode(tTJSExprNode *node);\n\ttTJSExprNode * GetCurrentNode();\n\tvoid PopCurrentNode();\n\n\ttTJSExprNode * MakeConstValNode(const tTJSVariant &val);\n\n\ttTJSExprNode * MakeNP0(tjs_int opecode);\n\ttTJSExprNode * MakeNP1(tjs_int opecode, tTJSExprNode * node1);\n\ttTJSExprNode * MakeNP2(tjs_int opecode, tTJSExprNode * node1, tTJSExprNode * node2);\n\ttTJSExprNode * MakeNP3(tjs_int opecode, tTJSExprNode * node1, tTJSExprNode * node2,\n\t\ttTJSExprNode * node3);\n\n\t//---------------------------------------------------------- disassembler\n\t// implemented in tjsDisassemble.cpp\n\n\tstatic tTJSString GetValueComment(const tTJSVariant &val);\n\n\tvoid Disassemble(\n\t\tvoid (*output_func)(const tjs_char *msg, const tjs_char *comment,\n\t\ttjs_int addr, const tjs_int32 *codestart, tjs_int size, void *data),\n\t\tvoid (*output_func_src)(const tjs_char *msg, const tjs_char *name,\n\t\t\ttjs_int line, void *data), void *data, tjs_int start = 0, tjs_int end = 0);\n\tvoid Disassemble(void (*output_func)(const tjs_char *msg, void* data), void *data,\n\t\ttjs_int start = 0, tjs_int end = 0);\n\tvoid Disassemble(tjs_int start = 0, tjs_int end = 0);\n\tvoid DisassembleSrcLine(tjs_int codepos);\n\n\n\t//--------------------------------------------------------- execute stuff\n\t// implemented in InterCodeExec.cpp\nprivate:\n\tvoid DisplayExceptionGeneratedCode(tjs_int codepos, const tTJSVariant *ra);\n\n\tvoid ThrowScriptException(tTJSVariant &val, tTJSScriptBlock *block, tjs_int srcpos);\n\n//\tvoid ExecuteAsGlobal(tTJSVariant *result);\n\tvoid ExecuteAsFunction(iTJSDispatch2 *objthis, tTJSVariant **args,\n\t\ttjs_int numargs,tTJSVariant *result, tjs_int start_ip);\n\ttjs_int ExecuteCode(tTJSVariant *ra, tjs_int startip, tTJSVariant **args,\n\t\ttjs_int numargs, tTJSVariant *result);\n\ttjs_int ExecuteCodeInTryBlock(tTJSVariant *ra, tjs_int startip,\n\t\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result,\n\t\ttjs_int catchip, tjs_int exobjreg);\n\n\tstatic void ContinuousClear(tTJSVariant *ra, const tjs_int32 *code);\n\tvoid GetPropertyDirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\tvoid SetPropertyDirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\tstatic void GetProperty(tTJSVariant *ra, const tjs_int32 *code);\n\tstatic void SetProperty(tTJSVariant *ra, const tjs_int32 *code);\n\tstatic void GetPropertyIndirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\tstatic void SetPropertyIndirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\tvoid OperatePropertyDirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 ope);\n\tstatic void OperatePropertyIndirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 ope);\n\tstatic void OperateProperty(tTJSVariant *ra, const tjs_int32 *code, tjs_uint32 ope);\n\tvoid OperatePropertyDirect0(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 ope);\n\tstatic void OperatePropertyIndirect0(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 ope);\n\tstatic void OperateProperty0(tTJSVariant *ra, const tjs_int32 *code, tjs_uint32 ope);\n\tvoid DeleteMemberDirect(tTJSVariant *ra, const tjs_int32 *code);\n\tstatic void DeleteMemberIndirect(tTJSVariant *ra, const tjs_int32 *code);\n\tvoid TypeOfMemberDirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\tstatic void TypeOfMemberIndirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttjs_uint32 flags);\n\ttjs_int CallFunction(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttTJSVariant **args,\n\t\ttjs_int numargs);\n\ttjs_int CallFunctionDirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttTJSVariant **args, tjs_int numargs);\n\ttjs_int CallFunctionIndirect(tTJSVariant *ra, const tjs_int32 *code,\n\t\ttTJSVariant **args, tjs_int numargs);\n\tstatic void AddClassInstanceInfo(tTJSVariant *ra, const tjs_int32 *code);\n\tvoid ProcessStringFunction(const tjs_char *member, const ttstr & target,\n\t\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result);\n\tvoid ProcessOctetFunction(const tjs_char *member, const tTJSVariantOctet * target,\n\t\ttTJSVariant **args, tjs_int numargs, tTJSVariant *result);\n\tstatic void TypeOf(tTJSVariant &val);\n\tvoid Eval(tTJSVariant &val, iTJSDispatch2 * objthis, bool resneed);\n\tstatic void CharacterCodeOf(tTJSVariant &val);\n\tstatic void CharacterCodeFrom(tTJSVariant &val);\n\tstatic void InstanceOf(const tTJSVariant &name, tTJSVariant &targ);\n\n\tvoid RegisterObjectMember(iTJSDispatch2 * dest);\n\n\t// for Byte code\n\tstatic inline void Add4ByteToVector( std::vector<tjs_uint8>* array, int value ) {\n\t\tarray->push_back( (tjs_uint8)((value>>0)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>8)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>16)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>24)&0xff) );\n\t}\n\tstatic inline void Add2ByteToVector( std::vector<tjs_uint8>* array, tjs_int16 value ) {\n\t\tarray->push_back( (tjs_uint8)((value>>0)&0xff) );\n\t\tarray->push_back( (tjs_uint8)((value>>8)&0xff) );\n\t}\npublic:\n\t// iTJSDispatch2 implementation\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis);\n\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\t\tGetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint,\n\t\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *mambername,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\t\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\t\tInvalidate(tjs_uint32 flag, const tjs_char *membername,  tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\t\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\t\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\t tTJSVariant *result,\n\t\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis);\n\n\t// for Byte code\n\tvoid SetCodeObject( tTJSInterCodeContext* parent, tTJSInterCodeContext* setter, tTJSInterCodeContext* getter, tTJSInterCodeContext* superclass ) {\n\t\tParent = parent;\n\t\tPropSetter = setter;\n\t\tif( setter ) setter->AddRef();\n\t\tPropGetter = getter;\n\t\tif( getter ) getter->AddRef();\n\t\tSuperClassGetter = superclass;\n#ifdef ENABLE_DEBUGGER\n\t\tif (Parent) Parent->AddRef();\n#endif\t// ENABLE_DEBUGGER\n\t}\n\t\n\ttTJSInterCodeContext( tTJSScriptBlock *block, const tjs_char *name, tTJSContextType type,\n\t\ttjs_int32* code, tjs_int codeSize, tTJSVariant* data, tjs_int dataSize,\n\t\ttjs_int varcount, tjs_int verrescount, tjs_int maxframe, tjs_int argcount, tjs_int arraybase, tjs_int colbase, bool srcsorted,\n\t\ttSourcePos* srcPos, tjs_int srcPosSize, std::vector<tjs_int>& superpointer );\n\n\tstd::vector<tjs_uint8>* ExportByteCode( bool outputdebug, tTJSScriptBlock *block, class tjsConstArrayData& constarray );\n\nprotected:\n\tvoid TJSVariantArrayStackAddRef();\n\tvoid TJSVariantArrayStackRelease();\n\n\tclass tTJSVariantArrayStack *TJSVariantArrayStack = nullptr;\n};\n//---------------------------------------------------------------------------\n}\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsInterface.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// iTJSDispatch2 interface definition\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsInterface.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsInterface.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// iTJSDispatch2 interface definition\n//---------------------------------------------------------------------------\n#ifndef tjsInterfaceH\n#define tjsInterfaceH\n\n#include \"tjsConfig.h\"\n#include \"tjsErrorDefs.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n\n/*[*/\n//---------------------------------------------------------------------------\n// call flag type\n//---------------------------------------------------------------------------\n#define TJS_MEMBERENSURE\t\t0x00000200 // create a member if not exists\n#define TJS_MEMBERMUSTEXIST     0x00000400 // member *must* exist ( for Dictionary/Array )\n#define TJS_IGNOREPROP\t\t\t0x00000800 // ignore property invoking\n#define TJS_HIDDENMEMBER\t\t0x00001000 // member is hidden\n#define TJS_STATICMEMBER\t\t0x00010000 // member is not registered to the\n\t\t\t\t\t\t\t\t\t\t   // object (internal use)\n\n#define TJS_ENUM_NO_VALUE\t\t0x00100000 // values are not retrieved\n\t\t\t\t\t\t\t\t\t\t   // (for EnumMembers)\n\n#define TJS_NIS_REGISTER\t\t0x00000001 // set native pointer\n#define TJS_NIS_GETINSTANCE\t\t0x00000002 // get native pointer\n\n#define TJS_CII_ADD\t\t\t\t0x00000001 // register name\n\t\t\t\t\t\t\t\t\t\t   // 'num' argument passed to CII is to be igonored.\n#define TJS_CII_GET\t\t\t\t0x00000000 // retrieve name\n\n#define TJS_CII_SET_FINALIZE\t0x00000002 // register \"finalize\" method name\n\t\t\t\t\t\t\t\t\t\t   // (set empty string not to call the method)\n\t\t\t\t\t\t\t\t\t\t   // 'num' argument passed to CII is to be igonored.\n#define TJS_CII_SET_MISSING\t\t0x00000003 // register \"missing\" method name.\n\t\t\t\t\t\t\t\t\t\t   // the method is called when the member is not present.\n\t\t\t\t\t\t\t\t\t\t   // (set empty string not to call the method)\n\t\t\t\t\t\t\t\t\t\t   // 'num' argument passed to CII is to be igonored.\n\t\t\t\t\t\t\t\t\t\t   // the method is to be called with three arguments;\n\t\t\t\t\t\t\t\t\t\t   // get_or_set    : false for get, true for set\n\t\t\t\t\t\t\t\t\t\t   // name          : member name\n\t\t\t\t\t\t\t\t\t\t   // value         : value property; you must\n\t\t\t\t\t\t\t\t\t\t   //               : dereference using unary '*' operator.\n\t\t\t\t\t\t\t\t\t\t   // the method must return true for found, false for not-found.\n#define TJS_CII_SET_SUPRECLASS\t0x00000004 // register super class instance\n#define TJS_CII_GET_SUPRECLASS\t0x00000005 // retrieve super class instance\n\n#define TJS_OL_LOCK\t\t\t\t0x00000001 // Lock the object\n#define TJS_OL_UNLOCK\t\t\t0x00000002 // Unlock the object\n\n\n\n//---------------------------------------------------------------------------\n// \tOperation  flag\n//---------------------------------------------------------------------------\n\n#define TJS_OP_BAND\t\t\t\t0x0001\n#define TJS_OP_BOR\t\t\t\t0x0002\n#define TJS_OP_BXOR\t\t\t\t0x0003\n#define TJS_OP_SUB\t\t\t\t0x0004\n#define TJS_OP_ADD\t\t\t\t0x0005\n#define TJS_OP_MOD\t\t\t\t0x0006\n#define TJS_OP_DIV\t\t\t\t0x0007\n#define TJS_OP_IDIV\t\t\t\t0x0008\n#define TJS_OP_MUL\t\t\t\t0x0009\n#define TJS_OP_LOR\t\t\t\t0x000a\n#define TJS_OP_LAND\t\t\t\t0x000b\n#define TJS_OP_SAR\t\t\t\t0x000c\n#define TJS_OP_SAL\t\t\t\t0x000d\n#define TJS_OP_SR\t\t\t\t0x000e\n#define TJS_OP_INC\t\t\t\t0x000f\n#define TJS_OP_DEC\t\t\t\t0x0010\n\n#define TJS_OP_MASK\t\t\t\t0x001f\n\n#define TJS_OP_MIN\t\t\t\tTJS_OP_BAND\n#define TJS_OP_MAX\t\t\t\tTJS_OP_DEC\n\n/* SAR = Shift Arithmetic Right, SR = Shift (bitwise) Right */\n\n\n\n//---------------------------------------------------------------------------\n// iTJSDispatch\n//---------------------------------------------------------------------------\n/*\n\tiTJSDispatch interface\n*/\nclass tTJSVariant;\nclass tTJSVariantClosure;\nclass tTJSVariantString;\nclass iTJSNativeInstance;\nclass iTJSDispatch2\n{\n/*\n\tmethods, that have \"ByNum\" at the end of the name, have\n\t\"num\" parameter that enables the function to call a member with number directly.\n\tfollowing two have the same effect:\n\tFuncCall(NULL, L\"123\", NULL, 0, NULL, NULL);\n\tFuncCallByNum(NULL, 123, NULL, 0, NULL, NULL);\n*/\n\npublic:\n\tvirtual tjs_uint TJS_INTF_METHOD AddRef(void) = 0;\n\tvirtual tjs_uint TJS_INTF_METHOD Release(void) = 0;\n\npublic:\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tFuncCall( // function invocation\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result\n\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\ttTJSVariant **param,\t\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tFuncCallByNum( // function invocation by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\ttTJSVariant *result,\t\t// result\n\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\ttTJSVariant **param,\t\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tPropGet( // property get\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tPropGetByNum( // property get by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\ttTJSVariant *result,\t\t// result\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tPropSet( // property set\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tPropSetByNum( // property set by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tGetCount( // get member count\n\t\ttjs_int *result,         \t// variable that receives the result\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis      // object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tGetCountByNum( // get member count by index number\n\t\ttjs_int *result,\t\t\t// variable that receives the result\n\t\ttjs_int num,\t\t\t\t// by index number\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tPropSetByVS( // property set by tTJSVariantString, for internal use\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttTJSVariantString *membername, // member name ( NULL for a default member )\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tEnumMembers( // enumerate members\n\t\ttjs_uint32 flag,\t\t\t// enumeration flag\n\t\ttTJSVariantClosure *callback,\t// callback function interface ( called on each member )\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tDeleteMember( // delete member\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tDeleteMemberByNum( // delete member by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tInvalidate( // invalidation\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tInvalidateByNum( // invalidation by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tIsValid( // get validation, returns TJS_S_TRUE (valid) or TJS_S_FALSE (invalid)\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tIsValidByNum( // get validation by index number, returns TJS_S_TRUE (valid) or TJS_S_FALSE (invalid)\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tCreateNew( // create new object\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 **result,\t\t// result\n\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\ttTJSVariant **param,\t\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tCreateNewByNum( // create new object by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tiTJSDispatch2 **result,\t\t// result\n\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\ttTJSVariant **param,\t\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tReserved1(\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tIsInstanceOf( // class instance matching returns TJS_S_FALSE or TJS_S_TRUE\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tconst tjs_char *classname,\t// class name to inquire\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tIsInstanceOfByNum( // class instance matching by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t\t// index number\n\t\tconst tjs_char *classname,\t// class name to inquire\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tOperation( // operation with member\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result ( can be NULL )\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tOperationByNum( // operation with member by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\ttTJSVariant *result,\t\t// result ( can be NULL )\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tNativeInstanceSupport( // support for native instance\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int32 classid,\t\t\t// native class ID\n\t\tiTJSNativeInstance **pointer// object pointer\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tClassInstanceInfo( // support for class instance information\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_uint num,\t\t\t\t// index number\n\t\ttTJSVariant *value\t\t\t// the name\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tReserved2(\n\t\t) = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\tReserved3(\n\t\t) = 0;\n\n\n};\n//---------------------------------------------------------------------------\nclass iTJSNativeInstance\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD Construct(tjs_int numparams,\n\t\ttTJSVariant **param, iTJSDispatch2 *tjs_obj) = 0;\n\t\t// TJS constructor\n\tvirtual void TJS_INTF_METHOD Invalidate() = 0;\n\t\t// called before destruction\n\tvirtual void TJS_INTF_METHOD Destruct() = 0;\n\t\t// must destruct itself\n};\n/*]*/\n//---------------------------------------------------------------------------\n\n\n\n\n} // namespace TJS\n\nusing namespace TJS;\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsLex.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 lexical analyzer\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <math.h>\n#include \"tjsInterCodeGen.h\"\n#include \"tjs.tab.hpp\"\n#include \"tjsLex.h\"\n#include \"tjsVariant.h\"\n#include \"tjsError.h\"\n#include \"tjsCompileControl.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsObject.h\"\n#include \"tjsMath.h\"\n\nnamespace TJS\n{\n\n\ntjs_nchar tjsEnableDicFuncQuickHack_mark[] = \" - 0 <- Put '1' to enable dicfunc quick-hack - \";\nbool tjsEnableDicFuncQuickHack = tjsEnableDicFuncQuickHack_mark[3] != '0';\n\t//----- dicfunc quick-hack\n\n//---------------------------------------------------------------------------\nconst tjs_char TJS_SKIP_CODE = (tjs_char)~((tjs_char)0);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJS_iswspace or etc. ( these functions do not collate )\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswspace(tjs_char ch)\n{\n\tif(ch&0xff00) return false; else return 0!=isspace(ch);\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswdigit(tjs_char ch)\n{\n\tif(ch&0xff00) return false; else return 0!=isdigit(ch);\n}\n//---------------------------------------------------------------------------\nstatic bool inline TJS_iswalpha(tjs_char ch)\n{\n\tif(ch&0xff00) return true; else return 0!=isalpha(ch);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TJSNext\n//---------------------------------------------------------------------------\nstatic void _TJSNext(const tjs_char **ptr)\n{\n\tdo\n\t{\n\t\t(*ptr)++;\n\t} while(*(*ptr) && *(*ptr)==TJS_SKIP_CODE);\n}\n\nbool inline TJSNext(const tjs_char **ptr)\n{\n\t(*ptr)++;\n\tif(*(*ptr) == TJS_SKIP_CODE) _TJSNext(ptr);\n\treturn *(*ptr)!=0;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSSkipSpace\n//---------------------------------------------------------------------------\nbool TJSSkipSpace(const tjs_char **ptr)\n{\n\twhile(*(*ptr) && (*(*ptr)==TJS_SKIP_CODE || TJS_iswspace(*(*ptr))))\n\t\t(*ptr)++;\n\treturn *(*ptr)!=0;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSHexNum\ntjs_int TJSHexNum(tjs_char ch) throw()\n{\n\tif(ch>=TJS_W('a') && ch<=TJS_W('f')) return ch-TJS_W('a')+10;\n\tif(ch>=TJS_W('A') && ch<=TJS_W('F')) return ch-TJS_W('A')+10;\n\tif(ch>=TJS_W('0') && ch<=TJS_W('9')) return ch-TJS_W('0');\n\treturn -1;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSOctNum\n//---------------------------------------------------------------------------\ntjs_int TJSOctNum(tjs_char ch) throw()\n{\n\tif(ch>=TJS_W('0') && ch<=TJS_W('7')) return ch-TJS_W('0');\n\treturn -1;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSDecNum\n//---------------------------------------------------------------------------\ntjs_int TJSDecNum(tjs_char ch) throw()\n{\n\tif(ch>=TJS_W('0') && ch<=TJS_W('9')) return ch-TJS_W('0');\n\treturn -1;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSBinNum\n//---------------------------------------------------------------------------\ntjs_int TJSBinNum(tjs_char ch) throw()\n{\n\tif(ch==TJS_W('0')) return 0;\n\tif(ch==TJS_W('1')) return 1;\n\treturn -1;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSUnescapeBackSlash\n//---------------------------------------------------------------------------\ntjs_int TJSUnescapeBackSlash(tjs_char ch) throw()\n{\n\t// convert \"\\?\"\n\t// ch must indicate \"?\"\n\tswitch(ch)\n\t{\n\tcase TJS_W('a'): return 0x07;\n\tcase TJS_W('b'): return 0x08;\n\tcase TJS_W('f'): return 0x0c;\n\tcase TJS_W('n'): return 0x0a;\n\tcase TJS_W('r'): return 0x0d;\n\tcase TJS_W('t'): return 0x09;\n\tcase TJS_W('v'): return 0x0b;\n\tdefault : return ch;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSSkipComment\n//---------------------------------------------------------------------------\nstatic tTJSSkipCommentResult TJSSkipComment(const tjs_char **ptr)\n{\n\tif((*ptr)[0] != TJS_W('/')) return scrNotComment;\n\n\tif((*ptr)[1] == TJS_W('/'))\n\t{\n\t\t// line comment; skip to newline\n\t\twhile(*(*ptr)!=TJS_W('\\n')) if(!TJSNext(&(*ptr))) break;\n\t\tif(*(*ptr) ==0) return scrEnded;\n\t\t(*ptr)++;\n\t\tTJSSkipSpace(&(*ptr));\n\t\tif(*(*ptr) ==0) return scrEnded;\n\n\t\treturn scrContinue;\n\t}\n\telse if((*ptr)[1] == TJS_W('*'))\n\t{\n\t\t// block comment; skip to the next '*' '/'\n\t\t// and we must allow nesting of the comment.\n\t\t(*ptr) += 2;\n\t\tif(*(*ptr) == 0) TJS_eTJSError(TJSUnclosedComment);\n\t\ttjs_int level = 0;\n\t\tfor(;;)\n\t\t{\n\t\t\tif((*ptr)[0] == TJS_W('/') && (*ptr)[1] == TJS_W('*'))\n\t\t\t{\n\t\t\t\t// note: we cannot avoid comment processing when the\n\t\t\t\t// nested comment is in string literals.\n\t\t\t\tlevel ++;\n\t\t\t}\n\t\t\tif((*ptr)[0] == TJS_W('*') && (*ptr)[1] == TJS_W('/'))\n\t\t\t{\n\t\t\t\tif(level == 0)\n\t\t\t\t{\n\t\t\t\t\t(*ptr) += 2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlevel --;\n\t\t\t}\n\t\t\tif(!TJSNext(&(*ptr))) TJS_eTJSError(TJSUnclosedComment);\n\t\t}\n\t\tif(*(*ptr) ==0) return scrEnded;\n\t\tTJSSkipSpace(&(*ptr));\n\t\tif(*(*ptr) ==0) return scrEnded;\n\n\t\treturn scrContinue;\n\t}\n\n\treturn scrNotComment;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSStringMatch\n//---------------------------------------------------------------------------\nbool TJSStringMatch(const tjs_char **sc, const tjs_char *wrd, bool isword)\n{\n\t// compare string with a script starting from sc and wrd.\n\t// word matching is processed if isword is true.\n\tconst tjs_char *save = (*sc);\n\twhile(*wrd && *(*sc))\n\t{\n\t\tif(*(*sc) != *wrd) break;\n\t\tTJSNext(sc);\n\t\twrd++;\n\t}\n\n\tif(*wrd) { (*sc)=save; return false; }\n\tif(isword)\n\t{\n\t\tif(TJS_iswalpha(*(*sc)) || *(*sc) == TJS_W('_'))\n\t\t\t{ (*sc)=save; return false; }\n\t}\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSParseString\n//---------------------------------------------------------------------------\nenum tTJSInternalParseStringResult\n{ psrNone, psrDelimiter, psrAmpersand, psrDollar };\nstatic tTJSInternalParseStringResult\n\tTJSInternalParseString(tTJSVariant &val, const tjs_char **ptr,\n\t\ttjs_char delim, bool embexpmode)\n{\n\t// delim1 must be '\\'' or '\"'\n\t// delim2 must be '&' or '\\0'\n\n\tttstr str;\n\n\ttTJSInternalParseStringResult status = psrNone;\n\n\tfor(;*(*ptr);)\n\t{\n\t\tif(*(*ptr)==TJS_W('\\\\'))\n\t\t{\n\t\t\t// escape\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t\tif(*(*ptr)==TJS_W('x') || *(*ptr)==TJS_W('X'))\n\t\t\t{\n\t\t\t\t// hex\n\t\t\t\t// starts with a \"\\x\", be parsed while characters are\n\t\t\t\t// recognized as hex-characters, but limited of size of tjs_char.\n\t\t\t\t// on Windows, \\xXXXXX will be parsed to UNICODE 16bit characters.\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\ttjs_int num;\n\t\t\t\ttjs_int code = 0;\n\t\t\t\ttjs_int count = 0;\n\t\t\t\twhile((num = TJSHexNum(*(*ptr)))!=-1 && count<(sizeof(tjs_char)*2))\n\t\t\t\t{\n\t\t\t\t\tcode*=16;\n\t\t\t\t\tcode+=num;\n\t\t\t\t\tcount ++;\n\t\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\t}\n\t\t\t\tif(*(*ptr) == 0) break;\n\t\t\t\tstr+=(tjs_char)code;\n\t\t\t}\n\t\t\telse if(*(*ptr) == TJS_W('0'))\n\t\t\t{\n\t\t\t\t// octal\n\t\t\t\tif(!TJSNext(ptr)) break;\n\n\t\t\t\ttjs_int num;\n\t\t\t\ttjs_int code=0;\n\t\t\t\twhile((num=TJSOctNum(*(*ptr)))!=-1)\n\t\t\t\t{\n\t\t\t\t\tcode*=8;\n\t\t\t\t\tcode+=num;\n\t\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\t}\n\t\t\t\tif(*(*ptr) == 0) break;\n\t\t\t\tstr += (tjs_char)code;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstr += (tjs_char)TJSUnescapeBackSlash(*(*ptr));\n\t\t\t\tTJSNext(ptr);\n\t\t\t}\n\t\t}\n\t\telse if(*(*ptr) == delim)\n\t\t{\n\t\t\t// string delimiters\n\t\t\tif(!TJSNext(ptr))\n\t\t\t{\n\t\t\t\tstatus = psrDelimiter;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst tjs_char *p=(*ptr);\n\t\t\tTJSSkipSpace(&p);\n\t\t\tif(*p == delim)\n\t\t\t{\n\t\t\t\t// sequence of 'A' 'B' will be combined as 'AB'\n\t\t\t\t(*ptr) = p;\n\t\t\t\tTJSNext(ptr);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstatus = psrDelimiter;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if(embexpmode && *(*ptr) == TJS_W('&'))\n\t\t{\n\t\t\t// '&'\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t\tstatus = psrAmpersand;\n\t\t\tbreak;\n\t\t}\n\t\telse if(embexpmode && *(*ptr) == TJS_W('$'))\n\t\t{\n\t\t\t// '$'\n\t\t\t// '{' must be placed immediately after '$'\n\t\t\tconst tjs_char *p = (*ptr);\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t\tif(*(*ptr) == TJS_W('{'))\n\t\t\t{\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\tstatus = psrDollar;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t(*ptr) = p;\n\t\t\t\tstr += *(*ptr);\n\t\t\t\tTJSNext(ptr);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstr+=*(*ptr);\n\t\t\tTJSNext(ptr);\n\t\t}\n\t}\n\n\tif(status == psrNone)\n\t{\n\t\t// error\n\t\tTJS_eTJSError(TJSStringParseError);\n\t}\n\n\tstr.FixLen();\n\tval = str;\n\n\treturn status;\n}\n//---------------------------------------------------------------------------\nbool TJSParseString(tTJSVariant &val, const tjs_char **ptr)\n{\n\t// parse a string starts with '\\'' or '\"'\n\n\ttjs_char delimiter=*(*ptr);\n\n\tTJSNext(ptr);\n\n\treturn TJSInternalParseString(val, ptr, delimiter, false) == psrDelimiter;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJSParseNumber\n//---------------------------------------------------------------------------\nstatic tTJSString TJSExtractNumber(tjs_int (*validdigits)(tjs_char ch),\n\tconst tjs_char *expmark, const tjs_char **ptr, bool &isreal)\n{\n\ttTJSString tmp;\n\n\tbool point_found = false;\n\tbool exp_found = false;\n\twhile(true)\n\t{\n\t\tif(validdigits(**ptr) != -1 && !exp_found)\n\t\t{\n\t\t\ttmp += **ptr;\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t}\n\t\telse if(**ptr == TJS_W('.') && !point_found && !exp_found)\n\t\t{\n\t\t\tpoint_found = true;\n\t\t\ttmp += **ptr;\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t}\n\t\telse if((**ptr == expmark[0] || **ptr == expmark[1]) && !exp_found)\n\t\t{\n\t\t\texp_found = true;\n\t\t\ttmp += **ptr;\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t\tif(!TJSSkipSpace(ptr)) break;\n\t\t\tif(**ptr == TJS_W('+'))\n\t\t\t{\n\t\t\t\ttmp += **ptr;\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\tif(!TJSSkipSpace(ptr)) break;\n\t\t\t}\n\t\t\telse if(**ptr == TJS_W('-'))\n\t\t\t{\n\t\t\t\ttmp += **ptr;\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\tif(!TJSSkipSpace(ptr)) break;\n\t\t\t}\n\t\t}\n\t\telse if (TJSDecNum(**ptr) != -1 && exp_found)\n\t\t{\n\t\t\ttmp += **ptr;\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tisreal = point_found || exp_found;\n\n\treturn tmp;\n}\n\nstatic bool TJSParseNonDecimalReal(tTJSVariant &val, const tjs_char **ptr,\n\ttjs_int (*validdigits)(tjs_char ch), tjs_int basebits)\n{\n\t// parse non-decimal(hexiadecimal, octal or binary) floating-point number.\n\t// this routine heavily depends on IEEE double floating-point number expression.\n\n\ttjs_uint64 main = TJS_UI64_VAL(0); // significand\n\ttjs_int exp = 0; // 2^n exponental\n\ttjs_int numsignif = 0; // significand bit count (including leading left-most '1') in \"main\"\n\tbool pointpassed = false;\n\n\n\t// scan input\n\twhile(true)\n\t{\n\t\tif(**ptr == TJS_W('.'))\n\t\t{\n\t\t\tpointpassed = true;\n\t\t}\n\t\telse if(**ptr == TJS_W('p') || **ptr == TJS_W('P'))\n\t\t{\n\t\t\tif(!TJSNext(ptr)) break;\n\t\t\tif(!TJSSkipSpace(ptr)) break;\n\n\t\t\tbool biassign = false;\n\t\t\tif(**ptr == TJS_W('+'))\n\t\t\t{\n\t\t\t\tbiassign = false;\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\tif(!TJSSkipSpace(ptr)) break;\n\t\t\t}\n\n\t\t\tif(**ptr == TJS_W('-'))\n\t\t\t{\n\t\t\t\tbiassign = true;\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t\tif(!TJSSkipSpace(ptr)) break;\n\t\t\t}\n\n\t\t\ttjs_int bias = 0;\n\t\t\twhile(true)\n\t\t\t{\n\t\t\t\tbias *= 10;\n\t\t\t\tbias += TJSDecNum(**ptr);\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t}\n\t\t\tif(biassign) bias = -bias;\n\t\t\texp += bias;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttjs_int n = validdigits(**ptr);\n\t\t\tif(numsignif == 0)\n\t\t\t{\n\t\t\t\t// find msb flaged bit\n\t\t\t\ttjs_int b = basebits - 1;\n\t\t\t\twhile(b >= 0)\n\t\t\t\t{\n\t\t\t\t\tif((1<<b) & n) break;\n\t\t\t\t\tb--;\n\t\t\t\t}\n\n\t\t\t\tb++;\n\t\t\t\tif(b)\n\t\t\t\t{\n\t\t\t\t\t// n is not zero\n\t\t\t\t\t// place it to the main's msb\n\t\t\t\t\tnumsignif = b;\n\t\t\t\t\tmain |= ((tjs_uint64)n << (64 - numsignif));\n\t\t\t\t\tif(pointpassed)\n\t\t\t\t\t\texp -= (basebits - b + 1);\n\t\t\t\t\telse\n\t\t\t\t\t\texp = b - 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// n is zero\n\t\t\t\t\tif(pointpassed) exp -= basebits;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// append to main\n\t\t\t\tif(numsignif + basebits < 64)\n\t\t\t\t{\n\t\t\t\t\tnumsignif += basebits;\n\t\t\t\t\tmain |= ((tjs_uint64)n << (64 - numsignif));\n\t\t\t\t}\n\t\t\t\tif(!pointpassed) exp += basebits;\n\t\t\t}\n\t\t}\n\t\tif(!TJSNext(ptr)) break;\n\t}\n\n\tmain >>= (64 - 1 - TJS_IEEE_D_SIGNIFICAND_BITS);\n\n\tif(main == 0)\n\t{\n\t\t// zero\n\t\tval = (tTVReal)0.0;\n\t\treturn true;\n\t}\n\n\tmain &= ((TJS_UI64_VAL(1) << TJS_IEEE_D_SIGNIFICAND_BITS) - TJS_UI64_VAL(1));\n\n\tif(exp < TJS_IEEE_D_EXP_MIN)\n\t{\n\t\t// denormal\n\t\t// treat as zero\n\t\tval = (tTVReal)0.0;\n\t\treturn true;\n\t}\n\n\tif(exp > TJS_IEEE_D_EXP_MAX)\n\t{\n\t\t// too large\n\t\t// treat as infinity\n\t\ttjs_real d;\n\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_INF;\n\t\tval = d;\n\t\treturn true;\n\t}\n\n\t// compose IEEE double\n\ttjs_real d;\n\t*(tjs_uint64*)&d =\n\t\tTJS_IEEE_D_MAKE_SIGN(0) |\n\t\tTJS_IEEE_D_MAKE_EXP(exp) |\n\t\tTJS_IEEE_D_MAKE_SIGNIFICAND(main);\n\tval = d;\n\treturn true;\n}\n\nstatic bool TJSParseNonDecimalInteger(tTJSVariant &val, const tjs_char **ptr,\n\ttjs_int (*validdigits)(tjs_char ch), tjs_int basebits)\n{\n\ttjs_int64 v = 0;\n\twhile(true)\n\t{\n\t\tv <<= basebits;\n\t\tv += validdigits(**ptr);\n\t\tif(!TJSNext(ptr)) break;\n\t}\n\tval = (tTVInteger)v;\n\treturn true;\n}\n\nstatic bool TJSParseNonDecimalNumber(tTJSVariant &val, const tjs_char **ptr,\n\ttjs_int (*validdigits)(tjs_char ch), tjs_int base)\n{\n\tbool isreal = false;\n\ttTJSString tmp(TJSExtractNumber(validdigits, TJS_W(\"Pp\"), ptr, isreal));\n\n\tif(tmp.IsEmpty()) return false;\n\n\tconst tjs_char *p = tmp.c_str();\n\tconst tjs_char **pp = &p;\n\n\tif(isreal)\n\t\treturn TJSParseNonDecimalReal(val, pp, validdigits, base);\n\telse\n\t\treturn TJSParseNonDecimalInteger(val, pp, validdigits, base);\n}\n\nstatic bool TJSParseDecimalReal(tTJSVariant &val, const tjs_char **pp)\n{\n\tval = (tTVReal)TJS_strtod(*pp, NULL);\n\treturn true;\n}\n\nstatic bool TJSParseDecimalInteger(tTJSVariant &val, const tjs_char **pp)\n{\n\tint n;\n\ttjs_int64 num = 0;\n\twhile((n = TJSDecNum(**pp)) != -1)\n\t{\n\t\tnum *= 10;\n\t\tnum += n;\n\t\tif(!TJSNext(pp)) break;\n\t}\n\tval = (tTVInteger)num;\n\treturn true;\n}\n\nstatic bool TJSParseNumber2(tTJSVariant &val, const tjs_char **ptr)\n{\n\t// stage 2\n\n\tif(TJSStringMatch(ptr, TJS_W(\"true\"), true))\n\t{\n\t\tval = (tjs_int)true;\n\t\treturn true;\n\t}\n\tif(TJSStringMatch(ptr, TJS_W(\"false\"), true))\n\t{\n\t\tval = (tjs_int)false;\n\t\treturn true;\n\t}\n\tif(TJSStringMatch(ptr, TJS_W(\"NaN\"), true))\n\t{\n\t\t// Not a Number\n\t\ttjs_real d;\n\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_NaN;\n\t\tval = d;\n\t\treturn true;\n\t}\n\tif(TJSStringMatch(ptr, TJS_W(\"Infinity\"), true))\n\t{\n\t\t// positive inifinity\n\t\ttjs_real d;\n\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_INF;\n\t\tval = d;\n\t\treturn true;\n\t}\n\n\tconst tjs_char *ptr_save = *ptr;\n\n\tif(**ptr == TJS_W('0'))\n\t{\n\t\tif(!TJSNext(ptr))\n\t\t{\n\t\t\tval = (tjs_int) 0;\n\t\t\treturn true;\n\t\t}\n\n\t\ttjs_char mark = **ptr;\n\n\t\tif(mark == TJS_W('X') || mark == TJS_W('x'))\n\t\t{\n\t\t\t// hexadecimal\n\t\t\tif(!TJSNext(ptr)) return false;\n\t\t\treturn TJSParseNonDecimalNumber(val, ptr, TJSHexNum, 4);\n\t\t}\n\n\t\tif(mark == TJS_W('B') || mark == TJS_W('b'))\n\t\t{\n\t\t\t// binary\n\t\t\tif(!TJSNext(ptr)) return false;\n\t\t\treturn TJSParseNonDecimalNumber(val, ptr, TJSBinNum, 1);\n\t\t}\n\n\t\tif(mark == TJS_W('.'))\n\t\t{\n\t\t\t// decimal point\n\t\t\t*ptr = ptr_save;\n\t\t\tgoto decimal;\n\t\t}\n\n\t\tif(mark == TJS_W('E') || mark == TJS_W('e'))\n\t\t{\n\t\t\t// exp\n\t\t\t*ptr = ptr_save;\n\t\t\tgoto decimal;\n\t\t}\n\n\t\tif(mark == TJS_W('P') || mark == TJS_W('p'))\n\t\t{\n\t\t\t// 2^n exp\n\t\t\treturn false;\n\t\t}\n\n\t\t// octal\n\t\t*ptr = ptr_save;\n\t\treturn TJSParseNonDecimalNumber(val, ptr, TJSOctNum, 3);\n\t}\n\n\t// integer decimal or real decimal\ndecimal:\n\tbool isreal = false;\n\ttTJSString tmp(TJSExtractNumber(TJSDecNum, TJS_W(\"Ee\"), ptr, isreal));\n\n\tif(tmp.IsEmpty()) return false;\n\n\tconst tjs_char *p = tmp.c_str();\n\tconst tjs_char **pp = &p;\n\n\tif(isreal)\n\t\treturn TJSParseDecimalReal(val, pp);\n\telse\n\t\treturn TJSParseDecimalInteger(val, pp);\n}\n\n\nbool TJSParseNumber(tTJSVariant &val, const tjs_char **ptr)\n{\n\t// parse a number pointed by (*ptr)\n\tTJSSetFPUE();\n\n\tbool sign = false; // true if negative\n\n\tif(**ptr == TJS_W('+'))\n\t{\n\t\tsign = false;\n\t\tif(!TJSNext(ptr)) return false;\n\t\tif(!TJSSkipSpace(ptr)) return false;\n\t}\n\telse if(**ptr == TJS_W('-'))\n\t{\n\t\tsign = true;\n\t\tif(!TJSNext(ptr)) return false;\n\t\tif(!TJSSkipSpace(ptr)) return false;\n\t}\n\n\tif(TJSParseNumber2(val, ptr))\n\t{\n\t\tif(sign) val = -val;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSParseOctet\n//---------------------------------------------------------------------------\nstatic bool TJSParseOctet(tTJSVariant &val, const tjs_char **ptr)\n{\n\t// parse a octet literal;\n\t// syntax is:\n\t// <% xx xx xx xx xx xx ... %>\n\t// where xx is hexadecimal 8bit(octet) binary representation.\n\tTJSNext(ptr);\n\tTJSNext(ptr);   // skip <%\n\n\ttjs_uint8 *buf = NULL;\n\ttjs_uint buflen = 0;\n\n\tbool leading = true;\n\ttjs_uint8 cur = 0;\n\n\tfor(;*(*ptr);)\n\t{\n\t\tswitch(TJSSkipComment(ptr))\n\t\t{\n\t\tcase scrEnded:\n\t\t\tTJS_eTJSError(TJSStringParseError);\n\t\tcase scrContinue:\n\t\tcase scrNotComment:\n\t\t\t;\n\t\t}\n\n\n\t\tconst tjs_char *next = *ptr;\n\t\tTJSNext(&next);\n\t\tif(*(*ptr) == TJS_W('%') && *next == TJS_W('>'))\n\t\t{\n\t\t\t*ptr = next;\n\t\t\tTJSNext(ptr);\n\n\t\t\t// literal ended\n\n\t\t\tif(!leading)\n\t\t\t{\n\t\t\t\tbuf = (tjs_uint8*)TJS_realloc(buf, buflen+1);\n\t\t\t\tif(!buf)\n\t\t\t\t\tthrow eTJSError(ttstr(TJSInsufficientMem));\n\t\t\t\tbuf[buflen] = cur;\n\t\t\t\tbuflen++;\n\t\t\t}\n\n\t\t\tval = tTJSVariant(buf, buflen); // create octet variant\n\t\t\tif(buf) TJS_free(buf);\n\t\t\treturn true;\n\t\t}\n\n\t\ttjs_char ch = *(*ptr);\n\t\ttjs_int n = TJSHexNum(ch);\n\t\tif(n != -1)\n\t\t{\n\t\t\tif(leading)\n\t\t\t{\n\t\t\t\tcur = (tjs_uint8)(n);\n\t\t\t\tleading = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcur <<= 4;\n\t\t\t\tcur += n;\n\n\t\t\t\t// store cur\n\t\t\t\tbuf = (tjs_uint8*)TJS_realloc(buf, buflen+1);\n\t\t\t\tif(!buf)\n\t\t\t\t\tthrow eTJSError(ttstr(TJSInsufficientMem));\n\t\t\t\tbuf[buflen] = cur;\n\t\t\t\tbuflen++;\n\n\t\t\t\tleading = true;\n\t\t\t}\n\t\t}\n\n\t\tif(!leading && ch == TJS_W(','))\n\t\t{\n\t\t\tbuf = (tjs_uint8*)TJS_realloc(buf, buflen+1);\n\t\t\tif(!buf)\n\t\t\t\tTJS_eTJSError(TJSInsufficientMem);\n\t\t\tbuf[buflen] = cur;\n\t\t\tbuflen++;\n\n\t\t\tleading = true;\n\t\t}\n\n\t\t*ptr = next;\n\t}\n\n\t// error\n\tTJS_eTJSError(TJSStringParseError);\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSParseRegExp\n//---------------------------------------------------------------------------\nstatic bool TJSParseRegExp(tTJSVariant &pat, const tjs_char **ptr)\n{\n\t// parse a regular expression pointed by 'ptr'.\n\t// this is essencially the same as string parsing, except for\n\t// not to decode escaped characters by '\\\\'.\n\t// the regexp must be terminated by the delimiter '/', not succeeded by '\\\\'.\n\n\t// this returns an internal representation: '//flag/pattern' that can be parsed by\n\t// RegExp._compile\n\n//\tif(!TJSNext((*ptr))) TJS_eTJSError(TJSStringParseError);\n\n\tbool ok = false;\n\tbool lastbackslash = false;\n\tttstr str;\n\n\tfor(;*(*ptr);)\n\t{\n\t\tif(*(*ptr)==TJS_W('\\\\'))\n\t\t{\n\t\t\tstr+=*(*ptr);\n\t\t\tif(lastbackslash)\n\t\t\t\tlastbackslash = false;\n\t\t\telse\n\t\t\t\tlastbackslash = true;\n\t\t}\n\t\telse if(*(*ptr)==TJS_W('/') && !lastbackslash)\n\t\t{\n\t\t\t// string delimiters\n//\t\t\tlastbackslash = false;\n\n\t\t\tif(!TJSNext(ptr))\n\t\t\t{\n\t\t\t\tok = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// flags can be here\n\t\t\tttstr flag;\n\t\t\twhile(*(*ptr) >= TJS_W('a') && *(*ptr) <= TJS_W('z'))\n\t\t\t{\n\t\t\t\tflag += *(*ptr);\n\t\t\t\tif(!TJSNext(ptr)) break;\n\t\t\t}\n\t\t\tstr = TJS_W(\"/\")TJS_W(\"/\")+ flag + TJS_W(\"/\") + str;\n\t\t\tok = true;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlastbackslash = false;\n\t\t\tstr+=*(*ptr);\n\t\t}\n\t\tTJSNext(ptr);\n\t}\n\n\tif(!ok)\n\t{\n\t\t// error\n\t\tTJS_eTJSError(TJSStringParseError);\n\t}\n\n\tpat = str;\n\n\treturn true;\n}\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// hash table for reserved words\n//---------------------------------------------------------------------------\nstatic tTJSCustomObject * TJSReservedWordHash = NULL;\nstatic bool TJSReservedWordHashInit = false;\nstatic tjs_int TJSReservedWordHashRefCount;\n//---------------------------------------------------------------------------\nvoid TJSReservedWordsHashAddRef()\n{\n\tif(TJSReservedWordHashRefCount == 0)\n\t{\n\t\tTJSReservedWordHashInit = false;\n\t\tTJSReservedWordHash = new tTJSCustomObject();\n\t}\n\tTJSReservedWordHashRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid TJSReservedWordsHashRelease()\n{\n\tTJSReservedWordHashRefCount --;\n\n\tif(TJSReservedWordHashRefCount == 0)\n\t{\n\t\tTJSReservedWordHash->Release();\n\t\tTJSReservedWordHash = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TJSRegisterReservedWordsHash(const tjs_char *word, tjs_int num)\n{\n\ttTJSVariant val(num);\n\tTJSReservedWordHash->PropSet(TJS_MEMBERENSURE, word, NULL, &val,\n\t\tTJSReservedWordHash);\n}\n//---------------------------------------------------------------------------\n#define TJS_REG_RES_WORD(word, value) TJSRegisterReservedWordsHash(TJS_W(word), value);\nstatic void TJSInitReservedWordsHashTable()\n{\n\tif(TJSReservedWordHashInit) return;\n\tTJSReservedWordHashInit = true;\n\n\tTJS_REG_RES_WORD(\"break\", T_BREAK);\n\tTJS_REG_RES_WORD(\"continue\", T_CONTINUE);\n\tTJS_REG_RES_WORD(\"const\", T_CONST);\n\tTJS_REG_RES_WORD(\"catch\", T_CATCH);\n\tTJS_REG_RES_WORD(\"class\", T_CLASS);\n\tTJS_REG_RES_WORD(\"case\", T_CASE);\n\tTJS_REG_RES_WORD(\"debugger\", T_DEBUGGER);\n\tTJS_REG_RES_WORD(\"default\", T_DEFAULT);\n\tTJS_REG_RES_WORD(\"delete\", T_DELETE);\n\tTJS_REG_RES_WORD(\"do\", T_DO);\n\tTJS_REG_RES_WORD(\"extends\", T_EXTENDS);\n\tTJS_REG_RES_WORD(\"export\", T_EXPORT);\n\tTJS_REG_RES_WORD(\"enum\", T_ENUM);\n\tTJS_REG_RES_WORD(\"else\", T_ELSE);\n\tTJS_REG_RES_WORD(\"function\", T_FUNCTION);\n\tTJS_REG_RES_WORD(\"finally\", T_FINALLY);\n\tTJS_REG_RES_WORD(\"false\", T_FALSE);\n\tTJS_REG_RES_WORD(\"for\", T_FOR);\n\tTJS_REG_RES_WORD(\"global\", T_GLOBAL);\n\tTJS_REG_RES_WORD(\"getter\", T_GETTER);\n\tTJS_REG_RES_WORD(\"goto\", T_GOTO);\n\tTJS_REG_RES_WORD(\"incontextof\", T_INCONTEXTOF);\n\tTJS_REG_RES_WORD(\"invalidate\", T_INVALIDATE);\n\tTJS_REG_RES_WORD(\"instanceof\", T_INSTANCEOF);\n\tTJS_REG_RES_WORD(\"isvalid\", T_ISVALID);\n\tTJS_REG_RES_WORD(\"import\", T_IMPORT);\n\tTJS_REG_RES_WORD(\"int\", T_INT);\n\tTJS_REG_RES_WORD(\"in\", T_IN);\n\tTJS_REG_RES_WORD(\"if\", T_IF);\n\tTJS_REG_RES_WORD(\"null\", T_NULL);\n\tTJS_REG_RES_WORD(\"new\", T_NEW);\n\tTJS_REG_RES_WORD(\"octet\", T_OCTET);\n\tTJS_REG_RES_WORD(\"protected\", T_PROTECTED);\n\tTJS_REG_RES_WORD(\"property\", T_PROPERTY);\n\tTJS_REG_RES_WORD(\"private\", T_PRIVATE);\n\tTJS_REG_RES_WORD(\"public\", T_PUBLIC);\n\tTJS_REG_RES_WORD(\"return\", T_RETURN);\n\tTJS_REG_RES_WORD(\"real\", T_REAL);\n\tTJS_REG_RES_WORD(\"synchronized\", T_SYNCHRONIZED);\n\tTJS_REG_RES_WORD(\"switch\", T_SWITCH);\n\tTJS_REG_RES_WORD(\"static\", T_STATIC);\n\tTJS_REG_RES_WORD(\"setter\", T_SETTER);\n\tTJS_REG_RES_WORD(\"string\", T_STRING);\n\tTJS_REG_RES_WORD(\"super\", T_SUPER);\n\tTJS_REG_RES_WORD(\"typeof\", T_TYPEOF);\n\tTJS_REG_RES_WORD(\"throw\", T_THROW);\n\tTJS_REG_RES_WORD(\"this\", T_THIS);\n\tTJS_REG_RES_WORD(\"true\", T_TRUE);\n\tTJS_REG_RES_WORD(\"try\", T_TRY);\n\tTJS_REG_RES_WORD(\"void\", T_VOID);\n\tTJS_REG_RES_WORD(\"var\", T_VAR);\n\tTJS_REG_RES_WORD(\"while\", T_WHILE);\n#ifndef TJS_NaN_and_Infinity_ARE_NOT_RESERVED_WORD\n\tTJS_REG_RES_WORD(\"NaN\", T_NAN);\n\tTJS_REG_RES_WORD(\"Infinity\", T_INFINITY);\n#endif\n#ifndef TJS_WITH_IS_NOT_RESERVED_WORD\n\tTJS_REG_RES_WORD(\"with\", T_WITH);\n#endif\n\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSLexicalAnalyzer\n//---------------------------------------------------------------------------\ntTJSLexicalAnalyzer::tTJSLexicalAnalyzer(tTJSScriptBlock *block,\n\tconst tjs_char *script, bool exprmode, bool resneeded)\n{\n\t// resneeded is valid only if exprmode is true\n\n\tTJS_F_TRACE(\"tTJSLexicalAnalyzer::tTJSLexicalAnalyzer\");\n\n\tTJSInitReservedWordsHashTable();\n\n\tBlock = block;\n\tExprMode = exprmode;\n\tResultNeeded = resneeded;\n\tPrevToken = -1;\n\ttjs_int len = (tjs_int)TJS_strlen(script);\n\tScript = new tjs_char[len+2];\n\tTJS_strcpy(Script, script);\n\tif(ExprMode)\n\t{\n\t\t// append ';' on expression analyze mode\n\t\tScript[len] = TJS_W(';');\n\t\tScript[len+1] = 0;\n\t}\n\telse\n\t{\n\t\tif(Script[0] == TJS_W('#') && Script[1] == TJS_W('!'))\n\t\t{\n\t\t\t// shell script like file\n\t\t\tScript[0] = TJS_W('/');\n\t\t\tScript[1] = TJS_W('/');  // convert #! to //\n\t\t}\n\t}\n\n\tif(tjsEnableDicFuncQuickHack) //----- dicfunc quick-hack\n\t{\n\t\tDicFunc = false;\n\t\tif(ExprMode && (Script[0] == TJS_W('[') || (Script[0] == TJS_W('%') && Script[1] == TJS_W('['))))\n\t\t{\n\t\t\tDicFunc = true;\n\t\t}\n\t}\n\n\tCurrent = Script;\n\tIfLevel = 0;\n\tPrevPos = 0;\n\tNestLevel = 0;\n\tFirst = true;\n\tRegularExpression = false;\n\tBareWord = false;\n\tPutValue(tTJSVariant());\n}\n//---------------------------------------------------------------------------\ntTJSLexicalAnalyzer::~tTJSLexicalAnalyzer()\n{\n\tFree();\n}\n//---------------------------------------------------------------------------\ntTJSSkipCommentResult tTJSLexicalAnalyzer::SkipUntil_endif()\n{\n\t// skip until @endif\n\ttjs_int exl = IfLevel;\n\tIfLevel ++;\n\twhile(true)\n\t{\n\t\tif(*Current == TJS_W('/'))\n\t\t{\n\t\t\tswitch(TJSSkipComment(&Current))\n\t\t\t{\n\t\t\tcase scrEnded:\n\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t\t\tbreak;\n\t\t\tcase scrContinue:\n\t\t\t\tbreak;\n\t\t\tcase scrNotComment:\n\t\t\t\tif(!TJSNext(&Current))\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if(*Current == TJS_W('@'))\n\t\t{\n\t\t\tCurrent ++;\n\t\t\tbool skipp = false;\n\n\t\t\tif(!TJS_strncmp(Current, TJS_W(\"if\"), 2))\n\t\t\t{\n\t\t\t\tIfLevel ++;\n\t\t\t\tCurrent += 2;\n\t\t\t\tskipp = true;\n\t\t\t}\n\t\t\telse if(!TJS_strncmp(Current, TJS_W(\"set\"), 3))\n\t\t\t{\n\t\t\t\tCurrent += 3;\n\t\t\t\tskipp = true;\n\t\t\t}\n\t\t\telse if(!TJS_strncmp(Current, TJS_W(\"endif\"), 5))\n\t\t\t{\n\t\t\t\t// endif\n\t\t\t\tCurrent += 5;\n\t\t\t\tIfLevel--;\n\t\t\t\tif(IfLevel == exl)\n\t\t\t\t{\n\t\t\t\t\t// skip ended\n\t\t\t\t\tTJSSkipSpace(&Current);\n\t\t\t\t\tif(!*Current) return scrEnded;\n\t\t\t\t\treturn scrContinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// skipp = false\n\t\t\t}\n\n\t\t\tif(skipp)\n\t\t\t{\n\t\t\t\t// skip parenthesises\n\t\t\t\tif(!TJSSkipSpace(&Current))\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\t\t\tif(*Current!=TJS_W('('))\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\t\t\tTJSNext(&Current);\n\t\t\t\ttjs_int plevel = 0;\n\t\t\t\twhile(*Current && (plevel || *Current!=TJS_W(')')))\n\t\t\t\t{\n\t\t\t\t\tif(*Current == TJS_W('(')) plevel++;\n\t\t\t\t\telse if(*Current == TJS_W(')')) plevel--;\n\t\t\t\t\tTJSNext(&Current);\n\t\t\t\t}\n\t\t\t\tif(!*Current)\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t\t\tTJSNext(&Current);\n\t\t\t\tif(!*Current)\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TJSNext(&Current))\n\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSSkipCommentResult tTJSLexicalAnalyzer::ProcessPPStatement()\n{\n\t// process pre-prosessor statements.\n\t// here \"Current\" points '@'.\n\tconst tjs_char *org = Current;\n\n\tCurrent ++;\n\n\tif(!TJS_strncmp(Current, TJS_W(\"set\"), 3))\n\t{\n\t\t// set statement\n\t\tBlock->NotifyUsingPreProcessor();\n\t\tCurrent+=3;\n\t\tif(!TJSSkipSpace(&Current))\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\tif(*Current!=TJS_W('('))\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\tTJSNext(&Current);\n\t\tconst tjs_char *st = Current;\n\t\ttjs_int plevel = 0;\n\t\twhile(*Current && (plevel || *Current!=TJS_W(')')))\n\t\t{\n\t\t\tif(*Current == TJS_W('(')) plevel++;\n\t\t\telse if(*Current == TJS_W(')')) plevel--;\n\t\t\tTJSNext(&Current);\n\t\t}\n\t\tconst tjs_char *ed = Current;\n\n\t\tTJSNext(&Current);\n\n\t\ttry\n\t\t{\n\t\t\tParsePPExpression(st, (tjs_int)(ed-st)); // evaluate exp\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t}\n\n\t\tTJSSkipSpace(&Current);\n\t\tif(!*Current) return scrEnded;\n\n\t\treturn scrContinue;\n\t}\n\n\tif(!TJS_strncmp(Current, TJS_W(\"if\"), 2))\n\t{\n\t\t// if statement\n\n\t\tBlock->NotifyUsingPreProcessor();\n\t\tCurrent += 2;\n\t\tif(!TJSSkipSpace(&Current))\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\tif(*Current!=TJS_W('('))\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\tTJSNext(&Current);\n\t\tconst tjs_char *st = Current;\n\t\ttjs_int plevel = 0;\n\t\twhile(*Current && (plevel || *Current!=TJS_W(')')))\n\t\t{\n\t\t\tif(*Current == TJS_W('(')) plevel++;\n\t\t\telse if(*Current == TJS_W(')')) plevel--;\n\t\t\tTJSNext(&Current);\n\t\t}\n\t\tconst tjs_char *ed = Current;\n\n\t\tTJSNext(&Current);\n\n\t\ttjs_int32 ret;\n\n\t\ttry\n\t\t{\n\t\t\tret = ParsePPExpression(st, (tjs_int)(ed-st)); // evaluate exp\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t}\n\n\t\tif(!ret) return SkipUntil_endif();  // skip to endif\n\n\t\tIfLevel ++;\n\n\t\tTJSSkipSpace(&Current);\n\t\tif(!*Current) return scrEnded;\n\t\treturn scrContinue;\n\t}\n\n\n\tif(!TJS_strncmp(Current, TJS_W(\"endif\"), 5))\n\t{\n\t\tCurrent += 5;\n\t\tIfLevel --;\n\t\tif(IfLevel < 0)\n\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\n\t\tTJSSkipSpace(&Current);\n\t\tif(!*Current) return scrEnded;\n\t\treturn scrContinue;\n\t}\n\n\tCurrent = org;\n\treturn scrNotComment;\n}\n//---------------------------------------------------------------------------\n#define TJS_MATCH_W(word, code) \\\n\tif(TJSStringMatch(&Current, TJS_W(word), true)) return (code)\n#define TJS_MATCH_S(word, code) \\\n\tif(TJSStringMatch(&Current, TJS_W(word), false)) return (code)\n#define TJS_MATCH_W_V(word, code, val) \\\n\tif(TJSStringMatch(&Current, TJS_W(word), true)) { n=PutValue(val); return (code); }\n#define TJS_MATCH_S_V(word, code, val) \\\n\tif(TJSStringMatch(&Current, TJS_W(word), false)) { n=PutValue(val); return (code); }\n#define TJS_1CHAR(code) \\\n\tTJSNext(&Current); return (code)\ntjs_int tTJSLexicalAnalyzer::GetToken(tjs_int &n)\n{\n\t// returns token, pointed by 'Current'\n\n\tif(*Current == 0) return 0;\n\n\tif(RegularExpression)\n\t{\n\t\t// the next token was marked as a regular expression by the parser\n\t\tRegularExpression = false;\n\n\t\tCurrent = Script + PrevPos; // draws position of the first '/' back\n\n\t\tTJSNext(&Current);\n\n\t\ttTJSVariant pat;\n\t\tTJSParseRegExp(pat, &Current);\n\t\tn = PutValue(pat);\n\n\t\treturn T_REGEXP;\n\t}\n\nre_match:\n\n\tPrevPos = (tjs_int)(Current - Script); // remember current position as \"PrevPos\"\n\n\tswitch(*Current)\n\t{\n\tcase TJS_W('>'):\n\t\tTJS_MATCH_S(\">>>=\", T_RBITSHIFTEQUAL);\n\t\tTJS_MATCH_S(\">>>\", T_RBITSHIFT);\n\t\tTJS_MATCH_S(\">>=\", T_RARITHSHIFTEQUAL);\n\t\tTJS_MATCH_S(\">>\", T_RARITHSHIFT);\n\t\tTJS_MATCH_S(\">=\", T_GTOREQUAL);\n\t\tTJS_1CHAR(T_GT);\n\n\tcase TJS_W('<'):\n\t\tTJS_MATCH_S(\"<<=\", T_LARITHSHIFTEQUAL);\n\t\tTJS_MATCH_S(\"<->\", T_SWAP);\n\t\tTJS_MATCH_S(\"<=\", T_LTOREQUAL);\n\t\tTJS_MATCH_S(\"<<\", T_LARITHSHIFT);\n\t\t{\n\t\t\tconst tjs_char *next = Current;\n\t\t\tTJSNext(&next);\n\t\t\tif(*next == TJS_W('%'))\n\t\t\t{\n\t\t\t\t// '<%'   octet literal\n\t\t\t\ttTJSVariant v;\n\t\t\t\tTJSParseOctet(v, &Current);\n\t\t\t\tn = PutValue(v);\n\t\t\t\treturn T_CONSTVAL;\n\t\t\t}\n\t\t}\n\t\tTJS_1CHAR(T_LT);\n\n\tcase TJS_W('='):\n\t\tTJS_MATCH_S(\"===\", T_DISCEQUAL);\n\t\tTJS_MATCH_S(\"==\", T_EQUALEQUAL);\n\t\tTJS_MATCH_S(\"=>\", T_COMMA);\n\t\t\t// just a replacement for comma, like perl\n\t\tTJS_1CHAR(T_EQUAL);\n\n\tcase TJS_W('!'):\n\t\tTJS_MATCH_S(\"!==\", T_DISCNOTEQUAL);\n\t\tTJS_MATCH_S(\"!=\", T_NOTEQUAL);\n\t\tTJS_1CHAR(T_EXCRAMATION);\n\n\tcase TJS_W('&'):\n\t\tTJS_MATCH_S(\"&&=\", T_LOGICALANDEQUAL);\n\t\tTJS_MATCH_S(\"&&\", T_LOGICALAND);\n\t\tTJS_MATCH_S(\"&=\", T_AMPERSANDEQUAL);\n\t\tTJS_1CHAR(T_AMPERSAND);\n\n\tcase TJS_W('|'):\n\t\tTJS_MATCH_S(\"||=\", T_LOGICALOREQUAL);\n\t\tTJS_MATCH_S(\"||\", T_LOGICALOR);\n\t\tTJS_MATCH_S(\"|=\", T_VERTLINEEQUAL);\n\t\tTJS_1CHAR(T_VERTLINE);\n\n\tcase TJS_W('.'):\n\t\tif(Current[1] >= TJS_W('0') && Current[1] <= TJS_W('9'))\n\t\t{\n\t\t\t// number\n\t\t\ttTJSVariant v;\n\t\t\tTJSParseNumber(v, &Current);\n\t\t\tn=PutValue(v);\n\t\t\treturn T_CONSTVAL;\n\t\t}\n\t\tTJS_MATCH_S(\"...\", T_OMIT);\n\t\tTJS_1CHAR(T_DOT);\n\n\tcase TJS_W('+'):\n\t\tTJS_MATCH_S(\"++\", T_INCREMENT);\n\t\tTJS_MATCH_S(\"+=\", T_PLUSEQUAL);\n\t\tTJS_1CHAR(T_PLUS);\n\n\tcase TJS_W('-'):\n\t\tTJS_MATCH_S(\"-=\", T_MINUSEQUAL);\n\t\tTJS_MATCH_S(\"--\", T_DECREMENT);\n\t\tTJS_1CHAR(T_MINUS);\n\n\tcase TJS_W('*'):\n\t\tTJS_MATCH_S(\"*=\", T_ASTERISKEQUAL);\n\t\tTJS_1CHAR(T_ASTERISK);\n\n\tcase TJS_W('/'):\n\t\t// check comments\n\t\tswitch(TJSSkipComment(&Current))\n\t\t{\n\t\tcase scrContinue:\n\t\t\tgoto re_match;\n\t\tcase scrEnded:\n\t\t\treturn 0;\n\t\tcase scrNotComment:\n\t\t\t;\n\t\t}\n\n\t\tTJS_MATCH_S(\"/=\", T_SLASHEQUAL);\n\t\tTJS_1CHAR(T_SLASH);\n\n\tcase TJS_W('\\\\'):\n\t\tTJS_MATCH_S(\"\\\\=\", T_BACKSLASHEQUAL);\n\t\tTJS_1CHAR(T_BACKSLASH);\n\n\tcase TJS_W('%'):\n\t\tTJS_MATCH_S(\"%=\", T_PERCENTEQUAL);\n\t\tTJS_1CHAR(T_PERCENT);\n\n\tcase TJS_W('^'):\n\t\tTJS_MATCH_S(\"^=\", T_CHEVRONEQUAL);\n\t\tTJS_1CHAR(T_CHEVRON);\n\n\tcase TJS_W('['):\n\t\tNestLevel++;\n\t\tTJS_1CHAR(T_LBRACKET);\n\n\tcase TJS_W(']'):\n\t\tNestLevel--;\n\t\tTJS_1CHAR(T_RBRACKET);\n\n\tcase TJS_W('('):\n\t\tNestLevel++;\n\t\tTJS_1CHAR(T_LPARENTHESIS);\n\n\tcase TJS_W(')'):\n\t\tNestLevel--;\n\t\tTJS_1CHAR(T_RPARENTHESIS);\n\n\tcase TJS_W('~'):\n\t\tTJS_1CHAR(T_TILDE);\n\n\tcase TJS_W('?'):\n\t\tTJS_1CHAR(T_QUESTION);\n\n\tcase TJS_W(':'):\n\t\tTJS_1CHAR(T_COLON);\n\n\tcase TJS_W(','):\n\t\tTJS_1CHAR(T_COMMA);\n\n\tcase TJS_W(';'):\n\t\tTJS_1CHAR(T_SEMICOLON);\n\n\tcase TJS_W('{'):\n\t\tNestLevel++;\n\t\tTJS_1CHAR(T_LBRACE);\n\n\tcase TJS_W('}'):\n\t\tNestLevel--;\n\t\tTJS_1CHAR(T_RBRACE);\n\n\tcase TJS_W('#'):\n\t\tTJS_1CHAR(T_SHARP);\n\n\tcase TJS_W('$'):\n\t\tTJS_1CHAR(T_DOLLAR);\n\n\tcase TJS_W('\\''):\n\tcase TJS_W('\\\"'):\n\t\t// literal string\n\t  {\n\t\ttTJSVariant v;\n\t\tTJSParseString(v, &Current);\n\t\tn=PutValue(v);\n\t\treturn T_CONSTVAL;\n\t  }\n\n\tcase TJS_W('@'):\n\t\t// embeddable expression in string (such as @\"this can be embeddable like &variable;\")\n\t  {\n\t\tconst tjs_char *org = Current;\n\t\tif(!TJSNext(&Current)) return 0;\n\t\tif(!TJSSkipSpace(&Current)) return 0;\n\t\tif(*Current == TJS_W('\\'') || *Current == TJS_W('\\\"'))\n\t\t{\n\t\t\ttEmbeddableExpressionData data;\n\t\t\tdata.State = evsStart;\n\t\t\tdata.WaitingNestLevel = NestLevel;\n\t\t\tdata.Delimiter = *Current;\n\t\t\tdata.NeedPlus = false;\n\t\t\tif(!TJSNext(&Current)) return 0;\n\t\t\tEmbeddableExpressionDataStack.push_back(data);\n\t\t\treturn -1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tCurrent = org;\n\t\t}\n\n\t\t// possible pre-prosessor statements\n\t\tswitch(ProcessPPStatement())\n\t\t{\n\t\tcase scrContinue:\n\t\t\tgoto re_match;\n\t\tcase scrEnded:\n\t\t\treturn 0;\n\t\tcase scrNotComment:\n\t\t\tCurrent = org;\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t  }\n\n\tcase TJS_W('0'):\n\tcase TJS_W('1'):\n\tcase TJS_W('2'):\n\tcase TJS_W('3'):\n\tcase TJS_W('4'):\n\tcase TJS_W('5'):\n\tcase TJS_W('6'):\n\tcase TJS_W('7'):\n\tcase TJS_W('8'):\n\tcase TJS_W('9'):\n\t\t// number\n\t  {\n\t\ttTJSVariant v;\n\t\tbool r = TJSParseNumber(v, &Current);\n\t\tif(!r) TJS_eTJSCompileError(TJSNumberError, Block, (tjs_int)(Current-Script));\n\t\tn=PutValue(v);\n\t\treturn T_CONSTVAL;\n\t  }\n\t}\n\n\tif(!TJS_iswalpha(*Current) && *Current!=TJS_W('_'))\n\t{\n\t\tttstr str(TJSInvalidChar);\n\t\tstr.Replace(TJS_W(\"%1\"), ttstr(*Current).EscapeC());\n\t\tTJS_eTJSError(str);\n\t}\n\n\n\tconst tjs_char *ptr = Current;\n\ttjs_int nch = 0;\n\twhile(TJS_iswdigit(*ptr) || TJS_iswalpha(*ptr) || *ptr==TJS_W('_') ||\n\t\t*ptr>0x0100 || *ptr == TJS_SKIP_CODE)\n\t\tptr++, nch++;\n\n\tif(nch == 0)\n\t{\n\t\tttstr str(TJSInvalidChar);\n\t\tstr.Replace(TJS_W(\"%1\"), ttstr(*Current).EscapeC());\n\t\tTJS_eTJSError(str);\n\t}\n\n\tttstr str(Current, nch);\n\tCurrent += nch;\n\n\ttjs_char *s, *d;\n\ts = d = str.Independ();\n\twhile(*s)\n\t{\n\t\t// eliminate TJS_SKIP_CODE\n\t\tif(*s == TJS_SKIP_CODE)\n\t\t{\n\t\t\ts++;\n\t\t\tcontinue;\n\t\t}\n\t\t*d = *s;\n\t\td++, s++;\n\t}\n\t*d = 0;\n\tstr.FixLen();\n\n\ttjs_int retnum;\n\n\tif(BareWord)\n\t\tretnum = -1;\n\telse\n\t\tretnum = TJSReservedWordHash->GetValueInteger(str.c_str(), str.GetHint());\n\n\tBareWord = false;\n\n\tif(retnum == -1)\n\t{\n\t\t// not a reserved word\n\t\tn = PutValue(str);\n\t\treturn T_SYMBOL;\n\t}\n\n\tswitch(retnum)\n\t{\n\tcase T_FALSE:\n\t\tn = PutValue(tTJSVariant(false));\n\t\treturn T_CONSTVAL;\n\tcase T_NULL:\n\t\tn = PutValue(tTJSVariant((iTJSDispatch2*)NULL));\n\t\treturn T_CONSTVAL;\n\tcase T_TRUE:\n\t\tn = PutValue(tTJSVariant(true));\n\t\treturn T_CONSTVAL;\n\tcase T_NAN:\n\t  {\n\t\tTJSSetFPUE();\n\t\ttjs_real d;\n\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_NaN;\n\t\tn = PutValue(tTJSVariant(d));\n\t\treturn T_CONSTVAL;\n\t  }\n\tcase T_INFINITY:\n\t  {\n\t\tTJSSetFPUE();\n\t\ttjs_real d;\n\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_INF;\n\t\tn = PutValue(tTJSVariant(d));\n\t\treturn T_CONSTVAL;\n\t  }\n\t}\n\n\treturn retnum;\n}\n//---------------------------------------------------------------------------\ntjs_int32 tTJSLexicalAnalyzer::ParsePPExpression(const tjs_char *start, tjs_int n)\n{\n\t// parses a conditional compile experssion starting with \"start\",\n\t// character count \"n\".\n\ttjs_char *buf = new tjs_char[n+1];\n\ttjs_char *p;\n\tconst tjs_char *lim = start + n;\n\tp=buf;\n\twhile(start < lim)\n\t{\n\t\t*p = *start;\n\t\tTJSNext(&start);\n\t\tp++;\n\t}\n\n\t*p = 0;\n\n\ttTJSPPExprParser *parser = new tTJSPPExprParser(Block->GetTJS(), buf);\n\n\ttjs_int32 result;\n\ttry\n\t{\n\t\tresult = parser->Parse();\n\t}\n\tcatch(...)\n\t{\n\t\tdelete parser;\n\t\tthrow;\n\t}\n\n\tdelete parser;\n\n\treturn result;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLexicalAnalyzer::PreProcess(void)\n{\n\tTJS_F_TRACE(\"tTJSLexicalAnalyzer::PreProcess\");\n\n\n\t// pre-process\n\n\t// proceeds newline code unification, conditional compile control.\n\n\n\t/* unify new line codes */\n\tTJS_D((TJS_W(\"unifying new line codes ...\\n\")))\n\n\ttjs_char *p;\n\tp=Script;\n\twhile(*p)\n\t{\n\t\tif(*p==TJS_W('\\r') && *(p+1)==TJS_W('\\n'))\n\t\t\t*p=TJS_SKIP_CODE;\n\t\telse if(*p==TJS_W('\\r'))\n\t\t\t*p=TJS_W('\\n');\n\t\tp++;\n\t}\n}\n\n//---------------------------------------------------------------------------\ntjs_int tTJSLexicalAnalyzer::PutValue(const tTJSVariant &val)\n{\n\ttTJSVariant *v = new tTJSVariant(val);\n\tValues.push_back(v);\n\treturn (tjs_int)(Values.size() -1);\n}\n//---------------------------------------------------------------------------\nvoid tTJSLexicalAnalyzer::Free(void)\n{\n\tif(Script) delete [] Script;\n\tstd::vector<tTJSVariant*>::iterator i;\n\tfor(i = Values.begin(); i != Values.end(); i++)\n\t{\n\t\tdelete *i;\n\t}\n\tValues.clear();\n}\n/*\n//---------------------------------------------------------------------------\nvoid tTJSLexicalAnalyzer::NextBraceIsBlockBrace()\n{\n\tBlockBrace = true;\n}\n*/\n//---------------------------------------------------------------------------\ntjs_int tTJSLexicalAnalyzer::GetCurrentPosition()\n{\n\treturn (tjs_int)(Current - Script);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSLexicalAnalyzer::GetNext(tjs_int &value)\n{\n\tTJS_F_TRACE(\"tTJSLexicalAnalyzer::GetNext\");\n\n\tif(First)\n\t{\n\t\tTJS_D((TJS_W(\"pre-processing ...\\n\")))\n\n\n\t\tFirst = false;\n\t\ttry\n\t\t{\n\t\t\tPreProcess();\n\t\t}\n\t\tcatch(eTJSCompileError &e)\n\t\t{\n\t\t\t_yyerror(e.GetMessage().c_str(), Block, e.GetPosition());\n\t\t\treturn 0;\n\t\t}\n\t\tCurrent = Script;\n\t\tPrevPos = 0;\n\n\t\tif(ExprMode && ResultNeeded)\n\t\t{\n\t\t\tvalue = 0;\n\t\t\treturn T_RETURN;\n\t\t\t\t// return T_RETURN first if 'expression' mode\n\t\t\t\t// (and ResultNeeded is specified)\n\t\t}\n\t}\n\n\ttjs_int n;\n\tvalue = 0;\n\n\tdo\n\t{\n\t\tif(RetValDeque.size())\n\t\t{\n\t\t\ttTokenPair pair = RetValDeque.front();\n\t\t\tRetValDeque.pop_front();\n\t\t\tvalue = pair.value;\n\t\t\tPrevToken = pair.token;\n\t\t\treturn pair.token;\n\t\t}\n\n\n\n\t\ttry\n\t\t{\n\t\t\tif(!EmbeddableExpressionDataStack.size())\n\t\t\t{\n\t\t\t\t// normal mode\n\t\t\t\tTJSSkipSpace(&Current);\n\t\t\t\tn = GetToken(value);\n\n\t\t\t\tif(tjsEnableDicFuncQuickHack) //----- dicfunc quick-hack\n\t\t\t\t{\n\t\t\t\t\tif(DicFunc)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(n == T_PERCENT)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// push \"function { return %\"\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_FUNCTION, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LBRACE, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RETURN, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_PERCENT, 0));\n\t\t\t\t\t\t\tn = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(n == T_LBRACKET && PrevToken != T_PERCENT)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// push \"function { return [\"\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_FUNCTION, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LBRACE, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RETURN, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LBRACKET, 0));\n\t\t\t\t\t\t\tn = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(n == T_RBRACKET)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// push \"] ; }( )\"\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RBRACKET, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_SEMICOLON, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RBRACE, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LPARENTHESIS, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RPARENTHESIS, 0));\n\t\t\t\t\t\t\tn = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// embeddable expression mode\n\t\t\t\ttEmbeddableExpressionData &data = EmbeddableExpressionDataStack.back();\n\t\t\t\tswitch(data.State)\n\t\t\t\t{\n\t\t\t\tcase evsStart:\n\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LPARENTHESIS, 0));\n\t\t\t\t\tn = -1;\n\t\t\t\t\tdata.State = evsNextIsStringLiteral;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase evsNextIsStringLiteral:\n\t\t\t\t  {\n\t\t\t\t\ttTJSVariant v;\n\t\t\t\t\ttTJSInternalParseStringResult res =\n\t\t\t\t\t\t//TJSInternalParseString(v, &Current, data.Delimiter, TJS_W('&'));\n\t\t\t\t\t\tTJSInternalParseString(v, &Current, data.Delimiter, true );\n\t\t\t\t\tif(res == psrDelimiter)\n\t\t\t\t\t{\n\t\t\t\t\t\t// embeddable expression mode ended\n\t\t\t\t\t\tttstr str(v);\n\t\t\t\t\t\tif(!str.IsEmpty())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(data.NeedPlus)\n\t\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_PLUS, 0));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!str.IsEmpty() || !data.NeedPlus)\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_CONSTVAL, PutValue(v)));\n\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RPARENTHESIS, 0));\n\t\t\t\t\t\tEmbeddableExpressionDataStack.pop_back();\n\t\t\t\t\t\tn = -1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// *Current is next to ampersand mark or '${'\n\t\t\t\t\t\tttstr str(v);\n\t\t\t\t\t\tif(!str.IsEmpty())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(data.NeedPlus)\n\t\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_PLUS, 0));\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_CONSTVAL, PutValue(v)));\n\t\t\t\t\t\t\tdata.NeedPlus = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(data.NeedPlus)\n\t\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_PLUS, 0));\n\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_STRING, 0));\n\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_LPARENTHESIS, 0));\n\t\t\t\t\t\tdata.State = evsNextIsExpression;\n\t\t\t\t\t\tif(res == psrAmpersand)\n\t\t\t\t\t\t\tdata.WaitingToken = T_SEMICOLON;\n\t\t\t\t\t\telse if(res == psrDollar)\n\t\t\t\t\t\t\tdata.WaitingToken = T_RBRACE, NestLevel++;\n\t\t\t\t\t\tn = -1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t  }\n\n\t\t\t\tcase evsNextIsExpression:\n\t\t\t\t  {\n\t\t\t\t\tTJSSkipSpace(&Current);\n\t\t\t\t\tn = GetToken(value);\n\n\t\t\t\t\tif(n == data.WaitingToken && NestLevel == data.WaitingNestLevel)\n\t\t\t\t\t{\n\t\t\t\t\t\t// end of embeddable expression mode\n\t\t\t\t\t\tRetValDeque.push_back(tTokenPair(T_RPARENTHESIS, 0));\n\t\t\t\t\t\tdata.NeedPlus = true;\n\t\t\t\t\t\tdata.State = evsNextIsStringLiteral;\n\t\t\t\t\t\tn = -1;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t  }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(n == 0)\n\t\t\t{\n\t\t\t\tif(IfLevel != 0)\n\t\t\t\t\tTJS_eTJSCompileError(TJSPPError, Block, (tjs_int)(Current-Script));\n\t\t\t}\n\t\t}\n\t\tcatch(eTJSCompileError &e)\n\t\t{\n\t\t\t_yyerror(e.GetMessage().c_str(), Block);\n\t\t\treturn 0;\n\t\t}\n\t\tcatch(eTJSScriptError &e)\n\t\t{\n\t\t\t_yyerror(e.GetMessage().c_str(), Block);\n\t\t\treturn 0;\n\t\t}\n\t\tcatch(eTJS &e)\n\t\t{\n\t\t\t_yyerror(e.GetMessage().c_str(), Block);\n\t\t\treturn 0;\n\t\t}\n\t#ifdef TJS_SUPPORT_VCL\n\t\tcatch(EAccessViolation &e)\n\t\t{\n\t\t\tttstr msg(e.Message.c_str());\n\t\t\t_yyerror(msg.c_str(), Block);\n\t\t\treturn 0;\n\t\t}\n\t\tcatch(Exception &e)\n\t\t{\n\t\t\tttstr msg(e.Message.c_str());\n\t\t\t_yyerror(msg.c_str(), Block);\n\t\t\treturn 0;\n\t\t}\n\t#endif\n\t} while(n < 0);\n\n/*\n\tif(BlockBrace)\n\t{\n\t\tif(n == T_LBRACE) n = T_BLOCK_LBRACE;\n\t\tBlockBrace = false;\n\t}\n*/\n\tPrevToken = n;\n\treturn n;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLexicalAnalyzer::SetStartOfRegExp(void)\n{\n\t// notifies that a regular expression ( regexp ) 's\n\t// first '/' ( that indicates the start of the regexp ) had been detected.\n\t// this will be called by the parser.\n\n\tRegularExpression = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLexicalAnalyzer::SetNextIsBareWord(void)\n{\n\t// notifies that the next word must be treated as a bare word\n\t// (not a reserved word)\n\t// this will be called after . (dot) operator by the parser.\n\n\tBareWord = true;\n}\n//---------------------------------------------------------------------------\n\n\n} // namespace TJS\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsLex.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 lexical analyzer\n//---------------------------------------------------------------------------\n#ifndef tjsLexH\n#define tjsLexH\n\n#include \"tjsConfig.h\"\n#include \"tjsVariant.h\"\n#include <vector>\n#include <deque>\n\n\nextern bool tjsEnableDicFuncQuickHack;\n// Defining this enables quick-hack, avoiding the dictionary/array parser\n// memory overflow.\n// This is done with replacing %[ ... ] to function { return %[ ... ]; }()\n// and replacing [ ... ] to function { return [ ... ]; }().\n// These replacing is applied for expression which starts with \"%[\" or \"[\", \n// may cause some sideeffects....\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nextern tjs_int TJSHexNum(tjs_char ch) throw();\nextern tjs_int TJSOctNum(tjs_char ch) throw();\nextern tjs_int TJSDecNum(tjs_char ch) throw();\nextern tjs_int TJSBinNum(tjs_char ch) throw();\n\nbool TJSParseString(tTJSVariant &val, const tjs_char **ptr);\nbool TJSParseNumber(tTJSVariant &val, const tjs_char **ptr);\nvoid TJSReservedWordsHashAddRef();\nvoid TJSReservedWordsHashRelease();\nenum tTJSSkipCommentResult\n{ scrContinue, scrEnded, scrNotComment };\n//---------------------------------------------------------------------------\nclass tTJSScriptBlock;\nclass tTJSLexicalAnalyzer\n{\npublic:\n\ttTJSLexicalAnalyzer(tTJSScriptBlock *block, const tjs_char *script,\n\t\tbool exprmode, bool resneeded);\n\t~tTJSLexicalAnalyzer();\n\nprivate:\n\tconst tjs_char *Current;\n\ttjs_int PrevPos;\n\ttjs_int PrevToken;\n\tbool First;\n\tbool ExprMode;\n\tbool ResultNeeded;\n\ttjs_int NestLevel;\n\n\tbool DicFunc; //----- dicfunc quick-hack\n\n\tstruct tTokenPair\n\t{\n\t\ttjs_int token;\n\t\ttjs_int value;\n\n\t\ttTokenPair(tjs_int token, tjs_int value)\n\t\t{\n\t\t\tthis->token = token;\n\t\t\tthis->value = value;\n\t\t}\n\t};\n\n\tstd::deque<tTokenPair> RetValDeque;\n\n//\tbool BlockBrace;\n\n\tbool RegularExpression;\n\tbool BareWord;\n\n\tenum tEmbeddableExpressionState\n\t{\tevsStart, evsNextIsStringLiteral, evsNextIsExpression };\n\n\tstruct tEmbeddableExpressionData\n\t{\n\t\ttEmbeddableExpressionState State;\n\t\ttjs_int WaitingNestLevel;\n\t\ttjs_int WaitingToken;\n\t\ttjs_char Delimiter;\n\t\tbool NeedPlus;\n\t};\n\n\tstd::vector<tEmbeddableExpressionData> EmbeddableExpressionDataStack;\n\n\n\ttTJSScriptBlock *Block;\n\n\ttjs_char *Script;\n\n\ttTJSSkipCommentResult SkipUntil_endif();\n\ttTJSSkipCommentResult ProcessPPStatement();\n\n\ttjs_int GetToken(tjs_int &value);\n\n\ttjs_int32 ParsePPExpression(const tjs_char *start,\n\t\ttjs_int n);\n\n\tvoid PreProcess(void);\n\n\tstd::vector<tTJSVariant *> Values;\n\n\ttjs_int PutValue(const tTJSVariant &val);\n\n\n\ttjs_int IfLevel; // @if nesting level\n\npublic:\n\tconst tTJSVariant & GetValue(tjs_int idx) const\n\t{\n\t\treturn *Values[idx];\n\t}\n\tconst tjs_char * GetString(tjs_int idx) const\n\t{\n\t\treturn Values[idx]->GetString();\n\t}\n\n\tvoid Free(void);\n\n//\tvoid NextBraceIsBlockBrace();\n\n\ttjs_int GetCurrentPosition();\n\n\ttjs_int GetNext(tjs_int &value);\n\n\tvoid SetStartOfRegExp(void);\n\tvoid SetNextIsBareWord();\n\n};\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsMT19937ar-cok.cpp",
    "content": "/* \n   A C-program for MT19937, with initialization improved 2002/2/10.\n   Coded by Takuji Nishimura and Makoto Matsumoto.\n   This is a faster version by taking Shawn Cokus's optimization,\n   Matthe Bellew's simplification, Isaku Wada's real version.\n\n   Before using, initialize the state by using init_genrand(seed) \n   or init_by_array(init_key, key_length).\n\n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   All rights reserved.\t\t\t\t\t\t\t \n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n\t 1. Redistributions of source code must retain the above copyright\n\t\tnotice, this list of conditions and the following disclaimer.\n\n\t 2. Redistributions in binary form must reproduce the above copyright\n\t\tnotice, this list of conditions and the following disclaimer in the\n\t\tdocumentation and/or other materials provided with the distribution.\n\n\t 3. The names of its contributors may not be used to endorse or promote \n\t\tproducts derived from this software without specific prior written \n\t\tpermission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.\t IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n   Any feedback is very welcome.\n   http://www.math.keio.ac.jp/matumoto/emt.html\n   email: matumoto@math.keio.ac.jp\n\n   ---------------------------------------------------------------------\n   C++ wrapped version by W.Dee <dee@kikyou.info>\n\n*/\n\n#include \"tjsCommHead.h\"\n\n\n#include <stdio.h>\n\n#include \"tjsMT19937ar-cok.h\"\n#include \"TickCount.h\"\n\nnamespace TJS\n{\n\n/* Period parameters */\t \n#define N TJS_MT_N\n#define M 397\n#define MATRIX_A 0x9908b0dfUL\t/* constant vector a */\n#define UMASK 0x80000000UL /* most significant w-r bits */\n#define LMASK 0x7fffffffUL /* least significant r bits */\n#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )\n#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))\n\n\n/* initializes state[N] with a seed */\ntTJSMersenneTwister::tTJSMersenneTwister(unsigned long s)\n{\n\tleft = 1;\n\n\tinit_genrand(s);\n}\n\n\n/* initializes state[N] with a seed */\nvoid tTJSMersenneTwister::init_genrand(unsigned long s)\n{\n\tint j;\n\tstate[0]= s & 0xffffffffUL;\n\tfor (j=1; j<N; j++) {\n\t\tstate[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);\n\t\t/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */\n\t\t/* In the previous versions, MSBs of the seed affect   */\n\t\t/* only MSBs of the array state[].\t\t\t\t\t\t  */\n\t\t/* 2002/01/09 modified by Makoto Matsumoto\t\t\t   */\n\t\tstate[j] &= 0xffffffffUL;   /* for >32 bit machines */\n\t}\n\tleft = 1;\n\tnext = state; /* this is not actually needed, but we do here to avoid CG warning; W.Dee */\n}\n\n\n/* initialize by an array with array-length */\n/* init_key is the array for initializing keys */\n/* key_length is its length */\ntTJSMersenneTwister::tTJSMersenneTwister(unsigned long init_key[], unsigned long key_length)\n{\n\tint i, j, k;\n\tinit_genrand(19650218UL);\n\ti=1; j=0;\n\tk = (N>key_length ? N : key_length);\n\tfor (; k; k--) {\n\t\tstate[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))\n\t\t  + init_key[j] + j; /* non linear */\n\t\tstate[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */\n\t\ti++; j++;\n\t\tif (i>=N) { state[0] = state[N-1]; i=1; }\n\t\tif ((unsigned long)j>=key_length) j=0;\n\t}\n\tfor (k=N-1; k; k--) {\n\t\tstate[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))\n\t\t  - i; /* non linear */\n\t\tstate[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */\n\t\ti++;\n\t\tif (i>=N) { state[0] = state[N-1]; i=1; }\n\t}\n\n\tstate[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ \n\tleft = 1;\n\tnext = state; /* this is not actually needed, but we do here to avoid CG warning; W.Dee */\n}\n\n/* construct tTJSMersenneTwisterData data */\ntTJSMersenneTwister::tTJSMersenneTwister(const tTJSMersenneTwisterData &data)\n{\n\tSetData(data);\n}\n\n\nvoid tTJSMersenneTwister::next_state(void)\n{\n\tunsigned long *p=state;\n\tint j;\n\n\tleft = N;\n\tnext = state;\n\t\n\tfor (j=N-M+1; --j; p++) \n\t\t*p = p[M] ^ TWIST(p[0], p[1]);\n\n\tfor (j=M; --j; p++) \n\t\t*p = p[M-N] ^ TWIST(p[0], p[1]);\n\n\t*p = p[M-N] ^ TWIST(p[0], state[0]);\n}\n\n/* generates a random number on [0,0xffffffff]-interval */\nunsigned long tTJSMersenneTwister::int32(void)\n{\n\tunsigned long y;\n\n\tif (--left == 0) next_state();\n\ty = *next++;\n\n\t/* Tempering */\n\ty ^= (y >> 11);\n\ty ^= (y << 7) & 0x9d2c5680UL;\n\ty ^= (y << 15) & 0xefc60000UL;\n\ty ^= (y >> 18);\n\n\treturn y;\n}\n\n/* generates a random number on [0,0x7fffffff]-interval */\nlong tTJSMersenneTwister::int31(void)\n{\n\tunsigned long y;\n\n\tif (--left == 0) next_state();\n\ty = *next++;\n\n\t/* Tempering */\n\ty ^= (y >> 11);\n\ty ^= (y << 7) & 0x9d2c5680UL;\n\ty ^= (y << 15) & 0xefc60000UL;\n\ty ^= (y >> 18);\n\n\treturn (long)(y>>1);\n}\n\n/* generates a random number on [0,1]-real-interval */\ndouble tTJSMersenneTwister::real1(void)\n{\n\tunsigned long y;\n\n\tif (--left == 0) next_state();\n\ty = *next++;\n\n\t/* Tempering */\n\ty ^= (y >> 11);\n\ty ^= (y << 7) & 0x9d2c5680UL;\n\ty ^= (y << 15) & 0xefc60000UL;\n\ty ^= (y >> 18);\n\n\treturn (double)y * (1.0/4294967295.0); \n\t/* divided by 2^32-1 */ \n}\n\n/* generates a random number on [0,1)-real-interval */\ndouble tTJSMersenneTwister::real2(void)\n{\n\tunsigned long y;\n\n\tif (--left == 0) next_state();\n\ty = *next++;\n\n\t/* Tempering */\n\ty ^= (y >> 11);\n\ty ^= (y << 7) & 0x9d2c5680UL;\n\ty ^= (y << 15) & 0xefc60000UL;\n\ty ^= (y >> 18);\n\n\treturn (double)y * (1.0/4294967296.0); \n\t/* divided by 2^32 */\n}\n\n/* generates a random number on (0,1)-real-interval */\ndouble tTJSMersenneTwister::real3(void)\n{\n\tunsigned long y;\n\n\tif (--left == 0) next_state();\n\ty = *next++;\n\n\t/* Tempering */\n\ty ^= (y >> 11);\n\ty ^= (y << 7) & 0x9d2c5680UL;\n\ty ^= (y << 15) & 0xefc60000UL;\n\ty ^= (y >> 18);\n\n\treturn ((double)y + 0.5) * (1.0/4294967296.0); \n\t/* divided by 2^32 */\n}\n\n/* generates a random number on [0,1) with 53-bit resolution*/\ndouble tTJSMersenneTwister::res53(void) \n{\n\tTJSSetFPUE();\n\tunsigned long a=int32()>>5, b=int32()>>6;\n\treturn(a*67108864.0+b)*(1.0/9007199254740992.0);\n}\n/* These real versions are due to Isaku Wada, 2002/01/09 added */\n\n\ndouble tTJSMersenneTwister::rand_double(void)\n{\n\t// Added by W.Dee\n\t/* generates a random number on [0,1) with IEEE 64-bit double precision */\n\n\ttjs_uint64 v;\n\n\tunsigned long y;\n\n\t{\n\t\tif (--left == 0) next_state();\n\t\ty = *next++;\n\n\t\t/* Tempering */\n\t\ty ^= (y >> 11);\n\t\ty ^= (y << 7) & 0x9d2c5680UL;\n\t\ty ^= (y << 15) & 0xefc60000UL;\n\t\ty ^= (y >> 18);\n\t}\n\n\t((tjs_uint32 *)&v)[0]   = y;\n\n\n\t{\n\t\tif (--left == 0) next_state();\n\t\ty = *next++;\n\n\t\t/* Tempering */\n\t\ty ^= (y >> 11);\n\t\ty ^= (y << 7) & 0x9d2c5680UL;\n\t\ty ^= (y << 15) & 0xefc60000UL;\n\t\ty ^= (y >> 18);\n\t}\n\n\t((tjs_uint32 *)&v)[1]   = y;\n\n\tv &= TJS_IEEE_D_SIGNIFICAND_MASK;\n\n\tv = TJS_IEEE_D_MAKE_SIGNIFICAND(v) | TJS_IEEE_D_MAKE_SIGN(0) |\n\t\t\tTJS_IEEE_D_MAKE_EXP(0);\n\n\t// at this point, v is : 1.0 <= v < 2.0\n\n\tTJSSetFPUE();\n\treturn *(double*)&v - 1.0; // returned value x is : 0.0 <= x < 1.0\n}\n\nvoid tTJSMersenneTwister::SetData(const tTJSMersenneTwisterData & rhs)\n{\n\t*(tTJSMersenneTwisterData*)this = rhs;\n\tnext = rhs.next - rhs.state + state; // fix pointer\n}\n\ntTJSMersenneTwister& tTJSMersenneTwister::sharedInstance()\n{\n\tstatic tTJSMersenneTwister* instance = nullptr;\n\tif (!instance) instance = new tTJSMersenneTwister(TVPGetRoughTickCount32());\n\treturn *instance;\n}\n\n} // namespace TJS\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsMT19937ar-cok.h",
    "content": "#ifndef tjsMT19937ar_cok_H\n#define tjsMT19937ar_cok_H\n\n/*\n   A C-program for MT19937\n   C++ wrapped version by W.Dee <dee@kikyou.info>\n*/\n\nnamespace TJS\n{\n\n\n#define TJS_MT_N 624\n\n\nstruct tTJSMersenneTwisterData\n{\n\tint left;\n\tunsigned long *next; /* points a value in 'state' */\n\tunsigned long state[TJS_MT_N]; /* the array for the state vector  */\n};\n\nclass tTJSMersenneTwister : protected tTJSMersenneTwisterData\n{\n\npublic:\n\ttTJSMersenneTwister(unsigned long s = 5489UL);\n\t\t/* initializes state[N] with a seed */\n\ttTJSMersenneTwister(unsigned long init_key[], unsigned long key_length);\n\t\t/* initialize by an array with array-length */\n\t\t/* init_key is the array for initializing keys */\n\t\t/* key_length is its length */\n\ttTJSMersenneTwister(const tTJSMersenneTwisterData &data);\n\t\t/* construct tTJSMersenneTwisterData data */\n\n\tvirtual ~tTJSMersenneTwister() {;}\n\n\tstatic tTJSMersenneTwister& sharedInstance();\n\nprivate:\n\tvoid init_genrand(unsigned long s);\n\n\tvoid next_state(void);\n\npublic:\n\tunsigned long int32(void); /* generates a random number on [0,0xffffffff]-interval */\n\tlong int31(void); /* generates a random number on [0,0x7fffffff]-interval */\n\tdouble real1(void); /* generates a random number on [0,1]-real-interval */\n\tdouble real2(void); /* generates a random number on [0,1)-real-interval */\n\tdouble real3(void); /* generates a random number on (0,1)-real-interval */\n\tdouble res53(void); /* generates a random number on [0,1) with 53-bit resolution*/\n\n\tdouble rand_double(void); /* generates a random number on [0,1) with IEEE 64-bit double precision */\n\n\tconst tTJSMersenneTwisterData & GetData() const { return *this; }\n\t\t/* retrieve data */\n\tvoid SetData(const tTJSMersenneTwisterData & rhs);\n\t\t/* set data */\n};\n\n\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsMath.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Math class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsMath.h\"\n#define _USE_MATH_DEFINES\n#include \"math.h\"\n#include \"time.h\"\n\n#ifdef __WIN32__\n#ifndef TJS_NO_MASK_MATHERR\n\t#include <float.h>\n#endif\n#ifdef _MSC_VER\n#define _USERENTRY\n#endif\n#endif\n\n//---------------------------------------------------------------------------\n// matherr and matherrl function\n//---------------------------------------------------------------------------\n// these functions invalidate the mathmarical error\n// (other exceptions, like divide-by-zero error, are not to be caught here)\n#if defined(__WIN32__) && !defined(__GNUC__)\n#ifndef TJS_NO_MASK_MATHERR\nint _USERENTRY _matherr(struct _exception *e)\n{\n\treturn 1;\n}\nint _USERENTRY _matherrl(struct _exception *e)\n{\n\treturn 1;\n}\n#endif\n#endif\n//---------------------------------------------------------------------------\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSXorshift\n//---------------------------------------------------------------------------\n// generates random number using Xorshift\nclass tTJSXorshift {\npublic:\n\tstatic void init(tjs_uint32 seed)\n\t{\n\t\tfor (tjs_uint32 i = 0; i < 4; ++i) {\n\t\t\tseeds[i] = seed = 1812433253 * (seed ^ (seed >> 30)) + i;\n\t\t}\n\t}\n\n\t// generates a random number in the range [0,1)\n\tstatic tTVReal random_real()\n\t{\n\t\tTJSSetFPUE();\n\t\treturn (tTVReal)((tTVReal)random() / ((tTVReal)MAX + 1));\n\t}\n\nprivate:\n\tstatic tjs_uint32 seeds[4];\n\tconst static tjs_uint32 MAX = (2LL << 31) - 1;\n\n\tstatic tjs_uint32 random()\n\t{\n\t\ttjs_uint32 t = seeds[0] ^ (seeds[0] << 11);\n\t\tseeds[0] = seeds[1];\n\t\tseeds[1] = seeds[2];\n\t\tseeds[2] = seeds[3];\n\t\tseeds[3] = (seeds[3] ^ (seeds[3] >> 19)) ^ (t ^ (t >> 8));\n\t\treturn seeds[3];\n\t}\n};\n\ntjs_uint32 tTJSXorshift::seeds[4] = { 123456789, 362436069, 521288629, 88675123 };\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Math : TJS Native Class : Math\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Math::ClassID = (tjs_uint32)-1;\ntTJSNC_Math::tTJSNC_Math() :\n\ttTJSNativeClass(TJS_W(\"Math\"))\n{\n\t// constructor\n\ttime_t time_num;\n\ttime(&time_num);\n\ttTJSXorshift::init((tjs_uint32)time_num);\n\n\t/*\n\t\tTJS2 cannot promise that the sequence of generated random numbers are\n\t\tunique.\n\t\tsince Math.RandomGenerator provides Mersenne Twister high-quality random\n\t\tgenerator.\n\t*/\n\n\tTJSSetFPUE();\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/Math)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/ Math)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Math)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/abs)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result=fabs(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/abs)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/acos)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = acos(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/acos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/asin)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = asin(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/asin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/atan)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = atan(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/atan)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/atan2)\n{\n\tif(numparams<2) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = atan2(param[0]->AsReal(), param[1]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/atan2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/ceil)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ceil(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/ceil)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exp)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = exp(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/exp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/floor)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = floor(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/floor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/log)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = log(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/log)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/pow)\n{\n\tif(numparams<2) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = pow(param[0]->AsReal(), param[1]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/pow)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/max)\n{\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\n\t\ttjs_real r;\n\t\t*(tjs_uint64*)&r = TJS_IEEE_D_N_INF;\n\t\tfor(tjs_int i = 0; i < numparams; ++i)\n\t\t{\n\t\t\ttTVReal v = param[i]->AsReal();\n\t\t\ttjs_uint64 *ui64 = (tjs_uint64*)&v;\n\t\t\tif(TJS_IEEE_D_IS_NaN(*ui64))\n\t\t\t{\n\t\t\t\ttjs_real d;\n\t\t\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_NaN;\n\t\t\t\t*result = d;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t\telse if(*ui64 == 0)\n\t\t\t{\n\t\t\t\t// v is positive-zero\n\t\t\t\t// check r is negative\n\t\t\t\tif(TJS_IEEE_D_GET_SIGN(*(tjs_uint64*)(&r))) // true if negative\n\t\t\t\t{\n\t\t\t\t\t// r is negative and v is positive-zero\n\t\t\t\t\tr = v;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(r < v)\n\t\t\t{\n\t\t\t\tr = v;\n\t\t\t}\n\t\t}\n\n\t\t*result = r;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/max)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/min)\n{\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\n\t\ttjs_real r;\n\t\t*(tjs_uint64*)&r = TJS_IEEE_D_P_INF;\n\t\tfor(tjs_int i = 0; i < numparams; ++i)\n\t\t{\n\t\t\ttTVReal v = param[i]->AsReal();\n\t\t\ttjs_uint64 *ui64 = (tjs_uint64*)&v;\n\t\t\tif(TJS_IEEE_D_IS_NaN(*ui64))\n\t\t\t{\n\t\t\t\ttjs_real d;\n\t\t\t\t*(tjs_uint64*)&d = TJS_IEEE_D_P_NaN;\n\t\t\t\t*result = d;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t\telse if(*ui64 == (0|TJS_IEEE_D_SIGN_MASK) )\n\t\t\t{\n\t\t\t\t// v is nagative-zero\n\t\t\t\t// note that 0|TJS_IEEE_D_SIGN_MASK is a presentation value of nagative-zero.\n\t\t\t\t// check r is positive\n\t\t\t\tif(! TJS_IEEE_D_GET_SIGN(*(tjs_uint64*)(&r))) // false if positive\n\t\t\t\t{\n\t\t\t\t\t// v is negative-zero and r is positive\n\t\t\t\t\tr = v;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(v < r)\n\t\t\t{\n\t\t\t\tr = v;\n\t\t\t}\n\t\t}\n\n\t\t*result = r;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/min)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/random)\n{\n\tif(result)\n\t{\n\t\t*result = tTJSXorshift::random_real();\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/random)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/round)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ::floor(param[0]->AsReal() + 0.5f);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/round)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/sin)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ::sin(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/sin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/cos)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ::cos(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/cos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/sqrt)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ::sqrt(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/sqrt)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/tan)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result)\n\t{\n\t\tTJSSetFPUE();\n\t\t*result = ::tan(param[0]->AsReal());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/tan)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(E)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_E;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(E)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(LOG2E)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_LOG2E;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(LOG2E)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(LOG10E)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_LOG10E;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(LOG10E)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(LN10)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_LN10;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(LN10)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(LN2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_LN2;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(LN2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(PI)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_PI;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(PI)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(SQRT1_2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (M_SQRT2/2);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(SQRT1_2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(SQRT2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = M_SQRT2;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(SQRT2)\n//---------------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n} // tTJSNC_Math::tTJSNC_Math()\n//---------------------------------------------------------------------------\n}  // namespace TJS\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsMath.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS Math class implementation\n//---------------------------------------------------------------------------\n#ifndef tjsMathH\n#define tjsMathH\n\n#include \"tjsNative.h\"\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\nclass tTJSNC_Math : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Math();\nprivate:\n\tstatic tjs_uint32 ClassID;\n\n};\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsMessage.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// message management\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsMessage.h\"\n#include \"tjsHashSearch.h\"\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// tTJSMessageMapper class\n//---------------------------------------------------------------------------\nclass tTJSMessageMapper\n{\n\ttTJSHashTable<ttstr, tTJSMessageHolder*> Hash;\n\ttjs_uint RefCount;\n\npublic:\n\ttTJSMessageMapper() {;}\n\t~tTJSMessageMapper() {;}\n\n\tvoid Register(const tjs_char *name, tTJSMessageHolder *holder)\n\t{\n\t\tHash.Add(ttstr(name), holder);\n\t}\n\n\tvoid Unregister(const tjs_char *name)\n\t{\n\t\tHash.Delete(ttstr(name));\n\t}\n\n\tbool AssignMessage(const tjs_char *name, const tjs_char *newmsg)\n\t{\n\t\ttTJSMessageHolder **holder = Hash.Find(ttstr(name));\n\t\tif(holder)\n\t\t{\n\t\t\t(*holder)->AssignMessage(newmsg);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tbool Get(const tjs_char *name, ttstr &str)\n\t{\n\t\ttTJSMessageHolder **holder = Hash.Find(ttstr(name));\n\t\tif(holder)\n\t\t{\n\t\t\tstr = (const tjs_char *)(**holder);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tttstr CreateMessageMapString();\n\n} static * TJSMessageMapper = NULL;\nstatic int TJSMessageMapperRefCount = 0;\n//---------------------------------------------------------------------------\nttstr tTJSMessageMapper::CreateMessageMapString()\n{\n\tttstr script;\n\ttTJSHashTable<ttstr, tTJSMessageHolder*>::tIterator i;\n\tfor(i = Hash.GetLast(); !i.IsNull(); i--)\n\t{\n\t\tttstr name = i.GetKey();\n\t\ttTJSMessageHolder *holder = i.GetValue();\n\t\tscript += TJS_W(\"\\tr(\\\"\");\n\t\tscript += name.EscapeC();\n\t\tscript += TJS_W(\"\\\", \\\"\");\n\t\tscript += ttstr((const tjs_char *)(*holder)).EscapeC();\n#ifdef TJS_TEXT_OUT_CRLF\n\t\tscript += TJS_W(\"\\\");\\r\\n\");\n#else\n\t\tscript += TJS_W(\"\\\");\\n\");\n#endif\n\t}\n\treturn script;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJSAddRefMessageMapper()\n{\n\tif(TJSMessageMapper)\n\t{\n\t\tTJSMessageMapperRefCount++;\n\t}\n\telse\n\t{\n\t\tTJSMessageMapper = new tTJSMessageMapper;\n\t\tTJSMessageMapperRefCount = 1;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSReleaseMessageMapper()\n{\n\tif(TJSMessageMapper)\n\t{\n\t\tTJSMessageMapperRefCount--;\n\t\tif(TJSMessageMapperRefCount == 0)\n\t\t{\n\t\t\tdelete TJSMessageMapper;\n\t\t\tTJSMessageMapper = NULL;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSRegisterMessageMap(const tjs_char *name, tTJSMessageHolder *holder)\n{\n\tif(TJSMessageMapper) TJSMessageMapper->Register(name, holder);\n}\n//---------------------------------------------------------------------------\nvoid TJSUnregisterMessageMap(const tjs_char *name)\n{\n\tif(TJSMessageMapper) TJSMessageMapper->Unregister(name);\n}\n//---------------------------------------------------------------------------\nbool TJSAssignMessage(const tjs_char *name, const tjs_char *newmsg)\n{\n\tif(TJSMessageMapper) return TJSMessageMapper->AssignMessage(name, newmsg);\n\treturn false;\n}\n//---------------------------------------------------------------------------\nttstr TJSCreateMessageMapString()\n{\n\tif(TJSMessageMapper) return TJSMessageMapper->CreateMessageMapString();\n\treturn TJS_W(\"\");\n}\n//---------------------------------------------------------------------------\nttstr TJSGetMessageMapMessage(const tjs_char *name)\n{\n\tif(TJSMessageMapper)\n\t{\n\t\tttstr ret;\n\t\tif(TJSMessageMapper->Get(name, ret)) return ret;\n\t\treturn ttstr();\n\t}\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n}\n\n"
  },
  {
    "path": "src/core/tjs2/tjsMessage.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// message management\n//---------------------------------------------------------------------------\n#ifndef tjsMessageH\n#define tjsMessageH\n\n#include \"tjsVariant.h\"\n#include \"tjsString.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// this class maps message and its object\n//---------------------------------------------------------------------------\nextern void TJSAddRefMessageMapper();\nextern void TJSReleaseMessageMapper();\nclass tTJSMessageHolder;\nextern void TJSRegisterMessageMap(const tjs_char *name, tTJSMessageHolder *holder);\nextern void TJSUnregisterMessageMap(const tjs_char *name);\nextern bool TJSAssignMessage(const tjs_char *name, const tjs_char *newmsg);\nextern ttstr TJSCreateMessageMapString();\nTJS_EXP_FUNC_DEF(ttstr, TJSGetMessageMapMessage, (const tjs_char *name));\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// a simple class to hold message\n// this holder should be created as a static object\n//---------------------------------------------------------------------------\nclass tTJSMessageHolder\n{\n\tconst tjs_char *Name;\n\tconst tjs_char *DefaultMessage;\n\ttjs_char *AssignedMessage;\n\npublic:\n\ttTJSMessageHolder(const tjs_char *name, const tjs_char *defmsg, bool regist = true)\n\t{\n\t\t/* \"name\" and \"defmsg\" must point static area */\n\t\tAssignedMessage = NULL;\n\t\tName = NULL;\n\t\tDefaultMessage = defmsg;\n\t\tTJSAddRefMessageMapper();\n\t\tif(regist)\n\t\t{\n\t\t\tName = name;\n\t\t\tTJSRegisterMessageMap(Name, this);\n\t\t}\n\t}\n\n\t~tTJSMessageHolder()\n\t{\n\t\tif(Name) TJSUnregisterMessageMap(Name);\n\t\tif(AssignedMessage) delete [] AssignedMessage, AssignedMessage = NULL;\n\t\tTJSReleaseMessageMapper();\n\t}\n\n\tvoid AssignMessage(const tjs_char *msg)\n\t{\n\t\tif(AssignedMessage) delete [] AssignedMessage, AssignedMessage = NULL;\n\t\tAssignedMessage = new tjs_char[TJS_strlen(msg) + 1];\n\t\tTJS_strcpy(AssignedMessage, msg);\n\t}\n\n\toperator const tjs_char * ()\n\t\t{ return AssignedMessage?AssignedMessage:DefaultMessage; }\n\t\t/* this function may called after destruction */\n};\n//---------------------------------------------------------------------------\n}\nextern ttstr TVPGetMessageByLocale(const std::string &key);\n#endif\n\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsNamespace.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Name Space Processing\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsInterface.h\"\n#include \"tjsNamespace.h\"\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSLocalSymbolList\n//---------------------------------------------------------------------------\n/*\n\tsymbol list class for compile-time local variables look-up\n*/\ntTJSLocalSymbolList::tTJSLocalSymbolList(tjs_int LocalCountStart)\n{\n\tthis->LocalCountStart=LocalCountStart;\n\tStartWriteAddr = NULL;\n\tCountWriteAddr = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSLocalSymbolList::~tTJSLocalSymbolList(void)\n{\n\tif(StartWriteAddr)\n\t{\n\t\t*StartWriteAddr = LocalCountStart;\n\t}\n\n\tif(CountWriteAddr)\n\t{\n\t\ttjs_int num = GetCount();\n\t\t*CountWriteAddr = num;\n\t}\n\n\tsize_t i;\n\tfor(i=0;i<List.size();i++)\n\t{\n\t\tif(List[i]) delete [] List[i]->Name;\n\t\tdelete List[i];\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalSymbolList::SetWriteAddr(tjs_int *StartWriteAddr, tjs_int *CountWriteAddr)\n{\n\tthis->StartWriteAddr = StartWriteAddr;\n\tthis->CountWriteAddr = CountWriteAddr;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalSymbolList::Add(const tjs_char * name)\n{\n\tif(Find(name)==-1)\n\t{\n\t\ttTJSLocalSymbol *newsym=new tTJSLocalSymbol;\n\t\tnewsym->Name=new tjs_char[TJS_strlen(name)+1];\n\t\tTJS_strcpy(newsym->Name,name);\n\t\tsize_t i;\n\t\tfor(i=0;i<List.size();i++)\n\t\t{\n\t\t\ttTJSLocalSymbol *sym=List[i];\n\t\t\tif(sym==NULL)\n\t\t\t{\n\t\t\t\tList[i]=newsym;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tList.push_back(newsym);\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSLocalSymbolList::Find(const tjs_char *name)\n{\n\tsize_t i;\n\tfor(i=0;i<List.size();i++)\n\t{\n\t\ttTJSLocalSymbol *sym=List[i];\n\t\tif(sym)\n\t\t{\n\t\t\tif(!TJS_strcmp(sym->Name,name))\n\t\t\t\treturn (tjs_int)i;\n\t\t}\n\t}\n\treturn -1;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalSymbolList::Remove(const tjs_char *name)\n{\n\ttjs_int idx=Find(name);\n\tif(idx!=-1)\n\t{\n\t\ttTJSLocalSymbol *sym=List[idx];\n\t\tdelete [] sym->Name;\n\t\tdelete sym;\n\t\tList[idx]=NULL;  // un-used\n\t}\n}\n//---------------------------------------------------------------------------\n// tTJSLocalNamespace\n//---------------------------------------------------------------------------\n/*\n a class for compile-time local variables look-up\n*/\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint time_ns_Push = 0;\ntjs_uint time_ns_Pop = 0;\ntjs_uint time_ns_Find = 0;\ntjs_uint time_ns_Add = 0;\ntjs_uint time_ns_Remove = 0;\ntjs_uint time_ns_Commit = 0;\n#endif\n\n//---------------------------------------------------------------------------\ntTJSLocalNamespace::tTJSLocalNamespace(void)\n{\n\tMaxCount=0;\n\tCurrentCount=0;\n\tMaxCountWriteAddr = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSLocalNamespace::~tTJSLocalNamespace(void)\n{\n\tif(MaxCountWriteAddr)\n\t{\n\t\t*MaxCountWriteAddr = MaxCount;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::SetMaxCountWriteAddr(tjs_int * MaxCountWriteAddr)\n{\n\tthis->MaxCountWriteAddr = MaxCountWriteAddr;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSLocalNamespace::GetCount(void)\n{\n\ttjs_int count=0;\n\tsize_t i;\n\tfor(i=0;i<Levels.size();i++)\n\t{\n\t\ttTJSLocalSymbolList * list= Levels[i];\n\t\tcount+= list->GetCount();\n\t}\n\treturn count;\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Push()\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Push);\n#endif\n\tCurrentCount=GetCount();\n\ttTJSLocalSymbolList * list=new tTJSLocalSymbolList(CurrentCount);\n\tLevels.push_back(list);\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Pop(void)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Pop);\n#endif\n\ttTJSLocalSymbolList * list= Levels[Levels.size()-1];\n\n\tCommit();\n\n\tCurrentCount= list->GetLocalCountStart();\n\n\tLevels.pop_back();\n\n\tdelete list;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSLocalNamespace::Find(const tjs_char *name)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Find);\n#endif\n\t// search \"name\"\n\ttjs_int i;  /* signed */\n\tfor(i=(tjs_int)(Levels.size()-1); i>=0; i--)\n\t{\n\t\ttTJSLocalSymbolList* list = Levels[i];\n\t\ttjs_int lidx = list->Find(name);\n\t\tif(lidx!=-1)\n\t\t{\n\t\t\tlidx += list->GetLocalCountStart();\n\t\t\treturn lidx;\n\t\t}\n\t}\n\treturn -1;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSLocalNamespace::GetLevel(void)\n{\n\t// gets current namespace depth\n\treturn (tjs_int)Levels.size();\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Add(const tjs_char * name)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Add);\n#endif\n\t// adds \"name\" to namespace\n\ttTJSLocalSymbolList * top = GetTopSymbolList();\n\tif(!top) return; // this is global\n\ttop->Add(name);\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Remove(const tjs_char *name)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Remove);\n#endif\n\ttjs_int i;\n\tfor(i=(tjs_int)(Levels.size()-1); i>=0; i--)\n\t{\n\t\ttTJSLocalSymbolList* list = Levels[i];\n\t\ttjs_int lidx = list->Find(name);\n\t\tif(lidx!=-1)\n\t\t{\n\t\t\tlist->Remove(name);\n\t\t\treturn;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Commit(void)\n{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\ttTJSTimeProfiler prof(time_ns_Commit);\n#endif\n\t// compute MaxCount\n\ttjs_int i;\n\ttjs_int count = 0;\n\tfor(i=(tjs_int)(Levels.size()-1); i>=0; i--)\n\t{\n\t\ttTJSLocalSymbolList* list = Levels[i];\n\t\tcount += list->GetCount();\n\t}\n\tif(MaxCount < count) MaxCount = count;\n}\n//---------------------------------------------------------------------------\ntTJSLocalSymbolList * tTJSLocalNamespace::GetTopSymbolList()\n{\n\t// returns top symbol list\n\tif(Levels.size() == 0) return NULL;\n\treturn (tTJSLocalSymbolList *)(Levels[Levels.size()-1]);\n}\n//---------------------------------------------------------------------------\nvoid tTJSLocalNamespace::Clear(void)\n{\n\t// all clear\n\twhile(Levels.size()) Pop();\n}\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsNamespace.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Name Space Processing\n//---------------------------------------------------------------------------\n#ifndef tjsNamespaceH\n#define tjsNamespaceH\n\n#include \"tjsVariant.h\"\n#include <vector>\nusing namespace std;\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nclass iTJSDispatch;\n//---------------------------------------------------------------------------\n// tTJSLocalSymbolList\n//---------------------------------------------------------------------------\nstruct tTJSLocalSymbol\n{\n\ttjs_char *Name;\n};\n//---------------------------------------------------------------------------\nclass tTJSLocalSymbolList\n{\n\tvector<tTJSLocalSymbol *> List;\n\ttjs_int LocalCountStart;\n\ttjs_int *StartWriteAddr;\n\ttjs_int *CountWriteAddr;\n\npublic:\n\ttTJSLocalSymbolList(tjs_int LocalCount);\n\t~tTJSLocalSymbolList(void);\n\n\tvoid SetWriteAddr(tjs_int *StartWriteAddr, tjs_int *CountWriteAddr);\n\n\tvoid Add(const tjs_char * name);\n\ttjs_int Find(const tjs_char * name);\n\tvoid Remove(const tjs_char * name);\n\n\ttjs_int GetCount(void) const  { return (tjs_int)List.size(); }\n\t\t// this count includes variable holder that is marked as un-used\n\ttjs_int GetLocalCountStart(void) const  { return LocalCountStart; }\n\n\ttjs_int * GetStartWriteAddr(void) const { return StartWriteAddr; }\n\ttjs_int * GetCountWriteAddr(void) const { return CountWriteAddr; }\n};\n//---------------------------------------------------------------------------\n// tTJSLocalNamespace\n//---------------------------------------------------------------------------\nclass tTJSLocalNamespace\n{\n\tvector<tTJSLocalSymbolList *> Levels;\n\ttjs_int MaxCount; // max count of local variables\n\ttjs_int CurrentCount; // current local variable count\n\ttjs_int * MaxCountWriteAddr;\n\npublic:\n\ttTJSLocalNamespace(void);\n\t~tTJSLocalNamespace(void);\n\n\tvoid SetMaxCountWriteAddr(tjs_int *MaxCountWriteAddr);\n\n\ttjs_int GetCount(void);\n\ttjs_int GetMaxCount(void) const { return MaxCount; }\n\ttjs_int Find(const tjs_char * name);\n\ttjs_int GetLevel(void);\n\tvoid Add(const tjs_char * name);\n\tvoid Remove(const tjs_char *name);\n\tvoid Commit(void);\n\n\ttTJSLocalSymbolList * GetTopSymbolList();\n\n\tvoid Push(void);\n\tvoid Pop(void);\n\n\tvoid Clear(void); // all clear\n};\n//---------------------------------------------------------------------------\n// tTJSLocalNamespaceAutoPushPop\n//---------------------------------------------------------------------------\nclass tTJSLocalNamespaceAutoPushPop\n{\n\ttTJSLocalNamespace *Space;\npublic:\n\ttTJSLocalNamespaceAutoPushPop(tTJSLocalNamespace *space)\n\t{\n\t\tSpace = space;\n\t\tSpace->Push();\n\t}\n\t~tTJSLocalNamespaceAutoPushPop()\n\t{\n\t\tSpace->Pop();\n\t}\n};\n//---------------------------------------------------------------------------\n// tTJSLocalNamespaceAutoClass\n//---------------------------------------------------------------------------\nclass tTJSLocalNamespaceAutoClass\n{\n\t// create namespace if necessary\n\ttTJSLocalNamespace *Space;\n\tbool SpaceCreated;\npublic:\n\ttTJSLocalNamespaceAutoClass(tTJSLocalNamespace *space)\n\t{\n\t\tSpace = space;\n\t\tif(Space == NULL)\n\t\t{\n\t\t\tSpace = new tTJSLocalNamespace;\n\t\t\tSpaceCreated = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tSpaceCreated = false;\n\t\t}\n\t\tSpace->Push();\n\t}\n\n\t~tTJSLocalNamespaceAutoClass()\n\t{\n\t\tSpace->Pop();\n\t\tif(SpaceCreated) delete Space;\n\t}\n\n\ttTJSLocalNamespace * GetNamespace(void){ return Space; }\n};\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsNative.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Support for C++ native class/method/property definitions\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include \"tjsNative.h\"\n#include \"tjsError.h\"\n#include \"tjsGlobalStringMap.h\"\n#include \"tjsDebug.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// NativeClass registration\n//---------------------------------------------------------------------------\nstatic std::vector<ttstr > NativeClassNames;\n//---------------------------------------------------------------------------\ntjs_int32 TJSRegisterNativeClass(const tjs_char *name)\n{\n\tfor(tjs_uint i = 0; i<NativeClassNames.size(); i++)\n\t{\n\t\tif(NativeClassNames[i] == name) return i;\n\t}\n\n\tNativeClassNames.push_back(TJSMapGlobalStringMap(name));\n\n\treturn (tjs_int32)(NativeClassNames.size() -1);\n}\n//---------------------------------------------------------------------------\ntjs_int32 TJSFindNativeClassID(const tjs_char *name)\n{\n\tfor(tjs_uint i = 0; i<NativeClassNames.size(); i++)\n\t{\n\t\tif(NativeClassNames[i] == name) return i;\n\t}\n\n\treturn -1;\n}\n//---------------------------------------------------------------------------\nconst tjs_char * TJSFindNativeClassName(tjs_int32 id)\n{\n\tif(id<0 || id>=(tjs_int32)NativeClassNames.size()) return NULL;\n\treturn NativeClassNames[id].c_str();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClassMethod\n//---------------------------------------------------------------------------\ntTJSNativeClassMethod::tTJSNativeClassMethod(tTJSNativeClassMethodCallback processfunc)\n{\n\tProcess = processfunc;\n\tif(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\ntTJSNativeClassMethod::~tTJSNativeClassMethod()\n{\n\tif(TJSObjectHashMapEnabled()) TJSRemoveObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClassMethod::IsInstanceOf(tjs_uint32 flag,\n\tconst tjs_char *membername,  tjs_uint32 *hint,\n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(!TJS_strcmp(classname, TJS_W(\"Function\"))) return TJS_S_TRUE;\n\t}\n\n\treturn inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNativeClassMethod::FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\ttjs_uint32 *hint, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n{\n\tif(membername) return inherited::FuncCall(flag, membername, hint,\n\t\tresult, numparams, param, objthis);\n\tif(!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\tif(result) result->Clear();\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = Process(result, numparams, param, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n\treturn er;\n}\n//---------------------------------------------------------------------------\ntTJSNativeClassMethod * TJSCreateNativeClassMethod\n\t(tTJSNativeClassMethodCallback callback)\n{\n\treturn new tTJSNativeClassMethod(callback);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClassConstructor\n//---------------------------------------------------------------------------\ntjs_error  TJS_INTF_METHOD\n\ttTJSNativeClassConstructor::FuncCall(tjs_uint32 flag,\n\tconst tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n{\n\tif(membername) return tTJSDispatch::FuncCall(flag, membername, hint,\n\t\tresult, numparams, param, objthis);\n\tif(result) result->Clear();\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = Process(result, numparams, param, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n\treturn er;\n}\n//---------------------------------------------------------------------------\ntTJSNativeClassMethod * TJSCreateNativeClassConstructor\n\t(tTJSNativeClassMethodCallback callback)\n{\n\treturn new tTJSNativeClassConstructor(callback);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClassProperty\n//---------------------------------------------------------------------------\ntTJSNativeClassProperty::tTJSNativeClassProperty(\n\ttTJSNativeClassPropertyGetCallback get,\n\ttTJSNativeClassPropertySetCallback set)\n{\n\tGet = get;\n\tSet = set;\n\tif(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\ntTJSNativeClassProperty::~tTJSNativeClassProperty()\n{\n\tif(TJSObjectHashMapEnabled()) TJSRemoveObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClassProperty::IsInstanceOf(tjs_uint32 flag,\n\tconst tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(!TJS_strcmp(classname, TJS_W(\"Property\"))) return TJS_S_TRUE;\n\t}\n\n\treturn inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClassProperty::PropGet(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint, tTJSVariant *result, iTJSDispatch2 *objthis)\n{\n\tif(membername) return inherited::PropGet(flag, membername, hint,\n\t\tresult, objthis);\n\tif(!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\tif(!result) return TJS_E_FAIL;\n\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = Get(result, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n\n\treturn er;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClassProperty::PropSet(tjs_uint32 flag, const tjs_char *membername,\n\ttjs_uint32 *hint, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(membername) return inherited::PropSet(flag, membername, hint,\n\t\tparam, objthis);\n\tif(!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\tif(!param) return TJS_E_FAIL;\n\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = Set(param, objthis);\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n\n\treturn er;\n}\n//---------------------------------------------------------------------------\ntTJSNativeClassProperty * TJSCreateNativeClassProperty(\n\ttTJSNativeClassPropertyGetCallback get,\n\ttTJSNativeClassPropertySetCallback set)\n{\n\treturn new tTJSNativeClassProperty(get, set);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClass\n//---------------------------------------------------------------------------\ntTJSNativeClass::tTJSNativeClass(const ttstr &name)\n{\n\tCallFinalize = false;\n\tClassName = TJSMapGlobalStringMap(name);\n\n\tif(TJSObjectHashMapEnabled())\n\t\tTJSObjectHashSetType(this, ttstr(TJS_W(\"(native class) \")) + ClassName);\n}\n//---------------------------------------------------------------------------\ntTJSNativeClass::~tTJSNativeClass()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSNativeClass::RegisterNCM(const tjs_char *name, iTJSDispatch2 *dsp,\n\tconst tjs_char *classname, tTJSNativeInstanceType type, tjs_uint32 flags)\n{\n\t// map name via Global String Map\n\tttstr tname = TJSMapGlobalStringMap(ttstr(name));\n\n\t// set object type for debugging\n\tif(TJSObjectHashMapEnabled())\n\t{\n\t\tswitch(type)\n\t\t{\n\t\tcase nitMethod:\n\t\t\tTJSObjectHashSetType(dsp, ttstr(TJS_W(\"(native function) \")) +\n\t\t\t\t\t\t\t\t\t\tclassname + TJS_W(\".\") + name);\n\t\t\tbreak;\n\t\tcase nitProperty:\n\t\t\tTJSObjectHashSetType(dsp, ttstr(TJS_W(\"(native property) \")) +\n\t\t\t\t\t\t\t\t\t\tclassname + TJS_W(\".\") + name);\n\t\t\tbreak;\n\t\t/*\n\t\tcase nitClass:\n\t\t\tThe information is not set here\n\t\t\t(is to be set in tTJSNativeClass::tTJSNativeClass)\n\t\t*/\n        default:\n            break;\n\t\t}\n\t}\n\n\t// add to this\n\ttTJSVariant val;\n\tval = dsp;\n\tif(PropSetByVS((TJS_MEMBERENSURE | TJS_IGNOREPROP) | flags,\n\t\ttname.AsVariantStringNoAddRef(), &val, this) == TJS_E_NOTIMPL)\n\t\tPropSet((TJS_MEMBERENSURE | TJS_IGNOREPROP) | flags,\n\t\t\ttname.c_str(), NULL, &val, this);\n\n\t// release dsp\n\tdsp->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNativeClass::Finalize(void)\n{\n\ttTJSCustomObject::Finalize();\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNativeClass::CreateBaseTJSObject()\n{\n\tif( SuperClass ) {\n\t\treturn new tTJSExtendableObject;\n\t} else {\n\t\treturn new tTJSCustomObject;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClass::FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername) {\n\t\ttjs_error hr = tTJSCustomObject::FuncCall(flag, membername, hint,\n\t\t\tresult, numparams, param, objthis);\n\t\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL ) {\n\t\t\thr = SuperClass->FuncCall( flag, membername, hint, result, numparams, param, objthis );\n\t\t}\n\t\treturn hr;\n\t}\n\n\ttTJSVariant name(ClassName);\n\tobjthis->ClassInstanceInfo(TJS_CII_ADD, 0, &name); // add class name\n\n\t// create base native object\n\tiTJSNativeInstance * nativeptr = CreateNativeInstance();\n\n\t// register native instance information to the object;\n\t// even if \"nativeptr\" is null\n\tobjthis->NativeInstanceSupport(TJS_NIS_REGISTER, _ClassID, &nativeptr);\n\n\t// register members to \"objthis\"\n\n\t// a class to receive member callback from class\n\tclass tCallback : public tTJSDispatch\n\t{\n\tpublic:\n\t\tiTJSDispatch2 * Dest; // destination object\n\t\ttjs_error TJS_INTF_METHOD FuncCall(\n\t\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *objthis)\n\t\t{\n\t\t\t// *param[0] = name   *param[1] = flags   *param[2] = value\n\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\tif(!(flags & TJS_STATICMEMBER))\n\t\t\t{\n\t\t\t\ttTJSVariant val = *param[2];\n\t\t\t\tif(val.Type() == tvtObject)\n\t\t\t\t{\n\t\t\t\t\t// change object's objthis if the object's objthis is null\n\t\t\t\t\tif(val.AsObjectThisNoAddRef() == NULL)\n\t\t\t\t\t\tval.ChangeClosureObjThis(Dest);\n\t\t\t\t}\n\n\t\t\t\tif(Dest->PropSetByVS(TJS_MEMBERENSURE|TJS_IGNOREPROP|flags,\n\t\t\t\t\tparam[0]->AsStringNoAddRef(), &val, Dest) == TJS_E_NOTIMPL)\n\t\t\t\t\tDest->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|flags,\n\t\t\t\t\tparam[0]->GetString(), NULL, &val, Dest);\n\t\t\t}\n\t\t\tif(result) *result = (tjs_int)(1); // returns true\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t};\n\n\ttCallback callback;\n\tcallback.Dest = objthis;\n\n\t// enumerate members\n    tTJSVariantClosure clo(&callback, (iTJSDispatch2*)NULL);\n\tEnumMembers(TJS_IGNOREPROP, &clo, this);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClass::CreateNew(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\t// CreateNew\n\tiTJSDispatch2 *superinst = NULL;\n\tif( SuperClass != NULL && membername == NULL ) {\n\t\ttjs_error hr = SuperClass->CreateNew( flag, membername, hint, &superinst, numparams, param, objthis );\n\t\tif(TJS_FAILED(hr)) {\n\t\t\tsuperinst = NULL;\n\t\t}\n\t}\n\n\tiTJSDispatch2 *dsp = CreateBaseTJSObject();\n\n\ttjs_error hr;\n\ttry\n\t{\n\t\t// set object type for debugging\n\t\tif(TJSObjectHashMapEnabled())\n\t\t\tTJSObjectHashSetType(dsp, TJS_W(\"instance of class \") + ClassName);\n\n\t\t// instance initialization\n\t\thr = FuncCall(0, NULL, NULL, NULL, 0, NULL, dsp); // add member to dsp\n\n\t\tif(TJS_FAILED(hr)) return hr;\n\n\t\tif( superinst != NULL ) {\n\t\t\ttTJSVariant param(superinst,superinst);\n\t\t\tdsp->ClassInstanceInfo( TJS_CII_SET_SUPRECLASS, 0, &param );\n\t\t\tsuperinst->Release();\n\t\t\tsuperinst = NULL;\n\t\t}\n\n\t\thr = FuncCall(0, ClassName.c_str(), ClassName.GetHint(), NULL, numparams, param, dsp);\n\t\t\t// call the constructor\n\t\tif(hr == TJS_E_MEMBERNOTFOUND) hr = TJS_S_OK;\n\t\t\t// missing constructor is OK ( is this ugly ? )\n\t}\n\tcatch(...)\n\t{\n\t\tdsp->Release();\n\t\tif( superinst ) superinst->Release();\n\t\tthrow;\n\t}\n\n\tif(TJS_SUCCEEDED(hr)) {\n\t\t*result = dsp;\n\t} else if( superinst ) {\n\t\tsuperinst->Release();\n\t}\n\treturn hr;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNativeClass::IsInstanceOf(tjs_uint32 flag,\n\tconst tjs_char *membername, tjs_uint32 *hint, const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(!TJS_strcmp(classname, TJS_W(\"Class\"))) return TJS_S_TRUE;\n\t\tif(!TJS_strcmp(classname, ClassName.c_str())) return TJS_S_TRUE;\n\t}\n\n\treturn inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeFunction\n//---------------------------------------------------------------------------\ntTJSNativeFunction::tTJSNativeFunction(const tjs_char *name)\n{\n\tif(TJSObjectHashMapEnabled())\n\t{\n\t\tTJSAddObjectHashRecord(this);\n\t\tif(name)\n\t\t\tTJSObjectHashSetType(this, ttstr(TJS_W(\"(native function) \")) + name);\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSNativeFunction::~tTJSNativeFunction()\n{\n\tif(TJSObjectHashMapEnabled()) TJSRemoveObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNativeFunction::FuncCall(\n\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result,\n\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(membername)\n\t{\n\t\treturn inherited::FuncCall(flag, membername, hint, result,\n\t\t\tnumparams, param, objthis);\n\t}\n\treturn Process(result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNativeFunction::IsInstanceOf(\n\ttjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(!TJS_strcmp(classname, TJS_W(\"Function\"))) return TJS_S_TRUE;\n\t}\n\n\treturn inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsNative.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Support for C++ native class/method/property definitions\n//---------------------------------------------------------------------------\n#ifndef tjsNativeH\n#define tjsNativeH\n\n#include \"tjsObjectExtendable.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_int32, TJSRegisterNativeClass, (const tjs_char *name));\nTJS_EXP_FUNC_DEF(tjs_int32, TJSFindNativeClassID, (const tjs_char *name));\nTJS_EXP_FUNC_DEF(const tjs_char *, TJSFindNativeClassName, (tjs_int32 id));\n//---------------------------------------------------------------------------\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSNativeInstanceType\n//---------------------------------------------------------------------------\nenum tTJSNativeInstanceType\n{\n\tnitClass,\n\tnitMethod,\n\tnitProperty\n};\n//---------------------------------------------------------------------------\n\n\n\n/*]*/\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSNativeInstance\n//---------------------------------------------------------------------------\nclass tTJSNativeInstance : public iTJSNativeInstance\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD Construct(tjs_int numparams,\n\t\ttTJSVariant **param, iTJSDispatch2 *tjs_obj) {return TJS_S_OK;}\n\tvirtual void TJS_INTF_METHOD Invalidate() {;}\n\tvirtual void TJS_INTF_METHOD Destruct() { delete this; }\n\tvirtual ~tTJSNativeInstance() {;};\n};\n//---------------------------------------------------------------------------\n\n\n\n/*]*/\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSNativeClassMethod\n//---------------------------------------------------------------------------\ntypedef tjs_error (TJS_INTF_METHOD *tTJSNativeClassMethodCallback)\n\t(tTJSVariant *result,tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis);\n/*]*/\n#ifdef __TP_STUB_H__\n/*[*/\nclass tTJSNativeClassMethod : public iTJSDispatch2 { };\n/*]*/\n#else\nclass tTJSNativeClassMethod;\n#endif\n/*[*/\n\n\n/*]*/\nTJS_EXP_FUNC_DEF(tTJSNativeClassMethod *, TJSCreateNativeClassMethod,\n\t(tTJSNativeClassMethodCallback callback));\n//---------------------------------------------------------------------------\nclass tTJSNativeClassMethod : public tTJSDispatch\n{\n\ttypedef tTJSDispatch inherited;\n\nprotected:\n\ttTJSNativeClassMethodCallback Process;\npublic:\n\n\ttTJSNativeClassMethod(tTJSNativeClassMethodCallback processfunc);\n\t~tTJSNativeClassMethod();\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\ttjs_error  TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClassConstructor\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSNativeClassMethod *, TJSCreateNativeClassConstructor,\n\t(tTJSNativeClassMethodCallback callback));\n//---------------------------------------------------------------------------\nclass tTJSNativeClassConstructor : public tTJSNativeClassMethod\n{\n\ttypedef tTJSNativeClassMethod inherited;\npublic:\n\ttTJSNativeClassConstructor(tTJSNativeClassMethodCallback processfunc)\n\t\t: tTJSNativeClassMethod(processfunc) {;}\n\n\ttjs_error  TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n};\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSNativeClassProperty\n//---------------------------------------------------------------------------\ntypedef tjs_error (TJS_INTF_METHOD *tTJSNativeClassPropertyGetCallback)\n\t(tTJSVariant *result, iTJSDispatch2 *objthis);\ntypedef tjs_error (TJS_INTF_METHOD *tTJSNativeClassPropertySetCallback)\n\t(const tTJSVariant *param, iTJSDispatch2 *objthis);\n/*]*/\n#ifdef __TP_STUB_H__\n/*[*/\nclass tTJSNativeClassProperty : public iTJSDispatch2 { };\n/*]*/\n#else\nclass tTJSNativeClassProperty;\n#endif\n/*[*/\n\n/*]*/\nTJS_EXP_FUNC_DEF(tTJSNativeClassProperty *, TJSCreateNativeClassProperty,\n\t(tTJSNativeClassPropertyGetCallback get,\n\t tTJSNativeClassPropertySetCallback set));\n//---------------------------------------------------------------------------\nclass tTJSNativeClassProperty : public tTJSDispatch\n{\n\ttypedef tTJSDispatch inherited;\n\nprotected:\n\ttTJSNativeClassPropertyGetCallback Get;\n\ttTJSNativeClassPropertySetCallback Set;\npublic:\n\n\ttTJSNativeClassProperty(tTJSNativeClassPropertyGetCallback get,\n\t\ttTJSNativeClassPropertySetCallback set);\n\t~tTJSNativeClassProperty();\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis);\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNativeClass\n//---------------------------------------------------------------------------\nclass tTJSNativeClass : public tTJSExtendableObject\n{\n\ttypedef tTJSExtendableObject inherited;\n\npublic:\n\ttTJSNativeClass(const ttstr &name);\n\tvirtual ~tTJSNativeClass();\n\n\tvoid RegisterNCM(const tjs_char *name,\n\t\tiTJSDispatch2 *dsp,\n\t\tconst tjs_char *classname,\n\t\ttTJSNativeInstanceType type,\n\t\ttjs_uint32 flags = 0);\n\nprotected:\n\ttjs_int32 _ClassID;\n\tttstr ClassName;\n\tvoid Finalize(void);\n\n\tvirtual iTJSNativeInstance *CreateNativeInstance()  {return NULL;}\n\n\tvirtual iTJSDispatch2 *CreateBaseTJSObject();\n\nprivate:\n\npublic:\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\t iTJSDispatch2 **result,\n\t\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\t const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\n\tconst ttstr & GetClassName() const { return ClassName; }\n\n\tvoid SetClassID(tjs_int32 classid) { _ClassID = classid; }\n};\n//---------------------------------------------------------------------------\ninline TJS_EXP_FUNC_DEF(void, TJSNativeClassRegisterNCM, (\n\t\ttTJSNativeClass *cls,\n\t\tconst tjs_char *name,\n\t\tiTJSDispatch2 *dsp,\n\t\tconst tjs_char *classname,\n\t\ttTJSNativeInstanceType type,\n\t\ttjs_uint32 flags = 0))\n{\n\tcls->RegisterNCM(name, dsp, classname, type, flags);\n}\n//---------------------------------------------------------------------------\ninline TJS_EXP_FUNC_DEF(void, TJSNativeClassSetClassID, (\n\t\ttTJSNativeClass *cls,\n\t\ttjs_int32 classid))\n{\n\tcls->SetClassID(classid);\n}\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSNativeClassForPlugin : service class for plugins\n//---------------------------------------------------------------------------\ntypedef iTJSNativeInstance * (TJS_INTF_METHOD *tTJSCreateNativeInstance)();\n/*]*/\n#ifdef __TP_STUB_H__\n/*[*/\nclass tTJSNativeClass : public iTJSDispatch2 { };\nclass tTJSNativeClassForPlugin : public tTJSNativeClass { };\n/*]*/\n#else\nclass tTJSNativeClassForPlugin;\n#endif\n/*[*/\n\n/*]*/\n//---------------------------------------------------------------------------\n// This class is for nasty workaround of inter-compiler compatibility\nclass tTJSNativeClassForPlugin : public tTJSNativeClass\n{\n\ttTJSCreateNativeInstance procCreateNativeInstance;\npublic:\n\ttTJSNativeClassForPlugin(const ttstr &name,\n\t\ttTJSCreateNativeInstance proc) :\n\t\t\tprocCreateNativeInstance(proc), tTJSNativeClass(name)\n\t{\n\t\t;\n\t}\n\nprotected:\n\tiTJSNativeInstance *CreateNativeInstance()\n\t\t{return procCreateNativeInstance();}\n};\n//---------------------------------------------------------------------------\ninline TJS_EXP_FUNC_DEF(tTJSNativeClassForPlugin *, TJSCreateNativeClassForPlugin,\n\t(const ttstr &name, tTJSCreateNativeInstance createinstance))\n{\n\treturn new tTJSNativeClassForPlugin(name, createinstance);\n}\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// following macros are to be written in the constructor of child class\n// to define native methods/properties.\n/*]*/\n#ifdef __TP_STUB_H__\n/*[*/\n#define TJS_NCM_REG_THIS classobj\n#define TJS_NATIVE_SET_ClassID TJS_NATIVE_CLASSID_NAME = TJS_NCM_CLASSID;\n/*]*/\n#else\n#define TJS_NCM_REG_THIS  this\n#define TJS_NATIVE_SET_ClassID ClassID = TJS_NCM_CLASSID;\n#define TJS_NATIVE_CLASSID_NAME TJS_NCM_CLASSID\n#endif\n/*[*/\n\n#define TJS_GET_NATIVE_INSTANCE(varname, typename) \\\n\t\tif(!objthis) return TJS_E_NATIVECLASSCRASH; \\\n\t\ttypename *varname; \\\n\t\t{ \\\n\t\t\ttjs_error hr; \\\n\t\t\thr = objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \\\n\t\t\t\t\tTJS_NATIVE_CLASSID_NAME, (iTJSNativeInstance**)&varname); \\\n\t\t\tif(TJS_FAILED(hr)) return TJS_E_NATIVECLASSCRASH; \\\n\t\t}\n\n#define TJS_GET_NATIVE_INSTANCE_OUTER(classname, varname, typename) \\\n\t\tif(!objthis) return TJS_E_NATIVECLASSCRASH; \\\n\t\ttypename *varname; \\\n\t\t{ \\\n\t\t\ttjs_error hr; \\\n\t\t\thr = objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \\\n\t\t\t\t\tclassname::ClassID, (iTJSNativeInstance**)&varname); \\\n\t\t\tif(TJS_FAILED(hr)) return TJS_E_NATIVECLASSCRASH; \\\n\t\t}\n\n#define TJS_BEGIN_NATIVE_MEMBERS(classname) \\\n\t{ \\\n\t\tstatic const tjs_char *__classname = TJS_W(#classname); \\\n\t\tstatic tjs_int32 TJS_NCM_CLASSID = \\\n\t\t\tTJSRegisterNativeClass(__classname); \\\n\t\tTJSNativeClassSetClassID(TJS_NCM_REG_THIS, TJS_NCM_CLASSID); \\\n\t\tTJS_NATIVE_SET_ClassID\n\n#define TJS_BEGIN_NATIVE_METHOD_DECL(name) \\\n\t\tstruct NCM_##name { \\\n\t\t\tstatic tjs_error TJS_INTF_METHOD \\\n\t\t\tProcess( tTJSVariant *result, \\\n\t\t\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis) {\n\n#define TJS_END_NATIVE_METHOD_DECL_INT \\\n\t\t\t} \\\n\t\t};\n\n#define TJS_END_NATIVE_METHOD_DECL(name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassMethod(NCM_##name::Process), __classname, nitMethod);\n\n#define TJS_END_NATIVE_HIDDEN_METHOD_DECL(name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassMethod(NCM_##name::Process), __classname, nitMethod, \\\n\t\tTJS_HIDDENMEMBER);\n\n#define TJS_END_NATIVE_STATIC_METHOD_DECL(name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassMethod(NCM_##name::Process), __classname, nitMethod, \\\n\t\tTJS_STATICMEMBER);\n\n#define TJS_END_NATIVE_METHOD_DECL_OUTER(object, name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM((object), TJS_W(#name), \\\n\t\tTJSCreateNativeClassMethod(NCM_##name::Process), \\\n\t\t(object)->GetClassName().c_str(), nitMethod);\n\n#define TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(object, name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM((object), TJS_W(#name), \\\n\t\tTJSCreateNativeClassMethod(NCM_##name::Process), \\\n\t\t(object)->GetClassName().c_str(), nitMethod, TJS_STATICMEMBER);\n\n\n#define TJS_DECL_EMPTY_FINALIZE_METHOD \\\n\tTJS_BEGIN_NATIVE_METHOD_DECL(finalize) \\\n\t{ return TJS_S_OK; } \\\n\tTJS_END_NATIVE_METHOD_DECL(finalize)\n\n#define TJS_NATIVE_CONSTRUCTOR_CALL_NATIVE_CONSTRUCTOR(varname, typename) \\\n\t\t\t\ttypename *varname; \\\n\t\t\t\t{ \\\n\t\t\t\t\ttjs_error hr; \\\n\t\t\t\t\thr = objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \\\n\t\t\t\t\t\tTJS_NATIVE_CLASSID_NAME, \\\n\t\t\t\t\t\t(iTJSNativeInstance**)&varname); \\\n\t\t\t\t\tif(TJS_FAILED(hr)) return TJS_E_NATIVECLASSCRASH; \\\n\t\t\t\t\tif(!varname) return TJS_E_NATIVECLASSCRASH; \\\n\t\t\t\t\thr = varname->Construct(numparams, param, objthis); \\\n\t\t\t\t\tif(TJS_FAILED(hr)) return hr; \\\n\t\t\t\t}\n\n#define TJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(classname) \\\n\t\tstruct NCM_##classname { \\\n\t\t\tstatic tjs_error TJS_INTF_METHOD \\\n\t\t\tProcess(tTJSVariant *result, \\\n\t\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis) {\n\n#define TJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(varname, typename, classname) \\\n\t\tTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(classname) \\\n\t\tTJS_NATIVE_CONSTRUCTOR_CALL_NATIVE_CONSTRUCTOR(varname, typename)\n\n#define TJS_END_NATIVE_CONSTRUCTOR_DECL(name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassConstructor(NCM_##name::Process), __classname, \\\n\t\tnitMethod);\n\n#define TJS_END_NATIVE_STATIC_CONSTRUCTOR_DECL(name) \\\n\t\tTJS_END_NATIVE_METHOD_DECL_INT \\\n\t\tTJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassConstructor(NCM_##name::Process), __classname, \\\n\t\tnitMethod, TJS_STATICMEMBER);\n\n#define TJS_BEGIN_NATIVE_PROP_DECL(name) \\\n\t\tstruct NCM_##name\n\n#define TJS_END_NATIVE_PROP_DECL(name) \\\n\t\t;TJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassProperty(NCM_##name::Get, NCM_##name::Set), \\\n\t\t__classname, nitProperty);\n\n#define TJS_END_NATIVE_PROP_DECL_OUTER(object, name) \\\n\t\t;TJSNativeClassRegisterNCM((object), TJS_W(#name), \\\n\t\tTJSCreateNativeClassProperty(NCM_##name::Get, NCM_##name::Set), \\\n\t\t(object)->GetClassName().c_str(), nitProperty);\n\n#define TJS_END_NATIVE_STATIC_PROP_DECL(name) \\\n\t\t;TJSNativeClassRegisterNCM(TJS_NCM_REG_THIS, TJS_W(#name), \\\n\t\tTJSCreateNativeClassProperty(NCM_##name::Get, NCM_##name::Set), \\\n\t\t__classname, nitProperty, TJS_STATICMEMBER);\n\n#define TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(object, name) \\\n\t\t;TJSNativeClassRegisterNCM((object), TJS_W(#name), \\\n\t\tTJSCreateNativeClassProperty(NCM_##name::Get, NCM_##name::Set), \\\n\t\t(object)->GetClassName().c_str(), nitProperty, TJS_STATICMEMBER);\n\n\n#define TJS_BEGIN_NATIVE_PROP_GETTER \\\n\t\tstatic tjs_error TJS_INTF_METHOD Get(tTJSVariant *result, \\\n\t\tiTJSDispatch2 *objthis) { \\\n\n#define TJS_END_NATIVE_PROP_GETTER \\\n\t\t}\n\n#define TJS_DENY_NATIVE_PROP_GETTER \\\n\t\tstatic tjs_error TJS_INTF_METHOD Get(tTJSVariant *result, \\\n\t\tiTJSDispatch2 *objthis) \\\n\t\t{ return TJS_E_ACCESSDENYED; }\n\n#define TJS_BEGIN_NATIVE_PROP_SETTER \\\n\t\tstatic tjs_error TJS_INTF_METHOD Set(const tTJSVariant *param, \\\n\t\tiTJSDispatch2 *objthis) { \\\n\n#define TJS_END_NATIVE_PROP_SETTER \\\n\t\t}\n\n#define TJS_DENY_NATIVE_PROP_SETTER \\\n\t\tstatic tjs_error TJS_INTF_METHOD Set(const tTJSVariant *param, \\\n\t\tiTJSDispatch2 *objthis) \\\n\t\t{ return TJS_E_ACCESSDENYED; }\n\n#define TJS_END_NATIVE_MEMBERS \\\n\t}\n\n#define TJS_PARAM_EXIST(num) (numparams>(num) ? param[num]->Type()!=tvtVoid : false)\n\n\n/*]*/\n\n//---------------------------------------------------------------------------\n// tTJSNativeFunction\n//---------------------------------------------------------------------------\n// base class used for native function ( for non-class-method )\nclass tTJSNativeFunction : public tTJSDispatch\n{\n\ttypedef tTJSDispatch inherited;\npublic:\n\ttTJSNativeFunction(const tjs_char *name = NULL);\n\t\t// 'name' is just to be used as a label for debugging\n\t~tTJSNativeFunction();\n\n\ttjs_error TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\nprotected:\n\ttjs_error virtual Process(tTJSVariant *result, tjs_int numparams,\n\t\ttTJSVariant **param, iTJSDispatch2 *objthis) = 0;\n\t\t// override this instead of FuncCall\n};\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsObject.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 \"Object\" class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsObject.h\"\n#include \"tjsUtils.h\"\n#include \"tjsNative.h\"\n#include \"tjsHashSearch.h\"\n#include \"tjsGlobalStringMap.h\"\n#include \"tjsDebug.h\"\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// utility functions\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\nvoid TJSDoVariantOperation(tjs_int op, tTJSVariant &target, const tTJSVariant *param)\n{\n\tswitch(op)\n\t{\n\tcase TJS_OP_BAND:\n\t\ttarget.operator &= (*param);\n\t\treturn;\n\tcase TJS_OP_BOR:\n\t\ttarget.operator |= (*param);\n\t\treturn;\n\tcase TJS_OP_BXOR:\n\t\ttarget.operator ^= (*param);\n\t\treturn;\n\tcase TJS_OP_SUB:\n\t\ttarget.operator -= (*param);\n\t\treturn;\n\tcase TJS_OP_ADD:\n\t\ttarget.operator += (*param);\n\t\treturn;\n\tcase TJS_OP_MOD:\n\t\ttarget.operator %= (*param);\n\t\treturn;\n\tcase TJS_OP_DIV:\n\t\ttarget.operator /= (*param);\n\t\treturn;\n\tcase TJS_OP_IDIV:\n\t\ttarget.idivequal(*param);\n\t\treturn;\n\tcase TJS_OP_MUL:\n\t\ttarget.operator *= (*param);\n\t\treturn;\n\tcase TJS_OP_LOR:\n\t\ttarget.logicalorequal(*param);\n\t\treturn;\n\tcase TJS_OP_LAND:\n\t\ttarget.logicalandequal(*param);\n\t\treturn;\n\tcase TJS_OP_SAR:\n\t\ttarget.operator >>= (*param);\n\t\treturn;\n\tcase TJS_OP_SAL:\n\t\ttarget.operator <<= (*param);\n\t\treturn;\n\tcase TJS_OP_SR:\n\t\ttarget.rbitshiftequal(*param);\n\t\treturn;\n\tcase TJS_OP_INC:\n\t\ttarget.increment();\n\t\treturn;\n\tcase TJS_OP_DEC:\n\t\ttarget.decrement();\n\t\treturn;\n\t}\n\n}\n//---------------------------------------------------------------------------\n\n\n\n\n/*[C*/\n//---------------------------------------------------------------------------\n// tTJSDispatch\n//---------------------------------------------------------------------------\ntTJSDispatch::tTJSDispatch()\n{\n\tBeforeDestructionCalled = false;\n\tRefCount = 1;\n#ifdef TVP_IN_PLUGIN_STUB // TVP plug-in support\n\tTVPPluginGlobalRefCount++;\n#endif\n}\n//---------------------------------------------------------------------------\ntTJSDispatch::~tTJSDispatch()\n{\n\tif(!BeforeDestructionCalled)\n\t{\n\t\tBeforeDestructionCalled = true;\n\t\tBeforeDestruction();\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD  tTJSDispatch::AddRef(void)\n{\n#ifdef TVP_IN_PLUGIN_STUB // TVP plug-in support\n\tTVPPluginGlobalRefCount++;\n#endif\n\treturn ++RefCount;\n}\n//---------------------------------------------------------------------------\ntjs_uint TJS_INTF_METHOD  tTJSDispatch::Release(void)\n{\n#ifdef TVP_IN_PLUGIN_STUB // TVP plug-in support\n\tTVPPluginGlobalRefCount--;\n#endif\n\tif(RefCount == 1) // avoid to call \"BeforeDestruction\" with RefCount == 0\n\t{\n\t\t// object destruction\n\t\tif(!BeforeDestructionCalled)\n\t\t{\n\t\t\tBeforeDestructionCalled = true;\n\t\t\tBeforeDestruction();\n\t\t}\n\n\t\tif(RefCount == 1) // really ready to destruct ?\n\t\t{\n\t\t\tdelete this;\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn --RefCount;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::FuncCallByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn FuncCall(flag, buf, NULL, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::PropGetByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn PropGet(flag, buf, NULL, result, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::PropSetByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn PropSet(flag, buf, NULL, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::GetCountByNum(\n\t\ttjs_int *result,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn GetCount(result, buf, NULL, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::DeleteMemberByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn DeleteMember(flag, buf, NULL, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::InvalidateByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn Invalidate(flag, buf, NULL, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::IsValidByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn IsValid(flag, buf, NULL, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::CreateNewByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn CreateNew(flag, buf, NULL, result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::IsInstanceOfByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn IsInstanceOf(flag, buf, NULL, classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::OperationByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n{\n\ttjs_char buf[34];\n\tTJS_int_to_str(num, buf);\n\treturn Operation(flag, buf, NULL, result, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSDispatch::Operation(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t)\n{\n\ttjs_uint32 op = flag & TJS_OP_MASK;\n\n\tif(op!=TJS_OP_INC && op!=TJS_OP_DEC && param == NULL)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\tif(op<TJS_OP_MIN || op>TJS_OP_MAX)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\ttTJSVariant tmp;\n\ttjs_error hr;\n\thr = PropGet(0, membername, hint, &tmp, objthis);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tTJSDoVariantOperation(op, tmp, param);\n\n\thr = PropSet(0, membername, hint, &tmp, objthis);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tif(result) result->CopyRef(tmp);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\n/*C]*/\n\n\n\n\n\n//---------------------------------------------------------------------------\n// property object to get/set missing member\n//---------------------------------------------------------------------------\nclass tTJSSimpleGetSetProperty : public tTJSDispatch\n{\nprivate:\n\ttTJSVariant &Value;\n\npublic:\n\ttTJSSimpleGetSetProperty(tTJSVariant &value) : tTJSDispatch(), Value(value)\n\t{\n\t};\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\tif(membername) return TJS_E_MEMBERNOTFOUND;\n\t\tif(result) *result = Value;\n\t\treturn TJS_S_OK;\n\t}\n\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t const tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis)\n\t{\n\t\tif(membername) return TJS_E_MEMBERNOTFOUND;\n\t\tValue = *param;\n\t\treturn TJS_S_OK;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n\t{\n\t\tif(membername) return TJS_E_MEMBERNOTFOUND;\n\t\tValue = *param;\n\t\treturn TJS_S_OK;\n\t}\n\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// magic number for rebuilding hash\n//---------------------------------------------------------------------------\nstatic tjs_uint TJSGlobalRebuildHashMagic = 0;\nvoid TJSDoRehash() { TJSGlobalRebuildHashMagic ++; }\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSCustomObject\n//---------------------------------------------------------------------------\ntjs_int TJSObjectHashBitsLimit = 32;\nstatic ttstr FinalizeName;\nstatic ttstr MissingName;\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::tTJSSymbolData::ReShare()\n{\n\t// search shared string map using TJSMapGlobalStringMap,\n\t// and share the name string (if it can)\n\tif(Name)\n\t{\n\t\tttstr name(Name);\n\t\tName->Release(), Name = NULL;\n\t\tname = TJSMapGlobalStringMap(name);\n\t\tName = name.AsVariantStringNoAddRef();\n\t\tName->AddRef();\n\t}\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\ntTJSCustomObject::tTJSCustomObject(tjs_int hashbits)\n{\n\tif(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this);\n\tCount = 0;\n\tRebuildHashMagic = TJSGlobalRebuildHashMagic;\n\tif(hashbits > TJSObjectHashBitsLimit) hashbits = TJSObjectHashBitsLimit;\n\tHashSize = (1 << hashbits);\n\tHashMask = HashSize - 1;\n\tSymbols = new tTJSSymbolData[HashSize];\n\tmemset(Symbols, 0, sizeof(tTJSSymbolData) * HashSize);\n\tIsInvalidated = false;\n\tIsInvalidating = false;\n\tCallFinalize = true;\n\tCallMissing = false;\n\tProsessingMissing = false;\n\tif(FinalizeName.IsEmpty())\n\t{\n\t\t// first time; initialize 'finalize' name and 'missing' name\n\t\tstatic ttstr _finalize = TJSMapGlobalStringMap(TJS_W(\"finalize\"));\n\t\tstatic ttstr _missing = TJSMapGlobalStringMap(TJS_W(\"missing\"));\n\t\tFinalizeName = _finalize;\n\t\tMissingName = _missing;\n\t}\n\tfinalize_name = FinalizeName;\n\tmissing_name = MissingName;\n\tfor(tjs_int i=0; i<TJS_MAX_NATIVE_CLASS; i++)\n\t\tClassIDs[i] = (tjs_int32)-1;\n}\n//---------------------------------------------------------------------------\ntTJSCustomObject::~tTJSCustomObject()\n{\n\tfor(tjs_int i=TJS_MAX_NATIVE_CLASS-1; i>=0; i--)\n\t{\n\t\tif(ClassIDs[i]!=-1)\n\t\t{\n\t\t\tif(ClassInstances[i]) ClassInstances[i]->Destruct();\n\t\t}\n\t}\n\tdelete [] Symbols;\n\tif(TJSObjectHashMapEnabled()) TJSRemoveObjectHashRecord(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::_Finalize(void)\n{\n\tif(IsInvalidating) return; // to avoid re-entrance\n\tIsInvalidating = true;\n\ttry\n\t{\n\t\tif(!IsInvalidated)\n\t\t{\n\t\t\tFinalize();\n\t\t\tIsInvalidated = true;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tIsInvalidating = false;\n\t\tthrow;\n\t}\n\tIsInvalidating = false;\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::Finalize(void)\n{\n\t// call this object's \"finalize\"\n\tif(CallFinalize)\n\t{\n\t\tFuncCall(0, finalize_name.c_str(), finalize_name.GetHint(), NULL, 0,\n\t\t\tNULL, this);\n\t}\n\n\tfor(tjs_int i=TJS_MAX_NATIVE_CLASS-1; i>=0; i--)\n\t{\n\t\tif(ClassIDs[i]!=-1)\n\t\t{\n\t\t\tif(ClassInstances[i]) ClassInstances[i]->Invalidate();\n\t\t}\n\t}\n\tDeleteAllMembers();\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::BeforeDestruction(void)\n{\n\tif(TJSObjectHashMapEnabled())\n\t\tTJSSetObjectHashFlag(this, TJS_OHMF_DELETING, TJS_OHMF_SET);\n\t_Finalize();\n}\n//---------------------------------------------------------------------------\nbool tTJSCustomObject::CallGetMissing(const tjs_char *name, tTJSVariant &result)\n{\n\t// call 'missing' method for PopGet\n\tif(ProsessingMissing) return false;\n\tProsessingMissing = true;\n\tbool res = false;\n\ttry\n\t{\n\t\ttTJSVariant val;\n\t\ttTJSSimpleGetSetProperty * prop = new tTJSSimpleGetSetProperty(val);\n\t\ttry\n\t\t{\n\t\t\ttTJSVariant args[3];\n\t\t\targs[0] = (tjs_int) false; // false: get\n\t\t\targs[1] = name;        // member name\n\t\t\targs[2] = prop;\n\t\t\ttTJSVariant *pargs[3] = {args +0, args +1, args +2};\n\t\t\ttTJSVariant funcresult;\n\t\t\ttjs_error er = \n\t\t\t\tFuncCall(0, missing_name.c_str(), missing_name.GetHint(), &funcresult,\n\t\t\t\t\t3, pargs, this);\n\t\t\tif(TJS_FAILED(er))\n\t\t\t{\n\t\t\t\tres = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tres = 0!=(tjs_int)funcresult;\n\t\t\t\tresult = val;\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tprop->Release();\n\t\t\tthrow;\n\t\t}\n\t\tprop->Release();\n\t}\n\tcatch(...)\n\t{\n\t\tProsessingMissing = false;\n\t\tthrow;\n\t}\n\tProsessingMissing = false;\n\treturn res;\n}\n//---------------------------------------------------------------------------\nbool tTJSCustomObject::CallSetMissing(const tjs_char *name, const tTJSVariant &value)\n{\n\t// call 'missing' method for PopSet\n\tif(ProsessingMissing) return false;\n\tProsessingMissing = true;\n\tbool res = false;\n\ttry\n\t{\n\t\ttTJSVariant val(value);\n\t\ttTJSSimpleGetSetProperty * prop = new tTJSSimpleGetSetProperty(val);\n\t\ttry\n\t\t{\n\t\t\ttTJSVariant args[3];\n\t\t\targs[0] = (tjs_int) true; // true: set\n\t\t\targs[1] = name;        // member name\n\t\t\targs[2] = prop;\n\t\t\ttTJSVariant *pargs[3] = {args +0, args +1, args +2};\n\t\t\ttTJSVariant funcresult;\n\t\t\ttjs_error er = \n\t\t\t\tFuncCall(0, missing_name.c_str(), missing_name.GetHint(), &funcresult,\n\t\t\t\t\t3, pargs, this);\n\t\t\tif(TJS_FAILED(er))\n\t\t\t{\n\t\t\t\tres = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tres = 0!=(tjs_int)funcresult;\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tprop->Release();\n\t\t\tthrow;\n\t\t}\n\t\tprop->Release();\n\t}\n\tcatch(...)\n\t{\n\t\tProsessingMissing = false;\n\t\tthrow;\n\t}\n\tProsessingMissing = false;\n\treturn res;\n}\n//---------------------------------------------------------------------------\ntTJSCustomObject::tTJSSymbolData * tTJSCustomObject::Add(const tjs_char * name,\n\ttjs_uint32 *hint)\n{\n\t// add a data element named \"name\".\n\t// return existing element if the element named \"name\" is already alive.\n\n\tif(name == NULL)\n\t{\n\t\treturn NULL;\n\t}\n\n\ttTJSSymbolData *data;\n\tdata = Find(name, hint);\n\tif(data)\n\t{\n\t\t// the element is already alive\n\t\treturn data;\n\t}\n\n\ttjs_uint32 hash;\n\tif(hint && *hint)\n\t\thash = *hint;  // hint must be hash because of previous calling of \"Find\"\n\telse\n\t\thash = tTJSHashFunc<tjs_char *>::Make(name);\n\n\ttTJSSymbolData *lv1 = Symbols + (hash & HashMask);\n\n\tif((lv1->SymFlags & TJS_SYMBOL_USING))\n\t{\n\t\t// lv1 is using\n\t\t// make a chain and insert it after lv1\n\n\t\tdata = new tTJSSymbolData;\n\n\t\tdata->SelfClear();\n\n\t\tdata->Next = lv1->Next;\n\t\tlv1->Next = data;\n\n\t\tdata->SetName(name, hash);\n\t\tdata->SymFlags |= TJS_SYMBOL_USING;\n\t}\n\telse\n\t{\n\t\t// lv1 is unused\n\t\tif(!(lv1->SymFlags & TJS_SYMBOL_INIT))\n\t\t{\n\t\t\tlv1->SelfClear();\n\t\t}\n\n\t\tlv1->SetName(name, hash);\n\t\tlv1->SymFlags |= TJS_SYMBOL_USING;\n\t\tdata = lv1;\n\t}\n\n\tCount++;\n\n\n\treturn data;\n\n}\n//---------------------------------------------------------------------------\ntTJSCustomObject::tTJSSymbolData * tTJSCustomObject::Add(tTJSVariantString * name)\n{\n\t// tTJSVariantString version of above\n\n\tif(name == NULL)\n\t{\n\t\treturn NULL;\n\t}\n\n\ttTJSSymbolData *data;\n\tdata = Find((const tjs_char *)(*name), name->GetHint());\n\tif(data)\n\t{\n\t\t// the element is already alive\n\t\treturn data;\n\t}\n\n\ttjs_uint32 hash;\n\tif(*(name->GetHint()))\n\t\thash = *(name->GetHint());  // hint must be hash because of previous calling of \"Find\"\n\telse\n\t\thash = tTJSHashFunc<tjs_char *>::Make((const tjs_char *)(*name));\n\n\ttTJSSymbolData *lv1 = Symbols + (hash & HashMask);\n\n\tif((lv1->SymFlags & TJS_SYMBOL_USING))\n\t{\n\t\t// lv1 is using\n\t\t// make a chain and insert it after lv1\n\n\t\tdata = new tTJSSymbolData;\n\n\t\tdata->SelfClear();\n\n\t\tdata->Next = lv1->Next;\n\t\tlv1->Next = data;\n\n\t\tdata->SetName(name, hash);\n\t\tdata->SymFlags |= TJS_SYMBOL_USING;\n\t}\n\telse\n\t{\n\t\t// lv1 is unused\n\t\tif(!(lv1->SymFlags & TJS_SYMBOL_INIT))\n\t\t{\n\t\t\tlv1->SelfClear();\n\t\t}\n\n\t\tlv1->SetName(name, hash);\n\t\tlv1->SymFlags |= TJS_SYMBOL_USING;\n\t\tdata = lv1;\n\t}\n\n\tCount++;\n\n\n\treturn data;\n}\n//---------------------------------------------------------------------------\ntTJSCustomObject::tTJSSymbolData * tTJSCustomObject::AddTo(tTJSVariantString *name,\n\t\ttTJSSymbolData *newdata, tjs_int newhashmask)\n{\n\t// similar to Add, except for adding member to new hash space.\n\tif(name == NULL)\n\t{\n\t\treturn NULL;\n\t}\n\n\t// at this point, the member must not exist in destination hash space\n\n\ttjs_uint32 hash;\n\thash = tTJSHashFunc<tjs_char *>::Make((const tjs_char *)(*name));\n\n\ttTJSSymbolData *lv1 = newdata + (hash & newhashmask);\n\ttTJSSymbolData *data;\n\n\tif((lv1->SymFlags & TJS_SYMBOL_USING))\n\t{\n\t\t// lv1 is using\n\t\t// make a chain and insert it after lv1\n\n\t\tdata = new tTJSSymbolData;\n\n\t\tdata->SelfClear();\n\n\t\tdata->Next = lv1->Next;\n\t\tlv1->Next = data;\n\n\t\tdata->SetName(name, hash);\n\t\tdata->SymFlags |= TJS_SYMBOL_USING;\n\t}\n\telse\n\t{\n\t\t// lv1 is unused\n\t\tif(!(lv1->SymFlags & TJS_SYMBOL_INIT))\n\t\t{\n\t\t\tlv1->SelfClear();\n\t\t}\n\n\t\tlv1->SetName(name, hash);\n\t\tlv1->SymFlags |= TJS_SYMBOL_USING;\n\t\tdata = lv1;\n\t}\n\n\t// count is not incremented\n\n\treturn data;\n}\n//---------------------------------------------------------------------------\n#define GetValue(x) (*((tTJSVariant *)(&(x->Value))))\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::RebuildHash()\n{\n\tRebuildHash( Count );\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::RebuildHash( tjs_int requestcount )\n{\n\t// rebuild hash table\n\tRebuildHashMagic = TJSGlobalRebuildHashMagic;\n\n\t// decide new hash table size\n\n\ttjs_int r, v = requestcount;\n\tif(v & 0xffff0000) r = 16, v >>= 16; else r = 0;\n\tif(v & 0xff00) r += 8, v >>= 8;\n\tif(v & 0xf0) r += 4, v >>= 4;\n\tv<<=1;\n\ttjs_int newhashbits = r + ((0xffffaa50 >> v) &0x03) + 2;\n\tif(newhashbits > TJSObjectHashBitsLimit) newhashbits = TJSObjectHashBitsLimit;\n\ttjs_int newhashsize = (1 << newhashbits);\n\n\n\tif(newhashsize == HashSize) return;\n\n\ttjs_int newhashmask = newhashsize - 1;\n\ttjs_int orgcount = Count;\n\n\t// allocate new hash space\n\ttTJSSymbolData *newsymbols = new tTJSSymbolData[newhashsize];\n\n\n\t// enumerate current symbol and push to new hash space\n\n\ttry\n\t{\n\t\tmemset(newsymbols, 0, sizeof(tTJSSymbolData) * newhashsize);\n\t\t//tjs_int i;\n\t\ttTJSSymbolData * lv1 = Symbols;\n\t\ttTJSSymbolData * lv1lim = lv1 + HashSize;\n\t\tfor(; lv1 < lv1lim; lv1++)\n\t\t{\n\t\t\ttTJSSymbolData * d = lv1->Next;\n\t\t\twhile(d)\n\t\t\t{\n\t\t\t\ttTJSSymbolData * nextd = d->Next;\n\t\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t\t{\n//\t\t\t\t\td->ReShare();\n\t\t\t\t\ttTJSSymbolData *data = AddTo(d->Name, newsymbols, newhashmask);\n\t\t\t\t\tif(data)\n\t\t\t\t\t{\n\t\t\t\t\t\tGetValue(data).CopyRef(*(tTJSVariant*)(&(d->Value)));\n\t\t\t\t\t\tdata->SymFlags &= ~ (TJS_SYMBOL_HIDDEN | TJS_SYMBOL_STATIC);\n\t\t\t\t\t\tdata->SymFlags |= d->SymFlags & (TJS_SYMBOL_HIDDEN | TJS_SYMBOL_STATIC);\n\t\t\t\t\t\tCheckObjectClosureAdd(GetValue(data));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\td = nextd;\n\t\t\t}\n\n\t\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n//\t\t\t\tlv1->ReShare();\n\t\t\t\ttTJSSymbolData *data = AddTo(lv1->Name, newsymbols, newhashmask);\n\t\t\t\tif(data)\n\t\t\t\t{\n\t\t\t\t\tGetValue(data).CopyRef(*(tTJSVariant*)(&(lv1->Value)));\n\t\t\t\t\tdata->SymFlags &= ~ (TJS_SYMBOL_HIDDEN | TJS_SYMBOL_STATIC);\n\t\t\t\t\tdata->SymFlags |= lv1->SymFlags & (TJS_SYMBOL_HIDDEN | TJS_SYMBOL_STATIC);\n\t\t\t\t\tCheckObjectClosureAdd(GetValue(data));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\t// recover\n\t\ttjs_int _HashMask = HashMask;\n\t\ttjs_int _HashSize = HashSize;\n\t\ttTJSSymbolData * _Symbols = Symbols;\n\n\t\tSymbols = newsymbols;\n\t\tHashSize = newhashsize;\n\t\tHashMask = newhashmask;\n\n\t\tDeleteAllMembers();\n\t\tdelete [] Symbols;\n\n\t\tHashMask = _HashMask;\n\t\tHashSize = _HashSize;\n\t\tSymbols = _Symbols;\n\t\tCount = orgcount;\n\n\t\tthrow;\n\t}\n\n\t// delete all current members\n\tDeleteAllMembers();\n\tdelete [] Symbols;\n\n\t// assign new members\n\tSymbols = newsymbols;\n\tHashSize = newhashsize;\n\tHashMask = newhashmask;\n\tCount = orgcount;\n}\n//---------------------------------------------------------------------------\nbool tTJSCustomObject::DeleteByName(const tjs_char * name, tjs_uint32 *hint)\n{\n\t// TODO: utilize hint\n\t// find an element named \"name\" and deletes it\n\ttjs_uint32 hash = tTJSHashFunc<tjs_char *>::Make(name);\n\ttTJSSymbolData * lv1 = Symbols + (hash & HashMask);\n\n\tif(!(lv1->SymFlags & TJS_SYMBOL_USING) && lv1->Next== NULL)\n\t\treturn false; // not found\n\n\tif((lv1->SymFlags & TJS_SYMBOL_USING) && lv1->NameMatch(name))\n\t{\n\t\t// mark the element place as \"unused\"\n\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(lv1->Value)));\n\t\tlv1->PostClear();\n\t\tCount--;\n\t\treturn true;\n\t}\n\n\t// chain processing\n\ttTJSSymbolData * d = lv1->Next;\n\ttTJSSymbolData * prevd = lv1;\n\twhile(d)\n\t{\n\t\tif((d->SymFlags & TJS_SYMBOL_USING) && d->Hash == hash)\n\t\t{\n\t\t\tif(d->NameMatch(name))\n\t\t\t{\n\t\t\t\t// sever from the chain\n\t\t\t\tprevd->Next = d->Next;\n\t\t\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(d->Value)));\n\t\t\t\td->Destory();\n\n\t\t\t\tdelete d;\n\n\t\t\t\tCount--;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tprevd = d;\n\t\td = d->Next;\n\t}\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::DeleteAllMembers(void)\n{\n\t// delete all members\n\tif(Count <= 10) return _DeleteAllMembers();\n\n\tstd::vector<iTJSDispatch2*> vector;\n\ttry\n\t{\n\t\ttTJSSymbolData * lv1, *lv1lim;\n\n\t\t// list all members up that hold object\n\t\tlv1 = Symbols;\n\t\tlv1lim = lv1 + HashSize;\n\t\tfor(; lv1 < lv1lim; lv1++)\n\t\t{\n\t\t\ttTJSSymbolData * d = lv1->Next;\n\t\t\twhile(d)\n\t\t\t{\n\t\t\t\ttTJSSymbolData * nextd = d->Next;\n\t\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t\t{\n\t\t\t\t\tif(((tTJSVariant*)(&(d->Value)))->Type() == tvtObject)\n\t\t\t\t\t{\n\t\t\t\t\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(d->Value)));\n\t\t\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\t\t\t((tTJSVariant*)(&(d->Value)))->AsObjectClosureNoAddRef();\n\t\t\t\t\t\tclo.AddRef();\n\t\t\t\t\t\tif(clo.Object) vector.push_back(clo.Object);\n\t\t\t\t\t\tif(clo.ObjThis) vector.push_back(clo.ObjThis);\n\t\t\t\t\t\t((tTJSVariant*)(&(d->Value)))->Clear();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\td = nextd;\n\t\t\t}\n\n\t\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n\t\t\t\tif(((tTJSVariant*)(&(lv1->Value)))->Type() == tvtObject)\n\t\t\t\t{\n\t\t\t\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(lv1->Value)));\n\t\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\t\t((tTJSVariant*)(&(lv1->Value)))->AsObjectClosureNoAddRef();\n\t\t\t\t\tclo.AddRef();\n\t\t\t\t\tif(clo.Object) vector.push_back(clo.Object);\n\t\t\t\t\tif(clo.ObjThis) vector.push_back(clo.ObjThis);\n\t\t\t\t\t((tTJSVariant*)(&(lv1->Value)))->Clear();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// delete all members\n\t\tlv1 = Symbols;\n\t\tlv1lim = lv1 + HashSize;\n\t\tfor(; lv1 < lv1lim; lv1++)\n\t\t{\n\t\t\ttTJSSymbolData * d = lv1->Next;\n\t\t\twhile(d)\n\t\t\t{\n\t\t\t\ttTJSSymbolData * nextd = d->Next;\n\t\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t\t{\n\t\t\t\t\td->Destory();\n\t\t\t\t}\n\n\t\t\t\tdelete d;\n\n\t\t\t\td = nextd;\n\t\t\t}\n\n\t\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n\t\t\t\tlv1->PostClear();\n\t\t\t}\n\n\t\t\tlv1->Next = NULL;\n\t\t}\n\n\t\tCount = 0;\n\t}\n\tcatch(...)\n\t{\n\t\tstd::vector<iTJSDispatch2*>::iterator i;\n\t\tfor(i = vector.begin(); i != vector.end(); i++)\n\t\t{\n\t\t\t(*i)->Release();\n\t\t}\n\n\t\tthrow;\n\t}\n\n\t// release all objects\n\tstd::vector<iTJSDispatch2*>::iterator i;\n\tfor(i = vector.begin(); i != vector.end(); i++)\n\t{\n\t\t(*i)->Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::_DeleteAllMembers(void)\n{\n\tiTJSDispatch2 * dsps[20];\n\ttjs_int num_dsps = 0;\n\n\ttry\n\t{\n\t\ttTJSSymbolData * lv1, *lv1lim;\n\n\t\t// list all members up that hold object\n\t\tlv1 = Symbols;\n\t\tlv1lim = lv1 + HashSize;\n\t\tfor(; lv1 < lv1lim; lv1++)\n\t\t{\n\t\t\ttTJSSymbolData * d = lv1->Next;\n\t\t\twhile(d)\n\t\t\t{\n\t\t\t\ttTJSSymbolData * nextd = d->Next;\n\t\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t\t{\n\t\t\t\t\tif(((tTJSVariant*)(&(d->Value)))->Type() == tvtObject)\n\t\t\t\t\t{\n\t\t\t\t\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(d->Value)));\n\t\t\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\t\t\t((tTJSVariant*)(&(d->Value)))->AsObjectClosureNoAddRef();\n\t\t\t\t\t\tclo.AddRef();\n\t\t\t\t\t\tif(clo.Object) dsps[num_dsps++] = clo.Object;\n\t\t\t\t\t\tif(clo.ObjThis) dsps[num_dsps++] = clo.ObjThis;\n\t\t\t\t\t\t((tTJSVariant*)(&(d->Value)))->Clear();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\td = nextd;\n\t\t\t}\n\n\t\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n\t\t\t\tif(((tTJSVariant*)(&(lv1->Value)))->Type() == tvtObject)\n\t\t\t\t{\n\t\t\t\t\tCheckObjectClosureRemove(*(tTJSVariant*)(&(lv1->Value)));\n\t\t\t\t\ttTJSVariantClosure clo =\n\t\t\t\t\t\t((tTJSVariant*)(&(lv1->Value)))->AsObjectClosureNoAddRef();\n\t\t\t\t\tclo.AddRef();\n\t\t\t\t\tif(clo.Object) dsps[num_dsps++] = clo.Object;\n\t\t\t\t\tif(clo.ObjThis) dsps[num_dsps++] = clo.ObjThis;\n\t\t\t\t\t((tTJSVariant*)(&(lv1->Value)))->Clear();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// delete all members\n\t\tlv1 = Symbols;\n\t\tlv1lim = lv1 + HashSize;\n\t\tfor(; lv1 < lv1lim; lv1++)\n\t\t{\n\t\t\ttTJSSymbolData * d = lv1->Next;\n\t\t\twhile(d)\n\t\t\t{\n\t\t\t\ttTJSSymbolData * nextd = d->Next;\n\t\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t\t{\n\t\t\t\t\td->Destory();\n\t\t\t\t}\n\n\t\t\t\tdelete d;\n\n\t\t\t\td = nextd;\n\t\t\t}\n\n\t\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n\t\t\t\tlv1->PostClear();\n\t\t\t}\n\n\t\t\tlv1->Next = NULL;\n\t\t}\n\n\t\tCount = 0;\n\t}\n\tcatch(...)\n\t{\n\t\tfor(int i = 0; i<num_dsps; i++)\n\t\t{\n\t\t\tdsps[i]->Release();\n\t\t}\n\t\tthrow;\n\t}\n\n\t// release all objects\n\tfor(int i = 0; i<num_dsps; i++)\n\t{\n\t\tdsps[i]->Release();\n\t}\n\n}\n//---------------------------------------------------------------------------\ntTJSCustomObject::tTJSSymbolData * tTJSCustomObject::Find(const tjs_char * name,\n\ttjs_uint32 *hint)\n{\n\t// searche an element named \"name\" and return its \"SymbolData\".\n\t// return NULL if the element is not found.\n\n\tif(!name) return NULL;\n\n\tif(hint && *hint)\n\t{\n\t\t// try finding via hint\n\t\t// search over the chain\n\t\ttjs_uint32 hash = *hint;\n\t\ttjs_int cnt = 0;\n\t\ttTJSSymbolData * lv1 = Symbols + (hash & HashMask);\n\t\ttTJSSymbolData * prevd = lv1;\n\t\ttTJSSymbolData * d = lv1->Next;\n\t\tfor(; d; prevd = d, d=d->Next, cnt++)\n\t\t{\n\t\t\tif(d->Hash == hash && (d->SymFlags & TJS_SYMBOL_USING))\n\t\t\t{\n\t\t\t\tif(d->NameMatch(name))\n\t\t\t\t{\n\t\t\t\t\tif(cnt>2)\n\t\t\t\t\t{\n\t\t\t\t\t\t// move to first\n\t\t\t\t\t\tprevd->Next = d->Next;\n\t\t\t\t\t\td->Next = lv1->Next;\n\t\t\t\t\t\tlv1->Next = d;\n\t\t\t\t\t}\n\t\t\t\t\treturn d;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(lv1->Hash == hash && (lv1->SymFlags & TJS_SYMBOL_USING))\n\t\t{\n\t\t\tif(lv1->NameMatch(name))\n\t\t\t{\n\t\t\t\treturn lv1;\n\t\t\t}\n\t\t}\n\t}\n\n\ttjs_uint32 hash = tTJSHashFunc<tjs_char *>::Make(name);\n\tif(hint && *hint)\n\t{\n\t\tif(*hint == hash) return NULL;\n\t\t\t// given hint was not differ from the hash;\n\t\t\t// we already know that the member was not found.\n\t}\n\n\tif(hint) *hint = hash;\n\n\ttTJSSymbolData * lv1 = Symbols + (hash & HashMask);\n\n\tif(!(lv1->SymFlags & TJS_SYMBOL_USING) && lv1->Next == NULL)\n\t\treturn NULL; // lv1 is unused and does not have any chains\n\n\t// search over the chain\n\ttjs_int cnt = 0;\n\ttTJSSymbolData * prevd = lv1;\n\ttTJSSymbolData * d = lv1->Next;\n\tfor(; d; prevd = d, d=d->Next, cnt++)\n\t{\n\t\tif(d->Hash == hash && (d->SymFlags & TJS_SYMBOL_USING))\n\t\t{\n\t\t\tif(d->NameMatch(name))\n\t\t\t{\n\t\t\t\tif(cnt>2)\n\t\t\t\t{\n\t\t\t\t\t// move to first\n\t\t\t\t\tprevd->Next = d->Next;\n\t\t\t\t\td->Next = lv1->Next;\n\t\t\t\t\tlv1->Next = d;\n\t\t\t\t}\n\t\t\t\treturn d;\n\t\t\t}\n\t\t}\n\t}\n\n\tif(lv1->Hash == hash && (lv1->SymFlags & TJS_SYMBOL_USING))\n\t{\n\t\tif(lv1->NameMatch(name))\n\t\t{\n\t\t\treturn lv1;\n\t\t}\n\t}\n\n\treturn NULL;\n\n}\n//---------------------------------------------------------------------------\nbool tTJSCustomObject::CallEnumCallbackForData(\n\ttjs_uint32 flags, tTJSVariant ** params,\n\ttTJSVariantClosure & callback, iTJSDispatch2 * objthis,\n\tconst tTJSCustomObject::tTJSSymbolData * data)\n{\n\ttjs_uint32 newflags = 0;\n\tif(data->SymFlags & TJS_SYMBOL_HIDDEN) newflags |= TJS_HIDDENMEMBER;\n\tif(data->SymFlags & TJS_SYMBOL_STATIC) newflags |= TJS_STATICMEMBER;\n\n\t*params[0] = data->Name;\n\t*params[1] = (tjs_int)newflags;\n\n\tif(!(flags & TJS_ENUM_NO_VALUE))\n\t{\n\t\t// get value\n\t\tif(TJS_FAILED(TJSDefaultPropGet(flags, *(tTJSVariant*)(&(data->Value)),\n\t\t\tparams[2], objthis))) return false;\n\t}\n\n\ttTJSVariant res;\n\tif(TJS_FAILED(callback.FuncCall(NULL, NULL, NULL, &res,\n\t\t(flags & TJS_ENUM_NO_VALUE) ? 2 : 3, params, NULL))) return false;\n\treturn 0!=(tjs_int)(res);\n}\n//---------------------------------------------------------------------------\nvoid tTJSCustomObject::InternalEnumMembers(tjs_uint32 flags,\n\ttTJSVariantClosure *callback, iTJSDispatch2 *objthis)\n{\n\t// enumlate members by calling callback.\n\t// note that member changes(delete or insert) through this function is not guaranteed.\n\tif(!callback) return;\n\n\ttTJSVariant name;\n\ttTJSVariant newflags;\n\ttTJSVariant value;\n\ttTJSVariant * params[3] = { &name, &newflags, &value };\n\n\tconst tTJSSymbolData * lv1 = Symbols;\n\tconst tTJSSymbolData * lv1lim = lv1 + HashSize;\n\tfor(; lv1 < lv1lim; lv1++)\n\t{\n\t\tconst tTJSSymbolData * d = lv1->Next;\n\t\twhile(d)\n\t\t{\n\t\t\tconst tTJSSymbolData * nextd = d->Next;\n\n\t\t\tif(d->SymFlags & TJS_SYMBOL_USING)\n\t\t\t{\n\t\t\t\tif(!CallEnumCallbackForData(flags, params, *callback, objthis, d)) return ;\n\t\t\t}\n\t\t\td = nextd;\n\t\t}\n\n\t\tif(lv1->SymFlags & TJS_SYMBOL_USING)\n\t\t{\n\t\t\tif(!CallEnumCallbackForData(flags, params, *callback, objthis, lv1)) return ;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSCustomObject::GetValueInteger(const tjs_char * name, tjs_uint32 *hint)\n{\n\ttTJSSymbolData *data = Find(name, hint);\n\tif(!data) return -1;\n\treturn (tjs_int)data->Value.Integer;\n}\n//---------------------------------------------------------------------------\ntjs_error TJSTryFuncCallViaPropGet(tTJSVariantClosure tvclosure,\n\ttjs_uint32 flag, tTJSVariant *result,\n\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\t// retry using PropGet\n\ttTJSVariant tmp;\n\ttvclosure.AddRef();\n\ttjs_error er;\n\ttry\n\t{\n\t\ter = tvclosure.Object->PropGet(0, NULL, NULL, &tmp,\n\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t}\n\tcatch(...)\n\t{\n\t\ttvclosure.Release();\n\t\tthrow;\n\t}\n\ttvclosure.Release();\n\n\tif(TJS_SUCCEEDED(er))\n\t{\n\t\ttvclosure = tmp.AsObjectClosure();\n\t\ter =\n\t\t\ttvclosure.Object->FuncCall(flag, NULL, NULL, result,\n\t\t\t\tnumparams, param, TJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\ttvclosure.Release();\n\t}\n\treturn er;\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultFuncCall(tjs_uint32 flag, tTJSVariant &targ, tTJSVariant *result,\n\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(targ.Type() == tvtObject)\n\t{\n\t\ttjs_error er = TJS_E_INVALIDTYPE;\n\t\ttTJSVariantClosure tvclosure = targ.AsObjectClosure();\n\t\ttry\n\t\t{\n\t\t\tif(tvclosure.Object)\n\t\t\t{\n\t\t\t\t// bypass\n\t\t\t\ter =\n\t\t\t\t\ttvclosure.Object->FuncCall(flag, NULL, NULL, result,\n\t\t\t\t\t\tnumparams, param, TJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t\tif(er == TJS_E_INVALIDTYPE)\n\t\t\t\t{\n\t\t\t\t\t// retry using PropGet\n\t\t\t\t\ter = TJSTryFuncCallViaPropGet(tvclosure, flag, result,\n\t\t\t\t\t\tnumparams, param, objthis);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\ttvclosure.Release();\n\t\t\tthrow;\n\t\t}\n\t\ttvclosure.Release();\n\t\treturn er;\n\t}\n\n\treturn TJS_E_INVALIDTYPE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::FuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// this function is called as to call a default method,\n\t\t// but this object is not a function.\n\t\treturn TJS_E_INVALIDTYPE; // so returns TJS_E_INVALIDTYPE\n\t}\n\n\ttTJSSymbolData *data =  Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value_func;\n\t\t\tif(CallGetMissing(membername, value_func))\n\t\t\t\treturn TJSDefaultFuncCall(flag, value_func, result, numparams, param, objthis);\n\t\t}\n\n\t\treturn TJS_E_MEMBERNOTFOUND; // member not found\n\t}\n\n\treturn TJSDefaultFuncCall(flag, GetValue(data), result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultPropGet(tjs_uint32 flag, tTJSVariant &targ, tTJSVariant *result,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!(flag & TJS_IGNOREPROP))\n\t{\n\t\t// if TJS_IGNOREPROP is not specified\n\n\t\t// if member's type is tvtObject, call the object's PropGet with \"member=NULL\"\n\t\t//  ( default member invocation ). if it is succeeded, return its return value.\n\t\t// if the PropGet's return value is TJS_E_ACCESSDENYED,\n\t\t// return as an error, otherwise return the member itself.\n\t\tif(targ.Type() == tvtObject)\n\t\t{\n\t\t\ttTJSVariantClosure tvclosure = targ.AsObjectClosure();\n\t\t\ttjs_error hr = TJS_E_NOTIMPL;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(tvclosure.Object)\n\t\t\t\t{\n\t\t\t\t\thr = tvclosure.Object->PropGet(0, NULL, NULL, result,\n\t\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\ttvclosure.Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\ttvclosure.Release();\n\t\t\tif(TJS_SUCCEEDED(hr)) return hr;\n\t\t\tif(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t\treturn hr;\n\t\t}\n\t}\n\n\t// return the member itself\n\tif(!result) return TJS_E_INVALIDPARAM;\n\n\tresult->CopyRef(targ);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::PropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\tiTJSDispatch2 *objthis)\n{\n\tif(RebuildHashMagic != TJSGlobalRebuildHashMagic)\n\t{\n\t\tRebuildHash();\n\t}\n\n\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// this object itself has no information on PropGet with membername == NULL\n\t\treturn TJS_E_INVALIDTYPE;\n\t}\n\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value;\n\t\t\tif(CallGetMissing(membername, value))\n\t\t\t\treturn TJSDefaultPropGet(flag, value, result, objthis);\n\t\t}\n\t}\n\n\tif(!data && flag & TJS_MEMBERENSURE)\n\t{\n\t\t// create a member when TJS_MEMBERENSURE is specified\n\t\tdata = Add(membername, hint);\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\treturn TJSDefaultPropGet(flag, GetValue(data), result, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultPropSet(tjs_uint32 flag, tTJSVariant &targ, const tTJSVariant *param,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!(flag & TJS_IGNOREPROP))\n\t{\n\t\tif(targ.Type() == tvtObject)\n\t\t{\n\t\t\t// roughly the same as TJSDefaultPropGet\n\t\t\ttTJSVariantClosure tvclosure = targ.AsObjectClosure();\n\t\t\ttjs_error hr = TJS_E_NOTIMPL;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(tvclosure.Object)\n\t\t\t\t{\n\t\t\t\t\thr = tvclosure.Object->PropSet(0, NULL, NULL, param,\n\t\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\ttvclosure.Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\ttvclosure.Release();\n\t\t\tif(TJS_SUCCEEDED(hr)) return hr;\n\t\t\tif(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t\treturn hr;\n\t\t}\n\t}\n\n\t// normal substitution\n\tif(!param) return TJS_E_INVALIDPARAM;\n\n\ttarg.CopyRef(*param);\n\n\treturn TJS_S_OK;\n\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::PropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// no action is defined with the default member\n\t\treturn TJS_E_INVALIDTYPE;\n\t}\n\n\ttTJSSymbolData * data;\n\tif(CallMissing)\n\t{\n\t\tdata = Find(membername, hint);\n\t\tif(!data)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\tif(CallSetMissing(membername, *param))\n\t\t\t\treturn TJS_S_OK;\n\t\t}\n\t}\n\n\tif(flag & TJS_MEMBERENSURE)\n\t\tdata = Add(membername, hint); // create a member when TJS_MEMBERENSURE is specified\n\telse\n\t\tdata = Find(membername, hint);\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\tif(flag & TJS_HIDDENMEMBER)\n\t\tdata->SymFlags |= TJS_SYMBOL_HIDDEN;\n\telse\n\t\tdata->SymFlags &= ~TJS_SYMBOL_HIDDEN;\n\n\tif(flag & TJS_STATICMEMBER)\n\t\tdata->SymFlags |= TJS_SYMBOL_STATIC;\n\telse\n\t\tdata->SymFlags &= ~TJS_SYMBOL_STATIC;\n\n\t//-- below is mainly the same as TJSDefaultPropSet\n\n\tif(!(flag & TJS_IGNOREPROP))\n\t{\n\t\tif(GetValue(data).Type() == tvtObject)\n\t\t{\n\t\t\ttTJSVariantClosure tvclosure =\n\t\t\t\tGetValue(data).AsObjectClosureNoAddRef();\n\t\t\tif(tvclosure.Object)\n\t\t\t{\n\t\t\t\ttjs_error hr = tvclosure.Object->PropSet(0, NULL, NULL, param,\n\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t\tif(TJS_SUCCEEDED(hr)) return hr;\n\t\t\t\tif(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t\t\treturn hr;\n\t\t\t}\n\t\t\tdata = Find(membername, hint);\n\t\t}\n\t}\n\n\n\tif(!param) return TJS_E_INVALIDPARAM;\n\n\tCheckObjectClosureRemove(GetValue(data));\n\ttry\n\t{\n\t\tGetValue(data).CopyRef(*param);\n\t}\n\tcatch(...)\n\t{\n\t\tCheckObjectClosureAdd(GetValue(data));\n\t\tthrow;\n\t}\n\tCheckObjectClosureAdd(GetValue(data));\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::GetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(!result) return TJS_E_INVALIDPARAM;\n\n\t*result = Count;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::PropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// no action is defined with the default member\n\t\treturn TJS_E_INVALIDTYPE;\n\t}\n\n\ttTJSSymbolData * data;\n\tif(CallMissing)\n\t{\n\t\tdata = Find((const tjs_char *)(*membername), membername->GetHint());\n\t\tif(!data)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\tif(CallSetMissing((const tjs_char *)(*membername), *param))\n\t\t\t\treturn TJS_S_OK;\n\t\t}\n\t}\n\n\tif(flag & TJS_MEMBERENSURE)\n\t\tdata = Add(membername); // create a member when TJS_MEMBERENSURE is specified\n\telse\n\t\tdata = Find((const tjs_char *)(*membername), membername->GetHint());\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\tif(flag & TJS_HIDDENMEMBER)\n\t\tdata->SymFlags |= TJS_SYMBOL_HIDDEN;\n\telse\n\t\tdata->SymFlags &= ~TJS_SYMBOL_HIDDEN;\n\n\tif(flag & TJS_STATICMEMBER)\n\t\tdata->SymFlags |= TJS_SYMBOL_STATIC;\n\telse\n\t\tdata->SymFlags &= ~TJS_SYMBOL_STATIC;\n\n\t//-- below is mainly the same as TJSDefaultPropSet\n\n\tif(!(flag & TJS_IGNOREPROP))\n\t{\n\t\tif(GetValue(data).Type() == tvtObject)\n\t\t{\n\t\t\ttTJSVariantClosure tvclosure =\n\t\t\t\tGetValue(data).AsObjectClosureNoAddRef();\n\t\t\tif(tvclosure.Object)\n\t\t\t{\n\t\t\t\ttjs_error hr = tvclosure.Object->PropSet(0, NULL, NULL, param,\n\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t\tif(TJS_SUCCEEDED(hr)) return hr;\n\t\t\t\tif(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t\t\treturn hr;\n\t\t\t}\n\t\t\tdata = Find((const tjs_char *)(*membername), membername->GetHint());\n\t\t}\n\t}\n\n\n\tif(!param) return TJS_E_INVALIDPARAM;\n\n\tCheckObjectClosureRemove(GetValue(data));\n\ttry\n\t{\n\t\tGetValue(data).CopyRef(*param);\n\t}\n\tcatch(...)\n\t{\n\t\tCheckObjectClosureAdd(GetValue(data));\n\t\tthrow;\n\t}\n\tCheckObjectClosureAdd(GetValue(data));\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::EnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity()) return TJS_E_INVALIDOBJECT;\n\n\tInternalEnumMembers(flag, callback, objthis);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::DeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\treturn TJS_E_MEMBERNOTFOUND;\n\t}\n\n\tif(!DeleteByName(membername, hint)) return TJS_E_MEMBERNOTFOUND;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultInvalidate(tjs_uint32 flag, tTJSVariant &targ, iTJSDispatch2 *objthis)\n{\n\n\tif(targ.Type() == tvtObject)\n\t{\n\t\ttTJSVariantClosure tvclosure = targ.AsObjectClosureNoAddRef();\n\t\tif(tvclosure.Object)\n\t\t{\n\t\t\t// bypass\n\t\t\treturn\n\t\t\t\ttvclosure.Object->Invalidate(flag, NULL, NULL,\n\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t}\n\t}\n\n\treturn TJS_S_FALSE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::Invalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\tif(IsInvalidated) return TJS_S_FALSE;\n\t\t_Finalize();\n\t\treturn TJS_S_TRUE;\n\t}\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value;\n\t\t\tif(CallGetMissing(membername, value))\n\t\t\t\treturn TJSDefaultInvalidate(flag, value, objthis);\n\t\t}\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\treturn TJSDefaultInvalidate(flag, GetValue(data), objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultIsValid(tjs_uint32 flag, tTJSVariant &targ, iTJSDispatch2 * objthis)\n{\n\tif(targ.Type() == tvtObject)\n\t{\n\t\ttTJSVariantClosure tvclosure =targ.AsObjectClosureNoAddRef();\n\t\tif(tvclosure.Object)\n\t\t{\n\t\t\t// bypass\n\t\t\treturn\n\t\t\t\ttvclosure.Object->IsValid(flag, NULL, NULL,\n\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t}\n\t}\n\n\t// the target type is not tvtObject\n\treturn TJS_S_TRUE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::IsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis)\n{\n\tif(membername == NULL)\n\t{\n\t\tif(IsInvalidated) return TJS_S_FALSE;\n\t\treturn TJS_S_TRUE;\n\t}\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value;\n\t\t\tif(CallGetMissing(membername, value))\n\t\t\t\treturn TJSDefaultIsValid(flag, value, objthis);\n\t\t}\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\treturn TJSDefaultIsValid(flag, GetValue(data), objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultCreateNew(tjs_uint32 flag, tTJSVariant &targ,\n\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\tif(targ.Type() == tvtObject)\n\t{\n\t\ttTJSVariantClosure tvclosure = targ.AsObjectClosureNoAddRef();\n\t\tif(tvclosure.Object)\n\t\t{\n\t\t\t// bypass\n\t\t\treturn\n\t\t\t\ttvclosure.Object->CreateNew(flag, NULL, NULL, result, numparams,\n\t\t\t\t\tparam, TJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t}\n\t}\n\n\treturn TJS_E_INVALIDTYPE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::CreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// as an action of the default member, this object cannot create an object\n\t\t// because this object is not a class\n\t\treturn TJS_E_INVALIDTYPE;\n\t}\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value;\n\t\t\tif(CallGetMissing(membername, value))\n\t\t\t\treturn TJSDefaultCreateNew(flag, value, result, numparams, param, objthis);\n\t\t}\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\treturn TJSDefaultCreateNew(flag, GetValue(data), result, numparams, param, objthis);\n}\n//---------------------------------------------------------------------------\n/*\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::GetSuperClass(tjs_uint32 flag, iTJSDispatch2 **result,\n\t\tiTJSDispatch2 *objthis)\n{\n\t// TODO: GetSuperClass's reason for being\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\treturn TJS_E_NOTIMPL;\n}\n*/\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultIsInstanceOf(tjs_uint32 flag, tTJSVariant &targ, const tjs_char *name,\n\tiTJSDispatch2 *objthis)\n{\n\ttTJSVariantType vt;\n\tvt = targ.Type();\n\tif(vt == tvtVoid)\n\t{\n\t\treturn TJS_S_FALSE;\n\t}\n\n\tif(!TJS_strcmp(name, TJS_W(\"Object\"))) return TJS_S_TRUE;\n\n\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\treturn TJS_S_FALSE; // returns always false about tvtVoid\n\tcase tvtInteger:\n\tcase tvtReal:\n\t\tif(!TJS_strcmp(name, TJS_W(\"Number\"))) return TJS_S_TRUE;\n\t\treturn TJS_S_FALSE;\n\tcase tvtString:\n\t\tif(!TJS_strcmp(name, TJS_W(\"String\"))) return TJS_S_TRUE;\n\t\treturn TJS_S_FALSE;\n\tcase tvtOctet:\n\t\tif(!TJS_strcmp(name, TJS_W(\"Octet\"))) return TJS_S_TRUE;\n\t\treturn TJS_S_FALSE;\n\tcase tvtObject:\n\t\tif(vt == tvtObject)\n\t\t{\n\t\t\ttTJSVariantClosure tvclosure =targ.AsObjectClosureNoAddRef();\n\t\t\tif(tvclosure.Object)\n\t\t\t{\n\t\t\t\t// bypass\n\t\t\t\treturn\n\t\t\t\t\ttvclosure.Object->IsInstanceOf(flag, NULL, NULL, name,\n\t\t\t\t\t\tTJS_SELECT_OBJTHIS(tvclosure, objthis));\n\t\t\t}\n\t\t\treturn TJS_S_FALSE;\n\t\t}\n\t}\n\n\treturn TJS_S_FALSE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::IsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\tif(membername == NULL)\n\t{\n\t\t// always returns true if \"Object\" is specified\n\t\tif(!TJS_strcmp(classname, TJS_W(\"Object\")))\n\t\t{\n\t\t\treturn TJS_S_TRUE;\n\t\t}\n\n\t\t// look for the class instance information\n\t\tfor(tjs_uint i=0; i<ClassNames.size(); i++)\n\t\t{\n\t\t\tif(!TJS_strcmp(ClassNames[i].c_str(), classname))\n\t\t\t{\n\t\t\t\treturn TJS_S_TRUE;\n\t\t\t}\n\t\t}\n\n\t\treturn TJS_S_FALSE;\n\t}\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call 'missing' method\n\t\t\ttTJSVariant value;\n\t\t\tif(CallGetMissing(membername, value))\n\t\t\t\treturn TJSDefaultIsInstanceOf(flag, value, classname, objthis);\n\t\t}\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\treturn TJSDefaultIsInstanceOf(flag, GetValue(data), classname, objthis);\n}\n//---------------------------------------------------------------------------\ntjs_error TJSDefaultOperation(tjs_uint32 flag, tTJSVariant &targ,\n\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_uint32 op = flag & TJS_OP_MASK;\n\n\tif(op!=TJS_OP_INC && op!=TJS_OP_DEC && param == NULL)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\tif(op<TJS_OP_MIN || op>TJS_OP_MAX)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\tif(targ.Type() == tvtObject)\n\t{\n\t\t// the member may be a property handler if the member's type is \"tvtObject\"\n\t\t// so here try to access the object.\n\t\ttjs_error hr;\n\n\t\ttTJSVariantClosure tvclosure;\n\t\ttvclosure = targ.AsObjectClosureNoAddRef();\n\t\tif(tvclosure.Object)\n\t\t{\n\t\t\tiTJSDispatch2 * ot = TJS_SELECT_OBJTHIS(tvclosure, objthis);\n\n\t\t\ttTJSVariant tmp;\n\t\t\thr = tvclosure.Object->PropGet(0, NULL, NULL, &tmp, ot);\n\t\t\tif(TJS_SUCCEEDED(hr))\n\t\t\t{\n\t\t\t\tTJSDoVariantOperation(op, tmp, param);\n\n\t\t\t\thr = tvclosure.Object->PropSet(0, NULL, NULL, &tmp, ot);\n\t\t\t\tif(TJS_FAILED(hr)) return hr;\n\n\t\t\t\tif(result) result->CopyRef(tmp);\n\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t\telse if(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t{\n\t\t\t\treturn hr;\n\t\t\t}\n\n\t\t\t// normal operation is proceeded if \"PropGet\" is failed.\n\t\t}\n\t}\n\n\tTJSDoVariantOperation(op, targ, param);\n\n\tif(result) result->CopyRef(targ);\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::Operation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\tif(!GetValidity())\n\t\treturn TJS_E_INVALIDOBJECT;\n\n\t// operation about the member\n\t// processing line is the same as above function\n\n\tif(membername == NULL)\n\t{\n\t\treturn TJS_E_INVALIDTYPE;\n\t}\n\n\ttjs_uint32 op = flag & TJS_OP_MASK;\n\n\tif(op!=TJS_OP_INC && op!=TJS_OP_DEC && param == NULL)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\tif(op<TJS_OP_MIN || op>TJS_OP_MAX)\n\t\treturn TJS_E_INVALIDPARAM;\n\n\ttTJSSymbolData * data = Find(membername, hint);\n\n\tif(!data)\n\t{\n\t\tif(CallMissing)\n\t\t{\n\t\t\t// call default operation\n\t\t\treturn inherited::Operation(flag, membername, hint, result, param, objthis);\n\t\t}\n\t}\n\n\tif(!data) return TJS_E_MEMBERNOTFOUND; // not found\n\n\tif(GetValue(data).Type() == tvtObject)\n\t{\n\t\ttjs_error hr;\n\n\t\ttTJSVariantClosure tvclosure;\n\t\ttvclosure = GetValue(data).AsObjectClosureNoAddRef();\n\t\tif(tvclosure.Object)\n\t\t{\n\t\t\tiTJSDispatch2 * ot = TJS_SELECT_OBJTHIS(tvclosure, objthis);\n\n\t\t\ttTJSVariant tmp;\n\t\t\thr = tvclosure.Object->PropGet(0, NULL, NULL, &tmp, ot);\n\t\t\tif(TJS_SUCCEEDED(hr))\n\t\t\t{\n\t\t\t\tTJSDoVariantOperation(op, tmp, param);\n\n\t\t\t\thr = tvclosure.Object->PropSet(0, NULL, NULL, &tmp, ot);\n\t\t\t\tif(TJS_FAILED(hr)) return hr;\n\n\t\t\t\tif(result) result->CopyRef(tmp);\n\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t\telse if(hr != TJS_E_NOTIMPL && hr != TJS_E_INVALIDTYPE &&\n\t\t\t\thr != TJS_E_INVALIDOBJECT)\n\t\t\t{\n\t\t\t\treturn hr;\n\t\t\t}\n\t\t}\n\t}\n\n\n\tCheckObjectClosureRemove(GetValue(data));\n\n\ttTJSVariant &tmp = GetValue(data);\n\ttry\n\t{\n\t\tTJSDoVariantOperation(op, tmp, param);\n\t}\n\tcatch(...)\n\t{\n\t\tCheckObjectClosureAdd(GetValue(data));\n\t\tthrow;\n\t}\n\tCheckObjectClosureAdd(GetValue(data));\n\n\tif(result) result->CopyRef(tmp);\n\n\treturn TJS_S_OK;\n\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSCustomObject::NativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid,\n\t\tiTJSNativeInstance **pointer)\n{\n\tif(flag == TJS_NIS_GETINSTANCE)\n\t{\n\t\t// search \"classid\"\n\t\tfor(tjs_int i=0; i<TJS_MAX_NATIVE_CLASS; i++)\n\t\t{\n\t\t\tif(ClassIDs[i] == classid)\n\t\t\t{\n\t\t\t\t*pointer = ClassInstances[i];\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t}\n\t\treturn TJS_E_FAIL;\n\t}\n\n\tif(flag == TJS_NIS_REGISTER)\n\t{\n\t\t// search for the empty place\n\t\tfor(tjs_int i=0; i<TJS_MAX_NATIVE_CLASS; i++)\n\t\t{\n\t\t\tif(ClassIDs[i] == -1)\n\t\t\t{\n\t\t\t\t// found... writes there\n\t\t\t\tClassIDs[i] = classid;\n\t\t\t\tClassInstances[i] = *pointer;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t}\n\t\treturn TJS_E_FAIL;\n\t}\n\n\treturn TJS_E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD \ntTJSCustomObject::ClassInstanceInfo(tjs_uint32 flag, tjs_uint num, tTJSVariant *value)\n{\n\tswitch(flag)\n\t{\n\tcase TJS_CII_ADD:\n\t  {\n\t\t// add value\n\t\tttstr name = value->AsStringNoAddRef();\n\t\tif(TJSObjectHashMapEnabled() && ClassNames.size() == 0)\n\t\t\tTJSObjectHashSetType(this, TJS_W(\"instance of class \") + name);\n\t\t\t\t// First class name is used for the object classname\n\t\t\t\t// because the order of the class name\n\t\t\t\t// registration is from descendant to ancestor.\n\t\tClassNames.push_back(name);\n\t\treturn TJS_S_OK;\n\t  }\n\n\tcase TJS_CII_GET:\n\t  {\n\t\t// get value\n\t\tif(num>=ClassNames.size()) return TJS_E_FAIL;\n\t\t*value = ClassNames[num];\n\t\treturn TJS_S_OK;\n\t  }\n\n\tcase TJS_CII_SET_FINALIZE:\n\t  {\n\t\t// set 'finalize' method name\n\t\tfinalize_name = *value;\n\t\tCallFinalize = !finalize_name.IsEmpty();\n\t\treturn TJS_S_OK;\n\t  }\n\n\tcase TJS_CII_SET_MISSING:\n\t  {\n\t\t// set 'missing' method name\n\t\tmissing_name = *value;\n\t\tCallMissing = !missing_name.IsEmpty();\n\t\treturn TJS_S_OK;\n\t  }\n\n\n\t}\n\n\treturn TJS_E_NOTIMPL;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSCreateCustomObject\n//---------------------------------------------------------------------------\niTJSDispatch2 * TJSCreateCustomObject()\n{\n\t// utility function; returns newly created empty tTJSCustomObject\n\treturn new tTJSCustomObject();\n}\n//---------------------------------------------------------------------------\n\n\n}\n\n"
  },
  {
    "path": "src/core/tjs2/tjsObject.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TJS2 \"Object\" class implementation\n//---------------------------------------------------------------------------\n#ifndef tjsObjectH\n#define tjsObjectH\n\n#include <vector>\n#include \"tjsInterface.h\"\n#include \"tjsVariant.h\"\n#include \"tjsUtils.h\"\n#include \"tjsError.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// utility functions\n//---------------------------------------------------------------------------\nextern tjs_error\n\tTJSDefaultFuncCall(tjs_uint32 flag, tTJSVariant &targ, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\nextern tjs_error TJSDefaultPropGet(tjs_uint32 flag, tTJSVariant &targ, tTJSVariant *result,\n\tiTJSDispatch2 *objthis);\n\nextern tjs_error TJSDefaultPropSet(tjs_uint32 flag, tTJSVariant &targ, const tTJSVariant *param,\n\tiTJSDispatch2 *objthis);\n\nextern tjs_error\n\tTJSDefaultInvalidate(tjs_uint32 flag, tTJSVariant &targ, iTJSDispatch2 *objthis);\n\nextern tjs_error\n\tTJSDefaultIsValid(tjs_uint32 flag, tTJSVariant &targ, iTJSDispatch2 * objthis);\n\nextern tjs_error\n\tTJSDefaultCreateNew(tjs_uint32 flag, tTJSVariant &targ,\n\t\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *objthis);\n\nextern tjs_error\n\tTJSDefaultIsInstanceOf(tjs_uint32 flag, tTJSVariant &targ, const tjs_char *name,\n\t\tiTJSDispatch2 *objthis);\n\nextern tjs_error\n\tTJSDefaultOperation(tjs_uint32 flag, tTJSVariant &targ,\n\t\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis);\n\nTJS_EXP_FUNC_DEF(void, TJSDoVariantOperation, (tjs_int op, tTJSVariant &target, const tTJSVariant *param));\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// hash rebuilding\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TJSDoRehash, ());\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSDispatch\n//---------------------------------------------------------------------------\n/*\n\ttTJSDispatch is a base class that implements iTJSDispatch2, and every methods.\n\tmost methods are maked as simply returning \"TJS_E_NOTIMPL\";\n\tmethods, those access the object by index, call another methods that access\n\tthe object by string.\n*/\n/*\n#define TJS_SELECT_OBJTHIS(__closure__, __override__) \\\n\t((__closure__).ObjThis?((__override__)?(__override__):(__closure__).ObjThis):(__override__))\n*/\n#define TJS_SELECT_OBJTHIS(__closure__, __override__) \\\n\t((__closure__).ObjThis?(__closure__).ObjThis:(__override__))\n\nclass tTJSDispatch : public iTJSDispatch2\n{\n\tvirtual void BeforeDestruction(void) {;}\n\tbool BeforeDestructionCalled;\n\t\t// BeforeDestruction will be certainly called before object destruction\nprivate:\n\ttjs_uint RefCount;\npublic:\n\ttTJSDispatch();\n\tvirtual ~tTJSDispatch();\n\n//\tbool DestructionTrace;\n\npublic:\n\ttjs_uint TJS_INTF_METHOD  AddRef(void);\n\ttjs_uint TJS_INTF_METHOD  Release(void);\n\nprotected:\n\ttjs_uint GetRefCount() { return RefCount; }\n\npublic:\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCallByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGetByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\t\n\ttjs_error TJS_INTF_METHOD\n\tGetCount(\n\t\ttjs_int *result,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tGetCountByNum(\n\t\ttjs_int *result,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tEnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback, iTJSDispatch2 *objthis)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMember(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMemberByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidate(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidateByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValid(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValidByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char * membername,\n\t\ttjs_uint32 *hint,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNewByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams,\n\t\ttTJSVariant **param,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved1(\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis\n\t\t)\n\t{\n\t\treturn membername?TJS_E_MEMBERNOTFOUND:TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOfByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\tconst tjs_char *classname,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(\n\t\ttjs_uint32 flag,\n\t\tconst tjs_char *membername,\n\t\ttjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperationByNum(\n\t\ttjs_uint32 flag,\n\t\ttjs_int num,\n\t\ttTJSVariant *result,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis\n\t\t);\n\n\n\ttjs_error TJS_INTF_METHOD\n\tNativeInstanceSupport(\n\t\ttjs_uint32 flag,\n\t\ttjs_int32 classid,\n\t\tiTJSNativeInstance **pointer\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tClassInstanceInfo(\n\t\ttjs_uint32 flag,\n\t\ttjs_uint num,\n\t\ttTJSVariant *value\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved2(\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\ttjs_error TJS_INTF_METHOD\n\tReserved3(\n\t\t)\n\t{\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSCustomObject\n//---------------------------------------------------------------------------\n\n#define TJS_NAMESPACE_DEFAULT_HASH_BITS 3\n\nextern tjs_int TJSObjectHashBitsLimit;\n\t// this limits hash table size\n\n\n#define TJS_SYMBOL_USING\t0x1\n#define TJS_SYMBOL_INIT     0x2\n#define TJS_SYMBOL_HIDDEN   0x8\n#define TJS_SYMBOL_STATIC\t0x10\n\n#define TJS_MAX_NATIVE_CLASS 4\n/*\n\tNumber of \"Native Class Instance\" that can be used per a TJS Object is\n\tlimited as the number above.\n*/\n\n\nclass tTJSCustomObject : public tTJSDispatch\n{\n\ttypedef tTJSDispatch inherited;\n\n\t// tTJSSymbolData -----------------------------------------------------\npublic:\n\tstruct tTJSSymbolData\n\t{\n\t\ttTJSVariantString *Name; // name\n\t\ttjs_uint32 Hash; // hash code of the name\n\t\ttjs_uint32 SymFlags; // management flags\n\t\ttjs_uint32 Flags;  // flags\n\n\t\ttTJSVariant_S Value; // the value\n\t\t\t/*\n\t\t\t\tTTJSVariant_S must work with construction that fills\n\t\t\t\t\tall member to zero.\n\t\t\t*/\n\n\t\ttTJSSymbolData * Next; // next chain\n\n\t\tvoid SelfClear(void)\n\t\t{\n\t\t\tmemset(this, 0, sizeof(*this));\n\t\t\tSymFlags = TJS_SYMBOL_INIT;\n\t\t}\n\n\t\tvoid _SetName(const tjs_char * name)\n\t\t{\n\t\t\tif(Name) Name->Release(), Name = NULL;\n\t\t\tif(!name) TJS_eTJSError(TJSIDExpected);\n\t\t\tif(!name[0]) TJS_eTJSError(TJSIDExpected);\n\t\t\tName = TJSAllocVariantString(name);\n\t\t}\n\n\t\tvoid SetName(const tjs_char * name, tjs_uint32 hash)\n\t\t{\n\t\t\t_SetName(name);\n\t\t\tHash = hash;\n\t\t}\n\n\t\tvoid _SetName(tTJSVariantString *name)\n\t\t{\n\t\t\tif(name == Name) return;\n\t\t\tif(Name) Name->Release();\n\t\t\tName = name;\n\t\t\tif(Name) Name->AddRef();\n\t\t}\n\n\t\tvoid SetName(tTJSVariantString *name, tjs_uint32 hash)\n\t\t{\n\t\t\t_SetName(name);\n\t\t\tHash = hash;\n\t\t}\n\n\t\tconst tjs_char * GetName() const\n\t\t{\n\t\t\treturn (const tjs_char *)(*Name);\n\t\t}\n\n\t\tvoid PostClear()\n\t\t{\n\t\t\tif(Name) Name->Release(), Name = NULL;\n\t\t\t((tTJSVariant*)(&Value))->~tTJSVariant();\n\t\t\tmemset(&Value, 0, sizeof(Value));\n\t\t\tSymFlags &= ~TJS_SYMBOL_USING;\n\t\t}\n\n\t\tvoid Destory()\n\t\t{\n\t\t\tif(Name) Name->Release();\n\t\t\t((tTJSVariant*)(&Value))->~tTJSVariant();\n\t\t}\n\n\t\tbool NameMatch(const tjs_char * name)\n\t\t{\n\t\t\tconst tjs_char * this_name = GetName();\n\t\t\tif(this_name == name) return true;\n\t\t\treturn !TJS_strcmp(name, this_name);\n\t\t}\n\n\t\tvoid ReShare();\n\t};\n\n\n\n\t//---------------------------------------------------------------------\n\ttjs_int Count;\n\ttjs_int HashMask;\n\ttjs_int HashSize;\n\ttTJSSymbolData * Symbols;\n\ttjs_uint RebuildHashMagic;\n\tbool IsInvalidated;\n\tbool IsInvalidating;\n\tiTJSNativeInstance* ClassInstances[TJS_MAX_NATIVE_CLASS];\n\ttjs_int32 ClassIDs[TJS_MAX_NATIVE_CLASS];\n\n\n\tvoid _Finalize(void);\n\n\t//---------------------------------------------------------------------\nprotected:\n\tbool GetValidity() const { return !IsInvalidated; }\n\tbool CallFinalize; // set false if this object does not need to call \"finalize\"\n\tttstr finalize_name; // name of the 'finalize' method\n\tbool CallMissing; // set true if this object should call 'missing' method\n\tbool ProsessingMissing; // true if 'missing' method is being called\n\tttstr missing_name; // name of the 'missing' method\n\tvirtual void Finalize(void);\n\tstd::vector<ttstr > ClassNames;\n\n\t//---------------------------------------------------------------------\npublic:\n\n\ttTJSCustomObject(tjs_int hashbits = TJS_NAMESPACE_DEFAULT_HASH_BITS);\n\tvirtual ~tTJSCustomObject();\n\nprivate:\n\tvoid BeforeDestruction(void);\n\n\tvoid CheckObjectClosureAdd(const tTJSVariant &val)\n\t{\n\t\t// adjust the reference counter when the object closure's \"objthis\" is\n\t\t// referring to the object itself.\n\t\tif(val.Type() == tvtObject)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = val.AsObjectClosureNoAddRef().ObjThis;\n\t\t\tif(dsp == (iTJSDispatch2*)this) this->Release();\n\t\t}\n\t}\n\n\tvoid CheckObjectClosureRemove(const tTJSVariant &val)\n\t{\n\t\tif(val.Type() == tvtObject)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = val.AsObjectClosureNoAddRef().ObjThis;\n\t\t\tif(dsp == (iTJSDispatch2*)this) this->AddRef();\n\t\t}\n\t}\n\n\tbool CallGetMissing(const tjs_char *name, tTJSVariant &result);\n\tbool CallSetMissing(const tjs_char *name, const tTJSVariant &value);\n\n\ttTJSSymbolData * Add(const tjs_char * name, tjs_uint32 *hint);\n\t\t// Adds the symbol, returns the newly created data;\n\t\t// if already exists, returns the data.\n\n\ttTJSSymbolData * Add(tTJSVariantString * name);\n\t\t// tTJSVariantString version of above.\n\n\ttTJSSymbolData * AddTo(tTJSVariantString *name,\n\t\ttTJSSymbolData *newdata, tjs_int newhashmask);\n\t\t// Adds member to the new hash space, used in RebuildHash\n\n\tvoid RebuildHash(); // rebuild hash table\n\n\tbool DeleteByName(const tjs_char * name, tjs_uint32 *hint);\n\t\t// Deletes Name\n\n\tvoid DeleteAllMembers(void);\n\t\t// Deletes all members\n\tvoid _DeleteAllMembers(void);\n\t\t// Deletes all members ( not to use std::vector )\n\n\ttTJSSymbolData * Find(const tjs_char * name, tjs_uint32 *hint) ;\n\t\t// Finds Name, returns its data; if not found, returns NULL\n\n\tstatic bool CallEnumCallbackForData(tjs_uint32 flags,\n\t\ttTJSVariant ** params,\n\t\ttTJSVariantClosure & callback, iTJSDispatch2 * objthis,\n\t\tconst tTJSSymbolData * data);\n\tvoid InternalEnumMembers(tjs_uint32 flags, tTJSVariantClosure *callback,\n\t\tiTJSDispatch2 *objthis);\n\t//---------------------------------------------------------------------\npublic:\n\tvoid Clear() { DeleteAllMembers(); }\n\t/**\n\t * rebuild hash table\n\t */\n\tvoid RebuildHash( tjs_int requestcount );\n\n\t//---------------------------------------------------------------------\npublic:\n\ttjs_int GetValueInteger(const tjs_char * name, tjs_uint32 *hint);\n\t\t// service function for lexical analyzer\n\t//---------------------------------------------------------------------\npublic:\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t const tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tGetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint,\n\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tEnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidate(tjs_uint32 flag, const tjs_char *membername,  tjs_uint32 *hint,\n\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t iTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t const tjs_char *classname,\n\t\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t tTJSVariant *result,\n\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tNativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid,\n\t\tiTJSNativeInstance **pointer);\n\n\ttjs_error TJS_INTF_METHOD\n\tClassInstanceInfo(tjs_uint32 flag, tjs_uint num, tTJSVariant *value);\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TJSCreateCustomObject\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TJSCreateCustomObject, ());\n//---------------------------------------------------------------------------\n\n\n} // namespace TJS\n\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsObjectExtendable.cpp",
    "content": "//---------------------------------------------------------------------------\n// TJS2 \"ExtendableObject\" class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsObjectExtendable.h\"\n\nnamespace TJS\n{\n\ntTJSExtendableObject::~tTJSExtendableObject() {\n\tif( SuperClass ) {\n\t\tSuperClass->Release();\n\t\tSuperClass = NULL;\n\t}\n}\nvoid tTJSExtendableObject::SetSuper( iTJSDispatch2* dsp ) {\n\tif( SuperClass ) {\n\t\tSuperClass->Release();\n\t\tSuperClass = NULL;\n\t}\n\tSuperClass = dsp;\n\tSuperClass->AddRef();\n}\nvoid tTJSExtendableObject::ExtendsClass( iTJSDispatch2* global, const ttstr& classname ) {\n\ttTJSVariant val;\n\ttjs_error er = global->PropGet( TJS_MEMBERMUSTEXIST, classname.c_str(), NULL, &val, global );\n\tif( TJS_FAILED(er) ) TJSThrowFrom_tjs_error( er, classname.c_str() );\n\n\tSetSuper( val.AsObjectNoAddRef() );\n}\n\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::FuncCall( flag, membername, hint, result, numparams, param, objthis );\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->FuncCall( flag, membername, hint, result, numparams, param, objthis );\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::CreateNew(tjs_uint32 flag, const tjs_char * membername,\n\ttjs_uint32 *hint,\n\tiTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::CreateNew( flag, membername, hint, result, numparams, param, objthis );\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->CreateNew( flag, membername, hint, result, numparams, param, objthis );\n\t}\n\treturn hr;\n}\n\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::PropGet( tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result, iTJSDispatch2 *objthis )\n{\n\ttjs_error hr = inherited::PropGet( flag, membername, hint, result, objthis );\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->PropGet( flag, membername, hint, result, objthis );\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::PropSet( tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tTJSVariant *param, iTJSDispatch2 *objthis )\n{\n\ttjs_error hr = inherited::PropSet( flag, membername, hint, param, objthis );\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->PropSet( flag, membername, hint, param, objthis );\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::IsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tjs_char *classname, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->IsInstanceOf(flag, membername, hint, classname, objthis);\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::GetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::GetCount(result, membername, hint, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->GetCount(result, membername, hint, objthis);\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::DeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::DeleteMember( flag, membername, hint, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->DeleteMember( flag, membername, hint, objthis);\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::Invalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::Invalidate( flag, membername, hint, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->Invalidate( flag, membername, hint, objthis);\n\t}\n\tif( membername == NULL ) {\n\t\tSuperClass->Invalidate( flag, membername, hint, objthis);\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::IsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::IsValid( flag, membername, hint, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->IsValid( flag, membername, hint, objthis);\n\t}\n\treturn hr;\n}\n\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::Operation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis)\n{\n\ttjs_error hr = inherited::Operation( flag, membername, hint, result, param, objthis);\n\tif( hr == TJS_E_MEMBERNOTFOUND && SuperClass != NULL && membername != NULL ) {\n\t\thr = SuperClass->Operation( flag, membername, hint, result, param, objthis);\n\t}\n\treturn hr;\n}\n\ntjs_error TJS_INTF_METHOD\ntTJSExtendableObject::NativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid, iTJSNativeInstance **pointer) {\n\ttjs_error hr = inherited::NativeInstanceSupport( flag, classid, pointer );\n\tif( hr != TJS_S_OK && SuperClass != NULL && flag == TJS_NIS_GETINSTANCE ) {\n\t\thr = SuperClass->NativeInstanceSupport( flag, classid, pointer );\n\t}\n\treturn hr;\n}\ntjs_error TJS_INTF_METHOD tTJSExtendableObject::ClassInstanceInfo(tjs_uint32 flag, tjs_uint num, tTJSVariant *value) {\n\tif( flag == TJS_CII_SET_SUPRECLASS ) {\n\t\tSetSuper( value->AsObjectNoAddRef() );\n\t\treturn TJS_S_OK;\n\t} else if( flag == TJS_CII_GET_SUPRECLASS ) {\n\t\tif( SuperClass ) {\n\t\t\t*value = tTJSVariant(SuperClass,SuperClass);\n\t\t\treturn TJS_S_OK;\n\t\t} else {\n\t\t\treturn TJS_E_FAIL;\n\t\t}\n\t} else {\n\t\treturn inherited::ClassInstanceInfo( flag, num, value );\n\t}\n}\n\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsObjectExtendable.h",
    "content": "\n#ifndef tjsObjectExtendableH\n#define tjsObjectExtendableH\n\n#include \"tjsObject.h\"\n\nnamespace TJS\n{\n// dp̓T|[gȂ\nclass tTJSExtendableObject : public tTJSCustomObject {\n\ttypedef tTJSCustomObject inherited;\n\nprotected:\n\tiTJSDispatch2*\tSuperClass;\n\n\t/**\n\t * @param global : NXIuWFNg(ʂ̓O[o)\n\t * @param classname : NX\n\t */\n\tvoid ExtendsClass( iTJSDispatch2* global, const ttstr& classname );\npublic:\n\ttTJSExtendableObject() : SuperClass(NULL) {}\n\tvirtual ~tTJSExtendableObject();\n\n\tiTJSDispatch2* GetSuper() { return SuperClass; }\n\tconst iTJSDispatch2* GetSuper() const { return SuperClass; }\n\n\tvoid SetSuper( iTJSDispatch2* dsp );\n\n\ttjs_error TJS_INTF_METHOD\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, iTJSDispatch2 **result, tjs_int numparams,\n\t\ttTJSVariant **param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tPropGet( tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result, iTJSDispatch2 *objthis );\n\n\ttjs_error TJS_INTF_METHOD\n\tPropSet( tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tTJSVariant *param, iTJSDispatch2 *objthis );\n\n\ttjs_error TJS_INTF_METHOD\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tjs_char *classname, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tGetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tInvalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result, const tTJSVariant *param, iTJSDispatch2 *objthis);\n\n\ttjs_error TJS_INTF_METHOD\n\tNativeInstanceSupport(tjs_uint32 flag, tjs_int32 classid,\n\t\tiTJSNativeInstance **pointer);\n\n\t// X[p[NX̓o^Ǝ擾T|[g\n\ttjs_error TJS_INTF_METHOD \n\tClassInstanceInfo(tjs_uint32 flag, tjs_uint num, tTJSVariant *value);\n\n};\n} // namespace TJS\n#endif // tjsObjectExtendableH\n"
  },
  {
    "path": "src/core/tjs2/tjsOctPack.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include <map>\n#include <vector>\n#include <string>\n#include \"tjsArray.h\"\n#include \"tjsError.h\"\n\nnamespace TJS\n{\n\nenum OctPackType {\n\tOctPack_ascii,\t\t// a : ASCII string(k⊮)\n\tOctPack_ASCII,\t\t// A : ASCII string(Xy[X⊮)\n\tOctPack_bitstring,\t// b : bit string(ʃrbgʃrbg̏)\n\tOctPack_BITSTRING,\t// B : bit string(ʃrbg牺ʃrbg̏)\n\tOctPack_char,\t\t// c : t1oCgl(-128 ` 127)\n\tOctPack_CHAR,\t\t// C : 1oCgl(0`255)\n\tOctPack_double,\t\t// d : {x_\n\tOctPack_float,\t\t// f : Px_\n\tOctPack_hex,\t\t// h : hex string(low nybble first)\n\tOctPack_HEX,\t\t// H : hex string(high nybble first)\n\tOctPack_int,\t\t// i : tintl(ʏ4oCg)\n\tOctPack_INT,\t\t// I : intl(ʏ4oCg)\n\tOctPack_long,\t\t// l : tlongl(ʏ4oCg)\n\tOctPack_LONG,\t\t// L : longl(ʏ4oCg)\n\tOctPack_noshort,\t// n : shortl(lbg[NoCgI[_) network byte order short\n\tOctPack_NOLONG,\t\t// N : longl(lbg[NoCgI[_) network byte order long\n\tOctPack_pointer,\t// p : ւ̃|C^ null terminate char\n\tOctPack_POINTER,\t// P : \\(Œ蒷)ւ̃|C^ fix length char\n\tOctPack_short,\t\t// s : tshortl(ʏ2oCg) sign\n\tOctPack_SHORT,\t\t// S : shortl(ʏ2oCg) unsign\n\tOctPack_leshort,\t// v : gGfBAɂshortl little endian short\n\tOctPack_LELONG,\t\t// V : gGfBAɂlongl little endian long\n\tOctPack_uuencode,\t// u : uuencodeꂽ\n\tOctPack_BRE,\t\t// w : BERkꂽl\n\tOctPack_null,\t\t// x : k\n\tOctPack_NULL,\t\t// X : back up a byte\n\tOctPack_fill,\t\t// @ : Έʒu܂Ńk𖄂߂\n\tOctPack_base64,\t\t// m : Base64 encode / decode\n\tOctPack_EOT\n};\nstatic const tjs_char OctPackChar[OctPack_EOT] = {\n\tL'a',\n\tL'A',\n\tL'b',\n\tL'B',\n\tL'c',\n\tL'C',\n\tL'd',\n\tL'f',\n\tL'h',\n\tL'H',\n\tL'i',\n\tL'I',\n\tL'l',\n\tL'L',\n\tL'n',\n\tL'N',\n\tL'p',\n\tL'P',\n\tL's',\n\tL'S',\n\tL'v',\n\tL'V',\n\tL'u',\n\tL'w',\n\tL'x',\n\tL'X',\n\tL'@',\n\tL'm',\n};\nstatic bool OctPackMapInit = false;\nstatic std::map<tjs_char,tjs_int> OctPackMap;\nstatic void OctPackMapInitialize() {\n\tif( OctPackMapInit ) return;\n\tfor( tjs_int i = 0; i < OctPack_EOT; i++ ) {\n\t\tOctPackMap.insert( std::map<tjs_char,tjs_int>::value_type( OctPackChar[i], i ) );\n\t}\n\tOctPackMapInit = true;\n}\n\nstruct OctPackTemplate {\n\tOctPackType\tType;\n\ttjs_int\t\tLength;\n};\nstatic const tjs_char* ParseTemplateLength( OctPackTemplate& result, const tjs_char* c ) {\n\tif( *c ) {\n\t\tif( *c == L'*' ) {\n\t\t\tc++;\n\t\t\tresult.Length = -1;\t// tail list\n\t\t} else if( *c >= L'0' && *c <= L'9' ) {\n\t\t\ttjs_int num = 0;\n\t\t\twhile( *c && ( *c >= L'0' && *c <= L'9' ) ) {\n\t\t\t\tnum *= 10;\n\t\t\t\tnum += *c - L'0';\n\t\t\t\tc++;\n\t\t\t}\n\t\t\tresult.Length = num;\n\t\t} else {\n\t\t\tresult.Length = 1;\n\t\t}\n\t} else {\n\t\tresult.Length = 1;\n\t}\n\treturn c;\n}\n\nstatic void ParsePackTemplate( std::vector<OctPackTemplate>& result, const tjs_char* templ ) {\n\tOctPackMapInitialize();\n\n\tconst tjs_char* c = templ;\n\twhile( *c ) {\n\t\tstd::map<tjs_char,tjs_int>::iterator f = OctPackMap.find( *c );\n\t\tif( f == OctPackMap.end() ) {\n\t\t\tTJS_eTJSError( TJSUnknownPackUnpackTemplateCharcter );\n\t\t} else {\n\t\t\tc++;\n\t\t\tOctPackTemplate t;\n\t\t\tt.Type = static_cast<OctPackType>(f->second);\n\t\t\tc = ParseTemplateLength( t, c );\n\t\t\tresult.push_back( t );\n\t\t}\n\t}\n}\nstatic void AsciiToBin( std::vector<tjs_uint8>& bin, const ttstr& arg, tjs_nchar fillchar, tjs_int len ) {\n\tconst tjs_char* str = arg.c_str();\n\tif( len < 0 ) len = arg.length();\n\ttjs_int i = 0;\n\tfor( ; i < len && *str; str++, i++ ) {\n\t\tbin.push_back( (tjs_uint8)*str );\n\t}\n\tfor( ; i < len; i++ ) {\n\t\tbin.push_back( fillchar );\n\t}\n}\n// mtol : true : ʃrbg牺ʃrbg, false : ʃrbgʃrbg\n// w肵l̕傫ĂA͖̕\nstatic void BitStringToBin( std::vector<tjs_uint8>& bin, const ttstr& arg, bool mtol, tjs_int len ) {\n\tconst tjs_char* str = arg.c_str();\n\tif( len < 0 ) len = arg.length();\n\ttjs_uint8 val = 0;\n\ttjs_int pos = 0;\n\tif( mtol ) {\n\t\tpos = 7;\n\t\tfor( tjs_int i = 0; i < len && *str; str++, i++ ) {\n\t\t\tif( *str == L'0' ) {\n\t\t\t\t// val |= 0;\n\t\t\t} else if( *str == L'1' ) {\n\t\t\t\tval |= 1 << pos;\n\t\t\t} else {\n\t\t\t\tTJS_eTJSError( TJSUnknownBitStringCharacter );\n\t\t\t}\n\t\t\tif( pos == 0 ) {\n\t\t\t\tbin.push_back( val );\n\t\t\t\tpos = 7;\n\t\t\t\tval = 0;\n\t\t\t} else {\n\t\t\t\tpos--;\n\t\t\t}\n\t\t}\n\t\tif( pos < 7 ) {\n\t\t\tbin.push_back( val );\n\t\t}\n\t} else {\n\t\tfor( tjs_int i = 0; i < len && *str; str++, i++ ) {\n\t\t\tif( *str == L'0' ) {\n\t\t\t\t// val |= 0;\n\t\t\t} else if( *str == L'1' ) {\n\t\t\t\tval |= 1 << pos;\n\t\t\t} else {\n\t\t\t\tTJS_eTJSError( TJSUnknownBitStringCharacter );\n\t\t\t}\n\t\t\tif( pos == 7 ) {\n\t\t\t\tbin.push_back( val );\n\t\t\t\tpos = val = 0;\n\t\t\t} else {\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\t\tif( pos ) {\n\t\t\tbin.push_back( val );\n\t\t}\n\t}\n}\n// mtol\nstatic void HexToBin( std::vector<tjs_uint8>& bin, const ttstr& arg, bool mtol, tjs_int len ) {\n\tconst tjs_char* str = arg.c_str();\n\tif( len < 0 ) len = arg.length();\n\ttjs_uint8 val = 0;\n\ttjs_int pos = 0;\n\tif( mtol ) { // ʃju\n\t\tpos = 1;\n\t\tfor( tjs_int i = 0; i < len && *str; str++, i++ ) {\n\t\t\tif( *str >= L'0' && *str <= L'9' ) {\n\t\t\t\tval |= (*str - L'0') << (pos*4);\n\t\t\t} else if( *str >= L'a' && *str <= L'f' ) {\n\t\t\t\tval |= (*str - L'a' + 10) << (pos*4);\n\t\t\t} else if( *str >= L'A' && *str <= L'E' ) {\n\t\t\t\tval |= (*str - L'A' + 10) << (pos*4);\n\t\t\t} else {\n\t\t\t\tTJS_eTJSError( TJSUnknownHexStringCharacter  );\n\t\t\t}\n\t\t\tif( pos == 0 ) {\n\t\t\t\tbin.push_back( val );\n\t\t\t\tpos = 1;\n\t\t\t\tval = 0;\n\t\t\t} else {\n\t\t\t\tpos--;\n\t\t\t}\n\t\t}\n\t\tif( pos < 1 ) {\n\t\t\tbin.push_back( val );\n\t\t}\n\t} else { // ʃju\n\t\tfor( tjs_int i = 0; i < len && *str; str++, i++ ) {\n\t\t\tif( *str >= L'0' && *str <= L'9' ) {\n\t\t\t\tval |= (*str - L'0') << (pos*4);\n\t\t\t} else if( *str >= L'a' && *str <= L'f' ) {\n\t\t\t\tval |= (*str - L'a' + 10) << (pos*4);\n\t\t\t} else if( *str >= L'A' && *str <= L'E' ) {\n\t\t\t\tval |= (*str - L'A' + 10) << (pos*4);\n\t\t\t} else {\n\t\t\t\tTJS_eTJSError( TJSUnknownHexStringCharacter  );\n\t\t\t}\n\t\t\tif( pos ) {\n\t\t\t\tbin.push_back( val );\n\t\t\t\tpos = val = 0;\n\t\t\t} else {\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\t\tif( pos ) {\n\t\t\tbin.push_back( val );\n\t\t}\n\t}\n}\n// TRet : ŏIIɏo͂^\n// TTmp : ꎞIɏo͂^ variant ͈ꎞI tjs_int ɂȂƂȂȂ\ntemplate<typename TRet, typename TTmp, int NBYTE, typename TRetTmp>\nstatic void ReadNumberLE( std::vector<tjs_uint8>& result, const std::vector<tTJSVariant>& args, tjs_int numargs, tjs_int& argindex, tjs_int len ) {\n\tif( len < 0 ) len = numargs - argindex;\n\tif( (len+argindex) > numargs ) len = numargs - argindex;\n\tfor( tjs_int a = 0; a < len; a++ ) {\n\t\tTRet c = (TRet)(TTmp)args[argindex+a];\n\t\tTRetTmp val = *(TRetTmp*)&c;\n\t\tfor( int i = 0; i < NBYTE; i++ ) {\n\t\t\tTRetTmp tmp = ( val >> (i*8) ) & 0xFF;\n\t\t\tresult.push_back( (tjs_uint8)tmp ); // little endian\n\t\t}\n\t}\n\targindex += len-1;\n}\n\ntemplate<typename TRet, typename TTmp, int NBYTE, typename TRetTmp>\nstatic void ReadNumberBE( std::vector<tjs_uint8>& result, const std::vector<tTJSVariant>& args, tjs_int numargs, tjs_int& argindex, tjs_int len ) {\n\tif( len < 0 ) len = numargs - argindex;\n\tif( (len+argindex) > numargs ) len = numargs - argindex;\n\tfor( tjs_int a = 0; a < len; a++ ) {\n\t\tTRet c = (TRet)(TTmp)args[argindex+a];\n\t\tfor( int i = 0; i < NBYTE; i++ ) {\n\t\t\tresult.push_back( ((*(TRetTmp*)&c)&(0xFF<<((NBYTE-1-i)*8)))>>((NBYTE-1-i)*8) ); // big endian\n\t\t}\n\t}\n\targindex += len-1;\n}\n#if TJS_HOST_IS_BIG_ENDIAN\n#\tdefine ReadNumber ReadNumberBE\n#else\n#\tdefine ReadNumber ReadNumberLE\n#endif\n\n// from base64 plug-in (C) 2009 Kiyobee\n// ₷悤ɈꕔĂ\n//\tinbuf ̓e base64 GR[hāAoutbuf ɕƂďo\n//\toutbuf ̃TCÝAinsize / 4 * 3 Kv\n// outbuf ̃TCÝA(insize+2)/3 * 4 Kv\nstatic void encodeBase64( const tjs_uint8* inbuf, tjs_uint insize, std::wstring& outbuf) {\n\toutbuf.reserve( outbuf.size() + ((insize+2)/3) * 4 );\n\tstatic const char* base64str = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\ttjs_int\tinsize_3\t= insize - 3;\n\ttjs_int outptr\t\t= 0;\n\ttjs_int i;\n\tfor(i=0; i<=insize_3; i+=3)\n\t{\n\t\toutbuf.push_back( base64str[ (inbuf[i  ] >> 2) & 0x3F ] );\n\t\toutbuf.push_back( base64str[((inbuf[i  ] << 4) & 0x30) | ((inbuf[i+1] >> 4) & 0x0F)] );\n\t\toutbuf.push_back( base64str[((inbuf[i+1] << 2) & 0x3C) | ((inbuf[i+2] >> 6) & 0x03)] );\n\t\toutbuf.push_back( base64str[ (inbuf[i+2]     ) & 0x3F ] );\n\t}\n\tswitch(insize % 3)\n\t{\n\tcase 2:\n\t\toutbuf.push_back( base64str[ (inbuf[i  ] >> 2) & 0x3F ] );\n\t\toutbuf.push_back( base64str[((inbuf[i  ] << 4) & 0x30) | ((inbuf[i+1] >> 4) & 0x0F)] );\n\t\toutbuf.push_back( base64str[ (inbuf[i+1] << 2) & 0x3C ] );\n\t\toutbuf.push_back( '=' );\n\t\tbreak;\n\tcase 1:\n\t\toutbuf.push_back( base64str[ (inbuf[i  ] >> 2) & 0x3F ] );\n\t\toutbuf.push_back( base64str[ (inbuf[i  ] << 4) & 0x30 ] );\n\t\toutbuf.push_back(  '=' );\n\t\toutbuf.push_back(  '=' );\n\t\tbreak;\n\t}\n}\nstatic void decodeBase64( const ttstr& inbuf, std::vector<tjs_uint8>& outbuf ) {\n\ttjs_int len = (tjs_int)inbuf.length();\n\tconst tjs_char* data = inbuf.c_str();\n\tif( len < 4 ) { // too short\n\t\treturn;\n\t}\n\toutbuf.reserve( len / 4 * 3 );\n\tstatic const tjs_int base64tonum[] = {\n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  62,   0,   0,   0,  63, \n\t\t  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14, \n\t\t  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,   0,   0,   0,   0,   0, \n\t\t   0,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40, \n\t\t  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t\t   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0\n\t};\n\n\ttjs_int dptr = 0;\n\ttjs_int len_4 = len - 4;\n\twhile( dptr < len_4 ) {\n\t\toutbuf.push_back( static_cast<tjs_uint8>( (base64tonum[data[dptr]] << 2) | (base64tonum[data[dptr+1]] >> 4) ) );\n\t\tdptr++;\n\t\toutbuf.push_back( static_cast<tjs_uint8>( (base64tonum[data[dptr]] << 4) | (base64tonum[data[dptr+1]] >> 2) ) );\n\t\tdptr++;\n\t\toutbuf.push_back( static_cast<tjs_uint8>( (base64tonum[data[dptr]] << 6) | (base64tonum[data[dptr+1]]) ) );\n\t\tdptr+=2;\n\t}\n\toutbuf.push_back( static_cast<tjs_uint8>( (base64tonum[data[dptr]] << 2) | (base64tonum[data[dptr+1]] >> 4) )) ;\n\tdptr++;\n\ttjs_uint8 tmp = static_cast<tjs_uint8>( base64tonum[data[dptr++]] << 4 );\n\tif( data[dptr] != L'=' ) {\n\t\ttmp |= base64tonum[data[dptr]] >> 2;\n\t\toutbuf.push_back( tmp );\n\t\ttmp =  base64tonum[data[dptr++]] << 6;\n\t\tif( data[dptr] != L'=' ) {\n\t\t\ttmp |= base64tonum[data[dptr]];\n\t\t\toutbuf.push_back( tmp );\n\t\t}\n\t}\n}\n\nstatic tTJSVariantOctet* Pack( const std::vector<OctPackTemplate>& templ, const std::vector<tTJSVariant>& args ) {\n\ttjs_int numargs = static_cast<tjs_int>(args.size());\n\tstd::vector<tjs_uint8> result;\n\ttjs_size count = templ.size();\n\ttjs_int argindex = 0;\n\tfor( tjs_size i = 0; i < count && argindex < numargs; argindex++ ) {\n\t\tOctPackType t = templ[i].Type;\n\t\ttjs_int len = templ[i].Length;\n\t\tswitch( t ) {\n\t\tcase OctPack_ascii:\t\t// a : ASCII string(k⊮)\n\t\t\tAsciiToBin( result, args[argindex], '\\0', len );\n\t\t\tbreak;\n\t\tcase OctPack_ASCII:\t\t// A : ASCII string(Xy[X⊮)\n\t\t\tAsciiToBin( result, args[argindex], ' ', len );\n\t\t\tbreak;\n\t\tcase OctPack_bitstring:\t// b : bit string(ʃrbgʃrbg̏)\n\t\t\tBitStringToBin( result, args[argindex], false, len );\n\t\t\tbreak;\n\t\tcase OctPack_BITSTRING:\t// B : bit string(ʃrbg牺ʃrbg̏)\n\t\t\tBitStringToBin( result, args[argindex], true, len );\n\t\t\tbreak;\n\t\tcase OctPack_char:\t\t// c : t1oCgl(-128 ` 127)\n\t\t\tReadNumber<tjs_int8,tjs_int,1,tjs_int8>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_CHAR:\t\t// C : 1oCgl(0`255)\n\t\t\tReadNumber<tjs_uint8,tjs_int,1,tjs_uint8>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_double:\t// d : {x_\n\t\t\tReadNumber<tjs_real,tjs_real,8,tjs_uint64>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_float:\t\t// f : Px_\n\t\t\tReadNumber<float,tjs_real,4,tjs_uint32>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_hex:\t\t// h : hex string(low nybble first)\n\t\t\tHexToBin( result, args[argindex], false, len );\n\t\t\tbreak;\n\t\tcase OctPack_HEX:\t\t// H : hex string(high nybble first)\n\t\t\tHexToBin( result, args[argindex], true, len );\n\t\t\tbreak;\n\t\tcase OctPack_int:\t\t// i : tintl(ʏ4oCg)\n\t\tcase OctPack_long:\t\t// l : tlongl(ʏ4oCg)\n\t\t\tReadNumber<tjs_int,tjs_int,4,tjs_int32>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_INT:\t\t// I : intl(ʏ4oCg)\n\t\tcase OctPack_LONG:\t\t// L : longl(ʏ4oCg)\n\t\t\tReadNumber<tjs_uint,tjs_int64,4,tjs_uint32>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_noshort:\t// n : unsigned shortl(lbg[NoCgI[_) network byte order short\n\t\t\tReadNumberBE<tjs_uint16,tjs_int,2,tjs_uint16>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_NOLONG:\t// N : unsigned longl(lbg[NoCgI[_) network byte order long\n\t\t\tReadNumberBE<tjs_uint,tjs_int64,4,tjs_uint32>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_pointer:\t// p : ւ̃|C^ null terminate char\n\t\tcase OctPack_POINTER:\t// P : \\(Œ蒷)ւ̃|C^ fix length char\n\t\t\t// TODO\n\t\t\tbreak;\n\t\tcase OctPack_short:\t\t// s : tshortl(ʏ2oCg) sign\n\t\t\tReadNumber<tjs_int16,tjs_int,2,tjs_int16>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_SHORT:\t\t// S : shortl(ʏ2oCg) unsign\n\t\t\tReadNumber<tjs_uint16,tjs_int,2,tjs_uint16>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_leshort:\t// v : gGfBAɂunsigned shortl little endian short\n\t\t\tReadNumberLE<tjs_uint16,tjs_int,2,tjs_uint16>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_LELONG:\t// V : gGfBAɂunsigned longl little endian long\n\t\t\tReadNumberLE<tjs_uint,tjs_int64,4,tjs_uint32>( result, args, numargs, argindex, len );\n\t\t\tbreak;\n\t\tcase OctPack_uuencode:\t// u : uuencodeꂽ\n\t\t\tTJS_eTJSError( TJSNotSupportedUuencode );\n\t\t\tbreak;\n\t\tcase OctPack_BRE:\t\t// w : BERkꂽl\n\t\t\tTJS_eTJSError( TJSNotSupportedBER );\n\t\t\tbreak;\n\t\tcase OctPack_null:\t\t// x : k\n\t\t\tfor( tjs_int a = 0; a < len; a++ ) {\n\t\t\t\tresult.push_back( 0 );\n\t\t\t}\n\t\t\targindex--;\n\t\t\tbreak;\n\t\tcase OctPack_NULL:\t\t// X : back up a byte\n\t\t\tfor( tjs_int a = 0; a < len; a++ ) {\n\t\t\t\tresult.pop_back();\n\t\t\t}\n\t\t\targindex--;\n\t\t\tbreak;\n\t\tcase OctPack_fill: {\t\t// @ : Έʒu܂Ńk𖄂߂\n\t\t\ttjs_size count = result.size();\n\t\t\tfor( tjs_size i = count; i < (tjs_size)len; i++ ) {\n\t\t\t\tresult.push_back( 0 );\n\t\t\t}\n\t\t\targindex--;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_base64: {\t// m : Base64 encode / decode\n\t\t\tttstr tmp = args[argindex];\n\t\t\tdecodeBase64( tmp, result );\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_EOT:\n\t\t\tbreak;\n\t\t}\n\t\tif( len >= 0 ) { // '*' ̎-1AXg̖܂œǂ\n\t\t\ti++;\n\t\t}\n\t}\n\tif( result.size() > 0 )\n\t\treturn TJSAllocVariantOctet( &(result[0]), (tjs_uint)result.size() );\n\telse\n\t\treturn NULL;\n}\n\nstatic void BinToAscii( const tjs_uint8 *data, const tjs_uint8 *tail, tjs_uint len, ttstr& result ) {\n\t//std::vector<tjs_nchar> tmp(len+1);\n\tstd::vector<tjs_nchar> tmp;\n\ttmp.reserve(len+1);\n\tfor( tjs_int i = 0; i < static_cast<tjs_int>(len) && data != tail; data++, i++ ) {\n\t\tif( (*data) != '\\0' ) {\n\t\t\ttmp.push_back( (tjs_nchar)*data );\n\t\t}\n\t}\n\ttmp.push_back( (tjs_nchar)'\\0' );\n\tresult = tTJSString( &(tmp[0]) );\n}\n// mtol : true : ʃrbg牺ʃrbg, false : ʃrbgʃrbg\n// w肵l̕傫ĂA͖̕\nstatic void BinToBitString( const tjs_uint8 *data, const tjs_uint8 *tail, tjs_uint len, ttstr& result, bool mtol ) {\n\t//std::vector<tjs_char> tmp(len+1);\n\tstd::vector<tjs_char> tmp;\n\ttmp.reserve(len+1);\n\ttjs_int pos = 0;\n\tif( mtol ) {\n\t\tfor( ; data < tail; data++ ) {\n\t\t\tfor( tjs_int i = 0; i < 8 && pos < static_cast<tjs_int>(len); i++, pos++ ) {\n\t\t\t\tif( (*data)&(0x01<<(7-i)) ) {\n\t\t\t\t\ttmp.push_back( L'1' );\n\t\t\t\t} else {\n\t\t\t\t\ttmp.push_back( L'0' );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( pos >= static_cast<tjs_int>(len) ) break;\n\t\t}\n\t} else {\n\t\tfor( ; data < tail; data++ ) {\n\t\t\tfor( tjs_int i = 0; i < 8 && pos < static_cast<tjs_int>(len); i++, pos++ ) {\n\t\t\t\tif( (*data)&(0x01<<i) ) {\n\t\t\t\t\ttmp.push_back( L'1' );\n\t\t\t\t} else {\n\t\t\t\t\ttmp.push_back( L'0' );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( pos >= static_cast<tjs_int>(len) ) break;\n\t\t}\n\t}\n\ttmp.push_back( L'\\0' );\n\tresult = tTJSString( &(tmp[0]) );\n}\n\n// TRet : ŏIIɏo͂^\ntemplate<typename TRet, int NBYTE>\nstatic void BinToNumberLE( std::vector<TRet>& result, const tjs_uint8 *data, const tjs_uint8 *tail, tjs_int len ) {\n\tif( len < 0 ) len = (tjs_uint)(((tail - data)+NBYTE-1)/NBYTE);\n\tif( (data+len*NBYTE) < tail ) tail = data+len*NBYTE;\n\tTRet val = 0;\n\ttjs_uint bytes = 0;\n\tfor( ; data < tail; data++ ) {\n\t\tval |= (*data) << (bytes*8);\n\t\tif( bytes >= (NBYTE-1) ) { // little endian\n\t\t\tbytes = 0;\n\t\t\tresult.push_back( val );\n\t\t\tval = 0;\n\t\t} else {\n\t\t\tbytes++;\n\t\t}\n\t}\n\tif( bytes ) {\n\t\tresult.push_back( val );\n\t}\n}\n\ntemplate<typename TRet, typename TTmp, int NBYTE>\nstatic void BinToNumberLEReal( std::vector<TRet>& result, const tjs_uint8 *data, const tjs_uint8 *tail, tjs_int len ) {\n\tif( len < 0 ) len = (tjs_uint)(((tail - data)+NBYTE-1)/NBYTE);\n\tif( (data+len*NBYTE) < tail ) tail = data+len*NBYTE;\n\tTTmp val = 0;\n\ttjs_uint bytes = 0;\n\tfor( ; data < tail; data++ ) {\n\t\tval |= (TTmp)(*data) << (bytes*8);\n\t\tif( bytes >= (NBYTE-1) ) { // little endian\n\t\t\tbytes = 0;\n\t\t\tresult.push_back( *(TRet*)&val );\n\t\t\tval = 0;\n\t\t} else {\n\t\t\tbytes++;\n\t\t}\n\t}\n\tif( bytes ) {\n\t\tresult.push_back( *(TRet*)&val );\n\t}\n}\ntemplate<typename TRet, int NBYTE>\nstatic void BinToNumberBE( std::vector<TRet>& result, const tjs_uint8 *data, const tjs_uint8 *tail, tjs_int len ) {\n\tif( len < 0 ) len = (tjs_uint)(((tail - data)+NBYTE-1)/NBYTE);\n\tif( (data+len*NBYTE) < tail ) tail = data+len*NBYTE;\n\tTRet val = 0;\n\ttjs_uint bytes = NBYTE-1;\n\tfor( ; data < tail; data++ ) {\n\t\tval |= (*data) << (bytes*8);\n\t\tif( bytes == 0 ) { // big endian\n\t\t\tbytes = NBYTE-1;\n\t\t\tresult.push_back( val );\n\t\t\tval = 0;\n\t\t} else {\n\t\t\tbytes--;\n\t\t}\n\t}\n\tif( bytes < (NBYTE-1) ) {\n\t\tresult.push_back( val );\n\t}\n}\n\n#if TJS_HOST_IS_BIG_ENDIAN\n#\tdefine BinToNumber BinToNumberBE\n#else\n#\tdefine BinToNumber BinToNumberLE\n#\tdefine BinToReal BinToNumberLEReal\n#endif\n\n// mtol\nstatic void BinToHex( const tjs_uint8 *data, const tjs_uint8 *tail, tjs_uint len, ttstr& result, bool mtol ) {\n\tif( (data+len) < tail ) tail = data+(len+1)/2;\n\t//std::vector<tjs_char> tmp(len+1);\n\tstd::vector<tjs_char> tmp;\n\ttmp.reserve(len+1);\n\ttjs_int pos = 0;\n\tif( mtol ) { // ʃju\n\t\tpos = 1;\n\t\tfor( tjs_int i = 0; i < static_cast<tjs_int>(len) && data < tail; i++ ) {\n\t\t\ttjs_char ch = ((*data)&(0xF<<(pos*4)))>>(pos*4);\n\t\t\tif( ch > 9 ) {\n\t\t\t\tch = L'A' + (ch-10);\n\t\t\t} else {\n\t\t\t\tch = L'0' + ch;\n\t\t\t}\n\t\t\ttmp.push_back( ch );\n\t\t\tif( pos == 0 ) {\n\t\t\t\tpos = 1;\n\t\t\t\tdata++;\n\t\t\t} else {\n\t\t\t\tpos--;\n\t\t\t}\n\t\t}\n\t} else { // ʃju\n\t\tfor( tjs_int i = 0; i < static_cast<tjs_int>(len) && data < tail; i++ ) {\n\t\t\ttjs_char ch = ((*data)&(0xF<<(pos*4)))>>(pos*4);\n\t\t\tif( ch > 9 ) {\n\t\t\t\tch = L'A' + (ch-10);\n\t\t\t} else {\n\t\t\t\tch = L'0' + ch;\n\t\t\t}\n\t\t\ttmp.push_back( ch );\n\t\t\tif( pos ) {\n\t\t\t\tpos = 0;\n\t\t\t\tdata++;\n\t\t\t} else {\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\t}\n\ttmp.push_back( L'\\0' );\n\tresult = tTJSString( &(tmp[0]) );\n}\nstatic iTJSDispatch2* Unpack( const std::vector<OctPackTemplate>& templ, const tjs_uint8 *data, tjs_uint length ) {\n\ttTJSArrayObject* result = reinterpret_cast<tTJSArrayObject*>( TJSCreateArrayObject() );\n\ttTJSArrayNI *ni;\n\tif(TJS_FAILED(result->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJSGetArrayClassID(), (iTJSNativeInstance**)&ni)))\n\t\tTJS_eTJSError(TJSSpecifyArray);\n\n\tconst tjs_uint8 *current = data;\n\tconst tjs_uint8 *tail = data + length;\n\ttjs_size len = length;\n\ttjs_size count = templ.size();\n\ttjs_int argindex = 0;\n\tfor( tjs_int i = 0; i < (tjs_int)count && current < tail; argindex++ ) {\n\t\tOctPackType t = templ[i].Type;\n\t\ttjs_int len = templ[i].Length;\n\t\tswitch( t ) {\n\t\tcase OctPack_ascii:{ \t// a : ASCII string(k⊮)\n\t\t\tif( len < 0 ) len = (tail - current);\n\t\t\tttstr ret;\n\t\t\tBinToAscii( current, tail, (tjs_uint)len, ret );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += len;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_ASCII: {\t\t// A : ASCII string(Xy[X⊮)\n\t\t\tif( len < 0 ) len = (tail - current);\n\t\t\tttstr ret;\n\t\t\tBinToAscii( current, tail, (tjs_uint)len, ret );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += len;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_bitstring: {\t// b : bit string(ʃrbgʃrbg̏)\n\t\t\tif( len < 0 ) len = (tail - current)*8;\n\t\t\tttstr ret;\n\t\t\tBinToBitString( current, tail, (tjs_uint)len, ret, false );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += (len+7)/8;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_BITSTRING: {\t// B : bit string(ʃrbg牺ʃrbg̏)\n\t\t\tif( len < 0 ) len = (tail - current)*8;\n\t\t\tttstr ret;\n\t\t\tBinToBitString( current, tail, (tjs_uint)len, ret, true );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += (len+7)/8;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_char: {\t\t// c : t1oCgl(-128 ` 127)\n\t\t\tif( len < 0 ) len = tail - current;\n\t\t\tstd::vector<tjs_int8> ret;\n\t\t\tBinToNumber<tjs_int8,1>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_int8>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_CHAR: {\t\t// C : 1oCgl(0`255)\n\t\t\tif( len < 0 ) len = tail - current;\n\t\t\tstd::vector<tjs_uint8> ret;\n\t\t\tBinToNumber<tjs_uint8,1>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint8>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_double: {\t// d : {x_\n\t\t\tif( len < 0 ) len = (tail - current)/8;\n\t\t\tstd::vector<tjs_real> ret;\n\t\t\tBinToReal<tjs_real,tjs_uint64,8>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_real>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_real)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*8;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_float: {\t\t// f : Px_\n\t\t\tif( len < 0 ) len = (tail - current)/4;\n\t\t\tstd::vector<float> ret;\n\t\t\tBinToReal<float,tjs_uint32,4>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<float>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_real)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*4;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_hex: {\t\t// h : hex string(low nybble first)\n\t\t\tif( len < 0 ) len = (tail - current)*2;\n\t\t\tttstr ret;\n\t\t\tBinToHex( current, tail, (tjs_uint)len, ret, false );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += (len+1)/2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_HEX: {\t\t// H : hex string(high nybble first)\n\t\t\tif( len < 0 ) len = (tail - current)*2;\n\t\t\tttstr ret;\n\t\t\tBinToHex( current, tail, (tjs_uint)len, ret, true );\n\t\t\tresult->Add( ni, tTJSVariant( ret ) );\n\t\t\tcurrent += (len+1)/2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_int:\t\t// i : tintl(ʏ4oCg)\n\t\tcase OctPack_long: {\t// l : tlongl(ʏ4oCg)\n\t\t\tif( len < 0 ) len = (tail - current)/4;\n\t\t\tstd::vector<tjs_int> ret;\n\t\t\tBinToNumber<tjs_int,4>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_int>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*4;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_INT:\t\t// I : intl(ʏ4oCg)\n\t\tcase OctPack_LONG: {\t// L : longl(ʏ4oCg)\n\t\t\tif( len < 0 ) len = (tail - current)/4;\n\t\t\tstd::vector<tjs_uint> ret;\n\t\t\tBinToNumber<tjs_uint,4>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int64)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*4;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_noshort: {\t// n : unsigned shortl(lbg[NoCgI[_) network byte order short\n\t\t\tif( len < 0 ) len = (tail - current)/2;\n\t\t\tstd::vector<tjs_uint16> ret;\n\t\t\tBinToNumberBE<tjs_uint16,2>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint16>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_NOLONG: {\t// N : unsigned longl(lbg[NoCgI[_) network byte order long\n\t\t\tif( len < 0 ) len = ((tail - current)/4);\n\t\t\tstd::vector<tjs_uint> ret;\n\t\t\tBinToNumberBE<tjs_uint,4>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int64)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*4;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_pointer:\t// p : ւ̃|C^ null terminate char\n\t\t\tTJS_eTJSError( TJSNotSupportedUnpackLP );\n\t\t\tbreak;\n\t\tcase OctPack_POINTER:\t// P : \\(Œ蒷)ւ̃|C^ fix length char\n\t\t\tTJS_eTJSError( TJSNotSupportedUnpackP );\n\t\t\tbreak;\n\t\tcase OctPack_short: {\t// s : tshortl(ʏ2oCg) sign\n\t\t\tif( len < 0 ) len = ((tail - current)/2);\n\t\t\tstd::vector<tjs_int16> ret;\n\t\t\tBinToNumber<tjs_int16,2>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_int16>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_SHORT: {\t\t// S : shortl(ʏ2oCg) unsign\n\t\t\tif( len < 0 ) len = ((tail - current)/2);\n\t\t\tstd::vector<tjs_uint16> ret;\n\t\t\tBinToNumber<tjs_uint16,2>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint16>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_leshort: {\t// v : gGfBAɂunsigned shortl little endian short\n\t\t\tif( len < 0 ) len = ((tail - current)/2);\n\t\t\tstd::vector<tjs_uint16> ret;\n\t\t\tBinToNumberLE<tjs_uint16,2>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint16>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*2;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_LELONG: {\t// V : gGfBAɂunsigned longl little endian long\n\t\t\tif( len < 0 ) len = ((tail - current)/4);\n\t\t\tstd::vector<tjs_uint> ret;\n\t\t\tBinToNumberLE<tjs_uint,4>( ret, current, tail, (tjs_uint)len );\n\t\t\tfor( std::vector<tjs_uint>::const_iterator iter = ret.begin(); iter != ret.end(); iter++ ) {\n\t\t\t\tresult->Add( ni, tTJSVariant( (tjs_int64)*iter ) );\n\t\t\t}\n\t\t\tcurrent += len*4;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_uuencode:\t// u : uuencodeꂽ\n\t\t\tTJS_eTJSError( TJSNotSupportedUuencode );\n\t\t\tbreak;\n\t\tcase OctPack_BRE:\t\t// w : BERkꂽl\n\t\t\tTJS_eTJSError( TJSNotSupportedBER );\n\t\t\tbreak;\n\t\tcase OctPack_null:\t\t// x : k\n\t\t\tif( len < 0 ) len = (tail - current);\n\t\t\tfor( tjs_int x = 0; x < (tjs_int)len; x++ ) {\n\t\t\t\tcurrent++;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OctPack_NULL:\t\t// X : back up a byte\n\t\t\tif( len < 0 ) len = (current - data);\n\t\t\tfor( tjs_int x = 0; x < (tjs_int)len; x++ ) {\n\t\t\t\tif( data != current ) current--;\n\t\t\t\telse break;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OctPack_fill: {\t\t// @ : Έʒu܂Ńk𖄂߂\n\t\t\tif( len < 0 ) len = (tail - current);\n\t\t\tcurrent = &(data[len]);\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_base64: {\t// m : Base64 encode / decode\n\t\t\tstd::wstring ret;\n\t\t\tencodeBase64( current, (tjs_uint)(tail-current), ret );\n\t\t\tresult->Add( ni, tTJSVariant( ret.c_str() ) );\n\t\t\tcurrent = tail;\n\t\t\tbreak;\n\t\t}\n\t\tcase OctPack_EOT:\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\treturn result;\n}\n\n\n\ntjs_error TJSOctetPack( tTJSVariant **args, tjs_int numargs, const std::vector<tTJSVariant>& items, tTJSVariant *result ) {\n\tif( numargs < 1 ) return TJS_E_BADPARAMCOUNT;\n\tif( args[0]->Type() != tvtString ) return TJS_E_INVALIDPARAM;\n\n\tif( result ) {\n\t\tstd::vector<OctPackTemplate> templ;\n\t\tParsePackTemplate( templ, ((ttstr)*args[0]).c_str() );\n\t\ttTJSVariantOctet* oct = Pack( templ, items );\n\t\t*result = oct;\n\t\tif( oct ) oct->Release();\n\t\telse *result = tTJSVariant((iTJSDispatch2*)NULL,(iTJSDispatch2*)NULL);\n\t}\n\treturn TJS_S_OK;\n}\ntjs_error TJSOctetUnpack( const tTJSVariantOctet * target, tTJSVariant **args, tjs_int numargs, tTJSVariant *result ) {\n\tif( numargs < 1 ) return TJS_E_BADPARAMCOUNT;\n\tif( args[0]->Type() != tvtString ) return TJS_E_INVALIDPARAM;\n\tif( !target ) return TJS_E_INVALIDPARAM;\n\n\tif( result ) {\n\t\tstd::vector<OctPackTemplate> templ;\n\t\tParsePackTemplate( templ, ((ttstr)*args[0]).c_str() );\n\t\tiTJSDispatch2* disp = Unpack( templ, target->GetData(), target->GetLength() );\n\t\t*result = tTJSVariant(disp,disp);\n\t\tif( disp ) disp->Release();\n\t}\n\treturn TJS_S_OK;\n}\n\n} // namespace TJS\n"
  },
  {
    "path": "src/core/tjs2/tjsOctPack.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2013 T.Imoto and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n\n\n#ifndef tjsOctPackH\n#define tjsOctPackH\n\n\nnamespace TJS\n{\nextern tjs_error TJSOctetPack( tTJSVariant **args, tjs_int numargs, const std::vector<tTJSVariant>& items, tTJSVariant *result );\nextern tjs_error TJSOctetUnpack( const tTJSVariantOctet * target, tTJSVariant **args, tjs_int numargs, tTJSVariant *result );\n} // namespace TJS\n\n#endif // tjsOctPackH\n"
  },
  {
    "path": "src/core/tjs2/tjsRandomGenerator.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000-2005\t W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Math.RandomGenerator implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include <time.h>\n#include \"tjsError.h\"\n#include \"tjsRandomGenerator.h\"\n#include \"tjsDictionary.h\"\n#include \"tjsLex.h\"\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nvoid (*TJSGetRandomBits128)(void *dest) = NULL;\n\t// retrives 128-bits (16bytes) random bits for random seed.\n\t// this can be override application-specified routine, otherwise\n\t// TJS2 uses current time as a random seed.\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_RandomGenerator : TJS Native Instance : RandomGenerator\n//---------------------------------------------------------------------------\ntTJSNI_RandomGenerator::tTJSNI_RandomGenerator()\n{\n\t// C++ constructor\n\tGenerator = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_RandomGenerator::~tTJSNI_RandomGenerator()\n{\n\t// C++ destructor\n\tif(Generator) delete Generator;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_RandomGenerator::Randomize(tTJSVariant ** param, tjs_int numparams)\n{\n\tif(numparams == 0)\n\t{\n\t\t// parametor not given\n\t\tif(TJSGetRandomBits128)\n\t\t{\n\t\t\t// another random generator is given\n\t\t\ttjs_uint8 buf[32];\n\t\t\tunsigned long tmp[32];\n\t\t\tTJSGetRandomBits128(buf);\n\t\t\tTJSGetRandomBits128(buf+16);\n\t\t\tfor(tjs_int i = 0; i < 32; i++)\n\t\t\t\ttmp[i] = buf[i] + (buf[i] << 8) +\n\t\t\t\t(buf[1] << 16) + (buf[i] << 24);\n\n\t\t\tif(Generator) delete Generator, Generator = NULL;\n\t\t\tGenerator = new tTJSMersenneTwister(tmp, 32);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttime_t tm;\n\n\t\t\tif(Generator) delete Generator, Generator = NULL;\n\t\t\tGenerator = new tTJSMersenneTwister((unsigned long)time(&tm));\n\t\t}\n\t}\n\telse if(numparams >= 1)\n\t{\n\t\tif(param[0]->Type() == tvtObject)\n\t\t{\n\t\t\ttTJSMersenneTwisterData *data = NULL;\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// may be a reconstructible information\n\t\t\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\t\t\tif(!clo.Object) TJS_eTJSError(TJSNullAccess);\n\n\n\t\t\t\tttstr state;\n\t\t\t\ttTJSVariant val;\n\n\t\t\t\tdata = new tTJSMersenneTwisterData;\n\n\t\t\t\t// get state array\n\t\t\t\tTJS_THROW_IF_ERROR(clo.PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"state\"),\n\t\t\t\t\tNULL, &val, NULL));\n\n\t\t\t\tstate = val;\n\t\t\t\tif(state.GetLen() != TJS_MT_N * 8)\n\t\t\t\t\tTJS_eTJSError(TJSNotReconstructiveRandomizeData);\n\n\t\t\t\tconst tjs_char *p = state.c_str();\n\n\t\t\t\tfor(tjs_int i = 0; i < TJS_MT_N; i++)\n\t\t\t\t{\n\t\t\t\t\ttjs_uint32 n = 0;\n\t\t\t\t\ttjs_int tmp;\n\n\t\t\t\t\tfor(tjs_int j = 0; j < 8; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\ttmp = TJSHexNum(p[j]);\n\t\t\t\t\t\tif(tmp == -1)\n\t\t\t\t\t\t\tTJS_eTJSError(TJSNotReconstructiveRandomizeData);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tn <<= 4, n += tmp;\n\t\t\t\t\t}\n\n\t\t\t\t\tp += 8;\n\t\t\t\t\tdata->state[i] = (unsigned long)(n);\n\t\t\t\t}\n\n\t\t\t\t// get other members\n\t\t\t\tTJS_THROW_IF_ERROR(clo.PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"left\"), NULL,\n\t\t\t\t\t&val, NULL));\n\t\t\t\tdata->left = (tjs_int)val;\n\n\t\t\t\tTJS_THROW_IF_ERROR(clo.PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"next\"), NULL,\n\t\t\t\t\t&val, NULL));\n\t\t\t\tdata->next = (tjs_int)val + data->state;\n\n\t\t\t\tif(Generator) delete Generator, Generator = NULL;\n\t\t\t\tGenerator = new tTJSMersenneTwister(*data);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tif(data) delete data;\n\t\t\t\tTJS_eTJSError(TJSNotReconstructiveRandomizeData);\n\t\t\t}\n\t\t\tdelete data;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttjs_uint64 n = (tjs_int64)*param[0];\n\t\t\tunsigned long tmp[2];\n\t\t\ttmp[0] = (unsigned long)n;\n\t\t\ttmp[1] = (unsigned long)(n>>32);\n  \t\t\tif(Generator) delete Generator, Generator = NULL;\n\t\t\tGenerator = new tTJSMersenneTwister(tmp, 2);\n\t\t}\n\t}\n\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_RandomGenerator::Serialize()\n{\n\t// create dictionary object which has reconstructible information\n\t// which can be passed into constructor or randomize method.\n\tif(!Generator) return NULL;\n\n\n\tiTJSDispatch2 * dic = NULL;\n\ttTJSVariant val;\n\n\t// retrive tTJSMersenneTwisterData\n\tconst tTJSMersenneTwisterData & data = Generator->GetData();\n\n\ttry\n\t{\n\t\t// create 'state' string\n\t\tttstr state;\n\t\ttjs_char *p = state.AllocBuffer(TJS_MT_N * 8);\n\t\tfor(tjs_int i = 0; i < TJS_MT_N; i++)\n\t\t{\n\t\t\tconst static tjs_char hex[] = TJS_W(\"0123456789abcdef\");\n\t\t\tp[0] = hex[(data.state[i]  >> 28) & 0x000f];\n\t\t\tp[1] = hex[(data.state[i]  >> 24) & 0x000f];\n\t\t\tp[2] = hex[(data.state[i]  >> 20) & 0x000f];\n\t\t\tp[3] = hex[(data.state[i]  >> 16) & 0x000f];\n\t\t\tp[4] = hex[(data.state[i]  >> 12) & 0x000f];\n\t\t\tp[5] = hex[(data.state[i]  >>  8) & 0x000f];\n\t\t\tp[6] = hex[(data.state[i]  >>  4) & 0x000f];\n\t\t\tp[7] = hex[(data.state[i]  >>  0) & 0x000f];\n\t\t\tp += 8;\n\t\t}\n\t\tstate.FixLen();\n\n\t\t// create dictionary and store information\n\t\tdic = TJSCreateDictionaryObject();\n\n\t\tval = state;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"state\"), NULL, &val, dic);\n\n\t\tval = (tjs_int)data.left;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"left\"), NULL, &val, dic);\n\n\t\tval = (tjs_int)(data.next - data.state);\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"next\"), NULL, &val, dic);\n\t}\n\tcatch(...)\n\t{\n\t\tif(dic) dic->Release();\n\t\tthrow;\n\t}\n\treturn dic;\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_RandomGenerator::Random()\n{\n\t// returns double precision random value x, x is in 0 <= x < 1\n\tif(!Generator) return 0;\n\treturn Generator->rand_double();\n\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNI_RandomGenerator::Random32()\n{\n\t// returns 63 bit integer random value\n\tif(!Generator) return 0;\n\n\treturn Generator->int32();;\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTJSNI_RandomGenerator::Random63()\n{\n\t// returns 63 bit integer random value\n\tif(!Generator) return 0;\n\n\ttjs_uint64 v;\n\t((tjs_uint32 *)&v)[0]   = Generator->int32();\n\t((tjs_uint32 *)&v)[1]   = Generator->int32();\n\n\treturn v & TJS_UI64_VAL(0x7fffffffffffffff);\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTJSNI_RandomGenerator::Random64()\n{\n\t// returns 64 bit integer random value\n\tif(!Generator) return 0;\n\n\ttjs_uint64 v;\n\t((tjs_uint32 *)&v)[0]   = Generator->int32();\n\t((tjs_uint32 *)&v)[1]   = Generator->int32();\n\n\treturn v;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_RandomGenerator : TJS Native Class : RandomGenerator\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_RandomGenerator::ClassID = (tjs_uint32)-1;\ntTJSNC_RandomGenerator::tTJSNC_RandomGenerator() :\n\ttTJSNativeClass(TJS_W(\"RandomGenerator\"))\n{\n\t// class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/RandomGenerator)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator,\n\t/*TJS class name*/ RandomGenerator)\n{\n\t_this->Randomize(param, numparams);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/RandomGenerator)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/randomize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\t_this->Randomize(param, numparams);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/randomize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/random)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\t// returns 53-bit precision random value x, x is in 0 <= x < 1\n\n\tif(result)\n\t\t*result = _this->Random();\n\telse\n\t\t_this->Random(); // discard result\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/random)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/random32)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\t// returns 32-bit precision integer value x, x is in 0 <= x <= 4294967295\n\n\tif(result)\n\t\t*result = (tjs_int64)_this->Random32();\n\telse\n\t\t_this->Random32(); // discard result\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/random32)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/random63)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\t// returns 63-bit precision integer value x, x is in 0 <= x <= 9223372036854775807\n\n\tif(result)\n\t\t*result = _this->Random63();\n\telse\n\t\t_this->Random63(); // discard result\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/random63)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/random64)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\t// returns 64-bit precision integer value x, x is in\n\t// -9223372036854775808 <= x <= 9223372036854775807\n\n\tif(result)\n\t\t*result = _this->Random64();\n\telse\n\t\t_this->Random64(); // discard result\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/random64)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/serialize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RandomGenerator);\n\n\tif(result)\n\t{\n\t\tiTJSDispatch2 * dsp = _this->Serialize();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\tdsp->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/serialize)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_RandomGenerator::CreateNativeInstance()\n{\n\treturn new tTJSNI_RandomGenerator();\n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/tjs2/tjsRandomGenerator.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Math.RandomGenerator implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsRandomGeneratorH\n#define tjsRandomGeneratorH\n\n#include <time.h>\n#include \"tjsNative.h\"\n#include \"tjsMT19937ar-cok.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nextern void (*TJSGetRandomBits128)(void *dest);\n    // retrives 128-bits (16bytes) random bits for random seed.\n    // this can be override application-specified routine, otherwise\n    // TJS2 uses current time as a random seed.\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nclass tTJSNI_RandomGenerator : public tTJSNativeInstance\n{\npublic:\n\ttTJSNI_RandomGenerator();\n    ~tTJSNI_RandomGenerator();\nprivate:\n\ttTJSMersenneTwister *Generator;\n\npublic:\n\tiTJSDispatch2 * Serialize();\n\n\tvoid Randomize(tTJSVariant ** param, tjs_int numparams);\n\tdouble Random();\n\ttjs_uint32 Random32();\n\ttjs_int64 Random63();\n\ttjs_int64 Random64();\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\nclass tTJSNC_RandomGenerator : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_RandomGenerator();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsRegExp.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Regular Expression Support\n//---------------------------------------------------------------------------\n#ifndef TJS_NO_REGEXP\n#include \"tjsCommHead.h\"\n\n#include \"tjsRegExp.h\"\n#include \"tjsArray.h\"\n\n#include <functional>\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// Flags\n//---------------------------------------------------------------------------\n// some TJS flags\nconst tjs_uint32 globalsearch = (tjs_uint32)(((tjs_uint32)1)<<31);\nconst tjs_uint32 tjsflagsmask = (tjs_uint32)0xff000000;\n\n//---------------------------------------------------------------------------\nstatic tjs_uint32 TJSRegExpFlagToValue(tjs_char ch, tjs_uint32 prev)\n{\n\t// converts flag letter to internal flag value.\n\t// this returns modified prev.\n\t// when ch is '\\0', returns default flag value and prev is ignored.\n\n\tif(ch == 0) {\n\t\treturn ONIG_OPTION_DEFAULT|ONIG_OPTION_CAPTURE_GROUP|ONIG_OPTION_FIND_NOT_EMPTY;\n\t}\n\n\tswitch(ch)\n\t{\n\tcase TJS_W('g'): // global search\n\t\tprev|=globalsearch; return prev;\n\tcase TJS_W('i'): // ignore case\n\t\tprev|=ONIG_OPTION_IGNORECASE; return prev;\n\tcase TJS_W('l'): // use localized collation\n\t\t/*prev &= ~regbase::nocollate;*/ return prev; // ignore\n\tdefault:\n\t\treturn prev;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic tjs_uint32 TJSGetRegExpFlagsFromString(const tjs_char *string)\n{\n\t// returns a flag value represented by string\n\n\ttjs_uint32 flag = TJSRegExpFlagToValue(0, 0);\n\n\twhile(*string && *string != TJS_W('/'))\n\t{\n\t\tflag = TJSRegExpFlagToValue(*string, flag);\n\t\tstring++;\n\t}\n\n\treturn flag;\n}\n//---------------------------------------------------------------------------\nvoid replace_regex( tTJSVariant **param, tjs_int numparams, tTJSNI_RegExp *_this, iTJSDispatch2 *objthis, ttstr &res ) {\n\tttstr to;\n\ttTJSVariantClosure funcval;\n\tbool func;\n\tttstr target = *param[0];\n\tif(param[1]->Type() != tvtObject) {\n\t\tto = (*param[1]);\n\t\tfunc = false;\n\t} else {\n\t\tfuncval = param[1]->AsObjectClosureNoAddRef();\n\t\tif(funcval.ObjThis == NULL) {\n\t\t\t// replace with objthis when funcval's objthis is null\n\t\t\tfuncval.ObjThis = objthis;\n\t\t}\n\t\tfunc = true;\n\t}\n\t// grep thru target string\n\tbool isreplaceall = (_this->Flags & globalsearch) != 0;\n\tOnigRegion* region = onig_region_new();\n\tconst tjs_char* s = target.c_str();\n\tconst tjs_char* send = s + target.GetLen();\n\tint r = onig_search( _this->RegEx, (UChar*)s, (UChar*)send, (UChar*)s, (UChar*)send, region, ONIG_OPTION_NONE );\n\tint offset = 0;\n\tif( r >= 0 ) { // match\n\t\tdo {\n\t\t\ttjs_int pos = region->beg[0]/sizeof(tjs_char);\n\t\t\ttjs_int end = region->end[0]/sizeof(tjs_char);\n\t\t\tif( pos > 0 ) {\n\t\t\t\tres += ttstr(s,pos);\n\t\t\t}\n\t\t\tif( !func ) {\n\t\t\t\tres += to;\n\t\t\t} else {\n\t\t\t\t// call the callback function descripted as param[1]\n\t\t\t\ttTJSVariant result;\n\t\t\t\ttjs_error hr;\n\t\t\t\tiTJSDispatch2 *array = tTJSNC_RegExp::GetResultArray( true, s, _this, region );\n\t\t\t\ttTJSVariant arrayval(array, array);\n\t\t\t\ttTJSVariant *param = &arrayval;\n\t\t\t\tarray->Release();\n\t\t\t\thr = funcval.FuncCall(0, NULL, NULL, &result, 1, &param, NULL);\n\t\t\t\tif( TJS_FAILED(hr) ) {\n\t\t\t\t\tonig_region_free( region, 1  );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresult.ToString();\n\t\t\t\tres += result.GetString();\n\t\t\t}\n\t\t\ts += end;\n\t\t\tonig_region_free( region, 0  );\n\t\t} while( isreplaceall && s < send && onig_search( _this->RegEx, (UChar*)s, (UChar*)send, (UChar*)s, (UChar*)send, region, ONIG_OPTION_NONE ) >= 0 );\n\t\tif( s < send ) {\n\t\t\tres += ttstr(s,(int)(send-s));\n\t\t}\n\t} else {\n\t\tres += ttstr(s,(int)(send-s));\n\t}\n\tonig_region_free( region, 1  );\n}\n//---------------------------------------------------------------------------\niTJSDispatch2* split_regex( const ttstr &target, iTJSDispatch2 * array, tTJSNI_RegExp *_this, bool purgeempty ) {\n\ttjs_uint targlen = target.GetLen();\n\tOnigRegion* region = onig_region_new();\n\tconst tjs_char* s = target.c_str();\n\tconst tjs_char* send = s + targlen;\n\tint r = onig_search( _this->RegEx, (UChar*)s, (UChar*)send, (UChar*)s, (UChar*)send, region, ONIG_OPTION_NONE );\n\tint storecount = 0;\n\tif( r >= 0 ) { // match\n\t\tdo {\n\t\t\tint len = region->beg[0] / sizeof(tjs_char);\n\t\t\tif( !purgeempty || len > 0 ) {\n\t\t\t\ttTJSVariant val = ttstr( s, len );\n\t\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE, storecount++, &val, array);\n\t\t\t}\n\t\t\ts += region->end[0] / sizeof(tjs_char);\n\t\t\tonig_region_clear( region );\n\t\t} while( onig_search( _this->RegEx, (UChar*)s, (UChar*)send, (UChar*)s, (UChar*)send, region, ONIG_OPTION_NONE ) >= 0 );\n\t\tif( !purgeempty || s < send ) {\n\t\t\ttTJSVariant val = ttstr( s, (int)(send-s) );\n\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE, storecount++, &val, array);\n\t\t}\n\t} else {\n\t\ttTJSVariant val = ttstr( s, (int)(send-s) );\n\t\tarray->PropSetByNum(TJS_MEMBERENSURE, storecount++, &val, array);\n\t}\n\tonig_region_clear( region );\n\tonig_region_free( region, 1  );\n\treturn array;\n}\n//---------------------------------------------------------------------------\nvoid TJSReleaseRegex()\n{\n\tonig_end();\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTJSNI_RegExp : TJS Native Instance : RegExp\n//---------------------------------------------------------------------------\ntTJSNI_RegExp::tTJSNI_RegExp() : RegEx(NULL)\n{\n\t// C++constructor\n\tFlags = TJSRegExpFlagToValue(0, 0);\n\tStart = 0;\n\tIndex =0;\n\tLastIndex = 0;\n}\n//---------------------------------------------------------------------------\ntTJSNI_RegExp::~tTJSNI_RegExp() {\n\tif( RegEx ) {\n\t\tonig_free(RegEx);\n\t\tRegEx = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_RegExp::Split(iTJSDispatch2 ** array, const ttstr &target, bool purgeempty)\n{\n\tbool arrayallocated = false;\n\tif(!*array) *array = TJSCreateArrayObject(), arrayallocated = true;\n\n\ttry {\n\t\tsplit_regex( target, *array, this, purgeempty );\n\t} catch(...) {\n\t\tif(arrayallocated) (*array)->Release();\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTJSNC_RegExp : TJS Native Class : RegExp\n//---------------------------------------------------------------------------\ntTJSVariant tTJSNC_RegExp::LastRegExp;\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_RegExp::ClassID = (tjs_uint32)-1;\ntTJSNC_RegExp::tTJSNC_RegExp() :\n\ttTJSNativeClass(TJS_W(\"RegExp\"))\n{\n\t// class constructor\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/RegExp)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var. name*/_this, /*var. type*/tTJSNI_RegExp,\n\t/*TJS class name*/ RegExp)\n{\n\t/*\n\t\tTJS constructor\n\t*/\n\n\tif(numparams >= 1)\n\t{\n\t\ttTJSNC_RegExp::Compile(numparams, param, _this);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/RegExp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/compile)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\tcompiles given regular expression and flags.\n\t*/\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNC_RegExp::Compile(numparams, param, _this);\n\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/compile)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/_compile)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\tinternal function; compiles given constant regular expression.\n\t\tinput expression is following format:\n\t\t//flags/expression\n\t\twhere flags is flag letters ( [gil] )\n\t\tand expression is a Regular Expression\n\t*/\n\n\tif(numparams != 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr expr = *param[0];\n\n\tconst tjs_char *p = expr.c_str();\n\tif(!p || !p[0]) return TJS_E_FAIL;\n\n\tif(p[0] != TJS_W('/') || p[1] != TJS_W('/')) return TJS_E_FAIL;\n\n\tp+=2;\n\tconst tjs_char *exprstart = TJS_strchr(p, TJS_W('/'));\n\tif(!exprstart) return TJS_E_FAIL;\n\texprstart ++;\n\n\ttjs_uint32 flags = TJSGetRegExpFlagsFromString(p);\n\n\ttry\n\t{\n\t\tif( _this->RegEx ) {\n\t\t\tonig_free( _this->RegEx );\n\t\t\t_this->RegEx = NULL;\n\t\t}\n\t\tOnigErrorInfo einfo;\n\t\tint r = onig_new( &(_this->RegEx), (UChar*)exprstart, (UChar*)(expr.c_str()+expr.length()),\n\t\t\tflags&((ONIG_OPTION_MAXBIT<<1)-1), ONIG_ENCODING_UTF16_LE, ONIG_SYNTAX_PERL, &einfo );\n\t\tif( r ) {\n\t\t\tchar s[ONIG_MAX_ERROR_MESSAGE_LEN];\n\t\t\tonig_error_code_to_str( (UChar* )s, r, &einfo );\n\t\t\tTJS_eTJSError( s );\n\t\t}\n\t}\n\tcatch(std::exception &e)\n\t{\n\t\tTJS_eTJSError(e.what());\n\t}\n\n\t_this->Flags = flags;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/_compile)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/test)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\tdo the text searching.\n\t\treturn match found ( true ), or not found ( false ).\n\t\tthis function *changes* internal status.\n\t*/\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr target(*param[0]);\n\tOnigRegion* region = onig_region_new();\n\tbool matched = tTJSNC_RegExp::Exec( region, target, _this );\n\tonig_region_free(region, 1  );\n\n\ttTJSNC_RegExp::LastRegExp = tTJSVariant(objthis, objthis);\n\n\tif(result)\n\t{\n\t\t*result = matched;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/test)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/match)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\tdo the text searching.\n\t\tthis function is the same as test, except for its return value.\n\t\tmatch returns an array that contains each matching part.\n\t\tif match failed, returns empty array. eg.\n\t\tany internal status will not be changed.\n\t*/\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\n\tif(result)\n\t{\n\t\tttstr target(*param[0]);\n\t\tOnigRegion* region = onig_region_new();\n\t\tbool matched = tTJSNC_RegExp::Match( region, target, _this );\n\t\tiTJSDispatch2 *array = tTJSNC_RegExp::GetResultArray(matched, target, _this, region);\n\t\tonig_region_free(region, 1  );\n\t\t*result = tTJSVariant(array, array);\n\t\tarray->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/match)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exec)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\tsame as the match except for the internal status' change.\n\t\tvar ar;\n\t\tvar pat = /:(\\d+):(\\d+):/g;\n\t\twhile((ar = pat.match(target)).count)\n\t\t{\n\t\t\t// ...\n\t\t}\n\t*/\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr target(*param[0]);\n\tOnigRegion* region = onig_region_new();\n\ttTJSNC_RegExp::Exec(region, target, _this);\n\tonig_region_free(region, 1  );\n\n\ttTJSNC_RegExp::LastRegExp = tTJSVariant(objthis, objthis);\n\n\tif(result)\n\t{\n\t\t*result = _this->Array;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/exec)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/replace)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\treplaces the string\n\n\t\tnewstring = /regexp/.replace(orgstring, newsubstring);\n\t\tnewsubstring can be:\n\t\t\t1. normal string ( literal or expression that respresents string )\n\t\t\t2. a function\n\t\tfunction is called as in RegExp's context, returns new substring.\n\n\t\tor\n\n\t\tnewstring = string.replace(/regexp/, newsubstring);\n\t\t\t( via String.replace method )\n\n\t\treplace method ignores start property, and does not change any\n\t\t\tinternal status.\n\t*/\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tttstr res;\n\treplace_regex( param, numparams, _this, objthis, res );\n\tif(result) *result = res;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/replace)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/split)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\n\t/*\n\t\treplaces the string\n\n\t\tarray = /regexp/.replace(targetstring, <reserved>, purgeempty);\n\n\t\tor\n\n\t\tarray = targetstring.split(/regexp/, <reserved>, purgeempty);\n\n\t\tor\n\n\t\tarray = [].split(/regexp/, targetstring, <reserved>, purgeempty);\n\n\t\tthis method does not update properties\n\t*/\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tttstr target(*param[0]);\n\n\tbool purgeempty = false;\n\tif(numparams >= 3) purgeempty = param[2]->operator bool();\n\n\tiTJSDispatch2 *array = NULL;\n\n\t_this->Split(&array, target, purgeempty);\n\n\tif(result) *result = tTJSVariant(array, array);\n\n\tarray->Release();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/split)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(matches)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->Array;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(matches)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(start)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = (tTVInteger)_this->Start;\n\t\treturn TJS_S_OK;\n\t}\n    TJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/* var. name */_this, /* var. type */tTJSNI_RegExp);\n\t\t_this->Start = (tjs_uint)(tTVInteger)*param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(start)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(index)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = (tTVInteger)_this->Index;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(index)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(lastIndex)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = (tTVInteger)_this->LastIndex;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(lastIndex)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(input)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->Input;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(input)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(lastMatch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->LastMatch;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(lastMatch)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(lastParen)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->LastParen;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(lastParen)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(leftContext)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->LeftContext;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(leftContext)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(rightContext)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_RegExp);\n\t\t*result = _this->RightContext;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(rightContext)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(last)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = tTJSNC_RegExp::LastRegExp;;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(last)\n//---------------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_RegExp::CreateNativeInstance()\n{\n\treturn new tTJSNI_RegExp();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNC_RegExp::Compile(tjs_int numparams, tTJSVariant **param, tTJSNI_RegExp *_this)\n{\n\tttstr expr = *param[0];\n\n\ttjs_uint32 flags;\n\tif( numparams >= 2 ) {\n\t\tttstr fs = *param[1];\n\t\tflags = TJSGetRegExpFlagsFromString(fs.c_str());\n\t} else {\n\t\tflags = TJSRegExpFlagToValue(0, 0);\n\t}\n\n\tif(expr.IsEmpty()) expr = TJS_W(\"(?:)\"); // generate empty regular expression\n\n\tif( _this->RegEx ) {\n\t\tonig_free( _this->RegEx );\n\t\t_this->RegEx = NULL;\n\t}\n\tOnigErrorInfo einfo;\n\tint r = onig_new( &(_this->RegEx), (UChar*)expr.c_str(), (UChar*)(expr.c_str()+expr.length()),\n\t\tflags&((ONIG_OPTION_MAXBIT<<1)-1), ONIG_ENCODING_UTF16_LE, ONIG_SYNTAX_PERL, &einfo );\n\tif( r ) {\n\t\tchar s[ONIG_MAX_ERROR_MESSAGE_LEN];\n\t\tonig_error_code_to_str( (UChar* )s, r, &einfo );\n\t\tTJS_eTJSError( s );\n\t}\n\t_this->Flags = flags;\n}\n//---------------------------------------------------------------------------\nbool tTJSNC_RegExp::Match(OnigRegion* region, const ttstr &target, tTJSNI_RegExp *_this)\n{\n\ttjs_uint searchstart;\n\ttjs_uint targlen = target.GetLen();\n\tif( _this->Start == targlen ) {\n\t\t// Start already reached at end\n\t\treturn false;  // returns true if empty\n\t} else if(_this->Start > targlen) {\n\t\t// Start exceeds target's length\n\t\treturn false;\n\t}\n\tsearchstart = _this->Start;\n\tint r = onig_search( _this->RegEx, (UChar* )(target.c_str()+searchstart), (UChar* )(target.c_str()+targlen),\n\t\t  (UChar* )(target.c_str()+searchstart), (UChar* )(target.c_str()+targlen),\n\t\t  region, ONIG_OPTION_NONE );\n\treturn r >= 0;\n}\n//---------------------------------------------------------------------------\nbool tTJSNC_RegExp::Exec(OnigRegion* region, const ttstr &target, tTJSNI_RegExp *_this)\n{\n\tbool matched = tTJSNC_RegExp::Match( region, target, _this);\n\tiTJSDispatch2 *array = tTJSNC_RegExp::GetResultArray(matched, target.c_str() + _this->Start, _this, region );\n\t_this->Array = tTJSVariant(array, array);\n\tarray->Release();\n\n\t_this->Input = target;\n\tif( !matched || region->num_regs <= 0 ) {\n\t\t_this->Index = _this->Start;\n\t\t_this->LastIndex = _this->Start;\n\t\t_this->LastMatch = ttstr();\n\t\t_this->LastParen = ttstr();\n\t\t_this->LeftContext = ttstr(target, _this->Start);\n\t} else {\n\t\tint num_regs = region->num_regs;\n\t\t_this->Index = _this->Start + region->beg[0];\n\t\tint lastindex = 0;\n\t\tfor( int i = 0; i < num_regs; i++ ) {\n\t\t\tif( lastindex < region->end[i] ) {\n\t\t\t\tlastindex = region->end[i];\n\t\t\t}\n\t\t}\n\t\t_this->LastIndex = _this->Start + lastindex/sizeof(tjs_char);\n\t\t_this->LastMatch = ttstr( target.c_str()+(region->beg[0]/sizeof(tjs_char)), (region->end[0] - region->beg[0])/sizeof(tjs_char));\n\t\ttjs_uint last = num_regs-1;\n\t\t_this->LastParen = ttstr( target.c_str()+(region->beg[last]/sizeof(tjs_char)), (region->end[last] - region->beg[last])/sizeof(tjs_char));\n\t\t_this->LeftContext = ttstr(target, _this->Start + (region->beg[0])/sizeof(tjs_char));\n\t\t_this->RightContext = ttstr(target.c_str() + _this->LastIndex);\n\t\tif(_this->Flags & globalsearch)\n\t\t{\n\t\t\t// global search flag changes the next search starting position.\n\t\t\ttjs_uint match_end = _this->LastIndex;\n\t\t\t_this->Start = match_end;\n\t\t}\n\t}\n\treturn matched;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNC_RegExp::GetResultArray( bool matched, const tjs_char *target, tTJSNI_RegExp *_this, const OnigRegion* region ) {\n\tiTJSDispatch2 *array = TJSCreateArrayObject();\n\tif( matched ) {\n\t\t//if(_this->RegEx->.empty()) {\n\t\tif( region->num_regs <= 0 ) {\n\t\t\ttTJSVariant val(TJS_W(\"\"));\n\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE|TJS_IGNOREPROP, 0, &val, array);\n\t\t} else {\n\t\t\ttjs_uint size = region->num_regs;\n\t\t\ttry {\n\t\t\t\tfor( tjs_uint i = 0; i < size; i++ ) {\n\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\tval = ttstr( target+(region->beg[i]/sizeof(tjs_char)), (region->end[i] - region->beg[i])/sizeof(tjs_char) );\n\t\t\t\t\tarray->PropSetByNum(TJS_MEMBERENSURE|TJS_IGNOREPROP, i, &val, array);\n\t\t\t\t}\n\t\t\t} catch(...) {\n\t\t\t\tarray->Release();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t}\n\treturn array;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * TJSCreateRegExpClass()\n{\n\treturn new tTJSNC_RegExp();\n}\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n\n#endif"
  },
  {
    "path": "src/core/tjs2/tjsRegExp.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Regular Expression Support\n//---------------------------------------------------------------------------\n#ifndef tjsRegExpH\n#define tjsRegExpH\n\n#ifndef TJS_NO_REGEXP\n#define ONIG_EXTERN extern\n#include \"oniguruma.h\"\n#include \"tjsNative.h\"\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// tTJSNI_RegExp\n//---------------------------------------------------------------------------\nclass tTJSNI_RegExp : public tTJSNativeInstance\n{\npublic:\n\tregex_t* RegEx;\n\t//OnigRegion* Region;\n\ttjs_uint32 Flags;\n\ttjs_uint Start;\n\ttTJSVariant Array;\n\ttjs_uint Index;\n\tttstr Input;\n\ttjs_uint LastIndex;\n\tttstr LastMatch;\n\tttstr LastParen;\n\tttstr LeftContext;\n\tttstr RightContext;\nprivate:\n\npublic:\n\ttTJSNI_RegExp();\n\t~tTJSNI_RegExp();\n\tvoid Split(iTJSDispatch2 ** array, const ttstr &target, bool purgeempty);\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_RegExp\n//---------------------------------------------------------------------------\nclass tTJSNC_RegExp : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_RegExp();\n\n\tstatic void Compile(tjs_int numparam, tTJSVariant **param, tTJSNI_RegExp *_this);\n\tstatic bool Match(OnigRegion* region, const ttstr &target, tTJSNI_RegExp *_this);\n\tstatic bool Exec(OnigRegion* region, const ttstr &target, tTJSNI_RegExp *_this);\n\tstatic iTJSDispatch2 * GetResultArray(bool matched, const tjs_char *target, tTJSNI_RegExp *_this, const OnigRegion* region );\n\tstatic iTJSDispatch2 * GetResultArray(bool matched, const ttstr &target, tTJSNI_RegExp *_this, const OnigRegion* region ) {\n\t\treturn GetResultArray(matched, target.c_str(), _this, region);\n\t}\n\nprivate:\n\ttTJSNativeInstance *CreateNativeInstance();\n\npublic:\n\tstatic tjs_uint32 ClassID;\n\n\tstatic tTJSVariant LastRegExp;\n};\n//---------------------------------------------------------------------------\nextern iTJSDispatch2 * TJSCreateRegExpClass();\nextern void TJSReleaseRegex();\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n#endif\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsScriptBlock.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script Block Management\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsScriptBlock.h\"\n#include \"tjsInterCodeGen.h\"\n#include \"tjsConstArrayData.h\"\n#include \"tjs.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\nint yyparse(void*);\n//---------------------------------------------------------------------------\n// tTJSScriptBlock\n//---------------------------------------------------------------------------\ntTJSScriptBlock::tTJSScriptBlock(tTJS * owner)\n{\n\tRefCount = 1;\n\tOwner = owner;\n\tOwner->AddRef();\n\n\tScript = NULL;\n\tName = NULL;\n\n\tInterCodeContext = NULL;\n\tTopLevelContext = NULL;\n\tLexicalAnalyzer = NULL;\n\n\tUsingPreProcessor = false;\n\n\tLineOffset = 0;\n\n\tOwner->AddScriptBlock(this);\n}\n//---------------------------------------------------------------------------\n// for Bytecode\ntTJSScriptBlock::tTJSScriptBlock( tTJS* owner,  const tjs_char* name, tjs_int lineoffset ) {\n\tRefCount = 1;\n\tOwner = owner;\n\tOwner->AddRef();\n\tName = NULL;\n\tif(name)\n\t{\n\t\tName = new tjs_char[ TJS_strlen(name) + 1];\n\t\tTJS_strcpy(Name, name);\n\t}\n\tLineOffset = lineoffset;\n\tScript = NULL;\n\n\tInterCodeContext = NULL;\n\tTopLevelContext = NULL;\n\tLexicalAnalyzer = NULL;\n\n\tUsingPreProcessor = false;\n\n\tOwner->AddScriptBlock(this);\n}\n//---------------------------------------------------------------------------\ntTJSScriptBlock::~tTJSScriptBlock()\n{\n\tif(TopLevelContext) TopLevelContext->Release(), TopLevelContext = NULL;\n\twhile(ContextStack.size())\n\t{\n\t\tContextStack.top()->Release();\n\t\tContextStack.pop();\n\t}\n\n\tOwner->RemoveScriptBlock(this);\n\n\tif(LexicalAnalyzer) delete LexicalAnalyzer;\n\n\tif(Script) delete [] Script;\n\tif(Name) delete [] Name;\n\n\tOwner->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::AddRef(void)\n{\n\tRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Release(void)\n{\n\tif(RefCount <= 1)\n\t\tdelete this;\n\telse\n\t\tRefCount--;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::SetName(const tjs_char *name, tjs_int lineofs)\n{\n\tif(Name) delete [] Name, Name = NULL;\n\tif(name)\n\t{\n\t\tLineOffset = lineofs;\n\t\tName = new tjs_char[ TJS_strlen(name) + 1];\n\t\tTJS_strcpy(Name, name);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Add(tTJSInterCodeContext * cntx)\n{\n\tInterCodeContextList.push_back(cntx);\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Remove(tTJSInterCodeContext * cntx)\n{\n\tInterCodeContextList.remove(cntx);\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSScriptBlock::GetTotalVMCodeSize() const\n{\n\ttjs_uint size = 0;\n\n\tstd::list<tTJSInterCodeContext *>::const_iterator i;\n\tfor(i = InterCodeContextList.begin(); i != InterCodeContextList.end(); i++)\n\t{\n\t\tsize += (*i)->GetCodeSize();\n\t}\n\treturn size;\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSScriptBlock::GetTotalVMDataSize() const\n{\n\ttjs_uint size = 0;\n\n\tstd::list<tTJSInterCodeContext *>::const_iterator i;\n\tfor(i = InterCodeContextList.begin(); i != InterCodeContextList.end(); i++)\n\t{\n\t\tsize += (*i)->GetDataSize();\n\t}\n\treturn size;\n}\n//---------------------------------------------------------------------------\nconst tjs_char * tTJSScriptBlock::GetLine(tjs_int line, tjs_int *linelength) const\n{\n\tif( Script == NULL ) {\n\t\t*linelength = 10;\n\t\treturn TJS_W(\"Bytecode.\");\n\t}\n\t// note that this function DOES matter LineOffset\n\tline -= LineOffset;\n\tif(linelength) *linelength = LineLengthVector[line];\n\treturn Script + LineVector[line];\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSScriptBlock::SrcPosToLine(tjs_int pos) const\n{\n\ttjs_uint s = 0;\n\ttjs_uint e = (tjs_uint)LineVector.size();\n\twhile(true)\n\t{\n\t\tif(e-s <= 1) return s + LineOffset; // LineOffset is added\n\t\ttjs_uint m = s + (e-s)/2;\n\t\tif(LineVector[m] > pos)\n\t\t\te = m;\n\t\telse\n\t\t\ts = m;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSScriptBlock::LineToSrcPos(tjs_int line) const\n{\n\t// assumes line is added by LineOffset\n\tline -= LineOffset;\n\treturn LineVector[line];\n}\n//---------------------------------------------------------------------------\nttstr tTJSScriptBlock::GetLineDescriptionString(tjs_int pos) const\n{\n\t// get short description, like \"mainwindow.tjs(321)\"\n\t// pos is in character count from the first of the script\n\ttjs_int line =SrcPosToLine(pos)+1;\n\tttstr name;\n\tif(Name)\n\t{\n\t\tname = Name;\n\t}\n\telse\n\t{\n\t\ttjs_char ptr[128];\n\t\tTJS_snprintf(ptr, sizeof(ptr)/sizeof(tjs_char), TJS_W(\"0x%p\"), this);\n\t\tname = ttstr(TJS_W(\"anonymous@\")) + ptr;\n\t}\n\n\treturn name + TJS_W(\"(\") + ttstr(line) + TJS_W(\")\");\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::ConsoleOutput(const tjs_char *msg, void *data)\n{\n\ttTJSScriptBlock *blk = (tTJSScriptBlock*)data;\n\tblk->Owner->OutputToConsole(msg);\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_PROFILE_TIME\ntjs_uint parsetime = 0;\nextern tjs_uint time_make_np;\nextern tjs_uint time_PutData;\nextern tjs_uint time_PutCode;\nextern tjs_uint time_this_proxy;\nextern tjs_uint time_Commit;\nextern tjs_uint time_yylex;\nextern tjs_uint time_GenNodeCode;\n\nextern tjs_uint time_ns_Push;\nextern tjs_uint time_ns_Pop;\nextern tjs_uint time_ns_Find;\nextern tjs_uint time_ns_Add;\nextern tjs_uint time_ns_Remove;\nextern tjs_uint time_ns_Commit;\n\n#endif\n\nvoid tTJSScriptBlock::SetText(tTJSVariant *result, const tjs_char *text,\n\tiTJSDispatch2 * context, bool isexpression)\n{\n\tTJS_F_TRACE(\"tTJSScriptBlock::SetText\");\n\n\n\t// compiles text and executes its global level scripts.\n\t// the script will be compiled as an expression if isexpressn is true.\n\tif(!text) return;\n\tif(!text[0]) return;\n\n\tTJS_D((TJS_W(\"Counting lines ...\\n\")))\n\n\tScript = new tjs_char[TJS_strlen(text)+1];\n\tTJS_strcpy(Script, text);\n\n\t// calculation of line-count\n\ttjs_char *ls = Script;\n\ttjs_char *p = Script;\n\twhile(*p)\n\t{\n\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n'))\n\t\t{\n\t\t\tLineVector.push_back(int(ls - Script));\n\t\t\tLineLengthVector.push_back(int(p - ls));\n\t\t\tif(*p == TJS_W('\\r') && p[1] == TJS_W('\\n')) p++;\n\t\t\tp++;\n\t\t\tls = p;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tp++;\n\t\t}\n\t}\n\n\tif(p!=ls)\n\t{\n\t\tLineVector.push_back(int(ls - Script));\n\t\tLineLengthVector.push_back(int(p - ls));\n\t}\n\n\ttry\n\t{\n\n\t\t// parse and execute\n#ifdef TJS_DEBUG_PROFILE_TIME\n\t\t{\n\t\ttTJSTimeProfiler p(parsetime);\n#endif\n\n\t\tParse(text, isexpression, result != NULL);\n\n#ifdef TJS_DEBUG_PROFILE_TIME\n\t\t}\n\n\t\t{\n\t\t\tchar buf[256];\n\t\t\tTJS_nsprintf(buf, \"parsing : %d\", parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tif(parsetime)\n\t\t\t{\n\t\t\tTJS_nsprintf(buf, \"Commit : %d (%d%%)\", time_Commit, time_Commit*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"yylex : %d (%d%%)\", time_yylex, time_yylex*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"MakeNP : %d (%d%%)\", time_make_np, time_make_np*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"GenNodeCode : %d (%d%%)\", time_GenNodeCode, time_GenNodeCode*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"  PutCode : %d (%d%%)\", time_PutCode, time_PutCode*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"  PutData : %d (%d%%)\", time_PutData, time_PutData*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"  this_proxy : %d (%d%%)\", time_this_proxy, time_this_proxy*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\n\t\t\tTJS_nsprintf(buf, \"ns::Push : %d (%d%%)\", time_ns_Push, time_ns_Push*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"ns::Pop : %d (%d%%)\", time_ns_Pop, time_ns_Pop*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"ns::Find : %d (%d%%)\", time_ns_Find, time_ns_Find*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"ns::Remove : %d (%d%%)\", time_ns_Remove, time_ns_Remove*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\t\t\tTJS_nsprintf(buf, \"ns::Commit : %d (%d%%)\", time_ns_Commit, time_ns_Commit*100/parsetime);\n\t\t\tOutputDebugString(buf);\n\n\t\t\t}\n\t\t}\n#endif\n\n#ifdef TJS_DEBUG_DISASM\n\t\tstd::list<tTJSInterCodeContext *>::iterator i =\n\t\t\tInterCodeContextList.begin();\n\t\twhile(i != InterCodeContextList.end())\n\t\t{\n\t\t\tConsoleOutput(TJS_W(\"\"), (void*)this);\n\t\t\tConsoleOutput((*i)->GetName(), (void*)this);\n\t\t\t(*i)->Disassemble(ConsoleOutput, (void*)this);\n\t\t\ti++;\n\t\t}\n#endif\n\n\t\t// execute global level script\n\t\tExecuteTopLevelScript(result, context);\n\t}\n\tcatch(...)\n\t{\n\t\tif(InterCodeContextList.size() != 1)\n\t\t{\n\t\t\tif(TopLevelContext) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\t\twhile(ContextStack.size())\n\t\t\t{\n\t\t\t\tContextStack.top()->Release();\n\t\t\t\tContextStack.pop();\n\t\t\t}\n\t\t}\n\t\tthrow;\n\t}\n\n\tif(InterCodeContextList.size() != 1)\n\t{\n\t\t// this is not a single-context script block\n\t\t// (may hook itself)\n\t\t// release all contexts and global at this time\n\t\tif(TopLevelContext) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\twhile(ContextStack.size())\n\t\t{\n\t\t\tContextStack.top()->Release();\n\t\t\tContextStack.pop();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n// for Bytecode\nvoid tTJSScriptBlock::ExecuteTopLevel( tTJSVariant *result, iTJSDispatch2 * context )\n{\n\ttry {\n#ifdef TJS_DEBUG_DISASM\n\t\tstd::list<tTJSInterCodeContext *>::iterator i = InterCodeContextList.begin();\n\t\twhile(i != InterCodeContextList.end())\n\t\t{\n\t\t\tConsoleOutput(TJS_W(\"\"), (void*)this);\n\t\t\tConsoleOutput((*i)->GetName(), (void*)this);\n\t\t\t(*i)->Disassemble(ConsoleOutput, (void*)this);\n\t\t\ti++;\n\t\t}\n#endif\n\n\t\t// execute global level script\n\t\tExecuteTopLevelScript(result, context);\n\t} catch(...) {\n\t\tif(InterCodeContextList.size() != 1) {\n\t\t\tif(TopLevelContext) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\t\twhile(ContextStack.size()) {\n\t\t\t\tContextStack.top()->Release();\n\t\t\t\tContextStack.pop();\n\t\t\t}\n\t\t}\n\t\tthrow;\n\t}\n\n\tif(InterCodeContextList.size() != 1) {\n\t\t// this is not a single-context script block\n\t\t// (may hook itself)\n\t\t// release all contexts and global at this time\n\t\tif(TopLevelContext) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\twhile(ContextStack.size()) {\n\t\t\tContextStack.top()->Release();\n\t\t\tContextStack.pop();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::ExecuteTopLevelScript(tTJSVariant *result,\n\tiTJSDispatch2 * context)\n{\n\tif(TopLevelContext)\n\t{\n#ifdef TJS_DEBUG_PROFILE_TIME\n\t\tclock_t start = clock();\n#endif\n\t\tTopLevelContext->FuncCall(0, NULL, NULL, result, 0, NULL, context);\n#ifdef TJS_DEBUG_PROFILE_TIME\n\t\ttjs_char str[100];\n\t\tTJS_sprintf(str, TJS_W(\"%d\"), clock() - start);\n\t\tConsoleOutput(str, (void*)this);\n#endif\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::PushContextStack(const tjs_char *name, tTJSContextType type)\n{\n\ttTJSInterCodeContext *cntx;\n\tcntx = new tTJSInterCodeContext(InterCodeContext, name, this, type);\n\tif(InterCodeContext==NULL)\n\t{\n\t\tif(TopLevelContext) TJS_eTJSError(TJSInternalError);\n\t\tTopLevelContext = cntx;\n\t\tTopLevelContext->AddRef();\n\t}\n\tContextStack.push(cntx);\n\tInterCodeContext = cntx;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::PopContextStack(void)\n{\n\tInterCodeContext->Commit();\n\tInterCodeContext->Release();\n\tContextStack.pop();\n\tif(ContextStack.size() >= 1)\n\t\tInterCodeContext = ContextStack.top();\n\telse\n\t\tInterCodeContext = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Parse(const tjs_char *script, bool isexpr, bool resultneeded)\n{\n\tTJS_F_TRACE(\"tTJSScriptBlock::Parse\");\n\n\tif(!script) return;\n\n\tCompileErrorCount = 0;\n\n\n\tLexicalAnalyzer = new tTJSLexicalAnalyzer(this, script, isexpr, resultneeded);\n\n\ttry\n\t{\n\t\tyyparse(this);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete LexicalAnalyzer; LexicalAnalyzer=NULL;\n\t\tthrow;\n\t}\n\n\tdelete LexicalAnalyzer; LexicalAnalyzer=NULL;\n\n\tif(CompileErrorCount)\n\t{\n\t\tTJS_eTJSScriptError(FirstError, this, FirstErrorPos);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::SetFirstError(const tjs_char *error, tjs_int pos)\n{\n\tif(CompileErrorCount == 0)\n\t{\n\t\tFirstError = error;\n\t\tFirstErrorPos = pos;\n\t}\n}\n//---------------------------------------------------------------------------\nttstr tTJSScriptBlock::GetNameInfo() const\n{\n\tif(LineOffset == 0)\n\t{\n\t\treturn ttstr(Name);\n\t}\n\telse\n\t{\n\t\treturn ttstr(Name) + TJS_W(\"(line +\") + ttstr(LineOffset) + TJS_W(\")\");\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Dump() const\n{\n\tstd::list<tTJSInterCodeContext *>::const_iterator i =\n\t\tInterCodeContextList.begin();\n\twhile(i != InterCodeContextList.end())\n\t{\n\t\tConsoleOutput(TJS_W(\"\"), (void*)this);\n\t\ttjs_char ptr[256];\n\t\tTJS_snprintf(ptr, sizeof(ptr)/sizeof(tjs_char), TJS_W(\" 0x%p\"), (*i));\n\t\tConsoleOutput((ttstr(TJS_W(\"(\")) + ttstr((*i)->GetContextTypeName()) +\n\t\t\tTJS_W(\") \") + ttstr((*i)->GetName()) + ptr).c_str(), (void*)this);\n\t\t(*i)->Disassemble(ConsoleOutput, (void*)this);\n\t\ti++;\n\t}\n}\n//---------------------------------------------------------------------------\n// for Bytecode\ntjs_int tTJSScriptBlock::GetCodeIndex( const tTJSInterCodeContext* ctx ) const {\n\ttjs_int index = 0;\n\tfor( std::list<tTJSInterCodeContext *>::const_iterator i = InterCodeContextList.begin(); i != InterCodeContextList.end(); i++, index++ ) {\n\t\tif( (*i) == ctx ) {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn -1;\n}\n//---------------------------------------------------------------------------\nconst tjs_uint8 tTJSScriptBlock::BYTECODE_FILE_TAG[BYTECODE_FILE_TAG_SIZE] = { 'T', 'J', 'S', '2', '1', '0', '0', 0 };\nconst tjs_uint8 tTJSScriptBlock::BYTECODE_CODE_TAG[BYTECODE_TAG_SIZE] = { 'T', 'J', 'S', '2' };\nconst tjs_uint8 tTJSScriptBlock::BYTECODE_OBJ_TAG[BYTECODE_TAG_SIZE] = { 'O', 'B', 'J', 'S' };\nconst tjs_uint8 tTJSScriptBlock::BYTECODE_DATA_TAG[BYTECODE_TAG_SIZE] = { 'D', 'A', 'T', 'A' };\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::ExportByteCode( bool outputdebug, tTJSBinaryStream* output ) {\n\tconst int count = (int)InterCodeContextList.size();\n\tstd::vector<std::vector<tjs_uint8>* > objarray;\n\tobjarray.reserve( count * 2 );\n\ttjsConstArrayData* constarray = new tjsConstArrayData();\n\tint objsize = 0;\n\tfor( std::list<tTJSInterCodeContext *>::const_iterator i = InterCodeContextList.begin(); i != InterCodeContextList.end(); i++ ) {\n\t\ttTJSInterCodeContext* obj = (*i);\n\t\tstd::vector<tjs_uint8>* buf = obj->ExportByteCode( outputdebug, this, *constarray );\n\t\tobjarray.push_back( buf );\n\t\tobjsize += (int)buf->size() + BYTECODE_TAG_SIZE + BYTECODE_CHUNK_SIZE_LEN; // tag + size\n\t}\n\n\tobjsize += BYTECODE_TAG_SIZE + BYTECODE_CHUNK_SIZE_LEN + 4 + 4; // OBJS tag + size + toplevel + count\n\tstd::vector<tjs_uint8>* dataarea = constarray->ExportBuffer();\n\tint datasize = (int)dataarea->size() + BYTECODE_TAG_SIZE + BYTECODE_CHUNK_SIZE_LEN; // DATA tag + size\n\tint filesize = objsize + datasize + BYTECODE_FILE_TAG_SIZE + BYTECODE_CHUNK_SIZE_LEN; // TJS2 tag + file size\n\tint toplevel = -1;\n\tif( TopLevelContext != NULL ) {\n\t\ttoplevel = GetCodeIndex( TopLevelContext );\n\t}\n\ttjs_uint8 tmp[4];\n\toutput->Write( BYTECODE_FILE_TAG, 8 );\n\tWrite4Byte( tmp, filesize );\n\toutput->Write( tmp, 4 );\n\toutput->Write( BYTECODE_DATA_TAG, 4 );\n\tWrite4Byte( tmp, datasize );\n\toutput->Write( tmp, 4 );\n\toutput->Write( &((*dataarea)[0]), (tjs_uint)dataarea->size() );\n\toutput->Write( BYTECODE_OBJ_TAG, 4 );\n\tWrite4Byte( tmp, objsize );\n\toutput->Write( tmp, 4 );\n\tWrite4Byte( tmp, toplevel );\n\toutput->Write( tmp, 4 );\n\tWrite4Byte( tmp, count );\n\toutput->Write( tmp, 4 );\n\tfor( int i = 0; i < count; i++ ) {\n\t\tstd::vector<tjs_uint8>* buf = objarray[i];\n\t\tint size = (int)buf->size();\n\t\toutput->Write( BYTECODE_CODE_TAG, 4 );\n\t\tWrite4Byte( tmp, size );\n\t\toutput->Write( tmp, 4 );\n\t\toutput->Write( &((*buf)[0]), size );\n\t\tdelete buf;\n\t\tobjarray[i] = NULL;\n\t}\n\tobjarray.clear();\n\tdelete constarray;\n\tdelete dataarea;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptBlock::Compile( const tjs_char *text, bool isexpression, bool isresultneeded, bool outputdebug, tTJSBinaryStream* output ) {\n\tif(!text) return;\n\tif(!text[0]) return;\n\n\ttTJSInterCodeContext::IsBytecodeCompile = true;\n\ttry {\n\t\tScript = new tjs_char[TJS_strlen(text)+1];\n\t\tTJS_strcpy(Script, text);\n\n\t\t// calculation of line-count\n\t\ttjs_char *ls = Script;\n\t\ttjs_char *p = Script;\n\t\twhile( *p ) {\n\t\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n')) {\n\t\t\t\tLineVector.push_back(int(ls - Script));\n\t\t\t\tLineLengthVector.push_back(int(p - ls));\n\t\t\t\tif(*p == TJS_W('\\r') && p[1] == TJS_W('\\n')) p++;\n\t\t\t\tp++;\n\t\t\t\tls = p;\n\t\t\t} else {\n\t\t\t\tp++;\n\t\t\t}\n\t\t}\n\t\tif( p != ls ) {\n\t\t\tLineVector.push_back(int(ls - Script));\n\t\t\tLineLengthVector.push_back(int(p - ls));\n\t\t}\n\n\t\tParse( text, isexpression, isresultneeded );\n\n\t\tExportByteCode( outputdebug, output );\n\t} catch(...) {\n\t\tif(InterCodeContextList.size() != 1) {\n\t\t\tif( TopLevelContext ) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\t\twhile( ContextStack.size() ) {\n\t\t\t\tContextStack.top()->Release();\n\t\t\t\tContextStack.pop();\n\t\t\t}\n\t\t}\n\t\ttTJSInterCodeContext::IsBytecodeCompile = false;\n\t\tthrow;\n\t}\n\tif(InterCodeContextList.size() != 1) {\n\t\tif( TopLevelContext ) TopLevelContext->Release(), TopLevelContext = NULL;\n\t\twhile( ContextStack.size() ) {\n\t\t\tContextStack.top()->Release();\n\t\t\tContextStack.pop();\n\t\t}\n\t}\n\ttTJSInterCodeContext::IsBytecodeCompile = false;\n}\n//---------------------------------------------------------------------------\n\n#define TJS_OFFSET_VM_REG_ADDR( x ) ( (x) = TJS_FROM_VM_REG_ADDR(x) )\n#define TJS_OFFSET_VM_CODE_ADDR( x ) ( (x) = TJS_FROM_VM_CODE_ADDR(x) )\n/**\n * oCgR[h̃AhX͔z̃CfbNXŵŁAɍ킹ĕϊ\n */\nvoid tTJSScriptBlock::TranslateCodeAddress( tjs_int32* code, const tjs_int32 codeSize )\n{\n\ttjs_int i = 0;\n\tfor( ; i < codeSize; ) {\n\t\ttjs_int size;\n\t\tswitch( code[i] ) {\n\t\tcase VM_NOP: size = 1; break;\n\t\tcase VM_NF: size = 1; break;\n\t\tcase VM_CONST:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n#define OP2_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak\n\n\t\tOP2_DISASM(VM_CP);\n\t\tOP2_DISASM(VM_CEQ);\n\t\tOP2_DISASM(VM_CDEQ);\n\t\tOP2_DISASM(VM_CLT);\n\t\tOP2_DISASM(VM_CGT);\n\t\tOP2_DISASM(VM_CHKINS);\n#undef OP2_DISASM\n\n#define OP2_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+4]); \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+4]); \\\n\t\tsize = 5; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak\n\n\t\tOP2_DISASM(VM_LOR);\n\t\tOP2_DISASM(VM_LAND);\n\t\tOP2_DISASM(VM_BOR);\n\t\tOP2_DISASM(VM_BXOR);\n\t\tOP2_DISASM(VM_BAND);\n\t\tOP2_DISASM(VM_SAR);\n\t\tOP2_DISASM(VM_SAL);\n\t\tOP2_DISASM(VM_SR);\n\t\tOP2_DISASM(VM_ADD);\n\t\tOP2_DISASM(VM_SUB);\n\t\tOP2_DISASM(VM_MOD);\n\t\tOP2_DISASM(VM_DIV);\n\t\tOP2_DISASM(VM_IDIV);\n\t\tOP2_DISASM(VM_MUL);\n#undef OP2_DISASM\n\n#define OP1_DISASM TJS_OFFSET_VM_REG_ADDR(code[i+1]); size = 2;\n\t\tcase VM_TT:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_TF:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_SETF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_SETNF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_LNOT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_BNOT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_ASC:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHR:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_NUM:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHS:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CL:\t\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_INV:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_CHKINV:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_TYPEOF:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_EVAL:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_EEXP:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_INT:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_REAL:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_STR:\t\tOP1_DISASM;\tbreak;\n\t\tcase VM_OCTET:\t\tOP1_DISASM;\tbreak;\n#undef OP1_DISASM\n\n\t\tcase VM_CCL:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n#define OP1_DISASM(c) \\\n\tcase c: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tsize = 2; \\\n\t\tbreak; \\\n\tcase c+1: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+2: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]); \\\n\t\tsize = 4; \\\n\t\tbreak; \\\n\tcase c+3: \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]); \\\n\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]); \\\n\t\tsize = 3; \\\n\t\tbreak\n\n\t\tOP1_DISASM(VM_INC);\n\t\tOP1_DISASM(VM_DEC);\n#undef OP1_DISASM\n\n#define OP1A_DISASM TJS_OFFSET_VM_CODE_ADDR(code[i+1]); size = 2;\n\t\tcase VM_JF:\tOP1A_DISASM; break;\n\t\tcase VM_JNF:OP1A_DISASM; break;\n\t\tcase VM_JMP:OP1A_DISASM; break;\n#undef OP1A_DISASM\n\n\t\tcase VM_CALL:\n\t\tcase VM_CALLD:\n\t\tcase VM_CALLI:\n\t\tcase VM_NEW:\n\t\t  {\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\n\t\t\ttjs_int st; // start of arguments\n\t\t\tif(code[i] == VM_CALLD || code[i] == VM_CALLI) {\n\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\t\tst = 5;\n\t\t\t} else {\n\t\t\t\tst = 4;\n\t\t\t}\n\t\t\ttjs_int num = code[i+st-1];     // st-1 = argument count\n\t\t\ttjs_int c = 0;\n\t\t\tif(num == -1) {\n\t\t\t\tsize = st;\n\t\t\t} else if(num == -2) {\n\t\t\t\tst++;\n\t\t\t\tnum = code[i+st-1];\n\t\t\t\tsize = st + num * 2;\n\t\t\t\tfor(tjs_int j = 0; j < num; j++) {\n\t\t\t\t\tswitch(code[i+st+j*2]) {\n\t\t\t\t\tcase fatNormal:\n\t\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+st+j*2+1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatExpand:\n\t\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+st+j*2+1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase fatUnnamedExpand:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// normal operation\n\t\t\t\tsize = st + num;\n\t\t\t\twhile(num--) {\n\t\t\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+c+st]);\n\t\t\t\t\tc++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t  }\n\n\t\tcase VM_GPD:\n\t\tcase VM_GPDS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SPD:\n\t\tcase VM_SPDE:\n\t\tcase VM_SPDEH:\n\t\tcase VM_SPDS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_GPI:\n\t\tcase VM_GPIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SPI:\n\t\tcase VM_SPIE:\n\t\tcase VM_SPIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SETP:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GETP:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_DELD:\n\t\tcase VM_TYPEOFD:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_DELI:\n\t\tcase VM_TYPEOFI:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+3]);\n\t\t\tsize = 4;\n\t\t\tbreak;\n\n\t\tcase VM_SRV:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_RET: size = 1; break;\n\n\t\tcase VM_ENTRY:\n\t\t\tTJS_OFFSET_VM_CODE_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_EXTRY: size = 1; break;\n\n\t\tcase VM_THROW:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_CHGTHIS:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_GLOBAL:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tsize = 2;\n\t\t\tbreak;\n\n\t\tcase VM_ADDCI:\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+1]);\n\t\t\tTJS_OFFSET_VM_REG_ADDR(code[i+2]);\n\t\t\tsize = 3;\n\t\t\tbreak;\n\n\t\tcase VM_REGMEMBER: size = 1; break;\n\t\tcase VM_DEBUGGER: size = 1; break;\n\t\tdefault: size = 1; break;\n\t\t} /* switch */\n\t\ti+=size;\n\t}\n\tif( codeSize != i ) {\n\t\tTJS_eTJSScriptError( TJSInternalError, this, 0 );\n\t}\n}\n#undef TJS_OFFSET_VM_REG_ADDR\n#undef TJS_OFFSET_VM_CODE_ADDR\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n} // namespace\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsScriptBlock.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script Block Management\n//---------------------------------------------------------------------------\n#ifndef tjsScriptBlockH\n#define tjsScriptBlockH\n\n#include \"tjsInterface.h\"\n#include \"tjsInterCodeGen.h\"\n#include \"tjsLex.h\"\n#include \"tjs.h\"\n\n#include <list>\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSScriptBlock - a class for managing the script block\n//---------------------------------------------------------------------------\nclass tTJS;\nclass tTJSInterCodeContext;\nclass tTJSScriptBlock\n{\npublic:\n\ttTJSScriptBlock(tTJS * owner);\n\tvirtual ~tTJSScriptBlock();\n\n\t// for Bytecode               \n\tstatic const int BYTECODE_FILE_TAG_SIZE = 8;\nprivate:\n\ttTJS * Owner;\n\ttjs_int RefCount;\n\ttjs_char *Script;\n\ttjs_char *Name;\n\ttjs_int LineOffset;\n\n\tstd::list<tTJSInterCodeContext *> InterCodeContextList;\n\n\tstd::stack<tTJSInterCodeContext *> ContextStack;\n\n\ttTJSLexicalAnalyzer *LexicalAnalyzer;\n\n\ttTJSInterCodeContext *InterCodeContext;\n\n\tstd::vector<tjs_int> LineVector;\n\tstd::vector<tjs_int> LineLengthVector;\n\n\ttTJSInterCodeContext * TopLevelContext;\n\n\ttTJSString FirstError;\n\ttjs_int FirstErrorPos;\n\n\tbool UsingPreProcessor;\n\npublic:\n\ttjs_int CompileErrorCount;\n\n\ttTJS * GetTJS() { return Owner; }\n\n\tvoid AddRef();\n\tvoid Release();\n\n\tvoid Add(tTJSInterCodeContext * cntx);\n\tvoid Remove(tTJSInterCodeContext * cntx);\n\n\ttjs_uint GetContextCount() const { return (tjs_uint)InterCodeContextList.size(); }\n\ttjs_uint GetTotalVMCodeSize() const;  // returns in VM word size ( 1 word = 32bit )\n\ttjs_uint GetTotalVMDataSize() const;  // returns in tTJSVariant count\n\n\tbool IsReusable() const { return GetContextCount() == 1 &&\n\t\tTopLevelContext != NULL && !UsingPreProcessor; }\n\n\tconst tjs_char * GetLine(tjs_int line, tjs_int *linelength) const;\n\ttjs_int SrcPosToLine(tjs_int pos) const;\n\ttjs_int LineToSrcPos(tjs_int line) const;\n\n\tttstr GetLineDescriptionString(tjs_int pos) const;\n\n\tconst tjs_char *GetScript() const { return Script; }\n\n\tvoid PushContextStack(const tjs_char *name, tTJSContextType type);\n\tvoid PopContextStack(void);\n\tvoid Parse(const tjs_char *script, bool isexpr, bool resultneeded);\n\n\tvoid SetFirstError(const tjs_char *error, tjs_int pos);\n\n\ttTJSLexicalAnalyzer * GetLexicalAnalyzer() { return LexicalAnalyzer; }\n\ttTJSInterCodeContext * GetCurrentContext() { return InterCodeContext; }\n\n\tconst tjs_char *GetName() const { return Name; }\n\tvoid SetName(const tjs_char *name, tjs_int lineofs);\n\tttstr GetNameInfo() const;\n\n\ttjs_int GetLineOffset() const { return LineOffset; }\n\n\tvoid NotifyUsingPreProcessor() { UsingPreProcessor = true; }\n\n\tvoid Dump() const;\n\nprivate:\n\tstatic void ConsoleOutput(const tjs_char *msg, void *data);\n\n\t// for Bytecode\n\tstatic const int BYTECODE_TAG_SIZE = 4;\n\tstatic const int BYTECODE_CHUNK_SIZE_LEN = 4;\n\tstatic const tjs_uint8 BYTECODE_FILE_TAG[BYTECODE_FILE_TAG_SIZE];\n\tstatic const tjs_uint8 BYTECODE_CODE_TAG[BYTECODE_TAG_SIZE];\n\tstatic const tjs_uint8 BYTECODE_OBJ_TAG[BYTECODE_TAG_SIZE];\n\tstatic const tjs_uint8 BYTECODE_DATA_TAG[BYTECODE_TAG_SIZE];\n\n\tstatic inline void Write4Byte( tjs_uint8 output[4], int value ) {\n\t\toutput[0] = ( (tjs_uint8)((value>>0)&0xff) );\n\t\toutput[1] = ( (tjs_uint8)((value>>8)&0xff) );\n\t\toutput[2] = ( (tjs_uint8)((value>>16)&0xff) );\n\t\toutput[3] = ( (tjs_uint8)((value>>24)&0xff) );\n\t}\n\tvoid ExportByteCode( bool outputdebug, class tTJSBinaryStream* output );\n\npublic:\n\tstatic void (*GetConsoleOutput())(const tjs_char *msg, void *data)\n\t\t{ return ConsoleOutput; }\n\n\tvoid SetText(tTJSVariant *result, const tjs_char *text, iTJSDispatch2 * context,\n\t\tbool isexpression);\n\n\tvoid ExecuteTopLevelScript(tTJSVariant *result, iTJSDispatch2 * context);\n\n\t// for Bytecode\n\ttTJSScriptBlock( tTJS* owner,  const tjs_char* name, tjs_int lineoffset );\n\n\tvoid SetObjects( tTJSInterCodeContext* toplevel,std::vector<tTJSInterCodeContext*>& objs, int count ) {\n\t\tTopLevelContext = toplevel;\n\t\tfor( int i = 0; i < count; i++ ) {\n\t\t\tAdd( objs[i] );\n\t\t\tif( objs[i] != toplevel ) {\n\t\t\t\tAddRef();\n\t\t\t}\n\t\t\tobjs[i] = NULL;\n\t\t}\n\t}\n\tvoid ExecuteTopLevel( tTJSVariant *result, iTJSDispatch2 * context );\n\n\tint GetCodeIndex( const tTJSInterCodeContext* ctx ) const;\n\n\tvoid Compile( const tjs_char *text, bool isexpression, bool isresultneeded, bool outputdebug, tTJSBinaryStream* output );\n\tvoid TranslateCodeAddress( tjs_int32* code, const tjs_int32 codeSize );\n};\n//---------------------------------------------------------------------------\n}\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsScriptCache.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script block caching\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjs.h\"\n#include \"tjsScriptCache.h\"\n#include \"tjsScriptBlock.h\"\n#include \"tjsByteCodeLoader.h\"\n\n#define TJS_SCRIPT_CACHE_MAX 64\n\n\n// currently this object holds only anonymous, single-context expression.\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSScriptCache - a class to cache script blocks\n//---------------------------------------------------------------------------\ntTJSScriptCache::tTJSScriptCache(tTJS *owner)\n\t: Cache(TJS_SCRIPT_CACHE_MAX)\n{\n\tOwner = owner;\n}\n//---------------------------------------------------------------------------\ntTJSScriptCache::~tTJSScriptCache()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptCache::ExecScript(const tjs_char *script, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst tjs_char *name, tjs_int lineofs)\n{\n\t// currently this does nothing with normal script blocks.\n\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\ttry\n\t{\n\t\tif(name) blk->SetName(name, lineofs);\n\t\tblk->SetText(result, script, context, false);\n\t}\n\tcatch(...)\n\t{\n\t\tblk->Release();\n\t\tthrow;\n\t}\n\n\tblk->Release();\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptCache::ExecScript(const ttstr &script, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst ttstr *name, tjs_int lineofs)\n{\n\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\ttry\n\t{\n\t\tif(name) blk->SetName(name->c_str(), lineofs);\n\t\tblk->SetText(result, script.c_str(), context, false);\n\t}\n\tcatch(...)\n\t{\n\t\tblk->Release();\n\t\tthrow;\n\t}\n\n\tblk->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptCache::EvalExpression(const tjs_char *expression,\n\ttTJSVariant *result, iTJSDispatch2 * context,\n\tconst tjs_char *name, tjs_int lineofs)\n{\n\t// currently this works only with anonymous script blocks.\n\tif(name)\n\t{\n\t\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\t\ttry\n\t\t{\n\t\t\tblk->SetName(name, lineofs);\n\t\t\tblk->SetText(result, expression, context, true);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tblk->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\tblk->Release();\n\t\treturn;\n\t}\n\n\t// search through script block cache\n\ttScriptCacheData data;\n\tdata.Script = expression;\n\tdata.ExpressionMode = true;\n\tdata.MustReturnResult = result != NULL;\n\n\ttjs_uint32 hash = tScriptCacheHashFunc::Make(data);\n\n\ttScriptBlockHolder *holder = Cache.FindAndTouchWithHash(data, hash);\n\n\tif(holder)\n\t{\n\t\t// found in cache\n\n\t\t// execute script block in cache\n\t\tholder->GetObjectNoAddRef()->ExecuteTopLevelScript(result, context);\n\t\treturn;\n\t}\n\n\t// not found in cache\n\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\ttry\n\t{\n\t\tblk->SetText(result, expression, context, true);\n\t}\n\tcatch(...)\n\t{\n\t\tblk->Release();\n\t\tthrow;\n\t}\n\n\t// add to cache\n\tif(blk->IsReusable())\n\t{\n\t\t// currently only single-context script block is cached\n\t\ttScriptBlockHolder newholder(blk);\n\t\tCache.AddWithHash(data, hash, newholder);\n\t}\n\n\tblk->Release();\n\treturn;\n}\n//---------------------------------------------------------------------------\nvoid tTJSScriptCache::EvalExpression(const ttstr &expression, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst ttstr *name, tjs_int lineofs)\n{\n\t// currently this works only with anonymous script blocks.\n\n\t// note that this function is basically the same as function above.\n\n\tif(name && !name->IsEmpty())\n\t{\n\t\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\t\ttry\n\t\t{\n\t\t\tblk->SetName(name->c_str(), lineofs);\n\t\t\tblk->SetText(result, expression.c_str(), context, true);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tblk->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\tblk->Release();\n\t\treturn;\n\t}\n\n\t// search through script block cache\n\ttScriptCacheData data;\n\tdata.Script = expression;\n\tdata.ExpressionMode = true;\n\tdata.MustReturnResult = result != NULL;\n\n\ttjs_uint32 hash = tScriptCacheHashFunc::Make(data);\n\n\ttScriptBlockHolder *holder = Cache.FindAndTouchWithHash(data, hash);\n\n\tif(holder)\n\t{\n\t\t// found in cache\n\n\t\t// execute script block in cache\n\t\tholder->GetObjectNoAddRef()->ExecuteTopLevelScript(result, context);\n\t\treturn;\n\t}\n\n\t// not found in cache\n\ttTJSScriptBlock *blk = new tTJSScriptBlock(Owner);\n\n\ttry\n\t{\n\t\tblk->SetText(result, expression.c_str(), context, true);\n\t}\n\tcatch(...)\n\t{\n\t\tblk->Release();\n\t\tthrow;\n\t}\n\n\t// add to cache\n\tif(blk->IsReusable())\n\t{\n\t\t// currently only single-context script block is cached\n\t\ttScriptBlockHolder newholder(blk);\n\t\tCache.AddWithHash(data, hash, newholder);\n\t}\n\n\tblk->Release();\n\treturn;\n}\n//---------------------------------------------------------------------------\n// for Bytecode\nvoid tTJSScriptCache::LoadByteCode( const tjs_uint8* buff, size_t len, tTJSVariant *result,\n\t\tiTJSDispatch2 *context, const tjs_char *name )\n{\n\ttTJSByteCodeLoader* loader = new tTJSByteCodeLoader();\n\ttTJSScriptBlock* blk = NULL;\n\ttry {\n\t\tblk = loader->ReadByteCode( Owner, name, buff, len );\n\t\tif( blk != NULL ) {\n\t\t\t// blk->Dump();\n\t\t\tblk->ExecuteTopLevel( result, context );\n\t\t} else {\n\t\t\tTJS_eTJSScriptError( TJSByteCodeBroken, blk, 0 );\n\t\t}\n\t} catch(...) {\n\t\tif( blk ) blk->Release();\n\t\tdelete loader;\n\t\tthrow;\n\t}\n\tif( blk ) blk->Release();\n\tdelete loader;\n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n"
  },
  {
    "path": "src/core/tjs2/tjsScriptCache.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Script block caching\n//---------------------------------------------------------------------------\n\n#ifndef tjsScriptCacheH\n#define tjsScriptCacheH\n\n#include \"tjsConfig.h\"\n#include \"tjsHashSearch.h\"\n#include \"tjsUtils.h\"\n\n\nnamespace TJS\n{\n\n//---------------------------------------------------------------------------\n// tTJSScriptCache - a class to cache script blocks\n//---------------------------------------------------------------------------\nclass tTJS;\nclass tTJSScriptCache\n{\nprivate:\n\tstruct tScriptCacheData\n\t{\n\t\tttstr Script;\n\t\tbool ExpressionMode;\n\t\tbool MustReturnResult;\n\n\t\tbool operator ==(const tScriptCacheData &rhs) const\n\t\t{\n\t\t\treturn Script == rhs.Script && ExpressionMode == rhs.ExpressionMode &&\n\t\t\t\tMustReturnResult == rhs.MustReturnResult;\n\t\t}\n\t};\n\n\tclass tScriptCacheHashFunc\n\t{\n\tpublic:\n\t\tstatic tjs_uint32 Make(const tScriptCacheData &val)\n\t\t{\n\t\t\ttjs_uint32 v = tTJSHashFunc<ttstr>::Make(val.Script);\n\t\t\tv ^= val.ExpressionMode?1:0;\n\t\t\tv ^= val.MustReturnResult?1:0;\n\t\t\treturn v;\n\t\t}\n\t};\n\n\ttTJS *Owner;\n\n\ttypedef tTJSRefHolder<tTJSScriptBlock> tScriptBlockHolder;\n\n\ttypedef tTJSHashCache<tScriptCacheData, tScriptBlockHolder, tScriptCacheHashFunc>\n\t\ttCache;\n\n\ttCache Cache;\n\npublic:\n\ttTJSScriptCache(tTJS *owner);\n\tvirtual ~tTJSScriptCache();\n\n\npublic:\n\tvoid ExecScript(const tjs_char *script, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst tjs_char *name, tjs_int lineofs);\n\n\tvoid ExecScript(const ttstr &script, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst ttstr *name, tjs_int lineofs);\n\n\npublic:\n\n\tvoid EvalExpression(const tjs_char *expression, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst tjs_char *name, tjs_int lineofs);\n\n\tvoid EvalExpression(const ttstr &expression, tTJSVariant *result,\n\t\tiTJSDispatch2 * context,\n\t\tconst ttstr *name, tjs_int lineofs);\n\n\t// for Bytecode\n\tvoid LoadByteCode( const tjs_uint8* buff, size_t len, tTJSVariant *result,\n\t\tiTJSDispatch2 *context, const tjs_char *name );\n};\n//---------------------------------------------------------------------------\n\n}\n#endif\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsString.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// tTJSVariant friendly string class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <stdarg.h>\n#include <stdio.h>\n\n\n#include \"tjsString.h\"\n#include \"tjsVariant.h\"\n\n#define TJS_TTSTR_SPRINTF_BUF_SIZE 8192\n\n\nnamespace TJS\n{\nconst tjs_char *TJSNullStrPtr = TJS_W(\"\");\n//---------------------------------------------------------------------------\ntTJSString::tTJSString(const tTJSVariant & val)\n{\n\tPtr = val.AsString();\n}\n//---------------------------------------------------------------------------\ntTJSString::tTJSString(tjs_int n) // from int\n{\n\tPtr = TJSIntegerToString(n);\n}\n//---------------------------------------------------------------------------\ntTJSString::tTJSString(tjs_int64 n) // from int64\n{\n\tPtr = TJSIntegerToString(n);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSString::GetNarrowStrLen() const\n{\n\t// note that this function will return -1 when there are invalid chars in string.\n\tif(!Ptr) return 0;\n\treturn (tjs_int)TJS_wcstombs(NULL, c_str(), 0);\n}\n//---------------------------------------------------------------------------\nvoid tTJSString::ToNarrowStr(tjs_nchar *dest, tjs_int destmaxlen) const\n{\n\t// dest must be an array of char, its size must be at least destmaxlen+1\n\tdest[TJS_wcstombs(dest, c_str(), destmaxlen)] = 0;\n}\n//---------------------------------------------------------------------------\ntjs_char * tTJSString::InternalIndepend()\n{\n\t// severs sharing of the string instance\n\t// and returns independent internal buffer\n\n\ttTJSVariantString *newstr =\n\t\tTJSAllocVariantString(Ptr->operator const tjs_char*());\n\n\tPtr->Release();\n\tPtr = newstr;\n\n\treturn const_cast<tjs_char *>(newstr->operator const tjs_char*());\n}\n//---------------------------------------------------------------------------\ntjs_int64 tTJSString::AsInteger() const\n{\n\treturn Ptr->ToInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSString::Replace(const tTJSString &from, const tTJSString &to, bool forall)\n{\n\t// replaces the string partial \"from\", to \"to\".\n\t// all \"from\" are replaced when \"forall\" is true.\n\tif(IsEmpty()) return;\n\tif(from.IsEmpty()) return;\n\n\ttjs_int fromlen = from.GetLen();\n\n\tfor(;;)\n\t{\n\t\tconst tjs_char *st;\n\t\tconst tjs_char *p;\n\t\tst = c_str();\n\t\tp = TJS_strstr(st, from.c_str());\n\t\tif(p)\n\t\t{\n\t\t\ttTJSString name(*this, (int)(p-st));\n\t\t\ttTJSString n2(p + fromlen);\n\t\t\t*this = name + to + n2;\n\t\t\tif(!forall) break;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSString tTJSString::AsLowerCase() const\n{\n\ttjs_int len = GetLen();\n\n\tif(len == 0) return tTJSString();\n\n\ttTJSString ret((tTJSStringBufferLength)(len));\n\n\tconst tjs_char *s = c_str();\n\ttjs_char *d = ret.Independ();\n\twhile(*s)\n\t{\n\t\tif(*s >= TJS_W('A') && *s <= TJS_W('Z'))\n\t\t\t*d = *s +(TJS_W('a')-TJS_W('A'));\n\t\telse\n\t\t\t*d = *s;\n\t\td++;\n\t\ts++;\n\t}\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSString tTJSString::AsUpperCase() const\n{\n\ttjs_int len = GetLen();\n\n\tif(len == 0) return tTJSString();\n\n\ttTJSString ret((tTJSStringBufferLength)(len));\n\n\tconst tjs_char *s = c_str();\n\ttjs_char *d = ret.Independ();\n\twhile(*s)\n\t{\n\t\tif(*s >= TJS_W('a') && *s <= TJS_W('z'))\n\t\t\t*d = *s +(TJS_W('A')-TJS_W('a'));\n\t\telse\n\t\t\t*d = *s;\n\t\td++;\n\t\ts++;\n\t}\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\nvoid tTJSString::ToLowerCase()\n{\n\ttjs_char *p = Independ();\n\tif(p)\n\t{\n\t\twhile(*p)\n\t\t{\n\t\t\tif(*p >= TJS_W('A') && *p <= TJS_W('Z'))\n\t\t\t\t*p += (TJS_W('a')-TJS_W('A'));\n\t\t\tp++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSString::ToUppserCase()\n{\n\ttjs_char *p = Independ();\n\tif(p)\n\t{\n\t\twhile(*p)\n\t\t{\n\t\t\tif(*p >= TJS_W('a') && *p <= TJS_W('z'))\n\t\t\t\t*p += (TJS_W('A')-TJS_W('a'));\n\t\t\tp++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int TJS_cdecl tTJSString::printf(const tjs_char *format, ...)\n{\n\ttjs_int r;\n\ttjs_char *buf = new tjs_char [TJS_TTSTR_SPRINTF_BUF_SIZE];\n\ttry\n\t{\n\t\ttjs_int size = TJS_TTSTR_SPRINTF_BUF_SIZE-1; /*TJS_vsnprintf(NULL, 0, format, param);*/\n\t\tva_list param;\n\t\tva_start(param, format);\n\t\tr = TJS_vsnprintf(buf, size, format, param);\n\t\tAllocBuffer(r);\n\t\tif(r)\n\t\t{\n\t\t\tTJS_strcpy(const_cast<tjs_char*>(c_str()), buf);\n\t\t}\n\t\tva_end(param);\n\t\tFixLen();\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] buf;\n\t\tthrow;\n\t}\n\tdelete [] buf;\n\treturn r;\n}\n//---------------------------------------------------------------------------\ntTJSString tTJSString::EscapeC() const\n{\n\tttstr ret;\n\tconst tjs_char * p = c_str();\n\tbool hexflag = false;\n\tfor(;*p;p++)\n\t{\n\t\tswitch(*p)\n\t\t{\n\t\tcase 0x07: ret += TJS_W(\"\\\\a\"); hexflag = false; continue;\n\t\tcase 0x08: ret += TJS_W(\"\\\\b\"); hexflag = false; continue;\n\t\tcase 0x0c: ret += TJS_W(\"\\\\f\"); hexflag = false; continue;\n\t\tcase 0x0a: ret += TJS_W(\"\\\\n\"); hexflag = false; continue;\n\t\tcase 0x0d: ret += TJS_W(\"\\\\r\"); hexflag = false; continue;\n\t\tcase 0x09: ret += TJS_W(\"\\\\t\"); hexflag = false; continue;\n\t\tcase 0x0b: ret += TJS_W(\"\\\\v\"); hexflag = false; continue;\n\t\tcase TJS_W('\\\\'): ret += TJS_W(\"\\\\\\\\\"); hexflag = false; continue;\n\t\tcase TJS_W('\\''): ret += TJS_W(\"\\\\\\'\"); hexflag = false; continue;\n\t\tcase TJS_W('\\\"'): ret += TJS_W(\"\\\\\\\"\"); hexflag = false; continue;\n\t\tdefault:\n\t\t\tif(hexflag)\n\t\t\t{\n\t\t\t\tif((*p >= TJS_W('a') && *p <= TJS_W('f')) ||\n\t\t\t\t\t(*p >= TJS_W('A') && *p <= TJS_W('F')) ||\n\t\t\t\t\t\t(*p >= TJS_W('0') && *p <= TJS_W('9')) )\n\t\t\t\t{\n\t\t\t\t\ttjs_char buf[20];\n\t\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"\\\\x%02x\"), (int)*p);\n\t\t\t\t\thexflag = true;\n\t\t\t\t\tret += buf;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(*p < 0x20)\n\t\t\t{\n\t\t\t\ttjs_char buf[20];\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W(\"\\\\x%02x\"), (int)*p);\n\t\t\t\thexflag = true;\n\t\t\t\tret += buf;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tret += *p;\n\t\t\t\thexflag = false;\n\t\t\t}\n\t\t}\n\t}\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSString tTJSString::UnescapeC() const\n{\n\t// TODO: UnescapeC\n\treturn TJS_W(\"\");\n}\n//---------------------------------------------------------------------------\nbool tTJSString::StartsWith(const tjs_char *string) const\n{\n\t// return true if this starts with \"string\"\n\tif(!Ptr)\n\t{\n\t\tif(!*string) return true; // empty string starts with empty string\n\t\treturn false;\n\t}\n\tconst tjs_char *this_p = *Ptr;\n\twhile(*string && *this_p)\n\t{\n\t\tif(*string != *this_p) return false;\n\t\tstring++, this_p++;\n\t}\n\tif(!*string) return true;\n\treturn false;\n}\n\nTJS::tTJSString tTJSString::SubString( unsigned int pos, unsigned int len ) const\n{\n    if(Ptr == NULL || len == 0 || pos >= Ptr->GetLength()) return tTJSString();\n    if(pos == 0 && len >= Ptr->GetLength()) return tTJSString(*this);\n    return tTJSString(Ptr->operator const tjs_char *() + pos, len);\n}\n\nTJS::tTJSString tTJSString::Trim()\n{\n    const tjs_char * p = c_str();\n    while( *p > '\\0' && *p < 0x20 )\n        p++;\n\n    tTJSString _str(p);\n    tjs_char * p0 = (tjs_char *)_str.c_str();\n    tjs_char * p1 = (tjs_char *)_str.c_str() + _str.length() - 1;\n    while( p0 < p1 && *p1 != '\\0' && *p1 < 0x20 )\n        *p1-- = '\\0';\n    _str.Ptr->FixLength();\n    return _str;\n}\n\nint tTJSString::IndexOf( const tTJSString& str, unsigned int pos /*= 0*/ ) const\n{\n    if(!Ptr || !str.Ptr) return -1;\n    //    if(str.length() == 0 || pos >= length()) return -1;\n    const tjs_char *p = TJS_strstr(Ptr->operator const tjs_char *() + pos, str.Ptr->operator const tjs_char *());\n    if(p == NULL) return -1;\n    return p - Ptr->operator const tjs_char*();\n}\n#if 0\nconst std::string tTJSString::AsStdString() const {\n\tif (!Ptr) return \"\";\n\t// this constant string value must match std::string in type\n\tconst tjs_char * wide = Ptr->operator const tjs_char*();\n\tint n = TJS_wcstombs(nullptr, wide, 0);\n\tif (n == -1) return \"\";\n\tstd::string ret;\n\tret.resize(n);\n\tTJS_wcstombs((char*)ret.c_str(), wide, n);\n\treturn ret;\n}\n#endif\n//---------------------------------------------------------------------------\ntTJSString operator + (const tjs_char *lhs, const tTJSString &rhs)\n{\n\ttTJSString ret(lhs);\n\tret += rhs;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSString TJSInt32ToHex(tjs_uint32 num, int zeropad)\n{\n\t// convert given number to HEX string.\n\t// zeros are padded when the output string's length is smaller than \"zeropad\".\n\t// \"zeropad\" cannot be larger than 8.\n\tif(zeropad > 8) zeropad = 8;\n\n\ttjs_char buf[12];\n\ttjs_char buf2[12];\n\n\ttjs_char *p = buf;\n\ttjs_char *d = buf2;\n\n\tdo\n\t{\n\t\t*(p++) = (TJS_W(\"0123456789ABCDEF\"))[num % 16];\n\t\tnum /= 16;\n\t\tzeropad --;\n\t} while(zeropad || num);\n\n\tp--;\n\twhile(buf <= p) *(d++) = *(p--);\n\t*d = 0;\n\n\treturn ttstr(buf2); \n}\n//---------------------------------------------------------------------------\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsString.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// tTJSVariant friendly string class implementation\n//---------------------------------------------------------------------------\n\n#ifndef tjsStringH\n#define tjsStringH\n\n#include <string>\n#include \"tjsConfig.h\"\n#ifdef TJS_SUPPORT_VCL\n\t#include <vcl.h>\n#endif\n#include \"tjsVariantString.h\"\n\nnamespace TJS\n{\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSStringBufferLength\n//---------------------------------------------------------------------------\n#pragma pack(push, 4)\nclass tTJSStringBufferLength\n{\npublic:\n\ttjs_int n;\n\ttTJSStringBufferLength(tjs_int n) {this->n = n;}\n};\n#pragma pack(pop)\n/*]*/\n//---------------------------------------------------------------------------\n\n\n\n\n\nclass tTJSVariant;\nextern const tjs_char *TJSNullStrPtr;\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSString\n//---------------------------------------------------------------------------\n#pragma pack(push, 4)\nclass tTJSVariantString;\nstruct tTJSString_S\n{\n\ttTJSVariantString *Ptr;\n};\n#pragma pack(pop)\nclass tTJSString;\n/*]*/\n\n/*start-of-tTJSString*/\nclass tTJSString : protected tTJSString_S\n{\npublic:\n\t//-------------------------------------------------------- constructor --\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, ()) { Ptr = NULL; }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tTJSString &rhs)) { Ptr = rhs.Ptr; if(Ptr) Ptr->AddRef(); }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (tTJSVariantString *vstr))   { Ptr = vstr; if(Ptr) Ptr->AddRef(); }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tjs_char *str)) { Ptr = TJSAllocVariantString(str); }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tjs_nchar *str)) { Ptr = TJSAllocVariantString(str); }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tTJSStringBufferLength len))\n\t\t{ Ptr = TJSAllocVariantStringBuffer(len.n); }\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (tjs_char rch))\n\t{\n\t\ttjs_char ch[2];\n\t\tch[0] = rch;\n\t\tch[1] = 0;\n\t\tPtr = TJSAllocVariantString(ch);\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tTJSVariant & val));\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tTJSString &str, int n)) // construct with first n chars of str\n\t\t{ Ptr = TJSAllocVariantString(str.c_str(), n); }\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (const tjs_char *str, int n)) // same as above except for str's type\n\t\t{ Ptr = TJSAllocVariantString(str, n); }\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (tjs_int n)); // from int\n    TJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSString, (tjs_int64 n)); // from int64\n\n#ifdef TJS_SUPPORT_VCL\n\ttTJSString(const AnsiString &str) { Ptr = TJSAllocVariantString(str.c_str()); }\n\ttTJSString(const WideString &str) { Ptr = TJSAllocVariantString(str.c_bstr()); }\n#endif\n\ttTJSString(const std::basic_string<tjs_char> &str) { Ptr = TJSAllocVariantString(str.c_str()); }\n\ttTJSString(const std::string &str) { Ptr = TJSAllocVariantString(str.c_str()); }\n\n\t//--------------------------------------------------------- destructor --\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, ~tTJSString, ()) { if(Ptr) Ptr->Release(); }\n\n\t//--------------------------------------------------------- conversion --\n\tTJS_CONST_METHOD_DEF(const tjs_char *, c_str, ())\n\t\t{ return Ptr?Ptr->operator const tjs_char *():TJSNullStrPtr; }\n\n#ifdef TJS_SUPPORT_VCL\n\tconst AnsiString AsAnsiString() const\n\t{\n\t\tif(!Ptr) return \"\";\n\t\ttTJSNarrowStringHolder holder(Ptr->operator const tjs_char*());\n\t\treturn AnsiString(holder.operator const char *());\n\t}\n\tconst WideString AsWideString() const\n\t{\n\t\tif(!Ptr) return L\"\";\n\t\treturn WideString(Ptr->operator const tjs_char *());\n\t}\n#endif\n\n\tconst std::string AsStdString() const\n\t{\n#if 0\n\t\tif (!Ptr) return std::wstring(TJS_W(\"\"));\n\t\treturn std::wstring(c_str());\n#else\n\t\tif(!Ptr) return std::string(\"\");\n\t\t\t// this constant string value must match std::string in type\n\t\ttTJSNarrowStringHolder holder(Ptr->operator const tjs_char*());\n\t\treturn std::string(holder.operator const char *());\n#endif\n\t}\n\tconst std::string AsNarrowStdString() const\n\t{\n\t\tif(!Ptr) return std::string(\"\");\n\t\t\t// this constant string value must match std::string in type\n\t\ttTJSNarrowStringHolder holder(Ptr->operator const tjs_char*());\n\t\treturn std::string(holder.operator const char *());\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantString *, AsVariantStringNoAddRef, ())\n\t{\n\t\treturn Ptr;\n\t}\n\n\tTJS_CONST_METHOD_DEF(tjs_int64, AsInteger, ());\n\n\t//------------------------------------------------------- substitution --\n\tTJS_METHOD_DEF(tTJSString &, operator =, (const tTJSString & rhs))\n\t{\n\t\tif(rhs.Ptr) rhs.Ptr->AddRef();\n\t\tif(Ptr) Ptr->Release();\n\t\tPtr = rhs.Ptr;\n\t\treturn *this;\n\t}\n\n\tTJS_METHOD_DEF(tTJSString &, operator =, (const tjs_char * rhs))\n\t{\n\t\tif(Ptr)\n\t\t{\n\t\t\tIndepend();\n\t\t\tif(rhs && rhs[0])\n\t\t\t\tPtr->ResetString(rhs);\n\t\t\telse\n\t\t\t\tPtr->Release(), Ptr = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tPtr = TJSAllocVariantString(rhs);\n\t\t}\n\t\treturn *this;\n\t}\n\n\tTJS_METHOD_DEF(tTJSString &, operator =, (const tjs_nchar *rhs))\n\t{\n\t\tif(Ptr) Ptr->Release();\n\t\tPtr = TJSAllocVariantString(rhs);\n\t\treturn *this;\n\t}\n\n#ifdef TJS_SUPPORT_VCL\n\ttTJSString & operator =(AnsiString &rhs)\n\t{\n\t\tif(Ptr) Ptr->Release();\n\t\tPtr = TJSAllocVariantString(rhs.c_str());\n\t\treturn *this;\n\t}\n\n\ttTJSString & operator =(WideString &rhs)\n\t{\n\t\tif(Ptr) Ptr->Release();\n\t\tPtr = TJSAllocVariantString(rhs.c_bstr());\n\t\treturn *this;\n\t}\n#endif\n\n\t//------------------------------------------------------------ compare --\n\tTJS_CONST_METHOD_DEF(bool, operator ==, (const tTJSString & ref))\n\t{\n\t\tif(Ptr == ref.Ptr) return true; // both empty or the same pointer\n\t\tif(!Ptr && ref.Ptr) return false;\n\t\tif(Ptr && !ref.Ptr) return false;\n\t\tif(Ptr->Length != ref.Ptr->Length) return false;\n\t\treturn !TJS_strcmp(*Ptr, *ref.Ptr);\n\t}\n\n\tTJS_CONST_METHOD_DEF(bool, operator !=, (const tTJSString &ref))\n\t{\n\t\treturn ! this->operator == (ref);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tjs_int, CompareIC, (const tTJSString & ref))\n\t{\n\t\tif(!Ptr && !ref.Ptr) return true; // both empty string\n\t\tif(!Ptr && ref.Ptr) return false;\n\t\tif(Ptr && !ref.Ptr) return false;\n\t\treturn TJS_stricmp(*Ptr, *ref.Ptr);\n\t}\n\n\tTJS_CONST_METHOD_DEF(bool, operator ==, (const tjs_char * ref))\n\t{\n\t\tbool rnemp = ref && ref[0];\n\t\tif(!Ptr && !rnemp) return true; // both empty string\n\t\tif(!Ptr && rnemp) return false;\n\t\tif(Ptr && !rnemp) return false;\n\t\treturn !TJS_strcmp(*Ptr, ref);\n\t}\n\n\tTJS_CONST_METHOD_DEF(bool, operator !=, (const tjs_char * ref))\n\t{\n\t\treturn ! this->operator == (ref);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tjs_int, CompareIC, (const tjs_char * ref))\n\t{\n\t\tbool rnemp = ref && ref[0];\n\t\tif(!Ptr && !rnemp) return true; // both empty string\n\t\tif(!Ptr && rnemp) return false;\n\t\tif(Ptr && !rnemp) return false;\n\t\treturn TJS_stricmp(*Ptr, ref);\n\t}\n\n\tTJS_CONST_METHOD_DEF(bool, operator <, (const tTJSString &ref))\n\t{\n\t\tif(!Ptr && !ref.Ptr) return false;\n\t\tif(!Ptr && ref.Ptr) return true;\n\t\tif(Ptr && !ref.Ptr) return false;\n\t\treturn TJS_strcmp(*Ptr, *ref.Ptr)<0;\n\t}\n\n\tTJS_CONST_METHOD_DEF(bool, operator >, (const tTJSString &ref))\n\t{\n\t\tif(!Ptr && !ref.Ptr) return false;\n\t\tif(!Ptr && ref.Ptr) return false;\n\t\tif(Ptr && !ref.Ptr) return true;\n\t\treturn TJS_strcmp(*Ptr, *ref.Ptr)>0;\n\t}\n\n\t//---------------------------------------------------------- operation --\n\tTJS_METHOD_DEF(void, operator +=, (const tTJSString &ref))\n\t{\n\t\tif(!ref.Ptr) return;\n\t\tIndepend();\n\t\tPtr = TJSAppendVariantString(Ptr, *ref.Ptr);\n\t}\n\n\tTJS_METHOD_DEF(void, operator +=, (const tTJSVariantString *ref))\n\t{\n\t\tif(!ref) return;\n\t\tIndepend();\n\t\tPtr = TJSAppendVariantString(Ptr, ref);\n\t}\n\n\tTJS_METHOD_DEF(void, operator +=, (const tjs_char *ref))\n\t{\n\t\tif(!ref) return;\n\t\tIndepend();\n\t\tPtr = TJSAppendVariantString(Ptr, ref);\n\t}\n\n\tTJS_METHOD_DEF(void, operator +=, (tjs_char rch))\n\t{\n\t\tIndepend();\n\t\ttjs_char ch[2];\n\t\tch[0] = rch;\n\t\tch[1] = 0;\n\t\tPtr = TJSAppendVariantString(Ptr, ch);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSString, operator +, (const tTJSString &ref))\n\t{\n\t\tif(!ref.Ptr && !Ptr) return tTJSString();\n\t\tif(!ref.Ptr) return *this;\n\t\tif(!Ptr) return ref;\n\n\t\ttTJSString newstr;\n\t\tnewstr.Ptr = TJSAllocVariantString(*this->Ptr, *ref.Ptr);\n\t\treturn newstr;\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSString, operator +, (const tjs_char *ref))\n\t{\n\t\tif(!ref && !Ptr) return tTJSString();\n\t\tif(!ref) return *this;\n\t\tif(!Ptr) return tTJSString(ref);\n\n\t\ttTJSString newstr;\n\t\tnewstr.Ptr = TJSAllocVariantString(*this->Ptr, ref);\n\t\treturn newstr;\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSString, operator +, (tjs_char rch))\n\t{\n\t\tif(!Ptr) return tTJSString(rch);\n\t\ttjs_char ch[2];\n\t\tch[0] = rch;\n\t\tch[1] = 0;\n\t\ttTJSString newstr;\n\t\tnewstr.Ptr = TJSAllocVariantString(*this->Ptr, ch);\n\t\treturn newstr;\n\t}\n\n\t/*m[*/\n\tfriend tTJSString operator + (const tjs_char *lhs, const tTJSString &rhs);\n\t/*]m*/\n\n\tTJS_CONST_METHOD_DEF(tjs_char, operator [], (tjs_uint i))\n\t{\n\t\t// returns character at i. this function does not check the range.\n\t\tif(!Ptr) return 0;\n\t\treturn Ptr->operator const tjs_char *() [i];\n\t}\n\n\tTJS_METHOD_DEF(void, Clear, ())\n\t{\n\t\tif(Ptr) Ptr->Release(), Ptr = NULL;\n\t}\n\n\tTJS_METHOD_DEF(tjs_char *, AllocBuffer, (tjs_uint len))\n\t{\n\t\t/* you must call FixLen when you allocate larger buffer than actual string length */\n\n\t\tif(Ptr) Ptr->Release();\n\t\tPtr = TJSAllocVariantStringBuffer(len);\n\t\treturn const_cast<tjs_char*>(Ptr->operator const tjs_char *());\n\t}\n\n\tTJS_METHOD_DEF(tjs_char *, AppendBuffer, (tjs_uint len))\n\t{\n\t\t/* you must call FixLen when you allocate larger buffer than actual string length */\n\n\t\tif(!Ptr) return AllocBuffer(len);\n\t\tIndepend();\n\t\tPtr->AppendBuffer(len);\n\t\treturn const_cast<tjs_char *>(Ptr->operator const tjs_char *());\n\t}\n\n\n\tTJS_METHOD_DEF(void, FixLen, ())\n\t{\n\t\tIndepend();\n\t\tif(Ptr) Ptr = Ptr->FixLength();\n\t}\n\n\tTJS_METHOD_DEF(void, Replace,\n\t\t(const tTJSString &from, const tTJSString &to, bool forall = true));\n\n\ttTJSString AsLowerCase() const;\n\ttTJSString AsUpperCase() const;\n\n\tTJS_CONST_METHOD_DEF(void, AsLowerCase, (tTJSString &dest)) { dest = AsLowerCase(); }\n\tTJS_CONST_METHOD_DEF(void, AsUpperCase, (tTJSString &dest)) { dest = AsUpperCase(); }\n\n\tTJS_METHOD_DEF(void, ToLowerCase, ());\n\tTJS_METHOD_DEF(void, ToUppserCase, ());\n\n\ttjs_int printf(const tjs_char *format, ...);\n\n\ttTJSString EscapeC() const;   // c-style string escape/unescaep\n\ttTJSString UnescapeC() const;\n\n\tTJS_CONST_METHOD_DEF(void, EscapeC, (tTJSString &dest)) { dest = EscapeC(); }\n\tTJS_CONST_METHOD_DEF(void, UnescapeC, (tTJSString &dest)) { dest = UnescapeC(); }\n\n\tTJS_CONST_METHOD_DEF(bool, StartsWith, (const tjs_char *string));\n\tTJS_CONST_METHOD_DEF(bool, StartsWith, (const tTJSString & string))\n\t\t{ return StartsWith(string.c_str()); }\n\n\tTJS_METHOD_DEF(tjs_uint32 *, GetHint, ()) { if(!Ptr) return NULL; return Ptr->GetHint(); }\n\n\tTJS_CONST_METHOD_DEF(tjs_int, GetNarrowStrLen, ());\n\tTJS_CONST_METHOD_DEF(void, ToNarrowStr, (tjs_nchar *dest, tjs_int destmaxlen));\n\n\t//------------------------------------------------------------- others --\n\tTJS_CONST_METHOD_DEF(bool, IsEmpty, ()) { return Ptr==NULL; }\n\nprivate:\n\ttjs_char * InternalIndepend();\n\npublic:\n\tTJS_METHOD_DEF(tjs_char *, Independ, ())\n\t{\n\t\t// severs sharing of the string instance\n\t\t// and returns independent internal buffer\n\n\t\t// note that you must call FixLen after making modification of the buffer\n\t\t// if you shorten the string using this method's return value.\n\t\t// USING THIS METHOD'S RETURN VALUE AND MODIFYING THE INTERNAL\n\t\t// BUFFER IS VERY DANGER.\n\n\t\tif(!Ptr) return NULL;\n\n\t\tif(Ptr->GetRefCount() == 0)\n\t\t{\n\t\t\t// already indepentent\n\t\t\treturn const_cast<tjs_char *>(Ptr->operator const tjs_char *());\n\t\t}\n\t\treturn InternalIndepend();\n\t}\n\n\n\tTJS_CONST_METHOD_DEF(tjs_int, GetLen, ())\n\t{\n#ifdef __CODEGUARD__\n\t\tif(!Ptr) return 0; // tTJSVariantString::GetLength can return zero if 'this' is NULL\n#endif\n\t\treturn Ptr->GetLength();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tjs_int, length, ()) { return GetLen(); }\n\n\tTJS_CONST_METHOD_DEF(tjs_char, GetLastChar, ())\n\t{\n\t\tif(!Ptr) return (tjs_char)0;\n\t\tconst tjs_char * p = Ptr->operator const tjs_char*();\n\t\treturn p[Ptr->GetLength() - 1];\n\t}\n\n\n\t//---------------------------------------------- allocator/deallocater --\n\tTJS_STATIC_METHOD_DEF(void *, operator new, (size_t size)) { return new char[size]; }\n\tTJS_STATIC_METHOD_DEF(void, operator delete, (void * p)) { delete [] ((char*)p); }\n\n\tTJS_STATIC_METHOD_DEF(void *, operator new [], (size_t size)) { return new char[size]; }\n\tTJS_STATIC_METHOD_DEF(void, operator delete [], (void *p)) { delete [] ((char*)p); }\n\n\tTJS_STATIC_METHOD_DEF(void *, operator new, (size_t size, void *buf)) { return buf; }\n    //--------------------------------------------- indexer / finder --\n    int      IndexOf (const tTJSString& str, unsigned int pos = 0) const;\n    int      IndexOf (const char* s, unsigned int pos = 0, unsigned int n = -1) const { return IndexOf(tTJSString(s, n), pos); }\n    int      IndexOf (tjs_char c, unsigned int pos = 0) const { return IndexOf(tTJSString(&c, 1), pos); }\n    tTJSString    SubString(unsigned int pos, unsigned int len) const;\n    tTJSString Trim();\n};\n/*end-of-tTJSString*/\nTJS_EXP_FUNC_DEF(tTJSString, operator +, (const tjs_char *lhs, const tTJSString &rhs));\n\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSString, TJSInt32ToHex, (tjs_uint32 num, int zeropad = 8));\n//---------------------------------------------------------------------------\n/*[*/\ntypedef tTJSString ttstr;\n/*]*/\n//---------------------------------------------------------------------------\n} // namespace TJS\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsTypes.h",
    "content": "/*---------------------------------------------------------------------------*/\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/*---------------------------------------------------------------------------*/\n/* \"TJS2\" type definitions                                                   */\n/*---------------------------------------------------------------------------*/\n\n#ifndef __TJSTYPES_H__\n#define __TJSTYPES_H__\n\n#include <stdint.h>\n#include <stddef.h> // ptrdiff_t\n\n#ifdef HAVE_CONFIG_H\n #include \"config.h\"\n\n #ifndef HAVE_STRINGIZE\n # error \"preprocessor stringize required.\"\n #endif\n\n #if SIZEOF_INT < 4\n # error \"sizeof(int) must be larger than or equal to 4.\"\n #endif\n#endif /* end of HAVE_CONFIG_H */\n\n\n\n/* Functions that needs to be exported ( for non-class-member functions ) */\n/* This should only be applyed for function declaration in headers ( not body ) */\n#define TJS_EXP_FUNC_DEF(rettype, name, arg) extern rettype name arg\n\n\n/* Functions that needs to be exported ( for class-member functions ) */\n#define TJS_METHOD_DEF(rettype, name, arg) rettype name arg\n#define TJS_CONST_METHOD_DEF(rettype, name, arg) rettype name arg const\n#define TJS_STATIC_METHOD_DEF(rettype, name, arg) static rettype name arg\n#define TJS_STATIC_CONST_METHOD_DEF(rettype, name, arg) static rettype name arg const\n#define TJS_METHOD_RET_EMPTY\n#define TJS_METHOD_RET(type)\n\n\n\n#if defined(_WIN32)  && !defined(__GNUC__)\n\n/* VC++/BCC */\n\n/*[*/\ntypedef __int8 tjs_int8;\ntypedef unsigned __int8 tjs_uint8;\ntypedef __int16 tjs_int16;\ntypedef unsigned __int16 tjs_uint16;\ntypedef __int32 tjs_int32;\ntypedef unsigned __int32 tjs_uint32;\ntypedef __int64 tjs_int64;\ntypedef unsigned __int64 tjs_uint64;\ntypedef int tjs_int;    /* at least 32bits */\ntypedef unsigned int tjs_uint;    /* at least 32bits */\n\n#ifdef __cplusplus\ntypedef wchar_t tjs_char;\n#else\ntypedef unsigned short tjs_char;\n#endif\n\n#define TJS_W(X) L##X\n#define TJS_N(X) X\n\ntypedef char tjs_nchar;\ntypedef double tjs_real;\n\n#define TJS_HOST_IS_BIG_ENDIAN 0\n#define TJS_HOST_IS_LITTLE_ENDIAN 1\n\n#ifndef TJS_INTF_METHOD\n#define TJS_INTF_METHOD\n\t/* TJS_INTF_METHOD is \"cdecl\" (by default)\n\t\tsince TJS2 2.4.14 (kirikir2 2.25 beta 1) */\n#endif\n\n#define TJS_USERENTRY __cdecl\n\n#define TJS_I64_VAL(x) ((tjs_int64)(x##i64))\n#define TJS_UI64_VAL(x) ((tjs_uint64)(x##i64))\n\n#ifdef _M_X64\n#define TJS_64BIT_OS\t/* 64bit windows */\n#endif\n\ntypedef intptr_t tjs_intptr_t;\ntypedef uintptr_t tjs_uintptr_t;\n\n/*]*/\n\n#else\n\n/* gcc ? */\n\n#ifndef __GNUC__\n #error \"GNU C++ required.\"\n#endif\n/*\n#ifndef HAVE_CONFIG_H\n #error \"-DHAVE_CONFIG_H and config.h required.\"\n#endif\n*/\n#include <sys/types.h>\n#include <stdint.h>\n\n\n#if defined(__linux__)\n\ttypedef int8_t tjs_int8;\n\ttypedef u_int8_t tjs_uint8;\n\ttypedef int16_t tjs_int16;\n\ttypedef u_int16_t tjs_uint16;\n\ttypedef int32_t tjs_int32;\n\ttypedef u_int32_t tjs_uint32;\n\ttypedef int64_t tjs_int64;\n\ttypedef u_int64_t tjs_uint64;\n#elif defined(__GNUC__)\n\ttypedef int8_t tjs_int8;\n\ttypedef uint8_t tjs_uint8;\n\ttypedef int16_t tjs_int16;\n\ttypedef uint16_t tjs_uint16;\n\ttypedef int32_t tjs_int32;\n\ttypedef uint32_t tjs_uint32;\n\ttypedef int64_t tjs_int64;\n\ttypedef uint64_t tjs_uint64;\n#endif\n\n#ifdef __cplusplus\n    typedef char16_t tjs_char;\n#else\n    typedef unsigned short tjs_char;\n#endif\n#define TJS_W(X) u##X\n#define TJS_N(X) X\n\ntypedef char tjs_nchar;\ntypedef double tjs_real;\n\ntypedef int tjs_int;\ntypedef unsigned int tjs_uint;\n\ntypedef intptr_t tjs_intptr_t;\ntypedef uintptr_t tjs_uintptr_t;\n\n#define TJS_I64_VAL(x) ((tjs_int64)(x##LL))\n#define TJS_UI64_VAL(x) ((tjs_uint64)(x##LL))\n\n#ifdef WORDS_BIGENDIAN\n\t#define TJS_HOST_IS_BIG_ENDIAN 1\n\t#define TJS_HOST_IS_LITTLE_ENDIAN 0\n#else\n\t#define TJS_HOST_IS_BIG_ENDIAN 0\n\t#define TJS_HOST_IS_LITTLE_ENDIAN 1\n#endif\n\n#define TJS_INTF_METHOD\n#define TJS_USERENTRY\n\n\n#endif /* end of defined(_WIN32) && !defined(__GNUC__) */\n\n/*[*/\n\n\ntypedef tjs_int32 tjs_error;\n\ntypedef tjs_int64 tTVInteger;\ntypedef tjs_real tTVReal;\n\ntypedef size_t tjs_size;\ntypedef ptrdiff_t tjs_offset;\n\n/* IEEE double manipulation support\n (TJS requires IEEE double(64-bit float) native support on machine or C++ compiler) */\n\n/*\n\n63 62       52 51                         0\n+-+-----------+---------------------------+\n|s|    exp    |         significand       |\n+-+-----------+---------------------------+\n\ns = sign,  negative if this is 1, otherwise positive.\n\n\n\n*/\n\n/* double related constants */\n#define TJS_IEEE_D_EXP_MAX 1023\n#define TJS_IEEE_D_EXP_MIN -1022\n#define TJS_IEEE_D_SIGNIFICAND_BITS 52\n\n#define TJS_IEEE_D_EXP_BIAS 1023\n\n/* component extraction */\n#define TJS_IEEE_D_SIGN_MASK              (TJS_UI64_VAL(0x8000000000000000))\n#define TJS_IEEE_D_EXP_MASK               (TJS_UI64_VAL(0x7ff0000000000000))\n#define TJS_IEEE_D_SIGNIFICAND_MASK       (TJS_UI64_VAL(0x000fffffffffffff))\n#define TJS_IEEE_D_SIGNIFICAND_MSB_MASK   (TJS_UI64_VAL(0x0008000000000000))\n\n#define TJS_IEEE_D_GET_SIGN(x)   (0!=(x & TJS_IEEE_D_SIGN_MASK))\n#define TJS_IEEE_D_GET_EXP(x)  ((tjs_int)(((x & TJS_IEEE_D_EXP_MASK) >> \\\n\t\t\t\t\t\t\t\tTJS_IEEE_D_SIGNIFICAND_BITS) - TJS_IEEE_D_EXP_BIAS))\n#define TJS_IEEE_D_GET_SIGNIFICAND(x) (x & TJS_IEEE_D_SIGNIFICAND_MASK)\n\n/* component composition */\n#define TJS_IEEE_D_MAKE_SIGN(x)  ((x)?TJS_UI64_VAL(0x8000000000000000):TJS_UI64_VAL(0))\n#define TJS_IEEE_D_MAKE_EXP(x)   ((tjs_uint64)(x + TJS_IEEE_D_EXP_BIAS) << 52)\n#define TJS_IEEE_D_MAKE_SIGNIFICAND(x) ((tjs_uint64)(x))\n\n/* special expression */\n /* (quiet) NaN */\n  #define TJS_IEEE_D_P_NaN (tjs_uint64)(TJS_IEEE_D_EXP_MASK|TJS_IEEE_D_SIGNIFICAND_MSB_MASK)\n  #define TJS_IEEE_D_N_NaN (tjs_uint64)(TJS_IEEE_D_SIGN_MASK|TJS_IEEE_D_P_NaN)\n /* infinite */\n  #define TJS_IEEE_D_P_INF (tjs_uint64)(TJS_IEEE_D_EXP_MASK)\n  #define TJS_IEEE_D_N_INF (tjs_uint64)(TJS_IEEE_D_SIGN_MASK|TJS_IEEE_D_P_INF)\n\n/* special expression check */\n  #define TJS_IEEE_D_IS_NaN(x) ((TJS_IEEE_D_EXP_MASK & (x)) == TJS_IEEE_D_EXP_MASK) && \\\n\t\t\t\t(((x) & TJS_IEEE_D_SIGNIFICAND_MSB_MASK) || \\\n\t\t\t\t(!((x) & TJS_IEEE_D_SIGNIFICAND_MSB_MASK) && \\\n\t\t\t\t((x) & (TJS_IEEE_D_SIGNIFICAND_MASK ^ TJS_IEEE_D_SIGNIFICAND_MSB_MASK))))\n  #define TJS_IEEE_D_IS_INF(x) (((TJS_IEEE_D_EXP_MASK & (x)) == TJS_IEEE_D_EXP_MASK) && \\\n\t\t\t\t(!((x) & TJS_IEEE_D_SIGNIFICAND_MASK)))\n\n/*]*/\n\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsUtils.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// utility functions\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsUtils.h\"\n#include <mutex>\n#include <thread>\n#include \"TickCount.h\"\n#include \"Platform.h\"\n\nnamespace TJS\n{\n\nstruct tTJSCriticalSectionImpl {\n\tstd::mutex _mutex;\n\tstd::thread::id _tid;\n\tbool lock();\n\tvoid unlock();\n};\n\nbool tTJSCriticalSectionImpl::lock() {\n\tstd::thread::id id = std::this_thread::get_id();\n\tif (_tid == id) return false;\n\t_mutex.lock();\n\t_tid = id;\n\treturn true;\n}\n\nvoid tTJSCriticalSectionImpl::unlock() {\n\t_tid = std::thread::id();\n\t_mutex.unlock();\n}\n\nbool tTJSCriticalSection::lock() {\n\treturn _impl->lock();\n}\n\nvoid tTJSCriticalSection::unlock() {\n\t_impl->unlock();\n}\n\ntTJSCriticalSection::tTJSCriticalSection() {\n\t_impl = new tTJSCriticalSectionImpl;\n}\n\ntTJSCriticalSection::~tTJSCriticalSection() {\n\tdelete _impl;\n}\n\nvoid tTJSSpinLock::lock() {\n\twhile (atom_lock.test_and_set(std::memory_order_acquire)) {\n\t\tstd::this_thread::yield();\n//\t\tTVPRelinquishCPU();\n\t}\n}\n\nvoid tTJSSpinLock::unlock() {\n\tatom_lock.clear(std::memory_order_release);\n}\n\ntTJSSpinLock::tTJSSpinLock() {\n\tunlock();\n}\n\ntTJSSpinLockHolder::tTJSSpinLockHolder(tTJSSpinLock &lock) {\n\tlock.lock();\n\tLock = &lock;\n}\n\ntTJSSpinLockHolder::~tTJSSpinLockHolder() {\n\tif (Lock) {\n\t\tLock->unlock();\n\t}\n}\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * TJSObjectTraceTarget;\n//---------------------------------------------------------------------------\nstatic void TJSTrimStringLength(tTJSString &str, tjs_int len)\n{\n\tif(str.GetLen() > len)\n\t{\n\t\ttjs_char *p = str.Independ();\n\t\tp[len] = 0; // trim length\n\t\tif(len >= 3)\n\t\t{\n\t\t\tp[len-1] = TJS_W('.');\n\t\t\tp[len-2] = TJS_W('.');\n\t\t\tp[len-3] = TJS_W('.');\n\t\t}\n\t\tstr.FixLen();\n\t}\n}\n//---------------------------------------------------------------------------\nconst tjs_char * TJSVariantTypeToTypeString(tTJSVariantType type)\n{\n\tswitch(type)\n\t{\n\tcase tvtVoid: return (const tjs_char *)TJS_W(\"void\");\n\tcase tvtInteger: return (const tjs_char *)TJS_W(\"int\");\n\tcase tvtReal: return (const tjs_char *)TJS_W(\"real\");\n\tcase tvtString: return (const tjs_char *)TJS_W(\"string\");\n\tcase tvtOctet: return (const tjs_char *)TJS_W(\"octet\");\n\tcase tvtObject: return (const tjs_char *)TJS_W(\"object\");\n\t}\n\treturn (const tjs_char *)TJS_W(\"unknown\");\n}\n//---------------------------------------------------------------------------\ntTJSString TJSVariantToReadableString(const tTJSVariant &val,\n\ttjs_int maxlen)\n{\n\t// convert given variant to human-readable string\n\t// ( eg. \"(string)\\\"this is a\\\\nstring\\\"\" )\n\n\ttTJSVariantType type = val.Type();\n\n\tswitch(type)\n\t{\n\tcase tvtVoid:\n\t  {\n\t\ttTJSString str(TJS_W(\"(void)\"));\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\tcase tvtInteger:\n\t  {\n\t\ttTJSString str(TJS_W(\"(int)\"));\n\t\tstr += (tTJSString)val;\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\tcase tvtReal:\n\t  {\n\t\ttTJSString str(TJS_W(\"(real)\"));\n\t\tstr += (tTJSString)val;\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\tcase tvtString:\n\t  {\n\t\ttTJSString str(TJS_W(\"(string)\\\"\"));\n\t\tstr += ttstr(val).EscapeC();\n\t\tstr += TJS_W(\"\\\"\");\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\tcase tvtOctet:\n\t  {\n\t\t// TODO: octet conversion\n\t\ttTJSString str(TJS_W(\"(octet)<% \"));\n\t\ttTJSVariantString * s = TJSOctetToListString(val.AsOctetNoAddRef());\n\t\ttry\n\t\t{\n\t\t\tstr += s;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(s) s->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(s) s->Release();\n\t\tstr += TJS_W(\" %>\");\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\tcase tvtObject:\n\t  {\n\t\ttTJSString str(TJS_W(\"(object)\"));\n\t\ttry\n\t\t{\n\t\t\tstr += ttstr(val);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t}\n\t\tTJSTrimStringLength(str, maxlen);\n\t\treturn str;\n\t  }\n\t}\n\treturn TJS_W(\"\");\n}\n//---------------------------------------------------------------------------\ntTJSString TJSVariantToExpressionString(const tTJSVariant &val)\n{\n\t// convert given variant to string which can be interpret as an expression.\n\t// this function does not convert objects ( returns empty string )\n\n\ttTJSVariantType type = val.Type();\n\n\tswitch(type)\n\t{\n\tcase tvtVoid:\n\t  {\n\t\treturn TJS_W(\"void\");\n\t  }\n\tcase tvtInteger:\n\t  {\n\t\treturn ttstr(val);\n\t  }\n\tcase tvtReal:\n\t  {\n\t\ttTJSString str;\n\t\ttTJSVariantString *s = TJSRealToHexString(val.AsReal());\n\t\ttry\n\t\t{\n\t\t\tstr = s;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(s) s->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(s) s->Release();\n\t\treturn str + TJS_W(\" /\") TJS_W(\"* \") + ttstr(val) + TJS_W(\" *\") TJS_W(\"/\");\n\t  }\n\tcase tvtString:\n\t  {\n\t\ttTJSString str(TJS_W(\"\\\"\"));\n\t\tstr += ttstr(val).EscapeC();\n\t\tstr += TJS_W(\"\\\"\");\n\t\treturn str;\n\t  }\n\tcase tvtOctet:\n\t  {\n\t\ttTJSString str(TJS_W(\"<% \"));\n\t\ttTJSVariantString * s = TJSOctetToListString(val.AsOctetNoAddRef());\n\t\ttry\n\t\t{\n\t\t\tstr += s;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(s) s->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(s) s->Release();\n\t\tstr += TJS_W(\" %>\");\n\t\treturn str;\n\t  }\n\tcase tvtObject:\n\t  {\n\t\treturn TJS_W(\"\");\n\t  }\n\t}\n\treturn TJS_W(\"\");\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TJSAlignedAlloc : aligned memory allocator\n//---------------------------------------------------------------------------\n// template classes to determine an integer type which have the same size as void *.\nstruct tTJSPointerSizeEnum { enum tTJSPointerSize { size = sizeof(void*) }; };\ntemplate <tjs_int size> struct tTJSPointerSizedIntegerBase { typedef long type; };\ntemplate <> struct tTJSPointerSizedIntegerBase<8> { typedef tjs_uint64 type; };\ntemplate <> struct tTJSPointerSizedIntegerBase<4> { typedef tjs_uint32 type; };\nstruct tTJSPointerSizedInteger : public tTJSPointerSizedIntegerBase< tTJSPointerSizeEnum::size > {};\n//---------------------------------------------------------------------------\nvoid * TJSAlignedAlloc(tjs_uint bytes, tjs_uint align_bits)\n{\n\t// aligned memory allocation is to be used to gain performance on some processors.\n\ttjs_int align = 1 << align_bits;\n\tvoid *ptr = (void *)(new tjs_uint8[bytes + align + sizeof(void*)]);\n\tvoid *org_ptr = ptr;\n\ttTJSPointerSizedInteger::type *iptr =\n\t\treinterpret_cast<tTJSPointerSizedInteger::type *>(&ptr);\n\t*iptr += align + sizeof(void*);\n\t*iptr &= ~(tTJSPointerSizedInteger::type)(align - 1);\n\t(reinterpret_cast<void**>(ptr))[-1] = org_ptr;\n\treturn ptr;\n}\n//---------------------------------------------------------------------------\nvoid TJSAlignedDealloc(void *ptr)\n{\n\tdelete [] (tjs_uint8*)((reinterpret_cast<void**>(ptr))[-1]);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// floating-point class checker\n//---------------------------------------------------------------------------\ntjs_uint32 TJSGetFPClass(tjs_real r)\n{\n\ttjs_uint64 *ui64 = (tjs_uint64*)&r;\n\n\tif(TJS_IEEE_D_IS_NaN(*ui64))\n\t{\n\t\tif(TJS_IEEE_D_SIGN_MASK & *ui64)\n\t\t\treturn TJS_FC_CLASS_NAN | TJS_FC_SIGN_MASK;\n\t\telse\n\t\t\treturn TJS_FC_CLASS_NAN;\n\t}\n\tif(TJS_IEEE_D_IS_INF(*ui64))\n\t{\n\t\tif(TJS_IEEE_D_SIGN_MASK & *ui64)\n\t\t\treturn TJS_FC_CLASS_INF | TJS_FC_SIGN_MASK;\n\t\telse\n\t\t\treturn TJS_FC_CLASS_INF;\n\t}\n\tif(TJS_IEEE_D_SIGN_MASK & *ui64)\n\t\treturn TJS_FC_CLASS_NORMAL | TJS_FC_SIGN_MASK;\n\telse\n\t\treturn TJS_FC_CLASS_NORMAL;\n}\n//---------------------------------------------------------------------------\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsUtils.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// utility functions\n//---------------------------------------------------------------------------\n#ifndef tjsUtilsH\n#define tjsUtilsH\n\n#include \"tjsVariant.h\"\n#include \"tjsString.h\"\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSCriticalSection ( implement on each platform for multi-threading support )\n//---------------------------------------------------------------------------\nstruct tTJSCriticalSectionImpl;\nstruct tTJSCriticalSection {\n\ttTJSCriticalSectionImpl *_impl;\n\ttTJSCriticalSection();\n\t~tTJSCriticalSection();\n\tbool lock();\n\tvoid unlock();\n};\n//---------------------------------------------------------------------------\n// interlocked operation ( implement on each platform for multi-threading support )\n//---------------------------------------------------------------------------\n/*\n#ifdef __WIN32__\n#include <Windows.h>\n\n// we assume that sizeof(tjs_uint) is 4 on TJS2/win32.\n\ninline tjs_uint TJSInterlockedIncrement(tjs_uint & value)\n{\n\treturn InterlockedIncrement((long*)&value);\n}\n\n#else\n\ninline\n\n#endif\n*/\n//---------------------------------------------------------------------------\n// tTJSCriticalSectionHolder\n//---------------------------------------------------------------------------\nclass tTJSCriticalSectionHolder {\n\ttTJSCriticalSection *_cs;\n\npublic:\n\ttTJSCriticalSectionHolder(tTJSCriticalSection& cs) {\n\t\tif (cs.lock()) {\n\t\t\t_cs = &cs;\n\t\t} else {\n\t\t\t_cs = nullptr;\n\t}\n\t}\n\t~tTJSCriticalSectionHolder() {\n\t\tif (_cs) _cs->unlock();\n\t}\n};\ntypedef tTJSCriticalSectionHolder tTJSCSH;\n//---------------------------------------------------------------------------\ntypedef tTJSCriticalSection tTJSStaticCriticalSection;\n\nstruct tTJSSpinLock {\n\tstd::atomic_flag atom_lock;\n\ttTJSSpinLock();\n\tvoid lock(); // will stuck if locked in same thread!\n\tvoid unlock();\n};\n\nclass tTJSSpinLockHolder {\n\ttTJSSpinLock* Lock;\npublic:\n\ttTJSSpinLockHolder(tTJSSpinLock &lock);\n\n\t~tTJSSpinLockHolder();\n};\n\n//---------------------------------------------------------------------------\n// tTJSAtExit / tTJSAtStart\n//---------------------------------------------------------------------------\nclass tTJSAtExit\n{\n\tvoid (*Function)();\npublic:\n\ttTJSAtExit(void (*func)()) { Function = func; };\n\t~tTJSAtExit() { Function(); }\n};\n//---------------------------------------------------------------------------\nclass tTJSAtStart\n{\npublic:\n\ttTJSAtStart(void (*func)()) { func(); };\n};\n//---------------------------------------------------------------------------\nclass iTJSDispatch2;\nextern iTJSDispatch2 * TJSObjectTraceTarget;\n\n#define TJS_DEBUG_REFERENCE_BREAK \\\n\tif(TJSObjectTraceTarget == (iTJSDispatch2*)this) TJSNativeDebuggerBreak()\n#define TJS_SET_REFERENCE_BREAK(x) TJSObjectTraceTarget=(x)\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(const tjs_char *, TJSVariantTypeToTypeString, (tTJSVariantType type));\n\t// convert given variant type to type string ( \"void\", \"int\", \"object\" etc.)\n\nTJS_EXP_FUNC_DEF(tTJSString, TJSVariantToReadableString, (const tTJSVariant &val, tjs_int maxlen = 512));\n\t// convert given variant to human-readable string\n\t// ( eg. \"(string)\\\"this is a\\\\nstring\\\"\" )\nTJS_EXP_FUNC_DEF(tTJSString, TJSVariantToExpressionString, (const tTJSVariant &val));\n\t// convert given variant to string which can be interpret as an expression.\n\t// this function does not convert objects ( returns empty string )\n\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSRefHolder : a object holder for classes that has AddRef and Release methods\n//---------------------------------------------------------------------------\ntemplate <typename T>\nclass tTJSRefHolder\n{\nprivate:\n\tT *Object;\npublic:\n\ttTJSRefHolder(T * ref) { Object = ref; Object->AddRef(); }\n\ttTJSRefHolder(const tTJSRefHolder<T> &ref)\n\t{\n\t\tObject = ref.Object;\n\t\tObject->AddRef();\n\t}\n\t~tTJSRefHolder() { Object->Release(); }\n\n\tT* GetObject() { Object->AddRef(); return Object; }\n\tT* GetObjectNoAddRef() const { return Object; }\n\n\tconst tTJSRefHolder & operator = (const tTJSRefHolder & rhs)\n\t{\n\t\tif(rhs.Object != Object)\n\t\t{\n\t\t\tObject->Release();\n\t\t\tObject = rhs.Object;\n\t\t\tObject->AddRef();\n\t\t}\n\t\treturn *this;\n\t}\n};\n\ntemplate <typename T>\nclass tRefHolder\n{\n\tstruct _RefCountWrapper\n\t{\n\t\tT* _ptr = nullptr;\n\t\tint RefCount = 1;\n\n\t\t_RefCountWrapper() = default;\n\t\t_RefCountWrapper(T* p) : _ptr(p) {}\n\t\t~_RefCountWrapper() { if (_ptr) delete _ptr; }\n\t\tvoid AddRef() { RefCount++; }\n\t\tvoid Release()\n\t\t{\n\t\t\tif (RefCount == 1) {\n\t\t\t\tdelete this;\n\t\t\t} else {\n\t\t\t\tRefCount--;\n\t\t\t}\n\t\t}\n\t};\n\t_RefCountWrapper *_ptr;\n\npublic:\n\ttRefHolder() : _ptr(nullptr) {}\n\ttRefHolder(T* p) : _ptr(nullptr) { if (p) _ptr = new _RefCountWrapper(p); }\n\ttRefHolder(const tRefHolder<T> &ref) { _ptr = ref._ptr; if (_ptr) _ptr->AddRef(); }\n\t~tRefHolder() { if (_ptr) _ptr->Release(); }\n\tconst tRefHolder & operator = (const tRefHolder & rhs) {\n\t\tif (rhs._ptr != _ptr) {\n\t\t\tif (_ptr)_ptr->Release();\n\t\t\t_ptr = rhs._ptr;\n\t\t\tif (_ptr) _ptr->AddRef();\n\t\t}\n\t\treturn *this;\n\t}\n\tT* get() const { if (_ptr) return _ptr->_ptr; return nullptr; }\n\toperator T*() const { return get(); }\n\tT* operator->() const { return get(); }\n};\n\ntemplate <typename T>\nclass tRefPtr\n{\nprivate:\n\tT *_ptr;\npublic:\n\ttRefPtr() : _ptr(nullptr) {}\n\ttRefPtr(T* p) : _ptr(nullptr) { if (p) p->AddRef(), _ptr = p; }\n\ttRefPtr(const tRefPtr<T> &ref) { _ptr = ref._ptr; if (_ptr) _ptr->AddRef(); }\n\t~tRefPtr() { if (_ptr) _ptr->Release(); }\n\tconst tRefPtr & operator = (const tRefPtr & rhs) {\n\t\tif (rhs._ptr != _ptr) {\n\t\t\tif (_ptr)_ptr->Release();\n\t\t\t_ptr = rhs._ptr;\n\t\t\tif (_ptr) _ptr->AddRef();\n\t\t}\n\t\treturn *this;\n\t}\n\tconst tRefPtr & operator = (T *rhs) {\n\t\tif (rhs != _ptr) {\n\t\t\tif (_ptr)_ptr->Release();\n\t\t\t_ptr = rhs;\n\t\t\tif (_ptr) _ptr->AddRef();\n\t\t}\n\t\treturn *this;\n\t}\n\tT* get() const { return _ptr; }\n\toperator T*() const { return get(); }\n\tT* operator->() const { return get(); }\n};\n\n/*]*/\n\n//---------------------------------------------------------------------------\n\n#define VECLIST_MIN_CAPACITY 32\n#define VECLIST_MAX_CAPACITY_INCREASE 2048\n\ntemplate<typename T>\nclass tVectorList {\nprotected:\n\tstruct _tVectorList_Node {\n\t\tT Data;\n\t\tint prevIndex;\n\t\tint nextIndex;\n\t} *PointerBuffPtr;\n\tstd::vector<int> UnusedIndexStack;\n\tunsigned int nCpacity;\n\tunsigned int nQuantity;\n\tint lastIndex;\n\tint firstIndex;\n\n\ttVectorList(const tVectorList&);//���ɱ�����\n\ttVectorList& operator=(const tVectorList&);//���ɱ���ֵ\n\n\tvoid _erase(unsigned int index) {\n\t\t_tVectorList_Node &Node = PointerBuffPtr[index];\n\t\tif (Node.prevIndex != -1) {\n\t\t\tPointerBuffPtr[Node.prevIndex].nextIndex = Node.nextIndex;\n\t\t} else {\n\t\t\tfirstIndex = Node.nextIndex;\n\t\t}\n\t\tif (Node.nextIndex != -1) {\n\t\t\tPointerBuffPtr[Node.nextIndex].prevIndex = Node.prevIndex;\n\t\t} else {\n\t\t\tlastIndex = Node.prevIndex;\n\t\t}\n\t\tUnusedIndexStack.push_back(index);\n\t\t--nQuantity;\n\t}\n\n\tint _find(T &_Val) const {\n\t\tint i = firstIndex;\n\t\tfor (; i != -1; i = PointerBuffPtr[i].nextIndex) {\n\t\t\tif (PointerBuffPtr[i].Data == _Val)\n\t\t\t\tbreak;\n\t\t}\n\t\treturn i;\n\t}\n\n\tinline void _ensureCapacity() {\n\t\tif (UnusedIndexStack.empty())\n\t\t{\n\t\t\tint nNewCapacity;\n\t\t\tif (!PointerBuffPtr) {\n\t\t\t\tnNewCapacity = VECLIST_MIN_CAPACITY;\n\t\t\t\tPointerBuffPtr = (_tVectorList_Node*)new char[VECLIST_MIN_CAPACITY * sizeof(_tVectorList_Node)];\n\t\t\t} else {\n\t\t\t\tnNewCapacity = (nCpacity < VECLIST_MAX_CAPACITY_INCREASE) ?\n\t\t\t\t\tnCpacity * 2 : nCpacity + VECLIST_MAX_CAPACITY_INCREASE;\n\t\t\t\t_tVectorList_Node* newPtr = (_tVectorList_Node*)new char[nNewCapacity * sizeof(_tVectorList_Node)];\n\t\t\t\tmemcpy(newPtr, PointerBuffPtr, sizeof(_tVectorList_Node)* nCpacity);\n\t\t\t\tdelete[](char*)PointerBuffPtr;\n\t\t\t\tPointerBuffPtr = newPtr;\n\t\t\t}\n\t\t\tfor (int i = nNewCapacity - 1; i >= (int)nCpacity; --i) {\n\t\t\t\tUnusedIndexStack.push_back(i);\n\t\t\t}\n\t\t\tnCpacity = nNewCapacity;\n\t\t}\n\t}\n\npublic:\n\ttVectorList()\n\t\t: nCpacity(0)\n\t\t, nQuantity(0)\n\t\t, PointerBuffPtr(0)\n\t\t, lastIndex(-1)\n\t\t, firstIndex(-1)\n\t{\n\t}\n\n\t~tVectorList() {\n\t\tclear();\n\t}\n\n\tunsigned int capacity() const { return nCpacity; }\n\tunsigned int size() const { return nQuantity; }\n\t//     void resize(unsigned int newsize) {\n\t//         if(newsize < nQuantity) nQuantity = newsize;\n\t//     }\n\tbool empty() const { return nQuantity == 0; }\n\t//T* data() { return PointerBuffPtr; }\n\tvoid push_front(T &_Val) {\n\t\t_ensureCapacity();\n\t\tint currentIndex = UnusedIndexStack.back();\n\t\tUnusedIndexStack.pop_back();\n\t\t_tVectorList_Node &Node = PointerBuffPtr[currentIndex];\n\t\tNode.Data = _Val;\n\t\tNode.prevIndex = -1;\n\t\tNode.nextIndex = firstIndex;\n\t\tif (firstIndex != -1) {\n\t\t\t_tVectorList_Node &nextNode = PointerBuffPtr[firstIndex];\n\t\t\tnextNode.prevIndex = currentIndex;\n\t\t} else {\n\t\t\tlastIndex = currentIndex;\n\t\t}\n\t\tfirstIndex = currentIndex;\n\t\t++nQuantity;\n\t}\n\tvoid push_back(const T &_Val) {\n\t\t_ensureCapacity();\n\t\tint currentIndex = UnusedIndexStack.back();\n\t\tUnusedIndexStack.pop_back();\n\t\t_tVectorList_Node &Node = PointerBuffPtr[currentIndex];\n\t\tNode.Data = _Val;\n\t\tNode.prevIndex = lastIndex;\n\t\tNode.nextIndex = -1;\n\t\tif (lastIndex != -1) {\n\t\t\t_tVectorList_Node &prevNode = PointerBuffPtr[lastIndex];\n\t\t\tprevNode.nextIndex = currentIndex;\n\t\t} else {\n\t\t\tfirstIndex = currentIndex;\n\t\t}\n\t\tlastIndex = currentIndex;\n\t\t++nQuantity;\n\t}\n\tT& pop_back() {\n\t\t_tVectorList_Node &Node = PointerBuffPtr[lastIndex];\n\t\t_erase(lastIndex);\n\t\treturn Node.Data;\n\t}\n\tT& pop_front() {\n\t\t_tVectorList_Node &Node = PointerBuffPtr[firstIndex];\n\t\t_erase(firstIndex);\n\t\treturn Node.Data;\n\t}\n\tT& back() const { return PointerBuffPtr[lastIndex].Data; }\n\tT& front() const { return PointerBuffPtr[firstIndex].Data; }\n\tbool remove(T &arg) {\n\t\tint i = _find(arg);\n\t\tif (i != -1) {\n\t\t\t_erase(i);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tbool contains(T &arg) const { return _find(arg) != -1; }\n\tvoid clean() {\n\t\tif (PointerBuffPtr) delete[](char*)PointerBuffPtr;\n\t\tPointerBuffPtr = 0;\n\t\tnCpacity = 0;\n\t\tnQuantity = 0;\n\t\tlastIndex = firstIndex = -1;\n\t\tUnusedIndexStack.clear();\n\t}\n\n\tvoid clear() {\n\t\tif (!nCpacity) return;\n\t\tif (nCpacity <= VECLIST_MIN_CAPACITY * 2) {\n\t\t\tnQuantity = 0;\n\t\t\tlastIndex = firstIndex = -1;\n\t\t\tUnusedIndexStack.resize(nCpacity);\n\t\t\tint *p = &UnusedIndexStack.front();\n\t\t\tfor (int i = nCpacity - 1; i >= 0; --i) {\n\t\t\t\t*p++ = i;\n\t\t\t}\n\t\t} else {\n\t\t\tclean();\n\t\t}\n\t}\n\n\tclass iterator {\n\t\tfriend class tVectorList<T>;\n\tprivate:\n\t\t_tVectorList_Node** m_pNodeBuffer;\n\t\tint index;\n\n\tpublic:\n\t\titerator() :m_pNodeBuffer(0), index(-1){}\n\t\titerator(_tVectorList_Node** _p, int _index) :m_pNodeBuffer(_p), index(_index){}\n\n\t\tbool operator== (iterator rhs){ return m_pNodeBuffer == rhs.m_pNodeBuffer && index == rhs.index; }\n\t\tbool operator!= (iterator rhs){ return m_pNodeBuffer != rhs.m_pNodeBuffer || index != rhs.index; }\n\t\titerator&  operator++(){ // ++ prefix\n\t\t\tif (!end()) {\n\t\t\t\tindex = (*m_pNodeBuffer)[index].nextIndex;\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t\tconst iterator operator++(int _zero) { // ++ suffix\n\t\t\titerator ret = *this;\n\t\t\tif (!end()) {\n\t\t\t\tindex = (*m_pNodeBuffer)[index].nextIndex;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t\titerator&  operator--(){ // -- prefix\n\t\t\tif (!end())\n\t\t\t\tindex = (*m_pNodeBuffer)[index].prevIndex;\n\t\t\treturn *this;\n\t\t}\n\t\tconst iterator operator--(int _zero){ // -- suffix\n\t\t\titerator ret = *this;\n\t\t\tif (!end())\n\t\t\t\tindex = (*m_pNodeBuffer)[index].prevIndex;\n\t\t\treturn ret;\n\t\t}\n\t\tT& operator*() {\n#if (defined(WIN32) || defined(_WIN32)) && defined(_DEBUG)\n\t\t\tif (end())\n\t\t\t\tthrow;\n#endif\n\t\t\treturn (*m_pNodeBuffer)[index].Data;\n\t\t}\n\t\tT* operator->() {\n#if (defined(WIN32) || defined(_WIN32)) && defined(_DEBUG)\n\t\t\tif (end())\n\t\t\t\tthrow;\n#endif\n\t\t\treturn &(*m_pNodeBuffer)[index].Data;\n\t\t}\n\t\toperator bool() { return !end(); }\n\t\tbool end() { return index < 0; }\n\t};\n\titerator begin() { return iterator(&PointerBuffPtr, firstIndex); }\n\titerator rbegin() { return iterator(&PointerBuffPtr, lastIndex); }\n\titerator end() { return iterator(&PointerBuffPtr, -1); }\n\titerator rend() { return iterator(&PointerBuffPtr, -1); }\n\titerator find(T &_Val) { return iterator(&PointerBuffPtr, _find(_Val)); }\n\ttypedef iterator const_iterator;\n\n\tconst_iterator begin() const { return const_iterator(&PointerBuffPtr, firstIndex); }\n\tconst_iterator rbegin() const { return const_iterator(&PointerBuffPtr, lastIndex); }\n\tconst_iterator end() const { return const_iterator(&PointerBuffPtr, -1); }\n\tconst_iterator rend() const { return const_iterator(&PointerBuffPtr, -1); }\n\tconst_iterator find(T &_Val) const { return const_iterator(&PointerBuffPtr, _find(_Val)); }\n\tvoid erase(const iterator &it) { _erase(it.index); }\n\tvoid insert_before(iterator &it, T &_Val) {\n\t\tif (it.index == -1) {\n\t\t\tpush_back(_Val);\n\t\t\treturn;\n\t\t}\n\t\t_tVectorList_Node &IteratorNode = PointerBuffPtr[it.index];\n\t\tif (IteratorNode.prevIndex == -1) {\n\t\t\tpush_front(_Val);\n\t\t\treturn;\n\t\t}\n\t\t/*   __________    ______    __________\n\t\t*  | Iterator |  | Node |  | PrevNode |\n\t\t*  |----------|  |------|  |----------|\n\t\t*  |   prev  --->| prev -->|   prev   |\n\t\t*  |   next   |<-- next |<---- next   |\n\t\t*  |__________|  |______|  |__________|\n\t\t*/\n\n\t\t_ensureCapacity();\n\t\tint currentIndex = (int)UnusedIndexStack.back(); // ## fix error: cannot initialize a variable of type 'int'\n\t\t_tVectorList_Node &Node = PointerBuffPtr[currentIndex];\n\t\t_tVectorList_Node &PrevNode = PointerBuffPtr[IteratorNode.prevIndex];\n\t\tNode.Data = _Val;\n\n\t\tNode.prevIndex = IteratorNode.prevIndex;//PrevNode\n\t\tNode.nextIndex = it.index;\n\t\tPrevNode.nextIndex = currentIndex;\n\t\tIteratorNode.prevIndex = currentIndex;\n\t\t++nQuantity;\n\t}\n\tvoid insert_after(iterator &it, T &_Val) {\n\t\tif (it.index == -1) {\n\t\t\tpush_front(_Val);\n\t\t\treturn;\n\t\t}\n\t\t_tVectorList_Node &IteratorNode = PointerBuffPtr[it.index];\n\t\tif (IteratorNode.nextIndex == -1) {\n\t\t\tpush_back(_Val);\n\t\t\treturn;\n\t\t}\n\t\t/*   __________    ______    __________\n\t\t*  | Iterator |  | Node |  | NextNode |\n\t\t*  |----------|  |------|  |----------|\n\t\t*  |   prev   |<-- prev |<---- prev   |\n\t\t*  |   next  --->| next -->|   next   |\n\t\t*  |__________|  |______|  |__________|\n\t\t*/\n\n\t\t_ensureCapacity();\n\t\tint currentIndex = (int)UnusedIndexStack.pop_back();\n\t\t_tVectorList_Node &Node = PointerBuffPtr[currentIndex];\n\t\t_tVectorList_Node &NextNode = PointerBuffPtr[IteratorNode.nextIndex];\n\t\tNode.Data = _Val;\n\n\t\tNode.prevIndex = it.index;\n\t\tNode.nextIndex = IteratorNode.nextIndex;//NextNode\n\t\tNextNode.prevIndex = currentIndex;\n\t\tIteratorNode.nextIndex = currentIndex;\n\t\t++nQuantity;\n\t}\n};\n\n\n//---------------------------------------------------------------------------\n// TJSAlignedAlloc : aligned memory allocater\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void *, TJSAlignedAlloc, (tjs_uint bytes, tjs_uint align_bits));\nTJS_EXP_FUNC_DEF(void, TJSAlignedDealloc, (void *ptr));\n//---------------------------------------------------------------------------\n\n/*[*/\n//---------------------------------------------------------------------------\n// floating-point class checker\n//---------------------------------------------------------------------------\n// constants used in TJSGetFPClass\n#define TJS_FC_CLASS_MASK 7\n#define TJS_FC_SIGN_MASK 8\n\n#define TJS_FC_CLASS_NORMAL 0\n#define TJS_FC_CLASS_NAN 1\n#define TJS_FC_CLASS_INF 2\n\n#define TJS_FC_IS_NORMAL(x)  (((x)&TJS_FC_CLASS_MASK) == TJS_FC_CLASS_NORMAL)\n#define TJS_FC_IS_NAN(x)  (((x)&TJS_FC_CLASS_MASK) == TJS_FC_CLASS_NAN)\n#define TJS_FC_IS_INF(x)  (((x)&TJS_FC_CLASS_MASK) == TJS_FC_CLASS_INF)\n\n#define TJS_FC_IS_NEGATIVE(x) (0!=((x) & TJS_FC_SIGN_MASK))\n#define TJS_FC_IS_POSITIVE(x) (!TJS_FC_IS_NEGATIVE(x))\n\n\n/*]*/\nTJS_EXP_FUNC_DEF(tjs_uint32, TJSGetFPClass, (tjs_real r));\n//---------------------------------------------------------------------------\n}\n\n#endif\n\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsVariant.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// implementation of tTJSVariant\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsVariant.h\"\n#include \"tjsError.h\"\n#include \"tjsLex.h\"\n#include \"tjsUtils.h\"\n#include \"tjsDebug.h\"\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// tTJSVariantOctet related\n//---------------------------------------------------------------------------\ntTJSVariantOctet::tTJSVariantOctet(const tjs_uint8 *data, tjs_uint length)\n{\n\t// TODO : tTJSVariantOctet check\n\tRefCount = 1;\n\tLength = length;\n\tData = new tjs_uint8[length];\n\tTJS_octetcpy(Data, data, length);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet::tTJSVariantOctet(const tjs_uint8 *data1, tjs_uint len1,\n\tconst tjs_uint8 *data2, tjs_uint len2)\n{\n\tRefCount = 1;\n\tLength = len1 + len2;\n\tData = new tjs_uint8[Length];\n\tif(len1) TJS_octetcpy(Data, data1, len1);\n\tif(len2) TJS_octetcpy(Data + len1, data2, len2);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet::tTJSVariantOctet(const tTJSVariantOctet *o1,\n\tconst tTJSVariantOctet *o2)\n{\n\tRefCount = 1;\n\tLength = (o1?o1->Length:0) + (o2?o2->Length:0);\n\tData = new tjs_uint8[Length];\n\tif(o1 && o1->Length) TJS_octetcpy(Data, o1->Data, o1->Length);\n\tif(o2 && o2->Length) TJS_octetcpy(Data + (o1?o1->Length:0), o2->Data,\n\t\t\t\t\t\t\to2->Length);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet::~tTJSVariantOctet()\n{\n\tdelete [] Data;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariantOctet::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount--;\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet * TJSAllocVariantOctet(const tjs_uint8 *data, tjs_uint length)\n{\n\tif(!data) return NULL;\n\tif(length == 0) return NULL;\n\treturn new tTJSVariantOctet(data, length);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet * TJSAllocVariantOctet(const tjs_uint8 *data1, tjs_uint len1,\n\tconst tjs_uint8 *data2, tjs_uint len2)\n{\n\tif(!data1) len1 = 0;\n\tif(!data2) len2 = 0;\n\tif(len1 + len2 == 0) return NULL;\n\n\treturn new tTJSVariantOctet(data1, len1, data2, len2);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet * TJSAllocVariantOctet(const tTJSVariantOctet *o1, const\n\ttTJSVariantOctet *o2)\n{\n\tif(!o1 && !o2) return NULL;\n\treturn new tTJSVariantOctet(o1, o2);\n}\n//---------------------------------------------------------------------------\ntTJSVariantOctet * TJSAllocVariantOctet(const tjs_uint8 **src)\n{\n\ttjs_uint size = *(const tjs_uint*)(*src);\n\t*src += sizeof(tjs_uint);\n\tif(!size) return NULL;\n\ttTJSVariantOctet *octet =  new tTJSVariantOctet(*src, size);\n\t*src += size;\n\treturn octet;\n}\n//---------------------------------------------------------------------------\nvoid TJSDeallocVariantOctet(tTJSVariantOctet *o)\n{\n\tdelete o;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSOctetToListString(const tTJSVariantOctet *oct)\n{\n\tif(!oct) return NULL;\n\tif(oct->GetLength() == 0) return NULL;\n\ttjs_int stringlen = oct->GetLength() * 3 -1;\n\ttTJSVariantString * str = TJSAllocVariantStringBuffer(stringlen);\n\n\ttjs_char *buf = const_cast<tjs_char*>(str->operator const tjs_char*());\n\tstatic const tjs_char hex[] = TJS_W(\"0123456789ABCDEF\");\n\tconst tjs_uint8 *data = oct->GetData();\n\ttjs_uint n = oct->GetLength();\n\twhile(n--)\n\t{\n\t\tbuf[0] = hex[*data >> 4];\n\t\tbuf[1] = hex[*data & 0x0f];\n\t\tif(n != 0)\n\t\t\tbuf[2] = TJS_W(' ');\n\t\tbuf+=3;\n\t\tdata++;\n\t}\n\n\treturn str;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Utility Functions\n//---------------------------------------------------------------------------\ntTJSVariantClosure_S TJSNullVariantClosure={NULL,NULL};\n//---------------------------------------------------------------------------\nvoid TJSThrowVariantConvertError(const tTJSVariant & from, tTJSVariantType to)\n{\n\tif(to == tvtObject)\n\t{\n\t\tttstr msg(TJSVariantConvertErrorToObject);\n\n\t\tmsg.Replace(TJS_W(\"%1\"), TJSVariantToReadableString(from));\n\n\t\tTJS_eTJSVariantError(msg);\n\t}\n\telse\n\t{\n\t\tttstr msg(TJSVariantConvertError);\n\n\t\tmsg.Replace(TJS_W(\"%1\"), TJSVariantToReadableString(from));\n\n\t\tmsg.Replace(TJS_W(\"%2\"), TJSVariantTypeToTypeString(to));\n\n\t\tTJS_eTJSVariantError(msg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJSThrowVariantConvertError(const tTJSVariant & from, tTJSVariantType to1,\n\ttTJSVariantType to2)\n{\n\tttstr msg(TJSVariantConvertError);\n\n\tmsg.Replace(TJS_W(\"%1\"), TJSVariantToReadableString(from));\n\n\tmsg.Replace(TJS_W(\"%2\"), TJSVariantTypeToTypeString(to1) + ttstr(TJS_W(\"/\")) +\n\t\tTJSVariantTypeToTypeString(to2));\n\n\tTJS_eTJSVariantError(msg);\n}\n//---------------------------------------------------------------------------\nvoid TJSThrowNullAccess()\n{\n\tTJS_eTJSError(TJSNullAccess);\n}\n//---------------------------------------------------------------------------\nvoid TJSThrowDivideByZero()\n{\n\tTJS_eTJSVariantError(TJSDivideByZero);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSObjectToString(const tTJSVariantClosure &dsp)\n{\n\tif(TJSObjectTypeInfoEnabled())\n\t{\n\t\t// retrieve object type information from debugging facility\n\t\ttjs_char tmp[256];\n\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"(object %p\"), dsp.Object);\n\t\tttstr ret = tmp;\n\t\tttstr type = TJSGetObjectTypeInfo(dsp.Object);\n\t\tif(!type.IsEmpty()) ret += TJS_W(\"[\") + type + TJS_W(\"]\");\n\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\":%p\"), dsp.ObjThis);\n\t\tret += tmp;\n\t\ttype = TJSGetObjectTypeInfo(dsp.ObjThis);\n\t\tif(!type.IsEmpty()) ret += TJS_W(\"[\") + type + TJS_W(\"]\");\n\t\tret += TJS_W(\")\");\n\t\ttTJSVariantString * str = ret.AsVariantStringNoAddRef();\n\t\tstr->AddRef();\n\t\treturn str;\n\t}\n\telse\n\t{\n\t\ttjs_char tmp[256];\n\t\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"(object %p:%p)\"), dsp.Object, dsp.ObjThis);\n\t\treturn TJSAllocVariantString(tmp);\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSIntegerToString(tjs_int64 i)\n{\n\ttjs_char tmp[34];\n\treturn TJSAllocVariantString( TJS_tTVInt_to_str( i , tmp));\n}\n//---------------------------------------------------------------------------\nstatic  tTJSVariantString * TJSSpecialRealToString(tjs_real r)\n{\n\ttjs_int32 cls = TJSGetFPClass(r);\n\n\tif(TJS_FC_IS_NAN(cls))\n\t{\n\t\treturn TJSAllocVariantString(TJS_W(\"NaN\"));\n\t}\n\tif(TJS_FC_IS_INF(cls))\n\t{\n\t\tif(TJS_FC_IS_NEGATIVE(cls))\n\t\t\treturn TJSAllocVariantString(TJS_W(\"-Infinity\"));\n\t\telse\n\t\t\treturn TJSAllocVariantString(TJS_W(\"+Infinity\"));\n\t}\n\tif(r == 0.0)\n\t{\n\t\tif(TJS_FC_IS_NEGATIVE(cls))\n\t\t\treturn TJSAllocVariantString(TJS_W(\"-0.0\"));\n\t\telse\n\t\t\treturn TJSAllocVariantString(TJS_W(\"+0.0\"));\n\t}\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSRealToString(tjs_real r)\n{\n\ttTJSVariantString *v = TJSSpecialRealToString(r);\n\tif(v) return v;\n\n\tTJSSetFPUE();\n\ttjs_char tmp[128];\n\tTJS_snprintf(tmp, sizeof(tmp)/sizeof(tjs_char), TJS_W(\"%.15lg\"), r);\n    tjs_char ttmp[64];\n    // fast convert from ascii-only string\n    for(int i = 0; i < sizeof(tmp); ++i) {\n        int c = tmp[i];\n        ttmp[i] = c;\n        if(!c) break;\n\t}\n\n\treturn TJSAllocVariantString(ttmp);\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSRealToHexString(tjs_real r)\n{\n\ttTJSVariantString *v = TJSSpecialRealToString(r);\n\tif(v) return v;\n\n\ttjs_uint64 *ui64 = (tjs_uint64*)&r;\n\n\ttjs_char tmp[128];\n\n\ttjs_char *p;\n\n\tif(TJS_IEEE_D_GET_SIGN(*ui64))\n\t{\n\t\tTJS_strcpy(tmp, TJS_W(\"-0x1.\"));\n\t\tp = tmp + 5;\n\t}\n\telse\n\t{\n\t\tTJS_strcpy(tmp, TJS_W(\"0x1.\"));\n\t\tp = tmp + 4;\n\t}\n\n\tstatic tjs_char hexdigits[] = TJS_W(\"0123456789ABCDEF\");\n\n\ttjs_int exp = TJS_IEEE_D_GET_EXP(*ui64);\n\n\ttjs_int bits = TJS_IEEE_D_SIGNIFICAND_BITS;\n\n\twhile(true)\n\t{\n\t\tbits -= 4;\n\t\tif(bits < 0) break;\n\t\t*(p++) = hexdigits[(tjs_int)(*ui64 >> bits) & 0x0f];\n\t}\n\n\t*(p++) = TJS_W('p');\n\t//TJS_sprintf(p, TJS_W(\"%d\"), exp);\n\t//TJS_snprintf(p, (sizeof(tmp)-(p-tmp))/sizeof(tjs_char), TJS_W(\"%d\"), exp);\n\ttjs_char t2[128];\n\tTJS_snprintf( t2, 128, TJS_W(\"%d\"), exp);\n\tfor( tjs_int i = 0; t2[i] != 0 && p != (tmp+128); i++ ) {\n\t\t*(p++) = t2[i];\n\t}\n\tif( p != (tmp+128) ) *p = 0;\n\telse tmp[127] = 0;\n\n\treturn TJSAllocVariantString(tmp);\n}\n//---------------------------------------------------------------------------\ntTVInteger TJSStringToInteger(const tjs_char *str)\n{\n\ttTJSVariant val;\n\tif(TJSParseNumber(val, &str)) \treturn val.AsInteger();\n\treturn 0;\n}\n//---------------------------------------------------------------------------\ntTVReal TJSStringToReal(const tjs_char *str)\n{\n\ttTJSVariant val;\n\tif(TJSParseNumber(val, &str)) \treturn val.AsReal();\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSVariant member\n//---------------------------------------------------------------------------\ntTJSVariant::tTJSVariant(const tTJSVariant &ref) // from tTJSVariant\n{\n\n\ttTJSVariant_BITCOPY(*this, ref);\n\tif(vt==tvtObject)\n\t{\n\t\tif(Object.Object) Object.Object->AddRef();\n\t\tif(Object.ObjThis) Object.ObjThis->AddRef();\n\t}\n\telse\n\t{\n\t\tif(vt==tvtString) {\tif(String) String->AddRef(); }\n\t\telse if(vt==tvtOctet) { if(Octet) Octet->AddRef(); }\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSVariant::tTJSVariant(const tjs_uint8 ** src)\n{\n\t// from persistent storage\n\tvt = (tTJSVariantType) **src;\n\tsrc++;\n\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\tbreak;\n\n\tcase tvtObject:\n\t\tObject = *(tTJSVariantClosure_S*)(*src);\n\t\t// no addref\n\t\tbreak;\n\n\tcase tvtString:\n\t\tString = TJSAllocVariantString(src);\n\t\tbreak;\n\n\tcase tvtInteger:\n\t\tInteger = *(const tTVInteger *)(*src);\n\t\tbreak;\n\n\tcase tvtReal:\n\t\tTJSSetFPUE();\n\t\tReal = *(const tTVReal *)(*src);\n\t\tbreak;\n\n\tcase tvtOctet:\n\t\tOctet = TJSAllocVariantOctet(src);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak; // unknown type\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSVariant::~tTJSVariant()\n{\n\tClear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::Clear()\n{\n\ttTJSVariantType o_vt = vt;\n\tvt = tvtVoid;\n\tswitch(o_vt)\n\t{\n\tcase tvtObject:\n\t\tif(Object.Object) Object.Object->Release();\n\t\tif(Object.ObjThis) Object.ObjThis->Release();\n\t\tbreak;\n\tcase tvtString:\n\t\tif(String) String->Release();\n\t\tbreak;\n\tcase tvtOctet:\n\t\tif(Octet) Octet->Release();\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::ToString()\n{\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\tString=NULL;\n\t\tvt=tvtString;\n\t\tbreak;\n\n\tcase tvtObject:\n\t  {\n\t\ttTJSVariantString * string = TJSObjectToString(*(tTJSVariantClosure*)&Object);\n\t\tReleaseObject();\n\t\tString = string;\n\t\tvt=tvtString;\n\t\tbreak;\n\t  }\n\n\tcase tvtString:\n\t\tbreak;\n\n\tcase tvtInteger:\n\t\tString=TJSIntegerToString(Integer);\n\t\tvt=tvtString;\n\t\tbreak;\n\n\tcase tvtReal:\n\t\tString=TJSRealToString(Real);\n\t\tvt=tvtString;\n\t\tbreak;\n\n\tcase tvtOctet:\n\t\tTJSThrowVariantConvertError(*this, tvtString);\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::ToOctet()\n{\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\tOctet = NULL;\n\t\tvt = tvtOctet;\n\t\tbreak;\n\n\n\tcase tvtOctet:\n\t\tbreak;\n\n\tcase tvtString:\n\tcase tvtInteger:\n\tcase tvtReal:\n\tcase tvtObject:\n\t\tTJSThrowVariantConvertError(*this, tvtOctet);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::ToInteger()\n{\n\ttTVInteger i = AsInteger();\n\tReleaseContent();\n\tvt = tvtInteger;\n\tInteger = i;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::ToReal()\n{\n\ttTVReal r = AsReal();\n\tReleaseContent();\n\tvt = tvtReal;\n\tReal = r;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::CopyRef(const tTJSVariant & ref) // from reference to tTJSVariant\n{\n\tswitch(ref.vt)\n\t{\n\tcase tvtVoid:\n\t\tReleaseContent();\n\t\tvt = tvtVoid;\n\t\treturn;\n\tcase tvtObject:\n\t\tif(this != &ref)\n\t\t{\n\t\t\t/*\n\t\t\t\tnote:\n\t\t\t\tReleaseContent makes the object variables null during clear,\n\t\t\t\tthus makes the resulting object also null when the ref and this are\n\t\t\t\texactly the same object.\n\t\t\t\tThis does not affect string nor octet because the ReleaseContent\n\t\t\t\tdoes *not* make the pointer null during clear when the variant type\n\t\t\t\tis string or octet.\n\t\t\t*/\n\t\t\t((tTJSVariantClosure&)ref.Object).AddRef();\n\t\t\tReleaseContent();\n\t\t\tObject = ref.Object;\n\t\t\tvt = tvtObject;\n\t\t}\n\t\treturn;\n\tcase tvtString:\n\t\tif(ref.String) ref.String->AddRef();\n\t\tReleaseContent();\n\t\tString = ref.String;\n\t\tvt = tvtString;\n\t\treturn;\n\tcase tvtOctet:\n\t\tif(ref.Octet) ref.Octet->AddRef();\n\t\tReleaseContent();\n\t\tOctet = ref.Octet;\n\t\tvt = tvtOctet;\n\t\treturn;\n\tdefault:\n\t\tReleaseContent();\n\t\ttTJSVariant_BITCOPY(*this,ref);\n\t\treturn;\n\t}\n\n}\n//---------------------------------------------------------------------------\n\ntTJSVariant & tTJSVariant::operator =(iTJSDispatch2 *ref) // from Object\n{\n\tif(ref) ref->AddRef();\n\tReleaseContent();\n\tvt = tvtObject;\n\tObject.Object = ref;\n\tObject.ObjThis = NULL;\n\treturn *this;\n}\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::SetObject(iTJSDispatch2 *object, iTJSDispatch2 *objthis)\n{\n\tif(object) object->AddRef();\n\tif(objthis) objthis->AddRef();\n\tReleaseContent();\n\tvt = tvtObject;\n\tObject.Object = object;\n\tObject.ObjThis = objthis;\n\treturn *this;\n}\n//---------------------------------------------------------------------------\n\ntTJSVariant & tTJSVariant::operator =(tTJSVariantClosure ref) // from Object Closure\n{\n\tReleaseContent();\n\tvt=tvtObject;\n\tObject=ref;\n\tAddRefContent();\n\treturn *this;\n}\n//---------------------------------------------------------------------------\n\n#ifdef TJS_SUPPORT_VCL\ntTJSVariant & tTJSVariant::operator =(WideString s) // from WideString\n{\n\tReleaseContent();\n\tvt=tvtString;\n\tif(s.IsEmpty())\n\t\tString=NULL;\n\telse\n\t\tString=TJSAllocVariantString(s.c_bstr());\n\treturn *this;\n}\n#endif\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(tTJSVariantString *ref) // from tTJSVariantString\n{\n\tif(ref) ref->AddRef();\n\tReleaseContent();\n\tvt = tvtString;\n\tString = ref;\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(tTJSVariantOctet *ref) // from tTJSVariantOctet\n{\n\tif(ref) ref->AddRef();\n\tReleaseContent();\n\tvt = tvtOctet;\n\tOctet = ref;\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(const tTJSString & ref) // from tTJSString\n{\n\tReleaseContent();\n\tvt = tvtString;\n\tString = ref.AsVariantStringNoAddRef();\n\tif(String) String->AddRef();\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(const tjs_char *ref) //  from String\n{\n\tReleaseContent();\n\tvt=tvtString;\n\tString=TJSAllocVariantString(ref);\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(const tjs_nchar *ref) // from narrow string\n{\n\tReleaseContent();\n\tvt=tvtString;\n\tString = TJSAllocVariantString(ref);\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(bool ref)\n{\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=(tjs_int64)(tjs_int)ref;\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(tjs_int32 ref)\n{\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=(tTVInteger)ref;\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(const tTVInteger ref) // from Integer64\n{\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=ref;\n\treturn *this;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariant & tTJSVariant::operator =(tjs_real ref) // from double\n{\n\tReleaseContent();\n\tTJSSetFPUE();\n\tvt=tvtReal;\n\tReal=ref;\n\treturn *this;\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::NormalCompare(const tTJSVariant &val2) const\n{\n\ttry\n\t{\n\n\t\tif(vt == val2.vt)\n\t\t{\n\t\t\tif(vt == tvtInteger)\n\t\t\t{\n\t\t\t\treturn Integer == val2.Integer;\n\t\t\t}\n\n\t\t\tif(vt == tvtString)\n\t\t\t{\n\t\t\t\ttTJSVariantString *s1, *s2;\n\t\t\t\ts1 = String;\n\t\t\t\ts2 = val2.String;\n\t\t\t\tif(s1 == s2) return true; // both empty string or the same pointer\n\t\t\t\tif(!s1 && s2) return false;\n\t\t\t\tif(s1 && !s2) return false;\n\t\t\t\tif(s1->Length != s2->Length) return false;\n\t\t\t\treturn (! TJS_strcmp(*s1, *s2));\n\t\t\t}\n\n\t\t\tif(vt == tvtOctet)\n\t\t\t{\n\t\t\t\tif(Octet == val2.Octet) return true; // both empty octet or the same pointer\n\t\t\t\tif(!Octet && val2.Octet) return false;\n\t\t\t\tif(Octet && !val2.Octet) return false;\n\t\t\t\tif(Octet->GetLength() != val2.Octet->GetLength()) return false;\n\t\t\t\treturn !TJS_octetcmp(Octet->GetData(), val2.Octet->GetData(),\n\t\t\t\t\tOctet->GetLength());\n\t\t\t}\n\n\t\t\tif(vt == tvtObject)\n\t\t\t{\n\t\t\t\treturn Object.Object == val2.Object.Object/* &&\n\t\t\t\t\tObject.ObjThis == val2.Object.ObjThis*/;\n\t\t\t}\n\n\t\t\tif(vt == tvtVoid) return true;\n\t\t}\n\n\t\tif(vt==tvtString || val2.vt==tvtString)\n\t\t{\n\t\t\ttTJSVariantString *s1, *s2;\n\t\t\ts1 = AsString();\n\t\t\ts2 = val2.AsString();\n\t\t\tif(!s1 && !s2) return true; // both empty string\n\t\t\tif(!s1 && s2)\n\t\t\t{\n\t\t\t\ts2->Release();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(s1 && !s2)\n\t\t\t{\n\t\t\t\ts1->Release();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbool res = ! TJS_strcmp(*s1, *s2);\n\t\t\ts1->Release();\n\t\t\ts2->Release();\n\t\t\treturn res;\n\t\t}\n\n\t\tif(vt == tvtVoid)\n\t\t{\n\t\t\tswitch(val2.vt)\n\t\t\t{\n\t\t\tcase tvtInteger:\treturn val2.Integer == 0;\n\t\t\tcase tvtReal:\t\t{ TJSSetFPUE(); return val2.Real == 0; }\n\t\t\tcase tvtString:\t\treturn val2.String == 0;\n\t\t\tdefault:\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif(val2.vt == tvtVoid)\n\t\t{\n\t\t\tswitch(vt)\n\t\t\t{\n\t\t\tcase tvtInteger:\treturn Integer == 0;\n\t\t\tcase tvtReal:\t\t{ TJSSetFPUE(); return Real == 0; }\n\t\t\tcase tvtString:\t\treturn String == 0;\n\t\t\tdefault:\t\t\treturn false;\n\t\t\t}\n\t\t}\n#if 1\n\t\tstatic const bool TypeComparableTable[6][6] = {\n\t\t\t//\t   v, o, s, 8, i, r\n\t\t\t/*v*/{ 1, 0, 1, 0, 1, 1 },\n\t\t\t/*o*/{ 0, 1, 0, 0, 0, 0 },\n\t\t\t/*s*/{ 1, 0, 1, 0, 1, 1 },\n\t\t\t/*8*/{ 0, 0, 0, 1, 0, 0 },\n\t\t\t/*i*/{ 1, 0, 1, 0, 1, 1 },\n\t\t\t/*r*/{ 1, 0, 1, 0, 1, 1 },\n\t\t};\n\t\tif (!TypeComparableTable[vt][val2.vt])\n\t\t\treturn false;\n#endif\n\n\t\tTJSSetFPUE();\n\n\t\ttTVReal r1 = AsReal();\n\t\ttTVReal r2 = val2.AsReal();\n\n\t\ttjs_uint32 c1 = TJSGetFPClass(r1);\n\t\ttjs_uint32 c2 = TJSGetFPClass(r2);\n\n\t\tif(TJS_FC_IS_NAN(c1) || TJS_FC_IS_NAN(c2)) return false;\n\t\t\t// compare to NaN is always false\n\t\tif(TJS_FC_IS_INF(c1) || TJS_FC_IS_INF(c2))\n\t\t{\n\t\t\treturn c1 == c2;\n\t\t\t// +inf == +inf : true , -inf == -inf : true, otherwise : false\n\t\t}\n\t\treturn r1 == r2;\n\t}\n\tcatch(eTJSVariantError &/*e*/)\n\t{\n\t\treturn false;\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::DiscernCompare(const tTJSVariant &val2) const\n{\n\tif(vt==val2.vt)\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtObject:\n\t\t\treturn Object.Object == val2.Object.Object &&\n\t\t\t\tObject.ObjThis == val2.Object.ObjThis;\n\t\tcase tvtString:\n\t\t\treturn NormalCompare(val2);\n\t\tcase tvtOctet:\n\t\t\treturn NormalCompare(val2);\n\t\tcase tvtVoid:\n\t\t\treturn true;\n\t\tcase tvtReal:\n\t\t  {\n\t\t\tTJSSetFPUE();\n\n\t\t\ttjs_uint32 c1 = TJSGetFPClass(Real);\n\t\t\ttjs_uint32 c2 = TJSGetFPClass(val2.Real);\n\n\t\t\tif(TJS_FC_IS_NAN(c1) || TJS_FC_IS_NAN(c2)) return false;\n\t\t\t\t// compare to NaN is always false\n\t\t\tif(TJS_FC_IS_INF(c1) || TJS_FC_IS_INF(c2))\n\t\t\t{\n\t\t\t\treturn c1 == c2;\n\t\t\t\t// +inf == +inf : true , -inf == -inf : true, otherwise : false\n\t\t\t}\n\t\t\treturn Real == val2.Real;\n\t\t  }\n\t\tcase tvtInteger:\n\t\t\treturn Integer == val2.Integer;\n\t\t}\n\t\treturn false;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::DiscernCompareStrictReal(const tTJSVariant &val2) const\n{\n\t// this performs strict real compare\n\tif(vt == val2.vt && vt == tvtReal)\n\t{\n\t\ttjs_uint64 *ui64 = (tjs_uint64*)&Real;\n\t\ttjs_uint64 *v2ui64 = (tjs_uint64*)&(val2.Real);\n\t\treturn *ui64 == *v2ui64;\n\t}\n\n\treturn DiscernCompare(val2);\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::GreaterThan(const tTJSVariant &val2) const\n{\n\tif(vt!=tvtString || val2.vt!=tvtString)\n\t{\n\t\t// compare as number\n\t\tif(vt==tvtInteger && val2.vt==tvtInteger)\n\t\t{\n\t\t\treturn AsInteger()<val2.AsInteger();\n\t\t}\n\t\tTJSSetFPUE();\n\t\treturn AsReal()<val2.AsReal();\n\t}\n\t// compare as string\n\ttTJSVariantString *s1, *s2;\n\ts1 = AsString();\n\ts2 = val2.AsString();\n\tconst tjs_char *p1 = *s1;\n\tconst tjs_char *p2 = *s2;\n\tif(!p1) p1=TJS_W(\"\");\n\tif(!p2) p2=TJS_W(\"\");\n\tbool res = TJS_strcmp(p1, p2)<0;\n\tif(s1) s1->Release();\n\tif(s2) s2->Release();\n\treturn res;\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::LittlerThan(const tTJSVariant &val2) const\n{\n\tif(vt!=tvtString || val2.vt!=tvtString)\n\t{\n\t\t// compare as number\n\t\tif(vt==tvtInteger && val2.vt==tvtInteger)\n\t\t{\n\t\t\treturn AsInteger()>val2.AsInteger();\n\t\t}\n\t\tTJSSetFPUE();\n\t\treturn AsReal()>val2.AsReal();\n\t}\n\t// compare as string\n\ttTJSVariantString *s1, *s2;\n\ts1 = AsString();\n\ts2 = val2.AsString();\n\tconst tjs_char *p1 = *s1;\n\tconst tjs_char *p2 = *s2;\n\tif(!p1) p1=TJS_W(\"\");\n\tif(!p2) p2=TJS_W(\"\");\n\tbool res = TJS_strcmp(p1, p2)>0;\n\tif(s1) s1->Release();\n\tif(s2) s2->Release();\n\treturn res;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::logicalorequal (const tTJSVariant &rhs)\n{\n\tbool l=operator bool();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l||rhs.operator bool();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::logicalandequal (const tTJSVariant &rhs)\n{\n\tbool l=operator bool();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l&&rhs.operator bool();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator |= (const tTJSVariant &rhs)\n{\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l|rhs.AsInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::increment(void)\n{\n\tif(vt == tvtString)\n\t\tString->ToNumber(*this);\n\n\tif(vt == tvtReal)\n\t{\n\t\tTJSSetFPUE();\n\t\tReal+=1.0;\n\t}\n\telse if(vt == tvtInteger)\n\t\tInteger ++;\n\telse if(vt == tvtVoid)\n\t\tvt = tvtInteger, Integer = 1;\n\telse\n\t\tTJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::decrement(void)\n{\n\tif(vt == tvtString)\n\t\tString->ToNumber(*this);\n\n\tif(vt == tvtReal)\n\t{\n\t\tTJSSetFPUE();\n\t\tReal-=1.0;\n\t}\n\telse if(vt == tvtInteger)\n\t\tInteger --;\n\telse if(vt == tvtVoid)\n\t\tvt = tvtInteger, Integer = -1;\n\telse\n\t\tTJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator ^= (const tTJSVariant &rhs)\n{\n\ttjs_int64 l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l^rhs.AsInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator &= (const tTJSVariant &rhs)\n{\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l&rhs.AsInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator >>= (const tTJSVariant &rhs)\n{\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l>>(tjs_int)rhs.AsInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::rbitshiftequal (const tTJSVariant &rhs)\n{\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=(tjs_int64)((tjs_uint64)l>> (tjs_int)rhs);\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator <<= (const tTJSVariant &rhs)\n{\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l<<(tjs_int)rhs.AsInteger();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator %= (const tTJSVariant &rhs)\n{\n\ttTVInteger r=rhs.AsInteger();\n\tif(r == 0) TJSThrowDivideByZero();\n\ttTVInteger l=AsInteger();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l%r;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator /= (const tTJSVariant &rhs)\n{\n\tTJSSetFPUE();\n\ttTVReal l=AsReal();\n\ttTVReal r=rhs.AsReal();\n\tReleaseContent();\n\tvt=tvtReal;\n\tReal=l/r;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::idivequal (const tTJSVariant &rhs)\n{\n\ttTVInteger r=rhs.AsInteger();\n\ttTVInteger l=AsInteger();\n\tif(r == 0) TJSThrowDivideByZero();\n\tReleaseContent();\n\tvt=tvtInteger;\n\tInteger=l/r;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::InternalMul(const tTJSVariant &rhs)\n{\n\ttTJSVariant l;\n\tAsNumber(l);\n\tReleaseContent();\n\ttTJSVariant r;\n\trhs.AsNumber(r);\n\tif(l.vt == tvtInteger && r.vt == tvtInteger)\n\t{\n\t\tvt = tvtInteger;\n\t\tInteger = l.Integer * r.Integer;\n\t\treturn;\n\t}\n\tvt = tvtReal;\n\tTJSSetFPUE();\n\tReal = l.AsReal() * r.AsReal();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::logicalnot()\n{\n\tbool res = !operator bool();\n\tReleaseContent();\n\tvt = tvtInteger;\n\tInteger = (tjs_int)res;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::bitnot()\n{\n\ttjs_int64 res = ~AsInteger();\n\tReleaseContent();\n\tvt = tvtInteger;\n\tInteger = res;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::tonumber()\n{\n\tif(vt==tvtInteger || vt==tvtReal)\n\t\treturn; // nothing to do\n\n\tif(vt==tvtString)\n\t{\n\t\tString->ToNumber(*this);\n\t\treturn;\n\t}\n\n\tif(vt==tvtVoid) { *this = 0; return; }\n\n\tTJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::InternalChangeSign()\n{\n\ttTJSVariant val;\n\tAsNumber(val);\n\tReleaseContent();\n\tif(val.vt == tvtInteger)\n\t{\n\t\tvt = tvtInteger;\n\t\tInteger = -val.Integer;\n\t}\n\telse\n\t{\n\t\tvt = tvtReal;\n\t\tTJSSetFPUE();\n\t\tReal = -val.Real;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::InternalSub(const tTJSVariant &rhs)\n{\n\ttTJSVariant l;\n\tAsNumber(l);\n\tReleaseContent();\n\ttTJSVariant r;\n\trhs.AsNumber(r);\n\tif(l.vt == tvtInteger && r.vt == tvtInteger)\n\t{\n\t\tvt = tvtInteger;\n\t\tInteger = l.Integer - r.Integer;\n\t\treturn;\n\t}\n\tvt = tvtReal;\n\tTJSSetFPUE();\n\tReal = l.AsReal() - r.AsReal();\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::operator +=(const tTJSVariant &rhs)\n{\n\tif(vt==tvtString || rhs.vt==tvtString)\n\t{\n\t\tif(vt == tvtString && rhs.vt == tvtString)\n\t\t{\n\t\t\t// both are string\n\n\t\t\t// independ string\n\t\t\tif(String && String->GetRefCount() != 0)\n\t\t\t{\n\t\t\t\t// sever dependency\n\t\t\t\ttTJSVariantString *orgstr = String;\n\t\t\t\tString = TJSAllocVariantString(String->operator const tjs_char*());\n\t\t\t\torgstr->Release();\n\t\t\t}\n\n\t\t\t// append\n\t\t\tString = TJSAppendVariantString(String, rhs.String);\n\t\t\treturn;\n\t\t}\n\n\t\ttTJSVariant val;\n\t\tval.vt = tvtString;\n\t\ttTJSVariantString *s1, *s2;\n\t\ts1 = AsString();\n\t\ts2 = rhs.AsString();\n\t\tval.String = TJSAllocVariantString(*s1, *s2);\n\t\tif(s1) s1->Release();\n\t\tif(s2) s2->Release();   \n\t\t*this=val;\n\t\treturn;\n\t}\n\n\n\tif(vt == rhs.vt)\n\t{\n\t\tif(vt==tvtOctet)\n\t\t{\n\t\t\ttTJSVariant val;\n\t\t\tval.vt = tvtOctet;\n\t\t\tval.Octet = TJSAllocVariantOctet(Octet, rhs.Octet);\n\t\t\t*this=val;\n\t\t\treturn;\n\t\t}\n\n\t\tif(vt==tvtInteger)\n\t\t{\n\t\t\ttTVInteger l=Integer;\n\t\t\tReleaseContent();\n\t\t\tvt=tvtInteger;\n\t\t\tInteger=l+rhs.Integer;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif(vt == tvtVoid)\n\t{\n\t\tif(rhs.vt == tvtInteger)\n\t\t{\n\t\t\tvt = tvtInteger;\n\t\t\tInteger = rhs.Integer;\n\t\t\treturn;\n\t\t}\n\t\tif(rhs.vt == tvtReal)\n\t\t{\n\t\t\tvt = tvtReal;\n\t\t\tTJSSetFPUE();\n\t\t\tReal = rhs.Real;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif(rhs.vt == tvtVoid)\n\t{\n\t\tif(vt == tvtInteger) return;\n\t\tif(vt == tvtReal) return;\n\t}\n\n\tTJSSetFPUE();\n\ttTVReal l=AsReal();\n\tReleaseContent();\n\tvt=tvtReal;\n\tReal=l+rhs.AsReal();\n}\n//---------------------------------------------------------------------------\nbool tTJSVariant::IsInstanceOf(const tjs_char * classname) const\n{\n\t// not implemented\n\treturn false;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSVariant::QueryPersistSize() const\n{\n\t// return the size, in bytes, of storage needed to store current state.\n\t// this state cannot walk across platforms.\n\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\treturn 1;\n\n\tcase tvtObject:\n\t\treturn sizeof(tTJSVariantClosure_S) + 1;\n\n\tcase tvtString:\n\t\tif(String) return sizeof(tTJSVariantString*) + 1 + String->QueryPersistSize();\n\t\treturn sizeof(tTJSVariantString*) + 1;\n\n\tcase tvtInteger:\n\t\treturn sizeof(tTVInteger) + 1;\n\n\tcase tvtReal:\n\t\treturn sizeof(tTVReal) + 1;\n\n\tcase tvtOctet:\n\t\tif(Octet) return sizeof(tTJSVariantOctet*) + 1 + Octet->QueryPersistSize();\n\t\treturn sizeof(tTJSVariantOctet*) + 1;\n\t}\n\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariant::Persist(tjs_uint8 * dest)\n{\n\t// store current state to dest\n\t*dest = (tjs_uint8)vt;\n\tdest++;\n\n\tswitch(vt)\n\t{\n\tcase tvtVoid:\n\t\tbreak;\n\n\tcase tvtObject:\n\t\t*(tTJSVariantClosure_S*)(dest) = Object;\n\t\tbreak;\n\n\tcase tvtString:\n\t\tif(String)\n\t\t\tString->Persist(dest);\n\t\telse\n\t\t\t*(tjs_uint*)(dest) = 0;\n\t\tbreak;\n\n\tcase tvtInteger:\n\t\t*(tTVInteger*)(dest) = Integer;\n\t\tbreak;\n\n\tcase tvtReal:\n\t\t*(tTVReal*)(dest) = Real;\n\t\tbreak;\n\n\tcase tvtOctet:\n\t\tif(Octet)\n\t\t\tOctet->Persist(dest);\n\t\telse\n\t\t\t*(tjs_uint*)(dest) = 0;\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n} // namespace TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsVariant.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// implementation of tTJSVariant\n//---------------------------------------------------------------------------\n#ifndef tjsVariantH\n#define tjsVariantH\n\n//#include <stdlib.h>\n//#include <stdexcept>\n\n#ifdef TJS_SUPPORT_VCL\n #include <vcl.h>\n#endif\n\n#include \"tjsInterface.h\"\n#include \"tjsVariantString.h\"\n#include \"tjsString.h\"\n\nnamespace TJS\n{\nTJS_EXP_FUNC_DEF(void, TJSThrowNullAccess, ());\nTJS_EXP_FUNC_DEF(void, TJSThrowDivideByZero, ());\n//---------------------------------------------------------------------------\nclass tTJSVariantString;\nclass tTJSString;\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSVariantOctet\n//---------------------------------------------------------------------------\n\n#pragma pack(push, 4)\nstruct tTJSVariantOctet_S\n{\n\ttjs_uint Length;\n\ttjs_int RefCount;\n\ttjs_uint8 *Data;\n};\n#pragma pack(pop)\n/*]*/\n\n/*start-of-tTJSVariantOctet*/\nclass tTJSVariantOctet : protected tTJSVariantOctet_S\n{\npublic:\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariantOctet,\n\t\t(const tjs_uint8 *data, tjs_uint length));\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariantOctet,\n\t\t(const tjs_uint8 *data1, tjs_uint len1, const tjs_uint8 *data2,\n\t\ttjs_uint len2));\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariantOctet,\n\t\t(const tTJSVariantOctet *o1, const tTJSVariantOctet *o2));\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, ~tTJSVariantOctet, ());\n\n\tTJS_METHOD_DEF(void, AddRef, ())\n\t{\n\t\tRefCount ++;\n\t}\n\n\tTJS_METHOD_DEF(void, Release, ());\n\n\tTJS_CONST_METHOD_DEF(tjs_uint, GetLength, ())\n\t{\n\t\treturn Length;\n\t}\n\n\tTJS_CONST_METHOD_DEF(const tjs_uint8 *,  GetData, ())\n\t{\n\t\treturn Data;\n\t}\n\n\ttjs_int QueryPersistSize() { return sizeof(tjs_uint) + Length; }\n\tvoid Persist(tjs_uint8 * dest)\n\t{\n\t\t*(tjs_uint*)dest = Length;\n\t\tif(Data) TJS_octetcpy(dest + sizeof(tjs_uint), Data, Length);\n\t}\n};\n/*end-of-tTJSVariantOctet*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSVariantOctet *, TJSAllocVariantOctet, (const tjs_uint8 *data, tjs_uint length));\nTJS_EXP_FUNC_DEF(tTJSVariantOctet *, TJSAllocVariantOctet, (const tjs_uint8 *data1, tjs_uint len1,\n\tconst tjs_uint8 *data2, tjs_uint len2));\nTJS_EXP_FUNC_DEF(tTJSVariantOctet *, TJSAllocVariantOctet, (const tTJSVariantOctet *o1, const\n\ttTJSVariantOctet *o2));\nTJS_EXP_FUNC_DEF(tTJSVariantOctet *, TJSAllocVariantOctet, (const tjs_uint8 **src));\nTJS_EXP_FUNC_DEF(void, TJSDeallocVariantOctet, (tTJSVariantOctet *o));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSOctetToListString, (const tTJSVariantOctet *oct));\n//---------------------------------------------------------------------------\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSVariant_S\n//---------------------------------------------------------------------------\n#ifdef __BORLANDC__\n#pragma option push -b\n#endif\nenum tTJSVariantType\n{\n\ttvtVoid,  // empty\n\ttvtObject,\n\ttvtString,\n\ttvtOctet,  // octet binary data\n\ttvtInteger,\n\ttvtReal\n};\n#ifdef __BORLANDC__\n#pragma option pop\n#endif\n/*]*/\n//---------------------------------------------------------------------------\n#ifdef __BORLANDC__\n#pragma option push -b -a4\n#endif\n\n/*[*/\n#pragma pack(push, 4)\nclass iTJSDispatch2;\nstruct tTJSVariantClosure_S\n{\n\tiTJSDispatch2 *Object;\n\tiTJSDispatch2 *ObjThis;\n};\nclass tTJSVariantClosure;\n\nclass tTJSVariantString;\nclass tTJSVariantOctet;\nstruct tTJSVariant_S\n{\n\t//---- data members -----------------------------------------------------\n\n\t#define tTJSVariant_BITCOPY(a,b) \\\n\t{\\\n\t\t*(tTJSVariant_S*)&(a) = *(tTJSVariant_S*)&(b); \\\n\t}\n\n\tunion\n\t{\n\t\ttTJSVariantClosure_S Object;\n\t\ttTVInteger Integer;\n\t\ttTVReal Real;\n\t\ttTJSVariantString *String;\n\t\ttTJSVariantOctet *Octet;\n\t};\n\ttTJSVariantType vt;\n};\n#pragma pack(pop)\n/*]*/\n\n#ifdef __BORLANDC__\n#pragma option pop\n#endif\n//---------------------------------------------------------------------------\n// tTJSVariantClosure\n//---------------------------------------------------------------------------\nextern tTJSVariantClosure_S TJSNullVariantClosure;\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSVariantClosure\n//---------------------------------------------------------------------------\n/*]*/\n#if 0\n// for plug-in\n/*[*/\nvoid TJSThrowNullAccess();\n/*]*/\n#endif\n/*[*/\n\nclass tTJSVariantClosure : public tTJSVariantClosure_S\n{\n\t// tTJSVariantClosure does not provide any function of object lifetime\n\t// namagement. ( AddRef and Release are provided but tTJSVariantClosure\n\t// has no responsibility for them )\n\npublic:\n\ttTJSVariantClosure() {;} // note that default constructor does nothing \n\n\ttTJSVariantClosure(iTJSDispatch2 *obj, iTJSDispatch2 *objthis = NULL)\n\t{ Object = obj, ObjThis = objthis; }\n\n\tiTJSDispatch2 * SelectObjectNoAddRef()\n\t\t{ return ObjThis ? ObjThis : Object; }\n\npublic:\n\n\tbool operator == (const tTJSVariantClosure &rhs)\n\t{\n\t\treturn Object == rhs.Object && ObjThis == rhs.ObjThis;\n\t}\n\n\tbool operator != (const tTJSVariantClosure &rhs)\n\t{\n\t\treturn ! this->operator ==(rhs);\n\t}\n\n\n\tvoid AddRef()\n\t{\n\t\tif(Object) Object->AddRef();\n\t\tif(ObjThis) ObjThis->AddRef();\n\t}\n\n\tvoid Release()\n\t{\n\t\tif(Object) Object->Release();\n\t\tif(ObjThis) ObjThis->Release();\n\t}\n\n\n\ttjs_error\n\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->FuncCall(flag, membername, hint, result, numparams, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tFuncCallByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->FuncCallByNum(flag, num, result, numparams, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tPropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->PropGet(flag, membername, hint, result,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tPropGetByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->PropGetByNum(flag, num, result,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tPropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->PropSet(flag, membername, hint, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tPropSetByNum(tjs_uint32 flag, tjs_int num, const tTJSVariant *param,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->PropSetByNum(flag, num, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tGetCount(tjs_int *result, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->GetCount(result, membername, hint,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tGetCountByNum(tjs_int *result, tjs_int num, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->GetCountByNum(result, num,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tPropSetByVS(tjs_uint32 flag, tTJSVariantString *membername,\n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->PropSetByVS(flag, membername, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tEnumMembers(tjs_uint32 flag, tTJSVariantClosure *callback,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->EnumMembers(flag, callback,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tDeleteMember(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->DeleteMember(flag, membername, hint,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tDeleteMemberByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->DeleteMemberByNum(flag, num,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tInvalidate(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->Invalidate(flag, membername, hint,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tInvalidateByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->InvalidateByNum(flag, num,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tIsValid(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->IsValid(flag, membername, hint,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tIsValidByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->IsValidByNum(flag, num,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tCreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\tiTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->CreateNew(flag, membername, hint, result, numparams,\n\t\t\tparam, ObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tCreateNewByNum(tjs_uint32 flag, tjs_int num, iTJSDispatch2 **result,\n\t\ttjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->CreateNewByNum(flag, num, result, numparams, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n/*\n\ttjs_error\n\tReserved1() { }\n*/\n\n\ttjs_error\n\tIsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->IsInstanceOf(flag, membername, hint, classname,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tIsInstanceOf(tjs_uint32 flag, tjs_int num, tjs_char *classname,\n\t\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->IsInstanceOfByNum(flag, num, classname,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tOperation(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result, const tTJSVariant *param,\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->Operation(flag, membername, hint, result, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n\ttjs_error\n\tOperationByNum(tjs_uint32 flag, tjs_int num, tTJSVariant *result,\n\t\tconst tTJSVariant *param,\tiTJSDispatch2 *objthis) const\n\t{\n\t\tif(!Object) TJSThrowNullAccess();\n\t\treturn Object->OperationByNum(flag, num, result, param,\n\t\t\tObjThis?ObjThis:(objthis?objthis:Object));\n\t}\n\n/*\n\ttjs_error\n\tReserved2() { }\n*/\n\n/*\n\ttjs_error\n\tReserved3() { }\n*/\n\n};\n\n\n\n\n/*]*/\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSObjectToString, (const tTJSVariantClosure &dsp));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSIntegerToString, (tjs_int64 i));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSRealToString, (tjs_real r));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSRealToHexString, (tjs_real r));\nTJS_EXP_FUNC_DEF(tTVInteger, TJSStringToInteger, (const tjs_char *str));\nTJS_EXP_FUNC_DEF(tTVReal, TJSStringToReal, (const tjs_char *str));\n//---------------------------------------------------------------------------\nextern void TJSThrowVariantConvertError(const tTJSVariant & from, tTJSVariantType to);\nextern void TJSThrowVariantConvertError(const tTJSVariant & from, tTJSVariantType to1,\n\ttTJSVariantType to2);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSVariant\n//---------------------------------------------------------------------------\n\n#ifdef TJS_SUPPORT_VCL //  suppresses warnings about inline function\n\t#pragma warn -8027\n\t#pragma warn -8026\n#endif\n\n\n/*start-of-tTJSVariant*/\nclass tTJSVariant : protected tTJSVariant_S\n{\n\n\t//---- object management ------------------------------------------------\nprivate:\n\n\tvoid AddRefObject()\n\t{\n\t\tif(Object.Object) Object.Object->AddRef();\n\t\tif(Object.ObjThis) Object.ObjThis->AddRef();\n\t\t// does not addref the string or octet\n\t}\n\n\tvoid ReleaseObject()\n\t{\n\t\tiTJSDispatch2 * object = Object.Object;\n\t\tiTJSDispatch2 * objthis = Object.ObjThis;\n\t\tif(object) Object.Object = NULL, object->Release();\n\t\tif(objthis) Object.ObjThis = NULL, objthis->Release();\n\t\t// does not release the string nor octet\n\t}\n\n\tvoid AddRefContent()\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\tif(Object.Object) Object.Object->AddRef();\n\t\t\tif(Object.ObjThis) Object.ObjThis->AddRef();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(vt==tvtString) { if(String) String->AddRef(); }\n\t\t\telse if(vt==tvtOctet) { if(Octet) Octet->AddRef(); }\n\t\t}\n\t}\n\n\tvoid ReleaseContent()\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\tReleaseObject();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(vt==tvtString) { if(String) String->Release(); }\n\t\t\telse if(vt==tvtOctet) { if(Octet) Octet->Release(); }\n\t\t}\n\t}\n\npublic:\n\n\tTJS_METHOD_DEF(void, ChangeClosureObjThis, (iTJSDispatch2 *objthis))\n\t{\n\t\tif(objthis) objthis->AddRef();\n\t\tif(vt!=tvtObject) TJSThrowVariantConvertError(*this, tvtObject);\n\t\tif(Object.ObjThis)\n\t\t{\n\t\t\tiTJSDispatch2 * objthis = Object.ObjThis;\n\t\t\tObject.ObjThis = NULL;\n\t\t\tobjthis->Release();\n\t\t}\n\t\tObject.ObjThis = objthis;\n\t}\n\n\t//---- constructor ------------------------------------------------------\npublic:\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, ())\n\t{\n\t\tvt=tvtVoid;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tTJSVariant &ref)); // from tTJSVariant\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (iTJSDispatch2 *ref)) // from Object\n\t{\n\t\tif(ref) ref->AddRef();\n\t\tvt=tvtObject;\n\t\tObject.Object = ref;\n\t\tObject.ObjThis = NULL;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (iTJSDispatch2 *obj, iTJSDispatch2 *objthis)) // from closure\n\t{\n\t\tif(obj) obj->AddRef();\n\t\tif(objthis) objthis->AddRef();\n\t\tvt=tvtObject;\n\t\tObject.Object = obj;\n\t\tObject.ObjThis = objthis;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tjs_char *ref)) //  from String\n\t{\n\t\tvt=tvtString;\n\t\tif(ref)\n\t\t{\n\t\t\tString=TJSAllocVariantString(ref);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tString=NULL;\n\t\t}\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tTJSString & ref)) // from tTJSString\n\t{\n\t\tvt = tvtString;\n\t\tString = ref.AsVariantStringNoAddRef();\n\t\tif(String) String->AddRef();\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tjs_nchar *ref)) //  from NarrowString\n\t{\n\t\tvt=tvtString;\n\t\tif(ref)\n\t\t{\n\t\t\tString=TJSAllocVariantString(ref);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tString=NULL;\n\t\t}\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tjs_uint8 *ref, tjs_uint len)) // from octet\n\t{\n\t\tvt=tvtOctet;\n\t\tif(ref)\n\t\t{\n\t\t\tOctet = TJSAllocVariantOctet(ref, len);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tOctet = NULL;\n\t\t}\n\t}\n\n#ifdef TJS_SUPPORT_VCL\n\ttTJSVariant(const WideString ref) // from WideString\n\t{\n\t\tvt=tvtString;\n\t\tif(ref.IsEmpty())\n\t\t\tString=NULL;\n\t\telse\n\t\t\tString=TJSAllocVariantString(ref);\n\t}\n#endif\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (bool ref))\n\t{\n\t\tvt=tvtInteger;\n\t\tInteger=(tjs_int64)(tjs_int)ref;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (tjs_int32 ref))\n\t{\n\t\tvt=tvtInteger;\n\t\tInteger=(tjs_int64)ref;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (tjs_int64 ref))  // from Integer64\n\t{\n\t\tvt=tvtInteger;\n\t\tInteger=ref;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (tjs_real ref))  // from double\n\t{\n\t\tvt=tvtReal;\n\t\tTJSSetFPUE();\n\t\tReal=ref;\n\t}\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, tTJSVariant, (const tjs_uint8 ** src)); // from persistent storage\n\n\t//---- destructor -------------------------------------------------------\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET_EMPTY, ~tTJSVariant, ());\n\n\t//---- type -------------------------------------------------------------\n\n\tTJS_METHOD_DEF(tTJSVariantType, Type, ()) { return vt; } /* for plug-in compatibility */\n\tTJS_CONST_METHOD_DEF(tTJSVariantType, Type, ()) { return vt; }\n\n\t//---- compare ----------------------------------------------------------\n\n\tTJS_CONST_METHOD_DEF(bool, NormalCompare, (const tTJSVariant &val2));\n\tTJS_CONST_METHOD_DEF(bool, DiscernCompare, (const tTJSVariant &val2));\n\tTJS_CONST_METHOD_DEF(bool, DiscernCompareStrictReal, (const tTJSVariant &val2));\n\tTJS_CONST_METHOD_DEF(bool, GreaterThan, (const tTJSVariant &val2));\n\tTJS_CONST_METHOD_DEF(bool, LittlerThan, (const tTJSVariant &val2));\n\n\tTJS_CONST_METHOD_DEF(bool, IsInstanceOf, (const tjs_char * classname));\n\n\t//---- clear ------------------------------------------------------------\n\n\tTJS_METHOD_DEF(void, Clear, ());\n\n\t//---- type conversion --------------------------------------------------\n\n\tTJS_CONST_METHOD_DEF(iTJSDispatch2 *, AsObject, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\tif(Object.Object) Object.Object->AddRef();\n\t\t\treturn Object.Object;\n\t\t}\n\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\n\t\treturn NULL;\n\t}\n\n\tTJS_CONST_METHOD_DEF(iTJSDispatch2 *, AsObjectNoAddRef, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t\treturn Object.Object;\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\t\treturn NULL;\n\t}\n\n\tTJS_CONST_METHOD_DEF(iTJSDispatch2 *, AsObjectThis, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\tif(Object.ObjThis) Object.ObjThis->AddRef();\n\t\t\treturn Object.ObjThis;\n\t\t}\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\t\treturn NULL;\n\t}\n\n\tTJS_CONST_METHOD_DEF(iTJSDispatch2 *, AsObjectThisNoAddRef, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\treturn Object.ObjThis;\n\t\t}\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\t\treturn NULL;\n\t}\n\n\tTJS_METHOD_DEF(tTJSVariantClosure &, AsObjectClosure, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\tAddRefObject();\n\t\t\treturn *(tTJSVariantClosure*)&Object;\n\t\t}\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\t\treturn *(tTJSVariantClosure*)&TJSNullVariantClosure;\n\t}\n\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantClosure &, AsObjectClosureNoAddRef, ())\n\t{\n\t\tif(vt==tvtObject)\n\t\t{\n\t\t\treturn *(tTJSVariantClosure*)&Object;\n\t\t}\n\t\tTJSThrowVariantConvertError(*this, tvtObject);\n\t\treturn *(tTJSVariantClosure*)&TJSNullVariantClosure;\n\t}\n\n\tTJS_METHOD_DEF(void, ToObject, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtObject:  break;\n\t\tcase tvtVoid:\n\t\tcase tvtString:\n\t\tcase tvtInteger:\n\t\tcase tvtReal:\n\t\tcase tvtOctet:    TJSThrowVariantConvertError(*this, tvtObject);\n\t\t}\n\n\t}\n\n#ifdef TJS_SUPPORT_VCL\n\tvoid AttachTo(WideString &ws)\n\t{\n\t\ttTJSVariantString *str = AsString();\n\t\tws.Attach(SysAllocString(*str));\n\t\tif(str) str->Release();\n\t}\n#endif\n\n\tTJS_METHOD_DEF(TJS_METHOD_RET(iTJSDispatch2 *), operator iTJSDispatch2 *, ())\n\t{\n\t\treturn AsObject();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantString *, AsString, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return NULL;\n\t\tcase tvtObject:  return TJSObjectToString(*(tTJSVariantClosure*)&Object);\n\t\tcase tvtString:  { if(String) { String->AddRef(); } return String; }\n\t\tcase tvtInteger: return TJSIntegerToString(Integer);\n\t\tcase tvtReal:    return TJSRealToString(Real);\n\t\tcase tvtOctet:   TJSThrowVariantConvertError(*this, tvtString);\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantString *, AsStringNoAddRef, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return NULL;\n\t\tcase tvtString:  return String;\n\t\tcase tvtObject:\n\t\tcase tvtInteger:\n\t\tcase tvtReal:\n\t\tcase tvtOctet:   TJSThrowVariantConvertError(*this, tvtString);\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tTJS_METHOD_DEF(void, ToString, ());\n\n\tTJS_CONST_METHOD_DEF(const tjs_char *, GetString, ())\n\t{\n\t\t// returns String\n\t\tif(vt!=tvtString) TJSThrowVariantConvertError(*this, tvtString);\n\t\treturn *String;\n\t}\n\n\tTJS_METHOD_DEF(tjs_uint32 *, GetHint, ())\n\t{\n\t\t// returns String Hint\n\t\tif(vt!=tvtString) TJSThrowVariantConvertError(*this, tvtString);\n\t\tif(!String) return NULL;\n\t\treturn String->GetHint();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantOctet *, AsOctet, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return NULL;\n\t\tcase tvtOctet:   { if(Octet) Octet->AddRef(); } return Octet;\n\t\tcase tvtString:\n\t\tcase tvtInteger:\n\t\tcase tvtReal:\n\t\tcase tvtObject:  TJSThrowVariantConvertError(*this, tvtOctet);\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariantOctet *, AsOctetNoAddRef, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return NULL;\n\t\tcase tvtOctet:   return Octet;\n\t\tcase tvtString:\n\t\tcase tvtInteger:\n\t\tcase tvtReal:\n\t\tcase tvtObject:  TJSThrowVariantConvertError(*this, tvtOctet);\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tTJS_METHOD_DEF(void, ToOctet, ());\n\n\n#ifdef TJS_SUPPORT_VCL\n\toperator AnsiString () const\n\t{\n\t\tif(vt==tvtString)\n\t\t{\n\t\t\treturn AnsiString(*String);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTJSVariantString *s=AsString();\n\t\t\tif(s)\n\t\t\t{\n\t\t\t\tAnsiString r=AnsiString(*s);\n\t\t\t\ts->Release();\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t}\n\t}\n#endif\n\n\tTJS_CONST_METHOD_DEF(tTVInteger, AsInteger, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return 0;\n\t\tcase tvtObject:  TJSThrowVariantConvertError(*this, tvtInteger);\n\t\tcase tvtString:  return String->ToInteger();\n\t\tcase tvtInteger: return Integer;\n\t\tcase tvtReal:    TJSSetFPUE(); return (tTVInteger)Real;\n\t\tcase tvtOctet:   TJSThrowVariantConvertError(*this, tvtInteger);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tTJS_CONST_METHOD_DEF(void, AsNumber, (tTJSVariant &targ))\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    targ = (tjs_int)0; return;\n\t\tcase tvtObject:  TJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n\t\tcase tvtString:  String->ToNumber(targ); return;\n\t\tcase tvtInteger: targ = Integer; return;\n\t\tcase tvtReal:    TJSSetFPUE(); targ = Real; return;\n\t\tcase tvtOctet:   TJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n\t\t}\n\t\treturn;\n\t}\n\n\tTJS_METHOD_DEF(void, ToInteger, ());\n\n\tTJS_CONST_METHOD_DEF(TJS_METHOD_RET(tTVInteger), operator tTVInteger, ())\n\t{\n\t\treturn AsInteger();\n\t}\n\n\tTJS_CONST_METHOD_DEF(TJS_METHOD_RET(bool), operator bool, ())\n\t{\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:\t\treturn false;\n\t\t//case tvtObject:\t\treturn (bool)Object.Object;\n\t\tcase tvtObject:\t\treturn Object.Object != NULL;\n\t\t//case tvtString:\t\treturn (bool)AsInteger();\n\t\tcase tvtString:\t\treturn AsInteger() != 0;\n\t\tcase tvtOctet:\t\treturn 0!=Octet;\n\t\tcase tvtInteger:\treturn 0!=Integer;\n\t\tcase tvtReal:\t\tTJSSetFPUE(); return 0!=Real;\n\t\t}\n\t\treturn false;\n\t}\n\n\tTJS_CONST_METHOD_DEF(TJS_METHOD_RET(tjs_int), operator tjs_int, ())\n\t{\n\t\treturn (tjs_int)AsInteger();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTVReal, AsReal, ())\n\t{\n\t\tTJSSetFPUE();\n\n\t\tswitch(vt)\n\t\t{\n\t\tcase tvtVoid:    return 0;\n\t\tcase tvtObject:  TJSThrowVariantConvertError(*this, tvtReal);\n\t\tcase tvtString:  return String->ToReal();\n\t\tcase tvtInteger: return (tTVReal)Integer;\n\t\tcase tvtReal:    return Real;\n\t\tcase tvtOctet:   TJSThrowVariantConvertError(*this, tvtReal);\n\t\t}\n\t\treturn 0.0f;\n\t}\n\n\tTJS_METHOD_DEF(void, ToReal, ());\n\n\tTJS_CONST_METHOD_DEF(TJS_METHOD_RET(tTVReal), operator tTVReal, ())\n\t{\n\t\treturn AsReal();\n\t}\n\n\t//---- substitution -----------------------------------------------------\n\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (const tTJSVariant &ref))\n\t{\n\t\t// from tTJSVariant\n\t\tCopyRef(ref);\n\t\treturn *this;\n\t}\n\tTJS_METHOD_DEF(void, CopyRef, (const tTJSVariant & ref)); // from reference to tTJSVariant\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (iTJSDispatch2 *ref)); // from Object\n\tTJS_METHOD_DEF(tTJSVariant &, SetObject, (iTJSDispatch2 *ref)) { return this->operator =(ref); }\n\tTJS_METHOD_DEF(tTJSVariant &, SetObject, (iTJSDispatch2 *object, iTJSDispatch2 *objthis));\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (tTJSVariantClosure ref)); // from Object Closure\n#ifdef TJS_SUPPORT_VCL\n\ttTJSVariant & operator =(WideString s); // from WideString\n#endif\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (tTJSVariantString *ref)); // from tTJSVariantString\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (tTJSVariantOctet *ref)); // from tTJSVariantOctet\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (const tTJSString & ref)); // from tTJSString\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (const tjs_char *ref)); //  from String\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (const tjs_nchar *ref)); // from narrow string\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (bool ref));\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (tjs_int32 ref));\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (const tTVInteger ref)); // from Integer64\n\tTJS_METHOD_DEF(tTJSVariant &, operator =, (tjs_real ref)); // from double\n\n\t//---- operators --------------------------------------------------------\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator ||, (const tTJSVariant & rhs))\n\t{\n\t\treturn operator bool()||rhs.operator bool();\n\t}\n\n\tTJS_METHOD_DEF(void, logicalorequal, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator &&, (const tTJSVariant & rhs))\n\t{\n\t\treturn operator bool()&&rhs.operator bool();\n\t}\n\n\tTJS_METHOD_DEF(void, logicalandequal, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator |, (const tTJSVariant & rhs))\n\t{\n\t\treturn (tTVInteger)(AsInteger()|rhs.AsInteger());\n\t}\n\n\tTJS_METHOD_DEF(void, operator |=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator ^, (const tTJSVariant & rhs))\n\t{\n\t\treturn (tTVInteger)(AsInteger()^rhs.AsInteger());\n\t}\n\n\tTJS_METHOD_DEF(void, increment, ());\n\n\tTJS_METHOD_DEF(void, decrement, ());\n\n\tTJS_METHOD_DEF(void, operator ^=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator &, (const tTJSVariant & rhs))\n\t{\n\t\treturn (tTVInteger)(AsInteger()&rhs.AsInteger());\n\t}\n\n\tTJS_METHOD_DEF(void, operator &=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator !=, (const tTJSVariant & rhs))\n\t{\n\t\treturn !NormalCompare(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator ==, (const tTJSVariant & rhs))\n\t{\n\t\treturn NormalCompare(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator <, (const tTJSVariant & rhs))\n\t{\n\t\treturn GreaterThan(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator >, (const tTJSVariant & rhs))\n\t{\n\t\treturn LittlerThan(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator <=, (const tTJSVariant & rhs))\n\t{\n\t\treturn !LittlerThan(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator >=, (const tTJSVariant & rhs))\n\t{\n\t\treturn !GreaterThan(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator >>, (const tTJSVariant & rhs))\n\t{\n\t\treturn (tTVInteger)(AsInteger()>>(tjs_int)rhs.AsInteger());\n\t}\n\n\tTJS_METHOD_DEF(void, operator >>=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, rbitshift, (tjs_int count))\n\t{\n\t\treturn (tTVInteger)((tjs_uint64)AsInteger()>> count);\n\t}\n\n\tTJS_METHOD_DEF(void, rbitshiftequal, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator <<, (const tTJSVariant & rhs))\n\t{\n\t\treturn (tTVInteger)(AsInteger()<<(tjs_int)rhs.AsInteger());\n\t}\n\n\tTJS_METHOD_DEF(void, operator <<=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator %, (const tTJSVariant & rhs))\n\t{\n\t\ttTVInteger r = rhs.AsInteger();\n\t\tif(r == 0) TJSThrowDivideByZero();\n\t\treturn (tTVInteger)(AsInteger()%r);\n\t}\n\n\tTJS_METHOD_DEF(void, operator %=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator /, (const tTJSVariant & rhs))\n\t{\n\t\tTJSSetFPUE();\n\t\ttTVReal r = rhs.AsReal();\n\t\treturn (AsReal()/r);\n\t}\n\n\tTJS_METHOD_DEF(void, operator /=, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, idiv, (const tTJSVariant & rhs))\n\t{\n\t\ttTVInteger r = rhs.AsInteger();\n\t\tif(r == 0) TJSThrowDivideByZero();\n\t\treturn (tTVInteger)(AsInteger() / r);\n\t}\n\n\tTJS_METHOD_DEF(void, idivequal, (const tTJSVariant &rhs));\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator *, (const tTJSVariant & rhs))\n\t{\n\t\ttTJSVariant l(*this);\n\t\tl *= rhs;\n\t\treturn l;\n\t}\n\nprivate:\n\tvoid InternalMul(const tTJSVariant &rhs);\npublic:\n\tTJS_METHOD_DEF(void, operator *=, (const tTJSVariant &rhs))\n\t{\n\t\tif(vt == tvtInteger && rhs.vt == tvtInteger)\n\t\t{\n\t\t\tInteger *= rhs.Integer;\n\t\t\treturn;\n\t\t}\n\t\tInternalMul(rhs);\n\t}\n\n\tTJS_METHOD_DEF(void, logicalnot, ());\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator !, ())\n\t{\n\t\treturn (tjs_int)!operator bool();\n\t}\n\n\tTJS_METHOD_DEF(void, bitnot, ());\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator ~, ())\n\t{\n\t\treturn (tjs_int64)~AsInteger();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator -, (const tTJSVariant & rhs))\n\t{\n\t\ttTJSVariant l(*this);\n\t\tl -= rhs;\n\t\treturn l;\n\t}\n\n\tTJS_METHOD_DEF(void, tonumber, ());\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator +, ())\n\t{\n\t\tif(vt==tvtInteger || vt==tvtReal) return *this;\n\n\t\tif(vt==tvtString)\n\t\t{\n\t\t\ttTJSVariant val;\n\t\t\tString->ToNumber(val);\n\t\t\treturn val;\n\t\t}\n\n\t\tif(vt==tvtVoid) return 0;\n\n\t\tTJSThrowVariantConvertError(*this, tvtInteger, tvtReal);\n\t\treturn tTJSVariant();\n\t}\n\nprivate:\n\tvoid InternalChangeSign();\npublic:\n\tTJS_METHOD_DEF(void, changesign, ())\n\t{\n\t\tif(vt==tvtInteger)\n\t\t{\n\t\t\tInteger = -Integer;\n\t\t\treturn;\n\t\t}\n\t\tInternalChangeSign();\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator -, ())\n\t{\n\t\ttTJSVariant v(*this);\n\t\tv.changesign();\n\t\treturn v;\n\t}\n\nprivate:\n\tvoid InternalSub(const tTJSVariant &rhs);\npublic:\n\tTJS_METHOD_DEF(void, operator -=, (const tTJSVariant &rhs))\n\t{\n\t\tif(vt == tvtInteger && rhs.vt == tvtInteger)\n\t\t{\n\t\t\tInteger -= rhs.Integer;\n\t\t\treturn;\n\t\t}\n        InternalSub(rhs);\n\t}\n\n\tTJS_CONST_METHOD_DEF(tTJSVariant, operator +, (const tTJSVariant & rhs))\n\t{\n\t\tif(vt==tvtString || rhs.vt==tvtString)\n\t\t{\n\t\t\t// combines as string\n\t\t\ttTJSVariant val;\n\t\t\tval.vt = tvtString;\n\t\t\ttTJSVariantString *s1, *s2;\n\t\t\ts1 = AsString();\n\t\t\ts2 = rhs.AsString();\n\t\t\tval.String = TJSAllocVariantString(*s1, *s2);\n\t\t\tif(s1) s1->Release();\n\t\t\tif(s2) s2->Release();\n\t\t\treturn val;\n\t\t}\n\n\t\tif(vt == rhs.vt)\n\t\t{\n\t\t\tif(vt==tvtOctet)\n\t\t\t{\n\t\t\t\t// combine as octet\n\t\t\t\ttTJSVariant val;\n\t\t\t\tval.vt = tvtOctet;\n\t\t\t\tval.Octet = TJSAllocVariantOctet(Octet, rhs.Octet);\n\t\t\t\treturn val;\n\t\t\t}\n\n\t\t\tif(vt==tvtInteger)\n\t\t\t{\n\t\t\t\treturn Integer+rhs.Integer;\n\t\t\t}\n\t\t}\n\n\t\tif(vt == tvtVoid)\n\t\t{\n\t\t\tif(rhs.vt == tvtInteger || rhs.vt == tvtReal)\n\t\t\t\treturn rhs;\n\t\t}\n\n\t\tif(rhs.vt == tvtVoid)\n\t\t{\n\t\t\tif(vt == tvtInteger || vt == tvtReal) return *this;\n\t\t}\n\n\n\t\tTJSSetFPUE();\n\t\treturn AsReal()+rhs.AsReal();\n\t}\n\n\n\tTJS_METHOD_DEF(void, operator +=, (const tTJSVariant &rhs));\n\n\t//------ allocator/deallocater ------------------------------------------\n\tTJS_STATIC_METHOD_DEF(void *, operator new, (size_t size)) { return new char[size]; }\n\tTJS_STATIC_METHOD_DEF(void, operator delete, (void * p)) { delete [] ((char*)p); }\n\n\tTJS_STATIC_METHOD_DEF(void *, operator new [], (size_t size)) { return new char[size]; }\n\tTJS_STATIC_METHOD_DEF(void, operator delete [], (void *p)) { delete [] ((char*)p); }\n\n\tTJS_STATIC_METHOD_DEF(void *, operator new, (size_t size, void *buf)) { return buf; }\n\n\t//------ persist --------------------------------------------------------\n\n\ttjs_int QueryPersistSize() const;\n\tvoid Persist(tjs_uint8 * dest);\n};\n/*end-of-tTJSVariant*/\n//---------------------------------------------------------------------------\n#ifdef TJS_SUPPORT_VCL\n\t#pragma warn .8027\n\t#pragma warn .8026\n#endif\n\n//---------------------------------------------------------------------------\n\n} // namespace TJS\n#endif\n\n\n\n"
  },
  {
    "path": "src/core/tjs2/tjsVariantString.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// string heap management used by tTJSVariant and tTJSString\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsVariantString.h\"\n#include \"tjsError.h\"\n#include \"tjsUtils.h\"\n#include \"tjsLex.h\"\n#include <algorithm>\n\n\nnamespace TJS\n{\n//---------------------------------------------------------------------------\n// throwing error functions\n//---------------------------------------------------------------------------\nvoid TJSThrowStringDeallocError()\n{\n\tTJS_eTJSVariantError(TJSStringDeallocError);\n}\n//---------------------------------------------------------------------------\nvoid TJSThrowStringAllocError()\n{\n\tTJS_eTJSVariantError(TJSStringAllocError);\n}\n//---------------------------------------------------------------------------\nvoid TJSThrowNarrowToWideConversionError()\n{\n\tTJS_eTJSVariantError(TJSNarrowToWideConversionError);\n}\n//---------------------------------------------------------------------------\ntjs_int TJSGetShorterStrLen(const tjs_char *str, tjs_int max)\n{\n\t// select shorter length over strlen(str) and max\n\tif(!str) return 0;\n\tconst tjs_char *p = str;\n\tmax++;\n\twhile(*p && --max) p++;\n\treturn (tjs_int)(p - str);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// base memory allocation functions for long string\n//---------------------------------------------------------------------------\n#define TJSVS_ALLOC_INC_SIZE_S 16\n\t// additional space for long string heap under TJSVS_ALLOC_DOUBLE_LIMIT\n#define TJSVS_ALLOC_INC_SIZE_L 4000000\n\t// additional space for long string heap over TJSVS_ALLOC_DOUBLE_LIMIT\n#define TJSVS_ALLOC_DOUBLE_LIMIT 4000000\n\t// switching value of double-sizing or incremental-sizing\n//---------------------------------------------------------------------------\n/*static inline*/ tjs_char *TJSVS_malloc(tjs_uint len)\n{\n\tchar *ret = (char*)malloc(\n\t\t(len = (len + TJSVS_ALLOC_INC_SIZE_S))*sizeof(tjs_char) + sizeof(size_t));\n\tif(!ret) TJSThrowStringAllocError();\n\t*(size_t *)ret = len; // embed size\n\treturn (tjs_char*)(ret + sizeof(size_t));\n}\n//---------------------------------------------------------------------------\n/*static inline*/ tjs_char *TJSVS_realloc(tjs_char *buf, tjs_uint len)\n{\n\tif(!buf) return TJSVS_malloc(len);\n\n\t// compare embeded size\n\tsize_t * ptr = (size_t *)((char*)buf - sizeof(size_t));\n\tif(*ptr >= len) return buf; // still adequate\n\n//\tchar *ret = (char*)realloc(ptr,\n//\t\t(len = (len + TJSVS_ALLOC_INC_SIZE))*sizeof(tjs_char) + sizeof(size_t));\n\tif(len < TJSVS_ALLOC_DOUBLE_LIMIT)\n\t\tlen = len * 2;\n\telse\n\t\tlen = len + TJSVS_ALLOC_INC_SIZE_L;\n\n\tchar *ret = (char*)malloc(//ptr,\n\t\tlen*sizeof(tjs_char) + sizeof(size_t));\n\tif(!ret) TJSThrowStringAllocError();\n\tmemcpy(ret + sizeof(size_t), ptr + 1, *ptr*sizeof(tjs_char));\n\t*(size_t *)ret = len; // embed size\n\tTJSVS_free(buf);\n\treturn (tjs_char*)(ret + sizeof(size_t));\n}\n//---------------------------------------------------------------------------\n/*static inline*/ void TJSVS_free(tjs_char *buf)\n{\n\t// free buffer\n\tfree((char*)buf - sizeof(size_t));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// StringHeap\n//---------------------------------------------------------------------------\n//#define TJS_VS_USE_SYSTEM_NEW\n\n#define HEAP_FLAG_USING 0x01\n#define HEAP_FLAG_DELETE 0x02\n#define HEAP_CAPACITY_INC 4096\nstatic tTJSSpinLock TJSStringHeapCS;\nstatic std::vector<tTJSVariantString*> *TJSStringHeapList = NULL;\nstatic tTJSVariantString ** TJSStringHeapFreeCellList = NULL;\n//static tjs_uint TJSStringHeapFreeCellListCapacity = 0;\nstatic tjs_uint TJSStringHeapFreeCellListPointer = 0;\nstatic tjs_uint TJSStringHeapAllocCount = 0;\n\nstatic tjs_uint TJSStringHeapLastCheckedFreeBlock = 0;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic void TJSAddStringHeapBlock(void)\n{\n\t// allocate StringHeapBlock\n\ttTJSVariantString *h;\n\th = new tTJSVariantString[HEAP_CAPACITY_INC];\n\tmemset(h, 0, sizeof(tTJSVariantString) * HEAP_CAPACITY_INC);\n\tTJSStringHeapList->push_back(h);\n\n\t// re-allocate TJSFreeCellList\n\tif(TJSStringHeapFreeCellList) delete [] TJSStringHeapFreeCellList;\n\tTJSStringHeapFreeCellList =\n\t\tnew tTJSVariantString *[TJSStringHeapList->size() * HEAP_CAPACITY_INC];\n\n\t// prepare free list\n\tfor(tjs_int i = HEAP_CAPACITY_INC - 1; i >= 0; i--)\n\t\tTJSStringHeapFreeCellList[i] = h + i;\n\tTJSStringHeapFreeCellListPointer = HEAP_CAPACITY_INC;\n}\n//---------------------------------------------------------------------------\nstatic void TJSInitStringHeap()\n{\n\tTJSStringHeapList = new std::vector<tTJSVariantString*>();\n\tTJSAddStringHeapBlock(); // initial block\n}\n//---------------------------------------------------------------------------\nstatic void TJSUninitStringHeap(void)\n{\n\tif(!TJSStringHeapList) return;\n\tif(!TJSStringHeapList->empty())\n\t{\n#if 0\n\t\tstd::vector<tTJSVariantString*>::iterator c;\n\t\tfor(c = TJSStringHeapList->end()-1; c >= TJSStringHeapList->begin(); c--)\n\t\t{\n\t\t\ttTJSVariantString *h = *c;\n\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t{\n\t\t\t\tif(h[i].HeapFlag & HEAP_FLAG_USING)\n\t\t\t\t{\n\t\t\t\t\t// using cell\n\t\t\t\t\tif(h[i].LongString) TJSVS_free(h[i].LongString);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete [] h;\n\t\t}\n#else\n\t\tstd::vector<tTJSVariantString*>::reverse_iterator c;\n\t\tfor( c = TJSStringHeapList->rbegin(); c != TJSStringHeapList->rend(); c++ ) {\n\t\t\ttTJSVariantString *h = *c;\n\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++) {\n\t\t\t\tif(h[i].HeapFlag & HEAP_FLAG_USING) {\n\t\t\t\t\t// using cell\n\t\t\t\t\tif(h[i].LongString) TJSVS_free(h[i].LongString);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete [] h;\n\t\t}\n#endif\n\t}\n\n\tdelete TJSStringHeapList;\n\tTJSStringHeapList = NULL;\n\n\tif(TJSStringHeapFreeCellList)\n\t{\n\t\tdelete [] TJSStringHeapFreeCellList;\n\t\tTJSStringHeapFreeCellList = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_UNRELEASED_STRING\nstatic void TJSUninitStringHeap(void)\n{\n\tif(!TJSStringHeapList) return;\n\tif(!TJSStringHeapList->empty())\n\t{\n\t\tstd::vector<tTJSVariantString*>::iterator c;\n\t\tfor(c = TJSStringHeapList->end()-1; c >= TJSStringHeapList->begin(); c--)\n\t\t{\n\t\t\ttTJSVariantString *h = *c;\n\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t{\n\t\t\t\tif(h[i].HeapFlag & HEAP_FLAG_USING)\n\t\t\t\t{\n\t\t\t\t\t// using cell\n\t\t\t\t\tchar buf[1024];\n\t\t\t\t\tTJS_nsprintf(buf, \"%p:%ls\", h + i,\n\t\t\t\t\t\th[i].LongString?h[i].LongString:h[i].ShortString);\n\t\t\t\t\tOutputDebugString(buf);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n#pragma exit TJSReportUnreleasedStringHeap 1\n\n#endif\n\n//---------------------------------------------------------------------------\n#ifdef TJS_DEBUG_DUMP_STRING\nvoid TJSDumpStringHeap(void)\n{\n\tif(!TJSStringHeapList) return;\n\tif(!TJSStringHeapList->empty())\n\t{\n\t\tFILE *f = fopen(\"string.txt\", \"wt\");\n\t\tif(!f) return;\n\t\tstd::vector<tTJSVariantString*>::iterator c;\n\t\tfor(c = TJSStringHeapList->end()-1; c >= TJSStringHeapList->begin(); c--)\n\t\t{\n\t\t\ttTJSVariantString *h = *c;\n\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t{\n\t\t\t\tif(h[i].HeapFlag & HEAP_FLAG_USING)\n\t\t\t\t{\n\t\t\t\t\t// using cell\n\t\t\t\t\ttTJSNarrowStringHolder narrow(h[i].LongString?h[i].LongString:h[i].ShortString);\n\n\t\t\t\t\tfprintf(f, \"%s\\n\", (const char*)narrow);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfclose(f);\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nstatic int TJS_USERENTRY TJSStringHeapSortFunction(const void *a, const void *b)\n{\n\treturn (int)(*(const tTJSVariantString **)b - *(const tTJSVariantString **)a);\n}\n//---------------------------------------------------------------------------\nvoid TJSCompactStringHeap()\n{\n#ifdef TJS_DEBUG_CHECK_STRING_HEAP_INTEGRITY\n\n\tif(!TJSStringHeapList) return;\n\tif(!TJSStringHeapList->empty())\n\t{\n\t\tstd::vector<tTJSVariantString*>::iterator c;\n\t\tfor(c = TJSStringHeapList->end()-1; c >= TJSStringHeapList->begin(); c--)\n\t\t{\n\t\t\ttTJSVariantString *h = *c;\n\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t{\n\t\t\t\tif(h[i].HeapFlag & HEAP_FLAG_USING)\n\t\t\t\t{\n\t\t\t\t\t// using cell\n\t\t\t\t\tconst tjs_char * ptr = h[i].operator const tjs_char *();\n\t\t\t\t\tif(ptr[0] == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tOutputDebugString(\"empty string cell found\");\n\t\t\t\t\t}\n\t\t\t\t\tif(TJS_strlen(ptr) != h[i].GetLength())\n\t\t\t\t\t{\n\t\t\t\t\t\tOutputDebugString(\"invalid string length cell found\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n\n#define TJS_SORT_STR_CELL_MAX 1000\n#define TJS_CHECK_FREE_BLOCK_MAX 50\n\n\t// sort free cell list by address\n\tif(!TJSStringHeapFreeCellList) return;\n\tif(!TJSStringHeapList) return;\n\n\t{\t// thread-protected\n\t\ttTJSSpinLockHolder csh(TJSStringHeapCS);\n\n#ifndef __CODEGUARD__\n\t// may be very slow when used with codeguard\n\t\t// sort TJSStringHeapFreeCellList\n\t\ttTJSVariantString ** start;\n\t\ttjs_int count;\n\t\tif(TJSStringHeapFreeCellListPointer > TJS_SORT_STR_CELL_MAX)\n\t\t{\n\t\t\t// too large; sort last TJS_SORT_STR_CELL_MAX items\n\t\t\tstart = TJSStringHeapFreeCellList +\n\t\t\t\tTJSStringHeapFreeCellListPointer - TJS_SORT_STR_CELL_MAX;\n\t\t\tcount = TJS_SORT_STR_CELL_MAX;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstart = TJSStringHeapFreeCellList;\n\t\t\tcount = TJSStringHeapFreeCellListPointer;\n\t\t}\n\n\t\tqsort(start,\n\t\t\tcount,\n\t\t\tsizeof(tTJSVariantString *),\n\t\t\tTJSStringHeapSortFunction);\n#endif\n\n\t\t// delete all-freed heap block\n\n\t\t// - mark all-freed heap block\n\t\ttjs_int free_block_count = 0;\n\n\t\tif(TJSStringHeapList)\n\t\t{\n\t\t\tif(TJSStringHeapLastCheckedFreeBlock >= TJSStringHeapList->size())\n\t\t\t\tTJSStringHeapLastCheckedFreeBlock = 0;\n\t\t\ttjs_uint block_ind = TJSStringHeapLastCheckedFreeBlock;\n\t\t\ttjs_int count = 0;\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\ttjs_int freecount = 0;\n\t\t\t\ttTJSVariantString * block = (*TJSStringHeapList)[block_ind];\n\t\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t\t{\n\t\t\t\t\tif(!(block[i].HeapFlag & HEAP_FLAG_USING))\n\t\t\t\t\t\tfreecount ++;\n\t\t\t\t}\n\n\t\t\t\tif(freecount == HEAP_CAPACITY_INC)\n\t\t\t\t{\n\t\t\t\t\t// all freed\n\t\t\t\t\tfree_block_count ++;\n\t\t\t\t\tfor(tjs_int i = 0; i < HEAP_CAPACITY_INC; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock[i].HeapFlag = HEAP_FLAG_DELETE;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tblock_ind ++;\n\t\t\t\tif(block_ind >= TJSStringHeapList->size()) block_ind = 0;\n\t\t\t\tcount++;\n\t\t\t\t\n\t\t\t} while(count < TJS_CHECK_FREE_BLOCK_MAX &&\n\t\t\t\tblock_ind != TJSStringHeapLastCheckedFreeBlock);\n\n\t\t\tTJSStringHeapLastCheckedFreeBlock = block_ind;\n\t\t}\n\n\t\t// - delete all marked cell from TJSStringHeapFreeCellList\n\t\tif(free_block_count)\n\t\t{\n\t\t\ttTJSVariantString ** newlist =\n\t\t\t\tnew tTJSVariantString *\n\t\t\t\t\t[(TJSStringHeapList->size() - free_block_count) *\n\t\t\t\t\t  HEAP_CAPACITY_INC];\n\n\t\t\ttjs_uint wp = 0;\n\t\t\ttjs_uint rp;\n\t\t\tfor(rp = 0; rp < TJSStringHeapFreeCellListPointer; rp++)\n\t\t\t{\n\t\t\t\tif(TJSStringHeapFreeCellList[rp]->HeapFlag != HEAP_FLAG_DELETE)\n\t\t\t\t\tnewlist[wp++] =\n\t\t\t\t\t\tTJSStringHeapFreeCellList[rp];\n\t\t\t}\n\n\t\t\tTJSStringHeapFreeCellListPointer = wp;\n\n\t\t\tdelete [] TJSStringHeapFreeCellList;\n\t\t\tTJSStringHeapFreeCellList = newlist;\n\t\t}\n\n\t\t// - delete all marked block\n\t\tif(free_block_count)\n\t\t{\n\t\t\tstd::vector<tTJSVariantString*>::iterator i;\n\t\t\tfor(i = TJSStringHeapList->begin(); i != TJSStringHeapList->end();)\n\t\t\t{\n\t\t\t\tif((*i)[0].HeapFlag == HEAP_FLAG_DELETE)\n\t\t\t\t{\n\t\t\t\t\t// to be deleted\n\t\t\t\t\tdelete [] (*i);\n\t\t\t\t\ti = TJSStringHeapList->erase(i);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocStringHeap(void)\n{\n\tif(TJSStringHeapAllocCount == 0)\n\t{\n\t\t// first string to alloc\n\t\t// here must be called in main thread...\n\t\tTJSInitStringHeap(); // initial block\n\t}\n\n\t{\t// thread-protected\n\t\ttTJSSpinLockHolder csh(TJSStringHeapCS);\n\n#ifdef TJS_VS_USE_SYSTEM_NEW\n\t\ttTJSVariantString *ret = new tTJSVariantString();\n#else\n\t\tif(TJSStringHeapFreeCellListPointer == 0)\n\t\t\tTJSAddStringHeapBlock();\n\n\t\ttTJSVariantString *ret =\n\t\t\tTJSStringHeapFreeCellList[--TJSStringHeapFreeCellListPointer];\n#endif\n\n\t\tret->RefCount = 0;\n\t\tret->Length = 0;\n\t\tret->LongString = NULL;\n\t\tret->HeapFlag = HEAP_FLAG_USING;\n\t\tret->Hint = 0;\n\n\t\tTJSStringHeapAllocCount ++;\n\n\t\treturn ret;\n\n\t}\t// end-of-thread-protected\n}\n//---------------------------------------------------------------------------\nvoid TJSDeallocStringHeap(tTJSVariantString * vs)\n{\n\t// free vs\n\n\t{\t// thread-pretected\n\t\ttTJSSpinLockHolder csh(TJSStringHeapCS);\n\n#ifdef TJS_DEBUG_CHECK_STRING_HEAP_INTEGRITY\n\t\t{\n\t\t\tconst tjs_char * ptr = vs->operator const tjs_char *();\n\t\t\tif(ptr[0] == 0)\n\t\t\t{\n\t\t\t\tOutputDebugString(\"empty string cell found\");\n\t\t\t}\n\t\t\tif(TJS_strlen(ptr) != vs->GetLength())\n\t\t\t{\n\t\t\t\tOutputDebugString(\"invalid string length cell found\");\n\t\t\t}\n\t\t}\n#endif\n\n\n\t\tif(vs->LongString) TJSVS_free(vs->LongString);\n\n\t\tvs->HeapFlag = 0;\n\n#ifdef TJS_VS_USE_SYSTEM_NEW\n\t\tdelete vs;\n#else\n\t\tTJSStringHeapFreeCellList[TJSStringHeapFreeCellListPointer++] = vs;\n#endif\n\n\t\tTJSStringHeapAllocCount--;\n\t}\t// end-of-thread-protected\n\n\tif(TJSStringHeapAllocCount == 0)\n\t{\n\t\t// last string was freed\n\t\t// here must be called in main thread...\n\t\tTJSUninitStringHeap();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSVariantString\n//---------------------------------------------------------------------------\nvoid tTJSVariantString::Release()\n{\n/*\n\tif(!this) return;\n\t\t// this is not a REAL remedy, but enough to buster careless misses...\n\t\t// (NULL->Release() problem)\n*/\n\n\tif(RefCount==0)\n\t{\n\t\tTJSDeallocStringHeap(this);\n\t\treturn;\n\t}\n\tRefCount--;\n}\n//---------------------------------------------------------------------------\ntTVInteger tTJSVariantString::ToInteger() const\n{\n\tif(!this) return 0;\n\n\ttTJSVariant val;\n\tconst tjs_char *ptr = this->operator const tjs_char *();\n\tif(TJSParseNumber(val, &ptr)) \treturn val.AsInteger();\n\treturn 0;\n}\n//---------------------------------------------------------------------------\ntTVReal tTJSVariantString::ToReal() const\n{\n\tif(!this) return 0;\n\n\ttTJSVariant val;\n\tconst tjs_char *ptr = this->operator const tjs_char *();\n\tif(TJSParseNumber(val, &ptr)) return val.AsReal();\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSVariantString::ToNumber(tTJSVariant &dest) const\n{\n\tif(!this) { dest = 0; return; }\n\n\tconst tjs_char *ptr = this->operator const tjs_char *();\n\tif(TJSParseNumber(dest, &ptr)) return;\n\n\tdest = 0;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString::operator const tjs_char *() const\n{\n\treturn (!this) ? (NULL) : (LongString ? LongString : ShortString);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSVariantString::GetLength() const\n{\n\tif (!this) return 0;\n\treturn Length;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * tTJSVariantString::FixLength()\n{\n\tif(!this) return NULL;\n\n\tif(RefCount != 0) TJSThrowStringDeallocError();\n\tLength = (tjs_int)TJS_strlen(this->operator const tjs_char*());\n\tif(!Length)\n\t{\n\t\tTJSDeallocStringHeap(this);\n\t\treturn NULL;\n\t}\n\treturn this;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// other allocation functions\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantString(const tjs_char *ref1, const tjs_char *ref2)\n{\n\tif(!ref1 && !ref2) return NULL;\n\n\tif(ref1)\n\t{\n\t\tif(ref1[0]==0)\n\t\t{\n\t\t\tif(ref2)\n\t\t\t{\n\t\t\t\tif(ref2[0]==0) return NULL;\n\t\t\t}\n\t\t}\n\t}\n\n\ttjs_intptr_t len1 = ref1 ? TJS_strlen(ref1) : 0;\n\ttjs_intptr_t len2 = ref2 ? TJS_strlen(ref2) : 0;\n\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\n\tif(len1+len2>TJS_VS_SHORT_LEN)\n\t{\n\t\tret->LongString = TJSVS_malloc((tjs_uint)(len1+len2+1));\n\t\tif(ref1) TJS_strcpy(ret->LongString , ref1);\n\t\tif(ref2) TJS_strcpy(ret->LongString + len1, ref2);\n\t}\n\telse\n\t{\n\t\tif(ref1) TJS_strcpy(ret->ShortString, ref1);\n\t\tif(ref2) TJS_strcpy(ret->ShortString + len1, ref2);\n\t}\n\tret->Length = (tjs_int)(len1+len2);\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantString(const tjs_char *ref)\n{\n\tif(!ref) return NULL;\n\tif(ref[0]==0) return NULL;\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\tret->SetString(ref);\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantString(const tjs_char *ref, tjs_int n)\n{\n\tif(n==0) return NULL;\n\tif(!ref) return NULL;\n\tif(ref[0]==0) return NULL;\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\tret->SetString(ref, n);\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantString(const tjs_nchar *ref)\n{\n\tif(!ref) return NULL;\n\tif(ref[0]==0) return NULL;\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\tret->SetString(ref);\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantString(const tjs_uint8 **src)\n{\n\ttjs_uint size = *(const tjs_uint *)(*src);\n\t*src += sizeof(tjs_uint);\n\tif(!size) return 0;\n\t*src += sizeof(tjs_uint);\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\tret->SetString((const tjs_char *)src, size);\n\t*src += sizeof(tjs_char) * size;\n\treturn ret;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAllocVariantStringBuffer(tjs_uint len)\n{\n\t/* note that you must call FixLength if you allocate larger than the\n\tactual string size */\n\n\n\ttTJSVariantString *ret = TJSAllocStringHeap();\n\tret->AllocBuffer(len);\n\treturn ret;\n}\n\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAppendVariantString(tTJSVariantString *str,\n\tconst tjs_char *app)\n{\n\tif(!app) return str;\n\tif(!str)\n\t{\n\t\tstr = TJSAllocVariantString(app);\n\t\treturn str;\n\t}\n\tstr->Append(app);\n\treturn str;\n}\n//---------------------------------------------------------------------------\ntTJSVariantString * TJSAppendVariantString(tTJSVariantString *str,\n\tconst tTJSVariantString *app)\n{\n\tif(!app) return str;\n\tif(!str)\n\t{\n\t\tstr = TJSAllocVariantString(app->operator const tjs_char *());\n\t\treturn str;\n\t}\n\tstr->Append(app->operator const tjs_char *(), app->GetLength());\n\treturn str;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nclass tTVPVariantStringHolder\n{\n\t// this class keeps one Variant String from program start to program end,\n\t// to ensure heap system are alive during program's lifetime.\n\ttTJSVariantString * String;\npublic:\n\ttTVPVariantStringHolder()\n\t{ String = TJSAllocVariantString(TJS_W(\"This is a dummy.\")); }\n\t~tTVPVariantStringHolder()\n\t{ String->Release(); }\n} static TVPVariantStringHolder;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n#define TJS_VS_FS_OUT_INC_SIZE 32\ntTJSVariantString * TJSFormatString(const tjs_char *format, tjs_uint numparams,\n\ttTJSVariant **params)\n{\n\t// TODO: more reliable implementation\n\n\t// format the string with the format illustrated as \"format\"\n\t// this is similar to C sprintf format, but this support only following:\n\t// % [flags] [width] [.prec] type_char\n\t// flags : '-'|'+'|' '|'#'\n\t// width : n|'0'n|*|\n\t// .prec : '.0'|'.n'|'.*'\n\t// type_char : [diouxXfegEGcs]\n\t// [diouxX] as an integer\n\t// [fegEG] as a real\n\t// [cs] as a string\n\t// and, this is safe for output buffer memory or inadequate parameters.\n\n\tconst tjs_char *f = format;\n\tif(!f) return NULL;\n\n\tTJSSetFPUE();\n\ttTJSVariantString *ret = TJSAllocVariantStringBuffer(TJS_VS_FS_OUT_INC_SIZE);\n\ttjs_uint allocsize = TJS_VS_FS_OUT_INC_SIZE;\n\ttjs_char *o = const_cast<tjs_char*>(ret->operator const tjs_char*());\n\ttjs_uint s = 0;\n\n\ttjs_uint in = 0;\n\n#define check_alloc \\\n\t\t\tif(s >= allocsize) \\\n\t\t\t{ \\\n\t\t\t\tret->AppendBuffer(TJS_VS_FS_OUT_INC_SIZE); \\\n\t\t\t\to = const_cast<tjs_char*>(ret->operator const tjs_char*()); \\\n\t\t\t\tallocsize += TJS_VS_FS_OUT_INC_SIZE; \\\n\t\t\t}\n\n\tfor(;*f;)\n\t{\n\t\tif(*f!=TJS_W('%'))\n\t\t{\n\t\t\tcheck_alloc;\n\t\t\to[s++] = *(f++);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// following are only format-checking, actual processing is in sprintf.\n\n\t\ttjs_char flag = 0;\n\t\ttjs_uint width = 0;\n//\t\tbool zeropad = false;\n\t\tbool width_ind = false;\n\t\ttjs_uint prec = 0;\n//\t\tbool precspec = false;\n\t\tbool prec_ind = false;\n\t\tconst tjs_char *fst = f;\n\n\t\tf++;\n\t\tif(!*f) goto error;\n\n\t// flags\n\t\tswitch(*f)\n\t\t{\n\t\tcase TJS_W('-'): flag = TJS_W('-'); break;\n\t\tcase TJS_W('+'): flag = TJS_W('+'); break;\n\t\tcase TJS_W('#'): flag = TJS_W('#'); break;\n\t\tdefault: goto width;\n\t\t}\n\n\t\tf++;\n\t\tif(!*f) goto error;\n\n\twidth:\n\t\tswitch(*f)\n\t\t{\n\t\tcase TJS_W('0'): /*zeropad = true;*/ break;\n\t\tdefault: goto width_2;\n\t\t}\n\n\t\tf++;\n\t\tif(!*f) goto error;\n\n\twidth_2:\n\t\tswitch(*f)\n\t\t{\n\t\tcase TJS_W('*'): width_ind = true; break;\n\t\tdefault: goto width_3;\n\t\t}\n\n\t\tf++;\n\t\tif(!*f) goto error;\n\n\t\tgoto prec;\n\n\twidth_3:\n\t\twhile(true)\n\t\t{\n\t\t\tif(*f >= TJS_W('0') && *f <= TJS_W('9'))\n\t\t\t\twidth = width *10 + (*f - TJS_W('0'));\n\t\t\telse\n\t\t\t\tbreak;\n\t\t\tf++;\n\t\t}\n\n\t\tif(!*f) goto error;\n\n\tprec:\n\t\tif(*f == TJS_W('.'))\n\t\t{\n\t\t\tf++;\n\t\t\tif(!*f) goto error;\n\t\t\tif(*f == TJS_W('*'))\n\t\t\t{\n\t\t\t\tprec_ind = true;\n\t\t\t\tf++;\n\t\t\t\tif(!*f) goto error;\n\t\t\t\tgoto type_char;\n\t\t\t}\n\t\t\tif(*f < TJS_W('0') || *f > TJS_W('9')) goto error;\n\t\t\t/*precspec = true;*/\n\t\t\tdo\n\t\t\t{\n\t\t\t\tprec = prec * 10 + (*f-TJS_W('0'));\n\t\t\t\tf++;\n\t\t\t} while(*f >= TJS_W('0') && *f <= TJS_W('9'));\n\t\t}\n\n\ttype_char:\n\t\tswitch(*f)\n\t\t{\n\t\tcase TJS_W('%'):\n\t\t\t// literal '%'\n\t\t\tcheck_alloc;\n\t\t\to[s++] = '%';\n\t\t\tf++;\n\t\t\tcontinue;\n\n\n\t\tcase TJS_W('c'):\n\t\tcase TJS_W('s'):\n\t\t  {\n\t\t\tif(width_ind)\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\twidth = (tjs_int)(params[in++])->AsInteger();\n\t\t\t}\n\t\t\tif(prec_ind)\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tprec = (tjs_int)(params[in++])->AsInteger();\n\t\t\t}\n\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\ttTJSVariantString *str = (params[in++])->AsString();\n\t\t\tif(str)\n\t\t\t{\n\t\t\t\ttjs_uint slen = str->GetLength();\n\t\t\t\tif(!prec) prec = slen;\n\t\t\t\tif(*f == TJS_W('c') && prec > 1 ) prec = 1;\n\t\t\t\tif(width < prec) width = prec;\n\t\t\t\tif(s + width > allocsize)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_uint inc_size;\n\t\t\t\t\t\tret->AppendBuffer(inc_size = s+width-allocsize+TJS_VS_FS_OUT_INC_SIZE);\n\t\t\t\t\t\to = const_cast<tjs_char*>(ret->operator const tjs_char*());\n\t\t\t\t\t\tallocsize += inc_size;\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\tstr->Release();\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttjs_uint pad = width - prec;\n\t\t\t\tif(pad)\n\t\t\t\t{\n\t\t\t\t\tif(flag == TJS_W('-'))\n\t\t\t\t\t{\n\t\t\t\t\t\t// left align\n\t\t\t\t\t\tif(str) TJS_strncpy(o+s, *str, prec);\n\t\t\t\t\t\ttjs_char * p = o + s + prec;\n\t\t\t\t\t\twhile(pad--) 0[p++] = TJS_W(' ');\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// right align\n\t\t\t\t\t\tif(str) TJS_strncpy(o+s+pad, *str, prec);\n\t\t\t\t\t\ttjs_char *p = o + s;\n\t\t\t\t\t\twhile(pad--) 0[p++] = TJS_W(' ');\n\t\t\t\t\t}\n\t\t\t\t\ts += width;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(str) TJS_strncpy(o+s, *str, prec);\n\t\t\t\t\ts += prec;\n\t\t\t\t}\n\t\t\t\tstr->Release();\n\t\t\t}\n\t\t\tf++;\n\t\t\tcontinue;\n\t\t  }\n\t\tcase TJS_W('d'): case TJS_W('i'): case TJS_W('o'): case TJS_W('u'):\n\t\tcase TJS_W('x'): case TJS_W('X'):\n\t\t  {\n\t\t\t// integers\n\t\t\tif(width+prec > 900) goto error;// too long\n\t\t\ttjs_char buf[1024];\n\t\t\t//tjs_char *p;\n\t\t\ttjs_char fmt[70];\n\t\t\ttjs_uint fmtlen = (tjs_uint)(f - fst);\n\t\t\tif(fmtlen > 65) goto error;  // too long\n\t\t\tTJS_strncpy(fmt, fst, fmtlen);\n// #ifdef WIN32\n// \t\t\tfmt[fmtlen++] = 'I';\n// \t\t\tfmt[fmtlen++] = '6';\n// \t\t\tfmt[fmtlen++] = '4';\n// #else\n\t\t\tfmt[fmtlen++] = 'l';\n\t\t\tfmt[fmtlen++] = 'l';\n//#endif\n\t\t\tfmt[fmtlen++] = *f;\n\t\t\tfmt[fmtlen++] = 0;\n\t\t\tint ind[2];\n\t\t\tif(!width_ind && !prec_ind)\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVInteger integer = (params[in++])->AsInteger();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, integer);\n\t\t\t}\n\t\t\telse if((!width_ind && prec_ind) || (width_ind && !prec_ind))\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[0] = static_cast<int>( (params[in++])->AsInteger() );\n\t\t\t\tif(width_ind && ind[0] + prec > 900) goto error;\n\t\t\t\tif(prec_ind && ind[0] + width > 900) goto error;\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVInteger integer = (params[in++])->AsInteger();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, ind[0], integer);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[0] = static_cast<int>( (params[in++])->AsInteger() );\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[1] = static_cast<int>( (params[in++])->AsInteger() );\n\t\t\t\tif(ind[0] + ind[1] > 900) goto error;\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVInteger integer = (params[in++])->AsInteger();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, ind[0], ind[1], integer);\n\t\t\t}\n\n\t\t\ttjs_uint size = (tjs_uint)TJS_strlen(buf);\n\t\t\ttjs_uint inc_size;\n\t\t\tif(s+size > allocsize)\n\t\t\t{\n\t\t\t\tret->AppendBuffer(inc_size = s+size-allocsize+TJS_VS_FS_OUT_INC_SIZE);\n\t\t\t\to = const_cast<tjs_char*>(ret->operator const tjs_char*());\n\t\t\t\tallocsize += inc_size;\n\t\t\t}\n\t\t\tTJS_strcpy(o+s, buf);\n\t\t\ts += size;\n\n\t\t\tf++;\n\t\t\tcontinue;\n\t\t  }\n\t\tcase TJS_W('f'): case TJS_W('e'): case TJS_W('g'): case TJS_W('E'):\n\t\tcase TJS_W('G'):\n\t\t  {\n\t\t\t// reals\n \t\t\tif(width+prec > 900) goto error;// too long\n\t\t\ttjs_char buf[1024];\n\t\t\ttjs_char fmt[70];\n\t\t\ttjs_uint fmtlen = (tjs_uint)(f - fst);\n\t\t\tif(fmtlen > 67) goto error;  // too long\n\t\t\tTJS_strncpy(fmt, fst, fmtlen);\n// #ifdef WIN32\n// \t\t\tfmt[fmtlen++] = 'l';\n// #else\n\t\t\tfmt[fmtlen++] = 'l';\n//#endif\n\t\t\tfmt[fmtlen++] = *f;\n\t\t\tfmt[fmtlen++] = 0;\n\t\t\tint ind[2];\n\t\t\tif(!width_ind && !prec_ind)\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVReal real = (params[in++])->AsReal();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, real);\n\t\t\t}\n\t\t\telse if((!width_ind && prec_ind) || (width_ind && !prec_ind))\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[0] = static_cast<int>( (params[in++])->AsInteger() );\n \t\t\t\tif(width_ind && ind[0] + prec > 900) goto error;\n\t\t\t\tif(prec_ind && ind[0] + width > 900) goto error;\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVReal real = (params[in++])->AsReal();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, ind[0], real);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[0] = static_cast<int>( (params[in++])->AsInteger() );\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\tind[1] = static_cast<int>( (params[in++])->AsInteger() );\n\t\t\t\tif(ind[0] + ind[1] > 900) goto error;\n\t\t\t\tif(in>=numparams) TJS_eTJSVariantError(TJSBadParamCount);\n\t\t\t\ttTVReal real = (params[in++])->AsReal();\n\t\t\t\tTJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), fmt, ind[0], ind[1], real);\n\t\t\t}\n\n\t\t\ttjs_uint size = (tjs_uint)TJS_strlen(buf);\n\t\t\ttjs_uint inc_size;\n\t\t\tif(s+size > allocsize)\n\t\t\t{\n\t\t\t\tret->AppendBuffer(inc_size = s+size-allocsize+TJS_VS_FS_OUT_INC_SIZE);\n\t\t\t\to = const_cast<tjs_char*>(ret->operator const tjs_char*());\n\t\t\t\tallocsize += inc_size;\n\t\t\t}\n\t\t\tTJS_strcpy(o+s, buf);\n\t\t\ts += size;\n\t\t\tf++;\n\t\t\tcontinue;\n\t\t  }\n\t\t}\n\n\t}\n\n\to[s] = 0;\n\n\tret = ret->FixLength();\n\n\treturn ret;\n\nerror:\n\tTJS_eTJSVariantError(TJSInvalidFormatString);\n\treturn NULL; // not reached\n}\n//---------------------------------------------------------------------------\n\n} // namespcae TJS\n\n"
  },
  {
    "path": "src/core/tjs2/tjsVariantString.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// string heap management used by tTJSVariant and tTJSString\n//---------------------------------------------------------------------------\n#ifndef tjsVariantStringH\n#define tjsVariantStringH\n\n#include \"tjsConfig.h\"\n#include <stdlib.h>\n#include <string.h>\n#include <atomic>\n\nnamespace TJS\n{\n\n// #define TJS_DEBUG_UNRELEASED_STRING\n// #define TJS_DEBUG_CHECK_STRING_HEAP_INTEGRITY\n// #define TJS_DEBUG_DUMP_STRING\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSVariantString stuff\n//---------------------------------------------------------------------------\n#define TJS_VS_SHORT_LEN 21\n/*]*/\nclass tTJSVariantString;\nextern tjs_int TJSGetShorterStrLen(const tjs_char *str, tjs_int max);\nextern tTJSVariantString * TJSAllocStringHeap(void);\nextern void TJSDeallocStringHeap(tTJSVariantString * vs);\nextern void TJSThrowStringAllocError();\nextern void TJSThrowNarrowToWideConversionError();\nextern void TJSCompactStringHeap();\n#ifdef TJS_DEBUG_DUMP_STRING\nextern void TJSDumpStringHeap(void);\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// base memory allocation functions for long string\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_char *, TJSVS_malloc, (tjs_uint len));\nTJS_EXP_FUNC_DEF(tjs_char *, TJSVS_realloc, (tjs_char *buf, tjs_uint len));\nTJS_EXP_FUNC_DEF(void, TJSVS_free, (tjs_char *buf));\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTJSVariantString\n//---------------------------------------------------------------------------\n#pragma pack(push, 4)\nstruct tTJSVariantString_S\n{\n\t//tjs_int RefCount; // reference count - 1\n\tstd::atomic_long  RefCount;\n\ttjs_char *LongString;\n\ttjs_char ShortString[TJS_VS_SHORT_LEN +1];\n\ttjs_int Length; // string length\n\ttjs_uint32 HeapFlag;\n\ttjs_uint32 Hint;\n};\n#pragma pack(pop)\n/*]*/\n\n\n/*start-of-tTJSVariantString*/\nclass tTJSVariantString : public tTJSVariantString_S\n{\npublic:\n\n\tTJS_METHOD_DEF(void, AddRef, ())\n\t{\n\t\tRefCount++;\n\t}\n\n\tTJS_METHOD_DEF(void, Release, ());\n\n\tTJS_METHOD_DEF(void, SetString, (const tjs_char *ref, tjs_int maxlen = -1))\n\t{\n\t\tif(LongString) TJSVS_free(LongString), LongString = NULL;\n\t\ttjs_int len;\n\t\tif(maxlen != -1)\n\t\t\tlen = TJSGetShorterStrLen(ref, maxlen);\n\t\telse\n\t\t\tlen = (tjs_int)TJS_strlen(ref);\n\n\t\tLength = len;\n\t\tif(len>TJS_VS_SHORT_LEN)\n\t\t{\n\t\t\tLongString = TJSVS_malloc(len+1);\n\t\t\tTJS_strcpy_maxlen(LongString, ref, len);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTJS_strcpy_maxlen(ShortString, ref, len);\n\t\t}\n\t}\n\n\tTJS_METHOD_DEF(void, SetString, (const tjs_nchar *ref))\n\t{\n\t\tif(LongString) TJSVS_free(LongString), LongString = NULL;\n\t\ttjs_int len = (tjs_int)TJS_narrowtowidelen(ref);\n\t\tif(len == -1) TJSThrowNarrowToWideConversionError();\n\n\t\tLength = len;\n\t\tif(len>TJS_VS_SHORT_LEN)\n\t\t{\n\t\t\tLongString = TJSVS_malloc(len+1);\n\t\t\tLongString[TJS_narrowtowide(LongString, ref, len)] = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tShortString[TJS_narrowtowide(ShortString, ref, TJS_VS_SHORT_LEN)] = 0;\n\t\t}\n\t}\n\n\tTJS_METHOD_DEF(void, AllocBuffer, (tjs_uint len))\n\t{\n\t\t/* note that you must call FixLength if you allocate larger than the\n\t\t\tactual string size */\n\n\t\tif(LongString) TJSVS_free(LongString), LongString = NULL;\n\n\t\tLength = len;\n\t\tif(len>TJS_VS_SHORT_LEN)\n\t\t{\n\t\t\tLongString = TJSVS_malloc(len+1);\n\t\t\tLongString[len] = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tShortString[len] = 0;\n\t\t}\n\t}\n\n\tTJS_METHOD_DEF(void, ResetString, (const tjs_char *ref))\n\t{\n\t\tif(LongString) TJSVS_free(LongString), LongString = NULL;\n\t\tSetString(ref);\n\t}\n\n\n\tTJS_METHOD_DEF(void, AppendBuffer, (tjs_uint applen))\n\t{\n\t\t/* note that you must call FixLength if you allocate larger than the\n\t\t\tactual string size */\n\n\t\t// assume this != NULL\n\t\ttjs_int newlen = Length += applen;\n\t\tif(LongString)\n\t\t{\n\t\t\t// still long string\n\t\t\tLongString = TJSVS_realloc(LongString, newlen + 1);\n\t\t\tLongString[newlen] = 0;\n\t\t\treturn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(newlen <= TJS_VS_SHORT_LEN)\n\t\t\t{\n\t\t\t\t// still short string\n\t\t\t\tShortString[newlen] = 0;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// becomes a long string\n\t\t\ttjs_char *newbuf = TJSVS_malloc(newlen+1);\n\t\t\tTJS_strcpy(newbuf, ShortString);\n\t\t\tLongString = newbuf;\n\t\t\tLongString[newlen] = 0;\n\t\t\treturn;\n\t\t}\n\n\t}\n\n\tTJS_METHOD_DEF(void, Append, (const tjs_char *str))\n\t{\n\t\t// assume this != NULL\n\t\tAppend(str, (tjs_int)TJS_strlen(str));\n\t}\n\n\tTJS_METHOD_DEF(void, Append, (const tjs_char *str, tjs_int applen))\n\t{\n\t\t// assume this != NULL\n\t\ttjs_int orglen = Length;\n\t\ttjs_int newlen = Length += applen;\n\t\tif(LongString)\n\t\t{\n\t\t\t// still long string\n\t\t\tLongString = TJSVS_realloc(LongString, newlen + 1);\n\t\t\tTJS_strcpy(LongString+orglen, str);\n\t\t\treturn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(newlen <= TJS_VS_SHORT_LEN)\n\t\t\t{\n\t\t\t\t// still short string\n\t\t\t\tTJS_strcpy(ShortString + orglen, str);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// becomes a long string\n\t\t\ttjs_char *newbuf = TJSVS_malloc(newlen+1);\n\t\t\tTJS_strcpy(newbuf, ShortString);\n\t\t\tTJS_strcpy(newbuf+orglen, str);\n\t\t\tLongString = newbuf;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tTJS_CONST_METHOD_DEF(TJS_METHOD_RET(const tjs_char *), operator const tjs_char *, ());\n\n\tTJS_CONST_METHOD_DEF(tjs_int, GetLength, ());\n\n\tTJS_METHOD_DEF(tTJSVariantString *, FixLength, ());\n\n\tTJS_METHOD_DEF(tjs_uint32 *, GetHint, ()) { return &Hint; }\n\n\tTJS_CONST_METHOD_DEF(tTVInteger, ToInteger, ());\n\tTJS_CONST_METHOD_DEF(tTVReal, ToReal, ());\n\tTJS_CONST_METHOD_DEF(void, ToNumber, (tTJSVariant &dest));\n\n\tTJS_CONST_METHOD_DEF(tjs_int, GetRefCount, ())\n\t{\n\t\treturn RefCount;\n\t}\n\n\ttjs_int QueryPersistSize() const\n\t{\n\t\treturn sizeof(tjs_uint) +\n\t\t\tGetLength() * sizeof(tjs_char);\n\t}\n\n\tvoid Persist(tjs_uint8 *dest) const\n\t{\n\t\ttjs_uint size;\n\t\tconst tjs_char *ptr = LongString?LongString:ShortString;\n\t\t*(tjs_uint*)dest = size = GetLength();\n\t\tdest += sizeof(tjs_uint);\n\t\twhile(size--)\n\t\t{\n\t\t\t*(tjs_char*)dest = *ptr;\n\t\t\tdest += sizeof(tjs_char);\n\t\t\tptr++;\n\t\t}\n\t}\n};\n/*end-of-tTJSVariantString*/\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantString, (const tjs_char *ref1,\n\tconst tjs_char *ref2));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantString, (const tjs_char *ref, tjs_int n));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantString, (const tjs_char *ref));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantString, (const tjs_nchar *ref));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantString, (const tjs_uint8 **src));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAllocVariantStringBuffer, (tjs_uint len));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAppendVariantString, (tTJSVariantString *str,\n\tconst tjs_char *app));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSAppendVariantString, (tTJSVariantString *str,\n\tconst tTJSVariantString *app));\nTJS_EXP_FUNC_DEF(tTJSVariantString *, TJSFormatString, (const tjs_char *format, tjs_uint numparams,\n\ttTJSVariant **params));\n\n//---------------------------------------------------------------------------\n} // namespace TJS\n#endif\n"
  },
  {
    "path": "src/core/tjs2/tjsdate.tab.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton implementation for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n/* C LALR(1) parser skeleton written by Richard Stallman, by\n   simplifying the original so-called \"semantic\" parser.  */\n\n/* All symbols defined below should begin with yy or YY, to avoid\n   infringing on user name space.  This should be done even for local\n   variables, as they might otherwise be expanded by user macros.\n   There are some unavoidable exceptions within include files to\n   define necessary library symbols; they are noted \"INFRINGES ON\n   USER NAME SPACE\" below.  */\n\n/* Identify Bison output.  */\n#define YYBISON 1\n\n/* Bison version.  */\n#define YYBISON_VERSION \"2.4.1\"\n\n/* Skeleton name.  */\n#define YYSKELETON_NAME \"yacc.c\"\n\n/* Pure parsers.  */\n#define YYPURE 1\n\n/* Push parsers.  */\n#define YYPUSH 0\n\n/* Pull parsers.  */\n#define YYPULL 1\n\n/* Using locations.  */\n#define YYLSP_NEEDED 0\n\n/* Substitute the variable and function names.  */\n#define yyparse         dpparse\n#define yylex           dplex\n#define yyerror         dperror\n#define yylval          dplval\n#define yychar          dpchar\n#define yydebug         dpdebug\n#define yynerrs         dpnerrs\n\n\n/* Copy the first part of user declarations.  */\n\n/* Line 189 of yacc.c  */\n#line 1 \"tjsdate.y\"\n\n/*---------------------------------------------------------------------------*/\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/*---------------------------------------------------------------------------*/\n/* tjsdate.y */\n/* TJS2 date string parser */\n\n#include <memory>\n\n#include \"tjsTypes.h\"\n#include \"tjsDateParser.h\"\n\n#define YYMALLOC\t::malloc\n#define YYREALLOC\t::realloc\n#define YYFREE\t\t::free\n\n\n/* param */\n#define YYPARSE_PARAM pm\n#define YYLEX_PARAM pm\n\nnamespace TJS {\n\n/* yylex/yyerror prototype decl */\nint dplex(YYSTYPE *yylex, void *pm);\n\nint dperror(char * msg)\n{\n    return 0;\n}\n\n\n#define dp ((tTJSDateParser*)pm)\n\n\n\n/* Line 189 of yacc.c  */\n#line 123 \"tjsdate.tab.cpp\"\n\n/* Enabling traces.  */\n#ifndef YYDEBUG\n# define YYDEBUG 0\n#endif\n\n/* Enabling verbose error messages.  */\n#ifdef YYERROR_VERBOSE\n# undef YYERROR_VERBOSE\n# define YYERROR_VERBOSE 1\n#else\n# define YYERROR_VERBOSE 0\n#endif\n\n/* Enabling the token table.  */\n#ifndef YYTOKEN_TABLE\n# define YYTOKEN_TABLE 0\n#endif\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     DP_AM = 258,\n     DP_PM = 259,\n     DP_NUMBER = 260,\n     DP_MONTH = 261,\n     DP_WDAY = 262,\n     DP_TZ = 263\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 214 of yacc.c  */\n#line 45 \"tjsdate.y\"\n\n\ttjs_int32\t\t\t\t\tval;\n\n\n\n/* Line 214 of yacc.c  */\n#line 173 \"tjsdate.tab.cpp\"\n} YYSTYPE;\nYYLEX_PROTO_DECL\n\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n/* Copy the second part of user declarations.  */\n\n\n/* Line 264 of yacc.c  */\n#line 185 \"tjsdate.tab.cpp\"\n\n#ifdef short\n# undef short\n#endif\n\n#ifdef YYTYPE_UINT8\ntypedef YYTYPE_UINT8 yytype_uint8;\n#else\ntypedef unsigned char yytype_uint8;\n#endif\n\n#ifdef YYTYPE_INT8\ntypedef YYTYPE_INT8 yytype_int8;\n#elif (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\ntypedef signed char yytype_int8;\n#else\ntypedef short int yytype_int8;\n#endif\n\n#ifdef YYTYPE_UINT16\ntypedef YYTYPE_UINT16 yytype_uint16;\n#else\ntypedef unsigned short int yytype_uint16;\n#endif\n\n#ifdef YYTYPE_INT16\ntypedef YYTYPE_INT16 yytype_int16;\n#else\ntypedef short int yytype_int16;\n#endif\n\n#ifndef YYSIZE_T\n# ifdef __SIZE_TYPE__\n#  define YYSIZE_T __SIZE_TYPE__\n# elif defined size_t\n#  define YYSIZE_T size_t\n# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYSIZE_T size_t\n# else\n#  define YYSIZE_T unsigned int\n# endif\n#endif\n\n#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)\n\n#ifndef YY_\n# if YYENABLE_NLS\n#  if ENABLE_NLS\n#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */\n#   define YY_(msgid) dgettext (\"bison-runtime\", msgid)\n#  endif\n# endif\n# ifndef YY_\n#  define YY_(msgid) msgid\n# endif\n#endif\n\n/* Suppress unused-variable warnings by \"using\" E.  */\n#if ! defined lint || defined __GNUC__\n# define YYUSE(e) ((void) (e))\n#else\n# define YYUSE(e) /* empty */\n#endif\n\n/* Identity function, used to suppress warnings about constant conditions.  */\n#ifndef lint\n# define YYID(n) (n)\n#else\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic int\nYYID (int yyi)\n#else\nstatic int\nYYID (yyi)\n    int yyi;\n#endif\n{\n  return yyi;\n}\n#endif\n\n#if ! defined yyoverflow || YYERROR_VERBOSE\n\n/* The parser invokes alloca or malloc; define the necessary symbols.  */\n\n# ifdef YYSTACK_USE_ALLOCA\n#  if YYSTACK_USE_ALLOCA\n#   ifdef __GNUC__\n#    define YYSTACK_ALLOC __builtin_alloca\n#   elif defined __BUILTIN_VA_ARG_INCR\n#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */\n#   elif defined _AIX\n#    define YYSTACK_ALLOC __alloca\n#   elif defined _MSC_VER\n#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */\n#    define alloca _alloca\n#   else\n#    define YYSTACK_ALLOC alloca\n#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#     ifndef _STDLIB_H\n#      define _STDLIB_H 1\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n\n# ifdef YYSTACK_ALLOC\n   /* Pacify GCC's `empty if-body' warning.  */\n#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n    /* The OS might guarantee only one guard page at the bottom of the stack,\n       and a page size can be as small as 4096 bytes.  So we cannot safely\n       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number\n       to allow for a few compiler-allocated temporary stack slots.  */\n#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */\n#  endif\n# else\n#  define YYSTACK_ALLOC YYMALLOC\n#  define YYSTACK_FREE YYFREE\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM\n#  endif\n#  if (defined __cplusplus && ! defined _STDLIB_H \\\n       && ! ((defined YYMALLOC || defined malloc) \\\n\t     && (defined YYFREE || defined free)))\n#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#   ifndef _STDLIB_H\n#    define _STDLIB_H 1\n#   endif\n#  endif\n#  ifndef YYMALLOC\n#   define YYMALLOC malloc\n#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n#  ifndef YYFREE\n#   define YYFREE free\n#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid free (void *); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n# endif\n#endif /* ! defined yyoverflow || YYERROR_VERBOSE */\n\n\n#if (! defined yyoverflow \\\n     && (! defined __cplusplus \\\n\t || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))\n\n/* A type that is properly aligned for any stack member.  */\nunion yyalloc\n{\n  yytype_int16 yyss_alloc;\n  YYSTYPE yyvs_alloc;\n};\n\n/* The size of the maximum gap between one aligned stack and the next.  */\n# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\n\n/* The size of an array large to enough to hold all stacks, each with\n   N elements.  */\n# define YYSTACK_BYTES(N) \\\n     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \\\n      + YYSTACK_GAP_MAXIMUM)\n\n/* Copy COUNT objects from FROM to TO.  The source and destination do\n   not overlap.  */\n# ifndef YYCOPY\n#  if defined __GNUC__ && 1 < __GNUC__\n#   define YYCOPY(To, From, Count) \\\n      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))\n#  else\n#   define YYCOPY(To, From, Count)\t\t\\\n      do\t\t\t\t\t\\\n\t{\t\t\t\t\t\\\n\t  YYSIZE_T yyi;\t\t\t\t\\\n\t  for (yyi = 0; yyi < (Count); yyi++)\t\\\n\t    (To)[yyi] = (From)[yyi];\t\t\\\n\t}\t\t\t\t\t\\\n      while (YYID (0))\n#  endif\n# endif\n\n/* Relocate STACK from its old location to the new one.  The\n   local variables YYSIZE and YYSTACKSIZE give the old and new number of\n   elements in the stack, and YYPTR gives the new location of the\n   stack.  Advance YYPTR to a properly aligned location for the next\n   stack.  */\n# define YYSTACK_RELOCATE(Stack_alloc, Stack)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      {\t\t\t\t\t\t\t\t\t\\\n\tYYSIZE_T yynewbytes;\t\t\t\t\t\t\\\n\tYYCOPY (&yyptr->Stack_alloc, Stack, yysize);\t\t\t\\\n\tStack = &yyptr->Stack_alloc;\t\t\t\t\t\\\n\tyynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\\n\tyyptr += yynewbytes / sizeof (*yyptr);\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n\n#endif\n\n/* YYFINAL -- State number of the termination state.  */\n#define YYFINAL  6\n/* YYLAST -- Last index in YYTABLE.  */\n#define YYLAST   100\n\n/* YYNTOKENS -- Number of terminals.  */\n#define YYNTOKENS  17\n/* YYNNTS -- Number of nonterminals.  */\n#define YYNNTS  16\n/* YYNRULES -- Number of rules.  */\n#define YYNRULES  38\n/* YYNRULES -- Number of states.  */\n#define YYNSTATES  82\n\n/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */\n#define YYUNDEFTOK  2\n#define YYMAXUTOK   263\n\n#define YYTRANSLATE(YYX)\t\t\t\t\t\t\\\n  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\n\n/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */\nstatic const yytype_uint8 yytranslate[] =\n{\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n      15,    16,     2,    14,    10,     9,    12,    11,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,    13,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8\n};\n\n#if YYDEBUG\n/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in\n   YYRHS.  */\nstatic const yytype_uint8 yyprhs[] =\n{\n       0,     0,     3,     5,    12,    20,    29,    36,    44,    53,\n      60,    68,    75,    83,    92,    94,    97,    99,   100,   102,\n     104,   106,   109,   110,   117,   121,   123,   125,   127,   130,\n     133,   135,   136,   139,   142,   143,   144,   148,   149\n};\n\n/* YYRHS -- A `-1'-separated list of the rules' RHS.  */\nstatic const yytype_int8 yyrhs[] =\n{\n      18,     0,    -1,    19,    -1,    21,     5,    22,     5,    27,\n      32,    -1,    21,     5,     9,    22,     5,    27,    32,    -1,\n      21,     5,     9,    22,     9,     5,    27,    32,    -1,    21,\n      22,     5,     5,    27,    32,    -1,    21,    22,     9,     5,\n       5,    27,    32,    -1,    21,    22,     9,     5,     9,     5,\n      27,    32,    -1,    21,     5,    22,    27,     5,    32,    -1,\n      21,     5,     9,    22,    27,     5,    32,    -1,    21,    22,\n       5,    27,     5,    32,    -1,    21,    22,     9,     5,    27,\n       5,    32,    -1,    21,     5,    23,     5,    23,     5,    27,\n      32,    -1,     7,    -1,    20,    10,    -1,    20,    -1,    -1,\n       6,    -1,     9,    -1,    11,    -1,    12,     5,    -1,    -1,\n       5,    13,     5,    13,     5,    24,    -1,     5,    13,     5,\n      -1,     3,    -1,     4,    -1,    25,    -1,    26,    25,    -1,\n      25,    26,    -1,     8,    -1,    -1,    14,     5,    -1,     9,\n       5,    -1,    -1,    -1,    15,    31,    16,    -1,    -1,    28,\n      29,    30,    -1\n};\n\n/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\nstatic const yytype_uint8 yyrline[] =\n{\n       0,    66,    66,    76,    83,    90,    97,   104,   111,   118,\n     126,   134,   141,   148,   159,   163,   164,   165,   170,   174,\n     175,   180,   181,   185,   193,   203,   204,   208,   209,   210,\n     214,   215,   219,   220,   221,   227,   227,   229,   233\n};\n#endif\n\n#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE\n/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */\nstatic const char *const yytname[] =\n{\n  \"$end\", \"error\", \"$undefined\", \"DP_AM\", \"DP_PM\", \"DP_NUMBER\",\n  \"DP_MONTH\", \"DP_WDAY\", \"DP_TZ\", \"'-'\", \"','\", \"'/'\", \"'.'\", \"':'\", \"'+'\",\n  \"'('\", \"')'\", \"$accept\", \"input\", \"date_time_string\", \"wday\",\n  \"wday_omittable\", \"month\", \"hyphen_or_slash\", \"time_sub_sec_omittable\",\n  \"time_hms\", \"am_or_pm\", \"time\", \"tz_name_omittable\",\n  \"tz_offset_omittable\", \"tz_desc_omittable\", \"$@1\", \"tz_omittable\", 0\n};\n#endif\n\n# ifdef YYPRINT\n/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to\n   token YYLEX-NUM.  */\nstatic const yytype_uint16 yytoknum[] =\n{\n       0,   256,   257,   258,   259,   260,   261,   262,   263,    45,\n      44,    47,    46,    58,    43,    40,    41\n};\n# endif\n\n/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\nstatic const yytype_uint8 yyr1[] =\n{\n       0,    17,    18,    19,    19,    19,    19,    19,    19,    19,\n      19,    19,    19,    19,    20,    21,    21,    21,    22,    23,\n      23,    24,    24,    25,    25,    26,    26,    27,    27,    27,\n      28,    28,    29,    29,    29,    31,    30,    30,    32\n};\n\n/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */\nstatic const yytype_uint8 yyr2[] =\n{\n       0,     2,     1,     6,     7,     8,     6,     7,     8,     6,\n       7,     6,     7,     8,     1,     2,     1,     0,     1,     1,\n       1,     2,     0,     6,     3,     1,     1,     1,     2,     2,\n       1,     0,     2,     2,     0,     0,     3,     0,     3\n};\n\n/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state\n   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero\n   means the default is an error.  */\nstatic const yytype_uint8 yydefact[] =\n{\n      17,    14,     0,     2,    16,     0,     1,    15,     0,    18,\n       0,    19,    20,     0,     0,     0,     0,     0,    25,    26,\n       0,    27,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,    31,    29,    28,    31,    19,     0,    31,\n      31,     0,     0,     0,    31,     0,    31,    24,    30,    34,\n       3,     9,     0,     6,    11,    31,     0,    31,     4,    31,\n      10,     0,     0,     0,    37,    31,     7,    31,    12,     5,\n      22,    33,    32,    35,    38,    13,     8,     0,    23,     0,\n      21,    36\n};\n\n/* YYDEFGOTO[NTERM-NUM].  */\nstatic const yytype_int8 yydefgoto[] =\n{\n      -1,     2,     3,     4,     5,    10,    14,    78,    21,    22,\n      23,    49,    64,    74,    79,    50\n};\n\n/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n   STATE-NUM.  */\n#define YYPACT_NINF -22\nstatic const yytype_int8 yypact[] =\n{\n       4,   -22,    14,   -22,    22,    34,   -22,   -22,    11,   -22,\n      26,    55,   -22,    47,    40,    51,    57,    24,   -22,   -22,\n       3,    39,    58,    59,    -8,     3,    60,    44,     3,    61,\n      62,    56,    63,    52,   -22,   -22,    52,   -22,    65,    52,\n      52,     3,    66,    67,    52,    54,    52,    64,   -22,    -5,\n     -22,   -22,    54,   -22,   -22,    52,    54,    52,   -22,    52,\n     -22,    68,    69,    70,    71,    52,   -22,    52,   -22,   -22,\n      72,   -22,   -22,   -22,   -22,   -22,   -22,    73,   -22,    74,\n     -22,   -22\n};\n\n/* YYPGOTO[NTERM-NUM].  */\nstatic const yytype_int8 yypgoto[] =\n{\n     -22,   -22,   -22,   -22,   -22,    13,    75,   -22,    76,    79,\n     -15,   -22,   -22,   -22,   -22,   -21\n};\n\n/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If\n   positive, shift that token.  If negative, reduce the rule which\n   number is the opposite.  If zero, do what YYDEFACT says.\n   If YYTABLE_NINF, syntax error.  */\n#define YYTABLE_NINF -1\nstatic const yytype_uint8 yytable[] =\n{\n      26,    37,    30,    12,    62,    33,    18,    19,    31,    63,\n      39,     1,    43,    44,     6,    51,    32,     9,    53,    54,\n      11,    13,    12,    58,    17,    60,    55,    18,    19,    28,\n      59,    15,     7,    29,    66,    16,    68,    65,    69,     8,\n       9,    67,    18,    19,    75,    24,    76,    18,    19,    41,\n      18,    19,    20,    42,    18,    19,    25,    18,    19,    31,\n      48,     9,    27,    31,    36,    40,    45,    46,    47,    32,\n      52,    56,    57,    70,    71,    72,     0,    61,    80,     0,\n       0,     0,     0,     0,    77,     0,    73,     0,     0,     0,\n      81,     0,     0,     0,     0,     0,     0,     0,    35,    38,\n      34\n};\n\nstatic const yytype_int8 yycheck[] =\n{\n      15,     9,    17,    11,     9,    20,     3,     4,     5,    14,\n      25,     7,    27,    28,     0,    36,    13,     6,    39,    40,\n       9,     8,    11,    44,    11,    46,    41,     3,     4,     5,\n      45,     5,    10,     9,    55,     9,    57,    52,    59,     5,\n       6,    56,     3,     4,    65,     5,    67,     3,     4,     5,\n       3,     4,     5,     9,     3,     4,     5,     3,     4,     5,\n       8,     6,     5,     5,     5,     5,     5,     5,     5,    13,\n       5,     5,     5,     5,     5,     5,    -1,    13,     5,    -1,\n      -1,    -1,    -1,    -1,    12,    -1,    15,    -1,    -1,    -1,\n      16,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    22,    24,\n      21\n};\n\n/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\n   symbol of state STATE-NUM.  */\nstatic const yytype_uint8 yystos[] =\n{\n       0,     7,    18,    19,    20,    21,     0,    10,     5,     6,\n      22,     9,    11,    22,    23,     5,     9,    22,     3,     4,\n       5,    25,    26,    27,     5,     5,    27,     5,     5,     9,\n      27,     5,    13,    27,    26,    25,     5,     9,    23,    27,\n       5,     5,     9,    27,    27,     5,     5,     5,     8,    28,\n      32,    32,     5,    32,    32,    27,     5,     5,    32,    27,\n      32,    13,     9,    14,    29,    27,    32,    27,    32,    32,\n       5,     5,     5,    15,    30,    32,    32,    12,    24,    31,\n       5,    16\n};\n\n#define yyerrok\t\t(yyerrstatus = 0)\n#define yyclearin\t(yychar = YYEMPTY)\n#define YYEMPTY\t\t(-2)\n#define YYEOF\t\t0\n\n#define YYACCEPT\tgoto yyacceptlab\n#define YYABORT\t\tgoto yyabortlab\n#define YYERROR\t\tgoto yyerrorlab\n\n\n/* Like YYERROR except do call yyerror.  This remains here temporarily\n   to ease the transition to the new meaning of YYERROR, for GCC.\n   Once GCC version 2 has supplanted version 1, this can go.  */\n\n#define YYFAIL\t\tgoto yyerrlab\n\n#define YYRECOVERING()  (!!yyerrstatus)\n\n#define YYBACKUP(Token, Value)\t\t\t\t\t\\\ndo\t\t\t\t\t\t\t\t\\\n  if (yychar == YYEMPTY && yylen == 1)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yychar = (Token);\t\t\t\t\t\t\\\n      yylval = (Value);\t\t\t\t\t\t\\\n      yytoken = YYTRANSLATE (yychar);\t\t\t\t\\\n      YYPOPSTACK (1);\t\t\t\t\t\t\\\n      goto yybackup;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n  else\t\t\t\t\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yyerror (YY_(\"syntax error: cannot back up\")); \\\n      YYERROR;\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\nwhile (YYID (0))\n\n\n#define YYTERROR\t1\n#define YYERRCODE\t256\n\n\n/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\n   If N is 0, then set CURRENT to the empty location which ends\n   the previous symbol: RHS[0] (always defined).  */\n\n#define YYRHSLOC(Rhs, K) ((Rhs)[K])\n#ifndef YYLLOC_DEFAULT\n# define YYLLOC_DEFAULT(Current, Rhs, N)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      if (YYID (N))                                                    \\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;\t\\\n\t  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;\t\\\n\t  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;\t\t\\\n\t  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;\t\\\n\t}\t\t\t\t\t\t\t\t\\\n      else\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = (Current).last_line   =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_line;\t\t\t\t\\\n\t  (Current).first_column = (Current).last_column =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_column;\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n#endif\n\n\n/* YY_LOCATION_PRINT -- Print the location on the stream.\n   This macro was not mandated originally: define only if we know\n   we won't break user code: when these are the locations we know.  */\n\n#ifndef YY_LOCATION_PRINT\n# if YYLTYPE_IS_TRIVIAL\n#  define YY_LOCATION_PRINT(File, Loc)\t\t\t\\\n     fprintf (File, \"%d.%d-%d.%d\",\t\t\t\\\n\t      (Loc).first_line, (Loc).first_column,\t\\\n\t      (Loc).last_line,  (Loc).last_column)\n# else\n#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)\n# endif\n#endif\n\n\n/* YYLEX -- calling `yylex' with the right arguments.  */\n\n#ifdef YYLEX_PARAM\n# define YYLEX yylex (&yylval, YYLEX_PARAM)\n#else\n# define YYLEX yylex (&yylval)\n#endif\n\n/* Enable debugging if requested.  */\n#if YYDEBUG\n\n# ifndef YYFPRINTF\n#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYFPRINTF fprintf\n# endif\n\n# define YYDPRINTF(Args)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\\\n    YYFPRINTF Args;\t\t\t\t\\\n} while (YYID (0))\n\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\t\t\t  \\\ndo {\t\t\t\t\t\t\t\t\t  \\\n  if (yydebug)\t\t\t\t\t\t\t\t  \\\n    {\t\t\t\t\t\t\t\t\t  \\\n      YYFPRINTF (stderr, \"%s \", Title);\t\t\t\t\t  \\\n      yy_symbol_print (stderr,\t\t\t\t\t\t  \\\n\t\t  Type, Value); \\\n      YYFPRINTF (stderr, \"\\n\");\t\t\t\t\t\t  \\\n    }\t\t\t\t\t\t\t\t\t  \\\n} while (YYID (0))\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_value_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (!yyvaluep)\n    return;\n# ifdef YYPRINT\n  if (yytype < YYNTOKENS)\n    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\n# else\n  YYUSE (yyoutput);\n# endif\n  switch (yytype)\n    {\n      default:\n\tbreak;\n    }\n}\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (yytype < YYNTOKENS)\n    YYFPRINTF (yyoutput, \"token %s (\", yytname[yytype]);\n  else\n    YYFPRINTF (yyoutput, \"nterm %s (\", yytname[yytype]);\n\n  yy_symbol_value_print (yyoutput, yytype, yyvaluep);\n  YYFPRINTF (yyoutput, \")\");\n}\n\n/*------------------------------------------------------------------.\n| yy_stack_print -- Print the state stack from its BOTTOM up to its |\n| TOP (included).                                                   |\n`------------------------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)\n#else\nstatic void\nyy_stack_print (yybottom, yytop)\n    yytype_int16 *yybottom;\n    yytype_int16 *yytop;\n#endif\n{\n  YYFPRINTF (stderr, \"Stack now\");\n  for (; yybottom <= yytop; yybottom++)\n    {\n      int yybot = *yybottom;\n      YYFPRINTF (stderr, \" %d\", yybot);\n    }\n  YYFPRINTF (stderr, \"\\n\");\n}\n\n# define YY_STACK_PRINT(Bottom, Top)\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\t\t\\\n    yy_stack_print ((Bottom), (Top));\t\t\t\t\\\n} while (YYID (0))\n\n\n/*------------------------------------------------.\n| Report that the YYRULE is going to be reduced.  |\n`------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_reduce_print (YYSTYPE *yyvsp, int yyrule)\n#else\nstatic void\nyy_reduce_print (yyvsp, yyrule)\n    YYSTYPE *yyvsp;\n    int yyrule;\n#endif\n{\n  int yynrhs = yyr2[yyrule];\n  int yyi;\n  unsigned long int yylno = yyrline[yyrule];\n  YYFPRINTF (stderr, \"Reducing stack by rule %d (line %lu):\\n\",\n\t     yyrule - 1, yylno);\n  /* The symbols being reduced.  */\n  for (yyi = 0; yyi < yynrhs; yyi++)\n    {\n      YYFPRINTF (stderr, \"   $%d = \", yyi + 1);\n      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],\n\t\t       &(yyvsp[(yyi + 1) - (yynrhs)])\n\t\t       \t\t       );\n      YYFPRINTF (stderr, \"\\n\");\n    }\n}\n\n# define YY_REDUCE_PRINT(Rule)\t\t\\\ndo {\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\\\n    yy_reduce_print (yyvsp, Rule); \\\n} while (YYID (0))\n\n/* Nonzero means print parse trace.  It is left uninitialized so that\n   multiple parsers can coexist.  */\nint yydebug;\n#else /* !YYDEBUG */\n# define YYDPRINTF(Args)\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\n# define YY_STACK_PRINT(Bottom, Top)\n# define YY_REDUCE_PRINT(Rule)\n#endif /* !YYDEBUG */\n\n\n/* YYINITDEPTH -- initial size of the parser's stacks.  */\n#ifndef\tYYINITDEPTH\n# define YYINITDEPTH 200\n#endif\n\n/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\n   if the built-in stack extension method is used).\n\n   Do not make this value too large; the results are undefined if\n   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)\n   evaluated with infinite-precision integer arithmetic.  */\n\n#ifndef YYMAXDEPTH\n# define YYMAXDEPTH 10000\n#endif\n\n\f\n\n#if YYERROR_VERBOSE\n\n# ifndef yystrlen\n#  if defined __GLIBC__ && defined _STRING_H\n#   define yystrlen strlen\n#  else\n/* Return the length of YYSTR.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic YYSIZE_T\nyystrlen (const char *yystr)\n#else\nstatic YYSIZE_T\nyystrlen (yystr)\n    const char *yystr;\n#endif\n{\n  YYSIZE_T yylen;\n  for (yylen = 0; yystr[yylen]; yylen++)\n    continue;\n  return yylen;\n}\n#  endif\n# endif\n\n# ifndef yystpcpy\n#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE\n#   define yystpcpy stpcpy\n#  else\n/* Copy YYSRC to YYDEST, returning the address of the terminating '\\0' in\n   YYDEST.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic char *\nyystpcpy (char *yydest, const char *yysrc)\n#else\nstatic char *\nyystpcpy (yydest, yysrc)\n    char *yydest;\n    const char *yysrc;\n#endif\n{\n  char *yyd = yydest;\n  const char *yys = yysrc;\n\n  while ((*yyd++ = *yys++) != '\\0')\n    continue;\n\n  return yyd - 1;\n}\n#  endif\n# endif\n\n# ifndef yytnamerr\n/* Copy to YYRES the contents of YYSTR after stripping away unnecessary\n   quotes and backslashes, so that it's suitable for yyerror.  The\n   heuristic is that double-quoting is unnecessary unless the string\n   contains an apostrophe, a comma, or backslash (other than\n   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is\n   null, do not copy; instead, return the length of what the result\n   would have been.  */\nstatic YYSIZE_T\nyytnamerr (char *yyres, const char *yystr)\n{\n  if (*yystr == '\"')\n    {\n      YYSIZE_T yyn = 0;\n      char const *yyp = yystr;\n\n      for (;;)\n\tswitch (*++yyp)\n\t  {\n\t  case '\\'':\n\t  case ',':\n\t    goto do_not_strip_quotes;\n\n\t  case '\\\\':\n\t    if (*++yyp != '\\\\')\n\t      goto do_not_strip_quotes;\n\t    /* Fall through.  */\n\t  default:\n\t    if (yyres)\n\t      yyres[yyn] = *yyp;\n\t    yyn++;\n\t    break;\n\n\t  case '\"':\n\t    if (yyres)\n\t      yyres[yyn] = '\\0';\n\t    return yyn;\n\t  }\n    do_not_strip_quotes: ;\n    }\n\n  if (! yyres)\n    return yystrlen (yystr);\n\n  return yystpcpy (yyres, yystr) - yyres;\n}\n# endif\n\n/* Copy into YYRESULT an error message about the unexpected token\n   YYCHAR while in state YYSTATE.  Return the number of bytes copied,\n   including the terminating null byte.  If YYRESULT is null, do not\n   copy anything; just return the number of bytes that would be\n   copied.  As a special case, return 0 if an ordinary \"syntax error\"\n   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during\n   size calculation.  */\nstatic YYSIZE_T\nyysyntax_error (char *yyresult, int yystate, int yychar)\n{\n  int yyn = yypact[yystate];\n\n  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))\n    return 0;\n  else\n    {\n      int yytype = YYTRANSLATE (yychar);\n      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);\n      YYSIZE_T yysize = yysize0;\n      YYSIZE_T yysize1;\n      int yysize_overflow = 0;\n      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };\n      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];\n      int yyx;\n\n# if 0\n      /* This is so xgettext sees the translatable formats that are\n\t constructed on the fly.  */\n      YY_(\"syntax error, unexpected %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s or %s\");\n# endif\n      char *yyfmt;\n      char const *yyf;\n      static char const yyunexpected[] = \"syntax error, unexpected %s\";\n      static char const yyexpecting[] = \", expecting %s\";\n      static char const yyor[] = \" or %s\";\n      char yyformat[sizeof yyunexpected\n\t\t    + sizeof yyexpecting - 1\n\t\t    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)\n\t\t       * (sizeof yyor - 1))];\n      char const *yyprefix = yyexpecting;\n\n      /* Start YYX at -YYN if negative to avoid negative indexes in\n\t YYCHECK.  */\n      int yyxbegin = yyn < 0 ? -yyn : 0;\n\n      /* Stay within bounds of both yycheck and yytname.  */\n      int yychecklim = YYLAST - yyn + 1;\n      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n      int yycount = 1;\n\n      yyarg[0] = yytname[yytype];\n      yyfmt = yystpcpy (yyformat, yyunexpected);\n\n      for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n\tif (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\n\t  {\n\t    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)\n\t      {\n\t\tyycount = 1;\n\t\tyysize = yysize0;\n\t\tyyformat[sizeof yyunexpected - 1] = '\\0';\n\t\tbreak;\n\t      }\n\t    yyarg[yycount++] = yytname[yyx];\n\t    yysize1 = yysize + yytnamerr (0, yytname[yyx]);\n\t    yysize_overflow |= (yysize1 < yysize);\n\t    yysize = yysize1;\n\t    yyfmt = yystpcpy (yyfmt, yyprefix);\n\t    yyprefix = yyor;\n\t  }\n\n      yyf = YY_(yyformat);\n      yysize1 = yysize + yystrlen (yyf);\n      yysize_overflow |= (yysize1 < yysize);\n      yysize = yysize1;\n\n      if (yysize_overflow)\n\treturn YYSIZE_MAXIMUM;\n\n      if (yyresult)\n\t{\n\t  /* Avoid sprintf, as that infringes on the user's name space.\n\t     Don't have undefined behavior even if the translation\n\t     produced a string with the wrong number of \"%s\"s.  */\n\t  char *yyp = yyresult;\n\t  int yyi = 0;\n\t  while ((*yyp = *yyf) != '\\0')\n\t    {\n\t      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)\n\t\t{\n\t\t  yyp += yytnamerr (yyp, yyarg[yyi++]);\n\t\t  yyf += 2;\n\t\t}\n\t      else\n\t\t{\n\t\t  yyp++;\n\t\t  yyf++;\n\t\t}\n\t    }\n\t}\n      return yysize;\n    }\n}\n#endif /* YYERROR_VERBOSE */\n\f\n\n/*-----------------------------------------------.\n| Release the memory associated to this symbol.  |\n`-----------------------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)\n#else\nstatic void\nyydestruct (yymsg, yytype, yyvaluep)\n    const char *yymsg;\n    int yytype;\n    YYSTYPE *yyvaluep;\n#endif\n{\n  YYUSE (yyvaluep);\n\n  if (!yymsg)\n    yymsg = \"Deleting\";\n  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);\n\n  /*switch (yytype)\n    {\n\n      default:\n\tbreak;\n    }*/\n}\n\n/* Prevent warnings from -Wmissing-prototypes.  */\n#ifdef YYPARSE_PARAM\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void *YYPARSE_PARAM);\n#else\nint yyparse ();\n#endif\n#else /* ! YYPARSE_PARAM */\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void);\n#else\nint yyparse ();\n#endif\n#endif /* ! YYPARSE_PARAM */\n\n\n\n\n\n/*-------------------------.\n| yyparse or yypush_parse.  |\n`-------------------------*/\n\n#ifdef YYPARSE_PARAM\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void *YYPARSE_PARAM)\n#else\nint\nyyparse (YYPARSE_PARAM)\n    void *YYPARSE_PARAM;\n#endif\n#else /* ! YYPARSE_PARAM */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void)\n#else\nint\nyyparse ()\n\n#endif\n#endif\n{\n/* The lookahead symbol.  */\nint yychar;\n\n/* The semantic value of the lookahead symbol.  */\nYYSTYPE yylval;\n\n    /* Number of syntax errors so far.  */\n    int yynerrs;\n\n    int yystate;\n    /* Number of tokens to shift before error messages enabled.  */\n    int yyerrstatus;\n\n    /* The stacks and their tools:\n       `yyss': related to states.\n       `yyvs': related to semantic values.\n\n       Refer to the stacks thru separate pointers, to allow yyoverflow\n       to reallocate them elsewhere.  */\n\n    /* The state stack.  */\n    yytype_int16 yyssa[YYINITDEPTH];\n    yytype_int16 *yyss;\n    yytype_int16 *yyssp;\n\n    /* The semantic value stack.  */\n    YYSTYPE yyvsa[YYINITDEPTH];\n    YYSTYPE *yyvs;\n    YYSTYPE *yyvsp;\n\n    YYSIZE_T yystacksize;\n\n  int yyn;\n  int yyresult;\n  /* Lookahead token as an internal (translated) token number.  */\n  int yytoken;\n  /* The variables used to return semantic value and location from the\n     action routines.  */\n  YYSTYPE yyval;\n\n#if YYERROR_VERBOSE\n  /* Buffer for error messages, and its allocated size.  */\n  char yymsgbuf[128];\n  char *yymsg = yymsgbuf;\n  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;\n#endif\n\n#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))\n\n  /* The number of symbols on the RHS of the reduced rule.\n     Keep to zero when no symbol should be popped.  */\n  int yylen = 0;\n\n  yytoken = 0;\n  yyss = yyssa;\n  yyvs = yyvsa;\n  yystacksize = YYINITDEPTH;\n\n  YYDPRINTF ((stderr, \"Starting parse\\n\"));\n\n  yystate = 0;\n  yyerrstatus = 0;\n  yynerrs = 0;\n  yychar = YYEMPTY; /* Cause a token to be read.  */\n\n  /* Initialize stack pointers.\n     Waste one element of value and location stack\n     so that they stay on the same level as the state stack.\n     The wasted elements are never initialized.  */\n  yyssp = yyss;\n  yyvsp = yyvs;\n\n  goto yysetstate;\n\n/*------------------------------------------------------------.\n| yynewstate -- Push a new state, which is found in yystate.  |\n`------------------------------------------------------------*/\n yynewstate:\n  /* In all cases, when you get here, the value and location stacks\n     have just been pushed.  So pushing a state here evens the stacks.  */\n  yyssp++;\n\n yysetstate:\n  *yyssp = yystate;\n\n  if (yyss + yystacksize - 1 <= yyssp)\n    {\n      /* Get the current used size of the three stacks, in elements.  */\n      YYSIZE_T yysize = yyssp - yyss + 1;\n\n#ifdef yyoverflow\n      {\n\t/* Give user a chance to reallocate the stack.  Use copies of\n\t   these so that the &'s don't force the real ones into\n\t   memory.  */\n\tYYSTYPE *yyvs1 = yyvs;\n\tyytype_int16 *yyss1 = yyss;\n\n\t/* Each stack pointer address is followed by the size of the\n\t   data in use in that stack, in bytes.  This used to be a\n\t   conditional around just the two extra args, but that might\n\t   be undefined if yyoverflow is a macro.  */\n\tyyoverflow (YY_(\"memory exhausted\"),\n\t\t    &yyss1, yysize * sizeof (*yyssp),\n\t\t    &yyvs1, yysize * sizeof (*yyvsp),\n\t\t    &yystacksize);\n\n\tyyss = yyss1;\n\tyyvs = yyvs1;\n      }\n#else /* no yyoverflow */\n# ifndef YYSTACK_RELOCATE\n      goto yyexhaustedlab;\n# else\n      /* Extend the stack our own way.  */\n      if (YYMAXDEPTH <= yystacksize)\n\tgoto yyexhaustedlab;\n      yystacksize *= 2;\n      if (YYMAXDEPTH < yystacksize)\n\tyystacksize = YYMAXDEPTH;\n\n      {\n\tyytype_int16 *yyss1 = yyss;\n\tunion yyalloc *yyptr =\n\t  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\n\tif (! yyptr)\n\t  goto yyexhaustedlab;\n\tYYSTACK_RELOCATE (yyss_alloc, yyss);\n\tYYSTACK_RELOCATE (yyvs_alloc, yyvs);\n#  undef YYSTACK_RELOCATE\n\tif (yyss1 != yyssa)\n\t  YYSTACK_FREE (yyss1);\n      }\n# endif\n#endif /* no yyoverflow */\n\n      yyssp = yyss + yysize - 1;\n      yyvsp = yyvs + yysize - 1;\n\n      YYDPRINTF ((stderr, \"Stack size increased to %lu\\n\",\n\t\t  (unsigned long int) yystacksize));\n\n      if (yyss + yystacksize - 1 <= yyssp)\n\tYYABORT;\n    }\n\n  YYDPRINTF ((stderr, \"Entering state %d\\n\", yystate));\n\n  if (yystate == YYFINAL)\n    YYACCEPT;\n\n  goto yybackup;\n\n/*-----------.\n| yybackup.  |\n`-----------*/\nyybackup:\n\n  /* Do appropriate processing given the current state.  Read a\n     lookahead token if we need one and don't already have one.  */\n\n  /* First try to decide what to do without reference to lookahead token.  */\n  yyn = yypact[yystate];\n  if (yyn == YYPACT_NINF)\n    goto yydefault;\n\n  /* Not known => get a lookahead token if don't already have one.  */\n\n  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\n  if (yychar == YYEMPTY)\n    {\n      YYDPRINTF ((stderr, \"Reading a token: \"));\n      yychar = YYLEX;\n    }\n\n  if (yychar <= YYEOF)\n    {\n      yychar = yytoken = YYEOF;\n      YYDPRINTF ((stderr, \"Now at end of input.\\n\"));\n    }\n  else\n    {\n      yytoken = YYTRANSLATE (yychar);\n      YY_SYMBOL_PRINT (\"Next token is\", yytoken, &yylval, &yylloc);\n    }\n\n  /* If the proper action on seeing token YYTOKEN is to reduce or to\n     detect an error, take that action.  */\n  yyn += yytoken;\n  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\n    goto yydefault;\n  yyn = yytable[yyn];\n  if (yyn <= 0)\n    {\n      if (yyn == 0 || yyn == YYTABLE_NINF)\n\tgoto yyerrlab;\n      yyn = -yyn;\n      goto yyreduce;\n    }\n\n  /* Count tokens shifted since error; after three, turn off error\n     status.  */\n  if (yyerrstatus)\n    yyerrstatus--;\n\n  /* Shift the lookahead token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yytoken, &yylval, &yylloc);\n\n  /* Discard the shifted token.  */\n  yychar = YYEMPTY;\n\n  yystate = yyn;\n  *++yyvsp = yylval;\n\n  goto yynewstate;\n\n\n/*-----------------------------------------------------------.\n| yydefault -- do the default action for the current state.  |\n`-----------------------------------------------------------*/\nyydefault:\n  yyn = yydefact[yystate];\n  if (yyn == 0)\n    goto yyerrlab;\n  goto yyreduce;\n\n\n/*-----------------------------.\n| yyreduce -- Do a reduction.  |\n`-----------------------------*/\nyyreduce:\n  /* yyn is the number of a rule to reduce with.  */\n  yylen = yyr2[yyn];\n\n  /* If YYLEN is nonzero, implement the default value of the action:\n     `$$ = $1'.\n\n     Otherwise, the following line sets YYVAL to garbage.\n     This behavior is undocumented and Bison\n     users should not rely upon it.  Assigning to YYVAL\n     unconditionally makes the parser a bit smaller, and it avoids a\n     GCC warning that YYVAL may be used uninitialized.  */\n  yyval = yyvsp[1-yylen];\n\n\n  YY_REDUCE_PRINT (yyn);\n  switch (yyn)\n    {\n        case 3:\n\n/* Line 1455 of yacc.c  */\n#line 80 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(2) - (6)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(4) - (6)].val)); ;}\n    break;\n\n  case 4:\n\n/* Line 1455 of yacc.c  */\n#line 87 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(2) - (7)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(5) - (7)].val)); ;}\n    break;\n\n  case 5:\n\n/* Line 1455 of yacc.c  */\n#line 94 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(2) - (8)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(6) - (8)].val)); ;}\n    break;\n\n  case 6:\n\n/* Line 1455 of yacc.c  */\n#line 101 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(3) - (6)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(4) - (6)].val)); ;}\n    break;\n\n  case 7:\n\n/* Line 1455 of yacc.c  */\n#line 108 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(4) - (7)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(5) - (7)].val)); ;}\n    break;\n\n  case 8:\n\n/* Line 1455 of yacc.c  */\n#line 115 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(4) - (8)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(6) - (8)].val)); ;}\n    break;\n\n  case 9:\n\n/* Line 1455 of yacc.c  */\n#line 123 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(2) - (6)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(5) - (6)].val)); ;}\n    break;\n\n  case 10:\n\n/* Line 1455 of yacc.c  */\n#line 131 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(2) - (7)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(6) - (7)].val)); ;}\n    break;\n\n  case 11:\n\n/* Line 1455 of yacc.c  */\n#line 138 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(3) - (6)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(5) - (6)].val)); ;}\n    break;\n\n  case 12:\n\n/* Line 1455 of yacc.c  */\n#line 145 \"tjsdate.y\"\n    {\tdp->SetMDay((yyvsp[(4) - (7)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(6) - (7)].val)); ;}\n    break;\n\n  case 13:\n\n/* Line 1455 of yacc.c  */\n#line 153 \"tjsdate.y\"\n    {\tdp->SetMonth((yyvsp[(4) - (8)].val)-1);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetYear((yyvsp[(2) - (8)].val));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdp->SetMDay((yyvsp[(6) - (8)].val)); ;}\n    break;\n\n  case 18:\n\n/* Line 1455 of yacc.c  */\n#line 170 \"tjsdate.y\"\n    { dp->SetMonth((yyvsp[(1) - (1)].val)); ;}\n    break;\n\n  case 21:\n\n/* Line 1455 of yacc.c  */\n#line 180 \"tjsdate.y\"\n    { /* TODO: sub-seconds support */ ;}\n    break;\n\n  case 23:\n\n/* Line 1455 of yacc.c  */\n#line 188 \"tjsdate.y\"\n    {\n\t\t\tdp->SetHours((yyvsp[(1) - (6)].val));\n\t\t\tdp->SetMin((yyvsp[(3) - (6)].val));\n\t\t\tdp->SetSec((yyvsp[(5) - (6)].val));\n\t\t;}\n    break;\n\n  case 24:\n\n/* Line 1455 of yacc.c  */\n#line 195 \"tjsdate.y\"\n    {\n\t\t\tdp->SetHours((yyvsp[(1) - (3)].val));\n\t\t\tdp->SetMin((yyvsp[(3) - (3)].val));\n\t\t\tdp->SetSec(0);\n\t\t;}\n    break;\n\n  case 25:\n\n/* Line 1455 of yacc.c  */\n#line 203 \"tjsdate.y\"\n    { dp->SetAMPM(false); ;}\n    break;\n\n  case 26:\n\n/* Line 1455 of yacc.c  */\n#line 204 \"tjsdate.y\"\n    { dp->SetAMPM(true); ;}\n    break;\n\n  case 30:\n\n/* Line 1455 of yacc.c  */\n#line 214 \"tjsdate.y\"\n    { dp->SetTimeZone((yyvsp[(1) - (1)].val)); ;}\n    break;\n\n  case 32:\n\n/* Line 1455 of yacc.c  */\n#line 219 \"tjsdate.y\"\n    { dp->SetTimeZoneOffset((yyvsp[(2) - (2)].val)); ;}\n    break;\n\n  case 33:\n\n/* Line 1455 of yacc.c  */\n#line 220 \"tjsdate.y\"\n    { dp->SetTimeZoneOffset(-(yyvsp[(2) - (2)].val)); ;}\n    break;\n\n  case 35:\n\n/* Line 1455 of yacc.c  */\n#line 227 \"tjsdate.y\"\n    { dp->SkipToRightParenthesis(); ;}\n    break;\n\n\n\n/* Line 1455 of yacc.c  */\n#line 1607 \"tjsdate.tab.cpp\"\n      default: break;\n    }\n  YY_SYMBOL_PRINT (\"-> $$ =\", yyr1[yyn], &yyval, &yyloc);\n\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n\n  *++yyvsp = yyval;\n\n  /* Now `shift' the result of the reduction.  Determine what state\n     that goes to, based on the state we popped back to and the rule\n     number reduced by.  */\n\n  yyn = yyr1[yyn];\n\n  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\n  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\n    yystate = yytable[yystate];\n  else\n    yystate = yydefgoto[yyn - YYNTOKENS];\n\n  goto yynewstate;\n\n\n/*------------------------------------.\n| yyerrlab -- here on detecting error |\n`------------------------------------*/\nyyerrlab:\n  /* If not already recovering from an error, report this error.  */\n  if (!yyerrstatus)\n    {\n      ++yynerrs;\n#if ! YYERROR_VERBOSE\n      yyerror (YY_(\"syntax error\"));\n#else\n      {\n\tYYSIZE_T yysize = yysyntax_error (0, yystate, yychar);\n\tif (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)\n\t  {\n\t    YYSIZE_T yyalloc = 2 * yysize;\n\t    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))\n\t      yyalloc = YYSTACK_ALLOC_MAXIMUM;\n\t    if (yymsg != yymsgbuf)\n\t      YYSTACK_FREE (yymsg);\n\t    yymsg = (char *) YYSTACK_ALLOC (yyalloc);\n\t    if (yymsg)\n\t      yymsg_alloc = yyalloc;\n\t    else\n\t      {\n\t\tyymsg = yymsgbuf;\n\t\tyymsg_alloc = sizeof yymsgbuf;\n\t      }\n\t  }\n\n\tif (0 < yysize && yysize <= yymsg_alloc)\n\t  {\n\t    (void) yysyntax_error (yymsg, yystate, yychar);\n\t    yyerror (yymsg);\n\t  }\n\telse\n\t  {\n\t    yyerror (YY_(\"syntax error\"));\n\t    if (yysize != 0)\n\t      goto yyexhaustedlab;\n\t  }\n      }\n#endif\n    }\n\n\n\n  if (yyerrstatus == 3)\n    {\n      /* If just tried and failed to reuse lookahead token after an\n\t error, discard it.  */\n\n      if (yychar <= YYEOF)\n\t{\n\t  /* Return failure if at end of input.  */\n\t  if (yychar == YYEOF)\n\t    YYABORT;\n\t}\n      else\n\t{\n\t  yydestruct (\"Error: discarding\",\n\t\t      yytoken, &yylval);\n\t  yychar = YYEMPTY;\n\t}\n    }\n\n  /* Else will try to reuse lookahead token after shifting the error\n     token.  */\n  goto yyerrlab1;\n\n\n/*---------------------------------------------------.\n| yyerrorlab -- error raised explicitly by YYERROR.  |\n`---------------------------------------------------*/\nyyerrorlab:\n\n  /* Pacify compilers like GCC when the user code never invokes\n     YYERROR and the label yyerrorlab therefore never appears in user\n     code.  */\n  if (/*CONSTCOND*/ 0)\n     goto yyerrorlab;\n\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYERROR.  */\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n  yystate = *yyssp;\n  goto yyerrlab1;\n\n\n/*-------------------------------------------------------------.\n| yyerrlab1 -- common code for both syntax error and YYERROR.  |\n`-------------------------------------------------------------*/\nyyerrlab1:\n  yyerrstatus = 3;\t/* Each real token shifted decrements this.  */\n\n  for (;;)\n    {\n      yyn = yypact[yystate];\n      if (yyn != YYPACT_NINF)\n\t{\n\t  yyn += YYTERROR;\n\t  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\n\t    {\n\t      yyn = yytable[yyn];\n\t      if (0 < yyn)\n\t\tbreak;\n\t    }\n\t}\n\n      /* Pop the current state because it cannot handle the error token.  */\n      if (yyssp == yyss)\n\tYYABORT;\n\n\n      yydestruct (\"Error: popping\",\n\t\t  yystos[yystate], yyvsp);\n      YYPOPSTACK (1);\n      yystate = *yyssp;\n      YY_STACK_PRINT (yyss, yyssp);\n    }\n\n  *++yyvsp = yylval;\n\n\n  /* Shift the error token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yystos[yyn], yyvsp, yylsp);\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-------------------------------------.\n| yyacceptlab -- YYACCEPT comes here.  |\n`-------------------------------------*/\nyyacceptlab:\n  yyresult = 0;\n  goto yyreturn;\n\n/*-----------------------------------.\n| yyabortlab -- YYABORT comes here.  |\n`-----------------------------------*/\nyyabortlab:\n  yyresult = 1;\n  goto yyreturn;\n\n#if !defined(yyoverflow) || YYERROR_VERBOSE\n/*-------------------------------------------------.\n| yyexhaustedlab -- memory exhaustion comes here.  |\n`-------------------------------------------------*/\nyyexhaustedlab:\n  yyerror (YY_(\"memory exhausted\"));\n  yyresult = 2;\n  /* Fall through.  */\n#endif\n\nyyreturn:\n  if (yychar != YYEMPTY)\n     yydestruct (\"Cleanup: discarding lookahead\",\n\t\t yytoken, &yylval);\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYABORT or YYACCEPT.  */\n  YYPOPSTACK (yylen);\n  YY_STACK_PRINT (yyss, yyssp);\n  while (yyssp != yyss)\n    {\n      yydestruct (\"Cleanup: popping\",\n\t\t  yystos[*yyssp], yyvsp);\n      YYPOPSTACK (1);\n    }\n#ifndef yyoverflow\n  if (yyss != yyssa)\n    YYSTACK_FREE (yyss);\n#endif\n#if YYERROR_VERBOSE\n  if (yymsg != yymsgbuf)\n    YYSTACK_FREE (yymsg);\n#endif\n  /* Make sure YYID is used.  */\n  return YYID (yyresult);\n}\n\n\n\n/* Line 1675 of yacc.c  */\n#line 239 \"tjsdate.y\"\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsdate.tab.h",
    "content": "namespace TJS {\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton interface for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     DP_AM = 258,\n     DP_PM = 259,\n     DP_NUMBER = 260,\n     DP_MONTH = 261,\n     DP_WDAY = 262,\n     DP_TZ = 263\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 1676 of yacc.c  */\n#line 45 \"tjsdate.y\"\n\n\ttjs_int32\t\t\t\t\tval;\n\n\n\n/* Line 1676 of yacc.c  */\n#line 66 \"tjsdate.tab.h\"\n} YYSTYPE;\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjsdate.tab.hpp",
    "content": "namespace TJS {\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton interface for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     DP_AM = 258,\n     DP_PM = 259,\n     DP_NUMBER = 260,\n     DP_MONTH = 261,\n     DP_WDAY = 262,\n     DP_TZ = 263\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 1676 of yacc.c  */\n#line 45 \"tjsdate.y\"\n\n\ttjs_int32\t\t\t\t\tval;\n\n\n\n/* Line 1676 of yacc.c  */\n#line 66 \"tjsdate.tab.hpp\"\n} YYSTYPE;\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjspp.tab.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton implementation for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n/* C LALR(1) parser skeleton written by Richard Stallman, by\n   simplifying the original so-called \"semantic\" parser.  */\n\n/* All symbols defined below should begin with yy or YY, to avoid\n   infringing on user name space.  This should be done even for local\n   variables, as they might otherwise be expanded by user macros.\n   There are some unavoidable exceptions within include files to\n   define necessary library symbols; they are noted \"INFRINGES ON\n   USER NAME SPACE\" below.  */\n\n/* Identify Bison output.  */\n#define YYBISON 1\n\n/* Bison version.  */\n#define YYBISON_VERSION \"2.4.1\"\n\n/* Skeleton name.  */\n#define YYSKELETON_NAME \"yacc.c\"\n\n/* Pure parsers.  */\n#define YYPURE 1\n\n/* Push parsers.  */\n#define YYPUSH 0\n\n/* Pull parsers.  */\n#define YYPULL 1\n\n/* Using locations.  */\n#define YYLSP_NEEDED 0\n\n/* Substitute the variable and function names.  */\n#define yyparse         ppparse\n#define yylex           pplex\n#define yyerror         pperror\n#define yylval          pplval\n#define yychar          ppchar\n#define yydebug         ppdebug\n#define yynerrs         ppnerrs\n\n\n/* Copy the first part of user declarations.  */\n\n/* Line 189 of yacc.c  */\n#line 1 \"syntax/tjspp.y\"\n\n/*---------------------------------------------------------------------------*/\n/*\n\tTJS2 Script Engine\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n/*---------------------------------------------------------------------------*/\n/* tjspp.y */\n/* TJS2 conditional compiling control's conditional expression parser */\n\n#include <memory>\n\n#include \"tjs.h\"\n#include \"tjsCompileControl.h\"\n\n#define YYMALLOC\t::malloc\n#define YYREALLOC\t::realloc\n#define YYFREE\t\t::free\n\n\n/* param */\n#define YYPARSE_PARAM pm\n#define YYLEX_PARAM pm\n\nnamespace TJS {\n\n/* yylex/yyerror prototype decl */\n#define YYLEX_PROTO_DECL int pplex(YYSTYPE *yylex, void *pm);\n\nint _pperror(char * msg, void *pm)\n{\n\t(void)msg;\n\t(void)pm;\n    return 0;\n}\n\n#define pperror(msg) _pperror(msg, pm);\n\n\n#define tjs (((tTJSPPExprParser*)pm)->GetTJS())\n#define ep ((tTJSPPExprParser*)pm)\n\n\n/* Line 189 of yacc.c  */\n#line 127 \"tjspp.tab.cpp\"\n\n/* Enabling traces.  */\n#ifndef YYDEBUG\n# define YYDEBUG 0\n#endif\n\n/* Enabling verbose error messages.  */\n#ifdef YYERROR_VERBOSE\n# undef YYERROR_VERBOSE\n# define YYERROR_VERBOSE 1\n#else\n# define YYERROR_VERBOSE 0\n#endif\n\n/* Enabling the token table.  */\n#ifndef YYTOKEN_TABLE\n# define YYTOKEN_TABLE 0\n#endif\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     PT_LPARENTHESIS = 258,\n     PT_RPARENTHESIS = 259,\n     PT_ERROR = 260,\n     PT_COMMA = 261,\n     PT_EQUAL = 262,\n     PT_NOTEQUAL = 263,\n     PT_EQUALEQUAL = 264,\n     PT_LOGICALOR = 265,\n     PT_LOGICALAND = 266,\n     PT_VERTLINE = 267,\n     PT_CHEVRON = 268,\n     PT_AMPERSAND = 269,\n     PT_LT = 270,\n     PT_GT = 271,\n     PT_LTOREQUAL = 272,\n     PT_GTOREQUAL = 273,\n     PT_PLUS = 274,\n     PT_MINUS = 275,\n     PT_ASTERISK = 276,\n     PT_SLASH = 277,\n     PT_PERCENT = 278,\n     PT_EXCLAMATION = 279,\n     PT_UN = 280,\n     PT_SYMBOL = 281,\n     PT_NUM = 282\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 214 of yacc.c  */\n#line 49 \"syntax/tjspp.y\"\n\n\ttjs_int32\t\tval;\n\ttjs_int\t\t\tnv;\n\n\n\n/* Line 214 of yacc.c  */\n#line 197 \"tjspp.tab.cpp\"\n} YYSTYPE;\nYYLEX_PROTO_DECL\n\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n/* Copy the second part of user declarations.  */\n\n\n/* Line 264 of yacc.c  */\n#line 209 \"tjspp.tab.cpp\"\n\n#ifdef short\n# undef short\n#endif\n\n#ifdef YYTYPE_UINT8\ntypedef YYTYPE_UINT8 yytype_uint8;\n#else\ntypedef unsigned char yytype_uint8;\n#endif\n\n#ifdef YYTYPE_INT8\ntypedef YYTYPE_INT8 yytype_int8;\n#elif (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\ntypedef signed char yytype_int8;\n#else\ntypedef short int yytype_int8;\n#endif\n\n#ifdef YYTYPE_UINT16\ntypedef YYTYPE_UINT16 yytype_uint16;\n#else\ntypedef unsigned short int yytype_uint16;\n#endif\n\n#ifdef YYTYPE_INT16\ntypedef YYTYPE_INT16 yytype_int16;\n#else\ntypedef short int yytype_int16;\n#endif\n\n#ifndef YYSIZE_T\n# ifdef __SIZE_TYPE__\n#  define YYSIZE_T __SIZE_TYPE__\n# elif defined size_t\n#  define YYSIZE_T size_t\n# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYSIZE_T size_t\n# else\n#  define YYSIZE_T unsigned int\n# endif\n#endif\n\n#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)\n\n#ifndef YY_\n# if YYENABLE_NLS\n#  if ENABLE_NLS\n#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */\n#   define YY_(msgid) dgettext (\"bison-runtime\", msgid)\n#  endif\n# endif\n# ifndef YY_\n#  define YY_(msgid) msgid\n# endif\n#endif\n\n/* Suppress unused-variable warnings by \"using\" E.  */\n#if ! defined lint || defined __GNUC__\n# define YYUSE(e) ((void) (e))\n#else\n# define YYUSE(e) /* empty */\n#endif\n\n/* Identity function, used to suppress warnings about constant conditions.  */\n#ifndef lint\n# define YYID(n) (n)\n#else\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic int\nYYID (int yyi)\n#else\nstatic int\nYYID (yyi)\n    int yyi;\n#endif\n{\n  return yyi;\n}\n#endif\n\n#if ! defined yyoverflow || YYERROR_VERBOSE\n\n/* The parser invokes alloca or malloc; define the necessary symbols.  */\n\n# ifdef YYSTACK_USE_ALLOCA\n#  if YYSTACK_USE_ALLOCA\n#   ifdef __GNUC__\n#    define YYSTACK_ALLOC __builtin_alloca\n#   elif defined __BUILTIN_VA_ARG_INCR\n#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */\n#   elif defined _AIX\n#    define YYSTACK_ALLOC __alloca\n#   elif defined _MSC_VER\n#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */\n#    define alloca _alloca\n#   else\n#    define YYSTACK_ALLOC alloca\n#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\n#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#     ifndef _STDLIB_H\n#      define _STDLIB_H 1\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n\n# ifdef YYSTACK_ALLOC\n   /* Pacify GCC's `empty if-body' warning.  */\n#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n    /* The OS might guarantee only one guard page at the bottom of the stack,\n       and a page size can be as small as 4096 bytes.  So we cannot safely\n       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number\n       to allow for a few compiler-allocated temporary stack slots.  */\n#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */\n#  endif\n# else\n#  define YYSTACK_ALLOC YYMALLOC\n#  define YYSTACK_FREE YYFREE\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM\n#  endif\n#  if (defined __cplusplus && ! defined _STDLIB_H \\\n       && ! ((defined YYMALLOC || defined malloc) \\\n\t     && (defined YYFREE || defined free)))\n#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#   ifndef _STDLIB_H\n#    define _STDLIB_H 1\n#   endif\n#  endif\n#  ifndef YYMALLOC\n#   define YYMALLOC malloc\n#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n#  ifndef YYFREE\n#   define YYFREE free\n#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nvoid free (void *); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n# endif\n#endif /* ! defined yyoverflow || YYERROR_VERBOSE */\n\n\n#if (! defined yyoverflow \\\n     && (! defined __cplusplus \\\n\t || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))\n\n/* A type that is properly aligned for any stack member.  */\nunion yyalloc\n{\n  yytype_int16 yyss_alloc;\n  YYSTYPE yyvs_alloc;\n};\n\n/* The size of the maximum gap between one aligned stack and the next.  */\n# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\n\n/* The size of an array large to enough to hold all stacks, each with\n   N elements.  */\n# define YYSTACK_BYTES(N) \\\n     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \\\n      + YYSTACK_GAP_MAXIMUM)\n\n/* Copy COUNT objects from FROM to TO.  The source and destination do\n   not overlap.  */\n# ifndef YYCOPY\n#  if defined __GNUC__ && 1 < __GNUC__\n#   define YYCOPY(To, From, Count) \\\n      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))\n#  else\n#   define YYCOPY(To, From, Count)\t\t\\\n      do\t\t\t\t\t\\\n\t{\t\t\t\t\t\\\n\t  YYSIZE_T yyi;\t\t\t\t\\\n\t  for (yyi = 0; yyi < (Count); yyi++)\t\\\n\t    (To)[yyi] = (From)[yyi];\t\t\\\n\t}\t\t\t\t\t\\\n      while (YYID (0))\n#  endif\n# endif\n\n/* Relocate STACK from its old location to the new one.  The\n   local variables YYSIZE and YYSTACKSIZE give the old and new number of\n   elements in the stack, and YYPTR gives the new location of the\n   stack.  Advance YYPTR to a properly aligned location for the next\n   stack.  */\n# define YYSTACK_RELOCATE(Stack_alloc, Stack)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      {\t\t\t\t\t\t\t\t\t\\\n\tYYSIZE_T yynewbytes;\t\t\t\t\t\t\\\n\tYYCOPY (&yyptr->Stack_alloc, Stack, yysize);\t\t\t\\\n\tStack = &yyptr->Stack_alloc;\t\t\t\t\t\\\n\tyynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\\n\tyyptr += yynewbytes / sizeof (*yyptr);\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n\n#endif\n\n/* YYFINAL -- State number of the termination state.  */\n#define YYFINAL  14\n/* YYLAST -- Last index in YYTABLE.  */\n#define YYLAST   189\n\n/* YYNTOKENS -- Number of terminals.  */\n#define YYNTOKENS  28\n/* YYNNTS -- Number of nonterminals.  */\n#define YYNNTS  3\n/* YYNRULES -- Number of rules.  */\n#define YYNRULES  26\n/* YYNRULES -- Number of states.  */\n#define YYNSTATES  51\n\n/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */\n#define YYUNDEFTOK  2\n#define YYMAXUTOK   282\n\n#define YYTRANSLATE(YYX)\t\t\t\t\t\t\\\n  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\n\n/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */\nstatic const yytype_uint8 yytranslate[] =\n{\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n      25,    26,    27\n};\n\n#if YYDEBUG\n/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in\n   YYRHS.  */\nstatic const yytype_uint8 yyprhs[] =\n{\n       0,     0,     3,     5,     9,    13,    17,    21,    25,    29,\n      33,    37,    41,    45,    49,    53,    57,    61,    65,    69,\n      73,    77,    80,    83,    86,    90,    92\n};\n\n/* YYRHS -- A `-1'-separated list of the rules' RHS.  */\nstatic const yytype_int8 yyrhs[] =\n{\n      29,     0,    -1,    30,    -1,    30,     6,    30,    -1,    26,\n       7,    30,    -1,    30,     8,    30,    -1,    30,     9,    30,\n      -1,    30,    10,    30,    -1,    30,    11,    30,    -1,    30,\n      12,    30,    -1,    30,    13,    30,    -1,    30,    14,    30,\n      -1,    30,    15,    30,    -1,    30,    16,    30,    -1,    30,\n      18,    30,    -1,    30,    17,    30,    -1,    30,    19,    30,\n      -1,    30,    20,    30,    -1,    30,    23,    30,    -1,    30,\n      21,    30,    -1,    30,    22,    30,    -1,    24,    30,    -1,\n      19,    30,    -1,    20,    30,    -1,     3,    30,     4,    -1,\n      27,    -1,    26,    -1\n};\n\n/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\nstatic const yytype_uint8 yyrline[] =\n{\n       0,   104,   104,   108,   109,   110,   111,   112,   113,   114,\n     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,\n     125,   126,   127,   128,   129,   130,   131\n};\n#endif\n\n#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE\n/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */\nstatic const char *const yytname[] =\n{\n  \"$end\", \"error\", \"$undefined\", \"\\\"(\\\"\", \"\\\")\\\"\", \"PT_ERROR\", \"\\\",\\\"\",\n  \"\\\"=\\\"\", \"\\\"!=\\\"\", \"\\\"==\\\"\", \"\\\"||\\\"\", \"\\\"&&\\\"\", \"\\\"|\\\"\", \"\\\"^\\\"\",\n  \"\\\"&\\\"\", \"\\\"<\\\"\", \"\\\">\\\"\", \"\\\"<=\\\"\", \"\\\">=\\\"\", \"\\\"+\\\"\", \"\\\"-\\\"\", \"\\\"*\\\"\",\n  \"\\\"/\\\"\", \"\\\"%\\\"\", \"\\\"!\\\"\", \"PT_UN\", \"PT_SYMBOL\", \"PT_NUM\", \"$accept\",\n  \"input\", \"expr\", 0\n};\n#endif\n\n# ifdef YYPRINT\n/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to\n   token YYLEX-NUM.  */\nstatic const yytype_uint16 yytoknum[] =\n{\n       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\n     275,   276,   277,   278,   279,   280,   281,   282\n};\n# endif\n\n/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\nstatic const yytype_uint8 yyr1[] =\n{\n       0,    28,    29,    30,    30,    30,    30,    30,    30,    30,\n      30,    30,    30,    30,    30,    30,    30,    30,    30,    30,\n      30,    30,    30,    30,    30,    30,    30\n};\n\n/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */\nstatic const yytype_uint8 yyr2[] =\n{\n       0,     2,     1,     3,     3,     3,     3,     3,     3,     3,\n       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,\n       3,     2,     2,     2,     3,     1,     1\n};\n\n/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state\n   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero\n   means the default is an error.  */\nstatic const yytype_uint8 yydefact[] =\n{\n       0,     0,     0,     0,     0,    26,    25,     0,     2,     0,\n      22,    23,    21,     0,     1,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,    24,     4,     3,     5,     6,     7,     8,     9,\n      10,    11,    12,    13,    15,    14,    16,    17,    19,    20,\n      18\n};\n\n/* YYDEFGOTO[NTERM-NUM].  */\nstatic const yytype_int8 yydefgoto[] =\n{\n      -1,     7,     8\n};\n\n/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n   STATE-NUM.  */\n#define YYPACT_NINF -16\nstatic const yytype_int16 yypact[] =\n{\n      28,    28,    28,    28,    28,     6,   -16,    41,    70,    52,\n     -16,   -16,   -16,    28,   -16,    28,    28,    28,    28,    28,\n      28,    28,    28,    28,    28,    28,    28,    28,    28,    28,\n      28,    28,   -16,   166,    86,    17,    17,   102,   118,   134,\n     150,   166,   -15,   -15,   -15,   -15,   -12,   -12,   -16,   -16,\n     -16\n};\n\n/* YYPGOTO[NTERM-NUM].  */\nstatic const yytype_int8 yypgoto[] =\n{\n     -16,   -16,    -1\n};\n\n/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If\n   positive, shift that token.  If negative, reduce the rule which\n   number is the opposite.  If zero, do what YYDEFACT says.\n   If YYTABLE_NINF, syntax error.  */\n#define YYTABLE_NINF -1\nstatic const yytype_uint8 yytable[] =\n{\n       9,    10,    11,    12,    27,    28,    29,    30,    31,    29,\n      30,    31,    33,    13,    34,    35,    36,    37,    38,    39,\n      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,\n      50,     1,    23,    24,    25,    26,    27,    28,    29,    30,\n      31,    14,     0,     0,     0,     0,     0,     2,     3,     0,\n       0,     0,     4,     0,     5,     6,    32,     0,    15,     0,\n      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,\n      26,    27,    28,    29,    30,    31,    15,     0,    16,    17,\n      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,\n      28,    29,    30,    31,    16,    17,    18,    19,    20,    21,\n      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,\n      16,    17,     0,    19,    20,    21,    22,    23,    24,    25,\n      26,    27,    28,    29,    30,    31,    16,    17,     0,     0,\n      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,\n      30,    31,    16,    17,     0,     0,     0,    21,    22,    23,\n      24,    25,    26,    27,    28,    29,    30,    31,    16,    17,\n       0,     0,     0,     0,    22,    23,    24,    25,    26,    27,\n      28,    29,    30,    31,    16,    17,     0,     0,     0,     0,\n       0,    23,    24,    25,    26,    27,    28,    29,    30,    31\n};\n\nstatic const yytype_int8 yycheck[] =\n{\n       1,     2,     3,     4,    19,    20,    21,    22,    23,    21,\n      22,    23,    13,     7,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,\n      31,     3,    15,    16,    17,    18,    19,    20,    21,    22,\n      23,     0,    -1,    -1,    -1,    -1,    -1,    19,    20,    -1,\n      -1,    -1,    24,    -1,    26,    27,     4,    -1,     6,    -1,\n       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,\n      18,    19,    20,    21,    22,    23,     6,    -1,     8,     9,\n      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,\n      20,    21,    22,    23,     8,     9,    10,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n       8,     9,    -1,    11,    12,    13,    14,    15,    16,    17,\n      18,    19,    20,    21,    22,    23,     8,     9,    -1,    -1,\n      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,\n      22,    23,     8,     9,    -1,    -1,    -1,    13,    14,    15,\n      16,    17,    18,    19,    20,    21,    22,    23,     8,     9,\n      -1,    -1,    -1,    -1,    14,    15,    16,    17,    18,    19,\n      20,    21,    22,    23,     8,     9,    -1,    -1,    -1,    -1,\n      -1,    15,    16,    17,    18,    19,    20,    21,    22,    23\n};\n\n/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\n   symbol of state STATE-NUM.  */\nstatic const yytype_uint8 yystos[] =\n{\n       0,     3,    19,    20,    24,    26,    27,    29,    30,    30,\n      30,    30,    30,     7,     0,     6,     8,     9,    10,    11,\n      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,\n      22,    23,     4,    30,    30,    30,    30,    30,    30,    30,\n      30,    30,    30,    30,    30,    30,    30,    30,    30,    30,\n      30\n};\n\n#define yyerrok\t\t(yyerrstatus = 0)\n#define yyclearin\t(yychar = YYEMPTY)\n#define YYEMPTY\t\t(-2)\n#define YYEOF\t\t0\n\n#define YYACCEPT\tgoto yyacceptlab\n#define YYABORT\t\tgoto yyabortlab\n#define YYERROR\t\tgoto yyerrorlab\n\n\n/* Like YYERROR except do call yyerror.  This remains here temporarily\n   to ease the transition to the new meaning of YYERROR, for GCC.\n   Once GCC version 2 has supplanted version 1, this can go.  */\n\n#define YYFAIL\t\tgoto yyerrlab\n\n#define YYRECOVERING()  (!!yyerrstatus)\n\n#define YYBACKUP(Token, Value)\t\t\t\t\t\\\ndo\t\t\t\t\t\t\t\t\\\n  if (yychar == YYEMPTY && yylen == 1)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yychar = (Token);\t\t\t\t\t\t\\\n      yylval = (Value);\t\t\t\t\t\t\\\n      yytoken = YYTRANSLATE (yychar);\t\t\t\t\\\n      YYPOPSTACK (1);\t\t\t\t\t\t\\\n      goto yybackup;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n  else\t\t\t\t\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yyerror (YY_(\"syntax error: cannot back up\")); \\\n      YYERROR;\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\nwhile (YYID (0))\n\n\n#define YYTERROR\t1\n#define YYERRCODE\t256\n\n\n/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\n   If N is 0, then set CURRENT to the empty location which ends\n   the previous symbol: RHS[0] (always defined).  */\n\n#define YYRHSLOC(Rhs, K) ((Rhs)[K])\n#ifndef YYLLOC_DEFAULT\n# define YYLLOC_DEFAULT(Current, Rhs, N)\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      if (YYID (N))                                                    \\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;\t\\\n\t  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;\t\\\n\t  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;\t\t\\\n\t  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;\t\\\n\t}\t\t\t\t\t\t\t\t\\\n      else\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t  (Current).first_line   = (Current).last_line   =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_line;\t\t\t\t\\\n\t  (Current).first_column = (Current).last_column =\t\t\\\n\t    YYRHSLOC (Rhs, 0).last_column;\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n    while (YYID (0))\n#endif\n\n\n/* YY_LOCATION_PRINT -- Print the location on the stream.\n   This macro was not mandated originally: define only if we know\n   we won't break user code: when these are the locations we know.  */\n\n#ifndef YY_LOCATION_PRINT\n# if YYLTYPE_IS_TRIVIAL\n#  define YY_LOCATION_PRINT(File, Loc)\t\t\t\\\n     fprintf (File, \"%d.%d-%d.%d\",\t\t\t\\\n\t      (Loc).first_line, (Loc).first_column,\t\\\n\t      (Loc).last_line,  (Loc).last_column)\n# else\n#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)\n# endif\n#endif\n\n\n/* YYLEX -- calling `yylex' with the right arguments.  */\n\n#ifdef YYLEX_PARAM\n# define YYLEX yylex (&yylval, YYLEX_PARAM)\n#else\n# define YYLEX yylex (&yylval)\n#endif\n\n/* Enable debugging if requested.  */\n#if YYDEBUG\n\n# ifndef YYFPRINTF\n#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYFPRINTF fprintf\n# endif\n\n# define YYDPRINTF(Args)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\\\n    YYFPRINTF Args;\t\t\t\t\\\n} while (YYID (0))\n\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\t\t\t  \\\ndo {\t\t\t\t\t\t\t\t\t  \\\n  if (yydebug)\t\t\t\t\t\t\t\t  \\\n    {\t\t\t\t\t\t\t\t\t  \\\n      YYFPRINTF (stderr, \"%s \", Title);\t\t\t\t\t  \\\n      yy_symbol_print (stderr,\t\t\t\t\t\t  \\\n\t\t  Type, Value); \\\n      YYFPRINTF (stderr, \"\\n\");\t\t\t\t\t\t  \\\n    }\t\t\t\t\t\t\t\t\t  \\\n} while (YYID (0))\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_value_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (!yyvaluep)\n    return;\n# ifdef YYPRINT\n  if (yytype < YYNTOKENS)\n    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\n# else\n  YYUSE (yyoutput);\n# endif\n  switch (yytype)\n    {\n      default:\n\tbreak;\n    }\n}\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)\n#else\nstatic void\nyy_symbol_print (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE const * const yyvaluep;\n#endif\n{\n  if (yytype < YYNTOKENS)\n    YYFPRINTF (yyoutput, \"token %s (\", yytname[yytype]);\n  else\n    YYFPRINTF (yyoutput, \"nterm %s (\", yytname[yytype]);\n\n  yy_symbol_value_print (yyoutput, yytype, yyvaluep);\n  YYFPRINTF (yyoutput, \")\");\n}\n\n/*------------------------------------------------------------------.\n| yy_stack_print -- Print the state stack from its BOTTOM up to its |\n| TOP (included).                                                   |\n`------------------------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)\n#else\nstatic void\nyy_stack_print (yybottom, yytop)\n    yytype_int16 *yybottom;\n    yytype_int16 *yytop;\n#endif\n{\n  YYFPRINTF (stderr, \"Stack now\");\n  for (; yybottom <= yytop; yybottom++)\n    {\n      int yybot = *yybottom;\n      YYFPRINTF (stderr, \" %d\", yybot);\n    }\n  YYFPRINTF (stderr, \"\\n\");\n}\n\n# define YY_STACK_PRINT(Bottom, Top)\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\t\t\\\n    yy_stack_print ((Bottom), (Top));\t\t\t\t\\\n} while (YYID (0))\n\n\n/*------------------------------------------------.\n| Report that the YYRULE is going to be reduced.  |\n`------------------------------------------------*/\n\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyy_reduce_print (YYSTYPE *yyvsp, int yyrule)\n#else\nstatic void\nyy_reduce_print (yyvsp, yyrule)\n    YYSTYPE *yyvsp;\n    int yyrule;\n#endif\n{\n  int yynrhs = yyr2[yyrule];\n  int yyi;\n  unsigned long int yylno = yyrline[yyrule];\n  YYFPRINTF (stderr, \"Reducing stack by rule %d (line %lu):\\n\",\n\t     yyrule - 1, yylno);\n  /* The symbols being reduced.  */\n  for (yyi = 0; yyi < yynrhs; yyi++)\n    {\n      YYFPRINTF (stderr, \"   $%d = \", yyi + 1);\n      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],\n\t\t       &(yyvsp[(yyi + 1) - (yynrhs)])\n\t\t       \t\t       );\n      YYFPRINTF (stderr, \"\\n\");\n    }\n}\n\n# define YY_REDUCE_PRINT(Rule)\t\t\\\ndo {\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\\\n    yy_reduce_print (yyvsp, Rule); \\\n} while (YYID (0))\n\n/* Nonzero means print parse trace.  It is left uninitialized so that\n   multiple parsers can coexist.  */\nint yydebug;\n#else /* !YYDEBUG */\n# define YYDPRINTF(Args)\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\n# define YY_STACK_PRINT(Bottom, Top)\n# define YY_REDUCE_PRINT(Rule)\n#endif /* !YYDEBUG */\n\n\n/* YYINITDEPTH -- initial size of the parser's stacks.  */\n#ifndef\tYYINITDEPTH\n# define YYINITDEPTH 200\n#endif\n\n/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\n   if the built-in stack extension method is used).\n\n   Do not make this value too large; the results are undefined if\n   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)\n   evaluated with infinite-precision integer arithmetic.  */\n\n#ifndef YYMAXDEPTH\n# define YYMAXDEPTH 10000\n#endif\n\n\f\n\n#if YYERROR_VERBOSE\n\n# ifndef yystrlen\n#  if defined __GLIBC__ && defined _STRING_H\n#   define yystrlen strlen\n#  else\n/* Return the length of YYSTR.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic YYSIZE_T\nyystrlen (const char *yystr)\n#else\nstatic YYSIZE_T\nyystrlen (yystr)\n    const char *yystr;\n#endif\n{\n  YYSIZE_T yylen;\n  for (yylen = 0; yystr[yylen]; yylen++)\n    continue;\n  return yylen;\n}\n#  endif\n# endif\n\n# ifndef yystpcpy\n#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE\n#   define yystpcpy stpcpy\n#  else\n/* Copy YYSRC to YYDEST, returning the address of the terminating '\\0' in\n   YYDEST.  */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic char *\nyystpcpy (char *yydest, const char *yysrc)\n#else\nstatic char *\nyystpcpy (yydest, yysrc)\n    char *yydest;\n    const char *yysrc;\n#endif\n{\n  char *yyd = yydest;\n  const char *yys = yysrc;\n\n  while ((*yyd++ = *yys++) != '\\0')\n    continue;\n\n  return yyd - 1;\n}\n#  endif\n# endif\n\n# ifndef yytnamerr\n/* Copy to YYRES the contents of YYSTR after stripping away unnecessary\n   quotes and backslashes, so that it's suitable for yyerror.  The\n   heuristic is that double-quoting is unnecessary unless the string\n   contains an apostrophe, a comma, or backslash (other than\n   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is\n   null, do not copy; instead, return the length of what the result\n   would have been.  */\nstatic YYSIZE_T\nyytnamerr (char *yyres, const char *yystr)\n{\n  if (*yystr == '\"')\n    {\n      YYSIZE_T yyn = 0;\n      char const *yyp = yystr;\n\n      for (;;)\n\tswitch (*++yyp)\n\t  {\n\t  case '\\'':\n\t  case ',':\n\t    goto do_not_strip_quotes;\n\n\t  case '\\\\':\n\t    if (*++yyp != '\\\\')\n\t      goto do_not_strip_quotes;\n\t    /* Fall through.  */\n\t  default:\n\t    if (yyres)\n\t      yyres[yyn] = *yyp;\n\t    yyn++;\n\t    break;\n\n\t  case '\"':\n\t    if (yyres)\n\t      yyres[yyn] = '\\0';\n\t    return yyn;\n\t  }\n    do_not_strip_quotes: ;\n    }\n\n  if (! yyres)\n    return yystrlen (yystr);\n\n  return yystpcpy (yyres, yystr) - yyres;\n}\n# endif\n\n/* Copy into YYRESULT an error message about the unexpected token\n   YYCHAR while in state YYSTATE.  Return the number of bytes copied,\n   including the terminating null byte.  If YYRESULT is null, do not\n   copy anything; just return the number of bytes that would be\n   copied.  As a special case, return 0 if an ordinary \"syntax error\"\n   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during\n   size calculation.  */\nstatic YYSIZE_T\nyysyntax_error (char *yyresult, int yystate, int yychar)\n{\n  int yyn = yypact[yystate];\n\n  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))\n    return 0;\n  else\n    {\n      int yytype = YYTRANSLATE (yychar);\n      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);\n      YYSIZE_T yysize = yysize0;\n      YYSIZE_T yysize1;\n      int yysize_overflow = 0;\n      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };\n      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];\n      int yyx;\n\n# if 0\n      /* This is so xgettext sees the translatable formats that are\n\t constructed on the fly.  */\n      YY_(\"syntax error, unexpected %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s\");\n      YY_(\"syntax error, unexpected %s, expecting %s or %s or %s or %s\");\n# endif\n      char *yyfmt;\n      char const *yyf;\n      static char const yyunexpected[] = \"syntax error, unexpected %s\";\n      static char const yyexpecting[] = \", expecting %s\";\n      static char const yyor[] = \" or %s\";\n      char yyformat[sizeof yyunexpected\n\t\t    + sizeof yyexpecting - 1\n\t\t    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)\n\t\t       * (sizeof yyor - 1))];\n      char const *yyprefix = yyexpecting;\n\n      /* Start YYX at -YYN if negative to avoid negative indexes in\n\t YYCHECK.  */\n      int yyxbegin = yyn < 0 ? -yyn : 0;\n\n      /* Stay within bounds of both yycheck and yytname.  */\n      int yychecklim = YYLAST - yyn + 1;\n      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n      int yycount = 1;\n\n      yyarg[0] = yytname[yytype];\n      yyfmt = yystpcpy (yyformat, yyunexpected);\n\n      for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n\tif (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\n\t  {\n\t    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)\n\t      {\n\t\tyycount = 1;\n\t\tyysize = yysize0;\n\t\tyyformat[sizeof yyunexpected - 1] = '\\0';\n\t\tbreak;\n\t      }\n\t    yyarg[yycount++] = yytname[yyx];\n\t    yysize1 = yysize + yytnamerr (0, yytname[yyx]);\n\t    yysize_overflow |= (yysize1 < yysize);\n\t    yysize = yysize1;\n\t    yyfmt = yystpcpy (yyfmt, yyprefix);\n\t    yyprefix = yyor;\n\t  }\n\n      yyf = YY_(yyformat);\n      yysize1 = yysize + yystrlen (yyf);\n      yysize_overflow |= (yysize1 < yysize);\n      yysize = yysize1;\n\n      if (yysize_overflow)\n\treturn YYSIZE_MAXIMUM;\n\n      if (yyresult)\n\t{\n\t  /* Avoid sprintf, as that infringes on the user's name space.\n\t     Don't have undefined behavior even if the translation\n\t     produced a string with the wrong number of \"%s\"s.  */\n\t  char *yyp = yyresult;\n\t  int yyi = 0;\n\t  while ((*yyp = *yyf) != '\\0')\n\t    {\n\t      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)\n\t\t{\n\t\t  yyp += yytnamerr (yyp, yyarg[yyi++]);\n\t\t  yyf += 2;\n\t\t}\n\t      else\n\t\t{\n\t\t  yyp++;\n\t\t  yyf++;\n\t\t}\n\t    }\n\t}\n      return yysize;\n    }\n}\n#endif /* YYERROR_VERBOSE */\n\f\n\n/*-----------------------------------------------.\n| Release the memory associated to this symbol.  |\n`-----------------------------------------------*/\n\n/*ARGSUSED*/\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nstatic void\nyydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)\n#else\nstatic void\nyydestruct (yymsg, yytype, yyvaluep)\n    const char *yymsg;\n    int yytype;\n    YYSTYPE *yyvaluep;\n#endif\n{\n  YYUSE (yyvaluep);\n\n  if (!yymsg)\n    yymsg = \"Deleting\";\n  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);\n\n  /*switch (yytype)\n    {\n\n      default:\n\tbreak;\n    }*/\n}\n\n/* Prevent warnings from -Wmissing-prototypes.  */\n#ifdef YYPARSE_PARAM\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void *YYPARSE_PARAM);\n#else\nint yyparse ();\n#endif\n#else /* ! YYPARSE_PARAM */\n#if defined __STDC__ || defined __cplusplus\nint yyparse (void);\n#else\nint yyparse ();\n#endif\n#endif /* ! YYPARSE_PARAM */\n\n\n\n\n\n/*-------------------------.\n| yyparse or yypush_parse.  |\n`-------------------------*/\n\n#ifdef YYPARSE_PARAM\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void *YYPARSE_PARAM)\n#else\nint\nyyparse (YYPARSE_PARAM)\n    void *YYPARSE_PARAM;\n#endif\n#else /* ! YYPARSE_PARAM */\n#if (defined __STDC__ || defined __C99__FUNC__ \\\n     || defined __cplusplus || defined _MSC_VER)\nint\nyyparse (void)\n#else\nint\nyyparse ()\n\n#endif\n#endif\n{\n/* The lookahead symbol.  */\nint yychar;\n\n/* The semantic value of the lookahead symbol.  */\nYYSTYPE yylval;\n\n    /* Number of syntax errors so far.  */\n    int yynerrs;\n\n    int yystate;\n    /* Number of tokens to shift before error messages enabled.  */\n    int yyerrstatus;\n\n    /* The stacks and their tools:\n       `yyss': related to states.\n       `yyvs': related to semantic values.\n\n       Refer to the stacks thru separate pointers, to allow yyoverflow\n       to reallocate them elsewhere.  */\n\n    /* The state stack.  */\n    yytype_int16 yyssa[YYINITDEPTH];\n    yytype_int16 *yyss;\n    yytype_int16 *yyssp;\n\n    /* The semantic value stack.  */\n    YYSTYPE yyvsa[YYINITDEPTH];\n    YYSTYPE *yyvs;\n    YYSTYPE *yyvsp;\n\n    YYSIZE_T yystacksize;\n\n  int yyn;\n  int yyresult;\n  /* Lookahead token as an internal (translated) token number.  */\n  int yytoken;\n  /* The variables used to return semantic value and location from the\n     action routines.  */\n  YYSTYPE yyval;\n\n#if YYERROR_VERBOSE\n  /* Buffer for error messages, and its allocated size.  */\n  char yymsgbuf[128];\n  char *yymsg = yymsgbuf;\n  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;\n#endif\n\n#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))\n\n  /* The number of symbols on the RHS of the reduced rule.\n     Keep to zero when no symbol should be popped.  */\n  int yylen = 0;\n\n  yytoken = 0;\n  yyss = yyssa;\n  yyvs = yyvsa;\n  yystacksize = YYINITDEPTH;\n\n  YYDPRINTF ((stderr, \"Starting parse\\n\"));\n\n  yystate = 0;\n  yyerrstatus = 0;\n  yynerrs = 0;\n  yychar = YYEMPTY; /* Cause a token to be read.  */\n\n  /* Initialize stack pointers.\n     Waste one element of value and location stack\n     so that they stay on the same level as the state stack.\n     The wasted elements are never initialized.  */\n  yyssp = yyss;\n  yyvsp = yyvs;\n\n  goto yysetstate;\n\n/*------------------------------------------------------------.\n| yynewstate -- Push a new state, which is found in yystate.  |\n`------------------------------------------------------------*/\n yynewstate:\n  /* In all cases, when you get here, the value and location stacks\n     have just been pushed.  So pushing a state here evens the stacks.  */\n  yyssp++;\n\n yysetstate:\n  *yyssp = yystate;\n\n  if (yyss + yystacksize - 1 <= yyssp)\n    {\n      /* Get the current used size of the three stacks, in elements.  */\n      YYSIZE_T yysize = yyssp - yyss + 1;\n\n#ifdef yyoverflow\n      {\n\t/* Give user a chance to reallocate the stack.  Use copies of\n\t   these so that the &'s don't force the real ones into\n\t   memory.  */\n\tYYSTYPE *yyvs1 = yyvs;\n\tyytype_int16 *yyss1 = yyss;\n\n\t/* Each stack pointer address is followed by the size of the\n\t   data in use in that stack, in bytes.  This used to be a\n\t   conditional around just the two extra args, but that might\n\t   be undefined if yyoverflow is a macro.  */\n\tyyoverflow (YY_(\"memory exhausted\"),\n\t\t    &yyss1, yysize * sizeof (*yyssp),\n\t\t    &yyvs1, yysize * sizeof (*yyvsp),\n\t\t    &yystacksize);\n\n\tyyss = yyss1;\n\tyyvs = yyvs1;\n      }\n#else /* no yyoverflow */\n# ifndef YYSTACK_RELOCATE\n      goto yyexhaustedlab;\n# else\n      /* Extend the stack our own way.  */\n      if (YYMAXDEPTH <= yystacksize)\n\tgoto yyexhaustedlab;\n      yystacksize *= 2;\n      if (YYMAXDEPTH < yystacksize)\n\tyystacksize = YYMAXDEPTH;\n\n      {\n\tyytype_int16 *yyss1 = yyss;\n\tunion yyalloc *yyptr =\n\t  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\n\tif (! yyptr)\n\t  goto yyexhaustedlab;\n\tYYSTACK_RELOCATE (yyss_alloc, yyss);\n\tYYSTACK_RELOCATE (yyvs_alloc, yyvs);\n#  undef YYSTACK_RELOCATE\n\tif (yyss1 != yyssa)\n\t  YYSTACK_FREE (yyss1);\n      }\n# endif\n#endif /* no yyoverflow */\n\n      yyssp = yyss + yysize - 1;\n      yyvsp = yyvs + yysize - 1;\n\n      YYDPRINTF ((stderr, \"Stack size increased to %lu\\n\",\n\t\t  (unsigned long int) yystacksize));\n\n      if (yyss + yystacksize - 1 <= yyssp)\n\tYYABORT;\n    }\n\n  YYDPRINTF ((stderr, \"Entering state %d\\n\", yystate));\n\n  if (yystate == YYFINAL)\n    YYACCEPT;\n\n  goto yybackup;\n\n/*-----------.\n| yybackup.  |\n`-----------*/\nyybackup:\n\n  /* Do appropriate processing given the current state.  Read a\n     lookahead token if we need one and don't already have one.  */\n\n  /* First try to decide what to do without reference to lookahead token.  */\n  yyn = yypact[yystate];\n  if (yyn == YYPACT_NINF)\n    goto yydefault;\n\n  /* Not known => get a lookahead token if don't already have one.  */\n\n  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\n  if (yychar == YYEMPTY)\n    {\n      YYDPRINTF ((stderr, \"Reading a token: \"));\n      yychar = YYLEX;\n    }\n\n  if (yychar <= YYEOF)\n    {\n      yychar = yytoken = YYEOF;\n      YYDPRINTF ((stderr, \"Now at end of input.\\n\"));\n    }\n  else\n    {\n      yytoken = YYTRANSLATE (yychar);\n      YY_SYMBOL_PRINT (\"Next token is\", yytoken, &yylval, &yylloc);\n    }\n\n  /* If the proper action on seeing token YYTOKEN is to reduce or to\n     detect an error, take that action.  */\n  yyn += yytoken;\n  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\n    goto yydefault;\n  yyn = yytable[yyn];\n  if (yyn <= 0)\n    {\n      if (yyn == 0 || yyn == YYTABLE_NINF)\n\tgoto yyerrlab;\n      yyn = -yyn;\n      goto yyreduce;\n    }\n\n  /* Count tokens shifted since error; after three, turn off error\n     status.  */\n  if (yyerrstatus)\n    yyerrstatus--;\n\n  /* Shift the lookahead token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yytoken, &yylval, &yylloc);\n\n  /* Discard the shifted token.  */\n  yychar = YYEMPTY;\n\n  yystate = yyn;\n  *++yyvsp = yylval;\n\n  goto yynewstate;\n\n\n/*-----------------------------------------------------------.\n| yydefault -- do the default action for the current state.  |\n`-----------------------------------------------------------*/\nyydefault:\n  yyn = yydefact[yystate];\n  if (yyn == 0)\n    goto yyerrlab;\n  goto yyreduce;\n\n\n/*-----------------------------.\n| yyreduce -- Do a reduction.  |\n`-----------------------------*/\nyyreduce:\n  /* yyn is the number of a rule to reduce with.  */\n  yylen = yyr2[yyn];\n\n  /* If YYLEN is nonzero, implement the default value of the action:\n     `$$ = $1'.\n\n     Otherwise, the following line sets YYVAL to garbage.\n     This behavior is undocumented and Bison\n     users should not rely upon it.  Assigning to YYVAL\n     unconditionally makes the parser a bit smaller, and it avoids a\n     GCC warning that YYVAL may be used uninitialized.  */\n  yyval = yyvsp[1-yylen];\n\n\n  YY_REDUCE_PRINT (yyn);\n  switch (yyn)\n    {\n        case 2:\n\n/* Line 1455 of yacc.c  */\n#line 104 \"syntax/tjspp.y\"\n    { ep->Result = (yyvsp[(1) - (1)].val); ;}\n    break;\n\n  case 3:\n\n/* Line 1455 of yacc.c  */\n#line 108 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 4:\n\n/* Line 1455 of yacc.c  */\n#line 109 \"syntax/tjspp.y\"\n    { tjs->SetPPValue(ep->GetString((yyvsp[(1) - (3)].nv)), (yyvsp[(3) - (3)].val)); (yyval.val) = (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 5:\n\n/* Line 1455 of yacc.c  */\n#line 110 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) != (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 6:\n\n/* Line 1455 of yacc.c  */\n#line 111 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) == (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 7:\n\n/* Line 1455 of yacc.c  */\n#line 112 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) || (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 8:\n\n/* Line 1455 of yacc.c  */\n#line 113 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) && (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 9:\n\n/* Line 1455 of yacc.c  */\n#line 114 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) | (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 10:\n\n/* Line 1455 of yacc.c  */\n#line 115 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) ^ (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 11:\n\n/* Line 1455 of yacc.c  */\n#line 116 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) & (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 12:\n\n/* Line 1455 of yacc.c  */\n#line 117 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) < (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 13:\n\n/* Line 1455 of yacc.c  */\n#line 118 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) > (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 14:\n\n/* Line 1455 of yacc.c  */\n#line 119 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) >= (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 15:\n\n/* Line 1455 of yacc.c  */\n#line 120 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) <= (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 16:\n\n/* Line 1455 of yacc.c  */\n#line 121 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) + (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 17:\n\n/* Line 1455 of yacc.c  */\n#line 122 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) - (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 18:\n\n/* Line 1455 of yacc.c  */\n#line 123 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) % (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 19:\n\n/* Line 1455 of yacc.c  */\n#line 124 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (3)].val) * (yyvsp[(3) - (3)].val); ;}\n    break;\n\n  case 20:\n\n/* Line 1455 of yacc.c  */\n#line 125 \"syntax/tjspp.y\"\n    { if((yyvsp[(3) - (3)].val)==0) { YYABORT; } else { (yyval.val) = (yyvsp[(1) - (3)].val) / (yyvsp[(3) - (3)].val); } ;}\n    break;\n\n  case 21:\n\n/* Line 1455 of yacc.c  */\n#line 126 \"syntax/tjspp.y\"\n    { (yyval.val) = ! (yyvsp[(2) - (2)].val); ;}\n    break;\n\n  case 22:\n\n/* Line 1455 of yacc.c  */\n#line 127 \"syntax/tjspp.y\"\n    { (yyval.val) = + (yyvsp[(2) - (2)].val); ;}\n    break;\n\n  case 23:\n\n/* Line 1455 of yacc.c  */\n#line 128 \"syntax/tjspp.y\"\n    { (yyval.val) = - (yyvsp[(2) - (2)].val); ;}\n    break;\n\n  case 24:\n\n/* Line 1455 of yacc.c  */\n#line 129 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(2) - (3)].val); ;}\n    break;\n\n  case 25:\n\n/* Line 1455 of yacc.c  */\n#line 130 \"syntax/tjspp.y\"\n    { (yyval.val) = (yyvsp[(1) - (1)].val); ;}\n    break;\n\n  case 26:\n\n/* Line 1455 of yacc.c  */\n#line 131 \"syntax/tjspp.y\"\n    { (yyval.val) = tjs->GetPPValue(ep->GetString((yyvsp[(1) - (1)].nv))); ;}\n    break;\n\n\n\n/* Line 1455 of yacc.c  */\n#line 1636 \"tjspp.tab.cpp\"\n      default: break;\n    }\n  YY_SYMBOL_PRINT (\"-> $$ =\", yyr1[yyn], &yyval, &yyloc);\n\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n\n  *++yyvsp = yyval;\n\n  /* Now `shift' the result of the reduction.  Determine what state\n     that goes to, based on the state we popped back to and the rule\n     number reduced by.  */\n\n  yyn = yyr1[yyn];\n\n  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\n  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\n    yystate = yytable[yystate];\n  else\n    yystate = yydefgoto[yyn - YYNTOKENS];\n\n  goto yynewstate;\n\n\n/*------------------------------------.\n| yyerrlab -- here on detecting error |\n`------------------------------------*/\nyyerrlab:\n  /* If not already recovering from an error, report this error.  */\n  if (!yyerrstatus)\n    {\n      ++yynerrs;\n#if ! YYERROR_VERBOSE\n      yyerror (YY_(\"syntax error\"));\n#else\n      {\n\tYYSIZE_T yysize = yysyntax_error (0, yystate, yychar);\n\tif (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)\n\t  {\n\t    YYSIZE_T yyalloc = 2 * yysize;\n\t    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))\n\t      yyalloc = YYSTACK_ALLOC_MAXIMUM;\n\t    if (yymsg != yymsgbuf)\n\t      YYSTACK_FREE (yymsg);\n\t    yymsg = (char *) YYSTACK_ALLOC (yyalloc);\n\t    if (yymsg)\n\t      yymsg_alloc = yyalloc;\n\t    else\n\t      {\n\t\tyymsg = yymsgbuf;\n\t\tyymsg_alloc = sizeof yymsgbuf;\n\t      }\n\t  }\n\n\tif (0 < yysize && yysize <= yymsg_alloc)\n\t  {\n\t    (void) yysyntax_error (yymsg, yystate, yychar);\n\t    yyerror (yymsg);\n\t  }\n\telse\n\t  {\n\t    yyerror (YY_(\"syntax error\"));\n\t    if (yysize != 0)\n\t      goto yyexhaustedlab;\n\t  }\n      }\n#endif\n    }\n\n\n\n  if (yyerrstatus == 3)\n    {\n      /* If just tried and failed to reuse lookahead token after an\n\t error, discard it.  */\n\n      if (yychar <= YYEOF)\n\t{\n\t  /* Return failure if at end of input.  */\n\t  if (yychar == YYEOF)\n\t    YYABORT;\n\t}\n      else\n\t{\n\t  yydestruct (\"Error: discarding\",\n\t\t      yytoken, &yylval);\n\t  yychar = YYEMPTY;\n\t}\n    }\n\n  /* Else will try to reuse lookahead token after shifting the error\n     token.  */\n  goto yyerrlab1;\n\n\n/*---------------------------------------------------.\n| yyerrorlab -- error raised explicitly by YYERROR.  |\n`---------------------------------------------------*/\nyyerrorlab:\n\n  /* Pacify compilers like GCC when the user code never invokes\n     YYERROR and the label yyerrorlab therefore never appears in user\n     code.  */\n  if (/*CONSTCOND*/ 0)\n     goto yyerrorlab;\n\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYERROR.  */\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n  yystate = *yyssp;\n  goto yyerrlab1;\n\n\n/*-------------------------------------------------------------.\n| yyerrlab1 -- common code for both syntax error and YYERROR.  |\n`-------------------------------------------------------------*/\nyyerrlab1:\n  yyerrstatus = 3;\t/* Each real token shifted decrements this.  */\n\n  for (;;)\n    {\n      yyn = yypact[yystate];\n      if (yyn != YYPACT_NINF)\n\t{\n\t  yyn += YYTERROR;\n\t  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\n\t    {\n\t      yyn = yytable[yyn];\n\t      if (0 < yyn)\n\t\tbreak;\n\t    }\n\t}\n\n      /* Pop the current state because it cannot handle the error token.  */\n      if (yyssp == yyss)\n\tYYABORT;\n\n\n      yydestruct (\"Error: popping\",\n\t\t  yystos[yystate], yyvsp);\n      YYPOPSTACK (1);\n      yystate = *yyssp;\n      YY_STACK_PRINT (yyss, yyssp);\n    }\n\n  *++yyvsp = yylval;\n\n\n  /* Shift the error token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yystos[yyn], yyvsp, yylsp);\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-------------------------------------.\n| yyacceptlab -- YYACCEPT comes here.  |\n`-------------------------------------*/\nyyacceptlab:\n  yyresult = 0;\n  goto yyreturn;\n\n/*-----------------------------------.\n| yyabortlab -- YYABORT comes here.  |\n`-----------------------------------*/\nyyabortlab:\n  yyresult = 1;\n  goto yyreturn;\n\n#if !defined(yyoverflow) || YYERROR_VERBOSE\n/*-------------------------------------------------.\n| yyexhaustedlab -- memory exhaustion comes here.  |\n`-------------------------------------------------*/\nyyexhaustedlab:\n  yyerror (YY_(\"memory exhausted\"));\n  yyresult = 2;\n  /* Fall through.  */\n#endif\n\nyyreturn:\n  if (yychar != YYEMPTY)\n     yydestruct (\"Cleanup: discarding lookahead\",\n\t\t yytoken, &yylval);\n  /* Do not reclaim the symbols of the rule which action triggered\n     this YYABORT or YYACCEPT.  */\n  YYPOPSTACK (yylen);\n  YY_STACK_PRINT (yyss, yyssp);\n  while (yyssp != yyss)\n    {\n      yydestruct (\"Cleanup: popping\",\n\t\t  yystos[*yyssp], yyvsp);\n      YYPOPSTACK (1);\n    }\n#ifndef yyoverflow\n  if (yyss != yyssa)\n    YYSTACK_FREE (yyss);\n#endif\n#if YYERROR_VERBOSE\n  if (yymsg != yymsgbuf)\n    YYSTACK_FREE (yymsg);\n#endif\n  /* Make sure YYID is used.  */\n  return YYID (yyresult);\n}\n\n\n\n/* Line 1675 of yacc.c  */\n#line 134 \"syntax/tjspp.y\"\n\n\n\n}\n"
  },
  {
    "path": "src/core/tjs2/tjspp.tab.hpp",
    "content": "namespace TJS {\n\n/* A Bison parser, made by GNU Bison 2.4.1.  */\n\n/* Skeleton interface for Bison's Yacc-like parsers in C\n   \n      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006\n   Free Software Foundation, Inc.\n   \n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n   \n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n   \n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n   \n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     PT_LPARENTHESIS = 258,\n     PT_RPARENTHESIS = 259,\n     PT_ERROR = 260,\n     PT_COMMA = 261,\n     PT_EQUAL = 262,\n     PT_NOTEQUAL = 263,\n     PT_EQUALEQUAL = 264,\n     PT_LOGICALOR = 265,\n     PT_LOGICALAND = 266,\n     PT_VERTLINE = 267,\n     PT_CHEVRON = 268,\n     PT_AMPERSAND = 269,\n     PT_LT = 270,\n     PT_GT = 271,\n     PT_LTOREQUAL = 272,\n     PT_GTOREQUAL = 273,\n     PT_PLUS = 274,\n     PT_MINUS = 275,\n     PT_ASTERISK = 276,\n     PT_SLASH = 277,\n     PT_PERCENT = 278,\n     PT_EXCLAMATION = 279,\n     PT_UN = 280,\n     PT_SYMBOL = 281,\n     PT_NUM = 282\n   };\n#endif\n\n\n\n#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED\ntypedef union YYSTYPE\n{\n\n/* Line 1676 of yacc.c  */\n#line 49 \"tjspp.y\"\n\n\ttjs_int32\t\tval;\n\ttjs_int\t\t\tnv;\n\n\n\n/* Line 1676 of yacc.c  */\n#line 86 \"tjspp.tab.hpp\"\n} YYSTYPE;\n# define YYSTYPE_IS_TRIVIAL 1\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n#endif\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/core/utils/ClipboardIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Clipboard Class interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"ClipboardIntf.h\"\n\n\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_BaseClipboard::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *dsp)\n{\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_BaseClipboard::Invalidate()\n{\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Clipboard::ClassID = -1;\n//---------------------------------------------------------------------------\ntTJSNC_Clipboard::tTJSNC_Clipboard(): inherited(TJS_W(\"Clipboard\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Clipboard) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Clipboard)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Clipboard)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/hasFormat)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTVPClipboardFormat format  = (tTVPClipboardFormat)(tjs_int)*param[0];\n\n\tbool has = TVPClipboardHasFormat(format);\n\n\tif(result)\n\t\t*result = has;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/hasFormat)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(asText)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tttstr text;\n\t\tbool got = TVPClipboardGetText(text);\n\t\tif(got)\n\t\t\t*result = text;\n\t\telse\n\t\t\tresult->Clear();\n\t\t\t// returns void if the clipboard does not have a text data\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPClipboardSetText(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(asText)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Clipboard\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Clipboard::CreateNativeInstance()\n{\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Clipboard()\n{\n\ttTJSNativeClass *cls = new tTJSNC_Clipboard();\n\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/utils/ClipboardIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Clipboard Class interface\n//---------------------------------------------------------------------------\n#ifndef ClipboardIntfH\n#define ClipboardIntfH\n#include \"tjsNative.h\"\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTVPClipboardFormat\n//---------------------------------------------------------------------------\nenum tTVPClipboardFormat\n{\n\tcbfText = 1\n};\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// implement these in each platform\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(bool, TVPClipboardHasFormat, (tTVPClipboardFormat format));\nTJS_EXP_FUNC_DEF(void, TVPClipboardSetText, (const ttstr & text));\nTJS_EXP_FUNC_DEF(bool, TVPClipboardGetText, (ttstr & text));\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseClipboard\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseClipboard : public tTJSNativeInstance\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *dsp);\n\tvirtual void TJS_INTF_METHOD\n\t\tInvalidate();\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTJSNC_Clipboard : TJS Clipboard Class\n//---------------------------------------------------------------------------\nclass tTJSNC_Clipboard : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\npublic:\n\ttTJSNC_Clipboard();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Clipboard();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/DebugIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Utilities for Debugging\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <deque>\n#include <algorithm>\n#include <time.h>\n#include \"DebugIntf.h\"\n#include \"MsgIntf.h\"\n#include \"StorageIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"SysInitImpl.h\"\n#ifdef ENABLE_DEBUGGER\n#include \"tjsDebug.h\"\n#endif // ENABLE_DEBUGGER\n\n#include \"Application.h\"\n#include \"SystemControl.h\"\n//---------------------------------------------------------------------------\n// global variables\n//---------------------------------------------------------------------------\nstruct tTVPLogItem\n{\n\tttstr Log;\n\tttstr Time;\n\ttTVPLogItem(const ttstr &log, const ttstr &time)\n\t{\n\t\tLog = log;\n\t\tTime = time;\n\t}\n};\nstatic std::deque<tTVPLogItem> *TVPLogDeque = NULL;\nstatic tjs_uint TVPLogMaxLines = 2048;\n\nbool TVPAutoLogToFileOnError = true;\nbool TVPAutoClearLogOnError = false;\nbool TVPLoggingToFile = false;\nstatic tjs_uint TVPLogToFileRollBack = 100;\nstatic ttstr *TVPImportantLogs = NULL;\nstatic ttstr TVPLogLocation;\nttstr TVPNativeLogLocation;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic bool TVPLogObjectsInitialized = false;\nstatic void TVPEnsureLogObjects()\n{\n\tif(TVPLogObjectsInitialized) return;\n\tTVPLogObjectsInitialized = true;\n\n\tTVPLogDeque = new std::deque<tTVPLogItem>();\n\tTVPImportantLogs = new ttstr();\n}\n//---------------------------------------------------------------------------\nstatic void TVPDestroyLogObjects()\n{\n\tif(TVPLogDeque) delete TVPLogDeque, TVPLogDeque = NULL;\n\tif(TVPImportantLogs) delete TVPImportantLogs, TVPImportantLogs = NULL;\n}\n//---------------------------------------------------------------------------\ntTVPAtExit TVPDestroyLogObjectsAtExit\n\t(TVP_ATEXIT_PRI_CLEANUP, TVPDestroyLogObjects);\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\nvoid (*TVPOnLog)(const ttstr & line) = NULL;\n\t// this function is invoked when a line is logged\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPSetOnLog\n//---------------------------------------------------------------------------\nvoid TVPSetOnLog(void (*func)(const ttstr & line))\n{\n\tTVPOnLog = func;\n}\n//---------------------------------------------------------------------------\nstatic std::vector<tTJSVariantClosure> TVPLoggingHandlerVector;\n\nstatic void TVPCleanupLoggingHandlerVector()\n{\n\t// eliminate empty\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\tfor(i = TVPLoggingHandlerVector.begin();\n\t\ti != TVPLoggingHandlerVector.end();\n\t\ti++)\n\t{\n\t\tif(!i->Object)\n\t\t{\n\t\t\ti->Release();\n\t\t\ti = TVPLoggingHandlerVector.erase(i);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ti++;\n\t\t}\n\t}\n}\nstatic void TVPDestroyLoggingHandlerVector()\n{\n\tTVPSetOnLog(NULL);\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\tfor(i = TVPLoggingHandlerVector.begin();\n\t\ti != TVPLoggingHandlerVector.end();\n\t\ti++)\n\t{\n\t\ti->Release();\n\t}\n\tTVPLoggingHandlerVector.clear();\n}\n\nstatic tTVPAtExit TVPDestroyLoggingHandlerAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPDestroyLoggingHandlerVector);\n//---------------------------------------------------------------------------\nstatic bool TVPInDeliverLoggingEvent = false;\nstatic void _TVPDeliverLoggingEvent(const ttstr & line) // internal\n{\n\tif(!TVPInDeliverLoggingEvent)\n\t{\n\t\tTVPInDeliverLoggingEvent = true;\n\t\ttry\n\t\t{\n\t\t\tif(TVPLoggingHandlerVector.size())\n\t\t\t{\n\t\t\t\tbool emptyflag = false;\n\t\t\t\ttTJSVariant vline(line);\n\t\t\t\ttTJSVariant *pvline[] = { &vline };\n\t\t\t\tfor(tjs_uint i = 0; i < TVPLoggingHandlerVector.size(); i++)\n\t\t\t\t{\n\t\t\t\t\tif(TVPLoggingHandlerVector[i].Object)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_error er;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ter =\n\t\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].FuncCall(0, NULL, NULL, NULL, 1, pvline, NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(...)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// failed\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].Release();\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].Object =\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].ObjThis = NULL;\n\t\t\t\t\t\t\tthrow;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(TJS_FAILED(er))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// failed\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].Release();\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].Object =\n\t\t\t\t\t\t\tTVPLoggingHandlerVector[i].ObjThis = NULL;\n\t\t\t\t\t\t\temptyflag = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\temptyflag = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(emptyflag)\n\t\t\t\t{\n\t\t\t\t\t// the array has empty cell\n\t\t\t\t\tTVPCleanupLoggingHandlerVector();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!TVPLoggingHandlerVector.size())\n\t\t\t{\n\t\t\t\tTVPSetOnLog(NULL);\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPInDeliverLoggingEvent = false;\n\t\t\tthrow;\n\t\t}\n\t\tTVPInDeliverLoggingEvent = false;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPAddLoggingHandler(tTJSVariantClosure clo)\n{\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\ti = std::find(TVPLoggingHandlerVector.begin(),\n\t\tTVPLoggingHandlerVector.end(), clo);\n\tif(i == TVPLoggingHandlerVector.end())\n\t{\n\t\tclo.AddRef();\n\t\tTVPLoggingHandlerVector.push_back(clo);\n\t\tTVPSetOnLog(&_TVPDeliverLoggingEvent);\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPRemoveLoggingHandler(tTJSVariantClosure clo)\n{\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\ti = std::find(TVPLoggingHandlerVector.begin(),\n\t\tTVPLoggingHandlerVector.end(), clo);\n\tif(i != TVPLoggingHandlerVector.end())\n\t{\n\t\ti->Release();\n\t\ti->Object = i->ObjThis = NULL;\n\t}\n\n\tif(!TVPInDeliverLoggingEvent)\n\t{\n\t\tTVPCleanupLoggingHandlerVector();\n\t\tif(!TVPLoggingHandlerVector.size())\n\t\t{\n\t\t\tTVPSetOnLog(NULL);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// log stream holder\n//---------------------------------------------------------------------------\nclass tTVPLogStreamHolder\n{\n\tFILE * Stream;\n\tbool Alive;\n\tbool OpenFailed;\n\npublic:\n\ttTVPLogStreamHolder() { Stream = NULL; Alive = true; OpenFailed = false; }\n\t~tTVPLogStreamHolder() { if(Stream) fclose(Stream); Alive = false; }\n\nprivate:\n\tvoid Open(const tjs_nchar *mode);\n\npublic:\n\tvoid Clear(); // clear log stream\n\tvoid Log(const ttstr & text); // log given text\n\n\tvoid Reopen() { if(Stream) fclose(Stream); Stream = NULL; Alive = false; OpenFailed = false; } // reopen log stream\n\n} static TVPLogStreamHolder;\n//---------------------------------------------------------------------------\nvoid tTVPLogStreamHolder::Open(const tjs_nchar *mode)\n{\n\tif(OpenFailed) return; // no more try\n\n\ttry\n\t{\n\t\tttstr filename;\n\t\tif(TVPLogLocation.GetLen() == 0)\n\t\t{\n\t\t\tStream = NULL;\n\t\t\tOpenFailed = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// no log location specified\n\t\t\tfilename = TVPNativeLogLocation + TJS_W(\"/krkr.console.log\");\n\t\t\tTVPEnsureDataPathDirectory();\n\t\t\tstd::string _filename = filename.AsNarrowStdString();\n\t\t\tStream = fopen(_filename.c_str(), mode);\n\t\t\tif(!Stream) OpenFailed = true;\n\t\t}\n\n\t\tif(Stream)\n\t\t{\n\t\t\tfseek(Stream, 0, SEEK_END);\n\t\t\tif(ftell(Stream) == 0)\n\t\t\t{\n\t\t\t\t// write BOM\n\t\t\t\t// TODO: 32-bit unicode support\n\t\t\t\tfwrite(TJS_N(\"\\xff\\xfe\"), 1, 2, Stream); // indicate unicode text\n\t\t\t}\n\n#ifdef TJS_TEXT_OUT_CRLF\n\t\t\tttstr separator( TVPSeparatorCRLF );\n#else\n\t\t\tttstr separator( TVPSeparatorCR );\n#endif\n\t\t\tLog(separator);\n\n\n\t\t\tstatic tjs_char timebuf[80];\n\n\t\t\ttm *struct_tm;\n\t\t\ttime_t timer;\n\t\t\ttimer = time(&timer);\n\n\t\t\tstruct_tm = localtime(&timer);\n\t\t\tTJS_strftime(timebuf, 79, TJS_W(\"%#c\"), struct_tm);\n\n\t\t\tLog(ttstr(TJS_W(\"Logging to \")) + ttstr(filename) + TJS_W(\" started on \") + timebuf);\n\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tOpenFailed = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLogStreamHolder::Clear()\n{\n\t// clear log text\n\tif(Stream) fclose(Stream);\n\n\tOpen(TJS_N(\"wb\"));\n}\n//---------------------------------------------------------------------------\nvoid tTVPLogStreamHolder::Log(const ttstr & text)\n{\n\tif(!Stream) Open(TJS_N(\"ab\"));\n\n\ttry\n\t{\n\t\tif(Stream)\n\t\t{\n\t\t\tsize_t len = text.GetLen() * sizeof(tjs_char);\n\t\t\tif(len != fwrite(text.c_str(), 1, len, Stream))\n\t\t\t{\n\t\t\t\t// cannot write\n\t\t\t\tfclose(Stream);\n\t\t\t\tOpenFailed = true;\n\t\t\t\treturn;\n\t\t\t}\n\t#ifdef TJS_TEXT_OUT_CRLF\n\t\t\tfwrite(TJS_W(\"\\r\\n\"), 1, 2 * sizeof(tjs_char), Stream);\n\t#else\n\t\t\tfwrite(TJS_W(\"\\n\"), 1, 1 * sizeof(tjs_char), Stream);\n\t#endif\n\n\t\t\t// flush\n\t\t\tfflush(Stream);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif(Stream) fclose(Stream);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t}\n\n\t\tOpenFailed = true;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPAddLog\n//---------------------------------------------------------------------------\nvoid TVPAddLog(const ttstr &line, bool appendtoimportant)\n{\n\t// add a line to the log.\n\t// exceeded lines over TVPLogMaxLines are eliminated.\n\t// this function is not thread-safe ...\n\n\tTVPEnsureLogObjects();\n\tif(!TVPLogDeque) return; // log system is shuttingdown\n\tif(!TVPImportantLogs) return; // log system is shuttingdown\n\n\tstatic time_t prevlogtime = 0;\n\tstatic ttstr prevtimebuf;\n\tstatic tjs_char timebuf[40];\n\n\ttm *struct_tm;\n\ttime_t timer;\n\ttimer = time(&timer);\n\n\tif(prevlogtime != timer)\n\t{\n\t\tstruct_tm = localtime(&timer);\n\t\tTJS_strftime(timebuf, 39, TJS_W(\"%H:%M:%S\"), struct_tm);\n\t\tprevlogtime = timer;\n\t\tprevtimebuf = timebuf;\n\t}\n\n\tTVPLogDeque->push_back(tTVPLogItem(line, prevtimebuf));\n\n\tif(appendtoimportant)\n\t{\n#ifdef TJS_TEXT_OUT_CRLF\n\t\t*TVPImportantLogs += ttstr(timebuf) + TJS_W(\" ! \") + line + TJS_W(\"\\r\\n\");\n#else\n\t\t*TVPImportantLogs += ttstr(timebuf) + TJS_W(\" ! \") + line + TJS_W(\"\\n\");\n#endif\n\t}\n\twhile(TVPLogDeque->size() >= TVPLogMaxLines+100)\n\t{\n\t\tstd::deque<tTVPLogItem>::iterator i = TVPLogDeque->begin();\n\t\tTVPLogDeque->erase(i, i+100);\n\t}\n\n\ttjs_int timebuflen = (tjs_int)TJS_strlen(timebuf);\n\tttstr buf((tTJSStringBufferLength)(timebuflen + 1 + line.GetLen()));\n\ttjs_char * p = buf.Independ();\n\tTJS_strcpy(p, timebuf);\n\tp += timebuflen;\n\t*p = TJS_W(' ');\n\tp++;\n\tTJS_strcpy(p, line.c_str());\n\tif(TVPOnLog) TVPOnLog(buf);\n#ifdef ENABLE_DEBUGGER\n\tif( TJSEnableDebugMode ) TJSDebuggerLog(buf,appendtoimportant);\n\t//OutputDebugStringW( buf.c_str() );\n\t//OutputDebugStringW( L\"\\n\" );\n#endif\t// ENABLE_DEBUGGER\n\n\tApplication->PrintConsole( buf, appendtoimportant );\n\n\tif(TVPLoggingToFile) TVPLogStreamHolder.Log(buf);\n}\n//---------------------------------------------------------------------------\nvoid TVPAddLog(const ttstr &line)\n{\n\tTVPAddLog(line, false);\n}\n//---------------------------------------------------------------------------\nvoid TVPAddImportantLog(const ttstr &line)\n{\n\tTVPAddLog(line, true);\n}\n//---------------------------------------------------------------------------\nttstr TVPGetImportantLog()\n{\n\tif(!TVPImportantLogs) return ttstr();\n\treturn *TVPImportantLogs;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetLastLog : get last n lines of the log ( each line is spearated with '\\n'/'\\r\\n' )\n//---------------------------------------------------------------------------\nttstr TVPGetLastLog(tjs_uint n)\n{\n\tTVPEnsureLogObjects();\n\tif(!TVPLogDeque) return TJS_W(\"\"); // log system is shuttingdown\n\n\ttjs_uint len = 0;\n\ttjs_uint size = (tjs_uint)TVPLogDeque->size();\n\tif(n > size) n = size;\n\tif(n==0) return ttstr();\n\tstd::deque<tTVPLogItem>::iterator i = TVPLogDeque->end();\n\ti-=n;\n\ttjs_uint c;\n\tfor(c = 0; c<n; c++, i++)\n\t{\n#ifdef TJS_TEXT_OUT_CRLF\n\t\tlen += i->Time.GetLen() + 1 +  i->Log.GetLen() + 2;\n#else\n\t\tlen += i->Time.GetLen() + 1 +  i->Log.GetLen() + 1;\n#endif\n\t}\n\n\tttstr buf((tTJSStringBufferLength)len);\n\ttjs_char *p = buf.Independ();\n\n\ti = TVPLogDeque->end();\n\ti -= n;\n\tfor(c = 0; c<n; c++)\n\t{\n\t\tTJS_strcpy(p, i->Time.c_str());\n\t\tp += i->Time.GetLen();\n\t\t*p = TJS_W(' ');\n\t\tp++;\n\t\tTJS_strcpy(p, i->Log.c_str());\n\t\tp += i->Log.GetLen();\n#ifdef TJS_TEXT_OUT_CRLF\n\t\t*p = TJS_W('\\r');\n\t\tp++;\n\t\t*p = TJS_W('\\n');\n\t\tp++;\n#else\n\t\t*p = TJS_W('\\n');\n\t\tp++;\n#endif\n\t\ti++;\n\t}\n\treturn buf;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPStartLogToFile\n//---------------------------------------------------------------------------\nvoid TVPStartLogToFile(bool clear)\n{\n\tTVPEnsureLogObjects();\n\tif(!TVPImportantLogs) return; // log system is shuttingdown\n\n\tif(TVPLoggingToFile) return; // already logging\n\tif(clear) TVPLogStreamHolder.Clear();\n\n\t// log last lines\n\n\tTVPLogStreamHolder.Log(*TVPImportantLogs);\n\n#ifdef TJS_TEXT_OUT_CRLF\n\tttstr separator(TJS_W(\"\\r\\n\")\nTJS_W(\"------------------------------------------------------------------------------\\r\\n\"\n\t\t\t\t));\n#else\n\tttstr separator(TJS_W(\"\\n\")\nTJS_W(\"------------------------------------------------------------------------------\\n\"\n\t\t\t\t));\n#endif\n\n\tTVPLogStreamHolder.Log(separator);\n\n\tttstr content = TVPGetLastLog(TVPLogToFileRollBack);\n\tTVPLogStreamHolder.Log(content);\n\n\t//\n\tTVPLoggingToFile = true;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPOnError\n//---------------------------------------------------------------------------\nvoid TVPOnError()\n{\n\tif(TVPAutoLogToFileOnError) TVPStartLogToFile(TVPAutoClearLogOnError);\n\t// TVPOnErrorHook();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPSetLogLocation\n//---------------------------------------------------------------------------\nvoid TVPSetLogLocation(const ttstr &loc)\n{\n\tTVPLogLocation = TVPNormalizeStorageName(loc);\n\n\tttstr native = TVPGetLocallyAccessibleName(TVPLogLocation);\n\tif(native.IsEmpty())\n\t{\n\t\tTVPNativeLogLocation.Clear();\n\t\tTVPLogLocation.Clear();\n\t}\n\telse\n\t{\n\t\tTVPNativeLogLocation = native;\n\t\tif (TVPNativeLogLocation[TVPNativeLogLocation.length() - 1] != TJS_W('/'))\n\t\t\tTVPNativeLogLocation += TJS_W(\"/\");\n\t}\n\n\tTVPLogStreamHolder.Reopen();\n\n\t// check force logging option\n\ttTJSVariant val;\n\tif(TVPGetCommandLine(TJS_W(\"-forcelog\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t{\n\t\t\tTVPLoggingToFile = false;\n\t\t\tTVPStartLogToFile(false);\n\t\t}\n\t\telse if(str == TJS_W(\"clear\"))\n\t\t{\n\t\t\tTVPLoggingToFile = false;\n\t\t\tTVPStartLogToFile(true);\n\t\t}\n\t}\n\tif(TVPGetCommandLine(TJS_W(\"-logerror\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"no\"))\n\t\t{\n\t\t\tTVPAutoClearLogOnError = false;\n\t\t\tTVPAutoLogToFileOnError = false;\n\t\t}\n\t\telse if(str == TJS_W(\"clear\"))\n\t\t{\n\t\t\tTVPAutoClearLogOnError = true;\n\t\t\tTVPAutoLogToFileOnError = true;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Debug\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Debug::ClassID = -1;\ntTJSNC_Debug::tTJSNC_Debug() : tTJSNativeClass(TJS_W(\"Debug\"))\n{\n\tTJS_BEGIN_NATIVE_MEMBERS(Debug)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Debug)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Debug)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/message)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(numparams == 1)\n\t{\n\t\tTVPAddLog(*param[0]);\n\t}\n\telse\n\t{\n\t\t// display the arguments separated with \", \"\n\t\tttstr args;\n\t\tfor(int i = 0; i<numparams; i++)\n\t\t{\n\t\t\tif(i != 0) args += TJS_W(\", \");\n\t\t\targs += ttstr(*param[i]);\n\t\t}\n\t\tTVPAddLog(args);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/message)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/notice)\n{\n\tif(numparams<1) return TJS_E_BADPARAMCOUNT;\n\n\tif(numparams == 1)\n\t{\n\t\tTVPAddImportantLog(*param[0]);\n\t}\n\telse\n\t{\n\t\t// display the arguments separated with \", \"\n\t\tttstr args;\n\t\tfor(int i = 0; i<numparams; i++)\n\t\t{\n\t\t\tif(i != 0) args += TJS_W(\", \");\n\t\t\targs += ttstr(*param[i]);\n\t\t}\n\t\tTVPAddImportantLog(args);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/notice)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/startLogToFile)\n{\n\tbool clear = false;\n\n\tif(numparams >= 1)\n\t\tclear = param[0]->operator bool();\n\n\tTVPStartLogToFile(clear);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/startLogToFile)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/logAsError)\n{\n\tTVPOnError();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/logAsError)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addLoggingHandler)\n{\n\t// add function to logging handler list\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\n\tTVPAddLoggingHandler(clo);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/addLoggingHandler)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeLoggingHandler)\n{\n\t// remove function from logging handler list\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\n\tTVPRemoveLoggingHandler(clo);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/removeLoggingHandler)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getLastLog)\n{\n\ttjs_uint lines = TVPLogMaxLines + 100;\n\n\tif(numparams >= 1) lines = (tjs_uint)param[0]->AsInteger();\n\n\tif(result) *result = TVPGetLastLog(lines);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getLastLog)\n//---------------------------------------------------------------------------\n\n//-- properies\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(logLocation)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPLogLocation;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPSetLogLocation(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(logLocation)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(logToFileOnError)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPAutoLogToFileOnError;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPAutoLogToFileOnError = param->operator bool();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(logToFileOnError)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(clearLogFileOnError)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPAutoClearLogOnError;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPAutoClearLogOnError = param->operator bool();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(clearLogFileOnError)\n//----------------------------------------------------------------------\n\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n\t// put version information to DMS\n#if 0\n\tTVPAddImportantLog(TVPGetVersionInformation());\n\tTVPAddImportantLog(ttstr(TVPVersionInformation2));\n#endif\n} // end of tTJSNC_Debug::tTJSNC_Debug\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TJS2 Console Output Gateway\n//---------------------------------------------------------------------------\nclass tTVPTJS2ConsoleOutputGateway : public iTJSConsoleOutput\n{\n\tvoid ExceptionPrint(const tjs_char *msg)\n\t{\n\t\tTVPAddLog(msg);\n\t}\n\n\tvoid Print(const tjs_char *msg)\n\t{\n\t\tTVPAddLog(msg);\n\t}\n} static TVPTJS2ConsoleOutputGateway;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TJS2 Dump Output Gateway\n//---------------------------------------------------------------------------\nstatic ttstr TVPDumpOutFileName;\nstatic FILE *TVPDumpOutFile = NULL; // use traditional output routine\n//---------------------------------------------------------------------------\nclass tTVPTJS2DumpOutputGateway : public iTJSConsoleOutput\n{\n\tvoid ExceptionPrint(const tjs_char *msg) { Print(msg); }\n\n\tvoid Print(const tjs_char *msg)\n\t{\n\t\tif(TVPDumpOutFile)\n\t\t{\n\t\t\tfwrite(msg, 1, TJS_strlen(msg)*sizeof(tjs_char), TVPDumpOutFile);\n#ifdef TJS_TEXT_OUT_CRLF\n\t\t\tfwrite(TJS_W(\"\\r\\n\"), 1, 2 * sizeof(tjs_char), TVPDumpOutFile);\n#else\n\t\t\tfwrite(TJS_W(\"\\n\"), 1, 1 * sizeof(tjs_char), TVPDumpOutFile);\n#endif\n\t\t}\n\t}\n} static TVPTJS2DumpOutputGateway;\n//---------------------------------------------------------------------------\nvoid TVPTJS2StartDump()\n{\n#if 0\n\tttstr filename = ExePath() + TJS_W(\".dump.txt\");\n\tTVPDumpOutFileName = filename;\n\tTVPDumpOutFile = _wfopen(filename.c_str(), TJS_W(\"wb+\"));\n\tif(TVPDumpOutFile)\n\t{\n\t\t// TODO: 32-bit unicode support\n\t\tfwrite(TJS_N(\"\\xff\\xfe\"), 1, 2, TVPDumpOutFile); // indicate unicode text\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TVPTJS2EndDump()\n{\n#if 0\n\tif (TVPDumpOutFile)\n\t{\n\t\tfclose(TVPDumpOutFile), TVPDumpOutFile = NULL;\n\t\tTVPAddLog(ttstr(TJS_W(\"Dumped to \")) + TVPDumpOutFileName);\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// console interface retrieving functions\n//---------------------------------------------------------------------------\niTJSConsoleOutput *TVPGetTJS2ConsoleOutputGateway()\n{\n\treturn & TVPTJS2ConsoleOutputGateway;\n}\n//---------------------------------------------------------------------------\niTJSConsoleOutput *TVPGetTJS2DumpOutputGateway()\n{\n\treturn & TVPTJS2DumpOutputGateway;\n}\n//---------------------------------------------------------------------------\n\n/*\n//---------------------------------------------------------------------------\n// on-error hook\n//---------------------------------------------------------------------------\nvoid TVPOnErrorHook()\n{\n\tif(TVPMainForm) TVPMainForm->NotifySystemError();\n}\n//---------------------------------------------------------------------------\n*/\n"
  },
  {
    "path": "src/core/utils/DebugIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Utilities for Debugging\n//---------------------------------------------------------------------------\n#ifndef DebugIntfH\n#define DebugIntfH\n\n#include \"tjsNative.h\"\n\n//---------------------------------------------------------------------------\n// global definitions\n//---------------------------------------------------------------------------\nextern bool TVPAutoLogToFileOnError;\nextern bool TVPAutoClearLogOnError;\nextern bool TVPLoggingToFile;\nextern void TVPSetOnLog(void (*func)(const ttstr & line));\nTJS_EXP_FUNC_DEF(void, TVPAddLog, (const ttstr &line));\nTJS_EXP_FUNC_DEF(void, TVPAddImportantLog, (const ttstr &line));\nextern ttstr TVPGetLastLog(tjs_uint n);\nextern iTJSConsoleOutput * TVPGetTJS2ConsoleOutputGateway();\nextern iTJSConsoleOutput * TVPGetTJS2DumpOutputGateway();\nextern void TVPTJS2StartDump();\nextern void TVPTJS2EndDump();\nextern void TVPOnError();\nextern ttstr TVPGetImportantLog();\nextern void TVPSetLogLocation(const ttstr &loc);\nextern ttstr TVPNativeLogLocation;\nextern void TVPStartLogToFile(bool clear);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// implement in each platform\n//---------------------------------------------------------------------------\n//extern void TVPOnErrorHook();\n\t// called from TVPOnError, on system error.\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Debug : TJS Debug Class\n//---------------------------------------------------------------------------\nclass tTJSNC_Debug : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Debug();\n\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance * CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Debug();\n//---------------------------------------------------------------------------\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/utils/Debugger.h",
    "content": "/****************************************************************************/\n/*! @file\n@brief u[N|Cĝt@Cƍsԍێ\n\n-----------------------------------------------------------------------------\n\tCopyright (C) T.Imoto <http://www.kaede-software.com>\n-----------------------------------------------------------------------------\n@author\t\tT.Imoto\n@date\t\t2010/04/18\n@note\n*****************************************************************************/\n\n#ifndef __DEBUGGER_H__\n#define __DEBUGGER_H__\n\n#include <map>\n#include <string>\n#include <assert.h>\n\nenum tTJSDBGHOOKType {\n\tDBGHOOK_PREV_EXE_LINE,\t//!< Cs\n\tDBGHOOK_PREV_CALL,\t\t//!< ֐R[\n\tDBGHOOK_PREV_RETURN,\t//!< ^[\n\tDBGHOOK_PREV_EXCEPT,\t//!< Oˏo\n\tDBGHOOK_PREV_BREAK,\t\t//!< XNvg̃u[N\n};\n// gee = debuggee\n// ger = debugger\nenum tTJSDBGEvent {\n\tDBGEV_GEE_LOG = 0x8000,\t\t//!< gee -> ger Oo (lɓɈӖ͂Ȃ)\n\tDBGEV_GEE_BREAK,\t\t\t//!< gee -> ger ~ʒm\n\tDBGEV_GEE_STACK_TRACE,\t\t//!< gee -> ger X^bNg[Xʒm\n\tDBGEV_GEE_LOCAL_VALUE,\t\t//!< gee -> ger [Jϐ\n\tDBGEV_GEE_REQUEST_SETTINGS,\t//!< gee -> ger OʒmLAu[N|Cg񓙂v\n\tDBGEV_GEE_CLASS_VALUE,\t\t//!< gee -> ger NXϐ\n\n\tDBGEV_GER_EXEC = 0x9000,\t//!< ger -> gee s\n\tDBGEV_GER_BREAK,\t\t\t//!< ger -> gee ꎞ~\n\tDBGEV_GER_STEP,\t\t\t\t//!< ger -> gee Xebv\n\tDBGEV_GER_TRACE,\t\t\t//!< ger -> gee g[X\n\tDBGEV_GER_RETURN,\t\t\t//!< ger -> gee ^[\n\tDBGEV_GER_BREAKPOINT_START,\t//!< ger -> gee u[N|Cg񑗐MJn\n\tDBGEV_GER_BREAKPOINT,\t\t//!< ger -> gee u[N|Cg\n\tDBGEV_GER_BREAKPOINT_END,\t//!< ger -> gee u[N|Cg񑗐MI\n\tDBGEV_GER_EXCEPTION_FLG,\t//!< ger -> gee Oɒ~邩ǂ\n};\n\nstruct BreakpointLine {\n\ttypedef std::map<int,int>\t\tlines;\n\ttypedef lines::iterator\t\t\titerator;\n\ttypedef lines::const_iterator\tconst_iterator;\n\n\tlines\tLines;\n\n\tbool IsBreakPoint( int lineno ) const {\n\t\tconst_iterator j = Lines.find( lineno );\n\t\tif( j != Lines.end() ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tvoid SetBreakPoint( int lineno ) {\n\t\titerator i = Lines.find( lineno );\n\t\tif( i == Lines.end() ) {\n\t\t\tstd::pair<iterator, bool> ret = Lines.insert( BreakpointLine::lines::value_type( lineno, lineno ) );\n\t\t\tassert( ret.second );\n\t\t}\n\t}\n\tvoid ClearBreakPoint( int lineno ) {\n\t\tLines.erase( lineno );\n\t}\n};\n\nstruct Breakpoints {\n\ttypedef std::map<std::wstring,BreakpointLine>\tbreakpoints;\n\ttypedef breakpoints::iterator\t\t\t\t\titerator;\n\ttypedef breakpoints::const_iterator\t\t\t\tconst_iterator;\n\n\tbreakpoints BreakPoint;\n\n\tvoid SetBreakPoint( const std::wstring& filename, int lineno ) {\n\t\titerator i = BreakPoint.find( filename );\n\t\tif( i == BreakPoint.end() ) {\n\t\t\tstd::pair<iterator, bool> ret = BreakPoint.insert( breakpoints::value_type( filename, BreakpointLine() ) );\n\t\t\tassert( ret.second );\n\t\t\ti = ret.first;\n\t\t}\n\t\ti->second.SetBreakPoint(lineno);\n\t}\n\tvoid ClearBreakPoint( const std::wstring& filename, int lineno ) {\n\t\titerator i = BreakPoint.find( filename );\n\t\tif( i == BreakPoint.end() ) {\n\t\t\treturn;\n\t\t}\n\t\ti->second.ClearBreakPoint( lineno );\n\t}\n\tbool IsBreakPoint( const std::wstring& filename, int lineno ) const {\n\t\tconst_iterator i = BreakPoint.find( filename );\n\t\tif( i != BreakPoint.end() ) {\n\t\t\treturn i->second.IsBreakPoint(lineno);\n\t\t}\n\t\treturn false;\n\t}\n\tconst BreakpointLine* GetBreakPointLines( const std::wstring& filename ) const {\n\t\tconst_iterator i = BreakPoint.find( filename );\n\t\tif( i != BreakPoint.end() ) {\n\t\t\treturn &(i->second);\n\t\t}\n\t\treturn NULL;\n\t}\n\tBreakpointLine* GetBreakPointLines( const std::wstring& filename ) {\n\t\titerator i = BreakPoint.find( filename );\n\t\tif( i != BreakPoint.end() ) {\n\t\t\treturn &(i->second);\n\t\t}\n\t\treturn NULL;\n\t}\n\tbool HasBreakPoint( const std::wstring& filename ) {\n\t\titerator i = BreakPoint.find( filename );\n\t\tif( i != BreakPoint.end() ) {\n\t\t\treturn( i->second.Lines.size() > 0 );\n\t\t}\n\t\treturn false;\n\t}\n\tvoid ClearAll() {\n\t\tBreakPoint.clear();\n\t}\n};\n\n\n\n#endif // __DEBUGGER_H__\n"
  },
  {
    "path": "src/core/utils/Exception.h",
    "content": "\n#ifndef __EXCEPTION_H__\n#define __EXCEPTION_H__\n\n\nclass Exception /*: public std::exception*/ {\n\tttstr message_;\npublic:\n\tException(const ttstr& mes) : message_(mes) {\n\t}\n\tvirtual const ttstr& what() const {\n\t\treturn message_;\n\t}\n};\n\nclass EAbort : public Exception {\npublic:\n\tEAbort(const ttstr& mes) : Exception(mes) {\n\t}\n};\n\n#endif // __EXCEPTION_H__\n"
  },
  {
    "path": "src/core/utils/FilePathUtil.h",
    "content": "\n#ifndef __FILE_PATH_UTIL_H__\n#define __FILE_PATH_UTIL_H__\n\n#include <string>\n#include <stdlib.h>\n\n#if 0\n#include <shlwapi.h>\n#include <winnetwk.h>\n#endif\n\nstatic std::string IncludeTrailingBackslash(const std::string & path)\n{\n\tint n = path.length();\n\n\tif ( n == 0 )\n\t\treturn \"/\";\n\tswitch (path.c_str()[n - 1])\n\t{\n\tcase '\\\\':\n\tcase '/':\n\t\treturn path;\n\tdefault:\n\t\treturn path + '/';\n\t}\n}\n\nstatic ttstr IncludeTrailingBackslash(const ttstr& path) {\n\tint n = path.length();\n\tif (n == 0) return TJS_W(\"/\");\n\tswitch (path.c_str()[n - 1])\n\t{\n\tcase '\\\\':\n\tcase '/':\n\t\treturn path;\n\tdefault:\n\t\treturn path + '/';\n\t}\n\n#if 0\n\tif (path[path.length() - 1] != L'\\\\') {\n\t\treturn std::wstring(path+L\"\\\\\");\n\t}\n\treturn std::wstring(path);\n#endif\n}\ninline ttstr ExcludeTrailingBackslash(const ttstr& path) {\n\tif( path[path.length()-1] == L'\\\\' ) {\n\t\treturn ttstr(path, path.length() - 1);\n\t}\n\treturn path;\n}\n\nextern std::string ExtractFileDir(const std::string & FileName);\ninline ttstr ExtractFileDir(const ttstr& path) {\n\treturn ExtractFileDir(path.AsNarrowStdString());\n#if 0\n\twchar_t drive[_MAX_DRIVE];\n\twchar_t dir[_MAX_DIR];\n#ifdef _WIN32\n\t_wsplitpath_s(path.c_str(), drive, _MAX_DRIVE, dir,_MAX_DIR, NULL, 0, NULL, 0 );\n#else\n\twsplitpath(path.c_str(), drive, dir, NULL, NULL );\n#endif\n\tstd::wstring dirstr = std::wstring( dir );\n\tif( dirstr[dirstr.length()-1] != L'\\\\' ) {\n\t\treturn std::wstring( drive ) + dirstr;\n\t} else {\n\t\treturn std::wstring( drive ) + dirstr.substr(0,dirstr.length()-1);\n\t}\n#endif\n}\n#if 0\ninline std::wstring ExtractFilePath(const std::wstring& path) {\n\twchar_t drive[MAX_PATH];\n\twchar_t dir[MAX_PATH];\n#ifdef _WIN32\n\t_wsplitpath_s(path.c_str(), drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0);\n#else\n\twsplitpath(path.c_str(), drive, dir, NULL, NULL );\n#endif\n\treturn std::wstring(drive) + std::wstring(dir);\n}\n\n#define DirectoryExists TVPCheckExistentLocalFolder\n#define FileExists TVPCheckExistentLocalFile\ninline std::wstring ChangeFileExt( const std::wstring& path, const std::wstring& ext ) {\n\twchar_t drive[_MAX_DRIVE];\n\twchar_t dir[_MAX_DIR];\n\twchar_t fname[_MAX_FNAME];\n#ifdef _WIN32\n\t_wsplitpath_s( path.c_str(), drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, NULL, 0 );\n#else\n\twsplitpath( path.c_str(), drive, dir, fname, NULL );\n#endif\n\treturn std::wstring( drive ) + std::wstring( dir ) + std::wstring( fname ) + ext;\n}\ninline std::wstring ExtractFileName( const std::wstring& path ) {\n\twchar_t fname[_MAX_FNAME];\n\twchar_t ext[_MAX_EXT];\n#ifdef _WIN32\n\t_wsplitpath_s( path.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT );\n#else\n\twsplitpath( path.c_str(), NULL, NULL, fname, ext );\n#endif\n\treturn std::wstring( fname ) + std::wstring( ext );\n}\ninline std::wstring ExpandUNCFileName( const std::wstring& path ) {\n#ifdef _WIN32\n\tstd::wstring result;\n\tDWORD InfoSize = 0;\n\tif( ERROR_MORE_DATA == WNetGetUniversalName( path.c_str(), UNIVERSAL_NAME_INFO_LEVEL, NULL, &InfoSize) ) {\n\t\tUNIVERSAL_NAME_INFO* pInfo = reinterpret_cast<UNIVERSAL_NAME_INFO*>( ::GlobalAlloc(GMEM_FIXED, InfoSize) );\n\t\tDWORD ret = ::WNetGetUniversalName( path.c_str(), UNIVERSAL_NAME_INFO_LEVEL, pInfo, &InfoSize);\n\t\tif( NO_ERROR == ret ) {\n\t\t\tresult = std::wstring(pInfo->lpUniversalName);\n\t\t}\n\t\t::GlobalFree(pInfo);\n\t} else {\n\t\twchar_t fullpath[_MAX_PATH];\n\t\tresult = std::wstring( _wfullpath( fullpath, path.c_str(), _MAX_PATH ) );\n\t}\n\treturn result;\n#else\n\t#error Not Implemented yet.\n#endif\n}\n#endif\n#endif // __FILE_PATH_UTIL_H__\n"
  },
  {
    "path": "src/core/utils/KAGParser.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// KAG Parser Utility Class\n//---------------------------------------------------------------------------\n\n#include \"KAGParser.h\"\n#include \"EventIntf.h\"\nnamespace TJS { ttstr TJSMapGlobalStringMap(const ttstr & string); }\n\n//---------------------------------------------------------------------------\n/*\n  KAG System (Kirikiri Adventure Game System) is an application script for\n  TVP(Kirikiri), providing core system for Adventure Game/Visual Novel.\n  KAG has a simple tag-based mark-up language (\"scenario file\").\n  Version under 2.x of KAG is slow since the parser is written in TJS1.\n  KAG 3.x uses TVP's internal KAG parser written in C++ in this unit, will\n  acquire speed in compensation for ability of customizing.\n*/\n//---------------------------------------------------------------------------\n// #define TJS_strchr\t\t\twcschr\n// #define TJS_strcmp\t\t\twcscmp\n//#define TJS_strncpy\t\t\twcsncpy_s\n\nconst tjs_char* TVPKAGNoLine = TJS_W(\"Readed scenario file %1 is empty.\");\nconst tjs_char* TVPKAGCannotOmmitFirstLabelName = TJS_W(\"Can not ommit first label name in scenario.\");\n//const tjs_char* TVPInternalError = TJS_W(\"内部エラーが発生しました: at %1 line %2\");\nconst tjs_char* TVPKAGMalformedSaveData = TJS_W(\"Malformed savedata, data may damaged.\");\nconst tjs_char* TVPKAGLabelNotFound = TJS_W(\"Label %2 not found in scenario file %1.\");\nconst tjs_char* TVPLabelOrScriptInMacro = TJS_W(\"Label in macro 'iscript' is illegal.\");\nconst tjs_char* TVPKAGInlineScriptNotEnd = TJS_W(\"Matched [endscript] or @endscript not found.\");\nconst tjs_char* TVPKAGSyntaxError = TJS_W(\"Syntax error.'[' match to ']', \\\" match to \\\", 'macro' march to 'endmacro'. Notice space and newline.\");\nconst tjs_char* TVPKAGCallStackUnderflow = TJS_W(\"'return' is not matched to any 'call' ( 'return' is unexpected )\");\nconst tjs_char* TVPKAGReturnLostSync = TJS_W(\"Lost return position due to the scenario file changed.\");\nconst tjs_char* TVPKAGSpecifyKAGParser = TJS_W(\"Please specify KAGParser object.\");\nconst tjs_char* TVPUnknownMacroName = TJS_W(\"Unknown macro \\\"%1\\\"\");\n\n#define TVPThrowInternalError \\\n\tTVPThrowExceptionMessage(TVPInternalError, __FILE__,  __LINE__)\n\n#undef TJS_NATIVE_SET_ClassID\n#define TJS_NATIVE_SET_ClassID ClassID_KAGParser = TJS_NCM_CLASSID;\nstatic tjs_int32 ClassID_KAGParser = -1;\n//---------------------------------------------------------------------------\n// tTVPScenarioCacheItem : Scenario Cache Item\n//---------------------------------------------------------------------------\ntTVPScenarioCacheItem::tTVPScenarioCacheItem(const ttstr & name, bool isstring)\n{\n\tRefCount = 1;\n\tLines = NULL;\n\tLineCount = 0;\n\tLabelCached = false;\n\ttry\n\t{\n\t\tLoadScenario(name, isstring);\n\t}\n\tcatch(...)\n\t{\n\t\tif(Lines) delete [] Lines;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPScenarioCacheItem::~tTVPScenarioCacheItem()\n{\n\tif(Lines) delete [] Lines;\n}\n//---------------------------------------------------------------------------\nvoid tTVPScenarioCacheItem::AddRef()\n{\n\tRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid tTVPScenarioCacheItem::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount --;\n}\n//---------------------------------------------------------------------------\nvoid tTVPScenarioCacheItem::LoadScenario(const ttstr & name, bool isstring)\n{\n\t// load scenario from file or string to buffer\n\n\tif(isstring)\n\t{\n\t\t// when onScenarioLoad returns string;\n\t\t// assumes the string is scenario\n\t\tBuffer = name.c_str();\n\t}\n\telse\n\t{\n\t\t// else load from file\n\n\t\tiTJSTextReadStream * stream = NULL;\n\n\t\ttry\n\t\t{\n\t\t\tstream = TVPCreateTextStreamForRead(name, TJS_W(\"\"));\n//\t\t\tstream = TVPCreateTextStreamForReadByEncoding(name, TJS_W(\"\"), TJS_W(\"Shift_JIS\"));\n\t\t\tttstr tmp;\n\t\t\tif (stream) {\n\t\t\t\tstream->Read(tmp, 0);\n\t\t\t}\n\t\t\tBuffer = tmp.c_str();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(stream) stream->Destruct();\n\t\t\tthrow;\n\t\t}\n\t\tif(stream) stream->Destruct();\n\t}\n\n\ttjs_char *buffer_p = Buffer;\n\n\t// pass1: count lines\n\ttjs_int count = 0;\n\ttjs_char *ls = buffer_p;\n\ttjs_char *p = buffer_p;\n\twhile(*p)\n\t{\n\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n'))\n\t\t{\n\t\t\tcount++;\n\t\t\tif(*p == TJS_W('\\r') && p[1] == TJS_W('\\n')) p++;\n\t\t\tp++;\n\t\t\tls = p;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tp++;\n\t\t}\n\t}\n\n\tif(p!=ls)\n\t{\n\t\tcount++;\n\t}\n\n\tif(count == 0) TVPThrowExceptionMessage(TVPKAGNoLine, name);\n\n\tLines = new tLine[count];\n\tLineCount = count;\n\n\t// pass2: split lines\n\tcount = 0;\n\tls = buffer_p;\n\twhile(*ls == '\\t') ls++; // skip leading tabs\n\tp = ls;\n\twhile(*p)\n\t{\n\t\tif(*p == TJS_W('\\r') || *p == TJS_W('\\n'))\n\t\t{\n\t\t\tLines[count].Start = ls;\n\t\t\tLines[count].Length = p-ls;\n\t\t\tcount++;\n\t\t\ttjs_char *rp = p;\n\t\t\tif(*p == TJS_W('\\r') && p[1] == TJS_W('\\n')) p++;\n\t\t\tp++;\n\t\t\tls = p;\n\t\t\twhile(*ls == '\\t') ls++;  // skip leading tabs\n\t\t\tp = ls;\n\t\t\t*rp = 0; // end line with null terminater\n\t\t}\n\t\telse\n\t\t{\n\t\t\tp++;\n\t\t}\n\t}\n\n\tif(p != ls)\n\t{\n\t\tLines[count].Start = ls;\n\t\tLines[count].Length = p-ls;\n\t\tcount ++;\n\t}\n\n\tLineCount = count;\n\t\t\t// tab-only last line will not be counted in pass2, thus makes\n\t\t\t// pass2 counted lines are lesser than pass1 lines.\n}\n//---------------------------------------------------------------------------\nvoid tTVPScenarioCacheItem::EnsureLabelCache()\n{\n\t// construct label cache\n\tif(!LabelCached)\n\t{\n\t\t// make label cache\n\t\tLabelAliases.resize(LineCount);\n\t\tttstr prevlabel;\n\t\tconst tjs_char *p;\n\t\tconst tjs_char *vl;\n\t\ttjs_int i;\n\t\tfor(i = 0; i<LineCount; i++)\n\t\t{\n\t\t\tif(Lines[i].Length >= 2 &&\n\t\t\t\tLines[i].Start[0] == TJS_W('*'))\n\t\t\t{\n\t\t\t\tp = Lines[i].Start;\n\t\t\t\tvl = TJS_strchr(p, TJS_W('|'));\n\t\t\t\tttstr label;\n\t\t\t\tif(vl)\n\t\t\t\t{\n\t\t\t\t\t// page name found\n\t\t\t\t\tlabel = ttstr(p, vl-p);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlabel = p;\n\t\t\t\t}\n\n\t\t\t\tif(!label.c_str()[1])\n\t\t\t\t{\n\t\t\t\t\tif(prevlabel.IsEmpty())\n\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGCannotOmmitFirstLabelName);\n\t\t\t\t\tlabel = prevlabel;\n\t\t\t\t}\n\n\t\t\t\tprevlabel = label;\n\n\t\t\t\ttLabelCacheData *data = LabelCache.Find(label);\n\t\t\t\tif(data)\n\t\t\t\t{\n\t\t\t\t\t// previous label name found (duplicated label)\n\t\t\t\t\tdata->Count++;\n\t\t\t\t\tlabel = label + TJS_W(\":\") + ttstr(data->Count);\n\t\t\t\t}\n\n\t\t\t\tLabelCache.Add(label, tLabelCacheData(i, 1));\n\t\t\t\tLabelAliases[i] = label;\n\t\t\t}\n\t\t}\n\n\t\tLabelCached = true;\n\t}\n\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPScenarioCache\n//---------------------------------------------------------------------------\n#define TVP_SCENARIO_MAX_CACHE_SIZE 8\ntypedef tTJSRefHolder<tTVPScenarioCacheItem> tTVPScenarioCacheItemHolder;\ntypedef tTJSHashCache<ttstr, tTVPScenarioCacheItemHolder,  tTJSHashFunc<ttstr>,\n\t(TVP_SCENARIO_MAX_CACHE_SIZE*2)> tTVPScenarioCache;\ntTVPScenarioCache TVPScenarioCache(TVP_SCENARIO_MAX_CACHE_SIZE);\n//---------------------------------------------------------------------------\nvoid TVPClearScnearioCache()\n{\n\tTVPScenarioCache.Clear();\n}\n//---------------------------------------------------------------------------\nstruct tTVPClearScenarioCacheCallback : public tTVPCompactEventCallbackIntf\n{\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\tif(level >= TVP_COMPACT_LEVEL_DEACTIVATE)\n\t\t{\n\t\t\t// clear the scenario cache\n#ifndef _DEBUG\n\t\t\tTVPClearScnearioCache();\n#endif\n\t\t}\n\t}\n} static TVPClearScenarioCacheCallback;\nstatic bool TVPClearScenarioCacheCallbackInit = false;\n//---------------------------------------------------------------------------\ntTVPScenarioCacheItem * TVPGetScenario(const ttstr & storagename, bool isstring)\n{\n\t// compact interface initialization\n\tif(!TVPClearScenarioCacheCallbackInit)\n\t{\n\t\tTVPAddCompactEventHook(&TVPClearScenarioCacheCallback);\n\t\tTVPClearScenarioCacheCallbackInit = true;\n\t}\n\n\tif(isstring)\n\t{\n\t\t// we do not cache when the string is passed as a scenario\n\t\treturn new tTVPScenarioCacheItem(storagename, true);\n\t}\n\n\t// make hash and search over cache\n\ttjs_uint32 hash = tTVPScenarioCache::MakeHash(storagename);\n\n\ttTVPScenarioCacheItemHolder * ptr =\n\t\tTVPScenarioCache.FindAndTouchWithHash(storagename, hash);\n\tif(ptr)\n\t{\n\t\t// found in the cache\n\t\treturn ptr->GetObject();\n\t}\n\n\t// not found in the cache\n\ttTVPScenarioCacheItem * item = new tTVPScenarioCacheItem(storagename, false);\n\ttry\n\t{\n\t\t// push into scenario cache hash\n\t\ttTVPScenarioCacheItemHolder holder(item);\n\t\tTVPScenarioCache.AddWithHash(storagename, hash, holder);\n\t}\n\tcatch(...)\n\t{\n\t\titem->Release();\n\t\tthrow;\n\t}\n\n\treturn item;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_KAGParser : KAGParser TJS native instance\n//---------------------------------------------------------------------------\n// KAGParser is implemented as a TJS native class/object\ntTJSNI_KAGParser::tTJSNI_KAGParser()\n{\n\tOwner = NULL;\n\tScenario = NULL;\n\tLines = NULL;\n\tCurLineStr = NULL;\n\tProcessSpecialTags = true;\n\tIgnoreCR = false;\n\tDicClear = NULL;\n\tDicAssign = NULL;\n\tDicObj = NULL;\n\tMacros = NULL;\n\tRecordingMacro = false;\n\tDebugLevel = tkdlSimple;\n\tInterrupted = false;\n\tMacroArgStackDepth = 0;\n\tMacroArgStackBase = 0;\n\n\t// retrieve DictClear method and DictObj object\n\tiTJSDispatch2 * dictclass;\n\tDicObj = TJSCreateDictionaryObject(&dictclass);\n\tMacros = TJSCreateDictionaryObject();\n\ttry\n\t{\n\t\t// retrieve clear method from dictclass\n\t\ttTJSVariant val;\n\t\ttjs_error er;\n\n\t\ter = dictclass->PropGet(0, TJS_W(\"clear\"), NULL, &val, dictclass);\n\t\tif(TJS_FAILED(er)) TVPThrowInternalError;\n\t\tDicClear = val.AsObject();\n\n\t\ter = dictclass->PropGet(0, TJS_W(\"assign\"), NULL, &val, dictclass);\n\t\tif(TJS_FAILED(er)) TVPThrowInternalError;\n\t\tDicAssign = val.AsObject();\n\n\t}\n\tcatch(...)\n\t{\n\t\tdictclass->Release();\n\t\tDicObj->Release();\n\t\tMacros->Release();\n\t\tif(DicClear) DicClear->Release();\n\t\tif(DicAssign) DicAssign->Release();\n\t\tthrow;\n\t}\n\n\tdictclass->Release();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\t\ttTJSNI_KAGParser::Construct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tOwner = tjs_obj;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_KAGParser::Invalidate()\n{\n\t// invalidate this object\n\n\t// release objects\n\tif(DicAssign) DicAssign->Release();\n\tif(DicClear) DicClear->Release();\n\tif(DicObj) DicObj->Release();\n\tif(Macros) Macros->Release();\n\n\tClearMacroArgs();\n\tClearBuffer();\n\n\tOwner = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::operator = (const tTJSNI_KAGParser & ref)\n{\n\t// copy Macros\n\t{\n\t\ttTJSVariant src(ref.Macros, ref.Macros);\n\t\ttTJSVariant *psrc = &src;\n\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, Macros);\n\t}\n\n\t// copy MacroArgs\n\t{\n\t\tClearMacroArgs();\n\n\t\tfor(tjs_uint i = 0; i < ref.MacroArgStackDepth; i++)\n\t\t{\n\t\t\tiTJSDispatch2 * dic = TJSCreateDictionaryObject();\n\t\t\tiTJSDispatch2 * isrc = ref.MacroArgs[i];\n\t\t\ttTJSVariant src(isrc, isrc);\n\t\t\ttTJSVariant *psrc = &src;\n\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, dic);\n\t\t\tMacroArgs.push_back(dic);\n\t\t}\n\t\tMacroArgStackDepth = ref.MacroArgStackDepth;\n\t}\n\tMacroArgStackBase = ref.MacroArgStackBase;\n\n\t// copy CallStack\n\tCallStack = ref.CallStack;\n\n\t// copy StorageName, StorageShortName\n\tStorageName = ref.StorageName;\n\tStorageShortName = ref.StorageShortName;\n\n\n\t// copy Scenario\n\tif(Scenario != ref.Scenario)\n\t{\n\t\tif(Scenario) Scenario->Release(), Scenario = NULL, Lines = NULL, CurLineStr = NULL;\n\t\tScenario = ref.Scenario;\n\t\tLines = ref.Lines;\n\t\tLineCount = ref.LineCount;\n\t\tif(Scenario) Scenario->AddRef();\n\t}\n\n\t// copy CurStorage, CurLine, CurPos\n\tCurLine = ref.CurLine;\n\tCurPos = ref.CurPos;\n\n\t// copy CurLineStr, LineBuffer, LineBufferUsing\n\tCurLineStr = ref.CurLineStr;\n\tLineBuffer = ref.LineBuffer;\n\tLineBufferUsing = ref.LineBufferUsing;\n\n\t// copy CurLabel, CurPage, TagLine\n\tCurLabel = ref.CurLabel;\n\tCurPage = ref.CurPage;\n\tTagLine = ref.TagLine;\n\n\t// copy DebugLebel, IgnoreCR\n\tDebugLevel = ref.DebugLevel;\n\tIgnoreCR = ref.IgnoreCR;\n\n\t// copy RecordingMacro, RecordingMacroStr, RecordingMacroName\n\tRecordingMacro = ref.RecordingMacro;\n\tRecordingMacroStr = ref.RecordingMacroStr;\n\tRecordingMacroName = ref.RecordingMacroName;\n\n\t// copy ExcludeLevel, IfLevel\n\tExcludeLevel = ref.ExcludeLevel;\n\tIfLevel = ref.IfLevel;\n\tExcludeLevelStack = ref.ExcludeLevelStack;\n\tIfLevelExecutedStack = ref.IfLevelExecutedStack;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 *tTJSNI_KAGParser::Store()\n{\n\t// store current status into newly created dictionary object\n\t// and return the dictionary object.\n\tiTJSDispatch2 * dic = TJSCreateDictionaryObject();\n\ttry\n\t{\n\t\ttTJSVariant val;\n\n\t\t// create and assign macro dictionary\n\t\t{\n\t\t\tiTJSDispatch2 * dsp;\n\n\t\t\tdsp = TJSCreateDictionaryObject();\n\t\t\ttTJSVariant tmp(dsp, dsp);\n\t\t\tdsp->Release();\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macros\"), NULL,\n\t\t\t\t&tmp, dic);\n\n\t\t\ttTJSVariant src(Macros, Macros);\n\t\t\ttTJSVariant *psrc = &src;\n\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, dsp);\n\t\t}\n\n\t\t// create and assign macro arguments\n\t\t{\n\t\t\tiTJSDispatch2 *dsp;\n\t\t\tdsp = TJSCreateArrayObject();\n\t\t\ttTJSVariant tmp(dsp, dsp);\n\t\t\tdsp->Release();\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macroArgs\"), NULL,\n\t\t\t\t&tmp, dic);\n\n\t\t\tfor(tjs_uint i = 0; i < MacroArgStackDepth; i++)\n\t\t\t{\n\t\t\t\tiTJSDispatch2 *dic;\n\t\t\t\tdic = TJSCreateDictionaryObject();\n\t\t\t\ttTJSVariant tmp(dic, dic);\n\t\t\t\tdic->Release();\n\t\t\t\tdsp->PropSetByNum(TJS_MEMBERENSURE, i,\n\t\t\t\t\t&tmp, dsp);\n\n\t\t\t\tiTJSDispatch2 * isrc = MacroArgs[i];\n\t\t\t\ttTJSVariant src(isrc, isrc);\n\t\t\t\ttTJSVariant *psrc = &src;\n\t\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, dic);\n\t\t\t}\n\t\t}\n\n\n\t\t// create call stack array and copy call stack status\n\t\t{\n\t\t\tiTJSDispatch2 *dsp;\n\t\t\tdsp = TJSCreateArrayObject();\n\t\t\ttTJSVariant tmp(dsp, dsp);\n\t\t\tdsp->Release();\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"callStack\"), NULL,\n\t\t\t\t&tmp, dic);\n\n\t\t\tstd::vector<tCallStackData>::iterator i;\n\t\t\tfor(i = CallStack.begin(); i != CallStack.end(); i++)\n\t\t\t{\n\t\t\t\tiTJSDispatch2 *dic;\n\t\t\t\tdic = TJSCreateDictionaryObject();\n\t\t\t\ttTJSVariant tmp(dic, dic);\n\t\t\t\tdic->Release();\n\t\t\t\tdsp->PropSetByNum(TJS_MEMBERENSURE, i - CallStack.begin(),\n\t\t\t\t\t&tmp, dsp);\n\n\t\t\t\ttTJSVariant val;\n\t\t\t\tval = i->Storage;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"storage\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->Label;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"label\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->Offset;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"offset\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->OrgLineStr;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"orgLineStr\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->LineBuffer;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"lineBuffer\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->Pos;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"pos\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = (tjs_int)i->LineBufferUsing;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"lineBufferUsing\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = (tjs_int)i->MacroArgStackBase;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macroArgStackBase\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = (tjs_int)i->MacroArgStackDepth;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macroArgStackDepth\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = i->ExcludeLevel;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"ExcludeLevel\"), NULL,\n\t\t\t\t\t&val, dic);\n\t\t\t\tval = (tjs_int)i->IfLevel;\n\t\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"IfLevel\"), NULL,\n\t\t\t\t\t&val, dic);\n                \n\t\t\t\tStoreIntStackToDic(dic, i->ExcludeLevelStack, TJS_W(\"ExcludeLevelStack\"));\n\t\t\t\tStoreBoolStackToDic(dic, i->IfLevelExecutedStack, TJS_W(\"IfLevelExecutedStack\"));\n\t\t\t}\n\t\t}\n\t\t\n\t\t// store StorageName, StorageShortName ( Buffer is not stored )\n\t\tval = StorageName;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"storageName\"), NULL,\n\t\t\t&val, dic);\n\t\tval = StorageShortName;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"storageShortName\"), NULL,\n\t\t\t&val, dic);\n\n\t\t// ( Lines and LineCount are not stored )\n\n\t\t// store CurStorage, CurLine, CurPos\n\t\tval = CurLine;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"curLine\"), NULL,\n\t\t\t&val, dic);\n\t\tval = CurPos;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"curPos\"), NULL,\n\t\t\t&val, dic);\n\n\t\t// ( CurLineStr is not stored )\n\n\t\t// LineBuffer, LineBufferUsing\n\t\tval = LineBuffer;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"lineBuffer\"), NULL,\n\t\t\t&val, dic);\n\t\tval = (tjs_int)LineBufferUsing;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"lineBufferUsing\"), NULL,\n\t\t\t&val, dic);\n\n\t\t// store CurLabel ( CurPage TagLine is not stored )\n\t\tval = CurLabel;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"curLabel\"), NULL,\n\t\t\t&val, dic);\n\n\t\t// ( DebugLebel and IgnoreCR are not stored )\n\n\t\t// ( RecordingMacro, RecordingMacroStr, RecordingMacroName are not stored)\n\n\n\t\t// ExcludeLevel, IfLevel, ExcludeLevelStack, IfLevelExecutedStack\n\t\tval = ExcludeLevel;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"ExcludeLevel\"), NULL, &val, dic);\n\t\tval = IfLevel;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"IfLevel\"), NULL, &val, dic);\n\t\tStoreIntStackToDic(dic, ExcludeLevelStack, TJS_W(\"ExcludeLevelStack\"));\n\t\tStoreBoolStackToDic(dic, IfLevelExecutedStack, TJS_W(\"IfLevelExecutedStack\"));\n\n\t\t// store MacroArgStackBase, MacroArgStackDepth\n\t\tval = (tjs_int)MacroArgStackBase;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macroArgStackBase\"), NULL,\n\t\t\t&val, dic);\n\n\t\tval = (tjs_int)MacroArgStackDepth;\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"macroArgStackDepth\"), NULL,\n\t\t\t&val, dic);\n\n\t}\n\tcatch(...)\n\t{\n\t\tdic->Release();\n\t\tthrow;\n\t}\n\treturn dic;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::StoreIntStackToDic(iTJSDispatch2 *dic, std::vector<tjs_int> &stack, const tjs_char *membername)\n{\n\tttstr stack_str;\n\tconst static tjs_char hex[] = TJS_W(\"0123456789abcdef\");\n\ttjs_char *p = stack_str.AllocBuffer(stack.size() * 8);\n\tfor(std::vector<tjs_int>::iterator it = stack.begin(); it != stack.end(); ++it)\n\t{\n\t\ttjs_int v = *it;\n\t\tp[0] = hex[(v >> 28) & 0x000f];\n\t\tp[1] = hex[(v >> 24) & 0x000f];\n\t\tp[2] = hex[(v >> 20) & 0x000f];\n\t\tp[3] = hex[(v >> 16) & 0x000f];\n\t\tp[4] = hex[(v >> 12) & 0x000f];\n\t\tp[5] = hex[(v >>  8) & 0x000f];\n\t\tp[6] = hex[(v >>  4) & 0x000f];\n\t\tp[7] = hex[(v >>  0) & 0x000f];\n\t\tp += 8;\n\t}\n\t*p = '\\0';\n\tstack_str.FixLen();\n\ttTJSVariant val;\n\tval = stack_str;\n\tdic->PropSet(TJS_MEMBERENSURE, membername, NULL, &val, dic);\n}\n\nvoid tTJSNI_KAGParser::RestoreIntStackFromStr(std::vector<tjs_int> &stack, const ttstr &str)\n{\n\tstack.clear();\n\ttjs_int len = str.length() / 8;\n\tfor(tjs_int i = 0; i < len; ++i)\n\t{\n\t\tstack.push_back(\n\t\t\t(((str[i+0] <= '9') ? (str[i+0] - '0') : (str[i+0] - 'a' + 10)) << 28) |\n\t\t\t(((str[i+1] <= '9') ? (str[i+1] - '0') : (str[i+1] - 'a' + 10)) << 24) |\n\t\t\t(((str[i+2] <= '9') ? (str[i+2] - '0') : (str[i+2] - 'a' + 10)) << 20) |\n\t\t\t(((str[i+3] <= '9') ? (str[i+3] - '0') : (str[i+3] - 'a' + 10)) << 16) |\n\t\t\t(((str[i+4] <= '9') ? (str[i+4] - '0') : (str[i+4] - 'a' + 10)) << 12) |\n\t\t\t(((str[i+5] <= '9') ? (str[i+5] - '0') : (str[i+5] - 'a' + 10)) <<  8) |\n\t\t\t(((str[i+6] <= '9') ? (str[i+6] - '0') : (str[i+6] - 'a' + 10)) <<  4) |\n\t\t\t(((str[i+7] <= '9') ? (str[i+7] - '0') : (str[i+7] - 'a' + 10)) <<  0)\n\t\t);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::RestoreBoolStackFromStr(std::vector<bool> &stack, const ttstr &str)\n{\n\tstack.clear();\n\ttjs_int len = str.length();\n\tfor(tjs_int i = 0; i < len; ++i)\n\t{\n\t\tstack.push_back(str[i] == '1');\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::StoreBoolStackToDic(iTJSDispatch2 *dic, std::vector<bool> &stack, const tjs_char *membername)\n{\n\tttstr stack_str;\n\tconst static tjs_char bit[] = TJS_W(\"01\");\n\ttjs_char *p = stack_str.AllocBuffer(stack.size());\n\tfor(std::vector<bool>::iterator it = stack.begin(); it != stack.end(); ++it)\n\t{\n\t\t*p = bit[(tjs_int)(*it)];\n\t\t++p;\n\t}\n\t*p = '\\0';\n\tstack_str.FixLen();\n\ttTJSVariant val;\n\tval = stack_str;\n\tdic->PropSet(TJS_MEMBERENSURE, membername, NULL, &val, dic);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::Restore(iTJSDispatch2 *dic)\n{\n\t// restore status from \"dic\"\n\ttTJSVariant val;\n//\ttjs_error er;\n\n\t// restore macros\n\t{\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"macros\"), NULL, &val, dic);\n\t\tif(val.Type() != tvtVoid)\n\t\t{\n\t\t\ttTJSVariant *psrc = &val;\n\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, Macros);\n\t\t}\n\t}\n\n\t{\n\t\t// restore macro args\n\t\tMacroArgStackDepth = 0;\n\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"macroArgs\"), NULL, &val, dic);\n\t\tif(val.Type() != tvtVoid)\n\t\t{\n\t\t\ttTJSVariantClosure clo = val.AsObjectClosureNoAddRef();\n\t\t\ttTJSVariant v;\n\t\t\ttjs_int count = 0;\n\t\t\tclo.PropGet(0, TJS_W(\"count\"), NULL, &v, NULL);\n\t\t\tcount = v;\n\n\t\t\tClearMacroArgs();\n\n\t\t\tval.Clear();\n\t\t\tdic->PropGet(0, TJS_W(\"macroArgStackDepth\"), NULL,\n\t\t\t\t&val, dic);\n\t\t\tif(val.Type() != tvtVoid) MacroArgStackDepth = (tjs_uint)(tjs_int)val;\n\n\t\t\tfor(tjs_int i = 0; i<count; i++)\n\t\t\t{\n\t\t\t\tiTJSDispatch2 *dsp = TJSCreateDictionaryObject();\n\t\t\t\ttTJSVariant val(dsp, dsp);\n\t\t\t\tdsp->Release();\n\n\t\t\t\tclo.PropGetByNum(0, i, &v, NULL);\n\t\t\t\ttTJSVariant *psrc = &v;\n\t\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, dsp);\n\n\t\t\t\tdsp->AddRef();\n\t\t\t\tMacroArgs.push_back(dsp);\n\t\t\t}\n\t\t}\n\n\t\tif(MacroArgStackDepth != MacroArgs.size())\n\t\t\tTVPThrowExceptionMessage(TVPKAGMalformedSaveData);\n\n\t\tMacroArgStackBase = MacroArgs.size(); // later reset to MacroArgStackBase\n\n\t\t// restore call stack\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"callStack\"), NULL, &val, dic);\n\t\tif(val.Type() != tvtVoid)\n\t\t{\n\t\t\ttTJSVariantClosure clo = val.AsObjectClosureNoAddRef();\n\t\t\ttTJSVariant v;\n\t\t\ttjs_int count = 0;\n\t\t\tclo.PropGet(0, TJS_W(\"count\"), NULL, &v, NULL);\n\t\t\tcount = v;\n\n\t\t\tCallStack.clear();\n\n\t\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tttstr Storage;\n\t\t\t\tttstr Label;\n\t\t\t\ttjs_int Offset;\n\t\t\t\tttstr OrgLineStr;\n\t\t\t\tttstr LineBuffer;\n\t\t\t\ttjs_int Pos;\n\t\t\t\tbool LineBufferUsing;\n\t\t\t\ttjs_uint MacroArgStackBase;\n\t\t\t\ttjs_uint MacroArgStackDepth;\n\t\t\t\ttjs_int ExcludeLevel;\n\t\t\t\ttjs_int IfLevel;\n\t\t\t\tstd::vector<tjs_int> ExcludeLevelStack;\n\t\t\t\tstd::vector<bool> IfLevelExecutedStack;\n\n\t\t\t\ttTJSVariant val;\n\n\t\t\t\tclo.PropGetByNum(0, i, &v, NULL);\n\t\t\t\ttTJSVariantClosure dic = v.AsObjectClosureNoAddRef();\n\t\t\t\tdic.PropGet(0, TJS_W(\"storage\"), NULL, &val, NULL);\n\t\t\t\tStorage = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"label\"), NULL, &val, NULL);\n\t\t\t\tLabel = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"offset\"), NULL, &val, NULL);\n\t\t\t\tOffset = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"orgLineStr\"), NULL, &val, NULL);\n\t\t\t\tOrgLineStr = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"lineBuffer\"), NULL, &val, NULL);\n\t\t\t\tLineBuffer = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"pos\"), NULL, &val, NULL);\n\t\t\t\tPos = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"lineBufferUsing\"), NULL, &val, NULL);\n\t\t\t\tLineBufferUsing = 0!=(tjs_int)val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"macroArgStackBase\"), NULL, &val, NULL);\n\t\t\t\tMacroArgStackBase = (tjs_int)val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"macroArgStackDepth\"), NULL, &val, NULL);\n\t\t\t\tMacroArgStackDepth = (tjs_int)val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"ExcludeLevel\"), NULL, &val, NULL);\n\t\t\t\tExcludeLevel = val;\n\t\t\t\tdic.PropGet(0, TJS_W(\"IfLevel\"), NULL, &val, NULL);\n\t\t\t\tIfLevel = val;\n\n\t\t\t\tttstr stack_str;\n\t\t\t\tdic.PropGet(0, TJS_W(\"ExcludeLevelStack\"), NULL, &val, NULL);\n\t\t\t\tstack_str = val;\n\t\t\t\tRestoreIntStackFromStr(ExcludeLevelStack, stack_str);\n\n\t\t\t\tdic.PropGet(0, TJS_W(\"IfLevelExecutedStack\"), NULL, &val, NULL);\n\t\t\t\tstack_str = val;\n\t\t\t\tRestoreBoolStackFromStr(IfLevelExecutedStack, stack_str);\n\n\t\t\t\tCallStack.push_back(tCallStackData(\n\t\t\t\t\tStorage, Label, Offset, OrgLineStr, LineBuffer, Pos,\n\t\t\t\t\tLineBufferUsing, MacroArgStackBase, MacroArgStackDepth,\n\t\t\t\t\tExcludeLevelStack, ExcludeLevel, IfLevelExecutedStack, IfLevel));\n\t\t\t}\n\t\t}\n\n\t\t// restore StorageName, StorageShortName, CurStorage, CurLabel\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"storageName\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) StorageName = val;\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"storageShortName\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) StorageShortName = val;\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"curLabel\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) CurLabel = val;\n\n\t\t// load scenario\n\t\tttstr storage = StorageName, label = CurLabel;\n\t\tClearBuffer(); // ensure re-loading the scenario\n\t\tLoadScenario(storage);\n\t\tGoToLabel(label);\n\n\t\t// ExcludeLevel, IfLevel\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"ExcludeLevel\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) ExcludeLevel = (tjs_int)val;\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"IfLevel\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) IfLevel = (tjs_int)val;\n\n\t\t// ExcludeLevelStack, IfLevelExecutedStack\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"ExcludeLevelStack\"), NULL, &val, dic);\n\t\tif(val.Type() != tvtVoid)\n\t\t{\n\t\t\tttstr stack_str;\n\t\t\tstack_str = val;\n\t\t\tRestoreIntStackFromStr(ExcludeLevelStack, stack_str);\n\t\t}\n\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"IfLevelExecutedStack\"), NULL, &val, dic);\n\t\tif(val.Type() != tvtVoid)\n\t\t{\n\t\t\tttstr stack_str;\n\t\t\tstack_str = val;\n\t\t\tRestoreBoolStackFromStr(IfLevelExecutedStack, stack_str);\n\t\t}\n\n\n\t\t// restore MacroArgStackBase\n\t\tval.Clear();\n\t\tdic->PropGet(0, TJS_W(\"macroArgStackBase\"), NULL,\n\t\t\t&val, dic);\n\t\tif(val.Type() != tvtVoid) MacroArgStackBase = (tjs_uint)(tjs_int)val;\n\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::LoadScenario(const ttstr & name)\n{\n\t// load scenario to buffer\n\n\tBreakConditionAndMacro();\n\n\n\tif(StorageName == name)\n\t{\n\t\t// avoid re-loading\n\t\tRewind();\n\t}\n\telse\n\t{\n\t\tClearBuffer();\n\n\t\t// fire onScenarioLoad\n\t\ttTJSVariant param = name;\n\t\ttTJSVariant *pparam = &param;\n\t\ttTJSVariant result;\n\t\tstatic ttstr funcname(TJSMapGlobalStringMap(TJS_W(\"onScenarioLoad\")));\n\t\ttjs_error status = Owner->FuncCall(0, funcname.c_str(), funcname.GetHint(),\n\t\t\t&result, 1, &pparam, Owner);\n\n\t\tif(status == TJS_S_OK && result.Type() == tvtString)\n\t\t{\n\t\t\t// when onScenarioLoad returns string;\n\t\t\t// assumes the string is scenario\n\t\t\tScenario = TVPGetScenario(ttstr(result), true);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// else load from file\n\t\t\tScenario = TVPGetScenario(name, false);\n\t\t}\n\n\t\tLines = Scenario->GetLines();\n\t\tLineCount = Scenario->GetLineCount();\n\n\t\tRewind();\n\n\t\tStorageName = name;\n\t\tStorageShortName = TVPExtractStorageName(name);\n\n\t\tif(DebugLevel >= tkdlSimple)\n\t\t{\n\t\t\tstatic ttstr hr(TJS_W(\n\t\t\t\t\"========================================\")\n\t\t\t\tTJS_W(\"========================================\"));\n\t\t\tTVPAddLog(hr);\n\t\t\tTVPAddLog(TJS_W(\"Scenario loaded : \") + name);\n\t\t}\n\t}\n\n\n\tif(Owner)\n\t{\n\t\ttTJSVariant param = StorageName;\n\t\ttTJSVariant *pparam = &param;\n\t\tstatic ttstr funcname(TJSMapGlobalStringMap(TJS_W(\"onScenarioLoaded\")));\n\t\tOwner->FuncCall(0, funcname.c_str(), funcname.GetHint(),\n\t\t\tNULL, 1, &pparam, Owner);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::Clear()\n{\n\t// clear all states\n\tTVPClearScnearioCache(); // also invalidates the scenario cache\n\tClearBuffer();\n\tClearMacroArgs();\n\tClearCallStack();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::ClearBuffer()\n{\n\t// clear internal buffer\n\tif(Scenario) Scenario->Release(), Scenario = NULL, Lines = NULL, CurLineStr = NULL;\n\tStorageName.Clear();\n\tStorageShortName.Clear();\n\tBreakConditionAndMacro();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::Rewind()\n{\n\t// set current position to first\n\tCurLine = 0;\n\tCurPos = 0;\n\tCurLineStr = Lines[0].Start;\n\tLineBufferUsing = false;\n\tBreakConditionAndMacro();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::BreakConditionAndMacro()\n{\n\t// break condition state and macro recording\n\tRecordingMacro = false;\n\tExcludeLevel = -1;\n\tExcludeLevelStack.clear();\n\tIfLevelExecutedStack.clear();\n\tIfLevel = 0;\n\tPopMacroArgsTo(MacroArgStackBase);\n\t\t// clear macro argument down to current base stack position\n}\n//---------------------------------------------------------------------------\nstatic bool inline TVPIsWS(tjs_char ch)\n{\n\t// is white space ?\n\treturn (ch == TJS_W(' ') || ch == TJS_W('\\t'));\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::GoToLabel(const ttstr &name)\n{\n\t// search label and set current position\n\t// parameter \"name\" must start with '*'\n\tif(name.IsEmpty()) return;\n\n\tScenario->EnsureLabelCache();\n\n\ttTVPScenarioCacheItem::tLabelCacheData *newline;\n\n\tnewline = Scenario->GetLabelCache().Find(name);\n\n\tif(newline)\n\t{\n\t\t// found the label in cache\n\t\tconst tjs_char *vl;\n\t\tvl = TJS_strchr(Lines[newline->Line].Start, TJS_W('|'));\n\n\t\tCurLabel = Scenario->GetLabelAliasFromLine(newline->Line);\n\t\tif(vl) CurPage = vl+1; else CurPage.Clear();\n\t\tCurLine = newline->Line;\n\t\tCurPos = 0;\n\t\tLineBufferUsing = false;\n\t}\n\telse\n\t{\n\t\t// not found\n\t\tTVPThrowExceptionMessage(TVPKAGLabelNotFound, StorageName, name);\n\t}\n\n\tif(DebugLevel >= tkdlSimple)\n\t{\n\t\tstatic ttstr hr(TJS_W(\n\t\t\t\"- - - - - - - - - - - - - - - - - - - - \")\n\t\t\tTJS_W(\"- - - - - - - - - - - - - - - - - - - - \"));\n\t\tTVPAddLog(hr);\n\t\tTVPAddLog(StorageShortName + TJS_W(\" : jumped to : \") + name);\n\t}\n\n\tBreakConditionAndMacro();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::GoToStorageAndLabel(const ttstr &storage,\n\tconst ttstr &label)\n{\n\tif(!storage.IsEmpty()) LoadScenario(storage);\n\tif(!label.IsEmpty()) GoToLabel(label);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::CallLabel(const ttstr &name)\n{\n\tPushCallStack();\n\tGoToLabel(name);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_KAGParser::SkipCommentOrLabel()\n{\n\t// skip comment or label, and go to next line.\n\t// fire OnScript event if [script] thru [endscript] ( or @script thru\n\t// @endscript ) is found.\n\tScenario->EnsureLabelCache();\n\n\tCurPos = 0;\n\tif(CurLine >= LineCount) return false;\n\tfor(; CurLine < LineCount; CurLine++)\n\t{\n\t\tif(!Lines) return false; // in this loop, Lines can be NULL when onScript does so.\n\n\t\tconst tjs_char * p = Lines[CurLine].Start;\n\n\t\tif(p[0] == TJS_W(';'))\n\t\t\tcontinue; // comment\n\n\t\tif(p[0] == TJS_W('*'))\n\t\t{\n\t\t\t// label\n\t\t\tif(RecordingMacro)\n\t\t\t\tTVPThrowExceptionMessage(TVPLabelOrScriptInMacro);\n\n\t\t\ttjs_char * vl = TJS_strchr(const_cast<tjs_char*>(p), TJS_W('|'));\n\t\t\tbool pagename;\n\t\t\tif(vl)\n\t\t\t{\n\t\t\t\tCurLabel = Scenario->GetLabelAliasFromLine(CurLine);\n\t\t\t\tCurPage = ttstr(vl + 1);\n\t\t\t\tpagename = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tCurLabel = Scenario->GetLabelAliasFromLine(CurLine);\n\t\t\t\tCurPage.Clear();\n\t\t\t\tpagename = false;\n\t\t\t}\n\n\t\t\t// fire onLabel callback event\n\t\t\tif(Owner)\n\t\t\t{\n\t\t\t\ttTJSVariant param[2];\n\t\t\t\tparam[0] = CurLabel;\n\t\t\t\tif(pagename) param[1] = CurPage;\n\t\t\t\ttTJSVariant *pparam[2] = { param, param+1 };\n\t\t\t\tstatic ttstr onLabel_name(TJSMapGlobalStringMap(TJS_W(\"onLabel\")));\n\t\t\t\tOwner->FuncCall(0, onLabel_name.c_str(), onLabel_name.GetHint(),\n\t\t\t\t\tNULL, 2, pparam, Owner);\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif((p[0] == TJS_W('[') &&\n\t\t\t(!TJS_strcmp(p, TJS_W(\"[iscript]\")) ||\n\t\t\t !TJS_strcmp(p, TJS_W(\"[iscript]\\\\\")) ))||\n\t\t   (p[0] == TJS_W('@') &&\n\t\t\t(!TJS_strcmp(p, TJS_W(\"@iscript\")) ) ) )\n\t\t{\n\t\t\t// inline TJS script\n \t\t\tif(RecordingMacro)\n\t\t\t\tTVPThrowExceptionMessage(TVPLabelOrScriptInMacro);\n\n\t\t\tttstr script;\n\t\t\tCurLine++;\n\n\t\t\ttjs_int script_start = CurLine;\n\n\t\t\tfor(;CurLine < LineCount; CurLine++)\n\t\t\t{\n\t\t\t\tp = Lines[CurLine].Start;\n\t\t\t\tif((p[0] == TJS_W('[') &&\n\t\t\t\t\t(!TJS_strcmp(p, TJS_W(\"[endscript]\")) ||\n\t\t\t\t\t !TJS_strcmp(p, TJS_W(\"[endscript]\\\\\")) ))||\n\t\t\t\t  (p[0] == TJS_W('@') &&\n\t\t\t\t\t(!TJS_strcmp(p, TJS_W(\"@endscript\")) ) ) )\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif(ExcludeLevel == -1)\n\t\t\t\t{\n\t\t\t\t\tscript += p;\n\t\t\t\t\tscript += TJS_W(\"\\r\\n\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(CurLine == LineCount)\n\t\t\t\t TVPThrowExceptionMessage(TVPKAGInlineScriptNotEnd);\n\n\t\t\t// fire onScript callback event\n\t\t\tif(ExcludeLevel == -1)\n\t\t\t{\n\t\t\t\tif(Owner)\n\t\t\t\t{\n\t\t\t\t\ttTJSVariant param[3] = {script, StorageShortName, script_start};\n\t\t\t\t\ttTJSVariant *pparam[3] = { param, param+1, param+2 };\n\t\t\t\t\tstatic ttstr onScript_name(TJSMapGlobalStringMap(TJS_W(\"onScript\")));\n\t\t\t\t\tOwner->FuncCall(0, onScript_name.c_str(), onScript_name.GetHint(),\n\t\t\t\t\t\tNULL, 3, pparam, Owner);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tif(CurLine >= LineCount) return false;\n\n\tCurLineStr = Lines[CurLine].Start;\n\tLineBufferUsing = false;\n\n\tif(DebugLevel >= tkdlVerbose)\n\t{\n\t\tTVPAddLog(StorageShortName + TJS_W(\" : \") + CurLineStr);\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::PushMacroArgs(iTJSDispatch2 *args)\n{\n\tiTJSDispatch2 *dsp;\n\tif(MacroArgs.size() > MacroArgStackDepth)\n\t{\n\t\tdsp = MacroArgs[MacroArgStackDepth];\n\t}\n\telse\n\t{\n\t\tif(MacroArgStackDepth > MacroArgs.size())\n\t\t\tTVPThrowInternalError;\n\t\tdsp = TJSCreateDictionaryObject();\n\t\tMacroArgs.push_back(dsp);\n\t}\n\tMacroArgStackDepth++;\n\n\t// copy arguments from args to dsp\n\ttTJSVariant src(args, args);\n\ttTJSVariant *psrc = &src;\n\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, dsp);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::PopMacroArgs()\n{\n\tif(MacroArgStackDepth == 0) TVPThrowExceptionMessage(TVPKAGSyntaxError);\n\tMacroArgStackDepth--;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::ClearMacroArgs()\n{\n\tfor(std::vector<iTJSDispatch2 *>::iterator i = MacroArgs.begin();\n\t\ti != MacroArgs.end(); i++)\n\t{\n\t\t(*i)->Release();\n\t}\n\tMacroArgs.clear();\n\tMacroArgStackDepth = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::PopMacroArgsTo(tjs_uint base)\n{\n\tMacroArgStackDepth = base;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::FindNearestLabel(tjs_int start, tjs_int &labelline,\n\tttstr &labelname)\n{\n\t// find nearest label which be pleced before \"start\".\n\t// \"labelline\" is to be the label's line number (0-based), and\n\t// \"labelname\" is to be its label name.\n\t// \"labelline\" will be -1 and \"labelname\" be empty if the label is not found.\n\tScenario->EnsureLabelCache();\n\n\tstart--;\n\twhile(start >= 0)\n\t{\n\t\tif(Lines[start].Start[0] == TJS_W('*'))\n\t\t{\n\t\t\t// label found\n\t\t\tlabelname = Scenario->GetLabelAliasFromLine(start);\n\t\t\tbreak;\n\t\t}\n\t\tstart --;\n\t}\n\tlabelline = start;\n\tif(labelline == -1) labelname.Clear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::PushCallStack()\n{\n\t// push current position information\n\tif(DebugLevel >= tkdlVerbose)\n\t{\n\t\tTVPAddLog(StorageShortName + TJS_W(\" : call stack depth before calling : \")\n\t\t\t+ ttstr((int)CallStack.size()));\n\t}\n\n\ttjs_int labelline;\n\tttstr labelname;\n\tFindNearestLabel(CurLine, labelline, labelname);\n\tif(labelline < 0) labelline = 0;\n\n\tconst tjs_char *curline_content;\n\tif(Lines && CurLine < LineCount)\n\t\tcurline_content = Lines[CurLine].Start;\n\telse\n\t\tcurline_content = TJS_W(\"\");\n\n\tCallStack.push_back(tCallStackData(StorageName, labelname, CurLine - labelline,\n\t\tcurline_content,\n\t\tLineBuffer, CurPos, LineBufferUsing, MacroArgStackBase, MacroArgStackDepth,\n\t\tExcludeLevelStack, ExcludeLevel, IfLevelExecutedStack, IfLevel));\n\tMacroArgStackBase = MacroArgStackDepth;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::PopCallStack(const ttstr &storage, const ttstr &label)\n{\n\t// pop call stack information\n\tif(CallStack.size() == 0)\n\t\tTVPThrowExceptionMessage(TVPKAGCallStackUnderflow);\n\n\t// pop macro argument information\n\ttCallStackData & data = CallStack.back();\n\tMacroArgStackBase = data.MacroArgStackDepth; // later reset to MacroArgStackBase\n\tPopMacroArgsTo(data.MacroArgStackDepth);\n\n\t// goto label or previous position\n\tif(!storage.IsEmpty() || !label.IsEmpty())\n\t{\n\t\t// return to specified position\n\t\tGoToStorageAndLabel(storage, label);\n\t}\n\telse\n\t{\n\t\t// return to previous calling position\n\t\tLoadScenario(data.Storage);\n\t\tif(!data.Label.IsEmpty()) GoToLabel(data.Label);\n\t\tCurLine += data.Offset;\n\t\tif(CurLine > LineCount)\n\t\t\tTVPThrowExceptionMessage(TVPKAGReturnLostSync);\n\t\t\t\t/* CurLine == LineCount is OK (at end of file) */\n\t\tif(CurLine < LineCount)\n\t\t\tif(data.OrgLineStr != Lines[CurLine].Start) // check original line information\n\t\t\t\tTVPThrowExceptionMessage(TVPKAGReturnLostSync);\n\t\tif(data.LineBufferUsing)\n\t\t{\n\t\t\tLineBuffer = data.LineBuffer;\n\t\t\tCurLineStr = LineBuffer.c_str();\n\t\t\tLineBufferUsing = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(CurLine < LineCount)\n\t\t\t{\n\t\t\t\tCurLineStr = Lines[CurLine].Start;\n\t\t\t\tLineBufferUsing = false;\n\t\t\t}\n\t\t}\n\t\tCurPos = data.Pos;\n\n        ExcludeLevelStack = data.ExcludeLevelStack;\n        ExcludeLevel = data.ExcludeLevel;\n        IfLevelExecutedStack = data.IfLevelExecutedStack;\n        IfLevel = data.IfLevel;\n\n\t\tif(DebugLevel >= tkdlSimple)\n\t\t{\n\t\t\tttstr label;\n\t\t\tif(data.Label.IsEmpty()) label = TJS_W(\"(start)\"); else label = data.Label;\n\t\t\tTVPAddLog(StorageShortName + TJS_W(\" : returned to : \") + label +\n\t\t\t\tTJS_W(\" line offset \") + ttstr(data.Offset));\n\t\t}\n\t}\n\n\t// reset MacroArgStackBase\n\tMacroArgStackBase = data.MacroArgStackBase;\n\n\t// pop casll stack\n\tCallStack.pop_back();\n\n\n\t// call function back\n\tif(Owner)\n\t{\n\t\tstatic ttstr onAfterReturn_name(TJS_W(\"onAfterReturn\"));\n\t\tOwner->FuncCall(0, onAfterReturn_name.c_str(), onAfterReturn_name.GetHint(),\n\t\t\tNULL, 0, NULL, Owner);\n\t}\n\n\n\tif(DebugLevel >= tkdlVerbose)\n\t{\n\t\tTVPAddLog(StorageShortName + TJS_W(\" : call stack depth after returning : \")\n\t\t\t+ ttstr((int)CallStack.size()));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_KAGParser::ClearCallStack()\n{\n\tCallStack.clear();\n\tPopMacroArgsTo(MacroArgStackBase = 0); // macro arguments are also cleared\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_KAGParser::_GetNextTag()\n{\n\t// get next tag and return information dictionary object.\n\t// return NULL if the tag not found.\n\t// normal characters are interpreted as a \"ch\" tag.\n\t// CR code is interpreted as a \"r\" tag.\n\t// returned tag's line number is stored to TagLine.\n\t// tag paremeters are stored into return value.\n\t// tag name is also stored into return value, naemd \"__tag\".\n\n\t// pretty a nasty code.\nparse_start:\n\n\tif(CurLine >= LineCount) return NULL;\n\tif(!Lines) return NULL;\n\n\n\tstatic ttstr __tag_name(TJSMapGlobalStringMap(TJS_W(\"tagname\")));\n\tstatic ttstr __eol_name(TJSMapGlobalStringMap(TJS_W(\"eol\")));\n\tstatic ttstr __storage_name(TJSMapGlobalStringMap(TJS_W(\"storage\")));\n\tstatic ttstr __target_name(TJSMapGlobalStringMap(TJS_W(\"target\")));\n\tstatic ttstr __exp_name(TJSMapGlobalStringMap(TJS_W(\"exp\")));\n\n\twhile(true)\n\t{\n\t\tDicClear->FuncCall(0, NULL, NULL, NULL, 0, NULL, DicObj);\n\t\t\t// clear dictionary object\n\n\t\tif(Interrupted)\n\t\t{\n\t\t\t// interrupt current parsing\n\t\t\t// return as \"interrupted\" tag\n\t\t\tstatic tTJSVariant r_val(TJS_W(\"interrupt\"));\n\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &r_val, DicObj);\n\t\t\tInterrupted = false;\n\t\t\tDicObj->AddRef();\n\t\t\treturn DicObj;\n\t\t}\n\n\t\tif(CurLine >= LineCount) break; // all of scenario was decoded \n\n\t\ttjs_int tagstartpos = CurPos;\n\n\t\tif(!LineBufferUsing && CurPos == 0)\n\t\t\tif(!SkipCommentOrLabel()) return NULL;\n\n\t\tif(!IgnoreCR)\n\t\t{\n\t\t\tif((CurLineStr[CurPos] == TJS_W('\\\\') &&\n\t\t\t\tCurLineStr[CurPos+1] == 0 ) ||\n\t\t\t\t(CurLineStr[CurPos] == 0 && CurPos >= 3 &&\n\t\t\t\tCurLineStr[CurPos-3] == TJS_W('[') &&\n\t\t\t\tCurLineStr[CurPos-2] == TJS_W('p') && // for line ending with [p]\n\t\t\t\tCurLineStr[CurPos-1] == TJS_W(']')))\n\t\t\t{\n\t\t\t\t// line ended with '\\\\'\n\t\t\t\tCurLine++;\n\t\t\t\tCurPos = 0;\n\t\t\t\tLineBufferUsing = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t{\n\t\t\t\t// line ended ...\n\t\t\t\tTagLine = CurLine;\n\t\t\t\tstatic tTJSVariant r_val(TJS_W(\"r\"));\n\t\t\t\tstatic tTJSVariant true_val(TJS_W(\"true\"));\n\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &r_val, DicObj);\n\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t__eol_name.AsVariantStringNoAddRef(), &true_val, DicObj);\n\t\t\t\tif(RecordingMacro) RecordingMacroStr += TJS_W(\"[r eol=true]\");\n\t\t\t\tCurLine++;\n\t\t\t\tCurPos = 0;\n\t\t\t\tLineBufferUsing = false;\n\t\t\t\tif(!RecordingMacro && ExcludeLevel == -1)\n\t\t\t\t{\n\t\t\t\t\tDicObj->AddRef();\n\t\t\t\t\treturn DicObj;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\ttjs_char ldelim; // last delimiter\n\n\t\tif(!LineBufferUsing && CurPos == 0 && CurLineStr[0] == TJS_W('@'))\n\t\t{\n\t\t\t// line command mode\n\t\t\tldelim = 0; // tag last delimiter is a null terminater\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(CurLineStr[CurPos] != TJS_W('[') ||\n\t\t\t\tCurLineStr[CurPos] == TJS_W('[') &&\n\t\t\t\tCurLineStr[CurPos+1] == TJS_W('['))\n\t\t\t{\n\t\t\t\t// normal character\n\t\t\t\ttjs_char ch = CurLineStr[CurPos];\n\t\t\t\tTagLine = CurLine;\n\n\t\t\t\tif(ch == 0)\n\t\t\t\t{\n\t\t\t\t\t// line ended\n\t\t\t\t\tCurLine++;\n\t\t\t\t\tCurPos = 0;\n\t\t\t\t\tLineBufferUsing = false;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(ch == TJS_W('\\t'))\n\t\t\t\t{\n\t\t\t\t\tCurPos++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(ch != TJS_W('\\n'))\n\t\t\t\t{\n\t\t\t\t\tstatic tTJSVariant tag_val(TJS_W(\"ch\"));\n\t\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &tag_val, DicObj);\n\t\t\t\t\ttTJSVariant ch_val(ttstr(CurLineStr + CurPos, 1));\n\t\t\t\t\tstatic ttstr text_name(TJSMapGlobalStringMap(TJS_W(\"text\")));\n\t\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t\ttext_name.AsVariantStringNoAddRef(), &ch_val, DicObj);\n\n\t\t\t\t\tif(RecordingMacro)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(ch == TJS_W('['))\n\t\t\t\t\t\t\tRecordingMacroStr += TJS_W(\"[[\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tRecordingMacroStr += ch;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// \\n  ( reline )\n\t\t\t\t\tstatic tTJSVariant r_val(TJS_W(\"r\"));\n\t\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &r_val, DicObj);\n\t\t\t\t\tif(RecordingMacro) RecordingMacroStr += TJS_W(\"[r]\");\n\t\t\t\t}\n\n\t\t\t\tif(CurLineStr[CurPos] == TJS_W('[')) CurPos++;\n\t\t\t\tCurPos++;\n\n\t\t\t\tif(!RecordingMacro && ExcludeLevel == -1)\n\t\t\t\t{\n\t\t\t\t\tDicObj->AddRef();\n\t\t\t\t\treturn DicObj;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tldelim = TJS_W(']');\n\t\t}\n\n\t\t// a tag\n\t\tbool condition = true;\n\t\tTagLine = CurLine;\n\t\ttjs_int tagstart = CurPos;\n\t\tCurPos ++;\n\n\t\tif(CurLineStr[CurPos] == 0) TVPThrowExceptionMessage(TVPKAGSyntaxError);\n\n\t\t// tag name\n\t\twhile(TVPIsWS(CurLineStr[CurPos])) CurPos ++;\n\t\tif(CurLineStr[CurPos] == 0) TVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\tconst tjs_char * tagnamestart = CurLineStr + CurPos;\n\t\twhile(CurLineStr[CurPos] && !TVPIsWS(CurLineStr[CurPos]) &&\n\t\t\tCurLineStr[CurPos] != ldelim)\n\t\t\t\tCurPos ++;\n\n\t\tif(tagnamestart == CurLineStr + CurPos)\n\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\n\t\tttstr tagname(tagnamestart, CurLineStr + CurPos - tagnamestart);\n\t\ttagname.ToLowerCase();\n\t\t{\n\n\t\t\ttTJSVariant tag_val(tagname);\n\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &tag_val, DicObj);\n\t\t}\n\n\t\t// check special control tags\n\t\tenum tSpecialTags\n\t\t{ tag_other, tag_if, tag_else, tag_elsif, tag_ignore, tag_endif, tag_endignore,\n\t\t\ttag_emb, tag_macro, tag_endmacro, tag_macropop, tag_erasemacro,\n\t\t\ttag_jump, tag_call, tag_return} tagkind;\n\t\tstatic bool tag_checker_init = false;\n\t\tstatic tTJSHashTable<ttstr, tjs_int> special_tags_hash;\n\t\tif(!tag_checker_init)\n\t\t{\n\t\t\ttag_checker_init = true;\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"if\")), (tjs_int)tag_if);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"ignore\")), (tjs_int)tag_ignore);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"endif\")), (tjs_int)tag_endif);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"endignore\")), (tjs_int)tag_endignore);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"else\")), (tjs_int)tag_else);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"elsif\")), (tjs_int)tag_elsif);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"emb\")), (tjs_int)tag_emb);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"macro\")), (tjs_int)tag_macro);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"endmacro\")), (tjs_int)tag_endmacro);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"macropop\")), (tjs_int)tag_macropop);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"erasemacro\")), (tjs_int)tag_erasemacro);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"jump\")), (tjs_int)tag_jump);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"call\")), (tjs_int)tag_call);\n\t\t\tspecial_tags_hash.Add(\n\t\t\t\tttstr(TJS_W(\"return\")), (tjs_int)tag_return);\n\t\t}\n\n\n\t\ttjs_int * tag = special_tags_hash.Find(tagname);\n\t\tif(ProcessSpecialTags)\n\t\t\ttagkind = tag?(tSpecialTags)*tag:tag_other;\n\t\telse\n\t\t\ttagkind = tag_other;\n\n\t\tif(tagkind == tag_macro) RecordingMacroName.Clear();\n\n\n#define TVP_KAG_STEP_NEXT \\\n\t\t\t\t\t\tif(ldelim == 0) \\\n\t\t\t\t\t\t{ \\\n\t\t\t\t\t\t\tCurLine++; \\\n\t\t\t\t\t\t\tCurPos = 0; \\\n\t\t\t\t\t\t\tLineBufferUsing = false; \\\n\t\t\t\t\t\t} \\\n\t\t\t\t\t\telse \\\n\t\t\t\t\t\t{ \\\n\t\t\t\t\t\t\tCurPos++; \\\n\t\t\t\t\t\t}\n\n\n\t\t// tag attributes\n\t\twhile(true)\n\t\t{\n\t\t\twhile(TVPIsWS(CurLineStr[CurPos])) CurPos ++;\n\n\t\t\tif(CurLineStr[CurPos] == ldelim)\n\t\t\t{\n\t\t\t\t// tag ended\n\n\t\t\t\tbool ismacro = false;\n\t\t\t\tttstr macrocontent;\n\n\t\t\t\tif(condition && ExcludeLevel == -1)\n\t\t\t\t{\n\t\t\t\t\tif(tagkind == tag_endmacro)\n\t\t\t\t\t{\n\t\t\t\t\t\t// macro recording ended\n\t\t\t\t\t\t// endmacro\n\t\t\t\t\t\tif(!RecordingMacro)\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t\tRecordingMacro = false;\n\t\t\t\t\t\tif(DebugLevel >= tkdlVerbose)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVPAddLog(TJS_W(\"macro : \") + RecordingMacroName +\n\t\t\t\t\t\t\t\tTJS_W(\" : \") + RecordingMacroStr);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tRecordingMacroStr += TJS_W(\"[macropop]\");\n\t\t\t\t\t\t\t// ensure macro arguments are to be popped\n\n\t\t\t\t\t\t// register macro\n\t\t\t\t\t\ttTJSVariant macrocontent(RecordingMacroStr);\n\t\t\t\t\t\tMacros->PropSet(TJS_MEMBERENSURE, RecordingMacroName.c_str(),\n\t\t\t\t\t\t\tNULL, &macrocontent, Macros);\n\t\t\t\t\t}\n\n\t\t\t\t\t// record macro\n\t\t\t\t\tif(RecordingMacro)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(ldelim != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// normal tag\n\t\t\t\t\t\t\tRecordingMacroStr += ttstr(CurLineStr + tagstart,\n\t\t\t\t\t\t\t\tCurPos - tagstart + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// line command\n\t\t\t\t\t\t\tif(CurPos - tagstart >= 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tRecordingMacroStr += TJS_W(\"[\") +\n\t\t\t\t\t\t\t\t\tttstr(CurLineStr + tagstart +1,\n\t\t\t\t\t\t\t\t\tCurPos - tagstart - 1) + TJS_W(\"]\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tTVP_KAG_STEP_NEXT;\n\n\t\t\t\t\t\tbreak; // break\n\t\t\t\t\t}\n\n\n\t\t\t\t\t// is macro ?\n\t\t\t\t\ttTJSVariant macroval;\n\t\t\t\t\tismacro = TJS_SUCCEEDED(\n\t\t\t\t\t\tMacros->PropGet(0, tagname.c_str(), NULL, &macroval, Macros));\n\t\t\t\t\tif(ismacro) ismacro = macroval.Type() != tvtVoid;\n\t\t\t\t\tif(ismacro) macrocontent = ttstr(macroval);\n\t\t\t\t}\n\n\t\t\t\t// tag-specific processing\n\t\t\t\tif(tagkind == tag_other && !ismacro)\n\t\t\t\t{\n\t\t\t\t\t// not a control tag\n\n\t\t\t\t\tTVP_KAG_STEP_NEXT;\n\n\t\t\t\t\tif(condition && ExcludeLevel == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tDicObj->AddRef();\n\t\t\t\t\t\treturn DicObj;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// if/ignore\n\t\t\t\tif(tagkind == tag_if || tagkind == tag_ignore)\n\t\t\t\t{\n\t\t\t\t\tIfLevel ++;\n\t\t\t\t\tIfLevelExecutedStack.push_back(false);\n\t\t\t\t\tExcludeLevelStack.push_back(ExcludeLevel);\n\n\t\t\t\t\tif(ExcludeLevel == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\tttstr exp;\n\t\t\t\t\t\tDicObj->PropGet(0, __exp_name.c_str(), __exp_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\texp = val;\n\t\t\t\t\t\tif(exp == TJS_W(\"\"))\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t\tTVPExecuteExpression(exp, Owner, &val);\n\n\t\t\t\t\t\tbool cond = val.operator bool();\n\t\t\t\t\t\tif(tagkind == tag_ignore) cond = ! cond;\n\n\t\t\t\t\t\tIfLevelExecutedStack.back() = cond;\n\t\t\t\t\t\tif(!cond)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tExcludeLevel = IfLevel;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// elsif\n\t\t\t\tif(tagkind == tag_elsif)\n\t\t\t\t{\n\t\t\t\t\tif(IfLevelExecutedStack.empty())\n\t\t\t\t\t{\n\t\t\t\t\t\t// no preceded if/ignore tag.\n\t\t\t\t\t\t// should throw an exception?\n\t\t\t\t\t}\n\t\t\t\t\telse if(IfLevelExecutedStack.back())\n\t\t\t\t\t{\n\t\t\t\t\t\tExcludeLevel = IfLevel;\n\t\t\t\t\t}\n\t\t\t\t\telse if(IfLevel == ExcludeLevel){\n\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\tttstr exp;\n\t\t\t\t\t\tDicObj->PropGet(0, __exp_name.c_str(), __exp_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\texp = val;\n\t\t\t\t\t\t//const std::string s = exp.AsStdString();\n\t\t\t\t\t\tif(exp == TJS_W(\"\"))\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t\tTVPExecuteExpression(exp, Owner, &val);\n\n\t\t\t\t\t\tbool cond = val.operator bool();\n\t\t\t\t\t\tif(cond)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIfLevelExecutedStack.back() = true;\n\t\t\t\t\t\t\tExcludeLevel = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// else\n\t\t\t\tif(tagkind == tag_else)\n\t\t\t\t{\n\t\t\t\t\tif(IfLevelExecutedStack.empty())\n\t\t\t\t\t{\n\t\t\t\t\t\t// no preceded if/ignore tag.\n\t\t\t\t\t\t// should throw an exception?\n\t\t\t\t\t}\n\t\t\t\t\telse if(IfLevelExecutedStack.back())\n\t\t\t\t\t{\n\t\t\t\t\t\tExcludeLevel = IfLevel;\n\t\t\t\t\t}\n\t\t\t\t\telse if(IfLevel == ExcludeLevel)\n\t\t\t\t\t{\n\t\t\t\t\t\tIfLevelExecutedStack.back() = true;\n\t\t\t\t\t\tExcludeLevel = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// endif/endignore\n\t\t\t\tif(tagkind == tag_endif || tagkind == tag_endignore)\n\t\t\t\t{\n\t\t\t\t\t// endif\n\t\t\t\t\tif(!ExcludeLevelStack.empty())\n\t\t\t\t\t{\n\t\t\t\t\t\tExcludeLevel = ExcludeLevelStack.back();\n\t\t\t\t\t\tExcludeLevelStack.pop_back();\n\t\t\t\t\t}\n\t\t\t\t\tif(!IfLevelExecutedStack.empty())\n\t\t\t\t\t\tIfLevelExecutedStack.pop_back();\n\n\t\t\t\t\tIfLevel --;\n\t\t\t\t\tif(IfLevel < 0) IfLevel = 0;\n\n\t\t\t\t\tTVP_KAG_STEP_NEXT;\n\n\t\t\t\t\tbreak; // break\n\t\t\t\t}\n\n\n\t\t\t\tif(condition && ExcludeLevel == -1)\n\t\t\t\t{\n\t\t\t\t\tif(tagkind == tag_emb || (ismacro && tagkind==tag_other))\n\t\t\t\t\t{\n\t\t\t\t\t\t// embed string\n\t\t\t\t\t\t// insert string to current position\n\t\t\t\t\t\tif(ldelim != 0) CurPos++;\n\n\t\t\t\t\t\tif(!ismacro)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// execute expression\n\t\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\t\tttstr exp;\n\t\t\t\t\t\t\tDicObj->PropGet(0, __exp_name.c_str(), __exp_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\t\texp = val;\n\t\t\t\t\t\t\tif(exp == TJS_W(\"\"))\n\t\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t\t\tTVPExecuteExpression(exp, Owner, &val);\n\t\t\t\t\t\t\texp = val;\n\n\t\t\t\t\t\t\t// count '['\n\t\t\t\t\t\t\tconst tjs_char *p = exp.c_str();\n\t\t\t\t\t\t\ttjs_int r_count = 0;\n\t\t\t\t\t\t\twhile(*p)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(*p == TJS_W('[')) r_count++;\n\t\t\t\t\t\t\t\tp++;\n\t\t\t\t\t\t\t\tr_count++;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttjs_int curposlen = TJS_strlen(CurLineStr + CurPos);\n\t\t\t\t\t\t\ttjs_int finallen = r_count + tagstartpos + curposlen;\n\n\t\t\t\t\t\t\tif(ldelim == 0 && !IgnoreCR) finallen++;\n\n\t\t\t\t\t\t\tttstr newbuf;\n\n\t\t\t\t\t\t\ttjs_char *d = newbuf.AllocBuffer(finallen + 1);\n\n\t\t\t\t\t\t\tTJS_strncpy_s(d, finallen + 1, CurLineStr, tagstartpos);\n\t\t\t\t\t\t\td += tagstartpos;\n\n\t\t\t\t\t\t\t// escape '['\n\t\t\t\t\t\t\tp = exp.c_str();\n\t\t\t\t\t\t\twhile(*p)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(*p == TJS_W('['))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t*d = TJS_W('['); d++;\n\t\t\t\t\t\t\t\t\t*d = TJS_W('['); d++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t*d = *p; d++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp++;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tTJS_strcpy(d, CurLineStr + CurPos);\n\n\t\t\t\t\t\t\tif(ldelim == 0 && !IgnoreCR)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\td += curposlen;\n\t\t\t\t\t\t\t\t*d = TJS_W('\\\\'); d++;\n\t\t\t\t\t\t\t\t*d = 0;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnewbuf.FixLen();\n\t\t\t\t\t\t\tLineBuffer = newbuf;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_int maclen = macrocontent.GetLen();\n\t\t\t\t\t\t\ttjs_int curposlen = TJS_strlen(CurLineStr + CurPos);\n\t\t\t\t\t\t\ttjs_int finallen = tagstartpos + maclen + curposlen;\n\n\t\t\t\t\t\t\tif(ldelim == 0 && !IgnoreCR) finallen++;\n\n\t\t\t\t\t\t\tttstr newbuf;\n\t\t\t\t\t\t\ttjs_char *d = newbuf.AllocBuffer(finallen + 1);\n\n\t\t\t\t\t\t\tTJS_strncpy_s(d, finallen + 1, CurLineStr, tagstartpos);\n\t\t\t\t\t\t\td += tagstartpos;\n\t\t\t\t\t\t\tTJS_strcpy(d, macrocontent.c_str());\n\t\t\t\t\t\t\td += maclen;\n\t\t\t\t\t\t\tTJS_strcpy(d, CurLineStr + CurPos);\n\n\t\t\t\t\t\t\tif(ldelim == 0 && !IgnoreCR)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\td += curposlen;\n\t\t\t\t\t\t\t\t*d = TJS_W('\\\\'); d++;\n\t\t\t\t\t\t\t\t*d = 0;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnewbuf.FixLen();\n\t\t\t\t\t\t\tLineBuffer = newbuf;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tCurLineStr = LineBuffer.c_str();\n\t\t\t\t\t\tCurPos = tagstartpos;\n\n\t\t\t\t\t\tLineBufferUsing = true;\n\n\t\t\t\t\t\t// push macro arguments\n\t\t\t\t\t\tif(ismacro) PushMacroArgs(DicObj);\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse if(tagkind == tag_jump)\n\t\t\t\t\t{\n\t\t\t\t\t\t// jump tag\n\t\t\t\t\t\tttstr attrib_storage;\n\t\t\t\t\t\tttstr attrib_target;\n\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\tDicObj->PropGet(0, __storage_name.c_str(), __storage_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_storage = val;\n\t\t\t\t\t\tDicObj->PropGet(0, __target_name.c_str(), __target_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_target = val;\n\n\n\t\t\t\t\t\t// fire onJump event\n\t\t\t\t\t\tbool process = true;\n\t\t\t\t\t\tif(Owner)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTJSVariant param(DicObj, DicObj);\n\t\t\t\t\t\t\ttTJSVariant *pparam = &param;\n\t\t\t\t\t\t\tstatic ttstr event_name(TJSMapGlobalStringMap(TJS_W(\"onJump\")));\n\t\t\t\t\t\t\ttTJSVariant res;\n\t\t\t\t\t\t\ttjs_error er = Owner->FuncCall(0, event_name.c_str(),\n\t\t\t\t\t\t\t\tevent_name.GetHint(), &res, 1, &pparam, Owner);\n\t\t\t\t\t\t\tif(er == TJS_S_OK) process = res.operator bool();\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif(process)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tGoToStorageAndLabel(attrib_storage, attrib_target);\n\t\t\t\t\t\t\tgoto parse_start; // re-start parsing\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(tagkind == tag_call)\n\t\t\t\t\t{\n\t\t\t\t\t\t// call tag\n\t\t\t\t\t\tttstr attrib_storage;\n\t\t\t\t\t\tttstr attrib_target;\n\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\tDicObj->PropGet(0, __storage_name.c_str(), __storage_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_storage = val;\n\t\t\t\t\t\tDicObj->PropGet(0, __target_name.c_str(), __target_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_target = val;\n\n\t\t\t\t\t\t// fire onCall event\n\t\t\t\t\t\tbool process = true;\n\t\t\t\t\t\tif(Owner)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTJSVariant param(DicObj, DicObj);\n\t\t\t\t\t\t\ttTJSVariant *pparam = &param;\n\t\t\t\t\t\t\tstatic ttstr event_name(TJSMapGlobalStringMap(TJS_W(\"onCall\")));\n\t\t\t\t\t\t\ttTJSVariant res;\n\t\t\t\t\t\t\ttjs_error er = Owner->FuncCall(0, event_name.c_str(),\n\t\t\t\t\t\t\t\tevent_name.GetHint(), &res, 1, &pparam, Owner);\n\t\t\t\t\t\t\tif(er == TJS_S_OK) process = res.operator bool();\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif(process)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVP_KAG_STEP_NEXT;\n\n\t\t\t\t\t\t\tPushCallStack();\n\t\t\t\t\t\t\tGoToStorageAndLabel(attrib_storage, attrib_target);\n\t\t\t\t\t\t\tgoto parse_start;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(tagkind == tag_return)\n\t\t\t\t\t{\n\t\t\t\t\t\t// return tag\n\t\t\t\t\t\tttstr attrib_storage;\n\t\t\t\t\t\tttstr attrib_target;\n\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\tDicObj->PropGet(0, __storage_name.c_str(), __storage_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_storage = val;\n\t\t\t\t\t\tDicObj->PropGet(0, __target_name.c_str(), __target_name.GetHint(), &val, DicObj);\n\t\t\t\t\t\tattrib_target = val;\n\n\t\t\t\t\t\t// fire onReturn event\n\t\t\t\t\t\tbool process = true;\n\t\t\t\t\t\tif(Owner)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTJSVariant param(DicObj, DicObj);\n\t\t\t\t\t\t\ttTJSVariant *pparam = &param;\n\t\t\t\t\t\t\tstatic ttstr event_name(TJSMapGlobalStringMap(TJS_W(\"onReturn\")));\n\t\t\t\t\t\t\ttTJSVariant res;\n\t\t\t\t\t\t\ttjs_error er = Owner->FuncCall(0, event_name.c_str(),\n\t\t\t\t\t\t\t\tevent_name.GetHint(), &res, 1, &pparam, Owner);\n\t\t\t\t\t\t\tif(er == TJS_S_OK) process = res.operator bool();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(process)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPopCallStack(attrib_storage, attrib_target);\n\t\t\t\t\t\t\tgoto parse_start;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(tagkind == tag_macro)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\t\tDicObj->PropGet(0, TJS_W(\"name\"), 0, &val, DicObj);\n\t\t\t\t\t\t\tRecordingMacroName = val;\n\t\t\t\t\t\t\tRecordingMacroName.ToLowerCase();\n\t\t\t\t\t\t\tif(RecordingMacroName == TJS_W(\"\"))\n\t\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t\t\t\t\t// missing macro name\n\t\t\t\t\t\t\tRecordingMacro = true; // start recording macro\n\t\t\t\t\t\t\tRecordingMacroStr.Clear();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(tagkind == tag_macropop)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// pop macro arguments\n\t\t\t\t\t\t\tPopMacroArgs();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(tagkind == tag_erasemacro)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\t\t\tDicObj->PropGet(0, TJS_W(\"name\"), 0, &val, DicObj);\n\t\t\t\t\t\t\tttstr macroname = val;\n\t\t\t\t\t\t\tif(TJS_FAILED(\n\t\t\t\t\t\t\t\tMacros->DeleteMember(0, macroname.c_str(), 0, Macros)))\n\t\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPUnknownMacroName, macroname);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tTVP_KAG_STEP_NEXT;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\n\t\t\t// attrib name\n\t\t\tif(CurLineStr[CurPos] == TJS_W('*'))\n\t\t\t{\n\t\t\t\t// macro entity all\n\t\t\t\tif(!RecordingMacro)\n\t\t\t\t{\n\t\t\t\t\tiTJSDispatch2 *dsp = GetMacroTopNoAddRef();\n\t\t\t\t\tif(dsp)\n\t\t\t\t\t{\n\t\t\t\t\t\t// assign macro arguments to current arguments\n\t\t\t\t\t\ttTJSVariant src(dsp, dsp);\n\t\t\t\t\t\ttTJSVariant *psrc = &src;\n\t\t\t\t\t\tDicAssign->FuncCall(0, NULL, NULL, NULL, 1, &psrc, DicObj);\n\t\t\t\t\t}\n\t\t\t\t\ttTJSVariant tag_val(tagname);\n\t\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\t\t__tag_name.AsVariantStringNoAddRef(), &tag_val, DicObj);\n\t\t\t\t\t\t\t// reset tag_name\n\t\t\t\t}\n\n\t\t\t\tCurPos++;\n\t\t\t\twhile(CurLineStr[CurPos] && TVPIsWS(CurLineStr[CurPos])) CurPos ++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst tjs_char *attribnamestart = CurLineStr + CurPos;\n\t\t\twhile(CurLineStr[CurPos] && !TVPIsWS(CurLineStr[CurPos]) &&\n\t\t\t\tCurLineStr[CurPos] != TJS_W('=') && CurLineStr[CurPos] != ldelim)\n\t\t\t\t\tCurPos ++;\n\n\t\t\tconst tjs_char *attribnameend = CurLineStr + CurPos;\n\n\t\t\tttstr attribname(attribnamestart, attribnameend - attribnamestart);\n\t\t\tattribname.ToLowerCase();\n\n\t\t\t// =\n\t\t\twhile(TVPIsWS(CurLineStr[CurPos])) CurPos ++;\n\n\t\t\tbool entity = false;\n\t\t\tbool macroarg = false;\n\t\t\tttstr value;\n\n\t\t\tif(CurLineStr[CurPos] != TJS_W('='))\n\t\t\t{\n\t\t\t\t// arrtibute value omitted\n\t\t\t\tvalue = TJS_W(\"true\"); // always true\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\tCurPos++;\n\t\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\twhile(CurLineStr[CurPos] && TVPIsWS(CurLineStr[CurPos])) CurPos ++;\n\t\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\n\t\t\t\t// attrib value\n\t\t\t\ttjs_char vdelim = 0; // value delimiter\n\n\t\t\t\tif(CurLineStr[CurPos] == TJS_W('&'))\n\t\t\t\t\tentity = true, CurPos++;\n\t\t\t\telse if(CurLineStr[CurPos] == TJS_W('%'))\n\t\t\t\t\tmacroarg = true, CurPos++;\n\n\t\t\t\tif(CurLineStr[CurPos] == TJS_W('\\\"') ||\n\t\t\t\t\tCurLineStr[CurPos] == TJS_W('\\''))\n\t\t\t\t{\n\t\t\t\t\tvdelim = CurLineStr[CurPos];\n\t\t\t\t\tCurPos++;\n\t\t\t\t}\n\n\t\t\t\tconst tjs_char *valuestart = CurLineStr + CurPos;\n\n\t\t\t\twhile(CurLineStr[CurPos] &&\n\t\t\t\t\t(vdelim ? (CurLineStr[CurPos] != vdelim) :\n\t\t\t\t\t\t(CurLineStr[CurPos] != ldelim &&\n\t\t\t\t\t\t\t!TVPIsWS(CurLineStr[CurPos])) ) )\n\t\t\t\t{\n\t\t\t\t\tif(CurLineStr[CurPos] == TJS_W('`'))\n\t\t\t\t\t{\n\t\t\t\t\t\t// escaped with '`'\n\t\t\t\t\t\tCurPos++;\n\t\t\t\t\t\tif(CurLineStr[CurPos] == 0)\n\t\t\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\t\t}\n\t\t\t\t\tCurPos++;\n\t\t\t\t}\n\n\t\t\t\tif(ldelim != 0 && CurLineStr[CurPos] == 0)\n\t\t\t\t\tTVPThrowExceptionMessage(TVPKAGSyntaxError);\n\t\t\t\tconst tjs_char *valueend = CurLineStr + CurPos;\n\n\t\t\t\tif(vdelim) CurPos ++;\n\n\t\t\t\t// unescape ` character of value\n\t\t\t\tvalue = ttstr(valuestart, valueend - valuestart);\n\t\t\t\tif(valueend != valuestart)\n\t\t\t\t{\n\t\t\t\t\t// value has at least one character\n\t\t\t\t\ttjs_char * vp = value.Independ();\n\t\t\t\t\ttjs_char * wvp = vp;\n\n\t\t\t\t\tif(!entity && *vp == TJS_W('&')) entity = true, vp++;\n\t\t\t\t\tif(!macroarg && *vp == TJS_W('%')) macroarg = true, vp++;\n\n\t\t\t\t\twhile(*vp)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(*vp == TJS_W('`'))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvp++;\n\t\t\t\t\t\t\tif(!*vp) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t*wvp = *vp;\n\t\t\t\t\t\tvp++;\n\t\t\t\t\t\twvp++;\n\t\t\t\t\t}\n\t\t\t\t\t*wvp = 0;\n\t\t\t\t\tvalue.FixLen();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// special attibute processing\n\t\t\tbool store = true;\n\t\t\tif((!RecordingMacro && ExcludeLevel == -1) || tagkind == tag_elsif)\n\t\t\t{\n\t\t\t\t// process expression entity or macro argument\n\t\t\t\tif(entity)\n\t\t\t\t{\n\t\t\t\t\tTVPExecuteExpression(value, Owner, &ValueVariant);\n\t\t\t\t\tif(ValueVariant.Type() != tvtVoid) ValueVariant.ToString();\n\t\t\t\t}\n\t\t\t\telse if(macroarg)\n\t\t\t\t{\n\t\t\t\t\tiTJSDispatch2 *args = GetMacroTopNoAddRef();\n\t\t\t\t\tif(args)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_char *vp = TJS_strchr(const_cast<tjs_char*>(value.c_str()), TJS_W('|'));\n\n\t\t\t\t\t\tif(vp)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tttstr name(value.c_str(), vp - value.c_str());\n\t\t\t\t\t\t\targs->PropGet(0, name.c_str(), NULL, &ValueVariant, args);\n\t\t\t\t\t\t\tif(ValueVariant.Type() == tvtVoid)\n\t\t\t\t\t\t\t\t\tValueVariant = ttstr(vp + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targs->PropGet(0, value.c_str(), NULL, &ValueVariant, args);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tValueVariant = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tValueVariant = value;\n\t\t\t\t}\n\n\t\t\t\tif(attribname == TJS_W(\"cond\"))\n\t\t\t\t{\n\t\t\t\t\t// condition\n\n\t\t\t\t\ttTJSVariant val;\n\t\t\t\t\tTVPExecuteExpression(ttstr(ValueVariant), Owner, &val);\n\t\t\t\t\tcondition = val.operator bool();\n\t\t\t\t\tstore = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// store value into the dictionary object\n\t\t\tif(store)\n\t\t\t\tDicObj->PropSetByVS(TJS_MEMBERENSURE,\n\t\t\t\t\tattribname.AsVariantStringNoAddRef(), &ValueVariant, DicObj);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_KAGParser::GetNextTag()\n{\n\treturn _GetNextTag();\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 *tTJSNI_KAGParser::GetMacroTopNoAddRef() const\n{\n\tif(MacroArgStackDepth == 0) return NULL;\n\n\treturn MacroArgs[MacroArgStackDepth - 1];\n}\n//---------------------------------------------------------------------------\n\n\n\nstatic iTJSNativeInstance * TJS_INTF_METHOD Create_NI_KAGParser() {\n\treturn new tTJSNI_KAGParser();\n}\n\n//---------------------------------------------------------------------------\n// tTJSNC_KAGParser : KAGParser TJS native class\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateNativeClass_KAGParser() {\n\ttTJSNativeClassForPlugin * classobj = TJSCreateNativeClassForPlugin(TJS_W(\"KAGParser\"), Create_NI_KAGParser);\n\t// register native methods/properties\n#undef TJS_NCM_REG_THIS\n#define TJS_NCM_REG_THIS classobj\n\n\tTJS_BEGIN_NATIVE_MEMBERS(KAGParser)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n// constructor/methods\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_KAGParser,\n\t/*TJS class name*/KAGParser)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/KAGParser)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadScenario)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->LoadScenario(*param[0]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/loadScenario)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/goToLabel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->GoToLabel(*param[0]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/goToLabel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/callLabel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->CallLabel(*param[0]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/callLabel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getNextTag)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n//\tif(numparams < 0) return TJS_E_BADPARAMCOUNT;\n\tiTJSDispatch2 *dsp = _this->GetNextTag();\n\tif(dsp == NULL)\n\t{\n\t\tif(result) result->Clear(); // return void ( not null )\n\t}\n\telse\n\t{\n\t\tif(result) *result = tTJSVariant(dsp, dsp);\n\t\tdsp->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getNextTag)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/assign)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_KAGParser *src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\tClassID_KAGParser, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPKAGSpecifyKAGParser);\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPKAGSpecifyKAGParser);\n\t}\n\n\t_this->Assign(*src);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/assign)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\t_this->Clear();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/clear)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/store)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\tiTJSDispatch2 * dsp = _this->Store();\n\tif(result) *result = tTJSVariant(dsp, dsp);\n\tdsp->Release();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/store)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/restore)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tiTJSDispatch2 * dsp = param[0]->AsObjectNoAddRef();\n\n\t_this->Restore(dsp);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/restore)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clearCallStack)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\t_this->ClearCallStack();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/clearCallStack)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/popMacroArgs) // undoc\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\t_this->PopMacroArgs();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/popMacroArgs)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/interrupt)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\t_this->Interrupt();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/interrupt)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/resetInterrupt)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\n\t_this->ResetInterrupt();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/resetInterrupt)\n//----------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n\n\n\n//----------------------------------------------------------------------\n// properties\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(curLine)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = _this->GetCurLine();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(curLine)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(curPos)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = _this->GetCurPos();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(curPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(curLineStr)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = ttstr(_this->GetCurLineStr());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(curLineStr)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(processSpecialTags)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = (tjs_int)_this->GetProcessSpecialTags();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t_this->SetProcessSpecialTags(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(processSpecialTags)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(ignoreCR)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = (tjs_int)_this->GetIgnoreCR();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t_this->SetIgnoreCR(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(ignoreCR)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(debugLevel)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = (tjs_int)_this->GetDebugLevel();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t_this->SetDebugLevel((tTVPKAGDebugLevel)(tjs_int)(*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(debugLevel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(macros)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\tiTJSDispatch2 *macros = _this->GetMacrosNoAddRef();\n\t\t*result = tTJSVariant(macros, macros);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(macros)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(macroParams)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\tiTJSDispatch2 *params = _this->GetMacroTopNoAddRef();\n\t\t*result = tTJSVariant(params, params);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(macroParams)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mp)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\tiTJSDispatch2 *params = _this->GetMacroTopNoAddRef();\n\t\t*result = tTJSVariant(params, params);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(callStackDepth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = _this->GetCallStackDepth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(callStackDepth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(curStorage)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = _this->GetStorageName();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t_this->LoadScenario(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(curStorage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(curLabel)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_KAGParser);\n\t\t*result = _this->GetCurLabel();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(curLabel)\n//---------------------------------------------------------------------------\n\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\t\n\treturn classobj;\n}\n#undef TJS_NATIVE_CLASSID_NAME\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/utils/KAGParser.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// KAG Parser Utility Class\n//---------------------------------------------------------------------------\n\n#ifndef KAGParserH\n#define KAGParserH\n//---------------------------------------------------------------------------\n\n//#include <windows.h>\n//#include \"tp_stub.h\"\n#include \"tjs.h\"\n#include \"tjsNative.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"DebugIntf.h\"\n#include \"StorageImpl.h\"\n#include \"TextStream.h\"\n#include \"MsgIntf.h\"\n#include \"PluginImpl.h\"\n#include \"CharacterSet.h\"\n#include \"TransIntf.h\"\n#include \"tjsHashSearch.h\"\n#include <vector>\nusing namespace TJS;\n/*[*/\n//---------------------------------------------------------------------------\n// KAG Parser debug level\n//---------------------------------------------------------------------------\nenum tTVPKAGDebugLevel\n{\n\ttkdlNone, // none is reported\n\ttkdlSimple, // simple report\n\ttkdlVerbose // complete report ( verbose )\n};\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// tTVPCharHolder\n//---------------------------------------------------------------------------\nclass tTVPCharHolder\n{\n\ttjs_char *Buffer;\n\tsize_t BufferSize;\npublic:\n\ttTVPCharHolder() : Buffer(NULL), BufferSize(0)\n\t{\n\t}\n\t~tTVPCharHolder()\n\t{\n\t\tClear();\n\t}\n\n\ttTVPCharHolder(const tTVPCharHolder &ref) : Buffer(NULL), BufferSize(0)\n\t{\n\t\toperator =(ref);\n\t}\n\n\tvoid Clear()\n\t{\n\t\tif(Buffer) delete [] Buffer, Buffer = NULL;\n\t\tBufferSize = 0;\n\t}\n\n\tvoid operator =(const tTVPCharHolder &ref)\n\t{\n\t\tClear();\n\t\tBufferSize = ref.BufferSize;\n\t\tBuffer = new tjs_char[BufferSize];\n\t\tmemcpy(Buffer, ref.Buffer, BufferSize *sizeof(tjs_char));\n\t}\n\n\tvoid operator =(const tjs_char *ref)\n\t{\n\t\tClear();\n\t\tif(ref)\n\t\t{\n\t\t\tBufferSize = TJS_strlen(ref) + 1;\n\t\t\tBuffer = new tjs_char[BufferSize];\n\t\t\tmemcpy(Buffer, ref, BufferSize*sizeof(tjs_char));\n\t\t}\n\t}\n\n\toperator const tjs_char *() const\n\t{\n\t\treturn Buffer;\n\t}\n\n\toperator tjs_char *()\n\t{\n\t\treturn Buffer;\n\t}\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPScenarioCacheItem : Scenario Cache Item\n//---------------------------------------------------------------------------\nclass tTVPScenarioCacheItem\n{\npublic:\n\tstruct tLine\n\t{\n\t\tconst tjs_char *Start;\n\t\ttjs_int Length;\n\t};\n\nprivate:\n\ttTVPCharHolder Buffer;\n\ttLine *Lines;\n\ttjs_int LineCount;\n\npublic:\n\tstruct tLabelCacheData\n\t{\n\t\ttjs_int Line;\n\t\ttjs_int Count;\n\t\ttLabelCacheData(tjs_int line, tjs_int count)\n\t\t{\n\t\t\tLine = line;\n\t\t\tCount = count;\n\t\t}\n\t};\n\npublic:\n\ttypedef tTJSHashTable<ttstr, tLabelCacheData> tLabelCacheHash;\nprivate:\n\ttLabelCacheHash LabelCache; // Label cache\n\tstd::vector<ttstr> LabelAliases;\n\tbool LabelCached; // whether the label is cached\n\n\ttjs_int RefCount;\n\npublic:\n\ttTVPScenarioCacheItem(const ttstr & name, bool istring);\nprotected:\n\t~tTVPScenarioCacheItem();\npublic:\n\tvoid AddRef();\n\tvoid Release();\nprivate:\n\tvoid LoadScenario(const ttstr & name, bool isstring);\n\t\t// load file or string to buffer\npublic:\n\tconst ttstr & GetLabelAliasFromLine(tjs_int line) const\n\t\t{ return LabelAliases[line]; }\n\tvoid EnsureLabelCache();\n\n\ttLine * GetLines() const { return Lines; }\n\ttjs_int GetLineCount() const { return LineCount; }\n\tconst tLabelCacheHash & GetLabelCache() const { return LabelCache; }\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_KAGParser\n//---------------------------------------------------------------------------\nclass tTJSNI_KAGParser : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\npublic:\n\ttTJSNI_KAGParser();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprivate:\n\tiTJSDispatch2 * Owner; // owner object\n\n\tiTJSDispatch2 * DicClear; // Dictionary.Clear method pointer\n\tiTJSDispatch2 * DicAssign; // Dictionary\n\tiTJSDispatch2 * DicObj; // DictionaryObject\n\n\tiTJSDispatch2 * Macros; // Macro Dictionary Object\n\n\tstd::vector<iTJSDispatch2 *> MacroArgs; // Macro arguments\n\ttjs_uint MacroArgStackDepth;\n\ttjs_uint MacroArgStackBase;\n\n\tstruct tCallStackData\n\t{\n\t\tttstr Storage; // caller storage\n\t\tttstr Label; // caller nearest label\n\t\ttjs_int Offset; // line offset from the label\n\t\tttstr OrgLineStr; // original line string\n\t\tttstr LineBuffer; // line string (if alive)\n\t\ttjs_int Pos;\n\t\tbool LineBufferUsing; // whether LineBuffer is used or not\n\t\ttjs_uint MacroArgStackBase;\n\t\ttjs_uint MacroArgStackDepth;\n\t\tstd::vector<tjs_int> ExcludeLevelStack;\n\t\tstd::vector<bool> IfLevelExecutedStack;\n        tjs_int ExcludeLevel;\n        tjs_int IfLevel;\n\n\t\ttCallStackData(const ttstr &storage, const ttstr &label,\n\t\t\ttjs_int offset, const ttstr &orglinestr, const ttstr &linebuffer,\n\t\t\ttjs_int pos, bool linebufferusing, tjs_uint macroargstackbase,\n\t\t\ttjs_uint macroargstackdepth,\n\t\t\tconst std::vector<tjs_int> &excludelevelstack, tjs_int excludelevel,\n\t\t\tconst std::vector<bool> &iflevelexecutedstack, tjs_int iflevel) :\n\t\t\tStorage(storage), Label(label), Offset(offset), OrgLineStr(orglinestr),\n\t\t\tLineBuffer(linebuffer), Pos(pos), LineBufferUsing(linebufferusing),\n\t\t\tMacroArgStackBase(macroargstackbase),\n\t\t\tMacroArgStackDepth(macroargstackdepth),\n\t\t\tExcludeLevelStack(excludelevelstack), ExcludeLevel(excludelevel),\n\t\t\tIfLevelExecutedStack(iflevelexecutedstack), IfLevel(iflevel) {;}\n\t};\n\tstd::vector<tCallStackData> CallStack;\n\n\ttTVPScenarioCacheItem * Scenario;\n\ttTVPScenarioCacheItem::tLine * Lines; // is copied from Scenario\n\ttjs_int LineCount; // is copied from Scenario\n\n\tttstr StorageName;\n\tttstr StorageShortName;\n\n\ttjs_int CurLine; // current processing line\n\ttjs_int CurPos; // current processing position ( column )\n\tconst tjs_char *CurLineStr; // current line string\n\tttstr LineBuffer; // line buffer ( if any macro/emb was expanded )\n\tbool LineBufferUsing;\n\tttstr CurLabel; // Current Label\n\tttstr CurPage; // Current Page Name\n\ttjs_int TagLine; // line number of previous tag\n\n\ttTVPKAGDebugLevel DebugLevel; // debugging log level\n\tbool ProcessSpecialTags; // whether to process special tags\n\tbool IgnoreCR; // CR is not interpreted as [r] tag when this is true\n\tbool RecordingMacro; // recording a macro\n\tttstr RecordingMacroStr; // recording macro content\n\tttstr RecordingMacroName; // recording macro's name\n\n\ttTJSVariant ValueVariant;\n\n\ttjs_int ExcludeLevel;\n\ttjs_int IfLevel;\n\n\tstd::vector<tjs_int> ExcludeLevelStack;\n\tstd::vector<bool> IfLevelExecutedStack;\n\n\tbool Interrupted;\n\npublic:\n\tvoid operator = (const tTJSNI_KAGParser & ref);\n\tiTJSDispatch2 *Store();\n\tvoid Restore(iTJSDispatch2 *dic);\n\n\tvoid Clear(); // clear all states\n\nprivate:\n\tvoid ClearBuffer(); // clear internal buffer\n\n\tvoid Rewind(); // set current position to first\n\n\tvoid BreakConditionAndMacro(); // break condition state and macro expansion\n\npublic:\n\tvoid LoadScenario(const ttstr & name);\n\tconst ttstr & GetStorageName() const { return StorageName; }\n\tvoid GoToLabel(const ttstr &name); // search label and set current position\n\tvoid GoToStorageAndLabel(const ttstr &storage, const ttstr &label);\n\tvoid CallLabel(const ttstr &name);\nprivate:\n\tbool SkipCommentOrLabel(); // skip comment or label and go to next line\n\n\tvoid PushMacroArgs(iTJSDispatch2 *args);\npublic:\n\tvoid PopMacroArgs();\nprivate:\n\tvoid ClearMacroArgs();\n\tvoid PopMacroArgsTo(tjs_uint base);\n\n\tvoid FindNearestLabel(tjs_int start, tjs_int &labelline, ttstr &labelname);\n\n\tvoid PushCallStack();\n\tvoid PopCallStack(const ttstr &storage, const ttstr &label);\n\tvoid StoreIntStackToDic(iTJSDispatch2 *dic, std::vector<tjs_int> &stack, const tjs_char *membername);\n\tvoid StoreBoolStackToDic(iTJSDispatch2 *dic, std::vector<bool> &stack, const tjs_char *membername);\n\tvoid RestoreIntStackFromStr(std::vector<tjs_int> &stack, const ttstr &str);\n\tvoid RestoreBoolStackFromStr(std::vector<bool> &stack, const ttstr &str);\n\npublic:\n\tvoid ClearCallStack();\n\n\tvoid Interrupt() { Interrupted = true; };\n\tvoid ResetInterrupt() { Interrupted = false; };\n\nprivate:\n\tiTJSDispatch2 * _GetNextTag();\n\npublic:\n\tiTJSDispatch2 * GetNextTag();\n\n\tconst ttstr & GetCurLabel() const { return CurLabel; }\n\ttjs_int GetCurLine() const { return CurLine; }\n\ttjs_int GetCurPos() const { return CurPos; }\n\tconst tjs_char* GetCurLineStr() const { return CurLineStr; }\n\n\tvoid SetProcessSpecialTags(bool b) { ProcessSpecialTags = b; }\n\tbool GetProcessSpecialTags() const { return ProcessSpecialTags; }\n\n\tvoid SetIgnoreCR(bool b) { IgnoreCR = b; }\n\tbool GetIgnoreCR() const { return IgnoreCR; }\n\n\tvoid SetDebugLevel(tTVPKAGDebugLevel level) { DebugLevel = level; }\n\ttTVPKAGDebugLevel GetDebugLevel(void) const { return DebugLevel; }\n\n\tiTJSDispatch2 *GetMacrosNoAddRef() const { return Macros; }\n\n\tiTJSDispatch2 *GetMacroTopNoAddRef() const;\n\t\t// get current macro argument (parameters)\n\n\ttjs_int GetCallStackDepth() const { return CallStack.size(); }\n\n\tvoid Assign(const tTJSNI_KAGParser &ref) { operator =(ref); }\n\n};\n\nextern iTJSDispatch2 * TVPCreateNativeClass_KAGParser();\n\n#if 0\n//---------------------------------------------------------------------------\n// tTJSNC_KAGParser\n//---------------------------------------------------------------------------\nclass tTJSNC_KAGParser : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_KAGParser();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\tiTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n#endif\n\n#endif\n"
  },
  {
    "path": "src/core/utils/MathAlgorithms.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief 数学関数群\n//---------------------------------------------------------------------------\n\n#ifndef RISA_MATHALGOLITHMS_H\n#define RISA_MATHALGOLITHMS_H\n#define _USE_MATH_DEFINES\n#include <math.h>\n\n//---------------------------------------------------------------------------\n\n// 共通\n\n//---------------------------------------------------------------------------\n/**\n * atan2 の高速版 (1x float, C言語版)\n * @note\t精度はあまり良くない。10bitぐらい。 @r\n *\t\t\t原典: http://www.dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm\n */\nstatic inline float VFast_arctan2(float y, float x)\n{\n   static const float coeff_1 = M_PI/4;\n   static const float coeff_2 = 3*coeff_1;\n   float angle;\n   float abs_y = fabs(y)+1e-10;     // kludge to prevent 0/0 condition\n   if (x>=0)\n   {\n      float r = (x - abs_y) / (x + abs_y);\n      angle = coeff_1 - coeff_1 * r;\n   }\n   else\n   {\n      float r = (x + abs_y) / (abs_y - x);\n      angle = coeff_2 - coeff_1 * r;\n   }\n   if (y < 0)\n     return(-angle);     // negate if in quad III or IV\n   else\n     return(angle);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nstatic inline float VFast_atan2_madd(float a, float b, float c) { return a*b+c; }\nstatic inline float VFast_atan2_nmsub(float a, float b, float c) { return -(a*b-c); }\nstatic inline float VFast_atan2_round(float a) { return (a>0)?(int)(a+0.5):(int)(a-0.5); }\n\n/**\n * sincos の高速版 (1x float, C言語版)\n * @note\t原典: http://arxiv.org/PS_cache/cs/pdf/0406/0406049.pdf\n */\nstatic inline void VFast_sincos(float v, float &sin, float &cos)\n{\n\tconst float  ss1 =  1.5707963235  ;\n\tconst float  ss2 =  -0.645963615  ;\n\tconst float  ss3 =  0.0796819754  ;\n\tconst float  ss4 =  -0.0046075748 ;\n\tconst float  cc1 =  -1.2336977925 ;\n\tconst float  cc2 =  0.2536086171  ;\n\tconst float  cc3 =  -0.0204391631 ;\n\n\tfloat s1, s2, c1, c2, fixmag1;\n\tfloat x1=VFast_atan2_madd(v, (float)(1.0/(2.0*3.1415926536)), (float)(0.0));\n\t/* q1=x/2pi reduced onto (-0.5,0.5), q2=q1**2 */\n\tfloat q1=VFast_atan2_nmsub(VFast_atan2_round(x1), (float)(1.0), x1);\n\tfloat q2=VFast_atan2_madd(q1, q1, (float)(0.0));\n\ts1= VFast_atan2_madd(q1,\n\t\t\tVFast_atan2_madd(q2,\n\t\t\t\tVFast_atan2_madd(q2,\n\t\t\t\t\tVFast_atan2_madd(q2, (float)(ss4),\n\t\t\t\t\t\t\t\t(float)(ss3)),\n\t\t\t\t\t\t\t\t\t(float)( ss2)),\n\t\t\t\t\t\t\t(float)(ss1)),\n\t\t\t\t\t\t(float)(0.0));\n\tc1= VFast_atan2_madd(q2,\n\t\t\tVFast_atan2_madd(q2,\n\t\t\t\tVFast_atan2_madd(q2, (float)(cc3),\n\t\t\t\t(float)(cc2)),\n\t\t\t(float)(cc1)),\n\t\t(float)(1.0));\n\n\t/* now, do one out of two angle-doublings to get sin & cos theta/2 */\n\tc2=VFast_atan2_nmsub(s1, s1, VFast_atan2_madd(c1, c1, (float)(0.0)));\n\ts2=VFast_atan2_madd((float)(2.0), VFast_atan2_madd(s1, c1, (float)(0.0)), (float)(0.0));\n\n\t/* now, cheat on the correction for magnitude drift...\n\tif the pair has drifted to (1+e)*(cos, sin),\n\tthe next iteration will be (1+e)**2*(cos, sin)\n\twhich is, for small e, (1+2e)*(cos,sin).\n\tHowever, on the (1+e) error iteration,\n\tsin**2+cos**2=(1+e)**2=1+2e also,\n\tso the error in the square of this term\n\twill be exactly the error in the magnitude of the next term.\n\tThen, multiply final result by (1-e) to correct */\n\n\t/* this works with properly normalized sine-cosine functions, but un-normalized is more */\n\tfixmag1=VFast_atan2_nmsub(s2,s2, VFast_atan2_nmsub(c2, c2, (float)(2.0)));\n\n\tc1=VFast_atan2_nmsub(s2, s2, VFast_atan2_madd(c2, c2, (float)(0.0)));\n\ts1=VFast_atan2_madd((float)(2.0), VFast_atan2_madd(s2, c2, (float)(0.0)), (float)(0.0));\n\tcos=VFast_atan2_madd(c1, fixmag1, (float)(0.0));\n\tsin=VFast_atan2_madd(s1, fixmag1, (float)(0.0));\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * Phase Wrapping(radianを-PI～PIにラップする) (1x float, C言語版)\n */\nstatic inline float WrapPi_F1(float v)\n{\n\tint rad_unit = static_cast<int>(v*(1.0/M_PI));\n\tif (rad_unit >= 0) rad_unit += rad_unit&1;\n\telse rad_unit -= rad_unit&1;\n\tv -= M_PI*(double)rad_unit;\n\treturn v;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/utils/MathAlgorithms_Default.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief 数学関数群\n//---------------------------------------------------------------------------\n#include <stdlib.h>\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid DeinterleaveApplyingWindow(float *  dest[], const float *  src,\n\t\t\t\t\tfloat *  win, int numch, size_t destofs, size_t len)\n{\n\tsize_t n;\n\tswitch(numch)\n\t{\n\tcase 1: // mono\n\t\t{\n\t\t\tfloat * dest0 = dest[0] + destofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest0[n] = src[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase 2: // stereo\n\t\t{\n\t\t\tfloat * dest0 = dest[0] + destofs;\n\t\t\tfloat * dest1 = dest[1] + destofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest0[n] = src[n*2 + 0] * win[n];\n\t\t\t\tdest1[n] = src[n*2 + 1] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tdefault: // generic\n\t\tfor(n = 0; n < len; n++)\n\t\t{\n\t\t\tfor(int ch = 0; ch < numch; ch++)\n\t\t\t{\n\t\t\t\tdest[ch][n + destofs] = *src * win[n];\n\t\t\t\tsrc ++;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nvoid  InterleaveOverlappingWindow(float *  dest,\n\tconst float *  const *  src,\n\tfloat *  win, int numch, size_t srcofs, size_t len)\n{\n\tsize_t n;\n\tswitch(numch)\n\t{\n\tcase 1: // mono\n\t\t{\n\t\t\tconst float * src0 = src[0] + srcofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest[n] += src0[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase 2: // stereo\n\t\t{\n\t\t\tconst float * src0 = src[0] + srcofs;\n\t\t\tconst float * src1 = src[1] + srcofs;\n\t\t\tfor(n = 0; n < len; n++)\n\t\t\t{\n\t\t\t\tdest[n*2 + 0] += src0[n] * win[n];\n\t\t\t\tdest[n*2 + 1] += src1[n] * win[n];\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tdefault: // generic\n\t\tfor(n = 0; n < len; n++)\n\t\t{\n\t\t\tfor(int ch = 0; ch < numch; ch++)\n\t\t\t{\n\t\t\t\t*dest += src[ch][n + srcofs] * win[n];\n\t\t\t\tdest ++;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/utils/MathAlgorithms_Default.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]      alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief 数学関数群\n//---------------------------------------------------------------------------\n#ifndef MATHALGORITHMSH\n#define MATHALGORITHMSH\n\n#include <stdlib.h>\n\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * 窓関数を適用しながらのインターリーブ解除\n * @param dest\t\t格納先(複数)\n * @param src\t\tソース\n * @param win\t\t窓関数\n * @param numch\t\tチャンネル数\n * @param destofs\tdestの処理開始位置\n * @param len\t\t処理するサンプル数\n *\t\t\t\t\t(各チャンネルごとの数; 実際に処理されるサンプル\n *\t\t\t\t\t数の総計はlen*numchになる)\n */\nvoid DeinterleaveApplyingWindow(float *  dest[], const float *  src,\n\t\t\t\t\tfloat *  win, int numch, size_t destofs, size_t len);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * 窓関数を適用しながらのインターリーブ+オーバーラッピング\n * @param dest\t\t格納先\n * @param src\t\tソース(複数)\n * @param win\t\t窓関数\n * @param numch\t\tチャンネル数\n * @param srcofs\tsrcの処理開始位置\n * @param len\t\t処理するサンプル数\n *\t\t\t\t\t(各チャンネルごとの数; 実際に処理されるサンプル\n *\t\t\t\t\t数の総計はlen*numchになる)\n */\nvoid  InterleaveOverlappingWindow(float *  dest,\n\tconst float *  const *  src,\n\tfloat *  win, int numch, size_t srcofs, size_t len);\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/utils/MiscUtility.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"CharacterSet.h\"\n#if 0\n#ifdef _WIN32\n#include <mmsystem.h>\n#endif\n\n//---------------------------------------------------------------------------\n// TVPGetRoughTickCount\n// 32bitltickJEg𓾂\n//---------------------------------------------------------------------------\ntjs_uint32 TVPGetRoughTickCount32()\n{\n#ifdef _WIN32\n\treturn timeGetTime();\n#else\n\t#error Not implemented yet.\n#endif\n}\n#endif\n//---------------------------------------------------------------------------\nbool TVPEncodeUTF8ToUTF16(ttstr &output, const std::string &source)\n{\n\ttjs_int len = TVPUtf8ToWideCharString( source.c_str(), NULL );\n\tif(len == -1) return false;\n\tstd::vector<tjs_char> outbuf( len+1, 0 );\n\ttjs_int ret = TVPUtf8ToWideCharString( source.c_str(), &(outbuf[0]));\n\tif( ret ) {\n\t\toutbuf[ret] = L'\\0';\n\t\toutput = &(outbuf[0]);\n\t\treturn true;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "src/core/utils/ObjectList.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Safe Object List\n//---------------------------------------------------------------------------\n#ifndef ObjectListH\n#define ObjectListH\n\n#include \"tjs.h\"\nusing namespace TJS;\n\n//---------------------------------------------------------------------------\n/*\n\tSimple implementation of auto array for objects.\n\tThis manages neither object's construction nor destruction.\n*/\n//---------------------------------------------------------------------------\n#define TOBJECTLIST_INC_COUNT 64\ntemplate <typename ObjT>\nclass tVoidObjectList\n{\nprivate:\n\tObjT** Objects;\n\tObjT** BackupedObjects;\n\t//void * * Objects; // array of the object\n\t//void * * BackupedObjects; // backuped objects\n\ttjs_int BackupedCount; // item count in BackupedObjects\n\ttjs_int Capacity; // capacity of the array\n\ttjs_int Count; // actual count\n\ttjs_int SafeLockCount; // safe lock reference count\n\tbool Backuped; // whether \"Object\" is backuped to \"BackupedObject\"\n\n\tvoid InternalAssign(const tVoidObjectList & ref)\n\t{\n\t\t// this internal function does not free the array previously allocated.\n\t\t// only \"Objects\" ( not \"BackupedObjects\" ) is copied.\n\t\tif(ref.Count)\n\t\t{\n\t\t\t//Objects = (void **)TJS_malloc(ref.Count * sizeof(void *) );\n\t\t\tObjects = new ObjT*[ref.Count];\n\t\t\tmemcpy(Objects, ref.Objects, ref.Count * sizeof(ObjT *) );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tObjects = NULL;\n\t\t}\n\t\tCapacity = Count = ref.Count;\n\t}\n\n\tvoid Backup()\n\t{\n\t\t// backup current \"Objects\" to \"BackupedObjects\"\n\t\tif(Count)\n\t\t{\n\t\t\t//BackupedObjects = (void**)TJS_malloc(Count * sizeof(void *) );\n\t\t\tBackupedObjects = new ObjT*[Count];\n\t\t\tmemcpy(BackupedObjects, Objects, Count * sizeof(ObjT *) );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tBackupedObjects = NULL;\n\t\t}\n\t\tBackupedCount = Count;\n\t\tBackuped = true;\n\t}\n\n\tvoid Commit()\n\t{\n\t\t// commit the current array\n\t\t// this simply free BackupedObjects ( and its related things )\n\t\tif(BackupedObjects) delete [](BackupedObjects);\n\t\tBackupedObjects = NULL;\n\t\tBackupedCount = 0;\n\t\tBackuped = false;\n\t}\n\npublic:\n\ttVoidObjectList()\n\t{\n\t\tObjects = NULL;\n\t\tBackupedObjects = NULL;\n\t\tCapacity = 0;\n\t\tCount = 0;\n\t\tBackuped = false;\n\t\tSafeLockCount = 0;\n\t}\n\n\ttVoidObjectList(const tVoidObjectList & ref)\n\t{\n\t\tSafeLockCount = 0;\n\t\tBackupedObjects = NULL;\n\t\tBackuped = false;\n\t\tInternalAssign(ref);\n\t}\n\n\t~tVoidObjectList()\n\t{\n\t\tif(Objects) delete[] Objects;\n\t\tif(BackupedObjects) delete[] BackupedObjects;\n\t}\n\n\tvoid operator =(const tVoidObjectList & ref)\n\t{\n\t\tAssign(ref);\n\t}\n\n\tvoid Assign(const tVoidObjectList & ref)\n\t{\n\t\t// note that this function does not change any safe locking\n\t\t// effects ( locking count is not changed )\n\t\tif(Objects) delete[] Objects;\n\t\tInternalAssign(ref);\n\t}\n\n\tvoid SafeLock()\n\t{\n\t\t// lock array safely\n\t\t// safe locking is managed by reference counter;\n\t\tif(SafeLockCount == 0)\n\t\t\tCompact(); // this is needed\n\t\tSafeLockCount ++;\n\t}\n\n\tvoid SafeUnlock()\n\t{\n\t\tSafeLockCount --;\n\t\tif(SafeLockCount == 0)\n\t\t\tCommit();\n\t}\n\n\ttjs_int GetSafeLockedObjectCount() const\n\t{\n\t\t// this function only valid in safe locking\n\t\tif(Backuped) return BackupedCount;\n\t\treturn Count;\n\t}\n\n\tObjT * GetSafeLockedObjectAt(tjs_int index) const\n\t{\n\t\t// this migight contain null pointer\n\t\tif(Backuped)\n\t\t{\n\t\t\treturn BackupedObjects[index];\n\t\t}\n\t\treturn Objects[index];\n\t}\n\n\ttjs_int GetCount() const\n\t{\n\t\t// note that if you want to ensure the result is\n\t\t// actual object count in the array,\n\t\t// call Compact() before GetCount().\n\t\treturn Count;\n\t}\n\n\ttjs_int GetActualCount()\n\t{\n\t\t// this does Compact() before returning current Count,\n\t\t// ensuring returned count is actual object count in the array.\n\t\tCompact();\n\t\treturn Count;\n\t}\n\n\tvoid SetCount(tjs_int count)\n\t{\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\tReserve(count);\n\t\tCount = count;\n\t}\n\n\tvoid Reserve(tjs_int count)\n\t{\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\tif(Capacity < count)\n\t\t{\n\t\t\tCapacity = count + TOBJECTLIST_INC_COUNT;\n\t\t\tif(Capacity) {\n\t\t\t\tObjT** tmp = new ObjT*[Capacity];\n\t\t\t\tif( Count > 0 ) {\n \t\t\t\t\tmemcpy( tmp, Objects, Count * sizeof(ObjT *) );\n\t\t\t\t}\n\t\t\t\tdelete[] Objects;\n\t\t\t\tObjects = tmp;\n\t\t\t\t//Objects = (void**)TJS_realloc(Objects, Capacity * sizeof(void *));\n\t\t\t}else\n\t\t\t\tif(Objects) delete[] Objects, Objects = NULL;\n\t\t}\n\t}\n\n\tvoid Compact()\n\t{\n\t\t// this eliminates NULL pointer from the array\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\tObjT **s, **d, **slim;\n\t\tslim = Objects + Count;\n\t\ts = d = Objects;\n\t\twhile(s < slim)\n\t\t{\n\t\t\tif(*s == NULL)\n\t\t\t{\n\t\t\t\ts++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(s != d) *d = *s;\n\t\t\ts++, d++;\n\t\t}\n\t\tCount = (tjs_int)(d - Objects);\n\t\tCapacity = Count;\n\t\tif(Count) {\n\t\t\t//Objects = (void**)TJS_realloc(Objects, Count * sizeof(void *));\n\t\t\tObjT** tmp = new ObjT*[Count];\n\t\t\tmemcpy( tmp, Objects, Count * sizeof(ObjT *) );\n\t\t\tdelete[] Objects;\n\t\t\tObjects = tmp;\n\t\t}else\n\t\t\tif(Objects) delete[] Objects, Objects = NULL;\n\t}\n\n\tObjT * &operator [] (tjs_int index)\n\t{\n\t\t// this might return a null pointer\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\treturn Objects[index];\n\t}\n\n\tObjT * const &operator [] (tjs_int index) const\n\t{\n\t\t// this might return a null pointer\n\t\treturn Objects[index];\n\t}\n\n\ttjs_int Find(ObjT * object) const\n\t{\n\t\t// find \"object\" from array\n\t\t// return -1 if \"object\" does not exist\n\t\tif(!object) return -1; // null cannot be finded\n\t\tObjT * const *  s = Objects;\n\t\tObjT * const *  slim = Objects + Count;\n\t\twhile(s < slim)\n\t\t{\n\t\t\tif(*s == object) return (tjs_int)(s - Objects);\n\t\t\ts++;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tbool Add(ObjT * object)\n\t{\n\t\t// add \"object\" to array\n\t\t// this does not allow duplicates\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\tif(!object) return false; // null cannot be added\n\t\tif(Find(object) == -1)\n\t\t{\n\t\t\ttjs_int orgcount = Count;\n\t\t\tSetCount(Count+1);\n\t\t\tObjects[orgcount] = object;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tbool Remove(ObjT * object)\n\t{\n\t\t// remove object from array\n\t\t// (this only set the pointer to null)\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\ttjs_int index = Find(object);\n\t\tbool ret;\n\t\tif(index != -1)\n\t\t{\n\t\t\tObjects[index] = NULL;\n\t\t\tret = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tret = false;\n\t\t}\n\t\tif(Backuped && object)\n\t\t{\n\t\t\t// remove also from BackupedObjects\n\t\t\tObjT * * s = BackupedObjects,\n\t\t\t\t* * slim = BackupedObjects + BackupedCount;\n\t\t\twhile(s < slim)\n\t\t\t{\n\t\t\t\tif(*s == object)\n\t\t\t\t{\n\t\t\t\t\t*s = NULL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ts++;\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t}\n\n\tvoid Remove(tjs_int index)\n\t{\n\t\tif(SafeLockCount && !Backuped) Backup();\n\t\tObjT * object = Objects[index];\n\t\tObjects[index] = NULL;\n\t\tif(Backuped && object)\n\t\t{\n\t\t\t// remove also from BackupedObjects\n\t\t\tObjT ** s = BackupedObjects,\n\t\t\t\t** slim = BackupedObjects + BackupedCount;\n\t\t\twhile(s < slim)\n\t\t\t{\n\t\t\t\tif(*s == object)\n\t\t\t\t{\n\t\t\t\t\t*s = NULL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ts++;\n\t\t\t}\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\n// template wrappter class for tVoidObjectList\ntemplate <typename ObjT>\nclass tObjectList\n{\nprivate:\n\ttVoidObjectList<ObjT> List;\n\npublic:\n\ttObjectList() : List()\n\t{\n\t}\n\n\ttObjectList(const tObjectList<ObjT> & ref) : List(ref.List)\n\t{\n\t}\n\n\t~tObjectList()\n\t{\n\t}\n\n\tvoid operator =(const tObjectList<ObjT> & ref)\n\t{\n\t\tList.operator =(ref.List);\n\t}\n\n\tvoid Assign(const tObjectList<ObjT> & ref)\n\t{\n\t\tList.Assign(ref.List);\n\t}\n\n\tvoid SafeLock()\n\t{\n\t\tList.SafeLock();\n\t}\n\n\tvoid SafeUnlock()\n\t{\n\t\tList.SafeUnlock();\n\t}\n\n\ttjs_int GetSafeLockedObjectCount() const\n\t{\n\t\treturn List.GetSafeLockedObjectCount();\n\t}\n\n\tObjT * GetSafeLockedObjectAt(tjs_int index) const\n\t{\n\t\treturn List.GetSafeLockedObjectAt(index);\n\t}\n\n\ttjs_int GetCount() const\n\t{\n\t\treturn List.GetCount();\n\t}\n\n\ttjs_int GetActualCount()\n\t{\n\t\treturn List.GetActualCount();\n\t}\n\n\tvoid SetCount(tjs_int count)\n\t{\n\t\tList.SetCount(count);\n\t}\n\n\tvoid Reserve(tjs_int count)\n\t{\n\t\tList.Reserve(count);\n\t}\n\n\tvoid Compact()\n\t{\n\t\tList.Compact();\n\t}\n\t\n\tObjT * & operator [] (tjs_int index)\n\t{\n\t\treturn List[index];\n\t}\n\n\tObjT * const & operator [] (tjs_int index) const\n\t{\n\t\treturn List[index];\n\t}\n\n\ttjs_int Find(ObjT * object) const\n\t{\n\t\treturn List.Find( object );\n\t}\n\n\tbool Add(ObjT * object)\n\t{\n\t\treturn List.Add( object );\n\t}\n\n\tbool Remove(ObjT * object)\n\t{\n\t\treturn List.Remove( object );\n\t}\n\n\tvoid Remove(tjs_int index)\n\t{\n\t\tList.Remove(index);\n\t}\n};\n//---------------------------------------------------------------------------\ntemplate <typename ObjT>\nclass tVoidObjectListSafeLockHolder\n{\nprivate:\n\ttVoidObjectList<ObjT> & List;\npublic:\n\ttVoidObjectListSafeLockHolder(tVoidObjectList<ObjT> &list) : List(list)\n\t{\n\t\tList.SafeLock();\n\t}\n\t~tVoidObjectListSafeLockHolder()\n\t{\n\t\tList.SafeUnlock();\n\t}\n};\n//---------------------------------------------------------------------------\ntemplate <typename ObjT>\nclass tObjectListSafeLockHolder\n{\nprivate:\n\ttObjectList<ObjT> & List;\npublic:\n\ttObjectListSafeLockHolder(tObjectList<ObjT> &list) : List(list)\n\t{\n\t\tList.SafeLock();\n\t}\n\t~tObjectListSafeLockHolder()\n\t{\n\t\tList.SafeUnlock();\n\t}\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/utils/PadIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text Editor\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"PadIntf.h\"\n//#include \"PadImpl.h\"\n\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_BasePad::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *dsp)\n{\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_BasePad::Invalidate()\n{\n}\n//---------------------------------------------------------------------------\n\ntTJSNativeInstance *tTJSNC_Pad::CreateNativeInstance()\n{\n\treturn new tTJSNativeInstance();\n}\n\n\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Pad::ClassID = -1;\n//---------------------------------------------------------------------------\ntTJSNC_Pad::tTJSNC_Pad(): inherited(TJS_W(\"Pad\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Pad) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Pad,\n\t/*TJS class name*/Pad)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Pad)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(text)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TJS_W(\"\");\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(text)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fileName)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TJS_W(\"\");\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fileName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(color)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(color)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(visible)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(title)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TJS_W(\"\");\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(title)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontColor)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontColor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)10;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontSize)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)10;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontBold)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontBold)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontItalic)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontItalic)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontUnderline)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontUnderline)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontStrikeOut)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontStrikeOut)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fontFace)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TJS_W(\"\");\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fontFace)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(readOnly)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = (tjs_int)1;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(readOnly)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(wordWrap)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = false;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(wordWrap)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(opacity)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 255;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(opacity)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(showStatusBar)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = false;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(showStatusBar)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(showScrollBars)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = false;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(showScrollBars)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(statusText)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TJS_W(\"\");\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(statusText)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(borderStyle)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(borderStyle)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 100;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 100;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(top)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(top)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(left)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(left)\n//----------------------------------------------------------------------\n\n\n\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\n\n\n\ntTJSNativeClass * TVPCreateNativeClass_Pad()\n{\n\treturn new tTJSNC_Pad();\n}\n"
  },
  {
    "path": "src/core/utils/PadIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text Editor\n//---------------------------------------------------------------------------\n#ifndef PadIntfH\n#define PadIntfH\n#include \"tjsNative.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BasePad\n//---------------------------------------------------------------------------\nclass tTJSNI_BasePad : public tTJSNativeInstance\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *dsp);\n\tvirtual void TJS_INTF_METHOD\n\t\tInvalidate();\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// font ralated constants\n// core/visual/tvpfontstruc.h Ɠ̂łB\n//---------------------------------------------------------------------------\n// #define TVP_TF_ITALIC    0x01\n// #define TVP_TF_BOLD      0x02\n// #define TVP_TF_UNDERLINE 0x04\n// #define TVP_TF_STRIKEOUT 0x08\n//---------------------------------------------------------------------------\n\n\n#include \"PadImpl.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Pad : TJS Pad Class\n//---------------------------------------------------------------------------\nclass tTJSNC_Pad : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\npublic:\n\ttTJSNC_Pad();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Pad();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/Random.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Simple Pseudo Random Generator\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"Random.h\"\n#include \"md5.h\"\n#include \"tjsUtils.h\"\n\n// this implements simple environment-noise based pseudo random generator using MD5.\n// may not be suitable for high security usage.\n\n//---------------------------------------------------------------------------\ntjs_uint8 TVPRandomSeedPool[0x1000 + 512];\n\t// 512 is to avoid buffer over-run posibility in multi-threaded access \ntjs_int TVPRandomSeedPoolPos = 0;\ntjs_uint8 TVPRandomSeedAtom; // need not to initialize\n//---------------------------------------------------------------------------\nvoid TVPPushEnvironNoise(const void *buf, tjs_int bufsize)\n{\n\tconst tjs_uint8 *p = (const tjs_uint8 *)buf;\n\tfor(int i = 0; i < bufsize; i++)\n\t{\n\t\tTVPRandomSeedPool[TVPRandomSeedPoolPos ++] ^=\n\t\t\t(TVPRandomSeedAtom ^= p[i]);\n\t\tTVPRandomSeedPoolPos &= 0xfff;\n\t}\n\tTVPRandomSeedPoolPos += (p[0]&1);\n\tTVPRandomSeedPoolPos &= 0xfff;\n}\n//---------------------------------------------------------------------------\nvoid TVPGetRandomBits128(void *dest)\n{\n\t// retrieve random bits\n\n\t// add some noise\n\ttjs_uint8 buf[16];\n\tTVPPushEnvironNoise(buf, 16); // dare to use uninitialized buffer\n\tTVPPushEnvironNoise(&TVPRandomSeedPoolPos, sizeof(TVPRandomSeedPoolPos));\n\n\t// make 128bit hash of TVPRandomSeedPool, using MD5 message digest\n\tmd5_state_t state;\n\tmd5_init(&state);\n\tmd5_append(&state, TVPRandomSeedPool, 0x1000);\n\tmd5_finish(&state, buf);\n\n\tmemcpy(dest, buf, 16);\n\n\t// push hash itself\n\tTVPPushEnvironNoise(buf, 16);\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/utils/Random.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Simple Pseudo Random Generator\n//---------------------------------------------------------------------------\n#ifndef RandomH\n#define RandomH\n//---------------------------------------------------------------------------\n\n\nTJS_EXP_FUNC_DEF(void, TVPPushEnvironNoise, (const void *buf, tjs_int bufsize));\nTJS_EXP_FUNC_DEF(void, TVPGetRandomBits128, (void *dest));\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/RealFFT.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]\t\t alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief 実数離散フーリエ変換\n//---------------------------------------------------------------------------\n#ifndef REALFFT_H\n#define REALFFT_H\n\n/*\n\tBased on\n\t\tReal Discrete FFT package from\n\t\t\thttp://momonga.t.u-tokyo.ac.jp/~ooura/fft-j.html\n\tand\n\t\tOgg Vorbis Optimization Project\n\t\t\thttp://homepage3.nifty.com/blacksword/\n*/\n\n//---------------------------------------------------------------------------\n\n    void rdft(int, int, float * , int * , float * );\n\n\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/utils/RealFFT_Default.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [りさ]\t\t alias 吉里吉里3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief 実数離散フーリエ変換\n//---------------------------------------------------------------------------\n\n/*\n\tReal Discrete FFT package from\n\t\thttp://momonga.t.u-tokyo.ac.jp/~ooura/fft-j.html\n*/\n\n//---------------------------------------------------------------------------\n\nstatic void cft1st(int n, float * a, float * w)\n{\n\tint j, k1, k2;\n\tfloat wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n\tfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\t\n\tx0r = a[0] + a[2];\n\tx0i = a[1] + a[3];\n\tx1r = a[0] - a[2];\n\tx1i = a[1] - a[3];\n\tx2r = a[4] + a[6];\n\tx2i = a[5] + a[7];\n\tx3r = a[4] - a[6];\n\tx3i = a[5] - a[7];\n\ta[0] = x0r + x2r;\n\ta[1] = x0i + x2i;\n\ta[4] = x0r - x2r;\n\ta[5] = x0i - x2i;\n\ta[2] = x1r - x3i;\n\ta[3] = x1i + x3r;\n\ta[6] = x1r + x3i;\n\ta[7] = x1i - x3r;\n\twk1r = w[2];\n\tx0r = a[8] + a[10];\n\tx0i = a[9] + a[11];\n\tx1r = a[8] - a[10];\n\tx1i = a[9] - a[11];\n\tx2r = a[12] + a[14];\n\tx2i = a[13] + a[15];\n\tx3r = a[12] - a[14];\n\tx3i = a[13] - a[15];\n\ta[8] = x0r + x2r;\n\ta[9] = x0i + x2i;\n\ta[12] = x2i - x0i;\n\ta[13] = x0r - x2r;\n\tx0r = x1r - x3i;\n\tx0i = x1i + x3r;\n\ta[10] = wk1r * (x0r - x0i);\n\ta[11] = wk1r * (x0r + x0i);\n\tx0r = x3i + x1r;\n\tx0i = x3r - x1i;\n\ta[14] = wk1r * (x0i - x0r);\n\ta[15] = wk1r * (x0i + x0r);\n\tk1 = 0;\n\tfor (j = 16; j < n; j += 16) {\n\t\tk1 += 2;\n\t\tk2 = 2 * k1;\n\t\twk2r = w[k1];\n\t\twk2i = w[k1 + 1];\n\t\twk1r = w[k2];\n\t\twk1i = w[k2 + 1];\n\t\twk3r = wk1r - 2 * wk2i * wk1i;\n\t\twk3i = 2 * wk2i * wk1r - wk1i;\n\t\tx0r = a[j] + a[j + 2];\n\t\tx0i = a[j + 1] + a[j + 3];\n\t\tx1r = a[j] - a[j + 2];\n\t\tx1i = a[j + 1] - a[j + 3];\n\t\tx2r = a[j + 4] + a[j + 6];\n\t\tx2i = a[j + 5] + a[j + 7];\n\t\tx3r = a[j + 4] - a[j + 6];\n\t\tx3i = a[j + 5] - a[j + 7];\n\t\ta[j] = x0r + x2r;\n\t\ta[j + 1] = x0i + x2i;\n\t\tx0r -= x2r;\n\t\tx0i -= x2i;\n\t\ta[j + 4] = wk2r * x0r - wk2i * x0i;\n\t\ta[j + 5] = wk2r * x0i + wk2i * x0r;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j + 2] = wk1r * x0r - wk1i * x0i;\n\t\ta[j + 3] = wk1r * x0i + wk1i * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j + 6] = wk3r * x0r - wk3i * x0i;\n\t\ta[j + 7] = wk3r * x0i + wk3i * x0r;\n\t\twk1r = w[k2 + 2];\n\t\twk1i = w[k2 + 3];\n\t\twk3r = wk1r - 2 * wk2r * wk1i;\n\t\twk3i = 2 * wk2r * wk1r - wk1i;\n\t\tx0r = a[j + 8] + a[j + 10];\n\t\tx0i = a[j + 9] + a[j + 11];\n\t\tx1r = a[j + 8] - a[j + 10];\n\t\tx1i = a[j + 9] - a[j + 11];\n\t\tx2r = a[j + 12] + a[j + 14];\n\t\tx2i = a[j + 13] + a[j + 15];\n\t\tx3r = a[j + 12] - a[j + 14];\n\t\tx3i = a[j + 13] - a[j + 15];\n\t\ta[j + 8] = x0r + x2r;\n\t\ta[j + 9] = x0i + x2i;\n\t\tx0r -= x2r;\n\t\tx0i -= x2i;\n\t\ta[j + 12] = -wk2i * x0r - wk2r * x0i;\n\t\ta[j + 13] = -wk2i * x0i + wk2r * x0r;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j + 10] = wk1r * x0r - wk1i * x0i;\n\t\ta[j + 11] = wk1r * x0i + wk1i * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j + 14] = wk3r * x0r - wk3i * x0i;\n\t\ta[j + 15] = wk3r * x0i + wk3i * x0r;\n\t}\n}\n\n\n\nstatic void cftmdl(int n, int l, float *  a, float *  w)\n{\n\tint j, j1, j2, j3, k, k1, k2, m, m2;\n\tfloat wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;\n\tfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\t\n\tm = l << 2;\n\tfor (j = 0; j < l; j += 2) {\n\t\tj1 = j + l;\n\t\tj2 = j1 + l;\n\t\tj3 = j2 + l;\n\t\tx0r = a[j] + a[j1];\n\t\tx0i = a[j + 1] + a[j1 + 1];\n\t\tx1r = a[j] - a[j1];\n\t\tx1i = a[j + 1] - a[j1 + 1];\n\t\tx2r = a[j2] + a[j3];\n\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\tx3r = a[j2] - a[j3];\n\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\ta[j] = x0r + x2r;\n\t\ta[j + 1] = x0i + x2i;\n\t\ta[j2] = x0r - x2r;\n\t\ta[j2 + 1] = x0i - x2i;\n\t\ta[j1] = x1r - x3i;\n\t\ta[j1 + 1] = x1i + x3r;\n\t\ta[j3] = x1r + x3i;\n\t\ta[j3 + 1] = x1i - x3r;\n\t}\n\twk1r = w[2];\n\tfor (j = m; j < l + m; j += 2) {\n\t\tj1 = j + l;\n\t\tj2 = j1 + l;\n\t\tj3 = j2 + l;\n\t\tx0r = a[j] + a[j1];\n\t\tx0i = a[j + 1] + a[j1 + 1];\n\t\tx1r = a[j] - a[j1];\n\t\tx1i = a[j + 1] - a[j1 + 1];\n\t\tx2r = a[j2] + a[j3];\n\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\tx3r = a[j2] - a[j3];\n\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\ta[j] = x0r + x2r;\n\t\ta[j + 1] = x0i + x2i;\n\t\ta[j2] = x2i - x0i;\n\t\ta[j2 + 1] = x0r - x2r;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j1] = wk1r * (x0r - x0i);\n\t\ta[j1 + 1] = wk1r * (x0r + x0i);\n\t\tx0r = x3i + x1r;\n\t\tx0i = x3r - x1i;\n\t\ta[j3] = wk1r * (x0i - x0r);\n\t\ta[j3 + 1] = wk1r * (x0i + x0r);\n\t}\n\tk1 = 0;\n\tm2 = 2 * m;\n\tfor (k = m2; k < n; k += m2) {\n\t\tk1 += 2;\n\t\tk2 = 2 * k1;\n\t\twk2r = w[k1];\n\t\twk2i = w[k1 + 1];\n\t\twk1r = w[k2];\n\t\twk1i = w[k2 + 1];\n\t\twk3r = wk1r - 2 * wk2i * wk1i;\n\t\twk3i = 2 * wk2i * wk1r - wk1i;\n\t\tfor (j = k; j < l + k; j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tj2 = j1 + l;\n\t\t\tj3 = j2 + l;\n\t\t\tx0r = a[j] + a[j1];\n\t\t\tx0i = a[j + 1] + a[j1 + 1];\n\t\t\tx1r = a[j] - a[j1];\n\t\t\tx1i = a[j + 1] - a[j1 + 1];\n\t\t\tx2r = a[j2] + a[j3];\n\t\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j2] - a[j3];\n\t\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i + x2i;\n\t\t\tx0r -= x2r;\n\t\t\tx0i -= x2i;\n\t\t\ta[j2] = wk2r * x0r - wk2i * x0i;\n\t\t\ta[j2 + 1] = wk2r * x0i + wk2i * x0r;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j1] = wk1r * x0r - wk1i * x0i;\n\t\t\ta[j1 + 1] = wk1r * x0i + wk1i * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3r * x0r - wk3i * x0i;\n\t\t\ta[j3 + 1] = wk3r * x0i + wk3i * x0r;\n\t\t}\n\t\twk1r = w[k2 + 2];\n\t\twk1i = w[k2 + 3];\n\t\twk3r = wk1r - 2 * wk2r * wk1i;\n\t\twk3i = 2 * wk2r * wk1r - wk1i;\n\t\tfor (j = k + m; j < l + (k + m); j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tj2 = j1 + l;\n\t\t\tj3 = j2 + l;\n\t\t\tx0r = a[j] + a[j1];\n\t\t\tx0i = a[j + 1] + a[j1 + 1];\n\t\t\tx1r = a[j] - a[j1];\n\t\t\tx1i = a[j + 1] - a[j1 + 1];\n\t\t\tx2r = a[j2] + a[j3];\n\t\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j2] - a[j3];\n\t\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i + x2i;\n\t\t\tx0r -= x2r;\n\t\t\tx0i -= x2i;\n\t\t\ta[j2] = -wk2i * x0r - wk2r * x0i;\n\t\t\ta[j2 + 1] = -wk2i * x0i + wk2r * x0r;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j1] = wk1r * x0r - wk1i * x0i;\n\t\t\ta[j1 + 1] = wk1r * x0i + wk1i * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3r * x0r - wk3i * x0i;\n\t\t\ta[j3 + 1] = wk3r * x0i + wk3i * x0r;\n\t\t}\n\t}\n}\n\nstatic void bitrv2(int n, int *  ip, float *  a)\n{\n\tint j, j1, k, k1, l, m, m2;\n\tfloat xr, xi, yr, yi;\n\t\n\tip[0] = 0;\n\tl = n;\n\tm = 1;\n\twhile ((m << 3) < l) {\n\t\tl >>= 1;\n\t\tfor (j = 0; j < m; j++) {\n\t\t\tip[m + j] = ip[j] + l;\n\t\t}\n\t\tm <<= 1;\n\t}\n\tm2 = 2 * m;\n\tif ((m << 3) == l) {\n\t\tfor (k = 0; k < m; k++) {\n\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\tj1 += m2;\n\t\t\t\tk1 += 2 * m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\tj1 += m2;\n\t\t\t\tk1 -= m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\tj1 += m2;\n\t\t\t\tk1 += 2 * m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t}\n\t\t\tj1 = 2 * k + m2 + ip[k];\n\t\t\tk1 = j1 + m2;\n\t\t\txr = a[j1];\n\t\t\txi = a[j1 + 1];\n\t\t\tyr = a[k1];\n\t\t\tyi = a[k1 + 1];\n\t\t\ta[j1] = yr;\n\t\t\ta[j1 + 1] = yi;\n\t\t\ta[k1] = xr;\n\t\t\ta[k1 + 1] = xi;\n\t\t}\n\t} else {\n\t\tfor (k = 1; k < m; k++) {\n\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\tj1 += m2;\n\t\t\t\tk1 += m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void rftfsub(int n, float *  a, int nc, float *  c)\n{\n\tint j, k, kk, ks, m;\n\tfloat wkr, wki, xr, xi, yr, yi;\n\t\n\tm = n >> 1;\n\tks = 2 * nc / m;\n\tkk = 0;\n\tfor (j = 2; j < m; j += 2) {\n\t\tk = n - j;\n\t\tkk += ks;\n\t\twkr = 0.5 - c[nc - kk];\n\t\twki = c[kk];\n\t\txr = a[j] - a[k];\n\t\txi = a[j + 1] + a[k + 1];\n\t\tyr = wkr * xr - wki * xi;\n\t\tyi = wkr * xi + wki * xr;\n\t\ta[j] -= yr;\n\t\ta[j + 1] -= yi;\n\t\ta[k] += yr;\n\t\ta[k + 1] -= yi;\n\t}\n}\n\nstatic void cftfsub(int n, float *  a, float *  w)\n{\n\tint j, j1, j2, j3, l;\n\tfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\t\n\tl = 2;\n\tif (n > 8) {\n\t\tcft1st(n, a, w);\n\t\tl = 8;\n\t\twhile ((l << 2) < n) {\n\t\t\tcftmdl(n, l, a, w);\n\t\t\tl <<= 2;\n\t\t}\n\t}\n\tif ((l << 2) == n) {\n\t\tfor (j = 0; j < l; j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tj2 = j1 + l;\n\t\t\tj3 = j2 + l;\n\t\t\tx0r = a[j] + a[j1];\n\t\t\tx0i = a[j + 1] + a[j1 + 1];\n\t\t\tx1r = a[j] - a[j1];\n\t\t\tx1i = a[j + 1] - a[j1 + 1];\n\t\t\tx2r = a[j2] + a[j3];\n\t\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j2] - a[j3];\n\t\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i + x2i;\n\t\t\ta[j2] = x0r - x2r;\n\t\t\ta[j2 + 1] = x0i - x2i;\n\t\t\ta[j1] = x1r - x3i;\n\t\t\ta[j1 + 1] = x1i + x3r;\n\t\t\ta[j3] = x1r + x3i;\n\t\t\ta[j3 + 1] = x1i - x3r;\n\t\t}\n\t} else {\n\t\tfor (j = 0; j < l; j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tx0r = a[j] - a[j1];\n\t\t\tx0i = a[j + 1] - a[j1 + 1];\n\t\t\ta[j] += a[j1];\n\t\t\ta[j + 1] += a[j1 + 1];\n\t\t\ta[j1] = x0r;\n\t\t\ta[j1 + 1] = x0i;\n\t\t}\n\t}\n}\n\n\nstatic void cftbsub(int n, float *  a, float *  w)\n{\n\tint j, j1, j2, j3, l;\n\tfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\t\n\tl = 2;\n\tif (n > 8) {\n\t\tcft1st(n, a, w);\n\t\tl = 8;\n\t\twhile ((l << 2) < n) {\n\t\t\tcftmdl(n, l, a, w);\n\t\t\tl <<= 2;\n\t\t}\n\t}\n\tif ((l << 2) == n) {\n\t\tfor (j = 0; j < l; j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tj2 = j1 + l;\n\t\t\tj3 = j2 + l;\n\t\t\tx0r = a[j] + a[j1];\n\t\t\tx0i = -a[j + 1] - a[j1 + 1];\n\t\t\tx1r = a[j] - a[j1];\n\t\t\tx1i = -a[j + 1] + a[j1 + 1];\n\t\t\tx2r = a[j2] + a[j3];\n\t\t\tx2i = a[j2 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j2] - a[j3];\n\t\t\tx3i = a[j2 + 1] - a[j3 + 1];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i - x2i;\n\t\t\ta[j2] = x0r - x2r;\n\t\t\ta[j2 + 1] = x0i + x2i;\n\t\t\ta[j1] = x1r - x3i;\n\t\t\ta[j1 + 1] = x1i - x3r;\n\t\t\ta[j3] = x1r + x3i;\n\t\t\ta[j3 + 1] = x1i + x3r;\n\t\t}\n\t} else {\n\t\tfor (j = 0; j < l; j += 2) {\n\t\t\tj1 = j + l;\n\t\t\tx0r = a[j] - a[j1];\n\t\t\tx0i = -a[j + 1] + a[j1 + 1];\n\t\t\ta[j] += a[j1];\n\t\t\ta[j + 1] = -a[j + 1] - a[j1 + 1];\n\t\t\ta[j1] = x0r;\n\t\t\ta[j1 + 1] = x0i;\n\t\t}\n\t}\n}\n\n\nstatic void rftbsub(int n, float *  a, int nc, float *  c)\n{\n\tint j, k, kk, ks, m;\n\tfloat wkr, wki, xr, xi, yr, yi;\n\t\n\ta[1] = -a[1];\n\tm = n >> 1;\n\tks = 2 * nc / m;\n\tkk = 0;\n\tfor (j = 2; j < m; j += 2) {\n\t\tk = n - j;\n\t\tkk += ks;\n\t\twkr = 0.5 - c[nc - kk];\n\t\twki = c[kk];\n\t\txr = a[j] - a[k];\n\t\txi = a[j + 1] + a[k + 1];\n\t\tyr = wkr * xr + wki * xi;\n\t\tyi = wkr * xi - wki * xr;\n\t\ta[j] -= yr;\n\t\ta[j + 1] = yi - a[j + 1];\n\t\ta[k] += yr;\n\t\ta[k + 1] = yi - a[k + 1];\n\t}\n\ta[m + 1] = -a[m + 1];\n}\n\n\n\n\n#include <math.h>\n\nvoid makewt(int nw, int *  ip, float *  w)\n{\n\tint j, nwh;\n\tfloat delta, x, y;\n\t\n\tip[0] = nw;\n\tip[1] = 1;\n\tif (nw > 2) {\n\t\tnwh = nw >> 1;\n\t\tdelta = atan(1.0) / nwh;\n\t\tw[0] = 1;\n\t\tw[1] = 0;\n\t\tw[nwh] = cos(delta * nwh);\n\t\tw[nwh + 1] = w[nwh];\n\t\tif (nwh > 2) {\n\t\t\tfor (j = 2; j < nwh; j += 2) {\n\t\t\t\tx = cos(delta * j);\n\t\t\t\ty = sin(delta * j);\n\t\t\t\tw[j] = x;\n\t\t\t\tw[j + 1] = y;\n\t\t\t\tw[nw - j] = y;\n\t\t\t\tw[nw - j + 1] = x;\n\t\t\t}\n\t\t\tbitrv2(nw, ip + 2, w);\n\t\t}\n\t}\n}\n\n\nvoid makect(int nc, int *  ip, float *  c)\n{\n\tint j, nch;\n\tfloat delta;\n\t\n\tip[1] = nc;\n\tif (nc > 1) {\n\t\tnch = nc >> 1;\n\t\tdelta = atan(1.0) / nch;\n\t\tc[0] = cos(delta * nch);\n\t\tc[nch] = 0.5 * c[0];\n\t\tfor (j = 1; j < nch; j++) {\n\t\t\tc[j] = 0.5 * cos(delta * j);\n\t\t\tc[nc - j] = 0.5 * sin(delta * j);\n\t\t}\n\t}\n}\n\n\n\n\n\nvoid rdft(int n, int isgn, float *  a, int *  ip, float *  w)\n{\n\tint nw, nc;\n\tfloat xi;\n\t\n\tnw = ip[0];\n\tif (n > (nw << 2)) {\n\t\tnw = n >> 2;\n\t\tmakewt(nw, ip, w);\n\t}\n\tnc = ip[1];\n\tif (n > (nc << 2)) {\n\t\tnc = n >> 2;\n\t\tmakect(nc, ip, w + nw);\n\t}\n\tif (isgn >= 0) {\n\t\tif (n > 4) {\n\t\t\tbitrv2(n, ip + 2, a);\n\t\t\tcftfsub(n, a, w);\n\t\t\trftfsub(n, a, nc, w + nw);\n\t\t} else if (n == 4) {\n\t\t\tcftfsub(n, a, w);\n\t\t}\n\t\txi = a[0] - a[1];\n\t\ta[0] += a[1];\n\t\ta[1] = xi;\n\t} else {\n\t\ta[1] = 0.5 * (a[0] - a[1]);\n\t\ta[0] -= a[1];\n\t\tif (n > 4) {\n\t\t\trftbsub(n, a, nc, w + nw);\n\t\t\tbitrv2(n, ip + 2, a);\n\t\t\tcftbsub(n, a, w);\n\t\t} else if (n == 4) {\n\t\t\tcftfsub(n, a, w);\n\t\t}\n\t}\n}\n\n\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/utils/StringUtil.h",
    "content": "\n#ifndef __STRING_UTILITY_H__\n#define __STRING_UTILITY_H__\n\n#include <string>\n#include <iostream>\n#include <algorithm>\n#include <locale>\n\nstruct equal_char_ignorecase {\n\tinline bool operator()(char x, char y) const {\n\t\tstd::locale loc;\n\t\treturn std::tolower(x,loc) == std::tolower(y,loc);\n\t}\n};\n\ninline bool icomp( const std::string& x, const std::string& y ) {\n\treturn x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin(), equal_char_ignorecase());\n}\n\nstruct equal_wchar_ignorecase {\n\tinline bool operator()(wchar_t x, wchar_t y) const {\n\t\tstd::locale loc;\n\t\treturn std::tolower(x,loc) == std::tolower(y,loc);\n\t}\n};\ninline bool icomp( const std::wstring& x, const std::wstring& y ) {\n\treturn x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin(), equal_wchar_ignorecase());\n}\n\nstatic int ttstr_find_first_not_of(const ttstr &str, const ttstr& r) {\n\tconst tjs_char *const pend = str.c_str() + str.length();\n\tfor (const tjs_char *p = str.c_str(); p < pend; ++p) {\n\t\tif (r.IndexOf(*p) != -1) {\n\t\t\treturn p - str.c_str();\n\t\t}\n\t}\n\treturn -1;\n}\n\nstatic int ttstr_find_last_not_of(const ttstr &str, const ttstr& r) {\n\tconst tjs_char *pbegin = str.c_str();\n\tfor (const tjs_char *p = str.c_str() + str.length();; --p) {\n\t\tif (r.IndexOf(*p) != -1)\n\t\t\treturn (p - str.c_str());\t// found a match\n\t\telse if (p == pbegin)\n\t\t\tbreak;\t// at beginning, no more chance for match\n\t}\n\treturn -1;\n}\n\ninline std::string Trim( const std::string& val ) {\n\tstatic const char* TRIM_STR=\" \\01\\02\\03\\04\\05\\06\\a\\b\\t\\n\\v\\f\\r\\x0E\\x0F\\x7F\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1A\\x1B\\x1C\\x1D\\x1E\\x1F\";\n\tstd::string::size_type pos = val.find_first_not_of( TRIM_STR );\n\tstd::string::size_type lastpos = val.find_last_not_of( TRIM_STR );\n\tif( pos == lastpos ) {\n\t\tif( pos == std::string::npos ) {\n\t\t\treturn val;\n\t\t} else {\n\t\t\treturn val.substr(pos,1);\n\t\t}\n\t} else {\n\t\tstd::string::size_type len = lastpos - pos + 1;\n\t\treturn val.substr(pos,len);\n\t}\n}\ninline ttstr Trim(const ttstr& val) {\n\tstatic const tjs_char* TRIM_STR=TJS_W(\" \\01\\02\\03\\04\\05\\06\\a\\b\\t\\n\\v\\f\\r\\x0E\\x0F\\x7F\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1A\\x1B\\x1C\\x1D\\x1E\\x1F\");\n\tint pos = ttstr_find_first_not_of(val, TRIM_STR);\n\tint lastpos = ttstr_find_last_not_of(val, TRIM_STR);\n\tif( pos == lastpos ) {\n\t\tif( pos == std::wstring::npos ) {\n\t\t\treturn val;\n\t\t} else {\n\t\t\treturn val.SubString(pos,1);\n\t\t}\n\t} else {\n\t\tstd::wstring::size_type len = lastpos - pos + 1;\n\t\treturn val.SubString(pos, len);\n\t}\n}\n\n#endif // __STRING_UTILITY_H__\n"
  },
  {
    "path": "src/core/utils/ThreadIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Thread base class\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"ThreadIntf.h\"\n#include \"ThreadImpl.h\"\n\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/utils/ThreadIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Thread base class\n//---------------------------------------------------------------------------\n#ifndef ThreadIntfH\n#define ThreadIntfH\n#include \"tjsNative.h\"\n#include <functional>\n\n\n//---------------------------------------------------------------------------\n// tTVPThreadPriority\n//---------------------------------------------------------------------------\nenum tTVPThreadPriority\n{\n\tttpIdle, ttpLowest, ttpLower, ttpNormal, ttpHigher, ttpHighest, ttpTimeCritical\n};\n//---------------------------------------------------------------------------\n\n#include \"ThreadImpl.h\"\n\n/*[*/\nconst tjs_int TVPMaxThreadNum = 8;\ntypedef const std::function<void(int)> &TVP_THREAD_TASK_FUNC;\n/*]*/\n\nTJS_EXP_FUNC_DEF(tjs_int, TVPGetProcessorNum, ());\nTJS_EXP_FUNC_DEF(tjs_int, TVPGetThreadNum, ());\nTJS_EXP_FUNC_DEF(void, TVPExecThreadTask, (int numThreads, TVP_THREAD_TASK_FUNC func));\n\n#endif\n"
  },
  {
    "path": "src/core/utils/TickCount.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// safe 64bit System Tick Count\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"tjsUtils.h\"\n#include \"TickCount.h\"\n#include \"SysInitIntf.h\"\n#include \"ThreadIntf.h\"\n\n#define DWORD uint32_t\n//---------------------------------------------------------------------------\n// 64bit may enough to hold usual time count.\n// ( 32bit is clearly insufficient )\n//---------------------------------------------------------------------------\nstatic tjs_uint64 TVPTickCountBias = 0;\nstatic DWORD TVPWatchLastTick;\nstatic tTJSCriticalSection TVPTickWatchCS;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic DWORD TVPCheckTickOverflow()\n{\n\tDWORD curtick;\n\t{\t// thread-protected\n\t\ttTJSCriticalSectionHolder holder(TVPTickWatchCS);\n\n\t\tcurtick = TVPGetRoughTickCount32();\n\t\tif(curtick < TVPWatchLastTick)\n\t\t{\n\t\t\t// timeGetTime() was overflowed\n\t\t\tTVPTickCountBias += 0x100000000L; // add 1<<32\n\t\t}\n\t\tTVPWatchLastTick = curtick;\n\t}\t// end-of-thread-protected\n\treturn curtick;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nclass tTVPWatchThread : public tTVPThread\n{\n\t// thread which watches overflow of 32bit counter of TVPGetRoughTickCount32\n\n\ttTVPThreadEvent Event;\n\npublic:\n\n\ttTVPWatchThread();\n\t~tTVPWatchThread();\n\nprotected:\n\tvoid Execute();\n\n} static * TVPWatchThread = NULL;\n//---------------------------------------------------------------------------\ntTVPWatchThread::tTVPWatchThread() : tTVPThread(true)\n{\n\tTVPWatchLastTick = TVPGetRoughTickCount32();\n\tSetPriority(ttpNormal);\n\tResume();\n}\n//---------------------------------------------------------------------------\ntTVPWatchThread::~tTVPWatchThread()\n{\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n}\n//---------------------------------------------------------------------------\nvoid tTVPWatchThread::Execute()\n{\n\twhile(!GetTerminated())\n\t{\n\t\tTVPCheckTickOverflow();\n\n\t\tEvent.WaitFor(0x10000000);\n\t\t\t// 0x10000000 will be enough to watch timeGetTime()'s counter overflow.\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic void TVPWatchThreadInit()\n{\n\tif(!TVPWatchThread)\n\t{\n\t\tTVPWatchThread = new tTVPWatchThread();\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPWatchThreadUninit()\n{\n\tif(TVPWatchThread)\n\t{\n\t\tdelete TVPWatchThread;\n\t\tTVPWatchThread = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPWatchThreadUninitAtExit(TVP_ATEXIT_PRI_SHUTDOWN,\n\tTVPWatchThreadUninit);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetTickCount\n//---------------------------------------------------------------------------\ntjs_uint64 TVPGetTickCount()\n{\n\tTVPWatchThreadInit();\n\n\tDWORD curtick = TVPCheckTickOverflow();\n\n\treturn curtick + TVPTickCountBias;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPStartTickCount\n//---------------------------------------------------------------------------\nvoid TVPStartTickCount()\n{\n\tTVPWatchThreadInit();\n}\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/utils/TickCount.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// safe 64bit System Tick Count\n//---------------------------------------------------------------------------\n#ifndef TickCountH\n#define TickCountH\n#include \"tjsTypes.h\"\n\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_uint64, TVPGetTickCount, ());\nextern tjs_uint32 TVPGetRoughTickCount32();\nextern void TVPStartTickCount();\n\t// this must be called before TVPGetTickCount(), in main thread.\n\t// this function can be called more than one time.\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/utils/TimerIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Timer Object Interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"TimerIntf.h\"\n#include \"EventIntf.h\"\n#include \"SysInitIntf.h\"\n\n\n#define TVP_DEFAULT_TIMER_CAPACITY 6\n\n//---------------------------------------------------------------------------\n// global variables\n//---------------------------------------------------------------------------\nbool TVPLimitTimerCapacity = false;\n\t// limit timer capacity to one\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseTimer\n//---------------------------------------------------------------------------\ntTJSNI_BaseTimer::tTJSNI_BaseTimer()\n{\n\tOwner = NULL;\n\tCounter = 0;\n\tCapacity = TVP_DEFAULT_TIMER_CAPACITY;\n\tActionOwner.Object = ActionOwner.ObjThis = NULL;\n\tActionName = TVPActionName;\n\tMode = atmNormal;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\t\ttTJSNI_BaseTimer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tActionName = *param[1]; // action function to be called\n\n\tActionOwner = param[0]->AsObjectClosure();\n\tOwner = tjs_obj;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseTimer::Invalidate()\n{\n\tTVPCancelSourceEvents(Owner);\n\tOwner = NULL;\n\n\tActionOwner.Release();\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseTimer::Fire(tjs_uint n)\n{\n\tif(!Owner) return;\n\tstatic ttstr eventname(TJS_W(\"onTimer\"));\n\n\ttjs_int count = TVPCountEventsInQueue(Owner, Owner, eventname, 0);\n\n\ttjs_int cap = TVPLimitTimerCapacity ? 1 : (Capacity == 0 ? 65535 : Capacity);\n\t\t// 65536 should be considered as to be no-limit.\n\n\ttjs_int more = cap - count;\n\n\tif(more > 0)\n\t{\n\t\tif(n > (tjs_uint)more) n = more;\n\t\tif(Owner)\n\t\t{\n\t\t\ttjs_uint32 tag = 1 + ((tjs_uint32)Counter << 1);\n\t\t\ttjs_uint32 flags = TVP_EPT_POST|TVP_EPT_DISCARDABLE;\n\t\t\tswitch(Mode)\n\t\t\t{\n\t\t\tcase atmNormal:\t\t\tflags |= TVP_EPT_NORMAL; break;\n\t\t\tcase atmExclusive:\t\tflags |= TVP_EPT_EXCLUSIVE; break;\n\t\t\tcase atmAtIdle:\t\t\tflags |= TVP_EPT_IDLE; break;\n\t\t\t}\n\t\t\twhile(n--)\n\t\t\t{\n\t\t\t\tTVPPostEvent(Owner, Owner, eventname, tag,\n\t\t\t\t\tflags, 0, NULL);\n\t\t\t}\n\t\t}\n\n\t\tCounter++;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseTimer::CancelEvents()\n{\n\t// cancel all events\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onTimer\"));\n\t\tTVPCancelEvents(Owner, Owner, eventname, 0);\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseTimer::AreEventsInQueue()\n{\n\t// are events in event queue ?\n\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onTimer\"));\n\t\treturn TVPAreEventsInQueue(Owner, Owner, eventname, 0);\n\t}\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Timer\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Timer::ClassID = -1;\ntTJSNC_Timer::tTJSNC_Timer() : inherited(TJS_W(\"Timer\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Timer) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Timer,\n\t/*TJS class name*/Timer)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Timer)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTimer)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_Timer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tttstr & actionname = _this->GetActionName();\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onTimer\", objthis);\n\t\tTVP_ACTION_INVOKE_END_NAME(obj,\n\t\t\tactionname.IsEmpty() ? NULL :actionname.c_str(),\n\t\t\tactionname.IsEmpty() ? NULL :actionname.GetHint());\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTimer)\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(interval)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t/*\n\t\t\tbcc 5.5.1 has an inliner bug which cannot treat 64bit integer return\n\t\t\tvalue properly in some occasions.\n\t\t\tOK : tjs_uint64 interval = _this->GetInterval(); *result = (tjs_int64)interval;\n\t\t\tNG : *result = (tjs_int64)interval;\n\t\t*/\n\t\tdouble interval = _this->GetInterval() * (1.0 / (1<<TVP_SUBMILLI_FRAC_BITS));\n\t\t*result = interval;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\tdouble interval = (double)*param * (1<<TVP_SUBMILLI_FRAC_BITS);\n\t\t_this->SetInterval((tjs_int64)(interval + 0.5));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(interval)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enabled)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t*result = _this->GetEnabled();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t_this->SetEnabled(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(enabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(capacity)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t*result = _this->GetCapacity();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t_this->SetCapacity(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(capacity)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t*result = (tjs_int)_this->GetMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Timer);\n\t\t_this->SetMode((tTVPAsyncTriggerMode)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mode)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n\n\ttTJSVariant val;\n\tif(TVPGetCommandLine(TJS_W(\"-laxtimer\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\"))\n\t\t\tTVPLimitTimerCapacity = true;\n\t}\n\n}\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/utils/TimerIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Timer Object Interface\n//---------------------------------------------------------------------------\n#ifndef TimerIntfH\n#define TimerIntfH\n\n#include \"tjsNative.h\"\n#include \"EventIntf.h\"\n\n\n// the timer has sub-milliseconds precision by fixed-point real.\n#define TVP_SUBMILLI_FRAC_BITS 16\n\n\n//---------------------------------------------------------------------------\n// global variables\n//---------------------------------------------------------------------------\nextern bool TVPLimitTimerCapacity;\n\t// limit timer capacity to one\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseTimer\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseTimer : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\nprotected:\n\tiTJSDispatch2 *Owner;\n\ttTJSVariantClosure ActionOwner; // object to send action\n\ttjs_uint16 Counter; // serial number for event tag\n\ttjs_int Capacity; // max queue size for this timer object\n\tttstr ActionName;\n\ttTVPAsyncTriggerMode Mode; // trigger mode\n\npublic:\n\ttTJSNI_BaseTimer();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\n\tvoid Fire(tjs_uint n);\n\tvoid CancelEvents();\n\tbool AreEventsInQueue();\n\npublic:\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n\tttstr & GetActionName() { return ActionName; }\n\n\ttjs_int GetCapacity() const { return Capacity; }\n\tvoid SetCapacity(tjs_int c) { Capacity = c; }\n\n\ttTVPAsyncTriggerMode GetMode() const { return Mode; }\n\tvoid SetMode(tTVPAsyncTriggerMode mode) { Mode = mode; }\n};\n//---------------------------------------------------------------------------\n\n#include \"TimerImpl.h\" // must define tTJSNI_Timer class\n\n//---------------------------------------------------------------------------\n// tTJSNC_Timer : TJS Timer class\n//---------------------------------------------------------------------------\nclass tTJSNC_Timer : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Timer();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNI_Timer.\n\t*/\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Timer();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNI_Timer.\n\t\tusually simple returns: new tTJSNC_Timer();\n\t*/\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/VelocityTracker.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"tjsCommHead.h\"\n\n#include <math.h>\n#include <limits.h>\n#include \"VelocityTracker.h\"\n\n\n// Nanoseconds per milliseconds.\n//static const nsecs_t NANOS_PER_MS = 1000000;\n// tick lŌvẐŁA̕\\̓~b\nstatic const tjs_uint64 NANOS_PER_MS = 1;\n\n// Threshold for determining that a pointer has stopped moving.\n// Some input devices do not send ACTION_MOVE events in the case where a pointer has\n// stopped.  We need to detect this case so that we can accurately predict the\n// velocity after the pointer starts moving again.\nstatic const tjs_uint64 ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;\n\n\nstatic float vectorDot(const float* a, const float* b, tjs_uint32 m) {\n    float r = 0;\n    while (m--) {\n        r += *(a++) * *(b++);\n    }\n    return r;\n}\n\nstatic float vectorNorm(const float* a, tjs_uint32 m) {\n    float r = 0;\n    while (m--) {\n        float t = *(a++);\n        r += t * t;\n    }\n    return sqrtf(r);\n}\n\n\n// --- VelocityTracker ---\nVelocityTracker::VelocityTracker() : mStrategy(2), mID(-1) { }\nVelocityTracker::~VelocityTracker() {}\nbool VelocityTracker::getVelocity( float& outVx, float& outVy ) const {\n    VelocityTrackerStrategy::Estimator estimator;\n    if (getEstimator(&estimator) && estimator.degree >= 1) {\n        outVx = estimator.xCoeff[1];\n        outVy = estimator.yCoeff[1];\n        return true;\n    }\n    outVx = 0;\n    outVy = 0;\n    return false;\n}\n\n// --- LeastSquaresVelocityTrackerStrategy ---\n\n//const tjs_uint64 LeastSquaresVelocityTrackerStrategy::HORIZON;\n//const tjs_uint32 LeastSquaresVelocityTrackerStrategy::HISTORY_SIZE;\n\nLeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(tjs_uint32 degree, Weighting weighting)\n : mDegree(degree), mWeighting(weighting) {\n    clear();\n}\n\nLeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {\n}\n\nvoid LeastSquaresVelocityTrackerStrategy::clear() {\n    mIndex = 0;\n\tmMovements[0].usingThis = false;\n}\n\nvoid LeastSquaresVelocityTrackerStrategy::addMovement( tjs_uint64 eventTime, float x, float y ) {\n    if (++mIndex == HISTORY_SIZE) {\n        mIndex = 0;\n    }\n\n    Movement& movement = mMovements[mIndex];\n    movement.eventTime = eventTime;\n    movement.positions.x = x;\n\tmovement.positions.y = y;\n\tmovement.usingThis = true;\n}\n\n/**\n * Solves a linear least squares problem to obtain a N degree polynomial that fits\n * the specified input data as nearly as possible.\n *\n * Returns true if a solution is found, false otherwise.\n *\n * The input consists of two vectors of data points X and Y with indices 0..m-1\n * along with a weight vector W of the same size.\n *\n * The output is a vector B with indices 0..n that describes a polynomial\n * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1] X[i]\n * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is minimized.\n *\n * Accordingly, the weight vector W should be initialized by the caller with the\n * reciprocal square root of the variance of the error in each input data point.\n * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 / stddev(Y[i]).\n * The weights express the relative importance of each data point.  If the weights are\n * all 1, then the data points are considered to be of equal importance when fitting\n * the polynomial.  It is a good idea to choose weights that diminish the importance\n * of data points that may have higher than usual error margins.\n *\n * Errors among data points are assumed to be independent.  W is represented here\n * as a vector although in the literature it is typically taken to be a diagonal matrix.\n *\n * That is to say, the function that generated the input data can be approximated\n * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.\n *\n * The coefficient of determination (R^2) is also returned to describe the goodness\n * of fit of the model for the given data.  It is a value between 0 and 1, where 1\n * indicates perfect correspondence.\n *\n * This function first expands the X vector to a m by n matrix A such that\n * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then\n * multiplies it by w[i]./\n *\n * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q\n * and an m by n upper triangular matrix R.  Because R is upper triangular (lower\n * part is all zeroes), we can simplify the decomposition into an m by n matrix\n * Q1 and a n by n matrix R1 such that A = Q1 R1.\n *\n * Finally we solve the system of linear equations given by R1 B = (Qtranspose W Y)\n * to find B.\n *\n * For efficiency, we lay out A and Q column-wise in memory because we frequently\n * operate on the column vectors.  Conversely, we lay out R row-wise.\n *\n * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares\n * http://en.wikipedia.org/wiki/Gram-Schmidt\n */\nstatic bool solveLeastSquares(const float* x, const float* y,\n        const float* w, tjs_uint32 m, tjs_uint32 n, float* outB, float* outDet) {\n\n    // Expand the X vector to a matrix A, pre-multiplied by the weights.\n    //float a[n][m]; // column-major order\n\tstd::vector<std::vector<float> >\ta(n);\n\tfor( tjs_uint32 i = 0; i < n; i++ ) a[i].resize(m);\n    for (tjs_uint32 h = 0; h < m; h++) {\n        a[0][h] = w[h];\n        for (tjs_uint32 i = 1; i < n; i++) {\n            a[i][h] = a[i - 1][h] * x[h];\n        }\n    }\n\n    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.\n    //float q[n][m]; // orthonormal basis, column-major order\n\tstd::vector<std::vector<float> >\tq(n);\n\tfor( tjs_uint32 i = 0; i < n; i++ ) q[i].resize(m);\n    //float r[n][n]; // upper triangular matrix, row-major order\n\tstd::vector<std::vector<float> >\tr(n);\n\tfor( tjs_uint32 i = 0; i < n; i++ ) r[i].resize(n);\n    for (tjs_uint32 j = 0; j < n; j++) {\n        for (tjs_uint32 h = 0; h < m; h++) {\n            q[j][h] = a[j][h];\n        }\n        for (tjs_uint32 i = 0; i < j; i++) {\n            float dot = vectorDot(&q[j][0], &q[i][0], m);\n            for (tjs_uint32 h = 0; h < m; h++) {\n                q[j][h] -= dot * q[i][h];\n            }\n        }\n\n        float norm = vectorNorm(&q[j][0], m);\n        if (norm < 0.000001f) {\n            // vectors are linearly dependent or zero so no solution\n            return false;\n        }\n\n        float invNorm = 1.0f / norm;\n        for (tjs_uint32 h = 0; h < m; h++) {\n            q[j][h] *= invNorm;\n        }\n        for (tjs_uint32 i = 0; i < n; i++) {\n            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);\n        }\n    }\n    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.\n    // We just work from bottom-right to top-left calculating B's coefficients.\n    //float wy[m];\n\tstd::vector<float> wy(m);\n    for (tjs_uint32 h = 0; h < m; h++) {\n        wy[h] = y[h] * w[h];\n    }\n    for (tjs_uint32 i = n; i-- != 0; ) {\n        outB[i] = vectorDot(&q[i][0], &(wy[0]), m);\n        for (tjs_uint32 j = n - 1; j > i; j--) {\n            outB[i] -= r[i][j] * outB[j];\n        }\n        outB[i] /= r[i][i];\n    }\n\n    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where\n    // SSerr is the residual sum of squares (variance of the error),\n    // and SStot is the total sum of squares (variance of the data) where each\n    // has been weighted.\n    float ymean = 0;\n    for (tjs_uint32 h = 0; h < m; h++) {\n        ymean += y[h];\n    }\n    ymean /= m;\n\n    float sserr = 0;\n    float sstot = 0;\n    for (tjs_uint32 h = 0; h < m; h++) {\n        float err = y[h] - outB[0];\n        float term = 1;\n        for (tjs_uint32 i = 1; i < n; i++) {\n            term *= x[h];\n            err -= term * outB[i];\n        }\n        sserr += w[h] * w[h] * err * err;\n        float var = y[h] - ymean;\n        sstot += w[h] * w[h] * var * var;\n    }\n    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;\n    return true;\n}\n\nbool LeastSquaresVelocityTrackerStrategy::getEstimator(VelocityTrackerStrategy::Estimator* outEstimator) const {\n    outEstimator->clear();\n\n    // Iterate over movement samples in reverse time order and collect samples.\n    float x[HISTORY_SIZE];\n    float y[HISTORY_SIZE];\n    float w[HISTORY_SIZE];\n    float time[HISTORY_SIZE];\n    tjs_uint32 m = 0;\n    tjs_uint32 index = mIndex;\n    const Movement& newestMovement = mMovements[mIndex];\n    do {\n        const Movement& movement = mMovements[index];\n        if( !movement.usingThis ) {\n            break;\n        }\n        tjs_uint64 age = newestMovement.eventTime - movement.eventTime;\n        if (age > HORIZON) {\n            break;\n        }\n\n        const Position& position = movement.getPosition();\n        x[m] = position.x;\n        y[m] = position.y;\n        w[m] = chooseWeight(index);\n        //time[m] = -age * 0.000000001f;\n    \ttime[m] = -(tjs_int64)age * 0.001f;\n        index = (index == 0 ? HISTORY_SIZE : index) - 1;\n    } while (++m < HISTORY_SIZE);\n\n    if (m == 0) {\n        return false; // no data\n    }\n\n    // Calculate a least squares polynomial fit.\n    tjs_uint32 degree = mDegree;\n    if (degree > m - 1) {\n        degree = m - 1;\n    }\n    if (degree >= 1) {\n        float xdet, ydet;\n        tjs_uint32 n = degree + 1;\n        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)\n                && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {\n            outEstimator->time = newestMovement.eventTime;\n            outEstimator->degree = degree;\n            outEstimator->confidence = xdet * ydet;\n            return true;\n        }\n    }\n\n    // No velocity data available for this pointer, but we do have its current position.\n    outEstimator->xCoeff[0] = x[0];\n    outEstimator->yCoeff[0] = y[0];\n    outEstimator->time = newestMovement.eventTime;\n    outEstimator->degree = 0;\n    outEstimator->confidence = 1;\n    return true;\n}\n\nfloat LeastSquaresVelocityTrackerStrategy::chooseWeight(tjs_uint32 index) const {\n    switch (mWeighting) {\n    case WEIGHTING_DELTA: {\n        // Weight points based on how much time elapsed between them and the next\n        // point so that points that \"cover\" a shorter time span are weighed less.\n        //   delta  0ms: 0.5\n        //   delta 10ms: 1.0\n        if (index == mIndex) {\n            return 1.0f;\n        }\n        tjs_uint32 nextIndex = (index + 1) % HISTORY_SIZE;\n        //float deltaMillis = (mMovements[nextIndex].eventTime- mMovements[index].eventTime) * 0.000001f;\n    \tfloat deltaMillis = (float)(mMovements[nextIndex].eventTime- mMovements[index].eventTime);\n        if (deltaMillis < 0) {\n            return 0.5f;\n        }\n        if (deltaMillis < 10) {\n            return 0.5f + deltaMillis * 0.05f;\n        }\n        return 1.0f;\n    }\n\n    case WEIGHTING_CENTRAL: {\n        // Weight points based on their age, weighing very recent and very old points less.\n        //   age  0ms: 0.5\n        //   age 10ms: 1.0\n        //   age 50ms: 1.0\n        //   age 60ms: 0.5\n        //float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime) * 0.000001f;\n    \tfloat ageMillis = (float)(mMovements[mIndex].eventTime - mMovements[index].eventTime);\n        if (ageMillis < 0) {\n            return 0.5f;\n        }\n        if (ageMillis < 10) {\n            return 0.5f + ageMillis * 0.05f;\n        }\n        if (ageMillis < 50) {\n            return 1.0f;\n        }\n        if (ageMillis < 60) {\n            return 0.5f + (60 - ageMillis) * 0.05f;\n        }\n        return 0.5f;\n    }\n\n    case WEIGHTING_RECENT: {\n        // Weight points based on their age, weighing older points less.\n        //   age   0ms: 1.0\n        //   age  50ms: 1.0\n        //   age 100ms: 0.5\n        //float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime) * 0.000001f;\n    \tfloat ageMillis = (float)(mMovements[mIndex].eventTime - mMovements[index].eventTime);\n        if (ageMillis < 50) {\n            return 1.0f;\n        }\n        if (ageMillis < 100) {\n            return 0.5f + (100 - ageMillis) * 0.01f;\n        }\n        return 0.5f;\n    }\n\n    case WEIGHTING_NONE:\n    default:\n        return 1.0f;\n    }\n}\n\n"
  },
  {
    "path": "src/core/utils/VelocityTracker.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * -------------------------------------------------------------------\n * ̃\\[XR[h Android ̃\\[XR[hggZɍ悤\n * ĈłB\n * |CgǗĂ̂́AID̊蓖ĕWindowsł͈ق\n * (͈̔͂Ɏ܂Ȃ)߁AooŊǗ`ɕύXB\n * ԂmsPʂɕύXB\n */\n\n#ifndef _LIBINPUT_VELOCITY_TRACKER_H\n#define _LIBINPUT_VELOCITY_TRACKER_H\n\n/*\n * Implements a particular velocity tracker algorithm.\n */\nclass VelocityTrackerStrategy {\npublic:\n    struct Position {\n        float x, y;\n    };\n\n    struct Estimator {\n        static const size_t MAX_DEGREE = 4;\n\n        // Estimator time base.\n    \ttjs_uint64 time;\n\n        // Polynomial coefficients describing motion in X and Y.\n        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];\n\n        // Polynomial degree (number of coefficients), or zero if no information is\n        // available.\n        tjs_uint32 degree;\n\n        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).\n        float confidence;\n\n        inline void clear() {\n            time = 0;\n            degree = 0;\n            confidence = 0;\n            for (size_t i = 0; i <= MAX_DEGREE; i++) {\n                xCoeff[i] = 0;\n                yCoeff[i] = 0;\n            }\n        }\n    };\nprotected:\n    VelocityTrackerStrategy() { }\n\npublic:\n    virtual ~VelocityTrackerStrategy() { }\n\n    virtual void clear() = 0;\n    virtual void addMovement( tjs_uint64 eventTime, float x, float y ) = 0;\n    virtual bool getEstimator( Estimator* outEstimator) const = 0;\n};\n\n\n/*\n * Velocity tracker algorithm based on least-squares linear regression.\n */\nclass LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {\npublic:\n    enum Weighting {\n        WEIGHTING_NONE,\t\t// No weights applied.  All data points are equally reliable.\n        WEIGHTING_DELTA,\t// Weight by time delta.  Data points clustered together are weighted less.\n        WEIGHTING_CENTRAL,\t// Weight such that points within a certain horizon are weighed more than those outside of that horizon.\n        WEIGHTING_RECENT,\t// Weight such that points older than a certain amount are weighed less.\n    };\n\n    // Degree must be no greater than Estimator::MAX_DEGREE.\n    LeastSquaresVelocityTrackerStrategy(tjs_uint32 degree, Weighting weighting = WEIGHTING_NONE);\n    virtual ~LeastSquaresVelocityTrackerStrategy();\n\n    virtual void clear();\n    virtual void addMovement( tjs_uint64 eventTime, float x, float y );\n    virtual bool getEstimator( Estimator* outEstimator ) const;\n\nprivate:\n    // Sample horizon.\n    // We don't use too much history by default since we want to react to quick\n    // changes in direction.\n    //static const tjs_uint64 HORIZON = 100 * 1000000; // 100 ms\n\tstatic const tjs_uint64 HORIZON = 100; // 100 ms\n\n    // Number of samples to keep.\n    static const tjs_uint32 HISTORY_SIZE = 20;\n\n    struct Movement {\n        tjs_uint64 eventTime;\n        Position positions;\n    \tbool usingThis;\n\n        inline const Position& getPosition() const {\n            return positions;\n        }\n    };\n\n    float chooseWeight(tjs_uint32 index) const;\n\n    const tjs_uint32 mDegree;\n    const Weighting mWeighting;\n    tjs_uint32 mIndex;\n    Movement mMovements[HISTORY_SIZE];\n};\n\n\n/*\n * Calculates the velocity of pointer movements over time.\n * |C^̓̑xvZ\n */\nclass VelocityTracker {\npublic:\n\n    // Creates a velocity tracker using the specified strategy.\n    // If strategy is NULL, uses the default strategy for the platform.\n    VelocityTracker();\n    ~VelocityTracker();\n\n    // Resets the velocity tracker state.\n\tvoid clear() {\n\t\tmID = -1;\n\t\tmStrategy.clear();\n\t}\n\n    // Adds movement information for a set of pointers.\n    // The idBits bitfield specifies the pointer ids of the pointers whose positions\n    // are included in the movement.\n    // The positions array contains position information for each pointer in order by\n    // increasing id.  Its size should be equal to the number of one bits in idBits.\n\tvoid addMovement( tjs_uint64 eventTime, float x, float y ) {\n\t\tmStrategy.addMovement( eventTime, x, y );\n\t}\n\n    // Gets the velocity of the specified pointer id in position units per second.\n    // Returns false and sets the velocity components to zero if there is\n    // insufficient movement information for the pointer.\n    bool getVelocity( float& outVx, float& outVy ) const;\n\n\tbool getVelocity( float& speed ) const {\n\t\tfloat x, y;\n\t\tif( getVelocity( x, y ) ) {\n\t\t\tspeed = hypotf(x, y);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n    // Gets an estimator for the recent movements of the specified pointer id.\n    // Returns false and clears the estimator if there is no information available\n    // about the pointer.\n\tbool getEstimator( VelocityTrackerStrategy::Estimator* outEstimator ) const {\n\t\treturn mStrategy.getEstimator(outEstimator);\n\t}\n\n\tinline void setID( tjs_int id ) { mID = id; }\n\tinline tjs_int getID() const { return mID; }\n\tinline void clearID() { mID = -1; }\n\nprivate:\n    class LeastSquaresVelocityTrackerStrategy mStrategy;\n\ttjs_int mID;\n};\n\n\n// ]̂ł͂ȂAȂ̂ŖȂx̂͂\nclass VelocityTrackers {\npublic:\n\tstatic const tjs_int MAX_TRACKING = 10;\n\nprivate:\n\tVelocityTracker\ttracker_[MAX_TRACKING];\n\nprivate:\n\tint findEmptyEntry() const {\n\t\tfor( int i = 0; i < MAX_TRACKING; i++ ) {\n\t\t\tif( tracker_[i].getID() < 0 ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\tint findEntry( tjs_int32 id ) const {\n\t\tfor( int i = 0; i < MAX_TRACKING; i++ ) {\n\t\t\tif( tracker_[i].getID() == id ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\npublic:\n\tvoid start( tjs_int id ) {\n\t\tint index = findEmptyEntry();\n\t\tif( index >= 0 ) {\n\t\t\ttracker_[index].clear();\n\t\t\ttracker_[index].setID( id );\n\t\t}\n\t}\n\tvoid update( tjs_int id, tjs_uint32 tick, float x, float y ) {\n\t\tint index = findEntry( id );\n\t\tif( index >= 0 ) {\n\t\t\ttracker_[index].addMovement( tick, x, y );\n\t\t}\n\t}\n\tvoid end( tjs_int id ) {\n\t\tint index = findEntry( id );\n\t\tif( index >= 0 ) {\n\t\t\ttracker_[index].clearID();\n\t\t}\n\t}\n\tbool getVelocity( tjs_int id, float& x, float& y, float& speed ) const {\n\t\tint index = findEntry( id );\n\t\tif( index >= 0 ) {\n\t\t\tif( tracker_[index].getVelocity( x, y ) ) {\n\t\t\t\tspeed = hypotf(x, y);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n};\n\n#endif // _LIBINPUT_VELOCITY_TRACKER_H\n"
  },
  {
    "path": "src/core/utils/encoding/gbk2unicode.c",
    "content": "// indexed from 0x8100\nstatic unsigned short gbk2uni[] = {\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n19970,\n19972,\n19973,\n19974,\n19983,\n19986,\n19991,\n19999,\n20000,\n20001,\n20003,\n20006,\n20009,\n20014,\n20015,\n20017,\n20019,\n20021,\n20023,\n20028,\n20032,\n20033,\n20034,\n20036,\n20038,\n20042,\n20049,\n20053,\n20055,\n20058,\n20059,\n20066,\n20067,\n20068,\n20069,\n20071,\n20072,\n20074,\n20075,\n20076,\n20077,\n20078,\n20079,\n20082,\n20084,\n20085,\n20086,\n20087,\n20088,\n20089,\n20090,\n20091,\n20092,\n20093,\n20095,\n20096,\n20097,\n20098,\n20099,\n20100,\n20101,\n20103,\n20106,\n0,\n20112,\n20118,\n20119,\n20121,\n20124,\n20125,\n20126,\n20131,\n20138,\n20143,\n20144,\n20145,\n20148,\n20150,\n20151,\n20152,\n20153,\n20156,\n20157,\n20158,\n20168,\n20172,\n20175,\n20176,\n20178,\n20186,\n20187,\n20188,\n20192,\n20194,\n20198,\n20199,\n20201,\n20205,\n20206,\n20207,\n20209,\n20212,\n20216,\n20217,\n20218,\n20220,\n20222,\n20224,\n20226,\n20227,\n20228,\n20229,\n20230,\n20231,\n20232,\n20235,\n20236,\n20242,\n20243,\n20244,\n20245,\n20246,\n20252,\n20253,\n20257,\n20259,\n20264,\n20265,\n20268,\n20269,\n20270,\n20273,\n20275,\n20277,\n20279,\n20281,\n20283,\n20286,\n20287,\n20288,\n20289,\n20290,\n20292,\n20293,\n20295,\n20296,\n20297,\n20298,\n20299,\n20300,\n20306,\n20308,\n20310,\n20321,\n20322,\n20326,\n20328,\n20330,\n20331,\n20333,\n20334,\n20337,\n20338,\n20341,\n20343,\n20344,\n20345,\n20346,\n20349,\n20352,\n20353,\n20354,\n20357,\n20358,\n20359,\n20362,\n20364,\n20366,\n20368,\n20370,\n20371,\n20373,\n20374,\n20376,\n20377,\n20378,\n20380,\n20382,\n20383,\n20385,\n20386,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n20388,\n20395,\n20397,\n20400,\n20401,\n20402,\n20403,\n20404,\n20406,\n20407,\n20408,\n20409,\n20410,\n20411,\n20412,\n20413,\n20414,\n20416,\n20417,\n20418,\n20422,\n20423,\n20424,\n20425,\n20427,\n20428,\n20429,\n20434,\n20435,\n20436,\n20437,\n20438,\n20441,\n20443,\n20448,\n20450,\n20452,\n20453,\n20455,\n20459,\n20460,\n20464,\n20466,\n20468,\n20469,\n20470,\n20471,\n20473,\n20475,\n20476,\n20477,\n20479,\n20480,\n20481,\n20482,\n20483,\n20484,\n20485,\n20486,\n20487,\n20488,\n20489,\n20490,\n0,\n20491,\n20494,\n20496,\n20497,\n20499,\n20501,\n20502,\n20503,\n20507,\n20509,\n20510,\n20512,\n20514,\n20515,\n20516,\n20519,\n20523,\n20527,\n20528,\n20529,\n20530,\n20531,\n20532,\n20533,\n20534,\n20535,\n20536,\n20537,\n20539,\n20541,\n20543,\n20544,\n20545,\n20546,\n20548,\n20549,\n20550,\n20553,\n20554,\n20555,\n20557,\n20560,\n20561,\n20562,\n20563,\n20564,\n20566,\n20567,\n20568,\n20569,\n20571,\n20573,\n20574,\n20575,\n20576,\n20577,\n20578,\n20579,\n20580,\n20582,\n20583,\n20584,\n20585,\n20586,\n20587,\n20589,\n20590,\n20591,\n20592,\n20593,\n20594,\n20595,\n20596,\n20597,\n20600,\n20601,\n20602,\n20604,\n20605,\n20609,\n20610,\n20611,\n20612,\n20614,\n20615,\n20617,\n20618,\n20619,\n20620,\n20622,\n20623,\n20624,\n20625,\n20626,\n20627,\n20628,\n20629,\n20630,\n20631,\n20632,\n20633,\n20634,\n20635,\n20636,\n20637,\n20638,\n20639,\n20640,\n20641,\n20642,\n20644,\n20646,\n20650,\n20651,\n20653,\n20654,\n20655,\n20656,\n20657,\n20659,\n20660,\n20661,\n20662,\n20663,\n20664,\n20665,\n20668,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n20669,\n20670,\n20671,\n20672,\n20673,\n20674,\n20675,\n20676,\n20677,\n20678,\n20679,\n20680,\n20681,\n20682,\n20683,\n20684,\n20685,\n20686,\n20688,\n20689,\n20690,\n20691,\n20692,\n20693,\n20695,\n20696,\n20697,\n20699,\n20700,\n20701,\n20702,\n20703,\n20704,\n20705,\n20706,\n20707,\n20708,\n20709,\n20712,\n20713,\n20714,\n20715,\n20719,\n20720,\n20721,\n20722,\n20724,\n20726,\n20727,\n20728,\n20729,\n20730,\n20732,\n20733,\n20734,\n20735,\n20736,\n20737,\n20738,\n20739,\n20740,\n20741,\n20744,\n0,\n20745,\n20746,\n20748,\n20749,\n20750,\n20751,\n20752,\n20753,\n20755,\n20756,\n20757,\n20758,\n20759,\n20760,\n20761,\n20762,\n20763,\n20764,\n20765,\n20766,\n20767,\n20768,\n20770,\n20771,\n20772,\n20773,\n20774,\n20775,\n20776,\n20777,\n20778,\n20779,\n20780,\n20781,\n20782,\n20783,\n20784,\n20785,\n20786,\n20787,\n20788,\n20789,\n20790,\n20791,\n20792,\n20793,\n20794,\n20795,\n20796,\n20797,\n20798,\n20802,\n20807,\n20810,\n20812,\n20814,\n20815,\n20816,\n20818,\n20819,\n20823,\n20824,\n20825,\n20827,\n20829,\n20830,\n20831,\n20832,\n20833,\n20835,\n20836,\n20838,\n20839,\n20841,\n20842,\n20847,\n20850,\n20858,\n20862,\n20863,\n20867,\n20868,\n20870,\n20871,\n20874,\n20875,\n20878,\n20879,\n20880,\n20881,\n20883,\n20884,\n20888,\n20890,\n20893,\n20894,\n20895,\n20897,\n20899,\n20902,\n20903,\n20904,\n20905,\n20906,\n20909,\n20910,\n20916,\n20920,\n20921,\n20922,\n20926,\n20927,\n20929,\n20930,\n20931,\n20933,\n20936,\n20938,\n20941,\n20942,\n20944,\n20946,\n20947,\n20948,\n20949,\n20950,\n20951,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n20952,\n20953,\n20954,\n20956,\n20958,\n20959,\n20962,\n20963,\n20965,\n20966,\n20967,\n20968,\n20969,\n20970,\n20972,\n20974,\n20977,\n20978,\n20980,\n20983,\n20990,\n20996,\n20997,\n21001,\n21003,\n21004,\n21007,\n21008,\n21011,\n21012,\n21013,\n21020,\n21022,\n21023,\n21025,\n21026,\n21027,\n21029,\n21030,\n21031,\n21034,\n21036,\n21039,\n21041,\n21042,\n21044,\n21045,\n21052,\n21054,\n21060,\n21061,\n21062,\n21063,\n21064,\n21065,\n21067,\n21070,\n21071,\n21074,\n21075,\n21077,\n21079,\n21080,\n0,\n21081,\n21082,\n21083,\n21085,\n21087,\n21088,\n21090,\n21091,\n21092,\n21094,\n21096,\n21099,\n21100,\n21101,\n21102,\n21104,\n21105,\n21107,\n21108,\n21109,\n21110,\n21111,\n21112,\n21113,\n21114,\n21115,\n21116,\n21118,\n21120,\n21123,\n21124,\n21125,\n21126,\n21127,\n21129,\n21130,\n21131,\n21132,\n21133,\n21134,\n21135,\n21137,\n21138,\n21140,\n21141,\n21142,\n21143,\n21144,\n21145,\n21146,\n21148,\n21156,\n21157,\n21158,\n21159,\n21166,\n21167,\n21168,\n21172,\n21173,\n21174,\n21175,\n21176,\n21177,\n21178,\n21179,\n21180,\n21181,\n21184,\n21185,\n21186,\n21188,\n21189,\n21190,\n21192,\n21194,\n21196,\n21197,\n21198,\n21199,\n21201,\n21203,\n21204,\n21205,\n21207,\n21209,\n21210,\n21211,\n21212,\n21213,\n21214,\n21216,\n21217,\n21218,\n21219,\n21221,\n21222,\n21223,\n21224,\n21225,\n21226,\n21227,\n21228,\n21229,\n21230,\n21231,\n21233,\n21234,\n21235,\n21236,\n21237,\n21238,\n21239,\n21240,\n21243,\n21244,\n21245,\n21249,\n21250,\n21251,\n21252,\n21255,\n21257,\n21258,\n21259,\n21260,\n21262,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n21265,\n21266,\n21267,\n21268,\n21272,\n21275,\n21276,\n21278,\n21279,\n21282,\n21284,\n21285,\n21287,\n21288,\n21289,\n21291,\n21292,\n21293,\n21295,\n21296,\n21297,\n21298,\n21299,\n21300,\n21301,\n21302,\n21303,\n21304,\n21308,\n21309,\n21312,\n21314,\n21316,\n21318,\n21323,\n21324,\n21325,\n21328,\n21332,\n21336,\n21337,\n21339,\n21341,\n21349,\n21352,\n21354,\n21356,\n21357,\n21362,\n21366,\n21369,\n21371,\n21372,\n21373,\n21374,\n21376,\n21377,\n21379,\n21383,\n21384,\n21386,\n21390,\n21391,\n0,\n21392,\n21393,\n21394,\n21395,\n21396,\n21398,\n21399,\n21401,\n21403,\n21404,\n21406,\n21408,\n21409,\n21412,\n21415,\n21418,\n21419,\n21420,\n21421,\n21423,\n21424,\n21425,\n21426,\n21427,\n21428,\n21429,\n21431,\n21432,\n21433,\n21434,\n21436,\n21437,\n21438,\n21440,\n21443,\n21444,\n21445,\n21446,\n21447,\n21454,\n21455,\n21456,\n21458,\n21459,\n21461,\n21466,\n21468,\n21469,\n21470,\n21473,\n21474,\n21479,\n21492,\n21498,\n21502,\n21503,\n21504,\n21506,\n21509,\n21511,\n21515,\n21524,\n21528,\n21529,\n21530,\n21532,\n21538,\n21540,\n21541,\n21546,\n21552,\n21555,\n21558,\n21559,\n21562,\n21565,\n21567,\n21569,\n21570,\n21572,\n21573,\n21575,\n21577,\n21580,\n21581,\n21582,\n21583,\n21585,\n21594,\n21597,\n21598,\n21599,\n21600,\n21601,\n21603,\n21605,\n21607,\n21609,\n21610,\n21611,\n21612,\n21613,\n21614,\n21615,\n21616,\n21620,\n21625,\n21626,\n21630,\n21631,\n21633,\n21635,\n21637,\n21639,\n21640,\n21641,\n21642,\n21645,\n21649,\n21651,\n21655,\n21656,\n21660,\n21662,\n21663,\n21664,\n21665,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n21666,\n21669,\n21678,\n21680,\n21682,\n21685,\n21686,\n21687,\n21689,\n21690,\n21692,\n21694,\n21699,\n21701,\n21706,\n21707,\n21718,\n21720,\n21723,\n21728,\n21729,\n21730,\n21731,\n21732,\n21739,\n21740,\n21743,\n21744,\n21745,\n21748,\n21749,\n21750,\n21751,\n21752,\n21753,\n21755,\n21758,\n21760,\n21762,\n21763,\n21764,\n21765,\n21768,\n21770,\n21771,\n21772,\n21773,\n21774,\n21778,\n21779,\n21781,\n21782,\n21783,\n21784,\n21785,\n21786,\n21788,\n21789,\n21790,\n21791,\n21793,\n21797,\n21798,\n0,\n21800,\n21801,\n21803,\n21805,\n21810,\n21812,\n21813,\n21814,\n21816,\n21817,\n21818,\n21819,\n21821,\n21824,\n21826,\n21829,\n21831,\n21832,\n21835,\n21836,\n21837,\n21838,\n21839,\n21841,\n21842,\n21843,\n21844,\n21847,\n21848,\n21849,\n21850,\n21851,\n21853,\n21854,\n21855,\n21856,\n21858,\n21859,\n21864,\n21865,\n21867,\n21871,\n21872,\n21873,\n21874,\n21875,\n21876,\n21881,\n21882,\n21885,\n21887,\n21893,\n21894,\n21900,\n21901,\n21902,\n21904,\n21906,\n21907,\n21909,\n21910,\n21911,\n21914,\n21915,\n21918,\n21920,\n21921,\n21922,\n21923,\n21924,\n21925,\n21926,\n21928,\n21929,\n21930,\n21931,\n21932,\n21933,\n21934,\n21935,\n21936,\n21938,\n21940,\n21942,\n21944,\n21946,\n21948,\n21951,\n21952,\n21953,\n21954,\n21955,\n21958,\n21959,\n21960,\n21962,\n21963,\n21966,\n21967,\n21968,\n21973,\n21975,\n21976,\n21977,\n21978,\n21979,\n21982,\n21984,\n21986,\n21991,\n21993,\n21997,\n21998,\n22000,\n22001,\n22004,\n22006,\n22008,\n22009,\n22010,\n22011,\n22012,\n22015,\n22018,\n22019,\n22020,\n22021,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n22022,\n22023,\n22026,\n22027,\n22029,\n22032,\n22033,\n22034,\n22035,\n22036,\n22037,\n22038,\n22039,\n22041,\n22042,\n22044,\n22045,\n22048,\n22049,\n22050,\n22053,\n22054,\n22056,\n22057,\n22058,\n22059,\n22062,\n22063,\n22064,\n22067,\n22069,\n22071,\n22072,\n22074,\n22076,\n22077,\n22078,\n22080,\n22081,\n22082,\n22083,\n22084,\n22085,\n22086,\n22087,\n22088,\n22089,\n22090,\n22091,\n22095,\n22096,\n22097,\n22098,\n22099,\n22101,\n22102,\n22106,\n22107,\n22109,\n22110,\n22111,\n22112,\n22113,\n0,\n22115,\n22117,\n22118,\n22119,\n22125,\n22126,\n22127,\n22128,\n22130,\n22131,\n22132,\n22133,\n22135,\n22136,\n22137,\n22138,\n22141,\n22142,\n22143,\n22144,\n22145,\n22146,\n22147,\n22148,\n22151,\n22152,\n22153,\n22154,\n22155,\n22156,\n22157,\n22160,\n22161,\n22162,\n22164,\n22165,\n22166,\n22167,\n22168,\n22169,\n22170,\n22171,\n22172,\n22173,\n22174,\n22175,\n22176,\n22177,\n22178,\n22180,\n22181,\n22182,\n22183,\n22184,\n22185,\n22186,\n22187,\n22188,\n22189,\n22190,\n22192,\n22193,\n22194,\n22195,\n22196,\n22197,\n22198,\n22200,\n22201,\n22202,\n22203,\n22205,\n22206,\n22207,\n22208,\n22209,\n22210,\n22211,\n22212,\n22213,\n22214,\n22215,\n22216,\n22217,\n22219,\n22220,\n22221,\n22222,\n22223,\n22224,\n22225,\n22226,\n22227,\n22229,\n22230,\n22232,\n22233,\n22236,\n22243,\n22245,\n22246,\n22247,\n22248,\n22249,\n22250,\n22252,\n22254,\n22255,\n22258,\n22259,\n22262,\n22263,\n22264,\n22267,\n22268,\n22272,\n22273,\n22274,\n22277,\n22279,\n22283,\n22284,\n22285,\n22286,\n22287,\n22288,\n22289,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n22290,\n22291,\n22292,\n22293,\n22294,\n22295,\n22296,\n22297,\n22298,\n22299,\n22301,\n22302,\n22304,\n22305,\n22306,\n22308,\n22309,\n22310,\n22311,\n22315,\n22321,\n22322,\n22324,\n22325,\n22326,\n22327,\n22328,\n22332,\n22333,\n22335,\n22337,\n22339,\n22340,\n22341,\n22342,\n22344,\n22345,\n22347,\n22354,\n22355,\n22356,\n22357,\n22358,\n22360,\n22361,\n22370,\n22371,\n22373,\n22375,\n22380,\n22382,\n22384,\n22385,\n22386,\n22388,\n22389,\n22392,\n22393,\n22394,\n22397,\n22398,\n22399,\n22400,\n0,\n22401,\n22407,\n22408,\n22409,\n22410,\n22413,\n22414,\n22415,\n22416,\n22417,\n22420,\n22421,\n22422,\n22423,\n22424,\n22425,\n22426,\n22428,\n22429,\n22430,\n22431,\n22437,\n22440,\n22442,\n22444,\n22447,\n22448,\n22449,\n22451,\n22453,\n22454,\n22455,\n22457,\n22458,\n22459,\n22460,\n22461,\n22462,\n22463,\n22464,\n22465,\n22468,\n22469,\n22470,\n22471,\n22472,\n22473,\n22474,\n22476,\n22477,\n22480,\n22481,\n22483,\n22486,\n22487,\n22491,\n22492,\n22494,\n22497,\n22498,\n22499,\n22501,\n22502,\n22503,\n22504,\n22505,\n22506,\n22507,\n22508,\n22510,\n22512,\n22513,\n22514,\n22515,\n22517,\n22518,\n22519,\n22523,\n22524,\n22526,\n22527,\n22529,\n22531,\n22532,\n22533,\n22536,\n22537,\n22538,\n22540,\n22542,\n22543,\n22544,\n22546,\n22547,\n22548,\n22550,\n22551,\n22552,\n22554,\n22555,\n22556,\n22557,\n22559,\n22562,\n22563,\n22565,\n22566,\n22567,\n22568,\n22569,\n22571,\n22572,\n22573,\n22574,\n22575,\n22577,\n22578,\n22579,\n22580,\n22582,\n22583,\n22584,\n22585,\n22586,\n22587,\n22588,\n22589,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n22590,\n22591,\n22592,\n22593,\n22594,\n22595,\n22597,\n22598,\n22599,\n22600,\n22601,\n22602,\n22603,\n22606,\n22607,\n22608,\n22610,\n22611,\n22613,\n22614,\n22615,\n22617,\n22618,\n22619,\n22620,\n22621,\n22623,\n22624,\n22625,\n22626,\n22627,\n22628,\n22630,\n22631,\n22632,\n22633,\n22634,\n22637,\n22638,\n22639,\n22640,\n22641,\n22642,\n22643,\n22644,\n22645,\n22646,\n22647,\n22648,\n22649,\n22650,\n22651,\n22652,\n22653,\n22655,\n22658,\n22660,\n22662,\n22663,\n22664,\n22666,\n22667,\n22668,\n0,\n22669,\n22670,\n22671,\n22672,\n22673,\n22676,\n22677,\n22678,\n22679,\n22680,\n22683,\n22684,\n22685,\n22688,\n22689,\n22690,\n22691,\n22692,\n22693,\n22694,\n22695,\n22698,\n22699,\n22700,\n22701,\n22702,\n22703,\n22704,\n22705,\n22706,\n22707,\n22708,\n22709,\n22710,\n22711,\n22712,\n22713,\n22714,\n22715,\n22717,\n22718,\n22719,\n22720,\n22722,\n22723,\n22724,\n22726,\n22727,\n22728,\n22729,\n22730,\n22731,\n22732,\n22733,\n22734,\n22735,\n22736,\n22738,\n22739,\n22740,\n22742,\n22743,\n22744,\n22745,\n22746,\n22747,\n22748,\n22749,\n22750,\n22751,\n22752,\n22753,\n22754,\n22755,\n22757,\n22758,\n22759,\n22760,\n22761,\n22762,\n22765,\n22767,\n22769,\n22770,\n22772,\n22773,\n22775,\n22776,\n22778,\n22779,\n22780,\n22781,\n22782,\n22783,\n22784,\n22785,\n22787,\n22789,\n22790,\n22792,\n22793,\n22794,\n22795,\n22796,\n22798,\n22800,\n22801,\n22802,\n22803,\n22807,\n22808,\n22811,\n22813,\n22814,\n22816,\n22817,\n22818,\n22819,\n22822,\n22824,\n22828,\n22832,\n22834,\n22835,\n22837,\n22838,\n22843,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n22845,\n22846,\n22847,\n22848,\n22851,\n22853,\n22854,\n22858,\n22860,\n22861,\n22864,\n22866,\n22867,\n22873,\n22875,\n22876,\n22877,\n22878,\n22879,\n22881,\n22883,\n22884,\n22886,\n22887,\n22888,\n22889,\n22890,\n22891,\n22892,\n22893,\n22894,\n22895,\n22896,\n22897,\n22898,\n22901,\n22903,\n22906,\n22907,\n22908,\n22910,\n22911,\n22912,\n22917,\n22921,\n22923,\n22924,\n22926,\n22927,\n22928,\n22929,\n22932,\n22933,\n22936,\n22938,\n22939,\n22940,\n22941,\n22943,\n22944,\n22945,\n22946,\n22950,\n0,\n22951,\n22956,\n22957,\n22960,\n22961,\n22963,\n22964,\n22965,\n22966,\n22967,\n22968,\n22970,\n22972,\n22973,\n22975,\n22976,\n22977,\n22978,\n22979,\n22980,\n22981,\n22983,\n22984,\n22985,\n22988,\n22989,\n22990,\n22991,\n22997,\n22998,\n23001,\n23003,\n23006,\n23007,\n23008,\n23009,\n23010,\n23012,\n23014,\n23015,\n23017,\n23018,\n23019,\n23021,\n23022,\n23023,\n23024,\n23025,\n23026,\n23027,\n23028,\n23029,\n23030,\n23031,\n23032,\n23034,\n23036,\n23037,\n23038,\n23040,\n23042,\n23050,\n23051,\n23053,\n23054,\n23055,\n23056,\n23058,\n23060,\n23061,\n23062,\n23063,\n23065,\n23066,\n23067,\n23069,\n23070,\n23073,\n23074,\n23076,\n23078,\n23079,\n23080,\n23082,\n23083,\n23084,\n23085,\n23086,\n23087,\n23088,\n23091,\n23093,\n23095,\n23096,\n23097,\n23098,\n23099,\n23101,\n23102,\n23103,\n23105,\n23106,\n23107,\n23108,\n23109,\n23111,\n23112,\n23115,\n23116,\n23117,\n23118,\n23119,\n23120,\n23121,\n23122,\n23123,\n23124,\n23126,\n23127,\n23128,\n23129,\n23131,\n23132,\n23133,\n23134,\n23135,\n23136,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n23137,\n23139,\n23140,\n23141,\n23142,\n23144,\n23145,\n23147,\n23148,\n23149,\n23150,\n23151,\n23152,\n23153,\n23154,\n23155,\n23160,\n23161,\n23163,\n23164,\n23165,\n23166,\n23168,\n23169,\n23170,\n23171,\n23172,\n23173,\n23174,\n23175,\n23176,\n23177,\n23178,\n23179,\n23180,\n23181,\n23182,\n23183,\n23184,\n23185,\n23187,\n23188,\n23189,\n23190,\n23191,\n23192,\n23193,\n23196,\n23197,\n23198,\n23199,\n23200,\n23201,\n23202,\n23203,\n23204,\n23205,\n23206,\n23207,\n23208,\n23209,\n23211,\n23212,\n0,\n23213,\n23214,\n23215,\n23216,\n23217,\n23220,\n23222,\n23223,\n23225,\n23226,\n23227,\n23228,\n23229,\n23231,\n23232,\n23235,\n23236,\n23237,\n23238,\n23239,\n23240,\n23242,\n23243,\n23245,\n23246,\n23247,\n23248,\n23249,\n23251,\n23253,\n23255,\n23257,\n23258,\n23259,\n23261,\n23262,\n23263,\n23266,\n23268,\n23269,\n23271,\n23272,\n23274,\n23276,\n23277,\n23278,\n23279,\n23280,\n23282,\n23283,\n23284,\n23285,\n23286,\n23287,\n23288,\n23289,\n23290,\n23291,\n23292,\n23293,\n23294,\n23295,\n23296,\n23297,\n23298,\n23299,\n23300,\n23301,\n23302,\n23303,\n23304,\n23306,\n23307,\n23308,\n23309,\n23310,\n23311,\n23312,\n23313,\n23314,\n23315,\n23316,\n23317,\n23320,\n23321,\n23322,\n23323,\n23324,\n23325,\n23326,\n23327,\n23328,\n23329,\n23330,\n23331,\n23332,\n23333,\n23334,\n23335,\n23336,\n23337,\n23338,\n23339,\n23340,\n23341,\n23342,\n23343,\n23344,\n23345,\n23347,\n23349,\n23350,\n23352,\n23353,\n23354,\n23355,\n23356,\n23357,\n23358,\n23359,\n23361,\n23362,\n23363,\n23364,\n23365,\n23366,\n23367,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n23368,\n23369,\n23370,\n23371,\n23372,\n23373,\n23374,\n23375,\n23378,\n23382,\n23390,\n23392,\n23393,\n23399,\n23400,\n23403,\n23405,\n23406,\n23407,\n23410,\n23412,\n23414,\n23415,\n23416,\n23417,\n23419,\n23420,\n23422,\n23423,\n23426,\n23430,\n23434,\n23437,\n23438,\n23440,\n23441,\n23442,\n23444,\n23446,\n23455,\n23463,\n23464,\n23465,\n23468,\n23469,\n23470,\n23471,\n23473,\n23474,\n23479,\n23482,\n23483,\n23484,\n23488,\n23489,\n23491,\n23496,\n23497,\n23498,\n23499,\n23501,\n23502,\n23503,\n0,\n23505,\n23508,\n23509,\n23510,\n23511,\n23512,\n23513,\n23514,\n23515,\n23516,\n23520,\n23522,\n23523,\n23526,\n23527,\n23529,\n23530,\n23531,\n23532,\n23533,\n23535,\n23537,\n23538,\n23539,\n23540,\n23541,\n23542,\n23543,\n23549,\n23550,\n23552,\n23554,\n23555,\n23557,\n23559,\n23560,\n23563,\n23564,\n23565,\n23566,\n23568,\n23570,\n23571,\n23575,\n23577,\n23579,\n23582,\n23583,\n23584,\n23585,\n23587,\n23590,\n23592,\n23593,\n23594,\n23595,\n23597,\n23598,\n23599,\n23600,\n23602,\n23603,\n23605,\n23606,\n23607,\n23619,\n23620,\n23622,\n23623,\n23628,\n23629,\n23634,\n23635,\n23636,\n23638,\n23639,\n23640,\n23642,\n23643,\n23644,\n23645,\n23647,\n23650,\n23652,\n23655,\n23656,\n23657,\n23658,\n23659,\n23660,\n23661,\n23664,\n23666,\n23667,\n23668,\n23669,\n23670,\n23671,\n23672,\n23675,\n23676,\n23677,\n23678,\n23680,\n23683,\n23684,\n23685,\n23686,\n23687,\n23689,\n23690,\n23691,\n23694,\n23695,\n23698,\n23699,\n23701,\n23709,\n23710,\n23711,\n23712,\n23713,\n23716,\n23717,\n23718,\n23719,\n23720,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n23722,\n23726,\n23727,\n23728,\n23730,\n23732,\n23734,\n23737,\n23738,\n23739,\n23740,\n23742,\n23744,\n23746,\n23747,\n23749,\n23750,\n23751,\n23752,\n23753,\n23754,\n23756,\n23757,\n23758,\n23759,\n23760,\n23761,\n23763,\n23764,\n23765,\n23766,\n23767,\n23768,\n23770,\n23771,\n23772,\n23773,\n23774,\n23775,\n23776,\n23778,\n23779,\n23783,\n23785,\n23787,\n23788,\n23790,\n23791,\n23793,\n23794,\n23795,\n23796,\n23797,\n23798,\n23799,\n23800,\n23801,\n23802,\n23804,\n23805,\n23806,\n23807,\n23808,\n0,\n23809,\n23812,\n23813,\n23816,\n23817,\n23818,\n23819,\n23820,\n23821,\n23823,\n23824,\n23825,\n23826,\n23827,\n23829,\n23831,\n23832,\n23833,\n23834,\n23836,\n23837,\n23839,\n23840,\n23841,\n23842,\n23843,\n23845,\n23848,\n23850,\n23851,\n23852,\n23855,\n23856,\n23857,\n23858,\n23859,\n23861,\n23862,\n23863,\n23864,\n23865,\n23866,\n23867,\n23868,\n23871,\n23872,\n23873,\n23874,\n23875,\n23876,\n23877,\n23878,\n23880,\n23881,\n23885,\n23886,\n23887,\n23888,\n23889,\n23890,\n23891,\n23892,\n23893,\n23894,\n23895,\n23897,\n23898,\n23900,\n23902,\n23903,\n23904,\n23905,\n23906,\n23907,\n23908,\n23909,\n23910,\n23911,\n23912,\n23914,\n23917,\n23918,\n23920,\n23921,\n23922,\n23923,\n23925,\n23926,\n23927,\n23928,\n23929,\n23930,\n23931,\n23932,\n23933,\n23934,\n23935,\n23936,\n23937,\n23939,\n23940,\n23941,\n23942,\n23943,\n23944,\n23945,\n23946,\n23947,\n23948,\n23949,\n23950,\n23951,\n23952,\n23953,\n23954,\n23955,\n23956,\n23957,\n23958,\n23959,\n23960,\n23962,\n23963,\n23964,\n23966,\n23967,\n23968,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n23969,\n23970,\n23971,\n23972,\n23973,\n23974,\n23975,\n23976,\n23977,\n23978,\n23979,\n23980,\n23981,\n23982,\n23983,\n23984,\n23985,\n23986,\n23987,\n23988,\n23989,\n23990,\n23992,\n23993,\n23994,\n23995,\n23996,\n23997,\n23998,\n23999,\n24000,\n24001,\n24002,\n24003,\n24004,\n24006,\n24007,\n24008,\n24009,\n24010,\n24011,\n24012,\n24014,\n24015,\n24016,\n24017,\n24018,\n24019,\n24020,\n24021,\n24022,\n24023,\n24024,\n24025,\n24026,\n24028,\n24031,\n24032,\n24035,\n24036,\n24042,\n24044,\n24045,\n0,\n24048,\n24053,\n24054,\n24056,\n24057,\n24058,\n24059,\n24060,\n24063,\n24064,\n24068,\n24071,\n24073,\n24074,\n24075,\n24077,\n24078,\n24082,\n24083,\n24087,\n24094,\n24095,\n24096,\n24097,\n24098,\n24099,\n24100,\n24101,\n24104,\n24105,\n24106,\n24107,\n24108,\n24111,\n24112,\n24114,\n24115,\n24116,\n24117,\n24118,\n24121,\n24122,\n24126,\n24127,\n24128,\n24129,\n24131,\n24134,\n24135,\n24136,\n24137,\n24138,\n24139,\n24141,\n24142,\n24143,\n24144,\n24145,\n24146,\n24147,\n24150,\n24151,\n24152,\n24153,\n24154,\n24156,\n24157,\n24159,\n24160,\n24163,\n24164,\n24165,\n24166,\n24167,\n24168,\n24169,\n24170,\n24171,\n24172,\n24173,\n24174,\n24175,\n24176,\n24177,\n24181,\n24183,\n24185,\n24190,\n24193,\n24194,\n24195,\n24197,\n24200,\n24201,\n24204,\n24205,\n24206,\n24210,\n24216,\n24219,\n24221,\n24225,\n24226,\n24227,\n24228,\n24232,\n24233,\n24234,\n24235,\n24236,\n24238,\n24239,\n24240,\n24241,\n24242,\n24244,\n24250,\n24251,\n24252,\n24253,\n24255,\n24256,\n24257,\n24258,\n24259,\n24260,\n24261,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n24262,\n24263,\n24264,\n24267,\n24268,\n24269,\n24270,\n24271,\n24272,\n24276,\n24277,\n24279,\n24280,\n24281,\n24282,\n24284,\n24285,\n24286,\n24287,\n24288,\n24289,\n24290,\n24291,\n24292,\n24293,\n24294,\n24295,\n24297,\n24299,\n24300,\n24301,\n24302,\n24303,\n24304,\n24305,\n24306,\n24307,\n24309,\n24312,\n24313,\n24315,\n24316,\n24317,\n24325,\n24326,\n24327,\n24329,\n24332,\n24333,\n24334,\n24336,\n24338,\n24340,\n24342,\n24345,\n24346,\n24348,\n24349,\n24350,\n24353,\n24354,\n24355,\n24356,\n0,\n24360,\n24363,\n24364,\n24366,\n24368,\n24370,\n24371,\n24372,\n24373,\n24374,\n24375,\n24376,\n24379,\n24381,\n24382,\n24383,\n24385,\n24386,\n24387,\n24388,\n24389,\n24390,\n24391,\n24392,\n24393,\n24394,\n24395,\n24396,\n24397,\n24398,\n24399,\n24401,\n24404,\n24409,\n24410,\n24411,\n24412,\n24414,\n24415,\n24416,\n24419,\n24421,\n24423,\n24424,\n24427,\n24430,\n24431,\n24434,\n24436,\n24437,\n24438,\n24440,\n24442,\n24445,\n24446,\n24447,\n24451,\n24454,\n24461,\n24462,\n24463,\n24465,\n24467,\n24468,\n24470,\n24474,\n24475,\n24477,\n24478,\n24479,\n24480,\n24482,\n24483,\n24484,\n24485,\n24486,\n24487,\n24489,\n24491,\n24492,\n24495,\n24496,\n24497,\n24498,\n24499,\n24500,\n24502,\n24504,\n24505,\n24506,\n24507,\n24510,\n24511,\n24512,\n24513,\n24514,\n24519,\n24520,\n24522,\n24523,\n24526,\n24531,\n24532,\n24533,\n24538,\n24539,\n24540,\n24542,\n24543,\n24546,\n24547,\n24549,\n24550,\n24552,\n24553,\n24556,\n24559,\n24560,\n24562,\n24563,\n24564,\n24566,\n24567,\n24569,\n24570,\n24572,\n24583,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n24584,\n24585,\n24587,\n24588,\n24592,\n24593,\n24595,\n24599,\n24600,\n24602,\n24606,\n24607,\n24610,\n24611,\n24612,\n24620,\n24621,\n24622,\n24624,\n24625,\n24626,\n24627,\n24628,\n24630,\n24631,\n24632,\n24633,\n24634,\n24637,\n24638,\n24640,\n24644,\n24645,\n24646,\n24647,\n24648,\n24649,\n24650,\n24652,\n24654,\n24655,\n24657,\n24659,\n24660,\n24662,\n24663,\n24664,\n24667,\n24668,\n24670,\n24671,\n24672,\n24673,\n24677,\n24678,\n24686,\n24689,\n24690,\n24692,\n24693,\n24695,\n24702,\n24704,\n0,\n24705,\n24706,\n24709,\n24710,\n24711,\n24712,\n24714,\n24715,\n24718,\n24719,\n24720,\n24721,\n24723,\n24725,\n24727,\n24728,\n24729,\n24732,\n24734,\n24737,\n24738,\n24740,\n24741,\n24743,\n24745,\n24746,\n24750,\n24752,\n24755,\n24757,\n24758,\n24759,\n24761,\n24762,\n24765,\n24766,\n24767,\n24768,\n24769,\n24770,\n24771,\n24772,\n24775,\n24776,\n24777,\n24780,\n24781,\n24782,\n24783,\n24784,\n24786,\n24787,\n24788,\n24790,\n24791,\n24793,\n24795,\n24798,\n24801,\n24802,\n24803,\n24804,\n24805,\n24810,\n24817,\n24818,\n24821,\n24823,\n24824,\n24827,\n24828,\n24829,\n24830,\n24831,\n24834,\n24835,\n24836,\n24837,\n24839,\n24842,\n24843,\n24844,\n24848,\n24849,\n24850,\n24851,\n24852,\n24854,\n24855,\n24856,\n24857,\n24859,\n24860,\n24861,\n24862,\n24865,\n24866,\n24869,\n24872,\n24873,\n24874,\n24876,\n24877,\n24878,\n24879,\n24880,\n24881,\n24882,\n24883,\n24884,\n24885,\n24886,\n24887,\n24888,\n24889,\n24890,\n24891,\n24892,\n24893,\n24894,\n24896,\n24897,\n24898,\n24899,\n24900,\n24901,\n24902,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n24903,\n24905,\n24907,\n24909,\n24911,\n24912,\n24914,\n24915,\n24916,\n24918,\n24919,\n24920,\n24921,\n24922,\n24923,\n24924,\n24926,\n24927,\n24928,\n24929,\n24931,\n24932,\n24933,\n24934,\n24937,\n24938,\n24939,\n24940,\n24941,\n24942,\n24943,\n24945,\n24946,\n24947,\n24948,\n24950,\n24952,\n24953,\n24954,\n24955,\n24956,\n24957,\n24958,\n24959,\n24960,\n24961,\n24962,\n24963,\n24964,\n24965,\n24966,\n24967,\n24968,\n24969,\n24970,\n24972,\n24973,\n24975,\n24976,\n24977,\n24978,\n24979,\n24981,\n0,\n24982,\n24983,\n24984,\n24985,\n24986,\n24987,\n24988,\n24990,\n24991,\n24992,\n24993,\n24994,\n24995,\n24996,\n24997,\n24998,\n25002,\n25003,\n25005,\n25006,\n25007,\n25008,\n25009,\n25010,\n25011,\n25012,\n25013,\n25014,\n25016,\n25017,\n25018,\n25019,\n25020,\n25021,\n25023,\n25024,\n25025,\n25027,\n25028,\n25029,\n25030,\n25031,\n25033,\n25036,\n25037,\n25038,\n25039,\n25040,\n25043,\n25045,\n25046,\n25047,\n25048,\n25049,\n25050,\n25051,\n25052,\n25053,\n25054,\n25055,\n25056,\n25057,\n25058,\n25059,\n25060,\n25061,\n25063,\n25064,\n25065,\n25066,\n25067,\n25068,\n25069,\n25070,\n25071,\n25072,\n25073,\n25074,\n25075,\n25076,\n25078,\n25079,\n25080,\n25081,\n25082,\n25083,\n25084,\n25085,\n25086,\n25088,\n25089,\n25090,\n25091,\n25092,\n25093,\n25095,\n25097,\n25107,\n25108,\n25113,\n25116,\n25117,\n25118,\n25120,\n25123,\n25126,\n25127,\n25128,\n25129,\n25131,\n25133,\n25135,\n25136,\n25137,\n25138,\n25141,\n25142,\n25144,\n25145,\n25146,\n25147,\n25148,\n25154,\n25156,\n25157,\n25158,\n25162,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n25167,\n25168,\n25173,\n25174,\n25175,\n25177,\n25178,\n25180,\n25181,\n25182,\n25183,\n25184,\n25185,\n25186,\n25188,\n25189,\n25192,\n25201,\n25202,\n25204,\n25205,\n25207,\n25208,\n25210,\n25211,\n25213,\n25217,\n25218,\n25219,\n25221,\n25222,\n25223,\n25224,\n25227,\n25228,\n25229,\n25230,\n25231,\n25232,\n25236,\n25241,\n25244,\n25245,\n25246,\n25251,\n25254,\n25255,\n25257,\n25258,\n25261,\n25262,\n25263,\n25264,\n25266,\n25267,\n25268,\n25270,\n25271,\n25272,\n25274,\n25278,\n25280,\n25281,\n0,\n25283,\n25291,\n25295,\n25297,\n25301,\n25309,\n25310,\n25312,\n25313,\n25316,\n25322,\n25323,\n25328,\n25330,\n25333,\n25336,\n25337,\n25338,\n25339,\n25344,\n25347,\n25348,\n25349,\n25350,\n25354,\n25355,\n25356,\n25357,\n25359,\n25360,\n25362,\n25363,\n25364,\n25365,\n25367,\n25368,\n25369,\n25372,\n25382,\n25383,\n25385,\n25388,\n25389,\n25390,\n25392,\n25393,\n25395,\n25396,\n25397,\n25398,\n25399,\n25400,\n25403,\n25404,\n25406,\n25407,\n25408,\n25409,\n25412,\n25415,\n25416,\n25418,\n25425,\n25426,\n25427,\n25428,\n25430,\n25431,\n25432,\n25433,\n25434,\n25435,\n25436,\n25437,\n25440,\n25444,\n25445,\n25446,\n25448,\n25450,\n25451,\n25452,\n25455,\n25456,\n25458,\n25459,\n25460,\n25461,\n25464,\n25465,\n25468,\n25469,\n25470,\n25471,\n25473,\n25475,\n25476,\n25477,\n25478,\n25483,\n25485,\n25489,\n25491,\n25492,\n25493,\n25495,\n25497,\n25498,\n25499,\n25500,\n25501,\n25502,\n25503,\n25505,\n25508,\n25510,\n25515,\n25519,\n25521,\n25522,\n25525,\n25526,\n25529,\n25531,\n25533,\n25535,\n25536,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n25537,\n25538,\n25539,\n25541,\n25543,\n25544,\n25546,\n25547,\n25548,\n25553,\n25555,\n25556,\n25557,\n25559,\n25560,\n25561,\n25562,\n25563,\n25564,\n25565,\n25567,\n25570,\n25572,\n25573,\n25574,\n25575,\n25576,\n25579,\n25580,\n25582,\n25583,\n25584,\n25585,\n25587,\n25589,\n25591,\n25593,\n25594,\n25595,\n25596,\n25598,\n25603,\n25604,\n25606,\n25607,\n25608,\n25609,\n25610,\n25613,\n25614,\n25617,\n25618,\n25621,\n25622,\n25623,\n25624,\n25625,\n25626,\n25629,\n25631,\n25634,\n25635,\n25636,\n0,\n25637,\n25639,\n25640,\n25641,\n25643,\n25646,\n25647,\n25648,\n25649,\n25650,\n25651,\n25653,\n25654,\n25655,\n25656,\n25657,\n25659,\n25660,\n25662,\n25664,\n25666,\n25667,\n25673,\n25675,\n25676,\n25677,\n25678,\n25679,\n25680,\n25681,\n25683,\n25685,\n25686,\n25687,\n25689,\n25690,\n25691,\n25692,\n25693,\n25695,\n25696,\n25697,\n25698,\n25699,\n25700,\n25701,\n25702,\n25704,\n25706,\n25707,\n25708,\n25710,\n25711,\n25712,\n25713,\n25714,\n25715,\n25716,\n25717,\n25718,\n25719,\n25723,\n25724,\n25725,\n25726,\n25727,\n25728,\n25729,\n25731,\n25734,\n25736,\n25737,\n25738,\n25739,\n25740,\n25741,\n25742,\n25743,\n25744,\n25747,\n25748,\n25751,\n25752,\n25754,\n25755,\n25756,\n25757,\n25759,\n25760,\n25761,\n25762,\n25763,\n25765,\n25766,\n25767,\n25768,\n25770,\n25771,\n25775,\n25777,\n25778,\n25779,\n25780,\n25782,\n25785,\n25787,\n25789,\n25790,\n25791,\n25793,\n25795,\n25796,\n25798,\n25799,\n25800,\n25801,\n25802,\n25803,\n25804,\n25807,\n25809,\n25811,\n25812,\n25813,\n25814,\n25817,\n25818,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n25819,\n25820,\n25821,\n25823,\n25824,\n25825,\n25827,\n25829,\n25831,\n25832,\n25833,\n25834,\n25835,\n25836,\n25837,\n25838,\n25839,\n25840,\n25841,\n25842,\n25843,\n25844,\n25845,\n25846,\n25847,\n25848,\n25849,\n25850,\n25851,\n25852,\n25853,\n25854,\n25855,\n25857,\n25858,\n25859,\n25860,\n25861,\n25862,\n25863,\n25864,\n25866,\n25867,\n25868,\n25869,\n25870,\n25871,\n25872,\n25873,\n25875,\n25876,\n25877,\n25878,\n25879,\n25881,\n25882,\n25883,\n25884,\n25885,\n25886,\n25887,\n25888,\n25889,\n0,\n25890,\n25891,\n25892,\n25894,\n25895,\n25896,\n25897,\n25898,\n25900,\n25901,\n25904,\n25905,\n25906,\n25907,\n25911,\n25914,\n25916,\n25917,\n25920,\n25921,\n25922,\n25923,\n25924,\n25926,\n25927,\n25930,\n25931,\n25933,\n25934,\n25936,\n25938,\n25939,\n25940,\n25943,\n25944,\n25946,\n25948,\n25951,\n25952,\n25953,\n25956,\n25957,\n25959,\n25960,\n25961,\n25962,\n25965,\n25966,\n25967,\n25969,\n25971,\n25973,\n25974,\n25976,\n25977,\n25978,\n25979,\n25980,\n25981,\n25982,\n25983,\n25984,\n25985,\n25986,\n25987,\n25988,\n25989,\n25990,\n25992,\n25993,\n25994,\n25997,\n25998,\n25999,\n26002,\n26004,\n26005,\n26006,\n26008,\n26010,\n26013,\n26014,\n26016,\n26018,\n26019,\n26022,\n26024,\n26026,\n26028,\n26030,\n26033,\n26034,\n26035,\n26036,\n26037,\n26038,\n26039,\n26040,\n26042,\n26043,\n26046,\n26047,\n26048,\n26050,\n26055,\n26056,\n26057,\n26058,\n26061,\n26064,\n26065,\n26067,\n26068,\n26069,\n26072,\n26073,\n26074,\n26075,\n26076,\n26077,\n26078,\n26079,\n26081,\n26083,\n26084,\n26090,\n26091,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n26098,\n26099,\n26100,\n26101,\n26104,\n26105,\n26107,\n26108,\n26109,\n26110,\n26111,\n26113,\n26116,\n26117,\n26119,\n26120,\n26121,\n26123,\n26125,\n26128,\n26129,\n26130,\n26134,\n26135,\n26136,\n26138,\n26139,\n26140,\n26142,\n26145,\n26146,\n26147,\n26148,\n26150,\n26153,\n26154,\n26155,\n26156,\n26158,\n26160,\n26162,\n26163,\n26167,\n26168,\n26169,\n26170,\n26171,\n26173,\n26175,\n26176,\n26178,\n26180,\n26181,\n26182,\n26183,\n26184,\n26185,\n26186,\n26189,\n26190,\n26192,\n26193,\n26200,\n0,\n26201,\n26203,\n26204,\n26205,\n26206,\n26208,\n26210,\n26211,\n26213,\n26215,\n26217,\n26218,\n26219,\n26220,\n26221,\n26225,\n26226,\n26227,\n26229,\n26232,\n26233,\n26235,\n26236,\n26237,\n26239,\n26240,\n26241,\n26243,\n26245,\n26246,\n26248,\n26249,\n26250,\n26251,\n26253,\n26254,\n26255,\n26256,\n26258,\n26259,\n26260,\n26261,\n26264,\n26265,\n26266,\n26267,\n26268,\n26270,\n26271,\n26272,\n26273,\n26274,\n26275,\n26276,\n26277,\n26278,\n26281,\n26282,\n26283,\n26284,\n26285,\n26287,\n26288,\n26289,\n26290,\n26291,\n26293,\n26294,\n26295,\n26296,\n26298,\n26299,\n26300,\n26301,\n26303,\n26304,\n26305,\n26306,\n26307,\n26308,\n26309,\n26310,\n26311,\n26312,\n26313,\n26314,\n26315,\n26316,\n26317,\n26318,\n26319,\n26320,\n26321,\n26322,\n26323,\n26324,\n26325,\n26326,\n26327,\n26328,\n26330,\n26334,\n26335,\n26336,\n26337,\n26338,\n26339,\n26340,\n26341,\n26343,\n26344,\n26346,\n26347,\n26348,\n26349,\n26350,\n26351,\n26353,\n26357,\n26358,\n26360,\n26362,\n26363,\n26365,\n26369,\n26370,\n26371,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n26372,\n26373,\n26374,\n26375,\n26380,\n26382,\n26383,\n26385,\n26386,\n26387,\n26390,\n26392,\n26393,\n26394,\n26396,\n26398,\n26400,\n26401,\n26402,\n26403,\n26404,\n26405,\n26407,\n26409,\n26414,\n26416,\n26418,\n26419,\n26422,\n26423,\n26424,\n26425,\n26427,\n26428,\n26430,\n26431,\n26433,\n26436,\n26437,\n26439,\n26442,\n26443,\n26445,\n26450,\n26452,\n26453,\n26455,\n26456,\n26457,\n26458,\n26459,\n26461,\n26466,\n26467,\n26468,\n26470,\n26471,\n26475,\n26476,\n26478,\n26481,\n26484,\n26486,\n0,\n26488,\n26489,\n26490,\n26491,\n26493,\n26496,\n26498,\n26499,\n26501,\n26502,\n26504,\n26506,\n26508,\n26509,\n26510,\n26511,\n26513,\n26514,\n26515,\n26516,\n26518,\n26521,\n26523,\n26527,\n26528,\n26529,\n26532,\n26534,\n26537,\n26540,\n26542,\n26545,\n26546,\n26548,\n26553,\n26554,\n26555,\n26556,\n26557,\n26558,\n26559,\n26560,\n26562,\n26565,\n26566,\n26567,\n26568,\n26569,\n26570,\n26571,\n26572,\n26573,\n26574,\n26581,\n26582,\n26583,\n26587,\n26591,\n26593,\n26595,\n26596,\n26598,\n26599,\n26600,\n26602,\n26603,\n26605,\n26606,\n26610,\n26613,\n26614,\n26615,\n26616,\n26617,\n26618,\n26619,\n26620,\n26622,\n26625,\n26626,\n26627,\n26628,\n26630,\n26637,\n26640,\n26642,\n26644,\n26645,\n26648,\n26649,\n26650,\n26651,\n26652,\n26654,\n26655,\n26656,\n26658,\n26659,\n26660,\n26661,\n26662,\n26663,\n26664,\n26667,\n26668,\n26669,\n26670,\n26671,\n26672,\n26673,\n26676,\n26677,\n26678,\n26682,\n26683,\n26687,\n26695,\n26699,\n26701,\n26703,\n26706,\n26710,\n26711,\n26712,\n26713,\n26714,\n26715,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n26716,\n26717,\n26718,\n26719,\n26730,\n26732,\n26733,\n26734,\n26735,\n26736,\n26737,\n26738,\n26739,\n26741,\n26744,\n26745,\n26746,\n26747,\n26748,\n26749,\n26750,\n26751,\n26752,\n26754,\n26756,\n26759,\n26760,\n26761,\n26762,\n26763,\n26764,\n26765,\n26766,\n26768,\n26769,\n26770,\n26772,\n26773,\n26774,\n26776,\n26777,\n26778,\n26779,\n26780,\n26781,\n26782,\n26783,\n26784,\n26785,\n26787,\n26788,\n26789,\n26793,\n26794,\n26795,\n26796,\n26798,\n26801,\n26802,\n26804,\n26806,\n26807,\n26808,\n0,\n26809,\n26810,\n26811,\n26812,\n26813,\n26814,\n26815,\n26817,\n26819,\n26820,\n26821,\n26822,\n26823,\n26824,\n26826,\n26828,\n26830,\n26831,\n26832,\n26833,\n26835,\n26836,\n26838,\n26839,\n26841,\n26843,\n26844,\n26845,\n26846,\n26847,\n26849,\n26850,\n26852,\n26853,\n26854,\n26855,\n26856,\n26857,\n26858,\n26859,\n26860,\n26861,\n26863,\n26866,\n26867,\n26868,\n26870,\n26871,\n26872,\n26875,\n26877,\n26878,\n26879,\n26880,\n26882,\n26883,\n26884,\n26886,\n26887,\n26888,\n26889,\n26890,\n26892,\n26895,\n26897,\n26899,\n26900,\n26901,\n26902,\n26903,\n26904,\n26905,\n26906,\n26907,\n26908,\n26909,\n26910,\n26913,\n26914,\n26915,\n26917,\n26918,\n26919,\n26920,\n26921,\n26922,\n26923,\n26924,\n26926,\n26927,\n26929,\n26930,\n26931,\n26933,\n26934,\n26935,\n26936,\n26938,\n26939,\n26940,\n26942,\n26944,\n26945,\n26947,\n26948,\n26949,\n26950,\n26951,\n26952,\n26953,\n26954,\n26955,\n26956,\n26957,\n26958,\n26959,\n26960,\n26961,\n26962,\n26963,\n26965,\n26966,\n26968,\n26969,\n26971,\n26972,\n26975,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n26977,\n26978,\n26980,\n26981,\n26983,\n26984,\n26985,\n26986,\n26988,\n26989,\n26991,\n26992,\n26994,\n26995,\n26996,\n26997,\n26998,\n27002,\n27003,\n27005,\n27006,\n27007,\n27009,\n27011,\n27013,\n27018,\n27019,\n27020,\n27022,\n27023,\n27024,\n27025,\n27026,\n27027,\n27030,\n27031,\n27033,\n27034,\n27037,\n27038,\n27039,\n27040,\n27041,\n27042,\n27043,\n27044,\n27045,\n27046,\n27049,\n27050,\n27052,\n27054,\n27055,\n27056,\n27058,\n27059,\n27061,\n27062,\n27064,\n27065,\n27066,\n27068,\n27069,\n0,\n27070,\n27071,\n27072,\n27074,\n27075,\n27076,\n27077,\n27078,\n27079,\n27080,\n27081,\n27083,\n27085,\n27087,\n27089,\n27090,\n27091,\n27093,\n27094,\n27095,\n27096,\n27097,\n27098,\n27100,\n27101,\n27102,\n27105,\n27106,\n27107,\n27108,\n27109,\n27110,\n27111,\n27112,\n27113,\n27114,\n27115,\n27116,\n27118,\n27119,\n27120,\n27121,\n27123,\n27124,\n27125,\n27126,\n27127,\n27128,\n27129,\n27130,\n27131,\n27132,\n27134,\n27136,\n27137,\n27138,\n27139,\n27140,\n27141,\n27142,\n27143,\n27144,\n27145,\n27147,\n27148,\n27149,\n27150,\n27151,\n27152,\n27153,\n27154,\n27155,\n27156,\n27157,\n27158,\n27161,\n27162,\n27163,\n27164,\n27165,\n27166,\n27168,\n27170,\n27171,\n27172,\n27173,\n27174,\n27175,\n27177,\n27179,\n27180,\n27181,\n27182,\n27184,\n27186,\n27187,\n27188,\n27190,\n27191,\n27192,\n27193,\n27194,\n27195,\n27196,\n27199,\n27200,\n27201,\n27202,\n27203,\n27205,\n27206,\n27208,\n27209,\n27210,\n27211,\n27212,\n27213,\n27214,\n27215,\n27217,\n27218,\n27219,\n27220,\n27221,\n27222,\n27223,\n27226,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n27228,\n27229,\n27230,\n27231,\n27232,\n27234,\n27235,\n27236,\n27238,\n27239,\n27240,\n27241,\n27242,\n27243,\n27244,\n27245,\n27246,\n27247,\n27248,\n27250,\n27251,\n27252,\n27253,\n27254,\n27255,\n27256,\n27258,\n27259,\n27261,\n27262,\n27263,\n27265,\n27266,\n27267,\n27269,\n27270,\n27271,\n27272,\n27273,\n27274,\n27275,\n27276,\n27277,\n27279,\n27282,\n27283,\n27284,\n27285,\n27286,\n27288,\n27289,\n27290,\n27291,\n27292,\n27293,\n27294,\n27295,\n27297,\n27298,\n27299,\n27300,\n27301,\n27302,\n0,\n27303,\n27304,\n27306,\n27309,\n27310,\n27311,\n27312,\n27313,\n27314,\n27315,\n27316,\n27317,\n27318,\n27319,\n27320,\n27321,\n27322,\n27323,\n27324,\n27325,\n27326,\n27327,\n27328,\n27329,\n27330,\n27331,\n27332,\n27333,\n27334,\n27335,\n27336,\n27337,\n27338,\n27339,\n27340,\n27341,\n27342,\n27343,\n27344,\n27345,\n27346,\n27347,\n27348,\n27349,\n27350,\n27351,\n27352,\n27353,\n27354,\n27355,\n27356,\n27357,\n27358,\n27359,\n27360,\n27361,\n27362,\n27363,\n27364,\n27365,\n27366,\n27367,\n27368,\n27369,\n27370,\n27371,\n27372,\n27373,\n27374,\n27375,\n27376,\n27377,\n27378,\n27379,\n27380,\n27381,\n27382,\n27383,\n27384,\n27385,\n27386,\n27387,\n27388,\n27389,\n27390,\n27391,\n27392,\n27393,\n27394,\n27395,\n27396,\n27397,\n27398,\n27399,\n27400,\n27401,\n27402,\n27403,\n27404,\n27405,\n27406,\n27407,\n27408,\n27409,\n27410,\n27411,\n27412,\n27413,\n27414,\n27415,\n27416,\n27417,\n27418,\n27419,\n27420,\n27421,\n27422,\n27423,\n27429,\n27430,\n27432,\n27433,\n27434,\n27435,\n27436,\n27437,\n27438,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n27439,\n27440,\n27441,\n27443,\n27444,\n27445,\n27446,\n27448,\n27451,\n27452,\n27453,\n27455,\n27456,\n27457,\n27458,\n27460,\n27461,\n27464,\n27466,\n27467,\n27469,\n27470,\n27471,\n27472,\n27473,\n27474,\n27475,\n27476,\n27477,\n27478,\n27479,\n27480,\n27482,\n27483,\n27484,\n27485,\n27486,\n27487,\n27488,\n27489,\n27496,\n27497,\n27499,\n27500,\n27501,\n27502,\n27503,\n27504,\n27505,\n27506,\n27507,\n27508,\n27509,\n27510,\n27511,\n27512,\n27514,\n27517,\n27518,\n27519,\n27520,\n27525,\n27528,\n0,\n27532,\n27534,\n27535,\n27536,\n27537,\n27540,\n27541,\n27543,\n27544,\n27545,\n27548,\n27549,\n27550,\n27551,\n27552,\n27554,\n27555,\n27556,\n27557,\n27558,\n27559,\n27560,\n27561,\n27563,\n27564,\n27565,\n27566,\n27567,\n27568,\n27569,\n27570,\n27574,\n27576,\n27577,\n27578,\n27579,\n27580,\n27581,\n27582,\n27584,\n27587,\n27588,\n27590,\n27591,\n27592,\n27593,\n27594,\n27596,\n27598,\n27600,\n27601,\n27608,\n27610,\n27612,\n27613,\n27614,\n27615,\n27616,\n27618,\n27619,\n27620,\n27621,\n27622,\n27623,\n27624,\n27625,\n27628,\n27629,\n27630,\n27632,\n27633,\n27634,\n27636,\n27638,\n27639,\n27640,\n27642,\n27643,\n27644,\n27646,\n27647,\n27648,\n27649,\n27650,\n27651,\n27652,\n27656,\n27657,\n27658,\n27659,\n27660,\n27662,\n27666,\n27671,\n27676,\n27677,\n27678,\n27680,\n27683,\n27685,\n27691,\n27692,\n27693,\n27697,\n27699,\n27702,\n27703,\n27705,\n27706,\n27707,\n27708,\n27710,\n27711,\n27715,\n27716,\n27717,\n27720,\n27723,\n27724,\n27725,\n27726,\n27727,\n27729,\n27730,\n27731,\n27734,\n27736,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n27737,\n27738,\n27746,\n27747,\n27749,\n27750,\n27751,\n27755,\n27756,\n27757,\n27758,\n27759,\n27761,\n27763,\n27765,\n27767,\n27768,\n27770,\n27771,\n27772,\n27775,\n27776,\n27780,\n27783,\n27786,\n27787,\n27789,\n27790,\n27793,\n27794,\n27797,\n27798,\n27799,\n27800,\n27802,\n27804,\n27805,\n27806,\n27808,\n27810,\n27816,\n27820,\n27823,\n27824,\n27828,\n27829,\n27830,\n27831,\n27834,\n27840,\n27841,\n27842,\n27843,\n27846,\n27847,\n27848,\n27851,\n27853,\n27854,\n27855,\n27857,\n27858,\n27864,\n0,\n27865,\n27866,\n27868,\n27869,\n27871,\n27876,\n27878,\n27879,\n27881,\n27884,\n27885,\n27890,\n27892,\n27897,\n27903,\n27904,\n27906,\n27907,\n27909,\n27910,\n27912,\n27913,\n27914,\n27917,\n27919,\n27920,\n27921,\n27923,\n27924,\n27925,\n27926,\n27928,\n27932,\n27933,\n27935,\n27936,\n27937,\n27938,\n27939,\n27940,\n27942,\n27944,\n27945,\n27948,\n27949,\n27951,\n27952,\n27956,\n27958,\n27959,\n27960,\n27962,\n27967,\n27968,\n27970,\n27972,\n27977,\n27980,\n27984,\n27989,\n27990,\n27991,\n27992,\n27995,\n27997,\n27999,\n28001,\n28002,\n28004,\n28005,\n28007,\n28008,\n28011,\n28012,\n28013,\n28016,\n28017,\n28018,\n28019,\n28021,\n28022,\n28025,\n28026,\n28027,\n28029,\n28030,\n28031,\n28032,\n28033,\n28035,\n28036,\n28038,\n28039,\n28042,\n28043,\n28045,\n28047,\n28048,\n28050,\n28054,\n28055,\n28056,\n28057,\n28058,\n28060,\n28066,\n28069,\n28076,\n28077,\n28080,\n28081,\n28083,\n28084,\n28086,\n28087,\n28089,\n28090,\n28091,\n28092,\n28093,\n28094,\n28097,\n28098,\n28099,\n28104,\n28105,\n28106,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n28109,\n28110,\n28111,\n28112,\n28114,\n28115,\n28116,\n28117,\n28119,\n28122,\n28123,\n28124,\n28127,\n28130,\n28131,\n28133,\n28135,\n28136,\n28137,\n28138,\n28141,\n28143,\n28144,\n28146,\n28148,\n28149,\n28150,\n28152,\n28154,\n28157,\n28158,\n28159,\n28160,\n28161,\n28162,\n28163,\n28164,\n28166,\n28167,\n28168,\n28169,\n28171,\n28175,\n28178,\n28179,\n28181,\n28184,\n28185,\n28187,\n28188,\n28190,\n28191,\n28194,\n28198,\n28199,\n28200,\n28202,\n28204,\n28206,\n28208,\n28209,\n28211,\n28213,\n0,\n28214,\n28215,\n28217,\n28219,\n28220,\n28221,\n28222,\n28223,\n28224,\n28225,\n28226,\n28229,\n28230,\n28231,\n28232,\n28233,\n28234,\n28235,\n28236,\n28239,\n28240,\n28241,\n28242,\n28245,\n28247,\n28249,\n28250,\n28252,\n28253,\n28254,\n28256,\n28257,\n28258,\n28259,\n28260,\n28261,\n28262,\n28263,\n28264,\n28265,\n28266,\n28268,\n28269,\n28271,\n28272,\n28273,\n28274,\n28275,\n28276,\n28277,\n28278,\n28279,\n28280,\n28281,\n28282,\n28283,\n28284,\n28285,\n28288,\n28289,\n28290,\n28292,\n28295,\n28296,\n28298,\n28299,\n28300,\n28301,\n28302,\n28305,\n28306,\n28307,\n28308,\n28309,\n28310,\n28311,\n28313,\n28314,\n28315,\n28317,\n28318,\n28320,\n28321,\n28323,\n28324,\n28326,\n28328,\n28329,\n28331,\n28332,\n28333,\n28334,\n28336,\n28339,\n28341,\n28344,\n28345,\n28348,\n28350,\n28351,\n28352,\n28355,\n28356,\n28357,\n28358,\n28360,\n28361,\n28362,\n28364,\n28365,\n28366,\n28368,\n28370,\n28374,\n28376,\n28377,\n28379,\n28380,\n28381,\n28387,\n28391,\n28394,\n28395,\n28396,\n28397,\n28398,\n28399,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n28400,\n28401,\n28402,\n28403,\n28405,\n28406,\n28407,\n28408,\n28410,\n28411,\n28412,\n28413,\n28414,\n28415,\n28416,\n28417,\n28419,\n28420,\n28421,\n28423,\n28424,\n28426,\n28427,\n28428,\n28429,\n28430,\n28432,\n28433,\n28434,\n28438,\n28439,\n28440,\n28441,\n28442,\n28443,\n28444,\n28445,\n28446,\n28447,\n28449,\n28450,\n28451,\n28453,\n28454,\n28455,\n28456,\n28460,\n28462,\n28464,\n28466,\n28468,\n28469,\n28471,\n28472,\n28473,\n28474,\n28475,\n28476,\n28477,\n28479,\n28480,\n28481,\n28482,\n0,\n28483,\n28484,\n28485,\n28488,\n28489,\n28490,\n28492,\n28494,\n28495,\n28496,\n28497,\n28498,\n28499,\n28500,\n28501,\n28502,\n28503,\n28505,\n28506,\n28507,\n28509,\n28511,\n28512,\n28513,\n28515,\n28516,\n28517,\n28519,\n28520,\n28521,\n28522,\n28523,\n28524,\n28527,\n28528,\n28529,\n28531,\n28533,\n28534,\n28535,\n28537,\n28539,\n28541,\n28542,\n28543,\n28544,\n28545,\n28546,\n28547,\n28549,\n28550,\n28551,\n28554,\n28555,\n28559,\n28560,\n28561,\n28562,\n28563,\n28564,\n28565,\n28566,\n28567,\n28568,\n28569,\n28570,\n28571,\n28573,\n28574,\n28575,\n28576,\n28578,\n28579,\n28580,\n28581,\n28582,\n28584,\n28585,\n28586,\n28587,\n28588,\n28589,\n28590,\n28591,\n28592,\n28593,\n28594,\n28596,\n28597,\n28599,\n28600,\n28602,\n28603,\n28604,\n28605,\n28606,\n28607,\n28609,\n28611,\n28612,\n28613,\n28614,\n28615,\n28616,\n28618,\n28619,\n28620,\n28621,\n28622,\n28623,\n28624,\n28627,\n28628,\n28629,\n28630,\n28631,\n28632,\n28633,\n28634,\n28635,\n28636,\n28637,\n28639,\n28642,\n28643,\n28644,\n28645,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n28646,\n28647,\n28648,\n28649,\n28650,\n28651,\n28652,\n28653,\n28656,\n28657,\n28658,\n28659,\n28660,\n28661,\n28662,\n28663,\n28664,\n28665,\n28666,\n28667,\n28668,\n28669,\n28670,\n28671,\n28672,\n28673,\n28674,\n28675,\n28676,\n28677,\n28678,\n28679,\n28680,\n28681,\n28682,\n28683,\n28684,\n28685,\n28686,\n28687,\n28688,\n28690,\n28691,\n28692,\n28693,\n28694,\n28695,\n28696,\n28697,\n28700,\n28701,\n28702,\n28703,\n28704,\n28705,\n28706,\n28708,\n28709,\n28710,\n28711,\n28712,\n28713,\n28714,\n0,\n28715,\n28716,\n28717,\n28718,\n28719,\n28720,\n28721,\n28722,\n28723,\n28724,\n28726,\n28727,\n28728,\n28730,\n28731,\n28732,\n28733,\n28734,\n28735,\n28736,\n28737,\n28738,\n28739,\n28740,\n28741,\n28742,\n28743,\n28744,\n28745,\n28746,\n28747,\n28749,\n28750,\n28752,\n28753,\n28754,\n28755,\n28756,\n28757,\n28758,\n28759,\n28760,\n28761,\n28762,\n28763,\n28764,\n28765,\n28767,\n28768,\n28769,\n28770,\n28771,\n28772,\n28773,\n28774,\n28775,\n28776,\n28777,\n28778,\n28782,\n28785,\n28786,\n28787,\n28788,\n28791,\n28793,\n28794,\n28795,\n28797,\n28801,\n28802,\n28803,\n28804,\n28806,\n28807,\n28808,\n28811,\n28812,\n28813,\n28815,\n28816,\n28817,\n28819,\n28823,\n28824,\n28826,\n28827,\n28830,\n28831,\n28832,\n28833,\n28834,\n28835,\n28836,\n28837,\n28838,\n28839,\n28840,\n28841,\n28842,\n28848,\n28850,\n28852,\n28853,\n28854,\n28858,\n28862,\n28863,\n28868,\n28869,\n28870,\n28871,\n28873,\n28875,\n28876,\n28877,\n28878,\n28879,\n28880,\n28881,\n28882,\n28883,\n28884,\n28885,\n28886,\n28887,\n28890,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n28892,\n28893,\n28894,\n28896,\n28897,\n28898,\n28899,\n28901,\n28906,\n28910,\n28912,\n28913,\n28914,\n28915,\n28916,\n28917,\n28918,\n28920,\n28922,\n28923,\n28924,\n28926,\n28927,\n28928,\n28929,\n28930,\n28931,\n28932,\n28933,\n28934,\n28935,\n28936,\n28939,\n28940,\n28941,\n28942,\n28943,\n28945,\n28946,\n28948,\n28951,\n28955,\n28956,\n28957,\n28958,\n28959,\n28960,\n28961,\n28962,\n28963,\n28964,\n28965,\n28967,\n28968,\n28969,\n28970,\n28971,\n28972,\n28973,\n28974,\n28978,\n28979,\n28980,\n0,\n28981,\n28983,\n28984,\n28985,\n28986,\n28987,\n28988,\n28989,\n28990,\n28991,\n28992,\n28993,\n28994,\n28995,\n28996,\n28998,\n28999,\n29000,\n29001,\n29003,\n29005,\n29007,\n29008,\n29009,\n29010,\n29011,\n29012,\n29013,\n29014,\n29015,\n29016,\n29017,\n29018,\n29019,\n29021,\n29023,\n29024,\n29025,\n29026,\n29027,\n29029,\n29033,\n29034,\n29035,\n29036,\n29037,\n29039,\n29040,\n29041,\n29044,\n29045,\n29046,\n29047,\n29049,\n29051,\n29052,\n29054,\n29055,\n29056,\n29057,\n29058,\n29059,\n29061,\n29062,\n29063,\n29064,\n29065,\n29067,\n29068,\n29069,\n29070,\n29072,\n29073,\n29074,\n29075,\n29077,\n29078,\n29079,\n29082,\n29083,\n29084,\n29085,\n29086,\n29089,\n29090,\n29091,\n29092,\n29093,\n29094,\n29095,\n29097,\n29098,\n29099,\n29101,\n29102,\n29103,\n29104,\n29105,\n29106,\n29108,\n29110,\n29111,\n29112,\n29114,\n29115,\n29116,\n29117,\n29118,\n29119,\n29120,\n29121,\n29122,\n29124,\n29125,\n29126,\n29127,\n29128,\n29129,\n29130,\n29131,\n29132,\n29133,\n29135,\n29136,\n29137,\n29138,\n29139,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29142,\n29143,\n29144,\n29145,\n29146,\n29147,\n29148,\n29149,\n29150,\n29151,\n29153,\n29154,\n29155,\n29156,\n29158,\n29160,\n29161,\n29162,\n29163,\n29164,\n29165,\n29167,\n29168,\n29169,\n29170,\n29171,\n29172,\n29173,\n29174,\n29175,\n29176,\n29178,\n29179,\n29180,\n29181,\n29182,\n29183,\n29184,\n29185,\n29186,\n29187,\n29188,\n29189,\n29191,\n29192,\n29193,\n29194,\n29195,\n29196,\n29197,\n29198,\n29199,\n29200,\n29201,\n29202,\n29203,\n29204,\n29205,\n29206,\n29207,\n29208,\n29209,\n29210,\n0,\n29211,\n29212,\n29214,\n29215,\n29216,\n29217,\n29218,\n29219,\n29220,\n29221,\n29222,\n29223,\n29225,\n29227,\n29229,\n29230,\n29231,\n29234,\n29235,\n29236,\n29242,\n29244,\n29246,\n29248,\n29249,\n29250,\n29251,\n29252,\n29253,\n29254,\n29257,\n29258,\n29259,\n29262,\n29263,\n29264,\n29265,\n29267,\n29268,\n29269,\n29271,\n29272,\n29274,\n29276,\n29278,\n29280,\n29283,\n29284,\n29285,\n29288,\n29290,\n29291,\n29292,\n29293,\n29296,\n29297,\n29299,\n29300,\n29302,\n29303,\n29304,\n29307,\n29308,\n29309,\n29314,\n29315,\n29317,\n29318,\n29319,\n29320,\n29321,\n29324,\n29326,\n29328,\n29329,\n29331,\n29332,\n29333,\n29334,\n29335,\n29336,\n29337,\n29338,\n29339,\n29340,\n29341,\n29342,\n29344,\n29345,\n29346,\n29347,\n29348,\n29349,\n29350,\n29351,\n29352,\n29353,\n29354,\n29355,\n29358,\n29361,\n29362,\n29363,\n29365,\n29370,\n29371,\n29372,\n29373,\n29374,\n29375,\n29376,\n29381,\n29382,\n29383,\n29385,\n29386,\n29387,\n29388,\n29391,\n29393,\n29395,\n29396,\n29397,\n29398,\n29400,\n29402,\n29403,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n12288,\n12289,\n12290,\n183,\n713,\n711,\n168,\n12291,\n12293,\n8212,\n65374,\n8214,\n8230,\n8216,\n8217,\n8220,\n8221,\n12308,\n12309,\n12296,\n12297,\n12298,\n12299,\n12300,\n12301,\n12302,\n12303,\n12310,\n12311,\n12304,\n12305,\n177,\n215,\n247,\n8758,\n8743,\n8744,\n8721,\n8719,\n8746,\n8745,\n8712,\n8759,\n8730,\n8869,\n8741,\n8736,\n8978,\n8857,\n8747,\n8750,\n8801,\n8780,\n8776,\n8765,\n8733,\n8800,\n8814,\n8815,\n8804,\n8805,\n8734,\n8757,\n8756,\n9794,\n9792,\n176,\n8242,\n8243,\n8451,\n65284,\n164,\n65504,\n65505,\n8240,\n167,\n8470,\n9734,\n9733,\n9675,\n9679,\n9678,\n9671,\n9670,\n9633,\n9632,\n9651,\n9650,\n8251,\n8594,\n8592,\n8593,\n8595,\n12307,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n8560,\n8561,\n8562,\n8563,\n8564,\n8565,\n8566,\n8567,\n8568,\n8569,\n0,\n0,\n0,\n0,\n0,\n0,\n9352,\n9353,\n9354,\n9355,\n9356,\n9357,\n9358,\n9359,\n9360,\n9361,\n9362,\n9363,\n9364,\n9365,\n9366,\n9367,\n9368,\n9369,\n9370,\n9371,\n9332,\n9333,\n9334,\n9335,\n9336,\n9337,\n9338,\n9339,\n9340,\n9341,\n9342,\n9343,\n9344,\n9345,\n9346,\n9347,\n9348,\n9349,\n9350,\n9351,\n9312,\n9313,\n9314,\n9315,\n9316,\n9317,\n9318,\n9319,\n9320,\n9321,\n0,\n0,\n12832,\n12833,\n12834,\n12835,\n12836,\n12837,\n12838,\n12839,\n12840,\n12841,\n0,\n0,\n8544,\n8545,\n8546,\n8547,\n8548,\n8549,\n8550,\n8551,\n8552,\n8553,\n8554,\n8555,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n65281,\n65282,\n65283,\n65509,\n65285,\n65286,\n65287,\n65288,\n65289,\n65290,\n65291,\n65292,\n65293,\n65294,\n65295,\n65296,\n65297,\n65298,\n65299,\n65300,\n65301,\n65302,\n65303,\n65304,\n65305,\n65306,\n65307,\n65308,\n65309,\n65310,\n65311,\n65312,\n65313,\n65314,\n65315,\n65316,\n65317,\n65318,\n65319,\n65320,\n65321,\n65322,\n65323,\n65324,\n65325,\n65326,\n65327,\n65328,\n65329,\n65330,\n65331,\n65332,\n65333,\n65334,\n65335,\n65336,\n65337,\n65338,\n65339,\n65340,\n65341,\n65342,\n65343,\n65344,\n65345,\n65346,\n65347,\n65348,\n65349,\n65350,\n65351,\n65352,\n65353,\n65354,\n65355,\n65356,\n65357,\n65358,\n65359,\n65360,\n65361,\n65362,\n65363,\n65364,\n65365,\n65366,\n65367,\n65368,\n65369,\n65370,\n65371,\n65372,\n65373,\n65507,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n12353,\n12354,\n12355,\n12356,\n12357,\n12358,\n12359,\n12360,\n12361,\n12362,\n12363,\n12364,\n12365,\n12366,\n12367,\n12368,\n12369,\n12370,\n12371,\n12372,\n12373,\n12374,\n12375,\n12376,\n12377,\n12378,\n12379,\n12380,\n12381,\n12382,\n12383,\n12384,\n12385,\n12386,\n12387,\n12388,\n12389,\n12390,\n12391,\n12392,\n12393,\n12394,\n12395,\n12396,\n12397,\n12398,\n12399,\n12400,\n12401,\n12402,\n12403,\n12404,\n12405,\n12406,\n12407,\n12408,\n12409,\n12410,\n12411,\n12412,\n12413,\n12414,\n12415,\n12416,\n12417,\n12418,\n12419,\n12420,\n12421,\n12422,\n12423,\n12424,\n12425,\n12426,\n12427,\n12428,\n12429,\n12430,\n12431,\n12432,\n12433,\n12434,\n12435,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n12449,\n12450,\n12451,\n12452,\n12453,\n12454,\n12455,\n12456,\n12457,\n12458,\n12459,\n12460,\n12461,\n12462,\n12463,\n12464,\n12465,\n12466,\n12467,\n12468,\n12469,\n12470,\n12471,\n12472,\n12473,\n12474,\n12475,\n12476,\n12477,\n12478,\n12479,\n12480,\n12481,\n12482,\n12483,\n12484,\n12485,\n12486,\n12487,\n12488,\n12489,\n12490,\n12491,\n12492,\n12493,\n12494,\n12495,\n12496,\n12497,\n12498,\n12499,\n12500,\n12501,\n12502,\n12503,\n12504,\n12505,\n12506,\n12507,\n12508,\n12509,\n12510,\n12511,\n12512,\n12513,\n12514,\n12515,\n12516,\n12517,\n12518,\n12519,\n12520,\n12521,\n12522,\n12523,\n12524,\n12525,\n12526,\n12527,\n12528,\n12529,\n12530,\n12531,\n12532,\n12533,\n12534,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n913,\n914,\n915,\n916,\n917,\n918,\n919,\n920,\n921,\n922,\n923,\n924,\n925,\n926,\n927,\n928,\n929,\n931,\n932,\n933,\n934,\n935,\n936,\n937,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n945,\n946,\n947,\n948,\n949,\n950,\n951,\n952,\n953,\n954,\n955,\n956,\n957,\n958,\n959,\n960,\n961,\n963,\n964,\n965,\n966,\n967,\n968,\n969,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n65077,\n65078,\n65081,\n65082,\n65087,\n65088,\n65085,\n65086,\n65089,\n65090,\n65091,\n65092,\n0,\n0,\n65083,\n65084,\n65079,\n65080,\n65073,\n0,\n65075,\n65076,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1040,\n1041,\n1042,\n1043,\n1044,\n1045,\n1025,\n1046,\n1047,\n1048,\n1049,\n1050,\n1051,\n1052,\n1053,\n1054,\n1055,\n1056,\n1057,\n1058,\n1059,\n1060,\n1061,\n1062,\n1063,\n1064,\n1065,\n1066,\n1067,\n1068,\n1069,\n1070,\n1071,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1072,\n1073,\n1074,\n1075,\n1076,\n1077,\n1105,\n1078,\n1079,\n1080,\n1081,\n1082,\n1083,\n1084,\n1085,\n1086,\n1087,\n1088,\n1089,\n1090,\n1091,\n1092,\n1093,\n1094,\n1095,\n1096,\n1097,\n1098,\n1099,\n1100,\n1101,\n1102,\n1103,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n714,\n715,\n729,\n8211,\n8213,\n8229,\n8245,\n8453,\n8457,\n8598,\n8599,\n8600,\n8601,\n8725,\n8735,\n8739,\n8786,\n8806,\n8807,\n8895,\n9552,\n9553,\n9554,\n9555,\n9556,\n9557,\n9558,\n9559,\n9560,\n9561,\n9562,\n9563,\n9564,\n9565,\n9566,\n9567,\n9568,\n9569,\n9570,\n9571,\n9572,\n9573,\n9574,\n9575,\n9576,\n9577,\n9578,\n9579,\n9580,\n9581,\n9582,\n9583,\n9584,\n9585,\n9586,\n9587,\n9601,\n9602,\n9603,\n9604,\n9605,\n9606,\n9607,\n0,\n9608,\n9609,\n9610,\n9611,\n9612,\n9613,\n9614,\n9615,\n9619,\n9620,\n9621,\n9660,\n9661,\n9698,\n9699,\n9700,\n9701,\n9737,\n8853,\n12306,\n12317,\n12318,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n257,\n225,\n462,\n224,\n275,\n233,\n283,\n232,\n299,\n237,\n464,\n236,\n333,\n243,\n466,\n242,\n363,\n250,\n468,\n249,\n470,\n472,\n474,\n476,\n252,\n234,\n593,\n0,\n324,\n328,\n0,\n609,\n0,\n0,\n0,\n0,\n12549,\n12550,\n12551,\n12552,\n12553,\n12554,\n12555,\n12556,\n12557,\n12558,\n12559,\n12560,\n12561,\n12562,\n12563,\n12564,\n12565,\n12566,\n12567,\n12568,\n12569,\n12570,\n12571,\n12572,\n12573,\n12574,\n12575,\n12576,\n12577,\n12578,\n12579,\n12580,\n12581,\n12582,\n12583,\n12584,\n12585,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n12321,\n12322,\n12323,\n12324,\n12325,\n12326,\n12327,\n12328,\n12329,\n12963,\n13198,\n13199,\n13212,\n13213,\n13214,\n13217,\n13252,\n13262,\n13265,\n13266,\n13269,\n65072,\n65506,\n65508,\n0,\n8481,\n12849,\n0,\n8208,\n0,\n0,\n0,\n12540,\n12443,\n12444,\n12541,\n12542,\n12294,\n12445,\n12446,\n65097,\n65098,\n65099,\n65100,\n65101,\n65102,\n65103,\n65104,\n65105,\n65106,\n65108,\n65109,\n65110,\n65111,\n65113,\n65114,\n65115,\n65116,\n65117,\n65118,\n65119,\n65120,\n65121,\n0,\n65122,\n65123,\n65124,\n65125,\n65126,\n65128,\n65129,\n65130,\n65131,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n12295,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n9472,\n9473,\n9474,\n9475,\n9476,\n9477,\n9478,\n9479,\n9480,\n9481,\n9482,\n9483,\n9484,\n9485,\n9486,\n9487,\n9488,\n9489,\n9490,\n9491,\n9492,\n9493,\n9494,\n9495,\n9496,\n9497,\n9498,\n9499,\n9500,\n9501,\n9502,\n9503,\n9504,\n9505,\n9506,\n9507,\n9508,\n9509,\n9510,\n9511,\n9512,\n9513,\n9514,\n9515,\n9516,\n9517,\n9518,\n9519,\n9520,\n9521,\n9522,\n9523,\n9524,\n9525,\n9526,\n9527,\n9528,\n9529,\n9530,\n9531,\n9532,\n9533,\n9534,\n9535,\n9536,\n9537,\n9538,\n9539,\n9540,\n9541,\n9542,\n9543,\n9544,\n9545,\n9546,\n9547,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29404,\n29405,\n29407,\n29410,\n29411,\n29412,\n29413,\n29414,\n29415,\n29418,\n29419,\n29429,\n29430,\n29433,\n29437,\n29438,\n29439,\n29440,\n29442,\n29444,\n29445,\n29446,\n29447,\n29448,\n29449,\n29451,\n29452,\n29453,\n29455,\n29456,\n29457,\n29458,\n29460,\n29464,\n29465,\n29466,\n29471,\n29472,\n29475,\n29476,\n29478,\n29479,\n29480,\n29485,\n29487,\n29488,\n29490,\n29491,\n29493,\n29494,\n29498,\n29499,\n29500,\n29501,\n29504,\n29505,\n29506,\n29507,\n29508,\n29509,\n29510,\n29511,\n29512,\n0,\n29513,\n29514,\n29515,\n29516,\n29518,\n29519,\n29521,\n29523,\n29524,\n29525,\n29526,\n29528,\n29529,\n29530,\n29531,\n29532,\n29533,\n29534,\n29535,\n29537,\n29538,\n29539,\n29540,\n29541,\n29542,\n29543,\n29544,\n29545,\n29546,\n29547,\n29550,\n29552,\n29553,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29554,\n29555,\n29556,\n29557,\n29558,\n29559,\n29560,\n29561,\n29562,\n29563,\n29564,\n29565,\n29567,\n29568,\n29569,\n29570,\n29571,\n29573,\n29574,\n29576,\n29578,\n29580,\n29581,\n29583,\n29584,\n29586,\n29587,\n29588,\n29589,\n29591,\n29592,\n29593,\n29594,\n29596,\n29597,\n29598,\n29600,\n29601,\n29603,\n29604,\n29605,\n29606,\n29607,\n29608,\n29610,\n29612,\n29613,\n29617,\n29620,\n29621,\n29622,\n29624,\n29625,\n29628,\n29629,\n29630,\n29631,\n29633,\n29635,\n29636,\n29637,\n29638,\n29639,\n0,\n29643,\n29644,\n29646,\n29650,\n29651,\n29652,\n29653,\n29654,\n29655,\n29656,\n29658,\n29659,\n29660,\n29661,\n29663,\n29665,\n29666,\n29667,\n29668,\n29670,\n29672,\n29674,\n29675,\n29676,\n29678,\n29679,\n29680,\n29681,\n29683,\n29684,\n29685,\n29686,\n29687,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29688,\n29689,\n29690,\n29691,\n29692,\n29693,\n29694,\n29695,\n29696,\n29697,\n29698,\n29700,\n29703,\n29704,\n29707,\n29708,\n29709,\n29710,\n29713,\n29714,\n29715,\n29716,\n29717,\n29718,\n29719,\n29720,\n29721,\n29724,\n29725,\n29726,\n29727,\n29728,\n29729,\n29731,\n29732,\n29735,\n29737,\n29739,\n29741,\n29743,\n29745,\n29746,\n29751,\n29752,\n29753,\n29754,\n29755,\n29757,\n29758,\n29759,\n29760,\n29762,\n29763,\n29764,\n29765,\n29766,\n29767,\n29768,\n29769,\n29770,\n29771,\n29772,\n29773,\n0,\n29774,\n29775,\n29776,\n29777,\n29778,\n29779,\n29780,\n29782,\n29784,\n29789,\n29792,\n29793,\n29794,\n29795,\n29796,\n29797,\n29798,\n29799,\n29800,\n29801,\n29802,\n29803,\n29804,\n29806,\n29807,\n29809,\n29810,\n29811,\n29812,\n29813,\n29816,\n29817,\n29818,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29819,\n29820,\n29821,\n29823,\n29826,\n29828,\n29829,\n29830,\n29832,\n29833,\n29834,\n29836,\n29837,\n29839,\n29841,\n29842,\n29843,\n29844,\n29845,\n29846,\n29847,\n29848,\n29849,\n29850,\n29851,\n29853,\n29855,\n29856,\n29857,\n29858,\n29859,\n29860,\n29861,\n29862,\n29866,\n29867,\n29868,\n29869,\n29870,\n29871,\n29872,\n29873,\n29874,\n29875,\n29876,\n29877,\n29878,\n29879,\n29880,\n29881,\n29883,\n29884,\n29885,\n29886,\n29887,\n29888,\n29889,\n29890,\n29891,\n29892,\n29893,\n29894,\n29895,\n0,\n29896,\n29897,\n29898,\n29899,\n29900,\n29901,\n29902,\n29903,\n29904,\n29905,\n29907,\n29908,\n29909,\n29910,\n29911,\n29912,\n29913,\n29914,\n29915,\n29917,\n29919,\n29921,\n29925,\n29927,\n29928,\n29929,\n29930,\n29931,\n29932,\n29933,\n29936,\n29937,\n29938,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n29939,\n29941,\n29944,\n29945,\n29946,\n29947,\n29948,\n29949,\n29950,\n29952,\n29953,\n29954,\n29955,\n29957,\n29958,\n29959,\n29960,\n29961,\n29962,\n29963,\n29964,\n29966,\n29968,\n29970,\n29972,\n29973,\n29974,\n29975,\n29979,\n29981,\n29982,\n29984,\n29985,\n29986,\n29987,\n29988,\n29990,\n29991,\n29994,\n29998,\n30004,\n30006,\n30009,\n30012,\n30013,\n30015,\n30017,\n30018,\n30019,\n30020,\n30022,\n30023,\n30025,\n30026,\n30029,\n30032,\n30033,\n30034,\n30035,\n30037,\n30038,\n30039,\n30040,\n0,\n30045,\n30046,\n30047,\n30048,\n30049,\n30050,\n30051,\n30052,\n30055,\n30056,\n30057,\n30059,\n30060,\n30061,\n30062,\n30063,\n30064,\n30065,\n30067,\n30069,\n30070,\n30071,\n30074,\n30075,\n30076,\n30077,\n30078,\n30080,\n30081,\n30082,\n30084,\n30085,\n30087,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30088,\n30089,\n30090,\n30092,\n30093,\n30094,\n30096,\n30099,\n30101,\n30104,\n30107,\n30108,\n30110,\n30114,\n30118,\n30119,\n30120,\n30121,\n30122,\n30125,\n30134,\n30135,\n30138,\n30139,\n30143,\n30144,\n30145,\n30150,\n30155,\n30156,\n30158,\n30159,\n30160,\n30161,\n30163,\n30167,\n30169,\n30170,\n30172,\n30173,\n30175,\n30176,\n30177,\n30181,\n30185,\n30188,\n30189,\n30190,\n30191,\n30194,\n30195,\n30197,\n30198,\n30199,\n30200,\n30202,\n30203,\n30205,\n30206,\n30210,\n30212,\n30214,\n30215,\n0,\n30216,\n30217,\n30219,\n30221,\n30222,\n30223,\n30225,\n30226,\n30227,\n30228,\n30230,\n30234,\n30236,\n30237,\n30238,\n30241,\n30243,\n30247,\n30248,\n30252,\n30254,\n30255,\n30257,\n30258,\n30262,\n30263,\n30265,\n30266,\n30267,\n30269,\n30273,\n30274,\n30276,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30277,\n30278,\n30279,\n30280,\n30281,\n30282,\n30283,\n30286,\n30287,\n30288,\n30289,\n30290,\n30291,\n30293,\n30295,\n30296,\n30297,\n30298,\n30299,\n30301,\n30303,\n30304,\n30305,\n30306,\n30308,\n30309,\n30310,\n30311,\n30312,\n30313,\n30314,\n30316,\n30317,\n30318,\n30320,\n30321,\n30322,\n30323,\n30324,\n30325,\n30326,\n30327,\n30329,\n30330,\n30332,\n30335,\n30336,\n30337,\n30339,\n30341,\n30345,\n30346,\n30348,\n30349,\n30351,\n30352,\n30354,\n30356,\n30357,\n30359,\n30360,\n30362,\n30363,\n0,\n30364,\n30365,\n30366,\n30367,\n30368,\n30369,\n30370,\n30371,\n30373,\n30374,\n30375,\n30376,\n30377,\n30378,\n30379,\n30380,\n30381,\n30383,\n30384,\n30387,\n30389,\n30390,\n30391,\n30392,\n30393,\n30394,\n30395,\n30396,\n30397,\n30398,\n30400,\n30401,\n30403,\n21834,\n38463,\n22467,\n25384,\n21710,\n21769,\n21696,\n30353,\n30284,\n34108,\n30702,\n33406,\n30861,\n29233,\n38552,\n38797,\n27688,\n23433,\n20474,\n25353,\n26263,\n23736,\n33018,\n26696,\n32942,\n26114,\n30414,\n20985,\n25942,\n29100,\n32753,\n34948,\n20658,\n22885,\n25034,\n28595,\n33453,\n25420,\n25170,\n21485,\n21543,\n31494,\n20843,\n30116,\n24052,\n25300,\n36299,\n38774,\n25226,\n32793,\n22365,\n38712,\n32610,\n29240,\n30333,\n26575,\n30334,\n25670,\n20336,\n36133,\n25308,\n31255,\n26001,\n29677,\n25644,\n25203,\n33324,\n39041,\n26495,\n29256,\n25198,\n25292,\n20276,\n29923,\n21322,\n21150,\n32458,\n37030,\n24110,\n26758,\n27036,\n33152,\n32465,\n26834,\n30917,\n34444,\n38225,\n20621,\n35876,\n33502,\n32990,\n21253,\n35090,\n21093,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30404,\n30407,\n30409,\n30411,\n30412,\n30419,\n30421,\n30425,\n30426,\n30428,\n30429,\n30430,\n30432,\n30433,\n30434,\n30435,\n30436,\n30438,\n30439,\n30440,\n30441,\n30442,\n30443,\n30444,\n30445,\n30448,\n30451,\n30453,\n30454,\n30455,\n30458,\n30459,\n30461,\n30463,\n30464,\n30466,\n30467,\n30469,\n30470,\n30474,\n30476,\n30478,\n30479,\n30480,\n30481,\n30482,\n30483,\n30484,\n30485,\n30486,\n30487,\n30488,\n30491,\n30492,\n30493,\n30494,\n30497,\n30499,\n30500,\n30501,\n30503,\n30506,\n30507,\n0,\n30508,\n30510,\n30512,\n30513,\n30514,\n30515,\n30516,\n30521,\n30523,\n30525,\n30526,\n30527,\n30530,\n30532,\n30533,\n30534,\n30536,\n30537,\n30538,\n30539,\n30540,\n30541,\n30542,\n30543,\n30546,\n30547,\n30548,\n30549,\n30550,\n30551,\n30552,\n30553,\n30556,\n34180,\n38649,\n20445,\n22561,\n39281,\n23453,\n25265,\n25253,\n26292,\n35961,\n40077,\n29190,\n26479,\n30865,\n24754,\n21329,\n21271,\n36744,\n32972,\n36125,\n38049,\n20493,\n29384,\n22791,\n24811,\n28953,\n34987,\n22868,\n33519,\n26412,\n31528,\n23849,\n32503,\n29997,\n27893,\n36454,\n36856,\n36924,\n40763,\n27604,\n37145,\n31508,\n24444,\n30887,\n34006,\n34109,\n27605,\n27609,\n27606,\n24065,\n24199,\n30201,\n38381,\n25949,\n24330,\n24517,\n36767,\n22721,\n33218,\n36991,\n38491,\n38829,\n36793,\n32534,\n36140,\n25153,\n20415,\n21464,\n21342,\n36776,\n36777,\n36779,\n36941,\n26631,\n24426,\n33176,\n34920,\n40150,\n24971,\n21035,\n30250,\n24428,\n25996,\n28626,\n28392,\n23486,\n25672,\n20853,\n20912,\n26564,\n19993,\n31177,\n39292,\n28851,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30557,\n30558,\n30559,\n30560,\n30564,\n30567,\n30569,\n30570,\n30573,\n30574,\n30575,\n30576,\n30577,\n30578,\n30579,\n30580,\n30581,\n30582,\n30583,\n30584,\n30586,\n30587,\n30588,\n30593,\n30594,\n30595,\n30598,\n30599,\n30600,\n30601,\n30602,\n30603,\n30607,\n30608,\n30611,\n30612,\n30613,\n30614,\n30615,\n30616,\n30617,\n30618,\n30619,\n30620,\n30621,\n30622,\n30625,\n30627,\n30628,\n30630,\n30632,\n30635,\n30637,\n30638,\n30639,\n30641,\n30642,\n30644,\n30646,\n30647,\n30648,\n30649,\n30650,\n0,\n30652,\n30654,\n30656,\n30657,\n30658,\n30659,\n30660,\n30661,\n30662,\n30663,\n30664,\n30665,\n30666,\n30667,\n30668,\n30670,\n30671,\n30672,\n30673,\n30674,\n30675,\n30676,\n30677,\n30678,\n30680,\n30681,\n30682,\n30685,\n30686,\n30687,\n30688,\n30689,\n30692,\n30149,\n24182,\n29627,\n33760,\n25773,\n25320,\n38069,\n27874,\n21338,\n21187,\n25615,\n38082,\n31636,\n20271,\n24091,\n33334,\n33046,\n33162,\n28196,\n27850,\n39539,\n25429,\n21340,\n21754,\n34917,\n22496,\n19981,\n24067,\n27493,\n31807,\n37096,\n24598,\n25830,\n29468,\n35009,\n26448,\n25165,\n36130,\n30572,\n36393,\n37319,\n24425,\n33756,\n34081,\n39184,\n21442,\n34453,\n27531,\n24813,\n24808,\n28799,\n33485,\n33329,\n20179,\n27815,\n34255,\n25805,\n31961,\n27133,\n26361,\n33609,\n21397,\n31574,\n20391,\n20876,\n27979,\n23618,\n36461,\n25554,\n21449,\n33580,\n33590,\n26597,\n30900,\n25661,\n23519,\n23700,\n24046,\n35815,\n25286,\n26612,\n35962,\n25600,\n25530,\n34633,\n39307,\n35863,\n32544,\n38130,\n20135,\n38416,\n39076,\n26124,\n29462,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30694,\n30696,\n30698,\n30703,\n30704,\n30705,\n30706,\n30708,\n30709,\n30711,\n30713,\n30714,\n30715,\n30716,\n30723,\n30724,\n30725,\n30726,\n30727,\n30728,\n30730,\n30731,\n30734,\n30735,\n30736,\n30739,\n30741,\n30745,\n30747,\n30750,\n30752,\n30753,\n30754,\n30756,\n30760,\n30762,\n30763,\n30766,\n30767,\n30769,\n30770,\n30771,\n30773,\n30774,\n30781,\n30783,\n30785,\n30786,\n30787,\n30788,\n30790,\n30792,\n30793,\n30794,\n30795,\n30797,\n30799,\n30801,\n30803,\n30804,\n30808,\n30809,\n30810,\n0,\n30811,\n30812,\n30814,\n30815,\n30816,\n30817,\n30818,\n30819,\n30820,\n30821,\n30822,\n30823,\n30824,\n30825,\n30831,\n30832,\n30833,\n30834,\n30835,\n30836,\n30837,\n30838,\n30840,\n30841,\n30842,\n30843,\n30845,\n30846,\n30847,\n30848,\n30849,\n30850,\n30851,\n22330,\n23581,\n24120,\n38271,\n20607,\n32928,\n21378,\n25950,\n30021,\n21809,\n20513,\n36229,\n25220,\n38046,\n26397,\n22066,\n28526,\n24034,\n21557,\n28818,\n36710,\n25199,\n25764,\n25507,\n24443,\n28552,\n37108,\n33251,\n36784,\n23576,\n26216,\n24561,\n27785,\n38472,\n36225,\n34924,\n25745,\n31216,\n22478,\n27225,\n25104,\n21576,\n20056,\n31243,\n24809,\n28548,\n35802,\n25215,\n36894,\n39563,\n31204,\n21507,\n30196,\n25345,\n21273,\n27744,\n36831,\n24347,\n39536,\n32827,\n40831,\n20360,\n23610,\n36196,\n32709,\n26021,\n28861,\n20805,\n20914,\n34411,\n23815,\n23456,\n25277,\n37228,\n30068,\n36364,\n31264,\n24833,\n31609,\n20167,\n32504,\n30597,\n19985,\n33261,\n21021,\n20986,\n27249,\n21416,\n36487,\n38148,\n38607,\n28353,\n38500,\n26970,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30852,\n30853,\n30854,\n30856,\n30858,\n30859,\n30863,\n30864,\n30866,\n30868,\n30869,\n30870,\n30873,\n30877,\n30878,\n30880,\n30882,\n30884,\n30886,\n30888,\n30889,\n30890,\n30891,\n30892,\n30893,\n30894,\n30895,\n30901,\n30902,\n30903,\n30904,\n30906,\n30907,\n30908,\n30909,\n30911,\n30912,\n30914,\n30915,\n30916,\n30918,\n30919,\n30920,\n30924,\n30925,\n30926,\n30927,\n30929,\n30930,\n30931,\n30934,\n30935,\n30936,\n30938,\n30939,\n30940,\n30941,\n30942,\n30943,\n30944,\n30945,\n30946,\n30947,\n0,\n30948,\n30949,\n30950,\n30951,\n30953,\n30954,\n30955,\n30957,\n30958,\n30959,\n30960,\n30961,\n30963,\n30965,\n30966,\n30968,\n30969,\n30971,\n30972,\n30973,\n30974,\n30975,\n30976,\n30978,\n30979,\n30980,\n30982,\n30983,\n30984,\n30985,\n30986,\n30987,\n30988,\n30784,\n20648,\n30679,\n25616,\n35302,\n22788,\n25571,\n24029,\n31359,\n26941,\n20256,\n33337,\n21912,\n20018,\n30126,\n31383,\n24162,\n24202,\n38383,\n21019,\n21561,\n28810,\n25462,\n38180,\n22402,\n26149,\n26943,\n37255,\n21767,\n28147,\n32431,\n34850,\n25139,\n32496,\n30133,\n33576,\n30913,\n38604,\n36766,\n24904,\n29943,\n35789,\n27492,\n21050,\n36176,\n27425,\n32874,\n33905,\n22257,\n21254,\n20174,\n19995,\n20945,\n31895,\n37259,\n31751,\n20419,\n36479,\n31713,\n31388,\n25703,\n23828,\n20652,\n33030,\n30209,\n31929,\n28140,\n32736,\n26449,\n23384,\n23544,\n30923,\n25774,\n25619,\n25514,\n25387,\n38169,\n25645,\n36798,\n31572,\n30249,\n25171,\n22823,\n21574,\n27513,\n20643,\n25140,\n24102,\n27526,\n20195,\n36151,\n34955,\n24453,\n36910,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n30989,\n30990,\n30991,\n30992,\n30993,\n30994,\n30996,\n30997,\n30998,\n30999,\n31000,\n31001,\n31002,\n31003,\n31004,\n31005,\n31007,\n31008,\n31009,\n31010,\n31011,\n31013,\n31014,\n31015,\n31016,\n31017,\n31018,\n31019,\n31020,\n31021,\n31022,\n31023,\n31024,\n31025,\n31026,\n31027,\n31029,\n31030,\n31031,\n31032,\n31033,\n31037,\n31039,\n31042,\n31043,\n31044,\n31045,\n31047,\n31050,\n31051,\n31052,\n31053,\n31054,\n31055,\n31056,\n31057,\n31058,\n31060,\n31061,\n31064,\n31065,\n31073,\n31075,\n0,\n31076,\n31078,\n31081,\n31082,\n31083,\n31084,\n31086,\n31088,\n31089,\n31090,\n31091,\n31092,\n31093,\n31094,\n31097,\n31099,\n31100,\n31101,\n31102,\n31103,\n31106,\n31107,\n31110,\n31111,\n31112,\n31113,\n31115,\n31116,\n31117,\n31118,\n31120,\n31121,\n31122,\n24608,\n32829,\n25285,\n20025,\n21333,\n37112,\n25528,\n32966,\n26086,\n27694,\n20294,\n24814,\n28129,\n35806,\n24377,\n34507,\n24403,\n25377,\n20826,\n33633,\n26723,\n20992,\n25443,\n36424,\n20498,\n23707,\n31095,\n23548,\n21040,\n31291,\n24764,\n36947,\n30423,\n24503,\n24471,\n30340,\n36460,\n28783,\n30331,\n31561,\n30634,\n20979,\n37011,\n22564,\n20302,\n28404,\n36842,\n25932,\n31515,\n29380,\n28068,\n32735,\n23265,\n25269,\n24213,\n22320,\n33922,\n31532,\n24093,\n24351,\n36882,\n32532,\n39072,\n25474,\n28359,\n30872,\n28857,\n20856,\n38747,\n22443,\n30005,\n20291,\n30008,\n24215,\n24806,\n22880,\n28096,\n27583,\n30857,\n21500,\n38613,\n20939,\n20993,\n25481,\n21514,\n38035,\n35843,\n36300,\n29241,\n30879,\n34678,\n36845,\n35853,\n21472,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31123,\n31124,\n31125,\n31126,\n31127,\n31128,\n31129,\n31131,\n31132,\n31133,\n31134,\n31135,\n31136,\n31137,\n31138,\n31139,\n31140,\n31141,\n31142,\n31144,\n31145,\n31146,\n31147,\n31148,\n31149,\n31150,\n31151,\n31152,\n31153,\n31154,\n31156,\n31157,\n31158,\n31159,\n31160,\n31164,\n31167,\n31170,\n31172,\n31173,\n31175,\n31176,\n31178,\n31180,\n31182,\n31183,\n31184,\n31187,\n31188,\n31190,\n31191,\n31193,\n31194,\n31195,\n31196,\n31197,\n31198,\n31200,\n31201,\n31202,\n31205,\n31208,\n31210,\n0,\n31212,\n31214,\n31217,\n31218,\n31219,\n31220,\n31221,\n31222,\n31223,\n31225,\n31226,\n31228,\n31230,\n31231,\n31233,\n31236,\n31237,\n31239,\n31240,\n31241,\n31242,\n31244,\n31247,\n31248,\n31249,\n31250,\n31251,\n31253,\n31254,\n31256,\n31257,\n31259,\n31260,\n19969,\n30447,\n21486,\n38025,\n39030,\n40718,\n38189,\n23450,\n35746,\n20002,\n19996,\n20908,\n33891,\n25026,\n21160,\n26635,\n20375,\n24683,\n20923,\n27934,\n20828,\n25238,\n26007,\n38497,\n35910,\n36887,\n30168,\n37117,\n30563,\n27602,\n29322,\n29420,\n35835,\n22581,\n30585,\n36172,\n26460,\n38208,\n32922,\n24230,\n28193,\n22930,\n31471,\n30701,\n38203,\n27573,\n26029,\n32526,\n22534,\n20817,\n38431,\n23545,\n22697,\n21544,\n36466,\n25958,\n39039,\n22244,\n38045,\n30462,\n36929,\n25479,\n21702,\n22810,\n22842,\n22427,\n36530,\n26421,\n36346,\n33333,\n21057,\n24816,\n22549,\n34558,\n23784,\n40517,\n20420,\n39069,\n35769,\n23077,\n24694,\n21380,\n25212,\n36943,\n37122,\n39295,\n24681,\n32780,\n20799,\n32819,\n23572,\n39285,\n27953,\n20108,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31261,\n31263,\n31265,\n31266,\n31268,\n31269,\n31270,\n31271,\n31272,\n31273,\n31274,\n31275,\n31276,\n31277,\n31278,\n31279,\n31280,\n31281,\n31282,\n31284,\n31285,\n31286,\n31288,\n31290,\n31294,\n31296,\n31297,\n31298,\n31299,\n31300,\n31301,\n31303,\n31304,\n31305,\n31306,\n31307,\n31308,\n31309,\n31310,\n31311,\n31312,\n31314,\n31315,\n31316,\n31317,\n31318,\n31320,\n31321,\n31322,\n31323,\n31324,\n31325,\n31326,\n31327,\n31328,\n31329,\n31330,\n31331,\n31332,\n31333,\n31334,\n31335,\n31336,\n0,\n31337,\n31338,\n31339,\n31340,\n31341,\n31342,\n31343,\n31345,\n31346,\n31347,\n31349,\n31355,\n31356,\n31357,\n31358,\n31362,\n31365,\n31367,\n31369,\n31370,\n31371,\n31372,\n31374,\n31375,\n31376,\n31379,\n31380,\n31385,\n31386,\n31387,\n31390,\n31393,\n31394,\n36144,\n21457,\n32602,\n31567,\n20240,\n20047,\n38400,\n27861,\n29648,\n34281,\n24070,\n30058,\n32763,\n27146,\n30718,\n38034,\n32321,\n20961,\n28902,\n21453,\n36820,\n33539,\n36137,\n29359,\n39277,\n27867,\n22346,\n33459,\n26041,\n32938,\n25151,\n38450,\n22952,\n20223,\n35775,\n32442,\n25918,\n33778,\n38750,\n21857,\n39134,\n32933,\n21290,\n35837,\n21536,\n32954,\n24223,\n27832,\n36153,\n33452,\n37210,\n21545,\n27675,\n20998,\n32439,\n22367,\n28954,\n27774,\n31881,\n22859,\n20221,\n24575,\n24868,\n31914,\n20016,\n23553,\n26539,\n34562,\n23792,\n38155,\n39118,\n30127,\n28925,\n36898,\n20911,\n32541,\n35773,\n22857,\n20964,\n20315,\n21542,\n22827,\n25975,\n32932,\n23413,\n25206,\n25282,\n36752,\n24133,\n27679,\n31526,\n20239,\n20440,\n26381,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31395,\n31396,\n31399,\n31401,\n31402,\n31403,\n31406,\n31407,\n31408,\n31409,\n31410,\n31412,\n31413,\n31414,\n31415,\n31416,\n31417,\n31418,\n31419,\n31420,\n31421,\n31422,\n31424,\n31425,\n31426,\n31427,\n31428,\n31429,\n31430,\n31431,\n31432,\n31433,\n31434,\n31436,\n31437,\n31438,\n31439,\n31440,\n31441,\n31442,\n31443,\n31444,\n31445,\n31447,\n31448,\n31450,\n31451,\n31452,\n31453,\n31457,\n31458,\n31460,\n31463,\n31464,\n31465,\n31466,\n31467,\n31468,\n31470,\n31472,\n31473,\n31474,\n31475,\n0,\n31476,\n31477,\n31478,\n31479,\n31480,\n31483,\n31484,\n31486,\n31488,\n31489,\n31490,\n31493,\n31495,\n31497,\n31500,\n31501,\n31502,\n31504,\n31506,\n31507,\n31510,\n31511,\n31512,\n31514,\n31516,\n31517,\n31519,\n31521,\n31522,\n31523,\n31527,\n31529,\n31533,\n28014,\n28074,\n31119,\n34993,\n24343,\n29995,\n25242,\n36741,\n20463,\n37340,\n26023,\n33071,\n33105,\n24220,\n33104,\n36212,\n21103,\n35206,\n36171,\n22797,\n20613,\n20184,\n38428,\n29238,\n33145,\n36127,\n23500,\n35747,\n38468,\n22919,\n32538,\n21648,\n22134,\n22030,\n35813,\n25913,\n27010,\n38041,\n30422,\n28297,\n24178,\n29976,\n26438,\n26577,\n31487,\n32925,\n36214,\n24863,\n31174,\n25954,\n36195,\n20872,\n21018,\n38050,\n32568,\n32923,\n32434,\n23703,\n28207,\n26464,\n31705,\n30347,\n39640,\n33167,\n32660,\n31957,\n25630,\n38224,\n31295,\n21578,\n21733,\n27468,\n25601,\n25096,\n40509,\n33011,\n30105,\n21106,\n38761,\n33883,\n26684,\n34532,\n38401,\n38548,\n38124,\n20010,\n21508,\n32473,\n26681,\n36319,\n32789,\n26356,\n24218,\n32697,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31535,\n31536,\n31538,\n31540,\n31541,\n31542,\n31543,\n31545,\n31547,\n31549,\n31551,\n31552,\n31553,\n31554,\n31555,\n31556,\n31558,\n31560,\n31562,\n31565,\n31566,\n31571,\n31573,\n31575,\n31577,\n31580,\n31582,\n31583,\n31585,\n31587,\n31588,\n31589,\n31590,\n31591,\n31592,\n31593,\n31594,\n31595,\n31596,\n31597,\n31599,\n31600,\n31603,\n31604,\n31606,\n31608,\n31610,\n31612,\n31613,\n31615,\n31617,\n31618,\n31619,\n31620,\n31622,\n31623,\n31624,\n31625,\n31626,\n31627,\n31628,\n31630,\n31631,\n0,\n31633,\n31634,\n31635,\n31638,\n31640,\n31641,\n31642,\n31643,\n31646,\n31647,\n31648,\n31651,\n31652,\n31653,\n31662,\n31663,\n31664,\n31666,\n31667,\n31669,\n31670,\n31671,\n31673,\n31674,\n31675,\n31676,\n31677,\n31678,\n31679,\n31680,\n31682,\n31683,\n31684,\n22466,\n32831,\n26775,\n24037,\n25915,\n21151,\n24685,\n40858,\n20379,\n36524,\n20844,\n23467,\n24339,\n24041,\n27742,\n25329,\n36129,\n20849,\n38057,\n21246,\n27807,\n33503,\n29399,\n22434,\n26500,\n36141,\n22815,\n36764,\n33735,\n21653,\n31629,\n20272,\n27837,\n23396,\n22993,\n40723,\n21476,\n34506,\n39592,\n35895,\n32929,\n25925,\n39038,\n22266,\n38599,\n21038,\n29916,\n21072,\n23521,\n25346,\n35074,\n20054,\n25296,\n24618,\n26874,\n20851,\n23448,\n20896,\n35266,\n31649,\n39302,\n32592,\n24815,\n28748,\n36143,\n20809,\n24191,\n36891,\n29808,\n35268,\n22317,\n30789,\n24402,\n40863,\n38394,\n36712,\n39740,\n35809,\n30328,\n26690,\n26588,\n36330,\n36149,\n21053,\n36746,\n28378,\n26829,\n38149,\n37101,\n22269,\n26524,\n35065,\n36807,\n21704,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31685,\n31688,\n31689,\n31690,\n31691,\n31693,\n31694,\n31695,\n31696,\n31698,\n31700,\n31701,\n31702,\n31703,\n31704,\n31707,\n31708,\n31710,\n31711,\n31712,\n31714,\n31715,\n31716,\n31719,\n31720,\n31721,\n31723,\n31724,\n31725,\n31727,\n31728,\n31730,\n31731,\n31732,\n31733,\n31734,\n31736,\n31737,\n31738,\n31739,\n31741,\n31743,\n31744,\n31745,\n31746,\n31747,\n31748,\n31749,\n31750,\n31752,\n31753,\n31754,\n31757,\n31758,\n31760,\n31761,\n31762,\n31763,\n31764,\n31765,\n31767,\n31768,\n31769,\n0,\n31770,\n31771,\n31772,\n31773,\n31774,\n31776,\n31777,\n31778,\n31779,\n31780,\n31781,\n31784,\n31785,\n31787,\n31788,\n31789,\n31790,\n31791,\n31792,\n31793,\n31794,\n31795,\n31796,\n31797,\n31798,\n31799,\n31801,\n31802,\n31803,\n31804,\n31805,\n31806,\n31810,\n39608,\n23401,\n28023,\n27686,\n20133,\n23475,\n39559,\n37219,\n25000,\n37039,\n38889,\n21547,\n28085,\n23506,\n20989,\n21898,\n32597,\n32752,\n25788,\n25421,\n26097,\n25022,\n24717,\n28938,\n27735,\n27721,\n22831,\n26477,\n33322,\n22741,\n22158,\n35946,\n27627,\n37085,\n22909,\n32791,\n21495,\n28009,\n21621,\n21917,\n33655,\n33743,\n26680,\n31166,\n21644,\n20309,\n21512,\n30418,\n35977,\n38402,\n27827,\n28088,\n36203,\n35088,\n40548,\n36154,\n22079,\n40657,\n30165,\n24456,\n29408,\n24680,\n21756,\n20136,\n27178,\n34913,\n24658,\n36720,\n21700,\n28888,\n34425,\n40511,\n27946,\n23439,\n24344,\n32418,\n21897,\n20399,\n29492,\n21564,\n21402,\n20505,\n21518,\n21628,\n20046,\n24573,\n29786,\n22774,\n33899,\n32993,\n34676,\n29392,\n31946,\n28246,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31811,\n31812,\n31813,\n31814,\n31815,\n31816,\n31817,\n31818,\n31819,\n31820,\n31822,\n31823,\n31824,\n31825,\n31826,\n31827,\n31828,\n31829,\n31830,\n31831,\n31832,\n31833,\n31834,\n31835,\n31836,\n31837,\n31838,\n31839,\n31840,\n31841,\n31842,\n31843,\n31844,\n31845,\n31846,\n31847,\n31848,\n31849,\n31850,\n31851,\n31852,\n31853,\n31854,\n31855,\n31856,\n31857,\n31858,\n31861,\n31862,\n31863,\n31864,\n31865,\n31866,\n31870,\n31871,\n31872,\n31873,\n31874,\n31875,\n31876,\n31877,\n31878,\n31879,\n0,\n31880,\n31882,\n31883,\n31884,\n31885,\n31886,\n31887,\n31888,\n31891,\n31892,\n31894,\n31897,\n31898,\n31899,\n31904,\n31905,\n31907,\n31910,\n31911,\n31912,\n31913,\n31915,\n31916,\n31917,\n31919,\n31920,\n31924,\n31925,\n31926,\n31927,\n31928,\n31930,\n31931,\n24359,\n34382,\n21804,\n25252,\n20114,\n27818,\n25143,\n33457,\n21719,\n21326,\n29502,\n28369,\n30011,\n21010,\n21270,\n35805,\n27088,\n24458,\n24576,\n28142,\n22351,\n27426,\n29615,\n26707,\n36824,\n32531,\n25442,\n24739,\n21796,\n30186,\n35938,\n28949,\n28067,\n23462,\n24187,\n33618,\n24908,\n40644,\n30970,\n34647,\n31783,\n30343,\n20976,\n24822,\n29004,\n26179,\n24140,\n24653,\n35854,\n28784,\n25381,\n36745,\n24509,\n24674,\n34516,\n22238,\n27585,\n24724,\n24935,\n21321,\n24800,\n26214,\n36159,\n31229,\n20250,\n28905,\n27719,\n35763,\n35826,\n32472,\n33636,\n26127,\n23130,\n39746,\n27985,\n28151,\n35905,\n27963,\n20249,\n28779,\n33719,\n25110,\n24785,\n38669,\n36135,\n31096,\n20987,\n22334,\n22522,\n26426,\n30072,\n31293,\n31215,\n31637,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n31935,\n31936,\n31938,\n31939,\n31940,\n31942,\n31945,\n31947,\n31950,\n31951,\n31952,\n31953,\n31954,\n31955,\n31956,\n31960,\n31962,\n31963,\n31965,\n31966,\n31969,\n31970,\n31971,\n31972,\n31973,\n31974,\n31975,\n31977,\n31978,\n31979,\n31980,\n31981,\n31982,\n31984,\n31985,\n31986,\n31987,\n31988,\n31989,\n31990,\n31991,\n31993,\n31994,\n31996,\n31997,\n31998,\n31999,\n32000,\n32001,\n32002,\n32003,\n32004,\n32005,\n32006,\n32007,\n32008,\n32009,\n32011,\n32012,\n32013,\n32014,\n32015,\n32016,\n0,\n32017,\n32018,\n32019,\n32020,\n32021,\n32022,\n32023,\n32024,\n32025,\n32026,\n32027,\n32028,\n32029,\n32030,\n32031,\n32033,\n32035,\n32036,\n32037,\n32038,\n32040,\n32041,\n32042,\n32044,\n32045,\n32046,\n32048,\n32049,\n32050,\n32051,\n32052,\n32053,\n32054,\n32908,\n39269,\n36857,\n28608,\n35749,\n40481,\n23020,\n32489,\n32521,\n21513,\n26497,\n26840,\n36753,\n31821,\n38598,\n21450,\n24613,\n30142,\n27762,\n21363,\n23241,\n32423,\n25380,\n20960,\n33034,\n24049,\n34015,\n25216,\n20864,\n23395,\n20238,\n31085,\n21058,\n24760,\n27982,\n23492,\n23490,\n35745,\n35760,\n26082,\n24524,\n38469,\n22931,\n32487,\n32426,\n22025,\n26551,\n22841,\n20339,\n23478,\n21152,\n33626,\n39050,\n36158,\n30002,\n38078,\n20551,\n31292,\n20215,\n26550,\n39550,\n23233,\n27516,\n30417,\n22362,\n23574,\n31546,\n38388,\n29006,\n20860,\n32937,\n33392,\n22904,\n32516,\n33575,\n26816,\n26604,\n30897,\n30839,\n25315,\n25441,\n31616,\n20461,\n21098,\n20943,\n33616,\n27099,\n37492,\n36341,\n36145,\n35265,\n38190,\n31661,\n20214,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32055,\n32056,\n32057,\n32058,\n32059,\n32060,\n32061,\n32062,\n32063,\n32064,\n32065,\n32066,\n32067,\n32068,\n32069,\n32070,\n32071,\n32072,\n32073,\n32074,\n32075,\n32076,\n32077,\n32078,\n32079,\n32080,\n32081,\n32082,\n32083,\n32084,\n32085,\n32086,\n32087,\n32088,\n32089,\n32090,\n32091,\n32092,\n32093,\n32094,\n32095,\n32096,\n32097,\n32098,\n32099,\n32100,\n32101,\n32102,\n32103,\n32104,\n32105,\n32106,\n32107,\n32108,\n32109,\n32111,\n32112,\n32113,\n32114,\n32115,\n32116,\n32117,\n32118,\n0,\n32120,\n32121,\n32122,\n32123,\n32124,\n32125,\n32126,\n32127,\n32128,\n32129,\n32130,\n32131,\n32132,\n32133,\n32134,\n32135,\n32136,\n32137,\n32138,\n32139,\n32140,\n32141,\n32142,\n32143,\n32144,\n32145,\n32146,\n32147,\n32148,\n32149,\n32150,\n32151,\n32152,\n20581,\n33328,\n21073,\n39279,\n28176,\n28293,\n28071,\n24314,\n20725,\n23004,\n23558,\n27974,\n27743,\n30086,\n33931,\n26728,\n22870,\n35762,\n21280,\n37233,\n38477,\n34121,\n26898,\n30977,\n28966,\n33014,\n20132,\n37066,\n27975,\n39556,\n23047,\n22204,\n25605,\n38128,\n30699,\n20389,\n33050,\n29409,\n35282,\n39290,\n32564,\n32478,\n21119,\n25945,\n37237,\n36735,\n36739,\n21483,\n31382,\n25581,\n25509,\n30342,\n31224,\n34903,\n38454,\n25130,\n21163,\n33410,\n26708,\n26480,\n25463,\n30571,\n31469,\n27905,\n32467,\n35299,\n22992,\n25106,\n34249,\n33445,\n30028,\n20511,\n20171,\n30117,\n35819,\n23626,\n24062,\n31563,\n26020,\n37329,\n20170,\n27941,\n35167,\n32039,\n38182,\n20165,\n35880,\n36827,\n38771,\n26187,\n31105,\n36817,\n28908,\n28024,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32153,\n32154,\n32155,\n32156,\n32157,\n32158,\n32159,\n32160,\n32161,\n32162,\n32163,\n32164,\n32165,\n32167,\n32168,\n32169,\n32170,\n32171,\n32172,\n32173,\n32175,\n32176,\n32177,\n32178,\n32179,\n32180,\n32181,\n32182,\n32183,\n32184,\n32185,\n32186,\n32187,\n32188,\n32189,\n32190,\n32191,\n32192,\n32193,\n32194,\n32195,\n32196,\n32197,\n32198,\n32199,\n32200,\n32201,\n32202,\n32203,\n32204,\n32205,\n32206,\n32207,\n32208,\n32209,\n32210,\n32211,\n32212,\n32213,\n32214,\n32215,\n32216,\n32217,\n0,\n32218,\n32219,\n32220,\n32221,\n32222,\n32223,\n32224,\n32225,\n32226,\n32227,\n32228,\n32229,\n32230,\n32231,\n32232,\n32233,\n32234,\n32235,\n32236,\n32237,\n32238,\n32239,\n32240,\n32241,\n32242,\n32243,\n32244,\n32245,\n32246,\n32247,\n32248,\n32249,\n32250,\n23613,\n21170,\n33606,\n20834,\n33550,\n30555,\n26230,\n40120,\n20140,\n24778,\n31934,\n31923,\n32463,\n20117,\n35686,\n26223,\n39048,\n38745,\n22659,\n25964,\n38236,\n24452,\n30153,\n38742,\n31455,\n31454,\n20928,\n28847,\n31384,\n25578,\n31350,\n32416,\n29590,\n38893,\n20037,\n28792,\n20061,\n37202,\n21417,\n25937,\n26087,\n33276,\n33285,\n21646,\n23601,\n30106,\n38816,\n25304,\n29401,\n30141,\n23621,\n39545,\n33738,\n23616,\n21632,\n30697,\n20030,\n27822,\n32858,\n25298,\n25454,\n24040,\n20855,\n36317,\n36382,\n38191,\n20465,\n21477,\n24807,\n28844,\n21095,\n25424,\n40515,\n23071,\n20518,\n30519,\n21367,\n32482,\n25733,\n25899,\n25225,\n25496,\n20500,\n29237,\n35273,\n20915,\n35776,\n32477,\n22343,\n33740,\n38055,\n20891,\n21531,\n23803,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32251,\n32252,\n32253,\n32254,\n32255,\n32256,\n32257,\n32258,\n32259,\n32260,\n32261,\n32262,\n32263,\n32264,\n32265,\n32266,\n32267,\n32268,\n32269,\n32270,\n32271,\n32272,\n32273,\n32274,\n32275,\n32276,\n32277,\n32278,\n32279,\n32280,\n32281,\n32282,\n32283,\n32284,\n32285,\n32286,\n32287,\n32288,\n32289,\n32290,\n32291,\n32292,\n32293,\n32294,\n32295,\n32296,\n32297,\n32298,\n32299,\n32300,\n32301,\n32302,\n32303,\n32304,\n32305,\n32306,\n32307,\n32308,\n32309,\n32310,\n32311,\n32312,\n32313,\n0,\n32314,\n32316,\n32317,\n32318,\n32319,\n32320,\n32322,\n32323,\n32324,\n32325,\n32326,\n32328,\n32329,\n32330,\n32331,\n32332,\n32333,\n32334,\n32335,\n32336,\n32337,\n32338,\n32339,\n32340,\n32341,\n32342,\n32343,\n32344,\n32345,\n32346,\n32347,\n32348,\n32349,\n20426,\n31459,\n27994,\n37089,\n39567,\n21888,\n21654,\n21345,\n21679,\n24320,\n25577,\n26999,\n20975,\n24936,\n21002,\n22570,\n21208,\n22350,\n30733,\n30475,\n24247,\n24951,\n31968,\n25179,\n25239,\n20130,\n28821,\n32771,\n25335,\n28900,\n38752,\n22391,\n33499,\n26607,\n26869,\n30933,\n39063,\n31185,\n22771,\n21683,\n21487,\n28212,\n20811,\n21051,\n23458,\n35838,\n32943,\n21827,\n22438,\n24691,\n22353,\n21549,\n31354,\n24656,\n23380,\n25511,\n25248,\n21475,\n25187,\n23495,\n26543,\n21741,\n31391,\n33510,\n37239,\n24211,\n35044,\n22840,\n22446,\n25358,\n36328,\n33007,\n22359,\n31607,\n20393,\n24555,\n23485,\n27454,\n21281,\n31568,\n29378,\n26694,\n30719,\n30518,\n26103,\n20917,\n20111,\n30420,\n23743,\n31397,\n33909,\n22862,\n39745,\n20608,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32350,\n32351,\n32352,\n32353,\n32354,\n32355,\n32356,\n32357,\n32358,\n32359,\n32360,\n32361,\n32362,\n32363,\n32364,\n32365,\n32366,\n32367,\n32368,\n32369,\n32370,\n32371,\n32372,\n32373,\n32374,\n32375,\n32376,\n32377,\n32378,\n32379,\n32380,\n32381,\n32382,\n32383,\n32384,\n32385,\n32387,\n32388,\n32389,\n32390,\n32391,\n32392,\n32393,\n32394,\n32395,\n32396,\n32397,\n32398,\n32399,\n32400,\n32401,\n32402,\n32403,\n32404,\n32405,\n32406,\n32407,\n32408,\n32409,\n32410,\n32412,\n32413,\n32414,\n0,\n32430,\n32436,\n32443,\n32444,\n32470,\n32484,\n32492,\n32505,\n32522,\n32528,\n32542,\n32567,\n32569,\n32571,\n32572,\n32573,\n32574,\n32575,\n32576,\n32577,\n32579,\n32582,\n32583,\n32584,\n32585,\n32586,\n32587,\n32588,\n32589,\n32590,\n32591,\n32594,\n32595,\n39304,\n24871,\n28291,\n22372,\n26118,\n25414,\n22256,\n25324,\n25193,\n24275,\n38420,\n22403,\n25289,\n21895,\n34593,\n33098,\n36771,\n21862,\n33713,\n26469,\n36182,\n34013,\n23146,\n26639,\n25318,\n31726,\n38417,\n20848,\n28572,\n35888,\n25597,\n35272,\n25042,\n32518,\n28866,\n28389,\n29701,\n27028,\n29436,\n24266,\n37070,\n26391,\n28010,\n25438,\n21171,\n29282,\n32769,\n20332,\n23013,\n37226,\n28889,\n28061,\n21202,\n20048,\n38647,\n38253,\n34174,\n30922,\n32047,\n20769,\n22418,\n25794,\n32907,\n31867,\n27882,\n26865,\n26974,\n20919,\n21400,\n26792,\n29313,\n40654,\n31729,\n29432,\n31163,\n28435,\n29702,\n26446,\n37324,\n40100,\n31036,\n33673,\n33620,\n21519,\n26647,\n20029,\n21385,\n21169,\n30782,\n21382,\n21033,\n20616,\n20363,\n20432,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32598,\n32601,\n32603,\n32604,\n32605,\n32606,\n32608,\n32611,\n32612,\n32613,\n32614,\n32615,\n32619,\n32620,\n32621,\n32623,\n32624,\n32627,\n32629,\n32630,\n32631,\n32632,\n32634,\n32635,\n32636,\n32637,\n32639,\n32640,\n32642,\n32643,\n32644,\n32645,\n32646,\n32647,\n32648,\n32649,\n32651,\n32653,\n32655,\n32656,\n32657,\n32658,\n32659,\n32661,\n32662,\n32663,\n32664,\n32665,\n32667,\n32668,\n32672,\n32674,\n32675,\n32677,\n32678,\n32680,\n32681,\n32682,\n32683,\n32684,\n32685,\n32686,\n32689,\n0,\n32691,\n32692,\n32693,\n32694,\n32695,\n32698,\n32699,\n32702,\n32704,\n32706,\n32707,\n32708,\n32710,\n32711,\n32712,\n32713,\n32715,\n32717,\n32719,\n32720,\n32721,\n32722,\n32723,\n32726,\n32727,\n32729,\n32730,\n32731,\n32732,\n32733,\n32734,\n32738,\n32739,\n30178,\n31435,\n31890,\n27813,\n38582,\n21147,\n29827,\n21737,\n20457,\n32852,\n33714,\n36830,\n38256,\n24265,\n24604,\n28063,\n24088,\n25947,\n33080,\n38142,\n24651,\n28860,\n32451,\n31918,\n20937,\n26753,\n31921,\n33391,\n20004,\n36742,\n37327,\n26238,\n20142,\n35845,\n25769,\n32842,\n20698,\n30103,\n29134,\n23525,\n36797,\n28518,\n20102,\n25730,\n38243,\n24278,\n26009,\n21015,\n35010,\n28872,\n21155,\n29454,\n29747,\n26519,\n30967,\n38678,\n20020,\n37051,\n40158,\n28107,\n20955,\n36161,\n21533,\n25294,\n29618,\n33777,\n38646,\n40836,\n38083,\n20278,\n32666,\n20940,\n28789,\n38517,\n23725,\n39046,\n21478,\n20196,\n28316,\n29705,\n27060,\n30827,\n39311,\n30041,\n21016,\n30244,\n27969,\n26611,\n20845,\n40857,\n32843,\n21657,\n31548,\n31423,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32740,\n32743,\n32744,\n32746,\n32747,\n32748,\n32749,\n32751,\n32754,\n32756,\n32757,\n32758,\n32759,\n32760,\n32761,\n32762,\n32765,\n32766,\n32767,\n32770,\n32775,\n32776,\n32777,\n32778,\n32782,\n32783,\n32785,\n32787,\n32794,\n32795,\n32797,\n32798,\n32799,\n32801,\n32803,\n32804,\n32811,\n32812,\n32813,\n32814,\n32815,\n32816,\n32818,\n32820,\n32825,\n32826,\n32828,\n32830,\n32832,\n32833,\n32836,\n32837,\n32839,\n32840,\n32841,\n32846,\n32847,\n32848,\n32849,\n32851,\n32853,\n32854,\n32855,\n0,\n32857,\n32859,\n32860,\n32861,\n32862,\n32863,\n32864,\n32865,\n32866,\n32867,\n32868,\n32869,\n32870,\n32871,\n32872,\n32875,\n32876,\n32877,\n32878,\n32879,\n32880,\n32882,\n32883,\n32884,\n32885,\n32886,\n32887,\n32888,\n32889,\n32890,\n32891,\n32892,\n32893,\n38534,\n22404,\n25314,\n38471,\n27004,\n23044,\n25602,\n31699,\n28431,\n38475,\n33446,\n21346,\n39045,\n24208,\n28809,\n25523,\n21348,\n34383,\n40065,\n40595,\n30860,\n38706,\n36335,\n36162,\n40575,\n28510,\n31108,\n24405,\n38470,\n25134,\n39540,\n21525,\n38109,\n20387,\n26053,\n23653,\n23649,\n32533,\n34385,\n27695,\n24459,\n29575,\n28388,\n32511,\n23782,\n25371,\n23402,\n28390,\n21365,\n20081,\n25504,\n30053,\n25249,\n36718,\n20262,\n20177,\n27814,\n32438,\n35770,\n33821,\n34746,\n32599,\n36923,\n38179,\n31657,\n39585,\n35064,\n33853,\n27931,\n39558,\n32476,\n22920,\n40635,\n29595,\n30721,\n34434,\n39532,\n39554,\n22043,\n21527,\n22475,\n20080,\n40614,\n21334,\n36808,\n33033,\n30610,\n39314,\n34542,\n28385,\n34067,\n26364,\n24930,\n28459,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n32894,\n32897,\n32898,\n32901,\n32904,\n32906,\n32909,\n32910,\n32911,\n32912,\n32913,\n32914,\n32916,\n32917,\n32919,\n32921,\n32926,\n32931,\n32934,\n32935,\n32936,\n32940,\n32944,\n32947,\n32949,\n32950,\n32952,\n32953,\n32955,\n32965,\n32967,\n32968,\n32969,\n32970,\n32971,\n32975,\n32976,\n32977,\n32978,\n32979,\n32980,\n32981,\n32984,\n32991,\n32992,\n32994,\n32995,\n32998,\n33006,\n33013,\n33015,\n33017,\n33019,\n33022,\n33023,\n33024,\n33025,\n33027,\n33028,\n33029,\n33031,\n33032,\n33035,\n0,\n33036,\n33045,\n33047,\n33049,\n33051,\n33052,\n33053,\n33055,\n33056,\n33057,\n33058,\n33059,\n33060,\n33061,\n33062,\n33063,\n33064,\n33065,\n33066,\n33067,\n33069,\n33070,\n33072,\n33075,\n33076,\n33077,\n33079,\n33081,\n33082,\n33083,\n33084,\n33085,\n33087,\n35881,\n33426,\n33579,\n30450,\n27667,\n24537,\n33725,\n29483,\n33541,\n38170,\n27611,\n30683,\n38086,\n21359,\n33538,\n20882,\n24125,\n35980,\n36152,\n20040,\n29611,\n26522,\n26757,\n37238,\n38665,\n29028,\n27809,\n30473,\n23186,\n38209,\n27599,\n32654,\n26151,\n23504,\n22969,\n23194,\n38376,\n38391,\n20204,\n33804,\n33945,\n27308,\n30431,\n38192,\n29467,\n26790,\n23391,\n30511,\n37274,\n38753,\n31964,\n36855,\n35868,\n24357,\n31859,\n31192,\n35269,\n27852,\n34588,\n23494,\n24130,\n26825,\n30496,\n32501,\n20885,\n20813,\n21193,\n23081,\n32517,\n38754,\n33495,\n25551,\n30596,\n34256,\n31186,\n28218,\n24217,\n22937,\n34065,\n28781,\n27665,\n25279,\n30399,\n25935,\n24751,\n38397,\n26126,\n34719,\n40483,\n38125,\n21517,\n21629,\n35884,\n25720,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33088,\n33089,\n33090,\n33091,\n33092,\n33093,\n33095,\n33097,\n33101,\n33102,\n33103,\n33106,\n33110,\n33111,\n33112,\n33115,\n33116,\n33117,\n33118,\n33119,\n33121,\n33122,\n33123,\n33124,\n33126,\n33128,\n33130,\n33131,\n33132,\n33135,\n33138,\n33139,\n33141,\n33142,\n33143,\n33144,\n33153,\n33155,\n33156,\n33157,\n33158,\n33159,\n33161,\n33163,\n33164,\n33165,\n33166,\n33168,\n33170,\n33171,\n33172,\n33173,\n33174,\n33175,\n33177,\n33178,\n33182,\n33183,\n33184,\n33185,\n33186,\n33188,\n33189,\n0,\n33191,\n33193,\n33195,\n33196,\n33197,\n33198,\n33199,\n33200,\n33201,\n33202,\n33204,\n33205,\n33206,\n33207,\n33208,\n33209,\n33212,\n33213,\n33214,\n33215,\n33220,\n33221,\n33223,\n33224,\n33225,\n33227,\n33229,\n33230,\n33231,\n33232,\n33233,\n33234,\n33235,\n25721,\n34321,\n27169,\n33180,\n30952,\n25705,\n39764,\n25273,\n26411,\n33707,\n22696,\n40664,\n27819,\n28448,\n23518,\n38476,\n35851,\n29279,\n26576,\n25287,\n29281,\n20137,\n22982,\n27597,\n22675,\n26286,\n24149,\n21215,\n24917,\n26408,\n30446,\n30566,\n29287,\n31302,\n25343,\n21738,\n21584,\n38048,\n37027,\n23068,\n32435,\n27670,\n20035,\n22902,\n32784,\n22856,\n21335,\n30007,\n38590,\n22218,\n25376,\n33041,\n24700,\n38393,\n28118,\n21602,\n39297,\n20869,\n23273,\n33021,\n22958,\n38675,\n20522,\n27877,\n23612,\n25311,\n20320,\n21311,\n33147,\n36870,\n28346,\n34091,\n25288,\n24180,\n30910,\n25781,\n25467,\n24565,\n23064,\n37247,\n40479,\n23615,\n25423,\n32834,\n23421,\n21870,\n38218,\n38221,\n28037,\n24744,\n26592,\n29406,\n20957,\n23425,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33236,\n33237,\n33238,\n33239,\n33240,\n33241,\n33242,\n33243,\n33244,\n33245,\n33246,\n33247,\n33248,\n33249,\n33250,\n33252,\n33253,\n33254,\n33256,\n33257,\n33259,\n33262,\n33263,\n33264,\n33265,\n33266,\n33269,\n33270,\n33271,\n33272,\n33273,\n33274,\n33277,\n33279,\n33283,\n33287,\n33288,\n33289,\n33290,\n33291,\n33294,\n33295,\n33297,\n33299,\n33301,\n33302,\n33303,\n33304,\n33305,\n33306,\n33309,\n33312,\n33316,\n33317,\n33318,\n33319,\n33321,\n33326,\n33330,\n33338,\n33340,\n33341,\n33343,\n0,\n33344,\n33345,\n33346,\n33347,\n33349,\n33350,\n33352,\n33354,\n33356,\n33357,\n33358,\n33360,\n33361,\n33362,\n33363,\n33364,\n33365,\n33366,\n33367,\n33369,\n33371,\n33372,\n33373,\n33374,\n33376,\n33377,\n33378,\n33379,\n33380,\n33381,\n33382,\n33383,\n33385,\n25319,\n27870,\n29275,\n25197,\n38062,\n32445,\n33043,\n27987,\n20892,\n24324,\n22900,\n21162,\n24594,\n22899,\n26262,\n34384,\n30111,\n25386,\n25062,\n31983,\n35834,\n21734,\n27431,\n40485,\n27572,\n34261,\n21589,\n20598,\n27812,\n21866,\n36276,\n29228,\n24085,\n24597,\n29750,\n25293,\n25490,\n29260,\n24472,\n28227,\n27966,\n25856,\n28504,\n30424,\n30928,\n30460,\n30036,\n21028,\n21467,\n20051,\n24222,\n26049,\n32810,\n32982,\n25243,\n21638,\n21032,\n28846,\n34957,\n36305,\n27873,\n21624,\n32986,\n22521,\n35060,\n36180,\n38506,\n37197,\n20329,\n27803,\n21943,\n30406,\n30768,\n25256,\n28921,\n28558,\n24429,\n34028,\n26842,\n30844,\n31735,\n33192,\n26379,\n40527,\n25447,\n30896,\n22383,\n30738,\n38713,\n25209,\n25259,\n21128,\n29749,\n27607,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33386,\n33387,\n33388,\n33389,\n33393,\n33397,\n33398,\n33399,\n33400,\n33403,\n33404,\n33408,\n33409,\n33411,\n33413,\n33414,\n33415,\n33417,\n33420,\n33424,\n33427,\n33428,\n33429,\n33430,\n33434,\n33435,\n33438,\n33440,\n33442,\n33443,\n33447,\n33458,\n33461,\n33462,\n33466,\n33467,\n33468,\n33471,\n33472,\n33474,\n33475,\n33477,\n33478,\n33481,\n33488,\n33494,\n33497,\n33498,\n33501,\n33506,\n33511,\n33512,\n33513,\n33514,\n33516,\n33517,\n33518,\n33520,\n33522,\n33523,\n33525,\n33526,\n33528,\n0,\n33530,\n33532,\n33533,\n33534,\n33535,\n33536,\n33546,\n33547,\n33549,\n33552,\n33554,\n33555,\n33558,\n33560,\n33561,\n33565,\n33566,\n33567,\n33568,\n33569,\n33570,\n33571,\n33572,\n33573,\n33574,\n33577,\n33578,\n33582,\n33584,\n33586,\n33591,\n33595,\n33597,\n21860,\n33086,\n30130,\n30382,\n21305,\n30174,\n20731,\n23617,\n35692,\n31687,\n20559,\n29255,\n39575,\n39128,\n28418,\n29922,\n31080,\n25735,\n30629,\n25340,\n39057,\n36139,\n21697,\n32856,\n20050,\n22378,\n33529,\n33805,\n24179,\n20973,\n29942,\n35780,\n23631,\n22369,\n27900,\n39047,\n23110,\n30772,\n39748,\n36843,\n31893,\n21078,\n25169,\n38138,\n20166,\n33670,\n33889,\n33769,\n33970,\n22484,\n26420,\n22275,\n26222,\n28006,\n35889,\n26333,\n28689,\n26399,\n27450,\n26646,\n25114,\n22971,\n19971,\n20932,\n28422,\n26578,\n27791,\n20854,\n26827,\n22855,\n27495,\n30054,\n23822,\n33040,\n40784,\n26071,\n31048,\n31041,\n39569,\n36215,\n23682,\n20062,\n20225,\n21551,\n22865,\n30732,\n22120,\n27668,\n36804,\n24323,\n27773,\n27875,\n35755,\n25488,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33598,\n33599,\n33601,\n33602,\n33604,\n33605,\n33608,\n33610,\n33611,\n33612,\n33613,\n33614,\n33619,\n33621,\n33622,\n33623,\n33624,\n33625,\n33629,\n33634,\n33648,\n33649,\n33650,\n33651,\n33652,\n33653,\n33654,\n33657,\n33658,\n33662,\n33663,\n33664,\n33665,\n33666,\n33667,\n33668,\n33671,\n33672,\n33674,\n33675,\n33676,\n33677,\n33679,\n33680,\n33681,\n33684,\n33685,\n33686,\n33687,\n33689,\n33690,\n33693,\n33695,\n33697,\n33698,\n33699,\n33700,\n33701,\n33702,\n33703,\n33708,\n33709,\n33710,\n0,\n33711,\n33717,\n33723,\n33726,\n33727,\n33730,\n33731,\n33732,\n33734,\n33736,\n33737,\n33739,\n33741,\n33742,\n33744,\n33745,\n33746,\n33747,\n33749,\n33751,\n33753,\n33754,\n33755,\n33758,\n33762,\n33763,\n33764,\n33766,\n33767,\n33768,\n33771,\n33772,\n33773,\n24688,\n27965,\n29301,\n25190,\n38030,\n38085,\n21315,\n36801,\n31614,\n20191,\n35878,\n20094,\n40660,\n38065,\n38067,\n21069,\n28508,\n36963,\n27973,\n35892,\n22545,\n23884,\n27424,\n27465,\n26538,\n21595,\n33108,\n32652,\n22681,\n34103,\n24378,\n25250,\n27207,\n38201,\n25970,\n24708,\n26725,\n30631,\n20052,\n20392,\n24039,\n38808,\n25772,\n32728,\n23789,\n20431,\n31373,\n20999,\n33540,\n19988,\n24623,\n31363,\n38054,\n20405,\n20146,\n31206,\n29748,\n21220,\n33465,\n25810,\n31165,\n23517,\n27777,\n38738,\n36731,\n27682,\n20542,\n21375,\n28165,\n25806,\n26228,\n27696,\n24773,\n39031,\n35831,\n24198,\n29756,\n31351,\n31179,\n19992,\n37041,\n29699,\n27714,\n22234,\n37195,\n27845,\n36235,\n21306,\n34502,\n26354,\n36527,\n23624,\n39537,\n28192,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33774,\n33775,\n33779,\n33780,\n33781,\n33782,\n33783,\n33786,\n33787,\n33788,\n33790,\n33791,\n33792,\n33794,\n33797,\n33799,\n33800,\n33801,\n33802,\n33808,\n33810,\n33811,\n33812,\n33813,\n33814,\n33815,\n33817,\n33818,\n33819,\n33822,\n33823,\n33824,\n33825,\n33826,\n33827,\n33833,\n33834,\n33835,\n33836,\n33837,\n33838,\n33839,\n33840,\n33842,\n33843,\n33844,\n33845,\n33846,\n33847,\n33849,\n33850,\n33851,\n33854,\n33855,\n33856,\n33857,\n33858,\n33859,\n33860,\n33861,\n33863,\n33864,\n33865,\n0,\n33866,\n33867,\n33868,\n33869,\n33870,\n33871,\n33872,\n33874,\n33875,\n33876,\n33877,\n33878,\n33880,\n33885,\n33886,\n33887,\n33888,\n33890,\n33892,\n33893,\n33894,\n33895,\n33896,\n33898,\n33902,\n33903,\n33904,\n33906,\n33908,\n33911,\n33913,\n33915,\n33916,\n21462,\n23094,\n40843,\n36259,\n21435,\n22280,\n39079,\n26435,\n37275,\n27849,\n20840,\n30154,\n25331,\n29356,\n21048,\n21149,\n32570,\n28820,\n30264,\n21364,\n40522,\n27063,\n30830,\n38592,\n35033,\n32676,\n28982,\n29123,\n20873,\n26579,\n29924,\n22756,\n25880,\n22199,\n35753,\n39286,\n25200,\n32469,\n24825,\n28909,\n22764,\n20161,\n20154,\n24525,\n38887,\n20219,\n35748,\n20995,\n22922,\n32427,\n25172,\n20173,\n26085,\n25102,\n33592,\n33993,\n33635,\n34701,\n29076,\n28342,\n23481,\n32466,\n20887,\n25545,\n26580,\n32905,\n33593,\n34837,\n20754,\n23418,\n22914,\n36785,\n20083,\n27741,\n20837,\n35109,\n36719,\n38446,\n34122,\n29790,\n38160,\n38384,\n28070,\n33509,\n24369,\n25746,\n27922,\n33832,\n33134,\n40131,\n22622,\n36187,\n19977,\n21441,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n33917,\n33918,\n33919,\n33920,\n33921,\n33923,\n33924,\n33925,\n33926,\n33930,\n33933,\n33935,\n33936,\n33937,\n33938,\n33939,\n33940,\n33941,\n33942,\n33944,\n33946,\n33947,\n33949,\n33950,\n33951,\n33952,\n33954,\n33955,\n33956,\n33957,\n33958,\n33959,\n33960,\n33961,\n33962,\n33963,\n33964,\n33965,\n33966,\n33968,\n33969,\n33971,\n33973,\n33974,\n33975,\n33979,\n33980,\n33982,\n33984,\n33986,\n33987,\n33989,\n33990,\n33991,\n33992,\n33995,\n33996,\n33998,\n33999,\n34002,\n34004,\n34005,\n34007,\n0,\n34008,\n34009,\n34010,\n34011,\n34012,\n34014,\n34017,\n34018,\n34020,\n34023,\n34024,\n34025,\n34026,\n34027,\n34029,\n34030,\n34031,\n34033,\n34034,\n34035,\n34036,\n34037,\n34038,\n34039,\n34040,\n34041,\n34042,\n34043,\n34045,\n34046,\n34048,\n34049,\n34050,\n20254,\n25955,\n26705,\n21971,\n20007,\n25620,\n39578,\n25195,\n23234,\n29791,\n33394,\n28073,\n26862,\n20711,\n33678,\n30722,\n26432,\n21049,\n27801,\n32433,\n20667,\n21861,\n29022,\n31579,\n26194,\n29642,\n33515,\n26441,\n23665,\n21024,\n29053,\n34923,\n38378,\n38485,\n25797,\n36193,\n33203,\n21892,\n27733,\n25159,\n32558,\n22674,\n20260,\n21830,\n36175,\n26188,\n19978,\n23578,\n35059,\n26786,\n25422,\n31245,\n28903,\n33421,\n21242,\n38902,\n23569,\n21736,\n37045,\n32461,\n22882,\n36170,\n34503,\n33292,\n33293,\n36198,\n25668,\n23556,\n24913,\n28041,\n31038,\n35774,\n30775,\n30003,\n21627,\n20280,\n36523,\n28145,\n23072,\n32453,\n31070,\n27784,\n23457,\n23158,\n29978,\n32958,\n24910,\n28183,\n22768,\n29983,\n29989,\n29298,\n21319,\n32499,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34051,\n34052,\n34053,\n34054,\n34055,\n34056,\n34057,\n34058,\n34059,\n34061,\n34062,\n34063,\n34064,\n34066,\n34068,\n34069,\n34070,\n34072,\n34073,\n34075,\n34076,\n34077,\n34078,\n34080,\n34082,\n34083,\n34084,\n34085,\n34086,\n34087,\n34088,\n34089,\n34090,\n34093,\n34094,\n34095,\n34096,\n34097,\n34098,\n34099,\n34100,\n34101,\n34102,\n34110,\n34111,\n34112,\n34113,\n34114,\n34116,\n34117,\n34118,\n34119,\n34123,\n34124,\n34125,\n34126,\n34127,\n34128,\n34129,\n34130,\n34131,\n34132,\n34133,\n0,\n34135,\n34136,\n34138,\n34139,\n34140,\n34141,\n34143,\n34144,\n34145,\n34146,\n34147,\n34149,\n34150,\n34151,\n34153,\n34154,\n34155,\n34156,\n34157,\n34158,\n34159,\n34160,\n34161,\n34163,\n34165,\n34166,\n34167,\n34168,\n34172,\n34173,\n34175,\n34176,\n34177,\n30465,\n30427,\n21097,\n32988,\n22307,\n24072,\n22833,\n29422,\n26045,\n28287,\n35799,\n23608,\n34417,\n21313,\n30707,\n25342,\n26102,\n20160,\n39135,\n34432,\n23454,\n35782,\n21490,\n30690,\n20351,\n23630,\n39542,\n22987,\n24335,\n31034,\n22763,\n19990,\n26623,\n20107,\n25325,\n35475,\n36893,\n21183,\n26159,\n21980,\n22124,\n36866,\n20181,\n20365,\n37322,\n39280,\n27663,\n24066,\n24643,\n23460,\n35270,\n35797,\n25910,\n25163,\n39318,\n23432,\n23551,\n25480,\n21806,\n21463,\n30246,\n20861,\n34092,\n26530,\n26803,\n27530,\n25234,\n36755,\n21460,\n33298,\n28113,\n30095,\n20070,\n36174,\n23408,\n29087,\n34223,\n26257,\n26329,\n32626,\n34560,\n40653,\n40736,\n23646,\n26415,\n36848,\n26641,\n26463,\n25101,\n31446,\n22661,\n24246,\n25968,\n28465,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34178,\n34179,\n34182,\n34184,\n34185,\n34186,\n34187,\n34188,\n34189,\n34190,\n34192,\n34193,\n34194,\n34195,\n34196,\n34197,\n34198,\n34199,\n34200,\n34201,\n34202,\n34205,\n34206,\n34207,\n34208,\n34209,\n34210,\n34211,\n34213,\n34214,\n34215,\n34217,\n34219,\n34220,\n34221,\n34225,\n34226,\n34227,\n34228,\n34229,\n34230,\n34232,\n34234,\n34235,\n34236,\n34237,\n34238,\n34239,\n34240,\n34242,\n34243,\n34244,\n34245,\n34246,\n34247,\n34248,\n34250,\n34251,\n34252,\n34253,\n34254,\n34257,\n34258,\n0,\n34260,\n34262,\n34263,\n34264,\n34265,\n34266,\n34267,\n34269,\n34270,\n34271,\n34272,\n34273,\n34274,\n34275,\n34277,\n34278,\n34279,\n34280,\n34282,\n34283,\n34284,\n34285,\n34286,\n34287,\n34288,\n34289,\n34290,\n34291,\n34292,\n34293,\n34294,\n34295,\n34296,\n24661,\n21047,\n32781,\n25684,\n34928,\n29993,\n24069,\n26643,\n25332,\n38684,\n21452,\n29245,\n35841,\n27700,\n30561,\n31246,\n21550,\n30636,\n39034,\n33308,\n35828,\n30805,\n26388,\n28865,\n26031,\n25749,\n22070,\n24605,\n31169,\n21496,\n19997,\n27515,\n32902,\n23546,\n21987,\n22235,\n20282,\n20284,\n39282,\n24051,\n26494,\n32824,\n24578,\n39042,\n36865,\n23435,\n35772,\n35829,\n25628,\n33368,\n25822,\n22013,\n33487,\n37221,\n20439,\n32032,\n36895,\n31903,\n20723,\n22609,\n28335,\n23487,\n35785,\n32899,\n37240,\n33948,\n31639,\n34429,\n38539,\n38543,\n32485,\n39635,\n30862,\n23681,\n31319,\n36930,\n38567,\n31071,\n23385,\n25439,\n31499,\n34001,\n26797,\n21766,\n32553,\n29712,\n32034,\n38145,\n25152,\n22604,\n20182,\n23427,\n22905,\n22612,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34297,\n34298,\n34300,\n34301,\n34302,\n34304,\n34305,\n34306,\n34307,\n34308,\n34310,\n34311,\n34312,\n34313,\n34314,\n34315,\n34316,\n34317,\n34318,\n34319,\n34320,\n34322,\n34323,\n34324,\n34325,\n34327,\n34328,\n34329,\n34330,\n34331,\n34332,\n34333,\n34334,\n34335,\n34336,\n34337,\n34338,\n34339,\n34340,\n34341,\n34342,\n34344,\n34346,\n34347,\n34348,\n34349,\n34350,\n34351,\n34352,\n34353,\n34354,\n34355,\n34356,\n34357,\n34358,\n34359,\n34361,\n34362,\n34363,\n34365,\n34366,\n34367,\n34368,\n0,\n34369,\n34370,\n34371,\n34372,\n34373,\n34374,\n34375,\n34376,\n34377,\n34378,\n34379,\n34380,\n34386,\n34387,\n34389,\n34390,\n34391,\n34392,\n34393,\n34395,\n34396,\n34397,\n34399,\n34400,\n34401,\n34403,\n34404,\n34405,\n34406,\n34407,\n34408,\n34409,\n34410,\n29549,\n25374,\n36427,\n36367,\n32974,\n33492,\n25260,\n21488,\n27888,\n37214,\n22826,\n24577,\n27760,\n22349,\n25674,\n36138,\n30251,\n28393,\n22363,\n27264,\n30192,\n28525,\n35885,\n35848,\n22374,\n27631,\n34962,\n30899,\n25506,\n21497,\n28845,\n27748,\n22616,\n25642,\n22530,\n26848,\n33179,\n21776,\n31958,\n20504,\n36538,\n28108,\n36255,\n28907,\n25487,\n28059,\n28372,\n32486,\n33796,\n26691,\n36867,\n28120,\n38518,\n35752,\n22871,\n29305,\n34276,\n33150,\n30140,\n35466,\n26799,\n21076,\n36386,\n38161,\n25552,\n39064,\n36420,\n21884,\n20307,\n26367,\n22159,\n24789,\n28053,\n21059,\n23625,\n22825,\n28155,\n22635,\n30000,\n29980,\n24684,\n33300,\n33094,\n25361,\n26465,\n36834,\n30522,\n36339,\n36148,\n38081,\n24086,\n21381,\n21548,\n28867,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34413,\n34415,\n34416,\n34418,\n34419,\n34420,\n34421,\n34422,\n34423,\n34424,\n34435,\n34436,\n34437,\n34438,\n34439,\n34440,\n34441,\n34446,\n34447,\n34448,\n34449,\n34450,\n34452,\n34454,\n34455,\n34456,\n34457,\n34458,\n34459,\n34462,\n34463,\n34464,\n34465,\n34466,\n34469,\n34470,\n34475,\n34477,\n34478,\n34482,\n34483,\n34487,\n34488,\n34489,\n34491,\n34492,\n34493,\n34494,\n34495,\n34497,\n34498,\n34499,\n34501,\n34504,\n34508,\n34509,\n34514,\n34515,\n34517,\n34518,\n34519,\n34522,\n34524,\n0,\n34525,\n34528,\n34529,\n34530,\n34531,\n34533,\n34534,\n34535,\n34536,\n34538,\n34539,\n34540,\n34543,\n34549,\n34550,\n34551,\n34554,\n34555,\n34556,\n34557,\n34559,\n34561,\n34564,\n34565,\n34566,\n34571,\n34572,\n34574,\n34575,\n34576,\n34577,\n34580,\n34582,\n27712,\n24311,\n20572,\n20141,\n24237,\n25402,\n33351,\n36890,\n26704,\n37230,\n30643,\n21516,\n38108,\n24420,\n31461,\n26742,\n25413,\n31570,\n32479,\n30171,\n20599,\n25237,\n22836,\n36879,\n20984,\n31171,\n31361,\n22270,\n24466,\n36884,\n28034,\n23648,\n22303,\n21520,\n20820,\n28237,\n22242,\n25512,\n39059,\n33151,\n34581,\n35114,\n36864,\n21534,\n23663,\n33216,\n25302,\n25176,\n33073,\n40501,\n38464,\n39534,\n39548,\n26925,\n22949,\n25299,\n21822,\n25366,\n21703,\n34521,\n27964,\n23043,\n29926,\n34972,\n27498,\n22806,\n35916,\n24367,\n28286,\n29609,\n39037,\n20024,\n28919,\n23436,\n30871,\n25405,\n26202,\n30358,\n24779,\n23451,\n23113,\n19975,\n33109,\n27754,\n29579,\n20129,\n26505,\n32593,\n24448,\n26106,\n26395,\n24536,\n22916,\n23041,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34585,\n34587,\n34589,\n34591,\n34592,\n34596,\n34598,\n34599,\n34600,\n34602,\n34603,\n34604,\n34605,\n34607,\n34608,\n34610,\n34611,\n34613,\n34614,\n34616,\n34617,\n34618,\n34620,\n34621,\n34624,\n34625,\n34626,\n34627,\n34628,\n34629,\n34630,\n34634,\n34635,\n34637,\n34639,\n34640,\n34641,\n34642,\n34644,\n34645,\n34646,\n34648,\n34650,\n34651,\n34652,\n34653,\n34654,\n34655,\n34657,\n34658,\n34662,\n34663,\n34664,\n34665,\n34666,\n34667,\n34668,\n34669,\n34671,\n34673,\n34674,\n34675,\n34677,\n0,\n34679,\n34680,\n34681,\n34682,\n34687,\n34688,\n34689,\n34692,\n34694,\n34695,\n34697,\n34698,\n34700,\n34702,\n34703,\n34704,\n34705,\n34706,\n34708,\n34709,\n34710,\n34712,\n34713,\n34714,\n34715,\n34716,\n34717,\n34718,\n34720,\n34721,\n34722,\n34723,\n34724,\n24013,\n24494,\n21361,\n38886,\n36829,\n26693,\n22260,\n21807,\n24799,\n20026,\n28493,\n32500,\n33479,\n33806,\n22996,\n20255,\n20266,\n23614,\n32428,\n26410,\n34074,\n21619,\n30031,\n32963,\n21890,\n39759,\n20301,\n28205,\n35859,\n23561,\n24944,\n21355,\n30239,\n28201,\n34442,\n25991,\n38395,\n32441,\n21563,\n31283,\n32010,\n38382,\n21985,\n32705,\n29934,\n25373,\n34583,\n28065,\n31389,\n25105,\n26017,\n21351,\n25569,\n27779,\n24043,\n21596,\n38056,\n20044,\n27745,\n35820,\n23627,\n26080,\n33436,\n26791,\n21566,\n21556,\n27595,\n27494,\n20116,\n25410,\n21320,\n33310,\n20237,\n20398,\n22366,\n25098,\n38654,\n26212,\n29289,\n21247,\n21153,\n24735,\n35823,\n26132,\n29081,\n26512,\n35199,\n30802,\n30717,\n26224,\n22075,\n21560,\n38177,\n29306,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34725,\n34726,\n34727,\n34729,\n34730,\n34734,\n34736,\n34737,\n34738,\n34740,\n34742,\n34743,\n34744,\n34745,\n34747,\n34748,\n34750,\n34751,\n34753,\n34754,\n34755,\n34756,\n34757,\n34759,\n34760,\n34761,\n34764,\n34765,\n34766,\n34767,\n34768,\n34772,\n34773,\n34774,\n34775,\n34776,\n34777,\n34778,\n34780,\n34781,\n34782,\n34783,\n34785,\n34786,\n34787,\n34788,\n34790,\n34791,\n34792,\n34793,\n34795,\n34796,\n34797,\n34799,\n34800,\n34801,\n34802,\n34803,\n34804,\n34805,\n34806,\n34807,\n34808,\n0,\n34810,\n34811,\n34812,\n34813,\n34815,\n34816,\n34817,\n34818,\n34820,\n34821,\n34822,\n34823,\n34824,\n34825,\n34827,\n34828,\n34829,\n34830,\n34831,\n34832,\n34833,\n34834,\n34836,\n34839,\n34840,\n34841,\n34842,\n34844,\n34845,\n34846,\n34847,\n34848,\n34851,\n31232,\n24687,\n24076,\n24713,\n33181,\n22805,\n24796,\n29060,\n28911,\n28330,\n27728,\n29312,\n27268,\n34989,\n24109,\n20064,\n23219,\n21916,\n38115,\n27927,\n31995,\n38553,\n25103,\n32454,\n30606,\n34430,\n21283,\n38686,\n36758,\n26247,\n23777,\n20384,\n29421,\n19979,\n21414,\n22799,\n21523,\n25472,\n38184,\n20808,\n20185,\n40092,\n32420,\n21688,\n36132,\n34900,\n33335,\n38386,\n28046,\n24358,\n23244,\n26174,\n38505,\n29616,\n29486,\n21439,\n33146,\n39301,\n32673,\n23466,\n38519,\n38480,\n32447,\n30456,\n21410,\n38262,\n39321,\n31665,\n35140,\n28248,\n20065,\n32724,\n31077,\n35814,\n24819,\n21709,\n20139,\n39033,\n24055,\n27233,\n20687,\n21521,\n35937,\n33831,\n30813,\n38660,\n21066,\n21742,\n22179,\n38144,\n28040,\n23477,\n28102,\n26195,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34852,\n34853,\n34854,\n34855,\n34856,\n34857,\n34858,\n34859,\n34860,\n34861,\n34862,\n34863,\n34864,\n34865,\n34867,\n34868,\n34869,\n34870,\n34871,\n34872,\n34874,\n34875,\n34877,\n34878,\n34879,\n34881,\n34882,\n34883,\n34886,\n34887,\n34888,\n34889,\n34890,\n34891,\n34894,\n34895,\n34896,\n34897,\n34898,\n34899,\n34901,\n34902,\n34904,\n34906,\n34907,\n34908,\n34909,\n34910,\n34911,\n34912,\n34918,\n34919,\n34922,\n34925,\n34927,\n34929,\n34931,\n34932,\n34933,\n34934,\n34936,\n34937,\n34938,\n0,\n34939,\n34940,\n34944,\n34947,\n34950,\n34951,\n34953,\n34954,\n34956,\n34958,\n34959,\n34960,\n34961,\n34963,\n34964,\n34965,\n34967,\n34968,\n34969,\n34970,\n34971,\n34973,\n34974,\n34975,\n34976,\n34977,\n34979,\n34981,\n34982,\n34983,\n34984,\n34985,\n34986,\n23567,\n23389,\n26657,\n32918,\n21880,\n31505,\n25928,\n26964,\n20123,\n27463,\n34638,\n38795,\n21327,\n25375,\n25658,\n37034,\n26012,\n32961,\n35856,\n20889,\n26800,\n21368,\n34809,\n25032,\n27844,\n27899,\n35874,\n23633,\n34218,\n33455,\n38156,\n27427,\n36763,\n26032,\n24571,\n24515,\n20449,\n34885,\n26143,\n33125,\n29481,\n24826,\n20852,\n21009,\n22411,\n24418,\n37026,\n34892,\n37266,\n24184,\n26447,\n24615,\n22995,\n20804,\n20982,\n33016,\n21256,\n27769,\n38596,\n29066,\n20241,\n20462,\n32670,\n26429,\n21957,\n38152,\n31168,\n34966,\n32483,\n22687,\n25100,\n38656,\n34394,\n22040,\n39035,\n24464,\n35768,\n33988,\n37207,\n21465,\n26093,\n24207,\n30044,\n24676,\n32110,\n23167,\n32490,\n32493,\n36713,\n21927,\n23459,\n24748,\n26059,\n29572,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n34988,\n34990,\n34991,\n34992,\n34994,\n34995,\n34996,\n34997,\n34998,\n35000,\n35001,\n35002,\n35003,\n35005,\n35006,\n35007,\n35008,\n35011,\n35012,\n35015,\n35016,\n35018,\n35019,\n35020,\n35021,\n35023,\n35024,\n35025,\n35027,\n35030,\n35031,\n35034,\n35035,\n35036,\n35037,\n35038,\n35040,\n35041,\n35046,\n35047,\n35049,\n35050,\n35051,\n35052,\n35053,\n35054,\n35055,\n35058,\n35061,\n35062,\n35063,\n35066,\n35067,\n35069,\n35071,\n35072,\n35073,\n35075,\n35076,\n35077,\n35078,\n35079,\n35080,\n0,\n35081,\n35083,\n35084,\n35085,\n35086,\n35087,\n35089,\n35092,\n35093,\n35094,\n35095,\n35096,\n35100,\n35101,\n35102,\n35103,\n35104,\n35106,\n35107,\n35108,\n35110,\n35111,\n35112,\n35113,\n35116,\n35117,\n35118,\n35119,\n35121,\n35122,\n35123,\n35125,\n35127,\n36873,\n30307,\n30505,\n32474,\n38772,\n34203,\n23398,\n31348,\n38634,\n34880,\n21195,\n29071,\n24490,\n26092,\n35810,\n23547,\n39535,\n24033,\n27529,\n27739,\n35757,\n35759,\n36874,\n36805,\n21387,\n25276,\n40486,\n40493,\n21568,\n20011,\n33469,\n29273,\n34460,\n23830,\n34905,\n28079,\n38597,\n21713,\n20122,\n35766,\n28937,\n21693,\n38409,\n28895,\n28153,\n30416,\n20005,\n30740,\n34578,\n23721,\n24310,\n35328,\n39068,\n38414,\n28814,\n27839,\n22852,\n25513,\n30524,\n34893,\n28436,\n33395,\n22576,\n29141,\n21388,\n30746,\n38593,\n21761,\n24422,\n28976,\n23476,\n35866,\n39564,\n27523,\n22830,\n40495,\n31207,\n26472,\n25196,\n20335,\n30113,\n32650,\n27915,\n38451,\n27687,\n20208,\n30162,\n20859,\n26679,\n28478,\n36992,\n33136,\n22934,\n29814,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35128,\n35129,\n35130,\n35131,\n35132,\n35133,\n35134,\n35135,\n35136,\n35138,\n35139,\n35141,\n35142,\n35143,\n35144,\n35145,\n35146,\n35147,\n35148,\n35149,\n35150,\n35151,\n35152,\n35153,\n35154,\n35155,\n35156,\n35157,\n35158,\n35159,\n35160,\n35161,\n35162,\n35163,\n35164,\n35165,\n35168,\n35169,\n35170,\n35171,\n35172,\n35173,\n35175,\n35176,\n35177,\n35178,\n35179,\n35180,\n35181,\n35182,\n35183,\n35184,\n35185,\n35186,\n35187,\n35188,\n35189,\n35190,\n35191,\n35192,\n35193,\n35194,\n35196,\n0,\n35197,\n35198,\n35200,\n35202,\n35204,\n35205,\n35207,\n35208,\n35209,\n35210,\n35211,\n35212,\n35213,\n35214,\n35215,\n35216,\n35217,\n35218,\n35219,\n35220,\n35221,\n35222,\n35223,\n35224,\n35225,\n35226,\n35227,\n35228,\n35229,\n35230,\n35231,\n35232,\n35233,\n25671,\n23591,\n36965,\n31377,\n35875,\n23002,\n21676,\n33280,\n33647,\n35201,\n32768,\n26928,\n22094,\n32822,\n29239,\n37326,\n20918,\n20063,\n39029,\n25494,\n19994,\n21494,\n26355,\n33099,\n22812,\n28082,\n19968,\n22777,\n21307,\n25558,\n38129,\n20381,\n20234,\n34915,\n39056,\n22839,\n36951,\n31227,\n20202,\n33008,\n30097,\n27778,\n23452,\n23016,\n24413,\n26885,\n34433,\n20506,\n24050,\n20057,\n30691,\n20197,\n33402,\n25233,\n26131,\n37009,\n23673,\n20159,\n24441,\n33222,\n36920,\n32900,\n30123,\n20134,\n35028,\n24847,\n27589,\n24518,\n20041,\n30410,\n28322,\n35811,\n35758,\n35850,\n35793,\n24322,\n32764,\n32716,\n32462,\n33589,\n33643,\n22240,\n27575,\n38899,\n38452,\n23035,\n21535,\n38134,\n28139,\n23493,\n39278,\n23609,\n24341,\n38544,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35234,\n35235,\n35236,\n35237,\n35238,\n35239,\n35240,\n35241,\n35242,\n35243,\n35244,\n35245,\n35246,\n35247,\n35248,\n35249,\n35250,\n35251,\n35252,\n35253,\n35254,\n35255,\n35256,\n35257,\n35258,\n35259,\n35260,\n35261,\n35262,\n35263,\n35264,\n35267,\n35277,\n35283,\n35284,\n35285,\n35287,\n35288,\n35289,\n35291,\n35293,\n35295,\n35296,\n35297,\n35298,\n35300,\n35303,\n35304,\n35305,\n35306,\n35308,\n35309,\n35310,\n35312,\n35313,\n35314,\n35316,\n35317,\n35318,\n35319,\n35320,\n35321,\n35322,\n0,\n35323,\n35324,\n35325,\n35326,\n35327,\n35329,\n35330,\n35331,\n35332,\n35333,\n35334,\n35336,\n35337,\n35338,\n35339,\n35340,\n35341,\n35342,\n35343,\n35344,\n35345,\n35346,\n35347,\n35348,\n35349,\n35350,\n35351,\n35352,\n35353,\n35354,\n35355,\n35356,\n35357,\n21360,\n33521,\n27185,\n23156,\n40560,\n24212,\n32552,\n33721,\n33828,\n33829,\n33639,\n34631,\n36814,\n36194,\n30408,\n24433,\n39062,\n30828,\n26144,\n21727,\n25317,\n20323,\n33219,\n30152,\n24248,\n38605,\n36362,\n34553,\n21647,\n27891,\n28044,\n27704,\n24703,\n21191,\n29992,\n24189,\n20248,\n24736,\n24551,\n23588,\n30001,\n37038,\n38080,\n29369,\n27833,\n28216,\n37193,\n26377,\n21451,\n21491,\n20305,\n37321,\n35825,\n21448,\n24188,\n36802,\n28132,\n20110,\n30402,\n27014,\n34398,\n24858,\n33286,\n20313,\n20446,\n36926,\n40060,\n24841,\n28189,\n28180,\n38533,\n20104,\n23089,\n38632,\n19982,\n23679,\n31161,\n23431,\n35821,\n32701,\n29577,\n22495,\n33419,\n37057,\n21505,\n36935,\n21947,\n23786,\n24481,\n24840,\n27442,\n29425,\n32946,\n35465,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35358,\n35359,\n35360,\n35361,\n35362,\n35363,\n35364,\n35365,\n35366,\n35367,\n35368,\n35369,\n35370,\n35371,\n35372,\n35373,\n35374,\n35375,\n35376,\n35377,\n35378,\n35379,\n35380,\n35381,\n35382,\n35383,\n35384,\n35385,\n35386,\n35387,\n35388,\n35389,\n35391,\n35392,\n35393,\n35394,\n35395,\n35396,\n35397,\n35398,\n35399,\n35401,\n35402,\n35403,\n35404,\n35405,\n35406,\n35407,\n35408,\n35409,\n35410,\n35411,\n35412,\n35413,\n35414,\n35415,\n35416,\n35417,\n35418,\n35419,\n35420,\n35421,\n35422,\n0,\n35423,\n35424,\n35425,\n35426,\n35427,\n35428,\n35429,\n35430,\n35431,\n35432,\n35433,\n35434,\n35435,\n35436,\n35437,\n35438,\n35439,\n35440,\n35441,\n35442,\n35443,\n35444,\n35445,\n35446,\n35447,\n35448,\n35450,\n35451,\n35452,\n35453,\n35454,\n35455,\n35456,\n28020,\n23507,\n35029,\n39044,\n35947,\n39533,\n40499,\n28170,\n20900,\n20803,\n22435,\n34945,\n21407,\n25588,\n36757,\n22253,\n21592,\n22278,\n29503,\n28304,\n32536,\n36828,\n33489,\n24895,\n24616,\n38498,\n26352,\n32422,\n36234,\n36291,\n38053,\n23731,\n31908,\n26376,\n24742,\n38405,\n32792,\n20113,\n37095,\n21248,\n38504,\n20801,\n36816,\n34164,\n37213,\n26197,\n38901,\n23381,\n21277,\n30776,\n26434,\n26685,\n21705,\n28798,\n23472,\n36733,\n20877,\n22312,\n21681,\n25874,\n26242,\n36190,\n36163,\n33039,\n33900,\n36973,\n31967,\n20991,\n34299,\n26531,\n26089,\n28577,\n34468,\n36481,\n22122,\n36896,\n30338,\n28790,\n29157,\n36131,\n25321,\n21017,\n27901,\n36156,\n24590,\n22686,\n24974,\n26366,\n36192,\n25166,\n21939,\n28195,\n26413,\n36711,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35457,\n35458,\n35459,\n35460,\n35461,\n35462,\n35463,\n35464,\n35467,\n35468,\n35469,\n35470,\n35471,\n35472,\n35473,\n35474,\n35476,\n35477,\n35478,\n35479,\n35480,\n35481,\n35482,\n35483,\n35484,\n35485,\n35486,\n35487,\n35488,\n35489,\n35490,\n35491,\n35492,\n35493,\n35494,\n35495,\n35496,\n35497,\n35498,\n35499,\n35500,\n35501,\n35502,\n35503,\n35504,\n35505,\n35506,\n35507,\n35508,\n35509,\n35510,\n35511,\n35512,\n35513,\n35514,\n35515,\n35516,\n35517,\n35518,\n35519,\n35520,\n35521,\n35522,\n0,\n35523,\n35524,\n35525,\n35526,\n35527,\n35528,\n35529,\n35530,\n35531,\n35532,\n35533,\n35534,\n35535,\n35536,\n35537,\n35538,\n35539,\n35540,\n35541,\n35542,\n35543,\n35544,\n35545,\n35546,\n35547,\n35548,\n35549,\n35550,\n35551,\n35552,\n35553,\n35554,\n35555,\n38113,\n38392,\n30504,\n26629,\n27048,\n21643,\n20045,\n28856,\n35784,\n25688,\n25995,\n23429,\n31364,\n20538,\n23528,\n30651,\n27617,\n35449,\n31896,\n27838,\n30415,\n26025,\n36759,\n23853,\n23637,\n34360,\n26632,\n21344,\n25112,\n31449,\n28251,\n32509,\n27167,\n31456,\n24432,\n28467,\n24352,\n25484,\n28072,\n26454,\n19976,\n24080,\n36134,\n20183,\n32960,\n30260,\n38556,\n25307,\n26157,\n25214,\n27836,\n36213,\n29031,\n32617,\n20806,\n32903,\n21484,\n36974,\n25240,\n21746,\n34544,\n36761,\n32773,\n38167,\n34071,\n36825,\n27993,\n29645,\n26015,\n30495,\n29956,\n30759,\n33275,\n36126,\n38024,\n20390,\n26517,\n30137,\n35786,\n38663,\n25391,\n38215,\n38453,\n33976,\n25379,\n30529,\n24449,\n29424,\n20105,\n24596,\n25972,\n25327,\n27491,\n25919,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35556,\n35557,\n35558,\n35559,\n35560,\n35561,\n35562,\n35563,\n35564,\n35565,\n35566,\n35567,\n35568,\n35569,\n35570,\n35571,\n35572,\n35573,\n35574,\n35575,\n35576,\n35577,\n35578,\n35579,\n35580,\n35581,\n35582,\n35583,\n35584,\n35585,\n35586,\n35587,\n35588,\n35589,\n35590,\n35592,\n35593,\n35594,\n35595,\n35596,\n35597,\n35598,\n35599,\n35600,\n35601,\n35602,\n35603,\n35604,\n35605,\n35606,\n35607,\n35608,\n35609,\n35610,\n35611,\n35612,\n35613,\n35614,\n35615,\n35616,\n35617,\n35618,\n35619,\n0,\n35620,\n35621,\n35623,\n35624,\n35625,\n35626,\n35627,\n35628,\n35629,\n35630,\n35631,\n35632,\n35633,\n35634,\n35635,\n35636,\n35637,\n35638,\n35639,\n35640,\n35641,\n35642,\n35643,\n35644,\n35645,\n35646,\n35647,\n35648,\n35649,\n35650,\n35651,\n35652,\n35653,\n24103,\n30151,\n37073,\n35777,\n33437,\n26525,\n25903,\n21553,\n34584,\n30693,\n32930,\n33026,\n27713,\n20043,\n32455,\n32844,\n30452,\n26893,\n27542,\n25191,\n20540,\n20356,\n22336,\n25351,\n27490,\n36286,\n21482,\n26088,\n32440,\n24535,\n25370,\n25527,\n33267,\n33268,\n32622,\n24092,\n23769,\n21046,\n26234,\n31209,\n31258,\n36136,\n28825,\n30164,\n28382,\n27835,\n31378,\n20013,\n30405,\n24544,\n38047,\n34935,\n32456,\n31181,\n32959,\n37325,\n20210,\n20247,\n33311,\n21608,\n24030,\n27954,\n35788,\n31909,\n36724,\n32920,\n24090,\n21650,\n30385,\n23449,\n26172,\n39588,\n29664,\n26666,\n34523,\n26417,\n29482,\n35832,\n35803,\n36880,\n31481,\n28891,\n29038,\n25284,\n30633,\n22065,\n20027,\n33879,\n26609,\n21161,\n34496,\n36142,\n38136,\n31569,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35654,\n35655,\n35656,\n35657,\n35658,\n35659,\n35660,\n35661,\n35662,\n35663,\n35664,\n35665,\n35666,\n35667,\n35668,\n35669,\n35670,\n35671,\n35672,\n35673,\n35674,\n35675,\n35676,\n35677,\n35678,\n35679,\n35680,\n35681,\n35682,\n35683,\n35684,\n35685,\n35687,\n35688,\n35689,\n35690,\n35691,\n35693,\n35694,\n35695,\n35696,\n35697,\n35698,\n35699,\n35700,\n35701,\n35702,\n35703,\n35704,\n35705,\n35706,\n35707,\n35708,\n35709,\n35710,\n35711,\n35712,\n35713,\n35714,\n35715,\n35716,\n35717,\n35718,\n0,\n35719,\n35720,\n35721,\n35722,\n35723,\n35724,\n35725,\n35726,\n35727,\n35728,\n35729,\n35730,\n35731,\n35732,\n35733,\n35734,\n35735,\n35736,\n35737,\n35738,\n35739,\n35740,\n35741,\n35742,\n35743,\n35756,\n35761,\n35771,\n35783,\n35792,\n35818,\n35849,\n35870,\n20303,\n27880,\n31069,\n39547,\n25235,\n29226,\n25341,\n19987,\n30742,\n36716,\n25776,\n36186,\n31686,\n26729,\n24196,\n35013,\n22918,\n25758,\n22766,\n29366,\n26894,\n38181,\n36861,\n36184,\n22368,\n32512,\n35846,\n20934,\n25417,\n25305,\n21331,\n26700,\n29730,\n33537,\n37196,\n21828,\n30528,\n28796,\n27978,\n20857,\n21672,\n36164,\n23039,\n28363,\n28100,\n23388,\n32043,\n20180,\n31869,\n28371,\n23376,\n33258,\n28173,\n23383,\n39683,\n26837,\n36394,\n23447,\n32508,\n24635,\n32437,\n37049,\n36208,\n22863,\n25549,\n31199,\n36275,\n21330,\n26063,\n31062,\n35781,\n38459,\n32452,\n38075,\n32386,\n22068,\n37257,\n26368,\n32618,\n23562,\n36981,\n26152,\n24038,\n20304,\n26590,\n20570,\n20316,\n22352,\n24231,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n35896,\n35897,\n35898,\n35899,\n35900,\n35901,\n35902,\n35903,\n35904,\n35906,\n35907,\n35908,\n35909,\n35912,\n35914,\n35915,\n35917,\n35918,\n35919,\n35920,\n35921,\n35922,\n35923,\n35924,\n35926,\n35927,\n35928,\n35929,\n35931,\n35932,\n35933,\n35934,\n35935,\n35936,\n35939,\n35940,\n35941,\n35942,\n35943,\n35944,\n35945,\n35948,\n35949,\n35950,\n35951,\n35952,\n35953,\n35954,\n35956,\n35957,\n35958,\n35959,\n35963,\n35964,\n35965,\n35966,\n35967,\n35968,\n35969,\n35971,\n35972,\n35974,\n35975,\n0,\n35976,\n35979,\n35981,\n35982,\n35983,\n35984,\n35985,\n35986,\n35987,\n35989,\n35990,\n35991,\n35993,\n35994,\n35995,\n35996,\n35997,\n35998,\n35999,\n36000,\n36001,\n36002,\n36003,\n36004,\n36005,\n36006,\n36007,\n36008,\n36009,\n36010,\n36011,\n36012,\n36013,\n20109,\n19980,\n20800,\n19984,\n24319,\n21317,\n19989,\n20120,\n19998,\n39730,\n23404,\n22121,\n20008,\n31162,\n20031,\n21269,\n20039,\n22829,\n29243,\n21358,\n27664,\n22239,\n32996,\n39319,\n27603,\n30590,\n40727,\n20022,\n20127,\n40720,\n20060,\n20073,\n20115,\n33416,\n23387,\n21868,\n22031,\n20164,\n21389,\n21405,\n21411,\n21413,\n21422,\n38757,\n36189,\n21274,\n21493,\n21286,\n21294,\n21310,\n36188,\n21350,\n21347,\n20994,\n21000,\n21006,\n21037,\n21043,\n21055,\n21056,\n21068,\n21086,\n21089,\n21084,\n33967,\n21117,\n21122,\n21121,\n21136,\n21139,\n20866,\n32596,\n20155,\n20163,\n20169,\n20162,\n20200,\n20193,\n20203,\n20190,\n20251,\n20211,\n20258,\n20324,\n20213,\n20261,\n20263,\n20233,\n20267,\n20318,\n20327,\n25912,\n20314,\n20317,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36014,\n36015,\n36016,\n36017,\n36018,\n36019,\n36020,\n36021,\n36022,\n36023,\n36024,\n36025,\n36026,\n36027,\n36028,\n36029,\n36030,\n36031,\n36032,\n36033,\n36034,\n36035,\n36036,\n36037,\n36038,\n36039,\n36040,\n36041,\n36042,\n36043,\n36044,\n36045,\n36046,\n36047,\n36048,\n36049,\n36050,\n36051,\n36052,\n36053,\n36054,\n36055,\n36056,\n36057,\n36058,\n36059,\n36060,\n36061,\n36062,\n36063,\n36064,\n36065,\n36066,\n36067,\n36068,\n36069,\n36070,\n36071,\n36072,\n36073,\n36074,\n36075,\n36076,\n0,\n36077,\n36078,\n36079,\n36080,\n36081,\n36082,\n36083,\n36084,\n36085,\n36086,\n36087,\n36088,\n36089,\n36090,\n36091,\n36092,\n36093,\n36094,\n36095,\n36096,\n36097,\n36098,\n36099,\n36100,\n36101,\n36102,\n36103,\n36104,\n36105,\n36106,\n36107,\n36108,\n36109,\n20319,\n20311,\n20274,\n20285,\n20342,\n20340,\n20369,\n20361,\n20355,\n20367,\n20350,\n20347,\n20394,\n20348,\n20396,\n20372,\n20454,\n20456,\n20458,\n20421,\n20442,\n20451,\n20444,\n20433,\n20447,\n20472,\n20521,\n20556,\n20467,\n20524,\n20495,\n20526,\n20525,\n20478,\n20508,\n20492,\n20517,\n20520,\n20606,\n20547,\n20565,\n20552,\n20558,\n20588,\n20603,\n20645,\n20647,\n20649,\n20666,\n20694,\n20742,\n20717,\n20716,\n20710,\n20718,\n20743,\n20747,\n20189,\n27709,\n20312,\n20325,\n20430,\n40864,\n27718,\n31860,\n20846,\n24061,\n40649,\n39320,\n20865,\n22804,\n21241,\n21261,\n35335,\n21264,\n20971,\n22809,\n20821,\n20128,\n20822,\n20147,\n34926,\n34980,\n20149,\n33044,\n35026,\n31104,\n23348,\n34819,\n32696,\n20907,\n20913,\n20925,\n20924,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36110,\n36111,\n36112,\n36113,\n36114,\n36115,\n36116,\n36117,\n36118,\n36119,\n36120,\n36121,\n36122,\n36123,\n36124,\n36128,\n36177,\n36178,\n36183,\n36191,\n36197,\n36200,\n36201,\n36202,\n36204,\n36206,\n36207,\n36209,\n36210,\n36216,\n36217,\n36218,\n36219,\n36220,\n36221,\n36222,\n36223,\n36224,\n36226,\n36227,\n36230,\n36231,\n36232,\n36233,\n36236,\n36237,\n36238,\n36239,\n36240,\n36242,\n36243,\n36245,\n36246,\n36247,\n36248,\n36249,\n36250,\n36251,\n36252,\n36253,\n36254,\n36256,\n36257,\n0,\n36258,\n36260,\n36261,\n36262,\n36263,\n36264,\n36265,\n36266,\n36267,\n36268,\n36269,\n36270,\n36271,\n36272,\n36274,\n36278,\n36279,\n36281,\n36283,\n36285,\n36288,\n36289,\n36290,\n36293,\n36295,\n36296,\n36297,\n36298,\n36301,\n36304,\n36306,\n36307,\n36308,\n20935,\n20886,\n20898,\n20901,\n35744,\n35750,\n35751,\n35754,\n35764,\n35765,\n35767,\n35778,\n35779,\n35787,\n35791,\n35790,\n35794,\n35795,\n35796,\n35798,\n35800,\n35801,\n35804,\n35807,\n35808,\n35812,\n35816,\n35817,\n35822,\n35824,\n35827,\n35830,\n35833,\n35836,\n35839,\n35840,\n35842,\n35844,\n35847,\n35852,\n35855,\n35857,\n35858,\n35860,\n35861,\n35862,\n35865,\n35867,\n35864,\n35869,\n35871,\n35872,\n35873,\n35877,\n35879,\n35882,\n35883,\n35886,\n35887,\n35890,\n35891,\n35893,\n35894,\n21353,\n21370,\n38429,\n38434,\n38433,\n38449,\n38442,\n38461,\n38460,\n38466,\n38473,\n38484,\n38495,\n38503,\n38508,\n38514,\n38516,\n38536,\n38541,\n38551,\n38576,\n37015,\n37019,\n37021,\n37017,\n37036,\n37025,\n37044,\n37043,\n37046,\n37050,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36309,\n36312,\n36313,\n36316,\n36320,\n36321,\n36322,\n36325,\n36326,\n36327,\n36329,\n36333,\n36334,\n36336,\n36337,\n36338,\n36340,\n36342,\n36348,\n36350,\n36351,\n36352,\n36353,\n36354,\n36355,\n36356,\n36358,\n36359,\n36360,\n36363,\n36365,\n36366,\n36368,\n36369,\n36370,\n36371,\n36373,\n36374,\n36375,\n36376,\n36377,\n36378,\n36379,\n36380,\n36384,\n36385,\n36388,\n36389,\n36390,\n36391,\n36392,\n36395,\n36397,\n36400,\n36402,\n36403,\n36404,\n36406,\n36407,\n36408,\n36411,\n36412,\n36414,\n0,\n36415,\n36419,\n36421,\n36422,\n36428,\n36429,\n36430,\n36431,\n36432,\n36435,\n36436,\n36437,\n36438,\n36439,\n36440,\n36442,\n36443,\n36444,\n36445,\n36446,\n36447,\n36448,\n36449,\n36450,\n36451,\n36452,\n36453,\n36455,\n36456,\n36458,\n36459,\n36462,\n36465,\n37048,\n37040,\n37071,\n37061,\n37054,\n37072,\n37060,\n37063,\n37075,\n37094,\n37090,\n37084,\n37079,\n37083,\n37099,\n37103,\n37118,\n37124,\n37154,\n37150,\n37155,\n37169,\n37167,\n37177,\n37187,\n37190,\n21005,\n22850,\n21154,\n21164,\n21165,\n21182,\n21759,\n21200,\n21206,\n21232,\n21471,\n29166,\n30669,\n24308,\n20981,\n20988,\n39727,\n21430,\n24321,\n30042,\n24047,\n22348,\n22441,\n22433,\n22654,\n22716,\n22725,\n22737,\n22313,\n22316,\n22314,\n22323,\n22329,\n22318,\n22319,\n22364,\n22331,\n22338,\n22377,\n22405,\n22379,\n22406,\n22396,\n22395,\n22376,\n22381,\n22390,\n22387,\n22445,\n22436,\n22412,\n22450,\n22479,\n22439,\n22452,\n22419,\n22432,\n22485,\n22488,\n22490,\n22489,\n22482,\n22456,\n22516,\n22511,\n22520,\n22500,\n22493,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36467,\n36469,\n36471,\n36472,\n36473,\n36474,\n36475,\n36477,\n36478,\n36480,\n36482,\n36483,\n36484,\n36486,\n36488,\n36489,\n36490,\n36491,\n36492,\n36493,\n36494,\n36497,\n36498,\n36499,\n36501,\n36502,\n36503,\n36504,\n36505,\n36506,\n36507,\n36509,\n36511,\n36512,\n36513,\n36514,\n36515,\n36516,\n36517,\n36518,\n36519,\n36520,\n36521,\n36522,\n36525,\n36526,\n36528,\n36529,\n36531,\n36532,\n36533,\n36534,\n36535,\n36536,\n36537,\n36539,\n36540,\n36541,\n36542,\n36543,\n36544,\n36545,\n36546,\n0,\n36547,\n36548,\n36549,\n36550,\n36551,\n36552,\n36553,\n36554,\n36555,\n36556,\n36557,\n36559,\n36560,\n36561,\n36562,\n36563,\n36564,\n36565,\n36566,\n36567,\n36568,\n36569,\n36570,\n36571,\n36572,\n36573,\n36574,\n36575,\n36576,\n36577,\n36578,\n36579,\n36580,\n22539,\n22541,\n22525,\n22509,\n22528,\n22558,\n22553,\n22596,\n22560,\n22629,\n22636,\n22657,\n22665,\n22682,\n22656,\n39336,\n40729,\n25087,\n33401,\n33405,\n33407,\n33423,\n33418,\n33448,\n33412,\n33422,\n33425,\n33431,\n33433,\n33451,\n33464,\n33470,\n33456,\n33480,\n33482,\n33507,\n33432,\n33463,\n33454,\n33483,\n33484,\n33473,\n33449,\n33460,\n33441,\n33450,\n33439,\n33476,\n33486,\n33444,\n33505,\n33545,\n33527,\n33508,\n33551,\n33543,\n33500,\n33524,\n33490,\n33496,\n33548,\n33531,\n33491,\n33553,\n33562,\n33542,\n33556,\n33557,\n33504,\n33493,\n33564,\n33617,\n33627,\n33628,\n33544,\n33682,\n33596,\n33588,\n33585,\n33691,\n33630,\n33583,\n33615,\n33607,\n33603,\n33631,\n33600,\n33559,\n33632,\n33581,\n33594,\n33587,\n33638,\n33637,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36581,\n36582,\n36583,\n36584,\n36585,\n36586,\n36587,\n36588,\n36589,\n36590,\n36591,\n36592,\n36593,\n36594,\n36595,\n36596,\n36597,\n36598,\n36599,\n36600,\n36601,\n36602,\n36603,\n36604,\n36605,\n36606,\n36607,\n36608,\n36609,\n36610,\n36611,\n36612,\n36613,\n36614,\n36615,\n36616,\n36617,\n36618,\n36619,\n36620,\n36621,\n36622,\n36623,\n36624,\n36625,\n36626,\n36627,\n36628,\n36629,\n36630,\n36631,\n36632,\n36633,\n36634,\n36635,\n36636,\n36637,\n36638,\n36639,\n36640,\n36641,\n36642,\n36643,\n0,\n36644,\n36645,\n36646,\n36647,\n36648,\n36649,\n36650,\n36651,\n36652,\n36653,\n36654,\n36655,\n36656,\n36657,\n36658,\n36659,\n36660,\n36661,\n36662,\n36663,\n36664,\n36665,\n36666,\n36667,\n36668,\n36669,\n36670,\n36671,\n36672,\n36673,\n36674,\n36675,\n36676,\n33640,\n33563,\n33641,\n33644,\n33642,\n33645,\n33646,\n33712,\n33656,\n33715,\n33716,\n33696,\n33706,\n33683,\n33692,\n33669,\n33660,\n33718,\n33705,\n33661,\n33720,\n33659,\n33688,\n33694,\n33704,\n33722,\n33724,\n33729,\n33793,\n33765,\n33752,\n22535,\n33816,\n33803,\n33757,\n33789,\n33750,\n33820,\n33848,\n33809,\n33798,\n33748,\n33759,\n33807,\n33795,\n33784,\n33785,\n33770,\n33733,\n33728,\n33830,\n33776,\n33761,\n33884,\n33873,\n33882,\n33881,\n33907,\n33927,\n33928,\n33914,\n33929,\n33912,\n33852,\n33862,\n33897,\n33910,\n33932,\n33934,\n33841,\n33901,\n33985,\n33997,\n34000,\n34022,\n33981,\n34003,\n33994,\n33983,\n33978,\n34016,\n33953,\n33977,\n33972,\n33943,\n34021,\n34019,\n34060,\n29965,\n34104,\n34032,\n34105,\n34079,\n34106,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36677,\n36678,\n36679,\n36680,\n36681,\n36682,\n36683,\n36684,\n36685,\n36686,\n36687,\n36688,\n36689,\n36690,\n36691,\n36692,\n36693,\n36694,\n36695,\n36696,\n36697,\n36698,\n36699,\n36700,\n36701,\n36702,\n36703,\n36704,\n36705,\n36706,\n36707,\n36708,\n36709,\n36714,\n36736,\n36748,\n36754,\n36765,\n36768,\n36769,\n36770,\n36772,\n36773,\n36774,\n36775,\n36778,\n36780,\n36781,\n36782,\n36783,\n36786,\n36787,\n36788,\n36789,\n36791,\n36792,\n36794,\n36795,\n36796,\n36799,\n36800,\n36803,\n36806,\n0,\n36809,\n36810,\n36811,\n36812,\n36813,\n36815,\n36818,\n36822,\n36823,\n36826,\n36832,\n36833,\n36835,\n36839,\n36844,\n36847,\n36849,\n36850,\n36852,\n36853,\n36854,\n36858,\n36859,\n36860,\n36862,\n36863,\n36871,\n36872,\n36876,\n36878,\n36883,\n36885,\n36888,\n34134,\n34107,\n34047,\n34044,\n34137,\n34120,\n34152,\n34148,\n34142,\n34170,\n30626,\n34115,\n34162,\n34171,\n34212,\n34216,\n34183,\n34191,\n34169,\n34222,\n34204,\n34181,\n34233,\n34231,\n34224,\n34259,\n34241,\n34268,\n34303,\n34343,\n34309,\n34345,\n34326,\n34364,\n24318,\n24328,\n22844,\n22849,\n32823,\n22869,\n22874,\n22872,\n21263,\n23586,\n23589,\n23596,\n23604,\n25164,\n25194,\n25247,\n25275,\n25290,\n25306,\n25303,\n25326,\n25378,\n25334,\n25401,\n25419,\n25411,\n25517,\n25590,\n25457,\n25466,\n25486,\n25524,\n25453,\n25516,\n25482,\n25449,\n25518,\n25532,\n25586,\n25592,\n25568,\n25599,\n25540,\n25566,\n25550,\n25682,\n25542,\n25534,\n25669,\n25665,\n25611,\n25627,\n25632,\n25612,\n25638,\n25633,\n25694,\n25732,\n25709,\n25750,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n36889,\n36892,\n36899,\n36900,\n36901,\n36903,\n36904,\n36905,\n36906,\n36907,\n36908,\n36912,\n36913,\n36914,\n36915,\n36916,\n36919,\n36921,\n36922,\n36925,\n36927,\n36928,\n36931,\n36933,\n36934,\n36936,\n36937,\n36938,\n36939,\n36940,\n36942,\n36948,\n36949,\n36950,\n36953,\n36954,\n36956,\n36957,\n36958,\n36959,\n36960,\n36961,\n36964,\n36966,\n36967,\n36969,\n36970,\n36971,\n36972,\n36975,\n36976,\n36977,\n36978,\n36979,\n36982,\n36983,\n36984,\n36985,\n36986,\n36987,\n36988,\n36990,\n36993,\n0,\n36996,\n36997,\n36998,\n36999,\n37001,\n37002,\n37004,\n37005,\n37006,\n37007,\n37008,\n37010,\n37012,\n37014,\n37016,\n37018,\n37020,\n37022,\n37023,\n37024,\n37028,\n37029,\n37031,\n37032,\n37033,\n37035,\n37037,\n37042,\n37047,\n37052,\n37053,\n37055,\n37056,\n25722,\n25783,\n25784,\n25753,\n25786,\n25792,\n25808,\n25815,\n25828,\n25826,\n25865,\n25893,\n25902,\n24331,\n24530,\n29977,\n24337,\n21343,\n21489,\n21501,\n21481,\n21480,\n21499,\n21522,\n21526,\n21510,\n21579,\n21586,\n21587,\n21588,\n21590,\n21571,\n21537,\n21591,\n21593,\n21539,\n21554,\n21634,\n21652,\n21623,\n21617,\n21604,\n21658,\n21659,\n21636,\n21622,\n21606,\n21661,\n21712,\n21677,\n21698,\n21684,\n21714,\n21671,\n21670,\n21715,\n21716,\n21618,\n21667,\n21717,\n21691,\n21695,\n21708,\n21721,\n21722,\n21724,\n21673,\n21674,\n21668,\n21725,\n21711,\n21726,\n21787,\n21735,\n21792,\n21757,\n21780,\n21747,\n21794,\n21795,\n21775,\n21777,\n21799,\n21802,\n21863,\n21903,\n21941,\n21833,\n21869,\n21825,\n21845,\n21823,\n21840,\n21820,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37058,\n37059,\n37062,\n37064,\n37065,\n37067,\n37068,\n37069,\n37074,\n37076,\n37077,\n37078,\n37080,\n37081,\n37082,\n37086,\n37087,\n37088,\n37091,\n37092,\n37093,\n37097,\n37098,\n37100,\n37102,\n37104,\n37105,\n37106,\n37107,\n37109,\n37110,\n37111,\n37113,\n37114,\n37115,\n37116,\n37119,\n37120,\n37121,\n37123,\n37125,\n37126,\n37127,\n37128,\n37129,\n37130,\n37131,\n37132,\n37133,\n37134,\n37135,\n37136,\n37137,\n37138,\n37139,\n37140,\n37141,\n37142,\n37143,\n37144,\n37146,\n37147,\n37148,\n0,\n37149,\n37151,\n37152,\n37153,\n37156,\n37157,\n37158,\n37159,\n37160,\n37161,\n37162,\n37163,\n37164,\n37165,\n37166,\n37168,\n37170,\n37171,\n37172,\n37173,\n37174,\n37175,\n37176,\n37178,\n37179,\n37180,\n37181,\n37182,\n37183,\n37184,\n37185,\n37186,\n37188,\n21815,\n21846,\n21877,\n21878,\n21879,\n21811,\n21808,\n21852,\n21899,\n21970,\n21891,\n21937,\n21945,\n21896,\n21889,\n21919,\n21886,\n21974,\n21905,\n21883,\n21983,\n21949,\n21950,\n21908,\n21913,\n21994,\n22007,\n21961,\n22047,\n21969,\n21995,\n21996,\n21972,\n21990,\n21981,\n21956,\n21999,\n21989,\n22002,\n22003,\n21964,\n21965,\n21992,\n22005,\n21988,\n36756,\n22046,\n22024,\n22028,\n22017,\n22052,\n22051,\n22014,\n22016,\n22055,\n22061,\n22104,\n22073,\n22103,\n22060,\n22093,\n22114,\n22105,\n22108,\n22092,\n22100,\n22150,\n22116,\n22129,\n22123,\n22139,\n22140,\n22149,\n22163,\n22191,\n22228,\n22231,\n22237,\n22241,\n22261,\n22251,\n22265,\n22271,\n22276,\n22282,\n22281,\n22300,\n24079,\n24089,\n24084,\n24081,\n24113,\n24123,\n24124,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37189,\n37191,\n37192,\n37201,\n37203,\n37204,\n37205,\n37206,\n37208,\n37209,\n37211,\n37212,\n37215,\n37216,\n37222,\n37223,\n37224,\n37227,\n37229,\n37235,\n37242,\n37243,\n37244,\n37248,\n37249,\n37250,\n37251,\n37252,\n37254,\n37256,\n37258,\n37262,\n37263,\n37267,\n37268,\n37269,\n37270,\n37271,\n37272,\n37273,\n37276,\n37277,\n37278,\n37279,\n37280,\n37281,\n37284,\n37285,\n37286,\n37287,\n37288,\n37289,\n37291,\n37292,\n37296,\n37297,\n37298,\n37299,\n37302,\n37303,\n37304,\n37305,\n37307,\n0,\n37308,\n37309,\n37310,\n37311,\n37312,\n37313,\n37314,\n37315,\n37316,\n37317,\n37318,\n37320,\n37323,\n37328,\n37330,\n37331,\n37332,\n37333,\n37334,\n37335,\n37336,\n37337,\n37338,\n37339,\n37341,\n37342,\n37343,\n37344,\n37345,\n37346,\n37347,\n37348,\n37349,\n24119,\n24132,\n24148,\n24155,\n24158,\n24161,\n23692,\n23674,\n23693,\n23696,\n23702,\n23688,\n23704,\n23705,\n23697,\n23706,\n23708,\n23733,\n23714,\n23741,\n23724,\n23723,\n23729,\n23715,\n23745,\n23735,\n23748,\n23762,\n23780,\n23755,\n23781,\n23810,\n23811,\n23847,\n23846,\n23854,\n23844,\n23838,\n23814,\n23835,\n23896,\n23870,\n23860,\n23869,\n23916,\n23899,\n23919,\n23901,\n23915,\n23883,\n23882,\n23913,\n23924,\n23938,\n23961,\n23965,\n35955,\n23991,\n24005,\n24435,\n24439,\n24450,\n24455,\n24457,\n24460,\n24469,\n24473,\n24476,\n24488,\n24493,\n24501,\n24508,\n34914,\n24417,\n29357,\n29360,\n29364,\n29367,\n29368,\n29379,\n29377,\n29390,\n29389,\n29394,\n29416,\n29423,\n29417,\n29426,\n29428,\n29431,\n29441,\n29427,\n29443,\n29434,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37350,\n37351,\n37352,\n37353,\n37354,\n37355,\n37356,\n37357,\n37358,\n37359,\n37360,\n37361,\n37362,\n37363,\n37364,\n37365,\n37366,\n37367,\n37368,\n37369,\n37370,\n37371,\n37372,\n37373,\n37374,\n37375,\n37376,\n37377,\n37378,\n37379,\n37380,\n37381,\n37382,\n37383,\n37384,\n37385,\n37386,\n37387,\n37388,\n37389,\n37390,\n37391,\n37392,\n37393,\n37394,\n37395,\n37396,\n37397,\n37398,\n37399,\n37400,\n37401,\n37402,\n37403,\n37404,\n37405,\n37406,\n37407,\n37408,\n37409,\n37410,\n37411,\n37412,\n0,\n37413,\n37414,\n37415,\n37416,\n37417,\n37418,\n37419,\n37420,\n37421,\n37422,\n37423,\n37424,\n37425,\n37426,\n37427,\n37428,\n37429,\n37430,\n37431,\n37432,\n37433,\n37434,\n37435,\n37436,\n37437,\n37438,\n37439,\n37440,\n37441,\n37442,\n37443,\n37444,\n37445,\n29435,\n29463,\n29459,\n29473,\n29450,\n29470,\n29469,\n29461,\n29474,\n29497,\n29477,\n29484,\n29496,\n29489,\n29520,\n29517,\n29527,\n29536,\n29548,\n29551,\n29566,\n33307,\n22821,\n39143,\n22820,\n22786,\n39267,\n39271,\n39272,\n39273,\n39274,\n39275,\n39276,\n39284,\n39287,\n39293,\n39296,\n39300,\n39303,\n39306,\n39309,\n39312,\n39313,\n39315,\n39316,\n39317,\n24192,\n24209,\n24203,\n24214,\n24229,\n24224,\n24249,\n24245,\n24254,\n24243,\n36179,\n24274,\n24273,\n24283,\n24296,\n24298,\n33210,\n24516,\n24521,\n24534,\n24527,\n24579,\n24558,\n24580,\n24545,\n24548,\n24574,\n24581,\n24582,\n24554,\n24557,\n24568,\n24601,\n24629,\n24614,\n24603,\n24591,\n24589,\n24617,\n24619,\n24586,\n24639,\n24609,\n24696,\n24697,\n24699,\n24698,\n24642,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37446,\n37447,\n37448,\n37449,\n37450,\n37451,\n37452,\n37453,\n37454,\n37455,\n37456,\n37457,\n37458,\n37459,\n37460,\n37461,\n37462,\n37463,\n37464,\n37465,\n37466,\n37467,\n37468,\n37469,\n37470,\n37471,\n37472,\n37473,\n37474,\n37475,\n37476,\n37477,\n37478,\n37479,\n37480,\n37481,\n37482,\n37483,\n37484,\n37485,\n37486,\n37487,\n37488,\n37489,\n37490,\n37491,\n37493,\n37494,\n37495,\n37496,\n37497,\n37498,\n37499,\n37500,\n37501,\n37502,\n37503,\n37504,\n37505,\n37506,\n37507,\n37508,\n37509,\n0,\n37510,\n37511,\n37512,\n37513,\n37514,\n37515,\n37516,\n37517,\n37519,\n37520,\n37521,\n37522,\n37523,\n37524,\n37525,\n37526,\n37527,\n37528,\n37529,\n37530,\n37531,\n37532,\n37533,\n37534,\n37535,\n37536,\n37537,\n37538,\n37539,\n37540,\n37541,\n37542,\n37543,\n24682,\n24701,\n24726,\n24730,\n24749,\n24733,\n24707,\n24722,\n24716,\n24731,\n24812,\n24763,\n24753,\n24797,\n24792,\n24774,\n24794,\n24756,\n24864,\n24870,\n24853,\n24867,\n24820,\n24832,\n24846,\n24875,\n24906,\n24949,\n25004,\n24980,\n24999,\n25015,\n25044,\n25077,\n24541,\n38579,\n38377,\n38379,\n38385,\n38387,\n38389,\n38390,\n38396,\n38398,\n38403,\n38404,\n38406,\n38408,\n38410,\n38411,\n38412,\n38413,\n38415,\n38418,\n38421,\n38422,\n38423,\n38425,\n38426,\n20012,\n29247,\n25109,\n27701,\n27732,\n27740,\n27722,\n27811,\n27781,\n27792,\n27796,\n27788,\n27752,\n27753,\n27764,\n27766,\n27782,\n27817,\n27856,\n27860,\n27821,\n27895,\n27896,\n27889,\n27863,\n27826,\n27872,\n27862,\n27898,\n27883,\n27886,\n27825,\n27859,\n27887,\n27902,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37544,\n37545,\n37546,\n37547,\n37548,\n37549,\n37551,\n37552,\n37553,\n37554,\n37555,\n37556,\n37557,\n37558,\n37559,\n37560,\n37561,\n37562,\n37563,\n37564,\n37565,\n37566,\n37567,\n37568,\n37569,\n37570,\n37571,\n37572,\n37573,\n37574,\n37575,\n37577,\n37578,\n37579,\n37580,\n37581,\n37582,\n37583,\n37584,\n37585,\n37586,\n37587,\n37588,\n37589,\n37590,\n37591,\n37592,\n37593,\n37594,\n37595,\n37596,\n37597,\n37598,\n37599,\n37600,\n37601,\n37602,\n37603,\n37604,\n37605,\n37606,\n37607,\n37608,\n0,\n37609,\n37610,\n37611,\n37612,\n37613,\n37614,\n37615,\n37616,\n37617,\n37618,\n37619,\n37620,\n37621,\n37622,\n37623,\n37624,\n37625,\n37626,\n37627,\n37628,\n37629,\n37630,\n37631,\n37632,\n37633,\n37634,\n37635,\n37636,\n37637,\n37638,\n37639,\n37640,\n37641,\n27961,\n27943,\n27916,\n27971,\n27976,\n27911,\n27908,\n27929,\n27918,\n27947,\n27981,\n27950,\n27957,\n27930,\n27983,\n27986,\n27988,\n27955,\n28049,\n28015,\n28062,\n28064,\n27998,\n28051,\n28052,\n27996,\n28000,\n28028,\n28003,\n28186,\n28103,\n28101,\n28126,\n28174,\n28095,\n28128,\n28177,\n28134,\n28125,\n28121,\n28182,\n28075,\n28172,\n28078,\n28203,\n28270,\n28238,\n28267,\n28338,\n28255,\n28294,\n28243,\n28244,\n28210,\n28197,\n28228,\n28383,\n28337,\n28312,\n28384,\n28461,\n28386,\n28325,\n28327,\n28349,\n28347,\n28343,\n28375,\n28340,\n28367,\n28303,\n28354,\n28319,\n28514,\n28486,\n28487,\n28452,\n28437,\n28409,\n28463,\n28470,\n28491,\n28532,\n28458,\n28425,\n28457,\n28553,\n28557,\n28556,\n28536,\n28530,\n28540,\n28538,\n28625,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37642,\n37643,\n37644,\n37645,\n37646,\n37647,\n37648,\n37649,\n37650,\n37651,\n37652,\n37653,\n37654,\n37655,\n37656,\n37657,\n37658,\n37659,\n37660,\n37661,\n37662,\n37663,\n37664,\n37665,\n37666,\n37667,\n37668,\n37669,\n37670,\n37671,\n37672,\n37673,\n37674,\n37675,\n37676,\n37677,\n37678,\n37679,\n37680,\n37681,\n37682,\n37683,\n37684,\n37685,\n37686,\n37687,\n37688,\n37689,\n37690,\n37691,\n37692,\n37693,\n37695,\n37696,\n37697,\n37698,\n37699,\n37700,\n37701,\n37702,\n37703,\n37704,\n37705,\n0,\n37706,\n37707,\n37708,\n37709,\n37710,\n37711,\n37712,\n37713,\n37714,\n37715,\n37716,\n37717,\n37718,\n37719,\n37720,\n37721,\n37722,\n37723,\n37724,\n37725,\n37726,\n37727,\n37728,\n37729,\n37730,\n37731,\n37732,\n37733,\n37734,\n37735,\n37736,\n37737,\n37739,\n28617,\n28583,\n28601,\n28598,\n28610,\n28641,\n28654,\n28638,\n28640,\n28655,\n28698,\n28707,\n28699,\n28729,\n28725,\n28751,\n28766,\n23424,\n23428,\n23445,\n23443,\n23461,\n23480,\n29999,\n39582,\n25652,\n23524,\n23534,\n35120,\n23536,\n36423,\n35591,\n36790,\n36819,\n36821,\n36837,\n36846,\n36836,\n36841,\n36838,\n36851,\n36840,\n36869,\n36868,\n36875,\n36902,\n36881,\n36877,\n36886,\n36897,\n36917,\n36918,\n36909,\n36911,\n36932,\n36945,\n36946,\n36944,\n36968,\n36952,\n36962,\n36955,\n26297,\n36980,\n36989,\n36994,\n37000,\n36995,\n37003,\n24400,\n24407,\n24406,\n24408,\n23611,\n21675,\n23632,\n23641,\n23409,\n23651,\n23654,\n32700,\n24362,\n24361,\n24365,\n33396,\n24380,\n39739,\n23662,\n22913,\n22915,\n22925,\n22953,\n22954,\n22947,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37740,\n37741,\n37742,\n37743,\n37744,\n37745,\n37746,\n37747,\n37748,\n37749,\n37750,\n37751,\n37752,\n37753,\n37754,\n37755,\n37756,\n37757,\n37758,\n37759,\n37760,\n37761,\n37762,\n37763,\n37764,\n37765,\n37766,\n37767,\n37768,\n37769,\n37770,\n37771,\n37772,\n37773,\n37774,\n37776,\n37777,\n37778,\n37779,\n37780,\n37781,\n37782,\n37783,\n37784,\n37785,\n37786,\n37787,\n37788,\n37789,\n37790,\n37791,\n37792,\n37793,\n37794,\n37795,\n37796,\n37797,\n37798,\n37799,\n37800,\n37801,\n37802,\n37803,\n0,\n37804,\n37805,\n37806,\n37807,\n37808,\n37809,\n37810,\n37811,\n37812,\n37813,\n37814,\n37815,\n37816,\n37817,\n37818,\n37819,\n37820,\n37821,\n37822,\n37823,\n37824,\n37825,\n37826,\n37827,\n37828,\n37829,\n37830,\n37831,\n37832,\n37833,\n37835,\n37836,\n37837,\n22935,\n22986,\n22955,\n22942,\n22948,\n22994,\n22962,\n22959,\n22999,\n22974,\n23045,\n23046,\n23005,\n23048,\n23011,\n23000,\n23033,\n23052,\n23049,\n23090,\n23092,\n23057,\n23075,\n23059,\n23104,\n23143,\n23114,\n23125,\n23100,\n23138,\n23157,\n33004,\n23210,\n23195,\n23159,\n23162,\n23230,\n23275,\n23218,\n23250,\n23252,\n23224,\n23264,\n23267,\n23281,\n23254,\n23270,\n23256,\n23260,\n23305,\n23319,\n23318,\n23346,\n23351,\n23360,\n23573,\n23580,\n23386,\n23397,\n23411,\n23377,\n23379,\n23394,\n39541,\n39543,\n39544,\n39546,\n39551,\n39549,\n39552,\n39553,\n39557,\n39560,\n39562,\n39568,\n39570,\n39571,\n39574,\n39576,\n39579,\n39580,\n39581,\n39583,\n39584,\n39586,\n39587,\n39589,\n39591,\n32415,\n32417,\n32419,\n32421,\n32424,\n32425,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37838,\n37839,\n37840,\n37841,\n37842,\n37843,\n37844,\n37845,\n37847,\n37848,\n37849,\n37850,\n37851,\n37852,\n37853,\n37854,\n37855,\n37856,\n37857,\n37858,\n37859,\n37860,\n37861,\n37862,\n37863,\n37864,\n37865,\n37866,\n37867,\n37868,\n37869,\n37870,\n37871,\n37872,\n37873,\n37874,\n37875,\n37876,\n37877,\n37878,\n37879,\n37880,\n37881,\n37882,\n37883,\n37884,\n37885,\n37886,\n37887,\n37888,\n37889,\n37890,\n37891,\n37892,\n37893,\n37894,\n37895,\n37896,\n37897,\n37898,\n37899,\n37900,\n37901,\n0,\n37902,\n37903,\n37904,\n37905,\n37906,\n37907,\n37908,\n37909,\n37910,\n37911,\n37912,\n37913,\n37914,\n37915,\n37916,\n37917,\n37918,\n37919,\n37920,\n37921,\n37922,\n37923,\n37924,\n37925,\n37926,\n37927,\n37928,\n37929,\n37930,\n37931,\n37932,\n37933,\n37934,\n32429,\n32432,\n32446,\n32448,\n32449,\n32450,\n32457,\n32459,\n32460,\n32464,\n32468,\n32471,\n32475,\n32480,\n32481,\n32488,\n32491,\n32494,\n32495,\n32497,\n32498,\n32525,\n32502,\n32506,\n32507,\n32510,\n32513,\n32514,\n32515,\n32519,\n32520,\n32523,\n32524,\n32527,\n32529,\n32530,\n32535,\n32537,\n32540,\n32539,\n32543,\n32545,\n32546,\n32547,\n32548,\n32549,\n32550,\n32551,\n32554,\n32555,\n32556,\n32557,\n32559,\n32560,\n32561,\n32562,\n32563,\n32565,\n24186,\n30079,\n24027,\n30014,\n37013,\n29582,\n29585,\n29614,\n29602,\n29599,\n29647,\n29634,\n29649,\n29623,\n29619,\n29632,\n29641,\n29640,\n29669,\n29657,\n39036,\n29706,\n29673,\n29671,\n29662,\n29626,\n29682,\n29711,\n29738,\n29787,\n29734,\n29733,\n29736,\n29744,\n29742,\n29740,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n37935,\n37936,\n37937,\n37938,\n37939,\n37940,\n37941,\n37942,\n37943,\n37944,\n37945,\n37946,\n37947,\n37948,\n37949,\n37951,\n37952,\n37953,\n37954,\n37955,\n37956,\n37957,\n37958,\n37959,\n37960,\n37961,\n37962,\n37963,\n37964,\n37965,\n37966,\n37967,\n37968,\n37969,\n37970,\n37971,\n37972,\n37973,\n37974,\n37975,\n37976,\n37977,\n37978,\n37979,\n37980,\n37981,\n37982,\n37983,\n37984,\n37985,\n37986,\n37987,\n37988,\n37989,\n37990,\n37991,\n37992,\n37993,\n37994,\n37996,\n37997,\n37998,\n37999,\n0,\n38000,\n38001,\n38002,\n38003,\n38004,\n38005,\n38006,\n38007,\n38008,\n38009,\n38010,\n38011,\n38012,\n38013,\n38014,\n38015,\n38016,\n38017,\n38018,\n38019,\n38020,\n38033,\n38038,\n38040,\n38087,\n38095,\n38099,\n38100,\n38106,\n38118,\n38139,\n38172,\n38176,\n29723,\n29722,\n29761,\n29788,\n29783,\n29781,\n29785,\n29815,\n29805,\n29822,\n29852,\n29838,\n29824,\n29825,\n29831,\n29835,\n29854,\n29864,\n29865,\n29840,\n29863,\n29906,\n29882,\n38890,\n38891,\n38892,\n26444,\n26451,\n26462,\n26440,\n26473,\n26533,\n26503,\n26474,\n26483,\n26520,\n26535,\n26485,\n26536,\n26526,\n26541,\n26507,\n26487,\n26492,\n26608,\n26633,\n26584,\n26634,\n26601,\n26544,\n26636,\n26585,\n26549,\n26586,\n26547,\n26589,\n26624,\n26563,\n26552,\n26594,\n26638,\n26561,\n26621,\n26674,\n26675,\n26720,\n26721,\n26702,\n26722,\n26692,\n26724,\n26755,\n26653,\n26709,\n26726,\n26689,\n26727,\n26688,\n26686,\n26698,\n26697,\n26665,\n26805,\n26767,\n26740,\n26743,\n26771,\n26731,\n26818,\n26990,\n26876,\n26911,\n26912,\n26873,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38183,\n38195,\n38205,\n38211,\n38216,\n38219,\n38229,\n38234,\n38240,\n38254,\n38260,\n38261,\n38263,\n38264,\n38265,\n38266,\n38267,\n38268,\n38269,\n38270,\n38272,\n38273,\n38274,\n38275,\n38276,\n38277,\n38278,\n38279,\n38280,\n38281,\n38282,\n38283,\n38284,\n38285,\n38286,\n38287,\n38288,\n38289,\n38290,\n38291,\n38292,\n38293,\n38294,\n38295,\n38296,\n38297,\n38298,\n38299,\n38300,\n38301,\n38302,\n38303,\n38304,\n38305,\n38306,\n38307,\n38308,\n38309,\n38310,\n38311,\n38312,\n38313,\n38314,\n0,\n38315,\n38316,\n38317,\n38318,\n38319,\n38320,\n38321,\n38322,\n38323,\n38324,\n38325,\n38326,\n38327,\n38328,\n38329,\n38330,\n38331,\n38332,\n38333,\n38334,\n38335,\n38336,\n38337,\n38338,\n38339,\n38340,\n38341,\n38342,\n38343,\n38344,\n38345,\n38346,\n38347,\n26916,\n26864,\n26891,\n26881,\n26967,\n26851,\n26896,\n26993,\n26937,\n26976,\n26946,\n26973,\n27012,\n26987,\n27008,\n27032,\n27000,\n26932,\n27084,\n27015,\n27016,\n27086,\n27017,\n26982,\n26979,\n27001,\n27035,\n27047,\n27067,\n27051,\n27053,\n27092,\n27057,\n27073,\n27082,\n27103,\n27029,\n27104,\n27021,\n27135,\n27183,\n27117,\n27159,\n27160,\n27237,\n27122,\n27204,\n27198,\n27296,\n27216,\n27227,\n27189,\n27278,\n27257,\n27197,\n27176,\n27224,\n27260,\n27281,\n27280,\n27305,\n27287,\n27307,\n29495,\n29522,\n27521,\n27522,\n27527,\n27524,\n27538,\n27539,\n27533,\n27546,\n27547,\n27553,\n27562,\n36715,\n36717,\n36721,\n36722,\n36723,\n36725,\n36726,\n36728,\n36727,\n36729,\n36730,\n36732,\n36734,\n36737,\n36738,\n36740,\n36743,\n36747,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38348,\n38349,\n38350,\n38351,\n38352,\n38353,\n38354,\n38355,\n38356,\n38357,\n38358,\n38359,\n38360,\n38361,\n38362,\n38363,\n38364,\n38365,\n38366,\n38367,\n38368,\n38369,\n38370,\n38371,\n38372,\n38373,\n38374,\n38375,\n38380,\n38399,\n38407,\n38419,\n38424,\n38427,\n38430,\n38432,\n38435,\n38436,\n38437,\n38438,\n38439,\n38440,\n38441,\n38443,\n38444,\n38445,\n38447,\n38448,\n38455,\n38456,\n38457,\n38458,\n38462,\n38465,\n38467,\n38474,\n38478,\n38479,\n38481,\n38482,\n38483,\n38486,\n38487,\n0,\n38488,\n38489,\n38490,\n38492,\n38493,\n38494,\n38496,\n38499,\n38501,\n38502,\n38507,\n38509,\n38510,\n38511,\n38512,\n38513,\n38515,\n38520,\n38521,\n38522,\n38523,\n38524,\n38525,\n38526,\n38527,\n38528,\n38529,\n38530,\n38531,\n38532,\n38535,\n38537,\n38538,\n36749,\n36750,\n36751,\n36760,\n36762,\n36558,\n25099,\n25111,\n25115,\n25119,\n25122,\n25121,\n25125,\n25124,\n25132,\n33255,\n29935,\n29940,\n29951,\n29967,\n29969,\n29971,\n25908,\n26094,\n26095,\n26096,\n26122,\n26137,\n26482,\n26115,\n26133,\n26112,\n28805,\n26359,\n26141,\n26164,\n26161,\n26166,\n26165,\n32774,\n26207,\n26196,\n26177,\n26191,\n26198,\n26209,\n26199,\n26231,\n26244,\n26252,\n26279,\n26269,\n26302,\n26331,\n26332,\n26342,\n26345,\n36146,\n36147,\n36150,\n36155,\n36157,\n36160,\n36165,\n36166,\n36168,\n36169,\n36167,\n36173,\n36181,\n36185,\n35271,\n35274,\n35275,\n35276,\n35278,\n35279,\n35280,\n35281,\n29294,\n29343,\n29277,\n29286,\n29295,\n29310,\n29311,\n29316,\n29323,\n29325,\n29327,\n29330,\n25352,\n25394,\n25520,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38540,\n38542,\n38545,\n38546,\n38547,\n38549,\n38550,\n38554,\n38555,\n38557,\n38558,\n38559,\n38560,\n38561,\n38562,\n38563,\n38564,\n38565,\n38566,\n38568,\n38569,\n38570,\n38571,\n38572,\n38573,\n38574,\n38575,\n38577,\n38578,\n38580,\n38581,\n38583,\n38584,\n38586,\n38587,\n38591,\n38594,\n38595,\n38600,\n38602,\n38603,\n38608,\n38609,\n38611,\n38612,\n38614,\n38615,\n38616,\n38617,\n38618,\n38619,\n38620,\n38621,\n38622,\n38623,\n38625,\n38626,\n38627,\n38628,\n38629,\n38630,\n38631,\n38635,\n0,\n38636,\n38637,\n38638,\n38640,\n38641,\n38642,\n38644,\n38645,\n38648,\n38650,\n38651,\n38652,\n38653,\n38655,\n38658,\n38659,\n38661,\n38666,\n38667,\n38668,\n38672,\n38673,\n38674,\n38676,\n38677,\n38679,\n38680,\n38681,\n38682,\n38683,\n38685,\n38687,\n38688,\n25663,\n25816,\n32772,\n27626,\n27635,\n27645,\n27637,\n27641,\n27653,\n27655,\n27654,\n27661,\n27669,\n27672,\n27673,\n27674,\n27681,\n27689,\n27684,\n27690,\n27698,\n25909,\n25941,\n25963,\n29261,\n29266,\n29270,\n29232,\n34402,\n21014,\n32927,\n32924,\n32915,\n32956,\n26378,\n32957,\n32945,\n32939,\n32941,\n32948,\n32951,\n32999,\n33000,\n33001,\n33002,\n32987,\n32962,\n32964,\n32985,\n32973,\n32983,\n26384,\n32989,\n33003,\n33009,\n33012,\n33005,\n33037,\n33038,\n33010,\n33020,\n26389,\n33042,\n35930,\n33078,\n33054,\n33068,\n33048,\n33074,\n33096,\n33100,\n33107,\n33140,\n33113,\n33114,\n33137,\n33120,\n33129,\n33148,\n33149,\n33133,\n33127,\n22605,\n23221,\n33160,\n33154,\n33169,\n28373,\n33187,\n33194,\n33228,\n26406,\n33226,\n33211,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38689,\n38690,\n38691,\n38692,\n38693,\n38694,\n38695,\n38696,\n38697,\n38699,\n38700,\n38702,\n38703,\n38705,\n38707,\n38708,\n38709,\n38710,\n38711,\n38714,\n38715,\n38716,\n38717,\n38719,\n38720,\n38721,\n38722,\n38723,\n38724,\n38725,\n38726,\n38727,\n38728,\n38729,\n38730,\n38731,\n38732,\n38733,\n38734,\n38735,\n38736,\n38737,\n38740,\n38741,\n38743,\n38744,\n38746,\n38748,\n38749,\n38751,\n38755,\n38756,\n38758,\n38759,\n38760,\n38762,\n38763,\n38764,\n38765,\n38766,\n38767,\n38768,\n38769,\n0,\n38770,\n38773,\n38775,\n38776,\n38777,\n38778,\n38779,\n38781,\n38782,\n38783,\n38784,\n38785,\n38786,\n38787,\n38788,\n38790,\n38791,\n38792,\n38793,\n38794,\n38796,\n38798,\n38799,\n38800,\n38803,\n38805,\n38806,\n38807,\n38809,\n38810,\n38811,\n38812,\n38813,\n33217,\n33190,\n27428,\n27447,\n27449,\n27459,\n27462,\n27481,\n39121,\n39122,\n39123,\n39125,\n39129,\n39130,\n27571,\n24384,\n27586,\n35315,\n26000,\n40785,\n26003,\n26044,\n26054,\n26052,\n26051,\n26060,\n26062,\n26066,\n26070,\n28800,\n28828,\n28822,\n28829,\n28859,\n28864,\n28855,\n28843,\n28849,\n28904,\n28874,\n28944,\n28947,\n28950,\n28975,\n28977,\n29043,\n29020,\n29032,\n28997,\n29042,\n29002,\n29048,\n29050,\n29080,\n29107,\n29109,\n29096,\n29088,\n29152,\n29140,\n29159,\n29177,\n29213,\n29224,\n28780,\n28952,\n29030,\n29113,\n25150,\n25149,\n25155,\n25160,\n25161,\n31035,\n31040,\n31046,\n31049,\n31067,\n31068,\n31059,\n31066,\n31074,\n31063,\n31072,\n31087,\n31079,\n31098,\n31109,\n31114,\n31130,\n31143,\n31155,\n24529,\n24528,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38814,\n38815,\n38817,\n38818,\n38820,\n38821,\n38822,\n38823,\n38824,\n38825,\n38826,\n38828,\n38830,\n38832,\n38833,\n38835,\n38837,\n38838,\n38839,\n38840,\n38841,\n38842,\n38843,\n38844,\n38845,\n38846,\n38847,\n38848,\n38849,\n38850,\n38851,\n38852,\n38853,\n38854,\n38855,\n38856,\n38857,\n38858,\n38859,\n38860,\n38861,\n38862,\n38863,\n38864,\n38865,\n38866,\n38867,\n38868,\n38869,\n38870,\n38871,\n38872,\n38873,\n38874,\n38875,\n38876,\n38877,\n38878,\n38879,\n38880,\n38881,\n38882,\n38883,\n0,\n38884,\n38885,\n38888,\n38894,\n38895,\n38896,\n38897,\n38898,\n38900,\n38903,\n38904,\n38905,\n38906,\n38907,\n38908,\n38909,\n38910,\n38911,\n38912,\n38913,\n38914,\n38915,\n38916,\n38917,\n38918,\n38919,\n38920,\n38921,\n38922,\n38923,\n38924,\n38925,\n38926,\n24636,\n24669,\n24666,\n24679,\n24641,\n24665,\n24675,\n24747,\n24838,\n24845,\n24925,\n25001,\n24989,\n25035,\n25041,\n25094,\n32896,\n32895,\n27795,\n27894,\n28156,\n30710,\n30712,\n30720,\n30729,\n30743,\n30744,\n30737,\n26027,\n30765,\n30748,\n30749,\n30777,\n30778,\n30779,\n30751,\n30780,\n30757,\n30764,\n30755,\n30761,\n30798,\n30829,\n30806,\n30807,\n30758,\n30800,\n30791,\n30796,\n30826,\n30875,\n30867,\n30874,\n30855,\n30876,\n30881,\n30883,\n30898,\n30905,\n30885,\n30932,\n30937,\n30921,\n30956,\n30962,\n30981,\n30964,\n30995,\n31012,\n31006,\n31028,\n40859,\n40697,\n40699,\n40700,\n30449,\n30468,\n30477,\n30457,\n30471,\n30472,\n30490,\n30498,\n30489,\n30509,\n30502,\n30517,\n30520,\n30544,\n30545,\n30535,\n30531,\n30554,\n30568,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n38927,\n38928,\n38929,\n38930,\n38931,\n38932,\n38933,\n38934,\n38935,\n38936,\n38937,\n38938,\n38939,\n38940,\n38941,\n38942,\n38943,\n38944,\n38945,\n38946,\n38947,\n38948,\n38949,\n38950,\n38951,\n38952,\n38953,\n38954,\n38955,\n38956,\n38957,\n38958,\n38959,\n38960,\n38961,\n38962,\n38963,\n38964,\n38965,\n38966,\n38967,\n38968,\n38969,\n38970,\n38971,\n38972,\n38973,\n38974,\n38975,\n38976,\n38977,\n38978,\n38979,\n38980,\n38981,\n38982,\n38983,\n38984,\n38985,\n38986,\n38987,\n38988,\n38989,\n0,\n38990,\n38991,\n38992,\n38993,\n38994,\n38995,\n38996,\n38997,\n38998,\n38999,\n39000,\n39001,\n39002,\n39003,\n39004,\n39005,\n39006,\n39007,\n39008,\n39009,\n39010,\n39011,\n39012,\n39013,\n39014,\n39015,\n39016,\n39017,\n39018,\n39019,\n39020,\n39021,\n39022,\n30562,\n30565,\n30591,\n30605,\n30589,\n30592,\n30604,\n30609,\n30623,\n30624,\n30640,\n30645,\n30653,\n30010,\n30016,\n30030,\n30027,\n30024,\n30043,\n30066,\n30073,\n30083,\n32600,\n32609,\n32607,\n35400,\n32616,\n32628,\n32625,\n32633,\n32641,\n32638,\n30413,\n30437,\n34866,\n38021,\n38022,\n38023,\n38027,\n38026,\n38028,\n38029,\n38031,\n38032,\n38036,\n38039,\n38037,\n38042,\n38043,\n38044,\n38051,\n38052,\n38059,\n38058,\n38061,\n38060,\n38063,\n38064,\n38066,\n38068,\n38070,\n38071,\n38072,\n38073,\n38074,\n38076,\n38077,\n38079,\n38084,\n38088,\n38089,\n38090,\n38091,\n38092,\n38093,\n38094,\n38096,\n38097,\n38098,\n38101,\n38102,\n38103,\n38105,\n38104,\n38107,\n38110,\n38111,\n38112,\n38114,\n38116,\n38117,\n38119,\n38120,\n38122,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39023,\n39024,\n39025,\n39026,\n39027,\n39028,\n39051,\n39054,\n39058,\n39061,\n39065,\n39075,\n39080,\n39081,\n39082,\n39083,\n39084,\n39085,\n39086,\n39087,\n39088,\n39089,\n39090,\n39091,\n39092,\n39093,\n39094,\n39095,\n39096,\n39097,\n39098,\n39099,\n39100,\n39101,\n39102,\n39103,\n39104,\n39105,\n39106,\n39107,\n39108,\n39109,\n39110,\n39111,\n39112,\n39113,\n39114,\n39115,\n39116,\n39117,\n39119,\n39120,\n39124,\n39126,\n39127,\n39131,\n39132,\n39133,\n39136,\n39137,\n39138,\n39139,\n39140,\n0,\n39141,\n39142,\n39145,\n39146,\n39147,\n39148,\n39149,\n39150,\n39151,\n39152,\n39153,\n39154,\n39155,\n39156,\n39157,\n39158,\n39159,\n39160,\n39161,\n39162,\n39163,\n39164,\n39165,\n39166,\n39167,\n39168,\n39169,\n39170,\n39171,\n39172,\n39173,\n39174,\n39175,\n38121,\n38123,\n38126,\n38127,\n38131,\n38132,\n38133,\n38135,\n38137,\n38140,\n38141,\n38143,\n38147,\n38146,\n38150,\n38151,\n38153,\n38154,\n38157,\n38158,\n38159,\n38162,\n38163,\n38164,\n38165,\n38166,\n38168,\n38171,\n38173,\n38174,\n38175,\n38178,\n38186,\n38187,\n38185,\n38188,\n38193,\n38194,\n38196,\n38198,\n38199,\n38200,\n38204,\n38206,\n38207,\n38210,\n38197,\n38212,\n38213,\n38214,\n38217,\n38220,\n38222,\n38223,\n38226,\n38227,\n38228,\n38230,\n38231,\n38232,\n38233,\n38235,\n38238,\n38239,\n38237,\n38241,\n38242,\n38244,\n38245,\n38246,\n38247,\n38248,\n38249,\n38250,\n38251,\n38252,\n38255,\n38257,\n38258,\n38259,\n38202,\n30695,\n30700,\n38601,\n31189,\n31213,\n31203,\n31211,\n31238,\n23879,\n31235,\n31234,\n31262,\n31252,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39176,\n39177,\n39178,\n39179,\n39180,\n39182,\n39183,\n39185,\n39186,\n39187,\n39188,\n39189,\n39190,\n39191,\n39192,\n39193,\n39194,\n39195,\n39196,\n39197,\n39198,\n39199,\n39200,\n39201,\n39202,\n39203,\n39204,\n39205,\n39206,\n39207,\n39208,\n39209,\n39210,\n39211,\n39212,\n39213,\n39215,\n39216,\n39217,\n39218,\n39219,\n39220,\n39221,\n39222,\n39223,\n39224,\n39225,\n39226,\n39227,\n39228,\n39229,\n39230,\n39231,\n39232,\n39233,\n39234,\n39235,\n39236,\n39237,\n39238,\n39239,\n39240,\n39241,\n0,\n39242,\n39243,\n39244,\n39245,\n39246,\n39247,\n39248,\n39249,\n39250,\n39251,\n39254,\n39255,\n39256,\n39257,\n39258,\n39259,\n39260,\n39261,\n39262,\n39263,\n39264,\n39265,\n39266,\n39268,\n39270,\n39283,\n39288,\n39289,\n39291,\n39294,\n39298,\n39299,\n39305,\n31289,\n31287,\n31313,\n40655,\n39333,\n31344,\n30344,\n30350,\n30355,\n30361,\n30372,\n29918,\n29920,\n29996,\n40480,\n40482,\n40488,\n40489,\n40490,\n40491,\n40492,\n40498,\n40497,\n40502,\n40504,\n40503,\n40505,\n40506,\n40510,\n40513,\n40514,\n40516,\n40518,\n40519,\n40520,\n40521,\n40523,\n40524,\n40526,\n40529,\n40533,\n40535,\n40538,\n40539,\n40540,\n40542,\n40547,\n40550,\n40551,\n40552,\n40553,\n40554,\n40555,\n40556,\n40561,\n40557,\n40563,\n30098,\n30100,\n30102,\n30112,\n30109,\n30124,\n30115,\n30131,\n30132,\n30136,\n30148,\n30129,\n30128,\n30147,\n30146,\n30166,\n30157,\n30179,\n30184,\n30182,\n30180,\n30187,\n30183,\n30211,\n30193,\n30204,\n30207,\n30224,\n30208,\n30213,\n30220,\n30231,\n30218,\n30245,\n30232,\n30229,\n30233,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39308,\n39310,\n39322,\n39323,\n39324,\n39325,\n39326,\n39327,\n39328,\n39329,\n39330,\n39331,\n39332,\n39334,\n39335,\n39337,\n39338,\n39339,\n39340,\n39341,\n39342,\n39343,\n39344,\n39345,\n39346,\n39347,\n39348,\n39349,\n39350,\n39351,\n39352,\n39353,\n39354,\n39355,\n39356,\n39357,\n39358,\n39359,\n39360,\n39361,\n39362,\n39363,\n39364,\n39365,\n39366,\n39367,\n39368,\n39369,\n39370,\n39371,\n39372,\n39373,\n39374,\n39375,\n39376,\n39377,\n39378,\n39379,\n39380,\n39381,\n39382,\n39383,\n39384,\n0,\n39385,\n39386,\n39387,\n39388,\n39389,\n39390,\n39391,\n39392,\n39393,\n39394,\n39395,\n39396,\n39397,\n39398,\n39399,\n39400,\n39401,\n39402,\n39403,\n39404,\n39405,\n39406,\n39407,\n39408,\n39409,\n39410,\n39411,\n39412,\n39413,\n39414,\n39415,\n39416,\n39417,\n30235,\n30268,\n30242,\n30240,\n30272,\n30253,\n30256,\n30271,\n30261,\n30275,\n30270,\n30259,\n30285,\n30302,\n30292,\n30300,\n30294,\n30315,\n30319,\n32714,\n31462,\n31352,\n31353,\n31360,\n31366,\n31368,\n31381,\n31398,\n31392,\n31404,\n31400,\n31405,\n31411,\n34916,\n34921,\n34930,\n34941,\n34943,\n34946,\n34978,\n35014,\n34999,\n35004,\n35017,\n35042,\n35022,\n35043,\n35045,\n35057,\n35098,\n35068,\n35048,\n35070,\n35056,\n35105,\n35097,\n35091,\n35099,\n35082,\n35124,\n35115,\n35126,\n35137,\n35174,\n35195,\n30091,\n32997,\n30386,\n30388,\n30684,\n32786,\n32788,\n32790,\n32796,\n32800,\n32802,\n32805,\n32806,\n32807,\n32809,\n32808,\n32817,\n32779,\n32821,\n32835,\n32838,\n32845,\n32850,\n32873,\n32881,\n35203,\n39032,\n39040,\n39043,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39418,\n39419,\n39420,\n39421,\n39422,\n39423,\n39424,\n39425,\n39426,\n39427,\n39428,\n39429,\n39430,\n39431,\n39432,\n39433,\n39434,\n39435,\n39436,\n39437,\n39438,\n39439,\n39440,\n39441,\n39442,\n39443,\n39444,\n39445,\n39446,\n39447,\n39448,\n39449,\n39450,\n39451,\n39452,\n39453,\n39454,\n39455,\n39456,\n39457,\n39458,\n39459,\n39460,\n39461,\n39462,\n39463,\n39464,\n39465,\n39466,\n39467,\n39468,\n39469,\n39470,\n39471,\n39472,\n39473,\n39474,\n39475,\n39476,\n39477,\n39478,\n39479,\n39480,\n0,\n39481,\n39482,\n39483,\n39484,\n39485,\n39486,\n39487,\n39488,\n39489,\n39490,\n39491,\n39492,\n39493,\n39494,\n39495,\n39496,\n39497,\n39498,\n39499,\n39500,\n39501,\n39502,\n39503,\n39504,\n39505,\n39506,\n39507,\n39508,\n39509,\n39510,\n39511,\n39512,\n39513,\n39049,\n39052,\n39053,\n39055,\n39060,\n39066,\n39067,\n39070,\n39071,\n39073,\n39074,\n39077,\n39078,\n34381,\n34388,\n34412,\n34414,\n34431,\n34426,\n34428,\n34427,\n34472,\n34445,\n34443,\n34476,\n34461,\n34471,\n34467,\n34474,\n34451,\n34473,\n34486,\n34500,\n34485,\n34510,\n34480,\n34490,\n34481,\n34479,\n34505,\n34511,\n34484,\n34537,\n34545,\n34546,\n34541,\n34547,\n34512,\n34579,\n34526,\n34548,\n34527,\n34520,\n34513,\n34563,\n34567,\n34552,\n34568,\n34570,\n34573,\n34569,\n34595,\n34619,\n34590,\n34597,\n34606,\n34586,\n34622,\n34632,\n34612,\n34609,\n34601,\n34615,\n34623,\n34690,\n34594,\n34685,\n34686,\n34683,\n34656,\n34672,\n34636,\n34670,\n34699,\n34643,\n34659,\n34684,\n34660,\n34649,\n34661,\n34707,\n34735,\n34728,\n34770,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39514,\n39515,\n39516,\n39517,\n39518,\n39519,\n39520,\n39521,\n39522,\n39523,\n39524,\n39525,\n39526,\n39527,\n39528,\n39529,\n39530,\n39531,\n39538,\n39555,\n39561,\n39565,\n39566,\n39572,\n39573,\n39577,\n39590,\n39593,\n39594,\n39595,\n39596,\n39597,\n39598,\n39599,\n39602,\n39603,\n39604,\n39605,\n39609,\n39611,\n39613,\n39614,\n39615,\n39619,\n39620,\n39622,\n39623,\n39624,\n39625,\n39626,\n39629,\n39630,\n39631,\n39632,\n39634,\n39636,\n39637,\n39638,\n39639,\n39641,\n39642,\n39643,\n39644,\n0,\n39645,\n39646,\n39648,\n39650,\n39651,\n39652,\n39653,\n39655,\n39656,\n39657,\n39658,\n39660,\n39662,\n39664,\n39665,\n39666,\n39667,\n39668,\n39669,\n39670,\n39671,\n39672,\n39674,\n39676,\n39677,\n39678,\n39679,\n39680,\n39681,\n39682,\n39684,\n39685,\n39686,\n34758,\n34696,\n34693,\n34733,\n34711,\n34691,\n34731,\n34789,\n34732,\n34741,\n34739,\n34763,\n34771,\n34749,\n34769,\n34752,\n34762,\n34779,\n34794,\n34784,\n34798,\n34838,\n34835,\n34814,\n34826,\n34843,\n34849,\n34873,\n34876,\n32566,\n32578,\n32580,\n32581,\n33296,\n31482,\n31485,\n31496,\n31491,\n31492,\n31509,\n31498,\n31531,\n31503,\n31559,\n31544,\n31530,\n31513,\n31534,\n31537,\n31520,\n31525,\n31524,\n31539,\n31550,\n31518,\n31576,\n31578,\n31557,\n31605,\n31564,\n31581,\n31584,\n31598,\n31611,\n31586,\n31602,\n31601,\n31632,\n31654,\n31655,\n31672,\n31660,\n31645,\n31656,\n31621,\n31658,\n31644,\n31650,\n31659,\n31668,\n31697,\n31681,\n31692,\n31709,\n31706,\n31717,\n31718,\n31722,\n31756,\n31742,\n31740,\n31759,\n31766,\n31755,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39687,\n39689,\n39690,\n39691,\n39692,\n39693,\n39694,\n39696,\n39697,\n39698,\n39700,\n39701,\n39702,\n39703,\n39704,\n39705,\n39706,\n39707,\n39708,\n39709,\n39710,\n39712,\n39713,\n39714,\n39716,\n39717,\n39718,\n39719,\n39720,\n39721,\n39722,\n39723,\n39724,\n39725,\n39726,\n39728,\n39729,\n39731,\n39732,\n39733,\n39734,\n39735,\n39736,\n39737,\n39738,\n39741,\n39742,\n39743,\n39744,\n39750,\n39754,\n39755,\n39756,\n39758,\n39760,\n39762,\n39763,\n39765,\n39766,\n39767,\n39768,\n39769,\n39770,\n0,\n39771,\n39772,\n39773,\n39774,\n39775,\n39776,\n39777,\n39778,\n39779,\n39780,\n39781,\n39782,\n39783,\n39784,\n39785,\n39786,\n39787,\n39788,\n39789,\n39790,\n39791,\n39792,\n39793,\n39794,\n39795,\n39796,\n39797,\n39798,\n39799,\n39800,\n39801,\n39802,\n39803,\n31775,\n31786,\n31782,\n31800,\n31809,\n31808,\n33278,\n33281,\n33282,\n33284,\n33260,\n34884,\n33313,\n33314,\n33315,\n33325,\n33327,\n33320,\n33323,\n33336,\n33339,\n33331,\n33332,\n33342,\n33348,\n33353,\n33355,\n33359,\n33370,\n33375,\n33384,\n34942,\n34949,\n34952,\n35032,\n35039,\n35166,\n32669,\n32671,\n32679,\n32687,\n32688,\n32690,\n31868,\n25929,\n31889,\n31901,\n31900,\n31902,\n31906,\n31922,\n31932,\n31933,\n31937,\n31943,\n31948,\n31949,\n31944,\n31941,\n31959,\n31976,\n33390,\n26280,\n32703,\n32718,\n32725,\n32741,\n32737,\n32742,\n32745,\n32750,\n32755,\n31992,\n32119,\n32166,\n32174,\n32327,\n32411,\n40632,\n40628,\n36211,\n36228,\n36244,\n36241,\n36273,\n36199,\n36205,\n35911,\n35913,\n37194,\n37200,\n37198,\n37199,\n37220,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39804,\n39805,\n39806,\n39807,\n39808,\n39809,\n39810,\n39811,\n39812,\n39813,\n39814,\n39815,\n39816,\n39817,\n39818,\n39819,\n39820,\n39821,\n39822,\n39823,\n39824,\n39825,\n39826,\n39827,\n39828,\n39829,\n39830,\n39831,\n39832,\n39833,\n39834,\n39835,\n39836,\n39837,\n39838,\n39839,\n39840,\n39841,\n39842,\n39843,\n39844,\n39845,\n39846,\n39847,\n39848,\n39849,\n39850,\n39851,\n39852,\n39853,\n39854,\n39855,\n39856,\n39857,\n39858,\n39859,\n39860,\n39861,\n39862,\n39863,\n39864,\n39865,\n39866,\n0,\n39867,\n39868,\n39869,\n39870,\n39871,\n39872,\n39873,\n39874,\n39875,\n39876,\n39877,\n39878,\n39879,\n39880,\n39881,\n39882,\n39883,\n39884,\n39885,\n39886,\n39887,\n39888,\n39889,\n39890,\n39891,\n39892,\n39893,\n39894,\n39895,\n39896,\n39897,\n39898,\n39899,\n37218,\n37217,\n37232,\n37225,\n37231,\n37245,\n37246,\n37234,\n37236,\n37241,\n37260,\n37253,\n37264,\n37261,\n37265,\n37282,\n37283,\n37290,\n37293,\n37294,\n37295,\n37301,\n37300,\n37306,\n35925,\n40574,\n36280,\n36331,\n36357,\n36441,\n36457,\n36277,\n36287,\n36284,\n36282,\n36292,\n36310,\n36311,\n36314,\n36318,\n36302,\n36303,\n36315,\n36294,\n36332,\n36343,\n36344,\n36323,\n36345,\n36347,\n36324,\n36361,\n36349,\n36372,\n36381,\n36383,\n36396,\n36398,\n36387,\n36399,\n36410,\n36416,\n36409,\n36405,\n36413,\n36401,\n36425,\n36417,\n36418,\n36433,\n36434,\n36426,\n36464,\n36470,\n36476,\n36463,\n36468,\n36485,\n36495,\n36500,\n36496,\n36508,\n36510,\n35960,\n35970,\n35978,\n35973,\n35992,\n35988,\n26011,\n35286,\n35294,\n35290,\n35292,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39900,\n39901,\n39902,\n39903,\n39904,\n39905,\n39906,\n39907,\n39908,\n39909,\n39910,\n39911,\n39912,\n39913,\n39914,\n39915,\n39916,\n39917,\n39918,\n39919,\n39920,\n39921,\n39922,\n39923,\n39924,\n39925,\n39926,\n39927,\n39928,\n39929,\n39930,\n39931,\n39932,\n39933,\n39934,\n39935,\n39936,\n39937,\n39938,\n39939,\n39940,\n39941,\n39942,\n39943,\n39944,\n39945,\n39946,\n39947,\n39948,\n39949,\n39950,\n39951,\n39952,\n39953,\n39954,\n39955,\n39956,\n39957,\n39958,\n39959,\n39960,\n39961,\n39962,\n0,\n39963,\n39964,\n39965,\n39966,\n39967,\n39968,\n39969,\n39970,\n39971,\n39972,\n39973,\n39974,\n39975,\n39976,\n39977,\n39978,\n39979,\n39980,\n39981,\n39982,\n39983,\n39984,\n39985,\n39986,\n39987,\n39988,\n39989,\n39990,\n39991,\n39992,\n39993,\n39994,\n39995,\n35301,\n35307,\n35311,\n35390,\n35622,\n38739,\n38633,\n38643,\n38639,\n38662,\n38657,\n38664,\n38671,\n38670,\n38698,\n38701,\n38704,\n38718,\n40832,\n40835,\n40837,\n40838,\n40839,\n40840,\n40841,\n40842,\n40844,\n40702,\n40715,\n40717,\n38585,\n38588,\n38589,\n38606,\n38610,\n30655,\n38624,\n37518,\n37550,\n37576,\n37694,\n37738,\n37834,\n37775,\n37950,\n37995,\n40063,\n40066,\n40069,\n40070,\n40071,\n40072,\n31267,\n40075,\n40078,\n40080,\n40081,\n40082,\n40084,\n40085,\n40090,\n40091,\n40094,\n40095,\n40096,\n40097,\n40098,\n40099,\n40101,\n40102,\n40103,\n40104,\n40105,\n40107,\n40109,\n40110,\n40112,\n40113,\n40114,\n40115,\n40116,\n40117,\n40118,\n40119,\n40122,\n40123,\n40124,\n40125,\n40132,\n40133,\n40134,\n40135,\n40138,\n40139,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n39996,\n39997,\n39998,\n39999,\n40000,\n40001,\n40002,\n40003,\n40004,\n40005,\n40006,\n40007,\n40008,\n40009,\n40010,\n40011,\n40012,\n40013,\n40014,\n40015,\n40016,\n40017,\n40018,\n40019,\n40020,\n40021,\n40022,\n40023,\n40024,\n40025,\n40026,\n40027,\n40028,\n40029,\n40030,\n40031,\n40032,\n40033,\n40034,\n40035,\n40036,\n40037,\n40038,\n40039,\n40040,\n40041,\n40042,\n40043,\n40044,\n40045,\n40046,\n40047,\n40048,\n40049,\n40050,\n40051,\n40052,\n40053,\n40054,\n40055,\n40056,\n40057,\n40058,\n0,\n40059,\n40061,\n40062,\n40064,\n40067,\n40068,\n40073,\n40074,\n40076,\n40079,\n40083,\n40086,\n40087,\n40088,\n40089,\n40093,\n40106,\n40108,\n40111,\n40121,\n40126,\n40127,\n40128,\n40129,\n40130,\n40136,\n40137,\n40145,\n40146,\n40154,\n40155,\n40160,\n40161,\n40140,\n40141,\n40142,\n40143,\n40144,\n40147,\n40148,\n40149,\n40151,\n40152,\n40153,\n40156,\n40157,\n40159,\n40162,\n38780,\n38789,\n38801,\n38802,\n38804,\n38831,\n38827,\n38819,\n38834,\n38836,\n39601,\n39600,\n39607,\n40536,\n39606,\n39610,\n39612,\n39617,\n39616,\n39621,\n39618,\n39627,\n39628,\n39633,\n39749,\n39747,\n39751,\n39753,\n39752,\n39757,\n39761,\n39144,\n39181,\n39214,\n39253,\n39252,\n39647,\n39649,\n39654,\n39663,\n39659,\n39675,\n39661,\n39673,\n39688,\n39695,\n39699,\n39711,\n39715,\n40637,\n40638,\n32315,\n40578,\n40583,\n40584,\n40587,\n40594,\n37846,\n40605,\n40607,\n40667,\n40668,\n40669,\n40672,\n40671,\n40674,\n40681,\n40679,\n40677,\n40682,\n40687,\n40738,\n40748,\n40751,\n40761,\n40759,\n40765,\n40766,\n40772,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40163,\n40164,\n40165,\n40166,\n40167,\n40168,\n40169,\n40170,\n40171,\n40172,\n40173,\n40174,\n40175,\n40176,\n40177,\n40178,\n40179,\n40180,\n40181,\n40182,\n40183,\n40184,\n40185,\n40186,\n40187,\n40188,\n40189,\n40190,\n40191,\n40192,\n40193,\n40194,\n40195,\n40196,\n40197,\n40198,\n40199,\n40200,\n40201,\n40202,\n40203,\n40204,\n40205,\n40206,\n40207,\n40208,\n40209,\n40210,\n40211,\n40212,\n40213,\n40214,\n40215,\n40216,\n40217,\n40218,\n40219,\n40220,\n40221,\n40222,\n40223,\n40224,\n40225,\n0,\n40226,\n40227,\n40228,\n40229,\n40230,\n40231,\n40232,\n40233,\n40234,\n40235,\n40236,\n40237,\n40238,\n40239,\n40240,\n40241,\n40242,\n40243,\n40244,\n40245,\n40246,\n40247,\n40248,\n40249,\n40250,\n40251,\n40252,\n40253,\n40254,\n40255,\n40256,\n40257,\n40258,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40259,\n40260,\n40261,\n40262,\n40263,\n40264,\n40265,\n40266,\n40267,\n40268,\n40269,\n40270,\n40271,\n40272,\n40273,\n40274,\n40275,\n40276,\n40277,\n40278,\n40279,\n40280,\n40281,\n40282,\n40283,\n40284,\n40285,\n40286,\n40287,\n40288,\n40289,\n40290,\n40291,\n40292,\n40293,\n40294,\n40295,\n40296,\n40297,\n40298,\n40299,\n40300,\n40301,\n40302,\n40303,\n40304,\n40305,\n40306,\n40307,\n40308,\n40309,\n40310,\n40311,\n40312,\n40313,\n40314,\n40315,\n40316,\n40317,\n40318,\n40319,\n40320,\n40321,\n0,\n40322,\n40323,\n40324,\n40325,\n40326,\n40327,\n40328,\n40329,\n40330,\n40331,\n40332,\n40333,\n40334,\n40335,\n40336,\n40337,\n40338,\n40339,\n40340,\n40341,\n40342,\n40343,\n40344,\n40345,\n40346,\n40347,\n40348,\n40349,\n40350,\n40351,\n40352,\n40353,\n40354,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40355,\n40356,\n40357,\n40358,\n40359,\n40360,\n40361,\n40362,\n40363,\n40364,\n40365,\n40366,\n40367,\n40368,\n40369,\n40370,\n40371,\n40372,\n40373,\n40374,\n40375,\n40376,\n40377,\n40378,\n40379,\n40380,\n40381,\n40382,\n40383,\n40384,\n40385,\n40386,\n40387,\n40388,\n40389,\n40390,\n40391,\n40392,\n40393,\n40394,\n40395,\n40396,\n40397,\n40398,\n40399,\n40400,\n40401,\n40402,\n40403,\n40404,\n40405,\n40406,\n40407,\n40408,\n40409,\n40410,\n40411,\n40412,\n40413,\n40414,\n40415,\n40416,\n40417,\n0,\n40418,\n40419,\n40420,\n40421,\n40422,\n40423,\n40424,\n40425,\n40426,\n40427,\n40428,\n40429,\n40430,\n40431,\n40432,\n40433,\n40434,\n40435,\n40436,\n40437,\n40438,\n40439,\n40440,\n40441,\n40442,\n40443,\n40444,\n40445,\n40446,\n40447,\n40448,\n40449,\n40450,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40451,\n40452,\n40453,\n40454,\n40455,\n40456,\n40457,\n40458,\n40459,\n40460,\n40461,\n40462,\n40463,\n40464,\n40465,\n40466,\n40467,\n40468,\n40469,\n40470,\n40471,\n40472,\n40473,\n40474,\n40475,\n40476,\n40477,\n40478,\n40484,\n40487,\n40494,\n40496,\n40500,\n40507,\n40508,\n40512,\n40525,\n40528,\n40530,\n40531,\n40532,\n40534,\n40537,\n40541,\n40543,\n40544,\n40545,\n40546,\n40549,\n40558,\n40559,\n40562,\n40564,\n40565,\n40566,\n40567,\n40568,\n40569,\n40570,\n40571,\n40572,\n40573,\n40576,\n0,\n40577,\n40579,\n40580,\n40581,\n40582,\n40585,\n40586,\n40588,\n40589,\n40590,\n40591,\n40592,\n40593,\n40596,\n40597,\n40598,\n40599,\n40600,\n40601,\n40602,\n40603,\n40604,\n40606,\n40608,\n40609,\n40610,\n40611,\n40612,\n40613,\n40615,\n40616,\n40617,\n40618,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40619,\n40620,\n40621,\n40622,\n40623,\n40624,\n40625,\n40626,\n40627,\n40629,\n40630,\n40631,\n40633,\n40634,\n40636,\n40639,\n40640,\n40641,\n40642,\n40643,\n40645,\n40646,\n40647,\n40648,\n40650,\n40651,\n40652,\n40656,\n40658,\n40659,\n40661,\n40662,\n40663,\n40665,\n40666,\n40670,\n40673,\n40675,\n40676,\n40678,\n40680,\n40683,\n40684,\n40685,\n40686,\n40688,\n40689,\n40690,\n40691,\n40692,\n40693,\n40694,\n40695,\n40696,\n40698,\n40701,\n40703,\n40704,\n40705,\n40706,\n40707,\n40708,\n40709,\n0,\n40710,\n40711,\n40712,\n40713,\n40714,\n40716,\n40719,\n40721,\n40722,\n40724,\n40725,\n40726,\n40728,\n40730,\n40731,\n40732,\n40733,\n40734,\n40735,\n40737,\n40739,\n40740,\n40741,\n40742,\n40743,\n40744,\n40745,\n40746,\n40747,\n40749,\n40750,\n40752,\n40753,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n40754,\n40755,\n40756,\n40757,\n40758,\n40760,\n40762,\n40764,\n40767,\n40768,\n40769,\n40770,\n40771,\n40773,\n40774,\n40775,\n40776,\n40777,\n40778,\n40779,\n40780,\n40781,\n40782,\n40783,\n40786,\n40787,\n40788,\n40789,\n40790,\n40791,\n40792,\n40793,\n40794,\n40795,\n40796,\n40797,\n40798,\n40799,\n40800,\n40801,\n40802,\n40803,\n40804,\n40805,\n40806,\n40807,\n40808,\n40809,\n40810,\n40811,\n40812,\n40813,\n40814,\n40815,\n40816,\n40817,\n40818,\n40819,\n40820,\n40821,\n40822,\n40823,\n40824,\n0,\n40825,\n40826,\n40827,\n40828,\n40829,\n40830,\n40833,\n40834,\n40845,\n40846,\n40847,\n40848,\n40849,\n40850,\n40851,\n40852,\n40853,\n40854,\n40855,\n40856,\n40860,\n40861,\n40862,\n40865,\n40866,\n40867,\n40868,\n40869,\n63788,\n63865,\n63893,\n63975,\n63985,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n64012,\n64013,\n64014,\n64015,\n64017,\n64019,\n64020,\n64024,\n64031,\n64032,\n64033,\n64035,\n64036,\n64039,\n64040,\n64041,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n0 };\n\nint gbk_mbtowc(unsigned short *wc, const unsigned char *s)\n{\n\tif (*s < 128) {\n\t\t*wc = *s;\n\t\treturn 1;\n\t}\n\tunsigned int idx = (s[0] << 8) | (s[1]);\n\tif (idx >= 0x8100) {\n\t\tunsigned short unichar = gbk2uni[idx - 0x8100];\n\t\tif (unichar) {\n\t\t\t*wc = unichar;\n\t\t\treturn 2;\n\t\t}\n\t}\n\treturn -1;\n}"
  },
  {
    "path": "src/core/utils/encoding/jis2unicode.c",
    "content": "// lower bit, 0xFFFF for double byte character\nstatic unsigned short jis2uni_low[] =\n{0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n 21,\n 22,\n 23,\n 24,\n 25,\n 26,\n 27,\n 28,\n 29,\n 30,\n 31,\n 32,\n 33,\n 34,\n 35,\n 36,\n 37,\n 38,\n 39,\n 40,\n 41,\n 42,\n 43,\n 44,\n 45,\n 46,\n 47,\n 48,\n 49,\n 50,\n 51,\n 52,\n 53,\n 54,\n 55,\n 56,\n 57,\n 58,\n 59,\n 60,\n 61,\n 62,\n 63,\n 64,\n 65,\n 66,\n 67,\n 68,\n 69,\n 70,\n 71,\n 72,\n 73,\n 74,\n 75,\n 76,\n 77,\n 78,\n 79,\n 80,\n 81,\n 82,\n 83,\n 84,\n 85,\n 86,\n 87,\n 88,\n 89,\n 90,\n 91,\n 92,\n 93,\n 94,\n 95,\n 96,\n 97,\n 98,\n 99,\n 100,\n 101,\n 102,\n 103,\n 104,\n 105,\n 106,\n 107,\n 108,\n 109,\n 110,\n 111,\n 112,\n 113,\n 114,\n 115,\n 116,\n 117,\n 118,\n 119,\n 120,\n 121,\n 122,\n 123,\n 124,\n 125,\n 126,\n 127,\n 128,\n 65535,\n 65535,\n 65535,\n 65535,\n 0,\n 0,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 63728,\n 65377,\n 65378,\n 65379,\n 65380,\n 65381,\n 65382,\n 65383,\n 65384,\n 65385,\n 65386,\n 65387,\n 65388,\n 65389,\n 65390,\n 65391,\n 65392,\n 65393,\n 65394,\n 65395,\n 65396,\n 65397,\n 65398,\n 65399,\n 65400,\n 65401,\n 65402,\n 65403,\n 65404,\n 65405,\n 65406,\n 65407,\n 65408,\n 65409,\n 65410,\n 65411,\n 65412,\n 65413,\n 65414,\n 65415,\n 65416,\n 65417,\n 65418,\n 65419,\n 65420,\n 65421,\n 65422,\n 65423,\n 65424,\n 65425,\n 65426,\n 65427,\n 65428,\n 65429,\n 65430,\n 65431,\n 65432,\n 65433,\n 65434,\n 65435,\n 65436,\n 65437,\n 65438,\n 65439,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 0,\n 0,\n 65535,\n 65535,\n 0,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 65535,\n 63729,\n 63730,\n 63731};\n\n// higher bit, indexed from 0x8000\nstatic unsigned short jis2uni_high[] =\n{0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 12288,\n 12289,\n 12290,\n 65292,\n 65294,\n 12539,\n 65306,\n 65307,\n 65311,\n 65281,\n 12443,\n 12444,\n 180,\n 65344,\n 168,\n 65342,\n 65507,\n 65343,\n 12541,\n 12542,\n 12445,\n 12446,\n 12291,\n 20189,\n 12293,\n 12294,\n 12295,\n 12540,\n 8213,\n 8208,\n 65295,\n 65340,\n 65374,\n 8741,\n 65372,\n 8230,\n 8229,\n 8216,\n 8217,\n 8220,\n 8221,\n 65288,\n 65289,\n 12308,\n 12309,\n 65339,\n 65341,\n 65371,\n 65373,\n 12296,\n 12297,\n 12298,\n 12299,\n 12300,\n 12301,\n 12302,\n 12303,\n 12304,\n 12305,\n 65291,\n 65293,\n 177,\n 215,\n 0,\n 247,\n 65309,\n 8800,\n 65308,\n 65310,\n 8806,\n 8807,\n 8734,\n 8756,\n 9794,\n 9792,\n 176,\n 8242,\n 8243,\n 8451,\n 65509,\n 65284,\n 65504,\n 65505,\n 65285,\n 65283,\n 65286,\n 65290,\n 65312,\n 167,\n 9734,\n 9733,\n 9675,\n 9679,\n 9678,\n 9671,\n 9670,\n 9633,\n 9632,\n 9651,\n 9650,\n 9661,\n 9660,\n 8251,\n 12306,\n 8594,\n 8592,\n 8593,\n 8595,\n 12307,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 8712,\n 8715,\n 8838,\n 8839,\n 8834,\n 8835,\n 8746,\n 8745,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 8743,\n 8744,\n 65506,\n 8658,\n 8660,\n 8704,\n 8707,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 8736,\n 8869,\n 8978,\n 8706,\n 8711,\n 8801,\n 8786,\n 8810,\n 8811,\n 8730,\n 8765,\n 8733,\n 8757,\n 8747,\n 8748,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 8491,\n 8240,\n 9839,\n 9837,\n 9834,\n 8224,\n 8225,\n 182,\n 0,\n 0,\n 0,\n 0,\n 9711,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 65296,\n 65297,\n 65298,\n 65299,\n 65300,\n 65301,\n 65302,\n 65303,\n 65304,\n 65305,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 65313,\n 65314,\n 65315,\n 65316,\n 65317,\n 65318,\n 65319,\n 65320,\n 65321,\n 65322,\n 65323,\n 65324,\n 65325,\n 65326,\n 65327,\n 65328,\n 65329,\n 65330,\n 65331,\n 65332,\n 65333,\n 65334,\n 65335,\n 65336,\n 65337,\n 65338,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 65345,\n 65346,\n 65347,\n 65348,\n 65349,\n 65350,\n 65351,\n 65352,\n 65353,\n 65354,\n 65355,\n 65356,\n 65357,\n 65358,\n 65359,\n 65360,\n 65361,\n 65362,\n 65363,\n 65364,\n 65365,\n 65366,\n 65367,\n 65368,\n 65369,\n 65370,\n 0,\n 0,\n 0,\n 0,\n 12353,\n 12354,\n 12355,\n 12356,\n 12357,\n 12358,\n 12359,\n 12360,\n 12361,\n 12362,\n 12363,\n 12364,\n 12365,\n 12366,\n 12367,\n 12368,\n 12369,\n 12370,\n 12371,\n 12372,\n 12373,\n 12374,\n 12375,\n 12376,\n 12377,\n 12378,\n 12379,\n 12380,\n 12381,\n 12382,\n 12383,\n 12384,\n 12385,\n 12386,\n 12387,\n 12388,\n 12389,\n 12390,\n 12391,\n 12392,\n 12393,\n 12394,\n 12395,\n 12396,\n 12397,\n 12398,\n 12399,\n 12400,\n 12401,\n 12402,\n 12403,\n 12404,\n 12405,\n 12406,\n 12407,\n 12408,\n 12409,\n 12410,\n 12411,\n 12412,\n 12413,\n 12414,\n 12415,\n 12416,\n 12417,\n 12418,\n 12419,\n 12420,\n 12421,\n 12422,\n 12423,\n 12424,\n 12425,\n 12426,\n 12427,\n 12428,\n 12429,\n 12430,\n 12431,\n 12432,\n 12433,\n 12434,\n 12435,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 12449,\n 12450,\n 12451,\n 12452,\n 12453,\n 12454,\n 12455,\n 12456,\n 12457,\n 12458,\n 12459,\n 12460,\n 12461,\n 12462,\n 12463,\n 12464,\n 12465,\n 12466,\n 12467,\n 12468,\n 12469,\n 12470,\n 12471,\n 12472,\n 12473,\n 12474,\n 12475,\n 12476,\n 12477,\n 12478,\n 12479,\n 12480,\n 12481,\n 12482,\n 12483,\n 12484,\n 12485,\n 12486,\n 12487,\n 12488,\n 12489,\n 12490,\n 12491,\n 12492,\n 12493,\n 12494,\n 12495,\n 12496,\n 12497,\n 12498,\n 12499,\n 12500,\n 12501,\n 12502,\n 12503,\n 12504,\n 12505,\n 12506,\n 12507,\n 12508,\n 12509,\n 12510,\n 12511,\n 0,\n 12512,\n 12513,\n 12514,\n 12515,\n 12516,\n 12517,\n 12518,\n 12519,\n 12520,\n 12521,\n 12522,\n 12523,\n 12524,\n 12525,\n 12526,\n 12527,\n 12528,\n 12529,\n 12530,\n 12531,\n 12532,\n 12533,\n 12534,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 913,\n 914,\n 915,\n 916,\n 917,\n 918,\n 919,\n 920,\n 921,\n 922,\n 923,\n 924,\n 925,\n 926,\n 927,\n 928,\n 929,\n 931,\n 932,\n 933,\n 934,\n 935,\n 936,\n 937,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 945,\n 946,\n 947,\n 948,\n 949,\n 950,\n 951,\n 952,\n 953,\n 954,\n 955,\n 956,\n 957,\n 958,\n 959,\n 960,\n 961,\n 963,\n 964,\n 965,\n 966,\n 967,\n 968,\n 969,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 1040,\n 1041,\n 1042,\n 1043,\n 1044,\n 1045,\n 1025,\n 1046,\n 1047,\n 1048,\n 1049,\n 1050,\n 1051,\n 1052,\n 1053,\n 1054,\n 1055,\n 1056,\n 1057,\n 1058,\n 1059,\n 1060,\n 1061,\n 1062,\n 1063,\n 1064,\n 1065,\n 1066,\n 1067,\n 1068,\n 1069,\n 1070,\n 1071,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 1072,\n 1073,\n 1074,\n 1075,\n 1076,\n 1077,\n 1105,\n 1078,\n 1079,\n 1080,\n 1081,\n 1082,\n 1083,\n 1084,\n 1085,\n 0,\n 1086,\n 1087,\n 1088,\n 1089,\n 1090,\n 1091,\n 1092,\n 1093,\n 1094,\n 1095,\n 1096,\n 1097,\n 1098,\n 1099,\n 1100,\n 1101,\n 1102,\n 1103,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 9472,\n 9474,\n 9484,\n 9488,\n 9496,\n 9492,\n 9500,\n 9516,\n 9508,\n 9524,\n 9532,\n 9473,\n 9475,\n 9487,\n 9491,\n 9499,\n 9495,\n 9507,\n 9523,\n 9515,\n 9531,\n 9547,\n 9504,\n 9519,\n 9512,\n 9527,\n 9535,\n 9501,\n 9520,\n 9509,\n 9528,\n 9538,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 9312,\n 9313,\n 9314,\n 9315,\n 9316,\n 9317,\n 9318,\n 9319,\n 9320,\n 9321,\n 9322,\n 9323,\n 9324,\n 9325,\n 9326,\n 9327,\n 9328,\n 9329,\n 9330,\n 9331,\n 8544,\n 8545,\n 8546,\n 8547,\n 8548,\n 8549,\n 8550,\n 8551,\n 8552,\n 8553,\n 0,\n 13129,\n 13076,\n 13090,\n 13133,\n 13080,\n 13095,\n 13059,\n 13110,\n 13137,\n 13143,\n 13069,\n 13094,\n 13091,\n 13099,\n 13130,\n 13115,\n 13212,\n 13213,\n 13214,\n 13198,\n 13199,\n 13252,\n 13217,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 13179,\n 0,\n 12317,\n 12319,\n 8470,\n 13261,\n 8481,\n 12964,\n 12965,\n 12966,\n 12967,\n 12968,\n 12849,\n 12850,\n 12857,\n 13182,\n 13181,\n 13180,\n 8786,\n 8801,\n 8747,\n 8750,\n 8721,\n 8730,\n 8869,\n 8736,\n 8735,\n 8895,\n 8757,\n 8745,\n 8746,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 20124,\n 21782,\n 23043,\n 38463,\n 21696,\n 24859,\n 25384,\n 23030,\n 36898,\n 33909,\n 33564,\n 31312,\n 24746,\n 25569,\n 28197,\n 26093,\n 33894,\n 33446,\n 39925,\n 26771,\n 22311,\n 26017,\n 25201,\n 23451,\n 22992,\n 34427,\n 39156,\n 32098,\n 32190,\n 39822,\n 25110,\n 31903,\n 34999,\n 23433,\n 24245,\n 25353,\n 26263,\n 26696,\n 38343,\n 38797,\n 26447,\n 20197,\n 20234,\n 20301,\n 20381,\n 20553,\n 22258,\n 22839,\n 22996,\n 23041,\n 23561,\n 24799,\n 24847,\n 24944,\n 26131,\n 26885,\n 28858,\n 30031,\n 30064,\n 31227,\n 32173,\n 32239,\n 32963,\n 33806,\n 34915,\n 35586,\n 36949,\n 36986,\n 21307,\n 20117,\n 20133,\n 22495,\n 32946,\n 37057,\n 30959,\n 19968,\n 22769,\n 28322,\n 36920,\n 31282,\n 33576,\n 33419,\n 39983,\n 20801,\n 21360,\n 21693,\n 21729,\n 22240,\n 23035,\n 24341,\n 39154,\n 28139,\n 32996,\n 34093,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 38498,\n 38512,\n 38560,\n 38907,\n 21515,\n 21491,\n 23431,\n 28879,\n 32701,\n 36802,\n 38632,\n 21359,\n 40284,\n 31418,\n 19985,\n 30867,\n 33276,\n 28198,\n 22040,\n 21764,\n 27421,\n 34074,\n 39995,\n 23013,\n 21417,\n 28006,\n 29916,\n 38287,\n 22082,\n 20113,\n 36939,\n 38642,\n 33615,\n 39180,\n 21473,\n 21942,\n 23344,\n 24433,\n 26144,\n 26355,\n 26628,\n 27704,\n 27891,\n 27945,\n 29787,\n 30408,\n 31310,\n 38964,\n 33521,\n 34907,\n 35424,\n 37613,\n 28082,\n 30123,\n 30410,\n 39365,\n 24742,\n 35585,\n 36234,\n 38322,\n 27022,\n 21421,\n 20870,\n 0,\n 22290,\n 22576,\n 22852,\n 23476,\n 24310,\n 24616,\n 25513,\n 25588,\n 27839,\n 28436,\n 28814,\n 28948,\n 29017,\n 29141,\n 29503,\n 32257,\n 33398,\n 33489,\n 34199,\n 36960,\n 37467,\n 40219,\n 22633,\n 26044,\n 27738,\n 29989,\n 20985,\n 22830,\n 22885,\n 24448,\n 24540,\n 25276,\n 26106,\n 27178,\n 27431,\n 27572,\n 29579,\n 32705,\n 35158,\n 40236,\n 40206,\n 40644,\n 23713,\n 27798,\n 33659,\n 20740,\n 23627,\n 25014,\n 33222,\n 26742,\n 29281,\n 20057,\n 20474,\n 21368,\n 24681,\n 28201,\n 31311,\n 38899,\n 19979,\n 21270,\n 20206,\n 20309,\n 20285,\n 20385,\n 20339,\n 21152,\n 21487,\n 22025,\n 22799,\n 23233,\n 23478,\n 23521,\n 31185,\n 26247,\n 26524,\n 26550,\n 27468,\n 27827,\n 28779,\n 29634,\n 31117,\n 31166,\n 31292,\n 31623,\n 33457,\n 33499,\n 33540,\n 33655,\n 33775,\n 33747,\n 34662,\n 35506,\n 22057,\n 36008,\n 36838,\n 36942,\n 38686,\n 34442,\n 20420,\n 23784,\n 25105,\n 29273,\n 30011,\n 33253,\n 33469,\n 34558,\n 36032,\n 38597,\n 39187,\n 39381,\n 20171,\n 20250,\n 35299,\n 22238,\n 22602,\n 22730,\n 24315,\n 24555,\n 24618,\n 24724,\n 24674,\n 25040,\n 25106,\n 25296,\n 25913,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 39745,\n 26214,\n 26800,\n 28023,\n 28784,\n 30028,\n 30342,\n 32117,\n 33445,\n 34809,\n 38283,\n 38542,\n 35997,\n 20977,\n 21182,\n 22806,\n 21683,\n 23475,\n 23830,\n 24936,\n 27010,\n 28079,\n 30861,\n 33995,\n 34903,\n 35442,\n 37799,\n 39608,\n 28012,\n 39336,\n 34521,\n 22435,\n 26623,\n 34510,\n 37390,\n 21123,\n 22151,\n 21508,\n 24275,\n 25313,\n 25785,\n 26684,\n 26680,\n 27579,\n 29554,\n 30906,\n 31339,\n 35226,\n 35282,\n 36203,\n 36611,\n 37101,\n 38307,\n 38548,\n 38761,\n 23398,\n 23731,\n 27005,\n 38989,\n 38990,\n 25499,\n 31520,\n 27179,\n 0,\n 27263,\n 26806,\n 39949,\n 28511,\n 21106,\n 21917,\n 24688,\n 25324,\n 27963,\n 28167,\n 28369,\n 33883,\n 35088,\n 36676,\n 19988,\n 39993,\n 21494,\n 26907,\n 27194,\n 38788,\n 26666,\n 20828,\n 31427,\n 33970,\n 37340,\n 37772,\n 22107,\n 40232,\n 26658,\n 33541,\n 33841,\n 31909,\n 21000,\n 33477,\n 29926,\n 20094,\n 20355,\n 20896,\n 23506,\n 21002,\n 21208,\n 21223,\n 24059,\n 21914,\n 22570,\n 23014,\n 23436,\n 23448,\n 23515,\n 24178,\n 24185,\n 24739,\n 24863,\n 24931,\n 25022,\n 25563,\n 25954,\n 26577,\n 26707,\n 26874,\n 27454,\n 27475,\n 27735,\n 28450,\n 28567,\n 28485,\n 29872,\n 29976,\n 30435,\n 30475,\n 31487,\n 31649,\n 31777,\n 32233,\n 32566,\n 32752,\n 32925,\n 33382,\n 33694,\n 35251,\n 35532,\n 36011,\n 36996,\n 37969,\n 38291,\n 38289,\n 38306,\n 38501,\n 38867,\n 39208,\n 33304,\n 20024,\n 21547,\n 23736,\n 24012,\n 29609,\n 30284,\n 30524,\n 23721,\n 32747,\n 36107,\n 38593,\n 38929,\n 38996,\n 39000,\n 20225,\n 20238,\n 21361,\n 21916,\n 22120,\n 22522,\n 22855,\n 23305,\n 23492,\n 23696,\n 24076,\n 24190,\n 24524,\n 25582,\n 26426,\n 26071,\n 26082,\n 26399,\n 26827,\n 26820,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 27231,\n 24112,\n 27589,\n 27671,\n 27773,\n 30079,\n 31048,\n 23395,\n 31232,\n 32000,\n 24509,\n 35215,\n 35352,\n 36020,\n 36215,\n 36556,\n 36637,\n 39138,\n 39438,\n 39740,\n 20096,\n 20605,\n 20736,\n 22931,\n 23452,\n 25135,\n 25216,\n 25836,\n 27450,\n 29344,\n 30097,\n 31047,\n 32681,\n 34811,\n 35516,\n 35696,\n 25516,\n 33738,\n 38816,\n 21513,\n 21507,\n 21931,\n 26708,\n 27224,\n 35440,\n 30759,\n 26485,\n 40653,\n 21364,\n 23458,\n 33050,\n 34384,\n 36870,\n 19992,\n 20037,\n 20167,\n 20241,\n 21450,\n 21560,\n 23470,\n 24339,\n 24613,\n 25937,\n 0,\n 26429,\n 27714,\n 27762,\n 27875,\n 28792,\n 29699,\n 31350,\n 31406,\n 31496,\n 32026,\n 31998,\n 32102,\n 26087,\n 29275,\n 21435,\n 23621,\n 24040,\n 25298,\n 25312,\n 25369,\n 28192,\n 34394,\n 35377,\n 36317,\n 37624,\n 28417,\n 31142,\n 39770,\n 20136,\n 20139,\n 20140,\n 20379,\n 20384,\n 20689,\n 20807,\n 31478,\n 20849,\n 20982,\n 21332,\n 21281,\n 21375,\n 21483,\n 21932,\n 22659,\n 23777,\n 24375,\n 24394,\n 24623,\n 24656,\n 24685,\n 25375,\n 25945,\n 27211,\n 27841,\n 29378,\n 29421,\n 30703,\n 33016,\n 33029,\n 33288,\n 34126,\n 37111,\n 37857,\n 38911,\n 39255,\n 39514,\n 20208,\n 20957,\n 23597,\n 26241,\n 26989,\n 23616,\n 26354,\n 26997,\n 29577,\n 26704,\n 31873,\n 20677,\n 21220,\n 22343,\n 24062,\n 37670,\n 26020,\n 27427,\n 27453,\n 29748,\n 31105,\n 31165,\n 31563,\n 32202,\n 33465,\n 33740,\n 34943,\n 35167,\n 35641,\n 36817,\n 37329,\n 21535,\n 37504,\n 20061,\n 20534,\n 21477,\n 21306,\n 29399,\n 29590,\n 30697,\n 33510,\n 36527,\n 39366,\n 39368,\n 39378,\n 20855,\n 24858,\n 34398,\n 21936,\n 31354,\n 20598,\n 23507,\n 36935,\n 38533,\n 20018,\n 27355,\n 37351,\n 23633,\n 23624,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 25496,\n 31391,\n 27795,\n 38772,\n 36705,\n 31402,\n 29066,\n 38536,\n 31874,\n 26647,\n 32368,\n 26705,\n 37740,\n 21234,\n 21531,\n 34219,\n 35347,\n 32676,\n 36557,\n 37089,\n 21350,\n 34952,\n 31041,\n 20418,\n 20670,\n 21009,\n 20804,\n 21843,\n 22317,\n 29674,\n 22411,\n 22865,\n 24418,\n 24452,\n 24693,\n 24950,\n 24935,\n 25001,\n 25522,\n 25658,\n 25964,\n 26223,\n 26690,\n 28179,\n 30054,\n 31293,\n 31995,\n 32076,\n 32153,\n 32331,\n 32619,\n 33550,\n 33610,\n 34509,\n 35336,\n 35427,\n 35686,\n 36605,\n 38938,\n 40335,\n 33464,\n 36814,\n 39912,\n 0,\n 21127,\n 25119,\n 25731,\n 28608,\n 38553,\n 26689,\n 20625,\n 27424,\n 27770,\n 28500,\n 31348,\n 32080,\n 34880,\n 35363,\n 26376,\n 20214,\n 20537,\n 20518,\n 20581,\n 20860,\n 21048,\n 21091,\n 21927,\n 22287,\n 22533,\n 23244,\n 24314,\n 25010,\n 25080,\n 25331,\n 25458,\n 26908,\n 27177,\n 29309,\n 29356,\n 29486,\n 30740,\n 30831,\n 32121,\n 30476,\n 32937,\n 35211,\n 35609,\n 36066,\n 36562,\n 36963,\n 37749,\n 38522,\n 38997,\n 39443,\n 40568,\n 20803,\n 21407,\n 21427,\n 24187,\n 24358,\n 28187,\n 28304,\n 29572,\n 29694,\n 32067,\n 33335,\n 35328,\n 35578,\n 38480,\n 20046,\n 20491,\n 21476,\n 21628,\n 22266,\n 22993,\n 23396,\n 24049,\n 24235,\n 24359,\n 25144,\n 25925,\n 26543,\n 28246,\n 29392,\n 31946,\n 34996,\n 32929,\n 32993,\n 33776,\n 34382,\n 35463,\n 36328,\n 37431,\n 38599,\n 39015,\n 40723,\n 20116,\n 20114,\n 20237,\n 21320,\n 21577,\n 21566,\n 23087,\n 24460,\n 24481,\n 24735,\n 26791,\n 27278,\n 29786,\n 30849,\n 35486,\n 35492,\n 35703,\n 37264,\n 20062,\n 39881,\n 20132,\n 20348,\n 20399,\n 20505,\n 20502,\n 20809,\n 20844,\n 21151,\n 21177,\n 21246,\n 21402,\n 21475,\n 21521,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 21518,\n 21897,\n 22353,\n 22434,\n 22909,\n 23380,\n 23389,\n 23439,\n 24037,\n 24039,\n 24055,\n 24184,\n 24195,\n 24218,\n 24247,\n 24344,\n 24658,\n 24908,\n 25239,\n 25304,\n 25511,\n 25915,\n 26114,\n 26179,\n 26356,\n 26477,\n 26657,\n 26775,\n 27083,\n 27743,\n 27946,\n 28009,\n 28207,\n 28317,\n 30002,\n 30343,\n 30828,\n 31295,\n 31968,\n 32005,\n 32024,\n 32094,\n 32177,\n 32789,\n 32771,\n 32943,\n 32945,\n 33108,\n 33167,\n 33322,\n 33618,\n 34892,\n 34913,\n 35611,\n 36002,\n 36092,\n 37066,\n 37237,\n 37489,\n 30783,\n 37628,\n 38308,\n 38477,\n 0,\n 38917,\n 39321,\n 39640,\n 40251,\n 21083,\n 21163,\n 21495,\n 21512,\n 22741,\n 25335,\n 28640,\n 35946,\n 36703,\n 40633,\n 20811,\n 21051,\n 21578,\n 22269,\n 31296,\n 37239,\n 40288,\n 40658,\n 29508,\n 28425,\n 33136,\n 29969,\n 24573,\n 24794,\n 39592,\n 29403,\n 36796,\n 27492,\n 38915,\n 20170,\n 22256,\n 22372,\n 22718,\n 23130,\n 24680,\n 25031,\n 26127,\n 26118,\n 26681,\n 26801,\n 28151,\n 30165,\n 32058,\n 33390,\n 39746,\n 20123,\n 20304,\n 21449,\n 21766,\n 23919,\n 24038,\n 24046,\n 26619,\n 27801,\n 29811,\n 30722,\n 35408,\n 37782,\n 35039,\n 22352,\n 24231,\n 25387,\n 20661,\n 20652,\n 20877,\n 26368,\n 21705,\n 22622,\n 22971,\n 23472,\n 24425,\n 25165,\n 25505,\n 26685,\n 27507,\n 28168,\n 28797,\n 37319,\n 29312,\n 30741,\n 30758,\n 31085,\n 25998,\n 32048,\n 33756,\n 35009,\n 36617,\n 38555,\n 21092,\n 22312,\n 26448,\n 32618,\n 36001,\n 20916,\n 22338,\n 38442,\n 22586,\n 27018,\n 32948,\n 21682,\n 23822,\n 22524,\n 30869,\n 40442,\n 20316,\n 21066,\n 21643,\n 25662,\n 26152,\n 26388,\n 26613,\n 31364,\n 31574,\n 32034,\n 37679,\n 26716,\n 39853,\n 31545,\n 21273,\n 20874,\n 21047,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 23519,\n 25334,\n 25774,\n 25830,\n 26413,\n 27578,\n 34217,\n 38609,\n 30352,\n 39894,\n 25420,\n 37638,\n 39851,\n 30399,\n 26194,\n 19977,\n 20632,\n 21442,\n 23665,\n 24808,\n 25746,\n 25955,\n 26719,\n 29158,\n 29642,\n 29987,\n 31639,\n 32386,\n 34453,\n 35715,\n 36059,\n 37240,\n 39184,\n 26028,\n 26283,\n 27531,\n 20181,\n 20180,\n 20282,\n 20351,\n 21050,\n 21496,\n 21490,\n 21987,\n 22235,\n 22763,\n 22987,\n 22985,\n 23039,\n 23376,\n 23629,\n 24066,\n 24107,\n 24535,\n 24605,\n 25351,\n 25903,\n 23388,\n 26031,\n 26045,\n 26088,\n 26525,\n 27490,\n 0,\n 27515,\n 27663,\n 29509,\n 31049,\n 31169,\n 31992,\n 32025,\n 32043,\n 32930,\n 33026,\n 33267,\n 35222,\n 35422,\n 35433,\n 35430,\n 35468,\n 35566,\n 36039,\n 36060,\n 38604,\n 39164,\n 27503,\n 20107,\n 20284,\n 20365,\n 20816,\n 23383,\n 23546,\n 24904,\n 25345,\n 26178,\n 27425,\n 28363,\n 27835,\n 29246,\n 29885,\n 30164,\n 30913,\n 31034,\n 32780,\n 32819,\n 33258,\n 33940,\n 36766,\n 27728,\n 40575,\n 24335,\n 35672,\n 40235,\n 31482,\n 36600,\n 23437,\n 38635,\n 19971,\n 21489,\n 22519,\n 22833,\n 23241,\n 23460,\n 24713,\n 28287,\n 28422,\n 30142,\n 36074,\n 23455,\n 34048,\n 31712,\n 20594,\n 26612,\n 33437,\n 23649,\n 34122,\n 32286,\n 33294,\n 20889,\n 23556,\n 25448,\n 36198,\n 26012,\n 29038,\n 31038,\n 32023,\n 32773,\n 35613,\n 36554,\n 36974,\n 34503,\n 37034,\n 20511,\n 21242,\n 23610,\n 26451,\n 28796,\n 29237,\n 37196,\n 37320,\n 37675,\n 33509,\n 23490,\n 24369,\n 24825,\n 20027,\n 21462,\n 23432,\n 25163,\n 26417,\n 27530,\n 29417,\n 29664,\n 31278,\n 33131,\n 36259,\n 37202,\n 39318,\n 20754,\n 21463,\n 21610,\n 23551,\n 25480,\n 27193,\n 32172,\n 38656,\n 22234,\n 21454,\n 21608,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 23447,\n 23601,\n 24030,\n 20462,\n 24833,\n 25342,\n 27954,\n 31168,\n 31179,\n 32066,\n 32333,\n 32722,\n 33261,\n 33311,\n 33936,\n 34886,\n 35186,\n 35728,\n 36468,\n 36655,\n 36913,\n 37195,\n 37228,\n 38598,\n 37276,\n 20160,\n 20303,\n 20805,\n 21313,\n 24467,\n 25102,\n 26580,\n 27713,\n 28171,\n 29539,\n 32294,\n 37325,\n 37507,\n 21460,\n 22809,\n 23487,\n 28113,\n 31069,\n 32302,\n 31899,\n 22654,\n 29087,\n 20986,\n 34899,\n 36848,\n 20426,\n 23803,\n 26149,\n 30636,\n 31459,\n 33308,\n 39423,\n 20934,\n 24490,\n 26092,\n 26991,\n 27529,\n 28147,\n 0,\n 28310,\n 28516,\n 30462,\n 32020,\n 24033,\n 36981,\n 37255,\n 38918,\n 20966,\n 21021,\n 25152,\n 26257,\n 26329,\n 28186,\n 24246,\n 32210,\n 32626,\n 26360,\n 34223,\n 34295,\n 35576,\n 21161,\n 21465,\n 22899,\n 24207,\n 24464,\n 24661,\n 37604,\n 38500,\n 20663,\n 20767,\n 21213,\n 21280,\n 21319,\n 21484,\n 21736,\n 21830,\n 21809,\n 22039,\n 22888,\n 22974,\n 23100,\n 23477,\n 23558,\n 23567,\n 23569,\n 23578,\n 24196,\n 24202,\n 24288,\n 24432,\n 25215,\n 25220,\n 25307,\n 25484,\n 25463,\n 26119,\n 26124,\n 26157,\n 26230,\n 26494,\n 26786,\n 27167,\n 27189,\n 27836,\n 28040,\n 28169,\n 28248,\n 28988,\n 28966,\n 29031,\n 30151,\n 30465,\n 30813,\n 30977,\n 31077,\n 31216,\n 31456,\n 31505,\n 31911,\n 32057,\n 32918,\n 33750,\n 33931,\n 34121,\n 34909,\n 35059,\n 35359,\n 35388,\n 35412,\n 35443,\n 35937,\n 36062,\n 37284,\n 37478,\n 37758,\n 37912,\n 38556,\n 38808,\n 19978,\n 19976,\n 19998,\n 20055,\n 20887,\n 21104,\n 22478,\n 22580,\n 22732,\n 23330,\n 24120,\n 24773,\n 25854,\n 26465,\n 26454,\n 27972,\n 29366,\n 30067,\n 31331,\n 33976,\n 35698,\n 37304,\n 37664,\n 22065,\n 22516,\n 39166,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 25325,\n 26893,\n 27542,\n 29165,\n 32340,\n 32887,\n 33394,\n 35302,\n 39135,\n 34645,\n 36785,\n 23611,\n 20280,\n 20449,\n 20405,\n 21767,\n 23072,\n 23517,\n 23529,\n 24515,\n 24910,\n 25391,\n 26032,\n 26187,\n 26862,\n 27035,\n 28024,\n 28145,\n 30003,\n 30137,\n 30495,\n 31070,\n 31206,\n 32051,\n 33251,\n 33455,\n 34218,\n 35242,\n 35386,\n 36523,\n 36763,\n 36914,\n 37341,\n 38663,\n 20154,\n 20161,\n 20995,\n 22645,\n 22764,\n 23563,\n 29978,\n 23613,\n 33102,\n 35338,\n 36805,\n 38499,\n 38765,\n 31525,\n 35535,\n 38920,\n 37218,\n 22259,\n 21416,\n 0,\n 36887,\n 21561,\n 22402,\n 24101,\n 25512,\n 27700,\n 28810,\n 30561,\n 31883,\n 32736,\n 34928,\n 36930,\n 37204,\n 37648,\n 37656,\n 38543,\n 29790,\n 39620,\n 23815,\n 23913,\n 25968,\n 26530,\n 36264,\n 38619,\n 25454,\n 26441,\n 26905,\n 33733,\n 38935,\n 38592,\n 35070,\n 28548,\n 25722,\n 23544,\n 19990,\n 28716,\n 30045,\n 26159,\n 20932,\n 21046,\n 21218,\n 22995,\n 24449,\n 24615,\n 25104,\n 25919,\n 25972,\n 26143,\n 26228,\n 26866,\n 26646,\n 27491,\n 28165,\n 29298,\n 29983,\n 30427,\n 31934,\n 32854,\n 22768,\n 35069,\n 35199,\n 35488,\n 35475,\n 35531,\n 36893,\n 37266,\n 38738,\n 38745,\n 25993,\n 31246,\n 33030,\n 38587,\n 24109,\n 24796,\n 25114,\n 26021,\n 26132,\n 26512,\n 30707,\n 31309,\n 31821,\n 32318,\n 33034,\n 36012,\n 36196,\n 36321,\n 36447,\n 30889,\n 20999,\n 25305,\n 25509,\n 25666,\n 25240,\n 35373,\n 31363,\n 31680,\n 35500,\n 38634,\n 32118,\n 33292,\n 34633,\n 20185,\n 20808,\n 21315,\n 21344,\n 23459,\n 23554,\n 23574,\n 24029,\n 25126,\n 25159,\n 25776,\n 26643,\n 26676,\n 27849,\n 27973,\n 27927,\n 26579,\n 28508,\n 29006,\n 29053,\n 26059,\n 31359,\n 31661,\n 32218,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 32330,\n 32680,\n 33146,\n 33307,\n 33337,\n 34214,\n 35438,\n 36046,\n 36341,\n 36984,\n 36983,\n 37549,\n 37521,\n 38275,\n 39854,\n 21069,\n 21892,\n 28472,\n 28982,\n 20840,\n 31109,\n 32341,\n 33203,\n 31950,\n 22092,\n 22609,\n 23720,\n 25514,\n 26366,\n 26365,\n 26970,\n 29401,\n 30095,\n 30094,\n 30990,\n 31062,\n 31199,\n 31895,\n 32032,\n 32068,\n 34311,\n 35380,\n 38459,\n 36961,\n 40736,\n 20711,\n 21109,\n 21452,\n 21474,\n 20489,\n 21930,\n 22766,\n 22863,\n 29245,\n 23435,\n 23652,\n 21277,\n 24803,\n 24819,\n 25436,\n 25475,\n 25407,\n 25531,\n 0,\n 25805,\n 26089,\n 26361,\n 24035,\n 27085,\n 27133,\n 28437,\n 29157,\n 20105,\n 30185,\n 30456,\n 31379,\n 31967,\n 32207,\n 32156,\n 32865,\n 33609,\n 33624,\n 33900,\n 33980,\n 34299,\n 35013,\n 36208,\n 36865,\n 36973,\n 37783,\n 38684,\n 39442,\n 20687,\n 22679,\n 24974,\n 33235,\n 34101,\n 36104,\n 36896,\n 20419,\n 20596,\n 21063,\n 21363,\n 24687,\n 25417,\n 26463,\n 28204,\n 36275,\n 36895,\n 20439,\n 23646,\n 36042,\n 26063,\n 32154,\n 21330,\n 34966,\n 20854,\n 25539,\n 23384,\n 23403,\n 23562,\n 25613,\n 26449,\n 36956,\n 20182,\n 22810,\n 22826,\n 27760,\n 35409,\n 21822,\n 22549,\n 22949,\n 24816,\n 25171,\n 26561,\n 33333,\n 26965,\n 38464,\n 39364,\n 39464,\n 20307,\n 22534,\n 23550,\n 32784,\n 23729,\n 24111,\n 24453,\n 24608,\n 24907,\n 25140,\n 26367,\n 27888,\n 28382,\n 32974,\n 33151,\n 33492,\n 34955,\n 36024,\n 36864,\n 36910,\n 38538,\n 40667,\n 39899,\n 20195,\n 21488,\n 22823,\n 31532,\n 37261,\n 38988,\n 40441,\n 28381,\n 28711,\n 21331,\n 21828,\n 23429,\n 25176,\n 25246,\n 25299,\n 27810,\n 28655,\n 29730,\n 35351,\n 37944,\n 28609,\n 35582,\n 33592,\n 20967,\n 34552,\n 21482,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 21481,\n 20294,\n 36948,\n 36784,\n 22890,\n 33073,\n 24061,\n 31466,\n 36799,\n 26842,\n 35895,\n 29432,\n 40008,\n 27197,\n 35504,\n 20025,\n 21336,\n 22022,\n 22374,\n 25285,\n 25506,\n 26086,\n 27470,\n 28129,\n 28251,\n 28845,\n 30701,\n 31471,\n 31658,\n 32187,\n 32829,\n 32966,\n 34507,\n 35477,\n 37723,\n 22243,\n 22727,\n 24382,\n 26029,\n 26262,\n 27264,\n 27573,\n 30007,\n 35527,\n 20516,\n 30693,\n 22320,\n 24347,\n 24677,\n 26234,\n 27744,\n 30196,\n 31258,\n 32622,\n 33268,\n 34584,\n 36933,\n 39347,\n 31689,\n 30044,\n 31481,\n 31569,\n 33988,\n 0,\n 36880,\n 31209,\n 31378,\n 33590,\n 23265,\n 30528,\n 20013,\n 20210,\n 23449,\n 24544,\n 25277,\n 26172,\n 26609,\n 27880,\n 34411,\n 34935,\n 35387,\n 37198,\n 37619,\n 39376,\n 27159,\n 28710,\n 29482,\n 33511,\n 33879,\n 36015,\n 19969,\n 20806,\n 20939,\n 21899,\n 23541,\n 24086,\n 24115,\n 24193,\n 24340,\n 24373,\n 24427,\n 24500,\n 25074,\n 25361,\n 26274,\n 26397,\n 28526,\n 29266,\n 30010,\n 30522,\n 32884,\n 33081,\n 33144,\n 34678,\n 35519,\n 35548,\n 36229,\n 36339,\n 37530,\n 38263,\n 38914,\n 40165,\n 21189,\n 25431,\n 30452,\n 26389,\n 27784,\n 29645,\n 36035,\n 37806,\n 38515,\n 27941,\n 22684,\n 26894,\n 27084,\n 36861,\n 37786,\n 30171,\n 36890,\n 22618,\n 26626,\n 25524,\n 27131,\n 20291,\n 28460,\n 26584,\n 36795,\n 34086,\n 32180,\n 37716,\n 26943,\n 28528,\n 22378,\n 22775,\n 23340,\n 32044,\n 29226,\n 21514,\n 37347,\n 40372,\n 20141,\n 20302,\n 20572,\n 20597,\n 21059,\n 35998,\n 21576,\n 22564,\n 23450,\n 24093,\n 24213,\n 24237,\n 24311,\n 24351,\n 24716,\n 25269,\n 25402,\n 25552,\n 26799,\n 27712,\n 30855,\n 31118,\n 31243,\n 32224,\n 33351,\n 35330,\n 35558,\n 36420,\n 36883,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 37048,\n 37165,\n 37336,\n 40718,\n 27877,\n 25688,\n 25826,\n 25973,\n 28404,\n 30340,\n 31515,\n 36969,\n 37841,\n 28346,\n 21746,\n 24505,\n 25764,\n 36685,\n 36845,\n 37444,\n 20856,\n 22635,\n 22825,\n 23637,\n 24215,\n 28155,\n 32399,\n 29980,\n 36028,\n 36578,\n 39003,\n 28857,\n 20253,\n 27583,\n 28593,\n 30000,\n 38651,\n 20814,\n 21520,\n 22581,\n 22615,\n 22956,\n 23648,\n 24466,\n 26007,\n 26460,\n 28193,\n 30331,\n 33759,\n 36077,\n 36884,\n 37117,\n 37709,\n 30757,\n 30778,\n 21162,\n 24230,\n 22303,\n 22900,\n 24594,\n 20498,\n 20826,\n 20908,\n 0,\n 20941,\n 20992,\n 21776,\n 22612,\n 22616,\n 22871,\n 23445,\n 23798,\n 23947,\n 24764,\n 25237,\n 25645,\n 26481,\n 26691,\n 26812,\n 26847,\n 30423,\n 28120,\n 28271,\n 28059,\n 28783,\n 29128,\n 24403,\n 30168,\n 31095,\n 31561,\n 31572,\n 31570,\n 31958,\n 32113,\n 21040,\n 33891,\n 34153,\n 34276,\n 35342,\n 35588,\n 35910,\n 36367,\n 36867,\n 36879,\n 37913,\n 38518,\n 38957,\n 39472,\n 38360,\n 20685,\n 21205,\n 21516,\n 22530,\n 23566,\n 24999,\n 25758,\n 27934,\n 30643,\n 31461,\n 33012,\n 33796,\n 36947,\n 37509,\n 23776,\n 40199,\n 21311,\n 24471,\n 24499,\n 28060,\n 29305,\n 30563,\n 31167,\n 31716,\n 27602,\n 29420,\n 35501,\n 26627,\n 27233,\n 20984,\n 31361,\n 26932,\n 23626,\n 40182,\n 33515,\n 23493,\n 37193,\n 28702,\n 22136,\n 23663,\n 24775,\n 25958,\n 27788,\n 35930,\n 36929,\n 38931,\n 21585,\n 26311,\n 37389,\n 22856,\n 37027,\n 20869,\n 20045,\n 20970,\n 34201,\n 35598,\n 28760,\n 25466,\n 37707,\n 26978,\n 39348,\n 32260,\n 30071,\n 21335,\n 26976,\n 36575,\n 38627,\n 27741,\n 20108,\n 23612,\n 24336,\n 36841,\n 21250,\n 36049,\n 32905,\n 34425,\n 24319,\n 26085,\n 20083,\n 20837,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 22914,\n 23615,\n 38894,\n 20219,\n 22922,\n 24525,\n 35469,\n 28641,\n 31152,\n 31074,\n 23527,\n 33905,\n 29483,\n 29105,\n 24180,\n 24565,\n 25467,\n 25754,\n 29123,\n 31896,\n 20035,\n 24316,\n 20043,\n 22492,\n 22178,\n 24745,\n 28611,\n 32013,\n 33021,\n 33075,\n 33215,\n 36786,\n 35223,\n 34468,\n 24052,\n 25226,\n 25773,\n 35207,\n 26487,\n 27874,\n 27966,\n 29750,\n 30772,\n 23110,\n 32629,\n 33453,\n 39340,\n 20467,\n 24259,\n 25309,\n 25490,\n 25943,\n 26479,\n 30403,\n 29260,\n 32972,\n 32954,\n 36649,\n 37197,\n 20493,\n 22521,\n 23186,\n 26757,\n 0,\n 26995,\n 29028,\n 29437,\n 36023,\n 22770,\n 36064,\n 38506,\n 36889,\n 34687,\n 31204,\n 30695,\n 33833,\n 20271,\n 21093,\n 21338,\n 25293,\n 26575,\n 27850,\n 30333,\n 31636,\n 31893,\n 33334,\n 34180,\n 36843,\n 26333,\n 28448,\n 29190,\n 32283,\n 33707,\n 39361,\n 40614,\n 20989,\n 31665,\n 30834,\n 31672,\n 32903,\n 31560,\n 27368,\n 24161,\n 32908,\n 30033,\n 30048,\n 20843,\n 37474,\n 28300,\n 30330,\n 37271,\n 39658,\n 20240,\n 32624,\n 25244,\n 31567,\n 38309,\n 40169,\n 22138,\n 22617,\n 34532,\n 38588,\n 20276,\n 21028,\n 21322,\n 21453,\n 21467,\n 24070,\n 25644,\n 26001,\n 26495,\n 27710,\n 27726,\n 29256,\n 29359,\n 29677,\n 30036,\n 32321,\n 33324,\n 34281,\n 36009,\n 31684,\n 37318,\n 29033,\n 38930,\n 39151,\n 25405,\n 26217,\n 30058,\n 30436,\n 30928,\n 34115,\n 34542,\n 21290,\n 21329,\n 21542,\n 22915,\n 24199,\n 24444,\n 24754,\n 25161,\n 25209,\n 25259,\n 26000,\n 27604,\n 27852,\n 30130,\n 30382,\n 30865,\n 31192,\n 32203,\n 32631,\n 32933,\n 34987,\n 35513,\n 36027,\n 36991,\n 38750,\n 39131,\n 27147,\n 31800,\n 20633,\n 23614,\n 24494,\n 26503,\n 27608,\n 29749,\n 30473,\n 32654,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 40763,\n 26570,\n 31255,\n 21305,\n 30091,\n 39661,\n 24422,\n 33181,\n 33777,\n 32920,\n 24380,\n 24517,\n 30050,\n 31558,\n 36924,\n 26727,\n 23019,\n 23195,\n 32016,\n 30334,\n 35628,\n 20469,\n 24426,\n 27161,\n 27703,\n 28418,\n 29922,\n 31080,\n 34920,\n 35413,\n 35961,\n 24287,\n 25551,\n 30149,\n 31186,\n 33495,\n 37672,\n 37618,\n 33948,\n 34541,\n 39981,\n 21697,\n 24428,\n 25996,\n 27996,\n 28693,\n 36007,\n 36051,\n 38971,\n 25935,\n 29942,\n 19981,\n 20184,\n 22496,\n 22827,\n 23142,\n 23500,\n 20904,\n 24067,\n 24220,\n 24598,\n 25206,\n 25975,\n 0,\n 26023,\n 26222,\n 28014,\n 29238,\n 31526,\n 33104,\n 33178,\n 33433,\n 35676,\n 36000,\n 36070,\n 36212,\n 38428,\n 38468,\n 20398,\n 25771,\n 27494,\n 33310,\n 33889,\n 34154,\n 37096,\n 23553,\n 26963,\n 39080,\n 33914,\n 34135,\n 20239,\n 21103,\n 24489,\n 24133,\n 26381,\n 31119,\n 33145,\n 35079,\n 35206,\n 28149,\n 24343,\n 25173,\n 27832,\n 20175,\n 29289,\n 39826,\n 20998,\n 21563,\n 22132,\n 22707,\n 24996,\n 25198,\n 28954,\n 22894,\n 31881,\n 31966,\n 32027,\n 38640,\n 25991,\n 32862,\n 19993,\n 20341,\n 20853,\n 22592,\n 24163,\n 24179,\n 24330,\n 26564,\n 20006,\n 34109,\n 38281,\n 38491,\n 31859,\n 38913,\n 20731,\n 22721,\n 30294,\n 30887,\n 21029,\n 30629,\n 34065,\n 31622,\n 20559,\n 22793,\n 29255,\n 31687,\n 32232,\n 36794,\n 36820,\n 36941,\n 20415,\n 21193,\n 23081,\n 24321,\n 38829,\n 20445,\n 33303,\n 37610,\n 22275,\n 25429,\n 27497,\n 29995,\n 35036,\n 36628,\n 31298,\n 21215,\n 22675,\n 24917,\n 25098,\n 26286,\n 27597,\n 31807,\n 33769,\n 20515,\n 20472,\n 21253,\n 21574,\n 22577,\n 22857,\n 23453,\n 23792,\n 23791,\n 23849,\n 24214,\n 25265,\n 25447,\n 25918,\n 26041,\n 26379,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 27861,\n 27873,\n 28921,\n 30770,\n 32299,\n 32990,\n 33459,\n 33804,\n 34028,\n 34562,\n 35090,\n 35370,\n 35914,\n 37030,\n 37586,\n 39165,\n 40179,\n 40300,\n 20047,\n 20129,\n 20621,\n 21078,\n 22346,\n 22952,\n 24125,\n 24536,\n 24537,\n 25151,\n 26292,\n 26395,\n 26576,\n 26834,\n 20882,\n 32033,\n 32938,\n 33192,\n 35584,\n 35980,\n 36031,\n 37502,\n 38450,\n 21536,\n 38956,\n 21271,\n 20693,\n 21340,\n 22696,\n 25778,\n 26420,\n 29287,\n 30566,\n 31302,\n 37350,\n 21187,\n 27809,\n 27526,\n 22528,\n 24140,\n 22868,\n 26412,\n 32763,\n 20961,\n 30406,\n 0,\n 25705,\n 30952,\n 39764,\n 40635,\n 22475,\n 22969,\n 26151,\n 26522,\n 27598,\n 21737,\n 27097,\n 24149,\n 33180,\n 26517,\n 39850,\n 26622,\n 40018,\n 26717,\n 20134,\n 20451,\n 21448,\n 25273,\n 26411,\n 27819,\n 36804,\n 20397,\n 32365,\n 40639,\n 19975,\n 24930,\n 28288,\n 28459,\n 34067,\n 21619,\n 26410,\n 39749,\n 24051,\n 31637,\n 23724,\n 23494,\n 34588,\n 28234,\n 34001,\n 31252,\n 33032,\n 22937,\n 31885,\n 27665,\n 30496,\n 21209,\n 22818,\n 28961,\n 29279,\n 30683,\n 38695,\n 40289,\n 26891,\n 23167,\n 23064,\n 20901,\n 21517,\n 21629,\n 26126,\n 30431,\n 36855,\n 37528,\n 40180,\n 23018,\n 29277,\n 28357,\n 20813,\n 26825,\n 32191,\n 32236,\n 38754,\n 40634,\n 25720,\n 27169,\n 33538,\n 22916,\n 23391,\n 27611,\n 29467,\n 30450,\n 32178,\n 32791,\n 33945,\n 20786,\n 26408,\n 40665,\n 30446,\n 26466,\n 21247,\n 39173,\n 23588,\n 25147,\n 31870,\n 36016,\n 21839,\n 24758,\n 32011,\n 38272,\n 21249,\n 20063,\n 20918,\n 22812,\n 29242,\n 32822,\n 37326,\n 24357,\n 30690,\n 21380,\n 24441,\n 32004,\n 34220,\n 35379,\n 36493,\n 38742,\n 26611,\n 34222,\n 37971,\n 24841,\n 24840,\n 27833,\n 30290,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 35565,\n 36664,\n 21807,\n 20305,\n 20778,\n 21191,\n 21451,\n 23461,\n 24189,\n 24736,\n 24962,\n 25558,\n 26377,\n 26586,\n 28263,\n 28044,\n 29494,\n 29495,\n 30001,\n 31056,\n 35029,\n 35480,\n 36938,\n 37009,\n 37109,\n 38596,\n 34701,\n 22805,\n 20104,\n 20313,\n 19982,\n 35465,\n 36671,\n 38928,\n 20653,\n 24188,\n 22934,\n 23481,\n 24248,\n 25562,\n 25594,\n 25793,\n 26332,\n 26954,\n 27096,\n 27915,\n 28342,\n 29076,\n 29992,\n 31407,\n 32650,\n 32768,\n 33865,\n 33993,\n 35201,\n 35617,\n 36362,\n 36965,\n 38525,\n 39178,\n 24958,\n 25233,\n 27442,\n 0,\n 27779,\n 28020,\n 32716,\n 32764,\n 28096,\n 32645,\n 34746,\n 35064,\n 26469,\n 33713,\n 38972,\n 38647,\n 27931,\n 32097,\n 33853,\n 37226,\n 20081,\n 21365,\n 23888,\n 27396,\n 28651,\n 34253,\n 34349,\n 35239,\n 21033,\n 21519,\n 23653,\n 26446,\n 26792,\n 29702,\n 29827,\n 30178,\n 35023,\n 35041,\n 37324,\n 38626,\n 38520,\n 24459,\n 29575,\n 31435,\n 33870,\n 25504,\n 30053,\n 21129,\n 27969,\n 28316,\n 29705,\n 30041,\n 30827,\n 31890,\n 38534,\n 31452,\n 40845,\n 20406,\n 24942,\n 26053,\n 34396,\n 20102,\n 20142,\n 20698,\n 20001,\n 20940,\n 23534,\n 26009,\n 26753,\n 28092,\n 29471,\n 30274,\n 30637,\n 31260,\n 31975,\n 33391,\n 35538,\n 36988,\n 37327,\n 38517,\n 38936,\n 21147,\n 32209,\n 20523,\n 21400,\n 26519,\n 28107,\n 29136,\n 29747,\n 33256,\n 36650,\n 38563,\n 40023,\n 40607,\n 29792,\n 22593,\n 28057,\n 32047,\n 39006,\n 20196,\n 20278,\n 20363,\n 20919,\n 21169,\n 23994,\n 24604,\n 29618,\n 31036,\n 33491,\n 37428,\n 38583,\n 38646,\n 38666,\n 40599,\n 40802,\n 26278,\n 27508,\n 21015,\n 21155,\n 28872,\n 35010,\n 24265,\n 24651,\n 24976,\n 28451,\n 29001,\n 31806,\n 32244,\n 32879,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 34030,\n 36899,\n 37676,\n 21570,\n 39791,\n 27347,\n 28809,\n 36034,\n 36335,\n 38706,\n 21172,\n 23105,\n 24266,\n 24324,\n 26391,\n 27004,\n 27028,\n 28010,\n 28431,\n 29282,\n 29436,\n 31725,\n 32769,\n 32894,\n 34635,\n 37070,\n 20845,\n 40595,\n 31108,\n 32907,\n 37682,\n 35542,\n 20525,\n 21644,\n 35441,\n 27498,\n 36036,\n 33031,\n 24785,\n 26528,\n 40434,\n 20121,\n 20120,\n 39952,\n 35435,\n 34241,\n 34152,\n 26880,\n 28286,\n 30871,\n 33109,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 24332,\n 19984,\n 19989,\n 20010,\n 20017,\n 20022,\n 20028,\n 20031,\n 20034,\n 20054,\n 20056,\n 20098,\n 20101,\n 35947,\n 20106,\n 33298,\n 24333,\n 20110,\n 20126,\n 20127,\n 20128,\n 20130,\n 20144,\n 20147,\n 20150,\n 20174,\n 20173,\n 20164,\n 20166,\n 20162,\n 20183,\n 20190,\n 20205,\n 20191,\n 20215,\n 20233,\n 20314,\n 20272,\n 20315,\n 20317,\n 20311,\n 20295,\n 20342,\n 20360,\n 20367,\n 20376,\n 20347,\n 20329,\n 20336,\n 20369,\n 20335,\n 20358,\n 20374,\n 20760,\n 20436,\n 20447,\n 20430,\n 20440,\n 20443,\n 20433,\n 20442,\n 20432,\n 20452,\n 20453,\n 20506,\n 20520,\n 20500,\n 20522,\n 20517,\n 20485,\n 20252,\n 20470,\n 20513,\n 20521,\n 20524,\n 20478,\n 20463,\n 20497,\n 20486,\n 20547,\n 20551,\n 26371,\n 20565,\n 20560,\n 20552,\n 20570,\n 20566,\n 20588,\n 20600,\n 20608,\n 20634,\n 20613,\n 20660,\n 20658,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 20681,\n 20682,\n 20659,\n 20674,\n 20694,\n 20702,\n 20709,\n 20717,\n 20707,\n 20718,\n 20729,\n 20725,\n 20745,\n 20737,\n 20738,\n 20758,\n 20757,\n 20756,\n 20762,\n 20769,\n 20794,\n 20791,\n 20796,\n 20795,\n 20799,\n 20800,\n 20818,\n 20812,\n 20820,\n 20834,\n 31480,\n 20841,\n 20842,\n 20846,\n 20864,\n 20866,\n 22232,\n 20876,\n 20873,\n 20879,\n 20881,\n 20883,\n 20885,\n 20886,\n 20900,\n 20902,\n 20898,\n 20905,\n 20906,\n 20907,\n 20915,\n 20913,\n 20914,\n 20912,\n 20917,\n 20925,\n 20933,\n 20937,\n 20955,\n 20960,\n 34389,\n 20969,\n 20973,\n 0,\n 20976,\n 20981,\n 20990,\n 20996,\n 21003,\n 21012,\n 21006,\n 21031,\n 21034,\n 21038,\n 21043,\n 21049,\n 21071,\n 21060,\n 21067,\n 21068,\n 21086,\n 21076,\n 21098,\n 21108,\n 21097,\n 21107,\n 21119,\n 21117,\n 21133,\n 21140,\n 21138,\n 21105,\n 21128,\n 21137,\n 36776,\n 36775,\n 21164,\n 21165,\n 21180,\n 21173,\n 21185,\n 21197,\n 21207,\n 21214,\n 21219,\n 21222,\n 39149,\n 21216,\n 21235,\n 21237,\n 21240,\n 21241,\n 21254,\n 21256,\n 30008,\n 21261,\n 21264,\n 21263,\n 21269,\n 21274,\n 21283,\n 21295,\n 21297,\n 21299,\n 21304,\n 21312,\n 21318,\n 21317,\n 19991,\n 21321,\n 21325,\n 20950,\n 21342,\n 21353,\n 21358,\n 22808,\n 21371,\n 21367,\n 21378,\n 21398,\n 21408,\n 21414,\n 21413,\n 21422,\n 21424,\n 21430,\n 21443,\n 31762,\n 38617,\n 21471,\n 26364,\n 29166,\n 21486,\n 21480,\n 21485,\n 21498,\n 21505,\n 21565,\n 21568,\n 21548,\n 21549,\n 21564,\n 21550,\n 21558,\n 21545,\n 21533,\n 21582,\n 21647,\n 21621,\n 21646,\n 21599,\n 21617,\n 21623,\n 21616,\n 21650,\n 21627,\n 21632,\n 21622,\n 21636,\n 21648,\n 21638,\n 21703,\n 21666,\n 21688,\n 21669,\n 21676,\n 21700,\n 21704,\n 21672,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 21675,\n 21698,\n 21668,\n 21694,\n 21692,\n 21720,\n 21733,\n 21734,\n 21775,\n 21780,\n 21757,\n 21742,\n 21741,\n 21754,\n 21730,\n 21817,\n 21824,\n 21859,\n 21836,\n 21806,\n 21852,\n 21829,\n 21846,\n 21847,\n 21816,\n 21811,\n 21853,\n 21913,\n 21888,\n 21679,\n 21898,\n 21919,\n 21883,\n 21886,\n 21912,\n 21918,\n 21934,\n 21884,\n 21891,\n 21929,\n 21895,\n 21928,\n 21978,\n 21957,\n 21983,\n 21956,\n 21980,\n 21988,\n 21972,\n 22036,\n 22007,\n 22038,\n 22014,\n 22013,\n 22043,\n 22009,\n 22094,\n 22096,\n 29151,\n 22068,\n 22070,\n 22066,\n 22072,\n 0,\n 22123,\n 22116,\n 22063,\n 22124,\n 22122,\n 22150,\n 22144,\n 22154,\n 22176,\n 22164,\n 22159,\n 22181,\n 22190,\n 22198,\n 22196,\n 22210,\n 22204,\n 22209,\n 22211,\n 22208,\n 22216,\n 22222,\n 22225,\n 22227,\n 22231,\n 22254,\n 22265,\n 22272,\n 22271,\n 22276,\n 22281,\n 22280,\n 22283,\n 22285,\n 22291,\n 22296,\n 22294,\n 21959,\n 22300,\n 22310,\n 22327,\n 22328,\n 22350,\n 22331,\n 22336,\n 22351,\n 22377,\n 22464,\n 22408,\n 22369,\n 22399,\n 22409,\n 22419,\n 22432,\n 22451,\n 22436,\n 22442,\n 22448,\n 22467,\n 22470,\n 22484,\n 22482,\n 22483,\n 22538,\n 22486,\n 22499,\n 22539,\n 22553,\n 22557,\n 22642,\n 22561,\n 22626,\n 22603,\n 22640,\n 27584,\n 22610,\n 22589,\n 22649,\n 22661,\n 22713,\n 22687,\n 22699,\n 22714,\n 22750,\n 22715,\n 22712,\n 22702,\n 22725,\n 22739,\n 22737,\n 22743,\n 22745,\n 22744,\n 22757,\n 22748,\n 22756,\n 22751,\n 22767,\n 22778,\n 22777,\n 22779,\n 22780,\n 22781,\n 22786,\n 22794,\n 22800,\n 22811,\n 26790,\n 22821,\n 22828,\n 22829,\n 22834,\n 22840,\n 22846,\n 31442,\n 22869,\n 22864,\n 22862,\n 22874,\n 22872,\n 22882,\n 22880,\n 22887,\n 22892,\n 22889,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 22904,\n 22913,\n 22941,\n 20318,\n 20395,\n 22947,\n 22962,\n 22982,\n 23016,\n 23004,\n 22925,\n 23001,\n 23002,\n 23077,\n 23071,\n 23057,\n 23068,\n 23049,\n 23066,\n 23104,\n 23148,\n 23113,\n 23093,\n 23094,\n 23138,\n 23146,\n 23194,\n 23228,\n 23230,\n 23243,\n 23234,\n 23229,\n 23267,\n 23255,\n 23270,\n 23273,\n 23254,\n 23290,\n 23291,\n 23308,\n 23307,\n 23318,\n 23346,\n 23248,\n 23338,\n 23350,\n 23358,\n 23363,\n 23365,\n 23360,\n 23377,\n 23381,\n 23386,\n 23387,\n 23397,\n 23401,\n 23408,\n 23411,\n 23413,\n 23416,\n 25992,\n 23418,\n 23424,\n 0,\n 23427,\n 23462,\n 23480,\n 23491,\n 23495,\n 23497,\n 23508,\n 23504,\n 23524,\n 23526,\n 23522,\n 23518,\n 23525,\n 23531,\n 23536,\n 23542,\n 23539,\n 23557,\n 23559,\n 23560,\n 23565,\n 23571,\n 23584,\n 23586,\n 23592,\n 23608,\n 23609,\n 23617,\n 23622,\n 23630,\n 23635,\n 23632,\n 23631,\n 23409,\n 23660,\n 23662,\n 20066,\n 23670,\n 23673,\n 23692,\n 23697,\n 23700,\n 22939,\n 23723,\n 23739,\n 23734,\n 23740,\n 23735,\n 23749,\n 23742,\n 23751,\n 23769,\n 23785,\n 23805,\n 23802,\n 23789,\n 23948,\n 23786,\n 23819,\n 23829,\n 23831,\n 23900,\n 23839,\n 23835,\n 23825,\n 23828,\n 23842,\n 23834,\n 23833,\n 23832,\n 23884,\n 23890,\n 23886,\n 23883,\n 23916,\n 23923,\n 23926,\n 23943,\n 23940,\n 23938,\n 23970,\n 23965,\n 23980,\n 23982,\n 23997,\n 23952,\n 23991,\n 23996,\n 24009,\n 24013,\n 24019,\n 24018,\n 24022,\n 24027,\n 24043,\n 24050,\n 24053,\n 24075,\n 24090,\n 24089,\n 24081,\n 24091,\n 24118,\n 24119,\n 24132,\n 24131,\n 24128,\n 24142,\n 24151,\n 24148,\n 24159,\n 24162,\n 24164,\n 24135,\n 24181,\n 24182,\n 24186,\n 40636,\n 24191,\n 24224,\n 24257,\n 24258,\n 24264,\n 24272,\n 24271,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 24278,\n 24291,\n 24285,\n 24282,\n 24283,\n 24290,\n 24289,\n 24296,\n 24297,\n 24300,\n 24305,\n 24307,\n 24304,\n 24308,\n 24312,\n 24318,\n 24323,\n 24329,\n 24413,\n 24412,\n 24331,\n 24337,\n 24342,\n 24361,\n 24365,\n 24376,\n 24385,\n 24392,\n 24396,\n 24398,\n 24367,\n 24401,\n 24406,\n 24407,\n 24409,\n 24417,\n 24429,\n 24435,\n 24439,\n 24451,\n 24450,\n 24447,\n 24458,\n 24456,\n 24465,\n 24455,\n 24478,\n 24473,\n 24472,\n 24480,\n 24488,\n 24493,\n 24508,\n 24534,\n 24571,\n 24548,\n 24568,\n 24561,\n 24541,\n 24755,\n 24575,\n 24609,\n 24672,\n 0,\n 24601,\n 24592,\n 24617,\n 24590,\n 24625,\n 24603,\n 24597,\n 24619,\n 24614,\n 24591,\n 24634,\n 24666,\n 24641,\n 24682,\n 24695,\n 24671,\n 24650,\n 24646,\n 24653,\n 24675,\n 24643,\n 24676,\n 24642,\n 24684,\n 24683,\n 24665,\n 24705,\n 24717,\n 24807,\n 24707,\n 24730,\n 24708,\n 24731,\n 24726,\n 24727,\n 24722,\n 24743,\n 24715,\n 24801,\n 24760,\n 24800,\n 24787,\n 24756,\n 24560,\n 24765,\n 24774,\n 24757,\n 24792,\n 24909,\n 24853,\n 24838,\n 24822,\n 24823,\n 24832,\n 24820,\n 24826,\n 24835,\n 24865,\n 24827,\n 24817,\n 24845,\n 24846,\n 24903,\n 24894,\n 24872,\n 24871,\n 24906,\n 24895,\n 24892,\n 24876,\n 24884,\n 24893,\n 24898,\n 24900,\n 24947,\n 24951,\n 24920,\n 24921,\n 24922,\n 24939,\n 24948,\n 24943,\n 24933,\n 24945,\n 24927,\n 24925,\n 24915,\n 24949,\n 24985,\n 24982,\n 24967,\n 25004,\n 24980,\n 24986,\n 24970,\n 24977,\n 25003,\n 25006,\n 25036,\n 25034,\n 25033,\n 25079,\n 25032,\n 25027,\n 25030,\n 25018,\n 25035,\n 32633,\n 25037,\n 25062,\n 25059,\n 25078,\n 25082,\n 25076,\n 25087,\n 25085,\n 25084,\n 25086,\n 25088,\n 25096,\n 25097,\n 25101,\n 25100,\n 25108,\n 25115,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 25118,\n 25121,\n 25130,\n 25134,\n 25136,\n 25138,\n 25139,\n 25153,\n 25166,\n 25182,\n 25187,\n 25179,\n 25184,\n 25192,\n 25212,\n 25218,\n 25225,\n 25214,\n 25234,\n 25235,\n 25238,\n 25300,\n 25219,\n 25236,\n 25303,\n 25297,\n 25275,\n 25295,\n 25343,\n 25286,\n 25812,\n 25288,\n 25308,\n 25292,\n 25290,\n 25282,\n 25287,\n 25243,\n 25289,\n 25356,\n 25326,\n 25329,\n 25383,\n 25346,\n 25352,\n 25327,\n 25333,\n 25424,\n 25406,\n 25421,\n 25628,\n 25423,\n 25494,\n 25486,\n 25472,\n 25515,\n 25462,\n 25507,\n 25487,\n 25481,\n 25503,\n 25525,\n 25451,\n 0,\n 25449,\n 25534,\n 25577,\n 25536,\n 25542,\n 25571,\n 25545,\n 25554,\n 25590,\n 25540,\n 25622,\n 25652,\n 25606,\n 25619,\n 25638,\n 25654,\n 25885,\n 25623,\n 25640,\n 25615,\n 25703,\n 25711,\n 25718,\n 25678,\n 25898,\n 25749,\n 25747,\n 25765,\n 25769,\n 25736,\n 25788,\n 25818,\n 25810,\n 25797,\n 25799,\n 25787,\n 25816,\n 25794,\n 25841,\n 25831,\n 33289,\n 25824,\n 25825,\n 25260,\n 25827,\n 25839,\n 25900,\n 25846,\n 25844,\n 25842,\n 25850,\n 25856,\n 25853,\n 25880,\n 25884,\n 25861,\n 25892,\n 25891,\n 25899,\n 25908,\n 25909,\n 25911,\n 25910,\n 25912,\n 30027,\n 25928,\n 25942,\n 25941,\n 25933,\n 25944,\n 25950,\n 25949,\n 25970,\n 25976,\n 25986,\n 25987,\n 35722,\n 26011,\n 26015,\n 26027,\n 26039,\n 26051,\n 26054,\n 26049,\n 26052,\n 26060,\n 26066,\n 26075,\n 26073,\n 26080,\n 26081,\n 26097,\n 26482,\n 26122,\n 26115,\n 26107,\n 26483,\n 26165,\n 26166,\n 26164,\n 26140,\n 26191,\n 26180,\n 26185,\n 26177,\n 26206,\n 26205,\n 26212,\n 26215,\n 26216,\n 26207,\n 26210,\n 26224,\n 26243,\n 26248,\n 26254,\n 26249,\n 26244,\n 26264,\n 26269,\n 26305,\n 26297,\n 26313,\n 26302,\n 26300,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 26308,\n 26296,\n 26326,\n 26330,\n 26336,\n 26175,\n 26342,\n 26345,\n 26352,\n 26357,\n 26359,\n 26383,\n 26390,\n 26398,\n 26406,\n 26407,\n 38712,\n 26414,\n 26431,\n 26422,\n 26433,\n 26424,\n 26423,\n 26438,\n 26462,\n 26464,\n 26457,\n 26467,\n 26468,\n 26505,\n 26480,\n 26537,\n 26492,\n 26474,\n 26508,\n 26507,\n 26534,\n 26529,\n 26501,\n 26551,\n 26607,\n 26548,\n 26604,\n 26547,\n 26601,\n 26552,\n 26596,\n 26590,\n 26589,\n 26594,\n 26606,\n 26553,\n 26574,\n 26566,\n 26599,\n 27292,\n 26654,\n 26694,\n 26665,\n 26688,\n 26701,\n 26674,\n 26702,\n 0,\n 26803,\n 26667,\n 26713,\n 26723,\n 26743,\n 26751,\n 26783,\n 26767,\n 26797,\n 26772,\n 26781,\n 26779,\n 26755,\n 27310,\n 26809,\n 26740,\n 26805,\n 26784,\n 26810,\n 26895,\n 26765,\n 26750,\n 26881,\n 26826,\n 26888,\n 26840,\n 26914,\n 26918,\n 26849,\n 26892,\n 26829,\n 26836,\n 26855,\n 26837,\n 26934,\n 26898,\n 26884,\n 26839,\n 26851,\n 26917,\n 26873,\n 26848,\n 26863,\n 26920,\n 26922,\n 26906,\n 26915,\n 26913,\n 26822,\n 27001,\n 26999,\n 26972,\n 27000,\n 26987,\n 26964,\n 27006,\n 26990,\n 26937,\n 26996,\n 26941,\n 26969,\n 26928,\n 26977,\n 26974,\n 26973,\n 27009,\n 26986,\n 27058,\n 27054,\n 27088,\n 27071,\n 27073,\n 27091,\n 27070,\n 27086,\n 23528,\n 27082,\n 27101,\n 27067,\n 27075,\n 27047,\n 27182,\n 27025,\n 27040,\n 27036,\n 27029,\n 27060,\n 27102,\n 27112,\n 27138,\n 27163,\n 27135,\n 27402,\n 27129,\n 27122,\n 27111,\n 27141,\n 27057,\n 27166,\n 27117,\n 27156,\n 27115,\n 27146,\n 27154,\n 27329,\n 27171,\n 27155,\n 27204,\n 27148,\n 27250,\n 27190,\n 27256,\n 27207,\n 27234,\n 27225,\n 27238,\n 27208,\n 27192,\n 27170,\n 27280,\n 27277,\n 27296,\n 27268,\n 27298,\n 27299,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 27287,\n 34327,\n 27323,\n 27331,\n 27330,\n 27320,\n 27315,\n 27308,\n 27358,\n 27345,\n 27359,\n 27306,\n 27354,\n 27370,\n 27387,\n 27397,\n 34326,\n 27386,\n 27410,\n 27414,\n 39729,\n 27423,\n 27448,\n 27447,\n 30428,\n 27449,\n 39150,\n 27463,\n 27459,\n 27465,\n 27472,\n 27481,\n 27476,\n 27483,\n 27487,\n 27489,\n 27512,\n 27513,\n 27519,\n 27520,\n 27524,\n 27523,\n 27533,\n 27544,\n 27541,\n 27550,\n 27556,\n 27562,\n 27563,\n 27567,\n 27570,\n 27569,\n 27571,\n 27575,\n 27580,\n 27590,\n 27595,\n 27603,\n 27615,\n 27628,\n 27627,\n 27635,\n 27631,\n 0,\n 40638,\n 27656,\n 27667,\n 27668,\n 27675,\n 27684,\n 27683,\n 27742,\n 27733,\n 27746,\n 27754,\n 27778,\n 27789,\n 27802,\n 27777,\n 27803,\n 27774,\n 27752,\n 27763,\n 27794,\n 27792,\n 27844,\n 27889,\n 27859,\n 27837,\n 27863,\n 27845,\n 27869,\n 27822,\n 27825,\n 27838,\n 27834,\n 27867,\n 27887,\n 27865,\n 27882,\n 27935,\n 34893,\n 27958,\n 27947,\n 27965,\n 27960,\n 27929,\n 27957,\n 27955,\n 27922,\n 27916,\n 28003,\n 28051,\n 28004,\n 27994,\n 28025,\n 27993,\n 28046,\n 28053,\n 28644,\n 28037,\n 28153,\n 28181,\n 28170,\n 28085,\n 28103,\n 28134,\n 28088,\n 28102,\n 28140,\n 28126,\n 28108,\n 28136,\n 28114,\n 28101,\n 28154,\n 28121,\n 28132,\n 28117,\n 28138,\n 28142,\n 28205,\n 28270,\n 28206,\n 28185,\n 28274,\n 28255,\n 28222,\n 28195,\n 28267,\n 28203,\n 28278,\n 28237,\n 28191,\n 28227,\n 28218,\n 28238,\n 28196,\n 28415,\n 28189,\n 28216,\n 28290,\n 28330,\n 28312,\n 28361,\n 28343,\n 28371,\n 28349,\n 28335,\n 28356,\n 28338,\n 28372,\n 28373,\n 28303,\n 28325,\n 28354,\n 28319,\n 28481,\n 28433,\n 28748,\n 28396,\n 28408,\n 28414,\n 28479,\n 28402,\n 28465,\n 28399,\n 28466,\n 28364,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 28478,\n 28435,\n 28407,\n 28550,\n 28538,\n 28536,\n 28545,\n 28544,\n 28527,\n 28507,\n 28659,\n 28525,\n 28546,\n 28540,\n 28504,\n 28558,\n 28561,\n 28610,\n 28518,\n 28595,\n 28579,\n 28577,\n 28580,\n 28601,\n 28614,\n 28586,\n 28639,\n 28629,\n 28652,\n 28628,\n 28632,\n 28657,\n 28654,\n 28635,\n 28681,\n 28683,\n 28666,\n 28689,\n 28673,\n 28687,\n 28670,\n 28699,\n 28698,\n 28532,\n 28701,\n 28696,\n 28703,\n 28720,\n 28734,\n 28722,\n 28753,\n 28771,\n 28825,\n 28818,\n 28847,\n 28913,\n 28844,\n 28856,\n 28851,\n 28846,\n 28895,\n 28875,\n 28893,\n 0,\n 28889,\n 28937,\n 28925,\n 28956,\n 28953,\n 29029,\n 29013,\n 29064,\n 29030,\n 29026,\n 29004,\n 29014,\n 29036,\n 29071,\n 29179,\n 29060,\n 29077,\n 29096,\n 29100,\n 29143,\n 29113,\n 29118,\n 29138,\n 29129,\n 29140,\n 29134,\n 29152,\n 29164,\n 29159,\n 29173,\n 29180,\n 29177,\n 29183,\n 29197,\n 29200,\n 29211,\n 29224,\n 29229,\n 29228,\n 29232,\n 29234,\n 29243,\n 29244,\n 29247,\n 29248,\n 29254,\n 29259,\n 29272,\n 29300,\n 29310,\n 29314,\n 29313,\n 29319,\n 29330,\n 29334,\n 29346,\n 29351,\n 29369,\n 29362,\n 29379,\n 29382,\n 29380,\n 29390,\n 29394,\n 29410,\n 29408,\n 29409,\n 29433,\n 29431,\n 20495,\n 29463,\n 29450,\n 29468,\n 29462,\n 29469,\n 29492,\n 29487,\n 29481,\n 29477,\n 29502,\n 29518,\n 29519,\n 40664,\n 29527,\n 29546,\n 29544,\n 29552,\n 29560,\n 29557,\n 29563,\n 29562,\n 29640,\n 29619,\n 29646,\n 29627,\n 29632,\n 29669,\n 29678,\n 29662,\n 29858,\n 29701,\n 29807,\n 29733,\n 29688,\n 29746,\n 29754,\n 29781,\n 29759,\n 29791,\n 29785,\n 29761,\n 29788,\n 29801,\n 29808,\n 29795,\n 29802,\n 29814,\n 29822,\n 29835,\n 29854,\n 29863,\n 29898,\n 29903,\n 29908,\n 29681,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 29920,\n 29923,\n 29927,\n 29929,\n 29934,\n 29938,\n 29936,\n 29937,\n 29944,\n 29943,\n 29956,\n 29955,\n 29957,\n 29964,\n 29966,\n 29965,\n 29973,\n 29971,\n 29982,\n 29990,\n 29996,\n 30012,\n 30020,\n 30029,\n 30026,\n 30025,\n 30043,\n 30022,\n 30042,\n 30057,\n 30052,\n 30055,\n 30059,\n 30061,\n 30072,\n 30070,\n 30086,\n 30087,\n 30068,\n 30090,\n 30089,\n 30082,\n 30100,\n 30106,\n 30109,\n 30117,\n 30115,\n 30146,\n 30131,\n 30147,\n 30133,\n 30141,\n 30136,\n 30140,\n 30129,\n 30157,\n 30154,\n 30162,\n 30169,\n 30179,\n 30174,\n 30206,\n 30207,\n 0,\n 30204,\n 30209,\n 30192,\n 30202,\n 30194,\n 30195,\n 30219,\n 30221,\n 30217,\n 30239,\n 30247,\n 30240,\n 30241,\n 30242,\n 30244,\n 30260,\n 30256,\n 30267,\n 30279,\n 30280,\n 30278,\n 30300,\n 30296,\n 30305,\n 30306,\n 30312,\n 30313,\n 30314,\n 30311,\n 30316,\n 30320,\n 30322,\n 30326,\n 30328,\n 30332,\n 30336,\n 30339,\n 30344,\n 30347,\n 30350,\n 30358,\n 30355,\n 30361,\n 30362,\n 30384,\n 30388,\n 30392,\n 30393,\n 30394,\n 30402,\n 30413,\n 30422,\n 30418,\n 30430,\n 30433,\n 30437,\n 30439,\n 30442,\n 34351,\n 30459,\n 30472,\n 30471,\n 30468,\n 30505,\n 30500,\n 30494,\n 30501,\n 30502,\n 30491,\n 30519,\n 30520,\n 30535,\n 30554,\n 30568,\n 30571,\n 30555,\n 30565,\n 30591,\n 30590,\n 30585,\n 30606,\n 30603,\n 30609,\n 30624,\n 30622,\n 30640,\n 30646,\n 30649,\n 30655,\n 30652,\n 30653,\n 30651,\n 30663,\n 30669,\n 30679,\n 30682,\n 30684,\n 30691,\n 30702,\n 30716,\n 30732,\n 30738,\n 31014,\n 30752,\n 31018,\n 30789,\n 30862,\n 30836,\n 30854,\n 30844,\n 30874,\n 30860,\n 30883,\n 30901,\n 30890,\n 30895,\n 30929,\n 30918,\n 30923,\n 30932,\n 30910,\n 30908,\n 30917,\n 30922,\n 30956,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 30951,\n 30938,\n 30973,\n 30964,\n 30983,\n 30994,\n 30993,\n 31001,\n 31020,\n 31019,\n 31040,\n 31072,\n 31063,\n 31071,\n 31066,\n 31061,\n 31059,\n 31098,\n 31103,\n 31114,\n 31133,\n 31143,\n 40779,\n 31146,\n 31150,\n 31155,\n 31161,\n 31162,\n 31177,\n 31189,\n 31207,\n 31212,\n 31201,\n 31203,\n 31240,\n 31245,\n 31256,\n 31257,\n 31264,\n 31263,\n 31104,\n 31281,\n 31291,\n 31294,\n 31287,\n 31299,\n 31319,\n 31305,\n 31329,\n 31330,\n 31337,\n 40861,\n 31344,\n 31353,\n 31357,\n 31368,\n 31383,\n 31381,\n 31384,\n 31382,\n 31401,\n 31432,\n 31408,\n 0,\n 31414,\n 31429,\n 31428,\n 31423,\n 36995,\n 31431,\n 31434,\n 31437,\n 31439,\n 31445,\n 31443,\n 31449,\n 31450,\n 31453,\n 31457,\n 31458,\n 31462,\n 31469,\n 31472,\n 31490,\n 31503,\n 31498,\n 31494,\n 31539,\n 31512,\n 31513,\n 31518,\n 31541,\n 31528,\n 31542,\n 31568,\n 31610,\n 31492,\n 31565,\n 31499,\n 31564,\n 31557,\n 31605,\n 31589,\n 31604,\n 31591,\n 31600,\n 31601,\n 31596,\n 31598,\n 31645,\n 31640,\n 31647,\n 31629,\n 31644,\n 31642,\n 31627,\n 31634,\n 31631,\n 31581,\n 31641,\n 31691,\n 31681,\n 31692,\n 31695,\n 31668,\n 31686,\n 31709,\n 31721,\n 31761,\n 31764,\n 31718,\n 31717,\n 31840,\n 31744,\n 31751,\n 31763,\n 31731,\n 31735,\n 31767,\n 31757,\n 31734,\n 31779,\n 31783,\n 31786,\n 31775,\n 31799,\n 31787,\n 31805,\n 31820,\n 31811,\n 31828,\n 31823,\n 31808,\n 31824,\n 31832,\n 31839,\n 31844,\n 31830,\n 31845,\n 31852,\n 31861,\n 31875,\n 31888,\n 31908,\n 31917,\n 31906,\n 31915,\n 31905,\n 31912,\n 31923,\n 31922,\n 31921,\n 31918,\n 31929,\n 31933,\n 31936,\n 31941,\n 31938,\n 31960,\n 31954,\n 31964,\n 31970,\n 39739,\n 31983,\n 31986,\n 31988,\n 31990,\n 31994,\n 32006,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 32002,\n 32028,\n 32021,\n 32010,\n 32069,\n 32075,\n 32046,\n 32050,\n 32063,\n 32053,\n 32070,\n 32115,\n 32086,\n 32078,\n 32114,\n 32104,\n 32110,\n 32079,\n 32099,\n 32147,\n 32137,\n 32091,\n 32143,\n 32125,\n 32155,\n 32186,\n 32174,\n 32163,\n 32181,\n 32199,\n 32189,\n 32171,\n 32317,\n 32162,\n 32175,\n 32220,\n 32184,\n 32159,\n 32176,\n 32216,\n 32221,\n 32228,\n 32222,\n 32251,\n 32242,\n 32225,\n 32261,\n 32266,\n 32291,\n 32289,\n 32274,\n 32305,\n 32287,\n 32265,\n 32267,\n 32290,\n 32326,\n 32358,\n 32315,\n 32309,\n 32313,\n 32323,\n 32311,\n 0,\n 32306,\n 32314,\n 32359,\n 32349,\n 32342,\n 32350,\n 32345,\n 32346,\n 32377,\n 32362,\n 32361,\n 32380,\n 32379,\n 32387,\n 32213,\n 32381,\n 36782,\n 32383,\n 32392,\n 32393,\n 32396,\n 32402,\n 32400,\n 32403,\n 32404,\n 32406,\n 32398,\n 32411,\n 32412,\n 32568,\n 32570,\n 32581,\n 32588,\n 32589,\n 32590,\n 32592,\n 32593,\n 32597,\n 32596,\n 32600,\n 32607,\n 32608,\n 32616,\n 32617,\n 32615,\n 32632,\n 32642,\n 32646,\n 32643,\n 32648,\n 32647,\n 32652,\n 32660,\n 32670,\n 32669,\n 32666,\n 32675,\n 32687,\n 32690,\n 32697,\n 32686,\n 32694,\n 32696,\n 35697,\n 32709,\n 32710,\n 32714,\n 32725,\n 32724,\n 32737,\n 32742,\n 32745,\n 32755,\n 32761,\n 39132,\n 32774,\n 32772,\n 32779,\n 32786,\n 32792,\n 32793,\n 32796,\n 32801,\n 32808,\n 32831,\n 32827,\n 32842,\n 32838,\n 32850,\n 32856,\n 32858,\n 32863,\n 32866,\n 32872,\n 32883,\n 32882,\n 32880,\n 32886,\n 32889,\n 32893,\n 32895,\n 32900,\n 32902,\n 32901,\n 32923,\n 32915,\n 32922,\n 32941,\n 20880,\n 32940,\n 32987,\n 32997,\n 32985,\n 32989,\n 32964,\n 32986,\n 32982,\n 33033,\n 33007,\n 33009,\n 33051,\n 33065,\n 33059,\n 33071,\n 33099,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 38539,\n 33094,\n 33086,\n 33107,\n 33105,\n 33020,\n 33137,\n 33134,\n 33125,\n 33126,\n 33140,\n 33155,\n 33160,\n 33162,\n 33152,\n 33154,\n 33184,\n 33173,\n 33188,\n 33187,\n 33119,\n 33171,\n 33193,\n 33200,\n 33205,\n 33214,\n 33208,\n 33213,\n 33216,\n 33218,\n 33210,\n 33225,\n 33229,\n 33233,\n 33241,\n 33240,\n 33224,\n 33242,\n 33247,\n 33248,\n 33255,\n 33274,\n 33275,\n 33278,\n 33281,\n 33282,\n 33285,\n 33287,\n 33290,\n 33293,\n 33296,\n 33302,\n 33321,\n 33323,\n 33336,\n 33331,\n 33344,\n 33369,\n 33368,\n 33373,\n 33370,\n 33375,\n 33380,\n 0,\n 33378,\n 33384,\n 33386,\n 33387,\n 33326,\n 33393,\n 33399,\n 33400,\n 33406,\n 33421,\n 33426,\n 33451,\n 33439,\n 33467,\n 33452,\n 33505,\n 33507,\n 33503,\n 33490,\n 33524,\n 33523,\n 33530,\n 33683,\n 33539,\n 33531,\n 33529,\n 33502,\n 33542,\n 33500,\n 33545,\n 33497,\n 33589,\n 33588,\n 33558,\n 33586,\n 33585,\n 33600,\n 33593,\n 33616,\n 33605,\n 33583,\n 33579,\n 33559,\n 33560,\n 33669,\n 33690,\n 33706,\n 33695,\n 33698,\n 33686,\n 33571,\n 33678,\n 33671,\n 33674,\n 33660,\n 33717,\n 33651,\n 33653,\n 33696,\n 33673,\n 33704,\n 33780,\n 33811,\n 33771,\n 33742,\n 33789,\n 33795,\n 33752,\n 33803,\n 33729,\n 33783,\n 33799,\n 33760,\n 33778,\n 33805,\n 33826,\n 33824,\n 33725,\n 33848,\n 34054,\n 33787,\n 33901,\n 33834,\n 33852,\n 34138,\n 33924,\n 33911,\n 33899,\n 33965,\n 33902,\n 33922,\n 33897,\n 33862,\n 33836,\n 33903,\n 33913,\n 33845,\n 33994,\n 33890,\n 33977,\n 33983,\n 33951,\n 34009,\n 33997,\n 33979,\n 34010,\n 34000,\n 33985,\n 33990,\n 34006,\n 33953,\n 34081,\n 34047,\n 34036,\n 34071,\n 34072,\n 34092,\n 34079,\n 34069,\n 34068,\n 34044,\n 34112,\n 34147,\n 34136,\n 34120,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 34113,\n 34306,\n 34123,\n 34133,\n 34176,\n 34212,\n 34184,\n 34193,\n 34186,\n 34216,\n 34157,\n 34196,\n 34203,\n 34282,\n 34183,\n 34204,\n 34167,\n 34174,\n 34192,\n 34249,\n 34234,\n 34255,\n 34233,\n 34256,\n 34261,\n 34269,\n 34277,\n 34268,\n 34297,\n 34314,\n 34323,\n 34315,\n 34302,\n 34298,\n 34310,\n 34338,\n 34330,\n 34352,\n 34367,\n 34381,\n 20053,\n 34388,\n 34399,\n 34407,\n 34417,\n 34451,\n 34467,\n 34473,\n 34474,\n 34443,\n 34444,\n 34486,\n 34479,\n 34500,\n 34502,\n 34480,\n 34505,\n 34851,\n 34475,\n 34516,\n 34526,\n 34537,\n 34540,\n 0,\n 34527,\n 34523,\n 34543,\n 34578,\n 34566,\n 34568,\n 34560,\n 34563,\n 34555,\n 34577,\n 34569,\n 34573,\n 34553,\n 34570,\n 34612,\n 34623,\n 34615,\n 34619,\n 34597,\n 34601,\n 34586,\n 34656,\n 34655,\n 34680,\n 34636,\n 34638,\n 34676,\n 34647,\n 34664,\n 34670,\n 34649,\n 34643,\n 34659,\n 34666,\n 34821,\n 34722,\n 34719,\n 34690,\n 34735,\n 34763,\n 34749,\n 34752,\n 34768,\n 38614,\n 34731,\n 34756,\n 34739,\n 34759,\n 34758,\n 34747,\n 34799,\n 34802,\n 34784,\n 34831,\n 34829,\n 34814,\n 34806,\n 34807,\n 34830,\n 34770,\n 34833,\n 34838,\n 34837,\n 34850,\n 34849,\n 34865,\n 34870,\n 34873,\n 34855,\n 34875,\n 34884,\n 34882,\n 34898,\n 34905,\n 34910,\n 34914,\n 34923,\n 34945,\n 34942,\n 34974,\n 34933,\n 34941,\n 34997,\n 34930,\n 34946,\n 34967,\n 34962,\n 34990,\n 34969,\n 34978,\n 34957,\n 34980,\n 34992,\n 35007,\n 34993,\n 35011,\n 35012,\n 35028,\n 35032,\n 35033,\n 35037,\n 35065,\n 35074,\n 35068,\n 35060,\n 35048,\n 35058,\n 35076,\n 35084,\n 35082,\n 35091,\n 35139,\n 35102,\n 35109,\n 35114,\n 35115,\n 35137,\n 35140,\n 35131,\n 35126,\n 35128,\n 35148,\n 35101,\n 35168,\n 35166,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 35174,\n 35172,\n 35181,\n 35178,\n 35183,\n 35188,\n 35191,\n 35198,\n 35203,\n 35208,\n 35210,\n 35219,\n 35224,\n 35233,\n 35241,\n 35238,\n 35244,\n 35247,\n 35250,\n 35258,\n 35261,\n 35263,\n 35264,\n 35290,\n 35292,\n 35293,\n 35303,\n 35316,\n 35320,\n 35331,\n 35350,\n 35344,\n 35340,\n 35355,\n 35357,\n 35365,\n 35382,\n 35393,\n 35419,\n 35410,\n 35398,\n 35400,\n 35452,\n 35437,\n 35436,\n 35426,\n 35461,\n 35458,\n 35460,\n 35496,\n 35489,\n 35473,\n 35493,\n 35494,\n 35482,\n 35491,\n 35524,\n 35533,\n 35522,\n 35546,\n 35563,\n 35571,\n 35559,\n 0,\n 35556,\n 35569,\n 35604,\n 35552,\n 35554,\n 35575,\n 35550,\n 35547,\n 35596,\n 35591,\n 35610,\n 35553,\n 35606,\n 35600,\n 35607,\n 35616,\n 35635,\n 38827,\n 35622,\n 35627,\n 35646,\n 35624,\n 35649,\n 35660,\n 35663,\n 35662,\n 35657,\n 35670,\n 35675,\n 35674,\n 35691,\n 35679,\n 35692,\n 35695,\n 35700,\n 35709,\n 35712,\n 35724,\n 35726,\n 35730,\n 35731,\n 35734,\n 35737,\n 35738,\n 35898,\n 35905,\n 35903,\n 35912,\n 35916,\n 35918,\n 35920,\n 35925,\n 35938,\n 35948,\n 35960,\n 35962,\n 35970,\n 35977,\n 35973,\n 35978,\n 35981,\n 35982,\n 35988,\n 35964,\n 35992,\n 25117,\n 36013,\n 36010,\n 36029,\n 36018,\n 36019,\n 36014,\n 36022,\n 36040,\n 36033,\n 36068,\n 36067,\n 36058,\n 36093,\n 36090,\n 36091,\n 36100,\n 36101,\n 36106,\n 36103,\n 36111,\n 36109,\n 36112,\n 40782,\n 36115,\n 36045,\n 36116,\n 36118,\n 36199,\n 36205,\n 36209,\n 36211,\n 36225,\n 36249,\n 36290,\n 36286,\n 36282,\n 36303,\n 36314,\n 36310,\n 36300,\n 36315,\n 36299,\n 36330,\n 36331,\n 36319,\n 36323,\n 36348,\n 36360,\n 36361,\n 36351,\n 36381,\n 36382,\n 36368,\n 36383,\n 36418,\n 36405,\n 36400,\n 36404,\n 36426,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 36423,\n 36425,\n 36428,\n 36432,\n 36424,\n 36441,\n 36452,\n 36448,\n 36394,\n 36451,\n 36437,\n 36470,\n 36466,\n 36476,\n 36481,\n 36487,\n 36485,\n 36484,\n 36491,\n 36490,\n 36499,\n 36497,\n 36500,\n 36505,\n 36522,\n 36513,\n 36524,\n 36528,\n 36550,\n 36529,\n 36542,\n 36549,\n 36552,\n 36555,\n 36571,\n 36579,\n 36604,\n 36603,\n 36587,\n 36606,\n 36618,\n 36613,\n 36629,\n 36626,\n 36633,\n 36627,\n 36636,\n 36639,\n 36635,\n 36620,\n 36646,\n 36659,\n 36667,\n 36665,\n 36677,\n 36674,\n 36670,\n 36684,\n 36681,\n 36678,\n 36686,\n 36695,\n 36700,\n 0,\n 36706,\n 36707,\n 36708,\n 36764,\n 36767,\n 36771,\n 36781,\n 36783,\n 36791,\n 36826,\n 36837,\n 36834,\n 36842,\n 36847,\n 36999,\n 36852,\n 36869,\n 36857,\n 36858,\n 36881,\n 36885,\n 36897,\n 36877,\n 36894,\n 36886,\n 36875,\n 36903,\n 36918,\n 36917,\n 36921,\n 36856,\n 36943,\n 36944,\n 36945,\n 36946,\n 36878,\n 36937,\n 36926,\n 36950,\n 36952,\n 36958,\n 36968,\n 36975,\n 36982,\n 38568,\n 36978,\n 36994,\n 36989,\n 36993,\n 36992,\n 37002,\n 37001,\n 37007,\n 37032,\n 37039,\n 37041,\n 37045,\n 37090,\n 37092,\n 25160,\n 37083,\n 37122,\n 37138,\n 37145,\n 37170,\n 37168,\n 37194,\n 37206,\n 37208,\n 37219,\n 37221,\n 37225,\n 37235,\n 37234,\n 37259,\n 37257,\n 37250,\n 37282,\n 37291,\n 37295,\n 37290,\n 37301,\n 37300,\n 37306,\n 37312,\n 37313,\n 37321,\n 37323,\n 37328,\n 37334,\n 37343,\n 37345,\n 37339,\n 37372,\n 37365,\n 37366,\n 37406,\n 37375,\n 37396,\n 37420,\n 37397,\n 37393,\n 37470,\n 37463,\n 37445,\n 37449,\n 37476,\n 37448,\n 37525,\n 37439,\n 37451,\n 37456,\n 37532,\n 37526,\n 37523,\n 37531,\n 37466,\n 37583,\n 37561,\n 37559,\n 37609,\n 37647,\n 37626,\n 37700,\n 37678,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 37657,\n 37666,\n 37658,\n 37667,\n 37690,\n 37685,\n 37691,\n 37724,\n 37728,\n 37756,\n 37742,\n 37718,\n 37808,\n 37804,\n 37805,\n 37780,\n 37817,\n 37846,\n 37847,\n 37864,\n 37861,\n 37848,\n 37827,\n 37853,\n 37840,\n 37832,\n 37860,\n 37914,\n 37908,\n 37907,\n 37891,\n 37895,\n 37904,\n 37942,\n 37931,\n 37941,\n 37921,\n 37946,\n 37953,\n 37970,\n 37956,\n 37979,\n 37984,\n 37986,\n 37982,\n 37994,\n 37417,\n 38000,\n 38005,\n 38007,\n 38013,\n 37978,\n 38012,\n 38014,\n 38017,\n 38015,\n 38274,\n 38279,\n 38282,\n 38292,\n 38294,\n 38296,\n 38297,\n 0,\n 38304,\n 38312,\n 38311,\n 38317,\n 38332,\n 38331,\n 38329,\n 38334,\n 38346,\n 28662,\n 38339,\n 38349,\n 38348,\n 38357,\n 38356,\n 38358,\n 38364,\n 38369,\n 38373,\n 38370,\n 38433,\n 38440,\n 38446,\n 38447,\n 38466,\n 38476,\n 38479,\n 38475,\n 38519,\n 38492,\n 38494,\n 38493,\n 38495,\n 38502,\n 38514,\n 38508,\n 38541,\n 38552,\n 38549,\n 38551,\n 38570,\n 38567,\n 38577,\n 38578,\n 38576,\n 38580,\n 38582,\n 38584,\n 38585,\n 38606,\n 38603,\n 38601,\n 38605,\n 35149,\n 38620,\n 38669,\n 38613,\n 38649,\n 38660,\n 38662,\n 38664,\n 38675,\n 38670,\n 38673,\n 38671,\n 38678,\n 38681,\n 38692,\n 38698,\n 38704,\n 38713,\n 38717,\n 38718,\n 38724,\n 38726,\n 38728,\n 38722,\n 38729,\n 38748,\n 38752,\n 38756,\n 38758,\n 38760,\n 21202,\n 38763,\n 38769,\n 38777,\n 38789,\n 38780,\n 38785,\n 38778,\n 38790,\n 38795,\n 38799,\n 38800,\n 38812,\n 38824,\n 38822,\n 38819,\n 38835,\n 38836,\n 38851,\n 38854,\n 38856,\n 38859,\n 38876,\n 38893,\n 40783,\n 38898,\n 31455,\n 38902,\n 38901,\n 38927,\n 38924,\n 38968,\n 38948,\n 38945,\n 38967,\n 38973,\n 38982,\n 38991,\n 38987,\n 39019,\n 39023,\n 39024,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 39025,\n 39028,\n 39027,\n 39082,\n 39087,\n 39089,\n 39094,\n 39108,\n 39107,\n 39110,\n 39145,\n 39147,\n 39171,\n 39177,\n 39186,\n 39188,\n 39192,\n 39201,\n 39197,\n 39198,\n 39204,\n 39200,\n 39212,\n 39214,\n 39229,\n 39230,\n 39234,\n 39241,\n 39237,\n 39248,\n 39243,\n 39249,\n 39250,\n 39244,\n 39253,\n 39319,\n 39320,\n 39333,\n 39341,\n 39342,\n 39356,\n 39391,\n 39387,\n 39389,\n 39384,\n 39377,\n 39405,\n 39406,\n 39409,\n 39410,\n 39419,\n 39416,\n 39425,\n 39439,\n 39429,\n 39394,\n 39449,\n 39467,\n 39479,\n 39493,\n 39490,\n 39488,\n 39491,\n 0,\n 39486,\n 39509,\n 39501,\n 39515,\n 39511,\n 39519,\n 39522,\n 39525,\n 39524,\n 39529,\n 39531,\n 39530,\n 39597,\n 39600,\n 39612,\n 39616,\n 39631,\n 39633,\n 39635,\n 39636,\n 39646,\n 39647,\n 39650,\n 39651,\n 39654,\n 39663,\n 39659,\n 39662,\n 39668,\n 39665,\n 39671,\n 39675,\n 39686,\n 39704,\n 39706,\n 39711,\n 39714,\n 39715,\n 39717,\n 39719,\n 39720,\n 39721,\n 39722,\n 39726,\n 39727,\n 39730,\n 39748,\n 39747,\n 39759,\n 39757,\n 39758,\n 39761,\n 39768,\n 39796,\n 39827,\n 39811,\n 39825,\n 39830,\n 39831,\n 39839,\n 39840,\n 39848,\n 39860,\n 39872,\n 39882,\n 39865,\n 39878,\n 39887,\n 39889,\n 39890,\n 39907,\n 39906,\n 39908,\n 39892,\n 39905,\n 39994,\n 39922,\n 39921,\n 39920,\n 39957,\n 39956,\n 39945,\n 39955,\n 39948,\n 39942,\n 39944,\n 39954,\n 39946,\n 39940,\n 39982,\n 39963,\n 39973,\n 39972,\n 39969,\n 39984,\n 40007,\n 39986,\n 40006,\n 39998,\n 40026,\n 40032,\n 40039,\n 40054,\n 40056,\n 40167,\n 40172,\n 40176,\n 40201,\n 40200,\n 40171,\n 40195,\n 40198,\n 40234,\n 40230,\n 40367,\n 40227,\n 40223,\n 40260,\n 40213,\n 40210,\n 40257,\n 40255,\n 40254,\n 40262,\n 40264,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 40285,\n 40286,\n 40292,\n 40273,\n 40272,\n 40281,\n 40306,\n 40329,\n 40327,\n 40363,\n 40303,\n 40314,\n 40346,\n 40356,\n 40361,\n 40370,\n 40388,\n 40385,\n 40379,\n 40376,\n 40378,\n 40390,\n 40399,\n 40386,\n 40409,\n 40403,\n 40440,\n 40422,\n 40429,\n 40431,\n 40445,\n 40474,\n 40475,\n 40478,\n 40565,\n 40569,\n 40573,\n 40577,\n 40584,\n 40587,\n 40588,\n 40594,\n 40597,\n 40593,\n 40605,\n 40613,\n 40617,\n 40632,\n 40618,\n 40621,\n 38753,\n 40652,\n 40654,\n 40655,\n 40656,\n 40660,\n 40668,\n 40670,\n 40669,\n 40672,\n 40677,\n 40680,\n 40687,\n 0,\n 40692,\n 40694,\n 40695,\n 40697,\n 40699,\n 40700,\n 40701,\n 40711,\n 40712,\n 30391,\n 40725,\n 40737,\n 40748,\n 40766,\n 40778,\n 40786,\n 40788,\n 40803,\n 40799,\n 40800,\n 40801,\n 40806,\n 40807,\n 40812,\n 40810,\n 40823,\n 40818,\n 40822,\n 40853,\n 40860,\n 40864,\n 22575,\n 27079,\n 36953,\n 29796,\n 20956,\n 29081,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 32394,\n 35100,\n 37704,\n 37512,\n 34012,\n 20425,\n 28859,\n 26161,\n 26824,\n 37625,\n 26363,\n 24389,\n 20008,\n 20193,\n 20220,\n 20224,\n 20227,\n 20281,\n 20310,\n 20370,\n 20362,\n 20378,\n 20372,\n 20429,\n 20544,\n 20514,\n 20479,\n 20510,\n 20550,\n 20592,\n 20546,\n 20628,\n 20724,\n 20696,\n 20810,\n 20836,\n 20893,\n 20926,\n 20972,\n 21013,\n 21148,\n 21158,\n 21184,\n 21211,\n 21248,\n 21255,\n 21284,\n 21362,\n 21395,\n 21426,\n 21469,\n 64014,\n 21660,\n 21642,\n 21673,\n 21759,\n 21894,\n 22361,\n 22373,\n 22444,\n 22472,\n 22471,\n 64015,\n 0,\n 64016,\n 22686,\n 22706,\n 22795,\n 22867,\n 22875,\n 22877,\n 22883,\n 22948,\n 22970,\n 23382,\n 23488,\n 29999,\n 23512,\n 23532,\n 23582,\n 23718,\n 23738,\n 23797,\n 23847,\n 23891,\n 64017,\n 23874,\n 23917,\n 23992,\n 23993,\n 24016,\n 24353,\n 24372,\n 24423,\n 24503,\n 24542,\n 24669,\n 24709,\n 24714,\n 24798,\n 24789,\n 24864,\n 24818,\n 24849,\n 24887,\n 24880,\n 24984,\n 25107,\n 25254,\n 25589,\n 25696,\n 25757,\n 25806,\n 25934,\n 26112,\n 26133,\n 26171,\n 26121,\n 26158,\n 26142,\n 26148,\n 26213,\n 26199,\n 26201,\n 64018,\n 26227,\n 26265,\n 26272,\n 26290,\n 26303,\n 26362,\n 26382,\n 63785,\n 26470,\n 26555,\n 26706,\n 26560,\n 26625,\n 26692,\n 26831,\n 64019,\n 26984,\n 64020,\n 27032,\n 27106,\n 27184,\n 27243,\n 27206,\n 27251,\n 27262,\n 27362,\n 27364,\n 27606,\n 27711,\n 27740,\n 27782,\n 27759,\n 27866,\n 27908,\n 28039,\n 28015,\n 28054,\n 28076,\n 28111,\n 28152,\n 28146,\n 28156,\n 28217,\n 28252,\n 28199,\n 28220,\n 28351,\n 28552,\n 28597,\n 28661,\n 28677,\n 28679,\n 28712,\n 28805,\n 28843,\n 28943,\n 28932,\n 29020,\n 28998,\n 28999,\n 64021,\n 29121,\n 29182,\n 29361,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 29374,\n 29476,\n 64022,\n 29559,\n 29629,\n 29641,\n 29654,\n 29667,\n 29650,\n 29703,\n 29685,\n 29734,\n 29738,\n 29737,\n 29742,\n 29794,\n 29833,\n 29855,\n 29953,\n 30063,\n 30338,\n 30364,\n 30366,\n 30363,\n 30374,\n 64023,\n 30534,\n 21167,\n 30753,\n 30798,\n 30820,\n 30842,\n 31024,\n 64024,\n 64025,\n 64026,\n 31124,\n 64027,\n 31131,\n 31441,\n 31463,\n 64028,\n 31467,\n 31646,\n 64029,\n 32072,\n 32092,\n 32183,\n 32160,\n 32214,\n 32338,\n 32583,\n 32673,\n 64030,\n 33537,\n 33634,\n 33663,\n 33735,\n 33782,\n 33864,\n 33972,\n 34131,\n 34137,\n 0,\n 34155,\n 64031,\n 34224,\n 64032,\n 64033,\n 34823,\n 35061,\n 35346,\n 35383,\n 35449,\n 35495,\n 35518,\n 35551,\n 64034,\n 35574,\n 35667,\n 35711,\n 36080,\n 36084,\n 36114,\n 36214,\n 64035,\n 36559,\n 64036,\n 64037,\n 36967,\n 37086,\n 64038,\n 37141,\n 37159,\n 37338,\n 37335,\n 37342,\n 37357,\n 37358,\n 37348,\n 37349,\n 37382,\n 37392,\n 37386,\n 37434,\n 37440,\n 37436,\n 37454,\n 37465,\n 37457,\n 37433,\n 37479,\n 37543,\n 37495,\n 37496,\n 37607,\n 37591,\n 37593,\n 37584,\n 64039,\n 37589,\n 37600,\n 37587,\n 37669,\n 37665,\n 37627,\n 64040,\n 37662,\n 37631,\n 37661,\n 37634,\n 37744,\n 37719,\n 37796,\n 37830,\n 37854,\n 37880,\n 37937,\n 37957,\n 37960,\n 38290,\n 63964,\n 64041,\n 38557,\n 38575,\n 38707,\n 38715,\n 38723,\n 38733,\n 38735,\n 38737,\n 38741,\n 38999,\n 39013,\n 64042,\n 64043,\n 39207,\n 64044,\n 39326,\n 39502,\n 39641,\n 39644,\n 39797,\n 39794,\n 39823,\n 39857,\n 39867,\n 39936,\n 40304,\n 40299,\n 64045,\n 40473,\n 40657,\n 0,\n 0,\n 8560,\n 8561,\n 8562,\n 8563,\n 8564,\n 8565,\n 8566,\n 8567,\n 8568,\n 8569,\n 65506,\n 65508,\n 65287,\n 65282,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 57344,\n 57345,\n 57346,\n 57347,\n 57348,\n 57349,\n 57350,\n 57351,\n 57352,\n 57353,\n 57354,\n 57355,\n 57356,\n 57357,\n 57358,\n 57359,\n 57360,\n 57361,\n 57362,\n 57363,\n 57364,\n 57365,\n 57366,\n 57367,\n 57368,\n 57369,\n 57370,\n 57371,\n 57372,\n 57373,\n 57374,\n 57375,\n 57376,\n 57377,\n 57378,\n 57379,\n 57380,\n 57381,\n 57382,\n 57383,\n 57384,\n 57385,\n 57386,\n 57387,\n 57388,\n 57389,\n 57390,\n 57391,\n 57392,\n 57393,\n 57394,\n 57395,\n 57396,\n 57397,\n 57398,\n 57399,\n 57400,\n 57401,\n 57402,\n 57403,\n 57404,\n 57405,\n 57406,\n 0,\n 57407,\n 57408,\n 57409,\n 57410,\n 57411,\n 57412,\n 57413,\n 57414,\n 57415,\n 57416,\n 57417,\n 57418,\n 57419,\n 57420,\n 57421,\n 57422,\n 57423,\n 57424,\n 57425,\n 57426,\n 57427,\n 57428,\n 57429,\n 57430,\n 57431,\n 57432,\n 57433,\n 57434,\n 57435,\n 57436,\n 57437,\n 57438,\n 57439,\n 57440,\n 57441,\n 57442,\n 57443,\n 57444,\n 57445,\n 57446,\n 57447,\n 57448,\n 57449,\n 57450,\n 57451,\n 57452,\n 57453,\n 57454,\n 57455,\n 57456,\n 57457,\n 57458,\n 57459,\n 57460,\n 57461,\n 57462,\n 57463,\n 57464,\n 57465,\n 57466,\n 57467,\n 57468,\n 57469,\n 57470,\n 57471,\n 57472,\n 57473,\n 57474,\n 57475,\n 57476,\n 57477,\n 57478,\n 57479,\n 57480,\n 57481,\n 57482,\n 57483,\n 57484,\n 57485,\n 57486,\n 57487,\n 57488,\n 57489,\n 57490,\n 57491,\n 57492,\n 57493,\n 57494,\n 57495,\n 57496,\n 57497,\n 57498,\n 57499,\n 57500,\n 57501,\n 57502,\n 57503,\n 57504,\n 57505,\n 57506,\n 57507,\n 57508,\n 57509,\n 57510,\n 57511,\n 57512,\n 57513,\n 57514,\n 57515,\n 57516,\n 57517,\n 57518,\n 57519,\n 57520,\n 57521,\n 57522,\n 57523,\n 57524,\n 57525,\n 57526,\n 57527,\n 57528,\n 57529,\n 57530,\n 57531,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 57532,\n 57533,\n 57534,\n 57535,\n 57536,\n 57537,\n 57538,\n 57539,\n 57540,\n 57541,\n 57542,\n 57543,\n 57544,\n 57545,\n 57546,\n 57547,\n 57548,\n 57549,\n 57550,\n 57551,\n 57552,\n 57553,\n 57554,\n 57555,\n 57556,\n 57557,\n 57558,\n 57559,\n 57560,\n 57561,\n 57562,\n 57563,\n 57564,\n 57565,\n 57566,\n 57567,\n 57568,\n 57569,\n 57570,\n 57571,\n 57572,\n 57573,\n 57574,\n 57575,\n 57576,\n 57577,\n 57578,\n 57579,\n 57580,\n 57581,\n 57582,\n 57583,\n 57584,\n 57585,\n 57586,\n 57587,\n 57588,\n 57589,\n 57590,\n 57591,\n 57592,\n 57593,\n 57594,\n 0,\n 57595,\n 57596,\n 57597,\n 57598,\n 57599,\n 57600,\n 57601,\n 57602,\n 57603,\n 57604,\n 57605,\n 57606,\n 57607,\n 57608,\n 57609,\n 57610,\n 57611,\n 57612,\n 57613,\n 57614,\n 57615,\n 57616,\n 57617,\n 57618,\n 57619,\n 57620,\n 57621,\n 57622,\n 57623,\n 57624,\n 57625,\n 57626,\n 57627,\n 57628,\n 57629,\n 57630,\n 57631,\n 57632,\n 57633,\n 57634,\n 57635,\n 57636,\n 57637,\n 57638,\n 57639,\n 57640,\n 57641,\n 57642,\n 57643,\n 57644,\n 57645,\n 57646,\n 57647,\n 57648,\n 57649,\n 57650,\n 57651,\n 57652,\n 57653,\n 57654,\n 57655,\n 57656,\n 57657,\n 57658,\n 57659,\n 57660,\n 57661,\n 57662,\n 57663,\n 57664,\n 57665,\n 57666,\n 57667,\n 57668,\n 57669,\n 57670,\n 57671,\n 57672,\n 57673,\n 57674,\n 57675,\n 57676,\n 57677,\n 57678,\n 57679,\n 57680,\n 57681,\n 57682,\n 57683,\n 57684,\n 57685,\n 57686,\n 57687,\n 57688,\n 57689,\n 57690,\n 57691,\n 57692,\n 57693,\n 57694,\n 57695,\n 57696,\n 57697,\n 57698,\n 57699,\n 57700,\n 57701,\n 57702,\n 57703,\n 57704,\n 57705,\n 57706,\n 57707,\n 57708,\n 57709,\n 57710,\n 57711,\n 57712,\n 57713,\n 57714,\n 57715,\n 57716,\n 57717,\n 57718,\n 57719,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 57720,\n 57721,\n 57722,\n 57723,\n 57724,\n 57725,\n 57726,\n 57727,\n 57728,\n 57729,\n 57730,\n 57731,\n 57732,\n 57733,\n 57734,\n 57735,\n 57736,\n 57737,\n 57738,\n 57739,\n 57740,\n 57741,\n 57742,\n 57743,\n 57744,\n 57745,\n 57746,\n 57747,\n 57748,\n 57749,\n 57750,\n 57751,\n 57752,\n 57753,\n 57754,\n 57755,\n 57756,\n 57757,\n 57758,\n 57759,\n 57760,\n 57761,\n 57762,\n 57763,\n 57764,\n 57765,\n 57766,\n 57767,\n 57768,\n 57769,\n 57770,\n 57771,\n 57772,\n 57773,\n 57774,\n 57775,\n 57776,\n 57777,\n 57778,\n 57779,\n 57780,\n 57781,\n 57782,\n 0,\n 57783,\n 57784,\n 57785,\n 57786,\n 57787,\n 57788,\n 57789,\n 57790,\n 57791,\n 57792,\n 57793,\n 57794,\n 57795,\n 57796,\n 57797,\n 57798,\n 57799,\n 57800,\n 57801,\n 57802,\n 57803,\n 57804,\n 57805,\n 57806,\n 57807,\n 57808,\n 57809,\n 57810,\n 57811,\n 57812,\n 57813,\n 57814,\n 57815,\n 57816,\n 57817,\n 57818,\n 57819,\n 57820,\n 57821,\n 57822,\n 57823,\n 57824,\n 57825,\n 57826,\n 57827,\n 57828,\n 57829,\n 57830,\n 57831,\n 57832,\n 57833,\n 57834,\n 57835,\n 57836,\n 57837,\n 57838,\n 57839,\n 57840,\n 57841,\n 57842,\n 57843,\n 57844,\n 57845,\n 57846,\n 57847,\n 57848,\n 57849,\n 57850,\n 57851,\n 57852,\n 57853,\n 57854,\n 57855,\n 57856,\n 57857,\n 57858,\n 57859,\n 57860,\n 57861,\n 57862,\n 57863,\n 57864,\n 57865,\n 57866,\n 57867,\n 57868,\n 57869,\n 57870,\n 57871,\n 57872,\n 57873,\n 57874,\n 57875,\n 57876,\n 57877,\n 57878,\n 57879,\n 57880,\n 57881,\n 57882,\n 57883,\n 57884,\n 57885,\n 57886,\n 57887,\n 57888,\n 57889,\n 57890,\n 57891,\n 57892,\n 57893,\n 57894,\n 57895,\n 57896,\n 57897,\n 57898,\n 57899,\n 57900,\n 57901,\n 57902,\n 57903,\n 57904,\n 57905,\n 57906,\n 57907,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 57908,\n 57909,\n 57910,\n 57911,\n 57912,\n 57913,\n 57914,\n 57915,\n 57916,\n 57917,\n 57918,\n 57919,\n 57920,\n 57921,\n 57922,\n 57923,\n 57924,\n 57925,\n 57926,\n 57927,\n 57928,\n 57929,\n 57930,\n 57931,\n 57932,\n 57933,\n 57934,\n 57935,\n 57936,\n 57937,\n 57938,\n 57939,\n 57940,\n 57941,\n 57942,\n 57943,\n 57944,\n 57945,\n 57946,\n 57947,\n 57948,\n 57949,\n 57950,\n 57951,\n 57952,\n 57953,\n 57954,\n 57955,\n 57956,\n 57957,\n 57958,\n 57959,\n 57960,\n 57961,\n 57962,\n 57963,\n 57964,\n 57965,\n 57966,\n 57967,\n 57968,\n 57969,\n 57970,\n 0,\n 57971,\n 57972,\n 57973,\n 57974,\n 57975,\n 57976,\n 57977,\n 57978,\n 57979,\n 57980,\n 57981,\n 57982,\n 57983,\n 57984,\n 57985,\n 57986,\n 57987,\n 57988,\n 57989,\n 57990,\n 57991,\n 57992,\n 57993,\n 57994,\n 57995,\n 57996,\n 57997,\n 57998,\n 57999,\n 58000,\n 58001,\n 58002,\n 58003,\n 58004,\n 58005,\n 58006,\n 58007,\n 58008,\n 58009,\n 58010,\n 58011,\n 58012,\n 58013,\n 58014,\n 58015,\n 58016,\n 58017,\n 58018,\n 58019,\n 58020,\n 58021,\n 58022,\n 58023,\n 58024,\n 58025,\n 58026,\n 58027,\n 58028,\n 58029,\n 58030,\n 58031,\n 58032,\n 58033,\n 58034,\n 58035,\n 58036,\n 58037,\n 58038,\n 58039,\n 58040,\n 58041,\n 58042,\n 58043,\n 58044,\n 58045,\n 58046,\n 58047,\n 58048,\n 58049,\n 58050,\n 58051,\n 58052,\n 58053,\n 58054,\n 58055,\n 58056,\n 58057,\n 58058,\n 58059,\n 58060,\n 58061,\n 58062,\n 58063,\n 58064,\n 58065,\n 58066,\n 58067,\n 58068,\n 58069,\n 58070,\n 58071,\n 58072,\n 58073,\n 58074,\n 58075,\n 58076,\n 58077,\n 58078,\n 58079,\n 58080,\n 58081,\n 58082,\n 58083,\n 58084,\n 58085,\n 58086,\n 58087,\n 58088,\n 58089,\n 58090,\n 58091,\n 58092,\n 58093,\n 58094,\n 58095,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 58096,\n 58097,\n 58098,\n 58099,\n 58100,\n 58101,\n 58102,\n 58103,\n 58104,\n 58105,\n 58106,\n 58107,\n 58108,\n 58109,\n 58110,\n 58111,\n 58112,\n 58113,\n 58114,\n 58115,\n 58116,\n 58117,\n 58118,\n 58119,\n 58120,\n 58121,\n 58122,\n 58123,\n 58124,\n 58125,\n 58126,\n 58127,\n 58128,\n 58129,\n 58130,\n 58131,\n 58132,\n 58133,\n 58134,\n 58135,\n 58136,\n 58137,\n 58138,\n 58139,\n 58140,\n 58141,\n 58142,\n 58143,\n 58144,\n 58145,\n 58146,\n 58147,\n 58148,\n 58149,\n 58150,\n 58151,\n 58152,\n 58153,\n 58154,\n 58155,\n 58156,\n 58157,\n 58158,\n 0,\n 58159,\n 58160,\n 58161,\n 58162,\n 58163,\n 58164,\n 58165,\n 58166,\n 58167,\n 58168,\n 58169,\n 58170,\n 58171,\n 58172,\n 58173,\n 58174,\n 58175,\n 58176,\n 58177,\n 58178,\n 58179,\n 58180,\n 58181,\n 58182,\n 58183,\n 58184,\n 58185,\n 58186,\n 58187,\n 58188,\n 58189,\n 58190,\n 58191,\n 58192,\n 58193,\n 58194,\n 58195,\n 58196,\n 58197,\n 58198,\n 58199,\n 58200,\n 58201,\n 58202,\n 58203,\n 58204,\n 58205,\n 58206,\n 58207,\n 58208,\n 58209,\n 58210,\n 58211,\n 58212,\n 58213,\n 58214,\n 58215,\n 58216,\n 58217,\n 58218,\n 58219,\n 58220,\n 58221,\n 58222,\n 58223,\n 58224,\n 58225,\n 58226,\n 58227,\n 58228,\n 58229,\n 58230,\n 58231,\n 58232,\n 58233,\n 58234,\n 58235,\n 58236,\n 58237,\n 58238,\n 58239,\n 58240,\n 58241,\n 58242,\n 58243,\n 58244,\n 58245,\n 58246,\n 58247,\n 58248,\n 58249,\n 58250,\n 58251,\n 58252,\n 58253,\n 58254,\n 58255,\n 58256,\n 58257,\n 58258,\n 58259,\n 58260,\n 58261,\n 58262,\n 58263,\n 58264,\n 58265,\n 58266,\n 58267,\n 58268,\n 58269,\n 58270,\n 58271,\n 58272,\n 58273,\n 58274,\n 58275,\n 58276,\n 58277,\n 58278,\n 58279,\n 58280,\n 58281,\n 58282,\n 58283,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 58284,\n 58285,\n 58286,\n 58287,\n 58288,\n 58289,\n 58290,\n 58291,\n 58292,\n 58293,\n 58294,\n 58295,\n 58296,\n 58297,\n 58298,\n 58299,\n 58300,\n 58301,\n 58302,\n 58303,\n 58304,\n 58305,\n 58306,\n 58307,\n 58308,\n 58309,\n 58310,\n 58311,\n 58312,\n 58313,\n 58314,\n 58315,\n 58316,\n 58317,\n 58318,\n 58319,\n 58320,\n 58321,\n 58322,\n 58323,\n 58324,\n 58325,\n 58326,\n 58327,\n 58328,\n 58329,\n 58330,\n 58331,\n 58332,\n 58333,\n 58334,\n 58335,\n 58336,\n 58337,\n 58338,\n 58339,\n 58340,\n 58341,\n 58342,\n 58343,\n 58344,\n 58345,\n 58346,\n 0,\n 58347,\n 58348,\n 58349,\n 58350,\n 58351,\n 58352,\n 58353,\n 58354,\n 58355,\n 58356,\n 58357,\n 58358,\n 58359,\n 58360,\n 58361,\n 58362,\n 58363,\n 58364,\n 58365,\n 58366,\n 58367,\n 58368,\n 58369,\n 58370,\n 58371,\n 58372,\n 58373,\n 58374,\n 58375,\n 58376,\n 58377,\n 58378,\n 58379,\n 58380,\n 58381,\n 58382,\n 58383,\n 58384,\n 58385,\n 58386,\n 58387,\n 58388,\n 58389,\n 58390,\n 58391,\n 58392,\n 58393,\n 58394,\n 58395,\n 58396,\n 58397,\n 58398,\n 58399,\n 58400,\n 58401,\n 58402,\n 58403,\n 58404,\n 58405,\n 58406,\n 58407,\n 58408,\n 58409,\n 58410,\n 58411,\n 58412,\n 58413,\n 58414,\n 58415,\n 58416,\n 58417,\n 58418,\n 58419,\n 58420,\n 58421,\n 58422,\n 58423,\n 58424,\n 58425,\n 58426,\n 58427,\n 58428,\n 58429,\n 58430,\n 58431,\n 58432,\n 58433,\n 58434,\n 58435,\n 58436,\n 58437,\n 58438,\n 58439,\n 58440,\n 58441,\n 58442,\n 58443,\n 58444,\n 58445,\n 58446,\n 58447,\n 58448,\n 58449,\n 58450,\n 58451,\n 58452,\n 58453,\n 58454,\n 58455,\n 58456,\n 58457,\n 58458,\n 58459,\n 58460,\n 58461,\n 58462,\n 58463,\n 58464,\n 58465,\n 58466,\n 58467,\n 58468,\n 58469,\n 58470,\n 58471,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 58472,\n 58473,\n 58474,\n 58475,\n 58476,\n 58477,\n 58478,\n 58479,\n 58480,\n 58481,\n 58482,\n 58483,\n 58484,\n 58485,\n 58486,\n 58487,\n 58488,\n 58489,\n 58490,\n 58491,\n 58492,\n 58493,\n 58494,\n 58495,\n 58496,\n 58497,\n 58498,\n 58499,\n 58500,\n 58501,\n 58502,\n 58503,\n 58504,\n 58505,\n 58506,\n 58507,\n 58508,\n 58509,\n 58510,\n 58511,\n 58512,\n 58513,\n 58514,\n 58515,\n 58516,\n 58517,\n 58518,\n 58519,\n 58520,\n 58521,\n 58522,\n 58523,\n 58524,\n 58525,\n 58526,\n 58527,\n 58528,\n 58529,\n 58530,\n 58531,\n 58532,\n 58533,\n 58534,\n 0,\n 58535,\n 58536,\n 58537,\n 58538,\n 58539,\n 58540,\n 58541,\n 58542,\n 58543,\n 58544,\n 58545,\n 58546,\n 58547,\n 58548,\n 58549,\n 58550,\n 58551,\n 58552,\n 58553,\n 58554,\n 58555,\n 58556,\n 58557,\n 58558,\n 58559,\n 58560,\n 58561,\n 58562,\n 58563,\n 58564,\n 58565,\n 58566,\n 58567,\n 58568,\n 58569,\n 58570,\n 58571,\n 58572,\n 58573,\n 58574,\n 58575,\n 58576,\n 58577,\n 58578,\n 58579,\n 58580,\n 58581,\n 58582,\n 58583,\n 58584,\n 58585,\n 58586,\n 58587,\n 58588,\n 58589,\n 58590,\n 58591,\n 58592,\n 58593,\n 58594,\n 58595,\n 58596,\n 58597,\n 58598,\n 58599,\n 58600,\n 58601,\n 58602,\n 58603,\n 58604,\n 58605,\n 58606,\n 58607,\n 58608,\n 58609,\n 58610,\n 58611,\n 58612,\n 58613,\n 58614,\n 58615,\n 58616,\n 58617,\n 58618,\n 58619,\n 58620,\n 58621,\n 58622,\n 58623,\n 58624,\n 58625,\n 58626,\n 58627,\n 58628,\n 58629,\n 58630,\n 58631,\n 58632,\n 58633,\n 58634,\n 58635,\n 58636,\n 58637,\n 58638,\n 58639,\n 58640,\n 58641,\n 58642,\n 58643,\n 58644,\n 58645,\n 58646,\n 58647,\n 58648,\n 58649,\n 58650,\n 58651,\n 58652,\n 58653,\n 58654,\n 58655,\n 58656,\n 58657,\n 58658,\n 58659,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 58660,\n 58661,\n 58662,\n 58663,\n 58664,\n 58665,\n 58666,\n 58667,\n 58668,\n 58669,\n 58670,\n 58671,\n 58672,\n 58673,\n 58674,\n 58675,\n 58676,\n 58677,\n 58678,\n 58679,\n 58680,\n 58681,\n 58682,\n 58683,\n 58684,\n 58685,\n 58686,\n 58687,\n 58688,\n 58689,\n 58690,\n 58691,\n 58692,\n 58693,\n 58694,\n 58695,\n 58696,\n 58697,\n 58698,\n 58699,\n 58700,\n 58701,\n 58702,\n 58703,\n 58704,\n 58705,\n 58706,\n 58707,\n 58708,\n 58709,\n 58710,\n 58711,\n 58712,\n 58713,\n 58714,\n 58715,\n 58716,\n 58717,\n 58718,\n 58719,\n 58720,\n 58721,\n 58722,\n 0,\n 58723,\n 58724,\n 58725,\n 58726,\n 58727,\n 58728,\n 58729,\n 58730,\n 58731,\n 58732,\n 58733,\n 58734,\n 58735,\n 58736,\n 58737,\n 58738,\n 58739,\n 58740,\n 58741,\n 58742,\n 58743,\n 58744,\n 58745,\n 58746,\n 58747,\n 58748,\n 58749,\n 58750,\n 58751,\n 58752,\n 58753,\n 58754,\n 58755,\n 58756,\n 58757,\n 58758,\n 58759,\n 58760,\n 58761,\n 58762,\n 58763,\n 58764,\n 58765,\n 58766,\n 58767,\n 58768,\n 58769,\n 58770,\n 58771,\n 58772,\n 58773,\n 58774,\n 58775,\n 58776,\n 58777,\n 58778,\n 58779,\n 58780,\n 58781,\n 58782,\n 58783,\n 58784,\n 58785,\n 58786,\n 58787,\n 58788,\n 58789,\n 58790,\n 58791,\n 58792,\n 58793,\n 58794,\n 58795,\n 58796,\n 58797,\n 58798,\n 58799,\n 58800,\n 58801,\n 58802,\n 58803,\n 58804,\n 58805,\n 58806,\n 58807,\n 58808,\n 58809,\n 58810,\n 58811,\n 58812,\n 58813,\n 58814,\n 58815,\n 58816,\n 58817,\n 58818,\n 58819,\n 58820,\n 58821,\n 58822,\n 58823,\n 58824,\n 58825,\n 58826,\n 58827,\n 58828,\n 58829,\n 58830,\n 58831,\n 58832,\n 58833,\n 58834,\n 58835,\n 58836,\n 58837,\n 58838,\n 58839,\n 58840,\n 58841,\n 58842,\n 58843,\n 58844,\n 58845,\n 58846,\n 58847,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 58848,\n 58849,\n 58850,\n 58851,\n 58852,\n 58853,\n 58854,\n 58855,\n 58856,\n 58857,\n 58858,\n 58859,\n 58860,\n 58861,\n 58862,\n 58863,\n 58864,\n 58865,\n 58866,\n 58867,\n 58868,\n 58869,\n 58870,\n 58871,\n 58872,\n 58873,\n 58874,\n 58875,\n 58876,\n 58877,\n 58878,\n 58879,\n 58880,\n 58881,\n 58882,\n 58883,\n 58884,\n 58885,\n 58886,\n 58887,\n 58888,\n 58889,\n 58890,\n 58891,\n 58892,\n 58893,\n 58894,\n 58895,\n 58896,\n 58897,\n 58898,\n 58899,\n 58900,\n 58901,\n 58902,\n 58903,\n 58904,\n 58905,\n 58906,\n 58907,\n 58908,\n 58909,\n 58910,\n 0,\n 58911,\n 58912,\n 58913,\n 58914,\n 58915,\n 58916,\n 58917,\n 58918,\n 58919,\n 58920,\n 58921,\n 58922,\n 58923,\n 58924,\n 58925,\n 58926,\n 58927,\n 58928,\n 58929,\n 58930,\n 58931,\n 58932,\n 58933,\n 58934,\n 58935,\n 58936,\n 58937,\n 58938,\n 58939,\n 58940,\n 58941,\n 58942,\n 58943,\n 58944,\n 58945,\n 58946,\n 58947,\n 58948,\n 58949,\n 58950,\n 58951,\n 58952,\n 58953,\n 58954,\n 58955,\n 58956,\n 58957,\n 58958,\n 58959,\n 58960,\n 58961,\n 58962,\n 58963,\n 58964,\n 58965,\n 58966,\n 58967,\n 58968,\n 58969,\n 58970,\n 58971,\n 58972,\n 58973,\n 58974,\n 58975,\n 58976,\n 58977,\n 58978,\n 58979,\n 58980,\n 58981,\n 58982,\n 58983,\n 58984,\n 58985,\n 58986,\n 58987,\n 58988,\n 58989,\n 58990,\n 58991,\n 58992,\n 58993,\n 58994,\n 58995,\n 58996,\n 58997,\n 58998,\n 58999,\n 59000,\n 59001,\n 59002,\n 59003,\n 59004,\n 59005,\n 59006,\n 59007,\n 59008,\n 59009,\n 59010,\n 59011,\n 59012,\n 59013,\n 59014,\n 59015,\n 59016,\n 59017,\n 59018,\n 59019,\n 59020,\n 59021,\n 59022,\n 59023,\n 59024,\n 59025,\n 59026,\n 59027,\n 59028,\n 59029,\n 59030,\n 59031,\n 59032,\n 59033,\n 59034,\n 59035,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 59036,\n 59037,\n 59038,\n 59039,\n 59040,\n 59041,\n 59042,\n 59043,\n 59044,\n 59045,\n 59046,\n 59047,\n 59048,\n 59049,\n 59050,\n 59051,\n 59052,\n 59053,\n 59054,\n 59055,\n 59056,\n 59057,\n 59058,\n 59059,\n 59060,\n 59061,\n 59062,\n 59063,\n 59064,\n 59065,\n 59066,\n 59067,\n 59068,\n 59069,\n 59070,\n 59071,\n 59072,\n 59073,\n 59074,\n 59075,\n 59076,\n 59077,\n 59078,\n 59079,\n 59080,\n 59081,\n 59082,\n 59083,\n 59084,\n 59085,\n 59086,\n 59087,\n 59088,\n 59089,\n 59090,\n 59091,\n 59092,\n 59093,\n 59094,\n 59095,\n 59096,\n 59097,\n 59098,\n 0,\n 59099,\n 59100,\n 59101,\n 59102,\n 59103,\n 59104,\n 59105,\n 59106,\n 59107,\n 59108,\n 59109,\n 59110,\n 59111,\n 59112,\n 59113,\n 59114,\n 59115,\n 59116,\n 59117,\n 59118,\n 59119,\n 59120,\n 59121,\n 59122,\n 59123,\n 59124,\n 59125,\n 59126,\n 59127,\n 59128,\n 59129,\n 59130,\n 59131,\n 59132,\n 59133,\n 59134,\n 59135,\n 59136,\n 59137,\n 59138,\n 59139,\n 59140,\n 59141,\n 59142,\n 59143,\n 59144,\n 59145,\n 59146,\n 59147,\n 59148,\n 59149,\n 59150,\n 59151,\n 59152,\n 59153,\n 59154,\n 59155,\n 59156,\n 59157,\n 59158,\n 59159,\n 59160,\n 59161,\n 59162,\n 59163,\n 59164,\n 59165,\n 59166,\n 59167,\n 59168,\n 59169,\n 59170,\n 59171,\n 59172,\n 59173,\n 59174,\n 59175,\n 59176,\n 59177,\n 59178,\n 59179,\n 59180,\n 59181,\n 59182,\n 59183,\n 59184,\n 59185,\n 59186,\n 59187,\n 59188,\n 59189,\n 59190,\n 59191,\n 59192,\n 59193,\n 59194,\n 59195,\n 59196,\n 59197,\n 59198,\n 59199,\n 59200,\n 59201,\n 59202,\n 59203,\n 59204,\n 59205,\n 59206,\n 59207,\n 59208,\n 59209,\n 59210,\n 59211,\n 59212,\n 59213,\n 59214,\n 59215,\n 59216,\n 59217,\n 59218,\n 59219,\n 59220,\n 59221,\n 59222,\n 59223,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 8560,\n 8561,\n 8562,\n 8563,\n 8564,\n 8565,\n 8566,\n 8567,\n 8568,\n 8569,\n 8544,\n 8545,\n 8546,\n 8547,\n 8548,\n 8549,\n 8550,\n 8551,\n 8552,\n 8553,\n 65506,\n 65508,\n 65287,\n 65282,\n 12849,\n 8470,\n 8481,\n 8757,\n 32394,\n 35100,\n 37704,\n 37512,\n 34012,\n 20425,\n 28859,\n 26161,\n 26824,\n 37625,\n 26363,\n 24389,\n 20008,\n 20193,\n 20220,\n 20224,\n 20227,\n 20281,\n 20310,\n 20370,\n 20362,\n 20378,\n 20372,\n 20429,\n 20544,\n 20514,\n 20479,\n 20510,\n 20550,\n 20592,\n 20546,\n 20628,\n 20724,\n 20696,\n 20810,\n 0,\n 20836,\n 20893,\n 20926,\n 20972,\n 21013,\n 21148,\n 21158,\n 21184,\n 21211,\n 21248,\n 21255,\n 21284,\n 21362,\n 21395,\n 21426,\n 21469,\n 64014,\n 21660,\n 21642,\n 21673,\n 21759,\n 21894,\n 22361,\n 22373,\n 22444,\n 22472,\n 22471,\n 64015,\n 64016,\n 22686,\n 22706,\n 22795,\n 22867,\n 22875,\n 22877,\n 22883,\n 22948,\n 22970,\n 23382,\n 23488,\n 29999,\n 23512,\n 23532,\n 23582,\n 23718,\n 23738,\n 23797,\n 23847,\n 23891,\n 64017,\n 23874,\n 23917,\n 23992,\n 23993,\n 24016,\n 24353,\n 24372,\n 24423,\n 24503,\n 24542,\n 24669,\n 24709,\n 24714,\n 24798,\n 24789,\n 24864,\n 24818,\n 24849,\n 24887,\n 24880,\n 24984,\n 25107,\n 25254,\n 25589,\n 25696,\n 25757,\n 25806,\n 25934,\n 26112,\n 26133,\n 26171,\n 26121,\n 26158,\n 26142,\n 26148,\n 26213,\n 26199,\n 26201,\n 64018,\n 26227,\n 26265,\n 26272,\n 26290,\n 26303,\n 26362,\n 26382,\n 63785,\n 26470,\n 26555,\n 26706,\n 26560,\n 26625,\n 26692,\n 26831,\n 64019,\n 26984,\n 64020,\n 27032,\n 27106,\n 27184,\n 27243,\n 27206,\n 27251,\n 27262,\n 27362,\n 27364,\n 27606,\n 27711,\n 27740,\n 27782,\n 27759,\n 27866,\n 27908,\n 28039,\n 28015,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 28054,\n 28076,\n 28111,\n 28152,\n 28146,\n 28156,\n 28217,\n 28252,\n 28199,\n 28220,\n 28351,\n 28552,\n 28597,\n 28661,\n 28677,\n 28679,\n 28712,\n 28805,\n 28843,\n 28943,\n 28932,\n 29020,\n 28998,\n 28999,\n 64021,\n 29121,\n 29182,\n 29361,\n 29374,\n 29476,\n 64022,\n 29559,\n 29629,\n 29641,\n 29654,\n 29667,\n 29650,\n 29703,\n 29685,\n 29734,\n 29738,\n 29737,\n 29742,\n 29794,\n 29833,\n 29855,\n 29953,\n 30063,\n 30338,\n 30364,\n 30366,\n 30363,\n 30374,\n 64023,\n 30534,\n 21167,\n 30753,\n 30798,\n 30820,\n 30842,\n 31024,\n 64024,\n 64025,\n 0,\n 64026,\n 31124,\n 64027,\n 31131,\n 31441,\n 31463,\n 64028,\n 31467,\n 31646,\n 64029,\n 32072,\n 32092,\n 32183,\n 32160,\n 32214,\n 32338,\n 32583,\n 32673,\n 64030,\n 33537,\n 33634,\n 33663,\n 33735,\n 33782,\n 33864,\n 33972,\n 34131,\n 34137,\n 34155,\n 64031,\n 34224,\n 64032,\n 64033,\n 34823,\n 35061,\n 35346,\n 35383,\n 35449,\n 35495,\n 35518,\n 35551,\n 64034,\n 35574,\n 35667,\n 35711,\n 36080,\n 36084,\n 36114,\n 36214,\n 64035,\n 36559,\n 64036,\n 64037,\n 36967,\n 37086,\n 64038,\n 37141,\n 37159,\n 37338,\n 37335,\n 37342,\n 37357,\n 37358,\n 37348,\n 37349,\n 37382,\n 37392,\n 37386,\n 37434,\n 37440,\n 37436,\n 37454,\n 37465,\n 37457,\n 37433,\n 37479,\n 37543,\n 37495,\n 37496,\n 37607,\n 37591,\n 37593,\n 37584,\n 64039,\n 37589,\n 37600,\n 37587,\n 37669,\n 37665,\n 37627,\n 64040,\n 37662,\n 37631,\n 37661,\n 37634,\n 37744,\n 37719,\n 37796,\n 37830,\n 37854,\n 37880,\n 37937,\n 37957,\n 37960,\n 38290,\n 63964,\n 64041,\n 38557,\n 38575,\n 38707,\n 38715,\n 38723,\n 38733,\n 38735,\n 38737,\n 38741,\n 38999,\n 39013,\n 64042,\n 64043,\n 39207,\n 64044,\n 39326,\n 39502,\n 39641,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 39644,\n 39797,\n 39794,\n 39823,\n 39857,\n 39867,\n 39936,\n 40304,\n 40299,\n 64045,\n 40473,\n 40657,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0};\n\n int sjis_mbtowc(unsigned short *wc, const unsigned char *s)\n {\n\t unsigned short unichar = jis2uni_low[*s];\n\t if (unichar == 0xffff) {\n\t\t // double byte\n\t\t unsigned int idx = (s[0] << 8) | (s[1]);\n\t\t unichar = jis2uni_high[idx - 0x8000];\n\t\t if (unichar) {\n\t\t\t *wc = unichar;\n\t\t\t return 2;\n\t\t }\n\t } else if (unichar) {\n\t\t *wc = unichar;\n\t\t return 1;\n\t }\n\t return -1;\n }"
  },
  {
    "path": "src/core/utils/iconv/iconv.h",
    "content": "#pragma once\n\ntypedef unsigned long ucs4_t;\ntypedef struct _conv_t{\n    unsigned int istate;\n    unsigned int ostate;\n} *conv_t;\n/* Return code if invalid. (xxx_wctomb) */\n#define RET_ILUNI      -1\n/* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */\n#define RET_TOOSMALL   -2\n/* Return code if invalid input after a shift sequence of n bytes was read.\n   (xxx_mbtowc) */\n#define RET_SHIFT_ILSEQ(n)  (-1-2*(n))\n/* Return code if invalid. (xxx_mbtowc) */\n#define RET_ILSEQ           RET_SHIFT_ILSEQ(0)\n/* Return code if only a shift sequence of n bytes was read. (xxx_mbtowc) */\n#define RET_TOOFEW(n)       (-2-2*(n))\n/* Retrieve the n from the encoded RET_... value. */\n#define DECODE_SHIFT_ILSEQ(r)  ((unsigned int)(RET_SHIFT_ILSEQ(0) - (r)) / 2)\n#define DECODE_TOOFEW(r)       ((unsigned int)(RET_TOOFEW(0) - (r)) / 2)\n"
  },
  {
    "path": "src/core/utils/iconv/utf8.h",
    "content": "/*\n * Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc.\n * This file is part of the GNU LIBICONV Library.\n *\n * The GNU LIBICONV Library is free software; you can redistribute it\n * and/or modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either version 2\n * of the License, or (at your option) any later version.\n *\n * The GNU LIBICONV Library is distributed in the hope that it will be\n * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with the GNU LIBICONV Library; see the file COPYING.LIB.\n * If not, write to the Free Software Foundation, Inc., 51 Franklin Street,\n * Fifth Floor, Boston, MA 02110-1301, USA.\n */\n\n/*\n * UTF-8\n */\n\n/* Specification: RFC 3629 */\n\nstatic int\nutf8_mbtowc (/*conv_t conv,*/ ucs4_t *pwc, const unsigned char *s, int n)\n{\n  unsigned char c = s[0];\n\n  if (c < 0x80) {\n    *pwc = c;\n    return 1;\n  } else if (c < 0xc2) {\n    return RET_ILSEQ;\n  } else if (c < 0xe0) {\n    if (n < 2)\n      return RET_TOOFEW(0);\n    if (!((s[1] ^ 0x80) < 0x40))\n      return RET_ILSEQ;\n    *pwc = ((ucs4_t) (c & 0x1f) << 6)\n           | (ucs4_t) (s[1] ^ 0x80);\n    return 2;\n  } else if (c < 0xf0) {\n    if (n < 3)\n      return RET_TOOFEW(0);\n    if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n          && (c >= 0xe1 || s[1] >= 0xa0)))\n      return RET_ILSEQ;\n    *pwc = ((ucs4_t) (c & 0x0f) << 12)\n           | ((ucs4_t) (s[1] ^ 0x80) << 6)\n           | (ucs4_t) (s[2] ^ 0x80);\n    return 3;\n  } else if (c < 0xf8 && sizeof(ucs4_t)*8 >= 32) {\n    if (n < 4)\n      return RET_TOOFEW(0);\n    if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n          && (s[3] ^ 0x80) < 0x40\n          && (c >= 0xf1 || s[1] >= 0x90)))\n      return RET_ILSEQ;\n    *pwc = ((ucs4_t) (c & 0x07) << 18)\n           | ((ucs4_t) (s[1] ^ 0x80) << 12)\n           | ((ucs4_t) (s[2] ^ 0x80) << 6)\n           | (ucs4_t) (s[3] ^ 0x80);\n    return 4;\n  } else if (c < 0xfc && sizeof(ucs4_t)*8 >= 32) {\n    if (n < 5)\n      return RET_TOOFEW(0);\n    if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n          && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40\n          && (c >= 0xf9 || s[1] >= 0x88)))\n      return RET_ILSEQ;\n    *pwc = ((ucs4_t) (c & 0x03) << 24)\n           | ((ucs4_t) (s[1] ^ 0x80) << 18)\n           | ((ucs4_t) (s[2] ^ 0x80) << 12)\n           | ((ucs4_t) (s[3] ^ 0x80) << 6)\n           | (ucs4_t) (s[4] ^ 0x80);\n    return 5;\n  } else if (c < 0xfe && sizeof(ucs4_t)*8 >= 32) {\n    if (n < 6)\n      return RET_TOOFEW(0);\n    if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40\n          && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40\n          && (s[5] ^ 0x80) < 0x40\n          && (c >= 0xfd || s[1] >= 0x84)))\n      return RET_ILSEQ;\n    *pwc = ((ucs4_t) (c & 0x01) << 30)\n           | ((ucs4_t) (s[1] ^ 0x80) << 24)\n           | ((ucs4_t) (s[2] ^ 0x80) << 18)\n           | ((ucs4_t) (s[3] ^ 0x80) << 12)\n           | ((ucs4_t) (s[4] ^ 0x80) << 6)\n           | (ucs4_t) (s[5] ^ 0x80);\n    return 6;\n  } else\n    return RET_ILSEQ;\n}\n\nstatic int\nutf8_wctomb (/*conv_t conv,*/ unsigned char *r, ucs4_t wc, int n) /* n == 0 is acceptable */\n{\n  int count;\n  if (wc < 0x80)\n    count = 1;\n  else if (wc < 0x800)\n    count = 2;\n  else if (wc < 0x10000)\n    count = 3;\n  else if (wc < 0x200000)\n    count = 4;\n  else if (wc < 0x4000000)\n    count = 5;\n  else if (wc <= 0x7fffffff)\n    count = 6;\n  else\n    return RET_ILUNI;\n  if (n < count)\n    return RET_TOOSMALL;\n  switch (count) { /* note: code falls through cases! */\n    case 6: r[5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000;\n    case 5: r[4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000;\n    case 4: r[3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000;\n    case 3: r[2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800;\n    case 2: r[1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0;\n    case 1: r[0] = wc;\n  }\n  return count;\n}\n"
  },
  {
    "path": "src/core/utils/md5.c",
    "content": "/*\n  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  L. Peter Deutsch\n  ghost@aladdin.com\n\n */\n/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */\n/*\n  Independent implementation of MD5 (RFC 1321).\n\n  This code implements the MD5 Algorithm defined in RFC 1321, whose\n  text is available at\n\thttp://www.ietf.org/rfc/rfc1321.txt\n  The code is derived from the text of the RFC, including the test suite\n  (section A.5) but excluding the rest of Appendix A.  It does not include\n  any code or documentation that is identified in the RFC as being\n  copyrighted.\n\n  The original and principal author of md5.c is L. Peter Deutsch\n  <ghost@aladdin.com>.  Other authors are noted in the change history\n  that follows (in reverse chronological order):\n\n  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order\n\teither statically or dynamically; added missing #include <string.h>\n\tin library.\n  2002-03-11 lpd Corrected argument list for main(), and added int return\n\ttype, in test program and T value program.\n  2002-02-21 lpd Added missing #include <stdio.h> in test program.\n  2000-07-03 lpd Patched to eliminate warnings about \"constant is\n\tunsigned in ANSI C, signed in traditional\"; made test program\n\tself-checking.\n  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.\n  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).\n  1999-05-03 lpd Original version.\n */\n\n#ifdef _M_IX86\n #undef ARCH_IS_BIG_ENDIAN\n #define ARCH_IS_BIG_ENDIAN 0\n#endif\n\n\n#include \"md5.h\"\n#include <string.h>\n\n#undef BYTE_ORDER\t/* 1 = big-endian, -1 = little-endian, 0 = unknown */\n#ifdef ARCH_IS_BIG_ENDIAN\n#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)\n#else\n#  define BYTE_ORDER 0\n#endif\n\n#define T_MASK ((md5_word_t)~0)\n#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)\n#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)\n#define T3    0x242070db\n#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)\n#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)\n#define T6    0x4787c62a\n#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)\n#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)\n#define T9    0x698098d8\n#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)\n#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)\n#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)\n#define T13    0x6b901122\n#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)\n#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)\n#define T16    0x49b40821\n#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)\n#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)\n#define T19    0x265e5a51\n#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)\n#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)\n#define T22    0x02441453\n#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)\n#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)\n#define T25    0x21e1cde6\n#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)\n#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)\n#define T28    0x455a14ed\n#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)\n#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)\n#define T31    0x676f02d9\n#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)\n#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)\n#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)\n#define T35    0x6d9d6122\n#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)\n#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)\n#define T38    0x4bdecfa9\n#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)\n#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)\n#define T41    0x289b7ec6\n#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)\n#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)\n#define T44    0x04881d05\n#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)\n#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)\n#define T47    0x1fa27cf8\n#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)\n#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)\n#define T50    0x432aff97\n#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)\n#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)\n#define T53    0x655b59c3\n#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)\n#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)\n#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)\n#define T57    0x6fa87e4f\n#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)\n#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)\n#define T60    0x4e0811a1\n#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)\n#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)\n#define T63    0x2ad7d2bb\n#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)\n\n\nstatic void\nmd5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)\n{\n    md5_word_t\n\ta = pms->abcd[0], b = pms->abcd[1],\n\tc = pms->abcd[2], d = pms->abcd[3];\n    md5_word_t t;\n#if BYTE_ORDER > 0\n    /* Define storage only for big-endian CPUs. */\n    md5_word_t X[16];\n#else\n    /* Define storage for little-endian or both types of CPUs. */\n    md5_word_t xbuf[16];\n    const md5_word_t *X;\n#endif\n\n    {\n#if BYTE_ORDER == 0\n\t/*\n\t * Determine dynamically whether this is a big-endian or\n\t * little-endian machine, since we can use a more efficient\n\t * algorithm on the latter.\n\t */\n\tstatic const int w = 1;\n\n\tif (*((const md5_byte_t *)&w)) /* dynamic little-endian */\n#endif\n#if BYTE_ORDER <= 0\t\t/* little-endian */\n\t{\n\t    /*\n\t     * On little-endian machines, we can process properly aligned\n\t     * data without copying it.\n\t     */\n\t    if (!((data - (const md5_byte_t *)0) & 3)) {\n\t\t/* data are properly aligned */\n\t\tX = (const md5_word_t *)data;\n\t    } else {\n\t\t/* not aligned */\n\t\tmemcpy(xbuf, data, 64);\n\t\tX = xbuf;\n\t    }\n\t}\n#endif\n#if BYTE_ORDER == 0\n\telse\t\t\t/* dynamic big-endian */\n#endif\n#if BYTE_ORDER >= 0\t\t/* big-endian */\n\t{\n\t    /*\n\t     * On big-endian machines, we must arrange the bytes in the\n\t     * right order.\n\t     */\n\t    const md5_byte_t *xp = data;\n\t    int i;\n\n#  if BYTE_ORDER == 0\n\t    X = xbuf;\t\t/* (dynamic only) */\n#  else\n#    define xbuf X\t\t/* (static only) */\n#  endif\n\t    for (i = 0; i < 16; ++i, xp += 4)\n\t\txbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);\n\t}\n#endif\n    }\n\n#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))\n\n    /* Round 1. */\n    /* Let [abcd k s i] denote the operation\n       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */\n#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + F(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n    /* Do the following 16 operations. */\n    SET(a, b, c, d,  0,  7,  T1);\n    SET(d, a, b, c,  1, 12,  T2);\n    SET(c, d, a, b,  2, 17,  T3);\n    SET(b, c, d, a,  3, 22,  T4);\n    SET(a, b, c, d,  4,  7,  T5);\n    SET(d, a, b, c,  5, 12,  T6);\n    SET(c, d, a, b,  6, 17,  T7);\n    SET(b, c, d, a,  7, 22,  T8);\n    SET(a, b, c, d,  8,  7,  T9);\n    SET(d, a, b, c,  9, 12, T10);\n    SET(c, d, a, b, 10, 17, T11);\n    SET(b, c, d, a, 11, 22, T12);\n    SET(a, b, c, d, 12,  7, T13);\n    SET(d, a, b, c, 13, 12, T14);\n    SET(c, d, a, b, 14, 17, T15);\n    SET(b, c, d, a, 15, 22, T16);\n#undef SET\n\n     /* Round 2. */\n     /* Let [abcd k s i] denote the operation\n          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */\n#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + G(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  1,  5, T17);\n    SET(d, a, b, c,  6,  9, T18);\n    SET(c, d, a, b, 11, 14, T19);\n    SET(b, c, d, a,  0, 20, T20);\n    SET(a, b, c, d,  5,  5, T21);\n    SET(d, a, b, c, 10,  9, T22);\n    SET(c, d, a, b, 15, 14, T23);\n    SET(b, c, d, a,  4, 20, T24);\n    SET(a, b, c, d,  9,  5, T25);\n    SET(d, a, b, c, 14,  9, T26);\n    SET(c, d, a, b,  3, 14, T27);\n    SET(b, c, d, a,  8, 20, T28);\n    SET(a, b, c, d, 13,  5, T29);\n    SET(d, a, b, c,  2,  9, T30);\n    SET(c, d, a, b,  7, 14, T31);\n    SET(b, c, d, a, 12, 20, T32);\n#undef SET\n\n     /* Round 3. */\n     /* Let [abcd k s t] denote the operation\n          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */\n#define H(x, y, z) ((x) ^ (y) ^ (z))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + H(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  5,  4, T33);\n    SET(d, a, b, c,  8, 11, T34);\n    SET(c, d, a, b, 11, 16, T35);\n    SET(b, c, d, a, 14, 23, T36);\n    SET(a, b, c, d,  1,  4, T37);\n    SET(d, a, b, c,  4, 11, T38);\n    SET(c, d, a, b,  7, 16, T39);\n    SET(b, c, d, a, 10, 23, T40);\n    SET(a, b, c, d, 13,  4, T41);\n    SET(d, a, b, c,  0, 11, T42);\n    SET(c, d, a, b,  3, 16, T43);\n    SET(b, c, d, a,  6, 23, T44);\n    SET(a, b, c, d,  9,  4, T45);\n    SET(d, a, b, c, 12, 11, T46);\n    SET(c, d, a, b, 15, 16, T47);\n    SET(b, c, d, a,  2, 23, T48);\n#undef SET\n\n     /* Round 4. */\n     /* Let [abcd k s t] denote the operation\n          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */\n#define I(x, y, z) ((y) ^ ((x) | ~(z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + I(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  0,  6, T49);\n    SET(d, a, b, c,  7, 10, T50);\n    SET(c, d, a, b, 14, 15, T51);\n    SET(b, c, d, a,  5, 21, T52);\n    SET(a, b, c, d, 12,  6, T53);\n    SET(d, a, b, c,  3, 10, T54);\n    SET(c, d, a, b, 10, 15, T55);\n    SET(b, c, d, a,  1, 21, T56);\n    SET(a, b, c, d,  8,  6, T57);\n    SET(d, a, b, c, 15, 10, T58);\n    SET(c, d, a, b,  6, 15, T59);\n    SET(b, c, d, a, 13, 21, T60);\n    SET(a, b, c, d,  4,  6, T61);\n    SET(d, a, b, c, 11, 10, T62);\n    SET(c, d, a, b,  2, 15, T63);\n    SET(b, c, d, a,  9, 21, T64);\n#undef SET\n\n     /* Then perform the following additions. (That is increment each\n        of the four registers by the value it had before this block\n        was started.) */\n    pms->abcd[0] += a;\n    pms->abcd[1] += b;\n    pms->abcd[2] += c;\n    pms->abcd[3] += d;\n}\n\nvoid\nmd5_init(md5_state_t *pms)\n{\n    pms->count[0] = pms->count[1] = 0;\n    pms->abcd[0] = 0x67452301;\n    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;\n    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;\n    pms->abcd[3] = 0x10325476;\n}\n\nvoid\nmd5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)\n{\n    const md5_byte_t *p = data;\n    int left = nbytes;\n    int offset = (pms->count[0] >> 3) & 63;\n    md5_word_t nbits = (md5_word_t)(nbytes << 3);\n\n    if (nbytes <= 0)\n\treturn;\n\n    /* Update the message length. */\n    pms->count[1] += nbytes >> 29;\n    pms->count[0] += nbits;\n    if (pms->count[0] < nbits)\n\tpms->count[1]++;\n\n    /* Process an initial partial block. */\n    if (offset) {\n\tint copy = (offset + nbytes > 64 ? 64 - offset : nbytes);\n\n\tmemcpy(pms->buf + offset, p, copy);\n\tif (offset + copy < 64)\n\t    return;\n\tp += copy;\n\tleft -= copy;\n\tmd5_process(pms, pms->buf);\n    }\n\n    /* Process full blocks. */\n    for (; left >= 64; p += 64, left -= 64)\n\tmd5_process(pms, p);\n\n    /* Process a final partial block. */\n    if (left)\n\tmemcpy(pms->buf, p, left);\n}\n\nvoid\nmd5_finish(md5_state_t *pms, md5_byte_t digest[16])\n{\n    static const md5_byte_t pad[64] = {\n\t0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n    };\n    md5_byte_t data[8];\n    int i;\n\n    /* Save the length before padding. */\n    for (i = 0; i < 8; ++i)\n\tdata[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));\n    /* Pad to 56 bytes mod 64. */\n    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);\n    /* Append the length. */\n    md5_append(pms, data, 8);\n    for (i = 0; i < 16; ++i)\n\tdigest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));\n}\n"
  },
  {
    "path": "src/core/utils/md5.h",
    "content": "/*\n  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  L. Peter Deutsch\n  ghost@aladdin.com\n\n */\n/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */\n/*\n  Independent implementation of MD5 (RFC 1321).\n\n  This code implements the MD5 Algorithm defined in RFC 1321, whose\n  text is available at\n\thttp://www.ietf.org/rfc/rfc1321.txt\n  The code is derived from the text of the RFC, including the test suite\n  (section A.5) but excluding the rest of Appendix A.  It does not include\n  any code or documentation that is identified in the RFC as being\n  copyrighted.\n\n  The original and principal author of md5.h is L. Peter Deutsch\n  <ghost@aladdin.com>.  Other authors are noted in the change history\n  that follows (in reverse chronological order):\n\n  2002-04-13 lpd Removed support for non-ANSI compilers; removed\n\treferences to Ghostscript; clarified derivation from RFC 1321;\n\tnow handles byte order either statically or dynamically.\n  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.\n  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);\n\tadded conditionalization for C++ compilation from Martin\n\tPurschke <purschke@bnl.gov>.\n  1999-05-03 lpd Original version.\n */\n\n#ifndef md5_INCLUDED\n#  define md5_INCLUDED\n\n/*\n * This package supports both compile-time and run-time determination of CPU\n * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be\n * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is\n * defined as non-zero, the code will be compiled to run only on big-endian\n * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to\n * run on either big- or little-endian CPUs, but will run slightly less\n * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.\n */\n\ntypedef unsigned char md5_byte_t; /* 8-bit byte */\ntypedef unsigned int md5_word_t; /* 32-bit word */\n\n/* Define the state of the MD5 Algorithm. */\ntypedef struct md5_state_s {\n    md5_word_t count[2];\t/* message length in bits, lsw first */\n    md5_word_t abcd[4];\t\t/* digest buffer */\n    md5_byte_t buf[64];\t\t/* accumulate block */\n} md5_state_t;\n\n#ifdef __cplusplus\nextern \"C\" \n{\n#endif\n\n/* Initialize the algorithm. */\nvoid md5_init(md5_state_t *pms);\n\n/* Append a string to the message. */\nvoid md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);\n\n/* Finish the message and return the digest. */\nvoid md5_finish(md5_state_t *pms, md5_byte_t digest[16]);\n\n#ifdef __cplusplus\n}  /* end extern \"C\" */\n#endif\n\n#endif /* md5_INCLUDED */\n"
  },
  {
    "path": "src/core/utils/minizip/crypt.h",
    "content": "/* crypt.h -- base code for crypt/uncrypt ZIPfile\n\n\n   Version 1.01e, February 12th, 2005\n\n   Copyright (C) 1998-2005 Gilles Vollant\n\n   This code is a modified version of crypting code in Infozip distribution\n\n   The encryption/decryption parts of this source code (as opposed to the\n   non-echoing password parts) were originally written in Europe.  The\n   whole source package can be freely distributed, including from the USA.\n   (Prior to January 2000, re-export from the US was a violation of US law.)\n\n   This encryption code is a direct transcription of the algorithm from\n   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This\n   file (appnote.txt) is distributed with the PKZIP program (even in the\n   version without encryption capabilities).\n\n   If you don't need crypting in your application, just define symbols\n   NOCRYPT and NOUNCRYPT.\n\n   This code support the \"Traditional PKWARE Encryption\".\n\n   The new AES encryption added on Zip format by Winzip (see the page\n   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong\n   Encryption is not supported.\n*/\n\n#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))\n\n/***********************************************************************\n * Return the next byte in the pseudo-random sequence\n */\nstatic int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)\n{\n    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an\n                     * unpredictable manner on 16-bit systems; not a problem\n                     * with any known compiler so far, though */\n\n    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;\n    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);\n}\n\n/***********************************************************************\n * Update the encryption keys with the next byte of plain text\n */\nstatic int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)\n{\n    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);\n    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;\n    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;\n    {\n      int keyshift = (int)((*(pkeys+1)) >> 24);\n      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);\n    }\n    return c;\n}\n\n\n/***********************************************************************\n * Initialize the encryption keys and the random header according to\n * the given password.\n */\nstatic void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)\n{\n    *(pkeys+0) = 305419896L;\n    *(pkeys+1) = 591751049L;\n    *(pkeys+2) = 878082192L;\n    while (*passwd != '\\0') {\n        update_keys(pkeys,pcrc_32_tab,(int)*passwd);\n        passwd++;\n    }\n}\n\n#define zdecode(pkeys,pcrc_32_tab,c) \\\n    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))\n\n#define zencode(pkeys,pcrc_32_tab,c,t) \\\n    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))\n\n#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n\n#define RAND_HEAD_LEN  12\n   /* \"last resort\" source for second part of crypt seed pattern */\n#  ifndef ZCR_SEED2\n#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */\n#  endif\n\nstatic int crypthead(const char* passwd,      /* password string */\n                     unsigned char* buf,      /* where to write header */\n                     int bufSize,\n                     unsigned long* pkeys,\n                     const unsigned long* pcrc_32_tab,\n                     unsigned long crcForCrypting)\n{\n    int n;                       /* index in random header */\n    int t;                       /* temporary */\n    int c;                       /* random byte */\n    unsigned char header[RAND_HEAD_LEN-2]; /* random header */\n    static unsigned calls = 0;   /* ensure different random header each time */\n\n    if (bufSize<RAND_HEAD_LEN)\n      return 0;\n\n    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the\n     * output of rand() to get less predictability, since rand() is\n     * often poorly implemented.\n     */\n    if (++calls == 1)\n    {\n        srand((unsigned)(time(NULL) ^ ZCR_SEED2));\n    }\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        c = (rand() >> 7) & 0xff;\n        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);\n    }\n    /* Encrypt random header (last two bytes is high word of crc) */\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);\n    }\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);\n    return n;\n}\n\n#endif\n"
  },
  {
    "path": "src/core/utils/minizip/ioapi.cpp",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n*/\n\n#include \"ioapi.h\"\n#include <unistd.h>\n\n#ifdef WIN32\n#define _POSIX_\n#include <direct.h>\n#endif\n#include <fcntl.h>\n#include <stdint.h>\n#include \"win32io.h\"\n\n// namespace cocos2d {\n\nvoidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)\n{\n    if (pfilefunc->zfile_func64.zopen64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);\n    else\n    {\n        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);\n    }\n}\n\nlong call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)\n{\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);\n    else\n    {\n        uLong offsetTruncated = (uLong)offset;\n        if (offsetTruncated != offset)\n            return -1;\n        else\n            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);\n    }\n}\n\nZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)\n{\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);\n    else\n    {\n        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);\n        if ((tell_uLong) == ((uLong)-1))\n            return (ZPOS64_T)-1;\n        else\n            return tell_uLong;\n    }\n}\n\nvoid fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)\n{\n    p_filefunc64_32->zfile_func64.zopen64_file = NULL;\n    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;\n    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;\n    p_filefunc64_32->zfile_func64.ztell64_file = NULL;\n    p_filefunc64_32->zfile_func64.zseek64_file = NULL;\n    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;\n    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;\n    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;\n}\n\n\n\nstatic voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));\nstatic uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));\nstatic uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));\nstatic ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));\nstatic long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\nstatic int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));\nstatic int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));\n\nstatic voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)\n{\n    unsigned int rw = 0;\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)\n        rw |= O_RDONLY;\n    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n        rw |= O_RDWR;\n    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n        rw |= O_RDWR | O_CREAT | O_TRUNC;\n\n    int Handle;\n    Handle = open(filename, rw);\n\n    return (voidpf)Handle;\n}\n\nstatic voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)\n{\n    return fopen_file_func(opaque, (const char*)filename, mode);\n}\n\n\nstatic uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)\n{\n    return (uLong)read((int64_t)stream, buf, size);\n}\n\nstatic uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)\n{\n    return (uLong)write((int64_t)stream, buf, size);\n}\n\nstatic ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)\n{\n    return (ZPOS64_T)lseek64((int64_t)stream, 0, SEEK_CUR);\n}\n\nstatic long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)\n{\n    return (long)ftell64_file_func(opaque, stream);\n}\n\nstatic long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)\n{\n    int fseek_origin=0;\n    long ret;\n    switch (origin)\n    {\n    case ZLIB_FILEFUNC_SEEK_CUR :\n        fseek_origin = SEEK_CUR;\n        break;\n    case ZLIB_FILEFUNC_SEEK_END :\n        fseek_origin = SEEK_END;\n        break;\n    case ZLIB_FILEFUNC_SEEK_SET :\n        fseek_origin = SEEK_SET;\n        break;\n    default: return -1;\n    }\n    ret = 0;\n\tlseek64((int64_t)stream, offset, fseek_origin);\n    return ret;\n}\n\nstatic long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)\n{\n    int fseek_origin=0;\n    switch (origin)\n    {\n    case ZLIB_FILEFUNC_SEEK_CUR :\n        fseek_origin = SEEK_CUR;\n        break;\n    case ZLIB_FILEFUNC_SEEK_END :\n        fseek_origin = SEEK_END;\n        break;\n    case ZLIB_FILEFUNC_SEEK_SET :\n        fseek_origin = SEEK_SET;\n        break;\n    default: return -1;\n    }\n\tlseek64((int64_t)stream, offset, fseek_origin);\n    return 0;\n}\n\n\nstatic int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)\n{\n    int ret;\n    ret = close((int64_t)stream);\n    return ret;\n}\n\nstatic int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)\n{\n    return 0;\n}\n\nvoid fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def) \n{\n    pzlib_filefunc_def->zopen_file = fopen_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell_file = ftell_file_func;\n    pzlib_filefunc_def->zseek_file = fseek_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\nzlib_filefunc64_def TVPZlibFileFunc;\nvoid fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = fopen64_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell64_file = ftell64_file_func;\n    pzlib_filefunc_def->zseek64_file = fseek64_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\nclass _TVPInitZlibFileFunc {\npublic:\n\t_TVPInitZlibFileFunc() {\n\t\tfill_fopen64_filefunc(&TVPZlibFileFunc);\n\t}\n} __TVPInitZlibFileFunc;\n\n//} // end of namespace cocos2d\n"
  },
  {
    "path": "src/core/utils/minizip/ioapi.h",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         Changes\n\n    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)\n    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.\n               More if/def section may be needed to support other platforms\n    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.\n                          (but you should use iowin32.c for windows instead)\n\n*/\n\n#ifndef _ZLIBIOAPI64_H\n#define _ZLIBIOAPI64_H\n\n//#include \"platform/CCPlatformConfig.h\"\n\n#if (!defined(_WIN32)) && (!defined(WIN32))\n\n  // Linux needs this to support file operation on files larger then 4+GB\n  // But might need better if/def to select just the platforms that needs them.\n\n        #ifndef __USE_FILE_OFFSET64\n                #define __USE_FILE_OFFSET64\n        #endif\n        #ifndef __USE_LARGEFILE64\n                #define __USE_LARGEFILE64\n        #endif\n        #ifndef _LARGEFILE64_SOURCE\n                #define _LARGEFILE64_SOURCE\n        #endif\n        #ifndef _FILE_OFFSET_BIT\n                #define _FILE_OFFSET_BIT 64\n        #endif\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"zlib.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(USE_FILE32API)\n#define fopen64 fopen\n#define ftello64 ftell\n#define fseeko64 fseek\n#else\n#ifdef _MSC_VER\n #define fopen64 fopen\n #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))\n  #define ftello64 _ftelli64\n  #define fseeko64 _fseeki64\n #else // old MSC\n  #define ftello64 ftell\n  #define fseeko64 fseek\n #endif\n#endif\n#endif\n\n/*\n#ifndef ZPOS64_T\n  #ifdef _WIN32\n                #define ZPOS64_T fpos_t\n  #else\n    #include <stdint.h>\n    #define ZPOS64_T uint64_t\n  #endif\n#endif\n*/\n\n#ifdef HAVE_MINIZIP64_CONF_H\n#include \"mz64conf.h\"\n#endif\n\n/* a type chosen by DEFINE */\n#ifdef HAVE_64BIT_INT_CUSTOM\ntypedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;\n#else\n#ifdef HAS_STDINT_H\n#include \"stdint.h\"\ntypedef uint64_t ZPOS64_T;\n#else\n\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\ntypedef unsigned __int64 ZPOS64_T;\n#else\ntypedef unsigned long long int ZPOS64_T;\n#endif\n#endif\n#endif\n\n\n\n#define ZLIB_FILEFUNC_SEEK_CUR (1)\n#define ZLIB_FILEFUNC_SEEK_END (2)\n#define ZLIB_FILEFUNC_SEEK_SET (0)\n\n#define ZLIB_FILEFUNC_MODE_READ      (1)\n#define ZLIB_FILEFUNC_MODE_WRITE     (2)\n#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)\n\n#define ZLIB_FILEFUNC_MODE_EXISTING (4)\n#define ZLIB_FILEFUNC_MODE_CREATE   (8)\n\n\n#ifndef ZCALLBACK\n #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)\n   #define ZCALLBACK CALLBACK\n #else\n   #define ZCALLBACK\n #endif\n#endif\n\n\n\n\ntypedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));\ntypedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));\ntypedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));\ntypedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));\ntypedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));\n\ntypedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));\n\n\n/* here is the \"old\" 32 bits structure structure */\ntypedef struct zlib_filefunc_def_s\n{\n    open_file_func      zopen_file;\n    read_file_func      zread_file;\n    write_file_func     zwrite_file;\n    tell_file_func      ztell_file;\n    seek_file_func      zseek_file;\n    close_file_func     zclose_file;\n    testerror_file_func zerror_file;\n    voidpf              opaque;\n} zlib_filefunc_def;\n\ntypedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\ntypedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));\n\ntypedef struct zlib_filefunc64_def_s\n{\n    open64_file_func    zopen64_file;\n    read_file_func      zread_file;\n    write_file_func     zwrite_file;\n    tell64_file_func    ztell64_file;\n    seek64_file_func    zseek64_file;\n    close_file_func     zclose_file;\n    testerror_file_func zerror_file;\n    voidpf              opaque;\n} zlib_filefunc64_def;\n\nvoid fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));\nvoid fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));\n\n/* now internal definition, only for zip.c and unzip.h */\ntypedef struct zlib_filefunc64_32_def_s\n{\n    zlib_filefunc64_def zfile_func64;\n    open_file_func      zopen32_file;\n    tell_file_func      ztell32_file;\n    seek_file_func      zseek32_file;\n} zlib_filefunc64_32_def;\n\n\n#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))\n#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))\n//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))\n//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))\n#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))\n#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))\n\nvoidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));\nlong    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));\nZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));\n\nvoid    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);\n\n#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))\n#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))\n#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/core/utils/minizip/unzip.c",
    "content": "/* unzip.c -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n\n  ------------------------------------------------------------------------------------\n  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of\n  compatibility with older software. The following is from the original crypt.c.\n  Code woven in by Terry Thorsen 1/2003.\n\n  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.\n\n  See the accompanying file LICENSE, version 2000-Apr-09 or later\n  (the contents of which are also included in zip.h) for terms of use.\n  If, for some reason, all these files are missing, the Info-ZIP license\n  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html\n\n        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]\n\n  The encryption/decryption parts of this source code (as opposed to the\n  non-echoing password parts) were originally written in Europe.  The\n  whole source package can be freely distributed, including from the USA.\n  (Prior to January 2000, re-export from the US was a violation of US law.)\n\n        This encryption code is a direct transcription of the algorithm from\n  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This\n  file (appnote.txt) is distributed with the PKZIP program (even in the\n  version without encryption capabilities).\n\n        ------------------------------------------------------------------------------------\n\n        Changes in unzip.c\n\n        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos\n  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*\n  2007-2008 - Even Rouault - Remove old C style function prototypes\n  2007-2008 - Even Rouault - Add unzip support for ZIP64\n\n        Copyright (C) 2007-2008 Even Rouault\n\n\n        Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).\n  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G\n                                should only read the compressed/uncompressed size from the Zip64 format if\n                                the size from normal header was 0xFFFFFFFF\n  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant\n        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)\n                                Patch created by Daniel Borca\n\n  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer\n\n  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson\n\n*/\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifndef NOUNCRYPT\n        #define NOUNCRYPT\n#endif\n\n#include \"zlib.h\"\n#include \"unzip.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\n    extern int errno;\n#else\n#   include <errno.h>\n#endif\n\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n\n#ifndef CASESENSITIVITYDEFAULT_NO\n#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)\n#    define CASESENSITIVITYDEFAULT_NO\n#  endif\n#endif\n\n\n#ifndef UNZ_BUFSIZE\n#define UNZ_BUFSIZE (16384)\n#endif\n\n#ifndef UNZ_MAXFILENAMEINZIP\n#define UNZ_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n# define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n# define TRYFREE(p) {if (p) free(p);}\n#endif\n\n#define SIZECENTRALDIRITEM (0x2e)\n#define SIZEZIPLOCALHEADER (0x1e)\n\n\nconst char unz_copyright[] =\n   \" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n/* unz_file_info_interntal contain internal info about a file in zipfile*/\ntypedef struct unz_file_info64_internal_s\n{\n    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */\n} unz_file_info64_internal;\n\n\n/* file_in_zip_read_info_s contain internal information about a file in zipfile,\n    when reading and decompress it */\ntypedef struct\n{\n    char  *read_buffer;         /* internal buffer for compressed data */\n    z_stream stream;            /* zLib stream structure for inflate */\n\n#ifdef HAVE_BZIP2\n    bz_stream bstream;          /* bzLib stream structure for bziped */\n#endif\n\n    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/\n    uLong stream_initialised;   /* flag set if stream structure is initialised*/\n\n    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */\n    uInt  size_local_extrafield;/* size of the local extra field */\n    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/\n    ZPOS64_T total_out_64;\n\n    uLong crc32;                /* crc32 of all data uncompressed */\n    uLong crc32_wait;           /* crc32 we must obtain after decompress all */\n    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */\n    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;        /* io structore of the zipfile */\n    uLong compression_method;   /* compression method (0==store) */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    int   raw;\n\n    int encrypted;\n#ifndef NOUNCRYPT\n    unsigned long keys[3];     /* keys defining the pseudo-random sequence */\n    const unsigned long* pcrc_32_tab;\n#endif\n\n} file_in_zip64_read_info_s;\n\n\n/* unz64_s contain internal information about the zipfile\n*/\ntypedef struct\n{\n    zlib_filefunc64_32_def z_filefunc;\n    int is64bitOpenFunction;\n    voidpf filestream;        /* io structore of the zipfile */\n    unz_global_info64 gi;       /* public global information */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    ZPOS64_T num_file;             /* number of the current file in the zipfile*/\n    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/\n    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/\n    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/\n\n    ZPOS64_T size_central_dir;     /* size of the central directory  */\n    ZPOS64_T offset_central_dir;   /* offset of start of central directory with\n                                   respect to the starting disk number */\n\n    unz_file_info64 cur_file_info; /* public info about the current file in zip*/\n    unz_file_info64_internal cur_file_info_internal; /* private info about it*/\n    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current\n                                        file if we are decompressing it */\n    int isZip64;\n\n} unz64_s;\n\n\n#ifndef NOUNCRYPT\n#include \"crypt.h\"\n#endif\n\n/* ===========================================================================\n     Read a byte from a gz_stream; update next_in and avail_in. Return EOF\n   for end of file.\n   IN assertion: the stream s has been sucessfully opened for reading.\n*/\n\n\nlocal int unz64local_getByte OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    int *pi));\n\nlocal int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);\n    if (err==1)\n    {\n        *pi = (int)c;\n        return UNZ_OK;\n    }\n    else\n    {\n        if (ZERROR64(*pzlib_filefunc_def,filestream))\n            return UNZ_ERRNO;\n        else\n            return UNZ_EOF;\n    }\n}\n\n\n/* ===========================================================================\n   Reads a long in LSB order from the given gz_stream. Sets\n*/\nlocal int unz64local_getShort OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                             voidpf filestream,\n                             uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<24;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    ZPOS64_T *pX));\n\n\nlocal int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            ZPOS64_T *pX)\n{\n    ZPOS64_T x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (ZPOS64_T)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<24;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<32;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<40;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<48;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<56;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\n/* My own strcmpi / strcasecmp */\nlocal int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)\n{\n    for (;;)\n    {\n        char c1=*(fileName1++);\n        char c2=*(fileName2++);\n        if ((c1>='a') && (c1<='z'))\n            c1 -= 0x20;\n        if ((c2>='a') && (c2<='z'))\n            c2 -= 0x20;\n        if (c1=='\\0')\n            return ((c2=='\\0') ? 0 : -1);\n        if (c2=='\\0')\n            return 1;\n        if (c1<c2)\n            return -1;\n        if (c1>c2)\n            return 1;\n    }\n}\n\n\n#ifdef  CASESENSITIVITYDEFAULT_NO\n#define CASESENSITIVITYDEFAULTVALUE 2\n#else\n#define CASESENSITIVITYDEFAULTVALUE 1\n#endif\n\n#ifndef STRCMPCASENOSENTIVEFUNCTION\n#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal\n#endif\n\n/*\n   Compare two filename (fileName1,fileName2).\n   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)\n   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi\n                                                                or strcasecmp)\n   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system\n        (like 1 on Unix, 2 on Windows)\n\n*/\nextern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,\n                                                 const char*  fileName2,\n                                                 int iCaseSensitivity)\n\n{\n    if (iCaseSensitivity==0)\n        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;\n\n    if (iCaseSensitivity==1)\n        return strcmp(fileName1,fileName2);\n\n    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);\n}\n\n#ifndef BUFREADCOMMENT\n#define BUFREADCOMMENT (0x400)\n#endif\n\n/*\n  Locate the Central directory of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\nlocal ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos ;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            break;\n\n        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    return uPosFound;\n}\n\n\n/*\n  Locate the Central directory 64 of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream));\n\nlocal ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                                      voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n    uLong uL;\n                ZPOS64_T relativeOffset;\n\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            break;\n\n        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    if (uPosFound == 0)\n        return 0;\n\n    /* Zip64 end of central directory locator */\n    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n    /* the signature, already checked */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    /* number of the disk with the start of the zip64 end of  central directory */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 0)\n        return 0;\n\n    /* relative offset of the zip64 end of central directory record */\n    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)\n        return 0;\n\n    /* total number of disks */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 1)\n        return 0;\n\n    /* Goto end of central directory record */\n    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n     /* the signature */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    if (uL != 0x06064b50)\n        return 0;\n\n    return relativeOffset;\n}\n\n/*\n  Open a Zip file. path contain the full pathname (by example,\n     on a Windows NT computer \"c:\\\\test\\\\zlib114.zip\" or on an Unix computer\n     \"zlib/zlib114.zip\".\n     If the zipfile cannot be opened (file doesn't exist or in not valid), the\n       return value is NULL.\n     Else, the return value is a unzFile Handle, usable with other function\n       of this unzip package.\n*/\nlocal unzFile unzOpenInternal (const void *path,\n                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,\n                               int is64bitOpenFunction)\n{\n    unz64_s us;\n    unz64_s *s;\n    ZPOS64_T central_pos;\n    uLong   uL;\n\n    uLong number_disk;          /* number of the current dist, used for\n                                   spaning ZIP, unsupported, always 0*/\n    uLong number_disk_with_CD;  /* number the the disk with central dir, used\n                                   for spaning ZIP, unsupported, always 0*/\n    ZPOS64_T number_entry_CD;      /* total number of entries in\n                                   the central dir\n                                   (same than number_entry on nospan) */\n\n    int err=UNZ_OK;\n\n    if (unz_copyright[0]!=' ')\n        return NULL;\n\n    us.z_filefunc.zseek32_file = NULL;\n    us.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def==NULL)\n        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);\n    else\n        us.z_filefunc = *pzlib_filefunc64_32_def;\n    us.is64bitOpenFunction = is64bitOpenFunction;\n\n\n\n    us.filestream = ZOPEN64(us.z_filefunc,\n                                                 path,\n                                                 ZLIB_FILEFUNC_MODE_READ |\n                                                 ZLIB_FILEFUNC_MODE_EXISTING);\n    if (us.filestream==NULL)\n        return NULL;\n\n    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);\n    if (central_pos)\n    {\n        uLong uS;\n        ZPOS64_T uL64;\n\n        us.isZip64 = 1;\n\n        if (ZSEEK64(us.z_filefunc, us.filestream,\n                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* size of zip64 end of central directory record */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version made by */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version needed to extract */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory on this disk */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* offset of start of central directory with respect to the\n          starting disk number */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        us.gi.size_comment = 0;\n    }\n    else\n    {\n        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);\n        if (central_pos==0)\n            err=UNZ_ERRNO;\n\n        us.isZip64 = 0;\n\n        if (ZSEEK64(us.z_filefunc, us.filestream,\n                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central dir on this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.gi.number_entry = uL;\n\n        /* total number of entries in the central dir */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        number_entry_CD = uL;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.size_central_dir = uL;\n\n        /* offset of start of central directory with respect to the\n            starting disk number */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.offset_central_dir = uL;\n\n        /* zipfile comment length */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)\n            err=UNZ_ERRNO;\n    }\n\n    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&\n        (err==UNZ_OK))\n        err=UNZ_BADZIPFILE;\n\n    if (err!=UNZ_OK)\n    {\n        ZCLOSE64(us.z_filefunc, us.filestream);\n        return NULL;\n    }\n\n    us.byte_before_the_zipfile = central_pos -\n                            (us.offset_central_dir+us.size_central_dir);\n    us.central_pos = central_pos;\n    us.pfile_in_zip_read = NULL;\n\n\n    s=(unz64_s*)ALLOC(sizeof(unz64_s));\n    if( s != NULL)\n    {\n        *s=us;\n        unzGoToFirstFile((unzFile)s);\n    }\n    return (unzFile)s;\n}\n\n\nextern unzFile ZEXPORT unzOpen2 (const char *path,\n                                        zlib_filefunc_def* pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);\n    }\n    else\n        return unzOpenInternal(path, NULL, 0);\n}\n\nextern unzFile ZEXPORT unzOpen2_64 (const void *path,\n                                     zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);\n    }\n    else\n        return unzOpenInternal(path, NULL, 1);\n}\n\nextern unzFile ZEXPORT unzOpen (const char *path)\n{\n    return unzOpenInternal(path, NULL, 0);\n}\n\nextern unzFile ZEXPORT unzOpen64 (const void *path)\n{\n    return unzOpenInternal(path, NULL, 1);\n}\n\n/*\n  Close a ZipFile opened with unzipOpen.\n  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),\n    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.\n  return UNZ_OK if there is no problem. */\nextern int ZEXPORT unzClose (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    if (s->pfile_in_zip_read!=NULL)\n        unzCloseCurrentFile(file);\n\n    ZCLOSE64(s->z_filefunc, s->filestream);\n    TRYFREE(s);\n    return UNZ_OK;\n}\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem. */\nextern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    *pglobal_info=s->gi;\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    /* to do : check if number_entry is not truncated */\n    pglobal_info32->number_entry = (uLong)s->gi.number_entry;\n    pglobal_info32->size_comment = s->gi.size_comment;\n    return UNZ_OK;\n}\n/*\n   Translate date/time from Dos format to tm_unz (readable more easilty)\n*/\nlocal void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)\n{\n    ZPOS64_T uDate;\n    uDate = (ZPOS64_T)(ulDosDate>>16);\n    ptm->tm_mday = (uInt)(uDate&0x1f) ;\n    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;\n    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;\n\n    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);\n    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;\n    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;\n}\n\n/*\n  Get Info about the current file in the zipfile, with internal only info\n*/\nlocal int unz64local_GetCurrentFileInfoInternal OF((unzFile file,\n                                                  unz_file_info64 *pfile_info,\n                                                  unz_file_info64_internal\n                                                  *pfile_info_internal,\n                                                  char *szFileName,\n                                                  uLong fileNameBufferSize,\n                                                  void *extraField,\n                                                  uLong extraFieldBufferSize,\n                                                  char *szComment,\n                                                  uLong commentBufferSize));\n\nlocal int unz64local_GetCurrentFileInfoInternal (unzFile file,\n                                                  unz_file_info64 *pfile_info,\n                                                  unz_file_info64_internal\n                                                  *pfile_info_internal,\n                                                  char *szFileName,\n                                                  uLong fileNameBufferSize,\n                                                  void *extraField,\n                                                  uLong extraFieldBufferSize,\n                                                  char *szComment,\n                                                  uLong commentBufferSize)\n{\n    unz64_s* s;\n    unz_file_info64 file_info;\n    unz_file_info64_internal file_info_internal;\n    int err=UNZ_OK;\n    uLong uMagic;\n    long lSeek=0;\n    uLong uL;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (ZSEEK64(s->z_filefunc, s->filestream,\n              s->pos_in_central_dir+s->byte_before_the_zipfile,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n\n    /* we check the magic */\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x02014b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.compressed_size = uL;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.uncompressed_size = uL;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n                // relative offset of local header\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info_internal.offset_curfile = uL;\n\n    lSeek+=file_info.size_filename;\n    if ((err==UNZ_OK) && (szFileName!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_filename<fileNameBufferSize)\n        {\n            *(szFileName+file_info.size_filename)='\\0';\n            uSizeRead = file_info.size_filename;\n        }\n        else\n            uSizeRead = fileNameBufferSize;\n\n        if ((file_info.size_filename>0) && (fileNameBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n        lSeek -= uSizeRead;\n    }\n\n    // Read extrafield\n    if ((err==UNZ_OK) && (extraField!=NULL))\n    {\n        ZPOS64_T uSizeRead ;\n        if (file_info.size_file_extra<extraFieldBufferSize)\n            uSizeRead = file_info.size_file_extra;\n        else\n            uSizeRead = extraFieldBufferSize;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n\n        lSeek += file_info.size_file_extra - (uLong)uSizeRead;\n    }\n    else\n        lSeek += file_info.size_file_extra;\n\n\n    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))\n    {\n                                uLong acc = 0;\n\n        // since lSeek now points to after the extra field we need to move back\n        lSeek -= file_info.size_file_extra;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        while(acc < file_info.size_file_extra)\n        {\n            uLong headerId;\n                                                uLong dataSize;\n\n            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            /* ZIP64 extra fields */\n            if (headerId == 0x0001)\n            {\n                                                        uLong uL;\n\n                                                                if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)\n                                                                {\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)\n                                                                                        err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)\n                                                                {\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)\n                                                                                  err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)\n                                                                {\n                                                                        /* Relative Header offset */\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)\n                                                                                err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info.disk_num_start == (unsigned long)-1)\n                                                                {\n                                                                        /* Disk Start Number */\n                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n                                                                                err=UNZ_ERRNO;\n                                                                }\n\n            }\n            else\n            {\n                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)\n                    err=UNZ_ERRNO;\n            }\n\n            acc += 2 + 2 + dataSize;\n        }\n    }\n\n    if ((err==UNZ_OK) && (szComment!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_file_comment<commentBufferSize)\n        {\n            *(szComment+file_info.size_file_comment)='\\0';\n            uSizeRead = file_info.size_file_comment;\n        }\n        else\n            uSizeRead = commentBufferSize;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_comment>0) && (commentBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n        lSeek+=file_info.size_file_comment - uSizeRead;\n    }\n    else\n        lSeek+=file_info.size_file_comment;\n\n\n    if ((err==UNZ_OK) && (pfile_info!=NULL))\n        *pfile_info=file_info;\n\n    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))\n        *pfile_info_internal=file_info_internal;\n\n    return err;\n}\n\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem.\n*/\nextern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,\n                                          unz_file_info64 * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize,\n                                          char* szComment,  uLong commentBufferSize)\n{\n    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                szComment,commentBufferSize);\n}\n\nextern int ZEXPORT unzGetCurrentFileInfo (unzFile file,\n                                          unz_file_info * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize,\n                                          char* szComment,  uLong commentBufferSize)\n{\n    int err;\n    unz_file_info64 file_info64;\n    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                szComment,commentBufferSize);\n    if (err==UNZ_OK)\n    {\n        pfile_info->version = file_info64.version;\n        pfile_info->version_needed = file_info64.version_needed;\n        pfile_info->flag = file_info64.flag;\n        pfile_info->compression_method = file_info64.compression_method;\n        pfile_info->dosDate = file_info64.dosDate;\n        pfile_info->crc = file_info64.crc;\n\n        pfile_info->size_filename = file_info64.size_filename;\n        pfile_info->size_file_extra = file_info64.size_file_extra;\n        pfile_info->size_file_comment = file_info64.size_file_comment;\n\n        pfile_info->disk_num_start = file_info64.disk_num_start;\n        pfile_info->internal_fa = file_info64.internal_fa;\n        pfile_info->external_fa = file_info64.external_fa;\n\n        pfile_info->tmu_date = file_info64.tmu_date,\n\n\n        pfile_info->compressed_size = (uLong)file_info64.compressed_size;\n        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;\n\n    }\n    return err;\n}\n/*\n  Set the current file of the zipfile to the first file.\n  return UNZ_OK if there is no problem\n*/\nextern int ZEXPORT unzGoToFirstFile (unzFile file)\n{\n    int err=UNZ_OK;\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    s->pos_in_central_dir=s->offset_central_dir;\n    s->num_file=0;\n    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                             &s->cur_file_info_internal,\n                                             NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\n/*\n  Set the current file of the zipfile to the next file.\n  return UNZ_OK if there is no problem\n  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.\n*/\nextern int ZEXPORT unzGoToNextFile (unzFile  file)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */\n      if (s->num_file+1==s->gi.number_entry)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +\n            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;\n    s->num_file++;\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\n\n/*\n  Try locate the file szFileName in the zipfile.\n  For the iCaseSensitivity signification, see unzipStringFileNameCompare\n\n  return value :\n  UNZ_OK if the file is found. It becomes the current file.\n  UNZ_END_OF_LIST_OF_FILE if the file is not found\n*/\nextern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)\n{\n    unz64_s* s;\n    int err;\n\n    /* We remember the 'current' position in the file so that we can jump\n     * back there if we fail.\n     */\n    unz_file_info64 cur_file_infoSaved;\n    unz_file_info64_internal cur_file_info_internalSaved;\n    ZPOS64_T num_fileSaved;\n    ZPOS64_T pos_in_central_dirSaved;\n\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n\n    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)\n        return UNZ_PARAMERROR;\n\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    /* Save the current state */\n    num_fileSaved = s->num_file;\n    pos_in_central_dirSaved = s->pos_in_central_dir;\n    cur_file_infoSaved = s->cur_file_info;\n    cur_file_info_internalSaved = s->cur_file_info_internal;\n\n    err = unzGoToFirstFile(file);\n\n    while (err == UNZ_OK)\n    {\n        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];\n        err = unzGetCurrentFileInfo64(file,NULL,\n                                    szCurrentFileName,sizeof(szCurrentFileName)-1,\n                                    NULL,0,NULL,0);\n        if (err == UNZ_OK)\n        {\n            if (unzStringFileNameCompare(szCurrentFileName,\n                                            szFileName,iCaseSensitivity)==0)\n                return UNZ_OK;\n            err = unzGoToNextFile(file);\n        }\n    }\n\n    /* We failed, so restore the state of the 'current file' to where we\n     * were.\n     */\n    s->num_file = num_fileSaved ;\n    s->pos_in_central_dir = pos_in_central_dirSaved ;\n    s->cur_file_info = cur_file_infoSaved;\n    s->cur_file_info_internal = cur_file_info_internalSaved;\n    return err;\n}\n\n\n/*\n///////////////////////////////////////////\n// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)\n// I need random access\n//\n// Further optimization could be realized by adding an ability\n// to cache the directory in memory. The goal being a single\n// comprehensive file read to put the file I need in a memory.\n*/\n\n/*\ntypedef struct unz_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   // offset in file\n    ZPOS64_T num_of_file;            // # of file\n} unz_file_pos;\n*/\n\nextern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)\n{\n    unz64_s* s;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;\n    file_pos->num_of_file           = s->num_file;\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    int err = unzGetFilePos64(file,&file_pos64);\n    if (err==UNZ_OK)\n    {\n        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;\n        file_pos->num_of_file = (uLong)file_pos64.num_of_file;\n    }\n    return err;\n}\n\nextern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    /* jump to the right spot */\n    s->pos_in_central_dir = file_pos->pos_in_zip_directory;\n    s->num_file           = file_pos->num_of_file;\n\n    /* set the current file */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               NULL,0,NULL,0,NULL,0);\n    /* return results */\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern int ZEXPORT unzGoToFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    if (file_pos == NULL)\n        return UNZ_PARAMERROR;\n\n    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;\n    file_pos64.num_of_file = file_pos->num_of_file;\n    return unzGoToFilePos64(file,&file_pos64);\n}\n\n/*\n// Unzip Helper Functions - should be here?\n///////////////////////////////////////////\n*/\n\n/*\n  Read the local header of the current zipfile\n  Check the coherency of the local header and info in the end of central\n        directory about this file\n  store in *piSizeVar the size of extra info in local header\n        (filename and size of extra field data)\n*/\nlocal int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,\n                                                    ZPOS64_T * poffset_local_extrafield,\n                                                    uInt  * psize_local_extrafield)\n{\n    uLong uMagic,uData,uFlags;\n    uLong size_filename;\n    uLong size_extra_field;\n    int err=UNZ_OK;\n\n    *piSizeVar = 0;\n    *poffset_local_extrafield = 0;\n    *psize_local_extrafield = 0;\n\n    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +\n                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x04034b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n/*\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))\n        err=UNZ_BADZIPFILE;\n*/\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))\n        err=UNZ_BADZIPFILE;\n\n    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n                         (s->cur_file_info.compression_method!=Z_DEFLATED))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))\n        err=UNZ_BADZIPFILE;\n\n    *piSizeVar += (uInt)size_filename;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)\n        err=UNZ_ERRNO;\n    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +\n                                    SIZEZIPLOCALHEADER + size_filename;\n    *psize_local_extrafield = (uInt)size_extra_field;\n\n    *piSizeVar += (uInt)size_extra_field;\n\n    return err;\n}\n\n/*\n  Open for reading data the current file in the zipfile.\n  If there is no error and the file is opened, the return value is UNZ_OK.\n*/\nextern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,\n                                            int* level, int raw, const char* password)\n{\n    unz64_s* s;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_PARAMERROR;\n\n    if (s->pfile_in_zip_read != NULL)\n        unzCloseCurrentFile(file);\n\n\treturn unzOpenData(file, &s->pfile_in_zip_read, method, level, raw, password);\n}\n\nextern int ZEXPORT unzOpenData (unzFile file, unzData *data,\n\t\t\t\t\t\t\t\tint* method,\n\t\t\t\t\t\t\t\tint* level,\n\t\t\t\t\t\t\t\tint raw,\n\t\t\t\t\t\t\t\tconst char* password) {\n    int err=UNZ_OK;\n    uInt iSizeVar;\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */\n    uInt  size_local_extrafield;    /* size of the local extra field */\n\tif (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_PARAMERROR;\n\n\t\n    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)\n        return UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_INTERNALERROR;\n\n    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);\n    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;\n    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;\n    pfile_in_zip_read_info->pos_local_extrafield=0;\n    pfile_in_zip_read_info->raw=raw;\n\n    if (pfile_in_zip_read_info->read_buffer==NULL)\n    {\n        TRYFREE(pfile_in_zip_read_info);\n        return UNZ_INTERNALERROR;\n    }\n\n    pfile_in_zip_read_info->stream_initialised=0;\n\n    if (method!=NULL)\n        *method = (int)s->cur_file_info.compression_method;\n\n    if (level!=NULL)\n    {\n        *level = 6;\n        switch (s->cur_file_info.flag & 0x06)\n        {\n          case 6 : *level = 1; break;\n          case 4 : *level = 2; break;\n          case 2 : *level = 9; break;\n        }\n    }\n\n    if ((s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n        (s->cur_file_info.compression_method!=Z_DEFLATED))\n\n        err=UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;\n    pfile_in_zip_read_info->crc32=0;\n    pfile_in_zip_read_info->total_out_64=0;\n    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;\n    pfile_in_zip_read_info->filestream=s->filestream;\n    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;\n    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;\n\n    pfile_in_zip_read_info->stream.total_out = 0;\n\n    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))\n    {\n#ifdef HAVE_BZIP2\n      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;\n      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;\n      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->bstream.state = (voidpf)0;\n\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = (voidpf)0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n#else\n      pfile_in_zip_read_info->raw=1;\n#endif\n    }\n    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))\n    {\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = 0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n        /* windowBits is passed < 0 to tell that there is no zlib header.\n         * Note that in this case inflate *requires* an extra \"dummy\" byte\n         * after the compressed stream in order to complete decompression and\n         * return Z_STREAM_END.\n         * In unzip, i don't wait absolutely Z_STREAM_END because I known the\n         * size of both compressed and uncompressed data\n         */\n    }\n    pfile_in_zip_read_info->rest_read_compressed =\n            s->cur_file_info.compressed_size ;\n    pfile_in_zip_read_info->rest_read_uncompressed =\n            s->cur_file_info.uncompressed_size ;\n\n\n    pfile_in_zip_read_info->pos_in_zipfile =\n            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +\n              iSizeVar;\n\n    pfile_in_zip_read_info->stream.avail_in = (uInt)0;\n\n\tpfile_in_zip_read_info->encrypted = 0;\n\n#ifndef NOUNCRYPT\n    if (password != NULL)\n    {\n        int i;\n\t\tpfile_in_zip_read_info->pcrc_32_tab = get_crc_table();\n\t\tinit_keys(password,\n\t\t\t\t  pfile_in_zip_read_info->keys,\n\t\t\t\t  pfile_in_zip_read_info->pcrc_32_tab);\n\t\tif (ZSEEK64(pfile_in_zip_read_info->z_filefunc,\n\t\t\t\t\tpfile_in_zip_read_info->filestream,\n\t\t\t\t\tpfile_in_zip_read_info->pos_in_zipfile +\n\t\t\t\t\tpfile_in_zip_read_info->byte_before_the_zipfile,\n\t\t\t\t\tSEEK_SET)!=0)\n            return UNZ_INTERNALERROR;\n        if(ZREAD64(pfile_in_zip_read_info->z_filefunc,\n\t\t\t\t   pfile_in_zip_read_info->filestream,source, 12)<12)\n            return UNZ_INTERNALERROR;\n\n        for (i = 0; i<12; i++)\n            zdecode(pfile_in_zip_read_info->keys,\n\t\t\t\t\tpfile_in_zip_read_info->pcrc_32_tab,source[i]);\n\n\t\tpfile_in_zip_read_info->pos_in_zipfile+=12;\n\t\tpfile_in_zip_read_info->encrypted=1;\n    }\n#endif\n\n    *data = pfile_in_zip_read_info;\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzOpenCurrentFile (unzFile file)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);\n}\n\nextern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);\n}\n\nextern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)\n{\n    return unzOpenCurrentFile3(file, method, level, raw, NULL);\n}\n\n/** Addition for GDAL : START */\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    s=(unz64_s*)file;\n    if (file==NULL)\n        return 0; //UNZ_PARAMERROR;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n    if (pfile_in_zip_read_info==NULL)\n        return 0; //UNZ_PARAMERROR;\n    return pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile;\n}\n\n/** Addition for GDAL : END */\n\n/*\n  Read bytes from the current file.\n  buf contain buffer where data must be copied\n  len the size of buf.\n\n  return the number of byte copied if somes bytes are copied\n  return 0 if the end of file was reached\n  return <0 with error code if there is an error\n    (UNZ_ERRNO for IO error, or zLib error for uncompress error)\n*/\nextern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\treturn unzReadData(s->pfile_in_zip_read, buf, len);\n}\n\nextern int ZEXPORT unzReadData (unzData data,\n\t\t\t\t\t\t\t\tvoidp buf,\n\t\t\t\t\t\t\t\tunsigned len)\n{\n    int err=UNZ_OK;\n    uInt iRead = 0;\n\tfile_in_zip64_read_info_s* pfile_in_zip_read_info = data;\n\t\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if ((pfile_in_zip_read_info->read_buffer == NULL))\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (len==0)\n        return 0;\n\n    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;\n\n    pfile_in_zip_read_info->stream.avail_out = (uInt)len;\n\n    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&\n        (!(pfile_in_zip_read_info->raw)))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;\n\n    if ((len>pfile_in_zip_read_info->rest_read_compressed+\n           pfile_in_zip_read_info->stream.avail_in) &&\n         (pfile_in_zip_read_info->raw))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_compressed+\n            pfile_in_zip_read_info->stream.avail_in;\n\n    while (pfile_in_zip_read_info->stream.avail_out>0)\n    {\n        if ((pfile_in_zip_read_info->stream.avail_in==0) &&\n            (pfile_in_zip_read_info->rest_read_compressed>0))\n        {\n            uInt uReadThis = UNZ_BUFSIZE;\n            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)\n                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;\n            if (uReadThis == 0)\n                return UNZ_EOF;\n            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile,\n                         ZLIB_FILEFUNC_SEEK_SET)!=0)\n                return UNZ_ERRNO;\n            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->read_buffer,\n                      uReadThis)!=uReadThis)\n                return UNZ_ERRNO;\n\n\n#            ifndef NOUNCRYPT\n            if(pfile_in_zip_read_info->encrypted)\n            {\n                uInt i;\n                for(i=0;i<uReadThis;i++)\n                  pfile_in_zip_read_info->read_buffer[i] =\n                      zdecode(pfile_in_zip_read_info->keys,\n\t\t\t\t\t\t\t  pfile_in_zip_read_info->pcrc_32_tab,\n                              pfile_in_zip_read_info->read_buffer[i]);\n            }\n#            endif\n\n\n            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;\n\n            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;\n\n            pfile_in_zip_read_info->stream.next_in =\n                (Bytef*)pfile_in_zip_read_info->read_buffer;\n            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;\n        }\n\n        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))\n        {\n            uInt uDoCopy,i ;\n\n            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                return (iRead==0) ? UNZ_EOF : iRead;\n\n            if (pfile_in_zip_read_info->stream.avail_out <\n                            pfile_in_zip_read_info->stream.avail_in)\n                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;\n            else\n                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;\n\n            for (i=0;i<uDoCopy;i++)\n                *(pfile_in_zip_read_info->stream.next_out+i) =\n                        *(pfile_in_zip_read_info->stream.next_in+i);\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,\n                                pfile_in_zip_read_info->stream.next_out,\n                                uDoCopy);\n            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;\n            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;\n            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;\n            pfile_in_zip_read_info->stream.next_out += uDoCopy;\n            pfile_in_zip_read_info->stream.next_in += uDoCopy;\n            pfile_in_zip_read_info->stream.total_out += uDoCopy;\n            iRead += uDoCopy;\n        }\n        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)\n        {\n#ifdef HAVE_BZIP2\n            uLong uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            uLong uOutThis;\n\n            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;\n            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;\n            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;\n            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;\n            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;\n            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;\n            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;\n            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;\n\n            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;\n            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;\n\n            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);\n\n            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));\n            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;\n            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;\n            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;\n            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;\n            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;\n            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;\n\n            if (err==BZ_STREAM_END)\n              return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=BZ_OK)\n              break;\n#endif\n        } // end Z_BZIP2ED\n        else\n        {\n            ZPOS64_T uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            ZPOS64_T uOutThis;\n            int flush=Z_SYNC_FLUSH;\n\n            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;\n            bufBefore = pfile_in_zip_read_info->stream.next_out;\n\n            /*\n            if ((pfile_in_zip_read_info->rest_read_uncompressed ==\n                     pfile_in_zip_read_info->stream.avail_out) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                flush = Z_FINISH;\n            */\n            err=inflate(&pfile_in_zip_read_info->stream,flush);\n\n            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))\n              err = Z_DATA_ERROR;\n\n            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 =\n                crc32(pfile_in_zip_read_info->crc32,bufBefore,\n                        (uInt)(uOutThis));\n\n            pfile_in_zip_read_info->rest_read_uncompressed -=\n                uOutThis;\n\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            if (err==Z_STREAM_END)\n                return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=Z_OK)\n                break;\n        }\n    }\n\n    if (err==Z_OK)\n        return iRead;\n    return err;\n}\n\n\n/*\n  Give the current position in uncompressed data\n*/\nextern z_off_t ZEXPORT unztell (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\treturn unztell(s->pfile_in_zip_read);\n}\n\nextern ZPOS64_T ZEXPORT unztellData (unzData data)\n{\n    file_in_zip64_read_info_s* pfile_in_zip_read_info = data;\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n    return (z_off_t)pfile_in_zip_read_info->stream.total_out;\n}\n\n\nextern ZPOS64_T ZEXPORT unztell64Data (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return (ZPOS64_T)-1;\n    s=(unz64_s*)file;\n\treturn unztell64 (s->pfile_in_zip_read);\n}\n\nextern ZPOS64_T ZEXPORT unztell64 (unzData data)\n{\n    file_in_zip64_read_info_s* pfile_in_zip_read_info = data;\n\n    if (pfile_in_zip_read_info==NULL)\n        return (ZPOS64_T)-1;\n\n    return pfile_in_zip_read_info->total_out_64;\n}\n\n\n/*\n  return 1 if the end of file was reached, 0 elsewhere\n*/\nextern int ZEXPORT unzeof (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\treturn unzeof(s->pfile_in_zip_read);\n}\n\nextern int ZEXPORT unzeofData (unzData data)\n{\n    file_in_zip64_read_info_s* pfile_in_zip_read_info = data;\n\t\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)\n        return 1;\n    else\n        return 0;\n}\n\n\n\n/*\nRead extra field from the current file (opened by unzOpenCurrentFile)\nThis is the local-header version of the extra field (sometimes, there is\nmore info in the local-header version than in the central-header)\n\n  if buf==NULL, it return the size of the local extra field that can be read\n\n  if buf!=NULL, len is the size of the buffer, the extra header is copied in\n    buf.\n  the return value is the number of bytes copied in buf, or (if <0)\n    the error code\n*/\nextern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    uInt read_now;\n    ZPOS64_T size_to_read;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -\n                pfile_in_zip_read_info->pos_local_extrafield);\n\n    if (buf==NULL)\n        return (int)size_to_read;\n\n    if (len>size_to_read)\n        read_now = (uInt)size_to_read;\n    else\n        read_now = (uInt)len ;\n\n    if (read_now==0)\n        return 0;\n\n    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,\n              pfile_in_zip_read_info->filestream,\n              pfile_in_zip_read_info->offset_local_extrafield +\n              pfile_in_zip_read_info->pos_local_extrafield,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,\n              pfile_in_zip_read_info->filestream,\n              buf,read_now)!=read_now)\n        return UNZ_ERRNO;\n\n    return (int)read_now;\n}\n\n/*\n  Close the file in zip opened with unzipOpenCurrentFile\n  Return UNZ_CRCERROR if all the file was read but the CRC is not good\n*/\nextern int ZEXPORT unzCloseCurrentFile (unzFile file)\n{\n    int err=UNZ_OK;\n\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n\terr = unzCloseData(s->pfile_in_zip_read);\n\n\ts->pfile_in_zip_read=NULL;\n\treturn err;\n}\n\n\nextern int ZEXPORT unzCloseData (unzData data)\n{\n    int err=UNZ_OK;\n\n\tfile_in_zip64_read_info_s* pfile_in_zip_read_info = data;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&\n        (!pfile_in_zip_read_info->raw))\n    {\n        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)\n            err=UNZ_CRCERROR;\n    }\n\n\n    TRYFREE(pfile_in_zip_read_info->read_buffer);\n    pfile_in_zip_read_info->read_buffer = NULL;\n    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)\n        inflateEnd(&pfile_in_zip_read_info->stream);\n#ifdef HAVE_BZIP2\n    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)\n        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);\n#endif\n\n\n    pfile_in_zip_read_info->stream_initialised = 0;\n    TRYFREE(pfile_in_zip_read_info);\n\n    return err;\n}\n\n\n/*\n  Get the global comment string of the ZipFile, in the szComment buffer.\n  uSizeBuf is the size of the szComment buffer.\n  return the number of byte copied or an error code <0\n*/\nextern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)\n{\n    unz64_s* s;\n    uLong uReadThis ;\n    if (file==NULL)\n        return (int)UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    uReadThis = uSizeBuf;\n    if (uReadThis>s->gi.size_comment)\n        uReadThis = s->gi.size_comment;\n\n    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (uReadThis>0)\n    {\n      *szComment='\\0';\n      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)\n        return UNZ_ERRNO;\n    }\n\n    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))\n        *(szComment+s->gi.size_comment)='\\0';\n    return (int)uReadThis;\n}\n\n/* Additions by RX '2004 */\nextern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)\n{\n    unz64_s* s;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n      return 0;\n    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)\n      if (s->num_file==s->gi.number_entry)\n         return 0;\n    return s->pos_in_central_dir;\n}\n\nextern uLong ZEXPORT unzGetOffset (unzFile file)\n{\n    ZPOS64_T offset64;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    offset64 = unzGetOffset64(file);\n    return (uLong)offset64;\n}\n\nextern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    s->pos_in_central_dir = pos;\n    s->num_file = s->gi.number_entry;      /* hack */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                              &s->cur_file_info_internal,\n                                              NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern int ZEXPORT unzSetOffset (unzFile file, uLong pos)\n{\n    return unzSetOffset64(file,pos);\n}\n"
  },
  {
    "path": "src/core/utils/minizip/unzip.h",
    "content": "/* unzip.h -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         ---------------------------------------------------------------------------------\n\n        Condition of use and distribution are the same than zlib :\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  ---------------------------------------------------------------------------------\n\n        Changes\n\n        See header of unzip64.c\n\n*/\n\n#ifndef _unz64_H\n#define _unz64_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#ifndef  _ZLIBIOAPI_H\n#include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagunzFile__ { int unused; } unzFile__;\ntypedef unzFile__ *unzFile;\n#else\ntypedef voidp unzFile;\n#endif\n\ntypedef voidp unzData;\n\n#define UNZ_OK                          (0)\n#define UNZ_END_OF_LIST_OF_FILE         (-100)\n#define UNZ_ERRNO                       (Z_ERRNO)\n#define UNZ_EOF                         (0)\n#define UNZ_PARAMERROR                  (-102)\n#define UNZ_BADZIPFILE                  (-103)\n#define UNZ_INTERNALERROR               (-104)\n#define UNZ_CRCERROR                    (-105)\n\n/* tm_unz contain date/time info */\ntypedef struct tm_unz_s\n{\n    uInt tm_sec;            /* seconds after the minute - [0,59] */\n    uInt tm_min;            /* minutes after the hour - [0,59] */\n    uInt tm_hour;           /* hours since midnight - [0,23] */\n    uInt tm_mday;           /* day of the month - [1,31] */\n    uInt tm_mon;            /* months since January - [0,11] */\n    uInt tm_year;           /* years - [1980..2044] */\n} tm_unz;\n\n/* unz_global_info structure contain global data about the ZIPfile\n   These data comes from the end of central dir */\ntypedef struct unz_global_info64_s\n{\n    ZPOS64_T number_entry;         /* total number of entries in\n                                     the central dir on this disk */\n    uLong size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info64;\n\ntypedef struct unz_global_info_s\n{\n    uLong number_entry;         /* total number of entries in\n                                     the central dir on this disk */\n    uLong size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info;\n\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_info64_s\n{\n    uLong version;              /* version made by                 2 bytes */\n    uLong version_needed;       /* version needed to extract       2 bytes */\n    uLong flag;                 /* general purpose bit flag        2 bytes */\n    uLong compression_method;   /* compression method              2 bytes */\n    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    uLong crc;                  /* crc-32                          4 bytes */\n    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */\n    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */\n    uLong size_filename;        /* filename length                 2 bytes */\n    uLong size_file_extra;      /* extra field length              2 bytes */\n    uLong size_file_comment;    /* file comment length             2 bytes */\n\n    uLong disk_num_start;       /* disk number start               2 bytes */\n    uLong internal_fa;          /* internal file attributes        2 bytes */\n    uLong external_fa;          /* external file attributes        4 bytes */\n\n    tm_unz tmu_date;\n} unz_file_info64;\n\ntypedef struct unz_file_info_s\n{\n    uLong version;              /* version made by                 2 bytes */\n    uLong version_needed;       /* version needed to extract       2 bytes */\n    uLong flag;                 /* general purpose bit flag        2 bytes */\n    uLong compression_method;   /* compression method              2 bytes */\n    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    uLong crc;                  /* crc-32                          4 bytes */\n    uLong compressed_size;      /* compressed size                 4 bytes */\n    uLong uncompressed_size;    /* uncompressed size               4 bytes */\n    uLong size_filename;        /* filename length                 2 bytes */\n    uLong size_file_extra;      /* extra field length              2 bytes */\n    uLong size_file_comment;    /* file comment length             2 bytes */\n\n    uLong disk_num_start;       /* disk number start               2 bytes */\n    uLong internal_fa;          /* internal file attributes        2 bytes */\n    uLong external_fa;          /* external file attributes        4 bytes */\n\n    tm_unz tmu_date;\n} unz_file_info;\n\nextern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,\n                                                 const char* fileName2,\n                                                 int iCaseSensitivity));\n/*\n   Compare two filename (fileName1,fileName2).\n   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)\n   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi\n                                or strcasecmp)\n   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system\n    (like 1 on Unix, 2 on Windows)\n*/\n\n\nextern unzFile ZEXPORT unzOpen OF((const char *path));\nextern unzFile ZEXPORT unzOpen64 OF((const void *path));\n/*\n  Open a Zip file. path contain the full pathname (by example,\n     on a Windows XP computer \"c:\\\\zlib\\\\zlib113.zip\" or on an Unix computer\n     \"zlib/zlib113.zip\".\n     If the zipfile cannot be opened (file don't exist or in not valid), the\n       return value is NULL.\n     Else, the return value is a unzFile Handle, usable with other function\n       of this unzip package.\n     the \"64\" function take a const void* pointer, because the path is just the\n       value passed to the open64_file_func callback.\n     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path\n       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*\n       does not describe the reality\n*/\n\n\nextern unzFile ZEXPORT unzOpen2 OF((const char *path,\n                                    zlib_filefunc_def* pzlib_filefunc_def));\n/*\n   Open a Zip file, like unzOpen, but provide a set of file low level API\n      for read/write the zip file (see ioapi.h)\n*/\n\nextern unzFile ZEXPORT unzOpen2_64 OF((const void *path,\n                                    zlib_filefunc64_def* pzlib_filefunc_def));\n/*\n   Open a Zip file, like unz64Open, but provide a set of file low level API\n      for read/write the zip file (see ioapi.h)\n*/\n\nextern int ZEXPORT unzClose OF((unzFile file));\n/*\n  Close a ZipFile opened with unzipOpen.\n  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),\n    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.\n  return UNZ_OK if there is no problem. */\n\nextern int ZEXPORT unzGetGlobalInfo OF((unzFile file,\n                                        unz_global_info *pglobal_info));\n\nextern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,\n                                        unz_global_info64 *pglobal_info));\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem. */\n\n\nextern int ZEXPORT unzGetGlobalComment OF((unzFile file,\n                                           char *szComment,\n                                           uLong uSizeBuf));\n/*\n  Get the global comment string of the ZipFile, in the szComment buffer.\n  uSizeBuf is the size of the szComment buffer.\n  return the number of byte copied or an error code <0\n*/\n\n\n/***************************************************************************/\n/* Unzip package allow you browse the directory of the zipfile */\n\nextern int ZEXPORT unzGoToFirstFile OF((unzFile file));\n/*\n  Set the current file of the zipfile to the first file.\n  return UNZ_OK if there is no problem\n*/\n\nextern int ZEXPORT unzGoToNextFile OF((unzFile file));\n/*\n  Set the current file of the zipfile to the next file.\n  return UNZ_OK if there is no problem\n  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.\n*/\n\nextern int ZEXPORT unzLocateFile OF((unzFile file,\n                     const char *szFileName,\n                     int iCaseSensitivity));\n/*\n  Try locate the file szFileName in the zipfile.\n  For the iCaseSensitivity signification, see unzStringFileNameCompare\n\n  return value :\n  UNZ_OK if the file is found. It becomes the current file.\n  UNZ_END_OF_LIST_OF_FILE if the file is not found\n*/\n\n\n/* ****************************************** */\n/* Ryan supplied functions */\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_pos_s\n{\n    uLong pos_in_zip_directory;   /* offset in zip file directory */\n    uLong num_of_file;            /* # of file */\n} unz_file_pos;\n\nextern int ZEXPORT unzGetFilePos(\n    unzFile file,\n    unz_file_pos* file_pos);\n\nextern int ZEXPORT unzGoToFilePos(\n    unzFile file,\n    unz_file_pos* file_pos);\n\ntypedef struct unz64_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */\n    ZPOS64_T num_of_file;            /* # of file */\n} unz64_file_pos;\n\nextern int ZEXPORT unzGetFilePos64(\n    unzFile file,\n    unz64_file_pos* file_pos);\n\nextern int ZEXPORT unzGoToFilePos64(\n    unzFile file,\n    const unz64_file_pos* file_pos);\n\n/* ****************************************** */\n\nextern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,\n                         unz_file_info64 *pfile_info,\n                         char *szFileName,\n                         uLong fileNameBufferSize,\n                         void *extraField,\n                         uLong extraFieldBufferSize,\n                         char *szComment,\n                         uLong commentBufferSize));\n\nextern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,\n                         unz_file_info *pfile_info,\n                         char *szFileName,\n                         uLong fileNameBufferSize,\n                         void *extraField,\n                         uLong extraFieldBufferSize,\n                         char *szComment,\n                         uLong commentBufferSize));\n/*\n  Get Info about the current file\n  if pfile_info!=NULL, the *pfile_info structure will contain somes info about\n        the current file\n  if szFileName!=NULL, the filemane string will be copied in szFileName\n            (fileNameBufferSize is the size of the buffer)\n  if extraField!=NULL, the extra field information will be copied in extraField\n            (extraFieldBufferSize is the size of the buffer).\n            This is the Central-header version of the extra field\n  if szComment!=NULL, the comment string of the file will be copied in szComment\n            (commentBufferSize is the size of the buffer)\n*/\n\n\n/** Addition for GDAL : START */\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));\n\n/** Addition for GDAL : END */\n\n\n/***************************************************************************/\n/* for reading the content of the current zipfile, you can open it, read data\n   from it, and close it (you can close it before reading all the file)\n   */\n\nextern int ZEXPORT unzOpenCurrentFile OF((unzFile file));\n/*\n  Open for reading data the current file in the zipfile.\n  If there is no error, the return value is UNZ_OK.\n*/\n\nextern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,\n                                                  const char* password));\n/*\n  Open for reading data the current file in the zipfile.\n  password is a crypting password\n  If there is no error, the return value is UNZ_OK.\n*/\n\nextern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,\n                                           int* method,\n                                           int* level,\n                                           int raw));\n/*\n  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)\n    if raw==1\n  *method will receive method of compression, *level will receive level of\n     compression\n  note : you can set level parameter as NULL (if you did not want known level,\n         but you CANNOT set method parameter as NULL\n*/\n\nextern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,\n                                           int* method,\n                                           int* level,\n                                           int raw,\n                                           const char* password));\n/*\n  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)\n    if raw==1\n  *method will receive method of compression, *level will receive level of\n     compression\n  note : you can set level parameter as NULL (if you did not want known level,\n         but you CANNOT set method parameter as NULL\n*/\n\nextern int ZEXPORT unzOpenData OF((unzFile file, unzData *data,\n\t\t\t\t\t\t\t\t   int* method,\n\t\t\t\t\t\t\t\t   int* level,\n\t\t\t\t\t\t\t\t   int raw,\n\t\t\t\t\t\t\t\t   const char* password));\n\nextern int ZEXPORT unzCloseCurrentFile OF((unzFile file));\n/*\n  Close the file in zip opened with unzOpenCurrentFile\n  Return UNZ_CRCERROR if all the file was read but the CRC is not good\n*/\n\nextern int ZEXPORT unzCloseData OF((unzData data));\n\nextern int ZEXPORT unzReadCurrentFile OF((unzFile file,\n                      voidp buf,\n                      unsigned len));\n/*\n  Read bytes from the current file (opened by unzOpenCurrentFile)\n  buf contain buffer where data must be copied\n  len the size of buf.\n\n  return the number of byte copied if somes bytes are copied\n  return 0 if the end of file was reached\n  return <0 with error code if there is an error\n    (UNZ_ERRNO for IO error, or zLib error for uncompress error)\n*/\n\nextern int ZEXPORT unzReadData OF((unzData data,\n                      voidp buf,\n                      unsigned len));\n\n\nextern z_off_t ZEXPORT unztell OF((unzFile file));\n\nextern ZPOS64_T ZEXPORT unztellData OF((unzData data));\n\nextern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));\n/*\n  Give the current position in uncompressed data\n*/\n\nextern ZPOS64_T ZEXPORT unztell64Data OF((unzData data));\n\nextern int ZEXPORT unzeof OF((unzFile file));\n/*\n  return 1 if the end of file was reached, 0 elsewhere\n*/\n\nextern int ZEXPORT unzeofData OF((unzData data));\n\nextern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,\n                                             voidp buf,\n                                             unsigned len));\n/*\n  Read extra field from the current file (opened by unzOpenCurrentFile)\n  This is the local-header version of the extra field (sometimes, there is\n    more info in the local-header version than in the central-header)\n\n  if buf==NULL, it return the size of the local extra field\n\n  if buf!=NULL, len is the size of the buffer, the extra header is copied in\n    buf.\n  the return value is the number of bytes copied in buf, or (if <0)\n    the error code\n*/\n\n/***************************************************************************/\n\n/* Get the current file offset */\nextern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);\nextern uLong ZEXPORT unzGetOffset (unzFile file);\n\n/* Set the current file offset */\nextern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);\nextern int ZEXPORT unzSetOffset (unzFile file, uLong pos);\n\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _unz64_H */\n"
  },
  {
    "path": "src/core/utils/minizip/zip.c",
    "content": "/* zip.c -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         Changes\n   Oct-2009 - Mathias Svensson - Remove old C style function prototypes\n   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives\n   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.\n   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data\n                                 It is used when recreting zip archive with RAW when deleting items from a zip.\n                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.\n   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)\n   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer\n\n*/\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include \"zlib.h\"\n#include \"zip.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\n    extern int errno;\n#else\n#   include <errno.h>\n#endif\n\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n#ifndef VERSIONMADEBY\n# define VERSIONMADEBY   (0x0) /* platform depedent */\n#endif\n\n#ifndef Z_BUFSIZE\n#define Z_BUFSIZE (64*1024) //(16384)\n#endif\n\n#ifndef Z_MAXFILENAMEINZIP\n#define Z_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n# define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n# define TRYFREE(p) {if (p) free(p);}\n#endif\n\n/*\n#define SIZECENTRALDIRITEM (0x2e)\n#define SIZEZIPLOCALHEADER (0x1e)\n*/\n\n/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */\n\n\n// NOT sure that this work on ALL platform\n#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))\n\n#ifndef SEEK_CUR\n#define SEEK_CUR    1\n#endif\n\n#ifndef SEEK_END\n#define SEEK_END    2\n#endif\n\n#ifndef SEEK_SET\n#define SEEK_SET    0\n#endif\n\n#ifndef DEF_MEM_LEVEL\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n#endif\nconst char zip_copyright[] =\" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n\n#define SIZEDATA_INDATABLOCK (4096-(4*4))\n\n#define LOCALHEADERMAGIC    (0x04034b50)\n#define CENTRALHEADERMAGIC  (0x02014b50)\n#define ENDHEADERMAGIC      (0x06054b50)\n#define ZIP64ENDHEADERMAGIC      (0x6064b50)\n#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)\n\n#define FLAG_LOCALHEADER_OFFSET (0x06)\n#define CRC_LOCALHEADER_OFFSET  (0x0e)\n\n#define SIZECENTRALHEADER (0x2e) /* 46 */\n\ntypedef struct linkedlist_datablock_internal_s\n{\n  struct linkedlist_datablock_internal_s* next_datablock;\n  uLong  avail_in_this_block;\n  uLong  filled_in_this_block;\n  uLong  unused; /* for future use and alignement */\n  unsigned char data[SIZEDATA_INDATABLOCK];\n} linkedlist_datablock_internal;\n\ntypedef struct linkedlist_data_s\n{\n    linkedlist_datablock_internal* first_block;\n    linkedlist_datablock_internal* last_block;\n} linkedlist_data;\n\n\ntypedef struct\n{\n    z_stream stream;            /* zLib stream structure for inflate */\n#ifdef HAVE_BZIP2\n    bz_stream bstream;          /* bzLib stream structure for bziped */\n#endif\n\n    int  stream_initialised;    /* 1 is stream is initialised */\n    uInt pos_in_buffered_data;  /* last written byte in buffered_data */\n\n    ZPOS64_T pos_local_header;     /* offset of the local header of the file\n                                     currenty writing */\n    char* central_header;       /* central header data for the current file */\n    uLong size_centralExtra;\n    uLong size_centralheader;   /* size of the central header for cur file */\n    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */\n    uLong flag;                 /* flag of the file currently writing */\n\n    int  method;                /* compression method of file currenty wr.*/\n    int  raw;                   /* 1 for directly writing raw data */\n    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/\n    uLong dosDate;\n    uLong crc32;\n    int  encrypt;\n    int  zip64;               /* Add ZIP64 extened information in the extra field */\n    ZPOS64_T pos_zip64extrainfo;\n    ZPOS64_T totalCompressedData;\n    ZPOS64_T totalUncompressedData;\n#ifndef NOCRYPT\n    unsigned long keys[3];     /* keys defining the pseudo-random sequence */\n    const unsigned long* pcrc_32_tab;\n    int crypt_header_size;\n#endif\n} curfile64_info;\n\ntypedef struct\n{\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;        /* io structore of the zipfile */\n    linkedlist_data central_dir;/* datablock with central dir in construction*/\n    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/\n    curfile64_info ci;            /* info on the file curretly writing */\n\n    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */\n    ZPOS64_T add_position_when_writting_offset;\n    ZPOS64_T number_entry;\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    char *globalcomment;\n#endif\n\n} zip64_internal;\n\n\n#ifndef NOCRYPT\n#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n#include \"crypt.h\"\n#endif\n\nlocal linkedlist_datablock_internal* allocate_new_datablock()\n{\n    linkedlist_datablock_internal* ldi;\n    ldi = (linkedlist_datablock_internal*)\n                 ALLOC(sizeof(linkedlist_datablock_internal));\n    if (ldi!=NULL)\n    {\n        ldi->next_datablock = NULL ;\n        ldi->filled_in_this_block = 0 ;\n        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;\n    }\n    return ldi;\n}\n\nlocal void free_datablock(linkedlist_datablock_internal* ldi)\n{\n    while (ldi!=NULL)\n    {\n        linkedlist_datablock_internal* ldinext = ldi->next_datablock;\n        TRYFREE(ldi);\n        ldi = ldinext;\n    }\n}\n\nlocal void init_linkedlist(linkedlist_data* ll)\n{\n    ll->first_block = ll->last_block = NULL;\n}\n\nlocal void free_linkedlist(linkedlist_data* ll)\n{\n    free_datablock(ll->first_block);\n    ll->first_block = ll->last_block = NULL;\n}\n\n\nlocal int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)\n{\n    linkedlist_datablock_internal* ldi;\n    const unsigned char* from_copy;\n\n    if (ll==NULL)\n        return ZIP_INTERNALERROR;\n\n    if (ll->last_block == NULL)\n    {\n        ll->first_block = ll->last_block = allocate_new_datablock();\n        if (ll->first_block == NULL)\n            return ZIP_INTERNALERROR;\n    }\n\n    ldi = ll->last_block;\n    from_copy = (unsigned char*)buf;\n\n    while (len>0)\n    {\n        uInt copy_this;\n        uInt i;\n        unsigned char* to_copy;\n\n        if (ldi->avail_in_this_block==0)\n        {\n            ldi->next_datablock = allocate_new_datablock();\n            if (ldi->next_datablock == NULL)\n                return ZIP_INTERNALERROR;\n            ldi = ldi->next_datablock ;\n            ll->last_block = ldi;\n        }\n\n        if (ldi->avail_in_this_block < len)\n            copy_this = (uInt)ldi->avail_in_this_block;\n        else\n            copy_this = (uInt)len;\n\n        to_copy = &(ldi->data[ldi->filled_in_this_block]);\n\n        for (i=0;i<copy_this;i++)\n            *(to_copy+i)=*(from_copy+i);\n\n        ldi->filled_in_this_block += copy_this;\n        ldi->avail_in_this_block -= copy_this;\n        from_copy += copy_this ;\n        len -= copy_this;\n    }\n    return ZIP_OK;\n}\n\n\n\n/****************************************************************************/\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n/* ===========================================================================\n   Inputs a long in LSB order to the given file\n   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)\n*/\n\nlocal int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));\nlocal int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)\n{\n    unsigned char buf[8];\n    int n;\n    for (n = 0; n < nbByte; n++)\n    {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n    if (x != 0)\n      {     /* data overflow - hack for ZIP64 (X Roche) */\n      for (n = 0; n < nbByte; n++)\n        {\n          buf[n] = 0xff;\n        }\n      }\n\n    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)\n        return ZIP_ERRNO;\n    else\n        return ZIP_OK;\n}\n\nlocal void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));\nlocal void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)\n{\n    unsigned char* buf=(unsigned char*)dest;\n    int n;\n    for (n = 0; n < nbByte; n++) {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n\n    if (x != 0)\n    {     /* data overflow - hack for ZIP64 */\n       for (n = 0; n < nbByte; n++)\n       {\n          buf[n] = 0xff;\n       }\n    }\n}\n\n/****************************************************************************/\n\n\nlocal uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)\n{\n    uLong year = (uLong)ptm->tm_year;\n    if (year>=1980)\n        year-=1980;\n    else if (year>=80)\n        year-=80;\n    return\n      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |\n        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));\n}\n\n\n/****************************************************************************/\n\nlocal int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));\n\nlocal int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);\n    if (err==1)\n    {\n        *pi = (int)c;\n        return ZIP_OK;\n    }\n    else\n    {\n        if (ZERROR64(*pzlib_filefunc_def,filestream))\n            return ZIP_ERRNO;\n        else\n            return ZIP_EOF;\n    }\n}\n\n\n/* ===========================================================================\n   Reads a long in LSB order from the given gz_stream. Sets\n*/\nlocal int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));\n\nlocal int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<8;\n\n    if (err==ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));\n\nlocal int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<8;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<16;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<24;\n\n    if (err==ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));\n\n\nlocal int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)\n{\n  ZPOS64_T x;\n  int i = 0;\n  int err;\n\n  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x = (ZPOS64_T)i;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<8;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<16;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<24;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<32;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<40;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<48;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<56;\n\n  if (err==ZIP_OK)\n    *pX = x;\n  else\n    *pX = 0;\n\n  return err;\n}\n\n#ifndef BUFREADCOMMENT\n#define BUFREADCOMMENT (0x400)\n#endif\n/*\n  Locate the Central directory of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\n\nlocal ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n  unsigned char* buf;\n  ZPOS64_T uSizeFile;\n  ZPOS64_T uBackRead;\n  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n  ZPOS64_T uPosFound=0;\n\n  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n    return 0;\n\n\n  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n  if (uMaxBack>uSizeFile)\n    uMaxBack = uSizeFile;\n\n  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n  if (buf==NULL)\n    return 0;\n\n  uBackRead = 4;\n  while (uBackRead<uMaxBack)\n  {\n    uLong uReadSize;\n    ZPOS64_T uReadPos ;\n    int i;\n    if (uBackRead+BUFREADCOMMENT>uMaxBack)\n      uBackRead = uMaxBack;\n    else\n      uBackRead+=BUFREADCOMMENT;\n    uReadPos = uSizeFile-uBackRead ;\n\n    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      break;\n\n    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n      break;\n\n    for (i=(int)uReadSize-3; (i--)>0;)\n      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))\n      {\n        uPosFound = uReadPos+i;\n        break;\n      }\n\n      if (uPosFound!=0)\n        break;\n  }\n  TRYFREE(buf);\n  return uPosFound;\n}\n\n/*\nLocate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before\nthe global comment)\n*/\nlocal ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\n\nlocal ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n  unsigned char* buf;\n  ZPOS64_T uSizeFile;\n  ZPOS64_T uBackRead;\n  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n  ZPOS64_T uPosFound=0;\n  uLong uL;\n  ZPOS64_T relativeOffset;\n\n  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n    return 0;\n\n  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n  if (uMaxBack>uSizeFile)\n    uMaxBack = uSizeFile;\n\n  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n  if (buf==NULL)\n    return 0;\n\n  uBackRead = 4;\n  while (uBackRead<uMaxBack)\n  {\n    uLong uReadSize;\n    ZPOS64_T uReadPos;\n    int i;\n    if (uBackRead+BUFREADCOMMENT>uMaxBack)\n      uBackRead = uMaxBack;\n    else\n      uBackRead+=BUFREADCOMMENT;\n    uReadPos = uSizeFile-uBackRead ;\n\n    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      break;\n\n    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n      break;\n\n    for (i=(int)uReadSize-3; (i--)>0;)\n    {\n      // Signature \"0x07064b50\" Zip64 end of central directory locater\n      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))\n      {\n        uPosFound = uReadPos+i;\n        break;\n      }\n    }\n\n      if (uPosFound!=0)\n        break;\n  }\n\n  TRYFREE(buf);\n  if (uPosFound == 0)\n    return 0;\n\n  /* Zip64 end of central directory locator */\n  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)\n    return 0;\n\n  /* the signature, already checked */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n\n  /* number of the disk with the start of the zip64 end of  central directory */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n  if (uL != 0)\n    return 0;\n\n  /* relative offset of the zip64 end of central directory record */\n  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)\n    return 0;\n\n  /* total number of disks */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n  if (uL != 1)\n    return 0;\n\n  /* Goto Zip64 end of central directory record */\n  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)\n    return 0;\n\n  /* the signature */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n\n  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'\n    return 0;\n\n  return relativeOffset;\n}\n\nint LoadCentralDirectoryRecord(zip64_internal* pziinit)\n{\n  int err=ZIP_OK;\n  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n\n  ZPOS64_T size_central_dir;     /* size of the central directory  */\n  ZPOS64_T offset_central_dir;   /* offset of start of central directory */\n  ZPOS64_T central_pos;\n  uLong uL;\n\n  uLong number_disk;          /* number of the current dist, used for\n                              spaning ZIP, unsupported, always 0*/\n  uLong number_disk_with_CD;  /* number the the disk with central dir, used\n                              for spaning ZIP, unsupported, always 0*/\n  ZPOS64_T number_entry;\n  ZPOS64_T number_entry_CD;      /* total number of entries in\n                                the central dir\n                                (same than number_entry on nospan) */\n  uLong VersionMadeBy;\n  uLong VersionNeeded;\n  uLong size_comment;\n\n  int hasZIP64Record = 0;\n\n  // check first if we find a ZIP64 record\n  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);\n  if(central_pos > 0)\n  {\n    hasZIP64Record = 1;\n  }\n  else if(central_pos == 0)\n  {\n    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);\n  }\n\n/* disable to allow appending to empty ZIP archive\n        if (central_pos==0)\n            err=ZIP_ERRNO;\n*/\n\n  if(hasZIP64Record)\n  {\n    ZPOS64_T sizeEndOfCentralDirectory;\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n      err=ZIP_ERRNO;\n\n    /* the signature, already checked */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* size of zip64 end of central directory record */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* version made by */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* version needed to extract */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of this disk */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of the disk with the start of the central directory */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central directory on this disk */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central directory */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))\n      err=ZIP_BADZIPFILE;\n\n    /* size of the central directory */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* offset of start of central directory with respect to the\n    starting disk number */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    // TODO..\n    // read the comment from the standard central header.\n    size_comment = 0;\n  }\n  else\n  {\n    // Read End of central Directory info\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      err=ZIP_ERRNO;\n\n    /* the signature, already checked */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of this disk */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of the disk with the start of the central directory */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central dir on this disk */\n    number_entry = 0;\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      number_entry = uL;\n\n    /* total number of entries in the central dir */\n    number_entry_CD = 0;\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      number_entry_CD = uL;\n\n    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))\n      err=ZIP_BADZIPFILE;\n\n    /* size of the central directory */\n    size_central_dir = 0;\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      size_central_dir = uL;\n\n    /* offset of start of central directory with respect to the starting disk number */\n    offset_central_dir = 0;\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      offset_central_dir = uL;\n\n\n    /* zipfile global comment length */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)\n      err=ZIP_ERRNO;\n  }\n\n  if ((central_pos<offset_central_dir+size_central_dir) &&\n    (err==ZIP_OK))\n    err=ZIP_BADZIPFILE;\n\n  if (err!=ZIP_OK)\n  {\n    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);\n    return ZIP_ERRNO;\n  }\n\n  if (size_comment>0)\n  {\n    pziinit->globalcomment = (char*)ALLOC(size_comment+1);\n    if (pziinit->globalcomment)\n    {\n      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);\n      pziinit->globalcomment[size_comment]=0;\n    }\n  }\n\n  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);\n  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;\n\n  {\n    ZPOS64_T size_central_dir_to_read = size_central_dir;\n    size_t buf_size = SIZEDATA_INDATABLOCK;\n    void* buf_read = (void*)ALLOC(buf_size);\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n      err=ZIP_ERRNO;\n\n    while ((size_central_dir_to_read>0) && (err==ZIP_OK))\n    {\n      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;\n      if (read_this > size_central_dir_to_read)\n        read_this = size_central_dir_to_read;\n\n      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)\n        err=ZIP_ERRNO;\n\n      if (err==ZIP_OK)\n        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);\n\n      size_central_dir_to_read-=read_this;\n    }\n    TRYFREE(buf_read);\n  }\n  pziinit->begin_pos = byte_before_the_zipfile;\n  pziinit->number_entry = number_entry_CD;\n\n  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)\n    err=ZIP_ERRNO;\n\n  return err;\n}\n\n\n#endif /* !NO_ADDFILEINEXISTINGZIP*/\n\n\n/************************************************************/\nextern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)\n{\n    zip64_internal ziinit;\n    zip64_internal* zi;\n    int err=ZIP_OK;\n\n    ziinit.z_filefunc.zseek32_file = NULL;\n    ziinit.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def==NULL)\n        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);\n    else\n        ziinit.z_filefunc = *pzlib_filefunc64_32_def;\n\n    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,\n                  pathname,\n                  (append == APPEND_STATUS_CREATE) ?\n                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :\n                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));\n\n    if (ziinit.filestream == NULL)\n        return NULL;\n\n    if (append == APPEND_STATUS_CREATEAFTER)\n        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);\n\n    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);\n    ziinit.in_opened_file_inzip = 0;\n    ziinit.ci.stream_initialised = 0;\n    ziinit.number_entry = 0;\n    ziinit.add_position_when_writting_offset = 0;\n    init_linkedlist(&(ziinit.central_dir));\n\n\n\n    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));\n    if (zi==NULL)\n    {\n        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);\n        return NULL;\n    }\n\n    /* now we add file in a zipfile */\n#    ifndef NO_ADDFILEINEXISTINGZIP\n    ziinit.globalcomment = NULL;\n    if (append == APPEND_STATUS_ADDINZIP)\n    {\n      // Read and Cache Central Directory Records\n      err = LoadCentralDirectoryRecord(&ziinit);\n    }\n\n    if (globalcomment)\n    {\n      *globalcomment = ziinit.globalcomment;\n    }\n#    endif /* !NO_ADDFILEINEXISTINGZIP*/\n\n    if (err != ZIP_OK)\n    {\n#    ifndef NO_ADDFILEINEXISTINGZIP\n        TRYFREE(ziinit.globalcomment);\n#    endif /* !NO_ADDFILEINEXISTINGZIP*/\n        TRYFREE(zi);\n        return NULL;\n    }\n    else\n    {\n        *zi = ziinit;\n        return (zipFile)zi;\n    }\n}\n\nextern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);\n        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    else\n        return zipOpen3(pathname, append, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    else\n        return zipOpen3(pathname, append, globalcomment, NULL);\n}\n\n\n\nextern zipFile ZEXPORT zipOpen (const char* pathname, int append)\n{\n    return zipOpen3((const void*)pathname,append,NULL,NULL);\n}\n\nextern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)\n{\n    return zipOpen3(pathname,append,NULL,NULL);\n}\n\nint Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)\n{\n  /* write the local header */\n  int err;\n  uInt size_filename = (uInt)strlen(filename);\n  uInt size_extrafield = size_extrafield_local;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);\n\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);\n\n  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */\n  }\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);\n\n  if(zi->ci.zip64)\n  {\n    size_extrafield += 20;\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);\n\n  if ((err==ZIP_OK) && (size_filename > 0))\n  {\n    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)\n      err = ZIP_ERRNO;\n  }\n\n  if ((err==ZIP_OK) && (size_extrafield_local > 0))\n  {\n    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)\n      err = ZIP_ERRNO;\n  }\n\n\n  if ((err==ZIP_OK) && (zi->ci.zip64))\n  {\n      // write the Zip64 extended info\n      short HeaderID = 1;\n      short DataSize = 16;\n      ZPOS64_T CompressedSize = 0;\n      ZPOS64_T UncompressedSize = 0;\n\n      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)\n      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);\n\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);\n\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);\n  }\n\n  return err;\n}\n\n/*\n NOTE.\n When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped\n before calling this function it can be done with zipRemoveExtraInfoBlock\n\n It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize\n unnecessary allocations.\n */\nextern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting,\n                                         uLong versionMadeBy, uLong flagBase, int zip64)\n{\n    zip64_internal* zi;\n    uInt size_filename;\n    uInt size_comment;\n    uInt i;\n    int err = ZIP_OK;\n\n#    ifdef NOCRYPT\n    if (password != NULL)\n        return ZIP_PARAMERROR;\n#    endif\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n#ifdef HAVE_BZIP2\n    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))\n      return ZIP_PARAMERROR;\n#else\n    if ((method!=0) && (method!=Z_DEFLATED))\n      return ZIP_PARAMERROR;\n#endif\n\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 1)\n    {\n        err = zipCloseFileInZip (file);\n        if (err != ZIP_OK)\n            return err;\n    }\n\n    if (filename==NULL)\n        filename=\"-\";\n\n    if (comment==NULL)\n        size_comment = 0;\n    else\n        size_comment = (uInt)strlen(comment);\n\n    size_filename = (uInt)strlen(filename);\n\n    if (zipfi == NULL)\n        zi->ci.dosDate = 0;\n    else\n    {\n        if (zipfi->dosDate != 0)\n            zi->ci.dosDate = zipfi->dosDate;\n        else\n          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);\n    }\n\n    zi->ci.flag = flagBase;\n    if ((level==8) || (level==9))\n      zi->ci.flag |= 2;\n    if ((level==2))\n      zi->ci.flag |= 4;\n    if ((level==1))\n      zi->ci.flag |= 6;\n    if (password != NULL)\n      zi->ci.flag |= 1;\n\n    zi->ci.crc32 = 0;\n    zi->ci.method = method;\n    zi->ci.encrypt = 0;\n    zi->ci.stream_initialised = 0;\n    zi->ci.pos_in_buffered_data = 0;\n    zi->ci.raw = raw;\n    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);\n\n    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;\n    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data\n\n    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);\n\n    zi->ci.size_centralExtra = size_extrafield_global;\n    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);\n    /* version info */\n    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);\n    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/\n    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/\n\n    if (zipfi==NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);\n\n    if (zipfi==NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);\n\n    if(zi->ci.pos_local_header >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);\n\n    for (i=0;i<size_filename;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);\n\n    for (i=0;i<size_extrafield_global;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =\n              *(((const char*)extrafield_global)+i);\n\n    for (i=0;i<size_comment;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+\n              size_extrafield_global+i) = *(comment+i);\n    if (zi->ci.central_header == NULL)\n        return ZIP_INTERNALERROR;\n\n    zi->ci.zip64 = zip64;\n    zi->ci.totalCompressedData = 0;\n    zi->ci.totalUncompressedData = 0;\n    zi->ci.pos_zip64extrainfo = 0;\n\n    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);\n\n#ifdef HAVE_BZIP2\n    zi->ci.bstream.avail_in = (uInt)0;\n    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n    zi->ci.bstream.total_in_hi32 = 0;\n    zi->ci.bstream.total_in_lo32 = 0;\n    zi->ci.bstream.total_out_hi32 = 0;\n    zi->ci.bstream.total_out_lo32 = 0;\n#endif\n\n    zi->ci.stream.avail_in = (uInt)0;\n    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.stream.next_out = zi->ci.buffered_data;\n    zi->ci.stream.total_in = 0;\n    zi->ci.stream.total_out = 0;\n    zi->ci.stream.data_type = Z_BINARY;\n\n#ifdef HAVE_BZIP2\n    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n#else\n    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n#endif\n    {\n        if(zi->ci.method == Z_DEFLATED)\n        {\n          zi->ci.stream.zalloc = (alloc_func)0;\n          zi->ci.stream.zfree = (free_func)0;\n          zi->ci.stream.opaque = (voidpf)0;\n\n          if (windowBits>0)\n              windowBits = -windowBits;\n\n          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);\n\n          if (err==Z_OK)\n              zi->ci.stream_initialised = Z_DEFLATED;\n        }\n        else if(zi->ci.method == Z_BZIP2ED)\n        {\n#ifdef HAVE_BZIP2\n            // Init BZip stuff here\n          zi->ci.bstream.bzalloc = 0;\n          zi->ci.bstream.bzfree = 0;\n          zi->ci.bstream.opaque = (voidpf)0;\n\n          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);\n          if(err == BZ_OK)\n            zi->ci.stream_initialised = Z_BZIP2ED;\n#endif\n        }\n\n    }\n\n#    ifndef NOCRYPT\n    zi->ci.crypt_header_size = 0;\n    if ((err==Z_OK) && (password != NULL))\n    {\n        unsigned char bufHead[RAND_HEAD_LEN];\n        unsigned int sizeHead;\n        zi->ci.encrypt = 1;\n        zi->ci.pcrc_32_tab = get_crc_table();\n        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/\n\n        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);\n        zi->ci.crypt_header_size = sizeHead;\n\n        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)\n                err = ZIP_ERRNO;\n    }\n#    endif\n\n    if (err==Z_OK)\n        zi->in_opened_file_inzip = 1;\n    return err;\n}\n\nextern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting,\n                                         uLong versionMadeBy, uLong flagBase)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, versionMadeBy, flagBase, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void* extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int raw)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void* extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int raw, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void*extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, 0,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void*extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, 0,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\nlocal int zip64FlushWriteBuffer(zip64_internal* zi)\n{\n    int err=ZIP_OK;\n\n    if (zi->ci.encrypt != 0)\n    {\n#ifndef NOCRYPT\n        uInt i;\n        int t;\n        for (i=0;i<zi->ci.pos_in_buffered_data;i++)\n            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);\n#endif\n    }\n\n    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)\n      err = ZIP_ERRNO;\n\n    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;\n\n#ifdef HAVE_BZIP2\n    if(zi->ci.method == Z_BZIP2ED)\n    {\n      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;\n      zi->ci.bstream.total_in_lo32 = 0;\n      zi->ci.bstream.total_in_hi32 = 0;\n    }\n    else\n#endif\n    {\n      zi->ci.totalUncompressedData += zi->ci.stream.total_in;\n      zi->ci.stream.total_in = 0;\n    }\n\n\n    zi->ci.pos_in_buffered_data = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)\n{\n    zip64_internal* zi;\n    int err=ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n\n    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);\n\n#ifdef HAVE_BZIP2\n    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))\n    {\n      zi->ci.bstream.next_in = (void*)buf;\n      zi->ci.bstream.avail_in = len;\n      err = BZ_RUN_OK;\n\n      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))\n      {\n        if (zi->ci.bstream.avail_out == 0)\n        {\n          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n            err = ZIP_ERRNO;\n          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n        }\n\n\n        if(err != BZ_RUN_OK)\n          break;\n\n        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n        {\n          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;\n//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;\n          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);\n\n          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;\n        }\n      }\n\n      if(err == BZ_RUN_OK)\n        err = ZIP_OK;\n    }\n    else\n#endif\n    {\n      zi->ci.stream.next_in = (Bytef*)buf;\n      zi->ci.stream.avail_in = len;\n\n      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))\n      {\n          if (zi->ci.stream.avail_out == 0)\n          {\n              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                  err = ZIP_ERRNO;\n              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n              zi->ci.stream.next_out = zi->ci.buffered_data;\n          }\n\n\n          if(err != ZIP_OK)\n              break;\n\n          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n          {\n              uLong uTotalOutBefore = zi->ci.stream.total_out;\n              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);\n              if(uTotalOutBefore > zi->ci.stream.total_out)\n              {\n                int bBreak = 0;\n                bBreak++;\n              }\n\n              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;\n          }\n          else\n          {\n              uInt copy_this,i;\n              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)\n                  copy_this = zi->ci.stream.avail_in;\n              else\n                  copy_this = zi->ci.stream.avail_out;\n\n              for (i = 0; i < copy_this; i++)\n                  *(((char*)zi->ci.stream.next_out)+i) =\n                      *(((const char*)zi->ci.stream.next_in)+i);\n              {\n                  zi->ci.stream.avail_in -= copy_this;\n                  zi->ci.stream.avail_out-= copy_this;\n                  zi->ci.stream.next_in+= copy_this;\n                  zi->ci.stream.next_out+= copy_this;\n                  zi->ci.stream.total_in+= copy_this;\n                  zi->ci.stream.total_out+= copy_this;\n                  zi->ci.pos_in_buffered_data += copy_this;\n              }\n          }\n      }// while(...)\n    }\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)\n{\n    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)\n{\n    zip64_internal* zi;\n    ZPOS64_T compressed_size;\n    uLong invalidValue = 0xffffffff;\n    short datasize = 0;\n    int err=ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n    zi->ci.stream.avail_in = 0;\n\n    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n                {\n                        while (err==ZIP_OK)\n                        {\n                                uLong uTotalOutBefore;\n                                if (zi->ci.stream.avail_out == 0)\n                                {\n                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                                                err = ZIP_ERRNO;\n                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n                                        zi->ci.stream.next_out = zi->ci.buffered_data;\n                                }\n                                uTotalOutBefore = zi->ci.stream.total_out;\n                                err=deflate(&zi->ci.stream,  Z_FINISH);\n                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;\n                        }\n                }\n    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n    {\n#ifdef HAVE_BZIP2\n      err = BZ_FINISH_OK;\n      while (err==BZ_FINISH_OK)\n      {\n        uLong uTotalOutBefore;\n        if (zi->ci.bstream.avail_out == 0)\n        {\n          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n            err = ZIP_ERRNO;\n          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n        }\n        uTotalOutBefore = zi->ci.bstream.total_out_lo32;\n        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);\n        if(err == BZ_STREAM_END)\n          err = Z_STREAM_END;\n\n        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);\n      }\n\n      if(err == BZ_FINISH_OK)\n        err = ZIP_OK;\n#endif\n    }\n\n    if (err==Z_STREAM_END)\n        err=ZIP_OK; /* this is normal */\n\n    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))\n                {\n        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)\n            err = ZIP_ERRNO;\n                }\n\n    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n    {\n        int tmp_err = deflateEnd(&zi->ci.stream);\n        if (err == ZIP_OK)\n            err = tmp_err;\n        zi->ci.stream_initialised = 0;\n    }\n#ifdef HAVE_BZIP2\n    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n    {\n      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);\n                        if (err==ZIP_OK)\n                                err = tmperr;\n                        zi->ci.stream_initialised = 0;\n    }\n#endif\n\n    if (!zi->ci.raw)\n    {\n        crc32 = (uLong)zi->ci.crc32;\n        uncompressed_size = zi->ci.totalUncompressedData;\n    }\n    compressed_size = zi->ci.totalCompressedData;\n\n#    ifndef NOCRYPT\n    compressed_size += zi->ci.crypt_header_size;\n#    endif\n\n    // update Current Item crc and sizes,\n    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)\n    {\n      /*version Made by*/\n      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);\n      /*version needed*/\n      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);\n\n    }\n\n    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/\n\n\n    if(compressed_size >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/\n\n    /// set internal file attributes field\n    if (zi->ci.stream.data_type == Z_ASCII)\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);\n\n    if(uncompressed_size >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/\n\n    // Add ZIP64 extra info field for uncompressed size\n    if(uncompressed_size >= 0xffffffff)\n      datasize += 8;\n\n    // Add ZIP64 extra info field for compressed size\n    if(compressed_size >= 0xffffffff)\n      datasize += 8;\n\n    // Add ZIP64 extra info field for relative offset to local file header of current file\n    if(zi->ci.pos_local_header >= 0xffffffff)\n      datasize += 8;\n\n    if(datasize > 0)\n    {\n      char* p = NULL;\n\n      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)\n      {\n        // we can not write more data to the buffer that we have room for.\n        return ZIP_BADZIPFILE;\n      }\n\n      p = zi->ci.central_header + zi->ci.size_centralheader;\n\n      // Add Extra Information Header for 'ZIP64 information'\n      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID\n      p += 2;\n      zip64local_putValue_inmemory(p, datasize, 2); // DataSize\n      p += 2;\n\n      if(uncompressed_size >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, uncompressed_size, 8);\n        p += 8;\n      }\n\n      if(compressed_size >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, compressed_size, 8);\n        p += 8;\n      }\n\n      if(zi->ci.pos_local_header >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);\n        p += 8;\n      }\n\n      // Update how much extra free space we got in the memory buffer\n      // and increase the centralheader size so the new ZIP64 fields are included\n      // ( 4 below is the size of HeaderID and DataSize field )\n      zi->ci.size_centralExtraFree -= datasize + 4;\n      zi->ci.size_centralheader += datasize + 4;\n\n      // Update the extra info size field\n      zi->ci.size_centralExtra += datasize + 4;\n      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);\n    }\n\n    if (err==ZIP_OK)\n        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);\n\n    free(zi->ci.central_header);\n\n    if (err==ZIP_OK)\n    {\n        // Update the LocalFileHeader with the new values.\n\n        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);\n\n        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err = ZIP_ERRNO;\n\n        if (err==ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */\n\n        if(uncompressed_size >= 0xffffffff)\n        {\n          if(zi->ci.pos_zip64extrainfo > 0)\n          {\n            // Update the size in the ZIP64 extended field.\n            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)\n              err = ZIP_ERRNO;\n\n            if (err==ZIP_OK) /* compressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);\n\n            if (err==ZIP_OK) /* uncompressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);\n          }\n        }\n        else\n        {\n          if (err==ZIP_OK) /* compressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);\n\n          if (err==ZIP_OK) /* uncompressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);\n        }\n\n        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err = ZIP_ERRNO;\n    }\n\n    zi->number_entry ++;\n    zi->in_opened_file_inzip = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZip (zipFile file)\n{\n    return zipCloseFileInZipRaw (file,0,0);\n}\n\nint Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)\n{\n  int err = ZIP_OK;\n  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);\n\n  /*num disks*/\n    if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  /*relative offset*/\n    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);\n\n  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/\n    if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);\n\n    return err;\n}\n\nint Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)\n{\n  int err = ZIP_OK;\n\n  uLong Zip64DataSize = 44;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);\n\n  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?\n\n  if (err==ZIP_OK) /* version made by */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);\n\n  if (err==ZIP_OK) /* version needed */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);\n\n  if (err==ZIP_OK) /* number of this disk */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */\n    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir */\n    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n\n  if (err==ZIP_OK) /* size of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);\n\n  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */\n  {\n    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);\n  }\n  return err;\n}\nint Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)\n{\n  int err = ZIP_OK;\n\n  /*signature*/\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);\n\n  if (err==ZIP_OK) /* number of this disk */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);\n\n  if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */\n  {\n    {\n      if(zi->number_entry >= 0xFFFF)\n        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record\n      else\n        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);\n    }\n  }\n\n  if (err==ZIP_OK) /* total number of entries in the central dir */\n  {\n    if(zi->number_entry >= 0xFFFF)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);\n  }\n\n  if (err==ZIP_OK) /* size of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);\n\n  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */\n  {\n    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    if(pos >= 0xffffffff)\n    {\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);\n    }\n    else\n                  err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);\n  }\n\n   return err;\n}\n\nint Write_GlobalComment(zip64_internal* zi, const char* global_comment)\n{\n  int err = ZIP_OK;\n  uInt size_global_comment = 0;\n\n  if(global_comment != NULL)\n    size_global_comment = (uInt)strlen(global_comment);\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);\n\n  if (err == ZIP_OK && size_global_comment > 0)\n  {\n    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)\n      err = ZIP_ERRNO;\n  }\n  return err;\n}\n\nextern int ZEXPORT zipClose (zipFile file, const char* global_comment)\n{\n    zip64_internal* zi;\n    int err = 0;\n    uLong size_centraldir = 0;\n    ZPOS64_T centraldir_pos_inzip;\n    ZPOS64_T pos;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 1)\n    {\n        err = zipCloseFileInZip (file);\n    }\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    if (global_comment==NULL)\n        global_comment = zi->globalcomment;\n#endif\n\n    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);\n\n    if (err==ZIP_OK)\n    {\n        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;\n        while (ldi!=NULL)\n        {\n            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))\n            {\n                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)\n                    err = ZIP_ERRNO;\n            }\n\n            size_centraldir += ldi->filled_in_this_block;\n            ldi = ldi->next_datablock;\n        }\n    }\n    free_linkedlist(&(zi->central_dir));\n\n    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    if(pos >= 0xffffffff)\n    {\n      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);\n      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);\n\n      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);\n    }\n\n    if (err==ZIP_OK)\n      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);\n\n    if(err == ZIP_OK)\n      err = Write_GlobalComment(zi, global_comment);\n\n    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)\n        if (err == ZIP_OK)\n            err = ZIP_ERRNO;\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    TRYFREE(zi->globalcomment);\n#endif\n    TRYFREE(zi);\n\n    return err;\n}\n\nextern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)\n{\n  char* p = pData;\n  int size = 0;\n  char* pNewHeader;\n  char* pTmp;\n  short header;\n  short dataSize;\n\n  int retVal = ZIP_OK;\n\n  if(pData == NULL || *dataLen < 4)\n    return ZIP_PARAMERROR;\n\n  pNewHeader = (char*)ALLOC(*dataLen);\n  pTmp = pNewHeader;\n\n  while(p < (pData + *dataLen))\n  {\n    header = *(short*)p;\n    dataSize = *(((short*)p)+1);\n\n    if( header == sHeader ) // Header found.\n    {\n      p += dataSize + 4; // skip it. do not copy to temp buffer\n    }\n    else\n    {\n      // Extra Info block should not be removed, So copy it to the temp buffer.\n      memcpy(pTmp, p, dataSize + 4);\n      p += dataSize + 4;\n      size += dataSize + 4;\n    }\n\n  }\n\n  if(size < *dataLen)\n  {\n    // clean old extra info block.\n    memset(pData,0, *dataLen);\n\n    // copy the new extra info block over the old\n    if(size > 0)\n      memcpy(pData, pNewHeader, size);\n\n    // set the new extra info size\n    *dataLen = size;\n\n    retVal = ZIP_OK;\n  }\n  else\n    retVal = ZIP_ERRNO;\n\n  TRYFREE(pNewHeader);\n\n  return retVal;\n}\n"
  },
  {
    "path": "src/core/utils/minizip/zip.h",
    "content": "/* zip.h -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         ---------------------------------------------------------------------------\n\n   Condition of use and distribution are the same than zlib :\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n        ---------------------------------------------------------------------------\n\n        Changes\n\n        See header of zip.h\n\n*/\n\n#ifndef _zip12_H\n#define _zip12_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//#define HAVE_BZIP2\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#ifndef _ZLIBIOAPI_H\n#include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagzipFile__ { int unused; } zipFile__;\ntypedef zipFile__ *zipFile;\n#else\ntypedef voidp zipFile;\n#endif\n\n#define ZIP_OK                          (0)\n#define ZIP_EOF                         (0)\n#define ZIP_ERRNO                       (Z_ERRNO)\n#define ZIP_PARAMERROR                  (-102)\n#define ZIP_BADZIPFILE                  (-103)\n#define ZIP_INTERNALERROR               (-104)\n\n#ifndef DEF_MEM_LEVEL\n#  if MAX_MEM_LEVEL >= 8\n#    define DEF_MEM_LEVEL 8\n#  else\n#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#  endif\n#endif\n/* default memLevel */\n\n/* tm_zip contain date/time info */\ntypedef struct tm_zip_s\n{\n    uInt tm_sec;            /* seconds after the minute - [0,59] */\n    uInt tm_min;            /* minutes after the hour - [0,59] */\n    uInt tm_hour;           /* hours since midnight - [0,23] */\n    uInt tm_mday;           /* day of the month - [1,31] */\n    uInt tm_mon;            /* months since January - [0,11] */\n    uInt tm_year;           /* years - [1980..2044] */\n} tm_zip;\n\ntypedef struct\n{\n    tm_zip      tmz_date;       /* date in understandable format           */\n    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */\n/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */\n\n    uLong       internal_fa;    /* internal file attributes        2 bytes */\n    uLong       external_fa;    /* external file attributes        4 bytes */\n} zip_fileinfo;\n\ntypedef const char* zipcharpc;\n\n\n#define APPEND_STATUS_CREATE        (0)\n#define APPEND_STATUS_CREATEAFTER   (1)\n#define APPEND_STATUS_ADDINZIP      (2)\n\nextern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));\nextern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));\n/*\n  Create a zipfile.\n     pathname contain on Windows XP a filename like \"c:\\\\zlib\\\\zlib113.zip\" or on\n       an Unix computer \"zlib/zlib113.zip\".\n     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip\n       will be created at the end of the file.\n         (useful if the file contain a self extractor code)\n     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will\n       add files in existing zip (be sure you don't add file that doesn't exist)\n     If the zipfile cannot be opened, the return value is NULL.\n     Else, the return value is a zipFile Handle, usable with other function\n       of this zip package.\n*/\n\n/* Note : there is no delete function into a zipfile.\n   If you want delete file into a zipfile, you must open a zipfile, and create another\n   Of couse, you can use RAW reading and writing to copy the file you did not want delte\n*/\n\nextern zipFile ZEXPORT zipOpen2 OF((const char *pathname,\n                                   int append,\n                                   zipcharpc* globalcomment,\n                                   zlib_filefunc_def* pzlib_filefunc_def));\n\nextern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,\n                                   int append,\n                                   zipcharpc* globalcomment,\n                                   zlib_filefunc64_def* pzlib_filefunc_def));\n\nextern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,\n                       const char* filename,\n                       const zip_fileinfo* zipfi,\n                       const void* extrafield_local,\n                       uInt size_extrafield_local,\n                       const void* extrafield_global,\n                       uInt size_extrafield_global,\n                       const char* comment,\n                       int method,\n                       int level));\n\nextern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,\n                       const char* filename,\n                       const zip_fileinfo* zipfi,\n                       const void* extrafield_local,\n                       uInt size_extrafield_local,\n                       const void* extrafield_global,\n                       uInt size_extrafield_global,\n                       const char* comment,\n                       int method,\n                       int level,\n                       int zip64));\n\n/*\n  Open a file in the ZIP for writing.\n  filename : the filename in zip (if NULL, '-' without quote will be used\n  *zipfi contain supplemental information\n  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local\n    contains the extrafield data the the local header\n  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global\n    contains the extrafield data the the local header\n  if comment != NULL, comment contain the comment string\n  method contain the compression method (0 for store, Z_DEFLATED for deflate)\n  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)\n  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.\n                    this MUST be '1' if the uncompressed size is >= 0xffffffff.\n\n*/\n\n\nextern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw));\n\n\nextern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int zip64));\n/*\n  Same than zipOpenNewFileInZip, except if raw=1, we write raw file\n */\n\nextern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting));\n\nextern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            int zip64\n                                            ));\n\n/*\n  Same than zipOpenNewFileInZip2, except\n    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2\n    password : crypting password (NULL for no crypting)\n    crcForCrypting : crc of file to compress (needed for crypting)\n */\n\nextern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            uLong versionMadeBy,\n                                            uLong flagBase\n                                            ));\n\n\nextern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            uLong versionMadeBy,\n                                            uLong flagBase,\n                                            int zip64\n                                            ));\n/*\n  Same than zipOpenNewFileInZip4, except\n    versionMadeBy : value for Version made by field\n    flag : value for flag field (compression level info will be added)\n */\n\n\nextern int ZEXPORT zipWriteInFileInZip OF((zipFile file,\n                       const void* buf,\n                       unsigned len));\n/*\n  Write data in the zipfile\n*/\n\nextern int ZEXPORT zipCloseFileInZip OF((zipFile file));\n/*\n  Close the current file in the zipfile\n*/\n\nextern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,\n                                            uLong uncompressed_size,\n                                            uLong crc32));\n\nextern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,\n                                            ZPOS64_T uncompressed_size,\n                                            uLong crc32));\n\n/*\n  Close the current file in the zipfile, for file opened with\n    parameter raw=1 in zipOpenNewFileInZip2\n  uncompressed_size and crc32 are value for the uncompressed size\n*/\n\nextern int ZEXPORT zipClose OF((zipFile file,\n                const char* global_comment));\n/*\n  Close the zipfile\n*/\n\n\nextern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));\n/*\n  zipRemoveExtraInfoBlock -  Added by Mathias Svensson\n\n  Remove extra information block from a extra information data for the local file header or central directory header\n\n  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.\n\n  0x0001 is the signature header for the ZIP64 extra information blocks\n\n  usage.\n                        Remove ZIP64 Extra information from a central director extra field data\n              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);\n\n                        Remove ZIP64 Extra information from a Local File Header extra field data\n        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);\n*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _zip64_H */\n"
  },
  {
    "path": "src/core/utils/win32/ClipboardImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Clipboard Class interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n#include \"MsgIntf.h\"\n#include \"Exception.h\"\n#include \"ClipboardIntf.h\"\n\n//---------------------------------------------------------------------------\n// clipboard related functions\n//---------------------------------------------------------------------------\nbool TVPClipboardHasFormat(tTVPClipboardFormat format)\n{\n\tswitch(format) {\n\t\tcase cbfText: {\n\t\tbool result = false;\n#if 0\n\t\tif( ::OpenClipboard(0) ) {\n\t\t\tresult = 0 != ::IsClipboardFormatAvailable(CF_TEXT);\n\t\t\tif( result == false ) {\n\t\t\t\tresult = 0 != ::IsClipboardFormatAvailable(CF_UNICODETEXT);\n\t\t\t}\n\t\t\t::CloseClipboard();\n\t\t}\n#endif\n\t\treturn result; // ANSI text or UNICODE text\n\t\t}\n\tdefault:\n\t\treturn false;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPClipboardSetText(const ttstr & text)\n{\n#if 0\n\tif( ::OpenClipboard(0) ) {\n\t\tHGLOBAL ansihandle = NULL;\n\t\tHGLOBAL unicodehandle = NULL;\n\t\ttry {\n\t\t\t// store ANSI string\n\t\t\tstd::string ansistr = text.AsNarrowStdString();\n\t\t\tint ansistrlen = (int)((ansistr.length() + 1)*sizeof(char));\n\t\t\tansihandle = ::GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, ansistrlen);\n\t\t\tif( !ansihandle ) TVPThrowExceptionMessage( TVPFaildClipboardCopy );\n\n\t\t\tchar *mem = (char*)::GlobalLock(ansihandle);\n\t\t\tif(mem) strncpy_s(mem, ansistrlen, ansistr.c_str(),ansistrlen);\n\t\t\t::GlobalUnlock(ansihandle);\n\n\t\t\t::SetClipboardData( CF_TEXT, ansihandle );\n\t\t\tansihandle = NULL;\n\n\t\t\t// store UNICODE string\n\t\t\tunicodehandle = ::GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, (text.GetLen() + 1) * sizeof(tjs_char));\n\t\t\tif(!unicodehandle) TVPThrowExceptionMessage( TVPFaildClipboardCopy );;\n\n\t\t\ttjs_char *unimem = (tjs_char*)::GlobalLock(unicodehandle);\n\t\t\tif(unimem) TJS_strcpy(unimem, text.c_str());\n\t\t\t::GlobalUnlock(unicodehandle);\n\n\t\t\t::SetClipboardData( CF_UNICODETEXT, unicodehandle );\n\t\t\tunicodehandle = NULL;\n\t\t} catch(...) {\n\t\t\tif(ansihandle) ::GlobalFree(ansihandle);\n\t\t\tif(unicodehandle) ::GlobalFree(unicodehandle);\n\t\t\t::CloseClipboard();\n\t\t\tthrow;\n\t\t}\n\t\t::CloseClipboard();\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nbool TVPClipboardGetText(ttstr & text)\n{\n#if 0\n\tif(!::OpenClipboard(NULL)) return false;\n\n\tbool result = false;\n\ttry\n\t{\n\t\t// select CF_UNICODETEXT or CF_TEXT\n\t\tUINT formats[2] = { CF_UNICODETEXT, CF_TEXT};\n\t\tint format = ::GetPriorityClipboardFormat(formats, 2);\n\n\t\tif(format == CF_UNICODETEXT)\n\t\t{\n\t\t\t// try to read unicode text\n\t\t\tHGLOBAL hglb = (HGLOBAL)::GetClipboardData(CF_UNICODETEXT);\n\t\t\tif(hglb != NULL)\n\t\t\t{\n\t\t\t\tconst tjs_char *p = (const tjs_char *)::GlobalLock(hglb);\n\t\t\t\tif(p)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttext = ttstr(p);\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\t::GlobalUnlock(hglb);\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\t::GlobalUnlock(hglb);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(format == CF_TEXT)\n\t\t{\n\t\t\t// try to read ansi text\n\t\t\tHGLOBAL hglb = (HGLOBAL)::GetClipboardData(CF_TEXT);\n\t\t\tif(hglb != NULL)\n\t\t\t{\n\t\t\t\tconst char *p = (const char *)::GlobalLock(hglb);\n\t\t\t\tif(p)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttext = ttstr(p);\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\t}\n\t\t\t\t\tcatch(...)\n\t\t\t\t\t{\n\t\t\t\t\t\t::GlobalUnlock(hglb);\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\t::GlobalUnlock(hglb);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\t::CloseClipboard();\n\t\tthrow;\n\t}\n\t::CloseClipboard();\n\treturn result;\n#endif\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/utils/win32/ClipboardImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Clipboard Class interface\n//---------------------------------------------------------------------------\n#ifndef ClipboardImplH\n#define ClipboardImplH\n//---------------------------------------------------------------------------\n#include \"tjsNative.h\"\n#include \"ClipboardIntf.h\"\n\n\n\n//---------------------------------------------------------------------------\n#endif\n\n"
  },
  {
    "path": "src/core/utils/win32/DebugImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Utilities for Debugging\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"DebugImpl.h\"\n\n\n//---------------------------------------------------------------------------\n// on-error hook\n//---------------------------------------------------------------------------\nvoid TVPOnErrorHook()\n{\n//\tif(TVPMainForm) TVPMainForm->NotifySystemError();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Controller : TJS Controller Class\n//---------------------------------------------------------------------------\nclass tTJSNC_Controller : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Controller();\n\n\tstatic tjs_uint32 ClassID;\n};\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Controller::ClassID = (tjs_uint32)-1;\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSNC_Controller::tTJSNC_Controller() : tTJSNativeClass(TJS_W(\"Controller\"))\n{\n\tTJS_BEGIN_NATIVE_MEMBERS(Debug)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Controller)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Controller)\n//----------------------------------------------------------------------\n\n// properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = 0;// TVPMainForm->getVisible();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\t//TVPMainForm->setVisible(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(visible)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n}\n//---------------------------------------------------------------------------\nstatic iTJSDispatch2 * TVPGetControllerClass()\n{\n\tstruct tClassHolder\n\t{\n\t\tiTJSDispatch2 *Object;\n\t\ttClassHolder() { Object = new tTJSNC_Controller(); }\n\t\t~tClassHolder() { Object->Release(); }\n\t} static Holder;\n\n\tHolder.Object->AddRef();\n\treturn Holder.Object;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Console : TJS Console Class\n//---------------------------------------------------------------------------\nclass tTJSNC_Console : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Console();\n\n\tstatic tjs_uint32 ClassID;\n};\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Console::ClassID = (tjs_uint32)-1;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\ntTJSNC_Console::tTJSNC_Console() : tTJSNativeClass(TJS_W(\"Console\"))\n{\n\tTJS_BEGIN_NATIVE_MEMBERS(Debug)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Console)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Console)\n//----------------------------------------------------------------------\n\n// properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n//\t\t*result = TVPMainForm->GetConsoleVisible();\n\t\t*result = false;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tbool visible = param->operator bool();\n//\t\tTVPMainForm->SetConsoleVisible(visible);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(visible)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n}\n//---------------------------------------------------------------------------\nstatic iTJSDispatch2 * TVPGetConsoleClass()\n{\n\tstruct tClassHolder\n\t{\n\t\tiTJSDispatch2 *Object;\n\t\ttClassHolder() { Object = new tTJSNC_Console(); }\n\t\t~tClassHolder() { Object->Release(); }\n\t} static Holder;\n\n\tHolder.Object->AddRef();\n\treturn Holder.Object;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Debug\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Debug::CreateNativeInstance()\n{\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Debug()\n{\n\ttTJSNativeClass *cls = new tTJSNC_Debug();\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(controller)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tiTJSDispatch2 *dsp = TVPGetControllerClass();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\tdsp->Release();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, controller)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(console)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tiTJSDispatch2 *dsp = TVPGetConsoleClass();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\tdsp->Release();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, console)\n//----------------------------------------------------------------------\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n\n\n"
  },
  {
    "path": "src/core/utils/win32/DebugImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Utilities for Debugging\n//---------------------------------------------------------------------------\n#ifndef DebugImplH\n#define DebugImplH\n\n#include \"DebugIntf.h\"\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/win32/PadImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text Editor\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"PadImpl.h\"\n#include \"PadIntf.h\"\n#if 0\n#include \"PadFormUnit.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Pad : Pad Class C++ Native Instance\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_Pad::Construct(tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 * dsp)\n{\n\tHRESULT hr = tTJSNI_BasePad::Construct(numparams, param, dsp);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tForm = new TTVPPadForm(Application);\n\tForm->SetExecButtonEnabled(false);\n\n\t// RXgN^NꂽXNvgGfB^ł͂ȂAƔfOKH\n// ۗɂ܂B\n//\tSetUserCreationMode(true);\n\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_Pad::Invalidate()\n{\n\tif(Form) delete Form, Form = NULL;\n\ttTJSNI_BasePad::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::OpenFromStorage(const ttstr & name)\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SaveToStorage(const ttstr & name)\n{\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetText(const ttstr &content)\n{\n\tForm->SetLines(content);\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Pad::GetText() const\n{\n\treturn Form->GetLines();\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNI_Pad::GetColor() const\n{\n\treturn Form->GetEditColor();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetColor(tjs_uint32 color)\n{\n\tForm->SetEditColor(color);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::GetVisible() const\n{\n\treturn Form->Visible;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetVisible(bool state)\n{\n\tForm->Visible = state;\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Pad::GetFileName() const\n{\n\treturn Form->GetFileName();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFileName(const ttstr & name)\n{\n\tForm->SetFileName(name);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetTitle(const ttstr &title)\n{\n\tForm->Caption = title.AsAnsiString();\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Pad::GetTitle() const\n{\n\treturn Form->Caption;\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNI_Pad::GetFontColor() const\n{\n\treturn Form->GetFontColor();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFontColor(tjs_uint32 color)\n{\n\tForm->SetFontColor(color);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFontHeight() const\t// pixel\n{\n\treturn Form->GetFontHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFontHeight(tjs_int t)\n{\n\tForm->SetFontHeight(t);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFontSize() const\t// point\n{\n\treturn Form->GetFontSize();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFontSize(tjs_int t)\n{\n\tForm->SetFontSize(t);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::ContainsFontStyle(tjs_int style) const\n{\n\treturn Form->ContainsFontStyle(style);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::AddFontStyle(tjs_int style)\n{\n\tForm->AddFontStyle(style);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::RemoveFontStyle(tjs_int style)\n{\n\tForm->RemoveFontStyle(style);\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Pad::GetFontName(void) const\n{\n\treturn Form->GetFontName();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFontName(const ttstr & name)\n{\n\treturn Form->SetFontName(name);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::IsReadOnly(void) const\n{\n\treturn Form->GetReadOnly();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetReadOnly(bool ro)\n{\n\tForm->SetReadOnly(ro);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetOpacity(void) const\n{\n\treturn Form->GetOpacity();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetOpacity(tjs_int opa)\n{\n\tForm->SetOpacity(opa);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::GetWordWrap(void) const\n{\n\treturn Form->GetWordWrap();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetWordWrap(bool ww)\n{\n\tForm->SetWordWrap(ww);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::GetStatusBarVisible(void) const\n{\n\treturn Form->GetStatusBarVisible();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetStatusBarVisible(bool vis)\n{\n\tForm->SetStatusBarVisible(vis);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetScrollBarsVisible(void) const\n{\n\treturn Form->GetScrollBarsVisible();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetScrollBarsVisible(tjs_int vis)\n{\n\tForm->SetScrollBarsVisible(vis);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetStatusText(const ttstr &title)\n{\n\tForm->SetStatusText(title);\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Pad::GetStatusText() const\n{\n\treturn Form->GetStatusText();\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetBorderStyle() const\n{\n\treturn Form->GetBorderStyle();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetBorderStyle(tjs_int style)\n{\n\tForm->SetBorderStyle(style);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFormHeight() const\n{\n\treturn Form->Height;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFormHeight(tjs_int value)\n{\n\tForm->Height = value;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFormWidth() const\n{\n\treturn Form->Width;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFormWidth(tjs_int value)\n{\n\tForm->Width = value;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFormTop() const\n{\n\treturn Form->Top;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFormTop(tjs_int value)\n{\n\tForm->Top = value;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Pad::GetFormLeft() const\n{\n\treturn Form->Left;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetFormLeft(tjs_int value)\n{\n\tForm->Left = value;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nbool tTJSNI_Pad::GetUserCreationMode(void) const\n{\n\treturn UserCreationMode;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Pad::SetUserCreationMode(bool user)\n{\n\tUserCreationMode = user;\n\tif (user)\n\t{\n\t\tForm->ToolBar->Visible = false;\n\t\tForm->ToolBar->Enabled = false;\n\t\tForm->ExecuteButton->Visible = false;\n\t\tForm->ExecuteButton->Enabled = false;\n\t\tForm->StatusBar->Left = 0;\n\n\t\tForm->SetEditColor(clWindow);\n\t\tForm->SetFontColor(clWindowText);\n\t\tForm->StatusBar->Width = Form->Width;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Pad\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Pad::CreateNativeInstance()\n{\n\treturn new tTJSNI_Pad();\n}\n//---------------------------------------------------------------------------\n\n#endif\n\n"
  },
  {
    "path": "src/core/utils/win32/PadImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Text Editor\n//---------------------------------------------------------------------------\n#ifndef PadImplH\n#define PadImplH\n//---------------------------------------------------------------------------\n#include \"tjsNative.h\"\n#include \"PadIntf.h\"\n\nclass TTVPPadForm;\n//---------------------------------------------------------------------------\n// tTJSNI_Pad : Pad Class C++ Native Instance\n//---------------------------------------------------------------------------\nclass tTJSNI_Pad : public tTJSNI_BasePad\n{\n\tTTVPPadForm *Form;\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *dsp);\n\tvirtual void TJS_INTF_METHOD Invalidate();\n\n// methods\n\tvirtual void OpenFromStorage(const ttstr & name);\n\tvirtual void SaveToStorage(const ttstr & name);\n\n// properties\n\tvirtual tjs_uint32 GetColor() const;\n\tvirtual void SetColor(tjs_uint32 color);\n\tvirtual bool GetVisible() const;\n\tvirtual void SetVisible(bool state);\n\tvirtual ttstr GetFileName() const;\n\tvirtual void SetFileName(const ttstr &name);\n\tvirtual void SetText(const ttstr &content);\n\tvirtual ttstr GetText() const;\n\tvirtual void SetTitle(const ttstr &title);\n\tvirtual ttstr GetTitle() const;\n\n\tvirtual tjs_uint32 GetFontColor() const;\n\tvirtual void SetFontColor(tjs_uint32 color);\n\tvirtual tjs_int GetFontHeight() const;\t// pixel\n\tvirtual void SetFontHeight(tjs_int height);\n\tvirtual tjs_int GetFontSize() const;\t// point\n\tvirtual void SetFontSize(tjs_int size);\n\tvirtual bool ContainsFontStyle(tjs_int style) const;\n\tvirtual void AddFontStyle(tjs_int style);\n\tvirtual void RemoveFontStyle(tjs_int style);\n\tvirtual ttstr GetFontName(void) const;\n\tvirtual void SetFontName(const ttstr & name);\n\tvirtual bool IsReadOnly(void) const;\n\tvirtual void SetReadOnly(bool ro);\n\tvirtual bool GetWordWrap(void) const;\n\tvirtual void SetWordWrap(bool ww);\n\tvirtual tjs_int GetOpacity(void) const;\n\tvirtual void SetOpacity(tjs_int opa);\n\tvirtual bool GetStatusBarVisible(void) const;\n\tvirtual void SetStatusBarVisible(bool vis);\n\tvirtual tjs_int GetScrollBarsVisible(void) const;\n\tvirtual void SetScrollBarsVisible(tjs_int vis);\n\tvirtual tjs_int GetBorderStyle(void) const;\n\tvirtual void SetBorderStyle(tjs_int style);\n\tvirtual ttstr GetStatusText() const;\n\tvirtual void SetStatusText(const ttstr &title);\n\n\t// form position and size\n\tvirtual tjs_int GetFormHeight(void) const;\n\tvirtual tjs_int GetFormWidth(void) const;\n\tvirtual tjs_int GetFormTop(void) const;\n\tvirtual tjs_int GetFormLeft(void) const;\n\tvirtual void SetFormHeight(tjs_int value);\n\tvirtual void SetFormWidth(tjs_int value);\n\tvirtual void SetFormTop(tjs_int value);\n\tvirtual void SetFormLeft(tjs_int value);\n\n\t// \n\tvirtual bool GetUserCreationMode(void) const;\n\tvirtual void SetUserCreationMode(bool mode);\n\nprotected:\n\tbool UserCreationMode; // true if this form was created by the userscript,\n\t\t\t\t\t\t// otherwise (when created by the system as \"Script Editor\") this will be false\n\tbool MultilineMode;\n\nprivate:\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#endif\n\n"
  },
  {
    "path": "src/core/utils/win32/TVPTimer.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"TVPTimer.h\"\n#include \"TickCount.h\"\n\nstruct tTVPTimerImpl {\n\ttTVPTimerImpl *Prev = nullptr, *Next = nullptr;\n\tTVPTimer *pTimer = nullptr;\n\tuint32_t Index;\n\t~tTVPTimerImpl() {\n\t\tif (Prev) Prev->Next = Next;\n\t\tif (Next) Next->Prev = Prev;\n\t}\n\tvoid SetTimer(TVPTimer * p) { pTimer = p; }\n\tvoid Kill() {\n\t\tif (Prev) Prev->Next = Next;\n\t\tif (Next) Next->Prev = Prev;\n\t\tNext = Prev = nullptr;\n\t}\n\tvoid Set();\n\tvoid Set(int idx);\n\tvoid Add(tTVPTimerImpl* p) {\n\t\tp->Next = Next;\n\t\tNext = p;\n\t\tp->Prev = this;\n\t}\n\tvoid FireNext();\n};\n\nstatic tTVPTimerImpl\n\t_timer_v1[256],\n\t_timer_v2[64],\n\t_timer_v3[64],\n\t_timer_v4[64],\n\t_timer_v5[64];\nstatic struct t_timer_idx {\n\tunion {\n\t\tstruct {\n\t\t\tunsigned int _idx_v1 : 8;\n\t\t\tunsigned int _idx_v2 : 6;\n\t\t\tunsigned int _idx_v3 : 6;\n\t\t\tunsigned int _idx_v4 : 6;\n\t\t\tunsigned int _idx_v5 : 6;\n\t\t};\n\t\tuint32_t _idx;\n\t};\n\tt_timer_idx(uint32_t idx) : _idx(idx) {}\n} _timer_idx(TVPGetRoughTickCount32());\n\nvoid tTVPTimerImpl::Set() {\n\tint interval = pTimer->GetInterval();\n\tSet(interval);\n}\n\nvoid tTVPTimerImpl::Set(int idx)\n{\n\tidx += _timer_idx._idx_v1;\n\tIndex = idx;\n\tif (idx < 256) {\n\t\t_timer_v1[idx].Add(this);\n\t\treturn;\n\t}\n\tidx >>= 8;\n\tidx += _timer_idx._idx_v2;\n\tif (idx < 64) {\n\t\t_timer_v2[idx].Add(this);\n\t\treturn;\n\t}\n\tidx >>= 6;\n\tidx += _timer_idx._idx_v3;\n\tif (idx < 64) {\n\t\t_timer_v3[idx].Add(this);\n\t\treturn;\n\t}\n\tidx >>= 6;\n\tidx += _timer_idx._idx_v4;\n\tif (idx < 64) {\n\t\t_timer_v4[idx].Add(this);\n\t\treturn;\n\t}\n\tidx >>= 6;\n\tidx += _timer_idx._idx_v5;\n\t_timer_v5[idx].Add(this);\n}\n\nstatic tTVPTimerImpl _processedTimer;\n\nvoid tTVPTimerImpl::FireNext() {\n\ttTVPTimerImpl* p = Next;\n\tif (!p) return;\n\tNext = nullptr;\n\n\tp->pTimer->FireEvent();\n\tp->FireNext();\n\t_processedTimer.Add(p);\n// \tint interval = p->pTimer->GetInterval();\n// \tp->Set(interval);\n}\n\nvoid TVPTimer::ProgressAllTimer()\n{\n\tuint32_t curTick = TVPGetRoughTickCount32();\n\tint past = curTick - _timer_idx._idx;\n\tfor (int i = 0; i < past; ++i) {\n\t\t_timer_v1[_timer_idx._idx_v1].FireNext();\n\t\t++_timer_idx._idx;\n\t\tif (_timer_idx._idx_v1 == 0) { // v2 step\n\t\t\ttTVPTimerImpl* root = &_timer_v2[_timer_idx._idx_v2];\n\t\t\ttTVPTimerImpl* p = root->Next;\n\t\t\troot->Next = nullptr;\n\t\t\twhile (p) {\n\t\t\t\ttTVPTimerImpl* next = p->Next;\n\t\t\t\tp->Next = nullptr;\n\t\t\t\tp->Index &= 255;\n\t\t\t\t_timer_v1[p->Index].Add(p);\n\t\t\t\tp = next;\n\t\t\t}\n\t\t}\n\t\tif (_timer_idx._idx_v2 == 0) { // v3 step\n\t\t\ttTVPTimerImpl* root = &_timer_v3[_timer_idx._idx_v3];\n\t\t\ttTVPTimerImpl* p = root->Next;\n\t\t\troot->Next = nullptr;\n\t\t\twhile (p) {\n\t\t\t\ttTVPTimerImpl* next = p->Next;\n\t\t\t\tp->Next = nullptr;\n\t\t\t\tint idx = p->Index >> 8;\n\t\t\t\tp->Index &= 255 | (63 << 8);\n\t\t\t\t_timer_v2[idx].Add(p);\n\t\t\t\tp = next;\n\t\t\t}\n\t\t}\n\t\tif (_timer_idx._idx_v3 == 0) { // v4 step\n\t\t\ttTVPTimerImpl* root = &_timer_v4[_timer_idx._idx_v4];\n\t\t\ttTVPTimerImpl* p = root->Next;\n\t\t\troot->Next = nullptr;\n\t\t\twhile (p) {\n\t\t\t\ttTVPTimerImpl* next = p->Next;\n\t\t\t\tp->Next = nullptr;\n\t\t\t\tint idx = p->Index >> (8 + 6);\n\t\t\t\tp->Index &= 255 | (63 << 8) | (63 << (8 + 6));\n\t\t\t\t_timer_v3[idx].Add(p);\n\t\t\t\tp = next;\n\t\t\t}\n\t\t}\n\t\tif (_timer_idx._idx_v4 == 0) { // v5 step\n\t\t\ttTVPTimerImpl* root = &_timer_v5[_timer_idx._idx_v5];\n\t\t\ttTVPTimerImpl* p = root->Next;\n\t\t\troot->Next = nullptr;\n\t\t\twhile (p) {\n\t\t\t\ttTVPTimerImpl* next = p->Next;\n\t\t\t\tp->Next = nullptr;\n\t\t\t\tint idx = p->Index >> (8 + 6 + 6);\n\t\t\t\tp->Index &= 255 | (63 << 8) | (63 << (8 + 6)) | (63 << (8 + 6 + 6));\n\t\t\t\t_timer_v4[idx].Add(p);\n\t\t\t\tp = next;\n\t\t\t}\n\t\t}\n\t}\n\ttTVPTimerImpl* p = _processedTimer.Next;\n\t_processedTimer.Next = nullptr;\n\twhile (p) {\n\t\ttTVPTimerImpl* next = p->Next;\n\t\tp->Next = nullptr;\n\t\tp->Set();\n\t\tp = next;\n\t}\n}\n\nTVPTimer::TVPTimer() : event_(NULL), interval_(1000), enabled_(true) {\n\timpl_ = new tTVPTimerImpl;\n\timpl_->pTimer = this;\n}\n\nTVPTimer::~TVPTimer() {\n\tdelete impl_;\n\tif( event_ ) {\n\t\tdelete event_;\n\t}\n}\n\nvoid TVPTimer::UpdateTimer() {\n\timpl_->Kill();\n\tif( interval_ > 0 && enabled_ && event_ != NULL ) {\n\t\timpl_->Set();\n\t}\n}\n\n"
  },
  {
    "path": "src/core/utils/win32/TVPTimer.h",
    "content": "\n#ifndef __TVP_TIMER_H__\n#define __TVP_TIMER_H__\n\nclass TVPTimerEventIntarface {\npublic:\n\tvirtual ~TVPTimerEventIntarface() {}\n\tvirtual void Handle() = 0;\n};\n\ntemplate<typename T>\nclass TVPTimerEvent : public TVPTimerEventIntarface {\n\tvoid (T::*handler_)();\n\tT* owner_;\n\npublic:\n\tTVPTimerEvent( T* owner, void (T::*Handler)() ) : owner_(owner), handler_(Handler) {}\n\tvoid Handle() { (owner_->*handler_)(); }\n};\nclass tTVPTimerImpl;\nclass TVPTimer {\n\tTVPTimerEventIntarface* event_;\n\tint\t\tinterval_;\n\tbool\tenabled_;\n\n\tvoid UpdateTimer();\n\n\tvoid FireEvent() {\n\t\tif( event_ ) {\n\t\t\tevent_->Handle();\n\t\t}\n\t}\n\n\tfriend class tTVPTimerImpl;\n\ttTVPTimerImpl *impl_;\n\npublic:\n\tTVPTimer();\n\t~TVPTimer();\n\n\ttemplate<typename T>\n\tvoid SetOnTimerHandler( T* owner, void (T::*Handler)() ) {\n\t\tif( event_ ) delete event_;\n\t\tevent_ = new TVPTimerEvent<T>( owner, Handler );\n\t\tUpdateTimer();\n\t}\n\n\tvoid SetInterval( int i ) {\n\t\tif( interval_ != i ) {\n\t\t\tinterval_ = i;\n\t\t\tUpdateTimer();\n\t\t}\n\t}\n\tint GetInterval() const {\n\t\treturn interval_;\n\t}\n\tvoid SetEnabled( bool b ) {\n\t\tif( enabled_ != b ) {\n\t\t\tenabled_ = b;\n\t\t\tUpdateTimer();\n\t\t}\n\t}\n\tbool GetEnable() const { return enabled_; }\n\n\tstatic void ProgressAllTimer();\n};\n\n\n#endif // __TVP_TIMER_H__\n"
  },
  {
    "path": "src/core/utils/win32/ThreadImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Thread base class\n//---------------------------------------------------------------------------\n#define NOMINMAX\n#include \"tjsCommHead.h\"\n\n//#include <process.h>\n#include <algorithm>\n\n#include \"ThreadIntf.h\"\n#include \"ThreadImpl.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n\n#if defined(CC_TARGET_OS_IPHONE) || defined(__aarch64__)\n#else\n//#define USING_THREADPOOL11\n#endif\n\n#ifdef USING_THREADPOOL11\n#include \"threadpool11/pool.hpp\"\n#endif\n#include <thread>\n\n//---------------------------------------------------------------------------\n// tTVPThread : a wrapper class for thread\n//---------------------------------------------------------------------------\ntTVPThread::tTVPThread(bool suspended)\n{\n\tTerminated = false;\n\tSuspended = suspended;\n\n\tpthread_attr_t attr;\n\tif (pthread_attr_init(&attr) != 0) {\n\t\tTVPThrowInternalError;\n\t}\n\tif (pthread_create(&Handle, &attr, StartProc, this) != 0) {\n\t\tpthread_attr_destroy(&attr);\n\t\tTVPThrowInternalError;\n\t}\n\tpthread_attr_destroy(&attr);\n}\n//---------------------------------------------------------------------------\ntTVPThread::~tTVPThread()\n{\n\t//CloseHandle(Handle);\n}\n//---------------------------------------------------------------------------\nvoid * tTVPThread::StartProc(void * arg)\n{\n\ttTVPThread* _this = ((tTVPThread*)arg);\n\tif (_this->Suspended) {\n\t\tstd::unique_lock<std::mutex> lk(_this->_mutex);\n\t\t_this->_cond.wait(lk);\n\t}\n\t_this->Execute();\n\tTVPOnThreadExited();\n\treturn nullptr;\n}\n//---------------------------------------------------------------------------\nvoid tTVPThread::WaitFor()\n{\n\tvoid *result;\n\tpthread_join(Handle, &result);\n}\n//---------------------------------------------------------------------------\ntTVPThreadPriority tTVPThread::GetPriority()\n{\n\tsched_param npri = { 0 };\n\tint policy = 0;\n\tpthread_getschedparam(Handle, &policy, &npri);\n\n\tswitch (policy)\n\t{\n\tcase 5/*SCHED_IDLE*/: return ttpIdle;\n\tcase 3/*SCHED_BATCH*/: return (npri.sched_priority == 0) ? ttpLowest : ttpLower;\n\tcase 0/*SCHED_NORMAL*/:\n\t\tswitch (npri.sched_priority) {\n\t\tcase 0: return ttpNormal;\n\t\tcase 1: return ttpHigher;\n\t\tcase 2: return ttpHighest;\n\t\t}\n\t\tbreak;\n\tcase 2/*SCHED_RR*/: return ttpTimeCritical;\n\t}\n\n\treturn ttpNormal;\n}\n//---------------------------------------------------------------------------\nvoid tTVPThread::SetPriority(tTVPThreadPriority pri)\n{\n\tsched_param npri = { 0 }; //SCHED_NORMAL\n\tint policy = 0;\n\tswitch (pri)\n\t{\n\tcase ttpIdle:\t\t\tpolicy = 5/*SCHED_IDLE*/;\t\t\tbreak;\n\tcase ttpLowest:\t\t\tpolicy = 3/*SCHED_BATCH*/;\tnpri.sched_priority = 0;\t\tbreak;\n\tcase ttpLower:\t\t\tpolicy = 3/*SCHED_BATCH*/;\tnpri.sched_priority = 1;        break;\n\tcase ttpNormal:\t\t\tpolicy = 0/*SCHED_NORMAL*/;\t\tbreak;\n\tcase ttpHigher:\t\t\tpolicy = 0/*SCHED_NORMAL*/;\tnpri.sched_priority = 1;    break;\n\tcase ttpHighest:\t\tpolicy = 0/*SCHED_NORMAL*/;\tnpri.sched_priority = 2;\tbreak;\n\tcase ttpTimeCritical:\tpolicy = 2/*SCHED_RR*/;\t    break;\n\t}\n\tpthread_setschedparam(Handle, policy, &npri);\n}\n//---------------------------------------------------------------------------\n// void tTVPThread::Suspend()\n// {\n// \tSuspendThread(Handle);\n// }\n//---------------------------------------------------------------------------\nvoid tTVPThread::Resume()\n{\n\tSuspended = false;\n\t_cond.notify_one();\n\t//while((tjs_int32)ResumeThread(Handle) > 1) ;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPThreadEvent\n//---------------------------------------------------------------------------\nvoid tTVPThreadEvent::Set()\n{\n\tstd::unique_lock<std::mutex> lk(Mutex);\n\tHandle.notify_one();\n}\n//---------------------------------------------------------------------------\nvoid tTVPThreadEvent::WaitFor(tjs_uint timeout)\n{\n\t// wait for event;\n\t// returns true if the event is set, otherwise (when timed out) returns false.\n\n\tstd::unique_lock<std::mutex> lk(Mutex);\n\tif (timeout != 0) {\n\t\tHandle.wait_for(lk, std::chrono::milliseconds(timeout));\n\t} else {\n\t\tHandle.wait(lk);\n\t}\n#if 0\n\tDWORD state = WaitForSingleObject(Handle, timeout == 0 ? INFINITE : timeout);\n\n\tif(state == WAIT_OBJECT_0) return true;\n\treturn false;\n#endif\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntjs_int TVPDrawThreadNum = 1;\n\nstatic std::vector<tjs_int> TVPProcesserIdList;\nstatic tjs_int TVPThreadTaskNum, TVPThreadTaskCount;\n\n//---------------------------------------------------------------------------\nstatic tjs_int GetProcesserNum(void)\n{\n  static tjs_int processor_num = 0;\n  if (! processor_num) {\n\t  processor_num = std::thread::hardware_concurrency();\n\ttjs_char tmp[34];\n\tTVPAddLog(ttstr(TJS_W(\"Detected CPU core(s): \")) + TJS_tTVInt_to_str(processor_num, tmp));\n  }\n  return processor_num;\n}\n\ntjs_int TVPGetProcessorNum(void)\n{\n  return GetProcesserNum();\n}\n\n//---------------------------------------------------------------------------\ntjs_int TVPGetThreadNum(void)\n{\n  tjs_int threadNum = TVPDrawThreadNum ? TVPDrawThreadNum : GetProcesserNum();\n  threadNum = std::min(threadNum, TVPMaxThreadNum);\n  return threadNum;\n}\n\n//---------------------------------------------------------------------------\nvoid TVPExecThreadTask(int numThreads, TVP_THREAD_TASK_FUNC func)\n{\n  if (numThreads == 1) {\n    func(0);\n    return;\n  }\n#if !defined(USING_THREADPOOL11)\n#pragma omp parallel for schedule(static)\n  for (int i = 0; i < numThreads; ++i)\n\t  func(i);\n#else\n  static threadpool11::Pool pool;\n  std::vector<std::future<void>> futures;\n  for (int i = 0; i < numThreads; ++i) {\n\t  futures.emplace_back(pool.postWork<void>(std::bind(func, i)));\n  }\n  for (auto& it : futures)\n\t  it.get();\n#endif\n#if 0\n  ThreadInfo *threadInfo;\n  threadInfo = TVPThreadList[TVPThreadTaskCount++];\n  threadInfo->lpStartAddress = func;\n  threadInfo->lpParameter = param;\n  InterlockedIncrement(&TVPRunningThreadCount);\n  while (ResumeThread(threadInfo->thread) == 0)\n    Sleep(0);\n#endif\n}\n//---------------------------------------------------------------------------\n\nstd::vector<std::function<void()>> _OnThreadExitedEvents;\n\nvoid TVPOnThreadExited() {\n\tfor (const auto &ev : _OnThreadExitedEvents) {\n\t\tev();\n\t}\n}\n\nvoid TVPAddOnThreadExitEvent(const std::function<void()> &ev)\n{\n\t_OnThreadExitedEvents.emplace_back(ev);\n}\n"
  },
  {
    "path": "src/core/utils/win32/ThreadImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Thread base class\n//---------------------------------------------------------------------------\n#ifndef ThreadImplH\n#define ThreadImplH\n#include \"tjsNative.h\"\n#include \"ThreadIntf.h\"\n#include <condition_variable>\n#include \"pthread.h\"\n\n\n//---------------------------------------------------------------------------\n// tTVPThread\n//---------------------------------------------------------------------------\nclass tTVPThread\n{\n\tbool Terminated;\n\tpthread_t Handle;\n\t//DWORD ThreadId;\n\tstd::mutex _mutex; // for suspend\n\tstd::condition_variable _cond;\n\tbool Suspended;\n\n\tstatic void* /*__stdcall*/ StartProc(void * arg);\n\npublic:\n\ttTVPThread(bool suspended);\n\tvirtual ~tTVPThread();\n\n\tbool GetTerminated() const { return Terminated; }\n\tvoid SetTerminated(bool s) { Terminated = s; }\n\tvoid Terminate() { Terminated = true; }\n\nprotected:\n\tvirtual void Execute() = 0;\n\npublic:\n\tvoid WaitFor();\n\n\ttTVPThreadPriority GetPriority();\n\tvoid SetPriority(tTVPThreadPriority pri);\n\n\t//void Suspend();\n\tvoid Resume();\n\n// \tHANDLE GetHandle() const { return Handle; } \t/* win32 specific */\n// \tDWORD GetThreadId() const { return ThreadId; }  /* win32 specific */\n\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPThreadEvent\n//---------------------------------------------------------------------------\nclass tTVPThreadEvent\n{\n\tstd::condition_variable Handle;\n\tstd::mutex Mutex;\n\npublic:\n\tvoid Set();\n\tvoid WaitFor(tjs_uint timeout);\n};\n//---------------------------------------------------------------------------\n\nvoid TVPAddOnThreadExitEvent(const std::function<void()> &ev);\nvoid TVPOnThreadExited();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/utils/win32/TimerImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Timer Object Implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"EventIntf.h\"\n#include \"TickCount.h\"\n#include \"TimerImpl.h\"\n#include \"SysInitIntf.h\"\n#include \"ThreadIntf.h\"\n#include \"MsgIntf.h\"\n\n#include \"NativeEventQueue.h\"\n#include \"UserEvent.h\"\n\n//---------------------------------------------------------------------------\n\n// TVP Timer class gives ability of triggering event on punctual interval.\n// a large quantity of event at once may easily cause freeze to system,\n// so we must trigger only porocess-able quantity of the event.\n#define TVP_LEAST_TIMER_INTERVAL 3\n#define INFINITE 0xFFFFFFFF\n\n\n//---------------------------------------------------------------------------\n// tTVPTimerThread\n//---------------------------------------------------------------------------\nclass tTVPTimerThread : public tTVPThread\n{\n\t// thread for triggering punctual event.\n\t// normal Windows timer cannot call the timer callback routine at\n\t// too short interval ( roughly less than 50ms ).\n\n\tstd::vector<tTJSNI_Timer *> List;\n\tstd::vector<tTJSNI_Timer *> Pending; // timer object which has pending events\n\tbool PendingEventsAvailable;\n\ttTVPThreadEvent Event;\n\t\n\tNativeEventQueue<tTVPTimerThread> EventQueue;\n\npublic:\n\n\ttTJSCriticalSection TVPTimerCS;\n\n\ttTVPTimerThread();\n\t~tTVPTimerThread();\n\nprotected:\n\tvoid Execute();\n\nprivate:\n\tvoid Proc( NativeEvent& event );\n\n\tvoid AddItem(tTJSNI_Timer * item);\n\tbool RemoveItem(tTJSNI_Timer *item);\n\tvoid RemoveFromPendingItem(tTJSNI_Timer *item);\n\tvoid RegisterToPendingItem(tTJSNI_Timer *item);\n\npublic:\n\tvoid SetEnabled(tTJSNI_Timer *item, bool enabled); // managed by this class\n\tvoid SetInterval(tTJSNI_Timer *item, tjs_uint64 interval); // managed by this class\n\npublic:\n\tstatic void Init();\n\tstatic void Uninit();\n\n\tstatic void Add(tTJSNI_Timer * item);\n\tstatic void Remove(tTJSNI_Timer *item);\n\n\tstatic void RemoveFromPending(tTJSNI_Timer *item);\n\tstatic void RegisterToPending(tTJSNI_Timer *item);\n\n} static * TVPTimerThread = NULL;\n//---------------------------------------------------------------------------\ntTVPTimerThread::tTVPTimerThread() : tTVPThread(true), EventQueue(this,&tTVPTimerThread::Proc)\n{\n\tPendingEventsAvailable = false;\n\tSetPriority(TVPLimitTimerCapacity ? ttpNormal : ttpHighest);\n\tEventQueue.Allocate();\n\tResume();\n}\n//---------------------------------------------------------------------------\ntTVPTimerThread::~tTVPTimerThread()\n{\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n\tEventQueue.Deallocate();\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::Execute()\n{\n\twhile(!GetTerminated())\n\t{\n\t\ttjs_uint64 step_next = (tjs_uint64)(tjs_int64)-1L; // invalid value\n\t\ttjs_uint64 curtick = TVPGetTickCount() << TVP_SUBMILLI_FRAC_BITS;\n\t\ttjs_uint32 sleeptime;\n\n\t\t{\t// thread-protected\n\t\t\ttTJSCriticalSectionHolder holder(TVPTimerCS);\n\n\t\t\tbool any_triggered = false;\n\n\t\t\tstd::vector<tTJSNI_Timer*>::iterator i;\n\t\t\tfor(i = List.begin(); i!=List.end(); i ++)\n\t\t\t{\n\t\t\t\ttTJSNI_Timer * item = *i;\n\n\t\t\t\tif(!item->GetEnabled() || item->GetInterval() == 0) continue;\n\n\t\t\t\tif(item->GetNextTick() < curtick)\n\t\t\t\t{\n\t\t\t\t\ttjs_uint n = static_cast<tjs_uint>( (curtick - item->GetNextTick()) / item->GetInterval() );\n\t\t\t\t\tn++;\n\t\t\t\t\tif(n > 40)\n\t\t\t\t\t{\n\t\t\t\t\t\t// too large amount of event at once; discard rest\n\t\t\t\t\t\titem->Trigger(1);\n\t\t\t\t\t\tany_triggered = true;\n\t\t\t\t\t\titem->SetNextTick(curtick + item->GetInterval());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\titem->Trigger(n);\n\t\t\t\t\t\tany_triggered = true;\n\t\t\t\t\t\titem->SetNextTick(item->GetNextTick() +\n\t\t\t\t\t\t\tn * item->GetInterval());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\ttjs_uint64 to_next = item->GetNextTick() - curtick;\n\n\t\t\t\tif(step_next == (tjs_uint64)(tjs_int64)-1L)\n\t\t\t\t{\n\t\t\t\t\tstep_next = to_next;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(step_next > to_next) step_next = to_next;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif(step_next != (tjs_uint64)(tjs_int64)-1L)\n\t\t\t{\n\t\t\t\t// too large step_next must be diminished to size of DWORD.\n\t\t\t\tif(step_next >= 0x80000000)\n\t\t\t\t\tsleeptime = 0x7fffffff; // smaller value than step_next is OK\n\t\t\t\telse\n\t\t\t\t\tsleeptime = static_cast<tjs_uint32>( step_next );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsleeptime = INFINITE;\n\t\t\t}\n\n\t\t\tif(List.size() == 0) sleeptime = INFINITE;\n\n\t\t\tif(any_triggered)\n\t\t\t{\n\t\t\t\t// triggered; post notification message to the UtilWindow\n\t\t\t\tif(!PendingEventsAvailable)\n\t\t\t\t{\n\t\t\t\t\tPendingEventsAvailable = true;\n\t\t\t\t\tEventQueue.PostEvent( NativeEvent(TVP_EV_TIMER_THREAD) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\t// end-of-thread-protected\n\n\t\t// now, sleeptime has sub-milliseconds precision but we need millisecond\n\t\t// precision time.\n\t\tif(sleeptime != INFINITE)\n\t\t\tsleeptime = (sleeptime >> TVP_SUBMILLI_FRAC_BITS) +\n\t\t\t\t\t\t\t(sleeptime & ((1<<TVP_SUBMILLI_FRAC_BITS)-1) ? 1: 0); // round up\n\n\t\t// clamp to TVP_LEAST_TIMER_INTERVAL ...\n\t\tif(sleeptime != INFINITE && sleeptime < TVP_LEAST_TIMER_INTERVAL)\n\t\t\tsleeptime = TVP_LEAST_TIMER_INTERVAL;\n\n\t\tEvent.WaitFor(sleeptime); // wait until sleeptime is elapsed or\n\t\t\t\t\t\t\t\t\t// Event->SetEvent() is executed.\n\t}\n}\n//---------------------------------------------------------------------------\n//void __fastcall tTVPTimerThread::UtilWndProc(Messages::TMessage &Msg)\nvoid tTVPTimerThread::Proc( NativeEvent& ev )\n{\n\t// Window procedure of UtilWindow\n\tif( ev.Message == TVP_EV_TIMER_THREAD && !GetTerminated())\n\t{\n\t\t// pending events occur\n\t\ttTJSCriticalSectionHolder holder(TVPTimerCS); // protect the object\n\n\t\tstd::vector<tTJSNI_Timer *>::iterator i;\n\t\tfor(i = Pending.begin(); i!=Pending.end(); i ++)\n\t\t{\n\t\t\ttTJSNI_Timer * item = *i;\n\t\t\titem->FirePendingEventsAndClear();\n\t\t}\n\n\t\tPending.clear();\n\t\tPendingEventsAvailable = false;\n\t}\n\telse\n\t{\n\t\tEventQueue.HandlerDefault(ev);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::AddItem(tTJSNI_Timer * item)\n{\n\ttTJSCriticalSectionHolder holder(TVPTimerCS);\n\n\tif(std::find(List.begin(), List.end(), item) == List.end())\n\t\tList.push_back(item);\n}\n//---------------------------------------------------------------------------\nbool tTVPTimerThread::RemoveItem(tTJSNI_Timer *item)\n{\n\ttTJSCriticalSectionHolder holder(TVPTimerCS);\n\n\tstd::vector<tTJSNI_Timer *>::iterator i;\n\n\t// remove from the List\n\tfor(i = List.begin(); i != List.end(); /**/)\n\t{\n\t\tif(*i == item) i = List.erase(i); else i++;\n\t}\n\n\t// also remove from the Pending list\n\tRemoveFromPendingItem(item);\n\n\treturn List.size() != 0;\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::RemoveFromPendingItem(tTJSNI_Timer *item)\n{\n\t// remove item from pending list\n \tstd::vector<tTJSNI_Timer *>::iterator i;\n\tfor(i = Pending.begin(); i != Pending.end(); /**/)\n\t{\n\t\tif(*i == item) i = Pending.erase(i); else i++;\n\t}\n\n\titem->ZeroPendingCount();\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::RegisterToPendingItem(tTJSNI_Timer *item)\n{\n\t// register item to the pending list\n\tPending.push_back(item);\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::SetEnabled(tTJSNI_Timer *item, bool enabled)\n{\n\t{ // thread-protected\n\t\ttTJSCriticalSectionHolder holder(TVPTimerCS);\n\n\t\titem->InternalSetEnabled(enabled);\n\t\tif(enabled)\n\t\t{\n\t\t\titem->SetNextTick((TVPGetTickCount()  << TVP_SUBMILLI_FRAC_BITS) + item->GetInterval());\n\t\t}\n\t\telse\n\t\t{\n\t\t\titem->CancelEvents();\n\t\t\titem->ZeroPendingCount();\n\t\t}\n\t} // end-of-thread-protected\n\n\tif(enabled) Event.Set();\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::SetInterval(tTJSNI_Timer *item, tjs_uint64 interval)\n{\n\t{ // thread-protected\n\t\ttTJSCriticalSectionHolder holder(TVPTimerCS);\n\n\t\titem->InternalSetInterval(interval);\n\t\tif(item->GetEnabled())\n\t\t{\n\t\t\titem->CancelEvents();\n\t\t\titem->ZeroPendingCount();\n\t\t\titem->SetNextTick((TVPGetTickCount()  << TVP_SUBMILLI_FRAC_BITS) + item->GetInterval());\n\t\t}\n\t} // end-of-thread-protected\n\n\tif(item->GetEnabled()) Event.Set();\n\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::Init()\n{\n\tif(!TVPTimerThread)\n\t{\n\t\tTVPStartTickCount(); // in TickCount.cpp\n\t\tTVPTimerThread = new tTVPTimerThread();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::Uninit()\n{\n\tif(TVPTimerThread)\n\t{\n\t\tdelete TVPTimerThread;\n\t\tTVPTimerThread = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPTimerThreadUninitAtExit(TVP_ATEXIT_PRI_SHUTDOWN,\n\ttTVPTimerThread::Uninit);\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::Add(tTJSNI_Timer * item)\n{\n\t// at this point, item->GetEnebled() must be false.\n\n\tInit();\n\n\tTVPTimerThread->AddItem(item);\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::Remove(tTJSNI_Timer *item)\n{\n\tif(TVPTimerThread)\n\t{\n\t\tif(!TVPTimerThread->RemoveItem(item)) Uninit();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::RemoveFromPending(tTJSNI_Timer *item)\n{\n\tif(TVPTimerThread)\n\t{\n\t\tTVPTimerThread->RemoveFromPendingItem(item);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPTimerThread::RegisterToPending(tTJSNI_Timer *item)\n{\n\tif(TVPTimerThread)\n\t{\n\t\tTVPTimerThread->RegisterToPendingItem(item);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Timer\n//---------------------------------------------------------------------------\ntTJSNI_Timer::tTJSNI_Timer()\n{\n\tNextTick = 0;\n\tInterval = 1000;\n\tPendingCount = 0;\n\tEnabled = false;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNI_Timer::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjs_obj)\n{\n\tinherited::Construct(numparams, param, tjs_obj);\n\n\ttTVPTimerThread::Add(this);\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Timer::Invalidate()\n{\n\ttTVPTimerThread::Remove(this);\n\tZeroPendingCount();\n\tCancelEvents();\n\tinherited::Invalidate();  // this sets Owner = NULL\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Timer::SetInterval(tjs_uint64 n)\n{\n\tTVPTimerThread->SetInterval(this, n);\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_Timer::GetInterval() const\n{\n\treturn Interval;\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_Timer::GetNextTick() const\n{\n\treturn NextTick;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Timer::SetEnabled(bool b)\n{\n\tTVPTimerThread->SetEnabled(this, b);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Timer::Trigger(tjs_uint n)\n{\n\t// this function is called by sub-thread.\n\tif(PendingCount == 0) tTVPTimerThread::RegisterToPending(this);\n\tPendingCount += n;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Timer::FirePendingEventsAndClear()\n{\n\t// fire all pending events and clear the pending event count\n\tif(PendingCount)\n\t{\n\t\tFire(PendingCount);\n\t\tZeroPendingCount();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Timer\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Timer::CreateNativeInstance()\n{\n\treturn new tTJSNI_Timer();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Timer\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Timer()\n{\n\treturn new tTJSNC_Timer();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/utils/win32/TimerImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Timer Object Implementation\n//---------------------------------------------------------------------------\n#ifndef TimerImplH\n#define TimerImplH\n\n#include \"TimerIntf.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_Timer : Timer Native Instance\n//---------------------------------------------------------------------------\nclass tTVPTimerThread;\nclass tTJSNI_Timer : public tTJSNI_BaseTimer\n{\n\ttypedef tTJSNI_BaseTimer inherited;\n\tfriend class tTVPTimerThread;\n\n\ttjs_uint64 Interval;\n\ttjs_uint64 NextTick;\n\ttjs_int PendingCount;\n\tbool Enabled;\n\npublic:\n\ttTJSNI_Timer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\tvoid InternalSetInterval(tjs_uint64 n) { Interval = n; }\n\tvoid SetInterval(tjs_uint64 n);\n\ttjs_uint64 GetInterval() const;\n\t\t// { return Interval; }\n\n\tvoid ZeroPendingCount() { PendingCount = 0; }\n\n\tvoid SetNextTick(tjs_uint64 n) { NextTick = n; }\n\ttjs_uint64 GetNextTick() const;\n\t\t// { return NextTick; }\n\t\t// bcc 5.5.1 has an inliner bug of bad returning of int64...\n\n\tvoid InternalSetEnabled(bool b) { Enabled = b; }\n\tvoid SetEnabled(bool b);\n\tbool GetEnabled() const { return Enabled; }\n\n\tvoid Trigger(tjs_uint n);\n\tvoid FirePendingEventsAndClear();\n\nprivate:\n\tvoid CancelTrigger();\n};\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/ARM/AlphaMovie_mjpeg.h",
    "content": "\n#define DCTSIZE2\t    64\t/* DCTSIZE squared; # of elements in a block */\n#define DCTSIZE\t\t    8\t/* The basic DCT block is 8x8 coefficients */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nconst int jpeg_natural_order[DCTSIZE2 + 16]; // in libjpeg\n#define DEQUANTIZE(coef,quantval)  ((coef) * (quantval))\n#define CONST_BITS  13\n#define PASS1_BITS  2\n#define ONE\t((int) 1)\n#define MULTIPLY(a,b)  ((a) * (b))\n#define RIGHT_SHIFT(a,b) ((a) >> (b))\n#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)\n#define FIX_0_298631336  ((int)  2446)\t/* FIX(0.298631336) */\n#define FIX_0_390180644  ((int)  3196)\t/* FIX(0.390180644) */\n#define FIX_0_541196100  ((int)  4433)\t/* FIX(0.541196100) */\n#define FIX_0_765366865  ((int)  6270)\t/* FIX(0.765366865) */\n#define FIX_0_899976223  ((int)  7373)\t/* FIX(0.899976223) */\n#define FIX_1_175875602  ((int)  9633)\t/* FIX(1.175875602) */\n#define FIX_1_501321110  ((int)  12299)\t/* FIX(1.501321110) */\n#define FIX_1_847759065  ((int)  15137)\t/* FIX(1.847759065) */\n#define FIX_1_961570560  ((int)  16069)\t/* FIX(1.961570560) */\n#define FIX_2_053119869  ((int)  16819)\t/* FIX(2.053119869) */\n#define FIX_2_562915447  ((int)  20995)\t/* FIX(2.562915447) */\n#define FIX_3_072711026  ((int)  25172)\t/* FIX(3.072711026) */\n\nstatic void AlphaMovie_mjpeg_IDCT_neon(int16_t *quantptr, int16_t *inptr, uint8_t *outptr, int outpitch) {\n\tint workspace[DCTSIZE2];\t/* buffers data between passes */\n\tint * wsptr = workspace;\n\tint tmp0, tmp1, tmp2, tmp3;\n\tint tmp10, tmp11, tmp12, tmp13;\n\tint z1, z2, z3, ctr;\n\tfor (ctr = DCTSIZE; ctr > 0; ctr--) {\n\t\tif (inptr[DCTSIZE * 1] == 0 && inptr[DCTSIZE * 2] == 0 &&\n\t\t\tinptr[DCTSIZE * 3] == 0 && inptr[DCTSIZE * 4] == 0 &&\n\t\t\tinptr[DCTSIZE * 5] == 0 && inptr[DCTSIZE * 6] == 0 &&\n\t\t\tinptr[DCTSIZE * 7] == 0) {\n\t\t\t/* AC terms all zero */\n\t\t\tint dcval = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]) << PASS1_BITS;\n\n\t\t\twsptr[DCTSIZE * 0] = dcval;\n\t\t\twsptr[DCTSIZE * 1] = dcval;\n\t\t\twsptr[DCTSIZE * 2] = dcval;\n\t\t\twsptr[DCTSIZE * 3] = dcval;\n\t\t\twsptr[DCTSIZE * 4] = dcval;\n\t\t\twsptr[DCTSIZE * 5] = dcval;\n\t\t\twsptr[DCTSIZE * 6] = dcval;\n\t\t\twsptr[DCTSIZE * 7] = dcval;\n\n\t\t\tinptr++;\t\t\t/* advance pointers to next column */\n\t\t\tquantptr++;\n\t\t\twsptr++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tz2 = DEQUANTIZE(inptr[DCTSIZE * 2], quantptr[DCTSIZE * 2]);\n\t\tz3 = DEQUANTIZE(inptr[DCTSIZE * 6], quantptr[DCTSIZE * 6]);\n\n\t\tz1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */\n\t\ttmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */\n\t\ttmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */\n\n\t\tz2 = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]);\n\t\tz3 = DEQUANTIZE(inptr[DCTSIZE * 4], quantptr[DCTSIZE * 4]);\n\t\tz2 <<= CONST_BITS;\n\t\tz3 <<= CONST_BITS;\n\t\t/* Add fudge factor here for final descale. */\n\t\tz2 += ONE << (CONST_BITS - PASS1_BITS - 1);\n\n\t\ttmp0 = z2 + z3;\n\t\ttmp1 = z2 - z3;\n\n\t\ttmp10 = tmp0 + tmp2;\n\t\ttmp13 = tmp0 - tmp2;\n\t\ttmp11 = tmp1 + tmp3;\n\t\ttmp12 = tmp1 - tmp3;\n\n\t\t/* Odd part per figure 8; the matrix is unitary and hence its\n\t\t* transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.\n\t\t*/\n\n\t\ttmp0 = DEQUANTIZE(inptr[DCTSIZE * 7], quantptr[DCTSIZE * 7]);\n\t\ttmp1 = DEQUANTIZE(inptr[DCTSIZE * 5], quantptr[DCTSIZE * 5]);\n\t\ttmp2 = DEQUANTIZE(inptr[DCTSIZE * 3], quantptr[DCTSIZE * 3]);\n\t\ttmp3 = DEQUANTIZE(inptr[DCTSIZE * 1], quantptr[DCTSIZE * 1]);\n\n\t\tz2 = tmp0 + tmp2;\n\t\tz3 = tmp1 + tmp3;\n\n\t\tz1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */\n\t\tz2 = MULTIPLY(z2, -FIX_1_961570560);          /* -c3-c5 */\n\t\tz3 = MULTIPLY(z3, -FIX_0_390180644);          /* -c3+c5 */\n\t\tz2 += z1;\n\t\tz3 += z1;\n\n\t\tz1 = MULTIPLY(tmp0 + tmp3, -FIX_0_899976223); /* -c3+c7 */\n\t\ttmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */\n\t\ttmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */\n\t\ttmp0 += z1 + z2;\n\t\ttmp3 += z1 + z3;\n\n\t\tz1 = MULTIPLY(tmp1 + tmp2, -FIX_2_562915447); /* -c1-c3 */\n\t\ttmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */\n\t\ttmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */\n\t\ttmp1 += z1 + z3;\n\t\ttmp2 += z1 + z2;\n\n\t\t/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */\n\n\t\twsptr[DCTSIZE * 0] = (int)RIGHT_SHIFT(tmp10 + tmp3, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 7] = (int)RIGHT_SHIFT(tmp10 - tmp3, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 1] = (int)RIGHT_SHIFT(tmp11 + tmp2, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 6] = (int)RIGHT_SHIFT(tmp11 - tmp2, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 2] = (int)RIGHT_SHIFT(tmp12 + tmp1, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 5] = (int)RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 3] = (int)RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS - PASS1_BITS);\n\t\twsptr[DCTSIZE * 4] = (int)RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS - PASS1_BITS);\n\n\t\tinptr++;\t\t\t/* advance pointers to next column */\n\t\tquantptr++;\n\t\twsptr++;\n\t}\n\t/* Pass 2: process rows from work array, store into output array.\n\t* Note that we must descale the results by a factor of 8 == 2**3,\n\t* and also undo the PASS1_BITS scaling.\n\t*/\n\twsptr = workspace;\n\tfor (ctr = 0; ctr < DCTSIZE; ctr++, outptr += outpitch) {\n\t\tif (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&\n\t\t\twsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {\n\t\t\t/* AC terms all zero */\n#define RANGE_MASK  (255 * 4 + 3) /* 2 bits wider than legal samples */\n\t\t\ttjs_uint8 dcval = range_limit(DESCALE((int)wsptr[0], PASS1_BITS + 3) + 128);\n\t\t\toutptr[0] = dcval;\n\t\t\toutptr[1] = dcval;\n\t\t\toutptr[2] = dcval;\n\t\t\toutptr[3] = dcval;\n\t\t\toutptr[4] = dcval;\n\t\t\toutptr[5] = dcval;\n\t\t\toutptr[6] = dcval;\n\t\t\toutptr[7] = dcval;\n\n\t\t\twsptr += DCTSIZE;\t\t/* advance pointer to next row */\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Even part: reverse the even part of the forward DCT.\n\t\t* The rotator is c(-6).\n\t\t*/\n\n\t\tz2 = (int32_t)wsptr[2];\n\t\tz3 = (int32_t)wsptr[6];\n\n\t\tz1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */\n\t\ttmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */\n\t\ttmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */\n\n\t\t/* Add fudge factor here for final descale. */\n\t\tz2 = (int32_t)wsptr[0] + (ONE << (PASS1_BITS + 2));\n\t\tz3 = (int32_t)wsptr[4];\n\n\t\ttmp0 = (z2 + z3) << CONST_BITS;\n\t\ttmp1 = (z2 - z3) << CONST_BITS;\n\n\t\ttmp10 = tmp0 + tmp2;\n\t\ttmp13 = tmp0 - tmp2;\n\t\ttmp11 = tmp1 + tmp3;\n\t\ttmp12 = tmp1 - tmp3;\n\n\t\t/* Odd part per figure 8; the matrix is unitary and hence its\n\t\t* transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.\n\t\t*/\n\n\t\ttmp0 = (int32_t)wsptr[7];\n\t\ttmp1 = (int32_t)wsptr[5];\n\t\ttmp2 = (int32_t)wsptr[3];\n\t\ttmp3 = (int32_t)wsptr[1];\n\n\t\tz2 = tmp0 + tmp2;\n\t\tz3 = tmp1 + tmp3;\n\n\t\tz1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */\n\t\tz2 = MULTIPLY(z2, -FIX_1_961570560);          /* -c3-c5 */\n\t\tz3 = MULTIPLY(z3, -FIX_0_390180644);          /* -c3+c5 */\n\t\tz2 += z1;\n\t\tz3 += z1;\n\n\t\tz1 = MULTIPLY(tmp0 + tmp3, -FIX_0_899976223); /* -c3+c7 */\n\t\ttmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */\n\t\ttmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */\n\t\ttmp0 += z1 + z2;\n\t\ttmp3 += z1 + z3;\n\n\t\tz1 = MULTIPLY(tmp1 + tmp2, -FIX_2_562915447); /* -c1-c3 */\n\t\ttmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */\n\t\ttmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */\n\t\ttmp1 += z1 + z3;\n\t\ttmp2 += z1 + z2;\n\n\t\t/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */\n\n\t\toutptr[0] = range_limit((int)RIGHT_SHIFT(tmp10 + tmp3,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[7] = range_limit((int)RIGHT_SHIFT(tmp10 - tmp3,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[1] = range_limit((int)RIGHT_SHIFT(tmp11 + tmp2,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[6] = range_limit((int)RIGHT_SHIFT(tmp11 - tmp2,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[2] = range_limit((int)RIGHT_SHIFT(tmp12 + tmp1,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[5] = range_limit((int)RIGHT_SHIFT(tmp12 - tmp1,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[3] = range_limit((int)RIGHT_SHIFT(tmp13 + tmp0,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\t\toutptr[4] = range_limit((int)RIGHT_SHIFT(tmp13 - tmp0,\n\t\t\tCONST_BITS + PASS1_BITS + 3)\n\t\t\t+ 128);\n\n\t\twsptr += DCTSIZE;\t\t/* advance pointer to next row */\n\t}\n}\n"
  },
  {
    "path": "src/core/visual/ARM/tvpgl_arm.cpp",
    "content": "#include \"tvpgl_arm_intf.h\"\n#include \"tvpgl_asm_init.h\"\n#include <arm_neon.h>\n#include <assert.h>\n#include <string.h>\n#include <stdarg.h>\n\n//#define TEST_ARM_NEON_CODE\n//#define DEBUG_ARM_NEON\n//#define LOG_NEON_TEST\n\n#ifdef __cplusplus\n#if defined(_MSC_VER)\n#include <opencv2/core/mat.hpp>\n#endif\n#include <vector>\nextern \"C\" {\n#endif\nextern unsigned char TVPNegativeMulTable[256*256];\nextern unsigned char TVPOpacityOnOpacityTable[256*256];\nextern unsigned short TVPRecipTableForOpacityOnOpacity[256];\n#ifdef __cplusplus\n};\n#endif\n\n#define __CAT_NAME(a, b) a##b\n#define _CAT_NAME(a, b) __CAT_NAME(a, b)\n\ntemplate <int elmcount, typename TElmDst, typename TElmSrc, typename TDst, typename TSrc,\n\ttypename LoadFuncS, typename LoadFuncD, typename StoreFunc, typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_blend_(LoadFuncS lfuncs, LoadFuncD lfuncd, StoreFunc sfunc, CFunc c_func, OPFunc op_func, TDst *dest, const TSrc *src, tjs_int len, TArg... args) {\n\tTDst* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & (elmcount - 1))) & (elmcount - 1)) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, src, PreFragLen, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsrc += PreFragLen;\n\t\t}\n\t}\n\n\tTDst* pVecEndDst = pEndDst - elmcount + 1;\n\tif ((intptr_t)src & (elmcount - 1)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tTElmSrc s = lfuncs((uint8_t *)src);\n\t\t\tTElmDst d = lfuncd((uint8_t *)__builtin_assume_aligned(dest, elmcount));\n\t\t\td = op_func(s, d, args...);\n\t\t\tsfunc((uint8_t *)__builtin_assume_aligned(dest, elmcount), d);\n\t\t\tdest += elmcount;\n\t\t\tsrc += elmcount;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tTElmSrc s = lfuncs((uint8_t *)__builtin_assume_aligned(src, elmcount));\n\t\t\tTElmDst d = lfuncd((uint8_t *)__builtin_assume_aligned(dest, elmcount));\n\t\t\td = op_func(s, d, args...);\n\t\t\tsfunc((uint8_t *)__builtin_assume_aligned(dest, elmcount), d);\n\t\t\tdest += elmcount;\n\t\t\tsrc += elmcount;\n\t\t}\n\t}\n\n\tif (dest < pEndDst) {\n\t\tc_func(dest, src, pEndDst - dest, args...);\n\t}\n}\n\nstatic uint8x8_t __vld1_u8(uint8_t* p) { return vld1_u8(p); }\nstatic uint8x8x4_t __vld4_u8(uint8_t* p) { return vld4_u8(p); }\nstatic void __vst4_u8(uint8_t* p, uint8x8x4_t v) { return vst4_u8(p, v); }\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, TArg... args) {\n\tdo_blend_<8, uint8x8x4_t, uint8x8x4_t>(__vld4_u8, __vld4_u8, __vst4_u8, c_func, op_func, dest, src, len, args...);\n}\nstatic uint8x16x4_t __vld4q_u8(uint8_t* p) {\n\t__builtin_prefetch(p, 0, 0);\n\treturn vld4q_u8(p);\n}\nstatic void __vst4q_u8(uint8_t* p, uint8x16x4_t v) { return vst4q_u8(p, v); }\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_blend_128(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, TArg... args) {\n\tdo_blend_<16, uint8x16x4_t, uint8x16x4_t>(__vld4q_u8, __vld4q_u8, __vst4q_u8, c_func, op_func, dest, src, len, args...);\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_blend_lum(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, TArg... args) {\n\tdo_blend_<8, uint8x8x4_t, uint8x8_t>(__vld1_u8, __vld4_u8, __vst4_u8, c_func, op_func, dest, src, len, args...);\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_stretch_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len,\n\tconst tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, PreFragLen, src, srcstart, srcstep, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsrcstart += PreFragLen * srcstep;\n\t\t}\n\t}\n\tuint8_t strechbuff[32 + 16];\n\ttjs_uint32 *tmp = (tjs_uint32*)((((intptr_t)strechbuff) + 7) & ~7);\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\twhile (dest < pVecEndDst) {\n\t\tfor (int i = 0; i < 8; ++i) {\n\t\t\ttmp[i] = src[(srcstart) >> 16];\n\t\t\tsrcstart += srcstep;\n\t\t}\n\t\tuint8x8x4_t s = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp, 8));\n\t\tuint8x8x4_t d = vld4_u8((uint8_t *)__builtin_assume_aligned(dest, 8));\n\t\td = op_func(s, d, args...);\n\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\tdest += 8;\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, pEndDst - dest, src, srcstart, srcstep, args...);\n\t}\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_lintrans_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len,\n\tconst tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, PreFragLen, src, sx, sy, stepx, stepy, srcpitch, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsx += stepx * PreFragLen;\n\t\t\tsy += stepy * PreFragLen;\n\t\t}\n\t}\n\tuint8_t strechbuff[32 + 16];\n\ttjs_uint32 *tmp = (tjs_uint32*)((((intptr_t)strechbuff) + 7) & ~7);\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\twhile (dest < pVecEndDst) {\n\t\tfor (int i = 0; i < 8; ++i) {\n\t\t\ttmp[i] = *((const tjs_uint32*)((const tjs_uint8*)src + ((sy) >> 16)*srcpitch) + ((sx) >> 16));\n\t\t\tsx += stepx;\n\t\t\tsy += stepy;\n\t\t}\n\t\tuint8x8x4_t s = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp, 8));\n\t\tuint8x8x4_t d = vld4_u8((uint8_t *)__builtin_assume_aligned(dest, 8));\n\t\td = op_func(s, d, args...);\n\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\tdest += 8;\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, pEndDst - dest, src, sx, sy, stepx, stepy, srcpitch, args...);\n\t}\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_interp_stretch_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len,\n\tconst tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int _blend_y, tjs_int srcstart, tjs_int srcstep, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, PreFragLen, src1, src2, _blend_y, srcstart, srcstep, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsrcstart += PreFragLen * srcstep;\n\t\t}\n\t}\n\ttjs_int blend_y = _blend_y + (_blend_y >> 7); /* adjust blend ratio */\n\n\tuint8_t tmpbuff[4 * 8 * 3 + 16];\n\ttjs_uint32 *tmp1_0 = (tjs_uint32*)((((intptr_t)tmpbuff) + 15) & ~15);\n\ttjs_uint32 *tmp1_1 = tmp1_0 + 8;\n\tuint16_t *blend_x = (uint16_t *)__builtin_assume_aligned(tmp1_1 + 8, 8);\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\twhile (dest < pVecEndDst) {\n\t\ttjs_int start = srcstart;\n\t\tfor (int i = 0; i < 8; ++i) {\n\t\t\tint addr = start >> 16;\n\t\t\ttmp1_0[i] = src2[addr];\n\t\t\ttmp1_1[i] = src2[addr + 1];\n\t\t\tblend_x[i] = (start & 0xffff) >> 8;\n\t\t\tstart += srcstep;\n\t\t}\n\t\t// TVPBlendARGB(src2[sp], src2[sp+1], blend_x)\n\t\tuint8x8x4_t b = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_0, 8));\n\t\tuint8x8x4_t a = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_1, 8));\n\t\tuint16x8_t ratio = vld1q_u16(blend_x); // qreg = 5\n\t\t// TVPBlendARGB: a * ratio + b * (1 - ratio) => b + (a - b) * ratio\n\t\tuint16x8_t s_a16 = vmulq_u16(vsubl_u8(a.val[3], b.val[3]), ratio);\n\t\tuint16x8_t s_r16 = vmulq_u16(vsubl_u8(a.val[2], b.val[2]), ratio);\n\t\tuint16x8_t s_g16 = vmulq_u16(vsubl_u8(a.val[1], b.val[1]), ratio);\n\t\tuint16x8_t s_b16 = vmulq_u16(vsubl_u8(a.val[0], b.val[0]), ratio); // qreg = 9\n\n\t\tuint8x8x4_t s_argb8;\n\t\ts_argb8.val[3] = vadd_u8(b.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts_argb8.val[2] = vadd_u8(b.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts_argb8.val[1] = vadd_u8(b.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts_argb8.val[0] = vadd_u8(b.val[0], vshrn_n_u16(s_b16, 8)); // qreg = 11\n\n\t\tstart = srcstart;\n\t\tfor (int i = 0; i < 8; ++i) {\n\t\t\tint addr = (start) >> 16;\n\t\t\ttmp1_0[i] = src1[addr];\n\t\t\ttmp1_1[i] = src1[addr + 1];\n\t\t\tstart += srcstep;\n\t\t}\n\t\t// TVPBlendARGB(src1[sp], src1[sp+1], blend_x)\n\t\tb = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_0, 8));\n\t\ta = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_1, 8));\n\t\ts_a16 = vmulq_u16(vsubl_u8(a.val[3], b.val[3]), ratio);\n\t\ts_r16 = vmulq_u16(vsubl_u8(a.val[2], b.val[2]), ratio);\n\t\ts_g16 = vmulq_u16(vsubl_u8(a.val[1], b.val[1]), ratio);\n\t\ts_b16 = vmulq_u16(vsubl_u8(a.val[0], b.val[0]), ratio);\n\t\tuint8x8x4_t s2;\n\t\ts2.val[3] = vadd_u8(b.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts2.val[2] = vadd_u8(b.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts2.val[1] = vadd_u8(b.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts2.val[0] = vadd_u8(b.val[0], vshrn_n_u16(s_b16, 8)); // qreg = 13\n\t\ts_a16 = vmulq_n_u16(vsubl_u8(s_argb8.val[3], s2.val[3]), blend_y);\n\t\ts_r16 = vmulq_n_u16(vsubl_u8(s_argb8.val[2], s2.val[2]), blend_y);\n\t\ts_g16 = vmulq_n_u16(vsubl_u8(s_argb8.val[1], s2.val[1]), blend_y);\n\t\ts_b16 = vmulq_n_u16(vsubl_u8(s_argb8.val[0], s2.val[0]), blend_y);\n\t\ts_argb8.val[3] = vadd_u8(s2.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts_argb8.val[2] = vadd_u8(s2.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts_argb8.val[1] = vadd_u8(s2.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts_argb8.val[0] = vadd_u8(s2.val[0], vshrn_n_u16(s_b16, 8));\n\t\tuint8x8x4_t d_argb8 = vld4_u8((uint8_t *)__builtin_assume_aligned(dest, 8));\n\t\td_argb8 = op_func(s_argb8, d_argb8, args...);\n\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d_argb8);\n\t\tsrcstart = start;\n\t\tdest += 8;\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, pEndDst - dest, src1, src2, _blend_y, srcstart, srcstep, args...);\n\t}\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_interp_lintrans_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len,\n\tconst tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, PreFragLen, src, sx, sy, stepx, stepy, srcpitch, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsx += stepx * PreFragLen;\n\t\t\tsy += stepy * PreFragLen;\n\t\t}\n\t}\n\tuint8_t tmpbuff[4 * 8 * 4 + 2 * 8 * 2 + 16];\n\ttjs_uint32 *tmp0_0 = (tjs_uint32*)((((intptr_t)tmpbuff) + 15) & ~15);\n\ttjs_uint32 *tmp0_1 = tmp0_0 + 8;\n\ttjs_uint32 *tmp1_0 = tmp0_1 + 8;\n\ttjs_uint32 *tmp1_1 = tmp1_0 + 8;\n\tuint16_t *blend_x = (uint16_t *)__builtin_assume_aligned(tmp1_1 + 8, 8);\n\tuint16_t *blend_y = (uint16_t *)__builtin_assume_aligned(blend_x + 8, 8);\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\twhile (dest < pVecEndDst) {\n\t\tfor (int i = 0; i < 8; ++i) {\n\t\t\tconst tjs_uint32 *p0, *p1;\n\t\t\tint bld_x, bld_y;\n\t\t\tbld_x = (sx & 0xffff) >> 8;\n\t\t\tbld_x += bld_x >> 7;\n\t\t\tbld_y = (sy & 0xffff) >> 8;\n\t\t\tbld_y += bld_y >> 7;\n\t\t\tblend_x[i] = bld_x;\n\t\t\tblend_y[i] = bld_y;\n\n\t\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy >> 16))*srcpitch) + (sx >> 16);\n\t\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\n\t\t\ttmp0_0[i] = p0[0];\n\t\t\ttmp0_1[i] = p0[1];\n\t\t\ttmp1_0[i] = p1[0];\n\t\t\ttmp1_1[i] = p1[1];\n\n\t\t\tsx += stepx;\n\t\t\tsy += stepy;\n\t\t}\n\t\t// TVPBlendARGB(src2[sp], src2[sp+1], blend_x)\n\t\tuint8x8x4_t b = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_0, 8));\n\t\tuint8x8x4_t a = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp1_1, 8));\n\t\tuint16x8_t ratio = vld1q_u16(blend_x); // qreg = 5\n\t\t// TVPBlendARGB: a * ratio + b * (1 - ratio) => b + (a - b) * ratio\n\t\tuint16x8_t s_a16 = vmulq_u16(vsubl_u8(a.val[3], b.val[3]), ratio);\n\t\tuint16x8_t s_r16 = vmulq_u16(vsubl_u8(a.val[2], b.val[2]), ratio);\n\t\tuint16x8_t s_g16 = vmulq_u16(vsubl_u8(a.val[1], b.val[1]), ratio);\n\t\tuint16x8_t s_b16 = vmulq_u16(vsubl_u8(a.val[0], b.val[0]), ratio); // qreg = 9\n\n\t\tuint8x8x4_t s_argb8;\n\t\ts_argb8.val[3] = vadd_u8(b.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts_argb8.val[2] = vadd_u8(b.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts_argb8.val[1] = vadd_u8(b.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts_argb8.val[0] = vadd_u8(b.val[0], vshrn_n_u16(s_b16, 8)); // qreg = 11\n\n\t\tb = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp0_0, 8));\n\t\ta = vld4_u8((uint8_t *)__builtin_assume_aligned(tmp0_1, 8));\n\t\ts_a16 = vmulq_u16(vsubl_u8(a.val[3], b.val[3]), ratio);\n\t\ts_r16 = vmulq_u16(vsubl_u8(a.val[2], b.val[2]), ratio);\n\t\ts_g16 = vmulq_u16(vsubl_u8(a.val[1], b.val[1]), ratio);\n\t\ts_b16 = vmulq_u16(vsubl_u8(a.val[0], b.val[0]), ratio);\n\t\tuint8x8x4_t s2;\n\t\ts2.val[3] = vadd_u8(b.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts2.val[2] = vadd_u8(b.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts2.val[1] = vadd_u8(b.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts2.val[0] = vadd_u8(b.val[0], vshrn_n_u16(s_b16, 8)); // qreg = 13\n\n\t\tratio = vld1q_u16(blend_y);\n\t\ts_a16 = vmulq_u16(vsubl_u8(s_argb8.val[3], s2.val[3]), ratio);\n\t\ts_r16 = vmulq_u16(vsubl_u8(s_argb8.val[2], s2.val[2]), ratio);\n\t\ts_g16 = vmulq_u16(vsubl_u8(s_argb8.val[1], s2.val[1]), ratio);\n\t\ts_b16 = vmulq_u16(vsubl_u8(s_argb8.val[0], s2.val[0]), ratio);\n\t\ts_argb8.val[3] = vadd_u8(s2.val[3], vshrn_n_u16(s_a16, 8));\n\t\ts_argb8.val[2] = vadd_u8(s2.val[2], vshrn_n_u16(s_r16, 8));\n\t\ts_argb8.val[1] = vadd_u8(s2.val[1], vshrn_n_u16(s_g16, 8));\n\t\ts_argb8.val[0] = vadd_u8(s2.val[0], vshrn_n_u16(s_b16, 8));\n\t\tuint8x8x4_t d_argb8 = vld4_u8((uint8_t *)__builtin_assume_aligned(dest, 8));\n\t\td_argb8 = op_func(s_argb8, d_argb8, args...);\n\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d_argb8);\n\t\tdest += 8;\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, pEndDst - dest, src, sx, sy, stepx, stepy, srcpitch, args...);\n\t}\n}\n\ntemplate <typename TElm, int elmcount, typename LoadFunc, typename StoreFunc, typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_apply_pixel_(LoadFunc lfunc, StoreFunc sfunc, CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, PreFragLen, args...);\n\t\t\tdest += PreFragLen;\n\t\t}\n\t}\n\ttjs_uint32* pVecEndDst = pEndDst - elmcount + 1;\n\twhile (dest < pVecEndDst) {\n\t\tTElm d = lfunc((uint8_t *)__builtin_assume_aligned(dest, 8));\n\t\td = op_func(d, args...);\n\t\tsfunc((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\tdest += 8;\n\t}\n\n\tif (dest < pEndDst) {\n\t\tc_func(dest, pEndDst - dest, args...);\n\t}\n}\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_apply_pixel(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, tjs_int len, TArg... args) {\n\tdo_apply_pixel_<uint8x8x4_t, 8>(__vld4_u8, __vst4_u8, c_func, op_func, dest, len, args...);\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_blend_2(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\t{\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tif (PreFragLen) {\n\t\t\tc_func(dest, src1, src2, PreFragLen, args...);\n\t\t\tdest += PreFragLen;\n\t\t\tsrc1 += PreFragLen;\n\t\t\tsrc2 += PreFragLen;\n\t\t}\n\t}\n\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\tif (((intptr_t)src1 & 7) || ((intptr_t)src2 & 7)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 4));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 4));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, args...);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 8;\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 8));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 8));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, args...);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 8;\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t}\n\t}\n\n\tif (dest < pEndDst) {\n\t\tc_func(dest, src1, src2, pEndDst - dest, args...);\n\t}\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_univ_blend(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\ttjs_int PreFragLen = (tjs_uint32*)((((intptr_t)dest) + 7)&~7) - dest;\n\tif (PreFragLen > len) PreFragLen = len;\n\tif (PreFragLen) {\n\t\tc_func(dest, src1, src2, rule, table, PreFragLen, args...);\n\t\tdest += PreFragLen;\n\t\tsrc1 += PreFragLen;\n\t\tsrc2 += PreFragLen;\n\t\trule += PreFragLen;\n\t}\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\tif (((intptr_t)src1 & 7) || ((intptr_t)src2 & 7)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8_t opa;\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 0);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 1);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 2);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 3);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 4);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 5);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 6);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 7);\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 4));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 4));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, opa);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t\tdest += 8;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8_t opa;\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 0);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 1);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 2);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 3);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 4);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 5);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 6);\n\t\t\topa = vset_lane_u8(table[*rule++], opa, 7);\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 8));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 8));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, opa);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t\tdest += 8;\n\t\t}\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, src1, src2, rule, table, pEndDst - dest);\n\t}\n}\n\ntemplate <typename CFunc, typename OPFunc, typename ...TArg>\nvoid do_univ_switch(CFunc c_func, OPFunc op_func, tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv, TArg... args) {\n\ttjs_uint32* pEndDst = dest + len;\n\ttjs_int PreFragLen = (tjs_uint32*)((((intptr_t)dest) + 7)&~7) - dest;\n\tif (PreFragLen > len) PreFragLen = len;\n\tif (PreFragLen) {\n\t\tc_func(dest, src1, src2, rule, table, PreFragLen, src1lv, src2lv, args...);\n\t\tdest += PreFragLen;\n\t\tsrc1 += PreFragLen;\n\t\tsrc2 += PreFragLen;\n\t\trule += PreFragLen;\n\t}\n\ttjs_uint32* pVecEndDst = pEndDst - 7;\n\tif (((intptr_t)src1 & 7) || ((intptr_t)src2 & 7)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8_t opa; tjs_int o;\n#define SET_LANE(i) \\\n\to = *rule++; if (o >= src1lv) { o = 0; } else if (o < src2lv) { o = 255; } else { o = table[o]; } opa = vset_lane_u8(o, opa, i)\n\t\t\tSET_LANE(0); SET_LANE(1); SET_LANE(2); SET_LANE(3); SET_LANE(4); SET_LANE(5); SET_LANE(6); SET_LANE(7);\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 4));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 4));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, opa);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t\tdest += 8;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8_t opa; tjs_int o;\n\t\t\tSET_LANE(0); SET_LANE(1); SET_LANE(2); SET_LANE(3); SET_LANE(4); SET_LANE(5); SET_LANE(6); SET_LANE(7);\n#undef SET_LANE\n\t\t\tuint8x8x4_t s1 = vld4_u8((uint8_t *)__builtin_assume_aligned(src1, 8));\n\t\t\tuint8x8x4_t s2 = vld4_u8((uint8_t *)__builtin_assume_aligned(src2, 8));\n\t\t\tuint8x8x4_t d = op_func(s2, s1, opa);\n\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tsrc1 += 8;\n\t\t\tsrc2 += 8;\n\t\t\tdest += 8;\n\t\t}\n\t}\n\tif (dest < pEndDst) {\n\t\tc_func(dest, src1, src2, rule, table, pEndDst - dest, src1lv, src2lv, args...);\n\t}\n}\n\ntemplate<typename TFunc, typename ...TArg>\nuint8x8x4_t do_SrcAlphaBranch(uint8x8x4_t s, uint8x8x4_t d, TFunc func, TArg... args) {\n\tuint64_t a = vget_lane_u64(vreinterpret_u64_u8(s.val[3]), 0);\n\tif (!a) {\n\t\treturn d;\n\t} else if (!~a) {\n\t\treturn s;\n\t}\n\treturn func(s, d, args...);\n}\ntemplate<typename TFunc, typename ...TArg>\nuint8x8x4_t do_SrcAddAlphaBranch(uint8x8x4_t s, uint8x8x4_t d, TFunc func, TArg... args) {\n\tuint64_t a = vget_lane_u64(vreinterpret_u64_u8(s.val[3]), 0);\n\tif (!a) {\n\t\treturn d;\n\t}\n\treturn func(s, d, args...);\n}\nstatic uint8x8x4_t do_copy_src(uint8x8x4_t s, uint8x8x4_t d) {\n\treturn s;\n}\n\n#ifndef Region_AlphaBlend\nstatic uint8x8x4_t do_AlphaBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\t// d + s * a - d * a\n\td.val[0] = vadd_u8(d.val[0], vsubhn_u16(vmull_u8(s.val[0], s.val[3]), vmull_u8(d.val[0], s.val[3])));\n\td.val[1] = vadd_u8(d.val[1], vsubhn_u16(vmull_u8(s.val[1], s.val[3]), vmull_u8(d.val[1], s.val[3])));\n\td.val[2] = vadd_u8(d.val[2], vsubhn_u16(vmull_u8(s.val[2], s.val[3]), vmull_u8(d.val[2], s.val[3])));\n\treturn d;\n}\nstatic uint8x8x4_t do_AlphaBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vshrn_n_u16(vmull_u8(s.val[3], vdup_n_u8(opa)), 8);\n\treturn do_AlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_AlphaBlend_d_(uint8x8x4_t s, uint8x8x4_t d, uint16x8_t sopa) {\n\tuint8_t tmpbuff[32 + 16];\n\tuint16_t *tmpsa = (uint16_t*)((((intptr_t)tmpbuff) + 15) & ~15);\n\tvst1q_u16((uint16_t *)__builtin_assume_aligned(tmpsa, 16), sopa);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[0]], s.val[3], 0);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[1]], s.val[3], 1);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[2]], s.val[3], 2);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[3]], s.val[3], 3);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[4]], s.val[3], 4);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[5]], s.val[3], 5);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[6]], s.val[3], 6);\n\ts.val[3] = vset_lane_u8(TVPOpacityOnOpacityTable[tmpsa[7]], s.val[3], 7);\n\treturn do_AlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_AlphaBlend_d(uint8x8x4_t s, uint8x8x4_t d) {\n\t//( 255 - (255-a)*(255-b)/ 255 ); \n\tuint16x8_t isd_a16 = vmull_u8(vmvn_u8(s.val[3]), vmvn_u8(d.val[3]));\n\tuint16x8_t sopa = vorrq_u16(vshll_n_u8(s.val[3], 8), vmovl_u8(d.val[3]));\n\td.val[3] = vmvn_u8(vshrn_n_u16(isd_a16, 8));\n\treturn do_AlphaBlend_d_(s, d, sopa);\n}\nstatic uint8x8x4_t do_AlphaBlend_do(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t s_a16 = vmull_u8(s.val[3], opa8);\n\ts.val[3] = vshrn_n_u16(s_a16, 8);\n\treturn do_AlphaBlend_d(s, d);\n}\nstatic uint8x8x4_t do_AddAlphaBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[3] = vmvn_u8(s.val[3]);\n\t// s + d * (1 - sa)\n\tuint16x8_t d_r16 = vmull_u8(d.val[2], s.val[3]);\n\tuint16x8_t d_g16 = vmull_u8(d.val[1], s.val[3]);\n\tuint16x8_t d_b16 = vmull_u8(d.val[0], s.val[3]);\n\n\t// 8-bit to do saturated add\n\td.val[2] = vqadd_u8(vshrn_n_u16(d_r16, 8), s.val[2]);\n\td.val[1] = vqadd_u8(vshrn_n_u16(d_g16, 8), s.val[1]);\n\td.val[0] = vqadd_u8(vshrn_n_u16(d_b16, 8), s.val[0]);\n\n\treturn d;\n}\nstatic uint8x8x4_t do_ConvertAlphaToAdditiveAlpha(uint8x8x4_t s) {\n\ts.val[2] = vshrn_n_u16(vmull_u8(s.val[2], s.val[3]), 8);\n\ts.val[1] = vshrn_n_u16(vmull_u8(s.val[1], s.val[3]), 8);\n\ts.val[0] = vshrn_n_u16(vmull_u8(s.val[0], s.val[3]), 8);\n\treturn s;\n}\nstatic uint8x8x4_t do_AlphaBlend_da(uint8x8x4_t s, uint8x8x4_t d) {\n\t//Da = Sa + Da - SaDa = Sa + (1 - Sa)Da\n\tuint16x8_t a16 = vmull_u8(vmvn_u8(s.val[3]), d.val[3]);\n\tuint8x8_t tmp = vshrn_n_u16(a16, 8);\n\td.val[3] = vadd_u8(s.val[3], tmp);\n\treturn d;\n}\nstatic uint8x8x4_t do_AlphaBlend_a(uint8x8x4_t s, uint8x8x4_t d) {\n\td = do_AlphaBlend_da(s, d);\n\ts = do_ConvertAlphaToAdditiveAlpha(s);\n\treturn do_AddAlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_AlphaBlend_ao(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t s_a16 = vmull_u8(s.val[3], opa8);\n\ts.val[3] = vshrn_n_u16(s_a16, 8);\n\treturn do_AlphaBlend_a(s, d);\n}\nstatic uint8x8x4_t do_ConstAlphaBlend(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\treturn do_AlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_ConstAlphaBlend_d(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\treturn do_AlphaBlend_d(s, d);\n}\nstatic uint8x8x4_t do_ConstAlphaBlend_a(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\td = do_AlphaBlend_da(s, d);\n\treturn do_AddAlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_ConstAlphaBlend_SD(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\td.val[3] = vadd_u8(d.val[3], vsubhn_u16(vmull_u8(s.val[3], vdup_n_u8(opa)), vmull_u8(d.val[3], vdup_n_u8(opa))));\n\treturn do_ConstAlphaBlend(s, d, opa);\n}\nstatic uint8x8x4_t do_ConstAlphaBlend_SD_d(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t sa = vmull_u8(s.val[3], opa8);\n\tuint8x8_t a = vadd_u8(d.val[3], vsubhn_u16(sa, vmull_u8(d.val[3], opa8)));\n\ts.val[3] = vshrn_n_u16(sa, 8);\n\td.val[3] = vshrn_n_u16(vmull_u8(d.val[3], vdup_n_u8(~opa)), 8);\n\td = do_AlphaBlend_d(s, d);\n\td.val[3] = a;\n\treturn d;\n}\nstatic uint8x8x4_t do_ConstAlphaBlend_SD_a(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\td.val[3] = vadd_u8(d.val[3], vsubhn_u16(vmull_u8(s.val[3], vdup_n_u8(opa)), vmull_u8(d.val[3], vdup_n_u8(opa))));\n\treturn do_ConstAlphaBlend(s, d, opa);\n}\n#endif\n\nstatic uint8x8x4_t do_AlphaColorMat(uint8x8x4_t s, tjs_uint32 color) {\n\tuint8x8x4_t d;\n\td.val[0] = vdup_n_u8(color & 0xff);\n\td.val[1] = vdup_n_u8((color >> 8) & 0xff);\n\td.val[2] = vdup_n_u8((color >> 16) & 0xff);\n\td.val[3] = vdup_n_u8(0xff);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPAlphaColorMat_frag(tjs_uint32 *dest, tjs_int len, const tjs_uint32 color) {\n\tTVPAlphaColorMat_c(dest, color, len);\n}\nstatic void TVPAlphaColorMat_NEON(tjs_uint32 *dest, const tjs_uint32 color, tjs_int len) {\n\tdo_apply_pixel(TVPAlphaColorMat_frag, do_AlphaColorMat, dest, len, color);\n}\n\n#ifndef Region_AdditiveAlphaBlend\n\nstatic uint8x8x4_t do_AddAlphaBlendSrc(uint8x8x4_t s, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t s_a16 = vmull_u8(s.val[3], opa8);\n\tuint16x8_t s_r16 = vmull_u8(s.val[2], opa8);\n\tuint16x8_t s_g16 = vmull_u8(s.val[1], opa8);\n\tuint16x8_t s_b16 = vmull_u8(s.val[0], opa8);\n\ts.val[3] = vshrn_n_u16(s_a16, 8);\n\ts.val[2] = vshrn_n_u16(s_r16, 8);\n\ts.val[1] = vshrn_n_u16(s_g16, 8);\n\ts.val[0] = vshrn_n_u16(s_b16, 8);\n\treturn s;\n}\nstatic uint8x8x4_t do_AddAlphaBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts = do_AddAlphaBlendSrc(s, opa);\n\treturn do_AddAlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_AddAlphaBlend_a(uint8x8x4_t s, uint8x8x4_t d) {\n\t//Da = Sa + Da - SaDa\n\tuint16x8_t d_a16 = vmull_u8(s.val[3], d.val[3]);\n\tuint16x8_t t = vaddl_u8(s.val[3], d.val[3]);\n\td_a16 = vsubq_u16(t, vshrq_n_u16(d_a16, 8));\n\td.val[3] = vmovn_u16(vsubq_u16(d_a16, vshrq_n_u16(d_a16, 8)));\n\treturn do_AddAlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_AddAlphaBlend_ao(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts = do_AddAlphaBlendSrc(s, opa);\n\treturn do_AddAlphaBlend_a(s, d);\n}\n#endif\n\nstatic uint8x8x4_t do_AlphaBlend_branch(uint8x8x4_t s, uint8x8x4_t d) {\n\treturn do_SrcAlphaBranch(s, d, do_AlphaBlend);\n}\nstatic uint8x8x4_t do_AlphaBlend_a_branch(uint8x8x4_t s, uint8x8x4_t d) {\n\treturn do_SrcAddAlphaBranch(s, d, do_AlphaBlend_a);\n}\nstatic uint8x8x4_t do_AlphaBlend_d_branch(uint8x8x4_t s, uint8x8x4_t d) {\n\treturn do_SrcAlphaBranch(s, d, do_AlphaBlend_d);\n}\nstatic void TVPAlphaBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPAlphaBlend_HDA_c, do_AlphaBlend_branch, dest, src, len);\n}\nstatic void TVPAlphaBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAlphaBlend_HDA_o_c, do_AlphaBlend_o, dest, src, len, opa);\n}\nstatic void TVPAlphaBlend_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPAlphaBlend_a_c, do_AlphaBlend_a_branch, dest, src, len);\n}\nstatic void TVPAlphaBlend_ao_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAlphaBlend_ao_c, do_AlphaBlend_ao, dest, src, len, opa);\n}\nstatic void TVPAlphaBlend_d_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPAlphaBlend_d_c, do_AlphaBlend_d_branch, dest, src, len);\n}\nstatic void TVPAlphaBlend_do_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAlphaBlend_do_c, do_AlphaBlend_do, dest, src, len, opa);\n}\nstatic void TVPAdditiveAlphaBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPAdditiveAlphaBlend_HDA_c, do_AddAlphaBlend, dest, src, len);\n}\nstatic void TVPAdditiveAlphaBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAdditiveAlphaBlend_HDA_o_c, do_AddAlphaBlend_o, dest, src, len, opa);\n}\nstatic void TVPAdditiveAlphaBlend_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPAdditiveAlphaBlend_a_c, do_AddAlphaBlend_a, dest, src, len);\n}\nstatic void TVPAdditiveAlphaBlend_ao_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAdditiveAlphaBlend_ao_c, do_AddAlphaBlend_ao, dest, src, len, opa);\n}\nstatic void TVPConvertAlphaToAdditiveAlpha_NEON(tjs_uint32 *dest, tjs_int len) {\n\tdo_apply_pixel(TVPConvertAlphaToAdditiveAlpha_c, do_ConvertAlphaToAdditiveAlpha, dest, len);\n}\n\n#ifndef Region_StretchBlend\n\nstatic void TVPStretchAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_HDA_c, do_AlphaBlend_branch, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPStretchAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_HDA_o_c, do_AlphaBlend_o, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_a_c, do_AlphaBlend_a_branch, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPStretchAlphaBlend_ao_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_ao_c, do_AlphaBlend_ao, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchAlphaBlend_d_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_d_c, do_AlphaBlend_d_branch, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPStretchAlphaBlend_do_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchAlphaBlend_do_c, do_AlphaBlend_do, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchAdditiveAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchAdditiveAlphaBlend_HDA_c, do_AddAlphaBlend, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPStretchAdditiveAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchAdditiveAlphaBlend_HDA_o_c, do_AddAlphaBlend_o, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchAdditiveAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchAdditiveAlphaBlend_a_c, do_AddAlphaBlend_a, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPStretchAdditiveAlphaBlend_ao_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchAdditiveAlphaBlend_ao_c, do_AddAlphaBlend_ao, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPLinTransAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_HDA_c, do_AlphaBlend_branch, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPLinTransAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_HDA_o_c, do_AlphaBlend_o, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_a_c, do_AlphaBlend_a_branch, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPLinTransAlphaBlend_ao_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_ao_c, do_AlphaBlend_ao, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransAlphaBlend_d_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_d_c, do_AlphaBlend_d_branch, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPLinTransAlphaBlend_do_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_do_c, do_AlphaBlend_do, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransAdditiveAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_HDA_c, do_AddAlphaBlend, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPLinTransAdditiveAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_HDA_o_c, do_AddAlphaBlend_o, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransAdditiveAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_a_c, do_AddAlphaBlend_a, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPLinTransAdditiveAlphaBlend_ao_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransAlphaBlend_ao_c, do_AddAlphaBlend_ao, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPInterpStretchCopy_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int _blend_y, tjs_int srcstart, tjs_int srcstep) {\n\tdo_interp_stretch_blend(TVPInterpStretchCopy_c, do_copy_src, dest, len, src1, src2, _blend_y, srcstart, srcstep);\n}\nstatic void TVPInterpLinTransCopy_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_interp_lintrans_blend(TVPInterpLinTransCopy_c, do_copy_src, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPInterpStretchAdditiveAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int _blend_y, tjs_int srcstart, tjs_int srcstep) {\n\tdo_interp_stretch_blend(TVPInterpStretchAdditiveAlphaBlend_c, do_AddAlphaBlend, dest, len, src1, src2, _blend_y, srcstart, srcstep);\n}\nstatic void TVPInterpStretchAdditiveAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int _blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_interp_stretch_blend(TVPInterpStretchAdditiveAlphaBlend_o_c, do_AddAlphaBlend_o, dest, len, src1, src2, _blend_y, srcstart, srcstep, opa);\n}\nstatic void TVPInterpLinTransAdditiveAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_interp_lintrans_blend(TVPInterpLinTransAdditiveAlphaBlend_c, do_AddAlphaBlend, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\nstatic void TVPInterpLinTransAdditiveAlphaBlend_o_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_interp_lintrans_blend(TVPInterpLinTransAdditiveAlphaBlend_o_c, do_AddAlphaBlend_o, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPInterpStretchConstAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int _blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_interp_stretch_blend(TVPInterpStretchConstAlphaBlend_c, do_ConstAlphaBlend_SD, dest, len, src1, src2, _blend_y, srcstart, srcstep, opa);\n}\nstatic void TVPInterpLinTransConstAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_interp_lintrans_blend(TVPInterpLinTransConstAlphaBlend_c, do_ConstAlphaBlend_SD, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\n\n#endif\n\nstatic uint8x8x4_t do_CopyOpaqueImage_64(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[3] = vdup_n_u8(0xFF);\n\treturn s;\n}\nstatic uint8x16x4_t do_CopyOpaqueImage_128(uint8x16x4_t s) {\n\ts.val[3] = vdupq_n_u8(0xFF);\n\treturn s;\n}\nstatic void TVPCopyOpaqueImage_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPCopyOpaqueImage_c, do_CopyOpaqueImage_64, dest, src, len);\n}\nstatic void TVPStretchCopyOpaqueImage_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep) {\n\tdo_stretch_blend(TVPStretchCopyOpaqueImage_c, do_CopyOpaqueImage_64, dest, len, src, srcstart, srcstep);\n}\nstatic void TVPLinTransCopyOpaqueImage_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch) {\n\tdo_lintrans_blend(TVPLinTransCopyOpaqueImage_c, do_CopyOpaqueImage_64, dest, len, src, sx, sy, stepx, stepy, srcpitch);\n}\n\n#ifndef Region_ConstAlphaBlend\nstatic void TVPConstAlphaBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPConstAlphaBlend_HDA_c, do_ConstAlphaBlend, dest, src, len, opa);\n}\nstatic void TVPConstAlphaBlend_d_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPConstAlphaBlend_d_c, do_ConstAlphaBlend_d, dest, src, len, opa);\n}\nstatic void TVPConstAlphaBlend_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPConstAlphaBlend_a_c, do_ConstAlphaBlend_a, dest, src, len, opa);\n}\n\nstatic void TVPStretchConstAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchConstAlphaBlend_HDA_c, do_ConstAlphaBlend, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchConstAlphaBlend_d_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchConstAlphaBlend_d_c, do_ConstAlphaBlend_d, dest, len, src, srcstart, srcstep, opa);\n}\nstatic void TVPStretchConstAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa) {\n\tdo_stretch_blend(TVPStretchConstAlphaBlend_a_c, do_ConstAlphaBlend_a, dest, len, src, srcstart, srcstep, opa);\n}\n\nstatic void TVPLinTransConstAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransConstAlphaBlend_HDA_c, do_ConstAlphaBlend, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransConstAlphaBlend_d_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransConstAlphaBlend_d_c, do_ConstAlphaBlend_d, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\nstatic void TVPLinTransConstAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa) {\n\tdo_lintrans_blend(TVPLinTransConstAlphaBlend_a_c, do_ConstAlphaBlend_a, dest, len, src, sx, sy, stepx, stepy, srcpitch, opa);\n}\n\nstatic void TVPConstAlphaBlend_SD_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa) {\n\tdo_blend_2(TVPConstAlphaBlend_SD_c, do_ConstAlphaBlend_SD, dest, src1, src2, len, opa);\n}\nstatic void TVPConstAlphaBlend_SD_d_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa) {\n\tdo_blend_2(TVPConstAlphaBlend_SD_d_c, do_ConstAlphaBlend_SD_d, dest, src1, src2, len, opa);\n}\nstatic void TVPConstAlphaBlend_SD_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa) {\n\tdo_blend_2(TVPConstAlphaBlend_SD_a_c, do_ConstAlphaBlend_SD_a, dest, src1, src2, len, opa);\n}\n#endif\n\n#ifndef Region_UnivTransBlend\nstatic uint8x8x4_t do_UnivTransBlend(uint8x8x4_t s2, uint8x8x4_t s1, uint8x8_t opa) {\n\ts2.val[3] = opa;\n\treturn do_AlphaBlend(s2, s1);\n}\nstatic uint8x8x4_t do_UnivTransBlend_d(uint8x8x4_t s2, uint8x8x4_t s1, uint8x8_t opa) {\n\tuint16x8_t s1_a16 = vmull_u8(s1.val[3], vmvn_u8(opa)); // a1*(256-opa)\n\tuint16x8_t d_a16 = vmulq_u16(vsubl_u8(s2.val[3], s1.val[3]), vmovl_u8(opa));\n\tuint16x8_t o16 = vsriq_n_u16(vmull_u8(s2.val[3], opa), s1_a16, 8); // addr\n\ts1.val[3] = vadd_u8(s1.val[3], vshrn_n_u16(d_a16, 8));\n\treturn do_AlphaBlend_d_(s2, s1, o16);\n}\nstatic uint8x8x4_t do_UnivTransBlend_a(uint8x8x4_t s2, uint8x8x4_t s1, uint8x8_t opa) {\n\ts1.val[3] = vadd_u8(s1.val[3], vsubhn_u16(vmull_u8(s2.val[3], opa), vmull_u8(s1.val[3], opa)));\n\treturn do_UnivTransBlend(s2, s1, opa);\n}\nstatic void TVPUnivTransBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len) {\n\tdo_univ_blend(TVPUnivTransBlend_c, do_UnivTransBlend, dest, src1, src2, rule, table, len);\n}\nstatic void TVPUnivTransBlend_d_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len) {\n\tdo_univ_blend(TVPUnivTransBlend_d_c, do_UnivTransBlend_d, dest, src1, src2, rule, table, len);\n}\nstatic void TVPUnivTransBlend_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len) {\n\tdo_univ_blend(TVPUnivTransBlend_a_c, do_UnivTransBlend_a, dest, src1, src2, rule, table, len);\n}\nstatic void TVPUnivTransBlend_switch_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv) {\n\tdo_univ_switch(TVPUnivTransBlend_switch_c, do_UnivTransBlend, dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\nstatic void TVPUnivTransBlend_switch_d_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv) {\n\tdo_univ_switch(TVPUnivTransBlend_switch_d_c, do_UnivTransBlend_d, dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\nstatic void TVPUnivTransBlend_switch_a_NEON(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv) {\n\tdo_univ_switch(TVPUnivTransBlend_switch_a_c, do_UnivTransBlend_a, dest, src1, src2, rule, table, len, src1lv, src2lv);\n}\n#endif\n\n#ifndef Region_ApplyColorMap\n\nstatic uint8x8x4_t do_mergeColorSrc(uint8x8_t s, tjs_uint32 color) {\n\tuint8x8x4_t src;\n\tsrc.val[2] = vdup_n_u8((color >> 16) & 0xFF);\n\tsrc.val[1] = vdup_n_u8((color >> 8) & 0xFF);\n\tsrc.val[0] = vdup_n_u8((color >> 0) & 0xFF);\n\tsrc.val[3] = s;\n\treturn src;\n}\n\nstatic uint8x8x4_t do_ApplyColorMap(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color) {\n\tuint8x8x4_t src = do_mergeColorSrc(s, color);\n\treturn do_AlphaBlend(src, d);\n}\nstatic uint8x8x4_t do_ApplyColorMap_o(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint8x8x4_t src = do_mergeColorSrc(s, color);\n\treturn do_AlphaBlend_o(src, d, opa);\n}\nstatic uint8x8x4_t do_ApplyColorMap_d(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color) {\n\tuint16x8_t s_a16 = vshll_n_u8(s, 8);\n\tuint16x8_t isd_a16 = vmull_u8(vmvn_u8(s), vmvn_u8(d.val[3]));\n\tuint16x8_t sopa = vorrq_u16(s_a16, vmovl_u8(d.val[3]));\n\tuint8x8x4_t src = do_mergeColorSrc(s, color);\n\td.val[3] = vmvn_u8(vshrn_n_u16(isd_a16, 8));\n\treturn do_AlphaBlend_d_(src, d, sopa);\n}\nstatic uint8x8x4_t do_ApplyColorMap_a(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color) {\n\tuint8x8x4_t src = do_mergeColorSrc(s, color);\n\treturn do_AlphaBlend_a(src, d);\n}\nstatic uint8x8x4_t do_ApplyColorMap_do(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint16x8_t s_a16 = vmull_u8(s, vdup_n_u8(opa));\n\ts = vshrn_n_u16(s_a16, 8);\n\treturn do_ApplyColorMap_d(s, d, color);\n}\nstatic uint8x8x4_t do_ApplyColorMap_ao(uint8x8_t s, uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint16x8_t s_a16 = vmull_u8(s, vdup_n_u8(opa));\n\ts = vshrn_n_u16(s_a16, 8);\n\treturn do_ApplyColorMap_a(s, d, color);\n}\n\nstatic void TVPApplyColorMap_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color) {\n\tdo_blend_lum(TVPApplyColorMap_HDA_c, do_ApplyColorMap, dest, src, len, color);\n}\nstatic void TVPApplyColorMap_o_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_blend_lum(TVPApplyColorMap_HDA_o_c, do_ApplyColorMap_o, dest, src, len, color, opa);\n}\nstatic void TVPApplyColorMap_d_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color) {\n\tdo_blend_lum(TVPApplyColorMap_d_c, do_ApplyColorMap_d, dest, src, len, color);\n}\nstatic void TVPApplyColorMap_a_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color) {\n\tdo_blend_lum(TVPApplyColorMap_a_c, do_ApplyColorMap_a, dest, src, len, color);\n}\nstatic void TVPApplyColorMap_do_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_blend_lum(TVPApplyColorMap_do_c, do_ApplyColorMap_do, dest, src, len, color, opa);\n}\nstatic void TVPApplyColorMap_ao_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_blend_lum(TVPApplyColorMap_ao_c, do_ApplyColorMap_ao, dest, src, len, color, opa);\n}\n#endif\n\n#ifndef Region_ConstColorAlphaBlend\nstatic uint8x8x4_t do_ConstColorAlphaBlend(uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint16x8_t s_r16 = vdupq_n_u16(((color >> 16) & 0xFF) * opa);\n\tuint16x8_t s_g16 = vdupq_n_u16(((color >> 8) & 0xFF) * opa);\n\tuint16x8_t s_b16 = vdupq_n_u16(((color >> 0) & 0xFF) * opa);\n\tuint8x8_t s_ia8 = vdup_n_u8(opa ^ 0xFF);\n\tuint16x8_t d_r16 = vmull_u8(d.val[2], s_ia8);\n\tuint16x8_t d_g16 = vmull_u8(d.val[1], s_ia8);\n\tuint16x8_t d_b16 = vmull_u8(d.val[0], s_ia8);\n\td.val[2] = vshrn_n_u16(vaddq_u16(d_r16, s_r16), 8);\n\td.val[1] = vshrn_n_u16(vaddq_u16(d_g16, s_g16), 8);\n\td.val[0] = vshrn_n_u16(vaddq_u16(d_b16, s_b16), 8);\n\treturn d;\n}\nstatic uint8x8x4_t do_ConstColorAlphaBlend_d(uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint16x8_t hopa16 = vdupq_n_u16(opa << 8);\n\tuint8x8_t s_ia8 = vdup_n_u8(opa ^ 0xFF);\n\tuint8x8x4_t s;\n\ts.val[2] = vdup_n_u8((color >> 16) & 0xFF);\n\ts.val[1] = vdup_n_u8((color >> 8) & 0xFF);\n\ts.val[0] = vdup_n_u8((color >> 0) & 0xFF);\n\tuint16x8_t isd_a16 = vmull_u8(s_ia8, vmvn_u8(d.val[3]));\n\tuint16x8_t s_a16 = vorrq_u16(hopa16, vmovl_u8(d.val[3]));\n\td.val[3] = vmvn_u8(vshrn_n_u16(isd_a16, 8)); //(255-((255-dopa)*(255-opa)>>8))\n\treturn do_AlphaBlend_d_(s, d, s_a16);\n}\nstatic uint8x8x4_t do_ConstColorAlphaBlend_a(uint8x8x4_t d, tjs_uint32 color, tjs_int opa) {\n\tuint8x8x4_t s;\n\ts.val[2] = vdup_n_u8((((color >> 16) & 0xFF) * opa) >> 8);\n\ts.val[1] = vdup_n_u8((((color >> 8) & 0xFF) * opa) >> 8);\n\ts.val[0] = vdup_n_u8((((color >> 0) & 0xFF) * opa) >> 8);\n\ts.val[3] = vdup_n_u8(opa);\n\td = do_AlphaBlend_da(s, d);\n\treturn do_AddAlphaBlend(s, d);\n}\nstatic void TVPConstColorAlphaBlend_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_apply_pixel(TVPConstColorAlphaBlend_c, do_ConstColorAlphaBlend, dest, len, color, opa);\n}\nstatic void TVPConstColorAlphaBlend_d_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_apply_pixel(TVPConstColorAlphaBlend_d_c, do_ConstColorAlphaBlend_d, dest, len, color, opa);\n}\nstatic void TVPConstColorAlphaBlend_a_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa) {\n\tdo_apply_pixel(TVPConstColorAlphaBlend_a_c, do_ConstColorAlphaBlend_a, dest, len, color, opa);\n}\n#endif\n\nstatic uint8x8x4_t do_RemoveConstOpacity(uint8x8x4_t d, tjs_int opa) {\n\td.val[3] = vshrn_n_u16(vmull_u8(d.val[3], vdup_n_u8(opa)), 8);\n\treturn d;\n}\nstatic uint8x8x4_t do_RemoveOpacity(uint8x8_t s, uint8x8x4_t d) {\n\td.val[3] = vshrn_n_u16(vmull_u8(d.val[3], vmvn_u8(s)), 8);\n\treturn d;\n}\nstatic uint8x8x4_t do_RemoveOpacity_o(uint8x8_t s, uint8x8x4_t d, tjs_int _strength) {\n\tuint8x8_t strength = vdup_n_u8(_strength);\n\tuint16x8_t s16 = vmull_u8(s, strength); // s * str(8pix)\n\ts16 = vmull_u8(vshrn_n_u16(vmvnq_u16(s16), 8), d.val[3]); // da * (65535 - s * str)\n\td.val[3] = vshrn_n_u16(s16, 8);\n\treturn d;\n}\nstatic void TVPRemoveConstOpacity_NEON(tjs_uint32 *dest, tjs_int len, tjs_int strength)\n{\n\tdo_apply_pixel(TVPRemoveConstOpacity_c, do_RemoveConstOpacity, dest, len, 255 - strength);\n}\nstatic void TVPRemoveOpacity_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len)\n{\n\tdo_blend_lum(TVPRemoveOpacity_c, do_RemoveOpacity, dest, src, len);\n}\nstatic void TVPRemoveOpacity_o_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int _strength)\n{\n\tdo_blend_lum(TVPRemoveOpacity_o_c, do_RemoveOpacity_o, dest, src, len, _strength);\n}\n\n#ifndef Region_AddBlend\nstatic uint8x16x4_t do_AddBlend_HDA_128(uint8x16x4_t s, uint8x16x4_t d) {\n\td.val[2] = vqaddq_u8(d.val[2], s.val[2]);\n\td.val[1] = vqaddq_u8(d.val[1], s.val[1]);\n\td.val[0] = vqaddq_u8(d.val[0], s.val[0]);\n\treturn d;\n}\nstatic uint8x16x4_t do_AddBlend_NonHDA_128(uint8x16x4_t s, uint8x16x4_t d) {\n\td = do_AddBlend_HDA_128(s, d);\n\td.val[3] = vqaddq_u8(d.val[3], s.val[3]);\n\treturn d;\n}\nstatic uint8x8x4_t do_AddBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\ts = do_ConvertAlphaToAdditiveAlpha(s);\n\td.val[2] = vqadd_u8(d.val[2], s.val[2]);\n\td.val[1] = vqadd_u8(d.val[1], s.val[1]);\n\td.val[0] = vqadd_u8(d.val[0], s.val[0]);\n\treturn d;\n}\nstatic void TVPAddBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPAddBlend_c, do_AddBlend_NonHDA_128, dest, src, len);\n}\nstatic void TVPAddBlend_HDA_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPAddBlend_HDA_c, do_AddBlend_HDA_128, dest, src, len);\n}\nstatic void TVPAddBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPAddBlend_HDA_o_c, do_AddBlend_o, dest, src, len, opa);\n}\n#endif\n\n#ifndef Region_SubBlend\nstatic uint8x16x4_t do_SubBlend_HDA(uint8x16x4_t s, uint8x16x4_t d) {\n\td.val[2] = vqsubq_u8(d.val[2], vmvnq_u8(s.val[2]));\n\td.val[1] = vqsubq_u8(d.val[1], vmvnq_u8(s.val[1]));\n\td.val[0] = vqsubq_u8(d.val[0], vmvnq_u8(s.val[0]));\n\treturn d;\n}\nstatic uint8x16x4_t do_SubBlend_NonHDA(uint8x16x4_t s, uint8x16x4_t d) {\n\td = do_SubBlend_HDA(s, d);\n\td.val[3] = vqsubq_u8(d.val[3], vmvnq_u8(s.val[3]));\n\treturn d;\n}\nstatic uint8x8x4_t do_SubBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\ts.val[2] = vmvn_u8(s.val[2]);\n\ts.val[1] = vmvn_u8(s.val[1]);\n\ts.val[0] = vmvn_u8(s.val[0]);\n\ts.val[2] = vshrn_n_u16(vmull_u8(s.val[2], opa8), 8);\n\ts.val[1] = vshrn_n_u16(vmull_u8(s.val[1], opa8), 8);\n\ts.val[0] = vshrn_n_u16(vmull_u8(s.val[0], opa8), 8);\n\td.val[2] = vqsub_u8(d.val[2], s.val[2]);\n\td.val[1] = vqsub_u8(d.val[1], s.val[1]);\n\td.val[0] = vqsub_u8(d.val[0], s.val[0]);\n\treturn d;\n}\nstatic void TVPSubBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPSubBlend_c, do_SubBlend_NonHDA, dest, src, len);\n}\nstatic void TVPSubBlend_HDA_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPSubBlend_HDA_c, do_SubBlend_HDA, dest, src, len);\n}\nstatic void TVPSubBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPSubBlend_HDA_o_c, do_SubBlend_o, dest, src, len, opa);\n}\n#endif\n\n#ifndef Region_MulBlend\nstatic uint8x8x4_t do_MulBlend_HDA(uint8x8x4_t s, uint8x8x4_t d) {\n\td.val[2] = vshrn_n_u16(vmull_u8(s.val[2], d.val[2]), 8);\n\td.val[1] = vshrn_n_u16(vmull_u8(s.val[1], d.val[1]), 8);\n\td.val[0] = vshrn_n_u16(vmull_u8(s.val[0], d.val[0]), 8);\n\treturn d;\n}\nstatic uint8x8x4_t do_MulBlend_o_HDA(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t s_r16 = vmull_u8(vmvn_u8(s.val[2]), opa8);\n\tuint16x8_t s_g16 = vmull_u8(vmvn_u8(s.val[1]), opa8);\n\tuint16x8_t s_b16 = vmull_u8(vmvn_u8(s.val[0]), opa8);\n\ts.val[2] = vmvn_u8(vshrn_n_u16(s_r16, 8));\n\ts.val[1] = vmvn_u8(vshrn_n_u16(s_g16, 8));\n\ts.val[0] = vmvn_u8(vshrn_n_u16(s_b16, 8));\n\treturn do_MulBlend_HDA(s, d);\n}\nstatic uint8x8x4_t do_MulBlend_NonHDA(uint8x8x4_t s, uint8x8x4_t d) {\n\td = do_MulBlend_HDA(s, d);\n\td.val[3] = vdup_n_u8(0);\n\treturn d;\n}\nstatic uint8x8x4_t do_MulBlend_o_NonHDA(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\td = do_MulBlend_o_HDA(s, d, opa);\n\td.val[3] = vdup_n_u8(0);\n\treturn d;\n}\nstatic void TVPMulBlend_HDA_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPMulBlend_HDA_c, do_MulBlend_HDA, dest, src, len);\n}\nstatic void TVPMulBlend_HDA_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPMulBlend_HDA_o_c, do_MulBlend_o_HDA, dest, src, len, opa);\n}\nstatic void TVPMulBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPMulBlend_c, do_MulBlend_NonHDA, dest, src, len);\n}\nstatic void TVPMulBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPMulBlend_o_c, do_MulBlend_o_NonHDA, dest, src, len, opa);\n}\n#endif\nstatic uint8x8x4_t do_ColorDodgeBlend(uint8x8x4_t s_argb8, uint8x8x4_t d_argb8) {\n\tuint8_t tmpbuff[16 + 8];\n\tuint8_t *tmpb = (uint8_t *)__builtin_assume_aligned((uint8_t*)((((intptr_t)tmpbuff) + 7) & ~7), 8);\n\tfor (int i = 0; i < 3; ++i) {\n\t\t// d = d * 255 / (255 - s)\n\t\ts_argb8.val[i] = vmvn_u8(s_argb8.val[i]);\n\t\tuint16x8_t tmp = vsubl_u8(s_argb8.val[i], d_argb8.val[i]);\n\t\tuint8x8_t mask = vshrn_n_u16(tmp, 8); // 00 or FF\n\t\tvst1_u8(tmpb, s_argb8.val[i]);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[0]], tmp, 0);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[1]], tmp, 1);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[2]], tmp, 2);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[3]], tmp, 3);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[4]], tmp, 4);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[5]], tmp, 5);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[6]], tmp, 6);\n\t\ttmp = vsetq_lane_u16(TVPRecipTableForOpacityOnOpacity[tmpb[7]], tmp, 7);\n\t\ttmp = vmulq_u16(vmovl_u8(d_argb8.val[i]), tmp);\n\t\td_argb8.val[i] = vorr_u8(vshrn_n_u16(tmp, 8), mask);\n\t}\n\treturn d_argb8;\n}\nstatic uint8x8x4_t do_ColorDodgeBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\ts = do_ConvertAlphaToAdditiveAlpha(s);\n\treturn do_ColorDodgeBlend(s, d);\n}\nstatic void TVPColorDodgeBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPColorDodgeBlend_HDA_c, do_ColorDodgeBlend, dest, src, len);\n}\nstatic void TVPColorDodgeBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPColorDodgeBlend_HDA_o_c, do_ColorDodgeBlend_o, dest, src, len, opa);\n}\n\nstatic uint8x16x4_t do_DarkenBlend(uint8x16x4_t s, uint8x16x4_t d) {\n\td.val[0] = vminq_u8(s.val[0], d.val[0]);\n\td.val[1] = vminq_u8(s.val[1], d.val[1]);\n\td.val[2] = vminq_u8(s.val[2], d.val[2]);\n\treturn d;\n}\nstatic uint8x8x4_t do_DarkenBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[2] = vmin_u8(s.val[2], d.val[2]);\n\ts.val[1] = vmin_u8(s.val[1], d.val[1]);\n\ts.val[0] = vmin_u8(s.val[0], d.val[0]);\n\ts.val[3] = vdup_n_u8(opa);\n\treturn do_AlphaBlend(s, d);\n}\nstatic uint8x16x4_t do_LightenBlend(uint8x16x4_t s, uint8x16x4_t d) {\n\td.val[0] = vmaxq_u8(s.val[0], d.val[0]);\n\td.val[1] = vmaxq_u8(s.val[1], d.val[1]);\n\td.val[2] = vmaxq_u8(s.val[2], d.val[2]);\n\treturn d;\n}\nstatic uint8x8x4_t do_LightenBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[2] = vmax_u8(s.val[2], d.val[2]);\n\ts.val[1] = vmax_u8(s.val[1], d.val[1]);\n\ts.val[0] = vmax_u8(s.val[0], d.val[0]);\n\ts.val[3] = vdup_n_u8(opa);\n\treturn do_AlphaBlend(s, d);\n}\nstatic uint8x8x4_t do_ScreenBlend(uint8x8x4_t s_argb8, uint8x8x4_t d_argb8) {\n\tuint16x8_t d_r16 = vmull_u8(vmvn_u8(s_argb8.val[2]), vmvn_u8(d_argb8.val[2]));\n\tuint16x8_t d_g16 = vmull_u8(vmvn_u8(s_argb8.val[1]), vmvn_u8(d_argb8.val[1]));\n\tuint16x8_t d_b16 = vmull_u8(vmvn_u8(s_argb8.val[0]), vmvn_u8(d_argb8.val[0]));\n\td_argb8.val[2] = vmvn_u8(vshrn_n_u16(d_r16, 8));\n\td_argb8.val[1] = vmvn_u8(vshrn_n_u16(d_g16, 8));\n\td_argb8.val[0] = vmvn_u8(vshrn_n_u16(d_b16, 8));\n\treturn d_argb8;\n}\nstatic uint8x8x4_t do_ScreenBlend_o(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\ts.val[3] = vdup_n_u8(opa);\n\ts = do_ConvertAlphaToAdditiveAlpha(s);\n\treturn do_ScreenBlend(s, d);\n}\nstatic void TVPDarkenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPDarkenBlend_HDA_c, do_DarkenBlend, dest, src, len);\n}\nstatic void TVPDarkenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPDarkenBlend_HDA_o_c, do_DarkenBlend_o, dest, src, len, opa);\n}\nstatic void TVPLightenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPLightenBlend_HDA_c, do_LightenBlend, dest, src, len);\n}\nstatic void TVPLightenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPDarkenBlend_HDA_o_c, do_LightenBlend_o, dest, src, len, opa);\n}\nstatic void TVPScreenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPScreenBlend_HDA_c, do_ScreenBlend, dest, src, len);\n}\nstatic void TVPScreenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPScreenBlend_HDA_o_c, do_ScreenBlend_o, dest, src, len, opa);\n}\n\nstatic void TVPFastLinearInterpV2_NEON(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src0, const tjs_uint32 *src1)\n{\n    tjs_uint32* pEndDst = dest + len;\n    {\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n        if(PreFragLen > len) PreFragLen = len;\n        if(PreFragLen) {\n            TVPFastLinearInterpV2_c(dest, PreFragLen, src0, src1);\n            dest += PreFragLen;\n            src0 += PreFragLen;\n            src1 += PreFragLen;\n        }\n    }\n\n    tjs_uint32* pVecEndDst = pEndDst-3;\n\tif ((((intptr_t)src0) & 7) || (((intptr_t)src1) & 7)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x16_t s0 = vld1q_u8((uint8_t *)__builtin_assume_aligned(src0, 4));\n\t\t\tuint8x16_t s1 = vld1q_u8((uint8_t *)__builtin_assume_aligned(src1, 4));\n\n\t\t\tvst1q_u8((uint8_t *)__builtin_assume_aligned(dest, 8), vhaddq_u8(s0, s1));\n\t\t\tdest += 4;\n\t\t\tsrc0 += 4;\n\t\t\tsrc1 += 4;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x16_t s0 = vld1q_u8((uint8_t *)__builtin_assume_aligned(src0, 8));\n\t\t\tuint8x16_t s1 = vld1q_u8((uint8_t *)__builtin_assume_aligned(src1, 8));\n\n\t\t\tvst1q_u8((uint8_t *)__builtin_assume_aligned(dest, 8), vhaddq_u8(s0, s1));\n\t\t\tdest += 4;\n\t\t\tsrc0 += 4;\n\t\t\tsrc1 += 4;\n\t\t}\n\t}\n\n    if(dest < pEndDst) {\n        TVPFastLinearInterpV2_c(dest, pEndDst - dest, src0, src1);\n    }\n}\nstatic uint8x8x4_t do_CopyMask(uint8x8x4_t s, uint8x8x4_t d) {\n\td.val[3] = s.val[3];\n\treturn d;\n}\nstatic void TVPCopyMask_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPCopyMask_c, do_CopyMask, dest, src, len);\n}\nstatic uint8x8x4_t do_CopyColor(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[3] = d.val[3];\n\treturn s;\n}\nstatic void TVPCopyColor_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPCopyColor_c, do_CopyColor, dest, src, len);\n}\nstatic uint8x8x4_t do_BindMaskToMain(uint8x8_t s, uint8x8x4_t d) {\n\td.val[3] = s;\n\treturn d;\n}\nstatic void TVPBindMaskToMain_NEON(tjs_uint32 *main, const tjs_uint8 *mask, tjs_int len) {\n\tdo_blend_lum(TVPBindMaskToMain_c, do_BindMaskToMain, main, mask, len);\n}\nstatic void TVPFillARGB_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 value)\n{\n\ttjs_uint32* pEndDst = dest + len;\n\twhile((((intptr_t)dest)&~15) && dest < pEndDst) {\n\t\t*dest++ = value;\n\t}\n\n\tuint32x4_t v = vdupq_n_u32(value);\n\ttjs_uint32* pVecEndDst = pEndDst-3;\n\twhile(dest < pVecEndDst) {\n\t\tvst1q_u32((uint32_t *)__builtin_assume_aligned(dest, 16), v);\n\t\tdest += 4;\n\t}\n\twhile(dest < pEndDst) {\n\t\t*dest++ = value;\n\t}\n}\nstatic uint8x8x4_t do_FillColor(uint8x8x4_t d, tjs_uint32 color) {\n    d.val[0] = vdup_n_u8(color & 0xff);\n    d.val[1] = vdup_n_u8((color >> 8) & 0xff);\n    d.val[2] = vdup_n_u8((color >> 16) & 0xff);\n\treturn d;\n}\n\nstatic void TVPFillColor_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 color) {\n\tdo_apply_pixel(TVPFillColor_c, do_FillColor, dest, len, color);\n}\nstatic uint8x8x4_t do_FillMask(uint8x8x4_t d, tjs_uint32 mask) {\n    d.val[3] = vdup_n_u8(mask);\n\treturn d;\n}\nstatic void TVPFillMask_NEON(tjs_uint32 *dest, tjs_int len, tjs_uint32 mask) {\n\tdo_apply_pixel(TVPFillMask_c, do_FillMask, dest, len, mask);\n}\n\nstatic void TVPAddSubVertSum16_NEON(tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n    tjs_uint16* pEndDst = dest + len * 4;\n\t// dest is always aligned\n//     {\n// \t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest) / 4;\n//         if(PreFragLen > len) PreFragLen = len;\n//         if(PreFragLen) {\n//             TVPAddSubVertSum16_c(dest, addline, subline, PreFragLen);\n//             dest += PreFragLen * 4;\n//             addline += PreFragLen;\n//             subline += PreFragLen;\n//         }\n//     }\n\n    tjs_uint16* pVecEndDst = pEndDst-7;\n\tif ((((intptr_t)addline) & 7) || (((intptr_t)subline) & 7)) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8x4_t add = vld4_u8((uint8_t *)__builtin_assume_aligned(addline, 4));\n\t\t\tuint8x8x4_t sub = vld4_u8((uint8_t *)__builtin_assume_aligned(subline, 4));\n\t\t\tuint16x8x4_t d = vld4q_u16((uint16_t *)__builtin_assume_aligned(dest, 8));\n\t\t\td.val[3] = vaddq_u16(d.val[3], vsubl_u8(add.val[3], sub.val[3]));\n\t\t\td.val[2] = vaddq_u16(d.val[2], vsubl_u8(add.val[2], sub.val[2]));\n\t\t\td.val[1] = vaddq_u16(d.val[1], vsubl_u8(add.val[1], sub.val[1]));\n\t\t\td.val[0] = vaddq_u16(d.val[0], vsubl_u8(add.val[0], sub.val[0]));\n\t\t\tvst4q_u16((uint16_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 8 * 4;\n\t\t\taddline += 8;\n\t\t\tsubline += 8;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x8x4_t add = vld4_u8((uint8_t *)__builtin_assume_aligned(addline, 8));\n\t\t\tuint8x8x4_t sub = vld4_u8((uint8_t *)__builtin_assume_aligned(subline, 8));\n\t\t\tuint16x8x4_t d = vld4q_u16((uint16_t *)__builtin_assume_aligned(dest, 8));\n\t\t\td.val[3] = vaddq_u16(d.val[3], vsubl_u8(add.val[3], sub.val[3]));\n\t\t\td.val[2] = vaddq_u16(d.val[2], vsubl_u8(add.val[2], sub.val[2]));\n\t\t\td.val[1] = vaddq_u16(d.val[1], vsubl_u8(add.val[1], sub.val[1]));\n\t\t\td.val[0] = vaddq_u16(d.val[0], vsubl_u8(add.val[0], sub.val[0]));\n\t\t\tvst4q_u16((uint16_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 8 * 4;\n\t\t\taddline += 8;\n\t\t\tsubline += 8;\n\t\t}\n\t}\n\n    if(dest < pEndDst) {\n        TVPAddSubVertSum16_c(dest, addline, subline, (pEndDst - dest) / 4);\n    }\n}\n\nstatic void TVPAddSubVertSum16_d_NEON(tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n    tjs_uint16* pEndDst = dest + len * 4;\n\t// dest is always aligned\n//     {\n// \t\ttjs_int PreFragLen = (((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest)) / 4;\n//         if(PreFragLen > len) PreFragLen = len;\n//         if(PreFragLen) {\n//             TVPAddSubVertSum16_d_c(dest, addline, subline, PreFragLen);\n//             dest += PreFragLen * 4;\n//             addline += PreFragLen;\n//             subline += PreFragLen;\n//         }\n//     }\n\n    tjs_uint16* pVecEndDst = pEndDst-7;\n\twhile (dest < pVecEndDst) {\n\t\tuint8x8x4_t add = vld4_u8((uint8_t *)__builtin_assume_aligned(addline, 4));\n\t\tuint8x8x4_t sub = vld4_u8((uint8_t *)__builtin_assume_aligned(subline, 4));\n\t\tuint16x8x4_t d = vld4q_u16((uint16_t*)__builtin_assume_aligned(dest, 8));\n\n        uint16x8_t add_a = vaddl_u8(add.val[3], vshr_n_u8(add.val[3], 7));\n        uint16x8_t sub_a = vaddl_u8(sub.val[3], vshr_n_u8(sub.val[3], 7));\n        d.val[3] = vaddq_u16(d.val[3], vsubl_u8(add.val[3], sub.val[3]));\n\n        uint16x8_t add_16 = vmulq_u16(vmovl_u8(add.val[2]), add_a);\n        uint16x8_t sub_16 = vmulq_u16(vmovl_u8(sub.val[2]), sub_a);\n        add_16 = vshrq_n_u16(add_16, 8);\n        sub_16 = vshrq_n_u16(sub_16, 8);\n        d.val[2] = vaddq_u16(d.val[2], vsubq_u16(add_16, sub_16));\n\n        add_16 = vmulq_u16(vmovl_u8(add.val[1]), add_a);\n        sub_16 = vmulq_u16(vmovl_u8(sub.val[1]), sub_a);\n        add_16 = vshrq_n_u16(add_16, 8);\n        sub_16 = vshrq_n_u16(sub_16, 8);\n        d.val[1] = vaddq_u16(d.val[1], vsubq_u16(add_16, sub_16));\n\n        add_16 = vmulq_u16(vmovl_u8(add.val[0]), add_a);\n        sub_16 = vmulq_u16(vmovl_u8(sub.val[0]), sub_a);\n        add_16 = vshrq_n_u16(add_16, 8);\n        sub_16 = vshrq_n_u16(sub_16, 8);\n        d.val[0] = vaddq_u16(d.val[0], vsubq_u16(add_16, sub_16));\n\n\t\tvst4q_u16((uint16_t*)__builtin_assume_aligned(dest, 8), d);\n        dest += 8 * 4;\n        addline += 8;\n        subline += 8;\n    }\n\n    if(dest < pEndDst) {\n        TVPAddSubVertSum16_d_c(dest, addline, subline, (pEndDst - dest) / 4);\n    }\n}\n\nstatic void TVPDoBoxBlurAvg16_NEON(tjs_uint32 *dest, tjs_uint16 *_sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len)\n{\n    tjs_uint32* pEndDst = dest + len;\n\t// dest is always aligned\n//     {\n// \t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n//         if(PreFragLen > len) PreFragLen = len;\n//         if(PreFragLen) {\n// \t\t\tTVPDoBoxBlurAvg16_c(dest, _sum, add, sub, n, PreFragLen);\n//             dest += PreFragLen;\n//             add += PreFragLen;\n//             sub += PreFragLen;\n//         }\n//     }\n\n\tstatic const int32_t c_shl_n[4] = { 0, 8, 16, 24 };\n\n    uint32x4_t rcp = vdupq_n_u32((1<<16) / n);\n\tint32x4_t shl_n = vld1q_s32(c_shl_n);\n    uint16x4_t half_n = vdup_n_u16(n >> 1);\n\n    tjs_uint32* pVecEndDst = pEndDst-7;\n\tuint16x4_t sum = vld1_u16(_sum);\n\twhile (dest < pVecEndDst) {\n\t\tuint32x4_t t = vmulq_u32(vaddl_u16(sum, half_n), rcp);\n\t\tuint32x4_t d = vshlq_u32(vshrq_n_u32(t, 16), shl_n);\n\n// \t\tt0 = vmul_u32(vaddl_u16(src_sum.val[2], half_n));\n// \t\tvorr_u32(d, vshl_n_u32(vshr_n_u32(t1, 16), 8));\n// \t\tt1 = vmul_u32(vaddl_u16(src_sum.val[3], half_n));\n// \t\tvorr_u32(d, vshl_n_u32(vshr_n_u32(t0, 16), 8));\n// \t\tvorr_u32(d, vshl_n_u32(vshr_n_u32(t1, 16), 8));\n// \n// \t\tuint16x4x4_t src_add = vld4_u16\n\n//         uint16x8_t add = vld1q_u16(add);\n//         uint16x8_t sub = vld1q_u16(sub);\n//         uint16x8_t d = vld4q_u16(dest);\n//         d.val[3] = vaddq_u16(d.val[3], vsubl_u8(add.val[3], sub.val[3]));\n//         d.val[2] = vaddq_u16(d.val[2], vsubl_u8(add.val[2], sub.val[2]));\n//         d.val[1] = vaddq_u16(d.val[1], vsubl_u8(add.val[1], sub.val[1]));\n//         d.val[0] = vaddq_u16(d.val[0], vsubl_u8(add.val[0], sub.val[0]));\n        vst1q_u32(dest, d);\n        dest += 8;\n        add += 8;\n        sub += 8;\n    }\n\n    if(dest < pEndDst) {\n\t\tTVPDoBoxBlurAvg16_c(dest, _sum, add, sub, n, pEndDst - dest);\n    }\n}\n\nstatic uint8x8x4_t do_Expand8BitTo32BitGray(uint8x8_t s, uint8x8x4_t d) {\n\td.val[0] = s;\n\td.val[1] = s;\n\td.val[2] = s;\n    d.val[3] = vdup_n_u8(0xFF);\n\treturn d;\n}\nstatic void TVPExpand8BitTo32BitGray_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len) {\n\tdo_blend_lum(TVPExpand8BitTo32BitGray_c, do_Expand8BitTo32BitGray, dest, src, len);\n}\nstatic uint8x16x4_t do_ReverseRGB(uint8x16x4_t s, uint8x16x4_t d) {\n\tuint8x16_t t = s.val[0];\n\ts.val[0] = s.val[2];\n\ts.val[2] = t;\n\treturn s;\n}\nstatic void TVPReverseRGB_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend_128(TVPReverseRGB_c, do_ReverseRGB, dest, src, len);\n}\n\nstatic void TVPUpscale65_255_NEON(tjs_uint8 *dest, tjs_int len) {\n\t// dest is already aligned by 16 bytes\n\ttjs_uint8* pEndDst = dest + len;\n\ttjs_uint8* pVecEndDst = pEndDst - 15;\n\n\twhile (dest < pVecEndDst) {\n\t\tuint8x16_t d = vld1q_u8((uint8_t *)__builtin_assume_aligned(dest, 16));\n\t\td = vqshlq_n_u8(d, 2);\n\t\tvst1q_u8((uint8_t *)__builtin_assume_aligned(dest, 16), d);\n\t\tdest += 16;\n\t}\n\twhile (dest < pEndDst) {\n\t\ttjs_uint c = *dest << 2;\n\t\t*dest = c > 255 ? 255 : c;\n\t\t++dest;\n\t}\n}\n\nstatic const unsigned char rgb555_lut[4][8] = {\n    { 0, 0x8, 0x10, 0x18, 0x21, 0x29, 0x31, 0x39 },\n    { 0x42, 0x4A, 0x52, 0x5A, 0x63, 0x6B, 0x73, 0x7B },\n    { 0x84, 0x8C, 0x94, 0x9C, 0xA5, 0xAD, 0xB5, 0xBD },\n    { 0xC6, 0xCE, 0xD6, 0xDE, 0xE7, 0xEF, 0xF7, 0xFF } };\n\nstatic void TVPBLConvert15BitTo32Bit_NEON(tjs_uint32 *dest, const tjs_uint16 *src, tjs_int len)\n{\n    tjs_uint32* pEndDst = dest + len;\n    {\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n        if (PreFragLen > len) PreFragLen = len;\n        if (PreFragLen) {\n            TVPBLConvert15BitTo32Bit_c(dest, src, PreFragLen);\n            dest += PreFragLen;\n            src += PreFragLen;\n        }\n    }\n\n    tjs_uint32* pVecEndDst = pEndDst - 7;\n\n    if (dest < pVecEndDst)\n    {\n        uint8x8x4_t d;\n        d.val[3] = vdup_n_u8(0xFF);\n#if 0 //def __LP64__\n        uint8x16x2_t lut;\n        lut.val[0] = vld1q_u8(rgb555_lut[0]);\n        lut.val[1] = vld1q_u8(rgb555_lut[2]);\n        \n        while (dest < pVecEndDst) {\n            uint16x8_t s = vshlq_n_u16(vld1q_u16(src), 1);\n            d.val[0] = vtbl2q_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n            s = vshlq_n_u16(s, 5);\n            d.val[1] = vtbl2q_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n            s = vshlq_n_u16(s, 5);\n            d.val[2] = vtbl2q_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n            vst4_u8((uint8_t*)dest, d);\n            dest += 8;\n            src += 8;\n        }\n#else\n        uint8x8x4_t lut;\n        lut.val[0] = vld1_u8(rgb555_lut[0]);\n        lut.val[1] = vld1_u8(rgb555_lut[1]);\n        lut.val[2] = vld1_u8(rgb555_lut[2]);\n        lut.val[3] = vld1_u8(rgb555_lut[3]);\n\n\t\tif (((intptr_t)src) & 7) {\n\t\t\twhile (dest < pVecEndDst) {\n\t\t\t\tuint16x8_t s = vshlq_n_u16(vld1q_u16((uint16_t *)__builtin_assume_aligned(src, 4)), 1);\n\t\t\t\td.val[0] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\ts = vshlq_n_u16(s, 5);\n\t\t\t\td.val[1] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\ts = vshlq_n_u16(s, 5);\n\t\t\t\td.val[2] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\t\tdest += 8;\n\t\t\t\tsrc += 8;\n\t\t\t}\n\t\t} else {\n\t\t\twhile (dest < pVecEndDst) {\n\t\t\t\tuint16x8_t s = vshlq_n_u16(vld1q_u16((uint16_t *)__builtin_assume_aligned(src, 8)), 1);\n\t\t\t\td.val[0] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\ts = vshlq_n_u16(s, 5);\n\t\t\t\td.val[1] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\ts = vshlq_n_u16(s, 5);\n\t\t\t\td.val[2] = vtbl4_u8(lut, vmovn_u16(vshrq_n_u16(s, 11)));\n\t\t\t\tvst4_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\t\tdest += 8;\n\t\t\t\tsrc += 8;\n\t\t\t}\n\t\t}\n#endif\n    }\n\n    if (dest < pEndDst) {\n        TVPBLConvert15BitTo32Bit_c(dest, src, pEndDst - dest);\n    }\n}\n\nstatic void TVPConvert24BitTo32Bit_NEON(tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len)\n{\n    tjs_uint32* pEndDst = dest + len;\n    {\n\t\ttjs_int PreFragLen = ((-(((tjs_int)(intptr_t)dest) & 7)) & 7) / sizeof(*dest);\n        if(PreFragLen > len) PreFragLen = len;\n        if(PreFragLen) {\n            TVPConvert24BitTo32Bit_c(dest, src, PreFragLen);\n            dest += PreFragLen;\n            src += PreFragLen * 3;\n        }\n    }\n\n    tjs_uint32* pVecEndDst = pEndDst-15;\n    uint8x16x4_t d;\n    d.val[3] = vdupq_n_u8(0xFF);\n\tif (((intptr_t)src) & 7) {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x16x3_t s = vld3q_u8((uint8_t *)__builtin_assume_aligned(src, 4));\n\t\t\td.val[2] = s.val[0];\n\t\t\td.val[1] = s.val[1];\n\t\t\td.val[0] = s.val[2];\n\t\t\tvst4q_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 16;\n\t\t\tsrc += 16 * 3;\n\t\t}\n\t} else {\n\t\twhile (dest < pVecEndDst) {\n\t\t\tuint8x16x3_t s = vld3q_u8((uint8_t *)__builtin_assume_aligned(src, 8));\n\t\t\td.val[2] = s.val[0];\n\t\t\td.val[1] = s.val[1];\n\t\t\td.val[0] = s.val[2];\n\t\t\tvst4q_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 16;\n\t\t\tsrc += 16 * 3;\n\t\t}\n\t}\n\n    if(dest < pEndDst) {\n        TVPConvert24BitTo32Bit_c(dest, src, pEndDst - dest);\n    }\n}\n\nstatic void TVPConvert32BitTo24Bit_NEON(tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len) {\n\tconst tjs_uint8* pEndSrc = src + len;\n\t{\n\t\ttjs_int PreFragLen = (-(((tjs_int)(intptr_t)src) & 7)) & 7;\n\t\tif (PreFragLen > len) PreFragLen = len;\n\t\tconst tjs_uint8 *pend = src + PreFragLen; // in bytes\n\t\twhile (src < pend)\n\t\t{\n\t\t\tdest[0] = src[0];\n\t\t\tdest[1] = src[1];\n\t\t\tdest[2] = src[2];\n\t\t\tdest += 3;\n\t\t\tsrc += 4;\n\t\t}\n\t}\n\n\tconst tjs_uint8* pVecEndSrc = pEndSrc - 15;\n\tuint8x16x3_t d;\n\tif (((intptr_t)dest) & 7) {\n\t\twhile (src < pVecEndSrc) {\n\t\t\tuint8x16x4_t s = vld4q_u8((uint8_t *)__builtin_assume_aligned(src, 8));\n\t\t\td.val[0] = s.val[0];\n\t\t\td.val[1] = s.val[1];\n\t\t\td.val[2] = s.val[2];\n\t\t\tvst3q_u8((uint8_t *)__builtin_assume_aligned(dest, 4), d);\n\t\t\tdest += 16 * 3;\n\t\t\tsrc += 16 * 4;\n\t\t}\n\t} else {\n\t\twhile (src < pVecEndSrc) {\n\t\t\tuint8x16x4_t s = vld4q_u8((uint8_t *)__builtin_assume_aligned(src, 8));\n\t\t\td.val[0] = s.val[0];\n\t\t\td.val[1] = s.val[1];\n\t\t\td.val[2] = s.val[2];\n\t\t\tvst3q_u8((uint8_t *)__builtin_assume_aligned(dest, 8), d);\n\t\t\tdest += 16 * 3;\n\t\t\tsrc += 16 * 4;\n\t\t}\n\t}\n\n\twhile (src < pEndSrc) {\n\t\tdest[0] = src[0];\n\t\tdest[1] = src[1];\n\t\tdest[2] = src[2];\n\t\tdest += 3;\n\t\tsrc += 4;\n\t}\n}\n\nstatic uint8x8x4_t do_GrayScale(uint8x8x4_t s) {\n    uint8x8_t const_19 = vdup_n_u8(19), const_183 = vdup_n_u8(183), const_54 = vdup_n_u8(54);\n\tuint16x8_t r = vmull_u8(s.val[0], const_19);\n\tuint16x8_t g = vmull_u8(s.val[1], const_183);\n\tuint16x8_t b = vmull_u8(s.val[2], const_54);\n\tr = vaddq_u16(r, g);\n\tr = vaddq_u16(r, b);\n\ts.val[2] = s.val[1] = s.val[0] = vshrn_n_u16(r, 8);\n\treturn s;\n}\nstatic void TVPDoGrayScale_NEON(tjs_uint32 *dest, tjs_int len) {\n\tdo_apply_pixel(TVPDoGrayScale_c, do_GrayScale, dest, len);\n}\n#ifndef Region_PsBlend\ntemplate <uint8x8x4_t op_func(uint8x8x4_t, uint8x8x4_t)>\nuint8x8x4_t do_PsAlphaBlend_so(uint8x8x4_t s, uint8x8x4_t d, tjs_int opa) {\n\tuint8x8_t opa8 = vdup_n_u8(opa);\n\tuint16x8_t a = vmull_u8(s.val[3], opa8);\n\ts.val[3] = vshrn_n_u16(a, 8);\n\treturn op_func(s, d);\n}\nstatic void TVPPsAlphaBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsAlphaBlend_HDA_c, do_AlphaBlend, dest, src, len);\n}\nstatic void TVPPsAlphaBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsAlphaBlend_HDA_o_c, do_PsAlphaBlend_so<do_AlphaBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsAddBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vqadd_u8(s.val[2], d.val[2]);\n\ts.val[1] = vqadd_u8(s.val[1], d.val[1]);\n\ts.val[0] = vqadd_u8(s.val[0], d.val[0]);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsAddBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsAddBlend_HDA_c, do_PsAddBlend, dest, src, len);\n}\nstatic void TVPPsAddBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsAddBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsAddBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsSubBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vqsub_u8(d.val[2], vmvn_u8(s.val[2]));\n\ts.val[1] = vqsub_u8(d.val[1], vmvn_u8(s.val[1]));\n\ts.val[0] = vqsub_u8(d.val[0], vmvn_u8(s.val[0]));\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsSubBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsSubBlend_HDA_c, do_PsSubBlend, dest, src, len);\n}\nstatic void TVPPsSubBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsSubBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsSubBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsMulBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vshrn_n_u16(vmull_u8(s.val[2], d.val[2]), 8);\n\ts.val[1] = vshrn_n_u16(vmull_u8(s.val[1], d.val[1]), 8);\n\ts.val[0] = vshrn_n_u16(vmull_u8(s.val[0], d.val[0]), 8);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsMulBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsMulBlend_HDA_c, do_PsMulBlend, dest, src, len);\n}\nstatic void TVPPsMulBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsMulBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsMulBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsScreenBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\tuint16x8_t d_r16 = vmull_u8(s.val[2], d.val[2]);\n\tuint16x8_t d_g16 = vmull_u8(s.val[1], d.val[1]);\n\tuint16x8_t d_b16 = vmull_u8(s.val[0], d.val[0]);\n\td_r16 = vsubl_u8(s.val[2], vshrn_n_u16(d_r16, 8));\n\td_g16 = vsubl_u8(s.val[1], vshrn_n_u16(d_g16, 8));\n\td_b16 = vsubl_u8(s.val[0], vshrn_n_u16(d_b16, 8));\n\td_r16 = vmulq_u16(d_r16, vmovl_u8(s.val[3]));\n\td_g16 = vmulq_u16(d_g16, vmovl_u8(s.val[3]));\n\td_b16 = vmulq_u16(d_b16, vmovl_u8(s.val[3]));\n\td.val[2] = vadd_u8(d.val[2], vshrn_n_u16(d_r16, 8));\n\td.val[1] = vadd_u8(d.val[1], vshrn_n_u16(d_g16, 8));\n\td.val[0] = vadd_u8(d.val[0], vshrn_n_u16(d_b16, 8));\n\treturn d;\n}\nstatic void TVPPsScreenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsScreenBlend_HDA_c, do_PsScreenBlend, dest, src, len);\n}\nstatic void TVPPsScreenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsScreenBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsScreenBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsOverlayBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\t// (s+d-s*d)*2-1, d>=128\n\t// s*d*2, d<128\n\tconst uint8x8_t mask80 = vdup_n_u8(0x80);\n\tconst uint8x8_t mask1 = vdup_n_u8(0x1);\n\tconst uint8x8_t maskFE = vdup_n_u8(0xFE);\n\tfor (int i = 0; i < 3; ++i) {\n\t\tuint16x8_t sa = vmull_u8(vorr_u8(s.val[i], mask1), d.val[i]);\n\t\tuint8x8_t n = vtst_u8(d.val[i], mask80); // n = d>=128\n\t\tuint8x8_t d1 = vand_u8(d.val[i], n), s1 = vand_u8(vand_u8(s.val[i], n), maskFE);\n\t\tsa = vshrq_n_u16(sa, 7);\n\t\tuint16x8_t t = vshll_n_u8(vadd_u8(s1, d1), 1);\n\t\tt = vsubw_u8(t, n);\n\t\tt = vsubq_u16(t, sa);\n\t\ts.val[i] = vand_u8(vmovn_u16(t), n);\n\t\ts.val[i] = vorr_u8(s.val[i], vand_u8(vmovn_u16(sa), vmvn_u8(n)));\n\n// \t\tuint8x8_t threshold = vtst_u8(d.val[i], mask80); // = (128<=s)?0xFF:0\n// \t\tuint16x8_t ms2 = vshlq_n_u16(vaddl_u8(s.val[i], d.val[i]), 1);\t// = (dst+src)*2\n// \t\tuint16x8_t ms = vshrq_n_u16(vmull_u8(s.val[i], d.val[i]), 7);\t// = dst*src*2/255\n// \t\tms2 = vsubw_u8(vsubq_u16(ms2, ms), threshold);\t// = (d+s-d*s)*2-255\n// \t\ts.val[i] = vand_u8(vmovn_u16(ms2), threshold);\n// \t\tthreshold = vmvn_u8(threshold);\n// \t\tthreshold = vand_u8(vmovn_u16(ms), threshold);\n// \t\ts.val[i] = vorr_u8(s.val[i], threshold);\n\t}\n\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsOverlayBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsOverlayBlend_HDA_c, do_PsOverlayBlend, dest, src, len);\n}\nstatic void TVPPsOverlayBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsOverlayBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsOverlayBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsHardLightBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\t// (s+d-s*d)*2-1, s>=128\n\t// s*d*2, s<128\n\tconst uint8x8_t mask80 = vdup_n_u8(0x80);\n\tconst uint8x8_t mask1 = vdup_n_u8(0x1);\n\tconst uint8x8_t maskFE = vdup_n_u8(0xFE);\n\tfor (int i = 0; i < 3; ++i) {\n\t\tuint16x8_t sa = vmull_u8(vorr_u8(s.val[i], mask1), d.val[i]);\n\t\tuint8x8_t n = vtst_u8(s.val[i], mask80); // n = d>=128\n\t\tuint8x8_t d1 = vand_u8(d.val[i], n), s1 = vand_u8(vand_u8(s.val[i], n), maskFE);\n\t\tsa = vshrq_n_u16(sa, 7);\n\t\tuint16x8_t t = vshll_n_u8(vadd_u8(s1, d1), 1);\n\t\tt = vsubw_u8(t, n);\n\t\tt = vsubq_u16(t, sa);\n\t\ts.val[i] = vand_u8(vmovn_u16(t), n);\n\t\ts.val[i] = vorr_u8(s.val[i], vand_u8(vmovn_u16(sa), vmvn_u8(n)));\n\n// \t\tuint8x8_t threshold = vtst_u8(s.val[i], mask80); // = (128<=s)?0xFF:0\n// \t\tuint16x8_t ms2 = vshlq_n_u16(vaddl_u8(s.val[i], d.val[i]), 1);\t// = (dst+src)*2\n// \t\tuint16x8_t ms = vshrq_n_u16(vmull_u8(s.val[i], d.val[i]), 7);\t// = dst*src*2/255\n// \t\tms2 = vqsubq_u16(vsubq_u16(ms2, ms), maskFF);\t// = (d+s-d*s)*2-255\n// \t\ts.val[i] = vand_u8(vmovn_u16(ms2), threshold);\n// \t\tthreshold = vmvn_u8(threshold);\n// \t\tthreshold = vand_u8(vmovn_u16(ms), threshold);\n// \t\ts.val[i] = vorr_u8(s.val[i], threshold);\n\t}\n\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsHardLightBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsHardLightBlend_HDA_c, do_PsHardLightBlend, dest, src, len);\n}\nstatic void TVPPsHardLightBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsHardLightBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsHardLightBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsLightenBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vmax_u8(s.val[2], d.val[2]);\n\ts.val[1] = vmax_u8(s.val[1], d.val[1]);\n\ts.val[0] = vmax_u8(s.val[0], d.val[0]);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsLightenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsLightenBlend_HDA_c, do_PsLightenBlend, dest, src, len);\n}\nstatic void TVPPsLightenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsLightenBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsLightenBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsDarkenBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vmin_u8(s.val[2], d.val[2]);\n\ts.val[1] = vmin_u8(s.val[1], d.val[1]);\n\ts.val[0] = vmin_u8(s.val[0], d.val[0]);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsDarkenBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsDarkenBlend_HDA_c, do_PsDarkenBlend, dest, src, len);\n}\nstatic void TVPPsDarkenBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsDarkenBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsDarkenBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsDiff5Blend(uint8x8x4_t s, uint8x8x4_t d) {\n\tuint16x8_t s_r16 = vmull_u8(s.val[2], s.val[3]);\n\tuint16x8_t s_g16 = vmull_u8(s.val[1], s.val[3]);\n\tuint16x8_t s_b16 = vmull_u8(s.val[0], s.val[3]);\n\td.val[2] = vabd_u8(vshrn_n_u16(s_r16, 8), d.val[2]);\n\td.val[1] = vabd_u8(vshrn_n_u16(s_g16, 8), d.val[1]);\n\td.val[0] = vabd_u8(vshrn_n_u16(s_b16, 8), d.val[0]);\n\treturn d;\n}\nstatic void TVPPsDiff5Blend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsDiff5Blend_HDA_c, do_PsDiff5Blend, dest, src, len);\n}\nstatic void TVPPsDiff5Blend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsDiff5Blend_HDA_o_c, do_PsAlphaBlend_so<do_PsDiff5Blend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsDiffBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\ts.val[2] = vabd_u8(s.val[2], d.val[2]);\n\ts.val[1] = vabd_u8(s.val[1], d.val[1]);\n\ts.val[0] = vabd_u8(s.val[0], d.val[0]);\n\treturn do_AlphaBlend(s, d);\n}\nstatic void TVPPsDiffBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsDiffBlend_HDA_c, do_PsDiffBlend, dest, src, len);\n}\nstatic void TVPPsDiffBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsDiffBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsDiffBlend>, dest, src, len, opa);\n}\n\nstatic uint8x8x4_t do_PsExclusionBlend(uint8x8x4_t s, uint8x8x4_t d) {\n\t// c = ((s+d-(s*d*2)/255)-d)*a + d = (s-(s*d*2)/255)*a + d\n\tuint16x8_t d_r16 = vmull_u8(s.val[2], d.val[2]);\n\tuint16x8_t d_g16 = vmull_u8(s.val[1], d.val[1]);\n\tuint16x8_t d_b16 = vmull_u8(s.val[0], d.val[0]);\n\td_r16 = vsubq_u16(vmovl_u8(s.val[2]), vshrq_n_u16(d_r16, 7));\n\td_g16 = vsubq_u16(vmovl_u8(s.val[1]), vshrq_n_u16(d_g16, 7));\n\td_b16 = vsubq_u16(vmovl_u8(s.val[0]), vshrq_n_u16(d_b16, 7));\n\td_r16 = vmulq_u16(d_r16, vmovl_u8(s.val[3]));\n\td_g16 = vmulq_u16(d_g16, vmovl_u8(s.val[3]));\n\td_b16 = vmulq_u16(d_b16, vmovl_u8(s.val[3]));\n\td.val[2] = vadd_u8(d.val[2], vshrn_n_u16(d_r16, 8));\n\td.val[1] = vadd_u8(d.val[1], vshrn_n_u16(d_g16, 8));\n\td.val[0] = vadd_u8(d.val[0], vshrn_n_u16(d_b16, 8));\n\treturn d;\n}\nstatic void TVPPsExclusionBlend_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) {\n\tdo_blend(TVPPsExclusionBlend_HDA_c, do_PsExclusionBlend, dest, src, len);\n}\nstatic void TVPPsExclusionBlend_o_NEON(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) {\n\tdo_blend(TVPPsExclusionBlend_HDA_o_c, do_PsAlphaBlend_so<do_PsExclusionBlend>, dest, src, len, opa);\n}\n#endif\n\n#if TVP_TLG6_W_BLOCK_SIZE != 8\n#error TVP_TLG6_W_BLOCK_SIZE must be 8 !\n#endif\n\nstatic uint8x8x4_t filter_insts_0_neon(uint8x8x4_t m) { return m; }\n// ( 1, IB+IG, IG, IR+IG)\nstatic uint8x8x4_t filter_insts_1_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[1]);\n\treturn m;\n}\n// ( 2, IB, IG+IB, IR+IB+IG)\nstatic uint8x8x4_t filter_insts_2_neon(uint8x8x4_t m) {\n\tm.val[1] = vadd_u8(m.val[1], m.val[0]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[1]);\n\treturn m;\n}\n// ( 3, IB+IR+IG, IG+IR, IR)\nstatic uint8x8x4_t filter_insts_3_neon(uint8x8x4_t m) {\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\treturn m;\n}\n// ( 4, IB+IR, IG+IB+IR, IR+IB+IR+IG)\nstatic uint8x8x4_t filter_insts_4_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[2]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[0]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[1]);\n\treturn m;\n}\n// ( 5, IB+IR, IG+IB+IR, IR)\nstatic uint8x8x4_t filter_insts_5_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[2]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[0]);\n\treturn m;\n}\n// ( 6, IB+IG, IG, IR)\nstatic uint8x8x4_t filter_insts_6_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\treturn m;\n}\n// ( 7, IB, IG+IB, IR)\nstatic uint8x8x4_t filter_insts_7_neon(uint8x8x4_t m) {\n\tm.val[1] = vadd_u8(m.val[1], m.val[0]);\n\treturn m;\n}\n// ( 8, IB, IG, IR+IG)\nstatic uint8x8x4_t filter_insts_8_neon(uint8x8x4_t m) {\n\tm.val[2] = vadd_u8(m.val[2], m.val[1]);\n\treturn m;\n}\n// ( 9, IB+IG+IR+IB, IG+IR+IB, IR+IB)\nstatic uint8x8x4_t filter_insts_9_neon(uint8x8x4_t m) {\n\tm.val[2] = vadd_u8(m.val[2], m.val[0]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\treturn m;\n}\n// (10, IB+IR, IG+IR, IR)\nstatic uint8x8x4_t filter_insts_10_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[2]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\treturn m;\n}\n// (11, IB, IG+IB, IR+IB)\nstatic uint8x8x4_t filter_insts_11_neon(uint8x8x4_t m) {\n\tm.val[1] = vadd_u8(m.val[1], m.val[0]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[0]);\n\treturn m;\n}\n// (12, IB, IG+IR+IB, IR+IB)\nstatic uint8x8x4_t filter_insts_12_neon(uint8x8x4_t m) {\n\tm.val[2] = vadd_u8(m.val[2], m.val[0]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\treturn m;\n}\n// (13, IB+IG, IG+IR+IB+IG, IR+IB+IG)\nstatic uint8x8x4_t filter_insts_13_neon(uint8x8x4_t m) {\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[0]);\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\treturn m;\n}\n// (14, IB+IG+IR, IG+IR, IR+IB+IG+IR)\nstatic uint8x8x4_t filter_insts_14_neon(uint8x8x4_t m) {\n\tm.val[1] = vadd_u8(m.val[1], m.val[2]);\n\tm.val[0] = vadd_u8(m.val[0], m.val[1]);\n\tm.val[2] = vadd_u8(m.val[2], m.val[0]);\n\treturn m;\n}\n// (15, IB, IG+(IB<<1), IR+(IB<<1))\nstatic uint8x8x4_t filter_insts_15_neon(uint8x8x4_t m) {\n\tuint8x8_t t = vshl_n_u8(m.val[0], 1);\n\tm.val[1] = vadd_u8(m.val[1], t);\n\tm.val[2] = vadd_u8(m.val[2], t);\n\treturn m;\n}\n\nstatic uint8x8x4_t tlg6_forward_input_neon(uint32_t* in) {\n\treturn vld4_u8((uint8_t*)__builtin_assume_aligned(in, 8));\n}\n\nstatic uint8x8x4_t tlg6_backward_input_neon(uint32_t* in) {\n\tuint8x8x4_t ret = vld4_u8((uint8_t*)__builtin_assume_aligned(in, 8));\n\tret.val[0] = vrev64_u8(ret.val[0]);\n\tret.val[1] = vrev64_u8(ret.val[1]);\n\tret.val[2] = vrev64_u8(ret.val[2]);\n\tret.val[3] = vrev64_u8(ret.val[3]);\n\treturn ret;\n}\n\nstatic inline uint8x8x4_t do_unpack_pixel_rgba(uint8x8x4_t minput) {\n\t// BGRA -> RGBA\n\tminput.val[0] = veor_u8(minput.val[0], minput.val[2]);\n\tminput.val[2] = veor_u8(minput.val[2], minput.val[0]);\n\tminput.val[0] = veor_u8(minput.val[0], minput.val[2]);\n\n\tuint8x8x2_t m01 = vtrn_u8(minput.val[0], minput.val[1]);\n\tuint8x8x2_t m23 = vtrn_u8(minput.val[2], minput.val[3]);\n\tuint16x8x2_t m = vtrnq_u16(\n\t\tvreinterpretq_u16_u8(vcombine_u8(m01.val[0], m01.val[1])),\n\t\tvreinterpretq_u16_u8(vcombine_u8(m23.val[0], m23.val[1])));\n\tminput.val[0] = vreinterpret_u8_u16(vget_low_u16(m.val[0]));\n\tminput.val[1] = vreinterpret_u8_u16(vget_high_u16(m.val[0]));\n\tminput.val[2] = vreinterpret_u8_u16(vget_low_u16(m.val[1]));\n\tminput.val[3] = vreinterpret_u8_u16(vget_high_u16(m.val[1]));\n\treturn minput;\n}\n\n/*\n +---+---+\n |lt | t |        / min(l, t), if lt >= max(l, t);\n +---+---+  ret = | max(l, t), if lt >= min(l, t);\n | l |ret|        \\ l + t - lt, otherwise;\n +---+---+\n*/\nstatic inline uint8x8_t do_med_neon(uint8x8_t a, uint8x8_t b, const uint8x8_t& c, uint8x8_t v) {\n\tuint8x8_t a2 = a;\n\ta = vmax_u8(a, b);\t// = max_a_b\n\tb = vmin_u8(b, a2);\t// = min_a_b\n\tv = vadd_u8(v, a);\n\ta = vmin_u8(a, c);\t// = max_a_b < c ? max_a_b : c\n\tv = vadd_u8(v, b);\n\ta = vmax_u8(a, b);\t// = min_a_b < a ? a : min_a_b\n\treturn vsub_u8(v, a);\n}\n\n#define vshr_n_u8_64(s, n) vreinterpret_u8_u64(vshr_n_u64(vreinterpret_u64_u8(s), n))\n\ntemplate<\n\tuint8x8x4_t filter(uint8x8x4_t),\n\tuint8x8x4_t input(uint32_t *)>\nstatic inline void do_filter_med_neon(uint32_t& inp, uint32_t& inup, uint32_t *in, uint32_t *prevline, uint32_t *curline) {\n\tuint8x8_t p = vreinterpret_u8_u32(vdup_n_u32(inp));\n\tuint8x8_t up = vreinterpret_u8_u32(vdup_n_u32(inup));\n\tuint8x8x4_t minput = input(in);\n\tminput = filter(minput);\n\tminput = do_unpack_pixel_rgba(minput);\n\tuint8x8_t u;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_med_neon(p, u, up, minput.val[0]);\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_med_neon(p, u, up, minput.val[1]);\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_med_neon(p, u, up, minput.val[2]);\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_med_neon(p, u, up, minput.val[3]);\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_med_neon(p, u, up, vshr_n_u8_64(minput.val[0], 32));\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_med_neon(p, u, up, vshr_n_u8_64(minput.val[1], 32));\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_med_neon(p, u, up, vshr_n_u8_64(minput.val[2], 32));\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_med_neon(p, u, up, vshr_n_u8_64(minput.val[3], 32));\n\tup = u;\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tinp = curline[-1];\n\tinup = vget_lane_u32(vreinterpret_u32_u8(u), 0);\n}\n\nstatic inline uint8x8_t do_avg_neon(const uint8x8_t &a, const uint8x8_t &b, const uint8x8_t &v) {\n\treturn vadd_u8(vrhadd_u8(a, b), v);\n}\n\ntemplate<\n\tuint8x8x4_t filter(uint8x8x4_t),\n\tuint8x8x4_t input(uint32_t *)>\ninline void do_filter_avg_neon(tjs_uint32& inp, tjs_uint32& up, tjs_uint32 *in, tjs_uint32 *prevline, tjs_uint32 *curline) {\n\tuint8x8_t p = vreinterpret_u8_u32(vdup_n_u32(inp));\n\tuint8x8x4_t minput = input(in);\n\tminput = filter(minput);\n\tminput = do_unpack_pixel_rgba(minput);\n\tuint8x8_t u;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_avg_neon(p, u, minput.val[0]);\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_avg_neon(p, u, minput.val[1]);\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_avg_neon(p, u, minput.val[2]);\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_avg_neon(p, u, minput.val[3]);\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_avg_neon(p, u, vshr_n_u8_64(minput.val[0], 32));\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_avg_neon(p, u, vshr_n_u8_64(minput.val[1], 32));\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tu = vld1_u8((uint8_t*)__builtin_assume_aligned(prevline, 8));\n\tp = do_avg_neon(p, u, vshr_n_u8_64(minput.val[2], 32));\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\n\tu = vshr_n_u8_64(u, 32);\n\tp = do_avg_neon(p, u, vshr_n_u8_64(minput.val[3], 32));\n\t*curline++ = vget_lane_u32(vreinterpret_u32_u8(p), 0);\n\tprevline += 2;\n\n\tinp = curline[-1];\n\tup = vget_lane_u32(vreinterpret_u32_u8(u), 0);\n}\n\n/*\n\tchroma/luminosity decoding\n\t(this does reordering, color correlation filter, MED/AVG  at a time)\n*/\nstatic void TVPTLG6DecodeLine_NEON(tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width/*, tjs_int start_block*/, tjs_int block_limit, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir)\n{\n// \tstd::vector<tjs_uint32> tmp; tmp.resize(TVP_TLG6_W_BLOCK_SIZE * (block_limit - start_block)); tjs_uint32* _curline = curline;\n// \tTVPTLG6DecodeLine_c(prevline, &tmp.front(), width, start_block, block_limit, filtertypes, skipblockbytes, in, initialp, oddskip, dir);\n\ttjs_int start_block = 0;\n\tuint32_t p, up;\n\n\tif(start_block)\n\t{\n\t\tprevline += start_block * TVP_TLG6_W_BLOCK_SIZE;\n\t\tcurline += start_block * TVP_TLG6_W_BLOCK_SIZE;\n\t\tp = curline[-1];\n\t\tup = prevline[-1];\n\t}\n\telse\n\t{\n\t\tp = up = initialp;\n\t}\n\n\toddskip *= TVP_TLG6_W_BLOCK_SIZE;\t// oddskip * 8\n\tif (dir & 1) {\n\t\t// forward\n\t\tskipblockbytes -= TVP_TLG6_W_BLOCK_SIZE;\n\t\tin += skipblockbytes * start_block;\n\t\tin += oddskip;\n\t\tfor (int i = start_block; i < block_limit; i++) {\n\t\t\tif (i & 1) {\n\t\t\t\tin += oddskip;\n\t\t\t} else {\n\t\t\t\tin -= oddskip;\n\t\t\t}\n\t\t\tswitch (filtertypes[i]) {\n#define TVP_TLG6_DO_CHROMA_DECODE_FORWARD(N) \\\n\tcase (N<<1)+0: do_filter_med_neon<filter_insts_##N##_neon, tlg6_forward_input_neon>(p, up, in, prevline, curline); break;\\\n\tcase (N<<1)+1: do_filter_avg_neon<filter_insts_##N##_neon, tlg6_forward_input_neon>(p, up, in, prevline, curline); break;\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(0);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(1);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(2);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(3);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(4);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(5);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(6);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(7);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(8);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(9);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(10);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(11);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(12);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(13);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(14);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_FORWARD(15);\n#undef TVP_TLG6_DO_CHROMA_DECODE_FORWARD\n\t\t\t}\n\t\t\tprevline += 8; curline += 8; in += 8;\n\t\t\tin += skipblockbytes;\n\t\t}\n\t} else {\n\t\t// backward\n\t\tskipblockbytes += TVP_TLG6_W_BLOCK_SIZE;\n\t\tin += skipblockbytes * start_block;\n\t\tin += oddskip;\n\t\t//in += (TVP_TLG6_W_BLOCK_SIZE - 1);\n\t\tin += TVP_TLG6_W_BLOCK_SIZE;\n\t\tfor (int i = start_block; i < block_limit; i++) {\n\t\t\tif (i & 1) {\n\t\t\t\tin += oddskip;\n\t\t\t} else{\n\t\t\t\tin -= oddskip;\n\t\t\t}\n\t\t\tin -= 8;\n\t\t\tswitch (filtertypes[i]) {\n#define TVP_TLG6_DO_CHROMA_DECODE_BACKWARD(N) \\\n\tcase (N<<1)+0: do_filter_med_neon<filter_insts_##N##_neon, tlg6_backward_input_neon>(p, up, in, prevline, curline); break;\\\n\tcase (N<<1)+1: do_filter_avg_neon<filter_insts_##N##_neon, tlg6_backward_input_neon>(p, up, in, prevline, curline); break;\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(0);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(1);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(2);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(3);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(4);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(5);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(6);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(7);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(8);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(9);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(10);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(11);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(12);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(13);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(14);\n\t\t\t\tTVP_TLG6_DO_CHROMA_DECODE_BACKWARD(15);\n#undef TVP_TLG6_DO_CHROMA_DECODE_BACKWARD\n\t\t\t}\n\t\t\tprevline += 8; curline += 8;\n\t\t\tin += skipblockbytes;\n\t\t}\n\t}\n\n// \tfor (int i = 0; i < tmp.size(); ++i) {\n// \t\tassert(tmp[i] == _curline[i]);\n// \t}\n}\n\nstatic void TVPTLG5ComposeColors3To4_NEON(tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const * buf, tjs_int width)\n{\n    const tjs_uint8 * p2 = buf[0];\n    const tjs_uint8 * p1 = buf[1];\n    const tjs_uint8 * p0 = buf[2];\n    int x = 0;\n    uint8x8x3_t pc;\n    pc.val[0] = vdup_n_u8(0);\n    pc.val[1] = vdup_n_u8(0);\n    pc.val[2] = vdup_n_u8(0);\n    uint8x8x4_t rgba;\n    rgba.val[3] = vdup_n_u8(0xFF);\n    for(x = 0; x < width - 7; x += 8) {\n        uint8x8x3_t c;\n        c.val[1] = vld1_u8(p1 + x);\n        c.val[0] = vadd_u8(vld1_u8(p0 + x), c.val[1]);\n        c.val[2] = vadd_u8(vld1_u8(p2 + x), c.val[1]);\n        pc.val[0] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[0], 7)), c.val[0]);\n        pc.val[1] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[1], 7)), c.val[1]);\n        pc.val[2] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[2], 7)), c.val[2]);\n        for(int i = 0; i < 7; ++i) {\n            c.val[0] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[0]), 8));\n            c.val[1] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[1]), 8));\n            c.val[2] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[2]), 8));\n            pc.val[0] = vadd_u8(pc.val[0], c.val[0]);\n            pc.val[1] = vadd_u8(pc.val[1], c.val[1]);\n            pc.val[2] = vadd_u8(pc.val[2], c.val[2]);\n        }\n\t\tuint8x8x4_t up = vld4_u8((uint8_t*)__builtin_assume_aligned(upper, 8));\n        rgba.val[0] = vadd_u8(pc.val[0], up.val[0]);\n        rgba.val[1] = vadd_u8(pc.val[1], up.val[1]);\n        rgba.val[2] = vadd_u8(pc.val[2], up.val[2]);\n\t\tvst4_u8((uint8_t*)__builtin_assume_aligned(outp, 8), rgba);\n        outp += 4 * 8;\n        upper += 4 * 8;\n    }\n\n    if(x < width) {\n        tjs_uint8 _pc[3];\n        tjs_uint8 _c[3];\n        _pc[0] = vget_lane_u8(pc.val[0], 7);\n        _pc[1] = vget_lane_u8(pc.val[1], 7);\n        _pc[2] = vget_lane_u8(pc.val[2], 7);\n        for(; x < width; x++)\n        {\n            _c[0] = p0[x];\n            _c[1] = p1[x];\n            _c[2] = p2[x];\n            _c[0] += _c[1]; _c[2] += _c[1];\n            *(tjs_uint32 *)outp =\n                ((((_pc[0] += _c[0]) + upper[0]) & 0xff)      ) +\n                ((((_pc[1] += _c[1]) + upper[1]) & 0xff) <<  8) +\n                ((((_pc[2] += _c[2]) + upper[2]) & 0xff) << 16) +\n                0xff000000;\n            outp += 4;\n            upper += 4;\n        }\n    }\n}\n\nstatic void TVPTLG5ComposeColors4To4_NEON(tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const * buf, tjs_int width)\n{\n#ifdef TEST_ARM_NEON_CODE\n\tTVPTLG5ComposeColors4To4_c(outp, upper, buf, width);\n\ttjs_uint8 *orig_outp = outp;\n\ttjs_uint8 *test_outp = outp = new tjs_uint8[width * 4];\n#endif\n    const tjs_uint8 * p2 = buf[0];\n    const tjs_uint8 * p1 = buf[1];\n    const tjs_uint8 * p0 = buf[2];\n    const tjs_uint8 * p3 = buf[3];\n    int x = 0;\n    uint8x8x4_t pc;\n    pc.val[0] = vdup_n_u8(0);\n    pc.val[1] = vdup_n_u8(0);\n    pc.val[2] = vdup_n_u8(0);\n    pc.val[3] = vdup_n_u8(0);\n    for(x = 0; x < width - 7; x += 8) {\n        uint8x8x4_t c;\n        c.val[1] = vld1_u8(p1 + x);\n        c.val[0] = vadd_u8(vld1_u8(p0 + x), c.val[1]);\n        c.val[2] = vadd_u8(vld1_u8(p2 + x), c.val[1]);\n        c.val[3] = vld1_u8(p3 + x);\n        pc.val[0] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[0], 7)), c.val[0]);\n        pc.val[1] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[1], 7)), c.val[1]);\n        pc.val[2] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[2], 7)), c.val[2]);\n        pc.val[3] = vadd_u8(vdup_n_u8(vget_lane_u8(pc.val[3], 7)), c.val[3]);\n        for(int i = 0; i < 7; ++i) {\n            c.val[0] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[0]), 8));\n            c.val[1] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[1]), 8));\n            c.val[2] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[2]), 8));\n            c.val[3] = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(c.val[3]), 8));\n            pc.val[0] = vadd_u8(pc.val[0], c.val[0]);\n            pc.val[1] = vadd_u8(pc.val[1], c.val[1]);\n            pc.val[2] = vadd_u8(pc.val[2], c.val[2]);\n            pc.val[3] = vadd_u8(pc.val[3], c.val[3]);\n        }\n\t\tuint8x8x4_t up = vld4_u8((uint8_t*)__builtin_assume_aligned(upper, 8));\n        uint8x8x4_t rgba;\n        rgba.val[0] = vadd_u8(pc.val[0], up.val[0]);\n        rgba.val[1] = vadd_u8(pc.val[1], up.val[1]);\n        rgba.val[2] = vadd_u8(pc.val[2], up.val[2]);\n        rgba.val[3] = vadd_u8(pc.val[3], up.val[3]);\n\t\tvst4_u8((uint8_t*)__builtin_assume_aligned(outp, 8), rgba);\n        outp += 4 * 8;\n        upper += 4 * 8;\n    }\n\n    if(x < width) {\n        tjs_uint8 _pc[4];\n        tjs_uint8 _c[4];\n        _pc[0] = vget_lane_u8(pc.val[0], 7);\n        _pc[1] = vget_lane_u8(pc.val[1], 7);\n        _pc[2] = vget_lane_u8(pc.val[2], 7);\n        _pc[3] = vget_lane_u8(pc.val[3], 7);\n        for(; x < width; x++)\n        {\n            _c[0] = p0[x];\n            _c[1] = p1[x];\n            _c[2] = p2[x];\n            _c[3] = p3[x];\n            _c[0] += _c[1]; _c[2] += _c[1];\n            *(tjs_uint32 *)outp =\n                ((((_pc[0] += _c[0]) + upper[0]) & 0xff)      ) +\n                ((((_pc[1] += _c[1]) + upper[1]) & 0xff) <<  8) +\n                ((((_pc[2] += _c[2]) + upper[2]) & 0xff) << 16) +\n                ((((_pc[3] += _c[3]) + upper[3]) & 0xff) << 24);\n            outp += 4;\n            upper += 4;\n        }\n    }\n#ifdef TEST_ARM_NEON_CODE\n\tfor (int i = 0; i < width * 4; ++i) {\n\t\tassert(test_outp[i] == orig_outp[i]);\n\t}\n\tdelete[]test_outp;\n#endif\n}\n\nstatic tjs_int TVPTLG5DecompressSlide_NEON(tjs_uint8 *out, const tjs_uint8 *in, tjs_int insize, tjs_uint8 *text, tjs_int initialr) {\n\t// test\n// \tstd::vector<tjs_uint8> tmp; tmp.resize(1024 * 768 * 4);\n// \tstd::vector<tjs_uint8> ttext; ttext.insert(ttext.begin(), text, text + 4096 + 16);\n// \ttjs_uint8 *pout = out;\n// \ttjs_int rr = TVPTLG5DecompressSlide_c(&tmp[0], in, insize, &ttext[0], initialr);\n\t\n\ttjs_int r = initialr;\n\ttjs_uint flags = 0;\n\tconst tjs_uint8 *inlim = in + insize;\n\twhile (in < inlim) {\n\t\tif (((flags >>= 1) & 256) == 0) {\n\t\t\tflags = in[0] | 0xff00;\n\t\t\tin++;\n\t\t\tif (flags == 0xff00 && r < (4096 - 8) && in < (inlim - 8)) {\t// copy 8byte\n\t\t\t\tuint8x8_t c = vld1_u8(in);\n\t\t\t\tvst1_u8(out, c);;\n\t\t\t\tvst1_u8(&text[r], c);;\n\t\t\t\tr += 8;\n\t\t\t\tin += 8;\n\t\t\t\tout += 8;\n\t\t\t\tflags = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (flags & 1) {\n\t\t\ttjs_uint16 in16 = *(tjs_uint16*)in;\n\t\t\ttjs_uint mpos = in16 & 0xFFF;\n\t\t\ttjs_uint mlen = (in16 >> 12) + 3;\n\t\t\tin += 2;\n\t\t\tif (mlen == 18)\n\t\t\t\tmlen += *in++;\n \t\t\tif (mlen > 15 && (mpos - r > 15 || r - mpos > 15)) {\n\t\t\t\tif ((mpos + mlen) < 4096 && (r + mlen) < 4096) {\n\t\t\t\t\ttjs_int count = mlen >> 4;\n\t\t\t\t\twhile (count--) {\n\t\t\t\t\t\tuint8x16_t c = vld1q_u8(&text[mpos]);\n\t\t\t\t\t\tvst1q_u8(out, c);\n\t\t\t\t\t\tvst1q_u8(&text[r], c);\n\t\t\t\t\t\tmpos += 16; r += 16; out += 16;\n\t\t\t\t\t}\n\t\t\t\t\tmlen &= 0x0f;\t// ���\n\t\t\t\t\twhile (mlen--) {\n\t\t\t\t\t\tout[0] = text[r++] = text[mpos++]; out++;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n#if 0\n\t\t\t\twhile (mlen) {\n\t\t\t\t\tuint8x16_t c = vld1q_u8(&text[mpos]);\n\t\t\t\t\tvst1q_u8(out, c);\n\t\t\t\t\tvst1q_u8(&text[r], c); // direct write to text is OK due to the extra 16 bytes\n\t\t\t\t\ttjs_int next = mlen < 16 ? mlen : 16;\n\t\t\t\t\tif (mpos + next > 4095) {\n\t\t\t\t\t\tnext = 4096 - mpos;\n\t\t\t\t\t\tmpos = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmpos += next;\n\t\t\t\t\t}\n\t\t\t\t\tout += next;\n\t\t\t\t\tr += next;\n\t\t\t\t\tmlen -= next;\n\t\t\t\t\tif (r > 4095) {\n\t\t\t\t\t\tr &= 0x0fff;\n\t\t\t\t\t\tvst1q_u8(&text[r - 16], c);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\n#endif\n\t\t\t}\n\t\t\twhile (mlen--) {\n\t\t\t\tout[0] = text[r++] = text[mpos++]; out++;\n\t\t\t\tmpos &= 0x0fff;\n\t\t\t\tr &= 0x0fff;\n\t\t\t}\n\t\t} else {\n\t\t\tunsigned char c = in[0]; in++;\n\t\t\tout[0] = c; out++;\n\t\t\ttext[r++] = c;\n\t\t\tr &= 0x0fff;\n\t\t}\n\t}\n\n\t// test\n// \tassert(rr == r);\n// \tfor (int i = 0; i < out - pout; ++i) {\n// \t\tassert(tmp[i] == pout[i]);\n// \t}\n\n\treturn r;\n}\n\n//#include <cpu-features.h>\n\nstatic tjs_uint32 *testbuff = NULL;\nstatic tjs_uint32 *testdata1 = NULL;\nstatic tjs_uint32 *testdata2 = NULL;\nstatic tjs_uint32 *testdest1 = NULL;\nstatic tjs_uint32 *testdest2 = NULL;\nstatic tjs_uint32 *testtable = NULL;\nstatic tjs_uint8  *testrule = NULL;\n#include <stdlib.h>\n#include <stdio.h>\n\n#ifdef __cplusplus\n#define FUNC_API extern \"C\"\n#else\n#define FUNC_API\n#endif\nFUNC_API int TVPShowSimpleMessageBox(const char * text, const char * caption, unsigned int nButton, const char **btnText); // C-style\ntjs_uint32 TVPGetRoughTickCount32();\n\nstatic void ShowInMessageBox(const char *text) {\n\tif (!text || !*text) return;\n\tconst char *btnText = \"OK\";\n\tTVPShowSimpleMessageBox(text, \"Log\", 1, &btnText);\n}\n\nstatic void InitTestData() {\n    if(!testtable) {\n        testtable = (tjs_uint32*)malloc(256 * sizeof(tjs_uint32));\n        for(int x = 0; x < 256; ++x) {\n            testtable[x] = rand() & 0xFF;\n        }\n        testrule = (tjs_uint8*)malloc(256 * 256);\n        for(int x = 0; x < 256 * 256; ++x) {\n            testrule[x] = rand() & 0xFF;\n        }\n\t\ttestbuff = (tjs_uint32*)malloc((256 * 256 * 4 + 2) * sizeof(tjs_uint32));\n\t\ttestdest1 = testbuff;\n\t\ttestdest2 = testdest1 + 256 * 256;\n\t\ttestdata1 = testdest2 + 256 * 256;\n        testdata2 = testdata1 + 256 * 256;\n    }\n\tint obfu = 65531;\n    for(int x = 0; x < 256; ++x) {\n        for(int y = 0; y < 256; ++y) {\n            typedef struct {\n                unsigned char a;\n                unsigned char r;\n                unsigned char g;\n                unsigned char b;\n            } clr;\n            clr *clr1 = (clr*)(testdata1 + 256 * y + x),\n                *clr2 = (clr*)(testdata2 + 256 * y + x);\n            clr1->a = 255 - x; clr2->a = 255 - y;\n            clr1->r = x; clr2->r = y;\n            clr1->g = y; clr2->g = 255 - x;\n            clr1->b = 255 - y; clr2->b = x;\n\t\t\tif (y == 0) {\n\t\t\t\tclr1->a = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr2->a = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr1->r = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr2->r = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr1->g = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr2->g = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr1->b = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n\t\t\t\tclr2->b = obfu;\n\t\t\t\tobfu = obfu * 3 + 29;\n        }\n    }\n    }\n    memcpy(testdest1, testdata2, 256 * 256 * 4);\n    memcpy(testdest2, testdata2, 256 * 256 * 4);\n}\n\n#if defined(TEST_ARM_NEON_CODE) || defined(LOG_NEON_TEST)\nstatic void CheckTestData(const char *pszFuncName)\n{\n\ttypedef union{\n\t\tstruct {\n\t\t\tunsigned char r;\n\t\t\tunsigned char g;\n\t\t\tunsigned char b;\n\t\t\tunsigned char a;\n\t\t};\n\t\tunsigned long u32;\n\t} clr; clr clr1, clr2;\n\tfor (int i = 0; i < 256 * 256; ++i) {\n\t\tclr1.u32 = testdest1[i];\n\t\tclr2.u32 = testdest2[i];\n\t\tif (clr1.a <= 1 && clr2.a <= 1) continue;\n\t\tif (abs(clr1.a - clr2.a) > 2 ||\n\t\t\tabs(clr1.r - clr2.r) > 2 ||\n\t\t\tabs(clr1.g - clr2.g) > 2 ||\n\t\t\tabs(clr1.b - clr2.b) > 2)\n\t\t{\n\t\t\tchar tmp[256];\n\t\t\tsprintf(tmp, \"test fail on function %s\", pszFuncName);\n#ifdef _MSC_VER\n\t\t\tcv::Mat test1(256, 256, CV_8UC4, testdest1, 1024);\n\t\t\tcv::Mat test2(256, 256, CV_8UC4, testdest2, 1024);\n#endif\n\t\t\tShowInMessageBox(tmp);\n#if !defined(WIN32) && 0\n\t\t\tconst char bmphdr[] = \"\\x42\\x4D\\x36\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x36\\x00\\x00\\x00\\x28\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x01\\x00\\x20\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x12\\x0B\\x00\\x00\\x12\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\n\t\t\tFILE* f = fopen(\"/sdcard/testdest1.bmp\", \"wb\");\n\t\t\tfwrite(bmphdr, sizeof(bmphdr), 1, f);\n\t\t\tfwrite(testdest1, 256 * 256, 4, f);\n\t\t\tfclose(f);\n\t\t\tf = fopen(\"/sdcard/testdest2.bmp\", \"wb\");\n\t\t\tfwrite(bmphdr, sizeof(bmphdr), 1, f);\n\t\t\tfwrite(testdest2, 256 * 256, 4, f);\n\t\t\tfclose(f);\n#endif\n\t\t\treturn;\n\t\t}\n\t}\n\t//SDL_Log(\"cheking %s pass\", pszFuncName);\n}\n#endif\nstatic void CheckTestData_RGB(const char *pszFuncName)\n{\n\ttypedef union{\n\t\tstruct {\n\t\t\tunsigned char r;\n\t\t\tunsigned char g;\n\t\t\tunsigned char b;\n\t\t\tunsigned char a;\n\t\t};\n\t\tunsigned long u32;\n\t} clr; clr clr1, clr2;\n\tfor (int i = 0; i < 256 * 256; ++i) {\n\t\tclr1.u32 = testdest1[i];\n\t\tclr2.u32 = testdest2[i];\n\t\tif (abs(clr1.r - clr2.r) > 2 ||\n\t\t\tabs(clr1.g - clr2.g) > 2 ||\n\t\t\tabs(clr1.b - clr2.b) > 2)\n\t\t{\n\t\t\tchar tmp[256];\n\t\t\tsprintf(tmp, \"test fail on function %s\", pszFuncName);\n#ifdef _MSC_VER\n\t\t\tcv::Mat test1(256, 256, CV_8UC4, testdest1, 1024);\n\t\t\tcv::Mat test2(256, 256, CV_8UC4, testdest2, 1024);\n#endif\n\t\t\tShowInMessageBox(tmp);\n\t\t\t//assert(!pszFuncName);\n\t\t\treturn;\n\t\t}\n\t}\n\t//SDL_Log(\"cheking %s pass\", pszFuncName);\n}\n\nstatic void testTLG6_chroma()\n{\n\ttjs_uint8 tmpbuff[(32 + 256) * 4 * 2 + 16];\n\ttjs_uint8 *block_src_ref = (tjs_uint8*)((((intptr_t)tmpbuff) + 7) & ~7);\n\ttjs_uint8 *block_src = block_src_ref + 32 * 4;\n\ttjs_uint32 *testdest1 = (tjs_uint32*)(block_src + 32 * 4);\n\ttjs_uint32 *testdest2 = testdest1 + 256;\n\ttjs_uint8 *psrc[4] = {\n\t\tblock_src,\n\t\tblock_src + 1,\n\t\tblock_src + 3,\n\t\tblock_src + 2,\n\t};\n\tfor (int i = 0; i < 32; ++i) {\n\t\tfor (int j = 0; j < 32 * 4; ++j) {\n\t\t\tblock_src_ref[j] = 240 - i - j * 3;\n\t\t\tblock_src[j] = 16 + i + j * 3;\n\t\t}\n\t\tfor (tjs_uint8 ft = 0; ft < 32; ++ft) {\n\t\t\tTVPTLG6DecodeLine_NEON((tjs_uint32 *)block_src_ref, testdest1, 64, /*0,*/ 1, &ft, 0, (tjs_uint32 *)block_src, 0, 0, 0);\n\t\t\tTVPTLG6DecodeLineGeneric_c((tjs_uint32 *)block_src_ref, testdest2, 64, 0, 1, &ft, 0, (tjs_uint32 *)block_src, 0, 0, 0);\n\t\t\tif (memcmp(testdest1, testdest2, 8 * 4) != 0) {\n\t\t\t\tShowInMessageBox(\"test fail on function TVPTLG6DecodeLineGeneric\");\n\t\t\t\tassert(0);\n\t\t\t}\n\t\t}\n\n\t\tTVPTLG5ComposeColors3To4_NEON((tjs_uint8*)testdest1, block_src_ref, psrc, 67);\n\t\tTVPTLG5ComposeColors3To4_c((tjs_uint8*)testdest2, block_src_ref, psrc, 67);\n\t\tif (memcmp(testdest1, testdest2, 8 * 4) != 0) {\n\t\t\tShowInMessageBox(\"test fail on function TVPTLG5ComposeColors3To4\");\n\t\t\tassert(0);\n\t\t}\n\t\tTVPTLG5ComposeColors4To4_NEON((tjs_uint8*)testdest1, block_src_ref, psrc, 67);\n\t\tTVPTLG5ComposeColors4To4_c((tjs_uint8*)testdest2, block_src_ref, psrc, 67);\n\t\tif (memcmp(testdest1, testdest2, 8 * 4) != 0) {\n\t\t\tShowInMessageBox(\"test fail on function TVPTLG5ComposeColors4To4\");\n\t\t\tassert(0);\n\t\t}\n\t}\n}\n\n#ifdef LOG_NEON_TEST\n#define SHOW_AND_CLEAR_LOG ShowInMessageBox(LogData); pLogData = LogData;\n#else\n#define SHOW_AND_CLEAR_LOG\n#endif\n\n#ifdef TEST_ARM_NEON_CODE\n\n#define REGISTER_TVPGL_BLEND_FUNC_2(origf, f) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, testdata1, 256 * 256);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, testdata1, 256 * 256);\\\n\tCheckTestData(#f);\n#define REGISTER_TVPGL_BLEND_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, testdata1, 256 * 256, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, testdata1, 256 * 256, __VA_ARGS__);\\\n\tCheckTestData(#f);\n#define REGISTER_TVPGL_STRECH_FUNC_2(origf, f) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 16 * 256, testdata1, 0, 1 << 16);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 16 * 256, testdata1, 0, 1 << 16);\\\n\tCheckTestData(#f);\n#define REGISTER_TVPGL_STRECH_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, 16 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, 16 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n\tCheckTestData(#f);\n#define REGISTER_TVPGL_LINTRANS_FUNC_2(origf, f) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 8 * 256, testdata1, 0, 0, 1<<16, 1<<16, 64);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 8 * 256, testdata1, 0, 0, 1<<16, 1<<16, 64);\\\n\tCheckTestData(#f);\n#define REGISTER_TVPGL_LINTRANS_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, 8 * 256, testdata1, 0, 0, 1<<16, 1<<16, 64, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, 8 * 256, testdata1, 0, 0, 1<<16, 1<<16, 64, __VA_ARGS__);\\\n    CheckTestData(#f);\n#define REGISTER_TVPGL_UNIVTRANS_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n    CheckTestData_RGB(#f);\n#define REGISTER_TVPGL_CUSTOM_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, __VA_ARGS__);\\\n    CheckTestData(#f);\n#define REGISTER_TVPGL_CUSTOM_FUNC_RGB(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, __VA_ARGS__);\\\n    CheckTestData_RGB(#f);\n#define REGISTER_TVPGL_CUSTOM_FUNC_TYPE(origf, f, DT, ...) \\\n    InitTestData();\\\n    origf##_c((DT)testdest2, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON((DT)testdest1, __VA_ARGS__);\\\n    CheckTestData(#f);\n#else\n#ifdef LOG_NEON_TEST\n\nstatic tjs_uint32 lastTick1, lastTick2;\nstatic tjs_int tickC, tickNEON;\nstatic unsigned int LogDataSize = 1024;\nstatic char *LogData, *pLogData;\n\nstatic void AddLog(const char *format, ...) {\n\tva_list args;\n\tva_start(args, format);\n\tchar buf[256];\n\tvsnprintf(buf, 256 - 3, format, args);\n\tchar *p = buf;\n\tif (!LogData) {\n\t\tLogData = (char*)TJS_malloc(LogDataSize);\n\t\tpLogData = LogData;\n\t}\n\n\twhile (*p) {\n\t\tif (LogData + LogDataSize - pLogData <= 2) {\n\t\t\tint used = pLogData - LogData;\n\t\t\tLogDataSize += 1024;\n\t\t\tLogData = (char*)TJS_realloc(LogData, LogDataSize);\n\t\t\tpLogData = LogData + used;\n\t\t}\n\t\t*pLogData++ = *p++;\n\t}\n\t*pLogData++ = '\\n';\n\t*pLogData = '\\0';\n\n\n\tva_end(args);\n}\n#ifdef _MSC_VER\n#define TEST_COUNT 0\n#else\n#define TEST_COUNT 200\n#endif\n#include \"tjsCommHead.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"UtilStreams.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerBitmapImpl.h\"\n#define TVP_clNone\t\t\t\t((tjs_uint32)(0x1fffffff))\nvoid TVPLoadTLG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx, tTVPGraphicLoadMode mode);\nstatic void logTLG6_chroma() {\n\tif (!TEST_COUNT) return;\n\ttjs_uint8 tmpbuff[(32 + 256) * 4 * 2 + 16];\n\ttjs_uint8 *block_src_ref = (tjs_uint8*)((((intptr_t)tmpbuff) + 7) & ~7);\n\ttjs_uint8 *block_src = block_src_ref + 32 * 4;\n\ttjs_uint32 *testdest1 = (tjs_uint32*)(block_src + 32 * 4);\n\ttjs_uint32 *testdest2 = testdest1 + 256;\n\ttjs_uint8 *psrc[4] = {\n\t\tblock_src,\n\t\tblock_src + 1,\n\t\tblock_src + 3,\n\t\tblock_src + 2,\n\t};\n\ttickC = 0; tickNEON = 0;\n\tfor (int i = 0; i < 32; ++i) {\n\t\tfor (int j = 0; j < 32 * 4; ++j) {\n\t\t\tblock_src_ref[j] = 240 - i - j * 3;\n\t\t\tblock_src[j] = 16 + i + j * 3;\n\t\t}\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 4; ++n)\n\t\tfor (tjs_uint8 ft = 0; ft < 32; ++ft) {\n\t\t\tTVPTLG6DecodeLineGeneric_c((tjs_uint32 *)block_src_ref, testdest2, 64, 0, 1, &ft, 0, (tjs_uint32 *)block_src, 0, 0, 0);\n\t\t}\n\t\ttickC += TVPGetRoughTickCount32() - lastTick1;\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 4; ++n)\n\t\tfor (tjs_uint8 ft = 0; ft < 32; ++ft) {\n\t\t\tTVPTLG6DecodeLine_NEON((tjs_uint32 *)block_src_ref, testdest2, 64, 0, 1, &ft, 0, (tjs_uint32 *)block_src, 0, 0, 0);\n\t\t}\n\t\ttickNEON += TVPGetRoughTickCount32() - lastTick1;\n\t}\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", \"TVPTLG6DecodeLineGeneric\", tickC, tickNEON, (float)tickNEON / tickC * 100);\n\n\ttickC = 0; tickNEON = 0;\n\tfor (int i = 0; i < 32; ++i) {\n\t\tfor (int j = 0; j < 32 * 4; ++j) {\n\t\t\tblock_src_ref[j] = 240 - i - j * 3;\n\t\t\tblock_src[j] = 16 + i + j * 3;\n\t\t}\n\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 16; ++n) TVPTLG5ComposeColors3To4_c((tjs_uint8*)testdest2, block_src_ref, psrc, 67);\n\t\ttickC += TVPGetRoughTickCount32() - lastTick1;\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 16; ++n) TVPTLG5ComposeColors3To4_NEON((tjs_uint8*)testdest1, block_src_ref, psrc, 67);\n\t\ttickNEON += TVPGetRoughTickCount32() - lastTick1;\n\t}\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", \"TVPTLG5ComposeColors3To4\", tickC, tickNEON, (float)tickNEON / tickC * 100);\n\n\ttickC = 0; tickNEON = 0;\n\tfor (int i = 0; i < 32; ++i) {\n\t\tfor (int j = 0; j < 32 * 4; ++j) {\n\t\t\tblock_src_ref[j] = 240 - i - j * 3;\n\t\t\tblock_src[j] = 16 + i + j * 3;\n\t\t}\n\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 16; ++n) TVPTLG5ComposeColors4To4_c((tjs_uint8*)testdest2, block_src_ref, psrc, 67);\n\t\ttickC += TVPGetRoughTickCount32() - lastTick1;\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int n = 0; n < TEST_COUNT * 16; ++n) TVPTLG5ComposeColors4To4_NEON((tjs_uint8*)testdest1, block_src_ref, psrc, 67);\n\t\ttickNEON += TVPGetRoughTickCount32() - lastTick1;\n\t}\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", \"TVPTLG5ComposeColors4To4\", tickC, tickNEON, (float)tickNEON / tickC * 100);\n\n\tFILE *fp = fopen(\"/sdcard/KR2/test.tlg\", \"rb\");\n\tif (fp) {\n\t\tfseek(fp, 0, SEEK_END);\n\t\tsize_t n = ftell(fp);\n\t\tfseek(fp, 0, SEEK_SET);\n\t\ttTVPMemoryStream memio; memio.SetSize(n);\n\t\tfread(memio.GetInternalBuffer(), 1, n, fp);\n\t\tfclose(fp);\n\t\tstatic tTVPBitmap *testbmp = nullptr;\n\t\tTVPTLG5ComposeColors3To4 = TVPTLG5ComposeColors3To4_NEON;\n\t\tTVPTLG5ComposeColors4To4 = TVPTLG5ComposeColors4To4_NEON;\n\t\tTVPTLG5DecompressSlide = TVPTLG5DecompressSlide_c;\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int i = 0; i < 32; ++i) {\n\t\t\tmemio.SetPosition(0);\n\t\t\tTVPLoadTLG(nullptr, nullptr, [](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int {\n\t\t\t\tif (!testbmp) testbmp = new tTVPBitmap(w, h, 32);\n\t\t\t\treturn testbmp->GetPitch();\n\t\t\t}, [](void *callbackdata, tjs_int y)->void* {\n\t\t\t\treturn testbmp->GetScanLine(y);\n\t\t\t}, [](void *callbackdata, const ttstr & name, const ttstr & value){}, &memio, TVP_clNone, glmNormal);\n\t\t}\n\t\ttickC = TVPGetRoughTickCount32() - lastTick1;\n\t\tdelete testbmp; testbmp = nullptr;\n\t\tTVPTLG5DecompressSlide = TVPTLG5DecompressSlide_NEON;\n\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\tfor (int i = 0; i < 32; ++i) {\n\t\t\tmemio.SetPosition(0);\n\t\t\tTVPLoadTLG(nullptr, nullptr, [](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int {\n\t\t\t\tif (!testbmp) testbmp = new tTVPBitmap(w, h, 32);\n\t\t\t\treturn testbmp->GetPitch();\n\t\t\t}, [](void *callbackdata, tjs_int y)->void* {\n\t\t\t\treturn testbmp->GetScanLine(y);\n\t\t\t}, [](void *callbackdata, const ttstr & name, const ttstr & value){}, &memio, TVP_clNone, glmNormal);\n\t\t}\n\t\ttickNEON = TVPGetRoughTickCount32() - lastTick1;\n\t\tdelete testbmp; testbmp = nullptr;\n\t\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", \"TVPLoadTLG5\", tickC, tickNEON, (float)tickNEON / tickC * 100);\n\t}\n}\n\n#define REGISTER_TVPGL_BLEND_FUNC_2(origf, f) \\\n    InitTestData();\\\n    origf##_c(testdest2, testdata1, 256 * 256);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, testdata1, 256 * 256);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n    InitTestData();\\\n    lastTick1 = TVPGetRoughTickCount32();\\\n\tfor (int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, testdata1, 256 * 256); \\\n    lastTick2 = TVPGetRoughTickCount32();\\\n\tfor (int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, testdata1, 256 * 256); \\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n\n#define REGISTER_TVPGL_BLEND_FUNC(origf, f, ...) \\\n    InitTestData();\\\n    origf##_c(testdest2, testdata1, 256 * 256, __VA_ARGS__);\\\n    f = f##_NEON;\\\n    f##_NEON(testdest1, testdata1, 256 * 256, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n    InitTestData();\\\n    lastTick1 = TVPGetRoughTickCount32();\\\n\tfor (int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, testdata1, 256 * 256, __VA_ARGS__); \\\n    lastTick2 = TVPGetRoughTickCount32();\\\n    for(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, testdata1, 256 * 256, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n\n#define REGISTER_TVPGL_STRECH_FUNC_2(origf, f, ...) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16); \\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_STRECH_FUNC(origf, f, ...) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_STRECH_FUNC_0(origf, f) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, 127 * 256, testdata1, 0, 1 << 16);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, 127 * 256, testdata1, 0, 1 << 16);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_LINTRANS_FUNC_2(origf, f) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 127 * 256, testdata1, 0, 0, 1 << 16, 0, 256); \\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 127 * 256, testdata1, 0, 0, 1 << 16, 0, 256); \\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor (int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, 127 * 256, testdata1, 0, 0, 1 << 16, 0, 256); \\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, 127 * 256, testdata1, 0, 0, 1<<16, 0, 256);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_LINTRANS_FUNC(origf, f, ...) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, 127 * 256, testdata1, 0, 0, 1<<16, 0, 256, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, 127 * 256, testdata1, 0, 0, 1<<16, 0, 256, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, 127 * 256, testdata1, 0, 0, 1<<16, 0, 256, __VA_ARGS__);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, 127 * 256, testdata1, 0, 0, 1<<16, 0, 256, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_UNIVTRANS_FUNC(origf, f, ...) \\\n\tInitTestData();\\\n    origf##_c(testdest2, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, testdata1, testdata2, testrule, testtable, 256 * 256, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_CUSTOM_FUNC(origf, f, ...) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, __VA_ARGS__);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_CUSTOM_FUNC_RGB(origf, f, ...) \\\n\tInitTestData();\\\n\torigf##_c(testdest2, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON(testdest1, __VA_ARGS__);\\\n\tCheckTestData_RGB(#f); if (TEST_COUNT) {\\\n\tInitTestData();\\\n\tlastTick1 = TVPGetRoughTickCount32();\\\n\tfor(int i = 0; i < TEST_COUNT; ++i) origf##_c(testdest2, __VA_ARGS__);\\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor(int i = 0; i < TEST_COUNT; ++i) f##_NEON(testdest1, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#define REGISTER_TVPGL_CUSTOM_FUNC_TYPE(origf, f, DT, ...) \\\n\tInitTestData();\\\n\torigf##_c((DT)testdest2, __VA_ARGS__);\\\n\tf = f##_NEON;\\\n\tf##_NEON((DT)testdest1, __VA_ARGS__);\\\n\tCheckTestData(#f); if (TEST_COUNT) {\\\n\tInitTestData(); \\\n\tlastTick1 = TVPGetRoughTickCount32(); \\\n\tfor (int i = 0; i < TEST_COUNT; ++i) origf##_c((DT)testdest2, __VA_ARGS__); \\\n\tlastTick2 = TVPGetRoughTickCount32(); \\\n\tfor (int i = 0; i < TEST_COUNT; ++i) f##_NEON((DT)testdest1, __VA_ARGS__);\\\n\ttickC = lastTick2 - lastTick1; tickNEON = TVPGetRoughTickCount32() - lastTick2; \\\n\tAddLog(\"%s: %d ms, NEON: %d ms(%g%%)\", #f, tickC, tickNEON, (float)tickNEON / tickC * 100); \\\n\tf = f##_NEON; }\n#else\n#define REGISTER_TVPGL_BLEND_FUNC_2(origf, f, ...)  f = f##_NEON;\n#define REGISTER_TVPGL_BLEND_FUNC(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_STRECH_FUNC_2(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_STRECH_FUNC(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_LINTRANS_FUNC_2(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_LINTRANS_FUNC(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_UNIVTRANS_FUNC(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_CUSTOM_FUNC(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_CUSTOM_FUNC_RGB(origf, f, ...) f = f##_NEON;\n#define REGISTER_TVPGL_CUSTOM_FUNC_TYPE(origf, f, ...) f = f##_NEON;\n#endif\n#endif\n#define REGISTER_TVPGL_ONLY(origf, f) origf = f;\n\n// #include \"Protect.h\"\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#include \"tvpgl_arm_route.h\"\n#ifdef __cplusplus\n};\n#endif\n\nFUNC_API void calcBezierPatch_c(float* result, /*const */float* arr/*16*/, /*const */float* a3);\nFUNC_API void calcBezierPatch_NEON(float* result, float* arr/*16*/, float* p);\n\nFUNC_API void TVPGL_ASM_Init()\n{\n    if ((TVPCPUFeatures & TVP_CPU_FAMILY_MASK) == TVP_CPU_FAMILY_ARM && (TVPCPUFeatures & TVP_CPU_HAS_NEON))\n\t{\n\t\tTVPInitTVPGL();\n#ifdef LOG_NEON_TEST\n#if 0\n\t\tdo {\t// test calcBezierPatch\n\t\t\tfloat arr[32];\n\t\t\tfloat resultC[2], resultNEON[2],\n\t\t\t\tpt[2] = {\n\t\t\t\t((rand() & 1) ? -1 : 1) * ((float)rand() / rand()),\n\t\t\t\t((rand() & 1) ? -1 : 1) * ((float)rand() / rand())\n\t\t\t};\n\t\t\tfor (int i = 0; i < 32; ++i) {\n\t\t\t\tarr[i] = ((rand() & 1) ? -1 : 1) * ((float)rand() / rand());\n\t\t\t}\n\t\t\tcalcBezierPatch_c(resultC, arr, pt);\n\t\t\tcalcBezierPatch_NEON(resultNEON, arr, pt);\n\t\t\tif (resultC[0] != resultNEON[0] || resultC[1] != resultNEON[1]) {\n\t\t\t\tShowInMessageBox(\"test calcBezierPatch fail\");\n\t\t\t}\n\t\t\tif (!TEST_COUNT) break;\n\t\t\tfor (int i = 0; i < 4; ++i) {\n\t\t\t\tlastTick1 = TVPGetRoughTickCount32();\n\t\t\t\tfor (int i = 0; i < 160000; ++i) calcBezierPatch_c(resultC, arr, pt);\n\t\t\t\tlastTick2 = TVPGetRoughTickCount32();\n\t\t\t\tfor (int i = 0; i < 160000; ++i) calcBezierPatch_NEON(resultNEON, arr, pt);\n\t\t\t\tAddLog(\"calcBezierPatch: %d ms, NEON: %d ms(%g%%)\", (tickC = lastTick2 - lastTick1), (tickNEON = TVPGetRoughTickCount32() - lastTick2), (float)tickNEON / tickC * 100);\n\t\t\t}\n\t\t\tSHOW_AND_CLEAR_LOG;\n\t\t} while (0);\n#endif\n#undef TEST_COUNT\n#define TEST_COUNT 1000\n// \t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_d, TVPStretchAlphaBlend_d);\n// \t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_d, TVPStretchAlphaBlend_d);\n// \t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_d, TVPStretchAlphaBlend_d);\n// \t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_d, TVPStretchAlphaBlend_d);\n// \t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_do, TVPStretchAlphaBlend_do, 100);\n// \t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_do, TVPStretchAlphaBlend_do, 100);\n// \t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_do, TVPStretchAlphaBlend_do, 100);\n// \t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_do, TVPStretchAlphaBlend_do, 100);\n//\t\tSHOW_AND_CLEAR_LOG;\n#undef TEST_COUNT\n#define TEST_COUNT 200\n\t\ttestTLG6_chroma();\n\t\tlogTLG6_chroma();\n#endif\n#if 1\n\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAlphaBlend, TVPAlphaBlend, testdata1, 256 * 256);\n        REGISTER_TVPGL_ONLY(TVPAlphaBlend_HDA, TVPAlphaBlend_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAlphaBlend_o, TVPAlphaBlend_o, testdata1, 256 * 256, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPAlphaBlend_HDA_o, TVPAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaBlend_d, TVPAlphaBlend_d, testdata1, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaBlend_a, TVPAlphaBlend_a, testdata1, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaBlend_do, TVPAlphaBlend_do, testdata1, 256 * 256, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaBlend_ao, TVPAlphaBlend_ao, testdata1, 256 * 256, 100);\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaColorMat, TVPAlphaColorMat, 0x98765432, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAdditiveAlphaBlend, TVPAdditiveAlphaBlend, testdata1, 256 * 256);\n\t\tREGISTER_TVPGL_ONLY(TVPAdditiveAlphaBlend_HDA, TVPAdditiveAlphaBlend_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAdditiveAlphaBlend_o, TVPAdditiveAlphaBlend_o, testdata1, 256 * 256, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPAdditiveAlphaBlend_HDA_o, TVPAdditiveAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAdditiveAlphaBlend_a, TVPAdditiveAlphaBlend_a, testdata1, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPAdditiveAlphaBlend_ao, TVPAdditiveAlphaBlend_ao, testdata1, 256 * 256, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPConvertAlphaToAdditiveAlpha, TVPConvertAlphaToAdditiveAlpha, 256 * 256);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPAlphaColorMat, TVPAlphaColorMat, 0x98765432, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPStretchAlphaBlend_HDA, TVPStretchAlphaBlend, 16 * 256, testdata1, 0, 1 << 16);\n        REGISTER_TVPGL_ONLY(TVPStretchAlphaBlend_HDA, TVPStretchAlphaBlend_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPStretchAlphaBlend_o, TVPStretchAlphaBlend_o, 16 * 256, testdata1, 0, 1 << 16, 100);\n        REGISTER_TVPGL_ONLY(TVPStretchAlphaBlend_HDA_o, TVPStretchAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_d, TVPStretchAlphaBlend_d);\n\t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAlphaBlend_a, TVPStretchAlphaBlend_a);\n        REGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_do, TVPStretchAlphaBlend_do, 100);\n        REGISTER_TVPGL_STRECH_FUNC(TVPStretchAlphaBlend_ao, TVPStretchAlphaBlend_ao, 100);\n\n\t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAdditiveAlphaBlend_HDA, TVPStretchAdditiveAlphaBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPStretchAdditiveAlphaBlend_HDA, TVPStretchAdditiveAlphaBlend_NEON);\n        REGISTER_TVPGL_STRECH_FUNC(TVPStretchAdditiveAlphaBlend_HDA_o, TVPStretchAdditiveAlphaBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPStretchAdditiveAlphaBlend_HDA_o, TVPStretchAdditiveAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_STRECH_FUNC_2(TVPStretchAdditiveAlphaBlend_a, TVPStretchAdditiveAlphaBlend_a);\n        REGISTER_TVPGL_STRECH_FUNC(TVPStretchAdditiveAlphaBlend_ao, TVPStretchAdditiveAlphaBlend_ao, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransAlphaBlend_HDA, TVPLinTransAlphaBlend);\n        REGISTER_TVPGL_ONLY(TVPLinTransAlphaBlend_HDA, TVPLinTransAlphaBlend_NEON);\n        REGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransAlphaBlend_HDA_o, TVPLinTransAlphaBlend_o, 100);\n        REGISTER_TVPGL_ONLY(TVPLinTransAlphaBlend_HDA_o, TVPLinTransAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransAlphaBlend_d, TVPLinTransAlphaBlend_d); // performance issue !\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransAlphaBlend_a, TVPLinTransAlphaBlend_a);\n        REGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransAlphaBlend_do, TVPLinTransAlphaBlend_do, 100);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransAlphaBlend_ao, TVPLinTransAlphaBlend_ao, 100);\n\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransAdditiveAlphaBlend_HDA, TVPLinTransAdditiveAlphaBlend);\n        REGISTER_TVPGL_ONLY(TVPLinTransAdditiveAlphaBlend_HDA, TVPLinTransAdditiveAlphaBlend_NEON);\n        REGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransAdditiveAlphaBlend_HDA_o, TVPLinTransAdditiveAlphaBlend_o, 100);\n        REGISTER_TVPGL_ONLY(TVPLinTransAdditiveAlphaBlend_HDA_o, TVPLinTransAdditiveAlphaBlend_o_NEON);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransAdditiveAlphaBlend_a, TVPLinTransAdditiveAlphaBlend_a);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransAdditiveAlphaBlend_ao, TVPLinTransAdditiveAlphaBlend_ao, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n// \t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPInterpStretchCopy, TVPInterpStretchCopy,\n// \t\t\t127 * 256, testdata1, testdata2, 127, 0, 1 << 16); // performance issue !\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPInterpLinTransCopy, TVPInterpLinTransCopy);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPInterpStretchAdditiveAlphaBlend, TVPInterpStretchAdditiveAlphaBlend,\n\t\t\t16 * 256, testdata1, testdata2, 127, 0, 1 << 16);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPInterpStretchAdditiveAlphaBlend_o, TVPInterpStretchAdditiveAlphaBlend_o,\n\t\t\t16 * 256, testdata1, testdata2, 127, 0, 1 << 16, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPInterpLinTransAdditiveAlphaBlend, TVPInterpLinTransAdditiveAlphaBlend,\n\t\t\t8 * 256, testdata1, 0, 0, 1 << 16, 1 << 16, 64);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPInterpLinTransAdditiveAlphaBlend_o, TVPInterpLinTransAdditiveAlphaBlend_o,\n\t\t\t8 * 256, testdata1, 0, 0, 1 << 16, 1 << 16, 64, 100);\n\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPInterpStretchConstAlphaBlend, TVPInterpStretchConstAlphaBlend,\n\t\t\t16 * 256, testdata1, testdata2, 127, 0, 1 << 16, 100);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPInterpLinTransConstAlphaBlend, TVPInterpLinTransConstAlphaBlend, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPCopyOpaqueImage, TVPCopyOpaqueImage);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPStretchCopyOpaqueImage, TVPStretchCopyOpaqueImage, 127 * 256, testdata1, 0, 1 << 16);\n\t\tREGISTER_TVPGL_LINTRANS_FUNC_2(TVPLinTransCopyOpaqueImage, TVPLinTransCopyOpaqueImage); // performance issue !\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPConstAlphaBlend_HDA, TVPConstAlphaBlend, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPConstAlphaBlend_HDA, TVPConstAlphaBlend_NEON);\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPConstAlphaBlend_d, TVPConstAlphaBlend_d, 100);\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPConstAlphaBlend_a, TVPConstAlphaBlend_a, 100);\n\n\t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchConstAlphaBlend_HDA, TVPStretchConstAlphaBlend, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPStretchConstAlphaBlend_HDA, TVPStretchConstAlphaBlend_NEON);\n\t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchConstAlphaBlend_d, TVPStretchConstAlphaBlend_d, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPStretchConstAlphaBlend_d, TVPStretchConstAlphaBlend_d_NEON);\n\t\tREGISTER_TVPGL_STRECH_FUNC(TVPStretchConstAlphaBlend_a, TVPStretchConstAlphaBlend_a, 100);\n\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransConstAlphaBlend_HDA, TVPLinTransConstAlphaBlend, 100); // performance issue !\n\t\tREGISTER_TVPGL_ONLY(TVPLinTransConstAlphaBlend_HDA, TVPLinTransConstAlphaBlend_NEON); // performance issue !\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransConstAlphaBlend_d, TVPLinTransConstAlphaBlend_d, 100); // performance issue !\n\t\tREGISTER_TVPGL_LINTRANS_FUNC(TVPLinTransConstAlphaBlend_a, TVPLinTransConstAlphaBlend_a, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPConstAlphaBlend_SD, TVPConstAlphaBlend_SD, testdata1, testdata2, 256 * 256, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPConstAlphaBlend_SD_a, TVPConstAlphaBlend_SD_a, testdata1, testdata2, 256 * 256, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPConstAlphaBlend_SD_d, TVPConstAlphaBlend_SD_d, testdata1, testdata2, 256 * 256, 100);\n\n        // TVPInitUnivTransBlendTable\n\t\tREGISTER_TVPGL_CUSTOM_FUNC_RGB(TVPUnivTransBlend, TVPUnivTransBlend, testdata1, testdata2, testrule, testtable, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPUnivTransBlend_d, TVPUnivTransBlend_d, testdata1, testdata2, testrule, testtable, 256 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPUnivTransBlend_a, TVPUnivTransBlend_a, testdata1, testdata2, testrule, testtable, 256 * 256);\n\t\tREGISTER_TVPGL_UNIVTRANS_FUNC(TVPUnivTransBlend_switch, TVPUnivTransBlend_switch, 240, 32);\n\t\tREGISTER_TVPGL_UNIVTRANS_FUNC(TVPUnivTransBlend_switch_d, TVPUnivTransBlend_switch_d, 240, 32);\n\t\tREGISTER_TVPGL_UNIVTRANS_FUNC(TVPUnivTransBlend_switch_a, TVPUnivTransBlend_switch_a, 240, 32);\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_HDA, TVPApplyColorMap, testrule, 256 * 256, 0x55d20688);\n        REGISTER_TVPGL_ONLY(TVPApplyColorMap_HDA, TVPApplyColorMap_NEON);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_HDA_o, TVPApplyColorMap_o, testrule, 256 * 256, 0x55d20688, 100);\n        REGISTER_TVPGL_ONLY(TVPApplyColorMap_HDA_o, TVPApplyColorMap_o_NEON);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_d, TVPApplyColorMap_d, testrule, 256 * 256, 0x55d20688);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_a, TVPApplyColorMap_a, testrule, 256 * 256, 0x55d20688);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_do, TVPApplyColorMap_do, testrule, 256 * 256, 0x55d20688, 100);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPApplyColorMap_ao, TVPApplyColorMap_ao, testrule, 256 * 256, 0x55d20688, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPConstColorAlphaBlend, TVPConstColorAlphaBlend, 256 * 256, 0x55d20688, 100);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPConstColorAlphaBlend_d, TVPConstColorAlphaBlend_d, 256 * 256, 0x55d20688, 100);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPConstColorAlphaBlend_a, TVPConstColorAlphaBlend_a, 256 * 256, 0x55d20688, 100);\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPRemoveConstOpacity, TVPRemoveConstOpacity, 256 * 256, 100);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPRemoveOpacity, TVPRemoveOpacity, testrule, 255 * 256);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPRemoveOpacity_o, TVPRemoveOpacity_o, testrule, 255 * 256, 100);\n\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPAddBlend, TVPAddBlend);\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPAddBlend_HDA, TVPAddBlend_HDA);\n        REGISTER_TVPGL_BLEND_FUNC(TVPAddBlend_HDA_o, TVPAddBlend_o, 100);\n        REGISTER_TVPGL_ONLY(TVPAddBlend_HDA_o, TVPAddBlend_o_NEON);\n\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPSubBlend, TVPSubBlend);\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPSubBlend_HDA, TVPSubBlend_HDA);\n        REGISTER_TVPGL_BLEND_FUNC(TVPSubBlend_HDA_o, TVPSubBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPSubBlend_HDA_o, TVPSubBlend_o_NEON);\n\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPMulBlend_HDA, TVPMulBlend_HDA);\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPMulBlend, TVPMulBlend);\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPMulBlend_HDA_o, TVPMulBlend_HDA_o, 100);\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPMulBlend_o, TVPMulBlend_o, 100);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n//         REGISTER_TVPGL_BLEND_FUNC_2(TVPColorDodgeBlend_HDA, TVPColorDodgeBlend); // performance issue\n//         REGISTER_TVPGL_ONLY(TVPColorDodgeBlend_HDA, TVPColorDodgeBlend_NEON);\n//         REGISTER_TVPGL_BLEND_FUNC(TVPColorDodgeBlend_HDA_o, TVPColorDodgeBlend_o, 100);\n//         REGISTER_TVPGL_ONLY(TVPColorDodgeBlend_HDA_o, TVPColorDodgeBlend_o_NEON);\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPDarkenBlend_HDA, TVPDarkenBlend);\n        REGISTER_TVPGL_ONLY(TVPDarkenBlend_HDA, TVPDarkenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPDarkenBlend_HDA_o, TVPDarkenBlend_o, 100);\n        REGISTER_TVPGL_ONLY(TVPDarkenBlend_HDA_o, TVPDarkenBlend_o_NEON);\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPLightenBlend_HDA, TVPLightenBlend);\n        REGISTER_TVPGL_ONLY(TVPLightenBlend_HDA, TVPLightenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPLightenBlend_HDA_o, TVPLightenBlend_o, 100);\n        REGISTER_TVPGL_ONLY(TVPLightenBlend_HDA_o, TVPLightenBlend_o_NEON);\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPScreenBlend_HDA, TVPScreenBlend);\n        REGISTER_TVPGL_ONLY(TVPScreenBlend_HDA, TVPScreenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPScreenBlend_HDA_o, TVPScreenBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPScreenBlend_HDA_o, TVPScreenBlend_o_NEON);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n//         TVPFastLinearInterpH2F, TVPFastLinearInterpH2F_c;\n//         TVPFastLinearInterpH2B, TVPFastLinearInterpH2B_c;\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPFastLinearInterpV2, TVPFastLinearInterpV2,\n            256 * 256, testdata1, testdata2);\n\n        //TVPStretchColorCopy, TVPStretchColorCopy_c;\n\n\t\t//TVPMakeAlphaFromKey, TVPMakeAlphaFromKey_c;\n        \n//\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPCopyMask, TVPCopyMask);\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPCopyColor, TVPCopyColor);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPBindMaskToMain, TVPBindMaskToMain, testrule, 256 * 256);\n\n\t\t// NEON's TVPFillARGB is slower than plain C\n//         REGISTER_TVPGL_CUSTOM_FUNC(TVPFillARGB, TVPFillARGB, 256 * 256, 0x55d20688);\n//  \t\tREGISTER_TVPGL_ONLY(TVPFillARGB_NC, TVPFillARGB_NEON);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPFillColor, TVPFillColor, 256 * 256, 0x55d20688);\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPFillMask, TVPFillMask, 256 * 256, 0x55d20688);\n        REGISTER_TVPGL_CUSTOM_FUNC_TYPE(TVPAddSubVertSum16, TVPAddSubVertSum16, tjs_uint16*, testdata1, testdata2, 128 * 256);\n        REGISTER_TVPGL_CUSTOM_FUNC_TYPE(TVPAddSubVertSum16_d, TVPAddSubVertSum16_d, tjs_uint16*, testdata1, testdata2, 128 * 256);\n\n//         TVPAddSubVertSum32, TVPAddSubVertSum32_c;\n//         TVPAddSubVertSum32_d, TVPAddSubVertSum32_d_c;\n//         TVPDoBoxBlurAvg16, TVPDoBoxBlurAvg16_c;\n//         TVPDoBoxBlurAvg16_d, TVPDoBoxBlurAvg16_d_c;\n//         TVPDoBoxBlurAvg32, TVPDoBoxBlurAvg32_c;\n//         TVPDoBoxBlurAvg32_d, TVPDoBoxBlurAvg32_d_c;\n//         TVPSwapLine8, TVPSwapLine8_c;\n//         TVPSwapLine32, TVPSwapLine32_c;\n//         TVPReverse8, TVPReverse8_c;\n//         TVPReverse32, TVPReverse32_c;\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPDoGrayScale, TVPDoGrayScale, 256 * 256);\n//         TVPInitGammaAdjustTempData, TVPInitGammaAdjustTempData_c;\n//         TVPUninitGammaAdjustTempData, TVPUninitGammaAdjustTempData_c;\n//         TVPAdjustGamma, TVPAdjustGamma_c;\n//         TVPAdjustGamma_a, TVPAdjustGamma_a_c;\n//         TVPChBlurMulCopy65, TVPChBlurMulCopy65_c;\n//         TVPChBlurAddMulCopy65, TVPChBlurAddMulCopy65_c;\n//         TVPChBlurCopy65, TVPChBlurCopy65_c;\n//         TVPBLExpand1BitTo8BitPal, TVPBLExpand1BitTo8BitPal_c;\n//         TVPBLExpand1BitTo8Bit, TVPBLExpand1BitTo8Bit_c;\n//         TVPBLExpand1BitTo32BitPal, TVPBLExpand1BitTo32BitPal_c;\n//         TVPBLExpand4BitTo8BitPal, TVPBLExpand4BitTo8BitPal_c;\n//         TVPBLExpand4BitTo8Bit, TVPBLExpand4BitTo8Bit_c;\n//         TVPBLExpand4BitTo32BitPal, TVPBLExpand4BitTo32BitPal_c;\n//         TVPBLExpand8BitTo8BitPal, TVPBLExpand8BitTo8BitPal_c;uni\n//         TVPBLExpand8BitTo32BitPal, TVPBLExpand8BitTo32BitPal_c;\n\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPExpand8BitTo32BitGray, TVPExpand8BitTo32BitGray, testrule, 256 * 256);\n//         TVPBLConvert15BitTo8Bit, TVPBLConvert15BitTo8Bit;\n        REGISTER_TVPGL_CUSTOM_FUNC(TVPBLConvert15BitTo32Bit, TVPBLConvert15BitTo32Bit, (const tjs_uint16*)testrule, 128 * 256);\n//         TVPBLConvert24BitTo8Bit, TVPBLConvert24BitTo8Bit;\n        REGISTER_TVPGL_ONLY(TVPBLConvert24BitTo32Bit, TVPConvert24BitTo32Bit_NEON);\n\t\tREGISTER_TVPGL_CUSTOM_FUNC(TVPConvert24BitTo32Bit, TVPConvert24BitTo32Bit, testrule, 256 * 256 / 3);\n\t\tREGISTER_TVPGL_ONLY(TVPConvert32BitTo24Bit, TVPConvert32BitTo24Bit);\n//         TVPBLConvert32BitTo8Bit, TVPBLConvert32BitTo8Bit;\n//         TVPBLConvert32BitTo32Bit_NoneAlpha, TVPBLConvert32BitTo32Bit_NoneAlpha;\n//         TVPBLConvert32BitTo32Bit_MulAddAlpha, TVPBLConvert32BitTo32Bit_MulAddAlpha;\n//         TVPBLConvert32BitTo32Bit_AddAlpha, TVPBLConvert32BitTo32Bit_AddAlpha;\n//         TVPDither32BitTo16Bit565, TVPDither32BitTo16Bit565;\n//         TVPDither32BitTo16Bit555, TVPDither32BitTo16Bit555;\n//         TVPDither32BitTo8Bit, TVPDither32BitTo8Bit;\n//         TVPTLG5DecompressSlide, TVPTLG5DecompressSlide;\n//         TVPTLG6DecodeGolombValuesForFirst, TVPTLG6DecodeGolombValuesForFirst;\n//         TVPTLG6DecodeGolombValues, TVPTLG6DecodeGolombValues;\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsAlphaBlend_HDA, TVPPsAlphaBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsAlphaBlend_HDA, TVPPsAlphaBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsAlphaBlend_HDA_o, TVPPsAlphaBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsAlphaBlend_HDA_o, TVPPsAlphaBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsAddBlend_HDA, TVPPsAddBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsAddBlend_HDA, TVPPsAddBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsAddBlend_HDA_o, TVPPsAddBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsAddBlend_HDA_o, TVPPsAddBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsSubBlend_HDA, TVPPsSubBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsSubBlend_HDA, TVPPsSubBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsSubBlend_HDA_o, TVPPsSubBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsSubBlend_HDA_o, TVPPsSubBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsMulBlend_HDA, TVPPsMulBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsMulBlend_HDA, TVPPsMulBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsMulBlend_HDA_o, TVPPsMulBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsMulBlend_HDA_o, TVPPsMulBlend_o_NEON);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsScreenBlend_HDA, TVPPsScreenBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsScreenBlend_HDA, TVPPsScreenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsScreenBlend_HDA_o, TVPPsScreenBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsScreenBlend_HDA_o, TVPPsScreenBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsOverlayBlend_HDA, TVPPsOverlayBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsOverlayBlend, TVPPsOverlayBlend_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPPsOverlayBlend_HDA, TVPPsOverlayBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsOverlayBlend_HDA_o, TVPPsOverlayBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsOverlayBlend_o, TVPPsOverlayBlend_o_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPPsOverlayBlend_HDA_o, TVPPsOverlayBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsHardLightBlend_HDA, TVPPsHardLightBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsHardLightBlend, TVPPsHardLightBlend_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPPsHardLightBlend_HDA, TVPPsHardLightBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsHardLightBlend_HDA_o, TVPPsHardLightBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsHardLightBlend_o, TVPPsHardLightBlend_o_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPPsHardLightBlend_HDA_o, TVPPsHardLightBlend_o_NEON);\n\n//         TVPPsSoftLightBlend = TVPPsSoftLightBlend_c;\n//         TVPPsSoftLightBlend_o = TVPPsSoftLightBlend_o_c;\n//         TVPPsSoftLightBlend_HDA = TVPPsSoftLightBlend_HDA_c;\n//         TVPPsSoftLightBlend_HDA_o = TVPPsSoftLightBlend_HDA_o_c;\n//         TVPPsColorDodgeBlend = TVPPsColorDodgeBlend_c;\n//         TVPPsColorDodgeBlend_o = TVPPsColorDodgeBlend_o_c;\n//         TVPPsColorDodgeBlend_HDA = TVPPsColorDodgeBlend_HDA_c;\n//         TVPPsColorDodgeBlend_HDA_o = TVPPsColorDodgeBlend_HDA_o_c;\n//         TVPPsColorDodge5Blend = TVPPsColorDodge5Blend_c;\n//         TVPPsColorDodge5Blend_o = TVPPsColorDodge5Blend_o_c;\n//         TVPPsColorDodge5Blend_HDA = TVPPsColorDodge5Blend_HDA_c;\n//         TVPPsColorDodge5Blend_HDA_o = TVPPsColorDodge5Blend_HDA_o_c;\n//         TVPPsColorBurnBlend = TVPPsColorBurnBlend_c;\n//         TVPPsColorBurnBlend_o = TVPPsColorBurnBlend_o_c;\n//         TVPPsColorBurnBlend_HDA = TVPPsColorBurnBlend_HDA_c;\n//         TVPPsColorBurnBlend_HDA_o = TVPPsColorBurnBlend_HDA_o_c;\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsLightenBlend_HDA, TVPPsLightenBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsLightenBlend_HDA, TVPPsLightenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsLightenBlend_HDA_o, TVPPsLightenBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsLightenBlend_HDA_o, TVPPsLightenBlend_o_NEON);\n\n\t\tSHOW_AND_CLEAR_LOG;\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsDarkenBlend_HDA, TVPPsDarkenBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDarkenBlend_HDA, TVPPsDarkenBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsDarkenBlend_HDA_o, TVPPsDarkenBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDarkenBlend_HDA_o, TVPPsDarkenBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsDiffBlend_HDA, TVPPsDiffBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDiffBlend_HDA, TVPPsDiffBlend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsDiffBlend_HDA_o, TVPPsDiffBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDiffBlend_HDA_o, TVPPsDiffBlend_o_NEON);\n\n        REGISTER_TVPGL_BLEND_FUNC_2(TVPPsDiff5Blend_HDA, TVPPsDiff5Blend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDiff5Blend_HDA, TVPPsDiff5Blend_NEON);\n        REGISTER_TVPGL_BLEND_FUNC(TVPPsDiff5Blend_HDA_o, TVPPsDiff5Blend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsDiff5Blend_HDA_o, TVPPsDiff5Blend_o_NEON);\n\n\t\tREGISTER_TVPGL_BLEND_FUNC_2(TVPPsExclusionBlend_HDA, TVPPsExclusionBlend);\n\t\tREGISTER_TVPGL_ONLY(TVPPsExclusionBlend_HDA, TVPPsExclusionBlend_NEON);\n\t\tREGISTER_TVPGL_BLEND_FUNC(TVPPsExclusionBlend_HDA_o, TVPPsExclusionBlend_o, 100);\n\t\tREGISTER_TVPGL_ONLY(TVPPsExclusionBlend_HDA_o, TVPPsExclusionBlend_o_NEON);\n\n\t\tREGISTER_TVPGL_ONLY(TVPTLG6DecodeLine, TVPTLG6DecodeLine_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPTLG5ComposeColors3To4, TVPTLG5ComposeColors3To4_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPTLG5ComposeColors4To4, TVPTLG5ComposeColors4To4_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPTLG5DecompressSlide, TVPTLG5DecompressSlide_NEON);\n\n\t\tREGISTER_TVPGL_ONLY(TVPReverseRGB, TVPReverseRGB_NEON);\n\t\tREGISTER_TVPGL_ONLY(TVPUpscale65_255, TVPUpscale65_255_NEON);\n\n\t\tSHOW_AND_CLEAR_LOG;\n#endif\n#ifdef DEBUG_ARM_NEON\n\t\tfree(testbuff);\n#ifdef _DEBUG\n        TVPInitTVPGL();\n#endif\n#endif\n\t}\n}\n\nFUNC_API void TVPGL_ASM_Test() {\n#ifdef LOG_NEON_TEST\n\tTVPCPUFeatures |= TVP_CPU_FAMILY_ARM | TVP_CPU_HAS_NEON;\n\tTVPGL_ASM_Init();\n#endif\n}"
  },
  {
    "path": "src/core/visual/ARM/tvpgl_arm_intf.h",
    "content": "/*\n\tthis is a part of TVP (KIRIKIRI) software source.\n\tsee other sources for license.\n\t(C)2001-2007 W.Dee <dee@kikyou.info> and contributors\n*/\n\n/* C-language interface to tvpgl_ia32.lib */\n/* this file is always generated by summary.pl */\n\n#ifndef __TVPGL_ARM_INTF__\n#define __TVPGL_ARM_INTF__\n\n#include \"tjsTypes.h\"\n#include \"tvpgl.h\"\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/ARM/tvpgl_arm_route.h",
    "content": " \n"
  },
  {
    "path": "src/core/visual/BitmapIntf.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"BitmapIntf.h\"\n#include \"MsgIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"TVPColor.h\"\n#include \"LayerIntf.h\"\n#include \"Application.h\"\n\ntTJSNI_Bitmap::tTJSNI_Bitmap() : Owner(NULL), Bitmap(NULL), Loading(false) {\n\tTVPTempBitmapHolderAddRef();\n}\ntTJSNI_Bitmap::~tTJSNI_Bitmap() {\n\tTVPTempBitmapHolderRelease();\n}\n//----------------------------------------------------------------------\n// string, [uint] t@CAJ[L[̏Ŏw\n// uint, uint, [bpp] AAbpp̏Ŏw\ntjs_error TJS_INTF_METHOD tTJSNI_Bitmap::Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj) {\n\tOwner = tjs_obj;\n\tif( numparams > 0 ) {\n\t\tif( param[0]->Type() == tvtString ) {\n\t\t\ttjs_uint32 colorkey = clNone;\n\t\t\tif( numparams > 1 ) {\n\t\t\t\tcolorkey = (tjs_uint32)(tjs_int64)*param[1];\n\t\t\t}\n\t\t\tiTJSDispatch2 *ret = Load( *param[0], colorkey );\n\t\t\tif( ret ) ret->Release(); // ignore\n\t\t} else if( numparams > 1 ) {\n\t\t\ttjs_uint32 width = (tjs_uint32)(tjs_int64)*param[0];\n\t\t\ttjs_uint32 height = (tjs_uint32)(tjs_int64)*param[1];\n\t\t\ttjs_uint32 bpp = 32;\n\t\t\tif( numparams > 2 ) {\n\t\t\t\tbpp = (tjs_int)*param[2];\n\t\t\t}\n\t\t\tBitmap = new tTVPBaseBitmap( width, height, bpp );\n\t\t}\n\t} else {\n\t\tBitmap = new tTVPBaseBitmap( TVPGetInitialBitmap() );\n\t}\n\treturn TJS_S_OK;\n}\n//----------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Bitmap::Invalidate() {\n\tif(Bitmap) delete Bitmap, Bitmap = NULL;\n}\n//----------------------------------------------------------------------\ntjs_uint32 tTJSNI_Bitmap::GetPixel(tjs_int x, tjs_int y) const {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\treturn TVPFromActualColor(Bitmap->GetPoint(x, y) & 0xffffff);\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetPixel(tjs_int x, tjs_int y, tjs_uint32 color) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tBitmap->SetPointMain(x, y, TVPToActualColor(color));\n}\n//----------------------------------------------------------------------\ntjs_int tTJSNI_Bitmap::GetMaskPixel(tjs_int x, tjs_int y) const {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\treturn (Bitmap->GetPoint(x, y) & 0xff000000) >> 24;\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetMaskPixel(tjs_int x, tjs_int y, tjs_int mask) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tBitmap->SetPointMask(x, y, mask);\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::Independ(bool copy) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(Bitmap) {\n\t\tif(copy)\n\t\t\tBitmap->Independ();\n\t\telse\n\t\t\tBitmap->IndependNoCopy();\n\t}\n}\n//----------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_Bitmap::Load(const ttstr &name, tjs_uint32 colorkey) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif( !Bitmap ) Bitmap = new tTVPBaseBitmap( TVPGetInitialBitmap() );\n\n\tiTJSDispatch2* metainfo = NULL;\n\tTVPLoadGraphic( Bitmap, name, colorkey, 0, 0, glmNormal, NULL, &metainfo);\n\treturn metainfo;\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::LoadAsync( const ttstr &name) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tLoading = true;\n\tApplication->LoadImageRequest( Owner, this, name );\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::Save(const ttstr &name, const ttstr &type, iTJSDispatch2* meta ) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tTVPSaveImage( name, type, Bitmap, meta );\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetSize(tjs_uint width, tjs_uint height, bool keepimage) {\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(width == Bitmap->GetWidth() && height == Bitmap->GetHeight()) return;\n\n\t// be called from geographical management\n\tif(!width || !height)\n\t\tTVPThrowExceptionMessage(TVPCannotCreateEmptyLayerImage);\n\n\tif(keepimage) {\n\t\tBitmap->SetSizeWithFill(width, height, 0);\n\t} else {\n\t\tBitmap->SetSize(width, height, false);\n\t}\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetSizeAndImageBuffer(tTVPBitmap* bmp) {\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\n\t// be called from geographical management\n\tif (!bmp->GetWidth() || !bmp->GetHeight())\n\t\tTVPThrowExceptionMessage(TVPCannotCreateEmptyLayerImage);\n\n\tBitmap->SetSizeAndImageBuffer( bmp );\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetWidth(tjs_uint width) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(width == Bitmap->GetWidth()) return;\n\n\tBitmap->SetSizeWithFill(width, Bitmap->GetHeight(), 0);\n}\n//----------------------------------------------------------------------\ntjs_uint tTJSNI_Bitmap::GetWidth() const {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn Bitmap->GetWidth();\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::SetHeight(tjs_uint height) {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(height == Bitmap->GetHeight()) return;\n\tBitmap->SetSizeWithFill(Bitmap->GetWidth(), height, 0);\n}\n//----------------------------------------------------------------------\ntjs_uint tTJSNI_Bitmap::GetHeight() const {\n\tif( Loading ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\tif(!Bitmap) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn Bitmap->GetHeight();\n}\n//----------------------------------------------------------------------\nconst void * tTJSNI_Bitmap::GetPixelBuffer() const {\n\tif(!Bitmap) return NULL;\n\treturn Bitmap->GetScanLine(0);\n}\n//----------------------------------------------------------------------\nvoid * tTJSNI_Bitmap::GetPixelBufferForWrite() {\n\tif(!Bitmap) return NULL;\n\treturn Bitmap->GetScanLineForWrite(0);\n}\n//----------------------------------------------------------------------\ntjs_int tTJSNI_Bitmap::GetPixelBufferPitch() const {\n\tif(!Bitmap) return 0;\n\treturn Bitmap->GetPitchBytes();\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::CopyFrom( const tTJSNI_Bitmap* src ) {\n\tBitmap->Assign(*src->GetBitmap());\n}\n//----------------------------------------------------------------------\nvoid tTJSNI_Bitmap::CopyFrom(const  iTVPBaseBitmap* src) {\n\tBitmap->Assign(*src);\n}\n//----------------------------------------------------------------------\ntjs_uint32 tTJSNC_Bitmap::ClassID = -1;\n\n//----------------------------------------------------------------------\ntTJSNC_Bitmap::tTJSNC_Bitmap() : inherited(TJS_W(\"Bitmap\") ) {\n\t\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Bitmap) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Bitmap,\n\t/*TJS class name*/Bitmap)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Bitmap)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(result) *result = (tjs_int64)_this->GetPixel(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->SetPixel(*param[0], *param[1], (tjs_int)*param[2]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getMaskPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(result) *result = _this->GetMaskPixel(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getMaskPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMaskPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->SetMaskPixel(*param[0], *param[1], *param[2]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMaskPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/independ)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tbool copy = true;\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tcopy = param[0]->operator bool();\n\t_this->Independ(copy);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/independ)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif( _this->IsLoading() ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\t_this->SetSize((tjs_int)*param[0], (tjs_int)*param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/copyFrom)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tif( _this->IsLoading() ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Bitmap* srcbmp = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t_this->CopyFrom( srcbmp );\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/copyFrom)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/save)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\tttstr type(TJS_W(\"bmp\"));\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\ttype = *param[1];\n\tiTJSDispatch2* meta = NULL;\n\tif( numparams >= 3 ) meta = param[2]->AsObjectNoAddRef();\n\t_this->Save( name, type, meta );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/save)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/load)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\ttjs_uint32 key = clNone;\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\tkey = (tjs_uint32)param[1]->AsInteger();\n\tiTJSDispatch2 * metainfo = _this->Load(name, key);\n\ttry {\n\t\tif(result) *result = metainfo;\n\t} catch(...) {\n\t\tif(metainfo) metainfo->Release();\n\t\tthrow;\n\t}\n\tif(metainfo) metainfo->Release();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/load)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadAsync)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\t_this->LoadAsync( name );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/loadAsync)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadHeader)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\tiTJSDispatch2 * dic = NULL;\n\ttry {\n\t\tif(result) {\n\t\t\tTVPLoadImageHeader( name, &dic );\n\t\t\tif(dic) {\n\t\t\t\t*result = dic;\n\t\t\t} else {\n\t\t\t\t*result = tTJSVariant();\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tif(dic) dic->Release();\n\t\tthrow;\n\t}\n\tif(dic) dic->Release();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/loadHeader)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getSaveOption)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr type(*param[0]);\n\tiTJSDispatch2 * dic = NULL;\n\ttry {\n\t\tif(result) {\n\t\t\tbool ret = TVPGetSaveOption( type, &dic );\n\t\t\tif(ret&&dic) {\n\t\t\t\t*result = dic;\n\t\t\t} else {\n\t\t\t\t*result = tTJSVariant();\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tif(dic) dic->Release();\n\t\tthrow;\n\t}\n\tif(dic) dic->Release();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getSaveOption)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onLoaded)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(4, \"onLoaded\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"meta\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"async\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"error\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"message\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onLoaded)\n//----------------------------------------------------------------------\n\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\t*result = (tjs_int64)_this->GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\t_this->SetWidth(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\t*result = (tjs_int64)_this->GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\t_this->SetHeight(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(buffer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\tif( _this->IsLoading() ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetPixelBuffer());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(buffer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bufferForWrite)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\tif( _this->IsLoading() ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetPixelBufferForWrite());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bufferForWrite)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bufferPitch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\tif( _this->IsLoading() ) TVPThrowExceptionMessage(TVPCurrentlyAsyncLoadBitmap);\n\t\t*result = _this->GetPixelBufferPitch();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bufferPitch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(loading)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Bitmap);\n\t\t*result = (tjs_int)( _this->IsLoading() ? 1 : 0 );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(loading)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Bitmap\n//---------------------------------------------------------------------------\nstruct tBitmapClassHolder {\n\ttTJSNativeClass * Obj;\n\ttBitmapClassHolder() : Obj(NULL) {}\n\tvoid Set( tTJSNativeClass* obj ) {\n\t\tif( Obj ) {\n\t\t\tObj->Release();\n\t\t\tObj = NULL;\n\t\t}\n\t\tObj = obj;\n\t\tObj->AddRef();\n\t}\n\t~tBitmapClassHolder() { if( Obj ) Obj->Release(), Obj = NULL; }\n} static bitmapclassholder;\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Bitmap::CreateNativeInstance() {\n\treturn new tTJSNI_Bitmap();\n}\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Bitmap()\n{\n\tif( bitmapclassholder.Obj ) {\n\t\ttTJSNativeClass* bmpclass = bitmapclassholder.Obj;\n\t\tbmpclass->AddRef();\n\t\treturn bmpclass;\n\t}\n\ttTJSNativeClass* bmpclass = new tTJSNC_Bitmap();\n\tbitmapclassholder.Set( bmpclass );\n\treturn bmpclass;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateBitmapObject()\n{\n\tif( bitmapclassholder.Obj == NULL ) {\n\t\tTVPThrowInternalError;\n\t}\n\tiTJSDispatch2 *out;\n\tif(TJS_FAILED(bitmapclassholder.Obj->CreateNew(0, NULL, NULL, &out, 0, NULL, bitmapclassholder.Obj)))\n\t\tTVPThrowInternalError;\n\n\treturn out;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/BitmapIntf.h",
    "content": "\n\n#ifndef BitmapIntfH\n#define BitmapIntfH\n\n#include \"tjsNative.h\"\nclass tTVPBitmap;\nclass tTVPBaseBitmap;\nclass tTJSNI_Bitmap : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\nprotected:\n\tiTJSDispatch2 *Owner;\n\ttTVPBaseBitmap* Bitmap;\n\tbool Loading;\n\npublic:\n\ttTJSNI_Bitmap();\n\tvirtual ~tTJSNI_Bitmap();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\ttTVPBaseBitmap* GetBitmap() { return Bitmap; }\n\tconst tTVPBaseBitmap* GetBitmap() const { return Bitmap; }\n\n\ttjs_uint32 GetPixel(tjs_int x, tjs_int y) const;\n\tvoid SetPixel(tjs_int x, tjs_int y, tjs_uint32 color);\n\n\ttjs_int GetMaskPixel(tjs_int x, tjs_int y) const;\n\tvoid SetMaskPixel(tjs_int x, tjs_int y, tjs_int mask);\n\n\tvoid Independ(bool copy = true);\n\n\tiTJSDispatch2* Load(const ttstr &name, tjs_uint32 colorkey);\n\tvoid LoadAsync(const ttstr &name);\n\tvoid Save(const ttstr &name, const ttstr &type, iTJSDispatch2* meta = NULL);\n\n\tvoid SetSize(tjs_uint width, tjs_uint height, bool keepimage = true);\n\t// for async load\n\t// @param bits : tTVPBitmapBitsAlloc::AllocŊmۂ̂gp邱\n\tvoid SetSizeAndImageBuffer(tTVPBitmap* bmp);\n\n\tvoid SetWidth(tjs_uint width);\n\ttjs_uint GetWidth() const;\n\tvoid SetHeight(tjs_uint height);\n\ttjs_uint GetHeight() const;\n\n\tconst void * GetPixelBuffer() const;\n\tvoid * GetPixelBufferForWrite();\n\ttjs_int GetPixelBufferPitch() const;\n\n\t// copy on wirte \n\tvoid CopyFrom( const tTJSNI_Bitmap* src );\n\n\tbool IsLoading() const { return Loading; }\n\n\t// for internal\n\tvoid CopyFrom( const class iTVPBaseBitmap* src );\n\tvirtual void SetLoading( bool load ) { Loading = load; }\n};\n\n\nclass tTJSNC_Bitmap : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Bitmap();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n\nextern tTJSNativeClass * TVPCreateNativeClass_Bitmap();\nextern iTJSDispatch2 * TVPCreateBitmapObject();\n#endif // BitmapIntfH\n"
  },
  {
    "path": "src/core/visual/BitmapLayerTreeOwner.cpp",
    "content": "//---------------------------------------------------------------------------\n/**\n * ` Bitmap Ƃ Layer Tree Owner\n * C[ɕ`āAꂽéÃNX̕ێ Bitmap ɕ`\n * ݒ̂߂ɌĂтꂽ\\bhCxgƂĒʒm\n */\n//---------------------------------------------------------------------------\n//!@file C[c[I[i[\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"ComplexRect.h\"\n#include \"BitmapIntf.h\"\n#include \"LayerIntf.h\"\n\n#include \"BitmapLayerTreeOwner.h\"\n#include \"MsgIntf.h\"\n\n#include <assert.h>\n\ntTJSNI_BitmapLayerTreeOwner::tTJSNI_BitmapLayerTreeOwner() \n: Owner(NULL), BitmapObject(NULL), BitmapNI(NULL)\n{\n}\ntTJSNI_BitmapLayerTreeOwner::~tTJSNI_BitmapLayerTreeOwner() {\n}\n\n// tTJSNativeInstance\ntjs_error TJS_INTF_METHOD tTJSNI_BitmapLayerTreeOwner::Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj) {\n\n\tOwner = tjs_obj; // no addref\n\n\tBitmapObject = GetBitmapObjectNoAddRef();\n\tif(TJS_FAILED(BitmapObject->NativeInstanceSupport(TJS_NIS_GETINSTANCE, tTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&BitmapNI)))\n\t\treturn TJS_E_INVALIDPARAM;\n\n\treturn TJS_S_OK;\n}\nvoid TJS_INTF_METHOD tTJSNI_BitmapLayerTreeOwner::Invalidate() {\n\t// invalidate bitmap object\n\tBitmapNI = NULL;\n\tif( BitmapObject ) {\n\t\tBitmapObject->Invalidate(0, NULL, NULL, BitmapObject);\n\t\tBitmapObject->Release();\n\t\tBitmapObject = NULL;\n\t}\n}\n\niTJSDispatch2* tTJSNI_BitmapLayerTreeOwner::GetBitmapObjectNoAddRef() {\n\tif(BitmapObject) return BitmapObject;\n\t// create bitmap object if the object is not yet created.\n\tBitmapObject = TVPCreateBitmapObject();\n\treturn BitmapObject;\n}\n\n// tTVPLayerTreeOwner\nvoid TJS_INTF_METHOD tTJSNI_BitmapLayerTreeOwner::StartBitmapCompletion(iTVPLayerManager * manager) {\n}\nvoid TJS_INTF_METHOD tTJSNI_BitmapLayerTreeOwner::NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\ttjs_int x, tjs_int y, tTVPBaseTexture *bitmapinfo,\n\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity) {\n\tassert(BitmapNI);\n\n\ttjs_int w, h;\n\tGetPrimaryLayerSize( w, h );\n\tif( BitmapNI ) {\n\t\tBitmapNI->SetSize( w, h );\n\t}\n\ttjs_uint8* dstbits = (tjs_uint8*)BitmapNI->GetPixelBufferForWrite();\n\ttjs_int dstpitch = BitmapNI->GetPixelBufferPitch();\n\t// cliprect ͂ݏoĂȂƂmF\n\tif( !(x < 0 || y < 0 || x + cliprect.get_width() > w || y + cliprect.get_height() > h) &&\n\t\t!(cliprect.left < 0 || cliprect.top < 0 ||\n\t\t\tcliprect.right > bitmapinfo->GetWidth() || cliprect.bottom > bitmapinfo->GetHeight()) )\n\t{\n\t\t// bitmapinfo ŕ\\ꂽ cliprect ̗̈ x,y ɃRs[\n\t\tlong src_y       = cliprect.top;\n\t\tlong src_y_limit = cliprect.bottom;\n\t\tlong src_x       = cliprect.left;\n\t\tlong width_bytes   = cliprect.get_width() * 4; // 32bit\n\t\tlong dest_y      = y;\n\t\tlong dest_x      = x;\n\t\tconst tjs_uint8 * src_p = (const tjs_uint8 *)bitmapinfo->GetScanLine(0);\n\t\tlong src_pitch;\n#if 0\n\t\tif(bitmapinfo->GetHeight() < 0) {\n\t\t\t// bottom-down\n\t\t\tsrc_pitch = bitmapinfo->GetWidth() * 4;\n\t\t} else\n#endif\n\t\t{\n\t\t\t// bottom-up\n\t\t\tsrc_pitch = -(int)bitmapinfo->GetWidth() * 4;\n\t\t\tsrc_p += bitmapinfo->GetWidth() * 4 * (bitmapinfo->GetHeight() - 1);\n\t\t}\n\n\t\tfor(; src_y < src_y_limit; src_y ++, dest_y ++) {\n\t\t\tconst void *srcp = src_p + src_pitch * src_y + src_x * 4;\n\t\t\tvoid *destp = dstbits + dstpitch * dest_y + dest_x * 4;\n\t\t\tmemcpy(destp, srcp, width_bytes);\n\t\t}\n\t}\n}\nvoid TJS_INTF_METHOD tTJSNI_BitmapLayerTreeOwner::EndBitmapCompletion(iTVPLayerManager * manager) {\n}\n\nvoid tTJSNI_BitmapLayerTreeOwner::OnSetMouseCursor( tjs_int cursor ) {\n\tif( Owner ) {\n\t\ttTJSVariant arg[1] = { cursor };\n\t\tstatic ttstr eventname(TJS_W(\"onSetMouseCursor\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnGetCursorPos(tjs_int &x, tjs_int &y) {\n\tif( Owner ) {\n\t\ttjs_int vx = x, vy = y;\n\t\ttTJSVariant arg[2] = { vx, vy };\n\t\tstatic ttstr eventname(TJS_W(\"onGetCursorPos\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t\tx = arg[0];\n\t\ty = arg[1];\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnSetCursorPos(tjs_int x, tjs_int y) {\n\tif( Owner ) {\n\t\ttTJSVariant arg[2] = { x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onSetCursorPos\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnReleaseMouseCapture() {\n\tif( Owner ) {\n\t\tstatic ttstr eventname(TJS_W(\"onReleaseMouseCapture\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnSetHintText(iTJSDispatch2* sender, const ttstr &hint) {\n\tif( Owner ) {\n\t\ttTJSVariant clo(sender, sender);\n\t\ttTJSVariant arg[2] = { clo, hint };\n\t\tstatic ttstr eventname(TJS_W(\"onSetHintText\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n}\n\nvoid tTJSNI_BitmapLayerTreeOwner::OnResizeLayer( tjs_int w, tjs_int h ) {\n\tif( BitmapNI ) {\n\t\tBitmapNI->SetSize( w, h ); // TCYύXɉāABitmapTCYύX\n\t}\n\tif( Owner ) {\n\t\ttTJSVariant arg[2] = { w, h };\n\t\tstatic ttstr eventname(TJS_W(\"onResizeLayer\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnChangeLayerImage() {\n\tif( Owner ) {\n\t\tstatic ttstr eventname(TJS_W(\"onChangeLayerImage\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n\nvoid tTJSNI_BitmapLayerTreeOwner::OnSetAttentionPoint(tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y) {\n\tif( Owner ) {\n\t\tiTJSDispatch2* owner = GetOwnerNoAddRef();\n\t\ttTJSVariant clo(owner, owner);\n\t\ttTJSVariant arg[3] = { clo, x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onSetAttentionPoint\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 3, arg);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnDisableAttentionPoint() {\n\tif( Owner ) {\n\t\tstatic ttstr eventname(TJS_W(\"onDisableAttentionPoint\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnSetImeMode(tjs_int mode) {\n\tif( Owner ) {\n\t\ttTJSVariant arg[1] = { mode };\n\t\tstatic ttstr eventname(TJS_W(\"onSetImeMode\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t}\n}\nvoid tTJSNI_BitmapLayerTreeOwner::OnResetImeMode() {\n\tif( Owner ) {\n\t\tstatic ttstr eventname(TJS_W(\"onResetImeMode\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n\n\n//----------------------------------------------------------------------\ntjs_uint32 tTJSNC_BitmapLayerTreeOwner::ClassID = -1;\n\n//----------------------------------------------------------------------\ntTJSNC_BitmapLayerTreeOwner::tTJSNC_BitmapLayerTreeOwner() : inherited(TJS_W(\"BitmapLayerTreeOwner\") ) {\n\n\t// registration of native members\n\tTJS_BEGIN_NATIVE_MEMBERS(BitmapLayerTreeOwner) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_BitmapLayerTreeOwner,\n\t/*TJS class name*/BitmapLayerTreeOwner)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/BitmapLayerTreeOwner)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->FireClick(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireDoubleClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->FireDoubleClick(*param[0], *param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireDoubleClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMouseDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t_this->FireMouseDown(*param[0], *param[1], (tTVPMouseButton)(tjs_int)*param[2], (tjs_uint32)(tjs_int64)*param[3]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMouseDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMouseUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t_this->FireMouseUp(*param[0], *param[1], (tTVPMouseButton)(tjs_int)*param[2], (tjs_uint32)(tjs_int64)*param[3]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMouseUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMouseMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->FireMouseMove(*param[0], *param[1], (tjs_uint32)(tjs_int64)*param[3]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMouseMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMouseWheel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t_this->FireMouseWheel((tjs_uint32)(tjs_int64)*param[0], *param[1], *param[2], *param[3] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMouseWheel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireReleaseCapture)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t_this->FireReleaseCapture();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireReleaseCapture)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMouseOutOfWindow)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t_this->FireMouseOutOfWindow();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMouseOutOfWindow)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireTouchDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\t_this->FireTouchDown(*param[0], *param[1], *param[2], *param[3], (tjs_uint32)(tjs_int64)*param[4]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireTouchDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireTouchUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\t_this->FireTouchUp(*param[0], *param[1], *param[2], *param[3], (tjs_uint32)(tjs_int64)*param[4]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireTouchUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireTouchMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\t_this->FireTouchMove(*param[0], *param[1], *param[2], *param[3], (tjs_uint32)(tjs_int64)*param[4]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireTouchMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireTouchScaling)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\t_this->FireTouchScaling(*param[0], *param[1], *param[2], *param[3], *param[4]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireTouchScaling)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireTouchRotate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 6) return TJS_E_BADPARAMCOUNT;\n\t_this->FireTouchRotate(*param[0], *param[1], *param[2], *param[3], *param[4], *param[5]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireTouchRotate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireMultiTouch)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t_this->FireMultiTouch();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireMultiTouch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireKeyDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->FireKeyDown( (tjs_uint32)(tjs_int64)*param[0], (tjs_uint32)(tjs_int64)*param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireKeyDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireKeyUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->FireKeyUp( (tjs_uint32)(tjs_int64)*param[0], (tjs_uint32)(tjs_int64)*param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireKeyUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireKeyPress)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->FireKeyPress( (tjs_char)(tjs_int)*param[0] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireKeyPress)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireDisplayRotate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\t_this->FireDisplayRotate(*param[0], *param[1], *param[2], *param[3], *param[4]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireDisplayRotate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireRecheckInputState)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t_this->FireRecheckInputState();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireRecheckInputState)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSetMouseCursor)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSetMouseCursor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onGetCursorPos)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onGetCursorPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSetCursorPos)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSetCursorPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onReleaseMouseCapture)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onReleaseMouseCapture)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSetHintText)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSetHintText)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onResizeLayer)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onResizeLayer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onChangeLayerImage)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onChangeLayerImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSetAttentionPoint)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSetAttentionPoint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onDisableAttentionPoint)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onDisableAttentionPoint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSetImeMode)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSetImeMode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onResetImeMode)\n{\n\t//TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onResetImeMode)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\t*result = (tjs_int64)_this->GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\t*result = (tjs_int64)_this->GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bitmap)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\tif( _this->GetBitmapObjectNoAddRef() )\n\t\t\t*result = tTJSVariant(_this->GetBitmapObjectNoAddRef(), _this->GetBitmapObjectNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bitmap)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(layerTreeOwnerInterface)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\t*result = reinterpret_cast<tjs_int64>(static_cast<iTVPLayerTreeOwner*>(_this));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layerTreeOwnerInterface)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(focusedLayer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\ttTJSNI_BaseLayer *lay = _this->GetFocusedLayer();\n\t\tif(lay && lay->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(lay->GetOwnerNoAddRef(), lay->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\n\t\ttTJSNI_BaseLayer *to = NULL;\n\n\t\tif(param->Type() != tvtVoid)\n\t\t{\n\t\t\ttTJSVariantClosure clo = param->AsObjectClosureNoAddRef();\n\t\t\tif(clo.Object)\n\t\t\t{\n\t\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&to)))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t}\n\t\t}\n\n\t\t_this->SetFocusedLayer(to);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(focusedLayer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(primaryLayer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BitmapLayerTreeOwner);\n\t\ttTJSNI_BaseLayer *pri = _this->GetPrimaryLayer();\n\t\tif(!pri) TVPThrowExceptionMessage(TJS_W(\"Not have primary layer\"));\n\n\t\tif(pri && pri->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(pri->GetOwnerNoAddRef(), pri->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(primaryLayer)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n\n//----------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_BitmapLayerTreeOwner::CreateNativeInstance() {\n\treturn new tTJSNI_BitmapLayerTreeOwner();\n}\n//----------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_BitmapLayerTreeOwner()\n{\n\treturn new tTJSNC_BitmapLayerTreeOwner();\n}\n//----------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/BitmapLayerTreeOwner.h",
    "content": "//---------------------------------------------------------------------------\n/**\n * ` Bitmap Ƃ Layer Tree Owner\n * C[ɕ`āAꂽéÃNX̕ێ Bitmap ɕ`\n * ݒ̂߂ɌĂтꂽ\\bhCxgƂĒʒm\n */\n//---------------------------------------------------------------------------\n//!@file C[c[I[i[\n//---------------------------------------------------------------------------\n\n#ifndef BitmapLayerTreeOwner_H\n#define BitmapLayerTreeOwner_H\n\n#include \"LayerTreeOwnerImpl.h\"\n\nclass tTJSNI_BitmapLayerTreeOwner : public tTJSNativeInstance, public tTVPLayerTreeOwner\n{\n\tiTJSDispatch2 *Owner;\n\tiTJSDispatch2 *BitmapObject;\n\ttTJSNI_Bitmap *BitmapNI;\n\npublic:public:\n\ttTJSNI_BitmapLayerTreeOwner();\n\t~tTJSNI_BitmapLayerTreeOwner();\n\n\t// tTJSNativeInstance\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\tiTJSDispatch2* GetBitmapObjectNoAddRef();\n\n\t// tTVPLayerTreeOwner\n\tiTJSDispatch2 * TJS_INTF_METHOD GetOwnerNoAddRef() const { return Owner; }\n\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, tTVPBaseTexture *bmp,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity);\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager);\n\n\tvirtual void OnSetMouseCursor( tjs_int cursor );\n\tvirtual void OnGetCursorPos(tjs_int &x, tjs_int &y);\n\tvirtual void OnSetCursorPos(tjs_int x, tjs_int y);\n\tvirtual void OnReleaseMouseCapture();\n\tvirtual void OnSetHintText(iTJSDispatch2* sender, const ttstr &hint);\n\n\tvirtual void OnResizeLayer( tjs_int w, tjs_int h );\n\tvirtual void OnChangeLayerImage();\n\n\tvirtual void OnSetAttentionPoint(tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y);\n\tvirtual void OnDisableAttentionPoint();\n\tvirtual void OnSetImeMode(tjs_int mode);\n\tvirtual void OnResetImeMode();\n\n\ttjs_int GetWidth() const { return BitmapNI->GetWidth(); }\n\ttjs_int GetHeight() const { return BitmapNI->GetHeight(); }\n};\n\nclass tTJSNC_BitmapLayerTreeOwner : public tTJSNativeClass {\n\ttypedef tTJSNativeClass inherited;\npublic:\n\ttTJSNC_BitmapLayerTreeOwner();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n\nextern tTJSNativeClass * TVPCreateNativeClass_BitmapLayerTreeOwner();\n#endif\n"
  },
  {
    "path": "src/core/visual/CharacterData.cpp",
    "content": "\n#include \"CharacterData.h\"\n#include \"tvpgl.h\"\n#include \"MsgIntf.h\"\n#include \"tjsUtils.h\"\n#include <complex>\n\n//---------------------------------------------------------------------------\ntTVPCharacterData::tTVPCharacterData( const tjs_uint8 * indata,\n\ttjs_int inpitch,\n\ttjs_int originx, tjs_int originy,\n\ttjs_uint blackboxw, tjs_uint blackboxh,\n\tconst tGlyphMetrics & metrics, bool fullcolor )\n: Antialiased(false), Blured(false)\n{\n\n\t// tB[h̃NA\n\tRefCount = 1; // QƃJE^̏l 1\n\tData = NULL;\n\n\t// Metrics rbg}bṽRs[\n\tMetrics = metrics;\n\tOriginX = originx;\n\tOriginY = originy;\n\tBlackBoxX = blackboxw;\n\tBlackBoxY = blackboxh;\n\tGray = 65;\n\tFullColored = fullcolor;\n\n\t// TCỸ`FbN\n\tif( BlackBoxX != 0 && BlackBoxY != 0 ) {\n\t\ttry {\n\t\t\t// rbg}bvRs[\n\t\t\tif( fullcolor ) {\n\t\t\t\t//- ̃sb`vZ\n\t\t\t\t// MMX ̎gplĉ 8 oCgŃAC\n\t\t\t\tPitch = (((blackboxw*4 - 1) >> 3) + 1) << 3;\n\n\t\t\t\t//- oCgvZăm\n\t\t\t\tData = (tjs_uint8 *)TJSAlignedAlloc(Pitch * blackboxh, 4);\n\n\t\t\t\t//- rbg}bvRs[\n\t\t\t\tinpitch *= 4;\n\t\t\t\tfor(tjs_uint y = 0; y < blackboxh; y++) {\n\t\t\t\t\tmemcpy( Data + Pitch * y, indata + inpitch * y, blackboxw*4);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//- ̃sb`vZ\n\t\t\t\t// MMX ̎gplĉ 8 oCgŃAC\n\t\t\t\tPitch = (((blackboxw - 1) >> 3) + 1) << 3;\n\n\t\t\t\t//- oCgvZăm\n\t\t\t\tData = (tjs_uint8 *)TJSAlignedAlloc(Pitch * blackboxh, 4);\n\n\t\t\t\t//- rbg}bvRs[\n\t\t\t\tfor(tjs_uint y = 0; y < blackboxh; y++) {\n\t\t\t\t\tmemcpy( Data + Pitch * y, indata + inpitch * y, blackboxw);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch(...) {\n\t\t\tif (Data) TJSAlignedDealloc(Data);\n\t\t\tthrow;\n\t\t}\n\t}\n}\n\n//---------------------------------------------------------------------------\n/**\n * Rs[RXgN^\n * @param ref\tQƃIuWFNg\n */\ntTVPCharacterData::tTVPCharacterData(const tTVPCharacterData & ref) {\n\t// Rs[RXgN^͖T|[g\n\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::tTVPCharacterData(const tTVPCharacterData & ref)\") );\n}\n\ntTVPCharacterData::~tTVPCharacterData()\n{\n\tif (Data) TJSAlignedDealloc(Data);\n}\n\nvoid tTVPCharacterData::Alloc(tjs_int size)\n{\n\tif (Data) TJSAlignedDealloc(Data), Data = NULL;\n\tData = (tjs_uint8*)TJSAlignedAlloc(size, 4);\n}\n\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Expand()\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Expand for FullColored\") );\n\n\t// expand the bitmap stored in 1bpp, to 8bpp\n\ttjs_int newpitch = (((BlackBoxX -1)>>2)+1)<<2;\n\ttjs_uint8 *nd;\n\ttjs_uint8 *newdata = nd = (tjs_uint8 *)TJSAlignedAlloc(newpitch * BlackBoxY, 4);\n\ttjs_int h = BlackBoxY;\n\ttjs_uint8 *d = Data;\n\n\ttjs_int w = BlackBoxX;\n\tstatic tjs_uint32 pal[2] = {0, 64};\n\twhile(h--)\n\t{\n\t\tTVPBLExpand1BitTo8BitPal(nd, d, w, pal);\n\t\tnd += newpitch, d += Pitch;\n\t}\n\tif (Data) TJSAlignedDealloc(Data);\n\tData = newdata;\n\tPitch = newpitch;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Blur(tjs_int blurlevel, tjs_int blurwidth)\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Blur for FullColored\") );\n\n\t// blur the bitmap with given parameters\n\t// blur the bitmap\n\tif(!Data) return;\n\tif(blurlevel == 255 && blurwidth == 0) return; // no need to blur\n\tif(blurwidth == 0)\n\t{\n\t\t// no need to blur but must be transparent\n\t\tif( Gray == 256 )\n\t\t\tTVPChBlurMulCopy(Data, Data, Pitch*BlackBoxY, BlurLevel<<10);\n\t\telse\n\t\t\tTVPChBlurMulCopy65(Data, Data, Pitch*BlackBoxY, BlurLevel<<10);\n\t\treturn;\n\t}\n\n\t// simple blur ( need to optimize )\n\ttjs_int bw = std::abs(blurwidth);\n\ttjs_int newwidth = BlackBoxX + bw*2;\n\ttjs_int newheight = BlackBoxY + bw*2;\n\ttjs_int newpitch =  (((newwidth -1)>>2)+1)<<2;\n\n\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\n\tif( Gray == 256 )\n\t\tTVPChBlurCopy(newdata, newpitch, newwidth, newheight, Data, Pitch, BlackBoxX,\n\t\t\tBlackBoxY, bw, blurlevel);\n\telse\n\t\tTVPChBlurCopy65(newdata, newpitch, newwidth, newheight, Data, Pitch, BlackBoxX,\n\t\t\tBlackBoxY, bw, blurlevel);\n\n\tTJSAlignedDealloc(Data);\n\tData = newdata;\n\tBlackBoxX = newwidth;\n\tBlackBoxY = newheight;\n\tPitch = newpitch;\n\tOriginX -= blurwidth;\n\tOriginY -= blurwidth;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Blur()\n{\n\t// blur the bitmap\n\tBlur(BlurLevel, BlurWidth);\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Bold(tjs_int size)\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Bold for FullColored\") );\n\n\t// enbold the bitmap for 65-level grayscale bitmap\n\tif(size < 0) size = -size;\n\ttjs_int level = (tjs_int)(size / 50) + 1;\n\tif(level > 8) level = 8;\n\n\t// compute new metrics\n\ttjs_int newwidth = BlackBoxX + level;\n\ttjs_int newheight = BlackBoxY;\n\ttjs_int newpitch =  (((newwidth -1)>>2)+1)<<2;\n\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\n\t// apply bold\n\ttjs_uint8 * srcp = Data;\n\ttjs_uint8 * destp = newdata;\n\tfor(tjs_int y = 0; y<newheight; y++)\n\t{\n\t\tfor(tjs_int i = 0; i<level; i++) destp[i] = srcp[i];\n\t\tdestp[0] = srcp[0];\n\t\tfor(tjs_int x = level; x<newwidth-level; x++)\n\t\t{\n\t\t\ttjs_uint largest = srcp[x];\n\t\t\tfor(tjs_int xx = x-level; xx<x; xx++)\n\t\t\t\tif((tjs_uint)srcp[xx] > largest) largest = srcp[xx];\n\t\t\tdestp[x] = largest;\n\t\t}\n\t\tfor(tjs_int i = 0; i<level; i++) destp[newwidth-i-1] = srcp[BlackBoxX-1-i];\n\n\t\tsrcp += Pitch;\n\t\tdestp += newpitch;\n\t}\n\n\t// replace old data\n\tTJSAlignedDealloc(Data);\n\tData = newdata;\n\tBlackBoxX = newwidth;\n\tBlackBoxY = newheight;\n\tOriginX -= level /2;\n\tPitch = newpitch;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Bold2(tjs_int size)\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Bold2 for FullColored\") );\n\n\t// enbold the bitmap for black/white monochrome bitmap\n\tif(size < 0) size = -size;\n\ttjs_int level = (tjs_int)(size / 50) + 1;\n\tif(level > 8) level = 8;\n\n\t// compute new metrics\n\ttjs_int newwidth = BlackBoxX + level;\n\ttjs_int newheight = BlackBoxY;\n\ttjs_int newpitch =  (((newwidth -1)>>5)+1)<<2;\n\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\n\t// apply bold\n\ttjs_uint8 * srcp = Data;\n\ttjs_uint8 * destp = newdata;\n\tfor(tjs_int y = 0; y<newheight; y++)\n\t{\n\t\tmemcpy(destp, srcp, Pitch);\n\t\tif(newpitch > Pitch) destp[Pitch] = 0;\n\n\t\tfor(tjs_int i = 1; i<=level; i++)\n\t\t{\n\t\t\ttjs_uint8 bollow = 0;\n\t\t\ttjs_int bl = 8 - i;\n\t\t\tfor(tjs_int x = 0; x < Pitch; x++)\n\t\t\t{\n\t\t\t\tdestp[x] |= (srcp[x] >> i) + bollow;\n\t\t\t\tbollow = srcp[x] << bl;\n\t\t\t}\n\t\t\tif(newpitch > Pitch) destp[Pitch] |= bollow;\n\t\t}\n\n\t\tsrcp += Pitch;\n\t\tdestp += newpitch;\n\t}\n\n\t// replace old data\n\tTJSAlignedDealloc(Data);\n\tData = newdata;\n\tBlackBoxX = newwidth;\n\tBlackBoxY = newheight;\n\tOriginX -= level /2;\n\tPitch = newpitch;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Resample4()\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Resample4 for FullColored\") );\n\n\t// down-sampling 4x4\n\n\tstatic tjs_uint16 bitcounter[256] = {0xffff};\n\tif(bitcounter[0] == 0xffff)\n\t{\n\t\t// initialize bitcounter table\n\t\ttjs_uint i;\n\t\tfor(i = 0; i<256; i++)\n\t\t{\n\t\t\ttjs_uint16 v;\n\t\t\ttjs_int n;\n\t\t\tn = i & 0x0f;\n\t\t\tn = (n & 0x5) + ((n & 0xa)>>1);\n\t\t\tn = (n & 0x3) + ((n & 0xc)>>2);\n\t\t\tv = (n<<2);\n\t\t\tn = i >> 4;\n\t\t\tn = (n & 0x5) + ((n & 0xa)>>1);\n\t\t\tn = (n & 0x3) + ((n & 0xc)>>2);\n\t\t\tv |= ((n<<2)) << 8;\n\t\t\tbitcounter[i] = v;\n\t\t}\n\t}\n\n\ttjs_int newwidth = ((BlackBoxX-1)>>2)+1;\n\ttjs_int newheight = ((BlackBoxY-1)>>2)+1;\n\ttjs_int newpitch =  (((newwidth -1)>>2)+1)<<2;\n\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\n\t// resampling\n\ttjs_uint8 * srcp = Data;\n\ttjs_uint8 * destp = newdata;\n\tfor(tjs_int y = 0; y<newheight; y++)\n\t{\n\t\tif(BlackBoxX & 7) srcp[BlackBoxX / 8] &=\n\t\t\t((tjs_int8)0x80) >> ((BlackBoxX & 7) -1); // mask right fraction\n\n\t\ttjs_uint orgy = y*4;\n\t\ttjs_int rem = BlackBoxY - orgy;\n\t\trem = rem > 4 ? 4 : rem;\n\n\t\ttjs_uint8 *dp = destp;\n\t\ttjs_int lim = (newwidth+1) >> 1;\n\t\tfor(tjs_int i = 0; i<lim; i++)\n\t\t{\n\t\t\ttjs_uint32 n = 0;\n\t\t\ttjs_uint8 *sp = srcp + i;\n\t\t\tswitch(rem)\n\t\t\t{\n\t\t\tcase 4:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 3:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 2:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 1:\tn += bitcounter[*sp];\n\t\t\t}\n\t\t\tdp[0] = n >> 8;\n\t\t\tdp[1] = n & 0xff;\n\t\t\tdp += 2;\n\t\t}\n\n\t\tsrcp += Pitch * 4;\n\t\tdestp += newpitch;\n\t}\n\n\t// replace old data\n\tTJSAlignedDealloc(Data);\n\tData = newdata;\n\tBlackBoxX = newwidth;\n\tBlackBoxY = newheight;\n\tOriginX = OriginX /4;\n\tOriginY = OriginY /4;\n\tPitch = newpitch;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::Resample8()\n{\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::Resample8 for FullColored\") );\n\n\t// down-sampling 8x8\n\n\tstatic tjs_uint8 bitcounter[256] = {0xff};\n\tif(bitcounter[0] == 0xff)\n\t{\n\t\t// initialize bitcounter table\n\t\ttjs_uint i;\n\t\tfor(i = 0; i<256; i++)\n\t\t{\n\t\t\ttjs_int n;\n\t\t\tn = (i & 0x55) + ((i & 0xaa)>>1);\n\t\t\tn = (n & 0x33) + ((n & 0xcc)>>2);\n\t\t\tn = (n & 0x0f) + ((n & 0xf0)>>4);\n\t\t\tbitcounter[i] = (tjs_uint8)n;\n\t\t}\n\t}\n\n\ttjs_int newwidth = ((BlackBoxX-1)>>3)+1;\n\ttjs_int newheight = ((BlackBoxY-1)>>3)+1;\n\ttjs_int newpitch =  (((newwidth -1)>>2)+1)<<2;\n\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\n\t// resampling\n\ttjs_uint8 * srcp = Data;\n\ttjs_uint8 * destp = newdata;\n\tfor(tjs_int y = 0;;)\n\t{\n\t\tif(BlackBoxX & 7) srcp[BlackBoxX / 8] &=\n\t\t\t((tjs_int8)0x80) >> ((BlackBoxX & 7) -1); // mask right fraction\n\n\t\ttjs_uint orgy = y*8;\n\t\ttjs_int rem = BlackBoxY - orgy;\n\t\trem = rem > 8 ? 8 : rem;\n\n\t\tfor(tjs_int x = 0; x<newwidth; x++)\n\t\t{\n\t\t\ttjs_uint n = 0;\n\t\t\ttjs_uint8 *sp = srcp + x;\n\t\t\tswitch(rem)\n\t\t\t{\n\t\t\tcase 8:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 7:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 6:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 5:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 4:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 3:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 2:\tn += bitcounter[*sp]; sp += Pitch;\n\t\t\tcase 1:\tn += bitcounter[*sp];\n\t\t\t}\n\t\t\tdestp[x] = n;\n\t\t}\n\n\t\ty++;\n\t\tif(y >= newheight) break;\n\t\tsrcp += Pitch * 8;\n\t\tdestp += newpitch;\n\t}\n\n\t// replace old data\n\tTJSAlignedDealloc(Data);\n\tData = newdata;\n\tBlackBoxX = newwidth;\n\tBlackBoxY = newheight;\n\tOriginX = OriginX /8;\n\tOriginY = OriginY /8;\n\tPitch = newpitch;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCharacterData::AddHorizontalLine( tjs_int liney, tjs_int thickness, tjs_uint8 val ) {\n\tif( FullColored )\n\t\tTVPThrowExceptionMessage( TJS_W(\"unimplemented: tTVPCharacterData::AddHorizontalLine for FullColored\") );\n\n\ttjs_int linetop = liney - thickness/2;\n\tif( linetop < 0 ) linetop = 0;\n\ttjs_int linebottom = linetop + thickness;\n\n\ttjs_int newwidth = BlackBoxX;\n\ttjs_int newheight = BlackBoxY;\n\ttjs_int overlapx = 0;\n\tif( OriginX < 0 ) overlapx = -OriginX;\t// O̕ɂԂ悤ɕ`悳邱Ƃ\n\tif( BlackBoxX != (Metrics.CellIncX+overlapx) ) {\n\t\tnewwidth = Metrics.CellIncX+overlapx;\n\t}\n\tint top = OriginY;\n\tint bottom = top + BlackBoxY;\n\tif( linetop < top ) { // ߂\n\t\ttop = linetop;\n\t} else if( linebottom > bottom ) { // ߂\n\t\tbottom = linebottom;\n\t}\n\tnewheight = bottom - top;\n\t// 傫ω鎞͍蒼\n\tif( newwidth != BlackBoxX || newheight != BlackBoxY ) {\n\t\t//tjs_int newpitch =  (((newwidth -1)>>2)+1)<<2;\n\t\ttjs_int newpitch =  (((newwidth*4 - 1) >> 3) + 1) << 3;\n\t\ttjs_uint8 *newdata = (tjs_uint8 *)TJSAlignedAlloc(newpitch * newheight, 4);\n\t\tmemset( newdata, 0, sizeof(tjs_uint8)*newpitch*newheight );\n\t\t// x  OriginX \n\t\t// y  OriginY - top\n\t\ttjs_int offsetx = OriginX;\n\t\tif( offsetx < 0 ) offsetx =0;\n\t\ttjs_int offsety = OriginY - top;\n\t\ttjs_uint8 *sp = Data;\n\t\ttjs_uint8 *dp = newdata + offsety*newpitch + offsetx;\n\t\tfor( tjs_uint y = 0; y < BlackBoxY; y++ ) {\n\t\t\tfor( tjs_uint x = 0; x < BlackBoxX; x++ ) {\n\t\t\t\tdp[x] = sp[x];\n\t\t\t}\n\t\t\tsp += Pitch;\n\t\t\tdp += newpitch;\n\t\t}\n\t\tTJSAlignedDealloc(Data);\n\t\tData = newdata;\n\t\tBlackBoxX = newwidth;\n\t\tBlackBoxY = newheight;\n\t\tif( OriginX > 0 ) OriginX = 0;\n\t\tOriginY = top;\n\t\tPitch = newpitch;\n\t}\n\ttjs_int end = linetop-OriginY+thickness;\n\ttjs_uint8 *dp = Data + (linetop-OriginY)*Pitch;\n\tfor( tjs_int y = 0; y < thickness; y++ ) {\n\t\tfor( tjs_uint x = 0; x < BlackBoxX; x++ ) {\n\t\t\tdp[x] = val;\n\t\t}\n\t\tdp += Pitch;\n\t}\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/CharacterData.h",
    "content": "\n\n#ifndef __CHARACTER_DATA_H__\n#define __CHARACTER_DATA_H__\n\n#include \"tjsCommHead.h\"\n#include \"tvpfontstruc.h\"\n\n/**\n * POt̃gbN\\\\\n */\nstruct tGlyphMetrics\n{\n\ttjs_int CellIncX;\t\t//!< ꕶi߂̕KvX̃sNZ\n\ttjs_int CellIncY;\t\t//!< ꕶi߂̕KvỸsNZ\n};\n\n//---------------------------------------------------------------------------\n/**\n * POt\\NX\n */\nclass tTVPCharacterData\n{\n\t// character data holder for caching\nprivate:\n\ttjs_uint8 * Data;\n\ttjs_int RefCount;\n\npublic:\n\ttjs_int OriginX; //!< Bitmap`悷ascentʒuƂ̉ItZbg\n\ttjs_int OriginY; //!< Bitmap`悷ascentʒuƂ̏cItZbg\n\ttGlyphMetrics\tMetrics; //!< gbNA蕝ƍێ\n\ttjs_int Pitch; //!< ێĂ摜sb`\n\ttjs_uint BlackBoxX; //!< ێĂ摜\n\ttjs_uint BlackBoxY; //!< ێĂ摜\n\ttjs_int BlurLevel;\n\ttjs_int BlurWidth;\n\ttjs_uint Gray; // K\n\n\tbool Antialiased;\n\tbool Blured;\n\tbool FullColored;\n\npublic:\n\ttTVPCharacterData() : Gray(65), FullColored(false) { RefCount = 1; Data = NULL; }\n\ttTVPCharacterData( const tjs_uint8 * indata,\n\t\ttjs_int inpitch,\n\t\ttjs_int originx, tjs_int originy,\n\t\ttjs_uint blackboxw, tjs_uint blackboxh,\n\t\tconst tGlyphMetrics & metrics,\n\t\tbool fullcolor = false );\n\ttTVPCharacterData(const tTVPCharacterData & ref);\n\t~tTVPCharacterData();\n\n\tvoid Alloc(tjs_int size);\n\n\ttjs_uint8 * GetData() const { return Data; }\n\n\tvoid AddRef() { RefCount ++; }\n\tvoid Release() {\n\t\tif(RefCount == 1) {\n\t\t\tdelete this;\n\t\t} else {\n\t\t\tRefCount--;\n\t\t}\n\t}\n\n\tvoid Expand();\n\n\tvoid Blur(tjs_int blurlevel, tjs_int blurwidth);\n\tvoid Blur();\n\n\tvoid Bold(tjs_int size);\n\tvoid Bold2(tjs_int size);\n\n\tvoid Resample4();\n\tvoid Resample8();\n\n\t/**\n\t * ǉ(AA_[Cp)\n\t * @param liney : CSʒu\n\t * @param thickness : C\n\t * @param val : Cl\n\t */\n\tvoid AddHorizontalLine( tjs_int liney, tjs_int thickness, tjs_uint8 val );\n};\n\n//---------------------------------------------------------------------------\n// Character Cache management\n//---------------------------------------------------------------------------\nstruct tTVPFontAndCharacterData\n{\n\ttTVPFont Font;\n\ttjs_uint32 FontHash;\n\ttjs_char Character;\n\ttjs_int BlurLevel;\n\ttjs_int BlurWidth;\n\tbool Antialiased;\n\tbool Blured;\n\tbool Hinting;\n\tbool operator == (const tTVPFontAndCharacterData &rhs) const {\n\t\treturn Character == rhs.Character && Font == rhs.Font &&\n\t\t\tAntialiased == rhs.Antialiased && BlurLevel == rhs.BlurLevel &&\n\t\t\tBlurWidth == rhs.BlurWidth && Blured == rhs.Blured &&\n\t\t\tHinting == rhs.Hinting;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPFontHashFunc\n{\npublic:\n\tstatic tjs_uint32 Make(const tTVPFontAndCharacterData &val)\n\t{\n\t\ttjs_uint32 v = val.FontHash;\n\n\t\tv ^= val.Antialiased?1:0;\n\t\tv ^= val.Character;\n\t\tv ^= val.Blured?1:0;\n\t\tv ^= val.BlurLevel ^ val.BlurWidth;\n\t\treturn v;\n\t}\n};\n\n\n\n\n\n#endif // __CHARACTER_DATA_H__\n"
  },
  {
    "path": "src/core/visual/ComplexRect.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Complex Rectangle Class\n//---------------------------------------------------------------------------\n#define NOMINMAX\n#include \"tjsCommHead.h\"\n\n#include \"ComplexRect.h\"\n#include <vector>\n#include <algorithm>\n\n// Some algorithms and ideas are based on implementation of Mozilla,\n// gfx/src/nsRegion.cpp.\n\n\n\n//---------------------------------------------------------------------------\n// TVPIntersectRect\n//---------------------------------------------------------------------------\nbool TVPIntersectRect(tTVPRect *dest, const tTVPRect &src1,\n\tconst tTVPRect &src2)\n{\n\ttjs_int left =\t\tstd::max(src1.left,\t\tsrc2.left);\n\ttjs_int top =\t\tstd::max(src1.top,\t\tsrc2.top);\n\ttjs_int right =\t\tstd::min(src1.right,\tsrc2.right);\n\ttjs_int bottom =\tstd::min(src1.bottom,\tsrc2.bottom);\n\n\tif(right > left && bottom > top)\n\t{\n\t\tif(dest)\n\t\t{\n\t\t\tdest->left =\tleft;\n\t\t\tdest->top =\t\ttop;\n\t\t\tdest->right =\tright;\n\t\t\tdest->bottom =\tbottom;\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPUnionRect\n//---------------------------------------------------------------------------\nbool TVPUnionRect(tTVPRect *dest, const tTVPRect &src1, const tTVPRect &src2)\n{\n\ttjs_int left =\t\tstd::min(src1.left,\t\tsrc2.left);\n\ttjs_int top =\t\tstd::min(src1.top,\t\tsrc2.top);\n\ttjs_int right =\t\tstd::max(src1.right,\tsrc2.right);\n\ttjs_int bottom =\tstd::max(src1.bottom,\tsrc2.bottom);\n\n\tif(right > left && bottom > top)\n\t{\n\n\t\tif(dest)\n\t\t{\n\t\t\tdest->left =\tleft;\n\t\t\tdest->top =\t\ttop;\n\t\t\tdest->right =\tright;\n\t\t\tdest->bottom =\tbottom;\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPRegionRect allocation routines\n//---------------------------------------------------------------------------\n// variables\nstatic tjs_uint TVPRegionFreeMaxCount = 0;\n\t// maximum count of free rectangles in TVPRegionFreeRects\nstatic std::vector<tTVPRegionRect *>  * TVPRegionFreeRects = NULL;\n#define TVP_REGIONRECT_ALLOC_UNITS   256\n\t// Number of rectangles which to be allocated in a call of\n\t// TVPPrepareRegionRectangle()\n//---------------------------------------------------------------------------\nclass tTVPRegionRectInitialHolder\n{\n\t// Initial rectangle holder to prevent unnecessary freeing of the vector.\n\t// This holds a rectangle from program start to end.\n\ttTVPRegionRect * InitialRect;\npublic:\n\ttTVPRegionRectInitialHolder() { InitialRect = NULL; }\n\tvoid Hold() { if(!InitialRect) { InitialRect = (tTVPRegionRect *)-1;\n\t\tInitialRect = TVPAllocateRegionRect(); } }\n\t~tTVPRegionRectInitialHolder() { if(InitialRect) TVPDeallocateRegionRect(InitialRect); }\n};\nstatic tTVPRegionRectInitialHolder TVPRegionRectInitialHolder;\n//---------------------------------------------------------------------------\nstatic void TVPPrepareRegionRectangle()\n{\n\t// Prepare rectangles and insert them into free rectangle list\n\tfor(tjs_int i = 0; i < TVP_REGIONRECT_ALLOC_UNITS; i++)\n\t{\n\t\tTVPRegionFreeRects->push_back(\n\t\t\t(tTVPRegionRect*)(new char[sizeof (tTVPRegionRect)]));\n\t\tTVPRegionFreeMaxCount++;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPRegionRect * TVPAllocateRegionRect()\n{\n\t// Allocate a region rectangle. Note that this function does not clear\n\t// nor initialize the rectangle object.\n\n\t// Create a vector of free rectangle list if it does not exists\n\tif(!TVPRegionFreeRects)\n\t\tTVPRegionFreeRects = new std::vector<tTVPRegionRect *>();\n\n\t// Prepare free rectangles if the free list is empty\n\tif(TVPRegionFreeRects->size() == 0)\n\t\tTVPPrepareRegionRectangle();\n\n\t// Take a free rectangle from last of the free rectangle list\n\ttTVPRegionRect * r = TVPRegionFreeRects->back();\n\tTVPRegionFreeRects->pop_back();\n\n\t// Hold initial rectangle\n\tTVPRegionRectInitialHolder.Hold();\n\n\t// Return the rectangle\n\treturn r;\n}\n//---------------------------------------------------------------------------\nvoid TVPDeallocateRegionRect(tTVPRegionRect * rect)\n{\n\t// Deallocate a region rectangle allocated in TVPAllocateRegionRect().\n\n\t// Append to TVPRegionFreeRects\n//\tif(!TVPRegionFreeRects) TVPThrowInternalError();  //----------------- geee\n\tTVPRegionFreeRects->push_back(rect);\n\n\t// Full-Free check\n\tif(TVPRegionFreeRects->size() == TVPRegionFreeMaxCount)\n\t{\n\t\t// Free all rectangles\n\t\tfor(std::vector<tTVPRegionRect *>::iterator i = TVPRegionFreeRects->begin();\n\t\t\ti != TVPRegionFreeRects->end(); i++)\n\t\t\tdelete [] (char *)(*i);\n\n\t\t// Free the vector\n\t\tdelete TVPRegionFreeRects, TVPRegionFreeRects = NULL;\n\t\tTVPRegionFreeMaxCount = 0;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPComplexRect\n//---------------------------------------------------------------------------\ntTVPComplexRect::tTVPComplexRect()\n{\n\t// normal constructor\n\tInit();\n}\n//---------------------------------------------------------------------------\ntTVPComplexRect::tTVPComplexRect(const tTVPComplexRect & ref)\n: Bound(ref.Bound)\n{\n\t// copy constructor\n\tInit();\n\n\t// allocate storage\n\tSetCount(ref.Count);\n\n\t// copy rectangles\n\tif(Count)\n\t{\n\t\ttTVPRegionRect * this_cur = Head;\n\t\ttTVPRegionRect * ref_cur = ref.Head;\n\t\tdo\n\t\t{\n\t\t\t*(tTVPRect*)this_cur = *(tTVPRect*)ref_cur; // copy as tTVPRect\n\t\t\tthis_cur = this_cur->Next;\n\t\t\tref_cur = ref_cur->Next;\n\t\t} while(ref_cur != ref.Head);\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPComplexRect::~tTVPComplexRect()\n{\n\t// destructor\n\tFreeAllRectangles();\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Clear()\n{\n\tFreeAllRectangles();\n\tInit();\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::FreeAllRectangles()\n{\n\t// free all rectangles\n\tif(Count)\n\t{\n\t\ttTVPRegionRect *cur = Head;\n\t\tdo\n\t\t{\n\t\t\ttTVPRegionRect *n  = cur->Next;\n\t\t\tdelete cur;\n\t\t\tcur = n;\n\t\t} while(cur != Head);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Init()\n{\n\t// initialize internal states\n\tHead = NULL;\n\tCurrent = NULL;\n\tCount = 0;\n\tBound.left = Bound.top = Bound.right = Bound.bottom = 0;\n\tBoundValid = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::SetCount(tjs_int count)\n{\n\t// grow or shrink rectangle storage area\n\tif(count > Count)\n\t{\n\t\t// grow\n\t\ttjs_int add_count = count - Count;\n\t\tif(!Count)\n\t\t{\n\t\t\t// no existent rectangle\n\t\t\tHead = new tTVPRegionRect();\n\t\t\tHead->Prev = Head;\n\t\t\tHead->Next = Head;\n\t\t\tadd_count --;\n\t\t}\n\n\t\ttTVPRegionRect * cur = Head->Prev;\n\t\tCurrent = cur;\n\t\twhile(add_count--)\n\t\t{\n\t\t\ttTVPRegionRect * newrect = new tTVPRegionRect();\n\t\t\tnewrect->LinkBefore(Head);\n\t\t}\n\t\tCount = count;\n\t}\n\telse if(count < Count)\n\t{\n\t\t// shrink\n\t\tif(Count)\n\t\t{\n\t\t\ttjs_int remove_count = Count - count;\n\t\t\ttTVPRegionRect * cur = Head->Prev;\n\t\t\twhile(remove_count--)\n\t\t\t{\n\t\t\t\ttTVPRegionRect * prev = cur->Prev;\n\t\t\t\tdelete cur;\n\t\t\t\tcur = prev;\n\t\t\t}\n\t\t\tCount = count;\n\t\t\tif(Count)\n\t\t\t\tcur->Next = Head, Current = Head, Head->Prev = cur;\n\t\t\telse\n\t\t\t\tHead = NULL, Current = NULL;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTVPComplexRect::Insert(const tTVPRect & rect)\n{\n\t// Insert a region rectangle inplace.\n\t// Note that this function does not update the bounding rectangle.\n\t// This does empty check.\n\n\tif(rect.is_empty()) return false;\n\n\tif(!Count)\n\t{\n\t\t// first insertion\n\t\tHead = new tTVPRegionRect(rect);\n\t\tHead->Prev = Head->Next = Head;\n\t\tCurrent = Head;\n\t\tCount = 1;\n\t\treturn true;\n\t}\n\n\t// Search insertion point and insert there.\n\t// Link list is sorted by upper-left point of the rectangle,\n\t// Search starts from \"Current\", which is the most recently touched rectangle.\n\tif(*Current > rect)\n\t{\n\t\t// insertion point is before Current\n\t\ttTVPRegionRect *prev;\n\t\twhile(true)\n\t\t{\n\t\t\tif(Current == Head)\n\t\t\t{\n\t\t\t\t// insert before head\n\t\t\t\tif(Head->top == rect.top && Head->bottom == rect.bottom &&\n\t\t\t\t\tHead->Left == rect.right)\n\t\t\t\t{\n\t\t\t\t\tHead->Left = rect.left; // unite Head\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttTVPRegionRect * new_rect = new tTVPRegionRect(rect);\n\t\t\t\t\tnew_rect->LinkBefore(Head);\n\t\t\t\t\tCount ++;\n\t\t\t\t\tHead = new_rect;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprev = Current->Prev;\n\t\t\tif(*prev < rect)\n\t\t\t{\n\n\t\t\t\t// insert between prev and Current\n\t\t\t\tif(Current->top == rect.top && Current->bottom == rect.bottom &&\n\t\t\t\t\tCurrent->left == rect.right)\n\t\t\t\t{\n\t\t\t\t\tCurrent->left = rect.left; // unite right\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse \n\t\t\t\t{\n\t\t\t\t\ttTVPRegionRect * new_rect = new tTVPRegionRect(rect);\n\t\t\t\t\tnew_rect->LinkBefore(Current);\n\t\t\t\t\tCount ++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tCurrent = prev;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// insertion point is after Current\n\t\ttTVPRegionRect *next;\n\t\twhile(true)\n\t\t{\n\t\t\tnext = Current->Next;\n\t\t\tif(next == Head)\n\t\t\t{\n\t\t\t\t// insert after last of the link list\n\t\t\t\t// (that is, before the Head)\n\t\t\t\tif(Current->top == rect.top && Current->bottom == rect.bottom &&\n\t\t\t\t\tCurrent->right == rect.left)\n\t\t\t\t{\n\t\t\t\t\tCurrent->right = rect.right; // unite right\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttTVPRegionRect * new_rect = new tTVPRegionRect(rect);\n\t\t\t\t\tnew_rect->LinkBefore(Head);\n\t\t\t\t\tCount ++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(*next > rect)\n\t\t\t{\n\t\t\t\t// insert between next and Current\n\t\t\t\tif(next->top == rect.top && next->bottom == rect.bottom &&\n\t\t\t\t\tnext->left == rect.right)\n\t\t\t\t{\n\t\t\t\t\tnext->left = rect.left; // unite right\n\t\t\t\t\tif(Current->top == rect.top && Current->bottom == rect.bottom &&\n\t\t\t\t\t\tCurrent->right == rect.left)\n\t\t\t\t\t{\n\t\t\t\t\t\tnext->left = Current->left; // unite left\n\t\t\t\t\t\tRemove(Current);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttTVPRegionRect * new_rect = new tTVPRegionRect(rect);\n\t\t\t\t\tnew_rect->LinkBefore(next);\n\t\t\t\t\tCount ++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tCurrent = next;\n\t\t}\n\t}\n\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Remove(tTVPRegionRect * rect)\n{\n\t// Remove a rectangle.\n\t// Note that this function does not update the bounding rectangle.\n\tif(rect == Head) Head = rect->Next;\n\n\tCount --;\n\tif(!Count)\n\t{\n\t\t// no more rectangles\n\t\tCurrent = Head = NULL;\n\t}\n\telse\n\t{\n\t\tif(rect == Current) Current = rect->Prev;\n\t}\n\trect->Unlink();\n\tdelete rect;\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Merge(const tTVPComplexRect & rects)\n{\n\t// Merge non-overlaped complex rectangle\n\n\t// Calculate bounding rectangle\n\t(const_cast<tTVPComplexRect *>(&rects))->EnsureBound();\n\tEnsureBound();\n\tif(Count)\n\t{\n\t\tif(rects.Count)\n\t\t\tBound.do_union(rects.Bound);\n\t\telse\n\t\t\t; // do nothing\n\t}\n\telse\n\t{\n\t\tif(rects.Count)\n\t\t\tBound = rects.Bound;\n\t\telse\n\t\t\treturn; // both empty; do nothing\n\t}\n\n\t// merge per a rectangle\n\ttTVPRegionRect * ref_cur = rects.Head;\n\tdo\n\t{\n\t\tInsert(*ref_cur);\n\t\tref_cur = ref_cur->Next;\n\t} while(ref_cur != rects.Head);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Or(const tTVPRect &r)\n{\n\t// OR operation\n\n\t// empty check\n\tif(r.is_empty()) return;\n\n\t// simply insert when no rectangle exists\n\tif(Count == 0)\n\t{\n\t\tif(Insert(r))\n\t\t\tBound = r, BoundValid = true;\n\t\treturn;\n\t}\n\n\t// Check for bounding rectangle\n\tEnsureBound();\n\tif(!Bound.intersects_with_no_empty_check(r))\n\t{\n\t\t// Out of the Bouding rectangle; Simply insert\n\t\tif(Insert(r))\n\t\t\tBound.do_union(r);\n\t\treturn;\n\t}\n\n\t// Check for null rectangle\n\tif(r.left >= r.right || r.top >= r.bottom) return; // null rect\n\n\t// Update bounding rectangle\n\tBound.do_union(r);\n\n\t// Walk through rectangles\n\ttTVPRegionRect *c = Head;\n\twhile(c->top < r.bottom)\n\t{\n\t\t// Check inclusion\n\t\tif(r.included_in_no_empty_check(*c))\n\t\t{\n\t\t\t// r is completely included in c\n\t\t\treturn; //---                         returns here\n\t\t}\n\n\t\t// Check intersection\n\t\tbool next_is_head;\n\t\tif(c->intersects_with_no_empty_check(r))\n\t\t{\n\t\t\t// Do OR operation. This may increase the rectangle count.\n\t\t\ttTVPRegionRect *next = c->Next;\n\t\t\tnext_is_head = next == Head;\n\t\t\tCurrent = c;\n\t\t\tRectangleSub(c, &r);\n\t\t\tc = next_is_head ? Head : next;\n\t\t\t\t// Re-assign head since the \"Head\" may change in \"RectangleSub\"\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Step next\n\t\t\tc = c->Next;\n\t\t\tnext_is_head = c == Head;\n\t\t}\n\n\t\tif(!Head || !c || next_is_head) break;\n\t}\n\n\t// finally insert r\n\tInsert(r);\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Or(const tTVPComplexRect &ref)\n{\n\t// OR operation\n\tif(ref.Count == 0) return; // nothing to do\n\n\tEnsureBound();\n\t(const_cast<tTVPComplexRect *>(&ref))->EnsureBound();\n\tif(!Bound.intersects_with_no_empty_check(ref.Bound))\n\t{\n\t\t// Out of the Bouding rectangle; Simply marge\n\t\tMerge(ref);\n\t\treturn;\n\t}\n\n\ttTVPRegionRect *c = ref.Head;\n\twhile(true)\n\t{\n\t\tOr(*c);\n\t\tc = c->Next;\n\t\tif(c == ref.Head) break;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Sub(const tTVPRect &r)\n{\n\t// Subtraction operation\n\n\t// Check for null rectangle\n\tif(r.left >= r.right || r.top >= r.bottom) return; // null rect\n\n\t// check bounding rectangle\n\tEnsureBound();\n\tif(!Bound.intersects_with_no_empty_check(r))\n\t{\n\t\t// Out of the Bouding rectangle; nothing to do\n\t\treturn;\n\t}\n\n\tswitch(GetRectangleIntersectionCode(Bound, r))\n\t{\n\tcase 8 + 4 + 2 + 1: // r overlaps Bound\n\t\tClear(); // nothing remains\n\t\treturn;\n\tcase 8 + 4 + 2: // r overlaps upper of Bound\n\t\tBound.top = r.bottom;\n\t\tbreak;\n\tcase 4 + 2 + 1: // r overlaps right of Bound\n\t\tBound.right = r.left;\n\t\tbreak;\n\tcase 8 + 4 + 1: // r overlaps bottom of Bound\n\t\tBound.bottom = r.top;\n\t\tbreak;\n\tcase 8 + 2 + 1: // r overlaps left of Bound\n\t\tBound.left = r.right;\n\t\tbreak;\n\t}\n\n\t// Walk through rectangles\n\ttTVPRegionRect *c = Head;\n\twhile(c->top < r.bottom)\n\t{\n\t\t// Check intersection\n\t\tbool next_is_head;\n\t\tif(c->intersects_with_no_empty_check(r))\n\t\t{\n\t\t\t// check bounding rectangle\n\t\t\tif(c->left == Bound.left ||\n\t\t\t\tc->top == Bound.top ||\n\t\t\t\tc->right == Bound.top ||\n\t\t\t\tc->bottom == Bound.bottom)\n\t\t\t{\n\t\t\t\t// one of the rectangle edge touches bounding rectangle\n\t\t\t\tBoundValid = false; // invalidate bounding rectangle\n\t\t\t}\n\n\t\t\t// Do Subtract operation. This may increase the rectangle count.\n\t\t\ttTVPRegionRect *next = c->Next;\n\t\t\tnext_is_head = next == Head;\n\t\t\tCurrent = c;\n\t\t\tRectangleSub(c, &r);\n\t\t\tc = next_is_head ? Head : next;\n\t\t\t\t// Re-assign head since the \"Head\" may change in \"RectangleSub\"\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Step next\n\t\t\tc = c->Next;\n\t\t\tnext_is_head = c == Head;\n\t\t}\n\n\t\tif(!Head || !c || next_is_head) break;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::Sub(const tTVPComplexRect &ref)\n{\n\t// Subtract operation\n\tif(ref.Count == 0) return; // nothing to do\n\n\t// check bounding rectangle\n\tEnsureBound();\n\t(const_cast<tTVPComplexRect *>(&ref))->EnsureBound();\n\tif(!Bound.intersects_with_no_empty_check(ref.Bound))\n\t{\n\t\t// Out of the Bouding rectangle; nothing to do\n\t\treturn;\n\t}\n\n\ttTVPRegionRect *c = ref.Head;\n\tbool boundvalid = true;\n\twhile(true)\n\t{\n\t\t// subtract a rectangle\n\t\tSub(*c);\n\n\t\t// check bounding rectangle validity\n\t\tboundvalid = BoundValid && boundvalid;\n\t\tBoundValid = true; // force validate bounding rectangle not to recalculate it.\n\n\t\t// step next\n\t\tc = c->Next;\n\t\tif(c == ref.Head) break;\n\t}\n\n\tBoundValid = boundvalid;\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::And(const tTVPRect &r)\n{\n\t// Do \"logical and\" operation\n\tif(Count == 0) return; // nothing to do\n\n\t// Check for null rectangle\n\tif(r.left >= r.right || r.top >= r.bottom)\n\t{\n\t\tClear(); // null rectangle; nothing remains\n\t\treturn;\n\t}\n\n\t// check bounding rectangle\n\tEnsureBound();\n\tif(!Bound.intersects_with_no_empty_check(r))\n\t{\n\t\t// Out of the Bouding rectangle; nothing remains\n\t\tClear();\n\t\treturn;\n\t}\n\n\tswitch(GetRectangleIntersectionCode(Bound, r))\n\t{\n\tcase 8 + 4 + 2 + 1: // r overlaps Bound\n\t\t// nothing to do\n\t\treturn;\n\t}\n\n\tbool is_first = true;\n\tbool next_is_head;\n\ttTVPRegionRect * c = Head, *cc;\n\twhile(true)\n\t{\n\t\tc = (cc = c)->Next;\n\t\tnext_is_head = c == Head;\n\t\tif(cc->clip(r)) // clip with r\n\t\t{\n\t\t\tif(is_first)\n\t\t\t\tBound = *cc, is_first = false;\n\t\t\telse\n\t\t\t\tBound.do_union(*cc);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tRemove(cc);\n\t\t}\n\n\t\tif(next_is_head) break;\n\t}\n\n\tif(is_first)\n\t\tBoundValid = false; // Nothing remains\n\telse\n\t\tBoundValid = true;\n\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::CopyWithOffsets(const tTVPComplexRect &ref, const tTVPRect &clip,\n\ttjs_int ofsx, tjs_int ofsy)\n{\n\t// Copy \"ref\" to this.\n\t// \"ref\" is to be added offsets, and is to be done logical-and with the \"clip\",\n\t// Note that this function must be called immediately after the construction or\n\t// the \"Clear\" function (This function never clears the rectangles).\n\n\t// copy rectangles\n\tif(ref.Count)\n\t{\n\t\ttTVPRegionRect * ref_cur = ref.Head;\n\t\tbool is_first = true;\n\t\tdo\n\t\t{\n\t\t\ttTVPRect rect(*ref_cur);\n\t\t\trect.add_offsets(ofsx, ofsy);\n\t\t\tif(TVPIntersectRect(&rect, rect, clip))\n\t\t\t{\n\t\t\t\t// has intersection\n\t\t\t\tInsert(rect);\n\t\t\t\tif(is_first)\n\t\t\t\t\tBound = rect, is_first = false;\n\t\t\t\telse\n\t\t\t\t\tBound.do_union(rect);\n\t\t\t}\n\t\t\tref_cur = ref_cur->Next;\n\t\t} while(ref_cur != ref.Head);\n\n\t\tif(is_first)\n\t\t\tBoundValid = false; // Nothing remains\n\t\telse\n\t\t\tBoundValid = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::AddOffsets(tjs_int x, tjs_int y)\n{\n\t// Add offsets to rectangles\n\tif(Count == 0) return; // nothing to do\n\n\t// for bounding rectangle\n\tBound.add_offsets(x, y);\n\n\t// process per a rectangle\n\ttTVPRegionRect * cur = Head;\n\tdo\n\t{\n\t\tcur->add_offsets(x, y);\n\t\tcur = cur->Next;\n\t} while(cur != Head);\n}\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::CalcBound()\n{\n\t// Calculate bounding rectangle\n\tif(Count)\n\t{\n\t\ttTVPRegionRect * c = Head;\n\t\tBound = *Head;\n\t\tc = c->Next;\n\t\twhile(c != Head)\n\t\t{\n\t\t\tBound.do_union(*c);\n\t\t\tc = c->Next;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// no rectangles; bounding rectangle is not valid\n\t\tBound.left = Bound.top = Bound.right = Bound.bottom = 0;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::RectangleSub(tTVPRegionRect *r, const tTVPRect *rr)\n{\n\t// Subtract rr from r\n\ttjs_int cond = GetRectangleIntersectionCode(*r, *rr);\n\n\ttTVPRect nr;\n\tswitch(cond)\n\t{\n//--------------------------------------------------\n\tcase 0:\n/*\n     +-----------+     \n\t |     r     |\n\t +---+---+---+\n     |nr2|rr |nr3|     \n     +---+---+---+     \n     |    nr4    |     \n\t +-----------+\n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = rr->left;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr3\n\t\tnr.left    = rr->right;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr4\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 4 + 2 + 1:\n/*\n+---------------------+\n|                     |\n|                     |\n|                     |\n|                     |\n|         rr          |\n|                     |\n|                     |\n|                     |\n|                     |\n+---------------------+\n*/\n\t\tRemove(r);\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 4:\n/*\n     +-----------+     \n\t |     r     |\n+----+-----------+----+\n|         rr          |\n+----+-----------+----+\n     |    nr2    |     \n     +-----------+     \n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 1 + 2:\n/*\n         +---+         \n         |   |         \n     +---+   +---+     \n     |   |   |   |     \n     |   |   |   |     \n\t | r |rr |nr2|\n     |   |   |   |     \n     |   |   |   |     \n     +---+   +---+     \n         |   |         \n         +---+         \n*/\n\t\t// nr2\n\t\tnr.left    = rr->right;\n\t\tnr.top     = r->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->right   = rr->left;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 2:\n/*\n+------+               \n|      |               \n|      +---------+     \n|  rr  |         |     \n|      |   nr1   |     \n|      |         |     \n+----+-+---------+     \n     |     nr2   |     \n     +-----------+     \n*/\n\t\t// nr1\n\t\tnr.left    = rr->right;\n\t\tnr.top     = r->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\tRemove(r);\n\t\tbreak;\n//--------------------------------------------------\n\tcase 4 + 2:\n/*\n               +------+\n               |      |\n     +---------+      |\n     |         |  rr  |\n\t |    r    |      |\n     |         |      |\n     +---------+-+----+\n     |   nr2     |     \n     +-----------+     \n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->bottom;\n\t\tr->right   = rr->left;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 4 + 1:\n/*\n\t +-----------+\n\t |     r     |\n\t +---------+-+----+\n\t |         |      |\n\t |    nr2  |      |\n\t |         |  rr  |\n\t +---------+      |\n\t\t\t   |      |\n\t\t\t   +------+\n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = rr->left;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 1:\n/*\n     +-----------+     \n\t |      r    |\n+----+-+---------+     \n|      |         |     \n|      |   nr2   |     \n|  rr  |         |     \n|      +---------+     \n|      |               \n+------+               \n*/\n\t\t// nr2\n\t\tnr.left    = rr->right;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 4 + 2:\n/*\n+---------------------+\n|                     |\n|                     |\n|          rr         |\n|                     |\n|                     |\n+----+-----------+----+\n\t |     nr    |\n\t +-----------+\n*/\n\t\t// nr\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\tRemove(r);\n\t\tbreak;\n//--------------------------------------------------\n\tcase 4 + 2 + 1:\n/*\n\t\t +------------+\n\t\t |            |\n\t +---+            |\n\t |   |            |\n\t |   |            |\n\t | r |     rr     |\n\t |   |            |\n\t |   |            |\n\t +---+            |\n\t\t |            |\n\t\t +------------+\n*/\n\t\t// r\n\t\tr->right   = rr->left;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 4 + 1:\n/*\n\t +-----------+\n\t |     r     |\n+----+-----------+----+\n|                     |\n|                     |\n|          rr         |\n|                     |\n|                     |\n+---------------------+\n*/\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8 + 2 + 1:\n/*\n+------------+         \n|            |         \n|            +---+     \n|            |   |     \n|            |   |     \n|    rr      |nr |     \n|            |   |     \n|            |   |     \n|            +---+     \n|            |         \n+------------+         \n*/\n\t\t// nr\n\t\tnr.left    = rr->right;\n\t\tnr.top     = r->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\tRemove(r);\n\t\tbreak;\n//--------------------------------------------------\n\tcase 8:\n/*\n     +-----------+     \n\t |      r    |\n+----+-+---------+     \n|  rr  |   nr2   |     \n+----+-+---------+     \n     |     nr3   |     \n     +-----------+     \n*/\n\t\t// nr2\n\t\tnr.left    = rr->right;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr3\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 4:\n/*\n     +-----------+     \n\t |    r      |\n\t +---------+-+----+\n     |   nr2   |  rr  |\n     +---------+-+----+\n     |   nr3     |     \n     +-----------+     \n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = rr->left;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr3\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 2:\n/*\n         +---+         \n         |   |         \n     +---+ rr+---+     \n\t | r |   |nr2|\n     +---+---+---+     \n     |           |     \n     |    nr3    |     \n     |           |     \n     +-----------+     \n*/\n\t\t// nr2\n\t\tnr.left    = rr->right;\n\t\tnr.top     = r->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = rr->bottom;\n\t\tInsert(nr);\n\t\t// nr3\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->bottom;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->right   = rr->left;\n\t\tr->bottom  = rr->bottom;\n\n\t\tbreak;\n//--------------------------------------------------\n\tcase 1:\n/*\n     +-----------+     \n     |           |     \n\t |     r     |\n     |           |     \n     +---+---+---+     \n     |nr2|   |nr3|     \n     +---+rr +---+     \n         |   |         \n         +---+         \n*/\n\t\t// nr2\n\t\tnr.left    = r->left;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = rr->left;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\t\t// nr3\n\t\tnr.left    = rr->right;\n\t\tnr.top     = rr->top;\n\t\tnr.right   = r->right;\n\t\tnr.bottom  = r->bottom;\n\t\tInsert(nr);\n\n\t\t// r\n\t\tr->bottom  = rr->top;\n\n\t\tbreak;\n\n\tdefault:\n\t\treturn  ;\n\t}\n\n}\n//---------------------------------------------------------------------------\n\nnamespace TJS {\n\tvoid TVPConsoleLog(const tjs_char *l);\n}\n#define OutputDebugString TVPConsoleLog\n//---------------------------------------------------------------------------\nvoid tTVPComplexRect::DumpChain()\n{\n\tttstr str;\n\ttIterator it = GetIterator();\n\twhile(it.Step()) {\n\t\ttjs_char tmp[200];\n\t\tTJS_snprintf(tmp, 200, TJS_W(\"%p (%p) %p : \"), it.Get().Prev, &(it.Get()), it.Get().Next);\n\t\tstr += tmp;\n\t}\n\tOutputDebugString(str.c_str());\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/ComplexRect.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Complex Rectangle Class\n//---------------------------------------------------------------------------\n\n#ifndef ComplexRectUnitH\n#define ComplexRectUnitH\n\n#include <stdlib.h>\n#include \"tjsTypes.h\"\n\n//---------------------------------------------------------------------------\n// tTVPRect - intersection and union\n//---------------------------------------------------------------------------\nstruct tTVPRect;\nextern bool TVPIntersectRect(tTVPRect *dest, const tTVPRect &src1,\n\tconst tTVPRect &src2);\nextern bool TVPUnionRect(tTVPRect *dest, const tTVPRect &src1, const tTVPRect &src2);\n//---------------------------------------------------------------------------\n\n\n/*[*/\n\n//---------------------------------------------------------------------------\n// tTVPRect - simple rectangle structure\n//---------------------------------------------------------------------------\n#pragma pack(push, 4)\nstruct tTVPPoint\n{\n\ttjs_int x;\n\ttjs_int y;\n};\n#pragma pack(pop)\n//---------------------------------------------------------------------------\nstruct tTVPPointD\n{\n\tdouble x;\n\tdouble y;\n};\n//---------------------------------------------------------------------------\nstruct tTVPRect\n{\n\ttTVPRect(tjs_int l, tjs_int t, tjs_int r, tjs_int b)\n\t\t{ left = l, top = t, right = r, bottom =b; }\n\n\ttTVPRect() {};\n\n\tunion\n\t{\n\t\tstruct\n\t\t{\n\t\t\ttjs_int left;\n\t\t\ttjs_int top;\n\t\t\ttjs_int right;\n\t\t\ttjs_int bottom;\n\t\t};\n\n\t\tstruct\n\t\t{\n\t\t\t// capital style\n\t\t\ttjs_int Left;\n\t\t\ttjs_int Top;\n\t\t\ttjs_int Right;\n\t\t\ttjs_int Bottom;\n\t\t};\n\n\t\tstruct\n\t\t{\n\t\t\ttTVPPoint upper_left;\n\t\t\ttTVPPoint bottom_right;\n\t\t};\n\n\t\ttjs_int array[4];\n\t};\n\n\ttjs_int get_width() const { return right - left; }\n\ttjs_int get_height() const { return bottom - top; }\n\n\tvoid set_width(tjs_int w) { right = left + w; }\n\tvoid set_height(tjs_int h) { bottom = top + h; }\n\n\tvoid add_offsets(tjs_int x, tjs_int y)\n\t{\n\t\tleft += x; right += x;\n\t\ttop += y; bottom += y;\n\t}\n\n\tvoid set_offsets(tjs_int x, tjs_int y)\n\t{\n\t\ttjs_int w = get_width();\n\t\ttjs_int h = get_height();\n\t\tleft = x;\n\t\ttop = y;\n\t\tright = x + w;\n\t\tbottom = y + h;\n\t}\n\n\tvoid set_size(tjs_int w, tjs_int h)\n\t{\n\t\tright = left + w;\n\t\tbottom = top + h;\n\t}\n\n\tvoid clear()\n\t{\n\t\tleft = top = right = bottom = 0;\n\t}\n\n\tbool is_empty() const\n\t{\n\t\treturn left >= right || top >= bottom;\n\t}\n\n\tbool do_union(const tTVPRect & ref)\n\t{\n\t\tif(ref.is_empty()) return false;\n\t\tif(left > ref.left) left = ref.left;\n\t\tif(top > ref.top) top = ref.top;\n\t\tif(right < ref.right) right = ref.right;\n\t\tif(bottom < ref.bottom) bottom = ref.bottom;\n\t\treturn true;\n\t}\n#ifndef __TP_STUB_H__\n\tbool clip(const tTVPRect &ref)\n\t{\n\t\t// Clip (take the intersection of) the rectangle with rectangle. \n\t\t// returns whether the rectangle remains.\n\t\treturn TVPIntersectRect(this, *this, ref);\n\t}\n#endif\n\tbool intersects_with_no_empty_check(const tTVPRect & ref) const\n\t{\n\t\t// returns wether this has intersection with \"ref\"\n\t\treturn !(\n\t\t\tleft >= ref.right ||\n\t\t\ttop >= ref.bottom ||\n\t\t\tright <= ref.left ||\n\t\t\tbottom <= ref.top );\n\t}\n\n\tbool intersects_with(const tTVPRect & ref) const\n\t{\n\t\t// returns wether this has intersection with \"ref\"\n\t\tif(ref.is_empty() || is_empty()) return false;\n\t\treturn intersects_with_no_empty_check(ref);\n\t}\n\n\tbool included_in_no_empty_check(const tTVPRect & ref) const\n\t{\n\t\t// returns wether this is included in \"ref\"\n\t\treturn\n\t\t\tref.left <= left &&\n\t\t\tref.top <= top &&\n\t\t\tref.right >= right &&\n\t\t\tref.bottom >= bottom;\n\t}\n\n\tbool included_in(const tTVPRect & ref) const\n\t{\n\t\t// returns wether this is included in \"ref\"\n\t\tif(ref.is_empty() || is_empty()) return false;\n\t\treturn included_in_no_empty_check(ref);\n\t}\n\npublic: // comparison operators for sorting\n\tbool operator < (const tTVPRect & rhs) const\n\t\t{ return top < rhs.top || (top == rhs.top && left < rhs.left); }\n\tbool operator > (const tTVPRect & rhs) const\n\t\t{ return top > rhs.top || (top == rhs.top && left > rhs.left); }\n\n\t// comparison methods\n\tbool operator == (const tTVPRect & rhs) const\n\t\t{ return top == rhs.top && left == rhs.left && right == rhs.right && bottom == rhs.bottom; }\n\tbool operator != (const tTVPRect & rhs) const { return !this->operator ==(rhs); }\n};\n//---------------------------------------------------------------------------\n\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// tTVPRegionRect : a class for a rectangle in region\n//---------------------------------------------------------------------------\nclass tTVPRegionRect;\nextern tTVPRegionRect * TVPAllocateRegionRect();\nextern void TVPDeallocateRegionRect(tTVPRegionRect * rect);\n//---------------------------------------------------------------------------\nclass tTVPRegionRect : public tTVPRect\n{\npublic: // data members\n\ttTVPRegionRect * Prev; // previous link\n\ttTVPRegionRect * Next; // next link\n\npublic: // new and delete\n\tvoid * operator new (size_t size) { return TVPAllocateRegionRect(); }\n\tvoid operator delete (void * p) { TVPDeallocateRegionRect((tTVPRegionRect*)p); }\n\npublic: // constructors and destructor\n\ttTVPRegionRect() {;};\n\ttTVPRegionRect(const tTVPRect &r) : tTVPRect(r) {;};\n\t~tTVPRegionRect() {;};\n\npublic: // link operations\n\tvoid LinkAfter(tTVPRegionRect * r)\n\t{\n\t\t// Insert this after r.\n\t\ttTVPRegionRect * n = r->Next;\n\t\tr->Next = this;\n\t\tn->Prev = this;\n\t\tPrev = r;\n\t\tNext = n;\n\t}\n\n\tvoid LinkBefore(tTVPRegionRect * r)\n\t{\n\t\t// Insert this before r.\n\t\ttTVPRegionRect * p = r->Prev;\n\t\tr->Prev = this;\n\t\tp->Next = this;\n\t\tPrev = p;\n\t\tNext = r;\n\t}\n\n\tvoid Unlink()\n\t{\n\t\t// unchain from the link list\n\t\ttTVPRegionRect *prev = Prev;\n\t\ttTVPRegionRect *next = Next;\n\t\tprev->Next = next;\n\t\tnext->Prev = prev;\n\t}\n\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPComplexRect\n//---------------------------------------------------------------------------\nclass tTVPComplexRect\n{\npublic: // iterator\n\tclass tIterator\n\t{\n\tprivate: // data members\n\t\tconst tTVPRegionRect * Head;\n\t\tconst tTVPRegionRect * Current;\n\n\tpublic: // constructor and destructor\n\t\ttIterator() : Head(NULL), Current(NULL) {;}\n\t\ttIterator(const tTVPRegionRect * head) : Head(head), Current(NULL) {;}\n\n\tpublic: // operator function (data access)\n\t\tconst tTVPRect & operator * () const { return *Current; }\n\t\tconst tTVPRect * operator -> () const { return Current; }\n\n\t\tconst tTVPRegionRect & Get() const { return *Current; }\n\n\tpublic: // stepping forward; this object supports only forward step.\n\t\t\t// method step returns true if stepping successful,\n\t\t\t// otherwise returns false (when already at last of the list)\n\t\t\t// sample:\n\t\t\t//   tTVPComplexRect::tIterator it = rects.GetIterator();\n\t\t\t//   while(it.Step()) { .. do something with it .. }\n\t\tbool Step()\n\t\t{\n\t\t\t// Step forward\n\t\t\tif(!Head) return false;\n\t\t\tif(!Current) { Current = Head; return true; }\n\t\t\tif(Current->Next == Head) { return false; }\n\t\t\tCurrent = Current->Next;\n\t\t\treturn true;\n\t\t}\n\t};\n\nprivate: // data members\n\ttTVPRegionRect * Head; // head of the link list\n\ttTVPRegionRect * Current; // a rectangle which is touched last time\n\ttjs_int Count; // rectangle Count\n\ttTVPRect Bound; // bounding rectangle\n\tbool BoundValid; // whether the bounding rectangle is ready to use\n\npublic: // constructors and destructors\n\ttTVPComplexRect();\n\ttTVPComplexRect(const tTVPComplexRect & ref);\n\t~tTVPComplexRect();\n\npublic: // storage management\n\tvoid Clear();\n\nprivate: // storage management\n\tvoid FreeAllRectangles(); // free all rectangles\n\tvoid Init(); // initialize internal states\n\tvoid SetCount(tjs_int count); // grow or shrink rectangle storage area\n\tbool Insert(const tTVPRect & rect); // insert inplace\n\tvoid Remove(tTVPRegionRect * rect); // remove a rectangle\n\tvoid Merge(const tTVPComplexRect & rects); // merge non-overlaped complex rectangle\npublic:\n\ttjs_int GetCount() const { return Count; }\n\npublic: // logical operations\n\tvoid Or(const tTVPRect &r);\n\tvoid Or(const tTVPComplexRect &ref);\n\tvoid Sub(const tTVPRect &r);\n\tvoid Sub(const tTVPComplexRect &ref);\n\tvoid And(const tTVPRect &r);\n\npublic: // operation utilities\n\tvoid CopyWithOffsets(const tTVPComplexRect &ref, const tTVPRect &clip,\n\t\ttjs_int ofsx, tjs_int ofsy); \n\npublic: // bounding rectangle\n\tconst tTVPRect & GetBound() const\n\t\t{ (const_cast<tTVPComplexRect *>(this))->EnsureBound(); return Bound; }\n\n\tvoid Unite()\n\t{\n\t\t// make union (bounding) one rectangle\n\t\ttTVPRect r(GetBound());\n\t\tClear();\n\t\tOr(r);\n\t}\n\nprivate: \n\tvoid EnsureBound() { if(!BoundValid) CalcBound(); }\n\tvoid CalcBound();\n\nprivate: // geometric rectangle operations\n\ttjs_int GetRectangleIntersectionCode(const tTVPRect &r, const tTVPRect &rr)\n\t{\n\t\t// Retrieve condition code which represents\n\t\t// how two rectangles have the intersection.\n\t\ttjs_int cond;\n\t\tif(rr.left   <= r.left   && rr.right   >= r.left   )\n\t\t\tcond =  8; else cond = 0;\n\t\tif(rr.left   <= r.right  && rr.right   >= r.right  )\n\t\t\tcond |= 4;\n\t\tif(rr.top    <= r.top    && rr.bottom  >= r.top    )\n\t\t\tcond |= 2;\n\t\tif(rr.top    <= r.bottom && rr.bottom  >= r.bottom )\n\t\t\tcond |= 1;\n\t\t\t/*\n\t\t\t\t\t   +8             +4\n\n\t\t\t\t\t+------+ +---+ +------+\n\t\t\t\t\t|rr    | |rr | |    rr|     +2\n\t\t\t\t\t|    +-----------+    |\n\t\t\t\t\t+----|-+ +---+ +-|----+\n\t\t\t\t\t+----|-+       +-|----+\n\t\t\t\t\t|rr  | |   r   | |  rr|\n\t\t\t\t\t+----|-+       +-|----+\n\t\t\t\t\t+----|-+ +---+ +-|----+\n\t\t\t\t\t|    +-----------+    |     +1\n\t\t\t\t\t|rr    | | rr| |    rr|\n\t\t\t\t\t+------+ +---+ +------+\n\t\t\t*/\n\t\treturn cond;\n\t}\n\n\tvoid RectangleSub(tTVPRegionRect *r, const tTVPRect *rr);\n\npublic:\n\tvoid AddOffsets(tjs_int x, tjs_int y);\n\npublic: // iterator\n\ttIterator GetIterator() const\n\t\t{ if(Count) return tIterator(Head); else return tIterator(NULL); }\n\npublic: // debug\n\tvoid DumpChain();\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTVPComplexRectIterator : iterator for walking over rectangles\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/FontImpl.cpp",
    "content": "#include \"FontImpl.h\"\n\n// ## fix error: unknown type name 'FT_Library'\n#include \"freetype2/ft2build.h\"\n#include \"freetype2/freetype.h\"\n#include \"freetype2/ftsnames.h\"\n#include \"freetype2/ttnameid.h\"\n// #include FT_TRUETYPE_IDS_H\n// #include FT_SFNT_NAMES_H\n// #include FT_FREETYPE_H\n\n#include \"StorageIntf.h\"\n#include \"DebugIntf.h\"\n#include \"MsgIntf.h\"\n#include <map>\n#include <math.h>\n#include \"Application.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#ifndef M_PI\n#define M_PI       3.14159265358979323846\n#endif\n\n#ifdef _MSC_VER\n#pragma comment(lib,\"freetype.lib\")\n#endif\n#include \"platform/CCFileUtils.h\"\n#include \"StorageImpl.h\"\n#include \"BinaryStream.h\"\n\ntTJSHashTable<ttstr, TVPFontNamePathInfo, tTVPttstrHash>\n    TVPFontNames;\nstatic ttstr TVPDefaultFontName;\nconst ttstr &TVPGetDefaultFontName() {\n\treturn TVPDefaultFontName;\n}\nvoid TVPGetAllFontList(std::vector<ttstr>& list) {\n\tauto itend = TVPFontNames.GetLast();\n\tfor (auto it = TVPFontNames.GetFirst(); it != itend; ++it) {\n\t\tlist.push_back(it.GetKey());\n\t}\n}\nstatic FT_Library TVPFontLibrary;\nFT_Library &TVPGetFontLibrary() {\n\tif (!TVPFontLibrary) {\n\t\tFT_Error error = FT_Init_FreeType(&TVPFontLibrary);\n\t\tif (error) TVPThrowExceptionMessage(\n\t\t\t(ttstr(TJS_W(\"Initialize FreeType failed, error = \")) + TJSIntegerToString((tjs_int)error)).c_str());\n\t\tTVPInitFontNames();\n\t}\n\treturn TVPFontLibrary;\n}\nvoid TVPReleaseFontLibrary() {\n\tif (TVPFontLibrary) {\n\t\tFT_Done_FreeType(TVPFontLibrary);\n\t}\n}\n//---------------------------------------------------------------------------\nstatic int TVPInternalEnumFonts(FT_Byte* pBuf, int buflen, const ttstr &FontPath, const std::function<tTJSBinaryStream*(TVPFontNamePathInfo*)>& getter) {\n\tunsigned int faceCount = 0;\n\tFT_Face fontface;\n\tFT_Error error = FT_New_Memory_Face(\n\t\tTVPGetFontLibrary(),\n\t\tpBuf,\n\t\tbuflen,\n\t\t0,\n\t\t&fontface);\n\tif (error) {\n\t\tTVPAddLog(ttstr(TJS_W(\"Load Font \\\"\") + FontPath + \"\\\" failed (\" + TJSIntegerToString((int)error) + \")\"));\n\t\treturn faceCount;\n\t}\n\tint nFaceNum = fontface->num_faces;\n\tfor (int i = 0; i < nFaceNum; ++i) {\n\t\tif (i > 0) {\n\t\t\tif (FT_New_Memory_Face(\n\t\t\t\tTVPGetFontLibrary(),\n\t\t\t\tpBuf,\n\t\t\t\tbuflen,\n\t\t\t\ti,\n\t\t\t\t&fontface)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (FT_IS_SCALABLE(fontface)) {\n\t\t\tFT_UInt namecount = FT_Get_Sfnt_Name_Count(fontface);\n\t\t\tint addCount = 0;\n\t\t\tfor (FT_UInt i = 0; i < namecount; ++i) {\n\t\t\t\tFT_SfntName name;\n\t\t\t\tif (FT_Get_Sfnt_Name(fontface, i, &name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (name.name_id != TT_NAME_ID_FONT_FAMILY) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (name.platform_id != TT_PLATFORM_MICROSOFT) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tswitch (name.language_id) { // for CJK names\n\t\t\t\tcase TT_MS_LANGID_JAPANESE_JAPAN:\n\t\t\t\tcase TT_MS_LANGID_CHINESE_GENERAL:\n\t\t\t\tcase TT_MS_LANGID_CHINESE_TAIWAN:\n\t\t\t\tcase TT_MS_LANGID_CHINESE_PRC:\n\t\t\t\tcase TT_MS_LANGID_CHINESE_HONG_KONG:\n\t\t\t\tcase TT_MS_LANGID_CHINESE_SINGAPORE:\n\t\t\t\tcase TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA:\n\t\t\t\tcase TT_MS_LANGID_KOREAN_JOHAB_KOREA:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tttstr fontname;\n\t\t\t\tif (name.encoding_id == TT_MS_ID_UNICODE_CS) {\n\t\t\t\t\tstd::vector<tjs_char> tmp;\n\t\t\t\t\tint namelen = name.string_len / 2;\n\t\t\t\t\ttmp.resize(namelen + 1);\n\t\t\t\t\tfor (int j = 0; j < namelen; ++j) {\n\t\t\t\t\t\ttmp[j] = (name.string[j * 2] << 8) | (name.string[j * 2 + 1]);\n\t\t\t\t\t}\n\t\t\t\t\tfontname = &tmp.front();\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tTVPFontNamePathInfo info;\n\t\t\t\tinfo.Path = FontPath;\n\t\t\t\tinfo.Index = i;\n\t\t\t\tinfo.Getter = getter;\n\t\t\t\tTVPFontNames.Add(fontname, info);\n\t\t\t\taddCount = 1;\n\t\t\t}\n\t\t\t/*if (!addCount)*/ {\n\t\t\t\tttstr fontname((tjs_nchar*)fontface->family_name);\n\t\t\t\tTVPFontNamePathInfo info;\n\t\t\t\tinfo.Path = FontPath;\n\t\t\t\tinfo.Index = i;\n\t\t\t\tinfo.Getter = getter;\n\t\t\t\tTVPFontNames.Add(fontname, info);\n\t\t\t}\n\t\t\t++faceCount;\n\t\t}\n\n\t\tFT_Done_Face(fontface);\n\t}\n\treturn faceCount;\n}\n\nint TVPEnumFontsProc(const ttstr &FontPath)\n{\n    if(!TVPIsExistentStorageNoSearch(FontPath)) {\n        return 0;\n    }\n\n    tTJSBinaryStream * Stream = TVPCreateStream(FontPath, TJS_BS_READ);\n    if(!Stream) {\n        return 0;\n    }\n    int bufflen = Stream->GetSize();\n\tstd::vector<FT_Byte> buf; buf.resize(bufflen);\n    Stream->ReadBuffer(&buf.front(), bufflen);\n    delete Stream;\n\treturn TVPInternalEnumFonts(&buf.front(), bufflen, FontPath, nullptr);\n}\n\ntTJSBinaryStream* TVPCreateFontStream(const ttstr &fontname)\n{\n\tTVPFontNamePathInfo *info = TVPFindFont(fontname);\n\tif (!info) {\n\t\tinfo = TVPFontNames.Find(TVPDefaultFontName);\n\t\tif (!info) return nullptr;\n\t}\n\tif (info->Getter) {\n\t\treturn info->Getter(info);\n\t}\n\treturn TVPCreateBinaryStreamForRead(info->Path, TJS_W(\"\"));\n}\n\n//---------------------------------------------------------------------------\n#ifdef __ANDROID__\nextern std::vector<ttstr> Android_GetExternalStoragePath();\nextern ttstr Android_GetInternalStoragePath();\nextern ttstr Android_GetApkStoragePath();\n#endif\nvoid TVPInitFontNames()\n{\n    static bool TVPFontNamesInit = false;\n    // enumlate all fonts\n    if(TVPFontNamesInit) return;\n\tTVPFontNamesInit = true;\n#ifdef __ANDROID__\n\tstd::vector<ttstr> pathlist = Android_GetExternalStoragePath();\n#endif\n\tdo {\n\t\tttstr userFont = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"default_font\", \"\");\n\t\tif (!userFont.IsEmpty() && TVPEnumFontsProc(userFont)) break;\n\n\t\tif (TVPEnumFontsProc(TVPGetAppPath() + \"default.ttf\")) break;\n\t\tif (TVPEnumFontsProc(TVPGetAppPath() + \"default.ttc\")) break;\n\t\tif (TVPEnumFontsProc(TVPGetAppPath() + \"default.otf\")) break;\n\t\tif (TVPEnumFontsProc(TVPGetAppPath() + \"default.otc\")) break;\n#if defined(__ANDROID__)\n\t\tint fontCount = 0;\n\t\tfor (const ttstr &path : pathlist) {\n\t\t\tfontCount += TVPEnumFontsProc(path + \"/default.ttf\");\n\t\t\tif (fontCount) break;\n\t\t}\n\t\tif (fontCount) break;\n\t\t\n\t\tif (TVPEnumFontsProc(Android_GetInternalStoragePath() + \"/default.ttf\")) break;\n\n\t\t{\t// from internal storage\n\t\t\tauto data = cocos2d::FileUtils::getInstance()->getDataFromFile(\"DroidSansFallback.ttf\");\n\t\t\tif (TVPInternalEnumFonts(data.getBytes(), data.getSize(), \"DroidSansFallback.ttf\", [](TVPFontNamePathInfo* info)->tTJSBinaryStream* {\n\t\t\t\tauto data = cocos2d::FileUtils::getInstance()->getDataFromFile(info->Path.AsStdString());\n\t\t\t\ttTVPMemoryStream *ret = new tTVPMemoryStream();\n\t\t\t\tret->WriteBuffer(data.getBytes(), data.getSize());\n\t\t\t\tret->SetPosition(0);\n\t\t\t\treturn ret;\n\t\t\t})) break;\n\t\t}\n\t\tif (TVPEnumFontsProc(TJS_W(\"file://./system/fonts/DroidSansFallback.ttf\"))) break;\n\t\tif (TVPEnumFontsProc(TJS_W(\"file://./system/fonts/NotoSansHans-Regular.otf\"))) break;\n\t\tif (TVPEnumFontsProc(TJS_W(\"file://./system/fonts/DroidSans.ttf\"))) break;\n#elif defined(WIN32)\n\t\tif (TVPEnumFontsProc(TJS_W(\"file://./c/windows/fonts/msyh.ttf\"))) break;\n\t\tif (TVPEnumFontsProc(TJS_W(\"file://./c/windows/fonts/simhei.ttf\"))) break;\n#endif\n        \n        std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(\"DroidSansFallback.ttf\");\n        if (TVPEnumFontsProc(fullPath)) break;\n\t} while (false);\n    if(TVPFontNames.GetCount() > 0)\n    {\n        // set default fontface name\n        TVPDefaultFontName = TVPFontNames.GetLast().GetKey();\n    }\n\n    // check exePath + \"/fonts/*.ttf\"\n\t{\n\t\tstd::vector<ttstr> list;\n\t\tauto lister = [&](const ttstr &name, tTVPLocalFileInfo* s) {\n\t\t\tif (s->Mode & (S_IFREG | S_IFDIR)) {\n\t\t\t\tlist.emplace_back(name);\n\t\t\t}\n\t\t};\n#ifdef __ANDROID__\n\t\tTVPGetLocalFileListAt(Android_GetInternalStoragePath() + \"/fonts\", lister);\n\t\tfor (const ttstr &path : pathlist) {\n\t\t\tTVPGetLocalFileListAt(path + \"/fonts\", lister);\n\t\t}\n#endif\n\t\tTVPGetLocalFileListAt(TVPGetAppPath() + \"/fonts\", lister);\n        auto itend = list.end();\n        for (auto it = list.begin(); it != itend; ++it) {\n            TVPEnumFontsProc(*it);\n        }\n    }\n\n\tif (TVPDefaultFontName.IsEmpty()) {\n\t\tTVPShowSimpleMessageBox((\"Could not found any font.\\nPlease ensure that at least \\\"default.ttf\\\" exists\"), \"Exception Occured\");\n    }\n}\n//---------------------------------------------------------------------------\nTVPFontNamePathInfo* TVPFindFont(const ttstr &fontname)\n{\n    // check existence of font\n    TVPInitFontNames();\n\n\tTVPFontNamePathInfo *info = nullptr;\n\tif (!fontname.IsEmpty() && fontname[0] == TJS_W('@')) { // vertical version\n\t\tinfo = TVPFontNames.Find(fontname.c_str() + 1);\n\t}\n\tif (!info) {\n\t\tinfo = TVPFontNames.Find(fontname);\n\t}\n    return info;\n}\n\ntjs_uint32 tTVPttstrHash::Make( const ttstr &val )\n{\n    const tjs_char * ptr = val.c_str();\n    if(*ptr == 0) return 0;\n    tjs_uint32 v = 0;\n    while(*ptr)\n    {\n        v += *ptr;\n        v += (v << 10);\n        v ^= (v >> 6);\n        ptr++;\n    }\n    v += (v << 3);\n    v ^= (v >> 11);\n    v += (v << 15);\n    if(!v) v = (tjs_uint32)-1;\n    return v;\n}\n"
  },
  {
    "path": "src/core/visual/FontImpl.h",
    "content": "#pragma once\n#include \"tjs.h\"\n#include \"tjsHashSearch.h\"\n#include <functional>\n\nvoid TVPInitFontNames();\nint TVPEnumFontsProc(const ttstr &FontPath);\nconst ttstr &TVPGetDefaultFontName();\ntTJSBinaryStream* TVPCreateFontStream(const ttstr &fontname);\nstruct TVPFontNamePathInfo {\n    ttstr Path;\n\tstd::function<tTJSBinaryStream*(TVPFontNamePathInfo*)> Getter;\n    int Index;\n};\nTVPFontNamePathInfo* TVPFindFont(const ttstr &name);\n\n//---------------------------------------------------------------------------\n// font enumeration and existence check\n//---------------------------------------------------------------------------\nclass tTVPttstrHash\n{\npublic:\n    static tjs_uint32 Make(const ttstr &val);\n};\nextern tTJSHashTable<ttstr, TVPFontNamePathInfo, tTVPttstrHash>\n    TVPFontNames;"
  },
  {
    "path": "src/core/visual/FontRasterizer.h",
    "content": "\n#ifndef __FONT_RASTERIZER_H__\n#define __FONT_RASTERIZER_H__\n\nclass FontRasterizer {\n\npublic:\n\tvirtual ~FontRasterizer() {}\n\tvirtual void AddRef() = 0;\n\tvirtual void Release() = 0;\n\tvirtual void ApplyFont( class tTVPNativeBaseBitmap *bmp, bool force ) = 0;\n\tvirtual void ApplyFont( const struct tTVPFont& font ) = 0;\n\tvirtual void GetTextExtent(tjs_char ch, tjs_int &w, tjs_int &h) = 0;\n\tvirtual tjs_int GetAscentHeight() = 0;\n\tvirtual class tTVPCharacterData* GetBitmap( const struct tTVPFontAndCharacterData & font, tjs_int aofsx, tjs_int aofsy ) = 0;\n\tvirtual void GetGlyphDrawRect( const ttstr & text, struct tTVPRect& area ) = 0;\n};\n\n#endif // __FREE_TYPE_FONT_RASTERIZER_H__\n"
  },
  {
    "path": "src/core/visual/FontSystem.cpp",
    "content": "\n\n#include \"tjsCommHead.h\"\n\n#include \"FontSystem.h\"\n#include \"StringUtil.h\"\n#include \"MsgIntf.h\"\n#include <vector>\n#include \"ConfigManager/IndividualConfigManager.h\"\n\nextern void TVPGetAllFontList(std::vector<ttstr>& list);\nextern const ttstr &TVPGetDefaultFontName();\n\nvoid FontSystem::InitFontNames() {\n\t// enumlate all fonts\n\tif(FontNamesInit) return;\n\n\tstd::vector<ttstr> list;\n\tTVPGetAllFontList( list );\n\tsize_t count = list.size();\n\tfor( size_t i = 0; i < count; i++ ) {\n\t\tAddFont( list[i] );\n\t}\n\n\tFontNamesInit = true;\n}\n//---------------------------------------------------------------------------\nvoid FontSystem::AddFont(const ttstr& name) {\n\tTVPFontNames.Add( name, 1 );\n}\n//---------------------------------------------------------------------------\nbool FontSystem::FontExists(const ttstr &name) {\n\t// check existence of font\n\tInitFontNames();\n\n\tint * t = TVPFontNames.Find(name);\n\treturn t != NULL;\n}\n\nFontSystem::FontSystem() : FontNamesInit(false), DefaultLOGFONTCreated(false) {\n\tConstructDefaultFont();\n}\n\nvoid FontSystem::ConstructDefaultFont() {\n\tif( !DefaultLOGFONTCreated ) {\n\t\tDefaultLOGFONTCreated = true;\n\t\tDefaultFont.Height = -12;\n\t\tDefaultFont.Flags = 0;\n\t\tDefaultFont.Angle = 0;\n\t\tDefaultFont.Face = ttstr(TVPGetDefaultFontName());\n\t}\n}\n\nttstr FontSystem::GetBeingFont(ttstr fonts) {\n\t// retrieve being font in the system.\n\t// font candidates are given by \"fonts\", separated by comma.\n\n\tbool vfont;\n\n\tif(fonts.c_str()[0] == TJS_W('@')) {     // for vertical writing\n\t\tfonts = fonts.c_str() + 1;\n\t\tvfont = true;\n\t} else {\n\t\tvfont = false;\n\t}\n\n\tstatic bool force_default_font = IndividualConfigManager::GetInstance()->GetValue<bool>(\"force_default_font\", false);\n\tif (!force_default_font) {\n\t\tbool prev_empty_name = false;\n\t\twhile (fonts != TJS_W(\"\")) {\n\t\t\tttstr fontname;\n\t\t\tint pos = fonts.IndexOf(TJS_W(\",\"));\n\t\t\tif (pos != -1) {\n\t\t\t\tfontname = Trim(fonts.SubString(0, pos));\n\t\t\t\tfonts = fonts.SubString(pos + 1, -1);\n\t\t\t} else {\n\t\t\t\tfontname = Trim(fonts);\n\t\t\t\tfonts = TJS_W(\"\");\n\t\t\t}\n\n\t\t\t// no existing check if previously specified font candidate is empty\n\t\t\t// eg. \",Fontname\"\n\n\t\t\tif (fontname != TJS_W(\"\") && (prev_empty_name || FontExists(fontname))) {\n\t\t\t\tif (vfont && fontname.c_str()[0] != TJS_W('@')) {\n\t\t\t\t\treturn  TJS_W(\"@\") + fontname;\n\t\t\t\t} else {\n\t\t\t\t\treturn fontname;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprev_empty_name = (fontname == TJS_W(\"\"));\n\t\t}\n\t}\n\n\tif(vfont) {\n\t\treturn ttstr(TJS_W(\"@\")) + TVPGetDefaultFontName();\n\t} else {\n\t\treturn TVPGetDefaultFontName();\n\t}\n}\n"
  },
  {
    "path": "src/core/visual/FontSystem.h",
    "content": "\n#ifndef __FONT_SYSTEM_H__\n#define __FONT_SYSTEM_H__\n\n#include \"tjsCommHead.h\"\n#include \"tvpfontstruc.h\"\n#include \"tjsHashSearch.h\"\n#include <string>\n\nclass tTVPWStringHash {\npublic:\n\tstatic tjs_uint32 Make(const ttstr &val)\n\t{\n\t\tconst tjs_char* ptr = val.c_str();\n\t\tif(*ptr == 0) return 0;\n\t\ttjs_uint32 v = 0;\n\t\twhile(*ptr)\n\t\t{\n\t\t\tv += *ptr;\n\t\t\tv += (v << 10);\n\t\t\tv ^= (v >> 6);\n\t\t\tptr++;\n\t\t}\n\t\tv += (v << 3);\n\t\tv ^= (v >> 11);\n\t\tv += (v << 15);\n\t\tif(!v) v = (tjs_uint32)-1;\n\t\treturn v;\n\t}\n};\n\nclass FontSystem {\n\tbool FontNamesInit;\n\ttTJSHashTable<ttstr, tjs_int, tTVPWStringHash> TVPFontNames;\n\n\ttTVPFont DefaultFont;\n\tbool DefaultLOGFONTCreated;\n\n\tvoid InitFontNames();\n\t//---------------------------------------------------------------------------\n\tvoid AddFont(const ttstr& name);\n\t//---------------------------------------------------------------------------\n\tbool FontExists(const ttstr &name);\n\n\tvoid ConstructDefaultFont();\n\npublic:\n\tFontSystem();\n\tttstr GetBeingFont(ttstr fonts);\n\tconst tTVPFont& GetDefaultFont() const {\n\t\treturn DefaultFont;\n\t}\n};\n\n#endif // __FONT_SYSTEM_H__\n\n"
  },
  {
    "path": "src/core/visual/FreeType.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief FreeType tHghCo\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n#include \"FreeType.h\"\n//#include \"NativeFreeTypeFace.h\"\n//#include \"uni_cp932.h\"\n//#include \"cp932_uni.h\"\n\n#include \"BinaryStream.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"ComplexRect.h\"\n\n#include <algorithm>\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4819)\n#endif\n#include <ft2build.h>\n#include FT_TRUETYPE_UNPATENTED_H\n#include FT_SYNTHESIS_H\n#include FT_BITMAP_H\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n#include \"FontImpl.h\"\n\nextern bool TVPEncodeUTF8ToUTF16(ttstr &output, const std::string &source);\n\n//---------------------------------------------------------------------------\n\nFT_Library FreeTypeLibrary = NULL;\t//!< FreeType Cu\nvoid TVPInitializeFont() {\n\tif( FreeTypeLibrary == NULL ) {\n\t\tFT_Error err = FT_Init_FreeType( &FreeTypeLibrary );\n\t}\n}\nvoid TVPUninitializeFreeFont() {\n\tif( FreeTypeLibrary ) {\n\t\tFT_Done_FreeType( FreeTypeLibrary );\n\t\tFreeTypeLibrary = NULL;\n\t}\n}\n\n//---------------------------------------------------------------------------\n/**\n * t@CVXeoRłFreeType Face NX\n */\nclass tGenericFreeTypeFace : public tBaseFreeTypeFace\n{\nprotected:\n\tFT_Face Face;\t//!< FreeType face IuWFNg\n\ttTJSBinaryStream* File;\t //!< tTJSBinaryStream IuWFNg\n\tstd::vector<ttstr> FaceNames; //!< Face񋓂z\n\nprivate:\n\tFT_StreamRec Stream;\n\npublic:\n\ttGenericFreeTypeFace(const ttstr &fontname, tjs_uint32 options);\n\tvirtual ~tGenericFreeTypeFace();\n\n\tvirtual FT_Face GetFTFace() const;\n\tvirtual void GetFaceNameList(std::vector<ttstr> & dest) const;\n\tvirtual tjs_char GetDefaultChar() const { return L' '; }\n\nprivate:\n\tvoid Clear();\n\tstatic unsigned long IoFunc( FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count );\n\tstatic void CloseFunc( FT_Stream  stream );\n\n\tbool OpenFaceByIndex(tjs_uint index, FT_Face & face);\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * RXgN^\n * @param fontname\ttHg\n * @param options\tIvV(TVP_TF_XXXX 萔TVP_FACE_OPTIONS_XXXX萔̑gݍ킹)\n */\ntGenericFreeTypeFace::tGenericFreeTypeFace(const ttstr &fontname, tjs_uint32 options) : File(NULL)\n{\n\t// tB[h̏\n\tFace = NULL;\n\tmemset(&Stream, 0, sizeof(Stream));\n\n\ttry {\n\t\tif(File) {\n\t\t\tdelete File;\n\t\t\tFile = NULL;\n\t\t} \n\n\t\t// t@CJ\n\t\tFile = TVPCreateFontStream(fontname);\n\t\tif( File == NULL ) {\n\t\t\tTVPThrowExceptionMessage( TVPCannotOpenFontFile, fontname );\n\t\t}\n\n\t\t// FT_StreamRec ̊etB[h𖄂߂\n\t\tFT_StreamRec * fsr = &Stream;\n\t\tfsr->base = 0;\n\t\tfsr->size = static_cast<unsigned long>(File->GetSize());\n\t\tfsr->pos = 0;\n\t\tfsr->descriptor.pointer = this;\n\t\tfsr->pathname.pointer = NULL;\n\t\tfsr->read = IoFunc;\n\t\tfsr->close = CloseFunc;\n\n\t\t// Face ꂼJAFace擾 FaceNames Ɋi[\n\t\ttjs_uint face_num = 1;\n\n\t\tFT_Face face = NULL;\n\n\t\tfor(tjs_uint i = 0; i < face_num; i++)\n\t\t{\n\t\t\tif(!OpenFaceByIndex(i, face))\n\t\t\t{\n\t\t\t\tFaceNames.push_back(ttstr());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst char * name = face->family_name;\n\t\t\t\tttstr wname;\n\t\t\t\tTVPEncodeUTF8ToUTF16( wname, std::string(name) );\n\t\t\t\tFaceNames.push_back( wname );\n\t\t\t\tface_num = face->num_faces;\n\t\t\t}\n\t\t}\n\n\t\tif(face) FT_Done_Face(face), face = NULL;\n\n\n\t\t// FreeType GWŃt@CJƂĂ݂\n\t\ttjs_uint index = TVP_GET_FACE_INDEX_FROM_OPTIONS(options);\n\t\tif(!OpenFaceByIndex(index, Face)) {\n\t\t\t// tHgJȂ\n\t\t\tTVPThrowExceptionMessage(TVPFontCannotBeUsed, fontname );\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * fXgN^\n */\ntGenericFreeTypeFace::~tGenericFreeTypeFace()\n{\n\tif(Face) FT_Done_Face(Face), Face = NULL;\n\tif(File) {\n\t\tdelete File;\n\t\tFile = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * FreeType  Face IuWFNgԂ\n */\nFT_Face tGenericFreeTypeFace::GetFTFace() const\n{\n\treturn Face;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * ̃tHgt@CĂtHgzƂĕԂ\n */\nvoid tGenericFreeTypeFace::GetFaceNameList(std::vector<ttstr> & dest) const\n{\n\tdest = FaceNames;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/**\n * FreeType p Xg[ǂݍ݊֐\n */\nunsigned long tGenericFreeTypeFace::IoFunc( FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count )\n{\n\ttGenericFreeTypeFace * _this =\n\t\tstatic_cast<tGenericFreeTypeFace*>(stream->descriptor.pointer);\n\n\tsize_t result;\n\tif(count == 0)\n\t{\n\t\t// seek\n\t\tresult = 0;\n\t\t_this->File->SetPosition( offset );\n\t}\n\telse\n\t{\n\t\t// read\n\t\t_this->File->SetPosition( offset );\n\t\t_this->File->ReadBuffer(buffer, count);\n\t\tresult = count;\n\t}\n\n\treturn (unsigned long)result;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * FreeType p Xg[폜֐\n */\nvoid tGenericFreeTypeFace::CloseFunc( FT_Stream  stream )\n{\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * wCfbNXFaceJ\n * @param index\tJindex\n * @param face\tFT_Face ϐւ̎Q\n * @return\tFaceJ true łȂ false\n * @note\t߂ Face Jꍇ face Ŏw肷ϐɂ null Ă\n */\nbool tGenericFreeTypeFace::OpenFaceByIndex(tjs_uint index, FT_Face & face)\n{\n\tif(face) FT_Done_Face(face), face = NULL;\n\n\tFT_Parameter parameters[1];\n\tparameters[0].tag = FT_PARAM_TAG_UNPATENTED_HINTING; // Apple̓s\n\tparameters[0].data = NULL;\n\n\tFT_Open_Args args;\n\tmemset(&args, 0, sizeof(args));\n\targs.flags = FT_OPEN_STREAM;\n\targs.stream = &Stream;\n\targs.driver = 0;\n\targs.num_params = 1;\n\targs.params = parameters;\n\n\tFT_Error err = FT_Open_Face( FreeTypeLibrary, &args, index, &face);\n\n\treturn err == 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n/**\n * RXgN^\n * @param fontname\ttHg\n * @param options\tIvV\n */\ntFreeTypeFace::tFreeTypeFace(const ttstr &fontname, tjs_uint32 options)\n\t: FontName(fontname)\n{\n\tTVPInitializeFont();\n\n\t// tB[hNA\n\tFace = NULL;\n\tGlyphIndexToCharcodeVector = NULL;\n\tUnicodeToLocalChar = NULL;\n\tLocalCharToUnicode = NULL;\n\tOptions = options;\n\tHeight = 10;\n\n\n\t// tHgJ\n\t//if(options & TVP_FACE_OPTIONS_FILE)\n\t{\n\t\t// t@CJ\n\t\tFace = new tGenericFreeTypeFace(fontname, options);\n\t\t\t// OŔ\\̂Œ\n\t}\n\t//else\n\t{\n\t\t// lCeBũtHgɂw (vbgtH[ˑ)\n\t\t//Face = new tNativeFreeTypeFace(fontname, options);\n\t\t\t// OŔ\\̂Œ\n\t}\n\tFTFace = Face->GetFTFace();\n\n\t// }bsOmF\n\tif(FTFace->charmap == NULL)\n\t{\n\t\t// FreeType ͎I UNICODE }bsOgp邪A\n\t\t// tHg UNICODE }bsȌ܂łȂꍇ\n\t\t// Iȕ}bsȎI͍sȂB\n\t\t// Ƃ肠({ɌČ) SJIS }bsOĂȂ\n\t\t// tHĝSJISIĂ݂B\n#if 0\n\t\tFT_Error err = FT_Select_Charmap(FTFace, FT_ENCODING_SJIS);\n\t\tif(!err)\n\t\t{\n\t\t\t// SJIS ւ̐؂ւ\n\t\t\t// ϊ֐Zbg\n \t\t\tUnicodeToLocalChar = UnicodeToSJIS;\n \t\t\tLocalCharToUnicode = SJISToUnicode;\n\t\t}\n\t\telse\n#else\n\t\tFT_Error err;\n#endif\n\t\t{\n\t\t\tint numcharmap = FTFace->num_charmaps;\n\t\t\tfor( int i = 0; i < numcharmap; i++ )\n\t\t\t{\n\t\t\t\tFT_Encoding enc = FTFace->charmaps[i]->encoding;\n\t\t\t\tif( enc != FT_ENCODING_NONE && enc != FT_ENCODING_APPLE_ROMAN )\n\t\t\t\t{\n\t\t\t\t\terr = FT_Select_Charmap(FTFace, enc);\n\t\t\t\t\tif(!err) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * fXgN^\n */\ntFreeTypeFace::~tFreeTypeFace()\n{\n\tif(GlyphIndexToCharcodeVector) delete GlyphIndexToCharcodeVector;\n\tif(Face) delete Face;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * FaceێĂglyph̐𓾂\n * @return\tFaceێĂglyph̐\n */\ntjs_uint tFreeTypeFace::GetGlyphCount()\n{\n\tif(!FTFace) return 0;\n\n\t// FreeType ԂĂOt̐́AۂɕR[h蓖ĂĂȂ\n\t// Ot܂񂾐ƂȂĂ\n\t// ŁAۂɃtHgɊ܂܂ĂOt擾\n\t// TODO:Xbhی삳ĂȂ̂ŒӁIIIIII\n\tif(!GlyphIndexToCharcodeVector)\n\t{\n\t\t// }bv쐬ĂȂ̂ō쐬\n\t\tGlyphIndexToCharcodeVector = new tGlyphIndexToCharcodeVector;\n\t\tFT_ULong  charcode;\n\t\tFT_UInt   gindex;\n\t\tcharcode = FT_Get_First_Char( FTFace, &gindex );\n\t\twhile ( gindex != 0 )\n\t\t{\n\t\t\tFT_ULong code;\n\t\t\tif(LocalCharToUnicode)\n\t\t\t\tcode = LocalCharToUnicode(charcode);\n\t\t\telse\n\t\t\t\tcode = charcode;\n\t\t\tGlyphIndexToCharcodeVector->push_back(code);\n\t\t\tcharcode = FT_Get_Next_Char( FTFace, charcode, &gindex );\n\t\t}\n\t\tstd::sort(\n\t\t\tGlyphIndexToCharcodeVector->begin(),\n\t\t\tGlyphIndexToCharcodeVector->end()); // R[hŕёւ\n\t}\n\n\treturn (tjs_uint)GlyphIndexToCharcodeVector->size();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/**\n * Glyph CfbNXΉ镶R[h𓾂\n * @param index\tCfbNX(FreeType̊ǗĂ镶indexƂ͈Ⴄ̂Œ)\n * @return\tΉ镶R[h(ΉR[hꍇ 0)\n */\ntjs_char tFreeTypeFace::GetCharcodeFromGlyphIndex(tjs_uint index)\n{\n\ttjs_uint size = GetGlyphCount(); // Ot𓾂łɃ}bv쐬\n\n\tif(!GlyphIndexToCharcodeVector) return 0;\n\tif(index >= size) return 0;\n\n\treturn static_cast<tjs_char>((*GlyphIndexToCharcodeVector)[index]);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * ̃tHgɊ܂܂FacẽXg𓾂\n * @param dest\ti[z\n */\nvoid tFreeTypeFace::GetFaceNameList(std::vector<ttstr> &dest)\n{\n\tFace->GetFaceNameList(dest);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * tHg̍ݒ肷\n * @param height\ttHg̍(sNZP)\n */\nvoid tFreeTypeFace::SetHeight(int height)\n{\n\tHeight = height;\n\tFT_Error err = FT_Set_Pixel_Sizes(FTFace, 0, Height);\n\tif(err)\n\t{\n\t\t// TODO: Error nhO\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * w肵R[hɑ΂Otrbg}bv𓾂\n * @param code\tR[h\n * @return\tVK쐬ꂽOtrbg}bvIuWFNgւ̃|C^\n *\t\t\tNULL ̏ꍇ͕ϊɎsꍇ\n */\ntTVPCharacterData * tFreeTypeFace::GetGlyphFromCharcode(tjs_char code)\n{\n\t// OtXbgɃOtǂݍ݁A@擾\n\ttGlyphMetrics metrics;\n\tif(!GetGlyphMetricsFromCharcode(code, metrics))\n\t\treturn NULL;\n\n\t// _O\n\tFT_Error err;\n\n\tif(FTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)\n\t{\n\t\tFT_Render_Mode mode;\n\t\tif(!(Options & TVP_FACE_OPTIONS_NO_ANTIALIASING))\n\t\t\tmode = FT_RENDER_MODE_NORMAL;\n\t\telse\n\t\t\tmode = FT_RENDER_MODE_MONO;\n\t\terr = FT_Render_Glyph(FTFace->glyph, mode);\n\t\t\t// note: ftHg̃_O[h FT_RENDER_MODE_NORMAL (256FO[XP[)\n\t\t\t//       FT_RENDER_MODE_MONO  1bpp mN[\n\t\tif(err) return NULL;\n\t}\n\n\t// ꉞrbg}bv``FbN\n\tFT_Bitmap *ft_bmp = &(FTFace->glyph->bitmap);\n\tFT_Bitmap new_bmp;\n\tbool release_ft_bmp = false;\n\ttTVPCharacterData * glyph_bmp = NULL;\n\ttry\n\t{\n\t\tif(ft_bmp->rows && ft_bmp->width)\n\t\t{\n\t\t\t// rbg}bvTCYĂꍇ\n\t\t\tif(ft_bmp->pixel_mode != ft_pixel_mode_grays)\n\t\t\t{\n\t\t\t\t// ft_pixel_mode_grays ł͂Ȃ̂ ft_pixel_mode_grays `ɕϊ\n\t\t\t\tFT_Bitmap_New(&new_bmp);\n\t\t\t\trelease_ft_bmp = true;\n\t\t\t\tft_bmp = &new_bmp;\n\t\t\t\terr = FT_Bitmap_Convert(FTFace->glyph->library,\n\t\t\t\t\t&(FTFace->glyph->bitmap),\n\t\t\t\t\t&new_bmp, 1);\n\t\t\t\t\t//  tGlyphBitmap `ɕϊۂɃACĝ\n\t\t\t\t\t// Ŏw肷 alignment  1 ł悢\n\t\t\t\tif(err)\n\t\t\t\t{\n\t\t\t\t\tif(release_ft_bmp) FT_Bitmap_Done(FTFace->glyph->library, ft_bmp);\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(ft_bmp->num_grays != 256)\n\t\t\t{\n\t\t\t\t// gray x 256 ł͂Ȃ\n\t\t\t\t// 256 ɂȂ悤ɏZs\n\t\t\t\ttjs_int32 multiply =\n\t\t\t\t\tstatic_cast<tjs_int32>((static_cast<tjs_int32> (1) << 30) - 1) /\n\t\t\t\t\t\t(ft_bmp->num_grays - 1);\n\t\t\t\tfor(tjs_int y = ft_bmp->rows - 1; y >= 0; y--)\n\t\t\t\t{\n\t\t\t\t\tunsigned char * p = ft_bmp->buffer + y * ft_bmp->pitch;\n\t\t\t\t\tfor(tjs_int x = ft_bmp->width - 1; x >= 0; x--)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_int32 v = static_cast<tjs_int32>((*p * multiply)  >> 22);\n\t\t\t\t\t\t*p = static_cast<unsigned char>(v);\n\t\t\t\t\t\tp++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// 64{Ă̂\n\t\tmetrics.CellIncX = FT_PosToInt( metrics.CellIncX );\n\t\tmetrics.CellIncY = FT_PosToInt( metrics.CellIncY );\n\n\t\t// tGlyphBitmap 쐬ĕԂ\n\t\t//int baseline = (int)(FTFace->height + FTFace->descender) * FTFace->size->metrics.y_ppem / FTFace->units_per_EM;\n\t\tint baseline = (int)( FTFace->ascender ) * FTFace->size->metrics.y_ppem / FTFace->units_per_EM;\n\n\t\tglyph_bmp = new tTVPCharacterData(\n\t\t\tft_bmp->buffer,\n\t\t\tft_bmp->pitch,\n\t\t\t  FTFace->glyph->bitmap_left,\n\t\t\t  baseline - FTFace->glyph->bitmap_top,\n\t\t\t  ft_bmp->width,\n\t\t\t  ft_bmp->rows,\n\t\t\tmetrics);\n\t\tglyph_bmp->Gray = 256;\n\n\t\t\n\t\tif( Options & TVP_TF_UNDERLINE ) {\n\t\t\ttjs_int pos = -1, thickness = -1;\n\t\t\tGetUnderline( pos, thickness );\n\t\t\tif( pos >= 0 && thickness > 0 ) {\n\t\t\t\tglyph_bmp->AddHorizontalLine( pos, thickness, 255 );\n\t\t\t}\n\t\t}\n\t\tif( Options & TVP_TF_STRIKEOUT ) {\n\t\t\ttjs_int pos = -1, thickness = -1;\n\t\t\tGetStrikeOut( pos, thickness );\n\t\t\tif( pos >= 0 && thickness > 0 ) {\n\t\t\t\tglyph_bmp->AddHorizontalLine( pos, thickness, 255 );\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(release_ft_bmp) FT_Bitmap_Done(FTFace->glyph->library, ft_bmp);\n\t\tthrow;\n\t}\n\tif(release_ft_bmp) FT_Bitmap_Done(FTFace->glyph->library, ft_bmp);\n\n\treturn glyph_bmp;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * w肵R[hɑ΂`̈𓾂\n * @param code\tR[h\n * @return\t_Ö`ւ̃|C^\n *\t\t\tNULL ̏ꍇ͕ϊɎsꍇ\n */\nbool tFreeTypeFace::GetGlyphRectFromCharcode( tTVPRect& rt, tjs_char code, tjs_int& advancex, tjs_int& advancey )\n{\n\tadvancex = advancey = 0;\n\tif( !LoadGlyphSlotFromCharcode(code) )\n\t\treturn false;\n\n\tint baseline = (int)( FTFace->ascender ) * FTFace->size->metrics.y_ppem / FTFace->units_per_EM;\n\t/*\n\tFT_Render_Glyph Ń_OȂƈȉ̊el͎擾łȂ\n\ttjs_int t = baseline - FTFace->glyph->bitmap_top;\n\ttjs_int l = FTFace->glyph->bitmap_left;\n\ttjs_int w = FTFace->glyph->bitmap.width;\n\ttjs_int h = FTFace->glyph->bitmap.rows;\n\t*/\n\ttjs_int t = baseline - FT_PosToInt( FTFace->glyph->metrics.horiBearingY );\n\ttjs_int l = FT_PosToInt( FTFace->glyph->metrics.horiBearingX );\n\ttjs_int w = FT_PosToInt( FTFace->glyph->metrics.width );\n\ttjs_int h = FT_PosToInt( FTFace->glyph->metrics.height );\n\tadvancex = FT_PosToInt( FTFace->glyph->advance.x );\n\tadvancey = FT_PosToInt( FTFace->glyph->advance.y );\n\trt = tTVPRect(l,t,l+w,t+h);\n\tif( Options & TVP_TF_UNDERLINE ) {\n\t\ttjs_int pos = -1, thickness = -1;\n\t\tGetUnderline( pos, thickness );\n\t\tif( pos >= 0 && thickness > 0 ) {\n\t\t\tif( rt.left > 0 ) rt.left = 0;\n\t\t\tif( rt.right < advancex ) rt.right = advancex;\n\t\t\tif( pos < rt.top ) rt.top = pos;\n\t\t\tif( (pos+thickness) >= rt.bottom ) rt.bottom = pos+thickness+1;\n\n\t\t}\n\t}\n\tif( Options & TVP_TF_STRIKEOUT ) {\n\t\ttjs_int pos = -1, thickness = -1;\n\t\tGetStrikeOut( pos, thickness );\n\t\tif( pos >= 0 && thickness > 0 ) {\n\t\t\tif( rt.left > 0 ) rt.left = 0;\n\t\t\tif( rt.right < advancex ) rt.right = advancex;\n\t\t\tif( pos < rt.top ) rt.top = pos;\n\t\t\tif( (pos+thickness) >= rt.bottom ) rt.bottom = pos+thickness+1;\n\t\t}\n\t}\n\treturn true;\n}\n\n//---------------------------------------------------------------------------\n/**\n * w肵R[hɑ΂Ot̐@𓾂(i߂邽߂̃TCY)\n * @param code\t\tR[h\n * @param metrics\t@\n * @return\t̏ꍇ^As̏ꍇU\n */\nbool tFreeTypeFace::GetGlyphMetricsFromCharcode(tjs_char code,\n\ttGlyphMetrics & metrics)\n{\n\tif(!LoadGlyphSlotFromCharcode(code)) return false;\n\n\t// gbN\\̂쐬\n\t// CellIncX  CellIncY  sNZl 64 {ꂽlȂ̂Œ\n\t// ͂Ƃ FreeType ̎dlǂARisałIɂ\n\t// ̐x CellIncX  CellIncY \n\tmetrics.CellIncX =  FTFace->glyph->advance.x;\n\tmetrics.CellIncY =  FTFace->glyph->advance.y;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * w肵R[hɑ΂Ot̃TCY𓾂(̑傫)\n * @param code\t\tR[h\n * @param metrics\tTCY\n * @return\t̏ꍇ^As̏ꍇU\n */\nbool tFreeTypeFace::GetGlyphSizeFromCharcode(tjs_char code, tGlyphMetrics & metrics)\n{\n\tif(!LoadGlyphSlotFromCharcode(code)) return false;\n\n\t// gbN\\̂쐬\n\tmetrics.CellIncX = FT_PosToInt( FTFace->glyph->metrics.horiAdvance );\n\tmetrics.CellIncY = FT_PosToInt( FTFace->glyph->metrics.vertAdvance );\n\n\treturn true;\n}\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * w肵R[hɑ΂OtOtXbgɐݒ肷\n * @param code\tR[h\n * @return\t̏ꍇ^As̏ꍇU\n */\nbool tFreeTypeFace::LoadGlyphSlotFromCharcode(tjs_char code)\n{\n\t// TODO: Xbhی\n\n\t// R[h𓾂\n\tFT_ULong localcode;\n\tif(UnicodeToLocalChar == NULL)\n\t\tlocalcode = code;\n\telse\n\t\tlocalcode = UnicodeToLocalChar(code);\n\n\t// R[h index 𓾂\n\tFT_UInt glyph_index = FT_Get_Char_Index(FTFace, localcode);\n\tif(glyph_index == 0)\n\t\treturn false;\n\n\t// OtXbgɕǂݍ\n\tFT_Int32 load_glyph_flag = 0;\n\tif(!(Options & TVP_FACE_OPTIONS_NO_ANTIALIASING))\n\t\tload_glyph_flag |= FT_LOAD_NO_BITMAP;\n\telse\n\t\tload_glyph_flag |= FT_LOAD_TARGET_MONO;\n\t\t\t// note: rbg}bvtHgǂݍ݂Ȃꍇ FT_LOAD_NO_BITMAP w\n\n\tif(Options & TVP_FACE_OPTIONS_NO_HINTING)\n\t\tload_glyph_flag |= FT_LOAD_NO_HINTING|FT_LOAD_NO_AUTOHINT;\n\tif(Options & TVP_FACE_OPTIONS_FORCE_AUTO_HINTING)\n\t\tload_glyph_flag |= FT_LOAD_FORCE_AUTOHINT;\n\n\tFT_Error err;\n\terr = FT_Load_Glyph(FTFace, glyph_index, load_glyph_flag);\n\n\tif(err) return false;\n\n\t// tHg̕ό`s\n\tif( Options & TVP_TF_BOLD ) FT_GlyphSlot_Embolden(FTFace->glyph);\n\tif( Options & TVP_TF_ITALIC ) FT_GlyphSlot_Oblique( FTFace->glyph );\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\nfloat FT_fixed26p6_to_float(long fixP) {\n\tconst unsigned long fractional_base = 1 << 6;\n\tconst unsigned long fractional_mask = fractional_base - 1;\n\treturn (float)(abs(fixP) & fractional_mask) / fractional_base + (fixP >> 6);\n}\n\nconst FT_Outline* tFreeTypeFace::GetOulineData(tjs_char code, float &w, float &h)\n{\n\tFT_UInt glyph_index = FT_Get_Char_Index(FTFace, code);\n\tif (glyph_index == 0) return GetOulineData(GetDefaultChar(), w, h);\n\tif (FT_Load_Glyph(FTFace, glyph_index, FT_LOAD_DEFAULT)) {\n\t\treturn nullptr;\n\t}\n\tw = FT_fixed26p6_to_float(FTFace->glyph->advance.x);\n\th = FT_fixed26p6_to_float(FTFace->glyph->advance.y);\n\tFT_GlyphSlot pGlyphSlot = FTFace->glyph;\n\treturn &pGlyphSlot->outline;\n}\n"
  },
  {
    "path": "src/core/visual/FreeType.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief FreeType tHghCo\n//---------------------------------------------------------------------------\n#ifndef _FREETYPE_H_\n#define _FREETYPE_H_\n\n\n#include \"CharacterData.h\"\n#include \"FreeTypeFace.h\"\n//#include \"NativeFreeTypeDriver.h\"\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4819)\n#endif\n#include \"freetype2/ft2build.h\"\n#include \"freetype2/freetype.h\"\n// #include FT_FREETYPE_H\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n//---------------------------------------------------------------------------\n#define\tTVP_GET_FACE_INDEX_FROM_OPTIONS(x) ((x) & 0xff) //!< IvVFaceCfbNXo}N\n#define\tTVP_FACE_OPTIONS_FACE_INDEX(x)\t\t((x) & 0xff) //!< FaceCfbNXIvVɕϊ}N\n#define\tTVP_FACE_OPTIONS_FILE\t\t\t\t0x00010000 //!< tHgł͂Ȃăt@CɂtHg̎ws\n#define TVP_FACE_OPTIONS_NO_HINTING\t\t\t0x00020000 //!< qeBOsȂ\n#define TVP_FACE_OPTIONS_FORCE_AUTO_HINTING\t0x00020000 //!< I auto hinting s\n#define TVP_FACE_OPTIONS_NO_ANTIALIASING\t0x00040000 //!< A`GCAXsȂ\n\n//---------------------------------------------------------------------------\n/**\n * FreeType tHg face\n */\nclass tFreeTypeFace\n{\n\tttstr FontName;\t\t//!< tHg\n\ttBaseFreeTypeFace * Face; //!< Face IuWFNg\n\tFT_Face FTFace; //!< FreeType Face IuWFNg\n\ttjs_uint32 Options; //!< tO\n\n\ttypedef std::vector<FT_ULong> tGlyphIndexToCharcodeVector;\n\ttGlyphIndexToCharcodeVector * GlyphIndexToCharcodeVector;\t\t//!< OtCfbNX當R[hւ̕ϊ}bv\n\ttjs_int Height;\t\t//!< tHgTCY() in pixel\n\n\ttjs_uint (*UnicodeToLocalChar)(tjs_char in); //!< SJISȂǂUnicodeɕϊ֐\n\ttjs_char (*LocalCharToUnicode)(tjs_uint in); //!< UnicodeSJISȂǂɕϊ֐\n\n\tstatic inline tjs_int FT_PosToInt( tjs_int x ) { return (((x) + (1 << 5)) >> 6); }\npublic:\n\ttFreeTypeFace(const ttstr &fontname, tjs_uint32 options);\n\t~tFreeTypeFace();\n\n\ttjs_uint GetGlyphCount();\n\ttjs_char GetCharcodeFromGlyphIndex(tjs_uint index);\n\n\tvoid GetFaceNameList(std::vector<ttstr> &dest);\n\n\tconst ttstr& GetFontName() const { return FontName; }\n\n\ttjs_int GetHeight() { return Height; }\n\tvoid SetHeight(int height);\n\n\tvoid SetOption( tjs_uint32 opt ) {\n\t\tOptions |= opt;\n\t}\n\tvoid ClearOption( tjs_uint32 opt ) {\n\t\tOptions &= ~opt;\n\t}\n\tbool GetOption( tjs_uint32 opt ) const {\n\t\treturn (Options&opt) == opt;\n\t}\n\ttjs_char GetDefaultChar() const {\n\t\treturn Face->GetDefaultChar();\n\t}\n\ttjs_char GetFirstChar() {\n\t\tFT_UInt gindex;\n\t\treturn static_cast<tjs_char>( FT_Get_First_Char( FTFace, &gindex ) );\n\t}\n\n\ttjs_int GetAscent() const {\n\t\ttjs_int ppem = FTFace->size->metrics.y_ppem;\n\t\ttjs_int upe = FTFace->units_per_EM;\n\t\treturn FTFace->ascender * ppem / upe;\n\t}\n\tvoid GetUnderline( tjs_int& pos, tjs_int& thickness ) const {\n\t\ttjs_int ppem = FTFace->size->metrics.y_ppem;\n\t\ttjs_int upe = FTFace->units_per_EM;\n\t\ttjs_int liney = 0; //̈ʒu\n\t\ttjs_int height = FT_PosToInt( FTFace->size->metrics.height );\n\t\tliney = ((FTFace->ascender-FTFace->underline_position) * ppem) / upe;\n\t\tthickness = (FTFace->underline_thickness * ppem) / upe;\n\t\tif( thickness < 1 ) thickness = 1;\n\t\tif( liney > height ) {\n\t\t\tliney = height - 1;\n\t\t}\n\t\tpos = liney;\n\t}\n\tvoid GetStrikeOut( tjs_int& pos, tjs_int& thickness ) const {\n\t\ttjs_int ppem = FTFace->size->metrics.y_ppem;\n\t\ttjs_int upe = FTFace->units_per_EM;\n\t\tthickness = FTFace->underline_thickness * ppem / upe;\n\t\tif( thickness < 1 ) thickness = 1;\n\t\tpos = FTFace->ascender * 7 * ppem / (10 * upe);\n\t}\n\ttTVPCharacterData * GetGlyphFromCharcode(tjs_char code);\n\tbool GetGlyphRectFromCharcode(struct tTVPRect& rt, tjs_char code, tjs_int& advancex, tjs_int& advancey );\n\tbool GetGlyphMetricsFromCharcode(tjs_char code, tGlyphMetrics & metrics);\n\tbool GetGlyphSizeFromCharcode(tjs_char code, tGlyphMetrics & metrics);\n\n\tconst FT_Outline* GetOulineData(tjs_char code, float &w, float &h);\n\ttBaseFreeTypeFace *GetBaseFace() { return Face; }\n\nprivate:\n\tbool LoadGlyphSlotFromCharcode(tjs_char code);\n};\n//---------------------------------------------------------------------------\n\n#endif /*_FREETYPE_H_*/\n"
  },
  {
    "path": "src/core/visual/FreeTypeFace.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief FreeType  Face NX̒`\n//---------------------------------------------------------------------------\n\n#ifndef FREETYPEFACE_H\n#define FREETYPEFACE_H\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4819)\n#endif\n#include \"freetype2/ft2build.h\"\n#include \"freetype2/freetype.h\"\n// #include FT_FREETYPE_H\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n#include <vector>\n#include <string>\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * FreeType Face ̊NX\n */\nclass tBaseFreeTypeFace\n{\npublic:\n\tvirtual FT_Face GetFTFace() const = 0; //!< FreeType  Face IuWFNgԂ\n\tvirtual void GetFaceNameList(std::vector<ttstr> & dest) const = 0; //!< ̃tHgt@CĂtHgzƂĕԂ\n\tvirtual ~tBaseFreeTypeFace() {;}\n\tvirtual tjs_char GetDefaultChar() const = 0; //!< `łȂɕ`悷镶R[hԂ\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/visual/FreeTypeFontRasterizer.cpp",
    "content": "\n#include \"FreeTypeFontRasterizer.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"FreeType.h\"\n#ifndef _USE_MATH_DEFINES\n#define _USE_MATH_DEFINES\n#endif\n#include <math.h>\n#include \"MsgIntf.h\"\n#include \"FontSystem.h\"\n#include <complex>\n\nextern void TVPUninitializeFreeFont();\nextern FontSystem* TVPFontSystem;\nextern const ttstr &TVPGetDefaultFontName();\nvoid FreeTypeFontRasterizer::ApplyFallbackFace()\n{\n\tif (!FaceFallback && Face && Face->GetFontName() != TVPGetDefaultFontName()) {\n\t\tFaceFallback = new tFreeTypeFace(TVPGetDefaultFontName(), 0);\n\t}\n\tif (!FaceFallback) return;\n\tFaceFallback->SetHeight(CurrentFont.Height < 0 ? -CurrentFont.Height : CurrentFont.Height);\n\tif (CurrentFont.Flags & TVP_TF_ITALIC) {\n\t\tFaceFallback->SetOption(TVP_TF_ITALIC);\n\t} else {\n\t\tFaceFallback->ClearOption(TVP_TF_ITALIC);\n\t}\n\tif (CurrentFont.Flags & TVP_TF_BOLD) {\n\t\tFaceFallback->SetOption(TVP_TF_BOLD);\n\t} else {\n\t\tFaceFallback->ClearOption(TVP_TF_BOLD);\n\t}\n\tif (CurrentFont.Flags & TVP_TF_UNDERLINE) {\n\t\tFaceFallback->SetOption(TVP_TF_UNDERLINE);\n\t} else {\n\t\tFaceFallback->ClearOption(TVP_TF_UNDERLINE);\n\t}\n\tif (CurrentFont.Flags & TVP_TF_STRIKEOUT) {\n\t\tFaceFallback->SetOption(TVP_TF_STRIKEOUT);\n\t} else {\n\t\tFaceFallback->ClearOption(TVP_TF_STRIKEOUT);\n\t}\n}\n\nFreeTypeFontRasterizer::FreeTypeFontRasterizer() : RefCount(0), Face(NULL), LastBitmap(NULL) {\n\tAddRef();\n}\nFreeTypeFontRasterizer::~FreeTypeFontRasterizer() {\n\tif( Face ) delete Face;\n\tFace = NULL;\n\tif (FaceFallback) {\n\t\tdelete FaceFallback;\n\t\tFaceFallback = nullptr;\n\t}\n\tTVPUninitializeFreeFont();\n}\nvoid FreeTypeFontRasterizer::AddRef() {\n\tRefCount++;\n}\n//---------------------------------------------------------------------------\nvoid FreeTypeFontRasterizer::Release() {\n\tRefCount--;\n\tLastBitmap = NULL;\n\tif( RefCount == 0 ) {\n\t\tif( Face ) delete Face;\n\t\tFace = NULL;\n\t\tif (FaceFallback) {\n\t\t\tdelete FaceFallback;\n\t\t\tFaceFallback = nullptr;\n\t\t}\n\t\tdelete this;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid FreeTypeFontRasterizer::ApplyFont( class tTVPNativeBaseBitmap *bmp, bool force ) {\n\tif( bmp != LastBitmap || force ) {\n\t\tApplyFont( bmp->GetFont() );\n\t\tLastBitmap = bmp;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid FreeTypeFontRasterizer::ApplyFont( const tTVPFont& font ) {\n\tCurrentFont = font;\n\tttstr stdname = TVPFontSystem->GetBeingFont(font.Face);\n\t// TVP_FACE_OPTIONS_NO_ANTIALIASING\n\t// TVP_FACE_OPTIONS_NO_HINTING\n\t// TVP_FACE_OPTIONS_FORCE_AUTO_HINTING\n\ttjs_uint32 opt = 0;\n\topt |= (font.Flags & TVP_TF_ITALIC) ? TVP_TF_ITALIC : 0;\n\topt |= (font.Flags & TVP_TF_BOLD) ? TVP_TF_BOLD : 0;\n\topt |= (font.Flags & TVP_TF_UNDERLINE) ? TVP_TF_UNDERLINE : 0;\n\topt |= (font.Flags & TVP_TF_STRIKEOUT) ? TVP_TF_STRIKEOUT : 0;\n\topt |= (font.Flags & TVP_TF_FONTFILE) ? TVP_FACE_OPTIONS_FILE : 0;\n\tbool recreate = false;\n\tif( Face ) {\n\t\tif( Face->GetFontName() != stdname ) {\n\t\t\tdelete Face;\n\t\t\tFace = new tFreeTypeFace( stdname, opt );\n\t\t\trecreate = true;\n\t\t}\n\t} else {\n\t\tFace = new tFreeTypeFace( stdname, opt );\n\t\trecreate = true;\n\t}\n\tFace->SetHeight( font.Height < 0 ? -font.Height : font.Height );\n\tif( recreate == false ) {\n\t\tif( font.Flags & TVP_TF_ITALIC ) {\n\t\t\tFace->SetOption(TVP_TF_ITALIC);\n\t\t} else {\n\t\t\tFace->ClearOption(TVP_TF_ITALIC);\n\t\t}\n\t\tif( font.Flags & TVP_TF_BOLD ) {\n\t\t\tFace->SetOption(TVP_TF_BOLD);\n\t\t} else {\n\t\t\tFace->ClearOption(TVP_TF_BOLD);\n\t\t}\n\t\tif( font.Flags & TVP_TF_UNDERLINE ) {\n\t\t\tFace->SetOption(TVP_TF_UNDERLINE);\n\t\t} else {\n\t\t\tFace->ClearOption(TVP_TF_UNDERLINE);\n\t\t}\n\t\tif( font.Flags & TVP_TF_STRIKEOUT ) {\n\t\t\tFace->SetOption(TVP_TF_STRIKEOUT);\n\t\t} else {\n\t\t\tFace->ClearOption(TVP_TF_STRIKEOUT);\n\t\t}\n\t}\n\tLastBitmap = NULL;\n}\n//---------------------------------------------------------------------------\nvoid FreeTypeFontRasterizer::GetTextExtent(tjs_char ch, tjs_int &w, tjs_int &h) {\n\tif( Face ) {\n\t\ttGlyphMetrics metrics;\n\t\tif( Face->GetGlyphSizeFromCharcode( ch, metrics) ) {\n\t\t\tw = metrics.CellIncX;\n\t\t\th = metrics.CellIncY;\n\t\t} else {\n\t\t\tw = Face->GetHeight();\n\t\t\th = w;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int FreeTypeFontRasterizer::GetAscentHeight() {\n\tif( Face ) return Face->GetAscent();\n\treturn 0;\n}\nstatic bool isUnicodeSpace(char16_t ch)\n{\n\treturn  (ch >= 0x0009 && ch <= 0x000D) || ch == 0x0020 || ch == 0x0085 || ch == 0x00A0 || ch == 0x1680\n\t\t|| (ch >= 0x2000 && ch <= 0x200A) || ch == 0x2028 || ch == 0x2029 || ch == 0x202F\n\t\t|| ch == 0x205F || ch == 0x3000;\n}\n//---------------------------------------------------------------------------\ntTVPCharacterData* FreeTypeFontRasterizer::GetBitmap( const tTVPFontAndCharacterData & font, tjs_int aofsx, tjs_int aofsy ) {\n\tif( font.Antialiased ) {\n\t\tFace->ClearOption( TVP_FACE_OPTIONS_NO_ANTIALIASING );\n\t} else {\n\t\tFace->SetOption( TVP_FACE_OPTIONS_NO_ANTIALIASING );\n\t}\n\tif( font.Hinting ) {\n\t\tFace->ClearOption( TVP_FACE_OPTIONS_NO_HINTING );\n\t\t//Face->SetOption( TVP_FACE_OPTIONS_FORCE_AUTO_HINTING );\n\t} else {\n\t\tFace->SetOption( TVP_FACE_OPTIONS_NO_HINTING );\n\t\t//Face->ClearOption( TVP_FACE_OPTIONS_FORCE_AUTO_HINTING );\n\t}\n\ttTVPCharacterData* data = Face->GetGlyphFromCharcode(font.Character);\n\tif (!data && !isUnicodeSpace(font.Character)) {\n\t\tApplyFallbackFace();\n\t\tif (FaceFallback) {\n\t\t\tdata = FaceFallback->GetGlyphFromCharcode(font.Character);\n\t\t}\n\t}\n\tif( data == NULL ) {\n\t\tdata = Face->GetGlyphFromCharcode( Face->GetDefaultChar() );\n\t}\n\tif( data == NULL ) {\n\t\tdata = Face->GetGlyphFromCharcode( Face->GetFirstChar() );\n\t}\n\tif( data == NULL ) {\n\t\tTVPThrowExceptionMessage( TVPFontRasterizeError );\n\t}\n\n\tint cx = data->Metrics.CellIncX;\n\tint cy = data->Metrics.CellIncY;\n\tif( font.Font.Angle == 0 ) {\n\t\tdata->Metrics.CellIncX = cx;\n\t\tdata->Metrics.CellIncY = 0;\n\t} else if(font.Font.Angle == 2700) {\n\t\tdata->Metrics.CellIncX = 0;\n\t\tdata->Metrics.CellIncY = cx;\n\t} else {\n\t\tdouble angle = font.Font.Angle * (M_PI/1800);\n\t\tdata->Metrics.CellIncX = static_cast<tjs_int>(  std::cos(angle) * cx);\n\t\tdata->Metrics.CellIncY = static_cast<tjs_int>(- std::sin(angle) * cx);\n\t}\n\n\tdata->Antialiased = font.Antialiased;\n\tdata->FullColored = false;\n\tdata->Blured = font.Blured;\n\tdata->BlurWidth = font.BlurWidth;\n\tdata->BlurLevel = font.BlurLevel;\n\tdata->OriginX += aofsx; // for vertical text\n//\tdata->OriginY += aofsy;\n\n\t// apply blur\n\tif(font.Blured) data->Blur(); // nasty ...\n\treturn data;\n}\n//---------------------------------------------------------------------------\nvoid FreeTypeFontRasterizer::GetGlyphDrawRect( const ttstr & text, tTVPRect& area ) {\n\t// A`GCAXƃqeBO͗Lɂ\n\tFace->ClearOption( TVP_FACE_OPTIONS_NO_ANTIALIASING );\n\tFace->ClearOption( TVP_FACE_OPTIONS_NO_HINTING );\n\n\tarea.left = area.top = area.right = area.bottom = 0;\n\ttjs_int offsetx = 0;\n\ttjs_int offsety = 0;\n\ttjs_uint len = text.length();\n\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\ttjs_char ch = text[i];\n\t\ttjs_int ax, ay;\n\t\ttTVPRect rt(0,0,0,0);\n\t\tbool result = Face->GetGlyphRectFromCharcode(rt,ch,ax,ay);\n\t\tif( result == false ) result = Face->GetGlyphRectFromCharcode(rt,Face->GetDefaultChar(),ax,ay);\n\t\tif( result == false ) result = Face->GetGlyphRectFromCharcode(rt,Face->GetFirstChar(),ax,ay);\n\t\tif( result ) {\n\t\t\trt.add_offsets( offsetx, offsety );\n\t\t\tif( i != 0 ) {\n\t\t\t\tarea.do_union( rt );\n\t\t\t} else {\n\t\t\t\tarea = rt;\n\t\t\t}\n\t\t}\n\t\toffsetx += ax;\n\t\toffsety = 0;\n\t}\n}\n\n"
  },
  {
    "path": "src/core/visual/FreeTypeFontRasterizer.h",
    "content": "\n#ifndef __FREE_TYPE_FONT_RASTERIZER_H__\n#define __FREE_TYPE_FONT_RASTERIZER_H__\n\n#include \"tjsCommHead.h\"\n#include \"CharacterData.h\"\n#include \"FontRasterizer.h\"\n\nclass FreeTypeFontRasterizer : public FontRasterizer {\n\ttjs_int RefCount;\n\tclass tFreeTypeFace* Face; //!< FaceIuWFNg\n\tclass tFreeTypeFace* FaceFallback = nullptr;\n\tclass tTVPNativeBaseBitmap * LastBitmap;\n\ttTVPFont CurrentFont;\n\tvoid ApplyFallbackFace();\n\npublic:\n\tFreeTypeFontRasterizer();\n\tvirtual ~FreeTypeFontRasterizer();\n\tvoid AddRef();\n\tvoid Release();\n\tvoid ApplyFont( class tTVPNativeBaseBitmap *bmp, bool force );\n\tvoid ApplyFont( const struct tTVPFont& font );\n\tvoid GetTextExtent(tjs_char ch, tjs_int &w, tjs_int &h);\n\ttjs_int GetAscentHeight();\n\ttTVPCharacterData* GetBitmap( const tTVPFontAndCharacterData & font, tjs_int aofsx, tjs_int aofsy );\n\tvoid GetGlyphDrawRect( const ttstr & text, struct tTVPRect& area );\n};\n\n#endif // __FREE_TYPE_FONT_RASTERIZER_H__\n"
  },
  {
    "path": "src/core/visual/GraphicsLoadThread.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"BitmapIntf.h\"\n#include \"GraphicsLoadThread.h\"\n#include \"ThreadIntf.h\"\n#include \"NativeEventQueue.h\"\n#include \"UserEvent.h\"\n#include \"EventIntf.h\"\n#include \"StorageIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"MsgIntf.h\"\n#include \"UtilStreams.h\"\n#include \"BitmapBitsAlloc.h\"\n#include \"LayerIntf.h\"\n\ntTVPTmpBitmapImage::tTVPTmpBitmapImage()\n\t: MetaInfo(NULL)\n{}\ntTVPTmpBitmapImage::~tTVPTmpBitmapImage() {\n\tif (bmp) {\n\t\tdelete bmp;\n\t\tbmp = NULL;\n\t}\n\tif( MetaInfo ) {\n\t\tdelete MetaInfo;\n\t\tMetaInfo = NULL;\n\t}\n}\ntTVPImageLoadCommand::tTVPImageLoadCommand() : owner_(NULL), bmp_(NULL), dest_(NULL) {}\ntTVPImageLoadCommand::~tTVPImageLoadCommand() {\n\tif( owner_ ) {\n\t\towner_->Release();\n\t\towner_ = NULL;\n\t}\n\tif( dest_ ) {\n\t\tdelete dest_;\n\t\tdest_ = NULL;\n\t}\n\tbmp_ = NULL;\n}\n\nstatic int TVPLoadGraphicAsync_SizeCallback(void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)\n{\n\ttTVPTmpBitmapImage* img = (tTVPTmpBitmapImage*)callbackdata;\n\tif (!img->bmp) {\n\t\timg->bmp = new tTVPBitmap(w, h, 32);\n\t} else if (img->bmp->GetWidth() != w || img->bmp->GetHeight() != h) {\n\t\timg->bmp->Release();\n\t\timg->bmp = new tTVPBitmap(w, h, 32);\n\t}\n\tswitch (fmt) {\n\tcase gpfLuminance:\n\tcase gpfRGB:\n\t\timg->bmp->IsOpaque = true; break;\n\tcase gpfPalette:\n\tcase gpfRGBA:\n\t\timg->bmp->IsOpaque = false; break;\n\t}\n\treturn img->bmp->GetPitch();\n}\n//---------------------------------------------------------------------------\nstatic void* TVPLoadGraphicAsync_ScanLineCallback(void *callbackdata, tjs_int y)\n{\n\ttTVPTmpBitmapImage* img = (tTVPTmpBitmapImage*)callbackdata;\n\tif( y >= 0 ) {\n\t\tif( y < (tjs_int)img->bmp->GetHeight() ) {\n\t\t\treturn img->bmp->GetScanLine(y);\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\treturn NULL; // -1 ̎̃tbV͉Ȃ\n}\n//---------------------------------------------------------------------------\nstatic void TVPLoadGraphicAsync_MetaInfoPushCallback(void *callbackdata, const ttstr & name, const ttstr & value)\n{\n\ttTVPTmpBitmapImage * img = (tTVPTmpBitmapImage *)callbackdata;\n\n\tif(!img->MetaInfo) img->MetaInfo = new std::vector<tTVPGraphicMetaInfoPair>();\n\timg->MetaInfo->push_back(tTVPGraphicMetaInfoPair(name, value));\n}\n//---------------------------------------------------------------------------\n\ntTVPAsyncImageLoader::tTVPAsyncImageLoader()\n: EventQueue(this,&tTVPAsyncImageLoader::Proc), tTVPThread(true)\n{\n\tEventQueue.Allocate();\n}\ntTVPAsyncImageLoader::~tTVPAsyncImageLoader() {\n\tExitRequest();\n\tWaitFor();\n\tEventQueue.Deallocate();\n\twhile( CommandQueue.size() > 0 ) {\n\t\ttTVPImageLoadCommand* cmd = CommandQueue.front();\n\t\tCommandQueue.pop();\n\t\tdelete cmd;\n\t}\n\twhile( LoadedQueue.size() > 0 ) {\n\t\ttTVPImageLoadCommand* cmd = LoadedQueue.front();\n\t\tLoadedQueue.pop();\n\t\tdelete cmd;\n\t}\n}\nvoid tTVPAsyncImageLoader::ExitRequest() {\n\tTerminate();\n\tPushCommandQueueEvent.Set();\n}\nvoid tTVPAsyncImageLoader::Execute() {\n\t// vCIeB͍Œɂ\n\tSetPriority(ttpIdle);\n\tLoadingThread();\n}\nvoid tTVPAsyncImageLoader::SendToLoadFinish() {\n\tNativeEvent ev(TVP_EV_IMAGE_LOAD_THREAD);\n\tEventQueue.PostEvent(ev);\n}\nvoid tTVPAsyncImageLoader::Proc( NativeEvent& ev )\n{\n\tif(ev.Message != TVP_EV_IMAGE_LOAD_THREAD) {\n\t\tEventQueue.HandlerDefault(ev);\n\t\treturn;\n\t}\n\tHandleLoadedImage();\n}\nvoid tTVPAsyncImageLoader::HandleLoadedImage() {\n\tbool loading;\n\tdo {\n\t\tloading = false;\n\t\ttTVPImageLoadCommand* cmd = NULL;\n\t\t{\n\t\t\ttTJSCriticalSectionHolder cs(ImageQueueCS);\n\t\t\tif( LoadedQueue.size() > 0 ) {\n\t\t\t\tcmd = LoadedQueue.front();\n\t\t\t\tLoadedQueue.pop();\n\t\t\t\tloading = true;\n\t\t\t}\n\t\t}\n\t\tif( cmd != NULL ) {\n\t\t\tcmd->bmp_->SetLoading( false );\n\t\t\tif( cmd->result_.length() > 0 ) {\n\t\t\t\t// error\n\t\t\t\ttTJSVariant param[4];\n\t\t\t\tparam[0] = tTJSVariant((iTJSDispatch2*)NULL,(iTJSDispatch2*)NULL);\n\t\t\t\tparam[1] = 1; // true async\n\t\t\t\tparam[2] = 1; // true error\n\t\t\t\tparam[3] = cmd->result_; // error_mes\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onLoaded\"));\n\t\t\t\tif (cmd->owner_ && cmd->owner_->IsValid(0, NULL, NULL, cmd->owner_) == TJS_S_TRUE) {\n\t\t\t\t\tTVPPostEvent(cmd->owner_, cmd->owner_, eventname, 0, TVP_EPT_IMMEDIATE, 4, param);\n\t\t\t\t}\n\n\t\t\t\tif( cmd->dest_->MetaInfo ) {\n\t\t\t\t\tdelete cmd->dest_->MetaInfo;\n\t\t\t\t\tcmd->dest_->MetaInfo = NULL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tiTJSDispatch2* metainfo = TVPMetaInfoPairsToDictionary(cmd->dest_->MetaInfo);\n\n\t\t\t\tcmd->bmp_->SetSizeAndImageBuffer(cmd->dest_->bmp);\n\t\t\t\t// Ǎ݊ɂLbV`FbN(񓯊Ȃ̂ŊOɓǂݍ܂Ă\\)\n\t\t\t\tif( TVPHasImageCache( cmd->path_, glmNormal, 0, 0, TVP_clNone ) == false ) {\n\t\t\t\t\tTVPPushGraphicCache( cmd->path_, cmd->dest_->bmp, cmd->dest_->MetaInfo );\n\t\t\t\t\tcmd->dest_->MetaInfo = NULL;\n\t\t\t\t} else {\n\t\t\t\t\tdelete cmd->dest_->MetaInfo;\n\t\t\t\t\tcmd->dest_->MetaInfo = NULL;\n\t\t\t\t}\n\t\t\t\tcmd->dest_->bmp->Release();\n\t\t\t\tcmd->dest_->bmp = NULL;\n\n\t\t\t\ttTJSVariant param[4];\n\t\t\t\tparam[0] = tTJSVariant(metainfo,metainfo);\n\t\t\t\tif( metainfo ) metainfo->Release();\n\t\t\t\tparam[1] = 1; // true async\n\t\t\t\tparam[2] = 0; // false error\n\t\t\t\tparam[3] = TJS_W(\"\"); // error_mes\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onLoaded\"));\n\t\t\t\tif (cmd->owner_ && cmd->owner_->IsValid(0, NULL, NULL, cmd->owner_) == TJS_S_TRUE) {\n\t\t\t\t\tTVPPostEvent(cmd->owner_, cmd->owner_, eventname, 0, TVP_EPT_IMMEDIATE, 4, param);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete cmd;\n\t\t}\n\t} while(loading);\n}\n//---------------------------------------------------------------------------\n\n// onLoaded( dic, is_async, is_error, error_mes ); G[\n// sync ( main thead )\nvoid tTVPAsyncImageLoader::LoadRequest( iTJSDispatch2 *owner, tTJSNI_Bitmap* bmp, const ttstr &name ) {\n\t//tTVPBaseBitmap* dest = new tTVPBaseBitmap( 32, 32, 32 );\n\ttTVPBaseBitmap dest( TVPGetInitialBitmap() );\n\tiTJSDispatch2* metainfo = NULL;\n\tttstr nname = TVPNormalizeStorageName(name);\n\tif( TVPCheckImageCache(nname,&dest,glmNormal,0,0,TVP_clNone,&metainfo) ) {\n\t\t// LbVɔAɓǍ݂\n\t\tif (bmp) {\n\t\t\tbmp->CopyFrom(&dest);\n\t\t\tbmp->SetLoading(false);\n\t\t}\n\t\tif (!owner) return;\n\t\ttTJSVariant param[4];\n\t\tparam[0] = tTJSVariant(metainfo,metainfo);\n\t\tif( metainfo ) metainfo->Release();\n\t\tparam[1] = 0; // false\n\t\tparam[2] = 0; // false\n\t\tparam[3] = TJS_W(\"\"); // error_mes\n\t\tstatic ttstr eventname(TJS_W(\"onLoaded\"));\n\t\tTVPPostEvent(owner, owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, param);\n\t\treturn;\n\t}\n\tif( TVPIsExistentStorage(name) == false ) {\n\t\tTVPThrowExceptionMessage(TVPCannotFindStorage, name);\n\t}\n\tttstr ext = TVPExtractStorageExt(name);\n\tif(ext == TJS_W(\"\")) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Filename extension not found/%1\"), name);\n\t}\n\n\tPushLoadQueue( owner, bmp, nname );\n}\n\n// tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS);\n//\ttTJSBinaryStream* stream = TVPCreateStream(nname, TJS_BS_READ);\n// TVPCreateStream ̓bNĂ̂ŁA񓯊Ŏs\\\n\nvoid tTVPAsyncImageLoader::PushLoadQueue( iTJSDispatch2 *owner, tTJSNI_Bitmap *bmp, const ttstr &nname ) {\n\ttTVPImageLoadCommand* cmd = new tTVPImageLoadCommand();\n\tcmd->owner_ = owner;\n\tif (owner) owner->AddRef();\n\tcmd->bmp_ = bmp;\n\tcmd->path_ = nname;\n\tcmd->dest_ = new tTVPTmpBitmapImage();\n\tcmd->result_.Clear();\n\t{\n\t\t// L[bNăvbV\n\t\ttTJSCriticalSectionHolder cs(CommandQueueCS);\n\t\tCommandQueue.push(cmd);\n\t}\n\t// ǉƂCxgŒʒm\n\tPushCommandQueueEvent.Set();\n}\nvoid tTVPAsyncImageLoader::LoadingThread() {\n\twhile( !GetTerminated() ) {\n\t\t// L[ǉCxg҂\n\t\tPushCommandQueueEvent.WaitFor(0);\n\t\tif( GetTerminated() ) break;\n\t\tbool loading;\n\t\tdo {\n\t\t\tloading = false;\n\t\t\ttTVPImageLoadCommand* cmd = NULL;\n\n\t\t\t{ // Lock\n\t\t\t\ttTJSCriticalSectionHolder cs(CommandQueueCS);\n\t\t\t\tif( CommandQueue.size() ) {\n\t\t\t\t\tcmd = CommandQueue.front();\n\t\t\t\t\tCommandQueue.pop();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( cmd ) {\n\t\t\t\tloading = true;\n\t\t\t\tLoadImageFromCommand(cmd);\n\t\t\t\t{\t// Lock\n\t\t\t\t\ttTJSCriticalSectionHolder cs(ImageQueueCS);\n\t\t\t\t\tLoadedQueue.push(cmd);\n\t\t\t\t}\n\t\t\t\t// Send to message\n\t\t\t\tSendToLoadFinish();\n\t\t\t}\n\t\t} while( loading && !GetTerminated() );\n\t}\n}\ntTVPGraphicHandlerType* TVPGuessGraphicLoadHandler(ttstr& name);\nvoid tTVPAsyncImageLoader::LoadImageFromCommand( tTVPImageLoadCommand* cmd ) {\n\tttstr ext = TVPExtractStorageExt(cmd->path_);\n\ttTVPGraphicHandlerType* handler = NULL;\n\tttstr name(cmd->path_);\n\tif (ext.IsEmpty()) {\n\t\t// missing extension\n\t\thandler = TVPGuessGraphicLoadHandler(name);\n//\t\tcmd->result_ = TJS_W(\"Filename extension not found\");\n\t} else {\n\t\thandler = TVPGetGraphicLoadHandler(ext);\n\t}\n\tif( handler ) {\n\t\ttry {\n\t\t\ttTVPStreamHolder holder(name);\n\t\t\thandler->Load(handler->FormatData, (void*)cmd->dest_, TVPLoadGraphicAsync_SizeCallback,\n\t\t\t\tTVPLoadGraphicAsync_ScanLineCallback, TVPLoadGraphicAsync_MetaInfoPushCallback,\n\t\t\t\tholder.Get(), -1, glmNormal );\n\t\t} catch(...) {\n\t\t\t// O͑SăLb`\n\t\t\tcmd->result_ = TVPFormatMessage(TVPImageLoadError, cmd->path_);\n\t\t}\n\t} else {\n\t\t// error\n\t\tcmd->result_ = TVPFormatMessage(TVPUnknownGraphicFormat, cmd->path_);\n\t}\n}\n\n"
  },
  {
    "path": "src/core/visual/GraphicsLoadThread.h",
    "content": "\n#ifndef __GRAPHICS_LOAD_THREAD_H__\n#define __GRAPHICS_LOAD_THREAD_H__\n\n#include <queue>\n#include <vector>\n#include \"ThreadIntf.h\"\n#include \"NativeEventQueue.h\"\n#include \"GraphicsLoaderIntf.h\"\n\n// BaseBitmap gƃGggł͂Ȃ̂ŁAʂ̍\\̂ɓƎɃ[hKv\nstruct tTVPTmpBitmapImage {\n\tclass tTVPBitmap* bmp = nullptr;\n\tstd::vector<tTVPGraphicMetaInfoPair> * MetaInfo;\n\ttTVPTmpBitmapImage();\n\t~tTVPTmpBitmapImage();\n// pbg֘A͌ǂ܂ȂAt@Cɏ]̂ł͂ȂAOwȂ̂\n};\n\nstruct tTVPImageLoadCommand {\n\tiTJSDispatch2*\t\t\towner_;\t// send to event\n\tclass tTJSNI_Bitmap*\tbmp_;\t// set bitmap image\n\tttstr\t\t\t\t\tpath_;\n\ttTVPTmpBitmapImage*\t\tdest_;\n\tttstr\t\t\t\t\tresult_;\n\ttTVPImageLoadCommand();\n\t~tTVPImageLoadCommand();\n};\n\nclass tTVPAsyncImageLoader : public tTVPThread {\n\t/** ǍݗvR}h̃L[pCS */\n\ttTJSCriticalSection CommandQueueCS;\n\t/** Ǎݍς݉摜L[pCS */\n\ttTJSCriticalSection ImageQueueCS;\n\n\t/** [hチCXbhŏ邽߂̃bZ[WL[ */\n\tNativeEventQueue<tTVPAsyncImageLoader> EventQueue;\n\t/**  Ǎ݃Xbh֓ǍݗvƂ`Cxg */\n\ttTVPThreadEvent PushCommandQueueEvent;\n\n\t/** ǍݗvR}hL[ */\n\tstd::queue<tTVPImageLoadCommand*> CommandQueue;\n\t/** Ǎ݊摜L[ */\n\tstd::queue<tTVPImageLoadCommand*> LoadedQueue;\n\nprivate:\n\t/**\n\t * Ǎ݃Xbh烁CXbh֓Ǎ݂Ƃʒm\n\t */\n\tvoid SendToLoadFinish();\n\t/**\n\t * Ǎ݊摜CXbhBitmap֊i[āACxgʒm\n\t */\n\tvoid HandleLoadedImage();\npublic:\n\t/**\n\t * Ǎ݂Ǎ݃Xbhɗv(L[֓)\n\t */\n\tvoid PushLoadQueue( iTJSDispatch2 *owner, tTJSNI_Bitmap *bmp, const ttstr &nname );\n\t\n\t/**\n\t * Ǎ݃Xbh\n\t * L[ɃR}ĥ҂ACxgL[R}hoēǍݏs\n\t * Ǎ݂Ǎݍς݉摜L[ɓăCXbh֊ʒm\n\t */\n\tvoid LoadingThread();\n\t\n\t/**\n\t * 摜Ǎݏ\n\t */\n\tvoid LoadImageFromCommand( tTVPImageLoadCommand* cmd );\n\t\n\t/**\n\t * Ǎ݃XbhC\n\t */\n\tvoid Execute();\n\n\t/**\n\t * CXbhnh\n\t * CXbhւ̃Cxg(bZ[W)ʒm󂯂\n\t */\n\tvoid Proc( NativeEvent& ev );\n\npublic:\n\ttTVPAsyncImageLoader();\n\t~tTVPAsyncImageLoader();\n\n\t/**\n\t Ǎ݃Xbh̏Iv(I͑҂Ȃ)\n\t */\n\tvoid ExitRequest();\n\t\n\t/**\n\t * Ǎݗv\n\t * CXbhǍ݃Xbh֓Ǎ݂vB\n\t * ǍݑOɃG[ꍇLbVɉ摜ꍇ͗v͍sꂸ\n\t * ɏIAonLoaded Cxg𔭐B\n\t */\n\tvoid LoadRequest( iTJSDispatch2 *owner, tTJSNI_Bitmap* bmp, const ttstr &name );\n};\n\n#endif // __GRAPHICS_LOAD_THREAD_H__\n"
  },
  {
    "path": "src/core/visual/GraphicsLoaderIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Graphics Loader ( loads graphic format from storage )\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include <stdlib.h>\n#include \"GraphicsLoaderIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerIntf.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsHashSearch.h\"\n#include \"EventIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n#include \"tvpgl.h\"\n#include \"TickCount.h\"\n#include \"DetectCPU.h\"\n#include \"UtilStreams.h\"\n#include \"tjsDictionary.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"RenderManager.h\"\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include <mutex>\n#include <thread>\n#include <condition_variable>\n#include \"Application.h\"\n#include \"BitmapIntf.h\"\n#include \"GraphicsLoadThread.h\"\n#include <complex>\n#include <list>\n\nvoid TVPLoadPVRv3(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int keyidx,\n\ttTVPGraphicLoadMode mode);\nvoid TVPLoadHeaderPVRv3(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic);\n\nstatic void TVPLoadGraphicRouter(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx, tTVPGraphicLoadMode mode) {\n\tuint8_t header[16];\n\ttjs_uint64 origSrcPos = src->GetPosition();\n\tif (src->Read(header, sizeof(header)) == sizeof(header)) {\n\t\tsrc->SetPosition(origSrcPos);\n#define CALL_LOAD_FUNC(f) f(formatdata, callbackdata, sizecallback, scanlinecallback, metainfopushcallback, src, keyidx, mode)\n\t\tif (!memcmp(header, \"BM\", 2)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadBMP);\n\t\t}\n\t\tif (!memcmp(header, \"\\x89PNG\", 4)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadPNG);\n\t\t}\n\t\tif (!memcmp(header, \"TLG\", 3)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadTLG);\n\t\t}\n\t\tif (!memcmp(header, \"\\xFF\\xD8\\xFF\", 3) &&\n\t\t\theader[3] >= 0xE0 && header[3] <= 0xEF ) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadJPEG);\n\t\t}\n\t\t// ## fix ld: error: undefined symbol: TVPLoadBPG\n\t\t// if (!memcmp(header, \"BPG\", 3)) {\n\t\t// \treturn CALL_LOAD_FUNC(TVPLoadBPG);\n\t\t// }\n\t\tif (!memcmp(header, \"RIFF\", 4) && !memcmp(header + 8, \"WEBPVP8\", 7)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadWEBP);\n\t\t}\n\t\t// if (!memcmp(header, \"\\x49\\x49\\xbc\\x01\", 4)) {\n\t\t// \treturn CALL_LOAD_FUNC(TVPLoadJXR);\n\t\t// }\n\t\tif (!memcmp(header, \"PVR\\3\", 4)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadPVRv3);\n\t\t}\n#undef CALL_LOAD_FUNC\n\t}\n\tTVPThrowExceptionMessage(TVPImageLoadError, TJS_W(\"Invalid image\"));\n}\n\nstatic void TVPLoadHeaderRouter(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic) {\n\tuint8_t header[16];\n\ttjs_uint64 origSrcPos = src->GetPosition();\n\tif (src->Read(header, sizeof(header)) == sizeof(header)) {\n\t\tsrc->SetPosition(origSrcPos);\n#define CALL_LOAD_FUNC(f) f(formatdata, src, dic)\n\t\tif (!memcmp(header, \"BM\", 2)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderBMP);\n\t\t}\n\t\tif (!memcmp(header, \"\\x89PNG\", 4)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderPNG);\n\t\t}\n\t\tif (!memcmp(header, \"TLG\", 3)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderTLG);\n\t\t}\n\t\tif (!memcmp(header, \"\\xFF\\xD8\\xFF\", 3) &&\n\t\t\theader[3] >= 0xE0 && header[3] <= 0xEF) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderJPG);\n\t\t}\n\t\t// if (!memcmp(header, \"BPG\", 3)) {\n\t\t// \treturn CALL_LOAD_FUNC(TVPLoadHeaderBPG);\n\t\t// }\n\t\tif (!memcmp(header, \"RIFF\", 4) && !memcmp(header + 8, \"WEBPVP8\", 7)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderWEBP);\n\t\t}\n\t\t// if (!memcmp(header, \"\\x49\\x49\\xbc\\x01\", 4)) {\n\t\t// \treturn CALL_LOAD_FUNC(TVPLoadHeaderJXR);\n\t\t// }\n\t\tif (!memcmp(header, \"PVR\\3\", 4)) {\n\t\t\treturn CALL_LOAD_FUNC(TVPLoadHeaderPVRv3);\n\t\t}\n#undef CALL_LOAD_FUNC\n\t}\n\tTVPThrowExceptionMessage(TVPImageLoadError, TJS_W(\"Invalid image\"));\n}\n\n//---------------------------------------------------------------------------\n\n\nbool TVPAcceptSaveAsBMP( void* formatdata, const ttstr & type, class iTJSDispatch2** dic )\n{\n\tbool result = false;\n\tif( type.StartsWith(TJS_W(\"bmp\")) ) result = true;\n\telse if( type == TJS_W(\".bmp\") ) result = true;\n\telse if( type == TJS_W(\".dib\") ) result = true;\n\tif( result && dic ) {\n\t\ttTJSVariant result;\n\t\tTVPExecuteExpression(\n\t\t\tTJS_W(\"(const)%[\")\n\t\t\tTJS_W(\"\\\"bpp\\\"=>(const)%[\\\"type\\\"=>\\\"select\\\",\\\"items\\\"=>(const)[\\\"32\\\",\\\"24\\\",\\\"8\\\"],\\\"desc\\\"=>\\\"bpp\\\",\\\"default\\\"=>0]\")\n\t\t\tTJS_W(\"]\"),\n\t\t\tNULL, &result );\n\t\tif( result.Type() == tvtObject ) {\n\t\t\t*dic = result.AsObject();\n\t\t}\n\t\t//*dic = TJSCreateDictionaryObject();\n\t}\n\treturn result;\n}\n//---------------------------------------------------------------------------\n// Graphics Format Management\n//---------------------------------------------------------------------------\n\nclass tTVPGraphicType\n{\npublic:\n\ttTJSHashTable<ttstr, tTVPGraphicHandlerType> Hash;\n\tstd::vector<tTVPGraphicHandlerType> Handlers;\n\n\tstatic bool Avail;\n\n\ttTVPGraphicType()\n\t{\n\t\t// register some native-supported formats\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".pvr\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, nullptr, nullptr, NULL));\n\t\t// Handlers.push_back(tTVPGraphicHandlerType(\n\t\t// \tTJS_W(\".jxr\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsJXR, TVPAcceptSaveAsJXR, NULL));\n\t\t// Handlers.push_back(tTVPGraphicHandlerType(\n\t\t// \tTJS_W(\".bpg\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, nullptr, nullptr, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".webp\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, nullptr, nullptr, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".bmp\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsBMP, TVPAcceptSaveAsBMP, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".dib\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsBMP, TVPAcceptSaveAsBMP, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".jpeg\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsJPG, TVPAcceptSaveAsJPG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".jpg\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsJPG, TVPAcceptSaveAsJPG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".jif\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsJPG, TVPAcceptSaveAsJPG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".png\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsPNG, TVPAcceptSaveAsPNG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".tlg\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsTLG, TVPAcceptSaveAsTLG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".tlg5\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsTLG, TVPAcceptSaveAsTLG, NULL));\n\t\tHandlers.push_back(tTVPGraphicHandlerType(\n\t\t\tTJS_W(\".tlg6\"), TVPLoadGraphicRouter, TVPLoadHeaderRouter, TVPSaveAsTLG, TVPAcceptSaveAsTLG, NULL));\n\t\tReCreateHash();\n\t\tAvail = true;\n\t}\n\n\t~tTVPGraphicType()\n\t{\n\t\tAvail = false;\n\t}\n\n\tvoid ReCreateHash()\n\t{\n\t\t// re-create hash table for faster search\n\n\t\tstd::vector<tTVPGraphicHandlerType>::iterator i;\n\t\tfor(i = Handlers.begin();\n\t\t\ti!= Handlers.end(); i++)\n\t\t{\n\t\t\tHash.Add(i->Extension, *i);\n\t\t}\n\t}\n\n\tvoid Register( const tTVPGraphicHandlerType& hander )\n\t{\n\t\t// register graphic format to the table.\n\t\tHandlers.push_back(hander);\n\t\tReCreateHash();\n\t}\n\n\tvoid Unregister( const tTVPGraphicHandlerType& hander )\n\t{\n\t\t// unregister format from table.\n\n\t\tstd::vector<tTVPGraphicHandlerType>::iterator i;\n\n\t\tif(Handlers.size() > 0)\n\t\t{\n\t\t\t//for(i = Handlers.end() -1; i >= Handlers.begin(); i--)\n\t\t\tfor(i = Handlers.begin(); i != Handlers.end(); i++)\n\t\t\t{\n\t\t\t\tif(hander == *i)\n\t\t\t\t{\n\t\t\t\t\tHandlers.erase(i);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tReCreateHash();\n\t}\n\n} static TVPGraphicType;\nbool tTVPGraphicType::Avail = false;\n//---------------------------------------------------------------------------\nvoid TVPRegisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandler loading,\n\ttTVPGraphicHeaderLoadingHandler header,\n\ttTVPGraphicSaveHandler save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid * formatdata)\n{\n\t// name must be un-capitalized\n\tif(TVPGraphicType.Avail)\n\t{\n\t\tTVPGraphicType.Register(tTVPGraphicHandlerType(name, loading, header, save, accept, formatdata));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPUnregisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandler loading,\n\ttTVPGraphicHeaderLoadingHandler header,\n\ttTVPGraphicSaveHandler save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid * formatdata)\n{\n\t// name must be un-capitalized\n\tif(TVPGraphicType.Avail)\n\t{\n\t\tTVPGraphicType.Unregister(tTVPGraphicHandlerType(name, loading, header, save, accept, formatdata));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPRegisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandlerForPlugin loading,\n\ttTVPGraphicHeaderLoadingHandlerForPlugin header,\n\ttTVPGraphicSaveHandlerForPlugin save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata)\n{\n\t// name must be un-capitalized\n\tif(TVPGraphicType.Avail)\n\t{\n\t\tTVPGraphicType.Register(tTVPGraphicHandlerType(name, loading, header, save, accept, formatdata));\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPUnregisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandlerForPlugin loading,\n\ttTVPGraphicHeaderLoadingHandlerForPlugin header,\n\ttTVPGraphicSaveHandlerForPlugin save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata)\n{\n\t// name must be un-capitalized\n\tif(TVPGraphicType.Avail)\n\t{\n\t\tTVPGraphicType.Unregister(tTVPGraphicHandlerType(name, loading, header, save, accept, formatdata));\n\t}\n}\n\ntTVPGraphicHandlerType* TVPGuessGraphicLoadHandler(ttstr& name) { // with name has no extension\n\t// suggest registered extensions\n\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\tfor (i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/)\n\t{\n\t\tttstr newname = name + i.GetKey();\n\t\tif (TVPIsExistentStorage(newname))\n\t\t{\n\t\t\t// file found\n\t\t\tname = newname;\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tif (i.IsNull())\n\t{\n\t\t// not found\n\t\treturn nullptr;\n\t}\n\treturn &i.GetValue();\n}\n//---------------------------------------------------------------------------\ntTVPGraphicHandlerType* TVPGetGraphicLoadHandler( const ttstr& ext )\n{\n\treturn TVPGraphicType.Hash.Find(ext);\n}\n/*\n\tloading handlers return whether the image contains an alpha channel.\n*/\n//---------------------------------------------------------------------------\nconst void* tTVPBitmapScanLineCallbackForSave(void *callbackdata, tjs_int y)\n{\n\ttTVPBaseBitmap* image = (tTVPBaseBitmap*)callbackdata;\n\treturn image->GetScanLine(y);\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadImageHeader( const ttstr & storagename, iTJSDispatch2** dic )\n{\n\tif( dic == NULL ) return;\n\n\tttstr ext = TVPExtractStorageExt(storagename);\n\tif(ext == TJS_W(\"\")) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, storagename);\n\ttTVPGraphicHandlerType * handler = TVPGraphicType.Hash.Find(ext);\n\tif(!handler) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, storagename);\n\n\ttTVPStreamHolder holder(storagename); // open a storage named \"storagename\"\n\thandler->Header( holder.Get(), dic );\n}\n//---------------------------------------------------------------------------\nvoid TVPSaveImage( const ttstr & storagename, const ttstr & mode, const iTVPBaseBitmap* image, iTJSDispatch2* meta )\n{\n\tif(!image->Is32BPP())\n\t\tTVPThrowInternalError;\n\n\ttTVPGraphicHandlerType * handler;\n\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\tfor(i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); i++)\n\t{\n\t\thandler = & i.GetValue();\n\t\tif( handler->AcceptSave( mode, NULL ) )\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\thandler = NULL;\n\t\t}\n\t}\n\tif( handler ) handler->Save( storagename, mode, image, meta );\n\telse TVPThrowExceptionMessage(TVPUnknownGraphicFormat, mode);\n}\n//---------------------------------------------------------------------------\nbool TVPGetSaveOption( const ttstr & type, iTJSDispatch2** dic )\n{\n\ttTVPGraphicHandlerType * handler;\n\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\tfor(i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); i++ )\n\t{\n\t\thandler = & i.GetValue();\n\t\tif( handler->AcceptSave( type, dic ) )\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// BMP loading handler\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#define TVP_BMP_READ_LINE_MAX 8\nvoid TVPInternalLoadBMP(void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\tTVP_WIN_BITMAPINFOHEADER &bi,\n\tconst tjs_uint8 *palsrc,\n\ttTJSBinaryStream * src,\n\ttjs_int keyidx,\n\ttTVPBMPAlphaType alphatype,\n\ttTVPGraphicLoadMode mode)\n{\n\t// mostly taken ( but totally re-written ) from SDL,\n\t// http://www.libsdl.org/\n\n\t// TODO: only checked on Win32 platform\n\n\n\tif(bi.biSize == 12)\n\t{\n\t\t// OS/2\n\t\tbi.biCompression = BI_RGB;\n\t\tbi.biClrUsed = 1 << bi.biBitCount;\n\t}\n\n\ttjs_uint16 orgbitcount = bi.biBitCount;\n\tif(bi.biBitCount == 1 || bi.biBitCount == 4)\n\t{\n\t\tbi.biBitCount = 8;\n\t}\n\n\tswitch(bi.biCompression)\n\t{\n\tcase BI_RGB:\n\t\t// if there are no masks, use the defaults\n\t\tbreak; // use default\n/*\n\t\tif( bf.bfOffBits == ( 14 + bi.biSize) )\n\t\t{\n\t\t}\n\t\t// fall through -- read the RGB masks\n*/\n\tcase BI_BITFIELDS:\n\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPBitFieldsNotSupported );\n\n\tdefault:\n \t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPCompressedBmpNotSupported );\n\t}\n\n\t// load palette\n\ttjs_uint32 palette[256];   // (msb) argb (lsb)\n\tif(orgbitcount <= 8)\n\t{\n\t\tif(bi.biClrUsed == 0) bi.biClrUsed = 1 << orgbitcount ;\n\t\tif(bi.biSize == 12)\n\t\t{\n\t\t\t// read OS/2 palette\n\t\t\tfor(tjs_uint i = 0; i < bi.biClrUsed; i++)\n\t\t\t{\n\t\t\t\tpalette[i] = (palsrc[0]<<16) + (palsrc[1]<<8) + (palsrc[2]<<0) +\n\t\t\t\t\t0xff000000;\n\t\t\t\tpalsrc += 3;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// read Windows palette\n\t\t\tfor(tjs_uint i = 0; i<bi.biClrUsed; i++)\n\t\t\t{\n\t\t\t\tpalette[i] = (palsrc[0]<<16) + (palsrc[1]<<8) + (palsrc[2]<<0) +\n\t\t\t\t\t0xff000000;\n\t\t\t\t\t// we assume here that the palette's unused segment is useless.\n\t\t\t\t\t// fill it with 0xff ( = completely opaque )\n\t\t\t\tpalsrc += 4;\n\t\t\t}\n\t\t}\n\n\t\tif(mode == glmGrayscale)\n\t\t{\n\t\t\tTVPDoGrayScale(palette, 256);\n\t\t}\n\n\t\tif(keyidx != -1)\n\t\t{\n\t\t\t// if color key by palette index is specified\n\t\t\tpalette[keyidx&0xff] &= 0x00ffffff; // make keyidx transparent\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(mode == glmPalettized)\n\t\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPUnsupportedColorModeForPalettImage );\n\t}\n\n\ttjs_int height;\n\theight = bi.biHeight<0?-bi.biHeight:bi.biHeight;\n\t\t// positive value of bi.biHeight indicates top-down DIB\n\n\ttTVPGraphicPixelFormat pixfmt;\n\tswitch (orgbitcount) {\n\tcase 32: pixfmt = gpfRGBA; break;\n\tcase 24: case 16: case 15:\n\t\tpixfmt = gpfRGB; break;\n\tdefault:\n\t\tpixfmt = gpfPalette; break;\n\t}\n\tsizecallback(callbackdata, bi.biWidth, height, pixfmt);\n\n\ttjs_int pitch;\n\tpitch = (((bi.biWidth * orgbitcount) + 31) & ~31) /8;\n\ttjs_uint8 *readbuf = (tjs_uint8 *)TJSAlignedAlloc(pitch * TVP_BMP_READ_LINE_MAX, 4);\n\ttjs_uint8 *buf;\n\ttjs_int bufremain = 0;\n\ttry\n\t{\n\t\t// process per a line\n\t\ttjs_int src_y = 0;\n\t\ttjs_int dest_y;\n\t\tif(bi.biHeight>0) dest_y = bi.biHeight-1; else dest_y = 0;\n\n\t\tfor(; src_y < height; src_y++)\n\t\t{\n\t\t\tif(bufremain == 0)\n\t\t\t{\n\t\t\t\ttjs_int remain = height - src_y;\n\t\t\t\ttjs_int read_lines = remain > TVP_BMP_READ_LINE_MAX ?\n\t\t\t\t\tTVP_BMP_READ_LINE_MAX : remain;\n\t\t\t\tsrc->ReadBuffer(readbuf, pitch * read_lines);\n\t\t\t\tbufremain = read_lines;\n\t\t\t\tbuf = readbuf;\n\t\t\t}\n\n\t\t\tvoid *scanline = scanlinecallback(callbackdata, dest_y);\n\t\t\tif(!scanline) break;\n\n\t\t\tswitch(orgbitcount)\n\t\t\t{\n\t\t\t\t// convert pixel format\n\t\t\tcase 1:\n\t\t\t\tif(mode == glmPalettized)\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand1BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse if(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand1BitTo8BitPal(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand1BitTo32BitPal(\n\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 4:\n\t\t\t\tif(mode == glmPalettized)\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand4BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse if(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand4BitTo8BitPal(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand4BitTo32BitPal(\n\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 8:\n\t\t\t\tif(mode == glmPalettized)\n\t\t\t\t{\n\t\t\t\t\t// intact copy\n\t\t\t\t\tmemcpy(scanline, buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\t// convert to grayscale\n\t\t\t\t\tTVPBLExpand8BitTo8BitPal(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLExpand8BitTo32BitPal(\n\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth, palette);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 15:\n\t\t\tcase 16:\n\t\t\t\tif(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert15BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint16*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert15BitTo32Bit(\n\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t(tjs_uint16*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 24:\n\t\t\t\tif(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert24BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert24BitTo32Bit(\n\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 32:\n\t\t\t\tif(mode == glmGrayscale)\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert32BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint32*)buf, bi.biWidth);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(alphatype == batNone)\n\t\t\t\t\t{\n\t\t\t\t\t\t// alpha channel is not given by the bitmap.\n\t\t\t\t\t\t// destination alpha is filled with 255.\n\t\t\t\t\t\tTVPBLConvert32BitTo32Bit_NoneAlpha(\n\t\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t\t(tjs_uint32*)buf, bi.biWidth);\n\t\t\t\t\t}\n\t\t\t\t\telse if(alphatype == batMulAlpha)\n\t\t\t\t\t{\n\t\t\t\t\t\t// this is the TVP native representation of the alpha channel.\n\t\t\t\t\t\t// simply copy from the buffer.\n\t\t\t\t\t\tTVPBLConvert32BitTo32Bit_MulAddAlpha(\n\t\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t\t(tjs_uint32*)buf, bi.biWidth);\n\t\t\t\t\t}\n\t\t\t\t\telse if(alphatype == batAddAlpha)\n\t\t\t\t\t{\n\t\t\t\t\t\t// this is alternate representation of the alpha channel,\n\t\t\t\t\t\t// this must be converted to TVP native representation.\n\t\t\t\t\t\tTVPBLConvert32BitTo32Bit_AddAlpha(\n\t\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t\t(tjs_uint32*)buf, bi.biWidth);\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tscanlinecallback(callbackdata, -1); // image was written\n\n\t\t\tif(bi.biHeight>0) dest_y--; else dest_y++;\n\t\t\tbuf += pitch;\n\t\t\tbufremain--;\n\t\t}\n\n\n\t}\n\tcatch(...)\n\t{\n\t\tTJSAlignedDealloc(readbuf);\n\t\tthrow;\n\t}\n\n\tTJSAlignedDealloc(readbuf);\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadBMP(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\t// Windows BMP Loader\n\t// mostly taken ( but totally re-written ) from SDL,\n\t// http://www.libsdl.org/\n\n\t// TODO: only checked in Win32 platform\n\n\n\n\ttjs_uint64 firstpos = src->GetPosition();\n\n\t// check the magic\n\ttjs_uint8 magic[2];\n\tsrc->ReadBuffer(magic, 2);\n\tif(magic[0] != TJS_N('B') || magic[1] != TJS_N('M'))\n\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPNotWindowsBmp );\n\n\t// read the BITMAPFILEHEADER\n\tTVP_WIN_BITMAPFILEHEADER bf;\n\tbf.bfSize = src->ReadI32LE();\n\tbf.bfReserved1 = src->ReadI16LE();\n\tbf.bfReserved2 = src->ReadI16LE();\n\tbf.bfOffBits = src->ReadI32LE();\n\n\t// read the BITMAPINFOHEADER\n\tTVP_WIN_BITMAPINFOHEADER bi;\n\tbi.biSize = src->ReadI32LE();\n\tif(bi.biSize == 12)\n\t{\n\t\t// OS/2 Bitmap\n\t\tmemset(&bi, 0, sizeof(bi));\n\t\tbi.biWidth = (tjs_uint32)src->ReadI16LE();\n\t\tbi.biHeight = (tjs_uint32)src->ReadI16LE();\n\t\tbi.biPlanes = src->ReadI16LE();\n\t\tbi.biBitCount = src->ReadI16LE();\n\t\tbi.biClrUsed = 1 << bi.biBitCount;\n\t}\n\telse if(bi.biSize == 40)\n\t{\n\t\t// Windows Bitmap\n\t\tbi.biWidth = src->ReadI32LE();\n\t\tbi.biHeight = src->ReadI32LE();\n\t\tbi.biPlanes = src->ReadI16LE();\n\t\tbi.biBitCount = src->ReadI16LE();\n\t\tbi.biCompression = src->ReadI32LE();\n\t\tbi.biSizeImage = src->ReadI32LE();\n\t\tbi.biXPelsPerMeter = src->ReadI32LE();\n\t\tbi.biYPelsPerMeter = src->ReadI32LE();\n\t\tbi.biClrUsed = src->ReadI32LE();\n\t\tbi.biClrImportant = src->ReadI32LE();\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPUnsupportedHeaderVersion );\n\t}\n\n\n\t// load palette\n\ttjs_int palsize = (bi.biBitCount <= 8) ?\n\t\t((bi.biClrUsed == 0 ? (1<<bi.biBitCount) : bi.biClrUsed) *\n\t\t((bi.biSize == 12) ? 3:4)) : 0;  // bi.biSize == 12 ( OS/2 palette )\n\ttjs_uint8 *palette = NULL;\n\n\tif(palsize) palette = new tjs_uint8 [palsize];\n\n\ttry\n\t{\n\t\tsrc->ReadBuffer(palette, palsize);\n\t\tsrc->SetPosition(firstpos + bf.bfOffBits);\n\n\t\tTVPInternalLoadBMP(callbackdata, sizecallback, scanlinecallback,\n\t\t\tbi, palette, src, keyidx, batMulAlpha, mode);\n\t}\n\tcatch(...)\n\t{\n\t\tif(palette) delete [] palette;\n\t\tthrow;\n\t}\n\tif(palette) delete [] palette;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// BMP saving handler\n//---------------------------------------------------------------------------\nstatic void TVPWriteLE16(tTJSBinaryStream * stream, tjs_uint16 number)\n{\n\ttjs_uint8 data[2];\n\tdata[0] = number & 0xff;\n\tdata[1] = (number >> 8) & 0xff;\n\tstream->WriteBuffer(data, 2);\n}\n//---------------------------------------------------------------------------\nstatic void TVPWriteLE32(tTJSBinaryStream * stream, tjs_uint32 number)\n{\n\ttjs_uint8 data[4];\n\tdata[0] = number & 0xff;\n\tdata[1] = (number >> 8) & 0xff;\n\tdata[2] = (number >> 16) & 0xff;\n\tdata[3] = (number >> 24) & 0xff;\n\tstream->WriteBuffer(data, 4);\n}\n//---------------------------------------------------------------------------\nvoid TVPSaveTextureAsBMP(tTJSBinaryStream* dst, iTVPTexture2D* bmp, const ttstr & mode, iTJSDispatch2* meta)\n{\n\ttjs_int pixelbytes;\n\n\tif (bmp->GetFormat() == TVPTextureFormat::Gray)\n\t\tpixelbytes = 1;\n\telse if(mode == TJS_W(\"bmp32\") || mode == TJS_W(\"bmp\"))\n\t\tpixelbytes = 4;\n\telse if(mode == TJS_W(\"bmp24\"))\n\t\tpixelbytes = 3;\n\telse if(mode == TJS_W(\"bmp8\"))\n\t\tpixelbytes = 1;\n\telse\n\t\tpixelbytes = 4;\n\n\tif( meta )\n\t{\n\t\ttTJSVariant val;\n\t\ttjs_error er = meta->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"bpp\"), NULL, &val, meta);\n\t\tif(TJS_SUCCEEDED(er))\n\t\t{\n\t\t\ttjs_int index = (tjs_int)val.AsInteger();\n\t\t\tswitch( index ) {\n\t\t\tcase 0: pixelbytes = 4; break;\n\t\t\tcase 1: pixelbytes = 3; break;\n\t\t\tcase 2: pixelbytes = 1; break;\n\t\t\t};\n\t\t}\n\t}\n\n\t// open stream\n\ttTJSBinaryStream *stream = dst;\n\ttjs_uint8 * buf = NULL;\n\n\ttry\n\t{\n\t\tTVPClearGraphicCache();\n\n\t\t// prepare header\n\t\ttjs_uint bmppitch = bmp->GetWidth() * pixelbytes;\n\t\tbmppitch = (((bmppitch - 1) >> 2) + 1) << 2;\n\n\t\tTVPWriteLE16(stream, 0x4d42);  /* bfType */\n\t\tTVPWriteLE32(stream, sizeof(TVP_WIN_BITMAPFILEHEADER) +\n\t\t\t\tsizeof(TVP_WIN_BITMAPINFOHEADER) + bmppitch * bmp->GetHeight() +\n\t\t\t\t(pixelbytes == 1 ? 1024 : 0)); /* bfSize */\n\t\tTVPWriteLE16(stream, 0); /* bfReserved1 */\n\t\tTVPWriteLE16(stream, 0); /* bfReserved2 */\n\t\tTVPWriteLE32(stream, sizeof(TVP_WIN_BITMAPFILEHEADER) +\n\t\t\t\tsizeof(TVP_WIN_BITMAPINFOHEADER)+\n\t\t\t\t(pixelbytes == 1 ? 1024 : 0)); /* bfOffBits */\n\n\t\tTVPWriteLE32(stream, sizeof(TVP_WIN_BITMAPINFOHEADER)); /* biSize */\n\t\tTVPWriteLE32(stream, bmp->GetWidth()); /* biWidth */\n\t\tTVPWriteLE32(stream, bmp->GetHeight()); /* biHeight */\n\t\tTVPWriteLE16(stream, 1); /* biPlanes */\n\t\tTVPWriteLE16(stream, pixelbytes * 8); /* biBitCount */\n\t\tTVPWriteLE32(stream, BI_RGB); /* biCompression */\n\t\tTVPWriteLE32(stream, 0); /* biSizeImage */\n\t\tTVPWriteLE32(stream, 0); /* biXPelsPerMeter */\n\t\tTVPWriteLE32(stream, 0); /* biYPelsPerMeter */\n\t\tTVPWriteLE32(stream, 0); /* biClrUsed */\n\t\tTVPWriteLE32(stream, 0); /* biClrImportant */\n\n\t\t// write palette\n\t\tif(pixelbytes == 1)\n\t\t{\n\t\t\ttjs_uint8 palette[1024];\n\t\t\ttjs_uint8 * p = palette;\n\t\t\tif (bmp->GetFormat() == TVPTextureFormat::Gray) {\n\t\t\t\tfor (tjs_int i = 0; i < 256; i++)\n\t\t\t\t{\n\t\t\t\t\tp[0] = i;\n\t\t\t\t\tp[1] = i;\n\t\t\t\t\tp[2] = i;\n\t\t\t\t\tp[3] = 0;\n\t\t\t\t\tp += 4;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (tjs_int i = 0; i < 256; i++)\n\t\t\t\t{\n\t\t\t\t\tp[0] = TVP252DitherPalette[0][i];\n\t\t\t\t\tp[1] = TVP252DitherPalette[1][i];\n\t\t\t\t\tp[2] = TVP252DitherPalette[2][i];\n\t\t\t\t\tp[3] = 0;\n\t\t\t\t\tp += 4;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstream->WriteBuffer(palette, 1024);\n\t\t}\n\n\t\t// write bitmap body\n\t\tif (bmp->GetFormat() == TVPTextureFormat::Gray) {\n\t\t\tfor (tjs_int y = bmp->GetHeight() - 1; y >= 0; y--)\n\t\t\t{\n\t\t\t\tif (!buf) buf = new tjs_uint8[bmppitch];\n\t\t\t\tmemcpy(buf, bmp->GetScanLineForRead(y), bmp->GetWidth());\n\t\t\t\tstream->WriteBuffer(buf, bmppitch);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = bmp->GetHeight() - 1; y >= 0; y--)\n\t\t\t{\n\t\t\t\tif (!buf) buf = new tjs_uint8[bmppitch];\n\t\t\t\tif (pixelbytes == 4) {\n\t\t\t\t\tTVPReverseRGB((tjs_uint32 *)buf, (const tjs_uint32 *)bmp->GetScanLineForRead(y), bmp->GetWidth());\n\t\t\t\t} else if (pixelbytes == 1) {\n\t\t\t\t\tTVPDither32BitTo8Bit(buf, (const tjs_uint32*)bmp->GetScanLineForRead(y),\n\t\t\t\t\t\tbmp->GetWidth(), 0, y);\n\t\t\t\t} else {\n\t\t\t\t\tconst tjs_uint8 *src = (const tjs_uint8 *)bmp->GetScanLineForRead(y);\n\t\t\t\t\ttjs_uint8 *dest = buf;\n\t\t\t\t\ttjs_int w = bmp->GetWidth();\n\t\t\t\t\tfor (tjs_int x = 0; x < w; x++)\n\t\t\t\t\t{\n\t\t\t\t\t\tdest[0] = src[2];\n\t\t\t\t\t\tdest[1] = src[1];\n\t\t\t\t\t\tdest[2] = src[0];\n\t\t\t\t\t\tdest += 3;\n\t\t\t\t\t\tsrc += 4;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstream->WriteBuffer(buf, bmppitch);\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(buf) delete [] buf;\n\t\tthrow;\n\t}\n\tif(buf) delete [] buf;\n}\n\nvoid TVPSaveTextureAsBMP(const ttstr &path, iTVPTexture2D* tex, const ttstr &mode, iTJSDispatch2* meta)\n{\n\ttTJSBinaryStream *dst = TVPCreateStream(path, TJS_BS_WRITE);\n\tTVPSaveTextureAsBMP(dst, tex, mode, meta);\n\tdelete dst;\n}\n\nvoid TVPSaveAsBMP(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* bmp, const ttstr & mode, iTJSDispatch2* meta)\n{\n\tTVPSaveTextureAsBMP(dst, bmp->GetTexture(), mode, meta);\n}\n//---------------------------------------------------------------------------\n\nvoid TVPLoadHeaderBMP( void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\ttjs_uint64 firstpos = src->GetPosition();\n\n\t// check the magic\n\ttjs_uint8 magic[2];\n\tsrc->ReadBuffer(magic, 2);\n\tif(magic[0] != TJS_N('B') || magic[1] != TJS_N('M'))\n\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPNotWindowsBmp );\n\n\t// read the BITMAPFILEHEADER\n\tTVP_WIN_BITMAPFILEHEADER bf;\n\tbf.bfSize = src->ReadI32LE();\n\tbf.bfReserved1 = src->ReadI16LE();\n\tbf.bfReserved2 = src->ReadI16LE();\n\tbf.bfOffBits = src->ReadI32LE();\n\n\t// read the BITMAPINFOHEADER\n\tTVP_WIN_BITMAPINFOHEADER bi;\n\tbi.biSize = src->ReadI32LE();\n\tif(bi.biSize == 12)\n\t{\n\t\t// OS/2 Bitmap\n\t\tmemset(&bi, 0, sizeof(bi));\n\t\tbi.biWidth = (tjs_uint32)src->ReadI16LE();\n\t\tbi.biHeight = (tjs_uint32)src->ReadI16LE();\n\t\tbi.biPlanes = src->ReadI16LE();\n\t\tbi.biBitCount = src->ReadI16LE();\n\t\tbi.biClrUsed = 1 << bi.biBitCount;\n\t}\n\telse if(bi.biSize == 40)\n\t{\n\t\t// Windows Bitmap\n\t\tbi.biWidth = src->ReadI32LE();\n\t\tbi.biHeight = src->ReadI32LE();\n\t\tbi.biPlanes = src->ReadI16LE();\n\t\tbi.biBitCount = src->ReadI16LE();\n\t\tbi.biCompression = src->ReadI32LE();\n\t\tbi.biSizeImage = src->ReadI32LE();\n\t\tbi.biXPelsPerMeter = src->ReadI32LE();\n\t\tbi.biYPelsPerMeter = src->ReadI32LE();\n\t\tbi.biClrUsed = src->ReadI32LE();\n\t\tbi.biClrImportant = src->ReadI32LE();\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPUnsupportedHeaderVersion );\n\t}\n\n\ttjs_int palsize = (bi.biBitCount <= 8) ?\n\t\t((bi.biClrUsed == 0 ? (1<<bi.biBitCount) : bi.biClrUsed) *\n\t\t((bi.biSize == 12) ? 3:4)) : 0;  // bi.biSize == 12 ( OS/2 palette )\n\tpalsize = palsize > 0 ? 1 : 0;\n\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val(bi.biWidth);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\tval = tTJSVariant(bi.biHeight);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic) );\n\tval = tTJSVariant(bi.biBitCount);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic) );\n\tval = tTJSVariant(palsize);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"palette\"), 0, &val, (*dic) );\n}\n\n//---------------------------------------------------------------------------\n// TVPLoadGraphic related\n//---------------------------------------------------------------------------\nenum tTVPLoadGraphicType\n{\n\tlgtFullColor, // full 32bit color\n\tlgtPalGray, // palettized or grayscale\n\tlgtMask // mask\n};\nstruct tTVPLoadGraphicData\n{\n\tttstr Name;\n\ttTVPBitmap *Dest;\n\ttTVPLoadGraphicType Type;\n\ttjs_int ColorKey;\n\ttjs_uint8 *Buffer;\n\ttjs_uint ScanLineNum;\n\ttjs_uint DesW;\n\ttjs_uint DesH;\n\ttjs_uint OrgW;\n\ttjs_uint OrgH;\n\ttjs_uint BufW;\n\ttjs_uint BufH;\n\tbool NeedMetaInfo;\n\tstd::vector<tTVPGraphicMetaInfoPair> * MetaInfo;\n};\n//---------------------------------------------------------------------------\nstatic int TVPLoadGraphic_SizeCallback(void *callbackdata, tjs_uint w,\n\ttjs_uint h, tTVPGraphicPixelFormat fmt)\n{\n\ttTVPLoadGraphicData * data = (tTVPLoadGraphicData *)callbackdata;\n\n\t// check size\n\tdata->OrgW = w;\n\tdata->OrgH = h;\n\tif(data->DesW && w < data->DesW) w = data->DesW;\n\tif(data->DesH && h < data->DesH) h = data->DesH;\n\tdata->BufW = w;\n\tdata->BufH = h;\n\n\t// create buffer\n\tif(data->Type == lgtMask)\n\t{\n\t\t// mask ( _m ) load\n\n\t\t// check the image previously loaded\n\t\tif(data->Dest->GetWidth() != w || data->Dest->GetHeight() != h)\n\t\t\tTVPThrowExceptionMessage(TVPMaskSizeMismatch);\n\n\t\t// allocate line buffer\n\t\tdata->Buffer = new tjs_uint8 [w];\n\t\tdata->Dest->IsOpaque = false;\n\t\treturn w;\n\t}\n\telse\n\t{\n\t\t// normal load or province load\n\t\tif (!data->Dest) {\n\t\t\tdata->Dest = new tTVPBitmap(w, h, data->Type == lgtFullColor ? 32 : 8);\n\t\t} else if (data->Dest->GetWidth() != w || data->Dest->GetHeight() != h) {\n\t\t\tdata->Dest->Release();\n\t\t\tdata->Dest = new tTVPBitmap(w, h, data->Type == lgtFullColor ? 32 : 8);\n\t\t}\n\t\tswitch(fmt) {\n\t\tcase gpfLuminance:\n\t\tcase gpfRGB:\n\t\t\tdata->Dest->IsOpaque = true; break;\n\t\tcase gpfPalette:\n\t\tcase gpfRGBA:\n\t\t\tdata->Dest->IsOpaque = false; break;\n\t\t}\n#if 0\n\t\tdata->Dest->Recreate(w, h, data->Type!=lgtFullColor?8:32);\n#endif\n\t\treturn data->Dest->GetPitch();\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void * TVPLoadGraphic_ScanLineCallback(void *callbackdata, tjs_int y)\n{\n\ttTVPLoadGraphicData * data = (tTVPLoadGraphicData *)callbackdata;\n\n\tif(y >= 0)\n\t{\n\t\t// query of line buffer\n\n\t\tdata->ScanLineNum = y;\n\t\tif(data->Type == lgtMask)\n\t\t{\n\t\t\t// mask\n\t\t\treturn data->Buffer;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// return the scanline for writing\n\t\t\treturn data->Dest->GetScanLine(y);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// y==-1 indicates the buffer previously returned was written\n\n\t\tif(data->Type == lgtMask)\n\t\t{\n\t\t\t// mask\n\n\t\t\t\t// tile for horizontal direction\n\t\t\t\ttjs_uint i;\n\t\t\tfor(i = data->OrgW; i<data->BufW; i+=data->OrgW)\n\t\t\t\t{\n\t\t\t\t\ttjs_uint w = data->BufW - i;\n\t\t\t\t\tw = w > data->OrgW ? data->OrgW : w;\n\t\t\t\tmemcpy(data->Buffer + i, data->Buffer, w);\n\t\t\t\t}\n\n\t\t\t\t// bind mask buffer to main image buffer ( and tile for vertical )\n\t\t\tfor(i = data->ScanLineNum; i<data->BufH; i+=data->OrgH)\n\t\t\t\t{\n\t\t\t\t\tTVPBindMaskToMain(\n\t\t\t\t\t(tjs_uint32*)data->Dest->GetScanLine(i),\n\t\t\t\t\tdata->Buffer, data->BufW);\n\t\t\t\t}\n\t\t\treturn NULL;\n\t\t\t}\n\t\telse if(data->Type == lgtFullColor)\n\t\t{\n\t\t\ttjs_uint32 * sl =\n\t\t\t\t(tjs_uint32*)data->Dest->GetScanLine(data->ScanLineNum);\n\t\t\tif((data->ColorKey & 0xff000000) == 0x00000000)\n\t\t\t{\n\t\t\t\t\t// make alpha from color key\n\t\t\t\t\tTVPMakeAlphaFromKey(\n\t\t\t\t\tsl,\n\t\t\t\t\t\tdata->BufW,\n\t\t\t\t\t\tdata->ColorKey);\n\t\t\t\t}\n\n\t\t\t\t\t// tile for horizontal direction\n\t\t\t\t\ttjs_uint i;\n\t\t\tfor(i = data->OrgW; i<data->BufW; i+=data->OrgW)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_uint w = data->BufW - i;\n\t\t\t\t\t\tw = w > data->OrgW ? data->OrgW : w;\n\t\t\t\t\t\tmemcpy(sl + i, sl, w * sizeof(tjs_uint32));\n\t\t\t\t\t}\n\n\t\t\t\t\t// tile for vertical direction\n\t\t\tfor(i = data->ScanLineNum + data->OrgH; i<data->BufH; i+=data->OrgH)\n\t\t\t\t\t{\n\t\t\t\t\t\tmemcpy(\n\t\t\t\t\t\t\t(tjs_uint32*)data->Dest->GetScanLine(i),\n\t\t\t\t\t\t\tsl,\n\t\t\t\t\tdata->BufW * sizeof(tjs_uint32) );\n\t\t\t\t\t}\n\n\t\t\treturn NULL;\n\t\t}\n\t\telse if(data->Type == lgtPalGray)\n\t\t{\n\t\t\t// nothing to do\n\t\t\tif(data->OrgW < data->BufW || data->OrgH < data->BufH)\n\t\t\t{\n\t\t\t\t\ttjs_uint8 * sl =\n\t\t\t\t\t\t(tjs_uint8*)data->Dest->GetScanLine(data->ScanLineNum);\n\t\t\t\t\ttjs_uint i;\n\n\t\t\t\t\t// tile for horizontal direction\n\t\t\t\tfor(i = data->OrgW; i<data->BufW; i+=data->OrgW)\n\t\t\t\t\t{\n\t\t\t\t\t\ttjs_uint w = data->BufW - i;\n\t\t\t\t\t\tw = w > data->OrgW ? data->OrgW : w;\n\t\t\t\t\t\tmemcpy(sl + i, sl, w * sizeof(tjs_uint8));\n\t\t\t\t\t}\n\n\t\t\t\t\t// tile for vertical direction\n\t\t\t\tfor(i = data->ScanLineNum + data->OrgH; i<data->BufH; i+=data->OrgH)\n\t\t\t\t\t{\n\t\t\t\t\t\tmemcpy(\n\t\t\t\t\t\t\t(tjs_uint8*)data->Dest->GetScanLine(i),\n\t\t\t\t\t\t\tsl,\n\t\t\t\t\t\t\tdata->BufW * sizeof(tjs_uint8));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\treturn NULL;\n\t\t}\n\t}\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\nstatic void TVPLoadGraphic_MetaInfoPushCallback(void *callbackdata,\n\tconst ttstr & name, const ttstr & value)\n{\n\ttTVPLoadGraphicData * data = (tTVPLoadGraphicData *)callbackdata;\n\n\tif(data->NeedMetaInfo)\n\t{\n\t\tif(!data->MetaInfo) data->MetaInfo = new std::vector<tTVPGraphicMetaInfoPair>();\n\t\tdata->MetaInfo->emplace_back(name, value);\n\t}\n}\n//---------------------------------------------------------------------------\n//static int _USERENTRY TVPColorCompareFunc(const void *_a, const void *_b)\nstatic int TVPColorCompareFunc(const void *_a, const void *_b)\n{\n\ttjs_uint32 a = *(const tjs_uint32*)_a;\n\ttjs_uint32 b = *(const tjs_uint32*)_b;\n\n\tif(a<b) return -1;\n\tif(a==b) return 0;\n\treturn 1;\n}\n//---------------------------------------------------------------------------\nstatic void TVPMakeAlphaFromAdaptiveColor(tTVPBitmap *dest)\n{\n\t// make adaptive color key and make alpha from it.\n\t// adaptive color key is most used(popular) color at first line of the\n\t// graphic.\n\tif(!dest->Is32bit()) return;\n\n\t// copy first line to buffer\n\ttjs_int w = dest->GetWidth();\n\ttjs_int pitch = std::abs(dest->GetPitch());\n\ttjs_uint32 * buffer = new tjs_uint32[pitch];\n\n\ttry\n\t{\n\t\tconst void *d = dest->GetScanLine(0);\n\n\t\tmemcpy(buffer, d, pitch);\n\t\ttjs_int i;\n\t\tfor(i = w -1; i>=0; i--) buffer[i] &= 0xffffff;\n\t\tbuffer[w] = (tjs_uint32)-1; // a sentinel\n\n\t\t// sort by color\n\t\tqsort(buffer, dest->GetWidth(), sizeof(tjs_uint32), TVPColorCompareFunc);\n\n\t\t// find most used color\n\t\ttjs_int maxlen = 0;\n\t\ttjs_uint32 maxlencolor = 0;\n\t\ttjs_uint32 pcolor = (tjs_uint32)-1;\n\t\ttjs_int l = 0;\n\t\tfor(i = 0; i< w+1; i++)\n\t\t{\n\t\t\tif(buffer[i] != pcolor)\n\t\t\t{\n\t\t\t\tif(maxlen < l)\n\t\t\t\t{\n\t\t\t\t\tmaxlen = l;\n\t\t\t\t\tmaxlencolor = pcolor;\n\t\t\t\t\tl = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tl++;\n\t\t\t}\n\t\t\tpcolor = buffer[i];\n\t\t}\n\n\t\tif(maxlencolor == (tjs_uint32)-1)\n\t\t{\n\t\t\t// may color be not found...\n\t\t\tmaxlencolor = 0; // black is a default colorkey\n\t\t}\n\n\t\t// make alpha from maxlencolor\n\t\ttjs_int h;\n\t\tfor(h = dest->GetHeight()-1; h>=0; h--)\n\t\t{\n\t\t\tTVPMakeAlphaFromKey((tjs_uint32*)dest->GetScanLine(h),\n\t\t\t\tw, maxlencolor);\n\n\t\t}\n\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] buffer;\n\t\tthrow;\n\t}\n\n\tdelete [] buffer;\n}\n//---------------------------------------------------------------------------\nstatic void TVPDoAlphaColorMat(tTVPBitmap *dest, tjs_uint32 color)\n{\n\t// Do alpha matting.\n\t// 'mat' means underlying color of the image. This function piles\n\t// specified color under the image, then blend. The output image\n\t// will be totally opaque. This function always assumes the image\n\t// has pixel value for alpha blend mode, not additive alpha blend mode.\n\tif(!dest->Is32bit()) return;\n\n\ttjs_int w = dest->GetWidth();\n\ttjs_int h = dest->GetHeight();\n\n\tfor(tjs_int y = 0; y < h; y++)\n\t{\n\t\ttjs_uint32 * buffer = (tjs_uint32*)dest->GetScanLine(y);\n\t\tTVPAlphaColorMat(buffer, color, w);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPMetaInfoPairsToDictionary(\n\tstd::vector<tTVPGraphicMetaInfoPair> *vec)\n{\n\tif(!vec) return NULL;\n\tstd::vector<tTVPGraphicMetaInfoPair>::iterator i;\n\tiTJSDispatch2 *dic = TJSCreateDictionaryObject();\n\ttry\n\t{\n\t\tfor(i = vec->begin(); i != vec->end(); i++)\n\t\t{\n\t\t\ttTJSVariant val(i->Value);\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, i->Name.c_str(), 0,\n\t\t\t\t&val, dic);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdic->Release();\n\t\tthrow;\n\t}\n\treturn dic;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Graphics Cache Management\n//---------------------------------------------------------------------------\nbool TVPAllocGraphicCacheOnHeap = false;\n\t// this allocates graphic cache's store memory on heap, rather than\n\t// sharing bitmap object. ( since sucking win9x cannot have so many bitmap\n\t// object at once, WinNT/2000 is ok. )\n\t// this will take more time for memory copying.\n//---------------------------------------------------------------------------\nstruct tTVPGraphicsSearchData\n{\n\tttstr Name;\n\ttjs_int32 KeyIdx; // color key index\n\ttTVPGraphicLoadMode Mode; // image mode\n\ttjs_uint DesW; // desired width ( 0 for original size )\n\ttjs_uint DesH; // desired height ( 0 for original size )\n\n\tbool operator == (const tTVPGraphicsSearchData &rhs) const\n\t{\n\t\treturn KeyIdx == rhs.KeyIdx && Mode == rhs.Mode &&\n\t\t\tName == rhs.Name && DesW == rhs.DesW && DesH == rhs.DesH;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPGraphicsSearchHashFunc\n{\npublic:\n\tstatic tjs_uint32 Make(const tTVPGraphicsSearchData &val)\n\t{\n\t\ttjs_uint32 v = tTJSHashFunc<ttstr>::Make(val.Name);\n\n\t\tv ^= val.KeyIdx + (val.KeyIdx >> 23);\n\t\tv ^= (val.Mode << 30);\n\t\tv ^= val.DesW + (val.DesW >> 8);\n\t\tv ^= val.DesH + (val.DesH >> 8);\n\t\treturn v;\n\t}\n};\n//---------------------------------------------------------------------------\nclass tTVPGraphicImageData\n{\nprivate:\n    tTVPBitmap *Bitmap;\n    iTVPTexture2D *Texture = nullptr;\n\ttjs_uint8 * RawData;\n\ttjs_int Width;\n\ttjs_int Height;\n\ttjs_int PixelSize;\n\npublic:\n\tttstr ProvinceName;\n\n\tstd::vector<tTVPGraphicMetaInfoPair> * MetaInfo;\n\nprivate:\n\ttjs_int RefCount;\n\ttjs_uint Size;\n\npublic:\n\ttTVPGraphicImageData()\n\t{\n\t\tRefCount = 1; Size = 0; Bitmap = NULL; RawData = NULL;\n\t\tMetaInfo = nullptr;\n\t}\n\t~tTVPGraphicImageData()\n\t{\n\t\tif (Bitmap) Bitmap->Release();\n\t\tif (Texture) Texture->Release();\n\t\tif(RawData) delete [] RawData;\n\t\tif(MetaInfo) delete MetaInfo;\n\t}\n\n\tvoid AssignBitmap(tTVPBitmap *bmp)\n\t{\n\t\tif(Bitmap) delete Bitmap, Bitmap = NULL;\n\t\tif(RawData) delete [] RawData, RawData = NULL;\n\t\tif (Texture) Texture->Release(), Texture = nullptr;\n\n\t\tWidth = bmp->GetWidth();\n\t\tHeight = bmp->GetHeight();\n\t\tPixelSize = bmp->GetBPP() / 8;\n\t\tSize =  Width*Height*PixelSize;\n\n\t\tif(!TVPAllocGraphicCacheOnHeap)\n\t\t{\n\t\t\t// simply assin to Bitmap\n\t\t\tBitmap = bmp;\n            Bitmap->AddRef();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// allocate heap and copy to it\n\t\t\ttjs_int h = Height;\n\t\t\tRawData = new tjs_uint8 [ Size ];\n\t\t\ttjs_uint8 *p = RawData;\n\t\t\ttjs_int rawpitch = Width * PixelSize;\n\t\t\tfor(h--; h>=0; h--)\n\t\t\t{\n\t\t\t\tmemcpy(p, bmp->GetScanLine(h), rawpitch);\n\t\t\t\tp += rawpitch;\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid AssignTexture(iTVPTexture2D *tex) {\n\t\tif (Bitmap) delete Bitmap, Bitmap = NULL;\n\t\tif (RawData) delete[] RawData, RawData = NULL;\n\t\tif (Texture) Texture->Release(), Texture = nullptr;\n\n\t\tWidth = tex->GetWidth();\n\t\tHeight = tex->GetHeight();\n\t\tPixelSize = (int)tex->GetFormat();\n\t\tSize = Width*Height*PixelSize;\n\n\t\tTexture = tex;\n\t\tTexture->AddRef();\n\t}\n\n\tvoid AssignToBitmap(tTVPBaseBitmap *bmp) const\n\t{\n\t\tif(!TVPAllocGraphicCacheOnHeap)\n\t\t{\n\t\t\t// simply assign to Bitmap\n\t\t\tif(Bitmap) bmp->AssignBitmap(Bitmap);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// copy from the rawdata heap\n\t\t\tif(RawData)\n\t\t\t{\n\t\t\t\tbmp->Recreate(Width, Height, PixelSize==4?32:8);\n\t\t\t\ttjs_int h = Height;\n\t\t\t\ttjs_uint8 *p = RawData;\n\t\t\t\ttjs_int rawpitch = Width * PixelSize;\n\t\t\t\tfor(h--; h>=0; h--)\n\t\t\t\t{\n\t\t\t\t\tmemcpy(bmp->GetScanLineForWrite(h), p, rawpitch);\n\t\t\t\t\tp += rawpitch;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid AssignToTexture(iTVPBaseBitmap *dst)\n    {\n        if(!Texture && Bitmap) {\n            int bmpw = Bitmap->GetWidth(), bmph = Bitmap->GetHeight();\n            TVPTextureFormat::e format;\n            switch(PixelSize) {\n            case 1:\n                format = TVPTextureFormat::Gray;\n                break;\n            case 3:\n                format = TVPTextureFormat::RGB;\n                break;\n            case 4:\n                format = TVPTextureFormat::RGBA;\n                break;\n            default:\n                return;\n            }\n\t\t\tTexture = TVPGetRenderManager()->CreateTexture2D(Bitmap);\n\t\t\tif (Bitmap) Bitmap->Release(), Bitmap = nullptr;\n\t\t\tif (RawData) delete[] RawData, RawData = nullptr;\n        }\n\n        if (Texture)\n            dst->AssignTexture(Texture);\n    }\n\n\ttjs_uint GetSize() const { return Size; }\n\n\tvoid AddRef() { RefCount ++; }\n\tvoid Release()\n\t{\n\t\tif(RefCount == 1)\n\t\t{\n\t\t\tdelete this;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tRefCount--;\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\ntypedef tTJSRefHolder<tTVPGraphicImageData> tTVPGraphicImageHolder;\n\ntypedef\ntTJSHashTable<tTVPGraphicsSearchData, tTVPGraphicImageHolder, tTVPGraphicsSearchHashFunc>\n\ttTVPGraphicCache;\ntTVPGraphicCache TVPGraphicCache;\nstatic bool TVPGraphicCacheEnabled = false;\nstatic tjs_uint64 TVPGraphicCacheLimit = 0;\nstatic tjs_uint64 TVPGraphicCacheTotalBytes = 0;\ntjs_uint64 TVPGraphicCacheSystemLimit = 0; // maximum possible value of  TVPGraphicCacheLimit\n//---------------------------------------------------------------------------\ntjs_uint64 TVPGetGraphicCacheTotalBytes() {\n\treturn TVPGraphicCacheTotalBytes;\n}\n//---------------------------------------------------------------------------\nstatic void TVPCheckGraphicCacheLimit()\n{\n\twhile(TVPGraphicCacheTotalBytes > TVPGraphicCacheLimit)\n\t{\n\t\t// chop last graphics\n\t\ttTVPGraphicCache::tIterator i;\n\t\ti = TVPGraphicCache.GetLast();\n\t\tif(!i.IsNull())\n\t\t{\n\t\t\ttjs_uint size = i.GetValue().GetObjectNoAddRef()->GetSize();\n\t\t\tTVPGraphicCacheTotalBytes -= size;\n\t\t\tTVPGraphicCache.ChopLast(1);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPClearGraphicCache()\n{\n\tTVPGraphicCache.Clear();\n\tTVPGraphicCacheTotalBytes = 0;\n}\nstatic tTVPAtExit\n\tTVPUninitMessageLoad(TVP_ATEXIT_PRI_RELEASE, TVPClearGraphicCache);\n//---------------------------------------------------------------------------\nstruct tTVPClearGraphicCacheCallback : public tTVPCompactEventCallbackIntf\n{\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\tif(level >= TVP_COMPACT_LEVEL_MINIMIZE)\n\t\t{\n\t\t\t// clear the font cache on application minimize\n\t\t\tTVPClearGraphicCache();\n\t\t}\n\t}\n} static TVPClearGraphicCacheCallback;\nstatic bool TVPClearGraphicCacheCallbackInit = false;\n//---------------------------------------------------------------------------\nvoid TVPPushGraphicCache( const ttstr& nname, tTVPBitmap* bmp, std::vector<tTVPGraphicMetaInfoPair>* meta )\n{\n\tif( TVPGraphicCacheEnabled ) {\n\t\t// graphic compact initialization\n\t\tif(!TVPClearGraphicCacheCallbackInit)\n\t\t{\n\t\t\tTVPAddCompactEventHook(&TVPClearGraphicCacheCallback);\n\t\t\tTVPClearGraphicCacheCallbackInit = true;\n\t\t}\n\n\t\ttTVPGraphicImageData* data = NULL;\n\t\ttry {\n\t\t\ttjs_uint32 hash;\n\t\t\ttTVPGraphicsSearchData searchdata;\n\n\t\t\tsearchdata.Name = nname;\n\t\t\tsearchdata.KeyIdx = TVP_clNone;\n\t\t\tsearchdata.Mode = glmNormal;\n\t\t\tsearchdata.DesW = 0;\n\t\t\tsearchdata.DesH = 0;\n\n\t\t\thash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\t\tdata = new tTVPGraphicImageData();\n\t\t\tdata->AssignBitmap(bmp);\n\t\t\tdata->ProvinceName = TJS_W(\"\");\n\t\t\tdata->MetaInfo = meta;\n\t\t\tmeta = NULL;\n\n\t\t\t// check size limit\n\t\t\tTVPCheckGraphicCacheLimit();\n\n\t\t\t// push into hash table\n\t\t\ttjs_uint datasize = data->GetSize();\n\t\t\tTVPGraphicCacheTotalBytes += datasize;\n\t\t\ttTVPGraphicImageHolder holder(data);\n\t\t\tTVPGraphicCache.AddWithHash(searchdata, hash, holder);\n\t\t} catch(...) {\n\t\t\tif(meta) delete meta;\n\t\t\tif(data) data->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(data) data->Release();\n\t} else {\n\t\tif( meta ) delete meta;\n\t}\n}\n//---------------------------------------------------------------------------\nbool TVPCheckImageCache( const ttstr& nname, tTVPBaseBitmap* dest, tTVPGraphicLoadMode mode, tjs_uint dw, tjs_uint dh, tjs_int32 keyidx, iTJSDispatch2** metainfo )\n{\n\ttjs_uint32 hash;\n\ttTVPGraphicsSearchData searchdata;\n\tif(TVPGraphicCacheEnabled)\n\t{\n\t\tsearchdata.Name = nname;\n\t\tsearchdata.KeyIdx = keyidx;\n\t\tsearchdata.Mode = mode;\n\t\tsearchdata.DesW = dw;\n\t\tsearchdata.DesH = dh;\n\n\t\thash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\ttTVPGraphicImageHolder * ptr =\n\t\t\tTVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n\t\tif(ptr)\n\t\t{\n\t\t\t// found in cache\n\t\t\tptr->GetObjectNoAddRef()->AssignToBitmap(dest);\n\t\t\tif(metainfo)\n\t\t\t\t*metainfo = TVPMetaInfoPairsToDictionary(ptr->GetObjectNoAddRef()->MetaInfo);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\n// ������������\nbool TVPHasImageCache( const ttstr& nname, tTVPGraphicLoadMode mode, tjs_uint dw, tjs_uint dh, tjs_int32 keyidx )\n{\n\ttjs_uint32 hash;\n\ttTVPGraphicsSearchData searchdata;\n\tif(TVPGraphicCacheEnabled)\n\t{\n\t\tsearchdata.Name = nname;\n\t\tsearchdata.KeyIdx = keyidx;\n\t\tsearchdata.Mode = mode;\n\t\tsearchdata.DesW = dw;\n\t\tsearchdata.DesH = dh;\n\n\t\thash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\ttTVPGraphicImageHolder * ptr =\n\t\t\tTVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n\t\tif(ptr)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\ntTVPGraphicHandlerType* TVPFindGraphicLoadHandler(ttstr &_name, ttstr *maskname, ttstr *provincename) {\n\t// graphic compact initialization\n\tif (!TVPClearGraphicCacheCallbackInit)\n\t{\n\t\tTVPAddCompactEventHook(&TVPClearGraphicCacheCallback);\n\t\tTVPClearGraphicCacheCallbackInit = true;\n\t}\n\n\t// search according with its extension\n\ttjs_int namelen = _name.GetLen();\n\tttstr name(_name);\n\n\tttstr ext = TVPExtractStorageExt(name);\n\tint extlen = ext.GetLen();\n\ttTVPGraphicHandlerType * handler;\n\n\tif (ext.IsEmpty()) {\n\t\t// missing extension\n\t\t// suggest registered extensions\n\t\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\t\tfor (i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/)\n\t\t{\n\t\t\tttstr newname = name + i.GetKey();\n\t\t\tif (TVPIsExistentStorage(newname))\n\t\t\t{\n\t\t\t\t// file found\n\t\t\t\tname = newname;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\t\tif (i.IsNull())\n\t\t{\n\t\t\t// not found\n\t\t\tttstr fmt = LocaleConfigManager::GetInstance()->GetText(\"err_cannot_suggest_graph_ext\");\n\t\t\tTVPThrowExceptionMessage(fmt.c_str(), name);\n\t\t}\n\n\t\thandler = &i.GetValue();\n\t} else {\n\t\thandler = TVPGraphicType.Hash.Find(ext);\n\t\tif (!handler) {\n\t\t\tstatic const ttstr ext_bmp(TJS_W(\".bmp\"));\n\t\t\thandler = TVPGraphicType.Hash.Find(ext_bmp);\n\t\t}\n\t}\n\n\tif (!handler) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, name);\n\tttstr retname(name);\n\n\tif (maskname) {\n\t\t// mask image handling ( addding _m suffix with the filename )\n\t\twhile (true) {\n\t\t\tname = ttstr(_name, namelen - extlen) + TJS_W(\"_m\") + ext;\n\t\t\tif (ext.IsEmpty()) {\n\t\t\t\t// missing extension\n\t\t\t\t// suggest registered extensions\n\t\t\t\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\t\t\t\tfor (i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/) {\n\t\t\t\t\tttstr newname = name;\n\t\t\t\t\tnewname += i.GetKey();\n\t\t\t\t\tif (TVPIsExistentStorage(newname))\n\t\t\t\t\t{\n\t\t\t\t\t\t// file found\n\t\t\t\t\t\tname = newname;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tif (i.IsNull()) {\n\t\t\t\t\t// not found\n\t\t\t\t\tmaskname->Clear();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t*maskname = name;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tif (!TVPIsExistentStorage(name)) {\n\t\t\t\t\t// not found\n\t\t\t\t\text.Clear();\n\t\t\t\t\tcontinue; // retry searching\n\t\t\t\t}\n\t\t\t\t*maskname = name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (provincename) {\n\t\t// set province name\n\t\t*provincename = ttstr(_name, namelen - extlen) + TJS_W(\"_p\");\n\n\t\t// search extensions\n\t\ttTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n\t\tfor (i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/) {\n\t\t\tttstr newname = *provincename + i.GetKey();\n\t\t\tif (TVPIsExistentStorage(newname))\n\t\t\t{\n\t\t\t\t// file found\n\t\t\t\t*provincename = newname;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\t\tif (i.IsNull()) {\n\t\t\t// not found\n\t\t\tprovincename->Clear();\n\t\t}\n\t}\n\n\t_name = retname;\n\treturn handler;\n}\n//---------------------------------------------------------------------------\nstatic tTVPBitmap* TVPInternalLoadBitmap(const ttstr &_name,\n\ttjs_uint32 keyidx, tjs_uint desw, tjs_int desh, std::vector<tTVPGraphicMetaInfoPair> * * MetaInfo,\n\t\ttTVPGraphicLoadMode mode, ttstr *provincename)\n{\n\t// name must be normalized.\n\t// if \"provincename\" is non-null, this function set it to province storage\n\t// name ( with _p suffix ) for convinience.\n\t// desw and desh are desired size. if the actual picture is smaller than\n\t// the given size, the graphic is to be tiled. give 0,0 to obtain default\n\t// size graphic.\n\n\tttstr name(_name), maskname;\n\ttTVPGraphicHandlerType * handler = TVPFindGraphicLoadHandler(name, &maskname, mode == glmNormal ? provincename : nullptr);\n\ttTVPStreamHolder holder(name); // open a storage named \"name\"\n\n\t// load the image\n\ttTVPLoadGraphicData data;\n\tdata.Dest = nullptr;\n\tdata.ColorKey = keyidx;\n\tdata.Type = mode == glmNormal? lgtFullColor : lgtPalGray;\n\tdata.Name = name;\n\tdata.DesW = desw;\n\tdata.DesH = desh;\n\tdata.NeedMetaInfo = true;\n\tdata.MetaInfo = NULL;\n\n\tbool keyadapt = (keyidx == TVP_clAdapt);\n\tbool doalphacolormat = TVP_Is_clAlphaMat(keyidx);\n\ttjs_uint32 alphamatcolor = TVP_get_clAlphaMat(keyidx);\n\n\tif(TVP_Is_clPalIdx(keyidx))\n\t{\n\t\t// pass the palette index number to the handler.\n\t\t// ( since only Graphic Loading Handler can process the palette information )\n\t\tkeyidx = TVP_get_clPalIdx(keyidx);\n\t}\n\telse\n\t{\n\t\tkeyidx = -1;\n\t}\n\n\thandler->Load(handler->FormatData, (void*)&data, TVPLoadGraphic_SizeCallback,\n\t\tTVPLoadGraphic_ScanLineCallback, TVPLoadGraphic_MetaInfoPushCallback,\n\t\tholder.Get(), keyidx, mode);\n\n\t*MetaInfo = data.MetaInfo;\n\n\tif(keyadapt && mode == glmNormal)\n\t{\n\t\t// adaptive color key\n\t\tTVPMakeAlphaFromAdaptiveColor(data.Dest);\n\t}\n\n\tif(mode != glmNormal) return data.Dest;\n\n\tif(!maskname.IsEmpty() && (handler = TVPFindGraphicLoadHandler(maskname, nullptr, nullptr)))\n\t{\n\t\t// open the mask file\n\t\tholder.Open(maskname);\n\n\t\t// fill \"data\"'s member\n\t    data.Type = lgtMask;\n//\t    data.Name = name;\n\t\tdata.Buffer = NULL;\n\t\tdata.DesW = desw;\n\t\tdata.DesH = desh;\n\t\tdata.NeedMetaInfo = false;\n\n\t    try\n\t    {\n\t\t\t// load image via handler\n\t\t\thandler->Load(handler->FormatData, (void*)&data,\n\t\t\t\tTVPLoadGraphic_SizeCallback, TVPLoadGraphic_ScanLineCallback,\n\t\t\t\tNULL,\n\t\t\t\tholder.Get(), -1, glmGrayscale);\n\t    }\n\t\tcatch(...)\n\t    {\n\t\t\tif(data.Buffer) delete [] data.Buffer;\n            if(data.Dest) data.Dest->Release();\n\t\t\tthrow;\n\t\t}\n\n\t    if(data.Buffer) delete [] data.Buffer;\n\t}\n\n\t// do color matting\n\tif(doalphacolormat)\n\t{\n\t\t// alpha color mat\n\t\tTVPDoAlphaColorMat(data.Dest, alphamatcolor);\n\t}\n\n\treturn data.Dest;\n}\n//---------------------------------------------------------------------------\niTVPTexture2D* TVPLoadPVRv3(tTJSBinaryStream *s, const std::function<void(const ttstr&, const tTJSVariant&)> &cb);\nstatic iTVPTexture2D *TVPInternalLoadTexture(const ttstr &_name,\n\tstd::vector<tTVPGraphicMetaInfoPair> * * MetaInfo, ttstr *provincename) {\n\tttstr name(_name), maskname;\n\ttTVPGraphicHandlerType * handler = TVPFindGraphicLoadHandler(name, &maskname, provincename);\n\tif (!maskname.IsEmpty()) {\n\t\t// mask merge is not supported\n\t\treturn nullptr;\n\t}\n\ttTVPStreamHolder holder(name);\n\treturn TVPLoadPVRv3(holder.Get(), [MetaInfo](const ttstr& k, const tTJSVariant& v) {\n\t\tif (!*MetaInfo) *MetaInfo = new std::vector<tTVPGraphicMetaInfoPair>;\n\t\t(*MetaInfo)->emplace_back(k, v);\n\t});\n}\n\nvoid TVPLoadGraphicProvince(tTVPBaseBitmap *dest, const ttstr &name, tjs_int keyidx,\n    tjs_uint desw, tjs_uint desh)\n{\n    tjs_uint32 hash;\n    ttstr nname = TVPNormalizeStorageName(name);\n    tTVPGraphicsSearchData searchdata;\n\tif (TVPGraphicCacheEnabled) {\n        searchdata.Name = nname;\n        searchdata.KeyIdx = keyidx;\n        searchdata.Mode = glmPalettized;\n        searchdata.DesW = desw;\n        searchdata.DesH = desh;\n\n        hash = tTVPGraphicCache::MakeHash(searchdata);\n\n        tTVPGraphicImageHolder * ptr =\n            TVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n        if (ptr) {\n            // found in cache\n            ptr->GetObjectNoAddRef()->AssignToBitmap(dest);\n            return;\n        }\n    }\n    // not found\n\n    // load into dest\n\ttTVPGraphicImageData * data = nullptr;\n\n    ttstr pn;\n\tstd::vector<tTVPGraphicMetaInfoPair> * mi = nullptr;\n    try {\n        tTVPBitmap *bmp = TVPInternalLoadBitmap(nname, keyidx, desw, desh, &mi, glmPalettized, &pn);\n        dest->AssignBitmap(bmp);\n        if (TVPGraphicCacheEnabled) {\n            data = new tTVPGraphicImageData();\n            data->AssignBitmap(bmp);\n            data->ProvinceName = pn;\n            data->MetaInfo = mi; // now mi is managed under tTVPGraphicImageData\n\t\t\tmi = nullptr;\n\n            // check size limit\n            TVPCheckGraphicCacheLimit();\n\n            // push into hash table\n            tjs_uint datasize = data->GetSize();\n            //\t\t\tif(datasize < TVPGraphicCacheLimit)\n            //\t\t\t{\n            TVPGraphicCacheTotalBytes += datasize;\n            tTVPGraphicImageHolder holder(data);\n            TVPGraphicCache.AddWithHash(searchdata, hash, holder);\n            //\t\t\t}\n        }\n        bmp->Release();\n    }\n    catch (...) {\n        if (mi) delete mi;\n        if (data) data->Release();\n        throw;\n    }\n\n    if (mi) delete mi;\n    if (data) data->Release();\n}\n\n//---------------------------------------------------------------------------\n// TVPLoadGraphic (to texture), return size\n//---------------------------------------------------------------------------\nint TVPLoadGraphic(iTVPBaseBitmap *dest, const ttstr &name, tjs_int32 keyidx,\n\ttjs_uint desw, tjs_uint desh,\n\ttTVPGraphicLoadMode mode, ttstr *provincename, iTJSDispatch2 ** metainfo)\n{\n\t// loading with cache management\n\tttstr nname = TVPNormalizeStorageName(name);\n\ttjs_uint32 hash;\n\ttTVPGraphicsSearchData searchdata;\n\n\tif(TVPGraphicCacheEnabled)\n\t{\n\t\tsearchdata.Name = nname;\n\t\tsearchdata.KeyIdx = keyidx;\n\t\tsearchdata.Mode = mode;\n\t\tsearchdata.DesW = desw;\n\t\tsearchdata.DesH = desh;\n\n\t\thash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\ttTVPGraphicImageHolder * ptr =\n\t\t\tTVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n\t\tif(ptr)\n\t\t{\n\t\t\t// found in cache\n\t\t\tif (dest)\n\t\t\t\tptr->GetObjectNoAddRef()->AssignToTexture(dest);\n\t\t\tif(provincename) *provincename = ptr->GetObjectNoAddRef()->ProvinceName;\n\t\t\tif(metainfo)\n\t\t\t\t*metainfo = TVPMetaInfoPairsToDictionary(ptr->GetObjectNoAddRef()->MetaInfo);\n            return ptr->GetObjectNoAddRef()->GetSize();\n\t\t}\n\t}\n\n\t// not found\n#if defined( WIN32 )&& defined(_DEBUG)\n\tTVPAddLog(TJS_W(\"load graphic: \") + nname);\n#endif\n\n\t// load into dest\n\ttTVPGraphicImageData * data = NULL;\n\n\tttstr pn;\n\tstd::vector<tTVPGraphicMetaInfoPair> * mi = nullptr;\n    int ret = 0;\n\ttry\n\t{\n\t\ttTVPBitmap *bmp = nullptr;\n\t\tiTVPTexture2D *texture = nullptr;\n\t\tif (mode == glmNormal && keyidx == TVP_clNone && !desw && !desh) {\n\t\t\ttexture = TVPInternalLoadTexture(nname, &mi, &pn);\n\t\t}\n\t\tif (!texture) {\n\t\t\tbmp = TVPInternalLoadBitmap(nname, keyidx, desw, desh, &mi, mode, &pn);\n\t\t}\n\n\t\tif(provincename) *provincename = pn;\n\t\tif(metainfo)\n\t\t\t*metainfo = TVPMetaInfoPairsToDictionary(mi);\n\n\t\tif(TVPGraphicCacheEnabled)\n\t\t{\n\t\t\tdata = new tTVPGraphicImageData();\n\t\t\tif (texture) {\n\t\t\t\tdata->AssignTexture(texture);\n\t\t\t} else {\n\t\t\t\tdata->AssignBitmap(bmp);\n\t\t\t}\n            if(dest) {\n                data->AssignToTexture(dest);\n            }\n\t\t\tdata->ProvinceName = pn;\n\t\t\tdata->MetaInfo = mi; // now mi is managed under tTVPGraphicImageData\n\t\t\tmi = NULL;\n\n\t\t\t// check size limit\n\t\t\tTVPCheckGraphicCacheLimit();\n\n\t\t\t// push into hash table\n\t\t\ttjs_uint datasize = data->GetSize();\n//\t\t\tif(datasize < TVPGraphicCacheLimit)\n//\t\t\t{\n\t\t\t\tTVPGraphicCacheTotalBytes += datasize;\n\t\t\t\ttTVPGraphicImageHolder holder(data);\n\t\t\t\tTVPGraphicCache.AddWithHash(searchdata, hash, holder);\n//\t\t\t}\n\t\t} else if(dest) {\n\t\t\ttTVPGraphicImageData data;\n\t\t\tif (texture) {\n\t\t\t\tdata.AssignTexture(texture);\n\t\t\t} else {\n\t\t\t\tdata.AssignBitmap(bmp);\n\t\t\t}\n\t\t\tdata.AssignToTexture(dest);\n\t\t}\n\t\tif (texture) {\n\t\t\tret = texture->GetInternalWidth() * texture->GetInternalHeight() * 4; // assume that always RGBA\n\t\t\ttexture->Release();\n\t\t} else {\n\t\t\tret = bmp->GetWidth() * bmp->GetHeight() * bmp->GetBPP() / 8;\n\t\t\tbmp->Release();\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(mi) delete mi;\n\t\tif(data) data->Release();\n\t\tthrow;\n\t}\n\n\tif(mi) delete mi;\n\tif(data) data->Release();\n\n    return ret;\n}\n//---------------------------------------------------------------------------\n#ifdef _MSC_VER\nextern \"C\"\n__declspec(dllimport) int __stdcall WideCharToMultiByte(\nunsigned int CodePage,\nunsigned long dwFlags,\nconst wchar_t* lpWideCharStr,\nint cchWideChar,\nchar *lpMultiByteStr,\nint cbMultiByte,\nvoid* lpDefaultChar,\nint* lpUsedDefaultChar\n);\n#endif\nclass TVPGraphicPreload {\npublic:\n\tstruct tImgInfo {\n\t\tttstr filename;\n\t\ttTVPGraphicHandlerType *handler;\n\t\ttRefHolder<tTJSBinaryStream> Stream;\n\t\ttImgInfo() : handler(nullptr) {}\n\t};\n\n    struct tItem {\n\t\ttImgInfo main, mask;\n\t\ttTVPGraphicsSearchData searchdata;\n\t\tttstr provincename;\n    };\n\n    struct tParam {\n        std::vector<tItem> items; // must be TVPNormalizeStorageName(name);\n        tjs_int limit;\n    };\n\n    static TVPGraphicPreload* Instance() {\n        static TVPGraphicPreload *instance;\n        if(!instance) instance = new TVPGraphicPreload;\n        return instance;\n    }\n\n    void addTask(tParam *param) { // called from main thread\n\t\t{\n\t\t\ttTJSCSH lock(CSTask);\n\t\t\tReqInterrupt = true;\n\t\t\tclearTask(); // drop all unfinished tasks\n\t\t\tTaskList.emplace_back(param);\n\t\t}\n\t\tTaskCond.notify_one();\n    }\n\nprivate:\n    std::list<tParam*> TaskList;\n    std::condition_variable TaskCond;\n\tstd::mutex TaskMutex;\n    tTJSCriticalSection CSTask;\n    bool ReqInterrupt;\n    \n    std::thread *ThreadID;\n    TVPGraphicPreload()\n    {\n//         TaskCond = SDL_CreateCond();\n//         TaskMutex = SDL_CreateMutex();\n\t\tThreadID = new std::thread(std::bind(&TVPGraphicPreload::_thread_loop, this));\n        ReqInterrupt = false;\n    }\n\n    void _thread_loop() {\n        while(true) {\n            ReqInterrupt = false;\n            tParam* CurrentTask = nullptr;\n\t\t\t{\n\t\t\t\ttTJSCSH lock(CSTask);\n\t\t\t\tif (!TaskList.empty()) {\n\t\t\t\t\tCurrentTask = TaskList.front();\n\t\t\t\t\tTaskList.pop_front();\n\t\t\t\t}\n\t\t\t}\n            if(!CurrentTask) {\n\t\t\t\tstd::unique_lock<std::mutex> lk(TaskMutex);\n\t\t\t\tTaskCond.wait(lk);\n                continue;\n            }\n\n            tjs_uint totalSize = 0;\n            for(auto it = CurrentTask->items.begin(); it != CurrentTask->items.end(); ++it) {\n                if(ReqInterrupt) break;\n                totalSize += loadOneGraph(*it);\n                if(totalSize >= (tjs_uint)CurrentTask->limit) break;\n            }\n            delete CurrentTask;\n        }\n    }\n\n//     static int _thread_entry(void *arg) {\n//         static_cast<TVPGraphicPreload*>(arg)->_thread_loop();\n//         return 0;\n//     }\n\n    void clearTask() {\n        for(auto it = TaskList.begin(); it != TaskList.end(); ++it) {\n            delete *it;\n        }\n        TaskList.clear();\n    }\n\n    unsigned int loadOneGraph(const tItem &item)\n    {\n\t\t// TODO move cache operation to main thread\n\t\ttjs_uint32 hash = tTVPGraphicCache::MakeHash(item.searchdata);\n        tTVPGraphicImageHolder * ptr =\n\t\t\tTVPGraphicCache.FindAndTouchWithHash(item.searchdata, hash);\n        if (ptr) {\n            return ptr->GetObjectNoAddRef()->GetSize(); // already in cache\n        }\n#ifdef WIN32\n\t\tchar buf[16384] = { 0 };\n\t\tttstr msg = TJS_W(\"Touching Image: \") + item.main.filename;\n\t\tWideCharToMultiByte(/*CP_ACP*/0, 0, msg.c_str(), -1, buf, sizeof(buf), nullptr, 0);\n\t\tputs(buf);\n\t\t//TVPAddLog(TJS_W(\"Touching Image: \") + item.main.filename);\n#endif\n\n        // load into dest\n\t\ttTVPGraphicImageData * data = nullptr;\n\n\t\tstd::vector<tTVPGraphicMetaInfoPair> * mi = nullptr;\n        int ret = 0;\n        try\n        {\n            tTVPBitmap *bmp;\n            // from TVPInternalLoadGraphic\n            {\n                //tTVPStreamHolder holder(item.imgfile); // open a storage named \"name\"\n\n                // load the image\n                tTVPLoadGraphicData data;\n\t\t\t\tdata.Dest = nullptr;\n                data.ColorKey = TVP_clNone;\n                data.Type = lgtFullColor;\n\t\t\t\tdata.Name = item.main.filename;\n                data.DesW = 0;\n                data.DesH = 0;\n                data.NeedMetaInfo = true;\n\t\t\t\tdata.MetaInfo = nullptr;\n\n\t\t\t\t(item.main.handler->Load)(item.main.handler->FormatData, (void*)&data, TVPLoadGraphic_SizeCallback,\n                    TVPLoadGraphic_ScanLineCallback, TVPLoadGraphic_MetaInfoPushCallback,\n\t\t\t\t\titem.main.Stream.get(), -1, glmNormal);\n\n                mi = data.MetaInfo;\n\n                if(item.mask.handler && item.mask.Stream) {\n                    // open the mask file\n                    //holder.Open(item.maskfile);\n\n                    // fill \"data\"'s member\n                    data.Type = lgtMask;\n\t\t\t\t\tdata.Name = item.mask.filename;\n\t\t\t\t\tdata.Buffer = nullptr;\n                    data.DesW = 0;\n                    data.DesH = 0;\n                    data.NeedMetaInfo = false;\n\n\t\t\t\t\t(item.mask.handler->Load)(item.mask.handler->FormatData, (void*)&data,\n                        TVPLoadGraphic_SizeCallback, TVPLoadGraphic_ScanLineCallback, nullptr,\n\t\t\t\t\t\titem.mask.Stream.get(), -1, glmGrayscale);\n                }\n\n                bmp = data.Dest;\n            }\n\n            data = new tTVPGraphicImageData();\n            data->AssignBitmap(bmp);\n            data->ProvinceName = item.provincename;\n            data->MetaInfo = mi; // now mi is managed under tTVPGraphicImageData\n\t\t\tmi = nullptr;\n\n            // check size limit\n            TVPCheckGraphicCacheLimit();\n\n            // push into hash table\n            tjs_uint datasize = data->GetSize();\n\t\t\tTVPGraphicCacheTotalBytes += datasize;\n\t\t\ttTVPGraphicImageHolder holder(data);\n\t\t\tTVPGraphicCache.AddWithHash(item.searchdata, hash, holder);\n            ret = bmp->GetWidth() * bmp->GetHeight() * bmp->GetBPP() / 8;\n            bmp->Release();\n        }\n        catch(...)\n        {\n            if(mi) delete mi;\n            if(data) data->Release();\n            throw;\n        }\n\n        if(mi) delete mi;\n        if(data) data->Release();\n\n        return ret;\n    }\n};\n\nclass tBitmapForAsyncTouch : public tTJSNI_Bitmap {\n\ttypedef tTJSNI_Bitmap inherit;\npublic:\n\ttBitmapForAsyncTouch() {\n\t\tConstruct(0, nullptr, nullptr);\n\t}\n\tvirtual void SetLoading(bool load) override {\n\t\tinherit::SetLoading(load);\n\t\tif (!load) {\n\t\t\t::Application->PostUserMessage([this](){\n\t\t\t\tInvalidate();\n\t\t\t\tDestruct();\n\t\t\t});\n\t\t}\n\t}\n};\n\n\n//---------------------------------------------------------------------------\n// TVPTouchImages\n//---------------------------------------------------------------------------\nvoid TVPTouchImages(const std::vector<ttstr> & storages, tjs_int64 limit,\n\ttjs_uint64 timeout)\n{\n\t// preload graphic files into the cache.\n\t// \"limit\" is a limit memory for preload, in bytes.\n\t// this function gives up when \"timeout\" (in ms) expired.\n\t// currently this function only loads normal graphics.\n\t// (univ.trans rule graphics nor province image may not work properly)\n\n\tif(!TVPGraphicCacheLimit || !TVPGraphicCacheEnabled) return;\n\n\ttjs_uint64 limitbytes;\n\tif(limit >= 0)\n\t{\n\t\tif( (tjs_uint64)limit > TVPGraphicCacheLimit || limit == 0)\n\t\t\tlimitbytes = TVPGraphicCacheLimit;\n\t\telse\n\t\t\tlimitbytes = limit;\n\t}\n\telse\n\t{\n\t\t// negative value of limit indicates remaining bytes after loading\n\t\tif((tjs_uint64)-limit >= TVPGraphicCacheLimit) return;\n\t\tlimitbytes = TVPGraphicCacheLimit + limit;\n\t}\n\tif (/*!timeout &&*/ storages.size()/* > 1*/) { // using async touching for multi images\n\t\tfor (const ttstr &name : storages) {\n\t\t\tttstr nname = TVPNormalizeStorageName(name);\n\t\t\ttjs_uint32 hash;\n\t\t\ttTVPGraphicsSearchData searchdata;\n\t\t\tif (TVPGraphicCacheEnabled) {\n\t\t\t\tsearchdata.Name = nname;\n\t\t\t\tsearchdata.KeyIdx = TVP_clNone;\n\t\t\t\tsearchdata.Mode = glmNormal;\n\t\t\t\tsearchdata.DesW = 0;\n\t\t\t\tsearchdata.DesH = 0;\n\n\t\t\t\thash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\t\t\ttTVPGraphicImageHolder * ptr =\n\t\t\t\t\tTVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n\t\t\t\tif (ptr) {\n\t\t\t\t\t// found in cache\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tApplication->GetAsyncImageLoader()->PushLoadQueue(nullptr, new tBitmapForAsyncTouch(), nname);\n\t\t}\n\t\treturn;\n\t}\n#if 0\n    // async version\n    TVPGraphicPreload::tParam *param = new TVPGraphicPreload::tParam;\n    param->limit = limitbytes;\n    for(auto it = storages.begin(); it != storages.end(); ++it) {\n        TVPGraphicPreload::tItem item;\n\t\titem.main.handler = nullptr;\n\t\tttstr name = TVPNormalizeStorageName(*it);\n\t\ttTVPGraphicsSearchData &searchdata = item.searchdata;\n\t\tsearchdata.Name = name;\n\t\tsearchdata.KeyIdx = TVP_clNone;\n\t\tsearchdata.Mode = glmNormal;\n\t\tsearchdata.DesW = 0;\n\t\tsearchdata.DesH = 0;\n\t\tttstr ext = TVPExtractStorageExt(name);\n        if(ext.IsEmpty()) { // to avoid handler searching\n            tTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n            for(i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/)\n            {\n                ttstr newname = name + i.GetKey();\n                if(TVPIsExistentStorage(newname))\n                {\n                    // file found\n\t\t\t\t\titem.main.filename = newname;\n\t\t\t\t\titem.main.handler = &i.GetValue();\n                    break;\n                }\n                i++;\n            }\n\t\t\tif (i.IsNull() || !item.main.handler)\n            {\n                // not found\n                //TVPThrowExceptionMessage(TVPCannotSuggestGraphicExtension, name);\n\t\t\t\tcontinue;\n            }\n        } else {\n\t\t\titem.main.filename = name;\n\t\t\titem.main.handler = TVPGraphicType.Hash.Find(ext);\n\t\t\tif (!item.main.handler) continue;\n\t\t}\n\n        ttstr provincename = ttstr(name, name.length()-ext.length()) + TJS_W(\"_p\");\n        // search extensions\n        tTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n        for(i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/)\n        {\n            ttstr newname = provincename + i.GetKey();\n            if(TVPIsExistentStorage(newname))\n            {\n                // file found\n                item.provincename = newname;\n                break;\n            }\n            i++;\n        }\n        // mask image handling ( addding _m suffix with the filename )\n        while(true)\n        {\n            name = ttstr(name, name.length()-ext.length()) + TJS_W(\"_m\") + ext;\n            if(ext.IsEmpty())\n            {\n                // missing extension\n                // suggest registered extensions\n                tTJSHashTable<ttstr, tTVPGraphicHandlerType>::tIterator i;\n                for(i = TVPGraphicType.Hash.GetFirst(); !i.IsNull(); /*i++*/)\n                {\n                    ttstr newname = name;\n                    newname += i.GetKey();\n                    if(TVPIsExistentStorage(newname))\n                    {\n                        // file found\n                        item.mask.filename = newname;\n\t\t\t\t\t\titem.mask.handler = &i.GetValue();\n                        break;\n                    }\n                    i++;\n                }\n                break;\n            }\n            else\n            {\n                if(!TVPIsExistentStorage(name))\n                {\n                    // not found\n                    ext.Clear();\n                    continue; // retry searching\n                }\n\t\t\t\titem.mask.handler = TVPGraphicType.Hash.Find(ext);\n                break;\n            }\n        }\n\n\t\titem.main.Stream = TVPCreateStream(item.main.filename, 0);\n\t\tif (item.main.Stream) {\n\t\t\tif (item.mask.handler) item.mask.Stream = TVPCreateStream(item.mask.filename, 0);\n\t\t\tparam->items.emplace_back(item);\n\t\t}\n    }\n    TVPGraphicPreload::Instance()->addTask(param);\n    return;\n#endif\n\ttjs_int count = 0;\n\ttjs_uint64 bytes = 0;\n\ttjs_uint64 starttime = TVPGetTickCount();\n\ttjs_uint64 limittime = starttime + timeout;\n\t//tTVPBaseBitmap tmp(32, 32, 32);\n \tttstr statusstr( (const tjs_char*)TVPInfoTouching );\n\tbool first = true;\n\twhile((tjs_uint)count < storages.size())\n\t{\n\t\tif(timeout && TVPGetTickCount() >= limittime)\n\t\t{\n\t\t\tstatusstr += (const tjs_char*)TVPAbortedTimeOut;\n\t\t\tbreak;\n\t\t}\n\t\tif(bytes >= limitbytes)\n\t\t{\n\t\t\tstatusstr += (const tjs_char*)TVPAbortedLimitByte;\n\t\t\tbreak;\n\t\t}\n\n\t\ttry\n\t\t{\n\t\t\tif(!first) statusstr += TJS_W(\", \");\n\t\t\tfirst = false;\n\t\t\tstatusstr += storages[count];\n\n\t\t\tbytes += TVPLoadGraphic(nullptr, storages[count++], TVP_clNone,\n\t\t\t\t0, 0, glmNormal, NULL); // load image\n\t\t}\n\t\tcatch(eTJS &e)\n\t\t{\n\t\t\tstatusstr += TJS_W(\"(error!:\");\n\t\t\tstatusstr += e.GetMessage();\n\t\t\tstatusstr += TJS_W(\")\");\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\t// ignore all errors\n\t\t}\n\t}\n\n\t// re-touch graphic cache to ensure that more earlier graphics in storages\n\t// array can get more priority in cache order.\n\tcount--;\n\tfor(;count >= 0; count--)\n\t{\n\t\ttTVPGraphicsSearchData searchdata;\n\t\tsearchdata.Name = TVPNormalizeStorageName(storages[count]);\n\t\tsearchdata.KeyIdx = TVP_clNone;\n\t\tsearchdata.Mode = glmNormal;\n\t\tsearchdata.DesW = 0;\n\t\tsearchdata.DesH = 0;\n\n\t\ttjs_uint32 hash = tTVPGraphicCache::MakeHash(searchdata);\n\n\t\tTVPGraphicCache.FindAndTouchWithHash(searchdata, hash);\n\t}\n\n\tstatusstr += TJS_W(\" (elapsed \");\n\tstatusstr += ttstr((tjs_int)(TVPGetTickCount() - starttime));\n\tstatusstr += TJS_W(\"ms)\");\n\n\tTVPAddLog(statusstr);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPSetGraphicCacheLimit\n//---------------------------------------------------------------------------\nvoid TVPSetGraphicCacheLimit(tjs_uint64 limit)\n{\n\t// set limit of graphic cache by total bytes.\n\tif(limit == 0 )\n\t{\n\t\tTVPGraphicCacheLimit = limit;\n\t\tTVPGraphicCacheEnabled = false;\n\t}\n\telse if(limit == -1)\n\t{\n\t\tTVPGraphicCacheLimit = TVPGraphicCacheSystemLimit;\n\t\tTVPGraphicCacheEnabled = true;\n\t}\n\telse\n\t{\n\t\tif(limit > TVPGraphicCacheSystemLimit)\n\t\t\tlimit = TVPGraphicCacheSystemLimit;\n\t\tTVPGraphicCacheLimit = limit;\n\t\tTVPGraphicCacheEnabled = true;\n\t}\n\n\tif (TVPGraphicCacheLimit > 512 * 1024 * 1024) // max for 512M\n\t\tTVPGraphicCacheLimit = 512 * 1024 * 1024;\n\n\tTVPCheckGraphicCacheLimit();\n}\n//---------------------------------------------------------------------------\ntjs_uint64 TVPGetGraphicCacheLimit()\n{\n\treturn TVPGraphicCacheLimit;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n"
  },
  {
    "path": "src/core/visual/GraphicsLoaderIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Graphics Loader ( loads graphic format from storage )\n//---------------------------------------------------------------------------\n\n#ifndef GraphicsLoaderIntfH\n#define GraphicsLoaderIntfH\n\n\n#include \"drawable.h\"\n\nclass tTVPBaseBitmap;\nnamespace TJS {\n    class tTJSBinaryStream;\n}\n\nenum tTVPGraphicPixelFormat\n{\n\tgpfLuminance,\n\tgpfPalette,\n\tgpfRGB,\n\tgpfRGBA\n};\n\n/*[*/\n//---------------------------------------------------------------------------\n// Graphic Loading Handler Type\n//---------------------------------------------------------------------------\ntypedef int (*tTVPGraphicSizeCallback) // return line pitch\n\t(void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt);\n/*\n\tcallback type to inform the image's size.\n\tcall this once before TVPGraphicScanLineCallback.\n*/\n\ntypedef void * (*tTVPGraphicScanLineCallback)\n\t(void *callbackdata, tjs_int y);\n/*\n\tcallback type to ask the scanline buffer for the decoded image, per a line.\n\treturning null can stop the processing.\n\n\tpassing of y=-1 notifies the scan line image had been written to the buffer that\n\twas given by previous calling of TVPGraphicScanLineCallback. in this time,\n\tthis callback function must return NULL.\n*/\n\ntypedef const void * (*tTVPGraphicSaveScanLineCallback)\n\t(void *callbackdata, tjs_int y);\n\ntypedef void (*tTVPMetaInfoPushCallback)\n\t(void *callbackdata, const ttstr & name, const ttstr & value);\n/*\n\tcallback type to push meta-information of the image.\n\tthis can be null.\n*/\n\nenum tTVPGraphicLoadMode\n{\n\tglmNormal, // normal, ie. 32bit ARGB graphic\n\tglmPalettized, // palettized 8bit mode\n\tglmGrayscale // grayscale 8bit mode\n};\n/*]*/\n\ntypedef void (*tTVPGraphicLoadingHandler)(void* formatdata,\n\tvoid *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src,\n\ttjs_int32 keyidx,\n\ttTVPGraphicLoadMode mode);\n/*\n\tformat = format specific data given at TVPRegisterGraphicLoadingHandler\n\tdest = destination callback function\n\tsrc = source stream\n\tkeyidx = color key for less than or equal to 8 bit image\n\tmode = if glmPalettized, the output image must be an 8bit color (for province\n\t   image. so the color is not important. color index must be preserved).\n\t   if glmGrayscale, the output image must be an 8bit grayscale image.\n\t   otherwise the output image must be a 32bit full-color with opacity.\n\n\tcolor key does not overrides image's alpha channel ( if the image has )\n\n\tthe function may throw an exception if error.\n*/\n\ntypedef void (*tTVPGraphicHeaderLoadingHandler)(void* formatdata,  tTJSBinaryStream *src, class iTJSDispatch2** dic );\ntypedef void (*tTVPGraphicSaveHandler)(void* formatdata,  tTJSBinaryStream* dst, const class iTVPBaseBitmap* image,\n\tconst ttstr & mode, class iTJSDispatch2* meta );\n\n/*[*/\ntypedef bool (*tTVPGraphicAcceptSaveHandler)(void* formatdata, const ttstr & type, class iTJSDispatch2** dic );\n/*]*/\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Graphics Format Management\n//---------------------------------------------------------------------------\nvoid TVPRegisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandler loading,\n\ttTVPGraphicHeaderLoadingHandler header,\n\ttTVPGraphicSaveHandler save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata);\nvoid TVPUnregisterGraphicLoadingHandler(const ttstr & name,\n\ttTVPGraphicLoadingHandler loading,\n\ttTVPGraphicHeaderLoadingHandler header,\n\ttTVPGraphicSaveHandler save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata);\n\n\n/*[*/\n/* For grahpic load and save */\ntypedef void (*tTVPGraphicLoadingHandlerForPlugin)(void* formatdata,\n\tvoid *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback,\n\tstruct IStream *src,\n\ttjs_int32 keyidx,\n\ttTVPGraphicLoadMode mode);\ntypedef void (*tTVPGraphicHeaderLoadingHandlerForPlugin)(void* formatdata, struct IStream* src, class iTJSDispatch2** dic );\ntypedef void (*tTVPGraphicSaveHandlerForPlugin)(void* formatdata, void* callbackdata, struct IStream* dst, const ttstr & mode,\n\ttjs_uint width, tjs_uint height,\n\ttTVPGraphicSaveScanLineCallback scanlinecallback,\n\tclass iTJSDispatch2* meta );\n/*]*/\n\nTJS_EXP_FUNC_DEF( void, TVPRegisterGraphicLoadingHandler, (const ttstr & name,\n\ttTVPGraphicLoadingHandlerForPlugin loading,\n\ttTVPGraphicHeaderLoadingHandlerForPlugin header,\n\ttTVPGraphicSaveHandlerForPlugin save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata));\n\nTJS_EXP_FUNC_DEF( void, TVPUnregisterGraphicLoadingHandler, (const ttstr & name,\n\ttTVPGraphicLoadingHandlerForPlugin loading,\n\ttTVPGraphicHeaderLoadingHandlerForPlugin header,\n\ttTVPGraphicSaveHandlerForPlugin save,\n\ttTVPGraphicAcceptSaveHandler accept,\n\tvoid* formatdata));\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// default handlers\n//---------------------------------------------------------------------------\nextern void TVPLoadBMP(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode);\n\nextern void TVPLoadJPEG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode);\n\nextern void TVPLoadPNG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode);\n\nextern void TVPLoadJXR(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode);\n\nextern void TVPLoadTLG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx, tTVPGraphicLoadMode mode);\n//---------------------------------------------------------------------------\nextern void TVPLoadWEBP(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode);\n\nextern void TVPLoadBPG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx, tTVPGraphicLoadMode mode);\n\n//---------------------------------------------------------------------------\n// Image header handler\n// dic = %[\n//    \"width\" => (int)width,\n//    \"height\" => (int)height,\n//    \"bpp\" => (int)bpp, // (option)\n//    \"palette\" => (bool)palette, // (option)\n//    \"grayscale\" => (bool)grayscale, // (option)\n//    \"comment\" => (string)comment, // (option)\n//    etc...\n// ]\n//---------------------------------------------------------------------------\nextern void TVPLoadHeaderBMP(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic );\nextern void TVPLoadHeaderJPG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic );\nextern void TVPLoadHeaderPNG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic );\nextern void TVPLoadHeaderJXR(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic );\nextern void TVPLoadHeaderTLG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic);\nextern void TVPLoadHeaderWEBP(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic);\nextern void TVPLoadHeaderBPG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Image saving handler\n//---------------------------------------------------------------------------\nextern void TVPSaveAsBMP(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\nextern void TVPSaveAsPNG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\nextern void TVPSaveAsJPG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\nextern void TVPSaveAsJXR(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\nextern void TVPSaveAsTLG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// is accept\n//---------------------------------------------------------------------------\nextern bool TVPAcceptSaveAsBMP(void* formatdata, const ttstr & type, iTJSDispatch2** dic );\nextern bool TVPAcceptSaveAsPNG(void* formatdata, const ttstr & type, iTJSDispatch2** dic );\nextern bool TVPAcceptSaveAsJPG(void* formatdata, const ttstr & type, iTJSDispatch2** dic );\nextern bool TVPAcceptSaveAsJXR(void* formatdata, const ttstr & type, iTJSDispatch2** dic );\nextern bool TVPAcceptSaveAsTLG(void* formatdata, const ttstr & type, iTJSDispatch2** dic );\n//---------------------------------------------------------------------------\n\nvoid TVPSaveTextureAsBMP(tTJSBinaryStream* dst, class iTVPTexture2D* bmp, const ttstr & mode = TJS_W(\"\"), iTJSDispatch2* meta = nullptr);\nvoid TVPSaveTextureAsBMP(const ttstr &path, class iTVPTexture2D* tex, const ttstr &mode = TJS_W(\"\"), iTJSDispatch2* meta = nullptr);\n\n//---------------------------------------------------------------------------\n// JPEG loading handler\n//---------------------------------------------------------------------------\nenum tTVPJPEGLoadPrecision\n{\n\tjlpLow,\n\tjlpMedium,\n\tjlpHigh\n};\n\nextern tTVPJPEGLoadPrecision TVPJPEGLoadPrecision;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Graphics cache management\n//---------------------------------------------------------------------------\nextern bool TVPAllocGraphicCacheOnHeap;\n\t// this allocates graphic cache's store memory on heap, rather than\n\t// shareing bitmap object. ( since sucking win9x cannot have so many bitmap\n\t// object at once, WinNT/2000 is ok. )\n\t// this will take more time for memory copying.\nextern void TVPSetGraphicCacheLimit(tjs_uint64 limit);\n\t// set graphic cache size limit by bytes.\n\t// limit == 0 disables the cache system.\n\t// limit == -1 sets the limit to TVPGraphicCacheSystemLimit\nextern tjs_uint64 TVPGetGraphicCacheLimit();\n\nextern tjs_uint64 TVPGraphicCacheSystemLimit;\n\t// maximum possible value of Graphic Cache Limit\n\nTJS_EXP_FUNC_DEF(void, TVPClearGraphicCache, ());\n\t// clear graphic cache\n\n\nextern void TVPTouchImages(const std::vector<ttstr> & storages, tjs_int64 limit,\n\ttjs_uint64 timeout);\n\n//---------------------------------------------------------------------------\n\n\n\n\nclass iTVPBaseBitmap;\n//---------------------------------------------------------------------------\n// TVPLoadGraphic\n//---------------------------------------------------------------------------\nextern int TVPLoadGraphic(iTVPBaseBitmap *dest, const ttstr &name, tjs_int keyidx,\n\ttjs_uint desw, tjs_uint desh,\n\ttTVPGraphicLoadMode mode, ttstr *provincename = NULL, iTJSDispatch2 ** metainfo = NULL);\n\t// throws exception when this function can not handle the file\n//---------------------------------------------------------------------------\n\nextern void TVPLoadGraphicProvince(tTVPBaseBitmap *dest, const ttstr &name, tjs_int keyidx,\n\ttjs_uint desw, tjs_uint desh);\n\n\n//---------------------------------------------------------------------------\n// BMP loading interface\n//---------------------------------------------------------------------------\n\n#ifndef BI_RGB // avoid re-define error on Win32\n\t#define BI_RGB\t\t\t0\n\t#define BI_RLE8\t\t\t1\n\t#define BI_RLE4\t\t\t2\n\t#define BI_BITFIELDS\t3\n#endif\n\n#pragma pack(push, 1)\nstruct TVP_WIN_BITMAPFILEHEADER\n{\n\ttjs_uint16\tbfType;\n\ttjs_uint32\tbfSize;\n\ttjs_uint16\tbfReserved1;\n\ttjs_uint16\tbfReserved2;\n\ttjs_uint32\tbfOffBits;\n};\nstruct TVP_WIN_BITMAPINFOHEADER\n{\n\ttjs_uint32\tbiSize;\n\ttjs_int\t\tbiWidth;\n\ttjs_int\t\tbiHeight;\n\ttjs_uint16\tbiPlanes;\n\ttjs_uint16\tbiBitCount;\n\ttjs_uint32\tbiCompression;\n\ttjs_uint32\tbiSizeImage;\n\ttjs_int\t\tbiXPelsPerMeter;\n\ttjs_int\t\tbiYPelsPerMeter;\n\ttjs_uint32\tbiClrUsed;\n\ttjs_uint32\tbiClrImportant;\n};\n#pragma pack(pop)\n\nenum tTVPBMPAlphaType\n{\n\t// this specifies alpha channel treatment if the bitmap is 32bpp.\n\t// note that TVP currently does not support new (V4 or V5) bitmap header\n\tbatNone, // plugin does not return alpha channel.\n\tbatMulAlpha, // returns alpha channel, d = d * alpha + s * (1-alpha)\n\tbatAddAlpha // returns alpha channel, d = d * alpha + s\n};\n\n\n\nextern void TVPInternalLoadBMP(void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\tTVP_WIN_BITMAPINFOHEADER &bi,\n\tconst tjs_uint8 *palsrc,\n\ttTJSBinaryStream * src,\n\ttjs_int keyidx,\n\ttTVPBMPAlphaType alphatype,\n\ttTVPGraphicLoadMode mode);\n\nextern const void* tTVPBitmapScanLineCallbackForSave(void *callbackdata, tjs_int y);\n\nstruct tTVPGraphicHandlerType\n{\n\tbool IsPlugin;\n\tttstr Extension;\n\tunion {\n\t\ttTVPGraphicLoadingHandler LoadHandler;\n\t\ttTVPGraphicLoadingHandlerForPlugin LoadHandlerPlugin;\n\t};\n\tunion {\n\t\ttTVPGraphicHeaderLoadingHandler HeaderHandler;\n\t\ttTVPGraphicHeaderLoadingHandlerForPlugin HeaderHandlerPlugin;\n\t};\n\tunion {\n\t\ttTVPGraphicSaveHandler SaveHandler;\n\t\ttTVPGraphicSaveHandlerForPlugin SaveHandlerPlugin;\n\t};\n\ttTVPGraphicAcceptSaveHandler AcceptHandler;\n\tvoid * FormatData;\n\n\ttTVPGraphicHandlerType(const ttstr &ext,\n\t\ttTVPGraphicLoadingHandler loading,\n\t\ttTVPGraphicHeaderLoadingHandler header,\n\t\ttTVPGraphicSaveHandler save,\n\t\ttTVPGraphicAcceptSaveHandler accept,\n\t\tvoid * data) : IsPlugin(false)\n\t{\n\t\tExtension = ext;\n\t\tLoadHandler = loading;\n\t\tHeaderHandler = header;\n\t\tSaveHandler = save;\n\t\tAcceptHandler = accept;\n\t\tFormatData = data;\n\t}\n\n\ttTVPGraphicHandlerType(const ttstr &ext,\n\t\ttTVPGraphicLoadingHandlerForPlugin loading,\n\t\ttTVPGraphicHeaderLoadingHandlerForPlugin header,\n\t\ttTVPGraphicSaveHandlerForPlugin save,\n\t\ttTVPGraphicAcceptSaveHandler accept,\n\t\tvoid * data) : IsPlugin(true)\n\t{\n\t\tExtension = ext;\n\t\tLoadHandlerPlugin = loading;\n\t\tHeaderHandlerPlugin = header;\n\t\tSaveHandlerPlugin = save;\n\t\tAcceptHandler = accept;\n\t\tFormatData = data;\n\t}\n\n\ttTVPGraphicHandlerType(const tTVPGraphicHandlerType & ref)\n\t{\n\t\tIsPlugin = ref.IsPlugin;\n\t\tif( IsPlugin )\n\t\t{\n\t\t\tLoadHandlerPlugin = ref.LoadHandlerPlugin;\n\t\t\tHeaderHandlerPlugin = ref.HeaderHandlerPlugin;\n\t\t\tSaveHandlerPlugin = ref.SaveHandlerPlugin;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tLoadHandler = ref.LoadHandler;\n\t\t\tHeaderHandler = ref.HeaderHandler;\n\t\t\tSaveHandler = ref.SaveHandler;\n\t\t}\n\t\tAcceptHandler = ref.AcceptHandler;\n\t\tExtension = ref.Extension;\n\t\tFormatData = ref.FormatData;\n\t}\n\n\tbool operator == (const tTVPGraphicHandlerType & ref) const\n\t{\n\t\treturn FormatData == ref.FormatData &&\n\t\t\tIsPlugin == ref.IsPlugin &&\n\t\t\tLoadHandler == ref.LoadHandler &&\n\t\t\tHeaderHandler == ref.HeaderHandler &&\n\t\t\tSaveHandler == ref.SaveHandler &&\n\t\t\tAcceptHandler == ref.AcceptHandler &&\n\t\t\tExtension == ref.Extension;\n\t}\n\tvoid Load( void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\t\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int32 keyidx, tTVPGraphicLoadMode mode);\n\tvoid Save( const ttstr & storagename, const ttstr & mode, const iTVPBaseBitmap* image, iTJSDispatch2* meta );\n\tvoid Header( tTJSBinaryStream *src, iTJSDispatch2** dic );\n\tbool AcceptSave( const ttstr & type, iTJSDispatch2** dic )\n\t{\n\t\tif( AcceptHandler == NULL ) return false;\n\t\treturn AcceptHandler( FormatData, type, dic );\n\t}\n};\nstruct tTVPGraphicMetaInfoPair\n{\n\tttstr Name;\n\tttstr Value;\n\ttTVPGraphicMetaInfoPair(const ttstr &name, const ttstr &value) :\n\t\tName(name), Value(value) {;}\n};\n\nextern iTJSDispatch2 * TVPMetaInfoPairsToDictionary( std::vector<tTVPGraphicMetaInfoPair> *vec );\nextern void TVPPushGraphicCache( const ttstr& nname, class tTVPBitmap* bmp,\n\tstd::vector<tTVPGraphicMetaInfoPair>* meta );\nextern tTVPGraphicHandlerType* TVPGetGraphicLoadHandler( const ttstr& ext );\nextern bool TVPCheckImageCache( const ttstr& nname, tTVPBaseBitmap* dest,\n\ttTVPGraphicLoadMode mode, tjs_uint dw, tjs_uint dh, tjs_int32 keyidx,\n\tiTJSDispatch2** metainfo );\nextern bool TVPHasImageCache( const ttstr& nname, tTVPGraphicLoadMode mode,\n\ttjs_uint dw, tjs_uint dh, tjs_int32 keyidx );\nextern void TVPLoadImageHeader( const ttstr & storagename, iTJSDispatch2** dic );\nextern void TVPSaveImage(const ttstr & storagename, const ttstr & mode, const iTVPBaseBitmap* image, iTJSDispatch2* meta);\nextern bool TVPGetSaveOption( const ttstr & type, iTJSDispatch2** dic );\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/ImageFunction.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"ImageFunction.h\"\n#include \"BitmapIntf.h\"\n#include \"RectItf.h\"\n\ntTJSNI_ImageFunction::tTJSNI_ImageFunction() {}\n\ntjs_error TJS_INTF_METHOD tTJSNI_ImageFunction::Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj) {\n\treturn TJS_S_OK;\n}\n\nvoid TJS_INTF_METHOD tTJSNI_ImageFunction::Invalidate() {}\n\ntTVPBBBltMethod tTJSNC_ImageFunction::GetBltMethodFromOperationMode( tTVPBlendOperationMode mode, tTVPDrawFace face )\n{\n\ttTVPBBBltMethod met = bmAlphaOnAlpha;\n\tswitch(mode)\n\t{\n\tcase omPsNormal:\t\t\tmet = bmPsNormal;\t\t\tbreak;\n\tcase omPsAdditive:\t\t\tmet = bmPsAdditive;\t\t\tbreak;\n\tcase omPsSubtractive:\t\tmet = bmPsSubtractive;\t\tbreak;\n\tcase omPsMultiplicative:\tmet = bmPsMultiplicative;\tbreak;\n\tcase omPsScreen:\t\t\tmet = bmPsScreen;\t\t\tbreak;\n\tcase omPsOverlay:\t\t\tmet = bmPsOverlay;\t\t\tbreak;\n\tcase omPsHardLight:\t\t\tmet = bmPsHardLight;\t\tbreak;\n\tcase omPsSoftLight:\t\t\tmet = bmPsSoftLight;\t\tbreak;\n\tcase omPsColorDodge:\t\tmet = bmPsColorDodge;\t\tbreak;\n\tcase omPsColorDodge5:\t\tmet = bmPsColorDodge5;\t\tbreak;\n\tcase omPsColorBurn:\t\t\tmet = bmPsColorBurn;\t\tbreak;\n\tcase omPsLighten:\t\t\tmet = bmPsLighten;\t\t\tbreak;\n\tcase omPsDarken:\t\t\tmet = bmPsDarken;\t\t\tbreak;\n\tcase omPsDifference:   \t\tmet = bmPsDifference;\t\tbreak;\n\tcase omPsDifference5:   \tmet = bmPsDifference5;\t\tbreak;\n\tcase omPsExclusion:\t\t\tmet = bmPsExclusion;\t\tbreak;\n\tcase omAdditive:\t\t\tmet = bmAdd;\t\t\t\tbreak;\n\tcase omSubtractive:\t\t\tmet = bmSub;\t\t\t\tbreak;\n\tcase omMultiplicative:\t\tmet = bmMul;\t\t\t\tbreak;\n\tcase omDodge:\t\t\t\tmet = bmDodge;\t\t\t\tbreak;\n\tcase omDarken:\t\t\t\tmet = bmDarken;\t\t\t\tbreak;\n\tcase omLighten:\t\t\t\tmet = bmLighten;\t\t\tbreak;\n\tcase omScreen:\t\t\t\tmet = bmScreen;\t\t\t\tbreak;\n\tcase omAlpha:\n\t\tif(face == dfAlpha)\n\t\t\t\t\t\t{\tmet = bmAlphaOnAlpha; break;\t\t}\n\t\telse if(face == dfAddAlpha)\n\t\t\t\t\t\t{\tmet = bmAlphaOnAddAlpha; break;\t\t}\n\t\telse if(face == dfOpaque)\n\t\t\t\t\t\t{\tmet = bmAlpha; break;\t\t\t\t}\n\t\tbreak;\n\tcase omAddAlpha:\n\t\tif(face == dfAlpha)\n\t\t\t\t\t\t{\tmet = bmAddAlphaOnAlpha; break;\t\t}\n\t\telse if(face == dfAddAlpha)\n\t\t\t\t\t\t{\tmet = bmAddAlphaOnAddAlpha; break;\t}\n\t\telse if(face == dfOpaque)\n\t\t\t\t\t\t{\tmet = bmAddAlpha; break;\t\t\t}\n\t\tbreak;\n\tcase omOpaque:\n\t\tif(face == dfAlpha)\n\t\t\t\t\t\t{\tmet = bmCopyOnAlpha; break;\t\t\t}\n\t\telse if(face == dfAddAlpha)\n\t\t\t\t\t\t{\tmet = bmCopyOnAddAlpha; break;\t\t}\n\t\telse if(face == dfOpaque)\n\t\t\t\t\t\t{\tmet = bmCopy; break;\t\t\t\t}\n\t\tbreak;\n\tcase omAuto:\n\t\tbreak;\n\t}\n\treturn met;\n}\nbool tTJSNC_ImageFunction::ClipDestPointAndSrcRect(tjs_int &dx, tjs_int &dy, tTVPRect &srcrectout, const tTVPRect &srcrect, const tTVPRect &clipRect)\n{\n\t// clip (dx, dy) <- srcrect\twith current clipping rectangle\n\tsrcrectout = srcrect;\n\ttjs_int dr = dx + srcrect.right - srcrect.left;\n\ttjs_int db = dy + srcrect.bottom - srcrect.top;\n\n\tif(dx < clipRect.left)\n\t{\n\t\tsrcrectout.left += (clipRect.left - dx);\n\t\tdx = clipRect.left;\n\t}\n\n\tif(dr > clipRect.right)\n\t{\n\t\tsrcrectout.right -= (dr - clipRect.right);\n\t}\n\n\tif(srcrectout.right <= srcrectout.left) return false; // out of the clipping rect\n\n\tif(dy < clipRect.top)\n\t{\n\t\tsrcrectout.top += (clipRect.top - dy);\n\t\tdy = clipRect.top;\n\t}\n\n\tif(db > clipRect.bottom)\n\t{\n\t\tsrcrectout.bottom -= (db - clipRect.bottom);\n\t}\n\n\tif(srcrectout.bottom <= srcrectout.top) return false; // out of the clipping rect\n\n\treturn true;\n}\n\n\ntjs_uint32 tTJSNC_ImageFunction::ClassID = -1;\n\ntTJSNC_ImageFunction::tTJSNC_ImageFunction() : inherited(TJS_W(\"ImageFunction\") )  {\n\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(ImageFunction) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_ImageFunction,\n\t/*TJS class name*/ImageFunction)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/ImageFunction)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateAffine)\n{\n\t// dst, src, x0/a, y0/b, x1/c, y1/d, x2/tx, y2/ty,\n\t// srcrect=null, cliprect=null, affine=true,\n\t// mode=omAlpha, face=dfAlpha, opa=255, type=0, hda=false\n\tif(numparams < 11) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\ttTJSNI_Bitmap * src = NULL;\n\tclo = param[1]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( (!dst) || (!src) ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect srcRect( 0, 0, src->GetWidth(), src->GetHeight() );\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 9 && param[8]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[8]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tsrcRect = rect->Get();\n\t\t}\n\t}\n\tif(numparams >= 10 && param[9]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[9]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\tbool affine = true;\n\tif(numparams >= 11 && param[10]->Type() != tvtVoid)\n\t\taffine = param[10]->operator bool();\n\n\ttTVPBlendOperationMode mode = omAlpha;\n\tif(numparams >= 12 && param[11]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[11]);\n\tif( mode == omAuto ) mode = omAlpha;\n\n\ttTVPDrawFace face = dfAlpha;\n\tif(numparams >= 13 && param[12]->Type() != tvtVoid)\n\t\tface = (tTVPDrawFace)(tjs_int)(*param[12]);\n\tif( face != dfAlpha && face != dfAddAlpha && face != dfOpaque ) face = dfAlpha;\n\n\ttjs_int opa = 255;\n\tif(numparams >= 14 && param[13]->Type() != tvtVoid)\n\t\topa = (tjs_int)*param[13];\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 15 && param[14]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[14];\n\n\tbool hda = false;\n\tif(numparams >= 16 && param[15]->Type() != tvtVoid)\n\t\thda = ((tjs_int)*param[15]) ? true : false;\n\n\ttTVPBBBltMethod met = GetBltMethodFromOperationMode( mode, face );\n\ttTVPRect updaterect; // ignore\n\tbool updated;\n\tif( affine ) {\n\t\t// affine matrix mode\n\t\tt2DAffineMatrix mat;\n\t\tmat.a = *param[2];\n\t\tmat.b = *param[3];\n\t\tmat.c = *param[4];\n\t\tmat.d = *param[5];\n\t\tmat.tx = *param[6];\n\t\tmat.ty = *param[7];\n\t\tupdated = dst->GetBitmap()->AffineBlt(clipRect, src->GetBitmap(), srcRect, mat, met, opa, &updaterect, hda, type);\n\t} else {\n\t\t// points mode\n\t\ttTVPPointD points[3];\n\t\tpoints[0].x = *param[2];\n\t\tpoints[0].y = *param[3];\n\t\tpoints[1].x = *param[4];\n\t\tpoints[1].y = *param[5];\n\t\tpoints[2].x = *param[6];\n\t\tpoints[2].y = *param[7];\n\t\tupdated = dst->GetBitmap()->AffineBlt(clipRect, src->GetBitmap(), srcRect, points, met, opa, &updaterect, hda, type);\n\t}\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( updaterect.left, updaterect.top, updaterect.right, updaterect.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/operateAffine)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateRect)\n{\n\t// dst, dleft, dtop, src, srect=null, cliprect=null\n\t// mode=omAlpha, face=dfAlpha, opa=255, hda=false\n\tif(numparams < 6) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\ttTJSNI_Bitmap * src = NULL;\n\tclo = param[3]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( (!dst) || (!src) ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect srcRect( 0, 0, src->GetWidth(), src->GetHeight() );\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 5 && param[4]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[4]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tsrcRect = rect->Get();\n\t\t}\n\t}\n\tif(numparams >= 6 && param[5]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[5]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\ttjs_int dleft = *param[1];\n\ttjs_int dtop = *param[2];\n\n\ttTVPBlendOperationMode mode = omAlpha;\n\tif(numparams >= 7 && param[6]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[6]);\n\t\n\tif( mode == omAuto ) mode = omAlpha;\n\n\ttTVPDrawFace face = dfAlpha;\n\tif(numparams >= 8 && param[7]->Type() != tvtVoid)\n\t\tface = (tTVPDrawFace)(tjs_int)(*param[7]);\n\n\tif( face != dfAlpha && face != dfAddAlpha && face != dfOpaque ) face = dfAlpha;\n\n\ttjs_int opa = 255;\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t\topa = *param[8];\n\n\tbool hda = false;\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\thda = ((tjs_int)*param[9]) ? true : false;\n\n\ttTVPRect rect;\n\tbool updated = false;\n\tif( ClipDestPointAndSrcRect( dleft, dtop, rect, srcRect, clipRect ) ) {\n\t\ttTVPBBBltMethod met = GetBltMethodFromOperationMode( mode, face );\n\t\tupdated = dst->GetBitmap()->Blt( dleft, dtop, src->GetBitmap(), rect, met, opa, hda );\n\t}\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\ttTVPRect ur = rect;\n\t\t\tur.set_offsets(dleft, dtop);\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( ur.left, ur.top, ur.right, ur.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/operateRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateStretch)\n{\n\t// dst, src, dstrect=null, srcrect=null, cliprect=null\n\t// mode=omAlpha, face=dfAlpha, opa=255, type=0, hda=false\n\t// dfAlpha,dfAddAlpha,dfOpaque\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\ttTJSNI_Bitmap * src = NULL;\n\tclo = param[1]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( (!dst) || (!src) ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect dstRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\ttTVPRect srcRect( 0, 0, src->GetWidth(), src->GetHeight() );\n\ttTVPRect clipRect( dstRect );\n\n\tif(numparams >= 3 && param[2]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[2]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tdstRect = rect->Get();\n\t\t}\n\t}\n\tif(numparams >= 4 && param[3]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[3]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tsrcRect = rect->Get();\n\t\t}\n\t}\n\tif(numparams >= 5 && param[4]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[4]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\n\ttTVPBlendOperationMode mode = omAlpha;\n\tif(numparams >= 6 && param[5]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[5]);\n\n\tif( mode == omAuto ) mode = omAlpha;\n\n\ttTVPDrawFace face = dfAlpha;\n\tif(numparams >= 7 && param[6]->Type() != tvtVoid)\n\t\tface = (tTVPDrawFace)(tjs_int)(*param[6]);\n\n\tif( face != dfAlpha && face != dfAddAlpha && face != dfOpaque ) face = dfAlpha;\n\n\ttjs_int opa = 255;\n\tif(numparams >= 8 && param[7]->Type() != tvtVoid)\n\t\topa = *param[7];\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[8];\n\n\tbool hda = false;\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\thda = ((tjs_int)*param[9]) ? true : false;\n\n\ttjs_real typeopt = 0.0;\n\tif(numparams >= 11)\n\t\ttypeopt = (tjs_real)*param[10];\n\telse if( type == stFastCubic || type == stCubic )\n\t\ttypeopt = -1.0;\n\n\tbool updated = false;\n\ttTVPRect ur = dstRect;\n\tif(ur.right < ur.left) std::swap(ur.right, ur.left);\n\tif(ur.bottom < ur.top) std::swap(ur.bottom, ur.top);\n\tif( TVPIntersectRect(&ur, ur, clipRect) ) {\n\t\ttTVPBBBltMethod met = GetBltMethodFromOperationMode( mode, face );\n\t\tupdated = dst->GetBitmap()->StretchBlt( clipRect, dstRect, src->GetBitmap(), srcRect, met, opa, hda, type, typeopt);\n\t}\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( ur.left, ur.top, ur.right, ur.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/operateStretch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/flipLR)\n{\n\t// dst, rect\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect dstRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 2 && param[1]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[1]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tdstRect = rect->Get();\n\t\t}\n\t}\n\tdst->GetBitmap()->LRFlip(dstRect);\n\tif( result ) {\n\t\tiTJSDispatch2 *ret = TVPCreateRectObject( dstRect.left, dstRect.top, dstRect.right, dstRect.bottom );\n\t\t*result = tTJSVariant(ret, ret);\n\t\tret->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/flipLR)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/flipUD)\n{\n\t// dst, rect\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect dstRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 2 && param[1]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[1]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tdstRect = rect->Get();\n\t\t}\n\t}\n\tdst->GetBitmap()->UDFlip(dstRect);\n\tif( result ) {\n\t\tiTJSDispatch2 *ret = TVPCreateRectObject( dstRect.left, dstRect.top, dstRect.right, dstRect.bottom );\n\t\t*result = tTJSVariant(ret, ret);\n\t\tret->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/flipUD)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/adjustGamma)\n{\n\t// bmp, rgamma=1.0, rfloor=0, rceil=255, ggamma=1.0, gfloor=0, gceil=255, bgamma=1.0, bfloor=0, bceil=255, cliprect=null, isaddalpha=false\n\t// cliprect=null, isaddalpha=false\n\tif( numparams < 1 ) return TJS_E_BADPARAMCOUNT;\n\tif( numparams == 1 ) return TJS_S_OK;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttTVPGLGammaAdjustData data;\n\tmemcpy(&data, &TVPIntactGammaAdjustData, sizeof(data));\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tdata.RGamma = static_cast<float>((double)*param[1]);\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tdata.RFloor = *param[2];\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\tdata.RCeil  = *param[3];\n\tif(numparams >= 5 && param[4]->Type() != tvtVoid)\n\t\tdata.GGamma = static_cast<float>((double)*param[4]);\n\tif(numparams >= 6 && param[5]->Type() != tvtVoid)\n\t\tdata.GFloor = *param[5];\n\tif(numparams >= 7 && param[6]->Type() != tvtVoid)\n\t\tdata.GCeil  = *param[6];\n\tif(numparams >= 8 && param[7]->Type() != tvtVoid)\n\t\tdata.BGamma = static_cast<float>((double)*param[7]);\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t\tdata.BFloor = *param[8];\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\tdata.BCeil  = *param[9];\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 11 && param[10]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[10]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\tbool isaddalpha = false;\n\tif(numparams >= 12 && param[11]->Type() != tvtVoid)\n\t\tisaddalpha = ((tjs_int)*param[11]) ? true : false;\n\t\n\tif( isaddalpha ) {\n\t\tdst->GetBitmap()->AdjustGammaForAdditiveAlpha( clipRect, data);\n\t} else {\n\t\tdst->GetBitmap()->AdjustGamma( clipRect, data);\n\t}\n\tif( result ) {\n\t\tiTJSDispatch2 *ret = TVPCreateRectObject( clipRect.left, clipRect.top, clipRect.right, clipRect.bottom );\n\t\t*result = tTJSVariant(ret, ret);\n\t\tret->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/adjustGamma)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doBoxBlur)\n{\n\t// bmp, xblur=1, yblur=1, clipRect=null, isalpha=true\n\tif( numparams < 1 ) return TJS_E_BADPARAMCOUNT;\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttjs_int xblur = 1;\n\ttjs_int yblur = 1;\n\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\txblur = (tjs_int)*param[1];\n\t\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tyblur = (tjs_int)*param[2];\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 4 && param[3]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[3]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\tbool isalpha = true;\n\tif(numparams >= 5 && param[4]->Type() != tvtVoid)\n\t\tisalpha = ((tjs_int)*param[4]) ? true : false;\n\n\tbool updated = false;\n\tif( isalpha == false )\n\t\tupdated = dst->GetBitmap()->DoBoxBlur(clipRect, tTVPRect(-xblur, -yblur, xblur, yblur));\n\telse\n\t\tupdated = dst->GetBitmap()->DoBoxBlurForAlpha(clipRect, tTVPRect(-xblur, -yblur, xblur, yblur));\n\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( clipRect.left, clipRect.top, clipRect.right, clipRect.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/doBoxBlur)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doGrayScale)\n{\n\t// bmp, clipRect=null\n\tif( numparams < 1 ) return TJS_E_BADPARAMCOUNT;\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 2 && param[1]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[1]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\n\tdst->GetBitmap()->DoGrayScale(clipRect);\n\tif( result ) {\n\t\tiTJSDispatch2 *ret = TVPCreateRectObject( clipRect.left, clipRect.top, clipRect.right, clipRect.bottom );\n\t\t*result = tTJSVariant(ret, ret);\n\t\tret->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/doGrayScale)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fillRect)\n{\n\t// bmp, value, rect=null, isalpha=true, cliprect=null\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttjs_uint32 color = static_cast<tjs_uint32>((tjs_int64)*param[1]);\n\n\ttTVPRect rect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 3 && param[2]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rectni = NULL;\n\t\tclo = param[2]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rectni)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\trect = rectni->Get();\n\t\t}\n\t}\n\n\tbool isalpha = true;\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\tisalpha = ((tjs_int)*param[3]) ? true : false;\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 5 && param[4]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[4]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\n\tbool updated = false;\n\ttTVPRect destrect;\n\tif( TVPIntersectRect(&destrect, rect, clipRect) ) {\n\t\tif( isalpha ) {\n\t\t\tcolor = (color & 0xff000000) + (TVPToActualColor(color&0xffffff)&0xffffff);\n\t\t\tupdated = dst->GetBitmap()->Fill( destrect, color );\n\t\t} else {\n\t\t\tcolor = TVPToActualColor(color);\n\t\t\tupdated = dst->GetBitmap()->FillColor(destrect, color, 255);\n\t\t}\n\t}\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( destrect.left, destrect.top, destrect.right, destrect.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/fillRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/colorRect)\n{\n\t// bmp, value, opa=255, rect=null, face=dfAlpha, cliprect=null\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttjs_uint32 color = static_cast<tjs_uint32>((tjs_int64)*param[1]);\n\n\ttjs_int opa = 255;\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\topa = *param[2];\n\n\ttTVPRect rect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 4 && param[3]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rectni = NULL;\n\t\tclo = param[3]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rectni)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\trect = rectni->Get();\n\t\t}\n\t}\n\n\ttTVPDrawFace face = dfAlpha;\n\tif(numparams >= 5 && param[4]->Type() != tvtVoid)\n\t\tface = (tTVPDrawFace)(tjs_int)(*param[4]);\n\t\n\tif( face != dfAlpha && face != dfAddAlpha && face != dfOpaque && face != dfMask ) face = dfAlpha;\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 6 && param[5]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[5]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\tbool updated = false;\n\ttTVPRect destrect;\n\tif( TVPIntersectRect(&destrect, rect, clipRect) ) {\n\t\tswitch( face ) {\n\t\tcase dfAlpha:\n\t\t\tif( opa > 0 ) {\n\t\t\t\tcolor = TVPToActualColor(color);\n\t\t\t\tupdated = dst->GetBitmap()->FillColorOnAlpha(destrect, color, opa);\n\t\t\t} else {\n\t\t\t\tupdated = dst->GetBitmap()->RemoveConstOpacity(destrect, -opa);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase dfAddAlpha:\n\t\t\tif( opa >= 0 ) {\n\t\t\t\tcolor = TVPToActualColor(color);\n\t\t\t\tupdated = dst->GetBitmap()->FillColorOnAddAlpha(destrect, color, opa);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase dfOpaque:\n\t\t\tcolor = TVPToActualColor(color);\n\t\t\tupdated = dst->GetBitmap()->FillColor(destrect, color, opa);\n\t\t\t// note that tTVPBaseBitmap::FillColor always holds destination alpha\n\t\t\tbreak;\n\t\tcase dfMask:\n\t\t\tupdated = dst->GetBitmap()->FillMask(destrect, color&0xff );\n\t\t\tbreak;\n\t\tcase dfProvince:\n\t\tcase dfAuto:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( destrect.left, destrect.top, destrect.right, destrect.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/colorRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/drawText)\n{\n\t// bmp, font, x, y, text, color, opa=255, aa=true, face=dfAlpha, shadowlevel=0, shadowcolor=0x000000, shadowwidth=0, shadowofsx=0, shadowofsy=0, hda=false, clipRect=null\n\tif(numparams < 6) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttTJSNI_Font* font = NULL;\n\tclo = param[1]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Font::ClassID, (iTJSNativeInstance**)&font)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !font ) return TJS_E_INVALIDPARAM;\n\n\ttjs_int x = *param[2];\n\ttjs_int y = *param[3];\n\tttstr text = *param[4];\n\ttjs_uint32 color = static_cast<tjs_uint32>((tjs_int64)*param[5]);\n\ttjs_int opa = (numparams >= 7 && param[6]->Type() != tvtVoid)?(tjs_int)*param[6] : (tjs_int)255;\n\tbool aa = (numparams >= 8 && param[7]->Type() != tvtVoid)? param[7]->operator bool() : true;\n\ttTVPDrawFace face = (numparams >= 9 && param[8]->Type() != tvtVoid)? (tTVPDrawFace)(tjs_int)(*param[8]) : dfAlpha;\n\ttjs_int shadowlevel = (numparams >= 10 && param[9]->Type() != tvtVoid)? (tjs_int)*param[9] : 0;\n\ttjs_uint32 shadowcolor = (numparams >= 11 && param[10]->Type() != tvtVoid)? static_cast<tjs_uint32>((tjs_int64)*param[10]) : 0;\n\ttjs_int shadowwidth = (numparams >= 12 && param[11]->Type() != tvtVoid)? (tjs_int)*param[11] : 0;\n\ttjs_int shadowofsx = (numparams >=13 && param[12]->Type() != tvtVoid)? (tjs_int)*param[12] : 0;\n\ttjs_int shadowofsy = (numparams >=14 && param[13]->Type() != tvtVoid)? (tjs_int)*param[13] : 0;\n\tbool hda = (numparams >=15 && param[14]->Type() != tvtVoid)? param[14]->operator bool() : false;\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 16 && param[15]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[15]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\n\ttTVPBBBltMethod met;\n\tswitch(face)\n\t{\n\tcase dfAlpha:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\tcase dfAddAlpha:\n\t\tif(opa<0) return TJS_E_INVALIDPARAM;\n\t\tmet = bmAlphaOnAddAlpha;\n\t\tbreak;\n\tcase dfOpaque:\n\t\tmet = bmAlpha;\n\t\tbreak;\n\tdefault:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\t}\n\tcolor = TVPToActualColor(color);\n\ttTVPComplexRect r;\n\tdst->GetBitmap()->SetFont( font->GetFont() );\n\tdst->GetBitmap()->DrawText(clipRect, x, y, text, color, met, opa, hda, aa, shadowlevel, shadowcolor, shadowwidth,\n\t\tshadowofsx, shadowofsy, &r);\n\n\tif( result ) {\n\t\tif( r.GetCount() ) {\n\t\t\tconst tTVPRect& ur = r.GetBound();\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( ur.left, ur.top, ur.right, ur.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/drawText)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/drawGlyph)\n{\n\t// bmp, x, y, glyph, color, opa=255, aa=true, face=dfAlpha, shadowlevel=0, shadowcolor=0x000000, shadowwidth=0, shadowofsx=0, shadowofsy=0, hda=false, clipRect=null\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_Bitmap * dst = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dst)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\tif( !dst ) return TJS_E_INVALIDPARAM;\n\n\ttjs_int x = *param[1];\n\ttjs_int y = *param[2];\n\tiTJSDispatch2* glyph = param[3]->AsObjectNoAddRef();\n\ttjs_uint32 color = static_cast<tjs_uint32>((tjs_int64)*param[4]);\n\ttjs_int opa = (numparams >= 6 && param[5]->Type() != tvtVoid)?(tjs_int)*param[5] : (tjs_int)255;\n\tbool aa = (numparams >= 7 && param[6]->Type() != tvtVoid)? param[6]->operator bool() : true;\n\ttTVPDrawFace face = (numparams >= 8 && param[7]->Type() != tvtVoid)? (tTVPDrawFace)(tjs_int)(*param[7]) : dfAlpha;\n\ttjs_int shadowlevel = (numparams >= 9 && param[8]->Type() != tvtVoid)? (tjs_int)*param[8] : 0;\n\ttjs_uint32 shadowcolor = (numparams >= 10 && param[9]->Type() != tvtVoid)? static_cast<tjs_uint32>((tjs_int64)*param[9]) : 0;\n\ttjs_int shadowwidth = (numparams >= 11 && param[10]->Type() != tvtVoid)? (tjs_int)*param[10] : 0;\n\ttjs_int shadowofsx = (numparams >=12 && param[11]->Type() != tvtVoid)? (tjs_int)*param[11] : 0;\n\ttjs_int shadowofsy = (numparams >=13 && param[12]->Type() != tvtVoid)? (tjs_int)*param[12] : 0;\n\tbool hda = (numparams >=14 && param[13]->Type() != tvtVoid)? param[13]->operator bool() : false;\n\n\ttTVPRect clipRect( 0, 0, dst->GetWidth(), dst->GetHeight() );\n\tif(numparams >= 15 && param[14]->Type() == tvtObject ) {\n\t\ttTJSNI_Rect * rect = NULL;\n\t\tclo = param[14]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&rect)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\t\t\tclipRect = rect->Get();\n\t\t}\n\t}\n\n\ttTVPBBBltMethod met;\n\tswitch(face)\n\t{\n\tcase dfAlpha:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\tcase dfAddAlpha:\n\t\tif(opa<0) return TJS_E_INVALIDPARAM;\n\t\tmet = bmAlphaOnAddAlpha;\n\t\tbreak;\n\tcase dfOpaque:\n\t\tmet = bmAlpha;\n\t\tbreak;\n\tdefault:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\t}\n\tcolor = TVPToActualColor(color);\n\ttTVPComplexRect r;\n\tdst->GetBitmap()->DrawGlyph(glyph, clipRect, x, y, color, met, opa, hda, aa, shadowlevel, shadowcolor, shadowwidth,\n\t\tshadowofsx, shadowofsy, &r);\n\n\tif( result ) {\n\t\tif( r.GetCount() ) {\n\t\t\tconst tTVPRect& ur = r.GetBound();\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( ur.left, ur.top, ur.right, ur.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/drawGlyph)\n\n\tTJS_END_NATIVE_MEMBERS\n}\n\ntTJSNativeInstance *tTJSNC_ImageFunction::CreateNativeInstance() {\n\treturn new tTJSNI_ImageFunction();\n}\ntTJSNativeClass * TVPCreateNativeClass_ImageFunction()\n{\n\ttTJSNativeClass *cls = new tTJSNC_ImageFunction();\n\treturn cls;\n}"
  },
  {
    "path": "src/core/visual/ImageFunction.h",
    "content": "\n#ifndef ImageFunctionH\n#define ImageFunctionH\n\n#include \"tjsNative.h\"\n#include \"LayerIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerBitmapImpl.h\"\n#include \"ComplexRect.h\"\n\nclass tTJSNI_ImageFunction : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\npublic:\n\ttTJSNI_ImageFunction();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n};\n\n\nclass tTJSNC_ImageFunction : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_ImageFunction();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\n\tstatic tTVPBBBltMethod GetBltMethodFromOperationMode( tTVPBlendOperationMode mode, tTVPDrawFace face );\n\tstatic bool ClipDestPointAndSrcRect(tjs_int &dx, tjs_int &dy, tTVPRect &srcrectout, const tTVPRect &srcrect, const tTVPRect &clipRect);\n};\n\nextern tTJSNativeClass * TVPCreateNativeClass_ImageFunction();\n#endif // ImageFunctionH\n"
  },
  {
    "path": "src/core/visual/LayerBitmapIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Base Layer Bitmap implementation\n//---------------------------------------------------------------------------\n#include <vector>\n\n#include \"tjsCommHead.h\"\n\n#include \"DebugIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"MsgIntf.h\"\n#include \"DebugIntf.h\"\n#include \"tvpgl.h\"\n#include \"argb.h\"\n#include \"tjsUtils.h\"\n#include \"ThreadIntf.h\"\n#include \"gl/ResampleImage.h\"\n#include \"RenderManager.h\"\n#include <assert.h>\n\n//#define TVP_FORCE_BILINEAR\n\niTVPRenderManager *TVPGetSoftwareRenderManager();\n\n//---------------------------------------------------------------------------\n// To forcing bilinear interpolation, define TVP_FORCE_BILINEAR.\n\n#ifdef TVP_FORCE_BILINEAR\n\t#define TVP_BILINEAR_FORCE_COND true\n#else\n\t#define TVP_BILINEAR_FORCE_COND false\n#endif\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// intact ( does not affect ) gamma adjustment data\ntTVPGLGammaAdjustData TVPIntactGammaAdjustData =\n{ 1.0, 0, 255, 1.0, 0, 255, 1.0, 0, 255 };\n//---------------------------------------------------------------------------\nconst static float sBmFactor[] =\n{\n  59, // bmCopy,\n  59, // bmCopyOnAlpha,\n  52, // bmAlpha,\n  52, // bmAlphaOnAlpha,\n  61, // bmAdd,\n  59, // bmSub,\n  45, // bmMul,\n  10, // bmDodge,\n  58, // bmDarken,\n  56, // bmLighten,\n  42, // bmScreen,\n  52, // bmAddAlpha,\n  52, // bmAddAlphaOnAddAlpha,\n  52, // bmAddAlphaOnAlpha,\n  52, // bmAlphaOnAddAlpha,\n  52, // bmCopyOnAddAlpha,\n  32, // bmPsNormal,\n  30, // bmPsAdditive,\n  29, // bmPsSubtractive,\n  27, // bmPsMultiplicative,\n  27, // bmPsScreen,\n  15, // bmPsOverlay,\n  15, // bmPsHardLight,\n  10, // bmPsSoftLight,\n  10, // bmPsColorDodge,\n  10, // bmPsColorDodge5,\n  10, // bmPsColorBurn,\n  29, // bmPsLighten,\n  29, // bmPsDarken,\n  29, // bmPsDifference,\n  26, // bmPsDifference5,\n  66, // bmPsExclusion\n};\n\n//---------------------------------------------------------------------------\n#if 0\nstatic tjs_int GetAdaptiveThreadNum(tjs_int pixelNum, float factor)\n{\n  if (pixelNum >= factor * 500)\n    return TVPGetThreadNum();\n  else\n    return 1;\n}\n#endif\n//---------------------------------------------------------------------------\n#define RET_VOID\n#define BOUND_CHECK(x) \\\n{ \\\n\ttjs_int i; \\\n\tif(rect.left < 0) rect.left = 0; \\\n\tif(rect.top < 0) rect.top = 0; \\\n\tif(rect.right > (i=GetWidth())) rect.right = i; \\\n\tif(rect.bottom > (i=GetHeight())) rect.bottom = i; \\\n\tif(rect.right - rect.left <= 0 || rect.bottom - rect.top <= 0) \\\n\t\treturn x; \\\n}\n\n\n//---------------------------------------------------------------------------\n// tTVPBaseBitmap\n//---------------------------------------------------------------------------\n#if 0\ntTVPBaseBitmap::tTVPBaseBitmap(tjs_uint w, tjs_uint h, tjs_uint bpp) :\n\t\ttTVPNativeBaseBitmap(w, h, bpp)\n{\n}\n//---------------------------------------------------------------------------\ntTVPBaseBitmap::~tTVPBaseBitmap()\n{\n}\n#endif\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::SetSizeWithFill(tjs_uint w, tjs_uint h, tjs_uint32 fillvalue)\n{\n\t// resize, and fill the expanded region with specified value.\n\n\ttjs_uint orgw = GetWidth();\n\ttjs_uint orgh = GetHeight();\n\n\tSetSize(w, h);\n\tfillvalue = TVP_REVRGB(fillvalue);\n\n\tif(w > orgw && h > orgh)\n\t{\n\t\t// both width and height were expanded\n\t\ttTVPRect rect;\n\t\trect.left = orgw;\n\t\trect.top = 0;\n\t\trect.right = w;\n\t\trect.bottom = h;\n\t\tFill(rect, fillvalue);\n\n\t\trect.left = 0;\n\t\trect.top = orgh;\n\t\trect.right = orgw;\n\t\trect.bottom = h;\n\t\tFill(rect, fillvalue);\n\t}\n\telse if(w > orgw)\n\t{\n\t\t// width was expanded\n\t\ttTVPRect rect;\n\t\trect.left = orgw;\n\t\trect.top = 0;\n\t\trect.right = w;\n\t\trect.bottom = h;\n\t\tFill(rect, fillvalue);\n\t}\n\telse if(h > orgh)\n\t{\n\t\t// height was expanded\n\t\ttTVPRect rect;\n\t\trect.left = 0;\n\t\trect.top = orgh;\n\t\trect.right = w;\n\t\trect.bottom = h;\n\t\tFill(rect, fillvalue);\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_uint32 iTVPBaseBitmap::GetPoint(tjs_int x, tjs_int y) const\n{\n\t// get specified point's color or color index\n\tif(x < 0 || y < 0 || x >= (tjs_int)GetWidth() || y >= (tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\treturn Bitmap->GetPoint(x, y);\n#if 0\n\tif(Is32BPP())\n\t\treturn  *( (const tjs_uint32*)GetScanLine(y) + x); // 32bpp\n\telse\n\t\treturn  *( (const tjs_uint8*)GetScanLine(y) + x); // 8bpp\n#endif\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::SetPoint(tjs_int x, tjs_int y, tjs_uint32 value)\n{\n\t// set specified point's color(and opacity) or color index\n\tif(x < 0 || y < 0 || x >= (tjs_int)GetWidth() || y >= (tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\tBitmap->SetPoint(x, y, TVP_REVRGB(value));\n#if 0\n\tif(Is32BPP())\n\t\t*( (tjs_uint32*)GetScanLineForWrite(y) + x) = value; // 32bpp\n\telse\n\t\t*( (tjs_uint8*)GetScanLine(y) + x) = value; // 8bpp\n#endif\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::SetPointMain(tjs_int x, tjs_int y, tjs_uint32 color)\n{\n\t// set specified point's color (mask is not touched)\n\t// for 32bpp\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(x < 0 || y < 0 || x >= (tjs_int)GetWidth() || y >= (tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\ttjs_uint32 clr = Bitmap->GetPoint(x, y);\n\tclr &= 0xff000000;\n\tclr += TVP_REVRGB(color) & 0xffffff;\n\tBitmap->SetPoint(x, y, clr);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::SetPointMask(tjs_int x, tjs_int y, tjs_int mask)\n{\n\t// set specified point's mask (color is not touched)\n\t// for 32bpp\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(x < 0 || y < 0 || x >= (tjs_int)GetWidth() || y >= (tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\ttjs_uint32 clr = Bitmap->GetPoint(x, y);\n\tclr &= 0x00ffffff;\n\tclr += (mask & 0xff) << 24;\n\tBitmap->SetPoint(x, y, clr);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTVPBaseBitmap::Fill(tTVPRect rect, tjs_uint32 value)\n{\n\t// fill target rectangle represented as \"rect\", with color ( and opacity )\n\t// passed by \"value\".\n\t// value must be : 0xAARRGGBB (for 32bpp) or 0xII ( for 8bpp )\n\tBOUND_CHECK(false);\n\n\tif (Is32BPP()) value = TVP_REVRGB(value);\n#if 0 // use GetTextureForRender instead\n\tif(!IsIndependent())\n\t{\n\t\tif(rect.left == 0 && rect.top == 0 &&\n\t\t\trect.right == (tjs_int)GetWidth() && rect.bottom == (tjs_int)GetHeight())\n\t\t{\n\t\t\t// cover overall\n\t\t\tIndependNoCopy(); // indepent with no-copy\n\t\t}\n\t}\n\n        tjs_int pitch = GetPitchBytes();\n        tjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        tjs_int h = rect.bottom - rect.top;\n        tjs_int w = rect.right - rect.left;\n        bool is32bpp = Is32BPP();\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, 150);\n        TVPBeginThreadTask(taskNum);\n        PartialFillParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1 = h * (i + 1) / taskNum;\n          PartialFillParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->pitch = pitch;\n          param->x = rect.left;\n          param->y = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->value = value;\n          param->is32bpp = is32bpp;\n          TVPExecThreadTask(&PartialFillEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n\tstatic iTVPRenderMethod* method = GetRenderManager()->GetRenderMethod(\"FillARGB\");\n\tstatic int paramid = method->EnumParameterID(\"color\");\n\tmethod->SetParameterColor4B(paramid, value);\n\tiTVPTexture2D *reftex = GetTexture();\n\tGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray());\n\n\treturn true;\n}\n\nbool iTVPBaseBitmap::Fill(tTVPRect rect, tjs_uint32 value)\n{\n\t// fill target rectangle represented as \"rect\", with color ( and opacity )\n\t// passed by \"value\".\n\t// value must be : 0xAARRGGBB (for 32bpp) or 0xII ( for 8bpp )\n\tBOUND_CHECK(false);\n\tif (Is32BPP()) value = TVP_REVRGB(value);\n\n\tstatic iTVPRenderMethod* method = TVPGetRenderManager()->GetRenderMethod(\"FillARGB\");\n\tstatic int paramid = method->EnumParameterID(\"color\");\n\tmethod->SetParameterColor4B(paramid, value);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray());\n        return true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialFillEntry(void *v)\n{\n  const PartialFillParam *param = (const PartialFillParam *)v;\n  param->self->PartialFill(param);\n}\n\nvoid tTVPBaseBitmap::PartialFill(const PartialFillParam *param)\n{\n\n\n\tif(param->is32bpp)\n\t{\n\t\t// 32bpp\n\t\ttjs_int pitch = param->pitch;\n\t\ttjs_uint8 *sc = param->dest + param->y * pitch;\n                tjs_int x = param->x;\n\t\ttjs_int height = param->h;\n\t\ttjs_int width = param->w;\n                tjs_uint32 value = param->value;\n\n                // don't use no cache version. (for test reason)\n#if 0\n\t\tif(height * width >= 64*1024/4)\n\t\t{\n                        while (height--) \n\t\t\t{\n\t\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + x;\n\t\t\t\tTVPFillARGB_NC(p, width, value);\n\t\t\t\tsc += pitch;\n\t\t\t}\n\t\t}\n\t\telse\n#endif\n\t\t{\n                        while (height--)\n\t\t\t{\n\t\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + x;\n\t\t\t\tTVPFillARGB(p, width, value);\n\t\t\t\tsc += pitch;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// 8bpp\n\t\ttjs_int pitch = param->pitch;\n\t\ttjs_uint8 *sc = param->dest + param->y * pitch;\n                tjs_int x = param->x;\n                tjs_int height = param->h;\n                tjs_int width = param->w;\n                tjs_uint32 value = param->value;\n\n\t\twhile (height--)\n\t\t{\n\t\t\ttjs_uint8 * p = (tjs_uint8*)sc + x;\n\t\t\tmemset(p, value, width);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::FillColor(tTVPRect rect, tjs_uint32 color, tjs_int opa)\n{\n\t// fill rectangle with specified color.\n\t// this ignores destination alpha (destination alpha will not change)\n\t// opa is fill opacity if opa is positive value.\n\t// negative value of opa is not allowed.\n\tBOUND_CHECK(false);\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(opa == 0) return false; // no action\n\n\tif(opa < 0) opa = 0;\n\tif(opa > 255) opa = 255;\n\n\tcolor = TVP_REVRGB(color);\n\tiTVPRenderMethod *method;\n\tif (opa == 255) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"FillColor\");\n\t\tstatic int opa_id = _method->EnumParameterID(\"opacity\"), color_id = _method->EnumParameterID(\"color\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterOpa(opa_id, opa);\n\t\tmethod->SetParameterColor4B(color_id, color);\n\t} else {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstColorAlphaBlend\");\n\t\tstatic int color_id = _method->EnumParameterID(\"color\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterColor4B(color_id, color | 0xFF000000);\n        }\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray());\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        tjs_int h = rect.bottom - rect.top;\n        tjs_int w = rect.right - rect.left;\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, opa == 255 ? 115.f : 55.f);\n        TVPBeginThreadTask(taskNum);\n        PartialFillColorParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1 = h * (i + 1) / taskNum;\n          PartialFillColorParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->pitch = pitch;\n          param->x = rect.left;\n          param->y = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->color = color;\n          param->opa = opa;\n          TVPExecThreadTask(&PartialFillColorEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n        return true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialFillColorEntry(void *v)\n{\n  const PartialFillColorParam *param = (const PartialFillColorParam *)v;\n  param->self->PartialFillColor(param);\n}\n\nvoid tTVPBaseBitmap::PartialFillColor(const PartialFillColorParam *param)\n{\n  tjs_uint8 *sc = param->dest + param->y * param->pitch;\n  tjs_int opa = param->opa;\n  tjs_uint32 color = param->color;\n  tjs_int left = param->x;\n  tjs_int width = param->w;\n  tjs_int height = param->h;\n  tjs_int pitch = param->pitch;\n        \n\tif(opa == 255)\n\t{\n\t\t// complete opaque fill\n\t\twhile(height--)\n\t\t{\n\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\tTVPFillColor(p, width, color);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// alpha fill\n                while(height--)\n\t\t{\n\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\tTVPConstColorAlphaBlend(p, width, color, opa);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::BlendColor(tTVPRect rect, tjs_uint32 color, tjs_int opa,\n\tbool additive)\n{\n\t// fill rectangle with specified color.\n\t// this considers destination alpha (additive or simple)\n\n\tBOUND_CHECK(false);\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(opa == 0) return false; // no action\n\tif(opa < 0) opa = 0;\n\tif(opa > 255) opa = 255;\n\n        if(opa == 255 && !IsIndependent())\n          {\n            if(rect.left == 0 && rect.top == 0 &&\n               rect.right == (tjs_int)GetWidth() && rect.bottom == (tjs_int)GetHeight())\n              {\n                // cover overall\n                IndependNoCopy(); // indepent with no-copy\n              }\n          }\n\tcolor = TVP_REVRGB(color);\n\tiTVPRenderMethod *method;\n\tif (opa == 255) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"FillARGB\");\n\t\tstatic int color_id = _method->EnumParameterID(\"color\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterColor4B(color_id, color | 0xFF000000);\n\t} else if (!additive) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstColorAlphaBlend_d\");\n\t\tstatic int opa_id = _method->EnumParameterID(\"opacity\"), color_id = _method->EnumParameterID(\"color\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterOpa(opa_id, opa);\n\t\tmethod->SetParameterColor4B(color_id, color);\n\t} else {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstColorAlphaBlend_a\");\n\t\tstatic int opa_id = _method->EnumParameterID(\"opacity\"), color_id = _method->EnumParameterID(\"color\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterOpa(opa_id, opa);\n\t\tmethod->SetParameterColor4B(color_id, color);\n        }\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray());\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        tjs_int h = rect.bottom - rect.top;\n        tjs_int w = rect.right - rect.left;\n\n        tjs_int factor;\n        if (opa == 255)\n          factor = 148;\n        else if (! additive)\n          factor = 25;\n        else\n          factor = 147;\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, static_cast<float>(factor) );\n        TVPBeginThreadTask(taskNum);\n        PartialBlendColorParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1 = h * (i + 1) / taskNum;\n          PartialBlendColorParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->pitch = pitch;\n          param->x = rect.left;\n          param->y = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->color = color;\n          param->opa = opa;\n          param->additive = additive;\n          TVPExecThreadTask(&PartialBlendColorEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n        return true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialBlendColorEntry(void *v)\n{\n  const PartialBlendColorParam *param = (const PartialBlendColorParam *)v;\n  param->self->PartialBlendColor(param);\n}\n\nvoid tTVPBaseBitmap::PartialBlendColor(const PartialBlendColorParam *param)\n{\n  tjs_uint32 color = param->color;\n  tjs_int opa = param->opa;\n  bool additive = param->additive;\n\n\tif(opa == 255)\n\t{\n\t\t// complete opaque fill\n\t\tcolor |= 0xff000000;\n\n\t\ttjs_int pitch = param->pitch;\n\t\ttjs_uint8 *sc = param->dest + pitch * param->y;\n                tjs_int left = param->x;\n\t\ttjs_int width = param->w;\n                tjs_int height = param->h;\n\n                while (height--)\n\t\t{\n\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\tTVPFillARGB(p, width, color);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// alpha fill\n\t\ttjs_int pitch = param->pitch;\n\t\ttjs_uint8 *sc = param->dest + pitch * param->y;\n                tjs_int left = param->x;\n\t\ttjs_int width = param->w;\n                tjs_int height = param->h;\n\n\t\tif(!additive)\n\t\t{\n                        while(height--)\n\t\t\t{\n\t\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\t\tTVPConstColorAlphaBlend_d(p, width, color, opa);\n\t\t\t\tsc += pitch;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n                        while(height--)\n\t\t\t{\n\t\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\t\tTVPConstColorAlphaBlend_a(p, width, color, opa);\n\t\t\t\tsc += pitch;\n\t\t\t}\n\t\t}\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::RemoveConstOpacity(tTVPRect rect, tjs_int level)\n{\n\t// remove constant opacity from bitmap. ( similar to PhotoShop's eraser tool )\n\t// level is a strength of removing ( 0 thru 255 )\n\t// this cannot work with additive alpha mode.\n\n\tBOUND_CHECK(false);\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(level == 0) return false; // no action\n\tif(level < 0) level = 0;\n\tif(level > 255) level = 255;\n\n\tiTVPRenderMethod *method;\n\tif (level == 255) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"FillMask\");\n\t\tstatic int opa_id = _method->EnumParameterID(\"opacity\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterOpa(opa_id, 0);\n\t} else {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"RemoveConstOpacity\");\n\t\tstatic int opa_id = _method->EnumParameterID(\"opacity\");\n\t\tmethod = _method;\n\t\tmethod->SetParameterOpa(opa_id, level);\n        }\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray());\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        tjs_int h = rect.bottom - rect.top;\n        tjs_int w = rect.right - rect.left;\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, level == 255 ? 83.f : 50.f);\n        TVPBeginThreadTask(taskNum);\n        PartialRemoveConstOpacityParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1 = h * (i + 1) / taskNum;\n          PartialRemoveConstOpacityParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->pitch = pitch;\n          param->x = rect.left;\n          param->y = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->level = level;\n          TVPExecThreadTask(&PartialRemoveConstOpacityEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n        return true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialRemoveConstOpacityEntry(void *v)\n{\n  const PartialRemoveConstOpacityParam *param = (const PartialRemoveConstOpacityParam *)v;\n  param->self->PartialRemoveConstOpacity(param);\n}\n\nvoid tTVPBaseBitmap::PartialRemoveConstOpacity(const PartialRemoveConstOpacityParam *param)\n{\n  tjs_int pitch = param->pitch;\n  tjs_uint8 *sc = param->dest + pitch * param->y;\n  tjs_int left = param->x;\n  tjs_int width = param->w;\n  tjs_int height = param->h;\n  tjs_int level = param->level;\n\n\tif(level == 255)\n\t{\n\t\t// completely remove opacity\n                while(height--)\n\t\t{\n\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\tTVPFillMask(p, width, 0);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n\telse\n\t{\n                while(height--)\n\t\t{\n\t\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\t\tTVPRemoveConstOpacity(p, width, level);\n\t\t\tsc += pitch;\n\t\t}\n\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::FillMask(tTVPRect rect, tjs_int value)\n{\n\t// fill mask with specified value.\n\tBOUND_CHECK(false);\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"FillMask\");\n\tstatic int opa_id = method->EnumParameterID(\"opacity\");\n\tmethod->SetParameterOpa(opa_id, value);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray());\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        tjs_int h = rect.bottom - rect.top;\n        tjs_int w = rect.right - rect.left;\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, 84);\n        TVPBeginThreadTask(taskNum);\n        PartialFillMaskParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1 = h * (i + 1) / taskNum;\n          PartialFillMaskParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->pitch = pitch;\n          param->x = rect.left;\n          param->y = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->value = value;\n          TVPExecThreadTask(&PartialFillMaskEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n        return true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialFillMaskEntry(void *v)\n{\n  const PartialFillMaskParam *param = (const PartialFillMaskParam *)v;\n  param->self->PartialFillMask(param);\n}\n\nvoid tTVPBaseBitmap::PartialFillMask(const PartialFillMaskParam *param)\n{\n  tjs_int pitch = param->pitch;\n  tjs_uint8 *sc = param->dest + pitch * param->y;\n  tjs_int left = param->x;\n  tjs_int width = param->w;\n  tjs_int height = param->h;\n  tjs_int value = param->value;\n\n        while(height--)\n\t{\n\t\ttjs_uint32 * p = (tjs_uint32*)sc + left;\n\t\tTVPFillMask(p, width, value);\n\t\tsc += pitch;\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\n\nbool tTVPBaseBitmap::CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\ttTVPRect refrect, tjs_int plane)\n{\n\t// copy bitmap rectangle.\n\t// TVP_BB_COPY_MAIN in \"plane\" : main image is copied\n\t// TVP_BB_COPY_MASK in \"plane\" : mask image is copied\n\t// \"plane\" is ignored if the bitmap is 8bpp\n\t// the source rectangle is ( \"refrect\" ) and the destination upper-left corner\n\t// is (x, y).\n\tif (!Is32BPP()) plane = (TVP_BB_COPY_MASK | TVP_BB_COPY_MAIN);\n\tif (x == 0 && y == 0 && refrect.left == 0 && refrect.top == 0 &&\n\t\trefrect.right == (tjs_int)ref->GetWidth() &&\n\t\trefrect.bottom == (tjs_int)ref->GetHeight() &&\n\t\t(tjs_int)GetWidth() == refrect.right &&\n\t\t(tjs_int)GetHeight() == refrect.bottom &&\n\t\tplane == (TVP_BB_COPY_MASK | TVP_BB_COPY_MAIN) &&\n\t\t(bool)!Is32BPP() == (bool)!ref->Is32BPP())\n\t{\n\t\t// entire area of both bitmaps\n\t\tAssignTexture(ref->GetTexture());\n\t\treturn true;\n\t}\n\n\t// bound check\n\ttjs_int bmpw, bmph;\n\n\tbmpw = ref->GetWidth();\n\tbmph = ref->GetHeight();\n\n\tif (refrect.left < 0)\n\t\tx -= refrect.left, refrect.left = 0;\n\tif (refrect.right > bmpw)\n\t\trefrect.right = bmpw;\n\n\tif (refrect.left >= refrect.right) return false;\n\n\tif (refrect.top < 0)\n\t\ty -= refrect.top, refrect.top = 0;\n\tif (refrect.bottom > bmph)\n\t\trefrect.bottom = bmph;\n\n\tif (refrect.top >= refrect.bottom) return false;\n\n\tbmpw = GetWidth();\n\tbmph = GetHeight();\n\n\ttTVPRect rect;\n\trect.left = x;\n\trect.top = y;\n\trect.right = rect.left + refrect.get_width();\n\trect.bottom = rect.top + refrect.get_height();\n\n\tif (rect.left < 0)\n\t{\n\t\trefrect.left += -rect.left;\n\t\trect.left = 0;\n\t}\n\n\tif (rect.right > bmpw)\n\t{\n\t\trefrect.right -= (rect.right - bmpw);\n\t\trect.right = bmpw;\n\t}\n\n\tif (refrect.left >= refrect.right) return false; // not drawable\n\n\tif (rect.top < 0)\n\t{\n\t\trefrect.top += -rect.top;\n\t\trect.top = 0;\n\t}\n\n\tif (rect.bottom > bmph)\n\t{\n\t\trefrect.bottom -= (rect.bottom - bmph);\n\t\trect.bottom = bmph;\n\t}\n\n\tif (refrect.top >= refrect.bottom) return false; // not drawable\n\n#if 0\n        // transfer\n        tjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        const tjs_uint8 *src = (const tjs_uint8*)ref->GetScanLine(0);\n        tjs_int dpitch = GetPitchBytes();\n        tjs_int spitch = ref->GetPitchBytes();\n\ttjs_int w = refrect.get_width();\n\ttjs_int h = refrect.get_height();\n\ttjs_int pixelsize = (Is32BPP()?sizeof(tjs_uint32):sizeof(tjs_uint8));\n        bool backwardCopy = (ref == this && rect.top > refrect.top);\n\n        tjs_int taskNum = (ref == this) ? 1 : GetAdaptiveThreadNum(w * h, 66);\n        TVPBeginThreadTask(taskNum);\n        PartialCopyRectParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1=  h * (i + 1) / taskNum;\n          PartialCopyRectParam *param = params + i;\n          param->self = this;\n          param->pixelsize = pixelsize;\n          param->dest = dest;\n          param->dpitch = dpitch;\n          param->dx = rect.left;\n          param->dy = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->src = reinterpret_cast<const tjs_int8*>(src);\n          param->spitch = spitch;\n          param->sx = refrect.left;\n          param->sy = refrect.top + y0;\n          param->plane = plane;\n          param->backwardCopy = backwardCopy;\n          TVPExecThreadTask(&PartialCopyRectEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n\tiTVPRenderMethod *method;\n\tswitch (plane)\n\t{\n\tcase TVP_BB_COPY_MAIN:\n\t{\n\t\tstatic iTVPRenderMethod *_method = GetRenderManager()->GetRenderMethod(\"CopyColor\");\n\t\tmethod = _method;\n\t}\n\t\tbreak;\n\tcase TVP_BB_COPY_MASK:\n\t{\n\t\tstatic iTVPRenderMethod *_method = GetRenderManager()->GetRenderMethod(\"CopyMask\");\n\t\tmethod = _method;\n\t}\n\t\tbreak;\n\tcase TVP_BB_COPY_MAIN | TVP_BB_COPY_MASK:\n\t{\n\t\tstatic iTVPRenderMethod *_method = GetRenderManager()->GetRenderMethod(\"Copy\");\n\t\tmethod = _method;\n\t}\n\t\tbreak;\n\t}\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(ref->GetTexture(), refrect)\n\t};\n\tiTVPTexture2D *reftex = GetTexture();\n\tGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray(src_tex));\n\n\treturn true;\n}\n\nbool iTVPBaseBitmap::CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tjs_int plane)\n{\n\t// copy bitmap rectangle.\n\t// TVP_BB_COPY_MAIN in \"plane\" : main image is copied\n\t// TVP_BB_COPY_MASK in \"plane\" : mask image is copied\n\t// \"plane\" is ignored if the bitmap is 8bpp\n\t// the source rectangle is ( \"refrect\" ) and the destination upper-left corner\n\t// is (x, y).\n\tif(!Is32BPP()) plane = (TVP_BB_COPY_MASK|TVP_BB_COPY_MAIN);\n\tif(x == 0 && y == 0 && refrect.left == 0 && refrect.top == 0 &&\n\t\trefrect.right == (tjs_int)ref->GetWidth() &&\n\t\trefrect.bottom == (tjs_int)ref->GetHeight() &&\n\t\t(tjs_int)GetWidth() == refrect.right &&\n\t\t(tjs_int)GetHeight() == refrect.bottom &&\n\t\tplane == (TVP_BB_COPY_MASK|TVP_BB_COPY_MAIN) &&\n\t\t(bool)!Is32BPP() == (bool)!ref->Is32BPP())\n\t{\n\t\t// entire area of both bitmaps\n\t\tAssignTexture(ref->GetTexture());\n\t\treturn true;\n\t}\n\n\t// bound check\n\ttjs_int bmpw, bmph;\n\n\tbmpw = ref->GetWidth();\n\tbmph = ref->GetHeight();\n\n\tif(refrect.left < 0)\n\t\tx -= refrect.left, refrect.left = 0;\n\tif(refrect.right > bmpw)\n\t\trefrect.right = bmpw;\n\n\tif(refrect.left >= refrect.right) return false;\n\n\tif(refrect.top < 0)\n\t\ty -= refrect.top, refrect.top = 0;\n\tif(refrect.bottom > bmph)\n\t\trefrect.bottom = bmph;\n\n\tif(refrect.top >= refrect.bottom) return false;\n\n\tbmpw = GetWidth();\n\tbmph = GetHeight();\n\n\ttTVPRect rect;\n\trect.left = x;\n\trect.top = y;\n\trect.right = rect.left + refrect.get_width();\n\trect.bottom = rect.top + refrect.get_height();\n\n\tif(rect.left < 0)\n\t{\n\t\trefrect.left += -rect.left;\n\t\trect.left = 0;\n\t}\n\n\tif(rect.right > bmpw)\n\t{\n\t\trefrect.right -= (rect.right - bmpw);\n\t\trect.right = bmpw;\n\t}\n\n\tif(refrect.left >= refrect.right) return false; // not drawable\n\n\tif(rect.top < 0)\n\t{\n\t\trefrect.top += -rect.top;\n\t\trect.top = 0;\n\t}\n\n\tif(rect.bottom > bmph)\n\t{\n\t\trefrect.bottom -= (rect.bottom - bmph);\n\t\trect.bottom = bmph;\n\t}\n\n\tif(refrect.top >= refrect.bottom) return false; // not drawable\n\n\tiTVPRenderMethod *method;\n\t\tswitch(plane)\n\t\t{\n\t\tcase TVP_BB_COPY_MAIN:\n\t\t\t{\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"CopyColor\");\n\t\t\tmethod = _method;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MASK:\n\t\t\t{\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"CopyMask\");\n\t\t\tmethod = _method;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MAIN|TVP_BB_COPY_MASK:\n\t\t\t{\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"Copy\");\n\t\t\tmethod = _method;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(ref->GetTexture(), refrect)\n\t};\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray(src_tex));\n\treturn true;\n}\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialCopyRectEntry(void *v)\n{\n  const PartialCopyRectParam *param = (const PartialCopyRectParam *)v;\n  param->self->PartialCopyRect(param);\n}\n\nvoid tTVPBaseBitmap::PartialCopyRect(const PartialCopyRectParam *param)\n{\n\t// transfer\n\ttjs_int pixelsize = (Is32BPP()?sizeof(tjs_uint32):sizeof(tjs_uint8));\n\ttjs_int dpitch = param->dpitch;\n\ttjs_int spitch = param->spitch;\n\ttjs_int w = param->w;\n\ttjs_int wbytes = param->w * pixelsize;\n\ttjs_int h = param->h;\n        tjs_int plane = param->plane;\n        bool backwardCopy = param->backwardCopy;\n\n\tif(backwardCopy)\n\t{\n\t\t// backward copy\n#if 0\n\t\ttjs_uint8 * dest = (tjs_uint8*)GetScanLineForWrite(rect.bottom-1) +\n\t\t\trect.left*pixelsize;\n\t\tconst tjs_uint8 * src = (const tjs_uint8*)ref->GetScanLine(refrect.bottom-1) +\n\t\t\trefrect.left*pixelsize;\n#endif\n\t\ttjs_uint8 * dest = param->dest + dpitch * (param->dy + param->h - 1) + param->dx * pixelsize;\n\t\tconst tjs_uint8 * src = reinterpret_cast<const tjs_uint8*>(param->src + spitch * (param->sy + param->h - 1) + param->sx * pixelsize);\n\n\t\tswitch(plane)\n\t\t{\n\t\tcase TVP_BB_COPY_MAIN:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPCopyColor((tjs_uint32*)dest, (const tjs_uint32*)src, w);\n\t\t\t\tdest -= dpitch;\n\t\t\t\tsrc -= spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MASK:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPCopyMask((tjs_uint32*)dest, (const tjs_uint32*)src, w);\n\t\t\t\tdest -= dpitch;\n\t\t\t\tsrc -= spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MAIN|TVP_BB_COPY_MASK:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tmemmove(dest, src, wbytes);\n\t\t\t\tdest -= dpitch;\n\t\t\t\tsrc -= spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// forward copy\n#if 0\n\t\ttjs_uint8 * dest = (tjs_uint8*)GetScanLineForWrite(rect.top) +\n\t\t\trect.left*pixelsize;\n\t\tconst tjs_uint8 * src = (const tjs_uint8*)ref->GetScanLine(refrect.top) +\n\t\t\trefrect.left*pixelsize;\n#endif\n\t\ttjs_uint8 * dest = param->dest + dpitch * (param->dy) + param->dx * pixelsize;\n\t\tconst tjs_uint8 * src = reinterpret_cast<const tjs_uint8*>(param->src + spitch * (param->sy) + param->sx * pixelsize);\n\n\t\tswitch(plane)\n\t\t{\n\t\tcase TVP_BB_COPY_MAIN:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPCopyColor((tjs_uint32*)dest, (const tjs_uint32*)src, w);\n\t\t\t\tdest += dpitch;\n\t\t\t\tsrc += spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MASK:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPCopyMask((tjs_uint32*)dest, (const tjs_uint32*)src, w);\n\t\t\t\tdest += dpitch;\n\t\t\t\tsrc += spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TVP_BB_COPY_MAIN|TVP_BB_COPY_MASK:\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tmemmove(dest, src, wbytes);\n\t\t\t\tdest += dpitch;\n\t\t\t\tsrc += spitch;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::Copy9Patch( const iTVPBaseBitmap *ref, tTVPRect& margin )\n{\n\tif(!Is32BPP()) return false;\n\n\ttjs_int w = ref->GetWidth();\n\ttjs_int h = ref->GetHeight();\n\t// 9 + ㉺11sNZ͕Kv\n\tif( w < 11 || h < 11 ) return false;\n\ttjs_int dw = GetWidth();\n\ttjs_int dh = GetHeight();\n\t// Rs[悪摜̓Rs[s\n\tif( dw < (w-2) || dh < (h-2) ) return false;\n\n\tif (!TVPGetRenderManager()->IsSoftware()) {\n\t\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"Copy\");\n\t\tiTVPTexture2D *reftex = GetTexture();\n\t\ttTVPRect rcdest(0, 0, dw, dh);\n\t\tiTVPTexture2D *dsttex = GetTextureForRender(method->IsBlendTarget(), &rcdest);\n\t\ttRenderTexRectArray::Element src_tex;\n\t\ttRenderTexRectArray srctex(&src_tex, 1);\n\t\tsrc_tex.first = ref->GetTexture();\n\t\tif (margin.top > 0) {\n\t\t\tsrc_tex.second.top = 0;\n\t\t\tsrc_tex.second.bottom = margin.top;\n\t\t\ttTVPRect rect(0, 0, 0, margin.top);\n\t\t\tif (margin.left > 0) { // LT\n\t\t\t\tsrc_tex.second.left = 0;\n\t\t\t\tsrc_tex.second.right = margin.left;\n\t\t\t\trect.left = 0;\n\t\t\t\trect.bottom = margin.left;\n\t\t\t\tTVPGetRenderManager()->OperateRect(method, dsttex, reftex, rect, srctex);\n\t\t\t}\n\t\t\tif (margin.get_width() > 0) { // T\n\t\t\t\tsrc_tex.second.left = margin.left;\n\t\t\t\tsrc_tex.second.right = margin.right;\n\t\t\t\tTVPGetRenderManager()->OperateRect(method, dsttex, reftex, tTVPRect(margin.left, 0, dw - margin.right, margin.top), srctex);\n\t\t\t}\n\t\t\tif (margin.right < w) { // RT\n\t\t\t\tsrc_tex.second.left = margin.right;\n\t\t\t\tsrc_tex.second.right = w;\n\t\t\t\tTVPGetRenderManager()->OperateRect(method, dsttex, reftex, tTVPRect(dw - margin.right, 0, dw, margin.top), srctex);\n\t\t\t}\n\t\t}\n\t\tif (margin.get_height() > 0) {\n\t\t\tif (margin.left > 0) { // L\n\t\t\t\tsrc_tex.second.left = 0;\n\t\t\t\tsrc_tex.second.top = margin.top;\n\t\t\t\tsrc_tex.second.right = margin.left;\n\t\t\t\tsrc_tex.second.bottom = margin.bottom;\n\t\t\t\tTVPGetRenderManager()->OperateRect(method, dsttex, reftex, tTVPRect(0, margin.top, margin.left, dh - margin.bottom), srctex);\n\t\t\t}\n\t\t\tif (margin.get_width() > 0) { // C\n\t\t\t\t;\n\t\t\t}\n\t\t}\n\t\treturn false; // TODO implement universal version\n\t}\n\n\tconst tjs_uint32 *src = (const tjs_uint32*)ref->GetScanLine(0);\n\ttjs_int pitch = ref->GetPitchBytes() / sizeof(tjs_uint32);\n\tconst tjs_uint32 *srcbottom = (const tjs_uint32*)ref->GetScanLine(h-1);\n\ttTVPRect scale(-1,-1,-1,-1);\n\tmargin = tTVPRect( -1, -1, -1, -1 );\n\ttTVPARGB<tjs_uint8> hor, ver;\n\tfor( tjs_int x = 1; x < (w-1); x++ )\n\t{\n\t\tif( scale.left == -1 && (src[x]&0xff000000) == 0xff000000 )\n\t\t{\n\t\t\tscale.left = x;\n\t\t\thor = src[x];\n\t\t}\n\t\telse if( scale.left != -1 && scale.right == -1 && (src[x]&0xff000000) == 0 )\n\t\t{\n\t\t\tscale.right = x;\n\t\t}\n\n\t\tif( margin.left == -1 && (srcbottom[x]&0xff000000) == 0xff000000 )\n\t\t{\n\t\t\tmargin.left = x-1;\n\t\t}\n\t\telse if( margin.left != -1 && margin.right == -1 && (srcbottom[x]&0xff000000) == 0 )\n\t\t{\n\t\t\tmargin.right = w-x-1;\n\t\t}\n\n\t\tif( scale.right != -1 && margin.right != -1 ) break;\n\t}\n\n\tfor( tjs_int y = 1; y < (h-1); y++ )\n\t{\n\t\tif( scale.top == -1 && (src[y*pitch]&0xff000000) == 0xff000000 )\n\t\t{\n\t\t\tscale.top = y;\n\t\t\tver = src[y*pitch];\n\t\t}\n\t\telse if( scale.top != -1 && scale.bottom == -1 && (src[y*pitch]&0xff000000) == 0 )\n\t\t{\n\t\t\tscale.bottom = y;\n\t\t}\n\n\t\tif( margin.top == -1 && (src[y*pitch+w-1]&0xff000000) == 0xff000000 )\n\t\t{\n\t\t\tmargin.top = y-1;\n\t\t}\n\t\telse if( margin.top != -1 && margin.bottom == -1 && (src[y*pitch+w-1]&0xff000000) == 0 )\n\t\t{\n\t\t\tmargin.bottom = h-y-1;\n\t\t}\n\n\t\tif( scale.bottom != -1 && margin.bottom != -1 ) break;\n\t}\n\t// XP[p̗̈悪tȂ̓Rs[łȂ\n\tif( scale.left == -1 || scale.right == -1 || scale.top == -1 || scale.bottom == -1 )\n\t\treturn false;\n\t\n\tconst tjs_int src_left_width = scale.left - 1;\n\tconst tjs_int src_right_width = w - 1 - scale.right;\n\tconst tjs_int dst_center_width = dw - src_left_width - src_right_width;\n\tconst tjs_int src_center_width = scale.right - scale.left;\n\tconst tjs_int src_top_height = scale.top - 1;\n\tconst tjs_int src_bottom_height = h - 1 - scale.bottom;\n\tconst tjs_int src_center_height = scale.bottom - scale.top;\n\tconst tjs_int dst_center_height = dh - src_top_height - src_bottom_height;\n\tconst tjs_int src_center_step = (src_center_width<<16) / dst_center_width;\n\n\ttjs_uint32 *dst = (tjs_uint32*)GetScanLineForWrite(0);\n\ttjs_int dpitch = GetPitchBytes() / sizeof(tjs_uint32);\n\tconst tjs_uint32 *s1 = src + pitch + 1;\n\tconst tjs_uint32 *s2 = src + pitch + scale.right;\n\ttjs_uint32 *d1 = dst;\n\ttjs_uint32 *d2 = dst + src_left_width + dst_center_width;\n\t// 㑤E[̃Rs[\n\tfor( tjs_int y = 0; y < src_top_height; y++ )\n\t{\n\t\tmemcpy( d1, s1, src_left_width*sizeof(tjs_uint32));\n\t\tmemcpy( d2, s2, src_right_width*sizeof(tjs_uint32));\n\t\td1 += dpitch; s1 += pitch;\n\t\td2 += dpitch; s2 += pitch;\n\t}\n\t// 㑤\n\tconst tjs_uint32 *s3 = src + pitch + scale.left;\n\ttjs_uint32 *d3 = dst + src_left_width;\n\tif( src_center_width == 1 )\n\t{   // Rs[̕1̎͂̐FœhԂ\n\t\tfor( tjs_int y = 0; y < src_top_height; y++ )\n\t\t{\n\t\t\tTVPFillARGB( d3, dst_center_width, *s3 );\n\t\t\td3 += dpitch; s3 += pitch;\n\t\t}\n\t}\n\t//else if( v.r == 0 ) { /* scale */ } else if( v.r == 255 ) { /* repeate */ } else { /* mirror */}\n\telse\n\t{   // scale\n\t\tfor( tjs_int y = 0; y < src_top_height; y++ )\n\t\t{   // c̓uhȂ̂ōo邪cc\n\t\t\tTVPInterpStretchCopy( d3, dst_center_width, s3, s3, 0, 0, src_center_step );\n\t\t\td3 += dpitch; s3 += pitch;\n\t\t}\n\t}\n\t// Ԉʒu\n\t// s1 s2 s3 d1 d2 d3 ́AԈʒuwĂ͂\n\tif( src_center_height == 1 )\n\t{\n\t\t// Ԉʒu̗[\n\t\tfor( tjs_int y = 0; y < dst_center_height; y ++ )\n\t\t{\n\t\t\tmemcpy( d1, s1, src_left_width*sizeof(tjs_uint32));\n\t\t\tmemcpy( d2, s2, src_right_width*sizeof(tjs_uint32));\n\t\t\td1 += dpitch; d2 += dpitch;\n\t\t}\n\t\t// Ԉʒu̐^\n\t\tif( src_center_width == 1 )\n\t\t{\n\t\t\tfor( tjs_int y = 0; y < dst_center_height; y ++ )\n\t\t\t{\n\t\t\t\tTVPFillARGB( d3, dst_center_width, *s3 );\n\t\t\t\td3 += dpitch;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor( tjs_int y = 0; y < dst_center_height; y ++ )\n\t\t\t{\n\t\t\t\tTVPInterpStretchCopy( d3, dst_center_width, s3, s3, 0, 0, src_center_step );\n\t\t\t\td3 += dpitch;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\ttTVPRect cliprect(0,0,dw,dh);\n\t\t{\t\t// \n\t\t\ttTVPRect srcrect( 1,        scale.top,     scale.left, scale.bottom );\n\t\t\ttTVPRect dstrect( 0,   src_top_height, src_left_width,   (src_top_height+dst_center_height) );\n\t\t\tTVPResampleImage( cliprect, this, dstrect, ref, srcrect, stSemiFastLinear, 0.0f, bmCopy, 255, false );\n\t\t}\n\t\t{\t\t// \n\t\t\ttTVPRect srcrect(     scale.left,      scale.top,                     scale.right, scale.bottom );\n\t\t\ttTVPRect dstrect( src_left_width, src_top_height, src_left_width+dst_center_width, src_top_height+dst_center_height );\n\t\t\tTVPResampleImage( cliprect, this, dstrect, ref, srcrect, stSemiFastLinear, 0.0f, bmCopy, 255, false );   \n\t\t}\n\t\t{\t\t// E\n\t\t\ttTVPRect srcrect(          scale.right,        scale.top, w-1, scale.bottom );\n\t\t\ttTVPRect dstrect( dw - src_right_width,   src_top_height,  dw,   src_top_height+dst_center_height );\n\t\t\tTVPResampleImage( cliprect, this, dstrect, ref, srcrect, stSemiFastLinear, 0.0f, bmCopy, 255, false );\n\t\t}\n\t}\n\t\n\t// E[̃Rs[\n\ts1 = src + pitch * scale.bottom + 1;\n\ts2 = src + pitch * scale.bottom + scale.right;\n\td1 = dst + dpitch * (dh-src_bottom_height);\n\td2 = dst + dpitch * (dh-src_bottom_height) + src_left_width + dst_center_width;\n\tfor( tjs_int y = 0; y < src_bottom_height; y++ )\n\t{\n\t\tmemcpy( d1, s1, src_left_width*sizeof(tjs_uint32));\n\t\tmemcpy( d2, s2, src_right_width*sizeof(tjs_uint32));\n\t\td1 += dpitch; s1 += pitch;\n\t\td2 += dpitch; s2 += pitch;\n\t}\n\t// \n\ts3 = src + pitch * scale.bottom + scale.left;\n\td3 = dst + dpitch * (dh-src_bottom_height) + src_left_width;\n\tif( src_center_width == 1 )\n\t{   // Rs[̕1̎͂̐FœhԂ\n\t\tfor( tjs_int y = 0; y < src_bottom_height; y++ )\n\t\t{\n\t\t\tTVPFillARGB( d3, dst_center_width, *s3 );\n\t\t\td3 += dpitch; s3 += pitch;\n\t\t}\n\t}\n\telse\n\t{   // scale\n\t\tfor( tjs_int y = 0; y < src_bottom_height; y++ )\n\t\t{\n\t\t\tTVPInterpStretchCopy( d3, dst_center_width, s3, s3, 0, 0, src_center_step );\n\t\t\td3 += dpitch; s3 += pitch;\n\t\t}\n\t}\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::Blt(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\ttTVPRect refrect, tTVPBBBltMethod method, tjs_int opa, bool hda)\n{\n\t// blt src bitmap with various methods.\n\n\t// hda option ( hold destination alpha ) holds distination alpha,\n\t// but will select more complex function ( and takes more time ) for it ( if\n\t// can do )\n\n\t// this function does not matter whether source and destination bitmap is\n\t// overlapped.\n\n\tif(opa == 255 && method == bmCopy && !hda)\n\t{\n\t\treturn CopyRect(x, y, ref, refrect);\n\t}\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(opa == 0) return false; // opacity==0 has no action\n\n\t// bound check\n\ttjs_int bmpw, bmph;\n\n\tbmpw = ref->GetWidth();\n\tbmph = ref->GetHeight();\n\n\tif(refrect.left < 0)\n\t\tx -= refrect.left, refrect.left = 0;\n\tif(refrect.right > bmpw)\n\t\trefrect.right = bmpw;\n\n\tif(refrect.left >= refrect.right) return false;\n\n\tif(refrect.top < 0)\n\t\ty -= refrect.top, refrect.top = 0;\n\tif(refrect.bottom > bmph)\n\t\trefrect.bottom = bmph;\n\n\tif(refrect.top >= refrect.bottom) return false;\n\n\tbmpw = GetWidth();\n\tbmph = GetHeight();\n\n\n\ttTVPRect rect;\n\trect.left = x;\n\trect.top = y;\n\trect.right = rect.left + refrect.get_width();\n\trect.bottom = rect.top + refrect.get_height();\n\n\tif(rect.left < 0)\n\t{\n\t\trefrect.left += -rect.left;\n\t\trect.left = 0;\n\t}\n\n\tif(rect.right > bmpw)\n\t{\n\t\trefrect.right -= (rect.right - bmpw);\n\t\trect.right = bmpw;\n\t}\n\n\tif(refrect.left >= refrect.right) return false; // not drawable\n\n\tif(rect.top < 0)\n\t{\n\t\trefrect.top += -rect.top;\n\t\trect.top = 0;\n\t}\n\n\tif(rect.bottom > bmph)\n\t{\n\t\trefrect.bottom -= (rect.bottom - bmph);\n\t\trect.bottom = bmph;\n\t}\n\n\tif(refrect.top >= refrect.bottom) return false; // not drawable\n\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(ref->GetTexture(), refrect)\n\t};\n\tiTVPRenderManager *mgr = GetRenderManager();\n\tiTVPRenderMethod *rmethod = mgr->GetRenderMethod(opa, hda, method);\n\tif (!rmethod) return false;\n\tiTVPTexture2D *reftex = GetTexture();\n\tmgr->OperateRect(rmethod, GetTextureForRender(rmethod->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray(src_tex));\n#if 0\n        tjs_uint8 *dest = (tjs_uint8*)GetScanLineForWrite(0);\n        const tjs_uint8 *src = (const tjs_uint8*)ref->GetScanLine(0);\n        tjs_int dpitch = GetPitchBytes();\n        tjs_int spitch = ref->GetPitchBytes();\n\ttjs_int w = refrect.get_width();\n\ttjs_int h = refrect.get_height();\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, sBmFactor[method]);\n        TVPBeginThreadTask(taskNum);\n        PartialBltParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = h * i / taskNum;\n          y1=  h * (i + 1) / taskNum;\n          PartialBltParam *param = params + i;\n          param->self = this;\n          param->dest = dest;\n          param->dpitch = dpitch;\n          param->dx = rect.left;\n          param->dy = rect.top + y0;\n          param->w = w;\n          param->h = y1 - y0;\n          param->src = reinterpret_cast<const tjs_int8*>(src);\n          param->spitch = spitch;\n          param->sx = refrect.left;\n          param->sy = refrect.top + y0;\n          param->method = method;\n          param->opa = opa;\n          param->hda = hda;\n          TVPExecThreadTask(&PartialBltEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n#endif\n        return true;\n}\n\n#if 0\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialBltEntry(void *v)\n{\n  const PartialBltParam *param = (const PartialBltParam *)v;\n  param->self->PartialBlt(param);\n}\n\nvoid tTVPBaseBitmap::PartialBlt(const PartialBltParam *param)\n{\n  tjs_uint8 *dest;\n  const tjs_uint8 *src;\n  tjs_int dpitch, dx, dy, w, h, spitch, sx, sy;\n  tTVPBBBltMethod method;\n  tjs_int opa;\n  bool hda;\n\n  dest = param->dest;\n  dpitch = param->dpitch;\n  dx = param->dx;\n  dy = param->dy;\n  w = param->w;\n  h = param->h;\n  src = reinterpret_cast<const tjs_uint8*>(param->src);\n  spitch = param->spitch;\n  sx = param->sx;\n  sy = param->sy;\n  method = param->method;\n  opa = param->opa;\n  hda = param->hda;\n\n  dest += dy * dpitch + dx * sizeof(tjs_uint32);\n  src  += sy * spitch + sx * sizeof(tjs_uint32);\n\n#define TVP_BLEND_4(basename) /* blend for 4 types (normal, opacity, HDA, HDA opacity) */ \\\n\tif(opa == 255)                                                            \\\n\t{                                                                         \\\n\t\tif(!hda)                                                              \\\n\t\t{                                                                     \\\n\t\t\twhile(h--)                                                        \\\n\t\t\t\tbasename((tjs_uint32*)dest, (tjs_uint32*)src, w),             \\\n\t\t\t\tdest+=dpitch, src+=spitch;                                    \\\n                                                                              \\\n\t\t}                                                                     \\\n\t\telse                                                                  \\\n\t\t{                                                                     \\\n\t\t\twhile(h--)                                                        \\\n\t\t\t\tbasename##_HDA((tjs_uint32*)dest, (tjs_uint32*)src, w),       \\\n\t\t\t\tdest+=dpitch, src+=spitch;                                    \\\n\t\t}                                                                     \\\n\t}                                                                         \\\n\telse                                                                      \\\n\t{                                                                         \\\n\t\tif(!hda)                                                              \\\n\t\t{                                                                     \\\n\t\t\twhile(h--)                                                        \\\n\t\t\t\tbasename##_o((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),    \\\n\t\t\t\tdest+=dpitch, src+=spitch;                                    \\\n\t\t}                                                                     \\\n\t\telse                                                                  \\\n\t\t{                                                                     \\\n\t\t\twhile(h--)                                                        \\\n\t\t\t\tbasename##_HDA_o((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\\\n\t\t\t\tdest+=dpitch, src+=spitch;                                    \\\n\t\t}                                                                     \\\n\t}\n\n\n\tswitch(method)\n\t{\n\tcase bmCopy:\n\t\t// constant ratio alpha blendng\n\t\tif(opa == 255 && hda)\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPCopyColor((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\telse if(!hda)\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPConstAlphaBlend((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPConstAlphaBlend_HDA((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\tbreak;\n\n\tcase bmCopyOnAlpha:\n\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t// with consideration of destination alpha\n\t\tif(opa == 255)\n\t\t\twhile(h--)\n\t\t\t\tTVPCopyOpaqueImage((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\telse\n\t\t\twhile(h--)\n\t\t\t\tTVPConstAlphaBlend_d((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\tbreak;\n\n\n\tcase bmAlpha:\n\t\t// alpha blending, ignoring destination alpha\n\t\tTVP_BLEND_4(TVPAlphaBlend);\n\t\tbreak;\n\n\tcase bmAlphaOnAlpha:\n\t\t// alpha blending, with consideration of destination alpha\n\t\tif(opa == 255)\n\t\t\twhile(h--)\n\t\t\t\tTVPAlphaBlend_d((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\telse\n\t\t\twhile(h--)\n\t\t\t\tTVPAlphaBlend_do((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\tbreak;\n\n\tcase bmAdd:\n\t\t// additive blending ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPAddBlend);\n\t\tbreak;\n\n\tcase bmSub:\n\t\t// subtractive blending ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPSubBlend);\n\t\tbreak;\n\n\tcase bmMul:\n\t\t// multiplicative blending ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPMulBlend);\n\t\tbreak;\n\n\n\tcase bmDodge:\n\t\t// color dodge mode ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPColorDodgeBlend);\n\t\tbreak;\n\n\n\tcase bmDarken:\n\t\t// darken mode ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPDarkenBlend);\n\t\tbreak;\n\n\n\tcase bmLighten:\n\t\t// lighten mode ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPLightenBlend);\n\t\tbreak;\n\n\n\tcase bmScreen:\n\t\t// screen multiplicative mode ( this does not consider distination alpha )\n\t\tTVP_BLEND_4(TVPScreenBlend);\n\t\tbreak;\n\n\n\tcase bmAddAlpha:\n\t\t// Additive Alpha\n\t\tTVP_BLEND_4(TVPAdditiveAlphaBlend);\n\t\tbreak;\n\n\n\tcase bmAddAlphaOnAddAlpha:\n\t\t// Additive Alpha on Additive Alpha\n\t\tif(opa == 255)\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPAdditiveAlphaBlend_a((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPAdditiveAlphaBlend_ao((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\tbreak;\n\n\n\tcase bmAddAlphaOnAlpha:\n\t\t// additive alpha on simple alpha\n\t\t// Not yet implemented\n\t\tbreak;\n\n\tcase bmAlphaOnAddAlpha:\n\t\t// simple alpha on additive alpha\n\t\tif(opa == 255)\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPAlphaBlend_a((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(h--)\n\t\t\t\tTVPAlphaBlend_ao((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\t}\n\t\tbreak;\n\n\tcase bmCopyOnAddAlpha:\n\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t// with consideration of destination additive alpha\n\t\tif(opa == 255)\n\t\t\twhile(h--)\n\t\t\t\tTVPCopyOpaqueImage((tjs_uint32*)dest, (tjs_uint32*)src, w),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\telse\n\t\t\twhile(h--)\n\t\t\t\tTVPConstAlphaBlend_a((tjs_uint32*)dest, (tjs_uint32*)src, w, opa),\n\t\t\t\tdest+=dpitch, src+=spitch;\n\t\tbreak;\n\n\n\tcase bmPsNormal:\n\t\t// Photoshop compatible normal blend\n\t\t// (may take the same effect as bmAlpha)\n\t\tTVP_BLEND_4(TVPPsAlphaBlend);\n\t\tbreak;\n\n\tcase bmPsAdditive:\n\t\t// Photoshop compatible additive blend\n\t\tTVP_BLEND_4(TVPPsAddBlend);\n\t\tbreak;\n\n\tcase bmPsSubtractive:\n\t\t// Photoshop compatible subtractive blend\n\t\tTVP_BLEND_4(TVPPsSubBlend);\n\t\tbreak;\n\n\tcase bmPsMultiplicative:\n\t\t// Photoshop compatible multiplicative blend\n\t\tTVP_BLEND_4(TVPPsMulBlend);\n\t\tbreak;\n\n\tcase bmPsScreen:\n\t\t// Photoshop compatible screen blend\n\t\tTVP_BLEND_4(TVPPsScreenBlend);\n\t\tbreak;\n\n\tcase bmPsOverlay:\n\t\t// Photoshop compatible overlay blend\n\t\tTVP_BLEND_4(TVPPsOverlayBlend);\n\t\tbreak;\n\n\tcase bmPsHardLight:\n\t\t// Photoshop compatible hard light blend\n\t\tTVP_BLEND_4(TVPPsHardLightBlend);\n\t\tbreak;\n\n\tcase bmPsSoftLight:\n\t\t// Photoshop compatible soft light blend\n\t\tTVP_BLEND_4(TVPPsSoftLightBlend);\n\t\tbreak;\n\n\tcase bmPsColorDodge:\n\t\t// Photoshop compatible color dodge blend\n\t\tTVP_BLEND_4(TVPPsColorDodgeBlend);\n\t\tbreak;\n\n\tcase bmPsColorDodge5:\n\t\t// Photoshop 5.x compatible color dodge blend\n\t\tTVP_BLEND_4(TVPPsColorDodge5Blend);\n\t\tbreak;\n\n\tcase bmPsColorBurn:\n\t\t// Photoshop compatible color burn blend\n\t\tTVP_BLEND_4(TVPPsColorBurnBlend);\n\t\tbreak;\n\n\tcase bmPsLighten:\n\t\t// Photoshop compatible compare (lighten) blend\n\t\tTVP_BLEND_4(TVPPsLightenBlend);\n\t\tbreak;\n\n\tcase bmPsDarken:\n\t\t// Photoshop compatible compare (darken) blend\n\t\tTVP_BLEND_4(TVPPsDarkenBlend);\n\t\tbreak;\n\n\tcase bmPsDifference:\n\t\t// Photoshop compatible difference blend\n\t\tTVP_BLEND_4(TVPPsDiffBlend);\n\t\tbreak;\n\n\tcase bmPsDifference5:\n\t\t// Photoshop 5.x compatible difference blend\n\t\tTVP_BLEND_4(TVPPsDiff5Blend);\n\t\tbreak;\n\n\tcase bmPsExclusion:\n\t\t// Photoshop compatible exclusion blend\n\t\tTVP_BLEND_4(TVPPsExclusionBlend);\n\t\tbreak;\n\n\n\tdefault:\n\t\t\t\t ;\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::Blt(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\tconst tTVPRect &refrect, tTVPLayerType type, tjs_int opa, bool hda) {\n\n\ttTVPBBBltMethod met;\n\tswitch (type) {\n\tcase ltBinder:\n\t\t// no action\n\t\treturn false;\n\n\tcase ltOpaque: // formerly ltCoverRect\n\t\t\t\t   // copy\n\t\tmet = opa == 255 ? bmCopy : bmCopyOnAlpha;\n\t\tbreak;\n\n\tcase ltAlpha: // formerly ltTransparent\n\t\t\t\t  // alpha blend\n\t\tmet = hda ? bmAlpha : bmAlphaOnAlpha;\n\t\tbreak;\n\n\tcase ltAdditive:\n\t\t// additive blend\n\t\t// hda = true if destination has alpha\n\t\t// ( preserving mask )\n\t\tmet = bmAdd;\n\t\tbreak;\n\n\tcase ltSubtractive:\n\t\t// subtractive blend\n\t\tmet = bmSub;\n\t\tbreak;\n\n\tcase ltMultiplicative:\n\t\t// multiplicative blend\n\t\tmet = bmMul;\n\t\tbreak;\n\n\tcase ltDodge:\n\t\t// color dodge ( \"Ooi yaki\" in Japanese )\n\t\tmet = bmDodge;\n\t\tbreak;\n\n\tcase ltDarken:\n\t\t// darken blend (select lower luminosity)\n\t\tmet = bmDarken;\n\t\tbreak;\n\n\tcase ltLighten:\n\t\t// lighten blend (select higher luminosity)\n\t\tmet = bmLighten;\n\t\tbreak;\n\n\tcase ltScreen:\n\t\t// screen multiplicative blend\n\t\tmet = bmScreen;\n\t\tbreak;\n\n\tcase ltAddAlpha:\n\t\t// alpha blend\n\t\tmet = bmAddAlpha;\n\t\tbreak;\n\n\tcase ltPsNormal:\n\t\t// Photoshop compatible normal blend\n\t\tmet = bmPsNormal;\n\t\tbreak;\n\n\tcase ltPsAdditive:\n\t\t// Photoshop compatible additive blend\n\t\tmet = bmPsAdditive;\n\t\tbreak;\n\n\tcase ltPsSubtractive:\n\t\t// Photoshop compatible subtractive blend\n\t\tmet = bmPsSubtractive;\n\t\tbreak;\n\n\tcase ltPsMultiplicative:\n\t\t// Photoshop compatible multiplicative blend\n\t\tmet = bmPsMultiplicative;\n\t\tbreak;\n\n\tcase ltPsScreen:\n\t\t// Photoshop compatible screen blend\n\t\tmet = bmPsScreen;\n\t\tbreak;\n\n\tcase ltPsOverlay:\n\t\t// Photoshop compatible overlay blend\n\t\tmet = bmPsOverlay;\n\t\tbreak;\n\n\tcase ltPsHardLight:\n\t\t// Photoshop compatible hard light blend\n\t\tmet = bmPsHardLight;\n\t\tbreak;\n\n\tcase ltPsSoftLight:\n\t\t// Photoshop compatible soft light blend\n\t\tmet = bmPsSoftLight;\n\t\tbreak;\n\n\tcase ltPsColorDodge:\n\t\t// Photoshop compatible color dodge blend\n\t\tmet = bmPsColorDodge;\n\t\tbreak;\n\n\tcase ltPsColorDodge5:\n\t\t// Photoshop 5.x compatible color dodge blend\n\t\tmet = bmPsColorDodge5;\n\t\tbreak;\n\n\tcase ltPsColorBurn:\n\t\t// Photoshop compatible color burn blend\n\t\tmet = bmPsColorBurn;\n\t\tbreak;\n\n\tcase ltPsLighten:\n\t\t// Photoshop compatible compare (lighten) blend\n\t\tmet = bmPsLighten;\n\t\tbreak;\n\n\tcase ltPsDarken:\n\t\t// Photoshop compatible compare (darken) blend\n\t\tmet = bmPsDarken;\n\t\tbreak;\n\n\tcase ltPsDifference:\n\t\t// Photoshop compatible difference blend\n\t\tmet = bmPsDifference;\n\t\tbreak;\n\n\tcase ltPsDifference5:\n\t\t// Photoshop 5.x compatible difference blend\n\t\tmet = bmPsDifference5;\n\t\tbreak;\n\n\tcase ltPsExclusion:\n\t\t// Photoshop compatible exclusion blend\n\t\tmet = bmPsExclusion;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\treturn Blt(x, y, ref, refrect, met, opa, hda);\n}\n#if 0\n//---------------------------------------------------------------------------\n// template function for strech loop\n//---------------------------------------------------------------------------\n\n// define function pointer types for stretching line\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPStretchFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int srcstart, tjs_int srcstep));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPStretchWithOpacityFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int srcstart, tjs_int srcstep, tjs_int opa));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearStretchFunction,\n\t(tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearStretchWithOpacityFunction,\n\t(tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\n\n//---------------------------------------------------------------------------\n\n// declare stretching function object class\nclass tTVPStretchFunctionObject\n{\n\ttTVPStretchFunction Func;\npublic:\n\ttTVPStretchFunctionObject(tTVPStretchFunction func) : Func(func) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int srcstart, tjs_int srcstep)\n\t{\n\t\tFunc(dest, len, src, srcstart, srcstep);\n\t}\n};\n\nclass tTVPStretchWithOpacityFunctionObject\n{\n\ttTVPStretchWithOpacityFunction Func;\n\ttjs_int Opacity;\npublic:\n\ttTVPStretchWithOpacityFunctionObject(tTVPStretchWithOpacityFunction func, tjs_int opa) :\n\t\tFunc(func), Opacity(opa) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int srcstart, tjs_int srcstep)\n\t{\n\t\tFunc(dest, len, src, srcstart, srcstep, Opacity);\n\t}\n};\n\nclass tTVPBilinearStretchFunctionObject\n{\nprotected:\n\ttTVPBilinearStretchFunction Func;\npublic:\n\ttTVPBilinearStretchFunctionObject(tTVPBilinearStretchFunction func) : Func(func) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep)\n\t{\n\t\tFunc(dest, destlen, src1, src2, blend_y, srcstart, srcstep);\n\t}\n};\n\n#define TVP_DEFINE_BILINEAR_STRETCH_FUNCTION(func, one) class \\\nt##func##FunctionObject : \\\n\tpublic tTVPBilinearStretchFunctionObject \\\n{ \\\npublic: \\\n\tt##func##FunctionObject() : \\\n\t\ttTVPBilinearStretchFunctionObject(func) {;} \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n};\n\n\nclass tTVPBilinearStretchWithOpacityFunctionObject\n{\nprotected:\n\ttTVPBilinearStretchWithOpacityFunction Func;\n\ttjs_int Opacity;\npublic:\n\ttTVPBilinearStretchWithOpacityFunctionObject(tTVPBilinearStretchWithOpacityFunction func, tjs_int opa) :\n\t\tFunc(func), Opacity(opa) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep)\n\t{\n\t\tFunc(dest, destlen, src1, src2, blend_y, srcstart, srcstep, Opacity);\n\t}\n};\n\n#define TVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(func, one) class \\\nt##func##FunctionObject : \\\n\tpublic tTVPBilinearStretchWithOpacityFunctionObject \\\n{ \\\npublic: \\\n\tt##func##FunctionObject(tjs_int opa) : \\\n\t\ttTVPBilinearStretchWithOpacityFunctionObject(func, opa) {;} \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n};\n\n//---------------------------------------------------------------------------\n\n// declare streting function object for bilinear interpolation\nTVP_DEFINE_BILINEAR_STRETCH_FUNCTION(\n\tTVPInterpStretchCopy,\n\t*dest = color);\n\nTVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(\n\tTVPInterpStretchConstAlphaBlend,\n\t*dest = TVPBlendARGB(*dest, color, Opacity));\n\nTVP_DEFINE_BILINEAR_STRETCH_FUNCTION(\n\tTVPInterpStretchAdditiveAlphaBlend,\n\t*dest = TVPAddAlphaBlend_n_a(*dest, color));\n\nTVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(\n\tTVPInterpStretchAdditiveAlphaBlend_o,\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, color, Opacity));\n\n//---------------------------------------------------------------------------\n\n// declare stretching loop function\n#define TVP_DoStretchLoop_ARGS  x_ref_start, y_ref_start, x_len, y_len, \\\n\t\t\t\t\t\tdestp, destpitch, x_step, \\\n\t\t\t\t\t\ty_step, refp, refpitch\ntemplate <typename tFunc>\nvoid tTVPBaseBitmap::TVPDoStretchLoop(\n\t\ttFunc func,\n\t\ttjs_int x_ref_start,\n\t\ttjs_int y_ref_start,\n\t\ttjs_int x_len, tjs_int y_len,\n\t\ttjs_uint8 * destp, tjs_int destpitch,\n\t\ttjs_int x_step, tjs_int y_step,\n\t\tconst tjs_uint8 * refp, tjs_int refpitch)\n{\n\ttjs_int y_ref = y_ref_start;\n\twhile(y_len--)\n\t{\n\t\tfunc(\n\t\t\t(tjs_uint32*)destp,\n\t\t\tx_len,\n\t\t\t(const tjs_uint32*)(refp + (y_ref>>16)*refpitch),\n\t\t\tx_ref_start,\n\t\t\tx_step);\n\t\ty_ref += y_step;\n\t\tdestp += destpitch;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n// declare stretching loop function for bilinear interpolation\n\n#define TVP_DoBilinearStretchLoop_ARGS  rw, rh, dw, dh, \\\n\t\t\t\t\t\tsrccliprect, x_ref_start, y_ref_start, x_len, y_len, \\\n\t\t\t\t\t\tdestp, destpitch, x_step, \\\n\t\t\t\t\t\ty_step, refp, refpitch\ntemplate <typename tStretchFunc>\nvoid tTVPBaseBitmap::TVPDoBiLinearStretchLoop(\n\t\ttStretchFunc stretch,\n\t\ttjs_int rw, tjs_int rh,\n\t\ttjs_int dw, tjs_int dh,\n\t\tconst tTVPRect & srccliprect,\n\t\ttjs_int x_ref_start,\n\t\ttjs_int y_ref_start,\n\t\ttjs_int x_len, tjs_int y_len,\n\t\ttjs_uint8 * destp, tjs_int destpitch,\n\t\ttjs_int x_step, tjs_int y_step,\n\t\tconst tjs_uint8 * refp, tjs_int refpitch)\n{\n/*\n\tmemo\n          0         1         2         3         4\n          .         .         .         .                  center = 1.5 = (4-1) / 2\n          ------------------------------                 reference area\n     ----------++++++++++----------++++++++++\n                         ^                                 4 / 1  step 4   ofs =  1.5   = ((4-1) - (1-1)*4) / 2\n               ^                   ^                       4 / 2  step 2   ofs =  0.5   = ((4-1) - (2-1)*2) / 2\n          ^         ^         ^         *                  4 / 4  step 1   ofs =  0     = ((4-1) - (4-1)*1) / 2\n         *       ^       ^       ^       *                 4 / 5  steo 0.8 ofs = -0.1   = ((4-1) - (5-1)*0.8) / 2\n        *    ^    ^    ^    ^    ^    ^    *               4 / 8  step 0.5 ofs = -0.25\n\n*/\n\n\n\n\t// adjust start point\n\tif(x_step >= 0)\n\t\tx_ref_start += (((rw-1)<<16) - (dw-1)*x_step)/2;\n\telse\n\t\tx_ref_start -= (((rw-1)<<16) + (dw-1)*x_step)/2 - x_step;\n\tif(y_step >= 0)\n\t\ty_ref_start += (((rh-1)<<16) - (dh-1)*y_step)/2;\n\telse\n\t\ty_ref_start -= (((rh-1)<<16) + (dh-1)*y_step)/2 - y_step;\n\n\t// horizontal destination line is splitted into three parts;\n\t// 1. left fraction (x_ref < srccliprect.left               (lf)\n\t//                or x_ref >= srccliprect.right - 1)\n\t// 2. center                                 (c)\n\t// 3. right fraction (x_ref >= srccliprect.right - 1        (rf)\n\t//                or x_ref < srccliprect.left)\n\n\ttjs_int ref_left_limit  = (srccliprect.left)<<16;\n\ttjs_int ref_right_limit = (srccliprect.right-1)<<16;\n\n\ttjs_int y_ref = y_ref_start;\n\twhile(y_len--)\n\t{\n\t\ttjs_int y1 = y_ref >> 16;\n\t\ttjs_int y2 = y1+1;\n\t\ttjs_int y_blend = (y_ref & 0xffff) >> 8;\n\t\tif(y1 < srccliprect.top)\n\t\t\ty1 = srccliprect.top;\n\t\telse if(y1 >= srccliprect.bottom)\n\t\t\ty1 = srccliprect.bottom - 1;\n\t\tif(y2 < srccliprect.top)\n\t\t\ty2 = srccliprect.top;\n\t\telse if(y2 >= srccliprect.bottom)\n\t\t\ty2 = srccliprect.bottom - 1;\n\n\t\tconst tjs_uint32 * l1 =\n\t\t\t(const tjs_uint32*)(refp + refpitch * y1);\n\t\tconst tjs_uint32 * l2 =\n\t\t\t(const tjs_uint32*)(refp + refpitch * y2);\n\n\n\t\t// perform left and right fractions\n\t\ttjs_int x_remain = x_len;\n\t\ttjs_uint32 * dp;\n\t\ttjs_int x_ref;\n\n\t\t// from last point\n\t\tif(x_remain)\n\t\t{\n\t\t\tdp = (tjs_uint32*)destp + (x_len - 1);\n\t\t\tx_ref = x_ref_start + (x_len - 1) * x_step;\n\t\t\tif(x_ref < ref_left_limit)\n\t\t\t{\n\t\t\t\ttjs_uint color =\n\t\t\t\t\tTVPBlendARGB(\n\t\t\t\t\t\t*(l1 + srccliprect.left),\n\t\t\t\t\t\t*(l2 + srccliprect.left), y_blend);\n\t\t\t\tdo\n\t\t\t\t\tstretch.DoOnePixel(dp, color), dp-- , x_ref -= x_step, x_remain --;\n\t\t\t\twhile(x_ref < ref_left_limit && x_remain);\n\t\t\t}\n\t\t\telse if(x_ref >= ref_right_limit)\n\t\t\t{\n\t\t\t\ttjs_uint color =\n\t\t\t\t\tTVPBlendARGB(\n\t\t\t\t\t\t*(l1 + srccliprect.right - 1),\n\t\t\t\t\t\t*(l2 + srccliprect.right - 1), y_blend);\n\t\t\t\tdo\n\t\t\t\t\tstretch.DoOnePixel(dp, color), dp-- , x_ref -= x_step, x_remain --;\n\t\t\t\twhile(x_ref >= ref_right_limit && x_remain);\n\t\t\t}\n\t\t}\n\n\t\t// from first point\n\t\tif(x_remain)\n\t\t{\n\t\t\tdp = (tjs_uint32*)destp;\n\t\t\tx_ref = x_ref_start;\n\t\t\tif(x_ref < ref_left_limit)\n\t\t\t{\n\t\t\t\ttjs_uint color =\n\t\t\t\t\tTVPBlendARGB(\n\t\t\t\t\t\t*(l1 + srccliprect.left),\n\t\t\t\t\t\t*(l2 + srccliprect.left), y_blend);\n\t\t\t\tdo\n\t\t\t\t\tstretch.DoOnePixel(dp, color), dp++ , x_ref += x_step, x_remain --;\n\t\t\t\twhile(x_ref < ref_left_limit && x_remain);\n\t\t\t}\n\t\t\telse if(x_ref >= ref_right_limit)\n\t\t\t{\n\t\t\t\ttjs_uint color =\n\t\t\t\t\tTVPBlendARGB(\n\t\t\t\t\t\t*(l1 + srccliprect.right - 1),\n\t\t\t\t\t\t*(l2 + srccliprect.right - 1), y_blend);\n\t\t\t\tdo\n\t\t\t\t\tstretch.DoOnePixel(dp, color), dp++ , x_ref += x_step, x_remain --;\n\t\t\t\twhile(x_ref >= ref_right_limit && x_remain);\n\t\t\t}\n\t\t}\n\n\t\t// perform center part\n\t\t// (this may take most time of this function)\n\t\tif(x_remain)\n\t\t{\n\t\t\tstretch(\n\t\t\t\tdp,\n\t\t\t\tx_remain,\n\t\t\t\tl1, l2, y_blend,\n\t\t\t\tx_ref,\n\t\t\t\tx_step);\n\t\t}\n\n\t\t// step to the next line\n\t\ty_ref += y_step;\n\t\tdestp += destpitch;\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::StretchBlt(tTVPRect cliprect,\n\t\ttTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tTVPBBBltMethod method, tjs_int opa,\n\t\t\tbool hda, tTVPBBStretchType mode, tjs_real typeopt )\n{\n\t// do stretch blt\n\t// stFastLinear is enabled only in following condition:\n\t// -------TODO: write corresponding condition--------\n\n\t// stLinear and stCubic mode are enabled only in following condition:\n\t// any magnification, opa:255, method:bmCopy, hda:false\n\t// no reverse, destination rectangle is within the image.\n\n\t// source and destination check\n\ttjs_int dw = destrect.get_width(), dh = destrect.get_height();\n\ttjs_int rw = refrect.get_width(), rh = refrect.get_height();\n\n\tif(!dw || !rw || !dh || !rh) return false; // nothing to do\n\n\t// quick check for simple blt\n\tif(dw == rw && dh == rh && destrect.included_in(cliprect))\n\t{\n\t\treturn Blt(destrect.left, destrect.top, ref, refrect, method, opa, hda);\n\t\t\t// no stretch; do normal blt\n\t}\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\t// check for special case noticed above\n\t\n\t//--- extract stretch type\n\ttTVPBBStretchType type = (tTVPBBStretchType)(mode & stTypeMask);\n\n\t//--- pull the dimension\n\ttjs_int w = GetWidth();\n\ttjs_int h = GetHeight();\n\ttjs_int refw = ref->GetWidth();\n\ttjs_int refh = ref->GetHeight();\n\n\t//--- clop clipping rectangle with the image\n\ttTVPRect cr = cliprect;\n\tif(cr.left < 0) cr.left = 0;\n\tif(cr.top < 0) cr.top = 0;\n\tif(cr.right > w) cr.right = w;\n\tif(cr.bottom > h) cr.bottom = h;\n\n\tif (cr.left > destrect.left) {\n\t\trefrect.left += (float)rw / dw * (cr.left - destrect.left);\n\t\tdestrect.left = cr.left;\n\t}\n\tif (cr.right < destrect.right) {\n\t\trefrect.right -= (float)refrect.get_width() / destrect.get_width() * (destrect.right - cr.right);\n\t\tdestrect.right = cr.right;\n\t}\n\tif (cr.top > destrect.top) {\n\t\trefrect.top += (float)rh / dh * (cr.top - destrect.top);\n\t\tdestrect.top = cr.top;\n\t}\n\tif (cr.bottom < destrect.bottom) {\n\t\trefrect.bottom -= (float)refrect.get_height() / destrect.get_height() * (destrect.bottom - cr.bottom);\n\t\tdestrect.bottom = cr.bottom;\n\t}\n\n\tstatic int StretchTypeId = TVPGetRenderManager()->EnumParameterID(\"StretchType\");\n\tTVPGetRenderManager()->SetParameterInt(StretchTypeId, (int)type);\n\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(ref->GetTexture(), refrect)\n\t};\n\tiTVPRenderManager *mgr = GetRenderManager();\n\tiTVPRenderMethod *rmethod = mgr->GetRenderMethod(opa, hda, method);\n\tif (!rmethod) return false;\n\tiTVPTexture2D *reftex = GetTexture();\n\tmgr->OperateRect(rmethod, GetTextureForRender(rmethod->IsBlendTarget(), &destrect), reftex,\n\t\tdestrect, tRenderTexRectArray(src_tex));\n\treturn true;\n#if 0\n\t//--- check mode and other conditions\n\tif( type >= stLinear )\n\t{\n\t\t// takes another routine\n\t\tTVPResampleImage( cliprect, this, destrect, ref, refrect, type, typeopt, method, opa, hda );\n\t\treturn true;\n\t}\n\n\n\n\t// pass to affine operation routine\n\ttTVPPointD points[3];\n\tpoints[0].x = (double)destrect.left - 0.5;\n\tpoints[0].y = (double)destrect.top - 0.5;\n\tpoints[1].x = (double)destrect.right - 0.5;\n\tpoints[1].y = (double)destrect.top - 0.5;\n\tpoints[2].x = (double)destrect.left - 0.5;\n\tpoints[2].y = (double)destrect.bottom - 0.5;\n\treturn AffineBlt(cliprect, ref, refrect, points, method,\n\t\t\t\t\topa, NULL, hda, mode, false, 0);\n\n#if 0\n\t// extract stretch type\n\ttTVPBBStretchType type = (tTVPBBStretchType)(mode & stTypeMask);\n\n\t// compute pitch, step, etc. needed for stretching copy/blt\n\ttjs_int w = GetWidth();\n\ttjs_int h = GetHeight();\n\ttjs_int refw = ref->GetWidth();\n\ttjs_int refh = ref->GetHeight();\n\n\n\t// check clipping rect\n\tif(cliprect.left < 0) cliprect.left = 0;\n\tif(cliprect.top < 0) cliprect.top = 0;\n\tif(cliprect.right > w) cliprect.right = w;\n\tif(cliprect.bottom > h) cliprect.bottom = h;\n\n\t// check mode\n\tif((type == stLinear || type == stCubic) && !hda && opa==255 && method==bmCopy\n\t\t&& dw > 0 && dh > 0 && rw > 0 && rh > 0 &&\n\t\tdestrect.left >= cliprect.left && destrect.top >= cliprect.top &&\n\t\tdestrect.right <= cliprect.right && destrect.bottom <= cliprect.bottom)\n\t{\n\t\t// takes another routine\n\t\tTVPResampleImage(this, destrect, ref, refrect, type==stLinear?1:2);\n\t\treturn true;\n\t}\n\n\n\t// check transfer direction\n\tbool x_dir = true, y_dir = true; // direction;  true:forward, false:backward\n\n\tif(dw < 0)\n\t\tx_dir = !x_dir, std::swap(destrect.left, destrect.right), dw = -dw;\n\tif(dh < 0)\n\t\ty_dir = !y_dir, std::swap(destrect.top, destrect.bottom), dh = -dh;\n\n\tif(rw < 0)\n\t\tx_dir = !x_dir, std::swap(refrect.left, refrect.right), rw = -rw;\n\tif(rh < 0)\n\t\ty_dir = !y_dir, std::swap(refrect.top, refrect.bottom), rh = -rh;\n\n\t// ref bound check\n\tif(refrect.left >= refrect.right ||\n\t\trefrect.top >= refrect.bottom) return false;\n\tif(refrect.left < 0 || refrect.right > refw ||\n\t\trefrect.top < 0 || refrect.bottom > refh)\n\t\tTVPThrowExceptionMessage(TVPSrcRectOutOfBitmap);\n\n\t// make srccliprect\n\ttTVPRect srccliprect;\n\tif(mode & stRefNoClip)\n\t\tsrccliprect.left = 0,\n\t\tsrccliprect.top = 0,\n\t\tsrccliprect.right = refw,\n\t\tsrccliprect.bottom = refh; // no clip; all the bitmap will be the source\n\telse\n\t\tsrccliprect = refrect; // clip; the source is limited to the source rectangle\n\n\t// compute step\n\ttjs_int x_step = (rw << 16) / dw;\n\ttjs_int y_step = (rh << 16) / dh;\n\n//\tbool x_2x = x_step == 32768;\n//\tbool y_2x = y_step == 32768;\n\n\ttjs_int x_ref_start, y_ref_start;\n\ttjs_int x_dest_start, y_dest_start;\n\ttjs_int x_len, y_len;\n\n\tif(x_dir)\n\t{\n\t\t// x; forward\n\t\tif(destrect.left < cliprect.left)\n\t\t\tx_dest_start = cliprect.left,\n\t\t\tx_ref_start = (refrect.left << 16) + x_step * (cliprect.left - destrect.left);\n\t\telse\n\t\t\tx_dest_start = destrect.left,\n\t\t\tx_ref_start = (refrect.left << 16);\n\n\t\tif(destrect.right > cliprect.right)\n\t\t\tx_len = cliprect.right - x_dest_start;\n\t\telse\n\t\t\tx_len = destrect.right - x_dest_start;\n\t}\n\telse\n\t{\n\t\t// x; backward\n\t\tx_step = -x_step;\n\n\t\tif(destrect.left < cliprect.left)\n\t\t\tx_ref_start = ((refrect.right << 16) - 1) + x_step * (cliprect.left - destrect.left),\n\t\t\tx_dest_start = cliprect.left;\n\t\telse\n\t\t\tx_ref_start = ((refrect.right << 16) - 1),\n\t\t\tx_dest_start = destrect.left;\n\n\t\tif(destrect.right > cliprect.right)\n\t\t\tx_len = cliprect.right - x_dest_start;\n\t\telse\n\t\t\tx_len = destrect.right - x_dest_start;\n\t}\n\tif(x_len <= 0) return false;\n\n\tif(y_dir)\n\t{\n\t\t// y; forward\n\t\tif(destrect.top < cliprect.top)\n\t\t\ty_dest_start = cliprect.top,\n\t\t\ty_ref_start = (refrect.top << 16) + y_step * (cliprect.top - destrect.top);\n\t\telse\n\t\t\ty_dest_start = destrect.top,\n\t\t\ty_ref_start = (refrect.top << 16);\n\n\t\tif(destrect.bottom > cliprect.bottom)\n\t\t\ty_len = cliprect.bottom - y_dest_start;\n\t\telse\n\t\t\ty_len = destrect.bottom - y_dest_start;\n\t}\n\telse\n\t{\n\t\t// y; backward\n\t\ty_step = -y_step;\n\n\t\tif(destrect.top < cliprect.top)\n\t\t\ty_ref_start = ((refrect.bottom << 16) - 1) + y_step * (cliprect.top - destrect.top),\n\t\t\ty_dest_start = cliprect.top;\n\t\telse\n\t\t\ty_ref_start = ((refrect.bottom << 16) - 1),\n\t\t\ty_dest_start = destrect.top;\n\n\t\tif(destrect.bottom > cliprect.bottom)\n\t\t\ty_len = cliprect.bottom - y_dest_start;\n\t\telse\n\t\t\ty_len = destrect.bottom - y_dest_start;\n\t}\n\n\tif(y_len <= 0) return false;\n\n\t// independent check\n\tif(method == bmCopy && opa == 255 && !hda && !IsIndependent())\n\t{\n\t\tif(destrect.left == 0 && destrect.top == 0 &&\n\t\t\tdestrect.right == (tjs_int)GetWidth() && destrect.bottom == (tjs_int)GetHeight())\n\t\t{\n\t\t\t// cover overall\n\t\t\tIndependNoCopy(); // indepent with no-copy\n\t\t}\n\t}\n\n\tconst tjs_uint8 * refp = (const tjs_uint8*)ref->GetScanLine(0);\n\ttjs_uint8 * destp = (tjs_uint8*)GetScanLineForWrite(y_dest_start);\n\tdestp += x_dest_start * sizeof(tjs_uint32);\n\ttjs_int refpitch = ref->GetPitchBytes();\n\ttjs_int destpitch = GetPitchBytes();\n\n\n\t// transfer\n\tswitch(method)\n\t{\n\tcase bmCopy:\n\t\tif(opa == 255)\n\t\t{\n\t\t\t// stretching copy\n\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t{\n\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t{\n\t\t\t\t\tTVPDoBiLinearStretchLoop( // bilinear interpolation\n\t\t\t\t\t\ttTVPInterpStretchCopyFunctionObject(),\n\t\t\t\t\t\tTVP_DoBilinearStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPDoStretchLoop(tTVPStretchFunctionObject(TVPStretchColorCopy),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(!hda)\n\t\t\t\t\tTVPDoStretchLoop(tTVPStretchFunctionObject(TVPStretchCopy),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoStretchLoop(tTVPStretchFunctionObject(TVPStretchColorCopy),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// stretching constant ratio alpha blendng\n\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t{\n\t\t\t\t// bilinear interpolation\n\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t{\n\t\t\t\t\tTVPDoBiLinearStretchLoop( // bilinear interpolation\n\t\t\t\t\t\ttTVPInterpStretchConstAlphaBlendFunctionObject(opa),\n\t\t\t\t\t\tTVP_DoBilinearStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(!hda)\n\t\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend, opa),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase bmCopyOnAlpha:\n\t\t// constant ratio alpha blending, with consideration of destination alpha\n\t\tif(opa == 255)\n\t\t{\n\t\t\t// full opaque stretching copy\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopyOpaqueImage),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// stretching constant ratio alpha blending\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_d, opa),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t}\n\t\tbreak;\n\n\tcase bmAlpha:\n\t\t// alpha blending, ignoring destination alpha\n\t\tif(opa == 255)\n\t\t{\n\t\t\tif(!hda)\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\telse\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_HDA),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!hda)\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_o, opa),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\telse\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_HDA_o, opa),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t}\n\t\tbreak;\n\n\tcase bmAlphaOnAlpha:\n\t\t// stretching alpha blending, with consideration of destination alpha\n\t\tif(opa == 255)\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_d),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\telse\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_do, opa),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\tbreak;\n\n\tcase bmAddAlpha:\n\t\t// additive alpha blending\n\t\tif(opa == 255)\n\t\t{\n\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t{\n\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t{\n\t\t\t\t\tTVPDoBiLinearStretchLoop( // bilinear interpolation\n\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlendFunctionObject(),\n\t\t\t\t\t\tTVP_DoBilinearStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend_HDA),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t{\n\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t{\n\t\t\t\t\tTVPDoBiLinearStretchLoop( // bilinear interpolation\n\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlend_oFunctionObject(opa),\n\t\t\t\t\t\tTVP_DoBilinearStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAdditiveAlphaBlend_o, opa),\n\t\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTVPDoStretchLoop(\n\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAdditiveAlphaBlend_HDA_o, opa),\n\t\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase bmAddAlphaOnAddAlpha:\n\t\t// additive alpha on additive alpha\n\t\tif(opa == 255)\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend_a),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\telse\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAdditiveAlphaBlend_ao, opa),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\tbreak;\n\n\tcase bmAddAlphaOnAlpha:\n\t\t// additive alpha on simple alpha\n\t\t; // yet not implemented\n\t\tbreak;\n\n\tcase bmAlphaOnAddAlpha:\n\t\t// simple alpha on additive alpha\n\t\tif(opa == 255)\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_a),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\telse\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_ao, opa),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\tbreak;\n\n\tcase bmCopyOnAddAlpha:\n\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t// with consideration of destination additive alpha\n\t\tif(opa == 255)\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopyOpaqueImage),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\telse\n\t\t\tTVPDoStretchLoop(\n\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_a, opa),\n\t\t\t\tTVP_DoStretchLoop_ARGS);\n\t\tbreak;\n\n\n\tdefault:\n\t\t; // yet not implemented\n\t}\n\n\treturn true;\n#endif\n}\n\n//---------------------------------------------------------------------------\n// template function for affine loop\n//---------------------------------------------------------------------------\n// define function pointer types for transforming line\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPAffineFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPAffineWithOpacityFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearAffineFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\ntypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearAffineWithOpacityFunction,\n\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\n\n//---------------------------------------------------------------------------\n\n// declare affine function object class\nclass tTVPAffineFunctionObject\n{\n\ttTVPAffineFunction Func;\npublic:\n\ttTVPAffineFunctionObject(tTVPAffineFunction func) : Func(func) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t{\n\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n\t}\n};\n\nclass tTVPAffineWithOpacityFunctionObject\n{\n\ttTVPAffineWithOpacityFunction Func;\n\ttjs_int Opacity;\npublic:\n\ttTVPAffineWithOpacityFunctionObject(tTVPAffineWithOpacityFunction func, tjs_int opa) :\n\t\tFunc(func), Opacity(opa) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t{\n\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch, Opacity);\n\t}\n};\n\nclass tTVPBilinearAffineFunctionObject\n{\nprotected:\n\ttTVPBilinearAffineFunction Func;\npublic:\n\ttTVPBilinearAffineFunctionObject(tTVPBilinearAffineFunction func) : Func(func) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t{\n\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n\t}\n};\n\n#define TVP_DEFINE_BILINEAR_AFFINE_FUNCTION(func, one) class \\\nt##func##FunctionObject : \\\n\tpublic tTVPBilinearAffineFunctionObject \\\n{ \\\npublic: \\\n\tt##func##FunctionObject() : \\\n\t\ttTVPBilinearAffineFunctionObject(func) {;} \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n};\n\n\nclass tTVPBilinearAffineWithOpacityFunctionObject\n{\nprotected:\n\ttTVPBilinearAffineWithOpacityFunction Func;\n\ttjs_int Opacity;\npublic:\n\ttTVPBilinearAffineWithOpacityFunctionObject(tTVPBilinearAffineWithOpacityFunction func, tjs_int opa) :\n\t\tFunc(func), Opacity(opa) {;}\n\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t{\n\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch, Opacity);\n\t}\n};\n\n#define TVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(func, one) class \\\nt##func##FunctionObject : \\\n\tpublic tTVPBilinearAffineWithOpacityFunctionObject \\\n{ \\\npublic: \\\n\tt##func##FunctionObject(tjs_int opa) : \\\n\t\ttTVPBilinearAffineWithOpacityFunctionObject(func, opa) {;} \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n};\n\n//---------------------------------------------------------------------------\n\n// declare affine transformation function object for bilinear interpolation\nTVP_DEFINE_BILINEAR_AFFINE_FUNCTION(\n\tTVPInterpLinTransCopy,\n\t*dest = color);\n\nTVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(\n\tTVPInterpLinTransConstAlphaBlend,\n\t*dest = TVPBlendARGB(*dest, color, Opacity));\n\n\nTVP_DEFINE_BILINEAR_AFFINE_FUNCTION(\n\tTVPInterpLinTransAdditiveAlphaBlend,\n\t*dest = TVPAddAlphaBlend_n_a(*dest, color));\n\nTVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(\n\tTVPInterpLinTransAdditiveAlphaBlend_o,\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, color, Opacity));\n\n//---------------------------------------------------------------------------\n\n// declare affine loop function\n#define TVP_DoAffineLoop_ARGS  sxs, sys, \\\n\t\tdest, l, len, src, srcpitch, sxl, syl, srcrect\ntemplate <typename tFuncStretch, typename tFuncAffine>\nvoid tTVPBaseBitmap::TVPDoAffineLoop(\n\t\ttFuncStretch stretch,\n\t\ttFuncAffine affine,\n\t\ttjs_int sxs,\n\t\ttjs_int sys,\n\t\ttjs_uint8 *dest,\n\t\ttjs_int l,\n\t\ttjs_int len,\n\t\tconst tjs_uint8 *src,\n\t\ttjs_int srcpitch,\n\t\ttjs_int sxl,\n\t\ttjs_int syl,\n\t\tconst tTVPRect & srcrect)\n{\n\ttjs_int len_remain = len;\n\n\t// skip \"out of source rectangle\" points\n\t// from last point\n\tsxl += 32768; // do +0.5 to rounding\n\tsyl += 32768; // do +0.5 to rounding\n\n\ttjs_int spx, spy;\n\ttjs_uint32 *dp;\n\tdp = (tjs_uint32*)dest + l + len-1;\n\tspx = (len-1)*sxs + sxl;\n\tspy = (len-1)*sys + syl;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int sx, sy;\n\t\tsx = spx >> 16;\n\t\tsy = spy >> 16;\n\t\tif(sx >= srcrect.left && sx < srcrect.right &&\n\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\tbreak;\n\t\tdp--;\n\t\tspx -= sxs;\n\t\tspy -= sys;\n\t\tlen_remain --;\n\t}\n\n\t// from first point\n\tspx = sxl;\n\tspy = syl;\n\tdp = (tjs_uint32*)dest + l;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int sx, sy;\n\t\tsx = spx >> 16;\n\t\tsy = spy >> 16;\n\t\tif(sx >= srcrect.left && sx < srcrect.right &&\n\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\tbreak;\n\t\tdp++;\n\t\tspx += sxs;\n\t\tspy += sys;\n\t\tlen_remain --;\n\t}\n\n\tif(len_remain > 0)\n\t{\n\t\t// transfer a line\n\t\tif(sys == 0)\n\t\t\tstretch(dp, len_remain,\n\t\t\t\t(tjs_uint32*)(src + (spy>>16) * srcpitch), spx, sxs);\n\t\telse\n\t\t\taffine(dp, len_remain,\n\t\t\t\t(tjs_uint32*)src, spx, spy, sxs, sys, srcpitch);\n\t}\n}\n\n//---------------------------------------------------------------------------\n// declare affine loop function for bilinear interpolation\n\n#define TVP_DoBilinearAffineLoop_ARGS  sxs, sys, \\\n\t\tdest, l, len, src, srcpitch, sxl, syl, srccliprect, srcrect\ntemplate <typename tFuncStretch, typename tFuncAffine>\nvoid tTVPBaseBitmap::TVPDoBilinearAffineLoop(\n\t\ttFuncStretch stretch,\n\t\ttFuncAffine affine,\n\t\ttjs_int sxs,\n\t\ttjs_int sys,\n\t\ttjs_uint8 *dest,\n\t\ttjs_int l,\n\t\ttjs_int len,\n\t\tconst tjs_uint8 *src,\n\t\ttjs_int srcpitch,\n\t\ttjs_int sxl,\n\t\ttjs_int syl,\n\t\tconst tTVPRect & srccliprect,\n\t\tconst tTVPRect & srcrect)\n{\n\t// bilinear interpolation copy\n\ttjs_int len_remain = len;\n\ttjs_int spx, spy;\n\ttjs_int sx, sy;\n\ttjs_uint32 *dp;\n\n\t// skip \"out of source rectangle\" points\n\t// from last point\n\tsxl += 32768; // do +0.5 to rounding\n\tsyl += 32768; // do +0.5 to rounding\n\n\tdp = (tjs_uint32*)dest + l + len-1;\n\tspx = (len-1)*sxs + sxl;\n\tspy = (len-1)*sys + syl;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int sx, sy;\n\t\tsx = spx >> 16;\n\t\tsy = spy >> 16;\n\t\tif(sx >= srcrect.left && sx < srcrect.right &&\n\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\tbreak;\n\t\tdp--;\n\t\tspx -= sxs;\n\t\tspy -= sys;\n\t\tlen_remain --;\n\t}\n\n\t// from first point\n\tspx = sxl;\n\tspy = syl;\n\tdp = (tjs_uint32*)dest + l;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int sx, sy;\n\t\tsx = spx >> 16;\n\t\tsy = spy >> 16;\n\t\tif(sx >= srcrect.left && sx < srcrect.right &&\n\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\tbreak;\n\t\tdp++;\n\t\tl++; // step l forward\n\t\tspx += sxs;\n\t\tspy += sys;\n\t\tlen_remain --;\n\t}\n\n\tsxl = spx;\n\tsyl = spy;\n\n\tsxl -= 32768; // take back the original\n\tsyl -= 32768; // take back the original\n\n#define FIX_SX_SY\t\\\n\tif(sx < srccliprect.left) \\\n\t\tsx = srccliprect.left, fixed_count ++; \\\n\tif(sx >= srccliprect.right) \\\n\t\tsx = srccliprect.right - 1, fixed_count++; \\\n\tif(sy < srccliprect.top) \\\n\t\tsy = srccliprect.top, fixed_count++; \\\n\tif(sy >= srccliprect.bottom) \\\n\t\tsy = srccliprect.bottom - 1, fixed_count++;\n\n\n\t// from last point\n\tspx = (len_remain-1)*sxs + sxl/* - 32768*/;\n\tspy = (len_remain-1)*sys + syl/* - 32768*/;\n\tdp = (tjs_uint32*)dest + l + len_remain-1;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int fixed_count = 0;\n\t\ttjs_uint32 c00, c01, c10, c11;\n\t\ttjs_int blend_x, blend_y;\n\n\t\tsx = (spx >> 16);\n\t\tsy = (spy >> 16);\n\t\tFIX_SX_SY\n\t\tc00 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16) + 1;\n\t\tsy = (spy >> 16);\n\t\tFIX_SX_SY\n\t\tc01 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16);\n\t\tsy = (spy >> 16) + 1;\n\t\tFIX_SX_SY\n\t\tc10 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16) + 1;\n\t\tsy = (spy >> 16) + 1;\n\t\tFIX_SX_SY\n\t\tc11 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tif(!fixed_count) break;\n\n\t\tblend_x = (spx & 0xffff) >> 8;\n\t\tblend_x += blend_x>>7; // adjust blend ratio\n\t\tblend_y = (spy & 0xffff) >> 8;\n\t\tblend_y += blend_y>>7;\n\n\t\taffine.DoOnePixel(dp, TVPBlendARGB(\n\t\t\tTVPBlendARGB(c00, c01, blend_x),\n\t\t\tTVPBlendARGB(c10, c11, blend_x),\n\t\t\t\tblend_y));\n\n\t\tdp--;\n\t\tspx -= sxs;\n\t\tspy -= sys;\n\t\tlen_remain --;\n\t}\n\n\t// from first point\n\tspx = sxl/* - 32768*/;\n\tspy = syl/* - 32768*/;\n\tdp = (tjs_uint32*)dest + l;\n\n\twhile(len_remain > 0)\n\t{\n\t\ttjs_int fixed_count = 0;\n\t\ttjs_uint32 c00, c01, c10, c11;\n\t\ttjs_int blend_x, blend_y;\n\n\t\tsx = (spx >> 16);\n\t\tsy = (spy >> 16);\n\t\tFIX_SX_SY\n\t\tc00 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16) + 1;\n\t\tsy = (spy >> 16);\n\t\tFIX_SX_SY\n\t\tc01 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16);\n\t\tsy = (spy >> 16) + 1;\n\t\tFIX_SX_SY\n\t\tc10 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tsx = (spx >> 16) + 1;\n\t\tsy = (spy >> 16) + 1;\n\t\tFIX_SX_SY\n\t\tc11 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\tif(!fixed_count) break;\n\n\t\tblend_x = (spx & 0xffff) >> 8;\n\t\tblend_x += blend_x>>7; // adjust blend ratio\n\t\tblend_y = (spy & 0xffff) >> 8;\n\t\tblend_y += blend_y>>7;\n\n\t\taffine.DoOnePixel(dp, TVPBlendARGB(\n\t\t\tTVPBlendARGB(c00, c01, blend_x),\n\t\t\tTVPBlendARGB(c10, c11, blend_x),\n\t\t\t\tblend_y));\n\n\t\tdp++;\n\t\tspx += sxs;\n\t\tspy += sys;\n\t\tlen_remain --;\n\t}\n\n\tif(len_remain > 0)\n\t{\n\t\t// do center part (this may takes most time)\n\t\tif(sys == 0)\n\t\t{\n\t\t\t// do stretch\n\t\t\tconst tjs_uint8 * l1 = src + (spy >> 16) * srcpitch;\n\t\t\tconst tjs_uint8 * l2 = l1 + srcpitch;\n\t\t\tstretch(\n\t\t\t\tdp,\n\t\t\t\tlen_remain,\n\t\t\t\t(const tjs_uint32*)l1,\n\t\t\t\t(const tjs_uint32*)l2,\n\t\t\t\t(spy & 0xffff) >> 8,\n\t\t\t\tspx,\n\t\t\t\tsxs);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// do affine\n\t\t\taffine(dp, len_remain,\n\t\t\t\t(tjs_uint32*)src, spx, spy, sxs, sys, srcpitch);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic inline tjs_int floor_16(tjs_int x)\n{\n\t// take floor of 16.16 fixed-point format\n\treturn (x >> 16) - (x < 0);\n}\nstatic inline tjs_int div_16(tjs_int x, tjs_int y)\n{\n\t// return x * 65536 / y\n\treturn (tjs_int)((tjs_int64)x * 65536 / y);\n}\nstatic inline tjs_int mul_16(tjs_int x, tjs_int y)\n{\n\t// return x * y / 65536\n\treturn (tjs_int)((tjs_int64)x * y / 65536);\n}\n//---------------------------------------------------------------------------\nint tTVPBaseBitmap::InternalAffineBlt(tTVPRect destrect, const tTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const tTVPPointD * points_in,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect,\n\t\t\tbool hda, tTVPBBStretchType mode, bool clear, tjs_uint32 clearcolor)\n{\n\t// unlike other drawing methods, 'destrect' is the clip rectangle of the\n\t// destination bitmap.\n\t// affine transformation coordinates are to be applied on zero-offset\n\t// source rectangle:\n\t// (0, 0) - (refreft.right - refrect.left, refrect.bottom - refrect.top)\n\n\t// points are given as destination points, corresponding to three source\n\t// points; upper-left, upper-right, bottom-left.\n\n\t// if 'clear' is true, area which is out of the affine destination and\n\t// within the destination bounding box, is to be filled with value 'clearcolor'.\n\n\t// returns 0 if the updating rect is not updated, 1 if error\n\t// otherwise returns 2\n\n\t// extract stretch type\n\ttTVPBBStretchType type = (tTVPBBStretchType)(mode & stTypeMask);\n\n\t// check source rectangle\n\tif(refrect.left >= refrect.right ||\n\t\trefrect.top >= refrect.bottom) return 1;\n\tif(refrect.left < 0 || refrect.top < 0 ||\n\t\trefrect.right > (tjs_int)ref->GetWidth() ||\n\t\trefrect.bottom > (tjs_int)ref->GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\t// multiply source rectangle points by 65536 (16.16 fixed-point)\n\t// note that each pixel has actually 1.0 x 1.0 size\n\t// eg. a pixel at 0,0 may have (-0.5, -0.5) - (0.5, 0.5) area\n\ttTVPRect srcrect = refrect; // unmultiplied source rectangle is saved as srcrect\n\trefrect.left   = refrect.left   * 65536 - 32768;\n\trefrect.top    = refrect.top    * 65536 - 32768;\n\trefrect.right  = refrect.right  * 65536 - 32768;\n\trefrect.bottom = refrect.bottom * 65536 - 32768;\n\n\t// create point list in fixed point real format\n\ttTVPPoint points[3];\n\tfor(tjs_int i = 0; i < 3; i++)\n\t\tpoints[i].x = static_cast<tjs_int>(points_in[i].x * 65536), points[i].y = static_cast<tjs_int>(points_in[i].y * 65536);\n\n\t// check destination rectangle\n\tif(destrect.left < 0) destrect.left = 0;\n\tif(destrect.top < 0) destrect.top = 0;\n\tif(destrect.right > (tjs_int)GetWidth()) destrect.right = GetWidth();\n\tif(destrect.bottom > (tjs_int)GetHeight()) destrect.bottom = GetHeight();\n\n\tif(destrect.left >= destrect.right ||\n\t\tdestrect.top >= destrect.bottom) return 1; // not drawable\n\n\t// vertex points\n\ttjs_int points_x[4];\n\ttjs_int points_y[4];\n\n\t// check each vertex and find most-top/most-bottom/most-left/most-right points\n\ttjs_int scanlinestart, scanlineend; // most-top/most-bottom\n\ttjs_int leftlimit, rightlimit; // most-left/most-right\n\n\t// - upper-left (p0)\n\tpoints_x[0] = points[0].x;\n\tpoints_y[0] = points[0].y;\n\tleftlimit = points_x[0];\n\trightlimit = points_x[0];\n\tscanlinestart = points_y[0];\n\tscanlineend = points_y[0];\n\n\t// - upper-right (p1)\n\tpoints_x[1] = points[1].x;\n\tpoints_y[1] = points[1].y;\n\tif(leftlimit > points_x[1]) leftlimit = points_x[1];\n\tif(rightlimit < points_x[1]) rightlimit = points_x[1];\n\tif(scanlinestart > points_y[1]) scanlinestart = points_y[1];\n\tif(scanlineend < points_y[1]) scanlineend = points_y[1];\n\n\t// - bottom-right (p2)\n\tpoints_x[2] = points[1].x - points[0].x + points[2].x;\n\tpoints_y[2] = points[1].y - points[0].y + points[2].y;\n\tif(leftlimit > points_x[2]) leftlimit = points_x[2];\n\tif(rightlimit < points_x[2]) rightlimit = points_x[2];\n\tif(scanlinestart > points_y[2]) scanlinestart = points_y[2];\n\tif(scanlineend < points_y[2]) scanlineend = points_y[2];\n\n\t// - bottom-left (p3)\n\tpoints_x[3] = points[2].x;\n\tpoints_y[3] = points[2].y;\n\tif(leftlimit > points_x[3]) leftlimit = points_x[3];\n\tif(rightlimit < points_x[3]) rightlimit = points_x[3];\n\tif(scanlinestart > points_y[3]) scanlinestart = points_y[3];\n\tif(scanlineend < points_y[3]) scanlineend = points_y[3];\n\n\t// rough check destrect intersections\n\tif(floor_16(leftlimit) >= destrect.right) return 0;\n\tif(floor_16(rightlimit) < destrect.left) return 0;\n\tif(floor_16(scanlinestart) >= destrect.bottom) return 0;\n\tif(floor_16(scanlineend) < destrect.top) return 0;\n\n\t// compute sxstep and systep (step count for source image)\n\ttjs_int sxstep, systep;\n\n\t{\n\t\tdouble dv01x = (points[1].x - points[0].x) * (1.0 / 65536.0);\n\t\tdouble dv01y = (points[1].y - points[0].y) * (1.0 / 65536.0);\n\t\tdouble dv02x = (points[2].x - points[0].x) * (1.0 / 65536.0);\n\t\tdouble dv02y = (points[2].y - points[0].y) * (1.0 / 65536.0);\n\n\t\tdouble x01, x02, s01, s02;\n\n\t\tif     (points[1].y == points[0].y)\n\t\t{\n\t\t\tsxstep = (tjs_int)((refrect.right - refrect.left) / dv01x);\n\t\t\tsystep = 0;\n\t\t}\n\t\telse if(points[2].y == points[0].y)\n\t\t{\n\t\t\tsxstep = 0;\n\t\t\tsystep = (tjs_int)((refrect.bottom - refrect.top) / dv02x);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tx01 = dv01x / dv01y;\n\t\t\ts01 = (refrect.right - refrect.left) / dv01y;\n\n\t\t\tx02 = dv02x / dv02y;\n\t\t\ts02 = (refrect.top - refrect.bottom) / dv02y;\n\n\t\t\tdouble len = x01 - x02;\n\n\t\t\tsxstep = (tjs_int)(s01 / len);\n\t\t\tsystep = (tjs_int)(s02 / len);\n\t\t}\n\t}\n\n\t// prepare to transform...\n\ttjs_int yc    = (scanlinestart + 32768) / 65536;\n\ttjs_int yclim = (scanlineend   + 32768) / 65536;\n\n\tif(destrect.top > yc) yc = destrect.top;\n\tif(destrect.bottom <= yclim) yclim = destrect.bottom - 1;\n\tif(yc >= destrect.bottom || yclim < 0)\n\t\treturn 0; // not drawable\n\n\ttjs_uint8 * dest = (tjs_uint8*)GetScanLineForWrite(yc);\n\ttjs_int destpitch = GetPitchBytes();\n\tconst tjs_uint8 * src = (const tjs_uint8 *)ref->GetScanLine(0);\n\ttjs_int srcpitch = ref->GetPitchBytes();\n\n//\tyc    = yc    * 65536;\n//\tyclim = yclim * 65536;\n\n\t// make srccliprect\n\ttTVPRect srccliprect;\n\tif(mode & stRefNoClip)\n\t\tsrccliprect.left = 0,\n\t\tsrccliprect.top = 0,\n\t\tsrccliprect.right = (tjs_int)ref->GetWidth(),\n\t\tsrccliprect.bottom = (tjs_int)ref->GetHeight(); // no clip; all the bitmap will be the source\n\telse\n\t\tsrccliprect = srcrect; // clip; the source is limited to the source rectangle\n\n\n\t// process per a line\n\ttjs_int mostupper  = -1;\n\ttjs_int mostbottom = -1;\n\tbool firstline = true;\n\n        tjs_int ych = yclim - yc + 1;\n        tjs_int w = destrect.right - destrect.left;\n        tjs_int h = destrect.bottom - destrect.top;\n\n        tjs_int taskNum = GetAdaptiveThreadNum(w * h, sBmFactor[method] * 13 / 59);\n        TVPBeginThreadTask(taskNum);\n        PartialAffineBltParam params[TVPMaxThreadNum];\n        for (tjs_int i = 0; i < taskNum; i++) {\n          tjs_int y0, y1;\n          y0 = ych * i / taskNum;\n          y1=  ych * (i + 1) / taskNum - 1;\n          PartialAffineBltParam *param = params + i;\n          param->self = this;\n          param->dest = dest + destpitch * y0;\n          param->destpitch = destpitch;\n          param->yc = (yc + y0) * 65536;\n          param->yclim = (yc + y1) * 65536;\n          param->scanlinestart = scanlinestart;\n          param->scanlineend = scanlineend;\n          param->points_x = points_x;\n          param->points_y = points_y;\n          param->refrect = &refrect;\n          param->sxstep = sxstep;\n          param->systep = systep;\n          param->destrect = &destrect;\n          param->method = method;\n          param->opa = opa;\n          param->hda = hda;\n          param->type = type;\n          param->clear = clear;\n          param->clearcolor = clearcolor;\n          param->leftlimit = leftlimit;\n          param->rightlimit = rightlimit;\n          param->mostupper = mostupper;\n          param->mostbottom = mostbottom;\n          param->firstline = firstline;\n          param->src = src;\n          param->srcpitch = srcpitch;\n          param->srccliprect = &srccliprect;\n          param->srcrect = &srcrect;\n          TVPExecThreadTask(&PartialAffineBltEntry, TVP_THREAD_PARAM(param));\n        }\n        TVPEndThreadTask();\n\n        // update area param\n        for (tjs_int i = 0; i < taskNum; i++) {\n          PartialAffineBltParam *param = params + i;\n          if (param->firstline)\n            continue;\n          if (firstline) {\n            firstline = false;\n            leftlimit = param->leftlimit;\n            rightlimit = param->rightlimit;\n            mostupper = param->mostupper;\n            mostbottom  = param->mostbottom;\n          } else {\n            if (param->leftlimit < leftlimit) leftlimit = param->leftlimit;\n            if (param->rightlimit > rightlimit) rightlimit = param->rightlimit;\n            if (param->mostupper < mostupper) mostupper = param->mostupper;\n            if (param->mostbottom > mostbottom) mostbottom = param->mostbottom;\n          }\n        }\n\n\t// clear upper and lower area of the affine transformation\n\tif(clear)\n\t{\n\t\ttjs_int h;\n\t\ttjs_uint8 * dest = (tjs_uint8*)GetScanLineForWrite(0);\n\t\ttjs_uint8 * p;\n\t\tif(mostupper == -1 && mostbottom == -1)\n\t\t{\n\t\t\t// special case: nothing was drawn;\n\t\t\t// clear entire area of the destrect\n\t\t\tmostupper  = destrect.bottom;\n\t\t\tmostbottom = destrect.bottom - 1;\n\t\t}\n\n\t\th = mostupper - destrect.top;\n\t\tif(h > 0)\n\t\t{\n\t\t\tp = dest + destrect.top * destpitch;\n\t\t\tdo\n\t\t\t\t(hda?TVPFillColor:TVPFillARGB)((tjs_uint32*)p + destrect.left,\n\t\t\t\t\tdestrect.right - destrect.left, clearcolor),\n\t\t\t\tp += destpitch;\n\t\t\twhile(--h);\n\t\t}\n\n\t\th = destrect.bottom - (mostbottom + 1);\n\t\tif(h > 0)\n\t\t{\n\t\t\tp = dest + (mostbottom + 1) * destpitch;\n\t\t\tdo\n\t\t\t\t(hda?TVPFillColor:TVPFillARGB)((tjs_uint32*)p + destrect.left,\n\t\t\t\t\tdestrect.right - destrect.left, clearcolor),\n\t\t\t\tp += destpitch;\n\t\t\twhile(--h);\n\t\t}\n\n\t}\n\n\t// fill members of updaterect\n\tif(updaterect)\n\t{\n\t\tif(clear)\n\t\t{\n\t\t\t// clear is specified\n\t\t\t*updaterect = destrect;\n\t\t\t\t// update rectangle is the same as the destination rectangle\n\t\t}\n\t\telse if(!firstline)\n\t\t{\n\t\t\t// update area is being\n\t\t\tupdaterect->left = leftlimit;\n\t\t\tupdaterect->right = rightlimit + 1;\n\t\t\tupdaterect->top = mostupper;\n\t\t\tupdaterect->bottom = mostbottom + 1;\n\t\t}\n\t}\n\n\treturn (clear || !firstline)?2:0;\n}\n\nvoid TJS_USERENTRY tTVPBaseBitmap::PartialAffineBltEntry(void *v)\n{\n  PartialAffineBltParam *param = (PartialAffineBltParam *)v;\n  param->self->PartialAffineBlt(param);\n}\n\nvoid tTVPBaseBitmap::PartialAffineBlt(PartialAffineBltParam *param)\n{\n  tjs_uint8 *dest = param->dest;\n  const tjs_int destpitch = param->destpitch;\n  tjs_int yc = param->yc;\n  tjs_int yclim = param->yclim;\n  const tjs_int scanlinestart = param->scanlinestart;\n  const tjs_int scanlineend = param->scanlineend;\n  const tjs_int *points_x = param->points_x;\n  const tjs_int *points_y = param->points_y;\n  const tTVPRect &refrect = *(param->refrect);\n  const tjs_int sxstep = param->sxstep;\n  const tjs_int systep = param->systep;\n  const tTVPRect &destrect = *(param->destrect);\n  const tTVPBBBltMethod method = param->method;\n  const tjs_int opa = param->opa;\n  const bool hda = param->hda;\n  const tTVPBBStretchType type = param->type;\n  const bool clear = param->clear;\n  const tjs_uint32 clearcolor = param->clearcolor;\n  const tjs_uint8 *const src  = param->src;\n  const tjs_int srcpitch = param->srcpitch;\n  const tTVPRect &srccliprect = *(param->srccliprect);\n  const tTVPRect &srcrect = *(param->srcrect);\n\n  tjs_int &leftlimit = param->leftlimit;\n  tjs_int &rightlimit = param->rightlimit;\n  tjs_int &mostupper = param->mostupper;\n  tjs_int &mostbottom = param->mostbottom;\n  bool &firstline = param->firstline;\n\n\tfor(; yc <= yclim; yc+=65536, dest += destpitch)\n\t{\n\t\t// transfer a line\n\n\t\t// skip out-of-range lines\n\t\ttjs_int yl = yc;\n\t\tif(yl < scanlinestart)\n\t\t\tcontinue;\n\t\tif(yl >= scanlineend)\n\t\t\tcontinue;\n\n\t\t// actual write line\n\t\ttjs_int y = (yc+32768) / 65536;\n\n\t\t// find line intersection\n\t\t// line codes are:\n\t\t// p0 .. p1  : 0\n\t\t// p1 .. p2  : 1\n\t\t// p2 .. p3  : 2\n\t\t// p3 .. p0  : 3\n\t\ttjs_int line_code0, line_code1;\n\t\ttjs_int where0, where1;\n\t\ttjs_int where, code;\n\n\t\tfor(code = 0; code < 4; code ++)\n\t\t{\n\t\t\ttjs_int ip0 = code;\n\t\t\ttjs_int ip1 = (code + 1) & 3;\n\t\t\tif     (points_y[ip0] == yl && points_y[ip1] == yl)\n\t\t\t{\n\t\t\t\twhere = points_x[ip1] > points_x[ip0] ? 0 : 65536;\n\t\t\t\tcode += 8;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(code < 8)\n\t\t{\n\t\t\tfor(code = 0; code < 4; code ++)\n\t\t\t{\n\t\t\t\ttjs_int ip0 = code;\n\t\t\t\ttjs_int ip1 = (code + 1) & 3;\n\t\t\t\tif(points_y[ip0] <= yl && points_y[ip1] > yl)\n\t\t\t\t{\n\t\t\t\t\twhere = div_16(yl - points_y[ip0], points_y[ip1] - points_y[ip0]);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if(points_y[ip0] >  yl && points_y[ip1] <= yl)\n\t\t\t\t{\n\t\t\t\t\twhere = div_16(points_y[ip0] - yl, points_y[ip0] - points_y[ip1]);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tline_code0 = code;\n\t\twhere0 = where;\n\n\t\tif(line_code0 < 4)\n\t\t{\n\t\t\tfor(code = 0; code < 4; code ++)\n\t\t\t{\n\t\t\t\tif(code == line_code0) continue;\n\t\t\t\ttjs_int ip0 = code;\n\t\t\t\ttjs_int ip1 = (code + 1) & 3;\n\t\t\t\tif     (points_y[ip0] == yl && points_y[ip1] == yl)\n\t\t\t\t{\n\t\t\t\t\twhere = points_x[ip1] > points_x[ip0] ? 0 : 65536;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if(points_y[ip0] <= yl && points_y[ip1] >  yl)\n\t\t\t\t{\n\t\t\t\t\twhere = div_16(yl - points_y[ip0], points_y[ip1] - points_y[ip0]);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if(points_y[ip0] >  yl && points_y[ip1] <= yl)\n\t\t\t\t{\n\t\t\t\t\twhere = div_16(points_y[ip0]- yl , points_y[ip0] - points_y[ip1]);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tline_code1 = code;\n\t\t\twhere1 = where;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tline_code0 &= 3;\n\t\t\tline_code1 = line_code0;\n\t\t\twhere1 = 65536 - where0;\n\t\t}\n\n\t\t// compute intersection point\n\t\ttjs_int ll, rr, sxl, syl, sxr, syr;\n\t\tswitch(line_code0)\n\t\t{\n\t\tcase 0:\n\t\t\tll  = mul_16(points_x[1] - points_x[0]   , where0) + points_x[0];\n\t\t\tsxl = mul_16(refrect.right - refrect.left, where0) + refrect.left;\n\t\t\tsyl = refrect.top;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tll  = mul_16(points_x[2] - points_x[1]   , where0) + points_x[1];\n\t\t\tsxl = refrect.right;\n\t\t\tsyl = mul_16(refrect.bottom - refrect.top, where0) + refrect.top;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tll  = mul_16(points_x[3] - points_x[2]   , where0) + points_x[2];\n\t\t\tsxl = mul_16(refrect.left - refrect.right, where0) + refrect.right;\n\t\t\tsyl = refrect.bottom;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tll  = mul_16(points_x[0] - points_x[3]   , where0) + points_x[3];\n\t\t\tsxl = refrect.left;\n\t\t\tsyl = mul_16(refrect.top - refrect.bottom, where0) + refrect.bottom;\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch(line_code1)\n\t\t{\n\t\tcase 0:\n\t\t\trr  = mul_16(points_x[1] - points_x[0]   , where1) + points_x[0];\n\t\t\tsxr = mul_16(refrect.right - refrect.left, where1) + refrect.left;\n\t\t\tsyr = refrect.top;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\trr  = mul_16(points_x[2] - points_x[1]   , where1) + points_x[1];\n\t\t\tsxr = refrect.right;\n\t\t\tsyr = mul_16(refrect.bottom - refrect.top, where1) + refrect.top;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\trr  = mul_16(points_x[3] - points_x[2]   , where1) + points_x[2];\n\t\t\tsxr = mul_16(refrect.left - refrect.right, where1) + refrect.right;\n\t\t\tsyr = refrect.bottom;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\trr  = mul_16(points_x[0] - points_x[3]   , where1) + points_x[3];\n\t\t\tsxr = refrect.left;\n\t\t\tsyr = mul_16(refrect.top - refrect.bottom, where1) + refrect.bottom;\n\t\t\tbreak;\n\t\t}\n\n\n\t\t// l, r, sxs, sys, and len\n\t\ttjs_int sxs, sys, len;\n\t\tsxs = sxstep;\n\t\tsys = systep;\n\t\tif(ll > rr)\n\t\t{\n\t\t\tstd::swap(ll, rr);\n\t\t\tstd::swap(sxl, sxr);\n\t\t\tstd::swap(syl, syr);\n\t\t}\n\n\t\t// round l and r to integer\n\t\ttjs_int l, r;\n\n\t\t// 0x8000000 were choosed to avoid special divition behavior around zero\n\t\tl = ((tjs_uint32)(ll + 0x80000000ul-1)/65536)-(0x80000000ul/65536)+1;\n\t\tsxl += mul_16(65535 - ((tjs_uint32)(ll+0x80000000ul-1) % 65536), sxs); // adjust source start point x\n\t\tsyl += mul_16(65535 - ((tjs_uint32)(ll+0x80000000ul-1) % 65536), sys); // adjust source start point y\n\n\t\tr = ((tjs_uint32)(rr + 0x80000000ul-1)/65536)-(0x80000000ul/65536)+1; // note that at this point r is *NOT* inclusive\n\n\t\t// - clip widh destrect.left and destrect.right\n\t\tif(l < destrect.left)\n\t\t{\n\t\t\ttjs_int d = destrect.left - l;\n\t\t\tsxl += d * sxs;\n\t\t\tsyl += d * sys;\n\t\t\tl = destrect.left;\n\t\t}\n\t\tif(r > destrect.right) r = destrect.right;\n\n\t\t// - compute horizontal length\n\t\tlen = r - l;\n\n\t\t// - transfer\n\t\tif(len > 0)\n\t\t{\n\t\t\t// fill left and right of the line if 'clear' is specified\n\t\t\tif(clear)\n\t\t\t{\n\t\t\t\ttjs_int clen;\n\n\t\t\t\tint ll = l + 1;\n\t\t\t\tif(ll > destrect.right) ll = destrect.right;\n\t\t\t\tclen = ll - destrect.left;\n\t\t\t\tif(clen > 0)\n\t\t\t\t\t(hda?TVPFillColor:TVPFillARGB)((tjs_uint32*)dest + destrect.left, clen, clearcolor);\n\t\t\t\tint rr = r - 1;\n\t\t\t\tif(rr < destrect.left) rr = destrect.left;\n\t\t\t\tclen = destrect.right - rr;\n\t\t\t\tif(clen > 0)\n\t\t\t\t\t(hda?TVPFillColor:TVPFillARGB)((tjs_uint32*)dest + rr, clen, clearcolor);\n\t\t\t}\n\n\n\t\t\t// update updaterect\n\t\t\tif(firstline)\n\t\t\t{\n\t\t\t\tleftlimit = l;\n\t\t\t\trightlimit = r;\n\t\t\t\tfirstline = false;\n\t\t\t\tmostupper = mostbottom = y;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(l < leftlimit) leftlimit = l;\n\t\t\t\tif(r > rightlimit) rightlimit = r;\n\t\t\t\tmostbottom = y;\n\t\t\t}\n\n\t\t\t// transfer using each blend function\n\t\t\tswitch(method)\n\t\t\t{\n\t\t\tcase bmCopy:\n\t\t\t\tif(opa == 255)\n\t\t\t\t{\n\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// bilinear interpolation\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchCopyFunctionObject(),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransCopyFunctionObject(),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// point on point (nearest) copy\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopy),\n\t\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransCopy),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchColorCopy),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransColorCopy),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// bilinear interpolation\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchConstAlphaBlendFunctionObject(opa),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransConstAlphaBlendFunctionObject(opa),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend, opa),\n\t\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend, opa),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase bmCopyOnAlpha:\n\t\t\t\t// constant ratio alpha blending, with consideration of destination alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopyOpaqueImage),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransCopyOpaqueImage),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_d, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_d, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\tbreak;\n\n\t\t\tcase bmAlpha:\n\t\t\t\t// alpha blending, ignoring destination alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t{\n\t\t\t\t\tif(!hda)\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\telse\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_HDA),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_HDA),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(!hda)\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_o, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_o, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\telse\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase bmAlphaOnAlpha:\n\t\t\t\t// alpha blending, with consideration of destination alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_d),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_d),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_do, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_do, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\tbreak;\n\n\t\t\tcase bmAddAlpha:\n\t\t\t\t// additive alpha blending, ignoring destination alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t{\n\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// bilinear interpolation\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlendFunctionObject(),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransAdditiveAlphaBlendFunctionObject(),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend),\n\t\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAdditiveAlphaBlend),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend_HDA),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAdditiveAlphaBlend_HDA),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || !hda)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(TVP_BILINEAR_FORCE_COND || type >= stFastLinear)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// bilinear interpolation\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlend_oFunctionObject(opa),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransAdditiveAlphaBlend_oFunctionObject(opa),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_o, opa),\n\t\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAdditiveAlphaBlend_o, opa),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAdditiveAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAdditiveAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase bmAddAlphaOnAddAlpha:\n\t\t\t\t// additive alpha blending, with consideration of destination additive alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_a),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAdditiveAlphaBlend_a),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_ao, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAdditiveAlphaBlend_ao, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\tbreak;\n\n\t\t\tcase bmAddAlphaOnAlpha:\n\t\t\t\t// additive alpha on simple alpha\n\t\t\t\t; // yet not implemented\n\t\t\t\tbreak;\n\n\t\t\tcase bmAlphaOnAddAlpha:\n\t\t\t\t// simple alpha on additive alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_a),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_a),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_ao, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_ao, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\tbreak;\n\n\t\t\tcase bmCopyOnAddAlpha:\n\t\t\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t\t\t// with consideration of destination additive alpha\n\t\t\t\tif(opa == 255)\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopyOpaqueImage),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransCopyOpaqueImage),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\telse\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_a, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_a, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t; // yet not implemented\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::AffineBlt(tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const tTVPPointD * points_in,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect,\n\t\t\tbool hda, tTVPBBStretchType mode, bool clear, tjs_uint32 clearcolor)\n{\n\t// check source rectangle\n\tif (refrect.left >= refrect.right ||\n\t\trefrect.top >= refrect.bottom) return false;\n\tif (refrect.left < 0 || refrect.top < 0 ||\n\t\trefrect.right >(tjs_int)ref->GetWidth() ||\n\t\trefrect.bottom >(tjs_int)ref->GetHeight())\n\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\t// create point list in fixed point real format\n\n\tif (destrect.left < 0) destrect.left = 0;\n\tif (destrect.top < 0) destrect.top = 0;\n\tif (destrect.right >(tjs_int)GetWidth()) destrect.right = GetWidth();\n\tif (destrect.bottom >(tjs_int)GetHeight()) destrect.bottom = GetHeight();\n\n\tif (destrect.left >= destrect.right ||\n\t\tdestrect.top >= destrect.bottom) return false; // not drawable\n\n\tif (clear)\n\t{\n\t\tif (hda)\n\t\t\tFillColor(destrect, clearcolor, 255);\n\t\telse\n\t\t\tFill(destrect, clearcolor);\n\t}\n\n\ttTVPPointD dstpt[6] = {\n\t\t{ points_in[0].x, points_in[0].y }, // left-top\n\t\t{ points_in[1].x, points_in[1].y }, // right-top\n\t\t{ points_in[2].x, points_in[2].y }, // left-bottom\n\n\t\t{ points_in[1].x, points_in[1].y }, // right-top\n\t\t{ points_in[2].x, points_in[2].y }, // left-bottom\n\t\t{ points_in[1].x - points_in[0].x + points_in[2].x, points_in[1].y - points_in[0].y + points_in[2].y }, // right-bottom\n\t};\n\ttTVPPointD refpt[6] = {\n\t\t{ (double)refrect.left, (double)refrect.top },\n\t\t{ (double)refrect.right, (double)refrect.top },\n\t\t{ (double)refrect.left, (double)refrect.bottom },\n\n\t\t{ (double)refrect.right, (double)refrect.top },\n\t\t{ (double)refrect.left, (double)refrect.bottom },\n\t\t{ (double)refrect.right, (double)refrect.bottom },\n\t};\n\n\ttTVPBBStretchType type = (tTVPBBStretchType)(mode & stTypeMask);\n\tstatic int StretchTypeId = TVPGetRenderManager()->EnumParameterID(\"StretchType\");\n\tTVPGetRenderManager()->SetParameterInt(StretchTypeId, (int)type);\n\tiTVPRenderManager *mgr = GetRenderManager();\n\tiTVPRenderMethod *_method = mgr->GetRenderMethod(opa, hda, method);\n\tif (!_method) return false;\n\ttRenderTexQuadArray::Element src_tex[] = { tRenderTexQuadArray::Element(ref->GetTexture(), refpt) };\n\tiTVPTexture2D *reftex = GetTexture();\n\tmgr->OperateTriangles(_method, 2, GetTextureForRender(_method->IsBlendTarget(), &destrect),\n\t\treftex, destrect, dstpt, tRenderTexQuadArray(src_tex));\n\tif (updaterect) *updaterect = destrect;\n\treturn true;\n#if 0\n\tif (0 == InternalAffineBlt(destrect, ref, refrect, points_in, method, opa, updaterect, hda,\n\t\tmode, clear, clearcolor))\n\t{\n\t\tif(clear)\n\t\t{\n\t\t\tif(hda)\n\t\t\t\tFillColor(destrect, clearcolor, 255);\n\t\t\telse\n\t\t\t\tFill(destrect, clearcolor);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n#endif\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::AffineBlt(tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const t2DAffineMatrix & matrix,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect,\n\t\t\tbool hda, tTVPBBStretchType type, bool clear, tjs_uint32 clearcolor)\n{\n\t// do transformation using 2D affine matrix.\n\t//  x' =  ax + cy + tx\n\t//  y' =  bx + dy + ty\n\ttTVPPointD points[3];\n\tint rp = refrect.get_width();\n\tint bp = refrect.get_height();\n\n\t// note that a pixel has actually 1 x 1 size, so\n\t// a pixel at (0,0) covers (-0.5, -0.5) - (0.5, 0.5).\n\n#define CALC_X(x, y) (matrix.a * (x) + matrix.c * (y) + matrix.tx)\n#define CALC_Y(x, y) (matrix.b * (x) + matrix.d * (y) + matrix.ty)\n\n\t// - upper-left\n\tpoints[0].x = CALC_X(-0.5, -0.5);\n\tpoints[0].y = CALC_Y(-0.5, -0.5);\n\n\t// - upper-right\n\tpoints[1].x = CALC_X(rp - 0.5, -0.5);\n\tpoints[1].y = CALC_Y(rp - 0.5, -0.5);\n\n/*\t// - bottom-right\n\tpoints[2].x = CALC_X(rp - 0.5, bp - 0.5);\n\tpoints[2].y = CALC_Y(rp - 0.5, bp - 0.5);\n*/\n\n\t// - bottom-left\n\tpoints[2].x = CALC_X(-0.5, bp - 0.5);\n\tpoints[2].y = CALC_Y(-0.5, bp - 0.5);\n\n\treturn AffineBlt(destrect, ref, refrect, points, method, opa, updaterect, hda, type, clear, clearcolor);\n}\n//---------------------------------------------------------------------------\n#if 0\n// some blur operation template functions to select algorithm by base integer type\ntemplate <typename tARGB, typename base_int_type>\nvoid TVPAddSubVertSum(base_int_type *dest, const tjs_uint32 *addline,\n\tconst tjs_uint32 *subline, tjs_int len)\n{\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB<tjs_uint16>, tjs_uint16 >(tjs_uint16 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum16(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB_AA<tjs_uint16>, tjs_uint16 >(tjs_uint16 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum16_d(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB<tjs_uint32>, tjs_uint32 >(tjs_uint32 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum32(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB_AA<tjs_uint32>, tjs_uint32 >(tjs_uint32 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum32_d(dest, addline, subline, len);\n}\n\ntemplate <typename tARGB, typename base_int_type>\nvoid TVPDoBoxBlurAvg(tjs_uint32 *dest, base_int_type *sum,\n\tconst base_int_type * add, const base_int_type * sub,\n\t\ttjs_int n, tjs_int len)\n{\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB<tjs_uint16>, tjs_uint16 >(tjs_uint32 *dest, tjs_uint16 *sum,\n\tconst tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg16(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB_AA<tjs_uint16>, tjs_uint16  >(tjs_uint32 *dest, tjs_uint16 *sum,\n\tconst tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg16_d(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB<tjs_uint32>, tjs_uint32  >(tjs_uint32 *dest, tjs_uint32 *sum,\n\tconst tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg32(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB_AA<tjs_uint32>, tjs_uint32  >(tjs_uint32 *dest, tjs_uint32 *sum,\n\tconst tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg32_d(dest, sum, add, sub, n, len);\n}\n\n\n//---------------------------------------------------------------------------\n\n\ntemplate <typename tARGB>\nvoid tTVPBaseBitmap::DoBoxBlurLoop(const tTVPRect &rect, const tTVPRect & area)\n{\n\t// Box-Blur template function used by tTVPBaseBitmap::DoBoxBlur family.\n\t// Based on contributed blur code by yun, say thanks to him.\n\n\ttypedef tARGB::base_int_type base_type;\n\n\ttjs_int width = GetWidth();\n\ttjs_int height = GetHeight();\n\n\ttjs_int dest_buf_size = area.top <= 0 ? (1-area.top) : 0;\n\n\ttjs_int vert_sum_left_limit = rect.left + area.left;\n\tif(vert_sum_left_limit < 0) vert_sum_left_limit = 0;\n\ttjs_int vert_sum_right_limit = (rect.right-1) + area.right;\n\tif(vert_sum_right_limit >= width) vert_sum_right_limit = width - 1;\n\n\n\ttARGB * vert_sum = NULL; // vertical sum of the pixel\n\ttjs_uint32 * * dest_buf = NULL; // destination pixel temporary buffer\n\n\ttjs_int vert_sum_count;\n\n\ttry\n\t{\n\t\t// allocate buffers\n\t\tvert_sum = (tARGB*)TJSAlignedAlloc(sizeof(tARGB) *\n\t\t\t(vert_sum_right_limit - vert_sum_left_limit + 1 + 1), 4); // use 128bit aligned allocation\n\n\t\tif(dest_buf_size)\n\t\t{\n\t\t\tdest_buf = new tjs_uint32 * [dest_buf_size];\n\t\t\tfor(tjs_int i = 0; i < dest_buf_size; i++)\n\t\t\t\tdest_buf[i] = new tjs_uint32[rect.right - rect.left];\n\t\t}\n\n\t\t// initialize vert_sum\n\t\t{\n\t\t\tfor(tjs_int i = vert_sum_right_limit - vert_sum_left_limit + 1 -1; i>=0; i--)\n\t\t\t\tvert_sum[i].Zero();\n\n\t\t\ttjs_int v_init_start = rect.top + area.top;\n\t\t\tif(v_init_start < 0) v_init_start = 0;\n\t\t\ttjs_int v_init_end = rect.top + area.bottom;\n\t\t\tif(v_init_end >= height) v_init_end = height - 1;\n\t\t\tvert_sum_count = v_init_end - v_init_start + 1;\n\t\t\tfor(tjs_int y = v_init_start; y <= v_init_end; y++)\n\t\t\t{\n\t\t\t\tconst tjs_uint32 * add_line;\n\t\t\t\tadd_line = (const tjs_uint32*)GetScanLine(y);\n\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\tfor(int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t*(vs++) += add_line[x];\n\t\t\t}\n\t\t}\n\n\t\t// prepare variables to be used in following loop\n\t\ttjs_int h_init_start = rect.left + area.left; // this always be the same value as vert_sum_left_limit\n\t\tif(h_init_start < 0) h_init_start = 0;\n\t\ttjs_int h_init_end = rect.left + area.right;\n\t\tif(h_init_end >= width) h_init_end = width - 1;\n\n\t\ttjs_int left_frac_len =\n\t\t\trect.left + area.left < 0 ? -(rect.left + area.left) : 0;\n\t\ttjs_int right_frac_len =\n\t\t\trect.right + area.right >= width ? rect.right + area.right - width + 1: 0;\n\t\ttjs_int center_len = rect.right - rect.left - left_frac_len - right_frac_len;\n\n\t\tif(center_len < 0)\n\t\t{\n\t\t\tleft_frac_len = rect.right - rect.left;\n\t\t\tright_frac_len = 0;\n\t\t\tcenter_len = 0;\n\t\t}\n\t\ttjs_int left_frac_lim = rect.left + left_frac_len;\n\t\ttjs_int center_lim = rect.left + left_frac_len + center_len;\n\n\t\t// for each line\n\t\ttjs_int dest_buf_free = dest_buf_size;\n\t\ttjs_int dest_buf_wp = 0;\n\n\t\tfor(tjs_int y = rect.top; y < rect.bottom; y++)\n\t\t{\n\t\t\t// rotate dest_buf\n\t\t\tif(dest_buf_free == 0)\n\t\t\t{\n\t\t\t\t// dest_buf is full;\n\t\t\t\t// write last dest_buf back to the bitmap\n\t\t\t\tmemcpy(\n\t\t\t\t\trect.left + ((tjs_uint32*)GetScanLineForWrite(y - dest_buf_size)),\n\t\t\t\t\tdest_buf[dest_buf_wp],\n\t\t\t\t\t(rect.right - rect.left) * sizeof(tjs_uint32));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdest_buf_free --;\n\t\t\t}\n\n\t\t\t// build initial sum\n\t\t\ttARGB sum;\n\t\t\tsum.Zero();\n\t\t\ttjs_int horz_sum_count = h_init_end - h_init_start + 1;\n\n\t\t\tfor(tjs_int x = h_init_start; x <= h_init_end; x++)\n\t\t\t\tsum += vert_sum[x - vert_sum_left_limit];\n\n\t\t\t// process a line\n\t\t\ttjs_uint32 *dp = dest_buf[dest_buf_wp];\n\t\t\ttjs_int x = rect.left;\n\n\t\t\t//- do left fraction part\n\t\t\tfor(; x < left_frac_lim; x++)\n\t\t\t{\n\t\t\t\ttARGB tmp = sum;\n\t\t\t\ttmp.average(horz_sum_count * vert_sum_count);\n\n\t\t\t\t*(dp++) = tmp;\n\n\t\t\t\t// update sum\n\t\t\t\tif(x + area.left >= 0)\n\t\t\t\t{\n\t\t\t\t\tsum -= vert_sum[x + area.left - vert_sum_left_limit];\n\t\t\t\t\thorz_sum_count --;\n\t\t\t\t}\n\t\t\t\tif(x + area.right + 1 < width)\n\t\t\t\t{\n\t\t\t\t\tsum += vert_sum[x + area.right + 1 - vert_sum_left_limit];\n\t\t\t\t\thorz_sum_count ++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//- do center part\n\t\t\tif(center_len > 0)\n\t\t\t{\n\t\t\t\t// uses function in tvpgl\n\t\t\t\tTVPDoBoxBlurAvg<tARGB>(dp, (base_type*)&sum,\n\t\t\t\t\t(const base_type *)(vert_sum + x + area.right + 1 - vert_sum_left_limit),\n\t\t\t\t\t(const base_type *)(vert_sum + x + area.left - vert_sum_left_limit),\n\t\t\t\t\thorz_sum_count * vert_sum_count,\n\t\t\t\t\tcenter_len);\n\t\t\t\tdp += center_len;\n\t\t\t}\n\t\t\tx = center_lim;\n\n\t\t\t//- do right fraction part\n\t\t\tfor(; x < rect.right; x++)\n\t\t\t{\n\t\t\t\ttARGB tmp = sum;\n\t\t\t\ttmp.average(horz_sum_count * vert_sum_count);\n\n\t\t\t\t*(dp++) = tmp;\n\n\t\t\t\t// update sum\n\t\t\t\tif(x + area.left >= 0)\n\t\t\t\t{\n\t\t\t\t\tsum -= vert_sum[x + area.left - vert_sum_left_limit];\n\t\t\t\t\thorz_sum_count --;\n\t\t\t\t}\n\t\t\t\tif(x + area.right + 1 < width)\n\t\t\t\t{\n\t\t\t\t\tsum += vert_sum[x + area.right + 1 - vert_sum_left_limit];\n\t\t\t\t\thorz_sum_count ++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// update vert_sum\n\t\t\tif(y != rect.bottom - 1)\n\t\t\t{\n\t\t\t\tconst tjs_uint32 * sub_line;\n\t\t\t\tconst tjs_uint32 * add_line;\n\t\t\t\tsub_line =\n\t\t\t\t\ty + area.top < 0 ?\n\t\t\t\t\t\t(const tjs_uint32 *)NULL :\n\t\t\t\t\t\t(const tjs_uint32 *)GetScanLine(y + area.top);\n\t\t\t\tadd_line =\n\t\t\t\t\ty + area.bottom + 1 >= height ?\n\t\t\t\t\t\t(const tjs_uint32 *)NULL :\n\t\t\t\t\t\t(const tjs_uint32 *)GetScanLine(y + area.bottom + 1);\n\n\t\t\t\tif(sub_line && add_line)\n\t\t\t\t{\n\t\t\t\t\t// both sub_line and add_line are available\n\t\t\t\t\t// uses function in tvpgl\n\t\t\t\t\tTVPAddSubVertSum<tARGB>((base_type*)vert_sum,\n\t\t\t\t\t\tadd_line + vert_sum_left_limit,\n\t\t\t\t\t\tsub_line + vert_sum_left_limit,\n\t\t\t\t\t\tvert_sum_right_limit - vert_sum_left_limit + 1);\n\n\t\t\t\t}\n\t\t\t\telse if(sub_line)\n\t\t\t\t{\n\t\t\t\t\t// only sub_line is available\n\t\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\t\tfor(int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t\t*vs -= sub_line[x], vs ++;\n\t\t\t\t\tvert_sum_count --;\n\t\t\t\t}\n\t\t\t\telse if(add_line)\n\t\t\t\t{\n\t\t\t\t\t// only add_line is available\n\t\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\t\tfor(int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t\t*vs += add_line[x], vs ++;\n\t\t\t\t\tvert_sum_count ++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// step dest_buf_wp\n\t\t\tdest_buf_wp++;\n\t\t\tif(dest_buf_wp >= dest_buf_size) dest_buf_wp = 0;\n\t\t}\n\n\t\t// write remaining dest_buf back to the bitmap\n\t\twhile(dest_buf_free < dest_buf_size)\n\t\t{\n\t\t\tmemcpy(\n\t\t\t\trect.left +\n\t\t\t\t(tjs_uint32*)(GetScanLineForWrite(rect.bottom - (dest_buf_size - dest_buf_free))),\n\t\t\t\tdest_buf[dest_buf_wp], (rect.right - rect.left) * sizeof(tjs_uint32));\n\n\t\t\tdest_buf_wp++;\n\t\t\tif(dest_buf_wp >= dest_buf_size) dest_buf_wp = 0;\n\t\t\tdest_buf_free++;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\t// exception caught\n\t\tif(vert_sum) TJSAlignedDealloc(vert_sum);\n\t\tif(dest_buf_size)\n\t\t{\n\t\t\tif(dest_buf)\n\t\t\t{\n\t\t\t\tfor(tjs_int i = 0 ; i < dest_buf_size; i++)\n\t\t\t\t\tif(dest_buf[i]) delete [] dest_buf[i];\n\t\t\t\tdelete [] dest_buf;\n\t\t\t}\n\t\t}\n\t\tthrow;\n\t}\n\n\t// free buffeers\n\tTJSAlignedDealloc(vert_sum);\n\tif(dest_buf_size)\n\t{\n\t\tfor(tjs_int i = 0 ; i < dest_buf_size; i++) delete [] dest_buf[i];\n\t\tdelete [] dest_buf;\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::InternalDoBoxBlur(tTVPRect rect, tTVPRect area, bool hasalpha)\n{\n\tBOUND_CHECK(false);\n\n\tif(area.right < area.left)\n\t\tstd::swap(area.right, area.left);\n\tif(area.bottom < area.top)\n\t\tstd::swap(area.bottom, area.top);\n\n\tif(area.left == 0 && area.right == 0 &&\n\t\tarea.top == 0 && area.bottom == 0) return false; // no conversion occurs\n\n\tif(area.left > 0 || area.right < 0 || area.top > 0 || area.bottom < 0)\n\t\tTVPThrowExceptionMessage(TVPBoxBlurAreaMustContainCenterPixel);\n\n#if 0\n\ttjs_uint64 area_size = (tjs_uint64)\n\t\t(area.right - area.left + 1) * (area.bottom - area.top + 1);\n\tif(area_size < 256)\n\t{\n\t\tif(!hasalpha)\n\t\t\tDoBoxBlurLoop<tTVPARGB<tjs_uint16> >(rect, area);\n\t\telse\n\t\t\tDoBoxBlurLoop<tTVPARGB_AA<tjs_uint16> >(rect, area);\n\t}\n\telse if(area_size < (1L<<24))\n\t{\n\t\tif(!hasalpha)\n\t\t\tDoBoxBlurLoop<tTVPARGB<tjs_uint32> >(rect, area);\n\t\telse\n\t\t\tDoBoxBlurLoop<tTVPARGB_AA<tjs_uint32> >(rect, area);\n\t}\n\telse\n\t\tTVPThrowExceptionMessage(TVPBoxBlurAreaMustBeSmallerThan16Million);\n\n#endif\n\tiTVPRenderMethod *method; int idL, idT, idR, idB;\n\tif (hasalpha) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"BoxBlurAlpha\");\n\t\tstatic int\n\t\t\t_idL = _method->EnumParameterID(\"area_left\"),\n\t\t\t_idT = _method->EnumParameterID(\"area_top\"),\n\t\t\t_idR = _method->EnumParameterID(\"area_right\"),\n\t\t\t_idB = _method->EnumParameterID(\"area_bottom\");\n\t\tidL = _idL, idT = _idT, idR = _idR, idB = _idB;\n\t\tmethod = _method;\n\t} else {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"BoxBlur\");\n\t\tstatic int\n\t\t\t_idL = _method->EnumParameterID(\"area_left\"),\n\t\t\t_idT = _method->EnumParameterID(\"area_top\"),\n\t\t\t_idR = _method->EnumParameterID(\"area_right\"),\n\t\t\t_idB = _method->EnumParameterID(\"area_bottom\");\n\t\tidL = _idL, idT = _idT, idR = _idR, idB = _idB;\n\t\tmethod = _method;\n\t}\n\tmethod->SetParameterInt(idL, area.left);\n\tmethod->SetParameterInt(idT, area.top);\n\tmethod->SetParameterInt(idR, area.right);\n\tmethod->SetParameterInt(idB, area.bottom);\n\n\tiTVPTexture2D *reftex = GetTexture();\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(reftex, rect)\n\t};\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray(src_tex));\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::DoBoxBlur(const tTVPRect & rect, const tTVPRect & area)\n{\n\t// Blur the bitmap with box-blur algorithm.\n\t// 'rect' is a rectangle to blur.\n\t// 'area' is an area which destination pixel refers.\n\t// right and bottom of 'area' *does contain* pixels in the boundary.\n\t// eg. area:(-1,-1,1,1)  : Blur is to be performed using average of 3x3\n\t//                          pixels around the destination pixel.\n\t//     area:(-10,0,10,0) : Blur is to be performed using average of 21x1\n\t//                          pixels around the destination pixel. This results\n\t//                          horizontal blur.\n\n\treturn InternalDoBoxBlur(rect, area, false);\n}\n//---------------------------------------------------------------------------\nbool iTVPBaseBitmap::DoBoxBlurForAlpha(const tTVPRect & rect, const tTVPRect &area)\n{\n\treturn InternalDoBoxBlur(rect, area, true);\n}\n//---------------------------------------------------------------------------\nvoid tTVPBaseBitmap::UDFlip(const tTVPRect &rect)\n{\n\t// up-down flip for given rectangle\n\n\tif (rect.left < 0 || rect.top < 0 || rect.right >(tjs_int)GetWidth() ||\n\t\trect.bottom >(tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPSrcRectOutOfBitmap);\n\n\ttjs_int h = (rect.bottom - rect.top) /2;\n\ttjs_int w = rect.right - rect.left;\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 * l1 = (tjs_uint8*)GetScanLineForWrite(rect.top);\n\ttjs_uint8 * l2 = (tjs_uint8*)GetScanLineForWrite(rect.bottom - 1);\n\n\n\tif(Is32BPP())\n\t{\n\t\t// 32bpp\n\t\tl1 += rect.left * sizeof(tjs_uint32);\n\t\tl2 += rect.left * sizeof(tjs_uint32);\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPSwapLine32((tjs_uint32*)l1, (tjs_uint32*)l2, w);\n\t\t\tl1 += pitch;\n\t\t\tl2 -= pitch;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// 8bpp\n\t\tl1 += rect.left;\n\t\tl2 += rect.left;\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPSwapLine8(l1, l2, w);\n\t\t\tl1 += pitch;\n\t\t\tl2 -= pitch;\n\t\t}\n\t}\n}\n\nvoid iTVPBaseBitmap::UDFlip(const tTVPRect &rect)\n{\n\t// up-down flip for given rectangle\n\n\tif(rect.left < 0 || rect.top < 0 || rect.right > (tjs_int)GetWidth() ||\n\t\trect.bottom > (tjs_int)GetHeight())\n\t\t\t\tTVPThrowExceptionMessage(TVPSrcRectOutOfBitmap);\n\n\tiTVPTexture2D * reftex = GetTexture();\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(reftex, tTVPRect(rect.left, rect.bottom, rect.right, rect.top))\n\t};\n\tstatic iTVPRenderMethod* method = GetRenderManager()->GetRenderMethod(\"Copy\");\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray(src_tex));\n}\n//---------------------------------------------------------------------------\nvoid tTVPBaseBitmap::LRFlip(const tTVPRect &rect)\n{\n\t// left-right flip\n\tif (rect.left < 0 || rect.top < 0 || rect.right >(tjs_int)GetWidth() ||\n\t\trect.bottom >(tjs_int)GetHeight())\n\t\tTVPThrowExceptionMessage(TVPSrcRectOutOfBitmap);\n\n\ttjs_int h = rect.bottom - rect.top;\n\ttjs_int w = rect.right - rect.left;\n\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(rect.top);\n\n\tif(Is32BPP())\n\t{\n\t\t// 32bpp\n\t\tline += rect.left * sizeof(tjs_uint32);\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPReverse32((tjs_uint32*)line, w);\n\t\t\tline += pitch;\n\t\t}\n\t}\n\telse\n\t{\n\t\t// 8bpp\n\t\tline += rect.left;\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPReverse8(line, w);\n\t\t\tline += pitch;\n\t\t}\n\t}\n}\n\nvoid iTVPBaseBitmap::LRFlip(const tTVPRect &rect)\n{\n\t// left-right flip\n\tif(rect.left < 0 || rect.top < 0 || rect.right > (tjs_int)GetWidth() ||\n\t\trect.bottom > (tjs_int)GetHeight())\n\t\t\t\tTVPThrowExceptionMessage(TVPSrcRectOutOfBitmap);\n\n\tiTVPTexture2D * reftex = GetTexture();\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(reftex, tTVPRect(rect.right, rect.top, rect.left, rect.bottom))\n\t};\n\tstatic iTVPRenderMethod* method = GetRenderManager()->GetRenderMethod(\"Copy\");\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect),\n\t\treftex, rect, tRenderTexRectArray(src_tex));\n}\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::DoGrayScale(tTVPRect rect)\n{\n\tif(!Is32BPP()) return;  // 8bpp is always grayscaled bitmap\n\n\tBOUND_CHECK(RET_VOID);\n#if 0\n\ttjs_int h = rect.bottom - rect.top;\n\ttjs_int w = rect.right - rect.left;\n\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(rect.top);\n\n\n\tline += rect.left * sizeof(tjs_uint32);\n\twhile(h--)\n\t{\n\t\tTVPDoGrayScale((tjs_uint32*)line, w);\n\t\tline += pitch;\n\t}\n#endif\n\tstatic iTVPRenderMethod* method = TVPGetRenderManager()->GetRenderMethod(\"DoGrayScale\");\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray());\n}\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::AdjustGamma(tTVPRect rect, const tTVPGLGammaAdjustData & data)\n{\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tBOUND_CHECK(RET_VOID);\n\n\tif(!memcmp(&data, &TVPIntactGammaAdjustData, sizeof(tTVPGLGammaAdjustData)))\n\t\treturn;\n#if 0\n\ttTVPGLGammaAdjustTempData temp;\n\tTVPInitGammaAdjustTempData(&temp, &data);\n\n\ttry\n\t{\n\t\ttjs_int h = rect.bottom - rect.top;\n\t\ttjs_int w = rect.right - rect.left;\n\n\t\ttjs_int pitch = GetPitchBytes();\n\t\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(rect.top);\n\n\n\t\tline += rect.left * sizeof(tjs_uint32);\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPAdjustGamma((tjs_uint32*)line, w, &temp);\n\t\t\tline += pitch;\n\t\t}\n\n\t}\n\tcatch(...)\n\t{\n\t\tTVPUninitGammaAdjustTempData(&temp);\n\t\tthrow;\n\t}\n\n\tTVPUninitGammaAdjustTempData(&temp);\n#endif\n\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"AdjustGamma\");\n\tstatic int data_id = method->EnumParameterID(\"gammaAdjustData\");\n\tmethod->SetParameterPtr(data_id, &data);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray());\n}\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::AdjustGammaForAdditiveAlpha(tTVPRect rect, const tTVPGLGammaAdjustData & data)\n{\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tBOUND_CHECK(RET_VOID);\n\n\tif(!memcmp(&data, &TVPIntactGammaAdjustData, sizeof(tTVPGLGammaAdjustData)))\n\t\treturn;\n#if 0\n\ttTVPGLGammaAdjustTempData temp;\n\tTVPInitGammaAdjustTempData(&temp, &data);\n\n\ttry\n\t{\n\t\ttjs_int h = rect.bottom - rect.top;\n\t\ttjs_int w = rect.right - rect.left;\n\n\t\ttjs_int pitch = GetPitchBytes();\n\t\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(rect.top);\n\n\n\t\tline += rect.left * sizeof(tjs_uint32);\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPAdjustGamma_a((tjs_uint32*)line, w, &temp);\n\t\t\tline += pitch;\n\t\t}\n\n\t}\n\tcatch(...)\n\t{\n\t\tTVPUninitGammaAdjustTempData(&temp);\n\t\tthrow;\n\t}\n\n\tTVPUninitGammaAdjustTempData(&temp);\n#endif\n\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"AdjustGamma_a\");\n\tstatic int data_id = method->EnumParameterID(\"gammaAdjustData\");\n\tmethod->SetParameterPtr(data_id, &data);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rect), reftex,\n\t\trect, tRenderTexRectArray());\n}\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::ConvertAddAlphaToAlpha()\n{\n\t// convert additive alpha representation to alpha representation\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\ttjs_int w = GetWidth();\n\ttjs_int h = GetHeight();\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(0);\n\n\twhile(h--)\n\t{\n\t\tTVPConvertAdditiveAlphaToAlpha((tjs_uint32*)line, w);\n\t\tline += pitch;\n\t}\n#endif\n\tstatic iTVPRenderMethod* method = TVPGetRenderManager()->GetRenderMethod(\"AdditiveAlphaToAlpha\");\n\ttTVPRect rc(0, 0, w, h);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rc), reftex,\n\t\trc, tRenderTexRectArray());\n}\n//---------------------------------------------------------------------------\nvoid iTVPBaseBitmap::ConvertAlphaToAddAlpha()\n{\n\t// convert additive alpha representation to alpha representation\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\ttjs_int w = GetWidth();\n\ttjs_int h = GetHeight();\n#if 0\n\ttjs_int pitch = GetPitchBytes();\n\ttjs_uint8 * line = (tjs_uint8*)GetScanLineForWrite(0);\n\n\twhile(h--)\n\t{\n\t\tTVPConvertAlphaToAdditiveAlpha((tjs_uint32*)line, w);\n\t\tline += pitch;\n\t}\n#endif\n\tstatic iTVPRenderMethod* method = TVPGetRenderManager()->GetRenderMethod(\"AlphaToAdditiveAlpha\");\n\ttTVPRect rc(0, 0, w, h);\n\tiTVPTexture2D *reftex = GetTexture();\n\tTVPGetRenderManager()->OperateRect(method, GetTextureForRender(method->IsBlendTarget(), &rc), reftex,\n\t\trc, tRenderTexRectArray());\n}\n//---------------------------------------------------------------------------\n\ntTVPBaseBitmap::tTVPBaseBitmap(tjs_uint w, tjs_uint h, tjs_uint bpp /*= 32*/) {\n\tif (!w) w = 1; if (!h) h = 1;\n\tBitmap = TVPGetSoftwareRenderManager()->CreateTexture2D(nullptr, 0, w, h, bpp == 8 ? TVPTextureFormat::Gray : TVPTextureFormat::RGBA);\n}\n\nbool tTVPBaseBitmap::AssignBitmap(tTVPBitmap *bmp) {\n\treturn AssignTexture(TVPGetSoftwareRenderManager()->CreateTexture2D(bmp));\n}\n\niTVPRenderManager* tTVPBaseBitmap::GetRenderManager() {\n\treturn TVPGetSoftwareRenderManager();\n}\n\n//---------------------------------------------------------------------------\ntTVPBaseTexture::tTVPBaseTexture(tjs_uint w, tjs_uint h, tjs_uint bpp /*= 32*/) {\n\tif (!w) w = 1; if (!h) h = 1;\n\tBitmap = TVPGetRenderManager()->CreateTexture2D(nullptr, 0, w, h, bpp == 8 ? TVPTextureFormat::Gray : TVPTextureFormat::RGBA);\n}\n\nbool tTVPBaseTexture::AssignBitmap(tTVPBitmap *bmp) {\n\tassert(false);\n\treturn false;\n}\n\niTVPRenderManager* tTVPBaseTexture::GetRenderManager() {\n\treturn TVPGetRenderManager();\n}\n\nvoid tTVPBaseTexture::Update(const void *pixel, unsigned int pitch, int x, int y, int w, int h)\n{\n\tGetTextureForRender(false, nullptr)->Update(pixel, TVPTextureFormat::RGBA, pitch, tTVPRect(x, y, x + w, y + h));\n}\n"
  },
  {
    "path": "src/core/visual/LayerBitmapIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Base Layer Bitmap implementation\n//---------------------------------------------------------------------------\n#ifndef LayerBitmapIntfH\n#define LayerBitmapIntfH\n\n\n#include \"ComplexRect.h\"\n#include \"tvpgl.h\"\n#include \"argb.h\"\n#include \"drawable.h\"\n\n#ifndef TVP_REVRGB\n#define TVP_REVRGB(v) ((v & 0xFF00FF00) | ((v >> 16) & 0xFF) | ((v & 0xFF) << 16))\n#endif\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTVPBBBltMethod and tTVPBBStretchType\n//---------------------------------------------------------------------------\nenum tTVPBBBltMethod\n{\n\tbmCopy,\n\tbmCopyOnAlpha,\n\tbmAlpha,\n\tbmAlphaOnAlpha,\n\tbmAdd,\n\tbmSub,\n\tbmMul,\n\tbmDodge,\n\tbmDarken,\n\tbmLighten,\n\tbmScreen,\n\tbmAddAlpha,\n\tbmAddAlphaOnAddAlpha,\n\tbmAddAlphaOnAlpha,\n\tbmAlphaOnAddAlpha,\n\tbmCopyOnAddAlpha,\n\tbmPsNormal,\n\tbmPsAdditive,\n\tbmPsSubtractive,\n\tbmPsMultiplicative,\n\tbmPsScreen,\n\tbmPsOverlay,\n\tbmPsHardLight,\n\tbmPsSoftLight,\n\tbmPsColorDodge,\n\tbmPsColorDodge5,\n\tbmPsColorBurn,\n\tbmPsLighten,\n\tbmPsDarken,\n\tbmPsDifference,\n\tbmPsDifference5,\n\tbmPsExclusion\n};\n\nenum tTVPBBStretchType\n{\n\tstNearest = 0, // primal method; nearest neighbor method\n\tstFastLinear = 1, // fast linear interpolation (does not have so much precision)\n\tstLinear = 2,  // (strict) linear interpolation\n\tstCubic = 3,    // cubic interpolation\n\tstSemiFastLinear = 4,\n\tstFastCubic = 5,\n\tstLanczos2 = 6,    // Lanczos 2 interpolation\n\tstFastLanczos2 = 7,\n\tstLanczos3 = 8,    // Lanczos 3 interpolation\n\tstFastLanczos3 = 9,\n\tstSpline16 = 10,\t// Spline16 interpolation\n\tstFastSpline16 = 11,\n\tstSpline36 = 12,\t// Spline36 interpolation\n\tstFastSpline36 = 13,\n\tstAreaAvg = 14,\t// Area average interpolation\n\tstFastAreaAvg = 15,\n\tstGaussian = 16,\n\tstFastGaussian = 17,\n\tstBlackmanSinc = 18,\n\tstFastBlackmanSinc = 19,\n\n\tstTypeMask = 0x0000ffff, // stretch type mask\n\tstFlagMask = 0xffff0000, // flag mask\n\n\tstRefNoClip = 0x10000 // referencing source is not limited by the given rectangle\n\t\t\t\t\t\t// (may allow to see the border pixel to interpolate)\n};\n/*]*/\n\n\n\n//---------------------------------------------------------------------------\n// FIXME: for including order problem\n//---------------------------------------------------------------------------\n#include \"LayerBitmapImpl.h\"\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// t2DAffineMatrix\n//---------------------------------------------------------------------------\nstruct t2DAffineMatrix\n{\n\t/* structure for subscribing following 2D affine transformation matrix */\n\t/*\n\t|                          | a  b  0 |\n\t| [x', y', 1] =  [x, y, 1] | c  d  0 |\n\t|                          | tx ty 1 |\n\t|  thus,\n\t|\n\t|  x' =  ax + cy + tx\n\t|  y' =  bx + dy + ty\n\t*/\n\n\tdouble a;\n\tdouble b;\n\tdouble c;\n\tdouble d;\n\tdouble tx;\n\tdouble ty;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n#define TVP_BB_COPY_MAIN 1\n#define TVP_BB_COPY_MASK 2\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\nextern tTVPGLGammaAdjustData TVPIntactGammaAdjustData;\nextern tjs_int TVPDrawThreadNum;\nextern tjs_int TVPGetProcessorNum(void);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPBaseBitmap\n//---------------------------------------------------------------------------\nclass tTVPNativeBaseBitmap;\nclass iTVPBaseBitmap : public tTVPNativeBaseBitmap\n{\npublic:\n\n\t//void operator =(const iTVPBaseBitmap & rhs) { Assign(rhs); }\n\n\t// metrics\n\tvoid SetSizeWithFill(tjs_uint w, tjs_uint h, tjs_uint32 fillvalue);\n\n\t// point access\n\ttjs_uint32 GetPoint(tjs_int x, tjs_int y) const;\n\tbool SetPoint(tjs_int x, tjs_int y, tjs_uint32 value);\n\tbool SetPointMain(tjs_int x, tjs_int y, tjs_uint32 color); // for 32bpp\n\tbool SetPointMask(tjs_int x, tjs_int y, tjs_int mask); // for 32bpp\n\n\t// drawing stuff\n\tvirtual bool Fill(tTVPRect rect, tjs_uint32 value);\n\n\tbool FillColor(tTVPRect rect, tjs_uint32 color, tjs_int opa);\n\nprivate:\n\tbool BlendColor(tTVPRect rect, tjs_uint32 color, tjs_int opa, bool additive);\n#if 0\n        struct PartialFillParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int x;\n          tjs_int y;\n          tjs_int w;\n          tjs_int h;\n          tjs_int pitch;\n          tjs_uint32 value;\n          bool is32bpp;\n        };\n        static void TJS_USERENTRY PartialFillEntry(void *param);\n        void PartialFill(const PartialFillParam *param);\n\n        struct PartialFillColorParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int x;\n          tjs_int y;\n          tjs_int w;\n          tjs_int h;\n          tjs_int pitch;\n          tjs_uint32 color;\n          tjs_int opa;\n        };\n        static void TJS_USERENTRY PartialFillColorEntry(void *param);\n        void PartialFillColor(const PartialFillColorParam *param);\n\n        struct PartialBlendColorParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int x;\n          tjs_int y;\n          tjs_int w;\n          tjs_int h;\n          tjs_int pitch;\n          tjs_uint32 color;\n          tjs_int opa;\n          bool additive;\n        };\n        static void TJS_USERENTRY PartialBlendColorEntry(void *param);\n        void PartialBlendColor(const PartialBlendColorParam *param);\n\n        struct PartialRemoveConstOpacityParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int x;\n          tjs_int y;\n          tjs_int w;\n          tjs_int h;\n          tjs_int pitch;\n          tjs_int level;\n        };\n        static void TJS_USERENTRY PartialRemoveConstOpacityEntry(void *param);\n        void PartialRemoveConstOpacity(const PartialRemoveConstOpacityParam *param);\n  \n        struct PartialFillMaskParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int x;\n          tjs_int y;\n          tjs_int w;\n          tjs_int h;\n          tjs_int pitch;\n          tjs_int value;\n        };\n        static void TJS_USERENTRY PartialFillMaskEntry(void *param);\n        void PartialFillMask(const PartialFillMaskParam *param);\n\n        struct PartialCopyRectParam {\n          iTVPBaseBitmap *self;\n          tjs_int pixelsize;\n          tjs_uint8 *dest;\n          tjs_int dpitch;\n          tjs_int dx;\n          tjs_int dy;\n          tjs_int w;\n          tjs_int h;\n          const tjs_int8 *src;\n          tjs_int spitch;\n          tjs_int sx;\n          tjs_int sy;\n          tjs_int plane;\n          bool backwardCopy;\n        };\n        static void TJS_USERENTRY PartialCopyRectEntry(void *param);\n        void PartialCopyRect(const PartialCopyRectParam *param);\n\n        struct PartialBltParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int dpitch;\n          tjs_int dx;\n          tjs_int dy;\n          tjs_int w;\n          tjs_int h;\n          const tjs_int8 *src;\n          tjs_int spitch;\n          tjs_int sx;\n          tjs_int sy;\n          tTVPBBBltMethod method;\n          tjs_int opa;\n          bool hda;\n        };\n        static void TJS_USERENTRY PartialBltEntry(void *param);\n        void PartialBlt(const PartialBltParam *param);\n#endif\npublic:\n\tbool FillColorOnAlpha(tTVPRect rect, tjs_uint32 color, tjs_int opa)\n\t{\n\t\treturn BlendColor(rect, color, opa, false);\n\t}\n\n\tbool FillColorOnAddAlpha(tTVPRect rect, tjs_uint32 color, tjs_int opa)\n\t{\n\t\treturn BlendColor(rect, color, opa, true);\n\t}\n\n\tbool RemoveConstOpacity(tTVPRect rect, tjs_int level);\n\n\tbool FillMask(tTVPRect rect, tjs_int value);\n\n\tvirtual bool CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tjs_int plane = (TVP_BB_COPY_MAIN|TVP_BB_COPY_MASK));\n\n    /**\n     * @param ref : Rs[摜(9patch`)\n     * @param margin : 9patch̉Eɂ`̈w擾\n     */\n    bool Copy9Patch( const iTVPBaseBitmap *ref, tTVPRect& margin );\n\n\tbool Blt(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tTVPBBBltMethod method, tjs_int opa,\n\t\t\tbool hda = true);\n\tbool Blt(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\tconst tTVPRect &refrect, tTVPLayerType type, tjs_int opa, bool hda = true);\n\n#if 0\nprivate:\n\ttemplate <typename tFunc>\n\tstatic void TVPDoStretchLoop(tFunc func,\n\t\ttjs_int x_ref_start,\n\t\ttjs_int y_ref_start,\n\t\ttjs_int x_len, tjs_int y_len,\n\t\ttjs_uint8 * destp, tjs_int destpitch,\n\t\ttjs_int x_step, tjs_int y_step,\n\t\tconst tjs_uint8 * refp, tjs_int refpitch);\n\n\ttemplate <typename tStretchFunc>\n\tstatic void TVPDoBiLinearStretchLoop(\n\t\t\ttStretchFunc stretch,\n\t\t\ttjs_int rw, tjs_int rh,\n\t\t\ttjs_int dw, tjs_int dh,\n\t\t\tconst tTVPRect & srccliprect,\n\t\t\ttjs_int x_ref_start,\n\t\t\ttjs_int y_ref_start,\n\t\t\ttjs_int x_len, tjs_int y_len,\n\t\t\ttjs_uint8 * destp, tjs_int destpitch,\n\t\t\ttjs_int x_step, tjs_int y_step,\n\t\t\tconst tjs_uint8 * refp, tjs_int refpitch);\n#endif\npublic:\n\tbool StretchBlt(tTVPRect cliprect, tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tTVPBBBltMethod method, tjs_int opa,\n\t\t\tbool hda = true, tTVPBBStretchType type = stNearest, tjs_real typeopt=0.0);\n#if 0\nprivate:\n\ttemplate <typename tFuncStretch, typename tFuncAffine>\n\tstatic void TVPDoAffineLoop(\n\t\t\ttFuncStretch stretch,\n\t\t\ttFuncAffine affine,\n\t\t\ttjs_int sxs,\n\t\t\ttjs_int sys,\n\t\t\ttjs_uint8 *dest,\n\t\t\ttjs_int l,\n\t\t\ttjs_int len,\n\t\t\tconst tjs_uint8 *src,\n\t\t\ttjs_int srcpitch,\n\t\t\ttjs_int sxl,\n\t\t\ttjs_int syl,\n\t\t\tconst tTVPRect & srcrect);\n\n\ttemplate <typename tFuncStretch, typename tFuncAffine>\n\tstatic void TVPDoBilinearAffineLoop(\n\t\t\ttFuncStretch stretch,\n\t\t\ttFuncAffine affine,\n\t\t\ttjs_int sxs,\n\t\t\ttjs_int sys,\n\t\t\ttjs_uint8 *dest,\n\t\t\ttjs_int l,\n\t\t\ttjs_int len,\n\t\t\tconst tjs_uint8 *src,\n\t\t\ttjs_int srcpitch,\n\t\t\ttjs_int sxl,\n\t\t\ttjs_int syl,\n\t\t\tconst tTVPRect & srccliprect,\n\t\t\tconst tTVPRect & srcrect);\n\n        struct PartialAffineBltParam {\n          iTVPBaseBitmap *self;\n          tjs_uint8 *dest;\n          tjs_int destpitch;\n          tjs_int yc;\n          tjs_int yclim;\n          tjs_int scanlinestart;\n          tjs_int scanlineend;\n          tjs_int *points_x;\n          tjs_int *points_y;\n          tTVPRect *refrect;\n          tjs_int sxstep;\n          tjs_int systep;\n          tTVPRect *destrect;\n          tTVPBBBltMethod method;\n          tjs_int opa;\n          bool hda;\n          tTVPBBStretchType type;\n          bool clear;\n          tjs_uint32 clearcolor;\n          const tjs_uint8 *src;\n          tjs_int srcpitch;\n          tTVPRect *srccliprect;\n          tTVPRect *srcrect;\n          // below variable returns value to main thread.\n          tjs_int leftlimit;\n          tjs_int rightlimit;\n          tjs_int mostupper;\n          tjs_int mostbottom;\n          bool firstline;\n        };\n        static void TJS_USERENTRY PartialAffineBltEntry(void *param);\n        void PartialAffineBlt(PartialAffineBltParam *param);\n\n\tint InternalAffineBlt(tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const tTVPPointD * points,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect = NULL,\n\t\t\tbool hda = true, tTVPBBStretchType mode = stNearest, bool clear = false,\n\t\t\t\ttjs_uint32 clearcolor = 0);\n#endif\npublic:\n\tbool AffineBlt(tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const tTVPPointD * points,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect = NULL,\n\t\t\tbool hda = true, tTVPBBStretchType mode = stNearest, bool clear = false,\n\t\t\t\ttjs_uint32 clearcolor = 0);\n\n\tbool AffineBlt(tTVPRect destrect, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, const t2DAffineMatrix & matrix,\n\t\t\ttTVPBBBltMethod method, tjs_int opa,\n\t\t\ttTVPRect * updaterect = NULL,\n\t\t\tbool hda = true, tTVPBBStretchType mode = stNearest, bool clear = false,\n\t\t\t\ttjs_uint32 clearcolor = 0);\n\nprivate:\n\tbool InternalDoBoxBlur(tTVPRect rect, tTVPRect area, bool hasalpha);\n\npublic:\n\tbool DoBoxBlur(const tTVPRect & rect, const tTVPRect & area);\n\tbool DoBoxBlurForAlpha(const tTVPRect & rect, const tTVPRect & area);\n\n\tvoid UDFlip(const tTVPRect &rect);\n\tvoid LRFlip(const tTVPRect &rect);\n\n\tvoid DoGrayScale(tTVPRect rect);\n\n\tvoid AdjustGamma(tTVPRect rect, const tTVPGLGammaAdjustData & data);\n\tvoid AdjustGammaForAdditiveAlpha(tTVPRect rect, const tTVPGLGammaAdjustData & data);\n\n\n\tvoid ConvertAddAlphaToAlpha();\n\tvoid ConvertAlphaToAddAlpha();\n\n\t// font and text related functions are implemented in each platform.\n};\n//---------------------------------------------------------------------------\nclass iTVPRenderManager;\nclass tTVPBaseBitmap : public iTVPBaseBitmap // for ProvinceImage\n{\npublic:\n\ttTVPBaseBitmap(tjs_uint w, tjs_uint h, tjs_uint bpp = 32);\n\ttTVPBaseBitmap(const iTVPBaseBitmap& r) : iTVPBaseBitmap(r) {}\n\tvirtual bool AssignBitmap(tTVPBitmap *bmp);\n\tvirtual iTVPRenderManager* GetRenderManager();\n\tbool Fill(tTVPRect rect, tjs_uint32 value) override;\n\tvirtual bool CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tjs_int plane = (TVP_BB_COPY_MAIN | TVP_BB_COPY_MASK));\n\tvoid UDFlip(const tTVPRect &rect);\n\tvoid LRFlip(const tTVPRect &rect);\n};\n//---------------------------------------------------------------------------\nclass tTVPBaseTexture : public iTVPBaseBitmap\n{\npublic:\n\ttTVPBaseTexture(tjs_uint w, tjs_uint h, tjs_uint bpp = 32);\n\ttTVPBaseTexture(const iTVPBaseBitmap& r) : iTVPBaseBitmap(r) {}\n\tvirtual bool AssignBitmap(tTVPBitmap *bmp);\n\tvirtual iTVPRenderManager* GetRenderManager();\n\tvoid Update(const void *pixel, unsigned int pitch, int x, int y, int w, int h);\n};\n#endif\n"
  },
  {
    "path": "src/core/visual/LayerIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n#ifndef _USE_MATH_DEFINES\n#define _USE_MATH_DEFINES\n#endif\n#include \"tjsCommHead.h\"\n\n#include <math.h>\n#include <cstdlib>\n#include <cmath>\n\n#include \"tjsArray.h\"\n#include \"LayerIntf.h\"\n#include \"MsgIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerTreeOwner.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"StorageIntf.h\"\n#include \"tvpgl.h\"\n#include \"EventIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"TickCount.h\"\n#include \"DebugIntf.h\"\n#include \"LayerManager.h\"\n#include \"BitmapIntf.h\"\n\n#include \"TVPColor.h\"\n//#include \"TVPSysFont.h\"\n#include \"FontRasterizer.h\"\n#include \"RectItf.h\"\n#include \"FontSystem.h\"\n#include \"tjsDictionary.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"vkdefine.h\"\n#include \"RenderManager.h\"\n#include <cstdlib>\n#include \"FontImpl.h\"\n\nextern void TVPSetFontRasterizer( tjs_int index );\nextern tjs_int TVPGetFontRasterizer();\nextern FontRasterizer* GetCurrentRasterizer();\nextern void TVPMapPrerenderedFont(const tTVPFont & font, const ttstr & storage);\nextern void TVPUnmapPrerenderedFont(const tTVPFont & font);\nextern tjs_int TVPGetCursor(const ttstr & name);\n//---------------------------------------------------------------------------\n// global flags\n//---------------------------------------------------------------------------\nbool TVPFreeUnusedLayerCache = false;\n\t// set true to free unused layer cache bitmap\n\t// (layer cache is not freed until system compact event if this is false)\n//---------------------------------------------------------------------------\n\nstatic bool IsGPU() {\n\tstatic bool isGPU = !TVPIsSoftwareRenderManager()\n\t\t&& !IndividualConfigManager::GetInstance()->GetValue<bool>(\"ogl_accurate_render\", false);\n\treturn isGPU;\n}\n\n//---------------------------------------------------------------------------\n// temporary bitmap management\n//---------------------------------------------------------------------------\nclass tTVPTempBitmapHolder;\nstatic tTVPTempBitmapHolder * TVPTempBitmapHolder = NULL;\nclass tTVPTempBitmapHolder : public tTVPCompactEventCallbackIntf\n{\n\t/*\n\t\tInitial layer bitmap and temporary bitmaps ( for window updating ) holder\n\n\t\tTVP(kirikiri) will be sometimes executed as a child process,\n\t\tsimply returns a argument information, or simply manages the restarting\n\t\tof itself.\n\t\tobject that is not necessary at first should not be created at\n\t\tbeginning of the process :-)\n\t*/\n\n\ttTVPBaseTexture *Bitmap;\n\n\tstd::vector<tTVPBaseTexture *> Temporaries;\n\ttjs_uint TempLevel;\n\tbool TempCompactInit;\n\nprivate:\n\ttjs_int RefCount;\n\ttTVPTempBitmapHolder() : TempLevel(0), TempCompactInit(false)\n\t{\n\t\t// the default image must be a transparent, white colored rectangle\n\t\tRefCount = 1;\n        Bitmap = new tTVPBaseTexture(32, 32);\n\t\tBitmap->Fill(tTVPRect(0, 0, 32, 32), TVP_RGBA2COLOR(255, 255, 255, 0));\n\t}\n\n\t~tTVPTempBitmapHolder()\n\t{\n\t\tstd::vector<tTVPBaseTexture*>::iterator i;\n\t\tfor(i = Temporaries.begin(); i != Temporaries.end(); i++)\n\t\t{\n\t\t\tdelete (*i);\n\t\t}\n\t\tif(TempCompactInit) TVPRemoveCompactEventHook(this);\n        if(Bitmap) delete Bitmap;\n\t}\n\n\ttTVPBaseTexture * InternalGetTemp(tjs_uint w, tjs_uint h, bool fit)\n\t{\n\t\t// compact initialization\n\t\tif(!TempCompactInit)\n\t\t{\n\t\t\tTVPAddCompactEventHook(this);\n\t\t\tTempCompactInit = true;\n\t\t}\n\n\t\t// align width to even\n\t\tif(!fit) w += (w & 1);\n\n\t\t// get temporary bitmap (nested)\n\t\tTempLevel++;\n\t\tif(TempLevel > Temporaries.size())\n\t\t{\n\t\t\t// increase buffer size\n\t\t\ttTVPBaseTexture *bmp = new tTVPBaseTexture(w, h);\n\t\t\tTemporaries.push_back(bmp);\n\t\t\treturn bmp;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTVPBaseTexture *bmp = Temporaries[TempLevel - 1];\n\t\t\tif(!fit)\n\t\t\t{\n\t\t\t\ttjs_uint bw = bmp->GetWidth();\n\t\t\t\ttjs_uint bh = bmp->GetHeight();\n\t\t\t\tif(bw < w || bh < h)\n\t\t\t\t{\n\t\t\t\t\t// increase image size\n\t\t\t\t\tbmp->SetSize(bw > w ? bw:w, bh > h ? bh:h, false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// the size must be fitted\n\t\t\t\ttjs_uint bw = bmp->GetWidth();\n\t\t\t\ttjs_uint bh = bmp->GetHeight();\n\t\t\t\tif(bw != w || bh != h)\n\t\t\t\t\tbmp->SetSize(w, h, false);\n\t\t\t}\n\t\t\treturn bmp;\n\t\t}\n\t}\n\n\tvoid InternalFreeTemp()\n\t{\n\t\tif(TempLevel == 0) return ; // this must be a logical failure\n\t\tTempLevel--;\n\t}\n\n\tvoid CompactTempBitmap()\n\t{\n\t\t// compact tmporary bitmap cache\n\t\tstd::vector<tTVPBaseTexture*>::iterator i;\n\t\tfor(i = Temporaries.begin() + TempLevel; i != Temporaries.end();\n\t\t\ti++)\n\t\t{\n\t\t\tdelete (*i);\n\t\t}\n\n\t\tTemporaries.resize(TempLevel);\n\t}\n\n\n\tvoid TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\t// OnCompact method from tTVPCompactEventCallbackIntf\n\t\t// called when the application is idle, deactivated, minimized, or etc...\n\t\tif(level >= TVP_COMPACT_LEVEL_DEACTIVATE) CompactTempBitmap();\n\t}\n\npublic:\n\tstatic void AddRef()\n\t{\n\t\tif(!TVPTempBitmapHolder)\n\t\t\tTVPTempBitmapHolder = new tTVPTempBitmapHolder();\n\t\telse\n\t\t\tTVPTempBitmapHolder ->RefCount++;\n\t}\n\n\tstatic void Release()\n\t{\n\t\tif(!TVPTempBitmapHolder) return;\n\t\tif(TVPTempBitmapHolder->RefCount == 1)\n\t\t{\n\t\t\tdelete TVPTempBitmapHolder;\n\t\t\tTVPTempBitmapHolder = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPTempBitmapHolder->RefCount --;\n\t\t}\n\t}\n\n\tstatic const tTVPBaseTexture * Get()\n\t\t{ return TVPTempBitmapHolder->Bitmap; }\n\n\n\tstatic tTVPBaseTexture * GetTemp(tjs_uint w, tjs_uint h, bool fit = false)\n\t\t{ return TVPTempBitmapHolder->InternalGetTemp(w, h, fit); }\n\n\tstatic void FreeTemp()\n\t\t{ TVPTempBitmapHolder->InternalFreeTemp(); }\n};\n//---------------------------------------------------------------------------\nconst tTVPBaseTexture & TVPGetInitialBitmap()\n{\n\ttTVPTempBitmapHolder::AddRef(); // ensure default bitmap\n\tconst tTVPBaseTexture *bmp = TVPTempBitmapHolder->Get();\n\ttTVPTempBitmapHolder::Release();\n\n\treturn *bmp;\n}\n//---------------------------------------------------------------------------\nvoid TVPTempBitmapHolderAddRef()\n{\n\ttTVPTempBitmapHolder::AddRef(); // ensure default bitmap\n}\n//---------------------------------------------------------------------------\nvoid TVPTempBitmapHolderRelease()\n{\n\ttTVPTempBitmapHolder::Release();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// FOR EACH CHILD\n//---------------------------------------------------------------------------\n#define TVP_LAYER_FOR_EACH_CHILD_BEGIN(varname)              \\\n\t{ \\\n\t\ttObjectListSafeLockHolder<tTJSNI_BaseLayer> __holder(Children); \\\n\t\ttjs_int __count = Children.GetSafeLockedObjectCount(); \\\n\t\ttjs_int __i; \\\n\t\tfor(__i = 0; __i < __count; __i++)                                 \\\n\t\t{                                                                  \\\n\t\t\ttTJSNI_BaseLayer * varname = Children.GetSafeLockedObjectAt(__i); \\\n\t\t\tif(!varname) continue;\n               \n#define TVP_LAYER_FOR_EACH_CHILD_END \\\n\t\t} \\\n\t\tChildrenArrayValid = false; \\\n\t\tChildrenOrderIndexValid = false; \\\n\t\tif(Manager) Manager->InvalidateOverallIndex(); \\\n\t}\n//---------------------------------------------------------------------------\n// for each child ( for static only access )\n#define TVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(varname)              \\\n\t{ \\\n\t\ttjs_int __count = Children.GetCount(); \\\n\t\ttjs_int __i; \\\n\t\tfor(__i = 0; __i < __count; __i++)                                 \\\n\t\t{                                                                  \\\n\t\t\ttTJSNI_BaseLayer * varname = Children[__i]; \\\n\t\t\tif(!varname) continue;\n\n#define TVP_LAYER_FOR_EACH_CHILD_NOLOCK_END \\\n\t\t} \\\n\t}\n\n#define TVP_LAYER_FOR_EACH_CHILD_NOLOCK_BACKWARD_BEGIN(varname)              \\\n\t{ \\\n\t\ttjs_int __count = Children.GetCount(); \\\n\t\ttjs_int __i; \\\n\t\tfor(__i = __count-1; __i >= 0; __i--)                                 \\\n\t\t{                                                                  \\\n\t\t\ttTJSNI_BaseLayer * varname = Children[__i]; \\\n\t\t\tif(!varname) continue;\n\n#define TVP_LAYER_FOR_EACH_CHILD_NOLOCK_BACKWARD_END \\\n\t\t} \\\n\t}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Recursive Call\n//---------------------------------------------------------------------------\n#define TVP_LAYER_REC_CALL(funccall, action)              \\\n\taction;                                                        \\\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)                  \\\n\t\tchild -> funccall;                                  \\\n\tTVP_LAYER_FOR_EACH_CHILD_END\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// global options\n//---------------------------------------------------------------------------\ntTVPGraphicSplitOperationType TVPGraphicSplitOperationType = gsotNone;\nbool TVPDefaultHoldAlpha = false;\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// below is the tTJSNI_BaseLayer implementation ( pretty large )\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// object lifetime stuff\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer::tTJSNI_BaseLayer()\n{\n\t// creates bitmap holder\n\ttTVPTempBitmapHolder::AddRef();\n\n\t// object lifetime stuff\n\tOwner = NULL;\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\tShutdown = false;\n\tCompactEventHookInit = false;\n\n\t// interface to layer manager\n\tManager = NULL;\n\n\t// tree management\n\tParent = NULL;\n\tVisible = false;\n\tOpacity = 255;\n\tVisibleChildrenCount = -1;\n\tChildrenArray = NULL;\n\tChildrenArrayValid = false;\n\tArrayClearMethod = NULL;\n\tOrderIndex = 0;\n\tOverallOrderIndex = 0;\n\tChildrenOrderIndexValid = false;\n\tAbsoluteOrderMode = false; // initially relative mode\n\tAbsoluteOrderIndex = 0;\n\n\t// layer type management\n\tDisplayType = Type = ltAlpha;\n\t\t// later reset this if the layer becomes a primary layer\n\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\n\t// geographical management\n\tExposedRegionValid = false;\n\tRect.left = 0;\n\tRect.top = 0;\n\tRect.right = 32;\n\tRect.bottom = 32;\n\n\t// input event / hit test management\n\tHitType = htMask;\n\tHitThreshold = 16;\n\tCursor = 0; // 0 = crDefault\n\tCursorX_Work = 0;\n\tShowParentHint = true;\n\tIgnoreHintSensing = false;\n\tUseAttention = false;\n\tImeMode = ::imDisable;\n\tAttentionLeft = AttentionTop = 0;\n\n\tEnabled = true;\n\tFocusable = false;\n\tJoinFocusChain = true;\n\n\t// image buffer management\n\tMainImage = NULL;\n\tCanHaveImage = true;\n\tProvinceImage = NULL;\n\tImageLeft = 0;\n\tImageTop = 0;\n\n\t// cache management\n\tCacheEnabledCount = 0;\n\tCacheBitmap = NULL;\n\tCached = false;\n\n\t// drawing function stuff\n\tFace = dfAuto;\n\tUpdateDrawFace();\n\tImageModified = false;\n\tHoldAlpha = TVPDefaultHoldAlpha;\n\tClipRect.left = 0;\n\tClipRect.right = 0;\n\tClipRect.top = 0;\n\tClipRect.bottom = 0;\n\n\t// Updating management\n\tCallOnPaint = false;\n\tInCompletion = false;\n\n\t// transition management\n\tDivisibleTransHandler = NULL;\n\tGiveUpdateTransHandler = NULL;\n\tTransDest = NULL;\n\tTransDestObj = NULL;\n\tTransSrc = NULL;\n\tTransSrcObj = NULL;\n\tInTransition = false;\n\tTransWithChildren = false;\n\tDestSLP = NULL;\n\tSrcSLP = NULL;\n\tTransCompEventPrevented = false;\n\tUseTransTickCallback = false;\n\tTransTickCallback = tTJSVariantClosure(NULL, NULL);\n\n\t// allocate the default image\n\tAllocateDefaultImage();\n\n\t// interface to font object\n\tFont = MainImage->GetFont(); // retrieve default font\n\tFontObject = NULL;\n\n#if 0\n\t// province management\n\tClearProvinceInformation();\n#endif\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer::~tTJSNI_BaseLayer()\n{\n\ttTVPTempBitmapHolder::Release();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_BaseLayer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tOwner = tjs_obj; // no addref\n\n\t// get the window native instance\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t//if(clo.Object == NULL) TVPThrowExceptionMessage(TVPSpecifyWindow);\n\tif(clo.Object == NULL) TVPThrowExceptionMessage(TJS_W(\"Please specify layerTreeOwnerInterface object\"));\n\n\tclass iTVPLayerTreeOwner* lto = NULL;\n\ttTJSVariant iface_v;\n\tif(TJS_FAILED(clo.PropGet(0, TJS_W(\"layerTreeOwnerInterface\"), NULL, &iface_v, NULL)))\n\t\tTVPThrowExceptionMessage( TJS_W(\"Cannot Retrive Layer Tree Owner Interface.\") );\n\tlto = reinterpret_cast<iTVPLayerTreeOwner *>((tjs_intptr_t)(tjs_int64)iface_v);\n\n\t// get the layer native instance\n\tclo = param[1]->AsObjectClosureNoAddRef();\n\ttTJSNI_Layer *lay = NULL;\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&lay)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\n\t// retrieve manager\n\t// layer manager is the same as the parent, if the parent is given\n\tif(lay)\n\t{\n\t\tManager = lay->GetManager();\n\t\tif (Manager)\n\t\t\tManager->AddRef(); // lock manager\n\t}\n\n\t// register to parent layer\n\tif(lay) Join(lay);\n\n\t// is primarylayer ?\n\t// ask window to create layer manager \n\tif(!lay)\n\t{\n\t\tManager = new tTVPLayerManager(lto);\n\t\tManager->AttachPrimary(this);\n\t\tManager->RegisterSelfToWindow();\n\n\t\tType = DisplayType = ltOpaque; // initially ltOpaque\n\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 255);\n\t\tUpdateDrawFace();\n\t\tHitThreshold = 0;\n\t}\n//\tIncCacheEnabledCount(); ///// -------------------- test\n\n\tActionOwner = param[0]->AsObjectClosure();\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_BaseLayer::Invalidate()\n{\n\tShutdown = true;\n\n\t// stop transition\n\tStopTransition();\n\tif(TransDest) TransDest->StopTransition();\n\tif(DestSLP) DestSLP->Release(), DestSLP = NULL;\n\tif(SrcSLP) SrcSLP->Release(), SrcSLP = NULL;\n\n\t// cancel events\n\tTVPCancelSourceEvents(Owner);\n\n\t// release all objects\n\tif(IsPrimary())\n\t{\n\t\tif(Manager) Manager->DetachPrimary();\n\t\t// also detach from draw device\n\t\tManager->UnregisterSelfFromWindow();\n\t}\n\n\tif(Manager)\n\t{\n\t\tManager->Release(); // no longer used in this context\n\t\tManager = NULL;\n\t}\n\n\t// part from the parent\n\tPart();\n\n\t// sever all children\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\tchild->Part();\n\tTVP_LAYER_FOR_EACH_CHILD_END\n\n\t// invalidate font object\n\tif(FontObject)\n\t{\n\t\tFontObject->Invalidate(0, NULL, NULL, FontObject);\n\t\tFontObject->Release();\n\t}\n\n\t// deallocate image\n\tDeallocateImage();\n\n\t// free cache image\n\tDeallocateCache();\n\n\t// release the owner\n\tActionOwner.Release();\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\n\t// release Children array\n\tif(ChildrenArray) ChildrenArray->Release(), ChildrenArray = NULL;\n\tif(ArrayClearMethod) ArrayClearMethod->Release(), ArrayClearMethod = NULL;\n\n\t// unregister from compact event hook\n\tif(CompactEventHookInit) TVPRemoveCompactEventHook(this);\n\n\t// cancel events once more\n\tTVPCancelSourceEvents(Owner);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::RegisterCompactEventHook()\n{\n\tif(!CompactEventHookInit)\n\t{\n\t\tTVPAddCompactEventHook(this);\n\t\tCompactEventHookInit = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseLayer::OnCompact(tjs_int level)\n{\n\t// method from tTVPCompactEventCallbackIntf\n\tif(level >= TVP_COMPACT_LEVEL_DEACTIVATE) CompactCache();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Interface to Manager\n//---------------------------------------------------------------------------\niTVPLayerTreeOwner * tTJSNI_BaseLayer::GetLayerTreeOwner() const\n{\n\tif(!Manager) return NULL;\n\treturn Manager->GetLayerTreeOwner();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tree management\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Join(tTJSNI_BaseLayer *parent)\n{\n\tif(parent == this)\n\t\tTVPThrowExceptionMessage(TVPCannotSetParentSelf);\n\tif(parent && parent->Manager != Manager)\n\t\tTVPThrowExceptionMessage(TVPCannotMoveToUnderOtherPrimaryLayer);\n\tif(Parent) Part();\n\tParent = parent;\n\tif(Parent) parent->AddChild(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Part()\n{\n\tUpdate();\n\n\tif(Manager) Manager->NotifyPart(this);\n\n\tif(Parent != NULL)\n\t\tParent->SeverChild(this), Parent = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AddChild(tTJSNI_BaseLayer *child)\n{\n\tNotifyChildrenVisualStateChanged();\n\tChildren.Add(child);\n\tif(AbsoluteOrderMode)\n\t{\n\t\t// first insertion\n\t\tChildren.Compact();\n\t\ttjs_int count = Children.GetCount();\n\t\tif(count >= 2)\n\t\t{\n\t\t\ttTJSNI_BaseLayer *last = Children[count-2];\n\t\t\tchild->AbsoluteOrderIndex = last->GetAbsoluteOrderIndex() +1;\n\t\t}\n\t}\n\tChildrenArrayValid = false;\n\tChildrenOrderIndexValid = false;\n\tif(Manager) Manager->CheckTreeFocusableState(child); // check focusable state of child\n\tif(Manager) Manager->InvalidateOverallIndex();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SeverChild(tTJSNI_BaseLayer *child)\n{\n\tif(Manager) Manager->BlurTree(child); // remove focus from \"child\"\n\tNotifyChildrenVisualStateChanged();\n\tChildren.Remove(child);\n\tChildrenArrayValid = false;\n\tChildrenOrderIndexValid = false;\n\tif(Manager) Manager->InvalidateOverallIndex();\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseLayer::GetChildrenArrayObjectNoAddRef()\n{\n\tif(!ChildrenArray)\n\t{\n\t\t// create an Array object\n\t\tiTJSDispatch2 * classobj;\n\t\tChildrenArray = TJSCreateArrayObject(&classobj);\n\t\ttry\n\t\t{\n\t\t\ttTJSVariant val;\n\t\t\ttjs_error er;\n\t\t\ter = classobj->PropGet(0, TJS_W(\"clear\"), NULL, &val, classobj);\n\t\t\t\t// retrieve clear method\n\t\t\tif(TJS_FAILED(er)) TVPThrowInternalError;\n\t\t\tArrayClearMethod = val.AsObject();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tChildrenArray->Release();\n\t\t\tChildrenArray = NULL;\n\t\t\tclassobj->Release();\n\t\t\tthrow;\n\t\t}\n\t\tclassobj->Release();\n\t}\n\n\tif(!ChildrenArrayValid)\n\t{\n\t\t// re-create children list\n\t\tArrayClearMethod->FuncCall(0, NULL, NULL, NULL, 0, NULL, ChildrenArray);\n\t\t\t// clear array\n\n\t\ttjs_int count = 0;\n\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\t\tiTJSDispatch2 *dsp = child->Owner;\n\t\t\ttTJSVariant val(dsp, dsp);\n\t\t\tChildrenArray->PropSetByNum(TJS_MEMBERENSURE, count, &val,\n\t\t\t\tChildrenArray);\n\t\t\tcount++;\n\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\t\tChildrenArrayValid = true;\n\t}\n\n\treturn ChildrenArray;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTJSNI_BaseLayer::GetAncestorChild(tTJSNI_BaseLayer *ancestor)\n{\n\t// retrieve \"ancestor\"'s child that is ancestor of this ( can be thisself )\n\ttTJSNI_BaseLayer *c = this;\n\ttTJSNI_BaseLayer *p = Parent;\n\twhile(p)\n\t{\n\t\tif(p == ancestor) return c;\n\t\tc = p;\n\t\tp = p->Parent;\n\t}\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::IsAncestor(tTJSNI_BaseLayer *ancestor)\n{\n\t// is \"ancestor\" is ancestor of this layer ? (cannot be itself)\n\ttTJSNI_BaseLayer *p = Parent;\n\twhile(p)\n\t{\n\t\tif(p == ancestor) return true;\n\t\tp = p->Parent;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::RecreateOverallOrderIndex(tjs_uint& index,\n\t\tstd::vector<tTJSNI_BaseLayer*>& nodes)\n{\n\tOverallOrderIndex = index;\n\tindex++;\n\n\tnodes.push_back(this);\n\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tchild->RecreateOverallOrderIndex(index, nodes);\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Exchange(tTJSNI_BaseLayer *target, bool keepchildren)\n{\n\t// exchange this for the other layer\n\tif(this == target) return;\n\n\ttTJSNI_BaseLayer *this_ancestor_child = this->GetAncestorChild(target);\n\ttTJSNI_BaseLayer *target_ancestor_child = target->GetAncestorChild(this);\n\n\ttTJSNI_BaseLayer *this_parent = this->Parent;\n\ttTJSNI_BaseLayer *target_parent = target->Parent;\n\n\tbool this_primary = this->IsPrimary();\n\tbool target_primary = target->IsPrimary();\n\n\tbool this_parent_absolute = true;\n\tif(this->Parent) this_parent_absolute = this->Parent->AbsoluteOrderMode;\n\ttjs_int this_index = this->GetAbsoluteOrderIndex();\n\n\tbool target_parent_absolute = true;\n\tif(target->Parent) target_parent_absolute = target->Parent->AbsoluteOrderMode;\n\ttjs_int target_index = target->GetAbsoluteOrderIndex();\n\n\t// remove primary\n\tif(Manager)\n\t{\n\t\tif(this_primary) Manager->DetachPrimary();\n\t\tif(target_primary) Manager->DetachPrimary();\n\t}\n\n\t// part from each parent\n\tthis->Part();\n\ttarget->Part();\n\n\ttTJSNI_BaseLayer * this_joined_parent;\n\ttTJSNI_BaseLayer * target_joined_parent;\n\tif(this_ancestor_child)\n\t{\n\t\t// \"this\" is a descendant of the \"target\"\n\t\tif(this_ancestor_child != this) this_ancestor_child->Part();\n\n\t\tif(!keepchildren)\n\t\t{\n\t\t\t// join to each target's parent\n\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\tif(target == this_parent)\n\t\t\t\ttarget->Join(target_joined_parent = this);\n\t\t\telse\n\t\t\t\ttarget->Join(target_joined_parent = this_parent);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// sever children\n\t\t\tstd::vector<tjs_int> this_orders;\n\t\t\tstd::vector<tjs_int> target_orders;\n\t\t\ttObjectList<tTJSNI_BaseLayer> this_children(this->Children);\n\t\t\ttObjectList<tTJSNI_BaseLayer> target_children(target->Children);\n\t\t\ttjs_int this_children_count = this_children.GetActualCount();\n\t\t\ttjs_int target_children_count = target_children.GetActualCount();\n\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t{\n\t\t\t\tthis_orders.push_back(this_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\tthis_children[i]->Part();\n\t\t\t}\n\t\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t{\n\t\t\t\ttarget_orders.push_back(target_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\ttarget_children[i]->Part();\n\t\t\t}\n\n\t\t\t// join to each target's parent\n\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\tif(target == this_parent)\n\t\t\t\ttarget->Join(target_joined_parent = this);\n\t\t\telse\n\t\t\t\ttarget->Join(target_joined_parent = this_parent);\n\n\t\t\t// let children join\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\tthis_children[i]->Join(target);\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\ttarget_children[i]->Join(this);\n\n\t\t\tif(this->AbsoluteOrderMode && target->AbsoluteOrderMode)\n\t\t\t{\n\t\t\t\t// reset order index\n\t\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\t\tthis_children[i]->SetAbsoluteOrderIndex(this_orders[i]);\n\t\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\t\ttarget_children[i]->SetAbsoluteOrderIndex(target_orders[i]);\n\t\t\t}\n\t\t}\n\n\n\t\tif(this_ancestor_child != this) this_ancestor_child->Join(this);\n\t}\n\telse if(target_ancestor_child)\n\t{\n\t\t// \"target\" is a descendant of \"this\"\n\t\tif(target_ancestor_child != target) target_ancestor_child->Part();\n\n\t\tif(!keepchildren)\n\t\t{\n\t\t\t// join to each target's parent\n\t\t\tif(this == target_parent)\n\t\t\t\tthis->Join(this_joined_parent = target);\n\t\t\telse\n\t\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\ttarget->Join(target_joined_parent = this_parent);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// sever children\n\t\t\tstd::vector<tjs_int> this_orders;\n\t\t\tstd::vector<tjs_int> target_orders;\n\t\t\ttObjectList<tTJSNI_BaseLayer> this_children(this->Children);\n\t\t\ttObjectList<tTJSNI_BaseLayer> target_children(target->Children);\n\t\t\ttjs_int this_children_count = this_children.GetActualCount();\n\t\t\ttjs_int target_children_count = target_children.GetActualCount();\n\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t{\n\t\t\t\tthis_orders.push_back(this_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\tthis_children[i]->Part();\n\t\t\t}\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t{\n\t\t\t\ttarget_orders.push_back(target_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\ttarget_children[i]->Part();\n\t\t\t}\n\n\t\t\t// join to each target's parent\n\t\t\tif(this == target_parent)\n\t\t\t\tthis->Join(this_joined_parent = target);\n\t\t\telse\n\t\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\ttarget->Join(target_joined_parent = this_parent);\n\n\t\t\t// let children join\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\tthis_children[i]->Join(target);\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\ttarget_children[i]->Join(this);\n\n\t\t\tif(this->AbsoluteOrderMode && target->AbsoluteOrderMode)\n\t\t\t{\n\t\t\t\t// reset order index\n\t\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\t\tthis_children[i]->SetAbsoluteOrderIndex(this_orders[i]);\n\t\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\t\ttarget_children[i]->SetAbsoluteOrderIndex(target_orders[i]);\n\t\t\t}\n\t\t}\n\n\t\tif(target_ancestor_child != target) target_ancestor_child->Join(target);\n\t}\n\telse\n\t{\n\t\t// two layers have no parent-child relationship\n\t\tif(!keepchildren)\n\t\t{\n\t\t\t// join to each target's parent\n\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\ttarget->Join(target_joined_parent = this_parent);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// sever children\n\t\t\tstd::vector<tjs_int> this_orders;\n\t\t\tstd::vector<tjs_int> target_orders;\n\t\t\ttObjectList<tTJSNI_BaseLayer> this_children(this->Children);\n\t\t\ttObjectList<tTJSNI_BaseLayer> target_children(target->Children);\n\t\t\ttjs_int this_children_count = this_children.GetActualCount();\n\t\t\ttjs_int target_children_count = target_children.GetActualCount();\n\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t{\n\t\t\t\tthis_orders.push_back(this_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\tthis_children[i]->Part();\n\t\t\t}\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t{\n\t\t\t\ttarget_orders.push_back(target_children[i]->GetAbsoluteOrderIndex());\n\t\t\t\ttarget_children[i]->Part();\n\t\t\t}\n\n\t\t\t// join to each target's parent\n\t\t\tthis->Join(this_joined_parent = target_parent);\n\t\t\ttarget->Join(target_joined_parent = this_parent);\n\n\t\t\t// let children join\n\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\tthis_children[i]->Join(target);\n\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\ttarget_children[i]->Join(this);\n\n\t\t\tif(this->AbsoluteOrderMode && target->AbsoluteOrderMode)\n\t\t\t{\n\t\t\t\t// reset order index\n\t\t\t\tfor(int i = 0; i < this_children_count; i++)\n\t\t\t\t\tthis_children[i]->SetAbsoluteOrderIndex(this_orders[i]);\n\t\t\t\tfor(int i = 0; i < target_children_count; i++)\n\t\t\t\t\ttarget_children[i]->SetAbsoluteOrderIndex(target_orders[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\t// attach primary\n\tif(Manager)\n\t{\n\t\tif(this_primary) Manager->AttachPrimary(target);\n\t\tif(target_primary) Manager->AttachPrimary(this);\n\t}\n\n\t// reset order index\n\tif(target_joined_parent == this_joined_parent &&\n\t\ttarget_joined_parent &&\n\t\ttarget_joined_parent->AbsoluteOrderMode == target_parent_absolute &&\n\t\tthis_joined_parent->AbsoluteOrderMode == this_parent_absolute &&\n\t\ttarget_parent_absolute == this_parent_absolute &&\n\t\ttarget_parent_absolute == false)\n\t{\n\t\t// two layers have the same parent and the same order mode\n\t\tif(this_index < target_index)\n\t\t{\n\t\t\ttarget->SetOrderIndex(this_index);\n\t\t\tthis->SetOrderIndex(target_index);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis->SetOrderIndex(target_index);\n\t\t\ttarget->SetOrderIndex(this_index);\n\t\t}\n\t}\n\telse\n\t{\n\t\tif(target_joined_parent &&\n\t\t\ttarget_joined_parent->AbsoluteOrderMode == target_parent_absolute)\n\t\t{\n\t\t\tif(target_parent_absolute)\n\t\t\t\ttarget->SetAbsoluteOrderIndex(target_index);\n\t\t\telse\n\t\t\t\ttarget->SetOrderIndex(target_index);\n\t\t}\n\n\t\tif(this_joined_parent &&\n\t\t\tthis_joined_parent->AbsoluteOrderMode == this_parent_absolute)\n\t\t{\n\t\t\tif(this_parent_absolute)\n\t\t\t\tthis->SetAbsoluteOrderIndex(this_index);\n\t\t\telse\n\t\t\t\tthis->SetOrderIndex(this_index);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CheckChildrenVisibleState()\n{\n\tif(!GetCount())\n\t{\n\t\tVisibleChildrenCount = 0;\n\t\treturn;\n\t}\n\tVisibleChildrenCount = 0;\n\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tif(child->GetVisible() && child->GetOpacity() != 0)\n\t\t\tVisibleChildrenCount++;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::NotifyChildrenVisualStateChanged()\n{\n\tVisibleChildrenCount = -1;\n\tSetToCreateExposedRegion(); // in geographical management\n\tif(Manager) Manager->NotifyVisualStateChanged();\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_BaseLayer::GetOverallOrderIndex()\n{\n\tif(!Manager) return 0;\n\tManager->RecreateOverallOrderIndex();\n\treturn OverallOrderIndex;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::RecreateOrderIndex()\n{\n\t// recreate order index information\n\ttjs_uint index = 0;\n\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tchild->OrderIndex = index;\n\t\tindex++;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\tChildrenOrderIndexValid = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetVisible(bool st)\n{\n\tif(Visible != st)\n\t{\n\t\tif(IsPrimary() && !st)\n\t\t\tTVPThrowExceptionMessage(TVPCannotSetPrimaryInvisible);\n\t\tif(!st) Update();\n\t\tVisible = st;\n\t\tif(st) Update();\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tif(Visible)\n\t\t{\n\t\t\tif(Manager) Manager->CheckTreeFocusableState(this);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(Manager) Manager->BlurTree(this); // in input/keyboard focus management\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetOpacity(tjs_int opa)\n{\n\tif(Opacity != opa)\n\t{\n\t\tif(IsPrimary() && opa!=255)\n\t\t\tTVPThrowExceptionMessage(TVPCannotSetPrimaryInvisible);\n\t\tOpacity = opa;\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::IsPrimary() const\n{\n\tif(!Manager) return false;\n\treturn Manager->GetPrimaryLayer() == this;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetParentVisible() const\n{\n\t// is parent visible? this does not check opacity\n\ttTJSNI_BaseLayer *par = Parent;\n\twhile(par)\n\t{\n\t\tif(!par->Visible) { return false; }\n\t\tpar = par->Parent;\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTJSNI_BaseLayer::GetNeighborAbove(bool loop)\n{\n\tif(!Manager) return NULL;\n\n\ttjs_uint index = GetOverallOrderIndex();\n\tstd::vector<tTJSNI_BaseLayer *> & allnodes = Manager->GetAllNodes();\n\n\tif(allnodes.size() == 0) return NULL; // must be an error !!\n\n\tif(index == 0)\n\t{\n\t\t// first ( primary )\n\t\tif(loop)\n\t\t\treturn *(allnodes.end()-1);\n\t\telse\n\t\t\treturn NULL;\n\t}\n\n\treturn *(allnodes.begin() + index -1);\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTJSNI_BaseLayer::GetNeighborBelow(bool loop)\n{\n\tif(!Manager) return NULL;\n\n\ttjs_uint index = GetOverallOrderIndex();\n\tstd::vector<tTJSNI_BaseLayer *> & allnodes = Manager->GetAllNodes();\n\n\tif(allnodes.size() == 0) return NULL; // must be an error !!\n\n\tif(index == allnodes.size() -1)\n\t{\n\t\t// last\n\t\tif(loop)\n\t\t\treturn *(allnodes.begin());\n\t\telse\n\t\t\treturn NULL;\n\t}\n\n\treturn *(allnodes.begin() + index +1);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CheckZOrderMoveRule(tTJSNI_BaseLayer *lay)\n{\n\tif(!Parent) TVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\tif(Parent->Children.GetActualCount() <= 1)\n\t\tTVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\tif(lay == this)\n\t\tTVPThrowExceptionMessage(TVPCannotMoveNextToSelfOrNotSiblings);\n\tif(lay->Parent != Parent)\n\t\tTVPThrowExceptionMessage(TVPCannotMoveNextToSelfOrNotSiblings);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ChildChangeOrder(tjs_int from, tjs_int to)\n{\n\t// called from children; change child's order from \"from\" to \"to\"\n\t// given orders are treated as orders before re-ordering.\n\tif(from == to) return; // no action\n\n\ttTJSNI_BaseLayer *fromlay;\n\ttTVPComplexRect rects;\n\tChildren.Compact();\n\tif(from < to)\n\t{\n\t\t// forward\n\n\t\t// rotate\n\t\tfromlay = Children[from];\n\t\tfor(tjs_int i = from; i < to; i++)\n\t\t{\n\t\t\tChildren[i] = Children[i + 1];\n\t\t\ttTVPRect r = fromlay->Rect;\n\t\t\tif(TVPIntersectRect(&r, r, Children[i]->Rect))\n\t\t\t\trects.Or(r); // add rectangle to update\n\t\t}\n\t\tChildren[to] = fromlay;\n\t}\n\telse\n\t{\n\t\t// backward\n\n\t\t// rotate\n\t\tfromlay = Children[from];\n\t\tfor(tjs_int i = from; i > to; i--)\n\t\t{\n\t\t\tChildren[i] = Children[i - 1];\n\t\t\ttTVPRect r = fromlay->Rect;\n\t\t\tif(TVPIntersectRect(&r, r, Children[i]->Rect))\n\t\t\t\trects.Or(r);\n\t\t}\n\t\tChildren[to] = fromlay;\n\t}\n\n\t// update\n\tUpdate(rects);\n\n\t// clear caches\n\tChildrenArrayValid = false;\n\tChildrenOrderIndexValid = false;\n\tif(Manager) Manager->InvalidateOverallIndex();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ChildChangeAbsoluteOrder(tjs_int from, tjs_int abs_to)\n{\n\t// find index order\n\ttjs_int to = 0;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tif(child->AbsoluteOrderIndex >= abs_to) break;\n\t\tto++;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\tif(from<to) to--;\n\n\tChildChangeOrder(from, to);\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::MoveBefore(tTJSNI_BaseLayer *lay)\n{\n\t// move before sibling : lay\n\t// lay must not be a null\n\tif(Parent) Parent->SetAbsoluteOrderMode(false);\n\n\tCheckZOrderMoveRule(lay);\n\n\ttjs_int this_order = GetOrderIndex();\n\ttjs_int lay_order = lay->GetOrderIndex();\n\n\tif(this_order < lay_order)\n\t\tParent->ChildChangeOrder(this_order, lay_order); // move forward\n\telse\n\t\tParent->ChildChangeOrder(this_order, lay_order + 1); // move backward\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::MoveBehind(tTJSNI_BaseLayer *lay)\n{\n\t// move behind sibling : lay\n\t// lay must not be a null\n\tif(Parent) Parent->SetAbsoluteOrderMode(false);\n\n\tCheckZOrderMoveRule(lay);\n\n\ttjs_int this_order = GetOrderIndex();\n\ttjs_int lay_order = lay->GetOrderIndex();\n\n\tif(this_order < lay_order)\n\t\tParent->ChildChangeOrder(this_order, lay_order - 1); // move forward\n\telse\n\t\tParent->ChildChangeOrder(this_order, lay_order); // move backward\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetOrderIndex(tjs_int index)\n{\n\t// change order index\n\tif(!Parent) TVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\n\tParent->SetAbsoluteOrderMode(false);\n\n\tif(index < 0) index = 0;\n\tif(index >= (tjs_int)Parent->Children.GetActualCount())\n\t\tindex = Parent->Children.GetActualCount()-1;\n\n\tParent->ChildChangeOrder(GetOrderIndex(), index);\n\tParent->NotifyChildrenVisualStateChanged();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::BringToBack()\n{\n\t// to most back position\n\tif(!Parent) TVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\n\tParent->SetAbsoluteOrderMode(false);\n\n\tSetOrderIndex(0);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::BringToFront()\n{\n\t// to most front position\n\tif(!Parent) TVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\n\tParent->SetAbsoluteOrderMode(false);\n\n\tSetOrderIndex(Parent->Children.GetActualCount() - 1);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetAbsoluteOrderIndex()\n{\n\t// retrieve order index in absolute position\n\tif(!Parent) return 0;\n\tif(Parent->AbsoluteOrderMode)\n\t\treturn AbsoluteOrderIndex;\n\treturn GetOrderIndex();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetAbsoluteOrderIndex(tjs_int index)\n{\n\tif(!Parent) TVPThrowExceptionMessage(TVPCannotMovePrimaryOrSiblingless);\n\n\tParent->SetAbsoluteOrderMode(true);\n\n\tParent->ChildChangeAbsoluteOrder(GetOrderIndex(), index);\n\n\tAbsoluteOrderIndex = index;\n\tParent->NotifyChildrenVisualStateChanged();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetAbsoluteOrderMode(bool b)\n{\n\t// set absolute order index mode\n\tif(AbsoluteOrderMode != b)\n\t{\n\t\tAbsoluteOrderMode = b;\n\t\tif(b)\n\t\t{\n\t\t\t// to absolute order mode\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\t\t\tchild->AbsoluteOrderIndex = child->GetOrderIndex();\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// to relative order mode\n\n\t\t\t// nothing to do\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DumpStructure(int level)\n{\n\ttjs_char *indent = new tjs_char[level*2+1];\n\ttry\n\t{\n\t\tfor(tjs_int i =0; i<level*2; i++) indent[i] = TJS_W(' ');\n\t\tindent[level*2] = 0;\n\n\t\tttstr name = Name;\n\t\tif(name.IsEmpty()) name = TJS_W(\"<noname>\");\n\t\ttjs_char ptr[80];\n\t\tTJS_snprintf(ptr, sizeof(ptr)/sizeof(tjs_char), TJS_W(\" (object 0x%p)\"), Owner);\n\t\ttjs_char ptr2[80];\n\t\tTJS_snprintf(ptr2, sizeof(ptr2)/sizeof(tjs_char), TJS_W(\" (native 0x%p)\"), this);\n\n\t\tTVPAddLog(ttstr(indent) + name +\n\t\t\tttstr(ptr) + ttstr(ptr2) +\n\t\t\tttstr(TJS_W(\" (\")) + ttstr(Rect.left) + ttstr(TJS_W(\",\")) +\n\t\t\tttstr(Rect.top) + ttstr(TJS_W(\")-(\")) + ttstr(Rect.right) +\n\t\t\tttstr(TJS_W(\",\")) + ttstr(Rect.bottom) + ttstr(TJS_W(\") (\")) +\n\t\t\tttstr(Rect.get_width()) + ttstr(TJS_W(\"x\"))+ ttstr(Rect.get_height()) +\n\t\t\tttstr(TJS_W(\")\")) + ttstr(TJS_W(\" \")) +\n\t\t\t\tttstr(GetVisible()?TJS_W(\"visible\"):TJS_W(\"invisible\")) +\n\t\t\t\tTJS_W(\" index=\") + ttstr(GetAbsoluteOrderIndex()) +\n\t\t\t\tttstr(ProvinceImage?TJS_W(\" p\"):TJS_W(\"\")) +\n\t\t\t\tTJS_W(\" \") + ttstr(GetTypeNameString()));\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] indent;\n\t\tthrow;\n\t}\n\n\tdelete [] indent;\n\n\tlevel++;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tchild->DumpStructure(level);\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// layer type management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::NotifyLayerTypeChange()\n{\n\tUpdateDrawFace();\n\n\tif(Parent) Parent->NotifyLayerTypeChange();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UpdateDrawFace()\n{\n\t// set DrawFace from Face and Type\n\tif(Face == dfAuto)\n\t{\n\t\t// DrawFace is chosen automatically from the layer type\n\t\tswitch(DisplayType)\n\t\t{\n\t//\tcase ltBinder:\n\t\tcase ltOpaque:\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltAlpha:\t\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltAdditive:\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltSubtractive:\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltMultiplicative:\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t//\tcase ltEffect:\n\t//\tcase ltFilter:\n\t\tcase ltDodge:\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltDarken:\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltLighten:\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltScreen:\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\tcase ltAddAlpha:\t\t\tDrawFace = dfAddAlpha;\t\t\tbreak;\n\t\tcase ltPsNormal:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsAdditive:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsSubtractive:\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsMultiplicative:\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsScreen:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsOverlay:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsHardLight:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsSoftLight:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsColorDodge:\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsColorDodge5:\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsColorBurn:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsLighten:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsDarken:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsDifference:\t \tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsDifference5:\t \tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tcase ltPsExclusion:\t\t\tDrawFace = dfAlpha;\t\t\t\tbreak;\n\t\tdefault:\n\t\t\t\t\t\t\tDrawFace = dfOpaque;\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\tDrawFace = Face;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPBlendOperationMode tTJSNI_BaseLayer::GetOperationModeFromType() const\n{\n\t// returns corresponding blend operation mode from layer type\n\n\tswitch(DisplayType)\n\t{\n//\tcase ltBinder:\n\tcase ltOpaque:\t\t\treturn omOpaque;\t\t\t \n\tcase ltAlpha:\t\t\treturn omAlpha;\n\tcase ltAdditive:\t\treturn omAdditive;\n\tcase ltSubtractive:\t\treturn omSubtractive;\n\tcase ltMultiplicative:\treturn omMultiplicative;\t \n//\tcase ltEffect:\n//\tcase ltFilter:\n\tcase ltDodge:\t\t\treturn omDodge;\n\tcase ltDarken:\t\t\treturn omDarken;\n\tcase ltLighten:\t\t\treturn omLighten;\n\tcase ltScreen:\t\t\treturn omScreen;\n\tcase ltAddAlpha:\t\treturn omAddAlpha;\n\tcase ltPsNormal:\t\treturn omPsNormal;\n\tcase ltPsAdditive:\t\treturn omPsAdditive;\n\tcase ltPsSubtractive:\treturn omPsSubtractive;\n\tcase ltPsMultiplicative:return omPsMultiplicative;\n\tcase ltPsScreen:\t\treturn omPsScreen;\n\tcase ltPsOverlay:\t\treturn omPsOverlay;\n\tcase ltPsHardLight:\t\treturn omPsHardLight;\n\tcase ltPsSoftLight:\t\treturn omPsSoftLight;\n\tcase ltPsColorDodge:\treturn omPsColorDodge;\n\tcase ltPsColorDodge5:\treturn omPsColorDodge5;\n\tcase ltPsColorBurn:\t\treturn omPsColorBurn;\n\tcase ltPsLighten:\t\treturn omPsLighten;\n\tcase ltPsDarken:\t\treturn omPsDarken;\n\tcase ltPsDifference:\treturn omPsDifference;\n\tcase ltPsDifference5:\treturn omPsDifference5;\n\tcase ltPsExclusion:\t\treturn omPsExclusion;\n\n\n\tdefault:\n\t\t\t\t\t\t\treturn omOpaque;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetType(tTVPLayerType type)\n{\n\t// set layer type to \"type\"\n\tif(Type != type)\n\t{\n\t\tType = type;\n\t\tswitch(Type)\n\t\t{\n\t\tcase ltBinder:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = false;\n\t\t\tDeallocateImage();\n\t\t\tbreak;\n\n\t\tcase ltOpaque: // formerly ltCoverRect\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltAlpha: // formerly ltTransparent\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltAdditive:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltSubtractive:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltMultiplicative:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltEffect:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = ltBinder;  // TODO: retrieve actual DrawType\n\t\t\tCanHaveImage = false;\n\t\t\tDeallocateImage();\n\t\t\tbreak;\n\n\t\tcase ltFilter:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = ltBinder;  // TODO: retrieve actual DisplayType\n\t\t\tCanHaveImage = false;\n\t\t\tDeallocateImage();\n\t\t\tbreak;\n\n\t\tcase ltDodge:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltDarken:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltLighten:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltScreen:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltAddAlpha:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsNormal:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsAdditive:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsSubtractive:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsMultiplicative:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsScreen:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsOverlay:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(128, 128, 128, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsHardLight:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(128, 128, 128, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsSoftLight:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(128, 128, 128, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsColorDodge:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsColorDodge5:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsColorBurn:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsLighten:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsDarken:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(255, 255, 255, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsDifference:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsDifference5:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\t\tcase ltPsExclusion:\n\t\t\tNeutralColor = TransparentColor = TVP_RGBA2COLOR(0, 0, 0, 0);\n\t\t\tDisplayType = Type;\n\t\t\tCanHaveImage = true;\n\t\t\tAllocateImage();\n\t\t\tbreak;\n\n\n\t\t}\n\t\tNotifyLayerTypeChange();\n\t\tSetToCreateExposedRegion();\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nconst tjs_char * tTJSNI_BaseLayer::GetTypeNameString()\n{\n\tswitch(Type)\n\t{\n\tcase ltBinder:\t\t\treturn TJS_W(\"ltBinder\");\n\tcase ltOpaque:\t\t\treturn TJS_W(\"ltOpaque\");\n\tcase ltAlpha:\t\t\treturn TJS_W(\"ltAlpha\");\n\tcase ltAdditive:\t\treturn TJS_W(\"ltAdditive\");\n\tcase ltSubtractive:\t\treturn TJS_W(\"ltSubtractive\");\n\tcase ltMultiplicative:\treturn TJS_W(\"ltMultiplicative\");\n\tcase ltEffect:\t\t\treturn TJS_W(\"ltEffect\");\n\tcase ltFilter:\t\t\treturn TJS_W(\"ltFilter\");\n\tcase ltDodge:\t\t\treturn TJS_W(\"ltDodge\");\n\tcase ltDarken:\t\t\treturn TJS_W(\"ltDarken\");\n\tcase ltLighten:\t\t\treturn TJS_W(\"ltLighten\");\n\tcase ltScreen:\t\t\treturn TJS_W(\"ltScreen\");\n\tcase ltAddAlpha:\t\treturn TJS_W(\"ltAddAlpha\");\n\tcase ltPsNormal:\t\treturn TJS_W(\"PsNormal\");\n\tcase ltPsAdditive:\t\treturn TJS_W(\"PsAdditive\");\n\tcase ltPsSubtractive:\treturn TJS_W(\"PsSubtractive\");\n\tcase ltPsMultiplicative:return TJS_W(\"PsMultiplicative\");\n\tcase ltPsScreen:\t\treturn TJS_W(\"PsScreen\");\n\tcase ltPsOverlay:\t\treturn TJS_W(\"PsOverlay\");\n\tcase ltPsHardLight:\t\treturn TJS_W(\"PsHardLight\");\n\tcase ltPsSoftLight:\t\treturn TJS_W(\"PsSoftLight\");\n\tcase ltPsColorDodge:\treturn TJS_W(\"PsColorDodge\");\n\tcase ltPsColorDodge5:\treturn TJS_W(\"PsColorDodge5\");\n\tcase ltPsColorBurn:\t\treturn TJS_W(\"PsColorBurn\");\n\tcase ltPsLighten:\t\treturn TJS_W(\"PsLighten\");\n\tcase ltPsDarken:\t\treturn TJS_W(\"PsDarken\");\n\tcase ltPsDifference:\treturn TJS_W(\"PsDifference\");\n\tcase ltPsDifference5:\treturn TJS_W(\"PsDifference5\");\n\tcase ltPsExclusion:\t\treturn TJS_W(\"PsExclusion\");\n\n\tdefault:\t\t\t\treturn TJS_W(\"unknown\");\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ConvertLayerType(tTVPDrawFace fromtype)\n{\n\t// convert layer pixel representation method\n\n\tif(DrawFace == dfAddAlpha && fromtype == dfAlpha)\n\t{\n\t\t// alpha -> additive alpha\n\t\tif(MainImage) MainImage->ConvertAlphaToAddAlpha();\n\t}\n\telse if(DrawFace == dfAlpha && fromtype == dfAddAlpha)\n\t{\n\t\t// additive alpha -> alpha\n\t\t// this may loose additive stuff\n\t\tif(MainImage) MainImage->ConvertAddAlphaToAlpha();\n\t}\n\telse\n\t{\n\t\t// throw an error\n\t\tTVPThrowExceptionMessage(TVPCannotConvertLayerTypeUsingGivenDirection);\n\t}\n\n\tImageModified = true;\n\n\tUpdate();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// geographical management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CreateExposedRegion()\n{\n\t// create exposed/overlapped region information\n\n\t// find region which is not piled by any children\n\tExposedRegion.Clear();\n\tOverlappedRegion.Clear();\n\n\ttTVPRect rect;\n\trect.left = rect.top = 0;\n\trect.right = Rect.get_width();\n\trect.bottom = Rect.get_height();\n\n\tif(MainImage != NULL)\n\t{\n\t\t// the layer has image\n\n\t\tif(GetVisibleChildrenCount() > TVP_EXPOSED_UNITE_LIMIT)\n\t\t{\n\t\t\tExposedRegion.Or(rect);\n\n\t\t\tbool first = true;\n\n\t\t\ttTVPRect r2;\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\n\t\t\t\tif(child->IsSeen())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(child->GetRect());\n\t\t\t\t\tif(TVPIntersectRect(&r, r, rect))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tr2 = child->GetRect();\n\t\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTVPUnionRect(&r2, r2, r);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\t\t\tOverlappedRegion.Or(r2);\n\n\t\t\tExposedRegion.Sub(OverlappedRegion);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttTVPRect rect;\n\t\t\trect.left = rect.top = 0;\n\t\t\trect.right = Rect.get_width();\n\t\t\trect.bottom = Rect.get_height();\n\t\t\tExposedRegion.Or(rect);\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\n\t\t\t\tif(child->IsSeen())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(child->GetRect());\n\t\t\t\t\tif(TVPIntersectRect(&r, r, rect))\n\t\t\t\t\t\tOverlappedRegion.Or(r);\n\t\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\t\t\tExposedRegion.Sub(OverlappedRegion);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// the layer has no image\n\t\t// ExposedRegion : child layer can directly transfer the image to the parent's target\n\t\t// OverlappedRegion : Inverse of ExposedRegion\n\n\t\tExposedRegion.Clear();\n\t\tOverlappedRegion.Clear();\n\t\tOverlappedRegion.Or(rect);\n\n\t\t// ExposedRegion is a region with is only one child layer piled\n\t\t// under the parent layer.\n\t\t// Recalculating this is pretty high-cost operation, \n\t\tif(GetVisibleChildrenCount() < TVP_DIRECT_UNITE_LIMIT)\n\t\t{\n\t\t\ttTVPComplexRect & one = ExposedRegion; // alias of ExposedRegion\n\t\t\ttTVPComplexRect   two; // region which is more than two layers piled\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\n\t\t\t\tif(child->IsSeen())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(child->GetRect());\n\t\t\t\t\tif(\n\t\t\t\t\t\tchild->DisplayType == this->DisplayType &&\n\t\t\t\t\t\tchild->Opacity == 255)\n\t\t\t\t\t{\n\t\t\t\t\t\ttTVPComplexRect one_and_r(one);\n\t\t\t\t\t\tone_and_r.And(r);\n\t\t\t\t\t\ttTVPComplexRect two_and_r(two);\n\t\t\t\t\t\ttwo_and_r.And(r);\n\t\t\t\t\t\tone.Sub(one_and_r);\n\t\t\t\t\t\ttwo.Or(one_and_r);\n\t\t\t\t\t\ttwo.Or(two_and_r);\n\t\t\t\t\t\ttTVPComplexRect tmp; tmp.Or(r);\n\t\t\t\t\t\ttmp.Sub(one_and_r);\n\t\t\t\t\t\ttmp.Sub(two_and_r);\n\t\t\t\t\t\tone.Or(tmp);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttwo.Or(r);\n\t\t\t\t\t\tone.Sub(r);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\t\t}\n\n\t\tOverlappedRegion.Sub(ExposedRegion);\n\t}\n\n\tExposedRegionValid = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalSetSize(tjs_uint width, tjs_uint height)\n{\n\tif(Rect.get_width() != (tjs_int)width ||\n\t\tRect.get_height() != (tjs_int)height)\n\t{\n\t\tUpdate(false);\n\t\tRect.set_width(width);\n\t\tRect.set_height(height);\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tSetToCreateExposedRegion();\n\t\tImageLayerSizeChanged();\n\t\tUpdate(false);\n\t\tif(IsPrimary() && Manager) Manager->NotifyLayerResize();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalSetBounds(const tTVPRect &rect)\n{\n\ttjs_int width = rect.right - rect.left;\n\ttjs_int height = rect.bottom - rect.top;\n\tif(width < 0 || height < 0) TVPThrowExceptionMessage(TVPInvalidParam);\n\n\tif(Rect.left != rect.left || Rect.top != rect.top)\n\t{\n\t\tbool visible = GetVisible() || GetNodeVisible();\n\t\tif(IsPrimary() && (rect.left != 0 || rect.top != 0))\n\t\t\tTVPThrowExceptionMessage(TVPCannotMovePrimary);\n\n\t\tif(visible) ParentUpdate();\n\t\tRect.set_offsets(rect.left, rect.top);\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tSetToCreateExposedRegion();\n\t\tif(visible) ParentUpdate();\n\t}\n\n\tInternalSetSize(width, height);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetLeft(tjs_int left)\n{\n\tif(Rect.left != left)\n\t{\n\t\tbool visible = GetVisible() || GetNodeVisible();\n\t\tif(IsPrimary() && left != 0)\n\t\t\tTVPThrowExceptionMessage(TVPCannotMovePrimary);\n\t\tif(visible) ParentUpdate();\n\t\ttjs_int w;\n\t\tw = Rect.get_width();\n\t\tRect.left = left;\n\t\tRect.right = w + Rect.left;\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\t// TODO: SetLeft\n\t\tif(visible) ParentUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetTop(tjs_int top)\n{\n\tif(Rect.top != top)\n\t{\n\t\tbool visible = GetVisible() || GetNodeVisible();\n\t\tif(IsPrimary() && top != 0)\n\t\t\tTVPThrowExceptionMessage(TVPCannotMovePrimary);\n\t\tif(visible) ParentUpdate();\n\t\ttjs_int h;\n\t\th = Rect.get_height();\n\t\tRect.top = top;\n\t\tRect.bottom = h + Rect.top;\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\t// TODO: SetTop;\n\t\tif(visible) ParentUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetPosition(tjs_int left, tjs_int top)\n{\n\tif(Rect.left != left || Rect.top != top)\n\t{\n\t\tbool visible = GetVisible() || GetNodeVisible();\n\t\tif(IsPrimary() && (left != 0 || top != 0))\n\t\t\tTVPThrowExceptionMessage(TVPCannotMovePrimary);\n\t\tif(visible) ParentUpdate();\n\t\tRect.set_offsets(left, top);\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\t// TODO: SetPosition\n\t\tif(visible) ParentUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetWidth(tjs_uint width)\n{\n\tif(Rect.get_width() != (tjs_int)width)\n\t{\n\t\tUpdate(false);\n\t\tRect.set_width(width);\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tSetToCreateExposedRegion();\n\t\tImageLayerSizeChanged();\n\t\tUpdate(false);\n\t\tif(IsPrimary() && Manager) Manager->NotifyLayerResize();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetHeight(tjs_uint height)\n{\n\tif(Rect.get_height() != (tjs_int)height)\n\t{\n\t\tUpdate(false);\n\t\tRect.set_height(height);\n\t\tif(Parent) Parent->NotifyChildrenVisualStateChanged();\n\t\tSetToCreateExposedRegion();\n\t\tImageLayerSizeChanged();\n\t\tUpdate(false);\n\t\tif(IsPrimary() && Manager) Manager->NotifyLayerResize();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetSize(tjs_uint width, tjs_uint height)\n{\n\tInternalSetSize(width, height);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetBounds(const tTVPRect &rect)\n{\n\t// TODO: SetBounds\n\tInternalSetBounds(rect);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ParentRectToChildRect(tTVPRect &rect)\n{\n\t// note that this function does not convert transformed layer coordinates.\n\trect.left -= Rect.left;\n\trect.right -= Rect.left;\n\trect.top -= Rect.top;\n\trect.bottom -= Rect.top;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ToPrimaryCoordinates(tjs_int &x, tjs_int &y) const\n{\n\tconst tTJSNI_BaseLayer *l = this;\n\n\twhile(l && !l->IsPrimary())\n\t{\n\t\tx += l->Rect.left; y += l->Rect.top;\n\t\tl = l->Parent;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FromPrimaryCoordinates(tjs_int &x, tjs_int &y) const\n{\n\tconst tTJSNI_BaseLayer *l = this;\n\n\twhile(l && !l->IsPrimary())\n\t{\n\t\tx -= l->Rect.left; y -= l->Rect.top;\n\t\tl = l->Parent;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FromPrimaryCoordinates(tjs_real &x, tjs_real &y) const\n{\n\tconst tTJSNI_BaseLayer *l = this;\n\n\twhile(l && !l->IsPrimary())\n\t{\n\t\tx -= (tjs_real)l->Rect.left; y -= (tjs_real)l->Rect.top;\n\t\tl = l->Parent;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// image buffer management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ChangeImageSize(tjs_uint width, tjs_uint height)\n{\n\t// be called from geographical management\n\tif(!width || !height)\n\t\tTVPThrowExceptionMessage(TVPCannotCreateEmptyLayerImage);\n\n\tif(MainImage) MainImage->SetSizeWithFill(width, height, NeutralColor);\n\tif(ProvinceImage) ProvinceImage->SetSizeWithFill(width, height, 0);\n\n\tif(MainImage) ResetClip();  // cliprect is reset\n\n\tImageModified = true;\n\n\tResizeCache(); // in cache management\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AllocateImage()\n{\n\tif(!MainImage)\n\t{\n\t\tImageLeft = 0;\n\t\tImageTop = 0;\n        MainImage = new tTVPBaseTexture(Rect.get_width(), Rect.get_height());\n\t\tMainImage->Fill(tTVPRect(0, 0, Rect.get_width(), Rect.get_height()), NeutralColor);\n\t\tMainImage->SetFont(Font); // set font\n\t}\n\n\tif(MainImage) ResetClip();  // cliprect is reset\n\n\tif(ProvinceImage)\n\t{\n\t\tProvinceImage->SetSizeWithFill(MainImage->GetWidth(),\n\t\t\tMainImage->GetHeight(), 0);\n\t}\n\n\tFontChanged = true; // invalidate font assignment cache\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DeallocateImage()\n{\n\tif(MainImage) delete MainImage, MainImage = NULL;\n\tif(ProvinceImage) delete ProvinceImage, ProvinceImage = NULL;\n\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AllocateProvinceImage()\n{\n\ttjs_uint neww = MainImage?MainImage->GetWidth():Rect.get_width();\n\ttjs_uint newh = MainImage?MainImage->GetHeight():Rect.get_height();\n\n\tif(!ProvinceImage)\n\t{\n\t\tProvinceImage = new tTVPBaseBitmap(neww, newh, 8);\n\t\tProvinceImage->Fill(tTVPRect(0, 0, neww, newh), 0);\n\t}\n\telse\n\t{\n\t\tProvinceImage->SetSizeWithFill(neww, newh, 0);\n\t}\n\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DeallocateProvinceImage()\n{\n\tif(ProvinceImage) delete ProvinceImage, ProvinceImage = NULL;\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AllocateDefaultImage()\n{\n\tif(!MainImage)\n\t\tMainImage = new tTVPBaseTexture(*TVPTempBitmapHolder->Get());\n\telse\n\t\tMainImage->Assign(*TVPTempBitmapHolder->Get());\n\n\tFontChanged = true; // invalidate font assignment cache\n\tResetClip();  // cliprect is reset\n\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AssignImages(tTJSNI_BaseLayer *src)\n{\n\t// assign images\n\tbool main_changed = true;\n\n\tif(src->MainImage)\n\t{\n\t\tif(MainImage)\n\t\t\tmain_changed = MainImage->Assign(* src->MainImage);\n\t\telse\n\t\t\tMainImage = new tTVPBaseTexture(* src->MainImage);\n\t\tFontChanged = true; // invalidate font assignment cache\n\t}\n\telse\n\t{\n\t\tDeallocateImage();\n\t}\n\n\tif(src->ProvinceImage)\n\t{\n\t\tif(ProvinceImage)\n\t\t\tProvinceImage->Assign(* src->ProvinceImage);\n\t\telse\n\t\t\tProvinceImage = new tTVPBaseBitmap(* src->ProvinceImage);\n\t}\n\telse\n\t{\n\t\tDeallocateProvinceImage();\n\t}\n\n\tif(main_changed && MainImage)\n\t{\n\t\tInternalSetImageSize(MainImage->GetWidth(), MainImage->GetHeight());\n\t\t\t// adjust position\n\t}\n\n\tImageModified = true;\n\n\tif(MainImage) ResetClip();  // cliprect is reset\n\n\tif(main_changed) Update(false); // update\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AssignMainImageWithUpdate(iTVPBaseBitmap *bmp)\n{\n\t// assign images\n\tbool main_changed = true;\n\n\tif(bmp)\n\t{\n\t\tif(MainImage)\n\t\t\tmain_changed = MainImage->Assign(*bmp);\n\t\telse\n\t\t\tMainImage = new tTVPBaseTexture(*bmp);\n\t\tFontChanged = true; // invalidate font assignment cache\n\t}\n\telse\n\t{\n\t\tDeallocateImage();\n\t}\n\n\tif(main_changed && MainImage)\n\t{\n\t\tInternalSetImageSize(MainImage->GetWidth(), MainImage->GetHeight());\n\t\t\t// adjust position\n\t}\n\n\tImageModified = true;\n\n\tif(MainImage) ResetClip();  // cliprect is reset\n\n\tif(main_changed) Update(false); // update\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AssignMainImage(iTVPBaseBitmap *bmp)\n{\n\t// assign single main bitmap image. the image size assigned must be\n\t// identical to the destination layer bitmap.\n\t// destination bitmap must have a layer bitmap\n\n\tif(!MainImage ||\n\t\tbmp->GetWidth() != MainImage->GetWidth() ||\n\t\tbmp->GetHeight() != MainImage->GetHeight() )\n\t{\n\t\t// destination layer does not have a main image or\n\t\t// the size is not identical to the source layer bitmap\n\t\tTVPThrowInternalError;\n\t}\n\n\tbool main_changed = MainImage->Assign(*bmp);\n\n\tif(main_changed)\n\t{\n\t\tImageModified = true;\n\t\tUpdate(false); // update\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CopyFromMainImage( tTJSNI_Bitmap* bmp )\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tbmp->CopyFrom( MainImage );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetHasImage(bool b)\n{\n\tif(!CanHaveImage && b)\n\t\tTVPThrowExceptionMessage(TVPLayerCannotHaveImage);\n\tif(b) AllocateImage(); else DeallocateImage();\n\tNotifyChildrenVisualStateChanged();\n\tUpdate();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetHasImage() const\n{\n\treturn MainImage != NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImageLeft(tjs_int left)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(ImageLeft != left)\n\t{\n\t\tif(left > 0) TVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tif((tjs_int)(MainImage->GetWidth()) + left < Rect.get_width())\n\t\t\tTVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tImageLeft = left;\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetImageLeft() const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn ImageLeft;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImageTop(tjs_int top)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(ImageTop != top)\n\t{\n\t\tif(top > 0) TVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tif((tjs_int)(MainImage->GetHeight()) + top < Rect.get_height())\n\t\t\tTVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tImageTop = top;\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetImageTop() const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn ImageTop;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImagePosition(tjs_int left, tjs_int top)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(ImageLeft != left || ImageTop != top)\n\t{\n\t\tif(left > 0) TVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tif(top > 0) TVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tif((tjs_int)(MainImage->GetWidth()) + left < Rect.get_width())\n\t\t\tTVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tif((tjs_int)(MainImage->GetHeight()) + top < Rect.get_height())\n\t\t\tTVPThrowExceptionMessage(TVPInvalidImagePosition);\n\t\tImageLeft = left;\n\t\tImageTop = top;\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImageWidth(tjs_uint width)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(width == MainImage->GetWidth()) return;\n\n\t// adjust position\n\tif((tjs_int)width < Rect.get_width())\n\t{\n\t\tImageLeft = 0;\n\t\tSetWidth(width); // change layer size\n\t}\n\n\tif((tjs_int)(width) + ImageLeft < Rect.get_width())\n\t{\n\t\tImageLeft = Rect.get_width() - width;\n\t}\n\n\t// change image size...\n\tChangeImageSize(width, MainImage->GetHeight());\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_BaseLayer::GetImageWidth() const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn MainImage->GetWidth();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImageHeight(tjs_uint height)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(height == MainImage->GetHeight()) return;\n\n\t// adjust position\n\tif((tjs_int)height < Rect.get_height())\n\t{\n\t\tImageTop = 0;\n\t\tSetHeight(height); // change layer size\n\t}\n\n\tif((tjs_int)(height + ImageTop) < Rect.get_height())\n\t{\n\t\tImageTop = Rect.get_height() - height;\n\t}\n\n\t// change image size...\n\tChangeImageSize(MainImage->GetWidth(), height);\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_BaseLayer::GetImageHeight() const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\treturn MainImage->GetHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalSetImageSize(tjs_uint width, tjs_uint height)\n{\n\t// adjust position\n\tif((tjs_int)width < Rect.get_width())\n\t{\n\t\tImageLeft = 0;\n\t\tSetWidth(width); // change layer size\n\t}\n\tif((tjs_int)(width + ImageLeft) < Rect.get_width())\n\t{\n\t\tImageLeft = Rect.get_width() - width;\n\t}\n\n\tif((tjs_int)height < Rect.get_height())\n\t{\n\t\tImageTop = 0;\n\t\tSetHeight(height); // change layer size\n\t}\n\tif((tjs_int)(height + ImageTop) < Rect.get_height())\n\t{\n\t\tImageTop = Rect.get_height() - height;\n\t}\n\n\tChangeImageSize(width, height);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImageSize(tjs_uint width, tjs_uint height)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(width == MainImage->GetWidth() && height == MainImage->GetHeight()) return;\n\n\tInternalSetImageSize(width, height);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ImageLayerSizeChanged()\n{\n\t// called from geographical management\n\tif(!MainImage) return;\n\n\tif((tjs_int)MainImage->GetWidth() < Rect.get_width())\n\t{\n\t\tChangeImageSize(Rect.get_width(), MainImage->GetHeight());\n\t}\n\tif((tjs_int)(MainImage->GetWidth() + ImageLeft) < Rect.get_width())\n\t{\n\t\tImageLeft = Rect.get_width() - MainImage->GetWidth();\n\t\tUpdate();\n\t}\n\n\tif((tjs_int)MainImage->GetHeight() < Rect.get_height())\n\t{\n\t\tChangeImageSize(MainImage->GetWidth(), Rect.get_height());\n\t}\n\tif((tjs_int)(MainImage->GetHeight() + ImageTop) < Rect.get_height())\n\t{\n\t\tImageTop = Rect.get_height() - MainImage->GetHeight();\n\t\tUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::IndependMainImage(bool copy)\n{\n\tif(MainImage)\n\t{\n\t\tif(copy)\n\t\t\tMainImage->Independ();\n\t\telse\n\t\t\tMainImage->IndependNoCopy();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::IndependProvinceImage(bool copy)\n{\n\tif(ProvinceImage)\n\t{\n\t\tif(copy)\n\t\t\tProvinceImage->Independ();\n\t\telse\n\t\t\tProvinceImage->IndependNoCopy();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SaveLayerImage(const ttstr &name, const ttstr &type)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\n\tiTJSDispatch2 *dic = TJSCreateDictionaryObject();\n\ttry {\n\t\ttTJSVariant val;\n\t\tswitch(Type) {\n\t\tcase ltOpaque:\t\t\t\tval = tTJSVariant(TJS_W(\"opaque\"));\t\tbreak;\n\t\tcase ltAlpha:\t\t\t\tval = tTJSVariant(TJS_W(\"alpha\"));\t\tbreak;\n\t\tcase ltAdditive:\t\t\tval = tTJSVariant(TJS_W(\"add\"));\t\tbreak;\n\t\tcase ltSubtractive:\t\t\tval = tTJSVariant(TJS_W(\"sub\"));\t\tbreak;\n\t\tcase ltMultiplicative:\t\tval = tTJSVariant(TJS_W(\"mul\"));\t\tbreak;\n\t\tcase ltDodge:\t\t\t\tval = tTJSVariant(TJS_W(\"dodge\"));\t\tbreak;\n\t\tcase ltDarken:\t\t\t\tval = tTJSVariant(TJS_W(\"darken\"));\t\tbreak;\n\t\tcase ltLighten:\t\t\t\tval = tTJSVariant(TJS_W(\"lighten\"));\tbreak;\n\t\tcase ltScreen:\t\t\t\tval = tTJSVariant(TJS_W(\"screen\"));\t\tbreak;\n\t\tcase ltAddAlpha:\t\t\tval = tTJSVariant(TJS_W(\"addalpha\"));\tbreak;\n\t\tcase ltPsNormal:\t\t\tval = tTJSVariant(TJS_W(\"psnormal\"));\tbreak;\n\t\tcase ltPsAdditive:\t\t\tval = tTJSVariant(TJS_W(\"psadd\"));\t\tbreak;\n\t\tcase ltPsSubtractive:\t\tval = tTJSVariant(TJS_W(\"pssub\"));\t\tbreak;\n\t\tcase ltPsMultiplicative:\tval = tTJSVariant(TJS_W(\"psmul\"));\t\tbreak;\n\t\tcase ltPsScreen:\t\t\tval = tTJSVariant(TJS_W(\"psscreen\"));\tbreak;\n\t\tcase ltPsOverlay:\t\t\tval = tTJSVariant(TJS_W(\"psoverlay\"));\tbreak;\n\t\tcase ltPsHardLight:\t\t\tval = tTJSVariant(TJS_W(\"pshlight\"));\tbreak;\n\t\tcase ltPsSoftLight:\t\t\tval = tTJSVariant(TJS_W(\"psslight\"));\tbreak;\n\t\tcase ltPsColorDodge:\t\tval = tTJSVariant(TJS_W(\"psdodge\"));\tbreak;\n\t\tcase ltPsColorDodge5:\t\tval = tTJSVariant(TJS_W(\"psdodge5\"));\tbreak;\n\t\tcase ltPsColorBurn:\t\t\tval = tTJSVariant(TJS_W(\"psburn\"));\t\tbreak;\n\t\tcase ltPsLighten:\t\t\tval = tTJSVariant(TJS_W(\"pslighten\"));\tbreak;\n\t\tcase ltPsDarken:\t\t\tval = tTJSVariant(TJS_W(\"psdarken\"));\tbreak;\n\t\tcase ltPsDifference:\t \tval = tTJSVariant(TJS_W(\"psdiff\"));\t\tbreak;\n\t\tcase ltPsDifference5:\t \tval = tTJSVariant(TJS_W(\"psdiff5\"));\tbreak;\n\t\tcase ltPsExclusion:\t\t\tval = tTJSVariant(TJS_W(\"psexcl\"));\t\tbreak;\n\t\tdefault:\t\t\t\t\tval = tTJSVariant(TJS_W(\"opaque\"));\t\tbreak;\n\t\t}\n\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"mode\"), 0, &val, dic );\n\n\t\tif( ImageLeft > 0 ) {\n\t\t\tval = tTJSVariant(ImageLeft);\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"offs_x\"), 0, &val, dic );\n\t\t}\n\t\tif( ImageTop > 0 ) {\n\t\t\tval = tTJSVariant(ImageTop);\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"offs_y\"), 0, &val, dic );\n\t\t}\n\t\tif( ImageLeft > 0 || ImageTop > 0 ) {\n\t\t\tval = tTJSVariant(TJS_W(\"pixel\"));\n\t\t\tdic->PropSet(TJS_MEMBERENSURE, TJS_W(\"offs_unit\"), 0, &val, dic );\n\t\t}\n\t\tTVPSaveImage( name, type, MainImage, dic );\n\t} catch(...) {\n\t\tdic->Release();\n\t\tthrow;\n\t}\n\tdic->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AssignTexture(iTVPTexture2D *tex)\n{\n\tif (!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tMainImage->AssignTexture(tex);\n\tInternalSetImageSize(MainImage->GetWidth(), MainImage->GetHeight());\n\tImageModified = true;\n\tResetClip();  // cliprect is reset\n\tUpdate(false);\n}\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseLayer::LoadImages(const ttstr &name, tjs_uint32 colorkey)\n{\n\t// loads image(s) from specified storage.\n\t// colorkey must be a color that should be transparent, or:\n\t// 0x 01 ff ff ff (clAdapt) : the color key will be automatically chosen from\n\t//                            target image, by selecting most used color from\n\t//                            the top line of the image.\n\t// 0x 1f ff ff ff (clNone)  : does not apply the colorkey, or uses image alpha\n\t//                            channel.\n\t// 0x30000000 (clPalIdx) + nn ( nn = palette index )\n\t//                          : select the color key by specified palette index.\n\t// 0x40000000 (TVP_clAlphaMat) + 0xRRGGBB ( 0xRRGGBB = matting color )\n\t//                          : do matting with the color using alpha blending.\n\t// returns graphic image metainfo.\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tttstr provincename;\n\tiTJSDispatch2 * metainfo = NULL;\n\n\tTVPLoadGraphic(MainImage, name, colorkey, 0, 0, glmNormal, &provincename, &metainfo);\n\ttry\n\t{\n\n\t\tInternalSetImageSize(MainImage->GetWidth(), MainImage->GetHeight());\n\n\t\tif(!provincename.IsEmpty())\n\t\t{\n\t\t\t// province image exists\n\t\t\tAllocateProvinceImage();\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tTVPLoadGraphicProvince(ProvinceImage, provincename, 0,\n\t\t\t\t\tMainImage->GetWidth(), MainImage->GetHeight());\n\n\t\t\t\tif(ProvinceImage->GetWidth() != MainImage->GetWidth() ||\n\t\t\t\t\tProvinceImage->GetHeight() != MainImage->GetHeight())\n\t\t\t\t\tTVPThrowExceptionMessage(TVPProvinceSizeMismatch, provincename);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tDeallocateProvinceImage();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// province image does not exist\n\t\t\tDeallocateProvinceImage();\n\t\t}\n\n\t\tImageModified = true;\n\n\t\tResetClip();  // cliprect is reset\n\n\t\tUpdate(false);\n\t}\n\tcatch(...)\n\t{\n\t\tif(metainfo) metainfo->Release();\n\t\tthrow;\n\t}\n\n\treturn metainfo;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::LoadProvinceImage(const ttstr &name)\n{\n\t// load an image as a province image\n\t\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tAllocateProvinceImage();\n\n\ttry\n\t{\n\t\tTVPLoadGraphicProvince(ProvinceImage, name, 0,\n\t\t\tMainImage->GetWidth(), MainImage->GetHeight());\n\n\t\tif(ProvinceImage->GetWidth() != MainImage->GetWidth() ||\n\t\t\tProvinceImage->GetHeight() != MainImage->GetHeight())\n\t\t\tTVPThrowExceptionMessage(TVPProvinceSizeMismatch, name);\n\t}\n\tcatch(...)\n\t{\n\t\tDeallocateProvinceImage();\n\t\tthrow;\n\t}\n\n\tImageModified = true;\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNI_BaseLayer::GetMainPixel(tjs_int x, tjs_int y) const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\treturn TVPFromActualColor(MainImage->GetPoint(x, y) & 0xffffff);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetMainPixel(tjs_int x, tjs_int y, tjs_uint32 color)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(x < ClipRect.left || y < ClipRect.top ||\n\t\tx >= ClipRect.right || y >= ClipRect.bottom) return; // out of clipping rectangle\n\n\tMainImage->SetPointMain(x, y, TVPToActualColor(color));\n\n\tImageModified = true;\n\ttTVPRect r;\n\tr.left = ImageLeft + x;\n\tr.top = ImageTop + y;\n\tr.right = r.left + 1;\n\tr.bottom = r.top + 1;\n\tUpdate(r);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetMaskPixel(tjs_int x, tjs_int y) const\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\treturn (MainImage->GetPoint(x, y) & 0xff000000) >> 24;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetMaskPixel(tjs_int x, tjs_int y, tjs_int mask)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(x < ClipRect.left || y < ClipRect.top ||\n\t\tx >= ClipRect.right || y >= ClipRect.bottom) return; // out of clipping rectangle\n\n\tMainImage->SetPointMask(x, y, mask);\n\n\tImageModified = true;\n\ttTVPRect r;\n\tr.left = ImageLeft + x;\n\tr.top = ImageTop + y;\n\tr.right = r.left + 1;\n\tr.bottom = r.top + 1;\n\tUpdate(r);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetProvincePixel(tjs_int x, tjs_int y) const\n{\n\tif(!ProvinceImage) return 0;\n\n\tif(x < 0 || y < 0 || x >= (tjs_int)ProvinceImage->GetWidth() ||\n\t\ty >= (tjs_int)ProvinceImage->GetHeight()) return 0;\n\n\treturn ProvinceImage->GetPoint(x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetProvincePixel(tjs_int x, tjs_int y, tjs_int n)\n{\n\tif(!ProvinceImage) AllocateProvinceImage();\n\n\tif(x < ClipRect.left || y < ClipRect.top ||\n\t\tx >= ClipRect.right || y >= ClipRect.bottom) return; // out of clipping rectangle\n\n\tProvinceImage->SetPoint(x, y, n);\n\n\tImageModified = true;\n\ttTVPRect r;\n\tr.left = ImageLeft + x;\n\tr.top = ImageTop + y;\n\tr.right = r.left + 1;\n\tr.bottom = r.top + 1;\n\tUpdate(r);\n}\n//---------------------------------------------------------------------------\nconst void * tTJSNI_BaseLayer::GetMainImagePixelBuffer() const\n{\n\tif(!MainImage) return NULL;\n\treturn MainImage->GetScanLine(0);\n}\n//---------------------------------------------------------------------------\nvoid * tTJSNI_BaseLayer::GetMainImagePixelBufferForWrite()\n{\n\tif(!MainImage) return NULL;\n\tImageModified = true;\n\treturn MainImage->GetScanLineForWrite(0);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetMainImagePixelBufferPitch() const\n{\n\tif(!MainImage) return 0;\n\treturn MainImage->GetPitchBytes();\n}\n//---------------------------------------------------------------------------\nconst void * tTJSNI_BaseLayer::GetProvinceImagePixelBuffer() const\n{\n\tif(!ProvinceImage) return NULL;\n\treturn ProvinceImage->GetScanLine(0);\n}\n//---------------------------------------------------------------------------\nvoid * tTJSNI_BaseLayer::GetProvinceImagePixelBufferForWrite()\n{\n\tif(!ProvinceImage) AllocateProvinceImage();\n\tImageModified = true;\n\treturn ProvinceImage->GetScanLineForWrite(0);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetProvinceImagePixelBufferPitch() const\n{\n\tif(!ProvinceImage) return 0;\n\treturn ProvinceImage->GetPitchBytes();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// input event / hit test management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCursorByStorage(const ttstr &storage)\n{\n\tCursor = TVPGetCursor(storage);\n\tif(Manager) Manager->NotifyMouseCursorChange(this, GetLayerActiveCursor());\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCursorByNumber(tjs_int num)\n{\n\tCursor = num;\n\tif(Manager) Manager->NotifyMouseCursorChange(this, GetLayerActiveCursor());\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetLayerActiveCursor()\n{\n\t// return layer's actual (active) mouse cursor\n\ttjs_int cursor = Cursor;\n\ttTJSNI_BaseLayer *p = this;\n\twhile(cursor == 0) // while cursor is 0 ( crDefault ) .. look up parent layer\n\t{\n\t\tp = p->Parent;\n\t\tif(!p) break;\n\t\tcursor = p->Cursor;\n\t}\n\treturn cursor;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCurrentCursorToWindow(void)\n{\n\t// set current layer cusor to the window\n\tif(Manager)\n\t{\n\t\tManager->SetMouseCursor(GetLayerActiveCursor());\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetCursorX()\n{\n\ttjs_int x, y;\n\tif(!Manager) return 0;\n\tManager->GetCursorPos(x, y);\n\n\ttTJSNI_BaseLayer *p = this;\n\twhile(p)\n\t{\n\t\tif(!p->Parent) break;\n\t\tx -= p->Rect.left;\n\t\tp = p->Parent;\n\t}\n\n\treturn x;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCursorX(tjs_int x)\n{\n\tCursorX_Work = x; // once store to this variable;\n\t// cursor moves on call to SetCursorY\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetCursorY()\n{\n\ttjs_int x, y;\n\tif(!Manager) return 0;\n\tManager->GetCursorPos(x, y);\n\n\ttTJSNI_BaseLayer *p = this;\n\twhile(p)\n\t{\n\t\tif(!p->Parent) break;\n\t\ty -= p->Rect.top;\n\t\tp = p->Parent;\n\t}\n\n\treturn y;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCursorY(tjs_int y)\n{\n\tif(!Manager) return;\n\n\ttjs_int x = CursorX_Work;\n\ttTJSNI_BaseLayer *p = this;\n\twhile(p)\n\t{\n\t\tif(!p->Parent) break;\n\t\tx += p->Rect.left;\n\t\ty += p->Rect.top;\n\t\tp = p->Parent;\n\t}\n\n\tManager->SetCursorPos(x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCursorPos(tjs_int x, tjs_int y)\n{\n\tif(!Manager) return;\n\n\ttTJSNI_BaseLayer *p = this;\n\twhile(p)\n\t{\n\t\tif(!p->Parent) break;\n\t\tx += p->Rect.left;\n\t\ty += p->Rect.top;\n\t\tp = p->Parent;\n\t}\n\n\tManager->SetCursorPos(x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCurrentHintToWindow()\n{\n\t// set current hint to the window\n\tif( IgnoreHintSensing ) return;\n\tif(Manager)\n\t{\n\t\ttTJSNI_BaseLayer *p = this;\n\t\twhile(p->ShowParentHint)\n\t\t{\n\t\t\tif(!p->Parent) break;\n\t\t\tp = p->Parent;\n\t\t}\n\n\t\tManager->SetHint( GetOwnerNoAddRef(), p->Hint);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetHint(const ttstr & hint)\n{\n\tShowParentHint = false;\n\tIgnoreHintSensing = false;\n\tHint = hint;\n\tif(Manager)\n\t\tManager->NotifyHintChange(this, hint);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetAttentionLeft(tjs_int l)\n{\n\tAttentionLeft = l;\n\tif(Manager) Manager->NotifyAttentionStateChanged(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetAttentionTop(tjs_int t)\n{\n\tAttentionTop = t;\n\tif(Manager) Manager->NotifyAttentionStateChanged(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetAttentionPoint(tjs_int l, tjs_int t)\n{\n\tAttentionLeft = l;\n\tAttentionTop = t;\n\tif(Manager) Manager->NotifyAttentionStateChanged(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetUseAttention(bool b)\n{\n\tUseAttention = b;\n\tif(Manager) Manager->NotifyAttentionStateChanged(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetImeMode(tTVPImeMode mode)\n{\n\tImeMode = mode;\n\tif(Manager) Manager->NotifyImeModeChanged(this);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::_HitTestNoVisibleCheck(tjs_int x, tjs_int y)\n{\n\t// do hit test.\n\t// this function does not check layer's visiblity\n\n\tif(HitType == htMask)\n\t{\n\t\t// use mask\n\t\tif(MainImage)\n\t\t{\n\t\t\ttjs_int px = x-ImageLeft, py = y-ImageTop;\n\t\t\tif(px >= 0 && py >= 0 && px < (tjs_int)MainImage->GetWidth() &&\n\t\t\t\tpy < (tjs_int)MainImage->GetHeight())\n\t\t\t{\n                if (HitThreshold <= 0) return true;\n\t\t\t\t\n\t\t\t\ttjs_uint32 cl = MainImage->GetPoint(px, py);\n\t\t\t\tif((tjs_int)(cl >> 24) < HitThreshold)\n\t\t\t\t\treturn false;\n\t\t\t\telse\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// layer has no image\n\t\t\t// all pixels are treated as 0 alpha value\n\t\t\tif(x >= 0 && y >= 0 && x < Rect.get_width() && y < Rect.get_height())\n\t\t\t{\n\t\t\t\tif(0 < HitThreshold) return false; else return true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\telse if(HitType == htProvince)\n\t{\n\t\t// use province\n\n\t\tif(ProvinceImage)\n\t\t{\n\t\t\ttjs_int px = x-ImageLeft, py = y-ImageTop;\n\t\t\tif(px >= 0 && py >= 0 && px < (tjs_int)ProvinceImage->GetWidth() &&\n\t\t\t\tpy < (tjs_int)ProvinceImage->GetHeight())\n\t\t\t{\n\t\t\t\ttjs_uint32 cl = ProvinceImage->GetPoint(px, py);\n\t\t\t\tif(cl == 0) return false; else return true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::HitTestNoVisibleCheck(tjs_int x, tjs_int y)\n{\n\tbool res = _HitTestNoVisibleCheck(x, y);\n\n\tif(res)\n\t{\n\t\t// call onHitTest to perform additional hittest\n\t\tif(Owner && !Shutdown)\n\t\t{\n\t\t\tOnHitTest_Work = true;\n\n\t\t\ttTJSVariant param[3];\n\t\t\tparam[0] = x;\n\t\t\tparam[1] = y;\n\t\t\tparam[2] = true;\n\t\t\tstatic ttstr eventname(TJS_W(\"onHitTest\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 3, param);\n\n\t\t\tres = OnHitTest_Work;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn res;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetMostFrontChildAt(tjs_int x, tjs_int y, tTJSNI_BaseLayer **lay,\n\tconst tTJSNI_BaseLayer *except, bool get_disabled)\n{\n\t// internal function\n\n\t// visible check\n\tif(!Visible) return false; // cannot hit invisible layer\n\n\t// convert coordinates ( the point is given by parent's coordinates )\n\tx -= Rect.left; y -= Rect.top;\n\n\t// rectangle test\n\tif(x < 0 || y < 0 || x >= Rect.get_width() || y >= Rect.get_height())\n\t\treturn false; // out of the rectangle\n\n\ttjs_int ox = x, oy = y;\n\n\t{ // locked\n\t\ttObjectListSafeLockHolder<tTJSNI_BaseLayer> holder(Children);\n\t\ttjs_int i = Children.GetSafeLockedObjectCount() - 1;\n\t\tfor(; i>=0; i--)\n\t\t{\n\t\t\ttTJSNI_BaseLayer * child = Children.GetSafeLockedObjectAt(i);\n\t\t\tif(!child) continue;\n\t\t\tbool b = child->GetMostFrontChildAt(x, y, lay, except, get_disabled);\n\t\t\tif(b) return true;\n\t\t}\n\t} // end locked\n\n\tif(except == this) return false; // exclusion\n\n\tif(HitTestNoVisibleCheck(ox, oy))\n\t{\n\t\tif(!get_disabled && (!GetNodeEnabled() || IsDisabledByMode()))\n\t\t{\n\t\t\t*lay = NULL;\n\t\t\treturn true; // cannot hit disabled or under modal layer\n\t\t}\n\t\t*lay = this;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTJSNI_BaseLayer::GetMostFrontChildAt(tjs_int x, tjs_int y,\n\tbool exclude_self, bool get_disabled)\n{\n\t// get most front layer at (x, y),\n\t// excluding self layer if \"exclude_self\" is true.\n\n\tif(!Manager) return NULL;\n\n\t// convert to primary layer's coods\n\ttTJSNI_BaseLayer *p = this;\n\twhile(p)\n\t{\n\t\tif(!p->Parent) break;\n\t\tx += p->Rect.left;\n\t\ty += p->Rect.top;\n\t\tp = p->Parent;\n\t}\n\n\t// call Manager->GetMostFrontChildAt\n\treturn Manager->GetMostFrontChildAt(x, y, exclude_self ? this : NULL, get_disabled);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireClick(tjs_int x, tjs_int y)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[2];\n\t\tparam[0] = x;\n\t\tparam[1] = y;\n\t\tstatic ttstr eventname(TJS_W(\"onClick\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireDoubleClick(tjs_int x, tjs_int y)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[2];\n\t\tparam[0] = x;\n\t\tparam[1] = y;\n\t\tstatic ttstr eventname(TJS_W(\"onDoubleClick\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[4];\n\t\tparam[0] = x;\n\t\tparam[1] = y;\n\t\tparam[2] = (tjs_int) mb;\n\t\tparam[3] = (tjs_int64)flags;\n\t\tstatic ttstr eventname(TJS_W(\"onMouseDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[4];\n\t\tparam[0] = x;\n\t\tparam[1] = y;\n\t\tparam[2] = (tjs_int) mb;\n\t\tparam[3] = (tjs_int64)flags;\n\t\tstatic ttstr eventname(TJS_W(\"onMouseUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[3];\n\t\tparam[0] = x;\n\t\tparam[1] = y;\n\t\tparam[2] = (tjs_int64)flags;\n\t\tstatic ttstr eventname(TJS_W(\"onMouseMove\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE|TVP_EPT_DISCARDABLE, 3, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseEnter()\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMouseEnter\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseLeave()\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMouseLeave\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ReleaseCapture()\n{\n\tif(Manager) Manager->ReleaseCapture();\n\t\t// this releases mouse capture from all layers, ignoring which layer captures.\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ReleaseTouchCapture( tjs_uint32 id, bool all ) {\n\tif(Manager)\n\t{\n\t\tif( all )\n\t\t{\n\t\t\tManager->ReleaseTouchCaptureAll();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tManager->ReleaseTouchCapture(id);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchMove\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE|TVP_EPT_DISCARDABLE, 5, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant arg[5] = { startdist, curdist, cx, cy, flag };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchScaling\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant arg[6] = { startangle, curangle, dist, cx, cy, flag };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchRotate\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 6, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMultiTouch()\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMultiTouch\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::ParentFocusable() const\n{\n\ttTJSNI_BaseLayer *par = Parent;\n\twhile(par)\n\t{\n\t\tif(!par->Visible || !par->Enabled) { return false; }\n\t\t\t// note that here we do not check parent's focusable state.\n\t\tpar = par->Parent;\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::SetFocus(bool direction)\n{\n\tif(Manager) return Manager->SetFocusTo(this, direction);\n\treturn false;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFocused()\n{\n\tif(!Manager) return false;\n\treturn Manager->GetFocusedLayer() == this;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTJSNI_BaseLayer::SearchFirstFocusable(bool ignore_chain_focusable)\n{\n\tif(ignore_chain_focusable)\n\t{\n\t\tif(GetNodeFocusable()) return this;\n\t}\n\telse\n\t{\n\t\tif(GetNodeFocusable() && JoinFocusChain) return this;\n\t}\n\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\ttTJSNI_BaseLayer * lay = child->SearchFirstFocusable(ignore_chain_focusable);\n\t\tif(lay) return lay;\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTJSNI_BaseLayer::_GetPrevFocusable()\n{\n\t// search next focusable layer backward\n\ttTJSNI_BaseLayer *p = this;\n\ttTJSNI_BaseLayer *current = this;\n\n\tp = p->GetNeighborAbove(true);\n\tif(current == p) return NULL;\n\tif(!p) return NULL;\n\tcurrent = p;\n\tdo\n\t{\n\t\tif(p->GetNodeFocusable() && p->JoinFocusChain) return p; // next focusable layer found\n\t} while(p = p->GetNeighborAbove(true), p && p != current);\n\n\treturn NULL; // no layer found\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTJSNI_BaseLayer::GetPrevFocusable()\n{\n\t// search next focusable layer backward\n\tFocusWork = _GetPrevFocusable();\n\tif(Owner && !Shutdown &&\n\t\t(!FocusWork || FocusWork->Owner))\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onSearchPrevFocusable\"));\n\t\ttTJSVariant param[1];\n\t\tif(FocusWork)\n\t\t\tparam[0] = tTJSVariant(FocusWork->Owner,\n\t\t\t\tFocusWork->Owner);\n\t\telse\n\t\t\tparam[0] = tTJSVariant((iTJSDispatch2*)NULL);\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE, 1, param);\n\n\t}\n\treturn FocusWork;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTJSNI_BaseLayer::_GetNextFocusable()\n{\n\t// search next focusable layer forward\n\ttTJSNI_BaseLayer *p = this;\n\ttTJSNI_BaseLayer *current = this;\n\n\tp = p->GetNeighborBelow(true);\n\tif(current == p) return NULL;\n\tif(!p) return NULL;\n\tcurrent = p;\n\tdo\n\t{\n\t\tif(p->GetNodeFocusable() && p->JoinFocusChain) return p; // next focusable layer found\n\t} while(p = p->GetNeighborBelow(true), p && p != current);\n\n\treturn NULL; // no layer found\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTJSNI_BaseLayer::GetNextFocusable()\n{\n\t// search next focusable layer forward\n\tFocusWork = _GetNextFocusable();\n\tif(Owner && !Shutdown &&\n\t\t(!FocusWork || FocusWork->Owner))\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onSearchNextFocusable\"));\n\t\ttTJSVariant param[1];\n\t\tif(FocusWork)\n\t\t\tparam[0] = tTJSVariant(FocusWork->Owner,\n\t\t\t\tFocusWork->Owner);\n\t\telse\n\t\t\tparam[0] = tTJSVariant((iTJSDispatch2*)NULL);\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE, 1, param);\n\n\t}\n\treturn FocusWork;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *  tTJSNI_BaseLayer::FocusPrev()\n{\n\tif(Manager) return Manager->FocusPrev(); else return NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *  tTJSNI_BaseLayer::FocusNext()\n{\n\tif(Manager) return Manager->FocusNext(); else return NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFocusable(bool b)\n{\n\tif(Focusable != b)\n\t{\n\t\tbool bstate = GetNodeFocusable();\n\t\tFocusable = b;\n\t\tbool astate = GetNodeFocusable();\n\t\tif(bstate != astate)\n\t\t{\n\t\t\tif(!astate)\n\t\t\t{\n\t\t\t\t// remove focus from this layer\n\t\t\t\tif(Manager)\n\t\t\t\t{\n\t\t\t\t\tif(Manager->GetFocusedLayer() == this)\n\t\t\t\t\t\tManager->SetFocusTo(GetNextFocusable(), true); // blur\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireBlur(tTJSNI_BaseLayer *prevfocused)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onBlur\"));\n\t\ttTJSVariant param[1];\n\t\tif(prevfocused)\n\t\t\tparam[0] = tTJSVariant(prevfocused->Owner, prevfocused->Owner);\n\t\telse\n\t\t\tparam[0] = tTJSVariant((iTJSDispatch2*)NULL);\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE, 1, param);\n\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireFocus(tTJSNI_BaseLayer *prevfocused, bool direction)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onFocus\"));\n\t\ttTJSVariant param[2];\n\t\tif(prevfocused)\n\t\t\tparam[0] = tTJSVariant(prevfocused->Owner, prevfocused->Owner);\n\t\telse\n\t\t\tparam[0] = tTJSVariant((iTJSDispatch2*)NULL);\n\t\tparam[1] = direction;\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE, 2, param);\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTJSNI_BaseLayer::FireBeforeFocus(\n\ttTJSNI_BaseLayer *prevfocused, bool direction)\n{\n\tFocusWork = this;\n\tif(Owner && !Shutdown)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onBeforeFocus\"));\n\t\ttTJSVariant param[3];\n\t\tparam[0] = tTJSVariant(Owner, Owner);\n\t\tif(prevfocused)\n\t\t\tparam[1] = tTJSVariant(prevfocused->Owner, prevfocused->Owner);\n\t\telse\n\t\t\tparam[1] = tTJSVariant((iTJSDispatch2*)NULL);\n\t\tparam[2] = direction;\n\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\tTVP_EPT_IMMEDIATE, 3, param);\n\n\t}\n\treturn FocusWork;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetMode()\n{\n\tif(Manager) Manager->SetModeTo(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::RemoveMode()\n{\n\tif(Manager) Manager->RemoveModeFrom(this);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::IsDisabledByMode()\n{\n\t// is \"this\" layer disable by modal layer?\n\tif(!Manager) return false;\n\ttTJSNI_BaseLayer *current = Manager->GetCurrentModalLayer();\n\tif(!current) return false;\n\treturn !IsAncestorOrSelf(current);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::NotifyNodeEnabledState()\n{\n\tbool en = GetNodeEnabled();\n\tif(Owner && !Shutdown && EnabledWork != en)\n\t{\n\t\tif(en)\n\t\t{\n\t\t\tstatic ttstr eventname(TJS_W(\"onNodeEnabled\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstatic ttstr eventname(TJS_W(\"onNodeDisabled\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t\t}\n\t}\n\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\tchild->NotifyNodeEnabledState();\n\tTVP_LAYER_FOR_EACH_CHILD_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SaveEnabledWork()\n{\n\tEnabledWork = GetNodeEnabled();\n\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BEGIN(child)\n\t\tchild->SaveEnabledWork();\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_END\n}\n//---------------------------------------------------------------------------\n\nvoid tTJSNI_BaseLayer::SetEnabled(bool b)\n{\n\t// set enabled\n\tif(Enabled != b)\n\t{\n\t\tif(Manager) Manager->SaveEnabledWork();\n\n\t\ttry\n\t\t{\n\t\t\tEnabled = b;\n\n\t\t\tif(Enabled)\n\t\t\t{\n\t\t\t\t// become enabled\n\t\t\t\tif(Manager) Manager->CheckTreeFocusableState(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// become disabled\n\t\t\t\tif(Manager) Manager->BlurTree(this);\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(Manager) Manager->NotifyNodeEnabledState();\n\t\t\tthrow;\n\t\t}\n\n\t\tif(Manager) Manager->NotifyNodeEnabledState();\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::ParentEnabled()\n{\n\ttTJSNI_BaseLayer *par = Parent;\n\twhile(par)\n\t{\n\t\tif(!par->Enabled) { return false; }\n\t\tpar = par->Parent;\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireKeyDown(tjs_uint key, tjs_uint32 shift)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[3];\n\t\tparam[0] = (tjs_int)key;\n\t\tparam[1] = (tjs_int)shift;\n\t\tparam[2] = true;\n\t\tstatic ttstr eventname(TJS_W(\"onKeyDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 3, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireKeyUp(tjs_uint key, tjs_uint32 shift)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant param[3];\n\t\tparam[0] = (tjs_int)key;\n\t\tparam[1] = (tjs_int)shift;\n\t\tparam[2] = true;\n\t\tstatic ttstr eventname(TJS_W(\"onKeyUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 3, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireKeyPress(tjs_char key)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttjs_char buf[2];\n\t\tbuf[0] = (tjs_char)key;\n\t\tbuf[1] = 0;\n\t\ttTJSVariant param[2];\n\t\tparam[0] = buf;\n\t\tparam[1] = true;\n\t\tstatic ttstr eventname(TJS_W(\"onKeyPress\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, param);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FireMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x,\n\ttjs_int y)\n{\n\tif(Owner && !Shutdown)\n\t{\n\t\ttTJSVariant val[4] = { (tjs_int)shift, delta, x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onMouseWheel\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, val);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DefaultKeyDown(tjs_uint key, tjs_uint32 shift)\n{\n\t// default keyboard behavior\n\t// this method is to be called by default onKeyDown event handler\n\tif(!Manager) return;\n\n\tbool no_shift_downed =  !(shift & TVP_SS_SHIFT) && !(shift & TVP_SS_ALT) &&\n\t\t!(shift & TVP_SS_CTRL);\n\n\tif((key == VK_TAB || key == VK_RIGHT || key == VK_DOWN) && no_shift_downed)\n\t{\n\t\t// [TAB] [<RIGHT>] [<DOWN>] : to next focusable\n\t\tManager->FocusNext();\n\t}\n\telse if((key == VK_TAB && (shift & TVP_SS_SHIFT) && !(shift & TVP_SS_ALT) &&\n\t\t!(shift & TVP_SS_CTRL)) || key == VK_LEFT || key == VK_UP)\n\t{\n\t\t// [SHIFT]+[TAB] [<LEFT>] [<UP>] : to previous focusable\n\t\tManager->FocusPrev();\n\t}\n\telse if((key == VK_RETURN || key == VK_ESCAPE) && no_shift_downed)\n\t{\n\t\t// [ENTER] or [ESC] : pass to parent layer\n\t\tif(Parent)\n\t\t{\n\t\t\tif(Parent->GetNodeEnabled()) Parent->FireKeyDown(key, shift);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DefaultKeyUp(tjs_uint key, tjs_uint32 shift)\n{\n\t// default keyboard behavior\n\tif(!Manager) return;\n\n\n\tbool no_shift_downed =  !(shift & TVP_SS_SHIFT) && !(shift & TVP_SS_ALT) &&\n\t\t!(shift & TVP_SS_CTRL);\n\n\tif((key == VK_RETURN || key == VK_ESCAPE) && no_shift_downed)\n\t{\n\t\t// [ENTER] or [ESC] : pass to parent layer\n\t\tif(Parent)\n\t\t{\n\t\t\tif(Parent->GetNodeEnabled()) Parent->FireKeyUp(key, shift);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DefaultKeyPress(tjs_char key)\n{\n\t// default keyboard behavior\n\tif(!Manager) return;\n\n\tif(key == 13/* enter */ || key == 0x1b/* esc */)\n\t{\n\t\tif(Parent)\n\t\t{\n\t\t\tif(Parent->GetNodeEnabled()) Parent->FireKeyPress(key);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// cache management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AllocateCache()\n{\n\tif(!CacheBitmap)\n\t{\n\t\tCacheBitmap =\n\t\t\tnew tTVPBaseTexture(Rect.get_width(), Rect.get_height(), 32);\n\t}\n\telse\n\t{\n\t\tCacheBitmap->SetSize(Rect.get_width(), Rect.get_height());\n\t}\n\tCacheRecalcRegion.Or(tTVPRect(0, 0, Rect.get_width(), Rect.get_height()));\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ResizeCache()\n{\n\t// resize to Rect's size\n\tif(CacheBitmap && MainImage)\n\t{\n\t\tCacheBitmap->SetSize(MainImage->GetWidth(), MainImage->GetHeight());\n\t}\n\tCacheRecalcRegion.Or(tTVPRect(0, 0, Rect.get_width(), Rect.get_height()));\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DeallocateCache()\n{\n\tif(CacheBitmap)\n\t{\n\t\tdelete CacheBitmap; CacheBitmap = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DispSizeChanged()\n{\n\t// is called from geographical management\n\tResizeCache();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CompactCache()\n{\n\t// free cache image if the cache is not needed\n\tif(!CacheEnabledCount) DeallocateCache();\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_BaseLayer::IncCacheEnabledCount()\n{\n\tCacheEnabledCount++;\n\tif(CacheEnabledCount)\n\t{\n\t\tRegisterCompactEventHook();\n\t\t\t// register to compact event hook to call CompactCache when idle\n\t\tAllocateCache();\n\t}\n\treturn CacheEnabledCount;\n}\n//---------------------------------------------------------------------------\ntjs_uint tTJSNI_BaseLayer::DecCacheEnabledCount()\n{\n\tCacheEnabledCount--;\n\tif(TVPFreeUnusedLayerCache && !CacheEnabledCount)\n\t\tDeallocateCache();\n\t\t// object is not freed until compact event, unless TVPFreeUnusedLayerCache flags\n\treturn CacheEnabledCount;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetCached(bool b)\n{\n\tif(b != Cached)\n\t{\n\t\tCached = b;\n\t\tif(b)\n\t\t\tIncCacheEnabledCount();\n\t\telse\n\t\t\tDecCacheEnabledCount();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// drawing function stuff\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ResetClip()\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tClipRect.left = ClipRect.top = 0;\n\tClipRect.right = MainImage->GetWidth();\n\tClipRect.bottom = MainImage->GetHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetClip(tjs_int left, tjs_int top, tjs_int width, tjs_int height)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tClipRect.left = left < 0 ? 0 : left;\n\tClipRect.top = top < 0 ? 0 : top;\n\ttjs_int right = width + left;\n\ttjs_int bottom = height + top;\n\ttjs_int w = MainImage->GetWidth();\n\ttjs_int h = MainImage->GetHeight();\n\tClipRect.right = w < right ? w : right;\n\tClipRect.bottom = h < bottom ? h : bottom;\n\tif(ClipRect.right < ClipRect.left) ClipRect.right = ClipRect.left;\n\tif(ClipRect.bottom < ClipRect.top) ClipRect.bottom = ClipRect.top;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetClipLeft(tjs_int left)\n{\n\tSetClip(left, GetClipTop(), GetClipWidth(), GetClipHeight());\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetClipTop(tjs_int top)\n{\n\tSetClip(GetClipLeft(), top, GetClipWidth(), GetClipHeight());\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetClipWidth(tjs_int width)\n{\n\tSetClip(GetClipLeft(), GetClipTop(), width, GetClipHeight());\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetClipHeight(tjs_int height)\n{\n\tSetClip(GetClipLeft(), GetClipTop(), GetClipWidth(), height);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::ClipDestPointAndSrcRect(tjs_int &dx, tjs_int &dy,\n\t\ttTVPRect &srcrectout, const tTVPRect &srcrect) const\n{\n\t// clip (dx, dy) <- srcrect\twith current clipping rectangle\n\tsrcrectout = srcrect;\n\ttjs_int dr = dx + srcrect.right - srcrect.left;\n\ttjs_int db = dy + srcrect.bottom - srcrect.top;\n\n\tif(dx < ClipRect.left)\n\t{\n\t\tsrcrectout.left += (ClipRect.left - dx);\n\t\tdx = ClipRect.left;\n\t}\n\n\tif(dr > ClipRect.right)\n\t{\n\t\tsrcrectout.right -= (dr - ClipRect.right);\n\t}\n\n\tif(srcrectout.right <= srcrectout.left) return false; // out of the clipping rect\n\n\tif(dy < ClipRect.top)\n\t{\n\t\tsrcrectout.top += (ClipRect.top - dy);\n\t\tdy = ClipRect.top;\n\t}\n\n\tif(db > ClipRect.bottom)\n\t{\n\t\tsrcrectout.bottom -= (db - ClipRect.bottom);\n\t}\n\n\tif(srcrectout.bottom <= srcrectout.top) return false; // out of the clipping rect\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetBltMethodFromOperationModeAndDrawFace(\n\t\ttTVPBBBltMethod & result,\n\t\ttTVPBlendOperationMode mode)\n{\n\t// resulting corresponding  tTVPBBBltMethod value of mode and current DrawFace.\n\t// returns whether the method is known.\n\ttTVPBBBltMethod met;\n\tbool met_set = false;\n\tswitch(mode)\n\t{\n\tcase omPsNormal:\t\t\tmet_set = true; met = bmPsNormal;\t\t\tbreak;\n\tcase omPsAdditive:\t\t\tmet_set = true; met = bmPsAdditive;\t\t\tbreak;\n\tcase omPsSubtractive:\t\tmet_set = true; met = bmPsSubtractive;\t\tbreak;\n\tcase omPsMultiplicative:\tmet_set = true; met = bmPsMultiplicative;\tbreak;\n\tcase omPsScreen:\t\t\tmet_set = true; met = bmPsScreen;\t\t\tbreak;\n\tcase omPsOverlay:\t\t\tmet_set = true; met = bmPsOverlay;\t\t\tbreak;\n\tcase omPsHardLight:\t\t\tmet_set = true; met = bmPsHardLight;\t\tbreak;\n\tcase omPsSoftLight:\t\t\tmet_set = true; met = bmPsSoftLight;\t\tbreak;\n\tcase omPsColorDodge:\t\tmet_set = true; met = bmPsColorDodge;\t\tbreak;\n\tcase omPsColorDodge5:\t\tmet_set = true; met = bmPsColorDodge5;\t\tbreak;\n\tcase omPsColorBurn:\t\t\tmet_set = true; met = bmPsColorBurn;\t\tbreak;\n\tcase omPsLighten:\t\t\tmet_set = true; met = bmPsLighten;\t\t\tbreak;\n\tcase omPsDarken:\t\t\tmet_set = true; met = bmPsDarken;\t\t\tbreak;\n\tcase omPsDifference:   \t\tmet_set = true; met = bmPsDifference;\t\tbreak;\n\tcase omPsDifference5:   \tmet_set = true; met = bmPsDifference5;\t\tbreak;\n\tcase omPsExclusion:\t\t\tmet_set = true; met = bmPsExclusion;\t\tbreak;\n\tcase omAdditive:\t\t\tmet_set = true; met = bmAdd;\t\t\t\tbreak;\n\tcase omSubtractive:\t\t\tmet_set = true; met = bmSub;\t\t\t\tbreak;\n\tcase omMultiplicative:\t\tmet_set = true; met = bmMul;\t\t\t\tbreak;\n\tcase omDodge:\t\t\t\tmet_set = true; met = bmDodge;\t\t\t\tbreak;\n\tcase omDarken:\t\t\t\tmet_set = true; met = bmDarken;\t\t\t\tbreak;\n\tcase omLighten:\t\t\t\tmet_set = true; met = bmLighten;\t\t\tbreak;\n\tcase omScreen:\t\t\t\tmet_set = true; met = bmScreen;\t\t\t\tbreak;\n\tcase omAlpha:\n\t\tif(DrawFace == dfAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAlphaOnAlpha; break;\t\t}\n\t\telse if(DrawFace == dfAddAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAlphaOnAddAlpha; break;\t\t}\n\t\telse if(DrawFace == dfOpaque)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAlpha; break;\t\t\t\t}\n\t\tbreak;\n\tcase omAddAlpha:\n\t\tif(DrawFace == dfAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAddAlphaOnAlpha; break;\t\t}\n\t\telse if(DrawFace == dfAddAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAddAlphaOnAddAlpha; break;\t}\n\t\telse if(DrawFace == dfOpaque)\n\t\t\t\t\t\t{\tmet_set = true; met = bmAddAlpha; break;\t\t\t}\n\t\tbreak;\n\tcase omOpaque:\n\t\tif(DrawFace == dfAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmCopyOnAlpha; break;\t\t\t}\n\t\telse if(DrawFace == dfAddAlpha)\n\t\t\t\t\t\t{\tmet_set = true; met = bmCopyOnAddAlpha; break;\t\t}\n\t\telse if(DrawFace == dfOpaque)\n\t\t\t\t\t\t{\tmet_set = true; met = bmCopy; break;\t\t\t\t}\n\t\tbreak;\n\tcase dfAuto:\n\t\tbreak;\n\t}\n\n\tresult = met;\n\n\treturn met_set;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::FillRect(const tTVPRect &rect, tjs_uint32 color)\n{\n\t// fill given rectangle with given \"color\"\n\t// this method does not do transparent coloring.\n\n\ttTVPRect destrect;\n\tif(!TVPIntersectRect(&destrect, rect, ClipRect)) return; // out of the clipping rectangle\n\n\tif(DrawFace == dfAlpha || DrawFace == dfAddAlpha || (DrawFace == dfOpaque && !HoldAlpha))\n\t{\n\t\t// main and mask\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tcolor = (color & 0xff000000) + (TVPToActualColor(color&0xffffff)&0xffffff);\n\t\tImageModified = MainImage->Fill(destrect, color) || ImageModified;\n\t}\n\telse if(DrawFace == dfOpaque)\n\t{\n\t\t// main only\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tcolor = TVPToActualColor(color);\n\t\tImageModified = MainImage->FillColor(destrect, color, 255) || ImageModified;\n\t}\n\telse if(DrawFace == dfMask)\n\t{\n\t\t// mask only\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tImageModified = MainImage->FillMask(destrect, color&0xff) || ImageModified;\n\t}\n\telse if(DrawFace == dfProvince)\n\t{\n\t\t// province\n\t\tcolor = color & 0xff;\n\t\tif(color)\n\t\t{\n\t\t\tif(!ProvinceImage) AllocateProvinceImage();\n\t\t\tif(ProvinceImage)\n\t\t\t\tImageModified = ProvinceImage->Fill(destrect, color&0xff) || ImageModified;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(ProvinceImage)\n\t\t\t{\n\t\t\t\tif(destrect.left == 0 && destrect.top == 0 &&\n\t\t\t\t\tdestrect.right == (tjs_int)ProvinceImage->GetWidth() &&\n\t\t\t\t\tdestrect.bottom == (tjs_int)ProvinceImage->GetHeight())\n\t\t\t\t{\n\t\t\t\t\t// entire area of the province image will be filled with 0\n\t\t\t\t\tDeallocateProvinceImage();\n\t\t\t\t\tImageModified = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tImageModified = ProvinceImage->Fill(destrect, color&0xff) || ImageModified;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\ttTVPRect ur = destrect;\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(destrect);\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ColorRect(const tTVPRect &rect, tjs_uint32 color, tjs_int opa)\n{\n\t// color given rectangle with given \"color\"\n\n\ttTVPRect destrect;\n\tif(!TVPIntersectRect(&destrect, rect, ClipRect)) return; // out of the clipping rectangle\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha: // main and mask\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(opa > 0)\n\t\t{\n\t\t\tcolor = TVPToActualColor(color);\n\t\t\tImageModified = MainImage->FillColorOnAlpha(destrect, color, opa) || ImageModified;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tImageModified = MainImage->RemoveConstOpacity(destrect, -opa) || ImageModified;\n\t\t}\n\t\tbreak;\n\n\tcase dfAddAlpha: // additive alpha; main and mask\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(opa >= 0)\n\t\t{\n\t\t\tcolor = TVPToActualColor(color);\n\t\t\tImageModified = MainImage->FillColorOnAddAlpha(destrect, color, opa) || ImageModified;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPNegativeOpacityNotSupportedOnThisFace);\n\t\t}\n\t\tbreak;\n\n\tcase dfOpaque: // main only\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tcolor = TVPToActualColor(color);\n\t\tImageModified = MainImage->FillColor(destrect, color, opa) || ImageModified;\n\t\t\t// note that tTVPBaseBitmap::FillColor always holds destination alpha\n\t\tbreak;\n\n\tcase dfMask: // mask ( opacity will be ignored )\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tImageModified = MainImage->FillMask(destrect, color&0xff ) || ImageModified;\n\t\tbreak;\n\n\tcase dfProvince: // province ( opacity will be ignored )\n\t\tcolor = color & 0xff;\n\t\tif(color)\n\t\t{\n\t\t\tif(!ProvinceImage) AllocateProvinceImage();\n\t\t\tif(ProvinceImage)\n\t\t\t\tImageModified = ProvinceImage->Fill(destrect, color&0xff) || ImageModified;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(ProvinceImage)\n\t\t\t{\n\t\t\t\tif(destrect.left == 0 && destrect.top == 0 &&\n\t\t\t\t\tdestrect.right == (tjs_int)ProvinceImage->GetWidth() &&\n\t\t\t\t\tdestrect.bottom == (tjs_int)ProvinceImage->GetHeight())\n\t\t\t\t{\n\t\t\t\t\t// entire area of the province image will be filled with 0\n\t\t\t\t\tDeallocateProvinceImage();\n\t\t\t\t\tImageModified = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tImageModified = ProvinceImage->Fill(destrect, color&0xff) || ImageModified;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\n\tcase dfAuto:\n\t\tbreak;\n\t}\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\ttTVPRect ur = destrect;\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(destrect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DrawText(tjs_int x, tjs_int y, const ttstr &text,\n\ttjs_uint32 color, tjs_int opa, bool aa, tjs_int shadowlevel,\n\t\ttjs_uint32 shadowcolor, tjs_int shadowwidth, tjs_int shadowofsx,\n\t\ttjs_int shadowofsy)\n{\n\t// draw text\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\ttTVPBBBltMethod met;\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\tcase dfAddAlpha:\n\t\tif(opa<0) TVPThrowExceptionMessage(TVPNegativeOpacityNotSupportedOnThisFace);\n\t\tmet = bmAlphaOnAddAlpha;\n\t\tbreak;\n\tcase dfOpaque:\n\t\tmet = bmAlpha;\n\t\tbreak;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"drawText\"));\n\t}\n\n\tApplyFont();\n\n\ttTVPComplexRect r;\n\n\tcolor = TVPToActualColor(color);\n\n\tMainImage->DrawText(ClipRect, x, y, text, TVP_REVRGB(color), met,\n\t\topa, HoldAlpha, aa, shadowlevel, TVP_REVRGB(shadowcolor), shadowwidth,\n\t\tshadowofsx, shadowofsy, &r);\n\n\tif(r.GetCount()) ImageModified = true;\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tr.AddOffsets(ImageLeft, ImageTop);\n\t}\n\tUpdate(r);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DrawGlyph(tjs_int x, tjs_int y, iTJSDispatch2* glyph, tjs_uint32 color,\n\t\ttjs_int opa, bool aa, tjs_int shadowlevel, tjs_uint32 shadowcolor,\n\t\ttjs_int shadowwidth, tjs_int shadowofsx, tjs_int shadowofsy)\n{\n\t// draw text\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\ttTVPBBBltMethod met;\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tmet = bmAlphaOnAlpha;\n\t\tbreak;\n\tcase dfAddAlpha:\n\t\tif(opa<0) TVPThrowExceptionMessage(TVPNegativeOpacityNotSupportedOnThisFace);\n\t\tmet = bmAlphaOnAddAlpha;\n\t\tbreak;\n\tcase dfOpaque:\n\t\tmet = bmAlpha;\n\t\tbreak;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"drawGlyph\"));\n\t}\n\n\tApplyFont();\n\n\ttTVPComplexRect r;\n\n\tcolor = TVPToActualColor(color);\n\n\tMainImage->DrawGlyph( glyph, ClipRect, x, y, color, met,\n\t\topa, HoldAlpha, aa, shadowlevel, shadowcolor, shadowwidth,\n\t\tshadowofsx, shadowofsy, &r);\n\n\tif(r.GetCount()) ImageModified = true;\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tr.AddOffsets(ImageLeft, ImageTop);\n\t}\n\tUpdate(r);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::PiledCopy(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect)\n{\n\t// rectangle copy of piled layer image\n\n\t// this can transfer the piled image of the source layer\n\t// this ignores Drawface of this, or DrawFace of the source layer.\n\t// this is affected by source layer type.\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\n\ttTVPRect rect;\n\tif(!ClipDestPointAndSrcRect(dx, dy, rect, srcrect)) return; // out of the clipping rect\n\n\tsrc->IncCacheEnabledCount(); // enable cache\n\ttry\n\t{\n        iTVPBaseBitmap *bmp = src->Complete(rect);\n\t\ttTVPRect rc(rect);\n\t\tif (IsGPU()) {\n\t\t\trc.set_offsets(0, 0);\n\t\t}\n\t\tImageModified = MainImage->CopyRect(dx, dy, bmp, rc,\n\t\t\tTVP_BB_COPY_MAIN|TVP_BB_COPY_MASK) || ImageModified;\n\t}\n\tcatch(...)\n\t{\n\t\tsrc->DecCacheEnabledCount();\n\t\tthrow;\n\t}\n\tsrc->DecCacheEnabledCount(); // disable cache\n\n\ttTVPRect ur = rect;\n\tur.set_offsets(dx, dy);\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CopyRect(tjs_int dx, tjs_int dy, iTVPBaseBitmap *src, iTVPBaseBitmap *provincesrc,\n\tconst tTVPRect &srcrect)\n{\n\t// copy rectangle\n\n\t// this method switches automatically backward or forward copy, when\n\t// the distination and the source each other are overlapped.\n\n\ttTVPRect rect;\n\tif(!ClipDestPointAndSrcRect(dx, dy, rect, srcrect)) return; // out of the clipping rect\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\tcase dfAddAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified = MainImage->CopyRect(dx, dy, src, rect,\n\t\t\tTVP_BB_COPY_MAIN|TVP_BB_COPY_MASK) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified = MainImage->CopyRect(dx, dy, src, rect,\n\t\t\tHoldAlpha?TVP_BB_COPY_MAIN:(TVP_BB_COPY_MAIN|TVP_BB_COPY_MASK)) || ImageModified;\n\t\tbreak;\n\n\tcase dfMask:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified = MainImage->CopyRect(dx, dy, src, rect,\n\t\t\tTVP_BB_COPY_MASK) || ImageModified;\n\t\tbreak;\n\n\tcase dfProvince:\n\t\tif(!provincesrc)\n\t\t{\n\t\t\t// source province image is null;\n\t\t\t// fill destination with zero\n\t\t\tif(ProvinceImage) ProvinceImage->Fill(rect, 0);\n\t\t\tImageModified = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// province image is not created if the image is not needed\n\t\t\t// allocate province image\n\t\t\tif(!ProvinceImage) AllocateProvinceImage();\n\t\t\t// then copy\n\t\t\tImageModified = ProvinceImage->CopyRect(dx, dy, provincesrc, rect) || ImageModified;\n\t\t}\n\t\tbreak;\n\tcase dfAuto:\n\t\tbreak;\n\t}\n\n\n\ttTVPRect ur = rect;\n\tur.set_offsets(dx, dy);\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::Copy9Patch( const iTVPBaseBitmap *src, tTVPRect &margin )\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tImageModified = MainImage->Copy9Patch( src, margin );\n\tif( ImageModified )\n\t{\n\t\ttTVPRect ur(0,0,GetImageWidth(),GetImageHeight());\n\t\tif(ImageLeft != 0 || ImageTop != 0)\n\t\t{\n\t\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\t\tUpdate(ur);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tUpdate(ur);\n\t\t}\n\t}\n\treturn ImageModified;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StretchCopy(const tTVPRect &destrect, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBBStretchType type, tjs_real typeopt)\n{\n\t// stretching copy\n\ttTVPRect ur = destrect;\n\tif(ur.right < ur.left) std::swap(ur.right, ur.left);\n\tif(ur.bottom < ur.top) std::swap(ur.bottom, ur.top);\n\tif(!TVPIntersectRect(&ur, ur, ClipRect)) return; // out of the clipping rectangle\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\tcase dfAddAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->StretchBlt(ClipRect, destrect, src, srcrect, bmCopy, 255, false,\n\t\t\t\ttype, typeopt) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->StretchBlt(ClipRect, destrect, src, srcrect,\n\t\t\t\tbmCopy, 255, HoldAlpha, type, typeopt) || ImageModified;\n\t\tbreak;\n\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"stretchCopy\"));\n\t}\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffineCopy(const t2DAffineMatrix &matrix, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBBStretchType type, bool clear)\n{\n\t// affine copy\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\tcase dfAddAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, matrix,\n\t\t\tbmCopy, 255, &updaterect, false, type, clear, NeutralColor);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, matrix,\n\t\t\tbmCopy, 255, &updaterect, HoldAlpha, type, clear, NeutralColor);\n\t\tbreak;\n\t  }\n\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affineCopy\"));\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffineCopy(const tTVPPointD *points, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBBStretchType type, bool clear)\n{\n\t// affine copy\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\tcase dfAddAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, points,\n\t\t\tbmCopy, 255, &updaterect, false, type, clear, NeutralColor);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, points,\n\t\t\tbmCopy, 255, &updaterect, HoldAlpha, type, clear, NeutralColor);\n\t\tbreak;\n\t  }\n\n\tdefault:\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affineCopy\"));\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::PileRect(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity)\n{\n\t// obsoleted (use OperateRect)\n\n\t// pile rectangle ( pixel alpha blend )\n\n\t// piled destination is determined by Drawface (not LayerType).\n\t// dfAlpha: destination alpha is considered\n\t// dfOpaque: destination alpha is ignored ( treated as full opaque )\n\t// dfMask or dfProvince : causes an error\n\t// this method ignores soruce layer's LayerType or DrawFace.\n\t// the destination alpha is held on dfAlpha if 'HoldAlpha' is true, otherwide the\n\t// alpha information is destroyed.\n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"pileRect\"));\n\t}\n\n\ttTVPRect rect;\n\tif(!ClipDestPointAndSrcRect(dx, dy, rect, srcrect)) return; // out of the clipping rect\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->Blt(dx, dy, src->MainImage, rect, bmAlphaOnAlpha, opacity, HoldAlpha) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->Blt(dx, dy, src->MainImage, rect, bmAlpha, opacity, HoldAlpha) || ImageModified;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\ttTVPRect ur = rect;\n\tur.set_offsets(dx, dy);\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::BlendRect(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity)\n{\n\t// obsoleted (use OperateRect)\n\n\t// blend rectangle ( constant alpha blend )\n\n\t// mostly the same as 'PileRect', but this does treat src as completely\n\t// opaque image. \n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"blendRect\"));\n\t}\n\n\ttTVPRect rect;\n\tif(!ClipDestPointAndSrcRect(dx, dy, rect, srcrect)) return; // out of the clipping rect\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->Blt(dx, dy, src->MainImage, rect, bmCopyOnAlpha, opacity, HoldAlpha) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tImageModified =\n\t\t\tMainImage->Blt(dx, dy, src->MainImage, rect, bmCopy, opacity, HoldAlpha) || ImageModified;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\ttTVPRect ur = rect;\n\tur.set_offsets(dx, dy);\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::OperateRect(tjs_int dx, tjs_int dy, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode,\n\t\t\ttjs_int opacity)\n{\n\t// operate on rectangle ( add/sub/mul/div and others )\n\ttTVPRect rect;\n\tif(!ClipDestPointAndSrcRect(dx, dy, rect, srcrect)) return; // out of the clipping rect\n\n\t// It does not throw an exception in this case perhaps\n\tif(mode == omAuto) TVPThrowExceptionMessage( TVPCannotAcceptModeAuto );\n\n\t// convert tTVPBlendOperationMode to tTVPBBBltMethod\n\ttTVPBBBltMethod met;\n\tif(!GetBltMethodFromOperationModeAndDrawFace(met, mode))\n\t{\n\t\t// unknown blt mode\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"operateRect\"));\n\t}\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\n\tImageModified =\n\t\tMainImage->Blt(dx, dy, src, rect, met, opacity, HoldAlpha) || ImageModified;\n\n\ttTVPRect ur = rect;\n\tur.set_offsets(dx, dy);\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StretchPile(const tTVPRect &destrect, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity, tTVPBBStretchType type)\n{\n\t// obsoleted (use OperateStretch)\n\n\t// stretching pile\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"stretchPile\"));\n\t}\n\n\ttTVPRect ur = destrect;\n\tif(ur.right < ur.left) std::swap(ur.right, ur.left);\n\tif(ur.bottom < ur.top) std::swap(ur.bottom, ur.top);\n\tif(!TVPIntersectRect(&ur, ur, ClipRect)) return; // out of the clipping rectangle\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n        ImageModified = MainImage->StretchBlt(ClipRect, destrect, src->MainImage, srcrect, bmAlphaOnAlpha,\n\t\t\topacity, HoldAlpha, type) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n        ImageModified = MainImage->StretchBlt(ClipRect, destrect, src->MainImage, srcrect, bmAlpha,\n\t\t\topacity, HoldAlpha, type) || ImageModified;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StretchBlend(const tTVPRect &destrect, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity, tTVPBBStretchType type)\n{\n\t// obsoleted (use OperateStretch)\n\n\t// stretching blend\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"stretchBlend\"));\n\t}\n\n\ttTVPRect ur = destrect;\n\tif(ur.right < ur.left) std::swap(ur.right, ur.left);\n\tif(ur.bottom < ur.top) std::swap(ur.bottom, ur.top);\n\tif(!TVPIntersectRect(&ur, ur, ClipRect)) return; // out of the clipping rectangle\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n        ImageModified = MainImage->StretchBlt(ClipRect, destrect, src->MainImage, srcrect, bmCopyOnAlpha,\n\t\t\topacity, HoldAlpha, type) || ImageModified;\n\t\tbreak;\n\n\tcase dfOpaque:\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n        ImageModified = MainImage->StretchBlt(ClipRect, destrect, src->MainImage, srcrect, bmCopy,\n\t\t\topacity, HoldAlpha, type) || ImageModified;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::OperateStretch(const tTVPRect &destrect,\n\tiTVPBaseBitmap *src, const tTVPRect &srcrect, tTVPBlendOperationMode mode, tjs_int opacity,\n\t\t\ttTVPBBStretchType type, tjs_real typeopt)\n{\n\t// stretching operation (add/mul/sub etc.)\n\n\ttTVPRect ur = destrect;\n\tif(ur.right < ur.left) std::swap(ur.right, ur.left);\n\tif(ur.bottom < ur.top) std::swap(ur.bottom, ur.top);\n\tif(!TVPIntersectRect(&ur, ur, ClipRect)) return; // out of the clipping rectangle\n\t\n\t// It does not throw an exception in this case perhaps\n\tif(mode == omAuto) TVPThrowExceptionMessage( TVPCannotAcceptModeAuto );\n\n\t// convert tTVPBlendOperationMode to tTVPBBBltMethod\n\ttTVPBBBltMethod met;\n\tif(!GetBltMethodFromOperationModeAndDrawFace(met, mode))\n\t{\n\t\t// unknown blt mode\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"operateStretch\"));\n\t}\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\tImageModified = MainImage->StretchBlt(ClipRect, destrect, src, srcrect, met,\n\t\topacity, HoldAlpha, type, typeopt) || ImageModified;\n\n\tif(ImageLeft != 0 || ImageTop != 0)\n\t{\n\t\tur.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(ur);\n\t}\n\telse\n\t{\n\t\tUpdate(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffinePile(const t2DAffineMatrix &matrix, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity,\n\ttTVPBBStretchType type)\n{\n\t// obsoleted (use OperateAffine)\n\n\t// affine pile\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affinePile\"));\n\t}\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, matrix,\n\t\t\tbmAlphaOnAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, matrix,\n\t\t\tbmAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\tdefault:\n\t\tbreak;\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffinePile(const tTVPPointD *points, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity,\n\ttTVPBBStretchType type)\n{\n\t// obsoleted (use OperateAffine)\n\n\t// affine pile\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affinePile\"));\n\t}\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, points,\n\t\t\tbmAlphaOnAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, points,\n\t\t\tbmAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\tdefault:\n\t\tbreak;\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffineBlend(const t2DAffineMatrix &matrix, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity,\n\ttTVPBBStretchType type)\n{\n\t// obsoleted (use OperateAffine)\n\n\t// affine blend\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affineBlend\"));\n\t}\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, matrix,\n\t\t\tbmCopyOnAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, matrix,\n\t\t\tbmCopy, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AffineBlend(const tTVPPointD *points, tTJSNI_BaseLayer *src,\n\tconst tTVPRect &srcrect, tjs_int opacity,\n\ttTVPBBStretchType type)\n{\n\t// obsoleted (use OperateAffine)\n\n\t// affine blend\n\ttTVPRect updaterect;\n\tbool updated;\n\n\tif(DrawFace != dfAlpha && DrawFace != dfOpaque)\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"affineBlend\"));\n\t}\n\n\n\tswitch(DrawFace)\n\t{\n\tcase dfAlpha:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, points,\n\t\t\tbmCopyOnAlpha, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tcase dfOpaque:\n\t  {\n\t\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\t\tif(!src->MainImage) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\t\tupdated = MainImage->AffineBlt(ClipRect, src->MainImage, srcrect, points,\n\t\t\tbmCopy, opacity, &updaterect, HoldAlpha, type);\n\t\tbreak;\n\t  }\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::OperateAffine(const t2DAffineMatrix &matrix,\n\tiTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode, tjs_int opacity,\n\t\ttTVPBBStretchType type)\n{\n\t// affine operation\n\ttTVPRect updaterect;\n\tbool updated;\n\t\n\t// It does not throw an exception in this case perhaps\n\tif(mode == omAuto) TVPThrowExceptionMessage( TVPCannotAcceptModeAuto );\n\n\t// convert tTVPBlendOperationMode to tTVPBBBltMethod\n\ttTVPBBBltMethod met;\n\tif(!GetBltMethodFromOperationModeAndDrawFace(met, mode))\n\t{\n\t\t// unknown blt mode\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"operateAffine\"));\n\t}\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, matrix,\n\t\tmet, opacity, &updaterect, HoldAlpha, type);\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::OperateAffine(const tTVPPointD *points, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode, tjs_int opacity,\n\t\ttTVPBBStretchType type)\n{\n\t// affine operation\n\ttTVPRect updaterect;\n\tbool updated;\n\t\n\t// It does not throw an exception in this case perhaps\n\tif(mode == omAuto) TVPThrowExceptionMessage( TVPCannotAcceptModeAuto );\n\n\t// convert tTVPBlendOperationMode to tTVPBBBltMethod\n\ttTVPBBBltMethod met;\n\tif(!GetBltMethodFromOperationModeAndDrawFace(met, mode))\n\t{\n\t\t// unknown blt mode\n\t\tTVPThrowExceptionMessage(TVPNotDrawableFaceType, TJS_W(\"operateAffine\"));\n\t}\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\tif(!src) TVPThrowExceptionMessage(TVPSourceLayerHasNoImage);\n\tupdated = MainImage->AffineBlt(ClipRect, src, srcrect, points,\n\t\tmet, opacity, &updaterect, HoldAlpha, type);\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DoBoxBlur(tjs_int xblur, tjs_int yblur)\n{\n\t// blur with box blur method\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tbool updated;\n\n\tif(DrawFace != dfAlpha)\n\t\tupdated = MainImage->DoBoxBlur(ClipRect, tTVPRect(-xblur, -yblur, xblur, yblur));\n\telse\n\t\tupdated = MainImage->DoBoxBlurForAlpha(ClipRect, tTVPRect(-xblur, -yblur, xblur, yblur));\n\n\tImageModified = updated || ImageModified;\n\n\tif(updated)\n\t{\n\t\ttTVPRect updaterect(ClipRect);\n\t\tupdaterect.add_offsets(ImageLeft, ImageTop);\n\t\tUpdate(updaterect);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AdjustGamma(const tTVPGLGammaAdjustData & data)\n{\n\t// this is not affected by DrawFace\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tif(DrawFace == dfAddAlpha)\n\t\tMainImage->AdjustGammaForAdditiveAlpha(\n\t\t\tClipRect,\n\t\t\tdata);\n\telse\n\t\tMainImage->AdjustGamma(\n\t\t\tClipRect,\n\t\t\tdata);\n\n\tImageModified = true;\n\tUpdate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DoGrayScale()\n{\n\t// this is not affected by DrawFace\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tMainImage->DoGrayScale(ClipRect);\n\n\tImageModified = true;\n\tUpdate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::LRFlip()\n{\n\t// this is not affected by DrawFace\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\ttTVPRect r(0, 0, MainImage->GetWidth(), MainImage->GetHeight());\n\tMainImage->LRFlip(r);\n\tif(ProvinceImage) ProvinceImage->LRFlip(r);\n\n\tImageModified = true;\n\tUpdate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UDFlip()\n{\n\t// this is not affected by DrawFace\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\ttTVPRect r(0, 0, MainImage->GetWidth(), MainImage->GetHeight());\n\tMainImage->UDFlip(r);\n\tif(ProvinceImage) ProvinceImage->UDFlip(r);\n\n\tImageModified = true;\n\tUpdate();\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// interface to font object\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ApplyFont()\n{\n\tif(FontChanged && MainImage)\n\t{\n\t\tFontChanged = false;\n\t\tMainImage->SetFont(Font);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontFace(const ttstr & face)\n{\n\tif(Font.Face != face)\n\t{\n\t\tFont.Face = face;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_BaseLayer::GetFontFace() const\n{\n\treturn Font.Face;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontHeight(tjs_int height)\n{\n\tif(height < 0) height = -height; // TVP2 does not support negative value of height\n\n\tif(Font.Height != height)\n\t{\n\t\tFont.Height = height;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetFontHeight() const\n{\n\treturn Font.Height;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontAngle(tjs_int angle)\n{\n\tif(Font.Angle != angle)\n\t{\n\t\tangle = angle % 3600;\n\t\tif(angle < 0) angle += 3600;\n\t\tFont.Angle = angle;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetFontAngle() const\n{\n\treturn Font.Angle;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontBold(bool b)\n{\n\tif( (0!=(Font.Flags & TVP_TF_BOLD)) != b)\n\t{\n\t\tFont.Flags &= ~TVP_TF_BOLD;\n\t\tif(b) Font.Flags |= TVP_TF_BOLD;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFontBold() const\n{\n\treturn 0!=(Font.Flags & TVP_TF_BOLD);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontItalic(bool b)\n{\n\tif( (0!=(Font.Flags & TVP_TF_ITALIC)) != b)\n\t{\n\t\tFont.Flags &= ~TVP_TF_ITALIC;\n\t\tif(b) Font.Flags |= TVP_TF_ITALIC;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFontItalic() const\n{\n\treturn 0!=(Font.Flags & TVP_TF_ITALIC);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontStrikeout(bool b)\n{\n\tif( (0!=(Font.Flags & TVP_TF_STRIKEOUT)) != b)\n\t{\n\t\tFont.Flags &= ~TVP_TF_STRIKEOUT;\n\t\tif(b) Font.Flags |= TVP_TF_STRIKEOUT;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFontStrikeout() const\n{\n\treturn 0!=(Font.Flags & TVP_TF_STRIKEOUT);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontUnderline(bool b)\n{\n\tif( (0!=(Font.Flags & TVP_TF_UNDERLINE)) != b)\n\t{\n\t\tFont.Flags &= ~TVP_TF_UNDERLINE;\n\t\tif(b) Font.Flags |= TVP_TF_UNDERLINE;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFontUnderline() const\n{\n\treturn 0!=(Font.Flags & TVP_TF_UNDERLINE);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::SetFontFaceIsFileName(bool b)\n{\n\tif( (0!=(Font.Flags & TVP_TF_FONTFILE)) != b)\n\t{\n\t\tFont.Flags &= ~TVP_TF_FONTFILE;\n\t\tif(b) Font.Flags |= TVP_TF_FONTFILE;\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseLayer::GetFontFaceIsFileName() const\n{\n\treturn 0!=(Font.Flags & TVP_TF_FONTFILE);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetTextWidth(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getTextWidth\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetTextWidth(text);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_BaseLayer::GetTextHeight(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getTextHeight\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetTextHeight(text);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_BaseLayer::GetEscWidthX(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getEscWidthX\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetEscWidthX(text);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_BaseLayer::GetEscWidthY(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getEscWidthY\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetEscWidthY(text);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_BaseLayer::GetEscHeightX(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getEscHeightX\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetEscHeightX(text);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_BaseLayer::GetEscHeightY(const ttstr & text)\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getEscHeightY\"));\n\n\tApplyFont();\n\n\treturn MainImage->GetEscHeightY(text);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::GetFontGlyphDrawRect( const ttstr & text, tTVPRect& area )\n{\n\tif(!MainImage) TVPThrowExceptionMessage(TVPUnsupportedLayerType,\n\t\t\t\t\t\tTJS_W(\"getGlyphDrawRect\"));\n\n\tApplyFont();\n\n\tMainImage->GetFontGlyphDrawRect(text,area);\n}\n//---------------------------------------------------------------------------\n#if 0\nbool tTJSNI_BaseLayer::DoUserFontSelect(tjs_uint32 flags, const ttstr &caption,\n\t\tconst ttstr &prompt, const ttstr &samplestring)\n{\n\tApplyFont();\n\n\tbool b = MainImage->SelectFont(flags, caption, prompt, samplestring,\n\t\tFont.Face);\n\tif(b) FontChanged = true;\n\treturn b;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::GetFontList(tjs_uint32 flags, std::vector<ttstr> & list)\n{\n\tApplyFont();\n\n\tMainImage->GetFontList(flags, list);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::MapPrerenderedFont(const ttstr & storage)\n{\n\tApplyFont();\n\n\tMainImage->MapPrerenderedFont(storage);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UnmapPrerenderedFont()\n{\n\tApplyFont();\n\n\tMainImage->UnmapPrerenderedFont();\n}\n//---------------------------------------------------------------------------\nconst tTVPFont&  tTJSNI_BaseLayer::GetFont() const\n{\n\treturn Font;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseLayer::GetFontObjectNoAddRef()\n{\n\tif(FontObject) return FontObject;\n\n\t// create font object if the object is not yet created.\n\tif(!Owner) TVPThrowExceptionMessage(TVPLayerObjectIsNotProperlyConstructed);\n\tFontObject = TVPCreateFontObject(Owner);\n\n\treturn FontObject;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// updating management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UpdateTransDestinationOnSelfUpdate(const tTVPComplexRect &region)\n{\n\tif(TransDest && TransDest->InTransition && TransDest->TransSelfUpdate )\n\t{\n\t\t// transition, its update is performed by user code, is processing on\n\t\t// transition destination.\n\t\t// update the transition destination as transition source does.\n\t\tswitch(TransDest->TransUpdateType)\n\t\t{\n\t\tcase tutDivisibleFade:\n\t\t  {\n\t\t\ttTVPComplexRect cp(region);\n\t\t\tTransDest->Update(cp, true);\n\t\t\tbreak;\n\t\t  }\n\t\tdefault:\n\t\t\tTransDest->Update(true);\n\t\t\t\t// update entire area of the transition destination\n\t\t\t\t// because we cannot determine where the update affects.\n\t\t\tbreak;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UpdateTransDestinationOnSelfUpdate(const tTVPRect &rect)\n{\n\t// essentially the same as UpdateTransDestinationOnSelfUpdate(const tTVPComplexRect &region)\n\tif(TransDest && TransDest->InTransition && TransDest->TransSelfUpdate )\n\t{\n\t\tswitch(TransDest->TransUpdateType)\n\t\t{\n\t\tcase tutDivisibleFade:\n\t\t\tTransDest->Update(rect, true);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTransDest->Update(true);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UpdateChildRegion(tTJSNI_BaseLayer *child,\n\tconst tTVPComplexRect &region,\n\tbool tempupdate, bool targvisible, bool addtoprimary)\n{\n\t// called by child.  add update rect subscribed in \"rect\"\n\n\ttTVPRect cr;\n\tcr.left = cr.top = 0;\n\tcr.right = Rect.get_width(); cr.bottom = Rect.get_height();\n\n\ttTVPComplexRect converted;\n\tconverted.CopyWithOffsets(region, cr, child->Rect.left, child->Rect.top);\n\n\tif(!tempupdate)\n\t{\n\t\tif(GetCacheEnabled())\n\t\t{\n\t\t\t// caching is enabled\n\t\t\tif(targvisible)\n\t\t\t{\n\t\t\t\tCacheRecalcRegion.Or(converted);\n\t\t\t\tif(CacheRecalcRegion.GetCount() > TVP_CACHE_UNITE_LIMIT)\n\t\t\t\t\tCacheRecalcRegion.Unite();\n\t\t\t}\n\t\t}\n\t}\n\n\tif(Parent)\n\t{\n\t\tParent->UpdateChildRegion(this, converted, tempupdate, targvisible,\n\t\t\taddtoprimary);\n\t}\n\telse\n\t{\n\t\tif(addtoprimary) if(Manager) Manager->AddUpdateRegion(converted);\n\t}\n\n\tUpdateTransDestinationOnSelfUpdate(converted);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalUpdate(const tTVPRect &rect, bool tempupdate)\n{\n\ttTVPRect cr;\n\tcr.left = cr.top = 0;\n\tcr.right = Rect.get_width(); cr.bottom = Rect.get_height();\n\tif(!TVPIntersectRect(&cr, cr, rect)) return;\n\n\tif(!tempupdate)\n\t{\n\t\tif(GetCacheEnabled())\n\t\t{\n\t\t\t// caching is enabled\n\t\t\tCacheRecalcRegion.Or(cr);\n\t\t\tif(CacheRecalcRegion.GetCount() > TVP_CACHE_UNITE_LIMIT)\n\t\t\t\tCacheRecalcRegion.Unite();\n\t\t}\n\t}\n\n\tif(Parent)\n\t{\n\t\ttTVPComplexRect c;\n\t\tc.Or(cr);\n\t\tParent->UpdateChildRegion(this, c, tempupdate, GetVisible(),\n\t\t\tGetNodeVisible());\n\t}\n\telse\n\t{\n\t\tif(Manager) Manager->AddUpdateRegion(cr);\n\t}\n\n\tUpdateTransDestinationOnSelfUpdate(cr);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Update(tTVPComplexRect &rects, bool tempupdate)\n{\n\ttTVPRect cr;\n\tcr.left = cr.top = 0;\n\tcr.right = Rect.get_width(); cr.bottom = Rect.get_height();\n\trects.And(cr);\n\n\tif(!rects.GetCount()) return;\n\n\tif(!tempupdate)\n\t{\n\t\t// in case of tempupdate == false\n\t\t/*\n\t\t\ttempupdate == true indicates that the layer content is not changed, \n\t\t\tbut the layer need to be updated to the window.\n\t\t\tMainly used by transition update.\n\n\t\t\tThere is no need to update CacheRecalcRegion because the\n\t\t\tlayer content is not changed when tempupdate == true.\n\t\t*/\n\n\t\tif(GetCacheEnabled())\n\t\t{\n\t\t\t// caching is enabled\n\t\t\tCacheRecalcRegion.Or(rects);\n\t\t\tif(CacheRecalcRegion.GetCount() > TVP_CACHE_UNITE_LIMIT)\n\t\t\t\tCacheRecalcRegion.Unite();\n\t\t}\n\t}\n\n\tif(Parent)\n\t{\n\t\tParent->UpdateChildRegion(this, rects, tempupdate, GetVisible(),\n\t\t\tGetNodeVisible());\n\t}\n\telse\n\t{\n\t\tif(Manager) Manager->AddUpdateRegion(rects);\n\t}\n\n\tUpdateTransDestinationOnSelfUpdate(rects);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Update(const tTVPRect &rect, bool tempupdate)\n{\n\t// update part of the layer\n\ttTVPRect cr;\n\tcr.left = cr.top = 0;\n\tcr.right = Rect.get_width(); cr.bottom = Rect.get_height();\n\tif(!TVPIntersectRect(&cr, cr, rect)) return;\n\n\tInternalUpdate(cr, tempupdate);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Update(bool tempupdate)\n{\n\t// update entire of the layer\n\ttTVPRect rect;\n\trect.left = rect.top = 0;\n\trect.right = Rect.get_width();\n\trect.bottom = Rect.get_height();\n\tInternalUpdate(rect, tempupdate);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::ParentUpdate()\n{\n\t// called when layer moves\n\tif(Parent)\n\t{\n\t\ttTVPRect rect;\n\t\trect.left = rect.top = 0;\n\t\trect.right = Rect.get_width();\n\t\trect.bottom = Rect.get_height();\n\t\ttTVPComplexRect c;\n\t\tc.Or(rect);\n\t\tParent->UpdateChildRegion(this, c, false, GetVisible(),\n\t\t\tGetNodeVisible());\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::UpdateAllChildren(bool tempupdate)\n{\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\n\t\tchild->Update(tempupdate);\n\n\tTVP_LAYER_FOR_EACH_CHILD_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::BeforeCompletion()\n{\n\t// called before the drawing is processed\n\tif(InCompletion) return;\n\t\t// calling during completion more than once is not allowed\n\n\n\t// fire onPaint\n\tif(CallOnPaint)\n\t{\n\t\tCallOnPaint = false;\n\t\tstatic ttstr eventname(TJS_W(\"onPaint\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n\n\n\t// for transition\n\tif(InTransition)\n\t{\n\t\t// transition is processing\n\n\t\tif(DivisibleTransHandler)\n\t\t{\n\t\t\t// notify start of processing unit\n\t\t\ttjs_error er;\n\t\t\tif(TransSelfUpdate)\n\t\t\t{\n\t\t\t\t// set TransTick here if the transition is performed by user code;\n\t\t\t\t// otherwise the TransTick is to be set at\n\t\t\t\t// tTJSNI_BaseLayer::InvokeTransition\n\t\t\t\tTransTick = GetTransTick();\n\t\t\t}\n\t\t\ter = DivisibleTransHandler->StartProcess(TransTick);\n\t\t\tif(er != TJS_S_TRUE) StopTransitionByHandler();\n\t\t}\n\t\telse if(GiveUpdateTransHandler)\n\t\t{\n\t\t\t// not yet implemented\n\t\t}\n\t}\n\n\tif(InTransition && TransWithChildren &&\n\t\tTransUpdateType == tutDivisible)\n\t{\n\t\t// complete all area of the layer\n\t\tInTransition = false; // cheat!!!\n\t\tTransDrawable.Src1Bmp = Complete();\n\t\tInTransition = true;\n\n\t\tif(TransSrc) TransDrawable.Src2Bmp = TransSrc->Complete();\n\t}\n\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\n\t\tchild->BeforeCompletion();\n\n\tTVP_LAYER_FOR_EACH_CHILD_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::AfterCompletion()\n{\n\t// called after the drawing is processed\n\tif(InCompletion) return;\n\t\t// calling during completion more than once is not allowed\n\n\tif(InTransition)\n\t{\n\t\t// transition is processing\n\t\tif(DivisibleTransHandler)\n\t\t{\n\t\t\t// notify start of processing unit\n\t\t\ttjs_error er;\n\t\t\ter = DivisibleTransHandler->EndProcess();\n\t\t\tif(er != TJS_S_TRUE) StopTransitionByHandler();\n\t\t}\n\t\telse if(GiveUpdateTransHandler)\n\t\t{\n\t\t\t// not yet implemented\n\t\t}\n\n\t}\n\n\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\n\t\tchild->AfterCompletion();\n\n\tTVP_LAYER_FOR_EACH_CHILD_END\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::QueryUpdateExcludeRect(tTVPRect &rect, bool parentvisible)\n{\n\t// query completely opaque area\n\n\t// convert to local coordinates\n\trect.left -= Rect.left;\n\trect.right -= Rect.left;\n\trect.top -= Rect.top;\n\trect.bottom -= Rect.top;\n\n\t// recur to children\n\tparentvisible = parentvisible && Visible &&\n\t\t(DisplayType == ltOpaque || DisplayType == ltAlpha || DisplayType == ltAddAlpha || DisplayType == ltPsNormal) &&\n\t\tOpacity == 255; // fixed 2004/01/09 W.Dee\n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BACKWARD_BEGIN(child)\n\n\t\tchild->QueryUpdateExcludeRect(rect, parentvisible);\n     \n\tTVP_LAYER_FOR_EACH_CHILD_NOLOCK_BACKWARD_END\n\n\t// copy current update exclude rect\n\tif(parentvisible) UpdateExcludeRect = rect; else UpdateExcludeRect.clear();\n\n\t// convert to parent's coordinates\n\trect.left += Rect.left;\n\trect.right += Rect.left;\n\trect.top += Rect.top;\n\trect.bottom += Rect.top;\n\n\t// check visibility & opacity\n\tif (parentvisible && (DisplayType == ltOpaque || (MainImage && MainImage->IsOpaque())) && Opacity == 255)\n\t{\n\t\tif(rect.is_empty())\n\t\t{\n\t\t\trect = Rect;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!TVPIntersectRect(&rect, rect, Rect))\n\t\t\t\trect.clear();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::BltImage(iTVPBaseBitmap *dest, tTVPLayerType destlayertype,\n\ttjs_int destx,\n    tjs_int desty, iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\ttTVPLayerType drawtype, tjs_int opacity, bool hda)\n{\n\t// draw src to dest according with layer type\n/*\n\t// do the effect\n\ttTVPRect destrect;\n\tdestrect.left = destx;\n\tdestrect.top = desty;\n\tdestrect.right = destx + srcrect.get_width();\n\tdestrect.bottom = desty + srcrect.get_height();\n\tEffectImage(dest, destrect);\n*/\n\n\t// blt to the target\n\ttTVPBBBltMethod met;\n\tswitch(drawtype)\n\t{\n\tcase ltBinder:\n\t\t// no action\n\t\treturn;\n\n\tcase ltOpaque: // formerly ltCoverRect\n\t\t// copy\n\t\tif(TVPIsTypeUsingAlpha(destlayertype))\n\t\t\tmet = bmCopyOnAlpha;\n\t\telse if(TVPIsTypeUsingAddAlpha(destlayertype))\n\t\t\tmet = bmCopyOnAddAlpha;\n\t\telse\n\t\t\tmet = bmCopy;\n\t\tbreak;\n\n\tcase ltAlpha: // formerly ltTransparent\n\t\t// alpha blend\n\t\tif(TVPIsTypeUsingAlpha(destlayertype))\n\t\t\tmet = bmAlphaOnAlpha;\n\t\telse if(TVPIsTypeUsingAddAlpha(destlayertype))\n\t\t\tmet = bmAlphaOnAddAlpha;\n\t\telse\n\t\t\tmet = bmAlpha;\n\t\tbreak;\n\n\tcase ltAdditive:\n\t\t// additive blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\t\t// hda = true if destination has alpha\n\t\t\t// ( preserving mask )\n\t\tmet = bmAdd;\n\t\tbreak;\n\n\tcase ltSubtractive:\n\t\t// subtractive blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmSub;\n\t\tbreak;\n\n\tcase ltMultiplicative:\n\t\t// multiplicative blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmMul;\n\t\tbreak;\n\n\tcase ltDodge:\n\t\t// color dodge ( \"Ooi yaki\" in Japanese )\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmDodge;\n\t\tbreak;\n\n\tcase ltDarken:\n\t\t// darken blend (select lower luminosity)\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmDarken;\n\t\tbreak;\n\n\tcase ltLighten:\n\t\t// lighten blend (select higher luminosity)\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmLighten;\n\t\tbreak;\n\n\tcase ltScreen:\n\t\t// screen multiplicative blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmScreen;\n\t\tbreak;\n\n\tcase ltAddAlpha:\n\t\t// alpha blend\n\t\tif(TVPIsTypeUsingAlpha(destlayertype))\n\t\t\tmet = bmAddAlphaOnAlpha;\n\t\telse if(TVPIsTypeUsingAddAlpha(destlayertype))\n\t\t\tmet = bmAddAlphaOnAddAlpha;\n\t\telse\n\t\t\tmet = bmAddAlpha;\n\t\tbreak;\n\n\tcase ltPsNormal:\n\t\t// Photoshop compatible normal blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsNormal;\n\t\tbreak;\n\n\tcase ltPsAdditive:\n\t\t// Photoshop compatible additive blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsAdditive;\n\t\tbreak;\n\n\tcase ltPsSubtractive:\n\t\t// Photoshop compatible subtractive blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsSubtractive;\n\t\tbreak;\n\n\tcase ltPsMultiplicative:\n\t\t// Photoshop compatible multiplicative blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsMultiplicative;\n\t\tbreak;\n\n\tcase ltPsScreen:\n\t\t// Photoshop compatible screen blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsScreen;\n\t\tbreak;\n\n\tcase ltPsOverlay:\n\t\t// Photoshop compatible overlay blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsOverlay;\n\t\tbreak;\n\n\tcase ltPsHardLight:\n\t\t// Photoshop compatible hard light blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsHardLight;\n\t\tbreak;\n\n\tcase ltPsSoftLight:\n\t\t// Photoshop compatible soft light blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsSoftLight;\n\t\tbreak;\n\n\tcase ltPsColorDodge:\n\t\t// Photoshop compatible color dodge blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsColorDodge;\n\t\tbreak;\n\n\tcase ltPsColorDodge5:\n\t\t// Photoshop 5.x compatible color dodge blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsColorDodge5;\n\t\tbreak;\n\n\tcase ltPsColorBurn:\n\t\t// Photoshop compatible color burn blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsColorBurn;\n\t\tbreak;\n\n\tcase ltPsLighten:\n\t\t// Photoshop compatible compare (lighten) blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsLighten;\n\t\tbreak;\n\n\tcase ltPsDarken:\n\t\t// Photoshop compatible compare (darken) blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsDarken;\n\t\tbreak;\n\n\tcase ltPsDifference:\n\t\t// Photoshop compatible difference blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsDifference;\n\t\tbreak;\n\n\tcase ltPsDifference5:\n\t\t// Photoshop 5.x compatible difference blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsDifference5;\n\t\tbreak;\n\n\tcase ltPsExclusion:\n\t\t// Photoshop compatible exclusion blend\n\t\thda = hda || TVPIsTypeUsingAlphaChannel(destlayertype);\n\t\tmet = bmPsExclusion;\n\t\tbreak;\n\n\tdefault:\n\t\treturn;\n\t}\n\n\tdest->Blt(destx, desty, src, srcrect, met, opacity, hda);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DrawSelf(tTVPDrawable *target, tTVPRect &pr,\n\ttTVPRect &cr)\n{\n\tif(!MainImage)\n\t{\n\t\tif(DisplayType == ltOpaque)\n\t\t{\n\t\t\t// fill destination with specified color\n\t\t\ttTVPBaseTexture *temp = tTVPTempBitmapHolder::GetTemp(\n\t\t\t\t\t\t\t\tcr.get_width(),\n\t\t\t\t\t\t\t\tcr.get_height());\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// do transition\n\t\t\t\ttTVPRect bitmaprect = cr;\n\t\t\t\tbitmaprect.set_offsets(0, 0);\n\t\t\t\tCopySelf(temp, 0, 0, bitmaprect); // this fills temp with neutral color\n\n\t\t\t\t// send completion message\n\t\t\t\ttarget->DrawCompleted(pr, temp, bitmaprect, DisplayType, Opacity);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\ttTVPTempBitmapHolder::FreeTemp();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\ttTVPTempBitmapHolder::FreeTemp();\n\t\t}\n\t\treturn;\n\t}\n\n\t// draw self MainImage(only) to target\n\tcr.add_offsets(-ImageLeft, -ImageTop);\n\n\tif(InTransition && !TransWithChildren && DivisibleTransHandler)\n\t{\n\t\t// transition without children\n\n\t\t// allocate temporary bitmap\n\t\ttTVPBaseTexture *temp = tTVPTempBitmapHolder::GetTemp(\n\t\t\t\t\t\t\tcr.get_width(),\n\t\t\t\t\t\t\tcr.get_height());\n\t\ttry\n\t\t{\n\t\t\t// do transition\n\t\t\ttTVPRect bitmaprect = cr;\n\t\t\tbitmaprect.set_offsets(0, 0);\n\t\t\tDoDivisibleTransition(temp, 0, 0, cr);\n\n\t\t\t// send completion message\n\t\t\ttarget->DrawCompleted(pr, temp, bitmaprect, DisplayType, Opacity);\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\ttTVPTempBitmapHolder::FreeTemp();\n\t\t\tthrow;\n\t\t}\n\t\ttTVPTempBitmapHolder::FreeTemp();\n\t}\n\telse\n\t{\n\t\ttarget->DrawCompleted(pr, MainImage, cr, DisplayType, Opacity);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CopySelfForRect(iTVPBaseBitmap *dest, tjs_int destx, tjs_int desty,\n\tconst tTVPRect &srcrect)\n{\n\t// copy self image to the target\n\ttTVPRect cr = srcrect;\n\tcr.add_offsets(-ImageLeft, -ImageTop);\n\n\tif(InTransition && !TransWithChildren && DivisibleTransHandler)\n\t{\n\t\t// transition without children\n\t\tDoDivisibleTransition(dest, destx, desty, cr);\n\t}\n\telse\n\t{\n\t\tif(MainImage)\n\t\t{\n\t\t\tdest->CopyRect(destx, desty, MainImage, cr);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// main image does not exist\n\t\t\t// fill destination with TransparentColor\n\t\t\t// (this need to be transparent, so we do not use NeutralColor which can be\n\t\t\t//  set by the user unless the DisplayType is ltOpaque)\n\t\t\tdest->Fill(tTVPRect(destx, desty,\n\t\t\t\t\tdestx + cr.get_width(), desty + cr.get_height()),\n\t\t\t\t\tDisplayType == ltOpaque ? NeutralColor : TransparentColor);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CopySelf(iTVPBaseBitmap *dest, tjs_int destx, tjs_int desty,\n\tconst tTVPRect &r)\n{\n\tconst tTVPRect &uer = UpdateExcludeRect;\n\tif(uer.is_empty())\n\t{\n\t\tCopySelfForRect(dest, destx, desty, r);\n\t}\n\telse\n\t{\n\t\tif(uer.top <= r.top && uer.bottom >= r.bottom)\n\t\t{\n\t\t\tif(uer.left > r.left && uer.right < r.right)\n\t\t\t{\n\t\t\t\t// split into two\n\t\t\t\ttTVPRect r2 = r;\n\t\t\t\tr2.right = uer.left;\n\t\t\t\tCopySelfForRect(dest, destx, desty, r2);\n\t\t\t\tr2.right = r.right;\n\t\t\t\tr2.left = uer.right;\n\t\t\t\tCopySelfForRect(dest, destx + (r2.left - r.left), desty, r2);\n\t\t\t}\n\t\t\telse if(r.left >= uer.left && r.right <= uer.right)\n\t\t\t{\n\t\t\t\t;// nothing to do\n\t\t\t}\n\t\t\telse if(r.right <= uer.left || r.left >= uer.right)\n\t\t\t{\n\t\t\t\tCopySelfForRect(dest, destx, desty, r);\n\t\t\t}\n\t\t\telse if(r.right > uer.left && r.right <= uer.right)\n\t\t\t{\n\t\t\t\ttTVPRect r2 = r;\n\t\t\t\tr2.right = uer.left;\n\t\t\t\tCopySelfForRect(dest, destx, desty, r2);\n\t\t\t}\n\t\t\telse if(r.left >= uer.left && r.left < uer.left)\n\t\t\t{\n\t\t\t\ttTVPRect r2 = r;\n\t\t\t\tr2.left = uer.right;\n\t\t\t\tCopySelfForRect(dest, destx + (r2.left - r.left), desty, r2);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tCopySelfForRect(dest, destx, desty, r);\n\t\t\t}\n\n\t\t}\n\t\telse\n\t\t{\n\t\t\tCopySelfForRect(dest, destx, desty, r);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::EffectImage(iTVPBaseBitmap *dest, const tTVPRect & destrect)\n{\n\tif(Type == ltFilter)\n\t{\n\t\t// TODO: do filtering\n\t}\n\telse if(Type == ltEffect)\n\t{\n\t\t// TODO: do effect\n\t}\n}\nvoid tTJSNI_BaseLayer::Draw_GPU(tTVPDrawable *target, int x, int y, const tTVPRect &r, bool visiblecheck) {\n    if(visiblecheck && !IsSeen()) return;\n\n\ttTVPRect rect;\n    if(!TVPIntersectRect(&rect, r, Rect)) return; // no intersection\n\tx += rect.left - r.left;\n\ty += rect.top - r.top;\n\n\ttTVPRect rctar(rect);\n\trctar.set_offsets(x, y);\n\n    CurrentDrawTarget = target;\n\n    ParentRectToChildRect(rect); // to this layer based axis\n\n\t// process drawing\n\tDirectTransferToParent = false;\n\n\t// caching is not enabled\n\n\tif (Opacity < 255 || (InTransition && TransWithChildren))\n\t{\n\t\t// rearrange pipe line for transition\n\t\tif (InTransition && TransWithChildren) {\n\t\t\tTransDrawable.Init(this, target);\n\t\t\ttarget = &TransDrawable;\n\t\t}\n\t\tif (GetVisibleChildrenCount() == 0) {\n\t\t\tDrawSelf(target, rctar, rect);\n\t\t} else {\n\t\t\t// rearrange pipe line for transition\n\t\t\tbool useTemp = false;\n\t\t\tif (GetCacheEnabled()) {\n\t\t\t\tUpdateBitmapForChild = CacheBitmap;\n\t\t\t} else {\n\t\t\t\tuseTemp = true;\n\t\t\t\tUpdateBitmapForChild = tTVPTempBitmapHolder::GetTemp(\n\t\t\t\t\tRect.get_width(),\n\t\t\t\t\tRect.get_height());\n\t\t\t}\n\t\t\ttTVPRect rectForChild(0, 0, Rect.get_width(), Rect.get_height());\n\n\t\t\t// copy self image to UpdateBitmapForChild\n\t\t\tif (MainImage != NULL) {\n// \t\t\t\tif (UpdateExcludeRect.top <= rect.top && UpdateExcludeRect.bottom >= rect.bottom &&\n// \t\t\t\t\trect.left >= UpdateExcludeRect.left && rect.right <= UpdateExcludeRect.right) {\n// \t\t\t\t} else\n\t\t\t\t\tCopySelfForRect(UpdateBitmapForChild, 0, 0, rectForChild); // transfer self image\n\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\t\t{\n\t\t\t\t// for each child...\n\n\t\t\t\t// visible check\n\t\t\t\tif (!child->Visible) continue;\n\n\t\t\t\t// intersection check\n\t\t\t\tif (!TVPIntersectRect(&UpdateRectForChild, rectForChild, child->Rect))\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// setup UpdateOfsX/Y UpdateRectForChildOfsX/Y\n\t\t\t\tUpdateOfsX = 0;\n\t\t\t\tUpdateOfsY = 0;\n \t\t\t\tUpdateRectForChildOfsX = UpdateRectForChild.left - child->Rect.left;\n \t\t\t\tUpdateRectForChildOfsY = UpdateRectForChild.top - child->Rect.top;\n\n\t\t\t\t// call children's \"Draw\" method\n\t\t\t\tchild->Draw_GPU((tTVPDrawable*)this, UpdateRectForChild.left, UpdateRectForChild.top, UpdateRectForChild);\n\t\t\t}\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_END\n\t\t\t// rect.set_offsets(0, 0);\n\t\t\ttarget->DrawCompleted(rctar, UpdateBitmapForChild, rect, DisplayType, Opacity);\n\t\t\tif (useTemp) tTVPTempBitmapHolder::FreeTemp();\n\t\t}\n\t} else {\n\t\tif (GetVisibleChildrenCount() == 0) {\n\t\t\tDrawSelf(target, rctar, rect);\n\t\t} else {\n\t\t\tDrawnRegion.Clear();\n\t\t\t// send completion message to the target\n\n// \t\t\tif (UpdateExcludeRect.top <= rect.top && UpdateExcludeRect.bottom >= rect.bottom &&\n// \t\t\t\trect.left >= UpdateExcludeRect.left && rect.right <= UpdateExcludeRect.right) {\n// \t\t\t} else \n\t\t\t{\n\t\t\t\ttTVPRect rc(rect);\n\t\t\t\tDrawSelf(target, rctar, rc);\n\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\t\t{\n\t\t\t\t// for each child...\n\n\t\t\t\t// visible check\n\t\t\t\tif (!child->Visible) continue;\n\n\t\t\t\t// intersection check\n\t\t\t\ttTVPRect chrect;\n\t\t\t\tif (!TVPIntersectRect(&chrect, rect, child->Rect))\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// call children's \"Draw\" method\n\t\t\t\tchild->Draw_GPU(target, x, y, rect);\n\t\t\t}\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_END\n\t\t}\n\t}\n\n    CurrentDrawTarget = NULL;\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalDrawNoCache_CPU(tTVPDrawable *target, const tTVPRect &rect)\n{\n    bool totalopaque = (DisplayType == ltOpaque && Opacity == 255);\n    if(GetVisibleChildrenCount() == 0)\n    {\n        // no visible children; no action needed\n        tTVPRect pr = rect;\n        pr.add_offsets(Rect.left, Rect.top);\n        tTVPRect cr = rect;\n        DrawSelf(target, pr, cr);\n    }\n    else\n    {\n        // has at least one visible child\n        const tTVPComplexRect & overlapped = GetOverlappedRegion();\n        const tTVPComplexRect & exposed = GetExposedRegion();\n\n        // process overlapped region\n        // clear DrawnRegion\n        tTVPComplexRect::tIterator it;\n\n\n        DrawnRegion.Clear();\n\n\n        it = overlapped.GetIterator();\n        while(it.Step())\n        {\n            tTVPRect cr(*it);\n\n            // intersection check\n            if(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\n            tTVPRect updaterectforchild;\n            bool tempalloc = false;\n\n            // setup UpdateBitmapForChild and \"updaterectforchild\"\n            if(totalopaque)\n            {\n                // this layer is totally opaque\n                UpdateBitmapForChild = target->GetDrawTargetBitmap(\n                    cr, updaterectforchild);\n            }\n            else\n            {\n                // this layer is transparent\n\n                // retrieve temporary bitmap\n                UpdateBitmapForChild = tTVPTempBitmapHolder::GetTemp(\n                    cr.get_width(),\n                    cr.get_height());\n                tempalloc = true;\n                updaterectforchild.left = 0;\n                updaterectforchild.top = 0;\n                updaterectforchild.right = cr.get_width();\n                updaterectforchild.bottom = cr.get_height();\n            }\n\n            try\n            {\n                // copy self image to the target\n                CopySelf(UpdateBitmapForChild,\n                    updaterectforchild.left, updaterectforchild.top, cr);\n\n                TVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n                {\n                    // for each child...\n\n                    // visible check\n                    if(!child->Visible) continue;\n\n                    // intersection check\n                    tTVPRect chrect;\n                    if(!TVPIntersectRect(&chrect, cr, child->Rect))\n                        continue;\n\n                    // setup UpdateRectForChild\n                    tjs_int ox = chrect.left - cr.left;\n                    tjs_int oy = chrect.top - cr.top;\n\n                    UpdateRectForChild = updaterectforchild;\n                    UpdateRectForChild.add_offsets(ox, oy);\n                    UpdateRectForChildOfsX = chrect.left - child->Rect.left;\n                    UpdateRectForChildOfsY = chrect.top - child->Rect.top;\n\n                    // setup UpdateOfsX, UpdateOfsY\n                    UpdateOfsX = cr.left - updaterectforchild.left;\n                    UpdateOfsY = cr.top - updaterectforchild.top;\n\n                    // call children's \"Draw\" method\n                    child->Draw((tTVPDrawable*)this, chrect, true);\n                }\n                TVP_LAYER_FOR_EACH_CHILD_END\n\n            }\n            catch(...)\n            {\n                if(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n                throw;\n            }\n\n            // send completion message to the target\n            if(DisplayType != ltBinder)\n            {\n                tTVPRect pr = cr;\n                pr.add_offsets(Rect.left, Rect.top);\n                target->DrawCompleted(pr, UpdateBitmapForChild, updaterectforchild,\n                    DisplayType, Opacity);\n            }\n\n            // release temporary bitmap\n            if(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n\n\n        } // overlapped region\n\n\n        // process exposed region\n        DirectTransferToParent = true; // this flag is used only when MainImage == NULL\n\n\n        it = exposed.GetIterator();\n        while(it.Step())\n        {\n            tTVPRect cr(*it);\n\n            // intersection check\n            if(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n            if(MainImage != NULL)\n            {\n                // send completion message to the target\n                tTVPRect pr = cr;\n                pr.add_offsets(Rect.left, Rect.top);\n                DrawSelf(target, pr, cr);\n            }\n            else\n            {\n                // call children's \"Draw\" method\n\n                tTVPRect cr(*it);\n\n                // intersection check\n                if(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\n                tTVPRect updaterectforchild;\n\n                TVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n                {\n                    // for each child...\n\n                    // visible check\n                    if(!child->Visible) continue;\n\n                    // intersection check\n                    tTVPRect chrect;\n                    if(!TVPIntersectRect(&chrect, cr, child->Rect))\n                        continue;\n\n                    // call children's \"Draw\" method\n                    child->Draw((tTVPDrawable*)this, chrect, true);\n                }\n                TVP_LAYER_FOR_EACH_CHILD_END\n            }\n        }\n        DirectTransferToParent = false;\n    } // has visible children/no visible children\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::Draw(tTVPDrawable *target, const tTVPRect &r, bool visiblecheck)\n{\n\t// process updating pipe line.\n\t// draw the layer content to \"target\".\n\t// \"r\" is a rectangle to be drawn in the parent's coordinates.\n\t// parent has responsibility for piling the image returned from children.\n\n\n\tif(visiblecheck && !IsSeen()) return;\n\n\ttTVPRect rect = r;\n\tif(!TVPIntersectRect(&rect, rect, Rect)) return; // no intersection\n\n\n\tCurrentDrawTarget = target;\n\n\tParentRectToChildRect(rect);\n\n\tif(InTransition && TransWithChildren)\n\t{\n\t\t// rearrange pipe line for transition\n\t\tTransDrawable.Init(this, target);\n\t\ttarget = &TransDrawable;\n\t}\n\n\t// process drawing\n\tDirectTransferToParent = false;\n\tbool totalopaque = (DisplayType == ltOpaque && Opacity == 255);\n\n\tif(GetCacheEnabled() &&\n\t\t!(InTransition && !TransWithChildren && DivisibleTransHandler))\n\t{\n\t\t// process must-recalc region\n\n\t\ttTVPComplexRect::tIterator it = CacheRecalcRegion.GetIterator();\n\t\twhile(it.Step())\n\t\t{\n\t\t\ttTVPRect cr(*it);\n\n\t\t\t// intersection check\n\t\t\tif(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\t\t\t// clear DrawnRegion\n\t\t\tDrawnRegion.Clear();\n\n\t\t\t// setup UpdateBitmapForChild\n\t\t\tUpdateBitmapForChild = CacheBitmap;\n\n\t\t\t// copy self image to UpdateBitmapForChild\n\t\t\tif(MainImage != NULL)\n\t\t\t{\n\t\t\t\tCopySelf(UpdateBitmapForChild,\n\t\t\t\t\t\tcr.left,\n\t\t\t\t\t\tcr.top, cr); // transfer self image\n\t\t\t}\n\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\t\t{\n\t\t\t\t// for each child...\n\n\t\t\t\t// intersection check\n\t\t\t\tif(!TVPIntersectRect(&UpdateRectForChild, cr, child->Rect))\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// setup UpdateOfsX/Y UpdateRectForChildOfsX/Y\n\t\t\t\tUpdateOfsX = 0;\n\t\t\t\tUpdateOfsY = 0;\n\t\t\t\tUpdateRectForChildOfsX = UpdateRectForChild.left - child->Rect.left;\n\t\t\t\tUpdateRectForChildOfsY = UpdateRectForChild.top - child->Rect.top;\n\n\t\t\t\t// call children's \"Draw\" method\n\t\t\t\tchild->Draw((tTVPDrawable*)this, UpdateRectForChild, true);\n\t\t\t}\n\t\t\tTVP_LAYER_FOR_EACH_CHILD_END\n\n\t\t\t// special optimazation for MainImage == NULL\n\n\t\t\tif(MainImage == NULL)\n\t\t\t{\n\t\t\t\ttTVPComplexRect nr;\n\t\t\t\tnr.Or(cr);\n\t\t\t\tnr.Sub(DrawnRegion);\n\t\t\t\ttTVPComplexRect::tIterator it = nr.GetIterator();\n\t\t\t\twhile(it.Step())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(*it);\n\t\t\t\t\tCopySelf(UpdateBitmapForChild,\n\t\t\t\t\t\t\tr.left,\n\t\t\t\t\t\t\tr.top, r);\n\t\t\t\t\t\t\t// CopySelf of MainImage == NULL actually\n\t\t\t\t\t\t\t// fills target rectangle with full transparency\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tCacheRecalcRegion.Sub(rect);\n\n\t\tif(CacheRecalcRegion.GetCount() > TVP_CACHE_UNITE_LIMIT)\n\t\t\tCacheRecalcRegion.Unite();\n\n\t\t// at this point, the cache bitmap should be completed\n\n\t\t// send completion message to the target\n\t\ttTVPRect pr = rect;\n\t\tpr.add_offsets(Rect.left, Rect.top);\n\t\ttarget->DrawCompleted(pr, CacheBitmap, rect, DisplayType, Opacity);\n\t}\n\telse\n\t{\n\t\t// caching is not enabled\n\n\t\tif(GetVisibleChildrenCount() == 0)\n\t\t{\n\t\t\t// no visible children; no action needed\n\t\t\ttTVPRect pr = rect;\n\t\t\tpr.add_offsets(Rect.left, Rect.top);\n\t\t\ttTVPRect cr = rect;\n\t\t\tDrawSelf(target, pr, cr);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// has at least one visible child\n\t\t\tconst tTVPComplexRect & overlapped = GetOverlappedRegion();\n\t\t\tconst tTVPComplexRect & exposed = GetExposedRegion();\n\n\t\t\t// process overlapped region\n\t\t\t// clear DrawnRegion\n\t\t\ttTVPComplexRect::tIterator it;\n\n\n\t\t\tDrawnRegion.Clear();\n\n\n\t\t\tit = overlapped.GetIterator();\n\t\t\twhile(it.Step())\n\t\t\t{\n\t\t\t\ttTVPRect cr(*it);\n\n\t\t\t\t// intersection check\n\t\t\t\tif(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\n\t\t\t\ttTVPRect updaterectforchild;\n\t\t\t\tbool tempalloc = false;\n\n\t\t\t\t// setup UpdateBitmapForChild and \"updaterectforchild\"\n\t\t\t\tif(totalopaque)\n\t\t\t\t{\n\t\t\t\t\t// this layer is totally opaque\n\t\t\t\t\tUpdateBitmapForChild = target->GetDrawTargetBitmap(\n\t\t\t\t\t\tcr, updaterectforchild);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// this layer is transparent\n\n\t\t\t\t\t// retrieve temporary bitmap\n\t\t\t\t\tUpdateBitmapForChild = tTVPTempBitmapHolder::GetTemp(\n\t\t\t\t\t\t\tcr.get_width(),\n\t\t\t\t\t\t\tcr.get_height());\n\t\t\t\t\ttempalloc = true;\n\t\t\t\t\tupdaterectforchild.left = 0;\n\t\t\t\t\tupdaterectforchild.top = 0;\n\t\t\t\t\tupdaterectforchild.right = cr.get_width();\n\t\t\t\t\tupdaterectforchild.bottom = cr.get_height();\n\t\t\t\t}\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// copy self image to the target\n\t\t\t\t\tCopySelf(UpdateBitmapForChild,\n\t\t\t\t\t\tupdaterectforchild.left, updaterectforchild.top, cr);\n\n\t\t\t\t\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\t\t\t\t{\n\t\t\t\t\t\t// for each child...\n\n\t\t\t\t\t\t// visible check\n\t\t\t\t\t\tif(!child->Visible) continue;\n\n\t\t\t\t\t\t// intersection check\n\t\t\t\t\t\ttTVPRect chrect;\n\t\t\t\t\t\tif(!TVPIntersectRect(&chrect, cr, child->Rect))\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t// setup UpdateRectForChild\n\t\t\t\t\t\ttjs_int ox = chrect.left - cr.left;\n\t\t\t\t\t\ttjs_int oy = chrect.top - cr.top;\n\n\t\t\t\t\t\tUpdateRectForChild = updaterectforchild;\n\t\t\t\t\t\tUpdateRectForChild.add_offsets(ox, oy);\n\t\t\t\t\t\tUpdateRectForChildOfsX = chrect.left - child->Rect.left;\n\t\t\t\t\t\tUpdateRectForChildOfsY = chrect.top - child->Rect.top;\n\n\t\t\t\t\t\t// setup UpdateOfsX, UpdateOfsY\n\t\t\t\t\t\tUpdateOfsX = cr.left - updaterectforchild.left;\n\t\t\t\t\t\tUpdateOfsY = cr.top - updaterectforchild.top;\n\n\t\t\t\t\t\t// call children's \"Draw\" method\n\t\t\t\t\t\tchild->Draw((tTVPDrawable*)this, chrect, true);\n\t\t\t\t\t}\n\t\t\t\t\tTVP_LAYER_FOR_EACH_CHILD_END\n\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\tif(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\n\t\t\t\t// send completion message to the target\n\t\t\t\tif(DisplayType != ltBinder)\n\t\t\t\t{\n\t\t\t\t\ttTVPRect pr = cr;\n\t\t\t\t\tpr.add_offsets(Rect.left, Rect.top);\n\t\t\t\t\ttarget->DrawCompleted(pr, UpdateBitmapForChild, updaterectforchild,\n\t\t\t\t\t\tDisplayType, Opacity);\n\t\t\t\t}\n\n\t\t\t\t// release temporary bitmap\n\t\t\t\tif(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n\n\n\t\t\t} // overlapped region\n\n\n\t\t\t// process exposed region\n\t\t\tDirectTransferToParent = true; // this flag is used only when MainImage == NULL\n\n\n\t\t\tit = exposed.GetIterator();\n\t\t\twhile(it.Step())\n\t\t\t{\n\t\t\t\ttTVPRect cr(*it);\n\n\t\t\t\t// intersection check\n\t\t\t\tif(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\t\t\t\tif(MainImage != NULL)\n\t\t\t\t{\n\t\t\t\t\t// send completion message to the target\n\t\t\t\t\ttTVPRect pr = cr;\n\t\t\t\t\tpr.add_offsets(Rect.left, Rect.top);\n\t\t\t\t\tDrawSelf(target, pr, cr);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// call children's \"Draw\" method\n\n\t\t\t\t\ttTVPRect cr(*it);\n\n\t\t\t\t\t// intersection check\n\t\t\t\t\tif(!TVPIntersectRect(&cr, cr, rect)) continue;\n\n\n\t\t\t\t\ttTVPRect updaterectforchild;\n\n\t\t\t\t\tTVP_LAYER_FOR_EACH_CHILD_BEGIN(child)\n\t\t\t\t\t{\n\t\t\t\t\t\t// for each child...\n\n\t\t\t\t\t\t// visible check\n\t\t\t\t\t\tif(!child->Visible) continue;\n\n\t\t\t\t\t\t// intersection check\n\t\t\t\t\t\ttTVPRect chrect;\n\t\t\t\t\t\tif(!TVPIntersectRect(&chrect, cr, child->Rect))\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t// call children's \"Draw\" method\n\t\t\t\t\t\tchild->Draw((tTVPDrawable*)this, chrect, true);\n\t\t\t\t\t}\n\t\t\t\t\tTVP_LAYER_FOR_EACH_CHILD_END\n\n\t\t\t\t}\n\t\t\t}\n\t\t\tDirectTransferToParent = false;\n\t\t} // has visible children/no visible children\n\t} // cache enabled/disabled\n\n\tCurrentDrawTarget = NULL;\n}\n//---------------------------------------------------------------------------\ntTVPBaseTexture * tTJSNI_BaseLayer::GetDrawTargetBitmap(const tTVPRect &rect,\n\ttTVPRect &cliprect)\n{\n\t// called from children to get the image buffer drawn to.\n\tif(DisplayType == ltBinder || (MainImage == NULL && DirectTransferToParent))\n\t{\n\t\ttTVPRect _rect(rect);\n\t\t_rect.add_offsets(Rect.left, Rect.top);\n\t\ttTVPBaseTexture * bmp = CurrentDrawTarget->GetDrawTargetBitmap(_rect, cliprect);\n\t\treturn bmp;\n\t}\n\ttjs_int w = rect.get_width();\n\ttjs_int h = rect.get_height();\n\tif(UpdateRectForChild.get_width() < w || UpdateRectForChild.get_height() < h)\n\t\tTVPThrowExceptionMessage(TVPInternalError);\n\tcliprect = UpdateRectForChild;\n\tcliprect.add_offsets(rect.left - UpdateRectForChildOfsX,\n\t\trect.top - UpdateRectForChildOfsY);\n\treturn UpdateBitmapForChild;\n}\n//---------------------------------------------------------------------------\ntTVPLayerType tTJSNI_BaseLayer::GetTargetLayerType()\n{\n\tif(DisplayType == ltBinder) // return parent's display layer type when DisplayType == ltBinder\n\t\treturn Parent ? Parent->DisplayType : ltOpaque;\n\treturn DisplayType;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DrawCompleted(const tTVPRect &destrect,\n\ttTVPBaseTexture *bmp,\n\tconst tTVPRect &cliprect,\n\ttTVPLayerType type, tjs_int opacity)\n{\n\t// called from children to notify that the image drawing is completed.\n\t// blend the image to the target unless bmp is the same as UpdateBitmapForChild.\n\tif(DisplayType == ltBinder || (MainImage == NULL && DirectTransferToParent))\n\t{\n\t\ttTVPRect _destrect(destrect);\n\t\ttTVPRect _cliprect(cliprect);\n\t\t_destrect.add_offsets(Rect.left, Rect.top);\n\t\tCurrentDrawTarget->DrawCompleted(_destrect, bmp, _cliprect, type, opacity);\n\t\treturn;\n\t}\n\n\tif(bmp != UpdateBitmapForChild)\n\t{\n\t\tif(MainImage == NULL)\n\t\t{\n\t\t\t// special optimization for MainImage == NULL\n\t\t\t// (all the layer face is treated as transparent)\n\t\t\ttTVPComplexRect nr; // new region\n\t\t\tnr.Or(destrect);\n\t\t\tnr.Sub(DrawnRegion);\n\t\t\ttTVPComplexRect opr; // operation region\n\t\t\t// now nr is a client region which is not overlapped by children\n\t\t\t// at this time\n\t\t\tif(DisplayType == type && opacity == 255)\n\t\t\t{\n\t\t\t\t// DisplayType == type and full opacity\n\t\t\t\t// just copy the target bitmap\n\t\t\t\ttTVPComplexRect::tIterator it = nr.GetIterator();\n\t\t\t\twhile(it.Step())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(*it);\n\t\t\t\t\ttTVPRect sr;\n\t\t\t\t\tsr.left = cliprect.left + (r.left - destrect.left);\n\t\t\t\t\tsr.top  = cliprect.top  + (r.top  - destrect.top );\n\t\t\t\t\tsr.right = sr.left + r.get_width();\n\t\t\t\t\tsr.bottom = sr.top + r.get_height();\n\n\t\t\t\t\tUpdateBitmapForChild->CopyRect(\n\t\t\t\t\t\tr.left - UpdateOfsX, r.top - UpdateOfsY,\n\t\t\t\t\t\tbmp, sr);\n\t\t\t\t}\n\t\t\t\t// calculate operation region\n\t\t\t\topr.Or(destrect);\n\t\t\t\topr.Sub(nr);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// set operation region\n\t\t\t\ttTVPComplexRect::tIterator it = nr.GetIterator();\n\t\t\t\twhile(it.Step())\n\t\t\t\t{\n\t\t\t\t\ttTVPRect r(*it);\n\t\t\t\t\tr.add_offsets(-UpdateOfsX, -UpdateOfsY);\n\t\t\t\t\t// fill r with transparent color\n\t\t\t\t\tCopySelf(UpdateBitmapForChild,\n\t\t\t\t\t\t\tr.left,\n\t\t\t\t\t\t\tr.top, r);\n\t\t\t\t\t\t\t// CopySelf of MainImage == NULL actually\n\t\t\t\t\t\t\t// fills target rectangle with full transparency\n\t\t\t\t}\n\t\t\t\topr.Or(destrect);\n\t\t\t}\n\n\t\t\t// operate r\n\t\t\ttTVPComplexRect::tIterator it = opr.GetIterator();\n\t\t\twhile(it.Step())\n\t\t\t{\n\t\t\t\ttTVPRect r(*it);\n\t\t\t\ttTVPRect sr;\n\t\t\t\tsr.left = cliprect.left + (r.left - destrect.left);\n\t\t\t\tsr.top  = cliprect.top  + (r.top  - destrect.top );\n\t\t\t\tsr.right = sr.left + r.get_width();\n\t\t\t\tsr.bottom = sr.top + r.get_height();\n\n\t\t\t\tBltImage(UpdateBitmapForChild, DisplayType,\n\t\t\t\t\tr.left - UpdateOfsX,\n\t\t\t\t\tr.top - UpdateOfsY,\n\t\t\t\t\tbmp, sr, type, opacity);\n\t\t\t}\n\n\t\t\t// update DrawnRegion\n\t\t\tDrawnRegion.Or(destrect);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tBltImage(UpdateBitmapForChild, DisplayType,\n\t\t\t\tdestrect.left - UpdateOfsX,\n\t\t\t\tdestrect.top - UpdateOfsY,\n\t\t\t\tbmp, cliprect, type, opacity);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalComplete2(tTVPComplexRect & updateregion,\n\ttTVPDrawable *drawable)\n{\n//--- querying phase\n\n\t// search ltOpaque, not to draw region behind them.\n\tif(Manager) Manager->QueryUpdateExcludeRect();\n\n//--- drawing phase\n\n\t// split the region to some stripes to utilize the CPU's memory\n\t// caching.\n\n\t//tjs_int i;\n\ttTVPComplexRect::tIterator it = updateregion.GetIterator();\n\twhile(it.Step())\n\t{\n\t\ttTVPRect r(*it);\n\n\t\t// Add layer offset because Draw() accepts the position in\n\t\t// *parent* 's coordinates.\n\t\tr.add_offsets(Rect.left, Rect.top);\n\n\t\tif(TVPGraphicSplitOperationType != gsotNone)\n\t\t{\n\t\t\t// compute optimum height of the stripe\n\t\t\ttjs_int oh;\n\n\t\t\tif(GetVisibleChildrenCount() || InTransition)\n\t\t\t{\n\t\t\t\t// split\n\t\t\t\ttjs_int rw = r.get_width();\n\t\t\t\tif(rw < 40) oh = 256;\n\t\t\t\telse if(rw < 80) oh = 128;\n\t\t\t\telse if(rw < 160) oh = 64;\n\t\t\t\telse if(rw < 320) oh = 32;\n\t\t\t\telse oh = 16; // 2 lines per core in modern 8 cores cpu\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// no need to split\n\t\t\t\toh = r.get_height();\n\t\t\t}\n\n\t\t\t// split to some stripes\n\t\t\ttjs_int y;\n\t\t\ttTVPRect opr;\n\t\t\topr.left = r.left;\n\t\t\topr.right = r.right;\n\t\t\tif(TVPGraphicSplitOperationType == gsotInterlace)\n\t\t\t{\n\t\t\t\t// interlaced split\n\t\t\t\tfor(y = r.top; y < r.bottom; y+= oh*2)\n\t\t\t\t{\n\t\t\t\t\topr.top = y;\n\t\t\t\t\topr.bottom = (y+oh < r.bottom) ? y+oh: r.bottom;\n\n\t\t\t\t\t// call \"Draw\" to draw to the window\n\t\t\t\t\tDraw(drawable, opr, false);\n\t\t\t\t}\n\t\t\t\tfor(y = r.top + oh; y < r.bottom; y+= oh*2)\n\t\t\t\t{\n\t\t\t\t\topr.top = y;\n\t\t\t\t\topr.bottom = (y+oh < r.bottom) ? y+oh: r.bottom;\n\n\t\t\t\t\t// call \"Draw\" to draw to the window\n\t\t\t\t\tDraw(drawable, opr, false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(TVPGraphicSplitOperationType == gsotSimple)\n\t\t\t{\n\t\t\t\t// non-interlaced\n\t\t\t\tfor(y = r.top; y < r.bottom; y+=oh)\n\t\t\t\t{\n\t\t\t\t\topr.top = y;\n\t\t\t\t\topr.bottom = (y+oh < r.bottom) ? y+oh: r.bottom;\n\n\t\t\t\t\t// call \"Draw\" to draw to the window\n\t\t\t\t\tDraw(drawable, opr, false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(TVPGraphicSplitOperationType == gsotBiDirection)\n\t\t\t{\n\t\t\t\t// bidirection\n\t\t\t\tstatic int direction = 0;\n\t\t\t\tif(direction & 1)\n\t\t\t\t{\n\t\t\t\t\tfor(y = r.top; y < r.bottom; y+=oh)\n\t\t\t\t\t{\n\t\t\t\t\t\topr.top = y;\n\t\t\t\t\t\topr.bottom = (y+oh < r.bottom) ? y+oh: r.bottom;\n\n\t\t\t\t\t\t// call \"Draw\" to draw to the window\n\t\t\t\t\t\tDraw(drawable, opr, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ty = r.bottom - oh;\n\t\t\t\t\tif(y < r.top) y = r.top;\n\t\t\t\t\twhile(1)\n\t\t\t\t\t{\n\t\t\t\t\t\topr.top = (y < r.top ? r.top : y);\n\t\t\t\t\t\topr.bottom = (y+oh < r.bottom) ? y+oh: r.bottom;\n\n\t\t\t\t\t\tif(opr.bottom <= r.top) break;\n\n\t\t\t\t\t\t// call \"Draw\" to draw to the window\n\t\t\t\t\t\tDraw(drawable, opr, false);\n\n\t\t\t\t\t\ty-=oh;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdirection++;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// don't split scanlines\n\t\t\tDraw(drawable, r, false);\n\t\t}\n\t}\n\n\tupdateregion.Clear();\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalComplete2_GPU(tTVPRect updateregion, tTVPDrawable *drawable)\n{\n\tif (Manager) Manager->QueryUpdateExcludeRect();\n\tupdateregion.add_offsets(Rect.left, Rect.top);\n\tDraw_GPU(drawable, 0, 0, updateregion, false);\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalComplete(tTVPComplexRect & updateregion,\n\ttTVPDrawable *drawable)\n{\n\tBeforeCompletion();\n\n\t// at this point, final update region (in this completion) is determined\n\tInCompletion = true;\n\n\tif (IsGPU()) {\n\t\tInternalComplete2_GPU(updateregion.GetBound(), drawable);\n\t} else {\n\t\tInternalComplete2(updateregion, drawable);\n\t}\n\n\tInCompletion = false;\n\tAfterCompletion();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::CompleteForWindow(tTVPDrawable *drawable)\n{\n\tBeforeCompletion();\n\n\tif(Manager) Manager->NotifyUpdateRegionFixed();\n\n\tInCompletion = true;\n\n\tif(Manager) Manager->GetLayerTreeOwner()->StartBitmapCompletion(Manager);\n\ttry\n\t{\n\t\tif (IsGPU()) {\n\t\t\tInternalComplete2_GPU(Rect, drawable);\n\t\t} else {\n\t\t\tInternalComplete2(Manager->GetUpdateRegionForCompletion(), drawable);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(Manager) Manager->GetLayerTreeOwner()->EndBitmapCompletion(Manager);\n\t\tthrow;\n\t}\n\tif(Manager) Manager->GetLayerTreeOwner()->EndBitmapCompletion(Manager);\n\n\tInCompletion = false;\n\tAfterCompletion();\n\n}\n//---------------------------------------------------------------------------\ntTVPBaseTexture * tTJSNI_BaseLayer::Complete(const tTVPRect & rect)\n{\n\tclass tCompleteDrawable : public tTVPDrawable\n\t{\n\tprotected:\n\t\ttTVPBaseTexture * Bitmap;\n\t\ttTVPRect BitmapRect;\n\t\ttTVPLayerType LayerType;\n\tpublic:\n\t\ttCompleteDrawable(tTVPBaseTexture *bmp, tTVPLayerType layertype)\n\t\t\t: Bitmap(bmp), LayerType(layertype) {};\n\n\t\ttTVPBaseTexture * GetDrawTargetBitmap(const tTVPRect &rect,\n\t\t\ttTVPRect &cliprect)\n\t\t\t{ cliprect = rect; return Bitmap; }\n\t\ttTVPLayerType GetTargetLayerType() { return LayerType; }\n\t\tvirtual void DrawCompleted(const tTVPRect &destrect,\n\t\t\ttTVPBaseTexture *bmp, const tTVPRect &cliprect,\n\t\t\ttTVPLayerType type, tjs_int opacity) override\n\t\t{\n\t\t\tif(bmp != Bitmap)\n\t\t\t{\n\t\t\t\tBitmap->CopyRect(destrect.left, destrect.top,\n\t\t\t\t\tbmp, cliprect);\n\t\t\t}\n\t\t}\n\t};\n\n\tclass tCompleteDrawable_GPU : public tCompleteDrawable {\n\tpublic:\n\t\ttCompleteDrawable_GPU(tTVPBaseTexture *bmp, tTVPLayerType layertype)\n\t\t\t: tCompleteDrawable(bmp, layertype) {\n\t\t\tbmp->Fill(tTVPRect(0, 0, bmp->GetWidth(), bmp->GetHeight()), layertype == ltOpaque ? 0xFF000000 : 0);\n\t\t};\n\n\t\tvirtual void DrawCompleted(const tTVPRect &destrect,\n\t\t\ttTVPBaseTexture *bmp, const tTVPRect &cliprect,\n\t\t\ttTVPLayerType type, tjs_int opacity) override {\n\t\t\tif (bmp != Bitmap) {\n\t\t\t\tBltImage(Bitmap, LayerType, destrect.left, destrect.top, bmp, cliprect, type, opacity, LayerType == ltOpaque);\n\t\t\t}\n\t\t}\n\t};\n\n\t// complete given rectangle of cache.\n\n\tif(!GetCacheEnabled()) return NULL;\n\t\t// caller must ensure that the caching is enabled\n\n\tif(GetVisibleChildrenCount() == 0 && ImageLeft == 0 && ImageTop == 0 &&\n\t\tMainImage->GetWidth() == GetWidth() && MainImage->GetHeight() == GetHeight())\n\t{\n\t\t// the layer has no visible children\n\t\t// and entire of the bitmap is the visible area.\n\t\t// simply returns main image\n\t\treturn MainImage;\n\t}\n\n\tif(CacheRecalcRegion.GetCount() == 0)\n\t{\n\t\t// the layer has not region to reconstruct\n\t\treturn CacheBitmap;\n\t}\n\n\ttTVPComplexRect ur;\n\tur.Or(rect);\n\tif (IsGPU()) {\n\t\ttCompleteDrawable_GPU drawable(CacheBitmap, DisplayType);\n\t\tInternalComplete(ur, &drawable); // complete cache\n\t} else {\n\t\t// create drawable object\n\t\ttCompleteDrawable drawable(CacheBitmap, DisplayType);\n\n\t\t// complete\n\t\tInternalComplete(ur, &drawable); // complete cache\n\t}\n\treturn CacheBitmap;\n}\n//---------------------------------------------------------------------------\ntTVPBaseTexture * tTJSNI_BaseLayer::Complete()\n{\n\t// complete entire area of the layer\n\ttTVPRect r;\n\tr.left = 0;\n\tr.top = 0;\n\tr.right = Rect.get_width();\n\tr.bottom = Rect.get_height();\n\n\treturn Complete(r);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// transition management\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StartTransition(const ttstr &name, bool withchildren,\n\ttTJSNI_BaseLayer * transsource, tTJSVariantClosure options)\n{\n\t// start transition\n\n\t// is current transition processing?\n\tif(InTransition)\n\t{\n\t\tTVPThrowExceptionMessage(TVPCurrentTransitionMustBeStopping);\n\t}\n\n\tif(transsource && transsource->TransSrc == this)\n\t{\n\t\tTVPThrowExceptionMessage(TVPTransitionMutualSource);\n\t}\n\n\t// pointers which must be released at last...\n\tiTVPTransHandlerProvider *pro = NULL;\n\ttTVPSimpleOptionProvider *sop = NULL;\n\tiTVPBaseTransHandler * handler = NULL;\n\n\ttry\n\t{\n\t\t// find transition handler\n\t\tpro = TVPFindTransHandlerProvider(name);\n\t\t\t// this may raise an exception\n\n\t\t// check selfupdate member of 'options'\n\t\ttTJSVariant var;\n\t\tTransSelfUpdate = false;\n\t\tstatic ttstr selfupdate_name(TJS_W(\"selfupdate\"));\n\t\tif(TJS_SUCCEEDED(options.PropGet(0, selfupdate_name.c_str(),\n\t\t\tselfupdate_name.GetHint(), &var, NULL)))\n\t\t{\n\t\t\tif(var.Type() != tvtVoid)\n\t\t\t\tTransSelfUpdate = 0!=(tjs_int)var;\n\t\t\t\t\t// selfupdate member found\n\t\t}\n\n\t\t// check callback member of 'options'\n\t\tTransTickCallback = tTJSVariantClosure(NULL, NULL);\n\t\tstatic ttstr callback_name(TJS_W(\"callback\"));\n\t\tUseTransTickCallback = false;\n\t\tif(TJS_SUCCEEDED(options.PropGet(0, callback_name.c_str(),\n\t\t\tcallback_name.GetHint(), &var, NULL)))\n\t\t{\n\t\t\t// selfupdate member found\n\t\t\tif(var.Type() != tvtVoid)\n\t\t\t{\n\t\t\t\tTransTickCallback = var.AsObjectClosure(); // AddRef() is performed here\n\t\t\t\tUseTransTickCallback = true;\n\t\t\t}\n\t\t}\n\n\n\t\t// create option provider\n\t\tsop = new tTVPSimpleOptionProvider(options);\n\n\t\t// notify starting of the transition to the provider\n\t\ttjs_error er = pro->StartTransition(sop, &TVPSimpleImageProvider,\n\t\t\tDisplayType,\n\t\t\twithchildren ? GetWidth()  : MainImage->GetWidth(),\n\t\t\twithchildren ? GetHeight() : MainImage->GetHeight(),\n\t\t\ttranssource?\n\t\t\t\t(withchildren?transsource->GetWidth() :\n\t\t\t\t\ttranssource->MainImage->GetWidth())  :0,\n\t\t\ttranssource?\n\t\t\t\t(withchildren?transsource->GetHeight() :\n\t\t\t\t\ttranssource->MainImage->GetHeight()) :0,\n\t\t\t&TransType, &TransUpdateType, &handler);\n\n\t\tif(TJS_FAILED(er))\n\t\t\tTVPThrowExceptionMessage(TVPTransHandlerError,\n\t\t\t\tTJS_W(\"iTVPTransHandlerProvider::StartTransition failed\"));\n\n\t\tif(TransUpdateType != tutDivisibleFade && TransUpdateType != tutDivisible\n\t\t\t&& TransUpdateType != tutGiveUpdate)\n\t\t\tTVPThrowExceptionMessage(TVPTransHandlerError, (const tjs_char*)TVPUnknownUpdateType );\n\n\t\tif(TransType != ttSimple && TransType != ttExchange)\n\t\t\tTVPThrowExceptionMessage(TVPTransHandlerError, (const tjs_char*)TVPUnknownTransitionType );\n\n\t\t// check update type\n\t\tif(TransUpdateType == tutGiveUpdate)\n\t\t\tTVPThrowExceptionMessage(TVPTransHandlerError, (const tjs_char*)TVPUnsupportedUpdateTypeTutGiveUpdate );\n\t\t\t\t\t// sorry for inconvinience\n\t\tif(TransType == ttExchange && !transsource)\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyTransitionSource);\n\n\t\t// check wether the source and destination both have image\n\t\tif(!withchildren)\n\t\t{\n\t\t\tif(!MainImage)\n\t\t\t\tTVPThrowExceptionMessage(TVPTransitionSourceAndDestinationMustHaveImage);\n\t\t\tif(transsource && !transsource->MainImage)\n\t\t\t\tTVPThrowExceptionMessage(TVPTransitionSourceAndDestinationMustHaveImage);\n\t\t}\n\n\t\t// set to cache\n\t\tTransWithChildren = withchildren;\n\t\tif(TransWithChildren)\n\t\t{\n\t\t\tIncCacheEnabledCount();\n\t\t\tif(transsource) transsource->IncCacheEnabledCount();\n\t\t}\n\n\t\t// set to interrupt into updating/completion pipe line\n\t\tTransSrc = transsource;\n\t\tif(transsource) transsource->TransDest = this;\n\n\t\t// set transition handler\n\t\tif(TransUpdateType == tutDivisibleFade || TransUpdateType == tutDivisible)\n\t\t\tDivisibleTransHandler =\n\t\t\tstatic_cast<iTVPDivisibleTransHandler *>(handler);\n\t\tif(TransUpdateType == tutGiveUpdate) GiveUpdateTransHandler =\n\t\t\tstatic_cast<iTVPGiveUpdateTransHandler *>(handler);\n\n\t\t// hold destination and source objects\n\t\tTransDestObj = Owner;\n\t\tif(TransDestObj) TransDestObj->AddRef();\n\t\tif(transsource) TransSrcObj = transsource->Owner; else TransSrcObj = NULL;\n\t\tif(TransSrcObj) TransSrcObj->AddRef();\n\n\t\t// register to idle event handler\n\t\tTransIdleCallback.Owner = this;\n\t\tif(!TransSelfUpdate) TVPAddContinuousEventHook(&TransIdleCallback);\n\n\t\t// initial tick count\n\t\tTVPStartTickCount();\n\t\tif(UseTransTickCallback)\n\t\t{\n\t\t\tTransTick = 0;\n\t\t\t// initially 0\n\t\t\t// dummy calling StartProcess/EndProcess to notify initial tick count;\n\t\t\t// for first call with TransTick = 0, these method should not\n\t\t\t// return any error status here.\n\t\t\tif(DivisibleTransHandler)\n\t\t\t{\n\t\t\t\tDivisibleTransHandler->StartProcess(TransTick);\n\t\t\t\tDivisibleTransHandler->EndProcess();\n\t\t\t}\n\t\t\telse if(GiveUpdateTransHandler)\n\t\t\t{\n\t\t\t\t;// not yet implemented\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTransTick = GetTransTick();\n\t\t}\n\n\t\t// set flag\n\t\tInTransition = true;\n\t\tTransCompEventPrevented = false;\n\n\t\t// update\n\t\tUpdate(true);\n\t}\n\tcatch(...)\n\t{\n\t\tif(pro) pro->Release();\n\t\tif(sop) sop->Release();\n\t\tif(handler) handler->Release();\n\t\tthrow;\n\t}\n\tif(pro) pro->Release();\n\tif(sop) sop->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InternalStopTransition()\n{\n\t// stop transition\n\tif(InTransition)\n\t{\n\t\tInTransition = false;\n\t\tTransCompEventPrevented = false;\n\n\t\t// unregister idle event handler\n\t\tif(!TransSelfUpdate) TVPRemoveContinuousEventHook(&TransIdleCallback);\n\n\t\t// disable cache\n\t\tif(TransWithChildren)\n\t\t{\n\t\t\tDecCacheEnabledCount();\n\t\t\tif(TransSrc) TransSrc->DecCacheEnabledCount();\n\t\t}\n\n\t\t//\n\t\t// exchange the layer\n\t\tif(TransType == ttExchange)\n\t\t{\n\t\t\ttjs_int tl = this->Rect.left;\n\t\t\ttjs_int tt = this->Rect.top;\n\t\t\ttjs_int sl = TransSrc->Rect.left;\n\t\t\ttjs_int st = TransSrc->Rect.top;\n\t\t\tbool tv = this->GetVisible();\n\t\t\tbool sv = TransSrc->GetVisible();\n\t\t\tif(TransWithChildren)\n\t\t\t{\n\t\t\t\t// exchange with tree structure\n\t\t\t\tExchange(TransSrc);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// exchange the layer and the target only\n\t\t\t\tSwap(TransSrc);\n\t\t\t}\n\t\t\tthis->SetPosition(sl, st);\n\t\t\tTransSrc->SetPosition(tl, tt);\n\t\t\tthis->SetVisible(sv);\n\t\t\tTransSrc->SetVisible(tv);\n\t\t}\n\n\t\tbool transsrcalive = false;\n\t\tif(TransSrc && !TransSrc->Shutdown) transsrcalive = true;\n\n\t\tif(TransSrc) TransSrc->TransDest = NULL;\n\t\tTransSrc = NULL;\n\n\t\t// release transition handler object\n\t\tif(DivisibleTransHandler)\n\t\t\tDivisibleTransHandler->Release(), DivisibleTransHandler = NULL;\n\t\tif(GiveUpdateTransHandler)\n\t\t\tGiveUpdateTransHandler->Release(), GiveUpdateTransHandler = NULL;\n\n\n\t\t// fire event\n\t\tif(Owner && !Shutdown && transsrcalive)\n\t\t{\n\t\t\tstatic ttstr eventname(TJS_W(\"onTransitionCompleted\"));\n\n\t\t\t// fire SYNCHRONOUS event of \"onTransitionCompleted\"\n\t\t\ttTJSVariant param[2];\n\t\t\tparam[0] = tTJSVariant(TransDestObj, TransDestObj);\n\t\t\tif(TransDestObj) TransDestObj->Release(), TransDestObj = NULL;\n\t\t\tparam[1] = tTJSVariant(TransSrcObj, TransSrcObj);\n\t\t\tif(TransSrcObj) TransSrcObj->Release(), TransSrcObj = NULL;\n\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0,\n\t\t\t\tTVP_EPT_IMMEDIATE, 2, param);\n\t\t}\n\n\t\t// release destination and source objects\n\t\tif(TransDestObj) TransDestObj->Release(), TransDestObj = NULL;\n\t\tif(TransSrcObj) TransSrcObj->Release(), TransSrcObj = NULL;\n\n\t\t// release TransTickCallback\n\t\tTransTickCallback.Release(), TransTickCallback = tTJSVariantClosure(NULL, NULL);\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StopTransition()\n{\n\t// stop the transition by manual\n\tInternalStopTransition();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::StopTransitionByHandler()\n{\n\t// stopping of the transition caused by the handler\n\tif(!TVPEventDisabled)\n\t{\n\t\t// event dispatching is enabled\n\t\tInternalStopTransition();\n\t}\n\telse\n\t{\n\t\t// event dispatching is not enabled\n\t\tTransCompEventPrevented = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::InvokeTransition(tjs_uint64 tick)\n{\n\tif(!TransCompEventPrevented)\n\t{\n\t\tif(UseTransTickCallback)\n\t\t\tTransTick = GetTransTick();\n\t\telse\n\t\t\tTransTick = tick;\n\t\tif(!GetNodeVisible())\n\t\t{\n\t\t\tStopTransitionByHandler();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(!MainImage && TransWithChildren &&\n\t\t\t\tTransUpdateType == tutDivisibleFade && DisplayType != ltOpaque)\n\t\t\t{\n\t\t\t\t// update only for child region\n\t\t\t\tUpdateAllChildren(true);\n\t\t\t\tif(TransSrc) TransSrc->UpdateAllChildren(true);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tUpdate(true); // update without re-computing piled images\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// transition complete event is prevented\n\t\tif(!TVPEventDisabled) // if event dispatching is enabled\n\t\t\tInternalStopTransition(); // stop the transition\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::DoDivisibleTransition(iTVPBaseBitmap *dest,\n\ttjs_int dx, tjs_int dy, const tTVPRect &srcrect)\n{\n\t// apply transition ( with no children ) over given target bitmap\n\tif(!InTransition || !DivisibleTransHandler) return;\n\n\ttTVPDivisibleData data;\n\tdata.Left = srcrect.left;\n\tdata.Top = srcrect.top;\n\tdata.Width = srcrect.get_width();\n\tdata.Height = srcrect.get_height();\n\n\t// src1\n\tif(!SrcSLP)\n\t\tSrcSLP = new tTVPScanLineProviderForBaseBitmap(MainImage);\n\telse\n\t\tSrcSLP->Attach(MainImage);\n\tdata.Src1 = SrcSLP;\n\tdata.Src1Left = srcrect.left;\n\tdata.Src1Top = srcrect.top;\n\tImageModified = true;\n\n\t// src2\n\tif(TransSrc)\n\t{\n\t\t// source available\n\t\tif(!TransSrc->SrcSLP)\n\t\t\tTransSrc->SrcSLP =\n\t\t\t\tnew tTVPScanLineProviderForBaseBitmap(TransSrc->MainImage);\n\t\telse\n\t\t\tTransSrc->SrcSLP->Attach(TransSrc->MainImage);\n\n\t\tdata.Src2 = TransSrc->SrcSLP;\n\t\tdata.Src2Left = srcrect.left;\n\t\tdata.Src2Top = srcrect.top;\n\t}\n\n\t// dest\n\tif(!DestSLP)\n\t\tDestSLP = new tTVPScanLineProviderForBaseBitmap(dest);\n\telse\n\t\tDestSLP->Attach(dest);\n\tdata.Dest = DestSLP;\n\tdata.DestLeft = dx;\n\tdata.DestTop = dy;\n\n\t// process\n\tDivisibleTransHandler->Process(&data);\n\n\tif(data.Dest == data.Src1)\n\t{\n\t\t// returned destination differs from given destination\n\t\t// (returned destination is data.Src1)\n\t\tdest->CopyRect(dx, dy, MainImage, srcrect);\n\t}\n\telse if(data.Dest == data.Src2)\n\t{\n\t\t// (returned destination is data.Src2)\n\t\tdest->CopyRect(dx, dy, TransSrc->MainImage, srcrect);\n\t}\n}\n//---------------------------------------------------------------------------\n//---------------------------------------------------------------------------\ntTVPBaseTexture * tTJSNI_BaseLayer::tTransDrawable::\n\tGetDrawTargetBitmap(const tTVPRect &rect, tTVPRect &cliprect)\n{\n\t// save target bitmap pointer\n\tTarget = OrgDrawable->GetDrawTargetBitmap(rect, cliprect);\n\tTargetRect = cliprect;\n\treturn Target;\n}\n//---------------------------------------------------------------------------\ntTVPLayerType tTJSNI_BaseLayer::tTransDrawable::GetTargetLayerType()\n{\n\treturn OrgDrawable->GetTargetLayerType();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseLayer::tTransDrawable::DrawCompleted(const tTVPRect &destrect,\n\ttTVPBaseTexture *bmp, const tTVPRect &cliprect, tTVPLayerType type,\n\t\ttjs_int opacity)\n{\n\t// do divisible transition\n\tif(!Owner->InTransition || !Owner->DivisibleTransHandler) return;\n\n\ttTVPDivisibleData data;\n\tdata.Left = destrect.left - Owner->Rect.left;\n\tdata.Top = destrect.top - Owner->Rect.top;\n\tdata.Width = cliprect.get_width();\n\tdata.Height = cliprect.get_height();\n\n    iTVPBaseBitmap * src1bmp;\n\tif(Owner->TransUpdateType == tutDivisible)\n\t\tsrc1bmp = Src1Bmp;\n\telse\n\t\tsrc1bmp = bmp;\n\tOwner->ImageModified = true;\n\n\tif(!Owner->SrcSLP)\n\t\tOwner->SrcSLP = new tTVPScanLineProviderForBaseBitmap(src1bmp);\n\telse\n\t\tOwner->SrcSLP->Attach(src1bmp);\n\n\tdata.Src1 = Owner->SrcSLP;\n\tdata.Src1Left = cliprect.left;\n\tdata.Src1Top = cliprect.top;\n\n\ttTVPBaseTexture *src = NULL;\n\tif(Owner->TransSrc)\n\t{\n\t\t// source available\n\t\t// prepare source 2 from CacheBitmap\n\t\tif(Owner->TransUpdateType == tutDivisible)\n\t\t\tsrc = Src2Bmp;\n\t\telse\n\t\t\tsrc = Owner->TransSrc->Complete(destrect);\n\t\tif(!Owner->TransSrc->SrcSLP)\n\t\t\tOwner->TransSrc->SrcSLP =\n\t\t\t\tnew tTVPScanLineProviderForBaseBitmap(src);\n\t\telse\n\t\t\tOwner->TransSrc->SrcSLP->Attach(src);\n\n\t\tdata.Src2 = Owner->TransSrc->SrcSLP;\n\t\tdata.Src2Left = data.Left; // destrect.left;\n\t\tdata.Src2Top = data.Top; //destrect.top;\n\t}\n\telse\n\t{\n\t\tdata.Src2 = NULL;\n\t}\n\n\ttTVPBaseTexture *dest;\n\tbool tempalloc = false;\n\tif(bmp == Target || Target == NULL)\n\t{\n\t\t// source bitmap is the same as the Original Target;\n\t\t// allocatte temporary bitmap\n\t\tdest = tTVPTempBitmapHolder::GetTemp(\n\t\t\t\t\t\t\tcliprect.get_width(),\n\t\t\t\t\t\t\tcliprect.get_height(), true);  // fit = true\n\n\t\t\t\t\t// TODO: check whether \"fit\" can affect the performance\n\n\t\ttempalloc = true;\n\t\tif(!Owner->DestSLP)\n\t\t\tOwner->DestSLP = new tTVPScanLineProviderForBaseBitmap(dest);\n\t\telse\n\t\t\tOwner->DestSLP->Attach(dest);\n\t\tdata.Dest = Owner->DestSLP;\n\t\tdata.DestLeft = 0;\n\t\tdata.DestTop = 0;\n\t}\n\telse\n\t{\n\t\tif(!Owner->DestSLP)\n\t\t\tOwner->DestSLP = new tTVPScanLineProviderForBaseBitmap(Target);\n\t\telse\n\t\t\tOwner->DestSLP->Attach(Target);\n\t\tdest = Target;\n\t\tdata.Dest = Owner->DestSLP;\n\t\tdata.DestLeft = TargetRect.left;\n\t\tdata.DestTop = TargetRect.top;\n\t}\n\n\ttry\n\t{\n\t\tOwner->DivisibleTransHandler->Process(&data);\n\t\ttTVPRect cr = cliprect;\n\n\t\tif(data.Dest == Owner->DestSLP)\n\t\t{\n\t\t\tcr.set_offsets(data.DestLeft, data.DestTop);\n\t\t\tOrgDrawable->DrawCompleted(destrect, dest, cr, type, opacity);\n\t\t}\n\t\telse if(data.Dest == data.Src1)\n\t\t{\n\t\t\tcr.set_offsets(data.DestLeft, data.DestTop);\n\t\t\tOrgDrawable->DrawCompleted(destrect, bmp, cr, type, opacity);\n\t\t}\n\t\telse if(data.Dest == data.Src2 && Owner->TransSrc)\n\t\t{\n\t\t\tcr.set_offsets(data.DestLeft, data.DestTop);\n\t\t\tOrgDrawable->DrawCompleted(destrect, src, cr, type, opacity);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n\t\tthrow;\n\t}\n\n\tif(tempalloc) tTVPTempBitmapHolder::FreeTemp();\n}\n//---------------------------------------------------------------------------\ntjs_uint64 tTJSNI_BaseLayer::GetTransTick()\n{\n\tif(!UseTransTickCallback)\n\t{\n\t\t// just use TVPGetTickCount() as a source\n\t\treturn TVPGetTickCount();\n\t}\n\telse\n\t{\n\t\t// call TransTickCallback to receive result\n\t\ttTJSVariant res;\n\t\tTransTickCallback.FuncCall(0, NULL, NULL, &res, 0, NULL, NULL);\n\t\treturn (tjs_uint64)(tjs_int64)res;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Layer : TJS Layer class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Layer::ClassID = -1;\ntTJSNC_Layer::tTJSNC_Layer() : tTJSNativeClass(TJS_W(\"Layer\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Layer) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Layer,\n\t/*TJS class name*/Layer)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Layer)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/moveBefore)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t_this->MoveBefore(src);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/moveBefore)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/moveBehind)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t_this->MoveBehind(src);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/moveBehind)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/bringToBack)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->BringToBack();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/bringToBack)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/bringToFront)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->BringToFront();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/bringToFront)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/saveLayerImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\tttstr type(TJS_W(\"bmp\"));\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\ttype = *param[1];\n\t_this->SaveLayerImage(name, type);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/saveLayerImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadImages)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\ttjs_uint32 key = clNone; // TODO IntfȂ̂ɌŗLl\n\tif(numparams >=2 && param[1]->Type() != tvtVoid)\n\t\tkey = (tjs_uint32)param[1]->AsInteger();\n\tiTJSDispatch2 * metainfo = _this->LoadImages(name, key);\n\ttry\n\t{\n\t\tif(result) *result = metainfo;\n\t}\n\tcatch(...)\n\t{\n\t\tif(metainfo) metainfo->Release();\n\t\tthrow;\n\t}\n\tif(metainfo) metainfo->Release();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/loadImages)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/loadProvinceImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name(*param[0]);\n\t_this->LoadProvinceImage(name);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/loadProvinceImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getMainPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(result) *result = (tjs_int64)_this->GetMainPixel(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getMainPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMainPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->SetMainPixel(*param[0], *param[1], (tjs_int)*param[2]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMainPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getMaskPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(result) *result = _this->GetMaskPixel(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getMaskPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMaskPixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->SetMaskPixel(*param[0], *param[1], *param[2]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMaskPixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getProvincePixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(result) *result = _this->GetProvincePixel(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getProvincePixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setProvincePixel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t_this->SetProvincePixel(*param[0], *param[1], *param[2]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setProvincePixel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getLayerAt)// not GetMostFrontChildAt\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\tbool exclude_self = false;\n\tbool get_disabled = false;\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\texclude_self = param[2]->operator bool();\n\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\tget_disabled = param[3]->operator bool();\n\n\ttTJSNI_BaseLayer *lay =\n\t\t_this->GetMostFrontChildAt(*param[0], *param[1], exclude_self, get_disabled);\n\n\tif(result)\n\t{\n\t\tif(lay && lay->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(lay->GetOwnerNoAddRef(), lay->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getLayerAt)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPos) // not setPosition\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\tif(numparams == 4 && param[2]->Type() != tvtVoid && param[3]->Type() != tvtVoid)\n\t{\n\t\t// set bounds\n\t\ttTVPRect r;\n\t\tr.left = *param[0];\n\t\tr.top = *param[1];\n\t\tr.right = (tjs_int)*param[2] + r.left;\n\t\tr.bottom = (tjs_int)*param[3] + r.top;\n\t\t_this->SetBounds(r);\n\t}\n\telse\n\t{\n\t\t// set position only\n\t\t_this->SetPosition(*param[0], *param[1]);\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetSize((tjs_int)*param[0], (tjs_int)*param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSizeToImageSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t_this->SetSize(_this->GetImageWidth(), _this->GetImageHeight());\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSizeToImageSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setImagePos)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetImagePosition((tjs_int)*param[0], (tjs_int)*param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setImagePos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setImageSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetImageSize((tjs_int)*param[0], (tjs_int)*param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setImageSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/independMainImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tbool copy = true;\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tcopy = param[0]->operator bool();\n\t_this->IndependMainImage(copy);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/independMainImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/independProvinceImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tbool copy = true;\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tcopy = param[0]->operator bool();\n\t_this->IndependProvinceImage(copy);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/independProvinceImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setClip) // not setClipRect\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams == 0)\n\t{\n\t\t// reset clip rectangle\n\t\t_this->ResetClip();\n\n\t}\n\telse\n\t{\n\n\t\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\n\t\t_this->SetClip(\n\t\t\t(tjs_int)*param[0],\n\t\t\t(tjs_int)*param[1],\n\t\t\t(tjs_int)*param[2],\n\t\t\t(tjs_int)*param[3]);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setClip)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fillRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\ttjs_int x, y;\n\tx = *param[0];\n\ty = *param[1];\n\t_this->FillRect(tTVPRect(x, y, x+(tjs_int)*param[2], y+(tjs_int)*param[3]),\n\t\tstatic_cast<tjs_uint32>((tjs_int64)*param[4]));\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fillRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/colorRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n\ttjs_int x, y;\n\tx = *param[0];\n\ty = *param[1];\n\t_this->ColorRect(tTVPRect(x, y, x+(tjs_int)*param[2], y+(tjs_int)*param[3]),\n\t\tstatic_cast<tjs_uint32>((tjs_int64)*param[4]),\n\t\t(numparams>=6 && param[5]->Type() != tvtVoid)? (tjs_int) *param[5] : 255);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/colorRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/drawText)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t_this->DrawText(\n\t\t*param[0],\n\t\t*param[1],\n\t\t*param[2],\n\t\tstatic_cast<tjs_uint32>((tjs_int64)*param[3]),\n\t\t(numparams >= 5 && param[4]->Type() != tvtVoid)?(tjs_int)*param[4] : (tjs_int)255,\n\t\t(numparams >= 6 && param[5]->Type() != tvtVoid)? param[5]->operator bool() : true,\n\t\t(numparams >= 7 && param[6]->Type() != tvtVoid)? (tjs_int)*param[6] : 0,\n\t\t(numparams >= 8 && param[7]->Type() != tvtVoid)? static_cast<tjs_uint32>((tjs_int64)*param[7]) : 0,\n\t\t(numparams >= 9 && param[8]->Type() != tvtVoid)? (tjs_int)*param[8] : 0,\n\t\t(numparams >=10 && param[9]->Type() != tvtVoid)? (tjs_int)*param[9] : 0,\n\t\t(numparams >=11 && param[10]->Type() != tvtVoid)? (tjs_int)*param[10] : 0\n\t\t);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/drawText)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/drawGlyph)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\tiTJSDispatch2* glyph = param[2]->AsObjectNoAddRef();\n\t_this->DrawGlyph(\n\t\t*param[0],\n\t\t*param[1],\n\t\tglyph,\n\t\tstatic_cast<tjs_uint32>((tjs_int64)*param[3]),\n\t\t(numparams >= 5 && param[4]->Type() != tvtVoid)?(tjs_int)*param[4] : (tjs_int)255,\n\t\t(numparams >= 6 && param[5]->Type() != tvtVoid)? param[5]->operator bool() : true,\n\t\t(numparams >= 7 && param[6]->Type() != tvtVoid)? (tjs_int)*param[6] : 0,\n\t\t(numparams >= 8 && param[7]->Type() != tvtVoid)? static_cast<tjs_uint32>((tjs_int64)*param[7]) : 0,\n\t\t(numparams >= 9 && param[8]->Type() != tvtVoid)? (tjs_int)*param[8] : 0,\n\t\t(numparams >=10 && param[9]->Type() != tvtVoid)? (tjs_int)*param[9] : 0,\n\t\t(numparams >=11 && param[10]->Type() != tvtVoid)? (tjs_int)*param[10] : 0\n\t\t);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/drawGlyph)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/piledCopy)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 7) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect rect(*param[3], *param[4], *param[5], *param[6]);\n\trect.right += rect.left;\n\trect.bottom += rect.top;\n\n\t_this->PiledCopy(*param[0], *param[1], src, rect);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/piledCopy)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/copyRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 7) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\tiTVPBaseBitmap* provinceSrc = NULL;\n\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = provinceSrc = NULL;\n\t\telse\n\t\t{\n\t\t\tsrc = srclayer->GetMainImage();\n\t\t\tprovinceSrc = srclayer->GetProvinceImage();\n\t\t}\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = provinceSrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = provinceSrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src && !provinceSrc) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect rect(*param[3], *param[4], *param[5], *param[6]);\n\trect.right += rect.left;\n\trect.bottom += rect.top;\n\n\t_this->CopyRect(*param[0], *param[1], src, provinceSrc, rect);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/copyRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/pileRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 7) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect rect(*param[3], *param[4], *param[5], *param[6]);\n\trect.right += rect.left;\n\trect.bottom += rect.top;\n\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.pileRect\"), TJS_W(\"9\")));\n\t}\n\n\t_this->PileRect(*param[0], *param[1], src, rect,\n\t\t(numparams>=8 && param[7]->Type() != tvtVoid)?(tjs_int)*param[7]:255);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/pileRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/blendRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 7) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect rect(*param[3], *param[4], *param[5], *param[6]);\n\trect.right += rect.left;\n\trect.bottom += rect.top;\n\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.blendRect\"), TJS_W(\"9\")));\n\t}\n\n\t_this->BlendRect(*param[0], *param[1], src, rect,\n\t\t(numparams>=8 && param[7]->Type() != tvtVoid)?(tjs_int)*param[7]:255);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/blendRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/copy9Patch)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t{\n\t\t\tsrc = srclayer->GetMainImage();\n\t\t}\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect margin;\n\tbool updated = _this->Copy9Patch( src, margin );\n\tif( result ) {\n\t\tif( updated ) {\n\t\t\tiTJSDispatch2 *ret = TVPCreateRectObject( margin.left, margin.top, margin.right, margin.bottom );\n\t\t\t*result = tTJSVariant(ret, ret);\n\t\t\tret->Release();\n\t\t} else {\n\t\t\tresult->Clear();\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/copy9Patch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 7) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\ttTVPBlendOperationMode automode = omAlpha;\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t\tsrc = srclayer->GetMainImage(), automode = srclayer->GetOperationModeFromType();\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect rect(*param[3], *param[4], *param[5], *param[6]);\n\trect.right += rect.left;\n\trect.bottom += rect.top;\n\n\ttTVPBlendOperationMode mode;\n\tif(numparams >= 8 && param[7]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[7]);\n\telse\n\t\tmode = omAuto;\n\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.operateRect\"), TJS_W(\"10\")));\n\t}\n\n\t// get correct blend mode if the mode is omAuto\n\tif(mode == omAuto) mode = automode;\n\n\t_this->OperateRect(*param[0], *param[1], src, rect, mode,\n\t\t(numparams>=9 && param[8]->Type() != tvtVoid)?(tjs_int)*param[8]:255);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/operateRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stretchCopy)\n{\n\t// dx, dy, dw, dh, src, sx, sy, sw, sh, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 9) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[4]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t\tsrc = srclayer->GetMainImage();\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect destrect(*param[0], *param[1], *param[2], *param[3]);\n\tdestrect.right += destrect.left;\n\tdestrect.bottom += destrect.top;\n\n\ttTVPRect srcrect(*param[5], *param[6], *param[7], *param[8]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 10)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[9];\n\n\ttjs_real typeopt = 0.0;\n\tif(numparams >= 11)\n\t\ttypeopt = (tjs_real)*param[10];\n\telse if( type == stFastCubic || type == stCubic )\n\t\ttypeopt = -1.0;\n\n\t_this->StretchCopy(destrect, src, srcrect, type, typeopt);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stretchCopy)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stretchPile)\n{\n\t// dx, dy, dw, dh, src, sx, sy, sw, sh, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 9) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[4]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect destrect(*param[0], *param[1], *param[2], *param[3]);\n\tdestrect.right += destrect.left;\n\tdestrect.bottom += destrect.top;\n\n\ttTVPRect srcrect(*param[5], *param[6], *param[7], *param[8]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttjs_int opa = 255;\n\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\topa = *param[9];\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 11 && param[10]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[10];\n\n\tif(numparams >= 12 && param[11]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.stretchPile\"), TJS_W(\"12\")));\n\t}\n\n\t_this->StretchPile(destrect, src, srcrect, opa, type);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stretchPile)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stretchBlend)\n{\n\t// dx, dy, dw, dh, src, sx, sy, sw, sh, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 9) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[4]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect destrect(*param[0], *param[1], *param[2], *param[3]);\n\tdestrect.right += destrect.left;\n\tdestrect.bottom += destrect.top;\n\n\ttTVPRect srcrect(*param[5], *param[6], *param[7], *param[8]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttjs_int opa = 255;\n\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\topa = *param[9];\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 11 && param[10]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[10];\n\tif(numparams >= 12 && param[11]->Type() != tvtVoid)\n\t{\n\t\tstatic bool IsWarned = false;\n\t\tif (!IsWarned) {\n\t\t\tIsWarned = true;\n\t\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\t\tTJS_W(\"Layer.stretchBlend\"), TJS_W(\"12\")));\n\t\t}\n\t}\n\n\t_this->StretchBlend(destrect, src, srcrect, opa, type);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stretchBlend)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateStretch)\n{\n\t// dx, dy, dw, dh, src, sx, sy, sw, sh, mode=omAuto, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 9) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[4]->AsObjectClosureNoAddRef();\n\ttTVPBlendOperationMode automode = omAlpha;\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t\tsrc = srclayer->GetMainImage(), automode = srclayer->GetOperationModeFromType();\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect destrect(*param[0], *param[1], *param[2], *param[3]);\n\tdestrect.right += destrect.left;\n\tdestrect.bottom += destrect.top;\n\n\ttTVPRect srcrect(*param[5], *param[6], *param[7], *param[8]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttTVPBlendOperationMode mode;\n\tif(numparams >= 10 && param[9]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[9]);\n\telse\n\t\tmode = omAuto;\n\n\ttjs_int opa = 255;\n\n\tif(numparams >= 11 && param[10]->Type() != tvtVoid)\n\t\topa = *param[10];\n\n\ttTVPBBStretchType type = stNearest;\n\tif(numparams >= 12 && param[11]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[11];\n\n\ttjs_real typeopt = 0.0;\n\tif(numparams >= 13)\n\t\ttypeopt = (tjs_real)*param[12];\n\telse if( type == stFastCubic || type == stCubic )\n\t\ttypeopt = -1.0;\n\n\t// get correct blend mode if the mode is omAuto\n\tif(mode == omAuto) mode = automode;\n\n\t_this->OperateStretch(destrect, src, srcrect, mode, opa, type, typeopt);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/operateStretch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/affineCopy)\n{\n\t// src, sx, sy, sw, sh, affine, x0/a, y0/b, x1/c, y1/d, x2/tx, y2/ty, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 12) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t\tsrc = srclayer->GetMainImage();\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect srcrect(*param[1], *param[2], *param[3], *param[4]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttTVPBBStretchType type = stNearest;\n\n\tif(numparams >= 13 && param[12]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[12];\n\n\tbool clear = false;\n\n\tif(numparams >= 14 && param[13]->Type() != tvtVoid)\n\t\tclear = 0!=(tjs_int)*param[13];\n\n\tif(param[5]->operator bool())\n\t{\n\t\t// affine matrix mode\n\t\tt2DAffineMatrix mat;\n\t\tmat.a = *param[6];\n\t\tmat.b = *param[7];\n\t\tmat.c = *param[8];\n\t\tmat.d = *param[9];\n\t\tmat.tx = *param[10];\n\t\tmat.ty = *param[11];\n\t\t_this->AffineCopy(mat, src, srcrect, type, clear);\n\t}\n\telse\n\t{\n\t\t// points mode\n\t\ttTVPPointD points[3];\n\t\tpoints[0].x = *param[6];\n\t\tpoints[0].y = *param[7];\n\t\tpoints[1].x = *param[8];\n\t\tpoints[1].y = *param[9];\n\t\tpoints[2].x = *param[10];\n\t\tpoints[2].y = *param[11];\n\t\t_this->AffineCopy(points, src, srcrect, type, clear);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/affineCopy)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/affinePile)\n{\n\t// src, sx, sy, sw, sh, affine, x0/a, y0/b, x1/c, y1/d, x2/tx, y2/ty, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 12) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect srcrect(*param[1], *param[2], *param[3], *param[4]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttjs_int opa = 255;\n\ttTVPBBStretchType type = stNearest;\n\n\tif(numparams >= 13 && param[12]->Type() != tvtVoid)\n\t\topa = (tjs_int)*param[12];\n\tif(numparams >= 14 && param[13]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[13];\n\tif(numparams >= 15 && param[14]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.affinePile\"), TJS_W(\"15\")));\n\t}\n\n\tif(param[5]->operator bool())\n\t{\n\t\t// affine matrix mode\n\t\tt2DAffineMatrix mat;\n\t\tmat.a = *param[6];\n\t\tmat.b = *param[7];\n\t\tmat.c = *param[8];\n\t\tmat.d = *param[9];\n\t\tmat.tx = *param[10];\n\t\tmat.ty = *param[11];\n\t\t_this->AffinePile(mat, src, srcrect, opa, type);\n\t}\n\telse\n\t{\n\t\t// points mode\n\t\ttTVPPointD points[3];\n\t\tpoints[0].x = *param[6];\n\t\tpoints[0].y = *param[7];\n\t\tpoints[1].x = *param[8];\n\t\tpoints[1].y = *param[9];\n\t\tpoints[2].x = *param[10];\n\t\tpoints[2].y = *param[11];\n\t\t_this->AffinePile(points, src, srcrect, opa, type);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/affinePile)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/affineBlend)\n{\n\t// src, sx, sy, sw, sh, affine, x0/a, y0/b, x1/c, y1/d, x2/tx, y2/ty, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 12) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer * src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTVPRect srcrect(*param[1], *param[2], *param[3], *param[4]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttjs_int opa = 255;\n\ttTVPBBStretchType type = stNearest;\n\n\tif(numparams >= 13 && param[12]->Type() != tvtVoid)\n\t\topa = (tjs_int)*param[12];\n\tif(numparams >= 14 && param[13]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[13];\n\tif(numparams >= 15 && param[14]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.affineBlend\"), TJS_W(\"15\")));\n\t}\n\n\tif(param[5]->operator bool())\n\t{\n\t\t// affine matrix mode\n\t\tt2DAffineMatrix mat;\n\t\tmat.a = *param[6];\n\t\tmat.b = *param[7];\n\t\tmat.c = *param[8];\n\t\tmat.d = *param[9];\n\t\tmat.tx = *param[10];\n\t\tmat.ty = *param[11];\n\t\t_this->AffineBlend(mat, src, srcrect, opa, type);\n\t}\n\telse\n\t{\n\t\t// points mode\n\t\ttTVPPointD points[3];\n\t\tpoints[0].x = *param[6];\n\t\tpoints[0].y = *param[7];\n\t\tpoints[1].x = *param[8];\n\t\tpoints[1].y = *param[9];\n\t\tpoints[2].x = *param[10];\n\t\tpoints[2].y = *param[11];\n\t\t_this->AffineBlend(points, src, srcrect, opa, type);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/affineBlend)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/operateAffine)\n{\n\t// src, sx, sy, sw, sh, affine, x0/a, y0/b, x1/c, y1/d, x2/tx, y2/ty,\n\t// mode=omAuto, opa=255, type=0\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\tif(numparams < 12) return TJS_E_BADPARAMCOUNT;\n\n\tiTVPBaseBitmap* src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTVPBlendOperationMode automode = omAlpha;\n\tif(clo.Object)\n\t{\n\t\ttTJSNI_BaseLayer * srclayer = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&srclayer)))\n\t\t\tsrc = NULL;\n\t\telse\n\t\t\tsrc = srclayer->GetMainImage(), automode = srclayer->GetOperationModeFromType();\n\n\t\tif( src == NULL )\n\t\t{\t// try to get bitmap interface\n\t\t\ttTJSNI_Bitmap * srcbmp = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\t\tsrc = NULL;\n\t\t\telse\n\t\t\t\tsrc = srcbmp->GetBitmap();\n\t\t}\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayerOrBitmap);\n\n\ttTVPRect srcrect(*param[1], *param[2], *param[3], *param[4]);\n\tsrcrect.right += srcrect.left;\n\tsrcrect.bottom += srcrect.top;\n\n\ttjs_int opa = 255;\n\ttTVPBBStretchType type = stNearest;\n\n\tif(numparams >= 14 && param[13]->Type() != tvtVoid)\n\t\topa = (tjs_int)*param[13];\n\tif(numparams >= 15 && param[14]->Type() != tvtVoid)\n\t\ttype = (tTVPBBStretchType)(tjs_int)*param[14];\n\tif(numparams >= 16 && param[15]->Type() != tvtVoid)\n\t{\n\t\tTVPAddLog(TVPFormatMessage(TVPHoldDestinationAlphaParameterIsNowDeprecated,\n\t\t\tTJS_W(\"Layer.operateAffine\"), TJS_W(\"16\")));\n\t}\n\n\ttTVPBlendOperationMode mode;\n\tif(numparams >= 13 && param[12]->Type() != tvtVoid)\n\t\tmode = (tTVPBlendOperationMode)(tjs_int)(*param[12]);\n\telse\n\t\tmode = omAuto;\n\n\t// get correct blend mode if the mode is omAuto\n\tif(mode == omAuto) mode = automode;\n\n\tif(param[5]->operator bool())\n\t{\n\t\t// affine matrix mode\n\t\tt2DAffineMatrix mat;\n\t\tmat.a = *param[6];\n\t\tmat.b = *param[7];\n\t\tmat.c = *param[8];\n\t\tmat.d = *param[9];\n\t\tmat.tx = *param[10];\n\t\tmat.ty = *param[11];\n\t\t_this->OperateAffine(mat, src, srcrect, mode, opa, type);\n\t}\n\telse\n\t{\n\t\t// points mode\n\t\ttTVPPointD points[3];\n\t\tpoints[0].x = *param[6];\n\t\tpoints[0].y = *param[7];\n\t\tpoints[1].x = *param[8];\n\t\tpoints[1].y = *param[9];\n\t\tpoints[2].x = *param[10];\n\t\tpoints[2].y = *param[11];\n\t\t_this->OperateAffine(points, src, srcrect, mode, opa, type);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/operateAffine)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doBoxBlur)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttjs_int xblur = 1;\n\ttjs_int yblur = 1;\n\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\txblur = (tjs_int)*param[0];\n\t\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tyblur = (tjs_int)*param[1];\n\t\n\t_this->DoBoxBlur(xblur, yblur);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/doBoxBlur)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/adjustGamma)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams == 0) return TJS_S_OK;\n\n\ttTVPGLGammaAdjustData data;\n\tmemcpy(&data, &TVPIntactGammaAdjustData, sizeof(data));\n\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tdata.RGamma = param[0]->AsReal();\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\tdata.RFloor = *param[1];\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t\tdata.RCeil  = *param[2];\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\tdata.GGamma = param[3]->AsReal();\n\tif(numparams >= 5 && param[4]->Type() != tvtVoid)\n\t\tdata.GFloor = *param[4];\n\tif(numparams >= 6 && param[5]->Type() != tvtVoid)\n\t\tdata.GCeil  = *param[5];\n\tif(numparams >= 7 && param[6]->Type() != tvtVoid)\n\t\tdata.BGamma = param[6]->AsReal();\n\tif(numparams >= 8 && param[7]->Type() != tvtVoid)\n\t\tdata.BFloor = *param[7];\n\tif(numparams >= 9 && param[8]->Type() != tvtVoid)\n\t\tdata.BCeil  = *param[8];\n\n\t_this->AdjustGamma(data);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/adjustGamma)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doGrayScale)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->DoGrayScale();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/doGrayScale)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/flipLR) // not LRFlip\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->LRFlip();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/flipLR)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/flipUD) // not UDFlip\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->UDFlip();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/flipUD)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/convertType)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTVPDrawFace fromtype = (tTVPDrawFace)(tjs_int)*param[0];\n\n\t_this->ConvertLayerType(fromtype);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/convertType)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/update)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t// this event sets CallOnPaint flag of tTJSNI_Layer, to\n\t// invoke onPaint event.\n\n\tif(numparams < 1)\n\t{\n\t\t_this->UpdateByScript();\n\t\t\t// update entire area of the layer\n\t}\n\telse\n\t{\n\t\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t\ttjs_int l, t, w, h;\n\t\tl = (tjs_int)*param[0];\n\t\tt = (tjs_int)*param[1];\n\t\tw = (tjs_int)*param[2];\n\t\th = (tjs_int)*param[3];\n\t\t_this->UpdateByScript(tTVPRect(l, t, l+w, t+h));\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/update)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setCursorPos)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\t_this->SetCursorPos(*param[0], *param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setCursorPos)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/releaseCapture)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->ReleaseCapture();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/releaseCapture)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/releaseTouchCapture)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\n\tif(numparams >= 1)\n\t{\n\t\ttjs_uint32 id = static_cast<tjs_uint32>(param[0]->AsInteger());\n\t\t_this->ReleaseTouchCapture(id);\n\t}\n\telse\n\t{\n\t\t_this->ReleaseTouchCapture(0,true);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/releaseTouchCapture)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/focus) // not setFocus\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tbool direction = true;\n\tif(numparams >= 1) direction = param[0]->operator bool();\n\n\tbool succeeded = _this->SetFocus(direction);\n\n\tif(result) *result = (tjs_int)succeeded;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/focus)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/focusPrev)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSNI_BaseLayer *lay = _this->FocusPrev();\n\n\tif(result)\n\t{\n\t\tif(lay && lay->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(lay->GetOwnerNoAddRef(), lay->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/focusPrev)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/focusNext)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSNI_BaseLayer *lay = _this->FocusNext();\n\n\tif(result)\n\t{\n\t\tif(lay && lay->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(lay->GetOwnerNoAddRef(), lay->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/focusNext)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMode)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->SetMode();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeMode)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->RemoveMode();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/removeMode)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setAttentionPos) // not setAttentionPoint\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\n\t_this->SetAttentionPoint(*param[0], *param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setAttentionPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/beginTransition)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t// parameters are : <name>, [<withchildren>=true], [<transwith>=null],\n\t//                  [<options>]\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\tttstr name = *param[0];\n\tbool withchildren = true;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\twithchildren = param[1]->operator bool();\n\ttTJSNI_BaseLayer * transsrc = NULL;\n\tif(numparams >= 3 && param[2]->Type() != tvtVoid)\n\t{\n\t\ttTJSVariantClosure clo = param[2]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&transsrc)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t}\n\t}\n\tif(!transsrc) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\ttTJSVariantClosure options(NULL, NULL);\n\tif(numparams >= 4 && param[3]->Type() != tvtVoid)\n\t\toptions = param[3]->AsObjectClosureNoAddRef();\n\n\t_this->StartTransition(name, withchildren, transsrc, options);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/beginTransition)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stopTransition)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t_this->StopTransition();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stopTransition)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/assignImages)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer *src;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t_this->AssignImages(src);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/assignImages)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dump)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t_this->DumpStructure();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/dump)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/copyToBitmapFromMainImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Bitmap* dstbmp = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&dstbmp)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\tif( dstbmp ) _this->CopyFromMainImage( dstbmp );\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/copyToBitmapFromMainImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/copyFromBitmapToMainImage)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Bitmap* srcbmp = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Bitmap::ClassID, (iTJSNativeInstance**)&srcbmp)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\tif( srcbmp ) _this->AssignMainImageWithUpdate( srcbmp->GetBitmap() );\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/copyFromBitmapToMainImage)\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onHitTest)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\t/*\n\t\tthis event does not call \"action\" method\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(3, \"onHitTest\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"hit\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\t*/\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\tbool b = param[2]->operator bool();\n\n\t_this->SetHitTestWork(b);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onHitTest)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(2, \"onClick\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onDoubleClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(2, \"onDoubleClick\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onDoubleClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseDown\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"button\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseUp\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"button\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(3, \"onMouseMove\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseEnter)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onMouseEnter\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseEnter)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseLeave)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onMouseLeave\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseLeave)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchDown\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchUp\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchMove\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchScaling)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchScaling\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"startdistance\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"currentdistance\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"flag\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchScaling)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchRotate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(6, \"onTouchRotate\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"startangle\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"currentangle\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"distance\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"flag\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchRotate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMultiTouch)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onMultiTouch\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMultiTouch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onBlur)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onBlur\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"focused\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onBlur)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFocus)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onFocus\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"blurred\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"direction\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFocus)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onNodeEnabled)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onNodeEnabled\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onNodeEnabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onNodeDisabled)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onNodeDisabled\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onNodeDisabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(3, \"onKeyDown\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"process\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// call default key down behavior handler\n\tif(numparams < 3 || param[2]->operator bool())\n\t\t_this->DefaultKeyDown((tjs_int)*param[0], (tjs_int)*param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(3, \"onKeyUp\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"process\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// call default key up behavior handler\n\tif(numparams < 3 || param[2]->operator bool())\n\t\t_this->DefaultKeyUp((tjs_int)*param[0], (tjs_int)*param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyPress)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(2, \"onKeyPress\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"process\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// call default key down behavior handler\n\tif(numparams < 2 || param[1]->operator bool())\n\t{\n\t\tttstr p = *param[0];\n\t\ttjs_char code;\n\t\tif(p.IsEmpty()) code = 0; else code = (tjs_char)*p.c_str();\n\t\t_this->DefaultKeyPress(code);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyPress)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseWheel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseWheel\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"delta\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseWheel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSearchPrevFocusable)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onSearchPrevFocusable\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"layer\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// set focusable layer back\n\tif(param[0]->Type() != tvtVoid)\n\t{\n\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\ttTJSNI_BaseLayer *src;\n\t\t\tif(clo.Object)\n\t\t\t{\n\t\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t}\n\t\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t_this->SetFocusWork(src);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_this->SetFocusWork(NULL);\n\t\t}\n\t}\n\telse\n\t{\n\t\t_this->SetFocusWork(NULL);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSearchPrevFocusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onSearchNextFocusable)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onSearchNextFocusable\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"layer\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// set focusable layer back\n\tif(param[0]->Type() != tvtVoid)\n\t{\n\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\ttTJSNI_BaseLayer *src;\n\t\t\tif(clo.Object)\n\t\t\t{\n\t\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t}\n\t\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t_this->SetFocusWork(src);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_this->SetFocusWork(NULL);\n\t\t}\n\t}\n\telse\n\t{\n\t\t_this->SetFocusWork(NULL);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onSearchNextFocusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onBeforeFocus)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(3, \"onBeforeFocus\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"layer\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"blurred\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"direction\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\t// set focusable layer back\n\tif(param[0]->Type() != tvtVoid)\n\t{\n\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\ttTJSNI_BaseLayer *src;\n\t\t\tif(clo.Object)\n\t\t\t{\n\t\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t}\n\t\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t_this->SetFocusWork(src);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_this->SetFocusWork(NULL);\n\t\t}\n\t}\n\telse\n\t{\n\t\t_this->SetFocusWork(NULL);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onBeforeFocus)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onPaint)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onPaint\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onPaint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTransitionCompleted)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(2, \"onTransitionCompleted\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"dest\"); // destination (before exchanging)\n\t\tTVP_ACTION_INVOKE_MEMBER(\"src\"); // source (also before exchanging;can be a null)\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTransitionCompleted)\n//----------------------------------------------------------------------\n\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(parent)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\ttTJSNI_BaseLayer *parent = _this->GetParent();\n\t\tif(parent)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = parent->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2 *) NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\n\t\ttTJSNI_BaseLayer *parent;\n\t\ttTJSVariantClosure clo = param->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&parent)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t}\n\n\t\t_this->SetParent(parent);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(parent)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(children)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\tiTJSDispatch2 *dsp = _this->GetChildrenArrayObjectNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(children)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(order) // not orderIndex\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetOrderIndex();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetOrderIndex(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(order)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(absolute) // not absoluteOrderIndex\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetAbsoluteOrderIndex();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetAbsoluteOrderIndex(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(absolute)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(absoluteOrderMode) // not absoluteOrderIndexMode\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetAbsoluteOrderMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetAbsoluteOrderMode(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(absoluteOrderMode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetVisible();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetVisible(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(visible)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(cached)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetCached();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetCached(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(cached)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(nodeVisible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetNodeVisible();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(nodeVisible)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(opacity)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetOpacity();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetOpacity(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(opacity)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(window)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\tiTVPLayerTreeOwner* lto = _this->GetLayerTreeOwner();\n\t\tif(!lto)\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = lto->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(window)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(isPrimary)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->IsPrimary();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(isPrimary)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(left)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetLeft(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(left)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(top)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetTop(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(top)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetWidth(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHeight(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imageLeft)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetImageLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImageLeft(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imageLeft)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imageTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetImageTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImageTop(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imageTop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imageWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetImageWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImageWidth(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imageWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imageHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetImageHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImageHeight(static_cast<tjs_uint>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imageHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(type)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetType();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetType((tTVPLayerType)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(type)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(face)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetFace();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetFace((tTVPDrawFace)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(face)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(holdAlpha)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetHoldAlpha();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHoldAlpha(0!=(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(holdAlpha)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(clipLeft)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetClipLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetClipLeft(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(clipLeft)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(clipTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetClipTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetClipTop(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(clipTop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(clipWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetClipWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetClipWidth(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(clipWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(clipHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetClipHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetClipHeight(static_cast<tjs_int>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(clipHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imageModified)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetImageModified();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImageModified(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imageModified)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hitType)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetHitType();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHitType((tTVPHitType)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hitType)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hitThreshold)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetHitThreshold();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHitThreshold((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hitThreshold)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(cursor)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetCursor();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\tif(param->Type() == tvtString)\n\t\t\t_this->SetCursorByStorage(*param);\n\t\telse\n\t\t\t_this->SetCursorByNumber(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(cursor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(cursorX)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetCursorX();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetCursorX(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(cursorX)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(cursorY)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetCursorY();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetCursorY(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(cursorY)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hint)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetHint();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHint(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(showParentHint)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetShowParentHint();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetShowParentHint(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(showParentHint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(ignoreHintSensing)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetIgnoreHintSensing();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetIgnoreHintSensing(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(ignoreHintSensing)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(focusable)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetFocusable();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetFocusable(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(focusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(prevFocusable)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\ttTJSNI_BaseLayer *lay = _this->GetPrevFocusable();\n\t\tif(lay)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = lay->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(prevFocusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(nextFocusable)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\ttTJSNI_BaseLayer *lay = _this->GetNextFocusable();\n\t\tif(lay)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = lay->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(nextFocusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(joinFocusChain)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetJoinFocusChain();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetJoinFocusChain(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(joinFocusChain)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(nodeFocusable)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetNodeFocusable();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(nodeFocusable)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(focused)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetFocused();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(focused)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enabled)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetEnabled();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetEnabled(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(enabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(nodeEnabled)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetNodeEnabled();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(nodeEnabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(attentionLeft)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetAttentionLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetAttentionLeft((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(attentionLeft)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(attentionTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetAttentionTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetAttentionTop((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(attentionTop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(useAttention)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetUseAttention();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetUseAttention(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(useAttention)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imeMode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)_this->GetImeMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetImeMode((tTVPImeMode) (tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imeMode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(callOnPaint)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetCallOnPaint();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetCallOnPaint(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(callOnPaint)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(font)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\tiTJSDispatch2 *dsp = _this->GetFontObjectNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(font)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(name)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = _this->GetName();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetName(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(name)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(neutralColor)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int64)_this->GetNeutralColor();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetNeutralColor(static_cast<tjs_uint32>((tjs_int64)*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(neutralColor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hasImage)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t*result = (tjs_int)(bool)_this->GetHasImage();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);\n\t\t_this->SetHasImage((bool)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hasImage)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mainImageBuffer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetMainImagePixelBuffer());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mainImageBuffer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mainImageBufferForWrite)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetMainImagePixelBufferForWrite());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mainImageBufferForWrite)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mainImageBufferPitch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = _this->GetMainImagePixelBufferPitch();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mainImageBufferPitch)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(provinceImageBuffer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetProvinceImagePixelBuffer());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(provinceImageBuffer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(provinceImageBufferForWrite)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = (tTVInteger)reinterpret_cast<tjs_intptr_t>(_this->GetProvinceImagePixelBufferForWrite());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(provinceImageBufferForWrite)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(provinceImageBufferPitch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Layer);;\n\t\t*result = _this->GetProvinceImagePixelBufferPitch();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(provinceImageBufferPitch)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n\n\n}\n//---------------------------------------------------------------------------\n\n\n\nextern FontSystem* TVPFontSystem;\n//---------------------------------------------------------------------------\n// tTJSNI_Font : Font Native Object\n//---------------------------------------------------------------------------\ntTJSNI_Font::tTJSNI_Font()\n{\n\tLayer = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_Font::~tTJSNI_Font()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNI_Font::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjs_obj)\n{\n\tif( numparams >= 1 )\n\t{\n\t\tiTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef();\n\n\t\ttTJSNI_Layer *lay = NULL;\n\t\tif(TJS_FAILED(dsp->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&lay)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t\tLayer = lay;\n\t}\n\telse\n\t{\n\t\tLayer = NULL;\n\t\tFont = TVPFontSystem->GetDefaultFont();\n\t}\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Font::Invalidate()\n{\n\tLayer = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontFace(const ttstr & face)\n{\n\tif( Layer ) Layer->SetFontFace(face);\n\telse\n\t{\n\t\tif(Font.Face != face)\n\t\t{\n\t\t\tFont.Face = face;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_Font::GetFontFace() const\n{\n\tif( Layer ) return Layer->GetFontFace();\n\telse return Font.Face;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontHeight(tjs_int height)\n{\n\tif( Layer ) Layer->SetFontHeight(height);\n\telse\n\t{\n\t\tif(height < 0) height = -height; // TVP2 does not support negative value of height\n\t\tif(Font.Height != height)\n\t\t{\n\t\t\tFont.Height = height;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Font::GetFontHeight() const\n{\n\tif( Layer ) return Layer->GetFontHeight();\n\telse return Font.Height;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontAngle(tjs_int angle)\n{\n\tif( Layer ) Layer->SetFontAngle( angle );\n\telse\n\t{\n\t\tif(Font.Angle != angle)\n\t\t{\n\t\t\tangle = angle % 3600;\n\t\t\tif(angle < 0) angle += 3600;\n\t\t\tFont.Angle = angle;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Font::GetFontAngle() const\n{\n\tif( Layer ) return Layer->GetFontAngle();\n\telse return Font.Angle;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontBold(bool b)\n{\n\tif( Layer ) Layer->SetFontBold(b);\n\telse\n\t{\n\t\tif( (0!=(Font.Flags & TVP_TF_BOLD)) != b)\n\t\t{\n\t\t\tFont.Flags &= ~TVP_TF_BOLD;\n\t\t\tif(b) Font.Flags |= TVP_TF_BOLD;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Font::GetFontBold() const\n{\n\tif( Layer ) return Layer->GetFontBold();\n\telse return 0!=(Font.Flags & TVP_TF_BOLD);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontItalic(bool b)\n{\n\tif( Layer ) Layer->SetFontItalic(b);\n\telse\n\t{\n\t\tif( (0!=(Font.Flags & TVP_TF_ITALIC)) != b)\n\t\t{\n\t\t\tFont.Flags &= ~TVP_TF_ITALIC;\n\t\t\tif(b) Font.Flags |= TVP_TF_ITALIC;\n\t\t} \n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Font::GetFontItalic() const\n{\n\tif( Layer ) return Layer->GetFontItalic();\n\telse return 0!=(Font.Flags & TVP_TF_ITALIC);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontStrikeout(bool b)\n{\n\tif( Layer ) Layer->SetFontStrikeout(b);\n\telse\n\t{\n\t\tif( (0!=(Font.Flags & TVP_TF_STRIKEOUT)) != b)\n\t\t{\n\t\t\tFont.Flags &= ~TVP_TF_STRIKEOUT;\n\t\t\tif(b) Font.Flags |= TVP_TF_STRIKEOUT;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Font::GetFontStrikeout() const\n{\n\tif( Layer ) return Layer->GetFontStrikeout();\n\telse return 0!=(Font.Flags & TVP_TF_STRIKEOUT);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontUnderline(bool b)\n{\n\tif( Layer ) Layer->SetFontUnderline(b);\n\telse\n\t{\n\t\tif( (0!=(Font.Flags & TVP_TF_UNDERLINE)) != b)\n\t\t{\n\t\t\tFont.Flags &= ~TVP_TF_UNDERLINE;\n\t\t\tif(b) Font.Flags |= TVP_TF_UNDERLINE;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Font::GetFontUnderline() const\n{\n\tif( Layer ) return Layer->GetFontUnderline();\n\telse return 0!=(Font.Flags & TVP_TF_UNDERLINE);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::SetFontFaceIsFileName(bool b)\n{\n\tif( Layer ) Layer->SetFontFaceIsFileName(b);\n\telse\n\t{\n\t\tif( (0!=(Font.Flags & TVP_TF_FONTFILE)) != b)\n\t\t{\n\t\t\tFont.Flags &= ~TVP_TF_FONTFILE;\n\t\t\tif(b) Font.Flags |= TVP_TF_FONTFILE;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Font::GetFontFaceIsFileName() const\n{\n\tif( Layer ) return Layer->GetFontFaceIsFileName();\n\telse return 0!=(Font.Flags & TVP_TF_FONTFILE);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Font::GetTextWidthDirect(const ttstr & text)\n{\n\tGetCurrentRasterizer()->ApplyFont( Font );\n\ttjs_uint width = 0;\n\tconst tjs_char *buf = text.c_str();\n\twhile(*buf)\n\t{\n\t\ttjs_int w, h;\n\t\tGetCurrentRasterizer()->GetTextExtent( *buf, w, h );\n\t\twidth += w;\n\t\tbuf++;\n\t}\n\treturn width;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Font::GetTextWidth(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetTextWidth(text);\n\telse return GetTextWidthDirect(text);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Font::GetTextHeight(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetTextHeight(text);\n\telse return std::abs(Font.Height);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_Font::GetEscWidthX(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetEscWidthX(text);\n\telse return std::cos(Font.Angle * (M_PI/1800)) * GetTextWidthDirect(text);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_Font::GetEscWidthY(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetEscWidthY(text);\n\telse return std::sin(Font.Angle * (M_PI/1800)) * (-GetTextWidthDirect(text));\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_Font::GetEscHeightX(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetEscHeightX(text);\n\telse return std::sin(Font.Angle * (M_PI/1800)) * std::abs(Font.Height);\n}\n//---------------------------------------------------------------------------\ndouble tTJSNI_Font::GetEscHeightY(const ttstr & text)\n{\n\tif( Layer ) return Layer->GetEscHeightY(text);\n\telse return std::cos(Font.Angle * (M_PI/1800)) * std::abs(Font.Height);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::GetFontGlyphDrawRect( const ttstr & text, tTVPRect& area )\n{\n\tif( Layer )\n\t{\n\t\tLayer->GetFontGlyphDrawRect(text,area);\n\t}\n\telse\n\t{\n\t\tGetCurrentRasterizer()->ApplyFont( Font );\n\t\tGetCurrentRasterizer()->GetGlyphDrawRect( text, area );\n\t}\n}\n//---------------------------------------------------------------------------\nextern void TVPGetAllFontList(std::vector<ttstr>& list);\nvoid tTJSNI_Font::GetFontList(tjs_uint32 flags, std::vector<ttstr> & list)\n{\n\tif( Layer ) Layer->GetFontList(flags,list);\n\telse\n\t{\n\t\tstd::vector<ttstr> ansilist;\n\t\tTVPGetAllFontList(ansilist);\n\t\tfor(std::vector<ttstr>::iterator i = ansilist.begin(); i != ansilist.end(); i++)\n\t\t\tlist.push_back(i->c_str());\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::MapPrerenderedFont(const ttstr & storage)\n{\n\tif( Layer ) Layer->MapPrerenderedFont(storage);\n\telse TVPMapPrerenderedFont(Font, storage);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Font::UnmapPrerenderedFont()\n{\n\tif( Layer ) Layer->UnmapPrerenderedFont();\n\telse TVPUnmapPrerenderedFont(Font);\n}\n//---------------------------------------------------------------------------\nconst tTVPFont& tTJSNI_Font::GetFont() const\n{\n\tif( Layer ) return Layer->GetFont();\n\telse return Font;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Font : TJS Font class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Font::ClassID = -1;\ntTJSNC_Font::tTJSNC_Font() : tTJSNativeClass(TJS_W(\"Font\"))\n{\n\tTJS_BEGIN_NATIVE_MEMBERS(Font) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Font,\n\t/*TJS class name*/Font)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Font)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTextWidth)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetTextWidth(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getTextWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTextHeight)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetTextHeight(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getTextHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getEscWidthX)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetEscWidthX(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getEscWidthX)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getEscWidthY)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetEscWidthY(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getEscWidthY)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getEscHeightX)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetEscHeightX(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getEscHeightX)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getEscHeightY)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) *result = _this->GetEscHeightY(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getEscHeightY)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getGlyphDrawRect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\tif(result) {\n\t\ttTVPRect rt;\n\t\t_this->GetFontGlyphDrawRect( *param[0], rt );\n\t\tiTJSDispatch2 *disp = TVPCreateRectObject( rt.left, rt.top, rt.right, rt.bottom );\n\t\t*result = tTJSVariant(disp, disp);\n\t\tdisp->Release();\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getGlyphDrawRect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doUserSelect)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_uint32 flags = (tjs_int64)*param[0];\n\tttstr caption = *param[1];\n\tttstr prompt = *param[2];\n\tttstr samplestring = *param[3];\n\n\ttjs_int ret = // TODO: implement it ?\n#if 0\n\t\t(tjs_int)_this->GetLayer()->DoUserFontSelect(flags, caption,\n\t\tprompt, samplestring);\n#else\n\t\t0;\n#endif\n\n\tif(result) *result = ret;\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/doUserSelect)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getList)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_uint32 flags = static_cast<tjs_uint32>((tjs_int64)*param[0]);\n\n\tstd::vector<ttstr> list;\n\t_this->GetFontList(flags, list);\n\n\tif(result)\n\t{\n\t\tiTJSDispatch2 *dsp;\n\t\tdsp = TJSCreateArrayObject();\n\t\ttTJSVariant tmp(dsp, dsp);\n\t\t*result = tmp;\n\t\tdsp->Release();\n\n\t\tfor(tjs_uint i = 0; i < list.size(); i++)\n\t\t{\n\t\t\ttmp = list[i];\n\t\t\tdsp->PropSetByNum(TJS_MEMBERENSURE, i, &tmp, dsp);\n\t\t}\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/getList)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/mapPrerenderedFont)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t_this->MapPrerenderedFont(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/mapPrerenderedFont)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/unmapPrerenderedFont)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\tif(numparams < 0) return TJS_E_BADPARAMCOUNT;\n\n\t_this->UnmapPrerenderedFont();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/unmapPrerenderedFont)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(face)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontFace();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontFace(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(face)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontHeight(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bold)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontBold();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontBold(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bold)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(italic)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontItalic();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontItalic(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(italic)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(strikeout)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontStrikeout();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontStrikeout(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(strikeout)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(underline)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontUnderline();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontUnderline(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(underline)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(angle)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontAngle();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontAngle(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(angle)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(faceIsFileName)\n{\n\t// Facet@CƂĊJAFreeTypeł̂ݗLBÃC[IMELꍇ͕s\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t*result = _this->GetFontFaceIsFileName();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Font);\n\t\t_this->SetFontFaceIsFileName(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(faceIsFileName)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(rasterizer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetFontRasterizer();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTVPSetFontRasterizer(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(rasterizer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(defaultFaceName)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\t*result = TVPGetDefaultFontName();\n\t\t// *result = ttstr(TVPFontSystem->GetDefaultFontName());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tttstr name( *param );\n\t\t// don't override, specified by preference\n\t\t// TVPFontSystem->SetDefaultFontName( name.c_str() );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL(defaultFaceName)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Font\n//---------------------------------------------------------------------------\nstruct tFontClassHolder {\n\ttTJSNativeClass * Obj;\n\ttFontClassHolder() : Obj(NULL) {}\n\tvoid Set( tTJSNativeClass* obj ) {\n\t\tif( Obj ) {\n\t\t\tObj->Release();\n\t\t\tObj = NULL;\n\t\t}\n\t\tObj = obj;\n\t\tObj->AddRef();\n\t}\n\t~tFontClassHolder() { if( Obj ) Obj->Release(), Obj = NULL; }\n} static fontclassholder;\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Font()\n{\n\tif( fontclassholder.Obj ) {\n\t\ttTJSNativeClass* fontclass = fontclassholder.Obj;\n\t\tfontclass->AddRef();\n\t\treturn fontclass;\n\t}\n\ttTJSNativeClass* fontclass = new tTJSNC_Font();\n\tfontclassholder.Set( fontclass );\n\treturn fontclass;\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateFontObject(iTJSDispatch2 * layer)\n{\n\tif( fontclassholder.Obj == NULL ) {\n\t\tTVPThrowInternalError;\n\t}\n\tiTJSDispatch2 *out;\n\ttTJSVariant param(layer);\n\ttTJSVariant *pparam = &param;\n\tif(TJS_FAILED(fontclassholder.Obj->CreateNew(0, NULL, NULL, &out, 1, &pparam, fontclassholder.Obj)))\n\t\tTVPThrowInternalError;\n\n\treturn out;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPGetObjectFrom_NI_BaseLayer(tTJSNI_BaseLayer * layer)\n{\n\tiTJSDispatch2 * disp = layer->Owner;\n\tif(disp) disp->AddRef();\n\treturn disp;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/LayerIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n#ifndef LayerIntfH\n#define LayerIntfH\n\n\n#include \"tjsNative.h\"\n#include \"tvpfontstruc.h\"\n#include \"ComplexRect.h\"\n#include \"drawable.h\"\n#include \"tvpinputdefs.h\"\n#include \"TransIntf.h\"\n#include \"EventIntf.h\"\n#include \"ObjectList.h\"\n\n\n\n\n//---------------------------------------------------------------------------\n// global flags\n//---------------------------------------------------------------------------\nextern bool TVPFreeUnusedLayerCache;\n\n//---------------------------------------------------------------------------\n// initial bitmap holder ( since tTVPBaseBitmap cannot create empty bitmap )\n//---------------------------------------------------------------------------\nconst tTVPBaseTexture & TVPGetInitialBitmap();\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// bitmap holder refcont control ( for Bitmap class )\n//---------------------------------------------------------------------------\nvoid TVPTempBitmapHolderAddRef();\nvoid TVPTempBitmapHolderRelease();\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// global options\n//---------------------------------------------------------------------------\nenum tTVPGraphicSplitOperationType\n{ gsotNone, gsotSimple, gsotInterlace, gsotBiDirection };\nextern tTVPGraphicSplitOperationType TVPGraphicSplitOperationType;\nextern bool TVPDefaultHoldAlpha;\n//---------------------------------------------------------------------------\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// drawn face types\n//---------------------------------------------------------------------------\nenum tTVPDrawFace\n{\n\tdfBoth  = 0,\n\tdfAlpha = 0,\n\tdfAddAlpha = 4,\n\tdfMain = 1,\n\tdfOpaque = 1,\n\tdfMask = 2,\n\tdfProvince = 3,\n\tdfAuto = 128 // face is chosen automatically from the layer type\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// alias to blending types\n//---------------------------------------------------------------------------\nenum tTVPBlendOperationMode\n{\n\tomPsNormal = ltPsNormal,\n\tomPsAdditive = ltPsAdditive,\n\tomPsSubtractive = ltPsSubtractive,\n\tomPsMultiplicative = ltPsMultiplicative,\n\tomPsScreen = ltPsScreen,\n\tomPsOverlay = ltPsOverlay,\n\tomPsHardLight = ltPsHardLight,\n\tomPsSoftLight = ltPsSoftLight,\n\tomPsColorDodge = ltPsColorDodge,\n\tomPsColorDodge5 = ltPsColorDodge5,\n\tomPsColorBurn = ltPsColorBurn,\n\tomPsLighten = ltPsLighten,\n\tomPsDarken = ltPsDarken,\n\tomPsDifference = ltPsDifference,\n\tomPsDifference5 = ltPsDifference5,\n\tomPsExclusion = ltPsExclusion,\n\tomAdditive = ltAdditive,\n\tomSubtractive = ltSubtractive,\n\tomMultiplicative = ltMultiplicative,\n\tomDodge = ltDodge,\n\tomDarken = ltDarken,\n\tomLighten = ltLighten,\n\tomScreen = ltScreen,\n\tomAlpha = ltTransparent,\n\tomAddAlpha = ltAddAlpha,\n\tomOpaque = ltCoverRect,\n\n\tomAuto = 128   // operation mode is guessed from the source layer type\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// layer hit test type\n//---------------------------------------------------------------------------\nenum tTVPHitType {htMask, htProvince};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// color key types\n//---------------------------------------------------------------------------\n#define TVP_clAdapt\t\t\t\t((tjs_uint32)(0x01ffffff))\n#define TVP_clNone\t\t\t\t((tjs_uint32)(0x1fffffff))\n#define TVP_clPalIdx\t\t\t((tjs_uint32)(0x03000000))\n#define TVP_clAlphaMat\t\t\t((tjs_uint32)(0x04000000))\n#define TVP_Is_clPalIdx(n)\t\t((tjs_uint32)(((n)&0xff000000) == TVP_clPalIdx))\n#define TVP_get_clPalIdx(n)\t\t((tjs_uint32)((n)&0xff))\n#define TVP_Is_clAlphaMat(n)\t((tjs_uint32)(((n)&0xff000000) == TVP_clAlphaMat))\n#define TVP_get_clAlphaMat(n)\t((tjs_uint32)((n)&0xffffff))\n//---------------------------------------------------------------------------\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// update optimization options\n//---------------------------------------------------------------------------\n#define TVP_UPDATE_UNITE_LIMIT 300\n#define TVP_CACHE_UNITE_LIMIT 60\n#define TVP_EXPOSED_UNITE_LIMIT 30\n#define TVP_DIRECT_UNITE_LIMIT 10\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPToActualColor :  convert color identifier to actual color\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_uint32, TVPToActualColor, (tjs_uint32 col));\n\t// implement in each platform\nTJS_EXP_FUNC_DEF(tjs_uint32, TVPFromActualColor, (tjs_uint32 col));\n\t// implement in each platform\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Plugin service functions\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseLayer;\nTJS_EXP_FUNC_DEF(iTJSDispatch2 *, TVPGetObjectFrom_NI_BaseLayer,   (tTJSNI_BaseLayer * layer));\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseLayer implementation\n//---------------------------------------------------------------------------\nclass tTJSNI_BaseWindow;\nclass tTVPBaseBitmap;\nclass tTVPLayerManager;\nclass tTJSNI_BaseLayer :\n\tpublic tTJSNativeInstance, public tTVPDrawable,\n\tpublic tTVPCompactEventCallbackIntf\n{\n\tfriend class tTVPLayerManager;\n\tfriend iTJSDispatch2 * TVPGetObjectFrom_NI_BaseLayer(tTJSNI_BaseLayer * layer);\nprotected:\n\tiTJSDispatch2 *Owner;\n\ttTJSVariantClosure ActionOwner;\n\n\t//---------------------------------------------- object lifetime stuff --\npublic:\n\ttTJSNI_BaseLayer(void);\n\t~tTJSNI_BaseLayer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\tiTJSDispatch2 * GetOwnerNoAddRef() const { return Owner; }\n\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n\n\nprivate:\n\tbool Shutdown; // true when shutting down\n\tbool CompactEventHookInit;\n\tvoid RegisterCompactEventHook();\n\tvoid TJS_INTF_METHOD OnCompact(tjs_int level); // method from tTVPCompactEventCallbackIntf\n\n\t//----------------------------------------------- interface to manager --\nprivate:\n\ttTVPLayerManager *Manager;\npublic:\n\ttTVPLayerManager *GetManager() const { return Manager; }\n\tclass iTVPLayerTreeOwner * GetLayerTreeOwner() const;\n\n\t//---------------------------------------------------- tree management --\nprivate:\n\ttTJSNI_BaseLayer *Parent;\n\ttObjectList<tTJSNI_BaseLayer> Children;\n\tttstr Name;\n\tbool Visible;\n\ttjs_int Opacity;\n\ttjs_uint OrderIndex;\n\t\t// index in parent's 'Children' array.\n\t\t// do not access this variable directly; use GetOrderIndex() instead.\n\ttjs_uint OverallOrderIndex;\n\t\t// index in overall tree.\n\t\t// use GetOverallOrderIndex instead\n\tbool AbsoluteOrderMode; // manage Z order in absolute Z position\n\ttjs_int AbsoluteOrderIndex;\n\t\t// do not access this variable directly; use GetAbsoluteOrderIndex() instead. \n\n\tbool ChildrenOrderIndexValid;\n\n\ttjs_int VisibleChildrenCount;\n\tiTJSDispatch2 *ChildrenArray; // Array object which holds children array ...\n\tiTJSDispatch2 *ArrayClearMethod; // holds Array.clear method\n\tbool ChildrenArrayValid;\n\n\tvoid Join(tTJSNI_BaseLayer *parent); // join to the parent\n\tvoid Part(); // part from the parent\n\n\tvoid AddChild(tTJSNI_BaseLayer *child);\n\tvoid SeverChild(tTJSNI_BaseLayer *child);\n\npublic:\n\tiTJSDispatch2 * GetChildrenArrayObjectNoAddRef();\n\nprivate:\n\n\ttTJSNI_BaseLayer* GetAncestorChild(tTJSNI_BaseLayer *ancestor);\n\t\t// retrieve \"ancestor\"'s child that is ancestor of this ( can be thisself )\n\tbool IsAncestor(tTJSNI_BaseLayer *ancestor);\n\t\t// is \"ancestor\" is ancestor of this layer ? (cannot be itself)\n\tbool IsAncestorOrSelf(tTJSNI_BaseLayer *ancestor)\n\t\t{ return ancestor == this || IsAncestor(ancestor); }\n\t\t\t// same as IsAncestor (but can be itself)\n\n\tvoid RecreateOverallOrderIndex(tjs_uint& index,\n\t\tstd::vector<tTJSNI_BaseLayer*>& nodes);\n\n\tvoid Exchange(tTJSNI_BaseLayer *target, bool keepchild = false);\n\t\t// exchange this for the other layer\n\tvoid Swap(tTJSNI_BaseLayer *target) // swap this for the other layer\n\t\t{ Exchange(target, true); }\n\n\ttjs_int GetVisibleChildrenCount()\n\t{ if(VisibleChildrenCount == -1) CheckChildrenVisibleState();\n\t\treturn VisibleChildrenCount; }\n\n\tvoid CheckChildrenVisibleState();\n\tvoid NotifyChildrenVisualStateChanged();\n\n\tvoid RecreateOrderIndex();\n\npublic:\n\ttjs_uint GetOrderIndex()\n\t{\n\t\tif(!Parent) return 0;\n\t\tif(Parent->ChildrenOrderIndexValid) return OrderIndex;\n\t\tParent->RecreateOrderIndex();\n\t\treturn OrderIndex;\n\t}\n\n\t// SetOrderIndex are below\n\n\ttjs_uint GetOverallOrderIndex();\n\n\ttTJSNI_BaseLayer * GetParent() const { return Parent; }\n\tvoid SetParent(tTJSNI_BaseLayer *parent) { Join(parent); }\n\n\ttjs_uint GetCount() { return Children.GetActualCount(); }\n\n\ttTJSNI_BaseLayer * GetChildren(tjs_int idx)\n\t\t{ Children.Compact(); return Children[idx]; }\n\n\tconst ttstr & GetName() const { return Name; }\n\tvoid SetName(const ttstr &name) { Name = name; }\n\tbool GetVisible() const { return Visible; }\n\tvoid SetVisible(bool st);\n\ttjs_int GetOpacity() const { return Opacity; }\n\tvoid SetOpacity(tjs_int opa);\n\tbool IsSeen() const { return Visible && Opacity != 0; }\n\tbool IsPrimary() const;\n\n\tbool GetParentVisible() const; // is parent visible? this does not check opacity\n\tbool GetNodeVisible() { return GetParentVisible() && Visible; } // this does not check opacity\n\n\ttTJSNI_BaseLayer * GetNeighborAbove(bool loop = false);\n\ttTJSNI_BaseLayer * GetNeighborBelow(bool loop = false);\n\nprivate:\n\tvoid CheckZOrderMoveRule(tTJSNI_BaseLayer *lay);\n\tvoid ChildChangeOrder(tjs_int from, tjs_int to);\n\tvoid ChildChangeAbsoluteOrder(tjs_int from, tjs_int abs_to);\n\n\npublic:\n\tvoid MoveBefore(tTJSNI_BaseLayer *lay); // move before sibling : lay\n\tvoid MoveBehind(tTJSNI_BaseLayer *lay); // move behind sibling : lay\n\n\tvoid SetOrderIndex(tjs_int index);\n\n\tvoid BringToBack(); // to most back position\n\tvoid BringToFront(); // to most front position\n\n\ttjs_int GetAbsoluteOrderIndex(); // retrieve order index in absolute position\n\tvoid SetAbsoluteOrderIndex(tjs_int index);\n\n\tbool GetAbsoluteOrderMode() const { return AbsoluteOrderMode; }\n\tvoid SetAbsoluteOrderMode(bool b);\n\npublic:\n\tvoid DumpStructure(int level = 0);  // dump layer structure to dms\n\n\n\n\t//--------------------------------------------- layer type management --\nprotected:\n\ttTVPLayerType Type; // user set Type\n\ttTVPLayerType DisplayType; // actual Type\n\t\t// note that Type and DisplayType are different when Type = {ltEffect|ltFilter}\n\n\tvoid NotifyLayerTypeChange();\n\n\tvoid UpdateDrawFace(); // set DrawFace from Face and Type\npublic:\n\ttTVPBlendOperationMode GetOperationModeFromType() const;\n\t\t// returns corresponding blend operation mode from layer type\n\npublic:\n\ttTVPLayerType GetType() const { return Type; }\n\tvoid SetType(tTVPLayerType type);\n\n\tconst tjs_char * GetTypeNameString();\n\n\tvoid ConvertLayerType(tTVPDrawFace fromtype);\n\n\t//-------------------------------------------- geographical management --\nprotected:\n\ttTVPRect Rect;\n\tbool ExposedRegionValid;\n\ttTVPComplexRect ExposedRegion; // exposed region (no-children-overlapped-region)\n\ttTVPComplexRect OverlappedRegion; // overlapped region (overlapped by children)\n\t\t// above two shuld not be accessed directly\n\n\tvoid SetToCreateExposedRegion() { ExposedRegionValid = false; }\n\tvoid CreateExposedRegion(); // create exposed/overlapped region information\n\tconst tTVPComplexRect & GetExposedRegion()\n\t\t{ if(!ExposedRegionValid) CreateExposedRegion();\n\t\t  return ExposedRegion; }\n\tconst tTVPComplexRect & GetOverlappedRegion()\n\t\t{ if(!ExposedRegionValid) CreateExposedRegion();\n\t\t  return OverlappedRegion; }\n\n\tvoid InternalSetSize(tjs_uint width, tjs_uint height);\n\tvoid InternalSetBounds(const tTVPRect &rect);\n\n\tvoid ConvertToParentRects(tTVPComplexRect &dest, const tTVPComplexRect &src);\n\nprivate:\n\npublic:\n\tconst tTVPRect & GetRect() const { return Rect; }\n\ttjs_int GetLeft() const { return Rect.left; }\n\ttjs_int GetTop() const { return Rect.top; }\n\ttjs_uint GetWidth() const { return (tjs_uint)Rect.get_width(); }\n\ttjs_uint GetHeight() const { return (tjs_uint)Rect.get_height(); }\n\n\n\tvoid SetLeft(tjs_int left);\n\tvoid SetTop(tjs_int top);\n\tvoid SetPosition(tjs_int left, tjs_int top);\n\tvoid SetWidth(tjs_uint width);\n\tvoid SetHeight(tjs_uint height);\n\tvoid SetSize(tjs_uint width, tjs_uint height);\n\tvoid SetBounds(const tTVPRect &rect);\n\n\tvoid ParentRectToChildRect(tTVPRect &rect);\n\n\tvoid ToPrimaryCoordinates(tjs_int &x, tjs_int &y) const;\n\tvoid FromPrimaryCoordinates(tjs_int &x, tjs_int &y) const;\n\tvoid FromPrimaryCoordinates(tjs_real &x, tjs_real &y) const;\n\n\t//-------------------------------------------- image buffer management --\n\ttTVPBaseTexture *MainImage;\nprotected:\n\tbool CanHaveImage; // whether the layer can have image\n\ttTVPBaseBitmap *ProvinceImage;\n\ttjs_uint32 NeutralColor; // Neutral Color (which can be set by the user)\n\ttjs_uint32 TransparentColor; // transparent color (which cannot be set by the user, decided by layer type)\n\n\tvoid ChangeImageSize(tjs_uint width, tjs_uint height);\n\n\ttjs_int ImageLeft; // image offset left\n\ttjs_int ImageTop; // image offset top\n\n\tvoid AllocateImage();\n\tvoid DeallocateImage();\n\tvoid AllocateProvinceImage();\n\tvoid DeallocateProvinceImage();\n\tvoid AllocateDefaultImage();\n\npublic:\n\tvoid AssignImages(tTJSNI_BaseLayer *src); // assign image content\n\n    void AssignMainImage(iTVPBaseBitmap *bmp);\n\t\t// assign single main bitmap image. the image size assigned must be\n\t\t// identical to the destination layer bitmap.\n\n\tvoid AssignMainImageWithUpdate(iTVPBaseBitmap *bmp);\n\tvoid CopyFromMainImage( class tTJSNI_Bitmap* bmp );\n#ifndef TVP_REVRGB\n#define TVP_REVRGB(v) ((v & 0xFF00FF00) | ((v >> 16) & 0xFF) | ((v & 0xFF) << 16))\n#endif\n\tvoid SetNeutralColor(tjs_uint32 color) { NeutralColor = TVP_REVRGB(color); }\n\ttjs_uint32 GetNeutralColor() const { return TVP_REVRGB(NeutralColor); }\n\n\tvoid SetHasImage(bool b);\n\tbool GetHasImage() const;\n\npublic:\n\tvoid SetImageLeft(tjs_int left);\n\ttjs_int GetImageLeft() const;\n\tvoid SetImageTop(tjs_int top);\n\ttjs_int GetImageTop() const;\n\tvoid SetImagePosition(tjs_int left, tjs_int top);\n\tvoid SetImageWidth(tjs_uint width);\n\ttjs_uint GetImageWidth() const;\n\tvoid SetImageHeight(tjs_uint height);\n\ttjs_uint GetImageHeight() const;\n\nprivate:\n\tvoid InternalSetImageSize(tjs_uint width, tjs_uint height);\npublic:\n\tvoid SetImageSize(tjs_uint width, tjs_uint height);\nprivate:\n\tvoid ImageLayerSizeChanged(); // called from geographical management\npublic:\n\ttTVPBaseTexture * GetMainImage() { ApplyFont(); return MainImage; }\n\ttTVPBaseBitmap * GetProvinceImage() { ApplyFont(); return ProvinceImage; }\n\t\t// exporting of these two members is a bit dangerous\n\t\t// in the manner of protecting\n\t\t// ( user can resize the image with the returned object !? )\n\n\tvoid IndependMainImage(bool copy = true);\n\tvoid IndependProvinceImage(bool copy = true);\n\n\tvoid SaveLayerImage(const ttstr &name, const ttstr &type);\n\n\tvoid AssignTexture(class iTVPTexture2D *tex);\n\tiTJSDispatch2 * LoadImages(const ttstr &name, tjs_uint32 colorkey);\n\n\tvoid LoadProvinceImage(const ttstr &name);\n\n\ttjs_uint32 GetMainPixel(tjs_int x, tjs_int y) const;\n\tvoid SetMainPixel(tjs_int x, tjs_int y, tjs_uint32 color);\n\ttjs_int GetMaskPixel(tjs_int x, tjs_int y) const;\n\tvoid SetMaskPixel(tjs_int x, tjs_int y, tjs_int mask);\n\ttjs_int GetProvincePixel(tjs_int x, tjs_int y) const;\n\tvoid SetProvincePixel(tjs_int x, tjs_int y, tjs_int n);\n\n\tconst void * GetMainImagePixelBuffer() const;\n\tvoid * GetMainImagePixelBufferForWrite();\n\ttjs_int GetMainImagePixelBufferPitch() const;\n\tconst void * GetProvinceImagePixelBuffer() const;\n\tvoid * GetProvinceImagePixelBufferForWrite();\n\ttjs_int GetProvinceImagePixelBufferPitch() const;\n\n\t//---------------------------------- input event / hit test management --\nprivate:\n\ttTVPHitType HitType;\n\ttjs_int HitThreshold;\n\tbool OnHitTest_Work;\n\tbool Enabled; // is layer enabled for input?\n\tbool EnabledWork; // work are for delivering onNodeEnabled or onNodeDisabled\n\tbool Focusable; // is layer focusable ?\n\tbool JoinFocusChain; // does layer join the focus chain ?\n\ttTJSNI_BaseLayer *FocusWork;\n\n\ttjs_int AttentionLeft; // attention position\n\ttjs_int AttentionTop;\n\ttjs_int UseAttention;\n\n\ttTVPImeMode ImeMode; // ime mode\n\n\ttjs_int Cursor; // mouse cursor\n\ttjs_int CursorX_Work; // holds x-coordinate in SetCursorX and SetCursorY\n\npublic:\n\tvoid SetCursorByStorage(const ttstr &storage);\n\tvoid SetCursorByNumber(tjs_int num);\n\n\nprivate:\n\ttjs_int GetLayerActiveCursor(); // return layer's actual (active) mouse cursor\n\tvoid SetCurrentCursorToWindow(); // set current layer cusor to the window\n\nprivate:\n\tbool _HitTestNoVisibleCheck(tjs_int x, tjs_int y);\n\npublic:\n\tbool HitTestNoVisibleCheck(tjs_int x, tjs_int y);\n\tvoid SetHitTestWork(bool b) { OnHitTest_Work = b; }\n\n\ttjs_int GetCursor() const { return Cursor; }\n\nprivate:\n\tttstr Hint; // layer hint text\n\tbool ShowParentHint; // show parent's hint ?\n\tbool IgnoreHintSensing;\n\n\tvoid SetCurrentHintToWindow(); // set current hint to the window\n\npublic:\n\tconst ttstr & GetHint() const { return Hint; }\n\tvoid SetHint(const ttstr & hint);\n\tbool GetShowParentHint() const { return ShowParentHint; }\n\tvoid SetShowParentHint(bool b) { ShowParentHint = b; }\n\tbool GetIgnoreHintSensing() const { return IgnoreHintSensing; }\n\tvoid SetIgnoreHintSensing(bool b) { IgnoreHintSensing = b; }\n\npublic:\n\ttjs_int GetAttentionLeft() const { return AttentionLeft; }\n\tvoid SetAttentionLeft(tjs_int l);\n\ttjs_int GetAttentionTop() const { return AttentionTop; }\n\tvoid SetAttentionTop(tjs_int t);\n\tvoid SetAttentionPoint(tjs_int l, tjs_int t);\n\tbool GetUseAttention() const { return 0!=UseAttention; }\n\tvoid SetUseAttention(bool b);\n\nprivate:\n\npublic:\n\tvoid SetImeMode(tTVPImeMode mode);\n\ttTVPImeMode GetImeMode() const { return ImeMode; }\n\npublic:\n\t// these mouse cursor position functions are based on layer's coordinates,\n\t// not layer image's coordinates.\n\ttjs_int GetCursorX();\n\tvoid SetCursorX(tjs_int x);\n\ttjs_int GetCursorY();\n\tvoid SetCursorY(tjs_int y);\n\tvoid SetCursorPos(tjs_int x, tjs_int y);\n\nprivate:\n\tbool GetMostFrontChildAt(tjs_int x, tjs_int y, tTJSNI_BaseLayer **lay,\n\t\tconst tTJSNI_BaseLayer *except = NULL, bool get_disabled = false);\n\npublic:\n\ttTJSNI_BaseLayer * GetMostFrontChildAt(tjs_int x, tjs_int y, bool exclude_self = false,\n\t\tbool get_disabled = false);\n\n\ttTVPHitType GetHitType() const { return HitType; }\n\tvoid SetHitType(tTVPHitType type) { HitType = type; }\n\n\ttjs_int GetHitThreshold() const { return HitThreshold; }\n\tvoid SetHitThreshold(tjs_int t) { HitThreshold = t; }\n\nprivate:\n\tvoid FireClick(tjs_int x, tjs_int y);\n\tvoid FireDoubleClick(tjs_int x, tjs_int y);\n\tvoid FireMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid FireMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid FireMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags);\n\tvoid FireMouseEnter();\n\tvoid FireMouseLeave();\n\n\tvoid FireTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid FireTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid FireMultiTouch();\n\npublic:\n\tvoid ReleaseCapture();\n\tvoid ReleaseTouchCapture( tjs_uint32 id, bool all = false );\n\nprivate:\n\ttTJSNI_BaseLayer *SearchFirstFocusable(bool ignore_chain_focusable = true);\n\n\ttTJSNI_BaseLayer *_GetPrevFocusable(); // search next focusable layer backward\n\ttTJSNI_BaseLayer *_GetNextFocusable(); // search next focusable layer forward\n\npublic:\n\ttTJSNI_BaseLayer *GetPrevFocusable();\n\ttTJSNI_BaseLayer *GetNextFocusable();\n\tvoid SetFocusWork(tTJSNI_BaseLayer *lay)\n\t\t{ FocusWork = lay; }\n\npublic:\n\n\ttTJSNI_BaseLayer * FocusPrev();\n\ttTJSNI_BaseLayer * FocusNext();\n\n\tvoid SetFocusable(bool b);\n\tbool GetFocusable() const { return Focusable; }\n\n\tvoid SetJoinFocusChain(bool b) { JoinFocusChain = b; }\n\tbool GetJoinFocusChain() const { return JoinFocusChain; }\n\n\tbool CheckFocusable() const { return Focusable && Visible && Enabled; }\n\tbool ParentFocusable() const;\n\tbool GetNodeFocusable()\n\t\t{ return CheckFocusable() && ParentFocusable() && !IsDisabledByMode(); }\n\n\tbool SetFocus(bool direction = true);\n\n\tbool GetFocused();\n\nprivate:\n\tvoid FireBlur(tTJSNI_BaseLayer *prevfocused);\n\tvoid FireFocus(tTJSNI_BaseLayer *prevfocused, bool direction);\n\ttTJSNI_BaseLayer * FireBeforeFocus(tTJSNI_BaseLayer *prevfocused, bool direction);\n\npublic:\n\tvoid SetMode();\n\tvoid RemoveMode();\n\n\tbool IsDisabledByMode();  // is \"this\" layer disable by modal layer?\n\nprivate:\n\npublic:\n\tvoid NotifyNodeEnabledState();\n\tvoid SaveEnabledWork();\n\tvoid SetEnabled(bool b);\n\tbool ParentEnabled();\n\tbool GetEnabled() const { return Enabled; }\n\n\tbool GetNodeEnabled()\n\t\t{ return GetEnabled() && ParentEnabled() && !IsDisabledByMode(); }\n\nprivate:\n\tvoid FireKeyDown(tjs_uint key, tjs_uint32 shift);\n\tvoid FireKeyUp(tjs_uint key, tjs_uint32 shift);\n\tvoid FireKeyPress(tjs_char key);\n\tvoid FireMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y);\n\npublic:\n\tvoid DefaultKeyDown(tjs_uint key, tjs_uint32 shift); // default keyboard behavior\n\tvoid DefaultKeyUp(tjs_uint key, tjs_uint32 shift); // default keyboard behavior\n\tvoid DefaultKeyPress(tjs_char key); // default keyboard behavior\n\n\t//--------------------------------------------------- cache management --\nprivate:\n\ttTVPBaseTexture *CacheBitmap;\n\t//tTVPComplexRect CachedRegion;\n\n\tvoid AllocateCache();\n\tvoid ResizeCache();\n\tvoid DeallocateCache();\n\tvoid DispSizeChanged(); // is called from geographical management\n\tvoid CompactCache(); // free cache image if the cache is not needed\n\n\ttjs_uint CacheEnabledCount;\n\n\tbool Cached;  // script-controlled cached state\n\npublic:\n\tbool GetCacheEnabled() const { return CacheEnabledCount!=0; }\n\n\n\ttjs_uint IncCacheEnabledCount();\n\ttjs_uint DecCacheEnabledCount();\n\n\tvoid SetCached(bool b);\n\tbool GetCached() const { return Cached; }\n\n\t//--------------------------------------------- drawing function stuff --\nprotected:\n\ttTVPDrawFace DrawFace; // (actual) current drawing layer face\n\ttTVPDrawFace Face; // (outward) current drawing layer face\n\n\tbool HoldAlpha; // whether the layer alpha channel is to be kept\n\t\t// when the layer type is ltOpaque\n\npublic:\n\tvoid SetFace(tTVPDrawFace f) { Face = f; UpdateDrawFace(); }\n\ttTVPDrawFace GetFace() const { return Face; }\n\n\tvoid SetHoldAlpha(bool b)  { HoldAlpha = b; }\n\tbool GetHoldAlpha() const  { return HoldAlpha; }\n\nprotected:\n\tbool ImageModified; // flag to know modification of layer image\n\ttTVPRect ClipRect; // clipping rectangle\npublic:\n\tvoid ResetClip();\n\tvoid SetClip(tjs_int left, tjs_int top, tjs_int width, tjs_int height);\n\ttjs_int GetClipLeft() const { return ClipRect.left; }\n\tvoid SetClipLeft(tjs_int left);\n\ttjs_int GetClipTop() const { return ClipRect.top; }\n\tvoid SetClipTop(tjs_int top);\n\ttjs_int GetClipWidth() const { return ClipRect.right - ClipRect.left; }\n\tvoid SetClipWidth(tjs_int width);\n\ttjs_int GetClipHeight() const { return ClipRect.bottom - ClipRect.top; }\n\tvoid SetClipHeight(tjs_int height);\n    const tTVPRect& GetClip() const { return ClipRect; }\n\nprivate:\n\tbool ClipDestPointAndSrcRect(tjs_int &dx, tjs_int &dy,\n\t\ttTVPRect &srcrectout, const tTVPRect &srcrect) const;\n\n\nprivate:\n\tbool GetBltMethodFromOperationModeAndDrawFace(\n\t\ttTVPBBBltMethod & result,\n\t\ttTVPBlendOperationMode mode);\t\n\npublic:\n\tvoid FillRect(const tTVPRect &rect, tjs_uint32 color);\n\tvoid ColorRect(const tTVPRect &rect, tjs_uint32 color, tjs_int opa);\n\n\tvoid DrawText(tjs_int x, tjs_int y, const ttstr &text, tjs_uint32 color,\n\t\ttjs_int opa, bool aa, tjs_int shadowlevel, tjs_uint32 shadowcolor,\n\t\t\ttjs_int shadowwidth,\n\t\ttjs_int shadowofsx, tjs_int shadowofsy);\n\n\tvoid DrawGlyph(tjs_int x, tjs_int y, iTJSDispatch2* glyph, tjs_uint32 color,\n\t\ttjs_int opa, bool aa, tjs_int shadowlevel, tjs_uint32 shadowcolor,\n\t\ttjs_int shadowwidth, tjs_int shadowofsx, tjs_int shadowofsy);\n\n\tvoid PiledCopy(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &rect);\n\n\tvoid CopyRect(tjs_int dx, tjs_int dy, iTVPBaseBitmap *src, iTVPBaseBitmap *provincesrc,\n\t\tconst tTVPRect &rect);\n\t\n\tbool Copy9Patch( const iTVPBaseBitmap *src, tTVPRect &margin );\n\n\tvoid StretchCopy(const tTVPRect &destrect, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &rect, tTVPBBStretchType mode = stNearest, tjs_real typeopt = 0.0);\n\n\tvoid AffineCopy(const t2DAffineMatrix &matrix, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBBStretchType mode = stNearest, bool clear = false);\n\n\tvoid AffineCopy(const tTVPPointD *points, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBBStretchType mode = stNearest, bool clear = false);\n\n\tvoid PileRect(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &rect, tjs_int opacity = 255);\n\n\tvoid BlendRect(tjs_int dx, tjs_int dy, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &rect, tjs_int opacity = 255);\n\n\tvoid OperateRect(tjs_int dx, tjs_int dy, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &rect, tTVPBlendOperationMode mode = omAuto,\n\t\t\ttjs_int opacity = 255);\n\n\tvoid StretchPile(const tTVPRect &destrect, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid StretchBlend(const tTVPRect &destrect, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid OperateStretch(const tTVPRect &destrect, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode = omAuto, tjs_int opacity = 255,\n\t\t\ttTVPBBStretchType type = stNearest, tjs_real typeopt = 0.0);\n\n\tvoid AffinePile(const t2DAffineMatrix &matrix, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid AffinePile(const tTVPPointD *points, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid AffineBlend(const t2DAffineMatrix &matrix, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid AffineBlend(const tTVPPointD *points, tTJSNI_BaseLayer *src,\n\t\tconst tTVPRect &srcrect, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid OperateAffine(const t2DAffineMatrix &matrix, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode = omAuto, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid OperateAffine(const tTVPPointD *points, iTVPBaseBitmap *src,\n\t\tconst tTVPRect &srcrect, tTVPBlendOperationMode mode = omAuto, tjs_int opacity = 255,\n\t\ttTVPBBStretchType type = stNearest);\n\n\tvoid DoBoxBlur(tjs_int xblur = 1, tjs_int yblur = 1);\n\n\tvoid AdjustGamma(const tTVPGLGammaAdjustData & data);\n\tvoid DoGrayScale();\n\tvoid LRFlip();\n\tvoid UDFlip();\n\n\tbool GetImageModified() const { return ImageModified; }\n\tvoid SetImageModified(bool b) { ImageModified = b; }\n\n\n\t//------------------------------------------- interface to font object --\n\nprivate:\n\ttTVPFont Font;\n\tbool FontChanged;\n\tiTJSDispatch2 *FontObject;\n\n\tvoid ApplyFont();\n\npublic:\n\tvoid SetFontFace(const ttstr & face);\n\tttstr GetFontFace() const;\n\tvoid SetFontHeight(tjs_int height);\n\ttjs_int GetFontHeight() const;\n\tvoid SetFontAngle(tjs_int angle);\n\ttjs_int GetFontAngle() const;\n\tvoid SetFontBold(bool b);\n\tbool GetFontBold() const;\n\tvoid SetFontItalic(bool b);\n\tbool GetFontItalic() const;\n\tvoid SetFontStrikeout(bool b);\n\tbool GetFontStrikeout() const;\n\tvoid SetFontUnderline(bool b);\n\tbool GetFontUnderline() const;\n\tvoid SetFontFaceIsFileName(bool b);\n\tbool GetFontFaceIsFileName() const;\n\n\n\ttjs_int GetTextWidth(const ttstr & text);\n\ttjs_int GetTextHeight(const ttstr & text);\n\tdouble GetEscWidthX(const ttstr & text);\n\tdouble GetEscWidthY(const ttstr & text);\n\tdouble GetEscHeightX(const ttstr & text);\n\tdouble GetEscHeightY(const ttstr & text);\n\tvoid GetFontGlyphDrawRect( const ttstr & text, tTVPRect& area );\n// \tbool DoUserFontSelect(tjs_uint32 flags, const ttstr &caption,\n// \t\tconst ttstr &prompt, const ttstr &samplestring);\n\n\tvoid GetFontList(tjs_uint32 flags, std::vector<ttstr> & list);\n\n\tvoid MapPrerenderedFont(const ttstr & storage);\n\tvoid UnmapPrerenderedFont();\n\n\tconst tTVPFont& GetFont() const;\n\n\tiTJSDispatch2 * GetFontObjectNoAddRef();\n\n\n\t//------------------------------------------------ updating management --\nprotected:\n\ttjs_int UpdateOfsX, UpdateOfsY;\n\ttTVPRect UpdateRectForChild; // to be used in tTVPDrawable::GetDrawTargetBitmap\n\ttjs_int UpdateRectForChildOfsX;\n\ttjs_int UpdateRectForChildOfsY;\n\ttTVPDrawable * CurrentDrawTarget; // set by Draw\n\ttTVPBaseTexture *UpdateBitmapForChild; // to be used in tTVPDrawable::GetDrawTargetBitmap\n\ttTVPRect UpdateExcludeRect; // rectangle whose update is not be needed\n\n\ttTVPComplexRect CacheRecalcRegion; // region that must be reconstructed for cache\n\ttTVPComplexRect DrawnRegion; // region that is already marked as \"blitted\"\n\tbool DirectTransferToParent; // child image should be directly transfered into parent\n\n\tbool CallOnPaint; // call onPaint event when flaged\n\n\tvoid UpdateTransDestinationOnSelfUpdate(const tTVPComplexRect &region);\n\tvoid UpdateTransDestinationOnSelfUpdate(const tTVPRect &rect);\n\n\tvoid UpdateChildRegion(tTJSNI_BaseLayer *child, const tTVPComplexRect &region,\n\t\tbool tempupdate, bool targnodevisible, bool addtoprimary);\n\n\tvoid InternalUpdate(const tTVPRect &rect, bool tempupdate = false);\n\npublic:\n\tvoid Update(tTVPComplexRect &rects, bool tempupdate = false);\n\tvoid Update(const tTVPRect &rect, bool tempupdate = false);\n\tvoid Update(bool tempupdate = false);\n\n\tvoid UpdateAllChildren(bool tempupdate = false);\n\n\tvoid UpdateByScript(const tTVPRect &rect) { CallOnPaint = true; Update(rect); }\n\tvoid UpdateByScript() { CallOnPaint = true; Update(); }\n\n\tvoid SetCallOnPaint(bool b) { CallOnPaint = b; }\n\tbool GetCallOnPaint() const { return CallOnPaint; }\n\n    //void InternalDrawNoCache_GPU(tTVPDrawable *target, const tTVPRect &rect);\n    void InternalDrawNoCache_CPU(tTVPDrawable *target, const tTVPRect &rect);\n\tvirtual void Draw_GPU(tTVPDrawable *target, int x, int y, const tTVPRect &r, bool visiblecheck = true);\n\nprivate:\n\tvoid ParentUpdate();  // called when layer moves\n\n\n\tbool InCompletion; // update/completion pipe line is processing\n\tvoid BeforeCompletion(); // called before the drawing is processed\n\tvoid AfterCompletion(); // called after the drawing is processed\n\n\tvoid QueryUpdateExcludeRect(tTVPRect &rect, bool parentvisible);\n\t\t// query update exclude rect ( checks completely opaque area )\n\n    static void BltImage(iTVPBaseBitmap *dest, tTVPLayerType targettype, tjs_int destx,\n        tjs_int desty, iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\t\ttTVPLayerType drawtype, tjs_int opacity, bool hda = false);\n\n\tvoid DrawSelf(tTVPDrawable *target, tTVPRect &pr, \n\t\ttTVPRect &cr);\n\tvoid CopySelfForRect(iTVPBaseBitmap *dest, tjs_int destx, tjs_int desty,\n\t\tconst tTVPRect &srcrect);\n\tvoid CopySelf(iTVPBaseBitmap *dest, tjs_int destx, tjs_int desty,\n\t\tconst tTVPRect &r);\n\tvoid EffectImage(iTVPBaseBitmap *dest, const tTVPRect & destrect);\n\n\tvoid Draw(tTVPDrawable *target, const tTVPRect &r, bool visiblecheck = true);\n\n\t// these 3 below are methods from tTVPDrawable\n\ttTVPBaseTexture * GetDrawTargetBitmap(const tTVPRect &rect,\n\t\ttTVPRect &cliprect);\n\ttTVPLayerType GetTargetLayerType();\n\tvoid DrawCompleted(const tTVPRect&destrect, tTVPBaseTexture *bmp,\n\t\tconst tTVPRect &cliprect,\n\t\ttTVPLayerType type, tjs_int opacity) override;\n\n\tvoid InternalComplete2(tTVPComplexRect & updateregion, tTVPDrawable *drawable);\n\tvoid InternalComplete2_GPU(tTVPRect updateregion, tTVPDrawable *drawable);\n\tvoid InternalComplete(tTVPComplexRect & updateregion, tTVPDrawable *drawable);\n\tvoid CompleteForWindow(tTVPDrawable *drawable);\npublic:\nprivate:\n\ttTVPBaseTexture * Complete(const tTVPRect & rect);\n\ttTVPBaseTexture * Complete(); // complete entire area of the layer\n\n\n\t//---------------------------------------------- transition management --\nprivate:\n\tiTVPDivisibleTransHandler * DivisibleTransHandler;\n\tiTVPGiveUpdateTransHandler * GiveUpdateTransHandler;\n\n\ttTJSNI_BaseLayer * TransDest; // transition destination\n\tiTJSDispatch2 *TransDestObj;\n\ttTJSNI_BaseLayer * TransSrc; // transition source\n\tiTJSDispatch2 *TransSrcObj;\n\n\tbool InTransition; // is transition processing?\n\tbool TransWithChildren; // is transition with children?\n\tbool TransSelfUpdate; // is transition update performed by user code ?\n\n\ttjs_uint64 TransTick; // current tick count\n\tbool UseTransTickCallback; // whether to use tick source callback function\n\ttTJSVariantClosure TransTickCallback; // tick callback function\n\n\ttTVPTransType TransType; // current transition type\n\ttTVPTransUpdateType TransUpdateType; // current transition update type\n\n\ttTVPScanLineProviderForBaseBitmap * DestSLP; // destination scan line provider\n\ttTVPScanLineProviderForBaseBitmap * SrcSLP; // source scan line provider\n\n\tbool TransCompEventPrevented; // whether \"onTransitionCompleted\" event is prevented\n\npublic:\n\tvoid StartTransition(const ttstr &name, bool withchildren,\n\t\ttTJSNI_BaseLayer *transsource, tTJSVariantClosure options);\n\nprivate:\n\tvoid InternalStopTransition();\n\npublic:\n\tvoid StopTransition();\n\nprivate:\n\tvoid StopTransitionByHandler();\n\n\tvoid InvokeTransition(tjs_uint64 tick); // called frequanctly\n\n    void DoDivisibleTransition(iTVPBaseBitmap *dest, tjs_int dx, tjs_int dy,\n\t\tconst tTVPRect &srcrect);\n\n\tstruct tTransDrawable : public tTVPDrawable\n\t{\n\t\t// tTVPDrawable class for Transition pipe line rearrangement\n\t\ttTJSNI_BaseLayer * Owner;\n\t\ttTVPBaseTexture * Target;\n\t\ttTVPRect TargetRect;\n\t\ttTVPDrawable *OrgDrawable;\n\n\t\ttTVPBaseTexture *Src1Bmp; // tutDivisible\n\t\ttTVPBaseTexture *Src2Bmp; // tutDivisible\n\n\t\tvoid Init(tTJSNI_BaseLayer *owner, tTVPDrawable *org)\n\t\t{\n\t\t\tOwner = owner;\n\t\t\tOrgDrawable = org;\n\t\t\tTarget = NULL;\n\t\t}\n\n\t\ttTVPBaseTexture * GetDrawTargetBitmap(const tTVPRect &rect,\n\t\t\ttTVPRect &cliprect) override;\n\t\ttTVPLayerType GetTargetLayerType();\n\t\tvoid DrawCompleted(const tTVPRect&destrect, tTVPBaseTexture *bmp,\n\t\t\tconst tTVPRect &cliprect,\n\t\t\ttTVPLayerType type, tjs_int opacity) override;\n\t} TransDrawable;\n\tfriend struct tTransDrawable;\n\n\tstruct tTransIdleCallback : public tTVPContinuousEventCallbackIntf\n\t{\n\t\ttTJSNI_BaseLayer * Owner;\n\t\tvoid TJS_INTF_METHOD OnContinuousCallback(tjs_uint64 tick)\n\t\t\t{ Owner->InvokeTransition(tick); }\n\t\t// from tTVPIdleEventCallbackIntf\n\t} TransIdleCallback;\n\tfriend struct tTransIdleCallback;\n\n\ttjs_uint64 GetTransTick();\n\n};\n//---------------------------------------------------------------------------\n\n\n\n#include \"LayerImpl.h\"\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Layer : TJS Layer class\n//---------------------------------------------------------------------------\nclass tTJSNC_Layer : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Layer();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNI_Layer.\n\t*/\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Layer();\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Font : Font Native Object\n//---------------------------------------------------------------------------\nclass tTJSNI_Font : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\n\ttTVPFont Font;\n\ttTJSNI_BaseLayer * Layer;\n\t\n\ttjs_int GetTextWidthDirect(const ttstr & text);\n\npublic:\n\ttTJSNI_Font();\n\t~tTJSNI_Font();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\ttTJSNI_BaseLayer * GetLayer() const { return Layer; }\n\n\tvoid SetFontFace(const ttstr & face);\n\tttstr GetFontFace() const;\n\tvoid SetFontHeight(tjs_int height);\n\ttjs_int GetFontHeight() const;\n\tvoid SetFontAngle(tjs_int angle);\n\ttjs_int GetFontAngle() const;\n\tvoid SetFontBold(bool b);\n\tbool GetFontBold() const;\n\tvoid SetFontItalic(bool b);\n\tbool GetFontItalic() const;\n\tvoid SetFontStrikeout(bool b);\n\tbool GetFontStrikeout() const;\n\tvoid SetFontUnderline(bool b);\n\tbool GetFontUnderline() const;\n\tvoid SetFontFaceIsFileName(bool b);\n\tbool GetFontFaceIsFileName() const;\n\n\ttjs_int GetTextWidth(const ttstr & text);\n\ttjs_int GetTextHeight(const ttstr & text);\n\tdouble GetEscWidthX(const ttstr & text);\n\tdouble GetEscWidthY(const ttstr & text);\n\tdouble GetEscHeightX(const ttstr & text);\n\tdouble GetEscHeightY(const ttstr & text);\n\tvoid GetFontGlyphDrawRect( const ttstr & text, tTVPRect& area );\n\n\tvoid GetFontList(tjs_uint32 flags, std::vector<ttstr> & list);\n\t\n\tvoid MapPrerenderedFont(const ttstr & storage);\n\tvoid UnmapPrerenderedFont();\n\n\tconst tTVPFont& GetFont() const;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Font : TJS Font class\n//---------------------------------------------------------------------------\nclass tTJSNC_Font : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Font();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance() { return new tTJSNI_Font(); }\n};\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateFontObject(iTJSDispatch2 * layer);\nextern tTJSNativeClass * TVPCreateNativeClass_Font();\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/LayerManager.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include \"tjsArray.h\"\n#include \"LayerManager.h\"\n#include \"MsgIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"EventIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"TickCount.h\"\n#include \"DebugIntf.h\"\n#include \"LayerTreeOwner.h\"\n\n\n\n//---------------------------------------------------------------------------\n// tTVPLayerManager\n//---------------------------------------------------------------------------\ntTVPLayerManager::tTVPLayerManager(iTVPLayerTreeOwner *owner)\n{\n\tRefCount = 1;\n\tLayerTreeOwner = owner;\n\tDrawDeviceData = NULL;\n\tDrawBuffer = NULL;\n\tDesiredLayerType = ltOpaque;\n\n\tCaptureOwner = NULL;\n\tLastMouseMoveSent = NULL;\n\tPrimary = NULL;\n\tFocusedLayer = NULL;\n\tOverallOrderIndexValid = false;\n\tEnabledWorkRefCount = 0;\n\tFocusChangeLock = false;\n\tVisualStateChanged = true;\n\tLastMouseMoveX = -1;\n\tLastMouseMoveY = -1;\n\tInNotifyingHintOrCursorChange = false;\n}\n//---------------------------------------------------------------------------\ntTVPLayerManager::~tTVPLayerManager()\n{\n\tif(DrawBuffer) delete DrawBuffer;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::AddRef()\n{\n\tRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount --;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::RegisterSelfToWindow()\n{\n\tLayerTreeOwner->RegisterLayerManager(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::UnregisterSelfFromWindow()\n{\n\tLayerTreeOwner->UnregisterLayerManager(this);\n}\n\nvoid tTVPLayerManager::SetHoldAlpha(bool b)\n{\n\tHoldAlpha = b;\n\tif (!DrawBuffer) return;\n\tstatic_cast<tTVPDestTexture*>(DrawBuffer)->SetHoldAlpha(b);\n}\n\n//---------------------------------------------------------------------------\ntTVPBaseTexture * tTVPLayerManager::GetDrawTargetBitmap(const tTVPRect &rect,\n\ttTVPRect &cliprect)\n{\n\t// retrieve draw target bitmap\n\ttjs_int w = rect.get_width();\n\ttjs_int h = rect.get_height();\n\n\tif(!DrawBuffer) {\n\t\t// create draw buffer\n        if(Primary) {\n            const tTVPRect & rc = Primary->GetRect();\n            w = rc.get_width();\n            h = rc.get_height();\n\t\t}\n        DrawBuffer = new tTVPDestTexture(w, h);\n\t\tDrawBuffer->Fill(tTVPRect(0, 0, w, h), 0xFF000000);\n\t\tstatic_cast<tTVPDestTexture*>(DrawBuffer)->SetHoldAlpha(HoldAlpha);\n    } else {\n\t\ttjs_int bw = DrawBuffer->GetWidth();\n\t\ttjs_int bh = DrawBuffer->GetHeight();\n\t\tif(bw < w || bh  < h) {\n\t\t\t// insufficient size; resize the draw buffer\n\t\t\ttjs_uint neww = bw > w ? bw:w, newh = bh > h ? bh : h;\n\t\t\tneww += (neww & 1); // align to even\n\t\t\tDrawBuffer->SetSize(neww, newh, false);\n\t\t\tDrawBuffer->Fill(tTVPRect(0, 0, neww, newh), 0xFF000000);\n\t\t}\n\t}\n\n\tcliprect = rect;\n\treturn DrawBuffer;\n}\n//---------------------------------------------------------------------------\ntTVPLayerType tTVPLayerManager::GetTargetLayerType()\n{\n\treturn DesiredLayerType;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::DrawCompleted(const tTVPRect &destrect,\n\ttTVPBaseTexture *bmp, const tTVPRect &cliprect,\n\t\ttTVPLayerType type, tjs_int opacity)\n{\n#if 0\n\tif (!LayerTreeOwner) return;\n\tLayerTreeOwner->NotifyBitmapCompleted(this, destrect.left, destrect.top, bmp, cliprect, type, opacity);\n#else\n    tjs_int w, h;\n\tif(!/*LayerTreeOwner->*/GetPrimaryLayerSize(w, h)) return;\n    //Window->GetDrawDevice()->GetSrcSize(w, h);\n    if (!DrawBuffer) {\n        // create draw buffer\n\t\tDrawBuffer = new tTVPDestTexture(w, h);\n\t\tDrawBuffer->Fill(tTVPRect(0, 0, w, h), 0xFF000000);\n\t\tstatic_cast<tTVPDestTexture*>(DrawBuffer)->SetHoldAlpha(HoldAlpha);\n\t} else {\n        tjs_int bw = DrawBuffer->GetWidth();\n        tjs_int bh = DrawBuffer->GetHeight();\n        if (bw < w || bh  < h) {\n            // insufficient size; resize the draw buffer\n            tjs_uint neww = bw > w ? bw : w, newh = bh > h ? bh : h;\n            neww += (neww & 1); // align to even\n            DrawBuffer->SetSize(neww, newh, false);\n\t\t\tDrawBuffer->Fill(tTVPRect(0, 0, neww, newh), 0xFF000000);\n\t\t}\n    }\n\n\tDrawBuffer->Blt(destrect.left, destrect.top, bmp, cliprect, type, opacity, HoldAlpha);\n#endif\n}\n\ntTVPBaseTexture* tTVPLayerManager::GetOrCreateDrawBuffer()\n{\n\tif (!DrawBuffer) {\n\t\ttjs_int w, h;\n\t\tif (!GetPrimaryLayerSize(w, h)) return nullptr;\n\t\tDrawBuffer = new tTVPDestTexture(w, h);\n\t\tDrawBuffer->Fill(tTVPRect(0, 0, w, h), 0xFF000000);\n\t\tstatic_cast<tTVPDestTexture*>(DrawBuffer)->SetHoldAlpha(HoldAlpha);\n\t}\n\treturn DrawBuffer;\n}\n\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::AttachPrimary(tTJSNI_BaseLayer *pri)\n{\n\t// attach primary layer to the manager\n\tDetachPrimary();\n\n\tif(!Primary)\n\t{\n\t\tPrimary = pri;\n\t\tEnabledWorkRefCount = 0;\n\t\tOverallOrderIndexValid = false;\n\t\tUpdateRegion.Clear();\n\t\tpri->SetVisible(true);\n\t\tpri->SetOpacity(255);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::DetachPrimary()\n{\n\t// detach primary layer from the manager\n\tif(Primary)\n\t{\n\t\tSetFocusTo(NULL);\n\t\tReleaseCapture();\n\t\tReleaseTouchCaptureAll();\n\t\tForceMouseLeave();\n\t\tNotifyPart(Primary);\n\t\tPrimary = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPLayerManager::GetPrimaryLayerSize(tjs_int &w, tjs_int &h) const\n{\n\tif(IsPrimaryLayerAttached())\n\t{\n\t\tw = Primary->GetWidth();\n\t\th = Primary->GetHeight();\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyPart(tTJSNI_BaseLayer *lay)\n{\n\t// notifies layer parting from its parent\n\tInvalidateOverallIndex();\n\tBlurTree(lay);\n\tReleaseCaptureFromTree(lay);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::InvalidateOverallIndex()\n{\n\tOverallOrderIndexValid = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::RecreateOverallOrderIndex()\n{\n\t// recreate overall order index\n\tif(!OverallOrderIndexValid)\n\t{\n\t\ttjs_uint index = 0;\n\t\tAllNodes.clear();\n\t\tif(Primary) Primary->RecreateOverallOrderIndex(index, AllNodes);\n\n\t\tOverallOrderIndexValid = true;\n\t}\n}\n//---------------------------------------------------------------------------\nstd::vector<tTJSNI_BaseLayer*> & tTVPLayerManager::GetAllNodes()\n{\n\tif(!OverallOrderIndexValid) RecreateOverallOrderIndex();\n\treturn AllNodes;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::QueryUpdateExcludeRect()\n{\n\tif(!VisualStateChanged) return;\n\ttTVPRect r;\n\tr.clear();\n\tif(Primary) Primary->QueryUpdateExcludeRect(r, true);\n\tVisualStateChanged = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyMouseCursorChange(\n\ttTJSNI_BaseLayer *layer, tjs_int cursor)\n{\n\tif(InNotifyingHintOrCursorChange) return;\n\n\tInNotifyingHintOrCursorChange = true;\n\ttry\n\t{\n\n\t\ttTJSNI_BaseLayer *l;\n\n\t\tif(CaptureOwner)\n\t\t\tl = CaptureOwner;\n\t\telse\n\t\t\tl = GetMostFrontChildAt(LastMouseMoveX, LastMouseMoveY);\n\n\t\tif(l == layer) SetMouseCursor(cursor);\n\t}\n\tcatch(...)\n\t{\n\t\tInNotifyingHintOrCursorChange = false;\n\t\tthrow;\n\t}\n\n\tInNotifyingHintOrCursorChange = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetMouseCursor(tjs_int cursor)\n{\n\tif(!LayerTreeOwner) return;\n\n\tLayerTreeOwner->SetMouseCursor(this, cursor);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::GetCursorPos(tjs_int &x, tjs_int &y)\n{\n\tif(!LayerTreeOwner) return;\n\tLayerTreeOwner->GetCursorPos(this, x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetCursorPos(tjs_int x, tjs_int y)\n{\n\tif(!LayerTreeOwner) return;\n\tLayerTreeOwner->SetCursorPos(this, x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyHintChange(tTJSNI_BaseLayer *layer, const ttstr & hint)\n{\n\tif(InNotifyingHintOrCursorChange) return;\n\n\tInNotifyingHintOrCursorChange = true;\n\n\ttry\n\t{\n\t\ttTJSNI_BaseLayer *l;\n\n\t\tif(CaptureOwner)\n\t\t\tl = CaptureOwner;\n\t\telse\n\t\t\tl = GetMostFrontChildAt(LastMouseMoveX, LastMouseMoveY);\n\n\t\tif(l == layer) SetHint(l->GetOwnerNoAddRef(),hint);\n\t}\n\tcatch(...)\n\t{\n\t\tInNotifyingHintOrCursorChange = false;\n\t\tthrow;\n\t}\n\n\tInNotifyingHintOrCursorChange = false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetHint(iTJSDispatch2* sender, const ttstr &hint)\n{\n\tif(!LayerTreeOwner) return;\n\tLayerTreeOwner->SetHint(this, sender, hint);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyLayerResize()\n{\n\t// notifies layer resizing to the LayerTreeOwner\n\tif(!LayerTreeOwner) return;\n\n\tLayerTreeOwner->NotifyLayerResize(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyWindowInvalidation()\n{\n\t// notifies layer surface is invalidated and should be transfered to LayerTreeOwner.\n\tif(!LayerTreeOwner) return;\n\n\tLayerTreeOwner->NotifyLayerImageChange(this);\n\t// TODO atlernative of LayerTreeOwner->RequestUpdate();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetLayerTreeOwner(class iTVPLayerTreeOwner* owner)\n{\n\t// sets LayerTreeOwner\n\tLayerTreeOwner = owner;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyResizeFromWindow(tjs_uint w, tjs_uint h)\n{\n\t// is called by the owner window, notifies windows's client area size\n\t// has been changed.\n\t// does not be called if owner window's \"autoResize\" property is false.\n\n\t// currently this function is not used.\n\n\tif(Primary) Primary->InternalSetSize(w, h);\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * tTVPLayerManager::GetMostFrontChildAt(tjs_int x, tjs_int y,\n\ttTJSNI_BaseLayer *except, bool get_disabled)\n{\n\t// return most front layer at given point.\n\t// this does checking of layer's visibility.\n\t// x and y are given in primary layer's coordinates.\n\tif(!Primary) return NULL;\n\n\ttTJSNI_BaseLayer *lay = NULL;\n\tPrimary->GetMostFrontChildAt(x, y, &lay, except, get_disabled);\n\treturn lay;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryClick(tjs_int x, tjs_int y)\n{\n\ttTJSNI_BaseLayer * l = GetMostFrontChildAt(x, y);\n\tif(l && CaptureOwner == l)\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tl->FireClick(x, y);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryDoubleClick(tjs_int x, tjs_int y)\n{\n\ttTJSNI_BaseLayer * l = GetMostFrontChildAt(x, y);\n\tif(l /*&& CaptureOwner == l*/)\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tl->FireDoubleClick(x, y);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\tPrimaryMouseMove(x, y, flags);\n\ttTJSNI_BaseLayer * l = CaptureOwner ? CaptureOwner : GetMostFrontChildAt(x, y);\n\tif(l)\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tReleaseCaptureCalled = false;\n\t\tl->FireMouseDown(x, y, mb, flags);\n\t\tbool no_capture = ReleaseCaptureCalled;\n\n\t\tif(CaptureOwner != l)\n\t\t{\n\t\t\tReleaseCapture();\n\n\t\t\tif(!no_capture)\n\t\t\t{\n\t\t\t\tCaptureOwner = l;\n\t\t\t\tif(CaptureOwner->Owner) CaptureOwner->Owner->AddRef(); // addref TJS object\n\t\t\t}\n\t\t}\n\t\t\n\t\tSetHint(NULL,ttstr());\n\t}\n\telse\n\t{\n\t\tReleaseCapture();\n\t}\n\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\ttTJSNI_BaseLayer *l;\n\n\tif(CaptureOwner)\n\t\tl = CaptureOwner;\n\telse\n\t\tl = GetMostFrontChildAt(x, y);\n\n\tif(l)\n\t{\n\t\tint orig_x = x, orig_y = y;\n\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tl->FireMouseUp(x, y, mb, flags);\n\n\t\tif(!TVPIsAnyMouseButtonPressedInShiftStateFlags(flags))\n\t\t{\n\t\t\tReleaseCapture();\n\t\t\tPrimaryMouseMove(orig_x, orig_y, flags); // force recheck current under-cursor layer\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags)\n{\n\tbool poschanged = (LastMouseMoveX != x || LastMouseMoveY != y);\n\tLastMouseMoveX = x;\n\tLastMouseMoveY = y;\n\n\ttTJSNI_BaseLayer *l;\n\n\tif(CaptureOwner)\n\t\tl = CaptureOwner;\n\telse\n\t\tl = GetMostFrontChildAt(x, y);\n\n\t// enter/leave event\n\tif(LastMouseMoveSent != l)\n\t{\n\t\tif(LastMouseMoveSent) LastMouseMoveSent->FireMouseLeave();\n\n\t\t// recheck l because the layer may become invalid during\n\t\t// FireMouseLeave call.\n\t\tif(CaptureOwner)\n\t\t\tl = CaptureOwner;\n\t\telse\n\t\t\tl = GetMostFrontChildAt(x, y);\n\n\t\tif(l)\n\t\t{\n\t\t\tInNotifyingHintOrCursorChange = true;\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttTJSNI_BaseLayer *ll;\n\n\t\t\t\tl->FireMouseEnter();\n\n\t\t\t\t// recheck l because the layer may become invalid during\n\t\t\t\t// FireMouseEnter call.\n\t\t\t\tif(CaptureOwner)\n\t\t\t\t\tll = CaptureOwner;\n\t\t\t\telse\n\t\t\t\t\tll = GetMostFrontChildAt(x, y);\n\n\t\t\t\tif(l != ll)\n\t\t\t\t{\n\t\t\t\t\tl->FireMouseLeave();\n\t\t\t\t\tl = ll;\n\t\t\t\t\tif(l) l->FireMouseEnter();\n\t\t\t\t}\n\n\t\t\t\t// note: rechecking is done only once to avoid infinite loop\n\n\t\t\t\tif(l) l->SetCurrentCursorToWindow();\n\t\t\t\tif(l) l->SetCurrentHintToWindow();\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tInNotifyingHintOrCursorChange = false;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tInNotifyingHintOrCursorChange = false;\n\t\t}\n\n\t\tif(!l)\n\t\t{\n\t\t\tSetMouseCursor(0);\n\t\t\tSetHint(NULL,ttstr());\n\t\t}\n\t}\n\n\tif(LastMouseMoveSent != l)\n\t{\n\t\tif(LastMouseMoveSent)\n\t\t{\n\t\t\ttTJSNI_BaseLayer *lay = LastMouseMoveSent;\n\t\t\tLastMouseMoveSent = NULL;\n\t\t\tif(lay->Owner) lay->Owner->Release();\n\t\t}\n\n\t\tLastMouseMoveSent = l;\n\n\n\t\tif(LastMouseMoveSent)\n\t\t{\n\t\t\tif(LastMouseMoveSent->Owner) LastMouseMoveSent->Owner->AddRef();\n\t\t}\n\t}\n\n\tif(l)\n\t{\n\t\tif(poschanged)\n\t\t{\n\t\t\tl->FromPrimaryCoordinates(x, y);\n\t\t\tl->FireMouseMove(x, y, flags);\n\t\t}\n\t}\n\telse\n\t{\n\t\t// no layer to send the event\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\ttjs_int ix = (tjs_int)x, iy = (tjs_int)y;\n\tReleaseTouchCapture(id);\n\ttTJSNI_BaseLayer * l = GetMostFrontChildAt(ix, iy);\n\tif( l )\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tReleaseTouchCaptureIDMark = (tjs_int64)id;\n\t\tl->FireTouchDown(x, y, cx, cy, id);\n\t\tif( ReleaseTouchCaptureIDMark == (tjs_int64)id ) {\n\t\t\tSetTouchCapture( id, l );\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\ttjs_int ix = (tjs_int)x, iy = (tjs_int)y;\n\ttTJSNI_BaseLayer * l = GetTouchCapture(id) ? GetTouchCapture(id) : GetMostFrontChildAt(ix, iy);\n\tif( l )\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tl->FireTouchUp(x, y, cx, cy, id);\n\t\tReleaseTouchCapture(id);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\ttjs_int ix = (tjs_int)x, iy = (tjs_int)y;\n\ttTJSNI_BaseLayer * l = GetTouchCapture(id) ? GetTouchCapture(id) : GetMostFrontChildAt(ix, iy);\n\tif( l )\n\t{\n\t\tl->FromPrimaryCoordinates(x, y);\n\t\tl->FireTouchMove(x, y, cx, cy, id);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireTouchScaling(startdist,curdist,cx,cy,flag);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireTouchRotate(startangle,curangle,dist,cx,cy,flag);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryMultiTouch()\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireMultiTouch();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ForceMouseLeave()\n{\n\tif(LastMouseMoveSent)\n\t{\n\t\ttTJSNI_BaseLayer *lay = LastMouseMoveSent;\n\t\tLastMouseMoveSent = NULL;\n\t\tlay->FireMouseLeave();\n\t\tif(lay->Owner) lay->Owner->Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ForceMouseRecheck()\n{\n\tPrimaryMouseMove(LastMouseMoveX, LastMouseMoveY, 0);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::MouseOutOfWindow()\n{\n\t// notifys that the mouse cursor goes outside of the window.\n\tif(!CaptureOwner)\n\t\tPrimaryMouseMove(-1, -1, 0); // force mouse cursor out of the all\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::LeaveMouseFromTree(tTJSNI_BaseLayer *root)\n{\n\t// force to leave mouse\n\tif(LastMouseMoveSent)\n\t{\n\t\tif(LastMouseMoveSent->IsAncestorOrSelf(root))\n\t\t{\n\t\t\ttTJSNI_BaseLayer *lay = LastMouseMoveSent;\n\t\t\tLastMouseMoveSent = NULL;\n\t\t\tlay->FireMouseLeave();\n\t\t\tif(lay->Owner) lay->Owner->Release();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::ReleaseCapture()\n{\n\t// release capture state\n\tReleaseCaptureCalled = true;\n\tif(CaptureOwner)\n\t{\n\t\ttTJSNI_BaseLayer *lay = CaptureOwner;\n\t\tCaptureOwner = NULL;\n\t\tif(lay->Owner) lay->Owner->Release();\n\t\t\t// release TJS object\n\n\t\tLayerTreeOwner->ReleaseMouseCapture(this);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ReleaseCaptureFromTree(tTJSNI_BaseLayer * layer)\n{\n\t// Release capture state, if the capture object is descendant of\n\t// 'layer' or 'layer' itself.\n\tif(CaptureOwner)\n\t{\n\t\tif(CaptureOwner->IsAncestorOrSelf(layer))\n\t\t{\n\t\t\tReleaseCapture();\n\t\t}\n\t}\n\tstd::vector<tTVPTouchCaptureLayer>::iterator itr = TouchCapture.begin();\n\twhile( itr != TouchCapture.end() )\n\t{\n\t\ttTJSNI_BaseLayer* l = itr->Owner;\n\t\tif( l && l->IsAncestorOrSelf(layer))\n\t\t{\n\t\t\tif( l->Owner ) l->Owner->Release();\n\t\t\tif( ReleaseTouchCaptureIDMark == (tjs_int64)(itr->TouchID) ) ReleaseTouchCaptureIDMark = -1;\n\t\t\titr = TouchCapture.erase(itr);\n\t\t}\n\t\telse\n\t\t{\n\t\t\titr++;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ReleaseTouchCapture( tjs_uint32 id )\n{\n\tFindTouchID pred( id );\n\tstd::vector<tTVPTouchCaptureLayer>::iterator itr = std::find_if( TouchCapture.begin(), TouchCapture.end(), pred );\n\tif( itr != TouchCapture.end() )\n\t{\n\t\ttTJSNI_BaseLayer* old = itr->Owner;\n\t\tif( old && old->Owner ) old->Owner->Release();\n\t\tTouchCapture.erase(itr);\n\t}\n\tif( ReleaseTouchCaptureIDMark == (tjs_int64)id ) ReleaseTouchCaptureIDMark = -1;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ReleaseTouchCaptureAll()\n{\n\tfor( std::vector<tTVPTouchCaptureLayer>::iterator itr = TouchCapture.begin(); itr != TouchCapture.end(); itr++ )\n\t{\n\t\ttTJSNI_BaseLayer* l = itr->Owner;\n\t\tif( l->Owner ) l->Owner->Release();\n\t}\n\tTouchCapture.clear();\n\tReleaseTouchCaptureIDMark = -1;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetTouchCapture( tjs_uint32 id, tTJSNI_BaseLayer* layer )\n{\n\tFindTouchID pred( id );\n\tstd::vector<tTVPTouchCaptureLayer>::iterator itr = std::find_if( TouchCapture.begin(), TouchCapture.end(), pred );\n\tif( itr != TouchCapture.end() )\n\t{\n\t\t// ɓID̂̂ꍇ́AꏊŒu\n\t\ttTJSNI_BaseLayer* old = itr->Owner;\n\t\tif( old && old->Owner ) old->Owner->Release();\n\t\titr->Owner = layer;\n\t\tif( layer->Owner ) layer->Owner->AddRef();\n\t}\n\telse\n\t{\n\t\t// Ȃꍇ́AɒǉB\n\t\tTouchCapture.push_back( tTVPTouchCaptureLayer( id, layer ) );\n\t\tif( layer->Owner ) layer->Owner->AddRef();\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTVPLayerManager::BlurTree(tTJSNI_BaseLayer *root)\n{\n\t// (primary only) remove focus from \"root\"\n\tRemoveTreeModalState(root);\n\tLeaveMouseFromTree(root);\n\n\tif(!FocusedLayer) return false;\n\n\tif(!FocusedLayer->IsAncestorOrSelf(root)) return false;\n\t\t// root is not ancestor of current focused layer\n\n\ttTJSNI_BaseLayer *next = root->GetNextFocusable();\n\n\tif(next != FocusedLayer)\n\t\tSetFocusTo(next, true); // focus to root's next focusable layer\n\telse\n\t\tSetFocusTo(NULL, true);\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::CheckTreeFocusableState(tTJSNI_BaseLayer *root)\n{\n\t// (primary only) check newly added tree's focusable state\n/*\t// uncomment here to auto-focus\n\tif(FocusedLayer) return;\n\n\ttTJSNI_BaseLayer *lay = root->SearchFirstFocusable(true);\n\tif(lay) SetFocusTo(lay, true);\n*/\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTVPLayerManager::FocusPrev()\n{\n\t// focus to previous layer\n\ttTJSNI_BaseLayer *l;\n\tif(!FocusedLayer)\n\t\tl = SearchFirstFocusable(false);// search first focusable layer\n\telse\n\t\tl = FocusedLayer->GetPrevFocusable();\n\n\tif(l) SetFocusTo(l, false);\n\treturn l;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTVPLayerManager::FocusNext()\n{\n\t// focus to next layer\n\ttTJSNI_BaseLayer *l;\n\tif(!FocusedLayer)\n\t\tl = SearchFirstFocusable(false);// search first focusable layer\n\telse\n\t\tl = FocusedLayer->GetNextFocusable();\n\n\tif(l) SetFocusTo(l, true);\n\treturn l;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTVPLayerManager::SearchFirstFocusable(bool ignore_chain_focusable)\n{\n\t// (primary only) search first focusable layer\n\tif(!Primary) return NULL;\n\ttTJSNI_BaseLayer *lay = Primary->SearchFirstFocusable(ignore_chain_focusable);\n\n\treturn lay;\n}\n//---------------------------------------------------------------------------\nbool tTVPLayerManager::SetFocusTo(tTJSNI_BaseLayer *layer, bool direction)\n{\n\t// set focus to layer\n\n\t// direction = true : forward focus\n\t// direction = false: backward focus\n\n\tif(layer && !layer->GetNodeFocusable()) return false;\n\n\tif(layer && !layer->Shutdown)\n\t\tlayer = layer->FireBeforeFocus(FocusedLayer, direction);\n\n\tif(layer && !layer->GetNodeFocusable()) return false;\n\n\tif(FocusedLayer == layer) return false;\n\n\n\tif(FocusChangeLock)\n\t\tTVPThrowExceptionMessage(TVPCannotChangeFocusInProcessingFocus);\n\tFocusChangeLock = true;\n\n\ttTJSNI_BaseLayer *org = FocusedLayer;\n\tFocusedLayer = layer;\n\n\ttry\n\t{\n\t\tif(org && !org->Shutdown)\n\t\t\torg->FireBlur(layer);\n\n\t\tif(FocusedLayer && !FocusedLayer->Shutdown)\n\t\t\tFocusedLayer->FireFocus(org, direction);\n\t}\n\tcatch(...)\n\t{\n\t\tif(FocusedLayer) if(FocusedLayer->Owner)\n\t\t\tFocusedLayer->Owner->AddRef();\n\t\tif(org) if(org->Owner)\n\t\t\torg->Owner->Release();\n\t\tFocusChangeLock = false;\n\t\tthrow;\n\t}\n\n\tif(FocusedLayer) if(FocusedLayer->Owner)\n\t\tFocusedLayer->Owner->AddRef();\n\tif(org) if(org->Owner)\n\t\torg->Owner->Release();\n\n\tif(FocusedLayer) SetImeModeOf(FocusedLayer); else ResetImeMode();\n\tif(FocusedLayer) SetAttentionPointOf(FocusedLayer); else DisableAttentionPoint();\n\n\tFocusChangeLock = false;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ReleaseAllModalLayer()\n{\n\t// (primary only) release all modal layer on invalidation\n\tstd::vector<tTJSNI_BaseLayer*> copy(ModalLayerVector);\n\tModalLayerVector.clear();\n\n\tstd::vector<tTJSNI_BaseLayer*>::iterator i;\n\tfor(i = copy.begin(); i < copy.end(); i++)\n\t{\n\t\tif((*i)->Owner) (*i)->Owner->Release();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetModeTo(tTJSNI_BaseLayer *layer)\n{\n\t// (primary only) set mode to layer\n\tif(!layer) return;\n\n\tSaveEnabledWork();\n\n\ttry\n\t{\n\t\ttTJSNI_BaseLayer *current = GetCurrentModalLayer();\n\t\tif(current && layer->IsAncestorOrSelf(current))\n\t\t\tTVPThrowExceptionMessage(TVPCannotSetModeToDisabledOrModal);\n\t\t\t\t// cannot set mode to parent layer\n\t\tif(!layer->Visible) layer->Visible = true;\n\t\tif(!layer->GetParentVisible() || !layer->Enabled)\n\t\t\tTVPThrowExceptionMessage(TVPCannotSetModeToDisabledOrModal);\n\t\t\t\t// cannot set mode to parent layer\n\t\tif(layer == current)\n\t\t\tTVPThrowExceptionMessage(TVPCannotSetModeToDisabledOrModal);\n\t\t\t\t// cannot set mode to already modal layer\n\n\t\tSetFocusTo(layer->SearchFirstFocusable(), true);\n\n\t\tif(layer->Owner) layer->Owner->AddRef();\n\t\tModalLayerVector.push_back(layer);\n\n\t}\n\tcatch(...)\n\t{\n\t\tNotifyNodeEnabledState();\n\t\tthrow;\n\t}\n\n\tNotifyNodeEnabledState();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::RemoveModeFrom(tTJSNI_BaseLayer *layer)\n{\n\t// remove modal state from given layer\n\tbool do_notify = false;\n\n\ttry\n\t{\n\t\tstd::vector<tTJSNI_BaseLayer*>::iterator i;\n\t\tfor(i = ModalLayerVector.begin(); i < ModalLayerVector.end();)\n\t\t{\n\t\t\tif(layer == *i)\n\t\t\t{\n\t\t\t\tif(!do_notify) { do_notify = true; SaveEnabledWork(); }\n\t\t\t\tif(layer->Owner) layer->Owner->Release();\n\t\t\t\tSetFocusTo(layer->GetNextFocusable(), true);\n\t\t\t\ti = ModalLayerVector.erase(i);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(do_notify) NotifyNodeEnabledState();\n\t\tthrow;\n\t}\n\n\tif(do_notify) NotifyNodeEnabledState();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::RemoveTreeModalState(tTJSNI_BaseLayer *root)\n{\n\t// remove modal state from given tree\n\tbool do_notify = false;\n\n\ttry\n\t{\n\t\tstd::vector<tTJSNI_BaseLayer*>::iterator i;\n\t\tfor(i = ModalLayerVector.begin(); i < ModalLayerVector.end();)\n\t\t{\n\t\t\tif((*i)->IsAncestorOrSelf(root))\n\t\t\t{\n\t\t\t\tif(!do_notify) { do_notify = true; SaveEnabledWork(); }\n\t\t\t\tif((*i)->Owner) (*i)->Owner->Release();\n\t\t\t\tSetFocusTo(root->GetNextFocusable(), true);\n\t\t\t\ti = ModalLayerVector.erase(i);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(do_notify) NotifyNodeEnabledState();\n\t\tthrow;\n\t}\n\n\tif(do_notify) NotifyNodeEnabledState();\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer *tTVPLayerManager::GetCurrentModalLayer() const\n{\n\t// (primary only) get current modal layer\n\ttjs_uint size = (tjs_uint)ModalLayerVector.size();\n\tif(size == 0) return NULL;\n\treturn *(ModalLayerVector.begin() + size - 1);\n}\n//---------------------------------------------------------------------------\nbool tTVPLayerManager::SearchAttentionPoint(tTJSNI_BaseLayer *target,\n\ttjs_int &x, tjs_int &y)\n{\n\t// search specified layer 's attention point\n\twhile(target)\n\t{\n\t\tif(target->UseAttention)\n\t\t{\n\t\t\tx = target->AttentionLeft, y = target->AttentionTop;\n\t\t\ttarget->ToPrimaryCoordinates(x, y);\n\t\t\treturn true;\n\t\t}\n\t\ttarget = target->Parent;\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetAttentionPointOf(tTJSNI_BaseLayer *layer)\n{\n\tif(!LayerTreeOwner) return;\n\ttjs_int x, y;\n\tif(SearchAttentionPoint(layer, x, y))\n\t\tLayerTreeOwner->SetAttentionPoint(this, layer, x, y);\n\telse\n\t\tLayerTreeOwner->DisableAttentionPoint(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::DisableAttentionPoint()\n{\n\tif(LayerTreeOwner) LayerTreeOwner->DisableAttentionPoint(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyAttentionStateChanged(tTJSNI_BaseLayer *from)\n{\n\tif(FocusedLayer == from)\n\t{\n\t\tSetAttentionPointOf(from);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SetImeModeOf(tTJSNI_BaseLayer *layer)\n{\n\tif(!LayerTreeOwner) return;\n\tLayerTreeOwner->SetImeMode(this, layer->ImeMode);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::ResetImeMode()\n{\n\tif(!LayerTreeOwner) return;\n\tLayerTreeOwner->ResetImeMode(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyImeModeChanged(tTJSNI_BaseLayer *from)\n{\n\tif(FocusedLayer == from)\n\t{\n\t\tSetImeModeOf(from);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::SaveEnabledWork()\n{\n\t// save current node enabled state to EnabledWork\n\t// this does recursive call\n\tif(EnabledWorkRefCount == 0) if(Primary) Primary->SaveEnabledWork();\n\n\tEnabledWorkRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyNodeEnabledState()\n{\n\t// notify node enabled state change to self and its children\n\t// this refers EnabledWork which is created by SaveEnabledWork\n\tEnabledWorkRefCount --;\n\n\tif(EnabledWorkRefCount == 0) if(Primary) Primary->NotifyNodeEnabledState();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryKeyDown(tjs_uint key, tjs_uint32 shift)\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireKeyDown(key, shift);\n\telse\n\t\tif(Primary) Primary->DefaultKeyDown(key, shift);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryKeyUp(tjs_uint key, tjs_uint32 shift)\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireKeyUp(key, shift);\n\telse\n\t\tif(Primary) Primary->DefaultKeyUp(key, shift);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryKeyPress(tjs_char key)\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireKeyPress(key);\n\telse\n\t\tif(Primary) Primary->DefaultKeyPress(key);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::PrimaryMouseWheel(tjs_uint32 shift, tjs_int delta,\n\ttjs_int x, tjs_int y)\n{\n\tif(FocusedLayer)\n\t\tFocusedLayer->FireMouseWheel(shift, delta, x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::AddUpdateRegion(const tTVPComplexRect &rects)\n{\n\tUpdateRegion.Or(rects);\n\tif(UpdateRegion.GetCount() > TVP_UPDATE_UNITE_LIMIT)\n\t\tUpdateRegion.Unite();\n\tNotifyWindowInvalidation();\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::AddUpdateRegion(const tTVPRect &rect)\n{\n\t// the window is invalidated;\n\tUpdateRegion.Or(rect);\n\tNotifyWindowInvalidation();\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::UpdateToDrawDevice()\n{\n\t// drawdevice -> layer\n\tif(!Primary) return;\n\tPrimary->CompleteForWindow(this);\n}\n//---------------------------------------------------------------------------\nvoid tTVPLayerManager::NotifyUpdateRegionFixed()\n{\n\t// called by primary layer, notifying final update region is fixed\n//\tWindow->NotifyUpdateRegionFixed(UpdateRegion);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::RequestInvalidation(const tTVPRect &r)\n{\n\t// called by the owner window to notify window surface is invalidated by\n\t// the system or user.\n\tif(!Primary) return;\n\n\ttTVPRect ur;\n\ttTVPRect cr(0, 0, Primary->Rect.get_width(), Primary->Rect.get_height());\n\n\tif(TVPIntersectRect(&ur, r, cr))\n\t{\n\t\tAddUpdateRegion(ur);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::RecheckInputState()\n{\n\t// To re-check current layer under current mouse position\n\t// and update hint, cursor type and process layer enter/leave.\n\t// This can be reasonably slow, about 1 sec interval.\n\tForceMouseRecheck();\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPLayerManager::DumpLayerStructure()\n{\n\tif(Primary) Primary->DumpStructure();\n}\n//---------------------------------------------------------------------------\n\nbool tTVPDestTexture::CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref, tTVPRect refrect, tjs_int plane /*= (TVP_BB_COPY_MAIN | TVP_BB_COPY_MASK)*/)\n{\n\tif (HoldAlpha) {\n\t\treturn tTVPBaseTexture::CopyRect(x, y, ref, refrect, TVP_BB_COPY_MAIN);\n\t} else {\n\t\treturn tTVPBaseTexture::CopyRect(x, y, ref, refrect, plane);\n\t}\n}\n"
  },
  {
    "path": "src/core/visual/LayerManager.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n#ifndef LayerManagerH\n#define LayerManagerH\n\n\n#include \"LayerIntf.h\"\n#include \"drawable.h\"\n#include <algorithm>\n#include <vector>\n\n/*[*/\nclass tTJSNI_BaseLayer;\n//---------------------------------------------------------------------------\n// abstract class of Layer Manager \n//---------------------------------------------------------------------------\nclass iTVPLayerManager\n{\npublic:\n//-- object lifetime management\n\t//! @brief\tQƃJE^CNg\n\tvirtual void TJS_INTF_METHOD AddRef() = 0;\n\n\t//! @brief\tQƃJE^fNg\n\tvirtual void TJS_INTF_METHOD Release() = 0;\n\n//-- draw device specific information\n\t//! @brief\t`foCXŗL̏ݒ肷\n\t//! @param\tdata\t`foCXŗL̏\n\t//! @note\t`foCXŗL̏C}l[Wɐݒ肷B\n\t//!\t\t\tC}l[Wł͂̏̒gɂĂ͊֒mȂB\n\t//!\t\t\t`foCXŖڈɎgȀƌтĊǗB\n\tvirtual void TJS_INTF_METHOD SetDrawDeviceData(void * data) = 0;\n\n\t//! @brief\t`foCXŗL̏擾\n\t//! @return\t`foCXŗL̏\n\tvirtual void * TJS_INTF_METHOD GetDrawDeviceData() const = 0;\n\n//-- layer metrics\n\t//! @brief\tvC}C̃TCY擾\n\t//! @param\tw\tC̉(sNZP)\n\t//! @param\th\tC̏c(sNZP)\n\t//! @return\t擾ɐΐ^As΋U\n\tvirtual bool TJS_INTF_METHOD GetPrimaryLayerSize(tjs_int &w, tjs_int &h) const = 0;\n\n//-- layer structure information\n\t//! @brief\tvC}C̎擾\n\t//! @return\tvC}C\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetPrimaryLayer() const = 0;\n\n\t//! @brief\ttH[JX̂郌C̎擾\n\t//! @return\ttH[JX̂郌C\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetFocusedLayer() const = 0;\n\n\t//! @brief\ttH[JX̂郌C̐ݒ\n\t//! @param\tlayer\ttH[JX̂郌C\n\tvirtual void TJS_INTF_METHOD SetFocusedLayer(tTJSNI_BaseLayer * layer) = 0;\n\n//-- HID releted\n\t//! @brief\t\tNbNꂽ\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\tvirtual void TJS_INTF_METHOD NotifyClick(tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t_uNbNꂽ\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\tvirtual void TJS_INTF_METHOD NotifyDoubleClick(tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t}EX{^ꂽ\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\t//! @param\t\tmb\t\tǂ̃}EX{^\n\t//! @param\t\tflags\ttO(TVP_SS_*萔̑gݍ킹)\n\tvirtual void TJS_INTF_METHOD NotifyMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t}EX{^ꂽ\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\t//! @param\t\tmb\t\tǂ̃}EX{^\n\t//! @param\t\tflags\ttO(TVP_SS_*萔̑gݍ킹)\n\tvirtual void TJS_INTF_METHOD NotifyMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t}EXړ\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\t//! @param\t\tflags\ttO(TVP_SS_*萔̑gݍ킹)\n\tvirtual void TJS_INTF_METHOD NotifyMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t}EXLv`\n\t//! @note\t\t}EXLv`ׂꍇɃEBhEĂ΂B\n\tvirtual void TJS_INTF_METHOD ReleaseCapture() = 0;\n\n\t//! @brief\t\t}EXvC}COɈړ\n\tvirtual void TJS_INTF_METHOD NotifyMouseOutOfWindow() = 0;\n\n\t//! @brief\t\tL[ꂽ\n\t//! @param\t\tkey\t\tzL[R[h\n\t//! @param\t\tshift\tVtgL[̏\n\tvirtual void TJS_INTF_METHOD NotifyKeyDown(tjs_uint key, tjs_uint32 shift) = 0;\n\n\t//! @brief\t\tL[ꂽ\n\t//! @param\t\tkey\t\tzL[R[h\n\t//! @param\t\tshift\tVtgL[̏\n\tvirtual void TJS_INTF_METHOD NotifyKeyUp(tjs_uint key, tjs_uint32 shift) = 0;\n\n\t//! @brief\t\tL[ɂ\n\t//! @param\t\tkey\t\tR[h\n\tvirtual void TJS_INTF_METHOD NotifyKeyPress(tjs_char key) = 0;\n\n\t//! @brief\t\t}EXzC[]\n\t//! @param\t\tshift\tVtgL[̏\n\t//! @param\t\tdelta\t]p\n\t//! @param\t\tx\t\tvC}CWɂ x ʒu\n\t//! @param\t\ty\t\tvC}CWɂ y ʒu\n\tvirtual void TJS_INTF_METHOD NotifyMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\tʂ^b`ꂽ\n\t//! @param\t\tx\t\t``ɂ x ʒu(``̍オ_)\n\t//! @param\t\ty\t\t``ɂ y ʒu(``̍オ_)\n\t//! @param\t\tcx\t\tGĂ镝\n\t//! @param\t\tcy\t\tGĂ鍂\n\t//! @param\t\tid\t\t^b`ʗpID\n\tvirtual void TJS_INTF_METHOD NotifyTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\t^b`ꂽ\n\t//! @param\t\tx\t\t``ɂ x ʒu(``̍オ_)\n\t//! @param\t\ty\t\t``ɂ y ʒu(``̍オ_)\n\t//! @param\t\tcx\t\tGĂ镝\n\t//! @param\t\tcy\t\tGĂ鍂\n\t//! @param\t\tid\t\t^b`ʗpID\n\tvirtual void TJS_INTF_METHOD NotifyTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\t^b`ړ\n\t//! @param\t\tx\t\t``ɂ x ʒu(``̍オ_)\n\t//! @param\t\ty\t\t``ɂ y ʒu(``̍オ_)\n\t//! @param\t\tcx\t\tGĂ镝\n\t//! @param\t\tcy\t\tGĂ鍂\n\t//! @param\t\tid\t\t^b`ʗpID\n\tvirtual void TJS_INTF_METHOD NotifyTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\tg^b`삪sꂽ\n\t//! @param\t\tstartdist\tJn2_Ԃ̕\n\t//! @param\t\tcurdist\t݂2_Ԃ̕\n\t//! @param\t\tcx\t\tGĂ镝\n\t//! @param\t\tcy\t\tGĂ鍂\n\t//! @param\t\tflag\t^b`ԃtO\n\tvirtual void TJS_INTF_METHOD NotifyTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag ) = 0;\n\n\t//! @brief\t\t]^b`삪sꂽ\n\t//! @param\t\tstartangle\tJn̊px\n\t//! @param\t\tcurangle\t݂̊px\n\t//! @param\t\tdist\t݂2_Ԃ̕\n\t//! @param\t\tcx\t\tGĂ镝\n\t//! @param\t\tcy\t\tGĂ鍂\n\t//! @param\t\tflag\t^b`ԃtO\n\tvirtual void TJS_INTF_METHOD NotifyTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag ) = 0;\n\n\t//! @brief\t\t}`^b`ԂXVꂽ\n\tvirtual void TJS_INTF_METHOD NotifyMultiTouch() = 0;\n\n\t//! @brief\t\t͏Ԃ̃`FbN\n\t//! @note\t\tEBhE1bɁAC}l[W[U̓͂̏Ԃ\n\t//!\t\t\t\tă`FbN邽߂ɌĂ΂BCԂ̕ω[U̓͂Ƃ\n\t//!\t\t\t\t񓯊ɍsꂽꍇAƂ΃}EXJ[\\̉ɃCo\n\t//!\t\t\t\t̂ɂ炸A}EXJ[\\̃C̎w肷`ɕύXȂ\n\t//!\t\t\t\tƂ󋵂B̂悤ȏ󋵂ɑΏ邽߁AEBhE\n\t//!\t\t\t\t̃\\bh1bɌĂ΂B\n\tvirtual void TJS_INTF_METHOD RecheckInputState() = 0;\n\n//-- invalidation/update\n\t//! @brief\t\t`foCX]ރC̏o͌`ݒ肷\n\t//! @param\t\ttype\tC`\n\t//! @note\t\tftHg ltOpaque B`foCX̌`̉摜o͂Ƃ\n\t//!\t\t\t\t]ނȂ΂̌`w肷BAvC}C type\n\t//!\t\t\t\tvpeBlɕύX邱ƁB\n\tvirtual void TJS_INTF_METHOD SetDesiredLayerType(tTVPLayerType type) = 0;\n\n\t//! @brief\t\t̋`̍ĕ`v\n\t//! @param\t\tr\t\tvC}CWɂ`\n\t//! @note\t\t̋`̍ĕ`C}l[Wɑ΂ėvB\n\t//!\t\t\t\tv͋L^邾ł̃\\bh͂ɖ߂Bۂɂꂪ\n\t//!\t\t\t\tẐ UpdateToDrawDevice() Ă񂾂ƂłB\n\tvirtual void TJS_INTF_METHOD RequestInvalidation(const tTVPRect &r) = 0; // draw device -> layer\n\n\t//! @brief\t\te̍ĕ`s\n\t//! @note\t\te̍ĕ`sۂɌĂԁB̃\\bhł́AC}l[W\n\t//!\t\t\t\tiTVPDrawDevice::StartBitmapCompletion()\n\t//!\t\t\t\tiTVPDrawDevice::NotifyBitmapCompleted()\n\t//!\t\t\t\tiTVPDrawDevice::EndBitmapCompletion() ̊e\\bhpA\n\t//!\t\t\t\t܂܂łɕύXsꂽ̈Ȃǂ`foCXɑB\n\tvirtual void TJS_INTF_METHOD UpdateToDrawDevice() = 0;\n\n//-- debug assist\n\t//! @brief\t\t(Window->DrawDevice) C\\R\\[Ƀ_v\n\tvirtual void TJS_INTF_METHOD DumpLayerStructure() = 0;\n    virtual iTVPBaseBitmap *GetDrawBuffer() = 0;\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n//---------------------------------------------------------------------------\n// Touch capture infomation for layer\n//---------------------------------------------------------------------------\nstruct tTVPTouchCaptureLayer {\n\ttjs_uint32\tTouchID;\n\ttTJSNI_BaseLayer*\tOwner;\n\ttTVPTouchCaptureLayer( tjs_uint32 id, tTJSNI_BaseLayer* layer ) : TouchID(id), Owner(layer){}\n};\n\n// texture for last render target\nclass tTVPDestTexture : public tTVPBaseTexture\n{\n\tbool HoldAlpha = true;\n\npublic:\n    tTVPDestTexture(tjs_uint w, tjs_uint h) : tTVPBaseTexture(w, h) {}\n\n//     bool Blt(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n// \t\ttTVPRect refrect, tTVPBBBltMethod method, tjs_int opa);\n\tvirtual bool CopyRect(tjs_int x, tjs_int y, const iTVPBaseBitmap *ref,\n\t\ttTVPRect refrect, tjs_int plane = (TVP_BB_COPY_MAIN | TVP_BB_COPY_MASK));\n\n\tvoid SetHoldAlpha(bool b) { HoldAlpha = b; }\n};\n\n//---------------------------------------------------------------------------\n// tTVPLayerManager\n//---------------------------------------------------------------------------\n// layer mamager which is to be connected to draw device\n//---------------------------------------------------------------------------\nclass tTVPLayerManager : public iTVPLayerManager, public tTVPDrawable\n{\n\ttjs_int RefCount; //!< reference count\n\tclass iTVPLayerTreeOwner* LayerTreeOwner;\n\n\tvoid * DrawDeviceData; //!< draw device specific information\n\n\ttTVPBaseTexture * DrawBuffer;\n\ttTVPLayerType DesiredLayerType; //!< desired layer type by the draw device for this layer manager\n\n\ttTJSNI_BaseLayer * CaptureOwner;\n\ttTJSNI_BaseLayer * LastMouseMoveSent;\n\tstd::vector<tTVPTouchCaptureLayer> TouchCapture;\t//!< ^b`͑Ă10_xȂ̂vectorŎ(ق1or2_)\n\ttjs_int64 ReleaseTouchCaptureIDMark;\t//!< last touch down id\n\n\tstd::vector<tTJSNI_BaseLayer *> ModalLayerVector;\n\t\t// pointer to modal layer vector\n\ttTJSNI_BaseLayer * FocusedLayer; // pointer to current focused layer\n\ttTJSNI_BaseLayer * Primary; // primary layer\n\tbool OverallOrderIndexValid;\n\tstd::vector<tTJSNI_BaseLayer*> AllNodes;\n\t\t// hold overall nodes;\n\t\t// use GetAllNodes to retrieve the newest information of this\n\ttTVPComplexRect UpdateRegion; // window update region\n\n\tbool FocusChangeLock;\n\n\tbool VisualStateChanged;\n\t\t// flag for visual\n\t\t// state changing ( see tTJSNI_BaseLaye::NotifyChildrenVisualStateChanged)\n\n\ttjs_int LastMouseMoveX;\n\ttjs_int LastMouseMoveY;\n\n\tbool ReleaseCaptureCalled;\n\n\tbool InNotifyingHintOrCursorChange;\n\tbool HoldAlpha = true;\npublic:\n\ttTVPLayerManager(class iTVPLayerTreeOwner *owner);\n\nprivate:\n\tvirtual ~tTVPLayerManager();\npublic:\n\tvirtual void TJS_INTF_METHOD AddRef();\n\tvirtual void TJS_INTF_METHOD Release();\n\n\tvirtual void TJS_INTF_METHOD SetDrawDeviceData(void * data) { DrawDeviceData = data; }\n\tvirtual void * TJS_INTF_METHOD GetDrawDeviceData() const { return DrawDeviceData; }\n\npublic:\n\tvoid RegisterSelfToWindow();\n\tvoid UnregisterSelfFromWindow();\n\npublic:\n\tvirtual void TJS_INTF_METHOD SetDesiredLayerType(tTVPLayerType type) { DesiredLayerType = type; }\n\tvoid SetHoldAlpha(bool b);\n\npublic: // methods from tTVPDrawable\n\tvirtual tTVPBaseTexture * GetDrawTargetBitmap(const tTVPRect &rect,\n\t\ttTVPRect &cliprect);\n\n\tvirtual tTVPLayerType GetTargetLayerType();\n\n\tvirtual void DrawCompleted(const tTVPRect &destrect,\n\t\ttTVPBaseTexture *bmp, const tTVPRect &cliprect,\n\t\ttTVPLayerType type, tjs_int opacity) override;\n\tvirtual tTVPBaseTexture *GetDrawBuffer() { return DrawBuffer; }\n\ttTVPBaseTexture* GetOrCreateDrawBuffer();\n\npublic:\n\tvoid AttachPrimary(tTJSNI_BaseLayer *pri); // attach primary layer to the manager\n\tvoid DetachPrimary(); // detach primary layer from the manager\n\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetPrimaryLayer() const { return Primary; }\n\tbool IsPrimaryLayerAttached() const { return Primary != NULL; } \n\n\tvirtual bool TJS_INTF_METHOD GetPrimaryLayerSize(tjs_int &w, tjs_int &h) const;\n\n\tvoid NotifyPart(tTJSNI_BaseLayer *lay); // notifies layer parting from its parent\n\n\ttTVPComplexRect & GetUpdateRegionForCompletion() { return UpdateRegion; }\n\nprivate:\n\n\tvoid _RecreateOverallOrderIndex(tjs_uint& index,\n\t\tstd::vector<tTJSNI_BaseLayer*>& nodes);\n\npublic:\n\tvoid InvalidateOverallIndex();\n\tvoid RecreateOverallOrderIndex();\n\n\tstd::vector<tTJSNI_BaseLayer*> & GetAllNodes();\n\n\tvoid NotifyVisualStateChanged() { VisualStateChanged = true; }\n\tbool GetVisualStateChanged() { return VisualStateChanged; }\n\tvoid QueryUpdateExcludeRect();\n\n\npublic:\n\n\tvoid NotifyMouseCursorChange(tTJSNI_BaseLayer *layer, tjs_int cursor);\n\tvoid SetMouseCursor(tjs_int cursor);\n\n\tvoid GetCursorPos(tjs_int &x, tjs_int &y);\n\t\t// get cursor position in primary coordinates\n\tvoid SetCursorPos(tjs_int x, tjs_int y);\n\t\t// set cursor position in primary coordinates\n\n\tvoid NotifyHintChange(tTJSNI_BaseLayer *layer, const ttstr & hint);\n\tvoid SetHint(iTJSDispatch2* sender, const ttstr &hint);\n\t\t// set layer hint to current window\n\n\tvoid NotifyLayerResize();  // layer -> window\n\tvoid NotifyWindowInvalidation(); // layer -> window\n\npublic:\n\tclass iTVPLayerTreeOwner* GetLayerTreeOwner() const { return LayerTreeOwner; }\n\tvoid SetLayerTreeOwner(class iTVPLayerTreeOwner* owner);\n\tvoid NotifyResizeFromWindow(tjs_uint w, tjs_uint h); // draw device -> layer\n\tvirtual void TJS_INTF_METHOD RequestInvalidation(const tTVPRect &r); // draw device -> layer\n\n\tvirtual void TJS_INTF_METHOD NotifyClick(tjs_int x, tjs_int y) { PrimaryClick(x, y); }\n\tvirtual void TJS_INTF_METHOD NotifyDoubleClick(tjs_int x, tjs_int y) { PrimaryDoubleClick(x, y); }\n\tvirtual void TJS_INTF_METHOD NotifyMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags)\n\t\t{ PrimaryMouseDown(x, y, mb, flags); }\n\tvirtual void TJS_INTF_METHOD NotifyMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags)\n\t\t{ PrimaryMouseUp(x, y, mb, flags); }\n\tvirtual void TJS_INTF_METHOD NotifyMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags)\n\t\t{ PrimaryMouseMove(x, y, flags); }\n\tvirtual void TJS_INTF_METHOD NotifyMouseOutOfWindow()\n\t\t{ MouseOutOfWindow(); }\n\tvirtual void TJS_INTF_METHOD NotifyKeyDown(tjs_uint key, tjs_uint32 shift)\n\t\t{ PrimaryKeyDown(key, shift); }\n\tvirtual void TJS_INTF_METHOD NotifyKeyUp(tjs_uint key, tjs_uint32 shift)\n\t\t{ PrimaryKeyUp(key, shift); }\n\tvirtual void TJS_INTF_METHOD NotifyKeyPress(tjs_char key)\n\t\t{ PrimaryKeyPress(key); }\n\tvirtual void TJS_INTF_METHOD NotifyMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y)\n\t\t{ PrimaryMouseWheel(shift, delta, x, y); }\n\n\tvirtual void TJS_INTF_METHOD NotifyTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n\t\t{ PrimaryTouchDown(x, y, cx, cy, id); }\n\tvirtual void TJS_INTF_METHOD NotifyTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n\t\t{ PrimaryTouchUp(x, y, cx, cy, id); }\n\tvirtual void TJS_INTF_METHOD NotifyTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n\t\t{ PrimaryTouchMove(x, y, cx, cy, id); }\n\tvirtual void TJS_INTF_METHOD NotifyTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag )\n\t\t{ PrimaryTouchScaling(startdist, curdist, cx, cy, flag); }\n\tvirtual void TJS_INTF_METHOD NotifyTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag )\n\t\t{ PrimaryTouchRotate(startangle, curangle, dist, cx, cy, flag); }\n\tvirtual void TJS_INTF_METHOD NotifyMultiTouch()\n\t\t{ PrimaryMultiTouch(); }\n\n\tvoid PrimaryTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid PrimaryTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid PrimaryTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid PrimaryTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid PrimaryTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid PrimaryMultiTouch();\n\n\ttTJSNI_BaseLayer * GetMostFrontChildAt(tjs_int x, tjs_int y,\n\t\ttTJSNI_BaseLayer *except = NULL, bool get_disabled = false);\n\n\tvoid PrimaryClick(tjs_int x, tjs_int y);\n\tvoid PrimaryDoubleClick(tjs_int x, tjs_int y);\n\n\tvoid PrimaryMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid PrimaryMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\n\tvoid PrimaryMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags);\n\tvoid ForceMouseLeave();\n\tvoid ForceMouseRecheck();\n\tvoid MouseOutOfWindow();\n\tvoid LeaveMouseFromTree(tTJSNI_BaseLayer *root); // force to leave mouse\n\n\tvirtual void TJS_INTF_METHOD ReleaseCapture();\n\tvoid ReleaseCaptureFromTree(tTJSNI_BaseLayer * layer);\n\n\tbool BlurTree(tTJSNI_BaseLayer *root); // remove focus from \"root\"\n\ttTJSNI_BaseLayer *SearchFirstFocusable(bool ignore_chain_focusable = true); // search first focusable layer\n\n\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetFocusedLayer() const { return FocusedLayer; }\n\tvoid CheckTreeFocusableState(tTJSNI_BaseLayer *root);\n\t\t// check newly added tree's focusable state\n\tbool SetFocusTo(tTJSNI_BaseLayer *layer, bool direction = true);\n\t\t// set focus to layer\n\tvoid TJS_INTF_METHOD SetFocusedLayer(tTJSNI_BaseLayer * layer) { SetFocusTo(layer, false); }\n\ttTJSNI_BaseLayer *FocusPrev(); // focus to previous layer\n\ttTJSNI_BaseLayer *FocusNext(); // focus to next layer\n\tvoid ReleaseAllModalLayer(); // release all modal layer on invalidation\n\tvoid SetModeTo(tTJSNI_BaseLayer *layer); // set mode to layer\n\tvoid RemoveModeFrom(tTJSNI_BaseLayer *layer); // remove mode from layer\n\tvoid RemoveTreeModalState(tTJSNI_BaseLayer *root);\n\t\t// remove modal state from given tree\n\ttTJSNI_BaseLayer *GetCurrentModalLayer() const;\n\nprivate:\n\tbool SearchAttentionPoint(tTJSNI_BaseLayer *target, tjs_int &x, tjs_int &y);\n\tvoid SetAttentionPointOf(tTJSNI_BaseLayer *layer);\n\tvoid DisableAttentionPoint();\n\npublic:\n\tvoid NotifyAttentionStateChanged(tTJSNI_BaseLayer *from);\n\nprivate:\n\tvoid SetImeModeOf(tTJSNI_BaseLayer *layer);\n\tvoid ResetImeMode();\n\npublic:\n\tvoid NotifyImeModeChanged(tTJSNI_BaseLayer *from);\n\nprivate:\n\ttjs_int EnabledWorkRefCount;\npublic:\n\tvoid SaveEnabledWork();\n\tvoid NotifyNodeEnabledState();\n\tvoid PrimaryKeyDown(tjs_uint key, tjs_uint32 shift);\n\tvoid PrimaryKeyUp(tjs_uint key, tjs_uint32 shift);\n\tvoid PrimaryKeyPress(tjs_char key);\n\tvoid PrimaryMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y);\n\n\tvoid AddUpdateRegion(const tTVPComplexRect &rects);\n\tvoid AddUpdateRegion(const tTVPRect & rect);\n\tvoid PrimaryUpdateByWindow(const tTVPRect &rect);\n\tvirtual void TJS_INTF_METHOD UpdateToDrawDevice();\n\tvoid NotifyUpdateRegionFixed();\n\npublic:\n\tvoid TJS_INTF_METHOD RecheckInputState();\n\t\t// To re-check current layer under current mouse position\n\t\t// and update hint, cursor type and process layer enter/leave.\n\t\t// This can be reasonably slow, about 1 sec interval.\n\npublic:\n\tvoid TJS_INTF_METHOD DumpLayerStructure();\n\t\n\tvoid ReleaseTouchCapture( tjs_uint32 id );\n\tvoid ReleaseTouchCaptureAll();\nprivate:\n\tstruct FindTouchID {\n\t\ttjs_uint32 TouchID;\n\t\tinline FindTouchID( tjs_uint32 id ) : TouchID(id) {}\n\t\tinline bool operator()(const tTVPTouchCaptureLayer& touch) const { return touch.TouchID == TouchID; }\n\t};\n\tinline tTJSNI_BaseLayer* GetTouchCapture( tjs_uint32 id )\n\t{\n\t\tFindTouchID pred( id );\n\t\tstd::vector<tTVPTouchCaptureLayer>::iterator itr = std::find_if( TouchCapture.begin(), TouchCapture.end(), pred );\n\t\tif( itr != TouchCapture.end() )\n\t\t{\n\t\t\treturn itr->Owner;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn NULL;\n\t\t}\n\t}\n\tvoid SetTouchCapture( tjs_uint32 id, tTJSNI_BaseLayer* layer );\n};\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/LayerTreeOwner.h",
    "content": "//---------------------------------------------------------------------------\n/**\n * C[c[ێ@\\ Windoŵ݂łȂAʉÃC^[tFCX\n * NXł΁AC[c[Ă悤ɂ\n * \n */\n//---------------------------------------------------------------------------\n//!@file C[c[I[i[\n//---------------------------------------------------------------------------\n#ifndef LayerTreeOwner_H\n#define LayerTreeOwner_H\n#include \"drawable.h\"\n\n\nclass iTVPLayerTreeOwner\n{\npublic:\n\t// LayerManager/Layer -> LTO\n\tvirtual void TJS_INTF_METHOD RegisterLayerManager( class iTVPLayerManager* manager ) = 0;\n\tvirtual void TJS_INTF_METHOD UnregisterLayerManager( class iTVPLayerManager* manager ) = 0;\n\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager) = 0;\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, class tTVPBaseTexture *bmp,\n\t\tconst struct tTVPRect &cliprect, enum tTVPLayerType type, tjs_int opacity) = 0;\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager) = 0;\n\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(class iTVPLayerManager* manager, tjs_int cursor) = 0;\n\tvirtual void TJS_INTF_METHOD GetCursorPos(class iTVPLayerManager* manager, tjs_int &x, tjs_int &y) = 0;\n\tvirtual void TJS_INTF_METHOD SetCursorPos(class iTVPLayerManager* manager, tjs_int x, tjs_int y) = 0;\n\tvirtual void TJS_INTF_METHOD ReleaseMouseCapture(class iTVPLayerManager* manager) = 0;\n\n\tvirtual void TJS_INTF_METHOD SetHint(class iTVPLayerManager* manager, iTJSDispatch2* sender, const ttstr &hint) = 0;\n\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(class iTVPLayerManager* manager) = 0;\n\tvirtual void TJS_INTF_METHOD NotifyLayerImageChange(class iTVPLayerManager* manager) = 0;\n\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(class iTVPLayerManager* manager, class tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y) = 0;\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint(class iTVPLayerManager* manager) = 0;\n\n\tvirtual void TJS_INTF_METHOD SetImeMode( class iTVPLayerManager* manager, tjs_int mode ) = 0; // mode == tTVPImeMode\n\tvirtual void TJS_INTF_METHOD ResetImeMode( class iTVPLayerManager* manager ) = 0;\n\n\tvirtual iTJSDispatch2 * TJS_INTF_METHOD GetOwnerNoAddRef() const = 0;\n\t// LTO -> LayerManager/Layer\n\t// LTO ̒ʒm͕Kvvł͂Ȃ\n};\n\n#endif\n"
  },
  {
    "path": "src/core/visual/LayerTreeOwnerImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/**\n * \n */\n//---------------------------------------------------------------------------\n//!@file C[c[I[i[\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"ComplexRect.h\"\n#include \"LayerTreeOwnerImpl.h\"\n\n#include <algorithm>\n#include \"DrawDevice.h\"\n#include \"MsgIntf.h\"\n#include \"LayerIntf.h\"\n#include \"LayerManager.h\"\n#include \"DebugIntf.h\"\n\ntTVPLayerTreeOwner::tTVPLayerTreeOwner() : PrimaryLayerManagerIndex(0) {\n\tDestRect.clear();\n}\n\niTVPLayerManager* tTVPLayerTreeOwner::GetLayerManagerAt(size_t index) {\n\tif(Managers.size() <= index) return NULL;\n\treturn Managers[index];\n}\nconst iTVPLayerManager* tTVPLayerTreeOwner::GetLayerManagerAt(size_t index) const {\n\tif(Managers.size() <= index) return NULL;\n\treturn Managers[index];\n}\nbool tTVPLayerTreeOwner::TransformToPrimaryLayerManager(tjs_int &x, tjs_int &y) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\t// vC}C}l[W̃vC}C̃TCY𓾂\n\ttjs_int pl_w, pl_h;\n\tif(!manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n\t// x , y  DestRect  0, 0 _ƂWƂēnĂĂ\n\ttjs_int w = DestRect.get_width();\n\ttjs_int h = DestRect.get_height();\n\tx = w ? (x * pl_w / w) : 0;\n\ty = h ? (y * pl_h / h) : 0;\n\treturn true;\n}\nbool tTVPLayerTreeOwner::TransformToPrimaryLayerManager(tjs_real &x, tjs_real &y) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\t// vC}C}l[W̃vC}C̃TCY𓾂\n\ttjs_int pl_w, pl_h;\n\tif(!manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n\t// x , y  DestRect  0, 0 _ƂWƂēnĂĂ\n\tx = pl_w ? (x * DestRect.get_width()  / pl_w) : 0.0;\n\ty = pl_h ? (y * DestRect.get_height() / pl_h) : 0.0;\n\treturn true;\n}\nbool tTVPLayerTreeOwner::TransformFromPrimaryLayerManager(tjs_int &x, tjs_int &y) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\t// vC}C}l[W̃vC}C̃TCY𓾂\n\ttjs_int pl_w, pl_h;\n\tif(!manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n\t// x , y  DestRect  0, 0 _ƂWƂēnĂĂ\n\tx = pl_w ? (x * DestRect.get_width()  / pl_w) : 0;\n\ty = pl_h ? (y * DestRect.get_height() / pl_h) : 0;\n\treturn true;\n}\nvoid tTVPLayerTreeOwner::GetPrimaryLayerSize( tjs_int &w, tjs_int &h ) const {\n\tw = h = 0;\n\tconst iTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tif(!manager->GetPrimaryLayerSize(w, h)) {\n\t\tw = h = 0;\n\t}\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::RegisterLayerManager( class iTVPLayerManager* manager ) {\n\t// Managers  manager  push BAddRef̂YȂƁB\n\tManagers.push_back(manager);\n\tmanager->AddRef();\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::UnregisterLayerManager( class iTVPLayerManager* manager ) {\n\t// Managers  manager 폜BReleaseB\n\tstd::vector<iTVPLayerManager *>::iterator i = std::find(Managers.begin(), Managers.end(), manager);\n\tif(i == Managers.end())\n\t\tTVPThrowInternalError;\n\t(*i)->Release();\n\tManagers.erase(i);\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::SetMouseCursor(class iTVPLayerManager* manager, tjs_int cursor) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnSetMouseCursor( cursor );\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::GetCursorPos(class iTVPLayerManager* manager, tjs_int &x, tjs_int &y) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tOnGetCursorPos(x, y);\n\tif(primary_manager != manager || !TransformToPrimaryLayerManager(x, y)) {\n\t\t// vC}C}l[WȊOɂ͍W 0,0 œnĂ\n\t\t x = y = 0;\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::SetCursorPos(class iTVPLayerManager* manager, tjs_int x, tjs_int y) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tif(TransformFromPrimaryLayerManager(x, y))\n\t\t\tOnSetCursorPos(x, y);\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::ReleaseMouseCapture(class iTVPLayerManager* manager) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnReleaseMouseCapture();\n\t}\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::SetHint(class iTVPLayerManager* manager, iTJSDispatch2* sender, const ttstr &hint) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnSetHintText(sender,hint);\n\t}\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::NotifyLayerResize(class iTVPLayerManager* manager) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(primary_manager == manager) {\n\t\ttjs_int w, h;\n\t\tGetPrimaryLayerSize( w, h );\n\t\tOnResizeLayer( w, h );\n\t\tDestRect.set_size( w, h );\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::NotifyLayerImageChange(class iTVPLayerManager* manager) {\n\t// change layer image\n\tfor(std::vector<iTVPLayerManager *>::iterator i = Managers.begin(); i != Managers.end(); i++) {\n\t\t(*i)->UpdateToDrawDevice();\n\t}\n\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(primary_manager == manager)\n\t\tOnChangeLayerImage();\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::SetAttentionPoint(class iTVPLayerManager* manager, tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tif(TransformFromPrimaryLayerManager(x, y))\n\t\t\tOnSetAttentionPoint( layer, x, y);\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::DisableAttentionPoint(class iTVPLayerManager* manager) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnDisableAttentionPoint();\n\t}\n}\n\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::SetImeMode( class iTVPLayerManager* manager, tjs_int mode ) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnSetImeMode(mode);\n\t}\n}\nvoid TJS_INTF_METHOD tTVPLayerTreeOwner::ResetImeMode( class iTVPLayerManager* manager ) {\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager) {\n\t\tOnResetImeMode();\n\t}\n}\n\nvoid tTVPLayerTreeOwner::FireClick(tjs_int x, tjs_int y) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyClick(x, y);\n}\nvoid tTVPLayerTreeOwner::FireDoubleClick(tjs_int x, tjs_int y) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyDoubleClick(x, y);\n}\nvoid tTVPLayerTreeOwner::FireMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMouseDown(x, y, mb, flags);\n}\nvoid tTVPLayerTreeOwner::FireMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMouseUp(x, y, mb, flags);\n}\nvoid tTVPLayerTreeOwner::FireMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMouseMove(x, y, flags);\n}\nvoid tTVPLayerTreeOwner::FireMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMouseWheel(shift, delta, x, y);\n}\nvoid tTVPLayerTreeOwner::FireReleaseCapture() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->ReleaseCapture();\n}\nvoid tTVPLayerTreeOwner::FireMouseOutOfWindow() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMouseOutOfWindow();\n}\n\nvoid tTVPLayerTreeOwner::FireTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyTouchDown(x, y, cx, cy, id);\n}\nvoid tTVPLayerTreeOwner::FireTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyTouchUp(x, y, cx, cy, id);\n}\nvoid tTVPLayerTreeOwner::FireTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyTouchMove(x, y, cx, cy, id);\n}\nvoid tTVPLayerTreeOwner::FireTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag ) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyTouchScaling(startdist, curdist, cx, cy, flag);\n}\nvoid tTVPLayerTreeOwner::FireTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag ) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyTouchRotate(startangle, curangle, dist, cx, cy, flag);\n}\nvoid tTVPLayerTreeOwner::FireMultiTouch() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyMultiTouch();\n}\n\nvoid tTVPLayerTreeOwner::FireKeyDown(tjs_uint key, tjs_uint32 shift) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyKeyDown(key, shift);\n}\nvoid tTVPLayerTreeOwner::FireKeyUp(tjs_uint key, tjs_uint32 shift) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyKeyUp(key, shift);\n}\nvoid tTVPLayerTreeOwner::FireKeyPress(tjs_char key) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->NotifyKeyPress(key);\n}\n\nvoid tTVPLayerTreeOwner::FireDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int hresolution, tjs_int vresolution ) {\n\t// Ȃ\n}\n\nvoid tTVPLayerTreeOwner::FireRecheckInputState() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->RecheckInputState();\n}\ntTJSNI_BaseLayer* tTVPLayerTreeOwner::GetPrimaryLayer() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return NULL;\n\treturn manager->GetPrimaryLayer();\n}\ntTJSNI_BaseLayer* tTVPLayerTreeOwner::GetFocusedLayer() {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return NULL;\n\treturn manager->GetFocusedLayer();\n}\nvoid tTVPLayerTreeOwner::SetFocusedLayer(tTJSNI_BaseLayer * layer) {\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->SetFocusedLayer(layer);\n}\n\n"
  },
  {
    "path": "src/core/visual/LayerTreeOwnerImpl.h",
    "content": "//---------------------------------------------------------------------------\n/**\n * \n */\n//---------------------------------------------------------------------------\n//!@file C[c[I[i[\n//---------------------------------------------------------------------------\n#ifndef LayerTreeOwnerImple_H\n#define LayerTreeOwnerImple_H\n\n#include \"LayerTreeOwner.h\"\n#include \"tvpinputdefs.h\"\n\n/**\n * ŏLayerTreeOwner@\\񋟂B\n * ق iTVPLayerManager ֘A\\bĥ\n * ̃\\bh͖Ȃ̂ŁApŎKv\n */\nclass tTVPLayerTreeOwner : public iTVPLayerTreeOwner\n{\nprotected:\n\tsize_t PrimaryLayerManagerIndex; //!< vC}C}l[W\n\tstd::vector<iTVPLayerManager *> Managers; //!< C}l[W̔z\n\ttTVPRect DestRect; //!< `ʒu\n\nprotected:\n\tiTVPLayerManager* GetLayerManagerAt(size_t index);\n\tconst iTVPLayerManager* GetLayerManagerAt(size_t index) const;\n\tbool TransformToPrimaryLayerManager(tjs_int &x, tjs_int &y);\n\tbool TransformToPrimaryLayerManager(tjs_real &x, tjs_real &y);\n\tbool TransformFromPrimaryLayerManager(tjs_int &x, tjs_int &y);\n\n\tvoid GetPrimaryLayerSize( tjs_int &w, tjs_int &h ) const;\n\npublic:\n\ttTVPLayerTreeOwner();\n\n\t// LayerManager/Layer -> LTO\n\tvirtual void TJS_INTF_METHOD RegisterLayerManager( class iTVPLayerManager* manager );\n\tvirtual void TJS_INTF_METHOD UnregisterLayerManager( class iTVPLayerManager* manager );\n\n\t/* ۂ̕`\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager) = 0;\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, const void * bits, const class BitmapInfomation * bitmapinfo,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity) = 0;\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager) = 0;\n\t*/\n\n\t// ȉ͉Ȃ\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(class iTVPLayerManager* manager, tjs_int cursor);\n\tvirtual void TJS_INTF_METHOD GetCursorPos(class iTVPLayerManager* manager, tjs_int &x, tjs_int &y);\n\tvirtual void TJS_INTF_METHOD SetCursorPos(class iTVPLayerManager* manager, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD ReleaseMouseCapture(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetHint(class iTVPLayerManager* manager, iTJSDispatch2* sender, const ttstr &hint);\n\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(class iTVPLayerManager* manager);\n\tvirtual void TJS_INTF_METHOD NotifyLayerImageChange(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(class iTVPLayerManager* manager, tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetImeMode( class iTVPLayerManager* manager, tjs_int mode );\n\tvirtual void TJS_INTF_METHOD ResetImeMode( class iTVPLayerManager* manager );\n\n\t// virtual iTJSDispatch2 * TJS_INTF_METHOD GetOwnerNoAddRef() const = 0;\n\n\t// ȉ͏q̃\\bhR[ꂽɁAۂɒlݒ肷邽߂ɌĂ΂\n\t// cursor == 0  default\n\tvirtual void OnSetMouseCursor( tjs_int cursor ) = 0;\n\tvirtual void OnGetCursorPos(tjs_int &x, tjs_int &y) = 0;\n\tvirtual void OnSetCursorPos(tjs_int x, tjs_int y) = 0;\n\tvirtual void OnReleaseMouseCapture() = 0;\n\tvirtual void OnSetHintText(iTJSDispatch2* sender, const ttstr &hint) = 0;\n\n\t/**\n\t * vC}[C[̃TCYύXꂽɌĂ΂\n\t */\n\tvirtual void OnResizeLayer( tjs_int w, tjs_int h ) = 0;\n\t/**\n\t * vC}[C[̉摜ύXꂽ̂ŁAKvɉčĕ`s\n\t * NotifyLayerImageChange Ă΂Ă\n\t */\n\tvirtual void OnChangeLayerImage() = 0;\n\n\tvirtual void OnSetAttentionPoint(tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y) = 0;\n\tvirtual void OnDisableAttentionPoint() = 0;\n\tvirtual void OnSetImeMode(tjs_int mode) = 0;\n\tvirtual void OnResetImeMode() = 0;\n\n\t// LTO -> LayerManager/Layer\n\t// LayerManager ɑ΂ăCxgʒm邽߂̃\\bh\n\tvoid FireClick(tjs_int x, tjs_int y);\n\tvoid FireDoubleClick(tjs_int x, tjs_int y);\n\tvoid FireMouseDown(tjs_int x, tjs_int y, enum tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid FireMouseUp(tjs_int x, tjs_int y, enum tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid FireMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags);\n\tvoid FireMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y);\n\n\tvoid FireReleaseCapture();\n\tvoid FireMouseOutOfWindow();\n\n\tvoid FireTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvoid FireTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid FireTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid FireMultiTouch();\n\n\tvoid FireKeyDown(tjs_uint key, tjs_uint32 shift);\n\tvoid FireKeyUp(tjs_uint key, tjs_uint32 shift);\n\tvoid FireKeyPress(tjs_char key);\n\n\tvoid FireDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int hresolution, tjs_int vresolution );\n\n\tvoid FireRecheckInputState();\n\n\t// C[Ǘ⏕\n\ttTJSNI_BaseLayer* GetPrimaryLayer();\n\ttTJSNI_BaseLayer* GetFocusedLayer();\n\tvoid SetFocusedLayer(tTJSNI_BaseLayer * layer);\n};\n\n#endif\n"
  },
  {
    "path": "src/core/visual/LoadBPG.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsDictionary.h\"\n#include <memory>\n\nextern \"C\" {\n#include \"libbpg/libbpg.h\"\n}\n\nextern void TVPInitLibAVCodec();\n\nstruct CBPGDecoderContext {\n\tBPGDecoderContext *ctx;\n\tCBPGDecoderContext() {\n\t\tTVPInitLibAVCodec();\n\t\tctx = bpg_decoder_open();\n\t}\n\t~CBPGDecoderContext() {\n\t\tbpg_decoder_close(ctx);\n\t}\n\tBPGDecoderContext *get() { return ctx; }\n};\n\nvoid TVPLoadBPG(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int keyidx,\n\ttTVPGraphicLoadMode mode)\n{\n\tCBPGDecoderContext img;\n\tint datasize = src->GetSize();\n\tstd::unique_ptr<uint8_t[]> data(new uint8_t[datasize]);\n\tsrc->ReadBuffer(data.get(), datasize);\n\n\tif (bpg_decoder_decode(img.get(), data.get(), datasize) < 0) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid BPG image\"));\n\t}\n\n\tBPGImageInfo img_info;\n\n\tbpg_decoder_get_info(img.get(), &img_info);\n\n\tsizecallback(callbackdata, img_info.width, img_info.height, img_info.has_alpha ? gpfRGBA : gpfRGB);\n\tbpg_decoder_start(img.get(), BPG_OUTPUT_FORMAT_RGBA32);\n\tif (glmNormal == mode) {\n\t\tfor (uint32_t y = 0; y < img_info.height; y++) {\n\t\t\tbpg_decoder_get_line(img.get(), (uint8_t*)scanlinecallback(callbackdata, y));\n\t\t}\n\t} else if (glmGrayscale == mode) {\n\t\tfor (uint32_t y = 0; y < img_info.height; y++) {\n\t\t\tbpg_decoder_get_gray_line(img.get(), (uint8_t*)scanlinecallback(callbackdata, y));\n\t\t}\n\t}\n\tscanlinecallback(callbackdata, -1); // image was written\n}\n\nvoid TVPLoadHeaderBPG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic) {\n\n\tCBPGDecoderContext img;\n\tint datasize = src->GetSize();\n\tstd::unique_ptr<uint8_t[]> data(new uint8_t[datasize]);\n\tsrc->ReadBuffer(data.get(), datasize);\n\n\tif (bpg_decoder_decode(img.get(), data.get(), datasize) < 0) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid BPG image\"));\n\t}\n\tBPGImageInfo img_info;\n\tbpg_decoder_get_info(img.get(), &img_info);\n\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val((tjs_int32)img_info.width);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic));\n\tval = tTJSVariant((tjs_int32)img_info.height);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic));\n\tval = tTJSVariant(img_info.has_alpha ? 32 : 24);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic));\n}\n\n"
  },
  {
    "path": "src/core/visual/LoadJPEG.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tvpgl.h\"\n\n#include \"tjsDictionary.h\"\n#include \"ScriptMgnIntf.h\"\n\nbool TVPAcceptSaveAsJPG(void* formatdata, const ttstr & type, class iTJSDispatch2** dic )\n{\n\tbool result = false;\n\tif( type.StartsWith(TJS_W(\"jpg\")) ) result = true;\n\telse if( type == TJS_W(\".jpg\") ) result = true;\n\telse if( type == TJS_W(\".jpeg\") ) result = true;\n\telse if( type == TJS_W(\".jif\") ) result = true;\n\t// quality 1 - 100\n\t// subsampling : select 0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:4\n\t// dct : select 0 : islow, 1 : ifast, 2 : float\n\t// progressive : boolean\n\tif( result && dic ) {\n\t\ttTJSVariant result;\n\t\tTVPExecuteExpression(\n\t\t\tTJS_W(\"(const)%[\")\n\t\t\tTJS_W(\"\\\"quality\\\"=>(const)%[\\\"type\\\"=>\\\"range\\\",\\\"min\\\"=>1,\\\"max\\\"=>100,\\\"desc\\\"=>\\\"100 is high quality, 1 is low quality\\\",\\\"default\\\"=>90],\")\n\t\t\tTJS_W(\"\\\"subsampling\\\"=>(const)%[\\\"type\\\"=>\\\"select\\\",\\\"items\\\"=>(const)[\\\"4:2:0\\\",\\\"4:2:2\\\",\\\"4:4:4\\\"],\\\"desc\\\"=>\\\"subsampling\\\",\\\"default\\\"=>0],\")\n\t\t\tTJS_W(\"\\\"dct\\\"=>(const)%[\\\"type\\\"=>\\\"select\\\",\\\"items\\\"=>(const)[\\\"islow\\\",\\\"ifast\\\",\\\"float\\\"],\\\"desc\\\"=>\\\"DCT method\\\",\\\"default\\\"=>0],\")\n\t\t\tTJS_W(\"\\\"progressive\\\"=>(const)%[\\\"type\\\"=>\\\"boolean\\\",\\\"desc\\\"=>\\\"100 is high quality, 1 is low quality\\\",\\\"default\\\"=>true]\")\n\t\t\tTJS_W(\"]\"),\n\t\t\tNULL, &result );\n\t\tif( result.Type() == tvtObject ) {\n\t\t\t*dic = result.AsObject();\n\t\t}\n\t}\n\treturn result;\n}\n\nextern \"C\"\n{\n#include <turbojpeg.h>\n#define XMD_H\n//#include <jinclude.h>\n#include <jpeglib.h>\n#include <jerror.h>\n}\n#define TVP_USE_TURBO_JPEG_API\n//---------------------------------------------------------------------------\n// JPEG loading handler\n//---------------------------------------------------------------------------\ntTVPJPEGLoadPrecision TVPJPEGLoadPrecision = jlpMedium;\n//---------------------------------------------------------------------------\nstruct my_error_mgr\n{\n\tstruct jpeg_error_mgr pub;\n};\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nmy_error_exit(j_common_ptr cinfo)\n{\n\tTVPThrowExceptionMessage(TVPJPEGLoadError,\n\t\tttstr(TVPErrorCode) + ttstr(cinfo->err->msg_code));\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nmy_emit_message(j_common_ptr c, int n)\n{\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nmy_output_message(j_common_ptr c)\n{\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nmy_format_message(j_common_ptr c, char* m)\n{\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nmy_reset_error_mgr(j_common_ptr c)\n{\n\tc->err->num_warnings = 0;\n\tc->err->msg_code = 0;\n}\n//---------------------------------------------------------------------------\n#define BUFFER_SIZE 8192\nstruct my_source_mgr\n{\n\tjpeg_source_mgr pub;\n\tJOCTET * buffer;\n\ttTJSBinaryStream * stream;\n\tboolean start_of_file;\n} ;\n//---------------------------------------------------------------------------\nMETHODDEF(void)\ninit_source(j_decompress_ptr cinfo)\n{\n\t// ??\n  my_source_mgr * src = (my_source_mgr*) cinfo->src;\n\n  src->start_of_file = TRUE;\n}\n//---------------------------------------------------------------------------\nMETHODDEF(boolean)\nfill_input_buffer(j_decompress_ptr cinfo)\n{\n  my_source_mgr * src = (my_source_mgr*) cinfo->src;\n\n  int nbytes = src->stream->Read(src->buffer, BUFFER_SIZE);\n\n  if(nbytes <= 0)\n  {\n\tif(src->start_of_file)\n\t\tERREXIT(cinfo, JERR_INPUT_EMPTY);\n\tWARNMS(cinfo, JWRN_JPEG_EOF);\n\n    src->buffer[0] = (JOCTET) 0xFF;\n\tsrc->buffer[1] = (JOCTET) JPEG_EOI;\n    nbytes = 2;\n  }\n\n  src->pub.next_input_byte = src->buffer;\n  src->pub.bytes_in_buffer = nbytes;\n\n  src->start_of_file = FALSE;\n\n  return TRUE;\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nskip_input_data(j_decompress_ptr cinfo, long num_bytes)\n{\n  my_source_mgr * src = (my_source_mgr*) cinfo->src;\n\n  if (num_bytes > 0) {\n\twhile (num_bytes > (long) src->pub.bytes_in_buffer) {\n\t  num_bytes -= (long) src->pub.bytes_in_buffer;\n\t  fill_input_buffer(cinfo);\n\t  /* note that we assume that fill_input_buffer will never return FALSE,\n\t   * so suspension need not be handled.\n\t   */\n\t}\n\tsrc->pub.next_input_byte += (size_t) num_bytes;\n\tsrc->pub.bytes_in_buffer -= (size_t) num_bytes;\n  }\n}\n//---------------------------------------------------------------------------\nMETHODDEF(void)\nterm_source (j_decompress_ptr cinfo)\n{\n  /* no work necessary here */\n}\n//---------------------------------------------------------------------------\nGLOBAL(void)\njpeg_TStream_src (j_decompress_ptr cinfo, tTJSBinaryStream * infile)\n{\n  my_source_mgr * src;\n\n  if (cinfo->src == NULL) {\t/* first time for this JPEG object? */\n\tcinfo->src = (struct jpeg_source_mgr *)\n\t  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,\n\t\t\t\t  sizeof(my_source_mgr));\n\tsrc = (my_source_mgr * ) cinfo->src;\n\tsrc->buffer = (JOCTET *)\n\t  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,\n\t\t\t\t  BUFFER_SIZE * sizeof(JOCTET));\n  }\n\n  src = (my_source_mgr *) cinfo->src;\n  src->pub.init_source = init_source;\n  src->pub.fill_input_buffer = fill_input_buffer;\n  src->pub.skip_input_data = skip_input_data;\n  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */\n  src->pub.term_source = term_source;\n  src->stream = infile;\n  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */\n  src->pub.next_input_byte = NULL; /* until buffer loaded */\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadJPEG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n#ifdef TVP_USE_TURBO_JPEG_API\n\t// JPEG does not support palettized image\n\tif(mode == glmPalettized)\n\t\tTVPThrowExceptionMessage(TVPJPEGLoadError,\n\t\t\tttstr(TVPUnsupportedJpegPalette));\n\n\tunsigned long jpegSize = (unsigned long)src->GetSize();\n\tunsigned char *jpegBuf = new unsigned char[jpegSize];\n\ttjs_uint nbytes = src->Read( jpegBuf, jpegSize );\n\tif( nbytes != jpegSize ) {\n\t\tdelete[] jpegBuf;\n\t\tTVPThrowExceptionMessage( TVPReadError );\n\t}\n\n\tint jpegSubsamp, width, height;\n\ttjhandle jpegDecompressor = tjInitDecompress();\n\ttjDecompressHeader2( jpegDecompressor, jpegBuf, jpegSize, &width, &height, &jpegSubsamp );\n\tsizecallback(callbackdata, width, height, gpfRGB); // jpeg has no alpha channel\n\n\t// decompress option\n\tint flags = TJFLAG_FASTDCT;\n\tswitch(TVPJPEGLoadPrecision)\n\t{\n\tcase jlpLow:\n\t\tflags = TJFLAG_FASTDCT|TJFLAG_FASTUPSAMPLE;\n\t\tbreak;\n\tcase jlpMedium:\n\t\tflags = TJFLAG_FASTDCT;\n\t\tbreak;\n\tcase jlpHigh:\n\t\tflags = TJFLAG_ACCURATEDCT;\n\t\tbreak;\n\t}\n\t//flags |= TJFLAG_BOTTOMUP;\n\tint pixelFormat = TJPF_RGBA;\n\tint numcolor = 4;\n\tif(mode == glmGrayscale) {\n\t\tpixelFormat =  TJPF_GRAY;\n\t\tnumcolor = 1;\n\t}\n\n\tunsigned char *buffer = NULL;\n\ttry {\n\t\tbuffer = tjAlloc(width*height*numcolor);\n\t\ttjDecompress2( jpegDecompressor, jpegBuf, jpegSize, buffer, width, width*numcolor, height, pixelFormat, flags );\n\t\tif(mode == glmGrayscale) {\n\t\t\tfor( int y = 0; y < height; y++ ) {\n\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, y);\n\t\t\t\tif(!scanline) break;\n\t\t\t\tmemcpy( scanline, (const void*)&buffer[y*width], width );\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n\t\t} else {\n\t\t\tfor( int y = 0; y < height; y++ ) {\n\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, y);\n\t\t\t\tif(!scanline) break;\n\t\t\t\tmemcpy( scanline, (const void*)&buffer[y*width*sizeof(tjs_uint32)], width*sizeof(tjs_uint32) );\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n\t\t}\n\t\tdelete[] jpegBuf;\n\t\tjpegBuf = NULL;\n\t\ttjFree( buffer );\n\t\tbuffer = NULL;\n\t} catch(...) {\n\t\tdelete[] jpegBuf;\n\t\tjpegBuf = NULL;\n\t\ttjFree( buffer );\n\t\ttjDestroy( jpegDecompressor );\n\t\tthrow;\n\t}\n\ttjDestroy( jpegDecompressor );\n#else\n\t// JPEG loading handler\n\n\t// JPEG does not support palettized image\n\tif(mode == glmPalettized)\n\t\tTVPThrowExceptionMessage(TVPJPEGLoadError,\n\t\t\tttstr(TVPUnsupportedJpegPalette));\n\n\t// prepare variables\n\tjpeg_decompress_struct cinfo;\n\tmy_error_mgr jerr;\n\tJSAMPARRAY buffer;\n\t//tjs_int row_stride;\n\n\t// error handling\n\tcinfo.err = jpeg_std_error(&jerr.pub);\n\tjerr.pub.error_exit = my_error_exit;\n\tjerr.pub.emit_message = my_emit_message;\n\tjerr.pub.output_message = my_output_message;\n\tjerr.pub.format_message = my_format_message;\n\tjerr.pub.reset_error_mgr = my_reset_error_mgr;\n\n\t// create decompress object\n\tjpeg_create_decompress(&cinfo);\n\n\t// set data source\n\tjpeg_TStream_src(&cinfo, src);\n\n\t// read the header\n\tjpeg_read_header(&cinfo, TRUE);\n\n\t// decompress option\n\tswitch(TVPJPEGLoadPrecision)\n\t{\n\tcase jlpLow:\n\t\tcinfo.dct_method = JDCT_IFAST;\n\t\tcinfo.do_fancy_upsampling = FALSE;\n\t\tbreak;\n\tcase jlpMedium:\n\t\t//cinfo.dct_method = JDCT_IFAST;\n\t\tcinfo.dct_method = JDCT_ISLOW;\n\t\tcinfo.do_fancy_upsampling = TRUE;\n\t\tbreak;\n\tcase jlpHigh:\n\t\tcinfo.dct_method = JDCT_FLOAT;\n\t\tcinfo.do_fancy_upsampling = TRUE;\n\t\tbreak;\n\t}\n\n\tif(mode == glmGrayscale) cinfo.out_color_space =  JCS_GRAYSCALE;\n\n\t// start decompression\n\tjpeg_start_decompress(&cinfo);\n\n\ttry\n\t{\n\t\tsizecallback(callbackdata, cinfo.output_width, cinfo.output_height);\n\t\tif( mode == glmNormal && cinfo.out_color_space == JCS_RGB ) {\n\t\t\tbuffer = new JSAMPROW[cinfo.output_height];\n\t\t\tfor( unsigned int i = 0; i < cinfo.output_height; i++ ) {\n\t\t\t\tbuffer[i] = (JSAMPLE*)scanlinecallback(callbackdata, i);\n\t\t\t}\n\t\t\twhile( cinfo.output_scanline < cinfo.output_height ) {\n\t\t\t\tjpeg_read_scanlines( &cinfo, buffer + cinfo.output_scanline, cinfo.output_height - cinfo.output_scanline );\n\t\t\t}\n\t\t\tdelete[] buffer;\n\t\t\tfor( unsigned int i = 0; i < cinfo.output_height; i++ ) {\n\t\t\t\tscanlinecallback(callbackdata, i);\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n\t\t} else\n\t\t{\n\t\t\tbuffer = (*cinfo.mem->alloc_sarray)\n\t\t\t\t((j_common_ptr) &cinfo, JPOOL_IMAGE,\n\t\t\t\t\tcinfo.output_width * cinfo.output_components + 3,\n\t\t\t\t\tcinfo.rec_outbuf_height);\n\n\t\t\twhile(cinfo.output_scanline < cinfo.output_height)\n\t\t\t{\n\t\t\t\ttjs_int startline = cinfo.output_scanline;\n\n\t\t\t\tjpeg_read_scanlines(&cinfo, buffer, cinfo.rec_outbuf_height);\n\n\t\t\t\ttjs_int endline = cinfo.output_scanline;\n\t\t\t\ttjs_int bufline;\n\t\t\t\ttjs_int line;\n\n\t\t\t\tfor(line = startline, bufline = 0; line < endline; line++, bufline++)\n\t\t\t\t{\n\t\t\t\t\tvoid *scanline =\n\t\t\t\t\t\tscanlinecallback(callbackdata, line);\n\t\t\t\t\tif(!scanline) break;\n\n\t\t\t\t\t// color conversion\n\t\t\t\t\tif(mode == glmGrayscale)\n\t\t\t\t\t{\n\t\t\t\t\t\t// write through\n\t\t\t\t\t\tmemcpy(scanline,\n\t\t\t\t\t\t\tbuffer[bufline], cinfo.output_width);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(cinfo.out_color_space == JCS_RGB)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmemcpy(scanline,\n\t\t\t\t\t\t\t\tbuffer[bufline], cinfo.output_width*sizeof(tjs_uint32));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// expand 8bits to 32bits\n\t\t\t\t\t\t\tTVPExpand8BitTo32BitGray(\n\t\t\t\t\t\t\t\t(tjs_uint32*)scanline,\n\t\t\t\t\t\t\t\t(tjs_uint8*)buffer[bufline], cinfo.output_width);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t\t}\n\t\t\t\tif(line != endline) break; // interrupted by !scanline\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tjpeg_destroy_decompress(&cinfo);\n\t\tthrow;\n\t}\n\n\tjpeg_finish_decompress(&cinfo);\n\tjpeg_destroy_decompress(&cinfo);\n#endif\n}\n//---------------------------------------------------------------------------\nstruct stream_destination_mgr {\n\tstruct jpeg_destination_mgr\tpub;\t\t/* public fields */\n\ttTJSBinaryStream*\t\t\tstream;\n\tJOCTET*\t\t\t\t\t\tbuffer;\t\t/* buffer start address */\n\tint\t\t\t\t\t\t\tbufsize;\t/* size of buffer */\n\tint\t\t\t\t\t\t\tbufsizeinit;/* size of buffer */\n\tsize_t\t\t\t\t\t\tdatasize;\t/* final size of compressed data */\n\tint*\t\t\t\t\t\toutsize;\t/* user pointer to datasize */\n};\ntypedef stream_destination_mgr* stream_dest_ptr;\n\nMETHODDEF(void) JPEG_write_init_destination( j_compress_ptr cinfo ) {\n\tstream_dest_ptr dest = (stream_dest_ptr)cinfo->dest;\n\tdest->pub.next_output_byte = dest->buffer;\n\tdest->pub.free_in_buffer = dest->bufsize;\n\tdest->datasize = 0;\t /* reset output size */\n}\n\nMETHODDEF(boolean) JPEG_write_empty_output_buffer( j_compress_ptr cinfo ) {\n\tstream_dest_ptr dest = (stream_dest_ptr)cinfo->dest;\n\t\n\t// ����Ȃ��Ȃ�����r����������\n\tsize_t\twrotelen = dest->bufsizeinit - dest->pub.free_in_buffer;\n\tdest->stream->WriteBuffer( dest->buffer, (tjs_uint)wrotelen );\n\n\tdest->pub.next_output_byte = dest->buffer;\n\tdest->pub.free_in_buffer = dest->bufsize;\n\treturn TRUE;\n}\n\nMETHODDEF(void) JPEG_write_term_destination( j_compress_ptr cinfo ) {\n\tstream_dest_ptr dest = (stream_dest_ptr)cinfo->dest;\n\tdest->datasize = dest->bufsize - dest->pub.free_in_buffer;\n\tif( dest->outsize ) *dest->outsize += (int)dest->datasize;\n}\nMETHODDEF(void) JPEG_write_stream( j_compress_ptr cinfo, JOCTET* buffer, int bufsize, int* outsize, tTJSBinaryStream* stream ) {\n\tstream_dest_ptr dest;\n\n\t/* first call for this instance - need to setup */\n\tif (cinfo->dest == 0) {\n\t\tcinfo->dest = (struct jpeg_destination_mgr*)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(stream_destination_mgr) );\n\t}\n\n\tdest = (stream_dest_ptr) cinfo->dest;\n\tdest->stream = stream;\n\tdest->bufsize = bufsize;\n\tdest->bufsizeinit = bufsize;\n\tdest->buffer = buffer;\n\tdest->outsize = outsize;\n\t/* set method callbacks */\n\tdest->pub.init_destination = JPEG_write_init_destination;\n\tdest->pub.empty_output_buffer = JPEG_write_empty_output_buffer;\n\tdest->pub.term_destination = JPEG_write_term_destination;\n}\nstruct tTVPJPGOption\n{\n\ttjs_uint quality;\n\tJ_DCT_METHOD dct_method;\n\tint subsampling;\n\tbool progressive;\n};\n//---------------------------------------------------------------------------\n/**\n * JPG��������\n * �t���J���[�ł̏������݂̂ݑΉ�\n * @param storagename : �o�̓t�@�C����\n * @param mode : ���[�h \"jpg\" �ƕK�v�Ȃ爳�k���𐔒l�Ō�ɕt������\n * @param image : �����o���C���[�W�f�[�^\n */\nvoid TVPSaveAsJPG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta )\n{\n\ttTVPJPGOption opt = { 90, JDCT_ISLOW, 0, true };\n\tif( mode.StartsWith(TJS_W(\"jpg\")) && mode.length() > 3 ) {\n\t\topt.quality = 0;\n\t\tfor( tjs_int len = 3; len < mode.length(); len++ ) {\n\t\t\ttjs_char c = mode[len];\n\t\t\tif( c >= TJS_W('0') && c <= TJS_W('9') ) {\n\t\t\t\topt.quality *= 10;\n\t\t\t\topt.quality += c-TJS_W('0');\n\t\t\t}\n\t\t}\n\t\tif( opt.quality <= 0 ) opt.quality = 10;\n\t\tif( opt.quality > 100 ) opt.quality = 100;\n\t}\n\n\t{\n\t\t// EnumCallback ���g���ăv���p�e�B��ݒ肷��\n\t\tstruct MetaDictionaryEnumCallback : public tTJSDispatch {\n\t\t\ttTVPJPGOption *opt_;\n\t\t\tMetaDictionaryEnumCallback( tTVPJPGOption *opt ) : opt_(opt) {}\n\t\t\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis) { // called from tTJSCustomObject::EnumMembers\n\t\t\t\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\t\tif(flags & TJS_HIDDENMEMBER) {\t// hidden members are not processed\n\t\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\t\treturn TJS_S_OK;\n\t\t\t\t}\n\t\t\t\t// push items\n\t\t\t\tttstr value = *param[0];\n\t\t\t\tif( value == TJS_W(\"quality\") ) {\n\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\tv = v < 1 ? 1 : v > 100 ? 100 : v;\n\t\t\t\t\topt_->quality = (tjs_uint)v;\n\t\t\t\t} else if( value == TJS_W(\"subsampling\") ) {\n\t\t\t\t\t// 0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:4\n\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\tv = v < 0 ? 0 : v > 2 ? 2 : v;\n\t\t\t\t\topt_->subsampling = (int)v;\n\t\t\t\t} else if( value == TJS_W(\"dct\") ) {\n\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\tv = v < 0 ? 0 : v > 2 ? 2 : v;\n\t\t\t\t\tswitch( v ) {\n\t\t\t\t\tcase 0: opt_->dct_method = JDCT_ISLOW; break;\n\t\t\t\t\tcase 1: opt_->dct_method = JDCT_IFAST; break;\n\t\t\t\t\tcase 2: opt_->dct_method = JDCT_FLOAT; break;\n\t\t\t\t\t}\n\t\t\t\t} else if( value == TJS_W(\"progressive\") ) {\n\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\tif( v ) {\n\t\t\t\t\t\topt_->progressive = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\topt_->progressive = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t} callback( &opt );\n\t\ttTJSVariantClosure clo(&callback, NULL);\n\t\tmeta->EnumMembers(TJS_IGNOREPROP, &clo, meta);\n\t}\n\n\ttjs_uint height = image->GetHeight();\n\ttjs_uint width = image->GetWidth();\n\tif( height == 0 || width == 0 ) TVPThrowInternalError;\n\n\t// open stream\n\ttTJSBinaryStream *stream = dst;\n\tstruct jpeg_compress_struct cinfo;\n\n\tsize_t buff_size = width*height*sizeof(tjs_uint32);\n\ttjs_uint8* dest_buf = new tjs_uint8[buff_size];\n\ttry {\n\t\tTVPClearGraphicCache();\n\n\t\tstruct jpeg_error_mgr jerr;\n\t\tcinfo.err = jpeg_std_error( &jerr );\n\t\tjerr.error_exit = my_error_exit;\n\t\tjerr.output_message = my_output_message;\n\t\tjerr.reset_error_mgr = my_reset_error_mgr;\n\t\t// emit_message, format_message �̓f�t�H���g�̂��g��\n\n\t\tjpeg_create_compress( &cinfo );\n\t\t\n\t\tint num_write_bytes = 0; //size of jpeg after compression\n\t\tJOCTET *jpgbuff = (JOCTET*)dest_buf; //JOCTET pointer to buffer\n\t\tJPEG_write_stream( &cinfo, jpgbuff , (int)buff_size, &num_write_bytes, stream );\n\n\t\tcinfo.image_width = width;\n\t\tcinfo.image_height = height;\n\t\tcinfo.input_components = 4;\n\t\tcinfo.in_color_space = JCS_EXT_RGBX;//JCS_RGB;\n\t\tcinfo.dct_method = opt.dct_method; //JDCT_ISLOW;\n\t\tjpeg_set_defaults( &cinfo );\n\t\tjpeg_set_quality( &cinfo, opt.quality, TRUE );\n\t\tif( opt.subsampling == 2 ) {\t// 444\n\t\t\tcinfo.comp_info[0].h_samp_factor = 1;\n\t\t\tcinfo.comp_info[0].v_samp_factor = 1;\n\t\t\tif( cinfo.num_components > 3 ) {\n\t\t\t\tcinfo.comp_info[3].h_samp_factor = 1;\n\t\t\t\tcinfo.comp_info[3].v_samp_factor = 1;\n\t\t\t}\n\t\t} else if( opt.subsampling == 1 ) {\t// 422\n\t\t\tcinfo.comp_info[0].h_samp_factor = 2;\n\t\t\tcinfo.comp_info[0].v_samp_factor = 1;\n\t\t\tif( cinfo.num_components > 3 ) {\n\t\t\t\tcinfo.comp_info[3].h_samp_factor = 2;\n\t\t\t\tcinfo.comp_info[3].v_samp_factor = 1;\n\t\t\t}\n\t\t} else {\t// 420\n\t\t\tcinfo.comp_info[0].h_samp_factor = 2;\n\t\t\tcinfo.comp_info[0].v_samp_factor = 2;\n\t\t\tif( cinfo.num_components > 3 ) {\n\t\t\t\tcinfo.comp_info[3].h_samp_factor = 2;\n\t\t\t\tcinfo.comp_info[3].v_samp_factor = 2;\n\t\t\t}\n\t\t}\n\t\tcinfo.comp_info[1].h_samp_factor=1;\n\t\tcinfo.comp_info[2].h_samp_factor=1;\n\t\tcinfo.comp_info[1].v_samp_factor=1;\n\t\tcinfo.comp_info[2].v_samp_factor=1;\n\t\tcinfo.optimize_coding = TRUE;\n\t\tif( opt.progressive ) {\n\t\t\tjpeg_simple_progression( &cinfo );\t// set progressive, may be more compression\n\t\t}\n\t\tjpeg_start_compress( &cinfo, TRUE );\n\n\t\twhile( cinfo.next_scanline < cinfo.image_height ) {\n\t\t\tJSAMPROW row_pointer[1];\n\t\t\tint y = cinfo.next_scanline;\n\t\t\trow_pointer[0] = reinterpret_cast<JSAMPROW>(const_cast<void*>(image->GetScanLine(y)));\n\t\t\tjpeg_write_scanlines( &cinfo, row_pointer, 1 );\n\t\t}\n\t\tjpeg_finish_compress(&cinfo);\n\t\tjpeg_destroy_compress(&cinfo);\n\t\tstream->WriteBuffer( dest_buf, num_write_bytes );\n\t} catch(...) {\n\t\tjpeg_destroy_compress(&cinfo);\n\t\tdelete[] dest_buf;\n\t\tthrow;\n\t}\n\tdelete[] dest_buf;\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadHeaderJPG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tjpeg_decompress_struct cinfo;\n\tmy_error_mgr jerr;\n\n\t// error handling\n\tcinfo.err = jpeg_std_error(&jerr.pub);\n\tjerr.pub.error_exit = my_error_exit;\n\tjerr.pub.emit_message = my_emit_message;\n\tjerr.pub.output_message = my_output_message;\n\tjerr.pub.format_message = my_format_message;\n\tjerr.pub.reset_error_mgr = my_reset_error_mgr;\n\n\t// create decompress object\n\tjpeg_create_decompress(&cinfo);\n\n\t// set data source\n\tjpeg_TStream_src(&cinfo, src);\n\n\t// read the header\n\tjpeg_read_header(&cinfo, TRUE);\n\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val((tjs_int64)cinfo.image_width);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\tval = tTJSVariant((tjs_int64)cinfo.image_height);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic));\n\tval = tTJSVariant((tjs_int64)24);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic));\n\n\tjpeg_destroy_decompress(&cinfo);\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/LoadJXR.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tvpgl.h\"\n\n#include \"DebugIntf.h\"\n#include \"tjsDictionary.h\"\n#include \"ScriptMgnIntf.h\"\n\nstatic tjs_uint32 GetStride( const tjs_uint32 width, const tjs_uint32 bitCount) {\n\tconst tjs_uint32 byteCount = bitCount / 8;\n\tconst tjs_uint32 stride = (width * byteCount + 3) & ~3;\n\treturn stride;\n}\n\nbool TVPAcceptSaveAsJXR(void* formatdata, const ttstr & type, class iTJSDispatch2** dic ) {\n\tbool result = false;\n\tif( type.StartsWith(TJS_W(\"jxr\")) ) result = true;\n\telse if( type == TJS_W(\".jxr\") ) result = true;\n\tif( result && dic ) {\n\t\t// quality 1 - 255\n\t\t// alphaQuality 1 - 255\n\t\t// subsampling : select 0 : 4:0:0, 1 : 4:2:0, 2 : 4:2:2, 3 : 4:4:4\n\t\t// alpha : bool\n\t\t/*\n\t\t%[\n\t\t\"quality\" => %[\"type\" => \"range\", \"min\" => 1, \"max\" => 255, \"desc\" => \"1 is lossless, 2 - 255 lossy : 2 is high quality, 255 is low quality\", \"default\"=>1 ]\n\t\t\"alphaQuality\" => %[\"type\" => \"range\", \"min\" => 1, \"max\" => 255, \"desc\" => \"1 is lossless, 2 - 255 lossy : 2 is high quality, 255 is low quality\", \"default\"=>1 ]\n\t\t\"subsampling\" => %[\"type\" => \"select\", \"items\" => [\"4:0:0\",\"4:2:0\",\"4:2:2\",\"4:4:4\"], \"desc\"=>\"subsampling\", \"default\"=>1 ]\n\t\t\"alpha\" => %[\"type\" => \"boolean\", \"default\"=>1]\n\t\t]\n\t\t*/\n\t\ttTJSVariant result;\n\t\tTVPExecuteExpression(\n\t\t\tTJS_W(\"(const)%[\")\n\t\t\tTJS_W(\"\\\"quality\\\"=>(const)%[\\\"type\\\"=>\\\"range\\\",\\\"min\\\"=>1,\\\"max\\\"=>255,\\\"desc\\\"=>\\\"1 is lossless, 2 - 255 lossy : 2 is high quality, 255 is low quality\\\",\\\"default\\\"=>1],\")\n\t\t\tTJS_W(\"\\\"alphaQuality\\\"=>(const)%[\\\"type\\\"=>\\\"range\\\",\\\"min\\\"=>1,\\\"max\\\"=>255,\\\"desc\\\"=>\\\"1 is lossless, 2 - 255 lossy : 2 is high quality, 255 is low quality\\\",\\\"default\\\"=>1],\")\n\t\t\tTJS_W(\"\\\"subsampling\\\"=>(const)%[\\\"type\\\"=>\\\"select\\\",\\\"items\\\"=>(const)[\\\"4:0:0\\\",\\\"4:2:0\\\",\\\"4:2:2\\\",\\\"4:4:4\\\"],\\\"desc\\\"=>\\\"subsampling\\\",\\\"default\\\"=>1],\")\n\t\t\tTJS_W(\"\\\"alpha\\\"=>(const)%[\\\"type\\\"=>\\\"boolean\\\",\\\"desc\\\"=>\\\"alpha channel\\\",\\\"default\\\"=>true]\")\n\t\t\tTJS_W(\"]\"),\n\t\t\tNULL, &result );\n\t\tif( result.Type() == tvtObject ) {\n\t\t\t*dic = result.AsObject();\n\t\t}\n\t}\n\treturn result;\n}\n// jxrlib go[Wł͏݂܂łĂȂ\n//#define TVP_JPEG_XR_USE_WIN_CODEC\n#if defined( WIN32 ) && defined( TVP_JPEG_XR_USE_WIN_CODEC )\n// Windows gݍ݋@\\ JPEG XR Jꍇ͂\n#include <wincodec.h>\n#include <wincodecsdk.h>\n#include <atlbase.h>\n#include <comutil.h>\n#include \"StorageImpl.h\"\n#pragma comment(lib, \"WindowsCodecs.lib\")\n#ifdef _DEBUG\n#pragma comment(lib, \"comsuppwd.lib\")\n#else\n#pragma comment(lib, \"comsuppw.lib\")\n#endif\n\n\nvoid TVPLoadJXR(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\tCoInitialize(NULL);\n\t{\n\t\ttTVPIStreamAdapter* s = new tTVPIStreamAdapter( src );\n\t\tCComPtr<tTVPIStreamAdapter> stream( s );\n\t\ts->Release();\n\t\t{\n\t\t\tCComPtr<IWICBitmapDecoder> decoder;\n\t\t\tHRESULT hr = decoder.CoCreateInstance(CLSID_WICWmpDecoder);\n\t\t\thr = decoder->Initialize( stream, WICDecodeMetadataCacheOnDemand);\n\t\t\tUINT frameCount = 0;\n\t\t\thr = decoder->GetFrameCount(&frameCount);\n\t\t\tfor( UINT index = 0; index < frameCount; ++index ) {\n\t\t\t\tCComPtr<IWICBitmapFrameDecode> frame;\n\t\t\t\thr = decoder->GetFrame(index, &frame);\n\t\t\t\tUINT width = 0;\n\t\t\t\tUINT height = 0;\n\t\t\t\tGUID pixelFormat = { 0 };\n\t\t\t\thr = frame->GetPixelFormat(&pixelFormat);\n\t\t\t\thr = frame->GetSize(&width, &height);\n\t\t\t\tconst UINT stride = GetStride(width, 32);\n#ifdef _DEBUG\n\t\t\t\tstd::vector<tjs_uint8> buff(stride*height*sizeof(tjs_uint8));\n#else\n\t\t\t\tstd::vector<tjs_uint8> buff;\n\t\t\t\tbuff.reserve(stride*height*sizeof(tjs_uint8));\n#endif\n\t\t\t\tsizecallback(callbackdata, width, height);\n\t\t\t\tWICRect rect = {0, 0, width, height};\n\t\t\t\tif( !IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppBGRA) ) {\n\t\t\t\t\tCComPtr<IWICFormatConverter> converter;\n\t\t\t\t\tCComPtr<IWICImagingFactory> wicFactory;\n\t\t\t\t\thr = wicFactory.CoCreateInstance( CLSID_WICImagingFactory );\n\t\t\t\t\twicFactory->CreateFormatConverter(&converter);\n\t\t\t\t\tconverter->Initialize(frame, GUID_WICPixelFormat32bppBGRA,WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);\n\t\t\t\t\thr = converter->CopyPixels( &rect, stride, stride*height, (BYTE*)&buff[0] );\n\t\t\t\t} else {\n\t\t\t\t\thr = frame->CopyPixels( &rect, stride, stride*height, (BYTE*)&buff[0] );\n\t\t\t\t}\n\t\t\t\tint offset = 0;\n\t\t\t\tfor( UINT i = 0; i < height; i++) {\n\t\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\t\tmemcpy( scanline, &buff[offset], width*sizeof(tjs_uint32));\n\t\t\t\t\toffset += stride;\n\t\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t\t} \n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif( stream ) stream->ClearStream();\n\t}\n\tCoUninitialize();\n}\n\nvoid TVPSaveAsJXR(void* formatdata, tTJSBinaryStream* dst, const class iTVPBaseBitmap* image, const ttstr & mode, class iTJSDispatch2* meta )\n{\n\tCoInitialize(NULL);\n\t{\n\t\ttTVPIStreamAdapter* s = new tTVPIStreamAdapter( dst );\n\t\tCComPtr<tTVPIStreamAdapter> stream( s );\n\t\ts->Release();\n\t\t{\n\t\t\tCComPtr<IWICBitmapEncoder> encoder;\n\t\t\tHRESULT hr = encoder.CoCreateInstance(CLSID_WICWmpEncoder);\n\t\t\tif( SUCCEEDED(hr) ) hr = encoder->Initialize(stream, WICBitmapEncoderNoCache);\n\t\t\tCComPtr<IPropertyBag2> property;\n\t\t\tCComPtr<IWICBitmapFrameEncode> frame;\n\t\t\tif( SUCCEEDED(hr) ) hr = encoder->CreateNewFrame( &frame, &property );\n\t\t\tWICPixelFormatGUID format = GUID_WICPixelFormat32bppBGRA;\n\t\t\tif( SUCCEEDED(hr) && meta ) {\n\t\t\t\tPROPBAG2 option = { 0 };\n\t\t\t\toption.pstrName = L\"UseCodecOptions\";\t// ڍׂȃIvVw肷\n\t\t\t\t_variant_t varValue( true );\n\t\t\t\thr = property->Write( 1, &option, &varValue );\n\n\t\t\t\t// EnumCallback găvpeBݒ肷\n\t\t\t\tstruct MetaDictionaryEnumCallback : public tTJSDispatch {\n\t\t\t\t\tIPropertyBag2 *prop_;\n\t\t\t\t\tWICPixelFormatGUID *format_;\n\t\t\t\t\tMetaDictionaryEnumCallback( IPropertyBag2 *prop, WICPixelFormatGUID* format ) : prop_(prop), format_(format) {}\n\t\t\t\t\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\t\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\t\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis) { // called from tTJSCustomObject::EnumMembers\n\t\t\t\t\t\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\t\t\t\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\t\t\t\tif(flags & TJS_HIDDENMEMBER) {\t// hidden members are not processed\n\t\t\t\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\t\t\t\treturn TJS_S_OK;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tHRESULT hr;\n\t\t\t\t\t\t// push items\n\t\t\t\t\t\tttstr value = *param[0];\n\t\t\t\t\t\tif( value == TJS_W(\"quality\") ) {\n\t\t\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\t\t\tv = v < 1 ? 1 : v > 255 ? 255 : v;\n\t\t\t\t\t\t\tUCHAR q = (UCHAR)v;\n\t\t\t\t\t\t\tPROPBAG2 option = { 0 };\n\t\t\t\t\t\t\toption.pstrName = L\"Quality\";\t//  1 : lossless mode, 2 - 255 : l掿\n\t\t\t\t\t\t\t_variant_t varValue( q );\n\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &varValue );\n\t\t\t\t\t\t\tif( q == 1 ) {\n\t\t\t\t\t\t\t\toption.pstrName = L\"Lossless\";\t// XX[h\n\t\t\t\t\t\t\t\t_variant_t var( VARIANT_TRUE );\n\t\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &var );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if( value == TJS_W(\"alphaQuality\") ) {\n\t\t\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\t\t\tv = v < 1 ? 1 : v > 255 ? 255 : v;\n\t\t\t\t\t\t\tUCHAR q = (UCHAR)v;\n\t\t\t\t\t\t\tPROPBAG2 option = { 0 };\n\t\t\t\t\t\t\toption.pstrName = L\"InterleavedAlpha\";\n\t\t\t\t\t\t\tif( q == 1 ) {\n\t\t\t\t\t\t\t\t_variant_t varValue( VARIANT_TRUE );\n\t\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &varValue );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t_variant_t varValue( VARIANT_FALSE );\n\t\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &varValue );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toption.pstrName = L\"AlphaQuality\";\t//  1 : lossless mode, 2 - 255 : l掿\n\t\t\t\t\t\t\t_variant_t varValue( q );\n\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &varValue );\n\t\t\t\t\t\t} else if( value == TJS_W(\"subsampling\") ) {\n\t\t\t\t\t\t\t// 0 : 4:0:0, 1 : 4:2:0, 2 : 4:2:2, 3 : 4:4:4\n\t\t\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\t\t\tv = v < 0 ? 0 : v > 3 ? 3 : v;\n\t\t\t\t\t\t\tUCHAR q = (UCHAR)v;\n\t\t\t\t\t\t\tPROPBAG2 option = { 0 };\n\t\t\t\t\t\t\toption.pstrName = L\"Subsampling\";\n\t\t\t\t\t\t\t_variant_t varValue( q );\n\t\t\t\t\t\t\thr = prop_->Write( 1, &option, &varValue );\n\t\t\t\t\t\t} else if( value == TJS_W(\"alpha\") ) {\n\t\t\t\t\t\t\t// true or false\n\t\t\t\t\t\t\ttjs_int64 v = param[2]->AsInteger();\n\t\t\t\t\t\t\tif( v ) {\n\t\t\t\t\t\t\t\t*format_ = GUID_WICPixelFormat32bppBGRA;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t*format_ = GUID_WICPixelFormat32bppBGR;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\t\t\treturn TJS_S_OK;\n\t\t\t\t\t}\n\t\t\t\t} callback( property, &format );\n\t\t\t\tmeta->EnumMembers(TJS_IGNOREPROP, &tTJSVariantClosure(&callback, NULL), meta);\n\t\t\t}\n\n\t\t\tif( SUCCEEDED(hr) ) hr = frame->Initialize( property );\n\t\t\tconst UINT width = image->GetWidth();\n\t\t\tconst UINT height = image->GetHeight();\n\t\t\tif( SUCCEEDED(hr) ) hr = frame->SetSize( width, height );\n\t\t\tif( SUCCEEDED(hr) ) hr = frame->SetPixelFormat(&format);\n\t\t\tconst UINT stride = width * sizeof(tjs_uint32);\n\t\t\tconst UINT buffersize = stride * height;\n\t\t\tif( SUCCEEDED(hr) ) {\n#ifdef _DEBUG\n\t\t\t\tstd::vector<tjs_uint8> buff(buffersize);\n#else\n\t\t\t\tstd::vector<tjs_uint8> buff;\n\t\t\t\tbuff.reserve(buffersize);\n#endif\n\t\t\t\tfor( UINT i = 0; i < height; i++ ) {\n\t\t\t\t\tmemcpy( &buff[i*stride], image->GetScanLine(i), stride );\n\t\t\t\t}\n\t\t\t\thr = frame->WritePixels( height, stride, buffersize, &buff[0] );\n\t\t\t}\n\t\t\tif( SUCCEEDED(hr) ) hr = frame->Commit();\n\t\t\tif( SUCCEEDED(hr) ) hr = encoder->Commit();\n\t\t}\n\t\tif( stream ) stream->ClearStream();\n\t}\n\tCoUninitialize();\n}\n\nvoid TVPLoadHeaderJXR(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tCoInitialize(NULL);\n\t{\n\t\ttTVPIStreamAdapter* s = new tTVPIStreamAdapter( src );\n\t\tCComPtr<tTVPIStreamAdapter> stream( s );\n\t\ts->Release();\n\t\tCComPtr<IWICBitmapDecoder> decoder;\n\t\tHRESULT hr = decoder.CoCreateInstance(CLSID_WICWmpDecoder);\n\t\tif( SUCCEEDED(hr) ) hr = decoder->Initialize( stream, WICDecodeMetadataCacheOnDemand);\n\t\tUINT frameCount = 0;\n\t\tif( SUCCEEDED(hr) ) hr = decoder->GetFrameCount(&frameCount);\n\t\tif( SUCCEEDED(hr) )\n\t\t{\n\t\t\tfor( UINT index = 0; index < frameCount; ++index ) {\n\t\t\t\tUINT width = 0;\n\t\t\t\tUINT height = 0;\n\t\t\t\tGUID pixelFormat = { 0 };\n\t\t\t\tdouble dpiX = 0.0;\n\t\t\t\tdouble dpiY = 0.0;\n\t\t\t\tCComPtr<IWICBitmapFrameDecode> frame;\n\t\t\t\tif( SUCCEEDED(hr) ) hr = decoder->GetFrame(index, &frame);\n\t\t\t\tif( SUCCEEDED(hr) ) hr = frame->GetPixelFormat(&pixelFormat);\n\t\t\t\tif( SUCCEEDED(hr) ) hr = frame->GetSize(&width, &height);\n\t\t\t\tif( SUCCEEDED(hr) ) hr = frame->GetResolution( &dpiX, &dpiY );\n\t\t\t\tif( SUCCEEDED(hr) )\n\t\t\t\t{\n\t\t\t\t\t*dic = TJSCreateDictionaryObject();\n\t\t\t\t\ttTJSVariant val((tjs_int64)width);\n\t\t\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\t\t\t\t\tval = tTJSVariant((tjs_int64)height);\n\t\t\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic) );\n\t\t\t\t\tval = tTJSVariant(dpiX);\n\t\t\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"dpi x\"), 0, &val, (*dic) );\n\t\t\t\t\tval = tTJSVariant(dpiY);\n\t\t\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"dpi y\"), 0, &val, (*dic) );\n\t\t\t\t\tif( IsEqualGUID( pixelFormat, GUID_WICPixelFormatBlackWhite) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"BlackWhite\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat8bppGray) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"8bppGray\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat16bppBGR555) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"16bppBGR555\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat16bppGray) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"16bppGray\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat24bppBGR) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"24bppBGR\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat24bppRGB) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"24bppRGB\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppBGR) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppBGR\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppBGRA) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppBGRA\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat48bppRGBFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"48bppRGBFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat16bppGrayFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"16bppGrayFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppBGR101010) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppBGR101010\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat48bppRGB) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"48bppRGB\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppRGBA) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppRGBA\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat96bppRGBFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"96bppRGBFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat96bppRGBFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"96bppRGBFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat128bppRGBFloat) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"128bppRGBFloat\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppCMYK) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppCMYK\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppRGBAFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppRGBAFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat128bppRGBAFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"128bppRGBAFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppCMYK) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppCMYK\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat24bpp3Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"24bpp3Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bpp4Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bpp4Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat40bpp5Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"40bpp5Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat48bpp6Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"48bpp6Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat56bpp7Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"56bpp7Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bpp8Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bpp8Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat48bpp3Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"48bpp3Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bpp4Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bpp4Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat80bpp5Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"80bpp5Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat96bpp6Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"96bpp6Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat112bpp7Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"112bpp7Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat128bpp8Channels) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"128bpp8Channels\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat40bppCMYKAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"40bppCMYKAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat80bppCMYKAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"80bppCMYKAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bpp3ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bpp3ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bpp7ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bpp7ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat72bpp8ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"72bpp8ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bpp3ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bpp3ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat80bpp4ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"80bpp4ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat96bpp5ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"96bpp5ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat112bpp6ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"112bpp6ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat128bpp7ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"128bpp7ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat144bpp8ChannelsAlpha) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"144bpp8ChannelsAlpha\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppRGBAHalf) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppRGBAHalf\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat48bppRGBHalf) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"48bppRGBHalf\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppRGBE) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppRGBE\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat16bppGrayHalf) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"16bppGrayHalf\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat32bppGrayFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"32bppGrayFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppRGBFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppRGBFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat128bppRGBFixedPoint) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"128bppRGBFixedPoint\"));\n\t\t\t\t\t} else if( IsEqualGUID( pixelFormat, GUID_WICPixelFormat64bppRGBHalf) ) {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"64bppRGBHalf\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tval = tTJSVariant(TJS_W(\"unknown\"));\n\t\t\t\t\t}\n\t\t\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"pixelformat\"), 0, &val, (*dic) );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif( stream ) stream->ClearStream();\n\t}\n\tCoUninitialize();\n}\n#else\n\n#include \"JXRGlue.h\"\n\n/*\njxrlibœǂݍ݂sꍇ\nexternal/jxrlib/image/vc11projects/CommonLib_vc11.vcxproj\nexternal/jxrlib/image/vc11projects/DecodeLib_vc11.vcxproj\nexternal/jxrlib/image/vc11projects/EncodeLib_vc11.vcxproj\nexternal/jxrlib/jxrgluelib/JXRGlueLib_vc11.vcxproj\n\\[Vɉărh邱\n*/\n#if defined( WIN32 )\n#ifdef _DEBUG\n// #pragma comment(lib, \"JXRCommonLib_d.lib\")\n// #pragma comment(lib, \"JXRDecodeLib_d.lib\")\n// #pragma comment(lib, \"JXREncodeLib_d.lib\")\n#pragma comment(lib, \"JXRGlueLib_d.lib\")\n#else\n#pragma comment(lib, \"JXRCommonLib.lib\")\n#pragma comment(lib, \"JXRDecodeLib.lib\")\n#pragma comment(lib, \"JXREncodeLib.lib\")\n#pragma comment(lib, \"JXRGlueLib.lib\")\n#endif\n#endif\n\nstatic ERR JXR_close( WMPStream** ppWS ) {\n\t/* Ȃ */\n\treturn WMP_errSuccess;\n}\nstatic Bool JXR_EOS(struct WMPStream* pWS) {\n\ttTJSBinaryStream* src = ((tTJSBinaryStream*)(pWS->state.pvObj));\n\treturn src->GetPosition() >= src->GetSize();\n}\nstatic ERR JXR_read(struct WMPStream* pWS, void* pv, size_t cb) {\n\ttTJSBinaryStream* src = ((tTJSBinaryStream*)(pWS->state.pvObj));\n\ttjs_uint size = src->Read( pv, (tjs_uint)cb );\n\treturn size == cb ? WMP_errSuccess : WMP_errFileIO;\n}\nstatic ERR JXR_write(struct WMPStream* pWS, const void* pv, size_t cb) {\n\tERR err = WMP_errSuccess;\n\tif( 0 != cb ) {\n\t\ttTJSBinaryStream* src = ((tTJSBinaryStream*)(pWS->state.pvObj));\n\t\ttjs_uint size = src->Write( pv, (tjs_uint)cb );\n\t\terr = size == cb ? WMP_errSuccess : WMP_errFileIO;\n\t}\n\treturn err;\n}\nstatic ERR JXR_set_pos( struct WMPStream* pWS, size_t offPos ) {\n\ttTJSBinaryStream* src = ((tTJSBinaryStream*)(pWS->state.pvObj));\n\ttjs_uint64 pos = src->Seek(  offPos, TJS_BS_SEEK_SET );\n\treturn pos == offPos ? WMP_errSuccess : WMP_errFileIO;\n}\nstatic ERR JXR_get_pos( struct WMPStream* pWS, size_t* poffPos ) {\n\ttTJSBinaryStream* src = ((tTJSBinaryStream*)(pWS->state.pvObj));\n\t*poffPos = (size_t)src->GetPosition();\n\treturn WMP_errSuccess;\n}\n\n\n#define SAFE_CALL( func ) if( Failed(err = (func)) ) { TVPThrowExceptionMessage( TJS_W(\"JPEG XR read error/%1\"), (tjs_int)err ); }\n//---------------------------------------------------------------------------\nvoid TVPLoadJXR(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\tif( glmNormal != mode ) {\n\t\t// not supprted yet.\n\t\tTVPThrowExceptionMessage( TJS_W(\"JPEG XR read error/%1\"), TJS_W(\"not supprted yet.\") );\n\t}\n\t\n\t//PKFactory* pFactory = NULL;\n\tPKImageDecode* pDecoder = NULL;\n\t//PKFormatConverter* pConverter = NULL;\n\tWMPStream* pStream = NULL;\n\t//PKCodecFactory* pCodecFactory = NULL;\n\ttry {\n\t\tERR err;\n\t\t//SAFE_CALL( PKCreateFactory(&pFactory, PK_SDK_VERSION) );\n\t\t//SAFE_CALL( PKCreateCodecFactory(&pCodecFactory, WMP_SDK_VERSION) );\n\t\t//SAFE_CALL(pCodecFactory->CreateDecoderFromFile(\"test.jxr\", &pDecoder));\n\n\t\tconst PKIID* pIID = NULL;\n\t\tSAFE_CALL( GetImageDecodeIID(\".jxr\", &pIID) );\n\t\t// create stream\n\t\tpStream = (WMPStream*)calloc(1, sizeof(WMPStream));\n\t\tpStream->state.pvObj = (void*)src;\n\t\tpStream->Close = JXR_close;\n\t\tpStream->EOS = JXR_EOS;\n\t\tpStream->Read = JXR_read;\n\t\tpStream->Write = JXR_write;\n\t\tpStream->SetPos = JXR_set_pos;\n\t\tpStream->GetPos = JXR_get_pos;\n\t\t// Create decoder\n\t\tSAFE_CALL( PKCodecFactory_CreateCodec(pIID, (void **)&pDecoder) );\n\t\t// attach stream to decoder\n\t\tSAFE_CALL( pDecoder->Initialize(pDecoder, pStream) );\n\t\tpDecoder->fStreamOwner = !0;\n\n\t\tPKPixelFormatGUID srcFormat;\n\t\tpDecoder->GetPixelFormat( pDecoder, &srcFormat );\n\t\tPKPixelInfo PI;\n\t\tPI.pGUIDPixFmt = &srcFormat;\n\t\tPixelFormatLookup(&PI, LOOKUP_FORWARD);\n\n\t\tpDecoder->WMP.wmiSCP.bfBitstreamFormat = SPATIAL;\n        if(!!(PI.grBit & PK_pixfmtHasAlpha))\n            pDecoder->WMP.wmiSCP.uAlphaMode = 2;\n        else\n            pDecoder->WMP.wmiSCP.uAlphaMode = 0;\n\t\tpDecoder->WMP.wmiSCP.sbSubband = SB_ALL;\n\t\tpDecoder->WMP.bIgnoreOverlap = FALSE;\n\t\tpDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat;\n\t\tpDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth;\n\t\tpDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;\n\t\tpDecoder->WMP.wmiI.cThumbnailWidth = pDecoder->WMP.wmiI.cWidth;\n\t\tpDecoder->WMP.wmiI.cThumbnailHeight = pDecoder->WMP.wmiI.cHeight;\n\t\tpDecoder->WMP.wmiI.bSkipFlexbits = FALSE;\n\t\tpDecoder->WMP.wmiI.cROILeftX = 0;\n\t\tpDecoder->WMP.wmiI.cROITopY = 0;\n\t\tpDecoder->WMP.wmiI.cROIWidth = pDecoder->WMP.wmiI.cThumbnailWidth;\n\t\tpDecoder->WMP.wmiI.cROIHeight = pDecoder->WMP.wmiI.cThumbnailHeight;\n\t\tpDecoder->WMP.wmiI.oOrientation = O_NONE;\n\t\tpDecoder->WMP.wmiI.cPostProcStrength = 0;\n\t\tpDecoder->WMP.wmiSCP.bVerbose = FALSE;\n\n\t\tint width = 0;\n\t\tint height = 0;\n\t\tpDecoder->GetSize( pDecoder, &width, &height );\n\t\tif( width == 0 || height == 0 ) {\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"JPEG XR read error/%1\"), TJS_W(\"width or height is zero.\") );\n\t\t}\n\t\tsizecallback(callbackdata, width, height, pDecoder->WMP.wmiSCP.uAlphaMode ? gpfRGBA : gpfRGB);\n\t\tconst tjs_uint32 stride = GetStride( (tjs_uint32)width, (tjs_uint32)32 );\n\t\tPKRect rect = {0, 0, width, height};\n#ifdef _DEBUG\n\t\tstd::vector<tjs_uint8> buff(stride*height*sizeof(tjs_uint8));\n#else\n\t\tstd::vector<tjs_uint8> buff;\n\t\tbuff.reserve(stride*height*sizeof(tjs_uint8));\n#endif\n\t\t// rect 1Cw肵ăfR[h@jxrlibł͂܂Ȃlq\n\t\tint offset = 0;\n\t\tif (!IsEqualGUID(srcFormat, GUID_PKPixelFormat32bppRGBA)) {\n\t\t\tif( IsEqualGUID( srcFormat, GUID_PKPixelFormat24bppRGB ) ) {\n\t\t\t\tpDecoder->Copy( pDecoder, &rect, (U8*)&buff[0], stride );\n\t\t\t\tfor( int i = 0; i < height; i++) {\n\t\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\t\ttjs_uint8* d = (tjs_uint8*)scanline;\n\t\t\t\t\ttjs_uint8* s = (tjs_uint8*)&buff[offset];\n\t\t\t\t\tfor( int x = 0; x < width; x++ ) {\n\t\t\t\t\t\td[0] = s[2];\n\t\t\t\t\t\td[1] = s[1];\n\t\t\t\t\t\td[2] = s[0];\n\t\t\t\t\t\td[3] = 0xff;\n\t\t\t\t\t\td+=4;\n\t\t\t\t\t\ts+=3;\n\t\t\t\t\t}\n\t\t\t\t\toffset += stride;\n\t\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tTVPThrowExceptionMessage( TJS_W(\"JPEG XR read error/%1\"), TJS_W(\"Not supported this file format yet.\") );\n\t\t\t}\n\t\t\t/*\n\t\t\tConverter ͂ǂ̂ŎgȂB\n\t\t\tSAFE_CALL( pCodecFactory->CreateFormatConverter(&pConverter) );\n\t\t\tSAFE_CALL( pConverter->Initialize(pConverter, pDecoder, NULL, GUID_PKPixelFormat32bppPBGRA) );\n\t\t\tpConverter->Copy( pConverter, &rect, (U8*)&buff[0], width*sizeof(int));\n\t\t\t*/\n\t\t} else {\n\t\t\t// At@`lĂ鎞[NĂ(jxrlib)\n\t\t\tpDecoder->Copy( pDecoder, &rect, (U8*)&buff[0], stride );\n\t\t\tfor( int i = 0; i < height; i++) {\n\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\tmemcpy( scanline, &buff[offset], width*sizeof(tjs_uint32));\n\t\t\t\toffset += stride;\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t} \n\t\t}\n\t\t//if( pConverter ) pConverter->Release(&pConverter);\n\t\tif( pDecoder ) pDecoder->Release(&pDecoder);\n\t\t//if( pCodecFactory ) pCodecFactory->Release(&pCodecFactory);\n\t\tif( pStream ) free( pStream );\n\t} catch(...) {\n\t\t//if( pConverter ) pConverter->Release(&pConverter);\n\t\tif( pDecoder ) pDecoder->Release(&pDecoder);\n\t\t//if( pCodecFactory ) pCodecFactory->Release(&pCodecFactory);\n\t\tif( pStream ) free( pStream );\n\t\tthrow;\n\t}\n}\n\n// Y, U, V, YHP, UHP, VHP\nstatic int DPK_QPS_420[12][6] = {      // for 8 bit only\n    { 66, 65, 70, 72, 72, 77 },\n    { 59, 58, 63, 64, 63, 68 },\n    { 52, 51, 57, 56, 56, 61 },\n    { 48, 48, 54, 51, 50, 55 },\n    { 43, 44, 48, 46, 46, 49 },\n    { 37, 37, 42, 38, 38, 43 },\n    { 26, 28, 31, 27, 28, 31 },\n    { 16, 17, 22, 16, 17, 21 },\n    { 10, 11, 13, 10, 10, 13 },\n    {  5,  5,  6,  5,  5,  6 },\n    {  2,  2,  3,  2,  2,  2 }\n};\nstatic int DPK_QPS_8[12][6] = {\n    { 67, 79, 86, 72, 90, 98 },\n    { 59, 74, 80, 64, 83, 89 },\n    { 53, 68, 75, 57, 76, 83 },\n    { 49, 64, 71, 53, 70, 77 },\n    { 45, 60, 67, 48, 67, 74 },\n    { 40, 56, 62, 42, 59, 66 },\n    { 33, 49, 55, 35, 51, 58 },\n    { 27, 44, 49, 28, 45, 50 },\n    { 20, 36, 42, 20, 38, 44 },\n    { 13, 27, 34, 13, 28, 34 },\n    {  7, 17, 21,  8, 17, 21 }, // Photoshop 100%\n    {  2,  5,  6,  2,  5,  6 }\n};\n// TODO : ȉ̏ł͂܂߂ĂȂBǂݒ肪slq\nvoid TVPSaveAsJXR(void* formatdata, tTJSBinaryStream* dst, const class iTVPBaseBitmap* image, const ttstr & mode, class iTJSDispatch2* meta )\n{\n\tPKImageEncode* pEncoder = NULL;\n\tWMPStream* pStream = NULL;\n\ttry {\n\t\tERR err;\n\n\t\tconst PKIID* pIID = NULL;\n\t\tSAFE_CALL( GetImageEncodeIID(\".jxr\", &pIID) );\n\t\t// create stream\n\t\tpStream = (WMPStream*)calloc(1, sizeof(WMPStream));\n\t\tpStream->state.pvObj = (void*)dst;\n\t\tpStream->Close = JXR_close;\n\t\tpStream->EOS = JXR_EOS;\n\t\tpStream->Read = JXR_read;\n\t\tpStream->Write = JXR_write;\n\t\tpStream->SetPos = JXR_set_pos;\n\t\tpStream->GetPos = JXR_get_pos;\n\t\t// Create encoder\n\t\tSAFE_CALL( PKCodecFactory_CreateCodec(pIID, (void **)&pEncoder) );\n\t\t\n\t\t//PKPixelInfo PI;\n\t\t//PI.pGUIDPixFmt = &GUID_PKPixelFormat32bppBGRA;\n\t\t//PixelFormatLookup(&PI, LOOKUP_FORWARD);\n\t\t\n\t\tconst tjs_uint width = image->GetWidth();\n\t\tconst tjs_uint height = image->GetHeight();\n\t\tconst tjs_uint stride = width * sizeof(tjs_uint32);\n\t\tconst tjs_uint buffersize = stride * height;\n\t\tCWMIStrCodecParam wmiSCP;\n\t\t\n\t\twmiSCP.bVerbose = FALSE;\n\t\twmiSCP.cfColorFormat = YUV_444;\t// Y_ONLY / YUV_420 / YUV_422 / YUV_444\n\t\twmiSCP.bdBitDepth = BD_SHORT; // BD_LONG;\n\t\t//wmiSCP.bfBitstreamFormat = SPATIAL;\n\t\twmiSCP.bfBitstreamFormat = FREQUENCY;\n\t\t//wmiSCP.uAlphaMode = 2;\t// alpha + color\n\t\twmiSCP.uAlphaMode = 0;\t// color\n\n\t\twmiSCP.bProgressiveMode = TRUE;\n\t\twmiSCP.olOverlap = OL_ONE;\n\t\twmiSCP.cNumOfSliceMinus1H = wmiSCP.cNumOfSliceMinus1V = 0;\n\t\twmiSCP.sbSubband = SB_ALL;\n\n\t\twmiSCP.uiDefaultQPIndex = 1;\n\t\twmiSCP.uiDefaultQPIndexAlpha = 1;\n\t\t\n\t\tU32 uTileY = 1 * MB_HEIGHT_PIXEL;\n        wmiSCP.cNumOfSliceMinus1H = (U32)height < (uTileY >> 1) ? 0 : (height + (uTileY >> 1)) / uTileY - 1;\n\t\tU32 uTileX = 1 * MB_HEIGHT_PIXEL;\n\t\twmiSCP.cNumOfSliceMinus1V = (U32)width < (uTileX >> 1) ? 0 : (width + (uTileX >> 1)) / uTileX - 1;\n\n\t\t// attach stream to encoder\n\t\tSAFE_CALL( pEncoder->Initialize(pEncoder, pStream, &wmiSCP, sizeof(wmiSCP)) );\n\t\t\n\t\t/*\n\t\tfloat quality = 0.99f;\n\t\tint qi;\n\t\tfloat qf;\n\t\tqi = (int) (10.f * quality);\n        qf = 10.f * quality - (float) qi;\n\t\tint* pQPs = (pEncoder->WMP.wmiSCP.cfColorFormat == YUV_420 || pEncoder->WMP.wmiSCP.cfColorFormat == YUV_422) ? DPK_QPS_420[qi] : DPK_QPS_8[qi];\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndex = (U8) (0.5f + (float) pQPs[0] * (1.f - qf) + (float) (pQPs + 6)[0] * qf);\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndexU = (U8) (0.5f + (float) pQPs[1] * (1.f - qf) + (float) (pQPs + 6)[1] * qf);\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndexV = (U8) (0.5f + (float) pQPs[2] * (1.f - qf) + (float) (pQPs + 6)[2] * qf);\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndexYHP = (U8) (0.5f + (float) pQPs[3] * (1.f - qf) + (float) (pQPs + 6)[3] * qf);\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndexUHP = (U8) (0.5f + (float) pQPs[4] * (1.f - qf) + (float) (pQPs + 6)[4] * qf);\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndexVHP = (U8) (0.5f + (float) pQPs[5] * (1.f - qf) + (float) (pQPs + 6)[5] * qf);\n\t\t*/\n\t\t\n\t\tpEncoder->WMP.wmiSCP.uiDefaultQPIndex = 1;\n\t\tif(pEncoder->WMP.wmiSCP.uAlphaMode == 2)\n\t\t\tpEncoder->WMP.wmiSCP_Alpha.uiDefaultQPIndex = wmiSCP.uiDefaultQPIndexAlpha;\n\n\t\tpEncoder->WMP.wmiSCP.olOverlap = OL_ONE;\n\n\t\t// ȉŃAt@̐ݒ肩\n\t\t// pEncoder->WMP.wmiI_Alpha;\n        // pEncoder->WMP.wmiSCP_Alpha;\n\t\t//pEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat32bppBGRA);\n\t\tpEncoder->SetPixelFormat(pEncoder, GUID_PKPixelFormat32bppRGB);\n\t\tpEncoder->SetSize(pEncoder, image->GetWidth(), image->GetHeight() );\n\t\t//Float rX = 98.0, rY = 98.0;\n\t\t//pEncoder->SetResolution(pEncoder, rX, rY);\n\t\t\n#ifdef _DEBUG\n\t\tstd::vector<tjs_uint8> buff(buffersize);\n#else\n\t\tstd::vector<tjs_uint8> buff;\n\t\tbuff.reserve(buffersize);\n#endif\n\t\tfor (tjs_uint i = 0; i < height; i++) {\n\t\t\tmemcpy( &buff[i*stride], image->GetScanLine(i), stride );\n\t\t}\n\t\tpEncoder->WritePixels( pEncoder, height, &buff[0], stride );\n\n\t\tpEncoder->Release(&pEncoder);\n\t\tif( pStream ) free( pStream );\n\t} catch(...) {\n\t\tif( pEncoder ) pEncoder->Release(&pEncoder);\n\t\tif( pStream ) free( pStream );\n\t\tthrow;\n\t}\n}\nvoid TVPLoadHeaderJXR(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tPKImageDecode* pDecoder = NULL;\n\tWMPStream* pStream = NULL;\n\ttry {\n\t\tERR err;\n\n\t\tconst PKIID* pIID = NULL;\n\t\tSAFE_CALL( GetImageDecodeIID(\".jxr\", &pIID) );\n\t\t// create stream\n\t\tpStream = (WMPStream*)calloc(1, sizeof(WMPStream));\n\t\tpStream->state.pvObj = (void*)src;\n\t\tpStream->Close = JXR_close;\n\t\tpStream->EOS = JXR_EOS;\n\t\tpStream->Read = JXR_read;\n\t\tpStream->Write = JXR_write;\n\t\tpStream->SetPos = JXR_set_pos;\n\t\tpStream->GetPos = JXR_get_pos;\n\t\t// Create decoder\n\t\tSAFE_CALL( PKCodecFactory_CreateCodec(pIID, (void **)&pDecoder) );\n\t\t// attach stream to decoder\n\t\tSAFE_CALL( pDecoder->Initialize(pDecoder, pStream) );\n\t\tpDecoder->fStreamOwner = !0;\n\n\t\tPKPixelFormatGUID srcFormat;\n\t\tpDecoder->GetPixelFormat( pDecoder, &srcFormat );\n\t\tPKPixelInfo PI;\n\t\tPI.pGUIDPixFmt = &srcFormat;\n\t\tPixelFormatLookup(&PI, LOOKUP_FORWARD);\n\n\t\tpDecoder->WMP.wmiSCP.bfBitstreamFormat = SPATIAL;\n        if(!!(PI.grBit & PK_pixfmtHasAlpha))\n            pDecoder->WMP.wmiSCP.uAlphaMode = 2;\n        else\n            pDecoder->WMP.wmiSCP.uAlphaMode = 0;\n\t\tpDecoder->WMP.wmiSCP.sbSubband = SB_ALL;\n\t\tpDecoder->WMP.bIgnoreOverlap = FALSE;\n\t\tpDecoder->WMP.wmiI.cfColorFormat = PI.cfColorFormat;\n\t\tpDecoder->WMP.wmiI.bdBitDepth = PI.bdBitDepth;\n\t\tpDecoder->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;\n\t\tpDecoder->WMP.wmiI.cThumbnailWidth = pDecoder->WMP.wmiI.cWidth;\n\t\tpDecoder->WMP.wmiI.cThumbnailHeight = pDecoder->WMP.wmiI.cHeight;\n\t\tpDecoder->WMP.wmiI.bSkipFlexbits = FALSE;\n\t\tpDecoder->WMP.wmiI.cROILeftX = 0;\n\t\tpDecoder->WMP.wmiI.cROITopY = 0;\n\t\tpDecoder->WMP.wmiI.cROIWidth = pDecoder->WMP.wmiI.cThumbnailWidth;\n\t\tpDecoder->WMP.wmiI.cROIHeight = pDecoder->WMP.wmiI.cThumbnailHeight;\n\t\tpDecoder->WMP.wmiI.oOrientation = O_NONE;\n\t\tpDecoder->WMP.wmiI.cPostProcStrength = 0;\n\t\tpDecoder->WMP.wmiSCP.bVerbose = FALSE;\n\n\t\tint width = 0;\n\t\tint height = 0;\n\t\tpDecoder->GetSize( pDecoder, &width, &height );\n\t\n\t\t*dic = TJSCreateDictionaryObject();\n\t\ttTJSVariant val(width);\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\t\tval = tTJSVariant(height);\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic));\n\t\tval = tTJSVariant((tjs_int64)(pDecoder->WMP.wmiSCP.uAlphaMode ? 32 : 24));\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic));\n\n\t\tif( pDecoder ) pDecoder->Release(&pDecoder);\n\t\tif( pStream ) free( pStream );\n\t} catch(...) {\n\t\tif( pDecoder ) pDecoder->Release(&pDecoder);\n\t\tif( pStream ) free( pStream );\n\t\tthrow;\n\t}\n}\n#endif\n"
  },
  {
    "path": "src/core/visual/LoadPNG.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tvpgl.h\"\n\n#include \"png.h\"\n//#include \"pngstruct.h\"\n//#include \"pnginfo.h\"\n\n#include \"DebugIntf.h\"\n#include \"tjsDictionary.h\"\n#include \"ScriptMgnIntf.h\"\n\nbool TVPAcceptSaveAsPNG(void* formatdata, const ttstr & type, class iTJSDispatch2** dic )\n{\n\tbool result = false;\n\tif( type.StartsWith(TJS_W(\"png\")) ) result = true;\n\telse if( type == TJS_W(\".png\") ) result = true;\n\n\tif( result && dic ) {\n#if 0\n\t\ttTJSVariant result;\n\t\tTVPExecuteExpression(\n\t\t\tTJS_W(\"(const)%[\"),\n\t\t\tTJS_W(\"\\\"offs_x\\\"=>(const)%[\\\"type\\\"=>\\\"integer\\\",\\\"desc\\\"=>\\\"offset x\\\",\\\"default\\\"=>0]\")\n\t\t\tTJS_W(\"\\\"offs_y\\\"=>(const)%[\\\"type\\\"=>\\\"integer\\\",\\\"desc\\\"=>\\\"offset y\\\",\\\"default\\\"=>0]\")\n\t\t\tTJS_W(\"\\\"offs_unit\\\"=>(const)%[\\\"type\\\"=>\\\"select text\\\",\\\"items\\\"=>[\\\"pixel\\\",\\\"micrometer\\\"],\\\"desc\\\"=>\\\"offset unit\\\",\\\"default\\\"=>\\\"pixel\\\"]\")\n\t\t\tTJS_W(\"]\"),\n\t\t\tNULL, &result );\n\t\tif( result.Type() == tvtObject ) {\n\t\t\t*dic = result.AsObject();\n\t\t}\n#endif\n\t\t// ^Ooɂ͑ΉĂȂ\n\t\t*dic = TJSCreateDictionaryObject();\n\t}\n\treturn result;\n}\n//---------------------------------------------------------------------------\n// PNG loading handler\n//---------------------------------------------------------------------------\nstatic ttstr PNG_tag_offs_x(TJS_W(\"offs_x\"));\nstatic ttstr PNG_tag_offs_y(TJS_W(\"offs_y\"));\nstatic ttstr PNG_tag_offs_unit(TJS_W(\"offs_unit\"));\nstatic ttstr PNG_tag_reso_x(TJS_W(\"reso_x\"));\nstatic ttstr PNG_tag_reso_y(TJS_W(\"reso_y\"));\nstatic ttstr PNG_tag_reso_unit(TJS_W(\"reso_unit\"));\nstatic ttstr PNG_tag_vpag_w(TJS_W(\"vpag_w\"));\nstatic ttstr PNG_tag_vpag_h(TJS_W(\"vpag_h\"));\nstatic ttstr PNG_tag_vpag_unit(TJS_W(\"vpag_unit\"));\nstatic ttstr PNG_tag_pixel(TJS_W(\"pixel\"));\nstatic ttstr PNG_tag_micrometer(TJS_W(\"micrometer\"));\nstatic ttstr PNG_tag_meter(TJS_W(\"meter\"));\nstatic ttstr PNG_tag_unknown(TJS_W(\"unknown\"));\n//---------------------------------------------------------------------------\n// meta callback information structure used by  PNG_read_chunk_callback\nstruct PNG_read_chunk_callback_user_struct\n{\n\tvoid * callbackdata;\n    tTVPMetaInfoPushCallback metainfopushcallback;\n};\n//---------------------------------------------------------------------------\n// user_malloc_fn\nstatic png_voidp PNG_malloc(png_structp ps, png_size_t size)\n{\n\treturn malloc(size);\n}\n//---------------------------------------------------------------------------\n// user_free_fn\nstatic void PNG_free (png_structp ps,void* /* png_structp*/ mem)\n{\n\tfree(mem);\n}\n//---------------------------------------------------------------------------\n// user_error_fn\nstatic void PNG_error (png_structp ps, png_const_charp msg)\n{\n\tTVPThrowExceptionMessage(TVPPNGLoadError, msg);\n}\n//---------------------------------------------------------------------------\n// user_warning_fn\nstatic void PNG_warning (png_structp ps, png_const_charp msg)\n{\n\t// do nothing\n\t//TVPAddLog( TJS_W(\"PNG warning:\") );\n\t//TVPAddLog( msg );\n}\n//---------------------------------------------------------------------------\n// user_read_data\nstatic void PNG_read_data(png_structp png_ptr,png_bytep data,png_size_t length)\n{\n\t((tTJSBinaryStream *)png_get_io_ptr(png_ptr))->ReadBuffer((void*)data, (tjs_uint)length);\n}\n//---------------------------------------------------------------------------\n// read_row_callback\nstatic void PNG_read_row_callback(png_structp png_ptr,png_uint_32 row,int pass)\n{\n\n}\n//---------------------------------------------------------------------------\n// read_chunk_callback\nstatic int PNG_read_chunk_callback(png_structp png_ptr,png_unknown_chunkp chunk)\n{\n\t// handle vpAg chunk (this will contain the virtual page size of the image)\n\t// vpAg chunk can be embeded by ImageMagick -trim option etc.\n\t// we don't care about how the chunk bit properties are being provided.\n\tif(\t(chunk->name[0] == 0x76/*'v'*/ || chunk->name[0] == 0x56/*'V'*/) &&\n\t\t(chunk->name[1] == 0x70/*'p'*/ || chunk->name[1] == 0x50/*'P'*/) &&\n\t\t(chunk->name[2] == 0x61/*'a'*/ || chunk->name[2] == 0x41/*'A'*/) &&\n\t\t(chunk->name[3] == 0x67/*'g'*/ || chunk->name[3] == 0x47/*'G'*/) && chunk->size >= 9)\n\t{\n\t\tPNG_read_chunk_callback_user_struct * user_struct =\n\t\t\treinterpret_cast<PNG_read_chunk_callback_user_struct *>(png_get_user_chunk_ptr(png_ptr));\n\t\t// vpAg found\n\t\t/*\n\t\t\tuint32 width\n\t\t\tuint32 height\n\t\t\tuchar unit\n\t\t*/\n\t\t// be careful because the integers are stored in network byte order\n\t\t#define PNG_read_be32(a) (((tjs_uint32)(a)[0]<<24)+\\\n\t\t\t((tjs_uint32)(a)[1]<<16)+((tjs_uint32)(a)[2]<<8)+\\\n\t\t\t((tjs_uint32)(a)[3]))\n\t\ttjs_uint32 width  = PNG_read_be32(chunk->data+0);\n\t\ttjs_uint32 height = PNG_read_be32(chunk->data+4);\n\t\ttjs_uint8  unit   = chunk->data[8];\n\n\t\t// push information into meta-info\n\t\tuser_struct->metainfopushcallback(user_struct->callbackdata, PNG_tag_vpag_w, ttstr((tjs_int)width));\n\t\tuser_struct->metainfopushcallback(user_struct->callbackdata, PNG_tag_vpag_h, ttstr((tjs_int)height));\n\t\tswitch(unit)\n\t\t{\n\t\tcase PNG_OFFSET_PIXEL:\n\t\t\tuser_struct->metainfopushcallback(user_struct->callbackdata, PNG_tag_vpag_unit, PNG_tag_pixel);\n\t\t\tbreak;\n\t\tcase PNG_OFFSET_MICROMETER:\n\t\t\tuser_struct->metainfopushcallback(user_struct->callbackdata, PNG_tag_vpag_unit, PNG_tag_micrometer);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tuser_struct->metainfopushcallback(user_struct->callbackdata, PNG_tag_vpag_unit, PNG_tag_unknown);\n\t\t\tbreak;\n\t\t}\n\t\treturn 1; // chunk read success\n\t}\n\treturn 0; // did not recognize\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadPNG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\tpng_structp png_ptr=NULL;\n\tpng_infop info_ptr=NULL;\n\tpng_infop end_info=NULL;\n\n\tpng_uint_32 i;\n\n\tpng_bytep *row_pointers=NULL;\n\ttjs_uint8 *image=NULL;\n\n\n\ttry\n\t{\n\t\t// create png_struct\n\t\tpng_ptr=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,\n\t\t\t(png_voidp)NULL, (png_error_ptr)PNG_error, (png_error_ptr)PNG_warning,\n\t\t\t(png_voidp)NULL, (png_malloc_ptr)PNG_malloc, (png_free_ptr)PNG_free);\n\t\t//png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)PNG_error, (png_error_ptr)PNG_warning );\n\t\tif( !png_ptr ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// set read_chunk_callback\n\t\tPNG_read_chunk_callback_user_struct read_chunk_callback_user_struct;\n\t\tread_chunk_callback_user_struct.callbackdata = callbackdata;\n\t\tread_chunk_callback_user_struct.metainfopushcallback = metainfopushcallback;\n\t\tpng_set_read_user_chunk_fn(png_ptr,\n\t\t\treinterpret_cast<void*>(&read_chunk_callback_user_struct),\n\t\t\t(png_user_chunk_ptr)PNG_read_chunk_callback);\n\t\tpng_set_keep_unknown_chunks(png_ptr, 2, NULL, 0);\n\t\t\t// keep only if safe-to-copy chunks, for all unknown chunks\n\n\t\t// create png_info\n\t\tinfo_ptr=png_create_info_struct(png_ptr);\n\t\tif( !info_ptr ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// create end_info\n\t\tend_info=png_create_info_struct(png_ptr);\n\t\tif( !end_info ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// set stream interface\n\t\tpng_set_read_fn(png_ptr,(png_voidp)src, (png_rw_ptr)PNG_read_data);\n\n\t\t// set read_row_callback\n\t\tpng_set_read_status_fn(png_ptr, (png_read_status_ptr)PNG_read_row_callback);\n\n\t\t// set png_read_info\n\t\tpng_read_info(png_ptr,info_ptr);\n\n\t\t// retrieve IHDR\n\t\tpng_uint_32 width,height;\n\t\tint bit_depth,color_type,interlace_type,compression_type,filter_type;\n\t\tpng_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,\n\t\t\t&interlace_type,&compression_type,&filter_type);\n\n\t\tif(bit_depth==16) png_set_strip_16(png_ptr);\n\n\t\t// retrieve offset information\n\t\tpng_int_32 offset_x, offset_y;\n\t\tint offset_unit_type;\n\t\tif(metainfopushcallback &&\n\t\t\tpng_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &offset_unit_type))\n\t\t{\n\t\t\t// push offset information into metainfo data\n\t\t\tmetainfopushcallback(callbackdata, PNG_tag_offs_x, ttstr((tjs_int)offset_x));\n\t\t\tmetainfopushcallback(callbackdata, PNG_tag_offs_y, ttstr((tjs_int)offset_y));\n\t\t\tswitch(offset_unit_type)\n\t\t\t{\n\t\t\tcase PNG_OFFSET_PIXEL:\n\t\t\t\tmetainfopushcallback(callbackdata, PNG_tag_offs_unit, PNG_tag_pixel);\n\t\t\t\tbreak;\n\t\t\tcase PNG_OFFSET_MICROMETER:\n\t\t\t\tmetainfopushcallback(callbackdata, PNG_tag_offs_unit, PNG_tag_micrometer);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tmetainfopushcallback(callbackdata, PNG_tag_offs_unit, PNG_tag_unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\n\t\tpng_uint_32 reso_x, reso_y;\n\t\tint reso_unit_type;\n\t\tif(metainfopushcallback &&\n\t\t\tpng_get_pHYs(png_ptr, info_ptr, &reso_x, &reso_y, &reso_unit_type))\n\t\t{\n\t\t\t// push offset information into metainfo data\n\t\t\tmetainfopushcallback(callbackdata, PNG_tag_reso_x, ttstr((tjs_int)reso_x));\n\t\t\tmetainfopushcallback(callbackdata, PNG_tag_reso_y, ttstr((tjs_int)reso_y));\n\t\t\tswitch(reso_unit_type)\n\t\t\t{\n\t\t\tcase PNG_RESOLUTION_METER:\n\t\t\t\tmetainfopushcallback(callbackdata, PNG_tag_reso_unit, PNG_tag_meter);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tmetainfopushcallback(callbackdata, PNG_tag_reso_unit, PNG_tag_unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\n\t\tbool do_convert_rgb_gray = false;\n\n\t\tif(mode == glmPalettized)\n\t\t{\n\t\t\t// convert the image to palettized one if needed\n\t\t\tif(bit_depth > 8)\n\t\t\t\tTVPThrowExceptionMessage(\n\t\t\t\t\tTVPPNGLoadError, (const tjs_char*)TVPUnsupportedColorTypePalette );\n\n\t\t\tif(color_type == PNG_COLOR_TYPE_PALETTE)\n\t\t\t{\n\t\t\t\tpng_set_packing(png_ptr);\n\t\t\t}\n\n\t\t\tif(color_type == PNG_COLOR_TYPE_GRAY) png_set_expand_gray_1_2_4_to_8(png_ptr);\n\t\t}\n\t\telse if(mode == glmGrayscale)\n\t\t{\n\t\t\t// convert the image to grayscale\n\t\t\tif(color_type == PNG_COLOR_TYPE_PALETTE)\n\t\t\t{\n\t\t\t\tpng_set_palette_to_rgb(png_ptr);\n\t\t\t//\tpng_set_bgr(png_ptr);\n\t\t\t\tif (bit_depth < 8)\n\t\t\t\t\tpng_set_packing(png_ptr);\n\t\t\t\tdo_convert_rgb_gray = true; // manual conversion\n\t\t\t}\n\t\t\tif(color_type == PNG_COLOR_TYPE_GRAY &&\n\t\t\t\tbit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);\n\t\t\tif(color_type == PNG_COLOR_TYPE_RGB ||\n\t\t\t\tcolor_type == PNG_COLOR_TYPE_RGB_ALPHA)\n\t\t\t\tpng_set_rgb_to_gray_fixed(png_ptr, 1, 0, 0);\n\t\t\tif(color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n\t\t\t\tcolor_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n\t\t\t\tpng_set_strip_alpha(png_ptr);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// glmNormal\n\t\t\t// convert the image to full color ( 32bits ) one if needed\n\n\t\t\tif(color_type == PNG_COLOR_TYPE_PALETTE)\n\t\t\t{\n\t\t\t\tif(keyidx == -1)\n\t\t\t\t{\n\t\t\t\t\tif(png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS))\n\t\t\t\t\t{\n\t\t\t\t\t\t// set expansion with palettized picture\n\t\t\t\t\t\tpng_set_palette_to_rgb(png_ptr);\n\t\t\t\t\t\tpng_set_tRNS_to_alpha(png_ptr);\n\t\t\t\t\t\tcolor_type=PNG_COLOR_TYPE_RGB_ALPHA;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tpng_set_palette_to_rgb(png_ptr);\n\t\t\t\t\t\tcolor_type=PNG_COLOR_TYPE_RGB;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpng_byte trans = (png_byte) keyidx;\n\t\t\t\t\tpng_set_tRNS(png_ptr, info_ptr, &trans, 1, 0);\n\t\t\t\t\t\t// make keyidx transparent color.\n\t\t\t\t\tpng_set_palette_to_rgb(png_ptr);\n\t\t\t\t\tpng_set_tRNS_to_alpha(png_ptr);\n\t\t\t\t\tcolor_type=PNG_COLOR_TYPE_RGB_ALPHA;\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch(color_type)\n\t\t\t{\n\t\t\tcase PNG_COLOR_TYPE_GRAY_ALPHA:\n\t\t\t\tpng_set_gray_to_rgb(png_ptr);\n\t\t\t\tcolor_type=PNG_COLOR_TYPE_RGB_ALPHA;\n\t\t\t\tpng_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);\n\t\t\t\tbreak;\n\t\t\tcase PNG_COLOR_TYPE_GRAY:\n\t\t\t\tpng_set_expand(png_ptr);\n\t\t\t\tpng_set_gray_to_rgb(png_ptr);\n\t\t\t\tcolor_type=PNG_COLOR_TYPE_RGB;\n\t\t\t\tpng_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);\n\t\t\t\tbreak;\n\t\t\tcase PNG_COLOR_TYPE_RGB_ALPHA:\n\t\t\t//\tpng_set_bgr(png_ptr);\n\t\t\t\tbreak;\n\t\t\tcase PNG_COLOR_TYPE_RGB:\n\t\t\t//\tpng_set_bgr(png_ptr);\n\t\t\t\tpng_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tTVPThrowExceptionMessage(\n \t\t\t\t\tTVPPNGLoadError, (const tjs_char*)TVPUnsupportedColorType );\n\t\t\t}\n\t\t}\n\n\n\t\t// size checking\n\t\tif(width>=65536 || height>=65536)\n\t\t{\n\t\t\t// too large image to handle\n\t\t\tTVPThrowExceptionMessage(\n\t\t\t\tTVPPNGLoadError, (const tjs_char*)TVPTooLargeImage );\n\t\t}\n\n\n\t\t// call png_read_update_info\n\t\tpng_read_update_info(png_ptr,info_ptr);\n\n\t\t// set size\n\t\tsizecallback(callbackdata, width, height, color_type == PNG_COLOR_TYPE_RGB_ALPHA ? gpfRGBA : gpfRGB);\n\n\t\t// load image\n\t\tif (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_NONE)\n\t\t{\n\t\t\t// non-interlace\n\t\t\tif(do_convert_rgb_gray)\n\t\t\t{\n\t\t\t\tpng_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\t\t\t\timage = new tjs_uint8[rowbytes];\n\t\t\t}\n#if 1\n\t\t\tif( !do_convert_rgb_gray ) {\n\t\t\t\tfor(i=0; i<height; i++) {\n\t\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\t\tif(!scanline) break;\n\t\t\t\t\tpng_read_row(png_ptr, (png_bytep)scanline, NULL);\n\t\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor(i=0; i<height; i++) {\n\t\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\t\tif(!scanline) break;\n\t\t\t\t\tpng_read_row(png_ptr, (png_bytep)image, NULL);\n\t\t\t\t\tTVPBLConvert24BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)image, width);\n\t\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tfor(i=0; i<height; i++)\n\t\t\t{\n\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\tif(!scanline) break;\n\t\t\t\tif(!do_convert_rgb_gray)\n\t\t\t\t{\n\t\t\t\t\tpng_read_row(png_ptr, (png_bytep)scanline, NULL);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpng_read_row(png_ptr, (png_bytep)image, NULL);\n\t\t\t\t\tTVPBLConvert24BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)image, width);\n\t\t\t\t}\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n#endif\n\t\t\t// finish loading\n\t\t\tpng_read_end(png_ptr,info_ptr);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// interlace handling\n\t\t\t// load the image at once\n\n\t\t\trow_pointers = new png_bytep[height];\n\t\t\tpng_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\t\t\timage = new tjs_uint8[rowbytes * height];\n\t\t\tfor(i=0; i<height; i++)\n\t\t\t{\n\t\t\t\trow_pointers[i] = image+ i*rowbytes;\n\t\t\t}\n\n\t\t\t// loads image\n\t\t\tpng_read_image(png_ptr, row_pointers);\n\n\t\t\t// finish loading\n\t\t\tpng_read_end(png_ptr, info_ptr);\n\n\t\t\t// set the pixel data\n\t\t\tfor(i=0; i<height; i++)\n\t\t\t{\n\t\t\t\tvoid *scanline = scanlinecallback(callbackdata, i);\n\t\t\t\tif(!scanline) break;\n\t\t\t\tif(!do_convert_rgb_gray)\n\t\t\t\t{\n\t\t\t\t\tmemcpy(scanline, row_pointers[i], rowbytes);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTVPBLConvert24BitTo8Bit(\n\t\t\t\t\t\t(tjs_uint8*)scanline,\n\t\t\t\t\t\t(tjs_uint8*)row_pointers[i], width);\n\t\t\t\t}\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tpng_destroy_read_struct(&png_ptr,&info_ptr,&end_info);\n\t\tif(row_pointers) delete [] row_pointers;\n\t\tif(image) delete [] image;\n\t\tthrow;\n\t}\n\n\tpng_destroy_read_struct(&png_ptr,&info_ptr,&end_info);\n\tif(row_pointers) delete [] row_pointers;\n\tif(image) delete [] image;\n\n}\n//---------------------------------------------------------------------------\n/**\n * PNG݃tbV\n * @param png_ptr : PNG\n */\nstatic void PNG_write_flash( png_structp png_ptr )\n{\n\t// Ȃ\n}\n//---------------------------------------------------------------------------\n/**\n * PNG\n * @param png_ptr : PNG\n * @param buf : ݃f[^\n * @param size : f[^TCY\n */\nstatic void PNG_write_write( png_structp png_ptr, png_bytep buf, png_size_t size )\n{\n    tTJSBinaryStream* stream=(tTJSBinaryStream*)png_get_io_ptr(png_ptr);\n    stream->WriteBuffer(buf,(tjs_uint)size);\n}\n//---------------------------------------------------------------------------\n/**\n * PNG\n * tJ[ł݂̏̂ݑΉ\n * @param dst : o͐\n * @param image : oC[Wf[^\n * @param mode : [h (݂pnĝ݉)\n * @param meta : ǉIvV (݂͖)\n */\nvoid TVPSaveAsPNG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta )\n{\n\tint bpp = 32;\n\tif( mode.StartsWith(TJS_W(\"png\")) && mode.length() > 3 ) {\n\t\tif( mode == TJS_W(\"png24\") ) {\n\t\t\tbpp = 24;\n\t\t}\n\t}\n\n\ttjs_uint height = image->GetHeight();\n\ttjs_uint width = image->GetWidth();\n\tif( height == 0 || width == 0 ) TVPThrowInternalError;\n\n\t// open stream\n\ttTJSBinaryStream *stream = dst;\n\n\ttry {\n\t\tTVPClearGraphicCache();\n\n\t\tpng_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);\n\t\tif( !png_ptr ) {\n\t\t\tTVPThrowExceptionMessage( TVPPngSaveError );\n\t\t}\n\t\tpng_infop info_ptr = png_create_info_struct(png_ptr);\n\t\tif( !info_ptr ) {\n\t\t\tpng_destroy_write_struct(&png_ptr,NULL);\n\t\t\tTVPThrowExceptionMessage( TVPPngSaveError );\n\t\t}\n\n\t\tpng_set_write_fn( png_ptr, (png_voidp)stream, (png_rw_ptr)PNG_write_write, (png_flush_ptr)PNG_write_flash );\n\n\t\tpng_set_IHDR( png_ptr, info_ptr, width, height, 8, (bpp == 32 ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB), PNG_INTERLACE_NONE,\n\t\t\t\t\tPNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );\n\t\n\t\tpng_color_8 sig_bit;\n\t\tsig_bit.red = 8;\n\t\tsig_bit.green = 8;\n\t\tsig_bit.blue = 8;\n\t\tsig_bit.gray = 0;\n\t\tsig_bit.alpha = bpp == 32 ? 8 : 0;\n\t\tpng_set_sBIT( png_ptr, info_ptr, &sig_bit );\n\n\t\t/* ----- CtH[Vwb_[o */\n\t\tpng_write_info( png_ptr, info_ptr );\n\t//\tpng_set_bgr( png_ptr );\n\n\t\t/* ----- sNZo */\n\t\ttjs_uint width_byte = (bpp*width)/8;\n\t\ttjs_uint8* buff = new tjs_uint8[width_byte];\n\t\tif( bpp == 32 ) {\n\t\t\tfor( tjs_uint32 y = 0; y < height; y++ ) {\n\t\t\t\tmemcpy( buff, image->GetScanLine(y), width_byte );\n\t\t\t\tpng_write_row( png_ptr, (png_bytep)buff );\n\t\t\t}\n\t\t} else {\n\t\t\tfor( tjs_uint32 y = 0; y < height; y++ ) {\n\t\t\t\tconst tjs_uint8* src = reinterpret_cast<const tjs_uint8*>(image->GetScanLine(y));\n\t\t\t\ttjs_uint8* dst = buff;\n\t\t\t\tfor( tjs_uint32 x = 0; x < width; x++ ) {\n\t\t\t\t\t*dst = *src; dst++; src++;\n\t\t\t\t\t*dst = *src; dst++; src++;\n\t\t\t\t\t*dst = *src; dst++; src++;\n\t\t\t\t\tsrc++;\n\t\t\t\t}\n\t\t\t\tpng_write_row( png_ptr, (png_bytep)buff );\n\t\t\t}\n\t\t}\n\t\t/* ----- ȍIAn */\n\t\tpng_write_end( png_ptr, info_ptr );\n\t\tpng_destroy_write_struct( &png_ptr, &info_ptr );\n\t\tdelete []buff;\n\t} catch(...) {\n\t\tthrow;\n\t}\n}\n\nvoid TVPLoadHeaderPNG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tpng_structp png_ptr=NULL;\n\tpng_infop info_ptr=NULL;\n\tpng_infop end_info=NULL;\n\ttry\n\t{\n\t\t// create png_struct\n\t\tpng_ptr=png_create_read_struct_2(PNG_LIBPNG_VER_STRING,\n\t\t\t(png_voidp)NULL, (png_error_ptr)PNG_error, (png_error_ptr)PNG_warning,\n\t\t\t(png_voidp)NULL, (png_malloc_ptr)PNG_malloc, (png_free_ptr)PNG_free);\n\n\t\tif( !png_ptr ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// create png_info\n\t\tinfo_ptr=png_create_info_struct(png_ptr);\n\t\tif( !info_ptr ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// create end_info\n\t\tend_info=png_create_info_struct(png_ptr);\n\t\tif( !end_info ) TVPThrowExceptionMessage(TVPPNGLoadError, (const tjs_char*)TVPLibpngError );\n\n\t\t// set stream interface\n\t\tpng_set_read_fn(png_ptr,(png_voidp)src, (png_rw_ptr)PNG_read_data);\n\n\t\t// set read_row_callback\n\t\tpng_set_read_status_fn(png_ptr, (png_read_status_ptr)PNG_read_row_callback);\n\n\t\t// set png_read_info\n\t\tpng_read_info(png_ptr,info_ptr);\n\n\t\t// retrieve IHDR\n\t\tpng_uint_32 width,height;\n\t\tint bit_depth,color_type,interlace_type,compression_type,filter_type;\n\t\tpng_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,\n\t\t\t&interlace_type,&compression_type,&filter_type);\n\t\tswitch(color_type) {\n\t\tcase PNG_COLOR_TYPE_GRAY:\tbit_depth *= 1; break;\n\t\tcase PNG_COLOR_TYPE_PALETTE:bit_depth *= 1; break;\n\t\tcase PNG_COLOR_TYPE_RGB:\tbit_depth *= 3; break;\n\t\tcase PNG_COLOR_TYPE_RGBA:\tbit_depth *= 4; break;\n\t\tcase PNG_COLOR_TYPE_GA:\t\tbit_depth *= 2; break;\n\t\t}\n\n\t\t*dic = TJSCreateDictionaryObject();\n\t\ttTJSVariant val((tjs_int64)width);\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\t\tval = tTJSVariant((tjs_int64)height);\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic) );\n\t\tval = tTJSVariant(bit_depth);\n\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic) );\n\t\t// color_type,interlace_type,compression_type,filter_type ꂽcc\n\n\t\t// retrieve offset information\n\t\tpng_int_32 offset_x, offset_y;\n\t\tint offset_unit_type;\n\t\tif( png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &offset_unit_type) )\n\t\t{\n\t\t\tval = tTJSVariant(offset_x);\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"offset x\"), 0, &val, (*dic) );\n\t\t\tval = tTJSVariant(offset_y);\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"offset y\"), 0, &val, (*dic) );\n\t\t\tswitch(offset_unit_type)\n\t\t\t{\n\t\t\tcase PNG_OFFSET_PIXEL:\n\t\t\t\tval = tTJSVariant(TJS_W(\"pixel\"));\n\t\t\t\tbreak;\n\t\t\tcase PNG_OFFSET_MICROMETER:\n\t\t\t\tval = tTJSVariant(TJS_W(\"micro meter\"));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tval = tTJSVariant(TJS_W(\"unknown\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"offset unit\"), 0, &val, (*dic) );\n\t\t}\n\n\t\tpng_uint_32 reso_x, reso_y;\n\t\tint reso_unit_type;\n\t\tif( png_get_pHYs(png_ptr, info_ptr, &reso_x, &reso_y, &reso_unit_type) )\n\t\t{\n\t\t\tval = tTJSVariant((tjs_int64)reso_x);\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"resolution x\"), 0, &val, (*dic) );\n\t\t\tval = tTJSVariant((tjs_int64)reso_y);\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"resolution y\"), 0, &val, (*dic) );\n\t\t\tswitch(reso_unit_type)\n\t\t\t{\n\t\t\tcase PNG_RESOLUTION_METER:\n\t\t\t\tval = tTJSVariant(TJS_W(\"meter\"));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tval = tTJSVariant(TJS_W(\"unknown\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"resolution unit\"), 0, &val, (*dic) );\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tpng_destroy_read_struct(&png_ptr,&info_ptr,&end_info);\n\t\tif( *dic ) (*dic)->Release();\n\t\tthrow;\n\t}\n\tpng_destroy_read_struct(&png_ptr,&info_ptr,&end_info);\n}\n\n"
  },
  {
    "path": "src/core/visual/LoadPVRv3.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"tjsDictionary.h\"\n#include \"MsgIntf.h\"\n#include \"ogl/etcpak.h\"\n#include \"ogl/pvr.h\"\n#include \"UtilStreams.h\"\n#include \"RenderManager.h\"\n#include \"tvpgl.h\"\n#include \"base/pvr.h\"\n#include \"LayerBitmapIntf.h\"\n\n// pvr format only used as normal picture or univ trans rule ( not as province image )\n\nstatic ttstr TVPUnserializeString(tTJSBinaryStream * s) {\n\ttjs_uint16 l = s->ReadI16LE();\n\tstd::vector<char> strbuf; strbuf.resize(l + 1);\n\tif (s->Read(&strbuf.front(), l) != l) { // in utf-8\n\t\treturn ttstr();\n\t}\n\treturn &strbuf.front();\n}\n\nstatic tTJSVariant TVPUnserializePVRv3Variable(tTJSBinaryStream * s) {\n\ttjs_uint8 typ = 0;\n\ts->ReadBuffer(&typ, 1);\n\tswitch (typ) {\n\tcase tvtVoid:\n\t\treturn tTJSVariant();\n\tcase tvtString:\n\t\treturn TVPUnserializeString(s);\n\tcase tvtInteger:\n\t\treturn (tjs_int64)s->ReadI64LE();\n\tcase tvtReal:\n\t{\n\t\ttTVReal v;\n\t\ts->ReadBuffer(&v, sizeof(v));\n\t\treturn v;\n\t}\n\tdefault:\n\t\treturn tTJSVariant();\n\t}\n}\n\nstatic int TVPUnserializePVRv3Metadata(tTJSBinaryStream *s, const std::function<void(const ttstr&, const tTJSVariant&)> &cb) {\n\tchar tmp[4];\n\ts->ReadBuffer(tmp, 4);\n\tif (memcmp(tmp, \"tags\", 4)) return 0;\n\ttjs_uint32 count = s->ReadI32LE();\n\tfor (tjs_uint32 i = 0; i < count; ++i) {\n\t\tttstr name = TVPUnserializeString(s);\n\t\tif (name.IsEmpty()) {\n\t\t\treturn i;\n\t\t}\n\t\tcb(name, TVPUnserializePVRv3Variable(s));\n\t}\n\treturn count;\n}\n\nstatic unsigned int TVPSerializePVRv3String(tTJSBinaryStream *dst, const std::string &str) {\n\ttjs_uint16 l = str.size();\n\tdst->Write(&l, sizeof(l));\n\tdst->Write(str.c_str(), l);\n\treturn l + 2;\n}\n\nstatic unsigned int TVPSerializePVRv3Variable(tTJSBinaryStream *dst, const tTJSVariant &v) {\n\ttjs_uint8 ty = v.Type();\n\tdst->WriteBuffer(&ty, sizeof(ty));\n\ttjs_int64 intv;\n\ttTVReal fltv;\n\tswitch (v.Type()) {\n\tcase tvtString:\n\t\treturn TVPSerializePVRv3String(dst, ttstr(v).AsStdString()) + 1;\n\tcase tvtInteger:\n\t\tintv = v.AsInteger();\n\t\tdst->WriteBuffer(&intv, sizeof(intv));\n\t\treturn 9;\n\tcase tvtReal:\n\t\tfltv = v.AsReal();\n\t\tdst->WriteBuffer(&fltv, sizeof(fltv));\n\t\treturn 9;\n\tdefault:\n\t\treturn 1;\n\t}\n}\n\nstatic unsigned int TVPSerializePVRv3Metadata(tTJSBinaryStream *dst, const std::vector<std::pair<ttstr, tTJSVariant> >& tags) {\n\tdst->WriteBuffer(\"tags\", 4);\n\ttjs_uint32 count = tags.size();\n\tdst->WriteBuffer(&count, sizeof(count));\n\tunsigned int totalSize = 8;\n\tfor (const std::pair<ttstr, tTJSVariant> &it : tags) {\n\t\ttotalSize += TVPSerializePVRv3String(dst, it.first.AsStdString());\n\t\ttotalSize += TVPSerializePVRv3Variable(dst, it.second);\n\t}\n\treturn totalSize;\n}\n\n// load texture directly\niTVPTexture2D* TVPLoadPVRv3(tTJSBinaryStream *src, const std::function<void(const ttstr&, const tTJSVariant&)> &cb) {\n\tiTVPTexture2D* ret = TVPGetRenderManager()->CreateTexture2D(src);\n\tif (!ret) return nullptr;\n\tsrc->SetPosition(0);\n\tPVRv3Header hdr;\n\tsrc->ReadBuffer(&hdr, sizeof(hdr));\n\tif (hdr.metadataLength > 8) {\n\t\ttTVPMemoryStream metadata; metadata.SetSize(hdr.metadataLength);\n\t\tsrc->ReadBuffer(metadata.GetInternalBuffer(), hdr.metadataLength);\n\t\tTVPUnserializePVRv3Metadata(&metadata, cb);\n\t}\n\treturn ret;\n}\n\nvoid TVPLoadPVRv3(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int keyidx,\n\ttTVPGraphicLoadMode mode) {\n\tif (mode == glmPalettized) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Unsupport palettized image\"));\n\t}\n\tPVRv3Header hdr;\n\tsrc->ReadBuffer(&hdr, sizeof(hdr));\n\tif (hdr.version != 0x03525650) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Invalid image\"));\n\t}\n\n\ttjs_uint64 dataoff = src->GetPosition() + hdr.metadataLength;\n\n\tif (hdr.metadataLength > 8) {\n\t\ttTVPMemoryStream metadata; metadata.SetSize(hdr.metadataLength);\n\t\tsrc->ReadBuffer(metadata.GetInternalBuffer(), hdr.metadataLength);\n\t\tTVPUnserializePVRv3Metadata(&metadata, [metainfopushcallback, callbackdata](const ttstr& k, const tTJSVariant& v) {\n\t\t\tmetainfopushcallback(callbackdata, k, v);\n\t\t});\n\t}\n\tunsigned int eachblkw = 0, eachblkh = 0;\n\tunsigned int blksize = 0;\n\ttTVPGraphicPixelFormat fmt;\n\tswitch ((PVR3TexturePixelFormat)hdr.pixelFormat) {\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGB:\n\t\teachblkw = 8; eachblkh = 4; blksize = 8; fmt = gpfRGB; break;\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGBA:\n\t\teachblkw = 8; eachblkh = 4; blksize = 8; fmt = gpfRGBA; break;\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGB:\n\t\teachblkw = 4; eachblkh = 4; blksize = 8; fmt = gpfRGB; break;\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGBA:\n\t\teachblkw = 4; eachblkh = 4; blksize = 8; fmt = gpfRGBA; break;\n\tcase PVR3TexturePixelFormat::ETC1:\n\tcase PVR3TexturePixelFormat::ETC2_RGB:\n\t\teachblkw = 4; eachblkh = 4; blksize = 8; fmt = gpfRGB; break;\n\tcase PVR3TexturePixelFormat::ETC2_RGBA:\n\t\teachblkw = 4; eachblkh = 4; blksize = 16; fmt = gpfRGBA; break;\n\tcase PVR3TexturePixelFormat::BGRA8888:\n\tcase PVR3TexturePixelFormat::RGBA8888:\n\t\teachblkw = 1; eachblkh = 1; blksize = 4; fmt = gpfRGBA; break;\n\tcase PVR3TexturePixelFormat::RGB888:\n\t\teachblkw = 1; eachblkh = 1; blksize = 3; fmt = gpfRGB; break;\n\tcase PVR3TexturePixelFormat::L8:\n\t\teachblkw = 1; eachblkh = 1; blksize = 1; fmt = gpfRGB; break;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Unsupport format [%1]\"),\n\t\t\tttstr((tjs_int)hdr.pixelFormat));\n\t}\n\t// ignore mipmap\n\tunsigned int blkh = hdr.height / eachblkh + !!(hdr.height & (eachblkh - 1));\n\tunsigned int blkw = hdr.width / eachblkw + !!(hdr.width & (eachblkw - 1));\n\tsize_t size = blkw * blkh * blksize;\n\ttjs_int pitch = sizecallback(callbackdata, hdr.width, hdr.height, fmt);\n\tstd::vector<unsigned char> buf; buf.resize(size);\n\tunsigned char *psrc = &buf.front();\n\tsrc->SetPosition(dataoff);\n\tsrc->ReadBuffer(psrc, size);\n\tvoid *pixel = scanlinecallback(callbackdata, 0);\n\tunsigned char *pdst = (unsigned char *)pixel;\n\tswitch ((PVR3TexturePixelFormat)hdr.pixelFormat) {\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGB:\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGBA:\n\t\tPVRTDecompressPVRTC(psrc, pitch / 4, hdr.height, pixel, true);\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGB:\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGBA:\n\t\tPVRTDecompressPVRTC(psrc, pitch / 4, hdr.height, pixel, false);\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::ETC1:\n\tcase PVR3TexturePixelFormat::ETC2_RGB:\n\t\tETCPacker::decode(psrc, pixel, pitch, hdr.height, blkw, blkh);\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::ETC2_RGBA:\n\t\tETCPacker::decodeWithAlpha(psrc, pixel, pitch, hdr.height, blkw, blkh);\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::BGRA8888:\n\t\tfor (uint32_t y = 0; y < hdr.height; ++y) {\n\t\t\tTVPReverseRGB((tjs_uint32 *)pixel, (const tjs_uint32 *)psrc, hdr.width);\n\t\t\tpdst += pitch;\n\t\t\tpsrc += hdr.width * 4;\n\t\t}\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::RGBA8888:\n\t\tfor (uint32_t y = 0; y < hdr.height; ++y) {\n\t\t\tmemcpy(pixel, psrc, hdr.width * 4);\n\t\t\tpdst += pitch;\n\t\t\tpsrc += hdr.width * 4;\n\t\t}\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::RGB888:\n\t\tfor (uint32_t y = 0; y < hdr.height; ++y) {\n\t\t\tTVPConvert24BitTo32Bit((tjs_uint32 *)pixel, (const tjs_uint8 *)psrc, hdr.width);\n\t\t\tpdst += pitch;\n\t\t\tpsrc += hdr.width * 3;\n\t\t}\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::L8:\n\t\tfor (uint32_t y = 0; y < hdr.height; ++y) {\n\t\t\tTVPExpand8BitTo32BitGray((tjs_uint32 *)pixel, (const tjs_uint8 *)psrc, hdr.width);\n\t\t\tpdst += pitch;\n\t\t\tpsrc += hdr.width;\n\t\t}\n\t\tbreak;\n\tcase PVR3TexturePixelFormat::RGBA4444: // not support yet\n\tcase PVR3TexturePixelFormat::RGBA5551:\n\tcase PVR3TexturePixelFormat::RGB565:\n\tcase PVR3TexturePixelFormat::A8:\n\tcase PVR3TexturePixelFormat::LA88:\n\tdefault:\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Unsupport format [%1]\"),\n\t\t\tttstr((tjs_int)hdr.pixelFormat));\n\t\tbreak;\n\t}\n\tscanlinecallback(callbackdata, -1);\n}\n\nvoid TVPLoadHeaderPVRv3(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic) {\n\tPVRv3Header hdr;\n\tsrc->ReadBuffer(&hdr, sizeof(hdr));\n\tif (hdr.version != 0x03525650) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Invalid image\"));\n\t}\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val((tjs_int32)hdr.width);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic));\n\tval = tTJSVariant((tjs_int32)hdr.height);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic));\n\ttjs_int64 bpp = 0;\n\tswitch ((PVR3TexturePixelFormat)hdr.pixelFormat) {\n\tcase PVR3TexturePixelFormat::ETC1:\n\tcase PVR3TexturePixelFormat::ETC2_RGB:\n\tcase PVR3TexturePixelFormat::RGB888:\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGB:\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGB:\n\t\tbpp = 24; break;\n\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGBA:\n\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGBA:\n\tcase PVR3TexturePixelFormat::ETC2_RGBA:\n\tcase PVR3TexturePixelFormat::BGRA8888:\n\tcase PVR3TexturePixelFormat::RGBA8888:\n\t\tbpp = 32; break;\n\tcase PVR3TexturePixelFormat::L8:\n\t\tbpp = 8; break;\n\tdefault:\n\t\tTVPThrowExceptionMessage(TJS_W(\"PVR Load Error/Unsupport format [%1]\"),\n\t\t\tttstr((tjs_int)hdr.pixelFormat));\n\t}\n\tif (hdr.metadataLength > 8) {\n\t\ttTVPMemoryStream metadata; metadata.SetSize(hdr.metadataLength);\n\t\tsrc->ReadBuffer(metadata.GetInternalBuffer(), hdr.metadataLength);\n\t\tTVPUnserializePVRv3Metadata(&metadata, [dic](const ttstr& k, const tTJSVariant& v) {\n\t\t\t(*dic)->PropSet(TJS_MEMBERENSURE, k.c_str(), const_cast<ttstr&>(k).GetHint(), &v, (*dic));\n\t\t});\n\t}\n\tval = tTJSVariant(bpp);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic));\n}\n\nvoid TVPSavePVRv3(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta) {\n\tstd::vector<std::pair<ttstr, tTJSVariant> > tags;\n\tif (meta) {\n\t\tstruct MetaDictionaryEnumCallback : public tTJSDispatch {\n\t\t\tstd::vector<std::pair<ttstr, tTJSVariant> >& Tags;\n\t\t\tMetaDictionaryEnumCallback(std::vector<std::pair<ttstr, tTJSVariant> >& tags) : Tags(tags) {}\n\t\t\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis) {\n\t\t\t\t// called from tTJSCustomObject::EnumMembers\n\t\t\t\tif (numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t\t\t\t// hidden members are not processed\n\t\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\t\tif (flags & TJS_HIDDENMEMBER) {\n\t\t\t\t\tif (result) *result = (tjs_int)1;\n\t\t\t\t\treturn TJS_S_OK;\n\t\t\t\t}\n\t\t\t\t// push items\n\t\t\t\tTags.emplace_back(*param[0], *param[2]);\n\t\t\t\tif (result) *result = (tjs_int)1;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t} callback(tags);\n\t\ttTJSVariantClosure clo(&callback, NULL);\n\t\tmeta->EnumMembers(TJS_IGNOREPROP, &clo, meta);\n\t}\n\ttTVPMemoryStream memstr;\n\tconst void *pixeldata = image->GetScanLine(0);\n\tint w = image->GetWidth(), h = image->GetHeight(), pitch = image->GetPitchBytes();\n\tPVR3TexturePixelFormat pixelFormat = PVR3TexturePixelFormat::RGBA8888;\n\tif (mode == TJS_W(\"ETC2_RGB\")) {\n\t\tpixelFormat = PVR3TexturePixelFormat::ETC2_RGB;\n\t\t// drop alpha data\n\t\tsize_t size;\n\t\ttjs_uint8 *data = (tjs_uint8 *)ETCPacker::convert(pixeldata, w, h, pitch, true, size);\n\t\tmemstr.WriteBuffer(data, size);\n\t} else if (mode == TJS_W(\"ETC2_RGBA\")) {\n\t\tpixelFormat = PVR3TexturePixelFormat::ETC2_RGBA;\n\t\tsize_t size;\n\t\ttjs_uint8 *data = (tjs_uint8 *)ETCPacker::convertWithAlpha(pixeldata, w, h, pitch, size);\n\t\tmemstr.WriteBuffer(data, size);\n\t} else if (mode == TJS_W(\"ETC1\")) {\n\t\tpixelFormat = PVR3TexturePixelFormat::ETC1;\n\t\t// drop alpha data\n\t\tsize_t size;\n\t\ttjs_uint8 *data = (tjs_uint8 *)ETCPacker::convert(pixeldata, w, h, pitch, false, size);\n\t\tmemstr.WriteBuffer(data, size);\n\t} else { // direct save as RGBA8888\n\t\tfor (int y = 0; y < h; ++y) {\n\t\t\tmemstr.WriteBuffer(image->GetScanLine(y), w * 4);\n\t\t}\n\t}\n\tdst->WriteBuffer(\"PVR\\3\", 4);\n\tdst->WriteBuffer(\"\\0\\0\\0\\0\", 4); // no premultiply alpha\n\tdst->WriteBuffer(&pixelFormat, sizeof(pixelFormat));\n\tdst->WriteBuffer(\"\\0\\0\\0\\0\", 4); // colorSpace\n\tdst->WriteBuffer(\"\\0\\0\\0\\0\", 4); // channelType\n\tdst->WriteBuffer(&h, sizeof(h));\n\tdst->WriteBuffer(&w, sizeof(w));\n\tdst->WriteBuffer(\"\\1\\0\\0\\0\", 4); // depth\n\tdst->WriteBuffer(\"\\1\\0\\0\\0\", 4); // numberOfSurfaces\n\tdst->WriteBuffer(\"\\1\\0\\0\\0\", 4); // numberOfFaces\n\tdst->WriteBuffer(\"\\1\\0\\0\\0\", 4); // numberOfMipmaps\n\tif (tags.empty()) {\n\t\tdst->WriteBuffer(\"\\0\\0\\0\\0\", 4); // metadataLength\n\t} else {\n\t\tTVPSerializePVRv3Metadata(dst, tags);\n\t}\n\tdst->WriteBuffer(memstr.GetInternalBuffer(), memstr.GetSize());\n}\n"
  },
  {
    "path": "src/core/visual/LoadTLG.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TLG5/6 decoder\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsUtils.h\"\n#include \"tvpgl.h\"\n#include \"tjsDictionary.h\"\n\n#include <stdlib.h>\n\n/*\n\tTLG5:\n\t\tLossless graphics compression method designed for very fast decoding\n\t\tspeed.\n\n\tTLG6:\n\t\tLossless/near-lossless graphics compression method which is designed\n\t\tfor high compression ratio and faster decoding. Decoding speed is\n\t\tsomewhat slower than TLG5 because the algorithm is much more complex\n\t\tthan TLG5. Though, the decoding speed (using SSE enabled code) is\n\t\tabout 20 times faster than JPEG2000 lossless mode (using JasPer\n\t\tlibrary) while the compression ratio can beat or compete with it.\n\t\tSummary of compression algorithm is described in\n\t\tenviron/win32/krdevui/tpc/tlg6/TLG6Saver.cpp\n\t\t(in Japanese).\n*/\n\n\n\n//---------------------------------------------------------------------------\n// TLG5 loading handler\n//---------------------------------------------------------------------------\nvoid TVPLoadTLG5(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\ttTJSBinaryStream *src,\n\ttjs_int keyidx,\n\ttTVPGraphicLoadMode mode)\n{\n\t// load TLG v5.0 lossless compressed graphic\n\tif(mode != glmNormal)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgUnsupportedUniversalTransitionRule );\n\n\tunsigned char mark[12];\n\ttjs_int width, height, colors, blockheight;\n\tsrc->ReadBuffer(mark, 1);\n\tcolors = mark[0];\n\twidth = src->ReadI32LE();\n\theight = src->ReadI32LE();\n\tblockheight = src->ReadI32LE();\n\n\tif(colors != 3 && colors != 4)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPUnsupportedColorType );\n\n\tint blockcount = (int)((height - 1) / blockheight) + 1;\n\n\t// skip block size section\n\tsrc->SetPosition(src->GetPosition() + blockcount * sizeof(tjs_uint32));\n\n\n\t// decomperss\n\tsizecallback(callbackdata, width, height, colors == 3 ? gpfRGB : gpfRGBA);\n\n\ttjs_uint8 *inbuf = NULL;\n\ttjs_uint8 *outbuf[4];\n\ttjs_uint8 *text = NULL;\n\ttjs_int r = 0;\n\tfor(int i = 0; i < colors; i++) outbuf[i] = NULL;\n\n\ttry\n\t{\n\t\ttext = (tjs_uint8*)TJSAlignedAlloc(4096+32, 4) + 16;\n\t\tmemset(text, 0, 4096);\n\n\t\tinbuf = (tjs_uint8*)TJSAlignedAlloc(blockheight * width + 10+16, 4);\n\t\tfor(tjs_int i = 0; i < colors; i++)\n\t\t\toutbuf[i] = (tjs_uint8*)TJSAlignedAlloc(blockheight * width + 10+16, 4);\n\n\t\ttjs_uint8 *prevline = NULL;\n\t\tfor(tjs_int y_blk = 0; y_blk < height; y_blk += blockheight)\n\t\t{\n\t\t\t// read file and decompress\n\t\t\tfor(tjs_int c = 0; c < colors; c++)\n\t\t\t{\n\t\t\t\tsrc->ReadBuffer(mark, 1);\n\t\t\t\ttjs_int size;\n\t\t\t\tsize = src->ReadI32LE();\n\t\t\t\tif(mark[0] == 0)\n\t\t\t\t{\n\t\t\t\t\t// modified LZSS compressed data\n\t\t\t\t\tsrc->ReadBuffer(inbuf, size);\n\t\t\t\t\tr = TVPTLG5DecompressSlide(outbuf[c], inbuf, size, text, r);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// raw data\n\t\t\t\t\tsrc->ReadBuffer(outbuf[c], size);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// compose colors and store\n\t\t\ttjs_int y_lim = y_blk + blockheight;\n\t\t\tif(y_lim > height) y_lim = height;\n\t\t\ttjs_uint8 * outbufp[4];\n\t\t\tfor(tjs_int c = 0; c < colors; c++) outbufp[c] = outbuf[c];\n\t\t\tfor(tjs_int y = y_blk; y < y_lim; y++)\n\t\t\t{\n\t\t\t\ttjs_uint8 *current = (tjs_uint8*)scanlinecallback(callbackdata, y);\n\t\t\t\ttjs_uint8 *current_org = current;\n\t\t\t\tif(prevline)\n\t\t\t\t{\n\t\t\t\t\t// not first line\n\t\t\t\t\tswitch(colors)\n\t\t\t\t\t{\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tTVPTLG5ComposeColors3To4(current, prevline, outbufp, width);\n\t\t\t\t\t\toutbufp[0] += width; outbufp[1] += width;\n\t\t\t\t\t\toutbufp[2] += width;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tTVPTLG5ComposeColors4To4(current, prevline, outbufp, width);\n\t\t\t\t\t\toutbufp[0] += width; outbufp[1] += width;\n\t\t\t\t\t\toutbufp[2] += width; outbufp[3] += width;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// first line\n\t\t\t\t\tswitch(colors)\n\t\t\t\t\t{\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tfor(tjs_int pr = 0, pg = 0, pb = 0, x = 0;\n\t\t\t\t\t\t\tx < width; x++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_int r = outbufp[0][x];\n\t\t\t\t\t\t\ttjs_int g = outbufp[1][x];\n\t\t\t\t\t\t\ttjs_int b = outbufp[2][x];\n\t\t\t\t\t\t\tb += g; r += g;\n\t\t\t\t\t\t\t0[current++] = pb += b;\n\t\t\t\t\t\t\t0[current++] = pg += g;\n\t\t\t\t\t\t\t0[current++] = pr += r;\n\t\t\t\t\t\t\t0[current++] = 0xff;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutbufp[0] += width;\n\t\t\t\t\t\toutbufp[1] += width;\n\t\t\t\t\t\toutbufp[2] += width;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tfor(tjs_int pr = 0, pg = 0, pb = 0, pa = 0, x = 0;\n\t\t\t\t\t\t\tx < width; x++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_int r = outbufp[0][x];\n\t\t\t\t\t\t\ttjs_int g = outbufp[1][x];\n\t\t\t\t\t\t\ttjs_int b = outbufp[2][x];\n\t\t\t\t\t\t\ttjs_int a = outbufp[3][x];\n\t\t\t\t\t\t\tb += g; r += g;\n\t\t\t\t\t\t\t0[current++] = pb += b;\n\t\t\t\t\t\t\t0[current++] = pg += g;\n\t\t\t\t\t\t\t0[current++] = pr += r;\n\t\t\t\t\t\t\t0[current++] = pa += a;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutbufp[0] += width;\n\t\t\t\t\t\toutbufp[1] += width;\n\t\t\t\t\t\toutbufp[2] += width;\n\t\t\t\t\t\toutbufp[3] += width;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\n\t\t\t\tprevline = current_org;\n\t\t\t}\n\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(inbuf) TJSAlignedDealloc(inbuf);\n\t\tif(text) TJSAlignedDealloc(text - 16);\n\t\tfor(tjs_int i = 0; i < colors; i++)\n\t\t\tif(outbuf[i]) TJSAlignedDealloc(outbuf[i]);\n\t\tthrow;\n\t}\n\tif(inbuf) TJSAlignedDealloc(inbuf);\n\tif(text) TJSAlignedDealloc(text - 16);\n\tfor(tjs_int i = 0; i < colors; i++)\n\t\tif(outbuf[i]) TJSAlignedDealloc(outbuf[i]);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TLG6 loading handler\n//---------------------------------------------------------------------------\nvoid TVPLoadTLG6(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\ttTJSBinaryStream *src,\n\ttjs_int keyidx,\n\tbool palettized)\n{\n\t// load TLG v6.0 lossless/near-lossless compressed graphic\n#if 0\n\tif(palettized)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgUnsupportedUniversalTransitionRule );\n#endif\n\tunsigned char buf[12];\n\n\tsrc->ReadBuffer(buf, 4);\n\n\ttjs_int colors = buf[0]; // color component count\n\n\tif(colors != 1 && colors != 4 && colors != 3)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError,\n\t\t\tttstr(TVPUnsupportedColorCount) + ttstr((int)colors)  );\n\n\tif(buf[1] != 0) // data flag\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError,\n\t\t\t(const tjs_char*)TVPDataFlagMustBeZero );\n\n\tif(buf[2] != 0) // color type  (currently always zero)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError,\n\t\t\tttstr(TVPUnsupportedColorTypeColon) + ttstr((int)buf[1])  );\n\n\tif(buf[3] != 0) // external golomb table (currently always zero)\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPUnsupportedExternalGolombBitLengthTable );\n\n\ttjs_int width, height;\n\n\twidth = src->ReadI32LE();\n\theight = src->ReadI32LE();\n\n\ttjs_int max_bit_length;\n\n\tmax_bit_length = src->ReadI32LE();\n\n\t// set destination size\n\tsizecallback(callbackdata, width, height, colors == 3 ? gpfRGB : gpfRGBA);\n\n\t// compute some values\n\ttjs_int x_block_count = (tjs_int)((width - 1)/ TVP_TLG6_W_BLOCK_SIZE) + 1;\n\ttjs_int y_block_count = (tjs_int)((height - 1)/ TVP_TLG6_H_BLOCK_SIZE) + 1;\n\ttjs_int main_count = width / TVP_TLG6_W_BLOCK_SIZE;\n\ttjs_int fraction = width -  main_count * TVP_TLG6_W_BLOCK_SIZE;\n\n\t// prepare memory pointers\n\ttjs_uint8 *bit_pool = NULL;\n\ttjs_uint32 *pixelbuf = NULL; // pixel buffer\n\ttjs_uint8 *filter_types = NULL;\n\ttjs_uint8 *LZSS_text = NULL;\n\ttjs_uint32 *zeroline = NULL;\n\n\ttjs_uint32 *tmpline[2] = { nullptr, nullptr };\n\ttjs_uint8 *grayline;\n\ttry\n\t{\n\t\t// allocate memories\n\t\tbit_pool = (tjs_uint8 *)TJSAlignedAlloc(max_bit_length / 8 + 5, 4);\n\t\tpixelbuf = (tjs_uint32 *)TJSAlignedAlloc(\n\t\t\tsizeof(tjs_uint32) * width * TVP_TLG6_H_BLOCK_SIZE + 1, 4);\n\t\tfilter_types = (tjs_uint8 *)TJSAlignedAlloc(\n\t\t\tx_block_count * y_block_count+16, 4);\n\t\tzeroline = (tjs_uint32 *)TJSAlignedAlloc(width * sizeof(tjs_uint32), 4);\n\t\tLZSS_text = (tjs_uint8*)TJSAlignedAlloc(4096+32, 4) + 16;\n\n\n\t\t// initialize zero line (virtual y=-1 line)\n\t\tTVPFillARGB(zeroline, width, colors==3?0xff000000:0x00000000);\n\t\t\t// 0xff000000 for colors=3 makes alpha value opaque\n\n\t\t// initialize LZSS text (used by chroma filter type codes)\n\t\t{\n\t\t\ttjs_uint32 *p = (tjs_uint32*)LZSS_text;\n\t\t\tfor(tjs_uint32 i = 0; i < 32*0x01010101; i+=0x01010101)\n\t\t\t{\n\t\t\t\tfor(tjs_uint32 j = 0; j < 16*0x01010101; j+=0x01010101)\n\t\t\t\t\tp[0] = i, p[1] = j, p += 2;\n\t\t\t}\n\t\t}\n\n\t\t// read chroma filter types.\n\t\t// chroma filter types are compressed via LZSS as used by TLG5.\n\t\t{\n\t\t\ttjs_int inbuf_size = src->ReadI32LE();\n\t\t\ttjs_uint8* inbuf = (tjs_uint8*)TJSAlignedAlloc(inbuf_size+16, 4);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tsrc->ReadBuffer(inbuf, inbuf_size);\n\t\t\t\tTVPTLG5DecompressSlide(filter_types, inbuf, inbuf_size,\n\t\t\t\t\tLZSS_text, 0);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tTJSAlignedDealloc(inbuf);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tTJSAlignedDealloc(inbuf);\n\t\t}\n\n\t\t// for each horizontal block group ...\n\t\ttjs_uint32 *prevline = zeroline;\n\t\tfor(tjs_int y = 0; y < height; y += TVP_TLG6_H_BLOCK_SIZE)\n\t\t{\n\t\t\ttjs_int ylim = y + TVP_TLG6_H_BLOCK_SIZE;\n\t\t\tif(ylim >= height) ylim = height;\n\n\t\t\ttjs_int pixel_count = (ylim - y) * width;\n\n\t\t\t// decode values\n\t\t\tfor(tjs_int c = 0; c < colors; c++)\n\t\t\t{\n\t\t\t\t// read bit length\n\t\t\t\ttjs_int bit_length = src->ReadI32LE();\n\n\t\t\t\t// get compress method\n\t\t\t\tint method = (bit_length >> 30)&3;\n\t\t\t\tbit_length &= 0x3fffffff;\n\n\t\t\t\t// compute byte length\n\t\t\t\ttjs_int byte_length = bit_length / 8;\n\t\t\t\tif(bit_length % 8) byte_length++;\n\n\t\t\t\t// read source from input\n\t\t\t\tsrc->ReadBuffer(bit_pool, byte_length);\n\n\t\t\t\t// decode values\n\t\t\t\t// two most significant bits of bitlength are\n\t\t\t\t// entropy coding method;\n\t\t\t\t// 00 means Golomb method,\n\t\t\t\t// 01 means Gamma method (not yet suppoted),\n\t\t\t\t// 10 means modified LZSS method (not yet supported),\n\t\t\t\t// 11 means raw (uncompressed) data (not yet supported).\n\n\t\t\t\tswitch(method)\n\t\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tif(c == 0 && colors != 1)\n\t\t\t\t\t\tTVPTLG6DecodeGolombValuesForFirst((tjs_int8*)pixelbuf,\n\t\t\t\t\t\t\tpixel_count, bit_pool);\n\t\t\t\t\telse\n\t\t\t\t\t\tTVPTLG6DecodeGolombValues((tjs_int8*)pixelbuf + c,\n\t\t\t\t\t\t\tpixel_count, bit_pool);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPUnsupportedEntropyCodingMethod );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// for each line\n\t\t\tunsigned char * ft =\n\t\t\t\tfilter_types + (y / TVP_TLG6_H_BLOCK_SIZE)*x_block_count;\n\t\t\tint skipbytes = (ylim-y)*TVP_TLG6_W_BLOCK_SIZE;\n\n\t\t\tfor(int yy = y; yy < ylim; yy++)\n\t\t\t{\n\t\t\t\ttjs_uint32* curline;\n\t\t\t\tif (!palettized)\n\t\t\t\t\tcurline = (tjs_uint32*)scanlinecallback(callbackdata, yy);\n\t\t\t\telse {\n\t\t\t\t\tif (!tmpline[0]) {\n\t\t\t\t\t\ttmpline[0] = (tjs_uint32*)TJSAlignedAlloc(sizeof(tjs_uint32)* width, 4);\n\t\t\t\t\t\ttmpline[1] = (tjs_uint32*)TJSAlignedAlloc(sizeof(tjs_uint32)* width, 4);\n\t\t\t\t\t}\n\t\t\t\t\tcurline = tmpline[yy & 1];\n\t\t\t\t\tgrayline = (tjs_uint8*)scanlinecallback(callbackdata, yy);\n\t\t\t\t}\n\n\t\t\t\tint dir = (yy&1)^1;\n\t\t\t\tint oddskip = ((ylim - yy -1) - (yy-y));\n\t\t\t\tif(main_count)\n\t\t\t\t{\n\t\t\t\t\tint start =\n\t\t\t\t\t\t((width < TVP_TLG6_W_BLOCK_SIZE) ? width : TVP_TLG6_W_BLOCK_SIZE) *\n\t\t\t\t\t\t\t(yy - y);\n\t\t\t\t\tTVPTLG6DecodeLine(\n\t\t\t\t\t\tprevline,\n\t\t\t\t\t\tcurline,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\tmain_count,\n\t\t\t\t\t\tft,\n\t\t\t\t\t\tskipbytes,\n\t\t\t\t\t\tpixelbuf + start, colors==3?0xff000000:0, oddskip, dir);\n\t\t\t\t}\n\n\t\t\t\tif(main_count != x_block_count)\n\t\t\t\t{\n\t\t\t\t\tint ww = fraction;\n\t\t\t\t\tif(ww > TVP_TLG6_W_BLOCK_SIZE) ww = TVP_TLG6_W_BLOCK_SIZE;\n\t\t\t\t\tint start = ww * (yy - y);\n\t\t\t\t\tTVPTLG6DecodeLineGeneric(\n\t\t\t\t\t\tprevline,\n\t\t\t\t\t\tcurline,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\tmain_count,\n\t\t\t\t\t\tx_block_count,\n\t\t\t\t\t\tft,\n\t\t\t\t\t\tskipbytes,\n\t\t\t\t\t\tpixelbuf + start, colors==3?0xff000000:0, oddskip, dir);\n\t\t\t\t}\n\n\t\t\t\tprevline = curline;\n\t\t\t\tif (palettized) {\n\t\t\t\t\tfor (int x = 0; x < width; ++x) {\n\t\t\t\t\t\tgrayline[x] = curline[x] & 0xFF; // red -> lumi\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tscanlinecallback(callbackdata, -1);\n\t\t\t}\n\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(bit_pool) TJSAlignedDealloc(bit_pool);\n\t\tif(pixelbuf) TJSAlignedDealloc(pixelbuf);\n\t\tif(filter_types) TJSAlignedDealloc(filter_types);\n\t\tif(zeroline) TJSAlignedDealloc(zeroline);\n\t\tif(LZSS_text) TJSAlignedDealloc(LZSS_text - 16);\n\t\tif (tmpline[0]) {\n\t\t\tTJSAlignedDealloc(tmpline[0]);\n\t\t\tTJSAlignedDealloc(tmpline[1]);\n\t\t}\n\t\tthrow;\n\t}\n\tif(bit_pool) TJSAlignedDealloc(bit_pool);\n\tif(pixelbuf) TJSAlignedDealloc(pixelbuf);\n\tif(filter_types) TJSAlignedDealloc(filter_types);\n\tif(zeroline) TJSAlignedDealloc(zeroline);\n\tif(LZSS_text) TJSAlignedDealloc(LZSS_text - 16);\n\tif (tmpline[0]) {\n\t\tTJSAlignedDealloc(tmpline[0]);\n\t\tTJSAlignedDealloc(tmpline[1]);\n\t}\n}\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TLG loading handler\n//---------------------------------------------------------------------------\nstatic void TVPInternalLoadTLG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\t// read header\n\tunsigned char mark[12];\n\tsrc->ReadBuffer(mark, 11);\n\n\t// check for TLG raw data\n\tif(!memcmp(\"TLG5.0\\x00raw\\x1a\\x00\", mark, 11))\n\t{\n\t\tTVPLoadTLG5(formatdata, callbackdata, sizecallback,\n\t\t\tscanlinecallback, src, keyidx, mode);\n\t}\n\telse if(!memcmp(\"TLG6.0\\x00raw\\x1a\\x00\", mark, 11))\n\t{\n\t\tTVPLoadTLG6(formatdata, callbackdata, sizecallback,\n\t\t\tscanlinecallback, src, keyidx, mode!=glmNormal);\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPInvalidTlgHeaderOrVersion );\n\t}\n}\n//---------------------------------------------------------------------------\n\nvoid TVPLoadTLG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx,  tTVPGraphicLoadMode mode)\n{\n\t// read header\n\tunsigned char mark[12];\n\tsrc->ReadBuffer(mark, 11);\n\n\t// check for TLG0.0 sds\n\tif(!memcmp(\"TLG0.0\\x00sds\\x1a\\x00\", mark, 11))\n\t{\n\t\t// read TLG0.0 Structured Data Stream\n\n\t\t// TLG0.0 SDS tagged data is simple \"NAME=VALUE,\" string;\n\t\t// Each NAME and VALUE have length:content expression.\n\t\t// eg: 4:LEFT=2:20,3:TOP=3:120,4:TYPE=1:3,\n\t\t// The last ',' cannot be ommited.\n\t\t// Each string (name and value) must be encoded in utf-8.\n\n\t\t// read raw data size\n\t\ttjs_uint rawlen = src->ReadI32LE();\n\n\t\t// try to load TLG raw data\n\t\tTVPInternalLoadTLG(formatdata, callbackdata, sizecallback,\n\t\t\tscanlinecallback, metainfopushcallback, src, keyidx, mode);\n\n\t\t// seek to meta info data point\n\t\tsrc->Seek(rawlen + 11 + 4, TJS_BS_SEEK_SET);\n\n\t\t// read tag data\n\t\twhile(true)\n\t\t{\n\t\t\tchar chunkname[4];\n\t\t\tif(4 != src->Read(chunkname, 4)) break;\n\t\t\t\t// cannot read more\n\t\t\ttjs_uint chunksize = src->ReadI32LE();\n\t\t\tif(!memcmp(chunkname, \"tags\", 4))\n\t\t\t{\n\t\t\t\t// tag information\n\t\t\t\tchar *tag = NULL;\n\t\t\t\tchar *name = NULL;\n\t\t\t\tchar *value = NULL;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\ttag = new char [chunksize + 1];\n\t\t\t\t\tsrc->ReadBuffer(tag, chunksize);\n\t\t\t\t\ttag[chunksize] = 0;\n\t\t\t\t\tif(metainfopushcallback)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst char *tagp = tag;\n\t\t\t\t\t\tconst char *tagp_lim = tag + chunksize;\n\t\t\t\t\t\twhile(tagp < tagp_lim)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttjs_uint namelen = 0;\n\t\t\t\t\t\t\twhile(*tagp >= '0' && *tagp <= '9')\n\t\t\t\t\t\t\t\tnamelen = namelen * 10 + *tagp - '0', tagp++;\n\t\t\t\t\t\t\tif(*tagp != ':') TVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgMalformedTagMissionColonAfterNameLength );\n\t\t\t\t\t\t\ttagp ++;\n\t\t\t\t\t\t\tname = new char [namelen + 1];\n\t\t\t\t\t\t\tmemcpy(name, tagp, namelen);\n\t\t\t\t\t\t\tname[namelen] = '\\0';\n\t\t\t\t\t\t\ttagp += namelen;\n\t\t\t\t\t\t\tif(*tagp != '=') TVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgMalformedTagMissionEqualsAfterName );\n\t\t\t\t\t\t\ttagp++;\n\t\t\t\t\t\t\ttjs_uint valuelen = 0;\n\t\t\t\t\t\t\twhile(*tagp >= '0' && *tagp <= '9')\n\t\t\t\t\t\t\t\tvaluelen = valuelen * 10 + *tagp - '0', tagp++;\n\t\t\t\t\t\t\tif(*tagp != ':') TVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgMalformedTagMissionColonAfterVaueLength );\n\t\t\t\t\t\t\ttagp++;\n\t\t\t\t\t\t\tvalue = new char [valuelen + 1];\n\t\t\t\t\t\t\tmemcpy(value, tagp, valuelen);\n\t\t\t\t\t\t\tvalue[valuelen] = '\\0';\n\t\t\t\t\t\t\ttagp += valuelen;\n \t\t\t\t\t\t\tif(*tagp != ',') TVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPTlgMalformedTagMissionCommaAfterTag );\n\t\t\t\t\t\t\ttagp++;\n\n\t\t\t\t\t\t\t// insert into name-value pairs ... TODO: utf-8 decode\n\t\t\t\t\t\t\tmetainfopushcallback(callbackdata, ttstr(name), ttstr(value));\n\n\t\t\t\t\t\t\tdelete [] name, name = NULL;\n\t\t\t\t\t\t\tdelete [] value, value = NULL;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(...)\n\t\t\t\t{\n\t\t\t\t\tif(tag) delete [] tag;\n\t\t\t\t\tif(name) delete [] name;\n\t\t\t\t\tif(value) delete [] value;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\n\t\t\t\tif(tag) delete [] tag;\n\t\t\t\tif(name) delete [] name;\n\t\t\t\tif(value) delete [] value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// skip the chunk\n\t\t\t\tsrc->SetPosition(src->GetPosition() + chunksize);\n\t\t\t}\n\t\t} // while\n\n\t}\n\telse\n\t{\n\t\tsrc->Seek(0, TJS_BS_SEEK_SET); // rewind\n\n\t\t// try to load TLG raw data\n\t\tTVPInternalLoadTLG(formatdata, callbackdata, sizecallback,\n\t\t\tscanlinecallback, metainfopushcallback, src, keyidx, mode);\n\t}\n\n\n}\n//---------------------------------------------------------------------------\nvoid TVPLoadHeaderTLG(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tif( dic == NULL ) return;\n\n\t// read header\n\tunsigned char mark[12];\n\tsrc->ReadBuffer(mark, 11);\n\n\ttjs_int width = 0;\n\ttjs_int height = 0;\n\ttjs_int colors = 0;\n\t// check for TLG0.0 sds\n\tif(!memcmp(\"TLG0.0\\x00sds\\x1a\\x00\", mark, 11))\n\t{\n\t\t// read raw data size\n\t\ttjs_uint rawlen = src->ReadI32LE();\n\t\tsrc->ReadBuffer(mark, 11);\n\t\tif(!memcmp(\"TLG5.0\\x00raw\\x1a\\x00\", mark, 11))\n\t\t{\n\t\t\tsrc->ReadBuffer(mark, 1);\n\t\t\tcolors = mark[0];\n\t\t\twidth = src->ReadI32LE();\n\t\t\theight = src->ReadI32LE();\n\t\t}\n\t\telse if(!memcmp(\"TLG6.0\\x00raw\\x1a\\x00\", mark, 11))\n\t\t{\n\t\t\tsrc->ReadBuffer(mark, 4);\n\t\t\tcolors = mark[0]; // color component count\n\t\t\twidth = src->ReadI32LE();\n\t\t\theight = src->ReadI32LE();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPInvalidTlgHeaderOrVersion );\n\t\t}\n\t}\n\telse if(!memcmp(\"TLG5.0\\x00raw\\x1a\\x00\", mark, 11))\n\t{\n\t\tsrc->ReadBuffer(mark, 1);\n\t\tcolors = mark[0];\n\t\twidth = src->ReadI32LE();\n\t\theight = src->ReadI32LE();\n\t}\n\telse if(!memcmp(\"TLG6.0\\x00raw\\x1a\\x00\", mark, 11))\n\t{\n\t\tsrc->ReadBuffer(mark, 4);\n\t\tcolors = mark[0]; // color component count\n\t\twidth = src->ReadI32LE();\n\t\theight = src->ReadI32LE();\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPTLGLoadError, (const tjs_char*)TVPInvalidTlgHeaderOrVersion );\n\t}\n\ttjs_int bpp = colors * 8;\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val(width);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic) );\n\tval = tTJSVariant(height);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic) );\n\tval = tTJSVariant(bpp);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic) );\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/LoadTLG.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// TLG5/6 decoder\n//---------------------------------------------------------------------------\n\n#ifndef LoadTLGH\n#define LoadTLGH\n\nextern void TVPLoadTLG(void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback, tTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src, tjs_int keyidx, tTVPGraphicLoadMode mode);\n\n\n#endif\n\n"
  },
  {
    "path": "src/core/visual/LoadWEBP.cpp",
    "content": "#include \"tjsCommHead.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsDictionary.h\"\n#include <memory>\n\n#include \"decode.h\"\nvoid TVPLoadWEBP(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int keyidx,\n\ttTVPGraphicLoadMode mode)\n{\n\tWebPDecoderConfig config;\n\tif (WebPInitDecoderConfig(&config) == 0) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image\"));\n\t}\n\n\tint datasize = src->GetSize();\n\tstd::unique_ptr<uint8_t[]> data(new uint8_t[datasize]);\n\tsrc->ReadBuffer(data.get(), datasize);\n\tif (WebPGetFeatures(data.get(), datasize, &config.input) != VP8_STATUS_OK) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image\"));\n\t}\n\n\tunsigned int stride = sizecallback(callbackdata, config.input.width, config.input.height,\n\t\tconfig.input.has_alpha ? gpfRGBA : gpfRGB);\n#if 0\n\tWebPData webp_data = { data, datasize };\n\tWebPDemuxer* demux = WebPDemux(&webp_data);\n\tWebPChunkIterator chunk_iter;\n\tif (WebPDemuxGetChunk(demux, \"USER\", 1, &chunk_iter)) {\n\t\tchunk_iter.chunk.bytes;\n\t\tWebPDemuxReleaseChunkIterator(&chunk_iter);\n\t}\n\n\tWebPDemuxDelete(demux);\n#endif\n\tuint8_t* scanline = (uint8_t*)scanlinecallback(callbackdata, 0);\n\tif (glmNormal == mode) {\n\t\tconfig.output.colorspace = MODE_RGBA;\n\t\tconfig.output.u.RGBA.rgba = scanline;\n\t\tconfig.output.u.RGBA.stride = stride;\n\t\tconfig.output.u.RGBA.size = config.input.height * stride;\n\t\tconfig.output.is_external_memory = 1;\n\t\tif (WebPDecode(data.get(), datasize, &config) != VP8_STATUS_OK) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image(RGBA mode)\"));\n\t\t}\n\t} else if (glmGrayscale == mode) {\n\t\tconfig.output.colorspace = MODE_YUV;\n\t\tunsigned int uvSize = config.input.width * config.input.height / 4 + config.input.width + config.input.width;\n\t\tstd::unique_ptr<uint8_t[]> dummy(new uint8_t[uvSize]);\n\t\tconfig.output.u.YUVA.y = scanline;\n\t\tconfig.output.u.YUVA.u = dummy.get();\n\t\tconfig.output.u.YUVA.v = dummy.get();\n\t\tconfig.output.u.YUVA.a = nullptr;\n\t\tconfig.output.u.YUVA.y_stride = stride;\n\t\tconfig.output.u.YUVA.u_stride = config.input.width / 2;\n\t\tconfig.output.u.YUVA.v_stride = config.input.width / 2;\n\t\tconfig.output.u.YUVA.a_stride = 0;\n\t\tconfig.output.u.YUVA.y_size = config.input.height * stride;\n\t\tconfig.output.u.YUVA.u_size = uvSize;\n\t\tconfig.output.u.YUVA.v_size = uvSize;\n\t\tconfig.output.u.YUVA.a_size = 0;\n\t\tconfig.output.is_external_memory = 1;\n\n\t\tif (WebPDecode(data.get(), datasize, &config) != VP8_STATUS_OK) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image(Grayscale Mode)\"));\n\t\t}\n\t} else {\n\t\tTVPThrowExceptionMessage(TJS_W(\"WebP does not support palettized image\"));\n\t}\n\tscanlinecallback(callbackdata, -1); // image was written\n}\n\nvoid TVPLoadHeaderWEBP(void* formatdata, tTJSBinaryStream *src, iTJSDispatch2** dic) {\n\tWebPDecoderConfig config;\n\tif (WebPInitDecoderConfig(&config) == 0) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image\"));\n\t}\n\n\tint datasize = src->GetSize();\n\tstd::unique_ptr<uint8_t[]> data(new uint8_t[datasize]);\n\tsrc->ReadBuffer(data.get(), datasize);\n\tif (WebPGetFeatures(data.get(), datasize, &config.input) != VP8_STATUS_OK) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Invalid WebP image\"));\n\t}\n\n\t*dic = TJSCreateDictionaryObject();\n\ttTJSVariant val((tjs_int32)config.input.width);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"width\"), 0, &val, (*dic));\n\tval = tTJSVariant((tjs_int32)config.input.height);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"height\"), 0, &val, (*dic));\n\tval = tTJSVariant(config.input.has_alpha ? 32 : 24);\n\t(*dic)->PropSet(TJS_MEMBERENSURE, TJS_W(\"bpp\"), 0, &val, (*dic));\n}\n"
  },
  {
    "path": "src/core/visual/MenuItemIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"MenuItem\" class interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"MsgIntf.h\"\n#include \"MenuItemIntf.h\"\n#include \"WindowIntf.h\"\n#include \"EventIntf.h\"\n#include \"tjsArray.h\"\n#include \"SystemImpl.h\"\n\n\n//---------------------------------------------------------------------------\n// Input Events\n//---------------------------------------------------------------------------\n// For input event tag\ntTVPUniqueTagForInputEvent tTVPOnMenuItemClickInputEvent      ::Tag;\n//---------------------------------------------------------------------------\n\nstatic const tjs_char* TVPSpecifyMenuItem = TJS_W(\"Please specity MenuItem class object.\");\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseMenuItem\n//---------------------------------------------------------------------------\ntTJSNI_BaseMenuItem::tTJSNI_BaseMenuItem()\n{\n\tOwner = NULL;\n\tWindow = NULL;\n\tParent = NULL;\n\tChildrenArrayValid = false;\n\tChildrenArray = NULL;\n\tArrayClearMethod = NULL;\n\n\tActionOwner.Object = ActionOwner.ObjThis = NULL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\t\ttTJSNI_BaseMenuItem::Construct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj)\n{\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tActionOwner = param[0]->AsObjectClosure();\n\tOwner = tjs_obj;\n\n\tif(numparams >= 2)\n\t{\n\t\tif(param[1]->Type() == tvtObject)\n\t\t{\n\t\t\t// is this Window instance ?\n\t\t\ttTJSVariantClosure clo = param[1]->AsObjectClosureNoAddRef();\n\t\t\tif(clo.Object == NULL) TVPThrowExceptionMessage(TVPSpecifyWindow);\n\t\t\ttTJSNI_Window *win = NULL;\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Window::ClassID, (iTJSNativeInstance**)&win)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyWindow);\n\t\t\tWindow = win;\n\t\t}\n\t}\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseMenuItem::Invalidate()\n{\n\tTVPCancelSourceEvents(Owner);\n\tTVPCancelInputEvents(this);\n\n\t{ // locked\n\t\ttTJSSpinLockHolder holder(Children.Lock);\n\t\ttjs_int count = Children.size();\n\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t{\n\t\t\ttTJSNI_BaseMenuItem *item = Children.at(i);\n\t\t\tif(!item) continue;\n\n\t\t\tif(item->Owner)\n\t\t\t{\n\t\t\t\titem->Owner->Invalidate(0, NULL, NULL, item->Owner);\n\t\t\t\titem->Owner->Release();\n\t\t\t}\n\t\t}\n\t\tChildren.clear();\n\t} // locked\n\n//\tOwner = NULL;\n\tWindow = NULL;\n\tParent = NULL;\n\n\tif(ChildrenArray) ChildrenArray->Release(), ChildrenArray = NULL;\n\tif(ArrayClearMethod) ArrayClearMethod->Release(), ArrayClearMethod = NULL;\n\n\tActionOwner.Release();\n\tActionOwner.ObjThis = ActionOwner.Object = NULL;\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\ntTJSNI_MenuItem * tTJSNI_BaseMenuItem::CastFromVariant(const tTJSVariant & from)\n{\n\tif(from.Type() == tvtObject)\n\t{\n\t\t// is this Window instance ?\n\t\ttTJSVariantClosure clo = from.AsObjectClosureNoAddRef();\n\t\tif(clo.Object == NULL) TVPThrowExceptionMessage(TVPSpecifyMenuItem);\n\t\ttTJSNI_MenuItem *menuitem = NULL;\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_MenuItem::ClassID, (iTJSNativeInstance**)&menuitem)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyMenuItem);\n\t\treturn menuitem;\n\t}\n\tTVPThrowExceptionMessage(TVPSpecifyMenuItem);\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseMenuItem::AddChild(tTJSNI_BaseMenuItem *item)\n{\n\tif(Children.Add(item))\n\t{\n\t\tChildrenArrayValid = false;\n\t\tif(item->Owner) item->Owner->AddRef();\n\t\titem->Parent = this;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseMenuItem::RemoveChild(tTJSNI_BaseMenuItem *item)\n{\n\tif(Children.Remove(item))\n\t{\n\t\tChildrenArrayValid = false;\n\t\tif(item->Owner) item->Owner->Release();\n\t\titem->Parent = NULL;\n\t}\n}\n//---------------------------------------------------------------------------\niTJSDispatch2 * tTJSNI_BaseMenuItem::GetChildrenArrayNoAddRef()\n{\n\tif(!ChildrenArray)\n\t{\n\t\t// create an Array object\n\t\tiTJSDispatch2 * classobj;\n\t\tChildrenArray = TJSCreateArrayObject(&classobj);\n\t\ttry\n\t\t{\n\t\t\ttTJSVariant val;\n\t\t\ttjs_error er;\n\t\t\ter = classobj->PropGet(0, TJS_W(\"clear\"), NULL, &val, classobj);\n\t\t\t\t// retrieve clear method\n\t\t\tif(TJS_FAILED(er)) TVPThrowInternalError;\n\t\t\tArrayClearMethod = val.AsObject();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tChildrenArray->Release();\n\t\t\tChildrenArray = NULL;\n\t\t\tclassobj->Release();\n\t\t\tthrow;\n\t\t}\n\t\tclassobj->Release();\n\t}\n\n\tif(!ChildrenArrayValid)\n\t{\n\t\t// re-create children list\n\t\tArrayClearMethod->FuncCall(0, NULL, NULL, NULL, 0, NULL, ChildrenArray);\n\t\t\t// clear array\n\n\t\t{ // locked\n\t\t\ttTJSSpinLockHolder holder(Children.Lock);\n\t\t\ttjs_int count = Children.size();\n\t\t\ttjs_int itemcount = 0;\n\t\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\ttTJSNI_BaseMenuItem *item = Children.at(i);\n\t\t\t\tif(!item) continue;\n\n\t\t\t\tiTJSDispatch2 * dsp = item->Owner;\n\t\t\t\ttTJSVariant val(dsp, dsp);\n\t\t\t\tChildrenArray->PropSetByNum(TJS_MEMBERENSURE, itemcount, &val,\n\t\t\t\t\tChildrenArray);\n\t\t\t\titemcount++;\n\t\t\t}\n\t\t} // locked\n\n\t\tChildrenArrayValid = true;\n\t}\n\n\treturn ChildrenArray;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseMenuItem::OnClick(void)\n{\n\t// fire onClick event\n\tif(!CanDeliverEvents()) return;\n\n\t// also check window\n\ttTJSNI_BaseMenuItem *item = this;\n\twhile(!item->Window)\n\t{\n\t\tif(!item->Parent) break;\n\t\titem = item->Parent;\n\t}\n\tif(!item->Window) return;\n\tif(!item->Window->CanDeliverEvents()) return;\n\n\t// fire event\n\tstatic ttstr eventname(TJS_W(\"onClick\"));\n\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\tTVPDoSaveSystemVariables();\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseMenuItem * tTJSNI_BaseMenuItem::GetRootMenuItem() const\n{\n\ttTJSNI_BaseMenuItem * current = const_cast<tTJSNI_BaseMenuItem*>(this);\n\ttTJSNI_BaseMenuItem * parent = current->GetParent();\n\twhile (parent)\n\t{\n\t\tcurrent = parent;\n\t\tparent = current->GetParent();\n\t}\n\treturn current;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_MenuItem\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_MenuItem::ClassID = -1;\ntTJSNC_MenuItem::tTJSNC_MenuItem() : inherited(TJS_W(\"MenuItem\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(MenuItem) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_MenuItem,\n\t/*TJS class name*/MenuItem)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/MenuItem)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/add)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n \ttTJSNI_MenuItem * item = tTJSNI_BaseMenuItem::CastFromVariant(*param[0]);\n \t_this->Add(item);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/add)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/insert)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n \ttTJSNI_MenuItem * item = tTJSNI_BaseMenuItem::CastFromVariant(*param[0]);\n \ttjs_int index = *param[1];\n \t_this->Insert(item, index);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/insert)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/remove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n \ttTJSNI_MenuItem * item = tTJSNI_BaseMenuItem::CastFromVariant(*param[0]);\n \t_this->Remove(item);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/remove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/popup) // not trackPopup\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\ttjs_uint32 flags = (tTVInteger)*param[0];\n\ttjs_int x = *param[1];\n\ttjs_int y = *param[2];\n\ttjs_int rv = _this->TrackPopup(flags, x, y);\n\tif (result) *result = rv;\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/popup) // not trackPopup\n//---------------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MenuItem);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(0, \"onClick\", objthis);\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/fireClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_MenuItem);\n\n\t_this->OnClick();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/fireClick)\n//----------------------------------------------------------------------\n\n//--properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(caption)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\tttstr res;\n\t\t_this->GetCaption(res);\n\t\t*result = res;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetCaption(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(caption)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(checked)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t*result = _this->GetChecked();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetChecked(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(checked)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enabled)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t*result = _this->GetEnabled();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetEnabled(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(enabled)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(group)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t*result = _this->GetGroup();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetGroup((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(group)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(radio)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t*result = _this->GetRadio();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetRadio(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(radio)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(shortcut)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\tttstr res;\n\t\t_this->GetShortcut(res);\n\t\t*result = res;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetShortcut(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(shortcut)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t*result = _this->GetVisible();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetVisible(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(visible)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(parent)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\ttTJSNI_BaseMenuItem *parent = _this->GetParent();\n\t\tif(parent)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = parent->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2 *)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(parent)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(children)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\tiTJSDispatch2 *dsp = _this->GetChildrenArrayNoAddRef();\n\t\t*result = tTJSVariant(dsp, dsp);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(children)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(root) // not rootMenuItem\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\ttTJSNI_BaseMenuItem * root = _this->GetRootMenuItem();\n\t\tif (root)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = root->GetOwnerNoAddRef();\n\t\t\tif (result) *result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (result) *result = tTJSVariant((iTJSDispatch2 *)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(root) // not rootMenuItem\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(window)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\ttTJSNI_Window * window = _this->GetWindow();\n\t\tif (window)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = window->GetOwnerNoAddRef();\n\t\t\tif (result) *result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (result) *result = tTJSVariant((iTJSDispatch2 *)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(window)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(index)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\tif (result) *result = (tTVInteger)_this->GetIndex();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\t_this->SetIndex((tjs_int)(*param));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(index)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateMenuItemObject(iTJSDispatch2 * window)\n{\n\tstruct tHolder\n\t{\n\t\tiTJSDispatch2 * Obj;\n\t\ttHolder() { Obj = new tTJSNC_MenuItem(); }\n\t\t~tHolder() { Obj->Release(); }\n\t} static menuitemclass;\n\n\tiTJSDispatch2 *out;\n\ttTJSVariant param(window);\n\ttTJSVariant *pparam[2] = {&param, &param};\n\tif(TJS_FAILED(menuitemclass.Obj->CreateNew(0, NULL, NULL, &out, 2, pparam,\n\t\tmenuitemclass.Obj)))\n\t\tTVPThrowExceptionMessage(TVPInternalError,\n\t\t\tTJS_W(\"TVPCreateMenuItemObject\"));\n\n\treturn out;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/MenuItemIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"MenuItem\" class interface\n//---------------------------------------------------------------------------\n#ifndef MenuItemIntfH\n#define MenuItemIntfH\n\n#include \"tjsNative.h\"\n#include \"EventIntf.h\"\n#include \"ObjectList.h\"\n#include <algorithm>\n\ntemplate <typename T>\nstruct ObjectVector : public std::vector<T*> { // thread safe vector\n\ttTJSSpinLock Lock;\n\n\ttjs_int Find(const T * object) const {\n\t\ttTJSSpinLockHolder holder(((ObjectVector*)this)->Lock);\n\t\tauto it = std::find(this->begin(), this->end(), object);\n\t\tif (it == this->end()) return -1;\n\t\treturn it - this->begin();\n\t}\n\n\tbool Add(T* object, tjs_int idx = -1) {\n\t\ttTJSSpinLockHolder holder(Lock);\n\t\tif (std::find(this->begin(), this->end(), object) != this->end()) return false;\n\t\tif (idx == -1)\n\t\t\tthis->push_back(object);\n\t\telse\n\t\t\tthis->insert(this->begin() + idx, object);\n\t\treturn true;\n\t}\n\n\tbool Remove(T* object) {\n\t\ttTJSSpinLockHolder holder(Lock);\n\t\tauto it = std::find(this->begin(), this->end(), object);\n\t\tif (it == this->end()) return false;\n\t\tthis->erase(it);\n\t\treturn true;\n\t}\n};\n\n//---------------------------------------------------------------------------\n// tTJSNI_MenuItem\n//---------------------------------------------------------------------------\nclass tTJSNI_Window;\nclass tTJSNI_MenuItem;\nclass tTJSNI_BaseMenuItem : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\tfriend class tTJSNI_MenuItem;\nprotected:\n\tObjectVector<tTJSNI_BaseMenuItem> Children;\n\ttTJSNI_Window *Window;\n\n\tiTJSDispatch2 *Owner;\n\ttTJSVariantClosure ActionOwner; // object to send action\n\n\ttTJSNI_BaseMenuItem *Parent;\n\n\tbool ChildrenArrayValid;\n\tiTJSDispatch2 * ChildrenArray;\n\tiTJSDispatch2 * ArrayClearMethod;\n\npublic:\n\ttTJSNI_BaseMenuItem();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\tstatic tTJSNI_MenuItem * CastFromVariant(const tTJSVariant & from);\n\nprotected:\n\tvirtual bool CanDeliverEvents() const = 0; // must be implemented in each platforms\n\nprotected:\n\tvoid AddChild(tTJSNI_BaseMenuItem *item);\n\tvoid RemoveChild(tTJSNI_BaseMenuItem *item);\n\npublic:\n\tvirtual void Add(tTJSNI_MenuItem * item) = 0;\n\tvirtual void Insert(tTJSNI_MenuItem *item, tjs_int index) = 0;\n\tvirtual void Remove(tTJSNI_MenuItem *item) = 0;\n\npublic:\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n\n\tiTJSDispatch2 * GetOwnerNoAddRef() const { return Owner; }\n\n\ttTJSNI_BaseMenuItem * GetParent() const { return Parent; }\n\n\ttTJSNI_BaseMenuItem * GetRootMenuItem() const;\n\n\ttTJSNI_Window * GetWindow() const { return Window; }\n\n\tiTJSDispatch2 * GetChildrenArrayNoAddRef();\n\n\npublic:\n\tvoid OnClick(void); // fire onClick event\n};\n//---------------------------------------------------------------------------\n\n#include \"MenuItemImpl.h\" // must define tTJSNI_MenuItem class\n\n//---------------------------------------------------------------------------\n// tTJSNC_MenuItem : TJS MenuItem class\n//---------------------------------------------------------------------------\nclass tTJSNC_MenuItem : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_MenuItem();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNC_MenuItem.\n\t*/\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_MenuItem();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNC_MenuItem.\n\t\tusually simple returns: new tTJSNC_MenuItem();\n\t*/\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nextern iTJSDispatch2 * TVPCreateMenuItemObject(iTJSDispatch2 * window);\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPMenuItemOnClickInputEvent : onClick input event class\n//---------------------------------------------------------------------------\nclass tTVPOnMenuItemClickInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnMenuItemClickInputEvent(tTJSNI_BaseMenuItem *menu) :\n\t\ttTVPBaseInputEvent(menu, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseMenuItem*)GetSource())->OnClick(); }\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/visual/PrerenderedFont.cpp",
    "content": "\n#include \"PrerenderedFont.h\"\n#include \"BinaryStream.h\"\n#include \"MsgIntf.h\"\n#include \"tvpgl.h\"\n\nextern tTJSHashTable<ttstr, tTVPPrerenderedFont *> TVPPrerenderedFonts;\n\ntTVPPrerenderedFont::tTVPPrerenderedFont(const ttstr &storage)\n//\t: LocalStorage(storage)\n{\n\tRefCount = 1;\n\tStorage = storage;\n\n\ttTJSBinaryStream* stream = TVPCreateBinaryStreamForRead( storage, TJS_W(\"\") );\n\tif( stream == NULL ) {\n\t\tTVPThrowExceptionMessage(TVPCannotOpenStorage, storage);\n\t}\n\n\tImage = NULL;\n\ttry {\n\t\tFileLength = stream->GetSize();\n\t\tif( FileLength == 0 ) {\n\t\t\tTVPThrowExceptionMessage( TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPFileSizeIsZero );\n\t\t}\n\t\tImage = new tjs_uint8[(tjs_uint)FileLength];\n\t\tif( Image == NULL ) {\n\t\t\tTVPThrowExceptionMessage( TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPMemoryAllocationError );\n\t\t}\n\t\ttjs_uint readsize = stream->Read( const_cast<tjs_uint8*>(Image), (tjs_uint)FileLength );\n\t\tif( readsize != FileLength ) {\n\t\t\tTVPThrowExceptionMessage( TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPFileReadError );\n\t\t}\n\t\tdelete stream;\n\t\tstream = NULL;\n\n\t\t// check header\n\t\tif( memcmp(\"TVP pre-rendered font\\x1a\", Image, 22) ) {\n\t\t\tTVPThrowExceptionMessage(TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPInvalidPrerenderedFontFile );\n\t\t}\n\n\t\tif( Image[23] != 2 ) {\n\t\t\tTVPThrowExceptionMessage(TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPNot16BitUnicodeFontFile );\n\t\t}\n\n\t\tVersion = Image[22];\n\t\tif( Version != 0 && Version != 1 ) {\n\t\t\tTVPThrowExceptionMessage(TVPPrerenderedFontMappingFailed, (const tjs_char*)TVPInvalidHeaderVersion );\n\t\t}\n\n\t\t// read index offset\n\t\tIndexCount = *(const tjs_uint32*)(Image + 24);\n\t\tChIndex = (const tjs_char*)(Image + *(const tjs_uint32*)(Image + 28));\n\t\tIndex = (const tTVPPrerenderedCharacterItem*)(Image + *(const tjs_uint32*)(Image + 32));\n\t} catch(...) {\n\t\tif( stream ) delete stream;\n\t\tif( Image ) delete[] Image;\n\t\tthrow;\n\t}\n\tTVPPrerenderedFonts.Add(storage, this);\n}\n//---------------------------------------------------------------------------\ntTVPPrerenderedFont::~tTVPPrerenderedFont()\n{\n\tif( Image ) delete[] Image;\n\n\tTVPPrerenderedFonts.Delete(Storage);\n}\n//---------------------------------------------------------------------------\nvoid tTVPPrerenderedFont::AddRef()\n{\n\tRefCount ++;\n}\n//---------------------------------------------------------------------------\nvoid tTVPPrerenderedFont::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount --;\n}\n//---------------------------------------------------------------------------\nconst tTVPPrerenderedCharacterItem *\n\t\ttTVPPrerenderedFont::Find(tjs_char ch)\n{\n\t// search through ChIndex\n\ttjs_uint s = 0;\n\ttjs_uint e = IndexCount;\n\tconst tjs_char *chindex = ChIndex;\n\twhile(true)\n\t{\n\t\ttjs_int d = e-s;\n\t\tif(d <= 1)\n\t\t{\n\t\t\tif(chindex[s] == ch)\n\t\t\t\treturn Index + s;\n\t\t\telse\n\t\t\t\treturn NULL;\n\t\t}\n\t\ttjs_uint m = s + (d>>1);\n\t\tif(chindex[m] > ch) e = m; else s = m;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPPrerenderedFont::Retrieve(const tTVPPrerenderedCharacterItem * item,\n\ttjs_uint8 *buffer, tjs_int bufferpitch)\n{\n\t// retrieve font data and store to buffer\n\t// bufferpitch must be larger then or equal to item->Width\n\tif(item->Width == 0 || item->Height == 0) return;\n\n\tconst tjs_uint8 *ptr = item->Offset + Image;\n\ttjs_uint8 *dest = buffer;\n\ttjs_uint8 *destlim = dest + item->Width * item->Height;\n\n\t// expand compressed character bitmap data\n\tif(Version == 0)\n\t{\n\t\t// version 0 decompressor\n\t\twhile(dest < destlim)\n\t\t{\n\t\t\tif(*ptr == 0x41) // running\n\t\t\t{\n\t\t\t\tptr++;\n\t\t\t\ttjs_uint8 last = dest[-1];\n\t\t\t\ttjs_int len = *ptr;\n\t\t\t\tptr++;\n\t\t\t\twhile(len--) *(dest++) = (tjs_uint8)last;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t*(dest++) = *(ptr++);\n\t\t\t}\n\t\t}\n\t}\n\telse if(Version >= 1)\n\t{\n\t\t// version 1+ decompressor\n\t\twhile(dest < destlim)\n\t\t{\n\t\t\tif(*ptr >= 0x41) // running\n\t\t\t{\n\t\t\t\ttjs_int len = *ptr - 0x40;\n\t\t\t\tptr++;\n\t\t\t\ttjs_uint8 last = dest[-1];\n\t\t\t\twhile(len--) *(dest++) = (tjs_uint8)last;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t*(dest++) = *(ptr++);\n\t\t\t}\n\t\t}\n\t}\n\n\tTVPUpscale65_255(buffer, item->Width * item->Height);\n\n\t// expand to each pitch\n\tptr = destlim - item->Width;\n\tdest = buffer + bufferpitch * item->Height - bufferpitch;\n\twhile(buffer <= dest)\n\t{\n\t\tif(dest != ptr)\n\t\t\tmemmove(dest, ptr, item->Width);\n\t\tdest -= bufferpitch;\n\t\tptr -= item->Width;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/visual/PrerenderedFont.h",
    "content": "\n#ifndef __TVP_PRERENDERED_FONT_H__\n#define __TVP_PRERENDERED_FONT_H__\n\n#include \"tjsCommHead.h\"\n#include \"UtilStreams.h\"\n\n#pragma pack(push, 1)\nstruct tTVPPrerenderedCharacterItem\n{\n\ttjs_uint32 Offset;\n\ttjs_uint16 Width;\n\ttjs_uint16 Height;\n\ttjs_int16 OriginX;\n\ttjs_int16 OriginY;\n\ttjs_int16 IncX;\n\ttjs_int16 IncY;\n\ttjs_int16 Inc;\n\ttjs_uint16 Reserved;\n};\n#pragma pack(pop)\n\n//---------------------------------------------------------------------------\n// tTVPPrerenderedFont\n//---------------------------------------------------------------------------\nclass tTVPPrerenderedFont\n{\nprivate:\n\tttstr Storage;\n\t// HANDLE FileHandle; // tft file handle\n\t// HANDLE MappingHandle; // file mapping handle\n\t// t@C}bsOł͂ȂASčŏɃf[^ǂݍł܂`ɂB\n\t// BinaryStream œǂݍ\n\tconst tjs_uint8 * Image; // tft mapped memory\n\ttjs_uint64 FileLength;\n\ttjs_uint RefCount;\n//\ttTVPLocalTempStorageHolder LocalStorage;\n\n\ttjs_int Version; // data version\n\tconst tjs_char * ChIndex;\n\tconst tTVPPrerenderedCharacterItem * Index;\n\ttjs_uint IndexCount;\n\npublic:\n\ttTVPPrerenderedFont(const ttstr &storage);\n\t~tTVPPrerenderedFont();\n\tvoid AddRef();\n\tvoid Release();\n\n\tconst tTVPPrerenderedCharacterItem* Find(tjs_char ch); // serch character\n\tvoid Retrieve(const tTVPPrerenderedCharacterItem * item, tjs_uint8 *buffer, tjs_int bufferpitch);\n\n};\n\n#endif // __TVP_PRERENDERED_FONT_H__\n\n"
  },
  {
    "path": "src/core/visual/RectItf.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"RectItf.h\"\n#include \"MsgIntf.h\"\n\ntTJSNI_Rect::tTJSNI_Rect() : Rect(0,0,0,0) {\n}\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_Rect::Construct(tjs_int numparams, tTJSVariant **param,\n\tiTJSDispatch2 *tjs_obj) {\n\tif( numparams > 0 ) {\n\t\tif( numparams == 1 ) {\n\t\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\t\ttTJSNI_Rect* src = NULL;\n\t\t\tif( clo.Object == NULL  ) return TJS_E_INVALIDPARAM;\n\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\treturn TJS_E_INVALIDPARAM;\n\n\t\t\tRect.left = src->Get().left;\n\t\t\tRect.top = src->Get().top;\n\t\t\tRect.right = src->Get().right;\n\t\t\tRect.bottom = src->Get().bottom;\n\t\t} else if( numparams == 4 ) {\n\t\t\tRect.left = *param[0];\n\t\t\tRect.top = *param[1];\n\t\t\tRect.right = *param[2];\n\t\t\tRect.bottom = *param[3];\n\t\t}\n\t}\n\treturn TJS_S_OK;\n}\nvoid TJS_INTF_METHOD tTJSNI_Rect::Invalidate() {\n}\n\n\ntjs_uint32 tTJSNC_Rect::ClassID = -1;\ntTJSNC_Rect::tTJSNC_Rect() : inherited(TJS_W(\"Rect\") ) {\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Rect) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Rect,\n\t/*TJS class name*/Rect)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Rect)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/isEmpty)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(result) *result = (tjs_int)( _this->IsEmpty() ? 1 : 0 );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/isEmpty)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetSize( *param[0], *param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setOffset)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetOffset( *param[0], *param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setOffset)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addOffset)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->AddOffset( *param[0], *param[1] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/addOffset)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clear)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t_this->Clear();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/clear)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/set)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\t_this->Set( *param[0], *param[1], *param[2], *param[3] );\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/set)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clip)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Rect* src = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\ttjs_int ret = _this->Clip( *src ) ? 1 : 0;\n\t\tif(result) *result = ret;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/clip)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/union)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Rect* src = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\ttjs_int ret = _this->Union( *src ) ? 1 : 0;\n\t\tif(result) *result = ret;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/union)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/intersects)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Rect* src = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\ttjs_int ret = _this->Intersects( *src ) ? 1 : 0;\n\t\tif(result) *result = ret;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/intersects)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/included)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Rect* src = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\ttjs_int ret = _this->Included( *src ) ? 1 : 0;\n\t\tif(result) *result = ret;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/included)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/includedPos)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\ttjs_int ret = _this->Included( *param[0], *param[1] ) ? 1 : 0;\n\tif(result) *result = ret;\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/includedPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/equal)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\ttTJSNI_Rect* src = NULL;\n\tif( clo.Object ) {\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Rect::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\treturn TJS_E_INVALIDPARAM;\n\t\ttjs_int ret = _this->Equal( *src ) ? 1 : 0;\n\t\tif(result) *result = ret;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/equal)\n//----------------------------------------------------------------------\n\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->SetWidth( *param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->SetHeight( *param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(left)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->Get().left;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->Get().left = *param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(left)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(top)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->Get().top;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->Get().top = *param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(top)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(right)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->Get().right;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->Get().right = *param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(right)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(bottom)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = _this->Get().bottom;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t_this->Get().bottom = *param;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(bottom)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(nativeArray)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Rect);\n\t\t*result = (tTVInteger)(tjs_intptr_t)_this->Get().array;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(nativeArray)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n}\n\ntTJSNativeInstance *tTJSNC_Rect::CreateNativeInstance() {\n\treturn new tTJSNI_Rect();\n}\n\n\n\n//---------------------------------------------------------------------------\niTJSDispatch2 * TVPCreateRectObject( tjs_int left, tjs_int top, tjs_int right, tjs_int bottom )\n{\n\tstruct tHolder\n\t{\n\t\tiTJSDispatch2 * Obj;\n\t\ttHolder() { Obj = new tTJSNC_Rect(); }\n\t\t~tHolder() { Obj->Release(); }\n\t} static rectclass;\n\n\tiTJSDispatch2 *out;\n\ttTJSVariant param[4] = { left, top, right, bottom};\n\ttTJSVariant *pparam[4] = { param, param+1, param+2, param+3 };\n\ttjs_error hr = rectclass.Obj->CreateNew(0, NULL, NULL, &out, 4, pparam, rectclass.Obj);\n\tif(TJS_FAILED(hr)) TVPThrowInternalError;\n\n\treturn out;\n}\n\n\ntTJSNativeClass * TVPCreateNativeClass_Rect()\n{\n\ttTJSNativeClass *cls = new tTJSNC_Rect();\n\treturn cls;\n}"
  },
  {
    "path": "src/core/visual/RectItf.h",
    "content": "\n\n#ifndef RectIntfH\n#define RectIntfH\n\n#include \"tjsNative.h\"\n#include \"ComplexRect.h\"\n\nclass tTJSNI_Rect : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\nprotected:\n\ttTVPRect Rect;\n\npublic:\n\ttTJSNI_Rect();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\ttTVPRect& Get() { return Rect; }\n\tconst tTVPRect& Get() const { return Rect; }\n\n\tvoid SetWidth(tjs_int width) {\n\t\tRect.set_width( width );\n\t}\n\ttjs_int GetWidth() const {\n\t\treturn Rect.get_width();\n\t}\n\tvoid SetHeight(tjs_int height) {\n\t\tRect.set_height( height );\n\t}\n\ttjs_int GetHeight() const {\n\t\treturn Rect.get_height();\n\t}\n\n\tvoid SetOffset( tjs_int x, tjs_int y ) {\n\t\tRect.set_offsets( x, y );\n\t}\n\tvoid AddOffset( tjs_int x, tjs_int y ) {\n\t\tRect.add_offsets( x, y );\n\t}\n\tvoid SetSize(tjs_int width, tjs_int height) {\n\t\tRect.set_size( width, height );\n\t}\n\tvoid Clear() {\n\t\tRect.clear();\n\t}\n\tvoid Set( tjs_int left, tjs_int top, tjs_int right, tjs_int bottom ) {\n\t\tRect.left = left;\n\t\tRect.top = top;\n\t\tRect.right = right;\n\t\tRect.bottom = bottom;\n\t}\n\n\tbool IsEmpty() const {\n\t\treturn Rect.is_empty();\n\t}\n\tbool Clip( const tTJSNI_Rect& r ) {\n\t\treturn Rect.clip( r.Rect );\n\t}\n\tbool Union( const tTJSNI_Rect& r ) {\n\t\treturn TVPUnionRect( &Rect, Rect, r.Rect );\n\t}\n\tbool Intersects( const tTJSNI_Rect& r ) const {\n\t\treturn Rect.intersects_with( r.Rect );\n\t}\n\tbool Included( const tTJSNI_Rect& r ) const {\n\t\treturn Rect.included_in( r.Rect );\n\t}\n\tbool Included( tjs_int x, tjs_int y  ) const {\n\t\treturn ( x >= Rect.left && x < Rect.right ) && ( y >= Rect.top && y < Rect.bottom );\n\t}\n\tbool Equal( const tTJSNI_Rect& r ) {\n\t\treturn Rect == r.Rect;\n\t}\n};\n\n\nclass tTJSNC_Rect : public tTJSNativeClass\n{\n\ttypedef tTJSNativeClass inherited;\n\npublic:\n\ttTJSNC_Rect();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n\nextern iTJSDispatch2 * TVPCreateRectObject( tjs_int left, tjs_int top, tjs_int right, tjs_int bottom );\nextern tTJSNativeClass * TVPCreateNativeClass_Rect();\n#endif // RectIntfH\n"
  },
  {
    "path": "src/core/visual/RenderManager.cpp",
    "content": "#include \"RenderManager.h\"\n#include \"renderer/CCTexture2D.h\"\ntypedef cocos2d::Texture2D::PixelFormat CCPixelFormat;\n#include \"MsgIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"tvpgl.h\"\n#include <assert.h>\n#include <algorithm>\n#include \"ThreadIntf.h\"\n#include \"argb.h\"\nextern \"C\" {\n#include <stdint.h>\n#ifndef UINT64_C\n#define UINT64_C(x)  (x ## ULL)\n#endif\n#ifndef __STDC_CONSTANT_MACROS\n#define __STDC_CONSTANT_MACROS\n#endif\n#include \"libswscale/swscale.h\"\n};\n#include \"opencv2/opencv.hpp\"\n#include \"Application.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"xxhash/xxhash.h\"\n#include \"tjsHashSearch.h\"\n#include \"EventIntf.h\"\n#include \"lz4/lz4.h\"\n\n#ifdef _MSC_VER\n#pragma comment(lib,\"opencv_ts300d.lib\")\n// #pragma comment(lib,\"ippicvmt.lib\")\n// #pragma comment(lib,\"opencv_core300d.lib\")\n// #pragma comment(lib,\"opencv_imgproc300d.lib\")\n// #pragma comment(lib,\"opencv_hal300d.lib\")\n#pragma comment(lib,\"opencv_world300d.lib\")\n#endif\n\n//#define USE_SWSCALE\n#define USE_CV_AFFINE\n\n//---------------------------------------------------------------------------\n// heap allocation functions for bitmap bits\n//---------------------------------------------------------------------------\ntypedef uint32_t tTJSPointerSizedInteger;\n// this must be a integer type that has the same size with the normal\n// pointer ( void *)\n//---------------------------------------------------------------------------\n#pragma pack(push, 1)\nstruct tTVPLayerBitmapMemoryRecord\n{\n\tvoid * alloc_ptr; // allocated pointer\n\ttjs_uint size; // original bmp bits size, in bytes\n\ttjs_uint32 sentinel_backup1; // sentinel value 1\n\ttjs_uint32 sentinel_backup2; // sentinel value 2\n};\n#pragma pack(pop)\n\n#ifdef WIN32\n//#define CHECK_MEM_OVERRUN\n#define MEM_COMMIT           0x1000     \n#define MEM_DECOMMIT         0x4000     \n#define PAGE_NOACCESS          0x01     \n#define PAGE_READWRITE         0x04     \n#endif\n\nstatic uint64_t _totalVMemSize = 0;\n\n//---------------------------------------------------------------------------\nstatic void * TVPAllocBitmapBits(tjs_uint size, tjs_uint width, tjs_uint height)\n{\n\tif (size == 0) return NULL;\n\n#if defined(WIN32) && defined(CHECK_MEM_OVERRUN)\n\t{\n\t\ttjs_uint8 * ptr; size += sizeof(tTVPLayerBitmapMemoryRecord);\n\t\tuint32_t pagesize = (size + 4095) & ~4095;\n\t\tptr = (tjs_uint8*)malloc(pagesize + 8192);\n\t\tuint8_t * p = (uint8_t*)(((intptr_t)ptr + 4095) & ~4095);\n\t\ttTVPLayerBitmapMemoryRecord* hdr = (tTVPLayerBitmapMemoryRecord*)(p + pagesize - size);\n\t\tDWORD old;\n\t\tVirtualProtect(p + pagesize, 4096, PAGE_NOACCESS, &old);\n\t\thdr->alloc_ptr = ptr;\n\t\thdr->size = size;\n\t\treturn hdr + 1;\n\t}\n#endif\n\n\ttjs_uint8 * ptrorg, *ptr;\n\ttjs_uint allocbytes = 16 + size + sizeof(tTVPLayerBitmapMemoryRecord)+sizeof(tjs_uint32)* 2;\n\tTVPCheckMemory();\n\tptr = ptrorg = (tjs_uint8*)malloc(allocbytes);\n\tif (!ptr) TVPThrowExceptionMessage(TVPCannotAllocateBitmapBits,\n\t\tTJS_W(\"at TVPAllocBitmapBits\"), ttstr((tjs_int)allocbytes) + TJS_W(\"(\") +\n\t\tttstr((int)width) + TJS_W(\"x\") + ttstr((int)height) + TJS_W(\")\"));\n\t// align to a paragraph ( 16-bytes )\n\tptr += 16 + sizeof(tTVPLayerBitmapMemoryRecord);\n\t*reinterpret_cast<tTJSPointerSizedInteger*>(&ptr) >>= 4;\n\t*reinterpret_cast<tTJSPointerSizedInteger*>(&ptr) <<= 4;\n\n\ttTVPLayerBitmapMemoryRecord * record =\n\t\t(tTVPLayerBitmapMemoryRecord*)\n\t\t(ptr - sizeof(tTVPLayerBitmapMemoryRecord)-sizeof(tjs_uint32));\n\n\t// fill memory allocation record\n\trecord->alloc_ptr = (void *)ptrorg;\n\trecord->size = size;\n\trecord->sentinel_backup1 = rand() + (rand() << 16);\n\trecord->sentinel_backup2 = rand() + (rand() << 16);\n\n\t// set sentinel\n\t*(tjs_uint32*)(ptr - sizeof(tjs_uint32)) = ~record->sentinel_backup1;\n\t*(tjs_uint32*)(ptr + size) = ~record->sentinel_backup2;\n\t// Stored sentinels are nagated, to avoid that the sentinel backups in\n\t// tTVPLayerBitmapMemoryRecord becomes the same value as the sentinels.\n\t// This trick will make the detection of the memory corruption easier.\n\t// Because on some occasions, running memory writing will write the same\n\t// values at first sentinel and the tTVPLayerBitmapMemoryRecord.\n\n\t// return buffer pointer\n\treturn ptr;\n}\n//---------------------------------------------------------------------------\nstatic void TVPFreeBitmapBits(void *ptr)\n{\n\tif (ptr)\n\t{\n#if defined(WIN32) && defined(CHECK_MEM_OVERRUN)\n\t\ttjs_uint8 * p = ((tjs_uint8 *)ptr) - sizeof(tTVPLayerBitmapMemoryRecord);\n\t\ttTVPLayerBitmapMemoryRecord* hdr = (tTVPLayerBitmapMemoryRecord*)p;\n\t\tDWORD old;\n\t\tVirtualProtect(p + hdr->size, 4096, PAGE_READWRITE, &old);\n\t\tfree(hdr->alloc_ptr);\n\t\treturn;\n#endif\n\t\t// get memory allocation record pointer\n\t\ttjs_uint8 *bptr = (tjs_uint8*)ptr;\n\t\ttTVPLayerBitmapMemoryRecord * record =\n\t\t\t(tTVPLayerBitmapMemoryRecord*)\n\t\t\t(bptr - sizeof(tTVPLayerBitmapMemoryRecord)-sizeof(tjs_uint32));\n\n\t\t// check sentinel\n\t\tif (~(*(tjs_uint32*)(bptr - sizeof(tjs_uint32))) != record->sentinel_backup1)\n\t\t\tTVPThrowExceptionMessage(\n\t\t\tTJS_W(\"Layer bitmap: Buffer underrun detected. Check your drawing code!\"));\n\t\tif (~(*(tjs_uint32*)(bptr + record->size)) != record->sentinel_backup2)\n\t\t\tTVPThrowExceptionMessage(\n\t\t\tTJS_W(\"Layer bitmap: Buffer overrun detected. Check your drawing code!\"));\n\n\t\tfree(record->alloc_ptr);\n\t}\n}\n//---------------------------------------------------------------------------\n\n#if 0\n//---------------------------------------------------------------------------\n// tTVPBitmap : internal bitmap object\n//---------------------------------------------------------------------------\n/*\nimportant:\nNote that each lines must be started at tjs_uint32 ( 4bytes ) aligned address.\nThis is the default Windows bitmap allocate behavior.\n*/\ntTVPBitmap::tTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp)\n{\n\t// tTVPBitmap constructor\n\n\tTVPInitWindowOptions(); // ensure window/bitmap usage options are initialized\n\n\tRefCount = 1;\n\n\tAllocate(width, height, bpp); // allocate initial bitmap\n}\n//---------------------------------------------------------------------------\ntTVPBitmap::~tTVPBitmap()\n{\n\tTVPFreeBitmapBits(Bits);\n\tfree(BitmapInfo);\n}\n//---------------------------------------------------------------------------\ntTVPBitmap::tTVPBitmap(const tTVPBitmap & r)\n{\n\t// constructor for cloning bitmap\n\tTVPInitWindowOptions(); // ensure window/bitmap usage options are initialized\n\n\tRefCount = 1;\n\n\t// allocate bitmap which has the same metrics to r\n\tAllocate(r.GetWidth(), r.GetHeight(), r.GetBPP());\n\n\t// copy BitmapInfo\n\tmemcpy(BitmapInfo, r.BitmapInfo, BitmapInfoSize);\n\n\t// copy Bits\n\tif (r.Bits) memcpy(Bits, r.Bits, r.BitmapInfo->bmiHeader.biSizeImage);\n\n\t// copy pitch\n\tPitchBytes = r.PitchBytes;\n\tPitchStep = r.PitchStep;\n}\n//---------------------------------------------------------------------------\nvoid tTVPBitmap::Allocate(tjs_uint width, tjs_uint height, tjs_uint bpp)\n{\n\t// allocate bitmap bits\n\t// bpp must be 8 or 32\n\n\t// create BITMAPINFO\n\tBitmapInfoSize = sizeof(BITMAPINFOHEADER)+\n\t\t((bpp == 8) ? sizeof(RGBQUAD)* 256 : 0);\n\tBitmapInfo = (_BITMAPINFO*)calloc(1, BitmapInfoSize);\n\t//GlobalAlloc(GPTR, BitmapInfoSize);\n\tif (!BitmapInfo) TVPThrowExceptionMessage(TVPCannotAllocateBitmapBits,\n\t\tTJS_W(\"allocating BITMAPINFOHEADER\"), ttstr((tjs_int)BitmapInfoSize));\n\n\tWidth = width;\n\tHeight = height;\n\n\ttjs_uint bitmap_width = width;\n\t// note that the allocated bitmap size can be bigger than the\n\t// original size because the horizontal pitch of the bitmap\n\t// is aligned to a paragraph (16bytes)\n\n\tif (bpp == 8)\n\t{\n\t\tbitmap_width = (((bitmap_width - 1) / 16) + 1) * 16; // align to a paragraph\n\t\tPitchBytes = (((bitmap_width - 1) >> 2) + 1) << 2;\n\t} else\n\t{\n\t\tbitmap_width = (((bitmap_width - 1) / 4) + 1) * 4; // align to a paragraph\n\t\tPitchBytes = bitmap_width * 4;\n\t}\n\n\tPitchStep = /*-*/PitchBytes;\n\n\n\tBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n\tBitmapInfo->bmiHeader.biWidth = bitmap_width;\n\tBitmapInfo->bmiHeader.biHeight = height;\n\tBitmapInfo->bmiHeader.biPlanes = 1;\n\tBitmapInfo->bmiHeader.biBitCount = bpp;\n\tBitmapInfo->bmiHeader.biCompression = 0/*BI_RGB*/;\n\tBitmapInfo->bmiHeader.biSizeImage = PitchBytes * height;\n\tBitmapInfo->bmiHeader.biXPelsPerMeter = 0;\n\tBitmapInfo->bmiHeader.biYPelsPerMeter = 0;\n\tBitmapInfo->bmiHeader.biClrUsed = 0;\n\tBitmapInfo->bmiHeader.biClrImportant = 0;\n\n\t// create grayscale palette\n\tif (bpp == 8)\n\t{\n\t\tRGBQUAD *pal = (RGBQUAD*)((tjs_uint8*)BitmapInfo + sizeof(BITMAPINFOHEADER));\n\n\t\tfor (tjs_int i = 0; i<256; i++)\n\t\t{\n\t\t\tpal[i].rgbBlue = pal[i].rgbGreen = pal[i].rgbRed = (BYTE)i;\n\t\t\tpal[i].rgbReserved = 0;\n\t\t}\n\t}\n\n\t// allocate bitmap bits\n\ttry\n\t{\n\t\tBits = TVPAllocBitmapBits(BitmapInfo->bmiHeader.biSizeImage,\n\t\t\twidth, height);\n\t} catch (...)\n\t{\n\t\tfree(BitmapInfo), BitmapInfo = NULL;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid * tTVPBitmap::GetScanLine(tjs_uint l) const\n{\n\tif ((tjs_int)l >= BitmapInfo->bmiHeader.biHeight)\n\t{\n\t\tTVPThrowExceptionMessage(TVPScanLineRangeOver, ttstr((tjs_int)l),\n\t\t\tttstr((tjs_int)BitmapInfo->bmiHeader.biHeight - 1));\n\t}\n\n\treturn /*(BitmapInfo->bmiHeader.biHeight - l -1 )*/l * PitchBytes + (tjs_uint8*)Bits;\n}\n\ntjs_uint tTVPBitmap::GetBPP() const {\n\treturn BitmapInfo->bmiHeader.biBitCount;\n}\n\nbool tTVPBitmap::Is32bit() const {\n\treturn BitmapInfo->bmiHeader.biBitCount == 32;\n}\n\nbool tTVPBitmap::Is8bit() const {\n\treturn BitmapInfo->bmiHeader.biBitCount == 8;\n}\n#endif\n//---------------------------------------------------------------------------\n\nstatic std::vector<iTVPTexture2D*> _toDeleteTextures;\n\nvoid iTVPTexture2D::RecycleProcess()\n{\n\tfor (iTVPTexture2D* tex : _toDeleteTextures) {\n\t\tdelete tex;\n\t}\n\t_toDeleteTextures.clear();\n}\nstatic tTVPAtExit\n\tTVPReleaseTexture2D(TVP_ATEXIT_PRI_RELEASE + 500, iTVPTexture2D::RecycleProcess);\n\nvoid iTVPTexture2D::Release() {\n\tif (RefCount == 1)\n\t\t_toDeleteTextures.push_back(this);\n\telse\n\t\t--RefCount;\n}\n\nclass iTVPSoftwareTexture2D : public iTVPTexture2D {\npublic:\n\tiTVPSoftwareTexture2D(tjs_int w, tjs_int h) : iTVPTexture2D(w, h) {}\n\tvirtual size_t GetBitmapSize() = 0;\n};\n\nclass tTVPSoftwareTexture2D_static : public iTVPSoftwareTexture2D {\npublic:\n\ttjs_int Pitch;\n\tTVPTextureFormat::e Format;\n\ttjs_uint8 * BmpData; // pointer to bitmap bits\n\ttTVPSoftwareTexture2D_static(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: iTVPSoftwareTexture2D(w, h), Format(format), BmpData((tjs_uint8*)pixel), Pitch(pitch)\n\t{\n\t}\n\tvirtual ~tTVPSoftwareTexture2D_static() {\n\t}\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) {\n\t\tassert(rc.left == 0 && rc.top == 0 && Format == format);\n\t\tPitch = pitch;\n\t\tBmpData = (tjs_uint8*)pixel;\n\t\tWidth = rc.get_width();\n\t\tHeight = rc.get_height();\n\t}\n\tvirtual bool IsStatic() { return true; }\n\tvirtual bool IsOpaque() { return false; }\n\tvirtual TVPTextureFormat::e GetFormat() const { return Format; }\n\tvirtual void SetPoint(int x, int y, tjs_uint32 clr) {\n\t\tassert(false);\n\t\t// nothing to do\n\t}\n\tvirtual uint32_t GetPoint(int x, int y) {\n\t\tif (Format == TVPTextureFormat::RGBA)\n\t\t\treturn  *((const uint32_t*)(BmpData + Pitch * y) + x); // 32bpp\n\t\telse if (Format == TVPTextureFormat::Gray)\n\t\t\treturn  *((const tjs_uint8*)(BmpData + Pitch * y) + x); // 8bpp\n\t\treturn 0;\n\t}\n\tvirtual const void * GetScanLineForRead(tjs_uint l) {\n\t\treturn BmpData + Pitch * l;\n\t}\n\tvirtual tjs_int GetPitch() const { return Pitch; }\n\n\tvirtual cocos2d::Texture2D* GetAdapterTexture(cocos2d::Texture2D* origTex) override {\n\t\tif (!origTex || origTex->getPixelsWide() != Width || origTex->getPixelsHigh() != Height) {\n\t\t\torigTex = new cocos2d::Texture2D;\n\t\t\torigTex->autorelease();\n\t\t\torigTex->initWithData(BmpData, Pitch * Height,\n\t\t\t\tCCPixelFormat::RGBA8888, Pitch / 4, Height,\n\t\t\t\tcocos2d::Size::ZERO);\n\t\t} else {\n\t\t\torigTex->updateWithData(BmpData, 0, 0, Pitch / 4, Height);\n\t\t}\n\t\treturn origTex;\n\t}\n\n\tvirtual size_t GetBitmapSize() override { return Pitch * Height * (Format == TVPTextureFormat::RGBA ? 4 : 1); }\n};\n\n#define EMPTY_LINE_BYTES 8192\nstatic const tjs_uint8 __empty_line[EMPTY_LINE_BYTES + 32] = {}; // at most 2048 pixels per line\nstatic const tjs_uint8* _empty_line = (const tjs_uint8*)(((intptr_t)(&__empty_line) + 15)&~15);\n\nclass tTVPSoftwareTexture2D_compress : public tTVPSoftwareTexture2D_static, public tTVPContinuousEventCallbackIntf {\nprotected:\n\ttjs_int PixelFrameLife = 0;\n\n\ttTVPSoftwareTexture2D_compress(int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: tTVPSoftwareTexture2D_static(nullptr, pitch, w, h, format) {}\n\n\t~tTVPSoftwareTexture2D_compress() {\n\t\tif (BmpData) {\n\t\t\tTVPFreeBitmapBits(BmpData);\n\t\t\tBmpData = nullptr;\n\t\t\tTVPRemoveContinuousEventHook(this);\n\t\t}\n\t}\n\n\tstatic bool all_of_zero(const tjs_uint8 *p, int n) {\n\t\twhile (--n > 0 && !p[n]);\n\t\treturn n < 0;\n\t}\n\n\t// return filled lines\n\tvirtual tjs_uint DecompressLineData(tjs_uint line, tjs_uint8 *buf) = 0;\n\npublic:\n\tvirtual const void * GetPixelData() override {\n\t\tif (!BmpData) {\n\t\t\tBmpData = (tjs_uint8*)TVPAllocBitmapBits(Pitch * Height, Width, Height);\n\t\t\ttjs_uint8 *dst = BmpData;\n\t\t\ttjs_int w = Width * (GetFormat() == TVPTextureFormat::RGBA ? sizeof(tjs_uint32) : sizeof(tjs_uint8));\n\t\t\ttjs_uint8 *dstend = dst + Pitch * Height;\n\t\t\ttjs_uint line = 0;\n\t\t\twhile (dst < dstend) {\n\t\t\t\ttjs_uint decodedLines = DecompressLineData(line, dst);\n\t\t\t\tdst += decodedLines * Pitch;\n\t\t\t\tline += decodedLines;\n\t\t\t}\n\t\t}\n\t\tif (PixelFrameLife == 0) TVPAddContinuousEventHook(this);\n\t\tPixelFrameLife = 3; // free pixel if not used in next 3 frames\n\t\treturn BmpData;\n\t}\n\n\tvirtual void OnContinuousCallback(tjs_uint64 tick) override {\n\t\tif (--PixelFrameLife) return;\n\t\tif (BmpData) {\n\t\t\tTVPFreeBitmapBits(BmpData);\n\t\t\tBmpData = nullptr;\n\t\t}\n\t\tPixelFrameLife = 0;\n\t\tTVPRemoveContinuousEventHook(this);\n\t}\n\n\tvirtual uint32_t GetPoint(int x, int y) override {\n\t\tGetPixelData();\n\t\tif (Format == TVPTextureFormat::RGBA)\n\t\t\treturn  *((const tjs_uint32*)(BmpData + y * Pitch) + x); // 32bpp\n\t\telse if (Format == TVPTextureFormat::Gray)\n\t\t\treturn  *((const tjs_uint8*)(BmpData + y * Pitch) + x); // 8bpp\n\t\treturn 0;\n\t}\n\n\tvirtual const void * GetScanLineForRead(tjs_uint l) override {\n\t\tGetPixelData();\n\t\treturn BmpData + l * Pitch;\n\t}\n\n\tvirtual void * GetScanLineForWrite(tjs_uint l) {\n\t\tassert(0);\n\t\treturn nullptr;\n\t}\n\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) override {\n\t\tassert(0);\n\t}\n\n\tvirtual cocos2d::Texture2D* GetAdapterTexture(cocos2d::Texture2D* origTex) override {\n\t\tGetPixelData();\n\t\tif (!origTex || origTex->getPixelsWide() != Width || origTex->getPixelsHigh() != Height) {\n\t\t\torigTex = new cocos2d::Texture2D;\n\t\t\torigTex->autorelease();\n\t\t\torigTex->initWithData(BmpData, Pitch * Height,\n\t\t\t\tCCPixelFormat::RGBA8888, Width, Height,\n\t\t\t\tcocos2d::Size::ZERO);\n\t\t} else {\n\t\t\torigTex->updateWithData(BmpData, 0, 0, Width, Height);\n\t\t}\n\t\treturn origTex;\n\t}\n};\n\nclass tTVPSoftwareTexture2D_half : public tTVPSoftwareTexture2D_compress {\n\tstd::vector<const tjs_uint8*> _scanline;\n\tstd::vector<tjs_uint8*> _scanlineData;\n\npublic:\n\ttTVPSoftwareTexture2D_half(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: tTVPSoftwareTexture2D_compress(pitch, w, h, format)\n\t{\n\t\tconst tjs_uint8 *src = static_cast<const tjs_uint8*>(pixel);\n\t\tif (format == TVPTextureFormat::RGB) w *= 3;\n\t\telse if (format == TVPTextureFormat::RGBA) w *= 4;\n\t\th = (h + 1) / 2;\n\t\tint pitch2 = pitch * 2;\n\t\t_scanline.resize(h);\n\t\tstd::unordered_map<tjs_uint32, const tjs_uint8*> usedPixel;\n\t\ttjs_uint32 seed = (intptr_t)bmp;\n\t\tif (w <= EMPTY_LINE_BYTES) usedPixel[XXH32(_empty_line, w, seed)] = _empty_line;\n\t\t\n\t\tfor (unsigned int l = 0; l < h; ++l, src += pitch2) {\n\t\t\ttjs_uint32 hash = XXH32(src, w, seed);\n\t\t\tauto it = usedPixel.find(hash);\n\t\t\tif (it == usedPixel.end()) {\n\t\t\t\ttjs_uint8* line = (tjs_uint8*)TVPAllocBitmapBits(w, Width, h);\n\t\t\t\t_scanlineData.push_back(line);\n\t\t\t\tmemcpy(line, src, w);\n\t\t\t\tusedPixel[hash] = line;\n\t\t\t\t_scanline[l] = line;\n\t\t\t} else {\n\t\t\t\t_scanline[l] = it->second;\n\t\t\t}\n\t\t}\n\t\t_totalVMemSize += _scanlineData.size() * w;\n\t}\n\n\tvirtual ~tTVPSoftwareTexture2D_half() {\n\t\tunsigned int w = Width;\n\t\tif (Format == TVPTextureFormat::RGB) w *= 3;\n\t\telse if (Format == TVPTextureFormat::RGBA) w *= 4;\n\t\t_totalVMemSize -= _scanlineData.size() * w;\n\t\tfor (tjs_uint8* line : _scanlineData) {\n\t\t\tTVPFreeBitmapBits(line);\n\t\t}\n\t}\n\n\tstatic iTVPTexture2D* Create(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format) {\n\t\treturn new tTVPSoftwareTexture2D_half(bmp, pixel, pitch, w, h, format);\n\t}\n\n\tvirtual const void * GetScanLineForRead(tjs_uint l) override {\n\t\treturn _scanline[l / 2];\n\t}\n\n\tvirtual uint32_t GetPoint(int x, int y) override {\n\t\tif (Format == TVPTextureFormat::RGBA)\n\t\t\treturn  *((const tjs_uint32*)(_scanline[y / 2]) + x); // 32bpp\n\t\telse if (Format == TVPTextureFormat::Gray)\n\t\t\treturn  *((const tjs_uint8*)(_scanline[y / 2]) + x); // 8bpp\n\t\treturn 0;\n\t}\n\n\tvirtual tjs_uint DecompressLineData(tjs_uint line, tjs_uint8 *buf) override {\n\t\tmemcpy(buf, tTVPSoftwareTexture2D_half::GetScanLineForRead(line), Pitch);\n\t\treturn 1;\n\t}\n\n\tvirtual cocos2d::Texture2D* GetAdapterTexture(cocos2d::Texture2D* origTex) override {\n\t\tif (!origTex || origTex->getPixelsWide() != Width || origTex->getPixelsHigh() != _scanline.size()) {\n\t\t\torigTex = new cocos2d::Texture2D;\n\t\t\torigTex->autorelease();\n\t\t\torigTex->initWithData(nullptr, Pitch * _scanline.size(),\n\t\t\t\tCCPixelFormat::RGBA8888, Width, _scanline.size(),\n\t\t\t\tcocos2d::Size::ZERO);\n\t\t}\n\t\tint y = 0;\n\t\tfor (const tjs_uint8* line : _scanline) {\n\t\t\torigTex->updateWithData(line, 0, y, Width, 1);\n\t\t\t++y;\n\t\t}\n\t\treturn origTex;\n\t}\n\n\tvirtual tjs_uint GetInternalHeight() const override { return _scanline.size(); }\n\n\tvirtual size_t GetBitmapSize() override { return Pitch * _scanlineData.size() * (Format == TVPTextureFormat::RGBA ? 4 : 1); }\n};\n\nclass tTVPSoftwareTexture2D_lz4 : public tTVPSoftwareTexture2D_compress {\nprotected:\n\tstruct Block {\n\t\tchar * Data;\n\t\ttjs_uint Length, Height;\n\t};\n\n\tstd::vector<Block> CompressedBlock;\n\ttjs_uint ShiftH = 0, DataSize = 0;\n\npublic:\n\ttTVPSoftwareTexture2D_lz4(int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: tTVPSoftwareTexture2D_compress(pitch, w, h, format) { }\n\n\t~tTVPSoftwareTexture2D_lz4() {\n\t\tfor (Block& blk : CompressedBlock) {\n\t\t\tdelete []blk.Data;\n\t\t}\n\t\t_totalVMemSize -= DataSize;\n\t}\n\n\tvoid Init(tTVPBitmap *bmp, const void *pixel, unsigned int w, unsigned int h) {\n\t\ttjs_uint BlockH = 16384 / Pitch;\n\t\tif (BlockH > h) {\n\t\t\tBlockH = h;\n\t\t} else if (BlockH == 0) {\n\t\t\tBlockH = 1;\n\t\t} else {\n\t\t\tShiftH = 31;\n\t\t\ttjs_uint test = 1 << 31;\n\t\t\tfor (; ShiftH > 1; ShiftH--, test >>= 1) {\n\t\t\t\tif (test & BlockH)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tBlockH = test;\n\t\t}\n\t\tconst char *src = (const char *)pixel;\n\t\ttjs_uint blkSize = BlockH * Pitch;\n\t\tstd::vector<char> tmp; tmp.resize(blkSize + w);\n\t\ttjs_uint y = 0;\n\t\tfor (; y < h - BlockH + 1; y += BlockH, src += blkSize) {\n\t\t\ttjs_uint dstSize = LZ4_compress_default(src, &tmp.front(), blkSize, blkSize + w);\n\t\t\tBlock blk = {\n\t\t\t\tnew char[dstSize],\n\t\t\t\tdstSize, BlockH\n\t\t\t};\n\t\t\tmemcpy(blk.Data, &tmp.front(), dstSize);\n\t\t\tCompressedBlock.emplace_back(blk);\n\t\t\tDataSize += dstSize;\n\t\t}\n\t\tif (h > y) {\n\t\t\th -= y;\n\t\t\tblkSize = h * Pitch;\n\t\t\ttjs_uint dstSize = LZ4_compress_default(src, &tmp.front(), blkSize, blkSize + w);\n\t\t\tBlock blk = {\n\t\t\t\tnew char[dstSize],\n\t\t\t\tdstSize, h\n\t\t\t};\n\t\t\tmemcpy(blk.Data, &tmp.front(), dstSize);\n\t\t\tCompressedBlock.emplace_back(blk);\n\t\t\tDataSize += dstSize;\n\t\t}\n\t\t_totalVMemSize += DataSize;\n\t}\n\n\tvirtual tjs_uint DecompressLineData(tjs_uint line, tjs_uint8 *buf) override {\n\t\tsize_t n = line >> ShiftH;\n\t\tif (n >= CompressedBlock.size())\n\t\t\tn = CompressedBlock.size() - 1;\n\t\tBlock &blk = CompressedBlock[n];\n\t\tn = LZ4_decompress_fast(blk.Data, (char*)buf, blk.Height * Pitch);\n\t\tassert(n == blk.Length);\n\t\treturn blk.Height;\n\t}\n\n\tstatic iTVPTexture2D* Create(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format) {\n\t\ttTVPSoftwareTexture2D_lz4 *tex = new tTVPSoftwareTexture2D_lz4(pitch, w, h, format);\n\t\ttex->Init(bmp, pixel, w, h);\n\t\treturn tex;\n\t}\n\n\tvirtual size_t GetBitmapSize() override { return DataSize; }\n};\n\nclass tTVPSoftwareTexture2D_lz4_tlg5 : public tTVPSoftwareTexture2D_lz4 {\n\tstatic const tjs_uint BlockSize = 4;\n\npublic:\n\ttTVPSoftwareTexture2D_lz4_tlg5(int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: tTVPSoftwareTexture2D_lz4(pitch, w, h, format) { }\n\n\tvoid CompressBlock(const char *src, tjs_uint w, tjs_uint h, char* tmp, char *tranbuf) {\n\t\ttjs_uint blkSize = BlockSize * Pitch;\n\t\tint clrBlkSize = blkSize / 4;\n\t\tchar *tran[4]/*, *prev[4] = { 0 }*/, *curline[4];\n\t\tconst char * prev = nullptr;\n\t\ttran[0] = tranbuf; // R\n\t\ttran[1] = tran[0] + clrBlkSize;  // G\n\t\ttran[2] = tran[1] + clrBlkSize;  // B\n\t\ttran[3] = tran[2] + clrBlkSize;  // A\n\t\tcurline[0] = tran[0];\n\t\tcurline[1] = tran[1];\n\t\tcurline[2] = tran[2];\n\t\tcurline[3] = tran[3];\n\t\tfor (tjs_uint line = 0; line < h; ++line) {\n\t\t\tchar prevcl[4] = { 0 }, val[4] = { 0 };\n\t\t\tconst char *cursrc = src;\n\t\t\tfor (tjs_uint x = 0; x < w; ++x) {\n\t\t\t\tchar cl[4];\n\t\t\t\tcl[0] = *src++;\n\t\t\t\tcl[1] = *src++;\n\t\t\t\tcl[2] = *src++;\n\t\t\t\tcl[3] = *src++;\n\t\t\t\tif (prev) {\n\t\t\t\t\tcl[0] -= *prev++;\n\t\t\t\t\tcl[1] -= *prev++;\n\t\t\t\t\tcl[2] -= *prev++;\n\t\t\t\t\tcl[3] -= *prev++;\n\t\t\t\t}\n\t\t\t\tval[0] = cl[0] - prevcl[0];\n\t\t\t\tval[1] = cl[1] - prevcl[1];\n\t\t\t\tval[2] = cl[2] - prevcl[2];\n\t\t\t\tval[3] = cl[3] - prevcl[3];\n\t\t\t\tprevcl[0] = cl[0];\n\t\t\t\tprevcl[1] = cl[1];\n\t\t\t\tprevcl[2] = cl[2];\n\t\t\t\tprevcl[3] = cl[3];\n\t\t\t\t*curline[0]++ = val[0] - val[1];\n\t\t\t\t*curline[1]++ = val[1];\n\t\t\t\t*curline[2]++ = val[2] - val[1];\n\t\t\t\t*curline[3]++ = val[3];\n\t\t\t}\n\t\t\tprev = cursrc;\n\t\t\ttran[0] = curline[0];\n\t\t\ttran[1] = curline[1];\n\t\t\ttran[2] = curline[2];\n\t\t\ttran[3] = curline[3];\n\t\t}\n\t\ttjs_uint dstSize = LZ4_compress_default(tranbuf, tmp, blkSize, blkSize);\n\t\tBlock blk = {\n\t\t\tnew char[dstSize],\n\t\t\tdstSize, h\n\t\t};\n\t\tmemcpy(blk.Data, tmp, dstSize);\n\t\tCompressedBlock.emplace_back(blk);\n\t\tDataSize += dstSize;\n\t}\n\n\tvoid Init(tTVPBitmap *bmp, const void *pixel, unsigned int w, unsigned int h) {\n\t\tShiftH = 2; // block size is always 4\n\t\tbool isOpaque = bmp->IsOpaque;\n\t\ttjs_uint blkSize = BlockSize * Pitch;\n\t\tw = Pitch / 4;\n\t\tstd::vector<char> tmp; tmp.resize(blkSize + w);\n\t\tchar *tranbuf = (char *)TVPAllocBitmapBits(blkSize, w, BlockSize);\n\t\tconst char *src = (const char *)pixel;\n\t\ttjs_uint y = 0;\n\t\tfor (; y < h - BlockSize + 1; y += BlockSize, src += blkSize) {\n\t\t\tCompressBlock(src, w, BlockSize, &tmp.front(), tranbuf);\n\t\t}\n\t\tif (h > y) {\n\t\t\tmemset(tranbuf, 0, blkSize);\n\t\t\tCompressBlock(src, w, h - y, &tmp.front(), tranbuf);\n\t\t}\n\t\tTVPFreeBitmapBits(tranbuf);\n\t\t_totalVMemSize += DataSize;\n\t}\n\n\tstatic iTVPTexture2D* Create(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format) {\n\t\tif (format == TVPTextureFormat::RGBA) {\n\t\t\ttTVPSoftwareTexture2D_lz4_tlg5 *tex = new tTVPSoftwareTexture2D_lz4_tlg5(pitch, w, h, format);\n\t\t\ttex->Init(bmp, pixel, w, h);\n\t\t\treturn tex;\n\t\t}\n\t\treturn tTVPSoftwareTexture2D_lz4::Create(bmp, pixel, pitch, w, h, format);\n\t}\n\n\tvirtual tjs_uint DecompressLineData(tjs_uint line, tjs_uint8 *buf) override {\n\t\tsize_t n = line >> ShiftH;\n\t\tif (n >= CompressedBlock.size())\n\t\t\tn = CompressedBlock.size() - 1;\n\t\tBlock &blk = CompressedBlock[n];\n\t\ttjs_uint w = Pitch / 4;\n\t\ttjs_uint blkSize = BlockSize * Pitch;\n\t\ttjs_uint clrBlkSize = blkSize / 4;\n\t\ttjs_uint8 *tranbuf = (tjs_uint8 *)TVPAllocBitmapBits(blkSize, w, BlockSize);\n\t\tn = LZ4_decompress_fast(blk.Data, (char*)tranbuf, blkSize);\n\t\tassert(n == blk.Length);\n\t\ttjs_uint8 *current = buf, *prevline = buf, *outbufp[4];\n\t\toutbufp[2] = tranbuf;\n\t\toutbufp[1] = outbufp[2] + clrBlkSize;\n\t\toutbufp[0] = outbufp[1] + clrBlkSize;\n\t\toutbufp[3] = outbufp[0] + clrBlkSize;\n\t\t// first line\n\t\ttjs_uint8 pr = 0, pg = 0, pb = 0, pa = 0;\n\t\tfor (tjs_uint x = 0; x < w; x++) {\n\t\t\ttjs_uint8 r = *outbufp[0]++;\n\t\t\ttjs_uint8 g = *outbufp[1]++;\n\t\t\ttjs_uint8 b = *outbufp[2]++;\n\t\t\ttjs_uint8 a = *outbufp[3]++;\n\t\t\tb += g; r += g;\n\t\t\t*current++ = pr += b;\n\t\t\t*current++ = pg += g;\n\t\t\t*current++ = pb += r;\n\t\t\t*current++ = pa += a;\n\t\t}\n\t\t// remain lines\n\t\tfor (tjs_uint y = 1; y < blk.Height; ++y) {\n\t\t\tTVPTLG5ComposeColors4To4(current, prevline, outbufp, w);\n\t\t\toutbufp[0] += w;\n\t\t\toutbufp[1] += w;\n\t\t\toutbufp[2] += w;\n\t\t\toutbufp[3] += w;\n\t\t\tprevline = current;\n\t\t\tcurrent += Pitch;\n\t\t}\n\t\tTVPFreeBitmapBits(tranbuf);\n\t\treturn blk.Height;\n\t}\n};\n\nclass tTVPSoftwareTexture2D : public tTVPSoftwareTexture2D_static {\n\ttTVPSoftwareTexture2D(tTVPBitmap *bmp)\n\t: tTVPSoftwareTexture2D_static(bmp->GetBits(), bmp->GetPitch(), bmp->GetWidth(), bmp->GetHeight(),\n\tbmp->GetBPP() == 8 ? TVPTextureFormat::Gray : TVPTextureFormat::RGBA)\n\t{\n\t\tBitmap = bmp;\n\t\t/*if (Bitmap)*/ Bitmap->AddRef();\n\t\t_totalVMemSize += Pitch * Height;\n\t}\npublic:\n\ttTVPBitmap *Bitmap;\n\ttTVPSoftwareTexture2D(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format)\n\t\t: tTVPSoftwareTexture2D_static(pixel, pitch, w, h, format)\n\t{\n\t\tint BPP;\n\t\tswitch ((Format = format)) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tBPP = 8;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tBPP = 32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"unsupported texture format %1\"), TJSIntegerToString((int)format));\n\t\t\tbreak;\n\t\t}\n\t\tBitmap = new tTVPBitmap(w, h, BPP);\n\t\tPitch = Bitmap->GetPitch();\n\t\tBmpData = (tjs_uint8*)Bitmap->GetBits();\n\n\t\t_totalVMemSize += Pitch * Height;\n\t}\n\t\n\tstatic iTVPTexture2D * CreateFromBitmap(tTVPBitmap *bmp) {\n\t\treturn new tTVPSoftwareTexture2D(bmp);\n\t}\n\n\tstatic iTVPTexture2D* Create(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format) {\n\t\tif (bmp) return new tTVPSoftwareTexture2D(bmp);\n\t\treturn new tTVPSoftwareTexture2D_static(pixel, pitch, w, h, format);\n\t}\n\n\ttTVPSoftwareTexture2D(iTVPTexture2D *tex, unsigned int w, unsigned int h)\n\t\t: tTVPSoftwareTexture2D_static(nullptr, 0, w, h, tex->GetFormat())\n\t{\n\t\tint BPP;\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tBPP = 8;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tBPP = 32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"unsupported texture format %1\"), TJSIntegerToString((int)tex->GetFormat()));\n\t\t\tbreak;\n\t\t}\n\t\tBitmap = new tTVPBitmap(w, h, BPP);\n\t\tif (tex) {\n\t\t\tint pitch =\n#ifdef _DEBUG\n\t\t\t\t0;\n#else\n\t\t\t\ttex->GetPitch();\n#endif\n\t\t\tif (pitch) {\n\t\t\t\tUpdate(tex->GetScanLineForRead(0), tex->GetFormat(), pitch, tTVPRect(0, 0, tex->GetWidth(), tex->GetHeight()));\n\t\t\t} else {\n\t\t\t\th = std::min(h, tex->GetHeight());\n\t\t\t\tw = std::min(w, tex->GetWidth());\n\t\t\t\ttjs_uint8 *dst = (tjs_uint8 *)Bitmap->GetScanLine(0);\n\t\t\t\tint dpitch = Bitmap->GetPitch();\n\t\t\t\tpitch = w * (BPP / 8);\n\t\t\t\tfor (unsigned int i = 0; i < h; ++i, dst += dpitch) {\n\t\t\t\t\ttjs_uint8 *src = (tjs_uint8*)tex->GetScanLineForRead(i);\n\t\t\t\t\tmemcpy(dst, src, pitch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tPitch = Bitmap->GetPitch();\n\t\tBmpData = (tjs_uint8*)Bitmap->GetBits();\n\t\t_totalVMemSize += Pitch * Height;\n\t}\n\t~tTVPSoftwareTexture2D() {\n\t\t_totalVMemSize -= Pitch * Height;\n\t\tif (Bitmap) Bitmap->Release();\n\t}\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) {\n\t\tassert(rc.left == 0);\n\t\tunsigned char *src = (unsigned char *)pixel;\n\t\ttjs_uint8 *dst = (tjs_uint8 *)Bitmap->GetScanLine(rc.top);\n\t\tint dstPitch = Bitmap->GetPitch();\n\t\tint h = std::min(rc.get_height(), (int)Bitmap->GetHeight()) - rc.top;\n\t\tint w = rc.get_width();\n\t\tif (w == Bitmap->GetWidth() && pitch == dstPitch) memcpy(dst, src, pitch * h);\n\t\telse if (format == TVPTextureFormat::RGB) {\n\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\tTVPConvert24BitTo32Bit((tjs_uint32*)dst, src, w);\n\t\t\t\tdst += dstPitch;\n\t\t\t\tsrc += pitch;\n\t\t\t}\n\t\t} else {\n\t\t\tint linesize = std::min(pitch, dstPitch);\n\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\tmemcpy(dst, src, linesize);\n\t\t\t\tdst += dstPitch;\n\t\t\t\tsrc += pitch;\n\t\t\t}\n\t\t}\n\t\tBitmap->IsOpaque = false;\n\t}\n\n\tvirtual uint32_t GetPoint(int x, int y) {\n\t\tif (Bitmap->Is32bit())\n\t\t\treturn  *((const tjs_uint32*)Bitmap->GetScanLine(y) + x); // 32bpp\n\t\telse\n\t\t\treturn  *((const tjs_uint8*)Bitmap->GetScanLine(y) + x); // 8bpp\n\t}\n\n\tvirtual void SetPoint(int x, int y, uint32_t clr) {\n\t\tif (Bitmap->Is32bit())\n\t\t\t*((tjs_uint32*)Bitmap->GetScanLine(y) + x) = clr; // 32bpp\n\t\telse\n\t\t\t*((tjs_uint8*)Bitmap->GetScanLine(y) + x) = (tjs_uint8)clr; // 8bpp\n\t\tBitmap->IsOpaque = false;\n\t}\n\tvirtual bool IsStatic() { return false; }\n\tvirtual bool IsOpaque() { return Bitmap->IsOpaque; }\n\tvirtual void * GetScanLineForWrite(tjs_uint l) {\n\t\tBitmap->IsOpaque = false;\n\t\treturn (void*)GetScanLineForRead(l);\n\t}\n};\n\nclass tTVPRenderMethod_Software : public iTVPRenderMethod {\n\tuint32_t _nameHash = 0;\n\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule) = 0;\n\n\tuint32_t GetNameHash() {\n\t\tif (!_nameHash) _nameHash = tTJSHashFunc<tjs_nchar *>::Make(Name.c_str());\n\t\treturn _nameHash;\n\t}\n};\n\ntemplate<typename TSrc, typename TDst,\n\tvoid(*&FuncWithOpa)(TDst*, const TSrc*, tjs_int, tjs_uint32, tjs_int),\n\tvoid(*&FuncWithoutOpa)(TDst*, const TSrc*, tjs_int, tjs_uint32)>\nclass tTVPRenderMethod_ColorOpacity : public tTVPRenderMethod_Software {\npublic:\n\tint opa;\n\ttjs_uint32 color;\n\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\telse if (!strcmp(name, \"color\")) return 1;\n\t\telse return -1;\n\t}\n\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\tvirtual void SetParameterColor4B(int id, unsigned int v) { color = v; }\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\tassert(_tar == _dst && rctar == rcdst);\n\t\tint h = rcsrc.get_height(), w = rcsrc.get_width();\n\t\tassert(h == rcdst.get_height() && w == rcdst.get_width());\n\t\tif (opa == 255) {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tFuncWithoutOpa(\n\t\t\t\t\t(TDst*)_dst->GetScanLineForWrite(rcdst.top + y) + rcdst.left,\n\t\t\t\t\t(const TSrc*)_src->GetScanLineForRead(rcsrc.top + y) + rcsrc.left, w, color);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tFuncWithOpa(\n\t\t\t\t\t(TDst*)_dst->GetScanLineForWrite(rcdst.top + y) + rcdst.left,\n\t\t\t\t\t(const TSrc*)_src->GetScanLineForRead(rcsrc.top + y) + rcsrc.left, w, color, opa);\n\t\t\t}\n\t\t}\n\t}\n};\n\nclass tTVPRenderMethod_RemoveOpacity : public tTVPRenderMethod_Software {\npublic:\n\tint opa;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\telse return -1;\n\t}\n\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\tassert(_tar == _dst && rctar == rcdst);\n\t\tint h = rcsrc.get_height(), w = rcsrc.get_width();\n\t\tassert(h == rcdst.get_height() && w == rcdst.get_width());\n\t\tif (opa == 255) {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\ttjs_uint8 *src = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top + y) + rcsrc.left;\n\t\t\t\ttjs_uint32* dst = (tjs_uint32*)_dst->GetScanLineForWrite(rcdst.top + y) + rcdst.left;\n\t\t\t\tTVPRemoveOpacity(dst, src, w);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\ttjs_uint8 *src = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top + y) + rcsrc.left;\n\t\t\t\ttjs_uint32* dst = (tjs_uint32*)_dst->GetScanLineForWrite(rcdst.top + y) + rcdst.left;\n\t\t\t\tTVPRemoveOpacity_o(dst, src, w, opa);\n\t\t\t}\n\t\t}\n\t}\n};\n\nstatic tjs_int GetAdaptiveThreadNum(tjs_int pixelNum, float factor)\n{\n\tif (pixelNum >= factor * 500)\n\t\treturn TVPGetThreadNum();\n\telse\n\t\treturn 1;\n}\n\nclass tTVPRenderMethod_FillARGB : public tTVPRenderMethod_Software {\n\n\tstruct PartialFillParam {\n\t\ttjs_uint8 *dest;\n\t\ttjs_int w;\n\t\ttjs_int h;\n\t\ttjs_int pitch;\n\t\tbool is32bpp;\n\t};\n\npublic:\n\ttjs_uint32 clr;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"color\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterColor4B(int id, tjs_uint32 v) { clr = v; }\n\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rect,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int pitch = _tar->GetPitch();\n\t\tbool is32bpp = _tar->GetFormat() == TVPTextureFormat::RGBA;\n\t\ttjs_uint8 *dest = (tjs_uint8*)_tar->GetScanLineForWrite(rect.top) + rect.left * (is32bpp ? 4 : 1);\n\t\ttjs_int h = rect.bottom - rect.top;\n\t\ttjs_int w = rect.right - rect.left;\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, 150);\n\t\tTVPExecThreadTask(taskNum, [&](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tPartialFillParam _param;\n\t\t\tPartialFillParam *param = &_param;\n\t\t\tparam->dest = dest + y0 * pitch;\n\t\t\tparam->pitch = pitch;\n\t\t\tparam->w = w;\n\t\t\tparam->h = y1 - y0;\n\t\t\tparam->is32bpp = is32bpp;\n\t\t\tPartialFill(param);\n\t\t});\n\t}\n\n\tvoid PartialFill(const PartialFillParam *param)\n\t{\n\t\tif (param->is32bpp)\n\t\t{\n\t\t\t// 32bpp\n\t\t\ttjs_int pitch = param->pitch;\n\t\t\ttjs_uint8 *sc = param->dest;\n\t\t\ttjs_int height = param->h;\n\t\t\ttjs_int width = param->w;\n\n\t\t\t// don't use no cache version. (for test reason)\n\t\t\t{\n\t\t\t\twhile (height--)\n\t\t\t\t{\n\t\t\t\t\tTVPFillARGB((tjs_uint32*)sc, width, clr);\n\t\t\t\t\tsc += pitch;\n\t\t\t\t}\n\t\t\t}\n\t\t} else\n\t\t{\n\t\t\t// 8bpp\n\t\t\ttjs_int pitch = param->pitch;\n\t\t\ttjs_uint8 *sc = param->dest;\n\t\t\ttjs_int height = param->h;\n\t\t\ttjs_int width = param->w;\n\n\t\t\twhile (height--)\n\t\t\t{\n\t\t\t\tmemset((tjs_uint8*)sc, clr, width);\n\t\t\t\tsc += pitch;\n\t\t\t}\n\t\t}\n\t}\n};\n\ntemplate < typename TDst, typename TParam, int THREAD_FACTOR,\n\tvoid(*&Func)(TDst*, tjs_int, TParam)>\nclass tTVPRenderMethod_Fill : public tTVPRenderMethod_Software {\n\tstruct PartialFillParam {\n\t\ttjs_uint8 *dest;\n\t\ttjs_int w, h;\n\t\ttjs_int pitch;\n\t};\nprotected:\n\tTParam param;\n\n\tvoid SetParamValue(const TParam &val) { param = val; }\n\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rect,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule) override\n\t{\n\t\ttjs_int pitch = _tar->GetPitch();\n\t\ttjs_uint8 *dest = (tjs_uint8*)_tar->GetScanLineForWrite(rect.top) + rect.left * sizeof(TDst);\n\t\ttjs_int h = rect.bottom - rect.top;\n\t\ttjs_int w = rect.right - rect.left;\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [=](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tPartialFillParam _param;\n\t\t\tPartialFillParam *p = &_param;\n\t\t\tp->dest = dest + pitch * y0;\n\t\t\tp->pitch = pitch;\n\t\t\tp->h = y1 - y0;\n\t\t\tp->w = w;\n\t\t\tthis->PartialFill(p);\n\t\t});\n\t}\n\n\tvoid PartialFill(const PartialFillParam *p)\n\t{\n\t\t// 32bpp\n\t\ttjs_int pitch = p->pitch;\n\t\ttjs_uint8 *sc = p->dest;\n\t\ttjs_int width = p->w;\n\t\ttjs_int height = p->h;\n\n\t\twhile (height--)\n\t\t{\n\t\t\tFunc((TDst*)sc, width, param);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n};\n\ntemplate<typename TDst, int THREAD_FACTOR,\n\tvoid(*&Func)(TDst*, tjs_int, tjs_uint32)>\nclass tTVPRenderMethod_FillWithColor : public tTVPRenderMethod_Fill<TDst, tjs_uint32, THREAD_FACTOR, Func> {\n\ttypedef tTVPRenderMethod_Fill<TDst, tjs_uint32, THREAD_FACTOR, Func> inherit;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"color\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterColor4B(int id, unsigned int v) { inherit::SetParamValue(v); }\n};\n\ntemplate<typename TDst, int THREAD_FACTOR, typename TPix,\n\tvoid(*&Func)(TDst*, tjs_int, TPix)>\nclass tTVPRenderMethod_FillWithOpacity : public tTVPRenderMethod_Fill<TDst, TPix, THREAD_FACTOR, Func> {\n\ttypedef tTVPRenderMethod_Fill<TDst, TPix, THREAD_FACTOR, Func> inherit;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterOpa(int id, int v) { inherit::SetParamValue(v); }\n};\n\ntemplate < typename TDst, int THREAD_FACTOR,\n\tvoid(*&Func)(TDst*, tjs_int, tjs_uint32, tjs_int)>\nclass tTVPRenderMethod_FillWithColorOpa : public tTVPRenderMethod_Software {\n\tstruct PartialFillParam {\n\t\ttjs_uint8 *dest;\n\t\ttjs_int w, h;\n\t\ttjs_int pitch;\n\t};\n\ttjs_uint32 clr;\n\ttjs_int opa;\n\npublic:\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"color\")) return 0;\n\t\tif (!strcmp(name, \"opacity\")) return 1;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterColor4B(int id, unsigned int v) { clr = v; }\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rect,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int pitch = _tar->GetPitch();\n\t\ttjs_uint8 *dest = (tjs_uint8*)_tar->GetScanLineForWrite(rect.top) + rect.left * sizeof(TDst);\n\t\ttjs_int h = rect.bottom - rect.top;\n\t\ttjs_int w = rect.right - rect.left;\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [&](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tPartialFillParam _param;\n\t\t\tPartialFillParam *param = &_param;\n\t\t\tparam->dest = dest + pitch * y0;\n\t\t\tparam->pitch = pitch;\n\t\t\tparam->h = y1 - y0;\n\t\t\tparam->w = w;\n\t\t\tthis->PartialFill(param);\n\t\t});\n\t}\n\n\tvoid PartialFill(const PartialFillParam *param)\n\t{\n\t\ttjs_int pitch = param->pitch;\n\t\ttjs_uint8 *sc = param->dest;\n\t\ttjs_int width = param->w;\n\t\ttjs_int height = param->h;\n\n\t\twhile (height--)\n\t\t{\n\t\t\tFunc((TDst*)sc, width, clr, opa);\n\t\t\tsc += pitch;\n\t\t}\n\t}\n};\n\ntemplate < typename TDst, typename TSrc, int THREAD_FACTOR,\n\tvoid(*&Func)(TDst*, TSrc*, tjs_int)>\nclass tTVPRenderMethod_Copy : public tTVPRenderMethod_Software {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(w == rctar.get_width() && h == rctar.get_height());\n\t\tbool backwardCopy = (_tar == _src && rctar.top > rcsrc.top);\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [=](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tthis->PartialCopy(\n\t\t\t\t_tar, rctar.left, rctar.top + y0,\n\t\t\t\t_src, rcsrc.left, rcsrc.top + y0,\n\t\t\t\tw, y1 - y0, backwardCopy);\n// \t\t\tPartialParam _param;\n// \t\t\tPartialParam *p = &_param;\n// \t\t\tp->src = src + spitch * y0;\n// \t\t\tp->dest = dest + dpitch * y0;\n// \t\t\tp->spitch = spitch;\n// \t\t\tp->dpitch = dpitch;\n// \t\t\tp->h = y1 - y0;\n// \t\t\tp->w = w;\n// \t\t\tthis->PartialCopy(p);\n\t\t});\n\t}\n\n\tvirtual void PartialCopy(\n\t\tiTVPTexture2D *dst, tjs_int dx, tjs_int dy,\n\t\tiTVPTexture2D *src, tjs_int sx, tjs_int sy,\n\t\ttjs_int w, tjs_int h, bool backwardCopy)\n\t{\n\t\t// 32bpp\n\t\tif (backwardCopy) {\n\t\t\tfor (tjs_int y = h - 1; y >= 0; --y) {\n\t\t\t\tFunc(((TDst*)dst->GetScanLineForWrite(dy + y)) + dx,\n\t\t\t\t\t((const TSrc*)src->GetScanLineForRead(sy + y)) + sx, w);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tFunc(((TDst*)dst->GetScanLineForWrite(dy + y)) + dx,\n\t\t\t\t\t((const TSrc*)src->GetScanLineForRead(sy + y)) + sx, w);\n\t\t\t}\n\t\t}\n\n// \t\ttjs_int spitch = p->spitch, dpitch = p->dpitch;\n// \t\ttjs_uint8 *src = p->src;\n// \t\ttjs_uint8 *dst = p->dest;\n// \t\ttjs_int width = p->w;\n// \t\ttjs_int height = p->h;\n// \n// \t\twhile (height--)\n// \t\t{\n// \t\t\tFunc((TDst*)dst, (TSrc*)src, width);\n// \t\t\tdst += dpitch;\n// \t\t\tsrc += spitch;\n// \t\t}\n\t}\n};\n\nclass tTVPRenderMethod_DirectCopy : public tTVPRenderMethod_Software {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\tint pixelsize = _tar->GetFormat() == TVPTextureFormat::Gray ? sizeof(tjs_uint8) : sizeof(tjs_uint32);\n\t\tif (rcsrc.top > rcsrc.bottom) {\n\t\t\t// for UDFlip\n\t\t\ttjs_int w = rctar.get_width(), h = rctar.get_height();\n\t\t\tassert(rcsrc.get_width() == w && rcsrc.get_height() == -h);\n// \t\t\ttjs_uint8 *src = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top - 1) + rcsrc.left * pixelsize;\n// \t\t\ttjs_uint8 *dst = (tjs_uint8*)_tar->GetScanLineForRead(rctar.top) + rctar.left * pixelsize;\n// \t\t\ttjs_int spitch = -_src->GetPitch(), dpitch = _tar->GetPitch();\n// \t\t\ttjs_int wbytes = w * pixelsize;\n// \t\t\twhile (h--) {\n// \t\t\t\tmemcpy(dst, src, wbytes);\n// \t\t\t\tsrc += spitch; dst += dpitch;\n// \t\t\t}\n\t\t\ttjs_int wbytes = w * pixelsize;\n\t\t\tif (pixelsize == 1) { // 8bit\n\t\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\t\tmemcpy((tjs_uint8*)_dst->GetScanLineForWrite(rctar.top + y) + rctar.left,\n\t\t\t\t\t\t(const tjs_uint8*)_src->GetScanLineForRead(rcsrc.top - y - 1) + rcsrc.left,\n\t\t\t\t\t\twbytes);\n\t\t\t\t}\n\t\t\t} else { // 32bit\n\t\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\t\tmemcpy((tjs_uint32*)_dst->GetScanLineForWrite(rctar.top + y) + rctar.left,\n\t\t\t\t\t\t(const tjs_uint32*)_src->GetScanLineForRead(rcsrc.top - y - 1) + rcsrc.left,\n\t\t\t\t\t\twbytes);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (rcsrc.left > rcsrc.right) {\n\t\t\t// for LRFlip\n\t\t\ttjs_int w = rctar.get_width(), h = rctar.get_height();\n\t\t\tassert(rcsrc.get_width() == -w && rcsrc.get_height() == h);\n// \t\t\ttjs_uint8 *src = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top) + rcsrc.right * pixelsize;\n// \t\t\ttjs_uint8 *dst = (tjs_uint8*)_tar->GetScanLineForRead(rctar.top) + rctar.left * pixelsize;\n// \t\t\ttjs_int spitch = _src->GetPitch(), dpitch = _tar->GetPitch();\n\t\t\ttjs_int wbytes = w * pixelsize;\n\t\t\ttjs_int srcright = rcsrc.right - 1;\n\t\t\tif (pixelsize == 4) { // 32bpp\n\t\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\t\ttjs_uint32 *dst = (tjs_uint32*)_dst->GetScanLineForWrite(rctar.top + y) + rctar.left;\n\t\t\t\t\tconst tjs_uint32* src = (const tjs_uint32*)_src->GetScanLineForRead(rcsrc.top + y) + srcright;\n\t\t\t\t\tmemcpy(dst, src, wbytes);\n\t\t\t\t\tTVPReverse32(dst, w);\n\t\t\t\t}\n// \t\t\t\twhile (h--) {\n// \t\t\t\t\tmemcpy(dst, src, wbytes);\n// \t\t\t\t\tTVPReverse32((tjs_uint32*)dst, w);\n// \t\t\t\t\tsrc += spitch; dst += dpitch;\n// \t\t\t\t}\n\t\t\t} else { // 8bpp\n\t\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\t\ttjs_uint8 *dst = (tjs_uint8*)_dst->GetScanLineForWrite(rctar.top + y) + rctar.left;\n\t\t\t\t\tconst tjs_uint8* src = (const tjs_uint8*)_src->GetScanLineForRead(rcsrc.top + y) + srcright;\n\t\t\t\t\tmemcpy(dst, src, wbytes);\n\t\t\t\t\tTVPReverse8(dst, w);\n\t\t\t\t}\n// \t\t\t\twhile (h--) {\n// \t\t\t\t\tmemcpy(dst, src, wbytes);\n// \t\t\t\t\tTVPReverse8(dst, w);\n// \t\t\t\t\tsrc += spitch; dst += dpitch;\n// \t\t\t\t}\n\t\t\t}\n\t\t} else {\n// \t\t\ttjs_int spitch = _src->GetPitch(), dpitch = _tar->GetPitch();\n// \t\t\ttjs_uint8 *dest, *src;\n\t\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\t\tassert(w == rctar.get_width() && h == rctar.get_height());\n\t\t\tbool backwardCopy = (_tar == _src && rctar.top > rcsrc.top);\n// \t\t\tif (backwardCopy) {\n// \t\t\t\tspitch = -spitch; dpitch = -dpitch;\n// \t\t\t\tsrc = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.bottom - 1) + rcsrc.left * pixelsize;\n// \t\t\t\tdest = (tjs_uint8*)_tar->GetScanLineForWrite(rcsrc.bottom - 1) + rcsrc.left * pixelsize;\n// \t\t\t} else {\n// \t\t\t\tsrc = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top) + rcsrc.left * pixelsize;\n// \t\t\t\tdest = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * pixelsize;\n// \t\t\t}\n\n\t\t\ttjs_int taskNum = _src == _tar ? 1 : GetAdaptiveThreadNum(w * h, 66);\n\t\t\tTVPExecThreadTask(taskNum, [=](int i){\n\t\t\t\ttjs_int y0 = h * i / taskNum;\n\t\t\t\ttjs_int y1 = h * (i + 1) / taskNum;\n\t\t\t\tthis->PartialCopy(\n\t\t\t\t\t_tar, rctar.left, rctar.top + y0,\n\t\t\t\t\t_src, rcsrc.left, rcsrc.top + y0,\n\t\t\t\t\tw, y1 - y0, backwardCopy);\n\t\t\t});\n\t\t}\n\t}\n\n\tvoid PartialCopy(\n\t\tiTVPTexture2D *dst, tjs_int dx, tjs_int dy,\n\t\tiTVPTexture2D *src, tjs_int sx, tjs_int sy,\n\t\ttjs_int w, tjs_int h, bool backwardCopy)\n\t{\n\t\t// 32bpp\n\t\tw *= sizeof(tjs_uint32);\n\t\tif (backwardCopy) {\n\t\t\tfor (tjs_int y = h - 1; y >= 0; --y) {\n\t\t\t\tmemmove(\n\t\t\t\t\t((tjs_uint32*)dst->GetScanLineForWrite(dy + y)) + dx,\n\t\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx,\n\t\t\t\t\tw);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tmemmove(\n\t\t\t\t\t((tjs_uint32*)dst->GetScanLineForWrite(dy + y)) + dx,\n\t\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx,\n\t\t\t\t\tw);\n\t\t\t}\n\t\t}\n// \t\ttjs_int spitch = p->spitch, dpitch = p->dpitch;\n// \t\ttjs_uint8 *src = p->src;\n// \t\ttjs_uint8 *dst = p->dest;\n// \t\ttjs_int wbytes = p->w * pixelsize;\n// \t\ttjs_int height = p->h;\n// \n// \t\twhile (height--)\n// \t\t{\n// \t\t\tmemmove(dst, src, wbytes);\n// \t\t\tdst += dpitch;\n// \t\t\tsrc += spitch;\n// \t\t}\n\t}\n};\n\nclass tTVPRenderMethod_DoGrayScale : public tTVPRenderMethod_DirectCopy {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttTVPRenderMethod_DirectCopy::DoRender(\n\t\t\t_tar, rctar,\n\t\t\t_dst, rcdst,\n\t\t\t_src, rcsrc,\n\t\t\trule, rcrule);\n\t\ttjs_int pitch = _tar->GetPitch();\n\t\ttjs_uint8 * line = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * sizeof(tjs_uint32);\n\t\ttjs_int h = rctar.bottom - rctar.top;\n\t\ttjs_int w = rctar.right - rctar.left;\n\t\twhile (h--)\n\t\t{\n\t\t\tTVPDoGrayScale((tjs_uint32*)line, w);\n\t\t\tline += pitch;\n\t\t}\n\t}\n};\n\ntemplate <typename TPix, int THREAD_FACTOR>\nclass tTVPRenderMethod_BaseBlt : public tTVPRenderMethod_Software {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(_tar == _dst && rctar == rcdst);\n\t\tassert(w == rctar.get_width() && h == rctar.get_height());\n\n\t\ttjs_int sx = rcsrc.left, dx = rctar.left, sy = rcsrc.top, dy = rctar.top;\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [this,_src,_tar,sx,sy,dx,dy,w,h,taskNum](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tthis->PartialFill(_tar, _src, sx, sy + y0, dx, dy + y0, w, y1 - y0);\n\t\t});\n\t}\n\n\tvirtual void PartialFill(iTVPTexture2D *dst, iTVPTexture2D *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int dx, tjs_int dy, tjs_int w, tjs_int h) = 0;\n};\n\ntemplate <int THREAD_FACTOR, void(*&Func)(tjs_uint32*, const tjs_uint32*, tjs_int)>\nclass tTVPRenderMethod_Blt : public tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> {\n\ttypedef tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> inherit;\n\tvirtual void PartialFill(iTVPTexture2D *dst, iTVPTexture2D *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int dx, tjs_int dy, tjs_int w, tjs_int h) override {\n\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\tFunc(((tjs_uint32*)dst->GetScanLineForWrite(dy + y)) + dx,\n\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx, w);\n\t\t}\n// \t\ttjs_uint8 *dst = p->dest, *src = p->src;\n// \t\ttjs_int width = p->w;\n// \t\ttjs_int height = p->h;\n// \n// \t\twhile (height--)\n// \t\t{\n// \t\t\tFunc((tjs_uint32*)dst, (const tjs_uint32*)src, width);\n// \t\t\tsrc += spitch; dst += dpitch;\n// \t\t}\n\t}\n};\n\ntemplate <int THREAD_FACTOR, void(*&Func)(tjs_uint32*, const tjs_uint32*, const tjs_uint32*, tjs_int, tjs_int)>\nclass tTVPRenderMethod_TransBlt : public tTVPRenderMethod_Software {\nprotected:\n\ttjs_int tpitch, spitch, dpitch;\n\ttjs_int opa;\n\n\tconst int ParameterIDBegin = 0;\n\tconst int ParameterIDEnd = ParameterIDBegin + 1;\n\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(w == rcdst.get_width() && h == rcdst.get_height());\n\t\tassert(w == rctar.get_width() && h == rctar.get_height());\n// \t\tspitch = _src->GetPitch();\n// \t\tdpitch = _dst->GetPitch();\n// \t\ttpitch = _tar->GetPitch();\n// \t\ttjs_uint8 *dest, *src, *tar;\n// \t\tsrc = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top) + rcsrc.left * sizeof(tjs_uint32);\n// \t\tdest = (tjs_uint8*)_dst->GetScanLineForRead(rcdst.top) + rcdst.left * sizeof(tjs_uint32);\n// \t\ttar = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * sizeof(tjs_uint32);\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [&](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tthis->PartialProc(\n\t\t\t\t_tar, rctar.left, rctar.top + y0,\n\t\t\t\t_src, rcsrc.left, rcsrc.top + y0,\n\t\t\t\t_dst, rcdst.left, rcdst.top + y0,\n\t\t\t\tw, y1 - y0\n\t\t\t\t);\n\t\t});\n\t}\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return ParameterIDBegin;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\n\tvirtual void PartialProc(\n\t\tiTVPTexture2D *tar, tjs_int tx, tjs_int ty,\n\t\tiTVPTexture2D *src, tjs_int sx, tjs_int sy,\n\t\tiTVPTexture2D *dst, tjs_int dx, tjs_int dy,\n\t\ttjs_int w, tjs_int h) {\n\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\tFunc(((tjs_uint32*)tar->GetScanLineForWrite(ty + y)) + tx,\n\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx,\n\t\t\t\t((const tjs_uint32*)dst->GetScanLineForRead(dy + y)) + dx,\n\t\t\t\tw, opa);\n\t\t}\n// \t\ttjs_uint8 *dst = p->dest, *src = p->src, *tar = p->tar;\n// \t\ttjs_int width = p->w;\n// \t\ttjs_int height = p->h;\n\n// \t\twhile (height--)\n// \t\t{\n// \t\t\tFunc((tjs_uint32*)tar, (const tjs_uint32*)src, (const tjs_uint32*)dst, width, opa);\n// \t\t\tsrc += spitch; dst += dpitch; tar += tpitch;\n// \t\t}\n\t}\n};\n\ntemplate <int THREAD_FACTOR,\n\tvoid(*&FuncInitTable)(tjs_uint32*, tjs_int, tjs_int),\n\tvoid(*&Func)(tjs_uint32*, const tjs_uint32*, const tjs_uint32*, const tjs_uint8 *, const tjs_uint32 *, tjs_int),\n\tvoid(*&FuncSwitch)(tjs_uint32*, const tjs_uint32*, const tjs_uint32*, const tjs_uint8 *, const tjs_uint32 *, tjs_int, tjs_int, tjs_int)>\nclass tTVPRenderMethod_UnivTransBlt : public tTVPRenderMethod_Software {\nprotected:\n\ttjs_int tpitch, spitch, dpitch, rpitch;\n\ttjs_int phase, vague;\n\ttjs_uint32 BlendTable[256];\n\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *_rule, const tTVPRect &rcrule)\n\t{\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(w == rcdst.get_width() && h == rcdst.get_height());\n\t\tassert(w == rctar.get_width() && h == rctar.get_height());\n// \t\tspitch = _src->GetPitch();\n// \t\tdpitch = _dst->GetPitch();\n// \t\ttpitch = _tar->GetPitch();\n// \t\trpitch = _rule->GetPitch();\n// \t\ttjs_uint8 *dest, *src, *tar, *rule;\n// \t\tsrc = (tjs_uint8*)_src->GetScanLineForRead(rcsrc.top) + rcsrc.left * sizeof(tjs_uint32);\n// \t\tdest = (tjs_uint8*)_dst->GetScanLineForRead(rcdst.top) + rcdst.left * sizeof(tjs_uint32);\n// \t\ttar = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * sizeof(tjs_uint32);\n// \t\trule = (tjs_uint8*)_rule->GetScanLineForRead(rcrule.top) + rcrule.left * sizeof(tjs_uint8);\n\n\t\ttjs_int taskNum = GetAdaptiveThreadNum(w * h, THREAD_FACTOR);\n\t\tTVPExecThreadTask(taskNum, [&](int i){\n\t\t\ttjs_int y0, y1;\n\t\t\ty0 = h * i / taskNum;\n\t\t\ty1 = h * (i + 1) / taskNum;\n\t\t\tthis->PartialProc(\n\t\t\t\t_tar, rctar.left, rctar.top + y0,\n\t\t\t\t_src, rcsrc.left, rcsrc.top + y0,\n\t\t\t\t_dst, rcdst.left, rcdst.top + y0,\n\t\t\t\t_rule, rcrule.left, rcrule.top + y0,\n\t\t\t\tw, y1 - y0);\n\t\t});\n\t}\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"phase\")) return 0;\n\t\tif (!strcmp(name, \"vague\")) return 1;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterInt(int id, int v) {\n\t\tswitch (id) {\n\t\tcase 0: phase = v; FuncInitTable(BlendTable, phase, vague); break;\n\t\tcase 1: vague = v; break;\n\t\tdefault: break;\n\t\t}\n\t}\n\n\tvirtual void PartialProc(\n\t\tiTVPTexture2D *tar, tjs_int tx, tjs_int ty,\n\t\tiTVPTexture2D *src, tjs_int sx, tjs_int sy,\n\t\tiTVPTexture2D *dst, tjs_int dx, tjs_int dy,\n\t\tiTVPTexture2D *rule, tjs_int rx, tjs_int ry,\n\t\ttjs_int w, tjs_int h) {\n// \t\ttjs_uint8 *dst = p->dest, *src = p->src, *tar = p->tar, *rule = p->rule;\n// \t\ttjs_int width = p->w;\n// \t\ttjs_int height = p->h;\n\n\t\tif (vague >= 512) {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tFunc(((tjs_uint32*)tar->GetScanLineForWrite(ty + y)) + tx,\n\t\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx,\n\t\t\t\t\t((const tjs_uint32*)dst->GetScanLineForRead(dy + y)) + dx,\n\t\t\t\t\t((const tjs_uint8*)rule->GetScanLineForRead(ry + y)) + rx,\n\t\t\t\t\tBlendTable, w);\n\t\t\t}\n// \t\t\twhile (height--)\n// \t\t\t{\n// \t\t\t\tFunc((tjs_uint32*)tar, (const tjs_uint32*)src, (const tjs_uint32*)dst, rule, BlendTable, width);\n// \t\t\t\tsrc += spitch; dst += dpitch; tar += tpitch; rule += rpitch;\n// \t\t\t}\n\t\t} else {\n\t\t\ttjs_int src1lv = phase;\n\t\t\ttjs_int src2lv = phase - vague;\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\tFuncSwitch(((tjs_uint32*)tar->GetScanLineForWrite(ty + y)) + tx,\n\t\t\t\t\t((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx,\n\t\t\t\t\t((const tjs_uint32*)dst->GetScanLineForRead(dy + y)) + dx,\n\t\t\t\t\t((const tjs_uint8*)rule->GetScanLineForRead(ry + y)) + rx,\n\t\t\t\t\tBlendTable, w, src1lv, src2lv);\n\t\t\t}\n// \t\t\twhile (height--)\n// \t\t\t{\n// \t\t\t\tFuncSwitch((tjs_uint32*)tar, (const tjs_uint32*)src, (const tjs_uint32*)dst, rule, BlendTable, width, src1lv, src2lv);\n// \t\t\t\tsrc += spitch; dst += dpitch; tar += tpitch; rule += rpitch;\n// \t\t\t}\n\t\t}\n\t}\n};\n\ntemplate <int THREAD_FACTOR, void(*&Func)(tjs_uint32*, const tjs_uint32*, tjs_int),\n\tvoid(*&FuncWithOpa)(tjs_uint32*, const tjs_uint32*, tjs_int, tjs_int)>\nclass tTVPRenderMethod_BltAndOpa : public tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> {\n\ttypedef tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> inherit;\npublic:\n\ttjs_int opa;\n\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\tvirtual void PartialFill(iTVPTexture2D *_dst, iTVPTexture2D *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int dx, tjs_int dy, tjs_int w, tjs_int h) {\n\t\tif (opa == 255) {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\ttjs_uint32 * dst = ((tjs_uint32*)_dst->GetScanLineForWrite(dy + y)) + dx;\n\t\t\t\tFunc(dst, ((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx, w);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\t\ttjs_uint32 * dst = ((tjs_uint32*)_dst->GetScanLineForWrite(dy + y)) + dx;\n\t\t\t\tFuncWithOpa(dst, ((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx, w, opa);\n\t\t\t}\n\t\t}\n\t}\n};\n\ntemplate <int THREAD_FACTOR, void(*&FuncWithOpa)(tjs_uint32*, const tjs_uint32*, tjs_int, tjs_int)>\nclass tTVPRenderMethod_BltWithOpa : public tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> {\n\ttypedef tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> inherit;\npublic:\n\ttjs_int opa;\n\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\tvirtual void PartialFill(iTVPTexture2D *_dst, iTVPTexture2D *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int dx, tjs_int dy, tjs_int w, tjs_int h) {\n\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\ttjs_uint32 * dst = ((tjs_uint32*)_dst->GetScanLineForWrite(dy + y)) + dx;\n\t\t\tFuncWithOpa(dst, ((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx, w, opa);\n\t\t}\n\t}\n};\n\ntemplate <int THREAD_FACTOR, void(*&FuncWithOpa)(tjs_uint32*, const tjs_uint32*, const tjs_uint32*, tjs_int, tjs_int)>\nclass tTVPRenderMethod_BltWithOpa_SD : public tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> {\n\ttypedef tTVPRenderMethod_BaseBlt<tjs_uint32, THREAD_FACTOR> inherit;\n\ttjs_int opa;\n\npublic:\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterOpa(int id, int v) { opa = v; }\n\tvirtual void PartialFill(iTVPTexture2D *_dst, iTVPTexture2D *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int dx, tjs_int dy, tjs_int w, tjs_int h) {\n\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\ttjs_uint32 * dst = ((tjs_uint32*)_dst->GetScanLineForWrite(dy + y)) + dx;\n\t\t\tFuncWithOpa(dst, dst, ((const tjs_uint32*)src->GetScanLineForRead(sy + y)) + sx, w, opa);\n\t\t}\n\t}\n};\n\ntemplate<void(*&Func)(tjs_uint32 *, tjs_int, tTVPGLGammaAdjustTempData *)>\nclass tTVPRenderMethod_AdjustGamma : public tTVPRenderMethod_Software {\n\ttTVPGLGammaAdjustTempData temp;\n\npublic:\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"gammaAdjustData\")) return 0;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterPtr(int id, const void *data) {\n\t\tTVPInitGammaAdjustTempData(&temp, (tTVPGLGammaAdjustData*)data);\n\t}\n\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n#if 0\n\t\ttTVPRenderMethod_DirectCopy::DoRender(\n\t\t\t_tar, rctar,\n\t\t\t_dst, rcdst,\n\t\t\t_src, rcsrc,\n\t\t\trule, rcrule);\n#endif\n\t\ttjs_uint8 *line = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * 4;\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(rctar.get_width() == w && rctar.get_height() == h);\n\t\ttjs_int pitch = _tar->GetPitch();\n\n\t\twhile (h--) {\n\t\t\tFunc((tjs_uint32*)line, w, &temp);\n\t\t\tline += pitch;\n\t\t}\n\t}\n};\n\ntemplate<void(*&Func)(tjs_uint32*, tjs_int)>\nclass tTVPRenderMethod_ApplySelf : public tTVPRenderMethod_DirectCopy {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n\t\ttTVPRenderMethod_DirectCopy::DoRender(\n\t\t\t_tar, rctar,\n\t\t\t_dst, rcdst,\n\t\t\t_src, rcsrc,\n\t\t\trule, rcrule);\n\n\t\ttjs_uint8 *line = (tjs_uint8*)_tar->GetScanLineForWrite(rctar.top) + rctar.left * 4;\n\t\ttjs_int h = rcsrc.bottom - rcsrc.top;\n\t\ttjs_int w = rcsrc.right - rcsrc.left;\n\t\tassert(rctar.get_width() == w && rctar.get_height() == h);\n\t\ttjs_int pitch = _tar->GetPitch();\n\n\t\twhile (h--) {\n\t\t\tFunc((tjs_uint32*)line, w);\n\t\t\tline += pitch;\n\t\t}\n\t}\n};\n\n// some blur operation template functions to select algorithm by base integer type\ntemplate <typename tARGB, typename base_int_type>\nvoid TVPAddSubVertSum(base_int_type *dest, const tjs_uint32 *addline,\n\tconst tjs_uint32 *subline, tjs_int len)\n{\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB<tjs_uint16>, tjs_uint16 >(tjs_uint16 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum16(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB_AA<tjs_uint16>, tjs_uint16 >(tjs_uint16 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum16_d(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB<tjs_uint32>, tjs_uint32 >(tjs_uint32 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum32(dest, addline, subline, len);\n}\ntemplate <>\nvoid TVPAddSubVertSum<tTVPARGB_AA<tjs_uint32>, tjs_uint32 >(tjs_uint32 *dest,\n\tconst tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len)\n{\n\tTVPAddSubVertSum32_d(dest, addline, subline, len);\n}\n\ntemplate <typename tARGB, typename base_int_type>\nvoid TVPDoBoxBlurAvg(tjs_uint32 *dest, base_int_type *sum,\n\tconst base_int_type * add, const base_int_type * sub,\n\ttjs_int n, tjs_int len)\n{\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB<tjs_uint16>, tjs_uint16 >(tjs_uint32 *dest, tjs_uint16 *sum,\n\tconst tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg16(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB_AA<tjs_uint16>, tjs_uint16  >(tjs_uint32 *dest, tjs_uint16 *sum,\n\tconst tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg16_d(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB<tjs_uint32>, tjs_uint32  >(tjs_uint32 *dest, tjs_uint32 *sum,\n\tconst tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg32(dest, sum, add, sub, n, len);\n}\ntemplate <>\nvoid TVPDoBoxBlurAvg<tTVPARGB_AA<tjs_uint32>, tjs_uint32  >(tjs_uint32 *dest, tjs_uint32 *sum,\n\tconst tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len)\n{\n\tTVPDoBoxBlurAvg32_d(dest, sum, add, sub, n, len);\n}\nnamespace TJS {\n\tvoid TVPConsoleLog(const tjs_nchar *format, ...);\n}\nstatic void _log_ptr(const char *n, void *_p, uint l) {\n\tunsigned char *p = (unsigned char *)_p;\n\tTVPConsoleLog(\"%s %p: %02X %02X %02X %02X %02X %02X %02X %02X ... %p: %02X %02X %02X %02X ... %p: %02X %02X %02X %02X %02X %02X %02X %02X\",\n\t\tn, p - 8, p[-8], p[-7], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p, p[0], p[1], p[2], p[3], p + l,\n\t\tp[l + 0], p[l + 1], p[l + 2], p[l + 3], p[l + 4], p[l + 5], p[l + 6], p[l + 7], p[l + 8]);\n}\n\ntemplate <typename tARGB>\nstruct TDoBoxBlurLoop {\n\n\tstatic void DoBoxBlurLoop(const tTVPRect &rect, const tTVPRect & area,\n\ttjs_int width/*of texture*/, tjs_int height/*of texture*/,\n\ttjs_uint32* line0, tjs_int pitch)\n\t{\n\t\t// Box-Blur template function used by tTVPBaseBitmap::DoBoxBlur family.\n\t\t// Based on contributed blur code by yun, say thanks to him.\n\n\t\t//\ttypedef tARGB::base_int_type base_type;\n\n\t\ttjs_int dest_buf_size = area.top <= 0 ? (1 - area.top) : 0;\n\n\t\ttjs_int vert_sum_left_limit = rect.left + area.left;\n\t\tif (vert_sum_left_limit < 0) vert_sum_left_limit = 0;\n\t\ttjs_int vert_sum_right_limit = (rect.right - 1) + area.right;\n\t\tif (vert_sum_right_limit >= width) vert_sum_right_limit = width - 1;\n\n\n\t\ttARGB * vert_sum = NULL; // vertical sum of the pixel\n\t\tstd::vector<tjs_uint32 *> dest_buf; // destination pixel temporary buffer\n//\t\tstd::vector<std::vector<tjs_uint32> > dest_buf;\n\n\t\ttjs_int vert_sum_count;\n\n\t\ttry\n\t\t{\n\t\t\t// allocate buffers\n\t\t\tvert_sum = (tARGB*)TJSAlignedAlloc(sizeof(tARGB)*\n\t\t\t\t(vert_sum_right_limit - vert_sum_left_limit + 1 + 1), 4); // use 128bit aligned allocation\n\n\t\t\tif (dest_buf_size)\n\t\t\t{\n\t\t\t\tdest_buf.resize(dest_buf_size);\n\t\t\t\tfor (tjs_int i = 0; i < dest_buf_size; i++) {\n\t\t\t\t\tdest_buf[i] = (tjs_uint32 *)TJSAlignedAlloc(rect.right - rect.left, 4);\n//\t\t\t\t\t_log_ptr(\"alloc bufN\", &dest_buf[i][0], (rect.right - rect.left) * 4);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// initialize vert_sum\n\t\t\t{\n\t\t\t\tfor (tjs_int i = vert_sum_right_limit - vert_sum_left_limit + 1 - 1; i >= 0; i--)\n\t\t\t\t\tvert_sum[i].Zero();\n\n\t\t\t\ttjs_int v_init_start = rect.top + area.top;\n\t\t\t\tif (v_init_start < 0) v_init_start = 0;\n\t\t\t\ttjs_int v_init_end = rect.top + area.bottom;\n\t\t\t\tif (v_init_end >= height) v_init_end = height - 1;\n\t\t\t\tvert_sum_count = v_init_end - v_init_start + 1;\n\t\t\t\tfor (tjs_int y = v_init_start; y <= v_init_end; y++)\n\t\t\t\t{\n\t\t\t\t\tconst tjs_uint32 * add_line;\n\t\t\t\t\tadd_line = line0 + pitch * y;\n\t\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\t\tfor (int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t\t*(vs++) += add_line[x];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// prepare variables to be used in following loop\n\t\t\ttjs_int h_init_start = rect.left + area.left; // this always be the same value as vert_sum_left_limit\n\t\t\tif (h_init_start < 0) h_init_start = 0;\n\t\t\ttjs_int h_init_end = rect.left + area.right;\n\t\t\tif (h_init_end >= width) h_init_end = width - 1;\n\n\t\t\ttjs_int left_frac_len =\n\t\t\t\trect.left + area.left < 0 ? -(rect.left + area.left) : 0;\n\t\t\ttjs_int right_frac_len =\n\t\t\t\trect.right + area.right >= width ? rect.right + area.right - width + 1 : 0;\n\t\t\ttjs_int center_len = rect.right - rect.left - left_frac_len - right_frac_len;\n\n\t\t\tif (center_len < 0)\n\t\t\t{\n\t\t\t\tleft_frac_len = rect.right - rect.left;\n\t\t\t\tright_frac_len = 0;\n\t\t\t\tcenter_len = 0;\n\t\t\t}\n\t\t\ttjs_int left_frac_lim = rect.left + left_frac_len;\n\t\t\ttjs_int center_lim = rect.left + left_frac_len + center_len;\n\n\t\t\t// for each line\n\t\t\ttjs_int dest_buf_free = dest_buf_size;\n\t\t\ttjs_int dest_buf_wp = 0;\n\n\t\t\tfor (tjs_int y = rect.top; y < rect.bottom; y++)\n\t\t\t{\n\t\t\t\t// rotate dest_buf\n\t\t\t\tif (dest_buf_free == 0)\n\t\t\t\t{\n\t\t\t\t\t// dest_buf is full;\n\t\t\t\t\t// write last dest_buf back to the bitmap\n\t\t\t\t\tmemcpy(\n\t\t\t\t\t\trect.left + line0 + pitch * (y - dest_buf_size),\n\t\t\t\t\t\t&dest_buf[dest_buf_wp][0],\n\t\t\t\t\t\t(rect.right - rect.left) * sizeof(tjs_uint32));\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tdest_buf_free--;\n\t\t\t\t}\n\n\t\t\t\t// build initial sum\n\t\t\t\ttARGB sum;\n\t\t\t\tsum.Zero();\n\t\t\t\ttjs_int horz_sum_count = h_init_end - h_init_start + 1;\n\n\t\t\t\tfor (tjs_int x = h_init_start; x <= h_init_end; x++)\n\t\t\t\t\tsum += vert_sum[x - vert_sum_left_limit];\n\n\t\t\t\t// process a line\n\t\t\t\ttjs_uint32 *dp = &dest_buf[dest_buf_wp][0];\n\t\t\t\ttjs_int x = rect.left;\n\n\t\t\t\t//- do left fraction part\n\t\t\t\tfor (; x < left_frac_lim; x++)\n\t\t\t\t{\n\t\t\t\t\ttARGB tmp = sum;\n\t\t\t\t\ttmp.average(horz_sum_count * vert_sum_count);\n\n\t\t\t\t\t*(dp++) = tmp;\n\n\t\t\t\t\t// update sum\n\t\t\t\t\tif (x + area.left >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsum -= vert_sum[x + area.left - vert_sum_left_limit];\n\t\t\t\t\t\thorz_sum_count--;\n\t\t\t\t\t}\n\t\t\t\t\tif (x + area.right + 1 < width)\n\t\t\t\t\t{\n\t\t\t\t\t\tsum += vert_sum[x + area.right + 1 - vert_sum_left_limit];\n\t\t\t\t\t\thorz_sum_count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//- do center part\n\t\t\t\tif (center_len > 0)\n\t\t\t\t{\n\t\t\t\t\t// uses function in tvpgl\n\t\t\t\t\tTVPDoBoxBlurAvg<tARGB>(dp, &sum.packed,\n\t\t\t\t\t\t&(vert_sum + x + area.right + 1 - vert_sum_left_limit)->packed,\n\t\t\t\t\t\t&(vert_sum + x + area.left - vert_sum_left_limit)->packed,\n\t\t\t\t\t\thorz_sum_count * vert_sum_count,\n\t\t\t\t\t\tcenter_len);\n\t\t\t\t\tdp += center_len;\n\t\t\t\t}\n\t\t\t\tx = center_lim;\n\n\t\t\t\t//- do right fraction part\n\t\t\t\tfor (; x < rect.right; x++)\n\t\t\t\t{\n\t\t\t\t\ttARGB tmp = sum;\n\t\t\t\t\ttmp.average(horz_sum_count * vert_sum_count);\n\n\t\t\t\t\t*(dp++) = tmp;\n\n\t\t\t\t\t// update sum\n\t\t\t\t\tif (x + area.left >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsum -= vert_sum[x + area.left - vert_sum_left_limit];\n\t\t\t\t\t\thorz_sum_count--;\n\t\t\t\t\t}\n\t\t\t\t\tif (x + area.right + 1 < width)\n\t\t\t\t\t{\n\t\t\t\t\t\tsum += vert_sum[x + area.right + 1 - vert_sum_left_limit];\n\t\t\t\t\t\thorz_sum_count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// update vert_sum\n\t\t\t\tif (y != rect.bottom - 1)\n\t\t\t\t{\n\t\t\t\t\tconst tjs_uint32 * sub_line;\n\t\t\t\t\tconst tjs_uint32 * add_line;\n\t\t\t\t\tsub_line =\n\t\t\t\t\t\ty + area.top < 0 ? nullptr : (line0 + (y + area.top) * pitch);\n\t\t\t\t\tadd_line =\n\t\t\t\t\t\ty + area.bottom + 1 >= height ? nullptr : (line0 + (y + area.bottom + 1) * pitch);\n\n\t\t\t\t\tif (sub_line && add_line)\n\t\t\t\t\t{\n\t\t\t\t\t\t// both sub_line and add_line are available\n\t\t\t\t\t\t// uses function in tvpgl\n\t\t\t\t\t\tTVPAddSubVertSum<tARGB>(&vert_sum->packed,\n\t\t\t\t\t\t\tadd_line + vert_sum_left_limit,\n\t\t\t\t\t\t\tsub_line + vert_sum_left_limit,\n\t\t\t\t\t\t\tvert_sum_right_limit - vert_sum_left_limit + 1);\n\n\t\t\t\t\t} else if (sub_line)\n\t\t\t\t\t{\n\t\t\t\t\t\t// only sub_line is available\n\t\t\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\t\t\tfor (int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t\t\t*vs -= sub_line[x], vs++;\n\t\t\t\t\t\tvert_sum_count--;\n\t\t\t\t\t} else if (add_line)\n\t\t\t\t\t{\n\t\t\t\t\t\t// only add_line is available\n\t\t\t\t\t\ttARGB * vs = vert_sum;\n\t\t\t\t\t\tfor (int x = vert_sum_left_limit; x <= vert_sum_right_limit; x++)\n\t\t\t\t\t\t\t*vs += add_line[x], vs++;\n\t\t\t\t\t\tvert_sum_count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// step dest_buf_wp\n\t\t\t\tdest_buf_wp++;\n\t\t\t\tif (dest_buf_wp >= dest_buf_size) dest_buf_wp = 0;\n\t\t\t}\n\n\t\t\t// write remaining dest_buf back to the bitmap\n\t\t\twhile (dest_buf_free < dest_buf_size)\n\t\t\t{\n\t\t\t\tmemcpy(\n\t\t\t\t\trect.left + line0 + (rect.bottom - (dest_buf_size - dest_buf_free)) * pitch,\n\t\t\t\t\t&dest_buf[dest_buf_wp][0], (rect.right - rect.left) * sizeof(tjs_uint32));\n\n\t\t\t\tdest_buf_wp++;\n\t\t\t\tif (dest_buf_wp >= dest_buf_size) dest_buf_wp = 0;\n\t\t\t\tdest_buf_free++;\n\t\t\t}\n\t\t} catch (...) {\n\t\t\t// exception caught\n\t\t\tif (vert_sum) TJSAlignedDealloc(vert_sum);\n\t\t\tif (dest_buf_size) {\n\t\t\t\tfor (tjs_int i = 0; i < dest_buf_size; i++) {\n\t\t\t\t//\t_log_ptr(\"free  bufN\", &dest_buf[i][0], (rect.right - rect.left) * 4);\n\t\t\t\t\tTJSAlignedDealloc(dest_buf[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow;\n\t\t}\n\n\t\t// free buffeers\n\t\tTJSAlignedDealloc(vert_sum);\n\t\tif (dest_buf_size) {\n\t\t\tfor (tjs_int i = 0; i < dest_buf_size; i++) {\n\t\t\t//\t_log_ptr(\"free  bufN\", &dest_buf[i][0], (rect.right - rect.left) * 4);\n\t\t\t\tTJSAlignedDealloc(dest_buf[i]);\n\t\t\t}\n\t\t}\n\t}\n};\n\ntemplate< typename Func16, typename Func32>\nclass tTVPRenderMethod_DoBoxBlur : public tTVPRenderMethod_DirectCopy {\n\ttTVPRect area;\n\npublic:\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"area_left\")) return 0;\n\t\tif (!strcmp(name, \"area_top\")) return 1;\n\t\tif (!strcmp(name, \"area_right\")) return 2;\n\t\tif (!strcmp(name, \"area_bottom\")) return 3;\n\t\treturn -1;\n\t}\n\tvirtual void SetParameterInt(int id, int v) {\n\t\tswitch (id) {\n\t\tcase 0: area.left = v; break;\n\t\tcase 1: area.top = v; break;\n\t\tcase 2: area.right = v; break;\n\t\tcase 3: area.bottom = v; break;\n\t\tdefault: break;\n\t\t}\n\t}\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule)\n\t{\n// \t\ttTVPRenderMethod_DirectCopy::DoRender(\n// \t\t\ttar, rctar,\n// \t\t\tdst, rcdst,\n// \t\t\tsrc, rcsrc,\n// \t\t\trule, rcrule);\n\n// \t\ttjs_uint64 area_size = (tjs_uint64)\n// \t\t\t(area.right - area.left + 1) * (area.bottom - area.top + 1);\n\n\t\tint\n\t\t\tsw = rcsrc.get_width(), sh = rcsrc.get_height(),\n\t\t\tdw = rctar.get_width(), dh = rctar.get_height();\n\n\t\tint spitch = src->GetPitch();\n\t\tconst uint8_t *sdata = (const uint8_t *)src->GetPixelData() + (rcsrc.top * spitch + rcsrc.left * 4);\n\t\tuint8_t *ddata = (uint8_t *)tar->GetScanLineForWrite(rcdst.top) + rcdst.left * 4;\n\t\tint dpitch = tar->GetPitch();\n\t\t\n\t\tcv::Mat src_img(sh, sw, CV_8UC4, (void*)sdata, spitch);\n\t\tcv::Mat dst_img(dh, dw, CV_8UC4, (void*)ddata, dpitch);\n\t\tcv::Size areasize(area.get_width() + 1, area.get_height() + 1);\n\t\tcv::boxFilter(src_img, dst_img, -1, areasize);\n// \t\tif (area_size < 256)\n// \t\t\tFunc16::DoBoxBlurLoop(rctar, area, _tar->GetWidth(), _tar->GetHeight(), (tjs_uint32*)line, pitchBytes);\n// \t\telse if (area_size < (1L << 24))\n// \t\t\tFunc32::DoBoxBlurLoop(rctar, area, _tar->GetWidth(), _tar->GetHeight(), (tjs_uint32*)line, pitchBytes);\n// \t\telse\n// \t\t\tTVPThrowExceptionMessage(TVPBoxBlurAreaMustBeSmallerThan16Million);\n\t}\n};\n\niTVPRenderMethod* iTVPRenderManager::GetRenderMethod(const char *name, tjs_uint32 *hint) {\n\ttjs_uint32 hash;\n\tif (hint && *hint) {\n\t\thash = *hint;\n\t} else {\n\t\thash = tTJSHashFunc<tjs_nchar*>::Make(name);\n\t\tif (hint) *hint = hash;\n\t}\n\tauto it = AllMethods.find(hash);\n\tif (it != AllMethods.end()) return it->second;\n\tTVPShowSimpleMessageBox(\n\t\tttstr(TJS_W(\"Operation \\\"\")) + name + TJS_W(\"\\\" is not supported under \") + GetName() + TJS_W(\" mode.\"),\n\t\tTJS_W(\"Please use software renderer\"));\n\treturn nullptr;\n}\n\nstruct tRenderMethodCache {\n\tstruct MethodInfo {\n\t\tiTVPRenderMethod* Normal = nullptr;\n\t\tiTVPRenderMethod* HDA = nullptr;\n\t\tiTVPRenderMethod* WithOpa = nullptr;\n\t\tiTVPRenderMethod* WithOpaHDA = nullptr;\n\t\tint NormalOpaID, HDAOpaID;\n\n\t\tvoid Init(iTVPRenderManager* mgr,\n\t\t\tconst char *nameNormal, const char *nameHDA, const char *nameOpa, const char *nameHDAOpa) {\n\t\t\tif (nameNormal) Normal = mgr->GetRenderMethod(nameNormal);\n\t\t\tif (nameHDA) HDA = mgr->GetRenderMethod(nameHDA);\n\t\t\tif (nameOpa) {\n\t\t\t\tWithOpa = mgr->GetRenderMethod(nameOpa);\n\t\t\t\tNormalOpaID = WithOpa->EnumParameterID(\"opacity\");\n\t\t\t}\n\t\t\tif (nameHDAOpa) {\n\t\t\t\tWithOpaHDA = mgr->GetRenderMethod(nameHDAOpa);\n\t\t\t\tHDAOpaID = WithOpaHDA->EnumParameterID(\"opacity\");\n\t\t\t}\n\t\t}\n\n\t\tiTVPRenderMethod *GetMethodWithOpa(tjs_int opa, bool hda) {\n\t\t\tiTVPRenderMethod *ret = hda ? WithOpaHDA : WithOpa;\n\t\t\tret->SetParameterOpa(hda ? HDAOpaID : NormalOpaID, opa);\n\t\t\treturn ret;\n\t\t}\n\t};\n\n\tMethodInfo Info[bmPsExclusion + 1];\n\n\ttRenderMethodCache(iTVPRenderManager* mgr) {\n\t\tInfo[bmCopy].Init(mgr, \"Copy\", \"CopyColor\", \"ConstAlphaBlend\", \"ConstAlphaBlend\");\n\t\tInfo[bmCopyOnAlpha].Init(mgr, \"CopyOpaqueImage\", \"CopyColor\", \"ConstAlphaBlend_d\", \"ConstAlphaBlend_d\");\n\t\tInfo[bmAlpha].Init(mgr, nullptr, nullptr, \"AlphaBlend\", \"AlphaBlend\");\n\t\tInfo[bmAlphaOnAlpha].Init(mgr, nullptr, nullptr, \"AlphaBlend_d\", \"AlphaBlend_d\");\n\t\tInfo[bmAdd].Init(mgr, nullptr, nullptr, \"AddBlend\", \"AddBlend\");\n\t\tInfo[bmSub].Init(mgr, nullptr, nullptr, \"SubBlend\", \"SubBlend\");\n\t\tInfo[bmMul].Init(mgr, nullptr, nullptr, \"MulBlend\", \"MulBlend_HDA\");\n\t\tInfo[bmDodge].Init(mgr, nullptr, nullptr, \"ColorDodgeBlend\", \"ColorDodgeBlend\");\n\t\tInfo[bmDarken].Init(mgr, nullptr, nullptr, \"DarkenBlend\", \"DarkenBlend\");\n\t\tInfo[bmLighten].Init(mgr, nullptr, nullptr, \"LightenBlend\", \"LightenBlend\");\n\t\tInfo[bmScreen].Init(mgr, nullptr, nullptr, \"ScreenBlend\", \"ScreenBlend\");\n\t\tInfo[bmAddAlpha].Init(mgr, nullptr, nullptr, \"AdditiveAlphaBlend\", \"AdditiveAlphaBlend\");\n\t\tInfo[bmAddAlphaOnAddAlpha].Init(mgr, nullptr, nullptr, \"AdditiveAlphaBlend_a\", \"AdditiveAlphaBlend_a\");\n\t\t//Info[bmAddAlphaOnAlpha].Init(mgr, nullptr, nullptr, nullptr, nullptr);\n\t\tInfo[bmAlphaOnAddAlpha].Init(mgr, nullptr, nullptr, \"AlphaBlend_a\", \"AlphaBlend_a\");\n\t\tInfo[bmCopyOnAddAlpha].Init(mgr, \"CopyOpaqueImage\", nullptr, \"ConstAlphaBlend_a\", \"ConstAlphaBlend_a\");\n\t\tInfo[bmPsNormal].Init(mgr, nullptr, nullptr, \"PsAlphaBlend\", \"PsAlphaBlend\");\n\t\tInfo[bmPsAdditive].Init(mgr, nullptr, nullptr, \"PsAddBlend\", \"PsAddBlend\");\n\t\tInfo[bmPsSubtractive].Init(mgr, nullptr, nullptr, \"PsSubBlend\", \"PsSubBlend\");\n\t\tInfo[bmPsMultiplicative].Init(mgr, nullptr, nullptr, \"PsMulBlend\", \"PsMulBlend\");\n\t\tInfo[bmPsScreen].Init(mgr, nullptr, nullptr, \"PsScreenBlend\", \"PsScreenBlend\");\n\t\tInfo[bmPsOverlay].Init(mgr, nullptr, nullptr, \"PsOverlayBlend\", \"PsOverlayBlend\");\n\t\tInfo[bmPsHardLight].Init(mgr, nullptr, nullptr, \"PsHardLightBlend\", \"PsHardLightBlend\");\n\t\tInfo[bmPsSoftLight].Init(mgr, nullptr, nullptr, \"PsSoftLightBlend\", \"PsSoftLightBlend\");\n\t\tInfo[bmPsColorDodge].Init(mgr, nullptr, nullptr, \"PsColorDodgeBlend\", \"PsColorDodgeBlend\");\n\t\tInfo[bmPsColorDodge5].Init(mgr, nullptr, nullptr, \"PsColorDodge5Blend\", \"PsColorDodge5Blend\");\n\t\tInfo[bmPsColorBurn].Init(mgr, nullptr, nullptr, \"PsColorBurnBlend\", \"PsColorBurnBlend\");\n\t\tInfo[bmPsLighten].Init(mgr, nullptr, nullptr, \"PsLightenBlend\", \"PsLightenBlend\");\n\t\tInfo[bmPsDarken].Init(mgr, nullptr, nullptr, \"PsDarkenBlend\", \"PsDarkenBlend\");\n\t\tInfo[bmPsDifference].Init(mgr, nullptr, nullptr, \"PsDiffBlend\", \"PsDiffBlend\");\n\t\tInfo[bmPsDifference5].Init(mgr, nullptr, nullptr, \"PsDiff5Blend\", \"PsDiff5Blend\");\n\t\tInfo[bmPsExclusion].Init(mgr, nullptr, nullptr, \"PsExclusionBlend\", \"PsExclusionBlend\");\n\t}\n\n\tiTVPRenderMethod* GetRenderMethod(const char *name, bool hda) {\n\t\tif (hda) {\n\t\t\t;\n\t\t} else {\n\t\t\t;\n\t\t}\n\t\treturn nullptr;\n\t}\n};\n\niTVPRenderMethod* iTVPRenderManager::GetRenderMethod(tjs_int opa, bool hda, int/*tTVPBBBltMethod*/ method)\n{\n\tswitch (method)\n\t{\n\tcase bmCopy:\n\t\t// constant ratio alpha blendng\n\tcase bmCopyOnAlpha:\n\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t// with consideration of destination alpha\n\tcase bmCopyOnAddAlpha:\n\t\t// constant ratio alpha blending (assuming source is opaque)\n\t\t// with consideration of destination additive alpha\n\t\tif (opa == 255) {\n\t\t\treturn hda ? RenderMethodCache->Info[method].HDA : RenderMethodCache->Info[method].Normal;\n\t\t} else {\n\t\t\treturn RenderMethodCache->Info[method].GetMethodWithOpa(opa, hda);\n\t\t}\n\t\tbreak;\n\tcase bmAlpha:\n\t\t// alpha blending, ignoring destination alpha\n\tcase bmAlphaOnAlpha:\n\t\t// alpha blending, with consideration of destination alpha\n\tcase bmAdd:\n\t\t// additive blending ( this does not consider distination alpha )\n\tcase bmSub:\n\t\t// subtractive blending ( this does not consider distination alpha )\n\tcase bmDodge:\n\t\t// color dodge mode ( this does not consider distination alpha )\n\tcase bmDarken:\n\t\t// darken mode ( this does not consider distination alpha )\n\tcase bmLighten:\n\t\t// lighten mode ( this does not consider distination alpha )\n\tcase bmScreen:\n\t\t// screen multiplicative mode ( this does not consider distination alpha )\n\tcase bmAddAlpha:\n\t\t// Additive Alpha\n\tcase bmAddAlphaOnAddAlpha:\n\t\t// Additive Alpha on Additive Alpha\n\tcase bmAlphaOnAddAlpha:\n\t\t// simple alpha on additive alpha\n\tcase bmPsNormal:\n\t\t// Photoshop compatible normal blend\n\t\t// (may take the same effect as bmAlpha)\n\tcase bmPsAdditive:\n\t\t// Photoshop compatible additive blend\n\tcase bmPsSubtractive:\n\t\t// Photoshop compatible subtractive blend\n\tcase bmPsMultiplicative:\n\t\t// Photoshop compatible multiplicative blend\n\tcase bmPsScreen:\n\t\t// Photoshop compatible screen blend\n\tcase bmPsOverlay:\n\t\t// Photoshop compatible overlay blend\n\tcase bmPsHardLight:\n\t\t// Photoshop compatible hard light blend\n\tcase bmPsSoftLight:\n\t\t// Photoshop compatible soft light blend\n\tcase bmPsColorDodge:\n\t\t// Photoshop compatible color dodge blend\n\tcase bmPsColorDodge5:\n\t\t// Photoshop 5.x compatible color dodge blend\n\tcase bmPsColorBurn:\n\t\t// Photoshop compatible color burn blend\n\tcase bmPsLighten:\n\t\t// Photoshop compatible compare (lighten) blend\n\tcase bmPsDarken:\n\t\t// Photoshop compatible compare (darken) blend\n\tcase bmPsDifference:\n\t\t// Photoshop compatible difference blend\n\tcase bmPsDifference5:\n\t\t// Photoshop 5.x compatible difference blend\n\tcase bmPsExclusion:\n\t\t// Photoshop compatible exclusion blend\n\tcase bmMul:\n\t\t// multiplicative blending ( this does not consider distination alpha )\n\t\treturn RenderMethodCache->Info[method].GetMethodWithOpa(opa, hda);\n\t\tbreak;\n\tcase bmAddAlphaOnAlpha:\n\t\t// additive alpha on simple alpha\n\t\t// Not yet implemented\n\t\treturn nullptr;\n\tdefault:\n\t\treturn nullptr;\n\t}\n\treturn nullptr;\n}\n\nvoid iTVPRenderManager::Initialize()\n{\n\tRenderMethodCache = new tRenderMethodCache(this);\n}\n\nvoid iTVPRenderManager::RegisterRenderMethod(const char *name, iTVPRenderMethod* method) {\n\ttjs_uint32 hash = tTJSHashFunc<tjs_nchar*>::Make(name);\n\tassert(method && AllMethods.find(hash) == AllMethods.end());\n\tAllMethods[hash] = method;\n\tmethod->SetName(name);\n}\n\niTVPRenderMethod* iTVPRenderManager::CompileRenderMethod(const char *name, const char *script, int nTex, unsigned int flags) {\n\tauto it = AllMethods.find(tTJSHashFunc<tjs_nchar*>::Make(name));\n\tassert(it == AllMethods.end());\n\tiTVPRenderMethod* method = GetRenderMethodFromScript(script, nTex, flags);\n\tRegisterRenderMethod(name, method);\n\treturn method;\n}\n\niTVPRenderMethod* iTVPRenderManager::GetOrCompileRenderMethod(const char *name, uint32_t *hint, const char *glsl_script, int nTex, unsigned int flags /*= 0*/) {\n\ttjs_uint32 hash;\n\tif (hint && *hint) {\n\t\thash = *hint;\n\t} else {\n\t\thash = tTJSHashFunc<tjs_nchar*>::Make(name);\n\t\tif (hint) *hint = hash;\n\t}\n\n\tauto it = AllMethods.find(hash);\n\tif (it != AllMethods.end()) return it->second;\n\treturn CompileRenderMethod(name, glsl_script, nTex, flags);\n}\n\nstatic int cvFlags[4] = {\n\tcv::INTER_NEAREST, // stNearest\n\tcv::INTER_AREA, // stFastLinear\n\tcv::INTER_LINEAR, // stLinear\n\tcv::INTER_CUBIC, // stCubic\n};\n\nstatic double tTVPPointD_distQ(const tTVPPointD& p0, const tTVPPointD& p1) {\n\tdouble dx = p0.x - p1.x, dy = p0.y - p1.y;\n\treturn dx * dx + dy * dy;\n}\n\nstatic bool isDoubleEqual(double a, double b) {\n\ta -= b; if (a < 0) a = -a;\n\treturn a < 0.001;\n}\n\nstatic bool checkQuadSquared(const tTVPPointD *p) {\n\tdouble d01 = tTVPPointD_distQ(p[0], p[1]);\n\tdouble d23 = tTVPPointD_distQ(p[2], p[3]);\n\tdouble d12 = tTVPPointD_distQ(p[1], p[2]);\n\tdouble d03 = tTVPPointD_distQ(p[0], p[3]);\n\treturn isDoubleEqual(d01, d23) && isDoubleEqual(d12, d03);\n}\n\nstatic iTVPTexture2D* (*_createStaticTexture2D)(tTVPBitmap *bmp, const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format);\nclass tTVPSoftwareRenderManager : public iTVPRenderManager {\n\n\tstruct eParameters {\n\t\tenum eEnums {\n\t\t\tStretchType,\n\t\t};\n\t};\n\n\ttTVPBBStretchType StretchType;\n\n\tstruct SwsContext *img_convert_ctx;\n\tSwsContext *sws_opts;\n\n\tiTVPTexture2D *tempTexture;\n\n\tiTVPTexture2D *getTempTexture(unsigned int w, unsigned int h) {\n\t\tif (!tempTexture || tempTexture->GetWidth() < w || tempTexture->GetHeight() < h) {\n\t\t\tif (tempTexture) tempTexture->Release();\n\t\t\ttempTexture = CreateTexture2D(nullptr, 0, w, h, TVPTextureFormat::RGBA);\n\t\t}\n\t\treturn tempTexture;\n\t}\n\n\ttjs_int32 _drawCount;\n\npublic:\n\tvoid Register_1() {\n\t\t// ---------- ApplyColorMap ----------\n// \t\t{\n// \t\t\tstatic tTVPRenderMethod_ColorOpacity<tjs_uint8, tjs_uint32, TVPApplyColorMap_o, TVPApplyColorMap> method;\n// \t\t\tRegisterRenderMethod(\"ApplyColorMap\", &method);\n// \t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_ColorOpacity<tjs_uint8, tjs_uint32, TVPApplyColorMap_HDA_o, TVPApplyColorMap_HDA> method;\n\t\t\tRegisterRenderMethod(\"ApplyColorMap\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_ColorOpacity<tjs_uint8, tjs_uint32, TVPApplyColorMap_do, TVPApplyColorMap_d> method;\n\t\t\tRegisterRenderMethod(\"ApplyColorMap_d\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_ColorOpacity<tjs_uint8, tjs_uint32, TVPApplyColorMap_ao, TVPApplyColorMap_a> method;\n\t\t\tRegisterRenderMethod(\"ApplyColorMap_a\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_RemoveOpacity method;\n\t\t\tRegisterRenderMethod(\"RemoveOpacity\", &method);\n\t\t}\n\t\t// ---------- Fill ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillARGB method;\n\t\t\tRegisterRenderMethod(\"FillARGB\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithColor<tjs_uint32, 115, TVPFillColor> method;\n\t\t\tRegisterRenderMethod(\"FillColor\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithOpacity<tjs_uint32, 84, tjs_uint32, TVPFillMask> method;\n\t\t\tRegisterRenderMethod(\"FillMask\", &method);\n\t\t}\n\t\t// ---------- ConstColorAlphaBlend ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithColorOpa<tjs_uint32, 55, TVPConstColorAlphaBlend> method;\n\t\t\tRegisterRenderMethod(\"ConstColorAlphaBlend\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithColorOpa<tjs_uint32, 25, TVPConstColorAlphaBlend_d> method;\n\t\t\tRegisterRenderMethod(\"ConstColorAlphaBlend_d\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithColorOpa<tjs_uint32, 147, TVPConstColorAlphaBlend_a> method;\n\t\t\tRegisterRenderMethod(\"ConstColorAlphaBlend_a\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_FillWithOpacity<tjs_uint32, 50, tjs_int, TVPRemoveConstOpacity> method;\n\t\t\tRegisterRenderMethod(\"RemoveConstOpacity\", &method);\n\t\t}\n\t\t// ---------- Copy ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_DirectCopy method;\n\t\t\tRegisterRenderMethod(\"Copy\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_Copy<tjs_uint32, const tjs_uint32, 66, TVPCopyColor> method;\n\t\t\tRegisterRenderMethod(\"CopyColor\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_Copy<tjs_uint32, const tjs_uint32, 66, TVPCopyMask> method;\n\t\t\tRegisterRenderMethod(\"CopyMask\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_Blt<59, TVPCopyOpaqueImage> method;\n\t\t\tRegisterRenderMethod(\"CopyOpaqueImage\", &method);\n\t\t}\n\t\t// ---------- ConstAlphaBlend ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend_a> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend_a\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend_d> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend_d\", &method);\n\t\t}\n\t\t// ---------- AdjustGamma ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_AdjustGamma<TVPAdjustGamma> method;\n\t\t\tRegisterRenderMethod(\"AdjustGamma\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_AdjustGamma<TVPAdjustGamma_a> method;\n\t\t\tRegisterRenderMethod(\"AdjustGamma_a\", &method);\n\t\t}\n\t\t// --------- ConstAlphaBlend_SD ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_TransBlt<59, TVPConstAlphaBlend_SD> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend_SD\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_TransBlt<59, TVPConstAlphaBlend_SD_a> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend_SD_a\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_TransBlt<59, TVPConstAlphaBlend_SD_d> method;\n\t\t\tRegisterRenderMethod(\"ConstAlphaBlend_SD_d\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltWithOpa_SD<59, TVPConstAlphaBlend_SD> method;\n\t\t\tRegisterRenderMethod(\"AlphaBlend_SD\", &method);\n\t\t}\n\t\t// ConstAlphaBlend_SD = ConstAlphaBlend\n\t\t// --------- UnivTransBlend ----------\n\t\t{\n\t\t\tstatic tTVPRenderMethod_UnivTransBlt<46, TVPInitUnivTransBlendTable_d, TVPUnivTransBlend_d, TVPUnivTransBlend_switch_d> method;\n\t\t\tRegisterRenderMethod(\"UnivTransBlend_d\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_UnivTransBlt<46, TVPInitUnivTransBlendTable_a, TVPUnivTransBlend_a, TVPUnivTransBlend_switch_a> method;\n\t\t\tRegisterRenderMethod(\"UnivTransBlend_a\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_UnivTransBlt<46, TVPInitUnivTransBlendTable, TVPUnivTransBlend, TVPUnivTransBlend_switch> method;\n\t\t\tRegisterRenderMethod(\"UnivTransBlend\", &method);\n\t\t}\n\t}\n\n\tvoid Register_2() {\n\t\t// TVPxxxBlend, TVPxxxBlend_HDA, TVPxxxBlend_o, TVPxxxBlend_HDA_o\n#define REGISER_BLEND_4(THREAD_FACTOR, NAME) \\\n\t\t{ static tTVPRenderMethod_BltAndOpa<THREAD_FACTOR, TVP ## NAME ## Blend_HDA, TVP ## NAME ## Blend_HDA_o> method; \\\n\t\tRegisterRenderMethod(#NAME \"Blend\", &method); }\n#define REGISER_BLEND_NON_HDA_4(THREAD_FACTOR, NAME) \\\n\t\t{ static tTVPRenderMethod_BltAndOpa<THREAD_FACTOR, TVP ## NAME ## Blend, TVP ## NAME ## Blend_o> method; \\\n\t\tRegisterRenderMethod(#NAME \"Blend\", &method); }\n#define REGISER_BLEND_WITH_HDA_4(THREAD_FACTOR, NAME) \\\n\t\t{ static tTVPRenderMethod_BltAndOpa<THREAD_FACTOR, TVP ## NAME ## Blend_HDA, TVP ## NAME ## Blend_HDA_o> method; \\\n\t\tRegisterRenderMethod(#NAME \"Blend_HDA\", &method); }\n\n\t\tREGISER_BLEND_4(52, Alpha);\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltAndOpa<52, TVPAlphaBlend_d, TVPAlphaBlend_do> method;\n\t\t\tRegisterRenderMethod(\"AlphaBlend_d\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltAndOpa<52, TVPAlphaBlend_a, TVPAlphaBlend_ao> method;\n\t\t\tRegisterRenderMethod(\"AlphaBlend_a\", &method);\n\t\t\tRegisterRenderMethod(\"PerspectiveAlphaBlend_a\", &method);\n\t\t}\n\t\tREGISER_BLEND_4(61, Add);\n\t\tREGISER_BLEND_4(59, Sub);\n\t\tREGISER_BLEND_NON_HDA_4(45, Mul);\n\t\tREGISER_BLEND_WITH_HDA_4(45, Mul);\n\t\tREGISER_BLEND_4(10, ColorDodge);\n\t\tREGISER_BLEND_4(58, Darken);\n\t}\n\n\tvoid Register_3() {\n\t\tREGISER_BLEND_4(56, Lighten);\n\t\tREGISER_BLEND_4(42, Screen);\n\t\tREGISER_BLEND_4(52, AdditiveAlpha);\n\t\t{\n\t\t\tstatic tTVPRenderMethod_BltAndOpa<52, TVPAdditiveAlphaBlend_a, TVPAdditiveAlphaBlend_ao> method;\n\t\t\tRegisterRenderMethod(\"AdditiveAlphaBlend_a\", &method);\n\t\t}\n\t\tREGISER_BLEND_4(32, PsAlpha);\n\t\tREGISER_BLEND_4(30, PsAdd);\n\t\tREGISER_BLEND_4(29, PsSub);\n\t\tREGISER_BLEND_4(27, PsMul);\n\t}\n\n\tvoid Register_4() {\n\t\tREGISER_BLEND_4(27, PsScreen);\n\t\tREGISER_BLEND_4(15, PsOverlay);\n\t\tREGISER_BLEND_4(15, PsHardLight);\n\t\tREGISER_BLEND_4(10, PsSoftLight);\n\t\tREGISER_BLEND_4(10, PsColorDodge);\n\t\tREGISER_BLEND_4(10, PsColorDodge5);\n\t\tREGISER_BLEND_4(10, PsColorBurn);\n\t}\n\n\ttTVPSoftwareRenderManager()\n\t\t: StretchType(stNearest)\n\t\t, tempTexture(nullptr)\n\t\t, img_convert_ctx(nullptr)\n\t\t, _drawCount(0)\n\t{\n\t\t_createStaticTexture2D = tTVPSoftwareTexture2D::Create;\n\t\tstd::string compTexMethod = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"software_compress_tex\", \"none\");\n\t\tif (compTexMethod == \"halfline\") _createStaticTexture2D = tTVPSoftwareTexture2D_half::Create;\n\t\telse if (compTexMethod == \"lz4\") _createStaticTexture2D = tTVPSoftwareTexture2D_lz4::Create;\n\t\telse if (compTexMethod == \"lz4+tlg5\") _createStaticTexture2D = tTVPSoftwareTexture2D_lz4_tlg5::Create;\n\n\t\tRegister_1();\n\t\tRegister_2();\n\t\tRegister_3();\n\t\tRegister_4();\n\n\t\tREGISER_BLEND_4(29, PsLighten);\n\t\tREGISER_BLEND_4(29, PsDarken);\n\t\tREGISER_BLEND_4(29, PsDiff);\n\t\tREGISER_BLEND_4(26, PsDiff5);\n\t\tREGISER_BLEND_4(66, PsExclusion);\n\t\t{\n\t\t\tstatic tTVPRenderMethod_ApplySelf<TVPConvertAlphaToAdditiveAlpha> method;\n\t\t\tRegisterRenderMethod(\"AlphaToAdditiveAlpha\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_ApplySelf<TVPConvertAdditiveAlphaToAlpha> method;\n\t\t\tRegisterRenderMethod(\"AdditiveAlphaToAlpha\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_DoGrayScale method;\n\t\t\tRegisterRenderMethod(\"DoGrayScale\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_DoBoxBlur<TDoBoxBlurLoop< tTVPARGB<tjs_uint16> >, TDoBoxBlurLoop< tTVPARGB<tjs_uint32> > > method;\n\t\t\tRegisterRenderMethod(\"BoxBlur\", &method);\n\t\t}\n\t\t{\n\t\t\tstatic tTVPRenderMethod_DoBoxBlur<TDoBoxBlurLoop< tTVPARGB_AA<tjs_uint16> >, TDoBoxBlurLoop< tTVPARGB_AA<tjs_uint32> > > method;\n\t\t\tRegisterRenderMethod(\"BoxBlurAlpha\", &method);\n\t\t}\n#undef REGISER_BLEND_4\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(const void *pixel, int pitch, unsigned int w, unsigned int h,\n\t\tTVPTextureFormat::e format = TVPTextureFormat::RGBA, int flags = 0) override\n\t{\n\t\tif (pixel) { // create static pixel reference texture\n\t\t\treturn /*_createStaticTexture2D*/tTVPSoftwareTexture2D::Create(nullptr, pixel, pitch, w, h, format);\n\t\t} else {\n\t\t\treturn new tTVPSoftwareTexture2D(pixel, pitch, w, h, format);\n\t\t}\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(tTVPBitmap* bmp) override {\n\t\tif (bmp->GetHeight() <= 16) {\n\t\t\treturn tTVPSoftwareTexture2D::CreateFromBitmap(bmp);\n\t\t} else {\n\t\t\treturn _createStaticTexture2D(bmp, bmp->GetBits(), bmp->GetPitch(), bmp->GetWidth(), bmp->GetHeight(), bmp->GetBPP() == 8 ? TVPTextureFormat::Gray : TVPTextureFormat::RGBA);\n\t\t}\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(unsigned int neww, unsigned int newh, iTVPTexture2D* tex) override {\n\t\treturn new tTVPSoftwareTexture2D(tex, neww, newh);\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(tTJSBinaryStream* s) {\n\t\treturn nullptr;\n\t}\n\n\tvirtual const char *GetName() { return \"Software\"; }\n\n\tvirtual bool IsSoftware() { return true; }\n\n\tvirtual bool GetRenderStat(unsigned int &drawCount, uint64_t &vmemsize) {\n\t\tdrawCount = _drawCount;\n\t\t_drawCount = 0;\n\t\tvmemsize = _totalVMemSize;\n\t\treturn true;\n\t}\n\n\tvirtual bool GetTextureStat(iTVPTexture2D *texture, uint64_t &vmemsize) {\n\t\tif (!texture) {\n\t\t\tvmemsize = 0;\n\t\t\treturn false;\n\t\t}\n\t\tvmemsize = static_cast<iTVPSoftwareTexture2D*>(texture)->GetBitmapSize();\n\t\treturn true;\n\t}\n\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"StretchType\")) {\n\t\t\treturn eParameters::StretchType;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tvirtual void SetParameterInt(int id, int Value) {\n\t\tswitch (id) {\n\t\tcase eParameters::StretchType:\n\t\t\tStretchType = (tTVPBBStretchType)Value;\n\t\t\tif (StretchType > sizeof(cvFlags) / sizeof(cvFlags[0])) {\n\t\t\t\tStretchType = (tTVPBBStretchType)(sizeof(cvFlags) / sizeof(cvFlags[0]) - 1);\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t};\n\n\tvoid OperateRect(iTVPRenderMethod* method,\n\t\tiTVPTexture2D *tar, tTVPRect rctar,\n\t\tiTVPTexture2D *src, tTVPRect rcsrc) {\n\t\tint sw = rcsrc.get_width(), sh = rcsrc.get_height(),\n\t\t\tdw = rctar.get_width(), dh = rctar.get_height();\n\t\tif (dw == 0 || dh == 0 || sw == 0 || sh == 0) return;\n\t\tif (sw > 0 && sh > 0 && (sw != dw || sh != dh)) {\n\t\t\ttTVPRect cr(0, 0, tar->GetWidth(), tar->GetHeight());\n\t\t\tif (cr.left > rctar.left) {\n\t\t\t\trcsrc.left += (float)sw / dw * (cr.left - rctar.left);\n\t\t\t\trctar.left = cr.left;\n\t\t\t}\n\t\t\tif (cr.right < rctar.right) {\n\t\t\t\trcsrc.right -= (float)rcsrc.get_width() / rctar.get_width() * (rctar.right - cr.right);\n\t\t\t\trctar.right = cr.right;\n\t\t\t}\n\t\t\tif (cr.top > rctar.top) {\n\t\t\t\trcsrc.top += (float)sh / dh * (cr.top - rctar.top);\n\t\t\t\trctar.top = cr.top;\n\t\t\t}\n\t\t\tif (cr.bottom < rctar.bottom) {\n\t\t\t\trcsrc.bottom -= (float)rcsrc.get_height() / rctar.get_height() * (rctar.bottom - cr.bottom);\n\t\t\t\trctar.bottom = cr.bottom;\n\t\t\t}\n\t\t\tsw = rcsrc.get_width(); sh = rcsrc.get_height();\n\t\t\tdw = rctar.get_width(); dh = rctar.get_height();\n\t\t\tif (sh == 0 || sw == 0 || dh == 0 || dw == 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst uint8_t *sdata;\n\t\t\tint spitch = src->GetPitch();\n\t\t\tsdata = (const uint8_t *)src->GetPixelData() + (rcsrc.top * spitch + rcsrc.left * 4);\n\n\t\t\tiTVPTexture2D *tmp = getTempTexture(dw, dh + 1);\n\t\t\tuint8_t *ddata = (uint8_t *)tmp->GetScanLineForWrite(0);\n\t\t\tint dpitch = tmp->GetPitch();\n// #ifdef _DEBUG\n// \t\t\tprintf(\"resize (%d, %d) -> (%d, %d)\\n\", sw, sh, dw, dh);\n// #endif\n#ifdef USE_SWSCALE\n\t\t\tstatic int swsFlags[4] = {\n\t\t\t\tSWS_POINT, // stNearest\n\t\t\t\tSWS_FAST_BILINEAR, // stFastLinear\n\t\t\t\tSWS_BILINEAR, // stLinear\n\t\t\t\tSWS_BICUBIC, // stCubic\n\t\t\t};\n\t\t\t//assert(StretchType < sizeof(swsFlags) / sizeof(swsFlags[0]));\n\t\t\timg_convert_ctx = sws_getCachedContext(img_convert_ctx,\n\t\t\t\tsw, sh, AV_PIX_FMT_RGBA, dw, dh, AV_PIX_FMT_RGBA,\n\t\t\t\tswsFlags[StretchType], nullptr, nullptr, nullptr);\n\t\t\t//assert(img_convert_ctx);\n\t\t\t// TODO multithreaded\n\t\t\tsws_scale(img_convert_ctx, &sdata, &spitch, 0, sh, &ddata, &dpitch);\n#else\n\t\t\tcv::Size dsize(dw, dh);\n\t\t\tcv::Mat src_img(sh, sw, CV_8UC4, (void*)sdata, spitch);\n\t\t\tcv::Mat dst_img(dh, dw, CV_8UC4, (void*)ddata, dpitch);\n\t\t\tcv::resize(src_img, dst_img, dsize, 0, 0, cvFlags[StretchType]);\n#endif\n\t\t\ttTVPRect rc(0, 0, dw, dh);\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttar, rctar,\n\t\t\t\ttar, rctar,\n\t\t\t\ttmp, rc,\n\t\t\t\tnullptr, rc);\n\t\t} else {\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttar, rctar,\n\t\t\t\ttar, rctar,\n\t\t\t\tsrc, rcsrc,\n\t\t\t\tnullptr, rcsrc);\n\t\t}\n\t}\n\n\tvirtual void OperateRect(iTVPRenderMethod* method,\n\t\tiTVPTexture2D *tar, iTVPTexture2D *reftar, const tTVPRect& rctar,\n\t\tconst tRenderTexRectArray &textures) {\n#ifdef _DEBUG\n\t\tstatic bool check = false;\n\t\tcv::Mat _src[3], _tar;\n\t\tif (check) {\n\t\t\tfor (int i = 0; i < textures.size(); ++i) {\n\t\t\t\tiTVPTexture2D* tex = textures[i].first;\n\t\t\t\tunsigned int fmt = tex->GetFormat() == TVPTextureFormat::RGBA ? CV_8UC4 : CV_8UC1;\n\t\t\t\t_src[i] = cv::Mat(tex->GetHeight(), tex->GetWidth(), fmt, (void*)tex->GetPixelData(), tex->GetPitch());\n\t\t\t}\n\t\t\tunsigned int fmt = tar->GetFormat() == TVPTextureFormat::RGBA ? CV_8UC4 : CV_8UC1;\n\t\t\t_tar = cv::Mat(tar->GetHeight(), tar->GetWidth(), fmt, (void*)tar->GetPixelData(), tar->GetPitch());\n\t\t\t_tar.type();\n\t\t}\n#endif\n\n\t\tfor (int i = 0; i < textures.size(); ++i) {\n\t\t\ttextures[i].first->GetScanLineForRead(0); // prepare pixel data for compressed texture\n\t\t}\n\n\t\t++_drawCount;\n\t\tswitch (textures.size()) {\n\t\tcase 0: // fill tar\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttar, rctar,\n\t\t\t\tnullptr, rctar,\n\t\t\t\treftar, rctar,\n\t\t\t\tnullptr, rctar);\n\t\t\tbreak;\n\t\tcase 1: // src -> tar\n\t\t\tOperateRect(method, tar, rctar, textures[0].first, textures[0].second);\n\t\t\tbreak;\n\t\tcase 2: // src x dst -> tar\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttar, rctar,\n\t\t\t\ttextures[1].first, textures[1].second,\n\t\t\t\ttextures[0].first, textures[0].second,\n\t\t\t\tnullptr, rctar);\n\t\t\tbreak;\n\t\tcase 3: // src x dst x rule->tar\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttar, rctar,\n\t\t\t\ttextures[1].first, textures[1].second,\n\t\t\t\ttextures[0].first, textures[0].second,\n\t\t\t\ttextures[2].first, textures[2].second);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tstatic bool CheckQuad(const tTVPPointD* pt) {\n\t\tif (pt[1].x == pt[3].x && pt[1].y == pt[3].y &&\n\t\t\tpt[2].x == pt[4].x && pt[2].y == pt[4].y) return true;\n\t\treturn false;\n\t}\n\tstatic bool CheckTextureQuad(const tRenderTexQuadArray &textures) {\n\t\tfor (int i = 0; i < textures.size(); ++i) {\n\t\t\tif (!CheckQuad(textures[i].second)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n#define TVP_DoAffineLoop_ARGS  sxs, sys, \\\n\tdest, l, len, src, srcpitch, sxl, syl, srcrect\n#define TVP_DoBilinearAffineLoop_ARGS  sxs, sys, \\\n\tdest, l, len, src, srcpitch, sxl, syl, srccliprect, srcrect\n\ttypedef std::function < void(\n\t\ttjs_int, tjs_int, tjs_uint8*, tjs_int, tjs_int, const tjs_uint8 *,\n\t\ttjs_int, tjs_int, tjs_int, const tTVPRect &, const tTVPRect &) > TAffuncFunc;\n\n\tstd::unordered_map<iTVPRenderMethod*, std::function<TAffuncFunc(tTVPRenderMethod_Software *)> > _stretchMethodFactory;\n\n\tTAffuncFunc GetStretchFunction(tTVPRenderMethod_Software *method) {\n\t\tif (_stretchMethodFactory.empty()) {\n#define TVP_BILINEAR_FORCE_COND false\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"Copy\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\tif (TVP_BILINEAR_FORCE_COND || StretchType >= stFastLinear) { // bilinear interpolation\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\ttTVPInterpStretchCopyFunctionObject(),\n\t\t\t\t\t\t\ttTVPInterpLinTransCopyFunctionObject(),\n\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t};\n// \t\t\t\t} else { // !hda\n// \t\t\t\t\taffineloop = [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n// \t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n// \t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n// \t\t\t\t\t\tTVPDoAffineLoop(\n// \t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchColorCopy),\n// \t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransColorCopy),\n// \t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n// \t\t\t\t\t};\n\t\t\t\t} else { // hda\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopy),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransCopy),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"ConstAlphaBlend\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend>*>(method)->opa;\n\t\t\t\tif (TVP_BILINEAR_FORCE_COND || StretchType >= stFastLinear) { // bilinear interpolation\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\ttTVPInterpStretchConstAlphaBlendFunctionObject(opa),\n\t\t\t\t\t\t\ttTVPInterpLinTransConstAlphaBlendFunctionObject(opa),\n\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_HDA, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"CopyOpaqueImage\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchCopyOpaqueImage),\n\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransCopyOpaqueImage),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t};\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"ConstAlphaBlend_d\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend_d>*>(method)->opa;\n\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_d, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_d, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t};\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"AlphaBlend\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltAndOpa<52, TVPAlphaBlend_HDA, TVPAlphaBlend_HDA_o>*>(method)->opa;\n\t\t\t\tif (opa == 255) {\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_HDA),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_HDA),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"AlphaBlend_d\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltAndOpa<52, TVPAlphaBlend_d, TVPAlphaBlend_do>*>(method)->opa;\n\t\t\t\tif (opa == 255) {\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_d),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_d),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_do, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_do, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"AdditiveAlphaBlend\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltAndOpa<52, TVPAdditiveAlphaBlend_HDA, TVPAdditiveAlphaBlend_HDA_o>*>(method)->opa;\n\t\t\t\tif (opa == 255) {\n\t\t\t\t\tif (TVP_BILINEAR_FORCE_COND || StretchType >= stFastLinear) {\n\t\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlendFunctionObject(),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransAdditiveAlphaBlendFunctionObject(),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAdditiveAlphaBlend_HDA),\n\t\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAdditiveAlphaBlend_HDA),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (TVP_BILINEAR_FORCE_COND || StretchType >= stFastLinear) {\n\t\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\t\t\t\t\ttTVPInterpStretchAdditiveAlphaBlend_oFunctionObject(opa),\n\t\t\t\t\t\t\t\ttTVPInterpLinTransAdditiveAlphaBlend_oFunctionObject(opa),\n\t\t\t\t\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAdditiveAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAdditiveAlphaBlend_HDA_o, opa),\n\t\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"AdditiveAlphaBlend_a\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltAndOpa<52, TVPAdditiveAlphaBlend_a, TVPAdditiveAlphaBlend_ao>*>(method)->opa;\n\t\t\t\tif (opa == 255) {\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_a),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAdditiveAlphaBlend_a),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_ao, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAdditiveAlphaBlend_ao, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"AlphaBlend_a\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltAndOpa<52, TVPAlphaBlend_a, TVPAlphaBlend_ao>*>(method)->opa;\n\t\t\t\tif (opa == 255) {\n\t\t\t\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchFunctionObject(TVPStretchAlphaBlend_a),\n\t\t\t\t\t\t\ttTVPAffineFunctionObject(TVPLinTransAlphaBlend_a),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchAlphaBlend_ao, opa),\n\t\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransAlphaBlend_ao, opa),\n\t\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\t\t\t_stretchMethodFactory[GetRenderMethod(\"ConstAlphaBlend_a\")] = [this](tTVPRenderMethod_Software *method)->TAffuncFunc{\n\t\t\t\ttjs_int opa = static_cast<tTVPRenderMethod_BltWithOpa<59, TVPConstAlphaBlend_a>*>(method)->opa;\n\t\t\t\treturn [opa](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\t\t\tTVPDoAffineLoop(\n\t\t\t\t\t\ttTVPStretchWithOpacityFunctionObject(TVPStretchConstAlphaBlend_a, opa),\n\t\t\t\t\t\ttTVPAffineWithOpacityFunctionObject(TVPLinTransConstAlphaBlend_a, opa),\n\t\t\t\t\t\tTVP_DoAffineLoop_ARGS);\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\t\tauto it = _stretchMethodFactory.find(method);\n\t\tif (_stretchMethodFactory.end() != it) return it->second(method);\n\t\treturn [](tjs_int sxs, tjs_int sys, tjs_uint8 *dest, tjs_int l, tjs_int len,\n\t\t\tconst tjs_uint8 *src, tjs_int srcpitch, tjs_int sxl, tjs_int syl,\n\t\t\tconst tTVPRect & srccliprect, const tTVPRect & srcrect){\n\t\t\tTVPDoBilinearAffineLoop(\n\t\t\t\ttTVPInterpStretchCopyFunctionObject(),\n\t\t\t\ttTVPInterpLinTransCopyFunctionObject(),\n\t\t\t\tTVP_DoBilinearAffineLoop_ARGS);\n\t\t};\n\t}\n\n\t// src x dst -> tar\n\tvirtual void OperateTriangles(iTVPRenderMethod* method, int nTriangles,\n\t\tiTVPTexture2D *target, iTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* pttar,\n\t\tconst tRenderTexQuadArray &textures) override {\n\t\t++_drawCount;\n\t\tassert(textures.size() == 1);\n\t\tfor (int i = 0; i < textures.size(); ++i) {\n\t\t\ttextures[i].first->GetScanLineForRead(0); // prepare pixel data for compressed texture\n\t\t}\n\t\tiTVPTexture2D *dst = target;\n\t\tconst tTVPPointD *dstpt = pttar;\n\t\tiTVPTexture2D *src = textures[0].first;\n\t\tconst tTVPPointD *srcpt = textures[0].second;\n\t\tif (nTriangles == 2 && CheckQuad(pttar) && CheckTextureQuad(textures)) {\n\t\t\tbool isSrcRect =\n\t\t\t\tisDoubleEqual(srcpt[0].y, srcpt[1].y) &&\n\t\t\t\tisDoubleEqual(srcpt[1].x, srcpt[5].x) &&\n\t\t\t\tisDoubleEqual(srcpt[0].x, srcpt[2].x) &&\n\t\t\t\tisDoubleEqual(srcpt[2].y, srcpt[5].y);\n\t\t\tbool isDstRect =\n\t\t\t\tisDoubleEqual(dstpt[0].y, dstpt[1].y) &&\n\t\t\t\tisDoubleEqual(dstpt[1].x, dstpt[5].x) &&\n\t\t\t\tisDoubleEqual(dstpt[0].x, dstpt[2].x) &&\n\t\t\t\tisDoubleEqual(dstpt[2].y, dstpt[5].y);\n\n\t\t\twhile (isSrcRect && isDstRect) {\n\t\t\t\ttTVPRect dstrect(dstpt[0].x, dstpt[0].y, dstpt[5].x, dstpt[5].y);\n\t\t\t\ttTVPRect refrect(srcpt[0].x, srcpt[0].y, srcpt[5].x, srcpt[5].y);\n\t\t\t\tif (dstrect.left > dstrect.right || dstrect.top > dstrect.bottom\n\t\t\t\t\t|| refrect.left > refrect.right || refrect.top > refrect.bottom)\n\t\t\t\t\tbreak;\n\t\t\t\tconst tTVPRect &cr = rcclip;\n\n\t\t\t\tif (refrect.right < refrect.left && dstrect.right < dstrect.left) {\n\t\t\t\t\tstd::swap(refrect.left, refrect.right);\n\t\t\t\t\tstd::swap(dstrect.left, dstrect.right);\n\t\t\t\t}\n\t\t\t\tif (refrect.bottom < refrect.top && dstrect.bottom < dstrect.top) {\n\t\t\t\t\tstd::swap(refrect.bottom, refrect.top);\n\t\t\t\t\tstd::swap(dstrect.bottom, dstrect.top);\n\t\t\t\t}\n\t\t\t\ttTVPRect rcdest;\n\t\t\t\tif (!TVPIntersectRect(&rcdest, cr, dstrect)) return;\n\n\t\t\t\ttjs_int dw = dstrect.get_width(), dh = dstrect.get_height();\n\t\t\t\ttjs_int rw = refrect.get_width(), rh = refrect.get_height();\n\t\t\t\t\n\t\t\t\tif (rcdest.left > dstrect.left) {\n\t\t\t\t\trefrect.left += (float)rw / dw * (rcdest.left - dstrect.left);\n\t\t\t\t}\n\t\t\t\tif (rcdest.right < dstrect.right) {\n\t\t\t\t\trefrect.right -= (float)rw / dw * (dstrect.right - rcdest.right);\n\t\t\t\t}\n\t\t\t\tif (rcdest.top > dstrect.top) {\n\t\t\t\t\trefrect.top += (float)rh / dh * (rcdest.top - dstrect.top);\n\t\t\t\t}\n\t\t\t\tif (rcdest.bottom < dstrect.bottom) {\n\t\t\t\t\trefrect.bottom -= (float)rh / dh * (dstrect.bottom - rcdest.bottom);\n\t\t\t\t}\n\n// \t\t\t\ttjs_int clipW = cr.get_width(), clipH = cr.get_height();\n// \t\t\t\tif (target->GetWidth() == clipW) {\n// \t\t\t\t\tmemset(target->GetScanLineForWrite(cr.top), 0, target->GetPitch() * clipH);\n// \t\t\t\t} else {\n// \t\t\t\t\tfor (int i = cr.top; i < cr.bottom; ++i) {\n// \t\t\t\t\t\tmemset((tjs_uint8*)target->GetScanLineForWrite(i) + cr.left, 0, clipW * 4);\n// \t\t\t\t\t}\n// \t\t\t\t}\n\t\t\t\tOperateRect(method, target, rcdest, src, refrect);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst uint8_t *sdata;\n\t\t\tint spitch = src->GetPitch();\n\t\t\tsdata = (const uint8_t *)src->GetPixelData();\n\n\t\t\t// upper-left, upper-right, bottom-right, bottom-left\n\t\t\tcv::Point2f pts_src[] = {\n\t\t\t\tcv::Point2f(srcpt[0].x, srcpt[0].y),\n\t\t\t\tcv::Point2f(srcpt[1].x + 1, srcpt[1].y),\n\t\t\t\tcv::Point2f(srcpt[5].x + 1, srcpt[5].y + 1),\n\t\t\t\tcv::Point2f(srcpt[2].x, srcpt[2].y + 1),\n\t\t\t};\n\t\t\tcv::Point2f pts_dst[] = {\n\t\t\t\tcv::Point2f(dstpt[0].x - rcclip.left, dstpt[0].y - rcclip.top),\n\t\t\t\tcv::Point2f(dstpt[1].x - rcclip.left, dstpt[1].y - rcclip.top),\n\t\t\t\tcv::Point2f(dstpt[5].x - rcclip.left, dstpt[5].y - rcclip.top),\n\t\t\t\tcv::Point2f(dstpt[2].x - rcclip.left, dstpt[2].y - rcclip.top),\n\t\t\t};\n\n\t\t\tcv::Mat src_img;\n\t\t\tif (isSrcRect) {\n\t\t\t\ttTVPRect rcsrc(0x7FFFFFFF, 0x7FFFFFFF, -1, -1);\n\t\t\t\tfor (int i = 0; i < 4; ++i) {\n\t\t\t\t\tconst cv::Point2f& pt = pts_src[i];\n\t\t\t\t\ttjs_int x = pt.x;\n\t\t\t\t\tif (x < rcsrc.left) rcsrc.left = x;\n\t\t\t\t\tif (++x > rcsrc.right) rcsrc.right = x;\n\t\t\t\t\ttjs_int y = pt.y;\n\t\t\t\t\tif (y < rcsrc.top) rcsrc.top = y;\n\t\t\t\t\tif (++y > rcsrc.bottom) rcsrc.bottom = y;\n\t\t\t\t}\n\t\t\t\tsdata += rcsrc.top * spitch + rcsrc.left * 4;\n\t\t\t\tfor (int i = 0; i < 4; ++i) {\n\t\t\t\t\tcv::Point2f& pt = pts_src[i];\n\t\t\t\t\tpt.x -= rcsrc.left;\n\t\t\t\t\tpt.y -= rcsrc.top;\n\t\t\t\t}\n\t\t\t\ttjs_int sw = src->GetWidth(), sh = src->GetHeight();\n\t\t\t\tif (rcsrc.get_width() > sw) rcsrc.set_width(sw);\n\t\t\t\tif (rcsrc.get_height() > sh) rcsrc.set_height(sh);\n\t\t\t\tsrc_img = cv::Mat(rcsrc.get_height(), rcsrc.get_width(), CV_8UC4,\n\t\t\t\t\t(void*)sdata, spitch);\n\t\t\t} else {\n\t\t\t\tsrc_img = cv::Mat(src->GetHeight(), src->GetWidth(), CV_8UC4, (void*)sdata, spitch);\n\t\t\t}\n\n\t\t\tcv::Mat dst_img;\n\t\t\tcv::Size dst_size(rcclip.get_width(), rcclip.get_height());\n#ifdef USE_CV_AFFINE\n\t\t\tif (isSrcRect && checkQuadSquared(dstpt)) {\n// #ifdef _DEBUG\n// \t\t\t\tprintf(\"affine (%d, %d;%d, %d;%d, %d;%d, %d) -> (%d, %d;%d, %d;%d, %d;%d, %d)\\n\",\n// \t\t\t\t\t(int)pts_src[0].x, (int)pts_src[0].y, (int)pts_src[1].x, (int)pts_src[1].y,\n// \t\t\t\t\t(int)pts_src[2].x, (int)pts_src[2].y, (int)pts_src[3].x, (int)pts_src[3].y,\n// \t\t\t\t\t(int)pts_dst[0].x, (int)pts_dst[0].y, (int)pts_dst[1].x, (int)pts_dst[1].y,\n// \t\t\t\t\t(int)pts_dst[2].x, (int)pts_dst[2].y, (int)pts_dst[3].x, (int)pts_dst[3].y\n// \t\t\t\t\t);\n// #endif\n\t\t\t\tcv::Mat affine_matrix = cv::getAffineTransform(pts_src, pts_dst);\n// \t\t\t\tdouble affine_check[6] = {\n// \t\t\t\t\taffine_matrix.at<double>(0, 0),\n// \t\t\t\t\taffine_matrix.at<double>(0, 1),\n// \t\t\t\t\taffine_matrix.at<double>(0, 2),\n// \t\t\t\t\taffine_matrix.at<double>(1, 0),\n// \t\t\t\t\taffine_matrix.at<double>(1, 1),\n// \t\t\t\t\taffine_matrix.at<double>(1, 2)\n// \t\t\t\t};\n\t\t\t\tcv::warpAffine(src_img, dst_img, affine_matrix, dst_size, cvFlags[StretchType]);\n\t\t\t}\n\t\t\telse\n#endif\n\t\t\t{\n// #ifdef _DEBUG\n// \t\t\t\tprintf(\"perspective (%d, %d;%d, %d;%d, %d;%d, %d) -> (%d, %d;%d, %d;%d, %d;%d, %d)\\n\",\n// \t\t\t\t\t(int)pts_src[0].x, (int)pts_src[0].y, (int)pts_src[1].x, (int)pts_src[1].y,\n// \t\t\t\t\t(int)pts_src[2].x, (int)pts_src[2].y, (int)pts_src[3].x, (int)pts_src[3].y,\n// \t\t\t\t\t(int)pts_dst[0].x, (int)pts_dst[0].y, (int)pts_dst[1].x, (int)pts_dst[1].y,\n// \t\t\t\t\t(int)pts_dst[2].x, (int)pts_dst[2].y, (int)pts_dst[3].x, (int)pts_dst[3].y\n// \t\t\t\t\t);\n// #endif\n\t\t\t\tcv::Mat perspective_matrix = cv::getPerspectiveTransform(pts_src, pts_dst);\n\t\t\t\tcv::warpPerspective(src_img, dst_img, perspective_matrix, dst_size, cvFlags[StretchType]);\n\t\t\t}\n\n\t\t\tiTVPTexture2D *tmp = new tTVPSoftwareTexture2D_static(dst_img.ptr(0), dst_img.step1(0), dst_size.width, dst_size.height, TVPTextureFormat::RGBA);\n\t\t\ttTVPRect rc(0, 0, dst_size.width, dst_size.height);\n// \t\t\tif (rc.right > dst->GetWidth()) rc.right = dst->GetWidth();\n// \t\t\tif (rc.bottom > dst->GetHeight()) rc.bottom = dst->GetHeight();\n\n\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\ttarget, rcclip,\n\t\t\t\ttarget, rcclip,\n\t\t\t\ttmp, rc,\n\t\t\t\tnullptr, rc);\n\t\t\ttmp->Release();\n\t\t} else {\n\t\t\t//TVPThrowExceptionMessage(TJS_W(\"OperateTriangles: unsupported draw mode\"));\n// \t\t\tiTVPTexture2D *tmp = new tTVPSoftwareTexture2D(nullptr, 0, rcclip.get_width(), rcclip.get_height(), TVPTextureFormat::RGBA);\n// \t\t\tmemset(tmp->GetScanLineForWrite(0), 0, tmp->GetPitch() * rcclip.get_height());\n\t\t\tTAffuncFunc affineloop = GetStretchFunction(static_cast<tTVPRenderMethod_Software*>(method));\n\n\t\t\ttjs_int taskNum = TVPGetThreadNum();\n\t\t\tif (taskNum > nTriangles) taskNum = nTriangles;\n\t\t\tTVPExecThreadTask(taskNum, [&](int n) {\n\t\t\t\tint begin = nTriangles * n / taskNum, end = nTriangles * (n + 1) / taskNum;\n\t\t\t\tfor (int i = begin; i < end; ++i) {\n\t\t\t\t\tbool nrot = i & 1;\n\t\t\t\t\tconst tTVPPointD *pt = srcpt + 3 * i;\n\t\t\t\t\t// TODO check srcpt in square\n\t\t\t\t\ttTVPRect rc;\n\t\t\t\t\tif (nrot) { // rt, lb, rb\n\t\t\t\t\t\trc.top = pt[0].y;\n\t\t\t\t\t\trc.right = pt[0].x;\n\t\t\t\t\t\trc.left = pt[1].x;\n\t\t\t\t\t\trc.bottom = pt[1].y;\n\t\t\t\t\t} else { // lt, rt, lb\n\t\t\t\t\t\trc.top = pt[1].y;\n\t\t\t\t\t\trc.right = pt[1].x;\n\t\t\t\t\t\trc.left = pt[2].x;\n\t\t\t\t\t\trc.bottom = pt[2].y;\n\t\t\t\t\t}\n\t\t\t\t\tInternalAffineBlt(rcclip, rc, rc, src, dst, dstpt + 3 * i, !nrot, affineloop);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tstatic inline tjs_int floor_16(tjs_int x)\n\t{\n\t\t// take floor of 16.16 fixed-point format\n\t\treturn (x >> 16) - (x < 0);\n\t}\n\tstatic inline tjs_int div_16(tjs_int x, tjs_int y)\n\t{\n\t\t// return x * 65536 / y\n\t\treturn (tjs_int)((tjs_int64)x * 65536 / y);\n\t}\n\tstatic inline tjs_int mul_16(tjs_int x, tjs_int y)\n\t{\n\t\t// return x * y / 65536\n\t\treturn (tjs_int)((tjs_int64)x * y / 65536);\n\t}\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPStretchFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int srcstart, tjs_int srcstep));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPStretchWithOpacityFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int srcstart, tjs_int srcstep, tjs_int opa));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearStretchFunction,\n\t\t(tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\t\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearStretchWithOpacityFunction,\n\t\t(tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\t\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\n\n\tclass tTVPBilinearStretchFunctionObject\n\t{\n\tprotected:\n\t\ttTVPBilinearStretchFunction Func;\n\tpublic:\n\t\ttTVPBilinearStretchFunctionObject(tTVPBilinearStretchFunction func) : Func(func) { ; }\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\t\t\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep)\n\t\t{\n\t\t\tFunc(dest, destlen, src1, src2, blend_y, srcstart, srcstep);\n\t\t}\n\t};\n\tclass tTVPBilinearStretchWithOpacityFunctionObject\n\t{\n\tprotected:\n\t\ttTVPBilinearStretchWithOpacityFunction Func;\n\t\ttjs_int Opacity;\n\tpublic:\n\t\ttTVPBilinearStretchWithOpacityFunctionObject(tTVPBilinearStretchWithOpacityFunction func, tjs_int opa) :\n\t\t\tFunc(func), Opacity(opa) {\n\t\t\t;\n\t\t}\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2,\n\t\t\ttjs_int blend_y, tjs_int srcstart, tjs_int srcstep)\n\t\t{\n\t\t\tFunc(dest, destlen, src1, src2, blend_y, srcstart, srcstep, Opacity);\n\t\t}\n\t};\n\n#define TVP_DEFINE_BILINEAR_STRETCH_FUNCTION(func, one) class \\\n\tt##func##FunctionObject : \\\n\tpublic tTVPBilinearStretchFunctionObject \\\n\t{ \\\n\tpublic: \\\n\tt##func##FunctionObject() : \\\n\ttTVPBilinearStretchFunctionObject(func) { ; } \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n\t};\n\n#define TVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(func, one) class \\\n\tt##func##FunctionObject : \\\n\tpublic tTVPBilinearStretchWithOpacityFunctionObject \\\n\t{ \\\n\tpublic: \\\n\tt##func##FunctionObject(tjs_int opa) : \\\n\ttTVPBilinearStretchWithOpacityFunctionObject(func, opa) { ; } \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n\t};\n\n\t// declare streting function object for bilinear interpolation\n\tTVP_DEFINE_BILINEAR_STRETCH_FUNCTION(\n\t\tTVPInterpStretchCopy,\n\t\t*dest = color);\n\n\tTVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(\n\t\tTVPInterpStretchConstAlphaBlend,\n\t\t*dest = TVPBlendARGB(*dest, color, Opacity));\n\n\tTVP_DEFINE_BILINEAR_STRETCH_FUNCTION(\n\t\tTVPInterpStretchAdditiveAlphaBlend,\n\t\t*dest = TVPAddAlphaBlend_n_a(*dest, color));\n\n\tTVP_DEFINE_BILINEAR_STRETCH_WITH_OPACITY_FUNCTION(\n\t\tTVPInterpStretchAdditiveAlphaBlend_o,\n\t\t*dest = TVPAddAlphaBlend_n_a_o(*dest, color, Opacity));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPAffineFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPAffineWithOpacityFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearAffineFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\n\ttypedef TVP_GL_FUNC_PTR_DECL(void, tTVPBilinearAffineWithOpacityFunction,\n\t\t(tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\n\n\t// declare affine function object class\n\tclass tTVPAffineFunctionObject\n\t{\n\t\ttTVPAffineFunction Func;\n\tpublic:\n\t\ttTVPAffineFunctionObject(tTVPAffineFunction func) : Func(func) { ; }\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t\t{\n\t\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n\t\t}\n\t};\n\n\tclass tTVPAffineWithOpacityFunctionObject\n\t{\n\t\ttTVPAffineWithOpacityFunction Func;\n\t\ttjs_int Opacity;\n\tpublic:\n\t\ttTVPAffineWithOpacityFunctionObject(tTVPAffineWithOpacityFunction func, tjs_int opa) :\n\t\t\tFunc(func), Opacity(opa) {\n\t\t\t;\n\t\t}\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t\t{\n\t\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch, Opacity);\n\t\t}\n\t};\n\tclass tTVPBilinearAffineFunctionObject\n\t{\n\tprotected:\n\t\ttTVPBilinearAffineFunction Func;\n\tpublic:\n\t\ttTVPBilinearAffineFunctionObject(tTVPBilinearAffineFunction func) : Func(func) { ; }\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t\t{\n\t\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch);\n\t\t}\n\t};\n\n#define TVP_DEFINE_BILINEAR_AFFINE_FUNCTION(func, one) class \\\n\tt##func##FunctionObject : \\\n\tpublic tTVPBilinearAffineFunctionObject \\\n\t{ \\\n\tpublic: \\\n\tt##func##FunctionObject() : \\\n\ttTVPBilinearAffineFunctionObject(func) { ; } \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n\t};\n\n\n\tclass tTVPBilinearAffineWithOpacityFunctionObject\n\t{\n\tprotected:\n\t\ttTVPBilinearAffineWithOpacityFunction Func;\n\t\ttjs_int Opacity;\n\tpublic:\n\t\ttTVPBilinearAffineWithOpacityFunctionObject(tTVPBilinearAffineWithOpacityFunction func, tjs_int opa) :\n\t\t\tFunc(func), Opacity(opa) {\n\t\t\t;\n\t\t}\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch)\n\t\t{\n\t\t\tFunc(dest, len, src, sx, sy, stepx, stepy, srcpitch, Opacity);\n\t\t}\n\t};\n\n#define TVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(func, one) class \\\n\tt##func##FunctionObject : \\\n\tpublic tTVPBilinearAffineWithOpacityFunctionObject \\\n\t{ \\\n\tpublic: \\\n\tt##func##FunctionObject(tjs_int opa) : \\\n\ttTVPBilinearAffineWithOpacityFunctionObject(func, opa) { ; } \\\n\tvoid DoOnePixel(tjs_uint32 *dest, tjs_uint32 color) \\\n\t{ one; } \\\n\t};\n\tTVP_DEFINE_BILINEAR_AFFINE_FUNCTION(\n\t\tTVPInterpLinTransCopy,\n\t\t*dest = color);\n\n\tTVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(\n\t\tTVPInterpLinTransConstAlphaBlend,\n\t\t*dest = TVPBlendARGB(*dest, color, Opacity));\n\n\n\tTVP_DEFINE_BILINEAR_AFFINE_FUNCTION(\n\t\tTVPInterpLinTransAdditiveAlphaBlend,\n\t\t*dest = TVPAddAlphaBlend_n_a(*dest, color));\n\n\tTVP_DEFINE_BILINEAR_AFFINE_WITH_OPACITY_FUNCTION(\n\t\tTVPInterpLinTransAdditiveAlphaBlend_o,\n\t\t*dest = TVPAddAlphaBlend_n_a_o(*dest, color, Opacity));\n\n\ttemplate <typename tFuncStretch, typename tFuncAffine>\n\tstatic void TVPDoBilinearAffineLoop(\n\t\ttFuncStretch stretch,\n\t\ttFuncAffine affine,\n\t\ttjs_int sxs,\n\t\ttjs_int sys,\n\t\ttjs_uint8 *dest,\n\t\ttjs_int l,\n\t\ttjs_int len,\n\t\tconst tjs_uint8 *src,\n\t\ttjs_int srcpitch,\n\t\ttjs_int sxl,\n\t\ttjs_int syl,\n\t\tconst tTVPRect & srccliprect,\n\t\tconst tTVPRect & srcrect)\n\t{\n\t\t// bilinear interpolation copy\n\t\ttjs_int len_remain = len;\n\t\ttjs_int spx, spy;\n\t\ttjs_int sx, sy;\n\t\ttjs_uint32 *dp;\n\n\t\t// skip \"out of source rectangle\" points\n\t\t// from last point\n\t\tsxl += 32768; // do +0.5 to rounding\n\t\tsyl += 32768; // do +0.5 to rounding\n\n\t\tdp = (tjs_uint32*)dest + l + len - 1;\n\t\tspx = (len - 1)*sxs + sxl;\n\t\tspy = (len - 1)*sys + syl;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\tsx = spx >> 16;\n\t\t\tsy = spy >> 16;\n\t\t\tif (sx >= srcrect.left && sx < srcrect.right &&\n\t\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\t\tbreak;\n\t\t\tdp--;\n\t\t\tspx -= sxs;\n\t\t\tspy -= sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\t// from first point\n\t\tspx = sxl;\n\t\tspy = syl;\n\t\tdp = (tjs_uint32*)dest + l;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\tsx = spx >> 16;\n\t\t\tsy = spy >> 16;\n\t\t\tif (sx >= srcrect.left && sx < srcrect.right &&\n\t\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\t\tbreak;\n\t\t\tdp++;\n\t\t\tl++; // step l forward\n\t\t\tspx += sxs;\n\t\t\tspy += sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\tsxl = spx;\n\t\tsyl = spy;\n\n\t\tsxl -= 32768; // take back the original\n\t\tsyl -= 32768; // take back the original\n\n#define FIX_SX_SY\t\\\n\t\tif (sx < srccliprect.left) \\\n\t\tsx = srccliprect.left, fixed_count++; \\\n\t\tif (sx >= srccliprect.right) \\\n\t\tsx = srccliprect.right - 1, fixed_count++; \\\n\t\tif (sy < srccliprect.top) \\\n\t\tsy = srccliprect.top, fixed_count++; \\\n\t\tif (sy >= srccliprect.bottom) \\\n\t\tsy = srccliprect.bottom - 1, fixed_count++;\n\n\n\t\t// from last point\n\t\tspx = (len_remain - 1)*sxs + sxl/* - 32768*/;\n\t\tspy = (len_remain - 1)*sys + syl/* - 32768*/;\n\t\tdp = (tjs_uint32*)dest + l + len_remain - 1;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\ttjs_int fixed_count = 0;\n\t\t\ttjs_uint32 c00, c01, c10, c11;\n\t\t\ttjs_int blend_x, blend_y;\n\n\t\t\tsx = (spx >> 16);\n\t\t\tsy = (spy >> 16);\n\t\t\tFIX_SX_SY\n\t\t\t\tc00 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16) + 1;\n\t\t\tsy = (spy >> 16);\n\t\t\tFIX_SX_SY\n\t\t\t\tc01 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16);\n\t\t\tsy = (spy >> 16) + 1;\n\t\t\tFIX_SX_SY\n\t\t\t\tc10 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16) + 1;\n\t\t\tsy = (spy >> 16) + 1;\n\t\t\tFIX_SX_SY\n\t\t\t\tc11 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tif (!fixed_count) break;\n\n\t\t\tblend_x = (spx & 0xffff) >> 8;\n\t\t\tblend_x += blend_x >> 7; // adjust blend ratio\n\t\t\tblend_y = (spy & 0xffff) >> 8;\n\t\t\tblend_y += blend_y >> 7;\n\n\t\t\taffine.DoOnePixel(dp, TVPBlendARGB(\n\t\t\t\tTVPBlendARGB(c00, c01, blend_x),\n\t\t\t\tTVPBlendARGB(c10, c11, blend_x),\n\t\t\t\tblend_y));\n\n\t\t\tdp--;\n\t\t\tspx -= sxs;\n\t\t\tspy -= sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\t// from first point\n\t\tspx = sxl/* - 32768*/;\n\t\tspy = syl/* - 32768*/;\n\t\tdp = (tjs_uint32*)dest + l;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\ttjs_int fixed_count = 0;\n\t\t\ttjs_uint32 c00, c01, c10, c11;\n\t\t\ttjs_int blend_x, blend_y;\n\n\t\t\tsx = (spx >> 16);\n\t\t\tsy = (spy >> 16);\n\t\t\tFIX_SX_SY\n\t\t\t\tc00 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16) + 1;\n\t\t\tsy = (spy >> 16);\n\t\t\tFIX_SX_SY\n\t\t\t\tc01 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16);\n\t\t\tsy = (spy >> 16) + 1;\n\t\t\tFIX_SX_SY\n\t\t\t\tc10 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tsx = (spx >> 16) + 1;\n\t\t\tsy = (spy >> 16) + 1;\n\t\t\tFIX_SX_SY\n\t\t\t\tc11 = *((const tjs_uint32*)(src + sy * srcpitch) + sx);\n\n\t\t\tif (!fixed_count) break;\n\n\t\t\tblend_x = (spx & 0xffff) >> 8;\n\t\t\tblend_x += blend_x >> 7; // adjust blend ratio\n\t\t\tblend_y = (spy & 0xffff) >> 8;\n\t\t\tblend_y += blend_y >> 7;\n\n\t\t\taffine.DoOnePixel(dp, TVPBlendARGB(\n\t\t\t\tTVPBlendARGB(c00, c01, blend_x),\n\t\t\t\tTVPBlendARGB(c10, c11, blend_x),\n\t\t\t\tblend_y));\n\n\t\t\tdp++;\n\t\t\tspx += sxs;\n\t\t\tspy += sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\tif (len_remain > 0)\n\t\t{\n\t\t\t// do center part (this may takes most time)\n\t\t\tif (sys == 0)\n\t\t\t{\n\t\t\t\t// do stretch\n\t\t\t\tconst tjs_uint8 * l1 = src + (spy >> 16) * srcpitch;\n\t\t\t\tconst tjs_uint8 * l2 = l1 + srcpitch;\n\t\t\t\tstretch(\n\t\t\t\t\tdp,\n\t\t\t\t\tlen_remain,\n\t\t\t\t\t(const tjs_uint32*)l1,\n\t\t\t\t\t(const tjs_uint32*)l2,\n\t\t\t\t\t(spy & 0xffff) >> 8,\n\t\t\t\t\tspx,\n\t\t\t\t\tsxs);\n\t\t\t} else\n\t\t\t{\n\t\t\t\t// do affine\n\t\t\t\taffine(dp, len_remain,\n\t\t\t\t\t(tjs_uint32*)src, spx, spy, sxs, sys, srcpitch);\n\t\t\t}\n\t\t}\n\t}\n\ttemplate <typename tFuncStretch, typename tFuncAffine>\n\tstatic void TVPDoAffineLoop(\n\t\ttFuncStretch stretch,\n\t\ttFuncAffine affine,\n\t\ttjs_int sxs,\n\t\ttjs_int sys,\n\t\ttjs_uint8 *dest,\n\t\ttjs_int l,\n\t\ttjs_int len,\n\t\tconst tjs_uint8 *src,\n\t\ttjs_int srcpitch,\n\t\ttjs_int sxl,\n\t\ttjs_int syl,\n\t\tconst tTVPRect & srcrect)\n\t{\n\t\ttjs_int len_remain = len;\n\n\t\t// skip \"out of source rectangle\" points\n\t\t// from last point\n\t\tsxl += 32768; // do +0.5 to rounding\n\t\tsyl += 32768; // do +0.5 to rounding\n\n\t\ttjs_int spx, spy;\n\t\ttjs_uint32 *dp;\n\t\tdp = (tjs_uint32*)dest + l + len - 1;\n\t\tspx = (len - 1)*sxs + sxl;\n\t\tspy = (len - 1)*sys + syl;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\ttjs_int sx, sy;\n\t\t\tsx = spx >> 16;\n\t\t\tsy = spy >> 16;\n\t\t\tif (sx >= srcrect.left && sx < srcrect.right &&\n\t\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\t\tbreak;\n\t\t\tdp--;\n\t\t\tspx -= sxs;\n\t\t\tspy -= sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\t// from first point\n\t\tspx = sxl;\n\t\tspy = syl;\n\t\tdp = (tjs_uint32*)dest + l;\n\n\t\twhile (len_remain > 0)\n\t\t{\n\t\t\ttjs_int sx, sy;\n\t\t\tsx = spx >> 16;\n\t\t\tsy = spy >> 16;\n\t\t\tif (sx >= srcrect.left && sx < srcrect.right &&\n\t\t\t\tsy >= srcrect.top && sy < srcrect.bottom)\n\t\t\t\tbreak;\n\t\t\tdp++;\n\t\t\tspx += sxs;\n\t\t\tspy += sys;\n\t\t\tlen_remain--;\n\t\t}\n\n\t\tif (len_remain > 0)\n\t\t{\n\t\t\t// transfer a line\n\t\t\tif (sys == 0)\n\t\t\t\tstretch(dp, len_remain,\n\t\t\t\t(tjs_uint32*)(src + (spy >> 16) * srcpitch), spx, sxs);\n\t\t\telse\n\t\t\t\taffine(dp, len_remain,\n\t\t\t\t(tjs_uint32*)src, spx, spy, sxs, sys, srcpitch);\n\t\t}\n\t}\n\t// declare stretching function object class\n\tclass tTVPStretchFunctionObject\n\t{\n\t\ttTVPStretchFunction Func;\n\tpublic:\n\t\ttTVPStretchFunctionObject(tTVPStretchFunction func) : Func(func) { ; }\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int srcstart, tjs_int srcstep)\n\t\t{\n\t\t\tFunc(dest, len, src, srcstart, srcstep);\n\t\t}\n\t};\n\tclass tTVPStretchWithOpacityFunctionObject\n\t{\n\t\ttTVPStretchWithOpacityFunction Func;\n\t\ttjs_int Opacity;\n\tpublic:\n\t\ttTVPStretchWithOpacityFunctionObject(tTVPStretchWithOpacityFunction func, tjs_int opa) :\n\t\t\tFunc(func), Opacity(opa) {\n\t\t\t;\n\t\t}\n\t\tvoid operator () (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src,\n\t\t\ttjs_int srcstart, tjs_int srcstep)\n\t\t{\n\t\t\tFunc(dest, len, src, srcstart, srcstep, Opacity);\n\t\t}\n\t};\n\n\tint InternalAffineBlt(/*CopyBitmapParam *param,*/tTVPRect destrect, tTVPRect refrect, tTVPRect srcrect,\n\t\tiTVPTexture2D *_src, iTVPTexture2D* dst, const tTVPPointD * points_in, bool rot,\n\t\tconst TAffuncFunc &affineloop)\n\t{\n\t\t//tTVPRect destrect = param->DestRect;\n\t\tint sw = _src->GetWidth(), sh = _src->GetHeight();\n\t\tint dw = dst->GetWidth(), dh = dst->GetHeight();\n\n\t\t// check source rectangle\n\t\tif (refrect.left >= refrect.right ||\n\t\t\trefrect.top >= refrect.bottom) return 1;\n\t\tif (refrect.left < 0 || refrect.top < 0 ||\n\t\t\trefrect.right > sw || refrect.bottom > sh)\n\t\t\tTVPThrowExceptionMessage(TVPOutOfRectangle);\n\n\t\t// multiply source rectangle points by 65536 (16.16 fixed-point)\n\t\t// note that each pixel has actually 1.0 x 1.0 size\n\t\t// eg. a pixel at 0,0 may have (-0.5, -0.5) - (0.5, 0.5) area\n\t\trefrect.left = refrect.left * 65536 - 32768;\n\t\trefrect.top = refrect.top * 65536 - 32768;\n\t\trefrect.right = refrect.right * 65536 - 32768;\n\t\trefrect.bottom = refrect.bottom * 65536 - 32768;\n\n\t\t// create point list in fixed point real format\n\t\ttTVPPoint points[3];\n\t\tfor (tjs_int i = 0; i < 3; i++)\n\t\t\tpoints[i].x = (int)(points_in[i].x * 65536), points[i].y = (int)(points_in[i].y * 65536);\n\n\t\t// check destination rectangle\n\t\tif (destrect.left < 0) destrect.left = 0;\n\t\tif (destrect.top < 0) destrect.top = 0;\n\t\tif (destrect.right > dw) destrect.right = dw;\n\t\tif (destrect.bottom > dh) destrect.bottom = dh;\n\n\t\tif (destrect.left >= destrect.right ||\n\t\t\tdestrect.top >= destrect.bottom) return 1; // not drawable\n\n\t\t// vertex points\n\t\ttjs_int points_x[3];\n\t\ttjs_int points_y[3];\n\n\t\t// check each vertex and find most-top/most-bottom/most-left/most-right points\n\t\ttjs_int scanlinestart, scanlineend; // most-top/most-bottom\n\t\ttjs_int leftlimit, rightlimit; // most-left/most-right\n\n\t\t// - upper-left (p0)\n\t\tif (rot) {\n\t\t\tpoints_x[0] = points[0].x;\n\t\t\tpoints_y[0] = points[0].y;\n\t\t\tpoints_x[1] = points[1].x;\n\t\t\tpoints_y[1] = points[1].y;\n\t\t\tpoints_y[2] = points[2].y;\n\t\t\tpoints_x[2] = points[2].x;\n\t\t} else {\n\t\t\tpoints_x[0] = points[0].x;\n\t\t\tpoints_y[0] = points[0].y;\n\t\t\tpoints_x[1] = points[1].x;\n\t\t\tpoints_y[1] = points[1].y;\n\t\t\tpoints_y[2] = points[2].y;\n\t\t\tpoints_x[2] = points[2].x;\n\t\t}\n\t\tleftlimit = points_x[0];\n\t\trightlimit = points_x[0];\n\t\tscanlinestart = points_y[0];\n\t\tscanlineend = points_y[0];\n\n\t\t// - upper-right (p1)\n\t\tif (leftlimit > points_x[1]) leftlimit = points_x[1];\n\t\tif (rightlimit < points_x[1]) rightlimit = points_x[1];\n\t\tif (scanlinestart > points_y[1]) scanlinestart = points_y[1];\n\t\tif (scanlineend < points_y[1]) scanlineend = points_y[1];\n\n\t\t// - bottom-right (p2)\n\t\tif (leftlimit > points_x[2]) leftlimit = points_x[2];\n\t\tif (rightlimit < points_x[2]) rightlimit = points_x[2];\n\t\tif (scanlinestart > points_y[2]) scanlinestart = points_y[2];\n\t\tif (scanlineend < points_y[2]) scanlineend = points_y[2];\n\n\t\t// rough check destrect intersections\n\t\tif (floor_16(leftlimit) >= destrect.right) return 0;\n\t\tif (floor_16(rightlimit) < destrect.left) return 0;\n\t\tif (floor_16(scanlinestart) >= destrect.bottom) return 0;\n\t\tif (floor_16(scanlineend) < destrect.top) return 0;\n\n\t\t// compute sxstep and systep (step count for source image)\n\t\ttjs_int sxstep, systep;\n\t\tdouble dv01x;\n\t\tdouble dv01y;\n\t\tdouble dv02x;\n\t\tdouble dv02y;\n\t\tif (rot)\n\t\t{\n\t\t\tdv01x = (points[1].x - points[0].x) * (1.0 / 65536.0);\n\t\t\tdv01y = (points[1].y - points[0].y) * (1.0 / 65536.0);\n\t\t\tdv02x = (points[2].x - points[0].x) * (1.0 / 65536.0);\n\t\t\tdv02y = (points[2].y - points[0].y) * (1.0 / 65536.0);\n\t\t} else {\n\t\t\tdv01x = (points[2].x - points[1].x) * (1.0 / 65536.0);\n\t\t\tdv01y = (points[2].y - points[1].y) * (1.0 / 65536.0);\n\t\t\tdv02x = (points[2].x - points[0].x) * (1.0 / 65536.0);\n\t\t\tdv02y = (points[2].y - points[0].y) * (1.0 / 65536.0);\n\t\t}\n\t\t{\n\t\t\tdouble x01, x02, s01, s02;\n\n\t\t\tif (dv01y == 0.0)\n\t\t\t{\n\t\t\t\tsxstep = (tjs_int)((refrect.right - refrect.left) / dv01x);\n\t\t\t\tsystep = 0;\n\t\t\t} else if (dv01y == 0.0)\n\t\t\t{\n\t\t\t\tsxstep = 0;\n\t\t\t\tsystep = (tjs_int)((refrect.bottom - refrect.top) / dv02x);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tx01 = dv01x / dv01y;\n\t\t\t\ts01 = (refrect.right - refrect.left) / dv01y;\n\n\t\t\t\tx02 = dv02x / dv02y;\n\t\t\t\ts02 = (refrect.top - refrect.bottom) / dv02y;\n\n\t\t\t\tdouble len = x01 - x02;\n\n\t\t\t\tsxstep = (tjs_int)(s01 / len);\n\t\t\t\tsystep = (tjs_int)(s02 / len);\n\t\t\t}\n\t\t}\n\n\t\t// prepare to transform...\n\t\ttjs_int yc = (scanlinestart + 32768) / 65536;\n\t\ttjs_int yclim = (scanlineend + 32768) / 65536;\n\n\t\tif (destrect.top > yc) yc = destrect.top;\n\t\tif (destrect.bottom <= yclim) yclim = destrect.bottom - 1;\n\t\tif (yc >= destrect.bottom || yclim < 0)\n\t\t\treturn 0; // not drawable\n\n\t\ttjs_int destpitch = dst->GetPitch();\n\t\ttjs_int srcpitch = _src->GetPitch();\n\t\ttjs_uint8 * dest = (tjs_uint8 *)dst->GetScanLineForWrite(yc);\n\t\tconst tjs_uint8 * src = (const tjs_uint8 *)_src->GetScanLineForRead(0);\n\n\t\ttTVPBBStretchType mode = /*param->mode*/StretchType;\n\t\ttTVPBBStretchType type = (tTVPBBStretchType)(mode & stTypeMask);\n\t\t//tTVPBBBltMethod method = param->method;\n\t\t// make srccliprect\n\t\ttTVPRect srccliprect;\n\t\tif (mode & stRefNoClip)\n\t\t\tsrccliprect.left = 0,\n\t\t\tsrccliprect.top = 0,\n\t\t\tsrccliprect.right = sw,\n\t\t\tsrccliprect.bottom = sh; // no clip; all the bitmap will be the source\n\t\telse\n\t\t\tsrccliprect = srcrect; // clip; the source is limited to the source rectangle\n\n\t\t// process per a line\n\t\ttjs_int mostupper = -1;\n\t\ttjs_int mostbottom = -1;\n\t\tbool firstline = true;\n\n\t\ttjs_int w = destrect.right - destrect.left;\n\t\ttjs_int h = destrect.bottom - destrect.top;\n\n\t\t//bool clear = param->clear, hda = param->hda;\n\t\t//tjs_uint32 clearcolor = param->clearcolor\n\t\ttjs_int opa = 255/*param->opa*/;\n\n\t\tyc = yc * 65536;\n\t\tyclim = yclim * 65536;\n\t\tfor (; yc <= yclim; yc += 65536, dest += destpitch)\n\t\t{\n\t\t\t// transfer a line\n\n\t\t\t// skip out-of-range lines\n\t\t\ttjs_int yl = yc;\n\t\t\tif (yl < scanlinestart)\n\t\t\t\tcontinue;\n\t\t\tif (yl >= scanlineend)\n\t\t\t\tcontinue;\n\n\t\t\t// actual write line\n\t\t\ttjs_int y = (yc + 32768) / 65536;\n\n\t\t\t// find line intersection\n\t\t\t// line codes are:\n\t\t\t// p0 .. p1  : 0\n\t\t\t// p1 .. p2  : 1\n\t\t\t// p2 .. p3  : 2\n\t\t\t// p3 .. p0  : 3\n\t\t\ttjs_int line_code0, line_code1;\n\t\t\ttjs_int where0, where1;\n\t\t\ttjs_int where, code;\n\n\t\t\tfor (code = 0; code < 3; code++)\n\t\t\t{\n\t\t\t\ttjs_int ip0 = code;\n\t\t\t\ttjs_int ip1 = (code + 1) % 3;\n\t\t\t\tif (points_y[ip0] == yl && points_y[ip1] == yl)\n\t\t\t\t{\n\t\t\t\t\twhere = points_x[ip1] > points_x[ip0] ? 0 : 65536;\n\t\t\t\t\tcode += 6;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (code < 6)\n\t\t\t{\n\t\t\t\tfor (code = 0; code < 3; code++)\n\t\t\t\t{\n\t\t\t\t\ttjs_int ip0 = code;\n\t\t\t\t\ttjs_int ip1 = (code + 1) % 3;\n\t\t\t\t\tif (points_y[ip0] <= yl && points_y[ip1] > yl)\n\t\t\t\t\t{\n\t\t\t\t\t\twhere = div_16(yl - points_y[ip0], points_y[ip1] - points_y[ip0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (points_y[ip0] >  yl && points_y[ip1] <= yl)\n\t\t\t\t\t{\n\t\t\t\t\t\twhere = div_16(points_y[ip0] - yl, points_y[ip0] - points_y[ip1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tline_code0 = code;\n\t\t\twhere0 = where;\n\n\t\t\tif (line_code0 < 3)\n\t\t\t{\n\t\t\t\tfor (code = 0; code < 3; code++)\n\t\t\t\t{\n\t\t\t\t\tif (code == line_code0) continue;\n\t\t\t\t\ttjs_int ip0 = code;\n\t\t\t\t\ttjs_int ip1 = (code + 1) % 3;\n\t\t\t\t\tif (points_y[ip0] == yl && points_y[ip1] == yl)\n\t\t\t\t\t{\n\t\t\t\t\t\twhere = points_x[ip1] > points_x[ip0] ? 0 : 65536;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (points_y[ip0] <= yl && points_y[ip1] > yl)\n\t\t\t\t\t{\n\t\t\t\t\t\twhere = div_16(yl - points_y[ip0], points_y[ip1] - points_y[ip0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (points_y[ip0] > yl && points_y[ip1] <= yl)\n\t\t\t\t\t{\n\t\t\t\t\t\twhere = div_16(points_y[ip0] - yl, points_y[ip0] - points_y[ip1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tline_code1 = code;\n\t\t\t\twhere1 = where;\n\t\t\t} else {\n\t\t\t\tline_code0 %= 3;\n\t\t\t\tline_code1 = line_code0;\n\t\t\t\twhere1 = 65536 - where0;\n\t\t\t}\n\n\t\t\t// compute intersection point\n\t\t\ttjs_int ll, rr, sxl, syl, sxr, syr;\n\t\t\tif (rot) {\n\t\t\t\tswitch (line_code0)\n\t\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tll = mul_16(points_x[1] - points_x[0], where0) + points_x[0];\n\t\t\t\t\tsxl = mul_16(refrect.right - refrect.left, where0) + refrect.left;\n\t\t\t\t\tsyl = refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tll = mul_16(points_x[2] - points_x[1], where0) + points_x[1];\n\t\t\t\t\tsxl = mul_16(refrect.left - refrect.right, where0) + refrect.right;\n\t\t\t\t\tsyl = mul_16(refrect.bottom - refrect.top, where0) + refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tll = mul_16(points_x[0] - points_x[2], where0) + points_x[2];\n\t\t\t\t\tsxl = refrect.left;\n\t\t\t\t\tsyl = mul_16(refrect.top - refrect.bottom, where0) + refrect.bottom;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tswitch (line_code1)\n\t\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\trr = mul_16(points_x[1] - points_x[0], where1) + points_x[0];\n\t\t\t\t\tsxr = mul_16(refrect.right - refrect.left, where1) + refrect.left;\n\t\t\t\t\tsyr = refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\trr = mul_16(points_x[2] - points_x[1], where1) + points_x[1];\n\t\t\t\t\tsxr = mul_16(refrect.left - refrect.right, where1) + refrect.right;\n\t\t\t\t\tsyr = mul_16(refrect.bottom - refrect.top, where1) + refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\trr = mul_16(points_x[0] - points_x[2], where1) + points_x[2];\n\t\t\t\t\tsxr = refrect.left;\n\t\t\t\t\tsyr = mul_16(refrect.top - refrect.bottom, where1) + refrect.bottom;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (line_code0) {\n\t\t\t\tcase 0:\n\t\t\t\t\tll = mul_16(points_x[1] - points_x[0], where0) + points_x[0];\n\t\t\t\t\tsxl = mul_16(refrect.left - refrect.right, where0) + refrect.right;\n\t\t\t\t\tsyl = mul_16(refrect.bottom - refrect.top, where0) + refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tll = mul_16(points_x[2] - points_x[1], where0) + points_x[1];\n\t\t\t\t\tsyl = refrect.bottom;\n\t\t\t\t\tsxl = mul_16(refrect.right - refrect.left, where0) + refrect.left;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tll = mul_16(points_x[0] - points_x[2], where0) + points_x[2];\n\t\t\t\t\tsxl = refrect.right;\n\t\t\t\t\tsyl = mul_16(refrect.top - refrect.bottom, where0) + refrect.bottom;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tswitch (line_code1)\n\t\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\trr = mul_16(points_x[1] - points_x[0], where1) + points_x[0];\n\t\t\t\t\tsxr = mul_16(refrect.left - refrect.right, where1) + refrect.right;\n\t\t\t\t\tsyr = mul_16(refrect.bottom - refrect.top, where1) + refrect.top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\trr = mul_16(points_x[2] - points_x[1], where1) + points_x[1];\n\t\t\t\t\tsxr = mul_16(refrect.right - refrect.left, where1) + refrect.left;\n\t\t\t\t\tsyr = refrect.bottom;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\trr = mul_16(points_x[0] - points_x[2], where1) + points_x[2];\n\t\t\t\t\tsxr = refrect.right;\n\t\t\t\t\tsyr = mul_16(refrect.top - refrect.bottom, where1) + refrect.bottom;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// l, r, sxs, sys, and len\n\t\t\ttjs_int sxs, sys, len;\n\t\t\tsxs = sxstep;\n\t\t\tsys = systep;\n\t\t\tif (ll > rr)\n\t\t\t{\n\t\t\t\tstd::swap(ll, rr);\n\t\t\t\tstd::swap(sxl, sxr);\n\t\t\t\tstd::swap(syl, syr);\n\t\t\t}\n\n\t\t\t// round l and r to integer\n\t\t\ttjs_int l, r;\n\n\t\t\t// 0x8000000 were choosed to avoid special divition behavior around zero\n\t\t\tl = ((tjs_uint32)(ll + 0x80000000ul - 1) / 65536) - (0x80000000ul / 65536) + 1;\n\t\t\tsxl += mul_16(65535 - ((tjs_uint32)(ll + 0x80000000ul - 1) % 65536), sxs); // adjust source start point x\n\t\t\tsyl += mul_16(65535 - ((tjs_uint32)(ll + 0x80000000ul - 1) % 65536), sys); // adjust source start point y\n\n\t\t\tr = ((tjs_uint32)(rr + 0x80000000ul - 1) / 65536) - (0x80000000ul / 65536) + 1; // note that at this point r is *NOT* inclusive\n\n\t\t\t// - clip widh destrect.left and destrect.right\n\t\t\tif (l < destrect.left)\n\t\t\t{\n\t\t\t\ttjs_int d = destrect.left - l;\n\t\t\t\tsxl += d * sxs;\n\t\t\t\tsyl += d * sys;\n\t\t\t\tl = destrect.left;\n\t\t\t}\n\t\t\tif (r > destrect.right) r = destrect.right;\n\n\t\t\t// - compute horizontal length\n\t\t\tlen = r - l;\n\n\t\t\t// - transfer\n\t\t\tif (len > 0)\n\t\t\t{\n\t\t\t\t// fill left and right of the line if 'clear' is specified\n// \t\t\t\tif (clear)\n// \t\t\t\t{\n// \t\t\t\t\ttjs_int clen;\n// \n// \t\t\t\t\tint ll = l + 1;\n// \t\t\t\t\tif (ll > destrect.right) ll = destrect.right;\n// \t\t\t\t\tclen = ll - destrect.left;\n// \t\t\t\t\tif (clen > 0)\n// \t\t\t\t\t\t(hda ? TVPFillColor : TVPFillARGB)((tjs_uint32*)dest + destrect.left, clen, clearcolor);\n// \t\t\t\t\tint rr = r - 1;\n// \t\t\t\t\tif (rr < destrect.left) rr = destrect.left;\n// \t\t\t\t\tclen = destrect.right - rr;\n// \t\t\t\t\tif (clen > 0)\n// \t\t\t\t\t\t(hda ? TVPFillColor : TVPFillARGB)((tjs_uint32*)dest + rr, clen, clearcolor);\n// \t\t\t\t}\n\n\t\t\t\t// update updaterect\n\t\t\t\tif (firstline)\n\t\t\t\t{\n\t\t\t\t\tleftlimit = l;\n\t\t\t\t\trightlimit = r;\n\t\t\t\t\tfirstline = false;\n\t\t\t\t\tmostupper = mostbottom = y;\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tif (l < leftlimit) leftlimit = l;\n\t\t\t\t\tif (r > rightlimit) rightlimit = r;\n\t\t\t\t\tmostbottom = y;\n\t\t\t\t}\n\n\t\t\t\t// transfer using each blend function\n\t\t\t\taffineloop(TVP_DoBilinearAffineLoop_ARGS);\n\t\t\t}\n\t\t}\n\n\t\t// clear upper and lower area of the affine transformation\n// \t\tif (clear)\n// \t\t{\n// \t\t\ttjs_int h;\n// \t\t\ttjs_uint8 * dest = param->Dst.ImageBuff;\n// \t\t\ttjs_uint8 * p;\n// \t\t\tif (mostupper == -1 && mostbottom == -1)\n// \t\t\t{\n// \t\t\t\t// special case: nothing was drawn;\n// \t\t\t\t// clear entire area of the destrect\n// \t\t\t\tmostupper = destrect.bottom;\n// \t\t\t\tmostbottom = destrect.bottom - 1;\n// \t\t\t}\n// \n// \t\t\th = mostupper - destrect.top;\n// \t\t\tif (h > 0)\n// \t\t\t{\n// \t\t\t\tp = dest + destrect.top * destpitch;\n// \t\t\t\tdo\n// \t\t\t\t(hda ? TVPFillColor : TVPFillARGB)((tjs_uint32*)p + destrect.left,\n// \t\t\t\t\tdestrect.right - destrect.left, clearcolor),\n// \t\t\t\t\tp += destpitch;\n// \t\t\t\twhile (--h);\n// \t\t\t}\n// \n// \t\t\th = destrect.bottom - (mostbottom + 1);\n// \t\t\tif (h > 0)\n// \t\t\t{\n// \t\t\t\tp = dest + (mostbottom + 1) * destpitch;\n// \t\t\t\tdo\n// \t\t\t\t(hda ? TVPFillColor : TVPFillARGB)((tjs_uint32*)p + destrect.left,\n// \t\t\t\t\tdestrect.right - destrect.left, clearcolor),\n// \t\t\t\t\tp += destpitch;\n// \t\t\t\twhile (--h);\n// \t\t\t}\n// \n// \t\t}\n\n\t\t//return (clear || !firstline) ? 2 : 0;\n\t\treturn 0;\n\t}\n\n\tvirtual void OperatePerspective(iTVPRenderMethod* method, int nQuads,\n\t\tiTVPTexture2D *target, iTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* pttar/*quad*/,\n\t\tconst tRenderTexQuadArray &textures) {\n\t\tassert(textures.size() == 1);\n\t\tfor (int i = 0; i < textures.size(); ++i) {\n\t\t\ttextures[i].first->GetScanLineForRead(0); // prepare pixel data for compressed texture\n\t\t}\n\t\tiTVPTexture2D *dst = target;\n\t\tconst tTVPPointD *dstpt = pttar;\n\t\tiTVPTexture2D *src = textures[0].first;\n\t\tconst tTVPPointD *srcpt = textures[0].second;\n\t\tfor (int i = 0; i < nQuads; ++i) {\n\t\t\tbool isSrcRect = // route for square rect\n\t\t\t\tisDoubleEqual(srcpt[0].y, srcpt[1].y) &&\n\t\t\t\tisDoubleEqual(srcpt[1].x, srcpt[3].x) &&\n\t\t\t\tisDoubleEqual(srcpt[0].x, srcpt[2].x) &&\n\t\t\t\tisDoubleEqual(srcpt[2].y, srcpt[3].y)\n\t\t\t\t&&\n\t\t\t\tisDoubleEqual(dstpt[0].y, dstpt[1].y) &&\n\t\t\t\tisDoubleEqual(dstpt[1].x, dstpt[3].x) &&\n\t\t\t\tisDoubleEqual(dstpt[0].x, dstpt[2].x) &&\n\t\t\t\tisDoubleEqual(dstpt[2].y, dstpt[3].y);\n\t\t\tbool processed = false;\n\n\t\t\tif (isSrcRect) do {\n\t\t\t\ttTVPRect dstrect(dstpt[0].x, dstpt[0].y, dstpt[2].x, dstpt[2].y);\n\t\t\t\ttTVPRect refrect(srcpt[0].x, srcpt[0].y, srcpt[2].x, srcpt[2].y);\n\t\t\t\tif (dstrect.left > dstrect.right || dstrect.top > dstrect.bottom\n\t\t\t\t\t|| refrect.left > refrect.right || refrect.top > refrect.bottom)\n\t\t\t\t\tbreak;\n\t\t\t\tconst tTVPRect &cr = rcclip;\n\n\t\t\t\tif (refrect.right < refrect.left && dstrect.right < dstrect.left) {\n\t\t\t\t\tstd::swap(refrect.left, refrect.right);\n\t\t\t\t\tstd::swap(dstrect.left, dstrect.right);\n\t\t\t\t}\n\t\t\t\tif (refrect.bottom < refrect.top && dstrect.bottom < dstrect.top) {\n\t\t\t\t\tstd::swap(refrect.bottom, refrect.top);\n\t\t\t\t\tstd::swap(dstrect.bottom, dstrect.top);\n\t\t\t\t}\n\t\t\t\ttTVPRect rcdest;\n\t\t\t\tif (TVPIntersectRect(&rcdest, cr, dstrect)) {\n\t\t\t\t\ttjs_int dw = dstrect.get_width(), dh = dstrect.get_height();\n\t\t\t\t\ttjs_int rw = refrect.get_width(), rh = refrect.get_height();\n\n\t\t\t\t\tif (rcdest.left > dstrect.left) {\n\t\t\t\t\t\trefrect.left += (float)rw / dw * (rcdest.left - dstrect.left);\n\t\t\t\t\t}\n\t\t\t\t\tif (rcdest.right < dstrect.right) {\n\t\t\t\t\t\trefrect.right -= (float)rw / dw * (dstrect.right - rcdest.right);\n\t\t\t\t\t}\n\t\t\t\t\tif (rcdest.top > dstrect.top) {\n\t\t\t\t\t\trefrect.top += (float)rh / dh * (rcdest.top - dstrect.top);\n\t\t\t\t\t}\n\t\t\t\t\tif (rcdest.bottom < dstrect.bottom) {\n\t\t\t\t\t\trefrect.bottom -= (float)rh / dh * (dstrect.bottom - rcdest.bottom);\n\t\t\t\t\t}\n\t\t\t\t\tOperateRect(method, target, rcdest, src, refrect);\n\t\t\t\t\tprocessed = true;\n\t\t\t\t}\n\t\t\t} while (false);\n\t\t\tif (!processed) {\n\t\t\t\tconst uint8_t *sdata;\n\t\t\t\tint spitch = src->GetPitch();\n\t\t\t\tsdata = (const uint8_t *)src->GetPixelData();\n\t\t\t\tcv::Mat src_img(src->GetHeight(), src->GetWidth(), CV_8UC4, (void*)sdata, spitch);\n\t\t\t\tcv::Mat dst_img;\n\t\t\t\tcv::Size dst_size(rcclip.get_width(), rcclip.get_height());\n\n\t\t\t\t// upper-left, upper-right, bottom-right, bottom-left\n\t\t\t\tcv::Point2f pts_src[] = {\n\t\t\t\t\tcv::Point2f(srcpt[0].x, srcpt[0].y),\n\t\t\t\t\tcv::Point2f(srcpt[1].x + 1, srcpt[1].y),\n\t\t\t\t\tcv::Point2f(srcpt[3].x + 1, srcpt[3].y + 1),\n\t\t\t\t\tcv::Point2f(srcpt[2].x, srcpt[2].y + 1) };\n\t\t\t\tcv::Point2f pts_dst[] = {\n\t\t\t\t\tcv::Point2f(dstpt[0].x - rcclip.left, dstpt[0].y - rcclip.top),\n\t\t\t\t\tcv::Point2f(dstpt[1].x - rcclip.left, dstpt[1].y - rcclip.top),\n\t\t\t\t\tcv::Point2f(dstpt[3].x - rcclip.left, dstpt[3].y - rcclip.top),\n\t\t\t\t\tcv::Point2f(dstpt[2].x - rcclip.left, dstpt[2].y - rcclip.top) };\n\n\t\t\t\tcv::Mat perspective_matrix = cv::getPerspectiveTransform(pts_src, pts_dst);\n\t\t\t\tcv::warpPerspective(src_img, dst_img, perspective_matrix, dst_size, cvFlags[StretchType]);\n\n\t\t\t\tiTVPTexture2D *tmp = new tTVPSoftwareTexture2D_static(dst_img.ptr(0), dst_img.step1(0), dst_size.width, dst_size.height, TVPTextureFormat::RGBA);\n\t\t\t\ttTVPRect rc(0, 0, dst_size.width, dst_size.height);\n\n\t\t\t\t((tTVPRenderMethod_Software*)method)->DoRender(\n\t\t\t\t\ttarget, rcclip,\n\t\t\t\t\ttarget, rcclip,\n\t\t\t\t\ttmp, rc,\n\t\t\t\t\tnullptr, rc);\n\t\t\t\ttmp->Release();\n\t\t\t}\n\n\t\t\tdstpt += 4;\n\t\t\tsrcpt += 4;\n\t\t}\n\t}\n};\n\nstatic std::map<ttstr, std::pair<iTVPRenderManager*(*)(), iTVPRenderManager*> > *_RenderManagerFactory;\n\nvoid TVPRegisterRenderManager(const char* name, iTVPRenderManager*(*func)()) {\n\tif (!_RenderManagerFactory) _RenderManagerFactory = new std::map<ttstr, std::pair<iTVPRenderManager*(*)(), iTVPRenderManager*> >;\n\t_RenderManagerFactory->emplace(name, std::make_pair(func, nullptr));\n}\n\niTVPRenderManager * TVPGetRenderManager(const ttstr &name)\n{\n\tauto it = _RenderManagerFactory->find(name);\n\tif (it == _RenderManagerFactory->end()) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"unsupported renderer %1\"), name);\n\t}\n\tif (it->second.second) {\n\t\treturn it->second.second;\n\t}\n\tiTVPRenderManager *mgr = it->second.first();\n\tmgr->Initialize();\n\tit->second.second = mgr;\n\treturn mgr;\n}\n\niTVPRenderManager * TVPGetRenderManager() {\n\tstatic iTVPRenderManager *_RenderManager;\n\tif (!_RenderManager) {\n\t\tttstr str = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"renderer\", \"software\");\n\t\t_RenderManager = TVPGetRenderManager(str);\n\t}\n\treturn _RenderManager;\n}\n\nbool TVPIsSoftwareRenderManager() {\n\tstatic bool ret = TVPGetRenderManager()->IsSoftware();\n\treturn ret;\n}\n\niTVPRenderManager * TVPGetSoftwareRenderManager() { // for province image process\n\tstatic tTVPSoftwareRenderManager* mgr = new tTVPSoftwareRenderManager;\n\treturn mgr;\n}\n\nstatic class __tTVPSoftwareRenderManagerAutoReigster{\npublic: __tTVPSoftwareRenderManagerAutoReigster() { TVPRegisterRenderManager(\"software\", TVPGetSoftwareRenderManager); }\n} __tTVPSoftwareRenderManagerAutoReigster_instance;\n"
  },
  {
    "path": "src/core/visual/RenderManager.h",
    "content": "#pragma once\n#include \"ComplexRect.h\"\n#include <unordered_map>\n#include <stdint.h>\n#include <string>\n\n#ifndef GL_ZERO\n#define GL_ZERO 0\n#define GL_ONE  1\n#endif\n#ifndef GL_SRC_ALPHA\n#define GL_SRC_ALPHA 0x0302\n#define GL_ONE_MINUS_SRC_ALPHA            0x0303\n#define GL_ONE_MINUS_DST_ALPHA            0x0305\n#define GL_FUNC_ADD 0x8006\n#endif\n#ifndef GL_MAX\n#define GL_MIN 0x8007\n#define GL_MAX 0x8008\n#define GL_FUNC_REVERSE_SUBTRACT 0x800B\n#endif\n#if 0\nstruct _BITMAPINFO;\n//---------------------------------------------------------------------------\n// tTVPBitmap : internal bitmap object\n//---------------------------------------------------------------------------\nclass tTVPBitmap\n{\n\ttjs_int RefCount;\n\n\tvoid * Bits; // pointer to bitmap bits\n\t_BITMAPINFO *BitmapInfo; // DIB information\n\ttjs_int BitmapInfoSize;\n\n\ttjs_int PitchBytes; // bytes required in a line\n\ttjs_int PitchStep; // step bytes to next(below) line\n\ttjs_int Width; // actual width\n\ttjs_int Height; // actual height\n\npublic:\n\ttTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp);\n\n\ttTVPBitmap(const tTVPBitmap & r);\n\n\t~tTVPBitmap();\n\n\tvoid Allocate(tjs_uint width, tjs_uint height, tjs_uint bpp);\n\n\tvoid AddRef(void)\n\t{\n\t\tRefCount++;\n\t}\n\n\tvoid Release(void)\n\t{\n\t\tif (RefCount == 1)\n\t\t\tdelete this;\n\t\telse\n\t\t\tRefCount--;\n\t}\n\n\ttjs_uint GetWidth() const { return Width; }\n\ttjs_uint GetHeight() const { return Height; }\n\n\ttjs_uint GetBPP() const;\n\tbool Is32bit() const;\n\tbool Is8bit() const;\n\n\n\tvoid * GetScanLine(tjs_uint l) const;\n\n\ttjs_int GetPitch() const { return PitchStep; }\n\n\tbool IsIndependent() const { return RefCount == 1; }\n\n\tconst void * GetBits() const { return Bits; }\n};\n#else\n//#include \"LayerBitmapImpl.h\"\n#endif\n\nstruct TVPTextureFormat {\n\tenum e {\n\t\tNone = 0,\n\t\tGray = 1,\n\t\tRGB = 3,\n\t\tRGBA = 4,\n\t\t// for opengl compressed texture, the argument pitch = block_width | (block_height << 16) or block_size\n\t\tCompressed = 0x10000,\n\t\tCompressedEnd = 0x20000,\n\t};\n};\n\nnamespace cocos2d {\n\tclass Texture2D;\n};\n\nclass iTVPTexture2D\n{\nprotected:\n\tint RefCount;\n\ttjs_int Width; // actual width\n\ttjs_int Height; // actual height\n\t//int Flags, TexWidth, TexHeight, ActualWidth, ActualHeight;\n\tiTVPTexture2D(tjs_int w, tjs_int h) : Width(w), Height(h), RefCount(1) {}\npublic:\n\tvirtual ~iTVPTexture2D() {};\n\tvoid AddRef() { ++RefCount; }\n\tvirtual void Release();\n\ttjs_uint GetWidth() const { return Width; }\n\ttjs_uint GetHeight() const { return Height; }\n\tvirtual tjs_uint GetInternalWidth() const { return Width; }\n\tvirtual tjs_uint GetInternalHeight() const { return Height; }\n\tvirtual void SetSize(unsigned int w, unsigned int h) { // may lost image content\n\t\tWidth = w; Height = h;\n\t}\n\n\tvirtual TVPTextureFormat::e GetFormat() const = 0;\n\tvirtual const void * GetScanLineForRead(tjs_uint l) { return nullptr; }\n\tvirtual const void * GetPixelData() { return GetScanLineForRead(0); }\n\tvirtual void * GetScanLineForWrite(tjs_uint l) { return (void*)GetScanLineForRead(l); }\n\tvirtual tjs_int GetPitch() const { return 0x100000; }\n\tbool IsIndependent() const { return RefCount == 1; }\n\n\t//virtual tGLTexture* GetTexture() = 0;\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) = 0;\n\tvirtual uint32_t GetPoint(int x, int y) = 0;\n\tvirtual void SetPoint(int x, int y, uint32_t clr) = 0;\n\tvirtual bool IsStatic() = 0; // aka. is readonly\n\tvirtual bool IsOpaque() = 0;\n\t//virtual void RefreshBitmap() = 0;\n\tvirtual cocos2d::Texture2D* GetAdapterTexture(cocos2d::Texture2D* origTex) = 0;\n\tvirtual bool GetScale(float &x, float &y) { x = 1.f; y = 1.f; return true; }\n\n\tstatic void RecycleProcess();\n};\n\nclass iTVPRenderMethod\n{\nprotected:\n\tvirtual ~iTVPRenderMethod() {} // undeletable\n\tstd::string Name;\npublic:\n\t// the parameter id should not change in whole lifecycle, valid id >= 0\n\tvirtual int EnumParameterID(const char *name) { return -1; };\n\tvirtual void SetParameterUInt(int id, unsigned int Value) {};\n\tvirtual void SetParameterInt(int id, int Value) {};\n\tvirtual void SetParameterPtr(int id, const void *Value) {};\n\tvirtual void SetParameterFloat(int id, float Value) {};\n\tvirtual void SetParameterColor4B(int id, unsigned int clr) {};\n\tvirtual void SetParameterOpa(int id, int Value) {};\n\tvirtual void SetParameterFloatArray(int id, float *Value, int nElem) {};\n\tvirtual iTVPRenderMethod* SetBlendFuncSeparate(int func, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) { return this; }\n\tvirtual bool IsBlendTarget() { return true; }\n\tvoid SetName(const std::string &name) { Name = name; }\n\tconst std::string &GetName() { return Name; }\n};\n\ntemplate <typename TElem>\nclass tRenderTextureArray {\n\tconst std::pair<iTVPTexture2D*, TElem>* pElem;\n\tsize_t nCount;\n\npublic:\n\ttypedef std::pair<iTVPTexture2D*, TElem> Element;\n\ttRenderTextureArray() : pElem(nullptr), nCount(0) {}\n\ttRenderTextureArray(std::pair<iTVPTexture2D*, TElem> *p, size_t n) : pElem(p), nCount(n) {}\n\n\ttemplate<typename T>\n\ttRenderTextureArray(const T& arr) {\n\t\tpElem = arr;\n\t\tnCount = sizeof(arr) / sizeof(arr[0]);\n\t}\n\n\tconst std::pair<iTVPTexture2D*, TElem>& operator[](size_t i) const {\n\t\treturn pElem[i];\n\t}\n\n\tsize_t size() const { return nCount; }\n};\n\ntypedef tRenderTextureArray<tTVPRect> tRenderTexRectArray;\ntypedef tRenderTextureArray<const tTVPPointD*> tRenderTexQuadArray;\n\nclass tTVPBitmap;\nnamespace TJS {\n\tclass tTJSBinaryStream;\n}\nclass iTVPRenderManager\n{\nprotected:\n\tvirtual ~iTVPRenderManager() {} // undeletable\n\tvoid RegisterRenderMethod(const char *name, iTVPRenderMethod* method);\n\tvirtual iTVPRenderMethod* GetRenderMethodFromScript(const char *script, int nTex, unsigned int flags) { return nullptr; }\n\tstd::unordered_map<uint32_t, iTVPRenderMethod*> AllMethods;\n\npublic:\n\tvoid Initialize();\n\npublic:\n#define RENDER_CREATE_TEXTURE_FLAG_ANY 0\n#define RENDER_CREATE_TEXTURE_FLAG_STATIC 1\n#define RENDER_CREATE_TEXTURE_FLAG_NO_COMPRESS 2\n\tvirtual iTVPTexture2D* CreateTexture2D(const void *pixel, int pitch, unsigned int w, unsigned int h,\n\t\tTVPTextureFormat::e format, int flags = RENDER_CREATE_TEXTURE_FLAG_ANY) = 0;\n\tvirtual iTVPTexture2D* CreateTexture2D(tTVPBitmap* bmp) = 0; // for province image\n\tvirtual iTVPTexture2D* CreateTexture2D(TJS::tTJSBinaryStream* s) = 0; // for compressed or special image format\n\tvirtual iTVPTexture2D* CreateTexture2D( // create and copy content from exist texture\n\t\tunsigned int neww, unsigned int newh, iTVPTexture2D* tex) = 0;\n\n\t// each method is singleton in whole lifecycle\n\tvirtual iTVPRenderMethod* GetRenderMethod(const char *name, uint32_t *hint = nullptr);\n#define RENDER_METHOD_FLAG_NONE 0\n#define RENDER_METHOD_FLAG_TARGET_AS_INPUT 1\n\tiTVPRenderMethod* CompileRenderMethod(const char *name, const char *glsl_script, int nTex, unsigned int flags = 0);\n\tiTVPRenderMethod* GetOrCompileRenderMethod(const char *name, uint32_t *hint, const char *glsl_script, int nTex, unsigned int flags = 0);\n\n\tvirtual bool IsSoftware() { return false; }\n\tvirtual const char *GetName() = 0;\n\n\tvirtual bool GetRenderStat(unsigned int &drawCount, uint64_t &vmemsize) = 0;\n\tvirtual bool GetTextureStat(iTVPTexture2D *texture, uint64_t &vmemsize) { return false; }\n\n\tvirtual void BeginStencil(iTVPTexture2D* reftex) {}\n\tvirtual void EndStencil() {}\n\n\tvirtual void SetRenderTarget(iTVPTexture2D *target) {} // for manual rendering\n\n\t// interface to access custom parameter\n\tvirtual int EnumParameterID(const char *name) { return -1; }\n\tvirtual void SetParameterUInt(int id, unsigned int Value) {};\n\tvirtual void SetParameterInt(int id, int Value) {};\n\tvirtual void SetParameterPtr(int id, const void *Value) {};\n\tvirtual void SetParameterFloat(int id, float Value) {};\n\n\t// -------------- operations ----------------\n\t// dst x Tex1 x ... x TexN -> dst\n\t// referenced target texture would be used if target texture is required as source\n\tvirtual void OperateRect(iTVPRenderMethod* method, iTVPTexture2D *tar, iTVPTexture2D *reftar,\n\t\tconst tTVPRect& rctar, const tRenderTexRectArray &textures) = 0;\n\n\t// src x dst -> tar\n\tvirtual void OperateTriangles(iTVPRenderMethod* method, int nTriangles,\n\t\tiTVPTexture2D *target, iTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* pttar,\n\t\tconst tRenderTexQuadArray &textures) = 0;\n\n\t// src -> tar\n\tvirtual void OperatePerspective(iTVPRenderMethod* method, int nQuads, iTVPTexture2D *target,\n\t\tiTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* pttar/*quad{lt,rt,lb,rb}*/,\n\t\tconst tRenderTexQuadArray &textures) = 0;\n\npublic:\n\t// utility function\n\tiTVPRenderMethod* GetRenderMethod(tjs_int opa, bool hda, int/*tTVPBBBltMethod*/ method);\n\tstruct tRenderMethodCache* RenderMethodCache = nullptr;\n\n};\n\nvoid TVPRegisterRenderManager(const char* name, iTVPRenderManager*(*func)());\n\n#define REGISTER_RENDERMANAGER(MGR, NAME) \\\n\tstatic iTVPRenderManager* __ ## MGR ## Factory() { return new MGR(); } \\\n\tstatic class __ ## MGR ## AutoReigster{ \\\n\tpublic: __ ## MGR ## AutoReigster() { TVPRegisterRenderManager(#NAME, __ ## MGR ## Factory); } \\\n\t} __ ## MGR ## AutoReigster_instance;\n\niTVPRenderManager *TVPGetRenderManager();\nnamespace TJS { class tTJSString; }\niTVPRenderManager *TVPGetRenderManager(const TJS::tTJSString &name);\nbool TVPIsSoftwareRenderManager();"
  },
  {
    "path": "src/core/visual/RenderManager_software.h",
    "content": "#pragma once\n#include \"RenderManager.h\"\n\nclass tTVPRenderMethod_Software : public iTVPRenderMethod {\npublic:\n\tvirtual void DoRender(\n\t\tiTVPTexture2D *_tar, const tTVPRect &rctar,\n\t\tiTVPTexture2D *_dst, const tTVPRect &rcdst,\n\t\tiTVPTexture2D *_src, const tTVPRect &rcsrc,\n\t\tiTVPTexture2D *rule, const tTVPRect &rcrule) = 0;\n};"
  },
  {
    "path": "src/core/visual/SaveTLG.h",
    "content": "\n#ifndef LoadTLGH\n#define LoadTLGH\n\n#define SLIDE_N 4096\n#define SLIDE_M (18+255)\nclass SlideCompressor\n{\n\t// XCh@ kNX\n\tstruct Chain\n\t{\n\t\tint Prev;\n\t\tint Next;\n\t};\n\n\tunsigned char Text[SLIDE_N + SLIDE_M - 1];\n\tint Map[256*256];\n\tChain Chains[SLIDE_N];\n\n\n\tunsigned char Text2[SLIDE_N + SLIDE_M - 1];\n\tint Map2[256*256];\n\tChain Chains2[SLIDE_N];\n\n\n\tint S;\n\tint S2;\n\npublic:\n\tSlideCompressor();\n\tvirtual ~SlideCompressor();\n\nprivate:\n\tint GetMatch(const unsigned char*cur, int curlen, int &pos, int s);\n\tvoid AddMap(int p);\n\tvoid DeleteMap(int p);\n\npublic:\n\tvoid Encode(const unsigned char *in, long inlen,\n\t\tunsigned char *out, long & outlen);\n\n\tvoid Store();\n\tvoid Restore();\n};\n#endif\n"
  },
  {
    "path": "src/core/visual/SaveTLG5.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsUtils.h\"\n#include \"tvpgl.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"BinaryStream.h\"\n\n#include <stdlib.h>\n#include \"SaveTLG.h\"\n\n//---------------------------------------------------------------------------\nSlideCompressor::SlideCompressor()\n{\n\tS = 0;\n\tfor(int i = 0; i < SLIDE_N + SLIDE_M; i++) Text[i] = 0;\n\tfor(int i = 0; i < 256*256; i++)\n\t\tMap[i] = -1;\n\tfor(int i = 0; i < SLIDE_N; i++)\n\t\tChains[i].Prev = Chains[i].Next = -1;\n\tfor(int i = SLIDE_N - 1; i >= 0; i--)\n\t\tAddMap(i);\n}\n//---------------------------------------------------------------------------\nSlideCompressor::~SlideCompressor()\n{\n}\n//---------------------------------------------------------------------------\nint SlideCompressor::GetMatch(const unsigned char*cur, int curlen, int &pos, int s)\n{\n\t// get match length\n\tif(curlen < 3) return 0;\n\n\tint place = cur[0] + ((int)cur[1] << 8);\n\n\tint maxlen = 0;\n\tif((place = Map[place]) != -1)\n\t{\n\t\tint place_org;\n\t\tcurlen -= 1;\n\t\tdo\n\t\t{\n\t\t\tplace_org = place;\n\t\t\tif(s == place || s == ((place + 1) & (SLIDE_N -1))) continue;\n\t\t\tplace += 2;\n\t\t\tint lim = (SLIDE_M < curlen ? SLIDE_M : curlen) + place_org;\n\t\t\tconst unsigned char *c = cur + 2;\n\t\t\tif(lim >= SLIDE_N)\n\t\t\t{\n\t\t\t\tif(place_org <= s && s < SLIDE_N)\n\t\t\t\t\tlim = s;\n\t\t\t\telse if(s < (lim&(SLIDE_N-1)))\n\t\t\t\t\tlim = s + SLIDE_N;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(place_org <= s && s < lim)\n\t\t\t\t\tlim = s;\n\t\t\t}\n\t\t\twhile(Text[place] == *(c++) && place < lim) place++;\n\t\t\tint matchlen = place - place_org;\n\t\t\tif(matchlen > maxlen) pos = place_org, maxlen = matchlen;\n\t\t\tif(matchlen == SLIDE_M) return maxlen;\n\n\t\t} while((place = Chains[place_org].Next) != -1);\n\t}\n\treturn maxlen;\n}\n//---------------------------------------------------------------------------\nvoid SlideCompressor::AddMap(int p)\n{\n\tint place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);\n\n\tif(Map[place] == -1)\n\t{\n\t\t// first insertion\n\t\tMap[place] = p;\n\t}\n\telse\n\t{\n\t\t// not first insertion\n\t\tint old = Map[place];\n\t\tMap[place] = p;\n\t\tChains[old].Prev = p;\n\t\tChains[p].Next = old;\n\t\tChains[p].Prev = -1;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid SlideCompressor::DeleteMap(int p)\n{\n\tint n;\n\tif((n = Chains[p].Next) != -1)\n\t\tChains[n].Prev = Chains[p].Prev;\n\n\tif((n = Chains[p].Prev) != -1)\n\t{\n\t\tChains[n].Next = Chains[p].Next;\n\t}\n\telse if(Chains[p].Next != -1)\n\t{\n\t\tint place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);\n\t\tMap[place] = Chains[p].Next;\n\t}\n\telse\n\t{\n\t\tint place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);\n\t\tMap[place] = -1;\n\t}\n\n\tChains[p].Prev = -1;\n\tChains[p].Next = -1;\n}\n//---------------------------------------------------------------------------\nvoid SlideCompressor::Encode(const unsigned char *in, long inlen,\n\t\tunsigned char *out, long & outlen)\n{\n\tunsigned char code[40], codeptr, mask;\n\n\tif(inlen == 0) return;\n\n\toutlen = 0;\n\tcode[0] = 0;\n\tcodeptr = mask = 1;\n\n\tint s = S;\n\twhile(inlen > 0)\n\t{\n\t\tint pos = 0;\n\t\tint len = GetMatch(in, inlen, pos, s);\n\t\tif(len >= 3)\n\t\t{\n\t\t\tcode[0] |= mask;\n\t\t\tif(len >= 18)\n\t\t\t{\n\t\t\t\tcode[codeptr++] = pos & 0xff;\n\t\t\t\tcode[codeptr++] = ((pos &0xf00)>> 8) | 0xf0;\n\t\t\t\tcode[codeptr++] = len - 18;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcode[codeptr++] = pos & 0xff;\n\t\t\t\tcode[codeptr++] = ((pos&0xf00)>> 8) | ((len-3)<<4);\n\t\t\t}\n\t\t\twhile(len--)\n\t\t\t{\n\t\t\t\tunsigned char c = 0[in++];\n\t\t\t\tDeleteMap((s - 1) & (SLIDE_N - 1));\n\t\t\t\tDeleteMap(s);\n\t\t\t\tif(s < SLIDE_M - 1) Text[s + SLIDE_N] = c;\n\t\t\t\tText[s] = c;\n\t\t\t\tAddMap((s - 1) & (SLIDE_N - 1));\n\t\t\t\tAddMap(s);\n\t\t\t\ts++;\n\t\t\t\tinlen--;\n\t\t\t\ts &= (SLIDE_N - 1);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned char c = 0[in++];\n\t\t\tDeleteMap((s - 1) & (SLIDE_N - 1));\n\t\t\tDeleteMap(s);\n\t\t\tif(s < SLIDE_M - 1) Text[s + SLIDE_N] = c;\n\t\t\tText[s] = c;\n\t \t\tAddMap((s - 1) & (SLIDE_N - 1));\n\t\t\tAddMap(s);\n\t\t\ts++;\n\t\t\tinlen--;\n\t\t\ts &= (SLIDE_N - 1);\n\t\t\tcode[codeptr++] = c;\n\t\t}\n\t\tmask <<= 1;\n\n\t\tif(mask == 0)\n\t\t{\n\t\t\tfor(int i = 0; i < codeptr; i++)\n\t\t\t\tout[outlen++] = code[i];\n\t\t\tmask = codeptr = 1;\n\t\t\tcode[0] = 0;\n\t\t}\n\t}\n\n\tif(mask != 1)\n\t{\n\t\tfor(int i = 0; i < codeptr; i++)\n\t\t\tout[outlen++] = code[i];\n\t}\n\n\tS = s;\n}\n//---------------------------------------------------------------------------\nvoid SlideCompressor::Store()\n{\n\tS2 = S;\n\tint i;\n\tfor(i = 0; i < SLIDE_N + SLIDE_M - 1; i++)\n\t\tText2[i] = Text[i];\n\n\tfor(i = 0; i < 256*256; i++)\n\t\tMap2[i] = Map[i];\n\n\tfor(i = 0; i < SLIDE_N; i++)\n\t\tChains2[i] = Chains[i];\n}\n//---------------------------------------------------------------------------\nvoid SlideCompressor::Restore()\n{\n\tS = S2;\n\tint i;\n\tfor(i = 0; i < SLIDE_N + SLIDE_M - 1; i++)\n\t\tText[i] = Text2[i];\n\n\tfor(i = 0; i < 256*256; i++)\n\t\tMap[i] = Map2[i];\n\n\tfor(i = 0; i < SLIDE_N; i++)\n\t\tChains[i] = Chains2[i];\n}\n//---------------------------------------------------------------------------\n\n#define BLOCK_HEIGHT 4\n//---------------------------------------------------------------------------\nstatic void WriteInt32(long num, tTJSBinaryStream *out)\n{\n\tchar buf[4];\n\tbuf[0] = num & 0xff;\n\tbuf[1] = (num >> 8) & 0xff;\n\tbuf[2] = (num >> 16) & 0xff;\n\tbuf[3] = (num >> 24) & 0xff;\n\tout->WriteBuffer(buf, 4);\n}\n//---------------------------------------------------------------------------\nstatic void Compress( const iTVPBaseBitmap *bmp, tTJSBinaryStream * out, bool is24 = false )\n{\n\t// compress 'bmp' to 'out'.\n\t// bmp will be modified (destroyed).\n\tint colors;\n\n\tif( bmp->Is32BPP() ) {\n\t\tif( is24 ) colors = 3;\n\t\telse colors = 4;\n\t} else {\n\t\tcolors = 1;\n\t}\n\n\t// header\n\t{\n\t\tout->WriteBuffer(\"TLG5.0\\x00raw\\x1a\\x00\", 11);\n\t\tout->WriteBuffer(&colors, 1);\n\t\tint width = bmp->GetWidth();\n\t\tint height = bmp->GetHeight();\n\t\tWriteInt32(width, out);\n\t\tWriteInt32(height, out);\n\t\tint blockheight = BLOCK_HEIGHT;\n\t\tWriteInt32(blockheight, out);\n\t}\n\n\tint blockcount = (int)((bmp->GetHeight() - 1) / BLOCK_HEIGHT) + 1;\n\n\n\t// buffers/compressors\n\tSlideCompressor * compressor = NULL;\n\tunsigned char *cmpinbuf[4];\n\tunsigned char *cmpoutbuf[4];\n\tfor(int i = 0; i < colors; i++)\n\t\tcmpinbuf[i] = cmpoutbuf[i] = NULL;\n\tlong written[4];\n\tint *blocksizes;\n\n\t// allocate buffers/compressors\n\ttry\n\t{\n\t\tcompressor = new SlideCompressor();\n\t\tfor(int i = 0; i < colors; i++)\n\t\t{\n\t\t\tcmpinbuf[i] = new unsigned char [bmp->GetWidth() * BLOCK_HEIGHT];\n\t\t\tcmpoutbuf[i] = new unsigned char [bmp->GetWidth() * BLOCK_HEIGHT * 9 / 4];\n\t\t\twritten[i] = 0;\n\t\t}\n\t\tblocksizes = new int[blockcount];\n\n\t\ttjs_uint64 blocksizepos = out->GetPosition();\n\t\t// write block size header\n\t\t// (later fill this)\n\t\tfor(int i = 0; i < blockcount; i++)\n\t\t{\n\t\t\tout->WriteBuffer(\"    \", 4);\n\t\t}\n\n\t\t//\n\t\tint block = 0;\n\t\tfor(int blk_y = 0; blk_y < (int)bmp->GetHeight(); blk_y += BLOCK_HEIGHT, block++)\n\t\t{\n\t\t\tint ylim = blk_y + BLOCK_HEIGHT;\n\t\t\tif(ylim > (int)bmp->GetHeight()) ylim = bmp->GetHeight();\n\n\t\t\tint inp = 0;\n\n\n\t\t\tfor(int y = blk_y; y < ylim; y++)\n\t\t\t{\n\t\t\t\t// retrieve scan lines\n\t\t\t\tconst unsigned char * upper;\n\t\t\t\tif(y != 0)\n\t\t\t\t\tupper = (const unsigned char *)bmp->GetScanLine(y-1);\n\t\t\t\telse\n\t\t\t\t\tupper = NULL;\n\t\t\t\tconst unsigned char * current;\n\t\t\t\tcurrent = (const unsigned char *)bmp->GetScanLine(y);\n\n\t\t\t\t// prepare buffer\n\t\t\t\tint prevcl[4];\n\t\t\t\tint val[4];\n\n\t\t\t\tfor(int c = 0; c < colors; c++) prevcl[c] = 0;\n\n\t\t\t\tfor(int x = 0; x < (int)bmp->GetWidth(); x++)\n\t\t\t\t{\n\t\t\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t\t\t{\n\t\t\t\t\t\tint cl;\n\t\t\t\t\t\tif(upper)\n\t\t\t\t\t\t\tcl = 0[current++] - 0[upper++];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcl = 0[current++];\n\t\t\t\t\t\tval[c] = cl - prevcl[c];\n\t\t\t\t\t\tprevcl[c] = cl;\n\t\t\t\t\t}\n\t\t\t\t\t// composite colors\n\t\t\t\t\tswitch(colors)\n\t\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcmpinbuf[0][inp] = val[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tcmpinbuf[0][inp] = val[0] - val[1];\n\t\t\t\t\t\tcmpinbuf[1][inp] = val[1];\n\t\t\t\t\t\tcmpinbuf[2][inp] = val[2] - val[1];\n\t\t\t\t\t\t// skip alpha\n\t\t\t\t\t\tcurrent++;\n\t\t\t\t\t\tif( upper ) upper++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tcmpinbuf[0][inp] = val[0] - val[1];\n\t\t\t\t\t\tcmpinbuf[1][inp] = val[1];\n\t\t\t\t\t\tcmpinbuf[2][inp] = val[2] - val[1];\n\t\t\t\t\t\tcmpinbuf[3][inp] = val[3];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tinp++;\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// compress buffer and write to the file\n\n\t\t\t// LZSS\n\t\t\tint blocksize = 0;\n\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t{\n\t\t\t\tlong wrote = 0;\n\t\t\t\tcompressor->Store();\n\t\t\t\tcompressor->Encode(cmpinbuf[c], inp,\n\t\t\t\t\tcmpoutbuf[c], wrote);\n\t\t\t\tif(wrote < inp)\n\t\t\t\t{\n\t\t\t\t\tout->WriteBuffer(\"\\x00\", 1);\n\t\t\t\t\tWriteInt32(wrote, out);\n\t\t\t\t\tout->WriteBuffer(cmpoutbuf[c], wrote);\n\t\t\t\t\tblocksize += wrote + 4 + 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcompressor->Restore();\n\t\t\t\t\tout->WriteBuffer(\"\\x01\", 1);\n\t\t\t\t\tWriteInt32(inp, out);\n\t\t\t\t\tout->WriteBuffer(cmpinbuf[c], inp);\n\t\t\t\t\tblocksize += inp + 4 + 1;\n\t\t\t\t}\n\t\t\t\twritten[c] += wrote;\n\t\t\t}\n\n\t\t\tblocksizes[block] = blocksize;\n\t\t}\n\n\n\t\t// write block sizes\n\t\ttjs_uint64 pos_save = out->GetPosition();\n\t\tout->SetPosition( blocksizepos );\n\t\tfor(int i = 0; i < blockcount; i++)\n\t\t{\n\t\t\tWriteInt32(blocksizes[i], out);\n\t\t}\n\t\tout->SetPosition( pos_save );\n\n\n\n\t\t// deallocate buffers/compressors\n\t}\n\tcatch(...)\n\t{\n\t\tfor(int i = 0; i < colors; i++)\n\t\t{\n\t\t\tif(cmpinbuf[i]) delete [] cmpinbuf[i];\n\t\t\tif(cmpoutbuf[i]) delete [] cmpoutbuf[i];\n\t\t}\n\t\tif(compressor) delete compressor;\n\t\tif(blocksizes) delete [] blocksizes;\n\t\tthrow;\n\t}\n\tfor(int i = 0; i < colors; i++)\n\t{\n\t\tif(cmpinbuf[i]) delete [] cmpinbuf[i];\n\t\tif(cmpoutbuf[i]) delete [] cmpoutbuf[i];\n\t}\n\tif(compressor) delete compressor;\n\tif(blocksizes) delete [] blocksizes;\n}\n//---------------------------------------------------------------------------\nvoid SaveTLG5( tTJSBinaryStream* stream, const iTVPBaseBitmap* image, bool is24 )\n{\n\tCompress(image, stream, is24);\n}\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/visual/SaveTLG6.cpp",
    "content": "#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderIntf.h\"\n#include \"MsgIntf.h\"\n#include \"tjsUtils.h\"\n#include \"tvpgl.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"StorageIntf.h\"\n#include \"SaveTLG.h\"\n#include \"UtilStreams.h\"\n\n#include <stdlib.h>\n#include <memory.h>\n#include <sstream>\n\n#include \"tjsDictionary.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"TickCount.h\"\n\nstatic const tjs_char * const LAYER_BLEND_MODES[] = {\n\tTJS_W(\"opaque\"), TJS_W(\"alpha\"), TJS_W(\"add\"), TJS_W(\"sub\"), TJS_W(\"mul\"),\n\tTJS_W(\"dodge\"), TJS_W(\"darken\"), TJS_W(\"lighten\"), TJS_W(\"screen\"), TJS_W(\"addalpha\"),\n\tTJS_W(\"psnormal\"), TJS_W(\"psadd\"), TJS_W(\"pssub\"), TJS_W(\"psmul\"), TJS_W(\"psscreen\"), TJS_W(\"psoverlay\"),\n\tTJS_W(\"pshlight\"), TJS_W(\"psslight\"), TJS_W(\"psdodge\"), TJS_W(\"psdodge5\"), TJS_W(\"psburn\"), TJS_W(\"pslighten\"),\n\tTJS_W(\"psdarken\"), TJS_W(\"psdiff\"), TJS_W(\"psdiff5\"), TJS_W(\"psexcl\"), TJS_W(\"opaque\"), NULL\n};\nbool TVPAcceptSaveAsTLG(void* formatdata, const ttstr & type, class iTJSDispatch2** dic )\n{\n\tbool result = false;\n\tif( type.StartsWith(TJS_W(\"tlg\")) ) result = true;\n\telse if( type == TJS_W(\".tlg\") ) result = true;\n\telse if( type == TJS_W(\".tlg5\") ) result = true;\n\telse if( type == TJS_W(\".tlg6\") ) result = true;\n\tif( result && dic ) {\n\t\t// mode : select text : opaque, alpha, add, sub, mul, dodge, darken, lighten, screen, addalpha\n\t\t//        psnormal, psadd, pssub, psmul, psscreen, psoverlay, pshlight, psslight, psdodge\n\t\t//        psdodge5, psburn, pslighten, psdarken, psdiff, psdiff5, psexcl, opaque\n\t\t// offs_x : integer\n\t\t// offs_y : integer\n\t\t// offs_unit : select text : pixel\n\t\ttTJSVariant result;\n\t\tTVPExecuteExpression(\n\t\t\tTJS_W(\"(const)%[\")\n\t\t\tTJS_W(\"\\\"mode\\\"=>(const)%[\\\"type\\\"=>\\\"select text\\\",\\\"items\\\"=>\")\n\t\t\t\tTJS_W(\"(const)[\\\"opaque\\\", \\\"alpha\\\", \\\"add\\\", \\\"sub\\\", \\\"mul\\\", \\\"dodge\\\", \\\"darken\\\", \\\"lighten\\\", \\\"screen\\\", \\\"addalpha\\\",\")\n\t\t\t\tTJS_W(\"\\\"psnormal\\\", \\\"psadd\\\", \\\"pssub\\\", \\\"psmul\\\", \\\"psscreen\\\", \\\"psoverlay\\\", \\\"pshlight\\\", \\\"psslight\\\", \\\"psdodge\\\",\")\n\t\t\t\tTJS_W(\"\\\"psdodge5\\\", \\\"psburn\\\", \\\"pslighten\\\", \\\"psdarken\\\", \\\"psdiff\\\", \\\"psdiff5\\\", \\\"psexcl\\\", \\\"opaque\\\"],\")\n\t\t\tTJS_W(\"\\\"desc\\\"=>\\\"blending mode\\\",\\\"default\\\"=>\\\"alpha\\\"],\")\n\n\t\t\tTJS_W(\"\\\"offs_x\\\"=>(const)%[\\\"type\\\"=>\\\"integer\\\",\\\"desc\\\"=>\\\"offset x\\\",\\\"default\\\"=>0],\")\n\t\t\tTJS_W(\"\\\"offs_y\\\"=>(const)%[\\\"type\\\"=>\\\"integer\\\",\\\"desc\\\"=>\\\"offset y\\\",\\\"default\\\"=>0],\")\n\t\t\tTJS_W(\"\\\"offs_unit\\\"=>(const)%[\\\"type\\\"=>\\\"select text\\\",\\\"items\\\"=>(const)[\\\"pixel\\\"],\\\"desc\\\"=>\\\"offset unit\\\",\\\"default\\\"=>\\\"pixel\\\"]\")\n\t\t\tTJS_W(\"]\"),\n\t\t\tNULL, &result );\n\t\tif( result.Type() == tvtObject ) {\n\t\t\t*dic = result.AsObject();\n\t\t}\n\t}\n\treturn result;\n}\n\n// Table for 'k' (predicted bit length) of golomb encoding\n#define TVP_TLG6_GOLOMB_N_COUNT 4\n\n// golomb bit length table is compressed, so we need to\n// decompress it.\nextern \"C\" char TVPTLG6GolombBitLengthTable[TVP_TLG6_GOLOMB_N_COUNT*2*128][TVP_TLG6_GOLOMB_N_COUNT];\nextern \"C\" short int TVPTLG6GolombCompressed[TVP_TLG6_GOLOMB_N_COUNT][9];\n\n// TLG6.0 bitstream output implementation\n\n\nclass TLG6BitStream\n{\n\tint BufferBitPos; // bit position of output buffer\n\tlong BufferBytePos; // byte position of output buffer\n\ttTJSBinaryStream * OutStream; // output stream\n\tunsigned char *Buffer; // output buffer\n\tlong BufferCapacity; // output buffer capacity\n\npublic:\n\tTLG6BitStream(tTJSBinaryStream * outstream) :\n\t\tOutStream(outstream),\n\t\tBufferBitPos(0),\n\t\tBufferBytePos(0),\n\t\tBuffer(NULL),\n\t\tBufferCapacity(0)\n\t{\n\t}\n\n\t~TLG6BitStream()\n\t{\n\t\tFlush();\n\t}\n\npublic:\n\tint GetBitPos() const { return BufferBitPos; }\n\tlong GetBytePos() const { return BufferBytePos; }\n\n\tvoid Flush()\n\t{\n\t\tif(Buffer && (BufferBitPos || BufferBytePos))\n\t\t{\n\t\t\tif(BufferBitPos) BufferBytePos ++;\n\t\t\tOutStream->Write(Buffer, BufferBytePos);\n\t\t\tBufferBytePos = 0;\n\t\t\tBufferBitPos = 0;\n\t\t}\n\t\tTJS_free(Buffer);\n\t\tBufferCapacity = 0;\n\t\tBuffer = NULL;\n\t}\n\n\tlong GetBitLength() const { return BufferBytePos * 8 + BufferBitPos; }\n\n\tvoid Put1Bit(bool b)\n\t{\n\t\tif(BufferBytePos == BufferCapacity)\n\t\t{\n\t\t\t// need more bytes\n\t\t\tlong org_cap = BufferCapacity;\n\t\t\tBufferCapacity += 0x1000;\n\t\t\tif(Buffer)\n\t\t\t\tBuffer = (unsigned char *)TJS_realloc(Buffer, BufferCapacity);\n\t\t\telse\n\t\t\t\tBuffer = (unsigned char *)TJS_malloc(BufferCapacity);\n\t\t\tif(!Buffer) TVPThrowExceptionMessage( TVPTlgInsufficientMemory );\n\t\t\tmemset(Buffer + org_cap, 0, BufferCapacity - org_cap);\n\t\t}\n\n\t\tif(b) Buffer[BufferBytePos] |= 1 << BufferBitPos;\n\t\tBufferBitPos ++;\n\t\tif(BufferBitPos == 8)\n\t\t{\n\t\t\tBufferBitPos = 0;\n\t\t\tBufferBytePos ++;\n\t\t}\n\t}\n\n\tvoid PutGamma(int v)\n\t{\n\t\t// Put a gamma code.\n\t\t// v must be larger than 0.\n\t\tint t = v;\n\t\tt >>= 1;\n\t\tint cnt = 0;\n\t\twhile(t)\n\t\t{\n\t\t\tPut1Bit(0);\n\t\t\tt >>= 1;\n\t\t\tcnt ++;\n\t\t}\n\t\tPut1Bit(1);\n\t\twhile(cnt--)\n\t\t{\n\t\t\tPut1Bit(v&1);\n\t\t\tv >>= 1;\n\t\t}\n\t}\n\n\tvoid PutInterleavedGamma(int v)\n\t{\n\t\t// Put a gamma code, interleaved.\n\t\t// interleaved gamma codes are:\n\t\t//     1 :                   1\n\t\t//   <=3 :                 1x0\n\t\t//   <=7 :               1x0x0\n\t\t//  <=15 :             1x0x0x0\n\t\t//  <=31 :           1x0x0x0x0\n\t\t// and so on.\n\t\t// v must be larger than 0.\n\t\t\n\t\tv --;\n\t\twhile(v)\n\t\t{\n\t\t\tv >>= 1;\n\t\t\tPut1Bit(0);\n\t\t\tPut1Bit(v&1);\n\t\t}\n\t\tPut1Bit(1);\n\t}\n\n\tstatic int GetGammaBitLengthGeneric(int v)\n\t{\n\t\tint needbits = 1;\n\t\tv >>= 1;\n\t\twhile(v)\n\t\t{\n\t\t\tneedbits += 2;\n\t\t\tv >>= 1;\n\t\t}\n\t\treturn needbits;\n\t}\n\n\tstatic int GetGammaBitLength(int v)\n\t{\n\t\t// Get bit length where v is to be encoded as a gamma code.\n\t\tif(v<=1) return 1;    //                   1\n\t\tif(v<=3) return 3;    //                 x10\n\t\tif(v<=7) return 5;    //               xx100\n\t\tif(v<=15) return 7;   //             xxx1000\n\t\tif(v<=31) return 9;   //          x xxx10000\n\t\tif(v<=63) return 11;  //        xxx xx100000\n\t\tif(v<=127) return 13; //      xxxxx x1000000\n\t\tif(v<=255) return 15; //    xxxxxxx 10000000\n\t\tif(v<=511) return 17; //   xxxxxxx1 00000000\n\t\treturn GetGammaBitLengthGeneric(v);\n\t}\n\n\tvoid PutNonzeroSigned(int v, int len)\n\t{\n\t\t// Put signed value into the bit pool, as length of \"len\".\n\t\t// v must not be zero. abs(v) must be less than 257.\n\t\tif(v > 0) v--;\n\t\twhile(len --)\n\t\t{\n\t\t\tPut1Bit(v&1);\n\t\t\tv >>= 1;\n\t\t}\n\t}\n\n\tstatic int GetNonzeroSignedBitLength(int v)\n\t{\n\t\t// Get bit (minimum) length where v is to be encoded as a non-zero signed value.\n\t\t// v must not be zero. abs(v) must be less than 257.\n\t\tif(v == 0) return 0;\n\t\tif(v < 0) v = -v;\n\t\tif(v <= 1) return 1;\n\t\tif(v <= 2) return 2;\n\t\tif(v <= 4) return 3;\n\t\tif(v <= 8) return 4;\n\t\tif(v <= 16) return 5;\n\t\tif(v <= 32) return 6;\n\t\tif(v <= 64) return 7;\n\t\tif(v <= 128) return 8;\n\t\tif(v <= 256) return 9;\n\t\treturn 10;\n\t}\n\n\tvoid PutValue(long v, int len)\n\t{\n\t\t// put value \"v\" as length of \"len\"\n\t\twhile(len --)\n\t\t{\n\t\t\tPut1Bit(v&1);\n\t\t\tv >>= 1;\n\t\t}\n\t}\n\n};\n#define MAX_COLOR_COMPONENTS 4\n\n#define FILTER_TRY_COUNT 16\n\n#define W_BLOCK_SIZE 8\n#define H_BLOCK_SIZE 8\n\n//------------------------------ FOR DEBUG\n//#define FILTER_TEST\n//#define WRITE_ENTROPY_VALUES\n//#define WRITE_VSTXT\n//------------------------------\n\n\n/*\n\tshift-jis\n\n\tTLG6 kASY(Tv)\n\n\tTLG6 ͋ggQŗp摜ktH[}bgłBO[XP[A\n\t24bitrbg}bvA8bitAt@`lt24bitrbg}bvɑΉ\n\tĂ܂BfUC̃RZvǵukł邱Ɓvu摜WJɂ\n\t\\ɍȎł邱ƁvłB\n\n\tTLG6 ͈ȉ̏ŉ摜k܂B\n\n\t1.   MED ܂ ϖ@ ɂPx\\\n\t2.   I[_Oɂʍ팸\n\t3.   FփtB^ɂʍ팸\n\t4.   SECXɂGgs[\n\n\n\n\t1.   MED ܂ ϖ@ ɂPx\\\n\n\t\tTLG6  MED (Median Edge Detector) 邢͕ϖ@ɂPx\\s\n\t\tA\\lƎۂ̒ľ덷L^܂B\n\n\t\tMED ́A\\ΏۂƂsNZʒu(}xʒu)ɑ΂ÃׂsNZ\n\t\t̋PxaÃׂsNZ̋PxbÃsNZ̋PxcƂA\\\n\t\tΏۂ̃sNZ̋Px x ȉ̂悤ɗ\\܂B\n\n\t\t\t+-----+-----+\n\t\t\t|  c  |  b  |\n\t\t\t+-----+-----+\n\t\t\t|  a  |  x  |\n\t\t\t+-----+-----+\n\n\t\t\tx = min(a,b)    (c > max(a,b) ̏ꍇ)\n\t\t\tx = max(a,b)    (c < min(a,b) ̏ꍇ)\n\t\t\tx = a + b - c   (̑̏ꍇ)\n\n\t\tMED́APȁA͂̃sNZ̋Px̕ςɂ\\ȂǂƔׁA摜\n\t\t̏c̃GbWł͏̃sNZÃGbWł͍̃sNZ\n\t\tQƂė\\s悤ɂȂ邽߁Â悢\\\\łB\n\n\t\tϖ@ł́Aa  b ̋Px̕ς\\Ώۂ̃sNZ̋Px x \\\n\t\t܂Bȉ̎p܂B\n\n\t\t\tx = (a + b + 1) >> 1\n\n\t\tMED  ϖ@́A8x8 ɋ؂ꂽ摜ubNŗɂ鈳k\n\t\trAk̍̕@I܂B\n\n\t\tR G B 摜 A R G B 摜ɑ΂Ă͂FR|[lgƂɍs\n\t\t܂B\n\n\t2.   I[_Oɂʍ팸\n\n\t\t덷݂̂ƂȂf[^́AI[_O(ёւ)s܂B\n\t\tTLG6ł́A܂摜8~8̏ȃubNɕ܂BubN͉\n\t\tɁÃubN珇ɉẼubNɌA񕪂̃ubN\n\t\t̏΁Ä񉺂̃ubNAƂŏs\n\t\tB\n\t\ťX̃ubNł́AsNZȉ̏Ԃɕёւ܂B\n\n\t\tʒũubN      ʒu̃ubN\n\t\t 1  2  3  4  5  6  7  8     57 58 59 60 61 62 63 64\n\t\t16 15 14 13 12 11 10  9     56 55 54 53 52 51 50 49\n\t\t17 18 19 20 21 22 23 24     41 42 43 44 45 46 47 48\n\t\t32 31 30 29 28 27 26 25     40 39 38 37 36 35 34 33\n\t\t33 34 35 36 37 38 39 40     25 26 27 28 29 30 31 32\n\t\t48 47 46 45 44 43 42 41     24 23 22 21 20 19 18 17\n\t\t49 50 51 52 53 54 55 56      9 10 11 12 13 14 15 16\n\t\t64 63 62 61 60 59 58 57      8  7  6  5  4  3  2  1\n\n\t\t̂悤ȁuWOUOv̕ёւsƂɂA(PxFA\n\t\tGbWȂ)̎sNZA\\ȂAĩGg\n\t\ts[ił̃[EEOXǩʂ߂邱Ƃł܂B\n\n\t3.   FփtB^ɂʍ팸\n\n\t\tR G B 摜 ( A R G B 摜 ) ɂẮAFR|[lg\n\t\t̑֐𗘗pďʂ点\\܂BTLG6ł́Aȉ\n\t\t16ނ̃tB^ubNƂɓKpAĩSECXɂ\n\t\t鈳kTCYZAƂTCY̏ȂtB^Kp\n\t\tBtB^ԍ MED/ϖ@̕ʂ LZSS @ɂ舳kAo͂\n\t\t܂B\n\n\t\t0          B        G        R              (tB^)\n\t\t1          B-G      G        R-G\n\t\t2          B        G-B      R-B-G\n\t\t3          B-R-G    G-R      R\n\t\t4          B-R      G-B-R    R-B-R-G\n\t\t5          B-R      G-B-R    R\n\t\t6          B-G      G        R\n\t\t7          B        G-B      R\n\t\t8          B        G        R-G\n\t\t9          B-G-R-B  G-R-B    R-B\n\t\t10         B-R      G-R      R\n\t\t11         B        G-B      R-B\n\t\t12         B        G-R-B    R-B\n\t\t13         B-G      G-R-B-G  R-B-G\n\t\t14         B-G-R    G-R      R-B-G-R\n\t\t15         B        G-(B<<1) R-(B<<1)\n\n\t\t̃tB^́Ả摜ŃeXgAtB^̎gppx\n\t\tׁAƂKp̑16̃tB^Io܂B\n\n\t4.   SECXɂGgs[\n\n\t\tŏIIȒl̓SECXɂrbgzɊi[܂B\n\t\tŏIIȒlɂ͘A[ɑ߁A[Ɣ[̘A\n\t\tK}pĕ܂([EEOX)B̂߁Arb\n\t\tgz񒆂ɂ͊{I\n\n\t\t1 [̘A(EOX)̃K}\n\t\t2 [̒l̃SECX (A JԂ)\n\t\t3 [̘A(EOX)̃K}\n\n\t\t񌻂邱ƂɂȂ܂B\n\n\t\tK}͈ȉ̌`ŁA0ۑKvȂ(0͂蓾\n\t\t̂)A\\łŒ̒l1ƂȂĂ܂B\n\n\t\t                  MSB      LSB\n\t\t(v=1)                            1\n\t\t(2<=v<=3)                      x10          x = v-2\n\t\t(4<=v<=7)                    xx100         xx = v-4\n\t\t(8<=v<=15)                 xxx1000        xxx = v-8\n\t\t(16<=v<=31)             x xxx10000       xxxx = v-16\n\t\t(32<=v<=63)           xxx xx100000      xxxxx = v-32\n\t\t(64<=v<=127)        xxxxx x1000000     xxxxxx = v-64\n\t\t(128<=v<=255)     xxxxxxx 10000000    xxxxxxx = v-128\n\t\t(256<=v<=511)    xxxxxxx1 00000000   xxxxxxxx = v-256\n\t\t      :                    :                  :\n\t\t      :                    :                  :\n\n\t\tSECX͈ȉ̕@ŕ܂B܂A悤Ƃ\n\t\tleƂ܂Beɂ1ȏ̐̐-1ȉ݂̐̕܂B\n\t\t0ȏ̐ɕϊ܂B̓Iɂ͈ȉ̎ŕϊs܂B\n\t\t(ϊ̒lmƂ)\n\n\t\tm = ((e >= 0) ? 2*e : -2*e-1) - 1\n\n\t\t̕ϊɂA̕\\̂悤ɁAemɁAemɕ\n\t\t܂B\n\n\t\t e     m\n\t\t-1     0\n\t\t 1     1\n\t\t-2     2\n\t\t 2     3\n\t\t-3     4\n\t\t 3     5\n\t\t :     :\n\t\t :     :\n\n\t\t̒l m ǂꂮ炢̃rbgŕ\\ł邩\\܂B̃rb\n\t\tg k Ƃ܂Bk  0 ȏ̐łB\\͂Am  k\n\t\trbgŕ\\łȂꍇ܂B̏ꍇ́Ak rbgŕ\\ł\n\t\tȂ mA܂ k>>m ̃[o͂AŌɂ̏I[L\n\t\t 1 o͂܂B\n\t\tm  krbgŕ\\łꍇ́AP 1 o͂܂B̂ƁA\n\t\tm ʃrbg k rbgo͂܂B\n\n\t\tƂ e  66  k  5 ̏ꍇ͈ȉ̂悤ɂȂ܂B\n\n\t\tm  m = ((e >= 0) ? 2*e : -2*e-1) - 1 ̎ɂ 131 ƂȂ܂B\n\t\t\\rbg 5 ŕ\\łl̍ől 31 ł̂ŁA131 ł\n\t\tm  k rbgŕ\\łȂƂƂɂȂ܂Bł̂ŁAm >> k\n\t\tł 4  0 o͂܂B\n\n\t\t0000\n\n\t\tɁA4 0 ̏I[LƂ 1 o͂܂B\n\n\t\t10000\n\n\t\tŌ m ʃrbg k rbgo͂܂B131 Qiŕ\\\n\t\t 10000011 ƂȂ܂Ảʂ 5 rbgo͂܂B\n\n\n        MSB  LSB\n\t\t00011 1 0000      (v10rbg)\n\t\t~~~~~ ~ ~~~~\n\t\t  c   b   a\n\n\t\ta   (m >> k)  0\n\t\tb   a  I[L\n\t\tc   m ̉ k rbg\n\n\t\tꂪ e=66 k=5 𕄍rbgƂȂ܂B\n\n\t\tIɂ k ̗\\́A܂łɏo͂ e ̐Βl̍vƂ܂ł\n\t\to͂ɁA炩ߎۂ̉摜̓v쐬ꂽe[u\n\t\tQƂ邱ƂŎZo܂B C++ ꕗɋLqƈȉ̂悤\n\t\tɂȂ܂B\n\n\t\tn = 3; // JE^\n\t\ta = 0; // e ̐Βl̍v\n\n\t\twhile(e ǂݍ)\n\t\t{\n\t\t\tk = table[a][n]; // e[u k Q\n\t\t\tm = ((e >= 0) ? 2*e : -2*e-1) - 1;\n\t\t\te  m  k ŕ;\n\t\t\ta += m >> 1; // e ̐Βl̍v ( m >>1 őp)\n\t\t\tif(--n < 0) a >>= 1, n = 3;\n\t\t}\n\n\t\t4 񂲂Ƃ a  n Zbg邽߁AO̒l̉e͕\n\t\tiނɂĔȂA߂̒lI k \\邱Ƃł\n\t\t܂B\n\n\n\tQl :\n\t\tGolomb codes\n\t\thttp://oku.edu.mie-u.ac.jp/~okumura/compression/golomb/\n\t\tOdw FɂS̊ȒPȉ\n*/\n\n//---------------------------------------------------------------------------\n#ifdef WRITE_VSTXT\nFILE *vstxt = fopen(\"vs.txt\", \"wt\");\n#endif\n#define GOLOMB_GIVE_UP_BYTES 4\nvoid CompressValuesGolomb(TLG6BitStream &bs, char *buf, int size)\n{\n\t// golomb encoding, -- http://oku.edu.mie-u.ac.jp/~okumura/compression/golomb/\n\n\t// run-length golomb method\n\tbs.PutValue(buf[0]?1:0, 1); // initial value state\n\n\tint count;\n\n\tint n = TVP_TLG6_GOLOMB_N_COUNT - 1; // ̃JE^\n\tint a = 0; // \\덷̐Βl̘a\n\n\tcount = 0;\n\tfor(int i = 0; i < size; i++)\n\t{\n\t\tif(buf[i])\n\t\t{\n\t\t\t// write zero count\n\t\t\tif(count) bs.PutGamma(count);\n\n\t\t\t// count non-zero values\n\t\t\tcount = 0;\n\t\t\tint ii;\n\t\t\tfor(ii = i; ii < size; ii++)\n\t\t\t{\n\t\t\t\tif(buf[ii]) count++; else break;\n\t\t\t}\n\n\t\t\t// write non-zero count\n\t\t\tbs.PutGamma(count);\n\n\t\t\t// write non-zero values\n\t\t\tfor(; i < ii; i++)\n\t\t\t{\n\t\t\t\tint e = buf[i];\n#ifdef WRITE_VSTXT\n\t\t\t\tfprintf(vstxt, \"%d \", e);\n#endif\n\t\t\t\tint k = TVPTLG6GolombBitLengthTable[a][n];\n\t\t\t\tint m = ((e >= 0) ? 2*e : -2*e-1) - 1;\n\t\t\t\tint store_limit = bs.GetBytePos() + GOLOMB_GIVE_UP_BYTES;\n\t\t\t\tbool put1 = true;\n\t\t\t\tfor(int c = (m >> k); c > 0; c--)\n\t\t\t\t{\n\t\t\t\t\tif(store_limit == bs.GetBytePos())\n\t\t\t\t\t{\n\t\t\t\t\t\tbs.PutValue(m >> k, 8);\n#ifdef WRITE_VSTXT\n\t\t\t\t\t\tfprintf(vstxt, \"[ %d ] \", m>>k);\n#endif\n\t\t\t\t\t\tput1 = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbs.Put1Bit(0);\n\t\t\t\t}\n\t\t\t\tif(store_limit == bs.GetBytePos())\n\t\t\t\t{\n\t\t\t\t\tbs.PutValue(m >> k, 8);\n#ifdef WRITE_VSTXT\n\t\t\t\t\tfprintf(vstxt, \"[ %d ] \", m>>k);\n#endif\n\t\t\t\t\tput1 = false;\n\t\t\t\t}\n\t\t\t\tif(put1) bs.Put1Bit(1);\n\t\t\t\tbs.PutValue(m, k);\n\t\t\t\ta += (m>>1);\n\t\t\t\tif (--n < 0) {\n\t\t\t\t\ta >>= 1; n = TVP_TLG6_GOLOMB_N_COUNT - 1;\n\t\t\t\t}\n\t\t\t}\n\n#ifdef WRITE_VSTXT\n\t\t\tfprintf(vstxt, \"\\n\");\n#endif\n\n\t\t\ti = ii - 1;\n\t\t\tcount = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// zero\n\t\t\tcount ++;\n\t\t}\n\t}\n\n\tif(count) bs.PutGamma(count);\n}\n//---------------------------------------------------------------------------\nclass TryCompressGolomb\n{\n\tint TotalBits; // total bit count\n\tint Count; // running count\n\tint N;\n\tint A;\n\tbool LastNonZero;\n\npublic:\n\tTryCompressGolomb()\n\t{\n\t\tReset();\n\t}\n\n\tTryCompressGolomb(const TryCompressGolomb &ref)\n\t{\n\t\tCopy(ref);\n\t}\n\n\t~TryCompressGolomb() { ; }\n\n\tvoid Copy(const TryCompressGolomb &ref)\n\t{\n\t\tTotalBits = ref.TotalBits;\n\t\tCount = ref.Count;\n\t\tN = ref.N;\n\t\tA = ref.A;\n\t\tLastNonZero = ref.LastNonZero;\n\t}\n\n\tvoid Reset()\n\t{\n\t\tTotalBits = 1;\n\t\tCount = 0;\n\t\tN = TVP_TLG6_GOLOMB_N_COUNT - 1;\n\t\tA = 0;\n\t\tLastNonZero = false;\n\t}\n\n\tint Try(char *buf, int size)\n\t{\n\t\tfor(int i = 0; i < size; i++)\n\t\t{\n\t\t\tif(buf[i])\n\t\t\t{\n\t\t\t\t// write zero count\n\t\t\t\tif(!LastNonZero)\n\t\t\t\t{\n\t\t\t\t\tif(Count)\n\t\t\t\t\t\tTotalBits +=\n\t\t\t\t\t\t\tTLG6BitStream::GetGammaBitLength(Count);\n\n\t\t\t\t\t// count non-zero values\n\t\t\t\t\tCount = 0;\n\t\t\t\t}\n\n\t\t\t\t// write non-zero values\n\t\t\t\tfor(; i < size; i++)\n\t\t\t\t{\n\t\t\t\t\tint e = buf[i];\n\t\t\t\t\tif(!e) break;\n\t\t\t\t\tCount ++;\n\t\t\t\t\tint k = TVPTLG6GolombBitLengthTable[A][N];\n\t\t\t\t\tint m = ((e >= 0) ? 2*e : -2*e-1) - 1;\n\t\t\t\t\tint unexp_bits = (m>>k);\n\t\t\t\t\tif(unexp_bits >= (GOLOMB_GIVE_UP_BYTES*8-8/2))\n\t\t\t\t\t\tunexp_bits = (GOLOMB_GIVE_UP_BYTES*8-8/2)+8;\n\t\t\t\t\tTotalBits += unexp_bits + 1 + k;\n\t\t\t\t\tA += (m>>1);\n\t\t\t\t\tif (--N < 0) {\n\t\t\t\t\t\tA >>= 1; N = TVP_TLG6_GOLOMB_N_COUNT - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// write non-zero count\n\n\t\t\t\ti--;\n\t\t\t\tLastNonZero = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// zero\n\t\t\t\tif(LastNonZero)\n\t\t\t\t{\n\t\t\t\t\tif(Count)\n\t\t\t\t\t{\n\t\t\t\t\t\tTotalBits += TLG6BitStream::GetGammaBitLength(Count);\n\t\t\t\t\t\tCount = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tCount ++;\n\t\t\t\tLastNonZero = false;\n\t\t\t}\n\t\t}\n\t\treturn TotalBits;\n\t}\n\n\tint Flush()\n\t{\n\t\tif(Count)\n\t\t{\n\t\t\tTotalBits += TLG6BitStream::GetGammaBitLength(Count);\n\t\t\tCount = 0;\n\t\t}\n\t\treturn TotalBits;\n\t}\n};\n//---------------------------------------------------------------------------\n#define DO_FILTER \\\n\tlen -= 4; \\\n\tfor(d = 0; d < len; d+=4) \\\n\t{ FILTER_FUNC(0); FILTER_FUNC(1); FILTER_FUNC(2); FILTER_FUNC(3); } \\\n\tlen += 4; \\\n\tfor(; d < len; d++) \\\n\t{ FILTER_FUNC(0); }\n\nvoid ApplyColorFilter(char * bufb, char * bufg, char * bufr, int len, int code)\n{\n\tint d;\n\tunsigned char t;\n\tswitch(code)\n\t{\n\tcase 0:\n\t\tbreak;\n\tcase 1:\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufr[d+n] -= bufg[d+n], \\\n\t\t\tbufb[d+n] -= bufg[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 2:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufg[d],\n\t\t\tbufg[d] -= bufb[d];\n\t\tbreak;\n\tcase 3:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufg[d],\n\t\t\tbufg[d] -= bufr[d];\n\t\tbreak;\n\tcase 4:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufg[d],\n\t\t\tbufg[d] -= bufb[d],\n\t\t\tbufb[d] -= bufr[d];\n\t\tbreak;\n\tcase 5:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufb[d],\n\t\t\tbufb[d] -= bufr[d];\n\t\tbreak;\n\tcase 6:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufb[d+n] -= bufg[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 7:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufg[d+n] -= bufb[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 8:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufr[d+n] -= bufg[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 9:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufg[d],\n\t\t\tbufg[d] -= bufr[d],\n\t\t\tbufr[d] -= bufb[d];\n\t\tbreak;\n\tcase 10:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufg[d+n] -= bufr[d+n], \\\n\t\t\tbufb[d+n] -= bufr[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 11:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufr[d+n] -= bufb[d+n], \\\n\t\t\tbufg[d+n] -= bufb[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 12:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufr[d],\n\t\t\tbufr[d] -= bufb[d];\n\t\tbreak;\n\tcase 13:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufr[d],\n\t\t\tbufr[d] -= bufb[d],\n\t\t\tbufb[d] -= bufg[d];\n\t\tbreak;\n\tcase 14:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufb[d],\n\t\t\tbufb[d] -= bufg[d],\n\t\t\tbufg[d] -= bufr[d];\n\t\tbreak;\n\tcase 15:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tt = bufb[d+n]<<1; \\\n\t\t\tbufr[d+n] -= t, \\\n\t\t\tbufg[d+n] -= t;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 16:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufg[d+n] -= bufr[d+n];\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 17:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufb[d],\n\t\t\tbufb[d] -= bufg[d];\n\t\tbreak;\n\tcase 18:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufb[d];\n\t\tbreak;\n\tcase 19:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufr[d],\n\t\t\tbufr[d] -= bufg[d];\n\t\tbreak;\n\tcase 20:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufr[d];\n\t\tbreak;\n\tcase 21:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufg[d]>>1;\n\t\tbreak;\n\tcase 22:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufg[d+n] -= bufb[d+n]>>1;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 23:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufb[d],\n\t\t\tbufb[d] -= bufr[d],\n\t\t\tbufr[d] -= bufg[d];\n\t\tbreak;\n\tcase 24:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufr[d],\n\t\t\tbufr[d] -= bufg[d],\n\t\t\tbufg[d] -= bufb[d];\n\t\tbreak;\n\tcase 25:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufg[d+n] -= bufr[d+n]>>1;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 26:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tbufr[d+n] -= bufg[d+n]>>1;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 27:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tt = bufr[d+n]>>1; \\\n\t\t\tbufg[d+n] -= t, \\\n\t\t\tbufb[d+n] -= t;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 28:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufb[d]>>1;\n\t\tbreak;\n\tcase 29:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tt = bufg[d+n]>>1; \\\n\t\t\tbufr[d+n] -= t, \\\n\t\t\tbufb[d+n] -= t;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 30:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tt = bufb[d+n]>>1; \\\n\t\t\tbufr[d+n] -= t, \\\n\t\t\tbufg[d+n] -= t;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 31:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufr[d]>>1;\n\t\tbreak;\n\tcase 32:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufb[d]<<1;\n\t\tbreak;\n\tcase 33:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufg[d]<<1;\n\t\tbreak;\n\tcase 34:\n\t\t#undef FILTER_FUNC\n\t\t#define FILTER_FUNC(n) \\\n\t\t\tt = bufr[d+n]<<1; \\\n\t\t\tbufg[d+n] -= t, \\\n\t\t\tbufb[d+n] -= t;\n\t\tDO_FILTER\n\t\tbreak;\n\tcase 35:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufb[d]<<1;\n\t\tbreak;\n\tcase 36:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufg[d]<<1;\n\t\tbreak;\n\tcase 37:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufr[d] -= bufg[d]<<1,\n\t\t\tbufb[d] -= bufg[d]<<1;\n\t\tbreak;\n\tcase 38:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufg[d] -= bufr[d]<<1;\n\t\tbreak;\n\tcase 39:\n\t\tfor( d = 0; d < len; d++)\n\t\t\tbufb[d] -= bufr[d]<<1;\n\t\tbreak;\n\n\t}\n\n}\n//---------------------------------------------------------------------------\nint DetectColorFilter(char *b, char *g, char *r, int size, int &outsize)\n{\n#ifndef FILTER_TEST\n\tint minbits = -1;\n\tint mincode = -1;\n\n\tchar bbuf[H_BLOCK_SIZE*W_BLOCK_SIZE];\n\tchar gbuf[H_BLOCK_SIZE*W_BLOCK_SIZE];\n\tchar rbuf[H_BLOCK_SIZE*W_BLOCK_SIZE];\n\tTryCompressGolomb bc, gc, rc;\n\n\tfor(int code = 0; code < FILTER_TRY_COUNT; code++)   // 17..27 are currently not used\n\t{\n\t\t// copy bbuf, gbuf, rbuf into b, g, r.\n\t\tmemcpy(bbuf, b, sizeof(char)*size);\n\t\tmemcpy(gbuf, g, sizeof(char)*size);\n\t\tmemcpy(rbuf, r, sizeof(char)*size);\n\n\t\t// copy compressor\n\t\tbc.Reset();\n\t\tgc.Reset();\n\t\trc.Reset();\n\n\t\t// Apply color filter\n\t\tApplyColorFilter(bbuf, gbuf, rbuf, size, code);\n\n\t\t// try to compress\n\t\tint bits;\n\t\tbits  = (bc.Try(bbuf, size), bc.Flush());\n\t\tif(minbits != -1 && minbits < bits) continue;\n\t\tbits += (gc.Try(gbuf, size), gc.Flush());\n\t\tif(minbits != -1 && minbits < bits) continue;\n\t\tbits += (rc.Try(rbuf, size), rc.Flush());\n\n\t\tif(minbits == -1 || minbits > bits)\n\t\t{\n\t\t\tminbits = bits, mincode = code;\n\t\t}\n\t}\n\n\toutsize = minbits;\n\n\treturn mincode;\n#else\n\tstatic int filter = 0;\n\n\tint f = filter;\n\n\tfilter++;\n\tif(filter >= FILTER_TRY_COUNT) filter = 0;\n\n\toutsize = 0;\n\n\treturn f;\n#endif\n}\n//---------------------------------------------------------------------------\nstatic void WriteInt32(long num, tTJSBinaryStream *out)\n{\n\tchar buf[4];\n\tbuf[0] = num & 0xff;\n\tbuf[1] = (num >> 8) & 0xff;\n\tbuf[2] = (num >> 16) & 0xff;\n\tbuf[3] = (num >> 24) & 0xff;\n\tout->WriteBuffer(buf, 4);\n}\n//---------------------------------------------------------------------------\nstatic void TLG6InitializeColorFilterCompressor(SlideCompressor &c)\n{\n\tunsigned char code[4096];\n\tunsigned char dum[4096];\n\tunsigned char *p = code;\n\tfor(int i = 0; i < 32; i++)\n\t{\n\t\tfor(int j = 0; j < 16; j++)\n\t\t{\n\t\t\tp[0] = p[1] = p[2] = p[3] = i;\n\t\t\tp += 4;\n\t\t\tp[0] = p[1] = p[2] = p[3] = j;\n\t\t\tp += 4;\n\t\t}\n\t}\n\n\tlong dumlen;\n\tc.Encode(code, 4096, dum, dumlen);\n}\n//---------------------------------------------------------------------------\n// int ftfreq[256] = {0};\nvoid SaveTLG6( tTJSBinaryStream* stream, const iTVPBaseBitmap* bmp, bool is24 )\n{\n\ttTJSBinaryStream *out = stream;\n\n\t// DWORD medstart, medend;\n\ttjs_uint reordertick;\n#ifdef WRITE_ENTROPY_VALUES\n\tFILE *vs = fopen(\"vs.bin\", \"wb\");\n#endif\n\n\tint colors;\n\n//\tTVPTLG6InitGolombTable();\n\n\t// check pixel format\n\tif( bmp->Is32BPP() ) {\n\t\tif( is24 ) colors = 3;\n\t\telse colors = 4;\n\t} else {\n\t\tcolors = 1;\n\t}\n\tint stride = colors;\n\tif( stride == 3 ) stride = 4;\n\n\t// output stream header\n\t{\n\t\tout->WriteBuffer(\"TLG6.0\\x00raw\\x1a\\x00\", 11);\n\t\tout->WriteBuffer(&colors, 1);\n\t\tint n = 0;\n\t\tout->WriteBuffer(&n, 1); // data flag (0)\n\t\tout->WriteBuffer(&n, 1); // color type (0)\n\t\tout->WriteBuffer(&n, 1); // external golomb table (0)\n\t\tint width = bmp->GetWidth();\n\t\tint height = bmp->GetHeight();\n\t\tWriteInt32(width, out);\n\t\tWriteInt32(height, out);\n\t}\n\n\t// compress\n\tlong max_bit_length = 0;\n\n\tunsigned char *buf[MAX_COLOR_COMPONENTS];\n\tfor(int i = 0; i < MAX_COLOR_COMPONENTS; i++) buf[i] = NULL;\n\tchar *block_buf[MAX_COLOR_COMPONENTS];\n\tfor(int i = 0; i < MAX_COLOR_COMPONENTS; i++) block_buf[i] = NULL;\n\tunsigned char *filtertypes = NULL;\n\ttTVPMemoryStream *memstream = NULL;\n\n\ttry\n\t{\n\t\tmemstream = new tTVPMemoryStream();\n\n\t\tTLG6BitStream bs(memstream);\n\n//\t\tint buf_size = bmp->Width * bmp->Height;\n\n\t\t// allocate buffer\n\t\tfor(int c = 0; c < colors; c++)\n\t\t{\n\t\t\tbuf[c] = new unsigned char [W_BLOCK_SIZE * H_BLOCK_SIZE * 3];\n\t\t\tblock_buf[c] = new char [H_BLOCK_SIZE * bmp->GetWidth()];\n\t\t}\n\t\tint w_block_count = (int)((bmp->GetWidth() - 1) / W_BLOCK_SIZE) + 1;\n\t\tint h_block_count = (int)((bmp->GetHeight() - 1) / H_BLOCK_SIZE) + 1;\n\t\tfiltertypes = new unsigned char [w_block_count * h_block_count];\n\n\t\tint fc = 0;\n\t\tfor(int y = 0; y < (int)bmp->GetHeight(); y += H_BLOCK_SIZE)\n\t\t{\n\t\t\tint ylim = y + H_BLOCK_SIZE;\n\t\t\tif(ylim > (int)bmp->GetHeight()) ylim = bmp->GetHeight();\n\t\t\tint gwp = 0;\n\t\t\tint xp = 0;\n\t\t\tfor(int x = 0; x < (int)bmp->GetWidth(); x += W_BLOCK_SIZE, xp++)\n\t\t\t{\n\t\t\t\tint xlim = x + W_BLOCK_SIZE;\n\t\t\t\tif(xlim > (int)bmp->GetWidth()) xlim = bmp->GetWidth();\n\t\t\t\tint bw = xlim - x;\n\n\t\t\t\tint p0size; // size of MED method (p=0)\n\t\t\t\tint minp = 0; // most efficient method (0:MED, 1:AVG)\n\t\t\t\tint ft; // filter type\n\t\t\t\tint wp; // write point\n\t\t\t\tfor(int p = 0; p < 2; p++)\n\t\t\t\t{\n\t\t\t\t\tint dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE);\n\n\t\t\t\t\t// do med(when p=0) or take average of upper and left pixel(p=1)\n\t\t\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t\t\t{\n\t\t\t\t\t\tint wp = 0;\n\t\t\t\t\t\tfor(int yy = y; yy < ylim; yy++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst unsigned char * sl = x*stride +\n\t\t\t\t\t\t\t\tc + (const unsigned char *)bmp->GetScanLine(yy);\n\t\t\t\t\t\t\tconst unsigned char * usl;\n\t\t\t\t\t\t\tif(yy >= 1)\n\t\t\t\t\t\t\t\tusl = x*stride + c + (const unsigned char *)bmp->GetScanLine(yy-1);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tusl = NULL;\n\t\t\t\t\t\t\tfor(int xx = x; xx < xlim; xx++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tunsigned char pa = xx > 0 ? sl[-stride] : 0;\n\t\t\t\t\t\t\t\tunsigned char pb = usl ? *usl : 0;\n\t\t\t\t\t\t\t\tunsigned char px = *sl;\n\n\t\t\t\t\t\t\t\tunsigned char py;\n\n//\t\t\t\t\t\t\t\tpy = 0;\n\t\t\t\t\t\t\t\tif(p == 0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tunsigned char pc = (xx > 0 && usl) ? usl[-stride] : 0;\n\t\t\t\t\t\t\t\t\tunsigned char min_a_b = pa>pb?pb:pa;\n\t\t\t\t\t\t\t\t\tunsigned char max_a_b = pa<pb?pb:pa;\n\n\t\t\t\t\t\t\t\t\tif(pc >= max_a_b)\n\t\t\t\t\t\t\t\t\t\tpy = min_a_b;\n\t\t\t\t\t\t\t\t\telse if(pc < min_a_b)\n\t\t\t\t\t\t\t\t\t\tpy = max_a_b;\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tpy = pa + pb - pc;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpy = (pa+pb+1)>>1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tbuf[c][wp] = (unsigned char)(px - py);\n\n\t\t\t\t\t\t\t\twp++;\n\t\t\t\t\t\t\t\tsl += stride;\n\t\t\t\t\t\t\t\tif(usl) usl += stride;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// reordering\n\t\t\t\t\t// Transfer the data into block_buf (block buffer).\n\t\t\t\t\t// Even lines are stored forward (left to right),\n\t\t\t\t\t// Odd lines are stored backward (right to left).\n\n\t\t\t\t\twp = 0;\n\t\t\t\t\ttjs_uint32 reorderstart = TVPGetRoughTickCount32();\n\t\t\t\t\tfor(int yy = y; yy < ylim; yy++)\n\t\t\t\t\t{\n\t\t\t\t\t\tint ofs;\n\t\t\t\t\t\tif(!(xp&1))\n\t\t\t\t\t\t\tofs = (yy - y)*bw;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tofs = (ylim - yy - 1) * bw;\n\t\t\t\t\t\tbool dir; // false for forward, true for backward\n\t\t\t\t\t\tif(!((ylim-y)&1))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// vertical line count per block is even\n\t\t\t\t\t\t\tdir = ((yy&1) ^ (xp&1)) ? true : false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// otherwise;\n\t\t\t\t\t\t\tif(xp & 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdir = (yy&1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdir = ((yy&1) ^ (xp&1)) ? true : false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(!dir)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// forward\n\t\t\t\t\t\t\tfor(int xx = 0; xx < bw; xx++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t\t\t\t\t\t\tbuf[c][wp + dbofs] =\n\t\t\t\t\t\t\t\t\tbuf[c][ofs + xx];\n\t\t\t\t\t\t\t\twp++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// backward\n\t\t\t\t\t\t\tfor(int xx = bw - 1; xx >= 0; xx--)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t\t\t\t\t\t\tbuf[c][wp + dbofs] =\n\t\t\t\t\t\t\t\t\tbuf[c][ofs + xx];\n\t\t\t\t\t\t\t\twp++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treordertick += TVPGetRoughTickCount32() - reorderstart;\n\t\t\t\t}\n\n\n\t\t\t\tfor(int p = 0; p < 2; p++)\n\t\t\t\t{\n\t\t\t\t\tint dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE);\n\t\t\t\t\t// detect color filter\n\t\t\t\t\tint size = 0;\n\t\t\t\t\tint ft_;\n\t\t\t\t\tif(colors >= 3)\n\t\t\t\t\t\tft_ = DetectColorFilter(\n\t\t\t\t\t\t\treinterpret_cast<char*>(buf[0] + dbofs),\n\t\t\t\t\t\t\treinterpret_cast<char*>(buf[1] + dbofs),\n\t\t\t\t\t\t\treinterpret_cast<char*>(buf[2] + dbofs), wp, size);\n\t\t\t\t\telse\n\t\t\t\t\t\tft_ = 0;\n\n\t\t\t\t\t// select efficient mode of p (MED or average)\n\t\t\t\t\tif(p == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tp0size = size;\n\t\t\t\t\t\tft = ft_;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p0size >= size)\n\t\t\t\t\t\t\tminp = 1, ft = ft_;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply most efficient color filter / prediction method\n\t\t\t\twp = 0;\n\t\t\t\tint dbofs = (minp + 1)  * (H_BLOCK_SIZE * W_BLOCK_SIZE);\n\t\t\t\tfor(int yy = y; yy < ylim; yy++)\n\t\t\t\t{\n\t\t\t\t\tfor(int xx = 0; xx < bw; xx++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t\t\t\t\tblock_buf[c][gwp + wp] = buf[c][wp + dbofs];\n\t\t\t\t\t\twp++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tApplyColorFilter(block_buf[0] + gwp,\n\t\t\t\t\tblock_buf[1] + gwp, block_buf[2] + gwp, wp, ft);\n\n\t\t\t\tfiltertypes[fc++] = (ft<<1) + minp;\n//\t\t\t\tftfreq[ft]++;\n\t\t\t\tgwp += wp;\n\t\t\t}\n\n\t\t\t// compress values (entropy coding)\n\t\t\tfor(int c = 0; c < colors; c++)\n\t\t\t{\n\t\t\t\tint method;\n\t\t\t\tCompressValuesGolomb(bs, block_buf[c], gwp);\n\t\t\t\tmethod = 0;\n#ifdef WRITE_ENTROPY_VALUES\n\t\t\t\tfwrite(block_buf[c], 1, gwp, vs);\n#endif\n\t\t\t\tlong bitlength = bs.GetBitLength();\n\t\t\t\tif(bitlength & 0xc0000000)\n\t\t\t\t\tTVPThrowExceptionMessage( TVPTlgTooLargeBitLength );\n\t\t\t\t// two most significant bits of bitlength are\n\t\t\t\t// entropy coding method;\n\t\t\t\t// 00 means Golomb method,\n\t\t\t\t// 01 means Gamma method (implemented but not used),\n\t\t\t\t// 10 means modified LZSS method (not yet implemented),\n\t\t\t\t// 11 means raw (uncompressed) data (not yet implemented).\n\t\t\t\tif(max_bit_length < bitlength) max_bit_length = bitlength;\n\t\t\t\tbitlength |= (method << 30);\n\t\t\t\tWriteInt32(bitlength, memstream);\n\t\t\t\tbs.Flush();\n\t\t\t}\n\n\t\t}\n\n\n\t\t// write max bit length\n\t\tWriteInt32(max_bit_length, out);\n\n\t\t// output filter types\n\t\t{\n\t\t\tSlideCompressor comp;\n\t\t\tTLG6InitializeColorFilterCompressor(comp);\n\t\t\tunsigned char *outbuf = new unsigned char[fc * 2];\n\t\t\ttry\n\t\t\t{\n\t\t\t\tlong outlen;\n\t\t\t\tcomp.Encode(filtertypes, fc, outbuf, outlen);\n\t\t\t\tWriteInt32(outlen, out);\n\t\t\t\tout->WriteBuffer(outbuf, outlen);\n\t\t\t}\n\t\t\tcatch(...)\n\t\t\t{\n\t\t\t\tdelete [] outbuf;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\tdelete [] outbuf;\n\n\t\t}\n\n\t\t// copy memory stream to output stream\n\t\tout->WriteBuffer( memstream->GetInternalBuffer(), (tjs_uint)memstream->GetSize() );\n\t}\n\tcatch(...)\n\t{\n\t\tfor(int i = 0; i < MAX_COLOR_COMPONENTS; i++)\n\t\t{\n\t\t\tif(buf[i]) delete [] (buf[i]);\n\t\t\tif(block_buf[i]) delete [] (block_buf[i]);\n\t\t}\n\t\tif(filtertypes) delete [] filtertypes;\n\t\tif(memstream) delete memstream;\n\t\tthrow;\n\t}\n\n\tfor(int i = 0; i < MAX_COLOR_COMPONENTS; i++)\n\t{\n\t\tif(buf[i]) delete [] (buf[i]);\n\t\tif(block_buf[i]) delete [] (block_buf[i]);\n\t}\n\tif(filtertypes) delete [] filtertypes;\n\tif(memstream) delete memstream;\n\n#ifdef WRITE_ENTROPY_VALUES\n\tfclose(vs);\n#endif\n}\n//---------------------------------------------------------------------------\nextern void SaveTLG5( tTJSBinaryStream* stream, const iTVPBaseBitmap* image, bool is24 );\n//---------------------------------------------------------------------------\nvoid TVPSaveAsTLG(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta )\n{\n\tstd::vector<std::string> tags;\n\tif( meta ) {\n\t\tstruct MetaDictionaryEnumCallback : public tTJSDispatch {\n\t\t\tstd::vector<std::string>& Tags;\n\t\t\tMetaDictionaryEnumCallback( std::vector<std::string>& tags ) : Tags(tags) {}\n\t\t\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char * membername,\n\t\t\t\ttjs_uint32 *hint, tTJSVariant *result, tjs_int numparams,\n\t\t\t\ttTJSVariant **param, iTJSDispatch2 *objthis) {\n\t\t\t\t// called from tTJSCustomObject::EnumMembers\n\t\t\t\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t\t\t\t// hidden members are not processed\n\t\t\t\ttjs_uint32 flags = (tjs_int)*param[1];\n\t\t\t\tif(flags & TJS_HIDDENMEMBER) {\n\t\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\t\treturn TJS_S_OK;\n\t\t\t\t}\n\t\t\t\t// push items\n\t\t\t\tttstr value = *param[0];\n\t\t\t\tTags.push_back( value.AsNarrowStdString() );\n\t\t\t\tvalue = *param[2];\n\t\t\t\tTags.push_back( value.AsNarrowStdString() );\n\t\t\t\tif(result) *result = (tjs_int)1;\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t} callback(tags);\n\t\ttTJSVariantClosure clo(&callback, NULL);\n\t\tmeta->EnumMembers(TJS_IGNOREPROP, &clo, meta);\n\t}\n\n\tbool istls6 = false;\n\tif( mode.StartsWith( TJS_W(\"tlg5\") ) ) {\n\t\tistls6 = false;\n\t} else if( mode.StartsWith( TJS_W(\"tlg6\") ) ) {\n\t\tistls6 = true;\n\t} else {\n\t\tistls6 = false;\t// default : TLG5\n\t}\n\n\ttjs_uint height = image->GetHeight();\n\ttjs_uint width = image->GetWidth();\n\tif( height == 0 || width == 0 ) TVPThrowInternalError;\n\n\t// open stream\n\ttTJSBinaryStream *stream = dst;\n\ttry {\n\t\tif( tags.size() ) {\n\t\t\t// write TLG0.0 Structured Data Stream header\n\t\t\tstream->WriteBuffer(\"TLG0.0\\x00sds\\x1a\\x00\", 11);\n\t\t\ttjs_uint rawlenpos = (tjs_uint)stream->GetPosition();\n\t\t\tstream->WriteBuffer(\"0000\", 4);\n\n\t\t\t// write raw TLG stream\n\t\t\tif( istls6 ) {\n\t\t\t\tSaveTLG6( stream, image, mode == TJS_W(\"tlg624\") );\n\t\t\t} else {\n\t\t\t\tSaveTLG5( stream, image, mode == TJS_W(\"tlg524\") );\n\t\t\t}\n\n\t\t\t// write raw data size\n\t\t\ttjs_uint pos_save = (tjs_uint)stream->GetPosition();\n\t\t\tstream->SetPosition( rawlenpos );\n\t\t\ttjs_uint size = pos_save - rawlenpos - 4;\n\t\t\tunsigned char bin[4]; // buffer for writing 32bit integer as little endian format\n\t\t\tbin[0] = size & 0xff;\n\t\t\tbin[1] = (size >> 8) & 0xff;\n\t\t\tbin[2] = (size >> 16) & 0xff;\n\t\t\tbin[3] = (size >> 24) & 0xff;\n\t\t\tstream->WriteBuffer(bin, 4);\n\t\t\tstream->SetPosition( pos_save );\n\n\t\t\t// write \"tags\" chunk name\n\t\t\tstream->WriteBuffer(\"tags\", 4);\n\n\t\t\t// build tag data\n\t\t\tstd::stringstream tag;\n\t\t\tfor( tjs_uint i = 0; i < (tags.size()-1); i+=2 ) {\n\t\t\t\tstd::string name = tags[i];\n\t\t\t\tif( name.empty() ) continue;\n\t\t\t\tstd::string value = tags[i+1];\n\t\t\t\ttag << name.length() << \":\" << name << \"=\" << value.length() << \":\" << value << \",\";\n\t\t\t}\n\n\t\t\t// write chunk size\n\t\t\tstd::string tagstr = tag.str();\n\t\t\tsize = (tjs_uint)tagstr.length();\n\t\t\tbin[0] = size & 0xff;\n\t\t\tbin[1] = (size >> 8) & 0xff;\n\t\t\tbin[2] = (size >> 16) & 0xff;\n\t\t\tbin[3] = (size >> 24) & 0xff;\n\t\t\tstream->WriteBuffer(bin, 4);\n\n\t\t\t// write chunk data\n\t\t\tstream->WriteBuffer( tagstr.c_str(), (tjs_uint)tagstr.length() );\n\t\t} else {\n\t\t\tif( istls6 ) {\n\t\t\t\tSaveTLG6( stream, image, mode == TJS_W(\"tlg624\") );\n\t\t\t} else {\n\t\t\t\tSaveTLG5( stream, image, mode == TJS_W(\"tlg524\") );\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tthrow;\n\t}\n}\n"
  },
  {
    "path": "src/core/visual/TransIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Transition handler mamagement & default transition handlers\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"TransIntf.h\"\n#include \"LayerIntf.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"tjsHashSearch.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"tvpgl.h\"\n#include \"TickCount.h\"\n#include \"DebugIntf.h\"\n#include \"RenderManager.h\"\n#include \"Platform.h\"\n\n// #define TVP_TRANS_SHOW_FPS\n\n//---------------------------------------------------------------------------\n// iTVPSimpleOptionProvider implementation\n//---------------------------------------------------------------------------\n/* this implementation should move into other proper unit */\ntTVPSimpleOptionProvider::tTVPSimpleOptionProvider(tTJSVariantClosure object)\n{\n\tRefCount = 1;\n\tObject = object;\n\tObject.AddRef();\n}\n//---------------------------------------------------------------------------\ntTVPSimpleOptionProvider::~tTVPSimpleOptionProvider()\n{\n\tObject.Release();\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::AddRef()\n{\n\tRefCount++;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount--;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::GetAsNumber(\n\t\t/*in*/const tjs_char *name, /*out*/tjs_int64 *value)\n{\n\ttry\n\t{\n\t\ttTJSVariant val;\n\t\ttjs_error er = Object.PropGet(0, name, NULL, &val, NULL);\n\t\tif(TJS_FAILED(er)) return er;\n\n\t\tif(val.Type() == tvtVoid) return TJS_E_MEMBERNOTFOUND;\n\n\t\tif(value) *value = val.AsInteger();\n\n\t\treturn TJS_S_OK;\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::GetAsString(\n\t\t/*in*/const tjs_char *name, /*out*/const tjs_char **out)\n{\n\ttry\n\t{\n\t\ttTJSVariant val;\n\t\ttjs_error er = Object.PropGet(0, name, NULL, &val, NULL);\n\t\tif(TJS_FAILED(er)) return er;\n\n\t\tif(val.Type() == tvtVoid) return TJS_E_MEMBERNOTFOUND;\n\n\t\tString = val;  // to hold string buffer\n\t\tif(out) *out = String.c_str();\n\n\t\treturn TJS_S_OK;\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::GetValue(\n\t\t\t/*in*/const tjs_char *name, /*out*/tTJSVariant *dest)\n{\n\ttry\n\t{\n\t\tif(!dest) return TJS_E_FAIL;\n\t\ttjs_error er = Object.PropGet(0, name, NULL, dest, NULL);\n\t\tif(TJS_FAILED(er)) return er;\n\t\treturn TJS_S_OK;\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleOptionProvider::\n\tGetDispatchObject(iTJSDispatch2 **dsp)\n{\n\ttry\n\t{\n\t\tObject.ObjThis->AddRef();\n\t\tif(dsp) *dsp = Object.ObjThis;\n\t\treturn TJS_S_OK;\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// iTVPSimpleImageProvider implementation\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPSimpleImageProvider::LoadImage(\n\t\t\t/*in*/const tjs_char *name, /*in*/tjs_int bpp,\n\t\t\t/*in*/tjs_uint32 key,\n\t\t\t/*in*/tjs_uint w,\n\t\t\t/*in*/tjs_uint h,\n\t\t\t/*out*/iTVPScanLineProvider ** scpro)\n{\n\tif(bpp != 8 && bpp != 32) return TJS_E_FAIL; // invalid bitmap color depth\n\n\ttTVPBaseTexture *bitmap = new tTVPBaseTexture(TVPGetInitialBitmap());\n\n\ttry\n\t{\n\t\tTVPLoadGraphic(bitmap, name, key, w, h, bpp == 8 ? glmGrayscale : glmNormal);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete bitmap;\n\t\treturn TJS_E_FAIL;\n\t}\n\n\tif(scpro) *scpro = new tTVPScanLineProviderForBaseBitmap(bitmap, true);\n\n\treturn TJS_S_OK;\n}\ntTVPSimpleImageProvider TVPSimpleImageProvider;\n//---------------------------------------------------------------------------\n\n\n#if 0\n//---------------------------------------------------------------------------\n// Image Provider Service for other plug-ins\n//---------------------------------------------------------------------------\niTVPScanLineProvider * TVPSLPLoadImage(const ttstr &name, tjs_int bpp,\n\ttjs_uint32 key, tjs_uint w, tjs_uint h)\n{\n\tif(bpp != 8 && bpp != 32) return NULL; // invalid bitmap color depth\n\n\ttTVPBaseBitmap *bitmap = new tTVPBaseBitmap(TVPGetInitialBitmap());\n\n\tiTVPScanLineProvider *pro;\n\n\ttry\n\t{\n\t\tTVPLoadGraphic(bitmap, name, key, w, h, bpp == 8 ? glmGrayscale : glmNormal);\n\t\tpro = new tTVPScanLineProviderForBaseBitmap(bitmap, true);\n\t}\n\tcatch(...)\n\t{\n\t\tdelete bitmap;\n\t\tthrow;\n\t}\n\n\treturn pro;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// iTVPScanLineProvider implementation for image provider ( holds tTVPBaseBitmap )\n//---------------------------------------------------------------------------\ntTVPScanLineProviderForBaseBitmap::\n\ttTVPScanLineProviderForBaseBitmap(iTVPBaseBitmap *bmp, bool own)\n{\n\tRefCount = 1;\n\tOwn = own;\n\tBitmap = bmp;\n}\n//---------------------------------------------------------------------------\ntTVPScanLineProviderForBaseBitmap::~tTVPScanLineProviderForBaseBitmap()\n{\n\tif(Own) if(Bitmap) delete Bitmap;\n}\n//---------------------------------------------------------------------------\nvoid tTVPScanLineProviderForBaseBitmap::Attach(iTVPBaseBitmap *bmp)\n{\n\t// attach bitmap\n\tBitmap = bmp;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPScanLineProviderForBaseBitmap::AddRef()\n{\n\tRefCount ++;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPScanLineProviderForBaseBitmap::Release()\n{\n\tif(RefCount == 1)\n\t\tdelete this;\n\telse\n\t\tRefCount--;\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTVPScanLineProviderForBaseBitmap::GetWidth(/*in*/tjs_int *width)\n{\n\tif(width) *width = Bitmap->GetWidth();\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTVPScanLineProviderForBaseBitmap::GetHeight(/*in*/tjs_int *height)\n{\n\tif(height) *height = Bitmap->GetHeight();\n\treturn TJS_S_OK;\n}\n#if 0\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTVPScanLineProviderForBaseBitmap::GetPixelFormat(/*out*/tjs_int *bpp)\n{\n\tif(bpp) *bpp = Bitmap->GetBPP();\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPScanLineProviderForBaseBitmap::GetPitchBytes(\n\t/*out*/tjs_int *pitch)\n{\n\tif(pitch) *pitch = Bitmap->GetPitchBytes();\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTVPScanLineProviderForBaseBitmap::GetScanLine(/*in*/tjs_int line,\n\t\t\t/*out*/const void ** scanline)\n{\n\ttry\n\t{\n\t\tif(scanline) *scanline = Bitmap->GetScanLine(line);\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTVPScanLineProviderForBaseBitmap::GetScanLineForWrite(/*in*/tjs_int line,\n\t\t\t/*out*/void ** scanline)\n{\n\ttry\n\t{\n\t\tif(scanline) *scanline = Bitmap->GetScanLineForWrite(line);\n\t}\n\tcatch(...)\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\n#endif\n\niTVPTexture2D * tTVPScanLineProviderForBaseBitmap::GetTexture()\n{\n\treturn Bitmap->GetTexture();\n}\n\niTVPTexture2D * tTVPScanLineProviderForBaseBitmap::GetTextureForRender()\n{\n\treturn Bitmap->GetTextureForRender(false, nullptr);\n}\n\n\n\n\n//---------------------------------------------------------------------------\n// transition handler management\n//---------------------------------------------------------------------------\ntypedef tTJSRefHolder<iTVPTransHandlerProvider> tTVPTransHandlerProviderHolder;\nstatic tTJSHashTable<ttstr, tTVPTransHandlerProviderHolder>\n\tTVPTransHandlerProviders;\nbool TVPTransHandlerProviderInit = true;\n//---------------------------------------------------------------------------\nvoid TVPAddTransHandlerProvider(iTVPTransHandlerProvider *pro)\n{\n\t// add transition handler provider to the system\n\n\t// retrieve transition name\n\tconst tjs_char *cname;\n\tif(TJS_FAILED(pro->GetName(&cname)))\n\t\tTVPThrowExceptionMessage(TVPTransHandlerError,\n\t\tTJS_W(\"tTVPTransHandlerProvider::GetName failed\"));\n\tttstr name = cname;\n\ttTVPTransHandlerProviderHolder *p =\n\t\tTVPTransHandlerProviders.Find(name);\n\tif(p)\n\t\tTVPThrowExceptionMessage(TVPTransAlreadyRegistered, name);\n\n\ttTVPTransHandlerProviderHolder holder(pro);\n\tTVPTransHandlerProviders.Add(name, holder);\n}\n//---------------------------------------------------------------------------\nvoid TVPRemoveTransHandlerProvider(iTVPTransHandlerProvider *pro)\n{\n\t// remove transition handler provider from the system\n\n\t// retrieve transition name\n\tconst tjs_char * cname;\n\tif(TJS_FAILED(pro->GetName(&cname)))\n\t\tTVPThrowExceptionMessage(TVPTransHandlerError,\n\t\tTJS_W(\"tTVPTransHandlerProvider::GetName failed\"));\n\tttstr name = cname;\n\n\tTVPTransHandlerProviders.Delete(name);\n}\n//---------------------------------------------------------------------------\nstatic void TVPRegisterDefaultTransHandlerProvider();\niTVPTransHandlerProvider * TVPFindTransHandlerProvider(const ttstr &name)\n{\n\tif(TVPTransHandlerProviderInit)\n\t{\n\t\t// we assume that transition that has the same name as the other does\n\t\t// not exist\n\t\tTVPRegisterDefaultTransHandlerProvider();\n\t\tTVPTransHandlerProviderInit = false;\n\t}\n\n\ttTVPTransHandlerProviderHolder *holder =\n\t\tTVPTransHandlerProviders.Find(name);\n\tif (!holder) {\n\t\tstatic bool showed = false;\n\t\tif (!showed) {\n\t\t\tTVPShowSimpleMessageBox(TVPFormatMessage(TVPCannotFindTransHander, name), TJS_W(\"Warning\"));\n\t\t\tshowed = true;\n\t\t}\n\t\tholder = TVPTransHandlerProviders.Find(TJS_W(\"crossfade\"));\n\t}\n\n\tiTVPTransHandlerProvider * pro = holder->GetObjectNoAddRef();\n\tpro->AddRef();\n\treturn pro;\n}\n//---------------------------------------------------------------------------\nstatic void TVPClearTransHandlerProvider()\n{\n\t// called at system shutdown\n\tTVPTransHandlerProviders.Clear();\n}\nstatic tTVPAtExit\n\tTVPClearTransHandlerProviderAtExit(TVP_ATEXIT_PRI_SHUTDOWN,\n\t\tTVPClearTransHandlerProvider);\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Cross fade transition handler\n//---------------------------------------------------------------------------\n//extern DWORD acctime;\n\nclass tTVPCrossFadeTransHandler : public iTVPDivisibleTransHandler\n{\n\ttjs_int RefCount;\nprotected:\n\tiTVPSimpleOptionProvider *Options;\n\ttTVPLayerType DestLayerType;\n\ttjs_uint64 StartTick;\n\ttjs_uint64 Time; // time during transition\n\tbool First;\n\n\ttjs_int PhaseMax;\n\ttjs_int Phase; // current phase (0 thru PhaseMax)\n\n#ifdef TVP_TRANS_SHOW_FPS\n\ttjs_int Count;\n\ttjs_uint32 ProcessTick;\n\ttjs_uint32 ProcessTime;\n\ttjs_uint32 BlendTick;\n\ttjs_uint32 BlendTime;\n#endif\n\npublic:\n\ttTVPCrossFadeTransHandler(iTVPSimpleOptionProvider *options,\n\t\ttTVPLayerType layertype, tjs_uint64 time, tjs_int phasemax = 255)\n\t{\n\t\tRefCount = 1;\n\t\tDestLayerType = layertype;\n\t\tOptions = options;\n\t\tif(Options) Options->AddRef();\n\t\tTime = time;\n\t\tPhaseMax = phasemax;\n#ifdef TVP_TRANS_SHOW_FPS\n\t\tCount = 0;\n\t\tProcessTime = 0;\n\t\tBlendTime = 0;\n\n//\t\tacctime = 0;\n#endif\n\t\tFirst = true;\n\t}\n\n\tvirtual ~tTVPCrossFadeTransHandler()\n\t{\n\t\tif(Options) Options->Release();\n\t}\n\n\ttjs_error TJS_INTF_METHOD AddRef()\n\t{\n\t\tRefCount ++;\n\t\treturn TJS_S_OK;\n\t}\n\n\ttjs_error TJS_INTF_METHOD Release()\n\t{\n\t\tif(RefCount == 1) delete this; else RefCount--;\n\t\treturn TJS_S_OK;\n\t}\n\n\n\ttjs_error TJS_INTF_METHOD SetOption(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options // option provider\n\t\t)\n\t{\n\t\tif(Options) Options->Release();\n\t\toptions = options;\n\t\tOptions = options;\n\t\tif(Options) Options->AddRef();\n\t\treturn TJS_S_OK;\n\t}\n\n\ttjs_error TJS_INTF_METHOD StartProcess(tjs_uint64 tick);\n\ttjs_error TJS_INTF_METHOD EndProcess();\n\ttjs_error TJS_INTF_METHOD Process(\n\t\t\t/*in,out*/tTVPDivisibleData *data);\n\ttjs_error TJS_INTF_METHOD MakeFinalImage(\n\t\t\t/*in,out*/iTVPScanLineProvider ** dest,\n\t\t\t/*in*/iTVPScanLineProvider * src1,\n\t\t\t/*in*/iTVPScanLineProvider * src2);\n\n\tvirtual void Blend(tTVPDivisibleData *data);\n};\n//---------------------------------------------------------------------------\n\ntTVPCrossFadeTransHandlerProvider::tTVPCrossFadeTransHandlerProvider()\n{\n\tRefCount = 1;\n}\n\ntTVPCrossFadeTransHandlerProvider::~tTVPCrossFadeTransHandlerProvider()\n{\n\n}\n\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandlerProvider::AddRef()\n{\n\tRefCount++;\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandlerProvider::Release()\n{\n\tif (RefCount == 1) delete this; else RefCount--;\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandlerProvider::GetName(/*out*/const tjs_char ** name)\n{\n\tif (name)\n\t{\n\t\t*name = TJS_W(\"crossfade\"); return TJS_S_OK;\n\t} else\n\t{\n\t\treturn TJS_E_FAIL;\n\t}\n}\n\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandlerProvider::StartTransition(/*in*/iTVPSimpleOptionProvider *options, /* option provider */ /*in*/iTVPSimpleImageProvider *imagepro, /* image provider */ /*in*/tTVPLayerType layertype, /* destination layer type */ /*in*/tjs_uint src1w, tjs_uint src1h, /* source 1 size */ /*in*/tjs_uint src2w, tjs_uint src2h, /* source 2 size */ /*out*/tTVPTransType *type, /* transition type */ /*out*/tTVPTransUpdateType * updatetype, /* update typwe */ /*out*/iTVPBaseTransHandler ** handler /* transition handler */)\n{\n\tif (type) *type = ttExchange; // transition type : exchange\n\tif (updatetype) *updatetype = tutDivisibleFade;\n\t// update type : divisible fade\n\tif (!handler) return TJS_E_FAIL;\n\tif (!options) return TJS_E_FAIL;\n\n\tif (src1w != src2w || src1h != src2h)\n\t\tTVPThrowExceptionMessage(TVPTransitionLayerSizeMismatch,\n\t\tttstr((tjs_int)src2w) + TJS_W(\"x\") + ttstr((tjs_int)src2h),\n\t\tttstr((tjs_int)src1w) + TJS_W(\"x\") + ttstr((tjs_int)src1h));\n\n\t*handler = GetTransitionObject(options, imagepro, layertype, src1w, src1h,\n\t\tsrc2w, src2h);\n\n\treturn TJS_S_OK;\n}\n\niTVPBaseTransHandler * tTVPCrossFadeTransHandlerProvider::GetTransitionObject(/*in*/iTVPSimpleOptionProvider *options, /* option provider */ /*in*/iTVPSimpleImageProvider *imagepro, /* image provider */ /*in*/tTVPLayerType layertype, /*in*/tjs_uint src1w, tjs_uint src1h, /* source 1 size */ /*in*/tjs_uint src2w, tjs_uint src2h) // source 2 size\n{\n\ttjs_int64 time;\n\ttjs_error er = options->GetAsNumber(TJS_W(\"time\"), (tjs_int64 *)&time);\n\tif (TJS_FAILED(er)) TVPThrowExceptionMessage(TVPSpecifyOption, TJS_W(\"time\"));\n\tif (time < 2) time = 2; // too small time may cause problem\n\n\treturn  (iTVPBaseTransHandler *)\n\t\t(new tTVPCrossFadeTransHandler(options, layertype, time));\n}\n\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandler::\n\tStartProcess(tjs_uint64 tick)\n{\n\t// notifies starting of the update\n\tif(First)\n\t{\n\t\tFirst = false;\n\t\tStartTick = tick;\n\n\t}\n\n\t// compute phase ( 0 thru 255 )\n\tPhase = static_cast<tjs_int>( (tick - StartTick)  * PhaseMax / Time );\n\tif(Phase >= PhaseMax) Phase = PhaseMax;\n\n#ifdef TVP_TRANS_SHOW_FPS\n\tif((tick-StartTick) >= Time/2)\n\t{\n\t\tif(Count)\n\t\t{\n\t\t\tTVPAddLog(TJS_W(\"update count : \") + ttstr(Count));\n\t\t\tTVPAddLog(TJS_W(\"trans time : \") + ttstr((tjs_int)(tick-StartTick)));\n\t\t\tTVPAddLog(TJS_W(\"process time : \") + ttstr((tjs_int)ProcessTime));\n\t\t\tTVPAddLog(TJS_W(\"process time / trans time (%) : \") +\n\t\t\t\tttstr((tjs_int)(ProcessTime*100/(tick-StartTick))));\n\t\t\tTVPAddLog(TJS_W(\"blend time / trans time (%) : \") +\n\t\t\t\tttstr((tjs_int)(BlendTime*100/(tick-StartTick))));\n//\t\t\tTVPAddLog(TJS_W(\"blt time / trans time (%) : \") +\n//\t\t\t\tttstr((tjs_int)(acctime*100/(tick-StartTick))));\n\t\t\ttjs_int avgtime;\n\t\t\tavgtime = ProcessTime / Count;\n\t\t\tTVPAddLog(TJS_W(\"process time / update count : \") + ttstr(avgtime));\n\t\t\ttjs_int fps = Count * 1000 / (tick - StartTick);\n\t\t\tTVPAddLog(TJS_W(\"fps : \") + ttstr(fps));\n\n\t\t\tCount = 0;\n\t\t}\n\t}\n\telse\n\t{\n\t\tCount++;\n\t}\n\n\n\tProcessTick = TVPGetRoughTickCount32();\n#endif\n\n\treturn TJS_S_TRUE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandler::EndProcess()\n{\n\t// notifies ending of the update\n#ifdef TVP_TRANS_SHOW_FPS\n\tProcessTime += TVPGetRoughTickCount32() - ProcessTick;\n#endif\n\n\tif(Phase >= PhaseMax) return TJS_S_FALSE;\n\treturn TJS_S_TRUE;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandler::Process(\n\t\t/*in,out*/tTVPDivisibleData *data)\n{\n\t// process divided region of the entire layer bitmap\n\n#ifdef TVP_TRANS_SHOW_FPS\n\tBlendTick = TVPGetRoughTickCount32();\n#endif\n\n\tif(Phase == 0)\n\t{\n\t\t// completely source 1\n\t\tdata->Dest = data->Src1;\n\t\tdata->DestLeft = data->Src1Left;\n\t\tdata->DestTop = data->Src1Top;\n\t}\n\telse if(Phase == PhaseMax)\n\t{\n\t\t// completety source 2\n\t\tdata->Dest = data->Src2;\n\t\tdata->DestLeft = data->Src2Left;\n\t\tdata->DestTop = data->Src2Top;\n\t}\n\telse\n\t{\n\t\t// blend\n\t\tBlend(data);\n\t}\n\n#ifdef TVP_TRANS_SHOW_FPS\n\tBlendTime += TVPGetRoughTickCount32() - BlendTick;\n#endif\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid tTVPCrossFadeTransHandler::Blend(tTVPDivisibleData *data)\n{\n\t// blend\n#if 0\n\ttjs_uint8 *dest;\n\tconst tjs_uint8 *src1;\n\tconst tjs_uint8 *src2;\n\ttjs_int destpitch;\n\ttjs_int src1pitch;\n\ttjs_int src2pitch;\n\n\tdata->Dest->GetScanLineForWrite(data->DestTop, (void**)&dest);\n\tdata->Src1->GetScanLine(data->Src1Top, (const void**)&src1);\n\tdata->Src2->GetScanLine(data->Src2Top, (const void**)&src2);\n\n\tdata->Dest->GetPitchBytes(&destpitch);\n\tdata->Src1->GetPitchBytes(&src1pitch);\n\tdata->Src2->GetPitchBytes(&src2pitch);\n\n\tdest += data->DestLeft * sizeof(tjs_uint32);\n\tsrc1 += data->Src1Left * sizeof(tjs_uint32);\n\tsrc2 += data->Src2Left * sizeof(tjs_uint32);\n\n\ttjs_int h = data->Height;\n\n\tif(TVPIsTypeUsingAlpha(DestLayerType))\n\t{\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPConstAlphaBlend_SD_d((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t(const tjs_uint32*)src2, data->Width, Phase);\n\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t}\n\t}\n\telse if(TVPIsTypeUsingAddAlpha(DestLayerType))\n\t{\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPConstAlphaBlend_SD_a((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t(const tjs_uint32*)src2, data->Width, Phase);\n\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t}\n\t}\n\telse\n\t{\n\t\twhile(h--)\n\t\t{\n\t\t\tTVPConstAlphaBlend_SD((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t(const tjs_uint32*)src2, data->Width, Phase);\n\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t}\n\t}\n#endif\n\tiTVPRenderMethod *method;\n\tint opa_id;\n\tif (TVPIsTypeUsingAlpha(DestLayerType)) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstAlphaBlend_SD_d\");\n\t\tstatic int _opa_id = _method->EnumParameterID(\"opacity\");\n\t\tmethod = _method; opa_id = _opa_id;\n\t} else if (TVPIsTypeUsingAddAlpha(DestLayerType)) {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstAlphaBlend_SD_a\");\n\t\tstatic int _opa_id = _method->EnumParameterID(\"opacity\");\n\t\tmethod = _method; opa_id = _opa_id;\n\t} else {\n\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"ConstAlphaBlend_SD\");\n\t\tstatic int _opa_id = _method->EnumParameterID(\"opacity\");\n\t\tmethod = _method; opa_id = _opa_id;\n\t}\n\tmethod->SetParameterOpa(opa_id, Phase);\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(data->Src1->GetTexture(), tTVPRect(data->Src1Left, data->Src1Top, data->Src1Left + data->Width, data->Src1Top + data->Height)),\n\t\ttRenderTexRectArray::Element(data->Src2->GetTexture(), tTVPRect(data->Src2Left, data->Src2Top, data->Src2Left + data->Width, data->Src2Top + data->Height))\n\t};\n\tTVPGetRenderManager()->OperateRect(method, data->Dest->GetTextureForRender(),\n\t\tnullptr, tTVPRect(data->DestLeft, data->DestTop, data->DestLeft + data->Width, data->DestTop + data->Height),\n\t\ttRenderTexRectArray(src_tex));\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPCrossFadeTransHandler::MakeFinalImage(\n\t\t/*in,out*/iTVPScanLineProvider ** dest,\n\t\t/*in*/iTVPScanLineProvider * src1,\n\t\t/*in*/iTVPScanLineProvider * src2)\n{\n\t// final image is the source2 bitmap\n\t*dest = src2;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// universal transition handler\n//---------------------------------------------------------------------------\nclass tTVPUniversalTransHandler : public tTVPCrossFadeTransHandler\n{\n\ttypedef tTVPCrossFadeTransHandler inherited;\n\n\ttjs_int Vague;\n\tiTVPScanLineProvider * Rule;\n\t//tjs_uint32 BlendTable[256];\n\tiTVPRenderMethod *Method;\n\ttjs_int MethodPhaseID, MethodVagueID;\npublic:\n\ttTVPUniversalTransHandler(\n\t\tiTVPSimpleOptionProvider *options,\n\t\ttTVPLayerType destlayertype, tjs_uint64 time, tjs_int vague,\n\t\tiTVPScanLineProvider *rule) :\n\t\t\ttTVPCrossFadeTransHandler(options, destlayertype, time, 255+vague)\n\t{\n\t\tVague = vague;\n\t\tRule = rule;\n\t\tRule->AddRef();\n\n\t\tif (TVPIsTypeUsingAlpha(DestLayerType)) {\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"UnivTransBlend_d\");\n\t\t\tstatic int phase_id = _method->EnumParameterID(\"phase\"), vague_id = _method->EnumParameterID(\"vague\");\n\t\t\tMethod = _method; MethodPhaseID = phase_id; MethodVagueID = vague_id;\n\t\t} else if (TVPIsTypeUsingAddAlpha(DestLayerType)) {\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"UnivTransBlend_a\");\n\t\t\tstatic int phase_id = _method->EnumParameterID(\"phase\"), vague_id = _method->EnumParameterID(\"vague\");\n\t\t\tMethod = _method; MethodPhaseID = phase_id; MethodVagueID = vague_id;\n\t\t} else {\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"UnivTransBlend\");\n\t\t\tstatic int phase_id = _method->EnumParameterID(\"phase\"), vague_id = _method->EnumParameterID(\"vague\");\n\t\t\tMethod = _method; MethodPhaseID = phase_id; MethodVagueID = vague_id;\n\t\t}\n\t\tMethod->SetParameterInt(MethodVagueID, vague);\n\t}\n\n\t~tTVPUniversalTransHandler()\n\t{\n\t\tRule->Release();\n\t}\n\n\ttjs_error TJS_INTF_METHOD StartProcess(tjs_uint64 tick);\n\t\t// tTVPCrossFadeTransHandler::blend override\n\tvoid Blend(tTVPDivisibleData *data);\n\t\t// tTVPCrossFadeTransHandler::blend override\n\n};\n//---------------------------------------------------------------------------\nclass tTVPUniversalTransHandlerProvider : public tTVPCrossFadeTransHandlerProvider\n{\npublic:\n\ttTVPUniversalTransHandlerProvider() : tTVPCrossFadeTransHandlerProvider() {}\n\tvirtual ~tTVPUniversalTransHandlerProvider() { };\n\n\ttjs_error TJS_INTF_METHOD GetName(\n\t\t\t/*out*/const tjs_char ** name)\n\t{\n\t\tif(name)\n\t\t\t{ *name = TJS_W(\"universal\"); return TJS_S_OK; }\n\t\telse\n\t\t\t{ return TJS_E_FAIL; }\n\n\t}\n\n\tvirtual iTVPBaseTransHandler * GetTransitionObject(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t\t/*in*/tTVPLayerType layertype,\n\t\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t\t/*in*/tjs_uint src2w, tjs_uint src2h) // source 2 size\n\t{\n\t\ttjs_error er;\n\n\t\t// retrieve \"time\" option\n\t\ttjs_int64 time;\n\t\ter = options->GetAsNumber(TJS_W(\"time\"), (tjs_int64 *)&time);\n\t\tif(TJS_FAILED(er)) TVPThrowExceptionMessage(TVPSpecifyOption, TJS_W(\"time\"));\n\t\tif(time < 2) time = 2; // too small time may cause problem\n\n\t\t// retrieve \"vague\" option\n\t\ttjs_int64 vague;\n\t\ter = options->GetAsNumber(TJS_W(\"vague\"), (tjs_int64 *)&vague);\n\t\tif(TJS_FAILED(er)) vague = 64;\n\n\t\t// retrieve \"rule\" option and load it as an image\n\t\tconst tjs_char *rulename;\n\t\ter = options->GetAsString(TJS_W(\"rule\"), &rulename);\n\t\tif(TJS_FAILED(er)) TVPThrowExceptionMessage(TVPSpecifyOption, TJS_W(\"rule\"));\n\n\t\tiTVPScanLineProvider *scpro;\n\t\ter = imagepro->LoadImage(rulename, 8, 0x02ffffff,\n\t\t\tsrc1w, src1h, &scpro);\n\t\tif(TJS_FAILED(er))\n\t\t\tTVPThrowExceptionMessage(TVPCannotLoadRuleGraphic, rulename);\n\n\t\t// create a transition object\n\t\tiTVPBaseTransHandler *ret;\n\t\ttry\n\t\t{\n\t\t\tret =  (iTVPBaseTransHandler *)\n\t\t\t\t(new tTVPUniversalTransHandler(options, layertype, time, static_cast<tjs_int>(vague),\n\t\t\t\t\tscpro));\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tscpro->Release();\n\t\t\tthrow;\n\t\t}\n\t\tscpro->Release();\n\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTVPUniversalTransHandler::StartProcess(\n\ttjs_uint64 tick)\n{\n\ttjs_error er;\n\ter = inherited::StartProcess(tick);\n\tif(TJS_FAILED(er)) return er;\n\n\t// start one frame of the transition\n\tMethod->SetParameterInt(MethodPhaseID, Phase);\n#if 0\n\t// create blend table\n\tif(TVPIsTypeUsingAlpha(DestLayerType))\n\t\tTVPInitUnivTransBlendTable_d(BlendTable, Phase, Vague);\n\telse if(TVPIsTypeUsingAddAlpha(DestLayerType))\n\t\tTVPInitUnivTransBlendTable_a(BlendTable, Phase, Vague);\n\telse\n\t\tTVPInitUnivTransBlendTable(BlendTable, Phase, Vague);\n#endif\n\treturn er;\n}\n//---------------------------------------------------------------------------\nvoid tTVPUniversalTransHandler::Blend(tTVPDivisibleData *data)\n{\n\t// blend the image according with the rule graphic\n#if 0\n\ttjs_uint8 *dest;\n\tconst tjs_uint8 *src1;\n\tconst tjs_uint8 *src2;\n\tconst tjs_uint8 *rule;\n\n\tdata->Dest->GetScanLineForWrite(data->DestTop, (void**)&dest);\n\tdata->Src1->GetScanLine(data->Src1Top, (const void**)&src1);\n\tdata->Src2->GetScanLine(data->Src2Top, (const void**)&src2);\n\tRule->GetScanLine(data->Top, (const void**)&rule);\n\n\ttjs_int destpitch;\n\ttjs_int src1pitch;\n\ttjs_int src2pitch;\n\ttjs_int rulepitch;\n\n\tdata->Dest->GetPitchBytes(&destpitch);\n\tdata->Src1->GetPitchBytes(&src1pitch);\n\tdata->Src2->GetPitchBytes(&src2pitch);\n\tRule->GetPitchBytes(&rulepitch);\n\n\tdest += data->DestLeft * sizeof(tjs_uint32);\n\tsrc1 += data->Src1Left * sizeof(tjs_uint32);\n\tsrc2 += data->Src2Left * sizeof(tjs_uint32);\n\trule += data->Left * sizeof(tjs_uint8);\n\n\ttjs_int h = data->Height;\n\tif(Vague >= 512)\n\t{\n\t\tif(TVPIsTypeUsingAlpha(DestLayerType))\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend_d((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t\telse if(TVPIsTypeUsingAddAlpha(DestLayerType))\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend_a((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\ttjs_int src1lv = Phase;\n\t\ttjs_int src2lv = Phase - Vague;\n\n\t\tif(TVPIsTypeUsingAlpha(DestLayerType))\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend_switch_d((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width,\n\t\t\t\t\t\tsrc1lv, src2lv);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t\telse if(TVPIsTypeUsingAddAlpha(DestLayerType))\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend_switch_a((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width,\n\t\t\t\t\t\tsrc1lv, src2lv);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(h--)\n\t\t\t{\n\t\t\t\tTVPUnivTransBlend_switch((tjs_uint32*)dest, (const tjs_uint32*)src1,\n\t\t\t\t\t(const tjs_uint32*)src2, rule, BlendTable, data->Width,\n\t\t\t\t\t\tsrc1lv, src2lv);\n\t\t\t\tdest += destpitch, src1 += src1pitch, src2 += src2pitch;\n\t\t\t\trule += rulepitch;\n\t\t\t}\n\t\t}\n\t}\n#endif\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(data->Src1->GetTexture(), tTVPRect(data->Src1Left, data->Src1Top, data->Src1Left + data->Width, data->Src1Top + data->Height)),\n\t\ttRenderTexRectArray::Element(data->Src2->GetTexture(), tTVPRect(data->Src2Left, data->Src2Top, data->Src2Left + data->Width, data->Src2Top + data->Height)),\n\t\ttRenderTexRectArray::Element(Rule->GetTexture(), tTVPRect(data->Left, data->Top, data->Left + data->Width, data->Top + data->Height))\n\t};\n\tTVPGetRenderManager()->OperateRect(Method, data->Dest->GetTextureForRender(),\n\t\tnullptr, tTVPRect(data->DestLeft, data->DestTop, data->DestLeft + data->Width, data->DestTop + data->Height),\n\t\ttRenderTexRectArray(src_tex));\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// scroll transition handler\n//---------------------------------------------------------------------------\nstatic void TVPSLPCopyRect(iTVPScanLineProvider *destimg, tjs_int x, tjs_int y,\n\tiTVPScanLineProvider *srcimg, const tTVPRect &srcrect)\n{\n\t// this function does not matter if the src==dest and copying area is\n\t// overlapped.\n\t// destimg and srcimg must be 32bpp bitmap.\n#if 0\n\ttjs_uint8 *dest;\n\tconst tjs_uint8 *src;\n\ttjs_int destpitch;\n\ttjs_int srcpitch;\n\n\tdestimg->GetScanLineForWrite(y, (void**)&dest);\n\tsrcimg->GetScanLine(srcrect.top, (const void**)&src);\n\n\tdestimg->GetPitchBytes(&destpitch);\n\tsrcimg->GetPitchBytes(&srcpitch);\n\n\tdest += x * sizeof(tjs_uint32);\n\tsrc += srcrect.left * sizeof(tjs_uint32);\n\n\ttjs_int h = srcrect.get_height();\n\ttjs_int bytes = srcrect.get_width() * sizeof(tjs_uint32);\n\twhile(h--)\n\t{\n\t\tmemcpy(dest, src, bytes);\n\t\tdest += destpitch, src += srcpitch;\n\t}\n#endif\n\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"Copy\");\n\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(srcimg->GetTexture(), srcrect)\n\t};\n\n\tTVPGetRenderManager()->OperateRect(method, destimg->GetTextureForRender(), nullptr,\n\t\ttTVPRect(x, y, x + srcrect.get_width(), y + srcrect.get_height()), tRenderTexRectArray(src_tex));\n}\n//---------------------------------------------------------------------------\nclass tTVPScrollTransHandler : public tTVPCrossFadeTransHandler\n{\n\ttypedef tTVPCrossFadeTransHandler inherited;\n\n\ttTVPScrollTransFrom From;\n\ttTVPScrollTransStay Stay;\n\npublic:\n\ttTVPScrollTransHandler(\n\t\tiTVPSimpleOptionProvider *options,\n\t\ttTVPLayerType layertype, tjs_uint64 time, tTVPScrollTransFrom from,\n\t\t\ttTVPScrollTransStay stay, tjs_int maxphase) :\n\t\t\ttTVPCrossFadeTransHandler(options, layertype, time, maxphase)\n\t{\n\t\tFrom = from;\n\t\tStay = stay;\n\t}\n\n\t~tTVPScrollTransHandler()\n\t{\n\t}\n\n\tvoid Blend(tTVPDivisibleData *data);\n\t\t// tTVPCrossFadeTransHandler::blend override\n\n};\n//---------------------------------------------------------------------------\nclass tTVPScrollTransHandlerProvider : public tTVPCrossFadeTransHandlerProvider\n{\npublic:\n\ttTVPScrollTransHandlerProvider() : tTVPCrossFadeTransHandlerProvider() {}\n\tvirtual ~tTVPScrollTransHandlerProvider() { };\n\n\ttjs_error TJS_INTF_METHOD GetName(\n\t\t\t/*out*/const tjs_char ** name)\n\t{\n\t\tif(name)\n\t\t\t{ *name = TJS_W(\"scroll\"); return TJS_S_OK; }\n\t\telse\n\t\t\t{ return TJS_E_FAIL; }\n\n\t}\n\n\ttjs_error TJS_INTF_METHOD StartTransition(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t\t/*in*/tTVPLayerType layertype, // destination layer type\n\t\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t\t/*in*/tjs_uint src2w, tjs_uint src2h, // source 2 size\n\t\t\t/*out*/tTVPTransType *type, // transition type\n\t\t\t/*out*/tTVPTransUpdateType * updatetype, // update typwe\n\t\t\t/*out*/iTVPBaseTransHandler ** handler // transition handler\n\t\t\t)\n\t{\n\t\ttjs_error er = tTVPCrossFadeTransHandlerProvider::StartTransition\n\t\t\t(options, imagepro, layertype, src1w, src1h, src2w, src2h,\n\t\t\ttype, updatetype, handler);\n\n\t\tif(TJS_SUCCEEDED(er)) *updatetype = tutDivisible;\n\n\t\treturn er;\n\t}\n\n\n\tvirtual iTVPBaseTransHandler * GetTransitionObject(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t\t/*in*/tTVPLayerType layertype,\n\t\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t\t/*in*/tjs_uint src2w, tjs_uint src2h) // source 2 size\n\t{\n\t\ttjs_error er;\n\t\ttjs_int64 value;\n\n\t\t// retrieve \"time\" option\n\t\ttjs_int64 time;\n\t\ter = options->GetAsNumber(TJS_W(\"time\"), &time);\n\t\tif(TJS_FAILED(er)) TVPThrowExceptionMessage(TVPSpecifyOption, TJS_W(\"time\"));\n\t\tif(time < 2) time = 2; // too small time may cause problem\n\n\t\t// retrieve \"from\" option\n\t\ttTVPScrollTransFrom from;\n\t\ter = options->GetAsNumber(TJS_W(\"from\"), &value);\n\t\tif(TJS_FAILED(er)) from = sttLeft; else from = (tTVPScrollTransFrom)value;\n\n\t\t// retrieve \"stay\" option\n\t\ttTVPScrollTransStay stay;\n\t\ter = options->GetAsNumber(TJS_W(\"stay\"), &value);\n\t\tif(TJS_FAILED(er)) stay = ststNoStay; else stay = (tTVPScrollTransStay)value;\n\n\t\t// determine maximum phase count\n\t\ttjs_int maxphase = (from == sttLeft || from == sttRight)?src1w:src2h;\n\n\t\t// create a transition object\n\t\tiTVPBaseTransHandler *ret;\n\t\tret =  (iTVPBaseTransHandler *)\n\t\t\t(new tTVPScrollTransHandler(options, layertype, time, from,\n\t\t\t\tstay, maxphase));\n\t\treturn ret;\n\t}\n};\n//---------------------------------------------------------------------------\nstruct tTVPScrollDivisibleData : public tTVPDivisibleData\n{\n\tvoid Blend(tTVPScrollTransFrom from, tTVPScrollTransStay stay, tjs_int phase);\n};\n//---------------------------------------------------------------------------\nvoid tTVPScrollTransHandler::Blend(tTVPDivisibleData *data)\n{\n\t((tTVPScrollDivisibleData*)data)->Blend(From, Stay, Phase);\n}\n//---------------------------------------------------------------------------\nvoid tTVPScrollDivisibleData::Blend(tTVPScrollTransFrom from,\n\ttTVPScrollTransStay stay, tjs_int phase)\n{\n\t// scroll the image\n\ttjs_int imagewidth;\n\ttjs_int imageheight;\n\tSrc1->GetWidth(&imagewidth);\n\tSrc1->GetHeight(&imageheight);\n\ttjs_int src1left = 0;\n\ttjs_int src1top = 0;\n\ttjs_int src2left = 0;\n\ttjs_int src2top = 0;\n\n\tswitch(from)\n\t{\n\tcase sttLeft:\n\t\tif(stay == ststNoStay)\n\t\t\tsrc1left = phase, src2left = phase - imagewidth;\n\t\telse if(stay == ststStayDest)\n\t\t\tsrc2left = phase - imagewidth;\n\t\telse if(stay == ststStaySrc)\n\t\t\tsrc1left = phase;\n\t\tbreak;\n\tcase sttTop:\n\t\tif(stay == ststNoStay)\n\t\t\tsrc1top = phase, src2top = phase - imageheight;\n\t\telse if(stay == ststStayDest)\n\t\t\tsrc2top = phase - imageheight;\n\t\telse if(stay == ststStaySrc)\n\t\t\tsrc1top = phase;\n\t\tbreak;\n\tcase sttRight:\n\t\tif(stay == ststNoStay)\n\t\t\tsrc1left = -phase, src2left = imagewidth - phase;\n\t\telse if(stay == ststStayDest)\n\t\t\tsrc2left = imagewidth - phase;\n\t\telse if(stay == ststStaySrc)\n\t\t\tsrc1left = -phase;\n\t\tbreak;\n\tcase sttBottom:\n\t\tif(stay == ststNoStay)\n\t\t\tsrc1top = -phase, src2top = imageheight - phase;\n\t\telse if(stay == ststStayDest)\n\t\t\tsrc2top = imageheight - phase;\n\t\telse if(stay == ststStaySrc)\n\t\t\tsrc1top = -phase;\n\t\tbreak;\n\t}\n\n\n\ttTVPRect rdest(Left, Top, Width+Left, Height+Top);\n\ttTVPRect rs1(src1left, src1top, imagewidth + src1left, imageheight + src1top);\n\ttTVPRect rs2(src2left, src2top, imagewidth + src2left, imageheight + src2top);\n\tif(stay == ststNoStay)\n\t{\n\t\t// both layers have no priority than another.\n\t\t// nothing to do.\n\t}\n\telse if(stay == ststStayDest)\n\t{\n\t\t// Src2 has priority.\n\t\tif(from == sttLeft || from == sttRight)\n\t\t{\n\t\t\tif(rs2.right >= rs1.left && rs2.right < rs1.right)\n\t\t\t\trs1.left = rs2.right;\n\t\t\tif(rs2.left >= rs1.left && rs2.left < rs1.right)\n\t\t\t\trs1.right = rs2.left;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(rs2.bottom >= rs1.top && rs2.bottom < rs1.bottom)\n\t\t\t\trs1.top = rs2.bottom;\n\t\t\tif(rs2.top >= rs1.top && rs2.top < rs1.bottom)\n\t\t\t\trs1.bottom = rs2.top;\n\t\t}\n\t}\n\telse if(stay == ststStaySrc)\n\t{\n\t\t// Src1 has priority.\n\t\tif(from == sttLeft || from == sttRight)\n\t\t{\n\t\t\tif(rs1.right >= rs2.left && rs1.right < rs2.right)\n\t\t\t\trs2.left = rs1.right;\n\t\t\tif(rs1.left >= rs2.left && rs1.left < rs2.right)\n\t\t\t\trs2.right = rs1.left;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(rs1.bottom >= rs2.top && rs1.bottom < rs2.bottom)\n\t\t\t\trs2.top = rs1.bottom;\n\t\t\tif(rs1.top >= rs2.top && rs1.top < rs2.bottom)\n\t\t\t\trs2.bottom = rs1.top;\n\t\t}\n\t}\n\n\t// copy to destination image\n\ttTVPRect d;\n\tif(TVPIntersectRect(&d, rdest, rs1))\n\t{\n\t\ttjs_int dl = d.left - Left + DestLeft, dt = d.top - Top + DestTop;\n\t\td.add_offsets(-src1left, -src1top);\n\t\tTVPSLPCopyRect(Dest, dl, dt, Src1, d);\n\t}\n\tif(TVPIntersectRect(&d, rdest, rs2))\n\t{\n\t\ttjs_int dl = d.left - Left + DestLeft, dt = d.top - Top + DestTop;\n\t\td.add_offsets(-src2left, -src2top);\n\t\tTVPSLPCopyRect(Dest, dl, dt, Src2, d);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n//---------------------------------------------------------------------------\nstatic void TVPRegisterDefaultTransHandlerProvider()\n{\n\t// register default internal transition handler providers.\n\n\tiTVPTransHandlerProvider *prov;\n\n\tprov = new tTVPCrossFadeTransHandlerProvider();\n\tTVPAddTransHandlerProvider(prov);\n\tprov->Release();\n\n\tprov = new tTVPUniversalTransHandlerProvider();\n\tTVPAddTransHandlerProvider(prov);\n\tprov->Release();\n\n\tprov = new tTVPScrollTransHandlerProvider();\n\tTVPAddTransHandlerProvider(prov);\n\tprov->Release();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/TransIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Transition handler mamagement & default transition handlers\n//---------------------------------------------------------------------------\n#ifndef TransIntfH\n#define TransIntfH\n//---------------------------------------------------------------------------\n\n#include \"LayerBitmapIntf.h\"\n#include \"transhandler.h\"\n\n\n//---------------------------------------------------------------------------\n// iTVPSimpleOptionProvider implementation\n//---------------------------------------------------------------------------\nclass tTVPSimpleOptionProvider : public iTVPSimpleOptionProvider\n{\n\ttjs_uint RefCount;\n\ttTJSVariantClosure Object;\n\tttstr String;\n\npublic:\n\ttTVPSimpleOptionProvider(tTJSVariantClosure object);\n\t~tTVPSimpleOptionProvider();\n\n\ttjs_error TJS_INTF_METHOD AddRef();\n\ttjs_error TJS_INTF_METHOD Release();\n\n\ttjs_error TJS_INTF_METHOD GetAsNumber(\n\t\t\t/*in*/const tjs_char *name, /*out*/tjs_int64 *value);\n\ttjs_error TJS_INTF_METHOD GetAsString(\n\t\t\t/*in*/const tjs_char *name, /*out*/const tjs_char **out);\n\n\ttjs_error TJS_INTF_METHOD GetValue(\n\t\t\t/*in*/const tjs_char *name, /*out*/tTJSVariant *dest);\n\n\ttjs_error TJS_INTF_METHOD Reserved2() { return TJS_E_NOTIMPL; }\n\n\ttjs_error TJS_INTF_METHOD GetDispatchObject(iTJSDispatch2 **dsp);\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPSimpleImageProvider implementation\n//---------------------------------------------------------------------------\nclass tTVPSimpleImageProvider : public iTVPSimpleImageProvider\n{\npublic:\n\ttjs_error TJS_INTF_METHOD LoadImage(\n\t\t\t/*in*/const tjs_char *name, /*in*/tjs_int bpp,\n\t\t\t/*in*/tjs_uint32 key, \n\t\t\t/*in*/tjs_uint w,\n\t\t\t/*in*/tjs_uint h,\n\t\t\t/*out*/iTVPScanLineProvider ** scpro);\n};\n//---------------------------------------------------------------------------\nextern tTVPSimpleImageProvider TVPSimpleImageProvider;\n//---------------------------------------------------------------------------\n#if 0\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(iTVPScanLineProvider *, TVPSLPLoadImage, (const ttstr &name, tjs_int bpp,\n\ttjs_uint32 key, tjs_uint w, tjs_uint h));\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// iTVPScanLineProvider implementation for image provider ( holds tTVPBaseBitmap )\n//---------------------------------------------------------------------------\n// provides layer scanline\nclass tTVPScanLineProviderForBaseBitmap : public iTVPScanLineProvider\n{\n\ttjs_uint RefCount;\n\tbool Own;\n\tiTVPBaseBitmap *Bitmap;\n\npublic:\n\ttTVPScanLineProviderForBaseBitmap(iTVPBaseBitmap *bmp, bool own = false);\n\t~tTVPScanLineProviderForBaseBitmap();\n\n\tvoid Attach(iTVPBaseBitmap *bmp); // attach bitmap\n\n\n\ttjs_error TJS_INTF_METHOD AddRef();\n\ttjs_error TJS_INTF_METHOD Release();\n\n\ttjs_error TJS_INTF_METHOD GetWidth(/*in*/tjs_int *width);\n\ttjs_error TJS_INTF_METHOD GetHeight(/*in*/tjs_int *height);\n#if 0\n\ttjs_error TJS_INTF_METHOD GetPixelFormat(/*out*/tjs_int *bpp);\n\ttjs_error TJS_INTF_METHOD GetPitchBytes(/*out*/tjs_int *pitch);\n\ttjs_error TJS_INTF_METHOD GetScanLine(/*in*/tjs_int line,\n\t\t\t/*out*/const void ** scanline);\n\ttjs_error TJS_INTF_METHOD GetScanLineForWrite(/*in*/tjs_int line,\n\t\t\t/*out*/void ** scanline);\n#endif\n\tvirtual iTVPTexture2D * GetTexture() override;\n\tvirtual iTVPTexture2D * GetTextureForRender() override;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// handler management functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(void, TVPAddTransHandlerProvider,(iTVPTransHandlerProvider *pro));\nTJS_EXP_FUNC_DEF(void, TVPRemoveTransHandlerProvider, (iTVPTransHandlerProvider *pro));\niTVPTransHandlerProvider * TVPFindTransHandlerProvider(const ttstr &name);\n//---------------------------------------------------------------------------\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// scroll transition handler\n//---------------------------------------------------------------------------\nenum tTVPScrollTransFrom\n{\n\tsttLeft, sttTop, sttRight, sttBottom\n};\nenum tTVPScrollTransStay\n{\n\tststNoStay, ststStayDest, ststStaySrc\n};\n/*]*/\n//---------------------------------------------------------------------------\n\nclass tTVPCrossFadeTransHandlerProvider : public iTVPTransHandlerProvider\n{\n\ttjs_int RefCount;\npublic:\n\ttTVPCrossFadeTransHandlerProvider();\n\tvirtual ~tTVPCrossFadeTransHandlerProvider();;\n\n\ttjs_error TJS_INTF_METHOD AddRef();\n\n\ttjs_error TJS_INTF_METHOD Release();\n\n\ttjs_error TJS_INTF_METHOD GetName(\n\t\t/*out*/const tjs_char ** name);\n\n\ttjs_error TJS_INTF_METHOD StartTransition(\n\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t/*in*/tTVPLayerType layertype, // destination layer type\n\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t/*in*/tjs_uint src2w, tjs_uint src2h, // source 2 size\n\t\t/*out*/tTVPTransType *type, // transition type\n\t\t/*out*/tTVPTransUpdateType * updatetype, // update typwe\n\t\t/*out*/iTVPBaseTransHandler ** handler // transition handler\n\t\t);\n\n\n\tvirtual iTVPBaseTransHandler * GetTransitionObject(\n\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t/*in*/tTVPLayerType layertype,\n\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t/*in*/tjs_uint src2w, tjs_uint src2h); // source 2 size\n};\n\n#endif\n"
  },
  {
    "path": "src/core/visual/VideoOvlIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Video Overlay support interface\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"MsgIntf.h\"\n#include \"WindowIntf.h\"\n#include \"VideoOvlIntf.h\"\n#include \"LayerIntf.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseVideoOverlay\n//---------------------------------------------------------------------------\ntTJSNI_BaseVideoOverlay::tTJSNI_BaseVideoOverlay()\n{\n\tActionOwner.Object = ActionOwner.ObjThis = NULL;\n\tStatus = ssUnload;\n\tOwner = NULL;\n\tCanDeliverEvents = true;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BaseVideoOverlay::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object == NULL) TVPThrowExceptionMessage(TVPSpecifyWindow);\n\ttTJSNI_Window *win = NULL;\n\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\ttTJSNC_Window::ClassID, (iTJSNativeInstance**)&win)))\n\t\tTVPThrowExceptionMessage(TVPSpecifyWindow);\n\tif(!win) TVPThrowExceptionMessage(TVPSpecifyWindow);\n\tWindow = win;\n\n\tWindow->RegisterVideoOverlayObject(this);\n\n\tActionOwner = param[0]->AsObjectClosure();\n\tOwner = tjs_obj;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseVideoOverlay::Invalidate()\n{\n\tOwner = NULL;\n\tif(Window) Window->UnregisterVideoOverlayObject(this);\n\tActionOwner.Release();\n\n\tinherited::Invalidate();\n}\n//---------------------------------------------------------------------------\nttstr tTJSNI_BaseVideoOverlay::GetStatusString() const\n{\n\tstatic ttstr unload(TJS_W(\"unload\"));\n\tstatic ttstr play(TJS_W(\"play\"));\n\tstatic ttstr stop(TJS_W(\"stop\"));\n\tstatic ttstr unknown(TJS_W(\"unknown\"));\n\tstatic ttstr pause(TJS_W(\"pause\"));\n\tstatic ttstr ready(TJS_W(\"ready\"));\n\n\tswitch(Status)\n\t{\n\tcase ssUnload:\treturn unload;\n\tcase ssPlay:\treturn play;\n\tcase ssStop:\treturn stop;\n\tcase ssPause:\treturn pause;\n\tcase ssReady:\treturn ready;\n\tdefault:\t\treturn unknown;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseVideoOverlay::SetStatus(tTVPSoundStatus s)\n{\n\t// this function may call the onStatusChanged event immediately\n\t\n\tif(Status != s)\n\t{\n\t\tStatus = s;\n\n\t\tif(Owner)\n\t\t{\n\t\t\t// Cancel Previous un-delivered Events\n\t\t\tTVPCancelSourceEvents(Owner);\n\n\t\t\t// fire\n\t\t\tif(CanDeliverEvents)\n\t\t\t{\n\t\t\t\t// fire onStatusChanged event\n\t\t\t\ttTJSVariant param(GetStatusString());\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onStatusChanged\"));\n\t\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE,\n\t\t\t\t\t1, &param);\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseVideoOverlay::SetStatusAsync(tTVPSoundStatus s)\n{\n\t// this function posts the onStatusChanged event\n\n\tif(Status != s)\n\t{\n\t\tStatus = s;\n\n\t\tif(Owner)\n\t\t{\n\t\t\t// Cancel Previous un-delivered Events\n\t\t\tTVPCancelSourceEvents(Owner);\n\n\t\t\t// fire\n\t\t\tif(CanDeliverEvents)\n\t\t\t{\n\t\t\t\t// fire onStatusChanged event\n\t\t\t\ttTJSVariant param(GetStatusString());\n\t\t\t\tstatic ttstr eventname(TJS_W(\"onStatusChanged\"));\n\t\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_POST,\n\t\t\t\t\t1, &param);\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseVideoOverlay::FireCallbackCommand(const ttstr & command,\n\tconst ttstr & argument)\n{\n\t// fire call back command event.\n\t// this is always synchronized event.\n\tif(Owner)\n\t{\n\t\t// fire\n\t\tif(CanDeliverEvents)\n\t\t{\n\t\t\t// fire onStatusChanged event\n\t\t\ttTJSVariant param[2] = {command, argument};\n\t\t\tstatic ttstr eventname(TJS_W(\"onCallbackCommand\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE,\n\t\t\t\t2, param);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseVideoOverlay::FirePeriodEvent(tTVPPeriodEventReason reason)\n{\n\t// fire onPeriod event\n\t// this is always synchronized event.\n\t\n\tif(Owner)\n\t{\n\t\t// fire\n\t\tif(CanDeliverEvents)\n\t\t{\n\t\t\t// fire onPeriod event\n\t\t\ttTJSVariant param[1] = {(tjs_int)reason};\n\t\t\tstatic ttstr eventname(TJS_W(\"onPeriod\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE,\n\t\t\t\t1, param);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseVideoOverlay::FireFrameUpdateEvent( tjs_int frame )\n{\n\t// fire onFrameUpdate event\n\t// this is always synchronized event.\n\t\n\tif(Owner)\n\t{\n\t\t// fire\n\t\tif(CanDeliverEvents)\n\t\t{\n\t\t\t// fire onPeriod event\n\t\t\ttTJSVariant param[1] = {frame};\n\t\t\tstatic ttstr eventname(TJS_W(\"onFrameUpdate\"));\n\t\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE,\n\t\t\t\t1, param);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_VideoOverlay : TJS VideoOverlay class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_VideoOverlay::ClassID = -1;\ntTJSNC_VideoOverlay::tTJSNC_VideoOverlay()  :\n\ttTJSNativeClass(TJS_W(\"VideoOverlay\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(VideoOverlay) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this,\n\t/*var.type*/tTJSNI_VideoOverlay,\n\t/*TJS class name*/VideoOverlay)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/VideoOverlay)\n//----------------------------------------------------------------------\n\n//-- methods\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/open)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t_this->Open(*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/open)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/play)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Play();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/play)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/stop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Stop();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/stop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/close)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Close();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/close)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPos) // not SetPosition\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetPosition(*param[0], *param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPos)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetSize(*param[0], *param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setBounds)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\ttTVPRect r;\n\tr.left = *param[0];\n\tr.top = *param[1];\n\tr.right = r.left + (tjs_int)*param[2];\n\tr.bottom = r.top + (tjs_int)*param[3];\n\t_this->SetBounds(r);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setBounds)\n//----------------------------------------------------------------------\n// Start: Add:\t2004/08/23\tT.Imoto\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/pause)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Pause();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/pause)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/rewind)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Rewind();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/rewind)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/prepare)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->Prepare();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/prepare)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSegmentLoop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetSegmentLoop(*param[0],*param[1]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSegmentLoop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/cancelSegmentLoop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->CancelSegmentLoop();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/cancelSegmentLoop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPeriodEvent)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif( numparams < 1 )\n\t\t_this->SetPeriodEvent( -1 );\n\telse if( numparams < 2 )\n\t\t_this->SetPeriodEvent( *param[0] );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPeriodEvent)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/cancelPeriodEvent)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->SetPeriodEvent( -1 );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/cancelPeriodEvent)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/selectAudioStream)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif( numparams < 1 ) return TJS_E_BADPARAMCOUNT;\n\n\t_this->SelectAudioStream( (tjs_uint)(tjs_int)*param[0] );\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/selectAudioStream)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMixingLayer)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\tif( numparams < 1 ) return TJS_E_BADPARAMCOUNT;\n\n\ttTJSNI_BaseLayer *src = NULL;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\tif(clo.Object)\n\t{\n\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\t_this->SetMixingLayer(src);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMixingLayer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/resetMixingLayer)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\t_this->ResetMixingBitmap();\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/resetMixingLayer)\n//----------------------------------------------------------------------\n// End: Add:\t2004/08/23\tT.Imoto\n//----------------------------------------------------------------------\n\n//-- events\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onStatusChanged\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"status\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onStatusChanged)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onCallbackCommand)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(2, \"onCallbackCommand\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"command\");\n\t\tTVP_ACTION_INVOKE_MEMBER(\"arg\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onCallbackCommand)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onPeriod)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onPeriod\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"reason\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onPeriod)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFrameUpdate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\n\t\t/*var. type*/tTJSNI_VideoOverlay);\n\n\ttTJSVariantClosure obj = _this->GetActionOwnerNoAddRef();\n\tif(obj.Object)\n\t{\n\t\tTVP_ACTION_INVOKE_BEGIN(1, \"onFrameUpdate\", objthis);\n\t\tTVP_ACTION_INVOKE_MEMBER(\"frame\");\n\t\tTVP_ACTION_INVOKE_END(obj);\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFrameUpdate)\n//----------------------------------------------------------------------\n\n//-- properties\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(position)\n{\n// Start: Add:\tT.Imoto\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = (tjs_int64)_this->GetTimePosition();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetTimePosition((tjs_int64)*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n// End: Add:\tT.Imoto\n}\nTJS_END_NATIVE_PROP_DECL(position)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(left)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetLeft();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetLeft(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(left)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(top)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetTop();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetTop(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(top)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetWidth();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetWidth(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetHeight();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetHeight(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(originalWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetOriginalWidth();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(originalWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(originalHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetOriginalHeight();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(originalHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetVisible();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetVisible(param->operator bool());\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(visible)\n//----------------------------------------------------------------------\n// Start: Add:\t\tT.Imoto\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(loop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetLoop();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetLoop(param->operator bool());\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(loop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(frame)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetFrame();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetFrame(*param);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(frame)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fps)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetFPS();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fps)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(numberOfFrame)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetNumberOfFrame();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(numberOfFrame)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(totalTime)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t*result = _this->GetTotalTime();\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(totalTime)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(layer1)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\ttTJSNI_BaseLayer *layer1 = _this->GetLayer1();\n\t\tif(layer1)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = layer1->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2 *) NULL);\n\t\t}\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\ttTJSNI_BaseLayer *src = NULL;\n\t\ttTJSVariantClosure clo = param->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t}\n\n\t\t_this->SetLayer1(src);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layer1)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(layer2)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\ttTJSNI_BaseLayer *layer2 = _this->GetLayer2();\n\t\tif(layer2)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = layer2->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2 *) NULL);\n\t\t}\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\ttTJSNI_BaseLayer *src = NULL;\n\t\ttTJSVariantClosure clo = param->AsObjectClosureNoAddRef();\n\t\tif(clo.Object)\n\t\t{\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\n\t\t\tif(!src) TVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t}\n\n\t\t_this->SetLayer2(src);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layer2)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetMode((tTVPVideoOverlayMode) (tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(playRate)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetPlayRate();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\n\t\t_this->SetPlayRate((tjs_real)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(playRate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(segmentLoopStartFrame)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetSegmentLoopStartFrame();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(segmentLoopStartFrame)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(segmentLoopEndFrame)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetSegmentLoopEndFrame();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(segmentLoopEndFrame)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(periodEventFrame)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetPeriodEventFrame();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetPeriodEvent((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(periodEventFrame)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(audioBalance)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetAudioBalance();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetAudioBalance((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(audioBalance)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(audioVolume)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetAudioVolume();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetAudioVolume((tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(audioVolume)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(numberOfAudioStream)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetNumberOfAudioStream();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(numberOfAudioStream)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enabledAudioStream)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetEnabledAudioStream();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SelectAudioStream( (tjs_uint)(tjs_int)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(enabledAudioStream)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(numberOfVideoStream)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetNumberOfVideoStream();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(numberOfVideoStream)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enabledVideoStream)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetEnabledVideoStream();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SelectVideoStream( (tjs_uint)(tjs_int)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(enabledVideoStream)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mixingMovieAlpha)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetMixingMovieAlpha();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetMixingMovieAlpha( (tjs_real)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mixingMovieAlpha)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mixingMovieBGColor)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_int)_this->GetMixingMovieBGColor();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetMixingMovieBGColor( (tjs_uint)(tjs_int)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mixingMovieBGColor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(contrastRangeMin)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetContrastRangeMin();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(contrastRangeMin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(contrastRangeMax)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetContrastRangeMax();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(contrastRangeMax)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(contrastDefaultValue)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetContrastDefaultValue();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(contrastDefaultValue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(contrastStepSize)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetContrastStepSize();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(contrastStepSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(contrast)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetContrast();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetContrast( (tjs_real)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(contrast)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(brightnessRangeMin)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetBrightnessRangeMin();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(brightnessRangeMin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(brightnessRangeMax)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetBrightnessRangeMax();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(brightnessRangeMax)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(brightnessDefaultValue)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetBrightnessDefaultValue();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(brightnessDefaultValue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(brightnessStepSize)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetBrightnessStepSize();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(brightnessStepSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(brightness)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetBrightness();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetBrightness( (tjs_real)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(brightness)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hueRangeMin)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetHueRangeMin();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hueRangeMin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hueRangeMax)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetHueRangeMax();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hueRangeMax)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hueDefaultValue)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetHueDefaultValue();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hueDefaultValue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hueStepSize)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetHueStepSize();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hueStepSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hue)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetHue();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetHue( (tjs_real)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(hue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(saturationRangeMin)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetSaturationRangeMin();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(saturationRangeMin)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(saturationRangeMax)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetSaturationRangeMax();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(saturationRangeMax)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(saturationDefaultValue)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetSaturationDefaultValue();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(saturationDefaultValue)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(saturationStepSize)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetSaturationStepSize();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(saturationStepSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(saturation)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t*result = (tjs_real)_this->GetSaturation();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_VideoOverlay);\n\t\t_this->SetSaturation( (tjs_real)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(saturation)\n//----------------------------------------------------------------------\n// End: Add:\tT.Imoto\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n//----------------------------------------------------------------------\n\n\n}\n\n"
  },
  {
    "path": "src/core/visual/VideoOvlIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Video Overlay support interface\n//---------------------------------------------------------------------------\n#ifndef VideoOvlIntfH\n#define VideoOvlIntfH\n\n#include \"tjsNative.h\"\n#include \"SoundBufferBaseIntf.h\"\n#include \"voMode.h\"\n#include <functional>\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTVPPeriodEventType : event type in onPeriod event\n//---------------------------------------------------------------------------\nenum tTVPPeriodEventReason\n{\n\tperLoop, // the event is by loop rewind\n\tperPeriod, // the event is by period point specified by the user\n\tperPrepare, // the event is by prepare() method\n\tperSegLoop, // the event is by segment loop rewind\n};\n\n\n\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseVideoOverlay\n//---------------------------------------------------------------------------\nclass tTJSNI_Window;\nclass tTJSNI_BaseVideoOverlay : public tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\npublic:\n\ttTJSNI_BaseVideoOverlay();\n\ttjs_error TJS_INTF_METHOD\n\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprotected:\n\tiTJSDispatch2 *Owner;\n\tbool CanDeliverEvents;\n\ttTJSNI_Window * Window;\n\tTJS::tTJSVariantClosure ActionOwner;\n\ttTVPSoundStatus Status; // status\n\n\tttstr GetStatusString() const;\n\tvoid SetStatus(tTVPSoundStatus s);\n\tvoid SetStatusAsync(tTVPSoundStatus s);\n\tvoid FireCallbackCommand(const ttstr & command, const ttstr & argument);\n\tvoid FirePeriodEvent(tTVPPeriodEventReason reason);\n\tvoid FireFrameUpdateEvent( tjs_int frame );\n\n\npublic:\n\tvirtual void Disconnect() = 0; // called from Window object's invalidation\n\tvirtual bool GetVisible() const = 0;\n\tvirtual const tTVPRect &GetBounds() const = 0;\n\tvirtual tTVPVideoOverlayMode GetMode() const = 0;\n\tvirtual bool GetVideoSize(tjs_int &w, tjs_int &h) const = 0;\n\n\ttTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; }\n};\n//---------------------------------------------------------------------------\n\n#include \"VideoOvlImpl.h\" // must define tTJSNI_VideoOverlay class\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_VideoOverlay : TJS VideoOverlay class\n//---------------------------------------------------------------------------\nclass tTJSNC_VideoOverlay : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_VideoOverlay();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_VideoOverlay();\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/WindowIntf.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Window\" TJS Class implementation\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"MsgIntf.h\"\n#include \"WindowIntf.h\"\n#include \"LayerIntf.h\"\n#include \"DebugIntf.h\"\n#include \"EventIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"VideoOvlIntf.h\"\n#include \"LayerManager.h\"\n#include \"BasicDrawDevice.h\"\n#include \"EventImpl.h\"\n\n#include \"Application.h\"\n\n//---------------------------------------------------------------------------\n// Window List\n//---------------------------------------------------------------------------\ntTJSNI_Window * TVPMainWindow = NULL; // main window\nstatic std::vector<tTJSNI_Window*> TVPWindowVector;\n//---------------------------------------------------------------------------\nstatic void TVPRegisterWindowToList(tTJSNI_Window *window)\n{\n\tif(TVPMainWindow == NULL && TVPWindowVector.size() == 0)\n\t{\n\t\t// first time the window is registered\n\t\tTVPMainWindow = window; // set as main window\n\t}\n\tTVPWindowVector.push_back(window);\n\n\t// notify that the layer must lost capture state\n\tstd::vector<tTJSNI_Window*>::iterator i;\n\tfor(i = TVPWindowVector.begin(); i!=TVPWindowVector.end(); i++)\n\t{\n\t\t(*i)->PostReleaseCaptureEvent();\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPUnregisterWindowToList(tTJSNI_Window *window)\n{\n\tstd::vector<tTJSNI_Window*>::iterator i;\n\ti = std::find(TVPWindowVector.begin(), TVPWindowVector.end(), window);\n\tif(i != TVPWindowVector.end())\n\t{\n\t\tbool flag = false;\n\t\tif(*i == TVPMainWindow) flag = true;\n\n\t\tTVPWindowVector.erase(i);\n\n\t\tif(flag)\n\t\t{\n\t\t\tTVPMainWindowClosed(); // MainWindow had been closed\n\t\t\tTVPMainWindow = NULL;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTJSNI_Window * TVPGetWindowListAt(tjs_int idx) { return TVPWindowVector[idx]; }\n//---------------------------------------------------------------------------\ntjs_int TVPGetWindowCount() { return (tjs_int)TVPWindowVector.size(); }\n//---------------------------------------------------------------------------\nvoid TVPClearAllWindowInputEvents()\n{\n\tstd::vector<tTJSNI_Window*>::iterator i;\n\tfor(i = TVPWindowVector.begin(); i!=TVPWindowVector.end(); i++)\n\t{\n\t\t(*i)->ClearInputEvents();\n\t}\n}\n//---------------------------------------------------------------------------\n\n#if 0\n//---------------------------------------------------------------------------\nbool TVPIsWaitVSync()\n{\n\tbool result = false;\n\tstd::vector<tTJSNI_Window*>::iterator i;\n\tfor(i = TVPWindowVector.begin(); i!=TVPWindowVector.end(); i++)\n\t{\n\t\tresult |= (*i)->GetWaitVSync();\n\t}\n\treturn result;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// Input Events\n//---------------------------------------------------------------------------\n// For each input event tag\ntTVPUniqueTagForInputEvent tTVPOnCloseInputEvent              ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnResizeInputEvent             ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnClickInputEvent              ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnDoubleClickInputEvent        ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseDownInputEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseUpInputEvent            ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseMoveInputEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnReleaseCaptureInputEvent     ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseOutOfWindowInputEvent   ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseEnterInputEvent         ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseLeaveInputEvent         ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnKeyDownInputEvent            ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnKeyUpInputEvent              ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnKeyPressInputEvent           ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnFileDropInputEvent           ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMouseWheelInputEvent         ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnPopupHideInputEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnWindowActivateEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnTouchDownInputEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnTouchUpInputEvent            ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnTouchMoveInputEvent          ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnTouchScalingInputEvent       ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnTouchRotateInputEvent        ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnMultiTouchInputEvent         ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnHintChangeInputEvent         ::Tag;\ntTVPUniqueTagForInputEvent tTVPOnDisplayRotateInputEvent      ::Tag;\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseWindow\n//---------------------------------------------------------------------------\ntTJSNI_BaseWindow::tTJSNI_BaseWindow()\n{\n\tWaitVSync = false;\n\tObjectVectorLocked = false;\n\tDrawBuffer = NULL;\n\tWindowExposedRegion.clear();\n\tWindowUpdating = false;\n\tDrawDevice = NULL;\n}\n//---------------------------------------------------------------------------\ntTJSNI_BaseWindow::~tTJSNI_BaseWindow()\n{\n\tTVPUnregisterWindowToList(static_cast<tTJSNI_Window*>(this));  // making sure...\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_BaseWindow::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\tOwner = tjs_obj; // no addref\n\tTVPRegisterWindowToList(static_cast<tTJSNI_Window*>(this));\n\n\t// set default draw device object \"PassThrough\"\n\t{\n\t\tiTJSDispatch2 * cls = NULL;\n\t\tiTJSDispatch2 * newobj = NULL;\n\t\ttry\n\t\t{\n\t\t\tcls = new tTJSNC_BasicDrawDevice();\n\t\t\tif(TJS_FAILED(cls->CreateNew(0, NULL, NULL, &newobj, 0, NULL, cls)))\n\t\t\t\tTVPThrowExceptionMessage(TVPInternalError,\n\t\t\t\t\tTJS_W(\"tTJSNI_Window::Construct\"));\n\t\t\tSetDrawDeviceObject(tTJSVariant(newobj, newobj));\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(cls) cls->Release();\n\t\t\tif(newobj) newobj->Release();\n\t\t\tthrow;\n\t\t}\n\t\tif(cls) cls->Release();\n\t\tif(newobj) newobj->Release();\n\t}\n\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_BaseWindow::Invalidate()\n{\n\t// remove from list\n\tTVPUnregisterWindowToList(static_cast<tTJSNI_Window*>(this));\n\n\t// remove all events\n\tTVPCancelSourceEvents(Owner);\n\tTVPCancelInputEvents(this);\n\n\t// clear all window update events\n\tTVPRemoveWindowUpdate((tTJSNI_Window*)this);\n\n\t// sever the primarylayer\n//\tif(LayerManager) LayerManager->DetachPrimary();\n\n\t// free DrawBuffer\n\tif(DrawBuffer) delete DrawBuffer;\n\n\t// disconnect all VideoOverlay objects\n\t{\n\t\ttObjectListSafeLockHolder<tTJSNI_BaseVideoOverlay> holder(VideoOverlay);\n\t\ttjs_int count = VideoOverlay.GetSafeLockedObjectCount();\n\t\tfor(tjs_int i = 0; i < count; i++)\n\t\t{\n\t\t\ttTJSNI_BaseVideoOverlay * item = VideoOverlay.GetSafeLockedObjectAt(i);\n\t\t\tif(!item) continue;\n\t\t\t\n\t\t\titem->Disconnect();\n\t\t}\n\t}\n\n\t// invalidate all registered objects\n\tObjectVectorLocked = true;\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\n\tfor(i = ObjectVector.begin(); i != ObjectVector.end(); i++)\n\t{\n\t\t// invalidate each --\n\t\t// objects may throw an exception while invalidating,\n\t\t// but here we cannot care for them.\n\t\ttry\n\t\t{\n\t\t\ti->Invalidate(0, NULL, NULL, NULL);\n\t\t\ti->Release();\n\t\t}\n\t\tcatch(eTJSError &e)\n\t\t{\n\t\t\tTVPAddLog(e.GetMessage()); // just in case, log the error\n\t\t}\n\t}\n\n\t// remove all events (again)\n\tTVPCancelSourceEvents(Owner);\n\tTVPCancelInputEvents(this);\n\n\t// notify that the window is no longer available\n//\tif(LayerManager) LayerManager->SetWindow(NULL);\n\n\t// clear all window update events (again)\n\tTVPRemoveWindowUpdate((tTJSNI_Window*)this);\n\n\t// release draw device\n\tSetDrawDeviceObject(tTJSVariant());\n\n\n\tinherited::Invalidate();\n\n\t/* NOTE: at this point, Owner is still non-null.\n\t   Caller must ensure that the Owner being null at the end of the\n\t   invalidate chain. */\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseWindow::IsMainWindow() const\n{\n\treturn TVPMainWindow == static_cast<const tTJSNI_Window*>(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::FireOnActivate(bool activate_or_deactivate)\n{\n\t// fire Window.onActivate or Window.onDeactivate event\n\tTVPPostInputEvent(\n\t\tnew tTVPOnWindowActivateEvent(this, activate_or_deactivate),\n\t\tTVP_EPT_REMOVE_POST // to discard redundant events\n\t\t);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::SetDrawDeviceObject(const tTJSVariant & val)\n{\n\t// invalidate existing draw device\n\tif(DrawDeviceObject.Type() == tvtObject)\n\t\tDrawDeviceObject.AsObjectClosureNoAddRef().Invalidate(0, NULL, NULL, DrawDeviceObject.AsObjectNoAddRef());\n\n\t// assign new device\n\tDrawDeviceObject = val;\n\tDrawDevice = NULL;\n\n\t// extract interface\n\tif(DrawDeviceObject.Type() == tvtObject)\n\t{\n\t\ttTJSVariantClosure clo = DrawDeviceObject.AsObjectClosureNoAddRef();\n\t\ttTJSVariant iface_v;\n\t\tif(TJS_FAILED(clo.PropGet(0, TJS_W(\"interface\"), NULL, &iface_v, NULL)))\n\t\t\tTVPThrowExceptionMessage( TVPCannotRetriveInterfaceFromDrawDevice );\n\t\tDrawDevice =\n\t\t\treinterpret_cast<iTVPDrawDevice *>((tjs_intptr_t)(tjs_int64)iface_v);\n\t\tDrawDevice->SetWindowInterface(const_cast<tTJSNI_BaseWindow*>(this));\n\t\tResetDrawDevice();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnClose()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[1] = {true};\n\t\tstatic ttstr eventname(TJS_W(\"onCloseQuery\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnResize()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onResize\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnClick(tjs_int x, tjs_int y)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[2] = { x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onClick\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnClick(x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnDoubleClick(tjs_int x, tjs_int y)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[2] = { x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onDoubleClick\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnDoubleClick(x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[4] = { x, y, (tjs_int64)mb, (tjs_int64)flags };\n\t\tstatic ttstr eventname(TJS_W(\"onMouseDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnMouseDown(x, y, mb, flags);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb,\n\ttjs_uint32 flags)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[4] = { x, y, (tjs_int)mb, (tjs_int)flags };\n\t\tstatic ttstr eventname(TJS_W(\"onMouseUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnMouseUp(x, y, mb, flags);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMouseMove\"));\n\t\t\ttTJSVariant arg[3] = { x, y, (tjs_int64)flags };\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_DISCARDABLE|TVP_EPT_IMMEDIATE\n\t\t\t/*discardable!!*/,\n\t\t\t3, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnMouseMove(x, y, flags);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnTouchDown(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnTouchUp(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[5] = { x, y, cx, cy, (tjs_int64)id };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchMove\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnTouchMove(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[5] = { startdist, curdist, cx, cy, flag };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchScaling\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnTouchScaling(startdist, curdist, cx, cy, flag);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[6] = { startangle, curangle, dist, cx, cy, flag };\n\t\tstatic ttstr eventname(TJS_W(\"onTouchRotate\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 6, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnTouchRotate(startangle, curangle, dist, cx, cy, flag);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMultiTouch() {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMultiTouch\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n\tif(DrawDevice) DrawDevice->OnMultiTouch();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnReleaseCapture()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(DrawDevice) DrawDevice->OnReleaseCapture();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseOutOfWindow()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(DrawDevice) DrawDevice->OnMouseOutOfWindow();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseEnter()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMouseEnter\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseLeave()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onMouseLeave\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnKeyDown(tjs_uint key, tjs_uint32 shift)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[2] = { (tjs_int)key, (tjs_int)shift };\n\t\tstatic ttstr eventname(TJS_W(\"onKeyDown\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnKeyDown(key, shift);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnKeyUp(tjs_uint key, tjs_uint32 shift)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[2] = { (tjs_int)key, (tjs_int)shift };\n\t\tstatic ttstr eventname(TJS_W(\"onKeyUp\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 2, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnKeyUp(key, shift);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnKeyPress(tjs_char key)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttjs_char buf[2];\n\t\tbuf[0] = (tjs_char)key;\n\t\tbuf[1] = 0;\n\t\ttTJSVariant arg[1] = { buf };\n\t\tstatic ttstr eventname(TJS_W(\"onKeyPress\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnKeyPress(key);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnFileDrop(const tTJSVariant &array)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[1] = { array };\n\t\tstatic ttstr eventname(TJS_W(\"onFileDrop\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnMouseWheel(tjs_uint32 shift, tjs_int delta,\n\ttjs_int x, tjs_int y)\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[4] = { (tjs_int)shift, delta, x, y };\n\t\tstatic ttstr eventname(TJS_W(\"onMouseWheel\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnMouseWheel(shift, delta, x, y);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnPopupHide()\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\tstatic ttstr eventname(TJS_W(\"onPopupHide\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnActivate(bool activate_or_deactivate)\n{\n\tif(!CanDeliverEvents()) return;\n\n\t// re-check the window activate state\n\tif(GetWindowActive() == activate_or_deactivate)\n\t{\n\t\tif(Owner)\n\t\t{\n\t\t\tstatic ttstr a_eventname(TJS_W(\"onActivate\"));\n\t\t\tstatic ttstr d_eventname(TJS_W(\"onDeactivate\"));\n\t\t\tTVPPostEvent(Owner, Owner, activate_or_deactivate?a_eventname:d_eventname,\n\t\t\t\t0, TVP_EPT_IMMEDIATE, 0, NULL);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnHintChange( const ttstr& text, tjs_int x, tjs_int y, bool isshow )\n{\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[6] = { text, x, y, isshow ? 1 : 0 };\n\t\tstatic ttstr eventname(TJS_W(\"onHintChanged\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 4, arg);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::OnDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int hresolution, tjs_int vresolution ) {\n\tif(!CanDeliverEvents()) return;\n\tif(Owner)\n\t{\n\t\ttTJSVariant arg[5] = { orientation, rotate, bpp, hresolution, vresolution };\n\t\tstatic ttstr eventname(TJS_W(\"onDisplayRotate\"));\n\t\tTVPPostEvent(Owner, Owner, eventname, 0, TVP_EPT_IMMEDIATE, 5, arg);\n\t}\n\tif(DrawDevice) DrawDevice->OnDisplayRotate(orientation, rotate, bpp, hresolution, vresolution);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::ClearInputEvents()\n{\n\tTVPCancelInputEvents(this);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::PostReleaseCaptureEvent()\n{\n\tTVPPostInputEvent(\n\t\tnew tTVPOnReleaseCaptureInputEvent(this));\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseWindow::RegisterLayerManager(iTVPLayerManager * manager)\n{\n\tif( DrawDevice ) DrawDevice->AddLayerManager(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseWindow::UnregisterLayerManager(iTVPLayerManager * manager)\n{\n\tif( DrawDevice ) DrawDevice->RemoveLayerManager(manager);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::NotifyWindowExposureToLayer(const tTVPRect &cliprect)\n{\n\tif( DrawDevice ) DrawDevice->RequestInvalidation(cliprect);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::NotifyUpdateRegionFixed(const tTVPComplexRect &updaterects)\n{\n\t// is called by layer manager\n\tBeginUpdate(updaterects);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::UpdateContent()\n{\n\tif( DrawDevice ) {\n\t\t// is called from event dispatcher\n\t\tDrawDevice->Update();\n\n\t\tif( !WaitVSync ) DrawDevice->Show();\n\n \t\tEndUpdate();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::DeliverDrawDeviceShow()\n{\n\t// call DrawDevice->Show, at VBlank\n\tif( DrawDevice ) DrawDevice->Show();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::BeginUpdate(const tTVPComplexRect & rects)\n{\n\tWindowUpdating = true;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::EndUpdate()\n{\n\tWindowUpdating = false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::DumpPrimaryLayerStructure()\n{\n\tif( DrawDevice ) DrawDevice->DumpLayerStructure();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::RecheckInputState()\n{\n\t// slow timer tick (about 1 sec interval, inaccurate)\n\tif( DrawDevice ) DrawDevice->RecheckInputState();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::SetShowUpdateRect(bool b)\n{\n\t// show update rectangle if possible\n\tif( DrawDevice ) DrawDevice->SetShowUpdateRect(b);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseWindow::RequestUpdate()\n{\n\t// is called from primary layer\n\n\t// post update event to self\n\tTVPPostWindowUpdate((tTJSNI_Window*)this);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BaseWindow::NotifySrcResize()\n{\n\t// is called from primary layer\n\tif(WindowUpdating)\n\t\tTVPThrowExceptionMessage(TVPInvalidMethodInUpdating);\n}\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::RegisterVideoOverlayObject(tTJSNI_BaseVideoOverlay * ovl)\n{\n\tVideoOverlay.Add(ovl);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::UnregisterVideoOverlayObject(tTJSNI_BaseVideoOverlay * ovl)\n{\n\tVideoOverlay.Remove(ovl);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---- methods\n\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::Add(tTJSVariantClosure clo)\n{\n\tif(ObjectVectorLocked) return;\n\tif(ObjectVector.end() == std::find(ObjectVector.begin(), ObjectVector.end(), clo))\n\t{\n\t\tObjectVector.push_back(clo);\n\t\tclo.AddRef();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::Remove(tTJSVariantClosure clo)\n{\n\tif(ObjectVectorLocked) return;\n\tstd::vector<tTJSVariantClosure>::iterator i;\n\ti = std::find(ObjectVector.begin(), ObjectVector.end(), clo);\n\tif(i != ObjectVector.end())\n\t{\n\t\tclo.Release();\n\t\tObjectVector.erase(i);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_BaseWindow::SetWaitVSync( bool enable )\n{\n\tWaitVSync = enable;\n\tUpdateVSyncThread();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_BaseWindow::GetWaitVSync() const\n{\n\treturn WaitVSync;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Window : TJS Window class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_Window::ClassID = -1;\ntTJSNC_Window::tTJSNC_Window() : tTJSNativeClass(TJS_W(\"Window\"))\n{\n\t// registration of native members\n\n\tTJS_BEGIN_NATIVE_MEMBERS(Window) // constructor\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_Window,\n\t/*TJS class name*/Window)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Window)\n//----------------------------------------------------------------------\n\n\n\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/close)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->Close();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/close)\n//----------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/beginMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->BeginMove();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/beginMove)\n#endif\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/bringToFront)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->BringToFront();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/bringToFront)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/update)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\ttTVPUpdateType type = utNormal;\n\tif(numparams >= 2 && param[1]->Type() != tvtVoid)\n\t\ttype = (tTVPUpdateType)(tjs_int)*param[0];\n\t_this->Update(type);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/update)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/showModal)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->ShowModal();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/showModal)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMaskRegion)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\ttjs_int threshold = 1;\n\tif(numparams >= 1 && param[0]->Type() != tvtVoid)\n\t\tthreshold = (tjs_int)*param[0];\n\t_this->SetMaskRegion(threshold);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMaskRegion)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeMaskRegion)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->RemoveMaskRegion();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/removeMaskRegion)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/add)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t_this->Add(clo);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/add)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/remove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t_this->Remove(clo);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/remove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetSize(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMinSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetMinSize(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMinSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setMaxSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetMaxSize(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setMaxSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setPos) // not setPosition\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetPosition(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setPos)\n//----------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setLayerPos) // not setLayerPosition\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetLayerPosition(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setLayerPos)\n#endif\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setInnerSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetInnerSize(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setInnerSize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setZoom)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->SetZoom(*param[0], *param[1]);\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/setZoom)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/hideMouseCursor)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->HideMouseCursor();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/hideMouseCursor)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/postInputEvent)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tif(numparams < 1)  return TJS_E_BADPARAMCOUNT;\n\tttstr eventname;\n\tiTJSDispatch2 * eventparams = NULL;\n\n\teventname = *param[0];\n\tif(numparams >= 2) eventparams = param[1]->AsObjectNoAddRef();\n\n\t_this->PostInputEvent(eventname, eventparams);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/postInputEvent)\n//----------------------------------------------------------------------\n\n\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onResize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onResize\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onResize)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseEnter)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onMouseEnter\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseEnter)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseLeave)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onMouseLeave\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseLeave)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(2, \"onClick\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onDoubleClick)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(2, \"onDoubleClick\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onDoubleClick)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseDown\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"button\");\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseUp\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"button\");\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(3, \"onMouseMove\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMouseWheel)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(4, \"onMouseWheel\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_MEMBER(\"delta\");\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMouseWheel)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchDown\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchUp\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchMove)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchMove\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"x\");\n\tTVP_ACTION_INVOKE_MEMBER(\"y\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\tTVP_ACTION_INVOKE_MEMBER(\"id\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchMove)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchScaling)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(5, \"onTouchScaling\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"startdistance\");\n\tTVP_ACTION_INVOKE_MEMBER(\"currentdistance\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\tTVP_ACTION_INVOKE_MEMBER(\"flag\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchScaling)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onTouchRotate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(6, \"onTouchRotate\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"startangle\");\n\tTVP_ACTION_INVOKE_MEMBER(\"currentangle\");\n\tTVP_ACTION_INVOKE_MEMBER(\"distance\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cx\");\n\tTVP_ACTION_INVOKE_MEMBER(\"cy\");\n\tTVP_ACTION_INVOKE_MEMBER(\"flag\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onTouchRotate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onMultiTouch)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onMultiTouch\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onMultiTouch)\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyDown)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(2, \"onKeyDown\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyDown)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyUp)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(2, \"onKeyUp\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\tTVP_ACTION_INVOKE_MEMBER(\"shift\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyUp)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onKeyPress)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(1, \"onKeyPress\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"key\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onKeyPress)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFileDrop)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(1, \"onFileDrop\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"files\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onFileDrop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onCloseQuery)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n/*\n\t// this event does not call \"action\" method\n\tTVP_ACTION_INVOKE_BEGIN(1, \"onCloseQuery\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"canClose\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n*/\n\t_this->OnCloseQueryCalled( 0 != (tjs_int)*param[0]);\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onCloseQuery)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onPopupHide)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onPopupHide\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onPopupHide)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onActivate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onActivate\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onActivate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onDeactivate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(0, \"onDeactivate\", objthis);\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onDeactivate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onDisplayRotate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\tTVP_ACTION_INVOKE_BEGIN(5, \"onDisplayRotate\", objthis);\n\tTVP_ACTION_INVOKE_MEMBER(\"orientation\");\n\tTVP_ACTION_INVOKE_MEMBER(\"angle\");\n\tTVP_ACTION_INVOKE_MEMBER(\"bpp\");\n\tTVP_ACTION_INVOKE_MEMBER(\"width\");\n\tTVP_ACTION_INVOKE_MEMBER(\"height\");\n\tTVP_ACTION_INVOKE_END(tTJSVariantClosure(objthis, objthis));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/onDisplayRotate)\n//----------------------------------------------------------------------\n\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(visible)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetVisible();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetVisible(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(visible)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(caption)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\tttstr res;\n\t\t_this->GetCaption(res);\n\t\t*result = res;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetCaption(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(caption)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(width)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetWidth(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(width)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(height)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetHeight(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(height)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(minWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetMinWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetMinWidth(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(minWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(minHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetMinHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetMinHeight(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(minHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(maxWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetMaxWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetMaxWidth(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(maxWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(maxHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetMaxHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetMaxHeight(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(maxHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(left)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetLeft(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(left)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(top)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetTop(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(top)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(focusable)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = (tjs_int) _this->GetFocusable();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetFocusable( 0 != (tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(focusable)\n//----------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nTJS_BEGIN_NATIVE_PROP_DECL(layerLeft)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetLayerLeft();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetLayerLeft(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layerLeft)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(layerTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetLayerTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetLayerTop(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layerTop)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(innerSunken)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetInnerSunken();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetInnerSunken(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(innerSunken)\n#endif\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(innerWidth)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetInnerWidth();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetInnerWidth(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(innerWidth)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(innerHeight)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetInnerHeight();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetInnerHeight(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(innerHeight)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(zoomNumer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetZoomNumer();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetZoomNumer(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(zoomNumer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(zoomDenom)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetZoomDenom();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetZoomDenom(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(zoomDenom)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(borderStyle)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = (tjs_int)_this->GetBorderStyle();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetBorderStyle((tTVPBorderStyle)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(borderStyle)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(stayOnTop)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetStayOnTop();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetStayOnTop(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(stayOnTop)\n//----------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nTJS_BEGIN_NATIVE_PROP_DECL(showScrollBars)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetShowScrollBars();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetShowScrollBars(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(showScrollBars)\n#endif\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(useMouseKey)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetUseMouseKey();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetUseMouseKey(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(useMouseKey)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(trapKey)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetTrapKey();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetTrapKey(param->operator bool());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(trapKey)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(imeMode) // not defaultImeMode\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = (tjs_int)_this->GetDefaultImeMode();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetDefaultImeMode((tTVPImeMode)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(imeMode)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mouseCursorState)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = (tjs_int)_this->GetMouseCursorState();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetMouseCursorState((tTVPMouseCursorState)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mouseCursorState)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(fullScreen)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetFullScreen();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetFullScreen( 0 != (tjs_int)*param );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(fullScreen)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(mainWindow) /* static */\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tif(TVPMainWindow)\n\t\t{\n\t\t\tiTJSDispatch2 *dsp = TVPMainWindow->GetOwnerNoAddRef();\n\t\t\t*result = tTJSVariant(dsp, dsp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(mainWindow)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(focusedLayer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\ttTJSNI_BaseLayer *lay = _this->GetDrawDevice()->GetFocusedLayer();\n\t\tif(lay && lay->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(lay->GetOwnerNoAddRef(), lay->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\n\t\ttTJSNI_BaseLayer *to = NULL;\n\n\t\tif(param->Type() != tvtVoid)\n\t\t{\n\t\t\ttTJSVariantClosure clo = param->AsObjectClosureNoAddRef();\n\t\t\tif(clo.Object)\n\t\t\t{\n\t\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&to)))\n\t\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t\t\t}\n\t\t}\n\n\t\t_this->GetDrawDevice()->SetFocusedLayer(to);\n\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(focusedLayer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(primaryLayer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\ttTJSNI_BaseLayer *pri = _this->GetDrawDevice()->GetPrimaryLayer();\n\t\tif(!pri) TVPThrowExceptionMessage(TVPWindowHasNoLayer);\n\n\t\tif(pri && pri->GetOwnerNoAddRef())\n\t\t\t*result = tTJSVariant(pri->GetOwnerNoAddRef(), pri->GetOwnerNoAddRef());\n\t\telse\n\t\t\t*result = tTJSVariant((iTJSDispatch2*)NULL);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(primaryLayer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(waitVSync)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetWaitVSync() ? 1 : 0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetWaitVSync( ((tjs_int)*param) ? true : false );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(waitVSync)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(layerTreeOwnerInterface)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = reinterpret_cast<tjs_int64>(static_cast<iTVPLayerTreeOwner*>(_this));\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(layerTreeOwnerInterface)\n//----------------------------------------------------------------------\n\n\tTJS_END_NATIVE_MEMBERS\n\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/WindowIntf.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Window\" TJS Class implementation\n//---------------------------------------------------------------------------\n#ifndef WindowIntfH\n#define WindowIntfH\n\n#include \"tjsNative.h\"\n#include \"drawable.h\"\n#include \"ComplexRect.h\"\n#include \"tvpinputdefs.h\"\n#include \"EventIntf.h\"\n#include \"ObjectList.h\"\n#include \"DrawDevice.h\"\n#include \"LayerTreeOwner.h\"\n\n#define USE_OBSOLETE_FUNCTIONS\n\n//---------------------------------------------------------------------------\n// Window List Management\n//---------------------------------------------------------------------------\nextern void TVPClearAllWindowInputEvents();\n//extern bool TVPIsWaitVSync();\n//---------------------------------------------------------------------------\n\n\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// Window related constants\n//---------------------------------------------------------------------------\nenum tTVPUpdateType\n{\n\tutNormal, // only needed region\n\tutEntire // entire of window\n};\n//---------------------------------------------------------------------------\nenum tTVPBorderStyle\n{\n\tbsNone=0,  bsSingle=1,  bsSizeable=2,  bsDialog=3,  bsToolWindow=4,\n\tbsSizeToolWin =5\n};\n//---------------------------------------------------------------------------\nenum tTVPMouseCursorState\n{\n\tmcsVisible, // the mouse cursor is visible\n\tmcsTempHidden, // the mouse cursor is temporarily hidden\n\tmcsHidden // the mouse cursor is invisible\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n/*[*/\n//---------------------------------------------------------------------------\n//! @brief Window basic interface\n//---------------------------------------------------------------------------\nclass iWindowLayer;\nclass iTVPWindow\n{\npublic:\n\t//! @brief\t摜̃TCYύXꂽ\n\t//! @note\t`foCXA摜̃TCYύXꂽƂʒm邽߂ɌĂԁB\n\t//!\t\t\tEBhE iTVPDrawDevice::GetSrcSize() ĂяoČ摜\n\t//!\t\t\tTCY擾AY[Ȃǂ̌vZsĂ \n\t//!\t\t\tiTVPDrawDevice::SetTargetWindow() ĂяoB\n\tvirtual void TJS_INTF_METHOD NotifySrcResize() = 0;\n\n\t//! @brief\t\t}EXJ[\\̌`ftHgɖ߂\n\t//! @note\t\t}EXJ[\\̌`ftHg̕ɖ߂ꍇɌĂ\n\tvirtual void TJS_INTF_METHOD SetDefaultMouseCursor() = 0; // set window mouse cursor to default\n\n\t//! @brief\t\t}EXJ[\\̌`ݒ肷\n\t//! @param\t\tcursor\t\t}EXJ[\\`ԍ\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(tjs_int cursor) = 0; // set window mouse cursor\n\n\t//! @brief\t\t}EXJ[\\̈ʒu擾\n\t//! @param\t\tx\t\t\t``̍Wɂ}EXJ[\\xʒu\n\t//! @param\t\ty\t\t\t``̍Wɂ}EXJ[\\yʒu\n\tvirtual void TJS_INTF_METHOD GetCursorPos(tjs_int &x, tjs_int &y) = 0;\n\t\t// get mouse cursor position in primary layer's coordinates\n\n\t//! @brief\t\t}EXJ[\\̈ʒuݒ肷\n\t//! @param\t\tx\t\t\t``̍Wɂ}EXJ[\\xʒu\n\t//! @param\t\ty\t\t\t``̍Wɂ}EXJ[\\yʒu\n\tvirtual void TJS_INTF_METHOD SetCursorPos(tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\tEBhẼ}EXLv`\n\t//! @note\t\tEBhẼ}EXLv`ׂꍇɌĂԁB\n\t//! @note\t\t̃\\bhł͊{Iɂ ::ReleaseCapture() Ȃǂ\n\t//!\t\t\t\t}EX̃Lv`J邱ƁB\n\tvirtual void TJS_INTF_METHOD WindowReleaseCapture() = 0;\n\n\t//! @brief\t\tc[`bvqgݒ肷\n\t//! @param\t\ttext\t\tqgeLXg(󕶎̏ꍇ̓qg̕\\LZ)\n\tvirtual void TJS_INTF_METHOD SetHintText(iTJSDispatch2* sender, const ttstr & text) = 0;\n\n\t//! @brief\t\t|Cg̐ݒ\n\t//! @param\t\tlayer\t\ttHg̊܂܂郌C\n\t//! @param\t\tx\t\t\t``̍Wɂ钍|Cgxʒu\n\t//! @param\t\ty\t\t\t``̍Wɂ钍|Cgyʒu\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(tTJSNI_BaseLayer *layer,\n\t\ttjs_int l, tjs_int t) = 0;\n\n\t//! @brief\t\t|Cg̉\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint() = 0;\n\n\t//! @brief\t\tIME[h̐ݒ\n\t//! @param\t\tmode\t\tIME[h\n\tvirtual void TJS_INTF_METHOD SetImeMode(tTVPImeMode mode) = 0;\n\n\t//! @brief\t\tIME[h̃Zbg\n\tvirtual void TJS_INTF_METHOD ResetImeMode() = 0;\n\n\t//! @brief\t\tiTVPWindow::Update() ̌Ăяov\n\t//! @note\t\tEBhEɑ΂ iTVPWindow::Update() ̓Kȃ^C~O\n\t//!\t\t\t\tĂяoƂvB\n\t//!\t\t\t\tiTVPWindow::Update() Ăяo܂ł͉ RequestUpdate() \n\t//!\t\t\t\tĂłʂ͓łB܂Ax iTVPWindow::Update() \n\t//!\t\t\t\tĂяoƁAĂ RequestUpdate() Ă΂Ȃ\n\t//!\t\t\t\tiTVPWindow::Update() ͌Ă΂ȂB\n\tvirtual void TJS_INTF_METHOD RequestUpdate() = 0;\n\n\n\t//! @brief\t\tWindowiTJSDispatch2C^[tF[X擾\n\tvirtual iTJSDispatch2 * GetWindowDispatch() = 0;\n\n\t// add by ZeaS\n\tvirtual iWindowLayer* GetForm() const = 0;\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BaseWindow\n//---------------------------------------------------------------------------\nclass tTVPBaseBitmap;\nclass tTJSNI_BaseLayer;\nclass tTJSNI_BaseVideoOverlay;\nclass tTJSNI_BaseWindow : public tTJSNativeInstance, public iTVPWindow, public iTVPLayerTreeOwner\n{\n\ttypedef tTJSNativeInstance inherited;\n\nprivate:\n\tstd::vector<tTJSVariantClosure> ObjectVector;\n\tbool ObjectVectorLocked;\n\nprotected:\n\tiTJSDispatch2 *Owner;\npublic:\n\tiTJSDispatch2 * TJS_INTF_METHOD GetOwnerNoAddRef() const { return Owner; }\n\npublic:\n\ttTJSNI_BaseWindow();\n\t~tTJSNI_BaseWindow();\n\ttjs_error TJS_INTF_METHOD\n\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\tbool IsMainWindow() const;\n\tvirtual bool GetWindowActive() = 0;\n\tvoid FireOnActivate(bool activate_or_deactivate);\n\n\n\t//-- interface to draw device\npublic:\n\ttTJSVariant DrawDeviceObject; //!< Current Draw Device TJS2 Object\n\tiTVPDrawDevice * DrawDevice; //!< Current Draw Device\n\tvoid SetDrawDeviceObject(const tTJSVariant & val);\n\tconst tTJSVariant & GetDrawDeviceObject() const { return DrawDeviceObject; }\n\tiTVPDrawDevice * GetDrawDevice() const { return DrawDevice ; }\n\tvirtual void ResetDrawDevice() = 0;\n\tvirtual iTJSDispatch2 * GetWindowDispatch() { if(Owner) Owner->AddRef(); return Owner; }\n\n\n\t//----- event dispatching\npublic:\n\tvirtual bool CanDeliverEvents() const = 0; // implement this in each platform\n\n\npublic:\n\n\tvoid OnClose();\n\tvoid OnResize();\n\tvoid OnClick(tjs_int x, tjs_int y);\n\tvoid OnDoubleClick(tjs_int x, tjs_int y);\n\tvoid OnMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid OnMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvoid OnMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags);\n\tvoid OnReleaseCapture();\n\tvoid OnMouseOutOfWindow();\n\tvoid OnMouseEnter();\n\tvoid OnMouseLeave();\n\tvoid OnKeyDown(tjs_uint key, tjs_uint32 shift);\n\tvoid OnKeyUp(tjs_uint key, tjs_uint32 shift);\n\tvoid OnKeyPress(tjs_char key);\n\tvoid OnFileDrop(const tTJSVariant &array);\n\tvoid OnMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y);\n\tvoid OnPopupHide();\n\tvoid OnActivate(bool activate_or_deactivate);\n\n\tvirtual void OnTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvirtual void OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvirtual void OnTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\t\n\tvoid OnTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid OnTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvoid OnMultiTouch();\n\n\tvoid OnHintChange( const ttstr& text, tjs_int x, tjs_int y, bool isshow );\n\n\tvoid OnDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int hresolution, tjs_int vresolution );\n\n\tvoid ClearInputEvents();\n\n\tvoid PostReleaseCaptureEvent();\n\n\t//----- layer managermant\npublic:\n\tvoid TJS_INTF_METHOD RegisterLayerManager(iTVPLayerManager * manager);\n\tvoid TJS_INTF_METHOD UnregisterLayerManager(iTVPLayerManager * manager);\n\n\nprotected:\n\ttTVPRect WindowExposedRegion;\n\ttTVPBaseBitmap * DrawBuffer;\n\n\tbool WindowUpdating; // window is in updating\n\npublic:\n\tvoid NotifyWindowExposureToLayer(const tTVPRect &cliprect);\n\npublic:\n\tvoid NotifyUpdateRegionFixed(const tTVPComplexRect &updaterects); // is called by layer manager\n\tvoid UpdateContent(); // is called from event dispatcher\n\tvoid DeliverDrawDeviceShow();\n\tvirtual void BeginUpdate(const tTVPComplexRect & rects);\n\tvirtual void EndUpdate();\n\tvirtual void TJS_INTF_METHOD RequestUpdate();\n\tvirtual void TJS_INTF_METHOD NotifySrcResize(); // is called from primary layer\n\tvirtual tTVPImeMode GetDefaultImeMode() const = 0;\n\n\tvoid DumpPrimaryLayerStructure();\n\n\tvoid RecheckInputState(); // slow timer tick (about 1 sec interval, inaccurate)\n\n\tvoid SetShowUpdateRect(bool b);\n\n\n\t//----- methods\n\tvoid Add(tTJSVariantClosure clo);\n\tvoid Remove(tTJSVariantClosure clo);\n\n\t//----- interface to video overlay object\nprotected:\n\ttObjectList<tTJSNI_BaseVideoOverlay> VideoOverlay;\n\npublic:\n\tvoid RegisterVideoOverlayObject(tTJSNI_BaseVideoOverlay *ovl);\n\tvoid UnregisterVideoOverlayObject(tTJSNI_BaseVideoOverlay *ovl);\n\n\t//----- vsync\nprotected:\n\tbool WaitVSync;\n\tvirtual void UpdateVSyncThread() = 0;\n\npublic:\n\tvoid SetWaitVSync( bool enable );\n\tbool GetWaitVSync() const;\n};\n//---------------------------------------------------------------------------\n\n#include \"WindowImpl.h\" // must define tTJSNI_Window class\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Window List\n//---------------------------------------------------------------------------\nclass tTJSNI_Window;\nextern tTJSNI_Window * TVPGetWindowListAt(tjs_int idx);\nextern tjs_int TVPGetWindowCount();\nextern tTJSNI_Window * TVPMainWindow; //  = NULL; // main window\n\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Window : TJS Window class\n//---------------------------------------------------------------------------\nclass tTJSNC_Window : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_Window();\n\tstatic tjs_uint32 ClassID;\n\nprotected:\n\ttTJSNativeInstance *CreateNativeInstance();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNI_Window.\n\t*/\n};\n//---------------------------------------------------------------------------\nextern tTJSNativeClass * TVPCreateNativeClass_Window();\n\t/*\n\t\timplement this in each platform.\n\t\tthis must return a proper instance of tTJSNI_Window.\n\t\tusually simple returns: new tTJSNC_Window();\n\t*/\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Input Events\n//---------------------------------------------------------------------------\nclass tTVPOnCloseInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnCloseInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnClose(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnResizeInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnResizeInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnResize(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnClickInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int X;\n\ttjs_int Y;\npublic:\n\ttTVPOnClickInputEvent(tTJSNI_BaseWindow *win, tjs_int x, tjs_int y) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnClick(X, Y); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnDoubleClickInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int X;\n\ttjs_int Y;\npublic:\n\ttTVPOnDoubleClickInputEvent(tTJSNI_BaseWindow *win, tjs_int x, tjs_int y) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnDoubleClick(X, Y); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseDownInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int X;\n\ttjs_int Y;\n\ttTVPMouseButton Buttons;\n\ttjs_uint32 Flags;\npublic:\n\ttTVPOnMouseDownInputEvent(tTJSNI_BaseWindow *win, tjs_int x, tjs_int y,\n\t\ttTVPMouseButton buttons, tjs_uint32 flags) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), Buttons(buttons), Flags(flags) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseDown(X, Y, Buttons, Flags); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseUpInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int X;\n\ttjs_int Y;\n\ttTVPMouseButton Buttons;\n\ttjs_uint32 Flags;\npublic:\n\ttTVPOnMouseUpInputEvent(tTJSNI_BaseWindow *win, tjs_int x, tjs_int y,\n\t\ttTVPMouseButton buttons, tjs_uint32 flags) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), Buttons(buttons), Flags(flags) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseUp(X, Y, Buttons, Flags); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseMoveInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int X;\n\ttjs_int Y;\n\ttjs_uint32 Flags;\npublic:\n\ttTVPOnMouseMoveInputEvent(tTJSNI_BaseWindow *win, tjs_int x, tjs_int y,\n\t\ttjs_uint32 flags) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), Flags(flags) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseMove(X, Y, Flags); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnReleaseCaptureInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnReleaseCaptureInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnReleaseCapture(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseOutOfWindowInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnMouseOutOfWindowInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseOutOfWindow(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseEnterInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnMouseEnterInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseEnter(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseLeaveInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnMouseLeaveInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseLeave(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnKeyDownInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_uint Key;\n\ttjs_uint32 Shift;\npublic:\n\ttTVPOnKeyDownInputEvent(tTJSNI_BaseWindow *win, tjs_uint key, tjs_uint32 shift) :\n\t\ttTVPBaseInputEvent(win, Tag), Key(key), Shift(shift) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnKeyDown(Key, Shift); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnKeyUpInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_uint Key;\n\ttjs_uint32 Shift;\npublic:\n\ttTVPOnKeyUpInputEvent(tTJSNI_BaseWindow *win, tjs_uint key, tjs_uint32 shift) :\n\t\ttTVPBaseInputEvent(win, Tag), Key(key), Shift(shift) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnKeyUp(Key, Shift); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnKeyPressInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_char Key;\npublic:\n\ttTVPOnKeyPressInputEvent(tTJSNI_BaseWindow *win, tjs_char key) :\n\t\ttTVPBaseInputEvent(win, Tag), Key(key) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnKeyPress(Key); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnFileDropInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttTJSVariant Array;\npublic:\n\ttTVPOnFileDropInputEvent(tTJSNI_BaseWindow *win, const tTJSVariant & val) :\n\t\ttTVPBaseInputEvent(win, Tag), Array(val) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnFileDrop(Array); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMouseWheelInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_uint32 Shift;\n\ttjs_int WheelDelta;\n\ttjs_int X;\n\ttjs_int Y;\npublic:\n\ttTVPOnMouseWheelInputEvent(tTJSNI_BaseWindow *win, tjs_uint32 shift,\n\t\ttjs_int wheeldelta, tjs_int x, tjs_int y) :\n\t\ttTVPBaseInputEvent(win, Tag), Shift(shift), WheelDelta(wheeldelta),\n\t\tX(x), Y(y) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMouseWheel(Shift, WheelDelta, X, Y); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnPopupHideInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\npublic:\n\ttTVPOnPopupHideInputEvent(tTJSNI_BaseWindow *win) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnPopupHide(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnWindowActivateEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\tbool ActivateOrDeactivate;\npublic:\n\ttTVPOnWindowActivateEvent(tTJSNI_BaseWindow *win, bool activate_or_deactivate) :\n\t\ttTVPBaseInputEvent(win, Tag), ActivateOrDeactivate(activate_or_deactivate) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnActivate(ActivateOrDeactivate); }\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nclass tTVPOnTouchDownInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_real X;\n\ttjs_real Y;\n\ttjs_real CX;\n\ttjs_real CY;\n\ttjs_uint32 ID;\npublic:\n\ttTVPOnTouchDownInputEvent(tTJSNI_BaseWindow *win, tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), CX(cx), CY(cy), ID(id) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnTouchDown(X, Y, CX, CY, ID); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnTouchUpInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_real X;\n\ttjs_real Y;\n\ttjs_real CX;\n\ttjs_real CY;\n\ttjs_uint32 ID;\npublic:\n\ttTVPOnTouchUpInputEvent(tTJSNI_BaseWindow *win, tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), CX(cx), CY(cy), ID(id) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnTouchUp(X, Y, CX, CY, ID); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnTouchMoveInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_real X;\n\ttjs_real Y;\n\ttjs_real CX;\n\ttjs_real CY;\n\ttjs_uint32 ID;\npublic:\n\ttTVPOnTouchMoveInputEvent(tTJSNI_BaseWindow *win, tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) :\n\t\ttTVPBaseInputEvent(win, Tag), X(x), Y(y), CX(cx), CY(cy), ID(id) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnTouchMove(X, Y, CX, CY, ID); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnTouchScalingInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_real StartDistance;\n\ttjs_real CurrentDistance;\n\ttjs_real CX;\n\ttjs_real CY;\n\ttjs_int Flag;\npublic:\n\ttTVPOnTouchScalingInputEvent(tTJSNI_BaseWindow *win, tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag ) :\n\t\ttTVPBaseInputEvent(win, Tag), StartDistance(startdist), CurrentDistance(curdist), CX(cx), CY(cy), Flag(flag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnTouchScaling( StartDistance, CurrentDistance, CX, CY, Flag ); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnTouchRotateInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_real StartAngle;\n\ttjs_real CurrentAngle;\n\ttjs_real Distance;\n\ttjs_real CX;\n\ttjs_real CY;\n\ttjs_int Flag;\npublic:\n\ttTVPOnTouchRotateInputEvent(tTJSNI_BaseWindow *win, tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag ) :\n\t\ttTVPBaseInputEvent(win, Tag), StartAngle(startangle), CurrentAngle(curangle), Distance(dist), CX(cx), CY(cy), Flag(flag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnTouchRotate( StartAngle, CurrentAngle, Distance, CX, CY, Flag ); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnMultiTouchInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\npublic:\n\ttTVPOnMultiTouchInputEvent(tTJSNI_BaseWindow *win ) :\n\t\ttTVPBaseInputEvent(win, Tag) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnMultiTouch(); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnHintChangeInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\tttstr HintMessage;\n\ttjs_int HintX;\n\ttjs_int HintY;\n\tbool IsShow;\npublic:\n\ttTVPOnHintChangeInputEvent(tTJSNI_BaseWindow *win, const ttstr& text, tjs_int x, tjs_int y, bool isshow ) :\n\t\ttTVPBaseInputEvent(win, Tag)\n\t\t, HintMessage(text), HintX(x), HintY(y), IsShow(isshow)\t{};\n\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnHintChange( HintMessage, HintX, HintY, IsShow ); }\n};\n//---------------------------------------------------------------------------\nclass tTVPOnDisplayRotateInputEvent : public tTVPBaseInputEvent\n{\n\tstatic tTVPUniqueTagForInputEvent Tag;\n\ttjs_int Orientation;\n\ttjs_int Rotate;\n\ttjs_int BPP;\n\ttjs_int HorizontalResolution;\n\ttjs_int VerticalResolution;\npublic:\n\ttTVPOnDisplayRotateInputEvent(tTJSNI_BaseWindow *win, tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int hresolution, tjs_int vresolution ) :\n\t\ttTVPBaseInputEvent(win, Tag), Orientation(orientation), Rotate(rotate), BPP(bpp),\n\t\tHorizontalResolution(hresolution), VerticalResolution(vresolution) {};\n\tvoid Deliver() const\n\t{ ((tTJSNI_BaseWindow*)GetSource())->OnDisplayRotate( Orientation, Rotate, BPP, HorizontalResolution, VerticalResolution ); }\n};\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/argb.cpp",
    "content": "#include \"argb.h\"\n\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::Zero()\n{\n\t*(tjs_uint32 *)this = 0;\n}\n\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::operator = (tjs_uint32 v)\n{\n\t*(tjs_uint32 *)this = v;\n}\n\ntemplate <>\ntTVPARGB<tjs_uint8>::operator tjs_uint32() const\n{\n\treturn *(const tjs_uint32 *)this;\n}\n\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::average(tjs_int n)\n{\n\ttjs_int half_n = n >> 1;\n\n\ttjs_int recip = (1L << 23) / n;\n\n\tb = (b + half_n)*recip >> 23;\n\tg = (g + half_n)*recip >> 23;\n\tr = (r + half_n)*recip >> 23;\n\ta = (a + half_n)*recip >> 23;\n}\n\ntemplate <>\nvoid tTVPARGB<tjs_uint16>::average(tjs_int n)\n{\n\ttjs_int half_n = n >> 1;\n\n\ttjs_int recip = (1L << 16) / n;\n\n\tb = (b + half_n)*recip >> 16;\n\tg = (g + half_n)*recip >> 16;\n\tr = (r + half_n)*recip >> 16;\n\ta = (a + half_n)*recip >> 16;\n}\n\ntemplate <>\nvoid tTVPARGB<tjs_uint32>::average(tjs_int n)\n{\n\ttjs_int half_n = n >> 1;\n\n\tb = (b + half_n) / n;\n\tg = (g + half_n) / n;\n\tr = (r + half_n) / n;\n\ta = (a + half_n) / n;\n}\n\n// avoid bug for VC compiler\nvoid __argb_hack_for_vc() {\n\ttTVPARGB<tjs_uint8> a;\n\ta = 0;\n\ta.Zero();\n\ta.operator tjs_uint32();\n\ta.average(0);\n\ttTVPARGB<tjs_uint16> b;\n\tb.average(0);\n\ttTVPARGB<tjs_uint32> c;\n\tc.average(0);\n}\n"
  },
  {
    "path": "src/core/visual/argb.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Structures for manipulating ARGB expression of a pixel\n//---------------------------------------------------------------------------\n#ifndef ARGBH\n#define ARGBH\n\n#include \"tjsTypes.h\"\n#include \"tvpgl.h\"\n//---------------------------------------------------------------------------\n#ifdef __WIN32__\n\t// for assembler compatibility\n\t#pragma pack(push,1)\n#endif\n//---------------------------------------------------------------------------\ntemplate <typename base_type>\nstruct tTVPARGB\n{\n\tunion {\n\t\tstruct {\n#if TJS_HOST_IS_LITTLE_ENDIAN\n\tbase_type b;\n\tbase_type g;\n\tbase_type r;\n\tbase_type a;\n#endif\n#if TJS_HOST_IS_BIG_ENDIAN\n\tbase_type a;\n\tbase_type r;\n\tbase_type g;\n\tbase_type b;\n#endif\n\t\t};\n\t\tstruct {\n\t\t\tbase_type packed;\n\t\t};\n\t};\n\n\ttypedef base_type base_int_type;\n\n\n\ttTVPARGB() {;}\n\n//\ttTVPARGB(const tTVPARGB & rhs)\n//\t\t{ this->operator =(rhs); }\n\n\tvoid Zero()\n\t{\n\t\tb = g = r = a = 0;\n\t}\n\n\tvoid operator += (const tTVPARGB & rhs)\n\t\t{ b += rhs.b; g += rhs.g; r += rhs.r; a += rhs.a; }\n\n\tvoid operator -= (const tTVPARGB & rhs)\n\t\t{ b -= rhs.b; g -= rhs.g; r -= rhs.r; a -= rhs.a; }\n\n\tvoid operator += (tjs_uint32 v)\n\t{\n\t\tb += v & 0xff;\n\t\tg += (v>>8) & 0xff;\n\t\tr += (v>>16) & 0xff;\n\t\ta += (v>>24);\n\t}\n\n\tvoid operator -= (tjs_uint32 v)\n\t{\n\t\tb -= v & 0xff;\n\t\tg -= (v>>8) & 0xff;\n\t\tr -= (v>>16) & 0xff;\n\t\ta -= (v>>24);\n\t}\n\n//\tvoid operator = (const tTVPARGB & rhs)\n//\t\t{ *this = rhs; }\n\n\tvoid average(tjs_int n)\n\t{\n\t\ttjs_int half_n = n >> 1;\n\n\t\tb /= n;\n\t\tg /= n;\n\t\tr /= n;\n\t\ta /= n;\n\t}\n\n\tvoid operator = (tjs_uint32 v)\n\t{\n\t\ta = v >> 24,\n\t\tr = (v >> 16) & 0xff,\n\t\tg = (v >> 8) & 0xff,\n\t\tb = v & 0xff;\n\t}\n\n\toperator tjs_uint32() const\n\t{\n\t\treturn b + (g << 8) + (r << 16) + (a << 24);\n\t}\n\n};\n//---------------------------------------------------------------------------\n// special member functions for tjs_uint8\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::Zero();\n\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::operator = (tjs_uint32 v);\n\ntemplate <>\ntTVPARGB<tjs_uint8>::operator tjs_uint32() const;\n\ntemplate <>\nvoid tTVPARGB<tjs_uint8>::average(tjs_int n);\n\n//---------------------------------------------------------------------------\n// special member functions for tjs_uint16\ntemplate <>\nvoid tTVPARGB<tjs_uint16>::average(tjs_int n);\n\n//---------------------------------------------------------------------------\n// special member functions for tjs_uint32\ntemplate <>\nvoid tTVPARGB<tjs_uint32>::average(tjs_int n);\n\n\n//---------------------------------------------------------------------------\n// a structure delivered from tTVPARGB, using Additive-Alpha expression\n// for tjs_uint32 (packed ARGB) input/output.\ntemplate <typename base_type>\nstruct tTVPARGB_AA : public tTVPARGB<base_type>\n{\n\tvoid operator += (const tTVPARGB_AA & rhs)\n\t\t{ this->b += rhs.b; this->g += rhs.g; this->r += rhs.r; this->a += rhs.a; }\n\n\tvoid operator -= (const tTVPARGB_AA & rhs)\n\t\t{ this->b -= rhs.b; this->g -= rhs.g; this->r -= rhs.r; this->a -= rhs.a; }\n\n\t// Four methods, which convert itself from/to tjs_uint32 (packed ARGB),\n\t// are overrided.\n\n\tvoid operator += (tjs_uint32 v)\n\t{\n\t\ttjs_int aadj;\n\t\tthis->a += (aadj = (v >> 24));\n\t\taadj += aadj >> 7;\n\t\tthis->b += (v & 0xff) * aadj >> 8;\n\t\tthis->g += ((v >> 8) & 0xff) * aadj >> 8;\n\t\tthis->r += ((v >> 16) & 0xff) * aadj >> 8;\n\t}\n\n\tvoid operator -= (tjs_uint32 v)\n\t{\n\t\ttjs_int aadj;\n\t\tthis->a -= (aadj = (v >> 24));\n\t\taadj += aadj >> 7;\n\t\tthis->b -= (v & 0xff) * aadj >> 8;\n\t\tthis->g -= ((v >> 8) & 0xff) * aadj >> 8;\n\t\tthis->r -= ((v >> 16) & 0xff) * aadj >> 8;\n\t}\n\n\tvoid operator = (tjs_uint32 v)\n\t{\n\t\tthis->a = v >> 24;\n\t\ttjs_int aadj = this->a + (this->a >> 7); // adjusted alpha\n\t\tthis->r = ((v >> 16) & 0xff) * aadj >> 8;\n\t\tthis->g = ((v >> 8) & 0xff) * aadj >> 8;\n\t\tthis->b = (v & 0xff) * aadj >> 8;\n\t}\n\n\toperator tjs_uint32() const\n\t{\n\t\ttjs_uint8 *t = TVPDivTable + (this->a << 8);\n\t\treturn t[this->b] + (t[this->g] << 8) + (t[this->r] << 16) + (this->a << 24);\n\t}\n\n};\n\n\n\n//---------------------------------------------------------------------------\n#ifdef __WIN32__\n\t// for assembler compatibility\n\t#pragma pack(pop)\n#endif\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/drawable.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"tTVPDrawable\" definition\n//---------------------------------------------------------------------------\n\n#ifndef __DRAWABLE_H__\n#define __DRAWABLE_H__\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// layer / blending types\n//---------------------------------------------------------------------------\nenum tTVPLayerType\n{\n\tltBinder = 0,\n\tltCoverRect = 1,\n\tltOpaque = 1, // the same as ltCoverRect\n\tltTransparent = 2, // alpha blend\n\tltAlpha = 2, // the same as ltTransparent\n\tltAdditive = 3,\n\tltSubtractive = 4,\n\tltMultiplicative = 5,\n\tltEffect = 6,\n\tltFilter = 7,\n\tltDodge = 8,\n\tltDarken = 9,\n\tltLighten = 10,\n\tltScreen = 11,\n\tltAddAlpha = 12, // additive alpha blend\n\tltPsNormal = 13,\n\tltPsAdditive = 14,\n\tltPsSubtractive = 15,\n\tltPsMultiplicative = 16,\n\tltPsScreen = 17,\n\tltPsOverlay = 18,\n\tltPsHardLight = 19,\n\tltPsSoftLight = 20,\n\tltPsColorDodge = 21,\n\tltPsColorDodge5 = 22,\n\tltPsColorBurn = 23,\n\tltPsLighten = 24,\n\tltPsDarken = 25,\n\tltPsDifference = 26,\n\tltPsDifference5 = 27,\n\tltPsExclusion = 28\n};\n//---------------------------------------------------------------------------\nstatic bool inline TVPIsTypeUsingAlpha(tTVPLayerType type)\n\t{\n\t\treturn\n\t\t\ttype == ltAlpha\t\t\t\t||\n\t\t\ttype == ltPsNormal\t\t\t||\n\t\t\ttype == ltPsAdditive\t\t||\n\t\t\ttype == ltPsSubtractive\t\t||\n\t\t\ttype == ltPsMultiplicative\t||\n\t\t\ttype == ltPsScreen\t\t\t||\n\t\t\ttype == ltPsOverlay\t\t\t||\n\t\t\ttype == ltPsHardLight\t\t||\n\t\t\ttype == ltPsSoftLight\t\t||\n\t\t\ttype == ltPsColorDodge\t\t||\n\t\t\ttype == ltPsColorDodge5\t\t||\n\t\t\ttype == ltPsColorBurn\t\t||\n\t\t\ttype == ltPsLighten\t\t\t||\n\t\t\ttype == ltPsDarken\t\t\t||\n\t\t\ttype == ltPsDifference\t\t||\n\t\t\ttype == ltPsDifference5\t\t||\n\t\t\ttype == ltPsExclusion\t\t;\n\t}\n\nstatic bool inline TVPIsTypeUsingAddAlpha(tTVPLayerType type)\n\t{\n\t\treturn type == ltAddAlpha;\n\t}\n\nstatic bool inline TVPIsTypeUsingAlphaChannel(tTVPLayerType type)\n\t{\n\t\treturn\n\t\t\tTVPIsTypeUsingAddAlpha(type) ||\n\t\t\tTVPIsTypeUsingAlpha(type);\n\t}\n//---------------------------------------------------------------------------\n\n\n\n/*]*/\n\n\n//---------------------------------------------------------------------------\n// tTVPDrawable definition\n//---------------------------------------------------------------------------\nclass tTVPBaseTexture;\nstruct tTVPRect;\nclass tTVPDrawable\n{\npublic:\n\t// base class of draw-able objects.\n\tvirtual tTVPBaseTexture * GetDrawTargetBitmap(const tTVPRect &rect,\n\t\ttTVPRect &cliprect) = 0;\n\t\t// returns target bitmap which has given size\n\t\t// (rect.get_width() * rect.get_height()).\n\t\t// put actually to be drawn rectangle to \"cliprect\"\n\n\tvirtual tTVPLayerType GetTargetLayerType() = 0;\n\t\t// returns target layer type\n\n\tvirtual void DrawCompleted(const tTVPRect &destrect,\n\t\ttTVPBaseTexture *bmp, const tTVPRect &cliprect,\n\t\ttTVPLayerType type, tjs_int opacity) = 0;\n\t\t// call this when the drawing is completed, passing\n\t\t// the bitmap containing the image, and its clip region.\n};\n//---------------------------------------------------------------------------\n\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/gl/ResampleImage.cpp",
    "content": "/******************************************************************************/\n/**\n * gk\n * ----------------------------------------------------------------------------\n * \tCopyright (C) T.Imoto <http://www.kaede-software.com>\n * ----------------------------------------------------------------------------\n * @author\t\tT.Imoto\n * @date\t\t2014/04/02\n * @note\n *****************************************************************************/\n\n#define _USE_MATH_DEFINES\n#include \"tjsCommHead.h\"\n\n#include <float.h>\n#include <math.h>\n#include <cmath>\n#include <vector>\n\n//#include \"tvpgl_ia32_intf.h\"\n//#include \"DetectCPU.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"LayerBitmapImpl.h\"\n#include \"WeightFunctor.h\"\n#include \"ThreadIntf.h\"\n\n#include \"aligned_allocator.h\"\n#include \"ResampleImageInternal.h\"\n\n\nextern void TVPResampleImageAVX2( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc,\n\tiTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\ttTVPBBStretchType type, tjs_real typeopt );\n\nextern void TVPResampleImageSSE2( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc,\n\tiTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\ttTVPBBStretchType type, tjs_real typeopt );\n\nvoid tTVPBlendParameter::setFunctionFromParam() {\n#define TVP_BLEND_4(basename) /* blend for 4 types (normal, opacity, HDA, HDA opacity) */ \\\n\tif( opa_ == 255 ) {                                                                   \\\n\t\tif( !hda_ ) {                                                                     \\\n\t\t\tcopy_func = basename;                                                         \\\n\t\t} else {                                                                          \\\n\t\t\tcopy_func = basename##_HDA;                                                   \\\n\t\t}                                                                                 \\\n\t} else {                                                                              \\\n\t\tif( !hda_ ) {                                                                     \\\n\t\t\tblend_func = basename##_o;                                                    \\\n\t\t} else {                                                                          \\\n\t\t\tblend_func = basename##_HDA_o;                                                \\\n\t\t}                                                                                 \\\n\t}\n\n\tblend_func = NULL;\n\tcopy_func = NULL;\n\tswitch( method_ ) {\n\tcase bmCopy:\n\t\tif( opa_ == 255 && hda_ ) {\n\t\t\tcopy_func = TVPCopyColor;\n\t\t} else if( !hda_ ) {\n\t\t\tblend_func = TVPConstAlphaBlend;\n\t\t} else {\n\t\t\tblend_func = TVPConstAlphaBlend_HDA;\n\t\t}\n\t\tbreak;\n\tcase bmCopyOnAlpha:\n\t\tif( opa_ == 255 )\n\t\t\tcopy_func = TVPCopyOpaqueImage;\n\t\telse\n\t\t\tblend_func = TVPConstAlphaBlend_d;\n\t\tbreak;\n\tcase bmAlpha:\n\t\tTVP_BLEND_4(TVPAlphaBlend);\n\t\tbreak;\n\tcase bmAlphaOnAlpha:\n\t\tif( opa_ == 255 )\n\t\t\tcopy_func = TVPAlphaBlend_d;\n\t\telse\n\t\t\tblend_func = TVPAlphaBlend_do;\n\t\tbreak;\n\tcase bmAdd:\n\t\tTVP_BLEND_4(TVPAddBlend);\n\t\tbreak;\n\tcase bmSub:\n\t\tTVP_BLEND_4(TVPSubBlend);\n\t\tbreak;\n\tcase bmMul:\n\t\tTVP_BLEND_4(TVPMulBlend);\n\t\tbreak;\n\tcase bmDodge:\n\t\tTVP_BLEND_4(TVPColorDodgeBlend);\n\t\tbreak;\n\tcase bmDarken:\n\t\tTVP_BLEND_4(TVPDarkenBlend);\n\t\tbreak;\n\tcase bmLighten:\n\t\tTVP_BLEND_4(TVPLightenBlend);\n\t\tbreak;\n\tcase bmScreen:\n\t\tTVP_BLEND_4(TVPScreenBlend);\n\t\tbreak;\n\tcase bmAddAlpha:\n\t\tTVP_BLEND_4(TVPAdditiveAlphaBlend);\n\t\tbreak;\n\tcase bmAddAlphaOnAddAlpha:\n\t\tif( opa_ == 255 ) {\n\t\t\tcopy_func = TVPAdditiveAlphaBlend_a;\n\t\t} else {\n\t\t\tblend_func = TVPAdditiveAlphaBlend_ao;\n\t\t}\n\t\tbreak;\n\tcase bmAddAlphaOnAlpha:\n\t\t// Not yet implemented\n\t\tbreak;\n\tcase bmAlphaOnAddAlpha:\n\t\tif( opa_ == 255 ) {\n\t\t\tcopy_func = TVPAlphaBlend_a;\n\t\t} else {\n\t\t\tblend_func = TVPAlphaBlend_ao;\n\t\t}\n\t\tbreak;\n\tcase bmCopyOnAddAlpha:\n\t\tif( opa_ == 255 )\n\t\t\tcopy_func = TVPCopyOpaqueImage;\n\t\telse\n\t\t\tblend_func = TVPConstAlphaBlend_a;\n\t\tbreak;\n\tcase bmPsNormal:\n\t\tTVP_BLEND_4(TVPPsAlphaBlend);\n\t\tbreak;\n\tcase bmPsAdditive:\n\t\tTVP_BLEND_4(TVPPsAddBlend);\n\t\tbreak;\n\tcase bmPsSubtractive:\n\t\tTVP_BLEND_4(TVPPsSubBlend);\n\t\tbreak;\n\tcase bmPsMultiplicative:\n\t\tTVP_BLEND_4(TVPPsMulBlend);\n\t\tbreak;\n\tcase bmPsScreen:\n\t\tTVP_BLEND_4(TVPPsScreenBlend);\n\t\tbreak;\n\tcase bmPsOverlay:\n\t\tTVP_BLEND_4(TVPPsOverlayBlend);\n\t\tbreak;\n\tcase bmPsHardLight:\n\t\tTVP_BLEND_4(TVPPsHardLightBlend);\n\t\tbreak;\n\tcase bmPsSoftLight:\n\t\tTVP_BLEND_4(TVPPsSoftLightBlend);\n\t\tbreak;\n\tcase bmPsColorDodge:\n\t\tTVP_BLEND_4(TVPPsColorDodgeBlend);\n\t\tbreak;\n\tcase bmPsColorDodge5:\n\t\tTVP_BLEND_4(TVPPsColorDodge5Blend);\n\t\tbreak;\n\tcase bmPsColorBurn:\n\t\tTVP_BLEND_4(TVPPsColorBurnBlend);\n\t\tbreak;\n\tcase bmPsLighten:\n\t\tTVP_BLEND_4(TVPPsLightenBlend);\n\t\tbreak;\n\tcase bmPsDarken:\n\t\tTVP_BLEND_4(TVPPsDarkenBlend);\n\t\tbreak;\n\tcase bmPsDifference:\n\t\tTVP_BLEND_4(TVPPsDiffBlend);\n\t\tbreak;\n\tcase bmPsDifference5:\n\t\tTVP_BLEND_4(TVPPsDiff5Blend);\n\t\tbreak;\n\tcase bmPsExclusion:\n\t\tTVP_BLEND_4(TVPPsExclusionBlend);\n\t\tbreak;\n\t}\n#undef TVP_BLEND_4\n}\n\nvoid tTVPResampleClipping::setClipping( const tTVPRect &cliprect, const tTVPRect &destrect ) {\n\tconst int dstwidth = destrect.get_width();\n\tconst int dstheight = destrect.get_height();\n\n\toffsetx_ = 0;\n\toffsety_ = 0;\n\twidth_ = dstwidth;\n\theight_ = dstheight;\n\tdst_left_ = destrect.left;\n\tdst_top_ = destrect.top;\n\n\t// 㕔NbsO\n\tif( cliprect.top > destrect.top ) {\n\t\toffsety_ = cliprect.top - destrect.top;\t\t\t// NbsOItZbg\n\t\tdst_top_ = cliprect.top;\n\t}\n\t// NbsO\n\tif( cliprect.bottom < destrect.bottom ) {\n\t\theight_ -= destrect.bottom - cliprect.bottom;\t// ͂ݏo\n\t}\n\t// NbsO\n\tif( cliprect.left > destrect.left ) {\n\t\toffsetx_ = cliprect.left - destrect.left;\t// NbsOItZbg\n\t\tdst_left_ = cliprect.left;\n\t}\n\t// ENbsO\n\tif( cliprect.right < destrect.right ) {\n\t\twidth_ -= destrect.right - cliprect.right;\t// ͂ݏo\n\t}\n}\n\n/**\n * eł̃EFCg炩ߌvZĂ\n */\ntemplate<typename TWeight=float, int NAlign=4>\nstruct AxisParam {\n\ttypedef TWeight weight_t;\n\ttypedef std::vector<weight_t,aligned_allocator<weight_t,NAlign> > weight_vector_t;\n\tstatic const int ALIGN_DIV = (NAlign/4);\n\tstatic const int ALIGN_OFFSET = ALIGN_DIV-1;\n\n\tstd::vector<int> start_;\t// JnCfbNX\n\tstd::vector<int> length_;\t// evf\n\tstd::vector<int> min_length_;\n\tweight_vector_t weight_;\n\n\tstatic const int toAlign( int& length ) {\n\t\tlength = ((length+ALIGN_OFFSET)/ALIGN_DIV)*ALIGN_DIV;\n\t}\n};\n\nstatic inline void AxisParamCalculateWeight( float* weight, float*& output, int& len, int leftedge, int rightedge ) {\n\t// len ɂ͂͂ݏo܂܂Ă̂ŁA܂͂̕Jbg\n\t// [orE[̎A͂ݏõEFCg[ɉZ\n\tif( leftedge ) {\n\t\t// [͂ݏoZ\n\t\tint i = 1;\n\t\tfor( ; i <= leftedge; i++ ) {\n\t\t\tweight[0] += weight[i];\n\t\t}\n\t\t// Zړ\n\t\tfor( int j = 1; i < len; i++, j++ ) {\n\t\t\tweight[j] = weight[i];\n\t\t}\n\t\t// ͂ݏo̒Jbg\n\t\tlen -= leftedge;\n\t}\n\tif( rightedge ) {\n\t\t// E[͂ݏoZ\n\t\tint i = len - rightedge;\n\t\tint r = i - 1;\n\t\tfor( ; i < len; i++ ) {\n\t\t\tweight[r] += weight[i];\n\t\t}\n\t\t// ͂ݏo̒Jbg\n\t\tlen -= rightedge;\n\t}\n\t// vl߂\n\tfloat* w = weight;\n\tfloat sum = 0.0f;\n\tfor( int i = 0; i < len; i++ ) {\n\t\tsum += *w;\n\t\tw++;\n\t}\n\n\t// EPSILON 菬ꍇ 0 ݒ\n\tfloat rcp;\n\tif( sum < FLT_EPSILON ) {\n\t\trcp = 0.0f;\n\t} else {\n\t\trcp = 1.0f / sum;\n\t}\n\t// K\n\tw = weight;\n\tfor( int i = 0; i < len; i++ ) {\n\t\t*output = (*w) * rcp;\n\t\toutput++;\n\t\tw++;\n\t}\n}\n\ntemplate<typename TParam, typename TWeightFunc>\nstatic void AxisParamCalculateAxis( TParam& param, int srcstart, int srcend, int srclength, int dstlength, float tap, TWeightFunc& func) {\n\tparam.start_.clear();\n\tparam.start_.reserve( dstlength );\n\tparam.length_.clear();\n\tparam.length_.reserve( dstlength );\n\t// ܂͋vZ\n\tif( srclength <= dstlength ) { // g\n\t\tfloat rangex = tap;\n\t\tint maxrange = ((int)rangex*2+2);\n\t\tstd::vector<float> work( maxrange, 0.0f );\n\t\tfloat* weight = &work[0];\n\t\tint length = (dstlength * maxrange + dstlength);\n#ifdef _DEBUG\n\t\tparam.weight_.resize( length );\n#else\n\t\tparam.weight_.reserve( length );\n#endif\n\t\ttypename TParam::weight_t* output = &param.weight_[0];\n\t\tfor( int x = 0; x < dstlength; x++ ) {\n\t\t\tfloat cx = (x+0.5f)*(float)srclength/(float)dstlength + srcstart;\n\t\t\tint left = (int)std::floor(cx-rangex);\n\t\t\tint right = (int)std::floor(cx+rangex);\n\t\t\tint start = left;\n\t\t\tint leftedge = 0;\n\t\t\tif( left < srcstart ) {\n\t\t\t\tleftedge = srcstart - left;\n\t\t\t\tstart = srcstart;\n\t\t\t}\n\t\t\tint rightedge = 0;\n\t\t\tif( right >= srcend ) {\n\t\t\t\trightedge = right - srcend;\n\t\t\t}\n\t\t\tparam.start_.push_back( start );\n\t\t\tint len = right - left;\n\t\t\tfloat dist = left + 0.5f - cx;\n\t\t\tfloat* w = weight;\n\t\t\tfor( int sx = 0; sx < len; sx++ ) {\n\t\t\t\t*w = func( std::abs(dist) );\n\t\t\t\tdist += 1.0f;\n\t\t\t\tw++;\n\t\t\t}\n\t\t\tAxisParamCalculateWeight( weight, output, len, leftedge, rightedge );\n\t\t\tparam.length_.push_back( len );\n\t\t}\n\t} else { // k\n\t\tfloat rangex = tap*(float)srclength/(float)dstlength;\n\t\tint maxrange = ((int)rangex*2+2);\n\t\tstd::vector<float> work( maxrange, 0.0f );\n\t\tfloat* weight = &work[0];\n\t\tint length = (srclength * maxrange + srclength);\n#ifdef _DEBUG\n\t\tparam.weight_.resize( length );\n#else\n\t\tparam.weight_.reserve( length );\n#endif\n\t\ttypename TParam::weight_t* output = &param.weight_[0];\n\t\tconst float delta = (float)dstlength/(float)srclength; // ]Wł̈ʒu\n\t\tfor( int x = 0; x < dstlength; x++ ) {\n\t\t\tfloat cx = (x+0.5f)*(float)srclength/(float)dstlength + srcstart;\n\t\t\tint left = (int)std::floor(cx-rangex);\n\t\t\tint right = (int)std::floor(cx+rangex);\n\t\t\tint start = left;\n\t\t\tint leftedge = 0;\n\t\t\tif( left < srcstart ) {\n\t\t\t\tleftedge = srcstart - left;\n\t\t\t\tstart = srcstart;\n\t\t\t}\n\t\t\tint rightedge = 0;\n\t\t\tif( right >= srcend ) {\n\t\t\t\trightedge = right - srcend;\n\t\t\t}\n\t\t\tparam.start_.push_back( start );\n\t\t\t// ]Wł̈ʒu\n\t\t\tint len = right-left;\n\t\t\tfloat dist = (left+0.5f-cx) * delta;\n\t\t\tfloat* w = weight;\n\t\t\tfor( int sx = 0; sx < len; sx++ ) {\n\t\t\t\t*w = func( std::abs(dist) );\n\t\t\t\tdist += delta;\n\t\t\t\tw++;\n\t\t\t}\n\t\t\tAxisParamCalculateWeight( weight, output, len, leftedge, rightedge );\n\t\t\tparam.length_.push_back( len );\n\t\t}\n\t}\n}\n\n/**\n * ̈敽σo[W\n */\ntemplate<typename TParam>\nstatic void AxisParamCalculateAxisAreaAvg( TParam& param, int srcstart, int srcend, int srclength, int dstlength ) {\n\tif( dstlength <= srclength ) { // k̂\n\t\tTVPCalculateAxisAreaAvg( srcstart, srcend, srclength, dstlength, param.start_, param.length_, param.weight_ );\n\t\tTVPNormalizeAxisAreaAvg( param.length_, param.weight_ );\n\t}\n}\n\n\nvoid TJS_USERENTRY ResamplerFunc( void* p );\n\nclass Resampler {\n\tAxisParam<> paramx_;\n\tAxisParam<> paramy_;\n\npublic:\n\t/** }`Xbhp */\n\tstruct ThreadParameter {\n\t\tResampler* sampler_;\n\t\tint start_;\n\t\tint end_;\n\t\tint width_;\n\n\t\tconst float* wstarty_;\n\t\tconst iTVPBaseBitmap* src_;\n\t\tconst tTVPRect* srcrect_;\n\t\tiTVPBaseBitmap* dest_;\n\t\tconst tTVPRect* destrect_;\n\n\t\tconst tTVPResampleClipping* clip_;\n\t\tconst tTVPImageCopyFuncBase* blendfunc_;\n\t};\n\n\t/** c̊gk */\n\tinline void samplingVertical( int y, tjs_uint32* dstbits, int dstheight, int srcwidth, const iTVPBaseBitmap *src, const tTVPRect &srcrect, const float*& wstarty ) {\n\t\tconst int top = paramy_.start_[y];\n\t\tconst int len = paramy_.length_[y];\n\t\tconst int bottom = top + len;\n\t\tconst float* weighty = wstarty;\n\t\tconst tjs_uint32* srctop = (const tjs_uint32*)src->GetScanLine(top) + srcrect.left;\n\t\ttjs_int stride = src->GetPitchBytes()/(int)sizeof(tjs_uint32);\n\t\tfor( int x = 0; x < srcwidth; x++ ) {\n\t\t\tweighty = wstarty;\n\t\t\tfloat color_element[4] = {0.0f,0.0f,0.0f,0.0f};\n\t\t\tconst tjs_uint32* src = &srctop[x];\n\t\t\tfor( int sy = top; sy < bottom; sy++ ) {\n\t\t\t\tconst float weight = *weighty;\n\t\t\t\ttjs_uint32 color = *src;\n\t\t\t\tcolor_element[0] += (color&0xff)*weight;\n\t\t\t\tcolor_element[1] += ((color>>8)&0xff)*weight;\n\t\t\t\tcolor_element[2] += ((color>>16)&0xff)*weight;\n\t\t\t\tcolor_element[3] += ((color>>24)&0xff)*weight;\n\t\t\t\tweighty++;\n\t\t\t\tsrc += stride;\n\t\t\t}\n\t\t\ttjs_uint32 color = (tjs_uint32)((color_element[0] > 255) ? 255 : (color_element[0] < 0) ? 0 : color_element[0]);\n\t\t\tcolor += (tjs_uint32)((color_element[1] > 255) ? 255 : (color_element[1] < 0) ? 0 : color_element[1]) << 8;\n\t\t\tcolor += (tjs_uint32)((color_element[2] > 255) ? 255 : (color_element[2] < 0) ? 0 : color_element[2]) << 16;\n\t\t\tcolor += (tjs_uint32)((color_element[3] > 255) ? 255 : (color_element[3] < 0) ? 0 : color_element[3]) << 24;\n\t\t\t*dstbits = color;\n\t\t\tdstbits++;\n\t\t}\n\t\twstarty = weighty;\n\t}\n\n\t/** ̊gk */\n\tinline void samplingHorizontal( tjs_uint32* dstbits, const int offsetx, const int dstwidth, const tjs_uint32* srcbits ) {\n\t\tconst float* weightx = &paramx_.weight_[0];\n\t\t// ܂offsetXLbv\n\t\tfor( int x = 0; x < offsetx; x++ ) {\n\t\t\tweightx += paramx_.length_[x];\n\t\t}\n\t\tconst tjs_uint32* src = srcbits;\n\t\tfor( int x = offsetx; x < dstwidth; x++ ) {\n\t\t\tconst int left = paramx_.start_[x];\n\t\t\tint right = left + paramx_.length_[x];\n\t\t\tfloat color_element[4] = {0.0f,0.0f,0.0f,0.0f};\n\t\t\tfor( int sx = left; sx < right; sx++ ) {\n\t\t\t\tconst float weight = *weightx;\n\t\t\t\ttjs_uint32 color = srcbits[sx];\n\t\t\t\tcolor_element[0] += (color&0xff)*weight;\n\t\t\t\tcolor_element[1] += ((color>>8)&0xff)*weight;\n\t\t\t\tcolor_element[2] += ((color>>16)&0xff)*weight;\n\t\t\t\tcolor_element[3] += ((color>>24)&0xff)*weight;\n\t\t\t\tweightx++;\n\t\t\t}\n\t\t\ttjs_uint32 color = (tjs_uint32)((color_element[0] > 255) ? 255 : (color_element[0] < 0) ? 0 : color_element[0]);\n\t\t\tcolor += (tjs_uint32)((color_element[1] > 255) ? 255 : (color_element[1] < 0) ? 0 : color_element[1]) << 8;\n\t\t\tcolor += (tjs_uint32)((color_element[2] > 255) ? 255 : (color_element[2] < 0) ? 0 : color_element[2]) << 16;\n\t\t\tcolor += (tjs_uint32)((color_element[3] > 255) ? 255 : (color_element[3] < 0) ? 0 : color_element[3]) << 24;\n\t\t\t*dstbits = color;\n\t\t\tdstbits++;\n\t\t}\n\t}\n\n\tvoid ResampleImage( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect ) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst int dstheight = destrect.get_height();\n#ifdef _DEBUG\n\t\tstd::vector<tjs_uint32> work(srcwidth);\n#else\n\t\tstd::vector<tjs_uint32> work;\n\t\twork.reserve( srcwidth );\n#endif\n\t\tconst float* wstarty = &paramy_.weight_[0];\n\t\t// NbsOXLbv\n\t\tfor( int y = 0; y < clip.offsety_; y++ ) {\n\t\t\twstarty += paramy_.length_[y];\n\t\t}\n\t\ttjs_uint32* workbits = &work[0];\n\t\ttjs_int dststride = dest->GetPitchBytes()/(int)sizeof(tjs_uint32);\n\t\ttjs_uint32* dstbits = (tjs_uint32*)dest->GetScanLineForWrite(clip.dst_top_) + clip.dst_left_;\n\t\tif( blendfunc == NULL ) {\n\t\t\tfor( int y = clip.offsety_; y < clip.height_; y++ ) {\n\t\t\t\tsamplingVertical( y, workbits, dstheight, srcwidth, src, srcrect, wstarty );\n\t\t\t\tsamplingHorizontal( dstbits, clip.offsetx_, clip.width_, workbits );\n\t\t\t\tdstbits += dststride;\n\t\t\t}\n\t\t} else {\t// PRs[ȊÓAxe|ɏoĂ獇\n#ifdef _DEBUG\n\t\t\tstd::vector<tjs_uint32> dstwork(clip.getDestWidth());\n#else\n\t\t\tstd::vector<tjs_uint32> dstwork;\n\t\t\tdstwork.reserve( clip.getDestWidth() );\n#endif\n\t\t\ttjs_uint32* midbits = &dstwork[0];\t// rpobt@\n\t\t\tfor( int y = clip.offsety_; y < clip.height_; y++ ) {\n\t\t\t\tsamplingVertical( y, workbits, dstheight, srcwidth, src, srcrect, wstarty );\n\t\t\t\tsamplingHorizontal( midbits, clip.offsetx_, clip.width_, workbits ); // ꎞobt@ɂ܂Rs[, ͈͊O͏Ȃ\n\t\t\t\t(*blendfunc)( dstbits, midbits, clip.getDestWidth() );\n\t\t\t\tdstbits += dststride;\n\t\t\t}\n\t\t}\n\t}\n\tvoid ResampleImageMT( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect, tjs_int threadNum ) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst float* wstarty = &paramy_.weight_[0];\n\t\t// NbsOXLbv\n\t\tfor( int y = 0; y < clip.offsety_; y++ ) {\n\t\t\twstarty += paramy_.length_[y];\n\t\t}\n\t\tint offset = clip.offsety_;\n\t\tconst int height = clip.getDestHeight();\n\n//\t\tTVPBeginThreadTask(threadNum);\n\t\tstd::vector<ThreadParameter> params(threadNum);\n\t\tfor( int i = 0; i < threadNum; i++ ) {\n\t\t\tThreadParameter* param = &params[i];\n\t\t\tparam->sampler_ = this;\n\t\t\tparam->start_ = height * i / threadNum + offset;\n\t\t\tparam->end_ = height * (i + 1) / threadNum + offset;\n\t\t\tparam->width_ = srcwidth;\n\t\t\tparam->wstarty_ = wstarty;\n\t\t\tparam->src_ = src;\n\t\t\tparam->srcrect_ = &srcrect;\n\t\t\tparam->dest_ = dest;\n\t\t\tparam->destrect_ = &destrect;\n\t\t\tparam->clip_ = &clip;\n\t\t\tparam->blendfunc_ = blendfunc;\n\t\t\tint top = param->start_;\n\t\t\tint bottom = param->end_;\n\t\t//\tTVPExecThreadTask(&ResamplerFunc, TVP_THREAD_PARAM(param));\n\t\t\tif( i < (threadNum-1) ) {\n\t\t\t\tfor( int y = top; y < bottom; y++ ) {\n\t\t\t\t\tint len = paramy_.length_[y];\n\t\t\t\t\twstarty += len;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t//\t\tTVPEndThreadTask();\n\t\tTVPExecThreadTask(threadNum, [&](int i){\n\t\t\tResamplerFunc(&params[i]);\n\t\t});\n\t}\npublic:\n\t/** VOXbh */\n\ttemplate<typename TWeightFunc>\n\tvoid Resample(const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect, float tap, TWeightFunc& func) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst int srcheight = srcrect.get_height();\n\t\tconst int dstwidth = destrect.get_width();\n\t\tconst int dstheight = destrect.get_height();\n\t\tAxisParamCalculateAxis( paramx_, 0, srcwidth, srcwidth, dstwidth, tap, func );\n\t\tAxisParamCalculateAxis( paramy_, srcrect.top, srcrect.bottom, srcheight, dstheight, tap, func );\n\t\tResampleImage( clip, blendfunc, dest, destrect, src, srcrect );\n\t}\n\ttemplate<typename TWeightFunc>\n\tvoid ResampleMT(const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect, float tap, TWeightFunc& func) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst int srcheight = srcrect.get_height();\n\t\tconst int dstwidth = destrect.get_width();\n\t\tconst int dstheight = destrect.get_height();\n\t\tint maxwidth = srcwidth > dstwidth ? srcwidth : dstwidth;\n\t\tint maxheight = srcheight > dstheight ? srcheight : dstheight;\n\t\tint threadNum = 1;\n\t\tint pixelNum = maxwidth*(int)tap*maxheight + maxheight*(int)tap*maxwidth;\n\t\tif( pixelNum >= 50 * 500 ) {\n\t\t\tthreadNum = TVPGetThreadNum();\n\t\t}\n\t\tif( threadNum == 1 ) { // ʐςȂXbh1̎͂̂܂܎s\n\t\t\tResample( clip, blendfunc, dest, destrect, src, srcrect, tap, func );\n\t\t\treturn;\n\t\t}\n\t\tAxisParamCalculateAxis( paramx_, 0, srcwidth, srcwidth, dstwidth, tap, func );\n\t\tAxisParamCalculateAxis( paramy_, srcrect.top, srcrect.bottom, srcheight, dstheight, tap, func );\n\t\tResampleImageMT( clip, blendfunc, dest, destrect, src, srcrect, threadNum );\n\t}\n\tvoid ResampleAreaAvg( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect ) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst int srcheight = srcrect.get_height();\n\t\tconst int dstwidth = destrect.get_width();\n\t\tconst int dstheight = destrect.get_height();\n\t\tif( dstwidth > srcwidth || dstheight > srcheight ) return;\n\t\tAxisParamCalculateAxisAreaAvg( paramx_, 0, srcwidth, srcwidth, dstwidth );\n\t\tAxisParamCalculateAxisAreaAvg( paramy_, srcrect.top, srcrect.bottom, srcheight, dstheight );\n\t\tResampleImage( clip, blendfunc, dest, destrect, src, srcrect );\n\t}\n\tvoid ResampleAreaAvgMT( const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect ) {\n\t\tconst int srcwidth = srcrect.get_width();\n\t\tconst int srcheight = srcrect.get_height();\n\t\tconst int dstwidth = destrect.get_width();\n\t\tconst int dstheight = destrect.get_height();\n\t\tif( dstwidth > srcwidth || dstheight > srcheight ) return;\n\t\tint maxwidth = srcwidth > dstwidth ? srcwidth : dstwidth;\n\t\tint maxheight = srcheight > dstheight ? srcheight : dstheight;\n\t\tint threadNum = 1;\n\t\tint pixelNum = maxwidth*maxheight;\n\t\tif( pixelNum >= 50 * 500 ) {\n\t\t\tthreadNum = TVPGetThreadNum();\n\t\t}\n\t\tif( threadNum == 1 ) { // ʐςȂXbh1̎͂̂܂܎s\n\t\t\tResampleAreaAvg( clip, blendfunc, dest, destrect, src, srcrect );\n\t\t\treturn;\n\t\t}\n\t\tAxisParamCalculateAxisAreaAvg( paramx_, 0, srcwidth, srcwidth, dstwidth );\n\t\tAxisParamCalculateAxisAreaAvg( paramy_, srcrect.top, srcrect.bottom, srcheight, dstheight );\n\t\tResampleImageMT( clip, blendfunc, dest, destrect, src, srcrect, threadNum );\n\t}\n};\n\nvoid TJS_USERENTRY ResamplerFunc( void* p ) {\n\tResampler::ThreadParameter* param = (Resampler::ThreadParameter*)p;\n\tconst int width = param->width_;\n#ifdef _DEBUG\n\tstd::vector<tjs_uint32> work(width);\n#else\n\tstd::vector<tjs_uint32> work;\n\twork.reserve( width );\n#endif\n\n\tiTVPBaseBitmap* dest = param->dest_;\n\tconst tTVPRect& destrect = *param->destrect_;\n\tconst iTVPBaseBitmap* src = param->src_;\n\tconst tTVPRect& srcrect = *param->srcrect_;\n\n\tconst int srcwidth = srcrect.get_width();\n\tconst int dstwidth = destrect.get_width();\n\tconst int dstheight = destrect.get_height();\n\tconst float* wstarty = param->wstarty_;\n\ttjs_uint32* workbits = &work[0];\n\ttjs_int dststride = dest->GetPitchBytes()/(int)sizeof(tjs_uint32);\n\ttjs_uint32* dstbits = (tjs_uint32*)dest->GetScanLineForWrite(param->start_+destrect.top) + param->clip_->dst_left_;\n\tif( param->blendfunc_ == NULL ) {\n\t\tfor( int y = param->start_; y < param->end_; y++ ) {\n\t\t\tparam->sampler_->samplingVertical( y, workbits, dstheight, srcwidth, src, srcrect, wstarty );\n\t\t\tparam->sampler_->samplingHorizontal( dstbits, param->clip_->offsetx_, param->clip_->width_, workbits );\n\t\t\tdstbits += dststride;\n\t\t}\n\t} else {\t// PRs[ȊO\n#ifdef _DEBUG\n\t\tstd::vector<tjs_uint32> dstwork(param->clip_->getDestWidth());\n#else\n\t\tstd::vector<tjs_uint32> dstwork;\n\t\tdstwork.reserve( param->clip_->getDestWidth() );\n#endif\n\t\ttjs_uint32* midbits = &dstwork[0];\t// rpobt@\n\t\tfor( int y = param->start_; y < param->end_; y++ ) {\n\t\t\tparam->sampler_->samplingVertical( y, workbits, dstheight, srcwidth, src, srcrect, wstarty );\n\t\t\tparam->sampler_->samplingHorizontal( midbits, param->clip_->offsetx_, param->clip_->width_, workbits ); // ꎞobt@ɂ܂Rs[, ͈͊O͏Ȃ\n\t\t\t(*param->blendfunc_)( dstbits, midbits, param->clip_->getDestWidth() );\n\t\t\tdstbits += dststride;\n\t\t}\n\t}\n}\n\nvoid TVPBicubicResample(const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect, float sharpness) {\n\tBicubicWeight weightfunc(sharpness);\n\tResampler sampler;\n\tsampler.ResampleMT( clip, blendfunc, dest, destrect, src, srcrect, BicubicWeight::RANGE, weightfunc );\n}\nvoid TVPAreaAvgResample(const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect) {\n\tResampler sampler;\n\tsampler.ResampleAreaAvgMT( clip, blendfunc, dest, destrect, src, srcrect );\n}\ntemplate<typename TWeightFunc>\nvoid TVPWeightResample(const tTVPResampleClipping &clip, const tTVPImageCopyFuncBase* blendfunc, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect) {\n\tTWeightFunc weightfunc;\n\tResampler sampler;\n\tsampler.ResampleMT( clip, blendfunc, dest, destrect, src, srcrect, TWeightFunc::RANGE, weightfunc );\n}\n\n/**\n * gk\n * @param dest : ݐ摜\n * @param destrect : ݐ`\n * @param src : ǂݍ݌摜\n * @param srcrect : ǂݍ݌`\n * @param type : gktB^^Cv\n * @param typeopt : gktB^^CvIvV\n * @param method : uh@\n * @param opa : sx\n * @param hda : ݐAt@ێ\n */\nvoid TVPResampleImage( const tTVPRect &cliprect, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\ttTVPBBStretchType type, tjs_real typeopt, tTVPBBBltMethod method, tjs_int opa, bool hda ) {\n\t// NbsO\n\ttTVPResampleClipping clip;\n\tclip.setClipping( cliprect, destrect );\n\tif( clip.getDestWidth() <= 0 || clip.getDestHeight() <= 0 ) return;\n\n\t// uh֐o^\n\ttTVPImageCopyFuncBase* func = NULL;\n\tif( hda || opa != 255 || method != bmCopy ) {\n\t\ttTVPBlendParameter blendparam( method, opa, hda );\n\t\tblendparam.setFunctionFromParam();\n\t\tif( blendparam.blend_func ) {\n\t\t\tfunc = new tTVPBlendImageFunc(blendparam.opa_,blendparam.blend_func);\n\t\t} else if( blendparam.copy_func ) {\n\t\t\tfunc = new tTVPCopyImageFunc(blendparam.copy_func);\n\t\t}\n\t}\n\n\ttry {\n#if 0\n\t\ttjs_uint32 CpuFeature = TVPGetCPUType();\n\t\tif( (CpuFeature & TVP_CPU_HAS_AVX2) ) {\n\t\t\tTVPResampleImageAVX2( clip, func, dest, destrect, src, srcrect, type, typeopt );\n\t\t} else if( (CpuFeature & TVP_CPU_HAS_SSE2) ) {\n\t\t\tTVPResampleImageSSE2( clip, func, dest, destrect, src, srcrect, type, typeopt );\n\t\t} else\n#endif\n\t\t{\n\t\t\t // Co[W͌Œ菬_łȂBxȂB\n\t\t\tswitch( type ) {\n\t\t\tcase stLinear:\n\t\t\t\tTVPWeightResample<BilinearWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stCubic:\n\t\t\t\tTVPBicubicResample(clip, func, dest, destrect, src, srcrect, (float)typeopt );\n\t\t\t\tbreak;\n\t\t\tcase stLanczos2:\n\t\t\t\tTVPWeightResample<LanczosWeight<2> >(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stLanczos3:\n\t\t\t\tTVPWeightResample<LanczosWeight<3> >(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stSpline16:\n\t\t\t\tTVPWeightResample<Spline16Weight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stSpline36:\n\t\t\t\tTVPWeightResample<Spline36Weight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stAreaAvg:\n\t\t\t\tTVPAreaAvgResample(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stGaussian:\n\t\t\t\tTVPWeightResample<GaussianWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stBlackmanSinc:\n\t\t\t\tTVPWeightResample<BlackmanSincWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stSemiFastLinear:\n\t\t\t\tTVPWeightResample<BilinearWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastCubic:\n\t\t\t\tTVPBicubicResample(clip, func, dest, destrect, src, srcrect, (float)typeopt );\n\t\t\t\tbreak;\n\t\t\tcase stFastLanczos2:\n\t\t\t\tTVPWeightResample<LanczosWeight<2> >(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastSpline16:\n\t\t\t\tTVPWeightResample<Spline16Weight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastLanczos3:\n\t\t\t\tTVPWeightResample<LanczosWeight<3> >(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastSpline36:\n\t\t\t\tTVPWeightResample<Spline36Weight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastAreaAvg:\n\t\t\t\tTVPAreaAvgResample(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastGaussian:\n\t\t\t\tTVPWeightResample<GaussianWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tcase stFastBlackmanSinc:\n\t\t\t\tTVPWeightResample<BlackmanSincWeight>(clip, func, dest, destrect, src, srcrect );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow L\"Not supported yet.\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} catch(...) {\n\t\tif( func ) delete func;\n\t\tthrow;\n\t}\n\tif( func ) delete func;\n}\n"
  },
  {
    "path": "src/core/visual/gl/ResampleImage.h",
    "content": "/******************************************************************************/\n/**\n * gk\n * ----------------------------------------------------------------------------\n * \tCopyright (C) T.Imoto <http://www.kaede-software.com>\n * ----------------------------------------------------------------------------\n * @author\t\tT.Imoto\n * @date\t\t2014/04/02\n * @note\n *****************************************************************************/\n\n\n#ifndef __RESAMPLE_IMAGE_H__\n#define __RESAMPLE_IMAGE_H__\n\nextern void TVPResampleImage( const tTVPRect &cliprect, iTVPBaseBitmap *dest, const tTVPRect &destrect, const iTVPBaseBitmap *src, const tTVPRect &srcrect,\n\ttTVPBBStretchType type, tjs_real typeopt, tTVPBBBltMethod method, tjs_int opa, bool hda );\n\n#endif // __RESAMPLE_IMAGE_H__\n\n"
  },
  {
    "path": "src/core/visual/gl/ResampleImageInternal.h",
    "content": "/******************************************************************************/\n/**\n * gkgpwb_\n * ----------------------------------------------------------------------------\n * \tCopyright (C) T.Imoto <http://www.kaede-software.com>\n * ----------------------------------------------------------------------------\n * @author\t\tT.Imoto\n * @date\t\t2014/04/04\n * @note\n *****************************************************************************/\n\n\n#ifndef __RESAMPLE_IMAGE_INTERNAL_H__\n#define __RESAMPLE_IMAGE_INTERNAL_H__\n\nstruct tTVPImageCopyFuncBase {\n\tvirtual ~tTVPImageCopyFuncBase() {}\n\tvirtual void operator() ( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) const = 0;\n};\nstruct tTVPBlendImageFunc : public tTVPImageCopyFuncBase {\n\ttjs_int opa_;\n\tvoid (*blend_func_)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa);\n\n\ttTVPBlendImageFunc( tjs_int opa, void (*blend_func)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa) )\n\t: opa_(opa), blend_func_(blend_func) {}\n\n\tvirtual void operator() ( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) const {\n\t\tblend_func_( dest, src, len, opa_ );\n\t}\n};\nstruct tTVPCopyImageFunc : public tTVPImageCopyFuncBase {\n\tvoid (*copy_func_)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len);\n\n\ttTVPCopyImageFunc( void (*copy_func)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len) )\n\t: copy_func_(copy_func) {}\n\n\tvirtual void operator() ( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) const {\n\t\tcopy_func_( dest, src, len );\n\t}\n};\n/**\n * uhp[^\n * uh֐|C^͊gklȂ\n */\nstruct tTVPBlendParameter {\n\t/** uh */\n\ttTVPBBBltMethod method_;\n\t/** sx */\n\ttjs_int opa_;\n\t/** ]At@ێL */\n\tbool hda_;\n\t/** sxlăuh */\n\tvoid (*blend_func)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa);\n\t/** Rs[(\\[XfXeBl[ṼAt@lꍇ) */\n\tvoid (*copy_func)(tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len);\n\n\ttTVPBlendParameter() : method_(bmCopy), opa_(255), hda_(false), blend_func(NULL), copy_func(NULL) {}\n\ttTVPBlendParameter( tTVPBBBltMethod method, tjs_int opa, bool hda ) : method_(method), opa_(opa), hda_(hda), blend_func(NULL), copy_func(NULL) {}\n\n\t/**\n\t * p[^Ɋ֐|C^肷\n\t */\n\tvoid setFunctionFromParam();\n};\n/**\n * NbsOp[^\n */\nstruct tTVPResampleClipping {\n\ttjs_int offsetx_;\t// NbsO鍶[\n\ttjs_int offsety_;\t// NbsO[\n\ttjs_int width_;\t\t// Rs[Aoffsetx_܂ł\n\ttjs_int height_;\t// Rs[Aoffsety_܂ł\n\ttjs_int dst_left_;\t// ۂ̃Rs[捶[\n\ttjs_int dst_top_;\t// ۂ̃Rs[[\n\n\tvoid setClipping( const tTVPRect &cliprect, const tTVPRect &destrect );\n\n\t/** ۂɃRs[镝 */\n\tinline tjs_int getDestWidth() const { return width_ - offsetx_; }\n\t/** ۂɃRs[鍂 */\n\tinline tjs_int getDestHeight() const { return height_ - offsety_; }\n};\n\n\n/**\n * ʐϕσp[^p\n */\ntemplate<typename TVector>\nvoid TVPCalculateAxisAreaAvg( int srcstart, int srcend, int srclength, int dstlength, std::vector<int>& start, std::vector<int>& length, TVector& weight ) {\n\tstart.clear();\n\tstart.reserve( dstlength );\n\tlength.clear();\n\tlength.reserve( dstlength );\n\tweight.clear();\n\tint wlength = srclength + dstlength;\n\tweight.reserve( wlength );\n\tint delta = 0;\n\tint srctarget = srclength;\n\tint len = 0;\n\tstart.push_back( 0 );\n\tfor( int x = 0; x < srclength; x++ ) {\n\t\tif( (delta + dstlength) <= srctarget ) {\t// EɒBĂȂ\n\t\t\tweight.push_back( 1.0f );\n\t\t\tlen++;\n\t\t} else { // E܂\n\t\t\tint d = (delta + dstlength) - srctarget;\n\t\t\tweight.push_back( (float)(dstlength - d) / (float)dstlength ); // Ö̗\n\t\t\tlength.push_back( len+1 );\n\n\t\t\tstart.push_back( x );\n\t\t\tlen = 1;\n\t\t\tweight.push_back( (float)d / (float)dstlength );\n\t\t\tsrctarget += srclength;\n\t\t}\n\t\tdelta += dstlength;\n\t}\n\tlength.push_back( len );\n}\n\n/**\n * ʐϕσp[^Kp\n */\ntemplate<typename TVector>\nvoid TVPNormalizeAxisAreaAvg( std::vector<int>& length, TVector& weight ) {\n\t// K\n\tconst int count = (const int)length.size();\n\tfloat* wstart = &weight[0];\n\tfor( int i = 0; i < count; i++ ) {\n\t\tint len = length[i];\n\t\t// vl߂\n\t\tfloat* w = wstart;\n\t\tfloat sum = 0.0f;\n\t\tfor( int j = 0; j < len; j++ ) {\n\t\t\tsum += *w;\n\t\t\tw++;\n\t\t}\n\n\t\t// EPSILON 菬ꍇ 0 ݒ\n\t\tfloat rcp;\n\t\tif( sum < FLT_EPSILON ) {\n\t\t\trcp = 0.0f;\n\t\t} else {\n\t\t\trcp = 1.0f / sum;\n\t\t}\n\t\t// K\n\t\tw = wstart;\n\t\tfor( int i = 0; i < len; i++ ) {\n\t\t\t*w *= rcp;\n\t\t\tw++;\n\t\t}\n\t\twstart = w;\n\t}\n}\n\n#endif // __RESAMPLE_IMAGE_INTERNAL_H__\n"
  },
  {
    "path": "src/core/visual/gl/WeightFunctor.cpp",
    "content": "/******************************************************************************/\n/**\n * etB^[̃EFCgvZ\n * ----------------------------------------------------------------------------\n * \tCopyright (C) T.Imoto <http://www.kaede-software.com>\n * ----------------------------------------------------------------------------\n * @author\t\tT.Imoto\n * @date\t\t2014/04/02\n * @note\n *****************************************************************************/\n\n\n#define _USE_MATH_DEFINES\n#include \"tjsCommHead.h\"\n\n#include <float.h>\n#include <math.h>\n#include <cmath>\n\n#include \"WeightFunctor.h\"\n\nconst float BilinearWeight::RANGE = 1.0f;\nconst float BicubicWeight::RANGE = 2.0f;\nconst float Spline16Weight::RANGE = 2.0f;\nconst float Spline36Weight::RANGE = 3.0f;\nconst float GaussianWeight::RANGE = 2.0f;\nconst float BlackmanSincWeight::RANGE = 4.0f;\n"
  },
  {
    "path": "src/core/visual/gl/WeightFunctor.h",
    "content": "/******************************************************************************/\n/**\n * etB^[̃EFCgvZ\n * ----------------------------------------------------------------------------\n * \tCopyright (C) T.Imoto <http://www.kaede-software.com>\n * ----------------------------------------------------------------------------\n * @author\t\tT.Imoto\n * @date\t\t2014/04/02\n * @note\n *****************************************************************************/\n\n\n#ifndef __WEIGHT_FUNCTOR_H__\n#define __WEIGHT_FUNCTOR_H__\n\n/**\n * oCjA\n */\nstruct BilinearWeight {\n\tstatic const float RANGE;\n\tinline float operator()( float distance ) const {\n\t\tfloat x = std::abs(distance);\n\t\tif( x < 1.0f ) {\n\t\t\treturn 1.0f - x;\n\t\t} else {\n\t\t\treturn 0.0f;\n\t\t}\n\t}\n};\n\n/**\n * oCL[rbN\n */\nstruct BicubicWeight {\n\tstatic const float RANGE;\n\n\tfloat coeff;\n\tfloat p[5];\n\t/**\n\t * @param c : V[vBȂɂċȂ\n\t */\n\tBicubicWeight( float c = -1 ) : coeff(c) {\n\t\tp[0] = coeff + 3.0f;\n\t\tp[1] = coeff + 2.0f;\n\t\tp[2] = -coeff*4.0f;\n\t\tp[3] = coeff*8.0f;\n\t\tp[4] = coeff*5.0f;\n\t}\n\tinline float operator()( float distance ) const {\n\t\tfloat x = std::abs(distance);\n\t\tif( x <= 1.0f ) {\n\t\t\treturn 1.0f - p[0]*x*x + p[1]*x*x*x;\n\t\t} else if( x <= 2.0f ) {\n\t\t\treturn p[2] + p[3]*x - p[4]*x*x + coeff*x*x*x;\n\t\t} else {\n\t\t\treturn 0.0f;\n\t\t}\n\t}\n};\n\n/**\n * Lanczos\n */\ntemplate<int TTap>\nstruct LanczosWeight {\n\tstatic const float RANGE;\n\tinline float operator()( float distance ) {\n\t\tfloat x = std::abs(distance);\n\t\tif( x < FLT_EPSILON ) return 1.0f;\n\t\tif( x >= (float)TTap ) return 0.0f;\n\t\treturn std::sin((float)M_PI*distance)*std::sin((float)M_PI*distance/TTap)/((float)M_PI*(float)M_PI*distance*distance/TTap);\n\t}\n};\ntemplate<int TTap>\nconst float LanczosWeight<TTap>::RANGE = (float)TTap;\n\n/**\n * Spline16 pEFCg֐\n */\nstruct Spline16Weight {\n\tstatic const float RANGE;\n\tinline float operator()( float distance ) const {\n\t\tfloat x = std::abs(distance);\n\t\tif( x <= 1.0f ) {\n\t\t\treturn  x*x*x           - x*x*9.0f/5.0f - x* 1.0f/ 5.0f + 1.0f;\n\t\t} else if( x <= 2.0f ) {\n\t\t\treturn -x*x*x*1.0f/3.0f + x*x*9.0f/5.0f - x*46.0f/15.0f + 8.0f/5.0f;\n\t\t} else {\n\t\t\treturn 0.0f;\n\t\t}\n\t}\n};\n\n/**\n * Spline36 pEFCg֐\n */\nstruct Spline36Weight {\n\tstatic const float RANGE;\n\tinline float operator()( float distance ) const {\n\t\tfloat x = std::abs(distance);\n\t\tif( x <= 1.0f ) {\n\t\t\treturn  x*x*x*13.0f/11.0f - x*x*453.0f/209.0f - x*   3.0f/209.0f + 1.0f;\n\t\t} else if( x <= 2.0f ) {\n\t\t\treturn -x*x*x* 6.0f/11.0f + x*x*612.0f/209.0f - x*1038.0f/209.0f + 540.0f/209.0f;\n\t\t} else if( x <= 3.0f ) {\n\t\t\treturn  x*x*x* 1.0f/11.0f - x*x*159.0f/209.0f + x* 434.0f/209.0f - 384.0f/209.0f;\n\t\t} else {\n\t\t\treturn 0.0f;\n\t\t}\n\t}\n};\n/**\n * KEX֐\n */\nstruct GaussianWeight {\n\tstatic const float RANGE;\n\tfloat sq2pi;\n\tGaussianWeight() : sq2pi( std::sqrt( 2.0f/(float)M_PI ) ) {\n\t}\n\tinline float operator()( float distance ) const {\n\t\tfloat x = distance;\n\t\treturn std::exp( (float)(-2.0f*x*x) ) * sq2pi;\n\t}\n};\n\n/**\n * Blackman-Sinc ֐\n * Blackman(x) = 0.42 - 0.5 cos( 2 pi x ) + 0.08 cos( 4 pi x ); if 0 <= x <= 1\n * Sinc(x) = sin( pi x ) / (pi x)\n */\nstruct BlackmanSincWeight {\n\tstatic const float RANGE;\n\tfloat coeff;\n\tBlackmanSincWeight( float c = RANGE ) : coeff(1.0f/c) {}\n\tinline float operator()( float distance ) const {\n\t\tfloat x = std::abs(distance);\n\t\tif( x < FLT_EPSILON ) {\n\t\t\treturn 1.0f;\n\t\t} else {\n\t\t\treturn (0.42f + 0.5f*std::cos( (float)M_PI*x*coeff ) + 0.08f*std::cos( 2.0f*(float)M_PI*x*coeff )) *\n\t\t\t\t(std::sin( (float)M_PI*x ) / ((float)M_PI*x));\n\t\t}\n\t}\n};\n\n#endif // __WEIGHT_FUNCTOR_H__\n"
  },
  {
    "path": "src/core/visual/gl/aligned_allocator.h",
    "content": " \n\n#ifndef __ALIGNED_ALLOCATOR_H__\n#define __ALIGNED_ALLOCATOR_H__\n\n// #include <intrin.h>\n#include <malloc.h>\t\t// _aligned_malloc and _aligned_free\n#include <memory>\t\t// std::allocator\n\n\n// #if defined( _M_IX86 ) || defined( _M_X64 )\n// STL allocator\ntemplate< class T, int TAlign=16 >\nstruct aligned_allocator : public std::allocator<T>\n{\n    typedef size_t\tsize_type;\n    typedef T*\t\tpointer;\n\tstatic const int ALIGN_SIZE = TAlign;\n\ttemplate <class U> struct rebind    { typedef aligned_allocator<U,TAlign> other; };\n\taligned_allocator() throw() {}\n\taligned_allocator(const aligned_allocator&) throw () {}\n\ttemplate <class U> aligned_allocator(const aligned_allocator<U, TAlign>&) throw() {}\n\ttemplate <class U> aligned_allocator& operator=(const aligned_allocator<U, TAlign>&) throw()  {}\n\t// allocate\n\tpointer allocate(size_type c, const void* hint = 0) {\n\t\treturn static_cast<pointer>( ::memalign( sizeof(T)*c, TAlign ) );\n\t}\n\t// deallocate\n\tvoid deallocate(pointer p, size_type n) {\n\t\t::free( p );\n\t}\n};\n\n\n#endif // __ALIGNED_ALLOCATOR_H__\n"
  },
  {
    "path": "src/core/visual/gl/blend_function.cpp",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n/******************************************************************************/\n/**\n * ev[gx[XGL\n * @note\t\t] TVP GL u\n *****************************************************************************/\n\n#define TVPPS_USE_OVERLAY_TABLE\n\n#include <math.h>\n#include <string.h>\n\n#include \"tjsTypes.h\"\n#include \"tvpgl.h\"\n\n#include \"tjsTypes.h\"\n#include \"tvpgl.h\"\n//#include \"tvpgl_ia32_intf.h\"\n#include \"tvpgl_mathutil.h\"\n\nextern \"C\" {\nextern unsigned char TVPDivTable[256*256];\nextern unsigned char TVPOpacityOnOpacityTable[256*256];\nextern unsigned char TVPNegativeMulTable[256*256];\nextern unsigned char TVPOpacityOnOpacityTable65[65*256];\nextern unsigned char TVPNegativeMulTable65[65*256];\nextern unsigned char TVPDitherTable_5_6[8][4][2][256];\nextern unsigned char TVPDitherTable_676[3][4][4][256];\nextern unsigned char TVP252DitherPalette[3][256];\nextern tjs_uint32 TVPRecipTable256[256];\nextern tjs_uint16 TVPRecipTable256_16[256];\n};\n\n#include \"blend_functor_c.h\"\n\n\nunsigned char ps_soft_light_table::TABLE[256][256];\nunsigned char ps_color_dodge_table::TABLE[256][256];\nunsigned char ps_color_burn_table::TABLE[256][256];\n#ifdef TVPPS_USE_OVERLAY_TABLE\nunsigned char ps_overlay_table::TABLE[256][256];\n#endif\n// ϊ\ntemplate<typename functor>\nstatic inline void convert_func_c( tjs_uint32 *dest, tjs_int len ) {\n\tfunctor func;\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i] );\n\t}\n}\ntemplate<typename functor>\nstatic inline void convert_func_c( tjs_uint32 *dest, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i] );\n\t}\n}\n\n// uhRs[\ntemplate<typename functor>\nstatic inline void copy_func_c( tjs_uint32 * __restrict dest, const tjs_uint32 * __restrict src, tjs_int len ) {\n\tfunctor func;\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\ntemplate<typename functor>\nstatic inline void blend_func_c( tjs_uint32 * __restrict dest, const tjs_uint32 * __restrict src, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\n// 8bit\ntemplate<typename functor>\nstatic inline void blend_func_c( tjs_uint8 * __restrict dest, const tjs_uint8 * __restrict src, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\n// src  dest dĂ\\̂\ntemplate<typename functor>\nstatic inline void overlap_blend_func_c( tjs_uint32 * dest, const tjs_uint32 * src, tjs_int len, const functor& func ) {\n\tconst tjs_uint32 *src_end = src + len;\n\tif( dest > src && dest < src_end ) {\n\t\t// backward I[o[bv̂Ō납Rs[\n\t\tlen--;\n\t\twhile( len >= 0 ) {\n\t\t\tdest[len] = func( dest[len], src[len] );\n\t\t\tlen--;\n\t\t}\n\t} else {\n\t\t// forward\n\t\tblend_func_c<functor>( dest, src, len, func );\n\t}\n}\ntemplate<typename functor>\nstatic void overlap_copy_func_c( tjs_uint32 * dest, const tjs_uint32 * src, tjs_int len ) {\n\tfunctor func;\n\toverlap_blend_func_c<functor>( dest, src, len, func );\n}\n// dest = src1 * src2 ƂȂĂ\ntemplate<typename functor>\nstatic inline void sd_blend_func_c( tjs_uint32 *__restrict dest, const tjs_uint32 * __restrict src1, const tjs_uint32 * __restrict src2, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( src1[i], src2[i] );\n\t}\n}\n// ɕ`掞ɃAt@lƐFgĕ`s\ntemplate<typename functor>\nstatic inline void apply_color_map_o_func_c( tjs_uint32 * __restrict dest, const tjs_uint8 * __restrict src, tjs_int len, tjs_uint32 color, tjs_int opa ) {\n\tfunctor func(color,opa);\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\ntemplate<typename functor>\nstatic inline void apply_color_map_func_c( tjs_uint32 * __restrict dest, const tjs_uint8 * __restrict src, tjs_int len, tjs_uint32 color ) {\n\tfunctor func(color);\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\n\ntemplate<typename functor>\nstatic inline void alpha_convert_func_c( tjs_uint32 * __restrict dest, const tjs_uint8 * __restrict src, tjs_int len ) {\n\tfunctor func;\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\ntemplate<typename functor>\nstatic inline void alpha_convert_func_c( tjs_uint32 * __restrict dest, const tjs_uint8 * __restrict src, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i], src[i] );\n\t}\n}\n\n\n#define DEFINE_CONVERT_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, tjs_int len ) {\t\\\n\tconvert_func_c<FUNC##_functor>( dest, len );\t\t\t\\\n}\n#define DEFINE_CONVERT_BLEND_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tconvert_func_c<FUNC##_functor>( dest, len, func );\t\t\t\t\t\t\\\n}\n#define DEFINE_ALPHA_COPY_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len ) {\t\\\n\talpha_convert_func_c<FUNC##_functor>( dest, src, len );\t\t\t\t\t\t\t\\\n}\n#define DEFINE_ALPHA_BLEND_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\talpha_convert_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n\n#define DEFINE_BLEND_FUNCTION_VARIATION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_HDA_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_o( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\t\\\n\tFUNC##_o_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA_o( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_HDA_o_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_d( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_d_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_a( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_a_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_do( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\t\\\n\tFUNC##_do_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_ao( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\t\\\n\tFUNC##_ao_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n\n#define DEFINE_BLEND_FUNCTION_MIN_VARIATION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\t\t\t\t\\\n\tcopy_func_c<FUNC##_HDA_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_o( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\t\\\n\tFUNC##_o_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA_o( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_HDA_o_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\n#define DEFINE_SD_BLEND_FUNCTION( FUNC )\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_SD(tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa){\t\\\n\tFUNC##_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tsd_blend_func_c( dest, src1, src2, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n#define DEFINE_OVERLAP_COPY( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\\\n\toverlap_copy_func_c<FUNC##_functor>( dest, src, len );\t\t\t\t\t\t\t\\\n}\n#define DEFINE_COPY_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len ) {\t\\\n\tcopy_func_c<FUNC##_functor>( dest, src, len );\t\t\t\t\t\t\t\t\t\\\n}\n#define DEFINE_BLEND_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n#define DEFINE_BLEND8_FUNCTION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa ) {\t\\\n\tFUNC##_functor func(opa);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tblend_func_c( dest, src, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n// ȉ2̓_~[\nstruct premulalpha_blend_d_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { return 0; }\n};\nstruct premulalpha_blend_do_functor {\n\tinline premulalpha_blend_do_functor( tjs_int opa ){}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { return 0; }\n};\n// ȉ2͎Ȃ\n// TVPAdditiveAlphaBlend_d_c\n// TVPAdditiveAlphaBlend_do_c\n\n#define DEFINE_COLOR_COPY( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, tjs_int len, tjs_uint32 value ) {\t\\\n\tFUNC##_functor func( value );\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tconst_color_copy( dest, len, func );\t\t\t\t\t\t\t\t\t\t\\\n}\n\n#define DEFINE_COLOR_BLEND( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, tjs_int len, tjs_uint32 value, tjs_int opa ) {\t\\\n\tFUNC##_functor func( opa, value );\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tconst_color_copy( dest, len, func );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n\n#define DEFINE_APPLY_FUNCTION_VARIATION( FUNC ) \\\nstatic void TVP_##FUNC( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color ) {\t\t\t\t\t\t\\\n\tapply_color_map_func_c<FUNC##_functor>( dest, src, len, color );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color ) {\t\t\t\t\t\\\n\tapply_color_map_func_c<FUNC##_HDA_functor>( dest, src, len, color );\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_o( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa ) {\t\t\\\n\tapply_color_map_o_func_c<FUNC##_o_functor>( dest, src, len, color, opa );\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_HDA_o( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa ) {\t\\\n\tapply_color_map_o_func_c<FUNC##_HDA_o_functor>( dest, src, len, color, opa );\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_d( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color ) {\t\t\t\t\t\\\n\tapply_color_map_func_c<FUNC##_d_functor>( dest, src, len, color );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_a( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color ) {\t\t\t\t\t\\\n\tapply_color_map_func_c<FUNC##_a_functor>( dest, src, len, color );\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_do( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa ) {\t\t\\\n\tapply_color_map_o_func_c<FUNC##_do_functor>( dest, src, len, color, opa );\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void TVP_##FUNC##_ao( tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa ) {\t\t\\\n\tapply_color_map_o_func_c<FUNC##_ao_functor>( dest, src, len, color, opa );\t\t\t\t\t\t\t\t\t\t\t\\\n}\n\nDEFINE_CONVERT_BLEND_FUNCTION( remove_const_opacity );\nDEFINE_ALPHA_COPY_FUNCTION( remove_opacity );\nDEFINE_ALPHA_COPY_FUNCTION( remove_opacity65 );\nDEFINE_ALPHA_BLEND_FUNCTION( remove_opacity_o );\nDEFINE_ALPHA_BLEND_FUNCTION( remove_opacity65_o );\n\nDEFINE_OVERLAP_COPY( color_copy );\nDEFINE_OVERLAP_COPY( alpha_copy );\nDEFINE_COPY_FUNCTION( color_opaque );\n\nDEFINE_BLEND_FUNCTION( const_alpha_blend );\nDEFINE_BLEND_FUNCTION( const_alpha_blend_hda );\nDEFINE_BLEND_FUNCTION( const_alpha_blend_d );\nDEFINE_BLEND_FUNCTION( const_alpha_blend_a );\n\nDEFINE_SD_BLEND_FUNCTION( const_alpha_blend );\nDEFINE_SD_BLEND_FUNCTION( sd_const_alpha_blend_a );\nDEFINE_SD_BLEND_FUNCTION( sd_const_alpha_blend_d );\n\nDEFINE_APPLY_FUNCTION_VARIATION( apply_color_map65 )\nDEFINE_APPLY_FUNCTION_VARIATION( apply_color_map )\n\nDEFINE_BLEND8_FUNCTION( ch_blur_mul_copy65 );\nDEFINE_BLEND8_FUNCTION( ch_blur_mul_copy );\nDEFINE_BLEND8_FUNCTION( ch_blur_add_mul_copy65 );\nDEFINE_BLEND8_FUNCTION( ch_blur_add_mul_copy );\n\nDEFINE_COLOR_COPY( fill_argb );\nDEFINE_COLOR_COPY( const_color_copy );\nDEFINE_COLOR_COPY( const_alpha_copy );\nDEFINE_COLOR_BLEND( const_alpha_fill_blend );\nDEFINE_COLOR_BLEND( const_alpha_fill_blend_d );\nDEFINE_COLOR_BLEND( const_alpha_fill_blend_a );\n\nDEFINE_BLEND_FUNCTION_VARIATION( alpha_blend );\nDEFINE_BLEND_FUNCTION_VARIATION( premulalpha_blend )\n\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( add_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( sub_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( mul_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( color_dodge_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( darken_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( lighten_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( screen_blend );\n\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_alpha_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_add_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_sub_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_mul_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_screen_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_soft_light_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_color_dodge_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_color_burn_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_overlay_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_hard_light_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_color_dodge5_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_lighten_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_darken_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_diff_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_diff5_blend );\nDEFINE_BLEND_FUNCTION_MIN_VARIATION( ps_exclusion_blend );\n\nstatic void TVP_make_alpha_from_key(tjs_uint32 *dest, tjs_int len, tjs_uint32 key) {\n\tmake_alpha_from_key_functor func(key);\n\tconvert_func_c( dest, len, func );\n}\nstatic void TVP_alpha_color_mat(tjs_uint32 *dest, tjs_uint32 color, tjs_int len ) {\n\talpha_color_mat_functor func(color);\n\tconvert_func_c( dest, len, func );\n}\nDEFINE_CONVERT_FUNCTION( convet_premulalpha_to_alpha );\nDEFINE_CONVERT_FUNCTION( convet_alpha_to_premulalpha );\nDEFINE_ALPHA_COPY_FUNCTION( bind_mask_to_main );\nDEFINE_CONVERT_FUNCTION( do_gray_scale );\n\n/* simple blur for character data */\n/* shuld be more optimized */\ntemplate<typename functor>\nstatic inline void ch_blur_copy_func( tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel ) {\n\t/* clear destination */\n\tmemset(dest, 0, destpitch*destheight);\n\n\t/* compute filter level */\n\ttjs_int lvsum = 0;\n\tfor(tjs_int y = -blurwidth; y <= blurwidth; y++) {\n\t\tfor(tjs_int x = -blurwidth; x <= blurwidth; x++) {\n\t\t\ttjs_int len = fast_int_hypot(x, y);\n\t\t\tif(len <= blurwidth)\n\t\t\t\tlvsum += (blurwidth - len +1);\n\t\t}\n\t}\n\n\tif(lvsum) lvsum = (1<<18)/lvsum; else lvsum=(1<<18);\n\n\t/* apply */\n\tfor(tjs_int y = -blurwidth; y <= blurwidth; y++) {\n\t\tfor(tjs_int x = -blurwidth; x <= blurwidth; x++) {\n\t\t\ttjs_int len = fast_int_hypot(x, y);\n\t\t\tif(len <= blurwidth) {\n\t\t\t\tlen = blurwidth - len +1;\n\t\t\t\tlen *= lvsum;\n\t\t\t\tlen *= blurlevel;\n\t\t\t\tlen >>= 8;\n\t\t\t\tfunctor func(len);\n\t\t\t\tfor(tjs_int sy = 0; sy < srcheight; sy++) {\n\t\t\t\t\tblend_func_c( dest + (y + sy + blurwidth)*destpitch + x + blurwidth, src + sy * srcpitch, srcwidth, func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\nvoid TVP_ch_blur_copy65( tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel ) {\n\tch_blur_copy_func<ch_blur_add_mul_copy65_functor>( dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel );\n}\nvoid TVP_ch_blur_copy( tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel ) {\n\tch_blur_copy_func<ch_blur_add_mul_copy_functor>( dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel );\n}\nvoid TVP_reverse32(tjs_uint32 *pixels, tjs_int len) {\n\ttjs_uint32 *pixels2 = pixels + len -1;\n\tlen/=2;\n\ttjs_uint32 *limit = pixels+len;\n\twhile( pixels < limit ) {\n\t\ttjs_uint32 tmp = *pixels;\n\t\t*pixels = *pixels2;\n\t\t*pixels2 = tmp;\n\t\tpixels2 --;\n\t\tpixels++;\n\t}\n}\nvoid TVP_reverse8( tjs_uint8 *pixels, tjs_int len ) {\n\ttjs_uint8 *pixels2 = pixels + len -1;\n\tlen/=2;\n\ttjs_uint8 *limit = pixels+len;\n\twhile( pixels < limit ) {\n\t\ttjs_uint8 tmp = *pixels;\n\t\t*pixels = *pixels2;\n\t\t*pixels2 = tmp;\n\t\tpixels2 --;\n\t\tpixels++;\n\t}\n}\nvoid TVP_swap_line32(tjs_uint32 *line1, tjs_uint32 *line2, tjs_int len) {\n\tfor( tjs_int i = 0; i < len; i++ ) {\n\t\ttjs_uint32 tmp = line1[i];\n\t\tline1[i] = line2[i];\n\t\tline2[i] = tmp;\n\t}\n}\nvoid TVP_swap_line8(tjs_uint8 *line1, tjs_uint8 *line2, tjs_int len)\n{\n\t#define swap_tmp_buf_size 256\n\ttjs_uint8 swap_tmp_buf[swap_tmp_buf_size];\n\twhile(len)\n\t{\n\t\ttjs_int le = len < swap_tmp_buf_size ? len : swap_tmp_buf_size;\n\t\tfor( tjs_int i = 0; i < le/4; i++ ) {\n\t\t}\n\t\tmemcpy(swap_tmp_buf, line1, le);\n\t\tmemcpy(line1, line2, le);\n\t\tmemcpy(line2, swap_tmp_buf, le);\n\t\tline1 += le;\n\t\tline2 += le;\n\t\tlen -= le;\n\t}\n\t#undef swap_tmp_buf_size\n}\n/* --------------------------------------------------------------------\n  Table initialize function\n-------------------------------------------------------------------- */\nstatic void TVPPsInitTable(void)\n{\n\tint s, d;\n\tfor (s=0; s<256; s++) {\n\t\tfor (d=0; d<256; d++) {\n\t\t\tps_soft_light_table::TABLE[s][d]  = (s>=128) ?\n\t\t\t\t( ((unsigned char)(pow(d/255.0, 128.0/s)*255.0)) ) :\n\t\t\t\t( ((unsigned char)(pow(d/255.0, (1.0-s/255.0)/0.5)*255.0)) );\n\t\t\tps_color_dodge_table::TABLE[s][d] = ((255-s)<=d) ? (0xff) : ((d*255)/(255-s));\n\t\t\tps_color_burn_table::TABLE[s][d]  = (s<=(255-d)) ? (0x00) : (255-((255-d)*255)/s);\n#ifdef TVPPS_USE_OVERLAY_TABLE\n\t\t\tps_overlay_table::TABLE[s][d]  = (d<128) ? ((s*d*2)/255) : (((s+d)*2)-((s*d*2)/255)-255);\n#endif\n\t\t}\n\t}\n}\n\n\n#define SET_BLEND_FUNCTIONS( DEST_FUNC, FUNC )\t\\\nTVP##DEST_FUNC = TVP_##FUNC;\t\t\t\t\t\\\nTVP##DEST_FUNC##_HDA = TVP_##FUNC##_HDA;\t\t\\\nTVP##DEST_FUNC##_o = TVP_##FUNC##_o;\t\t\t\\\nTVP##DEST_FUNC##_HDA_o = TVP_##FUNC##_HDA_o;\t\\\nTVP##DEST_FUNC##_d = TVP_##FUNC##_d;\t\t\t\\\nTVP##DEST_FUNC##_a = TVP_##FUNC##_a;\t\t\t\\\nTVP##DEST_FUNC##_do = TVP_##FUNC##_do;\t\t\t\\\nTVP##DEST_FUNC##_ao = TVP_##FUNC##_ao;\n\n#define SET_BLEND_MID_FUNCTIONS( DEST_FUNC, FUNC )\t\\\nTVP##DEST_FUNC = TVP_##FUNC;\t\t\t\t\t\\\nTVP##DEST_FUNC##_HDA = TVP_##FUNC##_HDA;\t\t\\\nTVP##DEST_FUNC##_o = TVP_##FUNC##_o;\t\t\t\\\nTVP##DEST_FUNC##_HDA_o = TVP_##FUNC##_HDA_o;\t\\\nTVP##DEST_FUNC##_d = TVP_##FUNC##_d;\t\t\t\\\nTVP##DEST_FUNC##_do = TVP_##FUNC##_do;\n\n#define SET_BLEND_MIN_FUNCTIONS( DEST_FUNC, FUNC )\t\\\nTVP##DEST_FUNC = TVP_##FUNC;\t\t\t\t\t\\\nTVP##DEST_FUNC##_HDA = TVP_##FUNC##_HDA;\t\t\\\nTVP##DEST_FUNC##_o = TVP_##FUNC##_o;\t\t\t\\\nTVP##DEST_FUNC##_HDA_o = TVP_##FUNC##_HDA_o;\n\n// dummy\nstatic void (*TVPAdditiveAlphaBlend_d)(tjs_uint32*,const tjs_uint32*,tjs_int);\nstatic void (*TVPAdditiveAlphaBlend_do)(tjs_uint32*,const tjs_uint32*,tjs_int,tjs_int);\n\nextern void TVP_ch_blur_add_mul_copy65_sse2_c( tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa );\nextern void TVP_ch_blur_add_mul_copy_sse2_c( tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa );\nextern void TVP_ch_blur_mul_copy65_sse2_c( tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa );\nextern void TVP_ch_blur_mul_copy_sse2_c( tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int opa );\n/**\n * GLB֐|C^ݒ肷\n */\nvoid TVPGL_C_Init() {\n\n\t// euh֐IuWFNg邱ƂŃAtBϊgkɓWJ₷\n\tSET_BLEND_FUNCTIONS( AlphaBlend, alpha_blend );\n\tSET_BLEND_FUNCTIONS( AdditiveAlphaBlend, premulalpha_blend );\n\tSET_BLEND_MIN_FUNCTIONS( AddBlend, add_blend );\n\tSET_BLEND_MIN_FUNCTIONS( SubBlend, sub_blend );\n\tSET_BLEND_MIN_FUNCTIONS( MulBlend, mul_blend );\n\tSET_BLEND_MIN_FUNCTIONS( ColorDodgeBlend, color_dodge_blend );\n\tSET_BLEND_MIN_FUNCTIONS( DarkenBlend, darken_blend );\n\tSET_BLEND_MIN_FUNCTIONS( LightenBlend, lighten_blend );\n\tSET_BLEND_MIN_FUNCTIONS( ScreenBlend, screen_blend );\n\n\tSET_BLEND_MIN_FUNCTIONS( PsAlphaBlend, ps_alpha_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsAddBlend, ps_add_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsSubBlend, ps_sub_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsMulBlend, ps_mul_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsScreenBlend, ps_screen_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsSoftLightBlend, ps_soft_light_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsColorDodgeBlend, ps_color_dodge_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsColorBurnBlend, ps_color_burn_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsOverlayBlend, ps_overlay_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsHardLightBlend, ps_hard_light_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsColorDodge5Blend, ps_color_dodge5_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsLightenBlend, ps_lighten_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsDarkenBlend, ps_darken_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsDiffBlend, ps_diff_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsDiff5Blend, ps_diff5_blend );\n\tSET_BLEND_MIN_FUNCTIONS( PsExclusionBlend, ps_exclusion_blend );\n\n\tTVPConstAlphaBlend = TVP_const_alpha_blend;\n\tTVPConstAlphaBlend_HDA = TVP_const_alpha_blend_hda;\n\tTVPConstAlphaBlend_d = TVP_const_alpha_blend_d;\n\tTVPConstAlphaBlend_a = TVP_const_alpha_blend_a;\n\n\tTVPConstAlphaBlend_SD =  TVP_const_alpha_blend_SD;\n\tTVPConstAlphaBlend_SD_a = TVP_sd_const_alpha_blend_a_SD;\n\tTVPConstAlphaBlend_SD_d = TVP_sd_const_alpha_blend_d_SD;\n\n\tTVPCopyColor = TVP_color_copy;\n\tTVPCopyMask = TVP_alpha_copy;\n\tTVPCopyOpaqueImage = TVP_color_opaque;\n\n\tTVPFillARGB = TVP_fill_argb;\n\tTVPFillARGB_NC = TVP_fill_argb;\n\tTVPFillColor = TVP_const_color_copy;\n\tTVPFillMask = TVP_const_alpha_copy;\n\n\tTVPConstColorAlphaBlend = TVP_const_alpha_fill_blend;\n\tTVPConstColorAlphaBlend_d = TVP_const_alpha_fill_blend_d;\n\tTVPConstColorAlphaBlend_a = TVP_const_alpha_fill_blend_a;\n\n\tTVPApplyColorMap65 = TVP_apply_color_map65;\n\tTVPApplyColorMap65_HDA = TVP_apply_color_map65_HDA;\n\tTVPApplyColorMap65_o = TVP_apply_color_map65_o;\n\tTVPApplyColorMap65_HDA_o = TVP_apply_color_map65_HDA_o;\n\tTVPApplyColorMap65_d = TVP_apply_color_map65_d;\n\tTVPApplyColorMap65_a = TVP_apply_color_map65_a;\n\tTVPApplyColorMap65_do = TVP_apply_color_map65_do;\n\tTVPApplyColorMap65_ao = TVP_apply_color_map65_ao;\n\n\tTVPApplyColorMap = TVP_apply_color_map;\n\tTVPApplyColorMap_HDA = TVP_apply_color_map_HDA;\n\tTVPApplyColorMap_o = TVP_apply_color_map_o;\n\tTVPApplyColorMap_HDA_o = TVP_apply_color_map_HDA_o;\n\tTVPApplyColorMap_d = TVP_apply_color_map_d;\n\tTVPApplyColorMap_a = TVP_apply_color_map_a;\n\tTVPApplyColorMap_do = TVP_apply_color_map_do;\n\tTVPApplyColorMap_ao = TVP_apply_color_map_ao;\n\n\tTVPRemoveConstOpacity = TVP_remove_const_opacity;\n\tTVPRemoveOpacity = TVP_remove_opacity;\n\tTVPRemoveOpacity_o = TVP_remove_opacity_o;\n\tTVPRemoveOpacity65 = TVP_remove_opacity65;\n\tTVPRemoveOpacity65_o = TVP_remove_opacity65_o;\n\n\tTVPMakeAlphaFromKey = TVP_make_alpha_from_key;\n\tTVPAlphaColorMat = TVP_alpha_color_mat;\n\tTVPConvertAdditiveAlphaToAlpha = TVP_convet_premulalpha_to_alpha;\n\tTVPConvertAlphaToAdditiveAlpha = TVP_convet_alpha_to_premulalpha;\n\tTVPBindMaskToMain = TVP_bind_mask_to_main;\n\n\tTVPSwapLine8 = TVP_swap_line8;\n\tTVPSwapLine32 = TVP_swap_line32;\n\tTVPReverse8 = TVP_reverse8;\n\tTVPReverse32 = TVP_reverse32;\n\tTVPDoGrayScale = TVP_do_gray_scale;\n\tTVPChBlurMulCopy65 = TVP_ch_blur_mul_copy65;\n\tTVPChBlurAddMulCopy65 = TVP_ch_blur_add_mul_copy65;\n\tTVPChBlurCopy65 = TVP_ch_blur_copy65;\n\tTVPChBlurMulCopy = TVP_ch_blur_mul_copy;\n\tTVPChBlurAddMulCopy = TVP_ch_blur_add_mul_copy;\n\tTVPChBlurCopy = TVP_ch_blur_copy;\n\n\tTVPPsInitTable();\n}\n\n"
  },
  {
    "path": "src/core/visual/gl/blend_functor_c.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n/******************************************************************************/\n/**\n * Additive alpha ́Apre-multiplied alpha ƌ\\L\n *****************************************************************************/\n\n#ifndef __ALPHA_BLEND_C_H__\n#define __ALPHA_BLEND_C_H__\n\n#include \"blend_util_func.h\"\n#include \"blend_variation.h\"\n\n#define DEFINE_BLEND_VARIATION( FUNC ) \\\ntypedef normal_op<FUNC##_func >\t\t\t\t\tFUNC##_functor;\t\t\t\\\ntypedef translucent_op<FUNC##_func >\t\t\tFUNC##_o_functor;\t\t\\\ntypedef hda_op<FUNC##_func >\t\t\t\t\tFUNC##_HDA_functor;\t\t\\\ntypedef hda_translucent_op<FUNC##_func >\t\tFUNC##_HDA_o_functor;\t\\\ntypedef dest_alpha_op<FUNC##_func >\t\t\t\tFUNC##_d_functor;\t\t\\\ntypedef dest_alpha_translucent_op<FUNC##_func >\tFUNC##_do_functor;\n\n/** 4p^[̃o[W */\n#define DEFINE_BLEND_MIN_VARIATION( FUNC ) \\\ntypedef translucent_nsa_op<FUNC##_func>\t\t\tFUNC##_o_functor;\t\t\\\ntypedef hda_nsa_op<FUNC##_functor>\t\t\t\tFUNC##_HDA_functor;\t\t\\\ntypedef hda_translucent_nsa_op<FUNC##_func>\t\tFUNC##_HDA_o_functor;\n\n/** 4p^[PSno[W */\n#define DEFINE_BLEND_PS_VARIATION( FUNC ) \\\ntypedef normal_op<FUNC##_func >\t\t\t\t\tFUNC##_functor;\t\t\t\\\ntypedef translucent_op<FUNC##_func >\t\t\tFUNC##_o_functor;\t\t\\\ntypedef hda_op<FUNC##_func >\t\t\t\t\tFUNC##_HDA_functor;\t\t\\\ntypedef hda_translucent_op<FUNC##_func >\t\tFUNC##_HDA_o_functor;\n\nextern \"C\" {\nextern tjs_uint32 TVPRecipTable256[256];\nextern unsigned char TVPOpacityOnOpacityTable[256*256];\nextern unsigned char TVPNegativeMulTable[256*256];\nextern unsigned char TVPOpacityOnOpacityTable65[65*256];\nextern unsigned char TVPNegativeMulTable65[65*256];\n}\n//------------------------------------------------------------------------------\n/**\n * alpha_blend_functor;\t\t\t// dstAt@\n * alpha_blend_HDA_functor;\t\t// dstAt@, dst At@ی\n * alpha_blend_o_functor;\t\t// dstAt@, opacity w\n * alpha_blend_HDA_o_functor;\t// dstAt@, dst At@ی, opacity w\n *\n * alpha_blend_d_functor;\t\t// dstAt@L\n * alpha_blend_do_functor;\t\t// dstAt@L, opacity w\n *\n * alpha_blend_a_functor;\t\t// dstAt@L, addalpha(pre-multiplied alpha)\n * alpha_blend_ao_functor;\t\t// dstAt@L, opacity w, addalpha(pre-multiplied alpha)\n */\n//------------------------------------------------------------------------------\n/** At@uh */\nstruct alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + (((s & 0xff00ff) - d1) * a >> 8)) & 0xff00ff;\n\t\td &= 0xff00;\n\t\ts &= 0xff00;\n\t\treturn d1 + ((d + ((s - d) * a >> 8)) & 0xff00);\n\t}\n};\nDEFINE_BLEND_VARIATION( alpha_blend )\n\n//------------------------------------------------------------------------------\nstruct alpha_blend_a_functor {\n\tpremulalpha_blend_a_a_func blend_;\n\talpha_to_premulalpha_func topremulalpha_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn blend_( d, topremulalpha_(s) );\n\t}\n};\n//------------------------------------------------------------------------------\n// typedef premulalpha_blend_a_d_o_func alpha_blend_ao_functor;\nstruct alpha_blend_ao_functor : public premulalpha_blend_a_d_o_func {\n\ttjs_int opa_;\n\t//alpha_blend_a_functor blend_;\n\tinline alpha_blend_ao_functor( tjs_int opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\t//s = (s & 0xffffff) + ((((s >> 24) * opa_) >> 8) << 24);\n\t\t//return blend_(d,s);\n\t\treturn premulalpha_blend_a_d_o_func::operator()( d, s, opa_ );\n\t}\n};\n//------------------------------------------------------------------------------\n/** pre-multiplied At@ */\n/*\nstruct premulalpha_blend_func {\n\tpremulalpha_blend_n_a_func add_alpha_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = (((s & 0xff00ff)*a >> 8) & 0xff00ff) + (((s >> 8) & 0xff00ff)*a & 0xff00ff00);\n\t\treturn add_alpha_(d, s);\n\t}\n};\nDEFINE_BLEND_VARIATION( premulalpha_blend )\n*/\nstruct premulalpha_blend_o_functor {\n\ttjs_int opa_;\n\tpremulalpha_blend_n_a_func add_alpha_;\n\tinline premulalpha_blend_o_functor( tjs_int opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ts = (((s & 0xff00ff)*opa_ >> 8) & 0xff00ff) + (((s >> 8) & 0xff00ff)*opa_ & 0xff00ff00);\n\t\treturn add_alpha_(d, s);\n\t}\n};\n/*\nstruct premulalpha_blend_HDA_o_functor : public premulalpha_blend_o_functor {\n\tinline premulalpha_blend_HDA_o_functor( tjs_int opa ) : premulalpha_blend_o_functor(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (premulalpha_blend_o_functor::operator()(d, s)&0x00ffffff) | (d&0xff000000);\n\t}\n};\n*/\n// t@N^d˂ƎxNg܂Ȃ悤Ȃ̂ŁAł͓WĴLq\nstruct premulalpha_blend_HDA_o_functor {\n\ttjs_int opa_;\n\tinline premulalpha_blend_HDA_o_functor( tjs_int opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 dopa = (d&0xff000000);\n\t\ts = (((s & 0xff00ff)*opa_ >> 8) & 0xff00ff) + (((s >> 8) & 0xff00ff)*opa_ & 0xff00ff00);\n\t\ttjs_uint32 sopa = (~s) >> 24;\n\t\ttjs_uint32 a = (((d & 0xff00ff)*sopa >> 8) & 0xff00ff) + (((d & 0xff00)*sopa >> 8) & 0xff00);\n\t\ttjs_uint32 b = s;\n\t\ttjs_uint32 tmp = (  ( a & b ) + ( ((a ^ b)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\n\t\ttmp = (tmp<<1) - (tmp>>7);\n\t\treturn (((a + b - tmp) | tmp) & 0x00FFFFFF) + dopa;\n\t}\n};\n\ntypedef premulalpha_blend_n_a_func premulalpha_blend_functor;\ntypedef hda_nsa_op<premulalpha_blend_n_a_func> premulalpha_blend_HDA_functor;\n// premulalpha_blend_o_functor\n// premulalpha_blend_HDA_o_functor;\ntypedef premulalpha_blend_a_a_func premulalpha_blend_a_functor;\ntypedef translucent_nsa_op<premulalpha_blend_a_a_o_func> premulalpha_blend_ao_functor;\n\n\n\n// ƂVvȃRs[ dst = src\nstruct const_copy_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { return s; }\n};\n// PRs[ alpha Rs[Ȃ(HDAƓ)\nstruct color_copy_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (d&0xff000000) + (s&0x00ffffff);\n\t}\n};\n// alphaRs[ : color_copy  src dest𔽓]\nstruct alpha_copy_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (s&0xff000000) + (d&0x00ffffff);\n\t}\n};\n// ̂܂܃Rs[邪At@0xffŖ߂ dst = 0xff000000 | src\nstruct color_opaque_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const { return 0xff000000 | s; }\n};\n//------------------------------------------------------------------------------\n/** Z */\n//typedef saturated_u8_add_func add_blend_functor;\nstruct add_blend_functor {\t// == saturated_u8_add_func\n\tinline tjs_uint32 operator()( tjs_uint32 a, tjs_uint32 b ) const {\n\t\ttjs_uint32 tmp = (  ( a & b ) + ( ((a ^ b)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\n\t\ttmp = (tmp<<1) - (tmp>>7);\n\t\treturn (a + b - tmp) | tmp;\n\t}\n};\n\nstruct add_blend_func : public add_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff);\n\t\treturn add_blend_functor::operator()( d, s );\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( add_blend )\n\n//------------------------------------------------------------------------------\n/** Z */ // IWiHDAƂH\nstruct sub_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 tmp = (  ( s & d ) + ( ((s^d)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\n\t\ttmp = (tmp << 1) - (tmp >> 7);\n\t\treturn (s + d - tmp) & tmp;\n\t}\n};\nstruct sub_blend_func : public sub_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ~s;\n\t\ts = ~ (( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff) );\n\t\treturn sub_blend_functor::operator()( d, s );\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( sub_blend )\n\n//------------------------------------------------------------------------------\n/** Z */\nstruct mul_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 tmp  = (d & 0xff) * (s & 0xff) & 0xff00;\n\t\ttmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\n\t\ttmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\n\t\treturn tmp >> 8;\n\t}\n};\nstruct mul_blend_func : public mul_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ~s;\n\t\ts = ~( ( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff));\n\t\treturn mul_blend_functor::operator()( d, s );\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( mul_blend )\n\n//------------------------------------------------------------------------------\n/** Ă */\nstruct color_dodge_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 tmp2 = ~s;\n\t\ttjs_uint32 tmp = (d& 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\n\t\ttjs_uint32 tmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\n\t\ttmp = ((d & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\n\t\ttmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\n\t\ttmp = ((d & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\n\t\ttmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n\t\treturn tmp3;\n\t}\n};\nstruct color_dodge_blend_func : public color_dodge_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = (( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff) );\n\t\treturn color_dodge_blend_functor::operator()( d, s );\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( color_dodge_blend )\n\n//------------------------------------------------------------------------------\n/** r() */\nstruct darken_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 m_src = ~s;\n\t\ttjs_uint32 tmp = ((m_src & d) + (((m_src ^ d) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\n\t\ttmp = (tmp << 1) - (tmp >> 7);\n\t\td ^= (d ^ s) & tmp;\n\t\treturn d;\n\t}\n};\nstruct darken_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32 m_src = ~s;\n\t\ttjs_uint32 tmp = ((m_src & d) + (((m_src ^ d) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\n\t\ttmp = (tmp << 1) - (tmp >> 7);\n\t\ttmp = d ^ ((d ^ s) & tmp);\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + (((tmp & 0xff00ff) - d1) * a >> 8)) & 0xff00ff;\n\t\tm_src = d & 0xff00;\n\t\ttmp &= 0xff00;\n\t\treturn d1 + ((m_src + ((tmp - m_src) * a >> 8)) & 0xff00);\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( darken_blend )\n\n//------------------------------------------------------------------------------\n/** r() */\nstruct lighten_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 m_dest = ~d;\n\t\ttjs_uint32 tmp = ((s & m_dest) + (((s ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\n\t\ttmp = (tmp << 1) - (tmp >> 7);\n\t\td ^= (d ^ s) & tmp;\n\t\treturn d;\n\t}\n};\nstruct lighten_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32 m_dest = ~d;\n\t\ttjs_uint32 tmp = ((s & m_dest) + (((s ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\n\t\ttmp = (tmp << 1) - (tmp >> 7);\n\t\ttmp = d ^ ((d ^ s) & tmp);\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + (((tmp & 0xff00ff) - d1) * a >> 8)) & 0xff00ff;\n\t\tm_dest = d & 0xff00;\n\t\ttmp &= 0xff00;\n\t\treturn d1 + ((m_dest + ((tmp - m_dest) * a >> 8)) & 0xff00);\n\t}\n};\nDEFINE_BLEND_MIN_VARIATION( lighten_blend )\n\n//------------------------------------------------------------------------------\n/** XN[ */\nstruct screen_blend_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ts = ~s;\n\t\td = ~d;\n\t\ttjs_uint32 tmp  = (d & 0xff) * (s & 0xff) & 0xff00;\n\t\ttmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\n\t\ttmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\n\t\ttmp >>= 8;\n\t\treturn ~tmp;\n\t}\n};\nstruct screen_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\td = ~d;\n\t\ts = ~( ( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff));\n\t\ttjs_uint32 tmp  = (d & 0xff) * (s & 0xff) & 0xff00;\n\t\ttmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\n\t\ttmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\n\t\ttmp >>= 8;\n\t\treturn tmp;\n\t}\n};\nstruct screen_blend_HDA_o_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\td = ~d;\n\t\ts = ~( ( ((s&0x00ff00)  * a >> 8)&0x00ff00) + (( (s&0xff00ff) * a >> 8)&0xff00ff));\n\t\ttjs_uint32 tmp  = (d & 0xff) * (s & 0xff) & 0xff00;\n\t\ttmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\n\t\ttmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\n\t\ttmp >>= 8;\n\t\treturn ~tmp ^ (d & 0xff000000);\n\t}\n};\ntypedef translucent_nsa_op<screen_blend_func>\t\tscreen_blend_o_functor;\ntypedef hda_nsa_op<screen_blend_functor>\t\t\tscreen_blend_HDA_functor;\ntypedef translucent_nsa_op<screen_blend_HDA_o_func>\tscreen_blend_HDA_o_functor;\n\n//------------------------------------------------------------------------------\n/*\n  Photoshop-like layer blender for KIRIKIRI (C-version)\n  (c)2004-2005 Kengo Takagi (Kenjo) <kenjo@ceres.dti.ne.jp>\n*/\n\n/** Photoshop݊̃At@ */\nstruct ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32 d1 = d & 0x00ff00ff;\n\t\ttjs_uint32 d2 = d & 0x0000ff00;\n\t\treturn ((((((s&0x00ff00ff)-d1)*a)>>8)+d1)&0x00ff00ff) | ((((((s&0x0000ff00)-d2)*a)>>8)+d2)&0x0000ff00);\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_alpha_blend )\n\n/** Photoshop݊́uĂ(jA)v */\nstruct ps_add_blend_func : public ps_alpha_blend_func {\n//\tps_alpha_blend_func func;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32\t\tn;\n\t\tn = (((d&s)<<1)+((d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\ts = (d+s-n)|n;\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_add_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂ(jA)v\nstruct ps_sub_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32\t\tn;\n\t\ts = ~s;\n\t\tn = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\ts = (d|n)-(s|n);\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_sub_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uZv\nstruct ps_mul_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff000000) |\n\t\t\t  ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff0000) |\n\t\t\t  ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 8;\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_mul_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uXN[v\nstruct ps_screen_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\t/* c = ((s+d-(s*d)/255)-d)*a + d = (s-(s*d)/255)*a + d */\n\t\ttjs_uint32 sd1, sd2;\n\t\tsd1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff000000) |\n\t\t\t\t((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 8;\n\t\tsd2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff0000) ) >> 8;\n\t\treturn ((((((s&0x00ff00ff)-sd1)*a)>>8)+(d&0x00ff00ff))&0x00ff00ff) |\n\t\t\t\t((((((s&0x0000ff00)-sd2)*a)>>8)+(d&0x0000ff00))&0x0000ff00);\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_screen_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! e[ugp\ntemplate<typename TTable>\nstruct ps_table_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = (TTable::TABLE[(s>>16)&0xff][(d>>16)&0xff]<<16) |\n\t\t\t(TTable::TABLE[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |\n\t\t\t(TTable::TABLE[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́u\\tgCgve[u\nstruct ps_soft_light_table { static unsigned char TABLE[256][256]; };\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂJ[ve[u\nstruct ps_color_dodge_table { static unsigned char TABLE[256][256]; };\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂ݃J[ve[u\nstruct ps_color_burn_table { static unsigned char TABLE[256][256]; };\n//--------------------------------------------------------------------------------------------------------\n#ifdef TVPPS_USE_OVERLAY_TABLE\n//! Photoshop݊́uI[o[Cve[u\nstruct ps_overlay_table { static unsigned char TABLE[256][256]; };\n#endif\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́u\\tgCgv\n//typedef ps_table_blend_func<ps_soft_light_table> ps_soft_light_blend_func\nstruct ps_soft_light_blend_func : public ps_table_blend_func<ps_soft_light_table> {};\nDEFINE_BLEND_PS_VARIATION( ps_soft_light_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂJ[v\n//typedef ps_table_blend_func<ps_color_dodge_table> ps_color_dodge_blend_func\nstruct ps_color_dodge_blend_func : public ps_table_blend_func<ps_color_dodge_table> {};\nDEFINE_BLEND_PS_VARIATION( ps_color_dodge_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂ݃J[v\n//typedef ps_table_blend_func<ps_color_burn_table> ps_color_burn_blend_func\nstruct ps_color_burn_blend_func : public ps_table_blend_func<ps_color_burn_table> {};\nDEFINE_BLEND_PS_VARIATION( ps_color_burn_blend )\n\n#ifdef TVPPS_USE_OVERLAY_TABLE\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uI[o[Cv\n//typedef ps_table_blend_func<ps_overlay_table> ps_overlay_blend_func\nstruct ps_overlay_blend_func : public ps_table_blend_func<ps_overlay_table> {};\n#else\nstruct ps_overlay_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32 n = (((d&0x00808080)>>7)+0x007f7f7f)^0x007f7f7f;\n\t\ttjs_uint32 sa1, sa2, d1 = d&n, s1 = s&n;\n\t\t/* some tricks to avoid overflow (error between /255 and >>8) */\n\t\ts |= 0x00010101;\n\t\tsa1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff800000) |\n\t\t\t\t((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 7;\n\t\tsa2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;\n\t\ts = ((sa1&~n)|(sa2&~n));\n\t\ts |= (((s1&0x00fe00fe)+(d1&0x00ff00ff))<<1)-(n&0x00ff00ff)-(sa1&n);\n\t\ts |= (((s1&0x0000fe00)+(d1&0x0000ff00))<<1)-(n&0x0000ff00)-(sa2&n);\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\n#endif\nDEFINE_BLEND_PS_VARIATION( ps_overlay_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́un[hCgv\nstruct ps_hard_light_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n#ifdef TVPPS_USE_OVERLAY_TABLE\n\t\ts = (ps_overlay_table::TABLE[(d>>16)&0xff][(s>>16)&0xff]<<16) |\n\t\t\t(ps_overlay_table::TABLE[(d>>8 )&0xff][(s>>8 )&0xff]<<8 ) |\n\t\t\t(ps_overlay_table::TABLE[(d>>0 )&0xff][(s>>0 )&0xff]<<0 );\n#else\n\t\ttjs_uint32 n = (((s&0x00808080)>>7)+0x007f7f7f)^0x007f7f7f;\n\t\ttjs_uint32 sa1, sa2, d1 = d&n, s1 = s&n;\n\t\t/* some tricks to avoid overflow (error between /255 and >>8) */\n\t\td |= 0x00010101;\n\t\tsa1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff800000) |\n                ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 7;\n\t\tsa2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;\n\t\ts = ((sa1&~n)|(sa2&~n));\n\t\ts |= (((s1&0x00ff00ff)+(d1&0x00fe00fe))<<1)-(n&0x00ff00ff)-(sa1&n);\n\t\ts |= (((s1&0x0000ff00)+(d1&0x0000fe00))<<1)-(n&0x0000ff00)-(sa2&n);\n#endif\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_hard_light_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uĂJ[v(Photoshop 5.x ȉƌ݊)\nstruct ps_color_dodge5_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ((((s&0x00ff00ff)*a)>>8)&0x00ff00ff)|((((s&0x0000ff00)*a)>>8)&0x0000ff00);\n\t\treturn\t(ps_color_dodge_table::TABLE[(s>>16)&0xff][(d>>16)&0xff]<<16) |\n\t\t\t\t(ps_color_dodge_table::TABLE[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |\n\t\t\t\t(ps_color_dodge_table::TABLE[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_color_dodge5_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́ur()v\nstruct ps_lighten_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32\tn;\n\t\tn = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\t/* n=mask (d<s:0xff, d>=s:0x00) */\n\t\ts = (s&n)|(d&~n);\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_lighten_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́ur()v\nstruct ps_darken_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32\tn;\n\t\tn = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\t/* n=mask (d<s:0xff, d>=s:0x00) */\n\t\ts = (d&n)|(s&~n);\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_darken_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́u̐Βlv\nstruct ps_diff_blend_func : public ps_alpha_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ttjs_uint32\tn;\n\t\tn = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\t/* n=mask (d<s:0xff, d>=s:0x00) */\n\t\ts = ((s&n)-(d&n))|((d&~n)-(s&~n));\n\t\treturn ps_alpha_blend_func::operator()( d, s, a );\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_diff_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́u̐Βlv(Photoshop 5.x ȉƌ݊)\nstruct ps_diff5_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\ts = ((((s&0x00ff00ff)*a)>>8)&0x00ff00ff)|((((s&0x0000ff00)*a)>>8)&0x0000ff00);\t/* Fade src first */\n\t\ttjs_uint32\tn;\n\t\tn = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;\n\t\tn = ((n>>8)+0x007f7f7f)^0x007f7f7f;\n\t\t/* n=mask (d<s:0xff, d>=s:0x00) */\n\t\treturn ((s&n)-(d&n))|((d&~n)-(s&~n));\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_diff5_blend )\n\n//--------------------------------------------------------------------------------------------------------\n//! Photoshop݊́uOv\nstruct ps_exclusion_blend_func {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a ) const {\n\t\t/* c = ((s+d-(s*d*2)/255)-d)*a + d = (s-(s*d*2)/255)*a + d */\n\t\ttjs_uint32\tsd1, sd2;\n\t\tsd1 = ( ((((d>>16)&0xff)*((s&0x00ff0000)>>7))&0x01ff0000) |\n\t\t\t((((d>>0 )&0xff)*( s&0x000000ff    ))>>7        ) );\n\t\tsd2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;\n\t\treturn\t((((((s&0x00ff00ff)-sd1)*a)>>8)+(d&0x00ff00ff))&0x00ff00ff) |\n\t\t\t\t((((((s&0x0000ff00)-sd2)*a)>>8)+(d&0x0000ff00))&0x0000ff00);\n\t}\n};\nDEFINE_BLEND_PS_VARIATION( ps_exclusion_blend )\n//--------------------------------------------------------------------------------------------------------\nstruct const_alpha_blend_functor {\n\tconst tjs_int32 opa_;\n\tinline const_alpha_blend_functor( tjs_int32 opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 s1, tjs_uint32 s2 ) const {\n\t\ttjs_uint32 s1_ = s1 & 0xff00ff;\n\t\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa_ >> 8)) & 0xff00ff;\n\t\ts2 &= 0xff00;\n\t\ts1 &= 0xff00;\n\t\treturn s1_ | ((s1 + ((s2 - s1) * opa_ >> 8)) & 0xff00);\n\t}\n};\nstruct sd_const_alpha_blend_a_functor {\n\tconst tjs_int32 opa_;\n\tblend_argb blend_;\n\tinline sd_const_alpha_blend_a_functor( tjs_int32 opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 s1, tjs_uint32 s2 ) const {\n\t\treturn blend_( s1, s2, opa_ );\n\t}\n};\nstruct const_alpha_blend_a_functor {\n\tconst tjs_int32 opa_;\n\tpremulalpha_blend_a_a_func blend_;\n\tinline const_alpha_blend_a_functor( tjs_int32 opa ) : opa_(opa<<24) {}\n\tinline tjs_uint32 operator()( tjs_uint32 s1, tjs_uint32 s2 ) const {\n\t\treturn blend_( s1, (s2&0xffffff)|opa_ );\n\t}\n};\nstruct sd_const_alpha_blend_d_functor {\n\tconst tjs_int32 opa_;\n\tconst tjs_int32 iopa_;\n\tinline sd_const_alpha_blend_d_functor( tjs_int32 opa ) : opa_(opa>127?opa+1:opa), iopa_(opa>127 ? 255-opa : 256-opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 s1, tjs_uint32 s2 ) const {\n\t\ttjs_uint32 a1 = s1 >> 24;\n\t\ttjs_uint32 a2 = s2 >> 24;\n\t\ttjs_uint32 addr = (a2*opa_ & 0xff00) + (a1*iopa_ >> 8);\n\t\ttjs_uint32 alpha = TVPOpacityOnOpacityTable[addr];\n\t\ttjs_uint32 s1_ = s1 & 0xff00ff;\n\t\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\t\ts1 &= 0xff00;\n\t\ts2 &= 0xff00;\n\t\ts1_ |= (a1 + ((a2 - a1)*opa_ >> 8)) << 24;\n\t\treturn s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\t}\n};\nstruct const_alpha_blend_d_functor {\n\tconst tjs_int32 opa_;\n\tinline const_alpha_blend_d_functor( tjs_int32 opa ) : opa_(opa<<8) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 addr = opa_ + (d>>24);\n\t\ttjs_uint32 alpha = TVPOpacityOnOpacityTable[addr];\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t\t(TVPNegativeMulTable[addr]<<24);\n\t\td &= 0xff00;\n\t\ts &= 0xff00;\n\t\treturn d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\t}\n};\nstruct const_alpha_blend_hda_functor {\n\tconst tjs_int32 opa_;\n\tinline const_alpha_blend_hda_functor( tjs_int32 opa ) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa_ >> 8)) & 0xff00ff) + (d & 0xff000000);\n\t\td &= 0xff00;\n\t\ts &= 0xff00;\n\t\treturn d1 | ((d + ((s - d) * opa_ >> 8)) & 0xff00);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\ntemplate<typename functor>\ninline void const_color_copy( tjs_uint32 *dest, tjs_int len, const functor& func ) {\n\tfor( int i = 0; i < len; i++ ) {\n\t\tdest[i] = func( dest[i] );\n\t}\n}\nstruct fill_argb_functor {\n\tconst tjs_uint32 color_;\n\tinline fill_argb_functor( tjs_uint32 c ) : color_(c) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn color_;\n\t}\n};\nstruct const_color_copy_functor {\n\tconst tjs_uint32 color_;\n\tinline const_color_copy_functor( tjs_uint32 c ) : color_(c&0xffffff) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn (d&0xff000000) + color_;\n\t}\n};\nstruct const_alpha_copy_functor {\n\tconst tjs_uint32 alpha_;\n\tinline const_alpha_copy_functor( tjs_uint32 a ) : alpha_(a<<24) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn (d&0x00ffffff) + alpha_;\n\t}\n};\nstruct const_alpha_fill_blend_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 color_mid_;\n\tconst tjs_int32 opa_;\n\tinline const_alpha_fill_blend_functor( tjs_int32 opa, tjs_int32 color ) : opa_(255-opa), color_((color&0xff00ff)*opa), color_mid_((color&0xff00)*opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn (d & 0xff000000) + ((((d & 0xff00ff) * opa_ + color_) >> 8) & 0xff00ff) + ((((d&0xff00) * opa_ + color_mid_) >> 8) & 0xff00);\n\t}\n};\nstruct const_alpha_fill_blend_d_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 color_mid_;\n\tconst tjs_int32 opa_;\n\tinline const_alpha_fill_blend_d_functor( tjs_int32 opa, tjs_int32 color ) : opa_(opa), color_(color&0xff00ff), color_mid_(color&0xff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\ttjs_uint32 dopa = d>>24;\n\t\ttjs_uint32 alpha = TVPOpacityOnOpacityTable[dopa + (opa_<<8)];\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = ((d1 + ((color_ - d1) * alpha >> 8)) & 0xff00ff) | ((255-((255-dopa)*(255-opa_)>>8)) << 24);\n\t\td &= 0xff00;\n\t\treturn d1 | ((d + ((color_mid_ - d) * alpha >> 8)) & 0xff00);\n\t}\n};\nstruct const_alpha_fill_blend_a_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 opa_inv_;\n\tconst tjs_int32 opa_;\n\tpremulalpha_blend_a_ca_func func_;\n\tinline const_alpha_fill_blend_a_functor( tjs_int32 opa, tjs_int32 color ) : opa_(opa),\n\t\tcolor_( (((((color&0x00ff00) * opa) & 0x00ff0000) + (((color&0xff00ff) * opa) & 0xff00ff00) ) >> 8)),\n\t\topa_inv_(opa^0xff) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn func_( d, opa_, opa_inv_, color_ );\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\ntemplate<int tshift>\nstruct apply_color_map_xx_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 c1_;\n\tinline apply_color_map_xx_functor( tjs_uint32 color ) : c1_(color&0xff00ff), color_(color&0x00ff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = ((d1 + ((c1_ - d1) * s >> tshift)) & 0xff00ff);\n\t\td &= 0xff00;\n\t\treturn d1 | ((d + ((color_ - d) * s >> tshift)) & 0x00ff00);\n\t}\n};\ntemplate<typename tbase>\nstruct apply_color_map_xx_o_functor : tbase {\n\ttjs_int opa_;\n\tinline apply_color_map_xx_o_functor( tjs_uint32 color, tjs_int opa ) : tbase(color), opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\treturn tbase::operator()( d, (tjs_uint8)( (s*opa_)>>8) );\n\t}\n};\ntypedef apply_color_map_xx_functor<6> apply_color_map65_functor;\ntypedef apply_color_map_xx_functor<8> apply_color_map_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_functor<6> > apply_color_map65_o_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_functor<8> > apply_color_map_o_functor;\n\ntemplate<int tshift>\nstruct apply_color_map_xx_HDA_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 c1_;\n\tinline apply_color_map_xx_HDA_functor( tjs_uint32 color ) : c1_(color&0xff00ff), color_(color&0x00ff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\ttjs_uint32 sopa = s;\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = ((d1 + ((c1_ - d1) * sopa >> tshift)) & 0xff00ff) + (d & 0xff000000);\n\t\td &= 0xff00;\n\t\treturn d1 | ((d + ((color_ - d) * sopa >> tshift)) & 0x00ff00);\n\t}\n};\ntypedef apply_color_map_xx_HDA_functor<6> apply_color_map65_HDA_functor;\ntypedef apply_color_map_xx_HDA_functor<8> apply_color_map_HDA_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_HDA_functor<6> > apply_color_map65_HDA_o_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_HDA_functor<8> > apply_color_map_HDA_o_functor;\n\nstruct apply_color_map65_d_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 c1_;\n\tinline apply_color_map65_d_functor( tjs_uint32 color ) : c1_(color&0xff00ff), color_(color&0x00ff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\ttjs_uint32 addr = (s<<8) + (d>>24);\n\t\ttjs_uint32 destalpha = TVPNegativeMulTable65[addr]<<24;\n\t\ttjs_uint32 sopa = TVPOpacityOnOpacityTable65[addr];\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + ((c1_ - d1) * sopa >> 8)) & 0xff00ff;\n\t\td &= 0x00ff00;\n\t\treturn d1 + ((d + ((color_ - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\t}\n};\nstruct apply_color_map_d_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 c1_;\n\tinline apply_color_map_d_functor( tjs_uint32 color ) : c1_(color&0xff00ff), color_(color&0x00ff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\ttjs_uint32 addr = (s<<8) + (d>>24);\n\t\ttjs_uint32 destalpha = TVPNegativeMulTable[addr]<<24;\n\t\ttjs_uint32 sopa = TVPOpacityOnOpacityTable[addr];\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + ((c1_ - d1) * sopa >> 8)) & 0xff00ff;\n\t\td &= 0x00ff00;\n\t\treturn d1 + ((d + ((color_ - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\t}\n};\ntypedef apply_color_map_xx_o_functor<apply_color_map65_d_functor> apply_color_map65_do_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_d_functor> apply_color_map_do_functor;\n\ntemplate<int tshift>\nstruct apply_color_map_xx_a_functor {\n\tconst tjs_uint32 color_;\n\tconst tjs_uint32 c1_;\n\tpremulalpha_blend_a_ca_func blend_;\n\tinline apply_color_map_xx_a_functor( tjs_uint32 color ) : c1_(color&0xff00ff), color_(color&0x00ff00) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\ttjs_int s_tmp = s;\n\t\ttjs_uint32 tmp =\n\t\t\t((s_tmp * (c1_    & 0xff00ff) >> tshift) & 0xff00ff) + \n\t\t\t((s_tmp * (color_ & 0x00ff00) >> tshift) & 0x00ff00);\n\t\ts_tmp <<= (8 - tshift);\n\t\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t\treturn blend_(d, s_tmp, s_tmp ^ 0xff, tmp);\n\t}\n};\ntypedef apply_color_map_xx_a_functor<6> apply_color_map65_a_functor;\ntypedef apply_color_map_xx_a_functor<8> apply_color_map_a_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_a_functor<6> > apply_color_map65_ao_functor;\ntypedef apply_color_map_xx_o_functor<apply_color_map_xx_a_functor<8> > apply_color_map_ao_functor;\n//--------------------------------------------------------------------------------------------------------\nstruct remove_const_opacity_functor {\n\ttjs_int strength_;\n\tinline remove_const_opacity_functor( tjs_int strength ) : strength_( 255-strength) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\treturn (d & 0xffffff) + ( (((d>>24)*strength_) << 16) & 0xff000000);\n\t}\n};\ntemplate<int tmax, int tshift>\nstruct remove_opacity_xx_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\treturn (d & 0xffffff) + ( (((d>>24) * (tmax-s)) << tshift) & 0xff000000);\n\t}\n};\ntemplate<int tmax, int tshift>\nstruct remove_opacity_xx_o_functor {\n\tconst tjs_int opa_;\n\tinline remove_opacity_xx_o_functor( tjs_int opa ) : opa_(opa>127?opa+1:opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint8 s ) const {\n\t\treturn (d & 0xffffff) + ( (((d>>24) * (tmax-s*opa_ )) << tshift) & 0xff000000);\n\t}\n};\ntypedef remove_opacity_xx_functor<255,16> remove_opacity_functor;\ntypedef remove_opacity_xx_functor< 64,18> remove_opacity65_functor;\ntypedef remove_opacity_xx_o_functor<65535,8> remove_opacity_o_functor;\ntypedef remove_opacity_xx_o_functor<16384,10> remove_opacity65_o_functor;\n//--------------------------------------------------------------------------------------------------------\nstruct make_alpha_from_key_functor {\n\ttjs_uint32 key_;\n\tinline make_alpha_from_key_functor( tjs_uint32 key ) : key_(key) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\td = d&0x00ffffff;\n\t\tif( d != key_ ) d |= 0xff000000;\n\t\treturn d;\n\t}\n};\n// const_alpha_fill_blend_functor ̋tAwcolordestƂĉZ`\nstruct alpha_color_mat_functor {\n\tconst tjs_uint32 color_;\n\tinline alpha_color_mat_functor( tjs_uint32 color ) : color_(color) {}\n\tinline tjs_uint32 operator()( tjs_uint32 s ) const {\n\t\ttjs_uint32 d = color_;\n\t\ttjs_uint32 sopa = s >> 24;\n\t\ttjs_uint32 d1 = d & 0xff00ff;\n\t\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\t\td &= 0xff00;\n\t\ts &= 0xff00;\n\t\treturn d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + 0xff000000;\n\t}\n};\nstruct convet_premulalpha_to_alpha_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\ttjs_uint32 tmp = d;\n\t\tconst tjs_uint8 * t = ((tmp >> 16) & 0xff00) + TVPDivTable;\n\t\treturn  (tmp & 0xff000000) +\n\t\t\t\t(t[(tmp >> 16) & 0xff] << 16) +\n\t\t\t\t(t[(tmp >>  8) & 0xff] <<  8) +\n\t\t\t\t(t[ tmp        & 0xff]      );\n\t}\n};\nstruct convet_alpha_to_premulalpha_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 d ) const {\n\t\ttjs_uint32 alpha = d >> 24;\n\t\ttjs_uint32 color = (((((d & 0x00ff00) * alpha) & 0x00ff0000) + (((d & 0xff00ff) * alpha) & 0xff00ff00) ) >> 8);\n\t\treturn color | (d&0xff000000);\n\t}\n};\nstruct bind_mask_to_main_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 c, tjs_uint8 a ) const {\n\t\treturn (c&0xffffff) | (a<<24);\n\t}\n};\nstruct do_gray_scale_functor {\n\tinline tjs_uint32 operator()( tjs_uint32 s1 ) const {\n\t\ttjs_uint32 d1 = (s1&0xff)*19;\n\t\td1 += ((s1 >> 8)&0xff)*183;\n\t\td1 += ((s1 >> 16)&0xff)*54;\n\t\treturn (d1 >> 8) * 0x10101 + (s1 & 0xff000000);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\ntemplate<int tmax>\nstruct ch_blur_mul_copy_xx_functor {\n\tconst tjs_int level_;\n\tinline ch_blur_mul_copy_xx_functor( tjs_int level ) : level_(level) {}\n\tinline tjs_uint8 operator()( tjs_uint8 d, tjs_uint8 s ) const {\n\t\ttjs_int a = (s * level_ >> 18);\n\t\tif(a>=tmax) a = tmax;\n\t\treturn (tjs_uint8)a;\n\t}\n};\ntemplate<int tmax>\nstruct ch_blur_add_mul_copy_xx_functor {\n\tconst tjs_int level_;\n\tinline ch_blur_add_mul_copy_xx_functor( tjs_int level ) : level_(level) {}\n\tinline tjs_uint32 operator()( tjs_uint8 d, tjs_uint8 s ) const {\n\t\ttjs_int a = d+(s * level_ >> 18);\n\t\tif(a>=tmax) a = tmax;\n\t\treturn (tjs_uint8)a;\n\t}\n};\ntypedef ch_blur_mul_copy_xx_functor<64> ch_blur_mul_copy65_functor;\ntypedef ch_blur_mul_copy_xx_functor<255> ch_blur_mul_copy_functor;\ntypedef ch_blur_add_mul_copy_xx_functor<64> ch_blur_add_mul_copy65_functor;\ntypedef ch_blur_add_mul_copy_xx_functor<255> ch_blur_add_mul_copy_functor;\n//--------------------------------------------------------------------------------------------------------\n#endif // ___ALPHA_BLEND_C_H__\n"
  },
  {
    "path": "src/core/visual/gl/blend_util_func.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n/******************************************************************************/\n/**\n * uh C ݂̂ŏꍇ̃[eBeBNX\n *****************************************************************************/\n\n\n#ifndef __BLEND_UTIL_FUNC_H__\n#define __BLEND_UTIL_FUNC_H__\n\n/** OaZZ(8bit) */\nstruct saturated_u8_add_func {\n\tinline tjs_uint32 operator()( tjs_uint32 a, tjs_uint32 b ) const {\n\t\t/* Add each byte of packed 8bit values in two 32bit uint32, with saturation. */\n\t\ttjs_uint32 tmp = (  ( a & b ) + ( ((a ^ b)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\n\t\ttmp = (tmp<<1) - (tmp>>7);\n\t\treturn (a + b - tmp) | tmp;\n\t}\n};\n/**\n * add_aldpha_blend_dest_src[_o]\n * dest/src    :    a(additive-alpha)  d(alpha)  n(none alpha)\n * _o          :    with opacity\n */\nstruct premulalpha_blend_n_a_func {\t// TVPAddAlphaBlend_n_a\n\tsaturated_u8_add_func sat_add_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 sopa = (~s) >> 24;\n\t\treturn sat_add_( (((d & 0xff00ff)*sopa >> 8) & 0xff00ff) + \n\t\t\t(((d & 0xff00)*sopa >> 8) & 0xff00), s);\n\t}\n};\n/* struct add_alpha_blend_hda_n_a_func {\t// TVPAddAlphaBlend_HDA_n_a\n\tadd_aldpha_blend_n_a_func add_alpha_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (d & 0xff000000) + (add_alpha_(d, s) & 0xffffff);\n\t}\n};*/\n/* struct add_aldpha_blend_n_a_o_func {\t// TVPAddAlphaBlend_n_a_o\n\tadd_aldpha_blend_n_a_func add_alpha_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_int opa ) const {\n\t\ts = (((s & 0xff00ff)*opa >> 8) & 0xff00ff) + (((s >> 8) & 0xff00ff)*opa & 0xff00ff00);\n\t\treturn add_alpha_(d, s);\n\t}\n};*/\n/* struct add_alpha_blend_hda_n_a_o_func {\t// TVPAddAlphaBlend_HDA_n_a_o\n\tadd_aldpha_blend_n_a_o_func add_alpha_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_int opa ) const {\n\t\treturn (d & 0xff000000) + (add_alpha_(d, s, opa) & 0xffffff);\n\t}\n};*/\n\n/** At@Zς݃J[m̃uh\n *\n * Di = sat(Si, (1-Sa)*Di)\n * Da = Sa + Da - SaDa\n */\nstruct premulalpha_blend_a_a_func {\t// TVPAddAlphaBlend_a_a\n\tsaturated_u8_add_func sat_add_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 da = d >> 24;\n\t\ttjs_uint32 sa = s >> 24;\n\t\tda = da + sa - (da*sa >> 8);\n\t\tda -= (da >> 8); /* adjust alpha */\n\t\tsa ^= 0xff;\n\t\ts &= 0xffffff;\n\t\treturn (da << 24) + sat_add_((((d & 0xff00ff)*sa >> 8) & 0xff00ff) + (((d & 0xff00)*sa >> 8) & 0xff00), s);\n\t}\n};\nstruct premulalpha_blend_a_a_o_func {\t// TVPAddAlphaBlend_a_a_o\n\tpremulalpha_blend_a_a_func func_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_int opa ) const {\n\t\ts = (((s & 0xff00ff)*opa >> 8) & 0xff00ff) + (((s >> 8) & 0xff00ff)*opa & 0xff00ff00);\n\t\treturn func_(d, s);\n\t}\n};\n\nstatic inline tjs_uint32 mul_color( tjs_uint32 color, tjs_uint32 fac ) {\n\treturn (((((color & 0x00ff00) * fac) & 0x00ff0000) +\n\t\t\t(((color & 0xff00ff) * fac) & 0xff00ff00) ) >> 8);\n}\nstatic inline tjs_uint32 alpha_and_color_to_additive_alpha( tjs_uint32 alpha, tjs_uint32 color ) {\n\treturn mul_color(color, alpha) + (color & 0xff000000);\n}\nstatic inline tjs_uint32 alpha_to_additive_alpha( tjs_uint32 a ) {\n\treturn alpha_and_color_to_additive_alpha( a >> 24, a );\n}\nstruct premulalpha_blend_a_d_func {\t// TVPAddAlphaBlend_a_d\n\tpremulalpha_blend_a_a_func func_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn func_(d, alpha_to_additive_alpha(s));\n\t}\n};\nstruct premulalpha_blend_a_d_o_func {\t// TVPAddAlphaBlend_a_d_o\n\tpremulalpha_blend_a_d_func func_;\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_int opa ) const {\n\t\ts = (s & 0xffffff) + ((((s >> 24) * opa) >> 8) << 24);\n\t\treturn func_(d, s);\n\t}\n};\n/*\n\tDi = sat(Si, (1-Sa)*Di)\n\tDa = Sa + Da - SaDa\n*/\nstruct premulalpha_blend_a_ca_func {\t// = TVPAddAlphaBlend_a_ca\n\tsaturated_u8_add_func sat_add_;\n\tinline tjs_uint32 operator()( tjs_uint32 dest, tjs_uint32 sopa, tjs_uint32 sopa_inv, tjs_uint32 src ) const {\n\t\ttjs_uint32 dopa = dest >> 24;\n\t\tdopa = dopa + sopa - (dopa*sopa >> 8);\n\t\tdopa -= (dopa >> 8); /* adjust alpha */\n\t\treturn (dopa << 24) + sat_add_((((dest & 0xff00ff)*sopa_inv >> 8) & 0xff00ff) + (((dest & 0xff00)*sopa_inv >> 8) & 0xff00), src);\n\t}\n};\n\n\n//------------------------------------------------------------------------------\n// J[fac\nstruct mul_color_func {\n\tinline tjs_uint32 operator()(tjs_uint32 color, tjs_uint32 fac) const {\n\t\treturn (((((color & 0x00ff00) * fac) & 0x00ff0000) + (((color & 0xff00ff) * fac) & 0xff00ff00) ) >> 8);\n\t}\n};\n//------------------------------------------------------------------------------\n// J[ɃAt@AAt@͈ێ\nstruct alpha_and_color_to_premulalpha_func {\n\tmul_color_func func_;\n\tinline tjs_uint32 operator()( tjs_uint32 alpha, tjs_uint32 color ) const {\n\t\treturn func_( color, alpha ) + (color & 0xff000000);\n\t}\n};\n//------------------------------------------------------------------------------\n// ʏ̃At@Fv}`vCh(Zς)At@`̐Fɕϊ\nstruct alpha_to_premulalpha_func {\n\talpha_and_color_to_premulalpha_func func_;\n\tinline tjs_uint32 operator()(tjs_uint32 a) const {\n\t\treturn func_( a >> 24, a );\n\t}\n};\n//------------------------------------------------------------------------------\n/* returns a * ratio + b * (1 - ratio) */\nstruct blend_argb {\n\tinline tjs_uint32 operator()(tjs_uint32 b, tjs_uint32 a, tjs_int ratio ) const {\n\t\ttjs_uint32 b2 = b & 0x00ff00ff;\n\t\ttjs_uint32 t = (b2 + (((a & 0x00ff00ff) - b2) * ratio >> 8)) & 0x00ff00ff;\n\t\tb2 = (b & 0xff00ff00) >> 8;\n\t\treturn t +  (((b2 + (( ((a & 0xff00ff00) >> 8) - b2) * ratio >> 8)) << 8)& 0xff00ff00);\n\t}\n};\n//------------------------------------------------------------------------------\n\n#endif // __BLEND_UTIL_FUNC_H__\n"
  },
  {
    "path": "src/core/visual/gl/blend_variation.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n/******************************************************************************/\n/**\n * At@̈ɂĔoG[V₷邽߂̃t@N^\n * blend_func ́A\n * tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s, tjs_uint32 a )\n * t@N^\n *****************************************************************************/\n\n#ifndef __BLEND_VARIATION_H__\n#define __BLEND_VARIATION_H__\n\n//--------------------------------------------------------------------------------------------------------\n// At@̈\n//--------------------------------------------------------------------------------------------------------\n// src̃At@gpo[W\ntemplate<class blend_func>\nstruct normal_op {\n\tblend_func\tfunc_;\n\tinline normal_op() {}\n\tinline normal_op(tjs_uint32 opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 a = (s>>24);\n\t\treturn func_(d,s,a);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n// xw肷o[W\ntemplate<class blend_func>\nstruct translucent_op {\n\tconst tjs_int\topa_;\n\tblend_func\t\tfunc_;\n\tinline translucent_op() : opa_(255) {}\n\tinline translucent_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 a = ((s>>24)*opa_)>>8;\n\t\treturn func_(d,s,a);\n\t}\n};\n// \\[X̃At@gpȂ\ntemplate<class blend_func>\nstruct translucent_nsa_op {\n\tconst tjs_int\topa_;\n\tblend_func\t\tfunc_;\n\tinline translucent_nsa_op() : opa_(255) {}\n\tinline translucent_nsa_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn func_(d,s,opa_);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n// destAt@ی삷o[W\ntemplate<class blend_func>\nstruct hda_op {\n\tblend_func\tfunc_;\n\tinline hda_op(){}\n\tinline hda_op(tjs_uint32 opa){}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 a = (s>>24);\n\t\treturn (func_(d,s,a)&0x00ffffff) | (d&0xff000000);\n\t}\n};\n// \\[X̃At@gpȂ\ntemplate<class blend_func>\nstruct hda_nsa_op {\n\tblend_func\tfunc_;\n\tinline hda_nsa_op(){}\n\tinline hda_nsa_op(tjs_uint32 opa){}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (func_(d,s)&0x00ffffff) | (d&0xff000000);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n// destAt@ی삵Axw肷o[W\ntemplate<class blend_func>\nstruct hda_translucent_op {\n\tconst tjs_uint32\topa_;\n\tblend_func\t\tfunc_;\n\tinline hda_translucent_op() : opa_(255) {}\n\tinline hda_translucent_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\ttjs_uint32 a = ((s>>24)*opa_)>>8;\n\t\treturn (func_(d,s,a)&0x00ffffff) | (d&0xff000000);\n\t}\n};\n// \\[X̃At@gpȂ\ntemplate<class blend_func>\nstruct hda_translucent_nsa_op {\n\tconst tjs_uint32\topa_;\n\tblend_func\t\tfunc_;\n\tinline hda_translucent_nsa_op() : opa_(255) {}\n\tinline hda_translucent_nsa_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn (func_(d,s,opa_)&0x00ffffff) | (d&0xff000000);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n// dest̃At@gpo[W\ntemplate<class blend_func>\nstruct dest_alpha_op {\n\tblend_func\tfunc_;\n\tinline dest_alpha_op() {}\n\tinline dest_alpha_op(tjs_uint32 opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n#ifdef NOT_USE_TABLE\n\t\ttjs_uint32 sa = s >> 24;\n\t\ttjs_uint32 da = d >> 24;\n\t\ttjs_uint32 sopa;\n\t\tif( da ) {\n\t\t\tfloat at = (float)(da/255.0);\n\t\t\tfloat bt = (float)(sa/255.0);\n\t\t\tfloat c = bt / at;\n\t\t\tc /= (float)( (1.0 - bt + c) );\n\t\t\ttjs_uint32 sopa = (tjs_uint32)(c*255);\n\t\t} else {\n\t\t\tsopa = 255;\n\t\t}\n\t\ttjs_uint32 destalpha = (unsigned char)( 255 - (255-da)*(255-sa)/ 255 ) << 24;\n#else\n\t\ttjs_uint32 addr = ((s >> 16) & 0xff00) + (d>>24);\n\t\ttjs_uint32 destalpha = TVPNegativeMulTable[addr]<<24;\n\t\ttjs_uint32 sopa = TVPOpacityOnOpacityTable[addr];\n#endif\n\t\treturn func_(d,s,sopa) + destalpha;\n\t}\n\t\n\t// (sa/da) / ( 1 - sa + (sa/da) )\n\t// 1 / (sa+da)\n\n\t// 1 - (1-da)*(1-sa)\n\t// 1 - sa - da + da*sa\n\t// ca = a + ba\n\t// ca = a + ba;\n\t// ca = a + ba;\n\t// ca = a + (((255-a)*da)/255\n};\n// \\[X̃At@gpȂ HDA ƓʂɂȂ̂ŁA\\[X̃At@gpȂo[W͕sv\n//--------------------------------------------------------------------------------------------------------\n// dest̃At@gpAxw肷o[W\ntemplate<class blend_func>\nstruct dest_alpha_translucent_op {\n\tconst tjs_int\topa_;\n\tblend_func\t\tfunc_;\n\tinline dest_alpha_translucent_op() : opa_(255) {}\n\tinline dest_alpha_translucent_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n#ifdef NOT_USE_TABLE\n\t\ttjs_uint32 sa = ((s>>24)*opa_)>>8;\n\t\ttjs_uint32 da = d >> 24;\n\t\ttjs_uint32 sopa;\n\t\tif( da ) {\n\t\t\tfloat at = (float)(da/255.0);\n\t\t\tfloat bt = (float)(sa/255.0);\n\t\t\tfloat c = bt / at;\n\t\t\tc /= (float)( (1.0 - bt + c) );\n\t\t\ttjs_uint32 sopa = (tjs_uint32)(c*255);\n\t\t} else {\n\t\t\tsopa = 255;\n\t\t}\n\t\ttjs_uint32 destalpha = (unsigned char)( 255 - (255-da)*(255-sa)/ 255 ) << 24;\n#else\n\t\ttjs_uint32 addr = (( (s>>24)*opa_) & 0xff00) + (d>>24);\n\t\ttjs_uint32 destalpha = TVPNegativeMulTable[addr]<<24;\n\t\ttjs_uint32 sopa = TVPOpacityOnOpacityTable[addr];\n#endif\n\t\treturn func_(d,s,sopa) + destalpha;\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n#if 0\n// so[W ł\ntemplate<class blend_func>\nstruct opacity_op {\n\tblend_func\tfunc_;\n\tinline opacity_op(){}\n\tinline opacity_op(tjs_uint32 opa){}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn func_(d,s,255);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n// so[W xw肷\ntemplate<class blend_func>\nstruct opacity_translucent_op {\n\tconst tjs_uint32\topa_;\n\tblend_func\t\tfunc_;\n\tinline opacity_translucent_op() : opa_(255) {}\n\tinline opacity_translucent_op(tjs_uint32 opa) : opa_(opa) {}\n\tinline tjs_uint32 operator()( tjs_uint32 d, tjs_uint32 s ) const {\n\t\treturn func_(d,s,opa_);\n\t}\n};\n//--------------------------------------------------------------------------------------------------------\n#endif\n#endif // __BLEND_VARIATION_H__\n"
  },
  {
    "path": "src/core/visual/gl/tvpgl_mathutil.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n\n\n#ifndef __TVP_MATH_UTIL_H__\n#define __TVP_MATH_UTIL_H__\n\n/* fast_int_hypot from http://demo.and.or.jp/makedemo/effect/math/hypot/fast_hypot.c */\nstatic inline tjs_uint fast_int_hypot(tjs_int lx, tjs_int ly) {\n\ttjs_uint len1, len2,t,length;\n\tif(lx<0) lx = -lx;\n\tif(ly<0) ly = -ly;\n\tif (lx >= ly) { len1 = lx ; len2 = ly; }\n\telse { len1 = ly ; len2 = lx; }\n\tt = len2 + (len2 >> 1) ;\n\tlength = len1 - (len1 >> 5) - (len1 >> 7) + (t >> 2) + (t >> 6) ;\n\treturn length;\n}\n\n#endif //__TVP_MATH_UTIL_H__\n"
  },
  {
    "path": "src/core/visual/ogl/RenderManager_ogl.cpp",
    "content": "#include \"renderer/CCTexture2D.h\"\n#include \"renderer/CCGLProgramCache.h\"\n#include \"renderer/CCGLProgram.h\"\n#include \"renderer/ccGLStateCache.h\"\n#include \"ogl_common.h\"\n#include \"tjsCommHead.h\"\n#include \"../RenderManager.h\"\n#include \"WindowImpl.h\"\n#include \"MsgIntf.h\"\n#include <string>\n#include \"../tvpgl.h\"\n#include \"SysInitIntf.h\"\n#include <assert.h>\n#include <sstream>\n#include \"base/CCDirector.h\"\n#include \"base/CCEventListenerCustom.h\"\n#include \"base/CCEventDispatcher.h\"\n#include \"base/CCEventType.h\"\n#include \"Platform.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n#include \"opencv2/opencv.hpp\"\n#include <deque>\n#include <algorithm>\n#include <unordered_set>\n#include \"ConfigManager/LocaleConfigManager.h\"\n#include \"etcpak.h\"\n#include \"pvrtc.h\"\n#include \"pvr.h\"\n\n// #define TEST_SHADER_ENABLED\n#ifndef GL_ETC1_RGB8_OES\n#define GL_ETC1_RGB8_OES    0x8D64\n#endif\n#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC\n#define GL_COMPRESSED_RGB8_ETC2 0x9274\n#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278\n#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2         0x9276 \n#endif\n#ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG  0x8C00\n#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG  0x8C01\n#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02\n#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03\n#endif\n#ifndef GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG\n#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG                  0x9137\n#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG                  0x9138\n#endif\n\nnamespace TJS {\n\tvoid TVPConsoleLog(const tjs_char *l);\n\tvoid TVPConsoleLog(const tjs_nchar *format, ...);\n}\nstatic void ShowInMessageBox(const char *format, ...) {\n\tva_list args;\n\tva_start(args, format);\n\tchar buf[256];\n\tvsnprintf(buf, 256 - 3, format, args);\n\tconst char *btnText = \"OK\";\n\tTVPShowSimpleMessageBox(buf, \"Log\", 1, &btnText);\n\n\tva_end(args);\n}\n\n#if 0\n#undef CHECK_GL_ERROR_DEBUG\n#define CHECK_GL_ERROR_DEBUG() \\\n\tdo { \\\n\tGLenum __error = glGetError(); \\\n\tif(__error) { \\\n\tShowInMessageBox(\"OpenGL error 0x%04X in %s %s %d\\n\", __error, __FILE__, __FUNCTION__, __LINE__); \\\n\t} \\\n\t} while (false)\n#define CHECK_GL_ERROR_DEBUG_WITH_FMT(fmt, ...) \\\n\tdo { \\\n\tGLenum __error = glGetError(); \\\n\tif(__error) { \\\n\tShowInMessageBox(\"OpenGL error 0x%04X in %s %s %d\\n\" fmt, __error, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \\\n\t} \\\n\t} while (false)\n#endif\n\nstruct _UsedGLExtInfo {\n\t_UsedGLExtInfo(){}\n\tconst char *NameBegin = nullptr;\n#define _DEFEXT(name) #name\n#define DEFEXT(name) const char *GLEXT_##name = _DEFEXT(GL_##name)\n\tDEFEXT(EXT_unpack_subimage);\n\tDEFEXT(EXT_shader_framebuffer_fetch);\n\tDEFEXT(ARM_shader_framebuffer_fetch);\n\tDEFEXT(NV_shader_framebuffer_fetch);\n\tDEFEXT(EXT_copy_image);\n\tDEFEXT(OES_copy_image);\n\tDEFEXT(ARB_copy_image);\n\tDEFEXT(NV_copy_image);\n\tDEFEXT(EXT_clear_texture);\n\tDEFEXT(ARB_clear_texture);\n\tDEFEXT(QCOM_alpha_test);\n#undef DEFEXT\n\tconst char *NameEnd = nullptr;\n};\nstatic const _UsedGLExtInfo UsedGLExtInfo;\n\nstatic std::unordered_set<std::string> sTVPGLExtensions;\n// some quick check flags\nstatic bool GL_CHECK_unpack_subimage;\nstatic bool GL_CHECK_shader_framebuffer_fetch;\n\nbool TVPCheckGLExtension(const std::string &extname) {\n\treturn sTVPGLExtensions.find(extname) != sTVPGLExtensions.end();\n}\nstatic bool TVPGLExtensionInfoInited = false;\nstatic void TVPInitGLExtensionInfo() {\n\tif (TVPGLExtensionInfoInited) return;\n\tTVPGLExtensionInfoInited = true;\n\tstd::string gl_extensions = (const char*)glGetString(GL_EXTENSIONS);\n\tconst char *p = gl_extensions.c_str();\n\tfor (char &c : gl_extensions) {\n\t\tif (c == ' ') {\n\t\t\tc = 0;\n\t\t\tsTVPGLExtensions.emplace(p);\n\t\t\tp = &c;\n\t\t\t++p;\n\t\t}\n\t}\n\tif (*p) sTVPGLExtensions.emplace(p);\n\tIndividualConfigManager *cfgMgr = IndividualConfigManager::GetInstance();\n\tfor (const char *const *name = (&UsedGLExtInfo.NameBegin) + 1; *name; ++name) {\n\t\tif (!cfgMgr->GetValue<int>(*name, 1)) {\n#ifndef _MSC_VER\n\t\t\tsTVPGLExtensions.erase(*name);\n#endif\n\t\t}\n\t}\n#ifdef WIN32\n\tsTVPGLExtensions.erase(\"GL_EXT_unpack_subimage\");\n#endif\n#ifdef TEST_SHADER_ENABLED\n\tfor (const std::string &line : sTVPGLExtensions) {\n\t\tcocos2d::log(\"%s\", line.c_str());\n\t}\n#endif\n}\n\nnamespace GL { // independ from global gl functions\n#ifndef GLAPIENTRY\n#define GLAPIENTRY\n#endif\n#ifdef _MSC_VER\ntypedef PROC (WINAPI fGetProcAddress)(LPCSTR);\n#elif defined(TARGET_OS_IPHONE)\ntypedef void* (fGetProcAddress)(const char *);\n#else\ntypedef void* (EGLAPIENTRY fGetProcAddress)(const char *);\n#endif\nstatic fGetProcAddress *glGetProcAddress = nullptr;\n\ntypedef void (GLAPIENTRY fCopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);\nstatic fCopyImageSubData *glCopyImageSubData;\ntypedef void (GLAPIENTRY fClearTexImage)(uint texture, int level, GLenum format, GLenum type, const void * data);\nstatic fClearTexImage *glClearTexImage;\ntypedef void (GLAPIENTRY fClearTexSubImage)(uint texture, int level, int xoffset, int yoffset, int zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data);\nstatic fClearTexSubImage *glClearTexSubImage;\n\n#ifdef _MSC_VER\ntypedef void (GLAPIENTRY fGetTextureImage)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nstatic fGetTextureImage *glGetTextureImage;\n#endif\n\ntypedef void (GLAPIENTRY fAlphaFunc)(GLenum func, GLclampf ref);\nstatic fAlphaFunc *glAlphaFunc;\n}\n\nstatic std::set<GLenum> TVPTextureFormats;\nvoid TVPInitTextureFormatList() {\n\tif (TVPTextureFormats.empty()) {\n\t\tGLint nTexFormats; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nTexFormats);\n\t\tstd::vector<GLint> texFormats; texFormats.resize(nTexFormats);\n\t\tglGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, &texFormats.front());\n\t\tfor (GLint f : texFormats) {\n\t\t\tTVPTextureFormats.insert(f);\n\t\t}\n\t}\n}\nbool TVPIsSupportTextureFormat(GLenum fmt) {\n\treturn TVPTextureFormats.end() != TVPTextureFormats.find(fmt);\n}\n\nstatic void TVPInitGLExtensionFunc() {\n#ifdef _MSC_VER\n\tGL::glGetProcAddress = wglGetProcAddress;\n#elif defined(EGLAPI)\n\tGL::glGetProcAddress = (GL::fGetProcAddress*)eglGetProcAddress;\n#endif\n\n\tGL_CHECK_unpack_subimage = TVPCheckGLExtension(\"GL_EXT_unpack_subimage\");\n\tGL_CHECK_shader_framebuffer_fetch =\n\t\tTVPCheckGLExtension(\"GL_EXT_shader_framebuffer_fetch\") ||\n\t\tTVPCheckGLExtension(\"GL_ARM_shader_framebuffer_fetch\") ||\n\t\tTVPCheckGLExtension(\"GL_NV_shader_framebuffer_fetch\");\n\n\tif (GL::glGetProcAddress) {\n#ifdef _MSC_VER\n\t\tGL::glGetTextureImage = (GL::fGetTextureImage*)GL::glGetProcAddress(\"glGetTextureImage\");\n#endif\n\t\tif (!GL::glCopyImageSubData && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_EXT_copy_image))\n\t\t\tGL::glCopyImageSubData = (GL::fCopyImageSubData*)GL::glGetProcAddress(\"glCopyImageSubDataEXT\");\n\t\tif (!GL::glCopyImageSubData && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_OES_copy_image))\n\t\t\tGL::glCopyImageSubData = (GL::fCopyImageSubData*)GL::glGetProcAddress(\"glCopyImageSubDataOES\");\n\t\tif (!GL::glCopyImageSubData && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_NV_copy_image))\n\t\t\tGL::glCopyImageSubData = (GL::fCopyImageSubData*)GL::glGetProcAddress(\"glCopyImageSubDataNV\");\n\t\tif (!GL::glCopyImageSubData && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_ARB_copy_image))\n\t\t\tGL::glCopyImageSubData = (GL::fCopyImageSubData*)GL::glGetProcAddress(\"glCopyImageSubData\");\n\n\t\tif (!GL::glClearTexImage && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_EXT_clear_texture)) {\n\t\t\tGL::glClearTexImage = (GL::fClearTexImage*)GL::glGetProcAddress(\"glClearTexImageEXT\");\n\t\t\tGL::glClearTexSubImage = (GL::fClearTexSubImage*)GL::glGetProcAddress(\"glClearTexSubImageEXT\");\n\t\t}\n\t\tif (!GL::glClearTexImage && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_ARB_clear_texture)) {\n\t\t\tGL::glClearTexImage = (GL::fClearTexImage*)GL::glGetProcAddress(\"glClearTexImage\");\n\t\t\tGL::glClearTexSubImage = (GL::fClearTexSubImage*)GL::glGetProcAddress(\"glClearTexSubImage\");\n\t\t}\n\t}\n#ifdef GL_ALPHA_TEST\n\tGL::glAlphaFunc = glAlphaFunc;\n#else\n#define GL_ALPHA_TEST                     0x0BC0\n#endif\n\tif (!GL::glAlphaFunc && TVPCheckGLExtension(UsedGLExtInfo.GLEXT_QCOM_alpha_test))\n\t\tGL::glAlphaFunc = (GL::fAlphaFunc*)GL::glGetProcAddress(\"glAlphaFuncQCOM\");\n}\n\nstd::string TVPGetOpenGLInfo() {\n//\tTVPInitGLExtensionInfo();\n\tstd::unordered_set<std::string> Extensions;\n\tstd::string gl_extensions = (const char*)glGetString(GL_EXTENSIONS);\n\tconst char *p = gl_extensions.c_str();\n\tfor (char &c : gl_extensions) {\n\t\tif (c == ' ') {\n\t\t\tc = 0;\n\t\t\tExtensions.emplace(p);\n\t\t\tp = &c;\n\t\t\t++p;\n\t\t}\n\t}\n\tif (*p) Extensions.emplace(p);\n\n\tstd::stringstream ret;\n\tret << \"Renderer : \"; ret << glGetString(GL_RENDERER); ret << \"\\n\";\n\tret << \"Vendor : \"; ret << glGetString(GL_VENDOR); ret << \"\\n\";\n\tret << \"Version : \"; ret << glGetString(GL_VERSION); ret << \"\\n\";\n\tGLint maxTextSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextSize);\n\tret << \"MaxTexureSize : \"; ret << int(maxTextSize); ret << \"\\n\";\n\tret << LocaleConfigManager::GetInstance()->GetText(\"supported_opengl_extension\");\n\tfor (const char *const *name = (&UsedGLExtInfo.NameBegin) + 1; *name; ++name) {\n\t\tif (Extensions.find(*name) != Extensions.end()) {\n\t\t\tret << \"\\n\";\n\t\t\tret << *name;\n\t\t}\n\t}\n\n\tTVPInitTextureFormatList();\n\tif (!TVPTextureFormats.empty()) {\n\t\tret << \"\\n\\n\";\n\t\tret << \"Support texture formats:\\n\";\n\t\tstd::map<GLenum, const char *> mapFormatName({\n\t\t\t{ 0x87EE, \"ATC_RGBA_INTERPOLATED_ALPHA_AMD\" },\n\n\t\t\t{ 0x87F9, \"3DC_X_AMD\" },\n\t\t\t{ 0x87FA, \"3DC_XY_AMD\" },\n\n\t\t\t{ 0x83F0, \"S3TC_DXT1_RGB\" },\n\t\t\t{ 0x83F1, \"S3TC_DXT1_RGBA\" },\n\t\t\t{ 0x83F2, \"S3TC_DXT3_RGBA\" },\n\t\t\t{ 0x83F3, \"S3TC_DXT5_RGBA\" },\n\n\t\t\t{ 0x8B90, \"PALETTE4_RGB8_OES\" },\n\t\t\t{ 0x8B91, \"PALETTE4_RGBA8_OES\" },\n\t\t\t{ 0x8B92, \"PALETTE4_R5_G6_B5_OES\" },\n\t\t\t{ 0x8B93, \"PALETTE4_RGBA4_OES\" },\n\t\t\t{ 0x8B94, \"PALETTE4_RGB5_A1_OES\" },\n\t\t\t{ 0x8B95, \"PALETTE8_RGB8_OES\" },\n\t\t\t{ 0x8B96, \"PALETTE8_RGBA8_OES\" },\n\t\t\t{ 0x8B97, \"PALETTE8_R5_G6_B5_OES\" },\n\t\t\t{ 0x8B98, \"PALETTE8_RGBA4_OES\" },\n\t\t\t{ 0x8B99, \"PALETTE8_RGB5_A1_OES\" },\n\n\t\t\t{ 0x8C00, \"PVRTC_RGB_4BPPV1\" },\n\t\t\t{ 0x8C01, \"PVRTC_RGB_2BPPV1\" },\n\t\t\t{ 0x8C02, \"PVRTC_RGBA_4BPPV1\" },\n\t\t\t{ 0x8C03, \"PVRTC_RGBA_2BPPV1\" },\n\t\t\t\n\t\t\t{ 0x8C92, \"ATC_RGB_AMD\" },\n\t\t\t{ 0x8C93, \"ATC_RGBA_EXPLICIT_ALPHA_AMD\" },\n\n\t\t\t{ 0x8D64, \"ETC1_RGB8\" },\n\n\t\t\t{ 0x9137, \"PVRTC_2BPPV2\" },\n\t\t\t{ 0x9138, \"PVRTC_4BPPV2\" },\n\n\t\t\t{ 0x9270, \"EAC_R11\" },\n\t\t\t{ 0x9271, \"EAC_SIGNED_R11\" },\n\t\t\t{ 0x9272, \"EAC_RG11\" },\n\t\t\t{ 0x9273, \"EAC_SIGNED_RG11\" },\n\t\t\t{ 0x9274, \"ETC2_RGB8\" },\n\t\t\t{ 0x9275, \"ETC2_SRGB8\" },\n\t\t\t{ 0x9276, \"ETC2_RGB8_PUNCHTHROUGH_ALPHA1\" },\n\t\t\t{ 0x9277, \"ETC2_SRGB8_PUNCHTHROUGH_ALPHA1\" },\n\t\t\t{ 0x9278, \"ETC2_RGBA8_EAC\" },\n\t\t\t{ 0x9279, \"ETC2_SRGB8_ALPHA8_EAC\" },\n\n\t\t\t{ 0x93B0, \"ASTC_RGBA_4x4\" },\n\t\t\t{ 0x93B1, \"ASTC_RGBA_5x4\" },\n\t\t\t{ 0x93B2, \"ASTC_RGBA_5x5\" },\n\t\t\t{ 0x93B3, \"ASTC_RGBA_6x5\" },\n\t\t\t{ 0x93B4, \"ASTC_RGBA_6x6\" },\n\t\t\t{ 0x93B5, \"ASTC_RGBA_8x5\" },\n\t\t\t{ 0x93B6, \"ASTC_RGBA_8x6\" },\n\t\t\t{ 0x93B7, \"ASTC_RGBA_8x8\" },\n\t\t\t{ 0x93B8, \"ASTC_RGBA_10x5\" },\n\t\t\t{ 0x93B9, \"ASTC_RGBA_10x6\" },\n\t\t\t{ 0x93BA, \"ASTC_RGBA_10x8\" },\n\t\t\t{ 0x93BB, \"ASTC_RGBA_10x10\" },\n\t\t\t{ 0x93BC, \"ASTC_RGBA_12x10\" },\n\t\t\t{ 0x93BD, \"ASTC_RGBA_12x12\" },\n\n\t\t\t{ 0x93C0, \"ASTC_RGBA_3x3x3\" },\n\t\t\t{ 0x93C1, \"ASTC_RGBA_4x3x3\" },\n\t\t\t{ 0x93C2, \"ASTC_RGBA_4x4x3\" },\n\t\t\t{ 0x93C3, \"ASTC_RGBA_4x4x4\" },\n\t\t\t{ 0x93C4, \"ASTC_RGBA_5x4x4\" },\n\t\t\t{ 0x93C5, \"ASTC_RGBA_5x5x4\" },\n\t\t\t{ 0x93C6, \"ASTC_RGBA_5x5x5\" },\n\t\t\t{ 0x93C7, \"ASTC_RGBA_6x5x5\" },\n\t\t\t{ 0x93C8, \"ASTC_RGBA_6x6x5\" },\n\t\t\t{ 0x93C9, \"ASTC_RGBA_6x6x6\" },\n\t\t\t\n\t\t\t{ 0x93D0, \"ASTC_SRGB8_ALPHA8_4x4\" },\n\t\t\t{ 0x93D1, \"ASTC_SRGB8_ALPHA8_5x4\" },\n\t\t\t{ 0x93D2, \"ASTC_SRGB8_ALPHA8_5x5\" },\n\t\t\t{ 0x93D3, \"ASTC_SRGB8_ALPHA8_6x5\" },\n\t\t\t{ 0x93D4, \"ASTC_SRGB8_ALPHA8_6x6\" },\n\t\t\t{ 0x93D5, \"ASTC_SRGB8_ALPHA8_8x5\" },\n\t\t\t{ 0x93D6, \"ASTC_SRGB8_ALPHA8_8x6\" },\n\t\t\t{ 0x93D7, \"ASTC_SRGB8_ALPHA8_8x8\" },\n\t\t\t{ 0x93D8, \"ASTC_SRGB8_ALPHA8_10x5\" },\n\t\t\t{ 0x93D9, \"ASTC_SRGB8_ALPHA8_10x6\" },\n\t\t\t{ 0x93DA, \"ASTC_SRGB8_ALPHA8_10x8\" },\n\t\t\t{ 0x93DB, \"ASTC_SRGB8_ALPHA8_10x10\" },\n\t\t\t{ 0x93DC, \"ASTC_SRGB8_ALPHA8_12x10\" },\n\t\t\t{ 0x93DD, \"ASTC_SRGB8_ALPHA8_12x12\" },\n\n\t\t\t{ 0x93E0, \"ASTC_SRGB8_ALPHA8_3x3x3\" },\n\t\t\t{ 0x93E1, \"ASTC_SRGB8_ALPHA8_4x3x3\" },\n\t\t\t{ 0x93E2, \"ASTC_SRGB8_ALPHA8_4x4x3\" },\n\t\t\t{ 0x93E3, \"ASTC_SRGB8_ALPHA8_4x4x4\" },\n\t\t\t{ 0x93E4, \"ASTC_SRGB8_ALPHA8_5x4x4\" },\n\t\t\t{ 0x93E5, \"ASTC_SRGB8_ALPHA8_5x5x4\" },\n\t\t\t{ 0x93E6, \"ASTC_SRGB8_ALPHA8_5x5x5\" },\n\t\t\t{ 0x93E7, \"ASTC_SRGB8_ALPHA8_6x5x5\" },\n\t\t\t{ 0x93E8, \"ASTC_SRGB8_ALPHA8_6x6x5\" },\n\t\t\t{ 0x93E9, \"ASTC_SRGB8_ALPHA8_6x6x6\" },\n\t\t});\n\t\tfor (GLenum f : TVPTextureFormats) {\n\t\t\tauto it = mapFormatName.find(f);\n\t\t\tif (mapFormatName.end() != it) {\n\t\t\t\tret << it->second;\n\t\t\t\tret << \"\\n\";\n\t\t\t} else {\n\t\t\t\tret << \"TexFormat[\";\n\t\t\t\tret << (int)f;\n\t\t\t\tret << \"]\\n\";\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ret.str();\n}\n\n// bool TVPOnOpenGLRendererSelected(bool forceNotice) {\n// \tif (!strstr((const char*)glGetString(GL_RENDERER), \"Adreno\")) {\n// \t\treturn false;\n// \t}\n// //\tTVPInitGLExtensionInfo();\n// \tbool ret = false;\n// \tif (strstr((const char*)glGetString(GL_EXTENSIONS), \"GL_EXT_shader_framebuffer_fetch\")) {\n// \t\tret = true;\n// \t\tif (forceNotice || GlobalConfigManager::GetInstance()->GetValue<int>(\"noticed_adreno_issue\", 0) < 1) {\n// \t\t\tconst char *btnText[2] = {\n// \t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"msgbox_ok\").c_str(),\n// \t\t\t\tLocaleConfigManager::GetInstance()->GetText(\"msgbox_nerver_notice\").c_str(),\n// \t\t\t};\n// \t\t\tint n = TVPShowSimpleMessageBox(LocaleConfigManager::GetInstance()->GetText\n// \t\t\t\t(\"issue_GL_EXT_shader_framebuffer_fetch\").c_str(), \"Info\", forceNotice ? 1 : 2, btnText);\n// \t\t\tif (n == 1) {\n// \t\t\t\tGlobalConfigManager::GetInstance()->SetValueInt(\"noticed_adreno_issue\", 1);\n// \t\t\t\tGlobalConfigManager::GetInstance()->SaveToFile();\n// \t\t\t}\n// \t\t}\n// \t}\n// //\tTVPGLExtensionInfoInited = false;\n// \treturn ret;\n// }\n\nclass tTVPOGLTexture2D;\nstruct GLVertexInfo {\n\ttTVPOGLTexture2D* tex;\n\tstd::vector<GLfloat> vtx;\n};\n\nstatic bool _CurrentFBOValid = false;\nstatic GLuint _FBO; // common frame buffer object for all renderable texture\nstatic GLuint _stencil_FBO;\nstatic GLuint _CurrentRenderTarget = 0;\nstatic GLenum _glCompressedTexFormat = GL_RGBA;\nunsigned int TVPMaxTextureSize;\nstatic uint64_t _totalVMemSize = 0;\nstatic unsigned int GetMaxTextureWidth()\n{\n\treturn TVPMaxTextureSize;\n}\nstatic unsigned int GetMaxTextureHeight()\n{\n\treturn TVPMaxTextureSize;\n}\nstatic unsigned int power_of_two(unsigned int input, unsigned int value = 32)\n{\n\twhile (value < input) {\n\t\tvalue <<= 1;\n\t}\n\treturn value;\n}\n\nstatic void _glBindTexture2D(GLuint t) {\n\tcocos2d::GL::activeTexture(GL_TEXTURE0);\n\tcocos2d::GL::bindTexture2D(t);\n}\n\nstatic GLint _prevRenderBuffer;\nstatic GLint  _screenFrameBuffer = 0;\nstatic unsigned int _stencilBufferW = 0, _stencilBufferH = 0;\nvoid TVPSetRenderTarget(GLuint t)\n{\n\tif (t) {\n\t\tif (!_CurrentFBOValid) {\n\t\t\t_CurrentFBOValid = true;\n\t\t\tglGetIntegerv(GL_FRAMEBUFFER_BINDING, &_screenFrameBuffer);\n\t\t\tglBindFramebuffer(GL_FRAMEBUFFER, _FBO);\n\t\t}\n\t\tif (_CurrentRenderTarget == t) return;\n\t\tglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t, 0);\n\t} else {\n\t\tglBindFramebuffer(GL_FRAMEBUFFER, _screenFrameBuffer);\n\t\t_CurrentFBOValid = false;\n\t}\n\t_CurrentRenderTarget = t;\n}\n\nstatic void _RestoreGLStatues() {\n    if (GL_CHECK_unpack_subimage) {\n        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);\n    }\n\tcocos2d::GL::blendResetToCache();\n\tTVPSetRenderTarget(0);\n\tcocos2d::Director::getInstance()->setViewport();\n}\n\nstatic tjs_uint8 *TVPShrinkXYBy2(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dstw = (srcw + 1) / 2, dsth = (srch + 1) / 2;\n\ttjs_uint dp = *dpitch = (dstw * 4 + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * dsth], *dst = ret;\n\ttjs_uint wpitch = srcw / 2 * 4, h = srch / 2;\n\tbool xtail = srcw & 1;\n\tfor (tjs_uint y = 0; y < h; y++) {\n\t\tconst tjs_uint8 *sline = src, *sline2 = src + spitch;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[4] + sline2[0] + sline2[4];\n\t\t\t*dline++ = sum / 4; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline[4] + sline2[0] + sline2[4];\n\t\t\t*dline++ = sum / 4; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline[4] + sline2[0] + sline2[4];\n\t\t\t*dline++ = sum / 4; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline[4] + sline2[0] + sline2[4];\n\t\t\t*dline++ = sum / 4; ++sline; ++sline2;\n\t\t\tsline += 4;\n\t\t\tsline2 += 4;\n\t\t}\n\t\tif (xtail) {\n\t\t\ttjs_uint32 sum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; /*++sline; ++sline2;*/\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t\tsrc += spitch;\n\t}\n\tif (srch & 1/*ytail*/) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsline += 4;\n\t\t}\n\t\tif (xtail) {\n\t\t\ttjs_uint32 sum = *(tjs_uint32*)sline;\n\t\t\t*(tjs_uint32*)dline = sum;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrinkXBy2(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dstw = (srcw + 1) / 2;\n\ttjs_uint dp = *dpitch = (dstw * 4 + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * srch], *dst = ret;\n\ttjs_uint wpitch = srcw / 2 * 4;\n\tbool xtail = srcw & 1;\n\tfor (tjs_uint y = 0; y < srch; y++) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsum = sline[0] + sline[4];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsline += 4;\n\t\t}\n\t\tif (xtail) {\n\t\t\ttjs_uint32 sum = *(tjs_uint32*)sline;\n\t\t\t*(tjs_uint32*)dline = sum;\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrinkYBy2(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dsth = (srch + 1) / 2;\n\ttjs_uint dp = *dpitch = (srcw * 4 + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * dsth], *dst = ret;\n\ttjs_uint wpitch = srcw * 4, h = srch / 2;\n\tfor (tjs_uint y = 0; y < h; y++) {\n\t\tconst tjs_uint8 *sline = src, *sline2 = src + spitch;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t\tsum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t\tsrc += spitch;\n\t}\n\tif (srch & 1/*ytail*/) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = *(tjs_uint32*)sline;\n\t\t\t*(tjs_uint32*)dline = sum;\n\t\t\tdline += 4;\n\t\t\tsline += 4;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrinkXYBy2_8(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dstw = (srcw + 1) / 2, dsth = (srch + 1) / 2;\n\ttjs_uint dp = *dpitch = (dstw + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * dsth], *dst = ret;\n\ttjs_uint wpitch = srcw / 2, h = srch / 2;\n\tbool xtail = srcw & 1;\n\tfor (tjs_uint y = 0; y < h; y++) {\n\t\tconst tjs_uint8 *sline = src, *sline2 = src + spitch;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[1] + sline2[0] + sline2[1];\n\t\t\t*dline++ = sum / 4; ++sline; ++sline2;\n\t\t\tsline += 1;\n\t\t\tsline2 += 1;\n\t\t}\n\t\tif (xtail) {\n\t\t\ttjs_uint32 sum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2;\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t\tsrc += spitch;\n\t}\n\tif (srch & 1/*ytail*/) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[1];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline;\n\t\t}\n\t\tif (xtail) {\n\t\t\t*dline = *sline;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrinkXBy2_8(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dstw = (srcw + 1) / 2;\n\ttjs_uint dp = *dpitch = (dstw + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * srch], *dst = ret;\n\ttjs_uint wpitch = srcw / 2;\n\tbool xtail = srcw & 1;\n\tfor (tjs_uint y = 0; y < srch; y++) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline[1];\n\t\t\t*dline++ = sum / 2; ++sline;\n\t\t\tsline += 1;\n\t\t}\n\t\tif (xtail) {\n\t\t\t*dline = *sline;\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrinkYBy2_8(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch) {\n\ttjs_uint dsth = (srch + 1) / 2;\n\ttjs_uint dp = *dpitch = (srcw + 7) &~7;\n\ttjs_uint8 *ret = new tjs_uint8[dp * dsth], *dst = ret;\n\ttjs_uint wpitch = srcw, h = srch / 2;\n\tfor (tjs_uint y = 0; y < h; y++) {\n\t\tconst tjs_uint8 *sline = src, *sline2 = src + spitch;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\ttjs_uint32 sum = sline[0] + sline2[0];\n\t\t\t*dline++ = sum / 2; ++sline; ++sline2;\n\t\t}\n\t\tdst += dp;\n\t\tsrc += spitch;\n\t\tsrc += spitch;\n\t}\n\tif (srch & 1/*ytail*/) {\n\t\tconst tjs_uint8 *sline = src;\n\t\ttjs_uint8 *dline = dst, *lend = dline + wpitch;\n\t\twhile (dline < lend) {\n\t\t\t*dline++ = *sline++;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic tjs_uint8 *TVPShrink(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch, tjs_uint dstw, tjs_uint dsth) {\n\tif (srcw == dstw) {\n\t\tif ((srch + 1) / 2 == dsth) {\n\t\t\treturn TVPShrinkYBy2(dpitch, src, spitch, srcw, srch);\n\t\t}\n\t} else if ((srcw + 1) / 2 == dstw) {\n\t\tif (srch == dsth) {\n\t\t\treturn TVPShrinkXBy2(dpitch, src, spitch, srcw, srch);\n\t\t} else if ((srch + 1) / 2 == dsth) {\n\t\t\treturn TVPShrinkXYBy2(dpitch, src, spitch, srcw, srch);\n\t\t}\n\t}\n\t*dpitch = (dstw * 4 + 7) &~7;\n\ttjs_uint8 *tmp = new tjs_uint8[*dpitch * dsth];\n\tcv::Size dsize(dstw, dsth);\n\tcv::Mat src_img(srch, srcw, CV_8UC4, (void*)src, spitch);\n\tcv::Mat dst_img(dsth, dstw, CV_8UC4, (void*)tmp, *dpitch);\n\tcv::resize(src_img, dst_img, dsize, 0, 0, cv::INTER_LINEAR);\n\treturn tmp;\n}\n\nstatic tjs_uint8 *TVPShrink_8(tjs_uint *dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch, tjs_uint dstw, tjs_uint dsth) {\n\tif (srcw == dstw) {\n\t\tif ((srch + 1) / 2 == dsth) {\n\t\t\treturn TVPShrinkYBy2_8(dpitch, src, spitch, srcw, srch);\n\t\t}\n\t} else if ((srcw + 1) / 2 == dstw) {\n\t\tif (srch == dsth) {\n\t\t\treturn TVPShrinkXBy2_8(dpitch, src, spitch, srcw, srch);\n\t\t} else if ((srch + 1) / 2 == dsth) {\n\t\t\treturn TVPShrinkXYBy2_8(dpitch, src, spitch, srcw, srch);\n\t\t}\n\t}\n\t*dpitch = (dstw + 7) &~7;\n\ttjs_uint8 *tmp = new tjs_uint8[*dpitch * dsth];\n\tcv::Size dsize(dstw, dsth);\n\tcv::Mat src_img(srch, srcw, CV_8UC1, (void*)src, spitch);\n\tcv::Mat dst_img(dsth, dstw, CV_8UC1, (void*)tmp, *dpitch);\n\tcv::resize(src_img, dst_img, dsize, 0, 0, cv::INTER_LINEAR);\n\treturn tmp;\n}\n\nstatic tjs_uint8 *TVPShrinkImage(TVPTextureFormat::e fmt, tjs_uint &dpitch, const tjs_uint8 *src, tjs_int spitch, tjs_uint srcw, tjs_uint srch, tjs_uint dstw, tjs_uint dsth) {\n\tif (srch == dsth && srcw == dstw) return nullptr;\n\treturn (fmt == TVPTextureFormat::RGBA ? TVPShrink : TVPShrink_8)(&dpitch, src, spitch, srcw, srch, dstw, dsth);\n}\n\nstatic bool TVPCheckOpaqueRGBA(const tjs_uint8 *pixel, tjs_int pitch, tjs_int w, tjs_int h) {\n\tconst tjs_uint8* p = pixel;\n\tfor (int y = 0; y < h; ++y) {\n\t\tconst tjs_uint8* line = p;\n\t\tfor (int x = 0; x < w; ++x) {\n\t\t\tif (line[3] != 0xFF) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tline += 4;\n\t\t}\n\t\tp += pitch;\n\t}\n\treturn true;\n}\n\nstatic bool TVPCheckSolidPixel(const tjs_uint8 *pixel, tjs_int pitch, tjs_int w, tjs_int h) {\n\tconst tjs_uint8* p = pixel;\n\ttjs_uint32 clr = *(const tjs_uint32*)p;\n\tfor (int y = 0; y < h; ++y) {\n\t\tconst tjs_uint32* line = (const tjs_uint32*)p;\n\t\tfor (int x = 0; x < w; ++x) {\n\t\t\tif (line[x] != clr) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tp += pitch;\n\t}\n\treturn true;\n}\n\nclass tTVPOGLTexture2D : public iTVPTexture2D {\n\tfriend class TVPRenderManager_OpenGL;\npublic:\n\tGLuint texture = 0;\n\tbool IsCompressed = false;\nprotected:\n\tTVPTextureFormat::e Format;\n\tunsigned int internalW;\n\tunsigned int internalH;\n\tunsigned char *PixelData = nullptr; // read only\n\tint PixelDataCounter = 0;\n\tfloat _scaleW = 1, _scaleH = 1;\n\n\ttTVPOGLTexture2D(unsigned int w, unsigned int h, TVPTextureFormat::e format, GLint mode = GL_LINEAR)\n\t\t: iTVPTexture2D(w, h)\n\t\t, Format(format)\n\t{\n\t\tif (mode) {\n\t\t\tglGenTextures(1, &texture);\n\t\t\tcocos2d::GL::bindTexture2D(texture);\n\n\t\t\t//glBindTexture(GL_TEXTURE_2D, texture);\n\t\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode);\n\t\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode);\n\t\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n\t\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n\t\t}\n\t}\n\n\t~tTVPOGLTexture2D() {\n\t\t_totalVMemSize -= internalW * internalH * getPixelSize();\n\t\tif (PixelData) delete[]PixelData;\n\t\tif (texture) cocos2d::GL::deleteTexture(texture);\n\t}\n\n\tint getPixelSize() {\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\treturn 1;\n\t\tcase TVPTextureFormat::RGB:\n\t\t\treturn 3;\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\treturn 4;\n\t\tdefault:\n\t\t\treturn (int)Format;\n\t\t}\n\t}\n\n\tvoid InternalInit(const void *pixel, unsigned int intw, unsigned int inth, unsigned int pitch) {\n\t\tGLenum pixfmt = GL_RGBA;\n\t\tGLenum internalfmt = GL_RGBA;\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tpixfmt = GL_LUMINANCE;\n\t\t\tinternalfmt = GL_LUMINANCE;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\t\tpixfmt = GL_RGB;\n\t\t\tinternalfmt = GL_RGB;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tpixfmt = GL_RGBA;\n\t\t\tinternalfmt = GL_RGBA;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (pitch & 7) {\n\t\tcase 0: glPixelStorei(GL_UNPACK_ALIGNMENT, 8); break;\n\t\tcase 2: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tcase 4: glPixelStorei(GL_UNPACK_ALIGNMENT, 4); break;\n\t\tcase 6: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tdefault: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); break;\n\t\t}\n\n\t\tTVPCheckMemory();\n\t\t_glBindTexture2D(texture);\n\t\tglTexImage2D(GL_TEXTURE_2D, 0, internalfmt, intw, inth, 0, pixfmt, GL_UNSIGNED_BYTE, pixel);\n\n\t\tinternalW = intw; internalH = inth;\n\t\t_totalVMemSize += internalW * internalH * getPixelSize();\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tvoid InternalUpdate(const void *pixel, int pitch, int x, int y, int w, int h) {\n\t\tif (_scaleW != 1.f || _scaleH != 1.f) {\n\t\t\tRestoreNormalSize();\n\t\t}\n\t\tconst unsigned char *src = (const unsigned char *)pixel;\n\t\tGLenum pixfmt;\n\t\t_glBindTexture2D(texture);\n\t\t//glBindTexture(GL_TEXTURE_2D, texture);\n\t\tunsigned int pixsize = Format & 0xF;\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tpixfmt = GL_LUMINANCE;\n\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\t\tpixfmt = GL_RGB;\n\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 4);\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tpixfmt = GL_RGBA;\n\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn;\n\t\t}\n\t\tbool rearranged = false;\n\t\tif (GL_CHECK_unpack_subimage) {\n\t\t\tglPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixsize);\n\t\t} else if (pitch != w * pixsize) {\n\t\t\trearranged = true;\n\t\t\tunsigned int arrpitch = w * pixsize;\n\t\t\tunsigned char *arr = new unsigned char[arrpitch * h], *p = arr;\n\t\t\tfor (int i = 0; i < h; ++i, p += arrpitch, src += pitch) memcpy(p, src, arrpitch);\n\t\t\tsrc = arr;\n\t\t}\n\t\tglTexSubImage2D(GL_TEXTURE_2D,\n\t\t\t0,\n\t\t\tx,\n\t\t\ty,\n\t\t\tw,\n\t\t\th,\n\t\t\tpixfmt,\n\t\t\tGL_UNSIGNED_BYTE,\n\t\t\tsrc);\n\t\tif (GL_CHECK_unpack_subimage)\n\t\t\tglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);\n\t\tif (rearranged) delete[] src;\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tbool RestoreNormalSize();\n\n\tvirtual TVPTextureFormat::e GetFormat() const override {\n\t\treturn Format;\n\t}\n\n\tclass AdapterTexture2D : public cocos2d::Texture2D {\n\tpublic:\n\t\tiTVPTexture2D *_owner;\n\t\tAdapterTexture2D(iTVPTexture2D* owner, GLuint name, int w, int h) {\n\t\t\t_name = name;\n\t\t\t_owner = owner;\n\t\t\t_owner->AddRef();\n\t\t\t_contentSize = cocos2d::Size(w, h);\n\t\t\t_maxS = 1;\n\t\t\t_maxT = 1;\n\t\t\t_pixelsWide = w;\n\t\t\t_pixelsHigh = h;\n\t\t\t_pixelFormat = PixelFormat::RGBA8888;\n\t\t\t_hasPremultipliedAlpha = false;\n\t\t\t_hasMipmaps = false;\n\t\t\tsetGLProgram(cocos2d::GLProgramCache::getInstance()->getGLProgram(cocos2d::GLProgram::SHADER_NAME_POSITION_TEXTURE));\n\t\t}\n\n\t\t~AdapterTexture2D() {\n\t\t\t_name = 0;\n\t\t\t_owner->Release();\n\t\t}\n\n\t\tvoid update(GLuint name) {\n\t\t\t_name = name;\n\t\t}\n\t};\n\n\tvirtual cocos2d::Texture2D* GetAdapterTexture(cocos2d::Texture2D* orig) override {\n\t\tif (orig) {\n\t\t\tif (orig->getPixelsWide() == internalW && orig->getPixelsHigh() == internalH) {\n\t\t\t\tstatic_cast<AdapterTexture2D*>(orig)->update(texture);\n\t\t\t\treturn orig;\n\t\t\t}\n\t\t}\n\t\tAdapterTexture2D *ret = new AdapterTexture2D(this, texture, internalW, internalH);\n\t\tret->autorelease();\n\t\treturn ret;\n\t}\npublic:\n\tvirtual bool IsOpaque() override {\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\tcase TVPTextureFormat::RGB:\n\t\t\treturn true;\n\t\tcase TVPTextureFormat::RGBA:\n\t\tcase TVPTextureFormat::None:\n\t\treturn false;\n\t}\n\t\treturn false;\n\t}\n\n\tvirtual bool GetScale(float &x, float &y) {\n\t\tx = _scaleW; y = _scaleH; return true;\n\t}\n\n\tvirtual const void * GetScanLineForRead(tjs_uint l) override;\n\n\tvirtual tjs_uint32 GetPoint(int x, int y) override {\n\t\tif (PixelData) return *(uint32_t*)&PixelData[y * GetPitch() + x * 4];\n\t\tunsigned long clr = 0;\n\t\tTVPSetRenderTarget(texture);\n\t\tglViewport(0, 0, internalW, internalH);\n\t\tglPixelStorei(GL_PACK_ALIGNMENT, 4);\n\t\tglReadPixels(x * _scaleW, y * _scaleH, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &clr);\n\t\treturn clr;\n\t}\n\n\tvirtual tjs_int GetPitch() const override {\n\t\tif (_scaleW == 1.f && _scaleH == 1.f) return internalW * 4;\n\t\treturn tjs_int(internalW / _scaleW) * 4;\n\t}\n\tvirtual tjs_uint GetInternalWidth() const override { return internalW; }\n\tvirtual tjs_uint GetInternalHeight() const override { return internalH; }\n\tvirtual void AsTarget() {\n\t\tassert(false);\n\t}\n\tvirtual void SyncPixel() {\n\t\tif (PixelData && --PixelDataCounter <= 0) {\n\t\t\tdelete[] PixelData;\n\t\t\tPixelData = nullptr;\n\t\t}\n\t}\n\tvirtual void ApplyVertex(GLVertexInfo &vtx, const tTVPRect &rc) {\n\t\tvtx.tex = this;\n\t\tGLfloat sminu, smaxu, sminv, smaxv;\n\t\tsminu = (GLfloat)rc.left;\n\t\tsmaxu = (GLfloat)rc.right;\n\t\tsminv = (GLfloat)rc.top;\n\t\tsmaxv = (GLfloat)rc.bottom;\n\t\tfloat tw = _scaleW / internalW;\n\t\tfloat th = _scaleH / internalH;\n\t\tsminu *= tw; smaxu *= tw;\n\t\tsminv *= th; smaxv *= th;\n\t\tvtx.vtx.resize(6 * 2); GLfloat* pt = &vtx.vtx.front();\n\t\tpt[0] = sminu; pt[1] = sminv;\n\t\tpt[2] = smaxu; pt[3] = sminv;\n\t\tpt[4] = sminu; pt[5] = smaxv;\n\n\t\tpt[6] = smaxu; pt[7] = sminv;\n\t\tpt[8] = sminu; pt[9] = smaxv;\n\t\tpt[10] = smaxu; pt[11] = smaxv;\n\t}\n\tvirtual void ApplyVertex(GLVertexInfo &vtx, const tTVPPointD *p, int n) {\n\t\tvtx.tex = this;\n\t\tvtx.vtx.resize(n * 2); GLfloat* pt = &vtx.vtx.front();\n\t\tfloat tw = _scaleW / internalW;\n\t\tfloat th = _scaleH / internalH;\n\t\tfor (int i = 0; i < n; ++i) {\n\t\t\tpt[i * 2 + 0] = (float)p[i].x * tw;\n\t\t\tpt[i * 2 + 1] = (float)p[i].y * th;\n\t\t}\n\t}\n\tvoid Bind(unsigned int i) {\n\t\tcocos2d::GL::bindTexture2DN(i, texture);\n\t}\n};\n\nstatic TVPTextureFormat::e _GetTextureFormatFromBPP(int bpp) {\n\tswitch (bpp) {\n\tcase 8: return TVPTextureFormat::Gray;\n\tcase 24: return TVPTextureFormat::RGB;\n\tcase 32: return TVPTextureFormat::RGBA;\n\tdefault: return TVPTextureFormat::None;\n\t}\n}\n\nclass tTVPOGLTexture2D_split : public tTVPOGLTexture2D {\n\tstruct GLTextureInfoPoint {\n\t\tuint16_t X, Y; // max to 65535 x 65535\n\t};\n\n\tunion GLTextureInfoIndexer {\n\t\tuint32_t Index;\n\t\tGLTextureInfoPoint Point;\n\t};\n\tstruct GLTextureInfo {\n\t\tGLuint Name = 0;\n\t//\tuint32_t LastAccessTimeStamp;\n\t\tGLTextureInfoPoint Point;\n\t\tuint16_t Width = 0, Height = 0;\n\t};\n//\tstd::vector<GLuint> UnusedTextureName;\n\tstd::map<uint32_t/*GLTextureInfoIndexer.Index*/, GLTextureInfo> CachedTexture;\n\ttTVPBitmap* Bitmap;\n\n\tvoid ClearTextureCache() {\n// \t\tfor (GLuint& name : UnusedTextureName) {\n// \t\t\tcocos2d::GL::deleteTexture(name);\n// \t\t}\n// \t\tUnusedTextureName.clear();\n\t\tfor (auto& it : CachedTexture) {\n\t\t\tcocos2d::GL::deleteTexture(it.second.Name);\n\t\t}\n\t\tCachedTexture.clear();\n\t\ttexture = 0;\n\t}\n\n\tGLuint FetchGLTexture() {\n// \t\tif (!UnusedTextureName.empty()) {\n// \t\t\tGLuint ret = UnusedTextureName.back();\n// \t\t\tUnusedTextureName.pop_back();\n// \t\t\treturn ret;\n// \t\t}\n\t\tGLuint ret; glGenTextures(1, &ret);\n\t\tcocos2d::GL::bindTexture2D(ret);\n\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n\t\treturn ret;\n\t}\n\npublic:\n\ttTVPOGLTexture2D_split(tTVPBitmap* bmp)\n\t\t: tTVPOGLTexture2D(bmp->GetWidth(), bmp->GetHeight(), _GetTextureFormatFromBPP(bmp->GetBPP()), 0/*don't generate texture*/)\n\t{ // only accept from bitmap\n\t\tBitmap = bmp;\n\t\tBitmap->AddRef();\n\t}\n\t~tTVPOGLTexture2D_split() {\n\t\tinternalW = 0;\n\t\tinternalH = 0;\n\t\tClearTextureCache();\n\t\tBitmap->Release();\n\t}\n\tvirtual const void * GetScanLineForRead(tjs_uint l) {\n\t\treturn Bitmap->GetScanLine(l);\n\t}\n\tvirtual tjs_int GetPitch() const { return Bitmap->GetPitch(); }\n\tvirtual tjs_uint32 GetPoint(int x, int y) override {\n\t\tif (Bitmap->Is32bit()) {\n\t\t\treturn ((uint32_t*)Bitmap->GetScanLine(y))[x];\n\t\t} else if (Bitmap->Is8bit()) {\n\t\t\treturn ((uint8_t*)Bitmap->GetScanLine(y))[x];\n\t\t} else {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Unsupported texture format[RGB] for getting point color.\"));\n\t\t\treturn 0;\n\t\t}\n\t}\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Static texture cannot update data.\"));\n\t}\n\tvirtual void SetPoint(int x, int y, uint32_t clr) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"Static texture cannot set point color.\"));\n\t}\n\tvirtual bool IsStatic() { return true; }\n\tvirtual bool IsOpaque() {\n\t\tif (Bitmap) return Bitmap->IsOpaque;\n\t\treturn false;\n\t}\n\tvirtual void SyncPixel() {\n// \t\tif (CachedTexture.size() > 1) {\n// \t\t\t;\n// \t\t}\n\t}\n\t\n\tvoid UpdateTextureData(GLTextureInfo &texinfo, const tTVPRect &rc) {\n\t\tunsigned int pixsize = Format & 0xF;\n\t\tGLenum pixfmt = GL_RGBA;\n\t\tGLenum internalfmt = GL_RGBA;\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tpixfmt = GL_LUMINANCE;\n\t\t\tinternalfmt = GL_LUMINANCE;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\t\tpixfmt = GL_RGB;\n\t\t\tinternalfmt = GL_RGB;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tpixfmt = GL_RGBA;\n\t\t\tinternalfmt = GL_RGBA;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tunsigned int pitch = Bitmap->GetPitch();\n\t\tswitch (pitch & 7) {\n\t\tcase 0: glPixelStorei(GL_UNPACK_ALIGNMENT, 8); break;\n\t\tcase 2: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tcase 4: glPixelStorei(GL_UNPACK_ALIGNMENT, 4); break;\n\t\tcase 6: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tdefault: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); break;\n\t\t}\n\n\t\tTVPCheckMemory();\n\t\t_glBindTexture2D(texinfo.Name);\n\t\ttexinfo.Width = pitch / pixsize;\n\t\ttexinfo.Height = rc.get_height();\n\t\tif (texinfo.Width > GetMaxTextureWidth()) {\n\t\t\ttexinfo.Width = rc.get_width();\n\t\t\tassert(texinfo.Width <= GetMaxTextureWidth());\n\t\t\tglTexImage2D(GL_TEXTURE_2D, 0, internalfmt, texinfo.Width, texinfo.Height, 0, pixfmt, GL_UNSIGNED_BYTE, nullptr);\n\t\t\tunsigned char *pix = nullptr;\n\t\t\tif (GL_CHECK_unpack_subimage) {\n\t\t\t\tpix = (unsigned char*)Bitmap->GetScanLine(rc.top);\n\t\t\t\tglPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixsize);\n\t\t\t} else {\n\t\t\t\tpix = new unsigned char [texinfo.Width * texinfo.Height * pixsize];\n\t\t\t\tunsigned char* src = (unsigned char*)Bitmap->GetScanLine(rc.top);\n\t\t\t\tunsigned char* dst = pix;\n\t\t\t\tint dpitch = texinfo.Width * pixsize;\n\t\t\t\tfor (int y = 0; y < texinfo.Height; ++y) {\n\t\t\t\t\tmemcpy(dst, src, dpitch);\n\t\t\t\t\tsrc += pitch;\n\t\t\t\t\tdst += dpitch;\n\t\t\t\t}\n\t\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\t\t\t}\n\t\t\tglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texinfo.Width, texinfo.Height, pixfmt, GL_UNSIGNED_BYTE, pix);\n\t\t\tif (GL_CHECK_unpack_subimage) {\n\t\t\t\tglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);\n\t\t\t} else {\n\t\t\t\tdelete[] pix;\n\t\t\t}\n\t\t} else {\n\t\t\tglTexImage2D(GL_TEXTURE_2D, 0, internalfmt, texinfo.Width, texinfo.Height, 0, pixfmt, GL_UNSIGNED_BYTE, Bitmap->GetScanLine(rc.top));\n\t\t}\n\n\t\t// if size is same, is's better to use glTexSubImage2D\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tvoid AsSingleTexture() {\n\t\tClearTextureCache();\n\t\tinternalW = Bitmap->GetWidth(), internalH = Bitmap->GetHeight();\n\t\tif (internalW > GetMaxTextureWidth()) {\n\t\t\t_scaleW = (float)GetMaxTextureWidth() / internalW;\n\t\t\tinternalW = GetMaxTextureWidth();\n\t\t}\n\t\tif (internalH > GetMaxTextureHeight()) {\n\t\t\t_scaleH = (float)GetMaxTextureHeight() / internalH;\n\t\t\tinternalH = GetMaxTextureHeight();\n\t\t}\n\n\t\tunsigned char *tmp = new unsigned char[internalW * internalH * 4];\n\t\tcv::Size dsize(internalW, internalH);\n\t\tcv::Mat src_img(Bitmap->GetHeight(), Bitmap->GetWidth(), CV_8UC4, (void*)Bitmap->GetBits(), Bitmap->GetPitch());\n\t\tcv::Mat dst_img(internalH, internalW, CV_8UC4, (void*)tmp, internalW * 4);\n\t\tcv::resize(src_img, dst_img, dsize, 0, 0, cv::INTER_LINEAR);\n\n\t\tBitmap->Release(); // release here to relieve memory peak\n\t\tBitmap = nullptr;\n\n\t\tunsigned int pixsize = Format & 0xF;\n\t\tGLenum pixfmt = GL_RGBA;\n\t\tGLenum internalfmt = GL_RGBA;\n\t\tswitch (Format) {\n\t\tcase TVPTextureFormat::Gray:\n\t\t\tpixfmt = GL_LUMINANCE;\n\t\t\tinternalfmt = GL_LUMINANCE;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGB:\n\t\t\tpixfmt = GL_RGB;\n\t\t\tinternalfmt = GL_RGB;\n\t\t\tbreak;\n\t\tcase TVPTextureFormat::RGBA:\n\t\t\tpixfmt = GL_RGBA;\n\t\t\tinternalfmt = GL_RGBA;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tunsigned int pitch = internalW * 4;\n\t\tswitch (pitch & 7) {\n\t\tcase 0: glPixelStorei(GL_UNPACK_ALIGNMENT, 8); break;\n\t\tcase 4: glPixelStorei(GL_UNPACK_ALIGNMENT, 4); break;\n\t\t}\n\n\t\tTVPCheckMemory();\n\t\ttexture = FetchGLTexture();\n\t\tglTexImage2D(GL_TEXTURE_2D, 0, internalfmt, internalW, internalH, 0, pixfmt, GL_UNSIGNED_BYTE, tmp);\n\n\t\tdelete[] tmp;\n\t}\n\n\tvirtual void ApplyVertex(GLVertexInfo &vtx, const tTVPPointD *p, int n) {\n\t\tif (!Bitmap) { // route of downscaled single texture\n\t\t\tvtx.tex = this;\n\t\t\tvtx.vtx.resize(n * 2); GLfloat* pt = &vtx.vtx.front();\n\t\t\tfloat tw = _scaleW / internalW;\n\t\t\tfloat th = _scaleH / internalH;\n\t\t\tfor (int i = 0; i < n; ++i) {\n\t\t\t\tpt[i * 2 + 0] = (float)p[i].x * tw;\n\t\t\t\tpt[i * 2 + 1] = (float)p[i].y * th;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tdouble\n\t\t\tl = Bitmap->GetWidth(),\n\t\t\tt = Bitmap->GetHeight(),\n\t\t\tr = 0,\n\t\t\tb = 0;\n\t\tfor (int i = 0; i < n; ++i) {\n\t\t\tconst tTVPPointD &pt = p[i];\n\t\t\tif (pt.x < l) l = pt.x;\n\t\t\tif (pt.y < t) t = pt.y;\n\t\t\tif (pt.x > r) r = pt.x;\n\t\t\tif (pt.y > b) b = pt.y;\n\t\t}\n\t\ttTVPRect rc(std::floor(l), std::floor(t), std::ceil(r), std::ceil(b));\n\t\ttjs_uint w = rc.get_width(), h = rc.get_height();\n\t\tif (w > GetMaxTextureWidth() || h > GetMaxTextureHeight()) {\n\t\t\tAsSingleTexture();\n\t\t\treturn ApplyVertex(vtx, p, n);\n\t\t}\n\n\t\tvtx.tex = this;\n\t\tGLTextureInfoIndexer indexer;\n\t\tindexer.Point.X = rc.left;\n\t\tindexer.Point.Y = rc.top;\n\t\tGLTextureInfo* texinfo;\n\t\tauto it = CachedTexture.find(indexer.Index);\n\t\tif (it != CachedTexture.end()) {\n\t\t\ttexinfo = &it->second;\n\t\t\ttexture = texinfo->Name;\n\t\t\tw = std::min(w, Bitmap->GetWidth());\n\t\t\th = std::min(h, Bitmap->GetHeight());\n\t\t\tif (texinfo->Width < w || texinfo->Height < h) {\n\t\t\t\tUpdateTextureData(*texinfo, rc);\n\t\t\t}\n\t\t} else {\n\t\t\ttexture = FetchGLTexture();\n\t\t\ttexinfo = &CachedTexture[indexer.Index];\n\t\t\ttexinfo->Name = texture;\n\t\t\ttexinfo->Point = indexer.Point;\n\t\t\tUpdateTextureData(*texinfo, rc);\n\t\t}\n\n\t\tvtx.vtx.resize(n * 2); GLfloat* pt = &vtx.vtx.front();\n\t\tfor (int i = 0; i < n; ++i) {\n\t\t\tpt[i * 2 + 0] = p[i].x - rc.left;\n\t\t\tpt[i * 2 + 1] = p[i].y - rc.top;\n\t\t}\n\t}\n\n\tvirtual void ApplyVertex(GLVertexInfo &vtx, const tTVPRect &rc) {\n\t\tif (!Bitmap) {\n\t\t\tvtx.tex = this;\n\t\t\tGLfloat sminu, smaxu, sminv, smaxv;\n\t\t\tsminu = (GLfloat)rc.left;\n\t\t\tsmaxu = (GLfloat)rc.right;\n\t\t\tsminv = (GLfloat)rc.top;\n\t\t\tsmaxv = (GLfloat)rc.bottom;\n\t\t\tfloat tw = _scaleW / internalW;\n\t\t\tfloat th = _scaleH / internalH;\n\t\t\tsminu *= tw; smaxu *= tw;\n\t\t\tsminv *= th; smaxv *= th;\n\t\t\tvtx.vtx.resize(6 * 2); GLfloat* pt = &vtx.vtx.front();\n\t\t\tpt[0] = sminu; pt[1] = sminv;\n\t\t\tpt[2] = smaxu; pt[3] = sminv;\n\t\t\tpt[4] = sminu; pt[5] = smaxv;\n\n\t\t\tpt[6] = smaxu; pt[7] = sminv;\n\t\t\tpt[8] = sminu; pt[9] = smaxv;\n\t\t\tpt[10] = smaxu; pt[11] = smaxv;\n\t\t\treturn;\n\t\t}\n\t\ttjs_uint w = rc.get_width(), h = rc.get_height();\n\t\tif (w > GetMaxTextureWidth() || h > GetMaxTextureHeight()) {\n\t\t\tAsSingleTexture();\n\t\t\treturn ApplyVertex(vtx, rc);\n\t\t}\n\t\tvtx.tex = this;\n\t\tGLTextureInfoIndexer indexer;\n\t\tindexer.Point.X = rc.left;\n\t\tindexer.Point.Y = rc.top;\n\t\tGLTextureInfo* texinfo;\n\t\tauto it = CachedTexture.find(indexer.Index);\n\t\tif (it != CachedTexture.end()) {\n\t\t\ttexinfo = &it->second;\n\t\t\ttexture = texinfo->Name;\n\t\t\tw = std::min(w, Bitmap->GetWidth());\n\t\t\th = std::min(h, Bitmap->GetHeight());\n\t\t\tif (texinfo->Width < w || texinfo->Height < h) {\n\t\t\t\tUpdateTextureData(*texinfo, rc);\n\t\t\t}\n\t\t//\tit->second.LastAccessTimeStamp = 120; // max to 120 frames ?\n\t\t} else {\n\t\t\ttexture = FetchGLTexture();\n\t\t\ttexinfo = &CachedTexture[indexer.Index];\n\t\t\ttexinfo->Name = texture;\n\t\t//\ttexinfo->LastAccessTimeStamp = 120;\n\t\t\ttexinfo->Point = indexer.Point;\n\t\t\tUpdateTextureData(*texinfo, rc);\n\t\t}\n\n\t\tvtx.vtx.resize(6 * 2); GLfloat* pt = &vtx.vtx.front();\n\t\tGLfloat sminu, smaxu, sminv, smaxv;\n\t\tsminu = (GLfloat)0;\n\t\tsmaxu = (GLfloat)w / texinfo->Width;\n\t\tsminv = (GLfloat)0;\n\t\tsmaxv = (GLfloat)h / texinfo->Height;\n\n\t\tpt[0] = sminu; pt[1] = sminv;\n\t\tpt[2] = smaxu; pt[3] = sminv;\n\t\tpt[4] = sminu; pt[5] = smaxv;\n\n\t\tpt[6] = smaxu; pt[7] = sminv;\n\t\tpt[8] = sminu; pt[9] = smaxv;\n\t\tpt[10] = smaxu; pt[11] = smaxv;\n\t}\n};\n\nclass tTVPOGLTexture2D_static : public tTVPOGLTexture2D {\npublic:\n\t// for manual init\n\ttTVPOGLTexture2D_static(TVPTextureFormat::e format, unsigned int tw, unsigned int th, float sw, float sh, GLint mode = GL_LINEAR)\n\t\t: tTVPOGLTexture2D(tw, th, format, mode) {\n\t\t_scaleW = sw; _scaleH = sh;\n\t}\n\n\ttTVPOGLTexture2D_static(const void *pixel, int pitch, unsigned int iw, unsigned int ih, TVPTextureFormat::e format,\n\t\tunsigned int tw, unsigned int th, float sw, float sh, GLint mode = GL_LINEAR)\n\t\t: tTVPOGLTexture2D(tw, th, format, mode)\n\t{\n\t\t_scaleW = sw; _scaleH = sh;\n\t//\tassert(pixel); // pixel must be exist\n\t\tint pixsize = getPixelSize();\n\t\tif (pitch == iw * pixsize || ((pitch & 7) == 0 && pitch - iw * pixsize < 8)) {\n\t\t\tInternalInit(pixel, iw, ih, pitch);\n\t\t} else if (GL_CHECK_unpack_subimage) {\n\t\t\tInternalInit(nullptr, iw, ih, 0);\n\t\t\tInternalUpdate(pixel, pitch, 0, 0, iw, ih);\n\t\t} else { // rearrange\n\t\t\tInternalInit(nullptr, iw, ih, 0);\n\t\t\tPixelData = new unsigned char[internalW * internalH * 4];\n\t\t\tint linesize = internalW * pixsize, dstpitch = internalW * 4;\n\t\t\tunsigned char *src = (unsigned char *)pixel;\n\t\t\tunsigned char *dst = (unsigned char *)PixelData;\n\t\t\tfor (unsigned int y = 0; y < internalH; ++y) {\n\t\t\t\tmemcpy(dst, src, linesize);\n\t\t\t\tsrc += pitch;\n\t\t\t\tdst += dstpitch;\n\t\t\t}\n\t\t\tInternalUpdate(PixelData, dstpitch, 0, 0, internalW, internalH);\n\t\t\tdelete[]PixelData;\n\t\t\tPixelData = nullptr;\n\t\t}\n\t\t//_totalVMemSize += internalW * internalH * pixsize;\n\t}\n\n\t// for compressed texture format\n\ttTVPOGLTexture2D_static(const void *data, int len, GLenum format, unsigned int tw, unsigned int th, unsigned int iw, unsigned int ih, float sw, float sh)\n\t\t: tTVPOGLTexture2D(tw, th, TVPTextureFormat::RGBA, GL_LINEAR)\n\t{\n\t\t_scaleW = sw; _scaleH = sh;\n\t\tInitCompressedPixel(data, len, format, iw, ih);\n\t}\n\n\tvoid InitCompressedPixel(const void *data, unsigned int len, GLenum format, unsigned int width, unsigned int height) {\n\t\tTVPCheckMemory();\n\t\t_glBindTexture2D(texture);\n\t\tglCompressedTexImage2D(GL_TEXTURE_2D, 0, format/*GL_ETC1_RGB8_OES*/, width, height, 0, len, data);\n\t\tIsCompressed = true;\n\t\tinternalW = width; internalH = height;\n\t\t_totalVMemSize += internalW * internalH * getPixelSize()/*len*/;\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tvoid InitPixel(const void* pixel, unsigned int pitch, GLenum format, GLenum pixfmt, unsigned int intw, unsigned int inth) {\n\t\tTVPCheckMemory();\n\t\t_glBindTexture2D(texture);\n\t\tglTexImage2D(GL_TEXTURE_2D, 0, format, intw, inth, 0, pixfmt, GL_UNSIGNED_BYTE, pixel);\n\n\t\tswitch (pitch & 7) {\n\t\tcase 0: glPixelStorei(GL_UNPACK_ALIGNMENT, 8); break;\n\t\tcase 2: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tcase 4: glPixelStorei(GL_UNPACK_ALIGNMENT, 4); break;\n\t\tcase 6: glPixelStorei(GL_UNPACK_ALIGNMENT, 2); break;\n\t\tdefault: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); break;\n\t\t}\n\n\t\tinternalW = intw; internalH = inth;\n\t\t_totalVMemSize += internalW * internalH * getPixelSize();\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) {\n\t\tif (PixelData) {\n\t\t\tdelete[] PixelData;\n\t\t\tPixelData = nullptr;\n\t\t}\n\t\tInternalUpdate(pixel, pitch, rc.left, rc.top, rc.get_width(), rc.get_height());\n\t};\n\n\tvirtual void * GetScanLineForWrite(tjs_uint l) {\n\t\tassert(false);\n\t\treturn nullptr;\n\t}\n\n\tvirtual void SetPoint(int x, int y, uint32_t clr) {\n\t\tif (texture) {\n\t\t\t_glBindTexture2D(texture);\n\t\t\t//glBindTexture(GL_TEXTURE_2D, texture);\n\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\t\t\tglTexSubImage2D(GL_TEXTURE_2D,\n\t\t\t\t0, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &clr);\n\t\t}\n\t}\n\n\tvirtual void SetSize(unsigned int w, unsigned int h) {\n\t\tassert(false);\n\t}\n\n\tvirtual bool IsStatic() { return true; }\n};\n\nclass tTVPOGLTexture2D_mutatble : public tTVPOGLTexture2D {\n\tbool IsTextureDirty;\n\npublic:\n\ttTVPOGLTexture2D_mutatble(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format, float sw, float sh)\n\t\t: tTVPOGLTexture2D(w, h, format == TVPTextureFormat::RGB ? TVPTextureFormat::RGBA : format, GL_LINEAR)\n\t{\n\t\tif (!pixel) {\n\t\t\t_scaleW = sw; _scaleH = sh;\n\t\t\tunsigned int intw = power_of_two(w * sw), inth = power_of_two(h * sh);\n\t\t\tif (intw < w) _scaleW = (float)intw / w; // use entire texture if possible\n\t\t\tif (inth < h) _scaleH = (float)inth / h;\n\t\t\tInternalInit(nullptr, intw, inth, 0);\n\t\t\tIsTextureDirty = false;\n\t\t\treturn;\n\t\t}\n\t\tassert(sw == 1.f && sh == 1.f);\n\n\t\tint pixsize = getPixelSize();\n\t\tint intw = w, inth = h;\n\t\tif (pixel) intw = pitch / pixsize;\n\t\tintw = power_of_two(intw), inth = power_of_two(inth);\n\t\tif (!pixel || pitch == intw * pixsize) {\n\t\t\tif (inth == h) {\n\t\t\t\tInternalInit(pixel, intw, inth, pitch);\n\t\t\t\tIsTextureDirty = false;\n\t\t\t} else {\n\t\t\t\tInternalInit(nullptr, intw, inth, 0);\n\t\t\t\tIsTextureDirty = false;\n\t\t\t\tif (pixel)\n\t\t\t\t\tUpdate(pixel, Format, pitch, tTVPRect(0, 0, w, h));\n\t\t\t}\n\t\t} else if (w == Width) {\n\t\t\tInternalInit(nullptr, intw, inth, 0);\n\t\t\tUpdate(pixel, Format, pitch, tTVPRect(0, 0, pitch / pixsize, h));\n\t\t} else if (GL_CHECK_unpack_subimage || pitch == w * pixsize) {\n\t\t\tInternalInit(nullptr, intw, inth, 0);\n\t\t\tUpdate(pixel, Format, pitch, tTVPRect(0, 0, w, h));\n\t\t} else {\n\t\t\tInternalInit(nullptr, intw, inth, 0);\n\t\t\tPixelData = new unsigned char[internalW * internalH * 4];\n\t\t\tint linesize = w * pixsize, dstpitch = internalW * 4;\n\t\t\tunsigned char *src = (unsigned char *)pixel;\n\t\t\tunsigned char *dst = (unsigned char *)PixelData;\n\t\t\tfor (unsigned int y = 0; y < h; ++y) {\n\t\t\t\tmemcpy(dst, src, linesize);\n\t\t\t\tsrc += pitch;\n\t\t\t\tdst += dstpitch;\n\t\t\t}\n\t\t\tIsTextureDirty = true;\n\t\t}\n\t}\n\n\tvirtual void SyncPixel() override {\n\t\tif (PixelData) {\n\t\t\tif (IsTextureDirty) {\n\t\t\t\tInternalUpdate(PixelData, internalW * 4, 0, 0, internalW, internalH);\n\t\t\t\tIsTextureDirty = false;\n\t\t\t\tdelete[] PixelData;\n\t\t\t\tPixelData = nullptr;\n\t\t\t} else if (--PixelDataCounter <= 0) {\n\t\t\t\tIsTextureDirty = false;\n\t\t\t\tdelete[] PixelData;\n\t\t\t\tPixelData = nullptr;\n\t\t\t}\n\t\t}\n\t}\n\n\tvirtual void Update(const void *pixel, TVPTextureFormat::e format, int pitch, const tTVPRect& rc) {\n\t\tif (PixelData) {\n\t\t\tif (rc.left > 0 || rc.top > 0 || rc.bottom < Height || rc.right < Width) {\n\t\t\t\tunsigned char *src = (unsigned char *)pixel, *dst = (unsigned char *)PixelData;\n\t\t\t\tint dpitch = internalW * 4;\n\t\t\t\tfor (int y = 0; y < Height; ++y) {\n\t\t\t\t\tmemcpy(dst, src, dpitch);\n\t\t\t\t\tsrc += pitch; dst += dpitch;\n\t\t\t\t}\n\t\t\t\tpixel = PixelData; pitch = internalW * 4;\n\t\t\t\tPixelDataCounter = 5;\n\t\t\t} else {\n\t\t\t\tdelete[] PixelData;\n\t\t\t\tPixelData = nullptr;\n\t\t\t}\n\t\t\tIsTextureDirty = false;\n\t\t}\n\t\tInternalUpdate(pixel, pitch, rc.left, rc.top, rc.get_width(), rc.get_height());\n\t}\n\n\tvirtual void * GetScanLineForWrite(tjs_uint l) {\n\t\tIsTextureDirty = true;\n\t\treturn (void*)GetScanLineForRead(l);\n\t}\n\n\tvirtual void SetPoint(int x, int y, tjs_uint32 clr) {\n\t\tif (texture) {\n\t\t\tSyncPixel();\n\t\t\t_glBindTexture2D(texture);\n\t\t\t//glBindTexture(GL_TEXTURE_2D, texture);\n\t\t\tglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\t\t\tglTexSubImage2D(GL_TEXTURE_2D,\n\t\t\t\t0, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &clr);\n\t\t}\n\t}\n\n\tvirtual void SetSize(unsigned int w, unsigned int h) {\n\t\tif (w > internalW || h > internalH) {\n\t\t\tif (PixelData) {\n\t\t\t\tdelete[]PixelData;\n\t\t\t\tPixelData = nullptr;\n\t\t\t}\n\t\t\tInternalInit(nullptr, power_of_two(w), power_of_two(h), 0);\n\t\t}\n\t\tWidth = w; Height = h;\n\t}\n\n\tvirtual bool IsStatic() override { return false; }\n\n\tvirtual void AsTarget() override {\n\t\tSyncPixel();\n\t\tTVPSetRenderTarget(texture);\n\t}\n};\n\nclass tTVPOGLRenderMethod : public iTVPRenderMethod {\nprotected:\n\tfriend class TVPRenderManager_OpenGL;\n\tGLint pos_attr_location;\n\tstd::vector<GLint> tex_coord_attr_location;\n\tGLenum program;\n\tint BlendFunc = 0, BlendSrcRGB, BlendDstRGB, BlendSrcA, BlendDstA;\n// \ttypedef bool(tTVPOGLRenderMethod::*FCustomProc)(tTVPOGLTexture2D *, const tTVPRect&, const std::vector<GLVertexInfo>&);\n// \tFCustomProc CustomProc;\n\tbool tar_as_src;\n\npublic:\n\ttTVPOGLRenderMethod() : tar_as_src(false)/*, CustomProc(nullptr)*/ {}\n\tGLint GetPosAttr() const {\n\t\treturn pos_attr_location;\n\t}\n\tGLint GetTexCoordAttr(unsigned int n) {\n\t\tif (n >= tex_coord_attr_location.size()) return -1;\n\t\treturn tex_coord_attr_location[n];\n\t}\n\tvirtual void Rebuild() = 0;\n\tvirtual void Apply() = 0;\n\tvirtual void onFinish() {}\n\ttTVPOGLRenderMethod* SetTargetAsSrc() { tar_as_src = true; return this; }\n\tvirtual tTVPOGLRenderMethod* SetBlendFuncSeparate(int func, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) override {\n\t\tBlendFunc = func;\n\t\tBlendSrcRGB = srcRGB;\n\t\tBlendDstRGB = dstRGB;\n\t\tBlendSrcA = srcAlpha;\n\t\tBlendDstA = dstAlpha;\n\t\treturn this;\n\t}\n\tvirtual bool IsBlendTarget() { return !!BlendFunc; }\n\tvirtual void ApplyTexture(unsigned int i, const GLVertexInfo &info) {\n\t\tinfo.tex->Bind(i);\n\t\tglVertexAttribPointer(GetTexCoordAttr(i), 2, GL_FLOAT, GL_FALSE, 0, &info.vtx.front());\n\t}\n\n\tbool(*CustomProc)(tTVPOGLRenderMethod *_method, tTVPOGLTexture2D *_tar, tTVPOGLTexture2D *reftar, const tTVPRect* rctar, const tRenderTexRectArray &textures) = nullptr;\n};\n\nstatic GLenum CompileShader(GLint shadertype, const std::string &src) {\n\tGLenum shader = glCreateShader(shadertype);\n\tGLint status;\n\tconst char *pszSource = src.c_str();\n\n\tglShaderSource(shader, 1, &pszSource, NULL);\n\tglCompileShader(shader);\n\tglGetShaderiv(shader, GL_COMPILE_STATUS, &status);\n\tif (status == 0) {\n\t\tGLint length;\n\t\tglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);\n\t\tchar *info = new char[length + 1];\n\t\tinfo[length] = 0;\n\t\tglGetShaderInfoLog(shader, length, NULL, info);\n\t\tttstr _info(info);\n\t\tdelete[]info;\n\t\tTVPThrowExceptionMessage(TJS_W(\"Failed to compile shader: %1\"), _info);\n\t\treturn 0;\n\t} else {\n\t\treturn shader;\n\t}\n}\n\nstatic GLenum CombineProgram(GLenum vert, GLenum frag) {\n\t/* Create one program object to rule them all */\n\tGLenum program = glCreateProgram();\n\t/* ... and in the darkness bind them */\n\tglAttachShader(program, vert);\n\tglAttachShader(program, frag);\n\tglLinkProgram(program);\n\n\tGLint linkSuccessful;\n\tglGetProgramiv(program, GL_LINK_STATUS, &linkSuccessful);\n\tif (!linkSuccessful)\n\t{\n\t\tGLint length = 0;\n\t\tglGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);\n\t\tchar *info = new char[length + 1];\n\t\tinfo[length] = 0;\n\t\tglGetProgramInfoLog(program, length, NULL, info);\n\t\tTVPThrowExceptionMessage(TJS_W(\"Failed to link shader program:\\n%1\"), info);\n\t\tdelete[]info;\n\t\treturn -1;\n\t}\n\n\treturn program;\n}\n\nclass tTVPOGLRenderMethod_Script : public tTVPOGLRenderMethod {\nprotected:\n\tstd::string m_strScript;\n\tint m_nTex;\n\t\npublic:\n\tint GetValidTex() {\n\t\treturn m_nTex - tar_as_src;\n\t}\n\tbool init(const std::string &body, int nTex, const char *prefix = nullptr) {\n\t\tm_nTex = nTex;\n\t\tstd::ostringstream str;\n\t\tif (prefix) str << prefix;\n\t\tstr <<\n\t\t\t\"#ifdef GL_ES\\n\"\n\t\t\t\"precision mediump float;\\n\"\n\t\t\t\"#endif\\n\";\n\t\tstd::ostringstream unif;\n\t\tfor (int i = 0; i < nTex; ++i) {\n\t\t\tstr << \"varying vec2 v_texCoord\";\n\t\t\tstr << i;\n\t\t\tstr << \";\\n\";\n\n\t\t\tunif << \"uniform sampler2D tex\";\n\t\t\tunif << i;\n\t\t\tunif << \";\\n\";\n\t\t}\n\t\tstr << unif.str();\n\t\tstr << body;\n\t\tm_strScript = str.str();\n\t\tRebuild();\n\t\treturn true;\n\t}\n\tvirtual void SetParameterColor4B(int id, unsigned int clr) {\n\t\tcocos2d::GL::useProgram(program);\n\t\tglUniform4f(id,\n\t\t\t(clr & 0xFF) / 255.0f,\n\t\t\t((clr >> 8) & 0xFF) / 255.0f,\n\t\t\t((clr >> 16) & 0xFF) / 255.0f,\n\t\t\t(clr >> 24) / 255.0f);\n\t};\n\tvirtual int EnumParameterID(const char *name) {\n\t\tint ret = glGetUniformLocation(program, name);\n#ifdef _DEBUG\n\t\t//assert(ret >= 0);\n#endif\n\t\treturn ret;\n\t}\n\tvirtual void SetParameterOpa(int id, int Value) {\n\t\tcocos2d::GL::useProgram(program);\n\t\tglUniform1f(id, Value / 255.f);\n\t};\n\tvirtual void SetParameterFloat(int id, float Value) {\n\t\tcocos2d::GL::useProgram(program);\n\t\tglUniform1f(id, Value);\n\t}\n\tvirtual void SetParameterFloatArray(int id, float *Value, int nElem) {\n\t\tcocos2d::GL::useProgram(program);\n\t\tswitch (nElem) {\n\t\tcase 2:\n\t\t\tglUniform2f(id, Value[0], Value[1]);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tglUniform3f(id, Value[0], Value[1], Value[2]);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tglUniform4f(id, Value[0], Value[1], Value[2], Value[4]);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tstatic std::vector<GLenum> m_cachedSahder;\n\tstatic void ClearCache() { m_cachedSahder.clear(); }\n\tstatic GLenum GetVertShader(unsigned int nTex) {\n\t\tif (nTex >= m_cachedSahder.size()) {\n\t\t\tm_cachedSahder.resize(nTex + 1);\n\t\t}\n\t\tif (!m_cachedSahder[nTex]) {\n\t\t\tstd::ostringstream shader;\n\t\t\tshader <<\n\t\t\t\t\"#ifdef GL_ES\\n\"\n\t\t\t\t\"precision mediump float;\\n\"\n\t\t\t\t\"#endif\\n\";\n\t\t\tshader << \"attribute vec2 a_position;\\n\";\n\t\t\tstd::ostringstream body;\n\t\t\tbody <<\n\t\t\t\t\"void main() {\\n\"\n\t\t\t\t\"    gl_Position = vec4(a_position, 0.0, 1.0);\\n\";\n\t\t\tstd::ostringstream vary;\n\t\t\tfor (unsigned int i = 0; i < nTex; ++i) {\n\t\t\t\tshader << \"attribute vec2 a_texCoord\";\n\t\t\t\tshader << i;\n\t\t\t\tshader << \";\\n\"; // attribute vec2 a_texCoord0;\n\t\t\t\tvary << \"varying vec2 v_texCoord\";\n\t\t\t\tvary << i;\n\t\t\t\tvary << \";\\n\"; // varying vec2 v_texCoord0;\n\t\t\t\tbody << \"    v_texCoord\";\n\t\t\t\tbody << i;\n\t\t\t\tbody << \" = a_texCoord\";\n\t\t\t\tbody << i;\n\t\t\t\tbody << \";\\n\"; // v_texCoord0 = a_texCoord0;\n\t\t\t}\n\t\t\tshader << vary.str();\n\t\t\tshader << body.str();\n\t\t\tshader << \"}\";\n\t\t\tm_cachedSahder[nTex] = CompileShader(GL_VERTEX_SHADER, shader.str());\n\t\t}\n\t\treturn m_cachedSahder[nTex];\n\t}\n\n\tvirtual void Rebuild() {\n\t\ttry {\n\t\t\tprogram = CombineProgram(GetVertShader(m_nTex),\n\t\t\t\tCompileShader(GL_FRAGMENT_SHADER, m_strScript));\n\t\t} catch (eTJSError &e) {\n\t\t\te.AppendMessage(\"\\n\");\n\t\t\te.AppendMessage(Name);\n\t\t\tthrow;\n\t\t}\n\t\tcocos2d::GL::useProgram(program);\n\t\tstd::string tex(\"tex\");\n\t\tstd::string coord(\"a_texCoord\");\n\t\tfor (int i = 0; i < m_nTex; ++i) {\n\t\t\tchar sCounter[8];\n\t\t\tsprintf(sCounter, \"%d\", i);\n\t\t\tint loc = glGetUniformLocation(program, (tex + sCounter).c_str());\n\t\t\tglUniform1i(loc, i);\n\t\t\tloc = glGetAttribLocation(program, (coord + sCounter).c_str());\n\t\t\ttex_coord_attr_location.push_back(loc);\n\t\t}\n\t\tpos_attr_location = glGetAttribLocation(program, \"a_position\");\n\t}\n\tvirtual void Apply() {\n\t\tcocos2d::GL::useProgram(program);\n\t\tif (BlendFunc) {\n\t\t\tglEnable(GL_BLEND);\n\t\t\tglBlendEquation(BlendFunc);\n\t\t\tglBlendFuncSeparate(BlendSrcRGB, BlendDstRGB, BlendSrcA, BlendDstA);\n\t\t} else {\n\t\t\tglDisable(GL_BLEND);\n\t\t}\n\t}\n\tconst std::string &GetScript() {\n\t\treturn m_strScript;\n\t}\n};\nstd::vector<GLenum> tTVPOGLRenderMethod_Script::m_cachedSahder;\n\nclass tTVPOGLRenderMethod_FillARGB : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\n\tuint32_t m_color;\n\npublic:\n\ttTVPOGLRenderMethod_FillARGB() {\n\t\tif (GL::glClearTexImage && GL::glClearTexSubImage) {\n\t\t\tCustomProc = &tTVPOGLRenderMethod_FillARGB::DoFill;\n\t\t}\n\t}\n\n\tvirtual int EnumParameterID(const char *name) {\n\t\treturn 0;\n\t}\n\tvirtual void SetParameterColor4B(int id, unsigned int clr) {\n\t\tif (CustomProc) m_color = clr;\n\t\telse inherit::SetParameterColor4B(id, clr);\n\t};\n\n\tstatic bool DoFill(tTVPOGLRenderMethod *method, tTVPOGLTexture2D *tar, tTVPOGLTexture2D *, const tTVPRect* rctar, const tRenderTexRectArray &) {\n\t\tuint32_t c = static_cast<tTVPOGLRenderMethod_FillARGB*>(method)->m_color;\n\t\tuint8_t clr[4] = {\n\t\t\t(uint8_t)c,\n\t\t\t(uint8_t)(c >> 8),\n\t\t\t(uint8_t)(c >> 16),\n\t\t\t(uint8_t)(c >> 24)\n\t\t};\n\t\tif (rctar->left <= 0 && rctar->top <= 0 && rctar->get_width() >= tar->GetWidth() && rctar->get_height() >= tar->GetHeight()) {\n\t\t\tGL::glClearTexImage(tar->texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, clr);\n\t\t} else {\n\t\t\tfloat sw, sh;\n\t\t\ttar->GetScale(sw, sh);\n\t\t\tif (sw != 1.f && sh != 1.f) return false;\n\t\t\tGL::glClearTexSubImage(tar->texture, 0, rctar->left, rctar->top, 0, rctar->get_width(), rctar->get_height(),\n\t\t\t\t1, GL_RGBA, GL_UNSIGNED_BYTE, clr);\n\t\t}\n\t\tCHECK_GL_ERROR_DEBUG();\n#ifdef _DEBUG\n\t\tstatic bool check = false;\n\t\tif (check) {\n\t\t\tcv::Mat _src(tar->GetInternalHeight(), tar->GetInternalWidth(), CV_8UC4);\n\t\t\tGL::glGetTextureImage(tar->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, tar->GetInternalHeight() * tar->GetInternalWidth() * 4, _src.ptr(0, 0));\n\t\t}\n#endif\n\t\treturn true;\n#if 0\n\t\ttar->AsTarget();\n\t\tglViewport(rctar.left, rctar.top, rctar.get_width(), rctar.get_height());\n\t\tglClearColor(\n\t\t\t(m_color & 0xFF) / 255.0f,\n\t\t\t((m_color >> 8) & 0xFF) / 255.0f,\n\t\t\t((m_color >> 16) & 0xFF) / 255.0f,\n\t\t\t(m_color >> 24) / 255.0f);\n\t\tglClear(GL_COLOR_BUFFER_BIT);\n\t\treturn true;\n#endif\n\t}\n};\n\nclass tTVPOGLRenderMethod_AlphaTest : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\npublic:\n\tvirtual int EnumParameterID(const char *name) override {\n\t\tif (!strcmp(\"alpha_threshold\", name)) {\n\t\t\treturn 0xA19A1E21;\n\t\t} else {\n\t\t\treturn inherit::EnumParameterID(name);\n\t\t}\n\t}\n\n\tvirtual void SetParameterOpa(int id, int Value) {\n\t\tif (id == 0xA19A1E21) {\n\t\t//\tglEnable(GL_ALPHA_TEST);\n\t\t\tGL::glAlphaFunc(GL_GREATER, Value / 255.f);\n\t\t} else {\n\t\t\treturn inherit::SetParameterOpa(id, Value);\n\t\t}\n\t}\n\n\tvirtual void Apply() override {\n\t\tinherit::Apply();\n\t\tglEnable(GL_ALPHA_TEST);\n\t}\n\n\tvirtual void onFinish() {\n\t\tglDisable(GL_ALPHA_TEST);\n\t}\n};\n\nclass tTVPOGLRenderMethod_Script_BlendColor : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"opacity\")) {\n\t\t\treturn 0x709AC167;\n\t\t}\n\t\treturn inherit::EnumParameterID(name);\n\t}\n\tvirtual void SetParameterOpa(int id, int Value) override {\n\t\tif (id == 0x709AC167) {\n\t\t\tfloat v = Value / 255.f;\n\t\t\tcocos2d::GL::useProgram(program);\n\t\t\tglBlendColor(v, v, v, v);\n\t\t} else {\n\t\t\tinherit::SetParameterOpa(id, Value);\n\t\t}\n\t};\n\tvirtual void SetParameterFloat(int id, float Value) override {\n\t\tif (id == 0x709AC167) {\n\t\t\tfloat v = Value;\n\t\t\tcocos2d::GL::useProgram(program);\n\t\t\tglBlendColor(v, v, v, v);\n\t\t} else {\n\t\t\tinherit::SetParameterFloat(id, Value);\n\t\t}\n\t};\n};\n\nclass tTVPOGLRenderMethod_AdjustGamma : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"gammaAdjustData\")) {\n\t\t\treturn 0x3a33aad6;\n\t\t}\n\t\treturn inherit::EnumParameterID(name);\n\t}\n\tvirtual void SetParameterPtr(int id, const void *v) {\n\t\tif (id == 0x3a33aad6) {\n\t\t\tconst tTVPGLGammaAdjustData &data = *(const tTVPGLGammaAdjustData*)v;\n\t\t\tstatic int\n\t\t\t\tid_gamma = EnumParameterID(\"u_gamma\"),\n\t\t\t\tid_floor = EnumParameterID(\"u_floor\"),\n\t\t\t\tid_amp = EnumParameterID(\"u_amp\");\n\t\t\tcocos2d::GL::useProgram(program);\n\t\t\tglUniform3f(id_gamma, 1.0f / data.RGamma, 1.0f / data.GGamma, 1.0f / data.BGamma);\n\t\t\tglUniform3f(id_floor, data.RFloor / 255.0f, data.GFloor / 255.0f, data.BFloor / 255.0f);\n\t\t\tglUniform3f(id_amp,\n\t\t\t\t(data.RCeil - data.RFloor) / 255.0f,\n\t\t\t\t(data.GCeil - data.GFloor) / 255.0f,\n\t\t\t\t(data.BCeil - data.BFloor) / 255.0f);\n\t\t} else {\n\t\t\tinherit::SetParameterPtr(id, v);\n\t\t}\n\t}\n};\n\nclass tTVPOGLRenderMethod_UnivTrans : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\n\tint u_phase, u_vague;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tint ret = inherit::EnumParameterID(name);\n\t\tif (!strcmp(name, \"phase\")) {\n\t\t\tu_phase = ret;\n\t\t} else if (!strcmp(name, \"vague\")) {\n\t\t\tu_vague = ret;\n\t\t}\n\t\treturn ret;\n\t}\n\tint m_vague;\n\tvirtual void SetParameterInt(int id, int Value) {\n\t\tcocos2d::GL::useProgram(program);\n\t\tif (id == u_vague) {\n\t\t\tm_vague = Value;\n\t\t\tglUniform1f(id, Value / 255.f);\n\t\t} else if (id == u_phase) {\n\t\t\tValue -= m_vague;\n\t\t\tglUniform1f(id, Value / 255.f);\n\t\t} else {\n\t\t\treturn inherit::SetParameterInt(id, Value);\n\t\t}\n\t}\n};\n\nclass tTVPOGLRenderMethod_BoxBlur : public tTVPOGLRenderMethod_Script {\n\ttypedef tTVPOGLRenderMethod_Script inherit;\n\tenum eArea {\n\t\teAreaLeft = 1,\n\t\teAreaTop,\n\t\teAreaRight,\n\t\teAreaBottom,\n\t};\n\ttTVPRect area;\n\tvirtual int EnumParameterID(const char *name) {\n\t\tif (!strcmp(name, \"area_left\")) {\n\t\t\treturn eAreaLeft;\n\t\t} else if (!strcmp(name, \"area_top\")) {\n\t\t\treturn eAreaTop;\n\t\t} else if (!strcmp(name, \"area_right\")) {\n\t\t\treturn eAreaRight;\n\t\t} else if (!strcmp(name, \"area_bottom\")) {\n\t\t\treturn eAreaBottom;\n\t\t}\n\t\treturn inherit::EnumParameterID(name);;\n\t}\n\t\n\tvirtual void SetParameterInt(int id, int Value) {\n\t\tswitch (id) {\n\t\tcase eAreaLeft: area.left = Value; break;\n\t\tcase eAreaTop: area.top = Value; break;\n\t\tcase eAreaRight: area.right = Value; break;\n\t\tcase eAreaBottom: area.bottom = Value; break;\n\t\t}\n\t}\n\n\tvirtual void ApplyTexture(unsigned int i, const GLVertexInfo &info) {\n\t\tif (i == 0) {\n\t\t\tstatic GLint u_pos = glGetUniformLocation(program, \"u_sample\");\n\t\t\tfloat w, h;\n\t\t\tinfo.tex[0].GetScale(w, h);\n\t\t\tw *= info.tex[0].GetInternalWidth();\n\t\t\th *= info.tex[0].GetInternalHeight();\n\t\t\tfloat pos[8 * 2];\n\t\t\tfloat l = area.left / w, t = area.top / h, r =area.right / w, b = area.bottom / h;\n\t\t\tpos[0] = l; pos[1] = t;\n\t\t\tpos[2] = 0; pos[3] = t;\n\t\t\tpos[4] = r; pos[5] = t;\n\t\t\tpos[6] = l; pos[7] = 0;\n\t\t\tpos[8] = r; pos[9] = 0;\n\t\t\tpos[10] = l; pos[11] = b;\n\t\t\tpos[12] = 0; pos[13] = b;\n\t\t\tpos[14] = r; pos[15] = b;\n\t\t\tglUniform2fv(u_pos, 8, pos);\n\t\t}\n\t\tinherit::ApplyTexture(i, info);\n\t}\n};\n\nbool tTVPOGLTexture2D::RestoreNormalSize()\n{\n\ttjs_uint w = internalW / _scaleW, h = internalH / _scaleH;\n\tif (w < GetMaxTextureWidth() && h < GetMaxTextureHeight()) {\n\t\tGLuint newtex;\n\t\tglGenTextures(1, &newtex);\n\t\tcocos2d::GL::bindTexture2D(newtex);\n\t\ttjs_int intw = power_of_two(w), inth = power_of_two(h);\n\t\tglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, intw, inth, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n\t\tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n\t\tGLfloat\n\t\t\tminx = -1,\n\t\t\tmaxx = 1,\n\t\t\tminy = -1,\n\t\t\tmaxy = 1;\n\t\tstatic const GLfloat vertices[12] = {\n\t\t\tminx, miny,\n\t\t\tmaxx, miny,\n\t\t\tminx, maxy,\n\n\t\t\tmaxx, miny,\n\t\t\tminx, maxy,\n\t\t\tmaxx, maxy\n\t\t};\n\t\tstatic tTVPOGLRenderMethod* method = (tTVPOGLRenderMethod*)TVPGetRenderManager()->GetRenderMethod(\"Copy\");\n\t\tmethod->Apply();\n\t\tTVPSetRenderTarget(newtex);\n\t\tglViewport(0, 0, w, h);\n\t\tint VA_flag = 1 << method->GetPosAttr();\n\t\tfor (unsigned int i = 0; i < 1; ++i) {\n\t\t\tVA_flag |= 1 << method->GetTexCoordAttr(i);\n\t\t}\n\t\tcocos2d::GL::enableVertexAttribs(VA_flag);\n\t\tglVertexAttribPointer(method->GetPosAttr(), 2, GL_FLOAT, GL_FALSE, 0, vertices);\n\n\t\tGLVertexInfo vtx;\n\t\tApplyVertex(vtx, tTVPRect(0, 0, w, h));\n\t\tcocos2d::GL::bindTexture2D(texture);\n\t\tglVertexAttribPointer(method->GetTexCoordAttr(0), 2, GL_FLOAT, GL_FALSE, 0, &vtx.vtx.front());\n\t\tglDrawArrays(GL_TRIANGLES, 0, 6);\n\t\tCHECK_GL_ERROR_DEBUG();\n\n\t\t_totalVMemSize -= internalW * internalH * getPixelSize();\n\t\tcocos2d::GL::deleteTexture(texture);\n\n\t\ttexture = newtex;\n\t\tinternalW = intw; internalH = inth;\n\t\t_totalVMemSize += internalW * internalH * getPixelSize();\n\t\t_scaleW = _scaleH = 1;\n\t\treturn true;\n\t} else {\n\t\tTVPShowSimpleMessageBox(\n\t\t\tttstr(TJS_W(\"Too large texture is not accessable by GPU.\")),\n\t\t\tTJS_W(\"Please use software renderer\"));\n\t\treturn false;\n\t}\n}\n\nconst void * tTVPOGLTexture2D::GetScanLineForRead(tjs_uint l)\n{\n\tPixelDataCounter = 5;\n\tif (_scaleW == 1.f && _scaleH == 1.f) {\n\t\tif (!PixelData) {\n\t\t\tPixelData = new unsigned char[internalW * internalH * 4];\n#ifdef _MSC_VER\n\t\t\tif (GL::glGetTextureImage) {\n\t\t\t\tGL::glGetTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, internalH * internalW * 4, PixelData);\n\t\t\t\treturn &PixelData[l * internalW * 4];\n\t\t\t}\n#endif\n\t\t\tTVPSetRenderTarget(texture);\n\t\t\tglViewport(0, 0, internalW, internalH);\n\t\t\tglPixelStorei(GL_PACK_ALIGNMENT, 4); // always dword aligned\n\t\t\tglReadPixels(0, 0, internalW, internalH, GL_RGBA, GL_UNSIGNED_BYTE, PixelData);\n\t\t}\n\t\treturn &PixelData[l * internalW * 4];\n\t} else {\n\t\tif (!PixelData) {\n\t\t\tif(RestoreNormalSize())\n\t\t\t\treturn GetScanLineForRead(l); // route of 1:1 size\n\t\t\treturn nullptr;\n\t\t}\n\t\ttjs_int w = internalW / _scaleW;\n\t\treturn &PixelData[l * w * 4];\n\t}\n}\n\n#ifdef TEST_SHADER_ENABLED\n#include \"RenderManager_ogl_test.hpp\"\n#else\n#define TEST_SHADER(...)\n#define TEST_SHADER_IGNORE_ALPHA(...)\n#endif\n\nvoid TVPSetPostUpdateEvent(void(*f)());\nstatic iTVPTexture2D * (*_CreateStaticTexture2D)(const void *dib, tjs_uint tw, tjs_uint th, tjs_int pitch,\n\tTVPTextureFormat::e fmt, bool isOpaque);\nstatic iTVPTexture2D * (*_CreateMutableTexture2D)(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e format);\nstatic const char *_glExtensions = nullptr;\n//static bool _duplicateTargetTexture = true;\nclass TVPRenderManager_OpenGL : public iTVPRenderManager {\nprotected:\n\tvirtual tTVPOGLRenderMethod_Script* GetRenderMethodFromScript(const char *script, int nTex, unsigned int flags) {\n\t\ttTVPOGLRenderMethod_Script *method = new tTVPOGLRenderMethod_Script();\n\t\tmethod->init(script, nTex);\n\t\tif (flags & RENDER_METHOD_FLAG_TARGET_AS_INPUT) {\n\t\t\tmethod->SetTargetAsSrc();\n\t\t}\n\t\treturn method;\n\t}\n\n\ttemplate<typename T>\n\tT* CompileAndRegScript(const char* name, const std::string &script, int nTex, const char *prefix = nullptr) {\n\t\tT *method = new T();\n\t\tmethod->init(script, nTex, prefix);\n\t\tRegisterRenderMethod(name, method);\n\t\treturn method;\n\t}\n\n\tconst char * const common_shader_framebuffer_fetch_prefix =\n\t\t\"#if defined(GL_ARM_shader_framebuffer_fetch)\"\t\t   \"\\n\"\n\t\t\"#extension GL_ARM_shader_framebuffer_fetch : require\" \"\\n\"\n\t\t\"#define gl_LastFragColor gl_LastFragColorARM\"\t\t   \"\\n\"\n\t\t\"#elif defined(GL_EXT_shader_framebuffer_fetch)\"\t   \"\\n\"\n\t\t\"#extension GL_EXT_shader_framebuffer_fetch : require\" \"\\n\"\n\t\t\"#define gl_LastFragColor gl_LastFragData[0]\"\t\t   \"\\n\"\n\t\t\"#elif defined(GL_NV_shader_framebuffer_fetch)\"\t   \"\\n\"\n\t\t\"#extension GL_NV_shader_framebuffer_fetch : require\" \"\\n\"\n\t\t\"#else\"\t\t\t\t\t\t\t\t\t\t\t   \"\\n\"\n\t\t\"#error noy any framebuffer fetch extension available\"   \"\\n\"\n\t\t\"#endif\"\t\t\t\t\t\t\t\t\t\t\t   \"\\n\"\n\t\t;\n\n\tconst std::string ScriptCommonPrefix =\n\t\t\"void main() {\\n\"\n\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\";\n\tconst std::string ScriptCommonBltPrefix = ScriptCommonPrefix +\n\t\t\"    vec4 d = texture2D(tex1, v_texCoord1);\\n\";\n\tconst std::string ScriptCommonFBFBltPrefix = ScriptCommonPrefix +\n\t\t\"    vec4 d = gl_LastFragColor;\\n\";\n\n\ttemplate<typename T = tTVPOGLRenderMethod_Script>\n\tT* CompileAndRegRegularBlendMethod(const char *name, const std::string &prefix, const std::string &code) {\n\t\tif (GL_CHECK_shader_framebuffer_fetch) {\n\t\t\treturn CompileAndRegScript<T>(name,\n\t\t\t\tprefix + ScriptCommonFBFBltPrefix + code, 1, common_shader_framebuffer_fetch_prefix);\n\t\t} else {\n\t\t\tT* method = CompileAndRegScript<T>(name,\n\t\t\t\tprefix + ScriptCommonBltPrefix + code, 2);\n\t\t\tmethod->SetTargetAsSrc();\n\t\t\treturn method;\n\t\t}\n\t}\n\n#ifdef WIN32\n\tstatic bool glew_dynamic_binding()\n\t{\n\t\tconst char *gl_extensions = (const char*)glGetString(GL_EXTENSIONS);\n\t\t// If the current opengl driver doesn't have framebuffers methods, check if an extension exists\n\t\tif (glGenFramebuffers == NULL) {\n\t\t\tTVPConsoleLog(\"OpenGL: glGenFramebuffers is NULL, try to detect an extension\");\n\t\t\tif (strstr(gl_extensions, \"ARB_framebuffer_object\")) {\n\t\t\t\tTVPConsoleLog(\"OpenGL: ARB_framebuffer_object is supported\");\n\n\t\t\t\tglIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress(\"glIsRenderbuffer\");\n\t\t\t\tglBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress(\"glBindRenderbuffer\");\n\t\t\t\tglDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress(\"glDeleteRenderbuffers\");\n\t\t\t\tglGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress(\"glGenRenderbuffers\");\n\t\t\t\tglRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress(\"glRenderbufferStorage\");\n\t\t\t\tglGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress(\"glGetRenderbufferParameteriv\");\n\t\t\t\tglIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress(\"glIsFramebuffer\");\n\t\t\t\tglBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress(\"glBindFramebuffer\");\n\t\t\t\tglDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress(\"glDeleteFramebuffers\");\n\t\t\t\tglGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress(\"glGenFramebuffers\");\n\t\t\t\tglCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress(\"glCheckFramebufferStatus\");\n\t\t\t\tglFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress(\"glFramebufferTexture1D\");\n\t\t\t\tglFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress(\"glFramebufferTexture2D\");\n\t\t\t\tglFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress(\"glFramebufferTexture3D\");\n\t\t\t\tglFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress(\"glFramebufferRenderbuffer\");\n\t\t\t\tglGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress(\"glGetFramebufferAttachmentParameteriv\");\n\t\t\t\tglGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress(\"glGenerateMipmap\");\n\t\t\t} else\n\t\t\tif (strstr(gl_extensions, \"EXT_framebuffer_object\")) {\n\t\t\t\tTVPConsoleLog(\"OpenGL: EXT_framebuffer_object is supported\");\n\t\t\t\tglIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress(\"glIsRenderbufferEXT\");\n\t\t\t\tglBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress(\"glBindRenderbufferEXT\");\n\t\t\t\tglDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress(\"glDeleteRenderbuffersEXT\");\n\t\t\t\tglGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress(\"glGenRenderbuffersEXT\");\n\t\t\t\tglRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress(\"glRenderbufferStorageEXT\");\n\t\t\t\tglGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress(\"glGetRenderbufferParameterivEXT\");\n\t\t\t\tglIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress(\"glIsFramebufferEXT\");\n\t\t\t\tglBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress(\"glBindFramebufferEXT\");\n\t\t\t\tglDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress(\"glDeleteFramebuffersEXT\");\n\t\t\t\tglGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress(\"glGenFramebuffersEXT\");\n\t\t\t\tglCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress(\"glCheckFramebufferStatusEXT\");\n\t\t\t\tglFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress(\"glFramebufferTexture1DEXT\");\n\t\t\t\tglFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress(\"glFramebufferTexture2DEXT\");\n\t\t\t\tglFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress(\"glFramebufferTexture3DEXT\");\n\t\t\t\tglFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress(\"glFramebufferRenderbufferEXT\");\n\t\t\t\tglGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress(\"glGetFramebufferAttachmentParameterivEXT\");\n\t\t\t\tglGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress(\"glGenerateMipmapEXT\");\n\t\t\t} else {\n\t\t\t\tTVPConsoleLog(\"OpenGL: No framebuffers extension is supported\");\n\t\t\t\tTVPConsoleLog(\"OpenGL: Any call to Fbo will crash!\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n#endif\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D(const void *dib, tjs_uint tw, tjs_uint th, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt, tjs_uint dstw, tjs_uint dsth, bool isOpaque) {\n\t\tconst tjs_uint8* pixel = (const tjs_uint8*)dib;\n\t\ttjs_uint8 *tmp = nullptr;\n\t\ttjs_uint w = tw, h = th;\n\t\tfloat sw = 1.f, sh = 1.f;\n\t\tif (dstw != tw || dsth != th) {\n\t\t\ttjs_uint dpitch;\n\t\t\ttmp = (fmt == TVPTextureFormat::RGBA ? TVPShrink : TVPShrink_8)(&dpitch, pixel, pitch, tw, th, dstw, dsth);\n\t\t\tpixel = tmp;\n\t\t\th = dsth;\n\t\t\tw = dstw;\n\t\t\tpitch = dpitch;\n\t\t\tsw = (float)(dstw - (tw & 1)) / tw;\n\t\t\tsh = (float)(dsth - (th & 1)) / th;\n\t\t\tif (!isOpaque) {\n\t\t\t\tisOpaque = TVPCheckOpaqueRGBA(pixel, dpitch, w, h);\n\t\t\t}\n\t\t}\n\t\tif (fmt == TVPTextureFormat::RGBA && isOpaque) {\n\t\t\tint dpitch = (w * 3 + 7) & ~7;\n\t\t\ttjs_uint8 *rgb = new tjs_uint8[dpitch * h + 16];\n\t\t\ttjs_uint8 *dst = (tjs_uint8*)(((intptr_t)rgb + 7) & ~7);\n\t\t\tconst tjs_uint8 *src = (const tjs_uint8 *)pixel;\n\t\t\tpixel = dst;\n\t\t\tfor (int y = 0; y < h; ++y) {\n\t\t\t\tTVPConvert32BitTo24Bit(dst, src, pitch);\n\t\t\t\tsrc += pitch;\n\t\t\t\tdst += dpitch;\n\t\t\t}\n\t\t\tif (tmp) delete[] tmp;\n\t\t\ttmp = rgb;\n\t\t\tfmt = TVPTextureFormat::RGB;\n\t\t\tpitch = dpitch;\n\t\t}\n\t\ttTVPOGLTexture2D_static* ret = new tTVPOGLTexture2D_static(pixel, pitch, w, h, fmt, tw, th, sw, sh);\n\t\tif (tmp) delete[] tmp;\n\t\treturn ret;\n\t}\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D_normal(const void *dib, tjs_uint w, tjs_uint h, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt, bool isOpaque) {\n\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\tint tw = (w + n - 1) / n;\n\t\tn = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\tint th = (h + n - 1) / n;\n\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, tw, th, isOpaque);\n\t}\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D_solid(const void *dib, tjs_uint w, tjs_uint h, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt) {\n\t\tif (TVPCheckSolidPixel((const tjs_uint8*)dib, pitch, w, h)) {\n\t\t\ttTVPOGLTexture2D_static *ret = new tTVPOGLTexture2D_static(dib, 4, 1, 1, fmt, w, h, 1.0f / w, 1.0f / h, GL_NEAREST);\n\t\t\treturn ret;\n\t\t}\n\t\treturn nullptr;\n\t}\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D_half(const void *dib, tjs_uint w, tjs_uint h, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt, bool isOpaque) {\n\t\tiTVPTexture2D *ret = CreateStaticTexture2D_solid(dib, w, h, pitch, fmt);\n\t\tif (ret) return ret;\n\t\tint tw = w, th = h;\n\t\tif (w > GetMaxTextureWidth()) {\n\t\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\t\ttw = (w + n - 1) / n;\n\t\t} else if (w > 64) {\n\t\t\ttw = (w + 1) / 2;\n\t\t}\n\t\tif (h > GetMaxTextureHeight()) {\n\t\t\tint n = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\t\tth = (h + n - 1) / n;\n\t\t} else if (h > 64) {\n\t\t\tth = (h + 1) / 2;\n\t\t}\n\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, tw, th, isOpaque);\n\t}\n\t\n\tstatic iTVPTexture2D *CreateStaticTexture2D_ETC2(const void *dib, tjs_uint w, tjs_uint h, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt, bool isOpaque) {\n\t\tiTVPTexture2D *ret = CreateStaticTexture2D_solid(dib, w, h, pitch, fmt);\n\t\tif (ret) return ret;\n\t\tif (w > GetMaxTextureWidth() || h > GetMaxTextureHeight()) {\n\t\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\t\tint tw = (w + n - 1) / n;\n\t\t\tn = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\t\tint th = (h + n - 1) / n;\n\t\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, tw, th, isOpaque);\n\t\t}\n\t\tif (w * h < 16 * 16) {\n\t\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, w, h, isOpaque);\n\t\t}\n\t\tif (!isOpaque) {\n\t\t\tisOpaque = TVPCheckOpaqueRGBA((const tjs_uint8*)dib, pitch, w, h);\n\t\t}\n\t\tuint8_t *pixel = nullptr; int tw, th;\n\t\tsize_t pvrsize;\n\t\tGLenum texfmt;\n\t\ttw = (w + 3) & ~3;\n\t\tth = (h + 3) & ~3;\n\t\tif (isOpaque) {\n\t\t\tpixel = (uint8_t *)ETCPacker::convert(dib, w, h, pitch, true, pvrsize);\n\t\t\ttexfmt = GL_COMPRESSED_RGB8_ETC2;\n\t\t} else {\n\t\t\tpixel = (uint8_t*)ETCPacker::convertWithAlpha(dib, w, h, pitch, pvrsize);\n\t\t\ttexfmt = GL_COMPRESSED_RGBA8_ETC2_EAC;\n\t\t}\n\n\t\tret = new tTVPOGLTexture2D_static(pixel, pvrsize, texfmt, w, h, tw, th, 1, 1);\n\t\tif (pixel) delete[] pixel;\n\t\treturn ret;\n\t}\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D_PVRTC(const void *dib, tjs_uint w, tjs_uint h, tjs_int pitch,\n\t\tTVPTextureFormat::e fmt, bool isOpaque) {\n\t\tiTVPTexture2D *ret = CreateStaticTexture2D_solid(dib, w, h, pitch, fmt);\n\t\tif (ret) return ret;\n\t\tif (w > GetMaxTextureWidth() || h > GetMaxTextureHeight()) {\n\t\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\t\tint tw = (w + n - 1) / n;\n\t\t\tn = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\t\tint th = (h + n - 1) / n;\n\t\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, tw, th, isOpaque);\n\t\t}\n\t\tif (w * h < 16 * 16) {\n\t\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, w, h, isOpaque);\n\t\t}\n\n\t\t// 4bpp / 4x4 -> 64bit, ratio = 1/8\n\t\t// square only\n\t\ttjs_uint totalPixel = w * h;\n\t\ttjs_uint pw = power_of_two(w, 16), ph = power_of_two(h, 16);\n\t\ttjs_uint texsize = std::max(pw, ph);\n\t\ttjs_uint pvrPixels = texsize * texsize;\n\t\tif (totalPixel / 8 >= pvrPixels) {\n\t\t\treturn CreateStaticTexture2D(dib, w, h, pitch, fmt, w, h, isOpaque);\n\t\t}\n\t\ttjs_uint pvrSize = pvrPixels / 2;\n\t\ttjs_uint32 *inBuf = (tjs_uint32*)TJSAlignedAlloc(pvrPixels * sizeof(tjs_uint32), 4);\n\t\ttjs_uint8 *outBuf = (tjs_uint8*)TJSAlignedAlloc(pvrSize, 4);\n\n\t\tconst tjs_uint8 *src = (const tjs_uint8 *)dib;\n\t\ttjs_uint8* dst = (tjs_uint8*)inBuf;\n\t\ttjs_uint dpitch = pw * 4;\n\t\tfor (tjs_uint y = 0; y < h; ++y) {\n\t\t\tmemcpy(dst, src, w * 4);\n\t\t\tsrc += pitch;\n\t\t\tdst += dpitch;\n\t\t}\n\t\tif (w < pw) {\n\t\t\tdst = (tjs_uint8*)inBuf;\n\t\t\tdst += w * 4;\n\t\t\ttjs_uint remain = (pw - w) * 4;\n\t\t\tfor (tjs_uint y = 0; y < h; ++y) {\n\t\t\t\tmemset(dst, 0xFF, remain);\n\t\t\t\tdst += dpitch;\n\t\t\t}\n\t\t}\n\t\tif (h < ph) {\n\t\t\tdst = (tjs_uint8*)inBuf;\n\t\t\tmemset(dst + dpitch * h, 0xFF, dpitch * (ph - h));\n\t\t}\n\n\t\tPvrTcEncoder::EncodeRgba4Bpp(inBuf, outBuf, texsize, texsize, isOpaque);\n\t\tTJSAlignedDealloc(inBuf);\n\t\tret = new tTVPOGLTexture2D_static(outBuf, pvrSize,\n\t\t\tisOpaque ? GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,\n\t\t\tw, h, texsize, texsize, 1, 1);\n\t\tTJSAlignedDealloc(outBuf);\n\t\treturn ret;\n\t}\n\n\tstatic iTVPTexture2D *CreateStaticTexture2D(tTVPBitmap* bmp) {\n\t\ttjs_uint w = bmp->GetWidth(), h = bmp->GetHeight();\n\t\tif (w > GetMaxTextureWidth()) {\n\t\t\tif (w > GetMaxTextureWidth() * 2 && GL_CHECK_unpack_subimage) {\n\t\t\t\treturn new tTVPOGLTexture2D_split(bmp);\n\t\t\t}\n\t\t} else if (h > GetMaxTextureHeight() * 2) {\n\t\t\treturn new tTVPOGLTexture2D_split(bmp);\n\t\t}\n\t\treturn _CreateStaticTexture2D(bmp->GetBits(), bmp->GetWidth(), bmp->GetHeight(), bmp->GetPitch(),\n\t\t\tbmp->Is32bit() ? TVPTextureFormat::RGBA : TVPTextureFormat::Gray, bmp->IsOpaque);\n\t}\n\n\tstatic iTVPTexture2D *CreateMutableTexture2D(const void *pixel, int pitch, unsigned int w, unsigned int h, float sw, float sh, TVPTextureFormat::e fmt) {\n\t\treturn new tTVPOGLTexture2D_mutatble(pixel, pitch, w, h, fmt, sw, sh);\n\t}\n\n\tstatic iTVPTexture2D *CreateMutableTexture2D_normal(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e fmt) {\n\t\tfloat sw = 1.f, sh = 1.f;\n\n\t\tif (!pixel) {\n\t\t\tif (w > GetMaxTextureWidth()) {\n\t\t\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\t\t\tsw = 1.0f / n;\n\t\t\t}\n\t\t\tif (h > GetMaxTextureHeight()) {\n\t\t\t\tint n = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\t\t\tsh = 1.0f / n;\n\t\t\t}\n\t\t}\n\n\t\treturn CreateMutableTexture2D(pixel, pitch, w, h, sw, sh, fmt);\n\t}\n\n\tstatic iTVPTexture2D *CreateMutableTexture2D_half(const void *pixel, int pitch, unsigned int w, unsigned int h, TVPTextureFormat::e fmt) {\n\t\tfloat sw = 1.f, sh = 1.f;\n\t\tif (!pixel) {\n\t\t\tif (w > GetMaxTextureWidth()) {\n\t\t\t\tint n = (w + GetMaxTextureWidth() - 1) / GetMaxTextureWidth();\n\t\t\t\tsw = 1.0f / n;\n\t\t\t} else if (w > 64) {\n\t\t\t\tsw = 0.5f;\n\t\t\t}\n\t\t\tif (h > GetMaxTextureHeight()) {\n\t\t\t\tint n = (h + GetMaxTextureHeight() - 1) / GetMaxTextureHeight();\n\t\t\t\tsh = 1.0f / n;\n\t\t\t} else if (h > 64) {\n\t\t\t\tsh = 0.5f;\n\t\t\t}\n\t\t}\n\n\t\treturn CreateMutableTexture2D(pixel, pitch, w, h, sw, sh, fmt);\n\t}\n\n\tvoid InitGL() {\n\t\tglGetIntegerv(GL_FRAMEBUFFER_BINDING, &_screenFrameBuffer);\n\t\tTVPInitTextureFormatList();\n\n\t\t_CreateStaticTexture2D = CreateStaticTexture2D_normal;\n\t\t_CreateMutableTexture2D = CreateMutableTexture2D_normal;\n\t\tstd::string compTexMethod = IndividualConfigManager::GetInstance()->GetValue<std::string>(\"ogl_compress_tex\", \"none\");\n\t\tif (compTexMethod == \"half\") {\n\t\t\t_CreateStaticTexture2D = CreateStaticTexture2D_half;\n\t\t//\t_CreateMutableTexture2D = CreateMutableTexture2D_half;\n\t\t} else if (compTexMethod == \"etc2\") {\n\t\t\tif (TVPIsSupportTextureFormat(GL_COMPRESSED_RGB8_ETC2)) {\n\t\t\t\t_CreateStaticTexture2D = CreateStaticTexture2D_ETC2;\n\t\t\t}\n\t\t} else if (compTexMethod == \"pvrtc\") {\n\t\t\tif (TVPIsSupportTextureFormat(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG)) {\n\t\t\t\t_CreateStaticTexture2D = CreateStaticTexture2D_PVRTC;\n\t\t\t}\n\t\t}\n\t\tGLint maxTextSize;\n\t\tglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextSize);\n\t\tTVPMaxTextureSize = maxTextSize;\n\t\tmaxTextSize = IndividualConfigManager::GetInstance()->GetValue<int>(\"ogl_max_texsize\", 0);\n\t\tif (maxTextSize > 0 && (maxTextSize < TVPMaxTextureSize || TVPMaxTextureSize < 1024)) {\n\t\t\tTVPMaxTextureSize = maxTextSize; // override by user config\n\t\t}\n\t\tGLint _maxTextureUnits;\n\t\tglGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &_maxTextureUnits);\n\n\t\tTVPInitGLExtensionInfo();\n\t\tTVPInitGLExtensionFunc();\n\n\t\tglGenFramebuffers(1, &_FBO);\n\t\tglGenRenderbuffers(1, &_stencil_FBO);\n\t\tif (!_FBO) {\n\t\t\tTVPConsoleLog(\"Fail to create FBO\");\n\t\t\tconst char *reason = nullptr;\n\t\t\tGLenum errcode = glCheckFramebufferStatus(GL_FRAMEBUFFER);\n#define SATATUE_CASE(x) case x: reason = #x; break;\n\t\t\tswitch (errcode) {\n\t\t\t\tSATATUE_CASE(GL_FRAMEBUFFER_COMPLETE);\n\t\t\t\tSATATUE_CASE(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);\n\t\t\t\tSATATUE_CASE(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);\n\t\t\t\tSATATUE_CASE(GL_FRAMEBUFFER_UNSUPPORTED);\n\t\t\tdefault:\n\t\t\t\t{\n\t\t\t\t\tchar tmp[16];\n\t\t\t\t\tsprintf(tmp, \"0x%X\", errcode);\n\t\t\t\t\tTVPConsoleLog((std::string(\"glCheckFramebufferStatus = \") + tmp).c_str());\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (reason) {\n\t\t\t\tTVPConsoleLog((std::string(\"glCheckFramebufferStatus = \") + reason).c_str());\n\t\t\t}\n\t\t}\n// \t\tif (TVPCheckGLExtension(GL_CHECK_ETC1_texture)) {\n// \t\t\t_glCompressedTexFormat = GL_ETC1_RGB8_OES;\n// \t\t}\n\t\t//glDisable(GL_DEPTH_TEST);\n\t\t//glDisable(GL_SCISSOR_TEST);\n\n//\t\t_duplicateTargetTexture = IndividualConfigManager::GetInstance()->GetValueBool(\"ogl_dup_target\", true);\n\t\tcocos2d::EventListenerCustom *listener =\n\t\t\tcocos2d::EventListenerCustom::create(EVENT_RENDERER_RECREATED,\n\t\t\t[this](cocos2d::EventCustom*)\n\t\t{\n\t\t\ttTVPOGLRenderMethod_Script::ClearCache();\n\t\t\tfor (auto it : AllMethods) {\n\t\t\t\ttTVPOGLRenderMethod *method = static_cast<tTVPOGLRenderMethod*>(it.second);\n\t\t\t\tmethod->Rebuild();\n\t\t\t}\n\t\t});\n\t\tcocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(listener, 1);\n\t\tTVPSetPostUpdateEvent(_RestoreGLStatues);\n\t}\n\n\ttjs_uint _drawCount;\npublic:\n\tTVPRenderManager_OpenGL()\n\t\t: tempTexture(nullptr)\n\t\t, _drawCount(0)\n\t{\n\t\tInitGL();\n#ifdef TEST_SHADER_ENABLED\n\t\tTVPInitTVPGL();\n#endif\n\n\t\tconst std::string opacityPrefix(\"uniform float opacity;\\n\");\n\t\tconst std::string alpha_thresholdPrefix(\"uniform float alpha_threshold;\\n\");\n\t\tconst std::string colorPrefix(\"uniform vec4 color;\\n\");\n\t\tconst std::string copyShader(\"void main(){\\n\"\n\t\t\t\"    gl_FragColor = texture2D(tex0, v_texCoord0);\"\n\t\t\t\"}\");\n\t\tCompileRenderMethod(\"Copy\", copyShader.c_str(), 1);\n\n\t\t// ---------- ApplyColorMap ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ApplyColorMap\",\n\t\t\topacityPrefix + colorPrefix + ScriptCommonPrefix +\n\t\t\t\"    gl_FragColor = vec4(color.rgb, s.r * opacity);\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(ApplyColorMap,\n\t\t\tTVPApplyColorMap_HDA_o(testdest, testrule, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA),\n\t\t\tsrc_tex[0].first = texdata[2]);\n\t\t\n\t\tCompileAndRegRegularBlendMethod(\"ApplyColorMap_d\", opacityPrefix + colorPrefix,\n\t\t\t\"    s.r *= opacity;\\n\"\n\t\t\t\"    d.a = s.r + d.a - s.r * d.a;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, color.rgb, s.r / (d.a + 0.0001));\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER(ApplyColorMap_d,\n\t\t\tTVPApplyColorMap_do(testdest, testrule, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA),\n\t\t\tsrc_tex[0].first = texdata[2]);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ApplyColorMap_a\",\n\t\t\topacityPrefix + colorPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a = s.r * opacity;\\n\"\n\t\t\t\"    s.rgb = color.rgb;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(ApplyColorMap_a,\n\t\t\tTVPApplyColorMap_ao(testdest, testrule, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA),\n\t\t\tsrc_tex[0].first = texdata[2]);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"RemoveOpacity\",\n\t\t\topacityPrefix + colorPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a = s.r * opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(RemoveOpacity,\n\t\t\tTVPRemoveOpacity_o(testdest, testrule, 256 * 256, TEST_SHADER_OPA),\n\t\t\tsrc_tex[0].first = texdata[2]);\n\n\t\t// ---------- Fill ----------\n\t\tstd::string fillColorShader(colorPrefix + \"void main(){\\n\"\n\t\t\t\"    gl_FragColor = color;\"\n\t\t\t\"}\");\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_FillARGB>(\"FillARGB\", fillColorShader, 0);\n \t\tTEST_SHADER(FillARGB, TVPFillARGB(testdest, 256 * 256, TEST_SHADER_COLOR));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"FillColor\", fillColorShader, 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ZERO, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(FillColor, TVPFillColor(testdest, 256 * 256, TEST_SHADER_COLOR));\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"FillMask\", \"void main(){gl_FragColor = vec4(0,0,0,1);}\", 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_CONSTANT_COLOR, GL_ZERO);\n\t\tTEST_SHADER(FillMask, TVPFillMask(testdest, 256 * 256, TEST_SHADER_OPA));\n\n\t\t// ---------- ConstColorAlphaBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"ConstColorAlphaBlend\", fillColorShader, 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(ConstColorAlphaBlend,\n\t\t\tTVPConstColorAlphaBlend(testdest, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"ConstColorAlphaBlend_a\", colorPrefix + \n\t\t\t\"void main(){\\n\"\n\t\t\t\"    vec4 s = color;\\n\"\n\t\t\t\"    s.a = 1.0;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR);\n\t\tTEST_SHADER(ConstColorAlphaBlend_a,\n\t\t\tTVPConstColorAlphaBlend_a(testdest, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA));\n\n\t\tconst char *shader_ConstColorAlphaBlend_d =\n\t\t\t\"    d.a = opacity + d.a - opacity * d.a;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, color.rgb, opacity / (d.a + 0.0001));\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tif (GL_CHECK_shader_framebuffer_fetch) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ConstColorAlphaBlend_d\",\n\t\t\t\topacityPrefix + colorPrefix +\n\t\t\t\t\"void main(){\\n\"\n\t\t\t\t\"    vec4 d = gl_LastFragColor;\\n\"\n\t\t\t\t+ shader_ConstColorAlphaBlend_d, 0, common_shader_framebuffer_fetch_prefix);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ConstColorAlphaBlend_d\",\n\t\t\t\topacityPrefix + colorPrefix +\n\t\t\t\t\"void main(){\\n\"\n\t\t\t\t\"    vec4 d = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\t+ shader_ConstColorAlphaBlend_d, 1)->SetTargetAsSrc();\n\t\t}\n\t\tTEST_SHADER(ConstColorAlphaBlend_d,\n\t\t\tmemcpy(testdest, testred, 256*256*4),\n\t\t\ttexdest->Update(testred, TVPTextureFormat::RGBA, 256 * 4, tTVPRect(0, 0, 256, 256)),\n\t\t\tTVPConstColorAlphaBlend_d(testdest, 256 * 256, TEST_SHADER_COLOR, TEST_SHADER_OPA)\n\t\t\t);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"RemoveConstOpacity\", opacityPrefix +\n\t\t\t\"void main(){\\n\"\n\t\t\t\"    gl_FragColor = vec4(0,0,0,opacity);\\n\"\n\t\t\t\"}\", 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(RemoveConstOpacity,\n\t\t\tTVPRemoveConstOpacity(testdest, 256 * 256, TEST_SHADER_OPA));\n\n\t\t// ---------- Copy ----------\n\t\tCompileRenderMethod(\"CopyOpaqueImage\", \"void main(){\\n\"\n\t\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    s.a = 1.0;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1);\n\t\tTEST_SHADER(CopyOpaqueImage,\n\t\t\tTVPCopyOpaqueImage(testdest, testdata1, 256 * 256));\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"CopyColor\", copyShader, 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ZERO, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(CopyColor,\n\t\t\tTVPCopyColor(testdest, testdata1, 256 * 256));\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"CopyMask\", copyShader, 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_ONE, GL_ZERO);\n\t\tTEST_SHADER(CopyMask,\n\t\t\tTVPCopyMask(testdest, testdata1, 256 * 256));\n\n\t\t// ---------- ConstAlphaBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"ConstAlphaBlend\", copyShader, 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(ConstAlphaBlend,\n\t\t\tTVPConstAlphaBlend_HDA(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ConstAlphaBlend_a\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a = opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(ConstAlphaBlend_a,\n\t\t\tTVPConstAlphaBlend_a(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\tCompileAndRegRegularBlendMethod(\"ConstAlphaBlend_d\", opacityPrefix,\n\t\t\t\"    d.a = opacity + d.a - opacity * d.a;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, opacity / (d.a + 0.0001));\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER(ConstAlphaBlend_d,\n\t\t\tTVPConstAlphaBlend_d(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\t// ---------- AdjustGamma ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_AdjustGamma>(\"AdjustGamma\",\n\t\t\t\"uniform vec3 u_gamma;\\n\" // rgb\n\t\t\t\"uniform vec3 u_floor;\\n\" // rgb\n\t\t\t\"uniform vec3 u_amp;\\n\" // rgb\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    s.rgb = clamp(pow(s.rgb, u_gamma) * u_amp + u_floor, 0.0, 1.0);\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetTargetAsSrc();\n#ifdef TEST_SHADER_ENABLED\n\t\ttTVPGLGammaAdjustTempData temp;\n\t\ttTVPGLGammaAdjustData data;\n\t\tdata.BCeil = 220;\n\t\tdata.BFloor = 20;\n\t\tdata.BGamma = 0.5;\n\t\tdata.RCeil = 210;\n\t\tdata.RFloor = 10;\n\t\tdata.RGamma = 1.5;\n\t\tdata.GCeil = 240;\n\t\tdata.GFloor = 50;\n\t\tdata.GGamma = 6.0;\n\t\tTVPInitGammaAdjustTempData(&temp, &data);\n#endif\n\t\tTEST_SHADER(AdjustGamma,\n\t\t\tTVPAdjustGamma(testdest, 256 * 256, &temp),\n\t\t\tmethod->SetParameterPtr(method->EnumParameterID(\"gammaAdjustData\"), &data));\n\n\t\tstd::string shader_AdjustGamma_a_1 =\n\t\t\t\"uniform vec3 u_gamma;\\n\" // rgb\n\t\t\t\"uniform vec3 u_floor;\\n\" // rgb\n\t\t\t\"uniform vec3 u_amp;\\n\" // rgb\n\t\t\t\"void main() {\\n\";\n\t\tstd::string shader_AdjustGamma_a_2 =\n\t\t\t\"    vec3 t = (s.rgb / (s.a + 0.001) - 1.0) * step(s.rgb, s.aaa + 0.001) + 1.0;\\n\"\n\t\t\t\"    t = clamp(pow(t, u_gamma) * u_amp + u_floor, 0.0, 1.0);\\n\"\n\t\t\t\"    s.rgb = t * s.a + clamp(s.rgb - s.a, 0.0, 1.0);\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tif (GL_CHECK_shader_framebuffer_fetch) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AdjustGamma>(\"AdjustGamma_a\",\n\t\t\t\tshader_AdjustGamma_a_1 +\n\t\t\t\t\"    vec4 s = gl_LastFragColor;\\n\"\n\t\t\t\t+ shader_AdjustGamma_a_2, 0, common_shader_framebuffer_fetch_prefix);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AdjustGamma>(\"AdjustGamma_a\",\n\t\t\t\tshader_AdjustGamma_a_1 +\n\t\t\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\t+ shader_AdjustGamma_a_2, 1)->SetTargetAsSrc();\n\t\t}\n// \t\tTEST_SHADER(AdjustGamma_a,\n// \t\t\tTVPAdjustGamma_a(testdest, 256 * 256, &temp),\n// \t\t\tmethod->SetParameterPtr(method->EnumParameterID(\"gammaAdjustData\"), &data));\n\t\t// pass\n\n\t\t// --------- ConstAlphaBlend_SD ----------\n\t\ttTVPOGLRenderMethod_Script *method;\n\t\tmethod = CompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ConstAlphaBlend_SD\", opacityPrefix + ScriptCommonBltPrefix +\n\t\t\t\"    gl_FragColor = mix(s, d, opacity);\\n\"\n\t\t\t\"}\", 2);\n\t\tTEST_SHADER_IGNORE_ALPHA(ConstAlphaBlend_SD,\n\t\t\tTVPConstAlphaBlend_SD(testdest, testdata1, testdata2, 256 * 256, TEST_SHADER_OPA));\n\t\tRegisterRenderMethod(\"ConstAlphaBlend_SD_a\", method);\n\t\tTEST_SHADER(ConstAlphaBlend_SD_a,\n\t\t\tTVPConstAlphaBlend_SD_a(testdest, testdata1, testdata2, 256 * 256, TEST_SHADER_OPA));\n\t\tCompileRenderMethod(\"ConstAlphaBlend_SD_d\", (opacityPrefix + ScriptCommonBltPrefix +\n\t\t\t\"    s.rgb = mix(s.rgb, d.rgb, d.a * opacity / (s.a * (1.0 - opacity) * (1.0 - d.a * opacity) + d.a * opacity + 0.0001));\\n\"//mix(x,y,a)=x*(1-a)+y*a\n\t\t\t\"    s.a = mix(s.a, d.a, opacity);\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\").c_str(), 2);\n\t\tTEST_SHADER(ConstAlphaBlend_SD_d,\n\t\t\tTVPConstAlphaBlend_SD_d(testdest, testdata1, testdata2, 256 * 256, TEST_SHADER_OPA));\n\t\t// ConstAlphaBlend_SD = ConstAlphaBlend\n\t\t// --------- UnivTransBlend ----------\n\t\tmethod = CompileAndRegScript<tTVPOGLRenderMethod_UnivTrans>(\"UnivTransBlend\",\n\t\t\t\"uniform float phase;\\n\" // = phase - vague\n\t\t\t\"uniform float vague;\\n\"\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s1 = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    vec4 s2 = texture2D(tex1, v_texCoord1);\\n\"\n\t\t\t\"    vec4 rule = texture2D(tex2, v_texCoord2);\\n\"\n\t\t\t\"    float opa = clamp((rule.r - phase) / vague, 0.0, 1.0);\\n\"\n\t\t\t\"    s1.rgb = mix(s2.rgb, s1.rgb, opa);\\n\"\n\t\t\t\"    gl_FragColor = s1;\\n\"\n\t\t\t\"}\", 3);\n\t\tTEST_SHADER_IGNORE_ALPHA(UnivTransBlend,\n\t\t\tTVPInitUnivTransBlendTable(testtable, 64, 128),\n\t\t\tTVPUnivTransBlend(testdest, testdata1, testdata2, testrule, testtable, 256 * 256),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 128),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 64));\n\t\tTEST_SHADER_IGNORE_ALPHA(UnivTransBlend,\n\t\t\tTVPInitUnivTransBlendTable(testtable, 192, 128),\n\t\t\tTVPUnivTransBlend(testdest, testdata1, testdata2, testrule, testtable, 256 * 256),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 192));\n\t\tTEST_SHADER_IGNORE_ALPHA(UnivTransBlend,\n\t\t\tTVPInitUnivTransBlendTable(testtable, 64 + 600, 600),\n\t\t\tTVPUnivTransBlend_switch(testdest, testdata1, testdata2, testrule, testtable, 256 * 256, 64 + 600, 64),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 600),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 64 + 600));\n\n\t\tmethod = CompileAndRegScript<tTVPOGLRenderMethod_UnivTrans>(\"UnivTransBlend_d\",\n\t\t\t\"uniform float phase;\\n\" // = phase - vague\n\t\t\t\"uniform float vague;\\n\"\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s1 = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    vec4 s2 = texture2D(tex1, v_texCoord1);\\n\"\n\t\t\t\"    vec4 rule = texture2D(tex2, v_texCoord2);\\n\"\n\t\t\t\"    float opa = clamp((rule.r - phase) / vague, 0.0, 1.0);\\n\"\n\t\t\t\"    s1.rgb = mix(s1.rgb, s2.rgb, s2.a * (1.0 - opa) / (s2.a * (1.0 - opa) * (1.0 - s1.a * opa) + s1.a * opa + 0.0001));\\n\"//mix(x,y,a)=x*(1-a)+y*a\n\t\t\t\"    s1.a = mix(s2.a, s1.a, opa);\\n\"\n\t\t\t\"    gl_FragColor = s1;\\n\"\n\t\t\t\"}\", 3);\n\t\tTEST_SHADER(UnivTransBlend_d,\n\t\t\tTVPInitUnivTransBlendTable(testtable, 215, 128),\n\t\t\tTVPUnivTransBlend_d(testdest, testdata1, testdata2, testrule, testtable, 256 * 256),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 128),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 215));\n\t\tTEST_SHADER(UnivTransBlend_d,\n\t\t\t(TVPInitUnivTransBlendTable(testtable, 215 + 600, 600),\n\t\t\tTVPUnivTransBlend_switch_d(testdest, testdata1, testdata2, testrule, testtable, 256 * 256, 215 + 600, 215)),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 600),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 215 + 600));\n\n\t\tmethod = CompileAndRegScript<tTVPOGLRenderMethod_UnivTrans>(\"UnivTransBlend_a\",\n\t\t\t\"uniform float phase;\\n\" // = phase - vague\n\t\t\t\"uniform float vague;\\n\"\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s1 = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    vec4 s2 = texture2D(tex1, v_texCoord1);\\n\"\n\t\t\t\"    vec4 rule = texture2D(tex2, v_texCoord2);\\n\"\n\t\t\t\"    float opa = clamp((rule.r - phase) / vague, 0.0, 1.0);\\n\"\n\t\t\t\"    gl_FragColor = mix(s2, s1, opa);\\n\"\n\t\t\t\"}\", 3);\n\t\tTEST_SHADER(UnivTransBlend_a,\n\t\t\t(TVPInitUnivTransBlendTable(testtable, 215, 128),\n\t\t\tTVPUnivTransBlend_a(testdest, testdata1, testdata2, testrule, testtable, 256 * 256)),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 128),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 215));\n\t\tTEST_SHADER(UnivTransBlend_a,\n\t\t\t(TVPInitUnivTransBlendTable(testtable, 215, 600),\n\t\t\tTVPUnivTransBlend_a(testdest, testdata1, testdata2, testrule, testtable, 256 * 256)),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"vague\"), 600),\n\t\t\tmethod->SetParameterInt(method->EnumParameterID(\"phase\"), 215));\n\n\t\t// --------- AlphaBlend ----------\n#define TEST_SHADER_BLTO(x) \\\n\tTEST_SHADER(x, TVP ## x ## _HDA_o(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(AlphaBlend);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend_color\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AlphaTest>(\"AlphaBlend_color_AlphaTest\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AlphaTest>(\"AlphaTest\", ScriptCommonPrefix +\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_ZERO, GL_ONE);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend_color_AlphaTest\", colorPrefix + alpha_thresholdPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    else gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaTest\", alpha_thresholdPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE, GL_ZERO, GL_ONE);\n\t\t}\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"AlphaBlend_SD\", /*opacityPrefix +*/ ScriptCommonPrefix +\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR);\n\t\tTEST_SHADER_BLTO(AlphaBlend);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsAlphaBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(PsAlphaBlend);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Perspective>(\"PerspectiveAlphaBlend_a\", opacityPrefix +\n\t\t\t\"uniform mat3 M;\\n\"\n\t\t\t\"void main() {\\n\"\n\t\t\t\"    vec3 S = vec3(gl_FragCoord.xy, 1) * M;\\n\"\n\t\t\t\"    vec4 s = texture2D(tex0, S.xy / S.z);\\n\"\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\t\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend_a\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(AlphaBlend_a,\n\t\t\tTVPAlphaBlend_ao(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend_color_a\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AlphaTest>(\"AlphaBlend_color_a_AlphaTest\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaBlend_color_a_AlphaTest\", colorPrefix + alpha_thresholdPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\t}\n\n\t\tconst char *shader_AlphaBlend_d =\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    d.a = s.a + d.a - s.a * d.a;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a / (d.a + 0.0001));\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"AlphaBlend_d\", opacityPrefix, shader_AlphaBlend_d);\n\t\tTEST_SHADER(AlphaBlend_d,\n\t\t\tTVPAlphaBlend_do(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\tshader_AlphaBlend_d =\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    d.a = s.a + d.a - s.a * d.a;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a / (d.a + 0.0001));\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"AlphaBlend_color_d\", colorPrefix, shader_AlphaBlend_d);\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegRegularBlendMethod<tTVPOGLRenderMethod_AlphaTest>(\"AlphaBlend_color_d_AlphaTest\", colorPrefix, shader_AlphaBlend_d);\n\t\t} else {\n\t\t\tCompileAndRegRegularBlendMethod(\"AlphaBlend_color_d_AlphaTest\", colorPrefix + alpha_thresholdPrefix,\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    d.a = s.a + d.a - s.a * d.a;\\n\"\n\t\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a / (d.a + 0.0001));\\n\"\n\t\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\t\"}\");\n\t\t}\n\n\t\t// --------- AddBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script_BlendColor>(\"AddBlend\", copyShader, 1)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_CONSTANT_COLOR, GL_ONE, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(AddBlend);\n\n\t\t// --------- SubBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"SubBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.rgb = (1.0 - s.rgb) * opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_ONE, GL_ONE, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(SubBlend);\n\n\t\t// --------- MulBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"MulBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.rgb = (1.0 - s.rgb) * opacity;\\n\"\n\t\t\t\"    s.a = 0.0;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\t//TEST_SHADER_BLTO(MulBlend);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"MulBlend_HDA\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.rgb = (1.0 - s.rgb) * opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\t//TEST_SHADER_BLTO(MulBlend_HDA);\n\n\t\t// --------- AdditiveAlpha ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AdditiveAlphaBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    gl_FragColor = s * opacity;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(AdditiveAlphaBlend);\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AdditiveAlphaBlend_a\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);\n\t\tTEST_SHADER(AdditiveAlphaBlend_a,\n\t\t\tTVPAdditiveAlphaBlend_ao(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\t// --------- ColorDodgeBlend ----------\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ColorDodgeBlend\", opacityPrefix + ScriptCommonBltPrefix +\n\t\t\t//\"    d.rgb /= (1.0 - s.rgb * opacity);\\n\"\n\t\t\t//\"    gl_FragColor = d;\\n\"\n\t\t\t\"    s.rgb = 1.0 / (1.0 - s.rgb * opacity);\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 2)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\t// TEST_SHADER_BLTO(ColorDodgeBlend); pass it\n\n\t\tCompileAndRegRegularBlendMethod(\"DarkenBlend\", opacityPrefix,\n\t\t\t\"    d.rgb = mix(d.rgb, min(s.rgb, d.rgb), opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(DarkenBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"LightenBlend\", opacityPrefix,\n\t\t\t\"    d.rgb = mix(d.rgb, max(s.rgb, d.rgb), opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER(LightenBlend,\n\t\t\tTVPLightenBlend_HDA_o(testdest, testdata1, 256 * 256, TEST_SHADER_OPA));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"ScreenBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\t\"    s.rgb *= opacity;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(ScreenBlend);\n\n\t\t// --------- PsXxxBlend ----------\n\t\tconst char *shader_PsAddBlend =\n\t\t\t\"    d.rgb = mix(d.rgb, clamp(s.rgb + d.rgb, 0.0, 1.0), s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"PsAddBlend\", opacityPrefix, shader_PsAddBlend);\n\t\tTEST_SHADER_BLTO(PsAddBlend);\n\n\t\tshader_PsAddBlend =\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, clamp(s.rgb + d.rgb, 0.0, 1.0), s.a);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"PsAddBlend_color\", colorPrefix, shader_PsAddBlend);\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegRegularBlendMethod<tTVPOGLRenderMethod_AlphaTest>(\"PsAddBlend_color_AlphaTest\", colorPrefix,\n\t\t\t\tshader_PsAddBlend);\n\t\t} else {\n\t\t\tCompileAndRegRegularBlendMethod(\"PsAddBlend_color_AlphaTest\", colorPrefix + alpha_thresholdPrefix,\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    d.rgb = mix(d.rgb, clamp(s.rgb + d.rgb, 0.0, 1.0), s.a);\\n\"\n\t\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\t\"}\");\n\t\t}\n\n\t\tconst char *shader_PsSubBlend =\n\t\t\t\"    d.rgb = mix(d.rgb, clamp(d.rgb + s.rgb - 1.0, 0.0, 1.0), s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"PsSubBlend\", opacityPrefix, shader_PsSubBlend);\n\t\tTEST_SHADER_BLTO(PsSubBlend);\n\n\t\tshader_PsSubBlend =\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, clamp(d.rgb + s.rgb - 1.0, 0.0, 1.0), s.a);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegRegularBlendMethod(\"PsSubBlend_color\", colorPrefix, shader_PsSubBlend);\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegRegularBlendMethod<tTVPOGLRenderMethod_AlphaTest>(\"PsSubBlend_color_AlphaTest\", colorPrefix,\n\t\t\t\tshader_PsSubBlend);\n\t\t} else {\n\t\t\tCompileAndRegRegularBlendMethod(\"PsSubBlend_color_AlphaTest\", colorPrefix + alpha_thresholdPrefix,\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    d.rgb = mix(d.rgb, clamp(d.rgb + s.rgb - 1.0, 0.0, 1.0), s.a);\\n\"\n\t\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\t\"}\");\n\t\t}\n\n\t\tconst char *shader_PsMulBlend =\n\t\t\t\"    s.a *= opacity;\\n\"\n\t\t\t\"    s.rgb *= s.a;\\n\"\n\t\t\t\"    s.rgb += 1.0 - s.a;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsMulBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\tshader_PsMulBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(PsMulBlend);\n\n\t\tshader_PsMulBlend =\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    s.rgb *= s.a;\\n\"\n\t\t\t\"    s.rgb += 1.0 - s.a;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsMulBlend_color\", colorPrefix + ScriptCommonPrefix +\n\t\t\tshader_PsMulBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AlphaTest>(\"PsMulBlend_color_AlphaTest\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\tshader_PsMulBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsMulBlend_color_AlphaTest\", colorPrefix + alpha_thresholdPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    s.rgb *= s.a;\\n\"\n\t\t\t\t\"    s.rgb += 1.0 - s.a;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);\n\t\t}\n\n\t\tCompileAndRegRegularBlendMethod(\"PsOverlayBlend\", opacityPrefix,\n\t\t\t\"    vec3 sd = s.rgb * d.rgb;\\n\"\n\t\t\t\"    s.rgb = step(0.5, d.rgb) * ((s.rgb + d.rgb) * 2.0 - sd * 4.0 - 1.0) + sd * 2.0;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsOverlayBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsHardLightBlend\", opacityPrefix,\n\t\t\t\"    vec3 sd = s.rgb * d.rgb;\\n\"\n\t\t\t\"    s.rgb = step(0.5, s.rgb) * ((s.rgb + d.rgb) * 2.0 - sd * 4.0 - 1.0) + sd * 2.0;\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsHardLightBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsSoftLightBlend\", opacityPrefix,\n\t\t\t\"    vec3 t = 0.5 / (s.rgb + 0.001);\\n\" // avoid n / 0\n\t\t\t\"    s.rgb = pow(d.rgb, (1.0 - step(0.5, s.rgb)) * ((1.0 - s.rgb) * 2.0 - t) + t);\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsSoftLightBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsColorDodgeBlend\", opacityPrefix,\n\t\t\t\"    s.rgb -= 0.001;\\n\" // avoid n / 0\n\t\t\t\"    s.rgb = d.rgb / max(1.0 - s.rgb, d.rgb);\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\t//TEST_SHADER_BLTO(PsColorDodgeBlend);\n\t\t//pass\n\n\t\tCompileAndRegRegularBlendMethod(\"PsColorDodge5Blend\", opacityPrefix,\n\t\t\t\"    s.rgb = s.rgb * s.a * opacity - 0.001;\\n\"\n\t\t\t\"    d.rgb = d.rgb / max(1.0 - s.rgb, d.rgb);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsColorDodge5Blend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsColorBurnBlend\", opacityPrefix,\n\t\t\t\"    vec3 t = 1.0 - d.rgb;\\n\"\n\t\t\t\"    s.rgb = step(t + 0.001, s.rgb) * (1.0 - t / s.rgb);\\n\"\n\t\t\t\"    s.rgb = clamp(s.rgb, 0.0, 1.0);\\n\"\n\t\t\t\"    d.rgb = mix(d.rgb, s.rgb, s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsColorBurnBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsLightenBlend\", opacityPrefix,\n\t\t\t\"    d.rgb = mix(d.rgb, max(s.rgb, d.rgb), s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsLightenBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsDarkenBlend\", opacityPrefix,\n\t\t\t\"    d.rgb = mix(d.rgb, min(s.rgb, d.rgb), s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsDarkenBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsDiffBlend\", opacityPrefix,\n\t\t\t\"    d.rgb = mix(d.rgb, abs(s.rgb - d.rgb), s.a * opacity);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsDiffBlend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsDiff5Blend\", opacityPrefix,\n\t\t\t\"    s.rgb *= s.a * opacity;\\n\"\n\t\t\t\"    d.rgb = abs(s.rgb - d.rgb);\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsDiff5Blend);\n\n\t\tCompileAndRegRegularBlendMethod(\"PsExclusionBlend\", opacityPrefix,\n\t\t\t\"    d.rgb += (s.rgb - (s.rgb * d.rgb * 2.0)) * s.a * opacity;\\n\"\n\t\t\t\"    gl_FragColor = d;\\n\"\n\t\t\t\"}\");\n\t\tTEST_SHADER_BLTO(PsExclusionBlend);\n\n\t\tconst char *shader_PsScreenBlend =\n\t\t\t\"    s.rgb *= opacity * s.a;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsScreenBlend\", opacityPrefix + ScriptCommonPrefix +\n\t\t\tshader_PsScreenBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER_BLTO(PsScreenBlend);\n\n\t\tshader_PsScreenBlend =\n\t\t\t\"    s *= color;\\n\"\n\t\t\t\"    s.rgb *= s.a;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsScreenBlend_color\", colorPrefix + ScriptCommonPrefix +\n\t\t\tshader_PsScreenBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ZERO, GL_ONE);\n\t\tif (GL::glAlphaFunc) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_AlphaTest>(\"PsScreenBlend_color_AlphaTest\", colorPrefix + ScriptCommonPrefix +\n\t\t\t\tshader_PsScreenBlend, 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ZERO, GL_ONE);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"PsScreenBlend_color_AlphaTest\", colorPrefix + alpha_thresholdPrefix + ScriptCommonPrefix +\n\t\t\t\t\"    s *= color;\\n\"\n\t\t\t\t\"    if(s.a < alpha_threshold) discard;\\n\"\n\t\t\t\t\"    s.rgb *= s.a;\\n\"\n\t\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\t\"}\", 1)->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ZERO, GL_ONE);\n\t\t}\n\t\t// AdditiveAlpha <-> Alpha\n\t\tconst char *shader_AdditiveAlphaToAlpha =\n\t\t\t\"    gl_FragColor = vec4(s.rgb / s.a, s.a);\"\n\t\t\t\"}\";\n\t\tif (GL_CHECK_shader_framebuffer_fetch) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AdditiveAlphaToAlpha\", std::string() +\n\t\t\t\t\"void main() {\\n\"\n\t\t\t\t\"    vec4 s = gl_LastFragColor;\\n\" +\n\t\t\t\tshader_AdditiveAlphaToAlpha, 0, common_shader_framebuffer_fetch_prefix);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AdditiveAlphaToAlpha\", ScriptCommonPrefix +\n\t\t\t\tshader_AdditiveAlphaToAlpha, 1)->SetTargetAsSrc();\n\t\t}\n\t\tTEST_SHADER(AdditiveAlphaToAlpha, TVPConvertAdditiveAlphaToAlpha(testdest, 256 * 256));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"AlphaToAdditiveAlpha\", \"void main(){}\", 0)\n\t\t\t->SetBlendFuncSeparate(GL_FUNC_ADD, GL_ZERO, GL_DST_ALPHA, GL_ZERO, GL_ONE);\n\t\tTEST_SHADER(AlphaToAdditiveAlpha, TVPConvertAlphaToAdditiveAlpha(testdest, 256 * 256));\n\n\t\t// DoGrayScale\n\t\tconst char *shader_DoGrayScale =\n\t\t\t\"    float c = s.r * 0.0743 + s.g * 0.7148 + s.b * 0.2109;\\n\"\n\t\t\t\"    s.r = c; s.g = c; s.b = c;\\n\"\n\t\t\t\"    gl_FragColor = s;\\n\"\n\t\t\t\"}\";\n\t\tif (GL_CHECK_shader_framebuffer_fetch) {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"DoGrayScale\", std::string() +\n\t\t\t\t\"void main() {\\n\"\n\t\t\t\t\"    vec4 s = gl_LastFragColor;\\n\" +\n\t\t\t\tshader_DoGrayScale, 0, common_shader_framebuffer_fetch_prefix);\n\t\t} else {\n\t\t\tCompileAndRegScript<tTVPOGLRenderMethod_Script>(\"DoGrayScale\", ScriptCommonPrefix +\n\t\t\t\tshader_DoGrayScale, 1)->SetTargetAsSrc();\n\t\t}\n\t\tTEST_SHADER(DoGrayScale, TVPDoGrayScale(testdest, 256 * 256));\n\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_BoxBlur>(\"BoxBlur\",\n\t\t\t\"uniform vec2 u_sample[8];\\n\"\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[0]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[1]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[2]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[3]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[4]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[5]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[6]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[7]);\\n\"\n\t\t\t\"    gl_FragColor = s / vec4(9, 9, 9, 9);\\n\"\n\t\t\t\"}\", 1)/*->SetTargetAsSrc()*/;\n\t\tCompileAndRegScript<tTVPOGLRenderMethod_BoxBlur>(\"BoxBlurAlpha\",\n\t\t\t\"uniform vec2 u_sample[8];\\n\"\n\t\t\t\"void main()\\n\"\n\t\t\t\"{\\n\"\n\t\t\t\"    vec4 s = texture2D(tex0, v_texCoord0);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[0]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[1]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[2]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[3]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[4]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[5]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[6]);\\n\"\n\t\t\t\"    s += texture2D(tex0, v_texCoord0 + u_sample[7]);\\n\"\n\t\t\t\"    gl_FragColor = s / vec4(9, 9, 9, 9);\\n\"\n\t\t\t\"}\", 1)/*->SetTargetAsSrc()*/;\n\t\t//TEST_SHADER(BoxBlur, TVPDoGrayScale(testdest, 256 * 256)); let it pass\n#if 0\n\t\t// GL_EXT_shader_framebuffer_fetch issue in some adreno GPUs\n\t\tif (TVPCheckGLExtension(\"GL_EXT_shader_framebuffer_fetch\")) {\n\t\t\ttTVPBitmap *testbmp1 = new tTVPBitmap(256, 256, 32);\n\t\t\ttTVPBitmap *testbmp2 = new tTVPBitmap(256, 256, 32);\n\t\t\tfor (int y = 0; y < 256; ++y) {\n\t\t\t\tuint8_t *pix1 = (uint8_t *)testbmp1->GetScanLine(y);\n\t\t\t\tuint8_t *pix2 = (uint8_t *)testbmp2->GetScanLine(y);\n\t\t\t\tfor (int x = 0; x < 256; ++x) {\n\t\t\t\t\tpix2[2] = pix1[0] = 255 - x;\n\t\t\t\t\tpix2[3] = pix1[1] = x;\n\t\t\t\t\tpix2[1] = pix1[2] = y;\n\t\t\t\t\tpix2[0] = pix1[3] = 255 - y;\n\t\t\t\t\tpix1 += 4;\n\t\t\t\t\tpix2 += 4;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttTVPRect rc(0, 0, 256, 256);\n\t\t\tiTVPTexture2D *testtex1 = CreateTexture2D(nullptr, 0, 256, 256, TVPTextureFormat::RGBA, 0);\n\t\t\ttesttex1->Update(testbmp1->GetScanLine(0), TVPTextureFormat::RGBA, testbmp1->GetPitch(), rc);\n\t\t\tiTVPTexture2D *testtex2 = CreateTexture2D(testbmp2);\n\t\t\t// test GL_EXT_shader_framebuffer_fetch\n\t\t\tTVPPsAddBlend_HDA((tjs_uint32*)testbmp1->GetScanLine(0), (tjs_uint32*)testbmp2->GetScanLine(0),\n\t\t\t\ttestbmp1->GetPitch() * 256 / 4);\n\n\t\t\ttTVPOGLRenderMethod_Script *method = (tTVPOGLRenderMethod_Script *)GetRenderMethod(\"PsAddBlend\");\n\t\t\tmethod->SetParameterOpa(method->EnumParameterID(\"opacity\"), 255);\n\t\t\tstd::vector<tRenderTexRectArray::Element> src_tex;\n\t\t\tsrc_tex.emplace_back(testtex2, rc);\n\t\t\tOperateRect(method, testtex1, testtex1, rc, tRenderTexRectArray(&src_tex[0], src_tex.size()));\n\n\t\t\tuint8_t *pix1 = (uint8_t *)testbmp1->GetScanLine(0);\n\t\t\tuint8_t *pix2 = (uint8_t *)testtex1->GetScanLineForRead(0);\n\t\t\tfor (int i = 0; i < 256 * 256 * 4; ++i) {\n\t\t\t\tif (std::abs(pix1[i] - pix2[i]) > 2) {\n\t\t\t\t\tconst char *btnText = \"OK\";\n\t\t\t\t\tTVPShowSimpleMessageBox(LocaleConfigManager::GetInstance()->GetText\n\t\t\t\t\t\t(\"issue_GL_EXT_shader_framebuffer_fetch\").c_str(), \"Info\", 1, &btnText);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tdelete testbmp1;\n\t\t\tdelete testbmp2;\n\t\t\tdelete testtex1;\n\t\t\tdelete testtex2;\n\t\t}\n#endif\n\t}\n\n\ttTVPOGLTexture2D *tempTexture;\n\ttTVPOGLTexture2D *GetTempTexture2D(tTVPOGLTexture2D* src, const tTVPRect& rcsrc) {\n\t\tunsigned int w = rcsrc.get_width(), h = rcsrc.get_height();\n\t\tif (!tempTexture || tempTexture->internalW < w || tempTexture->internalH < h) {\n\t\t\tif (tempTexture) tempTexture->Release();\n\t\t\ttempTexture = new tTVPOGLTexture2D_mutatble(nullptr, 0, w, h, TVPTextureFormat::RGBA, 1.f, 1.f);\n\t\t\t//tempTexture = (tTVPOGLTexture2D *)CreateTexture2D(nullptr, 0, w, h, TVPTextureFormat::RGBA);\n\t\t}\n\t\ttempTexture->Width = w; tempTexture->Height = h;\n\t\tCopyTexture(tempTexture, src, rcsrc);\n\t\treturn tempTexture;\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(const void *pixel, int pitch, unsigned int w, unsigned int h,\n\t\tTVPTextureFormat::e format, int flags) override {\n\t\tif (format > TVPTextureFormat::Compressed) {\n\t\t\tint block_width = pitch;\n\t\t\tint block_height = ((unsigned int)pitch) >> 16;\n\t\t\tif (!block_height) block_height = block_width;\n\t\t\tint blkw = (w + block_width - 1) / block_width;\n\t\t\tint blkh = (h + block_height - 1) / block_height;\n\t\t\tint blksize = 0;\n\t\t\tswitch (format) {\n\t\t\tcase TVPTextureFormat::Compressed + GL_COMPRESSED_RGB8_ETC2:\n\t\t\t\tblksize = 8; break;\n\t\t\tcase TVPTextureFormat::Compressed + GL_COMPRESSED_RGBA8_ETC2_EAC:\n\t\t\t\tblksize = 16; break;\n\t\t\tdefault:\n\t\t\t\tTVPThrowExceptionMessage(TJS_W(\"Unsupported compressed texture format [%1]\"), (tjs_int)(format - TVPTextureFormat::Compressed));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (w <= GetMaxTextureWidth() && h <= GetMaxTextureHeight()) {\n\t\t\t\treturn new tTVPOGLTexture2D_static(pixel, blkw * blkh * blksize, format - TVPTextureFormat::Compressed, w, h, w, h, 1, 1);\n\t\t\t}\n\t\t\t// too large texture, decompress and resize through default route\n\t\t\tpitch = blkw * block_width * 4;\n\t\t\ttjs_uint32* pixeldata = (tjs_uint32*)TJSAlignedAlloc(pitch * blkh * block_height, 4);\n\t\t\tbool opaque = false;\n\t\t\tswitch (format) {\n\t\t\tcase TVPTextureFormat::Compressed + GL_COMPRESSED_RGB8_ETC2:\n\t\t\t\tETCPacker::decode(pixel, pixeldata, pitch, h, blkw, blkh);\n\t\t\t\topaque = true;\n\t\t\t\tbreak;\n\t\t\tcase TVPTextureFormat::Compressed + GL_COMPRESSED_RGBA8_ETC2_EAC:\n\t\t\t\tETCPacker::decodeWithAlpha(pixel, pixeldata, pitch, h, blkw, blkh);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tTVPThrowExceptionMessage(TJS_W(\"Unsupported compressed texture format [%1]\"), (tjs_int)(format - TVPTextureFormat::Compressed));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tiTVPTexture2D *ret = _CreateStaticTexture2D(pixeldata, w, h, pitch, TVPTextureFormat::RGBA, opaque);\n\t\t\tTJSAlignedDealloc(pixeldata);\n\t\t\treturn ret;\n\t\t}\n\t\tif (pixel || (flags & RENDER_CREATE_TEXTURE_FLAG_STATIC)) {\n\t\t\tif (!pixel || (flags & RENDER_CREATE_TEXTURE_FLAG_NO_COMPRESS)) {\n\t\t\t\treturn CreateStaticTexture2D(pixel, w, h, pitch, format, w, h, false);\n\t\t\t}\n\t\t\treturn _CreateStaticTexture2D(pixel, w, h, pitch, format, false);\n\t\t}\n\t\treturn _CreateMutableTexture2D(pixel, pitch, w, h, format);\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(tTVPBitmap* bmp) override {\n\t\ttjs_uint w = bmp->GetWidth(), h = bmp->GetHeight();\n\t\tif (w > GetMaxTextureWidth()) {\n\t\t\tif (w > GetMaxTextureWidth() * 2 && GL_CHECK_unpack_subimage) {\n\t\t\t\treturn new tTVPOGLTexture2D_split(bmp);\n\t\t\t}\n\t\t} else if (h > GetMaxTextureHeight() * 2) {\n\t\t\treturn new tTVPOGLTexture2D_split(bmp);\n\t\t}\n\t\treturn _CreateStaticTexture2D(bmp->GetBits(), bmp->GetWidth(), bmp->GetHeight(), bmp->GetPitch(),\n\t\t\tbmp->Is32bit() ? TVPTextureFormat::RGBA : TVPTextureFormat::Gray, bmp->IsOpaque);\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(unsigned int neww, unsigned int newh, iTVPTexture2D* tex) override {\n\t\ttTVPOGLTexture2D* newtex = static_cast<tTVPOGLTexture2D*>(_CreateMutableTexture2D(nullptr, 0, neww, newh, tex->GetFormat()));\n\t\tCopyTexture(newtex, static_cast<tTVPOGLTexture2D*>(tex), tTVPRect(0, 0, tex->GetWidth(), tex->GetHeight()));\n\t\treturn newtex;\n\t}\n\n\tvirtual iTVPTexture2D* CreateTexture2D(tTJSBinaryStream* src) {\n\t\t// support PVRv3 only so far\n\t\tPVRv3Header header;\n\t\tif (src->Read(&header, sizeof(header)) != sizeof(header)) {\n\t\t\treturn nullptr;\n\t\t}\n\n\t\tif (memcmp(&header, \"PVR\\3\", 4)) {\n\t\t\treturn nullptr;\n\t\t}\n\n\t\tif (header.width > GetMaxTextureWidth() || header.height > GetMaxTextureHeight()) {\n\t\t\treturn nullptr;\n\t\t}\n\n\t\t// skip metainfo\n\t\tsrc->SetPosition(src->GetPosition() + header.metadataLength);\n\n\t\t// normal texture\n\t\tTVPTextureFormat::e texfmt;\n\t\tGLenum fmt = 0, pixtype = 0;\n\t\ttjs_uint pixsize = 0;\n\t\tswitch ((PVR3TexturePixelFormat)header.pixelFormat) {\n\t\tcase PVR3TexturePixelFormat::BGRA8888: texfmt = TVPTextureFormat::RGBA; fmt = GL_BGRA_EXT; pixsize = 4; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tcase PVR3TexturePixelFormat::RGBA8888: texfmt = TVPTextureFormat::RGBA; fmt = GL_RGBA; pixsize = 4; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tcase PVR3TexturePixelFormat::RGBA4444: texfmt = TVPTextureFormat::RGBA; fmt = GL_RGBA; pixsize = 2; pixtype = GL_UNSIGNED_SHORT_4_4_4_4; break;\n\t\tcase PVR3TexturePixelFormat::RGBA5551: texfmt = TVPTextureFormat::RGBA; fmt = GL_RGBA; pixsize = 2; pixtype = GL_UNSIGNED_SHORT_5_5_5_1; break;\n\t\tcase PVR3TexturePixelFormat::RGB565: texfmt = TVPTextureFormat::RGB; fmt = GL_RGB; pixsize = 2; pixtype = GL_UNSIGNED_SHORT_5_6_5; break;\n\t\tcase PVR3TexturePixelFormat::RGB888: texfmt = TVPTextureFormat::RGB; fmt = GL_RGB; pixsize = 3; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tcase PVR3TexturePixelFormat::A8: texfmt = TVPTextureFormat::Gray; fmt = GL_ALPHA; pixsize = 1; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tcase PVR3TexturePixelFormat::L8: texfmt = TVPTextureFormat::Gray; fmt = GL_LUMINANCE; pixsize = 1; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tcase PVR3TexturePixelFormat::LA88: texfmt = TVPTextureFormat::RGBA; fmt = GL_LUMINANCE_ALPHA; pixsize = 2; pixtype = GL_UNSIGNED_BYTE; break;\n\t\tdefault: break;\n\t\t}\n\t\t\n\t\tif (fmt) {\n\t\t\ttjs_uint pitch = header.width * pixsize;\n\t\t\tpixsize = pitch * header.height;\n\t\t\tstd::vector<unsigned char> buf; buf.resize(pixsize);\n\t\t\tif (src->Read(&buf.front(), pixsize) != pixsize) return nullptr;\n\t\t\tif (fmt == GL_BGRA_EXT &&\n\t\t\t\t!TVPCheckGLExtension(\"GL_EXT_texture_format_BGRA8888\") &&\n\t\t\t\t!TVPCheckGLExtension(\"GL_EXT_bgra\")) {\n\t\t\t\tTVPReverseRGB((tjs_uint32*)&buf.front(), (tjs_uint32*)&buf.front(), pixsize / 4);\n\t\t\t}\n\t\t\ttTVPOGLTexture2D_static *ret = new tTVPOGLTexture2D_static(texfmt, header.width, header.height,1, 1);\n\t\t\tret->InitPixel(&buf.front(), pitch, fmt, pixtype, header.width, header.height);\n\t\t\treturn ret;\n\t\t}\n\n\t\t// compressed texture\n\t\tfmt = 0;\n\t\tunsigned int eachblkw, eachblkh, blksize;\n\t\tswitch ((PVR3TexturePixelFormat)header.pixelFormat) {\n\t\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGB: fmt = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; eachblkw = 8; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::PVRTC2BPP_RGBA: fmt = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; eachblkw = 8; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGB: fmt = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; eachblkw = 4; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::PVRTC4BPP_RGBA: fmt = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; eachblkw = 4; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::PVRTC2_2BPP_RGBA: fmt = GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG; eachblkw = 8; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::PVRTC2_4BPP_RGBA: fmt = GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG; eachblkw = 8; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::ETC1: fmt = GL_ETC1_RGB8_OES; eachblkw = 4; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::ETC2_RGB: fmt = GL_COMPRESSED_RGB8_ETC2; eachblkw = 4; eachblkh = 4; blksize = 8; break;\n\t\tcase PVR3TexturePixelFormat::ETC2_RGBA: fmt = GL_COMPRESSED_RGBA8_ETC2_EAC; eachblkw = 4; eachblkh = 4; blksize = 16; break;\n\t\tcase PVR3TexturePixelFormat::ETC2_RGBA1: fmt = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; eachblkw = 4; eachblkh = 4; blksize = 8; break;\n\t\t// TODO ASTC\n\t\tdefault: return nullptr;\n\t\t}\n\n\t\tif (TVPIsSupportTextureFormat(fmt)) {\n\t\t\tunsigned int blkw = (header.width + eachblkw - 1) / eachblkw;\n\t\t\tunsigned int blkh = (header.height + eachblkh - 1) / eachblkh;\n\t\t\tunsigned int size = blkw * blkh * blksize;\n\t\t\tstd::vector<unsigned char> buf; buf.resize(size);\n\t\t\tif (src->Read(&buf.front(), pixsize) != pixsize) return nullptr;\n\t\t\ttTVPOGLTexture2D_static *ret = new tTVPOGLTexture2D_static(texfmt, header.width, header.height, 1, 1);\n\t\t\tret->InitCompressedPixel(&buf.front(), size, fmt, blkw * eachblkw, blkh * eachblkh);\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn nullptr;\n\t}\n\n\tvoid CopyTexture(tTVPOGLTexture2D *dst, tTVPOGLTexture2D *src, const tTVPRect &rcsrc) {\n\t\tif (GL::glCopyImageSubData && !src->IsCompressed &&\n\t\t\tsrc->_scaleW == dst->_scaleW && src->_scaleH == dst->_scaleH &&\n\t\t\tsrc->Format == dst->Format) {\n\t\t\ttTVPRect rc;\n\t\t\trc.left = rcsrc.left * src->_scaleW + 0.5f;\n\t\t\trc.right = rcsrc.right * src->_scaleW;\n\t\t\trc.top = rcsrc.top * src->_scaleH + 0.5f;\n\t\t\trc.bottom = rcsrc.bottom * src->_scaleH;\n\t\t\ttTVPRect rcsrc;\n\t\t\trcsrc.left = 0;\n\t\t\trcsrc.top = 0;\n\t\t\trcsrc.right = src->GetInternalWidth();\n\t\t\trcsrc.bottom = src->GetInternalHeight();\n\t\t\tTVPIntersectRect(&rc, rc, rcsrc);\n\t\t\tif (dst->GetInternalWidth() < rc.get_width()) {\n\t\t\t\trc.set_width(dst->GetInternalWidth());\n\t\t\t}\n\t\t\tif (dst->GetInternalHeight() < rc.get_height()) {\n\t\t\t\trc.set_height(dst->GetInternalHeight());\n\t\t\t}\n\t\t\tif (rc.get_width() == 0 || rc.get_height() == 0)\n\t\t\t\treturn;\n\t\t\tGL::glCopyImageSubData(\n\t\t\t\tsrc->texture, GL_TEXTURE_2D, 0, rc.left, rc.top, 0,\n\t\t\t\tdst->texture, GL_TEXTURE_2D, 0, 0, 0, 0,\n\t\t\t\trc.get_width(), rc.get_height(), 1);\n\t\t\tCHECK_GL_ERROR_DEBUG();\n#ifdef _DEBUG\n\t\t\tstatic bool check = false;\n\t\t\tif (check) {\n\t\t\t\tcv::Mat _src(src->internalH, src->internalW, CV_8UC4);\n\t\t\t\tcv::Mat _dst(dst->internalH, dst->internalW, CV_8UC4);\n\t\t\t\tGL::glGetTextureImage(src->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, src->internalH * src->internalW * 4, _src.ptr(0, 0));\n\t\t\t\tGL::glGetTextureImage(dst->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, dst->internalH * dst->internalW * 4, _dst.ptr(0, 0));\n\t\t\t\tdst = dst;\n\t\t\t}\n#endif\n\t\t\treturn;\n\t\t}\n\n\t\tstatic tTVPOGLRenderMethod* method = (tTVPOGLRenderMethod*)GetRenderMethod(\"Copy\");\n\t\tstatic const GLfloat\n\t\t\tminx = -1,\n\t\t\tmaxx = 1,\n\t\t\tminy = -1,\n\t\t\tmaxy = 1;\n\t\tstatic const GLfloat vertices[12] = {\n\t\t\tminx, miny,\n\t\t\tmaxx, miny,\n\t\t\tminx, maxy,\n\n\t\t\tmaxx, miny,\n\t\t\tminx, maxy,\n\t\t\tmaxx, maxy\n\t\t};\n\t\tCHECK_GL_ERROR_DEBUG();\n\t\tmethod->Apply();\n\t\tdst->AsTarget();\n\t\tfloat sw, sh;\n\t\tdst->GetScale(sw, sh);\n\t\tglViewport(0, 0, rcsrc.get_width() * sw, rcsrc.get_height() * sh);\n\t\tCHECK_GL_ERROR_DEBUG();\n\t\tint VA_flag = 1 << method->GetPosAttr();\n\t\tfor (unsigned int i = 0; i < 1; ++i) {\n\t\t\tVA_flag |= 1 << method->GetTexCoordAttr(i);\n\t\t}\n\t\tcocos2d::GL::enableVertexAttribs(VA_flag);\n\t\tglVertexAttribPointer(method->GetPosAttr(), 2, GL_FLOAT, GL_FALSE, 0, vertices);\n\n\t\tGLVertexInfo vtx;\n\t\tsrc->ApplyVertex(vtx, rcsrc);\n\t\tcocos2d::GL::bindTexture2D(src->texture);\n\n\t\tglVertexAttribPointer(method->GetTexCoordAttr(0), 2, GL_FLOAT, GL_FALSE, 0, &vtx.vtx.front());\n\t\tglDrawArrays(GL_TRIANGLES, 0, 6);\n\t\tmethod->onFinish();\n\t\tCHECK_GL_ERROR_DEBUG();\n#ifdef _DEBUG\n\t\tstatic bool check = false;\n\t\tif (check) {\n\t\t\tcv::Mat _src(src->internalH, src->internalW, CV_8UC4);\n\t\t\tcv::Mat _dst(dst->internalH, dst->internalW, CV_8UC4);\n\t\t\tGL::glGetTextureImage(src->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, src->internalH * src->internalW * 4, _src.ptr(0, 0));\n\t\t\tGL::glGetTextureImage(dst->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, dst->internalH * dst->internalW * 4, _dst.ptr(0, 0));\n\t\t\tdst = dst;\n\t\t}\n#endif\n\t}\n\n\tvirtual const char *GetName() { return \"OpenGL\"; }\n\tvirtual bool IsSoftware() { return false; }\n\tvirtual bool GetRenderStat(unsigned int &drawCount, uint64_t &vmemsize) {\n\t\tdrawCount = _drawCount;\n\t\t_drawCount = 0;\n\t\tvmemsize = _totalVMemSize;\n\n\t\treturn true;\n\t}\n\n\tvirtual bool GetTextureStat(iTVPTexture2D *texture, uint64_t &vmemsize) {\n\t\tif (!texture) {\n\t\t\tvmemsize = 0;\n\t\t\treturn false;\n\t\t}\n\t\tvmemsize = texture->GetInternalWidth() * texture->GetInternalHeight() * 4;\n\t\treturn true;\n\t}\n\n\t// dst x Tex1 x ... x TexN -> dst\n\tvirtual void OperateRect(iTVPRenderMethod* _method,\n\t\tiTVPTexture2D *_tar, iTVPTexture2D *reftar, const tTVPRect& rctar,\n\t\tconst tRenderTexRectArray &textures) {\n\t\t++_drawCount;\n\t\ttTVPOGLRenderMethod *method = (tTVPOGLRenderMethod*)_method;\n\t\ttTVPOGLTexture2D *tar = (tTVPOGLTexture2D *)_tar;\n\t\tif (reftar == _tar) reftar = nullptr;\n\t\tif (method->CustomProc && method->CustomProc(method, tar, (tTVPOGLTexture2D *)reftar, &rctar, textures)) {\n\t\t\treturn;\n\t\t}\n\n\t\tstd::vector<GLVertexInfo> texlist;\n\t\ttexlist.resize(textures.size() + (method->tar_as_src ? 1 : 0));\n\t\tfor (unsigned int i = 0; i < textures.size(); ++i) {\n\t\t\ttTVPOGLTexture2D *tex = (tTVPOGLTexture2D *)(textures[i].first);\n\t\t\ttex->SyncPixel();\n\t\t\tGLVertexInfo &texitem = texlist[i];\n\t\t\tif (/*_duplicateTargetTexture &&*/ tex == tar) {\n\t\t\t\ttTVPOGLTexture2D *newtex;\n\t\t\t\ttTVPRect rc = textures[i].second;\n\t\t\t\tif (reftar) {\n\t\t\t\t\tnewtex = (tTVPOGLTexture2D *)reftar;\n\t\t\t\t} else if (rc.get_width() >= 0 && rc.get_height() >= 0) {\n\t\t\t\t\tnewtex = GetTempTexture2D(tex, rc);\n\t\t\t\t\trc.set_offsets(0, 0);\n\t\t\t\t} else {\n\t\t\t\t\ttTVPRect rcsrc(rc);\n\t\t\t\t\ttjs_int w = rc.get_width(), h = rc.get_height();\n\t\t\t\t\tif (w < 0) {\n\t\t\t\t\t\tstd::swap(rcsrc.left, rcsrc.right);\n\t\t\t\t\t\trc.right = 0;\n\t\t\t\t\t\trc.left = -w;\n\t\t\t\t\t}\n\t\t\t\t\tif (h < 0) {\n\t\t\t\t\t\tstd::swap(rcsrc.top, rcsrc.bottom);\n\t\t\t\t\t\trc.bottom = 0;\n\t\t\t\t\t\trc.top = -h;\n\t\t\t\t\t}\n\t\t\t\t\tnewtex = GetTempTexture2D(tex, rcsrc);\n\t\t\t\t}\n\t\t\t\tnewtex->ApplyVertex(texitem, rc);\n\t\t\t} else {\n\t\t\t\ttex->ApplyVertex(texitem, textures[i].second);\n\t\t\t}\n\t\t}\n\t\ttar->SyncPixel();\n\t\tif (method->tar_as_src) {\n\t\t\ttTVPOGLTexture2D *tex = tar;\n\t\t\tGLVertexInfo &texitem = texlist.back();\n\t//\t\tif (_duplicateTargetTexture)\n\t\t\t{\n\t\t\t\ttTVPOGLTexture2D *newtex;\n\t\t\t\ttTVPRect rc = rctar;\n\t\t\t\tif (reftar) {\n\t\t\t\t\tnewtex = (tTVPOGLTexture2D *)reftar;\n\t\t\t\t} else {\n\t\t\t\t\tnewtex = GetTempTexture2D(tex, rc);\n#ifdef _DEBUG\n\t\t\t\t\tif (!newtex) {\n\t\t\t\t\t\ttex->GetScanLineForRead(0);\n\t\t\t\t\t\ttex = newtex;\n\t\t\t\t\t\ttex->GetScanLineForRead(0);\n\t\t\t\t\t}\n#endif\n\t\t\t\t\trc.set_offsets(0, 0);\n\t\t\t\t}\n\t\t\t\tnewtex->ApplyVertex(texitem, rc);\n// \t\t\t} else {\n// \t\t\t\ttex->ApplyVertex(texitem, rctar);\n\t\t\t}\n\t\t}\n\t\t//if (!method->CustomProc || !(method->*(method->CustomProc))(tar, rctar, texlist)) {\n\t\t\t//float tw = (float)tar->internalW, th = (float)tar->internalH;\n\t\t\tstatic const GLfloat\n\t\t\t\tminx = -1,//(GLfloat)rctar.left / tw,\n\t\t\t\tmaxx = 1,//(GLfloat)rctar.right / tw,\n\t\t\t\tminy = -1,//(GLfloat)rctar.top / th,\n\t\t\t\tmaxy = 1;//(GLfloat)rctar.bottom / th;\n\t\t\tstatic const GLfloat vertices[12] = {\n\t\t\t\tminx, miny,\n\t\t\t\tmaxx, miny,\n\t\t\t\tminx, maxy,\n\n\t\t\t\tmaxx, miny,\n\t\t\t\tminx, maxy,\n\t\t\t\tmaxx, maxy\n\t\t\t};\n\t\t\tmethod->Apply();\n\t\t\ttar->AsTarget();\n\t\t\tglViewport(rctar.left * tar->_scaleW, rctar.top * tar->_scaleH,\n\t\t\t\trctar.get_width() * tar->_scaleW, rctar.get_height() * tar->_scaleH);\n\t\t\tint VA_flag = 1 << method->GetPosAttr();\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\tVA_flag |= 1 << method->GetTexCoordAttr(i);\n\t\t\t}\n\t\t\tcocos2d::GL::enableVertexAttribs(VA_flag);\n\t\t\tglVertexAttribPointer(method->GetPosAttr(), 2, GL_FLOAT, GL_FALSE, 0, vertices);\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\tmethod->ApplyTexture(i, texlist[i]);\n\t\t\t}\n\t\t\tglDrawArrays(GL_TRIANGLES, 0, 6);\n        //}\n\t\tmethod->onFinish();\n        CHECK_GL_ERROR_DEBUG();\n#ifdef _DEBUG\n\t\tstatic bool check = false;\n\t\tif (check) {\n\t\t\tcv::Mat *_src[3] = { nullptr };\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\t_src[i] = new cv::Mat(texlist[i].tex->internalH, texlist[i].tex->internalW, CV_8UC4);\n\t\t\t\tGL::glGetTextureImage(texlist[i].tex->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, texlist[i].tex->internalH * texlist[i].tex->internalW * 4, _src[i]->ptr(0, 0));\n\t\t\t}\n\t\t\tcv::Mat _tar(tar->internalH, tar->internalW, CV_8UC4);\n\t\t\tcv::Mat _stencil(tar->internalH, tar->internalW, CV_8U);\n\t\t\tGL::glGetTextureImage(tar->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, tar->internalH * tar->internalW * 4, _tar.ptr(0, 0));\n\t\t\tif (glIsEnabled(GL_STENCIL_TEST)) {\n\t\t\t\tglReadPixels(0, 0, tar->internalW, tar->internalH, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, _stencil.ptr(0, 0));\n\t\t\t}\n\t\t\ttar = tar;\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\tdelete _src[i];\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\t// src x dst -> tar todo: OperateTriangles\n\tvirtual void OperateTriangles(iTVPRenderMethod* _method, int nTriangles,\n\t\tiTVPTexture2D *_tar, iTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* _pttar,\n\t\tconst tRenderTexQuadArray &textures) {\n\t\t++_drawCount;\n\t\ttTVPOGLRenderMethod *method = (tTVPOGLRenderMethod*)_method;\n\t\ttTVPOGLTexture2D *tar = (tTVPOGLTexture2D *)_tar;\n\t\tif (_tar == reftar) reftar = nullptr;\n\t\tint ptcount = nTriangles * 3;\n\n\t\tstd::vector<GLVertexInfo> texlist;\n\t\ttexlist.resize(textures.size() + (method->tar_as_src ? 1 : 0));\n\t\tfor (unsigned int i = 0; i < textures.size(); ++i) {\n\t\t\ttTVPOGLTexture2D *tex = (tTVPOGLTexture2D *)(textures[i].first);\n\t\t\ttex->SyncPixel();\n\t\t\tGLVertexInfo &texitem = texlist[i];\n\t\t\tif (/*_duplicateTargetTexture &&*/ tex == tar) {\n\t\t\t\ttTVPOGLTexture2D *newtex;\n\t\t\t\tif (reftar) newtex = (tTVPOGLTexture2D *)reftar;\n\t\t\t\telse {\n\t\t\t\t\tnewtex = GetTempTexture2D(tex, tTVPRect(0, 0, tex->GetWidth(), tex->GetHeight()));\n\t\t\t\t}\n\t\t\t\tnewtex->ApplyVertex(texitem, textures[i].second, ptcount);\n\t\t\t} else {\n\t\t\t\ttex->ApplyVertex(texitem, textures[i].second, ptcount);\n\t\t\t}\n\t\t}\n\t\tif (method->tar_as_src) {\n\t\t\ttTVPOGLTexture2D *tex = tar;\n\t\t\tGLVertexInfo &texitem = texlist.back();\n\t\t\t{\n\t\t\t\tif (reftar) {\n\t\t\t\t\tstatic_cast<tTVPOGLTexture2D *>(reftar)->ApplyVertex(texitem, _pttar, ptcount);\n\t\t\t\t} else {\n\t\t\t\t\tdouble l = rcclip.right, t = rcclip.bottom, r = rcclip.left, b = rcclip.top;\n\t\t\t\t\tfor (int i = 0; i < ptcount; ++i) {\n\t\t\t\t\t\tconst tTVPPointD& pt = _pttar[i];\n\t\t\t\t\t\tif (pt.x < l) l = pt.x;\n\t\t\t\t\t\tif (pt.x > r) r = pt.x;\n\t\t\t\t\t\tif (pt.y < t) t = pt.y;\n\t\t\t\t\t\tif (pt.y > b) b = pt.y;\n\t\t\t\t\t}\n\t\t\t\t\ttTVPRect rc(l, t, std::ceil(r), std::ceil(b));\n\t\t\t\t\tif (!TVPIntersectRect(&rc, rcclip, rc)) {\n\t\t\t\t\t\t// nothing to draw\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tl = rc.left; t = rc.top;\n\t\t\t\t\ttTVPOGLTexture2D *newtex = GetTempTexture2D(tex, rc);\n\t\t\t\t\tstd::vector<tTVPPointD> pttar; pttar.reserve(ptcount);\n\t\t\t\t\tfor (int i = 0; i < ptcount; ++i) {\n\t\t\t\t\t\tpttar.emplace_back(tTVPPointD{ _pttar[i].x - l, _pttar[i].y - t });\n\t\t\t\t\t}\n\t\t\t\t\tnewtex->ApplyVertex(texitem, &pttar.front(), ptcount);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tstd::vector<GLfloat> pttar;\n\t\tfloat rcw = rcclip.get_width(), rch = rcclip.get_height();\n\t\tfloat rcl = rcclip.left, rct = rcclip.top;\n\t\tpttar.resize(ptcount * 2);\n\t\tfor (int i = 0; i < ptcount; ++i) {\n\t\t\tpttar[i * 2 + 0] = (((GLfloat)_pttar[i].x - rcl) / rcw - 0.5f) * 2.f;\n\t\t\tpttar[i * 2 + 1] = (((GLfloat)_pttar[i].y - rct) / rch - 0.5f) * 2.f;\n\t\t}\n\t\trcw *= tar->_scaleW;\n\t\trch *= tar->_scaleH;\n\t\trcl *= tar->_scaleW;\n\t\trct *= tar->_scaleH;\n\t\ttar->AsTarget();\n\t\tglViewport(rcl, rct, rcw, rch);\n\t\tCHECK_GL_ERROR_DEBUG();\n//\t\tif (tar->GetWidth() == rcclip.get_width() && tar->GetHeight() == rcclip.get_height()) {\n// \t\t\tGLfloat oldClearColor[4] = { 0.0f };\n// \t\t\tglGetFloatv(GL_COLOR_CLEAR_VALUE, oldClearColor);\n// \t\t\tglClearColor(0.f, 0.f, 0.f, 0.f);\n// \t\t\tglClear(GL_COLOR_BUFFER_BIT);\n\t\t\t//glClearColor(oldClearColor[0], oldClearColor[1], oldClearColor[2], oldClearColor[3]);\n// \t\t} else {\n// \t\t\tstatic tTVPOGLRenderMethod* _method = static_cast<tTVPOGLRenderMethod*>(GetRenderMethod(\"FillARGB\"));\n// \t\t\tstatic int _id = _method->EnumParameterID(\"color\");\n// \t\t\t_method->SetParameterColor4B(_id, 0);\n// \t\t\tcocos2d::GL::enableVertexAttribs(1 << _method->GetPosAttr());\n// \t\t\t_method->Apply();\n// \t\t\tstatic const GLfloat\n// \t\t\t\tminx = -1,\n// \t\t\t\tmaxx = 1,\n// \t\t\t\tminy = -1,\n// \t\t\t\tmaxy = 1;\n// \t\t\tstatic const GLfloat vertices[8] = {\n// \t\t\t\tminx, miny,\n// \t\t\t\tmaxx, miny,\n// \t\t\t\tminx, maxy,\n// \t\t\t\tmaxx, maxy\n// \t\t\t};\n// \t\t\tglVertexAttribPointer(method->GetPosAttr(), 2, GL_FLOAT, GL_FALSE, 0, vertices);\n// \t\t\tglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\n// \t\t\tCHECK_GL_ERROR_DEBUG();\n// \t\t}\n\n\t\tmethod->Apply();\n\t\tint VA_flag = 1 << method->GetPosAttr();\n\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\tVA_flag |= 1 << method->GetTexCoordAttr(i);\n\t\t}\n\t\tcocos2d::GL::enableVertexAttribs(VA_flag);\n\t\tglVertexAttribPointer(method->GetPosAttr(), 2, GL_FLOAT, GL_FALSE, 0, &pttar.front());\n\t\tCHECK_GL_ERROR_DEBUG();\n\n\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t//tex->SyncPixel();\n\t\t\tmethod->ApplyTexture(i, texlist[i]);\n\t\t}\n        glDrawArrays(GL_TRIANGLES, 0, ptcount);\n\t\tmethod->onFinish();\n\t\tCHECK_GL_ERROR_DEBUG();\n#ifdef _DEBUG\n\t\tstatic bool check = false;\n\t\tif (check) {\n\t\t\tcv::Mat *_src[3] = { nullptr };\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\t_src[i] = new cv::Mat(texlist[i].tex->internalH, texlist[i].tex->internalW, CV_8UC4);\n\t\t\t\tGL::glGetTextureImage(texlist[i].tex->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, texlist[i].tex->internalH * texlist[i].tex->internalW * 4, _src[i]->ptr(0, 0));\n\t\t\t}\n\t\t\tcv::Mat _tar(tar->internalH, tar->internalW, CV_8UC4);\n\t\t\tcv::Mat _stencil(tar->internalH, tar->internalW, CV_8U);\n\t\t\tGL::glGetTextureImage(tar->texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, tar->internalH * tar->internalW * 4, _tar.ptr(0, 0));\n\t\t\tif (glIsEnabled(GL_STENCIL_TEST)) {\n\t\t\t\tglReadPixels(0, 0, tar->internalW, tar->internalH, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, _stencil.ptr(0, 0));\n\t\t\t}\n\t\t\ttar = tar;\n\t\t\tfor (unsigned int i = 0; i < texlist.size(); ++i) {\n\t\t\t\tdelete _src[i];\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tclass tTVPOGLRenderMethod_Perspective : public tTVPOGLRenderMethod_Script {\n\tpublic:\n\t\tint id_Matrix;\n\n\t\tvirtual void Rebuild() {\n\t\t\tprogram = CombineProgram(GetVertShader(m_nTex),\n\t\t\t\tCompileShader(GL_FRAGMENT_SHADER, m_strScript));\n\t\t\tcocos2d::GL::useProgram(program);\n\t\t\tstd::string tex(\"tex\");\n\t\t\tstd::string coord(\"a_texCoord\");\n\t\t\tfor (int i = 0; i < m_nTex; ++i) {\n\t\t\t\tchar sCounter[8];\n\t\t\t\tsprintf(sCounter, \"%d\", i);\n\t\t\t\tint loc = glGetUniformLocation(program, (tex + sCounter).c_str());\n\t\t\t\tglUniform1i(loc, i);\n\t\t\t\tloc = glGetAttribLocation(program, (coord + sCounter).c_str());\n\t\t\t\ttex_coord_attr_location.push_back(loc);\n\t\t\t}\n\t\t\tpos_attr_location = glGetAttribLocation(program, \"a_position\");\n\t\t\tid_Matrix = EnumParameterID(\"M\");\n\t\t}\n\n\t\tvirtual void ApplyTexture(unsigned int i, const GLVertexInfo &info) {\n\t\t\tinfo.tex->Bind(i);\n\t\t\t//glVertexAttribPointer(GetTexCoordAttr(i), 2, GL_FLOAT, GL_FALSE, 0, &info.vtx.front());\n\t\t}\n\n\t\tvoid ApplyMatrix(const float *mtx/*3x3*/) {\n\t\t\tcocos2d::GL::useProgram(program);\n\t\t\tglUniformMatrix3fv(id_Matrix, 1, GL_FALSE, mtx);\n\t\t}\n\t};\n\n\tvirtual void OperatePerspective(iTVPRenderMethod* _method, int nQuads, iTVPTexture2D *_tar,\n\t\tiTVPTexture2D *reftar, const tTVPRect& rcclip, const tTVPPointD* _pttar/*quad{lt,rt,lb,rb}*/,\n\t\tconst tRenderTexQuadArray &textures) {\n\t\t++_drawCount;\n\t\ttTVPOGLTexture2D *tar = (tTVPOGLTexture2D *)_tar;\n\n\t\ttTVPOGLRenderMethod_Perspective* method = (tTVPOGLRenderMethod_Perspective*)_method;\n\n\t\tconst tTVPPointD *dstpt = _pttar;\n\t\tconst tTVPPointD *srcpt = textures[0].second;\n\t\tfloat tw = textures[0].first->GetInternalWidth(), th = textures[0].first->GetInternalHeight();\n\t\tfloat dw = _tar->GetInternalWidth(), dh = _tar->GetInternalHeight();\n\n\t\tfor (int i = 0; i < nQuads; ++i) {\n\t\t\tcv::Point2f pts_src[] = {\n\t\t\t\tcv::Point2f(srcpt[0].x / tw, srcpt[0].y / th),\n\t\t\t\tcv::Point2f((srcpt[1].x + 1) / tw, srcpt[1].y / th),\n\t\t\t\tcv::Point2f((srcpt[3].x + 1) / tw, (srcpt[3].y + 1) / th),\n\t\t\t\tcv::Point2f(srcpt[2].x / tw, (srcpt[2].y + 1) / th) };\n\t\t\tcv::Point2f pts_dst[] = {\n\t\t\t\tcv::Point2f(dstpt[0].x * tar->_scaleW, dstpt[0].y * tar->_scaleH),\n\t\t\t\tcv::Point2f(dstpt[1].x * tar->_scaleW, dstpt[1].y * tar->_scaleH),\n\t\t\t\tcv::Point2f(dstpt[3].x * tar->_scaleW, dstpt[3].y * tar->_scaleH),\n\t\t\t\tcv::Point2f(dstpt[2].x * tar->_scaleW, dstpt[2].y * tar->_scaleH) };\n\n\t\t\tcv::Mat perspective_matrix = cv::getPerspectiveTransform(pts_dst, pts_src);\n\t\t\tif (perspective_matrix.elemSize1() == 4) { // float\n\t\t\t\tmethod->ApplyMatrix((float*)perspective_matrix.ptr());\n\t\t\t} else {\n\t\t\t\tfloat mtx[9];\n\t\t\t\tdouble *ptr = perspective_matrix.ptr<double>();\n\t\t\t\tfor (int i = 0; i < 9; ++i) {\n\t\t\t\t\tmtx[i] = ptr[i];\n\t\t\t\t}\n\t\t\t\tmethod->ApplyMatrix(mtx);\n\t\t\t}\n\n\t\t\t// pass to OperateTriangles\n\t\t\ttTVPPointD pttar[6] = {\n\t\t\t\tdstpt[0], // \n\t\t\t\tdstpt[1], // \n\t\t\t\tdstpt[2], // \n\n\t\t\t\tdstpt[1], // \n\t\t\t\tdstpt[2], // \n\t\t\t\tdstpt[3], // \n\t\t\t}, pttex[6] = {\n\t\t\t\tsrcpt[0],\n\t\t\t\tsrcpt[1],\n\t\t\t\tsrcpt[2],\n\n\t\t\t\tsrcpt[1],\n\t\t\t\tsrcpt[2],\n\t\t\t\tsrcpt[3]\n\t\t\t};\n\n\t\t\t*(tTVPPointD **)&textures[0].second = &pttex[0];\n\n\t\t\tdstpt += 4;\n\t\t\tsrcpt += 4;\n\n\t\t\tOperateTriangles(method, nQuads * 2, _tar, reftar, rcclip, &pttar[0], textures);\n\t\t}\n\t}\n\n\tvirtual void BeginStencil(iTVPTexture2D* reftex) {\n\t\tif (_CurrentFBOValid && _CurrentRenderTarget) {\n\t\t\tglGetIntegerv(GL_RENDERBUFFER_BINDING, &_prevRenderBuffer);\n\t\t\tglBindRenderbuffer(GL_RENDERBUFFER, _stencil_FBO);\n\t\t\tbool recreateRenderBuffer = false;\n\t\t\tunsigned int w = reftex->GetInternalWidth(), h = reftex->GetInternalHeight();\n\t\t\tif (_stencilBufferW != w) {\n\t\t\t\t_stencilBufferW = w;\n\t\t\t\trecreateRenderBuffer = true;\n\t\t\t}\n\t\t\tif (_stencilBufferH != h) {\n\t\t\t\t_stencilBufferH = h;\n\t\t\t\trecreateRenderBuffer = true;\n\t\t\t}\n\t\t\tif (recreateRenderBuffer) {\n\t\t\t\tglRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, _stencilBufferW, _stencilBufferH);\n\t\t\t}\n\t\t\tglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _stencil_FBO);\n\t\t\tglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _stencil_FBO);\n\t\t\tCHECK_GL_ERROR_DEBUG();\n\t\t}\n\t}\n\n\tvirtual void EndStencil() override {\n\t\tglDisable(GL_STENCIL_TEST);\n\t\tglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);\n\t\tglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);\n\t\tglBindRenderbuffer(GL_RENDERBUFFER, _prevRenderBuffer);\n\t\tCHECK_GL_ERROR_DEBUG();\n\t}\n\n\tvirtual void SetRenderTarget(iTVPTexture2D *target) override {\n\t\tstatic_cast<tTVPOGLTexture2D*>(target)->AsTarget();\n\t}\n\n};\n\nREGISTER_RENDERMANAGER(TVPRenderManager_OpenGL, opengl);\n"
  },
  {
    "path": "src/core/visual/ogl/RenderManager_ogl_test.hpp",
    "content": "#define TEST_SHADER_COLOR 0xAA981255\n#define TEST_SHADER_OPA 100\n#define TEST_SHADER(_method, ...) _TEST_SHADER(#_method, this, \\\n\t[&](std::vector<tRenderTexRectArray::Element> &src_tex, tTVPOGLRenderMethod *method){__VA_ARGS__; }, false);\n#define TEST_SHADER_IGNORE_ALPHA(_method, ...) _TEST_SHADER(#_method, this, \\\n\t[&](std::vector<tRenderTexRectArray::Element> &src_tex, tTVPOGLRenderMethod *method){__VA_ARGS__; }, true);\n\nstatic tjs_uint32 *testbuff = new tjs_uint32[256 * 256 * 4 + 2];\nstatic tjs_uint32 *testdata1 = testbuff + 0;\nstatic tjs_uint32 *testdata2 = testdata1 + 256 * 256;\nstatic tjs_uint32 *testdest = testdata2 + 256 * 256;\nstatic tjs_uint8 *testrule = new tjs_uint8[256 * 256];\nstatic tjs_uint32 *testtable = new tjs_uint32[256];\nstatic tjs_uint32 testcolor = 0xFFFFFFFF;\nstatic tTVPOGLTexture2D_mutatble *texdata[3];\nstatic tTVPOGLTexture2D_mutatble *texdest = NULL;\n\nstatic tjs_uint32 *testred = new tjs_uint32[256 * 256];\nstatic tjs_uint32 *testblue = new tjs_uint32[256 * 256];\nstatic tTVPOGLTexture2D_mutatble *texred = nullptr;\nstatic tTVPOGLTexture2D_mutatble *texblue = nullptr;\nstatic void ResetTestData() {\n\tif (!texdest) {\n\t\ttexdest = new tTVPOGLTexture2D_mutatble(nullptr, 0, 256, 256, TVPTextureFormat::RGBA, 1, 1);\n\t\tfor (int x = 0; x < 256; ++x) {\n\t\t\tfor (int y = 0; y < 256; ++y) {\n\t\t\t\tstruct clr {\n\t\t\t\t\tunsigned char a;\n\t\t\t\t\tunsigned char r;\n\t\t\t\t\tunsigned char g;\n\t\t\t\t\tunsigned char b;\n\t\t\t\t}   *clr1 = (clr*)(testdata1 + 256 * y + x),\n\t\t\t\t\t*clr2 = (clr*)(testdata2 + 256 * y + x);\n\t\t\t\tclr1->a = 255 - x; clr2->a = 255 - y;\n\t\t\t\tclr1->r = x; clr2->r = y;\n\t\t\t\tclr1->g = y; clr2->g = 255 - x;\n\t\t\t\tclr1->b = 255 - y; clr2->b = x;\n\t\t\t\ttestrule[256 * y + x] = (x + y) / 2;\n\t\t\t\ttestred[256 * y + x] = 0x0000FF | (x << 24);\n\t\t\t\ttestblue[256 * y + x] = 0xFF0000 | (y << 24);\n\t\t\t}\n\t\t}\n\t\ttexdata[2] = new tTVPOGLTexture2D_mutatble(testrule, 256, 256, 256, TVPTextureFormat::Gray, 1, 1);\n\t\ttexdata[0] = new tTVPOGLTexture2D_mutatble(testdata1, 256 * 4, 256, 256, TVPTextureFormat::RGBA, 1, 1);\n\t\ttexdata[1] = new tTVPOGLTexture2D_mutatble(testdata2, 256 * 4, 256, 256, TVPTextureFormat::RGBA, 1, 1);\n\t\ttexred = new tTVPOGLTexture2D_mutatble(testred, 256 * 4, 256, 256, TVPTextureFormat::RGBA, 1, 1);\n\t\ttexblue = new tTVPOGLTexture2D_mutatble(testblue, 256 * 4, 256, 256, TVPTextureFormat::RGBA, 1, 1);\n\t}\n\tmemcpy(testdest, testdata2, 256 * 256 * 4);\n\ttexdest->Update(testdata2, TVPTextureFormat::RGBA, 256 * 4, tTVPRect(0, 0, 256, 256));\n}\n\nstatic void CheckTestData(const char * funcname) {\n\tconst unsigned char *linetex = (const unsigned char *)texdest->GetScanLineForRead(0);\n\tunsigned char *linecmp = (unsigned char *)testdest;\n\tfor (int i = 0; i < 256 * 256; ++i) {\n\t\tint a1 = linetex[i * 4 + 3], a2 = linecmp[i * 4 + 3];\n\t\tif (std::abs(a1 - a2) > 3 || (a1 > 3 && (\n\t\t\t((std::abs(linetex[i * 4] - linecmp[i * 4]) * a1) >> 8) > 3 ||\n\t\t\t((std::abs(linetex[i * 4 + 1] - linecmp[i * 4 + 1]) * a1) >> 8) > 3 ||\n\t\t\t((std::abs(linetex[i * 4 + 2] - linecmp[i * 4 + 2]) * a1) >> 8) > 3))\n\t\t\t) {\n\t\t\tcocos2d::log(\"%s check fail\", funcname);\n\t\t\tfor (int j = 0; j < 256 * 256 * 4; ++j) {\n\t\t\t\tlinecmp[j] = std::abs(linetex[j] - linecmp[j]);\n\t\t\t}\n\t\t\tassert(false);\n\t\t\treturn;\n\t\t}\n\t}\n\tcocos2d::log(\"%s pass\", funcname);\n}\n\nstatic void _TEST_IGNORE_ALPHA() {\n\tconst unsigned char *linetex = (const unsigned char *)texdest->GetScanLineForRead(0);\n\tunsigned char *linecmp = (unsigned char *)testdest;\n\tfor (int i = 0; i < 256 * 256; ++i) {\n\t\tlinecmp[i * 4 + 3] = linetex[i * 4 + 3];\n\t}\n}\n\nstatic void _TEST_SHADER(const char *_method, iTVPRenderManager* _this,\n\tconst std::function<void(std::vector<tRenderTexRectArray::Element> &, tTVPOGLRenderMethod*)> &fcall,\n\tbool ignoreAlpha) {\n\ttTVPOGLRenderMethod_Script *method = (tTVPOGLRenderMethod_Script *)_this->GetRenderMethod(_method);\n\tint id_opa = method->EnumParameterID(\"opacity\"), id_clr = method->EnumParameterID(\"color\");\n\tif (id_opa >= 0) method->SetParameterOpa(id_opa, TEST_SHADER_OPA);\n\tif (id_clr >= 0) method->SetParameterColor4B(id_clr, TEST_SHADER_COLOR);\n\tResetTestData();\n\ttTVPRect rc(0, 0, 256, 256);\n\tstd::vector<tRenderTexRectArray::Element> src_tex;\n\tfor (int i = 0; i < method->GetValidTex(); ++i)\n\t\tsrc_tex.emplace_back(texdata[i], rc);\n\tfcall(src_tex, method);\n\t_this->OperateRect(method, texdest, nullptr, rc, src_tex.empty() ? tRenderTexRectArray() : tRenderTexRectArray(&src_tex[0], src_tex.size()));\n\tif (ignoreAlpha) _TEST_IGNORE_ALPHA();\n\tCheckTestData(_method);\n}"
  },
  {
    "path": "src/core/visual/ogl/astcrt.cpp",
    "content": "#include \"astcrt.h\"\n#include <cmath>\n#include <algorithm>\n#include <assert.h>\n#define DCHECK(x) assert(x)\n\nnamespace ASTCRealTimeCodec {\n\nconst size_t BLOCK_WIDTH = 4;\nconst size_t BLOCK_HEIGHT = 4;\nconst size_t BLOCK_TEXEL_COUNT = BLOCK_WIDTH * BLOCK_HEIGHT;\nconst size_t BLOCK_BYTES = 16;\n\nconst size_t MAXIMUM_ENCODED_WEIGHT_BITS = 96;\nconst size_t MAXIMUM_ENCODED_WEIGHT_BYTES = 12;\n\nconst size_t MAXIMUM_ENCODED_COLOR_ENDPOINT_BYTES = 12;\n\nconst size_t MAX_ENDPOINT_VALUE_COUNT = 18;\n\nconst int APPROX_COLOR_EPSILON = 50;\n\ntemplate <typename T>\nT min(T a, T b) {\n\treturn a <= b ? a : b;\n}\ntemplate <typename T>\nT max(T a, T b) {\n\treturn a >= b ? a : b;\n}\n\ntemplate <typename T>\nT clamp(T a, T b, T x) {\n\tif (x < a) {\n\t\treturn a;\n\t}\n\n\tif (x > b) {\n\t\treturn b;\n\t}\n\n\treturn x;\n}\n\ninline bool approx_equal(float x, float y, float epsilon) {\n\treturn fabs(x - y) < epsilon;\n}\n\ntemplate <typename T>\nunion vec3_t {\npublic:\n\tvec3_t() {}\n\tvec3_t(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}\n\n\tstruct {\n\t\tT x, y, z;\n\t};\n\tstruct {\n\t\tT r, g, b;\n\t};\n\tT components[3];\n};\n\ntypedef vec3_t<float> vec3f_t;\ntypedef vec3_t<int> vec3i_t;\n\ntemplate <typename T>\nvec3_t<T> operator+(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = a.x + b.x;\n\tresult.y = a.y + b.y;\n\tresult.z = a.z + b.z;\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> operator-(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = a.x - b.x;\n\tresult.y = a.y - b.y;\n\tresult.z = a.z - b.z;\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> operator*(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = a.x * b.x;\n\tresult.y = a.y * b.y;\n\tresult.z = a.z * b.z;\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> operator*(vec3_t<T> a, T b) {\n\tvec3_t<T> result;\n\tresult.x = a.x * b;\n\tresult.y = a.y * b;\n\tresult.z = a.z * b;\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> operator/(vec3_t<T> a, T b) {\n\tvec3_t<T> result;\n\tresult.x = a.x / b;\n\tresult.y = a.y / b;\n\tresult.z = a.z / b;\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> operator/(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = a.x / b.x;\n\tresult.y = a.y / b.y;\n\tresult.z = a.z / b.z;\n\treturn result;\n}\n\ntemplate <typename T>\nbool operator==(vec3_t<T> a, vec3_t<T> b) {\n\treturn a.x == b.x && a.y == b.y && a.z == b.z;\n}\n\ntemplate <typename T>\nbool operator!=(vec3_t<T> a, vec3_t<T> b) {\n\treturn a.x != b.x || a.y != b.y || a.z != b.z;\n}\n\ntemplate <typename T>\nT dot(vec3_t<T> a, vec3_t<T> b) {\n\treturn a.x * b.x + a.y * b.y + a.z * b.z;\n}\n\ntemplate <typename T>\nT quadrance(vec3_t<T> a) {\n\treturn dot(a, a);\n}\n\ntemplate <typename T>\nT norm(vec3_t<T> a) {\n\treturn static_cast<T>(sqrt(quadrance(a)));\n}\n\ntemplate <typename T>\nT distance(vec3_t<T> a, vec3_t<T> b) {\n\treturn norm(a - b);\n}\n\ntemplate <typename T>\nT qd(vec3_t<T> a, vec3_t<T> b) {\n\treturn quadrance(a - b);\n}\n\ntemplate <typename T>\nvec3_t<T> signorm(vec3_t<T> a) {\n\tT x = norm(a);\n\tDCHECK(x != 0.0);\n\treturn a / x;\n}\n\ntemplate <typename T>\nvec3_t<T> min(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = min(a.x, b.x);\n\tresult.y = min(a.y, b.y);\n\tresult.z = min(a.z, b.z);\n\treturn result;\n}\n\ntemplate <typename T>\nvec3_t<T> max(vec3_t<T> a, vec3_t<T> b) {\n\tvec3_t<T> result;\n\tresult.x = max(a.x, b.x);\n\tresult.y = max(a.y, b.y);\n\tresult.z = max(a.z, b.z);\n\treturn result;\n}\n\ntemplate <typename T>\nT qd_to_line(vec3_t<T> m, vec3_t<T> k, T kk, vec3_t<T> p) {\n\tT t = dot(p - m, k) / kk;\n\tvec3_t<T> q = k * t + m;\n\treturn qd(p, q);\n}\n\nunion unorm8_t {\n\tstruct RgbaColorType {\n\t\tuint8_t b, g, r, a;\n\t} channels;\n\tuint8_t components[4];\n\tuint32_t bits;\n};\n\nunion unorm16_t {\n\tstruct RgbaColorType {\n\t\tuint16_t b, g, r, a;\n\t} channels;\n\tuint16_t components[4];\n\tuint64_t bits;\n};\n\ninline bool is_greyscale(vec3i_t color) {\n\t// integer equality is transitive\n\treturn color.r == color.g && color.g == color.b;\n}\n\ninline int luminance(vec3i_t color) {\n\treturn (color.r + color.g + color.b) / 3;\n}\n\ninline bool approx_equal(vec3i_t a, vec3i_t b) {\n\treturn quadrance(a - b) <= APPROX_COLOR_EPSILON;\n}\n\ninline vec3i_t clamp_rgb(vec3i_t color) {\n\tvec3i_t result;\n\tresult.r = clamp(0, 255, color.r);\n\tresult.g = clamp(0, 255, color.g);\n\tresult.b = clamp(0, 255, color.b);\n\treturn result;\n}\n\ninline vec3f_t clamp_rgb(vec3f_t color) {\n\tvec3f_t result;\n\tresult.r = clamp(0.0f, 255.0f, color.r);\n\tresult.g = clamp(0.0f, 255.0f, color.g);\n\tresult.b = clamp(0.0f, 255.0f, color.b);\n\treturn result;\n}\n\ninline bool is_rgb(float color) {\n\treturn color >= 0.0f && color <= 255.0f;\n}\n\ninline bool is_rgb(vec3f_t color) {\n\treturn is_rgb(color.r) && is_rgb(color.g) && is_rgb(color.b);\n}\n\ninline vec3i_t floor(vec3f_t color) {\n\tvec3i_t result;\n\tresult.r = static_cast<int>(std::floor(color.r));\n\tresult.g = static_cast<int>(std::floor(color.g));\n\tresult.b = static_cast<int>(std::floor(color.b));\n\treturn result;\n}\n\ninline vec3i_t round(vec3f_t color) {\n\tvec3i_t result;\n\tresult.r = static_cast<int>(roundf(color.r));\n\tresult.g = static_cast<int>(roundf(color.g));\n\tresult.b = static_cast<int>(roundf(color.b));\n\treturn result;\n}\n\ninline vec3i_t to_vec3i(unorm8_t color) {\n\tvec3i_t result;\n\tresult.r = color.channels.r;\n\tresult.g = color.channels.g;\n\tresult.b = color.channels.b;\n\treturn result;\n}\n\ninline vec3i_t to_vec3i(vec3f_t color) {\n\tvec3i_t result;\n\tresult.r = static_cast<int>(color.r);\n\tresult.g = static_cast<int>(color.g);\n\tresult.b = static_cast<int>(color.b);\n\treturn result;\n}\n\ninline vec3f_t to_vec3f(unorm8_t color) {\n\tvec3f_t result;\n\tresult.r = color.channels.r;\n\tresult.g = color.channels.g;\n\tresult.b = color.channels.b;\n\treturn result;\n}\n\ninline vec3f_t to_vec3f(vec3i_t color) {\n\tvec3f_t result;\n\tresult.r = static_cast<float>(color.r);\n\tresult.g = static_cast<float>(color.g);\n\tresult.b = static_cast<float>(color.b);\n\treturn result;\n}\n\ninline unorm8_t to_unorm8(vec3i_t color) {\n\tunorm8_t result;\n\tresult.channels.r = static_cast<uint8_t>(color.r);\n\tresult.channels.g = static_cast<uint8_t>(color.g);\n\tresult.channels.b = static_cast<uint8_t>(color.b);\n\tresult.channels.a = 255;\n\treturn result;\n}\n\ninline unorm16_t unorm8_to_unorm16(unorm8_t c8) {\n\t// (x / 255) * (2^16-1) = x * 65535 / 255 = x * 257\n\tunorm16_t result;\n\tresult.channels.r = static_cast<uint16_t>(c8.channels.r * 257);\n\tresult.channels.g = static_cast<uint16_t>(c8.channels.g * 257);\n\tresult.channels.b = static_cast<uint16_t>(c8.channels.b * 257);\n\tresult.channels.a = static_cast<uint16_t>(c8.channels.a * 257);\n\treturn result;\n}\n\ninline bool getbit(size_t number, size_t n) {\n\treturn (number >> n) & 1;\n}\n\ninline uint8_t getbits(uint8_t number, uint8_t msb, uint8_t lsb) {\n\tint count = msb - lsb + 1;\n\treturn static_cast<uint8_t>((number >> lsb) & ((1 << count) - 1));\n}\n\ninline size_t getbits(size_t number, size_t msb, size_t lsb) {\n\tsize_t count = msb - lsb + 1;\n\treturn (number >> lsb) & (static_cast<size_t>(1 << count) - 1);\n}\n\ninline void orbits8_ptr(uint8_t* ptr,\n\tsize_t bitoffset,\n\tsize_t number,\n\tsize_t bitcount) {\n\tDCHECK(bitcount <= 8);\n\tDCHECK((number >> bitcount) == 0);\n\n\tsize_t index = bitoffset / 8;\n\tsize_t shift = bitoffset % 8;\n\n\t// Depending on the offset we might have to consider two bytes when\n\t// writing, for instance if we are writing 8 bits and the offset is 4,\n\t// then we have to write 4 bits to the first byte (ptr[index]) and 4 bits\n\t// to the second byte (ptr[index+1]).\n\t//\n\t// FIXME: Writing to the last byte when the number of bytes is a multiple of 2\n\t// will write past the allocated memory.\n\n\tuint8_t* p = ptr + index;\n\tsize_t mask = number << shift;\n\n\tDCHECK((p[0] & mask) == 0);\n\tDCHECK((p[1] & (mask >> 8)) == 0);\n\n\tp[0] |= static_cast<uint8_t>(mask & 0xFF);\n\tp[1] |= static_cast<uint8_t>((mask >> 8) & 0xFF);\n}\n\ninline void orbits16_ptr(uint8_t* ptr,\n\tsize_t bitoffset,\n\tsize_t number,\n\tsize_t bitcount) {\n\tDCHECK(bitcount > 8 && bitcount <= 16);\n\n\tsize_t index = bitoffset / 8;\n\tsize_t shift = bitoffset % 8;\n\n\tuint8_t* p = ptr + index;\n\tsize_t mask = number << shift;\n\n\tp[0] |= static_cast<uint8_t>(mask & 0xFF);\n\tp[1] |= static_cast<uint8_t>((mask >> 8) & 0xFF);\n\tp[2] |= static_cast<uint8_t>((mask >> 16) & 0xFF);\n\tp[3] |= static_cast<uint8_t>((mask >> 24) & 0xFF);\n}\n\ninline uint16_t getbytes2(const uint8_t* ptr, size_t byteoffset) {\n\tconst uint8_t* p = ptr + byteoffset;\n\treturn static_cast<uint16_t>((p[1] << 8) | p[0]);\n}\n\ninline void setbytes2(uint8_t* ptr, size_t byteoffset, uint16_t bytes) {\n\tptr[byteoffset + 0] = static_cast<uint8_t>(bytes & 0xFF);\n\tptr[byteoffset + 1] = static_cast<uint8_t>((bytes >> 8) & 0xFF);\n}\n\ninline void split_high_low(uint8_t n, size_t i, uint8_t& high, uint8_t& low) {\n\tDCHECK(i < 8);\n\n\tuint8_t low_mask = static_cast<uint8_t>((1 << i) - 1);\n\n\tlow = n & low_mask;\n\thigh = static_cast<uint8_t>(n >> i);\n}\n\nclass bitwriter {\npublic:\n\texplicit bitwriter(uint8_t* ptr) : ptr_(ptr), bitoffset_(0) {\n\t\t// assumption that all bits in ptr are zero after the offset\n\n\t\t// writing beyound the bounds of the allocated memory is undefined\n\t\t// behaviour\n\t}\n\n\t// Specialized function that can't write more than 8 bits.\n\tvoid write8(uint8_t number, size_t bitcount) {\n\t\torbits8_ptr(ptr_, bitoffset_, number, bitcount);\n\n\t\tbitoffset_ += bitcount;\n\t}\n\n\tsize_t offset() const { return bitoffset_; }\n\nprivate:\n\tuint8_t* ptr_;\n\tsize_t bitoffset_;  // in bits\n};\n\nconst uint8_t bit_reverse_table[256] = {\n\t0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,\n\t0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,\n\t0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,\n\t0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,\n\t0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,\n\t0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,\n\t0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,\n\t0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,\n\t0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,\n\t0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,\n\t0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,\n\t0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,\n\t0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,\n\t0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,\n\t0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,\n\t0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,\n\t0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,\n\t0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,\n\t0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,\n\t0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,\n\t0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,\n\t0x3F, 0xBF, 0x7F, 0xFF };\n\n/**\n* Reverse a byte, total function.\n*/\ninline uint8_t reverse_byte(uint8_t number) {\n\treturn bit_reverse_table[number];\n}\n\n/**\n* Reverse a sequence of bytes.\n*\n* Assumes that the bits written to (using bitwise or) are zero and that they\n* will not clash with bits already written to target sequence. That is it is\n* possible to write to a non-zero byte as long as the bits that are actually\n* written to are zero.\n*/\ninline void reverse_bytes(const uint8_t* source,\n\tsize_t bytecount,\n\tuint8_t* target) {\n\tfor (int i = 0; i < static_cast<int>(bytecount); ++i) {\n\t\tDCHECK((reverse_byte(source[i]) & target[-i]) == 0);\n\t\ttarget[-i] = target[-i] | reverse_byte(source[i]);\n\t}\n}\n\ninline void copy_bytes(const uint8_t* source,\n\tsize_t bytecount,\n\tuint8_t* target,\n\tsize_t bitoffset) {\n\tfor (size_t i = 0; i < bytecount; ++i) {\n\t\torbits8_ptr(target, bitoffset + i * 8, source[i], 8);\n\t}\n}\n\nstruct PhysicalBlock {\n\tuint8_t data[BLOCK_BYTES];\n};\n\ninline void void_extent_to_physical(unorm16_t color, PhysicalBlock* pb) {\n\tpb->data[0] = 0xFC;\n\tpb->data[1] = 0xFD;\n\tpb->data[2] = 0xFF;\n\tpb->data[3] = 0xFF;\n\tpb->data[4] = 0xFF;\n\tpb->data[5] = 0xFF;\n\tpb->data[6] = 0xFF;\n\tpb->data[7] = 0xFF;\n\n\tsetbytes2(pb->data, 8, color.channels.r);\n\tsetbytes2(pb->data, 10, color.channels.g);\n\tsetbytes2(pb->data, 12, color.channels.b);\n\tsetbytes2(pb->data, 14, color.channels.a);\n}\n\nenum color_endpoint_mode_t {\n\tCEM_LDR_LUMINANCE_DIRECT = 0,\n\tCEM_LDR_LUMINANCE_BASE_OFFSET = 1,\n\tCEM_HDR_LUMINANCE_LARGE_RANGE = 2,\n\tCEM_HDR_LUMINANCE_SMALL_RANGE = 3,\n\tCEM_LDR_LUMINANCE_ALPHA_DIRECT = 4,\n\tCEM_LDR_LUMINANCE_ALPHA_BASE_OFFSET = 5,\n\tCEM_LDR_RGB_BASE_SCALE = 6,\n\tCEM_HDR_RGB_BASE_SCALE = 7,\n\tCEM_LDR_RGB_DIRECT = 8,\n\tCEM_LDR_RGB_BASE_OFFSET = 9,\n\tCEM_LDR_RGB_BASE_SCALE_PLUS_TWO_ALPHA = 10,\n\tCEM_HDR_RGB = 11,\n\tCEM_LDR_RGBA_DIRECT = 12,\n\tCEM_LDR_RGBA_BASE_OFFSET = 13,\n\tCEM_HDR_RGB_LDR_ALPHA = 14,\n\tCEM_HDR_RGB_HDR_ALPHA = 15,\n\tCEM_MAX = 16\n};\n\n/**\n* Define normalized (starting at zero) numeric ranges that can be represented\n* with 8 bits or less.\n*/\nenum range_t {\n\tRANGE_2,\n\tRANGE_3,\n\tRANGE_4,\n\tRANGE_5,\n\tRANGE_6,\n\tRANGE_8,\n\tRANGE_10,\n\tRANGE_12,\n\tRANGE_16,\n\tRANGE_20,\n\tRANGE_24,\n\tRANGE_32,\n\tRANGE_40,\n\tRANGE_48,\n\tRANGE_64,\n\tRANGE_80,\n\tRANGE_96,\n\tRANGE_128,\n\tRANGE_160,\n\tRANGE_192,\n\tRANGE_256,\n\tRANGE_MAX\n};\n\n/**\n* Table of maximum value for each range, minimum is always zero.\n*/\nconst uint8_t range_max_table[RANGE_MAX] = {\n\t1,  2,  3,  4,   5,   7,   9,\n\t11, 15, 19, 23,  31,  39,  47,\n\t63, 79, 95, 127, 159, 191, 255 };\n\n\n/**\n* Table that describes the number of trits or quints along with bits required\n* for storing each range.\n*/\nconst uint8_t bits_trits_quints_table[RANGE_MAX][3] = {\n\t{ 1, 0, 0 },  // RANGE_2\n\t{ 0, 1, 0 },  // RANGE_3\n\t{ 2, 0, 0 },  // RANGE_4\n\t{ 0, 0, 1 },  // RANGE_5\n\t{ 1, 1, 0 },  // RANGE_6\n\t{ 3, 0, 0 },  // RANGE_8\n\t{ 1, 0, 1 },  // RANGE_10\n\t{ 2, 1, 0 },  // RANGE_12\n\t{ 4, 0, 0 },  // RANGE_16\n\t{ 2, 0, 1 },  // RANGE_20\n\t{ 3, 1, 0 },  // RANGE_24\n\t{ 5, 0, 0 },  // RANGE_32\n\t{ 3, 0, 1 },  // RANGE_40\n\t{ 4, 1, 0 },  // RANGE_48\n\t{ 6, 0, 0 },  // RANGE_64\n\t{ 4, 0, 1 },  // RANGE_80\n\t{ 5, 1, 0 },  // RANGE_96\n\t{ 7, 0, 0 },  // RANGE_128\n\t{ 5, 0, 1 },  // RANGE_160\n\t{ 6, 1, 0 },  // RANGE_192\n\t{ 8, 0, 0 }   // RANGE_256\n};\n\nconst uint8_t integer_from_trits[3][3][3][3][3] = {\n\t{ { { { 0, 1, 2 },{ 4, 5, 6 },{ 8, 9, 10 } },\n\t{ { 16, 17, 18 },{ 20, 21, 22 },{ 24, 25, 26 } },\n\t{ { 3, 7, 15 },{ 19, 23, 27 },{ 12, 13, 14 } } },\n\t{ { { 32, 33, 34 },{ 36, 37, 38 },{ 40, 41, 42 } },\n\t{ { 48, 49, 50 },{ 52, 53, 54 },{ 56, 57, 58 } },\n\t{ { 35, 39, 47 },{ 51, 55, 59 },{ 44, 45, 46 } } },\n\t{ { { 64, 65, 66 },{ 68, 69, 70 },{ 72, 73, 74 } },\n\t{ { 80, 81, 82 },{ 84, 85, 86 },{ 88, 89, 90 } },\n\t{ { 67, 71, 79 },{ 83, 87, 91 },{ 76, 77, 78 } } } },\n\t{ { { { 128, 129, 130 },{ 132, 133, 134 },{ 136, 137, 138 } },\n\t{ { 144, 145, 146 },{ 148, 149, 150 },{ 152, 153, 154 } },\n\t{ { 131, 135, 143 },{ 147, 151, 155 },{ 140, 141, 142 } } },\n\t{ { { 160, 161, 162 },{ 164, 165, 166 },{ 168, 169, 170 } },\n\t{ { 176, 177, 178 },{ 180, 181, 182 },{ 184, 185, 186 } },\n\t{ { 163, 167, 175 },{ 179, 183, 187 },{ 172, 173, 174 } } },\n\t{ { { 192, 193, 194 },{ 196, 197, 198 },{ 200, 201, 202 } },\n\t{ { 208, 209, 210 },{ 212, 213, 214 },{ 216, 217, 218 } },\n\t{ { 195, 199, 207 },{ 211, 215, 219 },{ 204, 205, 206 } } } },\n\t{ { { { 96, 97, 98 },{ 100, 101, 102 },{ 104, 105, 106 } },\n\t{ { 112, 113, 114 },{ 116, 117, 118 },{ 120, 121, 122 } },\n\t{ { 99, 103, 111 },{ 115, 119, 123 },{ 108, 109, 110 } } },\n\t{ { { 224, 225, 226 },{ 228, 229, 230 },{ 232, 233, 234 } },\n\t{ { 240, 241, 242 },{ 244, 245, 246 },{ 248, 249, 250 } },\n\t{ { 227, 231, 239 },{ 243, 247, 251 },{ 236, 237, 238 } } },\n\t{ { { 28, 29, 30 },{ 60, 61, 62 },{ 92, 93, 94 } },\n\t{ { 156, 157, 158 },{ 188, 189, 190 },{ 220, 221, 222 } },\n\t{ { 31, 63, 127 },{ 159, 191, 255 },{ 252, 253, 254 } } } } };\n\n/**\n* Encode a group of 5 numbers using trits and bits.\n*/\ninline void encode_trits(size_t bits,\n\tuint8_t b0,\n\tuint8_t b1,\n\tuint8_t b2,\n\tuint8_t b3,\n\tuint8_t b4,\n\tbitwriter& writer) {\n\tuint8_t t0, t1, t2, t3, t4;\n\tuint8_t m0, m1, m2, m3, m4;\n\n\tsplit_high_low(b0, bits, t0, m0);\n\tsplit_high_low(b1, bits, t1, m1);\n\tsplit_high_low(b2, bits, t2, m2);\n\tsplit_high_low(b3, bits, t3, m3);\n\tsplit_high_low(b4, bits, t4, m4);\n\n\tDCHECK(t0 < 3);\n\tDCHECK(t1 < 3);\n\tDCHECK(t2 < 3);\n\tDCHECK(t3 < 3);\n\tDCHECK(t4 < 3);\n\n\tuint8_t packed = integer_from_trits[t4][t3][t2][t1][t0];\n\n\twriter.write8(m0, bits);\n\twriter.write8(getbits(packed, 1, 0), 2);\n\twriter.write8(m1, bits);\n\twriter.write8(getbits(packed, 3, 2), 2);\n\twriter.write8(m2, bits);\n\twriter.write8(getbits(packed, 4, 4), 1);\n\twriter.write8(m3, bits);\n\twriter.write8(getbits(packed, 6, 5), 2);\n\twriter.write8(m4, bits);\n\twriter.write8(getbits(packed, 7, 7), 1);\n}\n\nconst uint8_t integer_from_quints[5][5][5] = \n{ { { 0, 1, 2, 3, 4 },\n\t{ 8, 9, 10, 11, 12 },\n\t{ 16, 17, 18, 19, 20 },\n\t{ 24, 25, 26, 27, 28 },\n\t{ 5, 13, 21, 29, 6 } },\n\t{ { 32, 33, 34, 35, 36 },\n\t{ 40, 41, 42, 43, 44 },\n\t{ 48, 49, 50, 51, 52 },\n\t{ 56, 57, 58, 59, 60 },\n\t{ 37, 45, 53, 61, 14 } },\n\t{ { 64, 65, 66, 67, 68 },\n\t{ 72, 73, 74, 75, 76 },\n\t{ 80, 81, 82, 83, 84 },\n\t{ 88, 89, 90, 91, 92 },\n\t{ 69, 77, 85, 93, 22 } },\n\t{ { 96, 97, 98, 99, 100 },\n\t{ 104, 105, 106, 107, 108 },\n\t{ 112, 113, 114, 115, 116 },\n\t{ 120, 121, 122, 123, 124 },\n\t{ 101, 109, 117, 125, 30 } },\n\t{ { 102, 103, 70, 71, 38 },\n\t{ 110, 111, 78, 79, 46 },\n\t{ 118, 119, 86, 87, 54 },\n\t{ 126, 127, 94, 95, 62 },\n\t{ 39, 47, 55, 63, 31 } } };\n\n/**\n* Encode a group of 3 numbers using quints and bits.\n*/\ninline void encode_quints(size_t bits,\n\tuint8_t b0,\n\tuint8_t b1,\n\tuint8_t b2,\n\tbitwriter& writer) {\n\tuint8_t q0, q1, q2;\n\tuint8_t m0, m1, m2;\n\n\tsplit_high_low(b0, bits, q0, m0);\n\tsplit_high_low(b1, bits, q1, m1);\n\tsplit_high_low(b2, bits, q2, m2);\n\n\tDCHECK(q0 < 5);\n\tDCHECK(q1 < 5);\n\tDCHECK(q2 < 5);\n\n\tuint8_t packed = integer_from_quints[q2][q1][q0];\n\n\twriter.write8(m0, bits);\n\twriter.write8(getbits(packed, 2, 0), 3);\n\twriter.write8(m1, bits);\n\twriter.write8(getbits(packed, 4, 3), 2);\n\twriter.write8(m2, bits);\n\twriter.write8(getbits(packed, 6, 5), 2);\n}\n\n/**\n* Encode a sequence of numbers using using one trit and a custom number of\n* bits per number.\n*/\ninline void encode_trits(const uint8_t* numbers,\n\tsize_t count,\n\tbitwriter& writer,\n\tsize_t bits) {\n\tfor (size_t i = 0; i < count; i += 5) {\n\t\tuint8_t b0 = numbers[i + 0];\n\t\tuint8_t b1 = i + 1 >= count ? 0 : numbers[i + 1];\n\t\tuint8_t b2 = i + 2 >= count ? 0 : numbers[i + 2];\n\t\tuint8_t b3 = i + 3 >= count ? 0 : numbers[i + 3];\n\t\tuint8_t b4 = i + 4 >= count ? 0 : numbers[i + 4];\n\n\t\tencode_trits(bits, b0, b1, b2, b3, b4, writer);\n\t}\n}\n\n/**\n* Encode a sequence of numbers using one quint and the custom number of bits\n* per number.\n*/\ninline void encode_quints(const uint8_t* numbers,\n\tsize_t count,\n\tbitwriter& writer,\n\tsize_t bits) {\n\tfor (size_t i = 0; i < count; i += 3) {\n\t\tuint8_t b0 = numbers[i + 0];\n\t\tuint8_t b1 = i + 1 >= count ? 0 : numbers[i + 1];\n\t\tuint8_t b2 = i + 2 >= count ? 0 : numbers[i + 2];\n\t\tencode_quints(bits, b0, b1, b2, writer);\n\t}\n}\n\n/**\n* Encode a sequence of numbers using binary representation with the selected\n* bit count.\n*/\ninline void encode_binary(const uint8_t* numbers,\n\tsize_t count,\n\tbitwriter& writer,\n\tsize_t bits) {\n\tDCHECK(count > 0);\n\tfor (size_t i = 0; i < count; ++i) {\n\t\twriter.write8(numbers[i], bits);\n\t}\n}\n\n/**\n* Encode a sequence of numbers in a specific range using the binary integer\n* sequence encoding. The numbers are assumed to be in the correct range and\n* the memory we are writing to is assumed to be zero-initialized.\n*/\ninline void integer_sequence_encode(const uint8_t* numbers,\n\tsize_t count,\n\trange_t range,\n\tbitwriter writer) {\n#ifndef NDEBUG\n\tfor (size_t i = 0; i < count; ++i) {\n\t\tDCHECK(numbers[i] <= range_max_table[range]);\n\t}\n#endif\n\n\tsize_t bits = bits_trits_quints_table[range][0];\n\tsize_t trits = bits_trits_quints_table[range][1];\n\tsize_t quints = bits_trits_quints_table[range][2];\n\n\tif (trits == 1) {\n\t\tencode_trits(numbers, count, writer, bits);\n\t} else if (quints == 1) {\n\t\tencode_quints(numbers, count, writer, bits);\n\t} else {\n\t\tencode_binary(numbers, count, writer, bits);\n\t}\n}\n\ninline void integer_sequence_encode(const uint8_t* numbers,\n\tsize_t count,\n\trange_t range,\n\tuint8_t* output) {\n\tinteger_sequence_encode(numbers, count, range, bitwriter(output));\n}\n\n/**\n* Compute the number of bits required to store a number of items in a specific\n* range using the binary integer sequence encoding.\n*/\ninline size_t compute_ise_bitcount(size_t items, range_t range) {\n\tsize_t bits = bits_trits_quints_table[range][0];\n\tsize_t trits = bits_trits_quints_table[range][1];\n\tsize_t quints = bits_trits_quints_table[range][2];\n\n\tif (trits) {\n\t\treturn ((8 + 5 * bits) * items + 4) / 5;\n\t}\n\n\tif (quints) {\n\t\treturn ((7 + 3 * bits) * items + 2) / 3;\n\t}\n\n\treturn items * bits;\n}\n\ninline void symbolic_to_physical(\n\tcolor_endpoint_mode_t color_endpoint_mode,\n\trange_t endpoint_quant,\n\trange_t weight_quant,\n\n\tsize_t partition_count,\n\tsize_t partition_index,\n\n\tconst uint8_t endpoint_ise[MAXIMUM_ENCODED_COLOR_ENDPOINT_BYTES],\n\n\t// FIXME: +1 needed here because orbits_8ptr breaks when the offset reaches\n\t// the last byte which always happens if the weight mode is RANGE_32.\n\tconst uint8_t weights_ise[MAXIMUM_ENCODED_WEIGHT_BYTES + 1],\n\n\tPhysicalBlock* pb) {\n\tDCHECK(weight_quant <= RANGE_32);\n\tDCHECK(endpoint_quant < RANGE_MAX);\n\tDCHECK(color_endpoint_mode < CEM_MAX);\n\tDCHECK(partition_count == 1 || partition_index < 1024);\n\tDCHECK(partition_count >= 1 && partition_count <= 4);\n\tDCHECK(compute_ise_bitcount(BLOCK_TEXEL_COUNT, weight_quant) <\n\t\tMAXIMUM_ENCODED_WEIGHT_BITS);\n\n\tsize_t n = BLOCK_WIDTH;\n\tsize_t m = BLOCK_HEIGHT;\n\n\tstatic const bool h_table[RANGE_32 + 1] = {\n\t\t0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };\n\n\tstatic const uint8_t r_table[RANGE_32 + 1] = {\n\t\t0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };\n\n\tbool h = h_table[weight_quant];\n\tsize_t r = r_table[weight_quant];\n\n\t// Use the first row of Table 11 in the ASTC specification. Beware that\n\t// this has to be changed if another block-size is used.\n\tsize_t a = m - 2;\n\tsize_t b = n - 4;\n\n\tbool d = 0;  // TODO: dual plane\n\n\tbool multi_part = partition_count > 1;\n\n\tsize_t part_value = partition_count - 1;\n\tsize_t part_index = multi_part ? partition_index : 0;\n\n\tsize_t cem_offset = multi_part ? 23 : 13;\n\tsize_t ced_offset = multi_part ? 29 : 17;\n\n\tsize_t cem_bits = multi_part ? 6 : 4;\n\tsize_t cem = color_endpoint_mode;\n\tcem = multi_part ? cem << 2 : cem;\n\n\t// Block mode\n\torbits8_ptr(pb->data, 0, getbit(r, 1), 1);\n\torbits8_ptr(pb->data, 1, getbit(r, 2), 1);\n\torbits8_ptr(pb->data, 2, 0, 1);\n\torbits8_ptr(pb->data, 3, 0, 1);\n\torbits8_ptr(pb->data, 4, getbit(r, 0), 1);\n\torbits8_ptr(pb->data, 5, a, 2);\n\torbits8_ptr(pb->data, 7, b, 2);\n\torbits8_ptr(pb->data, 9, h, 1);\n\torbits8_ptr(pb->data, 10, d, 1);\n\n\t// Partitions\n\torbits8_ptr(pb->data, 11, part_value, 2);\n\torbits16_ptr(pb->data, 13, part_index, 10);\n\n\t// CEM\n\torbits8_ptr(pb->data, cem_offset, cem, cem_bits);\n\n\tcopy_bytes(\n\t\tendpoint_ise, MAXIMUM_ENCODED_COLOR_ENDPOINT_BYTES, pb->data, ced_offset);\n\n\treverse_bytes(weights_ise, MAXIMUM_ENCODED_WEIGHT_BYTES, pb->data + 15);\n}\n\nconst int8_t color_endpoint_range_table[2][12][16] = {\n\t{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 17, 17, 17, 17 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 16, 16, 16 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 13, 13, 13, 13 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 16, 16, 16, 16, 11, 11, 11, 11 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 14, 14, 14, 14, 10, 10, 10, 10 },\n\t{ 20, 20, 20, 20, 19, 19, 19, 19, 11, 11, 11, 11, 7, 7, 7, 7 } },\n\t{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 14, 14, 14, 14, 9, 9, 9, 9 },\n\t{ 20, 20, 20, 20, 20, 20, 20, 20, 12, 12, 12, 12, 8, 8, 8, 8 },\n\t{ 20, 20, 20, 20, 19, 19, 19, 19, 11, 11, 11, 11, 7, 7, 7, 7 },\n\t{ 20, 20, 20, 20, 17, 17, 17, 17, 10, 10, 10, 10, 6, 6, 6, 6 },\n\t{ 20, 20, 20, 20, 15, 15, 15, 15, 8, 8, 8, 8, 5, 5, 5, 5 },\n\t{ 20, 20, 20, 20, 13, 13, 13, 13, 7, 7, 7, 7, 4, 4, 4, 4 },\n\t{ 20, 20, 20, 20, 11, 11, 11, 11, 6, 6, 6, 6, 3, 3, 3, 3 },\n\t{ 20, 20, 20, 20, 9, 9, 9, 9, 4, 4, 4, 4, 2, 2, 2, 2 },\n\t{ 17, 17, 17, 17, 7, 7, 7, 7, 3, 3, 3, 3, 1, 1, 1, 1 },\n\t{ 14, 14, 14, 14, 5, 5, 5, 5, 2, 2, 2, 2, 0, 0, 0, 0 },\n\t{ 10, 10, 10, 10, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0 } },\n};\n\n// FIXME: This is copied from ARM-code\nconst uint8_t color_unquantize_table[21][256] = {\n\t{ 0, 255 },\n\t{ 0, 128, 255 },\n\t{ 0, 85, 170, 255 },\n\t{ 0, 64, 128, 192, 255 },\n\t{ 0, 255, 51, 204, 102, 153 },\n\t{ 0, 36, 73, 109, 146, 182, 219, 255 },\n\t{ 0, 255, 28, 227, 56, 199, 84, 171, 113, 142 },\n\t{ 0, 255, 69, 186, 23, 232, 92, 163, 46, 209, 116, 139 },\n\t{ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 },\n\t{ 0,  255, 67, 188, 13,  242, 80, 175, 27,  228,\n\t94, 161, 40, 215, 107, 148, 54, 201, 121, 134 },\n\t{ 0,  255, 33,  222, 66, 189, 99, 156, 11, 244, 44,  211,\n\t77, 178, 110, 145, 22, 233, 55, 200, 88, 167, 121, 134 },\n\t{ 0,   8,   16,  24,  33,  41,  49,  57,  66,  74,  82,\n\t90,  99,  107, 115, 123, 132, 140, 148, 156, 165, 173,\n\t181, 189, 198, 206, 214, 222, 231, 239, 247, 255 },\n\t{ 0,   255, 32,  223, 65, 190, 97, 158, 6,   249, 39,  216, 71, 184,\n\t104, 151, 13,  242, 45, 210, 78, 177, 110, 145, 19,  236, 52, 203,\n\t84,  171, 117, 138, 26, 229, 58, 197, 91,  164, 123, 132 },\n\t{ 0,  255, 16, 239, 32, 223, 48, 207, 65, 190, 81, 174, 97,  158, 113, 142,\n\t5,  250, 21, 234, 38, 217, 54, 201, 70, 185, 86, 169, 103, 152, 119, 136,\n\t11, 244, 27, 228, 43, 212, 59, 196, 76, 179, 92, 163, 108, 147, 124, 131 },\n\t{ 0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,\n\t52,  56,  60,  65,  69,  73,  77,  81,  85,  89,  93,  97,  101,\n\t105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154,\n\t158, 162, 166, 170, 174, 178, 182, 186, 190, 195, 199, 203, 207,\n\t211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255 },\n\t{ 0,  255, 16, 239, 32, 223, 48, 207, 64, 191, 80, 175, 96,  159, 112, 143,\n\t3,  252, 19, 236, 35, 220, 51, 204, 67, 188, 83, 172, 100, 155, 116, 139,\n\t6,  249, 22, 233, 38, 217, 54, 201, 71, 184, 87, 168, 103, 152, 119, 136,\n\t9,  246, 25, 230, 42, 213, 58, 197, 74, 181, 90, 165, 106, 149, 122, 133,\n\t13, 242, 29, 226, 45, 210, 61, 194, 77, 178, 93, 162, 109, 146, 125, 130 },\n\t{ 0,   255, 8,   247, 16,  239, 24,  231, 32,  223, 40,  215, 48,  207,\n\t56,  199, 64,  191, 72,  183, 80,  175, 88,  167, 96,  159, 104, 151,\n\t112, 143, 120, 135, 2,   253, 10,  245, 18,  237, 26,  229, 35,  220,\n\t43,  212, 51,  204, 59,  196, 67,  188, 75,  180, 83,  172, 91,  164,\n\t99,  156, 107, 148, 115, 140, 123, 132, 5,   250, 13,  242, 21,  234,\n\t29,  226, 37,  218, 45,  210, 53,  202, 61,  194, 70,  185, 78,  177,\n\t86,  169, 94,  161, 102, 153, 110, 145, 118, 137, 126, 129 },\n\t{ 0,   2,   4,   6,   8,   10,  12,  14,  16,  18,  20,  22,  24,  26,  28,\n\t30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,\n\t60,  62,  64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,\n\t90,  92,  94,  96,  98,  100, 102, 104, 106, 108, 110, 112, 114, 116, 118,\n\t120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,\n\t151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,\n\t181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,\n\t211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,\n\t241, 243, 245, 247, 249, 251, 253, 255 },\n\t{ 0,   255, 8,   247, 16,  239, 24,  231, 32,  223, 40,  215, 48,  207, 56,\n\t199, 64,  191, 72,  183, 80,  175, 88,  167, 96,  159, 104, 151, 112, 143,\n\t120, 135, 1,   254, 9,   246, 17,  238, 25,  230, 33,  222, 41,  214, 49,\n\t206, 57,  198, 65,  190, 73,  182, 81,  174, 89,  166, 97,  158, 105, 150,\n\t113, 142, 121, 134, 3,   252, 11,  244, 19,  236, 27,  228, 35,  220, 43,\n\t212, 51,  204, 59,  196, 67,  188, 75,  180, 83,  172, 91,  164, 99,  156,\n\t107, 148, 115, 140, 123, 132, 4,   251, 12,  243, 20,  235, 28,  227, 36,\n\t219, 44,  211, 52,  203, 60,  195, 68,  187, 76,  179, 84,  171, 92,  163,\n\t100, 155, 108, 147, 116, 139, 124, 131, 6,   249, 14,  241, 22,  233, 30,\n\t225, 38,  217, 46,  209, 54,  201, 62,  193, 70,  185, 78,  177, 86,  169,\n\t94,  161, 102, 153, 110, 145, 118, 137, 126, 129 },\n\t{ 0,   255, 4,   251, 8,   247, 12,  243, 16,  239, 20,  235, 24,  231, 28,\n\t227, 32,  223, 36,  219, 40,  215, 44,  211, 48,  207, 52,  203, 56,  199,\n\t60,  195, 64,  191, 68,  187, 72,  183, 76,  179, 80,  175, 84,  171, 88,\n\t167, 92,  163, 96,  159, 100, 155, 104, 151, 108, 147, 112, 143, 116, 139,\n\t120, 135, 124, 131, 1,   254, 5,   250, 9,   246, 13,  242, 17,  238, 21,\n\t234, 25,  230, 29,  226, 33,  222, 37,  218, 41,  214, 45,  210, 49,  206,\n\t53,  202, 57,  198, 61,  194, 65,  190, 69,  186, 73,  182, 77,  178, 81,\n\t174, 85,  170, 89,  166, 93,  162, 97,  158, 101, 154, 105, 150, 109, 146,\n\t113, 142, 117, 138, 121, 134, 125, 130, 2,   253, 6,   249, 10,  245, 14,\n\t241, 18,  237, 22,  233, 26,  229, 30,  225, 34,  221, 38,  217, 42,  213,\n\t46,  209, 50,  205, 54,  201, 58,  197, 62,  193, 66,  189, 70,  185, 74,\n\t181, 78,  177, 82,  173, 86,  169, 90,  165, 94,  161, 98,  157, 102, 153,\n\t106, 149, 110, 145, 114, 141, 118, 137, 122, 133, 126, 129 },\n\t{ 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,\n\t15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,\n\t30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,\n\t45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,\n\t60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,\n\t75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,\n\t90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,\n\t105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\n\t120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,\n\t135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\n\t150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n\t165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,\n\t180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,\n\t195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,\n\t210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,\n\t225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,\n\t240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,\n\t255 } };\n\n// FIXME: This is copied from ARM-code\nconst uint8_t color_quantize_table[21][256] = {\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  1,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,\n\t2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,\n\t7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,\n\t9,  9,  9,  10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14,\n\t14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16,\n\t16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21,\n\t21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25,\n\t25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28,\n\t28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30,\n\t30, 30, 30, 30, 31, 31, 31, 31, 31 },\n\t{ 0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  16, 16, 16, 16, 16, 16, 16, 24, 24,\n\t24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 2,  2,  2,  2,  2,  2,  10, 10,\n\t10, 10, 10, 10, 10, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 34,\n\t34, 34, 34, 34, 34, 4,  4,  4,  4,  4,  4,  4,  12, 12, 12, 12, 12, 12, 20,\n\t20, 20, 20, 20, 20, 20, 28, 28, 28, 28, 28, 28, 36, 36, 36, 36, 36, 36, 36,\n\t6,  6,  6,  6,  6,  6,  14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22, 22, 22,\n\t30, 30, 30, 30, 30, 30, 30, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39,\n\t39, 39, 31, 31, 31, 31, 31, 31, 31, 23, 23, 23, 23, 23, 23, 15, 15, 15, 15,\n\t15, 15, 15, 7,  7,  7,  7,  7,  7,  37, 37, 37, 37, 37, 37, 37, 29, 29, 29,\n\t29, 29, 29, 21, 21, 21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13, 5,  5,  5,\n\t5,  5,  5,  5,  35, 35, 35, 35, 35, 35, 27, 27, 27, 27, 27, 27, 27, 19, 19,\n\t19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 3,  3,  3,  3,  3,  3,  33, 33,\n\t33, 33, 33, 33, 33, 25, 25, 25, 25, 25, 25, 17, 17, 17, 17, 17, 17, 17, 9,\n\t9,  9,  9,  9,  9,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 2,  2,  2,  2,  2,\n\t18, 18, 18, 18, 18, 18, 34, 34, 34, 34, 34, 4,  4,  4,  4,  4,  4,  20, 20,\n\t20, 20, 20, 36, 36, 36, 36, 36, 6,  6,  6,  6,  6,  6,  22, 22, 22, 22, 22,\n\t38, 38, 38, 38, 38, 38, 8,  8,  8,  8,  8,  24, 24, 24, 24, 24, 24, 40, 40,\n\t40, 40, 40, 10, 10, 10, 10, 10, 26, 26, 26, 26, 26, 26, 42, 42, 42, 42, 42,\n\t12, 12, 12, 12, 12, 12, 28, 28, 28, 28, 28, 44, 44, 44, 44, 44, 14, 14, 14,\n\t14, 14, 14, 30, 30, 30, 30, 30, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47,\n\t47, 31, 31, 31, 31, 31, 15, 15, 15, 15, 15, 15, 45, 45, 45, 45, 45, 29, 29,\n\t29, 29, 29, 13, 13, 13, 13, 13, 13, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27,\n\t27, 11, 11, 11, 11, 11, 41, 41, 41, 41, 41, 25, 25, 25, 25, 25, 25, 9,  9,\n\t9,  9,  9,  39, 39, 39, 39, 39, 39, 23, 23, 23, 23, 23, 7,  7,  7,  7,  7,\n\t7,  37, 37, 37, 37, 37, 21, 21, 21, 21, 21, 5,  5,  5,  5,  5,  5,  35, 35,\n\t35, 35, 35, 19, 19, 19, 19, 19, 19, 3,  3,  3,  3,  3,  33, 33, 33, 33, 33,\n\t17, 17, 17, 17, 17, 17, 1,  1,  1 },\n\t{ 0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,\n\t5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,\n\t9,  10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14,\n\t14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n\t19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23,\n\t23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28,\n\t28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33,\n\t33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,\n\t38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42,\n\t42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47,\n\t47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,\n\t52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 56,\n\t56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61,\n\t61, 61, 62, 62, 62, 62, 63, 63, 63 },\n\t{ 0,  0,  16, 16, 16, 32, 32, 32, 48, 48, 48, 48, 64, 64, 64, 2,  2,  2,  18,\n\t18, 18, 34, 34, 34, 50, 50, 50, 50, 66, 66, 66, 4,  4,  4,  20, 20, 20, 36,\n\t36, 36, 36, 52, 52, 52, 68, 68, 68, 6,  6,  6,  22, 22, 22, 38, 38, 38, 38,\n\t54, 54, 54, 70, 70, 70, 8,  8,  8,  24, 24, 24, 24, 40, 40, 40, 56, 56, 56,\n\t72, 72, 72, 10, 10, 10, 26, 26, 26, 26, 42, 42, 42, 58, 58, 58, 74, 74, 74,\n\t12, 12, 12, 12, 28, 28, 28, 44, 44, 44, 60, 60, 60, 76, 76, 76, 14, 14, 14,\n\t14, 30, 30, 30, 46, 46, 46, 62, 62, 62, 78, 78, 78, 78, 79, 79, 79, 79, 63,\n\t63, 63, 47, 47, 47, 31, 31, 31, 15, 15, 15, 15, 77, 77, 77, 61, 61, 61, 45,\n\t45, 45, 29, 29, 29, 13, 13, 13, 13, 75, 75, 75, 59, 59, 59, 43, 43, 43, 27,\n\t27, 27, 27, 11, 11, 11, 73, 73, 73, 57, 57, 57, 41, 41, 41, 25, 25, 25, 25,\n\t9,  9,  9,  71, 71, 71, 55, 55, 55, 39, 39, 39, 39, 23, 23, 23, 7,  7,  7,\n\t69, 69, 69, 53, 53, 53, 37, 37, 37, 37, 21, 21, 21, 5,  5,  5,  67, 67, 67,\n\t51, 51, 51, 51, 35, 35, 35, 19, 19, 19, 3,  3,  3,  65, 65, 65, 49, 49, 49,\n\t49, 33, 33, 33, 17, 17, 17, 1,  1 },\n\t{ 0,  0,  32, 32, 64, 64, 64, 2,  2,  2,  34, 34, 66, 66, 66, 4,  4,  4,  36,\n\t36, 68, 68, 68, 6,  6,  6,  38, 38, 70, 70, 70, 8,  8,  8,  40, 40, 40, 72,\n\t72, 10, 10, 10, 42, 42, 42, 74, 74, 12, 12, 12, 44, 44, 44, 76, 76, 14, 14,\n\t14, 46, 46, 46, 78, 78, 16, 16, 16, 48, 48, 48, 80, 80, 80, 18, 18, 50, 50,\n\t50, 82, 82, 82, 20, 20, 52, 52, 52, 84, 84, 84, 22, 22, 54, 54, 54, 86, 86,\n\t86, 24, 24, 56, 56, 56, 88, 88, 88, 26, 26, 58, 58, 58, 90, 90, 90, 28, 28,\n\t60, 60, 60, 92, 92, 92, 30, 30, 62, 62, 62, 94, 94, 94, 95, 95, 95, 63, 63,\n\t63, 31, 31, 93, 93, 93, 61, 61, 61, 29, 29, 91, 91, 91, 59, 59, 59, 27, 27,\n\t89, 89, 89, 57, 57, 57, 25, 25, 87, 87, 87, 55, 55, 55, 23, 23, 85, 85, 85,\n\t53, 53, 53, 21, 21, 83, 83, 83, 51, 51, 51, 19, 19, 81, 81, 81, 49, 49, 49,\n\t17, 17, 17, 79, 79, 47, 47, 47, 15, 15, 15, 77, 77, 45, 45, 45, 13, 13, 13,\n\t75, 75, 43, 43, 43, 11, 11, 11, 73, 73, 41, 41, 41, 9,  9,  9,  71, 71, 71,\n\t39, 39, 7,  7,  7,  69, 69, 69, 37, 37, 5,  5,  5,  67, 67, 67, 35, 35, 3,\n\t3,  3,  65, 65, 65, 33, 33, 1,  1 },\n\t{ 0,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,\n\t7,   8,   8,   9,   9,   10,  10,  11,  11,  12,  12,  13,  13,  14,  14,\n\t15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,\n\t22,  23,  23,  24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,\n\t30,  30,  31,  31,  32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,\n\t37,  38,  38,  39,  39,  40,  40,  41,  41,  42,  42,  43,  43,  44,  44,\n\t45,  45,  46,  46,  47,  47,  48,  48,  49,  49,  50,  50,  51,  51,  52,\n\t52,  53,  53,  54,  54,  55,  55,  56,  56,  57,  57,  58,  58,  59,  59,\n\t60,  60,  61,  61,  62,  62,  63,  63,  64,  64,  65,  65,  66,  66,  67,\n\t67,  68,  68,  69,  69,  70,  70,  71,  71,  72,  72,  73,  73,  74,  74,\n\t75,  75,  76,  76,  77,  77,  78,  78,  79,  79,  80,  80,  81,  81,  82,\n\t82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,  88,  88,  89,  89,\n\t90,  90,  91,  91,  92,  92,  93,  93,  94,  94,  95,  95,  96,  96,  97,\n\t97,  98,  98,  99,  99,  100, 100, 101, 101, 102, 102, 103, 103, 104, 104,\n\t105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112,\n\t112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119,\n\t120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127,\n\t127 },\n\t{ 0,   32,  32,  64,  96,  96,  128, 128, 2,   34,  34,  66,  98,  98,  130,\n\t130, 4,   36,  36,  68,  100, 100, 132, 132, 6,   38,  38,  70,  102, 102,\n\t134, 134, 8,   40,  40,  72,  104, 104, 136, 136, 10,  42,  42,  74,  106,\n\t106, 138, 138, 12,  44,  44,  76,  108, 108, 140, 140, 14,  46,  46,  78,\n\t110, 110, 142, 142, 16,  48,  48,  80,  112, 112, 144, 144, 18,  50,  50,\n\t82,  114, 114, 146, 146, 20,  52,  52,  84,  116, 116, 148, 148, 22,  54,\n\t54,  86,  118, 118, 150, 150, 24,  56,  56,  88,  120, 120, 152, 152, 26,\n\t58,  58,  90,  122, 122, 154, 154, 28,  60,  60,  92,  124, 124, 156, 156,\n\t30,  62,  62,  94,  126, 126, 158, 158, 159, 159, 127, 127, 95,  63,  63,\n\t31,  157, 157, 125, 125, 93,  61,  61,  29,  155, 155, 123, 123, 91,  59,\n\t59,  27,  153, 153, 121, 121, 89,  57,  57,  25,  151, 151, 119, 119, 87,\n\t55,  55,  23,  149, 149, 117, 117, 85,  53,  53,  21,  147, 147, 115, 115,\n\t83,  51,  51,  19,  145, 145, 113, 113, 81,  49,  49,  17,  143, 143, 111,\n\t111, 79,  47,  47,  15,  141, 141, 109, 109, 77,  45,  45,  13,  139, 139,\n\t107, 107, 75,  43,  43,  11,  137, 137, 105, 105, 73,  41,  41,  9,   135,\n\t135, 103, 103, 71,  39,  39,  7,   133, 133, 101, 101, 69,  37,  37,  5,\n\t131, 131, 99,  99,  67,  35,  35,  3,   129, 129, 97,  97,  65,  33,  33,\n\t1 },\n\t{ 0,   64,  128, 128, 2,   66,  130, 130, 4,   68,  132, 132, 6,   70,  134,\n\t134, 8,   72,  136, 136, 10,  74,  138, 138, 12,  76,  140, 140, 14,  78,\n\t142, 142, 16,  80,  144, 144, 18,  82,  146, 146, 20,  84,  148, 148, 22,\n\t86,  150, 150, 24,  88,  152, 152, 26,  90,  154, 154, 28,  92,  156, 156,\n\t30,  94,  158, 158, 32,  96,  160, 160, 34,  98,  162, 162, 36,  100, 164,\n\t164, 38,  102, 166, 166, 40,  104, 168, 168, 42,  106, 170, 170, 44,  108,\n\t172, 172, 46,  110, 174, 174, 48,  112, 176, 176, 50,  114, 178, 178, 52,\n\t116, 180, 180, 54,  118, 182, 182, 56,  120, 184, 184, 58,  122, 186, 186,\n\t60,  124, 188, 188, 62,  126, 190, 190, 191, 191, 127, 63,  189, 189, 125,\n\t61,  187, 187, 123, 59,  185, 185, 121, 57,  183, 183, 119, 55,  181, 181,\n\t117, 53,  179, 179, 115, 51,  177, 177, 113, 49,  175, 175, 111, 47,  173,\n\t173, 109, 45,  171, 171, 107, 43,  169, 169, 105, 41,  167, 167, 103, 39,\n\t165, 165, 101, 37,  163, 163, 99,  35,  161, 161, 97,  33,  159, 159, 95,\n\t31,  157, 157, 93,  29,  155, 155, 91,  27,  153, 153, 89,  25,  151, 151,\n\t87,  23,  149, 149, 85,  21,  147, 147, 83,  19,  145, 145, 81,  17,  143,\n\t143, 79,  15,  141, 141, 77,  13,  139, 139, 75,  11,  137, 137, 73,  9,\n\t135, 135, 71,  7,   133, 133, 69,  5,   131, 131, 67,  3,   129, 129, 65,\n\t1 },\n\t{ 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,\n\t15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,\n\t30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,\n\t45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,\n\t60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,\n\t75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,\n\t90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,\n\t105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\n\t120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,\n\t135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\n\t150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n\t165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,\n\t180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,\n\t195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,\n\t210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,\n\t225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,\n\t240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,\n\t255 } };\n\nrange_t endpoint_quantization(size_t partitions,\n\trange_t weight_quant,\n\tcolor_endpoint_mode_t endpoint_mode) {\n\tint8_t ce_range =\n\t\tcolor_endpoint_range_table[partitions - 1][weight_quant][endpoint_mode];\n\tDCHECK(ce_range >= 0 && ce_range <= RANGE_MAX);\n\treturn static_cast<range_t>(ce_range);\n}\n\nint color_channel_sum(vec3i_t color) {\n\treturn color.r + color.g + color.b;\n}\n\nuint8_t quantize_color(range_t quant, int c) {\n\tDCHECK(c >= 0 && c <= 255);\n\treturn color_quantize_table[quant][c];\n}\n\nvec3i_t quantize_color(range_t quant, vec3i_t c) {\n\tvec3i_t result;\n\tresult.r = color_quantize_table[quant][c.r];\n\tresult.g = color_quantize_table[quant][c.g];\n\tresult.b = color_quantize_table[quant][c.b];\n\treturn result;\n}\n\nuint8_t unquantize_color(range_t quant, int c) {\n\tDCHECK(c >= 0 && c <= 255);\n\treturn color_unquantize_table[quant][c];\n}\n\nvec3i_t unquantize_color(range_t quant, vec3i_t c) {\n\tvec3i_t result;\n\tresult.r = color_unquantize_table[quant][c.r];\n\tresult.g = color_unquantize_table[quant][c.g];\n\tresult.b = color_unquantize_table[quant][c.b];\n\treturn result;\n}\n\nvoid encode_luminance_direct(range_t endpoint_quant,\n\tint v0,\n\tint v1,\n\tuint8_t endpoint_unquantized[2],\n\tuint8_t endpoint_quantized[2]) {\n\tendpoint_quantized[0] = quantize_color(endpoint_quant, v0);\n\tendpoint_quantized[1] = quantize_color(endpoint_quant, v1);\n\tendpoint_unquantized[0] =\n\t\tunquantize_color(endpoint_quant, endpoint_quantized[0]);\n\tendpoint_unquantized[1] =\n\t\tunquantize_color(endpoint_quant, endpoint_quantized[1]);\n}\n\nvoid encode_rgb_direct(range_t endpoint_quant,\n\tvec3i_t e0,\n\tvec3i_t e1,\n\tuint8_t endpoint_quantized[6],\n\tvec3i_t endpoint_unquantized[2]) {\n\tvec3i_t e0q = quantize_color(endpoint_quant, e0);\n\tvec3i_t e1q = quantize_color(endpoint_quant, e1);\n\tvec3i_t e0u = unquantize_color(endpoint_quant, e0q);\n\tvec3i_t e1u = unquantize_color(endpoint_quant, e1q);\n\n\t// ASTC uses a different blue contraction encoding when the sum of values for\n\t// the first endpoint is larger than the sum of values in the second\n\t// endpoint. Sort the endpoints to ensure that the normal encoding is used.\n\tif (color_channel_sum(e0u) > color_channel_sum(e1u)) {\n\t\tendpoint_quantized[0] = static_cast<uint8_t>(e1q.r);\n\t\tendpoint_quantized[1] = static_cast<uint8_t>(e0q.r);\n\t\tendpoint_quantized[2] = static_cast<uint8_t>(e1q.g);\n\t\tendpoint_quantized[3] = static_cast<uint8_t>(e0q.g);\n\t\tendpoint_quantized[4] = static_cast<uint8_t>(e1q.b);\n\t\tendpoint_quantized[5] = static_cast<uint8_t>(e0q.b);\n\n\t\tendpoint_unquantized[0] = e1u;\n\t\tendpoint_unquantized[1] = e0u;\n\t} else {\n\t\tendpoint_quantized[0] = static_cast<uint8_t>(e0q.r);\n\t\tendpoint_quantized[1] = static_cast<uint8_t>(e1q.r);\n\t\tendpoint_quantized[2] = static_cast<uint8_t>(e0q.g);\n\t\tendpoint_quantized[3] = static_cast<uint8_t>(e1q.g);\n\t\tendpoint_quantized[4] = static_cast<uint8_t>(e0q.b);\n\t\tendpoint_quantized[5] = static_cast<uint8_t>(e1q.b);\n\n\t\tendpoint_unquantized[0] = e0u;\n\t\tendpoint_unquantized[1] = e1u;\n\t}\n}\n\n// FIXME: This is copied from ARM-code\nconst uint8_t weight_quantize_table[12][1025] = {\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },\n\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 20, 6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },\n\t{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,\n\t2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,\n\t3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,\n\t4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,\n\t5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,\n\t7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,\n\t8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,\n\t9,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n\t16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n\t17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,\n\t19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,\n\t30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,\n\t30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 } };\n\nuint8_t quantize_weight(range_t weight_quant, size_t weight) {\n\tDCHECK(weight_quant <= RANGE_32);\n\tDCHECK(weight <= 1024);\n\treturn weight_quantize_table[weight_quant][weight];\n}\n\n/**\n* Project a texel to a line and quantize the result in 1 dimension.\n*\n* The line is defined by t=k*x + m. This function calculates and quantizes x\n* by projecting n=t-m onto k, x=|n|/|k|. Since k and m is derived from the\n* minimum and maximum of all texel values the result will be in the range [0,\n* 1].\n*\n* To quantize the result using the weight_quantize_table the value needs to\n* be extended to the range [0, 1024].\n*\n* @param k the derivative of the line\n* @param m the minimum endpoint\n* @param t the texel value\n*/\nsize_t project(size_t k, size_t m, size_t t) {\n\tDCHECK(k > 0);\n\treturn size_t((t - m) * 1024) / k;\n}\n\n/**\n* Project a texel to a line and quantize the result in 3 dimensions.\n*/\nsize_t project(vec3i_t k, int kk, vec3i_t m, vec3i_t t) {\n\tDCHECK(kk > 0);\n\n\treturn static_cast<size_t>(clamp(0, 1024, dot(t - m, k) * 1024 / kk));\n}\n\nvoid calculate_quantized_weights_luminance(\n\tconst uint8_t texels[BLOCK_TEXEL_COUNT],\n\trange_t quant,\n\tuint8_t l0,\n\tuint8_t l1,\n\tuint8_t weights[BLOCK_TEXEL_COUNT]) {\n\tDCHECK(l0 < l1);\n\n\tsize_t k = l1 - l0;\n\tsize_t m = l0;\n\n\tfor (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {\n\t\tsize_t t = static_cast<size_t>(texels[i]);\n\t\tweights[i] = quantize_weight(quant, project(k, m, t));\n\t}\n}\n\nvoid calculate_quantized_weights_rgb(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\trange_t quant,\n\tvec3i_t e0,\n\tvec3i_t e1,\n\tuint8_t weights[BLOCK_TEXEL_COUNT]) {\n\tif (e0 == e1) {\n\t\tfor (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {\n\t\t\tweights[i] = 0;  // quantize_weight(quant, 0) is always 0\n\t\t}\n\t} else {\n\t\tvec3i_t k = e1 - e0;\n\t\tvec3i_t m = e0;\n\n\t\tint kk = dot(k, k);\n\t\tfor (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {\n\t\t\tweights[i] =\n\t\t\t\tquantize_weight(quant, project(k, kk, m, to_vec3i(texels[i])));\n\t\t}\n\t}\n}\n\n/**\n* Write void extent block bits for LDR mode and unused extent coordinates.\n*/\nvoid encode_void_extent(vec3i_t color, PhysicalBlock* physical_block) {\n\tvoid_extent_to_physical(unorm8_to_unorm16(to_unorm8(color)), physical_block);\n}\n\nvoid encode_luminance(const uint8_t texels[BLOCK_TEXEL_COUNT],\n\tPhysicalBlock* physical_block) {\n\tsize_t partition_count = 1;\n\tsize_t partition_index = 0;\n\n\tcolor_endpoint_mode_t color_endpoint_mode = CEM_LDR_LUMINANCE_DIRECT;\n\trange_t weight_quant = RANGE_32;\n\trange_t endpoint_quant =\n\t\tendpoint_quantization(partition_count, weight_quant, color_endpoint_mode);\n\n\tuint8_t l0 = 255;\n\tuint8_t l1 = 0;\n\tfor (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {\n\t\tl0 = min(l0, texels[i]);\n\t\tl1 = max(l1, texels[i]);\n\t}\n\n\tuint8_t endpoint_unquantized[2];\n\tuint8_t endpoint_quantized[2];\n\tencode_luminance_direct(\n\t\tendpoint_quant, l0, l1, endpoint_quantized, endpoint_unquantized);\n\n\tuint8_t weights_quantized[BLOCK_TEXEL_COUNT];\n\tcalculate_quantized_weights_luminance(texels,\n\t\tweight_quant,\n\t\tendpoint_unquantized[0],\n\t\tendpoint_unquantized[1],\n\t\tweights_quantized);\n\n\tuint8_t endpoint_ise[MAXIMUM_ENCODED_COLOR_ENDPOINT_BYTES] = { 0 };\n\tinteger_sequence_encode(endpoint_quantized, 2, RANGE_256, endpoint_ise);\n\n\tuint8_t weights_ise[MAXIMUM_ENCODED_WEIGHT_BYTES + 1] = { 0 };\n\tinteger_sequence_encode(\n\t\tweights_quantized, BLOCK_TEXEL_COUNT, RANGE_32, weights_ise);\n\n\tsymbolic_to_physical(color_endpoint_mode,\n\t\tendpoint_quant,\n\t\tweight_quant,\n\t\tpartition_count,\n\t\tpartition_index,\n\t\tendpoint_ise,\n\t\tweights_ise,\n\t\tphysical_block);\n}\n\nvoid encode_rgb_single_partition(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tvec3f_t e0,\n\tvec3f_t e1,\n\tPhysicalBlock* physical_block) {\n\tsize_t partition_index = 0;\n\tsize_t partition_count = 1;\n\n\tcolor_endpoint_mode_t color_endpoint_mode = CEM_LDR_RGB_DIRECT;\n\trange_t weight_quant = RANGE_12;\n\trange_t endpoint_quant =\n\t\tendpoint_quantization(partition_count, weight_quant, color_endpoint_mode);\n\n\tvec3i_t endpoint_unquantized[2];\n\tuint8_t endpoint_quantized[6];\n\tencode_rgb_direct(endpoint_quant,\n\t\tround(e0),\n\t\tround(e1),\n\t\tendpoint_quantized,\n\t\tendpoint_unquantized);\n\n\tuint8_t weights_quantized[BLOCK_TEXEL_COUNT];\n\tcalculate_quantized_weights_rgb(texels,\n\t\tweight_quant,\n\t\tendpoint_unquantized[0],\n\t\tendpoint_unquantized[1],\n\t\tweights_quantized);\n\n\tuint8_t endpoint_ise[MAXIMUM_ENCODED_COLOR_ENDPOINT_BYTES] = { 0 };\n\tinteger_sequence_encode(endpoint_quantized, 6, endpoint_quant, endpoint_ise);\n\n\tuint8_t weights_ise[MAXIMUM_ENCODED_WEIGHT_BYTES + 1] = { 0 };\n\tinteger_sequence_encode(\n\t\tweights_quantized, BLOCK_TEXEL_COUNT, weight_quant, weights_ise);\n\n\tsymbolic_to_physical(color_endpoint_mode,\n\t\tendpoint_quant,\n\t\tweight_quant,\n\t\tpartition_count,\n\t\tpartition_index,\n\t\tendpoint_ise,\n\t\tweights_ise,\n\t\tphysical_block);\n}\n\nbool is_solid(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tsize_t count,\n\tunorm8_t& color) {\n\tfor (size_t i = 0; i < count; ++i) {\n\t\tif (!approx_equal(to_vec3i(texels[i]), to_vec3i(texels[0]))) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// TODO: Calculate average color?\n\tcolor = texels[0];\n\treturn true;\n}\n\nbool is_greyscale(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tsize_t count,\n\tuint8_t luminances[BLOCK_TEXEL_COUNT]) {\n\tfor (size_t i = 0; i < count; ++i) {\n\t\tvec3i_t color = to_vec3i(texels[i]);\n\t\tluminances[i] = static_cast<uint8_t>(luminance(color));\n\t\tvec3i_t lum(luminances[i], luminances[i], luminances[i]);\n\t\tif (!approx_equal(color, lum)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nvec3f_t mean(const unorm8_t texels[BLOCK_TEXEL_COUNT], size_t count) {\n\tvec3i_t sum(0, 0, 0);\n\tfor (size_t i = 0; i < count; ++i) {\n\t\tsum = sum + to_vec3i(texels[i]);\n\t}\n\n\treturn to_vec3f(sum) / static_cast<float>(count);\n}\n\nvoid subtract(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tsize_t count,\n\tvec3f_t v,\n\tvec3f_t output[BLOCK_TEXEL_COUNT]) {\n\tfor (size_t i = 0; i < count; ++i) {\n\t\toutput[i] = to_vec3f(texels[i]) - v;\n\t}\n}\n\nstruct mat3x3f_t {\npublic:\n\tmat3x3f_t() {}\n\n\tmat3x3f_t(float m00,\n\t\tfloat m01,\n\t\tfloat m02,\n\t\tfloat m10,\n\t\tfloat m11,\n\t\tfloat m12,\n\t\tfloat m20,\n\t\tfloat m21,\n\t\tfloat m22) {\n\t\tm[0] = vec3f_t(m00, m01, m02);\n\t\tm[1] = vec3f_t(m10, m11, m12);\n\t\tm[2] = vec3f_t(m20, m21, m22);\n\t}\n\n\tconst vec3f_t& row(size_t i) const { return m[i]; }\n\n\tfloat& at(size_t i, size_t j) { return m[i].components[j]; }\n\tconst float& at(size_t i, size_t j) const { return m[i].components[j]; }\n\nprivate:\n\tvec3f_t m[3];\n};\n\ninline vec3f_t operator*(const mat3x3f_t& a, vec3f_t b) {\n\tvec3f_t tmp;\n\ttmp.x = dot(a.row(0), b);\n\ttmp.y = dot(a.row(1), b);\n\ttmp.z = dot(a.row(2), b);\n\treturn tmp;\n}\n\nvoid eigen_vector(const mat3x3f_t& a, vec3f_t& eig) {\n\tvec3f_t b = signorm(vec3f_t(1, 3, 2));  // FIXME: Magic number\n\tfor (size_t i = 0; i < 8; ++i) {\n\t\tb = signorm(a * b);\n\t}\n\n\teig = b;\n}\n\nmat3x3f_t covariance(const vec3f_t m[BLOCK_TEXEL_COUNT], size_t count) {\n\tmat3x3f_t cov;\n\tfor (size_t i = 0; i < 3; ++i) {\n\t\tfor (size_t j = 0; j < 3; ++j) {\n\t\t\tfloat s = 0;\n\t\t\tfor (size_t k = 0; k < count; ++k) {\n\t\t\t\ts += m[k].components[i] * m[k].components[j];\n\t\t\t}\n\t\t\tcov.at(i, j) = s / static_cast<float>(count - 1);\n\t\t}\n\t}\n\n\treturn cov;\n}\n\nvoid principal_component_analysis(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tsize_t count,\n\tvec3f_t& line_k,\n\tvec3f_t& line_m) {\n\t// Since we are working with fixed sized blocks count we can cap count. This\n\t// avoids dynamic allocation.\n\tDCHECK(count <= BLOCK_TEXEL_COUNT);\n\n\tline_m = mean(texels, count);\n\n\tvec3f_t n[BLOCK_TEXEL_COUNT];\n\tsubtract(texels, count, line_m, n);\n\n\tmat3x3f_t w = covariance(n, count);\n\n\teigen_vector(w, line_k);\n}\n\ninline void principal_component_analysis_block(\n\tconst unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tvec3f_t& line_k,\n\tvec3f_t& line_m) {\n\tprincipal_component_analysis(texels, BLOCK_TEXEL_COUNT, line_k, line_m);\n}\n\nvoid find_min_max(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tsize_t count,\n\tvec3f_t line_k,\n\tvec3f_t line_m,\n\tvec3f_t& e0,\n\tvec3f_t& e1) {\n\tDCHECK(count <= BLOCK_TEXEL_COUNT);\n\tDCHECK(approx_equal(quadrance(line_k), 1.0, 0.0001f));\n\n\tfloat a, b;\n\t{\n\t\tfloat t = dot(to_vec3f(texels[0]) - line_m, line_k);\n\t\ta = t;\n\t\tb = t;\n\t}\n\n\tfor (size_t i = 1; i < count; ++i) {\n\t\tfloat t = dot(to_vec3f(texels[i]) - line_m, line_k);\n\t\ta = min(a, t);\n\t\tb = max(b, t);\n\t}\n\n\te0 = clamp_rgb(line_k * a + line_m);\n\te1 = clamp_rgb(line_k * b + line_m);\n}\n\nvoid find_min_max_block(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tvec3f_t line_k,\n\tvec3f_t line_m,\n\tvec3f_t& e0,\n\tvec3f_t& e1) {\n\tfind_min_max(texels, BLOCK_TEXEL_COUNT, line_k, line_m, e0, e1);\n}\n\nvoid compress_block(const unorm8_t texels[BLOCK_TEXEL_COUNT],\n\tPhysicalBlock* physical_block) {\n\t\t{\n\t\t\tunorm8_t color;\n\t\t\tif (is_solid(texels, BLOCK_TEXEL_COUNT, color)) {\n\t\t\t\tencode_void_extent(to_vec3i(color), physical_block);\n\t\t\t\t/* encode_void_extent(vec3i_t(0, 0, 0), physical_block); */\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tuint8_t luminances[BLOCK_TEXEL_COUNT];\n\t\t\tif (is_greyscale(texels, BLOCK_TEXEL_COUNT, luminances)) {\n\t\t\t\tencode_luminance(luminances, physical_block);\n\t\t\t\t/* encode_void_extent(vec3i_t(255, 0, 0), physical_block); */\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tvec3f_t k, m;\n\t\tprincipal_component_analysis_block(texels, k, m);\n\t\tvec3f_t e0, e1;\n\t\tfind_min_max_block(texels, k, m, e0, e1);\n\t\tencode_rgb_single_partition(texels, e0, e1, physical_block);\n\t\t/* encode_void_extent(vec3i_t(0, 255, 0), physical_block); */\n}\n\nvoid fetch_image_block(const unorm8_t* source,\n\tsize_t image_width,\n\tsize_t xpos,\n\tsize_t ypos,\n\tunorm8_t texels[BLOCK_TEXEL_COUNT]) {\n\tsize_t topleft_index = ypos * image_width + xpos;\n\n\tconst unorm8_t* row0 = source + topleft_index;\n\tconst unorm8_t* row1 = row0 + image_width;\n\tconst unorm8_t* row2 = row0 + 2 * image_width;\n\tconst unorm8_t* row3 = row0 + 3 * image_width;\n\n\ttexels[0] = row0[0];\n\ttexels[1] = row0[1];\n\ttexels[2] = row0[2];\n\ttexels[3] = row0[3];\n\n\ttexels[4] = row1[0];\n\ttexels[5] = row1[1];\n\ttexels[6] = row1[2];\n\ttexels[7] = row1[3];\n\n\ttexels[8] = row2[0];\n\ttexels[9] = row2[1];\n\ttexels[10] = row2[2];\n\ttexels[11] = row2[3];\n\n\ttexels[12] = row3[0];\n\ttexels[13] = row3[1];\n\ttexels[14] = row3[2];\n\ttexels[15] = row3[3];\n}\n\nPhysicalBlock physical_block_zero = { 0 };\n\nvoid compress_texture_4x4(const uint8_t* src,\n\tuint8_t* dst,\n\tint width_int,\n\tint height_int) {\n\tconst unorm8_t* data = reinterpret_cast<const unorm8_t*>(src);\n\n\tsize_t width = static_cast<size_t>(width_int);\n\tsize_t height = static_cast<size_t>(height_int);\n\n\tPhysicalBlock* dst_re = reinterpret_cast<PhysicalBlock*>(dst);\n\n\tfor (size_t ypos = 0; ypos < height; ypos += BLOCK_WIDTH) {\n\t\tfor (size_t xpos = 0; xpos < width; xpos += BLOCK_HEIGHT) {\n\t\t\tunorm8_t texels[BLOCK_TEXEL_COUNT];\n\t\t\tfetch_image_block(data, width, xpos, ypos, texels);\n\n\t\t\t*dst_re = physical_block_zero;\n\t\t\tcompress_block(texels, dst_re);\n\n\t\t\t++dst_re;\n\t\t}\n\t}\n}\n\n}"
  },
  {
    "path": "src/core/visual/ogl/astcrt.h",
    "content": "#pragma once\n#include \"stdint.h\"\n\nnamespace ASTCRealTimeCodec {\n\t// from https://github.com/daoo/astcrt\n\n\t/**\n\t* Compress an texture with the ASTC format.\n\t*\n\t* @param src The source data, width*height*4 bytes with BGRA ordering.\n\t* @param dst The output, width*height bytes.\n\t* @param width The width of the input texture.\n\t* @param height The height of the input texture.\n\t*/\n\tvoid compress_texture_4x4(const uint8_t* src, uint8_t* dst, int width, int height);\n}\n"
  },
  {
    "path": "src/core/visual/ogl/etcpak.cpp",
    "content": "#include \"etcpak.h\"\n#include <array>\n#include <assert.h>\n#include <cstdint>\n#include <algorithm>\n#include <condition_variable>\n#include <mutex>\n#include <future>\n#include <cmath>\n#include \"ThreadIntf.h\"\n#include \"tvpgl.h\"\n\n#define _bswap(x) ((x&0xFF)<<24)|((x&0xFF00)<<8)|((x&0xFF0000)>>8)|(x>>24)\nnamespace std {\n\tfloat _fma_(float x, float y, float z) { return fmaf(x, y, z); }\n}\n#define fma _fma_\nfloat _log2_(float n) {\n\treturn log(n) / M_LN2;\n}\n#define log2 _log2_\n\nnamespace ETCPacker {\ntypedef int8_t      int8;\ntypedef uint8_t     uint8;\ntypedef int16_t     int16;\ntypedef uint16_t    uint16;\ntypedef int32_t     int32;\ntypedef uint32_t    uint32;\ntypedef int64_t     int64;\ntypedef uint64_t    uint64;\n\ntypedef unsigned int uint;\n\n// takes as input a value, returns the value clamped to the interval [0,255].\n// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.\nstatic int clamp(int val)\n{\n\tif (val < 0)\n\t\tval = 0;\n\tif (val > 255)\n\t\tval = 255;\n\treturn val;\n}\nstatic int alphaTableInitialized = 0;\nstatic int alphaTable[256][8];\nstatic int alphaBase[16][4] = {\n\t{ -15,-9,-6,-3 },\n\t{ -13,-10,-7,-3 },\n\t{ -13,-8,-5,-2 },\n\t{ -13,-6,-4,-2 },\n\t{ -12,-8,-6,-3 },\n\t{ -11,-9,-7,-3 },\n\t{ -11,-8,-7,-4 },\n\t{ -11,-8,-5,-3 },\n\t{ -10,-8,-6,-2 },\n\t{ -10,-8,-5,-2 },\n\t{ -10,-8,-4,-2 },\n\t{ -10,-7,-5,-2 },\n\t{ -10,-7,-4,-3 },\n\t{ -10,-3,-2, -1 },\n\t{ -9,-8,-6,-4 },\n\t{ -9,-7,-5,-3 }\n};\n\n// Table for fast implementationi of clamping to the interval [0,255]\nstatic const int clamp_table[768] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,\n255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };\n\nstatic void setupAlphaTable()\n{\n\tif (alphaTableInitialized)\n\t\treturn;\n\talphaTableInitialized = 1;\n\n\t//read table used for alpha compression\n\tint buf;\n\tfor (int i = 16; i < 32; i++)\n\t{\n\t\tfor (int j = 0; j < 8; j++)\n\t\t{\n\t\t\tbuf = alphaBase[i - 16][3 - j % 4];\n\t\t\tif (j < 4)\n\t\t\t\talphaTable[i][j] = buf;\n\t\t\telse\n\t\t\t\talphaTable[i][j] = (-buf - 1);\n\t\t}\n\t}\n\n\t//beyond the first 16 values, the rest of the table is implicit.. so calculate that!\n\tfor (int i = 0; i < 256; i++)\n\t{\n\t\t//fill remaining slots in table with multiples of the first ones.\n\t\tint mul = i / 16;\n\t\tint old = 16 + i % 16;\n\t\tfor (int j = 0; j < 8; j++)\n\t\t{\n\t\t\talphaTable[i][j] = alphaTable[old][j] * mul;\n\t\t\t//note: we don't do clamping here, though we could, because we'll be clamped afterwards anyway.\n\t\t}\n\t}\n}\n\nstatic uint8 getbit(uint8 input, int frompos, int topos)\n{\n\tuint8 output = 0;\n\tif (frompos > topos)\n\t\treturn ((1 << frompos)&input) >> (frompos - topos);\n\treturn ((1 << frompos)&input) << (topos - frompos);\n}\n\n// Compresses the alpha part of a GL_COMPRESSED_RGBA8_ETC2_EAC block.\n// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.\nvoid compressBlockAlphaFast(uint8 * data, uint8* returnData)\n{\n\tint alphasum = 0;\n\tint maxdist = -2;\n\tbool solid = true;\n\tfor (int x = 0; x < 16; x++) {\n\t\talphasum += data[x];\n\t}\n\tint alpha = (int)(((float)alphasum) / 16.0f + 0.5f); //average pixel value, used as guess for base value.\n\tfor (int x = 0; x < 16; x++) {\n\t\tif (abs(alpha - data[x])>maxdist)\n\t\t\tmaxdist = abs(alpha - data[x]); //maximum distance from average\n\t}\n\tif (maxdist == 0) {\n\t\t// fast route for solid block\n\t\tmemset(returnData, 0, 8);\n\t\treturnData[0] = alpha;\n\t\treturn;\n\t}\n\tint approxPos = (maxdist * 255) / 160 - 4;  //experimentally derived formula for calculating approximate table position given a max distance from average\n\tif (approxPos > 255)\n\t\tapproxPos = 255;\n\tint startTable = approxPos - 15; //first table to be tested\n\tif (startTable < 0)\n\t\tstartTable = 0;\n\tint endTable = clamp(approxPos + 15);  //last table to be tested\n\n\tint bestsum = 1000000000;\n\tint besttable = -3;\n\tint bestalpha = 128;\n\tint prevalpha = alpha;\n\n\t//main loop: determine best base alpha value and offset table to use for compression\n\t//try some different alpha tables.\n\tfor (int table = startTable; table < endTable&&bestsum>0; table++)\n\t{\n\t\tint tablealpha = prevalpha;\n\t\tint tablebestsum = 1000000000;\n\t\t//test some different alpha values, trying to find the best one for the given table.\t\n\t\tfor (int alphascale = 16; alphascale > 0; alphascale /= 4)\n\t\t{\n\t\t\tint startalpha;\n\t\t\tint endalpha;\n\t\t\tif (alphascale == 16)\n\t\t\t{\n\t\t\t\tstartalpha = clamp(tablealpha - alphascale * 4);\n\t\t\t\tendalpha = clamp(tablealpha + alphascale * 4);\n\t\t\t} else\n\t\t\t{\n\t\t\t\tstartalpha = clamp(tablealpha - alphascale * 2);\n\t\t\t\tendalpha = clamp(tablealpha + alphascale * 2);\n\t\t\t}\n\t\t\tfor (alpha = startalpha; alpha <= endalpha; alpha += alphascale)\n\t\t\t{\n\t\t\t\tint sum = 0;\n\t\t\t\tint val, diff, bestdiff = 10000000, index;\n\t\t\t\tfor (int x = 0; x < 16; x++)\n\t\t\t\t{\n\t\t\t\t//\tfor (int y = 0; y < 4; y++)\n\t\t\t\t\t{\n\t\t\t\t\t\t//compute best offset here, add square difference to sum..\n\t\t\t\t\t\tval = data[x];\n\t\t\t\t\t\tbestdiff = 1000000000;\n\t\t\t\t\t\t//the values are always ordered from small to large, with the first 4 being negative and the last 4 positive\n\t\t\t\t\t\t//search is therefore made in the order 0-1-2-3 or 7-6-5-4, stopping when error increases compared to the previous entry tested.\n\t\t\t\t\t\tif (val > alpha)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor (index = 7; index > 3; index--)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdiff = clamp_table[alpha + (int)(alphaTable[table][index]) + 255] - val;\n\t\t\t\t\t\t\t\tdiff *= diff;\n\t\t\t\t\t\t\t\tif (diff <= bestdiff)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbestdiff = diff;\n\t\t\t\t\t\t\t\t} else\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor (index = 0; index < 4; index++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdiff = clamp_table[alpha + (int)(alphaTable[table][index]) + 255] - val;\n\t\t\t\t\t\t\t\tdiff *= diff;\n\t\t\t\t\t\t\t\tif (diff < bestdiff)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbestdiff = diff;\n\t\t\t\t\t\t\t\t} else\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//best diff here is bestdiff, add it to sum!\n\t\t\t\t\t\tsum += bestdiff;\n\t\t\t\t\t\t//if the sum here is worse than previously best already, there's no use in continuing the count..\n\t\t\t\t\t\t//note that tablebestsum could be used for more precise estimation, but the speedup gained here is deemed more important.\n\t\t\t\t\t\tif (sum > bestsum)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tx = 9999; //just to make it large and get out of the x<4 loop\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (sum < tablebestsum)\n\t\t\t\t{\n\t\t\t\t\ttablebestsum = sum;\n\t\t\t\t\ttablealpha = alpha;\n\t\t\t\t}\n\t\t\t\tif (sum < bestsum)\n\t\t\t\t{\n\t\t\t\t\tbestsum = sum;\n\t\t\t\t\tbesttable = table;\n\t\t\t\t\tbestalpha = alpha;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (alphascale <= 2)\n\t\t\t\talphascale = 0;\n\t\t}\n\t}\n\n\talpha = bestalpha;\n\n\t//\"good\" alpha value and table are known!\n\t//store them, then loop through the pixels again and print indices.\n\n\treturnData[0] = alpha;\n\treturnData[1] = besttable;\n\tfor (int pos = 2; pos < 8; pos++)\n\t{\n\t\treturnData[pos] = 0;\n\t}\n\tint byte = 2;\n\tint bit = 0;\n\tfor (int x = 0; x < 16; x++)\n\t{\n\t//\tfor (int y = 0; y < 4; y++)\n\t\t{\n\t\t\t//find correct index\n\t\t\tint besterror = 1000000;\n\t\t\tint bestindex = 99;\n\t\t\tfor (int index = 0; index < 8; index++) //no clever ordering this time, as this loop is only run once per block anyway\n\t\t\t{\n\t\t\t\tint error = (clamp(alpha + (int)(alphaTable[besttable][index])) - data[x])*(clamp(alpha + (int)(alphaTable[besttable][index])) - data[x]);\n\t\t\t\tif (error < besterror)\n\t\t\t\t{\n\t\t\t\t\tbesterror = error;\n\t\t\t\t\tbestindex = index;\n\t\t\t\t}\n\t\t\t}\n\t\t\t//best table index has been determined.\n\t\t\t//pack 3-bit index into compressed data, one bit at a time\n\t\t\tfor (int numbit = 0; numbit < 3; numbit++)\n\t\t\t{\n\t\t\t\treturnData[byte] |= getbit(bestindex, 2 - numbit, 7 - bit);\n\n\t\t\t\tbit++;\n\t\t\t\tif (bit > 7)\n\t\t\t\t{\n\t\t\t\t\tbit = 0;\n\t\t\t\t\tbyte++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\ntemplate<typename T>\ninline T AlignPOT(T val)\n{\n\tif (val == 0) return 1;\n\tval--;\n\tfor (unsigned int i = 1; i < sizeof(T) * 8; i <<= 1)\n\t{\n\t\tval |= val >> i;\n\t}\n\treturn val + 1;\n}\n\ninline int CountSetBits(uint32 val)\n{\n\tval -= (val >> 1) & 0x55555555;\n\tval = ((val >> 2) & 0x33333333) + (val & 0x33333333);\n\tval = ((val >> 4) + val) & 0x0f0f0f0f;\n\tval += val >> 8;\n\tval += val >> 16;\n\treturn val & 0x0000003f;\n}\n\ninline int CountLeadingZeros(uint32 val)\n{\n\tval |= val >> 1;\n\tval |= val >> 2;\n\tval |= val >> 4;\n\tval |= val >> 8;\n\tval |= val >> 16;\n\treturn 32 - CountSetBits(val);\n}\n\ninline float sRGB2linear(float v)\n{\n\tconst float a = 0.055f;\n\tif (v <= 0.04045f)\n\t{\n\t\treturn v / 12.92f;\n\t} else\n\t{\n\t\treturn std::pow((v + a) / (1 + a), 2.4f);\n\t}\n}\n\ninline float linear2sRGB(float v)\n{\n\tconst float a = 0.055f;\n\tif (v <= 0.0031308f)\n\t{\n\t\treturn 12.92f * v;\n\t} else\n\t{\n\t\treturn (1 + a) * std::pow(v, 1 / 2.4f) - a;\n\t}\n}\n\ntemplate<class T>\ninline T SmoothStep(T x)\n{\n\treturn x*x*(3 - 2 * x);\n}\n\ninline uint8 clampu8(int32 val)\n{\n\treturn std::min(std::max(0, val), 255);\n}\n\ntemplate<class T>\ninline T sq(T val)\n{\n\treturn val * val;\n}\n\nstatic inline int mul8bit(int a, int b)\n{\n\tint t = a*b + 128;\n\treturn (t + (t >> 8)) >> 8;\n}\n\ntemplate<class T>\nstruct Vector2\n{\n\tVector2() : x(0), y(0) {}\n\tVector2(T v) : x(v), y(v) {}\n\tVector2(T _x, T _y) : x(_x), y(_y) {}\n\n\tbool operator==(const Vector2<T>& rhs) const { return x == rhs.x && y == rhs.y; }\n\tbool operator!=(const Vector2<T>& rhs) const { return !(*this == rhs); }\n\n\tVector2<T>& operator+=(const Vector2<T>& rhs)\n\t{\n\t\tx += rhs.x;\n\t\ty += rhs.y;\n\t\treturn *this;\n\t}\n\tVector2<T>& operator-=(const Vector2<T>& rhs)\n\t{\n\t\tx -= rhs.x;\n\t\ty -= rhs.y;\n\t\treturn *this;\n\t}\n\tVector2<T>& operator*=(const Vector2<T>& rhs)\n\t{\n\t\tx *= rhs.x;\n\t\ty *= rhs.y;\n\t\treturn *this;\n\t}\n\n\tT x, y;\n};\n\ntemplate<class T>\nVector2<T> operator+(const Vector2<T>& lhs, const Vector2<T>& rhs)\n{\n\treturn Vector2<T>(lhs.x + rhs.x, lhs.y + rhs.y);\n}\n\ntemplate<class T>\nVector2<T> operator-(const Vector2<T>& lhs, const Vector2<T>& rhs)\n{\n\treturn Vector2<T>(lhs.x - rhs.x, lhs.y - rhs.y);\n}\n\ntemplate<class T>\nVector2<T> operator*(const Vector2<T>& lhs, const float& rhs)\n{\n\treturn Vector2<T>(lhs.x * rhs, lhs.y * rhs);\n}\n\ntemplate<class T>\nVector2<T> operator/(const Vector2<T>& lhs, const T& rhs)\n{\n\treturn Vector2<T>(lhs.x / rhs, lhs.y / rhs);\n}\n\n\ntypedef Vector2<int32> v2i;\ntypedef Vector2<float> v2f;\n\n\ntemplate<class T>\nstruct Vector3\n{\n\tVector3() : x(0), y(0), z(0) {}\n\tVector3(T v) : x(v), y(v), z(v) {}\n\tVector3(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}\n\ttemplate<class Y>\n\tVector3(const Vector3<Y>& v) : x(T(v.x)), y(T(v.y)), z(T(v.z)) {}\n\n\tT Luminance() const { return T(x * 0.3f + y * 0.59f + z * 0.11f); }\n\tvoid Clamp()\n\t{\n\t\tx = std::min(T(1), std::max(T(0), x));\n\t\ty = std::min(T(1), std::max(T(0), y));\n\t\tz = std::min(T(1), std::max(T(0), z));\n\t}\n\n\tbool operator==(const Vector3<T>& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }\n\tbool operator!=(const Vector2<T>& rhs) const { return !(*this == rhs); }\n\n\tT& operator[](uint idx) { assert(idx < 3); return ((T*)this)[idx]; }\n\tconst T& operator[](uint idx) const { assert(idx < 3); return ((T*)this)[idx]; }\n\n\tVector3<T> operator+=(const Vector3<T>& rhs)\n\t{\n\t\tx += rhs.x;\n\t\ty += rhs.y;\n\t\tz += rhs.z;\n\t\treturn *this;\n\t}\n\n\tVector3<T> operator*=(const Vector3<T>& rhs)\n\t{\n\t\tx *= rhs.x;\n\t\ty *= rhs.y;\n\t\tz *= rhs.z;\n\t\treturn *this;\n\t}\n\n\tVector3<T> operator*=(const float& rhs)\n\t{\n\t\tx *= rhs;\n\t\ty *= rhs;\n\t\tz *= rhs;\n\t\treturn *this;\n\t}\n\n\tT x, y, z;\n\tT padding;\n};\n\ntemplate<class T>\nVector3<T> operator+(const Vector3<T>& lhs, const Vector3<T>& rhs)\n{\n\treturn Vector3<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);\n}\n\ntemplate<class T>\nVector3<T> operator-(const Vector3<T>& lhs, const Vector3<T>& rhs)\n{\n\treturn Vector3<T>(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);\n}\n\ntemplate<class T>\nVector3<T> operator*(const Vector3<T>& lhs, const Vector3<T>& rhs)\n{\n\treturn Vector3<T>(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);\n}\n\ntemplate<class T>\nVector3<T> operator*(const Vector3<T>& lhs, const float& rhs)\n{\n\treturn Vector3<T>(T(lhs.x * rhs), T(lhs.y * rhs), T(lhs.z * rhs));\n}\n\ntemplate<class T>\nVector3<T> operator/(const Vector3<T>& lhs, const T& rhs)\n{\n\treturn Vector3<T>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);\n}\n\ntemplate<class T>\nbool operator<(const Vector3<T>& lhs, const Vector3<T>& rhs)\n{\n\treturn lhs.Luminance() < rhs.Luminance();\n}\n\ntypedef Vector3<int32> v3i;\ntypedef Vector3<float> v3f;\ntypedef Vector3<uint8> v3b;\n\n\nstatic inline v3b v3f_to_v3b(const v3f& v)\n{\n\treturn 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));\n}\n\ntemplate<class T>\nVector3<T> Mix(const Vector3<T>& v1, const Vector3<T>& v2, float amount)\n{\n\treturn v1 + (v2 - v1) * amount;\n}\n\ntemplate<>\ninline v3b Mix(const v3b& v1, const v3b& v2, float amount)\n{\n\treturn v3b(v3f(v1) + (v3f(v2) - v3f(v1)) * amount);\n}\n\ntemplate<class T>\nVector3<T> Desaturate(const Vector3<T>& v)\n{\n\tT l = v.Luminance();\n\treturn Vector3<T>(l, l, l);\n}\n\ntemplate<class T>\nVector3<T> Desaturate(const Vector3<T>& v, float mul)\n{\n\tT l = T(v.Luminance() * mul);\n\treturn Vector3<T>(l, l, l);\n}\n\ntemplate<class T>\nVector3<T> pow(const Vector3<T>& base, float exponent)\n{\n\treturn Vector3<T>(\n\t\tstd::pow(base.x, exponent),\n\t\tstd::pow(base.y, exponent),\n\t\tstd::pow(base.z, exponent));\n}\n\ntemplate<class T>\nVector3<T> sRGB2linear(const Vector3<T>& v)\n{\n\treturn Vector3<T>(\n\t\tsRGB2linear(v.x),\n\t\tsRGB2linear(v.y),\n\t\tsRGB2linear(v.z));\n}\n\ntemplate<class T>\nVector3<T> linear2sRGB(const Vector3<T>& v)\n{\n\treturn Vector3<T>(\n\t\tlinear2sRGB(v.x),\n\t\tlinear2sRGB(v.y),\n\t\tlinear2sRGB(v.z));\n}\n\nenum class Channels\n{\n\tRGB,\n\tAlpha\n};\n\nclass Bitmap\n{\npublic:\n\tBitmap(const v2i& size);\n\tBitmap(const v2i& size, const void *pixelData, int pitch, uint lines);\n\tvirtual ~Bitmap();\n\n\tuint32* Data() { if (m_load.valid()) m_load.wait(); return m_data; }\n\tconst uint32* Data() const { if (m_load.valid()) m_load.wait(); return m_data; }\n\tconst v2i& Size() const { return m_size; }\n\tbool Alpha() const { return m_alpha; }\n\n\tconst uint32* NextBlock(uint& lines, bool& done);\n\nprotected:\n\tBitmap(const Bitmap& src, uint lines);\n\n\tuint32* m_data;\n\tuint32* m_block;\n\tuint m_lines;\n\tuint m_linesLeft;\n\tv2i m_size;\n\tbool m_alpha;\n//\tSemaphore m_sema;\n//\tstd::mutex m_lock;\n\tstd::future<void> m_load;\n};\n\ntypedef std::shared_ptr<Bitmap> BitmapPtr;\n\nstruct DataPart\n{\n\tconst uint32* src;\n\tuint width;\n\tuint lines;\n\tuint offset;\n};\n\nconst int32 g_table[8][4] = {\n    {  2,  8,   -2,   -8 },\n    {  5, 17,   -5,  -17 },\n    {  9, 29,   -9,  -29 },\n    { 13, 42,  -13,  -42 },\n    { 18, 60,  -18,  -60 },\n    { 24, 80,  -24,  -80 },\n    { 33, 106, -33, -106 },\n    { 47, 183, -47, -183 }\n};\n\nconst int64 g_table256[8][4] = {\n    {  2*256,  8*256,   -2*256,   -8*256 },\n    {  5*256, 17*256,   -5*256,  -17*256 },\n    {  9*256, 29*256,   -9*256,  -29*256 },\n    { 13*256, 42*256,  -13*256,  -42*256 },\n    { 18*256, 60*256,  -18*256,  -60*256 },\n    { 24*256, 80*256,  -24*256,  -80*256 },\n    { 33*256, 106*256, -33*256, -106*256 },\n    { 47*256, 183*256, -47*256, -183*256 }\n};\n\nconst uint32 g_id[4][16] = {\n    { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },\n    { 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2 },\n    { 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4 },\n    { 7, 7, 6, 6, 7, 7, 6, 6, 7, 7, 6, 6, 7, 7, 6, 6 }\n};\n\nconst uint32 g_avg2[16] = {\n    0x00,\n    0x11,\n    0x22,\n    0x33,\n    0x44,\n    0x55,\n    0x66,\n    0x77,\n    0x88,\n    0x99,\n    0xAA,\n    0xBB,\n    0xCC,\n    0xDD,\n    0xEE,\n    0xFF\n};\n\nconst uint32 g_flags[64] = {\n    0x80800402, 0x80800402, 0x80800402, 0x80800402,\n    0x80800402, 0x80800402, 0x80800402, 0x8080E002,\n    0x80800402, 0x80800402, 0x8080E002, 0x8080E002,\n    0x80800402, 0x8080E002, 0x8080E002, 0x8080E002,\n    0x80000402, 0x80000402, 0x80000402, 0x80000402,\n    0x80000402, 0x80000402, 0x80000402, 0x8000E002,\n    0x80000402, 0x80000402, 0x8000E002, 0x8000E002,\n    0x80000402, 0x8000E002, 0x8000E002, 0x8000E002,\n    0x00800402, 0x00800402, 0x00800402, 0x00800402,\n    0x00800402, 0x00800402, 0x00800402, 0x0080E002,\n    0x00800402, 0x00800402, 0x0080E002, 0x0080E002,\n    0x00800402, 0x0080E002, 0x0080E002, 0x0080E002,\n    0x00000402, 0x00000402, 0x00000402, 0x00000402,\n    0x00000402, 0x00000402, 0x00000402, 0x0000E002,\n    0x00000402, 0x00000402, 0x0000E002, 0x0000E002,\n    0x00000402, 0x0000E002, 0x0000E002, 0x0000E002\n};\n\ntemplate<class T>\nstatic size_t GetLeastError(const T* err, size_t num)\n{\n\tsize_t idx = 0;\n\tfor (size_t i = 1; i < num; i++)\n\t{\n\t\tif (err[i] < err[idx])\n\t\t{\n\t\t\tidx = i;\n\t\t}\n\t}\n\treturn idx;\n}\n\nstatic uint64 FixByteOrder(uint64 d)\n{\n\treturn ((d & 0x00000000FFFFFFFF)) |\n\t\t((d & 0xFF00000000000000) >> 24) |\n\t\t((d & 0x000000FF00000000) << 24) |\n\t\t((d & 0x00FF000000000000) >> 8) |\n\t\t((d & 0x0000FF0000000000) << 8);\n}\n\ntemplate<class T, class S>\nstatic uint64 EncodeSelectors(uint64 d, const T terr[2][8], const S tsel[16][8], const uint32* id)\n{\n\tsize_t tidx[2];\n\ttidx[0] = GetLeastError(terr[0], 8);\n\ttidx[1] = GetLeastError(terr[1], 8);\n\n\td |= tidx[0] << 26;\n\td |= tidx[1] << 29;\n\tfor (int i = 0; i < 16; i++)\n\t{\n\t\tuint64 t = tsel[i][tidx[id[i] % 2]];\n\t\td |= (t & 0x1) << (i + 32);\n\t\td |= (t & 0x2) << (i + 47);\n\t}\n\n\treturn d;\n}\n\nnamespace\n{\n\ntypedef std::array<uint16, 4> v4i;\n\nvoid Average( const uint8* data, v4i* a )\n{\n#ifdef __SSE4_1__\n    __m128i d0 = _mm_loadu_si128(((__m128i*)data) + 0);\n    __m128i d1 = _mm_loadu_si128(((__m128i*)data) + 1);\n    __m128i d2 = _mm_loadu_si128(((__m128i*)data) + 2);\n    __m128i d3 = _mm_loadu_si128(((__m128i*)data) + 3);\n\n    __m128i d0l = _mm_unpacklo_epi8(d0, _mm_setzero_si128());\n    __m128i d0h = _mm_unpackhi_epi8(d0, _mm_setzero_si128());\n    __m128i d1l = _mm_unpacklo_epi8(d1, _mm_setzero_si128());\n    __m128i d1h = _mm_unpackhi_epi8(d1, _mm_setzero_si128());\n    __m128i d2l = _mm_unpacklo_epi8(d2, _mm_setzero_si128());\n    __m128i d2h = _mm_unpackhi_epi8(d2, _mm_setzero_si128());\n    __m128i d3l = _mm_unpacklo_epi8(d3, _mm_setzero_si128());\n    __m128i d3h = _mm_unpackhi_epi8(d3, _mm_setzero_si128());\n\n    __m128i sum0 = _mm_add_epi16(d0l, d1l);\n    __m128i sum1 = _mm_add_epi16(d0h, d1h);\n    __m128i sum2 = _mm_add_epi16(d2l, d3l);\n    __m128i sum3 = _mm_add_epi16(d2h, d3h);\n\n    __m128i sum0l = _mm_unpacklo_epi16(sum0, _mm_setzero_si128());\n    __m128i sum0h = _mm_unpackhi_epi16(sum0, _mm_setzero_si128());\n    __m128i sum1l = _mm_unpacklo_epi16(sum1, _mm_setzero_si128());\n    __m128i sum1h = _mm_unpackhi_epi16(sum1, _mm_setzero_si128());\n    __m128i sum2l = _mm_unpacklo_epi16(sum2, _mm_setzero_si128());\n    __m128i sum2h = _mm_unpackhi_epi16(sum2, _mm_setzero_si128());\n    __m128i sum3l = _mm_unpacklo_epi16(sum3, _mm_setzero_si128());\n    __m128i sum3h = _mm_unpackhi_epi16(sum3, _mm_setzero_si128());\n\n    __m128i b0 = _mm_add_epi32(sum0l, sum0h);\n    __m128i b1 = _mm_add_epi32(sum1l, sum1h);\n    __m128i b2 = _mm_add_epi32(sum2l, sum2h);\n    __m128i b3 = _mm_add_epi32(sum3l, sum3h);\n\n    __m128i a0 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(b2, b3), _mm_set1_epi32(4)), 3);\n    __m128i a1 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(b0, b1), _mm_set1_epi32(4)), 3);\n    __m128i a2 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(b1, b3), _mm_set1_epi32(4)), 3);\n    __m128i a3 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(b0, b2), _mm_set1_epi32(4)), 3);\n\n    _mm_storeu_si128((__m128i*)&a[0], _mm_packus_epi32(_mm_shuffle_epi32(a0, _MM_SHUFFLE(3, 0, 1, 2)), _mm_shuffle_epi32(a1, _MM_SHUFFLE(3, 0, 1, 2))));\n    _mm_storeu_si128((__m128i*)&a[2], _mm_packus_epi32(_mm_shuffle_epi32(a2, _MM_SHUFFLE(3, 0, 1, 2)), _mm_shuffle_epi32(a3, _MM_SHUFFLE(3, 0, 1, 2))));\n#else\n    uint32 r[4];\n    uint32 g[4];\n    uint32 b[4];\n\n    memset(r, 0, sizeof(r));\n    memset(g, 0, sizeof(g));\n    memset(b, 0, sizeof(b));\n\n    for( int j=0; j<4; j++ )\n    {\n        for( int i=0; i<4; i++ )\n        {\n            int index = (j & 2) + (i >> 1);\n            b[index] += *data++;\n            g[index] += *data++;\n            r[index] += *data++;\n            data++;\n        }\n    }\n\n    a[0] = v4i{ uint16( (r[2] + r[3] + 4) / 8 ), uint16( (g[2] + g[3] + 4) / 8 ), uint16( (b[2] + b[3] + 4) / 8 ), 0};\n    a[1] = v4i{ uint16( (r[0] + r[1] + 4) / 8 ), uint16( (g[0] + g[1] + 4) / 8 ), uint16( (b[0] + b[1] + 4) / 8 ), 0};\n    a[2] = v4i{ uint16( (r[1] + r[3] + 4) / 8 ), uint16( (g[1] + g[3] + 4) / 8 ), uint16( (b[1] + b[3] + 4) / 8 ), 0};\n    a[3] = v4i{ uint16( (r[0] + r[2] + 4) / 8 ), uint16( (g[0] + g[2] + 4) / 8 ), uint16( (b[0] + b[2] + 4) / 8 ), 0};\n#endif\n}\n\nvoid CalcErrorBlock( const uint8* data, uint err[4][4] )\n{\n#ifdef __SSE4_1__\n    __m128i d0 = _mm_loadu_si128(((__m128i*)data) + 0);\n    __m128i d1 = _mm_loadu_si128(((__m128i*)data) + 1);\n    __m128i d2 = _mm_loadu_si128(((__m128i*)data) + 2);\n    __m128i d3 = _mm_loadu_si128(((__m128i*)data) + 3);\n\n    __m128i dm0 = _mm_and_si128(d0, _mm_set1_epi32(0x00FFFFFF));\n    __m128i dm1 = _mm_and_si128(d1, _mm_set1_epi32(0x00FFFFFF));\n    __m128i dm2 = _mm_and_si128(d2, _mm_set1_epi32(0x00FFFFFF));\n    __m128i dm3 = _mm_and_si128(d3, _mm_set1_epi32(0x00FFFFFF));\n\n    __m128i d0l = _mm_unpacklo_epi8(dm0, _mm_setzero_si128());\n    __m128i d0h = _mm_unpackhi_epi8(dm0, _mm_setzero_si128());\n    __m128i d1l = _mm_unpacklo_epi8(dm1, _mm_setzero_si128());\n    __m128i d1h = _mm_unpackhi_epi8(dm1, _mm_setzero_si128());\n    __m128i d2l = _mm_unpacklo_epi8(dm2, _mm_setzero_si128());\n    __m128i d2h = _mm_unpackhi_epi8(dm2, _mm_setzero_si128());\n    __m128i d3l = _mm_unpacklo_epi8(dm3, _mm_setzero_si128());\n    __m128i d3h = _mm_unpackhi_epi8(dm3, _mm_setzero_si128());\n\n    __m128i sum0 = _mm_add_epi16(d0l, d1l);\n    __m128i sum1 = _mm_add_epi16(d0h, d1h);\n    __m128i sum2 = _mm_add_epi16(d2l, d3l);\n    __m128i sum3 = _mm_add_epi16(d2h, d3h);\n\n    __m128i sum0l = _mm_unpacklo_epi16(sum0, _mm_setzero_si128());\n    __m128i sum0h = _mm_unpackhi_epi16(sum0, _mm_setzero_si128());\n    __m128i sum1l = _mm_unpacklo_epi16(sum1, _mm_setzero_si128());\n    __m128i sum1h = _mm_unpackhi_epi16(sum1, _mm_setzero_si128());\n    __m128i sum2l = _mm_unpacklo_epi16(sum2, _mm_setzero_si128());\n    __m128i sum2h = _mm_unpackhi_epi16(sum2, _mm_setzero_si128());\n    __m128i sum3l = _mm_unpacklo_epi16(sum3, _mm_setzero_si128());\n    __m128i sum3h = _mm_unpackhi_epi16(sum3, _mm_setzero_si128());\n\n    __m128i b0 = _mm_add_epi32(sum0l, sum0h);\n    __m128i b1 = _mm_add_epi32(sum1l, sum1h);\n    __m128i b2 = _mm_add_epi32(sum2l, sum2h);\n    __m128i b3 = _mm_add_epi32(sum3l, sum3h);\n\n    __m128i a0 = _mm_add_epi32(b2, b3);\n    __m128i a1 = _mm_add_epi32(b0, b1);\n    __m128i a2 = _mm_add_epi32(b1, b3);\n    __m128i a3 = _mm_add_epi32(b0, b2);\n\n    _mm_storeu_si128((__m128i*)&err[0], a0);\n    _mm_storeu_si128((__m128i*)&err[1], a1);\n    _mm_storeu_si128((__m128i*)&err[2], a2);\n    _mm_storeu_si128((__m128i*)&err[3], a3);\n#else\n    uint terr[4][4];\n\n    memset(terr, 0, 16 * sizeof(uint));\n\n    for( int j=0; j<4; j++ )\n    {\n        for( int i=0; i<4; i++ )\n        {\n            int index = (j & 2) + (i >> 1);\n            uint d = *data++;\n            terr[index][0] += d;\n            d = *data++;\n            terr[index][1] += d;\n            d = *data++;\n            terr[index][2] += d;\n            data++;\n        }\n    }\n\n    for( int i=0; i<3; i++ )\n    {\n        err[0][i] = terr[2][i] + terr[3][i];\n        err[1][i] = terr[0][i] + terr[1][i];\n        err[2][i] = terr[1][i] + terr[3][i];\n        err[3][i] = terr[0][i] + terr[2][i];\n    }\n    for( int i=0; i<4; i++ )\n    {\n        err[i][3] = 0;\n    }\n#endif\n}\n\nuint CalcError( const uint block[4], const v4i& average )\n{\n    uint err = 0x3FFFFFFF; // Big value to prevent negative values, but small enough to prevent overflow\n    err -= block[0] * 2 * average[2];\n    err -= block[1] * 2 * average[1];\n    err -= block[2] * 2 * average[0];\n    err += 8 * ( sq( average[0] ) + sq( average[1] ) + sq( average[2] ) );\n    return err;\n}\n\nvoid ProcessAverages( v4i* a )\n{\n#ifdef __SSE4_1__\n    for( int i=0; i<2; i++ )\n    {\n        __m128i d = _mm_loadu_si128((__m128i*)a[i*2].data());\n\n        __m128i t = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(31)), _mm_set1_epi16(128));\n\n        __m128i c = _mm_srli_epi16(_mm_add_epi16(t, _mm_srli_epi16(t, 8)), 8);\n\n        __m128i c1 = _mm_shuffle_epi32(c, _MM_SHUFFLE(3, 2, 3, 2));\n        __m128i diff = _mm_sub_epi16(c, c1);\n        diff = _mm_max_epi16(diff, _mm_set1_epi16(-4));\n        diff = _mm_min_epi16(diff, _mm_set1_epi16(3));\n\n        __m128i co = _mm_add_epi16(c1, diff);\n\n        c = _mm_blend_epi16(co, c, 0xF0);\n\n        __m128i a0 = _mm_or_si128(_mm_slli_epi16(c, 3), _mm_srli_epi16(c, 2));\n\n        _mm_storeu_si128((__m128i*)a[4+i*2].data(), a0);\n    }\n\n    for( int i=0; i<2; i++ )\n    {\n        __m128i d = _mm_loadu_si128((__m128i*)a[i*2].data());\n\n        __m128i t0 = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(15)), _mm_set1_epi16(128));\n        __m128i t1 = _mm_srli_epi16(_mm_add_epi16(t0, _mm_srli_epi16(t0, 8)), 8);\n\n        __m128i t2 = _mm_or_si128(t1, _mm_slli_epi16(t1, 4));\n\n        _mm_storeu_si128((__m128i*)a[i*2].data(), t2);\n    }\n#else\n    for( int i=0; i<2; i++ )\n    {\n        for( int j=0; j<3; j++ )\n        {\n            int32 c1 = mul8bit( a[i*2+1][j], 31 );\n            int32 c2 = mul8bit( a[i*2][j], 31 );\n\n            int32 diff = c2 - c1;\n            if( diff > 3 ) diff = 3;\n            else if( diff < -4 ) diff = -4;\n\n            int32 co = c1 + diff;\n\n            a[5+i*2][j] = ( c1 << 3 ) | ( c1 >> 2 );\n            a[4+i*2][j] = ( co << 3 ) | ( co >> 2 );\n        }\n    }\n\n    for( int i=0; i<4; i++ )\n    {\n        a[i][0] = g_avg2[mul8bit( a[i][0], 15 )];\n        a[i][1] = g_avg2[mul8bit( a[i][1], 15 )];\n        a[i][2] = g_avg2[mul8bit( a[i][2], 15 )];\n    }\n#endif\n}\n\nvoid EncodeAverages( uint64& _d, const v4i* a, size_t idx )\n{\n    auto d = _d;\n    d |= ( idx << 24 );\n    size_t base = idx << 1;\n\n    if( ( idx & 0x2 ) == 0 )\n    {\n        for( int i=0; i<3; i++ )\n        {\n            d |= uint64( a[base+0][i] >> 4 ) << ( i*8 );\n            d |= uint64( a[base+1][i] >> 4 ) << ( i*8 + 4 );\n        }\n    }\n    else\n    {\n        for( int i=0; i<3; i++ )\n        {\n            d |= uint64( a[base+1][i] & 0xF8 ) << ( i*8 );\n            int32 c = ( ( a[base+0][i] & 0xF8 ) - ( a[base+1][i] & 0xF8 ) ) >> 3;\n            c &= ~0xFFFFFFF8;\n            d |= ((uint64)c) << ( i*8 );\n        }\n    }\n    _d = d;\n}\n\nuint64 CheckSolid( const uint8* src )\n{\n#ifdef __SSE4_1__\n    __m128i d0 = _mm_loadu_si128(((__m128i*)src) + 0);\n    __m128i d1 = _mm_loadu_si128(((__m128i*)src) + 1);\n    __m128i d2 = _mm_loadu_si128(((__m128i*)src) + 2);\n    __m128i d3 = _mm_loadu_si128(((__m128i*)src) + 3);\n\n    __m128i c = _mm_shuffle_epi32(d0, _MM_SHUFFLE(0, 0, 0, 0));\n\n    __m128i c0 = _mm_cmpeq_epi8(d0, c);\n    __m128i c1 = _mm_cmpeq_epi8(d1, c);\n    __m128i c2 = _mm_cmpeq_epi8(d2, c);\n    __m128i c3 = _mm_cmpeq_epi8(d3, c);\n\n    __m128i m0 = _mm_and_si128(c0, c1);\n    __m128i m1 = _mm_and_si128(c2, c3);\n    __m128i m = _mm_and_si128(m0, m1);\n\n    if (!_mm_testc_si128(m, _mm_set1_epi32(-1)))\n    {\n        return 0;\n    }\n#else\n    const uint8* ptr = src + 4;\n    for( int i=1; i<16; i++ )\n    {\n        if( memcmp( src, ptr, 4 ) != 0 )\n        {\n            return 0;\n        }\n        ptr += 4;\n    }\n#endif\n    return 0x02000000 |\n        ( uint( src[0] & 0xF8 ) << 16 ) |\n        ( uint( src[1] & 0xF8 ) << 8 ) |\n        ( uint( src[2] & 0xF8 ) );\n}\n\nvoid PrepareAverages( v4i a[8], const uint8* src, uint err[4] )\n{\n    Average( src, a );\n    ProcessAverages( a );\n\n    uint errblock[4][4];\n    CalcErrorBlock( src, errblock );\n\n    for( int i=0; i<4; i++ )\n    {\n        err[i/2] += CalcError( errblock[i], a[i] );\n        err[2+i/2] += CalcError( errblock[i], a[i+4] );\n    }\n}\n\nvoid FindBestFit( uint64 terr[2][8], uint16 tsel[16][8], v4i a[8], const uint32* id, const uint8* data )\n{\n    for( size_t i=0; i<16; i++ )\n    {\n        uint16* sel = tsel[i];\n        uint bid = id[i];\n        uint64* ter = terr[bid%2];\n\n        uint8 b = *data++;\n        uint8 g = *data++;\n        uint8 r = *data++;\n        data++;\n\n        int dr = a[bid][0] - r;\n        int dg = a[bid][1] - g;\n        int db = a[bid][2] - b;\n\n#ifdef __SSE4_1__\n        // Reference implementation\n\n        __m128i pix = _mm_set1_epi32(dr * 77 + dg * 151 + db * 28);\n        // Taking the absolute value is way faster. The values are only used to sort, so the result will be the same.\n        __m128i error0 = _mm_abs_epi32(_mm_add_epi32(pix, g_table256_SIMD[0]));\n        __m128i error1 = _mm_abs_epi32(_mm_add_epi32(pix, g_table256_SIMD[1]));\n        __m128i error2 = _mm_abs_epi32(_mm_sub_epi32(pix, g_table256_SIMD[0]));\n        __m128i error3 = _mm_abs_epi32(_mm_sub_epi32(pix, g_table256_SIMD[1]));\n\n        __m128i index0 = _mm_and_si128(_mm_cmplt_epi32(error1, error0), _mm_set1_epi32(1));\n        __m128i minError0 = _mm_min_epi32(error0, error1);\n\n        __m128i index1 = _mm_sub_epi32(_mm_set1_epi32(2), _mm_cmplt_epi32(error3, error2));\n        __m128i minError1 = _mm_min_epi32(error2, error3);\n\n        __m128i minIndex0 = _mm_blendv_epi8(index0, index1, _mm_cmplt_epi32(minError1, minError0));\n        __m128i minError = _mm_min_epi32(minError0, minError1);\n\n        // Squaring the minimum error to produce correct values when adding\n        __m128i minErrorLow = _mm_shuffle_epi32(minError, _MM_SHUFFLE(1, 1, 0, 0));\n        __m128i squareErrorLow = _mm_mul_epi32(minErrorLow, minErrorLow);\n        squareErrorLow = _mm_add_epi64(squareErrorLow, _mm_loadu_si128(((__m128i*)ter) + 0));\n        _mm_storeu_si128(((__m128i*)ter) + 0, squareErrorLow);\n        __m128i minErrorHigh = _mm_shuffle_epi32(minError, _MM_SHUFFLE(3, 3, 2, 2));\n        __m128i squareErrorHigh = _mm_mul_epi32(minErrorHigh, minErrorHigh);\n        squareErrorHigh = _mm_add_epi64(squareErrorHigh, _mm_loadu_si128(((__m128i*)ter) + 1));\n        _mm_storeu_si128(((__m128i*)ter) + 1, squareErrorHigh);\n\n        // Taking the absolute value is way faster. The values are only used to sort, so the result will be the same.\n        error0 = _mm_abs_epi32(_mm_add_epi32(pix, g_table256_SIMD[2]));\n        error1 = _mm_abs_epi32(_mm_add_epi32(pix, g_table256_SIMD[3]));\n        error2 = _mm_abs_epi32(_mm_sub_epi32(pix, g_table256_SIMD[2]));\n        error3 = _mm_abs_epi32(_mm_sub_epi32(pix, g_table256_SIMD[3]));\n\n        index0 = _mm_and_si128(_mm_cmplt_epi32(error1, error0), _mm_set1_epi32(1));\n        minError0 = _mm_min_epi32(error0, error1);\n\n        index1 = _mm_sub_epi32(_mm_set1_epi32(2), _mm_cmplt_epi32(error3, error2));\n        minError1 = _mm_min_epi32(error2, error3);\n\n        __m128i minIndex1 = _mm_blendv_epi8(index0, index1, _mm_cmplt_epi32(minError1, minError0));\n        minError = _mm_min_epi32(minError0, minError1);\n\n        // Squaring the minimum error to produce correct values when adding\n        minErrorLow = _mm_shuffle_epi32(minError, _MM_SHUFFLE(1, 1, 0, 0));\n        squareErrorLow = _mm_mul_epi32(minErrorLow, minErrorLow);\n        squareErrorLow = _mm_add_epi64(squareErrorLow, _mm_loadu_si128(((__m128i*)ter) + 2));\n        _mm_storeu_si128(((__m128i*)ter) + 2, squareErrorLow);\n        minErrorHigh = _mm_shuffle_epi32(minError, _MM_SHUFFLE(3, 3, 2, 2));\n        squareErrorHigh = _mm_mul_epi32(minErrorHigh, minErrorHigh);\n        squareErrorHigh = _mm_add_epi64(squareErrorHigh, _mm_loadu_si128(((__m128i*)ter) + 3));\n        _mm_storeu_si128(((__m128i*)ter) + 3, squareErrorHigh);\n        __m128i minIndex = _mm_packs_epi32(minIndex0, minIndex1);\n        _mm_storeu_si128((__m128i*)sel, minIndex);\n#else\n        int pix = dr * 77 + dg * 151 + db * 28;\n\n        for( int t=0; t<8; t++ )\n        {\n            const int64* tab = g_table256[t];\n            uint idx = 0;\n            uint64 err = sq( tab[0] + pix );\n            for( int j=1; j<4; j++ )\n            {\n                uint64 local = sq( tab[j] + pix );\n                if( local < err )\n                {\n                    err = local;\n                    idx = j;\n                }\n            }\n            *sel++ = idx;\n            *ter++ += err;\n        }\n#endif\n    }\n}\n\n#ifdef __SSE4_1__\n// Non-reference implementation, but faster. Produces same results as the AVX2 version\nvoid FindBestFit( uint32 terr[2][8], uint16 tsel[16][8], v4i a[8], const uint32* id, const uint8* data )\n{\n    for( size_t i=0; i<16; i++ )\n    {\n        uint16* sel = tsel[i];\n        uint bid = id[i];\n        uint32* ter = terr[bid%2];\n\n        uint8 b = *data++;\n        uint8 g = *data++;\n        uint8 r = *data++;\n        data++;\n\n        int dr = a[bid][0] - r;\n        int dg = a[bid][1] - g;\n        int db = a[bid][2] - b;\n\n        // The scaling values are divided by two and rounded, to allow the differences to be in the range of signed int16\n        // This produces slightly different results, but is significant faster\n        __m128i pixel = _mm_set1_epi16(dr * 38 + dg * 76 + db * 14);\n        __m128i pix = _mm_abs_epi16(pixel);\n\n        // Taking the absolute value is way faster. The values are only used to sort, so the result will be the same.\n        // Since the selector table is symmetrical, we need to calculate the difference only for half of the entries.\n        __m128i error0 = _mm_abs_epi16(_mm_sub_epi16(pix, g_table128_SIMD[0]));\n        __m128i error1 = _mm_abs_epi16(_mm_sub_epi16(pix, g_table128_SIMD[1]));\n\n        __m128i index = _mm_and_si128(_mm_cmplt_epi16(error1, error0), _mm_set1_epi16(1));\n        __m128i minError = _mm_min_epi16(error0, error1);\n\n        // Exploiting symmetry of the selector table and use the sign bit\n        // This produces slightly different results, but is needed to produce same results as AVX2 implementation\n        __m128i indexBit = _mm_andnot_si128(_mm_srli_epi16(pixel, 15), _mm_set1_epi8(-1));\n        __m128i minIndex = _mm_or_si128(index, _mm_add_epi16(indexBit, indexBit));\n\n        // Squaring the minimum error to produce correct values when adding\n        __m128i squareErrorLo = _mm_mullo_epi16(minError, minError);\n        __m128i squareErrorHi = _mm_mulhi_epi16(minError, minError);\n\n        __m128i squareErrorLow = _mm_unpacklo_epi16(squareErrorLo, squareErrorHi);\n        __m128i squareErrorHigh = _mm_unpackhi_epi16(squareErrorLo, squareErrorHi);\n\n        squareErrorLow = _mm_add_epi32(squareErrorLow, _mm_loadu_si128(((__m128i*)ter) + 0));\n        _mm_storeu_si128(((__m128i*)ter) + 0, squareErrorLow);\n        squareErrorHigh = _mm_add_epi32(squareErrorHigh, _mm_loadu_si128(((__m128i*)ter) + 1));\n        _mm_storeu_si128(((__m128i*)ter) + 1, squareErrorHigh);\n\n        _mm_storeu_si128((__m128i*)sel, minIndex);\n    }\n}\n#endif\n\nuint8_t convert6(float f)\n{\n    int i = (std::min(std::max(static_cast<int>(f), 0), 1023) - 15) >> 1;\n    return (i + 11 - ((i + 11) >> 7) - ((i + 4) >> 7)) >> 3;\n}\n\nuint8_t convert7(float f)\n{\n    int i = (std::min(std::max(static_cast<int>(f), 0), 1023) - 15) >> 1;\n    return (i + 9 - ((i + 9) >> 8) - ((i + 6) >> 8)) >> 2;\n}\n\nstd::pair<uint64, uint64> Planar(const uint8* src)\n{\n    int32 r = 0;\n    int32 g = 0;\n    int32 b = 0;\n\n    for (int i = 0; i < 16; ++i)\n    {\n        b += src[i * 4 + 0];\n        g += src[i * 4 + 1];\n        r += src[i * 4 + 2];\n    }\n\n    int32 difRyz = 0;\n    int32 difGyz = 0;\n    int32 difByz = 0;\n    int32 difRxz = 0;\n    int32 difGxz = 0;\n    int32 difBxz = 0;\n\n    const int32 scaling[] = { -255, -85, 85, 255 };\n\n    for (int i = 0; i < 16; ++i)\n    {\n        int32 difB = (static_cast<int>(src[i * 4 + 0]) << 4) - b;\n        int32 difG = (static_cast<int>(src[i * 4 + 1]) << 4) - g;\n        int32 difR = (static_cast<int>(src[i * 4 + 2]) << 4) - r;\n\n        difRyz += difR * scaling[i % 4];\n        difGyz += difG * scaling[i % 4];\n        difByz += difB * scaling[i % 4];\n\n        difRxz += difR * scaling[i / 4];\n        difGxz += difG * scaling[i / 4];\n        difBxz += difB * scaling[i / 4];\n    }\n\n    const float scale = -4.0f / ((255 * 255 * 8.0f + 85 * 85 * 8.0f) * 16.0f);\n\n    float aR = difRxz * scale;\n    float aG = difGxz * scale;\n    float aB = difBxz * scale;\n\n    float bR = difRyz * scale;\n    float bG = difGyz * scale;\n    float bB = difByz * scale;\n\n    float dR = r * (4.0f / 16.0f);\n    float dG = g * (4.0f / 16.0f);\n    float dB = b * (4.0f / 16.0f);\n\n    // calculating the three colors RGBO, RGBH, and RGBV.  RGB = df - af * x - bf * y;\n    float cofR = std::fma(aR,  255.0f, std::fma(bR,  255.0f, dR));\n    float cofG = std::fma(aG,  255.0f, std::fma(bG,  255.0f, dG));\n    float cofB = std::fma(aB,  255.0f, std::fma(bB,  255.0f, dB));\n    float chfR = std::fma(aR, -425.0f, std::fma(bR,  255.0f, dR));\n    float chfG = std::fma(aG, -425.0f, std::fma(bG,  255.0f, dG));\n    float chfB = std::fma(aB, -425.0f, std::fma(bB,  255.0f, dB));\n    float cvfR = std::fma(aR,  255.0f, std::fma(bR, -425.0f, dR));\n    float cvfG = std::fma(aG,  255.0f, std::fma(bG, -425.0f, dG));\n    float cvfB = std::fma(aB,  255.0f, std::fma(bB, -425.0f, dB));\n\n    // convert to r6g7b6\n    int32 coR = convert6(cofR);\n    int32 coG = convert7(cofG);\n    int32 coB = convert6(cofB);\n    int32 chR = convert6(chfR);\n    int32 chG = convert7(chfG);\n    int32 chB = convert6(chfB);\n    int32 cvR = convert6(cvfR);\n    int32 cvG = convert7(cvfG);\n    int32 cvB = convert6(cvfB);\n\n    // Error calculation\n    auto ro0 = coR;\n    auto go0 = coG;\n    auto bo0 = coB;\n    auto ro1 = (ro0 >> 4) | (ro0 << 2);\n    auto go1 = (go0 >> 6) | (go0 << 1);\n    auto bo1 = (bo0 >> 4) | (bo0 << 2);\n    auto ro2 = (ro1 << 2) + 2;\n    auto go2 = (go1 << 2) + 2;\n    auto bo2 = (bo1 << 2) + 2;\n\n    auto rh0 = chR;\n    auto gh0 = chG;\n    auto bh0 = chB;\n    auto rh1 = (rh0 >> 4) | (rh0 << 2);\n    auto gh1 = (gh0 >> 6) | (gh0 << 1);\n    auto bh1 = (bh0 >> 4) | (bh0 << 2);\n\n    auto rh2 = rh1 - ro1;\n    auto gh2 = gh1 - go1;\n    auto bh2 = bh1 - bo1;\n\n    auto rv0 = cvR;\n    auto gv0 = cvG;\n    auto bv0 = cvB;\n    auto rv1 = (rv0 >> 4) | (rv0 << 2);\n    auto gv1 = (gv0 >> 6) | (gv0 << 1);\n    auto bv1 = (bv0 >> 4) | (bv0 << 2);\n\n    auto rv2 = rv1 - ro1;\n    auto gv2 = gv1 - go1;\n    auto bv2 = bv1 - bo1;\n\n    uint64 error = 0;\n\n    for (int i = 0; i < 16; ++i)\n    {\n        int32 cR = clampu8((rh2 * (i / 4) + rv2 * (i % 4) + ro2) >> 2);\n        int32 cG = clampu8((gh2 * (i / 4) + gv2 * (i % 4) + go2) >> 2);\n        int32 cB = clampu8((bh2 * (i / 4) + bv2 * (i % 4) + bo2) >> 2);\n\n        int32 difB = static_cast<int>(src[i * 4 + 0]) - cB;\n        int32 difG = static_cast<int>(src[i * 4 + 1]) - cG;\n        int32 difR = static_cast<int>(src[i * 4 + 2]) - cR;\n\n        int32 dif = difR * 38 + difG * 76 + difB * 14;\n\n        error += dif * dif;\n    }\n\n    /**/\n    uint32 rgbv = cvB | (cvG << 6) | (cvR << 13);\n    uint32 rgbh = chB | (chG << 6) | (chR << 13);\n    uint32 hi = rgbv | ((rgbh & 0x1FFF) << 19);\n    uint32 lo = (chR & 0x1) | 0x2 | ((chR << 1) & 0x7C);\n    lo |= ((coB & 0x07) <<  7) | ((coB & 0x18) <<  8) | ((coB & 0x20) << 11);\n    lo |= ((coG & 0x3F) << 17) | ((coG & 0x40) << 18);\n    lo |= coR << 25;\n\n    const auto idx = (coR & 0x20) | ((coG & 0x20) >> 1) | ((coB & 0x1E) >> 1);\n\n    lo |= g_flags[idx];\n\n    uint64 result = static_cast<uint32>(_bswap(lo));\n    result |= static_cast<uint64>(static_cast<uint32>(_bswap(hi))) << 32;\n\n    return std::make_pair(result, error);\n}\n\ntemplate<class T, class S>\nuint64 EncodeSelectors( uint64 d, const T terr[2][8], const S tsel[16][8], const uint32* id, const uint64 value, const uint64 error)\n{\n    size_t tidx[2];\n    tidx[0] = GetLeastError( terr[0], 8 );\n    tidx[1] = GetLeastError( terr[1], 8 );\n\n    if ((terr[0][tidx[0]] + terr[1][tidx[1]]) >= error)\n    {\n        return value;\n    }\n\n    d |= tidx[0] << 26;\n    d |= tidx[1] << 29;\n    for( int i=0; i<16; i++ )\n    {\n        uint64 t = tsel[i][tidx[id[i]%2]];\n        d |= ( t & 0x1 ) << ( i + 32 );\n        d |= ( t & 0x2 ) << ( i + 47 );\n    }\n\n    return FixByteOrder(d);\n}\n}\n\nuint64 ProcessRGB( const uint8* src )\n{\n    uint64 d = CheckSolid( src );\n    if( d != 0 ) return d;\n\n    v4i a[8];\n    uint err[4] = {};\n    PrepareAverages( a, src, err );\n    size_t idx = GetLeastError( err, 4 );\n    EncodeAverages( d, a, idx );\n\n#if defined __SSE4_1__ && !defined REFERENCE_IMPLEMENTATION\n    uint32 terr[2][8] = {};\n#else\n    uint64 terr[2][8] = {};\n#endif\n    uint16 tsel[16][8];\n    auto id = g_id[idx];\n    FindBestFit( terr, tsel, a, id, src );\n\n    return FixByteOrder( EncodeSelectors( d, terr, tsel, id ) );\n}\n\nuint64 ProcessRGB_ETC2( const uint8* src )\n{\n    auto result = Planar( src );\n\n    uint64 d = 0;\n\n    v4i a[8];\n    uint err[4] = {};\n    PrepareAverages( a, src, err );\n    size_t idx = GetLeastError( err, 4 );\n    EncodeAverages( d, a, idx );\n\n#if defined __SSE4_1__ && !defined REFERENCE_IMPLEMENTATION\n    uint32 terr[2][8] = {};\n#else\n    uint64 terr[2][8] = {};\n#endif\n    uint16 tsel[16][8];\n    auto id = g_id[idx];\n    FindBestFit( terr, tsel, a, id, src );\n\n    return EncodeSelectors( d, terr, tsel, id, result.first, result.second );\n}\n\ninline int NumberOfMipLevels(const v2i& size)\n{\n\treturn (int)floor(log2(std::max(size.x, size.y))) + 1;\n}\n\nBitmap::Bitmap(const v2i& size)\n\t: m_data(new uint32[size.x*size.y])\n\t, m_block(nullptr)\n\t, m_lines(1)\n\t, m_linesLeft(size.y / 4)\n\t, m_size(size)\n//\t, m_sema(0)\n{\n}\n\nBitmap::Bitmap(const Bitmap& src, uint lines)\n\t: m_lines(lines)\n\t, m_alpha(src.Alpha())\n//\t, m_sema(0)\n{\n}\n\nBitmap::Bitmap(const v2i& size, const void *pixelData, int pitch, uint lines)\n\t: m_data(nullptr)\n\t, m_block((uint32*)pixelData)\n\t, m_lines(lines)\n\t, m_linesLeft(size.y / 4)\n\t, m_size(size)\n//\t, m_sema(0)\n{\n\n}\n\nBitmap::~Bitmap()\n{\n\tdelete[] m_data;\n}\n\nconst uint32* Bitmap::NextBlock(uint& lines, bool& done)\n{\n//\tstd::lock_guard<std::mutex> lock(m_lock);\n\tlines = std::min(m_lines, m_linesLeft);\n\tauto ret = m_block;\n//\tm_sema.lock();\n\tm_block += m_size.x * 4 * lines;\n\tm_linesLeft -= lines;\n\tdone = m_linesLeft == 0;\n\treturn ret;\n}\n\nclass BitmapDownsampled : public Bitmap\n{\npublic:\n\tBitmapDownsampled(const Bitmap& bmp, uint lines);\n\t~BitmapDownsampled();\n};\n\nBitmapDownsampled::BitmapDownsampled(const Bitmap& bmp, uint lines)\n\t: Bitmap(bmp, lines)\n{\n\tm_size.x = std::max(1, bmp.Size().x / 2);\n\tm_size.y = std::max(1, bmp.Size().y / 2);\n\n\tint w = std::max(m_size.x, 4);\n\tint h = std::max(m_size.y, 4);\n\n//\tDBGPRINT(\"Subbitmap \" << m_size.x << \"x\" << m_size.y);\n\n\tm_block = m_data = new uint32[w*h];\n\n\tif (m_size.x < w || m_size.y < h)\n\t{\n\t\tmemset(m_data, 0, w*h*sizeof(uint32));\n\t\tm_linesLeft = h / 4;\n\t\tuint lines = 0;\n\t\tfor (int i = 0; i < h / 4; i++)\n\t\t{\n\t\t\tfor (int j = 0; j < 4; j++)\n\t\t\t{\n\t\t\t\tlines++;\n\t\t\t\tif (lines > m_lines)\n\t\t\t\t{\n\t\t\t\t\tlines = 0;\n\t\t\t\t//\tm_sema.unlock();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lines != 0)\n\t\t{\n\t\t//\tm_sema.unlock();\n\t\t}\n\t} else\n\t{\n\t\tm_linesLeft = h / 4;\n\t\tm_load = std::async(std::launch::async, [this, &bmp, w, h]() mutable\n\t\t{\n\t\t\tauto ptr = m_data;\n\t\t\tauto src1 = bmp.Data();\n\t\t\tauto src2 = src1 + bmp.Size().x;\n\t\t\tuint lines = 0;\n\t\t\tfor (int i = 0; i < h / 4; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < 4; j++)\n\t\t\t\t{\n\t\t\t\t\tfor (int k = 0; k < m_size.x; k++)\n\t\t\t\t\t{\n\t\t\t\t\t\tint r = ((*src1 & 0x000000FF) + (*(src1 + 1) & 0x000000FF) + (*src2 & 0x000000FF) + (*(src2 + 1) & 0x000000FF)) / 4;\n\t\t\t\t\t\tint g = (((*src1 & 0x0000FF00) + (*(src1 + 1) & 0x0000FF00) + (*src2 & 0x0000FF00) + (*(src2 + 1) & 0x0000FF00)) / 4) & 0x0000FF00;\n\t\t\t\t\t\tint b = (((*src1 & 0x00FF0000) + (*(src1 + 1) & 0x00FF0000) + (*src2 & 0x00FF0000) + (*(src2 + 1) & 0x00FF0000)) / 4) & 0x00FF0000;\n\t\t\t\t\t\tint a = (((((*src1 & 0xFF000000) >> 8) + ((*(src1 + 1) & 0xFF000000) >> 8) + ((*src2 & 0xFF000000) >> 8) + ((*(src2 + 1) & 0xFF000000) >> 8)) / 4) & 0x00FF0000) << 8;\n\t\t\t\t\t\t*ptr++ = r | g | b | a;\n\t\t\t\t\t\tsrc1 += 2;\n\t\t\t\t\t\tsrc2 += 2;\n\t\t\t\t\t}\n\t\t\t\t\tsrc1 += m_size.x * 2;\n\t\t\t\t\tsrc2 += m_size.x * 2;\n\t\t\t\t}\n\t\t\t\tlines++;\n\t\t\t\tif (lines >= m_lines)\n\t\t\t\t{\n\t\t\t\t\tlines = 0;\n\t\t\t\t//\tm_sema.unlock();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (lines != 0)\n\t\t\t{\n\t\t\t//\tm_sema.unlock();\n\t\t\t}\n\t\t});\n\t}\n}\n\nBitmapDownsampled::~BitmapDownsampled()\n{\n}\n\nstatic uint8 e5[32];\nstatic uint8 e6[64];\nstatic uint8 qrb[256 + 16];\nstatic uint8 qg[256 + 16];\n\nvoid InitDither()\n{\n\tfor (int i = 0; i < 32; i++)\n\t{\n\t\te5[i] = (i << 3) | (i >> 2);\n\t}\n\tfor (int i = 0; i < 64; i++)\n\t{\n\t\te6[i] = (i << 2) | (i >> 4);\n\t}\n\tfor (int i = 0; i < 256 + 16; i++)\n\t{\n\t\tint v = std::min(std::max(0, i - 8), 255);\n\t\tqrb[i] = e5[mul8bit(v, 31)];\n\t\tqg[i] = e6[mul8bit(v, 63)];\n\t}\n}\n\nvoid Dither(uint8* data)\n{\n\tint err[8];\n\tint* ep1 = err;\n\tint* ep2 = err + 4;\n\n\tfor (int ch = 0; ch < 3; ch++)\n\t{\n\t\tuint8* ptr = data + ch;\n\t\tuint8* quant = (ch == 1) ? qg + 8 : qrb + 8;\n\t\tmemset(err, 0, sizeof(err));\n\n\t\tfor (int y = 0; y < 4; y++)\n\t\t{\n\t\t\tuint8 tmp;\n\t\t\ttmp = quant[ptr[0] + ((3 * ep2[1] + 5 * ep2[0]) >> 4)];\n\t\t\tep1[0] = ptr[0] - tmp;\n\t\t\tptr[0] = tmp;\n\t\t\ttmp = quant[ptr[4] + ((7 * ep1[0] + 3 * ep2[2] + 5 * ep2[1] + ep2[0]) >> 4)];\n\t\t\tep1[1] = ptr[4] - tmp;\n\t\t\tptr[4] = tmp;\n\t\t\ttmp = quant[ptr[8] + ((7 * ep1[1] + 3 * ep2[3] + 5 * ep2[2] + ep2[1]) >> 4)];\n\t\t\tep1[2] = ptr[8] - tmp;\n\t\t\tptr[8] = tmp;\n\t\t\ttmp = quant[ptr[12] + ((7 * ep1[2] + 5 * ep2[3] + ep2[2]) >> 4)];\n\t\t\tep1[3] = ptr[12] - tmp;\n\t\t\tptr[12] = tmp;\n\t\t\tptr += 16;\n\t\t\tstd::swap(ep1, ep2);\n\t\t}\n\t}\n}\n\nvoid Swizzle(const uint8* data, const ptrdiff_t pitch, uint8* output)\n{\n\tfor (int i = 0; i < 4; ++i)\n\t{\n\t\tuint64 d0 = *(const uint64*)(data + i * pitch + 0);\n\t\tuint64 d1 = *(const uint64*)(data + i * pitch + 8);\n\n\t\t*(uint64*)(output + i * 16 + 0) = d0;\n\t\t*(uint64*)(output + i * 16 + 8) = d1;\n\t}\n}\n\nstatic int AdjustSizeForMipmaps(const v2i& size, int levels)\n{\n\tint len = 0;\n\tv2i current = size;\n\tfor (int i = 1; i < levels; i++)\n\t{\n\t\tassert(current.x != 1 || current.y != 1);\n\t\tcurrent.x = std::max(1, current.x / 2);\n\t\tcurrent.y = std::max(1, current.y / 2);\n\t\tlen += std::max(4, current.x) * std::max(4, current.y) / 2;\n\t}\n\tassert(current.x == 1 && current.y == 1);\n\treturn len;\n}\n\nstatic uint8* OpenForWriting(/*const char* fn,*/ size_t len, const v2i& size, /*FILE** f,*/ int levels)\n{\n\tauto ret = new uint8[len];\n\tauto dst = (uint32*)ret;\n\n\t*dst++ = 0x03525650;  // version\n\t*dst++ = 0;           // flags\n\t*dst++ = 6;           // pixelformat[0], value 22 is needed for etc2\n\t*dst++ = 0;           // pixelformat[1]\n\t*dst++ = 0;           // colourspace\n\t*dst++ = 0;           // channel type\n\t*dst++ = size.y;      // height\n\t*dst++ = size.x;      // width\n\t*dst++ = 1;           // depth\n\t*dst++ = 1;           // num surfs\n\t*dst++ = 1;           // num faces\n\t*dst++ = levels;      // mipmap count\n\t*dst++ = 0;           // metadata size\n\n\treturn ret;\n}\n\nstatic uint64 _f_rgb(uint8* ptr)\n{\n\treturn ProcessRGB(ptr);\n}\n\n#ifdef __SSE4_1__\nstatic uint64 _f_rgb_avx2(uint8* ptr)\n{\n\treturn ProcessRGB_AVX2(ptr);\n}\n#endif\n\nstatic uint64 _f_rgb_dither(uint8* ptr)\n{\n\tDither(ptr);\n\treturn ProcessRGB(ptr);\n}\n\n#ifdef __SSE4_1__\nstatic uint64 _f_rgb_dither_avx2(uint8* ptr)\n{\n\tDither(ptr);\n\treturn ProcessRGB_AVX2(ptr);\n}\n#endif\n\nstatic uint64 _f_rgb_etc2(uint8* ptr)\n{\n\treturn ProcessRGB_ETC2(ptr);\n}\n\n#ifdef __SSE4_1__\nstatic uint64 _f_rgb_etc2_avx2(uint8* ptr)\n{\n\treturn ProcessRGB_ETC2_AVX2(ptr);\n}\n#endif\n\nstatic uint64 _f_rgb_etc2_dither(uint8* ptr)\n{\n\tDither(ptr);\n\treturn ProcessRGB_ETC2(ptr);\n}\n\n#ifdef __SSE4_1__\nstatic uint64 _f_rgb_etc2_dither_avx2(uint8* ptr)\n{\n\tDither(ptr);\n\treturn ProcessRGB_ETC2_AVX2(ptr);\n}\n#endif\n\nnamespace\n{\n\tstruct BlockColor\n\t{\n\t\tuint32 r1, g1, b1;\n\t\tuint32 r2, g2, b2;\n\t};\n\n\tenum class Etc2Mode\n\t{\n\t\tnone,\n\t\tt,\n\t\th,\n\t\tplanar\n\t};\n\n\tEtc2Mode DecodeBlockColor(uint64 d, BlockColor& c)\n\t{\n\t\tif (d & 0x2)\n\t\t{\n\t\t\tint32 dr, dg, db;\n\n\t\t\tc.r1 = (d & 0xF8000000) >> 27;\n\t\t\tc.g1 = (d & 0x00F80000) >> 19;\n\t\t\tc.b1 = (d & 0x0000F800) >> 11;\n\n\t\t\tdr = (d & 0x07000000) >> 24;\n\t\t\tdg = (d & 0x00070000) >> 16;\n\t\t\tdb = (d & 0x00000700) >> 8;\n\n\t\t\tif (dr & 0x4)\n\t\t\t{\n\t\t\t\tdr |= 0xFFFFFFF8;\n\t\t\t}\n\t\t\tif (dg & 0x4)\n\t\t\t{\n\t\t\t\tdg |= 0xFFFFFFF8;\n\t\t\t}\n\t\t\tif (db & 0x4)\n\t\t\t{\n\t\t\t\tdb |= 0xFFFFFFF8;\n\t\t\t}\n\n\t\t\tint32 r = static_cast<int32_t>(c.r1) + dr;\n\t\t\tint32 g = static_cast<int32_t>(c.g1) + dg;\n\t\t\tint32 b = static_cast<int32_t>(c.b1) + db;\n\n\t\t\tif ((r < 0) || (r > 31))\n\t\t\t{\n\t\t\t\treturn Etc2Mode::t;\n\t\t\t}\n\n\t\t\tif ((g < 0) || (g > 31))\n\t\t\t{\n\t\t\t\treturn Etc2Mode::h;\n\t\t\t}\n\n\t\t\tif ((b < 0) || (b > 31))\n\t\t\t{\n\t\t\t\treturn Etc2Mode::planar;\n\t\t\t}\n\n\t\t\tc.r2 = c.r1 + dr;\n\t\t\tc.g2 = c.g1 + dg;\n\t\t\tc.b2 = c.b1 + db;\n\n\t\t\tc.r1 = (c.r1 << 3) | (c.r1 >> 2);\n\t\t\tc.g1 = (c.g1 << 3) | (c.g1 >> 2);\n\t\t\tc.b1 = (c.b1 << 3) | (c.b1 >> 2);\n\t\t\tc.r2 = (c.r2 << 3) | (c.r2 >> 2);\n\t\t\tc.g2 = (c.g2 << 3) | (c.g2 >> 2);\n\t\t\tc.b2 = (c.b2 << 3) | (c.b2 >> 2);\n\t\t} else\n\t\t{\n\t\t\tc.r1 = ((d & 0xF0000000) >> 24) | ((d & 0xF0000000) >> 28);\n\t\t\tc.r2 = ((d & 0x0F000000) >> 20) | ((d & 0x0F000000) >> 24);\n\t\t\tc.g1 = ((d & 0x00F00000) >> 16) | ((d & 0x00F00000) >> 20);\n\t\t\tc.g2 = ((d & 0x000F0000) >> 12) | ((d & 0x000F0000) >> 16);\n\t\t\tc.b1 = ((d & 0x0000F000) >> 8) | ((d & 0x0000F000) >> 12);\n\t\t\tc.b2 = ((d & 0x00000F00) >> 4) | ((d & 0x00000F00) >> 8);\n\t\t}\n\t\treturn Etc2Mode::none;\n\t}\n\n\tinline int32 expand6(uint32 value)\n\t{\n\t\treturn (value << 2) | (value >> 4);\n\t}\n\n\tinline int32 expand7(uint32 value)\n\t{\n\t\treturn (value << 1) | (value >> 6);\n\t}\n\n\tvoid DecodePlanar(uint64 block, uint32** l)\n\t{\n\t\tconst auto bv = expand6((block >> (0 + 32)) & 0x3F);\n\t\tconst auto gv = expand7((block >> (6 + 32)) & 0x7F);\n\t\tconst auto rv = expand6((block >> (13 + 32)) & 0x3F);\n\n\t\tconst auto bh = expand6((block >> (19 + 32)) & 0x3F);\n\t\tconst auto gh = expand7((block >> (25 + 32)) & 0x7F);\n\n\t\tconst auto rh0 = (block >> (32 - 32)) & 0x01;\n\t\tconst auto rh1 = ((block >> (34 - 32)) & 0x1F) << 1;\n\t\tconst auto rh = expand6(rh0 | rh1);\n\n\t\tconst auto bo0 = (block >> (39 - 32)) & 0x07;\n\t\tconst auto bo1 = ((block >> (43 - 32)) & 0x3) << 3;\n\t\tconst auto bo2 = ((block >> (48 - 32)) & 0x1) << 5;\n\t\tconst auto bo = expand6(bo0 | bo1 | bo2);\n\t\tconst auto go0 = (block >> (49 - 32)) & 0x3F;\n\t\tconst auto go1 = ((block >> (56 - 32)) & 0x01) << 6;\n\t\tconst auto go = expand7(go0 | go1);\n\t\tconst auto ro = expand6((block >> (57 - 32)) & 0x3F);\n\n\t\tfor (auto j = 0; j < 4; j++)\n\t\t{\n\t\t\tfor (auto i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tuint32 r = clampu8((i * (rh - ro) + j * (rv - ro) + 4 * ro + 2) >> 2);\n\t\t\t\tuint32 g = clampu8((i * (gh - go) + j * (gv - go) + 4 * go + 2) >> 2);\n\t\t\t\tuint32 b = clampu8((i * (bh - bo) + j * (bv - bo) + 4 * bo + 2) >> 2);\n\n\t\t\t\t*l[j]++ = r | (g << 8) | (b << 16) | 0xFF000000;\n\t\t\t}\n\t\t}\n\t}\n\n}\n\nstatic void DecodeBlock(uint64 d, uint32** l) {\n\td = ((d & 0xFF000000FF000000) >> 24) |\n\t\t((d & 0x000000FF000000FF) << 24) |\n\t\t((d & 0x00FF000000FF0000) >> 8) |\n\t\t((d & 0x0000FF000000FF00) << 8);\n\n\tBlockColor c;\n\tconst auto mode = DecodeBlockColor(d, c);\n\n\tif (mode == Etc2Mode::planar)\n\t{\n\t\tDecodePlanar(d, l);\n\t\treturn;\n\t}\n\n\tuint tcw[2];\n\ttcw[0] = (d & 0xE0) >> 5;\n\ttcw[1] = (d & 0x1C) >> 2;\n\n\tuint ra, ga, ba;\n\tuint rb, gb, bb;\n\tuint rc, gc, bc;\n\tuint rd, gd, bd;\n\n\tif (d & 0x1) {\n\t\tint o = 0;\n\t\tfor (int i = 0; i < 4; i++)\n\t\t{\n\t\t\tra = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tga = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tba = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\n\t\t\trb = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tgb = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tbb = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\n\t\t\trc = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tgc = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tbc = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\n\t\t\trd = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tgd = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tbd = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\n\t\t\t*l[0]++ = ra | (ga << 8) | (ba << 16) | 0xFF000000;\n\t\t\t*l[1]++ = rb | (gb << 8) | (bb << 16) | 0xFF000000;\n\t\t\t*l[2]++ = rc | (gc << 8) | (bc << 16) | 0xFF000000;\n\t\t\t*l[3]++ = rd | (gd << 8) | (bd << 16) | 0xFF000000;\n\n\t\t\to += 4;\n\t\t}\n\t} else {\n\t\tint o = 0;\n\t\tfor (int i = 0; i < 2; i++)\n\t\t{\n\t\t\tra = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tga = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tba = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\n\t\t\trb = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tgb = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tbb = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\n\t\t\trc = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tgc = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tbc = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\n\t\t\trd = clampu8(c.r1 + g_table[tcw[0]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tgd = clampu8(c.g1 + g_table[tcw[0]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tbd = clampu8(c.b1 + g_table[tcw[0]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\n\t\t\t*l[0]++ = ra | (ga << 8) | (ba << 16) | 0xFF000000;\n\t\t\t*l[1]++ = rb | (gb << 8) | (bb << 16) | 0xFF000000;\n\t\t\t*l[2]++ = rc | (gc << 8) | (bc << 16) | 0xFF000000;\n\t\t\t*l[3]++ = rd | (gd << 8) | (bd << 16) | 0xFF000000;\n\n\t\t\to += 4;\n\t\t}\n\t\tfor (int i = 0; i < 2; i++)\n\t\t{\n\t\t\tra = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tga = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\t\t\tba = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 32))) >> (o + 32)) | ((d & (1ll << (o + 48))) >> (o + 47))]);\n\n\t\t\trb = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tgb = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\t\t\tbb = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 33))) >> (o + 33)) | ((d & (1ll << (o + 49))) >> (o + 48))]);\n\n\t\t\trc = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tgc = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\t\t\tbc = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 34))) >> (o + 34)) | ((d & (1ll << (o + 50))) >> (o + 49))]);\n\n\t\t\trd = clampu8(c.r2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tgd = clampu8(c.g2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\t\t\tbd = clampu8(c.b2 + g_table[tcw[1]][((d & (1ll << (o + 35))) >> (o + 35)) | ((d & (1ll << (o + 51))) >> (o + 50))]);\n\n\t\t\t*l[0]++ = ra | (ga << 8) | (ba << 16) | 0xFF000000;\n\t\t\t*l[1]++ = rb | (gb << 8) | (bb << 16) | 0xFF000000;\n\t\t\t*l[2]++ = rc | (gc << 8) | (bc << 16) | 0xFF000000;\n\t\t\t*l[3]++ = rd | (gd << 8) | (bd << 16) | 0xFF000000;\n\n\t\t\to += 4;\n\t\t}\n\t}\n}\n\nstatic void DecodeAlphaBlock(const unsigned char* data, uint8** l) {\n\tint alpha = data[0];\n\tint table = data[1];\n\n\tint bit = 0;\n\tint byte = 2;\n\t//extract an alpha value for each pixel.\n\tfor (int x = 0; x < 4; x++) {\n\t\tfor (int y = 0; y < 4; y++) {\n\t\t\t//Extract table index\n\t\t\tint index = 0;\n\t\t\tfor (int bitpos = 0; bitpos < 3; bitpos++)\n\t\t\t{\n\t\t\t\tindex |= getbit(data[byte], 7 - bit, 2 - bitpos);\n\t\t\t\tbit++;\n\t\t\t\tif (bit > 7) {\n\t\t\t\t\tbit = 0;\n\t\t\t\t\tbyte++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tl[y][x * 4] = clampu8(alpha + alphaTable[table][index]);\n\t\t}\n\t}\n\tl[0] += 16;\n\tl[1] += 16;\n\tl[2] += 16;\n\tl[3] += 16;\n}\n\nvoid decode(const void *data, void* pixel, int pitch, int h, int blkw, int blkh)\n{\n\tint dpitch = pitch;\n\tuint32 *ret = (uint32 *)pixel;\n\tuint32* l[4];\n\tl[0] = ret;\n\tl[1] = l[0] + blkw * 4;\n\tl[2] = l[1] + blkw * 4;\n\tl[3] = l[2] + blkw * 4;\n\n\tconst uint64* src = (const uint64*)data;\n\tif (h & 3) --blkh;\n\tfor (int y = 0; y < blkh; y++)\n\t{\n\t\tfor (int x = 0; x < blkw; x++)\n\t\t{\n\t\t\tDecodeBlock(*src++, l);\n\t\t}\n\n\t\tl[0] += dpitch * 3;\n\t\tl[1] += dpitch * 3;\n\t\tl[2] += dpitch * 3;\n\t\tl[3] += dpitch * 3;\n\t}\n\tif (h & 3)\n\t{\n\t\th &= 3;\n\t\tstd::vector<uint32> dummy; dummy.resize(blkw * 4);\n\t\tfor (int y = 0; y < h; ++y) {\n\t\t\tl[3 - y] = &dummy.front();\n\t\t}\n\t\tfor (int x = 0; x < blkw; x++)\n\t\t{\n\t\t\tDecodeBlock(*src++, l);\n\t\t}\n\t}\n}\n\nvoid decodeWithAlpha(const void *data, void* pixel, int pitch, int h, int blkw, int blkh)\n{\n\tsetupAlphaTable();\n\tint dpitch = pitch;\n\tuint32 *ret = (uint32 *)pixel;\n\tuint32* l[4]; uint8* la[4];\n\tl[0] = ret;\n\tl[1] = l[0] + blkw * 4;\n\tl[2] = l[1] + blkw * 4;\n\tl[3] = l[2] + blkw * 4;\n\tla[0] = ((uint8*)ret) + 3;\n\tla[1] = la[0] + blkw * 4 * 4;\n\tla[2] = la[1] + blkw * 4 * 4;\n\tla[3] = la[2] + blkw * 4 * 4;\n\n\tconst uint64* src = (const uint64*)data;\n\tif (h & 3) --blkh;\n\tfor (int y = 0; y < blkh; y++)\n\t{\n\t\tfor (int x = 0; x < blkw; x++)\n\t\t{\n\t\t\tconst unsigned char *a = (const unsigned char *)src++;\n\t\t\tDecodeBlock(*src++, l);\n\t\t\tDecodeAlphaBlock(a, la);\n\t\t}\n\n\t\tl[0] += dpitch * 3;\n\t\tl[1] += dpitch * 3;\n\t\tl[2] += dpitch * 3;\n\t\tl[3] += dpitch * 3;\n\t\tla[0] += dpitch * 3;\n\t\tla[1] += dpitch * 3;\n\t\tla[2] += dpitch * 3;\n\t\tla[3] += dpitch * 3;\n\t}\n\tif (h & 3)\n\t{\n\t\th &= 3;\n\t\tstd::vector<uint32> dummy; dummy.resize(blkw * 4);\n\t\tfor (int y = 0; y < h; ++y) {\n\t\t\tl[3 - y] = &dummy.front();\n\t\t\tla[3 - y] = (uint8*)&dummy.front();\n\t\t}\n\t\tfor (int x = 0; x < blkw; x++)\n\t\t{\n\t\t\tconst unsigned char *a = (const unsigned char *)src++;\n\t\t\tDecodeBlock(*src++, l);\n\t\t\tDecodeAlphaBlock(a, la);\n\t\t}\n\t}\n}\n\nvoid* convert(const void *_pixel, int w, int h, int pitch, bool etc2, size_t &datalen)\n{\n\ttjs_uint32 *pixel = (tjs_uint32 *)TJSAlignedAlloc(pitch * h, 4);\n\tTVPReverseRGB(pixel, (const tjs_uint32 *)_pixel, pitch * h / 4);\n\tint blkw = w / 4, blkh = h / 4;\n\tint edgew = w % 4, edgeh = h % 4;\n\tint dpitch = (blkw + !!edgew) * 8;\n\tdatalen = dpitch * (blkh + !!edgeh);\n\tuint8* data = new uint8[datalen];\n\tuint8 *src = (uint8 *)pixel, *dst = data;\n\tfor (int blky = 0; blky < blkh; ++blky) {\n\t\tuint8* sline = src, *dline = dst;\n\t\tfor (int blkx = 0; blkx < blkw; ++blkx) {\n\t\t\tuint32 buf[4 * 4];\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < 4; ++y) {\n\t\t\t\tfor (int x = 0; x < 4; ++x) {\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t\tsline += 16;\n\t\t\tdline += 8;\n\t\t}\n\t\tsrc += pitch * 4;\n\t\tdst += dpitch;\n\t}\n\tif (edgew) {\n\t\tuint8* sline = ((uint8 *)pixel) + blkw * 16, *dline = data + blkw * 8;\n\t\tfor (int blky = 0; blky < blkh; ++blky) {\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < 4; ++y) {\n\t\t\t\tfor (int x = 0; x < edgew; ++x) {\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\t*(uint64*)(dline) = _f_rgb_etc2((uint8*)buf);\n\t\t\tsline += pitch * 4;\n\t\t\tdline += dpitch;\n\t\t}\n\t}\n\tif (edgeh) {\n\t\tuint8* sline = ((uint8 *)pixel) + blkh * pitch * 4, *dline = data + blkh * dpitch;\n\t\tfor (int blkx = 0; blkx < blkw; ++blkx) {\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < edgeh; ++y) {\n\t\t\t\tfor (int x = 0; x < 4; ++x) {\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t\tsline += 16;\n\t\t\tdline += 8;\n\t\t}\n\t\tif (edgew) {\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < edgeh; ++y) {\n\t\t\t\tfor (int x = 0; x < edgew; ++x) {\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t}\n\t}\n\tTJSAlignedDealloc(pixel);\n\treturn data;\n#if 0\n\tint nThread = TVPGetThreadNum() - 1; // don't use main thread if possible\n\tif (nThread < 1) nThread = 1;\n\telse if (nThread > num) nThread = num;\n\tTVPExecThreadTask(nThread, [&](int n) {\n\t\tfor (int i = n; i < data.size(); i += nThread) {\n\t\t\tDataPart& part = data[i];\n\t\t\tbool dither = false;\n\t\t\tbd->Process(part.src, part.width / 4 * part.lines, part.offset, part.width, Channels::RGB, dither, etc2);\n\t\t}\n\t});\n\tvoid* pixeldata = bd->Detach(datalen);\n//\tv2i size = dp.ImageData().Size();\n\n\tbd.reset();\n\treturn pixeldata;\n#endif\n}\n\nvoid* convertWithAlpha(const void *_pixel, int w, int h, int pitch, size_t &datalen)\n{\n\tsetupAlphaTable();\n\ttjs_uint32 *pixel = (tjs_uint32 *)TJSAlignedAlloc(pitch * h, 4);\n\tTVPReverseRGB(pixel, (const tjs_uint32 *)_pixel, pitch * h / 4);\n\tint blkw = w / 4, blkh = h / 4;\n\tint edgew = w % 4, edgeh = h % 4;\n\tint dpitch = (blkw + !!edgew) * 16;\n\tdatalen = dpitch * (blkh + !!edgeh);\n\tuint8* data = new uint8[datalen];\n\tuint8 *src = (uint8 *)pixel, *dst = data;\n\tfor (int blky = 0; blky < blkh; ++blky) {\n\t\tuint8* sline = src, *dline = dst;\n\t\tfor (int blkx = 0; blkx < blkw; ++blkx) {\n\t\t\tuint8 abuf[4 * 4];\n\t\t\tuint32 buf[4 * 4];\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < 4; ++y) {\n\t\t\t\tfor (int x = 0; x < 4; ++x) {\n\t\t\t\t\tabuf[x * 4 + y] = line[x * 4 + 3];\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\tcompressBlockAlphaFast(abuf, dline);\n\t\t\tdline += 8;\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t\tdline += 8;\n\t\t\tsline += 16;\n\t\t}\n\t\tsrc += pitch * 4;\n\t\tdst += dpitch;\n\t}\n\tif (edgew) {\n\t\tuint8* sline = ((uint8 *)pixel) + blkw * 16, *dline = data + blkw * 16;\n\t\tfor (int blky = 0; blky < blkh; ++blky) {\n\t\t\tuint8 abuf[4 * 4] = { 0 };\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < 4; ++y) {\n\t\t\t\tfor (int x = 0; x < edgew; ++x) {\n\t\t\t\t\tabuf[x * 4 + y] = line[x * 4 + 3];\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\tcompressBlockAlphaFast(abuf, dline);\n\t\t\t*(uint64*)(dline + 8) = _f_rgb_etc2((uint8*)buf);\n\t\t\tdline += dpitch;\n\t\t\tsline += pitch * 4;\n\t\t}\n\t}\n\tif (edgeh) {\n\t\tuint8* sline = ((uint8 *)pixel) + blkh * pitch * 4, *dline = data + blkh * dpitch;\n\t\tfor (int blkx = 0; blkx < blkw; ++blkx) {\n\t\t\tuint8 abuf[4 * 4] = { 0 };\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < edgeh; ++y) {\n\t\t\t\tfor (int x = 0; x < 4; ++x) {\n\t\t\t\t\tabuf[x * 4 + y] = line[x * 4 + 3];\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\tcompressBlockAlphaFast(abuf, dline);\n\t\t\tdline += 8;\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t\tdline += 8;\n\t\t\tsline += 16;\n\t\t}\n\t\tif (edgew) {\n\t\t\tuint8 abuf[4 * 4] = { 0 };\n\t\t\tuint32 buf[4 * 4] = { 0 };\n\t\t\tuint8* line = sline;\n\t\t\tfor (int y = 0; y < edgeh; ++y) {\n\t\t\t\tfor (int x = 0; x < edgew; ++x) {\n\t\t\t\t\tabuf[x * 4 + y] = line[x * 4 + 3];\n\t\t\t\t\tbuf[x * 4 + y] = *(uint32*)(line + x * 4);\n\t\t\t\t}\n\t\t\t\tline += pitch;\n\t\t\t}\n\t\t\tcompressBlockAlphaFast(abuf, dline);\n\t\t\tdline += 8;\n\t\t\t*(uint64*)dline = _f_rgb_etc2((uint8*)buf);\n\t\t}\n\t}\n\t\n\tTJSAlignedDealloc(pixel);\n\treturn data;\n}\n\n}"
  },
  {
    "path": "src/core/visual/ogl/etcpak.h",
    "content": "#pragma once\n#include <functional>\n\n// from https://bitbucket.org/wolfpld/etcpak.git\n\nnamespace ETCPacker {\n\tvoid* convert(const void *pixel, int w, int h, int pitch, bool etc2, size_t &datalen);\n\tvoid* convertWithAlpha(const void *pixel, int w, int h, int pitch, size_t &datalen);\n\tvoid decode(const void *data, void* pixel, int pitch, int h, int blkw, int blkh);\n\tvoid decodeWithAlpha(const void *data, void* pixel, int pitch, int h, int blkw, int blkh);\n}\n"
  },
  {
    "path": "src/core/visual/ogl/imagepacker.cpp",
    "content": "#include \"imagepacker.h\"\n#include <vector>\n#include <algorithm>\n#include <memory.h>\n\nusing namespace std;\n\nnamespace ImagePacker {\n\nbool area(rect_xywhf* a, rect_xywhf* b) {\n\treturn a->area() > b->area();\n}\n\nbool perimeter(rect_xywhf* a, rect_xywhf* b) {\n\treturn a->perimeter() > b->perimeter();\n}\n\nbool max_side(rect_xywhf* a, rect_xywhf* b) {\n\treturn std::max(a->w, a->h) > std::max(b->w, b->h);\n}\n\nbool max_width(rect_xywhf* a, rect_xywhf* b) {\n\treturn a->w > b->w;\n}\n\nbool max_height(rect_xywhf* a, rect_xywhf* b) {\n\treturn a->h > b->h;\n}\n\n\n// just add another comparing function name to cmpf to perform another packing attempt\n// more functions == slower but probably more efficient cases covered and hence less area wasted\n\nstatic bool(*cmpf[])(rect_xywhf*, rect_xywhf*) = {\n\tarea,\n\tperimeter,\n\tmax_side,\n\tmax_width,\n\tmax_height\n};\n\n// if you find the algorithm running too slow you may double this factor to increase speed but also decrease efficiency\n// 1 == most efficient, slowest\n// efficiency may be still satisfying at 64 or even 256 with nice speedup\n\nint discard_step = 128;\n\n/*\n\nFor every sorting function, algorithm will perform packing attempts beginning with a bin with width and height equal to max_side,\nand decreasing its dimensions if it finds out that rectangles did actually fit, increasing otherwise.\nAlthough, it's doing that in sort of binary search manner, so for every comparing function it will perform at most log2(max_side) packing attempts looking for the smallest possible bin size.\ndiscard_step = 128 means that the algorithm will break of the searching loop if the rectangles fit but \"it may be possible to fit them in a bin smaller by 128\"\nthe bigger the value, the sooner the algorithm will finish but the rectangles will be packed less tightly.\nuse discard_step = 1 for maximum tightness.\n\nthe algorithm was based on http://www.blackpawn.com/texts/lightmaps/default.html\nthe algorithm reuses the node tree so it doesn't reallocate them between searching attempts\n\n*/\n\n/*************************************************************************** CHAOS BEGINS HERE */\n\nstruct node {\n\tstruct pnode {\n\t\tnode* pn;\n\t\tbool fill;\n\n\t\tpnode() : fill(false), pn(0) {}\n\t\tvoid set(int l, int t, int r, int b) {\n\t\t\tif (!pn) pn = new node(rect_ltrb(l, t, r, b));\n\t\t\telse {\n\t\t\t\t(*pn).rc = rect_ltrb(l, t, r, b);\n\t\t\t\t(*pn).id = false;\n\t\t\t}\n\t\t\tfill = true;\n\t\t}\n\t};\n\n\tpnode c[2];\n\trect_ltrb rc;\n\tbool id;\n\tnode(rect_ltrb rc = rect_ltrb()) : id(false), rc(rc) {}\n\n\tvoid reset(const rect_wh& r) {\n\t\tid = false;\n\t\trc = rect_ltrb(0, 0, r.w, r.h);\n\t\tdelcheck();\n\t}\n\n\tnode* insert(rect_xywhf& img) {\n\t\tif (c[0].pn && c[0].fill) {\n\t\t\tnode* newn;\n\t\t\tif (newn = c[0].pn->insert(img)) return newn;\n\t\t\treturn    c[1].pn->insert(img);\n\t\t}\n\n\t\tif (id) return 0;\n\t\tint f = img.fits(rect_xywh(rc));\n\n\t\tswitch (f) {\n\t\tcase 0: return 0;\n// \t\tcase 1: img.flipped = false; break;\n// \t\tcase 2: img.flipped = true; break;\n\t\tcase 3: id = true; /*img.flipped = false;*/ return this;\n\t\tcase 4: id = true; /*img.flipped = true; */ return this;\n\t\t}\n\n\t\tint iw = img.w, ih = img.h;\n//\t\tint iw = (img.flipped ? img.h : img.w), ih = (img.flipped ? img.w : img.h);\n\n\t\tif (rc.w() - iw > rc.h() - ih) {\n\t\t\tc[0].set(rc.l, rc.t, rc.l + iw, rc.b);\n\t\t\tc[1].set(rc.l + iw, rc.t, rc.r, rc.b);\n\t\t} else {\n\t\t\tc[0].set(rc.l, rc.t, rc.r, rc.t + ih);\n\t\t\tc[1].set(rc.l, rc.t + ih, rc.r, rc.b);\n\t\t}\n\n\t\treturn c[0].pn->insert(img);\n\t}\n\n\tvoid delcheck() {\n\t\tif (c[0].pn) { c[0].fill = false; c[0].pn->delcheck(); }\n\t\tif (c[1].pn) { c[1].fill = false; c[1].pn->delcheck(); }\n\t}\n\n\t~node() {\n\t\tif (c[0].pn) delete c[0].pn;\n\t\tif (c[1].pn) delete c[1].pn;\n\t}\n};\n\nrect_wh _rect2D(rect_xywhf* const * v, int n, int max_s, vector<rect_xywhf*>& succ, vector<rect_xywhf*>& unsucc) {\n\tnode root;\n\n\tconst int funcs = (sizeof(cmpf) / sizeof(bool(*)(rect_xywhf*, rect_xywhf*)));\n\n\trect_xywhf** order[funcs];\n\n\tfor (int f = 0; f < funcs; ++f) {\n\t\torder[f] = new rect_xywhf*[n];\n\t\tmemcpy(order[f], v, sizeof(rect_xywhf*) * n);\n\t\tsort(order[f], order[f] + n, cmpf[f]);\n\t}\n\n\trect_wh min_bin = rect_wh(max_s, max_s);\n\tint min_func = -1, best_func = 0, best_area = 0, _area = 0, step, fit, i;\n\n\tbool fail = false;\n\n\tfor (int f = 0; f < funcs; ++f) {\n\t\tv = order[f];\n\t\tstep = min_bin.w / 2;\n\t\troot.reset(min_bin);\n\n\t\twhile (true) {\n\t\t\tif (root.rc.w() > min_bin.w) {\n\t\t\t\tif (min_func > -1) break;\n\t\t\t\t_area = 0;\n\n\t\t\t\troot.reset(min_bin);\n\t\t\t\tfor (i = 0; i < n; ++i)\n\t\t\t\t\tif (root.insert(*v[i]))\n\t\t\t\t\t\t_area += v[i]->area();\n\n\t\t\t\tfail = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfit = -1;\n\n\t\t\tfor (i = 0; i < n; ++i)\n\t\t\t\tif (!root.insert(*v[i])) {\n\t\t\t\t\tfit = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\tif (fit == -1 && step <= discard_step)\n\t\t\t\tbreak;\n\n\t\t\troot.reset(rect_wh(root.rc.w() + fit*step, root.rc.h() + fit*step));\n\n\t\t\tstep /= 2;\n\t\t\tif (!step)\n\t\t\t\tstep = 1;\n\t\t}\n\n\t\tif (!fail && (min_bin.area() >= root.rc.area())) {\n\t\t\tmin_bin = rect_wh(root.rc);\n\t\t\tmin_func = f;\n\t\t}\n\n\t\telse if (fail && (_area > best_area)) {\n\t\t\tbest_area = _area;\n\t\t\tbest_func = f;\n\t\t}\n\t\tfail = false;\n\t}\n\n\tv = order[min_func == -1 ? best_func : min_func];\n\n\tint clip_x = 0, clip_y = 0;\n\tnode* ret;\n\n\troot.reset(min_bin);\n\n\tfor (i = 0; i < n; ++i) {\n\t\tif (ret = root.insert(*v[i])) {\n\t\t\tv[i]->x = ret->rc.l;\n\t\t\tv[i]->y = ret->rc.t;\n\n// \t\t\tif (v[i]->flipped) {\n// \t\t\t\tv[i]->flipped = false;\n// \t\t\t\tv[i]->flip();\n// \t\t\t}\n\n\t\t\tclip_x = std::max(clip_x, ret->rc.r);\n\t\t\tclip_y = std::max(clip_y, ret->rc.b);\n\n\t\t\tsucc.push_back(v[i]);\n\t\t} else {\n\t\t\tunsucc.push_back(v[i]);\n\n//\t\t\tv[i]->flipped = false;\n\t\t}\n\t}\n\n\tfor (int f = 0; f < funcs; ++f)\n\t\tdelete[] order[f];\n\n\treturn rect_wh(clip_x, clip_y);\n}\n\n\nbool pack(rect_xywhf* const * v, int n, int max_s, vector<bin>& bins) {\n\trect_wh _rect(max_s, max_s);\n\n\tfor (int i = 0; i < n; ++i)\n\t\tif (!v[i]->fits(_rect)) return false;\n\n\tvector<rect_xywhf*> vec[2], *p[2] = { vec, vec + 1 };\n\tvec[0].resize(n);\n\tvec[1].clear();\n\tmemcpy(&vec[0][0], v, sizeof(rect_xywhf*)*n);\n\n\tbin* b = 0;\n\n\twhile (true) {\n\t\tbins.push_back(bin());\n\t\tb = &bins[bins.size() - 1];\n\n\t\tb->size = _rect2D(&((*p[0])[0]), p[0]->size(), max_s, b->rects, *p[1]);\n\t\tb->rects.shrink_to_fit();\n\t\tp[0]->clear();\n\n\t\tif (!p[1]->size()) break;\n\n\t\tstd::swap(p[0], p[1]);\n\t}\n\n\treturn true;\n}\n\n\nrect_wh::rect_wh(const rect_ltrb& rr) : w(rr.w()), h(rr.h()) {}\nrect_wh::rect_wh(const rect_xywh& rr) : w(rr.w), h(rr.h) {}\nrect_wh::rect_wh(int w, int h) : w(w), h(h) {}\n\nint rect_wh::fits(const rect_wh& r) const {\n\tif (w == r.w && h == r.h) return 3;\n//\tif (h == r.w && w == r.h) return 4;\n\tif (w <= r.w && h <= r.h) return 1;\n//\tif (h <= r.w && w <= r.h) return 2;\n\treturn 0;\n}\n\nrect_ltrb::rect_ltrb() : l(0), t(0), r(0), b(0) {}\nrect_ltrb::rect_ltrb(int l, int t, int r, int b) : l(l), t(t), r(r), b(b) {}\n\nint rect_ltrb::w() const {\n\treturn r - l;\n}\n\nint rect_ltrb::h() const {\n\treturn b - t;\n}\n\nint rect_ltrb::area() const {\n\treturn w()*h();\n}\n\nint rect_ltrb::perimeter() const {\n\treturn 2 * w() + 2 * h();\n}\n\nvoid rect_ltrb::w(int ww) {\n\tr = l + ww;\n}\n\nvoid rect_ltrb::h(int hh) {\n\tb = t + hh;\n}\n\nrect_xywh::rect_xywh() : x(0), y(0) {}\nrect_xywh::rect_xywh(const rect_ltrb& rc) : x(rc.l), y(rc.t) { b(rc.b); r(rc.r); }\nrect_xywh::rect_xywh(int x, int y, int w, int h) : x(x), y(y), rect_wh(w, h) {}\n\nrect_xywh::operator rect_ltrb() {\n\trect_ltrb rr(x, y, 0, 0);\n\trr.w(w); rr.h(h);\n\treturn rr;\n}\n\nint rect_xywh::r() const {\n\treturn x + w;\n};\n\nint rect_xywh::b() const {\n\treturn y + h;\n}\n\nvoid rect_xywh::r(int right) {\n\tw = right - x;\n}\n\nvoid rect_xywh::b(int bottom) {\n\th = bottom - y;\n}\n\nint rect_wh::area() {\n\treturn w*h;\n}\n\nint rect_wh::perimeter() {\n\treturn 2 * w + 2 * h;\n}\n\n\nrect_xywhf::rect_xywhf(const rect_ltrb& rr) : rect_xywh(rr)/*, flipped(false)*/ {}\nrect_xywhf::rect_xywhf(int x, int y, int width, int height) : rect_xywh(x, y, width, height)/*, flipped(false)*/ {}\nrect_xywhf::rect_xywhf() /*: flipped(false)*/ {}\n\n// void rect_xywhf::flip() {\n// \tflipped = !flipped;\n// \tstd::swap(w, h);\n// }\n\n}"
  },
  {
    "path": "src/core/visual/ogl/imagepacker.h",
    "content": "#ifndef IMAGEPACKER_H\n#define IMAGEPACKER_H\n\n// from https://github.com/TeamHypersomnia/rectpack2D\n\n#include <vector>\n#include \"ComplexRect.h\"\n\nnamespace ImagePacker {\n\n/* of your interest:\n\n1. rect_xywhf - structure representing your rectangle object\nmembers:\nint x, y, w, h;\nbool flipped;\n\n2. bin - structure representing resultant bin object\n3. bool pack(rect_xywhf* const * v, int n, int max_side, std::vector<bin>& bins) - actual packing function\nArguments:\ninput/output: v - pointer to array of pointers to your rectangles (const here means that the pointers will point to the same rectangles after the call)\ninput: n - rectangles count\n\ninput: max_side - maximum bins' side - algorithm works with square bins (in the end it may trim them to rectangular form).\nfor the algorithm to finish faster, pass a reasonable value (unreasonable would be passing 1 000 000 000 for packing 4 50x50 rectangles).\noutput: bins - vector to which the function will push_back() created bins, each of them containing vector to pointers of rectangles from \"v\" belonging to that particular bin.\nEvery bin also keeps information about its width and height of course, none of the dimensions is bigger than max_side.\n\nreturns true on success, false if one of the rectangles' dimension was bigger than max_side\n\nYou want to your rectangles representing your textures/glyph objects with GL_MAX_TEXTURE_SIZE as max_side,\nthen for each bin iterate through its rectangles, typecast each one to your own structure (or manually add userdata) and then memcpy its pixel contents (rotated by 90 degrees if \"flipped\" rect_xywhf's member is true)\nto the array representing your texture atlas to the place specified by the rectangle, then finally upload it with glTexImage2D.\n\nAlgorithm doesn't create any new rectangles.\nYou just pass an array of pointers - rectangles' x/y/w/h/flipped are modified in place.\nThere is a vector of pointers for every resultant bin to let you know which ones belong to the particular bin.\nThe algorithm may swap the w and h fields for the sake of better fitting, the flag \"flipped\" will be set to true whenever this occurs.\n\nFor description how to tune the algorithm and how it actually works see the .cpp file.\n\n\n*/\n\nstruct rect_ltrb;\nstruct rect_xywh;\n\nstruct rect_wh {\n\trect_wh(const rect_ltrb&);\n\trect_wh(const rect_xywh&);\n\trect_wh(int w = 0, int h = 0);\n\tint w, h, area(), perimeter(),\n\t\tfits(const rect_wh& bigger) const; // 0 - no, 1 - yes, 2 - flipped, 3 - perfectly, 4 perfectly flipped\n};\n\n// rectangle implementing left/top/right/bottom behaviour\n\nstruct rect_ltrb {\n\trect_ltrb();\n\trect_ltrb(int left, int top, int right, int bottom);\n\tint l, t, r, b, w() const, h() const, area() const, perimeter() const;\n\tvoid w(int), h(int);\n};\n\nstruct rect_xywh : public rect_wh {\n\trect_xywh();\n\trect_xywh(const rect_ltrb&);\n\trect_xywh(int x, int y, int width, int height);\n\toperator rect_ltrb();\n\n\tint x, y, r() const, b() const;\n\tvoid r(int), b(int);\n};\n\nstruct rect_xywhf : public rect_xywh {\n\trect_xywhf(const rect_ltrb&);\n\trect_xywhf(int x, int y, int width, int height);\n\trect_xywhf();\n//\tvoid flip();\n//\tbool flipped = false;\n};\n\nstruct bin {\n\trect_wh size;\n\tstd::vector<rect_xywhf*> rects;\n};\n\nbool pack(rect_xywhf* const * v, int n, int max_side, std::vector<bin>& bins);\n\n}\n\n#endif // IMAGEPACKER_H\n"
  },
  {
    "path": "src/core/visual/ogl/ogl_common.h",
    "content": "#pragma once\n#ifdef WIN32 \n#if defined(_M_X64)\n#define GLEW_STATIC\n#endif\n#include \"GL/glew.h\"\n#else\n#ifndef GL_UNPACK_ROW_LENGTH\n#define GL_UNPACK_ROW_LENGTH 0x0CF2\n#endif\n#ifdef __APPLE__\n#include <OpenGLES/ES2/gl.h>\n#include <OpenGLES/ES2/glext.h>\n#else\n#include <GLES2/gl2.h>\n#include <GLES2/gl2ext.h>\n#include <EGL/egl.h>\n#endif\n#endif\n\nbool TVPCheckGLExtension(const std::string &extname);\n"
  },
  {
    "path": "src/core/visual/ogl/pvr.h",
    "content": "#pragma once\n#include <stdint.h>\n\n#pragma pack(push, 1)\nstruct PVRv3Header\n{\n\tuint32_t version;\n\tuint32_t flags;\n\tuint64_t pixelFormat;\n\tuint32_t colorSpace;\n\tuint32_t channelType;\n\tuint32_t height;\n\tuint32_t width;\n\tuint32_t depth;\n\tuint32_t numberOfSurfaces;\n\tuint32_t numberOfFaces;\n\tuint32_t numberOfMipmaps;\n\tuint32_t metadataLength;\n};\nenum class PVR3TexturePixelFormat : uint64_t\n{\n\tPVRTC2BPP_RGB = 0ULL,\n\tPVRTC2BPP_RGBA = 1ULL,\n\tPVRTC4BPP_RGB = 2ULL,\n\tPVRTC4BPP_RGBA = 3ULL,\n\tPVRTC2_2BPP_RGBA = 4ULL,\n\tPVRTC2_4BPP_RGBA = 5ULL,\n\tETC1 = 6ULL,\n\tDXT1 = 7ULL,\n\tDXT2 = 8ULL,\n\tDXT3 = 9ULL,\n\tDXT4 = 10ULL,\n\tDXT5 = 11ULL,\n\tBC1 = 7ULL,\n\tBC2 = 9ULL,\n\tBC3 = 11ULL,\n\tBC4 = 12ULL,\n\tBC5 = 13ULL,\n\tBC6 = 14ULL,\n\tBC7 = 15ULL,\n\tUYVY = 16ULL,\n\tYUY2 = 17ULL,\n\tBW1bpp = 18ULL,\n\tR9G9B9E5 = 19ULL,\n\tRGBG8888 = 20ULL,\n\tGRGB8888 = 21ULL,\n\tETC2_RGB = 22ULL,\n\tETC2_RGBA = 23ULL,\n\tETC2_RGBA1 = 24ULL,\n\tEAC_R11_Unsigned = 25ULL,\n\tEAC_R11_Signed = 26ULL,\n\tEAC_RG11_Unsigned = 27ULL,\n\tEAC_RG11_Signed = 28ULL,\n\n\tBGRA8888 = 0x0808080861726762ULL,\n\tRGBA8888 = 0x0808080861626772ULL,\n\tRGBA4444 = 0x0404040461626772ULL,\n\tRGBA5551 = 0x0105050561626772ULL,\n\tRGB565 = 0x0005060500626772ULL,\n\tRGB888 = 0x0008080800626772ULL,\n\tA8 = 0x0000000800000061ULL,\n\tL8 = 0x000000080000006cULL,\n\tLA88 = 0x000008080000616cULL,\n};\n#pragma pack(pop)"
  },
  {
    "path": "src/core/visual/ogl/pvrtc.cpp",
    "content": "#include \"pvrtc.h\"\n\n#include <algorithm>\n#include <cassert>\n#include <cmath>\n#include <cstring>\n#include <iostream>\n#include <vector>\n\n//============================================================================\n//\n// Modulation data specifies weightings of colorA to colorB for each pixel\n//\n// For mode = 0\n//\t00: 0/8\n//  01: 3/8\n//  10: 5/8\n//  11: 8/8\n//\n// For mode = 1\n//  00: 0/8\n//  01: 4/8\n//  10: 4/8 with alpha punchthrough\n//  11: 8/8\n//\n// For colorIsOpaque=0\n//  3 bits A\n//  4 bits R\n//  4 bits G\n//  3/4 bits B\n//\n// For colorIsOpaque=1\n//  5 bits R\n//  5 bits G\n//  4/5 bits B\n//\n//============================================================================\n\n\nnamespace PvrTcEncoder {\nstatic const unsigned char MODULATION_LUT[16] = {\n\t0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3\n};\nconstexpr unsigned short MORTON_TABLE[256] =\n{\n\t0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,\n\t0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,\n\t0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,\n\t0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,\n\t0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,\n\t0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,\n\t0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,\n\t0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,\n\t0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,\n\t0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,\n\t0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,\n\t0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,\n\t0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,\n\t0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,\n\t0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,\n\t0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,\n\t0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,\n\t0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,\n\t0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,\n\t0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,\n\t0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,\n\t0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,\n\t0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,\n\t0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,\n\t0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,\n\t0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,\n\t0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,\n\t0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,\n\t0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,\n\t0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,\n\t0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,\n\t0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555\n};\nnamespace Data {\nconstexpr uint8_t BITSCALE_5_TO_8[32] = {\n\t0, 8, 16, 24, 32, 41, 49, 57, 65, 74,\n\t82, 90, 98, 106, 115, 123, 131, 139, 148, 156,\n\t164, 172, 180, 189, 197, 205, 213, 222, 230, 238,\n\t246, 255 };\n\nconstexpr uint8_t BITSCALE_4_TO_8[16] = {\n\t0, 17, 34, 51, 68, 85, 102, 119, 136, 153,\n\t170, 187, 204, 221, 238, 255 };\n\nconstexpr uint8_t BITSCALE_3_TO_8[8] = {\n\t0, 36, 72, 109, 145, 182, 218, 255 };\n\nconstexpr uint8_t BITSCALE_8_TO_5_FLOOR[256] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 1,\n\t1, 1, 1, 1, 1, 1, 1, 2, 2, 2,\n\t2, 2, 2, 2, 2, 3, 3, 3, 3, 3,\n\t3, 3, 3, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 5, 5, 5, 5, 5, 5, 5, 5,\n\t6, 6, 6, 6, 6, 6, 6, 6, 7, 7,\n\t7, 7, 7, 7, 7, 7, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 9, 9, 9, 9, 9,\n\t9, 9, 9, 10, 10, 10, 10, 10, 10, 10,\n\t10, 11, 11, 11, 11, 11, 11, 11, 11, 12,\n\t12, 12, 12, 12, 12, 12, 12, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 14, 14, 14, 14,\n\t14, 14, 14, 14, 15, 15, 15, 15, 15, 15,\n\t15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n\t17, 17, 17, 17, 17, 17, 17, 17, 17, 18,\n\t18, 18, 18, 18, 18, 18, 18, 19, 19, 19,\n\t19, 19, 19, 19, 19, 20, 20, 20, 20, 20,\n\t20, 20, 20, 21, 21, 21, 21, 21, 21, 21,\n\t21, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t23, 23, 23, 23, 23, 23, 23, 23, 24, 24,\n\t24, 24, 24, 24, 24, 24, 25, 25, 25, 25,\n\t25, 25, 25, 25, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 27, 27, 27, 27, 27, 27, 27,\n\t27, 28, 28, 28, 28, 28, 28, 28, 28, 29,\n\t29, 29, 29, 29, 29, 29, 29, 30, 30, 30,\n\t30, 30, 30, 30, 30, 31 };\n\nconstexpr uint8_t BITSCALE_8_TO_4_FLOOR[256] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 15 };\n\nconstexpr uint8_t BITSCALE_8_TO_3_FLOOR[256] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 7 };\n\nconstexpr uint8_t BITSCALE_8_TO_5_CEIL[256] = {\n\t0, 1, 1, 1, 1, 1, 1, 1, 1, 2,\n\t2, 2, 2, 2, 2, 2, 2, 3, 3, 3,\n\t3, 3, 3, 3, 3, 4, 4, 4, 4, 4,\n\t4, 4, 4, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 6, 6, 6, 6, 6, 6, 6, 6,\n\t7, 7, 7, 7, 7, 7, 7, 7, 8, 8,\n\t8, 8, 8, 8, 8, 8, 9, 9, 9, 9,\n\t9, 9, 9, 9, 9, 10, 10, 10, 10, 10,\n\t10, 10, 10, 11, 11, 11, 11, 11, 11, 11,\n\t11, 12, 12, 12, 12, 12, 12, 12, 12, 13,\n\t13, 13, 13, 13, 13, 13, 13, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 15, 15, 15, 15,\n\t15, 15, 15, 15, 16, 16, 16, 16, 16, 16,\n\t16, 16, 17, 17, 17, 17, 17, 17, 17, 17,\n\t18, 18, 18, 18, 18, 18, 18, 18, 18, 19,\n\t19, 19, 19, 19, 19, 19, 19, 20, 20, 20,\n\t20, 20, 20, 20, 20, 21, 21, 21, 21, 21,\n\t21, 21, 21, 22, 22, 22, 22, 22, 22, 22,\n\t22, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t24, 24, 24, 24, 24, 24, 24, 24, 25, 25,\n\t25, 25, 25, 25, 25, 25, 26, 26, 26, 26,\n\t26, 26, 26, 26, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 28, 28, 28, 28, 28, 28, 28,\n\t28, 29, 29, 29, 29, 29, 29, 29, 29, 30,\n\t30, 30, 30, 30, 30, 30, 30, 31, 31, 31,\n\t31, 31, 31, 31, 31, 31 };\n\nconstexpr uint8_t BITSCALE_8_TO_4_CEIL[256] = {\n\t0, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\t8, 8, 8, 8, 8, 8, 8, 9, 9, 9,\n\t9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t9, 9, 9, 9, 10, 10, 10, 10, 10, 10,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t10, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t11, 11, 11, 11, 11, 11, 11, 11, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15 };\n\nconstexpr uint8_t BITSCALE_8_TO_3_CEIL[256] = {\n\t0, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t2, 2, 2, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t4, 4, 4, 4, 4, 4, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t5, 5, 5, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7 };\n}\ntemplate<typename T>\nclass Point2 {\npublic:\n\tT x;\n\tT y;\n\n\tPoint2(int a, int b)\n\t\t: x(a)\n\t\t, y(b) {\n\t}\n};\n\nclass BitUtility {\npublic:\n\tstatic bool IsPowerOf2(unsigned int x) {\n\t\treturn (x & (x - 1)) == 0;\n\t}\n\n\tstatic unsigned int RotateRight(unsigned int value, unsigned int shift) {\n\t\tif ((shift &= sizeof(value) * 8 - 1) == 0) {\n\t\t\treturn value;\n\t\t}\n\t\treturn (value >> shift) | (value << (sizeof(value) * 8 - shift));\n\t}\n};\n\ntemplate<typename T>\nclass ColorRgb {\npublic:\n\tT r;\n\tT g;\n\tT b;\n\n\n\tColorRgb()\n\t\t: r(0)\n\t\t, g(0)\n\t\t, b(0) {\n\t}\n\n\tColorRgb(T red, T green, T blue)\n\t\t: r(red)\n\t\t, g(green)\n\t\t, b(blue) {\n\t}\n\n\tColorRgb(const ColorRgb<T> &x)\n\t\t: r(x.r)\n\t\t, g(x.g)\n\t\t, b(x.b) {\n\t}\n\n\tColorRgb<int> operator *(int x) {\n\t\treturn ColorRgb<int>(r * x, g * x, b * x);\n\t}\n\n\tColorRgb<int> operator +(const ColorRgb<T> &x) const {\n\t\treturn ColorRgb<int>(r + (int)x.r, g + (int)x.g, b + (int)x.b);\n\t}\n\n\tColorRgb<int> operator -(const ColorRgb<T> &x) const {\n\t\treturn ColorRgb<int>(r - (int)x.r, g - (int)x.g, b - (int)x.b);\n\t}\n\n\tint operator %(const ColorRgb<T> &x) const {\n\t\treturn r * (int)x.r + g * (int)x.g + b * (int)x.b;\n\t}\n\n\tbool operator ==(const ColorRgb<T> &x) const {\n\t\treturn r == x.r && g == x.g && b == x.b;\n\t}\n\n\tbool operator !=(const ColorRgb<T> &x) const {\n\t\treturn r != x.r || g != x.g || b != x.b;\n\t}\n\n\tvoid SetMin(const ColorRgb<T> &x) {\n\t\tif (x.r < r) {\n\t\t\tr = x.r;\n\t\t}\n\t\tif (x.g < g) {\n\t\t\tg = x.g;\n\t\t}\n\t\tif (x.b < b) {\n\t\t\tb = x.b;\n\t\t}\n\t}\n\n\tvoid SetMax(const ColorRgb<T> &x) {\n\t\tif (x.r > r) {\n\t\t\tr = x.r;\n\t\t}\n\t\tif (x.g > g) {\n\t\t\tg = x.g;\n\t\t}\n\t\tif (x.b > b) {\n\t\t\tb = x.b;\n\t\t}\n\t}\n};\n\ntemplate<typename T>\nclass ColorRgba : public ColorRgb<T> {\npublic:\n\tT a;\n\n\tColorRgba() :\n\t\ta(0) {\n\t}\n\n\tColorRgba(T red, T green, T blue, T alpha)\n\t\t: ColorRgb<T>(red, green, blue)\n\t\t, a(alpha) {\n\t}\n\n\tColorRgba(const ColorRgba<T> &x)\n\t\t: ColorRgb<T>(x.r, x.g, x.b)\n\t\t, a(x.a) {\n\t}\n\n\tColorRgba<int> operator *(int x) {\n\t\treturn ColorRgba<T>(ColorRgb<T>::r * x,\n\t\t\tColorRgb<T>::g * x,\n\t\t\tColorRgb<T>::b * x,\n\t\t\ta * x);\n\t}\n\n\tColorRgba<int> operator +(const ColorRgba<T> &x) {\n\t\treturn ColorRgba<T>(ColorRgb<T>::r + (int)x.r,\n\t\t\tColorRgb<T>::g + (int)x.g,\n\t\t\tColorRgb<T>::b + (int)x.b,\n\t\t\ta + (int)x.a);\n\t}\n\n\tColorRgba<int> operator -(const ColorRgba<T> &x) {\n\t\treturn ColorRgba<T>(ColorRgb<T>::r - (int)x.r,\n\t\t\tColorRgb<T>::g - (int)x.g,\n\t\t\tColorRgb<T>::b - (int)x.b,\n\t\t\ta - (int)x.a);\n\t}\n\n\tint operator %(const ColorRgba<T> &x) {\n\t\treturn ColorRgb<T>::r * (int)x.r +\n\t\t\tColorRgb<T>::g * (int)x.g +\n\t\t\tColorRgb<T>::b * (int)x.b +\n\t\t\ta * (int)x.a;\n\t}\n\n\tbool operator ==(const ColorRgba<T> &x) {\n\t\treturn ColorRgb<T>::r == x.r && ColorRgb<T>::g == x.g &&\n\t\t\tColorRgb<T>::b == x.b && a == x.a;\n\t}\n\n\tbool operator !=(const ColorRgba<T> &x) {\n\t\treturn ColorRgb<T>::r != x.r || ColorRgb<T>::g != x.g ||\n\t\t\tColorRgb<T>::b != x.b || a != x.a;\n\t}\n\n\tvoid SetMin(const ColorRgba<T> &x) {\n\t\tColorRgb<T>::SetMin(x);\n\t\tif (x.a < a) {\n\t\t\ta = x.a;\n\t\t}\n\t}\n\n\tvoid SetMax(const ColorRgba<T> &x) {\n\t\tColorRgb<T>::SetMax(x);\n\t\tif (x.a > a) {\n\t\t\ta = x.a;\n\t\t}\n\t}\n};\n//============================================================================\n\nstruct PvrTcPacket\n{\n\tunsigned int    modulationData;\n\tunsigned        usePunchthroughAlpha : 1;\n\tunsigned        colorA : 14;\n\tunsigned        colorAIsOpaque : 1;\n\tunsigned        colorB : 15;\n\tunsigned        colorBIsOpaque : 1;\n\n\tColorRgb<int> GetColorRgbA() const;\n\tColorRgb<int> GetColorRgbB() const;\n\tColorRgba<int> GetColorRgbaA() const;\n\tColorRgba<int> GetColorRgbaB() const;\n\n\tvoid SetColorA(const ColorRgb<unsigned char>& c);\n\tvoid SetColorB(const ColorRgb<unsigned char>& c);\n\n\tvoid SetColorA(const ColorRgba<unsigned char>& c);\n\tvoid SetColorB(const ColorRgba<unsigned char>& c);\n\n\tstatic const unsigned char BILINEAR_FACTORS[16][4];\n\tstatic const unsigned char WEIGHTS[8][4];\n};\n\nconst unsigned char PvrTcPacket::BILINEAR_FACTORS[16][4] =\n{\n\t{ 4, 4, 4, 4 },\n\t{ 2, 6, 2, 6 },\n\t{ 8, 0, 8, 0 },\n\t{ 6, 2, 6, 2 },\n\n\t{ 2, 2, 6, 6 },\n\t{ 1, 3, 3, 9 },\n\t{ 4, 0, 12, 0 },\n\t{ 3, 1, 9, 3 },\n\n\t{ 8, 8, 0, 0 },\n\t{ 4, 12, 0, 0 },\n\t{ 16, 0, 0, 0 },\n\t{ 12, 4, 0, 0 },\n\n\t{ 6, 6, 2, 2 },\n\t{ 3, 9, 1, 3 },\n\t{ 12, 0, 4, 0 },\n\t{ 9, 3, 3, 1 },\n};\n\n// Weights are { colorA, colorB, alphaA, alphaB }\nconst unsigned char PvrTcPacket::WEIGHTS[8][4] =\n{\n\t// Weights for Mode=0\n\t{ 8, 0, 8, 0 },\n\t{ 5, 3, 5, 3 },\n\t{ 3, 5, 3, 5 },\n\t{ 0, 8, 0, 8 },\n\n\t// Weights for Mode=1\n\t{ 8, 0, 8, 0 },\n\t{ 4, 4, 4, 4 },\n\t{ 4, 4, 0, 0 },\n\t{ 0, 8, 0, 8 },\n};\n\n//============================================================================\n\nColorRgb<int> PvrTcPacket::GetColorRgbA() const\n{\n\tif (colorAIsOpaque)\n\t{\n\t\tunsigned char r = colorA >> 9;\n\t\tunsigned char g = colorA >> 4 & 0x1f;\n\t\tunsigned char b = colorA & 0xf;\n\t\treturn ColorRgb<int>(Data::BITSCALE_5_TO_8[r],\n\t\t\tData::BITSCALE_5_TO_8[g],\n\t\t\tData::BITSCALE_4_TO_8[b]);\n\t} else\n\t{\n\t\tunsigned char r = (colorA >> 7) & 0xf;\n\t\tunsigned char g = (colorA >> 3) & 0xf;\n\t\tunsigned char b = colorA & 7;\n\t\treturn ColorRgb<int>(Data::BITSCALE_4_TO_8[r],\n\t\t\tData::BITSCALE_4_TO_8[g],\n\t\t\tData::BITSCALE_3_TO_8[b]);\n\t}\n}\n\nColorRgb<int> PvrTcPacket::GetColorRgbB() const\n{\n\tif (colorBIsOpaque)\n\t{\n\t\tunsigned char r = colorB >> 10;\n\t\tunsigned char g = colorB >> 5 & 0x1f;\n\t\tunsigned char b = colorB & 0x1f;\n\t\treturn ColorRgb<int>(Data::BITSCALE_5_TO_8[r],\n\t\t\tData::BITSCALE_5_TO_8[g],\n\t\t\tData::BITSCALE_5_TO_8[b]);\n\t} else\n\t{\n\t\tunsigned char r = colorB >> 8 & 0xf;\n\t\tunsigned char g = colorB >> 4 & 0xf;\n\t\tunsigned char b = colorB & 0xf;\n\t\treturn ColorRgb<int>(Data::BITSCALE_4_TO_8[r],\n\t\t\tData::BITSCALE_4_TO_8[g],\n\t\t\tData::BITSCALE_4_TO_8[b]);\n\t}\n}\n\nColorRgba<int> PvrTcPacket::GetColorRgbaA() const\n{\n\tif (colorAIsOpaque)\n\t{\n\t\tunsigned char r = colorA >> 9;\n\t\tunsigned char g = colorA >> 4 & 0x1f;\n\t\tunsigned char b = colorA & 0xf;\n\t\treturn ColorRgba<int>(Data::BITSCALE_5_TO_8[r],\n\t\t\tData::BITSCALE_5_TO_8[g],\n\t\t\tData::BITSCALE_4_TO_8[b],\n\t\t\t255);\n\t} else\n\t{\n\t\tunsigned char a = colorA >> 11 & 7;\n\t\tunsigned char r = colorA >> 7 & 0xf;\n\t\tunsigned char g = colorA >> 3 & 0xf;\n\t\tunsigned char b = colorA & 7;\n\t\treturn ColorRgba<int>(Data::BITSCALE_4_TO_8[r],\n\t\t\tData::BITSCALE_4_TO_8[g],\n\t\t\tData::BITSCALE_3_TO_8[b],\n\t\t\tData::BITSCALE_3_TO_8[a]);\n\t}\n}\n\nColorRgba<int> PvrTcPacket::GetColorRgbaB() const\n{\n\tif (colorBIsOpaque)\n\t{\n\t\tunsigned char r = colorB >> 10;\n\t\tunsigned char g = colorB >> 5 & 0x1f;\n\t\tunsigned char b = colorB & 0x1f;\n\t\treturn ColorRgba<int>(Data::BITSCALE_5_TO_8[r],\n\t\t\tData::BITSCALE_5_TO_8[g],\n\t\t\tData::BITSCALE_5_TO_8[b],\n\t\t\t255);\n\t} else\n\t{\n\t\tunsigned char a = colorB >> 12 & 7;\n\t\tunsigned char r = colorB >> 8 & 0xf;\n\t\tunsigned char g = colorB >> 4 & 0xf;\n\t\tunsigned char b = colorB & 0xf;\n\t\treturn ColorRgba<int>(Data::BITSCALE_4_TO_8[r],\n\t\t\tData::BITSCALE_4_TO_8[g],\n\t\t\tData::BITSCALE_4_TO_8[b],\n\t\t\tData::BITSCALE_3_TO_8[a]);\n\t}\n}\n\n//============================================================================\n\nvoid PvrTcPacket::SetColorA(const ColorRgb<unsigned char>& c)\n{\n\tint r = Data::BITSCALE_8_TO_5_FLOOR[c.r];\n\tint g = Data::BITSCALE_8_TO_5_FLOOR[c.g];\n\tint b = Data::BITSCALE_8_TO_4_FLOOR[c.b];\n\tcolorA = r << 9 | g << 4 | b;\n\tcolorAIsOpaque = true;\n}\n\nvoid PvrTcPacket::SetColorB(const ColorRgb<unsigned char>& c)\n{\n\tint r = Data::BITSCALE_8_TO_5_CEIL[c.r];\n\tint g = Data::BITSCALE_8_TO_5_CEIL[c.g];\n\tint b = Data::BITSCALE_8_TO_5_CEIL[c.b];\n\tcolorB = r << 10 | g << 5 | b;\n\tcolorBIsOpaque = true;\n}\n\nvoid PvrTcPacket::SetColorA(const ColorRgba<unsigned char>& c)\n{\n\tint a = Data::BITSCALE_8_TO_3_FLOOR[c.a];\n\tif (a == 7)\n\t{\n\t\tint r = Data::BITSCALE_8_TO_5_FLOOR[c.r];\n\t\tint g = Data::BITSCALE_8_TO_5_FLOOR[c.g];\n\t\tint b = Data::BITSCALE_8_TO_4_FLOOR[c.b];\n\t\tcolorA = r << 9 | g << 4 | b;\n\t\tcolorAIsOpaque = true;\n\t} else\n\t{\n\t\tint r = Data::BITSCALE_8_TO_4_FLOOR[c.r];\n\t\tint g = Data::BITSCALE_8_TO_4_FLOOR[c.g];\n\t\tint b = Data::BITSCALE_8_TO_3_FLOOR[c.b];\n\t\tcolorA = a << 11 | r << 7 | g << 3 | b;\n\t\tcolorAIsOpaque = false;\n\t}\n}\n\nvoid PvrTcPacket::SetColorB(const ColorRgba<unsigned char>& c)\n{\n\tint a = Data::BITSCALE_8_TO_3_CEIL[c.a];\n\tif (a == 7)\n\t{\n\t\tint r = Data::BITSCALE_8_TO_5_CEIL[c.r];\n\t\tint g = Data::BITSCALE_8_TO_5_CEIL[c.g];\n\t\tint b = Data::BITSCALE_8_TO_5_CEIL[c.b];\n\t\tcolorB = r << 10 | g << 5 | b;\n\t\tcolorBIsOpaque = true;\n\t} else\n\t{\n\t\tint r = Data::BITSCALE_8_TO_4_CEIL[c.r];\n\t\tint g = Data::BITSCALE_8_TO_4_CEIL[c.g];\n\t\tint b = Data::BITSCALE_8_TO_4_CEIL[c.b];\n\t\tcolorB = a << 12 | r << 8 | g << 4 | b;\n\t\tcolorBIsOpaque = false;\n\t}\n}\n\n//============================================================================\n\nclass Bitmap {\npublic:\n\tint width;\n\tint height;\n\tunsigned char *data;\n\n\tBitmap(int w, int h, int bytesPerPixel, unsigned char * pix)\n\t\t: width(w)\n\t\t, height(h)\n\t\t, data(pix) {\n\t}\n\n\tvirtual ~Bitmap() {\n\t//\tdelete[] data;\n\t}\n\n\tPoint2<int> GetSize() const { return Point2<int>(width, height); }\n\n\tint GetArea() const { return width * height; }\n\n\tint GetBitmapWidth() const { return width; }\n\n\tint GetBitmapHeight() const { return height; }\n\n\tconst unsigned char *GetRawData() const { return data; }\n};\n\nclass RgbaBitmap : public Bitmap {\npublic:\n\tRgbaBitmap(int w, int h, unsigned char * pix)\n\t\t: Bitmap(w, h, 4, pix) {\n\t}\n\n\tconst ColorRgba<unsigned char> *GetData() const {\n\t\treturn reinterpret_cast<ColorRgba<unsigned char> *>(data);\n\t}\n\n\tColorRgba<unsigned char> *GetData() {\n\t\treturn reinterpret_cast<ColorRgba<unsigned char> *>(data);\n\t}\n};\n\nstatic unsigned GetMortonNumber(int x, int y)\n{\n\treturn MORTON_TABLE[x >> 8] << 17 | MORTON_TABLE[y >> 8] << 16 | MORTON_TABLE[x & 0xFF] << 1 | MORTON_TABLE[y & 0xFF];\n}\n//============================================================================\n\ntemplate<typename T>\nclass Interval {\npublic:\n\tT min;\n\tT max;\n\n\tInterval() {\n\t}\n\n\tInterval<T> &operator|=(const T &x) {\n\t\tmin.SetMin(x);\n\t\tmax.SetMax(x);\n\t\treturn *this;\n\t}\n};\ntypedef Interval<ColorRgb<unsigned char>> ColorRgbBoundingBox;\n\n//============================================================================\n\nstatic void CalculateBoundingBox(ColorRgbBoundingBox& cbb, const RgbaBitmap& bitmap, int blockX, int blockY)\n{\n\tint size = bitmap.GetBitmapWidth();\n\tconst ColorRgba<unsigned char>* data = bitmap.GetData() + blockY * 4 * size + blockX * 4;\n\t\n\tcbb.min = data[0];\n\tcbb.max = data[0];\n\t\n\tcbb |= data[1];\n\tcbb |= data[2];\n\tcbb |= data[3];\n\t\n\tcbb |= data[size];\n\tcbb |= data[size+1];\n\tcbb |= data[size+2];\n\tcbb |= data[size+3];\n\t\n\tcbb |= data[2*size];\n\tcbb |= data[2*size+1];\n\tcbb |= data[2*size+2];\n\tcbb |= data[2*size+3];\n\t\n\tcbb |= data[3*size];\n\tcbb |= data[3*size+1];\n\tcbb |= data[3*size+2];\n\tcbb |= data[3*size+3];\n}\n\nvoid EncodeRgb4Bpp(void* result, const RgbaBitmap& bitmap)\n{\n\tassert(bitmap.GetBitmapWidth() == bitmap.GetBitmapHeight());\n\tassert(BitUtility::IsPowerOf2(bitmap.GetBitmapWidth()));\n\tconst int size = bitmap.GetBitmapWidth();\n\tconst int blocks = size / 4;\n\tconst int blockMask = blocks-1;\n\t\n\tPvrTcPacket* packets = static_cast<PvrTcPacket*>(result);\n\t\n\tfor(int y = 0; y < blocks; ++y)\n\t{\n\t\tfor(int x = 0; x < blocks; ++x)\n\t\t{\n\t\t\tColorRgbBoundingBox cbb;\n\t\t\tCalculateBoundingBox(cbb, bitmap, x, y);\n\t\t\tPvrTcPacket* packet = packets + GetMortonNumber(x, y);\n\t\t\tpacket->usePunchthroughAlpha = 0;\n\t\t\tpacket->SetColorA(cbb.min);\n\t\t\tpacket->SetColorB(cbb.max);\n\t\t}\n\t}\n\t\n\tfor(int y = 0; y < blocks; ++y)\n\t{\n\t\tfor(int x = 0; x < blocks; ++x)\n\t\t{\n\t\t\tconst unsigned char (*factor)[4] = PvrTcPacket::BILINEAR_FACTORS;\n\t\t\tconst ColorRgba<unsigned char>* data = bitmap.GetData() + y * 4 * size + x * 4;\n\t\t\t\n\t\t\tuint32_t modulationData = 0;\n\t\t\t\n\t\t\tfor(int py = 0; py < 4; ++py)\n\t\t\t{\n\t\t\t\tconst int yOffset = (py < 2) ? -1 : 0;\n\t\t\t\tconst int y0 = (y + yOffset) & blockMask;\n\t\t\t\tconst int y1 = (y0+1) & blockMask;\n\n\t\t\t\tfor(int px = 0; px < 4; ++px)\n\t\t\t\t{\n\t\t\t\t\tconst int xOffset = (px < 2) ? -1 : 0;\n\t\t\t\t\tconst int x0 = (x + xOffset) & blockMask;\n\t\t\t\t\tconst int x1 = (x0+1) & blockMask;\n\t\t\t\t\t\n\t\t\t\t\tconst PvrTcPacket* p0 = packets + GetMortonNumber(x0, y0);\n\t\t\t\t\tconst PvrTcPacket* p1 = packets + GetMortonNumber(x1, y0);\n\t\t\t\t\tconst PvrTcPacket* p2 = packets + GetMortonNumber(x0, y1);\n\t\t\t\t\tconst PvrTcPacket* p3 = packets + GetMortonNumber(x1, y1);\n\t\t\t\t\t\n\t\t\t\t\tColorRgb<int> ca = p0->GetColorRgbA() * (*factor)[0] +\n\t\t\t\t\t\t\t\t\t   p1->GetColorRgbA() * (*factor)[1] +\n\t\t\t\t\t\t\t\t\t   p2->GetColorRgbA() * (*factor)[2] +\n\t\t\t\t\t\t\t\t\t   p3->GetColorRgbA() * (*factor)[3];\n\t\t\t\t\t\n\t\t\t\t\tColorRgb<int> cb = p0->GetColorRgbB() * (*factor)[0] +\n\t\t\t\t\t\t\t\t\t   p1->GetColorRgbB() * (*factor)[1] +\n\t\t\t\t\t\t\t\t\t   p2->GetColorRgbB() * (*factor)[2] +\n\t\t\t\t\t\t\t\t\t   p3->GetColorRgbB() * (*factor)[3];\n\t\t\t\t\t\n\t\t\t\t\tconst ColorRgb<unsigned char>& pixel = data[py*size + px];\n\t\t\t\t\tColorRgb<int> d = cb - ca;\n\t\t\t\t\tColorRgb<int> p{pixel.r*16, pixel.g*16, pixel.b*16};\n\t\t\t\t\tColorRgb<int> v = p - ca;\n\t\t\t\t\t\n\t\t\t\t\t// PVRTC uses weightings of 0, 3/8, 5/8 and 1\n\t\t\t\t\t// The boundaries for these are 3/16, 1/2 (=8/16), 13/16\n\t\t\t\t\tint projection = (v % d) * 16;\n\t\t\t\t\tint lengthSquared = d % d;\n\t\t\t\t\tif(projection > 3*lengthSquared) modulationData++;\n\t\t\t\t\tif(projection > 8*lengthSquared) modulationData++;\n\t\t\t\t\tif(projection > 13*lengthSquared) modulationData++;\n\t\t\t\t\t\n\t\t\t\t\tmodulationData = BitUtility::RotateRight(modulationData, 2);\n\t\t\t\t\t\n\t\t\t\t\tfactor++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tPvrTcPacket* packet = packets + GetMortonNumber(x, y);\n\t\t\tpacket->modulationData = modulationData;\n\t\t}\n\t}\n}\n\n//============================================================================\n\ntypedef Interval<ColorRgba<unsigned char>> ColorRgbaBoundingBox;\n\nstatic void CalculateBoundingBox(ColorRgbaBoundingBox& cbb, const RgbaBitmap& bitmap, int blockX, int blockY)\n{\n\tint size = bitmap.GetBitmapWidth();\n\tconst ColorRgba<unsigned char>* data = bitmap.GetData() + blockY * 4 * size + blockX * 4;\n\t\n\tcbb.min = data[0];\n\tcbb.max = data[0];\n\t\n\tcbb |= data[1];\n\tcbb |= data[2];\n\tcbb |= data[3];\n\t\n\tcbb |= data[size];\n\tcbb |= data[size+1];\n\tcbb |= data[size+2];\n\tcbb |= data[size+3];\n\t\n\tcbb |= data[2*size];\n\tcbb |= data[2*size+1];\n\tcbb |= data[2*size+2];\n\tcbb |= data[2*size+3];\n\t\n\tcbb |= data[3*size];\n\tcbb |= data[3*size+1];\n\tcbb |= data[3*size+2];\n\tcbb |= data[3*size+3];\n}\n\nvoid EncodeRgba4Bpp(void* result, const RgbaBitmap& bitmap)\n{\n\tassert(bitmap.GetBitmapWidth() == bitmap.GetBitmapHeight());\n\tassert(BitUtility::IsPowerOf2(bitmap.GetBitmapWidth()));\n\tconst int size = bitmap.GetBitmapWidth();\n\tconst int blocks = size / 4;\n\tconst int blockMask = blocks-1;\n\t\n\tPvrTcPacket* packets = static_cast<PvrTcPacket*>(result);\n\t\n\tfor(int y = 0; y < blocks; ++y)\n\t{\n\t\tfor(int x = 0; x < blocks; ++x)\n\t\t{\n\t\t\tColorRgbaBoundingBox cbb;\n\t\t\tCalculateBoundingBox(cbb, bitmap, x, y);\n\t\t\tPvrTcPacket* packet = packets + GetMortonNumber(x, y);\n\t\t\tpacket->usePunchthroughAlpha = 0;\n\t\t\tpacket->SetColorA(cbb.min);\n\t\t\tpacket->SetColorB(cbb.max);\n\t\t}\n\t}\n\t\n\tfor(int y = 0; y < blocks; ++y)\n\t{\n\t\tfor(int x = 0; x < blocks; ++x)\n\t\t{\n\t\t\tconst unsigned char (*factor)[4] = PvrTcPacket::BILINEAR_FACTORS;\n\t\t\tconst ColorRgba<unsigned char>* data = bitmap.GetData() + y * 4 * size + x * 4;\n\t\t\t\n\t\t\tuint32_t modulationData = 0;\n\t\t\t\n\t\t\tfor(int py = 0; py < 4; ++py)\n\t\t\t{\n\t\t\t\tconst int yOffset = (py < 2) ? -1 : 0;\n\t\t\t\tconst int y0 = (y + yOffset) & blockMask;\n\t\t\t\tconst int y1 = (y0+1) & blockMask;\n\t\t\t\t\n\t\t\t\tfor(int px = 0; px < 4; ++px)\n\t\t\t\t{\n\t\t\t\t\tconst int xOffset = (px < 2) ? -1 : 0;\n\t\t\t\t\tconst int x0 = (x + xOffset) & blockMask;\n\t\t\t\t\tconst int x1 = (x0+1) & blockMask;\n\t\t\t\t\t\n\t\t\t\t\tconst PvrTcPacket* p0 = packets + GetMortonNumber(x0, y0);\n\t\t\t\t\tconst PvrTcPacket* p1 = packets + GetMortonNumber(x1, y0);\n\t\t\t\t\tconst PvrTcPacket* p2 = packets + GetMortonNumber(x0, y1);\n\t\t\t\t\tconst PvrTcPacket* p3 = packets + GetMortonNumber(x1, y1);\n\t\t\t\t\t\n\t\t\t\t\tColorRgba<int> ca = p0->GetColorRgbaA() * (*factor)[0] +\n\t\t\t\t\t\t\t\t\t\tp1->GetColorRgbaA() * (*factor)[1] +\n\t\t\t\t\t\t\t\t\t\tp2->GetColorRgbaA() * (*factor)[2] +\n\t\t\t\t\t\t\t\t\t\tp3->GetColorRgbaA() * (*factor)[3];\n\t\t\t\t\t\n\t\t\t\t\tColorRgba<int> cb = p0->GetColorRgbaB() * (*factor)[0] +\n\t\t\t\t\t\t\t\t\t\tp1->GetColorRgbaB() * (*factor)[1] +\n\t\t\t\t\t\t\t\t\t\tp2->GetColorRgbaB() * (*factor)[2] +\n\t\t\t\t\t\t\t\t\t\tp3->GetColorRgbaB() * (*factor)[3];\n\t\t\t\t\t\n\t\t\t\t\tconst ColorRgba<unsigned char>& pixel = data[py*size + px];\n\t\t\t\t\tColorRgba<int> d = cb - ca;\n\t\t\t\t\tColorRgba<int> p{pixel.r*16, pixel.g*16, pixel.b*16, pixel.a*16};\n\t\t\t\t\tColorRgba<int> v = p - ca;\n\t\t\t\t\t\n\t\t\t\t\t// PVRTC uses weightings of 0, 3/8, 5/8 and 1\n\t\t\t\t\t// The boundaries for these are 3/16, 1/2 (=8/16), 13/16\n\t\t\t\t\tint projection = (v % d) * 16;\n\t\t\t\t\tint lengthSquared = d % d;\n\t\t\t\t\tif(projection > 3*lengthSquared) modulationData++;\n\t\t\t\t\tif(projection > 8*lengthSquared) modulationData++;\n\t\t\t\t\tif(projection > 13*lengthSquared) modulationData++;\n\t\t\t\t\t\n\t\t\t\t\tmodulationData = BitUtility::RotateRight(modulationData, 2);\n\t\t\t\t\t\n\t\t\t\t\tfactor++;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tPvrTcPacket* packet = packets + GetMortonNumber(x, y);\n\t\t\tpacket->modulationData = modulationData;\n\t\t}\n\t}\n}\n\nvoid EncodeRgba4Bpp(const void *inBuf, void *outBuffer, unsigned int width, unsigned int height, bool isOpaque) {\n\tRgbaBitmap bitmap(width, height, (unsigned char *)inBuf);\n\n\tif (isOpaque) {\n\t\tEncodeRgb4Bpp(outBuffer, bitmap);\n\t} else {\n\t\tEncodeRgba4Bpp(outBuffer, bitmap);\n\t}\n}\n\n}"
  },
  {
    "path": "src/core/visual/ogl/pvrtc.h",
    "content": "#pragma once\n// from https://bitbucket.org/jthlim/pvrtccompressor\nnamespace PvrTcEncoder {\n\tvoid EncodeRgba4Bpp(const void *inBuf, void *outBuffer, unsigned int width, unsigned int height, bool isOpaque);\n}"
  },
  {
    "path": "src/core/visual/transhandler.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Transition handler interface\n//---------------------------------------------------------------------------\n\n#ifndef __TRANSHANDLER_H__\n#define __TRANSHANDLER_H__\n\n#include \"tjsTypes.h\"\n#include \"tjsErrorDefs.h\"\n#include \"drawable.h\"\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTVPTransType\n//---------------------------------------------------------------------------\n// transition type\n#ifdef __BORLANDC__\n\t#pragma option push -b\n#endif\nenum tTVPTransType\n{\n\tttSimple, // transition using only one(self) layer ( eg. simple fading )\n\tttExchange // transition using two layer ( eg. cross fading )\n};\n#ifdef __BORLANDC__\n\t#pragma option pop\n#endif\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPTransUpdateType\n//---------------------------------------------------------------------------\n// transition update type\n#ifdef __BORLANDC__\n\t#pragma option push -b\n#endif\nenum tTVPTransUpdateType\n{\n\ttutDivisibleFade,\n\ttutDivisible,\n\ttutGiveUpdate\n};\n#ifdef __BORLANDC__\n\t#pragma option pop\n#endif\n/*\n\tthere are two types of transition update method;\n\ttutDivisibleFade, tutDivisible and tutGiveUpdate.\n\n\ttutDivisibleFade\n\t\tused when the transition processing is region-divisible and\n\t\tthe transition updates entire area of the layer.\n\t\tupdate area is always given by iTVPTransHandler::Process caller.\n\t\thandler must use only given area of the source bitmap on each\n\t\tcallbacking.\n\n\ttutDivisible\n\t\tsame as tutDivisibleFade, except for its usage of source area.\n\t\thandler can use any area of the source bitmap.\n\t\tthis will somewhat slower than tutDivisibleFade.\n\n\ttutGiveUpdate\n\t\tused when the transition processing is not region-divisible or\n\t\tthe transition updates only some small regions rather than entire\n\t\tarea.\n\t\tupdate area is given by callee of iTVPTransHandler::Process, \n\t\tvia iTVPLayerUpdater interface.\n*/\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPScanLineProvider\n//---------------------------------------------------------------------------\n// provides layer scanline\nclass iTVPTexture2D;\nclass iTVPScanLineProvider\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD AddRef() = 0;\n\tvirtual tjs_error TJS_INTF_METHOD Release() = 0;\n\t\t// call \"Release\" when done with this object\n\n\tvirtual tjs_error TJS_INTF_METHOD GetWidth(/*out*/tjs_int *width) = 0;\n\t\t// return image width\n\tvirtual tjs_error TJS_INTF_METHOD GetHeight(/*out*/tjs_int *height) = 0;\n\t\t// return image height\n#if 0\n\tvirtual tjs_error TJS_INTF_METHOD GetPixelFormat(/*out*/tjs_int *bpp) = 0;\n\t\t// return image bit depth\n\tvirtual tjs_error TJS_INTF_METHOD GetPitchBytes(/*out*/tjs_int *pitch) = 0;\n\t\t// return image bitmap data width in bytes ( offset to next down line )\n\tvirtual tjs_error TJS_INTF_METHOD GetScanLine(/*in*/tjs_int line,\n\t\t\t/*out*/const void ** scanline) = 0;\n\t\t// return image pixel scan line pointer\n\tvirtual tjs_error TJS_INTF_METHOD GetScanLineForWrite(/*in*/tjs_int line,\n\t\t\t/*out*/void ** scanline) = 0;\n\t\t// return image pixel scan line pointer for writing\n#endif\n\tvirtual iTVPTexture2D * GetTexture() = 0;\n\tvirtual iTVPTexture2D * GetTextureForRender() = 0;\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPSimpleOptionProvider\n//---------------------------------------------------------------------------\n// provides option set\nclass iTVPSimpleOptionProvider\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD AddRef() = 0;\n\tvirtual tjs_error TJS_INTF_METHOD Release() = 0;\n\t\t// call this when done with this object\n\n\tvirtual tjs_error TJS_INTF_METHOD GetAsNumber(\n\t\t\t/*in*/const tjs_char *name, /*out*/tjs_int64 *value) = 0;\n\t\t// retrieve option as a number.\n\tvirtual tjs_error TJS_INTF_METHOD GetAsString(\n\t\t\t/*in*/const tjs_char *name, /*out*/const tjs_char **out) = 0;\n\t\t// retrieve option as a string.\n\t\t// note that you must use the returned string as an one time string\n\t\t// pointer; you cannot hold its pointer and/or use it later.\n\n\tvirtual tjs_error TJS_INTF_METHOD GetValue(\n\t\t\t/*in*/const tjs_char *name, /*out*/tTJSVariant *dest) = 0;\n\t\t// retrieve option as a tTJSVariant.\n\n\tvirtual tjs_error TJS_INTF_METHOD Reserved2() = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD GetDispatchObject(iTJSDispatch2 **dsp)\n\t\t = 0;\n\t\t// retrieve internal dispatch object ( if exists )\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// iTVPSimpleImageProvider\n//---------------------------------------------------------------------------\n// image loader\nclass iTVPSimpleImageProvider\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD LoadImage(\n\t\t\t/*in*/const tjs_char *name, /*in*/tjs_int bpp,\n\t\t\t/*in*/tjs_uint32 key, \n\t\t\t/*in*/tjs_uint w,\n\t\t\t/*in*/tjs_uint h,\n\t\t\t/*out*/iTVPScanLineProvider ** scpro) = 0;\n\t\t// load an image.\n\t\t// returned image be an 8bpp bitmap when bpp == 8, otherwise\n\t\t// 32bpp.\n\t\t// key is a color key. pass 0x02ffffff for not to apply color key.\n\t\t// you must release \"scpro\" when you done with it.\n\t\t// w and h are desired size of the image. if the actual size is smaller\n\t\t// than these, the image is to be tiled. give 0, 0 to obtain original\n\t\t// sized image.\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// iTVPLayerUpdater\n//---------------------------------------------------------------------------\n// layer update region notification interface\nclass iTVPLayerUpdater\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD UpdateRect(tjs_int left,\n\t\ttjs_int top, tjs_int right, tjs_int bottom);\n\t\t// notify that the layer image had been changed.\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPDivisibleData\n//---------------------------------------------------------------------------\n// structure used by iTVPDivisibleTransHandler::Process\n#ifdef _WIN32\n#pragma pack(push, 4)\n#endif\n\nstruct tTVPDivisibleData\n{\n\t/*const*/tjs_int Left; // processing rectangle left\n\t/*const*/tjs_int Top; // processing rectangle top\n\t/*const*/tjs_int Width; // processing rectangle width\n\t/*const*/tjs_int Height; // processing rectangle height\n\tiTVPScanLineProvider *Dest; // destination image\n\ttjs_int DestLeft; // destination image rectangle's left\n\ttjs_int DestTop; // destination image rectangle's top\n\t/*const*/iTVPScanLineProvider *Src1; // source 1 (self layer image)\n\t/*const*/tjs_int Src1Left; // source 1 image rectangle's left\n\t/*const*/tjs_int Src1Top; // source 1 image rectangle's top\n\t/*const*/iTVPScanLineProvider *Src2; // source 2 (other layer image)\n\t/*const*/tjs_int Src2Left; // source 2 image rectangle's left\n\t/*const*/tjs_int Src2Top; // source 2 image rectangle's top\n};\n/* note that \"Src2\" will be null when transition type is ttSimple. */\n/* Src1Left, Src1Top, Src2Left, Src2Top are not used when the transition is\n\ttutDivisible. */\n\n#ifdef _WIN32\n#pragma pack(pop)\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// iTVPBaseTransHandler\n//---------------------------------------------------------------------------\nclass iTVPBaseTransHandler\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD AddRef() = 0;\n\tvirtual tjs_error TJS_INTF_METHOD Release() = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD SetOption(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options // option provider\n\t\t) = 0;\n\t\t// Set option for current processing transition\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPDivisibleTransHandler\n//---------------------------------------------------------------------------\nclass iTVPDivisibleTransHandler : public iTVPBaseTransHandler\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD StartProcess(\n\t\t\t/*in*/tjs_uint64 tick) = 0;\n\t\t// called before one processing time unit.\n\t\t// expected return values are:\n\t\t// TJS_S_TRUE: continue processing\n\t\t// TJS_S_FALSE: break processing\n\n\tvirtual tjs_error TJS_INTF_METHOD EndProcess() = 0;\n\t\t// called after one processing time unit.\n\t\t// expected return values are:\n\t\t// TJS_S_TRUE: continue processing\n\t\t// TJS_S_FALSE: break processing\n\n\tvirtual tjs_error TJS_INTF_METHOD Process(\n\t\t\t/*in,out*/tTVPDivisibleData *data) = 0;\n\t\t// called during StartProcess and EndProcess per an update rectangle.\n\t\t// the handler processes given rectangle and put result image to\n\t\t// \"Dest\"( in tTVPDivisibleData ).\n\t\t// given \"Dest\" is a internal image buffer, but callee can change\n\t\t// the \"Dest\" pointer to Src1 or Src2. Also DestLeft and DestTop can\n\t\t// be changed to point destination image part.\n\n\tvirtual tjs_error TJS_INTF_METHOD MakeFinalImage(\n\t\t\t/*in,out*/iTVPScanLineProvider ** dest, // destination\n\t\t\t/*in*/iTVPScanLineProvider * src1, // source 1\n\t\t\t/*in*/iTVPScanLineProvider * src2 // source 2\n\t\t\t) = 0;\n\t\t// will be called after StartProcess/EndProcess returns TJS_S_FALSE.\n\t\t// this function does not called in some occasions.\n\t\t// fill \"dest\" to make a final image.\n\t\t// dest can be set to either src1 or src2.\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPGiveUpdateTransHandler\n//---------------------------------------------------------------------------\nclass iTVPGiveUpdateTransHandler : public iTVPBaseTransHandler\n{\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD Process(\n\t\t\t/*in*/tjs_uint64 tick, // tick count provided by the system in ms\n\t\t\t/*in*/iTVPLayerUpdater * updater, // layer updater object\n\t\t\t/*in*/iTVPScanLineProvider * dest, // destination\n\t\t\t/*in*/iTVPScanLineProvider * src1, // source 1\n\t\t\t/*in*/iTVPScanLineProvider * src2 // source 2\n\t\t) = 0;\n\t// process the transition.\n\t// callee must call updater->UpdateLayerRect when changing the layer image.\n\t// updater->UpdateLayerRect can be called more than once.\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// iTVPTransHandlerProvider\n//---------------------------------------------------------------------------\n// transition handler provider abstract class\nclass iTVPTransHandlerProvider\n{\npublic:\n\tvirtual ~iTVPTransHandlerProvider() {} // add by ZeaS\n\tvirtual tjs_error TJS_INTF_METHOD AddRef() = 0;\n\tvirtual tjs_error TJS_INTF_METHOD Release() = 0;\n\n\tvirtual tjs_error TJS_INTF_METHOD GetName(\n\t\t\t/*out*/const tjs_char ** name) = 0;\n\t\t// return this transition name\n\n\tvirtual tjs_error TJS_INTF_METHOD StartTransition(\n\t\t\t/*in*/iTVPSimpleOptionProvider *options, // option provider\n\t\t\t/*in*/iTVPSimpleImageProvider *imagepro, // image provider\n\t\t\t/*in*/tTVPLayerType layertype, // destination layer type\n\t\t\t/*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size\n\t\t\t/*in*/tjs_uint src2w, tjs_uint src2h, // source 2 size\n\t\t\t/*out*/tTVPTransType *type, // transition type\n\t\t\t/*out*/tTVPTransUpdateType * updatetype, // update typwe\n\t\t\t/*out*/iTVPBaseTransHandler ** handler // transition handler\n\t\t\t) = 0;\n\t\t// start transition and return a handler.\n\t\t// \"handler\" is an object of iTVPDivisibleTransHandler when\n\t\t// updatetype is tutDivisibleFade or tutDivisible.\n\t\t// Otherwise is an object of iTVPGiveUpdateTransHandler ( cast to\n\t\t// each class to use it )\n\t\t// layertype is the destination layer type.\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n#endif\n\n\n\n"
  },
  {
    "path": "src/core/visual/tvpfontstruc.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"tTVPFont\" definition\n//---------------------------------------------------------------------------\n\n#ifndef __TVPFONTSTRUC_H__\n#define __TVPFONTSTRUC_H__\n\n#include \"tjsCommHead.h\"\n\n//---------------------------------------------------------------------------\n// tTVPFont definition\n//---------------------------------------------------------------------------\nstruct tTVPFont\n{\n\ttjs_int Height; // height of text\n\ttjs_uint32 Flags;\n\ttjs_int Angle; // rotation angle ( in tenths of degrees ) 0 .. 1800 .. 3600\n\n\tttstr Face; // font name\n\n\tbool operator == (const tTVPFont & rhs) const\n\t{\n\t\treturn Height == rhs.Height &&\n\t\t\tFlags == rhs.Flags &&\n\t\t\tAngle == rhs.Angle && \n\t\t\tFace == rhs.Face;\n\t}\n\tbool operator != (const tTVPFont & rhs) const {\n\t\treturn !(operator==(rhs));\n\t}\n};\n\n\n/*[*/\n//---------------------------------------------------------------------------\n// font ralated constants\n//---------------------------------------------------------------------------\n#define TVP_TF_ITALIC    0x0100\n#define TVP_TF_BOLD      0x0200\n#define TVP_TF_UNDERLINE 0x0400\n#define TVP_TF_STRIKEOUT 0x0800\n#define TVP_TF_FONTFILE  0x1000\n\n\n//---------------------------------------------------------------------------\n#define TVP_FSF_FIXEDPITCH    0x01      // fsfFixedPitch\n#define TVP_FSF_SAMECHARSET   0x02      // fsfSameCharSet\n#define TVP_FSF_NOVERTICAL    0x04      // fsfNoVertical\n#define TVP_FSF_TRUETYPEONLY  0x08      // fsfTrueTypeOnly\n#define TVP_FSF_IGNORESYMBOL  0x10      // fsfIgnoreSymbol\n#define TVP_FSF_USEFONTFACE   0x100  // fsfUseFontFace\n\n/*]*/\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/tvpgl.cpp",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n\n/* core C routines for graphics operations */\n/* this file is always generated by gengl.pl rev. 0.1 */\n\n/* #include \"tjsCommHead.h\" */\n#include <string.h>\n#include <math.h>\n#include \"tjsTypes.h\"\n#include \"tvpgl.h\"\n// #include \"Protect.h\"\n#include <float.h>\n\n#define __cdecl\n#define TVP_REVRGB(v) ((v & 0xFF00FF00) | ((v >> 16) & 0xFF) | ((v & 0xFF) << 16))\n\nextern void TVPGL_C_Init();\nextern \"C\" {\n/*-----------------------------------------------------------------*/\nunsigned char TVPDivTable[256*256];\nunsigned char TVPOpacityOnOpacityTable[256*256];\nunsigned char TVPNegativeMulTable[256*256];\n/* following two are for 65-level anti-aliased letter drawing */\n/* ( TVPApplyColorMap65_d and TVPApplyColorMap65_do ) */\nunsigned char TVPOpacityOnOpacityTable65[65*256];\nunsigned char TVPNegativeMulTable65[65*256];\nunsigned char TVPTable65_255[65];\nunsigned char TVPDitherTable_5_6[8][4][2][256];\nunsigned char TVPDitherTable_676[3][4][4][256];\nunsigned char TVP252DitherPalette[3][256];\ntjs_uint32 TVPRecipTable256[256]; /* 1/x  table  ( 65536 ) multiplied */\ntjs_uint16 TVPRecipTable256_16[256]; /* 1/x  table  ( 65536 ) multiplied,\n\tbut limitted to 32767 (signed 16bits) */\ntjs_uint16 TVPRecipTableForOpacityOnOpacity[256]; /* 1/x table (65536) multiplied,\n                                                  limitted to 65535(unsigned 16bits)*/\nstatic const tjs_uint8 TVPDither4x4[4][4] = {\n {   0, 12,  2, 14   },\n {   8,  4, 10,  6   },\n {   3, 15,  1, 13   },\n {  11,  7,  9,  5   }};\n\n#define TVP_TLG6_GOLOMB_HALF_THRESHOLD 8\n\n\n#define TVP_TLG6_GOLOMB_N_COUNT  4\n#define TVP_TLG6_LeadingZeroTable_BITS 12\n#define TVP_TLG6_LeadingZeroTable_SIZE  (1<<TVP_TLG6_LeadingZeroTable_BITS)\ntjs_uint8 TVPTLG6LeadingZeroTable[TVP_TLG6_LeadingZeroTable_SIZE];\nshort int TVPTLG6GolombCompressed[TVP_TLG6_GOLOMB_N_COUNT][9] = {\n\t\t{3,7,15,27,63,108,223,448,130,},\n\t\t{3,5,13,24,51,95,192,384,257,},\n\t\t{2,5,12,21,39,86,155,320,384,},\n\t\t{2,3,9,18,33,61,129,258,511,},\n\t/* Tuned by W.Dee, 2004/03/25 */\n};\nchar TVPTLG6GolombBitLengthTable\n\t[TVP_TLG6_GOLOMB_N_COUNT*2*128][TVP_TLG6_GOLOMB_N_COUNT] =\n\t{ { 0 } };\n\n\nstatic void TVPPsMakeTable(void);\n\nstatic void TVPTLG6InitLeadingZeroTable(void)\n{\n\t/* table which indicates first set bit position + 1. */\n\t/* this may be replaced by BSF (IA32 instrcution). */\n\n\tint i;\n\tfor(i = 0; i < TVP_TLG6_LeadingZeroTable_SIZE; i++)\n\t{\n\t\tint cnt = 0;\n\t\tint j;\n\t\tfor(j = 1; j != TVP_TLG6_LeadingZeroTable_SIZE && !(i & j);\n\t\t\tj <<= 1, cnt++);\n\t\tcnt ++;\n\t\tif(j == TVP_TLG6_LeadingZeroTable_SIZE) cnt = 0;\n\t\tTVPTLG6LeadingZeroTable[i] = cnt;\n\t}\n}\n\nvoid TVPTLG6InitGolombTable(void)\n{\n\tint n, i, j;\n\tfor(n = 0; n < TVP_TLG6_GOLOMB_N_COUNT; n++)\n\t{\n\t\tint a = 0;\n\t\tfor(i = 0; i < 9; i++)\n\t\t{\n\t\t\tfor(j = 0; j < TVPTLG6GolombCompressed[n][i]; j++)\n\t\t\t\tTVPTLG6GolombBitLengthTable[a++][n] = (char)i;\n\t\t}\n\t\tif (a != TVP_TLG6_GOLOMB_N_COUNT * 2 * 128) {\n#ifdef _MSC_VER\n\t\t\t*(char*)0 = 0;   /* THIS MUST NOT BE EXECUETED! */\n#else\n\t\t\t__builtin_trap();\n#endif\n\t\t\t/* (this is for compressed table data check) */\n\t\t}\n\t}\n}\n\n\nstatic void TVPInitDitherTable(void)\n{\n\t/* create an ordered dither table for conversion of 8bit->6bit and 8bit->5bit and */\n\t/* RGB ( 256*256*256 ) -> palettized 252 colors ( 6*7*6 ) */\n\ttjs_int j, i, r, g, b, c;\n\n\tfor(j = 0; j < 4; j ++)\n\t{\n\t\tfor(i = 0; i < 4; i ++)\n\t\t{\n\t\t\tdouble v1 = TVPDither4x4[j][i] / 16.0;\n\t\t\tdouble v2 = TVPDither4x4[((j+1)%2)][((i+1)%2)] / 16.0;\n\t\t\tdouble v3 = TVPDither4x4[j][((i+1)%2)] / 16.0;\n\n\t\t\tint n;\n\n\t\t\tfor(n = 0; n < 256; n++)\n\t\t\t{\n\t\t\t\tdouble nt = n / 255.0;\n\t\t\t\tdouble frac;\n\t\t\t\tint main;\n\n\t\t\t\t/* for 5bit */\n\t\t\t\tmain = (int)(nt * 31.0);\n\t\t\t\tfrac = nt * 31.0 - (int)(nt * 31.0);\n\t\t\t\tTVPDitherTable_5_6[j][i][0][n] = main + ((v1 < frac)?1:0);\n\t\t\t\tTVPDitherTable_5_6[j+4][i][0][n] = TVPDitherTable_5_6[j][i][0][n];\n\n\t\t\t\t/* for 6bit */\n\t\t\t\tmain = (int)(nt * 63.0);\n\t\t\t\tfrac = nt * 63.0 - (int)(nt * 63.0);\n\t\t\t\tTVPDitherTable_5_6[j][i][1][n] = main + ((v2 < frac)?1:0);\n\t\t\t\tTVPDitherTable_5_6[j+4][i][1][n] = TVPDitherTable_5_6[j][i][1][n];\n\n\t\t\t\t/* 256 level -> 6 level R, B */\n\t\t\t\tmain = (int)(nt * 5);\n\t\t\t\tfrac = nt * 5 - (int)(nt * 5);\n\t\t\t\tTVPDitherTable_676[2][i][j][n] = (main + ((v1 < frac)?1:0)) * (6 * 7);\n\t\t\t\tTVPDitherTable_676[0][i][j][n] = (main + ((v2 < frac)?1:0));\n\n\t\t\t\t/* 256 level -> 7 level G */\n\t\t\t\tmain = (int)(nt * 6);\n\t\t\t\tfrac = nt * 6 - (int)(nt * 6);\n\t\t\t\tTVPDitherTable_676[1][i][j][n] = (main + ((v3 < frac)?1:0)) * (6);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* create 256 colors dither palette table */\n\t/* ( 252 colors are used ) */\n\tc = 0;\n\tfor(r = 0; r < 6; r++)\n\t{\n\t\tfor(g = 0; g < 7; g++)\n\t\t{\n\t\t\tfor(b = 0; b < 6; b++)\n\t\t\t{\n\t\t\t\tTVP252DitherPalette[0][c] = r * 255 / 5;\n\t\t\t\tTVP252DitherPalette[1][c] = g * 255 / 6;\n\t\t\t\tTVP252DitherPalette[2][c] = b * 255 / 5;\n\t\t\t\tc ++;\n\t\t\t}\n\t\t}\n\t}\n\tfor(; c < 256; c++)\n\t{\n\t\tTVP252DitherPalette[0][c] =\n\t\tTVP252DitherPalette[1][c] =\n\t\tTVP252DitherPalette[2][c] = 0;\n\t}\n\n\t/* create TVPRecipTable256 */\n\tTVPRecipTable256[0] = 65536;\n\tTVPRecipTable256_16[0] = 0x7fff;\n    TVPRecipTableForOpacityOnOpacity[0] = 0;\n\tfor(i = 1; i < 256; i++)\n\t{\n\t\tTVPRecipTable256[i] = 65536/i;\n\t\tTVPRecipTable256_16[i] = TVPRecipTable256[i] > 0x7fff ?\n\t\t\t\t\t\t\t\t\t0x7fff : TVPRecipTable256[i];\n        TVPRecipTableForOpacityOnOpacity[i] = 65535 / i;\n\t}\n}\n\n\nstatic void TVPCreateTable(void)\n{\n\tint a,b;\n\n\tfor(a=0; a<256; a++)\n\t{\n\t\tfor(b=0; b<256; b++)\n\t\t{\n\t\t\tfloat c;\n\t\t\tint ci;\n\t\t\tint addr = b*256+ a;\n\n\t\t\tif(a)\n\t\t\t{\n\t\t\t\tfloat at = a/255.0, bt = b/255.0;\n\t\t\t\tc = bt / at;\n\t\t\t\tc /= (1.0 - bt + c);\n\t\t\t\tci = (int)(c*255);\n\t\t\t\tif(ci>=256) ci = 255; /* will not overflow... */\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tci=255;\n\t\t\t}\n\n\t\t\tTVPOpacityOnOpacityTable[addr]=(unsigned char)ci;\n\t\t\t\t/* higher byte of the index is source opacity */\n\t\t\t\t/* lower byte of the index is destination opacity */\n\t\t\n\t\t\tTVPNegativeMulTable[addr] = (unsigned char)\n\t\t\t\t( 255 - (255-a)*(255-b)/ 255 ); \n\t\t}\n\t}\n\n\tfor(a=0; a<256; a++)\n\t{\n\t\tfor(b=0; b<65; b++)\n\t\t{\n\t\t\tfloat c;\n\t\t\tint ci;\n\t\t\tint addr = b*256+ a;\n\t\t\tint bb;\n\n\t\t\tif(a)\n\t\t\t{\n\t\t\t\tfloat at = a / 255.0, bt = b / 64.0;\n\t\t\t\tc = bt / at;\n\t\t\t\tc /= (1.0 - bt + c);\n\t\t\t\tci = (int)(c*255);\n\t\t\t\tif(ci>=256) ci = 255; /* will not overflow... */\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tci=255;\n\t\t\t}\n\n\t\t\tTVPOpacityOnOpacityTable65[addr]=(unsigned char)ci;\n\t\t\t\t/* higher byte of the index is source opacity */\n\t\t\t\t/* lower byte of the index is destination opacity */\n\n\t\t\tbb = b * 4;\n\t\t\tif(bb > 255) bb = 255;\n\t\t\tTVPNegativeMulTable65[addr] = (unsigned char)\n\t\t\t\t( 255 - (255-a)*(255-bb)/ 255 ); \n\t\t}\n\t}\n\n    for(a=0; a<65; a++) {\n\t\tTVPTable65_255[a] = float(a) / 65 * 255;\n    }\n\n\tfor(b=0; b<256; b++)\n\t{\n\t\tTVPDivTable[(0<<8)+b] = 0;\n\t\tfor(a=1; a<256; a++)\n\t\t{\n\t\t\ttjs_int tmp = (tjs_int)(b*255/a);\n\t\t\tif(tmp > 255) tmp = 255;\n\t\t\tTVPDivTable[(a<<8)+b] = (tjs_uint8)(tmp);\n\t\t}\n\t}\n\n\n\tTVPInitDitherTable();\n\tTVPTLG6InitLeadingZeroTable();\n\tTVPTLG6InitGolombTable();\n\tTVPPsMakeTable();\n}\n\nstatic void TVPDestroyTable(void)\n{\n\t/* nothing to do ... */\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_d_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n    if(s <= 0xFFFFFF) {\n        // *dest = *dest\n    } else if(s >= 0xFF000000) {\n        *dest = s;\n    } else {\n        d = *dest;\n        if(d <= 0xFFFFFF) {\n            *dest = s;\n        } else {\n            addr = ((s >> 16) & 0xff00) + (d>>24);\n            destalpha = TVPNegativeMulTable[addr]<<24;\n            sopa = TVPOpacityOnOpacityTable[addr];\n            d1 = d & 0xff00ff;\n            d1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n            d &= 0xff00;\n            s &= 0xff00;\n            *dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n        }\n    }\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n    src++;\n    if(s <= 0xFFFFFF) {\n        // *dest = *dest\n    } else if(s >= 0xFF000000) {\n        *dest = s;\n    } else {\n        d = *dest;\n        if(d <= 0xFFFFFF) {\n            *dest = s;\n        } else {\n            addr = ((s >> 16) & 0xff00) + (d>>24);\n            destalpha = TVPNegativeMulTable[addr]<<24;\n            sopa = TVPOpacityOnOpacityTable[addr];\n            d1 = d & 0xff00ff;\n            d1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n            d &= 0xff00;\n            s &= 0xff00;\n            *dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n        }\n    }\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n    src++;\n    if(s <= 0xFFFFFF) {\n        // *dest = *dest\n    } else if(s >= 0xFF000000) {\n        *dest = s;\n    } else {\n        d = *dest;\n        if(d <= 0xFFFFFF) {\n            *dest = s;\n        } else {\n            addr = ((s >> 16) & 0xff00) + (d>>24);\n            destalpha = TVPNegativeMulTable[addr]<<24;\n            sopa = TVPOpacityOnOpacityTable[addr];\n            d1 = d & 0xff00ff;\n            d1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n            d &= 0xff00;\n            s &= 0xff00;\n            *dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n        }\n    }\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n    src++;\n    if(s <= 0xFFFFFF) {\n        // *dest = *dest\n    } else if(s >= 0xFF000000) {\n        *dest = s;\n    } else {\n        d = *dest;\n        if(d <= 0xFFFFFF) {\n            *dest = s;\n        } else {\n            addr = ((s >> 16) & 0xff00) + (d>>24);\n            destalpha = TVPNegativeMulTable[addr]<<24;\n            sopa = TVPOpacityOnOpacityTable[addr];\n            d1 = d & 0xff00ff;\n            d1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n            d &= 0xff00;\n            s &= 0xff00;\n            *dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n        }\n    }\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_a_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_d(dest[(___index+0)], src[(___index+0)]);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_d(dest[(___index+1)], src[(___index+1)]);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_d(dest[(___index+2)], src[(___index+2)]);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_d(dest[(___index+3)], src[(___index+3)]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_d(dest[___index], src[___index]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_do_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaBlend_ao_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_d_o(dest[(___index+0)], src[(___index+0)], opa);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_d_o(dest[(___index+1)], src[(___index+1)], opa);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_d_o(dest[(___index+2)], src[(___index+2)], opa);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_d_o(dest[(___index+3)], src[(___index+3)], opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_d_o(dest[___index], src[___index], opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAlphaColorMat_c, (tjs_uint32 *dest, const tjs_uint32 color, tjs_int len))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *dest;\n\td = color;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + 0xff000000;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *dest;\n\td = color;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + 0xff000000;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *dest;\n\td = color;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + 0xff000000;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *dest;\n\td = color;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + 0xff000000;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_n_a(dest[(___index+0)], src[(___index+0)]);\n\tdest[(___index+1)] = TVPAddAlphaBlend_n_a(dest[(___index+1)], src[(___index+1)]);\n\tdest[(___index+2)] = TVPAddAlphaBlend_n_a(dest[(___index+2)], src[(___index+2)]);\n\tdest[(___index+3)] = TVPAddAlphaBlend_n_a(dest[(___index+3)], src[(___index+3)]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_n_a(dest[___index], src[___index]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_HDA_n_a(dest[(___index+0)], src[(___index+0)]);\n\tdest[(___index+1)] = TVPAddAlphaBlend_HDA_n_a(dest[(___index+1)], src[(___index+1)]);\n\tdest[(___index+2)] = TVPAddAlphaBlend_HDA_n_a(dest[(___index+2)], src[(___index+2)]);\n\tdest[(___index+3)] = TVPAddAlphaBlend_HDA_n_a(dest[(___index+3)], src[(___index+3)]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_HDA_n_a(dest[___index], src[___index]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_n_a_o(dest[(___index+0)], src[(___index+0)], opa);\n\tdest[(___index+1)] = TVPAddAlphaBlend_n_a_o(dest[(___index+1)], src[(___index+1)], opa);\n\tdest[(___index+2)] = TVPAddAlphaBlend_n_a_o(dest[(___index+2)], src[(___index+2)], opa);\n\tdest[(___index+3)] = TVPAddAlphaBlend_n_a_o(dest[(___index+3)], src[(___index+3)], opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_n_a_o(dest[___index], src[___index], opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_HDA_n_a_o(dest[(___index+0)], src[(___index+0)], opa);\n\tdest[(___index+1)] = TVPAddAlphaBlend_HDA_n_a_o(dest[(___index+1)], src[(___index+1)], opa);\n\tdest[(___index+2)] = TVPAddAlphaBlend_HDA_n_a_o(dest[(___index+2)], src[(___index+2)], opa);\n\tdest[(___index+3)] = TVPAddAlphaBlend_HDA_n_a_o(dest[(___index+3)], src[(___index+3)], opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_HDA_n_a_o(dest[___index], src[___index], opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_d_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = 0;\n\tdest[(___index+1)] = 0;\n\tdest[(___index+2)] = 0;\n\tdest[(___index+3)] = 0;\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = 0;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_a_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_a(dest[(___index+0)], src[(___index+0)]);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_a(dest[(___index+1)], src[(___index+1)]);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_a(dest[(___index+2)], src[(___index+2)]);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_a(dest[(___index+3)], src[(___index+3)]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_a(dest[___index], src[___index]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_do_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = 0;\n\tdest[(___index+1)] = 0;\n\tdest[(___index+2)] = 0;\n\tdest[(___index+3)] = 0;\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = 0;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdditiveAlphaBlend_ao_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_a_o(dest[(___index+0)], src[(___index+0)], opa);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_a_o(dest[(___index+1)], src[(___index+1)], opa);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_a_o(dest[(___index+2)], src[(___index+2)], opa);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_a_o(dest[(___index+3)], src[(___index+3)], opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_a_o(dest[___index], src[___index], opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConvertAdditiveAlphaToAlpha_c, (tjs_uint32 *buf, tjs_int len))\n{/*MAY LOOSE ADDITIVE STUFF*/\n\ttjs_uint32 tmp;\n\tconst tjs_uint8 * t;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttmp = *buf;\n\tt = ((tmp >> 16) & 0xff00) + TVPDivTable;\n\t*buf = (tmp & 0xff000000) +\n\t\t(t[(tmp >> 16) & 0xff] << 16) +\n\t\t(t[(tmp >>  8) & 0xff] <<  8) +\n\t\t(t[ tmp        & 0xff]      );\n\tbuf++;\n}\n;\n\tcase 3: {\n\ttmp = *buf;\n\tt = ((tmp >> 16) & 0xff00) + TVPDivTable;\n\t*buf = (tmp & 0xff000000) +\n\t\t(t[(tmp >> 16) & 0xff] << 16) +\n\t\t(t[(tmp >>  8) & 0xff] <<  8) +\n\t\t(t[ tmp        & 0xff]      );\n\tbuf++;\n}\n;\n\tcase 2: {\n\ttmp = *buf;\n\tt = ((tmp >> 16) & 0xff00) + TVPDivTable;\n\t*buf = (tmp & 0xff000000) +\n\t\t(t[(tmp >> 16) & 0xff] << 16) +\n\t\t(t[(tmp >>  8) & 0xff] <<  8) +\n\t\t(t[ tmp        & 0xff]      );\n\tbuf++;\n}\n;\n\tcase 1: {\n\ttmp = *buf;\n\tt = ((tmp >> 16) & 0xff00) + TVPDivTable;\n\t*buf = (tmp & 0xff000000) +\n\t\t(t[(tmp >> 16) & 0xff] << 16) +\n\t\t(t[(tmp >>  8) & 0xff] <<  8) +\n\t\t(t[ tmp        & 0xff]      );\n\tbuf++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConvertAlphaToAdditiveAlpha_c, (tjs_uint32 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tbuf[(___index+0)] = TVPAlphaToAdditiveAlpha(buf[(___index+0)]);\n\tbuf[(___index+1)] = TVPAlphaToAdditiveAlpha(buf[(___index+1)]);\n\tbuf[(___index+2)] = TVPAlphaToAdditiveAlpha(buf[(___index+2)]);\n\tbuf[(___index+3)] = TVPAlphaToAdditiveAlpha(buf[(___index+3)]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tbuf[___index] = TVPAlphaToAdditiveAlpha(buf[___index]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_HDA_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_do_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAlphaBlend_ao_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpStretchAdditiveAlphaBlend_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep))\n{\n\t/* stretching additive alpha blend with bilinear interpolation */\n\ttjs_int blend_x;\n\ttjs_int sp;\n\n\tblend_y += blend_y >> 7; /* adjust blend ratio */\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPAddAlphaBlend_n_a(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y));\n\t\tsrcstart += srcstep;\n\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[1] = TVPAddAlphaBlend_n_a(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y));\n\t\tsrcstart += srcstep;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPAddAlphaBlend_n_a(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y));\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpStretchAdditiveAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\t/* stretching additive alpha blend with bilinear interpolation */\n\ttjs_int blend_x;\n\ttjs_int sp;\n\n\tblend_y += blend_y >> 7; /* adjust blend ratio */\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPAddAlphaBlend_n_a_o(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[1] = TVPAddAlphaBlend_n_a_o(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPAddAlphaBlend_n_a_o(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_HDA_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 3: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 2: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 1: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, src[srcstart >> 16]);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_do_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 3: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 2: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\tcase 1: {\n\tsrcstart += srcstep;\n\t*dest = 0;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchAdditiveAlphaBlend_ao_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, src[srcstart >> 16], opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = s >> 24;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000); /* hda */\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_HDA_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\tsopa = ((s >> 24) * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = ((s >> 16) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_d(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_do_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, sopa, addr, destalpha;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 + ((d + ((s - d) * sopa >> 8)) & 0xff00) + destalpha;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAlphaBlend_ao_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_d_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpLinTransAdditiveAlphaBlend_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\t/* bilinear interpolation version */\n\t/* note that srcpitch unit is in byte */\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPAddAlphaBlend_n_a(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y));\n\t\tsx += stepx, sy += stepy;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[1] = TVPAddAlphaBlend_n_a(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y));\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPAddAlphaBlend_n_a(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y));\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/* HDA : hold destination alpha */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpLinTransAdditiveAlphaBlend_o_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\t/* bilinear interpolation version */\n\t/* note that srcpitch unit is in byte */\n\topa += opa >> 7;\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPAddAlphaBlend_n_a_o(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[1] = TVPAddAlphaBlend_n_a_o(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPAddAlphaBlend_n_a_o(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA_o_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_HDA_n_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_do_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = 0;\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransAdditiveAlphaBlend_ao_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a_o(*dest, \n\t\t*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)), opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPCopyOpaqueImage_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\ttjs_uint32 t1, t2;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = src[(___index+(0*2))];\n\tt2 = src[(___index+(0*2+1))];\n\tt1 |= 0xff000000;\n\tt2 |= 0xff000000;\n\tdest[(___index+(0*2))] = t1;\n\tdest[(___index+(0*2+1))] = t2;\n\tt1 = src[(___index+(1*2))];\n\tt2 = src[(___index+(1*2+1))];\n\tt1 |= 0xff000000;\n\tt2 |= 0xff000000;\n\tdest[(___index+(1*2))] = t1;\n\tdest[(___index+(1*2+1))] = t2;\n\tt1 = src[(___index+(2*2))];\n\tt2 = src[(___index+(2*2+1))];\n\tt1 |= 0xff000000;\n\tt2 |= 0xff000000;\n\tdest[(___index+(2*2))] = t1;\n\tdest[(___index+(2*2+1))] = t2;\n\tt1 = src[(___index+(3*2))];\n\tt2 = src[(___index+(3*2+1))];\n\tt1 |= 0xff000000;\n\tt2 |= 0xff000000;\n\tdest[(___index+(3*2))] = t1;\n\tdest[(___index+(3*2+1))] = t2;\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = src[___index];;\n\tt1 |= 0xff000000;;\n\tdest[___index] = t1;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_d_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, addr;\n\ttjs_int alpha;\n\topa <<= 8;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *src;\n\tsrc++;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_a_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n\topa <<= 24;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_a(dest[(___index+0)], (src[(___index+0)] & 0xffffff) | opa);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_a(dest[(___index+1)], (src[(___index+1)] & 0xffffff) | opa);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_a(dest[(___index+2)], (src[(___index+2)] & 0xffffff) | opa);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_a(dest[(___index+3)], (src[(___index+3)] & 0xffffff) | opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_a(dest[___index], (src[___index] & 0xffffff) | opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchCopyOpaqueImage_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = 0xff000000 | src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[1] = 0xff000000 | src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[2] = 0xff000000 | src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[3] = 0xff000000 | src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = 0xff000000 | src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchConstAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart>>16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart>>16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart>>16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart>>16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpStretchConstAlphaBlend_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\t/* stretch copy with bilinear interpolation */\n\ttjs_int blend_x;\n\ttjs_int sp;\n\n\tblend_y += blend_y >> 7; /* adjust blend ratio */\n\topa += opa >> 7; /* adjust opa */\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPBlendARGB(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[1] = TVPBlendARGB(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPBlendARGB(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchConstAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchConstAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, addr;\n\ttjs_int alpha;\n\tif(opa > 128) opa ++; /* adjust for error */\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = src[srcstart >> 16];\n\tsrcstart += srcstep;\n\td = *dest;\n\taddr = (( (s>>24)*opa) & 0xff00) + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchConstAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa))\n{\n\topa <<= 24;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, (src[srcstart >> 16] & 0xffffff) | opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, (src[srcstart >> 16] & 0xffffff) | opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, (src[srcstart >> 16] & 0xffffff) | opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, (src[srcstart >> 16] & 0xffffff) | opa);\n\tsrcstart += srcstep;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransCopyOpaqueImage_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = 0xff000000 | *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx;\n\t\tsy += stepy;\n\t\tdest[1] = 0xff000000 | *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx;\n\t\tsy += stepy;\n\t\tdest[2] = 0xff000000 | *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx;\n\t\tsy += stepy;\n\t\tdest[3] = 0xff000000 | *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx;\n\t\tsy += stepy;\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = 0xff000000 | *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx;\n\t\tsy += stepy;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransConstAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = (d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpLinTransConstAlphaBlend_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\t/* bilinear interpolation version */\n\t/* note that srcpitch unit is in byte */\n\topa += opa >> 7; /* adjust opacity */\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPBlendARGB(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[1] = TVPBlendARGB(dest[1], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPBlendARGB(dest[0], TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y), opa);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransConstAlphaBlend_HDA_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransConstAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\ttjs_uint32 d1, s, d, addr;\n\ttjs_int alpha;\n\topa <<= 8;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts = *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\tsx += stepx;\n\tsy += stepy;\n\td = *dest;\n\taddr = opa + (d>>24);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + (((s & 0xff00ff) - d1) * alpha >> 8)) & 0xff00ff) +\n\t\t(TVPNegativeMulTable[addr]<<24);\n\td &= 0xff00;\n\ts &= 0xff00;\n\t*dest = d1 | ((d + ((s - d) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransConstAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa))\n{\n\topa <<= 24;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t((*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16))) & 0xffffff) | opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 3: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t((*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16))) & 0xffffff) | opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 2: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t((*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16))) & 0xffffff) | opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\tcase 1: {\n\t*dest = TVPAddAlphaBlend_a_a(*dest, \n\t\t((*( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16))) & 0xffffff) | opa);\n\tsx += stepx;\n\tsy += stepy;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_SD_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa))\n{\n\ttjs_uint32 s1_, s1, s2;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts1 = *src1;\n\ts2 = *src2;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\tsrc1++;\n\tsrc2++;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\tsrc1++;\n\tsrc2++;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\tsrc1++;\n\tsrc2++;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\tsrc1++;\n\tsrc2++;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_SD_a_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPBlendARGB(src1[(___index+0)], src2[(___index+0)], opa);\n\tdest[(___index+1)] = TVPBlendARGB(src1[(___index+1)], src2[(___index+1)], opa);\n\tdest[(___index+2)] = TVPBlendARGB(src1[(___index+2)], src2[(___index+2)], opa);\n\tdest[(___index+3)] = TVPBlendARGB(src1[(___index+3)], src2[(___index+3)], opa);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPBlendARGB(src1[___index], src2[___index], opa);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstAlphaBlend_SD_d_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa))\n{/* alpha vs alpha, destination has alpha */\n\ttjs_uint32 s1_, s2, s1, addr;\n\ttjs_uint32 a1, a2;\n\ttjs_int alpha;\n\ttjs_int iopa;\n\tif(opa > 127) opa ++; /* adjust for error */\n\tiopa = 256 - opa;\n\t/* blending function for 'alpha-per-pixel enabled alpha blending' is complex. */\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*iopa >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*iopa >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*iopa >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*iopa >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInitUnivTransBlendTable_c, (tjs_uint32 *table, tjs_int phase, tjs_int vague))\n{\n\ttjs_int i;\n\ttjs_int phasemax = phase;\n\tphase -= vague;\n\tfor(i = 0; i<256; i++)\n\t{\n\t\tif(i<phase) table[i] = 255;\n\t\telse if(i>=phasemax) table[i] = 0;\n\t\telse\n\t\t{\n\t\t\tint tmp = (255-(( i - phase )*255 / vague));\n\t\t\tif(tmp<0) tmp = 0;\n\t\t\tif(tmp>255) tmp = 255;\n\t\t\ttable[i] = tmp;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInitUnivTransBlendTable_d_c, (tjs_uint32 *table, tjs_int phase, tjs_int vague))\n{\n\t/* alias to TVPInitUnivTransBlendTable_c */\n\tTVPInitUnivTransBlendTable_c(table, phase, vague);\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInitUnivTransBlendTable_a_c, (tjs_uint32 *table, tjs_int phase, tjs_int vague))\n{\n\t/* alias to TVPInitUnivTransBlendTable_c */\n\tTVPInitUnivTransBlendTable_c(table, phase, vague);\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len))\n{\n\ttjs_uint32 s1_, s1, s2;\n\ttjs_int opa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\tsrc1++;\n\ts2 = *src2;\n\tsrc2++;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\tsrc1++;\n\ts2 = *src2;\n\tsrc2++;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\tsrc1++;\n\ts2 = *src2;\n\tsrc2++;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\tsrc1++;\n\ts2 = *src2;\n\tsrc2++;\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\ts2 &= 0xff00;\n\ts1 &= 0xff00;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_switch_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv))\n{\n\ttjs_uint32 s1_, s1, s2;\n\ttjs_int opa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\tsrc1++;\n\t\ts2 = *src2;\n\t\tsrc2++;\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\t\ts2 &= 0xff00;\n\t\ts1 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 3: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\tsrc1++;\n\t\ts2 = *src2;\n\t\tsrc2++;\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\t\ts2 &= 0xff00;\n\t\ts1 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 2: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\tsrc1++;\n\t\ts2 = *src2;\n\t\tsrc2++;\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\t\ts2 &= 0xff00;\n\t\ts1 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 1: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\tsrc1++;\n\t\ts2 = *src2;\n\t\tsrc2++;\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = (s1_ + (((s2 & 0xff00ff) - s1_) * opa >> 8)) & 0xff00ff;\n\t\ts2 &= 0xff00;\n\t\ts1 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * opa >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_d_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len))\n{\n\ttjs_uint32 s1_, s2, s1, addr;\n\ttjs_uint32 a1, a2;\n\ttjs_int alpha;\n\ttjs_int opa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 3: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 2: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\tcase 1: {\n\topa = table[*rule];\n\trule++;\n\ts1 = *src1;\n\ts2 = *src2;\n\ta1 = s1 >> 24;\n\ta2 = s2 >> 24;\n\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\talpha = TVPOpacityOnOpacityTable[addr];\n\ts1_ = s1 & 0xff00ff;\n\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff);\n\tsrc1++;\n\tsrc2++;\n\ts1 &= 0xff00;\n\ts2 &= 0xff00;\n\ts1_ |= (a1 + ((a2 - a1)*opa >> 8)) << 24;\n\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_switch_d_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv))\n{\n\ttjs_uint32 s1_, s2, s1, addr;\n\ttjs_uint32 a1, a2;\n\ttjs_int alpha;\n\ttjs_int opa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\ts2 = *src2;\n\t\ta1 = s1 >> 24;\n\t\ta2 = s2 >> 24;\n\t\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\t\talpha = TVPOpacityOnOpacityTable[addr];\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff) +\n\t\t\t(TVPNegativeMulTable[addr]<<24);\n\t\tsrc1++;\n\t\tsrc2++;\n\t\ts1 &= 0xff00;\n\t\ts2 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 3: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\ts2 = *src2;\n\t\ta1 = s1 >> 24;\n\t\ta2 = s2 >> 24;\n\t\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\t\talpha = TVPOpacityOnOpacityTable[addr];\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff) +\n\t\t\t(TVPNegativeMulTable[addr]<<24);\n\t\tsrc1++;\n\t\tsrc2++;\n\t\ts1 &= 0xff00;\n\t\ts2 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 2: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\ts2 = *src2;\n\t\ta1 = s1 >> 24;\n\t\ta2 = s2 >> 24;\n\t\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\t\talpha = TVPOpacityOnOpacityTable[addr];\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff) +\n\t\t\t(TVPNegativeMulTable[addr]<<24);\n\t\tsrc1++;\n\t\tsrc2++;\n\t\ts1 &= 0xff00;\n\t\ts2 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\tcase 1: {\n\topa = *rule;\n\tif(opa >= src1lv)\n\t{\n\t\t*dest = *src1;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse if(opa < src2lv)\n\t{\n\t\t*dest = *src2;\n\t\trule++; src1++; src2++; dest++;\n\t}\n\telse\n\t{\n\t\topa = table[opa];\n\t\trule++;\n\t\ts1 = *src1;\n\t\ts2 = *src2;\n\t\ta1 = s1 >> 24;\n\t\ta2 = s2 >> 24;\n\t\taddr = (a2*opa & 0xff00) + (a1*(256-opa) >> 8);\n\t\talpha = TVPOpacityOnOpacityTable[addr];\n\t\ts1_ = s1 & 0xff00ff;\n\t\ts1_ = ((s1_ + (((s2 & 0xff00ff) - s1_) * alpha >> 8)) & 0xff00ff) +\n\t\t\t(TVPNegativeMulTable[addr]<<24);\n\t\tsrc1++;\n\t\tsrc2++;\n\t\ts1 &= 0xff00;\n\t\ts2 &= 0xff00;\n\t\t*dest = s1_ | ((s1 + ((s2 - s1) * alpha >> 8)) & 0xff00);\n\t\tdest++;\n\t}\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_a_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPBlendARGB(src1[(___index+0)], src2[(___index+0)], table[rule[(___index+0)]]);\n\tdest[(___index+1)] = TVPBlendARGB(src1[(___index+1)], src2[(___index+1)], table[rule[(___index+1)]]);\n\tdest[(___index+2)] = TVPBlendARGB(src1[(___index+2)], src2[(___index+2)], table[rule[(___index+2)]]);\n\tdest[(___index+3)] = TVPBlendARGB(src1[(___index+3)], src2[(___index+3)], table[rule[(___index+3)]]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPBlendARGB(src1[___index], src2[___index], table[rule[___index]]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUnivTransBlend_switch_a_c, (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv))\n{\n\ttjs_int opa;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\topa = rule[(___index+0)];\n\tif(opa >= src1lv)\n\t\tdest[(___index+0)] = src1[(___index+0)];\n\telse if(opa < src2lv)\n\t\tdest[(___index+0)] = src2[(___index+0)];\n\telse\n\t\tdest[(___index+0)] = TVPBlendARGB(src1[(___index+0)], src2[(___index+0)], table[opa]);\n\topa = rule[(___index+1)];\n\tif(opa >= src1lv)\n\t\tdest[(___index+1)] = src1[(___index+1)];\n\telse if(opa < src2lv)\n\t\tdest[(___index+1)] = src2[(___index+1)];\n\telse\n\t\tdest[(___index+1)] = TVPBlendARGB(src1[(___index+1)], src2[(___index+1)], table[opa]);\n\topa = rule[(___index+2)];\n\tif(opa >= src1lv)\n\t\tdest[(___index+2)] = src1[(___index+2)];\n\telse if(opa < src2lv)\n\t\tdest[(___index+2)] = src2[(___index+2)];\n\telse\n\t\tdest[(___index+2)] = TVPBlendARGB(src1[(___index+2)], src2[(___index+2)], table[opa]);\n\topa = rule[(___index+3)];\n\tif(opa >= src1lv)\n\t\tdest[(___index+3)] = src1[(___index+3)];\n\telse if(opa < src2lv)\n\t\tdest[(___index+3)] = src2[(___index+3)];\n\telse\n\t\tdest[(___index+3)] = TVPBlendARGB(src1[(___index+3)], src2[(___index+3)], table[opa]);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\topa = rule[___index];\n\tif(opa >= src1lv)\n\t\tdest[___index] = src1[___index];\n\telse if(opa < src2lv)\n\t\tdest[___index] = src2[___index];\n\telse\n\t\tdest[___index] = TVPBlendARGB(src1[___index], src2[___index], table[opa]);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_HDA_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_HDA_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 8)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_HDA_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = *src;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_HDA_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tsopa = (*src * opa) >> 8;\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((c1 - d1) * sopa >> 6)) & 0xff00ff) + (d & 0xff000000);\n\td &= 0x00ff00;\n\t*dest = d1 | ((d + ((color - d) * sopa >> 6)) & 0x00ff00);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_d_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa, addr, destalpha;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_d_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 d1, d, sopa, addr, destalpha;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\taddr = (*src<<8) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_a_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_a_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\ttjs_int s_tmp = *src;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_do_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa, addr, destalpha;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_do_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, d, sopa, addr, destalpha;\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\taddr = ((*src * opa) & 0xff00) + (d>>24);\n\tdestalpha = TVPNegativeMulTable65[addr]<<24;\n\tsopa = TVPOpacityOnOpacityTable65[addr];\n\td1 = d & 0xff00ff;\n\td1 = (d1 + ((c1 - d1) * sopa >> 8)) & 0xff00ff;\n\td &= 0x00ff00;\n\t*dest = d1 + ((d + ((color - d) * sopa >> 8)) & 0x00ff00) + destalpha;\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap_ao_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 8) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 8) & 0x00ff00);\n\ts_tmp <<= (8 - 8);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPApplyColorMap65_ao_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 c1 = color & 0xff00ff;\n\tcolor = color & 0x00ff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 3: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 2: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\tcase 1: {\n\ttjs_int s_tmp = (*src * opa) >> 8;\n\ttjs_uint32 tmp =\n\t\t((s_tmp * (c1    & 0xff00ff) >> 6) & 0xff00ff) + \n\t\t((s_tmp * (color & 0x00ff00) >> 6) & 0x00ff00);\n\ts_tmp <<= (8 - 6);\n\ts_tmp -= (s_tmp >> 8); /* adjust alpha */\n\t*dest = TVPAddAlphaBlend_a_ca(*dest, s_tmp, s_tmp ^ 0xff, tmp);\n\tsrc++;\n\tdest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstColorAlphaBlend_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\t/* this function always holds desitination alpha channel */\n\ttjs_uint32 s1, d;\n\ts1 = (color & 0xff00ff)*opa ;\n\tcolor = (color & 0xff00)*opa ;\n\topa = 255 - opa;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\t*dest = (d & 0xff000000) + ((((d & 0xff00ff) * opa + s1) >> 8) & 0xff00ff) +\n\t\t((((d&0xff00) * opa + color) >> 8) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\t*dest = (d & 0xff000000) + ((((d & 0xff00ff) * opa + s1) >> 8) & 0xff00ff) +\n\t\t((((d&0xff00) * opa + color) >> 8) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\t*dest = (d & 0xff000000) + ((((d & 0xff00ff) * opa + s1) >> 8) & 0xff00ff) +\n\t\t((((d&0xff00) * opa + color) >> 8) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\t*dest = (d & 0xff000000) + ((((d & 0xff00ff) * opa + s1) >> 8) & 0xff00ff) +\n\t\t((((d&0xff00) * opa + color) >> 8) & 0xff00);\n\tdest ++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstColorAlphaBlend_d_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 d1, s1, d, dopa;\n\ttjs_int alpha;\n\ts1 = color & 0xff00ff;\n\tcolor = color & 0xff00;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\td = *dest;\n\tdopa = d>>24;\n\talpha = TVPOpacityOnOpacityTable[dopa + (opa<<8)];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff) |\n\t\t((255-((255-dopa)*(255-opa)>>8)) << 24);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * alpha >> 8)) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 3: {\n\td = *dest;\n\tdopa = d>>24;\n\talpha = TVPOpacityOnOpacityTable[dopa + (opa<<8)];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff) |\n\t\t((255-((255-dopa)*(255-opa)>>8)) << 24);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * alpha >> 8)) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 2: {\n\td = *dest;\n\tdopa = d>>24;\n\talpha = TVPOpacityOnOpacityTable[dopa + (opa<<8)];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff) |\n\t\t((255-((255-dopa)*(255-opa)>>8)) << 24);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * alpha >> 8)) & 0xff00);\n\tdest ++;\n}\n;\n\tcase 1: {\n\td = *dest;\n\tdopa = d>>24;\n\talpha = TVPOpacityOnOpacityTable[dopa + (opa<<8)];\n\td1 = d & 0xff00ff;\n\td1 = ((d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff) |\n\t\t((255-((255-dopa)*(255-opa)>>8)) << 24);\n\td &= 0xff00;\n\t*dest = d1 | ((d + ((color - d) * alpha >> 8)) & 0xff00);\n\tdest ++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConstColorAlphaBlend_a_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa))\n{\n\ttjs_uint32 src = TVPMulColor(color & 0xffffff, opa);\n\ttjs_uint32 opa_inv = opa ^ 0xff;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[(___index+0)] = TVPAddAlphaBlend_a_ca(dest[(___index+0)], opa, opa_inv, src);\n\tdest[(___index+1)] = TVPAddAlphaBlend_a_ca(dest[(___index+1)], opa, opa_inv, src);\n\tdest[(___index+2)] = TVPAddAlphaBlend_a_ca(dest[(___index+2)], opa, opa_inv, src);\n\tdest[(___index+3)] = TVPAddAlphaBlend_a_ca(dest[(___index+3)], opa, opa_inv, src);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tdest[___index] = TVPAddAlphaBlend_a_ca(dest[___index], opa, opa_inv, src);\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveConstOpacity_c, (tjs_uint32 *dest, tjs_int len, tjs_int strength))\n{\n\ttjs_uint32 d, d2;\n\n\tstrength = 255 - strength;\n\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[(___index+(0*2))];\n\td2 = dest[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = (d & 0xffffff) + ( (((d>>24)*strength) << 16) & 0xff000000);\n\tdest[(___index+(0*2+1))] = (d2 & 0xffffff) + ( (((d2>>24)*strength) << 16) & 0xff000000);\n\td = dest[(___index+(1*2))];\n\td2 = dest[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = (d & 0xffffff) + ( (((d>>24)*strength) << 16) & 0xff000000);\n\tdest[(___index+(1*2+1))] = (d2 & 0xffffff) + ( (((d2>>24)*strength) << 16) & 0xff000000);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[___index];;\n\tdest[___index] = (d & 0xffffff) + ( (((d>>24)*strength) << 16) & 0xff000000);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveOpacity_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len))\n{\n\ttjs_uint32 d, d2;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[(___index+(0*2))];\n\td2 = dest[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = (d & 0xffffff) + ( (((d>>24) * (255-src[(___index+(0*2))])) << 16) & 0xff000000);\n\tdest[(___index+(0*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (255-src[(___index+(0*2+1))])) << 16) & 0xff000000);\n\td = dest[(___index+(1*2))];\n\td2 = dest[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = (d & 0xffffff) + ( (((d>>24) * (255-src[(___index+(1*2))])) << 16) & 0xff000000);\n\tdest[(___index+(1*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (255-src[(___index+(1*2+1))])) << 16) & 0xff000000);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[___index];;\n\tdest[___index] = (d & 0xffffff) + ( (((d>>24) * (255-src[___index])) << 16) & 0xff000000);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveOpacity_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength))\n{\n\ttjs_uint32 d, d2;\n\n\tif(strength > 127) strength ++; /* adjust for error */\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[(___index+(0*2))];\n\td2 = dest[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = (d & 0xffffff) + ( (((d>>24) * (65535-src[(___index+(0*2))]*strength )) << 8) & 0xff000000);\n\tdest[(___index+(0*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (65535-src[(___index+(0*2+1))]*strength )) << 8) & 0xff000000);\n\td = dest[(___index+(1*2))];\n\td2 = dest[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = (d & 0xffffff) + ( (((d>>24) * (65535-src[(___index+(1*2))]*strength )) << 8) & 0xff000000);\n\tdest[(___index+(1*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (65535-src[(___index+(1*2+1))]*strength )) << 8) & 0xff000000);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[___index];;\n\tdest[___index] = (d & 0xffffff) + ( (((d>>24) * (65535-src[___index]*strength )) << 8) & 0xff000000);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveOpacity65_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len))\n{\n\ttjs_uint32 d, d2;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[(___index+(0*2))];\n\td2 = dest[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = (d & 0xffffff) + ( (((d>>24) * (64-src[(___index+(0*2))])) << 18) & 0xff000000);\n\tdest[(___index+(0*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (64-src[(___index+(0*2+1))])) << 18) & 0xff000000);\n\td = dest[(___index+(1*2))];\n\td2 = dest[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = (d & 0xffffff) + ( (((d>>24) * (64-src[(___index+(1*2))])) << 18) & 0xff000000);\n\tdest[(___index+(1*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (64-src[(___index+(1*2+1))])) << 18) & 0xff000000);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[___index];;\n\tdest[___index] = (d & 0xffffff) + ( (((d>>24) * (64-src[___index])) << 18) & 0xff000000);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveOpacity65_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength))\n{\n\ttjs_uint32 d, d2;\n\n\tif(strength > 127) strength ++; /* adjust for error */\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[(___index+(0*2))];\n\td2 = dest[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = (d & 0xffffff) + ( (((d>>24) * (16384-src[(___index+(0*2))]*strength )) << 10) & 0xff000000);\n\tdest[(___index+(0*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (16384-src[(___index+(0*2+1))]*strength )) << 10) & 0xff000000);\n\td = dest[(___index+(1*2))];\n\td2 = dest[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = (d & 0xffffff) + ( (((d>>24) * (16384-src[(___index+(1*2))]*strength )) << 10) & 0xff000000);\n\tdest[(___index+(1*2+1))] = (d2 & 0xffffff) + ( (((d2>>24) * (16384-src[(___index+(1*2+1))]*strength )) << 10) & 0xff000000);\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td = dest[___index];;\n\tdest[___index] = (d & 0xffffff) + ( (((d>>24) * (16384-src[___index]*strength )) << 10) & 0xff000000);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveAdditiveConstOpacity_c, (tjs_uint32 *dest, tjs_int len, tjs_int strength))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveAdditiveOpacity_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveAdditiveOpacity_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveAdditiveOpacity65_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n}\n\n/*not export*/\nTVP_GL_FUNC_DECL(void, TVPRemoveAdditiveOpacity65_o_c, (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength))\n{/*YET NOT IMPLEMENTED*//*MAY LOOSE ADDITIVE STUFF*/\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (*src + *dest - tmp) | tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (*src + *dest - tmp) | tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (*src + *dest - tmp) | tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (*src + *dest - tmp) | tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((*src + *dest - tmp) | tmp) & 0xffffff) | (*dest & 0xff000000) ;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((*src + *dest - tmp) | tmp) & 0xffffff) | (*dest & 0xff000000) ;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((*src + *dest - tmp) | tmp) & 0xffffff) | (*dest & 0xff000000) ;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp = (  ( *src & *dest ) + ( ((*src^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((*src + *dest - tmp) | tmp) & 0xffffff) | (*dest & 0xff000000) ;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (s + *dest - tmp) | tmp;\ndest++;\n}\n;\n\tcase 3: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (s + *dest - tmp) | tmp;\ndest++;\n}\n;\n\tcase 2: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (s + *dest - tmp) | tmp;\ndest++;\n}\n;\n\tcase 1: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (s + *dest - tmp) | tmp;\ndest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((s + *dest - tmp) | tmp) & 0xffffff) + (*dest & 0xff000000) ;\ndest++;\n}\n;\n\tcase 3: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((s + *dest - tmp) | tmp) & 0xffffff) + (*dest & 0xff000000) ;\ndest++;\n}\n;\n\tcase 2: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((s + *dest - tmp) | tmp) & 0xffffff) + (*dest & 0xff000000) ;\ndest++;\n}\n;\n\tcase 1: {\ns = ( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff);\ntmp = (  ( s & *dest ) + ( ((s^*dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\nsrc++;\ntmp = (tmp<<1) - (tmp>>7);\n*dest= (((s + *dest - tmp) | tmp) & 0xffffff) + (*dest & 0xff000000) ;\ndest++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSubBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp = (  ( *src & *dest ) + ( ((*src ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (*src + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp = (  ( *src & *dest ) + ( ((*src ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (*src + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp = (  ( *src & *dest ) + ( ((*src ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (*src + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp = (  ( *src & *dest ) + ( ((*src ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (*src + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSubBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, s;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = *src | 0xff000000;\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = *src | 0xff000000;\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = *src | 0xff000000;\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = *src | 0xff000000;\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSubBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\ns = ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\ns = ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\ns = ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\ns = ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSubBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s, d;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\ns = 0xff000000 | ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\ns = 0xff000000 | ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\ns = 0xff000000 | ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\ns = 0xff000000 | ~ (( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (  ( s & *dest ) + ( ((s ^ *dest)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest = (s + *dest - tmp) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPMulBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPMulBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp  = (*dest & 0xff) * (*src & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (*src & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (*src & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPMulBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPMulBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (*dest & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((*dest & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((*dest & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPColorDodgeBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, tmp2, tmp3;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPColorDodgeBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, tmp2, tmp3;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp2 = ~*src;\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPColorDodgeBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, tmp2, tmp3;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPColorDodgeBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, tmp2, tmp3;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ntmp2 = ~ (( ((*src&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (*src&0xff00ff) * opa >> 8)&0xff00ff) );\ntmp = (*dest & 0xff) * TVPRecipTable256[tmp2 & 0xff] >> 8;\ntmp3 = (tmp | ((tjs_int32)~(tmp - 0x100) >> 31)) & 0xff;\ntmp = ((*dest & 0xff00)>>8) * TVPRecipTable256[(tmp2 & 0xff00)>>8];\ntmp3 |= (tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00;\ntmp = ((*dest & 0xff0000)>>16) * TVPRecipTable256[(tmp2 & 0xff0000)>>16];\ntmp3 |= ((tmp | ((tjs_int32)~(tmp - 0x10000) >> 31)) & 0xff00 ) << 8;\n*dest= tmp3 + (*dest & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDarkenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, m_src;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDarkenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, m_src;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDarkenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, m_src, d1;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 3: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 2: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 1: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDarkenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, m_src, d1;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_src = ~*src;\ntmp = ((m_src & *dest) + (((m_src ^ *dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_src = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_src + ((tmp - m_src) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLightenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, m_dest;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= (*dest ^ *src) & tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLightenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, m_dest;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\n*dest ^= ((*dest ^ *src) & tmp) & 0xffffff;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLightenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, m_dest, d1;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 3: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 2: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\tcase 1: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ ((*dest ^ *src) & tmp);\nd1 = *dest & 0xff00ff;\nd1 = (d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff;\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLightenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 tmp, m_dest, d1;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nm_dest = ~*dest;\ntmp = ((*src & m_dest) + (((*src ^ m_dest) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\ntmp = (tmp << 1) - (tmp >> 7);\ntmp = *dest ^ (((*dest ^ *src) & tmp) & 0xffffff);\nd1 = *dest & 0xff00ff;\nd1 = ((d1 + (((tmp & 0xff00ff) - d1) * opa >> 8)) & 0xff00ff) + (*dest & 0xff000000); /* hda */\nm_dest = *dest & 0xff00;\ntmp &= 0xff00;\n*dest = d1 + ((m_dest + ((tmp - m_dest) * opa >> 8)) & 0xff00);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPScreenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPScreenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n  tjs_uint32 tmp, s, d;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\ns = ~*src;\nd = ~*dest;\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPScreenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s, d;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = tmp;\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPScreenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{\n  tjs_uint32 s, d;\n  tjs_uint32 tmp;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 3: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 2: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\tcase 1: {\nd = ~*dest;\ns = *src;\ns = ~( ( ((s&0x00ff00)  * opa >> 8)&0x00ff00) +\n\t(( (s&0xff00ff) * opa >> 8)&0xff00ff));\ntmp  = (d & 0xff) * (s & 0xff) & 0xff00;\ntmp |= ((d & 0xff00) >> 8) * (s & 0xff00) & 0xff0000;\ntmp |= ((d & 0xff0000) >> 16) * (s & 0xff0000) & 0xff000000;\ntmp >>= 8;\n*dest = ~tmp ^ (d & 0xff000000);\ndest++;\nsrc++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[1] = src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[2] = src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest[3] = src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[srcstart >> 16];\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpStretchCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep))\n{\n\t/* stretch copy with bilinear interpolation */\n\ttjs_int blend_x;\n\ttjs_int sp;\n\n\tblend_y += blend_y >> 7; /* adjust blend ratio */\n\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y);\n\t\tsrcstart += srcstep;\n\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[1] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y);\n\t\tsrcstart += srcstep;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tblend_x = (srcstart & 0xffff) >> 8;\n\t\tsp = srcstart >> 16;\n\t\tdest[0] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(src1[sp], src1[sp+1], blend_x),\n\t\t\tTVPBlendARGB(src2[sp], src2[sp+1], blend_x),\n\t\t\t\tblend_y);\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n#define AVG_PACKED(x, y) (((x) & (y)) + ((((x) ^ (y)) & 0xfefefefe) >> 1))\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFastLinearInterpH2F_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src))\n{\n\t/* horizontal 2x fast linear interpolation; forward */\n\tdestlen -= 2;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[0];\n\t\tdest[1] = AVG_PACKED(src[0], src[1]);\n\t\tdest += 2;\n\t\tsrc ++;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 2;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[0];\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFastLinearInterpH2B_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src))\n{\n\t/* horizontal 2x fast linear interpolation; backward */\n\tdestlen -= 2;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[0];\n\t\tdest[1] = AVG_PACKED(src[0], src[-1]);\n\t\tdest += 2;\n\t\tsrc --;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 2;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = src[0];\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFastLinearInterpV2_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src0, const tjs_uint32 *src1))\n{\n\t/* vertical 2x fast linear interpolation */\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = AVG_PACKED(src0[0], src1[0]);\n\t\tdest[1] = AVG_PACKED(src0[1], src1[1]);\n\t\tdest[2] = AVG_PACKED(src0[2], src1[2]);\n\t\tdest[3] = AVG_PACKED(src0[3], src1[3]);\n\t\tdest += 4;\n\t\tsrc0 += 4;\n\t\tsrc1 += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = AVG_PACKED(src0[0], src1[0]);\n\t\tdest ++;\n\t\tsrc0 ++;\n\t\tsrc1 ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPStretchColorCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep))\n{\n\t/* this performs only color(main) copy */\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = (dest[0] & 0xff000000) + (src[srcstart >> 16] & 0xffffff);\n\t\tsrcstart += srcstep;\n\t\tdest[1] = (dest[1] & 0xff000000) + (src[srcstart >> 16] & 0xffffff);\n\t\tsrcstart += srcstep;\n\t\tdest[2] = (dest[2] & 0xff000000) + (src[srcstart >> 16] & 0xffffff);\n\t\tsrcstart += srcstep;\n\t\tdest[3] = (dest[3] & 0xff000000) + (src[srcstart >> 16] & 0xffffff);\n\t\tsrcstart += srcstep;\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = (dest[0] & 0xff0000) + (src[srcstart >> 16] & 0xffffff);\n\t\tsrcstart += srcstep;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\t/* note that srcpitch unit is in byte */\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = *( (const tjs_uint32*)((tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[1] = *( (const tjs_uint32*)((tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[2] = *( (const tjs_uint32*)((tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[3] = *( (const tjs_uint32*)((tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = *( (const tjs_uint32*)((tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16));\n\t\tsx += stepx, sy += stepy;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInterpLinTransCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\t/* bilinear interpolation version */\n\t/* note that srcpitch unit is in byte */\n\tdestlen -= 1;\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y);\n\t\tsx += stepx, sy += stepy;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[1] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 2;\n\t\tdestlen -= 2;\n\t}\n\n\tdestlen += 1;\n\n\twhile(destlen > 0)\n\t{\n\t\tint blend_x, blend_y;\n\t\tconst tjs_uint32 *p0, *p1;\n\n\t\tblend_x = (sx & 0xffff) >> 8;\n\t\tblend_x += blend_x >> 7;\n\t\tblend_y = (sy & 0xffff) >> 8;\n\t\tblend_y += blend_y >> 7;\n\t\tp0 = (const tjs_uint32*)((const tjs_uint8*)src + ((sy>>16)  )*srcpitch) + (sx>>16);\n\t\tp1 = (const tjs_uint32*)((const tjs_uint8*)p0 + srcpitch);\n\t\tdest[0] = TVPBlendARGB(\n\t\t\tTVPBlendARGB(p0[0], p0[1], blend_x),\n\t\t\tTVPBlendARGB(p1[0], p1[1], blend_x),\n\t\t\t\tblend_y);\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPLinTransColorCopy_c, (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch))\n{\n\t/* note that srcpitch unit is in byte */\n\tdestlen -= 3;\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = (dest[0] & 0xff000000) + (0x00ffffff & *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[1] = (dest[1] & 0xff000000) + (0x00ffffff & *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[2] = (dest[2] & 0xff000000) + (0x00ffffff & *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\t\tsx += stepx, sy += stepy;\n\t\tdest[3] = (dest[3] & 0xff000000) + (0x00ffffff & *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\t\tsx += stepx, sy += stepy;\n\n\t\tdest += 4;\n\t\tdestlen -= 4;\n\t}\n\n\tdestlen += 3;\n\n\twhile(destlen > 0)\n\t{\n\t\tdest[0] = (dest[0] & 0xff000000) + (0x00ffffff & *( (const tjs_uint32*)((const tjs_uint8*)src + (sy>>16)*srcpitch) + (sx>>16)));\n\t\tsx += stepx, sy += stepy;\n\t\tdest ++;\n\t\tdestlen --;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPMakeAlphaFromKey_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 key))\n{\n\ttjs_uint32 a, b;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = dest[(___index+(0*2))] & 0xffffff;\n\tb = dest[(___index+(0*2+1))] & 0xffffff;\n\tif(a != key) a |= 0xff000000;\n\tif(b != key) b |= 0xff000000;\n\tdest[(___index+(0*2))] = a;\n\tdest[(___index+(0*2+1))] = b;\n\ta = dest[(___index+(1*2))] & 0xffffff;\n\tb = dest[(___index+(1*2+1))] & 0xffffff;\n\tif(a != key) a |= 0xff000000;\n\tif(b != key) b |= 0xff000000;\n\tdest[(___index+(1*2))] = a;\n\tdest[(___index+(1*2+1))] = b;\n\ta = dest[(___index+(2*2))] & 0xffffff;\n\tb = dest[(___index+(2*2+1))] & 0xffffff;\n\tif(a != key) a |= 0xff000000;\n\tif(b != key) b |= 0xff000000;\n\tdest[(___index+(2*2))] = a;\n\tdest[(___index+(2*2+1))] = b;\n\ta = dest[(___index+(3*2))] & 0xffffff;\n\tb = dest[(___index+(3*2+1))] & 0xffffff;\n\tif(a != key) a |= 0xff000000;\n\tif(b != key) b |= 0xff000000;\n\tdest[(___index+(3*2))] = a;\n\tdest[(___index+(3*2+1))] = b;\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = dest[___index] & 0xffffff;;\n\tif(a != key) a |= 0xff000000;;\n\tdest[___index] = a;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPCopyMask_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\tif(dest < src)\n\t{\n\t\t/* backward */\n\tlen --;\n\n\twhile(len >= (8 -1))\n\t{\n\t\t{\n\t\t\tdest[(len-0)] = (dest[(len-0)] & 0xffffff) +\n\t\t\t\t(src[(len-0)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-1)] = (dest[(len-1)] & 0xffffff) +\n\t\t\t\t(src[(len-1)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-2)] = (dest[(len-2)] & 0xffffff) +\n\t\t\t\t(src[(len-2)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-3)] = (dest[(len-3)] & 0xffffff) +\n\t\t\t\t(src[(len-3)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-4)] = (dest[(len-4)] & 0xffffff) +\n\t\t\t\t(src[(len-4)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-5)] = (dest[(len-5)] & 0xffffff) +\n\t\t\t\t(src[(len-5)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-6)] = (dest[(len-6)] & 0xffffff) +\n\t\t\t\t(src[(len-6)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(len-7)] = (dest[(len-7)] & 0xffffff) +\n\t\t\t\t(src[(len-7)] & 0xff000000);\n\t\t}\n\t\tlen -= 8;\n\t}\n\n\twhile(len >= 0)\n\t{\n\t\t{\n\t\t\tdest[len] = (dest[len] & 0xffffff) +\n\t\t\t\t(src[len] & 0xff000000);\n\t\t}\n\t\tlen --;\n\t}\n\t}\n\telse\n\t{\n\t\t/* forward */\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\t\t{\n\t\t\tdest[(___index+0)] = (dest[(___index+0)] & 0xffffff) +\n\t\t\t\t(src[(___index+0)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+1)] = (dest[(___index+1)] & 0xffffff) +\n\t\t\t\t(src[(___index+1)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+2)] = (dest[(___index+2)] & 0xffffff) +\n\t\t\t\t(src[(___index+2)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+3)] = (dest[(___index+3)] & 0xffffff) +\n\t\t\t\t(src[(___index+3)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+4)] = (dest[(___index+4)] & 0xffffff) +\n\t\t\t\t(src[(___index+4)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+5)] = (dest[(___index+5)] & 0xffffff) +\n\t\t\t\t(src[(___index+5)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+6)] = (dest[(___index+6)] & 0xffffff) +\n\t\t\t\t(src[(___index+6)] & 0xff000000);\n\t\t}\n\t\t{\n\t\t\tdest[(___index+7)] = (dest[(___index+7)] & 0xffffff) +\n\t\t\t\t(src[(___index+7)] & 0xff000000);\n\t\t}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\t\t{\n\t\t\tdest[___index] = (dest[___index] & 0xffffff) +\n\t\t\t\t(src[___index] & 0xff000000);\n\t\t}\n\t\t\t___index ++;\n\t\t}\n\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPCopyColor_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{\n\tif(dest < src)\n\t{\n\t\t/* backward */\n\tlen --;\n\n\twhile(len >= (8 -1))\n\t{\n{\n\tdest[(len-0)] = (dest[(len-0)] & 0xff000000) +\n\t\t(src[(len-0)] & 0x00ffffff);\n}\n{\n\tdest[(len-1)] = (dest[(len-1)] & 0xff000000) +\n\t\t(src[(len-1)] & 0x00ffffff);\n}\n{\n\tdest[(len-2)] = (dest[(len-2)] & 0xff000000) +\n\t\t(src[(len-2)] & 0x00ffffff);\n}\n{\n\tdest[(len-3)] = (dest[(len-3)] & 0xff000000) +\n\t\t(src[(len-3)] & 0x00ffffff);\n}\n{\n\tdest[(len-4)] = (dest[(len-4)] & 0xff000000) +\n\t\t(src[(len-4)] & 0x00ffffff);\n}\n{\n\tdest[(len-5)] = (dest[(len-5)] & 0xff000000) +\n\t\t(src[(len-5)] & 0x00ffffff);\n}\n{\n\tdest[(len-6)] = (dest[(len-6)] & 0xff000000) +\n\t\t(src[(len-6)] & 0x00ffffff);\n}\n{\n\tdest[(len-7)] = (dest[(len-7)] & 0xff000000) +\n\t\t(src[(len-7)] & 0x00ffffff);\n}\n\t\tlen -= 8;\n\t}\n\n\twhile(len >= 0)\n\t{\n{\n\tdest[len] = (dest[len] & 0xff000000) +\n\t\t(src[len] & 0x00ffffff);\n}\n\t\tlen --;\n\t}\n\t}\n\telse\n\t{\n\t\t/* forward */\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] = (dest[(___index+0)] & 0xff000000) +\n\t\t(src[(___index+0)] & 0x00ffffff);\n}\n{\n\tdest[(___index+1)] = (dest[(___index+1)] & 0xff000000) +\n\t\t(src[(___index+1)] & 0x00ffffff);\n}\n{\n\tdest[(___index+2)] = (dest[(___index+2)] & 0xff000000) +\n\t\t(src[(___index+2)] & 0x00ffffff);\n}\n{\n\tdest[(___index+3)] = (dest[(___index+3)] & 0xff000000) +\n\t\t(src[(___index+3)] & 0x00ffffff);\n}\n{\n\tdest[(___index+4)] = (dest[(___index+4)] & 0xff000000) +\n\t\t(src[(___index+4)] & 0x00ffffff);\n}\n{\n\tdest[(___index+5)] = (dest[(___index+5)] & 0xff000000) +\n\t\t(src[(___index+5)] & 0x00ffffff);\n}\n{\n\tdest[(___index+6)] = (dest[(___index+6)] & 0xff000000) +\n\t\t(src[(___index+6)] & 0x00ffffff);\n}\n{\n\tdest[(___index+7)] = (dest[(___index+7)] & 0xff000000) +\n\t\t(src[(___index+7)] & 0x00ffffff);\n}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] = (dest[___index] & 0xff000000) +\n\t\t(src[___index] & 0x00ffffff);\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBindMaskToMain_c, (tjs_uint32 *main, const tjs_uint8 *mask, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tmain[(___index+0)] = (main[(___index+0)] & 0xffffff) + (mask[(___index+0)] << 24);\n}\n{\n\tmain[(___index+1)] = (main[(___index+1)] & 0xffffff) + (mask[(___index+1)] << 24);\n}\n{\n\tmain[(___index+2)] = (main[(___index+2)] & 0xffffff) + (mask[(___index+2)] << 24);\n}\n{\n\tmain[(___index+3)] = (main[(___index+3)] & 0xffffff) + (mask[(___index+3)] << 24);\n}\n{\n\tmain[(___index+4)] = (main[(___index+4)] & 0xffffff) + (mask[(___index+4)] << 24);\n}\n{\n\tmain[(___index+5)] = (main[(___index+5)] & 0xffffff) + (mask[(___index+5)] << 24);\n}\n{\n\tmain[(___index+6)] = (main[(___index+6)] & 0xffffff) + (mask[(___index+6)] << 24);\n}\n{\n\tmain[(___index+7)] = (main[(___index+7)] & 0xffffff) + (mask[(___index+7)] << 24);\n}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tmain[___index] = (main[___index] & 0xffffff) + (mask[___index] << 24);\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFillARGB_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 value))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] = value;\n}\n{\n\tdest[(___index+1)] = value;\n}\n{\n\tdest[(___index+2)] = value;\n}\n{\n\tdest[(___index+3)] = value;\n}\n{\n\tdest[(___index+4)] = value;\n}\n{\n\tdest[(___index+5)] = value;\n}\n{\n\tdest[(___index+6)] = value;\n}\n{\n\tdest[(___index+7)] = value;\n}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] = value;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFillARGB_NC_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 value))\n{\n\t/* non-cached version of TVPFillARGB */\n\t/* this routine written in C has no difference from TVPFillARGB. */ \n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] = value;\n}\n{\n\tdest[(___index+1)] = value;\n}\n{\n\tdest[(___index+2)] = value;\n}\n{\n\tdest[(___index+3)] = value;\n}\n{\n\tdest[(___index+4)] = value;\n}\n{\n\tdest[(___index+5)] = value;\n}\n{\n\tdest[(___index+6)] = value;\n}\n{\n\tdest[(___index+7)] = value;\n}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] = value;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFillColor_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 color))\n{\n\ttjs_uint32 t1, t2;\n\n\tcolor &= 0xffffff;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = dest[(___index+(0*2))];\n\tt2 = dest[(___index+(0*2+1))];\n\tt1 &= 0xff000000;\n\tt2 &= 0xff000000;\n\tt1 += color;\n\tt2 += color;\n\tdest[(___index+(0*2))] = t1;\n\tdest[(___index+(0*2+1))] = t2;\n\tt1 = dest[(___index+(1*2))];\n\tt2 = dest[(___index+(1*2+1))];\n\tt1 &= 0xff000000;\n\tt2 &= 0xff000000;\n\tt1 += color;\n\tt2 += color;\n\tdest[(___index+(1*2))] = t1;\n\tdest[(___index+(1*2+1))] = t2;\n\tt1 = dest[(___index+(2*2))];\n\tt2 = dest[(___index+(2*2+1))];\n\tt1 &= 0xff000000;\n\tt2 &= 0xff000000;\n\tt1 += color;\n\tt2 += color;\n\tdest[(___index+(2*2))] = t1;\n\tdest[(___index+(2*2+1))] = t2;\n\tt1 = dest[(___index+(3*2))];\n\tt2 = dest[(___index+(3*2+1))];\n\tt1 &= 0xff000000;\n\tt2 &= 0xff000000;\n\tt1 += color;\n\tt2 += color;\n\tdest[(___index+(3*2))] = t1;\n\tdest[(___index+(3*2+1))] = t2;\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = dest[___index];;\n\tt1 &= 0xff000000;;\n\tt1 += color;;\n\tdest[___index] = t1;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPFillMask_c, (tjs_uint32 *dest, tjs_int len, tjs_uint32 mask))\n{\n\ttjs_uint32 t1, t2;\n\tmask <<= 24;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = dest[(___index+(0*2))];\n\tt2 = dest[(___index+(0*2+1))];\n\tt1 &= 0x00ffffff;\n\tt2 &= 0x00ffffff;\n\tt1 += mask;\n\tt2 += mask;\n\tdest[(___index+(0*2))] = t1;\n\tdest[(___index+(0*2+1))] = t2;\n\tt1 = dest[(___index+(1*2))];\n\tt2 = dest[(___index+(1*2+1))];\n\tt1 &= 0x00ffffff;\n\tt2 &= 0x00ffffff;\n\tt1 += mask;\n\tt2 += mask;\n\tdest[(___index+(1*2))] = t1;\n\tdest[(___index+(1*2+1))] = t2;\n\tt1 = dest[(___index+(2*2))];\n\tt2 = dest[(___index+(2*2+1))];\n\tt1 &= 0x00ffffff;\n\tt2 &= 0x00ffffff;\n\tt1 += mask;\n\tt2 += mask;\n\tdest[(___index+(2*2))] = t1;\n\tdest[(___index+(2*2+1))] = t2;\n\tt1 = dest[(___index+(3*2))];\n\tt2 = dest[(___index+(3*2+1))];\n\tt1 &= 0x00ffffff;\n\tt2 &= 0x00ffffff;\n\tt1 += mask;\n\tt2 += mask;\n\tdest[(___index+(3*2))] = t1;\n\tdest[(___index+(3*2+1))] = t2;\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\tt1 = dest[___index];;\n\tt1 &= 0x00ffffff;;\n\tt1 += mask;;\n\tdest[___index] = t1;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddSubVertSum16_c, (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+0)];\n\tsub = subline[(___index+0)];\n\tdest[(___index+0)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+0)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+0)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+0)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+1)];\n\tsub = subline[(___index+1)];\n\tdest[(___index+1)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+1)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+1)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+1)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+2)];\n\tsub = subline[(___index+2)];\n\tdest[(___index+2)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+2)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+2)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+2)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+3)];\n\tsub = subline[(___index+3)];\n\tdest[(___index+3)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+3)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+3)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+3)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[___index];\n\tsub = subline[___index];\n\tdest[___index*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[___index*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[___index*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[___index*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddSubVertSum16_d_c, (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+0)];\n\tsub = subline[(___index+0)];\n\tdest[(___index+0)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+0)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+0)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+0)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+1)];\n\tsub = subline[(___index+1)];\n\tdest[(___index+1)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+1)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+1)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+1)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+2)];\n\tsub = subline[(___index+2)];\n\tdest[(___index+2)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+2)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+2)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+2)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+3)];\n\tsub = subline[(___index+3)];\n\tdest[(___index+3)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+3)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+3)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+3)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[___index];\n\tsub = subline[___index];\n\tdest[___index*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[___index*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[___index*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[___index*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddSubVertSum32_c, (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+0)];\n\tsub = subline[(___index+0)];\n\tdest[(___index+0)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+0)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+0)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+0)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+1)];\n\tsub = subline[(___index+1)];\n\tdest[(___index+1)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+1)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+1)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+1)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+2)];\n\tsub = subline[(___index+2)];\n\tdest[(___index+2)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+2)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+2)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+2)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[(___index+3)];\n\tsub = subline[(___index+3)];\n\tdest[(___index+3)*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[(___index+3)*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[(___index+3)*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[(___index+3)*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\tadd = addline[___index];\n\tsub = subline[___index];\n\tdest[___index*4+0] += ((add    ) & 0xff) - ((sub    ) & 0xff);\n\tdest[___index*4+1] += ((add>>8 ) & 0xff) - ((sub>>8 ) & 0xff);\n\tdest[___index*4+2] += ((add>>16) & 0xff) - ((sub>>16) & 0xff);\n\tdest[___index*4+3] += ((add>>24)       ) - ((sub>>24)       );\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAddSubVertSum32_d_c, (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+0)];\n\tsub = subline[(___index+0)];\n\tdest[(___index+0)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+0)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+0)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+0)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+1)];\n\tsub = subline[(___index+1)];\n\tdest[(___index+1)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+1)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+1)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+1)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+2)];\n\tsub = subline[(___index+2)];\n\tdest[(___index+2)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+2)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+2)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+2)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[(___index+3)];\n\tsub = subline[(___index+3)];\n\tdest[(___index+3)*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[(___index+3)*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[(___index+3)*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[(___index+3)*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 add, sub;\n\ttjs_int add_a, sub_a;\n\tadd = addline[___index];\n\tsub = subline[___index];\n\tdest[___index*4+3] += (add_a = (add>>24)       ) - (sub_a = (sub>>24)       );\n\tadd_a += add_a >> 7;\n\tsub_a += sub_a >> 7;\n\tdest[___index*4+0] += (((add    ) & 0xff) * add_a >> 8) - (((sub    ) & 0xff) * sub_a >> 8);\n\tdest[___index*4+1] += (((add>>8 ) & 0xff) * add_a >> 8) - (((sub>>8 ) & 0xff) * sub_a >> 8);\n\tdest[___index*4+2] += (((add>>16) & 0xff) * add_a >> 8) - (((sub>>16) & 0xff) * sub_a >> 8);\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDoBoxBlurAvg16_c, (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len))\n{\n\ttjs_int rcp = (1<<16) / n;\n\ttjs_int half_n = n >> 1;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] =\n\t\t(((sum[0] + half_n) * rcp >> 16)       )+\n\t\t(((sum[1] + half_n) * rcp >> 16) << 8  )+\n\t\t(((sum[2] + half_n) * rcp >> 16) << 16 )+\n\t\t(((sum[3] + half_n) * rcp >> 16) << 24 );\n\n\tsum[0] += add[(___index+0)*4+0] - sub[(___index+0)*4+0];\n\tsum[1] += add[(___index+0)*4+1] - sub[(___index+0)*4+1];\n\tsum[2] += add[(___index+0)*4+2] - sub[(___index+0)*4+2];\n\tsum[3] += add[(___index+0)*4+3] - sub[(___index+0)*4+3];\n}\n{\n\tdest[(___index+1)] =\n\t\t(((sum[0] + half_n) * rcp >> 16)       )+\n\t\t(((sum[1] + half_n) * rcp >> 16) << 8  )+\n\t\t(((sum[2] + half_n) * rcp >> 16) << 16 )+\n\t\t(((sum[3] + half_n) * rcp >> 16) << 24 );\n\n\tsum[0] += add[(___index+1)*4+0] - sub[(___index+1)*4+0];\n\tsum[1] += add[(___index+1)*4+1] - sub[(___index+1)*4+1];\n\tsum[2] += add[(___index+1)*4+2] - sub[(___index+1)*4+2];\n\tsum[3] += add[(___index+1)*4+3] - sub[(___index+1)*4+3];\n}\n{\n\tdest[(___index+2)] =\n\t\t(((sum[0] + half_n) * rcp >> 16)       )+\n\t\t(((sum[1] + half_n) * rcp >> 16) << 8  )+\n\t\t(((sum[2] + half_n) * rcp >> 16) << 16 )+\n\t\t(((sum[3] + half_n) * rcp >> 16) << 24 );\n\n\tsum[0] += add[(___index+2)*4+0] - sub[(___index+2)*4+0];\n\tsum[1] += add[(___index+2)*4+1] - sub[(___index+2)*4+1];\n\tsum[2] += add[(___index+2)*4+2] - sub[(___index+2)*4+2];\n\tsum[3] += add[(___index+2)*4+3] - sub[(___index+2)*4+3];\n}\n{\n\tdest[(___index+3)] =\n\t\t(((sum[0] + half_n) * rcp >> 16)       )+\n\t\t(((sum[1] + half_n) * rcp >> 16) << 8  )+\n\t\t(((sum[2] + half_n) * rcp >> 16) << 16 )+\n\t\t(((sum[3] + half_n) * rcp >> 16) << 24 );\n\n\tsum[0] += add[(___index+3)*4+0] - sub[(___index+3)*4+0];\n\tsum[1] += add[(___index+3)*4+1] - sub[(___index+3)*4+1];\n\tsum[2] += add[(___index+3)*4+2] - sub[(___index+3)*4+2];\n\tsum[3] += add[(___index+3)*4+3] - sub[(___index+3)*4+3];\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] =\n\t\t(((sum[0] + half_n) * rcp >> 16)       )+\n\t\t(((sum[1] + half_n) * rcp >> 16) << 8  )+\n\t\t(((sum[2] + half_n) * rcp >> 16) << 16 )+\n\t\t(((sum[3] + half_n) * rcp >> 16) << 24 );\n\n\tsum[0] += add[___index*4+0] - sub[___index*4+0];\n\tsum[1] += add[___index*4+1] - sub[___index*4+1];\n\tsum[2] += add[___index*4+2] - sub[___index*4+2];\n\tsum[3] += add[___index*4+3] - sub[___index*4+3];\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDoBoxBlurAvg16_d_c, (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len))\n{\n\ttjs_int rcp = (1<<16) / n;\n\ttjs_int half_n = n >> 1;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_int a = ((sum[3] + half_n) * rcp >> 16);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+0)] =\n\t\t(t[(sum[0] + half_n) * rcp >> 16]       )+\n\t\t(t[(sum[1] + half_n) * rcp >> 16] << 8  )+\n\t\t(t[(sum[2] + half_n) * rcp >> 16] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+0)*4+0] - sub[(___index+0)*4+0];\n\tsum[1] += add[(___index+0)*4+1] - sub[(___index+0)*4+1];\n\tsum[2] += add[(___index+0)*4+2] - sub[(___index+0)*4+2];\n\tsum[3] += add[(___index+0)*4+3] - sub[(___index+0)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) * rcp >> 16);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+1)] =\n\t\t(t[(sum[0] + half_n) * rcp >> 16]       )+\n\t\t(t[(sum[1] + half_n) * rcp >> 16] << 8  )+\n\t\t(t[(sum[2] + half_n) * rcp >> 16] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+1)*4+0] - sub[(___index+1)*4+0];\n\tsum[1] += add[(___index+1)*4+1] - sub[(___index+1)*4+1];\n\tsum[2] += add[(___index+1)*4+2] - sub[(___index+1)*4+2];\n\tsum[3] += add[(___index+1)*4+3] - sub[(___index+1)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) * rcp >> 16);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+2)] =\n\t\t(t[(sum[0] + half_n) * rcp >> 16]       )+\n\t\t(t[(sum[1] + half_n) * rcp >> 16] << 8  )+\n\t\t(t[(sum[2] + half_n) * rcp >> 16] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+2)*4+0] - sub[(___index+2)*4+0];\n\tsum[1] += add[(___index+2)*4+1] - sub[(___index+2)*4+1];\n\tsum[2] += add[(___index+2)*4+2] - sub[(___index+2)*4+2];\n\tsum[3] += add[(___index+2)*4+3] - sub[(___index+2)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) * rcp >> 16);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+3)] =\n\t\t(t[(sum[0] + half_n) * rcp >> 16]       )+\n\t\t(t[(sum[1] + half_n) * rcp >> 16] << 8  )+\n\t\t(t[(sum[2] + half_n) * rcp >> 16] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+3)*4+0] - sub[(___index+3)*4+0];\n\tsum[1] += add[(___index+3)*4+1] - sub[(___index+3)*4+1];\n\tsum[2] += add[(___index+3)*4+2] - sub[(___index+3)*4+2];\n\tsum[3] += add[(___index+3)*4+3] - sub[(___index+3)*4+3];\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_int a = ((sum[3] + half_n) * rcp >> 16);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[___index] =\n\t\t(t[(sum[0] + half_n) * rcp >> 16]       )+\n\t\t(t[(sum[1] + half_n) * rcp >> 16] << 8  )+\n\t\t(t[(sum[2] + half_n) * rcp >> 16] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[___index*4+0] - sub[___index*4+0];\n\tsum[1] += add[___index*4+1] - sub[___index*4+1];\n\tsum[2] += add[___index*4+2] - sub[___index*4+2];\n\tsum[3] += add[___index*4+3] - sub[___index*4+3];\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDoBoxBlurAvg32_c, (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len))\n{\n\t/* This function is very slow since using divisiion in loop. Function written in assembly should be used. */\n\ttjs_int half_n = n >> 1;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] =\n\t\t(((sum[0] + half_n) / n)       )+\n\t\t(((sum[1] + half_n) / n) << 8  )+\n\t\t(((sum[2] + half_n) / n) << 16 )+\n\t\t(((sum[3] + half_n) / n) << 24 );\n\n\tsum[0] += add[(___index+0)*4+0] - sub[(___index+0)*4+0];\n\tsum[1] += add[(___index+0)*4+1] - sub[(___index+0)*4+1];\n\tsum[2] += add[(___index+0)*4+2] - sub[(___index+0)*4+2];\n\tsum[3] += add[(___index+0)*4+3] - sub[(___index+0)*4+3];\n}\n{\n\tdest[(___index+1)] =\n\t\t(((sum[0] + half_n) / n)       )+\n\t\t(((sum[1] + half_n) / n) << 8  )+\n\t\t(((sum[2] + half_n) / n) << 16 )+\n\t\t(((sum[3] + half_n) / n) << 24 );\n\n\tsum[0] += add[(___index+1)*4+0] - sub[(___index+1)*4+0];\n\tsum[1] += add[(___index+1)*4+1] - sub[(___index+1)*4+1];\n\tsum[2] += add[(___index+1)*4+2] - sub[(___index+1)*4+2];\n\tsum[3] += add[(___index+1)*4+3] - sub[(___index+1)*4+3];\n}\n{\n\tdest[(___index+2)] =\n\t\t(((sum[0] + half_n) / n)       )+\n\t\t(((sum[1] + half_n) / n) << 8  )+\n\t\t(((sum[2] + half_n) / n) << 16 )+\n\t\t(((sum[3] + half_n) / n) << 24 );\n\n\tsum[0] += add[(___index+2)*4+0] - sub[(___index+2)*4+0];\n\tsum[1] += add[(___index+2)*4+1] - sub[(___index+2)*4+1];\n\tsum[2] += add[(___index+2)*4+2] - sub[(___index+2)*4+2];\n\tsum[3] += add[(___index+2)*4+3] - sub[(___index+2)*4+3];\n}\n{\n\tdest[(___index+3)] =\n\t\t(((sum[0] + half_n) / n)       )+\n\t\t(((sum[1] + half_n) / n) << 8  )+\n\t\t(((sum[2] + half_n) / n) << 16 )+\n\t\t(((sum[3] + half_n) / n) << 24 );\n\n\tsum[0] += add[(___index+3)*4+0] - sub[(___index+3)*4+0];\n\tsum[1] += add[(___index+3)*4+1] - sub[(___index+3)*4+1];\n\tsum[2] += add[(___index+3)*4+2] - sub[(___index+3)*4+2];\n\tsum[3] += add[(___index+3)*4+3] - sub[(___index+3)*4+3];\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] =\n\t\t(((sum[0] + half_n) / n)       )+\n\t\t(((sum[1] + half_n) / n) << 8  )+\n\t\t(((sum[2] + half_n) / n) << 16 )+\n\t\t(((sum[3] + half_n) / n) << 24 );\n\n\tsum[0] += add[___index*4+0] - sub[___index*4+0];\n\tsum[1] += add[___index*4+1] - sub[___index*4+1];\n\tsum[2] += add[___index*4+2] - sub[___index*4+2];\n\tsum[3] += add[___index*4+3] - sub[___index*4+3];\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDoBoxBlurAvg32_d_c, (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len))\n{\n\t/* This function is very slow since using divisiion in loop. Function written in assembly should be used. */\n\ttjs_int half_n = n >> 1;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_int a = ((sum[3] + half_n) / n);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+0)] =\n\t\t(t[(sum[0] + half_n) / n]       )+\n\t\t(t[(sum[1] + half_n) / n] << 8  )+\n\t\t(t[(sum[2] + half_n) / n] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+0)*4+0] - sub[(___index+0)*4+0];\n\tsum[1] += add[(___index+0)*4+1] - sub[(___index+0)*4+1];\n\tsum[2] += add[(___index+0)*4+2] - sub[(___index+0)*4+2];\n\tsum[3] += add[(___index+0)*4+3] - sub[(___index+0)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) / n);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+1)] =\n\t\t(t[(sum[0] + half_n) / n]       )+\n\t\t(t[(sum[1] + half_n) / n] << 8  )+\n\t\t(t[(sum[2] + half_n) / n] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+1)*4+0] - sub[(___index+1)*4+0];\n\tsum[1] += add[(___index+1)*4+1] - sub[(___index+1)*4+1];\n\tsum[2] += add[(___index+1)*4+2] - sub[(___index+1)*4+2];\n\tsum[3] += add[(___index+1)*4+3] - sub[(___index+1)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) / n);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+2)] =\n\t\t(t[(sum[0] + half_n) / n]       )+\n\t\t(t[(sum[1] + half_n) / n] << 8  )+\n\t\t(t[(sum[2] + half_n) / n] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+2)*4+0] - sub[(___index+2)*4+0];\n\tsum[1] += add[(___index+2)*4+1] - sub[(___index+2)*4+1];\n\tsum[2] += add[(___index+2)*4+2] - sub[(___index+2)*4+2];\n\tsum[3] += add[(___index+2)*4+3] - sub[(___index+2)*4+3];\n}\n{\n\ttjs_int a = ((sum[3] + half_n) / n);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[(___index+3)] =\n\t\t(t[(sum[0] + half_n) / n]       )+\n\t\t(t[(sum[1] + half_n) / n] << 8  )+\n\t\t(t[(sum[2] + half_n) / n] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[(___index+3)*4+0] - sub[(___index+3)*4+0];\n\tsum[1] += add[(___index+3)*4+1] - sub[(___index+3)*4+1];\n\tsum[2] += add[(___index+3)*4+2] - sub[(___index+3)*4+2];\n\tsum[3] += add[(___index+3)*4+3] - sub[(___index+3)*4+3];\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_int a = ((sum[3] + half_n) / n);\n\ttjs_uint8 * t = TVPDivTable + (a << 8);\n\tdest[___index] =\n\t\t(t[(sum[0] + half_n) / n]       )+\n\t\t(t[(sum[1] + half_n) / n] << 8  )+\n\t\t(t[(sum[2] + half_n) / n] << 16 )+\n\t\t(a << 24 );\n\n\tsum[0] += add[___index*4+0] - sub[___index*4+0];\n\tsum[1] += add[___index*4+1] - sub[___index*4+1];\n\tsum[2] += add[___index*4+2] - sub[___index*4+2];\n\tsum[3] += add[___index*4+3] - sub[___index*4+3];\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSwapLine8_c, (tjs_uint8 *line1, tjs_uint8 *line2, tjs_int len))\n{\n\t#define swap_tmp_buf_size 256\n\ttjs_uint8 swap_tmp_buf[swap_tmp_buf_size];\n\twhile(len)\n\t{\n\t\ttjs_int le = len < swap_tmp_buf_size ? len : swap_tmp_buf_size;\n\t\tmemcpy(swap_tmp_buf, line1, le);\n\t\tmemcpy(line1, line2, le);\n\t\tmemcpy(line2, swap_tmp_buf, le);\n\t\tline1 += le;\n\t\tline2 += le;\n\t\tlen -= le;\n\t}\n\t#undef swap_tmp_buf_size\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPSwapLine32_c, (tjs_uint32 *line1, tjs_uint32 *line2, tjs_int len))\n{\n\ttjs_uint32 tmp, tmp2;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ttmp = line1[(___index+(0*2))];\n\ttmp2 = line1[(___index+(0*2+1))];\n\tline1[(___index+(0*2))] = line2[(___index+(0*2))];\n\tline1[(___index+(0*2+1))] = line2[(___index+(0*2+1))];\n\tline2[(___index+(0*2))] = tmp;\n\tline2[(___index+(0*2+1))] = tmp2;\n\ttmp = line1[(___index+(1*2))];\n\ttmp2 = line1[(___index+(1*2+1))];\n\tline1[(___index+(1*2))] = line2[(___index+(1*2))];\n\tline1[(___index+(1*2+1))] = line2[(___index+(1*2+1))];\n\tline2[(___index+(1*2))] = tmp;\n\tline2[(___index+(1*2+1))] = tmp2;\n\ttmp = line1[(___index+(2*2))];\n\ttmp2 = line1[(___index+(2*2+1))];\n\tline1[(___index+(2*2))] = line2[(___index+(2*2))];\n\tline1[(___index+(2*2+1))] = line2[(___index+(2*2+1))];\n\tline2[(___index+(2*2))] = tmp;\n\tline2[(___index+(2*2+1))] = tmp2;\n\ttmp = line1[(___index+(3*2))];\n\ttmp2 = line1[(___index+(3*2+1))];\n\tline1[(___index+(3*2))] = line2[(___index+(3*2))];\n\tline1[(___index+(3*2+1))] = line2[(___index+(3*2+1))];\n\tline2[(___index+(3*2))] = tmp;\n\tline2[(___index+(3*2+1))] = tmp2;\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ttmp = line1[___index];;\n\tline1[___index] = line2[___index];;\n\tline2[___index] = tmp;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPReverse8_c, (tjs_uint8 *pixels, tjs_int len))\n{\n\ttjs_uint8 *pixels2 = pixels + len -1;\n\tlen/=2;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_uint8 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 3: {\n\ttjs_uint8 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 2: {\n\ttjs_uint8 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 1: {\n\ttjs_uint8 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPReverse32_c, (tjs_uint32 *pixels, tjs_int len))\n{\n\ttjs_uint32 *pixels2 = pixels + len -1;\n\tlen/=2;\n  if(len > 0)\n  {\n\tint lu_n = (len + (4-1)) / 4;\n\tswitch(len % 4)\n\t{\n\tcase 0: do { {\n\ttjs_uint32 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 3: {\n\ttjs_uint32 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 2: {\n\ttjs_uint32 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\tcase 1: {\n\ttjs_uint32 tmp = *pixels;\n\t*pixels = *pixels2;\n\t*pixels2 = tmp;\n\tpixels2 --;\n\tpixels++;\n}\n;\n\t   } while(-- lu_n);\n\t}\n  }\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDoGrayScale_c, (tjs_uint32 *dest, tjs_int len))\n{\n\ttjs_uint32 s1, d1, s2, d2;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ts1 = dest[(___index+(0*2))];\n\ts2 = dest[(___index+(0*2+1))];\n\td1 = (s1&0xff)*19;\n\td2 = (s2&0xff)*19;\n\td1 += ((s1 >> 8)&0xff)*183;\n\td2 += ((s2 >> 8)&0xff)*183;\n\td1 += ((s1 >> 16)&0xff)*54;\n\td2 += ((s2 >> 16)&0xff)*54;\n\td1 = (d1 >> 8) * 0x10101 + (s1 & 0xff000000);\n\td2 = (d2 >> 8) * 0x10101 + (s2 & 0xff000000);\n\tdest[(___index+(0*2))] = d1;\n\tdest[(___index+(0*2+1))] = d2;\n\ts1 = dest[(___index+(1*2))];\n\ts2 = dest[(___index+(1*2+1))];\n\td1 = (s1&0xff)*19;\n\td2 = (s2&0xff)*19;\n\td1 += ((s1 >> 8)&0xff)*183;\n\td2 += ((s2 >> 8)&0xff)*183;\n\td1 += ((s1 >> 16)&0xff)*54;\n\td2 += ((s2 >> 16)&0xff)*54;\n\td1 = (d1 >> 8) * 0x10101 + (s1 & 0xff000000);\n\td2 = (d2 >> 8) * 0x10101 + (s2 & 0xff000000);\n\tdest[(___index+(1*2))] = d1;\n\tdest[(___index+(1*2+1))] = d2;\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ts1 = dest[___index];;\n\td1 = (s1&0xff)*19;;\n\td1 += ((s1 >> 8)&0xff)*183;;\n\td1 += ((s1 >> 16)&0xff)*54;;\n\td1 = (d1 >> 8) * 0x10101 + (s1 & 0xff000000);;\n\tdest[___index] = d1;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInitGammaAdjustTempData_c, (tTVPGLGammaAdjustTempData *temp, const tTVPGLGammaAdjustData *data))\n{\n\t/* make table */\n\n\tdouble ramp = data->RCeil - data->RFloor;\n\tdouble gamp = data->GCeil - data->GFloor;\n\tdouble bamp = data->BCeil - data->BFloor;\n\n\tdouble rgamma = data->RGamma == 0.0 ? DBL_MAX : 1.0 / data->RGamma;\n\tdouble ggamma = data->GGamma == 0.0 ? DBL_MAX : 1.0 / data->GGamma;\n\tdouble bgamma = data->BGamma == 0.0 ? DBL_MAX : 1.0 / data->BGamma;\n\n\tint i;\n\tfor(i=0;i<256;i++)\n\t{\n#if 0\n\t\tdouble rate = (double)i/255.0;\n\t\tint n;\n\t\tn = (int)(pow(rate, rgamma)*ramp+0.5+(double)data->RFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->R[i]= n;\n\t\tn = (int)(pow(rate, ggamma)*gamp+0.5+(double)data->GFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->G[i]= n;\n\t\tn = (int)(pow(rate, bgamma)*bamp+0.5+(double)data->BFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->B[i]= n;\n#else\n\t\t// pow(x, y) == exp(y * log(x))\n\t\tdouble rate = log((double)i/255.0);\n\t\tint n;\n\t\tn = (int)(exp(rate * rgamma)*ramp+0.5+(double)data->RFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->R[i]= n;\n\t\tn = (int)(exp(rate * ggamma)*gamp+0.5+(double)data->GFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->G[i]= n;\n\t\tn = (int)(exp(rate * bgamma)*bamp+0.5+(double)data->BFloor);\n\t\tif(n<0) n=0; else if(n>255) n=255;\n\t\ttemp->B[i]= n;\n#endif\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUninitGammaAdjustTempData_c, (tTVPGLGammaAdjustTempData *temp))\n{\n\t/* nothing to do */\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdjustGamma_c, (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp))\n{\n\ttjs_uint32 d1, t1;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td1 = dest[(___index+0)];;\n\tif(d1 > 0x00ffffff)\n\t{\n\t\t/* process only non-fully-transparent pixel */\n\t\tt1 = temp->R[d1 & 0xff];;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->G[d1 & 0xff]<<8);;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->B[d1 & 0xff]<<16);;\n\t\tt1 += ((d1 & 0xff00) << 16);;\n\t\tdest[(___index+0)] = t1;;\n\t}\n\td1 = dest[(___index+1)];;\n\tif(d1 > 0x00ffffff)\n\t{\n\t\t/* process only non-fully-transparent pixel */\n\t\tt1 = temp->R[d1 & 0xff];;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->G[d1 & 0xff]<<8);;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->B[d1 & 0xff]<<16);;\n\t\tt1 += ((d1 & 0xff00) << 16);;\n\t\tdest[(___index+1)] = t1;;\n\t}\n\td1 = dest[(___index+2)];;\n\tif(d1 > 0x00ffffff)\n\t{\n\t\t/* process only non-fully-transparent pixel */\n\t\tt1 = temp->R[d1 & 0xff];;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->G[d1 & 0xff]<<8);;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->B[d1 & 0xff]<<16);;\n\t\tt1 += ((d1 & 0xff00) << 16);;\n\t\tdest[(___index+2)] = t1;;\n\t}\n\td1 = dest[(___index+3)];;\n\tif(d1 > 0x00ffffff)\n\t{\n\t\t/* process only non-fully-transparent pixel */\n\t\tt1 = temp->R[d1 & 0xff];;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->G[d1 & 0xff]<<8);;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->B[d1 & 0xff]<<16);;\n\t\tt1 += ((d1 & 0xff00) << 16);;\n\t\tdest[(___index+3)] = t1;;\n\t}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\td1 = dest[___index];;\n\tif(d1 > 0x00ffffff)\n\t{\n\t\t/* process only non-fully-transparent pixel */\n\t\tt1 = temp->R[d1 & 0xff];;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->G[d1 & 0xff]<<8);;\n\t\td1 >>= 8;;\n\t\tt1 += (temp->B[d1 & 0xff]<<16);;\n\t\tt1 += ((d1 & 0xff00) << 16);;\n\t\tdest[___index] = t1;;\n\t}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPAdjustGamma_a_c, (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp))\n{\n\t/* gamma adjustment for additive alpha */\n\t{\n\t\tint ___index = 0;\n\n\t\twhile(___index < len)\n\t\t{\n{\n\ttjs_uint32 d;\n\ttjs_int alpha;\n\ttjs_int alpha_adj;\n\ttjs_int recip;\n\ttjs_int t, d_tmp;\n\n\td = dest[___index];\n\n\tif(d >= 0xff000000)\n\t{\n\t\t/* completely opaque */\n\t\tt = d & 0xff;\n\t\td_tmp =   temp->R[t];\n\t\tt = (d>>8) & 0xff;\n\t\td_tmp |=  temp->G[t] << 8;\n\t\tt = (d>>16) & 0xff; \n\t\td_tmp |=  temp->B[t] << 16;\n\t\td_tmp |= 0xff000000;\n\t\tdest[___index] = d_tmp;\n\t}\n\telse if(d != 0)\n\t{\n\t\t/* not completely transparent */\n\t\talpha = d >> 24;\n\t\talpha_adj = alpha + (alpha >> 7);\n\t\trecip = TVPRecipTable256_16[alpha];\n\n\t\t/* B */\n\t\tt = d & 0xff;\n\t\tif(t > alpha)\n\t\t\td_tmp = (temp->R[255] * alpha_adj >> 8) + t - alpha;\n\t\telse\n\t\t\td_tmp = temp->R[recip * t >> 8] * alpha_adj >> 8;\n\t\t/* G */\n\t\tt = (d>>8) & 0xff; \n\t\tif(t > alpha)\n\t\t\td_tmp |= ((temp->G[255] * alpha_adj >> 8) + t - alpha) << 8;\n\t\telse\n\t\t\td_tmp |= (temp->G[recip * t >> 8] * alpha_adj >> 8) << 8;\n\t\t/* R */\n\t\tt = (d>>16) & 0xff; \n\t\tif(t > alpha)\n\t\t\td_tmp |= ((temp->B[255] * alpha_adj >> 8) + t - alpha) << 16;\n\t\telse\n\t\t\td_tmp |= (temp->B[recip * t >> 8] * alpha_adj >> 8) << 16;\n\t\t/* A */\n\t\td_tmp |= d & 0xff000000;\n\n\t\tdest[___index] = d_tmp;\n\t}\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPChBlurMulCopy65_c, (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level))\n{\n\ttjs_int a, b;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = (src[(___index+(0*2))] * level >> 18);\n\tb = (src[(___index+(0*2+1))] * level >> 18);\n\tif(a>=255) a = 255;\n\tif(b>=255) b = 255;\n\tdest[(___index+(0*2))] = a;\n\tdest[(___index+(0*2+1))] = b;\n\ta = (src[(___index+(1*2))] * level >> 18);\n\tb = (src[(___index+(1*2+1))] * level >> 18);\n\tif(a>=255) a = 255;\n\tif(b>=255) b = 255;\n\tdest[(___index+(1*2))] = a;\n\tdest[(___index+(1*2+1))] = b;\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = (src[___index] * level >> 18);;\n\tif(a>=255) a = 255;;\n\tdest[___index] = a;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPChBlurAddMulCopy65_c, (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level))\n{\n\ttjs_int a, b;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = dest[(___index+(0*2))] +(src[(___index+(0*2))] * level >> 18);\n\tb = dest[(___index+(0*2+1))] +(src[(___index+(0*2+1))] * level >> 18);\n\tif(a>=255) a = 255;\n\tif(b>=255) b = 255;\n\tdest[(___index+(0*2))] = a;\n\tdest[(___index+(0*2+1))] = b;\n\ta = dest[(___index+(1*2))] +(src[(___index+(1*2))] * level >> 18);\n\tb = dest[(___index+(1*2+1))] +(src[(___index+(1*2+1))] * level >> 18);\n\tif(a>=255) a = 255;\n\tif(b>=255) b = 255;\n\tdest[(___index+(1*2))] = a;\n\tdest[(___index+(1*2+1))] = b;\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = dest[___index] +(src[___index] * level >> 18);;\n\tif(a>=255) a = 255;;\n\tdest[___index] = a;;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/* fast_int_hypot from http://demo.and.or.jp/makedemo/effect/math/hypot/fast_hypot.c */\ntjs_uint fast_int_hypot(tjs_int lx, tjs_int ly)\n{\n\ttjs_uint len1, len2,t,length;\n\n/*\tlx = abs(lx); */\n/*\tly = abs(ly); */\n\tif(lx<0) lx = -lx;\n\tif(ly<0) ly = -ly;\n\t/*\n\t\tCWD\n\t\tXOR EAX,EDX\n\t\tSUB EAX,EDX\n\t*/\n\t\n\tif (lx >= ly)\n\t{\n\t\tlen1 = lx ; len2 = ly;\n\t}\n\telse\n\t{\n\t\tlen1 = ly ; len2 = lx;\n\t}\n\n\tt = len2 + (len2 >> 1) ;\n\tlength = len1 - (len1 >> 5) - (len1 >> 7) + (t >> 2) + (t >> 6) ;\n\treturn length;\n}\n\n\n\n/* simple blur for character data */\n/* shuld be more optimized */\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPChBlurCopy65_c, (tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel))\n{\n\ttjs_int lvsum, x, y;\n\n\t/* clear destination */\n\tmemset(dest, 0, destpitch*destheight);\n\n\t/* compute filter level */\n\tlvsum = 0;\n\tfor(y = -blurwidth; y <= blurwidth; y++)\n\t{\n\t\tfor(x = -blurwidth; x <= blurwidth; x++)\n\t\t{\n\t\t\ttjs_int len = fast_int_hypot(x, y);\n\t\t\tif(len <= blurwidth)\n\t\t\t\tlvsum += (blurwidth - len +1);\n\t\t}\n\t}\n\n\tif(lvsum) lvsum = (1<<18)/lvsum; else lvsum=(1<<18);\n\n\t/* apply */\n\tfor(y = -blurwidth; y <= blurwidth; y++)\n\t{\n\t\tfor(x = -blurwidth; x <= blurwidth; x++)\n\t\t{\n\t\t\ttjs_int len = fast_int_hypot(x, y);\n\t\t\tif(len <= blurwidth)\n\t\t\t{\n\t\t\t\ttjs_int sy;\n\n\t\t\t\tlen = blurwidth - len +1;\n\t\t\t\tlen *= lvsum;\n\t\t\t\tlen *= blurlevel;\n\t\t\t\tlen >>= 8;\n\t\t\t\tfor(sy = 0; sy < srcheight; sy++)\n\t\t\t\t{\n\t\t\t\t\tTVPChBlurAddMulCopy65(dest + (y + sy + blurwidth)*destpitch + x + blurwidth, \n\t\t\t\t\t\tsrc + sy * srcpitch, srcwidth, len);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand1BitTo8BitPal_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\ttjs_uint8 p[2];\n\ttjs_uint8 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tp[0] = pal[0]&0xff, p[1] = pal[1]&0xff;\n\tdlim = dest + len-7;\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = p[(tjs_uint)(b&(tjs_uint)0x80)>>7];\n\t\td[1] = p[(tjs_uint)(b&(tjs_uint)0x40)>>6];\n\t\td[2] = p[(tjs_uint)(b&(tjs_uint)0x20)>>5];\n\t\td[3] = p[(tjs_uint)(b&(tjs_uint)0x10)>>4];\n\t\td[4] = p[(tjs_uint)(b&(tjs_uint)0x08)>>3];\n\t\td[5] = p[(tjs_uint)(b&(tjs_uint)0x04)>>2];\n\t\td[6] = p[(tjs_uint)(b&(tjs_uint)0x02)>>1];\n\t\td[7] = p[(tjs_uint)(b&(tjs_uint)0x01)   ];\n\t\td += 8;\n\t}\n\tdlim = dest + len;\n\tb = *buf;\n\twhile(d<dlim)\n\t{\n\t\t*(d++) = (b&0x80) ? p[1] : p[0];\n\t\tb<<=1;\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand1BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\ttjs_uint8 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tdlim = dest + len-7;\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = (tjs_uint8)((b&(tjs_uint)0x80)>>7);\n\t\td[1] = (tjs_uint8)((b&(tjs_uint)0x40)>>6);\n\t\td[2] = (tjs_uint8)((b&(tjs_uint)0x20)>>5);\n\t\td[3] = (tjs_uint8)((b&(tjs_uint)0x10)>>4);\n\t\td[4] = (tjs_uint8)((b&(tjs_uint)0x08)>>3);\n\t\td[5] = (tjs_uint8)((b&(tjs_uint)0x04)>>2);\n\t\td[6] = (tjs_uint8)((b&(tjs_uint)0x02)>>1);\n\t\td[7] = (tjs_uint8)((b&(tjs_uint)0x01)   );\n\t\td += 8;\n\t}\n\tdlim = dest + len;\n\tb = *buf;\n\twhile(d<dlim)\n\t{\n\t\t*(d++) = (b&0x80) ? 1 : 0;\n\t\tb<<=1;\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand1BitTo32BitPal_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\ttjs_uint32 p[2];\n\ttjs_uint32 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tp[0] = pal[0], p[1] = pal[1];\n\tdlim = dest + len-7;\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = p[(tjs_uint)(b&(tjs_uint)0x80)>>7];\n\t\td[1] = p[(tjs_uint)(b&(tjs_uint)0x40)>>6];\n\t\td[2] = p[(tjs_uint)(b&(tjs_uint)0x20)>>5];\n\t\td[3] = p[(tjs_uint)(b&(tjs_uint)0x10)>>4];\n\t\td[4] = p[(tjs_uint)(b&(tjs_uint)0x08)>>3];\n\t\td[5] = p[(tjs_uint)(b&(tjs_uint)0x04)>>2];\n\t\td[6] = p[(tjs_uint)(b&(tjs_uint)0x02)>>1];\n\t\td[7] = p[(tjs_uint)(b&(tjs_uint)0x01)   ];\n\t\td += 8;\n\t}\n\tdlim = dest + len;\n\tb = *buf;\n\twhile(d<dlim)\n\t{\n\t\t*(d++) = (b&0x80) ? p[1] : p[0];\n\t\tb<<=1;\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand4BitTo8BitPal_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\ttjs_uint8 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tdlim = dest + (len & ~1);\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = (tjs_uint8)pal[(b&0xf0)>>4];\n\t\td[1] = (tjs_uint8)pal[b&0x0f];\n\t\td += 2;\n\t}\n\tif(len & 1)\n\t{\n\t\tb = *buf;\n\t\tif(d<dlim) *d = (tjs_uint8)pal[(b&0xf0)>>4];\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand4BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\ttjs_uint8 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tdlim = dest + (len & ~1);\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = (tjs_uint8)((b&0xf0)>>4);\n\t\td[1] = (tjs_uint8)(b&0x0f);\n\t\td += 2;\n\t}\n\tif(len & 1)\n\t{\n\t\tb = *buf;\n\t\tif(d<dlim) *d = (tjs_uint8)((b&0xf0)>>4);\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand4BitTo32BitPal_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\ttjs_uint32 *d=dest, *dlim;\n\ttjs_uint8 b;\n\n\tdlim = dest + (len & ~1);\n\twhile(d < dlim)\n\t{\n\t\tb = *(buf++);\n\t\td[0] = pal[(b&0xf0)>>4];\n\t\td[1] = pal[b&0x0f];\n\t\td += 2;\n\t}\n\tif(len & 1)\n\t{\n\t\tb = *buf;\n\t\t*d = pal[(b&0xf0)>>4];\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand8BitTo8BitPal_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] = pal[buf[(___index+0)]]&0xff;\n}\n{\n\tdest[(___index+1)] = pal[buf[(___index+1)]]&0xff;\n}\n{\n\tdest[(___index+2)] = pal[buf[(___index+2)]]&0xff;\n}\n{\n\tdest[(___index+3)] = pal[buf[(___index+3)]]&0xff;\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] = pal[buf[___index]]&0xff;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLExpand8BitTo32BitPal_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[(___index+0)] = pal[buf[(___index+0)]];\n}\n{\n\tdest[(___index+1)] = pal[buf[(___index+1)]];\n}\n{\n\tdest[(___index+2)] = pal[buf[(___index+2)]];\n}\n{\n\tdest[(___index+3)] = pal[buf[(___index+3)]];\n}\n{\n\tdest[(___index+4)] = pal[buf[(___index+4)]];\n}\n{\n\tdest[(___index+5)] = pal[buf[(___index+5)]];\n}\n{\n\tdest[(___index+6)] = pal[buf[(___index+6)]];\n}\n{\n\tdest[(___index+7)] = pal[buf[(___index+7)]];\n}\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n\tdest[___index] = pal[buf[___index]];\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPExpand8BitTo32BitGray_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\ttjs_uint8 a, b;\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = buf[(___index+(0*2))];\n\tb = buf[(___index+(0*2+1))];\n\tdest[(___index+(0*2))] = 0xff000000 + (a * 0x10101);\n\tdest[(___index+(0*2+1))] = 0xff000000 + (b * 0x10101);\n\ta = buf[(___index+(1*2))];\n\tb = buf[(___index+(1*2+1))];\n\tdest[(___index+(1*2))] = 0xff000000 + (a * 0x10101);\n\tdest[(___index+(1*2+1))] = 0xff000000 + (b * 0x10101);\n\ta = buf[(___index+(2*2))];\n\tb = buf[(___index+(2*2+1))];\n\tdest[(___index+(2*2))] = 0xff000000 + (a * 0x10101);\n\tdest[(___index+(2*2+1))] = 0xff000000 + (b * 0x10101);\n\ta = buf[(___index+(3*2))];\n\tb = buf[(___index+(3*2+1))];\n\tdest[(___index+(3*2))] = 0xff000000 + (a * 0x10101);\n\tdest[(___index+(3*2+1))] = 0xff000000 + (b * 0x10101);\n\t\t\t___index += 8;\n\t\t}\n\n\t\tlen += (8-1);\n\n\t\twhile(___index < len)\n\t\t{\n\ta = buf[___index];;\n\tdest[___index] = 0xff000000 + (a * 0x10101);;\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert15BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint16 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+0)) << 8 + *((tjs_uint8*)(buf+(___index+0))+1);\n#else\n\ttjs_uint16 s = buf[(___index+0)];\n#endif\n\tdest[(___index+0)] =\n\t\t((s&0x7c00)*56+ (s&0x03e0)*(187<<5)+ (s&0x001f)*(21<<10)) >> 15;\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+1)) << 8 + *((tjs_uint8*)(buf+(___index+1))+1);\n#else\n\ttjs_uint16 s = buf[(___index+1)];\n#endif\n\tdest[(___index+1)] =\n\t\t((s&0x7c00)*56+ (s&0x03e0)*(187<<5)+ (s&0x001f)*(21<<10)) >> 15;\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+2)) << 8 + *((tjs_uint8*)(buf+(___index+2))+1);\n#else\n\ttjs_uint16 s = buf[(___index+2)];\n#endif\n\tdest[(___index+2)] =\n\t\t((s&0x7c00)*56+ (s&0x03e0)*(187<<5)+ (s&0x001f)*(21<<10)) >> 15;\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+3)) << 8 + *((tjs_uint8*)(buf+(___index+3))+1);\n#else\n\ttjs_uint16 s = buf[(___index+3)];\n#endif\n\tdest[(___index+3)] =\n\t\t((s&0x7c00)*56+ (s&0x03e0)*(187<<5)+ (s&0x001f)*(21<<10)) >> 15;\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+___index) << 8 + *((tjs_uint8*)(buf+___index)+1);\n#else\n\ttjs_uint16 s = buf[___index];\n#endif\n\tdest[___index] =\n\t\t((s&0x7c00)*56+ (s&0x03e0)*(187<<5)+ (s&0x001f)*(21<<10)) >> 15;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert15BitTo32Bit_c, (tjs_uint32 *dest, const tjs_uint16 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+0)) << 8 + *((tjs_uint8*)(buf+(___index+0))+1);\n#else\n\ttjs_uint16 s = buf[(___index+0)];\n#endif\n\ttjs_int r = s&0x7c00;\n\ttjs_int g = s&0x03e0;\n\ttjs_int b = s&0x001f;\n\tdest[(___index+0)] = 0xff000000 +\n\t\t(r >> 7) + (r >> 12) +\n\t\t(g <<  6) + ((g&0x0380)<<1) +\n\t\t(b << 19) + ((b&0x1C)<<14);\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+1)) << 8 + *((tjs_uint8*)(buf+(___index+1))+1);\n#else\n\ttjs_uint16 s = buf[(___index+1)];\n#endif\n\ttjs_int r = s&0x7c00;\n\ttjs_int g = s&0x03e0;\n\ttjs_int b = s&0x001f;\n    dest[(___index + 1)] = 0xff000000 +\n        (r >> 7) + (r >> 12) +\n        (g << 6) + ((g & 0x0380) << 1) +\n        (b << 19) + ((b & 0x1C) << 14);\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+2)) << 8 + *((tjs_uint8*)(buf+(___index+2))+1);\n#else\n\ttjs_uint16 s = buf[(___index+2)];\n#endif\n\ttjs_int r = s&0x7c00;\n\ttjs_int g = s&0x03e0;\n\ttjs_int b = s&0x001f;\n    dest[(___index + 2)] = 0xff000000 +\n        (r >> 7) + (r >> 12) +\n        (g << 6) + ((g & 0x0380) << 1) +\n        (b << 19) + ((b & 0x1C) << 14);\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+(___index+3)) << 8 + *((tjs_uint8*)(buf+(___index+3))+1);\n#else\n\ttjs_uint16 s = buf[(___index+3)];\n#endif\n\ttjs_int r = s&0x7c00;\n\ttjs_int g = s&0x03e0;\n\ttjs_int b = s&0x001f;\n    dest[(___index + 3)] = 0xff000000 +\n        (r >> 7) + (r >> 12) +\n        (g << 6) + ((g & 0x0380) << 1) +\n        (b << 19) + ((b & 0x1C) << 14);\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint16 s = *(tjs_uint8*)(buf+___index) << 8 + *((tjs_uint8*)(buf+___index)+1);\n#else\n\ttjs_uint16 s = buf[___index];\n#endif\n\ttjs_int r = s&0x7c00;\n\ttjs_int g = s&0x03e0;\n\ttjs_int b = s&0x001f;\n    dest[___index] = 0xff000000 +\n        (r >> 7) + (r >> 12) +\n        (g << 6) + ((g & 0x0380) << 1) +\n        (b << 19) + ((b & 0x1C) << 14);\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n# define compose_grayscale(r,g,b) ((unsigned char)((((tjs_int)(b)*19 + (tjs_int)(g)*183 + (tjs_int)(r)*54)>>8)))\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert24BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\ttjs_uint8 *slimglim = dest + len;\n\ttjs_uint8 *slimglims = slimglim - 3;\n\twhile(dest < slimglims)\n\t{\n        dest[0] = compose_grayscale(buf[0], buf[1], buf[2]);\n        dest[1] = compose_grayscale(buf[3], buf[4], buf[5]);\n        dest[2] = compose_grayscale(buf[6], buf[7], buf[8]);\n\t\tdest[3] = compose_grayscale(buf[9], buf[10], buf[11]);\n\t\tdest += 4;\n\t\tbuf += 12;\n\t}\n\twhile(dest < slimglim)\n\t{\n\t\tdest[0] = compose_grayscale(buf[0], buf[1], buf[2]);\n\t\tdest ++;\n\t\tbuf += 3;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert24BitTo32Bit_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\ttjs_uint32 *slimglim = dest + len;\n\ttjs_uint32 *slimglims = slimglim - 7;\n\twhile(dest < slimglims)\n\t{\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\tdest[0] = 0xff000000 + buf[0] + (buf[1]<<8) + (buf[2]<<16);\n\t\tdest[1] = 0xff000000 + buf[3] + (buf[4]<<8) + (buf[5]<<16);\n\t\tdest[2] = 0xff000000 + buf[6] + (buf[7]<<8) + (buf[8]<<16);\n\t\tdest[3] = 0xff000000 + buf[9] + (buf[10]<<8) + (buf[11]<<16);\n\t\tdest += 4;\n\t\tbuf += 12;\n\t\tdest[0] = 0xff000000 + buf[0] + (buf[1]<<8) + (buf[2]<<16);\n\t\tdest[1] = 0xff000000 + buf[3] + (buf[4]<<8) + (buf[5]<<16);\n\t\tdest[2] = 0xff000000 + buf[6] + (buf[7]<<8) + (buf[8]<<16);\n\t\tdest[3] = 0xff000000 + buf[9] + (buf[10]<<8) + (buf[11]<<16);\n\t\tdest += 4;\n\t\tbuf += 12;\n#else\n\t\tdest[0] = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n\t\tdest[1] = 0xff000000 + (buf[3]<<16) + (buf[4]<<8) + (buf[5]);\n\t\tdest[2] = 0xff000000 + (buf[6]<<16) + (buf[7]<<8) + (buf[8]);\n\t\tdest[3] = 0xff000000 + (buf[9]<<16) + (buf[10]<<8) + (buf[11]);\n\t\tdest += 4;\n\t\tbuf += 12;\n\t\tdest[0] = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n\t\tdest[1] = 0xff000000 + (buf[3]<<16) + (buf[4]<<8) + (buf[5]);\n\t\tdest[2] = 0xff000000 + (buf[6]<<16) + (buf[7]<<8) + (buf[8]);\n\t\tdest[3] = 0xff000000 + (buf[9]<<16) + (buf[10]<<8) + (buf[11]);\n\t\tdest += 4;\n\t\tbuf += 12;\n#endif\n\t}\n\twhile(dest < slimglim)\n\t{\n#if TJS_HOST_IS_BIG_ENDIAN\n\t\t*(dest++) = 0xff000000 + buf[0] + (buf[1]<<8) + (buf[2]<<16);\n#else\n\t\t*(dest++) = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n#endif\n\t\tbuf += 3;\n\t}\n}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPConvert24BitTo32Bit_c, (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\t/* this function does not matter the host endian */\n\ttjs_uint32 *slimglim = dest + len;\n\ttjs_uint32 *slimglims = slimglim - 7;\n\twhile(dest < slimglims)\n\t{\n\t\tdest[0] = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n\t\tdest[1] = 0xff000000 + (buf[3]<<16) + (buf[4]<<8) + (buf[5]);\n\t\tdest[2] = 0xff000000 + (buf[6]<<16) + (buf[7]<<8) + (buf[8]);\n\t\tdest[3] = 0xff000000 + (buf[9]<<16) + (buf[10]<<8) + (buf[11]);\n\t\tdest += 4;\n\t\tbuf += 12;\n\t\tdest[0] = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n\t\tdest[1] = 0xff000000 + (buf[3]<<16) + (buf[4]<<8) + (buf[5]);\n\t\tdest[2] = 0xff000000 + (buf[6]<<16) + (buf[7]<<8) + (buf[8]);\n\t\tdest[3] = 0xff000000 + (buf[9]<<16) + (buf[10]<<8) + (buf[11]);\n\t\tdest += 4;\n\t\tbuf += 12;\n\t}\n\twhile(dest < slimglim)\n\t{\n\t\t*(dest++) = 0xff000000 + (buf[0]<<16) + (buf[1]<<8) + (buf[2]);\n\t\tbuf += 3;\n\t}\n}\n\nTVP_GL_FUNC_DECL(void, TVPReverseRGB_c, (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len))\n{\n    int ___index = 0; tjs_uint32 c;\n    len -= (8-1);\n\n    while(___index < len)\n    {\n        {\n            c = buf[(___index+0)];\n            dest[(___index+0)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+1)];\n            dest[(___index+1)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+2)];\n            dest[(___index+2)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+3)];\n            dest[(___index+3)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+4)];\n            dest[(___index+4)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+5)];\n            dest[(___index+5)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+6)];\n            dest[(___index+6)] = TVP_REVRGB(c);\n        }\n        {\n            c = buf[(___index+7)];\n            dest[(___index+7)] = TVP_REVRGB(c);\n        }\n        ___index += 8;\n    }\n\n    len += (8-1);\n\n    while(___index < len)\n    {\n        {\n            c = buf[___index];\n            dest[___index] = TVP_REVRGB(c);\n        }\n        ___index ++;\n    }\n}\n\nTVP_GL_FUNC_DECL(void, TVPUpscale65_255_c, (tjs_uint8 *dest, tjs_int len)) {\n\ttjs_uint8* end = dest + len;\n\twhile (dest < end - 8) {\n\t\ttjs_uint64 c = *(tjs_uint64*)dest;\n\t\t// left shift with saturation\n\t\ttjs_uint64 tmp = c & 0x4040404040404040ULL;\n\t\ttjs_uint64 tmp2 = tmp << 2;\n\t\ttmp = tmp2 - (tmp >> 6);\n\t\tc <<= 2;\n\t\tc -= tmp2;\n\t\tc |= tmp;\n\t\t*(tjs_uint64*)dest = c;\n\t\tdest += 8;\n\t}\n\twhile (dest < end) {\n\t\ttjs_uint c = *dest << 2;\n\t\t*dest = c > 255 ? 255 : c;\n\t\t++dest;\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert32BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint32 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+0)];\n    dest[(___index + 0)] = compose_grayscale((d & 0xff0000) >> 16, (d & 0xff00) >> 8, d & 0xff);\n#else\n\ttjs_uint32 d = buf[(___index+0)];\n    dest[(___index + 0)] = compose_grayscale(d & 0xff, (d & 0xff00) >> 8, (d & 0xff0000) >> 16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+1)];\n    dest[(___index + 1)] = compose_grayscale((d & 0xff0000) >> 16, (d & 0xff00) >> 8, d & 0xff);\n#else\n\ttjs_uint32 d = buf[(___index+1)];\n    dest[(___index + 1)] = compose_grayscale(d & 0xff, (d & 0xff00) >> 8, (d & 0xff0000) >> 16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+2)];\n    dest[(___index + 2)] = compose_grayscale((d & 0xff0000) >> 16, (d & 0xff00) >> 8, d & 0xff);\n#else\n\ttjs_uint32 d = buf[(___index+2)];\n    dest[(___index + 2)] = compose_grayscale(d & 0xff, (d & 0xff00) >> 8, (d & 0xff0000) >> 16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+3)];\n    dest[(___index + 3)] = compose_grayscale((d & 0xff0000) >> 16, (d & 0xff00) >> 8, d & 0xff);\n#else\n\ttjs_uint32 d = buf[(___index+3)];\n    dest[(___index + 3)] = compose_grayscale(d & 0xff, (d & 0xff00) >> 8, (d & 0xff0000) >> 16);\n#endif\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = compose_grayscale(d&0xff, (d&0xff00)>>8, (d&0xff0000)>>16);\n#else\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = compose_grayscale((d&0xff0000)>>16, (d&0xff00)>>8, d&0xff);\n#endif\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert32BitTo32Bit_NoneAlpha_c, (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+0)];\n\tdest[(___index+0)] = 0xff000000 + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+0)];\n\tdest[(___index+0)] = TVP_REVRGB(d) | 0xff000000;\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+1)];\n\tdest[(___index+1)] = 0xff000000 + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+1)];\n\tdest[(___index+1)] = TVP_REVRGB(d) | 0xff000000;\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+2)];\n\tdest[(___index+2)] = 0xff000000 + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+2)];\n\tdest[(___index+2)] = TVP_REVRGB(d) | 0xff000000;\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+3)];\n\tdest[(___index+3)] = 0xff000000 + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+3)];\n\tdest[(___index+3)] = TVP_REVRGB(d) | 0xff000000;\n#endif\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = 0xff000000 + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = TVP_REVRGB(d) | 0xff000000;\n#endif\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert32BitTo32Bit_MulAddAlpha_c, (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+0)];\n\tdest[(___index+0)] = ((d&0xff)<<24) + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+0)];\n\tdest[(___index+0)] = TVP_REVRGB(d);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+1)];\n\tdest[(___index+1)] = ((d&0xff)<<24) + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+1)];\n\tdest[(___index + 1)] = TVP_REVRGB(d);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+2)];\n\tdest[(___index+2)] = ((d&0xff)<<24) + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+2)];\n\tdest[(___index + 2)] = TVP_REVRGB(d);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+3)];\n\tdest[(___index+3)] = ((d&0xff)<<24) + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[(___index+3)];\n\tdest[(___index + 3)] = TVP_REVRGB(d);\n#endif\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = ((d&0xff)<<24) + ((d&0xff00)<<8) +  ((d&0xff0000)>>8) + ((d&0xff000000)>>24);\n#else\n\ttjs_uint32 d = buf[___index];\n\tdest[___index] = TVP_REVRGB(d);\n#endif\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPBLConvert32BitTo32Bit_AddAlpha_c, (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len))\n{\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+0)];\n\ttjs_uint8 *t = TVPDivTable + ((d & 0xff)<<8);\n\tdest[(___index+0)] = ((d&0xff)<<24) + (t[(d&0xff00)>>8]<<16) +  (t[(d&0xff0000)>>16]<<8) + (t[(d&0xff000000)>>24]);\n#else\n\ttjs_uint32 d = buf[(___index+0)];\n\ttjs_uint8 *t = TVPDivTable + ((d>>16) & 0xff00);\n\tdest[(___index+0)] = (d&0xff000000) + (t[(d&0xff0000)>>16]) + (t[(d&0xff00)>>8]<<8) + (t[d&0xff<<16]<<16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+1)];\n\ttjs_uint8 *t = TVPDivTable + ((d & 0xff)<<8);\n\tdest[(___index+1)] = ((d&0xff)<<24) + (t[(d&0xff00)>>8]<<16) +  (t[(d&0xff0000)>>16]<<8) + (t[(d&0xff000000)>>24]);\n#else\n\ttjs_uint32 d = buf[(___index+1)];\n\ttjs_uint8 *t = TVPDivTable + ((d>>16) & 0xff00);\n\tdest[(___index+1)] = (d&0xff000000) + (t[(d&0xff0000)>>16]) + (t[(d&0xff00)>>8]<<8) + (t[d&0xff]<<16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+2)];\n\ttjs_uint8 *t = TVPDivTable + ((d & 0xff)<<8);\n\tdest[(___index+2)] = ((d&0xff)<<24) + (t[(d&0xff00)>>8]<<16) +  (t[(d&0xff0000)>>16]<<8) + (t[(d&0xff000000)>>24]);\n#else\n\ttjs_uint32 d = buf[(___index+2)];\n\ttjs_uint8 *t = TVPDivTable + ((d>>16) & 0xff00);\n\tdest[(___index+2)] = (d&0xff000000) + (t[(d&0xff0000)>>16]) + (t[(d&0xff00)>>8]<<8) + (t[d&0xff]<<16);\n#endif\n}\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[(___index+3)];\n\ttjs_uint8 *t = TVPDivTable + ((d & 0xff)<<8);\n\tdest[(___index+3)] = ((d&0xff)<<24) + (t[(d&0xff00)>>8]<<16) +  (t[(d&0xff0000)>>16]<<8) + (t[(d&0xff000000)>>24]);\n#else\n\ttjs_uint32 d = buf[(___index+3)];\n\ttjs_uint8 *t = TVPDivTable + ((d>>16) & 0xff00);\n\tdest[(___index+3)] = (d&0xff000000) + (t[(d&0xff0000)>>16]) + (t[(d&0xff00)>>8]<<8) + (t[d&0xff]<<16);\n#endif\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\n#if TJS_HOST_IS_BIG_ENDIAN\n\ttjs_uint32 d = buf[___index];\n\ttjs_uint8 *t = TVPDivTable + ((d & 0xff)<<8);\n\tdest[___index] = ((d&0xff)<<24) + (t[(d&0xff00)>>8]<<16) +  (t[(d&0xff0000)>>16]<<8) + (t[(d&0xff000000)>>24]);\n#else\n\ttjs_uint32 d = buf[___index];\n\ttjs_uint8 *t = TVPDivTable + ((d>>16) & 0xff00);\n\tdest[___index] = (d&0xff000000) + (t[(d&0xff0000)>>16]) + (t[(d&0xff00)>>8]<<8) + (t[d&0xff]<<16);\n#endif\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDither32BitTo16Bit565_c, (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs))\n{\n\ntjs_uint8 *line = TVPDitherTable_5_6[yofs & 0x03][0][0];\ntjs_int x = (xofs & 0x03) << 9;\n\n\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 11)+  (line[x + (v & 0xff)]) +\n\t(line[x + 256 + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 11)+  (line[x + (v & 0xff)]) +\n\t(line[x + 256 + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 11)+  (line[x + (v & 0xff)]) +\n\t(line[x + 256 + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 11)+  (line[x + (v & 0xff)]) +\n\t(line[x + 256 + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 11)+  (line[x + (v & 0xff)]) +\n\t(line[x + 256 + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDither32BitTo16Bit555_c, (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs))\n{\n\ntjs_uint8 *line = TVPDitherTable_5_6[yofs & 0x03][0][0];\ntjs_int x = (xofs & 0x03) << 9;\n\n\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 10) + (line[x + (v & 0xff)]) +\n\t(line[x + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 10) + (line[x + (v & 0xff)]) +\n\t(line[x + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 10) + (line[x + (v & 0xff)]) +\n\t(line[x + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 10) + (line[x + (v & 0xff)]) +\n\t(line[x + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 16) & 0xff)] << 10) + (line[x + (v & 0xff)]) +\n\t(line[x + ((v >> 8) & 0xff)] << 5);\ndest++;\nsrc++;\nx+= 0x200;\nx &= 0x600;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPDither32BitTo8Bit_c, (tjs_uint8 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs))\n{\n\ntjs_uint8 *line = &(TVPDitherTable_676[0][yofs & 0x03][0][0]);\ntjs_int x = (xofs & 0x03) << 8;\n\n\n\t{\n\t\tint ___index = 0;\n\t\tlen -= (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 0) & 0xff)]) + (line[(256 * 16 * 2) + x + ((v >> 16) & 0xff)]) +\n\t(line[(16 * 256) + x + ((v >> 8) & 0xff)]);\ndest++;\nsrc++;\nx += 0x100;\nx &= 0x300;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 0) & 0xff)]) + (line[(256 * 16 * 2) + x + ((v >> 16) & 0xff)]) +\n\t(line[(16 * 256) + x + ((v >> 8) & 0xff)]);\ndest++;\nsrc++;\nx += 0x100;\nx &= 0x300;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 0) & 0xff)]) + (line[(256 * 16 * 2) + x + ((v >> 16) & 0xff)]) +\n\t(line[(16 * 256) + x + ((v >> 8) & 0xff)]);\ndest++;\nsrc++;\nx += 0x100;\nx &= 0x300;\n}\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 0) & 0xff)]) + (line[(256 * 16 * 2) + x + ((v >> 16) & 0xff)]) +\n\t(line[(16 * 256) + x + ((v >> 8) & 0xff)]);\ndest++;\nsrc++;\nx += 0x100;\nx &= 0x300;\n}\n\t\t\t___index += 4;\n\t\t}\n\n\t\tlen += (4-1);\n\n\t\twhile(___index < len)\n\t\t{\n{\ntjs_uint32 v = *src;\n*dest = (line[x + ((v >> 0) & 0xff)]) + (line[(256 * 16 * 2) + x + ((v >> 16) & 0xff)]) +\n\t(line[(16 * 256) + x + ((v >> 8) & 0xff)]);\ndest++;\nsrc++;\nx += 0x100;\nx &= 0x300;\n}\n\t\t\t___index ++;\n\t\t}\n\t}\n\n}\n\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG5ComposeColors3To4_c, (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const * buf, tjs_int width))\n{\n\ttjs_int x;\n\ttjs_uint8 pc[3];\n\ttjs_uint8 c[3];\n\tpc[0] = pc[1] = pc[2] = 0;\n\tfor(x = 0; x < width; x++)\n\t{\n\t\tc[2] = buf[0][x];\n\t\tc[1] = buf[1][x];\n\t\tc[0] = buf[2][x];\n\t\tc[0] += c[1]; c[2] += c[1];\n\t\t*(tjs_uint32 *)outp =\n\t\t\t\t\t\t\t\t((((pc[0] += c[0]) + upper[0]) & 0xff)      ) +\n\t\t\t\t\t\t\t\t((((pc[1] += c[1]) + upper[1]) & 0xff) <<  8) +\n\t\t\t\t\t\t\t\t((((pc[2] += c[2]) + upper[2]) & 0xff) << 16) +\n\t\t\t\t\t\t\t\t0xff000000;\n\t\toutp += 4;\n\t\tupper += 4;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG5ComposeColors4To4_c, (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const* buf, tjs_int width))\n{\n\ttjs_int x;\n\ttjs_uint8 pc[4];\n\ttjs_uint8 c[4];\n\tpc[0] = pc[1] = pc[2] = pc[3] = 0;\n\tfor(x = 0; x < width; x++)\n\t{\n\t\tc[0] = buf[2][x];\n\t\tc[1] = buf[1][x];\n\t\tc[2] = buf[0][x];\n\t\tc[3] = buf[3][x];\n\t\tc[0] += c[1]; c[2] += c[1];\n\t\t*(tjs_uint32 *)outp =\n\t\t\t\t\t\t\t\t((((pc[0] += c[0]) + upper[0]) & 0xff)      ) +\n\t\t\t\t\t\t\t\t((((pc[1] += c[1]) + upper[1]) & 0xff) <<  8) +\n\t\t\t\t\t\t\t\t((((pc[2] += c[2]) + upper[2]) & 0xff) << 16) +\n\t\t\t\t\t\t\t\t((((pc[3] += c[3]) + upper[3]) & 0xff) << 24);\n\t\toutp += 4;\n\t\tupper += 4;\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(tjs_int, TVPTLG5DecompressSlide_c, (tjs_uint8 *out, const tjs_uint8 *in, tjs_int insize, tjs_uint8 *text, tjs_int initialr))\n{\n#if 1\n    tjs_int r = initialr;\n    tjs_uint flags = 0;\n    const tjs_uint8 *inlim = in + insize;\n    while ( in < inlim )\n    {\n        if(((flags >>= 1) & 0x100) == 0) {\n\t\t\tflags = *in++ | 0xff00;\n\t\t\tif (flags == 0xff00 && r < (4096 - 8) && in < (inlim - 8)) {\t// copy 8byte\n\t\t\t\tmemcpy(out, in, 8);\n\t\t\t\tmemcpy(&text[r], in, 8);\n\t\t\t\tr += 8;\n\t\t\t\tin += 8;\n\t\t\t\tout += 8;\n\t\t\t\tflags = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n        }\n        if ( flags & 1 )\n        {\n\t\t\ttjs_uint16 in16 = *(tjs_uint16*)in;\n\t\t\ttjs_uint mpos = in16 & 0xFFF;\n\t\t\ttjs_uint mlen = (in16 >> 12) + 3;\n            in += 2;\n            if ( mlen == 18 )\n\t\t\t\tmlen += *in++;\n\t\t\tif ((mpos + mlen) < 4096 && (r + mlen) < 4096) {\n\t\t\t\tmemcpy(out, &text[mpos], mlen);\n\t\t\t\tmemmove(&text[r], &text[mpos], mlen);\n\t\t\t\tout += mlen;\n\t\t\t\tr += mlen;\n\t\t\t\tcontinue;\n\t\t\t}\n            while ( mlen-- ) {\n                *out++ = text[r++] = text[mpos++];\n                mpos &= 0xFFF;\n                r &= 0xFFF;\n            }\n        } else {\n            *out++ = text[r++] = *in++;\n            r &= 0xFFF;\n        }\n    }\n    return r;\n#else\n\ttjs_int r = initialr;\n\ttjs_uint flags = 0;\n\tconst tjs_uint8 *inlim = in + insize;\n\twhile(in < inlim)\n\t{\n\t\tif(((flags >>= 1) & 256) == 0)\n\t\t{\n\t\t\tflags = 0[in++] | 0xff00;\n\t\t}\n\t\tif(flags & 1)\n\t\t{\n\t\t\ttjs_int mpos = in[0] | ((in[1] & 0xf) << 8);\n\t\t\ttjs_int mlen = (in[1] & 0xf0) >> 4;\n\t\t\tin += 2;\n\t\t\tmlen += 3;\n\t\t\tif(mlen == 18) mlen += 0[in++];\n\n\t\t\twhile(mlen--)\n\t\t\t{\n\t\t\t\t0[out++] = text[r++] = text[mpos++];\n\t\t\t\tmpos &= (4096 - 1);\n\t\t\t\tr &= (4096 - 1);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned char c = 0[in++];\n\t\t\t0[out++] = c;\n\t\t\ttext[r++] = c;\n/*\t\t\t0[out++] = text[r++] = 0[in++];*/\n\t\t\tr &= (4096 - 1);\n\t\t}\n\t}\n\treturn r;\n#endif\n}\n\n\n#if TJS_HOST_IS_BIG_ENDIAN\n\t#define TVP_TLG6_BYTEOF(a, x) (((tjs_uint8*)(a))[(x)])\n\n\t#define TVP_TLG6_FETCH_32BITS(addr) ((tjs_uint32)TVP_TLG6_BYTEOF((addr), 0) +  \\\n\t\t\t\t\t\t\t\t\t((tjs_uint32)TVP_TLG6_BYTEOF((addr), 1) << 8) + \\\n\t\t\t\t\t\t\t\t\t((tjs_uint32)TVP_TLG6_BYTEOF((addr), 2) << 16) + \\\n\t\t\t\t\t\t\t\t\t((tjs_uint32)TVP_TLG6_BYTEOF((addr), 3) << 24) )\n#else\n\t#define TVP_TLG6_FETCH_32BITS(addr) (*(tjs_uint32*)addr)\n#endif\n\n\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG6DecodeGolombValuesForFirst_c, (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool))\n{\n\t/*\n\t\tdecode values packed in \"bit_pool\".\n\t\tvalues are coded using golomb code.\n\n\t\t\"ForFirst\" function do dword access to pixelbuf,\n\t\tclearing with zero except for blue (least siginificant byte).\n\t*/\n\n\tint n = TVP_TLG6_GOLOMB_N_COUNT - 1; /* output counter */\n\tint a = 0; /* summary of absolute values of errors */\n\n\ttjs_int bit_pos = 1;\n\ttjs_uint8 zero = (*bit_pool & 1)?0:1;\n\n\ttjs_int8 * limit = pixelbuf + pixel_count*4;\n\n\twhile(pixelbuf < limit)\n\t{\n\t\t/* get running count */\n\t\tint count;\n\n\t\t{\n\t\t\ttjs_uint32 t = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\ttjs_int b = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\tint bit_count = b;\n\t\t\twhile(!b)\n\t\t\t{\n\t\t\t\tbit_count += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\tbit_pos += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\tbit_pos &= 7;\n\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\tbit_count += b;\n\t\t\t}\n\n\n\t\t\tbit_pos += b;\n\t\t\tbit_pool += bit_pos >> 3;\n\t\t\tbit_pos &= 7;\n\n\t\t\tbit_count --;\n\t\t\tcount = 1 << bit_count;\n\t\t\tcount += ((TVP_TLG6_FETCH_32BITS(bit_pool) >> (bit_pos)) & (count-1));\n\n\t\t\tbit_pos += bit_count;\n\t\t\tbit_pool += bit_pos >> 3;\n\t\t\tbit_pos &= 7;\n\n\t\t}\n\n\t\tif(zero)\n\t\t{\n\t\t\t/* zero values */\n\n\t\t\t/* fill distination with zero */\n\t\t\tdo { *(tjs_uint32*)pixelbuf = 0; pixelbuf+=4; } while(--count);\n\n\t\t\tzero ^= 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* non-zero values */\n\n\t\t\t/* fill distination with glomb code */\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\tint k = TVPTLG6GolombBitLengthTable[a][n], v, sign;\n\n\t\t\t\ttjs_uint32 t = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\ttjs_int bit_count;\n\t\t\t\ttjs_int b;\n\t\t\t\tif(t)\n\t\t\t\t{\n\t\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\t\tbit_count = b;\n\t\t\t\t\twhile(!b)\n\t\t\t\t\t{\n\t\t\t\t\t\tbit_count += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\t\t\tbit_pos += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\t\t\tbit_pos &= 7;\n\t\t\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\t\t\tbit_count += b;\n\t\t\t\t\t}\n\t\t\t\t\tbit_count --;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbit_pool += 5;\n\t\t\t\t\tbit_count = bit_pool[-1];\n\t\t\t\t\tbit_pos = 0;\n\t\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool);\n\t\t\t\t\tb = 0;\n\t\t\t\t}\n\n\n\t\t\t\tv = (bit_count << k) + ((t >> b) & ((1<<k)-1));\n\t\t\t\tsign = (v & 1) - 1;\n\t\t\t\tv >>= 1;\n\t\t\t\ta += v;\n\t\t\t\t*(tjs_uint32*)pixelbuf = (unsigned char) ((v ^ sign) + sign + 1);\n\t\t\t\tpixelbuf += 4;\n\n\t\t\t\tbit_pos += b;\n\t\t\t\tbit_pos += k;\n\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\tbit_pos &= 7;\n\n\t\t\t\tif (--n < 0) {\n\t\t\t\t\ta >>= 1;  n = TVP_TLG6_GOLOMB_N_COUNT - 1;\n\t\t\t\t}\n\t\t\t} while(--count);\n\t\t\tzero ^= 1;\n\t\t}\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG6DecodeGolombValues_c, (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool))\n{\n\t/*\n\t\tdecode values packed in \"bit_pool\".\n\t\tvalues are coded using golomb code.\n\t*/\n\n\tint n = TVP_TLG6_GOLOMB_N_COUNT - 1; /* output counter */\n\tint a = 0; /* summary of absolute values of errors */\n\n\ttjs_int bit_pos = 1;\n\ttjs_uint8 zero = (*bit_pool & 1)?0:1;\n\n\ttjs_int8 * limit = pixelbuf + pixel_count*4;\n\n\twhile(pixelbuf < limit)\n\t{\n\t\t/* get running count */\n\t\tint count;\n\n\t\t{\n\t\t\ttjs_uint32 t = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\ttjs_int b = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\tint bit_count = b;\n\t\t\twhile(!b)\n\t\t\t{\n\t\t\t\tbit_count += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\tbit_pos += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\tbit_pos &= 7;\n\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\tbit_count += b;\n\t\t\t}\n\n\n\t\t\tbit_pos += b;\n\t\t\tbit_pool += bit_pos >> 3;\n\t\t\tbit_pos &= 7;\n\n\t\t\tbit_count --;\n\t\t\tcount = 1 << bit_count;\n\t\t\tcount += ((TVP_TLG6_FETCH_32BITS(bit_pool) >> (bit_pos)) & (count-1));\n\n\t\t\tbit_pos += bit_count;\n\t\t\tbit_pool += bit_pos >> 3;\n\t\t\tbit_pos &= 7;\n\n\t\t}\n\n\t\tif(zero)\n\t\t{\n\t\t\t/* zero values */\n\n\t\t\t/* fill distination with zero */\n\t\t\tdo { *pixelbuf = 0; pixelbuf+=4; } while(--count);\n\n\t\t\tzero ^= 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* non-zero values */\n\n\t\t\t/* fill distination with glomb code */\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\tint k = TVPTLG6GolombBitLengthTable[a][n], v, sign;\n\n\t\t\t\ttjs_uint32 t = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\ttjs_int bit_count;\n\t\t\t\ttjs_int b;\n\t\t\t\tif(t)\n\t\t\t\t{\n\t\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\t\tbit_count = b;\n\t\t\t\t\twhile(!b)\n\t\t\t\t\t{\n\t\t\t\t\t\tbit_count += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\t\t\tbit_pos += TVP_TLG6_LeadingZeroTable_BITS;\n\t\t\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\t\t\tbit_pos &= 7;\n\t\t\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool) >> bit_pos;\n\t\t\t\t\t\tb = TVPTLG6LeadingZeroTable[t&(TVP_TLG6_LeadingZeroTable_SIZE-1)];\n\t\t\t\t\t\tbit_count += b;\n\t\t\t\t\t}\n\t\t\t\t\tbit_count --;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbit_pool += 5;\n\t\t\t\t\tbit_count = bit_pool[-1];\n\t\t\t\t\tbit_pos = 0;\n\t\t\t\t\tt = TVP_TLG6_FETCH_32BITS(bit_pool);\n\t\t\t\t\tb = 0;\n\t\t\t\t}\n\n\n\t\t\t\tv = (bit_count << k) + ((t >> b) & ((1<<k)-1));\n\t\t\t\tsign = (v & 1) - 1;\n\t\t\t\tv >>= 1;\n\t\t\t\ta += v;\n\t\t\t\t*pixelbuf = (char) ((v ^ sign) + sign + 1);\n\t\t\t\tpixelbuf += 4;\n\n\t\t\t\tbit_pos += b;\n\t\t\t\tbit_pos += k;\n\t\t\t\tbit_pool += bit_pos >> 3;\n\t\t\t\tbit_pos &= 7;\n\n\t\t\t\tif (--n < 0) {\n\t\t\t\t\ta >>= 1;  n = TVP_TLG6_GOLOMB_N_COUNT - 1;\n\t\t\t\t}\n\t\t\t} while(--count);\n\t\t\tzero ^= 1;\n\t\t}\n\t}\n}\n\n\nstatic TVP_INLINE_FUNC tjs_uint32 make_gt_mask(tjs_uint32 a, tjs_uint32 b){\n\ttjs_uint32 tmp2 = ~b;\n\ttjs_uint32 tmp = ((a & tmp2) + (((a ^ tmp2) >> 1) & 0x7f7f7f7f) ) & 0x80808080;\n\ttmp = ((tmp >> 7) + 0x7f7f7f7f) ^ 0x7f7f7f7f;\n\treturn tmp;\n}\nstatic TVP_INLINE_FUNC tjs_uint32 packed_bytes_add(tjs_uint32 a, tjs_uint32 b)\n{\n\ttjs_uint32 tmp = (((a & b)<<1) + ((a ^ b) & 0xfefefefe) ) & 0x01010100;\n\treturn a+b-tmp;\n}\nstatic TVP_INLINE_FUNC tjs_uint32 med2(tjs_uint32 a, tjs_uint32 b, tjs_uint32 c){\n\t/* do Median Edge Detector   thx, Mr. sugi  at    kirikiri.info */\n\ttjs_uint32 aa_gt_bb = make_gt_mask(a, b);\n\ttjs_uint32 a_xor_b_and_aa_gt_bb = ((a ^ b) & aa_gt_bb);\n\ttjs_uint32 aa = a_xor_b_and_aa_gt_bb ^ a;\n\ttjs_uint32 bb = a_xor_b_and_aa_gt_bb ^ b;\n\ttjs_uint32 n = make_gt_mask(c, bb);\n\ttjs_uint32 nn = make_gt_mask(aa, c);\n\ttjs_uint32 m = ~(n | nn);\n\treturn (n & aa) | (nn & bb) | ((bb & m) - (c & m) + (aa & m));\n}\nstatic TVP_INLINE_FUNC tjs_uint32 med(tjs_uint32 a, tjs_uint32 b, tjs_uint32 c, tjs_uint32 v){\n\treturn packed_bytes_add(med2(a, b, c), v);\n}\n\n#define TLG6_AVG_PACKED(x, y) ((((x) & (y)) + ((((x) ^ (y)) & 0xfefefefe) >> 1)) +\\\n\t\t\t(((x)^(y))&0x01010101))\n\nstatic TVP_INLINE_FUNC tjs_uint32 avg(tjs_uint32 a, tjs_uint32 b, tjs_uint32 c, tjs_uint32 v){\n\treturn packed_bytes_add(TLG6_AVG_PACKED(a, b), v);\n}\n\n#define TVP_TLG6_DO_CHROMA_DECODE_PROTO(B, G, R, A, POST_INCREMENT) do \\\n\t\t\t{ \\\n\t\t\t\ttjs_uint32 u = *prevline; \\\n\t\t\t\tp = med(p, u, up, \\\n\t\t\t\t\t(0xff0000 & ((B)<<16)) + (0xff00 & ((G)<<8)) + (0xff & (R)) + ((A) << 24) ); \\\n\t\t\t\tup = u; \\\n\t\t\t\t*curline = p; \\\n\t\t\t\tcurline ++; \\\n\t\t\t\tprevline ++; \\\n\t\t\t\tPOST_INCREMENT \\\n\t\t\t} while(--w);\n#define TVP_TLG6_DO_CHROMA_DECODE_PROTO2(B, G, R, A, POST_INCREMENT) do \\\n\t\t\t{ \\\n\t\t\t\ttjs_uint32 u = *prevline; \\\n\t\t\t\tp = avg(p, u, up, \\\n\t\t\t\t\t(0xff0000 & ((B)<<16)) + (0xff00 & ((G)<<8)) + (0xff & (R)) + ((A) << 24) ); \\\n\t\t\t\tup = u; \\\n\t\t\t\t*curline = p; \\\n\t\t\t\tcurline ++; \\\n\t\t\t\tprevline ++; \\\n\t\t\t\tPOST_INCREMENT \\\n\t\t\t} while(--w);\n#define TVP_TLG6_DO_CHROMA_DECODE(N, R, G, B) case (N<<1): \\\n\tTVP_TLG6_DO_CHROMA_DECODE_PROTO(R, G, B, IA, {in+=step;}) break; \\\n\tcase (N<<1)+1: \\\n\tTVP_TLG6_DO_CHROMA_DECODE_PROTO2(R, G, B, IA, {in+=step;}) break;\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG6DecodeLineGeneric_c, (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int start_block, tjs_int block_limit, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir))\n{\n\t/*\n\t\tchroma/luminosity decoding\n\t\t(this does reordering, color correlation filter, MED/AVG  at a time)\n\t*/\n\ttjs_uint32 p, up;\n\tint step, i;\n\n\tif (start_block)\n\t{\n\t\tprevline += start_block * TVP_TLG6_W_BLOCK_SIZE;\n\t\tcurline  += start_block * TVP_TLG6_W_BLOCK_SIZE;\n\t\tp  = curline[-1];\n\t\tup = prevline[-1];\n\t}\n\telse\n\t{\n\t\tp = up = initialp;\n\t}\n\n\tin += skipblockbytes * start_block;\n\tstep = (dir&1)?1:-1;\n\n\tfor(i = start_block; i < block_limit; i ++)\n\t{\n\t\tint w = width - i*TVP_TLG6_W_BLOCK_SIZE, ww;\n\t\tif(w > TVP_TLG6_W_BLOCK_SIZE) w = TVP_TLG6_W_BLOCK_SIZE;\n\t\tww = w;\n\t\tif(step==-1) in += ww-1;\n\t\tif(i&1) in += oddskip * ww;\n\t\tswitch(filtertypes[i])\n\t\t{\n#define IA\t(char)((*in>>24)&0xff)\n#define IR\t(char)((*in>>16)&0xff)\n#define IG  (char)((*in>>8 )&0xff)\n#define IB  (char)((*in    )&0xff)\n\t\tTVP_TLG6_DO_CHROMA_DECODE( 0, IB, IG, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 1, IB+IG, IG, IR+IG); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 2, IB, IG+IB, IR+IB+IG); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 3, IB+IR+IG, IG+IR, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 4, IB+IR, IG+IB+IR, IR+IB+IR+IG); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 5, IB+IR, IG+IB+IR, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 6, IB+IG, IG, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 7, IB, IG+IB, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 8, IB, IG, IR+IG); \n\t\tTVP_TLG6_DO_CHROMA_DECODE( 9, IB+IG+IR+IB, IG+IR+IB, IR+IB); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(10, IB+IR, IG+IR, IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(11, IB, IG+IB, IR+IB); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(12, IB, IG+IR+IB, IR+IB); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(13, IB+IG, IG+IR+IB+IG, IR+IB+IG); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(14, IB+IG+IR, IG+IR, IR+IB+IG+IR); \n\t\tTVP_TLG6_DO_CHROMA_DECODE(15, IB, IG+(IB<<1), IR+(IB<<1));\n\n\t\tdefault: return;\n\t\t}\n\t\tif(step == 1)\n\t\t\tin += skipblockbytes - ww;\n\t\telse\n\t\t\tin += skipblockbytes + 1;\n\t\tif(i&1) in -= oddskip * ww;\n#undef IR\n#undef IG\n#undef IB\n\t}\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPTLG6DecodeLine_c, (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int block_count, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir))\n{\n\tTVPTLG6DecodeLineGeneric(prevline, curline, width, 0, block_count,\n\t\tfiltertypes, skipblockbytes, in, initialp, oddskip, dir);\n}\n\n\n/*\n  Photoshop-like layer blender for KIRIKIRI (C-version)\n  (c)2004-2005 Kengo Takagi (Kenjo) <kenjo@ceres.dti.ne.jp>\n*/\n\n\n#define TVPPS_REG\n#define TVPPS_USE_OVERLAY_TABLE\n\n/* --------------------------------------------------------------------\n  Tables\n  These three operations use pow()/divide, so table reference should be\n  faster than normal calc.\n-------------------------------------------------------------------- */\nunsigned char TVPPsTableSoftLight[256][256];\nunsigned char TVPPsTableColorDodge[256][256];\nunsigned char TVPPsTableColorBurn[256][256];\n\n#ifdef TVPPS_USE_OVERLAY_TABLE\n/* only for C version */\nunsigned char TVPPsTableOverlay[256][256];\n#endif\n\n\n/* --------------------------------------------------------------------\n  Operation defines\n-------------------------------------------------------------------- */\n#define TVPPS_MAINLOOP \\\n\t\tif(len > 0) {                                        \\\n\t\t\ttjs_int lu_n = (len + (4-1)) / 4;                \\\n\t\t\tswitch(len % 4) {                                \\\n\t\t\tcase 0:                                          \\\n\t\t\t\t\tdo {                                     \\\n\t\t\t\t\t\tOPERATION1;                          \\\n\t\t\tcase 3:\t\tOPERATION1;                          \\\n\t\t\tcase 2:\t\tOPERATION1;                          \\\n\t\t\tcase 1:\t\tOPERATION1;                          \\\n\t\t\t\t\t} while(-- lu_n);                        \\\n\t\t\t}                                                \\\n\t\t}\n\n#define TVPPS_ALPHABLEND { \\\n        TVPPS_REG tjs_uint32 d1 = d&0x00ff00ff, d2 = d&0x0000ff00;                                         \\\n        s = ((((((s&0x00ff00ff)-d1)*a)>>8)+d1)&0x00ff00ff)|((((((s&0x0000ff00)-d2)*a)>>8)+d2)&0x0000ff00); \\\n}\n\n#define TVPPS_FADESRC   s = ((((s&0x00ff00ff)*a)>>8)&0x00ff00ff)|((((s&0x0000ff00)*a)>>8)&0x0000ff00);\n\n\n#define TVPPsOperationAlphaBlend      { \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#if 0 /* Fade src BEFORE add/sub */\n#define TVPPsOperationAddBlend        { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        TVPPS_FADESRC                                                                                      \\\n        n = (((d&s)<<1)+((d^s)&0x00fefefe))&0x01010100;                                                    \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        s = (d+s-n)|n;                                                                                     \\\n}\n#define TVPPsOperationSubBlend        { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        TVPPS_FADESRC                                                                                      \\\n        s = ~s;                                                                                            \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        s = (d|n)-(s|n);                                                                                   \\\n}\n#else  /* Blend src and dst AFTER add/sub */\n#define TVPPsOperationAddBlend        { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        n = (((d&s)<<1)+((d^s)&0x00fefefe))&0x01010100;                                                    \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        s = (d+s-n)|n;                                                                                     \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationSubBlend        { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        s = ~s;                                                                                            \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        s = (d|n)-(s|n);                                                                                   \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#endif\n#define TVPPsOperationMulBlend        { \\\n        s = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff000000) |                                               \\\n              ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff0000) |                                               \\\n              ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 8;                                         \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationScreenBlend     { \\\n        /* c = ((s+d-(s*d)/255)-d)*a + d = (s-(s*d)/255)*a + d */                                          \\\n        TVPPS_REG tjs_uint32 sd1, sd2;                                                                     \\\n        sd1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff000000) |                                             \\\n                ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 8;                                       \\\n        sd2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff0000) ) >> 8;                                       \\\n        s = ((((((s&0x00ff00ff)-sd1)*a)>>8)+(d&0x00ff00ff))&0x00ff00ff) |                                  \\\n            ((((((s&0x0000ff00)-sd2)*a)>>8)+(d&0x0000ff00))&0x0000ff00);                                   \\\n}\n#ifdef TVPPS_USE_OVERLAY_TABLE\n#define TVPPsOperationOverlayBlend    { \\\n        s = (TVPPsTableOverlay[(s>>16)&0xff][(d>>16)&0xff]<<16) |                                          \\\n            (TVPPsTableOverlay[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |                                          \\\n            (TVPPsTableOverlay[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );                                           \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationHardLightBlend  { \\\n        s = (TVPPsTableOverlay[(d>>16)&0xff][(s>>16)&0xff]<<16) |                                          \\\n            (TVPPsTableOverlay[(d>>8 )&0xff][(s>>8 )&0xff]<<8 ) |                                          \\\n            (TVPPsTableOverlay[(d>>0 )&0xff][(s>>0 )&0xff]<<0 );                                           \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#else\n#define TVPPsOperationOverlayBlend    { \\\n        TVPPS_REG tjs_uint32 n = (((d&0x00808080)>>7)+0x007f7f7f)^0x007f7f7f;                              \\\n        TVPPS_REG tjs_uint32 sa1, sa2, d1 = d&n, s1 = s&n;                                                 \\\n        /* some tricks to avoid overflow (error between /255 and >>8) */                                   \\\n        s |= 0x00010101;                                                                                   \\\n        sa1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff800000) |                                             \\\n                ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 7;                                       \\\n        sa2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;                                       \\\n        s = ((sa1&~n)|(sa2&~n));                                                                           \\\n        s |= (((s1&0x00fe00fe)+(d1&0x00ff00ff))<<1)-(n&0x00ff00ff)-(sa1&n);                                \\\n        s |= (((s1&0x0000fe00)+(d1&0x0000ff00))<<1)-(n&0x0000ff00)-(sa2&n);                                \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationHardLightBlend  { \\\n        TVPPS_REG tjs_uint32 n = (((s&0x00808080)>>7)+0x007f7f7f)^0x007f7f7f;                              \\\n        TVPPS_REG tjs_uint32 sa1, sa2, d1 = d&n, s1 = s&n;                                                 \\\n        /* some tricks to avoid overflow (error between /255 and >>8) */                                   \\\n        d |= 0x00010101;                                                                                   \\\n        sa1 = ( ((((d>>16)&0xff)*(s&0x00ff0000))&0xff800000) |                                             \\\n                ((((d>>0 )&0xff)*(s&0x000000ff))           ) ) >> 7;                                       \\\n        sa2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;                                       \\\n        s = ((sa1&~n)|(sa2&~n));                                                                           \\\n        s |= (((s1&0x00ff00ff)+(d1&0x00fe00fe))<<1)-(n&0x00ff00ff)-(sa1&n);                                \\\n        s |= (((s1&0x0000ff00)+(d1&0x0000fe00))<<1)-(n&0x0000ff00)-(sa2&n);                                \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#endif\n#define TVPPsOperationSoftLightBlend  { \\\n        s = (TVPPsTableSoftLight[(s>>16)&0xff][(d>>16)&0xff]<<16) |                                        \\\n            (TVPPsTableSoftLight[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |                                        \\\n            (TVPPsTableSoftLight[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );                                         \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationColorDodgeBlend { \\\n        s = (TVPPsTableColorDodge[(s>>16)&0xff][(d>>16)&0xff]<<16) |                                       \\\n            (TVPPsTableColorDodge[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |                                       \\\n            (TVPPsTableColorDodge[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );                                        \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationColorDodge5Blend { \\\n        TVPPS_FADESRC                                                                                      \\\n        s = (TVPPsTableColorDodge[(s>>16)&0xff][(d>>16)&0xff]<<16) |                                       \\\n            (TVPPsTableColorDodge[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |                                       \\\n            (TVPPsTableColorDodge[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );                                        \\\n}\n#define TVPPsOperationColorBurnBlend  { \\\n        s = (TVPPsTableColorBurn[(s>>16)&0xff][(d>>16)&0xff]<<16) |                                        \\\n            (TVPPsTableColorBurn[(s>>8 )&0xff][(d>>8 )&0xff]<<8 ) |                                        \\\n            (TVPPsTableColorBurn[(s>>0 )&0xff][(d>>0 )&0xff]<<0 );                                         \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationLightenBlend    { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        /* n=mask (d<s:0xff, d>=s:0x00) */                                                                 \\\n        s = (s&n)|(d&~n);                                                                                  \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationDarkenBlend     { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        /* n=mask (d<s:0xff, d>=s:0x00) */                                                                 \\\n        s = (d&n)|(s&~n);                                                                                  \\\n        TVPPS_ALPHABLEND                                                                                   \\\n}\n#define TVPPsOperationDiffBlend       { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        /* n=mask (d<s:0xff, d>=s:0x00) */                                                                 \\\n        s = ((s&n)-(d&n))|((d&~n)-(s&~n));                                                                 \\\n        TVPPS_ALPHABLEND     /* Alphablend result & dst */                                                 \\\n}\n#define TVPPsOperationDiff5Blend      { \\\n        TVPPS_REG tjs_uint32 n;                                                                            \\\n        TVPPS_FADESRC        /* Fade src first */                                                          \\\n        n = (((~d&s)<<1)+((~d^s)&0x00fefefe))&0x01010100;                                                  \\\n        n = ((n>>8)+0x007f7f7f)^0x007f7f7f;                                                                \\\n        /* n=mask (d<s:0xff, d>=s:0x00) */                                                                 \\\n        s = ((s&n)-(d&n))|((d&~n)-(s&~n));                                                                 \\\n}\n#define TVPPsOperationExclusionBlend  { \\\n        /* c = ((s+d-(s*d*2)/255)-d)*a + d = (s-(s*d*2)/255)*a + d */                                      \\\n        TVPPS_REG tjs_uint32 sd1, sd2;                                                                     \\\n        sd1 = ( ((((d>>16)&0xff)*((s&0x00ff0000)>>7))&0x01ff0000) |                                        \\\n                ((((d>>0 )&0xff)*( s&0x000000ff    ))>>7        ) );                                       \\\n        sd2 = ( ((((d>>8 )&0xff)*(s&0x0000ff00))&0x00ff8000) ) >> 7;                                       \\\n        s = ((((((s&0x00ff00ff)-sd1)*a)>>8)+(d&0x00ff00ff))&0x00ff00ff) |                                  \\\n            ((((((s&0x0000ff00)-sd2)*a)>>8)+(d&0x0000ff00))&0x0000ff00);                                   \\\n}\n\n\n/* --------------------------------------------------------------------\n  Table initialize function\n-------------------------------------------------------------------- */\nvoid TVPPsMakeTable(void)\n{\n\tint s, d;\n\tfor (s=0; s<256; s++) {\n\t\tfor (d=0; d<256; d++) {\n\t\t\tTVPPsTableSoftLight[s][d]  = (s>=128) ?\n\t\t\t\t( ((unsigned char)(pow(d/255.0, 128.0/s)*255.0)) ) :\n\t\t\t\t( ((unsigned char)(pow(d/255.0, (1.0-s/255.0)/0.5)*255.0)) );\n\t\t\tTVPPsTableColorDodge[s][d] = ((255-s)<=d) ? (0xff) : ((d*255)/(255-s));\n\t\t\tTVPPsTableColorBurn[s][d]  = (s<=(255-d)) ? (0x00) : (255-((255-d)*255)/s);\n#ifdef TVPPS_USE_OVERLAY_TABLE\n\t\t\tTVPPsTableOverlay[s][d]  = (d<128) ? ((s*d*2)/255) : (((s+d)*2)-((s*d*2)/255)-255);\n#endif\n\t\t}\n\t}\n}\n\n/* --------------------------------------------------------------------\n  Function substances\n-------------------------------------------------------------------- */\n#define TVPPS_FUNC_NORM  TVPPsAlphaBlend_c\n#define TVPPS_FUNC_O     TVPPsAlphaBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsAlphaBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsAlphaBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationAlphaBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsAddBlend_c\n#define TVPPS_FUNC_O     TVPPsAddBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsAddBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsAddBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationAddBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsSubBlend_c\n#define TVPPS_FUNC_O     TVPPsSubBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsSubBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsSubBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationSubBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsMulBlend_c\n#define TVPPS_FUNC_O     TVPPsMulBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsMulBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsMulBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationMulBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsScreenBlend_c\n#define TVPPS_FUNC_O     TVPPsScreenBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsScreenBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsScreenBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationScreenBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsOverlayBlend_c\n#define TVPPS_FUNC_O     TVPPsOverlayBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsOverlayBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsOverlayBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationOverlayBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsHardLightBlend_c\n#define TVPPS_FUNC_O     TVPPsHardLightBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsHardLightBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsHardLightBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationHardLightBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsSoftLightBlend_c\n#define TVPPS_FUNC_O     TVPPsSoftLightBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsSoftLightBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsSoftLightBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationSoftLightBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsColorDodgeBlend_c\n#define TVPPS_FUNC_O     TVPPsColorDodgeBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsColorDodgeBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsColorDodgeBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationColorDodgeBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsColorDodge5Blend_c\n#define TVPPS_FUNC_O     TVPPsColorDodge5Blend_o_c\n#define TVPPS_FUNC_HDA   TVPPsColorDodge5Blend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsColorDodge5Blend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationColorDodge5Blend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsColorBurnBlend_c\n#define TVPPS_FUNC_O     TVPPsColorBurnBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsColorBurnBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsColorBurnBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationColorBurnBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsLightenBlend_c\n#define TVPPS_FUNC_O     TVPPsLightenBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsLightenBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsLightenBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationLightenBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsDarkenBlend_c\n#define TVPPS_FUNC_O     TVPPsDarkenBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsDarkenBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsDarkenBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationDarkenBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsDiffBlend_c\n#define TVPPS_FUNC_O     TVPPsDiffBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsDiffBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsDiffBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationDiffBlend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsDiff5Blend_c\n#define TVPPS_FUNC_O     TVPPsDiff5Blend_o_c\n#define TVPPS_FUNC_HDA   TVPPsDiff5Blend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsDiff5Blend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationDiff5Blend\n#include \"tvpps.inc\"\n\n#define TVPPS_FUNC_NORM  TVPPsExclusionBlend_c\n#define TVPPS_FUNC_O     TVPPsExclusionBlend_o_c\n#define TVPPS_FUNC_HDA   TVPPsExclusionBlend_HDA_c\n#define TVPPS_FUNC_HDA_O TVPPsExclusionBlend_HDA_o_c\n#define TVPPS_OPERATION  TVPPsOperationExclusionBlend\n#include \"tvpps.inc\"\n\n#if 0\n/* dummy definitions to be checked in gengl.pl */\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAlphaBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAlphaBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAlphaBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAlphaBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAddBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAddBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAddBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsAddBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSubBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSubBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSubBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSubBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsMulBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsMulBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsMulBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsMulBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsScreenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsScreenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsScreenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsScreenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsOverlayBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsOverlayBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsOverlayBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsOverlayBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsHardLightBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsHardLightBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsHardLightBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsHardLightBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSoftLightBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSoftLightBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSoftLightBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsSoftLightBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodgeBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodgeBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodgeBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodgeBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodge5Blend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodge5Blend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodge5Blend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorDodge5Blend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorBurnBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorBurnBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorBurnBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsColorBurnBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsLightenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsLightenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsLightenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsLightenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDarkenBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDarkenBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDarkenBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDarkenBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiffBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiffBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiffBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiffBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiff5Blend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiff5Blend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiff5Blend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsDiff5Blend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsExclusionBlend_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsExclusionBlend_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsExclusionBlend_HDA_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len))\n{}\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPPsExclusionBlend_HDA_o_c, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa))\n{}\n\n#endif\n\nTVP_GL_FUNC_DECL(void, TVPConvert32BitTo24Bit_c, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len))\n{\n\tconst tjs_uint8 *slimglim = buf + len; // in bytes\n\tconst tjs_uint8 *slimglims = slimglim - 16;\n\twhile (buf < slimglims) {\n\t\ttjs_uint32 c0 = 0[(tjs_uint32*)buf] & 0xFFFFFF;\n\t\ttjs_uint32 c1 = 1[(tjs_uint32*)buf] & 0xFFFFFF;\n\t\ttjs_uint32 c2 = 2[(tjs_uint32*)buf] & 0xFFFFFF;\n\t\ttjs_uint32 c3 = 3[(tjs_uint32*)buf] & 0xFFFFFF;\n\t\t0[(tjs_uint32*)dest] = (c0) | (c1 << 24);\n\t\t1[(tjs_uint32*)dest] = (c1 >> 8) | (c2 << 16);\n\t\t2[(tjs_uint32*)dest] = (c2 >> 16) | (c3 << 8);\n\t\tbuf += 16;\n\t\tdest += 12;\n\t}\n\twhile (buf < slimglim)\n\t{\n\t\t*(tjs_uint32*)dest = *(tjs_uint32*)buf;\n\t\tdest += 3;\n\t\tbuf += 4;\n\t}\n}\n\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_do,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaBlend_ao,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAlphaColorMat,  (tjs_uint32 *dest, const tjs_uint32 color, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConvertAdditiveAlphaToAlpha,  (tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPConvertAlphaToAdditiveAlpha,  (tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_do,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpStretchAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpStretchAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_do,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpLinTransAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpLinTransAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPCopyOpaqueImage,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchCopyOpaqueImage,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchConstAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpStretchConstAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchConstAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchConstAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchConstAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransCopyOpaqueImage,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransConstAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpLinTransConstAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransConstAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransConstAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransConstAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_SD,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_SD_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstAlphaBlend_SD_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPInitUnivTransBlendTable,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_DECL(void, TVPInitUnivTransBlendTable_d,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_DECL(void, TVPInitUnivTransBlendTable_a,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend_switch,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend_switch_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPUnivTransBlend_switch_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_HDA,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_HDA_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_HDA,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_HDA_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_d,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_d,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_a,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_a,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_do,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_do,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap_ao,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPApplyColorMap65_ao,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstColorAlphaBlend,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstColorAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPConstColorAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPRemoveConstOpacity,  (tjs_uint32 *dest, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_DECL(void, TVPRemoveOpacity,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPRemoveOpacity_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_DECL(void, TVPRemoveOpacity65,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPRemoveOpacity65_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPSubBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPSubBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPSubBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPSubBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPMulBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPMulBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPMulBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPMulBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPColorDodgeBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPColorDodgeBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPColorDodgeBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPColorDodgeBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPDarkenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDarkenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDarkenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPDarkenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLightenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPLightenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPLightenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPLightenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPScreenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPScreenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPScreenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPScreenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpStretchCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPFastLinearInterpH2F,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src));\nTVP_GL_FUNC_PTR_DECL(void, TVPFastLinearInterpH2B,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src));\nTVP_GL_FUNC_PTR_DECL(void, TVPFastLinearInterpV2,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src0, const tjs_uint32 *src1));\nTVP_GL_FUNC_PTR_DECL(void, TVPStretchColorCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPInterpLinTransCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPLinTransColorCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_DECL(void, TVPMakeAlphaFromKey,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 key));\nTVP_GL_FUNC_PTR_DECL(void, TVPCopyMask,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPCopyColor,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBindMaskToMain,  (tjs_uint32 *main, const tjs_uint8 *mask, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPFillARGB,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 value));\nTVP_GL_FUNC_PTR_DECL(void, TVPFillARGB_NC,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 value));\nTVP_GL_FUNC_PTR_DECL(void, TVPFillColor,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_DECL(void, TVPFillMask,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 mask));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddSubVertSum16,  (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddSubVertSum16_d,  (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddSubVertSum32,  (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPAddSubVertSum32_d,  (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDoBoxBlurAvg16,  (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDoBoxBlurAvg16_d,  (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDoBoxBlurAvg32,  (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDoBoxBlurAvg32_d,  (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPSwapLine8,  (tjs_uint8 *line1, tjs_uint8 *line2, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPSwapLine32,  (tjs_uint32 *line1, tjs_uint32 *line2, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPReverse8,  (tjs_uint8 *pixels, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPReverse32,  (tjs_uint32 *pixels, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDoGrayScale,  (tjs_uint32 *dest, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPInitGammaAdjustTempData,  (tTVPGLGammaAdjustTempData *temp, const tTVPGLGammaAdjustData *data));\nTVP_GL_FUNC_PTR_DECL(void, TVPUninitGammaAdjustTempData,  (tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdjustGamma,  (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_DECL(void, TVPAdjustGamma_a,  (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurMulCopy65,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level));\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurAddMulCopy65,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level));\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurCopy65,  (tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel));\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurMulCopy,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level) );\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurAddMulCopy,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level) );\nTVP_GL_FUNC_PTR_DECL(void, TVPChBlurCopy,  (tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel) );\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand1BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand1BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand1BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand4BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand4BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand4BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand8BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLExpand8BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_DECL(void, TVPExpand8BitTo32BitGray,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert15BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint16 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert15BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint16 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert24BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert24BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPConvert24BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert32BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert32BitTo32Bit_NoneAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert32BitTo32Bit_MulAddAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPBLConvert32BitTo32Bit_AddAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPDither32BitTo16Bit565,  (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_DECL(void, TVPDither32BitTo16Bit555,  (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_DECL(void, TVPDither32BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG5ComposeColors3To4,  (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const * buf, tjs_int width));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG5ComposeColors4To4,  (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const* buf, tjs_int width));\nTVP_GL_FUNC_PTR_DECL(tjs_int, TVPTLG5DecompressSlide,  (tjs_uint8 *out, const tjs_uint8 *in, tjs_int insize, tjs_uint8 *text, tjs_int initialr));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG6DecodeGolombValuesForFirst,  (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG6DecodeGolombValues,  (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG6DecodeLineGeneric,  (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int start_block, tjs_int block_limit, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir));\nTVP_GL_FUNC_PTR_DECL(void, TVPTLG6DecodeLine,  (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int block_count, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAddBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAddBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAddBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsAddBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSubBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSubBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSubBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSubBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsMulBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsMulBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsMulBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsMulBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsScreenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsScreenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsScreenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsScreenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsOverlayBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsOverlayBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsOverlayBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsOverlayBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsHardLightBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsHardLightBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsHardLightBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsHardLightBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSoftLightBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSoftLightBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSoftLightBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsSoftLightBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodgeBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodgeBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodgeBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodgeBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodge5Blend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodge5Blend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodge5Blend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorDodge5Blend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorBurnBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorBurnBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorBurnBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsColorBurnBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsLightenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsLightenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsLightenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsLightenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDarkenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDarkenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDarkenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDarkenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiffBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiffBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiffBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiffBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiff5Blend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiff5Blend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiff5Blend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsDiff5Blend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsExclusionBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsExclusionBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsExclusionBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPPsExclusionBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\n\n// add by ZeaS\nTVP_GL_FUNC_PTR_DECL(void, TVPReverseRGB, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPUpscale65_255, (tjs_uint8 *dest, tjs_int len));\nTVP_GL_FUNC_PTR_DECL(void, TVPConvert32BitTo24Bit, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\n\n/* suffix \"_c\" : function is written in C */\n#include \"tvpgl_route.h\"\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPInitTVPGL, ())\n{\n    //_Initialize_Route_Ptr();\n#if 1\n#if 0 // krkrz's blend_function\n\tTVPAlphaBlend = TVPAlphaBlend_c;\n\tTVPAlphaBlend_HDA = TVPAlphaBlend_HDA_c;\n\tTVPAlphaBlend_o = TVPAlphaBlend_o_c;\n\tTVPAlphaBlend_HDA_o = TVPAlphaBlend_HDA_o_c;\n\tTVPAlphaBlend_d = TVPAlphaBlend_d_c;\n\tTVPAlphaBlend_a = TVPAlphaBlend_a_c;\n\tTVPAlphaBlend_do = TVPAlphaBlend_do_c;\n\tTVPAlphaBlend_ao = TVPAlphaBlend_ao_c;\n\tTVPAlphaColorMat = TVPAlphaColorMat_c;\n\tTVPAdditiveAlphaBlend = TVPAdditiveAlphaBlend_c;\n\tTVPAdditiveAlphaBlend_HDA = TVPAdditiveAlphaBlend_HDA_c;\n\tTVPAdditiveAlphaBlend_o = TVPAdditiveAlphaBlend_o_c;\n\tTVPAdditiveAlphaBlend_HDA_o = TVPAdditiveAlphaBlend_HDA_o_c;\n\tTVPAdditiveAlphaBlend_a = TVPAdditiveAlphaBlend_a_c;\n\tTVPAdditiveAlphaBlend_ao = TVPAdditiveAlphaBlend_ao_c;\n\tTVPConvertAdditiveAlphaToAlpha = TVPConvertAdditiveAlphaToAlpha_c;\n\tTVPConvertAlphaToAdditiveAlpha = TVPConvertAlphaToAdditiveAlpha_c;\n#endif\n\tTVPStretchAlphaBlend = TVPStretchAlphaBlend_c;\n\tTVPStretchAlphaBlend_HDA = TVPStretchAlphaBlend_HDA_c;\n\tTVPStretchAlphaBlend_o = TVPStretchAlphaBlend_o_c;\n\tTVPStretchAlphaBlend_HDA_o = TVPStretchAlphaBlend_HDA_o_c;\n\tTVPStretchAlphaBlend_d = TVPStretchAlphaBlend_d_c;\n\tTVPStretchAlphaBlend_a = TVPStretchAlphaBlend_a_c;\n\tTVPStretchAlphaBlend_do = TVPStretchAlphaBlend_do_c;\n\tTVPStretchAlphaBlend_ao = TVPStretchAlphaBlend_ao_c;\n\tTVPStretchAdditiveAlphaBlend = TVPStretchAdditiveAlphaBlend_c;\n\tTVPInterpStretchAdditiveAlphaBlend = TVPInterpStretchAdditiveAlphaBlend_c;\n\tTVPStretchAdditiveAlphaBlend_HDA = TVPStretchAdditiveAlphaBlend_HDA_c;\n\tTVPStretchAdditiveAlphaBlend_o = TVPStretchAdditiveAlphaBlend_o_c;\n\tTVPInterpStretchAdditiveAlphaBlend_o = TVPInterpStretchAdditiveAlphaBlend_o_c;\n\tTVPStretchAdditiveAlphaBlend_HDA_o = TVPStretchAdditiveAlphaBlend_HDA_o_c;\n\tTVPStretchAdditiveAlphaBlend_a = TVPStretchAdditiveAlphaBlend_a_c;\n\tTVPStretchAdditiveAlphaBlend_ao = TVPStretchAdditiveAlphaBlend_ao_c;\n\tTVPLinTransAlphaBlend = TVPLinTransAlphaBlend_c;\n\tTVPLinTransAlphaBlend_HDA = TVPLinTransAlphaBlend_HDA_c;\n\tTVPLinTransAlphaBlend_o = TVPLinTransAlphaBlend_o_c;\n\tTVPLinTransAlphaBlend_HDA_o = TVPLinTransAlphaBlend_HDA_o_c;\n\tTVPLinTransAlphaBlend_d = TVPLinTransAlphaBlend_d_c;\n\tTVPLinTransAlphaBlend_a = TVPLinTransAlphaBlend_a_c;\n\tTVPLinTransAlphaBlend_do = TVPLinTransAlphaBlend_do_c;\n\tTVPLinTransAlphaBlend_ao = TVPLinTransAlphaBlend_ao_c;\n\tTVPLinTransAdditiveAlphaBlend = TVPLinTransAdditiveAlphaBlend_c;\n\tTVPInterpLinTransAdditiveAlphaBlend = TVPInterpLinTransAdditiveAlphaBlend_c;\n\tTVPLinTransAdditiveAlphaBlend_HDA = TVPLinTransAdditiveAlphaBlend_HDA_c;\n\tTVPLinTransAdditiveAlphaBlend_o = TVPLinTransAdditiveAlphaBlend_o_c;\n\tTVPInterpLinTransAdditiveAlphaBlend_o = TVPInterpLinTransAdditiveAlphaBlend_o_c;\n\tTVPLinTransAdditiveAlphaBlend_HDA_o = TVPLinTransAdditiveAlphaBlend_HDA_o_c;\n\tTVPLinTransAdditiveAlphaBlend_a = TVPLinTransAdditiveAlphaBlend_a_c;\n\tTVPLinTransAdditiveAlphaBlend_ao = TVPLinTransAdditiveAlphaBlend_ao_c;\n#if 0 // krkrz's blend_function\n\tTVPCopyOpaqueImage = TVPCopyOpaqueImage_c;\n\tTVPConstAlphaBlend = TVPConstAlphaBlend_c;\n\tTVPConstAlphaBlend_HDA = TVPConstAlphaBlend_HDA_c;\n\tTVPConstAlphaBlend_d = TVPConstAlphaBlend_d_c;\n\tTVPConstAlphaBlend_a = TVPConstAlphaBlend_a_c;\n#endif\n\tTVPStretchCopyOpaqueImage = TVPStretchCopyOpaqueImage_c;\n\tTVPStretchConstAlphaBlend = TVPStretchConstAlphaBlend_c;\n\tTVPInterpStretchConstAlphaBlend = TVPInterpStretchConstAlphaBlend_c;\n\tTVPStretchConstAlphaBlend_HDA = TVPStretchConstAlphaBlend_HDA_c;\n\tTVPStretchConstAlphaBlend_d = TVPStretchConstAlphaBlend_d_c;\n\tTVPStretchConstAlphaBlend_a = TVPStretchConstAlphaBlend_a_c;\n\tTVPLinTransCopyOpaqueImage = TVPLinTransCopyOpaqueImage_c;\n\tTVPLinTransConstAlphaBlend = TVPLinTransConstAlphaBlend_c;\n\tTVPInterpLinTransConstAlphaBlend = TVPInterpLinTransConstAlphaBlend_c;\n\tTVPLinTransConstAlphaBlend_HDA = TVPLinTransConstAlphaBlend_HDA_c;\n\tTVPLinTransConstAlphaBlend_d = TVPLinTransConstAlphaBlend_d_c;\n\tTVPLinTransConstAlphaBlend_a = TVPLinTransConstAlphaBlend_a_c;\n#if 0 // krkrz's blend_function\n\tTVPConstAlphaBlend_SD = TVPConstAlphaBlend_SD_c;\n\tTVPConstAlphaBlend_SD_a = TVPConstAlphaBlend_SD_a_c;\n\tTVPConstAlphaBlend_SD_d = TVPConstAlphaBlend_SD_d_c;\n#endif\n\tTVPInitUnivTransBlendTable = TVPInitUnivTransBlendTable_c;\n\tTVPInitUnivTransBlendTable_d = TVPInitUnivTransBlendTable_d_c;\n\tTVPInitUnivTransBlendTable_a = TVPInitUnivTransBlendTable_a_c;\n\tTVPUnivTransBlend = TVPUnivTransBlend_c;\n\tTVPUnivTransBlend_switch = TVPUnivTransBlend_switch_c;\n\tTVPUnivTransBlend_d = TVPUnivTransBlend_d_c;\n\tTVPUnivTransBlend_switch_d = TVPUnivTransBlend_switch_d_c;\n\tTVPUnivTransBlend_a = TVPUnivTransBlend_a_c;\n\tTVPUnivTransBlend_switch_a = TVPUnivTransBlend_switch_a_c;\n#if 0 // krkrz's blend_function\n\tTVPApplyColorMap = TVPApplyColorMap_c;\n\tTVPApplyColorMap_o = TVPApplyColorMap_o_c;\n// \tTVPApplyColorMap65 = TVPApplyColorMap65_c;\n// \tTVPApplyColorMap65_o = TVPApplyColorMap65_o_c;\n\tTVPApplyColorMap_HDA = TVPApplyColorMap_HDA_c;\n\tTVPApplyColorMap_HDA_o = TVPApplyColorMap_HDA_o_c;\n// \tTVPApplyColorMap65_HDA = TVPApplyColorMap65_HDA_c;\n// \tTVPApplyColorMap65_HDA_o = TVPApplyColorMap65_HDA_o_c;\n\tTVPApplyColorMap_d = TVPApplyColorMap_d_c;\n//\tTVPApplyColorMap65_d = TVPApplyColorMap65_d_c;\n\tTVPApplyColorMap_a = TVPApplyColorMap_a_c;\n//\tTVPApplyColorMap65_a = TVPApplyColorMap65_a_c;\n\tTVPApplyColorMap_do = TVPApplyColorMap_do_c;\n//\tTVPApplyColorMap65_do = TVPApplyColorMap65_do_c;\n\tTVPApplyColorMap_ao = TVPApplyColorMap_ao_c;\n//\tTVPApplyColorMap65_ao = TVPApplyColorMap65_ao_c;\n\tTVPConstColorAlphaBlend = TVPConstColorAlphaBlend_c;\n\tTVPConstColorAlphaBlend_d = TVPConstColorAlphaBlend_d_c;\n\tTVPConstColorAlphaBlend_a = TVPConstColorAlphaBlend_a_c;\n\tTVPRemoveConstOpacity = TVPRemoveConstOpacity_c;\n\tTVPRemoveOpacity = TVPRemoveOpacity_c;\n\tTVPRemoveOpacity_o = TVPRemoveOpacity_o_c;\n// \tTVPRemoveOpacity65 = TVPRemoveOpacity65_c;\n// \tTVPRemoveOpacity65_o = TVPRemoveOpacity65_o_c;\n\tTVPAddBlend = TVPAddBlend_c;\n\tTVPAddBlend_HDA = TVPAddBlend_HDA_c;\n\tTVPAddBlend_o = TVPAddBlend_o_c;\n\tTVPAddBlend_HDA_o = TVPAddBlend_HDA_o_c;\n\tTVPSubBlend = TVPSubBlend_c;\n\tTVPSubBlend_HDA = TVPSubBlend_HDA_c;\n\tTVPSubBlend_o = TVPSubBlend_o_c;\n\tTVPSubBlend_HDA_o = TVPSubBlend_HDA_o_c;\n\tTVPMulBlend = TVPMulBlend_c;\n\tTVPMulBlend_HDA = TVPMulBlend_HDA_c;\n\tTVPMulBlend_o = TVPMulBlend_o_c;\n\tTVPMulBlend_HDA_o = TVPMulBlend_HDA_o_c;\n\tTVPColorDodgeBlend = TVPColorDodgeBlend_c;\n\tTVPColorDodgeBlend_HDA = TVPColorDodgeBlend_HDA_c;\n\tTVPColorDodgeBlend_o = TVPColorDodgeBlend_o_c;\n\tTVPColorDodgeBlend_HDA_o = TVPColorDodgeBlend_HDA_o_c;\n\tTVPDarkenBlend = TVPDarkenBlend_c;\n\tTVPDarkenBlend_HDA = TVPDarkenBlend_HDA_c;\n\tTVPDarkenBlend_o = TVPDarkenBlend_o_c;\n\tTVPDarkenBlend_HDA_o = TVPDarkenBlend_HDA_o_c;\n\tTVPLightenBlend = TVPLightenBlend_c;\n\tTVPLightenBlend_HDA = TVPLightenBlend_HDA_c;\n\tTVPLightenBlend_o = TVPLightenBlend_o_c;\n\tTVPLightenBlend_HDA_o = TVPLightenBlend_HDA_o_c;\n\tTVPScreenBlend = TVPScreenBlend_c;\n\tTVPScreenBlend_HDA = TVPScreenBlend_HDA_c;\n\tTVPScreenBlend_o = TVPScreenBlend_o_c;\n\tTVPScreenBlend_HDA_o = TVPScreenBlend_HDA_o_c;\n#endif\n\tTVPStretchCopy = TVPStretchCopy_c;\n\tTVPInterpStretchCopy = TVPInterpStretchCopy_c;\n\tTVPFastLinearInterpH2F = TVPFastLinearInterpH2F_c;\n\tTVPFastLinearInterpH2B = TVPFastLinearInterpH2B_c;\n\tTVPFastLinearInterpV2 = TVPFastLinearInterpV2_c;\n\tTVPStretchColorCopy = TVPStretchColorCopy_c;\n\tTVPLinTransCopy = TVPLinTransCopy_c;\n\tTVPInterpLinTransCopy = TVPInterpLinTransCopy_c;\n\tTVPLinTransColorCopy = TVPLinTransColorCopy_c;\n#if 0 // krkrz's blend_function\n\tTVPMakeAlphaFromKey = TVPMakeAlphaFromKey_c;\n\tTVPCopyMask = TVPCopyMask_c;\n\tTVPCopyColor = TVPCopyColor_c;\n\tTVPBindMaskToMain = TVPBindMaskToMain_c;\n\tTVPFillARGB = TVPFillARGB_c;\n\tTVPFillARGB_NC = TVPFillARGB_NC_c;\n\tTVPFillColor = TVPFillColor_c;\n\tTVPFillMask = TVPFillMask_c;\n#endif\n\tTVPAddSubVertSum16 = TVPAddSubVertSum16_c;\n\tTVPAddSubVertSum16_d = TVPAddSubVertSum16_d_c;\n\tTVPAddSubVertSum32 = TVPAddSubVertSum32_c;\n\tTVPAddSubVertSum32_d = TVPAddSubVertSum32_d_c;\n\tTVPDoBoxBlurAvg16 = TVPDoBoxBlurAvg16_c;\n\tTVPDoBoxBlurAvg16_d = TVPDoBoxBlurAvg16_d_c;\n\tTVPDoBoxBlurAvg32 = TVPDoBoxBlurAvg32_c;\n\tTVPDoBoxBlurAvg32_d = TVPDoBoxBlurAvg32_d_c;\n#if 0 // krkrz's blend_function\n\tTVPSwapLine8 = TVPSwapLine8_c;\n\tTVPSwapLine32 = TVPSwapLine32_c;\n\tTVPReverse8 = TVPReverse8_c;\n\tTVPReverse32 = TVPReverse32_c;\n\tTVPDoGrayScale = TVPDoGrayScale_c;\n#endif\n\tTVPInitGammaAdjustTempData = TVPInitGammaAdjustTempData_c;\n\tTVPUninitGammaAdjustTempData = TVPUninitGammaAdjustTempData_c;\n\tTVPAdjustGamma = TVPAdjustGamma_c;\n\tTVPAdjustGamma_a = TVPAdjustGamma_a_c;\n#if 0 // krkrz's blend_function\n\tTVPChBlurMulCopy65 = TVPChBlurMulCopy65_c;\n\tTVPChBlurAddMulCopy65 = TVPChBlurAddMulCopy65_c;\n\tTVPChBlurCopy65 = TVPChBlurCopy65_c;\n#endif\n\tTVPBLExpand1BitTo8BitPal = TVPBLExpand1BitTo8BitPal_c;\n\tTVPBLExpand1BitTo8Bit = TVPBLExpand1BitTo8Bit_c;\n\tTVPBLExpand1BitTo32BitPal = TVPBLExpand1BitTo32BitPal_c;\n\tTVPBLExpand4BitTo8BitPal = TVPBLExpand4BitTo8BitPal_c;\n\tTVPBLExpand4BitTo8Bit = TVPBLExpand4BitTo8Bit_c;\n\tTVPBLExpand4BitTo32BitPal = TVPBLExpand4BitTo32BitPal_c;\n\tTVPBLExpand8BitTo8BitPal = TVPBLExpand8BitTo8BitPal_c;\n\tTVPBLExpand8BitTo32BitPal = TVPBLExpand8BitTo32BitPal_c;\n\tTVPExpand8BitTo32BitGray = TVPExpand8BitTo32BitGray_c;\n\tTVPBLConvert15BitTo8Bit = TVPBLConvert15BitTo8Bit_c;\n\tTVPBLConvert15BitTo32Bit = TVPBLConvert15BitTo32Bit_c;\n\tTVPBLConvert24BitTo8Bit = TVPBLConvert24BitTo8Bit_c;\n\tTVPBLConvert24BitTo32Bit = TVPBLConvert24BitTo32Bit_c;\n\tTVPConvert24BitTo32Bit = TVPConvert24BitTo32Bit_c;\n\tTVPBLConvert32BitTo8Bit = TVPBLConvert32BitTo8Bit_c;\n\tTVPBLConvert32BitTo32Bit_NoneAlpha = TVPBLConvert32BitTo32Bit_NoneAlpha_c;\n\tTVPBLConvert32BitTo32Bit_MulAddAlpha = TVPBLConvert32BitTo32Bit_MulAddAlpha_c;\n\tTVPBLConvert32BitTo32Bit_AddAlpha = TVPBLConvert32BitTo32Bit_AddAlpha_c;\n\tTVPDither32BitTo16Bit565 = TVPDither32BitTo16Bit565_c;\n\tTVPDither32BitTo16Bit555 = TVPDither32BitTo16Bit555_c;\n\tTVPDither32BitTo8Bit = TVPDither32BitTo8Bit_c;\n\tTVPTLG5ComposeColors3To4 = TVPTLG5ComposeColors3To4_c;\n\tTVPTLG5ComposeColors4To4 = TVPTLG5ComposeColors4To4_c;\n\tTVPTLG5DecompressSlide = TVPTLG5DecompressSlide_c;\n\tTVPTLG6DecodeGolombValuesForFirst = TVPTLG6DecodeGolombValuesForFirst_c;\n\tTVPTLG6DecodeGolombValues = TVPTLG6DecodeGolombValues_c;\n\tTVPTLG6DecodeLineGeneric = TVPTLG6DecodeLineGeneric_c;\n\tTVPTLG6DecodeLine = TVPTLG6DecodeLine_c;\n#if 0 // krkrz's blend_function\n\tTVPPsAlphaBlend = TVPPsAlphaBlend_c;\n\tTVPPsAlphaBlend_o = TVPPsAlphaBlend_o_c;\n\tTVPPsAlphaBlend_HDA = TVPPsAlphaBlend_HDA_c;\n\tTVPPsAlphaBlend_HDA_o = TVPPsAlphaBlend_HDA_o_c;\n\tTVPPsAddBlend = TVPPsAddBlend_c;\n\tTVPPsAddBlend_o = TVPPsAddBlend_o_c;\n\tTVPPsAddBlend_HDA = TVPPsAddBlend_HDA_c;\n\tTVPPsAddBlend_HDA_o = TVPPsAddBlend_HDA_o_c;\n\tTVPPsSubBlend = TVPPsSubBlend_c;\n\tTVPPsSubBlend_o = TVPPsSubBlend_o_c;\n\tTVPPsSubBlend_HDA = TVPPsSubBlend_HDA_c;\n\tTVPPsSubBlend_HDA_o = TVPPsSubBlend_HDA_o_c;\n\tTVPPsMulBlend = TVPPsMulBlend_c;\n\tTVPPsMulBlend_o = TVPPsMulBlend_o_c;\n\tTVPPsMulBlend_HDA = TVPPsMulBlend_HDA_c;\n\tTVPPsMulBlend_HDA_o = TVPPsMulBlend_HDA_o_c;\n\tTVPPsScreenBlend = TVPPsScreenBlend_c;\n\tTVPPsScreenBlend_o = TVPPsScreenBlend_o_c;\n\tTVPPsScreenBlend_HDA = TVPPsScreenBlend_HDA_c;\n\tTVPPsScreenBlend_HDA_o = TVPPsScreenBlend_HDA_o_c;\n\tTVPPsOverlayBlend = TVPPsOverlayBlend_c;\n\tTVPPsOverlayBlend_o = TVPPsOverlayBlend_o_c;\n\tTVPPsOverlayBlend_HDA = TVPPsOverlayBlend_HDA_c;\n\tTVPPsOverlayBlend_HDA_o = TVPPsOverlayBlend_HDA_o_c;\n\tTVPPsHardLightBlend = TVPPsHardLightBlend_c;\n\tTVPPsHardLightBlend_o = TVPPsHardLightBlend_o_c;\n\tTVPPsHardLightBlend_HDA = TVPPsHardLightBlend_HDA_c;\n\tTVPPsHardLightBlend_HDA_o = TVPPsHardLightBlend_HDA_o_c;\n\tTVPPsSoftLightBlend = TVPPsSoftLightBlend_c;\n\tTVPPsSoftLightBlend_o = TVPPsSoftLightBlend_o_c;\n\tTVPPsSoftLightBlend_HDA = TVPPsSoftLightBlend_HDA_c;\n\tTVPPsSoftLightBlend_HDA_o = TVPPsSoftLightBlend_HDA_o_c;\n\tTVPPsColorDodgeBlend = TVPPsColorDodgeBlend_c;\n\tTVPPsColorDodgeBlend_o = TVPPsColorDodgeBlend_o_c;\n\tTVPPsColorDodgeBlend_HDA = TVPPsColorDodgeBlend_HDA_c;\n\tTVPPsColorDodgeBlend_HDA_o = TVPPsColorDodgeBlend_HDA_o_c;\n\tTVPPsColorDodge5Blend = TVPPsColorDodge5Blend_c;\n\tTVPPsColorDodge5Blend_o = TVPPsColorDodge5Blend_o_c;\n\tTVPPsColorDodge5Blend_HDA = TVPPsColorDodge5Blend_HDA_c;\n\tTVPPsColorDodge5Blend_HDA_o = TVPPsColorDodge5Blend_HDA_o_c;\n\tTVPPsColorBurnBlend = TVPPsColorBurnBlend_c;\n\tTVPPsColorBurnBlend_o = TVPPsColorBurnBlend_o_c;\n\tTVPPsColorBurnBlend_HDA = TVPPsColorBurnBlend_HDA_c;\n\tTVPPsColorBurnBlend_HDA_o = TVPPsColorBurnBlend_HDA_o_c;\n\tTVPPsLightenBlend = TVPPsLightenBlend_c;\n\tTVPPsLightenBlend_o = TVPPsLightenBlend_o_c;\n\tTVPPsLightenBlend_HDA = TVPPsLightenBlend_HDA_c;\n\tTVPPsLightenBlend_HDA_o = TVPPsLightenBlend_HDA_o_c;\n\tTVPPsDarkenBlend = TVPPsDarkenBlend_c;\n\tTVPPsDarkenBlend_o = TVPPsDarkenBlend_o_c;\n\tTVPPsDarkenBlend_HDA = TVPPsDarkenBlend_HDA_c;\n\tTVPPsDarkenBlend_HDA_o = TVPPsDarkenBlend_HDA_o_c;\n\tTVPPsDiffBlend = TVPPsDiffBlend_c;\n\tTVPPsDiffBlend_o = TVPPsDiffBlend_o_c;\n\tTVPPsDiffBlend_HDA = TVPPsDiffBlend_HDA_c;\n\tTVPPsDiffBlend_HDA_o = TVPPsDiffBlend_HDA_o_c;\n\tTVPPsDiff5Blend = TVPPsDiff5Blend_c;\n\tTVPPsDiff5Blend_o = TVPPsDiff5Blend_o_c;\n\tTVPPsDiff5Blend_HDA = TVPPsDiff5Blend_HDA_c;\n\tTVPPsDiff5Blend_HDA_o = TVPPsDiff5Blend_HDA_o_c;\n\tTVPPsExclusionBlend = TVPPsExclusionBlend_c;\n\tTVPPsExclusionBlend_o = TVPPsExclusionBlend_o_c;\n\tTVPPsExclusionBlend_HDA = TVPPsExclusionBlend_HDA_c;\n\tTVPPsExclusionBlend_HDA_o = TVPPsExclusionBlend_HDA_o_c;\n#endif\n// add by ZeaS\n    TVPReverseRGB = TVPReverseRGB_c;\n\tTVPUpscale65_255 = TVPUpscale65_255_c;\n\tTVPConvert32BitTo24Bit = TVPConvert32BitTo24Bit_c;\n#endif\n\tTVPCreateTable();\n\tTVPGL_C_Init();\n}\n\n/*export*/\nTVP_GL_FUNC_DECL(void, TVPUninitTVPGL, ())\n{\n\tTVPDestroyTable();\n}\n/*end of the file*/\n}\n"
  },
  {
    "path": "src/core/visual/tvpgl.h",
    "content": "/*\n\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2009 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n\n\n*/\n/* core C routines for graphics operations */\n/* this file is always generated by gengl.pl rev. 0.1 */\n#ifndef _TVPGL_H_\n#define _TVPGL_H_\n\n/*\n\tkey to blending suffix:\n\td : destination has alpha\n\ta : destination has additive-alpha\n\to : blend with opacity\n*/\n\n\n/*[*/\n#ifdef __cplusplus\n extern \"C\" {\n#endif\n/*]*/\n\n/*[*/\n#pragma pack(push, 4)\ntypedef struct\n{\n\t/* structure used for adjustment of gamma levels */\n\n\tfloat RGamma; /* R gamma   ( 0.10 -- 1.00 -- 9.99) */\n\ttjs_int RFloor;   /* output floor value  ( 0 -- 255 ) */\n\ttjs_int RCeil;    /* output ceil value ( 0 -- 255 ) */\n\tfloat GGamma; /* G */\n\ttjs_int GFloor;\n\ttjs_int GCeil;\n\tfloat BGamma; /* B */\n\ttjs_int BFloor;\n\ttjs_int BCeil;\n} tTVPGLGammaAdjustData;\n#pragma pack(pop)\n/*]*/\n\n#if 1\n#define TVP_GL_FUNC_DECL(rettype, funcname, arg)  rettype  funcname arg\n#define TVP_GL_FUNC_EXTERN_DECL(rettype, funcname, arg)  extern rettype  funcname arg\n#define TVP_GL_FUNC_PTR_DECL(rettype, funcname, arg) rettype ( * funcname) arg\n#define TVP_GL_FUNC_PTR_EXTERN_DECL_(rettype, funcname, arg) \\\n\textern rettype ( * funcname) arg; \\\n\textern rettype funcname##_c arg;\n#define TVP_GL_FUNC_PTR_EXTERN_DECL TVP_GL_FUNC_PTR_EXTERN_DECL_\n#endif\n\nextern unsigned char TVPDivTable[256*256];\nextern unsigned char TVP252DitherPalette[3][256];\n\n#define TVP_TLG6_H_BLOCK_SIZE 8\n#define TVP_TLG6_W_BLOCK_SIZE 8\n\n/* put platform dependent declaration here */\n\n\n/* add here compiler specific inline directives */\n#if defined( __BORLANDC__ ) || ( _MSC_VER )\n\t#define TVP_INLINE_FUNC __inline\n#else\n\t#define TVP_INLINE_FUNC \n#endif\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPSaturatedAdd(tjs_uint32 a, tjs_uint32 b)\n{\n\t/* Add each byte of packed 8bit values in two 32bit uint32, with saturation. */\n\ttjs_uint32 tmp = (  ( a & b ) + ( ((a ^ b)>>1) & 0x7f7f7f7f)  ) & 0x80808080;\n\ttmp = (tmp<<1) - (tmp>>7);\n\treturn (a + b - tmp) | tmp;\n}\n\n/*\n\tTVPAddAlphaBlend_dest_src[_o]\n\tdest/src    :    a(additive-alpha)  d(alpha)  n(none alpha)\n\t_o          :    with opacity\n*/\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_n_a(tjs_uint32 dest, tjs_uint32 src)\n{\n\ttjs_uint32 sopa = (~src) >> 24;\n\treturn TVPSaturatedAdd((((dest & 0xff00ff)*sopa >> 8) & 0xff00ff) + \n\t\t(((dest & 0xff00)*sopa >> 8) & 0xff00), src);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_HDA_n_a(tjs_uint32 dest, tjs_uint32 src)\n{\n\treturn (dest & 0xff000000) + (TVPAddAlphaBlend_n_a(dest, src) & 0xffffff);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_n_a_o(tjs_uint32 dest, tjs_uint32 src, tjs_int opa)\n{\n\tsrc = (((src & 0xff00ff)*opa >> 8) & 0xff00ff) + (((src >> 8) & 0xff00ff)*opa & 0xff00ff00);\n\treturn TVPAddAlphaBlend_n_a(dest, src);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_HDA_n_a_o(tjs_uint32 dest, tjs_uint32 src, tjs_int opa)\n{\n\treturn (dest & 0xff000000) + (TVPAddAlphaBlend_n_a_o(dest, src, opa) & 0xffffff);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_a_a(tjs_uint32 dest, tjs_uint32 src)\n{\n\t/*\n\t\tDi = sat(Si, (1-Sa)*Di)\n\t\tDa = Sa + Da - SaDa\n\t*/\n\n\ttjs_uint32 dopa = dest >> 24;\n\ttjs_uint32 sopa = src >> 24;\n\tdopa = dopa + sopa - (dopa*sopa >> 8);\n\tdopa -= (dopa >> 8); /* adjust alpha */\n\tsopa ^= 0xff;\n\tsrc &= 0xffffff;\n\treturn (dopa << 24) + \n\t\tTVPSaturatedAdd((((dest & 0xff00ff)*sopa >> 8) & 0xff00ff) +\n\t\t\t(((dest & 0xff00)*sopa >> 8) & 0xff00), src);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_a_ca(tjs_uint32 dest, tjs_uint32 sopa, tjs_uint32 sopa_inv, tjs_uint32 src)\n{\n\t/*\n\t\tDi = sat(Si, (1-Sa)*Di)\n\t\tDa = Sa + Da - SaDa\n\t*/\n\n\ttjs_uint32 dopa = dest >> 24;\n\tdopa = dopa + sopa - (dopa*sopa >> 8);\n\tdopa -= (dopa >> 8); /* adjust alpha */\n\treturn (dopa << 24) + \n\t\tTVPSaturatedAdd((((dest & 0xff00ff)*sopa_inv >> 8) & 0xff00ff) +\n\t\t\t(((dest & 0xff00)*sopa_inv >> 8) & 0xff00), src);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_a_a_o(tjs_uint32 dest, tjs_uint32 src, tjs_int opa)\n{\n\tsrc = (((src & 0xff00ff)*opa >> 8) & 0xff00ff) + (((src >> 8) & 0xff00ff)*opa & 0xff00ff00);\n\treturn TVPAddAlphaBlend_a_a(dest, src);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPMulColor(tjs_uint32 color, tjs_uint32 fac)\n{\n\treturn (((((color & 0x00ff00) * fac) & 0x00ff0000) +\n\t\t\t(((color & 0xff00ff) * fac) & 0xff00ff00) ) >> 8);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAlphaAndColorToAdditiveAlpha(tjs_uint32 alpha, tjs_uint32 color)\n{\n\treturn TVPMulColor(color, alpha) + (color & 0xff000000);\n\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAlphaToAdditiveAlpha(tjs_uint32 a)\n{\n\treturn TVPAlphaAndColorToAdditiveAlpha(a >> 24, a);\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_a_d(tjs_uint32 dest, tjs_uint32 src)\n{\n\treturn TVPAddAlphaBlend_a_a(dest, TVPAlphaToAdditiveAlpha(src));\n}\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPAddAlphaBlend_a_d_o(tjs_uint32 dest, tjs_uint32 src, tjs_int opa)\n{\n\tsrc = (src & 0xffffff) + ((((src >> 24) * opa) >> 8) << 24);\n\treturn TVPAddAlphaBlend_a_d(dest, src);\n}\n\n/* TVPAddAlphaBlend_d_a is not yet implemented because the expression may loose precision. */\n\n\nstatic tjs_uint32 TVP_INLINE_FUNC TVPBlendARGB(tjs_uint32 b, tjs_uint32 a, tjs_int ratio)\n{\n\t/* returns a * ratio + b * (1 - ratio) */\n\ttjs_uint32 b2;\n\ttjs_uint32 t;\n\tb2 = b & 0x00ff00ff;\n\tt = (b2 + (((a & 0x00ff00ff) - b2) * ratio >> 8)) & 0x00ff00ff;\n\tb2 = (b & 0xff00ff00) >> 8;\n\treturn t + \n\t\t(((b2 + (( ((a & 0xff00ff00) >> 8) - b2) * ratio >> 8)) << 8)& 0xff00ff00);\n}\n\n\n\n\n/*[*/\n#pragma pack(push, 4)\ntypedef struct\n{\n\ttjs_uint8 B[256];\n\ttjs_uint8 G[256];\n\ttjs_uint8 R[256];\n} tTVPGLGammaAdjustTempData;\n#pragma pack(pop)\n/*]*/\n/* begin function list */\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_do,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaBlend_ao,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAlphaColorMat,  (tjs_uint32 *dest, const tjs_uint32 color, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConvertAdditiveAlphaToAlpha,  (tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConvertAlphaToAdditiveAlpha,  (tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_do,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpStretchAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpStretchAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_do,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpLinTransAdditiveAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpLinTransAdditiveAlphaBlend_o,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend_HDA_o,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransAdditiveAlphaBlend_ao,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPCopyOpaqueImage,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchCopyOpaqueImage,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchConstAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpStretchConstAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchConstAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchConstAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchConstAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransCopyOpaqueImage,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransConstAlphaBlend,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpLinTransConstAlphaBlend,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransConstAlphaBlend_HDA,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransConstAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransConstAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_SD,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_SD_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstAlphaBlend_SD_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInitUnivTransBlendTable,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInitUnivTransBlendTable_d,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInitUnivTransBlendTable_a,  (tjs_uint32 *table, tjs_int phase, tjs_int vague));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend_switch,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend_switch_d,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUnivTransBlend_switch_a,  (tjs_uint32 *dest, const tjs_uint32 *src1, const tjs_uint32 *src2, const tjs_uint8 *rule, const tjs_uint32 *table, tjs_int len, tjs_int src1lv, tjs_int src2lv));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_HDA,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_HDA_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_HDA,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_HDA_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_d,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_d,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_a,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_a,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_do,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_do,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap_ao,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPApplyColorMap65_ao,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstColorAlphaBlend,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstColorAlphaBlend_d,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConstColorAlphaBlend_a,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPRemoveConstOpacity,  (tjs_uint32 *dest, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPRemoveOpacity,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPRemoveOpacity_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPRemoveOpacity65,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPRemoveOpacity65_o,  (tjs_uint32 *dest, const tjs_uint8 *src, tjs_int len, tjs_int strength));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSubBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSubBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSubBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSubBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPMulBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPMulBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPMulBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPMulBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPColorDodgeBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPColorDodgeBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPColorDodgeBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPColorDodgeBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDarkenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDarkenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDarkenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDarkenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLightenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLightenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLightenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLightenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPScreenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPScreenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPScreenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPScreenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpStretchCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src1, const tjs_uint32 *src2, tjs_int blend_y, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFastLinearInterpH2F,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFastLinearInterpH2B,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFastLinearInterpV2,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src0, const tjs_uint32 *src1));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPStretchColorCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int srcstart, tjs_int srcstep));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInterpLinTransCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPLinTransColorCopy,  (tjs_uint32 *dest, tjs_int destlen, const tjs_uint32 *src, tjs_int sx, tjs_int sy, tjs_int stepx, tjs_int stepy, tjs_int srcpitch));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPMakeAlphaFromKey,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 key));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPCopyMask,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPCopyColor,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBindMaskToMain,  (tjs_uint32 *main, const tjs_uint8 *mask, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFillARGB,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 value));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFillARGB_NC,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 value));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFillColor,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 color));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPFillMask,  (tjs_uint32 *dest, tjs_int len, tjs_uint32 mask));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddSubVertSum16,  (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddSubVertSum16_d,  (tjs_uint16 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddSubVertSum32,  (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAddSubVertSum32_d,  (tjs_uint32 *dest, const tjs_uint32 *addline, const tjs_uint32 *subline, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDoBoxBlurAvg16,  (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDoBoxBlurAvg16_d,  (tjs_uint32 *dest, tjs_uint16 *sum, const tjs_uint16 * add, const tjs_uint16 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDoBoxBlurAvg32,  (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDoBoxBlurAvg32_d,  (tjs_uint32 *dest, tjs_uint32 *sum, const tjs_uint32 * add, const tjs_uint32 * sub, tjs_int n, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSwapLine8,  (tjs_uint8 *line1, tjs_uint8 *line2, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPSwapLine32,  (tjs_uint32 *line1, tjs_uint32 *line2, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPReverse8,  (tjs_uint8 *pixels, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPReverse32,  (tjs_uint32 *pixels, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDoGrayScale,  (tjs_uint32 *dest, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPInitGammaAdjustTempData,  (tTVPGLGammaAdjustTempData *temp, const tTVPGLGammaAdjustData *data));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUninitGammaAdjustTempData,  (tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdjustGamma,  (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPAdjustGamma_a,  (tjs_uint32 *dest, tjs_int len, tTVPGLGammaAdjustTempData *temp));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurMulCopy65,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurAddMulCopy65,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurCopy65,  (tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurMulCopy,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level) );\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurAddMulCopy,  (tjs_uint8 *dest, const tjs_uint8 *src, tjs_int len, tjs_int level) );\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPChBlurCopy,  (tjs_uint8 *dest, tjs_int destpitch, tjs_int destwidth, tjs_int destheight, const tjs_uint8 * src, tjs_int srcpitch, tjs_int srcwidth, tjs_int srcheight, tjs_int blurwidth, tjs_int blurlevel) );\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand1BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand1BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand1BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand4BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand4BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand4BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand8BitTo8BitPal,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLExpand8BitTo32BitPal,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len, const tjs_uint32 *pal));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPExpand8BitTo32BitGray,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert15BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint16 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert15BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint16 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert24BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert24BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConvert24BitTo32Bit,  (tjs_uint32 *dest, const tjs_uint8 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert32BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert32BitTo32Bit_NoneAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert32BitTo32Bit_MulAddAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPBLConvert32BitTo32Bit_AddAlpha,  (tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDither32BitTo16Bit565,  (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDither32BitTo16Bit555,  (tjs_uint16 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPDither32BitTo8Bit,  (tjs_uint8 *dest, const tjs_uint32 *src, tjs_int len, tjs_int xofs, tjs_int yofs));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG5ComposeColors3To4,  (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const * buf, tjs_int width));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG5ComposeColors4To4,  (tjs_uint8 *outp, const tjs_uint8 *upper, tjs_uint8 * const* buf, tjs_int width));\nTVP_GL_FUNC_PTR_EXTERN_DECL(tjs_int, TVPTLG5DecompressSlide,  (tjs_uint8 *out, const tjs_uint8 *in, tjs_int insize, tjs_uint8 *text, tjs_int initialr));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG6DecodeGolombValuesForFirst,  (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG6DecodeGolombValues,  (tjs_int8 *pixelbuf, tjs_int pixel_count, tjs_uint8 *bit_pool));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG6DecodeLineGeneric,  (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int start_block, tjs_int block_limit, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPTLG6DecodeLine,  (tjs_uint32 *prevline, tjs_uint32 *curline, tjs_int width, tjs_int block_count, tjs_uint8 *filtertypes, tjs_int skipblockbytes, tjs_uint32 *in, tjs_uint32 initialp, tjs_int oddskip, tjs_int dir));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAlphaBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAlphaBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAlphaBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAlphaBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAddBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAddBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAddBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsAddBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSubBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSubBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSubBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSubBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsMulBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsMulBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsMulBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsMulBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsScreenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsScreenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsScreenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsScreenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsOverlayBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsOverlayBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsOverlayBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsOverlayBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsHardLightBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsHardLightBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsHardLightBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsHardLightBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSoftLightBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSoftLightBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSoftLightBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsSoftLightBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodgeBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodgeBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodgeBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodgeBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodge5Blend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodge5Blend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodge5Blend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorDodge5Blend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorBurnBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorBurnBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorBurnBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsColorBurnBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsLightenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsLightenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsLightenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsLightenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDarkenBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDarkenBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDarkenBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDarkenBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiffBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiffBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiffBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiffBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiff5Blend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiff5Blend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiff5Blend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsDiff5Blend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsExclusionBlend,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsExclusionBlend_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsExclusionBlend_HDA,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPPsExclusionBlend_HDA_o,  (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len, tjs_int opa));\n/* end function list */\n\n// add by ZeaS\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPReverseRGB, (tjs_uint32 *dest, const tjs_uint32 *src, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPUpscale65_255, (tjs_uint8 *dest, tjs_int len));\nTVP_GL_FUNC_PTR_EXTERN_DECL(void, TVPConvert32BitTo24Bit, (tjs_uint8 *dest, const tjs_uint8 *buf, tjs_int len));\n/* end function list */\n\nTVP_GL_FUNC_EXTERN_DECL(void, TVPInitTVPGL, ());\nTVP_GL_FUNC_EXTERN_DECL(void, TVPUninitTVPGL, ());\n/*[*/\n#ifdef __cplusplus\n }\n#endif\n/*]*/\n/* some utilities */\n/*[*/\n#define TVP_RGB2COLOR(r,g,b) ((((r)<<16) + ((g)<<8) + (b)) | 0xff000000)\n#define TVP_RGBA2COLOR(r,g,b,a) \\\n\t(((a)<<24) +  (((r)<<16) + ((g)<<8) + (b)))\n/*]*/\n\n#endif\n/* end of the file */\n"
  },
  {
    "path": "src/core/visual/tvpgl_asm_init.h",
    "content": "#pragma once\n#include \"cpu_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n    extern void TVPGL_ASM_Init();\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "src/core/visual/tvpgl_route.h",
    "content": " \n"
  },
  {
    "path": "src/core/visual/tvphal.h",
    "content": "#pragma once\n#include \"ComplexRect.h\"\n#include <string>\n\nstruct SDL_Renderer;\nstruct SDL_Window;\nstruct tTVPRect;\n\nstruct texRect\n{\n    int x, y, w, h;\n    texRect() : x(0), y(0), w(0), h(0) {}\n    texRect(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h) {}\n    texRect(const tTVPRect& rc);\n};\n\nextern unsigned int TVPMaxTextureSize;\n\nvoid TVPGLInitPrimaryRender(bool needShader);\n\nSDL_Renderer *TVPGLCreateRender(bool needShader = false);\n\nenum eTextureProgram\n{\n    texProgramNone = 0,\n\n    // operation with no texture\n    //texFillARGB,\n\n    // operation from one texture\n    //texFillMask,\n    //texFillColor,\n    //texCopy,\n    //texCopyOpaqueImage,\n    texDoGrayScale,\n\n    texAdditiveAlphaToAlpha,\n    //texAlphaToAdditiveAlpha,\n\n    //texRemoveConstOpacity,\n    //texConstColorAlphaBlend,\n    //texConstColorAlphaBlend_a,\n    texConstColorAlphaBlend_d,\n    texAdjustGamma,\n    texAdjustGamma_a,\n\n    // operation with two texture\n    //texCopyColor,\n    //texCopyMask,\n    texConstAlpha,\n    //texConstAlpha_a,\n    texConstAlpha_d,\n    texConstAlpha_SD_d,\n    texConstAlpha_SD_a,\n    //texAlphaBlend,\n    //texAlphaBlend_a,\n    //texAlphaBlend_d,\n    //texAddBlend,\n    //texSubBlend,\n    //texMulBlend,\n    //texAddAlpha,\n    //texAddAlpha_a,\n    //texApplyColorMap,\n    //texApplyColorMap_d,\n    //texApplyColorMap_a,\n    //texRemoveOpacity,\n    //texColorDodgeBlend,\n    texDarkenBlend,\n    texLightenBlend,\n    //texScreenBlend,\n    // ps series\n    //texPsAlphaBlend = texAlphaBlend,\n    //texPsAddBlend,\n    //texPsSubBlend,\n    //texPsMulBlend,\n    //texPsScreenBlend,\n    //texPsOverlayBlend,\n    texPsHardLightBlend,\n    texPsSoftLightBlend,\n    texPsColorDodgeBlend,\n    texPsColorDodge5Blend,\n    texPsColorBurnBlend,\n    texPsLightenBlend,\n    texPsDarkenBlend,\n    texPsDiffBlend,\n    texPsDiff5Blend,\n    texPsExclusionBlend,\n\n    // operation with rule\n    texUnivTransBlend,\n    texUnivTransBlend_d,\n    texUnivTransBlend_a,\n\n    texShaderUser,\n    texShaderCount\n};\n\nenum eVertShader {\n    eVertShaderNone,\n\teVertShader0Tex,\n\teVertShader1Tex,\n    eVertShader2Tex,\n    eVertShader3Tex,\n\n    eVertShaderCount\n};\nextern int TVPVertShaders[eVertShaderCount];\n\nenum eTextureFormat {\n    texNone = 0,\n    texGray = 1,\n    texRGB  = 3,\n    texRGBA = 4,\n};\n\nclass iTVPTexture\n{\npublic:\n    int RefCount;\n    int Flags, TexWidth, TexHeight, ActualWidth, ActualHeight;\n    iTVPTexture(unsigned int w, unsigned int h, unsigned int aw, unsigned int ah);\n    void AddRef();\n    virtual void Release() = 0;\n    //virtual tGLTexture* GetTexture() = 0;\n    virtual void Update(const void *pixel, eTextureFormat format, unsigned int pitch, int x, int y, int w, int h) = 0;\n    virtual unsigned long GetPoint(int x, int y) = 0;\n    virtual bool SetPoint(int x, int y, unsigned long clr) = 0;\n\tvirtual bool IsStatic() = 0;\n    //virtual void RefreshBitmap() = 0;\n};\n\ntypedef int tGLShader;\n\nstruct GLFunction\n{\nprivate:\n    GLFunction();\npublic:\n    static void Finish();\n\n    static void UseProgram(tGLShader shader);\n    static int GetUniformLocation(tGLShader prog, const char *name);\n    static int GetAttribLocation(tGLShader prog, const char *name);\n\n    static void Uniform1i(int location, int i);\n    static void Uniform2i(int location, int i1, int i2);\n    static void Uniform1f(int location, float f1);\n    static void Uniform2f(int location, float f1, float f2);\n    static void Uniform4f(int location, float f1, float f2, float f3, float f4);\n};\n\nclass iTVPShader\n{\npublic:\n    iTVPShader() {}\n    static bool CompileShader(tGLShader shader, const std::string &src);\n    static tGLShader CreateVertProgram(const std::string &vert_source);\n    static tGLShader CreateFragProgram(const std::string &frag_source);\n    static tGLShader CombineProgram(tGLShader vert_shader, tGLShader frag_shader);\n\npublic:\n    virtual void apply() const {}\n    virtual int getPosAttr() const { return -1; }\n    virtual int getTexCoordAttr(int idx) const {return -1;}\n};\n\n// with opacity and color\nclass tTVPStandardShader : public iTVPShader\n{\nprotected:\n    float opacity;\n\tunsigned long Color;\n    tGLShader program;\n\tint opa_uniform_location;\n\tint clr_uniform_location;\n    int pos_attr_location;\n    int tex0_coord_attr_location;\n    int tex1_coord_attr_location;\n    int tex2_coord_attr_location;\n    int BlendFunc, BlendSrcRGB, BlendDstRGB, BlendSrcA, BlendDstA;\n    bool IsEnableBlend, IsEnableBlendOpa;\n\n    void initDefaultData();\n\npublic:\n    tTVPStandardShader(tGLShader prog);\n    tTVPStandardShader(tGLShader vert_prog, tGLShader frag_prog);\n    tTVPStandardShader(tGLShader vert_prog, const std::string &frag_source);\n    virtual void apply() const;\n    virtual int getPosAttr() const;\n    virtual int getTexCoordAttr(int idx) const;\n\n    void init(int opa /*0~255*/, unsigned long clr);\n    void setBlendFuncSeparate(int func, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha);\n    void enableBlendColorAsOpa(bool bEnableBlendOpa = false);\n    bool isBlendEnabled();\n\npublic:\n    // preset shaders\n    static tTVPStandardShader* Copy;\n    static tTVPStandardShader* CopyOpaqueImage;\n\tstatic tTVPStandardShader* FillARGB;\n\tstatic tTVPStandardShader* FillMask;\n\tstatic tTVPStandardShader* FillColor;\n\tstatic tTVPStandardShader* RemoveConstOpacity;\n\tstatic tTVPStandardShader* AdditiveAlphaToAlpha;\n\tstatic tTVPStandardShader* AlphaToAdditiveAlpha;\n\n    static tTVPStandardShader* CopyColor;\n    static tTVPStandardShader* CopyMask;\n    //static tTVPStandardShader* ConstAlpha_SD_a;\n    //static tTVPStandardShader* ConstAlpha_SD_d;\n    static tTVPStandardShader* ConstAlpha;\n    static tTVPStandardShader* ConstAlpha_a;\n    static tTVPStandardShader* AlphaBlend;\n    static tTVPStandardShader* AlphaBlend_a;\n\tstatic tTVPStandardShader* AlphaBlend_d;\n\tstatic tTVPStandardShader* AddBlend;\n\tstatic tTVPStandardShader* SubBlend;\n\tstatic tTVPStandardShader* MulBlend;\n\tstatic tTVPStandardShader* AddAlpha;\n\tstatic tTVPStandardShader* AddAlpha_a;\n\tstatic tTVPStandardShader* ApplyColorMap;\n    static tTVPStandardShader* ApplyColorMap_a;\n\tstatic tTVPStandardShader* ApplyColorMap_d;\n\tstatic tTVPStandardShader* RemoveOpacity;\n\n\tstatic tTVPStandardShader* ColorDodgeBlend;\n\tstatic tTVPStandardShader* ScreenBlend;\n\n\tstatic tTVPStandardShader* PsAlphaBlend;\n\tstatic tTVPStandardShader* PsAddBlend;\n\tstatic tTVPStandardShader* PsSubBlend;\n\tstatic tTVPStandardShader* PsMulBlend;\n    static tTVPStandardShader* PsScreenBlend;\n    static tTVPStandardShader* PsOverlayBlend;\n    static tTVPStandardShader* ConstColorAlphaBlend;\n    static tTVPStandardShader* ConstColorAlphaBlend_a;\n};\n\n//void TVPTextureToBitmap(iTVPTexture2D* src, void *dst, unsigned int w, unsigned int h);\n\nstruct tTVPGLGammaAdjustData;\nvoid TVPTextureAdjustGamma(iTVPTexture* src, eTextureProgram method,\n    const texRect& rc, const tTVPGLGammaAdjustData& data);\n\nvoid TVPClearScreen();\nvoid TVPClearRect(const texRect& rc);\n\n//---------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/tvpinputdefs.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// input related definition\n//---------------------------------------------------------------------------\n\n\n#ifndef __TVPINPUTDEFS_H__\n#define __TVPINPUTDEFS_H__\n\n/*[*/\n//---------------------------------------------------------------------------\n// mouse button\n//---------------------------------------------------------------------------\nenum tTVPMouseButton\n{\n\tmbLeft,\n\tmbRight,\n\tmbMiddle,\n\tmbX1,\n\tmbX2\n};\n\n\n\n//---------------------------------------------------------------------------\n// IME modes : comes from VCL's TImeMode\n//---------------------------------------------------------------------------\nenum tTVPImeMode\n{\n\timDisable,\n\timClose,\n\timOpen,\n\timDontCare,\n\timSAlpha,\n\timAlpha,\n\timHira,\n\timSKata,\n\timKata,\n\timChinese,\n\timSHanguel,\n\timHanguel\n};\n\n\n//---------------------------------------------------------------------------\n// shift state\n//---------------------------------------------------------------------------\n#define TVP_SS_SHIFT   0x01\n#define TVP_SS_ALT     0x02\n#define TVP_SS_CTRL    0x04\n#define TVP_SS_LEFT    0x08\n#define TVP_SS_RIGHT   0x10\n#define TVP_SS_MIDDLE  0x20\n#define TVP_SS_DOUBLE  0x40\n#define TVP_SS_REPEAT  0x80\n\n\ninline bool TVPIsAnyMouseButtonPressedInShiftStateFlags(tjs_uint32 state)\n{ return (state & \n\t(TVP_SS_LEFT | TVP_SS_RIGHT | TVP_SS_MIDDLE | TVP_SS_DOUBLE)) != 0; }\n\n\n\n//---------------------------------------------------------------------------\n// JoyPad virtual key codes\n//---------------------------------------------------------------------------\n// These VKs are KIRIKIRI specific. Not widely used.\n#define VK_PAD_FIRST\t0x1B0   // first PAD related key code\n#define VK_PADLEFT\t\t0x1B5\n#define VK_PADUP\t\t0x1B6\n#define VK_PADRIGHT\t\t0x1B7\n#define VK_PADDOWN\t\t0x1B8\n#define VK_PAD1\t\t\t0x1C0\n#define VK_PAD2\t\t\t0x1C1\n#define VK_PAD3\t\t\t0x1C2\n#define VK_PAD4\t\t\t0x1C3\n#define VK_PAD5\t\t\t0x1C4\n#define VK_PAD6\t\t\t0x1C5\n#define VK_PAD7\t\t\t0x1C6\n#define VK_PAD8\t\t\t0x1C7\n#define VK_PAD9\t\t\t0x1C8\n#define VK_PAD10\t\t0x1C9\n#define VK_PADANY\t\t0x1DF   // returns whether any one of pad buttons are pressed,\n\t\t\t\t\t\t\t    // in System.getKeyState\n#define VK_PAD_LAST\t\t0x1DF   // last PAD related key code\n//---------------------------------------------------------------------------\n/*]*/\n//---------------------------------------------------------------------------\n\n#endif\n\n\n\n"
  },
  {
    "path": "src/core/visual/tvpps.inc",
    "content": "/*\n  Photoshop-like layer blender for KIRIKIRI (C-version)\n  (c)2004-2005 Kengo Takagi (Kenjo) <kenjo@ceres.dti.ne.jp>\n\n  Include file for function macro expansion (see also tvpps.c)\n*/\n\n/* ------------------------------ */\n#define OPERATION1 { TVPPS_REG tjs_uint32 s = *buf++, d = *dest, a = s>>24; TVPPS_OPERATION; *dest++ = s; }\nvoid __cdecl TVPPS_FUNC_NORM(tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len)\n{\n\tTVPPS_MAINLOOP\n}\n#undef OPERATION1\n/* ------------------------------ */\n#define OPERATION1 { TVPPS_REG tjs_uint32 s = *buf++, d = *dest, a = ((s>>24)*opa)>>8; TVPPS_OPERATION; *dest++ = s; }\nvoid __cdecl TVPPS_FUNC_O(tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len, tjs_int opa)\n{\n\tTVPPS_MAINLOOP\n}\n#undef OPERATION1\n/* ------------------------------ */\n#define OPERATION1 { TVPPS_REG tjs_uint32 s = *buf++, d = *dest, a = s>>24; TVPPS_OPERATION; *dest++ = s|(d&0xff000000); }\nvoid __cdecl TVPPS_FUNC_HDA(tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len)\n{\n\tTVPPS_MAINLOOP\n}\n#undef OPERATION1\n/* ------------------------------ */\n#define OPERATION1 { TVPPS_REG tjs_uint32 s = *buf++, d = *dest, a = ((s>>24)*opa)>>8; TVPPS_OPERATION; *dest++ = s|(d&0xff000000); }\nvoid __cdecl TVPPS_FUNC_HDA_O(tjs_uint32 *dest, const tjs_uint32 *buf, tjs_int len, tjs_int opa)\n{\n\tTVPPS_MAINLOOP\n}\n#undef OPERATION1\n\n#undef TVPPS_FUNC_NORM\n#undef TVPPS_FUNC_O\n#undef TVPPS_FUNC_HDA\n#undef TVPPS_FUNC_HDA_O\n#undef TVPPS_OPERATION\n"
  },
  {
    "path": "src/core/visual/voMode.h",
    "content": "/****************************************************************************/\n/*! @file\n@brief rfIĐ[h\n\n-----------------------------------------------------------------------------\n\tCopyright (C) 2004 T.Imoto\n-----------------------------------------------------------------------------\n@author\t\tT.Imoto\n@date\t\t2004/09/19\n@note\n\t\t\t2004/09/19\tT.Imoto\t\t\n*****************************************************************************/\n\n#ifndef __VOMODE_H__\n#define __VOMODE_H__\n\n/*[*/\n//---------------------------------------------------------------------------\n// tTVPVideoOverlayMode\n//---------------------------------------------------------------------------\nenum tTVPVideoOverlayMode {\n\tvomOverlay,\t\t// Overlay\n\tvomLayer,\t\t// Draw Layer\n\tvomMixer,\t\t// VMR\n\tvomMFEVR,\t\t// Media Foundation with EVR\n};\n\n\n\n\n/*]*/\n\n#endif\t// __VOMODE_H__\n"
  },
  {
    "path": "src/core/visual/win32/BasicDrawDevice.cpp",
    "content": "\n#define NOMINMAX\n#include \"tjsCommHead.h\"\n#include \"DrawDevice.h\"\n#include \"BasicDrawDevice.h\"\n#include \"LayerIntf.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"WindowIntf.h\"\n#include \"DebugIntf.h\"\n#include \"ThreadIntf.h\"\n#include \"ComplexRect.h\"\n#include \"EventImpl.h\"\n#include \"WindowImpl.h\"\n\n#define ZeroMemory(p,n) memset(p, 0, n);\n// #include <d3d9.h>\n// #include <mmsystem.h>\n#include <algorithm>\n\n//---------------------------------------------------------------------------\n// IvV\n//---------------------------------------------------------------------------\nstatic tjs_int TVPBasicDrawDeviceOptionsGeneration = 0;\nbool TVPZoomInterpolation = true;\n//---------------------------------------------------------------------------\nstatic void TVPInitBasicDrawDeviceOptions()\n{\n\tif(TVPBasicDrawDeviceOptionsGeneration == TVPGetCommandLineArgumentGeneration()) return;\n\tTVPBasicDrawDeviceOptionsGeneration = TVPGetCommandLineArgumentGeneration();\n\n\ttTJSVariant val;\n\tTVPZoomInterpolation = true;\n\tif(TVPGetCommandLine(TJS_W(\"-smoothzoom\"), &val))\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"no\"))\n\t\t\tTVPZoomInterpolation = false;\n\t\telse\n\t\t\tTVPZoomInterpolation = true;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\ntTVPBasicDrawDevice::tTVPBasicDrawDevice()\n{\n\tTVPInitBasicDrawDeviceOptions(); // read and initialize options\n\tTargetWindow = NULL;\n\tDrawUpdateRectangle = false;\n\tBackBufferDirty = true;\n\n\tDirect3D = NULL;\n\tDirect3DDevice = NULL;\n\tTexture = NULL;\n\tShouldShow = false;\n\tTextureBuffer = NULL;\n\tTextureWidth = TextureHeight = 0;\n\tVsyncInterval = 16;\n \tZeroMemory( &D3dPP, sizeof(D3dPP) );\n \tZeroMemory( &DispMode, sizeof(DispMode) );\n}\n//---------------------------------------------------------------------------\ntTVPBasicDrawDevice::~tTVPBasicDrawDevice()\n{\n\tDestroyD3DDevice();\n}\n#if 0\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::DestroyD3DDevice() {\n\tDestroyTexture();\n\tif(Direct3DDevice) Direct3DDevice->Release(), Direct3DDevice = NULL;\n\tif(Direct3D) Direct3D = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::DestroyTexture() {\n\tif(TextureBuffer && Texture) Texture->UnlockRect(0), TextureBuffer = NULL;\n\tif(Texture) Texture->Release(), Texture = NULL;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::InvalidateAll()\n{\n\t// CZʂׂăNGXg\n\t// T[tF[X lost ۂɓeč\\zړIŗp\n\tRequestInvalidation(tTVPRect(0, 0, DestRect.get_width(), DestRect.get_height()));\n}\n#if 0\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::CheckMonitorMoved() {\n\tUINT iCurrentMonitor = GetMonitorNumber( TargetWindow );\n\tif( CurrentMonitor != iCurrentMonitor ) {\n\t\t// j^ړĂ̂ŁAfoCXĐ\n\t\tCreateD3DDevice();\n\t}\n}\n//---------------------------------------------------------------------------\nbool tTVPBasicDrawDevice::IsTargetWindowActive() const {\n \tif( TargetWindow == NULL ) return false;\n \treturn ::GetForegroundWindow() == TargetWindow;\n}\n//---------------------------------------------------------------------------\nbool tTVPBasicDrawDevice::GetDirect3D9Device() {\n\tDestroyD3DDevice();\n\n\tTVPEnsureDirect3DObject();\n\n\tif( NULL == ( Direct3D = TVPGetDirect3DObjectNoAddRef() ) )\n\t\tTVPThrowExceptionMessage( TVPFaildToCreateDirect3D );\n\n\tHRESULT hr;\n\tif( FAILED( hr = DecideD3DPresentParameters() ) ) {\n\t\tif( IsTargetWindowActive() ) {\n\t\t\tErrorToLog( hr );\n\t\t\tTVPThrowExceptionMessage( TVPFaildToDecideBackbufferFormat );\n\t\t}\n\t\treturn false;\n\t}\n\n\tUINT iCurrentMonitor = GetMonitorNumber( TargetWindow );\n\tDWORD\tBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;\n\tif( D3D_OK != ( hr = Direct3D->CreateDevice( iCurrentMonitor, D3DDEVTYPE_HAL, TargetWindow, BehaviorFlags, &D3dPP, &Direct3DDevice ) ) ) {\n\t\tif( IsTargetWindowActive() ) {\n\t\t\tErrorToLog( hr );\n\t\t\tTVPThrowExceptionMessage( TVPFaildToCreateDirect3DDevice );\n\t\t}\n\t\treturn false;\n\t}\n\tCurrentMonitor = iCurrentMonitor;\n\tBackBufferDirty = true;\n\n\t/*\n\tD3DVIEWPORT9 vp;\n\tvp.X  = DestLeft;\n\tvp.Y  = DestTop;\n\tvp.Width = DestWidth != 0 ? DestWidth : D3dPP.BackBufferWidth;\n\tvp.Height = DestHeight != 0 ? DestHeight : D3dPP.BackBufferHeight;\n\t*/\n\t\n\tD3DVIEWPORT9 vp;\n\tvp.X  = 0;\n\tvp.Y  = 0;\n\tvp.Width = D3dPP.BackBufferWidth;\n\tvp.Height = D3dPP.BackBufferHeight;\n\tvp.MinZ  = 0.0f;\n\tvp.MaxZ  = 1.0f;\n\tif( FAILED(hr = Direct3DDevice->SetViewport(&vp)) ) {\n\t\tif( IsTargetWindowActive() ) {\n\t\t\tErrorToLog( hr );\n\t\t\tTVPThrowExceptionMessage( TVPFaildToSetViewport );\n\t\t}\n\t\treturn false;\n\t}\n\n\tif( FAILED( hr = InitializeDirect3DState() ) ) {\n\t\tif( IsTargetWindowActive() ) {\n\t\t\tErrorToLog( hr );\n \t\t\tTVPThrowExceptionMessage( TVPFaildToSetRenderState );\n\t\t}\n\t\treturn false;\n\t}\n\n\tint refreshrate = DispMode.RefreshRate;\n\tif( refreshrate == 0 ) {\n\t\tHDC hdc;\n\t\thdc = ::GetDC(TargetWindow);\n\t\trefreshrate = GetDeviceCaps( hdc, VREFRESH );\n\t\t::ReleaseDC( TargetWindow, hdc );\n\t}\n\tVsyncInterval = 1000 / refreshrate;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nHRESULT tTVPBasicDrawDevice::InitializeDirect3DState() {\n\tHRESULT\thr;\n\tD3DCAPS9\td3dcaps;\n\tif( FAILED( hr = Direct3DDevice->GetDeviceCaps( &d3dcaps ) ) )\n\t\treturn hr;\n\n\tif( d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR ) {\n\t\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, TVPZoomInterpolation?D3DTEXF_LINEAR:D3DTEXF_POINT ) ) )\n\t\t\treturn hr;\n\t} else {\n\t\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ) ) )\n\t\t\treturn hr;\n\t}\n\n\tif( d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR ) {\n\t\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, TVPZoomInterpolation?D3DTEXF_LINEAR:D3DTEXF_POINT ) ) )\n\t\t\treturn hr;\n\t} else {\n\t\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ) ) )\n\t\treturn hr;\n\t}\n\n\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU,  D3DTADDRESS_CLAMP ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV,  D3DTADDRESS_CLAMP ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ) ) )\n\t\treturn hr;\n\tif( FAILED( hr = Direct3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE ) ) )\n\t\treturn hr;\n\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nUINT tTVPBasicDrawDevice::GetMonitorNumber( HWND window )\n{\n\tif( Direct3D == NULL || window == NULL ) return D3DADAPTER_DEFAULT;\n\tHMONITOR windowMonitor = ::MonitorFromWindow( window, MONITOR_DEFAULTTOPRIMARY );\n\tUINT iCurrentMonitor = 0;\n\tUINT numOfMonitor = Direct3D->GetAdapterCount();\n\tfor( ; iCurrentMonitor < numOfMonitor; ++iCurrentMonitor ) \t{\n\t\tif( Direct3D->GetAdapterMonitor(iCurrentMonitor) == windowMonitor )\n\t\t\tbreak;\n\t}\n\tif( iCurrentMonitor == numOfMonitor )\n\t\tiCurrentMonitor = D3DADAPTER_DEFAULT;\n\treturn iCurrentMonitor;\n}\n//---------------------------------------------------------------------------\nHRESULT tTVPBasicDrawDevice::DecideD3DPresentParameters() {\n\tHRESULT\t\t\thr;\n\tUINT iCurrentMonitor = GetMonitorNumber(TargetWindow);\n\tif( FAILED( hr = Direct3D->GetAdapterDisplayMode( iCurrentMonitor, &DispMode ) ) )\n\t\treturn hr;\n\n\tZeroMemory( &D3dPP, sizeof(D3dPP) );\n\tD3dPP.Windowed = TRUE;\n\tD3dPP.SwapEffect = D3DSWAPEFFECT_COPY;\n\tD3dPP.BackBufferFormat = D3DFMT_UNKNOWN;\n\tD3dPP.BackBufferHeight = DispMode.Height > (tjs_uint)DestRect.get_height() ? DispMode.Height : (tjs_uint)DestRect.get_height();\n\tD3dPP.BackBufferWidth = DispMode.Width > (tjs_uint)DestRect.get_width() ? DispMode.Width : (tjs_uint)DestRect.get_width();\n\tD3dPP.hDeviceWindow = TargetWindow;\n\tD3dPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;\n\n\treturn S_OK;\n}\n//---------------------------------------------------------------------------\nbool tTVPBasicDrawDevice::CreateD3DDevice()\n{\n\t// Direct3D foCXAeNX`Ȃǂ쐬\n\tDestroyD3DDevice();\n\tif( TargetWindow ) {\n\t\ttjs_int w, h;\n\t\tGetSrcSize( w, h );\n\t\tif( w > 0 && h > 0 ) {\n\t\t\t// get Direct3D9 interface\n\t\t\tif( GetDirect3D9Device() ) {\n\t\t\t\treturn CreateTexture();\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n//---------------------------------------------------------------------------\nbool tTVPBasicDrawDevice::CreateTexture() {\n\tDestroyTexture();\n\ttjs_int w, h;\n\tGetSrcSize( w, h );\n\tif(TargetWindow && w > 0 && h > 0) {\n\t\tHRESULT hr = S_OK;\n\n\t\tD3DCAPS9 d3dcaps;\n\t\tDirect3DDevice->GetDeviceCaps( &d3dcaps );\n\n\t\tTextureWidth = w;\n\t\tTextureHeight = h;\n\t\tif( d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {\n\t\t\t// only square textures are supported\n\t\t\tTextureWidth = std::max(TextureHeight, TextureWidth);\n\t\t\tTextureHeight = TextureWidth;\n\t\t}\n\n\t\tDWORD dwWidth = 64;\n\t\tDWORD dwHeight = 64;\n\t\tif( d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2 ) {\n\t\t\t// 2̗ݏ̂݋邩ǂ\n\t\t\twhile( dwWidth < TextureWidth ) dwWidth = dwWidth << 1;\n\t\t\twhile( dwHeight < TextureHeight ) dwHeight = dwHeight << 1;\n\t\t\tTextureWidth = dwWidth;\n\t\t\tTextureHeight = dwHeight;\n\n\t\t\tif( dwWidth > d3dcaps.MaxTextureWidth || dwHeight > d3dcaps.MaxTextureHeight ) {\n\t\t\t\tTVPAddLog( (const tjs_char*)TVPWarningImageSizeTooLargeMayBeCannotCreateTexture );\n\t\t\t}\n\t\t\tTVPAddLog( (const tjs_char*)TVPUsePowerOfTwoSurface );\n\t\t} else {\n\t\t\tdwWidth = TextureWidth;\n\t\t\tdwHeight = TextureHeight;\n\t\t}\n\n\t\tif( D3D_OK != ( hr = Direct3DDevice->CreateTexture( dwWidth, dwHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &Texture, NULL) ) ) {\n\t\t\tif( IsTargetWindowActive() ) {\n\t\t\t\tErrorToLog( hr );\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotAllocateD3DOffScreenSurface,TJSInt32ToHex(hr, 8));\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::EnsureDevice()\n{\n\tTVPInitBasicDrawDeviceOptions();\n\tif( TargetWindow ) {\n\t\ttry {\n\t\t\tbool recreate = false;\n\t\t\tif( Direct3D == NULL || Direct3DDevice == NULL ) {\n\t\t\t\tif( GetDirect3D9Device() == false ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trecreate = true;\n\t\t\t}\n\t\t\tif( Texture == NULL ) {\n\t\t\t\tif( CreateTexture() == false ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trecreate = true;\n\t\t\t}\n\t\t\tif( recreate ) {\n\t\t\t\tInvalidateAll();\n\t\t\t}\n\t\t} catch(const eTJS & e) {\n\t\t\tTVPAddImportantLog( TVPFormatMessage(TVPBasicDrawDeviceFailedToCreateDirect3DDevice,e.GetMessage()) );\n\t\t\tDestroyD3DDevice();\n\t\t} catch(...) {\n\t\t\tTVPAddImportantLog( (const tjs_char*)TVPBasicDrawDeviceFailedToCreateDirect3DDeviceUnknownReason );\n\t\t\tDestroyD3DDevice();\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::TryRecreateWhenDeviceLost()\n{\n\tbool success = false;\n\tif( Direct3DDevice ) {\n\t\tDestroyTexture();\n\t\tHRESULT hr = Direct3DDevice->TestCooperativeLevel();\n\t\tif( hr == D3DERR_DEVICENOTRESET ) {\n\t\t\thr = Direct3DDevice->Reset(&D3dPP);\n\t\t}\n\t\tif( FAILED(hr) ) {\n\t\t\tsuccess = CreateD3DDevice();\n\t\t} else {\n\t\t\tif( D3D_OK == InitializeDirect3DState() ) {\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tsuccess = CreateD3DDevice();\n\t}\n\tif( success ) {\n\t\tInvalidateAll();\t// 摜̍ĕ`(Layer Update)v\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPBasicDrawDevice::ErrorToLog( HRESULT hr ) {\n\tswitch( hr ) {\n\tcase D3DERR_DEVICELOST:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDeviceLost );\n\t\tbreak;\n\tcase D3DERR_DRIVERINTERNALERROR:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDriverIinternalError );\n\t\tbreak;\n\tcase D3DERR_INVALIDCALL:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrInvalidCall );\n\t\tbreak;\n\tcase D3DERR_OUTOFVIDEOMEMORY:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrOutOfVideoMemory );\n\t\tbreak;\n\tcase E_OUTOFMEMORY:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrOutOfMemory );\n\t\tbreak;\n\tcase D3DERR_WRONGTEXTUREFORMAT:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrWrongTextureFormat );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDCOLOROPERATION:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsuportedColorOperation );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDCOLORARG:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsuportedColorArg );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDALPHAOPERATION:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsuportedAalphtOperation );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDALPHAARG:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsuportedAlphaArg );\n\t\tbreak;\n\tcase D3DERR_TOOMANYOPERATIONS:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrTooManyOperations );\n\t\tbreak;\n\tcase D3DERR_CONFLICTINGTEXTUREFILTER:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrConflictioningTextureFilter );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDFACTORVALUE:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsuportedFactorValue );\n\t\tbreak;\n\tcase D3DERR_CONFLICTINGRENDERSTATE:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrConflictioningRenderState );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDTEXTUREFILTER:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsupportedTextureFilter );\n\t\tbreak;\n\tcase D3DERR_CONFLICTINGTEXTUREPALETTE:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrConflictioningTexturePalette );\n\t\tbreak;\n\tcase D3DERR_NOTFOUND:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrNotFound );\n\t\tbreak;\n\tcase D3DERR_MOREDATA:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrMoreData );\n\t\tbreak;\n\tcase D3DERR_DEVICENOTRESET:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDeviceNotReset );\n\t\tbreak;\n\tcase D3DERR_NOTAVAILABLE:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrNotAvailable );\n\t\tbreak;\n\tcase D3DERR_INVALIDDEVICE:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrInvalidDevice );\n\t\tbreak;\n\tcase D3DERR_DRIVERINVALIDCALL:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDriverInvalidCall );\n\t\tbreak;\n\tcase D3DERR_WASSTILLDRAWING:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrWasStillDrawing );\n\t\tbreak;\n\tcase D3DERR_DEVICEHUNG:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDeviceHung );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDOVERLAY:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsupportedOverlay );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDOVERLAYFORMAT:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsupportedOverlayFormat );\n\t\tbreak;\n\tcase D3DERR_CANNOTPROTECTCONTENT:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrCannotProtectContent );\n\t\tbreak;\n\tcase D3DERR_UNSUPPORTEDCRYPTO:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrUnsupportedCrypto );\n\t\tbreak;\n\tcase D3DERR_PRESENT_STATISTICS_DISJOINT:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrPresentStatisticsDisJoint );\n\t\tbreak;\n\tcase D3DERR_DEVICEREMOVED:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDeviceRemoved );\n\t\tbreak;\n\tcase D3D_OK:\n\t\tbreak;\n\tcase D3DOK_NOAUTOGEN:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dOkNoAutoGen );\n\t\tbreak;\n\tcase E_FAIL:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrFail );\n\t\tbreak;\n\tcase E_INVALIDARG:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dErrInvalidArg );\n\t\tbreak;\n\tdefault:\n\t\tTVPAddLog( (const tjs_char*)TVPD3dUnknownError );\n\t\tbreak;\n\t}\n}\n#endif\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::AddLayerManager(iTVPLayerManager * manager)\n{\n\tif(inherited::Managers.size() > 0)\n\t{\n\t\t// \"Basic\" foCXł͂QȏLayer Managero^łȂ\n\t\tTVPThrowExceptionMessage(TVPBasicDrawDeviceDoesNotSupporteLayerManagerMoreThanOne);\n\t}\n\tinherited::AddLayerManager(manager);\n\n\tmanager->SetDesiredLayerType(ltOpaque); // ltOpaque ȏo͂󂯎肽\n}\n//---------------------------------------------------------------------------\n#if 0\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::SetTargetWindow(HWND wnd, bool is_main)\n{\n\tTVPInitBasicDrawDeviceOptions();\n\tDestroyD3DDevice();\n\tTargetWindow = wnd;\n\tIsMainWindow = is_main;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::SetDestRectangle(const tTVPRect & rect)\n{\n#if 0\n\tBackBufferDirty = true;\n\t// ʒu̕ύX̏ꍇǂ`FbN\n\tif(rect.get_width() == DestRect.get_width() && rect.get_height() == DestRect.get_height()) {\n\t\t// ʒu̕ύX\n\t\tinherited::SetDestRectangle(rect);\n\t} else {\n\t\t// TCYႤ\n\t\tif( rect.get_width() > (tjs_int)D3dPP.BackBufferWidth || rect.get_height() > (tjs_int)D3dPP.BackBufferHeight ) {\n\t\t\t// obNobt@TCY傫TCYw肳ꂽꍇxjBEnsureDeviceōĐB\n\t\t\tDestroyD3DDevice();\n\t\t}\n\t\tbool success = true;\n\t\tinherited::SetDestRectangle(rect);\n\n\t\ttry {\n\t\t\tEnsureDevice();\n\t\t} catch(const eTJS & e) {\n\t\t\tTVPAddImportantLog( TVPFormatMessage(TVPBasicDrawDeviceFailedToCreateDirect3DDevices,e.GetMessage() ) );\n\t\t\tsuccess = false;\n\t\t} catch(...) {\n\t\t\tTVPAddImportantLog( (const tjs_char*)TVPBasicDrawDeviceFailedToCreateDirect3DDevicesUnknownReason );\n\t\t\tsuccess = false;\n\t\t}\n\t\tif( success == false ) {\n\t\t\tDestroyD3DDevice();\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::NotifyLayerResize(iTVPLayerManager * manager)\n{\n\tinherited::NotifyLayerResize(manager);\n\n\tBackBufferDirty = true;\n\n\t// eNX`̂Ăč蒼B\n//\tCreateTexture();\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::Show()\n{\n\tif (Window) {\n\t\tiWindowLayer *form = Window->GetForm();\n\t\tif (form && !Managers.empty()) {\n\t\t\tiTVPBaseBitmap *buf = Managers.back()->GetDrawBuffer();\n\t\t\tif (buf);\n\t\t\t\tform->UpdateDrawBuffer(buf->GetTexture());\n\t\t}\n\t}\n#if 0\n\tif(!TargetWindow) return;\n\tif(!Texture) return;\n\tif(!Direct3DDevice) return;\n\tif(!ShouldShow) return;\n\n\tShouldShow = false;\n\n\tHRESULT hr = D3D_OK;\n\tRECT client;\n\tif( ::GetClientRect( TargetWindow, &client ) ) {\n\t\tRECT drect;\n\t\tdrect.left   = 0;\n\t\tdrect.top    = 0;\n\t\tdrect.right  = client.right - client.left;\n\t\tdrect.bottom = client.bottom - client.top;\n\n\t\tRECT srect = drect;\n\t\thr = Direct3DDevice->Present( &srect, &drect, TargetWindow, NULL );\n\t} else {\n\t\tShouldShow = true;\n\t}\n\n\tif(hr == D3DERR_DEVICELOST) {\n\t\tif( IsTargetWindowActive() ) ErrorToLog( hr );\n\t\tTryRecreateWhenDeviceLost();\n\t} else if(hr != D3D_OK) {\n\t\tErrorToLog( hr );\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPBasicDrawDeviceInfDirect3DDevicePresentFailed,TJSInt32ToHex(hr, 8)) );\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\n#if 0\nbool TJS_INTF_METHOD tTVPBasicDrawDevice::WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed )\n{\n\tif( Direct3DDevice == NULL ) return false;\n\n\tbool inVsync = false;\n\tD3DRASTER_STATUS rs;\n\tif( D3D_OK == Direct3DDevice->GetRasterStatus(0,&rs) ) {\n\t\tinVsync = rs.InVBlank == TRUE;\n\t}\n\n\t// VSync ҂s\n\tbool isdelayed = false;\n\tif(!inVsync) {\n\t\t// vblank 甲܂ő҂\n\t\tDWORD timeout_target_tick = ::timeGetTime() + 1;\n\t\trs.InVBlank = FALSE;\n\t\tHRESULT hr = D3D_OK;\n\t\tdo {\n\t\t\thr = Direct3DDevice->GetRasterStatus(0,&rs);\n\t\t} while( D3D_OK == hr && rs.InVBlank == TRUE && (long)(::timeGetTime() - timeout_target_tick) <= 0);\n\n\t\t// vblank ɓ܂ő҂\n\t\trs.InVBlank = TRUE;\n\t\tdo {\n\t\t\thr = Direct3DDevice->GetRasterStatus(0,&rs);\n\t\t} while( D3D_OK == hr && rs.InVBlank == FALSE && (long)(::timeGetTime() - timeout_target_tick) <= 0);\n\n\t\tif((int)(::timeGetTime() - timeout_target_tick) > 0) {\n\t\t\t// t[XLbvƍlĂ悢\n\t\t\tisdelayed  = true;\n\t\t}\n\t\tinVsync = rs.InVBlank == TRUE;\n\t}\n\t*delayed = isdelayed ? 1 : 0;\n\t*in_vblank = inVsync ? 1 : 0;\n\treturn true;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::StartBitmapCompletion(iTVPLayerManager * manager)\n{\n#if 0\n\tEnsureDevice();\n\n\tif( Texture && TargetWindow ) {\n\t\tif(TextureBuffer) {\n\t\t\tTVPAddImportantLog( (const tjs_char*)TVPBasicDrawDeviceTextureHasAlreadyBeenLocked );\n\t\t\tTexture->UnlockRect(0), TextureBuffer = NULL;\n\t\t}\n\n\t\tD3DLOCKED_RECT rt;\n\t\tHRESULT hr = Texture->LockRect( 0, &rt, NULL, D3DLOCK_NO_DIRTY_UPDATE );\n\n\t\tif(hr == D3DERR_INVALIDCALL && IsTargetWindowActive() ) {\n\t\t\tTVPThrowExceptionMessage( TVPInternalErrorResult, TJSInt32ToHex(hr, 8));\n\t\t}\n\n\t\tif(hr != D3D_OK) {\n\t\t\tErrorToLog( hr );\n\t\t\tTextureBuffer = NULL;\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else /*if(hr == DD_OK) */ {\n\t\t\tTextureBuffer = rt.pBits;\n\t\t\tTexturePitch = rt.Pitch;\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::NotifyBitmapCompleted(iTVPLayerManager * manager,\n\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity)\n{\n\t// bits, bitmapinfo ŕ\\rbg}bv cliprect ̗̈Ax, y ɕ`\n\t// B\n\t// opacity  type ͖邵Ȃ̂Ŗ\n\ttjs_int w, h;\n\tGetSrcSize( w, h );\n#if 0\n\tif( TextureBuffer && TargetWindow &&\n\t\t!(x < 0 || y < 0 ||\n\t\t\tx + cliprect.get_width() > w ||\n\t\t\ty + cliprect.get_height() > h) &&\n\t\t!(cliprect.left < 0 || cliprect.top < 0 ||\n\t\t\tcliprect.right > bitmapinfo->bmiHeader.biWidth ||\n\t\t\tcliprect.bottom > bitmapinfo->bmiHeader.biHeight))\n\t{\n\t\t// ͈͊O̓](ꕔ]̂ł͂Ȃ)Ă悢\n\t\tShouldShow = true;\n\n\t\t// bitmapinfo ŕ\\ꂽ cliprect ̗̈ x,y ɃRs[\n\t\tlong src_y       = cliprect.top;\n\t\tlong src_y_limit = cliprect.bottom;\n\t\tlong src_x       = cliprect.left;\n\t\tlong width_bytes   = cliprect.get_width() * 4; // 32bit\n\t\tlong dest_y      = y;\n\t\tlong dest_x      = x;\n\t\tconst tjs_uint8 * src_p = (const tjs_uint8 *)bits;\n\t\tlong src_pitch;\n\n\t\tif(bitmapinfo->bmiHeader.biHeight < 0)\n\t\t{\n\t\t\t// bottom-down\n\t\t\tsrc_pitch = bitmapinfo->bmiHeader.biWidth * 4;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// bottom-up\n\t\t\tsrc_pitch = -bitmapinfo->bmiHeader.biWidth * 4;\n\t\t\tsrc_p += bitmapinfo->bmiHeader.biWidth * 4 * (bitmapinfo->bmiHeader.biHeight - 1);\n\t\t}\n\n\t\tfor(; src_y < src_y_limit; src_y ++, dest_y ++)\n\t\t{\n\t\t\tconst void *srcp = src_p + src_pitch * src_y + src_x * 4;\n\t\t\tvoid *destp = (tjs_uint8*)TextureBuffer + TexturePitch * dest_y + dest_x * 4;\n\t\t\tmemcpy(destp, srcp, width_bytes);\n\t\t}\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::EndBitmapCompletion(iTVPLayerManager * manager)\n{\n\tif(!TargetWindow) return;\n#if 0\n\tif(!Texture) return;\n\tif(!Direct3DDevice) return;\n\n\tif(!TextureBuffer) return;\n\tTexture->UnlockRect(0);\n\tTextureBuffer = NULL;\n\n\n\t//- build vertex list\n\tstruct tVertices\n\t{\n\t\tfloat x, y, z, rhw;\n\t\tfloat tu, tv;\n\t};\n\n\t// ]NbsO`ɊÂNbsO\n\tfloat dl = (float)( DestRect.left < ClipRect.left ? ClipRect.left : DestRect.left );\n\tfloat dt = (float)( DestRect.top < ClipRect.top ? ClipRect.top : DestRect.top );\n\tfloat dr = (float)( DestRect.right > ClipRect.right ? ClipRect.right : DestRect.right );\n\tfloat db = (float)( DestRect.bottom > ClipRect.bottom ? ClipRect.bottom : DestRect.bottom );\n\tfloat dw = (float)DestRect.get_width();\n\tfloat dh = (float)DestRect.get_height();\n\n\t// ͂ݏoĂ镝߂\n\tfloat cl = dl - (float)DestRect.left;\n\tfloat ct = dt - (float)DestRect.top;\n\tfloat cr = (float)DestRect.right - dr;\n\tfloat cb = (float)DestRect.bottom - db;\n\n\t// ͂ݏoĂ镝lāA]摜NbsO\n\ttjs_int w, h;\n\tGetSrcSize( w, h );\n\tfloat sl = (float)(cl * w / dw ) / (float)TextureWidth;\n\tfloat st = (float)(ct * h / dh ) / (float)TextureHeight;\n\tfloat sr = (float)(w - (cr * w / dw) ) / (float)TextureWidth;\n\tfloat sb = (float)(h - (cb * h / dh) ) / (float)TextureHeight;\n\n\ttVertices vertices[] =\n\t{\n\t\t{dl - 0.5f, dt - 0.5f, 1.0f, 1.0f, sl, st },\n\t\t{dr - 0.5f, dt - 0.5f, 1.0f, 1.0f, sr, st },\n\t\t{dl - 0.5f, db - 0.5f, 1.0f, 1.0f, sl, sb },\n\t\t{dr - 0.5f, db - 0.5f, 1.0f, 1.0f, sr, sb }\n\t};\n\n\tHRESULT hr;\n\n// tXN[A1͑S̏Aȍ~̓EBhE͈͓݂̔̂ɂIB\n\tD3DVIEWPORT9 vp;\n\tvp.X  = 0;\n\tvp.Y  = 0;\n\tvp.Width = D3dPP.BackBufferWidth;\n\tvp.Height = D3dPP.BackBufferHeight;\n\tvp.MinZ  = 0.0f;\n\tvp.MaxZ  = 1.0f;\n\tDirect3DDevice->SetViewport(&vp);\n\n\tif( SUCCEEDED(Direct3DDevice->BeginScene()) ) {\n\t\tstruct CAutoEndSceneCall {\n\t\t\tIDirect3DDevice9*\tm_Device;\n\t\t\tCAutoEndSceneCall( IDirect3DDevice9* device ) : m_Device(device) {}\n\t\t\t~CAutoEndSceneCall() { m_Device->EndScene(); }\n\t\t} autoEnd(Direct3DDevice);\n\n\t\tif( BackBufferDirty ) {\n\t\t\tDirect3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0, 0 );\n\t\t\tBackBufferDirty = false;\n\t\t}\n\n\t\t//- draw as triangles\n\t\tif( FAILED(hr = Direct3DDevice->SetTexture(0, Texture)) )\n\t\t\tgoto got_error;\n\n\t\tif( FAILED( hr = Direct3DDevice->SetFVF( D3DFVF_XYZRHW|D3DFVF_TEX1 ) ) )\n\t\t\tgoto got_error;\n\n\t\tif( FAILED( hr = Direct3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(tVertices) ) ) )\n\t\t\tgoto got_error;\n\n\t\tif( FAILED( hr = Direct3DDevice->SetTexture( 0, NULL) ) )\n\t\t\tgoto got_error;\n\t}\n\ngot_error:\n\tif( hr == D3DERR_DEVICELOST ) {\n\t\tTryRecreateWhenDeviceLost();\n\t} else if(hr == D3DERR_DEVICENOTRESET ) {\n\t\thr = Direct3DDevice->Reset(&D3dPP);\n\t\tif( hr == D3DERR_DEVICELOST ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDeviceLost );\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else if( hr == D3DERR_DRIVERINTERNALERROR ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPD3dErrDriverIinternalError );\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else if( hr == D3DERR_INVALIDCALL ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPD3dErrInvalidCall );\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else if( hr  == D3DERR_OUTOFVIDEOMEMORY ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPD3dErrOutOfVideoMemory );\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else if( hr == E_OUTOFMEMORY  ) {\n\t\t\tTVPAddLog( (const tjs_char*)TVPD3dErrOutOfMemory );\n\t\t\tTryRecreateWhenDeviceLost();\n\t\t} else if( hr == D3D_OK ) {\n\t\t\tif( FAILED( hr = InitializeDirect3DState() ) ) {\n\t\t\t\tif( IsTargetWindowActive() ) {\n\t\t\t\t\tErrorToLog( hr );\n\t\t\t\t\tTVPThrowExceptionMessage( TVPFaildToSetRenderState );\n\t\t\t\t} else {\n\t\t\t\t\tDestroyD3DDevice();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if(hr != D3D_OK) {\n\t\tErrorToLog( hr );\n\t\tTVPAddImportantLog( TVPFormatMessage(TVPBasicDrawDeviceInfPolygonDrawingFailed,TJSInt32ToHex(hr, 8)) );\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::SetShowUpdateRect(bool b)\n{\n\tDrawUpdateRectangle = b;\n}\n#if 0\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPBasicDrawDevice::SwitchToFullScreen( HWND window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color, bool changeresolution )\n{\n\t// tXN[̏͂ȂɂsȂA݊̂߂ɃEBhESʉ݂̂ŏ\n\t// Direct3D9 ŃtXN[ƃtH[JXƃfoCXXĝŁÂтɃZbgor蒼KvɂȂB\n\t// [_EBhEgpVXeł́Â͍ŏɃEBhE[hōsB\n\t// [_EBhEgpȂVXeɂ̂ȂAtXN[gpDrawDeviceƗǂB\n\tBackBufferDirty = true;\n\tShouldShow = true;\n\tCheckMonitorMoved();\n\treturn true;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPBasicDrawDevice::RevertFromFullScreen( HWND window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color )\n{\n\tBackBufferDirty = true;\n\tShouldShow = true;\n\tCheckMonitorMoved();\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BasicDrawDevice : BasicDrawDevice TJS native class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_BasicDrawDevice::ClassID = (tjs_uint32)-1;\ntTJSNC_BasicDrawDevice::tTJSNC_BasicDrawDevice() :\n\ttTJSNativeClass(TJS_W(\"BasicDrawDevice\"))\n{\n\t// register native methods/properties\n\n\tTJS_BEGIN_NATIVE_MEMBERS(BasicDrawDevice)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n// constructor/methods\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_BasicDrawDevice,\n\t/*TJS class name*/BasicDrawDevice)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/BasicDrawDevice)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/recreate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BasicDrawDevice);\n#if 0\n\t_this->GetDevice()->SetToRecreateDrawer();\n\t_this->GetDevice()->EnsureDevice();\n#endif\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/recreate)\n//----------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n//----------------------------------------------------------------------\n// properties\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(interface)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BasicDrawDevice);\n\t\t*result = reinterpret_cast<tjs_int64>(_this->GetDevice());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(interface)\n//----------------------------------------------------------------------\n#define TVP_REGISTER_PTDD_ENUM(name) \\\n\tTJS_BEGIN_NATIVE_PROP_DECL(name) \\\n\t{ \\\n\t\tTJS_BEGIN_NATIVE_PROP_GETTER \\\n\t\t{ \\\n\t\t*result = (tjs_int64)tTVPBasicDrawDevice::name; \\\n\t\t\treturn TJS_S_OK; \\\n\t\t} \\\n\t\tTJS_END_NATIVE_PROP_GETTER \\\n\t\tTJS_DENY_NATIVE_PROP_SETTER \\\n\t} \\\n\tTJS_END_NATIVE_PROP_DECL(name)\n// compatible for old kirikiri2\nTVP_REGISTER_PTDD_ENUM(dtNone)\nTVP_REGISTER_PTDD_ENUM(dtDrawDib)\nTVP_REGISTER_PTDD_ENUM(dtDBGDI)\nTVP_REGISTER_PTDD_ENUM(dtDBDD)\nTVP_REGISTER_PTDD_ENUM(dtDBD3D)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(preferredDrawer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BasicDrawDevice);\n\t\t*result = (tjs_int64)(_this->GetDevice()->GetPreferredDrawerType());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BasicDrawDevice);\n\t\t_this->GetDevice()->SetPreferredDrawerType((tTVPBasicDrawDevice::tDrawerType)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(preferredDrawer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(drawer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_BasicDrawDevice);\n\t\t*result = (tjs_int64)(_this->GetDevice()->GetDrawerType());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(drawer)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\niTJSNativeInstance *tTJSNC_BasicDrawDevice::CreateNativeInstance()\n{\n\treturn new tTJSNI_BasicDrawDevice();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\ntTJSNI_BasicDrawDevice::tTJSNI_BasicDrawDevice()\n{\n\tDevice = new tTVPBasicDrawDevice();\n}\n//---------------------------------------------------------------------------\ntTJSNI_BasicDrawDevice::~tTJSNI_BasicDrawDevice()\n{\n\tif(Device) Device->Destruct(), Device = NULL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_BasicDrawDevice::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_BasicDrawDevice::Invalidate()\n{\n\tif(Device) Device->Destruct(), Device = NULL;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/win32/BasicDrawDevice.h",
    "content": "\n#ifndef BASIC_DRAW_DEVICE_H\n#define BASIC_DRAW_DEVICE_H\n\n#include \"DrawDevice.h\"\n//#include <d3d9.h>\n\n//---------------------------------------------------------------------------\n//! @brief\t\tuBasicvfoCX(Ƃ{Iȕ`ŝ݂̃foCX)\n//---------------------------------------------------------------------------\nclass tTVPBasicDrawDevice : public tTVPDrawDevice\n{\n\ttypedef tTVPDrawDevice inherited;\n\n\tvoid*TargetWindow;\n\tbool IsMainWindow;\n\tbool DrawUpdateRectangle;\n\tbool BackBufferDirty;\n\n\tvoid*\t\t\t\tDirect3D;\n\tvoid*\t\tDirect3DDevice;\n\tvoid*\t\tTexture;\n\tint\tD3dPP;\n\tint\t\t\tDispMode;\n\n//\tUINT\tCurrentMonitor;\n \tvoid*\tTextureBuffer; //!< eNX`̃T[tF[Xւ̃|C^\n// \tlong\tTexturePitch; //!< eNX`̃sb`\n\n\ttjs_uint TextureWidth; //!< eNX`̉\n\ttjs_uint TextureHeight; //!< eNX`̏c\n\n\tbool ShouldShow; //!< show Ŏۂɉʂɉ摜]ׂ\n\n\ttjs_uint VsyncInterval;\n\npublic:\n\ttTVPBasicDrawDevice(); //!< RXgN^\n\nprivate:\n\t~tTVPBasicDrawDevice(); //!< fXgN^\n\n\tvoid InvalidateAll();\n#if 0\n\tUINT GetMonitorNumber( HWND window );\n\n\tbool IsTargetWindowActive() const;\n\n\tbool GetDirect3D9Device();\n\tHRESULT InitializeDirect3DState();\n\tHRESULT DecideD3DPresentParameters();\n\n \tbool CreateD3DDevice();\n#endif\n\tvoid DestroyD3DDevice() {}\n\n// \tbool CreateTexture();\n// \tvoid DestroyTexture();\n\n\tvoid TryRecreateWhenDeviceLost();\n//\tvoid ErrorToLog( HRESULT hr );\n//\tvoid CheckMonitorMoved();\n\npublic:\n//\tvoid SetToRecreateDrawer() { DestroyD3DDevice(); }\n\tenum tDrawerType\n\t{\n\t\tdtNone, //!< drawer Ȃ\n\t\tdtDrawDib, //!< ƂPdrawer\n\t\tdtDBGDI, // GDI ɂ_uobt@Osdrawer\n\t\tdtDBDD, // DirectDraw ɂ_uobt@Osdrawer\n\t\tdtDBD3D // Direct3D ɂ_uobt@Osdrawer\n\t} DrawerType = dtDrawDib, PreferredDrawerType = dtDrawDib;\n\ttDrawerType GetDrawerType() const { return DrawerType; }\n\tvoid SetPreferredDrawerType(tDrawerType type) { PreferredDrawerType = type; }\n\ttDrawerType GetPreferredDrawerType() const { return PreferredDrawerType; }\n\npublic:\n//\tvoid EnsureDevice();\n\n//---- LayerManager ̊Ǘ֘A\n\tvirtual void TJS_INTF_METHOD AddLayerManager(iTVPLayerManager * manager);\n\n//---- `ʒuETCY֘A\n//\tvirtual void TJS_INTF_METHOD SetTargetWindow(HWND wnd, bool is_main);\n\tvirtual void TJS_INTF_METHOD SetDestRectangle(const tTVPRect & rect);\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(iTVPLayerManager * manager);\n\n//---- ĕ`֘A\n\tvirtual void TJS_INTF_METHOD Show();\n//\tvirtual bool TJS_INTF_METHOD WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed );\n\n//---- LayerManager ̉摜󂯓n֘A\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity);\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager);\n\n//---- fobOx\n\tvirtual void TJS_INTF_METHOD SetShowUpdateRect(bool b);\n#if 0\n//---- tXN[\n\tvirtual bool TJS_INTF_METHOD SwitchToFullScreen( HWND window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color, bool changeresolution );\n\tvirtual void TJS_INTF_METHOD RevertFromFullScreen( HWND window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color );\n#endif\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_BasicDrawDevice\n//---------------------------------------------------------------------------\nclass tTJSNI_BasicDrawDevice :\n\tpublic tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\n\ttTVPBasicDrawDevice * Device;\n\npublic:\n\ttTJSNI_BasicDrawDevice();\n\t~tTJSNI_BasicDrawDevice();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\ttTVPBasicDrawDevice * GetDevice() const { return Device; }\n\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_BasicDrawDevice\n//---------------------------------------------------------------------------\nclass tTJSNC_BasicDrawDevice : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_BasicDrawDevice();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\tiTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n\n\n#endif // BASIC_DRAW_DEVICE_H"
  },
  {
    "path": "src/core/visual/win32/BitmapBitsAlloc.cpp",
    "content": "#include \"tjsCommHead.h\"\n//---------------------------------------------------------------------------\n#include \"tjsUtils.h\"\n#include \"MsgIntf.h\"\n#include \"BitmapBitsAlloc.h\"\n#include \"SysInitIntf.h\"\n#include \"EventIntf.h\"\n#include \"DebugIntf.h\"\n\nclass BasicAllocator : public iTVPMemoryAllocator\n{\npublic:\n\tBasicAllocator() {\n\t\tTVPAddLog( TJS_W(\"(info) Use malloc for Bitmap\") );\n\t}\n\tvoid* allocate( size_t size ) { return malloc(size); }\n\tvoid free( void* mem ) { ::free( mem ); }\n};\n#if 0\nclass GlobalAllocAllocator : public iTVPMemoryAllocator\n{\npublic:\n\tGlobalAllocAllocator() {\n\t\tTVPAddLog( TJS_W(\"(info) Use GlobalAlloc allocater for Bitmap\") );\n\t}\n\tvoid* allocate( size_t size ) { return GlobalAlloc(GMEM_FIXED,size); }\n\tvoid free( void* mem ) { GlobalFree((HGLOBAL)mem ); }\n};\nclass HeapAllocAllocator : public iTVPMemoryAllocator\n{\n\tstatic const DWORD HeapFlag = 0;\n\n\tHANDLE HeapHandle;\npublic:\n\tHeapAllocAllocator() : HeapHandle(NULL) {\n\t\ttTJSVariant val;\n\t\ttjs_uint64 size = 0;\n\t\tif(TVPGetCommandLine(TJS_W(\"-bitmapheapsize\"), &val)) {\n\t\t\tttstr str(val);\n\t\t\tif(str == TJS_W(\"auto\")) {\n\t\t\t\tsize = 0;\n\t\t\t} else {\n\t\t\t\tsize = (tjs_int64)val;\n\t\t\t\tif( size == 0 ) {\n\t\t\t\t\tHeapHandle = ::HeapCreate( HeapFlag, 0, 0 );\n\t\t\t\t}\n\t\t\t\tsize *= 1024*1024;\n\t\t\t}\n\t\t}\n\t\tif( HeapHandle == NULL ) {\n\t\t\tif( size == 0 ) {\n\t\t\t\tMEMORYSTATUSEX status = { sizeof(MEMORYSTATUSEX) };\n\t\t\t\t::GlobalMemoryStatusEx(&status);\n\t\t\t\tsize = status.ullAvailVirtual;\n\t\t\t\tif( size > (512LL*1024*1024) ) {\n\t\t\t\t\tsize -= (128LL*1024*1024);\n\t\t\t\t} else {\n\t\t\t\t\tsize /= 2;\n\t\t\t\t}\n\t\t\t\tif( size > (512LL*1024*1024) ) {\n\t\t\t\t\tsize = (512LL*1024*1024); // 512MBɐ\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile( HeapHandle == NULL && size > (1024*1024) ) {\n\t\t\t\tHeapHandle = ::HeapCreate( HeapFlag, (SIZE_T)size, 0 );\n\t\t\t\tif( HeapHandle == NULL ) {\n\t\t\t\t\tif( size > (128LL*1024*1024) ) {\n\t\t\t\t\t\tsize -= (128LL*1024*1024);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsize /= 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} \n\t\t}\n\n\t\tif( HeapHandle ) {\n\t\t\tULONG HeapInformation = 2;\n\t\t\tBOOL lfhenable = ::HeapSetInformation( HeapHandle, HeapCompatibilityInformation, &HeapInformation, sizeof(HeapInformation) );\n\t\t}\n\t\tTVPAddLog( TJS_W(\"(info) Use separate heap allocater for Bitmap\") );\n\t}\n\tvirtual ~HeapAllocAllocator() {\n\t\tif( HeapHandle ) ::HeapDestroy(HeapHandle);\n\t\tHeapHandle = NULL;\n\t}\n\tvoid* allocate( size_t size ) {\n\t\tif( HeapHandle == NULL ) return NULL;\n\t\tvoid* result = ::HeapAlloc( HeapHandle, HeapFlag, size );\n\t\tif( result == NULL ) {\n\t\t\t::HeapCompact( HeapHandle, HeapFlag );\t// try compact\n\t\t\tresult = ::HeapAlloc( HeapHandle, HeapFlag, size ); // retry\n\t\t}\n\t\treturn result;\n\t}\n\tvoid free( void* mem ) {\n\t\tif( HeapHandle ) {\n\t\t\tBOOL ret = ::HeapFree( HeapHandle, HeapFlag, mem );\n\t\t\t::HeapCompact( HeapHandle, HeapFlag );\n\t\t}\n\t}\n};\n#endif\n\niTVPMemoryAllocator* tTVPBitmapBitsAlloc::Allocator = NULL;\ntTJSCriticalSection tTVPBitmapBitsAlloc::AllocCS;\n\nvoid tTVPBitmapBitsAlloc::InitializeAllocator() {\n\tif( Allocator == NULL ) {\n#if 0\n\t\ttTJSVariant val;\n\t\tif (TVPGetCommandLine(TJS_W(\"-bitmapallocator\"), &val)) {\n\t\t\tttstr str(val);\n\t\t\tif(str == TJS_W(\"globalalloc\"))\n\t\t\t\tAllocator = new GlobalAllocAllocator();\n\t\t\telse if(str == TJS_W(\"separateheap\"))\n\t\t\t\tAllocator = new HeapAllocAllocator();\n\t\t\telse    // malloc\n#endif\n\t\t\t\tAllocator = new BasicAllocator();\n#if 0\n\t\t} else {\n\t\t\tAllocator = new GlobalAllocAllocator();\n\t\t}\n#endif\n\t}\n}\nvoid tTVPBitmapBitsAlloc::FreeAllocator() {\n\tif( Allocator ) delete Allocator;\n\tAllocator = NULL;\n}\nstatic tTVPAtExit\n\tTVPUninitMessageLoad(TVP_ATEXIT_PRI_CLEANUP, tTVPBitmapBitsAlloc::FreeAllocator);\n\nvoid* tTVPBitmapBitsAlloc::Alloc( tjs_uint size, tjs_uint width, tjs_uint height ) {\n\tif(size == 0) return NULL;\n\ttTJSCriticalSectionHolder Lock(AllocCS);\t// Lock\n\n\tInitializeAllocator();\n\ttjs_uint8 * ptrorg, * ptr;\n\ttjs_uint allocbytes = 16 + size + sizeof(tTVPLayerBitmapMemoryRecord) + sizeof(tjs_uint32)*2;\n\n\tptr = ptrorg = (tjs_uint8*)Allocator->allocate(allocbytes);\n\tif(!ptr) TVPThrowExceptionMessage(TVPCannotAllocateBitmapBits,\n\t\tTJS_W(\"at TVPAllocBitmapBits\"), ttstr((tjs_int)allocbytes) + TJS_W(\"(\") +\n\t\t\tttstr((int)width) + TJS_W(\"x\") + ttstr((int)height) + TJS_W(\")\"));\n\t// align to a paragraph ( 16-bytes )\n\tptr += 16 + sizeof(tTVPLayerBitmapMemoryRecord);\n\t*reinterpret_cast<tTJSPointerSizedInteger*>(&ptr) >>= 4;\n\t*reinterpret_cast<tTJSPointerSizedInteger*>(&ptr) <<= 4;\n\n\ttTVPLayerBitmapMemoryRecord * record =\n\t\t(tTVPLayerBitmapMemoryRecord*)\n\t\t(ptr - sizeof(tTVPLayerBitmapMemoryRecord) - sizeof(tjs_uint32));\n\n\t// fill memory allocation record\n\trecord->alloc_ptr = (void *)ptrorg;\n\trecord->size = size;\n\trecord->sentinel_backup1 = rand() + (rand() << 16);\n\trecord->sentinel_backup2 = rand() + (rand() << 16);\n\n\t// set sentinel\n\t*(tjs_uint32*)(ptr - sizeof(tjs_uint32)) = ~record->sentinel_backup1;\n\t*(tjs_uint32*)(ptr + size              ) = ~record->sentinel_backup2;\n\t\t// Stored sentinels are nagated, to avoid that the sentinel backups in\n\t\t// tTVPLayerBitmapMemoryRecord becomes the same value as the sentinels.\n\t\t// This trick will make the detection of the memory corruption easier.\n\t\t// Because on some occasions, running memory writing will write the same\n\t\t// values at first sentinel and the tTVPLayerBitmapMemoryRecord.\n\n\t// return buffer pointer\n\treturn ptr;\n}\nvoid tTVPBitmapBitsAlloc::Free( void* ptr ) {\n\tif(ptr)\n\t{\n\t\ttTJSCriticalSectionHolder Lock(AllocCS);\t// Lock\n\n\t\t// get memory allocation record pointer\n\t\ttjs_uint8 *bptr = (tjs_uint8*)ptr;\n\t\ttTVPLayerBitmapMemoryRecord * record =\n\t\t\t(tTVPLayerBitmapMemoryRecord*)\n\t\t\t(bptr - sizeof(tTVPLayerBitmapMemoryRecord) - sizeof(tjs_uint32));\n\n\t\t// check sentinel\n\t\tif(~(*(tjs_uint32*)(bptr - sizeof(tjs_uint32))) != record->sentinel_backup1)\n\t\t\tTVPThrowExceptionMessage( TVPLayerBitmapBufferUnderrunDetectedCheckYourDrawingCode );\n\t\tif(~(*(tjs_uint32*)(bptr + record->size      )) != record->sentinel_backup2)\n\t\t\tTVPThrowExceptionMessage( TVPLayerBitmapBufferOverrunDetectedCheckYourDrawingCode );\n\n\t\tAllocator->free( record->alloc_ptr );\n\t}\n}\n\n"
  },
  {
    "path": "src/core/visual/win32/BitmapBitsAlloc.h",
    "content": "#ifndef __BITMAP_BITS_ALLOC_H__\n#define __BITMAP_BITS_ALLOC_H__\n#include <stdint.h>\n\n//---------------------------------------------------------------------------\n// memory allocation class\n//---------------------------------------------------------------------------\nclass iTVPMemoryAllocator {\npublic:\n\tvirtual ~iTVPMemoryAllocator() {};\n\tvirtual void* allocate( size_t size ) = 0;\n\tvirtual void free( void* mem ) = 0;\n};\n//---------------------------------------------------------------------------\n// heap allocation functions for bitmap bits\n//---------------------------------------------------------------------------\nclass tTVPBitmapBitsAlloc {\n\ttypedef intptr_t tTJSPointerSizedInteger;\n\t// this must be a integer type that has the same size with the normal\n\t// pointer ( void *)\n\t//---------------------------------------------------------------------------\n\t#pragma pack(push, 1)\n\tstruct tTVPLayerBitmapMemoryRecord\n\t{\n\t\tvoid * alloc_ptr; // allocated pointer\n\t\ttjs_uint size; // original bmp bits size, in bytes\n\t\ttjs_uint32 sentinel_backup1; // sentinel value 1\n\t\ttjs_uint32 sentinel_backup2; // sentinel value 2\n\t};\n\t#pragma pack(pop)\n\tstatic iTVPMemoryAllocator* Allocator;\n\tstatic tTJSCriticalSection AllocCS;\n\tstatic void InitializeAllocator();\n\npublic:\n\tstatic void FreeAllocator();\n\tstatic void* Alloc( tjs_uint size, tjs_uint width, tjs_uint height );\n\tstatic void Free( void* ptr );\n};\n\n#endif // __BITMAP_BITS_ALLOC_H__\n\n"
  },
  {
    "path": "src/core/visual/win32/BitmapInfomation.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n#include \"BitmapInfomation.h\"\n#include \"MsgIntf.h\"\n\nBitmapInfomation::BitmapInfomation( tjs_uint width, tjs_uint height, int bpp ) {\n\tBitmapInfoSize = sizeof(TVPBITMAPINFOHEADER) + ((bpp == 8) ? sizeof(TVPRGBQUAD) * 256 : 0);\n\tBitmapInfo = (TVPBITMAPINFO*)malloc(BitmapInfoSize);\n\tif(!BitmapInfo) TVPThrowExceptionMessage(TVPCannotAllocateBitmapBits,\n\t\tTJS_W(\"allocating BITMAPINFOHEADER\"), ttstr((tjs_int)BitmapInfoSize));\n\n\ttjs_int PitchBytes;\n\ttjs_uint bitmap_width = width;\n\t// note that the allocated bitmap size can be bigger than the\n\t// original size because the horizontal pitch of the bitmap\n\t// is aligned to a paragraph (16bytes)\n\tif( bpp == 8 ) {\n\t\tbitmap_width = (((bitmap_width-1) / 16)+1) *16; // align to a paragraph\n\t\tPitchBytes = (((bitmap_width-1) >> 2)+1) <<2;\n\t} else {\n\t\tbitmap_width = (((bitmap_width-1) / 4)+1) *4; // align to a paragraph\n\t\tPitchBytes = bitmap_width * 4;\n\t}\n\tBitmapInfo->bmiHeader.biSize = sizeof(BitmapInfo->bmiHeader);\n\tBitmapInfo->bmiHeader.biWidth = bitmap_width;\n\tBitmapInfo->bmiHeader.biHeight = height;\n\tBitmapInfo->bmiHeader.biPlanes = 1;\n\tBitmapInfo->bmiHeader.biBitCount = bpp;\n\tBitmapInfo->bmiHeader.biCompression = /*BI_RGB*/0;\n\tBitmapInfo->bmiHeader.biSizeImage = PitchBytes * height;\n\tBitmapInfo->bmiHeader.biXPelsPerMeter = 0;\n\tBitmapInfo->bmiHeader.biYPelsPerMeter = 0;\n\tBitmapInfo->bmiHeader.biClrUsed = 0;\n\tBitmapInfo->bmiHeader.biClrImportant = 0;\n\n\t// create grayscale palette\n\tif(bpp == 8) {\n\t\tTVPRGBQUAD *pal = (TVPRGBQUAD*)((tjs_uint8*)BitmapInfo + sizeof(TVPBITMAPINFOHEADER));\n\t\tfor( tjs_int i=0; i<256; i++ ) {\n\t\t\tpal[i].rgbBlue = pal[i].rgbGreen = pal[i].rgbRed = (tjs_uint8)i;\n\t\t\tpal[i].rgbReserved = 0;\n\t\t}\n\t}\n}\n\nBitmapInfomation::~BitmapInfomation() {\n\tfree(BitmapInfo);\n\tBitmapInfo = NULL;\n}\n\n"
  },
  {
    "path": "src/core/visual/win32/BitmapInfomation.h",
    "content": "\n\n#ifndef __BITMAP_INFOMATION_H__\n#define __BITMAP_INFOMATION_H__\n\nstruct TVPRGBQUAD {\n\tuint8_t    rgbBlue;\n\tuint8_t    rgbGreen;\n\tuint8_t    rgbRed;\n\tuint8_t    rgbReserved;\n};\n\nstruct TVPBITMAPINFOHEADER{\n\tuint32_t biSize;\n\tint32_t            biWidth;\n\tint32_t            biHeight;\n\tuint16_t  biPlanes;\n\tuint16_t  biBitCount;\n\tuint32_t   biCompression;\n\tuint32_t   biSizeImage;\n\tint32_t            biXPelsPerMeter;\n\tint32_t            biYPelsPerMeter;\n\tuint32_t   biClrUsed;\n\tuint32_t   biClrImportant;\n};\n\nstruct TVPBITMAPINFO {\n\tTVPBITMAPINFOHEADER    bmiHeader;\n\tTVPRGBQUAD             bmiColors[1];\n};\n\nclass BitmapInfomation {\n\tTVPBITMAPINFO* BitmapInfo;\n\ttjs_int BitmapInfoSize;\npublic:\n\tBitmapInfomation( tjs_uint width, tjs_uint height, int bpp );\n\t~BitmapInfomation();\n\n\tinline unsigned int GetBPP() const { return BitmapInfo->bmiHeader.biBitCount; }\n\tinline bool Is32bit() const { return GetBPP() == 32; }\n\tinline bool Is8bit() const { return GetBPP() == 8; }\n\tinline int GetWidth() const { return BitmapInfo->bmiHeader.biWidth; }\n\tinline int GetHeight() const { return BitmapInfo->bmiHeader.biHeight; }\n\tinline tjs_uint GetImageSize() const { return BitmapInfo->bmiHeader.biSizeImage; }\n\tinline int GetPitchBytes() const { return GetImageSize()/GetHeight(); }\n\tBitmapInfomation& operator=(BitmapInfomation& r) {\n\t\tmemcpy(BitmapInfo, r.BitmapInfo, BitmapInfoSize);\n\t\treturn *this;\n\t}\n\n\t// ȉAWin32 ݂̂̃\\bh\n\tTVPBITMAPINFO* GetBITMAPINFO() { return BitmapInfo; }\n\tconst TVPBITMAPINFO* GetBITMAPINFO() const { return BitmapInfo; }\n};\n\n#endif // __BITMAP_INFOMATION_H__\n\n"
  },
  {
    "path": "src/core/visual/win32/DInputMgn.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// DirectInput management\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n//#include \"WindowFormUnit.h\"\n#include \"WindowImpl.h\"\n#include \"EventIntf.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"SystemImpl.h\"\n#include \"tvpinputdefs.h\"\n#include \"DInputMgn.h\"\n\n#include \"DebugIntf.h\"\n#include \"Application.h\"\n#include \"TVPScreen.h\"\n#include \"TickCount.h\"\n\n//---------------------------------------------------------------------------\n// DirectInput management\n//---------------------------------------------------------------------------\n/*\n\ttvp32 uses DirectInput to detect wheel rotation. This will avoid\n\tDirectX/Windows bug which prevents wheel messages when the window is\n\tfull-screened.\n*/\ntTVPWheelDetectionType TVPWheelDetectionType = wdtWindowMessage/*wdtDirectInput*/;\ntTVPJoyPadDetectionType TVPJoyPadDetectionType = jdtNone/*jdtDirectInput*/;\nstatic bool TVPDirectInputInit = false;\nstatic tjs_int TVPDirectInputLibRefCount = 0;\n//static HMODULE TVPDirectInputLibHandle = NULL; // module handle for dinput.dll\n//static IDirectInput *TVPDirectInput = NULL; // DirectInput object\n//---------------------------------------------------------------------------\n#if 0\nstruct tTVPDIWheelData { LONG delta; }; // data structure for DirectInput(Mouse)\nstatic DIOBJECTDATAFORMAT TVPWheelDIODF[] =\n{ { &GUID_ZAxis, 0, DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 } };\nstatic DIDATAFORMAT TVPWheelDIDF =\n{\n\tsizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), DIDF_RELAXIS,\n\tsizeof(tTVPDIWheelData), 1, TVPWheelDIODF\n};\n#endif\n// Joystick (pad) related codes are contributed by Mr. Kiyobee @ TYPE-MOON.\n// Say thanks to him.\n\n//\tin http://www.mediawars.ne.jp/~freemage/progs/other03.htm\nconst static tjs_uint32 q = 0x80000000;\n#if 0\nstatic DIOBJECTDATAFORMAT _c_rgodf[ ] = {\n\t{ &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE, lX), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE, lY), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE, lZ), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE, lRx), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE, lRy), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE, lRz), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_Slider, FIELD_OFFSET(DIJOYSTATE, rglSlider[0]), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_Slider, FIELD_OFFSET(DIJOYSTATE, rglSlider[1]), q | DIDFT_AXIS | DIDFT_ANYINSTANCE, 256, },\n\t{ &GUID_POV, FIELD_OFFSET(DIJOYSTATE, rgdwPOV[0]), q | DIDFT_POV | DIDFT_ANYINSTANCE, 0, },\n\t{ &GUID_POV, FIELD_OFFSET(DIJOYSTATE, rgdwPOV[1]), q | DIDFT_POV | DIDFT_ANYINSTANCE, 0, },\n\t{ &GUID_POV, FIELD_OFFSET(DIJOYSTATE, rgdwPOV[2]), q | DIDFT_POV | DIDFT_ANYINSTANCE, 0, },\n\t{ &GUID_POV, FIELD_OFFSET(DIJOYSTATE, rgdwPOV[3]), q | DIDFT_POV | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[0]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[1]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[2]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[3]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[4]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[5]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[6]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[7]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[8]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[9]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[10]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[11]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[12]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[13]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[14]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[15]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[16]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[17]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[18]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[19]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[20]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[21]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[22]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[23]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[24]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[25]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[26]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[27]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[28]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[29]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[30]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n\t{ 0, FIELD_OFFSET(DIJOYSTATE, rgbButtons[31]), q | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, },\n};\n#define numObjects (sizeof(_c_rgodf) / sizeof(_c_rgodf[0]))\nstatic DIDATAFORMAT c_dfPad =\n{\n\tsizeof(DIDATAFORMAT),\t\t//\tstructure size   \\̃TCY\n\tsizeof(DIOBJECTDATAFORMAT),\t//\tsize of object data format IuWFNgf[^`̃TCY\n\tDIDF_ABSAXIS,\t\t\t\t//\tabsolute axis system ΎWn\n\tsizeof(DIJOYSTATE),\t\t\t//\tsize of device data foCXf[^̃TCY\n\tnumObjects, \t\t\t\t//\tcount of objects IuWFNg\n\t_c_rgodf,\t\t\t\t\t//\tposition ʒu\n};\n#endif\nstatic const tjs_int   PadAxisMax = +32767;\nstatic const tjs_int   PadAxisMin = -32768;\nstatic const tjs_int   PadAxisThreshold   = 95; // Assumes 95% value can turn input on. 95%̓͂OK\nstatic const tjs_int   PadAxisUpperThreshold  = PadAxisMax * PadAxisThreshold / 100;\nstatic const tjs_int   PadAxisLowerThreshold  = PadAxisMin * PadAxisThreshold / 100;\n//static bool CALLBACK EnumJoySticksCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);\nstatic tjs_uint32\tPadLastTrigger;\nstatic tjs_uint32 /*__fastcall*/ PadState();\n\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// pad virtual key code map\n//---------------------------------------------------------------------------\nconst int TVPPadVirtualKeyMap[TVP_NUM_PAD_KEY] = // tTVPPadKeyFlag to VK\n{\n\tVK_PADLEFT,\n\tVK_PADRIGHT,\n\tVK_PADUP,\n\tVK_PADDOWN,\n\tVK_PAD1,\n\tVK_PAD2,\n\tVK_PAD3,\n\tVK_PAD4,\n\tVK_PAD5,\n\tVK_PAD6,\n\tVK_PAD7,\n\tVK_PAD8,\n\tVK_PAD9,\n\tVK_PAD10,\n};\n//---------------------------------------------------------------------------\nstatic tTVPPadKeyFlag TVPVirtualKeyToPadCode(WORD vk)\n{\n\t// VK to tTVPPadKeyFlag\n\tswitch(vk)\n\t{\n\tcase VK_PADLEFT:\t\treturn pkfLeft;\n\tcase VK_PADRIGHT:\t\treturn pkfRight;\n\tcase VK_PADUP:\t\t\treturn pkfUp;\n\tcase VK_PADDOWN:\t\treturn pkfDown;\n\tcase VK_PAD1:\t\t\treturn pkfButton0;\n\tcase VK_PAD2:\t\t\treturn pkfButton1;\n\tcase VK_PAD3:\t\t\treturn pkfButton2;\n\tcase VK_PAD4:\t\t\treturn pkfButton3;\n\tcase VK_PAD5:\t\t\treturn pkfButton4;\n\tcase VK_PAD6:\t\t\treturn pkfButton5;\n\tcase VK_PAD7:\t\t\treturn pkfButton6;\n\tcase VK_PAD8:\t\t\treturn pkfButton7;\n\tcase VK_PAD9:\t\t\treturn pkfButton8;\n\tcase VK_PAD10:\t\t\treturn pkfButton9;\n\t}\n\treturn (tTVPPadKeyFlag)-1;\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// tTVPKeyRepeatEmulator : A class for emulating keyboard key repeats.\n//---------------------------------------------------------------------------\ntjs_int32 tTVPKeyRepeatEmulator::HoldTime = 500; // keyboard key-repeats hold-time\ntjs_int32 tTVPKeyRepeatEmulator::IntervalTime = 30; // keyboard key-repeats interval-time\n//---------------------------------------------------------------------------\nvoid tTVPKeyRepeatEmulator::GetKeyRepeatParam()\n{\n\tstatic tjs_int ArgumentGeneration = 0;\n\tif(ArgumentGeneration != TVPGetCommandLineArgumentGeneration())\n\t{\n\t\tArgumentGeneration = TVPGetCommandLineArgumentGeneration();\n\t\ttTJSVariant val;\n\t\tif(TVPGetCommandLine(TJS_W(\"-paddelay\"), &val))\n\t\t{\n\t\t\tHoldTime = (int)val;\n\t\t}\n\t\tif(TVPGetCommandLine(TJS_W(\"-padinterval\"), &val))\n\t\t{\n\t\t\tIntervalTime = (int)val;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n#define TVP_REPEAT_LIMIT 10\ntTVPKeyRepeatEmulator::tTVPKeyRepeatEmulator() : Pressed(false)\n{\n}\n//---------------------------------------------------------------------------\ntTVPKeyRepeatEmulator::~tTVPKeyRepeatEmulator()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTVPKeyRepeatEmulator::Down()\n{\n\tPressed = true;\n\tPressedTick = TVPGetRoughTickCount32();\n\tLastRepeatCount = 0;\n}\n//---------------------------------------------------------------------------\nvoid tTVPKeyRepeatEmulator::Up()\n{\n\tPressed = false;\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPKeyRepeatEmulator::GetRepeatCount()\n{\n\t// calculate repeat count, from previous call of \"GetRepeatCount\" function.\n\tGetKeyRepeatParam();\n\n\tif(!Pressed) return 0;\n\tif(HoldTime<0) return 0;\n\tif(IntervalTime<=0) return 0;\n\n\ttjs_int elapsed = (tjs_int)(TVPGetRoughTickCount32() - PressedTick);\n\n\telapsed -= HoldTime;\n\tif(elapsed < 0) return 0; // still in hold time\n\n\telapsed /= IntervalTime;\n\n\ttjs_int ret = elapsed - LastRepeatCount;\n\tif(ret > TVP_REPEAT_LIMIT) ret = TVP_REPEAT_LIMIT;\n\n\tLastRepeatCount = elapsed;\n\n\treturn ret;\n}\n//---------------------------------------------------------------------------\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// DirectInput management\n//---------------------------------------------------------------------------\nIDirectInput * TVPAddRefDirectInput()\n{\n\t// addref DirectInput.\n\tTVPDirectInputLibRefCount ++;\n\tif(TVPDirectInputInit)\n\t{\n\t\t// DirectInput is not to be loaded more than once\n\t\t// even if the loading is failed.\n\t\treturn TVPDirectInput;\n\t}\n\n\tTVPDirectInputInit = true;\n\n\tTVPDirectInputLibHandle = ::LoadLibrary(TJS_W(\"dinput.dll\"));\n\tif(!TVPDirectInputLibHandle) return NULL; // load error; is not a fatal error\n\n\tHRESULT (WINAPI *procDirectInputCreateW)\n\t\t(HINSTANCE hinst, DWORD dwVersion,\n\t\t\tLPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter);\n\n\tprocDirectInputCreateW =\n\t\t(HRESULT (WINAPI *)(HINSTANCE, DWORD, LPDIRECTINPUTW*, LPUNKNOWN))\n\t\tGetProcAddress(TVPDirectInputLibHandle, \"DirectInputCreateA\");\n\tif(!procDirectInputCreateW)\n\t{\n\t\t// missing DirectInputCreate\n\t\t::FreeLibrary(TVPDirectInputLibHandle);\n\t\tTVPDirectInputLibHandle = NULL;\n\t\treturn NULL;\n\t}\n\n\tHRESULT hr = procDirectInputCreateW(GetHInstance(), DIRECTINPUT_VERSION,\n\t\t&TVPDirectInput, NULL);\n\tif(FAILED(hr))\n\t{\n\t\t// DirectInputCreate failed\n\t\tFreeLibrary(TVPDirectInputLibHandle);\n\t\tTVPDirectInputLibHandle = NULL;\n\t\treturn NULL;\n\t}\n\n\treturn TVPDirectInput;\n}\n//---------------------------------------------------------------------------\nvoid TVPReleaseDirectInput()\n{\n\tTVPDirectInputLibRefCount--;\n\tif(TVPDirectInputLibRefCount == 0)\n\t{\n\t\tif(TVPDirectInput)\n\t\t\tTVPDirectInput->Release(), TVPDirectInput = NULL;\n\t\tif(TVPDirectInputLibHandle)\n\t\t\tFreeLibrary(TVPDirectInputLibHandle), TVPDirectInputLibHandle = NULL;\n\t\tTVPDirectInputInit = false;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPDirectInputDevice : A base class for managing DirectInput device\n//---------------------------------------------------------------------------\ntTVPDirectInputDevice::tTVPDirectInputDevice()\n{\n\tTVPAddRefDirectInput();\n\tDevice = NULL;\n}\n//---------------------------------------------------------------------------\ntTVPDirectInputDevice::~tTVPDirectInputDevice()\n{\n\tif(Device)\n\t{\n\t\tDevice->Unacquire();\n\t\tDevice->Release();\n\t}\n\tTVPReleaseDirectInput();\n}\n//---------------------------------------------------------------------------\nvoid tTVPDirectInputDevice::SetCooperativeLevel(HWND window)\n{\n\tif(Device)\n\t{\n\t\tif(FAILED(Device->SetCooperativeLevel(\n\t\t\twindow, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND)))\n\t\t{\n\t\t\tDevice->Release();\n\t\t\tDevice = NULL;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPWheelDirectInputDevice : DirectInput device manager for mouse wheel\n//---------------------------------------------------------------------------\ntTVPWheelDirectInputDevice::tTVPWheelDirectInputDevice(HWND window) :\n\ttTVPDirectInputDevice()\n{\n\tif(TVPDirectInput)\n\t{\n\t\tif(TVPWheelDetectionType == wdtDirectInput)\n\t\t{\n\t\t\t// initialize mouse wheel\n\t\t\tIDirectInputDevice *dev = NULL;\n\t\t\tHRESULT hr = TVPDirectInput->CreateDevice(\n\t\t\t\tGUID_SysMouse, &dev, NULL);\n\t\t\tif(SUCCEEDED(hr) && dev)\n\t\t\t{\n\t\t\t\thr\t= dev->QueryInterface(\n\t\t\t\t\tIID_IDirectInputDevice2, (LPVOID*)&Device);\n\t\t\t\tdev->Release();\n\t\t\t\tif(FAILED(hr)) Device = NULL;\n\t\t\t}\n\t\t\tif(SUCCEEDED(hr) && Device)\n\t\t\t{\n\t\t\t\tif(FAILED(Device->SetDataFormat(&TVPWheelDIDF)))\n\t\t\t\t{\n\t\t\t\t\tDevice->Release();\n\t\t\t\t\tDevice = NULL;\n\t\t\t\t}\n\t\t\t\tif(Device) SetCooperativeLevel(window);\n\t\t\t\tif(Device) Device->Acquire();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDevice = NULL;\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPWheelDirectInputDevice::~tTVPWheelDirectInputDevice()\n{\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPWheelDirectInputDevice::GetWheelDelta()\n{\n\tif(!Device) return 0;\n\n\ttTVPDIWheelData wd;\n\tZeroMemory(&wd, sizeof(wd));\n\tHRESULT hr = Device->GetDeviceState(sizeof(wd), &wd);\n\tif(FAILED(hr))\n\t{\n\t\tDWORD tick = GetTickCount();\n\t\tdo\n\t\t{\n\t\t\thr = Device->Acquire();\n\t\t} while(hr == DIERR_INPUTLOST && (GetTickCount() - tick) < 20);\n\t\t\t// has 20ms timeout\n\n\t\tif(!FAILED(hr))\n\t\t{\n\t\t\tHRESULT hr = Device->GetDeviceState(sizeof(wd), &wd);\n\t\t\tif(FAILED(hr)) return 0;\n\t\t}\n\t}\n\n\treturn (tjs_int)wd.delta;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPPadDirectInputDevice : DirectInput device manager for JoyPad\n//---------------------------------------------------------------------------\nstd::vector<tTVPPadDirectInputDevice*>  *\n\ttTVPPadDirectInputDevice::PadDevices = NULL;\ntjs_uint32 tTVPPadDirectInputDevice::GlobalPadPushedFlag = 0;\n//---------------------------------------------------------------------------\ntTVPPadDirectInputDevice::tTVPPadDirectInputDevice(HWND window) :\n\ttTVPDirectInputDevice()\n{\n\tLastPadState = 0;\n\tLastPushedTrigger = 0;\n\tKeyUpdateMask = 0;\n\n\tif(TVPDirectInput)\n\t{\n\t\tif(TVPJoyPadDetectionType == jdtDirectInput)\n\t\t{\n\t\t\t// initialize joy pad\n\t\t\t// enumerate JoyStick devices. need DIRECTINPUT_VERSION 0x0500 or higher.\n\t\t\tHRESULT hr;\n\t\t\thr = TVPDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK,\n\t\t\t\t(LPDIENUMDEVICESCALLBACK)EnumJoySticksCallback,\n\t\t\t\t&Device, DIEDFL_ATTACHEDONLY);\n\t\t\tif(FAILED(hr) || Device==NULL)\n\t\t\t{\n\t\t\t\tDevice\t= NULL;\n\t\t\t}\n\n\t\t\t//\tinitialize joy stick device.\n\t\t\tif(Device)\n\t\t\t{\n\t\t\t\tif(FAILED(Device->SetDataFormat(&c_dfPad)))\n\t\t\t\t{\n\t\t\t\t\tDevice->Release();\n\t\t\t\t\tDevice = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(Device) SetCooperativeLevel(window);\n\t\t\tif(Device)\n\t\t\t{\n\t\t\t\tDIPROPRANGE\trange;\n\t\t\t\tDIPROPDWORD\tpw;\n\t\t\t\tZeroMemory(&range, sizeof(range));\n\t\t\t\tZeroMemory(&pw, sizeof(pw));\n\t\t\t\trange.diph.dwSize\t\t= sizeof(DIPROPRANGE);\n\t\t\t\tpw.diph.dwSize\t\t\t= sizeof(DIPROPDWORD);\n\t\t\t\trange.diph.dwHeaderSize\t= pw.diph.dwHeaderSize\t= sizeof(DIPROPHEADER);\n\t\t\t\trange.diph.dwHow\t\t= pw.diph.dwHow\t\t\t= DIPH_BYOFFSET;\n\t\t\t\trange.lMin\t\t\t\t= PadAxisMin;\n\t\t\t\trange.lMax\t\t\t\t= PadAxisMax;\n\t\t\t\tpw.dwData\t\t\t\t= 5000;\t\t//\tupper 50 percent\n\t\t\t\trange.diph.dwObj\t= pw.diph.dwObj\t= DIJOFS_X;\t\t//\tX Axis\n\t\t\t\thr = Device->SetProperty(DIPROP_RANGE, &range.diph);\n\t\t\t\thr |=Device->SetProperty(DIPROP_DEADZONE, &pw.diph);\n\t\t\t\trange.diph.dwObj\t= pw.diph.dwObj\t= DIJOFS_Y;\t\t//\tY Axis\n\t\t\t\thr |=Device->SetProperty(DIPROP_RANGE, &range.diph);\n\t\t\t\thr |=Device->SetProperty(DIPROP_DEADZONE, &pw.diph);\n\t\t\t\tif(FAILED(hr))\n\t\t\t\t{\n\t\t\t\t\tDevice->Release();\n\t\t\t\t\tDevice = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(Device) Device->Acquire();\n\n\t\t\t// for polling state\n\t\t\tLastPadState       = 0;\n\t\t}\n\t}\n\n\t// register self to PadDevices\n\tif(!PadDevices)\n\t\tPadDevices = new std::vector<tTVPPadDirectInputDevice*>();\n\tPadDevices->push_back(this);\n}\n//---------------------------------------------------------------------------\ntTVPPadDirectInputDevice::~tTVPPadDirectInputDevice()\n{\n\t// unregister from PadDevices\n\tstd::vector<tTVPPadDirectInputDevice*>::iterator i;\n\ti = std::find(PadDevices->begin(), PadDevices->end(), this);\n\tif(i != PadDevices->end()) PadDevices->erase(i);\n\tif(PadDevices->size() == 0) delete PadDevices, PadDevices = NULL;\n}\n//---------------------------------------------------------------------------\nbool CALLBACK tTVPPadDirectInputDevice::EnumJoySticksCallback(\n\tLPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)\n{\n\tHRESULT\thr;\n\tIDirectInputDevice*\tdev;\n\n\t//\tjoy stick detect first is created.\n\thr\t= TVPDirectInput->CreateDevice(lpddi->guidInstance,\n\t\t(IDirectInputDevice**)&dev, NULL);\n\n\tif(FAILED(hr)) return DIENUM_CONTINUE;\n\n\t//\texpanse DirectInputDevice to DirectInputDevice2\n\thr\t= dev->QueryInterface(IID_IDirectInputDevice2, (LPVOID*)pvRef);\n\tdev->Release();\n\tif(FAILED(hr)) return DIENUM_CONTINUE;\n\n\treturn DIENUM_STOP;\n}\n//---------------------------------------------------------------------------\nvoid tTVPPadDirectInputDevice::Update(tjs_uint32 newstate)\n{\n\tUppedKeys.clear();\n\tDownedKeys.clear();\n\tRepeatKeys.clear();\n\n\ttjs_uint32 downed = newstate & ~LastPadState; // newly pressed buttons\n\ttjs_uint32 upped  = ~newstate & LastPadState; // newly released buttons\n\n\tGlobalPadPushedFlag |= downed;\n\n\n\t// emulate key repeats.\n\t// key repeats are calculated about two groups independently.\n\t// one is cross-keys(up, down, left, right) and the other is\n\t// trigger buttons(button0 .. button9).\n\tconst tjs_uint32 cross_group_mask =\n\t\t((1<<pkfLeft)|(1<<pkfRight)|(1<<pkfUp)|(1<<pkfDown));\n\tconst tjs_uint32 trigger_group_mask = ~cross_group_mask;\n\n\tif(!(LastPadState & cross_group_mask) && (newstate & cross_group_mask))\n\t\tCrossKeysRepeater.Down(); // any pressed\n\tif(!(newstate     & cross_group_mask))\n\t\tCrossKeysRepeater.Up(); // all released\n\n\tif     (downed & trigger_group_mask) TriggerKeysRepeater.Down();\n\telse if(upped  & trigger_group_mask) TriggerKeysRepeater.Up();\n\n\tif(downed & trigger_group_mask) LastPushedTrigger = downed & trigger_group_mask;\n\n\t// scan downed buttons\n\tfor(tjs_int i = 0; i < TVP_NUM_PAD_KEY; i++)\n\t\tif((1<<i) & downed) DownedKeys.push_back(TVPPadVirtualKeyMap[i]);\n\t// scan upped buttons\n\tfor(tjs_int i = 0; i < TVP_NUM_PAD_KEY; i++)\n\t\tif((1<<i) & upped)  UppedKeys.push_back(TVPPadVirtualKeyMap[i]);\n\t// scan cross group repeats\n\ttjs_int cnt;\n\tcnt = CrossKeysRepeater.GetRepeatCount();\n\tif(cnt)\n\t{\n\t\ttjs_uint32 t = newstate & cross_group_mask;\n\t\tdo\n\t\t{\n\t\t\tfor(tjs_int i = 0; i < TVP_NUM_PAD_KEY; i++)\n\t\t\t\tif((1<<i) & t) RepeatKeys.push_back(TVPPadVirtualKeyMap[i]);\n\t\t} while(--cnt);\n\t}\n\n\t// scan trigger group repeats\n\tcnt = TriggerKeysRepeater.GetRepeatCount();\n\tif(cnt)\n\t{\n\t\ttjs_uint32 t = LastPushedTrigger;\n\t\tdo\n\t\t{\n\t\t\tfor(tjs_int i = 0; i < TVP_NUM_PAD_KEY; i++)\n\t\t\t{\n\t\t\t\tif((1<<i) & t)\n\t\t\t\t{\n\t\t\t\t\tRepeatKeys.push_back(TVPPadVirtualKeyMap[i]);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while(--cnt);\n\t}\n\n\t// update last state\n\tLastPadState = newstate;\n}\n//---------------------------------------------------------------------------\nvoid tTVPPadDirectInputDevice::UpdateWithCurrentState()\n{\n\t// called every 50ms intervally\n\ttjs_uint32 state = GetState();\n\tKeyUpdateMask |= ~state;\n\tUpdate(state & KeyUpdateMask);\n}\n//---------------------------------------------------------------------------\nvoid tTVPPadDirectInputDevice::UpdateWithSuspendedState()\n{\n\t// called when the window is inactive\n\tKeyUpdateMask = 0;\n\tUpdate(0);\n}\n//---------------------------------------------------------------------------\nvoid tTVPPadDirectInputDevice::WindowActivated()\n{\n\t// dummy read to obtain stable pad status ... nasty.\n\n\tGetState();\n\tGetState();\n\tGetState();\n}\n//---------------------------------------------------------------------------\nvoid tTVPPadDirectInputDevice::WindowDeactivated()\n{\n\tKeyUpdateMask = 0;\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTVPPadDirectInputDevice::GetState()\n{\n\tif(!Device)\treturn 0;\n\n\t// polling\n\tif(FAILED(Device->Poll()))\n\t{\n\t\t//  for lost.\n\t\tDevice->Acquire();\n\t\treturn 0;\n\t}\n\n\tDIJOYSTATE\tjs;\n\tZeroMemory(&js, sizeof(js));\n\tHRESULT\thr = Device->GetDeviceState(sizeof(js), &js);\n\tif(FAILED(hr))\n\t{\n\t\tDWORD tick = GetTickCount();\n\t\tdo\n\t\t{\n\t\t\thr = Device->Acquire();\n\t\t} while(hr == DIERR_INPUTLOST && (GetTickCount() - tick) < 20);\n\t\t\t// has 20ms timeout\n\n\t\tif(!FAILED(hr))\n\t\t{\n\t\t\tHRESULT hr = Device->GetDeviceState(sizeof(js), &js);\n\t\t\tif(FAILED(hr)) return 0;\n\t\t}\n\t}\n\n\t//\tstructure DIJOYSTATE => unsigned integer JoyState\n\ttjs_uint32\tpress\t= 0;\n#define JOY_CROSSKEY(value, plus, minus)\t((value)>=PadAxisUpperThreshold ? \\\n\t\t\t(plus) : ((value)<=PadAxisLowerThreshold ? (minus) : 0))\n#define\tJOY_BUTTON(value, on)\t\t\t\t((value&0x80) ? (on) : 0)\n\tpress\t|= JOY_CROSSKEY(js.lX, (1<<pkfRight), (1<<pkfLeft));\n\tpress\t|= JOY_CROSSKEY(js.lY, (1<<pkfDown), (1<<pkfUp));\n/*#ifdef _DEBUG\n\tif(js.lX!=0 || js.lY!=0)\n\t{\n\t\tTVPAddLog(TJS_W(\"JoyStick: lX = \")+ttstr((int)js.lX)+TJS_W(\", lY = \")+ttstr((int)js.lY));\n\t}\n#endif\n*/\n\tpress\t|= JOY_BUTTON(js.rgbButtons[0], 1<<pkfButton0);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[1], 1<<pkfButton1);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[2], 1<<pkfButton2);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[3], 1<<pkfButton3);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[4], 1<<pkfButton4);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[5], 1<<pkfButton5);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[6], 1<<pkfButton6);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[7], 1<<pkfButton7);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[8], 1<<pkfButton8);\n\tpress\t|= JOY_BUTTON(js.rgbButtons[9], 1<<pkfButton9);\n#undef JOY_BUTTON\n#undef JOY_CROSSKEY\n\n\treturn press;\n}\n//---------------------------------------------------------------------------\ntjs_uint32 tTVPPadDirectInputDevice::GetGlobalPadState()\n{\n\tif(!PadDevices) return 0;\n\tstd::vector<tTVPPadDirectInputDevice*>::iterator i;\n\ttjs_uint32 state = 0;\n\tfor(i = PadDevices->begin(); i != PadDevices->end(); i++)\n\t\tstate |= (*i)->LastPadState;\n\treturn state;\n}\n//---------------------------------------------------------------------------\nbool tTVPPadDirectInputDevice::GetAsyncState(tjs_uint keycode, bool getcurrent)\n{\n\t// This emulates System.getKeyState\n\ttjs_uint32 bit;\n\tif(keycode != VK_PADANY)\n\t{\n\t\ttTVPPadKeyFlag flag = TVPVirtualKeyToPadCode(keycode);\n\t\tif(flag == (tTVPPadKeyFlag)-1) return false;\n\n\t\tbit = (1<<flag);\n\t}\n\telse\n\t{\n\t\t// returns whether any pad buttons are pressed\n\t\tbit = -1;\n\t}\n\n\tif(getcurrent)\n\t{\n\t\treturn 0!=(GetGlobalPadState() & bit);\n\t}\n\telse\n\t{\n\t\tbool ret = 0!=(GlobalPadPushedFlag  & bit);\n\t\tGlobalPadPushedFlag &= ~bit;\n\t\treturn ret;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\nstatic void TVPUninitDirectInput()\n{\n\t// release all devices\n\tApplication->FreeDirectInputDeviceForWindows();\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit\n\tTVPUninitDirectInputAtExit(TVP_ATEXIT_PRI_RELEASE, TVPUninitDirectInput);\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Utility functionss\n//---------------------------------------------------------------------------\nbool TVPGetJoyPadAsyncState(tjs_uint keycode, bool getcurrent)\n{\n\treturn tTVPPadDirectInputDevice::GetAsyncState(keycode, getcurrent);\n}\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/DInputMgn.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// DirectInput management\n//---------------------------------------------------------------------------\n\n\n#ifndef __DINPUTMGN_H__\n#define __DINPUTMGN_H__\n\n#define DIRECTINPUT_VERSION 0x0500\n//#include <dinput.h>\n#ifndef CALLBACK\n#define CALLBACK\ntypedef const void  *LPCDIDEVICEINSTANCE;\n#endif\n\n#include <vector>\n\n//---------------------------------------------------------------------------\n// Enumerations/constants\n//---------------------------------------------------------------------------\nenum tTVPWheelDetectionType { wdtNone, wdtDirectInput, wdtWindowMessage };\nenum tTVPJoyPadDetectionType { jdtNone, jdtDirectInput };\nenum tTVPPadKeyFlag {\n\tpkfLeft,\n\tpkfRight,\n\tpkfUp,\n\tpkfDown,\n//\tpkfButton,\n\tpkfButton0,\n\tpkfButton1,\n\tpkfButton2,\n\tpkfButton3,\n\tpkfButton4,\n\tpkfButton5,\n\tpkfButton6,\n\tpkfButton7,\n\tpkfButton8,\n\tpkfButton9,\n};\n#define TVP_NUM_PAD_KEY (4 + 10)\n\t\t// count of supported pad buttions (including cross keys)\nextern const int TVPPadVirtualKeyMap[TVP_NUM_PAD_KEY];\nextern tTVPWheelDetectionType TVPWheelDetectionType; // = wdtDirectInput;\nextern tTVPJoyPadDetectionType TVPJoyPadDetectionType; // = jdtDirectInput;\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPKeyRepeatEmulator : A class for emulating keyboard key repeats.\n//---------------------------------------------------------------------------\nclass tTVPKeyRepeatEmulator\n{\n\ttjs_uint32 PressedTick;\n\tbool  Pressed;\n\ttjs_int LastRepeatCount;\n\n\tstatic tjs_int HoldTime; // keyboard key-repeats hold-time\n\tstatic tjs_int IntervalTime; // keyboard key-repeats interval-time\n\n\n\t/*\n\t\t          hold time           repeat interval time\n\t\t   <------------------------> <--->\n\t\t   +------------------------+ +-+ +-+ +-+\n\t\t___|                        |_| |_| |_| |____\n\t\t   <------------------------------------->\n\t\t   key pressed                           key released\n\t\t-----------------------------------------------------------> time\n\n\t*/\n\n\tstatic void GetKeyRepeatParam();\n\npublic:\n\ttTVPKeyRepeatEmulator();\n\t~tTVPKeyRepeatEmulator();\n\n\tvoid Down();\n\tvoid Up();\n\n\ttjs_int GetRepeatCount();\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPDirectInputDevice : A base class for managing DirectInput device\n//---------------------------------------------------------------------------\nstruct IDirectInputDevice2;\nclass tTVPDirectInputDevice\n{\nprotected:\n\tIDirectInputDevice2 * Device;\n\npublic:\n\ttTVPDirectInputDevice();\n\n\tvirtual ~tTVPDirectInputDevice();\n\n\tvoid SetCooperativeLevel(int window);\n\t\t// set cooperatice level to the Device.\n\t\t// This may be called from the constructor\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPWheelDirectInputDevice : DirectInput device manager for mouse wheel\n//---------------------------------------------------------------------------\nclass tTVPWheelDirectInputDevice : public tTVPDirectInputDevice\n{\npublic:\n\ttTVPWheelDirectInputDevice(int window);\n\t~tTVPWheelDirectInputDevice();\n\n\ttjs_int GetWheelDelta();\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTVPPadDirectInputDevice : DirectInput device manager for JoyPad\n//---------------------------------------------------------------------------\nclass tTVPPadDirectInputDevice : public tTVPDirectInputDevice\n{\n\ttjs_uint32 LastPadState;\n\ttjs_uint32 LastPushedTrigger;\n\n\ttjs_uint32 KeyUpdateMask;\n\n\ttTVPKeyRepeatEmulator CrossKeysRepeater;\n\ttTVPKeyRepeatEmulator TriggerKeysRepeater;\n\n\tstd::vector<tjs_uint16> UppedKeys;\n\tstd::vector<tjs_uint16> DownedKeys;\n\tstd::vector<tjs_uint16> RepeatKeys;\n\npublic:\n\ttTVPPadDirectInputDevice(int window);\n\t~tTVPPadDirectInputDevice();\n\nprivate:\n\tstatic bool CALLBACK EnumJoySticksCallback(\n\t\tLPCDIDEVICEINSTANCE lpddi, void* pvRef);\n\nprivate:\n\tvoid Update(tjs_uint32 newstate);\n\npublic:\n\tvoid UpdateWithCurrentState();\n\tvoid UpdateWithSuspendedState();\n\n\tvoid WindowActivated();\n\tvoid WindowDeactivated();\n\n\tconst std::vector<tjs_uint16>& GetUppedKeys() const { return UppedKeys; }\n\tconst std::vector<tjs_uint16>& GetDownedKeys() const { return DownedKeys; }\n\tconst std::vector<tjs_uint16>& GetRepeatKeys() const { return RepeatKeys; }\n\nprivate:\n\ttjs_uint32 GetState();\n\nprivate:\n\tstatic std::vector<tTVPPadDirectInputDevice*> * PadDevices;\n    static tjs_uint32 GlobalPadPushedFlag;\n\npublic:\n\tstatic tjs_uint32 GetGlobalPadState();\n\t\t// returns global (not on Window context) JoyPad State.\n\n\tstatic bool GetAsyncState(tjs_uint keycode, bool getcurrent);\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Utility functionss\n//---------------------------------------------------------------------------\nbool TVPGetJoyPadAsyncState(tjs_uint keycode, bool getcurrent);\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/DrawDevice.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//!@file 描画デバイス管理\n//---------------------------------------------------------------------------\n\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"DrawDevice.h\"\n#include \"MsgIntf.h\"\n#include \"LayerIntf.h\"\n#include \"LayerManager.h\"\n#include \"WindowIntf.h\"\n#include \"DebugIntf.h\"\n\n//---------------------------------------------------------------------------\ntTVPDrawDevice::tTVPDrawDevice()\n{\n\t// コンストラクタ\n\tWindow = NULL;\n\tPrimaryLayerManagerIndex = 0;\n\tDestRect.clear();\n\tClipRect.clear();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTVPDrawDevice::~tTVPDrawDevice()\n{\n\t// すべての managers を開放する\n\t//TODO: プライマリレイヤ無効化、あるいはウィンドウ破棄時の終了処理が正しいか？\n\t// managers は 開放される際、自身の登録解除を行うために\n\t// RemoveLayerManager() を呼ぶかもしれないので注意。\n\t// そのため、ここではいったん配列をコピーしてからそれぞれの\n\t// Release() を呼ぶ。\n\tstd::vector<iTVPLayerManager *> backup = Managers;\n\tfor(std::vector<iTVPLayerManager *>::iterator i = backup.begin(); i != backup.end(); i++)\n\t\t(*i)->Release();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nbool tTVPDrawDevice::TransformToPrimaryLayerManager(tjs_int &x, tjs_int &y)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\treturn true;\n\n\t// プライマリレイヤマネージャのプライマリレイヤのサイズを得る\n\ttjs_int pl_w = LockedWidth, pl_h = LockedHeight;\n\tif(pl_w <= 0 && pl_h <= 0 && !manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n    //pl_w = WinWidth; pl_h = WinHeight;\n\n\t// x , y は DestRect の 0, 0 を原点とした座標として渡されてきている\n\ttjs_int w = DestRect.get_width();\n\ttjs_int h = DestRect.get_height();\n\tx = w ? ((x - DestRect.left) * pl_w / w) : 0;\n\ty = h ? ((y - DestRect.top) * pl_h / h) : 0;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nbool tTVPDrawDevice::TransformFromPrimaryLayerManager(tjs_int &x, tjs_int &y)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\treturn true;\n\n\t// プライマリレイヤマネージャのプライマリレイヤのサイズを得る\n\ttjs_int pl_w = LockedWidth, pl_h = LockedHeight;\n\tif (pl_w <= 0 && pl_h <= 0 && !manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n    //pl_w = WinWidth; pl_h = WinHeight;\n\n\t// x , y は DestRect の 0, 0 を原点とした座標として渡されてきている\n\tx = pl_w ? (x * DestRect.get_width()  / pl_w) : 0;\n\ty = pl_h ? (y * DestRect.get_height() / pl_h) : 0;\n    x += DestRect.left;\n    y += DestRect.top;\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nbool tTVPDrawDevice::TransformToPrimaryLayerManager(tjs_real &x, tjs_real &y)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return false;\n\n\t// プライマリレイヤマネージャのプライマリレイヤのサイズを得る\n\ttjs_int pl_w, pl_h;\n\tif(!manager->GetPrimaryLayerSize(pl_w, pl_h)) return false;\n\n\t// x , y は DestRect の 0, 0 を原点とした座標として渡されてきている\n\ttjs_int w = DestRect.get_width();\n\ttjs_int h = DestRect.get_height();\n\tx = w ? (x * pl_w / w) : 0.0;\n\ty = h ? (y * pl_h / h) : 0.0;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::Destruct()\n{\n\tdelete this;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetWindowInterface(iTVPWindow * window)\n{\n\tWindow = window;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::AddLayerManager(iTVPLayerManager * manager)\n{\n\t// Managers に manager を push する。AddRefするのを忘れないこと。\n\tManagers.push_back(manager);\n\tmanager->AddRef();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::RemoveLayerManager(iTVPLayerManager * manager)\n{\n\t// Managers から manager を削除する。Releaseする。\n\tstd::vector<iTVPLayerManager *>::iterator i = std::find(Managers.begin(), Managers.end(), manager);\n\tif(i == Managers.end())\n\t\tTVPThrowInternalError;\n\t(*i)->Release();\n\tManagers.erase(i);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetDestRectangle(const tTVPRect & rect)\n{\n\tDestRect = rect;\n}\n//---------------------------------------------------------------------------\n\n\nvoid tTVPDrawDevice::SetLockedSize(tjs_int w, tjs_int h)\n{\n\tLockedWidth = w; LockedHeight = h;\n}\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetClipRectangle(const tTVPRect & rect)\n{\n\tClipRect = rect;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::GetSrcSize(tjs_int &w, tjs_int &h)\n{\n\tw = LockedWidth;\n\th = LockedHeight;\n\tif (w > 0 && h > 0) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tif(!manager->GetPrimaryLayerSize(w, h))\n\t{\n\t\tw = 0;\n\t\th = 0;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::NotifyLayerResize(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(primary_manager == manager)\n\t\tWindow->NotifySrcResize();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::NotifyLayerImageChange(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(primary_manager == manager)\n\t\tWindow->RequestUpdate();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnClick(tjs_int x, tjs_int y)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyClick(x, y);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnDoubleClick(tjs_int x, tjs_int y)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyDoubleClick(x, y);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMouseDown(x, y, mb, flags);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMouseUp(x, y, mb, flags);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMouseMove(x, y, flags);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnReleaseCapture()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->ReleaseCapture();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMouseOutOfWindow()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMouseOutOfWindow();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnKeyDown(tjs_uint key, tjs_uint32 shift)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyKeyDown(key, shift);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnKeyUp(tjs_uint key, tjs_uint32 shift)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyKeyUp(key, shift);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnKeyPress(tjs_char key)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyKeyPress(key);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y)\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMouseWheel(shift, delta, x, y);\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyTouchDown(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyTouchUp(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\tif(!TransformToPrimaryLayerManager(x, y)) return;\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyTouchMove(x, y, cx, cy, id);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyTouchScaling(startdist, curdist, cx, cy, flag);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag )\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyTouchRotate(startangle, curangle, dist, cx, cy, flag);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnMultiTouch()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->NotifyMultiTouch();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::OnDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int width, tjs_int height )\n{\n\t// 何もしない\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::RecheckInputState()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\n\tmanager->RecheckInputState();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetDefaultMouseCursor(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->SetDefaultMouseCursor();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetMouseCursor(iTVPLayerManager * manager, tjs_int cursor)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->SetMouseCursor(cursor);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::GetCursorPos(iTVPLayerManager * manager, tjs_int &x, tjs_int &y)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tWindow->GetCursorPos(x, y);\n\tif(primary_manager != manager || !TransformToPrimaryLayerManager(x, y))\n\t{\n\t\t// プライマリレイヤマネージャ以外には座標 0,0 で渡しておく\n\t\t x = 0;\n\t\t y = 0;\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetCursorPos(iTVPLayerManager * manager, tjs_int x, tjs_int y)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tif(TransformFromPrimaryLayerManager(x, y))\n\t\t\tWindow->SetCursorPos(x, y);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::WindowReleaseCapture(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->WindowReleaseCapture();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetHintText(iTVPLayerManager * manager, iTJSDispatch2* sender, const ttstr & text)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->SetHintText(sender,text);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetAttentionPoint(iTVPLayerManager * manager, tTJSNI_BaseLayer *layer,\n\t\t\t\ttjs_int l, tjs_int t)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tif(TransformFromPrimaryLayerManager(l, t))\n\t\t\tWindow->SetAttentionPoint(layer, l, t);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::DisableAttentionPoint(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->DisableAttentionPoint();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetImeMode(iTVPLayerManager * manager, tTVPImeMode mode)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->SetImeMode(mode);\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::ResetImeMode(iTVPLayerManager * manager)\n{\n\tiTVPLayerManager * primary_manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!primary_manager) return;\n\tif(primary_manager == manager)\n\t{\n\t\tWindow->ResetImeMode();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * TJS_INTF_METHOD tTVPDrawDevice::GetPrimaryLayer()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return NULL;\n\treturn manager->GetPrimaryLayer();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTJSNI_BaseLayer * TJS_INTF_METHOD tTVPDrawDevice::GetFocusedLayer()\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return NULL;\n\treturn manager->GetFocusedLayer();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetFocusedLayer(tTJSNI_BaseLayer * layer)\n{\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->SetFocusedLayer(layer);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::RequestInvalidation(const tTVPRect & rect)\n{\n\ttjs_int l = rect.left, t = rect.top, r = rect.right, b = rect.bottom;\n\tif(!TransformToPrimaryLayerManager(l, t)) return;\n\tif(!TransformToPrimaryLayerManager(r, b)) return;\n\tr ++; // 誤差の吸収(本当はもうちょっと厳密にやらないとならないがそれが問題になることはない)\n\tb ++;\n\n\tiTVPLayerManager * manager = GetLayerManagerAt(PrimaryLayerManagerIndex);\n\tif(!manager) return;\n\tmanager->RequestInvalidation(tTVPRect(l, t, r, b));\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::Update()\n{\n\t// すべての layer manager の UpdateToDrawDevice を呼ぶ\n\tfor(std::vector<iTVPLayerManager *>::iterator i = Managers.begin(); i != Managers.end(); i++)\n\t{\n\t\t(*i)->UpdateToDrawDevice();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::Show()\n{\n\t// なにもしない\n}\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPDrawDevice::WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed )\n{\n\treturn false;\n}\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::DumpLayerStructure()\n{\n\t// すべての layer manager の DumpLayerStructure を呼ぶ\n\tfor(std::vector<iTVPLayerManager *>::iterator i = Managers.begin(); i != Managers.end(); i++)\n\t{\n\t\t(*i)->DumpLayerStructure();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetShowUpdateRect(bool b)\n{\n\t// なにもしない\n}\n\nvoid TJS_INTF_METHOD tTVPDrawDevice::SetWindowSize(tjs_int w, tjs_int h) {\n    WinWidth = w; WinHeight = h;\n}\n\n//---------------------------------------------------------------------------\nbool TJS_INTF_METHOD tTVPDrawDevice::SwitchToFullScreen( int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color, bool changeresolution )\n{\n\treturn true;\n#if 0\n\t// ChangeDisplaySettings を使用したフルスクリーン化\n\tbool success = false;\n\tDEVMODE dm;\n\tZeroMemory(&dm, sizeof(DEVMODE));\n\tdm.dmSize = sizeof(DEVMODE);\n\tdm.dmPelsWidth = w;\n\tdm.dmPelsHeight = h;\n\tdm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;\n\tdm.dmBitsPerPel = bpp;\n\tLONG ret = ::ChangeDisplaySettings((DEVMODE*)&dm, CDS_FULLSCREEN);\n\tswitch(ret)\n\t{\n\tcase DISP_CHANGE_SUCCESSFUL:\n\t\t::SetWindowPos(window, HWND_TOP, 0, 0, w, h, SWP_SHOWWINDOW);\n\t\tsuccess = true;\n\t\tbreak;\n\tcase DISP_CHANGE_RESTART:\n\t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeRestart );\n\t\tbreak;\n\tcase DISP_CHANGE_BADFLAGS:\n\t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeBadFlags );\n\t\tbreak;\n\tcase DISP_CHANGE_BADPARAM:\n\t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeBadParam );\n\t\tbreak;\n\tcase DISP_CHANGE_FAILED:\n\t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeFailed );\n\t\tbreak;\n\tcase DISP_CHANGE_BADMODE:\n\t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeBadMode );\n\t\tbreak;\n\tcase DISP_CHANGE_NOTUPDATED:\n \t\tTVPAddLog( (const tjs_char*)TVPChangeDisplaySettingsFailedDispChangeNotUpdated );\n\t\tbreak;\n\tdefault:\n\t\tTVPAddLog( TVPFormatMessage(TVPChangeDisplaySettingsFailedUnknownReason,ttstr((tjs_int)ret)) );\n\t\tbreak;\n\t}\n\treturn success;\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPDrawDevice::RevertFromFullScreen(int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color)\n{\n\t// ChangeDisplaySettings を使用したフルスクリーン解除\n//\t::ChangeDisplaySettings(NULL, 0);\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/win32/DrawDevice.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//!@file 描画デバイス管理\n//---------------------------------------------------------------------------\n#ifndef DRAWDEVICE_H\n#define DRAWDEVICE_H\n\n#include \"LayerIntf.h\"\n#include \"LayerManager.h\"\n#include \"ComplexRect.h\"\n\nclass iTVPWindow;\nclass tTJSNI_BaseLayer;\n\n/*[*/\n//---------------------------------------------------------------------------\n//! @brief\t\t描画デバイスインターフェース\n//---------------------------------------------------------------------------\nclass iTVPDrawDevice\n{\npublic:\n//---- オブジェクト生存期間制御\n\t//! @brief\t\t(Window→DrawDevice) 描画デバイスを破棄する\n\t//! @note\t\tウィンドウが破棄されるとき、あるいはほかの描画デバイスが\n\t//!\t\t\t\t設定されたためにこの描画デバイスが必要なくなった際に呼ばれる。\n\t//!\t\t\t\t通常、ここでは delete this を実行し、描画デバイスを破棄するが、その前に\n\t//!\t\t\t\tAddLayerManager() でこの描画デバイスの管理下に入っている\n\t//!\t\t\t\tレイヤマネージャをすべて Release する。\n\t//!\t\t\t\tレイヤマネージャの Release 中に RemoveLayerManager() が呼ばれる\n\t//!\t\t\t\t可能性があることに注意すること。\n\tvirtual void TJS_INTF_METHOD Destruct() = 0;\n\n//---- window interface 関連\n\t//! @brief\t\t(Window→DrawDevice) ウィンドウインターフェースを設定する\n\t//! @param\t\twindow\t\tウィンドウインターフェース\n\t//! @note\t\t(TJSから) Window.drawDevice プロパティを設定した直後に呼ばれる。\n\tvirtual void TJS_INTF_METHOD SetWindowInterface(iTVPWindow * window) = 0;\n\n//---- LayerManager の管理関連\n\t//! @brief\t\t(Window→DrawDevice) レイヤマネージャを追加する\n\t//! @note\t\tプライマリレイヤがウィンドウに追加されると、自動的にレイヤマネージャが\n\t//!\t\t\t\t作成され、それが描画デバイスにもこのメソッドの呼び出しにて通知される。\n\t//!\t\t\t\t描画デバイスでは iTVPLayerManager::AddRef() を呼び出して、追加された\n\t//!\t\t\t\tレイヤマネージャをロックすること。\n\tvirtual void TJS_INTF_METHOD AddLayerManager(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) レイヤマネージャを削除する\n\t//! @note\t\tプライマリレイヤが invalidate される際に呼び出される。\n\t//TODO: プライマリレイヤ無効化、あるいはウィンドウ破棄時の終了処理が正しいか？\n\tvirtual void TJS_INTF_METHOD RemoveLayerManager(iTVPLayerManager * manager) = 0;\n\n//---- 描画位置・サイズ関連\n\t//! @brief\t\t(Window→DrawDevice) 描画先ウィンドウの設定\n\t//! @param\t\twnd\t\tウィンドウハンドル\n\t//! @param\t\tis_main\tメインウィンドウの場合に真\n\t//! @note\t\tウィンドウから描画先となるウィンドウハンドルを指定するために呼ばれる。\n\t//!\t\t\t\tしばしば、Window.borderStyle プロパティが変更されたり、フルスクリーンに\n\t//!\t\t\t\t移行するときやフルスクリーンから戻る時など、ウィンドウが再作成される\n\t//!\t\t\t\tことがあるが、そのような場合には、ウィンドウがいったん破棄される直前に\n\t//!\t\t\t\twnd = NULL の状態でこのメソッドが呼ばれることに注意。ウィンドウが作成\n\t//!\t\t\t\tされたあと、再び有効なウィンドウハンドルを伴ってこのメソッドが呼ばれる。\n\t//!\t\t\t\tこのメソッドは、ウィンドウが作成された直後に呼ばれる保証はない。\n\t//!\t\t\t\tたいてい、一番最初にウィンドウが表示された直後に呼ばれる。\n//\tvirtual void TJS_INTF_METHOD SetTargetWindow(int wnd, bool is_main) = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 描画矩形の設定\n\t//! @note\t\tウィンドウから、描画先となる矩形を設定するために呼ばれる。\n\t//!\t\t\t\t描画デバイスは、SetTargetWindow() で指定されたウィンドウのクライアント領域の、\n\t//!\t\t\t\tこのメソッドで指定された矩形に表示を行う必要がある。\n\t//!\t\t\t\tこの矩形は、GetSrcSize で返した値に対し、Window.zoomNumer や Window.zoomDenum\n\t//!\t\t\t\tプロパティによる拡大率や、Window.layerLeft や Window.layerTop が加味された\n\t//!\t\t\t\t矩形である。\n\t//!\t\t\t\tこのメソッドによって描画矩形が変わったとしても、このタイミングで\n\t//!\t\t\t\t描画デバイス側で再描画を行う必要はない(必要があれば別メソッドにより\n\t//!\t\t\t\t再描画の必要性が通知されるため)。\n\tvirtual void TJS_INTF_METHOD SetDestRectangle(const tTVPRect & rect) = 0;\n\n\tvirtual void TJS_INTF_METHOD SetWindowSize(tjs_int w, tjs_int h) = 0;\n\t//! @brief\t\t(Window->DrawDevice) クリッピング矩形の設定\n\t//! @note\t\tウィンドウから、描画先をクリッピングするための矩形を設定するために呼ばれる。\n\t//!\t\t\t\t描画デバイスは、SetDestRectangleで指定された領域を、このメソッドで指定された矩形\n\t//!\t\t\t\tでクリッピングを行い表示を行う必要がある。\n\t//!\t\t\t\tこのメソッドによって描画領域が変わったとしても、このタイミングで\n\t//!\t\t\t\t描画デバイス側で再描画を行う必要はない(必要があれば別メソッドにより\n\t//!\t\t\t\t再描画の必要性が通知されるため)。\n\tvirtual void TJS_INTF_METHOD SetClipRectangle(const tTVPRect & rect) = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 元画像のサイズを得る\n\t//! @note\t\tウィンドウから、描画矩形のサイズを決定するために元画像のサイズが\n\t//!\t\t\t\t必要になった際に呼ばれる。ウィンドウはこれをもとに SetDestRectangle()\n\t//!\t\t\t\tメソッドで描画矩形を通知してくるだけなので、\n\t//!\t\t\t\tなんらかの意味のあるサイズである必要は必ずしもない。\n\tvirtual void TJS_INTF_METHOD GetSrcSize(tjs_int &w, tjs_int &h) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) レイヤサイズ変更の通知\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @note\t\tレイヤマネージャにアタッチされているプライマリレイヤのサイズが変わった\n\t//!\t\t\t\t際に呼び出される\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) レイヤの画像の変更の通知\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @note\t\tレイヤの画像に変化があった際に呼び出される。\n\t//!\t\t\t\tこの通知を受け取った後に iTVPLayerManager::UpdateToDrawDevice()\n\t//!\t\t\t\tを呼び出せば、該当部分を描画デバイスに対して描画させることができる。\n\t//!\t\t\t\tこの通知を受け取っても無視することは可能。その場合は、\n\t//!\t\t\t\t次に iTVPLayerManager::UpdateToDrawDevice() を呼んだ際に、\n\t//!\t\t\t\tそれまでの変更分がすべて描画される。\n\tvirtual void TJS_INTF_METHOD NotifyLayerImageChange(iTVPLayerManager * manager) = 0;\n\n//---- ユーザーインターフェース関連\n\t//! @brief\t\t(Window→DrawDevice) クリックされた\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\tvirtual void TJS_INTF_METHOD OnClick(tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) ダブルクリックされた\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\tvirtual void TJS_INTF_METHOD OnDoubleClick(tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マウスボタンが押下された\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tmb\t\tどのマウスボタンか\n\t//! @param\t\tflags\tフラグ(TVP_SS_*定数の組み合わせ)\n\tvirtual void TJS_INTF_METHOD OnMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マウスボタンが離された\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tmb\t\tどのマウスボタンか\n\t//! @param\t\tflags\tフラグ(TVP_SS_*定数の組み合わせ)\n\tvirtual void TJS_INTF_METHOD OnMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マウスが移動した\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tflags\tフラグ(TVP_SS_*定数の組み合わせ)\n\tvirtual void TJS_INTF_METHOD OnMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) レイヤのマウスキャプチャを解放する\n\t//! @note\t\tレイヤのマウスキャプチャを解放すべき場合にウィンドウから呼ばれる。\n\t//! @note\t\tWindowReleaseCapture() と混同しないこと。\n\tvirtual void TJS_INTF_METHOD OnReleaseCapture() = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マウスが描画矩形外に移動した\n\tvirtual void TJS_INTF_METHOD OnMouseOutOfWindow() = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) キーが押された\n\t//! @param\t\tkey\t\t仮想キーコード\n\t//! @param\t\tshift\tシフトキーの状態\n\tvirtual void TJS_INTF_METHOD OnKeyDown(tjs_uint key, tjs_uint32 shift) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) キーが離された\n\t//! @param\t\tkey\t\t仮想キーコード\n\t//! @param\t\tshift\tシフトキーの状態\n\tvirtual void TJS_INTF_METHOD OnKeyUp(tjs_uint key, tjs_uint32 shift) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) キーによる入力\n\t//! @param\t\tkey\t\t文字コード\n\tvirtual void TJS_INTF_METHOD OnKeyPress(tjs_char key) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マウスホイールが回転した\n\t//! @param\t\tshift\tシフトキーの状態\n\t//! @param\t\tdelta\t回転角\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\tvirtual void TJS_INTF_METHOD OnMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) 画面がタッチされた\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tcx\t\t触れている幅\n\t//! @param\t\tcy\t\t触れている高さ\n\t//! @param\t\tid\t\tタッチ識別用ID\n\tvirtual void TJS_INTF_METHOD OnTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) タッチが離された\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tcx\t\t触れている幅\n\t//! @param\t\tcy\t\t触れている高さ\n\t//! @param\t\tid\t\tタッチ識別用ID\n\tvirtual void TJS_INTF_METHOD OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) タッチが移動した\n\t//! @param\t\tx\t\t描画矩形内における x 位置(描画矩形の左上が原点)\n\t//! @param\t\ty\t\t描画矩形内における y 位置(描画矩形の左上が原点)\n\t//! @param\t\tcx\t\t触れている幅\n\t//! @param\t\tcy\t\t触れている高さ\n\t//! @param\t\tid\t\tタッチ識別用ID\n\tvirtual void TJS_INTF_METHOD OnTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id ) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) 拡大タッチ操作が行われた\n\t//! @param\t\tstartdist\t開始時の2点間の幅\n\t//! @param\t\tcurdist\t現在の2点間の幅\n\t//! @param\t\tcx\t\t触れている幅\n\t//! @param\t\tcy\t\t触れている高さ\n\t//! @param\t\tflag\tタッチ状態フラグ\n\tvirtual void TJS_INTF_METHOD OnTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag ) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) 回転タッチ操作が行われた\n\t//! @param\t\tstartangle\t開始時の角度\n\t//! @param\t\tcurangle\t現在の角度\n\t//! @param\t\tdist\t現在の2点間の幅\n\t//! @param\t\tcx\t\t触れている幅\n\t//! @param\t\tcy\t\t触れている高さ\n\t//! @param\t\tflag\tタッチ状態フラグ\n\tvirtual void TJS_INTF_METHOD OnTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag ) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) マルチタッチ状態が更新された\n\tvirtual void TJS_INTF_METHOD OnMultiTouch() = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 画面の回転が行われた\n\t//! @param\t\torientation\t画面の向き ( 横向き、縦向き、不明 )\n\t//! @param\t\trotate\t\t回転角度。Degree。負の値の時不明\n\t//! @param\t\tbpp\t\t\tBits per pixel\n\t//! @param\t\twidth\t\t画面幅\n\t//! @param\t\theight\t\t画面高さ\n\tvirtual void TJS_INTF_METHOD OnDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int width, tjs_int height ) = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 入力状態のチェック\n\t//! @note\t\tウィンドウから約1秒おきに、レイヤマネージャがユーザからの入力の状態を\n\t//!\t\t\t\t再チェックするために呼ばれる。レイヤ状態の変化がユーザの入力とは\n\t//!\t\t\t\t非同期に行われた場合、たとえばマウスカーソルの下にレイヤが出現した\n\t//!\t\t\t\tのにもかかわらず、マウスカーソルがそのレイヤの指定する形状に変更されない\n\t//!\t\t\t\tといった状況が発生しうる。このような状況に対処するため、ウィンドウから\n\t//!\t\t\t\tこのメソッドが約1秒おきに呼ばれる。\n\tvirtual void TJS_INTF_METHOD RecheckInputState() = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) マウスカーソルの形状をデフォルトに戻す\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @note\t\tマウスカーソルの形状をデフォルトの物に戻したい場合に呼ばれる\n\tvirtual void TJS_INTF_METHOD SetDefaultMouseCursor(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) マウスカーソルの形状を設定する\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\tcursor\t\tマウスカーソル形状番号\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(iTVPLayerManager * manager, tjs_int cursor) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) マウスカーソルの位置を取得する\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\tx\t\t\tプライマリレイヤ上の座標におけるマウスカーソルのx位置\n\t//! @param\t\ty\t\t\tプライマリレイヤ上の座標におけるマウスカーソルのy位置\n\t//! @note\t\t座標はプライマリレイヤ上の座標なので、必要ならば変換を行う\n\tvirtual void TJS_INTF_METHOD GetCursorPos(iTVPLayerManager * manager, tjs_int &x, tjs_int &y) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) マウスカーソルの位置を設定する\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\tx\t\t\tプライマリレイヤ上の座標におけるマウスカーソルのx位置\n\t//! @param\t\ty\t\t\tプライマリレイヤ上の座標におけるマウスカーソルのy位置\n\t//! @note\t\t座標はプライマリレイヤ上の座標なので、必要ならば変換を行う\n\tvirtual void TJS_INTF_METHOD SetCursorPos(iTVPLayerManager * manager, tjs_int x, tjs_int y) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) ウィンドウのマウスキャプチャを解放する\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @note\t\tウィンドウのマウスキャプチャを解放すべき場合にレイヤマネージャから呼ばれる。\n\t//! @note\t\tウィンドウのマウスキャプチャは OnReleaseCapture() で開放できるレイヤのマウスキャプチャ\n\t//!\t\t\t\tと異なることに注意。ウィンドウのマウスキャプチャは主にOSのウィンドウシステムの\n\t//!\t\t\t\t機能であるが、レイヤのマウスキャプチャは吉里吉里がレイヤマネージャごとに\n\t//!\t\t\t\t独自に管理している物である。このメソッドでは基本的には ::ReleaseCapture() などで\n\t//!\t\t\t\tマウスのキャプチャを開放する。\n\tvirtual void TJS_INTF_METHOD WindowReleaseCapture(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) ツールチップヒントを設定する\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\ttext\t\tヒントテキスト(空文字列の場合はヒントの表示をキャンセルする)\n\tvirtual void TJS_INTF_METHOD SetHintText(iTVPLayerManager * manager, iTJSDispatch2* sender, const ttstr & text) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) 注視ポイントの設定\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\tlayer\t\tフォント情報の含まれるレイヤ\n\t//! @param\t\tx\t\t\tプライマリレイヤ上の座標における注視ポイントのx位置\n\t//! @param\t\ty\t\t\tプライマリレイヤ上の座標における注視ポイントのy位置\n\t//! @note\t\t注視ポイントは通常キャレット位置のことで、そこにIMEのコンポジット・ウィンドウが\n\t//!\t\t\t\t表示されたり、ユーザ補助の拡大鏡がそこを拡大したりする。IMEがコンポジットウィンドウを\n\t//!\t\t\t\t表示したり、未確定の文字をそこに表示したりする際のフォントは layer パラメータ\n\t//!\t\t\t\tで示されるレイヤが持つ情報によるが、プラグインからその情報を得たり設定したり\n\t//!\t\t\t\tするインターフェースは今のところない。\n\t//! @note\t\t座標はプライマリレイヤ上の座標なので、必要ならば変換を行う。\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(iTVPLayerManager * manager, tTJSNI_BaseLayer *layer,\n\t\t\t\t\t\t\ttjs_int l, tjs_int t) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) 注視ポイントの解除\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) IMEモードの設定\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\t//! @param\t\tmode\t\tIMEモード\n\tvirtual void TJS_INTF_METHOD SetImeMode(iTVPLayerManager * manager, tTVPImeMode mode) = 0;\n\n\t//! @brief\t\t(LayerManager→DrawDevice) IMEモードのリセット\n\t//! @param\t\tmanager\t\tレイヤマネージャ\n\tvirtual void TJS_INTF_METHOD ResetImeMode(iTVPLayerManager * manager) = 0;\n\n//---- プライマリレイヤ関連\n\t//! @brief\t\t(Window→DrawDevice) プライマリレイヤの取得\n\t//! @return\t\tプライマリレイヤ\n\t//! @note\t\tWindow.primaryLayer が読み出された際にこのメソッドが呼ばれる。\n\t//!\t\t\t\tそれ以外に呼ばれることはない。\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetPrimaryLayer() = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) フォーカスのあるレイヤの取得\n\t//! @return\t\tフォーカスのあるレイヤ(NULL=フォーカスのあるレイヤがない場合)\n\t//! @note\t\tWindow.focusedLayer が読み出された際にこのメソッドが呼ばれる。\n\t//!\t\t\t\tそれ以外に呼ばれることはない。\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetFocusedLayer() = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) フォーカスのあるレイヤの設定\n\t//! @param\t\tlayer\t\tフォーカスのあるレイヤ(NULL=フォーカスのあるレイヤがない状態にしたい場合)\n\t//! @note\t\tWindow.focusedLayer が書き込まれた際にこのメソッドが呼ばれる。\n\t//!\t\t\t\tそれ以外に呼ばれることはない。\n\tvirtual void TJS_INTF_METHOD SetFocusedLayer(tTJSNI_BaseLayer * layer) = 0;\n\n\n//---- 再描画関連\n\t//! @brief\t\t(Window→DrawDevice) 描画矩形の無効化の通知\n\t//! @param\t\trect\t\t描画矩形内の座標における、無効になった領域\n\t//!\t\t\t\t\t\t\t(描画矩形の左上が原点)\n\t//! @note\t\t描画矩形の一部あるいは全部が無効になった際にウィンドウから通知される。\n\t//!\t\t\t\t描画デバイスは、なるべく早い時期に無効になった部分を再描画すべきである。\n\tvirtual void TJS_INTF_METHOD RequestInvalidation(const tTVPRect & rect) = 0;\n\n\t//! @brief\t\t(Window→DrawDevice) 更新の要求\n\t//! @note\t\t描画矩形の内容を最新の状態に更新すべきタイミングで、ウィンドウから呼ばれる。\n\t//!\t\t\t\tiTVPWindow::RequestUpdate() を呼んだ後、システムが描画タイミングに入った際に\n\t//!\t\t\t\t呼ばれる。通常、描画デバイスはこのタイミングを利用してオフスクリーン\n\t//!\t\t\t\tサーフェースに画像を描画する。\n\tvirtual void TJS_INTF_METHOD Update() = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 画像の表示\n\t//! @note\t\tオフスクリーンサーフェースに描画された画像を、オンスクリーンに表示する\n\t//!\t\t\t\t(あるいはフリップする) タイミングで呼ばれる。通常は Update の直後に\n\t//!\t\t\t\t呼ばれるが、VSync 待ちが有効になっている場合は Update 直後ではなく、\n\t//!\t\t\t\tVBlank 中に呼ばれる可能性がある。オフスクリーンサーフェースを\n\t//!\t\t\t\t使わない場合は無視してかまわない。\n\tvirtual void TJS_INTF_METHOD Show() = 0;\n\n//---- LayerManager からの画像受け渡し関連\n\t//! @brief\t\t(LayerManager->DrawDevice) ビットマップの描画を開始する\n\t//! @param\t\tmanager\t\t描画を開始するレイヤマネージャ\n\t//! @note\t\tレイヤマネージャから描画デバイスへ画像が転送される前に呼ばれる。\n\t//!\t\t\t\tこのあと、NotifyBitmapCompleted() が任意の回数呼ばれ、最後に\n\t//!\t\t\t\tEndBitmapCompletion() が呼ばれる。\n\t//!\t\t\t\t必要ならば、このタイミングで描画デバイス側でサーフェースのロックなどを\n\t//!\t\t\t\t行うこと。\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager) = 0;\n\n\t//! @brief\t\t(LayerManager->DrawDevice) ビットマップの描画を通知する\n\t//! @param\t\tmanager\t\t画像の提供元のレイヤマネージャ\n\t//! @param\t\tx\t\t\tプライマリレイヤ上の座標における画像の左端位置\n\t//! @param\t\ty\t\t\tプライマリレイヤ上の座標における画像の上端位置\n\t//! @param\t\tbits\t\tビットマップデータ\n\t//! @param\t\tbitmapinfo\tビットマップの形式情報\n\t//! @param\t\tcliprect\tbits のうち、どの部分を使って欲しいかの情報\n\t//! @param\t\ttype\t\t提供される画像が想定する合成モード\n\t//! @param\t\topacity\t\t提供される画像が想定する不透明度(0～255)\n\t//! @note\t\tレイヤマネージャが合成を完了し、結果を描画デバイスに描画してもらいたい際に\n\t//!\t\t\t\t呼ばれる。一つの更新が複数の矩形で構成される場合があるため、このメソッドは\n\t//!\t\t\t\tStartBitmapCompletion() と EndBitmapCompletion() の間に複数回呼ばれる可能性がある。\n\t//!\t\t\t\t基本的には、bits と bitmapinfo で表されるビットマップのうち、cliprect で\n\t//!\t\t\t\t示される矩形を x, y 位置に転送すればよいが、描画矩形の大きさに合わせた\n\t//!\t\t\t\t拡大や縮小などは描画デバイス側で面倒を見る必要がある。\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity) = 0;\n\n\t//! @brief\t\t(LayerManager->DrawDevice) ビットマップの描画を終了する\n\t//! @param\t\tmanager\t\t描画を終了するレイヤマネージャ\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager) = 0;\n\n//---- デバッグ支援\n\t//! @brief\t\t(Window->DrawDevice) レイヤ構造をコンソールにダンプする\n\tvirtual void TJS_INTF_METHOD DumpLayerStructure() = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) 更新矩形の表示を行うかどうかを設定する\n\t//! @param\t\tb\t\t表示を行うかどうか\n\t//! @note\t\tレイヤ表示機構が差分更新を行う際の矩形を表示し、\n\t//!\t\t\t\t差分更新の最適化に役立てるための支援機能。\n\t//!\t\t\t\t実装する必要はないが、実装することが望ましい。\n\tvirtual void TJS_INTF_METHOD SetShowUpdateRect(bool b) = 0;\n    virtual void Clear() {}\n\n\t//! @brief\t\t(Window->DrawDevice) フルスクリーン化する\n\t//! @param\t\twindow\t\tウィンドウハンドル\n\t//! @param\t\tw\t\t\t要求する幅\n\t//! @param\t\th\t\t\t要求する高さ\n\t//! @param\t\tbpp\t\t\tBit per pixels\n\t//! @param\t\tcolor\t\t16bpp の時 565 か 555を指定\n\t//! @param\t\tchangeresolution\t解像度変更を行うかどうか\n\tvirtual bool TJS_INTF_METHOD SwitchToFullScreen( int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color, bool changeresolution ) = 0;\n\t\n\t//! @brief\t\t(Window->DrawDevice) フルスクリーンを解除する\n\t//! @param\t\twindow\t\tウィンドウハンドル\n\t//! @param\t\tw\t\t\t要求する幅\n\t//! @param\t\th\t\t\t要求する高さ\n\t//! @param\t\tbpp\t\t\t元々のBit per pixels\n\t//! @param\t\tcolor\t\t16bpp の時 565 か 555を指定\n\tvirtual void TJS_INTF_METHOD RevertFromFullScreen(int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color) = 0;\n\n\t//! @brief\t\t(Window->DrawDevice) VBlank待ちを行う\n\t//! @param\t\tin_vblank\t待たなくてもVBlank内だったかどうかを返す( !0 : 内、0: 外 )\n\t//! @param\t\tdelayed\t\t1フレーム遅延が発生したかどうかを返す( !0 : 発生、0: 発生せず )\n\t//! @return\t\tWait可不可 true : 可能、false : 不可\n\tvirtual bool TJS_INTF_METHOD WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed ) = 0;\n};\n//---------------------------------------------------------------------------\n/*]*/\n\n//---------------------------------------------------------------------------\n//! @brief\t\t描画デバイスインターフェースの基本的な実装\n//---------------------------------------------------------------------------\nclass tTVPDrawDevice : public iTVPDrawDevice\n{\nprotected:\n\tiTVPWindow * Window;\n\tsize_t PrimaryLayerManagerIndex; //!< プライマリレイヤマネージャ\n\tstd::vector<iTVPLayerManager *> Managers; //!< レイヤマネージャの配列\n\ttTVPRect DestRect; //!< 描画先位置\n    tjs_int SrcWidth, SrcHeight;\n    tjs_int WinWidth, WinHeight;\n\ttjs_int LockedWidth = 0, LockedHeight = 0;\n\ttTVPRect ClipRect; //!< クリッピング矩形\n\nprotected:\n\ttTVPDrawDevice(); //!< コンストラクタ\nprotected:\n\tvirtual ~tTVPDrawDevice(); //!< デストラクタ\n\npublic:\n\t//! @brief\t\t指定位置にあるレイヤマネージャを得る\n\t//! @param\t\tindex\t\tインデックス(0～)\n\t//! @return\t\t指定位置にあるレイヤマネージャ(AddRefされないので注意)。\n\t//!\t\t\t\t指定位置にレイヤマネージャがなければNULLが返る\n\tiTVPLayerManager * GetLayerManagerAt(size_t index)\n\t{\n\t\tif(Managers.size() <= index) return NULL;\n\t\treturn Managers[index];\n\t}\n\n\t//! @brief\t\tDevice→LayerManager方向の座標の変換を行う\n\t//! @param\t\tx\t\tX位置\n\t//! @param\t\ty\t\tY位置\n\t//! @return\t\t変換に成功すれば真。さもなければ偽。PrimaryLayerManagerIndexに該当する\n\t//!\t\t\t\tレイヤマネージャがなければ偽が返る\n\t//! @note\t\tx, y は DestRectの (0,0) を原点とする座標として渡されると見なす\n\tbool TransformToPrimaryLayerManager(tjs_int &x, tjs_int &y);\n\tbool TransformToPrimaryLayerManager(tjs_real &x, tjs_real &y);\n\n\t//! @brief\t\tLayerManager→Device方向の座標の変換を行う\n\t//! @param\t\tx\t\tX位置\n\t//! @param\t\ty\t\tY位置\n\t//! @return\t\t変換に成功すれば真。さもなければ偽。PrimaryLayerManagerIndexに該当する\n\t//!\t\t\t\tレイヤマネージャがなければ偽が返る\n\t//! @note\t\tx, y は レイヤの (0,0) を原点とする座標として渡されると見なす\n\tbool TransformFromPrimaryLayerManager(tjs_int &x, tjs_int &y);\n\n//---- オブジェクト生存期間制御\n\tvirtual void TJS_INTF_METHOD Destruct();\n\n//---- window interface 関連\n\tvirtual void TJS_INTF_METHOD SetWindowInterface(iTVPWindow * window);\n\n//---- LayerManager の管理関連\n\tvirtual void TJS_INTF_METHOD AddLayerManager(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD RemoveLayerManager(iTVPLayerManager * manager);\n\n//---- 描画位置・サイズ関連\n\tvirtual void TJS_INTF_METHOD SetDestRectangle(const tTVPRect & rect);\n    virtual void TJS_INTF_METHOD SetWindowSize(tjs_int w, tjs_int h);\n\tvirtual void TJS_INTF_METHOD SetClipRectangle(const tTVPRect & rect);\n\tvirtual void TJS_INTF_METHOD GetSrcSize(tjs_int &w, tjs_int &h);\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD NotifyLayerImageChange(iTVPLayerManager * manager);\n\n//---- ユーザーインターフェース関連\n\t// window → drawdevice\n\tvirtual void TJS_INTF_METHOD OnClick(tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD OnDoubleClick(tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD OnMouseDown(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvirtual void TJS_INTF_METHOD OnMouseUp(tjs_int x, tjs_int y, tTVPMouseButton mb, tjs_uint32 flags);\n\tvirtual void TJS_INTF_METHOD OnMouseMove(tjs_int x, tjs_int y, tjs_uint32 flags);\n\tvirtual void TJS_INTF_METHOD OnReleaseCapture();\n\tvirtual void TJS_INTF_METHOD OnMouseOutOfWindow();\n\tvirtual void TJS_INTF_METHOD OnKeyDown(tjs_uint key, tjs_uint32 shift);\n\tvirtual void TJS_INTF_METHOD OnKeyUp(tjs_uint key, tjs_uint32 shift);\n\tvirtual void TJS_INTF_METHOD OnKeyPress(tjs_char key);\n\tvirtual void TJS_INTF_METHOD OnMouseWheel(tjs_uint32 shift, tjs_int delta, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD OnTouchDown( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvirtual void TJS_INTF_METHOD OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvirtual void TJS_INTF_METHOD OnTouchMove( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\n\tvirtual void TJS_INTF_METHOD OnTouchScaling( tjs_real startdist, tjs_real curdist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvirtual void TJS_INTF_METHOD OnTouchRotate( tjs_real startangle, tjs_real curangle, tjs_real dist, tjs_real cx, tjs_real cy, tjs_int flag );\n\tvirtual void TJS_INTF_METHOD OnMultiTouch();\n\tvirtual void TJS_INTF_METHOD OnDisplayRotate( tjs_int orientation, tjs_int rotate, tjs_int bpp, tjs_int width, tjs_int height );\n\tvirtual void TJS_INTF_METHOD RecheckInputState();\n\n\t// layer manager → drawdevice\n\tvirtual void TJS_INTF_METHOD SetDefaultMouseCursor(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(iTVPLayerManager * manager, tjs_int cursor);\n\tvirtual void TJS_INTF_METHOD GetCursorPos(iTVPLayerManager * manager, tjs_int &x, tjs_int &y);\n\tvirtual void TJS_INTF_METHOD SetCursorPos(iTVPLayerManager * manager, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD SetHintText(iTVPLayerManager * manager, iTJSDispatch2* sender, const ttstr & text);\n\tvirtual void TJS_INTF_METHOD WindowReleaseCapture(iTVPLayerManager * manager);\n\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(iTVPLayerManager * manager, tTJSNI_BaseLayer *layer,\n\t\t\t\t\t\t\ttjs_int l, tjs_int t);\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD SetImeMode(iTVPLayerManager * manager, tTVPImeMode mode);\n\tvirtual void TJS_INTF_METHOD ResetImeMode(iTVPLayerManager * manager);\n\n//---- プライマリレイヤ関連\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetPrimaryLayer();\n\tvirtual tTJSNI_BaseLayer * TJS_INTF_METHOD GetFocusedLayer();\n\tvirtual void TJS_INTF_METHOD SetFocusedLayer(tTJSNI_BaseLayer * layer);\n\n//---- 再描画関連\n\tvirtual void TJS_INTF_METHOD RequestInvalidation(const tTVPRect & rect);\n\tvirtual void TJS_INTF_METHOD Update();\n\tvirtual void TJS_INTF_METHOD Show() = 0;\n\tvirtual bool TJS_INTF_METHOD WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed );\n\n//---- デバッグ支援\n\tvirtual void TJS_INTF_METHOD DumpLayerStructure();\n\tvirtual void TJS_INTF_METHOD SetShowUpdateRect(bool b);\n\n\tvoid SetLockedSize(tjs_int w, tjs_int h);\n//---- フルスクリーン\n\tvirtual bool TJS_INTF_METHOD SwitchToFullScreen(int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color, bool changeresolution);\n\tvirtual void TJS_INTF_METHOD RevertFromFullScreen(int window, tjs_uint w, tjs_uint h, tjs_uint bpp, tjs_uint color);\n\n// ほかのメソッドについては実装しない\n};\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/GDIFontRasterizer.cpp",
    "content": "\n#define _USE_MATH_DEFINES\n#include \"GDIFontRasterizer.h\"\n\n#include \"LayerBitmapIntf.h\"\n#include <math.h>\n\n#include \"FontSystem.h\"\n#include \"TVPSysFont.h\"\n#include \"SysInitImpl.h\"\n\nextern FontSystem* TVPFontSystem;\n\n\n//---------------------------------------------------------------------------\nvoid GDIFontRasterizer::InitChAntialiasMethod() {\n\tif(ChAntialiasMethodInit) return;\n\n\tChAntialiasMethod = camAPI; // default\n\n\ttTJSVariant val;\n\tif( TVPGetCommandLine(TJS_W(\"-aamethod\"), &val) ) {\n\t\tttstr str(val);\n#if 0 // ܂Ӗ̂ȂR[hH\n\t\tif(str == TJS_W(\"auto\"))\n\t\t\t; // nothing to do\n#endif\n\t\tif(str == TJS_W(\"res8\"))\n\t\t\tChAntialiasMethod = camResample8;\n\t\telse if(str == TJS_W(\"res4\"))\n\t\t\tChAntialiasMethod = camResample4;\n\t\telse if(str == TJS_W(\"api\"))\n\t\t\tChAntialiasMethod = camAPI;\n\t\telse if(str == TJS_W(\"rgb\"))\n\t\t\tChAntialiasMethod = camSubpixelRGB;\n\t\telse if(str == TJS_W(\"bgr\"))\n\t\t\tChAntialiasMethod = camSubpixelBGR;\n\t}\n\n\tChAntialiasMethodInit = true;\n}\n//---------------------------------------------------------------------------\n\n\nGDIFontRasterizer::GDIFontRasterizer()\n: RefCount(0), FontDC(NULL), NonBoldFontDC(NULL), LastBitmap(NULL), ChAntialiasMethodInit(false)\n, ChUseResampling(false), ChAntialiasMethod(camResample8)\n{\n\tAddRef();\n}\n\nGDIFontRasterizer::~GDIFontRasterizer() {\n}\nvoid GDIFontRasterizer::AddRef() {\n\tif( RefCount == 0 ) {\n\t\tFontDC = new tTVPSysFont();\n\t\tNonBoldFontDC = new tTVPSysFont();\n\t}\n\tRefCount ++;\n}\nvoid GDIFontRasterizer::Release() {\n\tRefCount --;\n\tLastBitmap = NULL;\n\tif( RefCount == 0 ) {\n\t\tdelete FontDC;\n\t\tFontDC = NULL;\n\t\tdelete NonBoldFontDC;\n\t\tNonBoldFontDC = NULL;\n\n\t\tdelete this;\n\t}\n}\nvoid GDIFontRasterizer::ApplyFont( tTVPNativeBaseBitmap *bmp, bool force ) {\n\tif( bmp != LastBitmap || force ) {\n\t\tApplyFont( bmp->GetFont() );\n\t\tLastBitmap = bmp;\n\t}\n}\nvoid GDIFontRasterizer::ApplyFont( const tTVPFont& font ) {\n\tLOGFONT LogFont={0};\n\tLogFont.lfHeight = -std::abs(font.Height);\n\tLogFont.lfItalic = (font.Flags & TVP_TF_ITALIC) ? TRUE:FALSE;\n\tLogFont.lfWeight = (font.Flags & TVP_TF_BOLD) ? 700 : 400;\n\tLogFont.lfUnderline = (font.Flags & TVP_TF_UNDERLINE) ? TRUE:FALSE;\n\tLogFont.lfStrikeOut = (font.Flags & TVP_TF_STRIKEOUT) ? TRUE:FALSE;\n\tLogFont.lfEscapement = LogFont.lfOrientation = font.Angle;\n\tLogFont.lfCharSet = DEFAULT_CHARSET;\n\tLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;\n\tLogFont.lfQuality = DEFAULT_QUALITY;\n\tLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\n\tstd::wstring face = TVPFontSystem->GetBeingFont(font.Face.AsStdString());\n\tTJS_strncpy(LogFont.lfFaceName, face.c_str(), LF_FACESIZE -1);\n\tLogFont.lfFaceName[LF_FACESIZE-1] = 0;\n\n\tFontDC->ApplyFont( &LogFont );\n\tCurentLOGFONT = LogFont;\n\tint orgweight = CurentLOGFONT.lfWeight;\n\tCurentLOGFONT.lfWeight = 400;\n\tNonBoldFontDC->ApplyFont( &CurentLOGFONT );\n\tCurentLOGFONT.lfWeight = orgweight;\n\tLastBitmap = NULL;\n}\nvoid GDIFontRasterizer::GetTextExtent(tjs_char ch, tjs_int &w, tjs_int &h) {\n\tSIZE s;\n\ts.cx = 0;\n\ts.cy = 0;\n\t::GetTextExtentPoint32(NonBoldFontDC->GetDC(), &ch, 1, &s);\n\n\tw = s.cx;\n\th = s.cy;\n\n\tif( CurentLOGFONT.lfWeight >= 700 ) {\n\t\tw += (int)(h / 50) + 1; // calculate bold font size\n\t}\n}\ntjs_int GDIFontRasterizer::GetAscentHeight() {\n  return FontDC->GetAscentHeight();\n}\ntTVPCharacterData* GDIFontRasterizer::GetBitmap( const tTVPFontAndCharacterData & font, tjs_int aofsx, tjs_int aofsy ) {\n\tInitChAntialiasMethod();\n\n\t// setup GLYPHMETRICS and reveive buffer\n\tGLYPHMETRICS gm;\n\tZeroMemory(&gm, sizeof(gm));\n\tstatic MAT2 no_transform_matrix = { {0,1}, {0,0}, {0,0}, {0,1} };\n\t\t// transformation matrix for intact conversion\n\t\t// | 1 0 |\n\t\t// | 0 1 |\n\tstatic MAT2 scale_4x_matrix = { {0,4}, {0,0}, {0,0}, {0,4} };\n\t\t// transformation matrix for 4x\n\t\t// | 4 0 |\n\t\t// | 0 4 |\n\tstatic MAT2 scale_8x_matrix = { {0,8}, {0,0}, {0,0}, {0,8} };\n\t\t// transformation matrix for 8x\n\t\t// | 8 0 |\n\t\t// | 0 8 |\n\n\n\t// determine format and transformation matrix\n\ttjs_int factor = 0;\n\tMAT2 *transmat;\n\tUINT format = font.Antialiased ? GGO_GRAY8_BITMAP : GGO_BITMAP;\n\tif(font.Antialiased)\n\t{\n\t\tswitch(ChAntialiasMethod)\n\t\t{\n\t\tcase camAPI:\n\t\t\ttransmat = &no_transform_matrix;\n\t\t\tbreak;\n\t\tcase camResample4:\n\t\t\ttransmat = &scale_4x_matrix, factor = 2;\n\t\t\tformat = GGO_BITMAP;\n\t\t\tbreak;\n\t\tcase camSubpixelRGB:\n\t\tcase camSubpixelBGR:\n\t\tcase camResample8:\n\t\t\ttransmat = &scale_8x_matrix, factor = 3;\n\t\t\tformat = GGO_BITMAP;\n\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\ttransmat = &no_transform_matrix;\n\t}\n\n\n\t// retrieve character code\n\tWORD code;\n\t// system supports UNICODE\n\tcode = font.Character;\n\n\t// get buffer size and output dimensions\n\tint size = ::GetGlyphOutline( FontDC->GetDC(), code, format, &gm, 0, NULL, transmat);\n\n\t// set up structure's variables\n\ttTVPCharacterData * data = new tTVPCharacterData();\n\n\t{\n\t\tSIZE s;\n\t\ts.cx = 0;\n\t\ts.cy = 0;\n\t\tGetTextExtentPoint32( NonBoldFontDC->GetDC(), &font.Character, 1, &s);\n\n\t\tif(font.Font.Flags & TVP_TF_BOLD)\n\t\t{\n\t\t\t// calculate bold font width;\n\t\t\t// because sucking Win32 API returns different character size\n\t\t\t// between Win9x and WinNT, when we specified bold characters.\n\t\t\t// so we must alternatively calculate bold font size based on\n\t\t\t// non-bold font width.\n\t\t\ts.cx += (int)(s.cx / 50) + 1;\n\t\t}\n\n\t\tif(font.Font.Angle == 0)\n\t\t{\n\t\t\tdata->Metrics.CellIncX = s.cx;\n\t\t\tdata->Metrics.CellIncY = 0;\n\t\t}\n\t\telse if(font.Font.Angle == 2700)\n\t\t{\n\t\t\tdata->Metrics.CellIncX = 0;\n\t\t\tdata->Metrics.CellIncY = s.cx;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdouble angle = font.Font.Angle * (M_PI/1800);\n\t\t\tdata->Metrics.CellIncX = static_cast<tjs_int>(  cos(angle) * s.cx);\n\t\t\tdata->Metrics.CellIncY = static_cast<tjs_int>(- sin(angle) * s.cx);\n\t\t}\n\t}\n\tdata->Gray = 65;\n\tdata->BlackBoxX = gm.gmBlackBoxX;\n\tdata->BlackBoxY = gm.gmBlackBoxY;\n\tdata->OriginX =\n\t\t(gm.gmptGlyphOrigin.x) +\n\t\t(aofsx<<factor);\n\tdata->OriginY = -gm.gmptGlyphOrigin.y + (aofsy<<factor);\n\n\tdata->Antialiased = font.Antialiased;\n\n\tdata->FullColored = false;\n\n\tdata->Blured = font.Blured;\n\tdata->BlurWidth = font.BlurWidth;\n\tdata->BlurLevel = font.BlurLevel;\n\n\tif(size == 0 || gm.gmBlackBoxY == 0)\n\t{\n\t\tdata->BlackBoxX = 0;\n\t\tdata->BlackBoxY = 0;\n\t}\n\telse\n\t{\n\n\t\tif(format == GGO_GRAY8_BITMAP)\n\t\t{\n\t\t\tdata->Pitch = (size / gm.gmBlackBoxY) & ~0x03;\n\t\t\t\t// data is aligned to DWORD\n\t\t\t/*\n\t\t\t\tdata->Pitch = (((gm.gmBlackBoxX -1)>>2)+1)<<2 seems to be proper,\n\t\t\t\tbut does not work with some characters.\n\t\t\t*/\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdata->Pitch = (((gm.gmBlackBoxX -1)>>5)+1)<<2;\n\t\t\t\t// data is aligned to DWORD\n\t\t}\n\n\t\tdata->Alloc(size);\n\n\t\ttry\n\t\t{\n\t\t\t// draw to buffer\n\t\t\t::GetGlyphOutline( FontDC->GetDC(), code, format, &gm, size, data->GetData(), transmat);\n\n\t\t\tif( (ChUseResampling ) && (font.Font.Flags & TVP_TF_BOLD) ) {\n\t\t\t\t// our sucking win9x based OS cannot output bold characters\n\t\t\t\t// even if BOLD is specified.\n\t\t\t\tif(format == GGO_BITMAP)\n\t\t\t\t\tdata->Bold2(font.Font.Height<<factor);\n\t\t\t\telse\n\t\t\t\t\tdata->Bold(font.Font.Height<<factor);\n\t\t\t\t\t// so here we go a nasty way ...\n\t\t\t}\n\n\t\t\tif(!font.Antialiased)\n\t\t\t{\n\t\t\t\t// not antialiased\n\t\t\t\tdata->Expand(); // nasty...\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// antialiased\n\t\t\t\tswitch(ChAntialiasMethod)\n\t\t\t\t{\n\t\t\t\tcase camAPI:\n\t\t\t\t\tbreak;\n\t\t\t\tcase camResample4:\n\t\t\t\t\tdata->Resample4();\n\t\t\t\t\tbreak;\n\t\t\t\tcase camResample8:\n\t\t\t\t\tdata->Resample8();\n\t\t\t\t\tbreak;\n\t\t\t\tcase camSubpixelRGB:\n//\t\t\t\t\t\tdata->ResampleRGB();\n\t\t\t\t\tbreak;\n\t\t\t\tcase camSubpixelBGR:\n//\t\t\t\t\t\tdata->ResampleBGR();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// apply blur\n\t\t\tif(font.Blured) data->Blur(); // nasty ...\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdata->Release();\n\t\t\tthrow;\n\t\t}\n\t}\n\tif( font.Font.Flags & (TVP_TF_UNDERLINE|TVP_TF_STRIKEOUT) ) {\n\t\tOUTLINETEXTMETRIC otm = { sizeof(OUTLINETEXTMETRIC) };\n\t\t::GetOutlineTextMetrics( FontDC->GetDC(), otm.otmSize, &otm );\n\t\ttjs_int y = GetAscentHeight();\n\t\tif( font.Font.Flags & TVP_TF_UNDERLINE ) {\n\t\t\ttjs_int liney = y - otm.otmsUnderscorePosition;\n\t\t\ttjs_int height = otm.otmTextMetrics.tmHeight;\n\t\t\ttjs_int thickness = otm.otmsUnderscoreSize;\n\t\t\tif( liney >= height ) liney = height - 1;\n\t\t\tif( liney >= 0 && thickness > 0 ) {\n\t\t\t\tdata->AddHorizontalLine( liney, thickness, 64 );\n\t\t\t}\n\t\t}\n\t\tif( font.Font.Flags & TVP_TF_STRIKEOUT ) {\n\t\t\ttjs_int liney = y - otm.otmsStrikeoutPosition;\n\t\t\ttjs_int thickness =  otm.otmsStrikeoutSize;\n\t\t\tif( liney >= 0 && thickness > 0 ) {\n\t\t\t\tdata->AddHorizontalLine( liney, thickness, 64 );\n\t\t\t}\n\t\t}\n\t}\n\treturn data;\n}\nvoid GDIFontRasterizer::GetGlyphDrawRect( const ttstr & text, tTVPRect& area )\n{\n\tstatic MAT2 no_transform_matrix = { {0,1}, {0,0}, {0,0}, {0,1} };\n\tGLYPHMETRICS gm;\n\n\ttjs_int ascent = GetAscentHeight();\n\n\tLOGFONT LogFont;\n\tFontDC->GetFont( &LogFont );\n\tOUTLINETEXTMETRIC otm = { sizeof(OUTLINETEXTMETRIC) };\n\tif( LogFont.lfUnderline || LogFont.lfStrikeOut ) {\n\t\t::GetOutlineTextMetrics( FontDC->GetDC(), otm.otmSize, &otm );\n\t}\n\n\tarea.left = area.top = area.right = area.bottom = 0;\n\ttjs_int offsetx = 0;\n\ttjs_int offsety = 0;\n\ttjs_uint len = text.length();\n\tfor( tjs_uint i = 0; i < len; i++ ) {\n\t\ttjs_char code = text[i];\n\t\tZeroMemory(&gm, sizeof(gm));\n\t\tint err = ::GetGlyphOutline( FontDC->GetDC(), code, GGO_METRICS, &gm, 0, NULL, &no_transform_matrix );\n\t\tSIZE s = {0,0};\n\t\tif( err != GDI_ERROR ) {\n\t\t\t::GetTextExtentPoint32( NonBoldFontDC->GetDC(), &code, 1, &s );\n\t\t\ttjs_int w = gm.gmBlackBoxX;\n\t\t\ttjs_int h = gm.gmBlackBoxY;\n\t\t\ttjs_int l = gm.gmptGlyphOrigin.x;\n\t\t\ttjs_int t = ascent - gm.gmptGlyphOrigin.y;\n\t\t\ttTVPRect rt( l, t, l+w, t+h );\n\t\t\tif( LogFont.lfUnderline ) {\n\t\t\t\ttjs_int liney = ascent - otm.otmsUnderscorePosition;\n\t\t\t\ttjs_int height = otm.otmTextMetrics.tmHeight;\n\t\t\t\ttjs_int thickness = otm.otmsUnderscoreSize;\n\t\t\t\tif( liney >= height ) liney = height - 1;\n\t\t\t\tif( liney >= 0 && thickness > 0 ) {\n\t\t\t\t\tif( rt.left > 0 ) rt.left = 0;\n\t\t\t\t\tif( rt.right < s.cx ) rt.right = s.cx;\n\t\t\t\t\tif( liney < rt.top ) rt.top = liney;\n\t\t\t\t\tif( (liney+thickness) >= rt.bottom ) rt.bottom = liney+thickness+1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( LogFont.lfStrikeOut ) {\n\t\t\t\ttjs_int liney = ascent - otm.otmsStrikeoutPosition;\n\t\t\t\ttjs_int thickness =  otm.otmsStrikeoutSize;\n\t\t\t\tif( liney >= 0 && thickness > 0 ) {\n\t\t\t\t\tif( rt.left > 0 ) rt.left = 0;\n\t\t\t\t\tif( rt.right < s.cx ) rt.right = s.cx;\n\t\t\t\t\tif( liney < rt.top ) rt.top = liney;\n\t\t\t\t\tif( (liney+thickness) >= rt.bottom ) rt.bottom = liney+thickness+1;\n\t\t\t\t}\n\t\t\t}\n\t\t\trt.add_offsets( offsetx, offsety );\n\t\t\tif( i != 0 ) {\n\t\t\t\tarea.do_union( rt );\n\t\t\t} else {\n\t\t\t\tarea = rt;\n\t\t\t}\n\t\t}\n\t\toffsetx += s.cx;\n\t\toffsety = 0;\n\t}\n}\n\n\n"
  },
  {
    "path": "src/core/visual/win32/GDIFontRasterizer.h",
    "content": "\n#ifndef __GDI_FONT_RASTERIZER_H__\n#define __GDI_FONT_RASTERIZER_H__\n\n#include \"tjsCommHead.h\"\n#include \"CharacterData.h\"\n#include \"FontRasterizer.h\"\n\nclass GDIFontRasterizer : public FontRasterizer {\n\ttjs_int RefCount;\n\tclass tTVPSysFont* FontDC;\n\tclass tTVPSysFont* NonBoldFontDC;\n\tclass tTVPNativeBaseBitmap* LastBitmap;\n\tLOGFONT CurentLOGFONT;\n\n\tbool ChUseResampling; // whether to use resampling anti-aliasing\n\tbool ChAntialiasMethodInit;\n\t\n\tenum tTVPChAntialiasMethod\n\t{\tcamAPI,\tcamResample4, camResample8, camSubpixelRGB, camSubpixelBGR };\n\ttTVPChAntialiasMethod ChAntialiasMethod;\n\n\tvoid InitChAntialiasMethod();\npublic:\n\tGDIFontRasterizer();\n\tvirtual ~GDIFontRasterizer();\n\tvoid AddRef();\n\tvoid Release();\n\tvoid ApplyFont( class tTVPNativeBaseBitmap *bmp, bool force );\n\tvoid ApplyFont( const struct tTVPFont& font );\n\tvoid GetTextExtent(tjs_char ch, tjs_int &w, tjs_int &h);\n\ttjs_int GetAscentHeight();\n\tclass tTVPCharacterData* GetBitmap( const struct tTVPFontAndCharacterData & font, tjs_int aofsx, tjs_int aofsy );\n\tvoid GetGlyphDrawRect( const ttstr & text, struct tTVPRect& area );\n};\n\n#endif // __GDI_FONT_RASTERIZER_H__\n"
  },
  {
    "path": "src/core/visual/win32/GraphicsLoaderImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Graphics Loader ( loads graphic format from storage )\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"GraphicsLoaderImpl.h\"\n#include \"GraphicsLoaderIntf.h\"\n#include \"tjsHashSearch.h\"\n#include \"StorageImpl.h\"\n#include \"MsgIntf.h\"\n#include \"tjsUtils.h\"\n#include \"SysInitIntf.h\"\n#include \"DebugIntf.h\"\n\n#include \"StorageImpl.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"MsgIntf.h\"\n\nvoid tTVPGraphicHandlerType::Load( void* formatdata, void *callbackdata, tTVPGraphicSizeCallback sizecallback, tTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback, tTJSBinaryStream *src, tjs_int32 keyidx, tTVPGraphicLoadMode mode)\n{\n\tif( LoadHandler == NULL ) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, TJS_W(\"unknown\"));\n#if 0\n\tif( IsPlugin )\n\t{\n\t\ttTVPIStreamAdapter *istream = new tTVPIStreamAdapter(src);\n\t\ttry {\n\t\t\tLoadHandlerPlugin( formatdata, callbackdata, sizecallback, scanlinecallback, metainfopushcallback,\n\t\t\t\tistream, keyidx, mode);\n\t\t} catch(...) {\n\t\t\tistream->ClearStream();\n\t\t\tistream->Release();\n\t\t\tthrow;\n\t\t}\n\t\tistream->ClearStream();\n\t\tistream->Release();\n\t}\n\telse\n#endif\n\t{\n\t\tLoadHandler( formatdata, callbackdata, sizecallback, scanlinecallback, metainfopushcallback,\n\t\t\tsrc, keyidx, mode);\n\t}\n}\nvoid tTVPGraphicHandlerType::Save( const ttstr & storagename, const ttstr & mode, const iTVPBaseBitmap* image, iTJSDispatch2* meta )\n{\n\tif( SaveHandler == NULL ) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, mode );\n\n\ttTJSBinaryStream *stream = TVPCreateStream(TVPNormalizeStorageName(storagename), TJS_BS_WRITE);\n#if 0\n\tif (IsPlugin)\n\t{\n\t\ttTVPIStreamAdapter *istream = new tTVPIStreamAdapter(stream);\n\t\ttry {\n\t\t\ttjs_uint h = image->GetHeight();\n\t\t\ttjs_uint w = image->GetWidth();\n\t\t\tSaveHandlerPlugin( FormatData, (void*)image, istream, mode, w, h, tTVPBitmapScanLineCallbackForSave, meta );\n\t\t} catch(...) {\n\t\t\tistream->Release();\n\t\t\tthrow;\n\t\t}\n\t\tistream->Release();\n\t}\n\telse\n#endif\n\t{\n\t\ttry {\n\t\t\tSaveHandler( FormatData, stream, image, mode, meta );\n\t\t} catch(...) {\n\t\t\tdelete stream;\n\t\t\tthrow;\n\t\t}\n\t\tdelete stream;\n\t}\n}\nvoid tTVPGraphicHandlerType::Header( tTJSBinaryStream *src, iTJSDispatch2** dic )\n{\n\tif( HeaderHandler == NULL ) TVPThrowExceptionMessage(TVPUnknownGraphicFormat, TJS_W(\"unknown\") );\n#if 0\n\tif( IsPlugin )\n\t{\n\t\ttTVPIStreamAdapter *istream = new tTVPIStreamAdapter(src);\n\t\ttry {\n\t\t\tHeaderHandlerPlugin( FormatData, istream, dic );\n\t\t} catch(...) {\n\t\t\tistream->ClearStream();\n\t\t\tistream->Release();\n\t\t\tthrow;\n\t\t}\n\t\tistream->ClearStream();\n\t\tistream->Release();\n\t}\n\telse\n#endif\n\t{\n\t\tHeaderHandler( FormatData, src, dic );\n\t}\n}\n/*\n\tsupport of SPI for archive files is in StorageImpl.cpp\n*/\n#if 0\n//---------------------------------------------------------------------------\n// tTVPSusiePlugin\n//---------------------------------------------------------------------------\ntTVPSusiePlugin::tTVPSusiePlugin(HINSTANCE inst, const char *api)\n{\n\tModuleInstance = inst;\n\n\t// get functions\n\t*(FARPROC*)&GetPluginInfo = GetProcAddress(inst, \"GetPluginInfo\");\n\t*(FARPROC*)&IsSupported = GetProcAddress(inst, \"IsSupported\");\n\n\t*(FARPROC*)&GetPicture = GetProcAddress(inst, \"GetPicture\");\n\n\n\t*(FARPROC*)&GetArchiveInfo = GetProcAddress(inst, \"GetArchiveInfo\");\n\t*(FARPROC*)&GetFile = GetProcAddress(inst, \"GetFile\");\n\n\tif(!memcmp(api, \"00IN\", 4))\n\t{\n\t\tif(!GetPluginInfo || !IsSupported || !GetPicture)\n\t\t\tTVPThrowExceptionMessage(TVPNotSusiePlugin);\n\t}\n\telse if(!memcmp(api, \"00AM\", 4))\n\t{\n\t\tif(!GetPluginInfo || !IsSupported || !GetArchiveInfo || !GetFile)\n\t\t\tTVPThrowExceptionMessage(TVPNotSusiePlugin);\n\t}\n\telse\n\t{\n\t\tTVPThrowInternalError;\n\t}\n\n\t// check API version and dump copyright information\n\tchar buffer[256];\n\tchar buffer2[256];\n\n\tif(GetPluginInfo(0, buffer, 255) >= 4)\n\t{\n\t\tif(memcmp(buffer, api, 4))\n\t\t\tTVPThrowExceptionMessage(TVPNotSusiePlugin);\n\t}\n\telse\n\t{\n\t\tTVPThrowExceptionMessage(TVPNotSusiePlugin);\n\t}\n\n\tmemset(buffer, 0, 256);\n\tGetPluginInfo(1, buffer, 255);\n\tif(buffer[0]) TVPAddImportantLog( TVPFormatMessage(TVPInfoSusiePluginInfo,ttstr(buffer)) );\n\n\t// retrieve format information\n\ttjs_int i;\n\tfor(i = 0; ; i++)\n\t{\n\t\tint r = GetPluginInfo(2*i + 2, buffer, 255);\n\t\tif(r == 0) break;\n\t\tbuffer[255] = 0;\n\n\t\t// here buffer contains exetension information such as \"*.JPG\" \"*.RGB;*.Q0\"\n\t\t_strlwr(buffer);\n\n\t\t// split buffer to each extensions\n\t\tchar *p = buffer;\n\t\twhile((p = strstr(p, \"*.\")) != NULL)\n\t\t{\n\t\t\tp++;\n\t\t\tchar *b2 = buffer2;\n\t\t\twhile(*p && *p != ' ' && *p != ';')\n\t\t\t{\n\t\t\t\t*b2 = *p;\n\t\t\t\tb2++;\n\t\t\t\tp++;\n\t\t\t}\n\t\t\t*b2 = 0;\n\t\t\tExtensions.push_back(ttstr(buffer2));\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\ntTVPSusiePlugin::~tTVPSusiePlugin()\n{\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPSusiePicturePlugin\n//---------------------------------------------------------------------------\nclass tTVPSusiePicturePlugin : public tTVPSusiePlugin\n{\n\ttTVPBMPAlphaType AlphaType;\npublic:\n\ttTVPSusiePicturePlugin(HINSTANCE inst, tTVPBMPAlphaType alphatype);\n\t~tTVPSusiePicturePlugin();\n\n\ttTVPBMPAlphaType GetAlphaType() const { return AlphaType; }\n\n\tvoid Load(void *callbackdata,\n\t\ttTVPGraphicSizeCallback sizecallback,\n\t\ttTVPGraphicScanLineCallback scanlinecallback,\n\t\ttTJSBinaryStream *src,\n\t\ttjs_int keyidx,\n\t\ttTVPGraphicLoadMode mode);\n\n};\n//---------------------------------------------------------------------------\ntTVPSusiePicturePlugin::tTVPSusiePicturePlugin(HINSTANCE inst,\n\ttTVPBMPAlphaType alphatype) : tTVPSusiePlugin(inst, \"00IN\")\n{\n\t// member setup\n\tAlphaType = alphatype;\n}\n//---------------------------------------------------------------------------\ntTVPSusiePicturePlugin::~tTVPSusiePicturePlugin()\n{\n}\n//---------------------------------------------------------------------------\nvoid tTVPSusiePicturePlugin::Load(void *callbackdata,\n\t\ttTVPGraphicSizeCallback sizecallback,\n\t\ttTVPGraphicScanLineCallback scanlinecallback,\n\t\ttTJSBinaryStream *src,\n\t\ttjs_int keyidx,\n\t\ttTVPGraphicLoadMode mode)\n{\n\tbool bitmaplocked = false;\n\tHLOCAL bitmap = NULL;\n\tbool infolocked = false;\n\tHLOCAL info = NULL;\n\n\t// load source to memory\n\ttjs_uint64 size = src->GetSize();\n\ttjs_uint8 * source = new tjs_uint8[(tjs_int)size];\n\n\ttry\n\t{\n\t\tsrc->ReadBuffer(source, static_cast<tjs_uint>(size) );\n\n\t\t// call GetPicture\n\t\tint r = GetPicture((LPSTR)source, (long)size, 0x01, &info, &bitmap,\n\t\t\t(FARPROC)ProgressCallback, 0);\n\t\tif((r&0xff) != 0) TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(r));\n\n\t\t// setup bitmapinfoheader\n\t\tTVP_WIN_BITMAPINFOHEADER bi;\n\t\tmemset(&bi, 0, sizeof(bi));\n\t\tBITMAPINFOHEADER *srcbi = (BITMAPINFOHEADER *)LocalLock(info);\n\t\tinfolocked = true;\n\t\ttjs_int datasize = (tjs_int)LocalSize(bitmap);\n\t\tvoid * data = (void*) LocalLock(bitmap);\n\t\tbitmaplocked = true;\n\n\t\tif(srcbi->biSize == 12)\n\t\t{\n\t\t\t// OS/2 bitmap header\n\t\t\tbi.biSize = srcbi->biSize;\n\t\t\tbi.biWidth = srcbi->biWidth;\n\t\t\tbi.biHeight = srcbi->biHeight;\n\t\t\tbi.biPlanes = srcbi->biPlanes;\n\t\t\tbi.biBitCount = srcbi->biBitCount;\n\t\t\tbi.biClrUsed = 0;\n\t\t\tbi.biCompression = BI_RGB;\n\t\t}\n\t\telse if(srcbi->biSize == 40)\n\t\t{\n\t\t\t// Windows bitmap header\n\t\t\tbi.biSize = srcbi->biSize;\n\t\t\tbi.biWidth = srcbi->biWidth;\n\t\t\tbi.biHeight = srcbi->biHeight;\n\t\t\tbi.biPlanes = srcbi->biPlanes;\n\t\t\tbi.biBitCount = srcbi->biBitCount;\n\t\t\tbi.biCompression = srcbi->biCompression;\n\t\t\tbi.biSizeImage = srcbi->biSizeImage;\n\t\t\tbi.biXPelsPerMeter = srcbi->biXPelsPerMeter;\n\t\t\tbi.biYPelsPerMeter = srcbi->biYPelsPerMeter;\n\t\t\tbi.biClrUsed = srcbi->biClrUsed;\n\t\t\tbi.biClrImportant = srcbi->biClrImportant;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// not supported bitmap format\n\t\t\tTVPThrowExceptionMessage(TVPImageLoadError, (const tjs_char*)TVPSusiePluginUnsupportedBitmapHeader );\n\n\t\t}\n\n\t\t// create reference memory stream for bitmap pixel data\n\t\ttTVPMemoryStream memstream(data, datasize);\n\n\t\tif(bi.biClrUsed == 0 && bi.biBitCount <= 8)\n\t\t\tbi.biClrUsed = 1 << bi.biBitCount;\n\n\t\t// pass information to TVPInternalLoadBMP\n\t\tTVPInternalLoadBMP(callbackdata, sizecallback, scanlinecallback,\n\t\t\tbi, ((tjs_uint8*)srcbi) + bi.biSize, &memstream, keyidx, AlphaType,\n\t\t\t\tmode);\n\n\t}\n\tcatch(...)\n\t{\n\t\tdelete [] source;\n\t\tif(bitmaplocked) LocalUnlock(bitmap);\n\t\tif(bitmap) LocalFree(bitmap);\n\t\tif(infolocked) LocalUnlock(info);\n\t\tif(info) LocalFree(info);\n\t\tthrow;\n\t}\n\n\tdelete [] source;\n\tif(bitmaplocked) LocalUnlock(bitmap);\n\tif(bitmap) LocalFree(bitmap);\n\tif(infolocked) LocalUnlock(info);\n\tif(info) LocalFree(info);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Global/static data\n//---------------------------------------------------------------------------\ntypedef tTJSHashTable<HINSTANCE, tTVPSusiePicturePlugin*> tTVPSusiePluginList;\nstatic tTVPSusiePluginList TVPSusiePluginList;\n\nstatic void TVPDestroySusiePluginList()\n{\n\ttTVPSusiePluginList::tIterator i;\n\tfor(i = TVPSusiePluginList.GetFirst(); !i.IsNull(); i++)\n\t{\n\t\tdelete i.GetValue();\n\t}\n}\nstatic tTVPAtExit TVPDestroySusiePluginListAtExit\n\t(TVP_ATEXIT_PRI_CLEANUP, TVPDestroySusiePluginList);\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// TVPLoadViaSusiePlugin\n//---------------------------------------------------------------------------\nstatic void TVPLoadViaSusiePlugin(void* formatdata, void *callbackdata,\n\ttTVPGraphicSizeCallback sizecallback,\n\ttTVPGraphicScanLineCallback scanlinecallback,\n\ttTVPMetaInfoPushCallback metainfopushcallback,\n\ttTJSBinaryStream *src,\n\ttjs_int keyidx,\n\ttTVPGraphicLoadMode mode)\n{\n\ttTVPSusiePicturePlugin * plugin = (tTVPSusiePicturePlugin*)formatdata;\n\tplugin->Load(callbackdata, sizecallback, scanlinecallback, src, keyidx,\n\t\tmode);\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPLoadPictureSPI/TVPUnloadPictureSPI : load/unload spi\n//---------------------------------------------------------------------------\nvoid TVPLoadPictureSPI(HINSTANCE inst, tTVPBMPAlphaType alphatype)\n{\n\t// load specified Picture Susie plug-in.\n\ttTVPSusiePicturePlugin *spi = new tTVPSusiePicturePlugin(inst, alphatype);\n\n\tTVPSusiePluginList.Add(inst, spi);\n\n\tconst std::vector<ttstr> & exts = spi->GetExtensions();\n\tstd::vector<ttstr>::const_iterator i;\n\tfor(i = exts.begin(); i != exts.end(); i++)\n\t{\n\t\tTVPRegisterGraphicLoadingHandler(*i, TVPLoadViaSusiePlugin, NULL, NULL, NULL, (void*)spi);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPUnloadPictureSPI(HINSTANCE inst)\n{\n\t// unload specified Picture Susie plug-in from System.\n\ttTVPSusiePicturePlugin** p = TVPSusiePluginList.Find(inst);\n\n\tif(!p)\n\t\tTVPThrowExceptionMessage(TVPNotLoadedPlugin);\n\n\tconst std::vector<ttstr> & exts = (*p)->GetExtensions();\n\tstd::vector<ttstr>::const_iterator i;\n\tfor(i = exts.begin(); i != exts.end(); i++)\n\t{\n\t\tTVPUnregisterGraphicLoadingHandler(*i, TVPLoadViaSusiePlugin, NULL, NULL, NULL, (void*)*p);\n\t}\n\n\tTVPSusiePluginList.Delete(inst);\n\n\tdelete *p;\n}\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/GraphicsLoaderImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Graphics Loader ( loads graphic format from storage )\n//---------------------------------------------------------------------------\n\n#ifndef GraphicsLoaderImplH\n#define GraphicsLoaderImplH\n\n#include \"GraphicsLoaderIntf.h\"\n#if 0\n//---------------------------------------------------------------------------\n// tTVPSusiePlugin\n//---------------------------------------------------------------------------\nclass tTVPSusiePlugin\n{\nprotected:\n\tint (PASCAL * GetPluginInfo)(int infono, LPSTR buf,int buflen);\n\tint (PASCAL * IsSupported)(LPSTR filename, DWORD dw);\n\tint (PASCAL * GetPicture)(LPSTR buf, long len, unsigned int flag,\n\t\t\t  HANDLE *pHBInfo, HANDLE *pHBm,\n\t\t\t  FARPROC lpPrgressCallback, long lData);\n\tint (PASCAL * GetArchiveInfo)(LPSTR buf,long len,\n\t\t\tunsigned int flag, HLOCAL *lphInf);\n\tint (PASCAL * GetFile)(LPSTR src,long len, LPSTR dest,unsigned int flag,\n\t\t\t\tFARPROC prgressCallback, long lData);\n\n\tHINSTANCE ModuleInstance;\n\n\tstd::vector<ttstr> Extensions;\n\n\ttTVPSusiePlugin(HINSTANCE inst, const char *api);\n\tvirtual ~tTVPSusiePlugin();\n\n\tstatic int PASCAL ProgressCallback(int nNum,int nDenom,long lData) { return 0; }\n\npublic:\n\tconst std::vector<ttstr> & GetExtensions() const { return Extensions; }\n\n\tHINSTANCE GetModuleInstance() const { return ModuleInstance; }\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Susie Plug-in management functions\n// ( support of SPI for archive files is in StorageImpl.cpp )\n//---------------------------------------------------------------------------\nextern void TVPLoadPictureSPI(HINSTANCE inst, tTVPBMPAlphaType alphatype = batMulAlpha);\nextern void TVPUnloadPictureSPI(HINSTANCE inst);\n//---------------------------------------------------------------------------\n#endif\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/LayerBitmapImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Base Layer Bitmap implementation\n//---------------------------------------------------------------------------\n#define _USE_MATH_DEFINES\n#include \"tjsCommHead.h\"\n\n#include <memory>\n#include <stdlib.h>\n#include <math.h>\n\n#include \"LayerBitmapIntf.h\"\n#include \"LayerBitmapImpl.h\"\n#include \"MsgIntf.h\"\n#include \"ComplexRect.h\"\n#include \"tvpgl.h\"\n#include \"tjsHashSearch.h\"\n#include \"EventIntf.h\"\n#include \"SysInitImpl.h\"\n#include \"StorageIntf.h\"\n#include \"DebugIntf.h\"\n//#include \"WindowFormUnit.h\"\nvoid TVPInitWindowOptions();\n#include \"UtilStreams.h\"\n#include \"ConfigManager/IndividualConfigManager.h\"\n\n//#include \"FontSelectFormUnit.h\"\n\n#include \"StringUtil.h\"\n//#include \"TVPSysFont.h\"\n#include \"CharacterData.h\"\n#include \"PrerenderedFont.h\"\n#include \"FontSystem.h\"\n#include \"visual/FreeType.h\"\n#include \"FreeTypeFontRasterizer.h\"\n//#include \"GDIFontRasterizer.h\"\n#include \"BitmapBitsAlloc.h\"\n#include \"RenderManager.h\"\n\n//---------------------------------------------------------------------------\n// prototypes\n//---------------------------------------------------------------------------\nvoid TVPClearFontCache();\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// default FONT retrieve function\n//---------------------------------------------------------------------------\nFontSystem* TVPFontSystem = NULL;\nstatic tjs_int TVPGlobalFontStateMagic = 0;\n\t// this is for checking global font status' change\n\n\nenum {\n\tFONT_RASTER_FREE_TYPE,\n//\tFONT_RASTER_GDI,\n\tFONT_RASTER_EOT\n};\nstatic FontRasterizer* TVPFontRasterizers[FONT_RASTER_EOT];\nstatic bool TVPFontRasterizersInit = false;\nstatic tjs_int TVPCurrentFontRasterizers = FONT_RASTER_FREE_TYPE;\n//static tjs_int TVPCurrentFontRasterizers = FONT_RASTER_GDI;\nvoid TVPInializeFontRasterizers() {\n\tif( TVPFontRasterizersInit == false ) {\n\t\tTVPFontRasterizers[FONT_RASTER_FREE_TYPE] = new FreeTypeFontRasterizer();\n//\t\tTVPFontRasterizers[FONT_RASTER_GDI] = new GDIFontRasterizer();\n\n\t\tTVPFontSystem = new FontSystem();\n\t\tTVPFontRasterizersInit = true;\n\t}\n}\nvoid TVPUninitializeFontRasterizers() {\n\tfor( tjs_int i = 0; i < FONT_RASTER_EOT; i++ ) {\n\t\tif( TVPFontRasterizers[i] ) {\n\t\t\tTVPFontRasterizers[i]->Release();\n\t\t\tTVPFontRasterizers[i] = NULL;\n\t\t}\n\t}\n\tif( TVPFontSystem ) {\n\t\tdelete TVPFontSystem;\n\t\tTVPFontSystem = NULL;\n\t}\n}\nstatic tTVPAtExit\n\tTVPUninitializeFontRaster(TVP_ATEXIT_PRI_RELEASE, TVPUninitializeFontRasterizers);\n\nvoid TVPSetFontRasterizer( tjs_int index ) {\n\tif( TVPCurrentFontRasterizers != index && index >= 0 && index < FONT_RASTER_EOT ) {\n\t\tTVPCurrentFontRasterizers = index;\n\t\tTVPClearFontCache(); // X^CU؂ւ鎞ALbV̓NAĂ܂\n\t\tTVPGlobalFontStateMagic++; // ApplyFont 悤ɂ\n\t}\n}\ntjs_int TVPGetFontRasterizer() {\n\treturn TVPCurrentFontRasterizers;\n}\nFontRasterizer* GetCurrentRasterizer() {\n\treturn TVPFontRasterizers[TVPCurrentFontRasterizers];\n}\n\n//---------------------------------------------------------------------------\n#define TVP_CH_MAX_CACHE_COUNT 1300\n#define TVP_CH_MAX_CACHE_COUNT_LOW 100\n#define TVP_CH_MAX_CACHE_HASH_SIZE 512\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// Pre-rendered font management\n//---------------------------------------------------------------------------\ntTJSHashTable<ttstr, tTVPPrerenderedFont *> TVPPrerenderedFonts;\n\n\n\n//---------------------------------------------------------------------------\n// tTVPPrerenderedFontMap\n//---------------------------------------------------------------------------\nstruct tTVPPrerenderedFontMap\n{\n\ttTVPFont Font; // mapped font\n\ttTVPPrerenderedFont * Object; // prerendered font object\n};\nstatic std::vector<tTVPPrerenderedFontMap> TVPPrerenderedFontMapVector;\n//---------------------------------------------------------------------------\nvoid TVPMapPrerenderedFont(const tTVPFont & font, const ttstr & storage)\n{\n\t// map specified font to specified prerendered font\n\tttstr fn = TVPSearchPlacedPath(storage);\n\n\t// search or retrieve specified storage\n\ttTVPPrerenderedFont * object;\n\n\ttTVPPrerenderedFont ** found = TVPPrerenderedFonts.Find(fn);\n\tif(!found)\n\t{\n\t\t// not yet exist; create\n\t\tobject = new tTVPPrerenderedFont(fn);\n\t}\n\telse\n\t{\n\t\t// already exist\n\t\tobject = *found;\n\t\tobject->AddRef();\n\t}\n\n\t// search existing mapped font\n\tstd::vector<tTVPPrerenderedFontMap>::iterator i;\n\tfor(i = TVPPrerenderedFontMapVector.begin();\n\t\ti !=TVPPrerenderedFontMapVector.end(); i++)\n\t{\n\t\tif(i->Font == font)\n\t\t{\n\t\t\t// found font\n\t\t\t// replace existing\n\t\t\ti->Object->Release();\n\t\t\ti->Object = object;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(i == TVPPrerenderedFontMapVector.end())\n\t{\n\t\t// not found\n\t\ttTVPPrerenderedFontMap map;\n\t\tmap.Font = font;\n\t\tmap.Object = object;\n\t\tTVPPrerenderedFontMapVector.push_back(map); // add\n\t}\n\n\tTVPGlobalFontStateMagic ++; // increase magic number\n\n\tTVPClearFontCache(); // clear font cache\n}\n//---------------------------------------------------------------------------\nvoid TVPUnmapPrerenderedFont(const tTVPFont & font)\n{\n\t// unmap specified font\n\tstd::vector<tTVPPrerenderedFontMap>::iterator i;\n\tfor(i = TVPPrerenderedFontMapVector.begin();\n\t\ti !=TVPPrerenderedFontMapVector.end(); i++)\n\t{\n\t\tif(i->Font == font)\n\t\t{\n\t\t\t// found font\n\t\t\t// replace existing\n\t\t\ti->Object->Release();\n\t\t\tTVPPrerenderedFontMapVector.erase(i);\n\t\t\tTVPGlobalFontStateMagic ++; // increase magic number\n\t\t\tTVPClearFontCache();\n\t\t\treturn;\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPUnmapAllPrerenderedFonts()\n{\n\t// unmap all prerendered fonts\n\tstd::vector<tTVPPrerenderedFontMap>::iterator i;\n\tfor(i = TVPPrerenderedFontMapVector.begin();\n\t\ti !=TVPPrerenderedFontMapVector.end(); i++)\n\t{\n\t\ti->Object->Release();\n\t}\n\tTVPPrerenderedFontMapVector.clear();\n\tTVPGlobalFontStateMagic ++; // increase magic number\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit TVPUnmapAllPrerenderedFontsAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPUnmapAllPrerenderedFonts);\n//---------------------------------------------------------------------------\nstatic tTVPPrerenderedFont * TVPGetPrerenderedMappedFont(const tTVPFont &font)\n{\n\t// search mapped prerendered font\n\tstd::vector<tTVPPrerenderedFontMap>::iterator i;\n\tfor(i = TVPPrerenderedFontMapVector.begin();\n\t\ti !=TVPPrerenderedFontMapVector.end(); i++)\n\t{\n\t\tif(i->Font == font)\n\t\t{\n\t\t\t// found font\n\t\t\t// replace existing\n\t\t\ti->Object->AddRef();\n\n\t\t\t// note that the object is AddRefed\n\t\t\treturn i->Object;\n\t\t}\n\t}\n\treturn NULL;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntypedef tTJSRefHolder<tTVPCharacterData> tTVPCharacterDataHolder;\n\ntypedef\ntTJSHashCache<tTVPFontAndCharacterData, tTVPCharacterDataHolder,\n\ttTVPFontHashFunc, TVP_CH_MAX_CACHE_HASH_SIZE> tTVPFontCache;\ntTVPFontCache TVPFontCache(TVP_CH_MAX_CACHE_COUNT);\n//---------------------------------------------------------------------------\nvoid TVPSetFontCacheForLowMem()\n{\n\t// set character cache limit\n\tTVPFontCache.SetMaxCount(TVP_CH_MAX_CACHE_COUNT_LOW);\n}\n//---------------------------------------------------------------------------\nvoid TVPClearFontCache()\n{\n\tTVPFontCache.Clear();\n}\n//---------------------------------------------------------------------------\nstruct tTVPClearFontCacheCallback : public tTVPCompactEventCallbackIntf\n{\n\tvirtual void TJS_INTF_METHOD OnCompact(tjs_int level)\n\t{\n\t\tif(level >= TVP_COMPACT_LEVEL_MINIMIZE)\n\t\t{\n\t\t\t// clear the font cache on application minimize\n\t\t\tTVPClearFontCache();\n\t\t}\n\t}\n} static TVPClearFontCacheCallback;\nstatic bool TVPClearFontCacheCallbackInit = false;\n//---------------------------------------------------------------------------\nstatic tTVPCharacterData * TVPGetCharacter(const tTVPFontAndCharacterData & font,\n\ttTVPNativeBaseBitmap *bmp, tTVPPrerenderedFont *pfont, tjs_int aofsx, tjs_int aofsy)\n{\n\t// returns specified character data.\n\t// draw a character if needed.\n\n\t// compact interface initialization\n\tif(!TVPClearFontCacheCallbackInit)\n\t{\n\t\tTVPAddCompactEventHook(&TVPClearFontCacheCallback);\n\t\tTVPClearFontCacheCallbackInit = true;\n\t}\n\n\t// make hash and search over cache\n\ttjs_uint32 hash = tTVPFontCache::MakeHash(font);\n\n\ttTVPCharacterDataHolder * ptr = TVPFontCache.FindAndTouchWithHash(font, hash);\n\tif(ptr)\n\t{\n\t\t// found in the cache\n\t\treturn ptr->GetObject();\n\t}\n\n\t// not found in the cache\n\n\t// look prerendered font\n\tconst tTVPPrerenderedCharacterItem *pitem = NULL;\n\tif(pfont)\n\t\tpitem = pfont->Find(font.Character);\n\n\tif(pitem)\n\t{\n\t\t// prerendered font\n\t\ttTVPCharacterData *data = new tTVPCharacterData();\n\t\tdata->BlackBoxX = pitem->Width;\n\t\tdata->BlackBoxY = pitem->Height;\n\t\tdata->Metrics.CellIncX = pitem->IncX;\n\t\tdata->Metrics.CellIncY = pitem->IncY;\n\t\tdata->OriginX = pitem->OriginX + aofsx;\n\t\tdata->OriginY = -pitem->OriginY + aofsy;\n\n\t\tdata->Antialiased = font.Antialiased;\n\n\t\tdata->FullColored = false;\n\n\t\tdata->Blured = font.Blured;\n\t\tdata->BlurWidth = font.BlurWidth;\n\t\tdata->BlurLevel = font.BlurLevel;\n\n\t\ttry\n\t\t{\n\t\t\tif(data->BlackBoxX && data->BlackBoxY)\n\t\t\t{\n\t\t\t\t// render\n\t\t\t\ttjs_int newpitch =  (((pitem->Width -1)>>2)+1)<<2;\n\t\t\t\tdata->Pitch = newpitch;\n\n\t\t\t\tdata->Alloc(newpitch * data->BlackBoxY);\n\n\t\t\t\tpfont->Retrieve(pitem, data->GetData(), newpitch);\n\t\t\t\tdata->Gray = 256;\n\t\t\t\t// apply blur\n\t\t\t\tif(font.Blured) data->Blur(); // nasty ...\n\n\t\t\t\t// add to hash table\n\t\t\t\ttTVPCharacterDataHolder holder(data);\n\t\t\t\tTVPFontCache.AddWithHash(font, hash, holder);\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tdata->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\treturn data;\n\t}\n\telse\n\t{\n\t\t// render font\n\t\ttTVPCharacterData *data = GetCurrentRasterizer()->GetBitmap( font, aofsx, aofsy );\n\n\t\t// add to hash table\n\t\ttTVPCharacterDataHolder holder(data);\n\t\tTVPFontCache.AddWithHash(font, hash, holder);\n\t\treturn data;\n\t}\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTVPBitmap : internal bitmap object\n//---------------------------------------------------------------------------\n/*\n\timportant:\n\tNote that each lines must be started at tjs_uint32 ( 4bytes ) aligned address.\n\tThis is the default Windows bitmap allocate behavior.\n*/\ntTVPBitmap::tTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp)\n{\n\t// tTVPBitmap constructor\n\n\tTVPInitWindowOptions(); // ensure window/bitmap usage options are initialized\n\n\tRefCount = 1;\n\n\tAllocate(width, height, bpp); // allocate initial bitmap\n}\n//---------------------------------------------------------------------------\ntTVPBitmap::tTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp, void* bits)\n{\n\t// tTVPBitmap constructor\n\tTVPInitWindowOptions(); // ensure window/bitmap usage options are initialized\n\n\tRefCount = 1;\n\n\tBitmapInfo = new BitmapInfomation( width, height, bpp );\n\tWidth = width;\n\tHeight = height;\n\tPitchBytes = BitmapInfo->GetPitchBytes();\n\tPitchStep = PitchBytes;\n\n\t// set bitmap bits\n\ttry\n\t{\n\t\tBits = bits;\n\t\tif( bpp == 8 ) {\n\t\t\tPalette = new tjs_uint[DEFAULT_PALETTE_COUNT];\n\t\t\tActualPalCount = 0;\n\t\t} else {\n\t\t\tPalette = NULL;\n\t\t\tActualPalCount = 0;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdelete BitmapInfo;\n\t\tBitmapInfo = NULL;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPBitmap::~tTVPBitmap()\n{\n\ttTVPBitmapBitsAlloc::Free(Bits);\n\tdelete BitmapInfo;\n\tif( Palette ) delete Palette;\n}\n//---------------------------------------------------------------------------\ntTVPBitmap::tTVPBitmap(const tTVPBitmap & r)\n{\n\t// constructor for cloning bitmap\n\tTVPInitWindowOptions(); // ensure window/bitmap usage options are initialized\n\n\tRefCount = 1;\n\n\t// allocate bitmap which has the same metrics to r\n\tAllocate(r.GetWidth(), r.GetHeight(), r.GetBPP());\n\n\t// copy BitmapInfo\n\t*BitmapInfo = *r.BitmapInfo;\n\n\t// copy Bits\n\tif(r.Bits) memcpy(Bits, r.Bits, r.BitmapInfo->GetImageSize() );\n\tif(r.Palette) {\n\t\tmemcpy(Palette, r.Palette, sizeof(tjs_uint)*DEFAULT_PALETTE_COUNT );\n\t\tActualPalCount = r.ActualPalCount;\n\t}\n\n\t// copy pitch\n\tPitchBytes = r.PitchBytes;\n\tPitchStep = r.PitchStep;\n}\n//---------------------------------------------------------------------------\nvoid tTVPBitmap::Allocate(tjs_uint width, tjs_uint height, tjs_uint bpp)\n{\n\t// allocate bitmap bits\n\t// bpp must be 8 or 32\n\n\t// create BITMAPINFO\n\tBitmapInfo = new BitmapInfomation( width, height, bpp );\n\n\tWidth = width;\n\tHeight = height;\n\tPitchBytes = BitmapInfo->GetPitchBytes();\n\tPitchStep = PitchBytes;\n\n\t// allocate bitmap bits\n\ttry\n\t{\n\t\tBits = tTVPBitmapBitsAlloc::Alloc(BitmapInfo->GetImageSize(), width, height);\n\t\tif( bpp == 8 ) {\n\t\t\tPalette = new tjs_uint[DEFAULT_PALETTE_COUNT];\n\t\t\tActualPalCount = 0;\n\t\t} else {\n\t\t\tPalette = NULL;\n\t\t\tActualPalCount = 0;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tdelete BitmapInfo;\n\t\tBitmapInfo = NULL;\n\t\tthrow;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid * tTVPBitmap::GetScanLine(tjs_uint l) const\n{\n\tif((tjs_int)l>=BitmapInfo->GetHeight() )\n\t{\n\t\tTVPThrowExceptionMessage(TVPScanLineRangeOver, ttstr((tjs_int)l),\n\t\t\tttstr((tjs_int)BitmapInfo->GetHeight()-1));\n\t}\n\n\treturn l * PitchBytes + (tjs_uint8*)Bits;\n}\n//---------------------------------------------------------------------------\nvoid tTVPBitmap::SetPaletteCount( tjs_uint count ) {\n\tif( !Is8bit() ) TVPThrowExceptionMessage(TVPInvalidOperationFor32BPP);\n\tif( count >= DEFAULT_PALETTE_COUNT )\n\t\tTVPThrowExceptionMessage(TJSRangeError);\n\n\tActualPalCount = count;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTVPNativeBaseBitmap\n//---------------------------------------------------------------------------\ntTVPNativeBaseBitmap::tTVPNativeBaseBitmap(/*tjs_uint w, tjs_uint h, tjs_uint bpp*/)\n{\n\tTVPInializeFontRasterizers();\n\t// TVPFontRasterizer->AddRef(); TODO\n\n\t// TVPConstructDefaultFont();\n\tFont = TVPFontSystem->GetDefaultFont();\n\tPrerenderedFont = NULL;\n\t//LogFont = TVPDefaultLOGFONT;\n\tFontChanged = true;\n\tGlobalFontState = -1;\n\tTextWidth = TextHeight = 0;\n\t//Bitmap = new tTVPBitmap(w, h, bpp);\n}\n//---------------------------------------------------------------------------\ntTVPNativeBaseBitmap::tTVPNativeBaseBitmap(const tTVPNativeBaseBitmap & r)\n{\n\tTVPInializeFontRasterizers();\n\t// TVPFontRasterizer->AddRef(); TODO\n\n\tBitmap = r.Bitmap;\n\tif (Bitmap) Bitmap->AddRef();\n\n\tFont = r.Font;\n\tPrerenderedFont = NULL;\n\t//LogFont = TVPDefaultLOGFONT;\n\tFontChanged = true;\n\tTextWidth = TextHeight = 0;\n}\n//---------------------------------------------------------------------------\ntTVPNativeBaseBitmap::~tTVPNativeBaseBitmap()\n{\n\tif (Bitmap) Bitmap->Release();\n\tif(PrerenderedFont) PrerenderedFont->Release();\n\n\t// TVPFontRasterizer->Release(); TODO\n}\n//---------------------------------------------------------------------------\ntjs_uint tTVPNativeBaseBitmap::GetWidth() const\n{\n\treturn Bitmap->GetWidth();\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetWidth(tjs_uint w)\n{\n\tSetSize(w, Bitmap->GetHeight());\n}\n//---------------------------------------------------------------------------\ntjs_uint tTVPNativeBaseBitmap::GetHeight() const\n{\n\treturn Bitmap->GetHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetHeight(tjs_uint h)\n{\n\tSetSize(Bitmap->GetWidth(), h);\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetSize(tjs_uint w, tjs_uint h, bool keepimage)\n{\n\tif (w == 0) w = 1;\n\tif (h == 0) h = 1;\n\tif (Bitmap->GetWidth() != w || Bitmap->GetHeight() != h)\n\t{\n\t\t// create a new bitmap and copy existing bitmap\n\t\tiTVPTexture2D *newbitmap;\n\t\tif (keepimage)\n\t\t\tnewbitmap = GetRenderManager()->CreateTexture2D(w, h, Bitmap);\n\t\telse\n\t\t\tnewbitmap = GetRenderManager()->CreateTexture2D(nullptr, 0, w, h, Bitmap->GetFormat());\n#if 0\n\t\ttTVPBitmap *newbitmap = new tTVPBitmap(w, h, Bitmap->GetBPP());\n\n\t\tif(keepimage)\n\t\t{\n\t\t\ttjs_int pixelsize = Bitmap->Is32bit() ? 4 : 1;\n\t\t\ttjs_int lh = h < Bitmap->GetHeight() ?\n\t\t\t\th : Bitmap->GetHeight();\n\t\t\ttjs_int lw = w < Bitmap->GetWidth() ?\n\t\t\t\tw : Bitmap->GetWidth();\n\t\t\ttjs_int cs = lw * pixelsize;\n\t\t\ttjs_int i;\n\t\t\tfor(i = 0; i < lh; i++)\n\t\t\t{\n\t\t\t\tvoid * ds = newbitmap->GetScanLine(i);\n\t\t\t\tvoid * ss = Bitmap->GetScanLine(i);\n\n\t\t\t\tmemcpy(ds, ss, cs);\n\t\t\t}\n\t\t\tif( pixelsize == 1 )\n\t\t\t\tmemcpy(newbitmap->GetPalette(), Bitmap->GetPalette(), sizeof(tjs_uint)*tTVPBitmap::DEFAULT_PALETTE_COUNT);\n\t\t}\n#endif\n\t\tBitmap->Release();\n\t\tBitmap = newbitmap;\n\n\t\tFontChanged = true;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetSizeAndImageBuffer(tTVPBitmap* bmp)\n{\n\t// create a new bitmap and copy existing bitmap\n\tiTVPTexture2D *newbitmap = GetRenderManager()->CreateTexture2D(bmp);\n\tBitmap->Release();\n\tBitmap = newbitmap;\n\tFontChanged = true;\n}\n//---------------------------------------------------------------------------\ntjs_uint tTVPNativeBaseBitmap::GetBPP() const\n{\n\tswitch (Bitmap->GetFormat()) {\n\tcase TVPTextureFormat::Gray:\n\t\treturn 8;\n\tcase TVPTextureFormat::RGBA:\n\t\treturn 32;\n\tcase TVPTextureFormat::RGB:\n\t\treturn 24;\n\tdefault:\n\t\t// error !\n\t\treturn 0;\n\t}\n#if 0\n\treturn Bitmap->GetBPP();\n#endif\n}\n//---------------------------------------------------------------------------\nbool tTVPNativeBaseBitmap::Is32BPP() const\n{\n\treturn Bitmap->GetFormat() != TVPTextureFormat::Gray; \n}\n//---------------------------------------------------------------------------\nbool tTVPNativeBaseBitmap::Is8BPP() const\n{\n\treturn Bitmap->GetFormat() == TVPTextureFormat::Gray;\n}\n\nbool tTVPNativeBaseBitmap::IsOpaque() const\n{\n\treturn Bitmap->IsOpaque();\n}\n\n//---------------------------------------------------------------------------\nbool tTVPNativeBaseBitmap::Assign(const tTVPNativeBaseBitmap &rhs)\n{\n\tif(this == &rhs || Bitmap == rhs.Bitmap) return false;\n\n\tBitmap->Release();\n\tBitmap = rhs.Bitmap;\n\tBitmap->AddRef();\n\n\tFont = rhs.Font;\n\tFontChanged = true; // informs internal font information is invalidated\n\n\n\treturn true; // changed\n}\n//---------------------------------------------------------------------------\nbool tTVPNativeBaseBitmap::AssignBitmap(const tTVPNativeBaseBitmap &rhs)\n{\n\t// assign only bitmap\n\tif(this == &rhs || Bitmap == rhs.Bitmap) return false;\n\n\tBitmap->Release();\n\tBitmap = rhs.Bitmap;\n\tBitmap->AddRef();\n\n\t// font information are not copyed\n\tFontChanged = true; // informs internal font information is invalidated\n\n\treturn true;\n}\nbool tTVPNativeBaseBitmap::AssignTexture(iTVPTexture2D *tex)\n{\n\tif (Bitmap == tex) return false;\n\n\tBitmap->Release();\n\tBitmap = tex;// CreateTexture2D(bmp);\n\tBitmap->AddRef();\n\n    // font information are not copyed\n    FontChanged = true; // informs internal font information is invalidated\n\n    return true;\n}\n//---------------------------------------------------------------------------\nconst void * tTVPNativeBaseBitmap::GetScanLine(tjs_uint l) const\n{\n\treturn Bitmap->GetScanLineForRead(l);\n}\n//---------------------------------------------------------------------------\nvoid * tTVPNativeBaseBitmap::GetScanLineForWrite(tjs_uint l)\n{\n\tIndepend();\n\treturn Bitmap->GetScanLineForWrite(l);\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPNativeBaseBitmap::GetPitchBytes() const\n{\n\tif (Bitmap)\n\t\treturn Bitmap->GetPitch();\n\treturn 0;\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::Independ()\n{\n\t// sever Bitmap's image sharing\n\tif (Bitmap->IsIndependent() && !Bitmap->IsStatic()) return;\n\tiTVPTexture2D *newb = GetRenderManager()->CreateTexture2D(Bitmap->GetWidth(), Bitmap->GetHeight(), Bitmap);\n\tBitmap->Release();\n\tBitmap = newb;\n\tFontChanged = true; // informs internal font information is invalidated\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::IndependNoCopy()\n{\n\t// indepent the bitmap, but not to copy the original bitmap\n\tif (!Bitmap->IsStatic() && Bitmap->IsIndependent()) return;\n\tRecreate();\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::Recreate()\n{\n\tRecreate(Bitmap->GetWidth(), Bitmap->GetHeight(), Bitmap->GetFormat() == TVPTextureFormat::Gray ? 8 : 32);\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::Recreate(tjs_uint w, tjs_uint h, tjs_uint bpp)\n{\n\tBitmap->Release();\n\tBitmap = GetRenderManager()->CreateTexture2D(nullptr, 0, w, h, bpp == 8 ? TVPTextureFormat::Gray : TVPTextureFormat::RGBA);\n\tFontChanged = true; // informs internal font information is invalidated\n}\n\nbool tTVPNativeBaseBitmap::IsIndependent() const\n{\n\treturn Bitmap->IsIndependent() && !Bitmap->IsStatic();\n}\n#if 0\n//---------------------------------------------------------------------------\ntjs_uint tTVPNativeBaseBitmap::GetPalette( tjs_uint index ) const {\n\tif( !Is8BPP() ) TVPThrowExceptionMessage(TVPInvalidOperationFor32BPP);\n\tif( index >= Bitmap->GetPaletteCount() )\n\t\tTVPThrowExceptionMessage(TJSRangeError);\n\n\treturn Bitmap->GetPalette()[index];\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetPalette( tjs_uint index, tjs_uint color ) {\n\tif( !Is8BPP() ) TVPThrowExceptionMessage(TVPInvalidOperationFor32BPP);\n\tif( index >= Bitmap->GetPaletteCount() ) {\n\t\tBitmap->SetPaletteCount( index+1 );\n\t}\n\tBitmap->GetPalette()[index] = color;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::ApplyFont()\n{\n\t// apply font\n\tif(FontChanged || GlobalFontState != TVPGlobalFontStateMagic)\n\t{\n\t\tIndepend();\n\n\t\tFontChanged = false;\n\t\tGlobalFontState = TVPGlobalFontStateMagic;\n\t\tCachedText.Clear();\n\t\tTextWidth = TextHeight = 0;\n\n\t\tif(PrerenderedFont) PrerenderedFont->Release();\n\t\tPrerenderedFont = TVPGetPrerenderedMappedFont(Font);\n\n\t\t// compute ascent offset\n\t\tGetCurrentRasterizer()->ApplyFont( this, true );\n\t\ttjs_int ascent = GetCurrentRasterizer()->GetAscentHeight();\n\t\tRadianAngle = Font.Angle * (M_PI/1800);\n\t\tdouble angle90 = RadianAngle + M_PI_2;\n\t\tAscentOfsX = static_cast<tjs_int>(-cos(angle90) * ascent);\n\t\tAscentOfsY = static_cast<tjs_int>(sin(angle90) * ascent);\n\n\t\t// compute font hash\n\t\tFontHash = tTJSHashFunc<ttstr>::Make(Font.Face);\n\t\tFontHash ^= Font.Height ^ Font.Flags ^ Font.Angle;\n\t}\n\telse\n\t{\n\t\tGetCurrentRasterizer()->ApplyFont( this, false );\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::SetFont(const tTVPFont &font)\n{\n\tFont = font;\n\tFontChanged = true;\n}\n//---------------------------------------------------------------------------\nextern void TVPGetAllFontList(std::vector<ttstr>& list);\nvoid tTVPNativeBaseBitmap::GetFontList(tjs_uint32 flags, std::vector<ttstr> &list)\n{\n\tApplyFont();\n\tstd::vector<ttstr> ansilist;\n\tTVPGetAllFontList(ansilist);\n\tfor(std::vector<ttstr>::iterator i = ansilist.begin(); i != ansilist.end(); i++)\n\t\tlist.push_back(*i);\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::MapPrerenderedFont(const ttstr & storage)\n{\n\tApplyFont();\n\tTVPMapPrerenderedFont(Font, storage);\n\tFontChanged = true;\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::UnmapPrerenderedFont()\n{\n\tApplyFont();\n\tTVPUnmapPrerenderedFont(Font);\n\tFontChanged = true;\n}\n//---------------------------------------------------------------------------\nstruct tTVPDrawTextData\n{\n\ttTVPRect rect;\n\ttjs_int bmppitch;\n\ttjs_int opa;\n\tbool holdalpha;\n\ttTVPBBBltMethod bltmode;\n};\n\nstatic iTVPTexture2D *_CharacterTexture = nullptr, *_CharacterTextureRGBA = nullptr;\n\nbool tTVPNativeBaseBitmap::InternalBlendText(\n    tTVPCharacterData *data, tTVPDrawTextData *dtdata, tjs_uint32 color, const tTVPRect &srect, tTVPRect &drect)\n{\n    // blend to the bitmap\n    tjs_int pitch = data->Pitch;\n    //tjs_uint8 *sl = (tjs_uint8*)GetScanLineForWrite(drect.top);\n    tjs_int h = drect.bottom - drect.top;\n    tjs_int w = drect.right - drect.left;\n\ttjs_uint8 *bp = data->GetData() + pitch * srect.top;\n\n\tiTVPRenderMethod * method = nullptr;\n\tint opa_id, clr_id;\n#define GEMTHOD_OPA_CLR(n) \\\n\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(#n); \\\n\tstatic int _opa_id = _method->EnumParameterID(\"opacity\"); \\\n\tstatic int _clr_id = _method->EnumParameterID(\"color\"); \\\n\tmethod = _method; opa_id = _opa_id; clr_id = _clr_id;\n\n\tstatic bool fastGPURoute = !TVPIsSoftwareRenderManager()\n\t\t&& !IndividualConfigManager::GetInstance()->GetValue<bool>(\"ogl_accurate_render\", false);\n\n\tiTVPTexture2D *pTexSrc;\n\tif (fastGPURoute && dtdata->bltmode == bmAlphaOnAlpha && dtdata->opa > 0) {\n\t\t// convert to addalpha bitmap\n\t\ttTVPBitmap* tmp = new tTVPBitmap(w, h, 32);\n\t\ttjs_int spitch = pitch;\n\t\ttjs_int dpitch = tmp->GetPitch();\n\t\ttjs_uint8 *src = bp;\n\t\ttjs_uint8* dst = (tjs_uint8*)tmp->GetBits();\n\t\tfor (tjs_int y = 0; y < h; ++y) {\n\t\t\tfor (tjs_int x = 0; x < w; ++x) {\n\t\t\t\t((tjs_uint32*)dst)[x] = (color & 0xFFFFFF) | (src[x] << 24);\n\t\t\t}\n\t\t\tTVPConvertAlphaToAdditiveAlpha((tjs_uint32*)dst, w);\n\t\t\tdst += dpitch;\n\t\t\tsrc += spitch;\n\t\t}\n\t\tif (_CharacterTextureRGBA) {\n\t\t\tif (_CharacterTextureRGBA->GetFormat() != TVPTextureFormat::RGBA) {\n\t\t\t\t_CharacterTextureRGBA->Release();\n\t\t\t\t_CharacterTextureRGBA = nullptr;\n\t\t\t}\n\t\t}\n\t\tif (!_CharacterTextureRGBA) {\n\t\t\t_CharacterTextureRGBA = GetRenderManager()->CreateTexture2D(tmp->GetBits(), dpitch, w, h, TVPTextureFormat::RGBA, RENDER_CREATE_TEXTURE_FLAG_NO_COMPRESS);\n\t\t} else if (_CharacterTextureRGBA->GetInternalWidth() < w || _CharacterTextureRGBA->GetInternalHeight() < h) {\n\t\t\t_CharacterTextureRGBA->Release();\n\t\t\t_CharacterTextureRGBA = GetRenderManager()->CreateTexture2D(tmp->GetBits(), dpitch, w, h, TVPTextureFormat::RGBA, RENDER_CREATE_TEXTURE_FLAG_NO_COMPRESS);\n\t\t} else {\n\t\t\t_CharacterTextureRGBA->Update(tmp->GetBits(), TVPTextureFormat::RGBA, dpitch, tTVPRect(0, 0, w, h));\n\t\t}\n\n\t\ttmp->Release();\n\n\t\tGEMTHOD_OPA_CLR(AlphaBlend_a);\n\t\tmethod->SetParameterOpa(opa_id, dtdata->opa);\n\t\tpTexSrc = _CharacterTextureRGBA;\n\t} else {\n\t\tif (dtdata->bltmode == bmAlphaOnAlpha) {\n\t\t\tif (dtdata->opa > 0) {\n\t\t\t\tGEMTHOD_OPA_CLR(ApplyColorMap_d);\n\t\t\t} else {\n\t\t\t\t// opacity removal\n\t\t\t\tGEMTHOD_OPA_CLR(RemoveOpacity);\n\t\t\t}\n\t\t} else if (dtdata->bltmode == bmAlphaOnAddAlpha) {\n\t\t\tGEMTHOD_OPA_CLR(ApplyColorMap_a);\n\t\t} else {\n\t\t\tGEMTHOD_OPA_CLR(ApplyColorMap);\n\t\t}\n\n\t\t// blend to the texture\n\t\tif (!_CharacterTexture) {\n\t\t\t_CharacterTexture = GetRenderManager()->CreateTexture2D(nullptr, pitch, w, h, TVPTextureFormat::Gray);\n\t\t} else if (_CharacterTexture->GetInternalWidth() < w || _CharacterTexture->GetInternalHeight() < h) {\n\t\t\t_CharacterTexture->Release();\n\t\t\t_CharacterTexture = GetRenderManager()->CreateTexture2D(nullptr, pitch, w, h, TVPTextureFormat::Gray);\n\t\t}\n\t\t_CharacterTexture->Update(bp, TVPTextureFormat::Gray, pitch, tTVPRect(0, 0, w, h));\n\n\t\tmethod->SetParameterOpa(opa_id, dtdata->opa);\n\t\tmethod->SetParameterColor4B(clr_id, color);\n\n\t\tpTexSrc = _CharacterTexture;\n\t}\n#if 0\n    if (pShader->isBlendEnabled() || !IsIndependent()) {\n\t\tiTVPTexture2D *origTex = GetTexture();\n\t\tiTVPTexture2D *tex = GetTextureForRender();\n        TVPRenderTexture2(pShader,\n            tex, drect,\n            origTex, drect,\n            _CharacterTexture, texRect(0, 0, w, h));\n    } else { // optimize for independent texture\n\t\tiTVPTexture2D *tmptex = TVPCreateTextureForRender(drect.get_width(), drect.get_height());\n\t\tiTVPTexture2D *tex = GetTexture();\n        texRect rc(drect);\n        rc.x = 0; rc.y = 0;\n        TVPCopyTexture(\n            tmptex, rc,\n            tex, drect);\n        TVPRenderTexture2(pShader,\n            tex, drect,\n            tmptex, rc,\n            _CharacterTexture, texRect(0, 0, w, h));\n        tmptex->Release();\n    }\n#endif\n\ttRenderTexRectArray::Element src_tex[] = {\n\t\ttRenderTexRectArray::Element(pTexSrc, tTVPRect(0, 0, w, h))\n\t};\n\tTVPGetRenderManager()->OperateRect(method,\n\t\tGetTextureForRender(method->IsBlendTarget(), &drect), nullptr, drect,\n\t\ttRenderTexRectArray(src_tex));\n    return true;\n}\n\nbool tTVPNativeBaseBitmap::InternalDrawText(tTVPCharacterData *data, tjs_int x,\n\ttjs_int y, tjs_uint32 color, tTVPDrawTextData *dtdata, tTVPRect &drect)\n{\n\t// setup destination and source rectangle\n\tdrect.left = x + data->OriginX;\n\tdrect.top = y + data->OriginY;\n\tdrect.right = drect.left + data->BlackBoxX;\n\tdrect.bottom = drect.top + data->BlackBoxY;\n\n\ttTVPRect srect;\n\tsrect.left = srect.top = 0;\n\tsrect.right = data->BlackBoxX;\n\tsrect.bottom = data->BlackBoxY;\n\n\t// check boundary\n\tif(drect.left < dtdata->rect.left)\n\t{\n\t\tsrect.left += (dtdata->rect.left - drect.left);\n\t\tdrect.left = dtdata->rect.left;\n\t}\n\n\tif(drect.right > dtdata->rect.right)\n\t{\n\t\tsrect.right -= (drect.right - dtdata->rect.right);\n\t\tdrect.right = dtdata->rect.right;\n\t}\n\n\tif(srect.left >= srect.right) return false; // not drawable\n\n\tif(drect.top < dtdata->rect.top)\n\t{\n\t\tsrect.top += (dtdata->rect.top - drect.top);\n\t\tdrect.top = dtdata->rect.top;\n\t}\n\n\tif(drect.bottom > dtdata->rect.bottom)\n\t{\n\t\tsrect.bottom -= (drect.bottom - dtdata->rect.bottom);\n\t\tdrect.bottom = dtdata->rect.bottom;\n\t}\n\n\tif(srect.top >= srect.bottom) return false; // not drawable\n\n    return InternalBlendText(data, dtdata, color, srect, drect);\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::DrawGlyph(iTJSDispatch2* glyph, const tTVPRect &destrect, tjs_int x, tjs_int y,\n\t\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa,\n\t\t\tbool holdalpha, bool aa, tjs_int shlevel,\n\t\t\ttjs_uint32 shadowcolor,\n\t\t\ttjs_int shwidth, tjs_int shofsx, tjs_int shofsy,\n\t\t\ttTVPComplexRect *updaterects )\n{\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(bltmode == bmAlphaOnAlpha)\n\t{\n\t\tif(opa < -255) opa = -255;\n\t\tif(opa > 255) opa = 255;\n\t}\n\telse\n\t{\n\t\tif(opa < 0) opa = 0;\n\t\tif(opa > 255 ) opa = 255;\n\t}\n\n\tif(opa == 0) return; // nothing to do\n\n\n\ttjs_int itemcount;\n\ttTJSVariant tmp;\n\tif(TJS_SUCCEEDED(glyph->PropGet(TJS_MEMBERMUSTEXIST, TJS_W(\"count\"), 0, &tmp, glyph)))\n\t\titemcount = tmp;\n\telse\n\t\titemcount = 0;\n\n\tif( itemcount < 8 ) TVPThrowExceptionMessage( TVPFaildGlyphForDrawGlyph );\n\n\tenum {\n\t\tGLYPH_WIDTH,\n\t\tGLYPH_HEIGHT,\n\t\tGLYPH_ORIGINX,\n\t\tGLYPH_ORIGINY,\n\t\tGLYPH_INCX,\n\t\tGLYPH_INCY,\n\t\tGLYPH_INC,\n\t\tGLYPH_BITMAP,\n\t\tGLYPH_COLORS,\n\t\tGLYPH_EOT\n\t};\n\ttjs_int glyphitem[7];\n\tfor( tjs_int i = 0; i < 7; i++ ) {\n\t\tif(TJS_FAILED(glyph->PropGetByNum(TJS_MEMBERMUSTEXIST, i, &tmp, glyph)))\n\t\t\tTVPThrowExceptionMessage( TVPFaildGlyphForDrawGlyph );\n\t\tglyphitem[i] = tmp;\n\t}\n\n\tif(TJS_FAILED(glyph->PropGetByNum(TJS_MEMBERMUSTEXIST, GLYPH_BITMAP, &tmp, glyph)))\n\t\tTVPThrowExceptionMessage( TVPFaildGlyphForDrawGlyph );\n\n\ttjs_int numcolor = 256;\n\tif( itemcount >= 9 ) {\n\t\tif(TJS_FAILED(glyph->PropGetByNum(TJS_MEMBERMUSTEXIST, GLYPH_COLORS, &tmp, glyph)))\n\t\t\tTVPThrowExceptionMessage( TVPFaildGlyphForDrawGlyph );\n\t\tnumcolor = tmp;\n\t}\n\ttTJSVariantOctet *o = tmp.AsOctetNoAddRef();\n\n\tIndepend();\n\tApplyFont();\n\n\ttTVPDrawTextData dtdata;\n\tdtdata.rect = destrect;\n\tdtdata.bmppitch = GetPitchBytes();\n\tdtdata.bltmode = bltmode;\n\tdtdata.opa = opa;\n\tdtdata.holdalpha = holdalpha;\n\n\ttTVPCharacterData* data = NULL;\n\ttTVPCharacterData* shadow = NULL;\n\ttry {\n\t\ttGlyphMetrics metrics;\n\t\tmetrics.CellIncX = glyphitem[GLYPH_INCX];\n\t\tmetrics.CellIncY = glyphitem[GLYPH_INCY];\n\t\tdata = new tTVPCharacterData( o->GetData(), glyphitem[GLYPH_WIDTH],\n\t\t\tglyphitem[GLYPH_ORIGINX] + AscentOfsX, -glyphitem[GLYPH_ORIGINY] + AscentOfsY,\n\t\t\tglyphitem[GLYPH_WIDTH], glyphitem[GLYPH_HEIGHT],\n\t\t\tmetrics, numcolor > 256 );\n\n\t\tdata->Antialiased = aa;\n\t\tdata->Blured = false;\n\t\tdata->BlurWidth = shwidth;\n\t\tdata->BlurLevel = shlevel;\n\t\tdata->Gray = numcolor;\n\t\tif( shlevel != 0 ) {\n\t\t\tif( shlevel == 255 && shwidth == 0 ) {\n\t\t\t\t// normal shadow\n\t\t\t\tshadow = data;\n\t\t\t\tshadow->AddRef();\n\t\t\t} else {\n\t\t\t\t// blured shadow\n\t\t\t\tshadow = new tTVPCharacterData( o->GetData(), glyphitem[GLYPH_WIDTH],\n\t\t\t\t\tglyphitem[GLYPH_ORIGINX] + AscentOfsX, -glyphitem[GLYPH_ORIGINY] + AscentOfsY,\n\t\t\t\t\tglyphitem[GLYPH_WIDTH], glyphitem[GLYPH_HEIGHT],\n\t\t\t\t\tmetrics, numcolor > 256 );\n\t\t\t\tshadow->Antialiased = aa;\n\t\t\t\tshadow->Blured = true;\n\t\t\t\tshadow->BlurWidth = shwidth;\n\t\t\t\tshadow->BlurLevel = shlevel;\n\t\t\t\tshadow->Gray = numcolor;\n\t\t\t\tif( !shadow->FullColored ) shadow->Blur();\n\t\t\t}\n\t\t}\n\n\t\tif(data)\n\t\t{\n\n\t\t\tif(data->BlackBoxX != 0 && data->BlackBoxY != 0)\n\t\t\t{\n\t\t\t\ttTVPRect drect;\n\t\t\t\ttTVPRect shadowdrect;\n\n\t\t\t\tbool shadowdrawn = false;\n\n\t\t\t\tif(shadow)\n\t\t\t\t{\n\t\t\t\t\tshadowdrawn = InternalDrawText(shadow, x + shofsx, y + shofsy,\n\t\t\t\t\t\tshadowcolor, &dtdata, shadowdrect);\n\t\t\t\t}\n\n\t\t\t\tbool drawn = InternalDrawText(data, x, y, color, &dtdata, drect);\n\t\t\t\tif(updaterects)\n\t\t\t\t{\n\t\t\t\t\tif(!shadowdrawn)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(drawn) updaterects->Or(drect);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(drawn)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTVPRect d;\n\t\t\t\t\t\t\tTVPUnionRect(&d, drect, shadowdrect);\n\t\t\t\t\t\t\tupdaterects->Or(d);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdaterects->Or(shadowdrect);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(data) data->Release();\n\t\tif(shadow) shadow->Release();\n\t\tthrow;\n\t}\n\n\tif(data) data->Release();\n\tif(shadow) shadow->Release();\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::DrawTextSingle(const tTVPRect &destrect,\n\ttjs_int x, tjs_int y, const ttstr &text,\n\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa,\n\t\t\tbool holdalpha, bool aa, tjs_int shlevel,\n\t\t\ttjs_uint32 shadowcolor,\n\t\t\ttjs_int shwidth, tjs_int shofsx, tjs_int shofsy,\n\t\t\ttTVPComplexRect *updaterects)\n{\n\t// text drawing function for single character\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(bltmode == bmAlphaOnAlpha)\n\t{\n\t\tif(opa < -255) opa = -255;\n\t\tif(opa > 255) opa = 255;\n\t}\n\telse\n\t{\n\t\tif(opa < 0) opa = 0;\n\t\tif(opa > 255 ) opa = 255;\n\t}\n\n\tif(opa == 0) return; // nothing to do\n\n\tIndepend();\n\n\tApplyFont();\n\n\tconst tjs_char *p = text.c_str();\n\ttTVPDrawTextData dtdata;\n\tdtdata.rect = destrect;\n\tdtdata.bmppitch = GetPitchBytes();\n\tdtdata.bltmode = bltmode;\n\tdtdata.opa = opa;\n\tdtdata.holdalpha = holdalpha;\n\n\ttTVPFontAndCharacterData font;\n\tfont.Font = Font;\n\tfont.Antialiased = aa;\n\tfont.Hinting = true;\n\tfont.BlurLevel = shlevel;\n\tfont.BlurWidth = shwidth;\n\tfont.FontHash = FontHash;\n\n\tfont.Character = *p;\n\n\tfont.Blured = false;\n\ttTVPCharacterData * shadow = NULL;\n\ttTVPCharacterData * data = NULL;\n\n\ttry\n\t{\n\t\tdata = TVPGetCharacter(font, this, PrerenderedFont, AscentOfsX, AscentOfsY);\n\n\t\tif(shlevel != 0)\n\t\t{\n\t\t\tif(shlevel == 255 && shwidth == 0)\n\t\t\t{\n\t\t\t\t// normal shadow\n\t\t\t\tshadow = data;\n\t\t\t\tshadow->AddRef();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// blured shadow\n\t\t\t\tfont.Blured = true;\n\t\t\t\tshadow =\n\t\t\t\t\tTVPGetCharacter(font, this, PrerenderedFont, AscentOfsX, AscentOfsY);\n\t\t\t}\n\t\t}\n\n\n\t\tif(data)\n\t\t{\n\n\t\t\tif(data->BlackBoxX != 0 && data->BlackBoxY != 0)\n\t\t\t{\n\t\t\t\ttTVPRect drect;\n\t\t\t\ttTVPRect shadowdrect;\n\n\t\t\t\tbool shadowdrawn = false;\n\n\t\t\t\tif(shadow)\n\t\t\t\t{\n\t\t\t\t\tshadowdrawn = InternalDrawText(shadow, x + shofsx, y + shofsy,\n\t\t\t\t\t\tshadowcolor, &dtdata, shadowdrect);\n\t\t\t\t}\n\n\t\t\t\tbool drawn = InternalDrawText(data, x, y, color, &dtdata, drect);\n\t\t\t\tif(updaterects)\n\t\t\t\t{\n\t\t\t\t\tif(!shadowdrawn)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(drawn) updaterects->Or(drect);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(drawn)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttTVPRect d;\n\t\t\t\t\t\t\tTVPUnionRect(&d, drect, shadowdrect);\n\t\t\t\t\t\t\tupdaterects->Or(d);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tupdaterects->Or(shadowdrect);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(data) data->Release();\n\t\tif(shadow) shadow->Release();\n\t\tthrow;\n\t}\n\n\tif(data) data->Release();\n\tif(shadow) shadow->Release();\n}\n//---------------------------------------------------------------------------\n// structure for holding data for a character\nstruct tTVPCharacterDrawData\n{\n\ttTVPCharacterData * Data; // main character data\n\ttTVPCharacterData * Shadow; // shadow character data\n\ttjs_int X, Y;\n\ttTVPRect ShadowRect;\n\tbool ShadowDrawn;\n\n\ttTVPCharacterDrawData(\n\t\ttTVPCharacterData * data,\n\t\ttTVPCharacterData * shadow,\n\t\ttjs_int x, tjs_int y)\n\t{\n\t\tData = data;\n\t\tShadow = shadow;\n\t\tX = x;\n\t\tY = y;\n\t\tShadowDrawn = false;\n\n\t\tif(Data) Data->AddRef();\n\t\tif(Shadow) Shadow->AddRef();\n\t}\n\n\t~tTVPCharacterDrawData()\n\t{\n\t\tif(Data) Data->Release();\n\t\tif(Shadow) Shadow->Release();\n\t}\n\n\ttTVPCharacterDrawData(const tTVPCharacterDrawData & rhs)\n\t{\n\t\tData = Shadow = NULL;\n\t\t*this = rhs;\n\t}\n\n\tvoid operator = (const tTVPCharacterDrawData & rhs)\n\t{\n\t\tX = rhs.X;\n\t\tY = rhs.Y;\n\t\tShadowRect = rhs.ShadowRect;\n\t\tShadowDrawn = rhs.ShadowDrawn;\n\n\t\tif(Data != rhs.Data)\n\t\t{\n\t\t\tif(Data) Data->Release();\n\t\t\tData = rhs.Data;\n\t\t\tif(Data) Data->AddRef();\n\t\t}\n\t\tif(Shadow != rhs.Shadow)\n\t\t{\n\t\t\tif(Shadow) Shadow->Release();\n\t\t\tShadow = rhs.Shadow;\n\t\t\tif(Shadow) Shadow->AddRef();\n\t\t}\n\t}\n};\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::DrawTextMultiple(const tTVPRect &destrect,\n\ttjs_int x, tjs_int y, const ttstr &text,\n\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa,\n\t\t\tbool holdalpha, bool aa, tjs_int shlevel,\n\t\t\ttjs_uint32 shadowcolor,\n\t\t\ttjs_int shwidth, tjs_int shofsx, tjs_int shofsy,\n\t\t\ttTVPComplexRect *updaterects)\n{\n\t// text drawing function for multiple characters\n\n\tif(!Is32BPP()) TVPThrowExceptionMessage(TVPInvalidOperationFor8BPP);\n\n\tif(bltmode == bmAlphaOnAlpha)\n\t{\n\t\tif(opa < -255) opa = -255;\n\t\tif(opa > 255) opa = 255;\n\t}\n\telse\n\t{\n\t\tif(opa < 0) opa = 0;\n\t\tif(opa > 255 ) opa = 255;\n\t}\n\n\tif(opa == 0) return; // nothing to do\n\n\tIndepend();\n\n\tApplyFont();\n\n\tconst tjs_char *p = text.c_str();\n\ttTVPDrawTextData dtdata;\n\tdtdata.rect = destrect;\n\tdtdata.bmppitch = GetPitchBytes();\n\tdtdata.bltmode = bltmode;\n\tdtdata.opa = opa;\n\tdtdata.holdalpha = holdalpha;\n\n\ttTVPFontAndCharacterData font;\n\tfont.Font = Font;\n\tfont.Antialiased = aa;\n\tfont.Hinting = true;\n\tfont.BlurLevel = shlevel;\n\tfont.BlurWidth = shwidth;\n\tfont.FontHash = FontHash;\n\n\n\tstd::vector<tTVPCharacterDrawData> drawdata;\n\tdrawdata.reserve(text.GetLen());\n\n\t// prepare all drawn characters\n\twhile(*p) // while input string is remaining\n\t{\n\t\tfont.Character = *p;\n\n\t\tfont.Blured = false;\n\t\ttTVPCharacterData * data = NULL;\n\t\ttTVPCharacterData * shadow = NULL;\n\t\ttry\n\t\t{\n\t\t\tdata =\n\t\t\t\tTVPGetCharacter(font, this, PrerenderedFont, AscentOfsX, AscentOfsY);\n\n\t\t\tif(data)\n\t\t\t{\n\t\t\t\tif(shlevel != 0)\n\t\t\t\t{\n\t\t\t\t\tif(shlevel == 255 && shwidth == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// normal shadow\n\t\t\t\t\t\t// shadow is the same as main character data\n\t\t\t\t\t\tshadow = data;\n\t\t\t\t\t\tshadow->AddRef();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// blured shadow\n\t\t\t\t\t\tfont.Blured = true;\n\t\t\t\t\t\tshadow =\n\t\t\t\t\t\t\tTVPGetCharacter(font, this, PrerenderedFont, AscentOfsX, AscentOfsY);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tif(data->BlackBoxX != 0 && data->BlackBoxY != 0)\n\t\t\t\t{\n\t\t\t\t\t// append to array\n\t\t\t\t\tdrawdata.push_back(tTVPCharacterDrawData(data, shadow, x, y));\n\t\t\t\t}\n\n\t\t\t\t// step to the next character position\n\t\t\t\tx += data->Metrics.CellIncX;\n\t\t\t\tif(data->Metrics.CellIncY != 0)\n\t\t\t\t{\n\t\t\t\t\t// Windows 9x returns negative CellIncY.\n\t\t\t\t\t// so we must verify whether CellIncY is proper.\n\t\t\t\t\tif(Font.Angle < 1800)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(data->Metrics.CellIncY > 0) data->Metrics.CellIncY = - data->Metrics.CellIncY;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(data->Metrics.CellIncY < 0) data->Metrics.CellIncY = - data->Metrics.CellIncY;\n\t\t\t\t\t}\n\t\t\t\t\ty += data->Metrics.CellIncY;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\t if(data) data->Release();\n\t\t\t if(shadow) shadow->Release();\n\t\t\t throw;\n\t\t}\n\t\tif(data) data->Release();\n\t\tif(shadow) shadow->Release();\n\n\t\tp++;\n\t}\n\n\t// draw shadows first\n\tif(shlevel != 0)\n\t{\n\t\tfor(std::vector<tTVPCharacterDrawData>::iterator i = drawdata.begin();\n\t\t\ti != drawdata.end(); i++)\n\t\t{\n\t\t\ttTVPCharacterData * shadow = i->Shadow;\n\n\t\t\tif(shadow)\n\t\t\t{\n\t\t\t\ti->ShadowDrawn = InternalDrawText(shadow, i->X + shofsx, i->Y + shofsy,\n\t\t\t\t\tshadowcolor, &dtdata, i->ShadowRect);\n\t\t\t}\n\t\t}\n\t}\n\n\t// then draw main characters\n\t// and compute returning update rectangle\n\tfor(std::vector<tTVPCharacterDrawData>::iterator i = drawdata.begin();\n\t\ti != drawdata.end(); i++)\n\t{\n\t\ttTVPCharacterData * data = i->Data;\n\t\ttTVPRect drect;\n\n\t\tbool drawn = InternalDrawText(data, i->X, i->Y, color, &dtdata, drect);\n\t\tif(updaterects)\n\t\t{\n\t\t\tif(!i->ShadowDrawn)\n\t\t\t{\n\t\t\t\tif(drawn) updaterects->Or(drect);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(drawn)\n\t\t\t\t{\n\t\t\t\t\ttTVPRect d;\n\t\t\t\t\tTVPUnionRect(&d, drect, i->ShadowRect);\n\t\t\t\t\tupdaterects->Or(d);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tupdaterects->Or(i->ShadowRect);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::GetTextSize(const ttstr & text)\n{\n\tApplyFont();\n\n\tif(text != CachedText)\n\t{\n\t\tCachedText = text;\n\n\t\tif(PrerenderedFont)\n\t\t{\n\t\t\ttjs_uint width = 0;\n\t\t\tconst tjs_char *buf = text.c_str();\n\t\t\twhile(*buf)\n\t\t\t{\n\t\t\t\tconst tTVPPrerenderedCharacterItem * item =\n\t\t\t\t\tPrerenderedFont->Find(*buf);\n\t\t\t\tif(item != NULL)\n\t\t\t\t{\n\t\t\t\t\twidth += item->Inc;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttjs_int w, h;\n\t\t\t\t\tGetCurrentRasterizer()->GetTextExtent( *buf, w, h );\n\t\t\t\t\twidth += w;\n\t\t\t\t}\n\t\t\t\tbuf++;\n\t\t\t}\n\t\t\tTextWidth = width;\n\t\t\tTextHeight = std::abs(Font.Height);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttjs_uint width = 0;\n\t\t\tconst tjs_char *buf = text.c_str();\n\n\t\t\twhile(*buf)\n\t\t\t{\n\t\t\t\ttjs_int w, h;\n\t\t\t\tGetCurrentRasterizer()->GetTextExtent( *buf, w, h );\n\t\t\t\twidth += w;\n\t\t\t\tbuf++;\n\t\t\t}\n\t\t\tTextWidth = width;\n\t\t\tTextHeight = std::abs(Font.Height);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPNativeBaseBitmap::GetTextWidth(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn TextWidth;\n}\n//---------------------------------------------------------------------------\ntjs_int tTVPNativeBaseBitmap::GetTextHeight(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn TextHeight;\n}\n//---------------------------------------------------------------------------\ndouble tTVPNativeBaseBitmap::GetEscWidthX(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn cos(RadianAngle) * TextWidth;\n}\n//---------------------------------------------------------------------------\ndouble tTVPNativeBaseBitmap::GetEscWidthY(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn sin(RadianAngle) * (-TextWidth);\n}\n//---------------------------------------------------------------------------\ndouble tTVPNativeBaseBitmap::GetEscHeightX(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn sin(RadianAngle) * TextHeight;\n}\n//---------------------------------------------------------------------------\ndouble tTVPNativeBaseBitmap::GetEscHeightY(const ttstr & text)\n{\n\tGetTextSize(text);\n\treturn cos(RadianAngle) * TextHeight;\n}\n//---------------------------------------------------------------------------\nvoid tTVPNativeBaseBitmap::GetFontGlyphDrawRect( const ttstr & text, struct tTVPRect& area )\n{\n\tApplyFont();\n\tGetCurrentRasterizer()->GetGlyphDrawRect( text, area );\n}\niTVPTexture2D * tTVPNativeBaseBitmap::GetTextureForRender(bool isBlendTarget, const tTVPRect *rc) {\n\tif (isBlendTarget || !rc) Independ();\n\telse {\n\t\tint w = Bitmap->GetWidth(), h = Bitmap->GetHeight();\n\t\tif (rc->left == 0 && rc->top == 0 && rc->right >= w && rc->bottom >= h) {\n\t\t\tIndependNoCopy();\n\t\t} else {\n\t\t\tIndepend();\n\t\t}\n\t}\n\treturn GetTexture();\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/win32/LayerBitmapImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Base Layer Bitmap implementation\n//---------------------------------------------------------------------------\n#ifndef LayerBitmapImplH\n#define LayerBitmapImplH\n\n#include \"tvpfontstruc.h\"\n#include \"ComplexRect.h\"\n\n#include \"BitmapInfomation.h\"\n\n//---------------------------------------------------------------------------\nextern void TVPSetFontCacheForLowMem();\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTVPBitmap : internal bitmap object\n//---------------------------------------------------------------------------\nclass tTVPBitmap\n{\npublic:\n\tstatic const tjs_int DEFAULT_PALETTE_COUNT = 256;\nprivate:\n\ttjs_int RefCount;\n\n\tvoid * Bits; // pointer to bitmap bits\n\tBitmapInfomation *BitmapInfo; // DIB information\n\n\ttjs_int PitchBytes; // bytes required in a line\n\ttjs_int PitchStep; // step bytes to next(below) line\n\ttjs_int Width; // actual width\n\ttjs_int Height; // actual height\n\n\ttjs_int ActualPalCount;\n\ttjs_uint* Palette;\n\npublic:\n\ttTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp);\n\t// for async load\n\t// @param bits : tTVPBitmapBitsAlloc::AllocŊmۂ̂gp邱\n\ttTVPBitmap(tjs_uint width, tjs_uint height, tjs_uint bpp, void* bits);\n\n\ttTVPBitmap(const tTVPBitmap & r);\n\n\t~tTVPBitmap();\n\n\tvoid Allocate(tjs_uint width, tjs_uint height, tjs_uint bpp);\n\n\tvoid AddRef(void)\n\t{\n\t\tRefCount ++;\n\t}\n\n\tvoid Release(void)\n\t{\n\t\tif(RefCount == 1)\n\t\t\tdelete this;\n\t\telse\n\t\t\tRefCount--;\n\t}\n\n\ttjs_uint GetWidth() const { return Width; }\n\ttjs_uint GetHeight() const { return Height; }\n\n\ttjs_uint GetBPP() const { return BitmapInfo->GetBPP(); }\n\tbool Is32bit() const { return BitmapInfo->Is32bit(); }\n\tbool Is8bit() const { return BitmapInfo->Is8bit(); }\n\n\n\tvoid * GetScanLine(tjs_uint l) const;\n\n\ttjs_int GetPitch() const { return PitchStep; }\n\n\tbool IsIndependent() const { return RefCount == 1; }\n\n\tconst BitmapInfomation* GetBitmapInfomation() const { return BitmapInfo; }\n#ifdef _WIN32\n\tconst TVPBITMAPINFO * GetBITMAPINFO() const { return BitmapInfo->GetBITMAPINFO(); }\n\tconst TVPBITMAPINFOHEADER * GetBITMAPINFOHEADER() const { return (const TVPBITMAPINFOHEADER*)(BitmapInfo->GetBITMAPINFO()); }\n#endif\n\n\tconst void * GetBits() const { return Bits; }\n\tconst tjs_uint* GetPalette() const { return Palette; };\n\ttjs_uint* GetPalette() { return Palette; };\n\ttjs_uint GetPaletteCount() const { return ActualPalCount; };\n\tvoid SetPaletteCount( tjs_uint count );\n\n\tbool IsOpaque = false;\n};\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTVPNativeBaseBitmap\n//---------------------------------------------------------------------------\nclass iTVPTexture2D;\nclass tTVPComplexRect;\nclass tTVPCharacterData;\nstruct tTVPDrawTextData;\nclass tTVPPrerenderedFont;\nclass tTVPNativeBaseBitmap\n{\npublic:\n\ttTVPNativeBaseBitmap(/*tjs_uint w, tjs_uint h, tjs_uint bpp*/);\n\ttTVPNativeBaseBitmap(const tTVPNativeBaseBitmap & r);\n\tvirtual ~tTVPNativeBaseBitmap();\n\n\t/* metrics */\n\ttjs_uint GetWidth() const ;\n\tvoid SetWidth(tjs_uint w);\n\ttjs_uint GetHeight() const;\n\tvoid SetHeight(tjs_uint h);\n\n\tvoid SetSize(tjs_uint w, tjs_uint h, bool keepimage = true);\n\t// for async load\n\t// @param bits : tTVPBitmapBitsAlloc::AllocŊmۂ̂gp邱\n\tvoid SetSizeAndImageBuffer(tTVPBitmap* bmp);\n\n\t/* color depth */\n\ttjs_uint GetBPP() const;\n\n\tbool Is32BPP() const;\n\tbool Is8BPP() const;\n\tbool IsOpaque() const;\n\n\t/* assign */\n\tbool Assign(const tTVPNativeBaseBitmap &rhs) ;\n\tbool AssignBitmap(const tTVPNativeBaseBitmap &rhs) ; // assigns only bitmap\n\tbool AssignTexture(iTVPTexture2D *tex);\n\n\t/* scan line */\n\tconst void * GetScanLine(tjs_uint l) const;\n\tvoid * GetScanLineForWrite(tjs_uint l);\n\ttjs_int GetPitchBytes() const;\n\n\n\t/* object lifetime management */\n\tvoid Independ();\n\tvoid IndependNoCopy();\n\tvoid Recreate();\n\tvoid Recreate(tjs_uint w, tjs_uint h, tjs_uint bpp);\n\n\tbool IsIndependent() const;\n\n\t/* other utilities */\n\tiTVPTexture2D * GetTexture() const { return Bitmap; }\n\tvirtual iTVPTexture2D *GetTextureForRender(bool isBlendTarget, const tTVPRect *rc);\n#if 0\n\ttjs_uint GetPalette( tjs_uint index ) const;\n\tvoid SetPalette( tjs_uint index, tjs_uint color );\n#endif\n\t/* font and text functions */\nprivate:\n\ttTVPFont Font;\n\tbool FontChanged;\n\ttjs_int GlobalFontState;\n\n\t// v--- these can be recreated in ApplyFont if FontChanged flag is set\n\ttTVPPrerenderedFont *PrerenderedFont;\n\ttjs_int AscentOfsX;\n\ttjs_int AscentOfsY;\n\tdouble RadianAngle;\n\ttjs_uint32 FontHash;\n\t// ^---\n\n\tvoid ApplyFont();\n\npublic:\n\tvoid SetFont(const tTVPFont &font);\n\tconst tTVPFont & GetFont() const { return Font; };\n\n\tvoid GetFontList(tjs_uint32 flags, std::vector<ttstr> &list);\n\n\tvoid MapPrerenderedFont(const ttstr & storage);\n\tvoid UnmapPrerenderedFont();\n\nprivate:\n    bool InternalBlendText(tTVPCharacterData *data, tTVPDrawTextData *dtdata, tjs_uint32 color, const tTVPRect &srect, tTVPRect &drect);\n\n\tbool InternalDrawText(tTVPCharacterData *data, tjs_int x,\n\t\ttjs_int y, tjs_uint32 shadowcolor,tTVPDrawTextData *dtdata, tTVPRect &drect);\n\npublic:\n\tvoid DrawTextSingle(const tTVPRect &destrect, tjs_int x, tjs_int y, const ttstr &text,\n\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa = 255,\n\t\t\tbool holdalpha = true, bool aa = true, tjs_int shlevel = 0,\n\t\t\ttjs_uint32 shadowcolor = 0,\n\t\t\ttjs_int shwidth = 0, tjs_int shofsx = 0, tjs_int shofsy = 0,\n\t\t\ttTVPComplexRect *updaterects = NULL);\n\tvoid DrawTextMultiple(const tTVPRect &destrect, tjs_int x, tjs_int y, const ttstr &text,\n\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa = 255,\n\t\t\tbool holdalpha = true, bool aa = true, tjs_int shlevel = 0,\n\t\t\ttjs_uint32 shadowcolor = 0,\n\t\t\ttjs_int shwidth = 0, tjs_int shofsx = 0, tjs_int shofsy = 0,\n\t\t\ttTVPComplexRect *updaterects = NULL);\n\tvoid DrawText(const tTVPRect &destrect, tjs_int x, tjs_int y, const ttstr &text,\n\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa = 255,\n\t\t\tbool holdalpha = true, bool aa = true, tjs_int shlevel = 0,\n\t\t\ttjs_uint32 shadowcolor = 0,\n\t\t\ttjs_int shwidth = 0, tjs_int shofsx = 0, tjs_int shofsy = 0,\n\t\t\ttTVPComplexRect *updaterects = NULL)\n\t{\n\t\ttjs_int len = text.GetLen();\n\t\tif(len == 0) return;\n\t\tif(len >= 2)\n\t\t\tDrawTextMultiple(\n\t\t\t\tdestrect, x, y, text,\n\t\t\t\tcolor, bltmode, opa,\n\t\t\t\tholdalpha, aa, shlevel,\n\t\t\t\tshadowcolor, shwidth, shofsx, shofsy,\n\t\t\t\tupdaterects);\n\t\telse    /* if len == 1 */\n\t\t\tDrawTextSingle(\n\t\t\t\tdestrect, x, y, text,\n\t\t\t\tcolor, bltmode, opa,\n\t\t\t\tholdalpha, aa, shlevel,\n\t\t\t\tshadowcolor, shwidth, shofsx, shofsy,\n\t\t\t\tupdaterects);\n\t}\n\tvoid DrawGlyph(iTJSDispatch2* glyph, const tTVPRect &destrect, tjs_int x, tjs_int y,\n\t\t\ttjs_uint32 color, tTVPBBBltMethod bltmode, tjs_int opa = 255,\n\t\t\tbool holdalpha = true, bool aa = true, tjs_int shlevel = 0,\n\t\t\ttjs_uint32 shadowcolor = 0,\n\t\t\ttjs_int shwidth = 0, tjs_int shofsx = 0, tjs_int shofsy = 0,\n\t\t\ttTVPComplexRect *updaterects = NULL);\n\n\nprivate:\n\ttjs_int TextWidth;\n\ttjs_int TextHeight;\n\tttstr CachedText;\n\n\tvoid GetTextSize(const ttstr & text);\n\npublic:\n\ttjs_int GetTextWidth(const ttstr & text);\n\ttjs_int GetTextHeight(const ttstr & text);\n\tdouble GetEscWidthX(const ttstr & text);\n\tdouble GetEscWidthY(const ttstr & text);\n\tdouble GetEscHeightX(const ttstr & text);\n\tdouble GetEscHeightY(const ttstr & text);\n\tvoid GetFontGlyphDrawRect( const ttstr & text, struct tTVPRect& area );\n\nprotected:\n\t//tTVPBitmap *Bitmap;\n\tiTVPTexture2D *Bitmap;\npublic:\n\tvoid operator =(const tTVPNativeBaseBitmap &rhs) { Assign(rhs); }\n\tvirtual class iTVPRenderManager* GetRenderManager() = 0;\n};\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/LayerImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n#include \"LayerImpl.h\"\n#include \"MsgIntf.h\"\n\n#include \"TVPColor.h\"\n\n//---------------------------------------------------------------------------\n//  convert color identifier or TVP system color to/from actual color\n//---------------------------------------------------------------------------\ntjs_uint32 TVPToActualColor(tjs_uint32 color)\n{\n\tif(color & 0xff000000)\n\t{\n\t\tcolor = ColorToRGB( color ); // system color to RGB\n\t\t// convert byte order to 0xRRGGBB since ColorToRGB's return value is in\n\t\t// a format of 0xBBGGRR.\n\t\treturn ((color&0xff)<<16) + (color&0xff00) + ((color&0xff0000)>>16);\n\t}\n\telse\n\t{\n\t\treturn color;\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_uint32 TVPFromActualColor(tjs_uint32 color)\n{\n\tcolor &= 0xffffff;\n\treturn color;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Layer\n//---------------------------------------------------------------------------\ntTJSNI_Layer::tTJSNI_Layer(void)\n{\n}\n//---------------------------------------------------------------------------\ntTJSNI_Layer::~tTJSNI_Layer()\n{\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_Layer::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\treturn tTJSNI_BaseLayer::Construct(numparams, param, tjs_obj);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD\ntTJSNI_Layer::Invalidate()\n{\n\ttTJSNI_BaseLayer::Invalidate();\n}\n//---------------------------------------------------------------------------\n#if 0\n#pragma pack(push, 1)\nHRGN tTJSNI_Layer::CreateMaskRgn(tjs_uint threshold)\n{\n\t// create a region according with the mask value of the layer bitmap.\n\t// based on  <builder-ctl@venus13.aid.kyushu-id.ac.jp> builder ML 14870\n\t// Mr. Nakamura's code\n\n\tstruct tRegionData\n\t{\n\t\tDWORD Size, iType, Count, RgnSize;\n\t\tRECT Bounds;\n\t\tRECT Rects[4000];\n\n\t\tHRGN CreateRegion()\n\t\t{\n\t\t\tXFORM Form;\n\t\t\tForm.eM11 = 1; Form.eM12 = 0; Form.eM21 = 0; Form.eM22 = 1;\n\t\t\tForm.eDx = 0; Form.eDy = 0;\n\t\t\tRgnSize = Count * 16;\n\t\t\treturn ExtCreateRegion(&Form, 32 + Count * 16, (RGNDATA *)this);\n\t\t}\n\t};\n\n\tint i, j, w, h;\n\tint sx, ex;\n\ttTVPBaseBitmap *MainImage = GetMainImage();\n\tconst tjs_uint32 *pRGBQ;\n\tHRGN Rgn;\n\tstd::vector<HRGN> RgnList;\n\ttRegionData Data;\n\n\tif(!MainImage) TVPThrowExceptionMessage(TVPNotDrawableLayerType);\n\n\tw = MainImage->GetWidth(); h = MainImage->GetHeight();\n\n\tData.Size = 32; Data.iType = RDH_RECTANGLES;\n\tData.Count = 0;\n\tData.Bounds.left = 0;\n\tData.Bounds.top = 0;\n\tData.Bounds.right = w;\n\tData.Bounds.bottom = h;\n\n\tfor (j = 0; j < h; j++)\n\t{\n\t\tpRGBQ = (const tjs_uint32 *)MainImage->GetScanLine(j);\n\t\tsx = -1; /*ex = -1;*/\n\n\t\tfor (i = 0; i < w; i++)\n\t\t{\n\n\t\t\tif ( (*pRGBQ>>24) >= threshold )\n\t\t\t{\n\t\t\t\tif ( sx == -1 ) sx = i;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tex = i;\n\t\t\t\tif (sx != -1 )\n\t\t\t\t{\n\t\t\t\t\tif (Data.Count == 4000)\n\t\t\t\t\t{\n\t\t\t\t\t\tRgn = Data.CreateRegion();\n\t\t\t\t\t\tRgnList.push_back(Rgn);\n\t\t\t\t\t\tData.Count = 0;\n\t\t\t\t\t}\n\t\t\t\t\tRECT &r = Data.Rects[Data.Count];\n\t\t\t\t\tr.left = sx;\n\t\t\t\t\tr.top = j;\n\t\t\t\t\tr.right = ex;\n\t\t\t\t\tr.bottom = j + 1;\n\t\t\t\t\tData.Count++;\n\t\t\t\t\tsx = -1; /*ex = -1;*/\n\t\t\t\t}\n\t\t\t}\n\t\t\tpRGBQ++;\n\t\t}\n\t\tif ( sx != -1)\n\t\t{\n\t\t\tif (Data.Count == 4000)\n\t\t\t{\n\t\t\t\tRgn = Data.CreateRegion();\n\t\t\t\tRgnList.push_back(Rgn);\n\t\t\t\tData.Count = 0;\n\t\t\t}\n\t\t\tRECT &r = Data.Rects[Data.Count];\n\t\t\tr.left = sx;\n\t\t\tr.top = j;\n\t\t\tr.right = w;\n\t\t\tr.bottom = j + 1;\n\t\t\tData.Count++;\n\t\t}\n\t}\n\n\tif (Data.Count > 0)\n\t{\n\t\tRgn = Data.CreateRegion();\n\t\tRgnList.push_back(Rgn);\n\t}\n\n\tRgn = CreateRectRgn(0, 0, 0, 0);\n\tfor (tjs_uint i = 0; i < RgnList.size(); i++)\n\t{\n\t\tCombineRgn(Rgn, Rgn, HRGN(RgnList[i]), RGN_OR);\n\t\tDeleteObject(HRGN(RgnList[i]));\n\t}\n\n\treturn Rgn;\n}\n#pragma pack(pop)\n//---------------------------------------------------------------------------\n#endif\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_Layer::CreateNativeInstance : returns proper instance object\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Layer::CreateNativeInstance()\n{\n\treturn new tTJSNI_Layer();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Layer\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Layer()\n{\n\treturn new tTJSNC_Layer();\n}\n//---------------------------------------------------------------------------\n\n// utility functions for custom plugins\ntTJSNI_Layer* tTJSNI_Layer::FromVariant(const tTJSVariant& var) {\n\treturn FromObject(var.AsObjectNoAddRef());\n}\n\ntTJSNI_Layer* tTJSNI_Layer::FromObject(iTJSDispatch2* obj)\n{\n\ttTJSNI_Layer * lay = nullptr;\n\tif (obj) {\n\t\tif (TJS_FAILED(obj->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\ttTJSNC_Layer::ClassID, (iTJSNativeInstance**)&lay)))\n\t\t\tTVPThrowExceptionMessage(TVPSpecifyLayer);\n\t}\n\treturn lay;\n}\n"
  },
  {
    "path": "src/core/visual/win32/LayerImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Layer Management\n//---------------------------------------------------------------------------\n#ifndef LayerImplH\n#define LayerImplH\n\n\n#include \"LayerIntf.h\"\n//---------------------------------------------------------------------------\n// tTJSNI_Layer\n//---------------------------------------------------------------------------\nclass tTJSNI_Layer : public tTJSNI_BaseLayer\n{\npublic:\n\ttTJSNI_Layer(void);\n\t~tTJSNI_Layer();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\tstatic tTJSNI_Layer* FromVariant(const tTJSVariant& var);\n\tstatic tTJSNI_Layer* FromObject(iTJSDispatch2* obj);\n\t//HRGN CreateMaskRgn(tjs_uint threshold);\n};\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/MenuItemImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"MenuItem\" class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n\n#include \"EventIntf.h\"\n#include \"MenuItemImpl.h\"\n#include \"MsgIntf.h\"\n#include \"WindowIntf.h\"\n#include \"Application.h\"\n#include \"tjsDictionary.h\"\n#include \"vkdefine.h\"\n#include \"ScriptMgnIntf.h\"\n#include <map>\n\nstatic std::map<tTVInteger, iTJSDispatch2*> MENU_LIST;\nstatic void AddMenuDispatch(tTVInteger hWnd, iTJSDispatch2* menu) {\n\tMENU_LIST.insert(std::map<tTVInteger, iTJSDispatch2*>::value_type(hWnd, menu));\n}\niTJSDispatch2* TVPGetMenuDispatch(tTVInteger hWnd) {\n\tstd::map<tTVInteger, iTJSDispatch2*>::iterator i = MENU_LIST.find(hWnd);\n\tif (i != MENU_LIST.end()) {\n\t\treturn i->second;\n\t}\n\treturn NULL;\n}\nstatic void DelMenuDispatch(tTVInteger hWnd) {\n\tMENU_LIST.erase(hWnd);\n}\nstatic bool _IsWindow(tTVInteger hWnd) {\n\ttjs_int count = TVPGetWindowCount();\n\tfor (tjs_int i = 0; i < count; ++i) {\n\t\tif (TVPGetWindowListAt(i) == (tTJSNI_Window*)(hWnd))\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void UpdateMenuList() {\n\tstd::map<tTVInteger, iTJSDispatch2*>::iterator i = MENU_LIST.begin();\n\tfor (; i != MENU_LIST.end();) {\n\t\ttTVInteger hWnd = i->first;\n\t\tbool exist = _IsWindow(hWnd);\n\t\tif (exist == false) {\n\t\t\t// ȤˤʤʤäWindow\n\t\t\tstd::map<tTVInteger, iTJSDispatch2*>::iterator target = i;\n\t\t\ti++;\n\t\t\tiTJSDispatch2* menu = target->second;\n\t\t\tMENU_LIST.erase(target);\n\t\t\tmenu->Release();\n\t\t\t//TVPDeleteAcceleratorKeyTable(hWnd);\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n}\n\nclass WindowMenuProperty : public tTJSDispatch {\n\ttjs_error TJS_INTF_METHOD PropGet(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, tTJSVariant *result, iTJSDispatch2 *objthis) {\n\t\ttTJSVariant var;\n\t\tif (TJS_FAILED(objthis->PropGet(0, TJS_W(\"HWND\"), NULL, &var, objthis))) {\n\t\t\treturn TJS_E_INVALIDOBJECT;\n\t\t}\n\t\ttTVInteger hWnd = var.AsInteger();\n\t\tiTJSDispatch2* menu = TVPGetMenuDispatch(hWnd);\n\t\tif (menu == NULL) {\n\t\t\tUpdateMenuList();\n\t\t\tmenu = TVPCreateMenuItemObject(objthis);\n\t\t\tAddMenuDispatch(hWnd, menu);\n\t\t}\n\t\t*result = tTJSVariant(menu, menu);\n\t\treturn TJS_S_OK;\n\t}\n\ttjs_error TJS_INTF_METHOD PropSet(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tTJSVariant *param, iTJSDispatch2 *objthis) {\n\t\treturn TJS_E_ACCESSDENYED;\n\t}\n} *gWindowMenuProperty;\n\n//---------------------------------------------------------------------------\n// tTJSNI_MenuItem\n//---------------------------------------------------------------------------\ntTJSNI_MenuItem::tTJSNI_MenuItem()\n{\n\tIsChecked = false;\n\tIsAttched = true;\n\tIsEnabled = true;\n\tIsRadio = false;\n\tIsVisible = true;\n\tGroupIndex = 0;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD tTJSNI_MenuItem::Construct(tjs_int numparams,\n\ttTJSVariant **param, iTJSDispatch2 *tjs_obj)\n{\n\tinherited::Construct(numparams, param, tjs_obj);\n\n\t// create or attach MenuItem object\n\tif(Window)\n\t{\n\t\t//MenuItem = Window->GetRootMenuItem();\n\t\tIsAttched = true;\n\t}\n\telse\n\t{\n// \t\tMenuItem = new TMenuItem();\n// \t\tMenuItem->OnClick = std::bind(&tTJSNI_MenuItem::MenuItemClick, this);\n\t\tIsAttched = false;\n\t}\n\n\t// fetch initial caption\n\tif(!Window && numparams >= 2)\n\t{\n\t\tCaption = *param[1];\n\t\t//MenuItem->setCaption (Caption);\n\t}\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_MenuItem::Invalidate()\n{\n\t// invalidate inherited\n\tinherited::Invalidate();  // this sets Owner = NULL\n\n\t// delete VCL object\n\t//if (!IsAttched && MenuItem) delete MenuItem, MenuItem = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::MenuItemClick()\n{\n\t// VCL event handler\n\t// post to the event queue\n\tTVPPostInputEvent(new tTVPOnMenuItemClickInputEvent(this));\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MenuItem::CanDeliverEvents() const\n{\n\t// returns whether events can be delivered\n\t//if(!MenuItem) return false;\n\tbool enabled = true;\n\t\n\tconst tTJSNI_MenuItem *item = this;\n\twhile(item)\n\t{\n\t\tif (!item->GetEnabled())\n\t\t{\n\t\t\tenabled = false;\n\t\t\tbreak;\n\t\t}\n\t\titem = static_cast<const tTJSNI_MenuItem*>(item->GetParent());\n\t}\n\treturn enabled;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::Add(tTJSNI_MenuItem * item)\n{\n// \tif(MenuItem && item->MenuItem)\n// \t{\n// \t\tMenuItem->Add(item->MenuItem);\n\t\tAddChild(item);\n\t//}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::Insert(tTJSNI_MenuItem *item, tjs_int index)\n{\n// \tif(MenuItem && item->MenuItem)\n// \t{\n// \t\tMenuItem->Insert(index, item->MenuItem);\n\tif (Children.Add(item, index))\n\t{\n\t\tChildrenArrayValid = false;\n\t\tif (item->Owner) item->Owner->AddRef();\n\t\titem->Parent = this;\n\t}\n\t\t//AddChild(item);\n\t//}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::Remove(tTJSNI_MenuItem *item)\n{\n// \tif(MenuItem && item->MenuItem)\n// \t{\n// \t\tint index = MenuItem->IndexOf(item->MenuItem);\n// \t\tif(index == -1) TVPThrowExceptionMessage(TVPNotChildMenuItem);\n// \n// \t\tMenuItem->Delete(index);\n\t\tRemoveChild(item);\n\t//}\n}\n//---------------------------------------------------------------------------\nvoid *tTJSNI_MenuItem::GetMenuItemHandleForPlugin() const\n{\n\t/*if(!MenuItem)*/ return NULL;\n\t//return MenuItem->getHandle();\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_MenuItem::GetIndex() const\n{\n\tif (!Parent) return 0;\n\t//if(!MenuItem) return 0;\n\t//return MenuItem->getMenuIndex();\n\ttjs_int idx = Parent->Children.Find((tTJSNI_BaseMenuItem*)this);\n\tif (idx < 0) idx = 0;\n\treturn idx;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetIndex(tjs_int newIndex)\n{\n// \tif(!MenuItem) return;\n// \tMenuItem->setMenuIndex (newIndex);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetCaption(const ttstr & caption)\n{\n\t//if(!MenuItem) return;\n\tCaption = caption;\n// \tMenuItem->setAutoHotkeys (maManual);\n// \tMenuItem->setCaption (caption);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::GetCaption(ttstr & caption) const\n{\n\t//if(!MenuItem) caption.Clear();\n\tcaption = Caption;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetChecked(bool b)\n{\n\t//if(!MenuItem) return;\n\t//MenuItem->setChecked (b);\n\tif (b && IsRadio && Parent) {\n\t\tfor (tTJSNI_BaseMenuItem *_item : Parent->Children) {\n\t\t\ttTJSNI_MenuItem *item = static_cast<tTJSNI_MenuItem*>(_item);\n\t\t\tif (item->IsRadio && item->GroupIndex == GroupIndex)\n\t\t\t\titem->IsChecked = false;\n\t\t}\n\t}\n\tIsChecked = b;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MenuItem::GetChecked() const\n{\n// \tif(!MenuItem) return false;\n// \treturn MenuItem->getChecked();\n\treturn IsChecked;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetEnabled(bool b)\n{\n\tIsEnabled = b;\n// \tif(!MenuItem) return;\n// \tMenuItem->setEnabled (b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MenuItem::GetEnabled() const\n{\n\treturn IsEnabled;\n// \tif(!MenuItem) return false;\n// \treturn MenuItem->getEnabled();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetGroup(tjs_int g)\n{\n\tGroupIndex = g;\n// \tif(!MenuItem) return;\n// \tMenuItem->setGroupIndex ((BYTE)g);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_MenuItem::GetGroup() const\n{\n\treturn GroupIndex;\n// \tif(!MenuItem) return 0;\n// \treturn MenuItem->getGroupIndex();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetRadio(bool b)\n{\n\tIsRadio = b;\n// \tif(!MenuItem) return;\n// \tMenuItem->setRadioItem (b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MenuItem::GetRadio() const\n{\n\treturn IsRadio;\n// \tif(!MenuItem) return false;\n// \treturn MenuItem->getRadioItem();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetShortcut(const ttstr & shortcut)\n{\n\t//if(!MenuItem) return;\n//\tMenuItem->setShortCut (TextToShortCut(shortcut.AsAnsiString()));\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::GetShortcut(ttstr & shortcut) const\n{\n\t/*if(!MenuItem)*/ shortcut.Clear();\n//\tshortcut = ShortCutToText(MenuItem->getShortCut());\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_MenuItem::SetVisible(bool b)\n{\n\tIsVisible = b;\n// \tif(!MenuItem) return;\n// \tif(Window) Window->SetMenuBarVisible(b); else MenuItem->setVisible (b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_MenuItem::GetVisible() const\n{\n\treturn IsVisible;\n// \tif(!MenuItem) return false;\n// \tif(Window) return Window->GetMenuBarVisible(); else return MenuItem->getVisible();\n}\n\nvoid TVPShowPopMenu(tTJSNI_MenuItem* menu);\n\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_MenuItem::TrackPopup(tjs_uint32 flags, tjs_int x, tjs_int y) const\n{\n\t//if (!MenuItem) return 0;\n\t// TODO\n\tTVPShowPopMenu((tTJSNI_MenuItem*)this);\n\treturn 1;\n// \n// \tHWND  hWindow;\n// \tif (GetRootMenuItem() && GetRootMenuItem()->GetWindow()) {\n// \t\thWindow = GetRootMenuItem()->GetWindow()->GetMenuOwnerWindowHandle();\n// \t} else {\n// \t\treturn 0;\n// \t}\n// \tHMENU hMenuItem = GetMenuItemHandleForPlugin();\n// \n// \t// we assume where that x and y are in client coordinates.\n// \t// TrackPopupMenuEx requires screen coordinates, so here converts them.\n// \tPOINT scrPoint;\t// screen\n// \tscrPoint.x = x;\n// \tscrPoint.y = y;\n// \tBOOL rvScr = ::ClientToScreen(hWindow, &scrPoint);\n// \tif (!rvScr)\n// \t{\n// \t\t// TODO\n// \t}\n// \n// \tBOOL rvPopup = TrackPopupMenuEx(hMenuItem, flags, scrPoint.x, scrPoint.y, hWindow, NULL);\n// \tif (!rvPopup)\n// \t{\n// \t\t// TODO\n// \t\t// should raise an exception when the API fails\n// \t}\n// \n// \treturn rvPopup;\n}\n\n\nstatic iTJSDispatch2* textToKeycodeMap = nullptr;\nstatic iTJSDispatch2* keycodeToTextList = nullptr;\n\nstatic bool SetShortCutKeyCode(ttstr text, int key, bool force) {\n\ttTJSVariant vtext(text);\n\ttTJSVariant vkey(key);\n\n\ttext.ToLowerCase();\n\tif (TJS_FAILED(textToKeycodeMap->PropSet(TJS_MEMBERENSURE, text.c_str(), nullptr, &vkey, textToKeycodeMap)))\n\t\treturn false;\n\tif (force == false) {\n\t\ttTJSVariant var;\n\t\tkeycodeToTextList->PropGetByNum(0, key, &var, keycodeToTextList);\n\t\tif (var.Type() == tvtString) return true;\n\t}\n\treturn TJS_SUCCEEDED(keycodeToTextList->PropSetByNum(TJS_MEMBERENSURE, key, &vtext, keycodeToTextList));\n}\n\nstatic void CreateShortCutKeyCodeTable() {\n\ttextToKeycodeMap = TJSCreateDictionaryObject();\n\tkeycodeToTextList = TJSCreateArrayObject();\n\tif (textToKeycodeMap == nullptr || keycodeToTextList == nullptr) return;\n#if 0\n\ttjs_char tempKeyText[32];\n\tfor (int key = 8; key <= 255; key++) {\n\t\tint code = (::MapVirtualKey(key, 0) << 16) | (1 << 25);\n\t\tif (::GetKeyNameText(code, tempKeyText, 32) > 0) {\n\t\t\tttstr text(tempKeyText);\n\t\t\t// special for NumPad key\n\t\t\tif (TJS_strnicmp(text.c_str(), TJS_W(\"Num \"), 4) == 0) {\n\t\t\t\tbool numpad = (key >= VK_NUMPAD0 && key <= VK_DIVIDE);\n\t\t\t\tif (!numpad && ::GetKeyNameText(code | (1 << 24), tempKeyText, 32) > 0) {\n\t\t\t\t\ttext = tempKeyText;\n\t\t\t\t}\n\t\t\t}\n\t\t\tSetShortCutKeyCode(text, key, true);\n\t\t}\n\t}\n#endif\n\n\t// ＪQå`ȥå\n\tSetShortCutKeyCode(TJS_W(\"BkSp\"), VK_BACK, false);\n\tSetShortCutKeyCode(TJS_W(\"PgUp\"), VK_PRIOR, false);\n\tSetShortCutKeyCode(TJS_W(\"PgDn\"), VK_NEXT, false);\n}\n\n//---------------------------------------------------------------------------\n// tTJSNC_MenuItem::CreateNativeInstance\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_MenuItem::CreateNativeInstance()\n{\n\treturn new tTJSNI_MenuItem();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_MenuItem\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_MenuItem()\n{\n\ttTJSNativeClass *cls = new tTJSNC_MenuItem();\n\tstatic tjs_uint32 TJS_NCM_CLASSID;\n\tTJS_NCM_CLASSID = tTJSNC_MenuItem::ClassID;\n\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(HMENU)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_MenuItem);\n\t\tif (result) *result = (tTVInteger)(void*)_this->GetMenuItemHandleForPlugin();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, HMENU)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(textToKeycode)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tif (result) *result = tTJSVariant(textToKeycodeMap, textToKeycodeMap);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, textToKeycode)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(keycodeToText)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\tif (result) *result = tTJSVariant(keycodeToTextList, keycodeToTextList);\n\treturn TJS_S_OK;\n}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\t\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, keycodeToText)\n//---------------------------------------------------------------------------\n\n\tif (!textToKeycodeMap) {\n\t\tCreateShortCutKeyCodeTable();\n\n\t\ttTJSVariant val;\n\n\t\tiTJSDispatch2 * global = TVPGetScriptDispatch();\n\n\t\t{\n\t\t\tgWindowMenuProperty = new WindowMenuProperty();\n\t\t\tval = tTJSVariant(gWindowMenuProperty);\n\t\t\tgWindowMenuProperty->Release();\n\t\t\ttTJSVariant win;\n\t\t\tif (TJS_SUCCEEDED(global->PropGet(0, TJS_W(\"Window\"), NULL, &win, global))) {\n\t\t\t\tiTJSDispatch2* obj = win.AsObjectNoAddRef();\n\t\t\t\tobj->PropSet(TJS_MEMBERENSURE, TJS_W(\"menu\"), NULL, &val, obj);\n\t\t\t\twin.Clear();\n\t\t\t}\n\t\t\tval.Clear();\n\n\t\t\t//-----------------------------------------------------------------------\n\t\t\tiTJSDispatch2 * tjsclass = TVPCreateNativeClass_MenuItem();\n\t\t\tval = tTJSVariant(tjsclass);\n\t\t\ttjsclass->Release();\n\t\t\tglobal->PropSet(TJS_MEMBERENSURE, TJS_W(\"MenuItem\"), NULL, &val, global);\n\t\t\t//-----------------------------------------------------------------------\n\n\t\t}\n\n\t\tglobal->Release();\n\t}\n\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/win32/MenuItemImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"MenuItem\" class implementation\n//---------------------------------------------------------------------------\n#ifndef MenuItemImplH\n#define MenuItemImplH\n\n//#include <Menus.hpp>\n#include \"MenuItemIntf.h\"\n//#include \"Menus.hpp\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_MenuItem : MenuItem Native Instance\n//---------------------------------------------------------------------------\nclass tTJSNI_MenuItem : public tTJSNI_BaseMenuItem\n{\n\ttypedef tTJSNI_BaseMenuItem inherited;\n\n\t//TMenuItem* MenuItem;\n\n\tttstr Caption;\n\tttstr Shortcut;\n\tbool IsAttched;\n\tbool IsChecked;\n\tbool IsEnabled;\n\tbool IsRadio;\n\tbool IsVisible;\n\t\n\ttjs_int GroupIndex;\n\npublic:\n\ttTJSNI_MenuItem();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\nprivate:\n\tvoid MenuItemClick();\n\nprotected:\n\tbool CanDeliverEvents() const;\n\t\t// tTJSNI_BaseMenuItem::CanDeliverEvents override\n\n\npublic:\n\tvoid Add(tTJSNI_MenuItem * item);\n\tvoid Insert(tTJSNI_MenuItem *item, tjs_int index);\n\tvoid Remove(tTJSNI_MenuItem *item);\n\n\tvoid SetCaption(const ttstr & caption);\n\tvoid GetCaption(ttstr & caption) const;\n\n\tvoid SetChecked(bool b);\n\tbool GetChecked() const;\n\n\tvoid SetEnabled(bool b);\n\tbool GetEnabled() const;\n\n\tvoid SetGroup(tjs_int g);\n\ttjs_int GetGroup() const;\n\n\tvoid SetRadio(bool b);\n\tbool GetRadio() const;\n\n\tvoid SetShortcut(const ttstr & shortcut);\n\tvoid GetShortcut(ttstr & shortcut) const;\n\n\tvoid SetVisible(bool b);\n\tbool GetVisible() const;\n\n\ttjs_int GetIndex() const;\n\tvoid SetIndex(tjs_int newIndex);\n\n\ttjs_int TrackPopup(tjs_uint32 flags, tjs_int x, tjs_int y) const;\n\n\tconst ObjectVector<tTJSNI_BaseMenuItem>& GetChildren() const { return Children; }\n\n//-- interface to plugin\n\t/*HMENU*/void* GetMenuItemHandleForPlugin() const;\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/NativeFreeTypeFace.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n//! @brief Win32 GDI oRłFreeType Face\n/**\n * @note\ttHgtHgt@C𓾂铮삪OSƂɈقȂ邽߁A\n *\t\t\ttFreeTypeFace vbgtH[ƂɈقȂƂȂB\n */\n//#include \"../prec.h\"\n#include \"tjsCommHead.h\"\n#include \"NativeFreeTypeFace.h\"\n#include \"FreeType.h\"\n#include \"MsgIntf.h\"\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4819)\n#endif\n#include <ft2build.h>\n#include FT_FREETYPE_H\n#include FT_TRUETYPE_TAGS_H\n#include FT_TRUETYPE_TABLES_H\n#include FT_TRUETYPE_UNPATENTED_H\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n//---------------------------------------------------------------------------\n\n#define TVP_TT_TABLE_ttcf  (('t' << 0) + ('t' << 8) + ('c' << 16) + ('f' << 24))\n#define TVP_TT_TABLE_name  (('n' << 0) + ('a' << 8) + ('m' << 16) + ('e' << 24))\n\n//---------------------------------------------------------------------------\n/**\n * RXgN^\n * @param fontname\ttHg\n * @param options\tIvV\n */\ntNativeFreeTypeFace::tNativeFreeTypeFace(const std::wstring &fontname,\n\ttjs_uint32 options)\n{\n\t// tB[h̃NA\n\tFaceName = fontname;\n\tFace = NULL;\n\tmemset(&Stream, 0, sizeof(Stream));\n\tDC = NULL;\n\tOldFont = NULL;\n\tIsTTC = false;\n\n\tunsigned char *name_content    = NULL; // Windows 擾 name ^O̓e\n\tunsigned char *name_content_ft = NULL; // FreeType 擾 name ^O̓e\n\ttjs_int name_content_size;\n\n\t// TrueType CutbN\n\ttry\n\t{\n\t\t// w̃tHgfoCXReLXg쐬\n\t\tDC = GetDC(0);\n\t\tLOGFONT l;\n\t\tl.lfHeight = -12;\n\t\tl.lfWidth = 0;\n\t\tl.lfEscapement = 0;\n\t\tl.lfOrientation = 0;\n\t\tl.lfWeight = 400;\n\t\tl.lfItalic = FALSE;\n\t\tl.lfUnderline = FALSE;\n\t\tl.lfStrikeOut = FALSE;\n\t\tl.lfCharSet = DEFAULT_CHARSET;\n\t\tl.lfOutPrecision = OUT_DEFAULT_PRECIS;\n\t\tl.lfQuality = DEFAULT_QUALITY;\n\t\tl.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\n\t\tTJS_strcpy( l.lfFaceName, fontname.c_str() );\n\t\tl.lfFaceName[LF_FACESIZE-1] = TJS_W('\\0');\n\n\t\tHFONT newfont = CreateFontIndirect(&l);\n\t\tOldFont = static_cast<HFONT>(SelectObject(DC, newfont));\n\t\tZeroMemory( &TextMetric, sizeof(TextMetric) );\n\t\t::GetTextMetrics( DC, &TextMetric );\n\n\t\t// ̃tHg GetFontData API ň邩ǂ\n\t\t// 'name' ^O̓e擾悤Ƃ邱ƂŃ`FbN\n\t\t// (name ^O GetFontData 悤 TrueType/OpenType tHgɂ\n\t\t//  KĂ)\n\t\tDWORD result = GetFontData(DC, TVP_TT_TABLE_name, 0, NULL, 0);\n\t\tif(result == GDI_ERROR)\n\t\t{\n\t\t\t// G[; GetFontData ł͈Ȃ\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t}\n\n\t\t//- ̎_ result  name ^O̓êɕKvȃoCg\n\t\tname_content_size = result;\n\t\tname_content = new unsigned char [name_content_size]; // m\n\t\tname_content_ft = new unsigned char [name_content_size]; // m\n\n\t\t//- name ^O̓eɓǂݍ\n\t\tresult = GetFontData(DC, TVP_TT_TABLE_name, 0, name_content, name_content_size);\n\t\tif(result == GDI_ERROR)\n\t\t{\n\t\t\t// G[; ɓǂݍނƂoȂ\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t}\n\n\t\t// tHgt@C̃TCY擾\n\t\ttjs_int fontsize;\n\n\t\t//- TTC (True Type Collection) t@C̃`FbN\n\t\t//- GetFontData API ̎dlł́ATTC t@Cɑ΂ẮAݑIĂ\n\t\t//- tHgɑ΂񂵂ԂȂB FreeType  TTC t@CŜ\n\t\t//- KvƂB̏ꍇAGetFontData  'ttcf' 𓾂悤Ɏw\n\t\t//- t@CŜ̏𓾂邱ƂoB\n\t\t//- Q : microsoft.public.win32.programmer.gdi GetFontData and TTC fonts\n\t\tunsigned char buf[4];\n\t\tresult = GetFontData(DC, TVP_TT_TABLE_ttcf, 0, &buf, 1);\n\t\tif(result == 1)\n\t\t{\n\t\t\t// TTC t@CƎv\n\t\t\tresult = GetFontData(DC, TVP_TT_TABLE_ttcf, 0, NULL, 0);\n\t\t\tIsTTC = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tresult = GetFontData(DC, 0, 0, NULL, 0);\n\t\t}\n\n\t\tif(result == GDI_ERROR)\n\t\t{\n\t\t\t// G[; GetFontData ł͈Ȃ\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t}\n\t\tfontsize = result;\n\n\t\t// FT_StreamRec ̊etB[h𖄂߂\n\t\tFT_StreamRec * fsr = &Stream;\n\t\tfsr->base = 0;\n\t\tfsr->size = fontsize;\n\t\tfsr->pos = 0;\n\t\tfsr->descriptor.pointer = this;\n\t\tfsr->pathname.pointer = NULL;\n\t\tfsr->read = IoFunc;\n\t\tfsr->close = CloseFunc;\n\n\t\t// FreeType ŊJ\n\t\t//  0 Ԃ Face J\n\t\t// (̎_ŊJƂoȂΗO𔭐)\n\t\tint index = 0;\n\t\tif(!OpenFaceByIndex(index))\n\t\t{\n\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t}\n\n\t\t// GDIݑIĂt@CFreeTypeANZXĂt@C\n\t\t// ۂɍvĂ邩ǂAname ^ÖvŌB\n\t\t// Ƃ TTC t@C̏ꍇ́Aname ^ÖvȂAface ̃Cfb\n\t\t// NX₵ȂAΏۂƂtHgTȂ΂ȂȂB\n\t\twhile(true)\n\t\t{\n\t\t\t// FreeType Aname ^ÕTCY擾\n\t\t\tFT_ULong length = 0;\n\t\t\tFT_Error err = FT_Load_Sfnt_Table(Face, TTAG_name, 0, NULL, &length);\n\t\t\tif(err)\n\t\t\t{\n\t\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t\t}\n\n\t\t\t// FreeType 瓾 name ^O̒ Windows 瓾Ɣr\n\t\t\tif(length == name_content_size)\n\t\t\t{\n\t\t\t\t// FreeType  name ^O擾\n\t\t\t\terr = FT_Load_Sfnt_Table(Face, TTAG_name, 0, name_content_ft, &length);\n\t\t\t\tif(err)\n\t\t\t\t{\n\t\t\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t\t\t}\n\t\t\t\t// FreeType ǂݍ name ^O̓eƁAWindows ǂݍ\n\t\t\t\t// name ^O̓erB\n\t\t\t\t// vĂ΂ index ̃tHggB\n\t\t\t\tif(!memcmp(name_content, name_content_ft, name_content_size))\n\t\t\t\t{\n\t\t\t\t\t// v\n\t\t\t\t\t// face ͊J܂\n\t\t\t\t\tbreak; // [v𔲂\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// vȂ\n\t\t\t// CfbNX₵A face J\n\t\t\tindex ++;\n\n\t\t\tif(!OpenFaceByIndex(index))\n\t\t\t{\n\t\t\t\t// v face Ȃ܂ CfbNX͈͂𒴂ƌ\n\t\t\t\t// index  0 ɐݒ肵Ă index JA[v𔲂\n\t\t\t\tindex = 0;\n\t\t\t\tif(!OpenFaceByIndex(index))\n\t\t\t\t{\n\t\t\t\t\tTVPThrowExceptionMessage( TJS_W(\"Font '%1$s' cannot be used\"), fontname );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t}\n\tcatch(...)\n\t{\n\t\tClear();\n\t\tif(name_content) delete [] name_content;\n\t\tif(name_content_ft) delete [] name_content_ft;\n\t\tthrow;\n\t}\n\tdelete [] name_content;\n\tdelete [] name_content_ft;\n\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * fXgN^\n */\ntNativeFreeTypeFace::~tNativeFreeTypeFace()\n{\n\tClear();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * FreeType  Face IuWFNgԂ\n */\nFT_Face tNativeFreeTypeFace::GetFTFace() const\n{\n\treturn Face;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * `łȂ̎ɕ`悷镶R[h\n */\ntjs_char tNativeFreeTypeFace::GetDefaultChar() const\n{\n\tFT_UInt ret = FT_Get_Char_Index( Face, TextMetric.tmDefaultChar );\n\tif( ret != 0 ) return TextMetric.tmDefaultChar;\n\tret = FT_Get_Char_Index( Face, TextMetric.tmBreakChar );\n\tif( ret != 0 ) return TextMetric.tmBreakChar;\n\treturn L' ';\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n/**\n * ̃tHgt@CĂtHgzƂĕԂ\n * @param dest\ti[z\n */\nvoid tNativeFreeTypeFace::GetFaceNameList(std::vector<std::wstring> & dest) const\n{\n\t// FacȅꍇAFace͓肳Ă邽߁Ap\\\n\t// Face ͏1ŁAtHg͂̃IuWFNg\\zꂽۂɓnꂽ\n\t// tHgƂȂ\n\tdest.clear();\n\tdest.push_back(FaceName);\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/**\n * SẴIuWFNg\n */\nvoid tNativeFreeTypeFace::Clear()\n{\n\tif(Face) FT_Done_Face(Face), Face = NULL;\n\tif(OldFont && DC)\n\t{\n\t\tHFONT font = static_cast<HFONT>(SelectObject(DC, OldFont));\n\t\tDeleteObject(font);\n\t\tOldFont = NULL;\n\t}\n\tif(DC) ReleaseDC(0, DC), DC = NULL;\n}\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/**\n * FreeType p Xg[ǂݍ݊֐\n * @param stream\tFT_Streamւ̃|C^\n * @param offset\tXg[擪̃ItZbg\n * @param buffer\ti[obt@\n * @param count\t\tǂݏooCg\n * @return\toCgǂݍ܂ꂽ\n */\nunsigned long tNativeFreeTypeFace::IoFunc(\n\t\t\tFT_Stream stream,\n\t\t\tunsigned long   offset,\n\t\t\tunsigned char*  buffer,\n\t\t\tunsigned long   count )\n{\n\tif(count != 0)\n\t{\n\t\ttNativeFreeTypeFace * _this =\n\t\t\tstatic_cast<tNativeFreeTypeFace*>(stream->descriptor.pointer);\n\t\tDWORD result = GetFontData(_this->DC, \n\t\t\t\t_this->IsTTC ? TVP_TT_TABLE_ttcf : 0,\n\t\t\t\toffset, buffer, count);\n\t\tif(result == GDI_ERROR)\n\t\t{\n\t\t\t// G[\n\t\t\treturn 0;\n\t\t}\n\t\treturn result;\n\t}\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n/**\n * FreeType p Xg[폜֐\n * @param stream\tFT_Streamւ̃|C^\n */\nvoid tNativeFreeTypeFace::CloseFunc( FT_Stream  stream )\n{\n\t// Ȃ\n}\n//---------------------------------------------------------------------------\n\nextern FT_Library FreeTypeLibrary;\n//---------------------------------------------------------------------------\n/**\n * wCfbNXFaceJ\n * @param index\tJindex\n * @return\tFaceJ true łȂ false\n */\nbool tNativeFreeTypeFace::OpenFaceByIndex(int index)\n{\n\tif(Face) FT_Done_Face(Face), Face = NULL;\n\n\tFT_Parameter parameters[1];\n\tparameters[0].tag = FT_PARAM_TAG_UNPATENTED_HINTING; // Apple̓s\n\tparameters[0].data = NULL;\n\n\tFT_Open_Args args;\n\tmemset(&args, 0, sizeof(args));\n\targs.flags = FT_OPEN_STREAM | FT_OPEN_PARAMS;\n\targs.stream = &Stream;\n\targs.driver = 0;\n\targs.num_params = 1;\n\targs.params = parameters;\n\n\tFT_Error err = FT_Open_Face(FreeTypeLibrary, &args, index, &Face);\n\treturn err == 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n//---------------------------------------------------------------------------\n\n\n"
  },
  {
    "path": "src/core/visual/win32/NativeFreeTypeFace.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tRisa [肳]      alias gg3 [kirikiri-3]\n\t stands for \"Risa Is a Stagecraft Architecture\"\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//! @file\n// @brief Win32 GDI oRłFreeType Face\n//---------------------------------------------------------------------------\n#ifndef _NATIVEFREETYPEFACE_H_\n#define _NATIVEFREETYPEFACE_H_\n\n#include \"tvpfontstruc.h\"\n#include \"FreeTypeFace.h\"\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4819)\n#endif\n#include <ft2build.h>\n#include FT_FREETYPE_H\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n//! @brief\t\tWin32 GDI oRłFreeType Face NX\n//---------------------------------------------------------------------------\nclass tNativeFreeTypeFace : public tBaseFreeTypeFace\n{\nprotected:\n\tstd::wstring FaceName;\t//!< Face = tHg\n\tFT_Face Face;\t//!< FreeType face IuWFNg\n\nprivate:\n// \tHDC DC;\t\t\t//!< foCXReLXg\n// \tHFONT OldFont;\t//!< foCXReLXgɌXo^ĂÂtHg\n\tbool IsTTC;\t\t//!< TTC(TrueTypeCollection)t@CĂꍇɐ^\n\tFT_StreamRec Stream;\n//\tTEXTMETRIC TextMetric;\n\npublic:\n\ttNativeFreeTypeFace(const std::wstring &fontname, tjs_uint32 options);\n\tvirtual ~tNativeFreeTypeFace();\n\n\tvirtual FT_Face GetFTFace() const;\n\tvirtual void GetFaceNameList(std::vector<std::wstring> & dest) const; \n\n\tbool GetIsTTC() const { return IsTTC; }\n\ttjs_char GetDefaultChar() const;\n\nprivate:\n\tvoid Clear();\n\tstatic unsigned long IoFunc(\n\t\t\tFT_Stream stream,\n\t\t\tunsigned long   offset,\n\t\t\tunsigned char*  buffer,\n\t\t\tunsigned long   count );\n\tstatic void CloseFunc( FT_Stream  stream );\n\n\tbool OpenFaceByIndex(int index);\n\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n\n\n\n\n#endif /*_NATIVEFREETYPEFACE_H_*/\n"
  },
  {
    "path": "src/core/visual/win32/PassThroughDrawDevice.cpp",
    "content": "﻿//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//!@file \"PassThrough\" 描画デバイス管理\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n#include \"DrawDevice.h\"\n#include \"PassThroughDrawDevice.h\"\n#include \"LayerIntf.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"WindowIntf.h\"\n#include \"DebugIntf.h\"\n#include \"ThreadIntf.h\"\n\n#include \"TickCount.h\"\n#include <assert.h>\n#include <math.h>\n/*\n\tPassThroughDrawDevice クラスには、Window.PassThroughDrawDevice として\n\tアクセスできる。通常、Window クラスを生成すると、その drawDevice プロパ\n\tティには自動的にこのクラスのインスタンスが設定されるので、(ほかのDrawDevice\n\tを使わない限りは) 特に意識する必要はない。\n\n\tPassThroughDrawDevice は以下のメソッドとプロパティを持つ。\n\n\trecreate()\n\t\tDrawer (内部で使用している描画方式) を切り替える。preferredDrawer プロパティ\n\t\tが dtNone 以外であればそれに従うが、必ず指定された drawer が使用される保証はない。\n\n\tpreferredDrawer\n\t\t使用したい drawer を表すプロパティ。以下のいずれかの値をとる。\n\t\t値を設定することも可能。new 直後の値は コマンドラインオプションの dbstyle で\n\t\t設定した値になる。\n\t\tdrawerがこの値になる保証はない (たとえば dtDBD3D を指定していても何らかの\n\t\t原因で Direct3D の初期化に失敗した場合は DirectDraw が使用される可能性がある)。\n\t\tウィンドウ作成直後、最初にプライマリレイヤを作成するよりも前にこのプロパティを\n\t\t設定する事により、recreate() をわざわざ実行しなくても指定の drawer を使用\n\t\tさせることができる。\n\t\tWindow.PassThroughDrawDevice.dtNone\t\t\t指定しない\n\t\tWindow.PassThroughDrawDevice.dtDrawDib\t\t拡大縮小が必要な場合はGDI、\n\t\t\t\t\t\t\t\t\t\t\t\t\tそうでなければDBなし\n\t\tWindow.PassThroughDrawDevice.dtDBGDI\t\tGDIによるDB\n\t\tWindow.PassThroughDrawDevice.dtDBDD\t\t\tDirectDrawによるDB\n\t\tWindow.PassThroughDrawDevice.dtDBD3D\t\tDirect3DによるDB\n\n\tdrawer\n\t\t現在使用されている drawer を表すプロパティ。以下のいずれかの値をとる。\n\t\t読み取り専用。\n\t\tWindow.PassThroughDrawDevice.dtNone\t\t\t普通はこれはない\n\t\tWindow.PassThroughDrawDevice.dtDrawDib\t\tダブルバッファリング(DB)なし\n\t\tWindow.PassThroughDrawDevice.dtDBGDI\t\tGDIによるDB\n\t\tWindow.PassThroughDrawDevice.dtDBDD\t\t\tDirectDrawによるDB\n\t\tWindow.PassThroughDrawDevice.dtDBD3D\t\tDirect3DによるDB\n*/\n\n\n//---------------------------------------------------------------------------\n// オプション\n//---------------------------------------------------------------------------\nstatic tjs_int TVPPassThroughOptionsGeneration = 0;\nstatic bool TVPZoomInterpolation = true;\nstatic tTVPPassThroughDrawDevice::tDrawerType TVPPreferredDrawType = tTVPPassThroughDrawDevice::dtNone;\n//---------------------------------------------------------------------------\nstatic void TVPInitPassThroughOptions()\n{\n\tif(TVPPassThroughOptionsGeneration == TVPGetCommandLineArgumentGeneration()) return;\n\tTVPPassThroughOptionsGeneration = TVPGetCommandLineArgumentGeneration();\n\n\tTVPZoomInterpolation = true;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n//! @brief\tPassThrough で用いる描画方法用インターフェース\n//---------------------------------------------------------------------------\nclass tTVPDrawer\n{\nprotected:\n\ttTVPPassThroughDrawDevice * Device;\n\ttjs_int DestLeft;\n\ttjs_int DestTop;\n\ttjs_int DestWidth;\n\ttjs_int DestHeight;\n\ttjs_int SrcWidth;\n\ttjs_int SrcHeight;\n\t//SDL_Window* TargetWindow;\n\tbool DrawUpdateRectangle;\npublic:\n\ttTVPDrawer(tTVPPassThroughDrawDevice * device)\n\t{\n\t\tDevice = device;\n\t\tSrcWidth = 0;\n\t\tSrcHeight = 0;\n\t\tDestLeft = DestTop = DestWidth = DestHeight = 0;\n\t\t//TargetWindow = NULL;\n\t\tDrawUpdateRectangle = false;\n\t} \n\tvirtual ~tTVPDrawer()\n\t{\n\t}\n\tvirtual ttstr GetName() = 0;\n\n\tvirtual bool SetDestPos(tjs_int left, tjs_int top)\n\t\t{ DestLeft = left; DestTop = top; return true; }\n\tvirtual bool SetDestSize(tjs_int width, tjs_int height)\n\t\t{ DestWidth = width; DestHeight = height; return true; }\n\tvoid GetDestSize(tjs_int &width, tjs_int &height) const\n\t\t{ width = DestWidth; height = DestHeight; }\n\tvirtual bool NotifyLayerResize(tjs_int w, tjs_int h)\n\t\t{ SrcWidth = w; SrcHeight = h; return true; }\n\tvoid GetSrcSize(tjs_int &w, tjs_int &h) const\n\t\t{ w = SrcWidth; h = SrcHeight; }\n\tvirtual bool SetDestSizeAndNotifyLayerResize(tjs_int width, tjs_int height, tjs_int w, tjs_int h)\n\t{\n\t\tif(!SetDestSize(width, height)) return false;\n\t\tif(!NotifyLayerResize(w, h)) return false;\n\t\treturn true;\n\t}\n\tvirtual void SetTargetWindow(int wnd)\n\t{\n\t\t//TargetWindow = wnd;\n\t}\n\tvirtual void StartBitmapCompletion() = 0;\n// \tvirtual void NotifyBitmapCompleted(tjs_int x, tjs_int y,\n// \t\ttTVPBaseTexture *bmp,\n// \t\tconst tTVPRect &cliprect) = 0;\n\tvirtual void EndBitmapCompletion(iTVPBaseBitmap *bmp) = 0;\n\tvirtual void Show() {;}\n\tvirtual void SetShowUpdateRect(bool b)  { DrawUpdateRectangle = b; }\n\tvirtual int GetInterpolationCapability() { return 3; }\n\t\t// bit 0 for point-on-point, bit 1 for bilinear interpolation\n\n\tvirtual void InitTimings() {;} // notifies begining of benchmark\n\tvirtual void ReportTimings() {;} // notifies end of benchmark\n\n    virtual void Clear() = 0;\n};\n\n\nclass tTVPDrawer_Software : public tTVPDrawer\n{\npublic:\n\ttTVPDrawer_Software(tTVPPassThroughDrawDevice * device) : tTVPDrawer(device)\n    {\n    }\n\n\tvirtual ttstr GetName() { return TJS_W(\"Software rendering\"); }\n\n\tvirtual void StartBitmapCompletion()\n\t{\n\t\tClear();\n// \t\tSDL_Renderer *renderer = TVPGetPrimaryRender();\n// \t\tSDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);\n// \t\tSDL_RenderFillRect(renderer, NULL);\n\t}\n\n    virtual void EndBitmapCompletion(iTVPBaseBitmap *_bmp)\n    {\n        if(!_bmp) return;\n\n\t\ttTVPRect rcdst(DestLeft, DestTop, DestLeft + DestWidth, DestTop + DestHeight);\n\t\ttTVPRect rcsrc(0, 0, SrcWidth, SrcHeight);\n\t\t//TVPGetRenderManager()->DrawScreen(rcdst, _bmp->GetTexture(), rcsrc);\n//        SDL_DestroyTexture(texture);\n//        SDL_FreeSurface(surface);\n    }\n\tvirtual void Show()\n\t{\n\t\t/* Update the screen! */\n\t\t//TVPGetRenderManager()->PresentScreen();\n\t}\n    virtual void Clear()\n    {\n\t\t//TVPGetRenderManager()->ClearScreen();\n    }\n};\n\n//---------------------------------------------------------------------------\ntTVPPassThroughDrawDevice::tTVPPassThroughDrawDevice()\n{\n\tTVPInitPassThroughOptions(); // read and initialize options\n\tPreferredDrawerType = TVPPreferredDrawType;\n\t//TargetWindow = NULL;\n\tDrawer = NULL;\n\tDrawerType = dtNone;\n\tDestSizeChanged = false;\n\tSrcSizeChanged = false;\n\tLockedWidth = LockedHeight = -1;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTVPPassThroughDrawDevice::~tTVPPassThroughDrawDevice()\n{\n\tDestroyDrawer();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPPassThroughDrawDevice::DestroyDrawer()\n{\n\tif(Drawer) delete Drawer, Drawer = NULL;\n\tDrawerType = dtNone;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPPassThroughDrawDevice::CreateDrawer(tDrawerType type)\n{\n\tif(Drawer) delete Drawer, Drawer = NULL;\n\n\tswitch(type)\n\t{\n\tcase dtNone:\n\t\tbreak;\n    case dtDBD3D:\n\tcase dtDrawDib:\n    case dtDBGDI:\n    case dtDBDD:\n\t\tbreak;\n\t}\n        Drawer = new tTVPDrawer_Software(this);\n\n\ttry\n\t{\n\n// \t\tif(Drawer)\n// \t\t\tDrawer->SetTargetWindow(TargetWindow);\n\n\t\tif(Drawer)\n\t\t{\n\t\t\tif(!Drawer->SetDestPos(DestRect.left, DestRect.top))\n\t\t\t{\n\t\t\t\tTVPAddImportantLog(\n\t\t\t\t\tTJS_W(\"Passthrough: Failed to set destination position to draw device drawer\"));\n\t\t\t\tdelete Drawer, Drawer = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif(Drawer)\n\t\t{\n\t\t\tGetSrcSize(SrcWidth, SrcHeight);\n\t\t\tif(!Drawer->SetDestSizeAndNotifyLayerResize(DestRect.get_width(), DestRect.get_height(), SrcWidth, SrcHeight))\n\t\t\t{\n\t\t\t\tTVPAddImportantLog(\n\t\t\t\t\tTJS_W(\"Passthrough: Failed to set destination size and source layer size to draw device drawer\"));\n\t\t\t\tdelete Drawer, Drawer = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif(Drawer) DrawerType = type; else DrawerType = dtNone;\n\n\t\tRequestInvalidation(tTVPRect(0, 0, DestRect.get_width(), DestRect.get_height()));\n\t}\n\tcatch(const eTJS & e)\n\t{\n\t\tTVPAddImportantLog(TJS_W(\"Passthrough: Failed to create drawer: \") + e.GetMessage());\n\t\tDestroyDrawer();\n\t}\n\tcatch(...)\n\t{\n\t\tTVPAddImportantLog(TJS_W(\"Passthrough: Failed to create drawer: unknown reason\"));\n\t\tDestroyDrawer();\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPPassThroughDrawDevice::CreateDrawer(bool zoom_required, bool should_benchmark)\n{\n    // only create once under android\n    CreateDrawer(dtDrawDib);\n    return;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPPassThroughDrawDevice::EnsureDrawer()\n{\n\t// このメソッドでは、以下の条件の際に drawer を作る(作り直す)。\n\t// 1. Drawer が NULL の場合\n\t// 2. 現在の Drawer のタイプが適切でなくなったとき\n\t// 3. 元のレイヤのサイズが変更されたとき\n\tTVPInitPassThroughOptions();\n\n\t//if(TargetWindow)\n\t{\n\t\t// ズームは必要だったか？\n\t\tbool zoom_was_required = false;\n        bool need_recreate = false;\n        tjs_int srcw, srch;\n        GetSrcSize(srcw, srch);\n        if (Drawer)\n\t\t{\n            tjs_int drawsrcw, drawsrch;\n            Drawer->GetSrcSize(drawsrcw, drawsrch);\n\t\t\ttjs_int destw, desth;\n\t\t\tDrawer->GetDestSize(destw, desth);\n\t\t\tif(destw != srcw || desth != srch)\n\t\t\t\tzoom_was_required = true;\n            if (drawsrcw != srcw || drawsrch != srch)\n                need_recreate = true;\n            Drawer->SetDestPos(DestRect.left, DestRect.top);\n\t\t}\n\n\t\t// ズームは(今回は)必要か？\n\t\tbool zoom_is_required = false;\n\t\tif(DestRect.get_width() != srcw || DestRect.get_height() != srch)\n\t\t\tzoom_is_required = true;\n\n\n\t\tbool should_benchmark = false;\n\t\tif(!Drawer) need_recreate = true;\n\t\tif(zoom_was_required != zoom_is_required) need_recreate = true;\n//\t\tif(need_recreate) should_benchmark = true;\n//\t\tif(SrcSizeChanged) { SrcSizeChanged = false; need_recreate = true; }\n\t\t\t// SrcSizeChanged という理由だけでは should_benchmark は真には\n\t\t\t// 設定しない\n\n\t\tif(need_recreate)\n\t\t{\n\t\t\t// Drawer の再作成が必要\n\t\t\tCreateDrawer(zoom_is_required, should_benchmark);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::AddLayerManager(iTVPLayerManager * manager)\n{\n\tif(inherited::Managers.size() > 0)\n\t{\n\t\t// \"Pass Through\" デバイスでは２つ以上のLayer Managerを登録できない\n\t\tTVPThrowExceptionMessage(TJS_W(\"\\\"passthrough\\\" device does not support layer manager more than 1\"));\n\t\t\t// TODO: i18n\n\t}\n\tinherited::AddLayerManager(manager);\n\n\tmanager->SetDesiredLayerType(ltOpaque); // ltOpaque な出力を受け取りたい\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::SetTargetWindow(int wnd, bool is_main)\n{\n\tTVPInitPassThroughOptions();\n\tDestroyDrawer();\n\t//TargetWindow = wnd;\n\t//IsMainWindow = is_main;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::SetDestRectangle(const tTVPRect & rect)\n{\n\t// 位置だけの変更の場合かどうかをチェックする\n\tif(rect.get_width() == DestRect.get_width() && rect.get_height() == DestRect.get_height())\n\t{\n\t\t// 位置だけの変更だ\n\t\tif(Drawer) Drawer->SetDestPos(rect.left, rect.top);\n\t\tinherited::SetDestRectangle(rect);\n\t}\n\telse\n\t{\n\t\t// サイズも違う\n\t\tDestSizeChanged = true;\n\t\tinherited::SetDestRectangle(rect);\n\t\tEnsureDrawer();\n\t\tif(Drawer)\n\t\t{\n\t\t\tif(!Drawer->SetDestSize(rect.get_width(), rect.get_height()))\n\t\t\t\tDestroyDrawer(); // エラーが起こったのでその drawer を破棄する\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::NotifyLayerResize(iTVPLayerManager * manager)\n{\n\tinherited::NotifyLayerResize(manager);\n\tSrcSizeChanged = true;\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::Show()\n{\n\tif(Drawer) {\n        //TVPDrawCursor();\n        Drawer->Show();\n    }\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::StartBitmapCompletion(iTVPLayerManager * manager)\n{\n\tEnsureDrawer();\n\n\t// この中で DestroyDrawer が呼ばれる可能性に注意すること\n\t//if(Drawer) Drawer->StartBitmapCompletion();\n\n\tif(!Drawer)\n\t{\n\t\t// リトライする\n\t\tEnsureDrawer();\n\t\t//if(Drawer) Drawer->StartBitmapCompletion();\n\t}\n\n\tif (Drawer) Drawer->StartBitmapCompletion();\n\n//     if(TVPForceUpdateScreen) {\n//         iTVPBaseBitmap *buffer = manager->GetDrawBuffer();\n//         tTVPRect rc;\n//         if(buffer) {\n//             rc.bottom = buffer->GetHeight();\n//             rc.right = buffer->GetWidth();\n//             buffer->Fill(rc, 0xFF000000);\n//         }\n//         ((tTVPLayerManager*)manager)->AddUpdateRegion(rc);\n//     }\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::NotifyBitmapCompleted(iTVPLayerManager * manager,\n\ttjs_int x, tjs_int y, tTVPBaseTexture *bmp,\n\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity)\n{\n\t// bits, bitmapinfo で表されるビットマップの cliprect の領域を、x, y に描画\n\t// する。\n\t// opacity と type は無視するしかないので無視する\n// \tif(Drawer)\n// \t{\n// \t\tTVPInitPassThroughOptions();\n// \t\tDrawer->NotifyBitmapCompleted(x, y, bmp, cliprect);\n// \t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::EndBitmapCompletion(iTVPLayerManager * manager)\n{\n//     TVPCopyTexture(\n//         NULL, texRect(DestRect.left, DestRect.bottom, DestRect.get_width(), -DestRect.get_height()),\n//         manager->GetDrawBuffer()->GetTexture(), texRect(0, 0, SrcWidth, SrcHeight)\n//         );\n    if (Drawer) {\n//         tTVPBaseTexture *bmp = manager->GetDrawBuffer();\n//         tTVPRect rc(0, 0, bmp->GetWidth(), bmp->GetHeight());\n//         Drawer->NotifyBitmapCompleted(0, 0, bmp, rc);\n        Drawer->EndBitmapCompletion(manager->GetDrawBuffer());\n    }\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTVPPassThroughDrawDevice::SetShowUpdateRect(bool b)\n{\n\tif(Drawer) Drawer->SetShowUpdateRect(b);\n}\n\nvoid tTVPPassThroughDrawDevice::Clear() {\n    if(Drawer) Drawer->Clear();\n}\n\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_PassThroughDrawDevice : PassThroughDrawDevice TJS native class\n//---------------------------------------------------------------------------\ntjs_uint32 tTJSNC_PassThroughDrawDevice::ClassID = (tjs_uint32)-1;\ntTJSNC_PassThroughDrawDevice::tTJSNC_PassThroughDrawDevice() :\n\ttTJSNativeClass(TJS_W(\"PassThroughDrawDevice\"))\n{\n\t// register native methods/properties\n\n\tTJS_BEGIN_NATIVE_MEMBERS(PassThroughDrawDevice)\n\tTJS_DECL_EMPTY_FINALIZE_METHOD\n//----------------------------------------------------------------------\n// constructor/methods\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_PassThroughDrawDevice,\n\t/*TJS class name*/PassThroughDrawDevice)\n{\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/PassThroughDrawDevice)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/recreate)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\t_this->GetDevice()->SetToRecreateDrawer();\n\t_this->GetDevice()->EnsureDrawer();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/recreate)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/lockTouchSize)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\tif (numparams < 2) return TJS_E_BADPARAMCOUNT;\n\t_this->GetDevice()->SetLockedSize(param[0]->operator tjs_int(), param[1]->operator tjs_int());\n\tif (result) result->Clear();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL(/*func. name*/lockTouchSize)\n\n\n//---------------------------------------------------------------------------\n//----------------------------------------------------------------------\n// properties\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(interface)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\t\t*result = reinterpret_cast<tjs_int64>(_this->GetDevice());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(interface)\n//----------------------------------------------------------------------\n#define TVP_REGISTER_PTDD_ENUM(name) \\\n\tTJS_BEGIN_NATIVE_PROP_DECL(name) \\\n\t{ \\\n\t\tTJS_BEGIN_NATIVE_PROP_GETTER \\\n\t\t{ \\\n\t\t\t*result = (tjs_int64)tTVPPassThroughDrawDevice::name; \\\n\t\t\treturn TJS_S_OK; \\\n\t\t} \\\n\t\tTJS_END_NATIVE_PROP_GETTER \\\n\t\tTJS_DENY_NATIVE_PROP_SETTER \\\n\t} \\\n\tTJS_END_NATIVE_PROP_DECL(name)\n\nTVP_REGISTER_PTDD_ENUM(dtNone)\nTVP_REGISTER_PTDD_ENUM(dtDrawDib)\nTVP_REGISTER_PTDD_ENUM(dtDBGDI)\nTVP_REGISTER_PTDD_ENUM(dtDBDD)\nTVP_REGISTER_PTDD_ENUM(dtDBD3D)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(preferredDrawer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\t\t*result = (tjs_int64)(_this->GetDevice()->GetPreferredDrawerType());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\t\t_this->GetDevice()->SetPreferredDrawerType((tTVPPassThroughDrawDevice::tDrawerType)(tjs_int)*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(preferredDrawer)\n//----------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(drawer)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_PassThroughDrawDevice);\n\t\t*result = (tjs_int64)(_this->GetDevice()->GetDrawerType());\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL(drawer)\n//----------------------------------------------------------------------\n\tTJS_END_NATIVE_MEMBERS\n}\n//---------------------------------------------------------------------------\niTJSNativeInstance *tTJSNC_PassThroughDrawDevice::CreateNativeInstance()\n{\n\treturn new tTJSNI_PassThroughDrawDevice();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\ntTJSNI_PassThroughDrawDevice::tTJSNI_PassThroughDrawDevice()\n{\n\tDevice = new tTVPPassThroughDrawDevice();\n}\n//---------------------------------------------------------------------------\ntTJSNI_PassThroughDrawDevice::~tTJSNI_PassThroughDrawDevice()\n{\n\tif(Device) Device->Destruct(), Device = NULL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\n\ttTJSNI_PassThroughDrawDevice::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_PassThroughDrawDevice::Invalidate()\n{\n\tif(Device) Device->Destruct(), Device = NULL;\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/win32/PassThroughDrawDevice.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000-2007 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n//!@file \"PassThrough\" `foCXǗ\n//---------------------------------------------------------------------------\n#ifndef PASSTHROUGHDRAWDEVICE_H\n#define PASSTHROUGHDRAWDEVICE_H\n\n#include \"DrawDevice.h\"\n\nclass tTVPDrawer;\n//---------------------------------------------------------------------------\n//! @brief\t\tuPass ThroughvfoCX(Ƃ{Iȕ`ŝ݂̃foCX)\n//---------------------------------------------------------------------------\nclass tTVPPassThroughDrawDevice : public tTVPDrawDevice\n{\n\ttypedef tTVPDrawDevice inherited;\n\t//SDL_Window *TargetWindow;\n\t//bool IsMainWindow;\n\ttTVPDrawer * Drawer; //!< `s\n\npublic:\n\t//! @brief\tdrawer̃^Cv\n\tenum tDrawerType\n\t{\n\t\tdtNone, //!< drawer Ȃ\n\t\tdtDrawDib, //!< ƂPdrawer\n\t\tdtDBGDI, // GDI ɂ_uobt@Osdrawer\n\t\tdtDBDD, // DirectDraw ɂ_uobt@Osdrawer\n\t\tdtDBD3D // Direct3D ɂ_uobt@Osdrawer\n\t};\n\nprivate:\n\ttDrawerType DrawerType; //!< drawer ̃^Cv\n\ttDrawerType PreferredDrawerType; //!< gė~ drawer ̃^Cv\n\n\tbool DestSizeChanged; //!< DestRect ̃TCYɕύX\n\tbool SrcSizeChanged; //!< SrcSize ɕύX\n\npublic:\n\ttTVPPassThroughDrawDevice(); //!< RXgN^\nprivate:\n\t~tTVPPassThroughDrawDevice(); //!< fXgN^\n\npublic:\n\tvoid SetToRecreateDrawer() { DestroyDrawer(); }\n\tvoid DestroyDrawer();\nprivate:\n\tvoid CreateDrawer(tDrawerType type);\n\tvoid CreateDrawer(bool zoom_required, bool should_benchmark);\n\npublic:\n\tvoid EnsureDrawer();\n\n\ttDrawerType GetDrawerType() const { return DrawerType; }\n\tvoid SetPreferredDrawerType(tDrawerType type) { PreferredDrawerType = type; }\n\ttDrawerType GetPreferredDrawerType() const { return PreferredDrawerType; }\n\n//---- LayerManager ̊Ǘ֘A\n\tvirtual void TJS_INTF_METHOD AddLayerManager(iTVPLayerManager * manager);\n\n//---- `ʒuETCY֘A\n\tvirtual void TJS_INTF_METHOD SetTargetWindow(int wnd, bool is_main);\n\tvirtual void TJS_INTF_METHOD SetDestRectangle(const tTVPRect & rect);\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(iTVPLayerManager * manager);\n\n//---- ĕ`֘A\n\tvirtual void TJS_INTF_METHOD Show();\n\n//---- LayerManager ̉摜󂯓n֘A\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity);\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager);\n\n//---- fobOx\n\tvirtual void TJS_INTF_METHOD SetShowUpdateRect(bool b);\n    virtual void Clear();\n};\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_PassThroughDrawDevice\n//---------------------------------------------------------------------------\nclass tTJSNI_PassThroughDrawDevice :\n\tpublic tTJSNativeInstance\n{\n\ttypedef tTJSNativeInstance inherited;\n\n\ttTVPPassThroughDrawDevice * Device;\n\npublic:\n\ttTJSNI_PassThroughDrawDevice();\n\t~tTJSNI_PassThroughDrawDevice();\n\ttjs_error TJS_INTF_METHOD\n\t\tConstruct(tjs_int numparams, tTJSVariant **param,\n\t\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\npublic:\n\ttTVPPassThroughDrawDevice * GetDevice() const { return Device; }\n\n};\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_PassThroughDrawDevice\n//---------------------------------------------------------------------------\nclass tTJSNC_PassThroughDrawDevice : public tTJSNativeClass\n{\npublic:\n\ttTJSNC_PassThroughDrawDevice();\n\n\tstatic tjs_uint32 ClassID;\n\nprivate:\n\tiTJSNativeInstance *CreateNativeInstance();\n};\n//---------------------------------------------------------------------------\n\n\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/TVPColor.h",
    "content": "\n#ifndef __TVP_COLOR_H__\n#define __TVP_COLOR_H__\n\nenum {\n\tclScrollBar = 0x80000000,\n\tclBackground = 0x80000001,\n\tclActiveCaption = 0x80000002,\n\tclInactiveCaption = 0x80000003,\n\tclMenu = 0x80000004,\n\tclWindow = 0x80000005,\n\tclWindowFrame = 0x80000006,\n\tclMenuText = 0x80000007,\n\tclWindowText = 0x80000008,\n\tclCaptionText = 0x80000009,\n\tclActiveBorder = 0x8000000a,\n\tclInactiveBorder = 0x8000000b,\n\tclAppWorkSpace = 0x8000000c,\n\tclHighlight = 0x8000000d,\n\tclHighlightText = 0x8000000e,\n\tclBtnFace = 0x8000000f,\n\tclBtnShadow = 0x80000010,\n\tclGrayText = 0x80000011,\n\tclBtnText = 0x80000012,\n\tclInactiveCaptionText = 0x80000013,\n\tclBtnHighlight = 0x80000014,\n\tcl3DDkShadow = 0x80000015,\n\tcl3DLight = 0x80000016,\n\tclInfoText = 0x80000017,\n\tclInfoBk = 0x80000018,\n\tclNone = 0x1fffffff,\n\tclAdapt= 0x01ffffff,\n\tclPalIdx = 0x3000000,\n\tclAlphaMat = 0x4000000,\n\tclUnknown = 0x80000019,\n\tclHotLight = 0x8000001a,\n\tclGradientActiveCaption = 0x8000001b,\n\tclGradientInactiveCaption = 0x8000001c,\n\tclMenuLight = 0x8000001d,\n\tclMenuBar = 0x8000001e,\n};\n\nunsigned long ColorToRGB(unsigned int col);\n\n#endif\n\n"
  },
  {
    "path": "src/core/visual/win32/TVPScreen.cpp",
    "content": "#include \"cocos2d.h\"\n#include \"tjsCommHead.h\"\n\n#include \"TVPScreen.h\"\n#include \"Application.h\"\n\nint tTVPScreen::GetWidth() {\n\treturn 2048;\n}\nint tTVPScreen::GetHeight() {\n\tconst cocos2d::Size &size = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize();\n\tint w = GetWidth();\n\tint h = w * (size.height / size.width);\n\treturn w;\n}\n\nint tTVPScreen::GetDesktopLeft() {\n\treturn 0;\n}\nint tTVPScreen::GetDesktopTop() {\n\treturn 0;\n}\nint tTVPScreen::GetDesktopWidth() {\n\treturn GetWidth();\n}\nint tTVPScreen::GetDesktopHeight() {\n\treturn GetHeight();\n}\n\n"
  },
  {
    "path": "src/core/visual/win32/TVPScreen.h",
    "content": "\n#ifndef __TVP_SCREEN_H__\n#define __TVP_SCREEN_H__\nclass tTVPScreen {\npublic:\n\ttTVPScreen();\n\tstatic int GetWidth();\n\tstatic int GetHeight();\n//\tstatic void GetDesktopRect( RECT& r );\n\tstatic int GetDesktopLeft();\n\tstatic int GetDesktopTop();\n\tstatic int GetDesktopWidth();\n\tstatic int GetDesktopHeight();\n};\n\n#endif // __TVP_SCREEN_H__\n"
  },
  {
    "path": "src/core/visual/win32/TVPSysFont.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include \"tvpfontstruc.h\"\n#include \"TVPSysFont.h\"\n#include \"FontSystem.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n\nextern FontSystem* TVPFontSystem;\n\nstatic bool IsInitDefalutFontName = false;\n/**\n * XgbNtHgw̏ꍇAVXetHg擾āÃIuWFNgftHgƂ\n */\nconst tjs_char *TVPGetDefaultFontName() {\n\tif( IsInitDefalutFontName ) {\n\t\treturn TVPDefaultFontName;\n\t}\n\n\t// R}hCŎw肪ꍇÃtHggp\n\ttTJSVariant opt;\n\tif(TVPGetCommandLine(TJS_W(\"-deffont\"), &opt)) {\n\t\tttstr str(opt);\n\t\tTVPDefaultFontName.AssignMessage( str.c_str() );\n\t}\n\tIsInitDefalutFontName =  true;\n\n\t// VXe`̃tHgǂ`FbN\n\tttstr name = ttstr(TVPDefaultFontName);\n\tHGDIOBJ obj = NULL;\n\tif( name == ttstr(TJS_W(\"ANSI_FIXED_FONT\")) ) {\n\t\tobj = ::GetStockObject(ANSI_FIXED_FONT);\n\t} else if( name == ttstr(TJS_W(\"ANSI_VAR_FONT\")) ) {\n\t\tobj = ::GetStockObject(ANSI_VAR_FONT);\n\t} else if( name == ttstr(TJS_W(\"DEVICE_DEFAULT_FONT\")) ) {\n\t\tobj = ::GetStockObject(DEVICE_DEFAULT_FONT);\n\t} else if( name == ttstr(TJS_W(\"DEFAULT_GUI_FONT\")) ) {\n\t\tobj = ::GetStockObject(DEFAULT_GUI_FONT);\n\t} else if( name == ttstr(TJS_W(\"OEM_FIXED_FONT\")) ) {\n\t\tobj = ::GetStockObject(OEM_FIXED_FONT);\n\t} else if( name == ttstr(TJS_W(\"SYSTEM_FONT\")) ) {\n\t\tobj = ::GetStockObject(SYSTEM_FONT);\n\t} else if( name == ttstr(TJS_W(\"SYSTEM_FIXED_FONT\")) ) {\n\t\tobj = ::GetStockObject(SYSTEM_FIXED_FONT);\n\t}\n\tif( obj != NULL ) {\n\t\tHFONT font = (HFONT)obj;\n\t\tLOGFONT logfont={0};\n\t\t::GetObject( font, sizeof(LOGFONT), &logfont );\n\t\tTVPDefaultFontName.AssignMessage( logfont.lfFaceName );\n\t}\n\treturn TVPDefaultFontName;\n}\n\nvoid tTVPSysFont::InitializeMemDC() {\n\tBITMAPINFO bmpinfo;\n\tZeroMemory( &bmpinfo, sizeof(bmpinfo) );\n\tbmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n\tbmpinfo.bmiHeader.biBitCount = 32;\n\tbmpinfo.bmiHeader.biPlanes = 1;\n\tbmpinfo.bmiHeader.biWidth = 32;\n\tbmpinfo.bmiHeader.biHeight = 32;\n\n\thMemDC_ = ::CreateCompatibleDC( NULL );\n\tchar * Bits;\n\thBmp_ = ::CreateDIBSection( NULL, &bmpinfo, DIB_RGB_COLORS, (void **)(&Bits), NULL, 0 );\n\thOldBmp_ = ::SelectObject( hMemDC_, hBmp_ );\n}\n\ntTVPSysFont::tTVPSysFont() : hFont_(INVALID_HANDLE_VALUE), hOldFont_(INVALID_HANDLE_VALUE), hMemDC_(INVALID_HANDLE_VALUE),\n\thBmp_(INVALID_HANDLE_VALUE), hOldBmp_(INVALID_HANDLE_VALUE) {\n\n\tInitializeMemDC();\n\n\tHFONT hFont = (HFONT)::GetStockObject( ANSI_FIXED_FONT );\n\tLOGFONT logfont={0};\n\t::GetObject( hFont_, sizeof(LOGFONT), &logfont );\n\tlogfont.lfHeight = -12;\n\tlogfont.lfWidth = 0;\n\tlogfont.lfCharSet = DEFAULT_CHARSET;\n\tTJS_strncpy_s( logfont.lfFaceName, LF_FACESIZE, TVPGetDefaultFontName(), LF_FACESIZE );\n\tlogfont.lfItalic = FALSE;\n\tlogfont.lfUnderline = FALSE;\n\tlogfont.lfStrikeOut = FALSE;\n\tApplyFont( &logfont );\n}\ntTVPSysFont::tTVPSysFont( const tTVPFont &font ) : hFont_(INVALID_HANDLE_VALUE), hOldFont_(INVALID_HANDLE_VALUE), hMemDC_(INVALID_HANDLE_VALUE),\n\thBmp_(INVALID_HANDLE_VALUE), hOldBmp_(INVALID_HANDLE_VALUE) {\n\n\tInitializeMemDC();\n\n\tHFONT hFont = (HFONT)::GetStockObject( ANSI_FIXED_FONT );\n\tLOGFONT LogFont={0};\n\tLogFont.lfHeight = -std::abs(font.Height);\n\tLogFont.lfItalic = (font.Flags & TVP_TF_ITALIC) ? TRUE:FALSE;\n\tLogFont.lfWeight = (font.Flags & TVP_TF_BOLD) ? 700 : 400;\n\tLogFont.lfUnderline = (font.Flags & TVP_TF_UNDERLINE) ? TRUE:FALSE;\n\tLogFont.lfStrikeOut = (font.Flags & TVP_TF_STRIKEOUT) ? TRUE:FALSE;\n\tLogFont.lfEscapement = LogFont.lfOrientation = font.Angle;\n\tLogFont.lfCharSet = DEFAULT_CHARSET;\n\tLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;\n\tLogFont.lfQuality = DEFAULT_QUALITY;\n\tLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\n\tttstr face = TVPFontSystem->GetBeingFont(font.Face.AsStdString());\n\tTJS_strncpy_s(LogFont.lfFaceName, LF_FACESIZE, face.c_str(), LF_FACESIZE -1);\n\tLogFont.lfFaceName[LF_FACESIZE-1] = 0;\n\n\tApplyFont( &LogFont );\n}\ntTVPSysFont::~tTVPSysFont() {\n\t::SelectObject( hMemDC_, hOldBmp_ );\n\tif( INVALID_HANDLE_VALUE != hOldFont_ ) {\n\t\t::SelectObject( hMemDC_, hOldFont_ );\n\t}\n\tif( hFont_ != INVALID_HANDLE_VALUE ) {\n\t\t::DeleteObject( hFont_ );\n\t}\n\t::DeleteObject( hBmp_ );\n\t::DeleteDC( hMemDC_ );\n}\n\nint tTVPSysFont::GetAscentHeight() {\n\tint otmSize = ::GetOutlineTextMetrics( hMemDC_, 0, NULL );\n\tchar *otmBuf = new char[otmSize];\n\tOUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC*)otmBuf;\n\t::GetOutlineTextMetrics( hMemDC_, otmSize, otm );\n\tint result = otm->otmAscent;\n\t//int result = otm->otmMacAscent;\n\tdelete[] otmBuf;\n\treturn result;\n}\n\nvoid tTVPSysFont::Assign( const tTVPSysFont* font ) {\n\tLOGFONT logfont = {0};\n\tfont->GetFont( &logfont );\n\tApplyFont( &logfont );\n}\nvoid tTVPSysFont::Assign( const tTVPFont &font ) {\n\tLOGFONT LogFont={0};\n\tLogFont.lfHeight = -std::abs(font.Height);\n\tLogFont.lfItalic = (font.Flags & TVP_TF_ITALIC) ? TRUE:FALSE;\n\tLogFont.lfWeight = (font.Flags & TVP_TF_BOLD) ? 700 : 400;\n\tLogFont.lfUnderline = (font.Flags & TVP_TF_UNDERLINE) ? TRUE:FALSE;\n\tLogFont.lfStrikeOut = (font.Flags & TVP_TF_STRIKEOUT) ? TRUE:FALSE;\n\tLogFont.lfEscapement = LogFont.lfOrientation = font.Angle;\n\tLogFont.lfCharSet = DEFAULT_CHARSET;\n\tLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;\n\tLogFont.lfQuality = DEFAULT_QUALITY;\n\tLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\n\tttstr face = TVPFontSystem->GetBeingFont(font.Face.AsStdString());\n\tTJS_strncpy_s(LogFont.lfFaceName, LF_FACESIZE, face.c_str(), LF_FACESIZE -1);\n\tLogFont.lfFaceName[LF_FACESIZE-1] = 0;\n\tApplyFont( &LogFont );\n}\nvoid tTVPSysFont::ApplyFont( const LOGFONT* info ) {\n\tHFONT hFont = ::CreateFontIndirect( info );\n\tif( hFont_ != INVALID_HANDLE_VALUE ) {\n\t\tHFONT hOld = ::SelectObject( hMemDC_, hFont );\n\t\t//assert( hOld == hFont_ );\n\t\t::DeleteObject( hOld );\n\t\thFont_ = hFont;\n\t} else {\n\t\thOldFont_ = ::SelectObject( hMemDC_, hFont );\n\t\thFont_ = hFont;\n\t}\n}\nvoid tTVPSysFont::GetFont( LOGFONT* font ) const {\n\t::GetObject( hFont_, sizeof(LOGFONT), font );\n}\n\n//---------------------------------------------------------------------------\nstruct tTVPFSEnumFontsProcData {\n\tstd::vector<ttstr> &List;\n\ttjs_uint32 Flags;\n\tBYTE CharSet;\n\ttTVPFSEnumFontsProcData(std::vector<ttstr> & list, tjs_uint32 flags, BYTE charSet) :\n\t\tList(list), Flags(flags), CharSet(charSet) {\n\t}\n};\n//---------------------------------------------------------------------------\n/**\n * @param lpelfe : pointer to logical-font data\n * @param lpntme : pointer to physical-font data\n * @param FontType : type of font\n */\nstatic int CALLBACK TVPFSFEnumFontsProc( ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, int FontType, LPARAM userdata ) {\n\t// enumerate fonts\n\ttTVPFSEnumFontsProcData *data = reinterpret_cast<tTVPFSEnumFontsProcData*>(userdata);\n\tif( data->Flags & TVP_FSF_FIXEDPITCH ) {\n\t\t// fixed pitch only ?\n\t\tif(lpntme->ntmTm.tmPitchAndFamily & TMPF_FIXED_PITCH) return 1;\n\t}\n\n\tif( data->Flags & TVP_FSF_SAMECHARSET ) {\n\t\t// same character set only ?\n\t\tif(lpelfe->elfLogFont.lfCharSet != data->CharSet ) return 1;\n\t}\n\n\tif( data->Flags & TVP_FSF_IGNORESYMBOL ) {\n\t\tif(lpelfe->elfLogFont.lfCharSet == SYMBOL_CHARSET ) return 1;\n\t}\n\n\tif( data->Flags & TVP_FSF_NOVERTICAL ) {\n\t\t// not to list vertical fonts up ?\n\t\tif(lpelfe->elfLogFont.lfFaceName[0] == '@') return 1;\n\t}\n\n\tif( data->Flags & TVP_FSF_TRUETYPEONLY ) {\n\t\t// true type or opentype only ?\n\t\tbool is_outline = (lpntme->ntmTm.ntmFlags &  NTM_PS_OPENTYPE) || (lpntme->ntmTm.ntmFlags &  NTM_TT_OPENTYPE) || (FontType & TRUETYPE_FONTTYPE);\n\t\tif(!is_outline) return 1;\n\t}\n\n\tttstr facename(lpelfe->elfLogFont.lfFaceName);\n\tif(std::find(data->List.begin(), data->List.end(), facename) == data->List.end())\n\t\tdata->List.push_back(facename); // not insert the same face twice\n\n\treturn 1;\n}\n// tHgLZbg𓾂\nstatic int CALLBACK TVPFSFEnumCurFaceFontsProc( ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, int FontType, LPARAM userdata ) {\n\tBYTE* data = reinterpret_cast<BYTE*>(userdata);\n\t*data = lpelfe->elfLogFont.lfCharSet;\n\t// lpntme->ntmTm.tmDefaultChar;\n\treturn 0;\n}\nstatic void SetDefaultLogFont( LOGFONT& l, const tjs_char* face ) {\n\tl.lfHeight = -12;\n\tl.lfWidth = 0;\n\tl.lfEscapement = 0;\n\tl.lfOrientation = 0;\n\tl.lfWeight = 400;\n\tl.lfItalic = FALSE;\n\tl.lfUnderline = FALSE;\n\tl.lfStrikeOut = FALSE;\n\tl.lfCharSet = DEFAULT_CHARSET;\n\tl.lfOutPrecision = OUT_DEFAULT_PRECIS;\n\tl.lfQuality = DEFAULT_QUALITY;\n\tl.lfPitchAndFamily = 0;\n\tif( face ) {\n\t\tTJS_strncpy_s( l.lfFaceName, LF_FACESIZE, face, LF_FACESIZE );\n\t} else {\n\t\tl.lfFaceName[0] = '\\0';\n\t}\n}\nvoid TVPGetFontList(std::vector<ttstr> & list, tjs_uint32 flags, const tTVPFont & font) {\n\tLOGFONT l;\n\tSetDefaultLogFont( l, NULL );\n\n\tLOGFONT clf;\n\tmemcpy( &clf, &l, sizeof(LOGFONT) );\n\tTJS_strncpy_s( clf.lfFaceName, LF_FACESIZE, font.Face.c_str(), LF_FACESIZE );\n\n\tHDC dc = ::GetDC(NULL);\n\tBYTE charSet = DEFAULT_CHARSET;\n\t::EnumFontFamiliesEx( dc, &clf, (FONTENUMPROC)TVPFSFEnumCurFaceFontsProc, reinterpret_cast<LPARAM>(&charSet), 0);\n\ttTVPFSEnumFontsProcData data( list, flags, charSet );\n\t::EnumFontFamiliesEx( dc, &l, (FONTENUMPROC)TVPFSFEnumFontsProc, reinterpret_cast<LPARAM>(&data), 0);\n \t::ReleaseDC(NULL, dc);\n}\ntjs_uint8 TVPGetCharSetFromFaceName( const tjs_char* face ) {\n\tLOGFONT l;\n\tSetDefaultLogFont( l, face );\n\tHDC dc = ::GetDC(NULL);\n\tBYTE charSet = DEFAULT_CHARSET;\n\t::EnumFontFamiliesEx( dc, &l, (FONTENUMPROC)TVPFSFEnumCurFaceFontsProc, reinterpret_cast<LPARAM>(&charSet), 0);\n \t::ReleaseDC(NULL, dc);\n\treturn charSet;\n}\n#if 0\nstatic int CALLBACK TVPFSFEnumDefaultCharProc( ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, int FontType, LPARAM userdata ) {\n\ttjs_char* data = reinterpret_cast<tjs_char*>(userdata);\n\t// *data = lpntme->ntmTm.tmDefaultChar;\n\t*data = lpntme->ntmTm.tmBreakChar;\n\treturn 0;\n}\ntjs_char TVPGetDefaultCharFromFaceName( const tjs_char* face ) {\n\tLOGFONT l;\n\tSetDefaultLogFont( l, face );\n\tHDC dc = ::GetDC(NULL);\n\ttjs_char defchar = 0;\n\t::EnumFontFamiliesEx( dc, &l, (FONTENUMPROC)TVPFSFEnumDefaultCharProc, reinterpret_cast<LPARAM>(&defchar), 0);\n \t::ReleaseDC(NULL, dc);\n\treturn defchar;\n}\n#endif\nstatic int CALLBACK EnumAllFontsProc( LOGFONT *lplf, TEXTMETRIC *lptm, DWORD type, LPARAM data ) {\n\tstd::vector<ttstr>* list = (std::vector<ttstr>*)data;\n\tlist->push_back(ttstr(lplf->lfFaceName));\n\treturn 1;\n}\nvoid TVPGetAllFontList(std::vector<ttstr>& list) {\n\tHDC dc = ::GetDC(NULL);\n\t::EnumFonts(dc, NULL, (FONTENUMPROC)EnumAllFontsProc,(LPARAM)&list );\n \t::ReleaseDC(NULL, dc);\n}\n\n\n"
  },
  {
    "path": "src/core/visual/win32/TVPSysFont.h",
    "content": "#ifndef __TVP_SYS_FONT_H__\n#define __TVP_SYS_FONT_H__\n\nclass tTVPSysFont {\n// \tHFONT hFont_;\n// \tHFONT hOldFont_;\n// \tHDC hMemDC_;\n// \tHBITMAP hBmp_;\n// \tHBITMAP hOldBmp_;\n\nprivate:\n\tvoid InitializeMemDC();\n\npublic:\n\ttTVPSysFont();\n\ttTVPSysFont( const tTVPFont &font );\n\t~tTVPSysFont();\n\n\tint GetAscentHeight();\n\tvoid Assign( const tTVPSysFont* font );\n\tvoid Assign( const tTVPFont &font );\n// \tvoid ApplyFont( const LOGFONT* info );\n// \tvoid GetFont( LOGFONT* font ) const;\n// \tHDC GetDC() { return hMemDC_; }\n};\n\nextern void TVPGetAllFontList(std::vector<ttstr>& list);\nextern void TVPGetFontList(std::vector<ttstr> & list, tjs_uint32 flags, const tTVPFont & font);\nextern tjs_uint8 TVPGetCharSetFromFaceName( const tjs_char* face );\n#endif // __TVP_SYS_FONT_H__\n"
  },
  {
    "path": "src/core/visual/win32/VSyncTimingThread.cpp",
    "content": "\n#include \"tjsCommHead.h\"\n\n#include <mmsystem.h>\n\n#include \"VSyncTimingThread.h\"\n#include \"WindowImpl.h\"\n#include \"EventIntf.h\"\n#include \"UserEvent.h\"\n#include \"DebugIntf.h\"\n#include \"MsgIntf.h\"\n\n//---------------------------------------------------------------------------\ntTVPVSyncTimingThread::tTVPVSyncTimingThread(tTJSNI_Window* owner)\n\t : tTVPThread(true), EventQueue(this,&tTVPVSyncTimingThread::Proc), OwnerWindow(owner)\n{\n\tSleepTime = 1;\n\tLastVBlankTick = 0;\n\tVSyncInterval = 16; // 60FPS\n\tEnabled = false;\n\tEventQueue.Allocate();\n\tMeasureVSyncInterval();\n\tResume();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\ntTVPVSyncTimingThread::~tTVPVSyncTimingThread()\n{\n\tTerminate();\n\tResume();\n\tEvent.Set();\n\tWaitFor();\n\tEventQueue.Deallocate();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPVSyncTimingThread::Execute()\n{\n\twhile(!GetTerminated())\n\t{\n\t\t// SleepTime  LastVBlankTick 𓾂\n\t\tDWORD sleep_time, last_vblank_tick;\n\t\t{\t// thread-protected\n\t\t\ttTJSCriticalSectionHolder holder(CS);\n\t\t\tsleep_time = SleepTime;\n\t\t\tlast_vblank_tick = LastVBlankTick;\n\t\t}\n\n\t\t// SleepTime \n\t\t// LastVBlankTick NZASleepTime \n\t\tDWORD sleep_start_tick = timeGetTime();\n\n\t\tDWORD sleep_time_adj = sleep_start_tick - last_vblank_tick;\n\n\t\tif(sleep_time_adj < sleep_time)\n\t\t{\n\t\t\t::Sleep(sleep_time - sleep_time_adj);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// ʁACXbh Event.Set() Ȃ΁A\n\t\t\t// ^CXCX(10ms) I鍠\n\t\t\t// ɗĂ͂łB\n\t\t\t// sleep_time ͒ʏ 10ms 蒷̂ŁA\n\t\t\t// ɗĂُ͈̂B\n\t\t\t// قǃVXedԂɂȂĂƍlB\n\t\t\t// ŗđ Cxg|Xg킯ɂ͂Ȃ̂\n\t\t\t// KȎ({ɓK) B\n\t\t\t::Sleep(5);\n\t\t}\n\n\t\t// Cxg|Xg\n\t\tNativeEvent ev(TVP_EV_VSYNC_TIMING_THREAD);\n\t\tev.LParam = (LPARAM)sleep_start_tick;\n\t\tEventQueue.PostEvent(ev);\n\n\t\tEvent.WaitFor(0x7fffffff); // vsync ܂ő҂\n\t}\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPVSyncTimingThread::Proc( NativeEvent& ev )\n{\n\tif(ev.Message != TVP_EV_VSYNC_TIMING_THREAD) {\n\t\tEventQueue.HandlerDefault(ev);\n\t\treturn;\n\t}\n\tif( OwnerWindow == NULL ) return;\n\n\t// tTVPVSyncTimingThread 瓊ꂽbZ[W\n\n\ttjs_int in_vblank = 0;\n\ttjs_int delayed = 0;\n\tbool supportvwait = OwnerWindow->WaitForVBlank( &in_vblank, &delayed );\n\tif( supportvwait == false )\n\t{\t// VBlank҂̓T|[gĂȂ̂ŁACɂ̂܂ܐis(҂Ԃ͂CɂȂƂɂ)\n\t\tin_vblank = 0;\n\t\tdelayed = 0;\n\t}\n\n\t// ^C}̎Ԍ_ݒ肷\n\tif(!delayed)\n\t{\n\t\ttTJSCriticalSectionHolder holder(CS);\n\t\tLastVBlankTick = timeGetTime(); // ꂪɖ鎞Ԃ̋NZ_ɂȂ\n\t}\n\telse\n\t{\n\t\ttTJSCriticalSectionHolder holder(CS);\n\t\tLastVBlankTick += VSyncInterval; // ꂪɖ鎞Ԃ̋NZ_ɂȂ()\n\t\tif((long) (timeGetTime() - (LastVBlankTick + SleepTime)) <= 0)\n\t\t{\n\t\t\t// AɋN悤Ƃ鎞ԂłɉߋȂ̂Ŗ܂\n\t\t\tLastVBlankTick = timeGetTime(); // Iɍ̎ɂ܂\n\t\t}\n\t}\n\n\t// ʂ̍XVs (DrawDeviceShow\\bhĂ)\n\tOwnerWindow->DeliverDrawDeviceShow();\n\n\t//  vsync ҂sOAł vblank ɓĂꍇ́A\n\t// ҂ԂƌƂł\n\tif(in_vblank)\n\t{\n\t\t// ̏ꍇ SleepTime 炷\n\t\ttTJSCriticalSectionHolder holder(CS);\n\t\tif(SleepTime > 8) SleepTime --;\n\t}\n\telse\n\t{\n\t\t// vblank Ŗꍇ͓̏ꍇl\n\t\t// 1. vblank O\n\t\t// 2. vblank ゾ\n\t\t// ǂ͕Ȃ\n\t\t// SleepTime 𑝂₷Bꂪ VSyncInterval 𒴂͂͂ȂB\n\t\ttTJSCriticalSectionHolder holder(CS);\n\t\tSleepTime ++;\n\t\tif(SleepTime > VSyncInterval) SleepTime = VSyncInterval;\n\t}\n\n\t// ^C}N\n\tEvent.Set();\n\n\t// ContinuousHandler Ă\n\t// ͏\\ȎԂƂ悤Avsync ҂̒ɌĂ΂\n\tTVPProcessContinuousHandlerEventFlag = true; // set flag to invoke continuous handler on next idle\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nvoid tTVPVSyncTimingThread::MeasureVSyncInterval()\n{\n\tTVPEnsureDirect3DObject();\n\n\tDWORD vsync_interval = 10000;\n\tDWORD vsync_rate = 0;\n\n\tHDC dc = ::GetDC(0);\n\tvsync_rate = ::GetDeviceCaps(dc, VREFRESH);\n\t::ReleaseDC(0, dc);\n\n\tif(vsync_rate != 0)\n\t\tvsync_interval = 1000 / vsync_rate;\n\telse\n\t\tvsync_interval = 0;\n\n\tTVPAddLog( TVPFormatMessage(TVPRoughVsyncIntervalReadFromApi,ttstr((int)vsync_interval)) );\n\n\t// vsync ͓K؂ۂH\n\tif(vsync_interval < 6 || vsync_interval > 66)\n\t{\n\t\tTVPAddLog( (const tjs_char*)TVPRoughVsyncIntervalStillSeemsWrong );\n\t\tvsync_interval = 16;\n\t}\n\n\tVSyncInterval = vsync_interval;\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/win32/VSyncTimingThread.h",
    "content": "\n#ifndef __VSYNC_TIMING_THREAD_H__\n#define __VSYNC_TIMING_THREAD_H__\n\n#include \"ThreadIntf.h\"\n#include \"NativeEventQueue.h\"\n\n//---------------------------------------------------------------------------\n// VSyncp̃^C~O𔭐邽߂̃Xbh\n//---------------------------------------------------------------------------\nclass tTVPVSyncTimingThread : public tTVPThread\n{\n\ttjs_uint32 SleepTime;\n\ttTVPThreadEvent Event;\n\ttTJSCriticalSection CS;\n\ttjs_uint32 VSyncInterval; //!< VSync ̊Ԋu(Qll)\n\ttjs_uint32 LastVBlankTick; //!< Ō vblank ̎\n\n\tbool Enabled;\n\n\tNativeEventQueue<tTVPVSyncTimingThread> EventQueue;\n\n\tclass tTJSNI_Window* OwnerWindow;\npublic:\n\ttTVPVSyncTimingThread(class tTJSNI_Window* owner);\n\t~tTVPVSyncTimingThread();\n\nprotected:\n\tvoid Execute();\n\tvoid Proc( NativeEvent& ev );\n\npublic:\n\tvoid MeasureVSyncInterval(); // VSyncInterval v\n};\n//---------------------------------------------------------------------------\n\n#endif // __VSYNC_TIMING_THREAD_H__\n"
  },
  {
    "path": "src/core/visual/win32/VideoOvlImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Video Overlay support implementation\n//---------------------------------------------------------------------------\n\n\n#include \"tjsCommHead.h\"\n\n#include <algorithm>\n#include \"MsgIntf.h\"\n#include \"VideoOvlImpl.h\"\n#include \"DebugIntf.h\"\n#include \"LayerIntf.h\"\n#include \"LayerBitmapIntf.h\"\n#include \"SysInitIntf.h\"\n#include \"StorageImpl.h\"\n#include \"krmovie.h\"\n#include \"PluginImpl.h\"\n#include \"WaveImpl.h\"  // for DirectSound attenuate <-> TVP volume\n//#include <evcode.h>\n\n#include \"Application.h\"\n#include \"combase.h\"\n\nextern void GetVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, struct IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, class iTVPVideoOverlay **out);\n\nextern void GetVideoLayerObject(\n\ttTJSNI_VideoOverlay* callbackwin, struct IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, class iTVPVideoOverlay **out);\n\nextern void GetMixingVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, struct IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, class iTVPVideoOverlay **out);\n\nextern void GetMFVideoOverlayObject(\n\ttTJSNI_VideoOverlay* callbackwin, struct IStream *stream, const tjs_char * streamname,\n\tconst tjs_char *type, uint64_t size, class iTVPVideoOverlay **out);\n\n//---------------------------------------------------------------------------\nstatic std::vector<tTJSNI_VideoOverlay *> TVPVideoOverlayVector;\n//---------------------------------------------------------------------------\nstatic void TVPAddVideOverlay(tTJSNI_VideoOverlay *ovl)\n{\n\tTVPVideoOverlayVector.push_back(ovl);\n}\n//---------------------------------------------------------------------------\nstatic void TVPRemoveVideoOverlay(tTJSNI_VideoOverlay *ovl)\n{\n\tstd::vector<tTJSNI_VideoOverlay*>::iterator i;\n\ti = std::find(TVPVideoOverlayVector.begin(), TVPVideoOverlayVector.end(), ovl);\n\tif(i != TVPVideoOverlayVector.end())\n\t\tTVPVideoOverlayVector.erase(i);\n}\n//---------------------------------------------------------------------------\nstatic void TVPShutdownVideoOverlay()\n{\n\t// shutdown all overlay object and release krmovie.dll / krflash.dll\n\tstd::vector<tTJSNI_VideoOverlay*>::iterator i;\n\tfor(i = TVPVideoOverlayVector.begin(); i != TVPVideoOverlayVector.end(); i++)\n\t{\n\t\t(*i)->Shutdown();\n\t}\n}\nstatic tTVPAtExit TVPShutdownVideoOverlayAtExit\n\t(TVP_ATEXIT_PRI_PREPARE, TVPShutdownVideoOverlay);\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_VideoOverlay\n//---------------------------------------------------------------------------\ntTJSNI_VideoOverlay::tTJSNI_VideoOverlay()\n: EventQueue(this,&tTJSNI_VideoOverlay::WndProc)\n{\n\tVideoOverlay = NULL;\n\tRect.left = 0;\n\tRect.top = 0;\n\tRect.right = 320;\n\tRect.bottom = 240;\n\tVisible = false;\n//\tOwnerWindow = NULL;\n\tLocalTempStorageHolder = NULL;\n\n\tEventQueue.Allocate();\n\n\tLayer1 = NULL;\n\tLayer2 = NULL;\n\tMode = vomOverlay;\n\tLoop = false;\n\tIsPrepare = false;\n\tSegLoopStartFrame = -1;\n\tSegLoopEndFrame = -1;\n\tIsEventPast = false;\n\tEventFrame = -1;\n\n\tBitmap[0] = Bitmap[1] = NULL;\n\tBmpBits[0] = BmpBits[1] = NULL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_VideoOverlay::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = inherited::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_VideoOverlay::Invalidate()\n{\n\tinherited::Invalidate();\n\n\tClose();\n\tif (CachedOverlay) {\n\t\tCachedOverlay->Release();\n\t\tCachedOverlay = nullptr;\n\t}\n\tEventQueue.Deallocate();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Open(const ttstr &_name)\n{\n\t// open\n\n\t// first, close\n\tClose();\n\n\n\t// check window\n\tif(!Window) TVPThrowExceptionMessage(TVPWindowAlreadyMissing);\n\n\t// open target storage\n\tttstr name(_name);\n\tttstr param;\n\n\tconst tjs_char * param_pos;\n\tint param_pos_ind;\n\tparam_pos = TJS_strchr(name.c_str(), TJS_W('?'));\n\tparam_pos_ind = (int)(param_pos - name.c_str());\n\tif(param_pos != NULL)\n\t{\n\t\tparam = param_pos;\n\t\tname = ttstr(name, param_pos_ind);\n\t}\n\n\tIStream *istream = NULL;\n\tlong size;\n\tttstr ext = TVPExtractStorageExt(name).c_str();\n\text.ToLowerCase();\n\n\t{\n\t\t// prepate IStream\n\t\ttTJSBinaryStream *stream0 = NULL;\n\t\ttry\n\t\t{\n\t\t\tstream0 = TVPCreateStream(name);\n\t\t\tsize = (long)stream0->GetSize();\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tif(stream0) delete stream0;\n\t\t\tthrow;\n\t\t}\n\n\t\tistream = TVPCreateIStream(stream0);\n\t}\n\n\t// 'istream' is an IStream instance at this point\n\n\t// create video overlay object\n\ttry\n\t{\n\t\tif (CachedOverlay && CachedOverlayMode == Mode && CachedPlayingFile == _name) {\n\t\t\tVideoOverlay = CachedOverlay;\n\t\t\tCachedOverlay = nullptr;\n\t\t\tVideoOverlay->Rewind();\n\t\t} else {\n\t\t\tif (CachedOverlay) {\n\t\t\t\tCachedOverlay->Release();\n\t\t\t\tCachedOverlay = nullptr;\n\t\t\t}\n\t\t\tif (Mode == vomLayer)\n\t\t\t\tGetVideoLayerObject(EventQueue.GetOwner(), istream, name.c_str(), ext.c_str(), size, &VideoOverlay);\n\t\t\telse if(Mode == vomMixer)\n\t\t\t\tGetMixingVideoOverlayObject(EventQueue.GetOwner(), istream, name.c_str(), ext.c_str(), size, &VideoOverlay);\n\t\t\telse if(Mode == vomMFEVR)\n\t\t\t\tGetMFVideoOverlayObject(EventQueue.GetOwner(), istream, name.c_str(), ext.c_str(), size, &VideoOverlay);\n\t\t\telse\n\t\t\t\tGetVideoOverlayObject(EventQueue.GetOwner(), istream, name.c_str(), ext.c_str(), size, &VideoOverlay);\n\t\t}\n\t\tif( (Mode == vomOverlay) || (Mode == vomMixer) || (Mode == vomMFEVR) )\n\t\t{\n\t\t\tResetOverlayParams();\n\t\t}\n\t\telse\n\t\t{\t// set font and back buffer to layerVideo\n\t\t\tlong\twidth, height;\n\t\t\tlong\t\t\tsize;\n\t\t\tVideoOverlay->GetVideoSize( &width, &height );\n\t\t\t\n\t\t\tif( width <= 0 || height <= 0 )\n\t\t\t\tTVPThrowExceptionMessage(TVPErrorInKrMovieDLL, (const tjs_char*)TVPInvalidVideoSize);\n\n\t\t\tsize = width * height * 4;\n\t\t\tif( Bitmap[0] != NULL )\n\t\t\t\tdelete Bitmap[0];\n\t\t\tif( Bitmap[1] != NULL )\n\t\t\t\tdelete Bitmap[1];\n\t\t\tBitmap[0] = new tTVPBaseTexture(width, height, 32);\n\t\t\tBitmap[1] = new tTVPBaseTexture(width, height, 32);\n#if 0\n\t\t\tBmpBits[0] = static_cast<BYTE*>(Bitmap[0]->GetBitmap()->GetScanLine( Bitmap[0]->GetBitmap()->GetHeight()-1 ));\n\t\t\tBmpBits[1] = static_cast<BYTE*>(Bitmap[1]->GetBitmap()->GetScanLine( Bitmap[1]->GetBitmap()->GetHeight()-1 ));\n#endif\n\t\t\tVideoOverlay->SetVideoBuffer(Bitmap[0], Bitmap[1], size);\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tif(istream) istream->Release();\n\t\tClose();\n\t\tthrow;\n\t}\n\tif(istream) istream->Release();\n\n\t// set Status\n\tClearWndProcMessages();\n\tSetStatus(ssStop);\n\tCachedPlayingFile = _name;\n\tCachedOverlayMode = Mode;\n\tif (Loop) VideoOverlay->SetLoopSegement(0, -1);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Close()\n{\n\t// close\n\t// release VideoOverlay object\n\tif(VideoOverlay)\n\t{\n\t\tif (CachedOverlay) {\n\t\t\tCachedOverlay->Release();\n\t\t\tCachedOverlay = nullptr;\n\t\t}\n\t\tVideoOverlay->SetVisible(false);\n\t\tVideoOverlay->Pause();\n\t\tCachedOverlay = VideoOverlay;\n\t\tVideoOverlay = NULL;\n//\t\t::SetFocus(Window->GetWindowHandle());\n\t}\n\tif(LocalTempStorageHolder)\n\t\tdelete LocalTempStorageHolder, LocalTempStorageHolder = NULL;\n\tClearWndProcMessages();\n\tSetStatus(ssUnload);\n\n\tif( Bitmap[0] )\n\t\tdelete Bitmap[0];\n\tif( Bitmap[1] )\n\t\tdelete Bitmap[1];\n\n\tBitmap[0] = Bitmap[1] = NULL;\n\tBmpBits[0] = BmpBits[1] = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Shutdown()\n{\n\t// shutdown the system\n\t// this functions closes the overlay object, but must not fire any events.\n\tbool c = CanDeliverEvents;\n\tClearWndProcMessages();\n\tSetStatus(ssUnload);\n\ttry\n\t{\n\t\tif (VideoOverlay) {\n\t\t\tif (CachedOverlay) {\n\t\t\t\tCachedOverlay->Release();\n\t\t\t\tCachedOverlay = nullptr;\n\t\t\t}\n\t\t\tVideoOverlay->SetVisible(false);\n\t\t\tVideoOverlay->Pause();\n\t\t\tCachedOverlay = VideoOverlay;\n\t\t\tVideoOverlay = NULL;\n\t\t}\n\t}\n\tcatch(...)\n\t{\n\t\tCanDeliverEvents = c;\n\t\tthrow;\n\t}\n\tCanDeliverEvents = c;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Disconnect()\n{\n\t// disconnect the object\n\tShutdown();\n\n\tWindow = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Play()\n{\n\t// start playing\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->Play();\n\t\tClearWndProcMessages();\n\t\tif( Mode != vomMFEVR ) SetStatus(ssPlay);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Stop()\n{\n\t// stop playing\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->Stop();\n\t\tClearWndProcMessages();\n\t\tif( Mode != vomMFEVR ) SetStatus(ssStop);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::Pause()\n{\n\t// pause playing\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->Pause();\n//\t\tClearWndProcMessages();\n\t\tif( Mode != vomMFEVR ) SetStatus(ssPause);\n\t}\n}\nvoid tTJSNI_VideoOverlay::Rewind()\n{\n\t// rewind playing\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->Rewind();\n\t\tif (Status == ssPlay)\n\t\t\tVideoOverlay->Play();\n\t\tClearWndProcMessages();\n\n\t\tif( EventFrame >= 0 && IsEventPast )\n\t\t\tIsEventPast = false;\n\t}\n}\nvoid tTJSNI_VideoOverlay::Prepare()\n{\t// prepare movie\n\tif( VideoOverlay && (Mode == vomLayer) )\n\t{\n\t\tPause();\n\t\tRewind();\n\t\tIsPrepare = true;\n\t\tPlay();\n\t}\n}\nvoid tTJSNI_VideoOverlay::SetSegmentLoop( int comeFrame, int goFrame )\n{\n\tSegLoopStartFrame = comeFrame;\n\tSegLoopEndFrame = goFrame;\n\tif (VideoOverlay) VideoOverlay->SetLoopSegement(SegLoopStartFrame, SegLoopEndFrame);\n}\nvoid tTJSNI_VideoOverlay::SetPeriodEvent( int eventFrame )\n{\n\tEventFrame = eventFrame;\n\n\tif( eventFrame <= GetFrame() )\n\t\tIsEventPast = true;\n\telse\n\t\tIsEventPast = false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetRectangleToVideoOverlay()\n{\n\t// set Rectangle to video overlay\n\tif(VideoOverlay /*&& OwnerWindow*/)\n\t{\n\t\ttjs_int ofsx, ofsy;\n\t\tWindow->GetVideoOffset(ofsx, ofsy);\n\t\ttjs_int l = Rect.left;\n\t\ttjs_int t = Rect.top;\n\t\ttjs_int r = Rect.right;\n\t\ttjs_int b = Rect.bottom;\n\t\tTVPAddLog(TJS_W(\"Video zoom: (\") + ttstr(l) + TJS_W(\",\") + ttstr(t) + TJS_W(\")-(\") +\n\t\t\tttstr(r) + TJS_W(\",\") + ttstr(b) + TJS_W(\") ->\"));\n\t\tWindow->ZoomRectangle(l, t, r, b);\n\t\tTVPAddLog(TJS_W(\"(\") + ttstr(l) + TJS_W(\",\") + ttstr(t) + TJS_W(\")-(\") +\n\t\t\tttstr(r) + TJS_W(\",\") + ttstr(b) + TJS_W(\")\"));\n\t//\tRECT rect = {l + ofsx, t + ofsy, r + ofsx, b + ofsy};\n\t\tVideoOverlay->SetRect(l + ofsx, t + ofsy, r + ofsx, b + ofsy);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetPosition(tjs_int left, tjs_int top)\n{\n\tif( Mode == vomLayer )\n\t{\n\t\tif( Layer1 != NULL ) Layer1->SetPosition( left, top );\n\t\tif( Layer2 != NULL ) Layer2->SetPosition( left, top );\n\t}\n\telse\n\t{\n\t\tRect.set_offsets(left, top);\n\t\tSetRectangleToVideoOverlay();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetSize(tjs_int width, tjs_int height)\n{\n\tif( Mode == vomLayer ) return;\n\n\tRect.set_size(width, height);\n\tSetRectangleToVideoOverlay();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetBounds(const tTVPRect & rect)\n{\n\tif( Mode == vomLayer ) return;\n\n\tRect = rect;\n\tSetRectangleToVideoOverlay();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetLeft(tjs_int l)\n{\n\tif( Mode == vomLayer )\n\t{\n\t\tif( Layer1 != NULL ) Layer1->SetLeft( l );\n\t\tif( Layer2 != NULL ) Layer2->SetLeft( l );\n\t}\n\telse\n\t{\n\t\tRect.set_offsets(l, Rect.top);\n\t\tSetRectangleToVideoOverlay();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetTop(tjs_int t)\n{\n\tif( Mode == vomLayer )\n\t{\n\t\tif( Layer1 != NULL ) Layer1->SetTop( t );\n\t\tif( Layer2 != NULL ) Layer2->SetTop( t );\n\t}\n\telse\n\t{\n\t\tRect.set_offsets(Rect.left, t);\n\t\tSetRectangleToVideoOverlay();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetWidth(tjs_int w)\n{\n\tif( Mode == vomLayer ) return;\n\n\tRect.right = Rect.left + w;\n\tSetRectangleToVideoOverlay();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetHeight(tjs_int h)\n{\n\tif( Mode == vomLayer ) return;\n\n\tRect.bottom = Rect.top + h;\n\tSetRectangleToVideoOverlay();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetVisible(bool b)\n{\n\tVisible = b;\n\tif(VideoOverlay)\n\t{\n\t\tif( Mode == vomLayer )\n\t\t{\n\t\t\tif( Layer1 != NULL ) Layer1->SetVisible( Visible );\n\t\t\tif( Layer2 != NULL ) Layer2->SetVisible( Visible );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVideoOverlay->SetVisible(Visible);\n\t\t}\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::ResetOverlayParams()\n{\n\t// retrieve new window information from owner window and\n\t// set video owner window / message drain window.\n\t// also sets rectangle and visible state.\n\tif(VideoOverlay && Window && (Mode == vomOverlay || Mode == vomMixer || Mode == vomMFEVR) )\n\t{\n//\t\tOwnerWindow = Window->GetWindowHandle();\n\t\tVideoOverlay->SetWindow(Window);\n\n//\t\tVideoOverlay->SetMessageDrainWindow(Window->GetSurfaceWindowHandle());\n\n\t\t// set Rectangle\n\t\tSetRectangleToVideoOverlay();\n\n\t\t// set Visible\n\t\tVideoOverlay->SetVisible(Visible);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::DetachVideoOverlay()\n{\n\tif(VideoOverlay && Window && (Mode == vomOverlay || Mode == vomMixer || Mode == vomMFEVR) )\n\t{\n\t\tVideoOverlay->SetWindow(NULL);\n\t\tVideoOverlay->SetMessageDrainWindow(EventQueue.GetOwner());\n\t\t\t// once set to util window\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetRectOffset(tjs_int ofsx, tjs_int ofsy)\n{\n\tif(VideoOverlay)\n\t{\n// \t\tRECT r = {Rect.left + ofsx, Rect.top + ofsy,\n// \t\t\tRect.right + ofsx, Rect.bottom + ofsy};\n\t\tVideoOverlay->SetRect(Rect.left + ofsx, Rect.top + ofsy,\n\t\t\tRect.right + ofsx, Rect.bottom + ofsy);\n\t}\n}\n//---------------------------------------------------------------------------\n//void __fastcall tTJSNI_VideoOverlay::WndProc(Messages::TMessage &Msg)\nvoid tTJSNI_VideoOverlay::WndProc( NativeEvent& ev )\n{\n\t// EventQueue's message procedure\n\tif(VideoOverlay)\n\t{\n\t\tswitch(ev.Message) {\n\t\tcase WM_GRAPHNOTIFY:\n\t\t{\n\t\t\tlong evcode;\n//\t\t\tLONG_PTR p1, p2;\n\t\t\tbool got = false;\n\t\t\tdo {\n#if 0\n\t\t\t\tVideoOverlay->GetEvent(&evcode, &p1, &p2, &got);\n\t\t\t\tif( got == false)\n\t\t\t\t\treturn;\n#endif\n\t\t\t\tevcode = ev.WParam;\n\t\t\t\tswitch( evcode )\n\t\t\t\t{\n\t\t\t\t\tcase EC_COMPLETE:\n\t\t\t\t\t\tif( Status == ssPlay )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( Loop )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tRewind();\n\t\t\t\t\t\t\t\tFirePeriodEvent(perLoop); // fire period event by loop rewind\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Graph manager seems not to complete playing\n\t\t\t\t\t\t\t\t// at this point (rewinding the movie at the event\n\t\t\t\t\t\t\t\t// handler called asynchronously from SetStatusAsync\n\t\t\t\t\t\t\t\t// makes continuing playing, but the graph seems to\n\t\t\t\t\t\t\t\t// be unstable).\n\t\t\t\t\t\t\t\t// We manually stop the manager anyway.\n\t\t\t\t\t\t\t\tVideoOverlay->Stop();\n\t\t\t\t\t\t\t\tSetStatusAsync(ssStop); // All data has been rendered\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EC_UPDATE:\n\t\t\t\t\t\tif( Mode == vomLayer && Status == ssPlay )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint\t\tcurFrame = (int)ev.LParam;\n\t\t\t\t\t\t\tif( Layer1 == NULL && Layer2 == NULL )\t// nothing to do.\n\t\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t\t// 2t[ȏ㍷ƂGetFrame() ݂̃t[Ƃ\n\t\t\t\t\t\t\tint frame = GetFrame();\n\t\t\t\t\t\t\tif( (frame+1) < curFrame || (frame-1) > curFrame )\n\t\t\t\t\t\t\t\tcurFrame = frame;\n\n\t\t\t\t\t\t\tif( (!IsPrepare) && (SegLoopEndFrame > 0) && (frame >= SegLoopEndFrame) ) {\n\t\t\t\t\t\t\t\tSetFrame( SegLoopStartFrame > 0 ? SegLoopStartFrame : 0 );\n\t\t\t\t\t\t\t\tFirePeriodEvent(perSegLoop); // fire period event by segment loop rewind\n\t\t\t\t\t\t\t\treturn; // UpdatesȂ\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// get video image size\n\t\t\t\t\t\t\tlong\twidth, height;\n\t\t\t\t\t\t\tVideoOverlay->GetVideoSize( &width, &height );\n\n\t\t\t\t\t\t\ttTJSNI_BaseLayer\t*l1 = Layer1;\n\t\t\t\t\t\t\ttTJSNI_BaseLayer\t*l2 = Layer2;\n\n\t\t\t\t\t\t\t// Check layer image size\n\t\t\t\t\t\t\tif( l1 != NULL )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif( (long)l1->GetImageWidth() != width || (long)l1->GetImageHeight() != height )\n\t\t\t\t\t\t\t\t\tl1->SetImageSize( width, height );\n\t\t\t\t\t\t\t\tif( (long)l1->GetWidth() != width || (long)l1->GetHeight() != height )\n\t\t\t\t\t\t\t\t\tl1->SetSize( width, height );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif( l2 != NULL )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif( (long)l2->GetImageWidth() != width || (long)l2->GetImageHeight() != height )\n\t\t\t\t\t\t\t\t\tl2->SetImageSize( width, height );\n\t\t\t\t\t\t\t\tif( (long)l2->GetWidth() != width || (long)l2->GetHeight() != height )\n\t\t\t\t\t\t\t\t\tl2->SetSize( width, height );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttTVPBaseTexture *buff = VideoOverlay->GetFrontBuffer(  );\n\t\t\t\t\t\t\tif( buff == Bitmap[0] )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif( l1 ) l1->AssignMainImage( Bitmap[0] );\n\t\t\t\t\t\t\t\tif( l2 ) l2->AssignMainImage( Bitmap[0] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\t// 0ȂA1Ƃ݂ȂB\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif( l1 ) l1->AssignMainImage( Bitmap[1] );\n\t\t\t\t\t\t\t\tif( l2 ) l2->AssignMainImage( Bitmap[1] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif( l1 ) l1->Update();\n\t\t\t\t\t\t\tif( l2 ) l2->Update();\n\t\t\t\t\t\t\tFireFrameUpdateEvent( curFrame );\n\n\t\t\t\t\t\t\t// ! Prepare mode ?\n\t\t\t\t\t\t\tif( !IsPrepare )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Send period event ?\n\t\t\t\t\t\t\t\tif( EventFrame >= 0 && !IsEventPast && curFrame >= EventFrame )\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tEventFrame = -1;\n\t\t\t\t\t\t\t\t\tFirePeriodEvent(perPeriod); // fire period event by setPeriodEvent()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\t// Prepare mode\n\t\t\t\t\t\t\t\tFirePeriodEvent(perPrepare); // fire period event by prepare()\n\t\t\t\t\t\t\t\tPause();\n\t\t\t\t\t\t\t\tRewind();\n\t\t\t\t\t\t\t\tIsPrepare = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if( Mode == vomMixer && Status == ssPlay )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint frame = GetFrame();\n\t\t\t\t\t\t\tif( (!IsPrepare) && (SegLoopEndFrame > 0) && (frame >= SegLoopEndFrame) ) {\n\t\t\t\t\t\t\t\tSetFrame( SegLoopStartFrame > 0 ? SegLoopStartFrame : 0 );\n\t\t\t\t\t\t\t\tFirePeriodEvent(perSegLoop); // fire period event by segment loop rewind\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tVideoOverlay->PresentVideoImage();\n\t\t\t\t\t\t\tFireFrameUpdateEvent( frame );\n\t\t\t\t\t\t\t// Send period event ?\n\t\t\t\t\t\t\tif( EventFrame >= 0 && !IsEventPast && frame >= EventFrame )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tEventFrame = -1;\n\t\t\t\t\t\t\t\tFirePeriodEvent(perPeriod); // fire period event by setPeriodEvent()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n//\t\t\t\tVideoOverlay->FreeEventParams( evcode, p1, p2 );\n\t\t\t} while( got );\n\t\t\treturn;\n\t\t}\n\t\tcase WM_CALLBACKCMD:\n\t\t{\n\t\t\t// wparam : command\n\t\t\t// lparam : argument\n\t\t\tFireCallbackCommand((tjs_char*)ev.WParam, (tjs_char*)ev.LParam);\n\t\t\treturn;\n\t\t}\n\t\tcase WM_STATE_CHANGE:\n\t\t\t{\n\t\t\t\tswitch( ev.WParam ) {\n\t\t\t\tcase vsStopped:\n\t\t\t\t\tSetStatusAsync( ssStop );\n\t\t\t\t\tbreak;\n\t\t\t\tcase vsPlaying:\n\t\t\t\t\tSetStatusAsync( ssPlay );\n\t\t\t\t\tbreak;\n\t\t\t\tcase vsPaused:\n\t\t\t\t\tSetStatusAsync( ssPause );\n\t\t\t\t\tbreak;\n\t\t\t\tcase vsReady:\n\t\t\t\t\tSetStatusAsync( ssReady );\n\t\t\t\t\tbreak;\n\t\t\t\tcase vsEnded:\n\t\t\t\t\tif( Status == ssPlay )\n\t\t\t\t\t{\n\t\t\t\t\t\tif( Loop )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tVideoOverlay->Play();\n\t\t\t\t\t\t\tFirePeriodEvent(perLoop); // fire period event by loop rewind\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tVideoOverlay->Stop();\n\t\t\t\t\t\t\tSetStatusAsync(ssStop); // All data has been rendered\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tEventQueue.HandlerDefault(ev);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::SetTimePosition( tjs_uint64 p )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetPosition( p );\n\t}\n}\ntjs_uint64 tTJSNI_VideoOverlay::GetTimePosition()\n{\n\ttjs_uint64\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetPosition( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SetFrame( tjs_int f )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetFrame( f );\n\n\t\tif( EventFrame >= f && IsEventPast )\n\t\t\tIsEventPast = false;\n\t}\n}\ntjs_int tTJSNI_VideoOverlay::GetFrame()\n{\n\ttjs_int\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetFrame( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SetStopFrame( tjs_int f )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetStopFrame( f );\n\t}\n}\nvoid tTJSNI_VideoOverlay::SetDefaultStopFrame()\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetDefaultStopFrame();\n\t}\n}\ntjs_int tTJSNI_VideoOverlay::GetStopFrame()\n{\n\ttjs_int\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetStopFrame( &result );\n\t}\n\treturn result;\n}\ntjs_real tTJSNI_VideoOverlay::GetFPS()\n{\n\ttjs_real\tresult = 0.0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetFPS( &result );\n\t}\n\treturn result;\n}\ntjs_int tTJSNI_VideoOverlay::GetNumberOfFrame()\n{\n\ttjs_int\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetNumberOfFrame( &result );\n\t}\n\treturn result;\n}\ntjs_int64 tTJSNI_VideoOverlay::GetTotalTime()\n{\n\ttjs_int64\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetTotalTime( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SetLoop( bool b )\n{\n\tLoop = b;\n\tif (VideoOverlay) {\n\t\tif (Loop)\n\t\t\tVideoOverlay->SetLoopSegement(0, -1);\n\t\telse\n\t\t\tVideoOverlay->SetLoopSegement(-1, -1);\n\t}\n}\nvoid tTJSNI_VideoOverlay::SetLayer1( tTJSNI_BaseLayer *l )\n{\n\tLayer1 = l;\n}\nvoid tTJSNI_VideoOverlay::SetLayer2( tTJSNI_BaseLayer *l )\n{\n\tLayer2 = l;\n}\nvoid tTJSNI_VideoOverlay::SetMode( tTVPVideoOverlayMode m )\n{\n\t// rfII[ṽ[hύX͋֎~\n\tif( !VideoOverlay )\n\t{\n\t\tMode = m;\n\t}\n}\n\ntjs_real tTJSNI_VideoOverlay::GetPlayRate()\n{\n\ttjs_real\tresult = 0.0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetPlayRate( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SetPlayRate(tjs_real r)\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetPlayRate( r );\n\t}\n}\n\ntjs_int tTJSNI_VideoOverlay::GetAudioBalance()\n{\n\tlong\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetAudioBalance( &result );\n\t}\n\treturn /*TVPDSAttenuateToPan*/( result );\n}\nvoid tTJSNI_VideoOverlay::SetAudioBalance(tjs_int b)\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetAudioBalance( /*TVPPanToDSAttenuate*/( b ) );\n\t}\n}\ntjs_int tTJSNI_VideoOverlay::GetAudioVolume()\n{\n\tlong\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetAudioVolume( &result );\n\t}\n\treturn /*TVPDSAttenuateToVolume*/( result );\n}\nvoid tTJSNI_VideoOverlay::SetAudioVolume(tjs_int b)\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetAudioVolume( /*TVPVolumeToDSAttenuate*/( b ) );\n\t}\n}\ntjs_uint tTJSNI_VideoOverlay::GetNumberOfAudioStream()\n{\n\tunsigned long\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetNumberOfAudioStream( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SelectAudioStream(tjs_uint n)\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SelectAudioStream( n );\n\t}\n}\ntjs_int tTJSNI_VideoOverlay::GetEnabledAudioStream()\n{\n\tlong\t\tresult = -1;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetEnableAudioStreamNum( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::DisableAudioStream()\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->DisableAudioStream();\n\t}\n}\n\ntjs_uint tTJSNI_VideoOverlay::GetNumberOfVideoStream()\n{\n\tunsigned long\tresult = 0;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetNumberOfVideoStream( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SelectVideoStream(tjs_uint n)\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SelectVideoStream( n );\n\t}\n}\ntjs_int tTJSNI_VideoOverlay::GetEnabledVideoStream()\n{\n\tlong\t\tresult = -1;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetEnableVideoStreamNum( &result );\n\t}\n\treturn result;\n}\nvoid tTJSNI_VideoOverlay::SetMixingLayer( tTJSNI_BaseLayer *l )\n{\n\tif(VideoOverlay)\n\t{\n\t\tif( l )\n\t\t{\n\t\t\tif( l->GetVisible() )\n\t\t\t{\n\t\t\t\tfloat\talpha = static_cast<float>(l->GetOpacity()) / 255.0f;\n#if 0\n\t\t\t\tRECT\tdest;\n\t\t\t\tdest.left = l->GetLeft() + l->GetImageLeft();\n\t\t\t\tdest.top = l->GetTop() + l->GetImageTop();\n\t\t\t\tdest.right = dest.left + l->GetImageWidth();\n\t\t\t\tdest.bottom = dest.top + l->GetImageHeight();\n\n\t\t\t\t// tTVPBaseBitmap->tTVPBitmap\n\t\t\t\ttTVPBitmap *bmp = l->GetMainImage()->GetBitmap();\n\t\t\t\tif( bmp )\n\t\t\t\t{\n\t\t\t\t\t// ODC\n\t\t\t\t\tHDC hdc;\n\t\t\t\t\tHDC\t\t\tref = GetDC(0);\n\t\t\t\t\tHBITMAP\t\tmyDIB = CreateDIBitmap( ref, bmp->GetBITMAPINFOHEADER(), CBM_INIT, bmp->GetBits(), bmp->GetBITMAPINFO(), bmp->Is8bit() ? DIB_PAL_COLORS : DIB_RGB_COLORS );\n\t\t\t\t\thdc = CreateCompatibleDC( NULL );\n\t\t\t\t\tHGDIOBJ\t\thOldBmp = SelectObject( hdc, myDIB );\n\n\t\t\t\t\tVideoOverlay->SetMixingBitmap( hdc, &dest, alpha );\n\n\t\t\t\t\tSelectObject( hdc, hOldBmp );\n\t\t\t\t\tDeleteObject( myDIB );\n\t\t\t\t\tDeleteDC( hdc );\n\t\t\t\t}\n#endif\n\t\t\t\tVideoOverlay->SetMixingBitmap(l->GetMainImage(), alpha);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tVideoOverlay->ResetMixingBitmap();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVideoOverlay->ResetMixingBitmap();\n\t\t}\n\t}\n}\nvoid tTJSNI_VideoOverlay::ResetMixingBitmap()\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->ResetMixingBitmap();\n\t}\n}\nvoid tTJSNI_VideoOverlay::SetMixingMovieAlpha( tjs_real a )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetMixingMovieAlpha( static_cast<float>(a) );\n\t}\n}\ntjs_real tTJSNI_VideoOverlay::GetMixingMovieAlpha()\n{\n\tfloat\tret = 0.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetMixingMovieAlpha( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\nvoid tTJSNI_VideoOverlay::SetMixingMovieBGColor( tjs_uint col )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetMixingMovieBGColor( col );\n\t}\n}\ntjs_uint tTJSNI_VideoOverlay::GetMixingMovieBGColor()\n{\n\tunsigned long\tret;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetMixingMovieBGColor( &ret );\n\t}\n\treturn static_cast<tjs_uint>(ret);\n}\n\n\n\ntjs_real tTJSNI_VideoOverlay::GetContrastRangeMin()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetContrastRangeMin( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetContrastRangeMax()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetContrastRangeMax( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetContrastDefaultValue()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetContrastDefaultValue( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetContrastStepSize()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetContrastStepSize( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetContrast()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetContrast( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\nvoid tTJSNI_VideoOverlay::SetContrast( tjs_real v )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetContrast( static_cast<float>(v) );\n\t}\n}\ntjs_real tTJSNI_VideoOverlay::GetBrightnessRangeMin()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetBrightnessRangeMin( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetBrightnessRangeMax()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetBrightnessRangeMax( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetBrightnessDefaultValue()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetBrightnessDefaultValue( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetBrightnessStepSize()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetBrightnessStepSize( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetBrightness()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetBrightness( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\nvoid tTJSNI_VideoOverlay::SetBrightness( tjs_real v )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetBrightness( static_cast<float>(v) );\n\t}\n}\n\ntjs_real tTJSNI_VideoOverlay::GetHueRangeMin()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetHueRangeMin( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetHueRangeMax()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetHueRangeMax( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetHueDefaultValue()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetHueDefaultValue( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetHueStepSize()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetHueStepSize( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetHue()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetHue( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\nvoid tTJSNI_VideoOverlay::SetHue( tjs_real v )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetHue( static_cast<float>(v) );\n\t}\n}\n\ntjs_real tTJSNI_VideoOverlay::GetSaturationRangeMin()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetSaturationRangeMin( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetSaturationRangeMax()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetSaturationRangeMax( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetSaturationDefaultValue()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetSaturationDefaultValue( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetSaturationStepSize()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetSaturationStepSize( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\ntjs_real tTJSNI_VideoOverlay::GetSaturation()\n{\n\tfloat ret = -1.0f;\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->GetSaturation( &ret );\n\t}\n\treturn static_cast<tjs_real>(ret);\n}\nvoid tTJSNI_VideoOverlay::SetSaturation( tjs_real v )\n{\n\tif(VideoOverlay)\n\t{\n\t\tVideoOverlay->SetSaturation( static_cast<float>(v) );\n\t}\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_VideoOverlay::GetOriginalWidth()\n{\n\t// retrieve original (coded in the video stream) width size\n\tif(!VideoOverlay) return 0;\n\n\tlong\twidth, height;\n\tVideoOverlay->GetVideoSize( &width, &height );\n\n\treturn (tjs_int)width;\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_VideoOverlay::GetOriginalHeight()\n{\n\t// retrieve original (coded in the video stream) height size\n\n\tlong\twidth, height;\n\tVideoOverlay->GetVideoSize( &width, &height );\n\n\treturn (tjs_int)height;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_VideoOverlay::ClearWndProcMessages()\n{\n\t// clear WndProc's message queue\n\tEventQueue.Clear(WM_GRAPHNOTIFY);\n\tEventQueue.Clear(WM_CALLBACKCMD);\n#if 0 // only valuable for DirectShow\n\tMSG msg;\n\twhile(PeekMessage(&msg, EventQueue.GetOwner(), WM_GRAPHNOTIFY, WM_GRAPHNOTIFY+2, PM_REMOVE))\n\t{\n\t\tif(VideoOverlay)\n\t\t{\n\t\t\tlong evcode;\n\t\t\tLONG_PTR p1, p2;\n\t\t\tbool got;\n\t\t\tVideoOverlay->GetEvent(&evcode, &p1, &p2, &got); // dummy call\n\t\t\tif( got )\n\t\t\t\tVideoOverlay->FreeEventParams( evcode, p1, p2 );\n\t\t}\n\t}\n#endif\n}\n\nbool tTJSNI_VideoOverlay::GetVideoSize(tjs_int &w, tjs_int &h) const  {\n\tif (VideoOverlay) {\n\t\tlong _w, _h;\n\t\tVideoOverlay->GetVideoSize(&_w, &_h);\n\t\tw = _w; h = _h;\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNC_VideoOverlay::CreateNativeInstance : returns proper instance object\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_VideoOverlay::CreateNativeInstance()\n{\n\treturn new tTJSNI_VideoOverlay();\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_VideoOverlay\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_VideoOverlay()\n{\n\treturn new tTJSNC_VideoOverlay();\n}\n//---------------------------------------------------------------------------\n\n"
  },
  {
    "path": "src/core/visual/win32/VideoOvlImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// Video Overlay support implementation\n//---------------------------------------------------------------------------\n#ifndef VideoOvlImplH\n#define VideoOvlImplH\n//---------------------------------------------------------------------------\n#include \"tjsNative.h\"\n#include \"WindowIntf.h\"\n\n#include \"VideoOvlIntf.h\"\n#include \"StorageIntf.h\"\n#include \"UtilStreams.h\"\n\n#include \"voMode.h\"\n\n#include \"NativeEventQueue.h\"\n//#include \"typedefine.h\"\n\n//---------------------------------------------------------------------------\n// tTJSNI_VideoOverlay : VideoOverlay Native Instance\n//---------------------------------------------------------------------------\nclass iTVPVideoOverlay;\nclass tTJSNI_VideoOverlay : public tTJSNI_BaseVideoOverlay\n{\n\ttypedef tTJSNI_BaseVideoOverlay inherited;\n\n\tiTVPVideoOverlay *VideoOverlay;\n\tiTVPVideoOverlay *CachedOverlay = nullptr;\n\ttTVPVideoOverlayMode CachedOverlayMode;\n\tttstr   CachedPlayingFile;\n\n\ttTVPRect Rect;\n\tbool Visible;\n\n//\tHWND OwnerWindow;\n\n\t// HWND UtilWindow; // window which receives messages from video overlay object\n\tNativeEventQueue<tTJSNI_VideoOverlay> EventQueue;\n\n\ttTVPLocalTempStorageHolder *LocalTempStorageHolder;\n\tclass tTJSNI_BaseLayer\t*Layer1;\n\tclass tTJSNI_BaseLayer\t*Layer2;\n\ttTVPVideoOverlayMode\tMode;\t//!< Mode̓IȕύX͏oȂBopenOɃZbgĂ\n\tbool\tLoop;\n\n\tclass tTVPBaseTexture\t*Bitmap[2];\t//!< Layer`pobt@pBitmap\n\tuint8_t\t\t\t*BmpBits[2];\n\n\tbool\tIsPrepare;\t\t\t//!< [hǂ\n\n\tint\t\tSegLoopStartFrame;\t//!< ZOg[vJnt[\n\tint\t\tSegLoopEndFrame;\t//!< ZOg[vIt[\n\n\t//! Cxgݒ肳ꂽA݃t[̕iłǂB\n\t//! Cxgݒ肳Ăt[OɌ݃t[ړÃtO͉B\n\tbool\tIsEventPast;\n\tint\t\tEventFrame;\t\t//!< Cxg𔭐t[\n\npublic:\n\ttTJSNI_VideoOverlay();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\n\npublic:\n\tvoid Open(const ttstr &name);\n\tvoid Close();\n\tvoid Shutdown();\n\tvoid Disconnect(); // tTJSNI_BaseVideoOverlay::Disconnect override\n\n\tvoid Play();\n\tvoid Stop();\n\tvoid Pause();\n\tvoid Rewind();\n\tvoid Prepare();\n\n\tvoid SetSegmentLoop( int comeFrame, int goFrame );\n\tvoid CancelSegmentLoop() { SegLoopStartFrame = -1; SegLoopEndFrame = -1; }\n\tvoid SetPeriodEvent( int eventFrame );\n\n\tvoid SetStopFrame( tjs_int f );\n\tvoid SetDefaultStopFrame();\n\ttjs_int GetStopFrame();\n\npublic:\n\tvoid SetRectangleToVideoOverlay();\n\n\tvoid SetPosition(tjs_int left, tjs_int top);\n\tvoid SetSize(tjs_int width, tjs_int height);\n\tvoid SetBounds(const tTVPRect & rect);\n\tvirtual const tTVPRect &GetBounds() const override { return Rect; }\n\n\tvoid SetLeft(tjs_int l);\n\ttjs_int GetLeft() const { return Rect.left; }\n\tvoid SetTop(tjs_int t);\n\ttjs_int GetTop() const { return Rect.top; }\n\tvoid SetWidth(tjs_int w);\n\ttjs_int GetWidth() const { return Rect.get_width(); }\n\tvoid SetHeight(tjs_int h);\n\ttjs_int GetHeight() const { return Rect.get_height(); }\n\n\tvoid SetVisible(bool b);\n\tbool GetVisible() const { return Visible; }\n\n\tvoid SetTimePosition( tjs_uint64 p );\n\ttjs_uint64 GetTimePosition();\n\n\tvoid SetFrame( tjs_int f );\n\ttjs_int GetFrame();\n\n\ttjs_real GetFPS();\n\ttjs_int GetNumberOfFrame();\n\ttjs_int64 GetTotalTime();\n\n\tvoid SetLoop( bool b );\n\tbool GetLoop() const { return Loop; }\n\n\tvoid SetLayer1( tTJSNI_BaseLayer *l );\n\ttTJSNI_BaseLayer *GetLayer1() { return Layer1; }\n\tvoid SetLayer2( tTJSNI_BaseLayer *l );\n\ttTJSNI_BaseLayer *GetLayer2() { return Layer2; }\n\n\tvoid SetMode( tTVPVideoOverlayMode m );\n\tvirtual tTVPVideoOverlayMode GetMode() const override { return Mode; }\n\n\ttjs_real GetPlayRate();\n\tvoid SetPlayRate(tjs_real r);\n\n\ttjs_int GetSegmentLoopStartFrame() { return SegLoopStartFrame; }\n\ttjs_int GetSegmentLoopEndFrame() { return SegLoopEndFrame; }\n\ttjs_int GetPeriodEventFrame() { return EventFrame; }\n\n\ttjs_int GetAudioBalance();\n\tvoid SetAudioBalance(tjs_int b);\n\ttjs_int GetAudioVolume();\n\tvoid SetAudioVolume(tjs_int v);\n\n\ttjs_uint GetNumberOfAudioStream();\n\tvoid SelectAudioStream(tjs_uint n);\n\ttjs_int GetEnabledAudioStream();\n\tvoid DisableAudioStream();\n\n\ttjs_uint GetNumberOfVideoStream();\n\tvoid SelectVideoStream(tjs_uint n);\n\ttjs_int GetEnabledVideoStream();\n\tvoid SetMixingLayer( tTJSNI_BaseLayer *l );\n\tvoid ResetMixingBitmap();\n\n\tvoid SetMixingMovieAlpha( tjs_real a );\n\ttjs_real GetMixingMovieAlpha();\n\tvoid SetMixingMovieBGColor( tjs_uint col );\n\ttjs_uint GetMixingMovieBGColor();\n\n\n\ttjs_real GetContrastRangeMin();\n\ttjs_real GetContrastRangeMax();\n\ttjs_real GetContrastDefaultValue();\n\ttjs_real GetContrastStepSize();\n\ttjs_real GetContrast();\n\tvoid SetContrast( tjs_real v );\n\n\ttjs_real GetBrightnessRangeMin();\n\ttjs_real GetBrightnessRangeMax();\n\ttjs_real GetBrightnessDefaultValue();\n\ttjs_real GetBrightnessStepSize();\n\ttjs_real GetBrightness();\n\tvoid SetBrightness( tjs_real v );\n\n\ttjs_real GetHueRangeMin();\n\ttjs_real GetHueRangeMax();\n\ttjs_real GetHueDefaultValue();\n\ttjs_real GetHueStepSize();\n\ttjs_real GetHue();\n\tvoid SetHue( tjs_real v );\n\n\ttjs_real GetSaturationRangeMin();\n\ttjs_real GetSaturationRangeMax();\n\ttjs_real GetSaturationDefaultValue();\n\ttjs_real GetSaturationStepSize();\n\ttjs_real GetSaturation();\n\tvoid SetSaturation( tjs_real v );\n\n\ttjs_int GetOriginalWidth();\n\ttjs_int GetOriginalHeight();\n\n\tbool GetVideoSize(tjs_int &w, tjs_int &h) const override;\n\n\tvoid ResetOverlayParams();\n\tvoid SetRectOffset(tjs_int ofsx, tjs_int ofsy);\n\tvoid DetachVideoOverlay();\n\n\tvoid PostEvent(const NativeEvent& ev) { EventQueue.PostEvent(ev); }\n\npublic:\n\tvoid WndProc( NativeEvent& ev );\n\t\t// UtilWindow's window procedure\n\tvoid ClearWndProcMessages(); // clear WndProc's message queue\n\n};\n//---------------------------------------------------------------------------\n\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/WindowImpl.cpp",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Window\" TJS Class implementation\n//---------------------------------------------------------------------------\n#include \"tjsCommHead.h\"\n\n//#define DIRECTDRAW_VERSION 0x0300\n//#include <ddraw.h>\n//#include <d3d9.h>\n\n#include <algorithm>\n#include \"MsgIntf.h\"\n#include \"WindowIntf.h\"\n#include \"LayerIntf.h\"\n//#include \"WindowFormUnit.h\"\n#include \"SysInitIntf.h\"\n#include \"tjsHashSearch.h\"\n#include \"StorageIntf.h\"\n#include \"VideoOvlIntf.h\"\n#include \"DebugIntf.h\"\n#include \"PluginImpl.h\"\n#include \"LayerManager.h\"\n#include \"EventImpl.h\"\n\n#include \"Application.h\"\n#include \"TVPScreen.h\"\n#include \"tjsDictionary.h\"\n//#include \"VSyncTimingThread.h\"\n//#include \"MouseCursor.h\"\n\niWindowLayer *TVPCreateAndAddWindow(tTJSNI_Window *w);\n#define MK_SHIFT 4\n#define MK_CONTROL 8\n#define MK_ALT (0x20)\ntjs_uint32 TVP_TShiftState_To_uint32(tjs_uint32 state) {\n\ttjs_uint32 result = 0;\n\tif (state & MK_SHIFT) {\n\t\tresult |= ssShift;\n\t}\n\tif (state & MK_CONTROL) {\n\t\tresult |= ssCtrl;\n\t}\n\tif (state & MK_ALT) {\n\t\tresult |= ssAlt;\n\t}\n\treturn result;\n}\ntjs_uint32 TVP_TShiftState_From_uint32(tjs_uint32 state){\n\ttjs_uint32 result = 0;\n\tif (state & ssShift) {\n\t\tresult |= MK_SHIFT;\n\t}\n\tif (state & ssCtrl) {\n\t\tresult |= MK_CONTROL;\n\t}\n\tif (state & ssAlt) {\n\t\tresult |= MK_ALT;\n\t}\n\treturn result;\n}\n\n//---------------------------------------------------------------------------\n// Mouse Cursor management\n//---------------------------------------------------------------------------\nstatic tTJSHashTable<ttstr, tjs_int> TVPCursorTable;\ntjs_int TVPGetCursor(const ttstr & name)\n{\n\t// get placed path\n\tttstr place(TVPSearchPlacedPath(name));\n\n\t// search in cache\n\ttjs_int * in_hash = TVPCursorTable.Find(place);\n\tif(in_hash) return *in_hash;\n#if 0\n\t// not found\n\ttTVPLocalTempStorageHolder file(place);\n\n\tHCURSOR handle = ::LoadCursorFromFile(file.GetLocalName().c_str());\n\n\tif(!handle) TVPThrowExceptionMessage(TVPCannotLoadCursor, place);\n\n\tint id = MouseCursor::AddCursor( handle );\n\n\tTVPCursorTable.Add(place, id);\n\n\treturn id;\n#endif\n\treturn 0;\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n#if 0\n//---------------------------------------------------------------------------\n// Direct3D/Full Screen and priamary surface management\n//---------------------------------------------------------------------------\n\n//! @brief\t\tDisplay resolution mode for full screen\nenum tTVPFullScreenResolutionMode\n{\n\tfsrAuto, //!< auto negotiation\n\tfsrProportional, //!< let screen resolution fitting neaest to the preferred resolution,\n\t\t\t\t\t\t\t\t//!< preserving the original aspect ratio\n\tfsrNearest, //!< let screen resolution fitting neaest to the preferred resolution.\n\t\t\t\t//!< There is no guarantee that the aspect ratio is preserved\n\tfsrNoChange,//!< no change resolution\n\tfsrExpandWindow\t//!< expand window\n};\nstatic IDirect3D9 *TVPDirect3D=NULL;\n\nstatic IDirect3D9* (WINAPI * TVPDirect3DCreate)( UINT SDKVersion ) = NULL;\n\nstatic HMODULE TVPDirect3DDLLHandle=NULL;\nstatic bool TVPUseChangeDisplaySettings = false;\nstatic tTVPScreenMode TVPDefaultScreenMode;\n\nstatic bool TVPInFullScreen = false;\nstatic HWND TVPFullScreenWindow = NULL;\ntTVPScreenModeCandidate TVPFullScreenMode;\n\nstatic tjs_int TVPPreferredFullScreenBPP = 0;\nstatic tTVPFullScreenResolutionMode TVPPreferredFullScreenResolutionMode = fsrNoChange;\nenum tTVPFullScreenUsingEngineZoomMode\n{\n\tfszmNone, //!< no zoom by the engine\n\tfszmInner, //!< inner fit on the monitor (uncovered areas may be filled with black)\n\tfszmOuter //!< outer fit on the monitor (primary layer may jut out of the monitor)\n};\nstatic tTVPFullScreenUsingEngineZoomMode TVPPreferredFullScreenUsingEngineZoomMode = fszmInner;\n\n\n//---------------------------------------------------------------------------\n// Color Format Detection\n//---------------------------------------------------------------------------\ntjs_int TVPDisplayColorFormat = 0;\nstatic tjs_int TVPGetDisplayColorFormat()\n{\n\t// detect current 16bpp display color format\n\t// return value:\n\t// 555 : 16bit 555 mode\n\t// 565 : 16bit 565 mode\n\t// 0   : other modes\n\n\tif( TVPDirect3D ) {\n\t\t// ܂ Direct3D p 16bit color format 擾݂\n\t\tD3DDISPLAYMODE mode = {0};\n\t\tif( SUCCEEDED( TVPDirect3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &mode ) ) ) {\n\t\t\tif( mode.Format == D3DFMT_R5G6B5 ) {\n\t\t\t\tTVPDisplayColorFormat = 565;\n\t\t\t\treturn 565;\n\t\t\t} else if( mode.Format == D3DFMT_X1R5G5B5 ) {\n\t\t\t\tTVPDisplayColorFormat = 555;\n\t\t\t\treturn 555;\n\t\t\t} else {\n\t\t\t\tTVPDisplayColorFormat = 0;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\t// create temporary bitmap and device contexts\n\tHDC desktopdc = ::GetDC(0);\n\tHDC bitmapdc = ::CreateCompatibleDC(desktopdc);\n\tHBITMAP bmp = ::CreateCompatibleBitmap(desktopdc, 1, 1);\n\tHBITMAP oldbmp = ::SelectObject(bitmapdc, bmp);\n\n\tint count;\n\tint r, g, b;\n\tCOLORREF lastcolor;\n\n\t// red\n\tcount = 0;\n\tlastcolor = 0xffffff;\n\tfor(int i = 0; i < 256; i++)\n\t{\n\t\t::SetPixel(bitmapdc, 0, 0, RGB(i, 0, 0));\n\t\tCOLORREF rgb = ::GetPixel(bitmapdc, 0, 0);\n\t\tif(rgb != lastcolor) count ++;\n\t\tlastcolor = rgb;\n\t}\n\tr = count;\n\n\t// green\n\tcount = 0;\n\tlastcolor = 0xffffff;\n\tfor(int i = 0; i < 256; i++)\n\t{\n\t\t::SetPixel(bitmapdc, 0, 0, RGB(0, i, 0));\n\t\tCOLORREF rgb = ::GetPixel(bitmapdc, 0, 0);\n\t\tif(rgb != lastcolor) count ++;\n\t\tlastcolor = rgb;\n\t}\n\tg = count;\n\n\t// blue\n\tcount = 0;\n\tlastcolor = 0xffffff;\n\tfor(int i = 0; i < 256; i++)\n\t{\n\t\t::SetPixel(bitmapdc, 0, 0, RGB(0, 0, i));\n\t\tCOLORREF rgb = ::GetPixel(bitmapdc, 0, 0);\n\t\tif(rgb != lastcolor) count ++;\n\t\tlastcolor = rgb;\n\t}\n\tb = count;\n\n\t// free bitmap and device contexts\n\t::SelectObject(bitmapdc, oldbmp);\n\t::DeleteObject(bmp);\n\t::DeleteDC(bitmapdc);\n\t::ReleaseDC(0, desktopdc);\n\n\t// determine type\n\tif(r == 32 && g == 64 && b == 32)\n\t{\n\t\tTVPDisplayColorFormat = 565;\n\t\treturn 565;\n\t}\n\telse if(r == 32 && g == 32 && b == 32)\n\t{\n\t\tTVPDisplayColorFormat = 555;\n\t\treturn 555;\n\t}\n\telse\n\t{\n\t\tTVPDisplayColorFormat = 0;\n\t\treturn 0;\n\t}\n}\n//---------------------------------------------------------------------------\nstatic void TVPInitFullScreenOptions()\n{\n\ttTJSVariant val;\n\n\tif(TVPGetCommandLine(TJS_W(\"-fsbpp\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"16\"))\n\t\t\tTVPPreferredFullScreenBPP = 16;\n\t\telse if(str == TJS_W(\"24\"))\n\t\t\tTVPPreferredFullScreenBPP = 24;\n\t\telse if(str == TJS_W(\"32\"))\n\t\t\tTVPPreferredFullScreenBPP = 32;\n\t\telse\n\t\t\tTVPPreferredFullScreenBPP = 0; // means nochange\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-fsres\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"auto\"))\n\t\t\tTVPPreferredFullScreenResolutionMode = fsrAuto;\n\t\telse if(str == TJS_W(\"prop\") || str == TJS_W(\"proportional\"))\n\t\t\tTVPPreferredFullScreenResolutionMode = fsrProportional;\n\t\telse if(str == TJS_W(\"nearest\"))\n\t\t\tTVPPreferredFullScreenResolutionMode = fsrNearest;\n\t\telse if(str == TJS_W(\"nochange\"))\n\t\t\tTVPPreferredFullScreenResolutionMode = fsrNoChange;\n\t\telse if(str == TJS_W(\"expandwindow\"))\n\t\t\tTVPPreferredFullScreenResolutionMode = fsrExpandWindow;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-fszoom\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"yes\") || str == TJS_W(\"inner\"))\n\t\t\tTVPPreferredFullScreenUsingEngineZoomMode = fszmInner;\n\t\tif(str == TJS_W(\"outer\"))\n\t\t\tTVPPreferredFullScreenUsingEngineZoomMode = fszmOuter;\n\t\telse if(str == TJS_W(\"no\"))\n\t\t\tTVPPreferredFullScreenUsingEngineZoomMode = fszmNone;\n\t}\n\n\tif(TVPGetCommandLine(TJS_W(\"-fsmethod\"), &val) )\n\t{\n\t\tttstr str(val);\n\t\tif(str == TJS_W(\"cds\"))\n\t\t\tTVPUseChangeDisplaySettings = true;\n\t\telse\n\t\t\tTVPUseChangeDisplaySettings = false;\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TVPDumpDirect3DDriverInformation()\n{\n\tif(TVPDirect3D)\n\t{\n\t\tIDirect3D9 *d3d9 = TVPDirect3D;\n\t\tstatic bool dumped = false;\n\t\tif(dumped) return;\n\t\tdumped = true;\n\n\t\tTVPAddImportantLog( (const tjs_char*)TVPInfoFoundDirect3DInterface );\n\n\t\ttry\n\t\t{\n\t\t\t// dump direct3d information\n\t\t\tUINT numofadapter = d3d9->GetAdapterCount();\n\t\t\tttstr infostart(TJS_W(\"(info)  \"));\n\t\t\tttstr log;\n\t\t\tlog = infostart + TJS_W(\"Found \") + ttstr((tjs_int)numofadapter) + TJS_W(\" Devices.\");\n\t\t\tTVPAddImportantLog(log);\n\n\t\t\tfor( UINT adapter = 0; adapter < numofadapter; adapter++ )\n\t\t\t{\n\t\t\t\tlog = infostart + TJS_W(\"Device Number : \") + ttstr((tjs_int)adapter);\n\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\tD3DADAPTER_IDENTIFIER9 D3DID = {0};\n\t\t\t\tif(SUCCEEDED(d3d9->GetAdapterIdentifier( adapter, 0, &D3DID)))\n\t\t\t\t{\n\t\t\t\t\t// driver string\n\t\t\t\t\tlog = infostart + ttstr(D3DID.Description) + TJS_W(\" [\") + ttstr(D3DID.Driver) + TJS_W(\"]\");\n\t\t\t\t\tTVPAddImportantLog(log);\n\t\t\t\t\tlog = infostart + TJS_W(\" [\") + ttstr(D3DID.DeviceName) + TJS_W(\"]\");\n\t\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\t\t// driver version(reported)\n\t\t\t\t\tlog = infostart + TJS_W(\"Driver version (reported) : \");\n\t\t\t\t\twchar_t tmp[256];\n\t\t\t\t\tTJS_snprintf( tmp, 256, L\"%d.%02d.%02d.%04d \",\n\t\t\t\t\t\t\t  HIWORD( D3DID.DriverVersion.HighPart ),\n\t\t\t\t\t\t\t  LOWORD( D3DID.DriverVersion.HighPart ),\n\t\t\t\t\t\t\t  HIWORD( D3DID.DriverVersion.LowPart  ),\n\t\t\t\t\t\t\t  LOWORD( D3DID.DriverVersion.LowPart  ) );\n\t\t\t\t\tlog += tmp;\n\t\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\t\t// driver version(actual)\n\t\t\t\t\tstd::wstring driverName = ttstr(D3DID.Driver).AsStdString();\n\t\t\t\t\twchar_t driverpath[1024];\n\t\t\t\t\twchar_t *driverpath_filename = NULL;\n\t\t\t\t\tbool success = 0!=SearchPath(NULL, driverName.c_str(), NULL, 1023, driverpath, &driverpath_filename);\n\n\t\t\t\t\tif(!success)\n\t\t\t\t\t{\n\t\t\t\t\t\twchar_t syspath[1024];\n\t\t\t\t\t\tGetSystemDirectory(syspath, 1023);\n\t\t\t\t\t\tTJS_strcat(syspath, L\"\\\\drivers\"); // SystemDir\\drivers\n\t\t\t\t\t\tsuccess = 0!=SearchPath(syspath, driverName.c_str(), NULL, 1023, driverpath, &driverpath_filename);\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!success)\n\t\t\t\t\t{\n\t\t\t\t\t\twchar_t syspath[1024];\n\t\t\t\t\t\tGetWindowsDirectory(syspath, 1023);\n\t\t\t\t\t\tTJS_strcat(syspath, L\"\\\\system32\"); // WinDir\\system32\n\t\t\t\t\t\tsuccess = 0!=SearchPath(syspath, driverName.c_str(), NULL, 1023, driverpath, &driverpath_filename);\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!success)\n\t\t\t\t\t{\n\t\t\t\t\t\twchar_t syspath[1024];\n\t\t\t\t\t\tGetWindowsDirectory(syspath, 1023);\n\t\t\t\t\t\tTJS_strcat(syspath, L\"\\\\system32\\\\drivers\"); // WinDir\\system32\\drivers\n\t\t\t\t\t\tsuccess = 0!=SearchPath(syspath, driverName.c_str(), NULL, 1023, driverpath, &driverpath_filename);\n\t\t\t\t\t}\n\n\t\t\t\t\tif(success)\n\t\t\t\t\t{\n\t\t\t\t\t\tlog = infostart + TJS_W(\"Driver version (\") + ttstr(driverpath) + TJS_W(\") : \");\n\t\t\t\t\t\ttjs_int major, minor, release, build;\n\t\t\t\t\t\tif(TVPGetFileVersionOf(driverpath, major, minor, release, build))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTJS_snprintf(tmp, 256, L\"%d.%d.%d.%d\", (int)major, (int)minor, (int)release, (int)build);\n\t\t\t\t\t\t\tlog += tmp;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlog += TJS_W(\"unknown\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tlog = infostart + TJS_W(\"Driver \") + ttstr(D3DID.Driver) +\n\t\t\t\t\t\t\tTJS_W(\" is not found in search path.\");\n\t\t\t\t\t}\n\t\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\t\t// device id\n\t\t\t\t\tTJS_snprintf(tmp, 256, L\"VendorId:%08X  DeviceId:%08X  SubSysId:%08X  Revision:%08X\",\n\t\t\t\t\t\tD3DID.VendorId, D3DID.DeviceId, D3DID.SubSysId, D3DID.Revision);\n\t\t\t\t\tlog = infostart + TJS_W(\"Device ids : \") + tmp;\n\t\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\t\t// Device GUID\n\t\t\t\t\tGUID *pguid = &D3DID.DeviceIdentifier;\n\t\t\t\t\tTJS_snprintf( tmp, 256, L\"%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\",\n\t\t\t\t\t\t\t  pguid->Data1,\n\t\t\t\t\t\t\t  pguid->Data2,\n\t\t\t\t\t\t\t  pguid->Data3,\n\t\t\t\t\t\t\t  pguid->Data4[0], pguid->Data4[1], pguid->Data4[2], pguid->Data4[3],\n\t\t\t\t\t\t\t  pguid->Data4[4], pguid->Data4[5], pguid->Data4[6], pguid->Data4[7] );\n\t\t\t\t\tlog = infostart + TJS_W(\"Unique driver/device id : \") + tmp;\n\t\t\t\t\tTVPAddImportantLog(log);\n\n\t\t\t\t\t// WHQL level\n\t\t\t\t\tTJS_snprintf(tmp, 256, L\"%08x\", D3DID.WHQLLevel);\n\t\t\t\t\tlog = infostart + TJS_W(\"WHQL level : \")  + tmp;\n\t\t\t\t\tTVPAddImportantLog(log);\n\t\t\t\t} else {\n\t\t\t\t\tTVPAddImportantLog( (const tjs_char*)TVPInfoFaild );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t}\n\t}\n\n}\n//---------------------------------------------------------------------------\nstatic void TVPUnloadDirect3D();\nstatic void TVPInitDirect3D()\n{\n\tif(!TVPDirect3DDLLHandle)\n\t{\n\t\t// load d3d9.dll\n\t\tTVPAddLog( (const tjs_char*)TVPInfoDirect3D );\n\t\tTVPDirect3DDLLHandle = ::LoadLibrary( L\"d3d9.dll\" );\n\t\tif(!TVPDirect3DDLLHandle)\n\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirect3D, (const tjs_char*)TVPCannotLoadD3DDLL );\n\t}\n\n\tif(!TVPDirect3D)\n\t{\n\t\ttry\n\t\t{\n\t\t\t// get Direct3DCreaet function\n\t\t\tTVPDirect3DCreate = (IDirect3D9*(WINAPI * )(UINT))GetProcAddress(TVPDirect3DDLLHandle, \"Direct3DCreate9\");\n\t\t\tif(!TVPDirect3DCreate)\n\t\t\t\tTVPThrowExceptionMessage(TVPCannotInitDirect3D, (const tjs_char*)TVPNotFoundDirect3DCreate );\n\n\t\t\tTVPDirect3D = TVPDirect3DCreate( D3D_SDK_VERSION );\n\t\t\tif( NULL == TVPDirect3D )\n\t\t\t\tTVPThrowExceptionMessage( TVPFaildToCreateDirect3D );\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPUnloadDirect3D();\n\t\t\tthrow;\n\t\t}\n\t}\n\n\tTVPGetDisplayColorFormat();\n}\n//---------------------------------------------------------------------------\nstatic void TVPUninitDirect3D()\n{\n\t// release Direct3D object ( DLL will not be released )\n}\n//---------------------------------------------------------------------------\nstatic void TVPUnloadDirect3D()\n{\n\t// release Direct3D object and /*release it's DLL */\n\tTVPUninitDirect3D();\n\tif(TVPDirect3D) TVPDirect3D->Release(), TVPDirect3D = NULL;\n\n\tTVPGetDisplayColorFormat();\n}\n//---------------------------------------------------------------------------\nvoid TVPEnsureDirect3DObject()\n{\n\ttry\n\t{\n\t\tTVPInitDirect3D();\n\t}\n\tcatch(...)\n\t{\n\t}\n}\n//---------------------------------------------------------------------------\nIDirect3D9 * TVPGetDirect3DObjectNoAddRef()\n{\n\t// retrieves IDirect3D9 interface\n\treturn TVPDirect3D;\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nstatic tTVPAtExit\n\tTVPUnloadDirect3DAtExit(TVP_ATEXIT_PRI_RELEASE, TVPUnloadDirect3D);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n//! @brief\t\tGet tTVPFullScreenResolutionMode enumeration string\nstatic ttstr TVPGetGetFullScreenResolutionModeString(tTVPFullScreenResolutionMode mode)\n{\n\tswitch(mode)\n\t{\n\tcase fsrAuto:\t\t\t\treturn TJS_W(\"fsrAuto\");\n\tcase fsrProportional:\t\treturn TJS_W(\"fsrProportional\");\n\tcase fsrNearest:\t\t\treturn TJS_W(\"fsrNearest\");\n\tcase fsrNoChange:\t\t\treturn TJS_W(\"fsrNoChange\");\n\tcase fsrExpandWindow:\t\treturn TJS_W(\"fsrExpandWindow\");\n\t}\n\treturn ttstr();\n}\n//---------------------------------------------------------------------------\n//! @brief\tdo reduction for numer over denom\nstatic void TVPDoReductionNumerAndDenom(tjs_int &n, tjs_int &d)\n{\n\ttjs_int a = n;\n\ttjs_int b = d;\n\twhile(b)\n\t{\n\t\ttjs_int t = b;\n\t\tb = a % b;\n\t\ta = t;\n\t}\n\tn = n / a;\n\td = d / a;\n}\n//---------------------------------------------------------------------------\nstatic void TVPGetOriginalScreenMetrics()\n{\n\t// retrieve original (un-fullscreened) information\n\tTVPDefaultScreenMode.Width = tTVPScreen::GetWidth();\n\tTVPDefaultScreenMode.Height = tTVPScreen::GetHeight();\n\tHDC dc = GetDC(0);\n\tTVPDefaultScreenMode.BitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);\n\tReleaseDC(0, dc);\n}\n//---------------------------------------------------------------------------\n//! @brief\tenumerate all display modes\nvoid TVPEnumerateAllDisplayModes(std::vector<tTVPScreenMode> & modes)\n{\n\tmodes.clear();\n\n\tif(!TVPUseChangeDisplaySettings)\n\t{\n\t\t// if DisplaySettings APIs is not preferred\n\t\t// use Direct3D\n\t\tTVPEnsureDirect3DObject();\n\t\tIDirect3D9* d3d = TVPGetDirect3DObjectNoAddRef();\n\t\tif(d3d)\n\t\t{\n\t\t\tstatic const D3DFORMAT PixelFormatTypes[] = {\n\t\t\t\t//D3DFMT_A1R5G5B5, // not support display\n\t\t\t\t//D3DFMT_A2R10G10B10, // not support display\n\t\t\t\t//D3DFMT_A8R8G8B8, // not support display\n\t\t\t\tD3DFMT_R5G6B5,\n\t\t\t\t// D3DFMT_X1R5G5B5, // IDirect3D9::EnumAdapterModes ł D3DFMT_R5G6B5 ƓƏ\n\t\t\t\tD3DFMT_X8R8G8B8\n\t\t\t};\n\t\t\tstatic const int NumOfFormat = sizeof(PixelFormatTypes) / sizeof(PixelFormatTypes[0]);\n\t\t\tfor( int f = 0; f < NumOfFormat; f++ )\n\t\t\t{\n\t\t\t\tD3DFORMAT format = PixelFormatTypes[f];\n\t\t\t\tUINT count = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT,format);\n\t\t\t\tfor( UINT a = 0; a < count; a++ )\n\t\t\t\t{\n\t\t\t\t\tD3DDISPLAYMODE mode;\n\t\t\t\t\tHRESULT hr = d3d->EnumAdapterModes( D3DADAPTER_DEFAULT, format, a, &mode );\n\t\t\t\t\tif( SUCCEEDED( hr ) )\n\t\t\t\t\t{\n\t\t\t\t\t\ttTVPScreenMode sm;\n\t\t\t\t\t\tsm.Width =  mode.Width;\n\t\t\t\t\t\tsm.Height = mode.Height;\n\t\t\t\t\t\t// modes.Refreshrate\n\t\t\t\t\t\tif( mode.Format == D3DFMT_R5G6B5 || mode.Format == D3DFMT_X1R5G5B5 ) {\n\t\t\t\t\t\t\tsm.BitsPerPixel = 16;\n\t\t\t\t\t\t\tmodes.push_back(sm);\n\t\t\t\t\t\t} else if( mode.Format == D3DFMT_X8R8G8B8 ) {\n\t\t\t\t\t\t\tsm.BitsPerPixel = 32;\n\t\t\t\t\t\t\tmodes.push_back(sm);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// unknown ł͖\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif(modes.size() == 0)\n\t{\n\t\t// try another API to retrieve screen sizes\n\t\tTVPUseChangeDisplaySettings = true;\n\n\t\t// attempt to use EnumDisplaySettings\n\t\tDWORD num = 0;\n\t\tdo\n\t\t{\n\t\t\tDEVMODE dm;\n\t\t\tZeroMemory(&dm, sizeof(DEVMODE));\n\t\t\tdm.dmSize = sizeof(DEVMODE);\n\t\t\tdm.dmDriverExtra = 0;\n\t\t\tif(::EnumDisplaySettings(NULL, num, reinterpret_cast<DEVMODE*>(&dm)) == 0) break;\n\t\t\ttTVPScreenMode mode;\n\t\t\tmode.Width  = dm.dmPelsWidth;\n\t\t\tmode.Height = dm.dmPelsHeight;\n\t\t\tmode.BitsPerPixel = dm.dmBitsPerPel;\n\t\t\tmodes.push_back(mode);\n\t\t\tnum ++;\n\t\t} while(true);\n\t}\n\n\tTVPAddLog( TVPFormatMessage(TVPInfoEnvironmentUsing,\n\t\t(TVPUseChangeDisplaySettings?TJS_W(\"ChangeDisplaySettings API\"):TJS_W(\"Direct3D\"))) );\n}\n//---------------------------------------------------------------------------\n//! @brief\t\tmake full screen mode candidates\n//! @note\t\tAlways call this function *before* entering full screen mode\nstatic void TVPMakeFullScreenModeCandidates(\n\tconst tTVPScreenMode & preferred,\n\ttTVPFullScreenResolutionMode mode,\n\ttTVPFullScreenUsingEngineZoomMode zoom_mode,\n\tstd::vector<tTVPScreenModeCandidate> & candidates)\n{\n\t// adjust give parameter\n\tif(mode == fsrAuto && zoom_mode == fszmNone) zoom_mode = fszmInner;\n\t\t// fszmInner is ignored (as always be fszmInner) if mode == fsrAuto && zoom_mode == fszmNone\n\n\t// print debug information\n\tTVPAddLog((const tjs_char*)TVPInfoSearchBestFullscreenResolution);\n\tTVPAddLog(TVPFormatMessage(TVPInfoConditionPreferredScreenMode, preferred.Dump()));\n\tTVPAddLog(TVPFormatMessage(TVPInfoConditionMode, TVPGetGetFullScreenResolutionModeString(mode)));\n\tTVPAddLog(TVPFormatMessage(TVPInfoConditionZoomMode, ttstr(\n\t\tzoom_mode == fszmInner ? TJS_W(\"inner\") :\n\t\tzoom_mode == fszmOuter ? TJS_W(\"outer\") :\n\t\t\tTJS_W(\"none\"))));\n\n\t// get original screen metrics\n\tTVPGetOriginalScreenMetrics();\n\n\t// decide preferred bpp\n\ttjs_int preferred_bpp = preferred.BitsPerPixel == 0 ?\n\t\t\tTVPDefaultScreenMode.BitsPerPixel : preferred.BitsPerPixel;\n\n\t// get original screen aspect ratio\n\ttjs_int screen_aspect_numer = TVPDefaultScreenMode.Width;\n\ttjs_int screen_aspect_denom = TVPDefaultScreenMode.Height;\n\tTVPDoReductionNumerAndDenom(screen_aspect_numer, screen_aspect_denom); // do reduction\n\tTVPAddLog(TVPFormatMessage(TVPInfoEnvironmentDefaultScreenMode, TVPDefaultScreenMode.Dump()));\n\tTVPAddLog(TVPFormatMessage(TVPInfoEnvironmentDefaultScreenAspectRatio,\n\t\tttstr(screen_aspect_numer),ttstr(screen_aspect_denom)) );\n\n\t// clear destination array\n\tcandidates.clear();\n\n\t// enumerate all display modes\n\tstd::vector<tTVPScreenMode> modes;\n\tTVPEnumerateAllDisplayModes(modes);\n\tstd::sort(modes.begin(), modes.end()); // sort by area, and bpp\n\t{\t// d鍀ڂ폜(tbV[gŏd\\)\n\t\tstd::vector<tTVPScreenMode>::iterator new_end = std::unique(modes.begin(),modes.end());\n\t\tmodes.erase(new_end, modes.end());\n\t}\n\n\t{\n\t\ttjs_int last_width = -1, last_height = -1;\n\t\tttstr last_line;\n\t\tTVPAddLog( (const tjs_char*)TVPInfoEnvironmentAvailableDisplayModes );\n\t\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin(); i != modes.end(); i++)\n\t\t{\n\t\t\tif(last_width != i->Width || last_height != i->Height)\n\t\t\t{\n\t\t\t\tif(!last_line.IsEmpty()) TVPAddLog(last_line);\n\t\t\t\ttjs_int w = i->Width, h = i->Height;\n\t\t\t\tTVPDoReductionNumerAndDenom(w, h);\n\t\t\t\tlast_line = TJS_W(\"(info)  \") + i->DumpHeightAndWidth() +\n\t\t\t\t\tTJS_W(\", AspectRatio=\") + ttstr(w) + TJS_W(\":\") + ttstr(h) +\n\t\t\t\t\tTJS_W(\", BitsPerPixel=\") + ttstr(i->BitsPerPixel);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlast_line += TJS_W(\"/\") + ttstr(i->BitsPerPixel);\n\t\t\t}\n\t\t\tlast_width = i->Width; last_height = i->Height;\n\t\t}\n\t\tif(!last_line.IsEmpty()) TVPAddLog(last_line);\n\t}\n\n\tif(mode != fsrNoChange && mode != fsrExpandWindow )\n\t{\n\n\t\tif(mode != fsrNearest)\n\t\t{\n\t\t\t// for fstAuto and fsrProportional, we need to see screen aspect ratio\n\n\t\t\t// reject screen mode which does not match the original screen aspect ratio\n\t\t\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\t\t\ti != modes.end(); /**/)\n\t\t\t{\n\t\t\t\ttjs_int aspect_numer = i->Width;\n\t\t\t\ttjs_int aspect_denom = i->Height;\n\t\t\t\tTVPDoReductionNumerAndDenom(aspect_numer, aspect_denom);\n\t\t\t\tif(aspect_numer != screen_aspect_numer || aspect_denom != screen_aspect_denom)\n\t\t\t\t\ti = modes.erase(i);\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tif(zoom_mode == fszmNone)\n\t\t{\n\t\t\t// we cannot use resolution less than preferred resotution when\n\t\t\t// we do not use zooming, so reject them.\n\t\t\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\t\t\ti != modes.end(); /**/)\n\t\t\t{\n\t\t\t\tif(i->Width < preferred.Width || i->Height < preferred.Height)\n\t\t\t\t\ti = modes.erase(i);\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// reject resolutions other than the original size\n\t\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\t\ti != modes.end(); /**/)\n\t\t{\n\t\t\tif(\ti->Width  != TVPDefaultScreenMode.Width ||\n\t\t\t\ti->Height != TVPDefaultScreenMode.Height)\n\t\t\t\ti = modes.erase(i);\n\t\t\telse\n\t\t\t\ti++;\n\t\t}\n\t}\n\n\t// reject resolutions larger than the default screen mode\n\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\ti != modes.end(); /**/)\n\t{\n\t\tif(i->Width > TVPDefaultScreenMode.Width || i->Height > TVPDefaultScreenMode.Height)\n\t\t\ti = modes.erase(i);\n\t\telse\n\t\t\ti++;\n\t}\n\n\t// reject resolutions less than 16\n\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\ti != modes.end(); /**/)\n\t{\n\t\tif(i->BitsPerPixel < 16)\n\t\t\ti = modes.erase(i);\n\t\telse\n\t\t\ti++;\n\t}\n\n\t// check there is at least one candidate mode\n\tif(modes.size() == 0)\n\t{\n\t\t// panic! no candidates\n\t\t// this could be if the driver does not provide the screen\n\t\t// mode which is the same size as the default screen...\n\t\t// push the default screen mode\n\t\tTVPAddImportantLog( (const tjs_char*)TVPInfoNotFoundScreenModeFromDriver );\n\t\ttTVPScreenMode mode;\n\t\tmode.Width  = TVPDefaultScreenMode.Width;\n\t\tmode.Height = TVPDefaultScreenMode.Height;\n\t\tmode.BitsPerPixel = TVPDefaultScreenMode.BitsPerPixel;\n\t\tmodes.push_back(mode);\n\t}\n\n\t// copy modes to candidation, with making zoom ratio and resolution rank\n\tfor(std::vector<tTVPScreenMode>::iterator i = modes.begin();\n\t\ti != modes.end(); i++)\n\t{\n\t\ttTVPScreenModeCandidate candidate;\n\t\tcandidate.Width = i->Width;\n\t\tcandidate.Height = i->Height;\n\t\tcandidate.BitsPerPixel = i->BitsPerPixel;\n\t\tif(zoom_mode != fszmNone)\n\t\t{\n\t\t\tdouble width_r  = (double)candidate.Width /  (double)preferred.Width;\n\t\t\tdouble height_r = (double)candidate.Height / (double)preferred.Height;\n\n\t\t\t// select width or height, to fit to target screen from preferred size\n\t\t\tif(zoom_mode == fszmInner ? (width_r < height_r) : (width_r > height_r))\n\t\t\t{\n\t\t\t\tcandidate.ZoomNumer = candidate.Width;\n\t\t\t\tcandidate.ZoomDenom = preferred.Width;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcandidate.ZoomNumer = candidate.Height;\n\t\t\t\tcandidate.ZoomDenom = preferred.Height;\n\t\t\t}\n\n\t\t\t// if the zooming range is between 1.00 and 1.034 we treat this as 1.00\n\t\t\tdouble zoom_r = (double)candidate.ZoomNumer / (double)candidate.ZoomDenom;\n\t\t\tif(zoom_r > 1.000 && zoom_r < 1.034)\n\t\t\t\tcandidate.ZoomDenom = candidate.ZoomNumer = 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// zooming disabled\n\t\t\tcandidate.ZoomDenom = candidate.ZoomNumer = 1;\n\t\t}\n\t\tTVPDoReductionNumerAndDenom(candidate.ZoomNumer, candidate.ZoomDenom);\n\n\t\t// make rank on each candidate\n\n\t\t// BPP\n\t\t// take absolute difference of preferred and candidate.\n\t\t// lesser bpp has less priority, so add 1000 to lesser bpp.\n\t\tcandidate.RankBPP = std::abs(preferred_bpp - candidate.BitsPerPixel);\n\t\tif(candidate.BitsPerPixel < preferred_bpp) candidate.RankBPP += 1000;\n\n\t\t// Zoom-in\n\t\t// we usually use zoom-in, zooming out (this situation will occur if\n\t\t// the screen resolution is lesser than expected) has lesser priority.\n\t\tif(candidate.ZoomNumer < candidate.ZoomDenom)\n\t\t\tcandidate.RankZoomIn = 1;\n\t\telse\n\t\t\tcandidate.RankZoomIn = 0;\n\n\t\t// Zoom-Beauty\n\t\tif(mode == fsrAuto)\n\t\t{\n\t\t\t// 0: no zooming is the best.\n\t\t\t// 1: zooming using monitor's function is fastest and most preferable.\n\t\t\t// 2: zooming using kirikiri's zooming functions is somewhat slower but not so bad.\n\t\t\t// 3: zooming using monitor's function and kirikiri's function tends to be dirty\n\t\t\t//   because the zooming is applied twice. this is not preferable.\n\t\t\ttjs_int zoom_rank = 0;\n\t\t\tif(candidate.Width != TVPDefaultScreenMode.Width ||\n\t\t\t\tcandidate.Height != TVPDefaultScreenMode.Height)\n\t\t\t\tzoom_rank += 1; // zoom by monitor\n\n\t\t\tif(candidate.ZoomNumer != 1 || candidate.ZoomDenom != 1)\n\t\t\t\tzoom_rank += 2; // zoom by the engine\n\n\t\t\tcandidate.RankZoomBeauty = zoom_rank;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Zoom-Beauty is not considered\n\t\t\tcandidate.RankZoomBeauty = 0;\n\t\t}\n\n\t\t// Size\n\t\t// size rank is a absolute difference between area size of candidate and preferred.\n\t\tcandidate.RankSize = std::abs(\n\t\t\tcandidate.Width * candidate.Height - preferred.Width * preferred.Height);\n\n\t\t// push candidate into candidates array\n\t\tcandidates.push_back(candidate);\n\t}\n\n\t// sort candidate by its rank\n\tstd::sort(candidates.begin(), candidates.end());\n\n\t// dump all candidates to log\n\tTVPAddLog( (const tjs_char*)TVPInfoResultCandidates );\n\tfor(std::vector<tTVPScreenModeCandidate>::iterator i = candidates.begin();\n\t\ti != candidates.end(); i++)\n\t{\n\t\tTVPAddLog(TJS_W(\"(info)  \") + i->Dump());\n\t}\n}\n//---------------------------------------------------------------------------\n#if 0\ntjs_uint TVPGetMonitorNumber( HWND window )\n{\n\tif( TVPDirect3D == NULL ) return D3DADAPTER_DEFAULT;\n\tHMONITOR windowMonitor = ::MonitorFromWindow( window, MONITOR_DEFAULTTOPRIMARY );\n\tUINT iCurrentMonitor = 0;\n\tUINT numOfMonitor = TVPDirect3D->GetAdapterCount();\n\tfor( ; TVPDirect3D < numOfMonitor; ++iCurrentMonitor ) \t{\n\t\tif( IDirect3D9->GetAdapterMonitor(iCurrentMonitor) == windowMonitor )\n\t\t\tbreak;\n\t}\n\tif( iCurrentMonitor == numOfMonitor )\n\t\tiCurrentMonitor = D3DADAPTER_DEFAULT;\n\treturn iCurrentMonitor;\n}\n#endif\n//---------------------------------------------------------------------------\nvoid TVPSwitchToFullScreen(HWND window, tjs_int w, tjs_int h, iTVPDrawDevice* drawdevice )\n{\n\tif(TVPInFullScreen) return;\n\n\tTVPInitFullScreenOptions();\n\n\t//TVPReleaseVSyncTimingThread();\n\n\tif(!TVPUseChangeDisplaySettings)\n\t{\n\t\ttry\n\t\t{\n\t\t\tTVPInitDirect3D();\n\t\t}\n\t\tcatch(eTJS &e)\n\t\t{\n\t\t\tTVPAddLog(e.GetMessage());\n\t\t\tTVPUseChangeDisplaySettings = true;\n\t\t}\n\t\tcatch(...)\n\t\t{\n\t\t\tTVPUseChangeDisplaySettings = true;\n\t\t}\n\t}\n\n\t// get fullscreen mode candidates\n\tstd::vector<tTVPScreenModeCandidate> candidates;\n\ttTVPScreenMode preferred;\n\tpreferred.Width = w;\n\tpreferred.Height = h;\n\tpreferred.BitsPerPixel = TVPPreferredFullScreenBPP;\n\tTVPMakeFullScreenModeCandidates(\n\t\tpreferred,\n\t\tTVPPreferredFullScreenResolutionMode,\n\t\tTVPPreferredFullScreenUsingEngineZoomMode,\n\t\tcandidates);\n\n\t// try changing display mode\n\tbool success = false;\n\tfor(std::vector<tTVPScreenModeCandidate>::iterator i = candidates.begin();\n\t\ti != candidates.end(); i++)\n\t{\n\t\tTVPAddLog( TVPFormatMessage(TVPInfoTryScreenMode, i->Dump()) );\n\t\tsuccess = drawdevice->SwitchToFullScreen( window, i->Width, i->Height, i->BitsPerPixel, TVPDisplayColorFormat, TVPPreferredFullScreenResolutionMode != fsrExpandWindow );\n\t\tif( success )\n\t\t{\n\t\t\tTVPFullScreenMode = *i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif(!success)\n\t{\n\t\tTVPThrowExceptionMessage(TVPCannotSwitchToFullScreen, (const tjs_char*)TVPAllScreenModeError );\n\t}\n\n\tTVPAddLog( (const tjs_char*)TVPInfoChangeScreenModeSuccess );\n\n\tTVPInFullScreen = true;\n\n\tTVPGetDisplayColorFormat();\n\t//TVPEnsureVSyncTimingThread();\n}\n//---------------------------------------------------------------------------\nvoid TVPRecalcFullScreen( tjs_int w, tjs_int h )\n{\n\tif( TVPInFullScreen != true ) return;\n\n\tTVPInitFullScreenOptions();\n\n\t// get fullscreen mode candidates\n\tstd::vector<tTVPScreenModeCandidate> candidates;\n\ttTVPScreenMode preferred;\n\tpreferred.Width = w;\n\tpreferred.Height = h;\n\tpreferred.BitsPerPixel = TVPPreferredFullScreenBPP;\n\tTVPMakeFullScreenModeCandidates(\n\t\tpreferred,\n\t\tTVPPreferredFullScreenResolutionMode,\n\t\tTVPPreferredFullScreenUsingEngineZoomMode,\n\t\tcandidates);\n\n\tTVPFullScreenMode = *(candidates.begin());\n\tTVPGetDisplayColorFormat();\n}\n//---------------------------------------------------------------------------\nvoid TVPRevertFromFullScreen(HWND window,tjs_uint w,tjs_uint h, iTVPDrawDevice* drawdevice)\n{\n\tif(!TVPInFullScreen) return;\n\n\t//TVPReleaseVSyncTimingThread();\n\n\tdrawdevice->RevertFromFullScreen( window, w, h, TVPDefaultScreenMode.BitsPerPixel, TVPDisplayColorFormat );\n\n\tTVPInFullScreen = false;\n\n\tTVPGetDisplayColorFormat();\n\t//TVPEnsureVSyncTimingThread();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\nvoid TVPMinimizeFullScreenWindowAtInactivation()\n{\n\t// only works when TVPUseChangeDisplaySettings == true\n\t// (Direct3D framework does this)\n\n\tif(!TVPInFullScreen) return;\n\tif(!TVPUseChangeDisplaySettings) return;\n\n\t::ChangeDisplaySettings(NULL, 0);\n\n\t::ShowWindow(TVPFullScreenWindow, SW_MINIMIZE);\n}\n//---------------------------------------------------------------------------\nvoid TVPRestoreFullScreenWindowAtActivation()\n{\n\t// only works when TVPUseChangeDisplaySettings == true\n\t// (Direct3D framework does this)\n\n\tif(!TVPInFullScreen) return;\n\tif(!TVPUseChangeDisplaySettings) return;\n\n\tDEVMODE dm;\n\tZeroMemory(&dm, sizeof(DEVMODE));\n\tdm.dmSize = sizeof(DEVMODE);\n\tdm.dmPelsWidth = TVPFullScreenMode.Width;\n\tdm.dmPelsHeight = TVPFullScreenMode.Height;\n\tdm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;\n\tdm.dmBitsPerPel = TVPFullScreenMode.BitsPerPixel;\n\t::ChangeDisplaySettings((DEVMODE*)&dm, CDS_FULLSCREEN);\n\n\tShowWindow(TVPFullScreenWindow, SW_RESTORE);\n\tSetWindowPos(TVPFullScreenWindow, HWND_TOP,\n\t\t0, 0, TVPFullScreenMode.Width, TVPFullScreenMode.Height, SWP_SHOWWINDOW);\n}\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\nstatic void TVPRestoreDisplayMode()\n{\n\t// only works when TVPUseChangeDisplaySettings == true\n\tif(!TVPUseChangeDisplaySettings) return;\n\tif(!TVPInFullScreen) return;\n\t::ChangeDisplaySettings(NULL, 0);\n}\n//---------------------------------------------------------------------------\nstatic tTVPAtExit\n\tTVPRestoreDisplayModeAtExit(TVP_ATEXIT_PRI_CLEANUP, TVPUnloadDirect3D);\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPGetModalWindowOwner\n//---------------------------------------------------------------------------\nHWND TVPGetModalWindowOwnerHandle()\n{\n\tif(TVPFullScreenedWindow)\n\t\treturn TVPFullScreenedWindow->GetHandle();\n\telse\n\t\treturn Application->GetHandle();\n}\n//---------------------------------------------------------------------------\n#endif\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Window\n//---------------------------------------------------------------------------\ntTJSNI_Window::tTJSNI_Window()\n{\n\t//TVPEnsureVSyncTimingThread();\n//\tVSyncTimingThread = NULL;\n\tForm = NULL;\n}\n//---------------------------------------------------------------------------\ntjs_error TJS_INTF_METHOD\ntTJSNI_Window::Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj)\n{\n\ttjs_error hr = tTJSNI_BaseWindow::Construct(numparams, param, tjs_obj);\n\tif(TJS_FAILED(hr)) return hr;\n\tif( numparams >= 1 && param[0]->Type() == tvtObject ) {\n\t\ttTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n\t\ttTJSNI_Window *win = NULL;\n\t\tif(clo.Object != NULL) {\n\t\t\tif(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,tTJSNC_Window::ClassID, (iTJSNativeInstance**)&win)))\n\t\t\t\tTVPThrowExceptionMessage(TVPSpecifyWindow);\n\t\t\tif(!win) TVPThrowExceptionMessage(TVPSpecifyWindow);\n\t\t}\n#if 0\n\t\tForm = new TTVPWindowForm(Application, this, win);\n\t} else {\n\t\tForm = new TTVPWindowForm(Application, this);\n#endif\n\t}\n\tForm = TVPCreateAndAddWindow(this);\n\treturn TJS_S_OK;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::Invalidate()\n{\n\ttTJSNI_BaseWindow::Invalidate();\n#if 0\n\tif( VSyncTimingThread )\n\t{\n\t\tdelete VSyncTimingThread;\n\t\tVSyncTimingThread = NULL;\n\t}\n#endif\n\tif(Form)\n\t{\n\t\tForm->InvalidateClose();\n\t\tForm = NULL;\n\t}\n\n\t// remove all events\n\tTVPCancelSourceEvents(Owner);\n\tTVPCancelInputEvents(this);\n\n\t// Set Owner null\n\tOwner = NULL;\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::CanDeliverEvents() const\n{\n\tif(!Form) return false;\n\treturn GetVisible() && Form->GetFormEnabled();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::NotifyWindowClose()\n{\n\tForm = NULL;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SendCloseMessage()\n{\n\tif(Form) Form->SendCloseMessage();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::TickBeat()\n{\n\tif(Form) Form->TickBeat();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetWindowActive()\n{\n\tif(Form) return Form->GetWindowActive();\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::ResetDrawDevice()\n{\n\tif(Form) Form->ResetDrawDevice();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::FullScreenGuard() const {\n\tif( Form ) {\n\t\tif(Form->GetFullScreenMode())\n\t\t\tTVPThrowExceptionMessage(TVPInvalidPropertyInFullScreen);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::PostInputEvent(const ttstr &name, iTJSDispatch2 * params)\n{\n\t// posts input event\n\tif(!Form) return;\n\n\tstatic ttstr key_name(TJS_W(\"key\"));\n\tstatic ttstr shift_name(TJS_W(\"shift\"));\n\n\t// check input event name\n\tenum tEventType\n\t{\n\t\tetUnknown, etOnKeyDown, etOnKeyUp, etOnKeyPress\n\t} type;\n\n\tif(name == TJS_W(\"onKeyDown\"))\n\t\ttype = etOnKeyDown;\n\telse if(name == TJS_W(\"onKeyUp\"))\n\t\ttype = etOnKeyUp;\n\telse if(name == TJS_W(\"onKeyPress\"))\n\t\ttype = etOnKeyPress;\n\telse\n\t\ttype = etUnknown;\n\n\tif(type == etUnknown)\n\t\tTVPThrowExceptionMessage(TVPSpecifiedEventNameIsUnknown, name);\n\n\n\tif(type == etOnKeyDown || type == etOnKeyUp)\n\t{\n\t\t// this needs params, \"key\" and \"shift\"\n\t\tif(params == NULL)\n\t\t\tTVPThrowExceptionMessage(\n\t\t\t\tTVPSpecifiedEventNeedsParameter, name);\n\n\n\t\ttjs_uint key;\n\t\ttjs_uint32 shift = 0;\n\n\t\ttTJSVariant val;\n\t\tif(TJS_SUCCEEDED(params->PropGet(0, key_name.c_str(), key_name.GetHint(),\n\t\t\t&val, params)))\n\t\t\tkey = (tjs_int)val;\n\t\telse\n\t\t\tTVPThrowExceptionMessage(TVPSpecifiedEventNeedsParameter2,\n\t\t\t\tname, TJS_W(\"key\"));\n\n\t\tif(TJS_SUCCEEDED(params->PropGet(0, shift_name.c_str(), shift_name.GetHint(),\n\t\t\t&val, params)))\n\t\t\tshift = (tjs_int)val;\n\t\telse\n\t\t\tTVPThrowExceptionMessage(TVPSpecifiedEventNeedsParameter2,\n\t\t\t\tname, TJS_W(\"shift\"));\n\n\t\tuint16_t vcl_key = key;\n\t\tif(type == etOnKeyDown)\n\t\t\tForm->InternalKeyDown(key, shift);\n\t\telse if(type == etOnKeyUp)\n\t\t\t//Form->OnKeyUp(Form, vcl_key, TVP_TShiftState_From_uint32(shift));\n\t\t\tForm->OnKeyUp( vcl_key, TVP_TShiftState_From_uint32(shift) );\n\t}\n\telse if(type == etOnKeyPress)\n\t{\n\t\t// this needs param, \"key\"\n\t\tif(params == NULL)\n\t\t\tTVPThrowExceptionMessage(\n\t\t\t\tTVPSpecifiedEventNeedsParameter, name);\n\n\n\t\ttjs_uint key;\n\n\t\ttTJSVariant val;\n\t\tif(TJS_SUCCEEDED(params->PropGet(0, key_name.c_str(), key_name.GetHint(),\n\t\t\t&val, params)))\n\t\t\tkey = (tjs_int)val;\n\t\telse\n\t\t\tTVPThrowExceptionMessage(TVPSpecifiedEventNeedsParameter2,\n\t\t\t\tname, TJS_W(\"key\"));\n\n\t\tchar vcl_key = key;\n\t\t//Form->OnKeyPress(Form, vcl_key);\n\t\tForm->OnKeyPress(vcl_key,0,false,false);\n\t}\n}\n\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::NotifySrcResize()\n{\n\ttTJSNI_BaseWindow::NotifySrcResize();\n\n\t// is called from primary layer\n\t// ( or from TWindowForm to reset paint box's size )\n\ttjs_int w, h;\n\tDrawDevice->GetSrcSize(w, h);\n\tif(Form)\n\t\tForm->SetPaintBoxSize(w, h);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetDefaultMouseCursor()\n{\n\t// set window mouse cursor to default\n\tif(Form) Form->SetDefaultMouseCursor();\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetMouseCursor(tjs_int handle)\n{\n\t// set window mouse cursor\n\tif(Form) Form->SetMouseCursor(handle);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::GetCursorPos(tjs_int &x, tjs_int &y)\n{\n\t// get cursor pos in primary layer's coordinates\n\tif(Form) Form->GetCursorPos(x, y);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetCursorPos(tjs_int x, tjs_int y)\n{\n\t// set cursor pos in primar layer's coordinates\n\tif(Form) Form->SetCursorPos(x, y);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::WindowReleaseCapture()\n{\n\t//::ReleaseCapture(); // Windows API\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetHintText(iTJSDispatch2* sender, const ttstr & text)\n{\n\t// set hint text to window\n\tif(Form) Form->SetHintText(sender,text);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetAttentionPoint(tTJSNI_BaseLayer *layer,\n\ttjs_int l, tjs_int t)\n{\n\t// set attention point to window\n\tif(Form)\n\t{\n\t\t//class TFont * font = NULL;\n\t\tconst tTVPFont * font = NULL;\n\t\tif(layer)\n\t\t{\n\t\t\tiTVPBaseBitmap *bmp = layer->GetMainImage();\n\t\t\tif(bmp) {\n\t\t\t\t//font = bmp->GetFontCanvas()->GetFont(); =\n\t\t\t\t// font = bmp->GetFontCanvas();\n\t\t\t\tconst tTVPFont & finfo = bmp->GetFont();\n\t\t\t\tfont = &finfo;\n\t\t\t}\n\t\t}\n\n\t\tForm->SetAttentionPoint(l, t, font);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::DisableAttentionPoint()\n{\n\t// disable attention point\n\tif(Form) Form->DisableAttentionPoint();\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetImeMode(tTVPImeMode mode)\n{\n\t// set ime mode\n\tif(Form) Form->SetImeMode(mode);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetDefaultImeMode(tTVPImeMode mode)\n{\n\t// set default ime mode\n\tif(Form)\n\t{\n//\t\tForm->SetDefaultImeMode(mode, LayerManager->GetFocusedLayer() == NULL);\n\t}\n}\n//---------------------------------------------------------------------------\ntTVPImeMode tTJSNI_Window::GetDefaultImeMode() const\n{\n\tif(Form) return Form->GetDefaultImeMode();\n\treturn ::imDisable;\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::ResetImeMode()\n{\n\t// set default ime mode ( default mode is imDisable; IME is disabled )\n\tif(Form) Form->ResetImeMode();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::BeginUpdate(const tTVPComplexRect &rects)\n{\n\ttTJSNI_BaseWindow::BeginUpdate(rects);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::EndUpdate()\n{\n\ttTJSNI_BaseWindow::EndUpdate();\n}\n//---------------------------------------------------------------------------\n#if 0\nHWND tTJSNI_Window::GetSurfaceWindowHandle()\n{\n\tif(!Form) return NULL;\n\treturn Form->GetSurfaceWindowHandle();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::ZoomRectangle(\n\ttjs_int & left, tjs_int & top,\n\ttjs_int & right, tjs_int & bottom)\n{\n\tif(!Form) return;\n\tForm->ZoomRectangle(left, top, right, bottom);\n}\n//---------------------------------------------------------------------------\n#if 0\nHWND tTJSNI_Window::GetWindowHandle()\n{\n\tif(!Form) return NULL;\n\treturn Form->GetWindowHandle();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::GetVideoOffset(tjs_int &ofsx, tjs_int &ofsy)\n{\n\tif(!Form) {\n\t\tofsx = 0;\n\t\tofsy = 0;\n\t} else {\n\t\tForm->GetVideoOffset(ofsx,ofsy);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::ReadjustVideoRect()\n{\n\tif(!Form) return;\n\n\t// re-adjust video rectangle.\n\t// this reconnects owner window and video offsets.\n\n\ttObjectListSafeLockHolder<tTJSNI_BaseVideoOverlay> holder(VideoOverlay);\n\ttjs_int count = VideoOverlay.GetSafeLockedObjectCount();\n\n\tfor(tjs_int i = 0; i < count; i++)\n\t{\n\t\ttTJSNI_VideoOverlay * item = (tTJSNI_VideoOverlay*)\n\t\t\tVideoOverlay.GetSafeLockedObjectAt(i);\n\t\tif(!item) continue;\n\t\titem->ResetOverlayParams();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::WindowMoved()\n{\n\t// inform video overlays that the window has moved.\n\t// video overlays typically owns Direct3D surface which is not a part of\n\t// normal window systems and does not matter where the owner window is.\n\t// so we must inform window moving to overlay window.\n\n\ttObjectListSafeLockHolder<tTJSNI_BaseVideoOverlay> holder(VideoOverlay);\n\ttjs_int count = VideoOverlay.GetSafeLockedObjectCount();\n\tfor(tjs_int i = 0; i < count; i++)\n\t{\n\t\ttTJSNI_VideoOverlay * item = (tTJSNI_VideoOverlay*)\n\t\t\tVideoOverlay.GetSafeLockedObjectAt(i);\n\t\tif(!item) continue;\n\t\titem->SetRectangleToVideoOverlay();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::DetachVideoOverlay()\n{\n\t// detach video overlay window\n\t// this is done before the window is being fullscreened or un-fullscreened.\n\ttObjectListSafeLockHolder<tTJSNI_BaseVideoOverlay> holder(VideoOverlay);\n\ttjs_int count = VideoOverlay.GetSafeLockedObjectCount();\n\tfor(tjs_int i = 0; i < count; i++)\n\t{\n\t\ttTJSNI_VideoOverlay * item = (tTJSNI_VideoOverlay*)\n\t\t\tVideoOverlay.GetSafeLockedObjectAt(i);\n\t\tif(!item) continue;\n\t\titem->DetachVideoOverlay();\n\t}\n}\n//---------------------------------------------------------------------------\n#if 0\nHWND tTJSNI_Window::GetWindowHandleForPlugin()\n{\n\tif(!Form) return NULL;\n\treturn Form->GetWindowHandleForPlugin();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::RegisterWindowMessageReceiver(tTVPWMRRegMode mode,\n\t\tvoid * proc, const void *userdata)\n{\n\tif(!Form) return;\n\tForm->RegisterWindowMessageReceiver(mode, proc, userdata);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::Close()\n{\n\tif(Form) Form->Close();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::OnCloseQueryCalled(bool b)\n{\n\tif(Form) Form->OnCloseQueryCalled(b);\n}\n//---------------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nvoid tTJSNI_Window::BeginMove()\n{\n\tFullScreenGuard();\n\tif(Form) Form->BeginMove();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::BringToFront()\n{\n\tif(Form) Form->BringToFront();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::Update(tTVPUpdateType type)\n{\n\tif(Form) Form->UpdateWindow(type);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::ShowModal()\n{\n\tFullScreenGuard();\n\tif(Form)\n\t{\n\t\tTVPClearAllWindowInputEvents();\n\t\t\t// cancel all input events that can cause delayed operation\n\t\tForm->ShowWindowAsModal();\n\t}\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::HideMouseCursor()\n{\n\tif(Form) Form->HideMouseCursor();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetVisible() const\n{\n\tif(!Form) return false;\n\treturn Form->GetVisible();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetVisible(bool s)\n{\n\tFullScreenGuard();\n\tif( Form ) Form->SetVisibleFromScript(s);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::GetCaption(ttstr & v) const\n{\n\tif(Form) v = Form->GetCaption(); else v.Clear();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetCaption(const ttstr & v)\n{\n\tif(Form) Form->SetCaption( v.AsStdString() );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetWidth(tjs_int w)\n{\n\tFullScreenGuard();\n\tif( Form ) Form->SetWidth( w );\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetWidth() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetWidth();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetHeight(tjs_int h)\n{\n\tFullScreenGuard();\n\tif( Form ) Form->SetHeight( h );\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetHeight() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetLeft(tjs_int l)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetLeft( l );\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetLeft() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetLeft();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetTop(tjs_int t)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetTop( t );\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetTop() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetTop();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetSize(tjs_int w, tjs_int h)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetSize( w, h );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMinWidth(int v)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMinWidth( v );\n}\n//---------------------------------------------------------------------------\nint  tTJSNI_Window::GetMinWidth() const\n{\n\tif(Form) return Form->GetMinWidth(); else return 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMinHeight(int v)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMinHeight( v );\n}\n//---------------------------------------------------------------------------\nint  tTJSNI_Window::GetMinHeight() const\n{\n\tif(Form) return Form->GetMinHeight(); else return 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMinSize(int w, int h)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMinSize( w, h );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMaxWidth(int v)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMaxWidth( v );\n}\n//---------------------------------------------------------------------------\nint  tTJSNI_Window::GetMaxWidth() const\n{\n\tif(Form) return Form->GetMaxWidth(); else return 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMaxHeight(int v)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMaxHeight( v );\n}\n//---------------------------------------------------------------------------\nint  tTJSNI_Window::GetMaxHeight() const\n{\n\tif(Form) return Form->GetMaxHeight(); else return 0;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMaxSize(int w, int h)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetMaxSize( w, h );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetPosition(tjs_int l, tjs_int t)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetPosition( l, t );\n}\n//---------------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nvoid tTJSNI_Window::SetLayerLeft(tjs_int l)\n{\n\tif(Form) Form->SetLayerLeft(l);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetLayerLeft() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetLayerLeft();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetLayerTop(tjs_int t)\n{\n\tif(Form) Form->SetLayerTop(t);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetLayerTop() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetLayerTop();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetLayerPosition(tjs_int l, tjs_int t)\n{\n\tif(Form) Form->SetLayerPosition(l, t);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetInnerSunken(bool b)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetInnerSunken(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetInnerSunken() const\n{\n\tif(!Form) return true;\n\treturn Form->GetInnerSunken();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetInnerWidth(tjs_int w)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetInnerWidth(w);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetInnerWidth() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetInnerWidth();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetInnerHeight(tjs_int h)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetInnerHeight(h);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetInnerHeight() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetInnerHeight();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetInnerSize(tjs_int w, tjs_int h)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetInnerSize(w, h);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetBorderStyle(tTVPBorderStyle st)\n{\n\tFullScreenGuard();\n\tif(Form) Form->SetBorderStyle(st);\n}\n//---------------------------------------------------------------------------\ntTVPBorderStyle tTJSNI_Window::GetBorderStyle() const\n{\n\tif(!Form) return (tTVPBorderStyle)0;\n\treturn Form->GetBorderStyle();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetStayOnTop(bool b)\n{\n\tif(!Form) return;\n\tForm->SetStayOnTop(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetStayOnTop() const\n{\n\tif(!Form) return false;\n\treturn Form->GetStayOnTop();\n}\n//---------------------------------------------------------------------------\n#ifdef USE_OBSOLETE_FUNCTIONS\nvoid tTJSNI_Window::SetShowScrollBars(bool b)\n{\n\tif(Form) Form->SetShowScrollBars(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetShowScrollBars() const\n{\n\tif(!Form) return true;\n\treturn Form->GetShowScrollBars();\n}\n#endif\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetFullScreen(bool b)\n{\n\tif(!Form) return;\n\tForm->SetFullScreenMode(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetFullScreen() const\n{\n\tif(!Form) return false;\n\treturn Form->GetFullScreenMode();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetUseMouseKey(bool b)\n{\n\tif(!Form) return;\n\tForm->SetUseMouseKey(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetUseMouseKey() const\n{\n\tif(!Form) return false;\n\treturn Form->GetUseMouseKey();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetTrapKey(bool b)\n{\n\tif(!Form) return;\n\tForm->SetTrapKey(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetTrapKey() const\n{\n\tif(!Form) return false;\n\treturn Form->GetTrapKey();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMaskRegion(tjs_int threshold)\n{\n\tif(!Form) return;\n\n\tif(!DrawDevice) TVPThrowExceptionMessage(TVPWindowHasNoLayer);\n\ttTJSNI_BaseLayer *lay = DrawDevice->GetPrimaryLayer();\n\tif(!lay) TVPThrowExceptionMessage(TVPWindowHasNoLayer);\n//\tForm->SetMaskRegion( ((tTJSNI_Layer*)lay)->CreateMaskRgn((tjs_uint)threshold) );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::RemoveMaskRegion()\n{\n\tif(!Form) return;\n\tForm->RemoveMaskRegion();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetMouseCursorState(tTVPMouseCursorState mcs)\n{\n\tif(!Form) return;\n\tForm->SetMouseCursorState(mcs);\n}\n//---------------------------------------------------------------------------\ntTVPMouseCursorState tTJSNI_Window::GetMouseCursorState() const\n{\n\tif(!Form) return mcsVisible;\n\treturn Form->GetMouseCursorState();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetFocusable(bool b)\n{\n\tif(!Form) return;\n\tForm->SetFocusable(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetFocusable()\n{\n\tif(!Form) return true;\n\treturn Form->GetFocusable();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetZoom(tjs_int numer, tjs_int denom)\n{\n\tif(!Form) return;\n\tForm->SetZoom(numer, denom);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetZoomNumer(tjs_int n)\n{\n\tif(!Form) return;\n\tForm->SetZoomNumer(n);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetZoomNumer() const\n{\n\tif(!Form) return 1;\n\treturn Form->GetZoomNumer();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetZoomDenom(tjs_int n)\n{\n\tif(!Form) return;\n\tForm->SetZoomDenom(n);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetZoomDenom() const\n{\n\tif(!Form) return 1;\n\treturn Form->GetZoomDenom();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetTouchScaleThreshold( tjs_real threshold ) {\n\tif(!Form) return;\n\tForm->SetTouchScaleThreshold(threshold);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchScaleThreshold() const {\n\tif(!Form) return 0;\n\treturn Form->GetTouchScaleThreshold();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetTouchRotateThreshold( tjs_real threshold ) {\n\tif(!Form) return;\n\tForm->SetTouchRotateThreshold(threshold);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchRotateThreshold() const {\n\tif(!Form) return 0;\n\treturn Form->GetTouchRotateThreshold();\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchPointStartX( tjs_int index ) {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointStartX(index);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchPointStartY( tjs_int index ) {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointStartY(index);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchPointX( tjs_int index ) {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointX(index);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchPointY( tjs_int index ) {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointY(index);\n}\n//---------------------------------------------------------------------------\ntjs_real tTJSNI_Window::GetTouchPointID( tjs_int index ) {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointID(index);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetTouchPointCount() {\n\tif(!Form) return 0;\n\treturn Form->GetTouchPointCount();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetTouchVelocity( tjs_int id, float& x, float& y, float& speed ) const {\n\tif(!Form) return false;\n\treturn Form->GetTouchVelocity( id, x, y, speed );\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetMouseVelocity( float& x, float& y, float& speed ) const {\n\tif(!Form) return false;\n\treturn Form->GetMouseVelocity( x, y, speed );\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::ResetMouseVelocity() {\n\tif(!Form) return;\n\treturn Form->ResetMouseVelocity();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetHintDelay( tjs_int delay )\n{\n\tif(!Form) return;\n\tForm->SetHintDelay(delay);\n}\n//---------------------------------------------------------------------------\ntjs_int tTJSNI_Window::GetHintDelay() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetHintDelay();\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::SetEnableTouch( bool b )\n{\n\tif(!Form) return;\n\tForm->SetEnableTouch(b);\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::GetEnableTouch() const\n{\n\tif(!Form) return 0;\n\treturn Form->GetEnableTouch();\n}\n//---------------------------------------------------------------------------\nint tTJSNI_Window::GetDisplayOrientation()\n{\n\tif(!Form) return orientUnknown;\n\treturn Form->GetDisplayOrientation();\n}\n//---------------------------------------------------------------------------\nint tTJSNI_Window::GetDisplayRotate()\n{\n\tif(!Form) return -1;\n\treturn Form->GetDisplayRotate();\n}\n//---------------------------------------------------------------------------\nbool tTJSNI_Window::WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed )\n{\n\tif( DrawDevice ) return DrawDevice->WaitForVBlank( in_vblank, delayed );\n\treturn false;\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::UpdateVSyncThread()\n{\n#if 0\n\tif( WaitVSync ) {\n\t\tif( VSyncTimingThread == NULL ) {\n\t\t\tVSyncTimingThread = new tTVPVSyncTimingThread(this);\n\t\t}\n\t} else {\n\t\tif( VSyncTimingThread ) {\n\t\t\tdelete VSyncTimingThread;\n\t\t}\n\t\tVSyncTimingThread = NULL;\n\t}\n#endif\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::StartBitmapCompletion(iTVPLayerManager * manager)\n{\n\tif( DrawDevice ) DrawDevice->StartBitmapCompletion(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity)\n{\n\tif( DrawDevice ) {\n#if 0\n\t\tDrawDevice->NotifyBitmapCompleted(manager,x,y,bits,bitmapinfo->GetBITMAPINFO(), cliprect, type, opacity );\n#endif\n\t\tDrawDevice->NotifyBitmapCompleted(manager, x, y, bmp, cliprect, type, opacity);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::EndBitmapCompletion(iTVPLayerManager * manager)\n{\n\tif( DrawDevice ) DrawDevice->EndBitmapCompletion(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetMouseCursor(class iTVPLayerManager* manager, tjs_int cursor)\n{\n\tif( DrawDevice ) {\n\t\tif(cursor == 0)\n\t\t\tDrawDevice->SetDefaultMouseCursor(manager);\n\t\telse\n\t\t\tDrawDevice->SetMouseCursor(manager, cursor);\n\t}\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::GetCursorPos(class iTVPLayerManager* manager, tjs_int &x, tjs_int &y)\n{\n\tif( DrawDevice ) DrawDevice->GetCursorPos(manager, x, y);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetCursorPos(class iTVPLayerManager* manager, tjs_int x, tjs_int y)\n{\n\tif( DrawDevice ) DrawDevice->SetCursorPos(manager, x, y);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::ReleaseMouseCapture(class iTVPLayerManager* manager)\n{\n\tif( DrawDevice ) DrawDevice->WindowReleaseCapture(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetHint(class iTVPLayerManager* manager, iTJSDispatch2* sender, const ttstr &hint)\n{\n\tif( DrawDevice ) DrawDevice->SetHintText(manager, sender, hint);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::NotifyLayerResize(class iTVPLayerManager* manager)\n{\n\tif( DrawDevice ) DrawDevice->NotifyLayerResize(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::NotifyLayerImageChange(class iTVPLayerManager* manager)\n{\n\tif( DrawDevice ) DrawDevice->NotifyLayerImageChange(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetAttentionPoint(class iTVPLayerManager* manager, tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y)\n{\n\tif( DrawDevice ) DrawDevice->SetAttentionPoint(manager, layer, x, y);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::DisableAttentionPoint(class iTVPLayerManager* manager)\n{\n\tif( DrawDevice ) DrawDevice->DisableAttentionPoint(manager);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::SetImeMode( class iTVPLayerManager* manager, tjs_int mode ) // mode == tTVPImeMode\n{\n\tif( DrawDevice ) DrawDevice->SetImeMode(manager, (tTVPImeMode)mode);\n}\n//---------------------------------------------------------------------------\nvoid TJS_INTF_METHOD tTJSNI_Window::ResetImeMode( class iTVPLayerManager* manager )\n{\n\tif( DrawDevice ) DrawDevice->ResetImeMode(manager);\n}\n//---------------------------------------------------------------------------\nvoid tTJSNI_Window::OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id )\n{\n\ttTJSNI_BaseWindow::OnTouchUp( x, y, cx, cy, id );\n\tif( Form )\n\t{\n\t\tForm->ResetTouchVelocity( id );\n\t}\n}\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n// tTJSNC_Window::CreateNativeInstance : returns proper instance object\n//---------------------------------------------------------------------------\ntTJSNativeInstance *tTJSNC_Window::CreateNativeInstance()\n{\n\treturn new tTJSNI_Window();\n}\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// TVPCreateNativeClass_Window\n//---------------------------------------------------------------------------\ntTJSNativeClass * TVPCreateNativeClass_Window()\n{\n\ttTJSNativeClass *cls = new tTJSNC_Window();\n\tstatic tjs_uint32 TJS_NCM_CLASSID;\n\tTJS_NCM_CLASSID = tTJSNC_Window::ClassID;\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(findFullScreenCandidates)\n{\n\tif(numparams < 5) return TJS_E_BADPARAMCOUNT;\n#if 0\n\tstd::vector<tTVPScreenModeCandidate> candidates;\n\n\ttTVPScreenMode preferred;\n\tpreferred.Width = *param[0];\n\tpreferred.Height = *param[1];\n\tpreferred.BitsPerPixel = *param[2];\n\ttjs_int mode = *param[3];\n\ttjs_int zoom_mode = *param[4];\n\n\tTVPMakeFullScreenModeCandidates(preferred, (tTVPFullScreenResolutionMode)mode,\n\t\t(tTVPFullScreenUsingEngineZoomMode)zoom_mode, candidates);\n#endif\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, findFullScreenCandidates)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(registerMessageReceiver)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\t_this->RegisterWindowMessageReceiver((tTVPWMRRegMode)((tjs_int)*param[0]),\n\t\treinterpret_cast<void *>(param[1]->AsInteger()),\n\t\treinterpret_cast<const void *>(param[2]->AsInteger()));\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, registerMessageReceiver)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(getTouchPoint)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_int index = (tjs_int)*param[0];\n\tif( index < _this->GetTouchPointCount() ) {\n\t\tif( result ) {\n\t\t\tiTJSDispatch2 * object = TJSCreateDictionaryObject();\n\n\t\t\tstatic ttstr startX_name(TJS_W(\"startX\"));\n\t\t\tstatic ttstr startY_name(TJS_W(\"startY\"));\n\t\t\tstatic ttstr X_name(TJS_W(\"x\"));\n\t\t\tstatic ttstr Y_name(TJS_W(\"y\"));\n\t\t\tstatic ttstr ID_name(TJS_W(\"ID\"));\n\t\t\t{\n\t\t\t\ttTJSVariant val(_this->GetTouchPointStartX(index));\n\t\t\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, startX_name.c_str(), startX_name.GetHint(), &val, object)))\n\t\t\t\t\t\tTVPThrowInternalError;\n\t\t\t}\n\t\t\t{\n\t\t\t\ttTJSVariant val(_this->GetTouchPointStartY(index));\n\t\t\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, startY_name.c_str(), startY_name.GetHint(), &val, object)))\n\t\t\t\t\t\tTVPThrowInternalError;\n\t\t\t}\n\t\t\t{\n\t\t\t\ttTJSVariant val(_this->GetTouchPointX(index));\n\t\t\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, X_name.c_str(), X_name.GetHint(), &val, object)))\n\t\t\t\t\t\tTVPThrowInternalError;\n\t\t\t}\n\t\t\t{\n\t\t\t\ttTJSVariant val(_this->GetTouchPointY(index));\n\t\t\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, Y_name.c_str(), Y_name.GetHint(), &val, object)))\n\t\t\t\t\t\tTVPThrowInternalError;\n\t\t\t}\n\t\t\t{\n\t\t\t\ttTJSVariant val(_this->GetTouchPointID(index));\n\t\t\t\tif(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, ID_name.c_str(), ID_name.GetHint(), &val, object)))\n\t\t\t\t\t\tTVPThrowInternalError;\n\t\t\t}\n\t\t\ttTJSVariant objval(object, object);\n\t\t\tobject->Release();\n\t\t\t*result = objval;\n\t\t}\n\t} else {\n\t\treturn TJS_E_INVALIDPARAM;\n\t}\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, getTouchPoint)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(getTouchVelocity)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 4) return TJS_E_BADPARAMCOUNT;\n\n\ttjs_int id = (tjs_int)*param[0];\n\tfloat x, y, speed;\n\tbool ret = _this->GetTouchVelocity( id, x, y, speed );\n\tif( result ) {\n\t\t*result = ret ? (tjs_int)1 : (tjs_int)0;\n\t}\n\tif( ret ) {\n\t\t(*param[1]) = (tjs_real)x;\n\t\t(*param[2]) = (tjs_real)y;\n\t\t(*param[3]) = (tjs_real)speed;\n\t} else {\n\t\t(*param[1]) = (tjs_real)0.0;\n\t\t(*param[2]) = (tjs_real)0.0;\n\t\t(*param[3]) = (tjs_real)0.0;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, getTouchVelocity)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(getMouseVelocity)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\tif(numparams < 3) return TJS_E_BADPARAMCOUNT;\n\n\tfloat x, y, speed;\n\tbool ret = _this->GetMouseVelocity( x, y, speed );\n\tif( result ) {\n\t\t*result = ret ? (tjs_int)1 : (tjs_int)0;\n\t}\n\tif( ret ) {\n\t\t(*param[0]) = (tjs_real)x;\n\t\t(*param[1]) = (tjs_real)y;\n\t\t(*param[2]) = (tjs_real)speed;\n\t} else {\n\t\t(*param[0]) = (tjs_real)0.0;\n\t\t(*param[1]) = (tjs_real)0.0;\n\t\t(*param[2]) = (tjs_real)0.0;\n\t}\n\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, getMouseVelocity)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_METHOD_DECL(resetMouseVelocity)\n{\n\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t_this->ResetMouseVelocity();\n\treturn TJS_S_OK;\n}\nTJS_END_NATIVE_METHOD_DECL_OUTER(cls, resetMouseVelocity)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(HWND)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = (tTVInteger)(tjs_intptr_t)_this/*->GetWindowHandleForPlugin()*/;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, HWND)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(drawDevice)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetDrawDeviceObject();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetDrawDeviceObject(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, drawDevice)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(touchScaleThreshold)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetTouchScaleThreshold();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetTouchScaleThreshold(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, touchScaleThreshold)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(touchRotateThreshold)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetTouchRotateThreshold();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetTouchRotateThreshold(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, touchRotateThreshold)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(touchPointCount)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetTouchPointCount();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, touchPointCount)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(hintDelay)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetHintDelay();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetHintDelay(*param);\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, hintDelay)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(enableTouch)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetEnableTouch()?1:0;\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_BEGIN_NATIVE_PROP_SETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t_this->SetEnableTouch( ((tjs_int)*param) ? true : false );\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, enableTouch)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(displayOrientation)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetDisplayOrientation();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, displayOrientation)\n//---------------------------------------------------------------------------\nTJS_BEGIN_NATIVE_PROP_DECL(displayRotate)\n{\n\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t{\n\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_Window);\n\t\t*result = _this->GetDisplayRotate();\n\t\treturn TJS_S_OK;\n\t}\n\tTJS_END_NATIVE_PROP_GETTER\n\n\tTJS_DENY_NATIVE_PROP_SETTER\n}\nTJS_END_NATIVE_PROP_DECL_OUTER(cls, displayRotate)\n//---------------------------------------------------------------------------\n\n\t// TVPGetDisplayColorFormat(); // this will be ran only once here\n\n\treturn cls;\n}\n//---------------------------------------------------------------------------\n"
  },
  {
    "path": "src/core/visual/win32/WindowImpl.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// \"Window\" TJS Class implementation\n//---------------------------------------------------------------------------\n\n\n#ifndef WindowImplH\n#define WindowImplH\n\n#include \"WindowIntf.h\"\n#include \"win32/TVPWindow.h\"\n\n/*[*/\n//---------------------------------------------------------------------------\n// window message receivers\n//---------------------------------------------------------------------------\n#if 0\n#pragma pack(push, 4)\nstruct tTVPWindowMessage\n{\n\tunsigned int Msg; // window message\n\tWPARAM WParam;  // WPARAM\n\tLPARAM LParam;  // LPARAM\n\tLRESULT Result;  // result\n};\n#pragma pack(pop)\ntypedef bool (__stdcall * tTVPWindowMessageReceiver)\n\t(void *userdata, tTVPWindowMessage *Message);\n\n#define TVP_WM_DETACH (WM_USER+106)  // before re-generating the window\n#define TVP_WM_ATTACH (WM_USER+107)  // after re-generating the window\n#define TVP_WM_FULLSCREEN_CHANGING (WM_USER+108)  // before full-screen or window changing\n#define TVP_WM_FULLSCREEN_CHANGED  (WM_USER+109)  // after full-screen or window changing\n#endif\n\n/*]*/\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n/*\nstruct tTVP_devicemodeA {\n\t// copy of DEVMODE, to avoid windows platform SDK version mismatch\n#pragma pack(push, 1)\n\tBYTE   dmDeviceName[CCHDEVICENAME];\n\tWORD dmSpecVersion;\n\tWORD dmDriverVersion;\n\tWORD dmSize;\n\tWORD dmDriverExtra;\n\tDWORD dmFields;\n\tunion {\n\t  struct {\n\t\tshort dmOrientation;\n\t\tshort dmPaperSize;\n\t\tshort dmPaperLength;\n\t\tshort dmPaperWidth;\n\t  };\n\t  POINTL dmPosition;\n\t};\n\tshort dmScale;\n\tshort dmCopies;\n\tshort dmDefaultSource;\n\tshort dmPrintQuality;\n\tshort dmColor;\n\tshort dmDuplex;\n\tshort dmYResolution;\n\tshort dmTTOption;\n\tshort dmCollate;\n\tBYTE   dmFormName[CCHFORMNAME];\n\tWORD   dmLogPixels;\n\tDWORD  dmBitsPerPel;\n\tDWORD  dmPelsWidth;\n\tDWORD  dmPelsHeight;\n\tunion {\n\t\tDWORD  dmDisplayFlags;\n\t\tDWORD  dmNup;\n\t};\n\tDWORD  dmDisplayFrequency;\n\tDWORD  dmICMMethod;\n\tDWORD  dmICMIntent;\n\tDWORD  dmMediaType;\n\tDWORD  dmDitherType;\n\tDWORD  dmReserved1;\n\tDWORD  dmReserved2;\n#pragma pack(pop)\n};\n*/\n//---------------------------------------------------------------------------\n\n\n//---------------------------------------------------------------------------\n// Mouse Cursor Management\n//---------------------------------------------------------------------------\nextern tjs_int TVPGetCursor(const ttstr & name);\n//---------------------------------------------------------------------------\n\n\n\n//---------------------------------------------------------------------------\n// Utility functions\n//---------------------------------------------------------------------------\nTJS_EXP_FUNC_DEF(tjs_uint32, TVPGetCurrentShiftKeyState, ());\n\n// implement for Application\n#if 0\nTJS_EXP_FUNC_DEF(void, TVPRegisterAcceleratorKey, (HWND hWnd, char virt, short key, short cmd) );\nTJS_EXP_FUNC_DEF(void, TVPUnregisterAcceleratorKey, (HWND hWnd, short cmd));\nTJS_EXP_FUNC_DEF(void, TVPDeleteAcceleratorKeyTable, (HWND hWnd));\nHWND TVPGetModalWindowOwnerHandle();\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Color Format Detection\n//---------------------------------------------------------------------------\nextern tjs_int TVPDisplayColorFormat;\n//---------------------------------------------------------------------------\n\n\n\n\n//---------------------------------------------------------------------------\n// Screen Mode management\n//---------------------------------------------------------------------------\n\n//! @brief\t\tStructure for monitor screen mode\nstruct tTVPScreenMode\n{\n\ttjs_int Width; //!< width of screen in pixel\n\ttjs_int Height; //!< height of screen in pixel\n\ttjs_int BitsPerPixel; //!< bits per pixel (0 = unspecified)\n\n\tttstr Dump() const\n\t{\n\t\treturn\n\t\t\tDumpHeightAndWidth() +\n\t\t\tTJS_W(\", BitsPerPixel=\") + (BitsPerPixel?ttstr(BitsPerPixel):ttstr(TJS_W(\"unspecified\")));\n\t}\n\n\tttstr DumpHeightAndWidth() const\n\t{\n\t\treturn\n\t\t\tTJS_W(\"Width=\") + ttstr(Width) +\n\t\t\tTJS_W(\", Height=\") + ttstr(Height);\n\t}\n\n\tbool operator < (const tTVPScreenMode & rhs) const {\n\t\ttjs_int area_this = Width * Height;\n\t\ttjs_int area_rhs  = rhs.Width * rhs.Height;\n\t\tif(area_this < area_rhs) return true;\n\t\tif(area_this > area_rhs) return false;\n\t\tif(BitsPerPixel < rhs.BitsPerPixel) return true;\n\t\tif(BitsPerPixel > rhs.BitsPerPixel) return false;\n\t\treturn false;\n\t}\n\tbool operator == (const tTVPScreenMode & rhs) const {\n\t\treturn ( Width == rhs.Width && Height == rhs.Height && BitsPerPixel == rhs.BitsPerPixel );\n\t}\n};\n\n//! @brief\t\tStructure for monitor screen mode candidate\nstruct tTVPScreenModeCandidate : tTVPScreenMode\n{\n\ttjs_int ZoomNumer; //!< zoom ratio numer\n\ttjs_int ZoomDenom; //!< zoom ratio denom\n\ttjs_int RankZoomIn;\n\ttjs_int RankBPP;\n\ttjs_int RankZoomBeauty;\n\ttjs_int RankSize; //!< candidate preference priority (lower value is higher preference)\n\n\tttstr Dump() const\n\t{\n\t\treturn tTVPScreenMode::Dump() +\n\t\t\tTJS_W(\", ZoomNumer=\") + ttstr(ZoomNumer) +\n\t\t\tTJS_W(\", ZoomDenom=\") + ttstr(ZoomDenom) +\n\t\t\tTJS_W(\", RankZoomIn=\") + ttstr(RankZoomIn) +\n\t\t\tTJS_W(\", RankBPP=\") + ttstr(RankBPP) +\n\t\t\tTJS_W(\", RankZoomBeauty=\") + ttstr(RankZoomBeauty) +\n\t\t\tTJS_W(\", RankSize=\") + ttstr(RankSize);\n\t}\n\n\tbool operator < (const tTVPScreenModeCandidate & rhs) const{\n\t\tif(RankZoomIn < rhs.RankZoomIn) return true;\n\t\tif(RankZoomIn > rhs.RankZoomIn) return false;\n\t\tif(RankBPP < rhs.RankBPP) return true;\n\t\tif(RankBPP > rhs.RankBPP) return false;\n\t\tif(RankZoomBeauty < rhs.RankZoomBeauty) return true;\n\t\tif(RankZoomBeauty > rhs.RankZoomBeauty) return false;\n\t\tif(RankSize < rhs.RankSize) return true;\n\t\tif(RankSize > rhs.RankSize) return false;\n\t\treturn false;\n\t}\n};\nstruct IDirect3D9;\nextern void TVPTestDisplayMode(tjs_int w, tjs_int h, tjs_int & bpp);\nextern void TVPSwitchToFullScreen(HWND window, tjs_int w, tjs_int h, class iTVPDrawDevice* drawdevice);\nextern void TVPRecalcFullScreen( tjs_int w, tjs_int h );\nextern void TVPRevertFromFullScreen(HWND window,tjs_uint w,tjs_uint h, class iTVPDrawDevice* drawdevice);\nTJS_EXP_FUNC_DEF(void, TVPEnsureDirect3DObject, ());\nvoid TVPDumpDirect3DDriverInformation();\nextern tTVPScreenModeCandidate TVPFullScreenMode;\n/*[*/\n//---------------------------------------------------------------------------\n// Direct3D former declaration\n//---------------------------------------------------------------------------\n#ifndef DIRECT3D_VERSION\nstruct IDirect3D9;\n#endif\n\n/*]*/\nTJS_EXP_FUNC_DEF(IDirect3D9 *,  TVPGetDirect3DObjectNoAddRef, ());\nextern void TVPMinimizeFullScreenWindowAtInactivation();\nextern void TVPRestoreFullScreenWindowAtActivation();\n#endif\n//---------------------------------------------------------------------------\n\n\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------\n// tTJSNI_Window : Window Native Instance\n//---------------------------------------------------------------------------\ntypedef iWindowLayer TTVPWindowForm;\nclass iTVPDrawDevice;\nclass tTJSNI_BaseLayer;\nclass tTJSNI_Window : public tTJSNI_BaseWindow\n{\n\tTTVPWindowForm *Form;\n//\tclass tTVPVSyncTimingThread *VSyncTimingThread;\n\npublic:\n\ttTJSNI_Window();\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param,\n\t\tiTJSDispatch2 *tjs_obj);\n\tvoid TJS_INTF_METHOD Invalidate();\n\tbool CloseFlag;\n\npublic:\n\tbool CanDeliverEvents() const; // tTJSNI_BaseWindow::CanDeliverEvents override\n\npublic:\n\tTTVPWindowForm * GetForm() const override { return Form; }\n\tvoid NotifyWindowClose();\n\tvoid SendCloseMessage();\n\tvoid TickBeat();\n\nprivate:\n\tbool GetWindowActive();\n\tvoid UpdateVSyncThread();\n\t/**\n\t * tXN[ɑłȂlς悤ƂɊmF̂ߌĂяoAtXN[̎Oo\n\t */\n\tvoid FullScreenGuard() const;\n\npublic:\n//-- draw device\n\tvirtual void ResetDrawDevice();\n\n//-- event control\n\tvirtual void PostInputEvent(const ttstr &name, iTJSDispatch2 * params);  // override\n\n//-- interface to layer manager\n\tvoid TJS_INTF_METHOD NotifySrcResize(); // is called from primary layer\n\n\tvoid TJS_INTF_METHOD SetDefaultMouseCursor(); // set window mouse cursor to default\n\tvoid TJS_INTF_METHOD SetMouseCursor(tjs_int cursor); // set window mouse cursor\n\tvoid TJS_INTF_METHOD GetCursorPos(tjs_int &x, tjs_int &y);\n\tvoid TJS_INTF_METHOD SetCursorPos(tjs_int x, tjs_int y);\n\tvoid TJS_INTF_METHOD WindowReleaseCapture();\n\tvoid TJS_INTF_METHOD SetHintText(iTJSDispatch2* sender, const ttstr & text);\n\tvoid TJS_INTF_METHOD SetAttentionPoint(tTJSNI_BaseLayer *layer,\n\t\ttjs_int l, tjs_int t);\n\tvoid TJS_INTF_METHOD DisableAttentionPoint();\n\tvoid TJS_INTF_METHOD SetImeMode(tTVPImeMode mode);\n\tvoid SetDefaultImeMode(tTVPImeMode mode);\n\ttTVPImeMode GetDefaultImeMode() const;\n\tvoid TJS_INTF_METHOD ResetImeMode();\n\n//-- update managment\n\tvoid BeginUpdate(const tTVPComplexRect &rects);\n\tvoid EndUpdate();\n\n//-- interface to VideoOverlay object\npublic:\n#if 0\n\tHWND GetSurfaceWindowHandle();\n\tHWND GetWindowHandle();\n#endif\n\tvoid GetVideoOffset(tjs_int &ofsx, tjs_int &ofsy);\n\n\tvoid ReadjustVideoRect();\n\tvoid WindowMoved();\n\tvoid DetachVideoOverlay();\n\n//-- interface to plugin\n\tvoid ZoomRectangle(\n\t\ttjs_int & left, tjs_int & top,\n\t\ttjs_int & right, tjs_int & bottom);\n#if 0\n\tHWND GetWindowHandleForPlugin();\n#endif\n\tvoid RegisterWindowMessageReceiver(tTVPWMRRegMode mode,\n\t\tvoid * proc, const void *userdata);\n\n//-- methods\n\tvoid Close();\n\tvoid OnCloseQueryCalled(bool b);\n\t\n#ifdef USE_OBSOLETE_FUNCTIONS\n\tvoid BeginMove();\n#endif\n\n\tvoid BringToFront();\n\tvoid Update(tTVPUpdateType);\n\n\tvoid ShowModal();\n\n\tvoid HideMouseCursor();\n\n//-- properties\n\tbool GetVisible() const;\n\tvoid SetVisible(bool s);\n\n\tvoid GetCaption(ttstr & v) const;\n\tvoid SetCaption(const ttstr & v);\n\n\tvoid SetWidth(tjs_int w);\n\ttjs_int GetWidth() const;\n\tvoid SetHeight(tjs_int h);\n\ttjs_int GetHeight() const;\n\tvoid SetSize(tjs_int w, tjs_int h);\n\n\tvoid SetMinWidth(int v);\n\tint GetMinWidth() const;\n\tvoid SetMinHeight(int v);\n\tint GetMinHeight() const;\n\tvoid SetMinSize(int w, int h);\n\n\tvoid SetMaxWidth(int v);\n\tint GetMaxWidth() const;\n\tvoid SetMaxHeight(int v);\n\tint GetMaxHeight() const;\n\tvoid SetMaxSize(int w, int h);\n\n\tvoid SetLeft(tjs_int l);\n\ttjs_int GetLeft() const;\n\tvoid SetTop(tjs_int t);\n\ttjs_int GetTop() const;\n\tvoid SetPosition(tjs_int l, tjs_int t);\n\n#ifdef USE_OBSOLETE_FUNCTIONS\n\tvoid SetLayerLeft(tjs_int l);\n\ttjs_int GetLayerLeft() const;\n\tvoid SetLayerTop(tjs_int t);\n\ttjs_int GetLayerTop() const;\n\tvoid SetLayerPosition(tjs_int l, tjs_int t);\n\n\tvoid SetInnerSunken(bool b);\n\tbool GetInnerSunken() const;\n#endif\n\n\tvoid SetInnerWidth(tjs_int w);\n\ttjs_int GetInnerWidth() const;\n\tvoid SetInnerHeight(tjs_int h);\n\ttjs_int GetInnerHeight() const;\n\n\tvoid SetInnerSize(tjs_int w, tjs_int h);\n\n\tvoid SetBorderStyle(tTVPBorderStyle st);\n\ttTVPBorderStyle GetBorderStyle() const;\n\n\tvoid SetStayOnTop(bool b);\n\tbool GetStayOnTop() const;\n\n#ifdef USE_OBSOLETE_FUNCTIONS\n\tvoid SetShowScrollBars(bool b);\n\tbool GetShowScrollBars() const;\n#endif\n\n\tvoid SetFullScreen(bool b);\n\tbool GetFullScreen() const;\n\n\tvoid SetUseMouseKey(bool b);\n\tbool GetUseMouseKey() const;\n\n\tvoid SetTrapKey(bool b);\n\tbool GetTrapKey() const;\n\n\tvoid SetMaskRegion(tjs_int threshold);\n\tvoid RemoveMaskRegion();\n\n\tvoid SetMouseCursorState(tTVPMouseCursorState mcs);\n    tTVPMouseCursorState GetMouseCursorState() const;\n\n\tvoid SetFocusable(bool b);\n\tbool GetFocusable();\n\n\tvoid SetZoom(tjs_int numer, tjs_int denom);\n\tvoid SetZoomNumer(tjs_int n);\n\ttjs_int GetZoomNumer() const;\n\tvoid SetZoomDenom(tjs_int n);\n\ttjs_int GetZoomDenom() const;\n\t\n\tvoid SetTouchScaleThreshold( tjs_real threshold );\n\ttjs_real GetTouchScaleThreshold() const;\n\tvoid SetTouchRotateThreshold( tjs_real threshold );\n\ttjs_real GetTouchRotateThreshold() const;\n\n\ttjs_real GetTouchPointStartX( tjs_int index );\n\ttjs_real GetTouchPointStartY( tjs_int index );\n\ttjs_real GetTouchPointX( tjs_int index );\n\ttjs_real GetTouchPointY( tjs_int index );\n\ttjs_real GetTouchPointID( tjs_int index );\n\ttjs_int GetTouchPointCount();\n\tbool GetTouchVelocity( tjs_int id, float& x, float& y, float& speed ) const;\n\tbool GetMouseVelocity( float& x, float& y, float& speed ) const;\n\tvoid ResetMouseVelocity();\n\t\n\tvoid SetHintDelay( tjs_int delay );\n\ttjs_int GetHintDelay() const;\n\n\tvoid SetEnableTouch( bool b );\n\tbool GetEnableTouch() const;\n\n\tint GetDisplayOrientation();\n\tint GetDisplayRotate();\n\t\n\tbool WaitForVBlank( tjs_int* in_vblank, tjs_int* delayed );\n\n\tvoid OnTouchUp( tjs_real x, tjs_real y, tjs_real cx, tjs_real cy, tjs_uint32 id );\npublic: // for iTVPLayerTreeOwner\n\t// LayerManager -> LTO\n\t/*\n\timplements on tTJSNI_BaseWindow\n\tvirtual void TJS_INTF_METHOD RegisterLayerManager( class iTVPLayerManager* manager );\n\tvirtual void TJS_INTF_METHOD UnregisterLayerManager( class iTVPLayerManager* manager );\n\t*/\n\n\tvirtual void TJS_INTF_METHOD StartBitmapCompletion(iTVPLayerManager * manager);\n\tvirtual void TJS_INTF_METHOD NotifyBitmapCompleted(class iTVPLayerManager * manager,\n\t\ttjs_int x, tjs_int y, tTVPBaseTexture * bmp,\n\t\tconst tTVPRect &cliprect, tTVPLayerType type, tjs_int opacity);\n\tvirtual void TJS_INTF_METHOD EndBitmapCompletion(iTVPLayerManager * manager);\n\n\tvirtual void TJS_INTF_METHOD SetMouseCursor(class iTVPLayerManager* manager, tjs_int cursor);\n\tvirtual void TJS_INTF_METHOD GetCursorPos(class iTVPLayerManager* manager, tjs_int &x, tjs_int &y);\n\tvirtual void TJS_INTF_METHOD SetCursorPos(class iTVPLayerManager* manager, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD ReleaseMouseCapture(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetHint(class iTVPLayerManager* manager, iTJSDispatch2* sender, const ttstr &hint);\n\n\tvirtual void TJS_INTF_METHOD NotifyLayerResize(class iTVPLayerManager* manager);\n\tvirtual void TJS_INTF_METHOD NotifyLayerImageChange(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetAttentionPoint(class iTVPLayerManager* manager, tTJSNI_BaseLayer *layer, tjs_int x, tjs_int y);\n\tvirtual void TJS_INTF_METHOD DisableAttentionPoint(class iTVPLayerManager* manager);\n\n\tvirtual void TJS_INTF_METHOD SetImeMode( class iTVPLayerManager* manager, tjs_int mode ); // mode == tTVPImeMode\n\tvirtual void TJS_INTF_METHOD ResetImeMode( class iTVPLayerManager* manager );\n\nprotected:\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#endif\n"
  },
  {
    "path": "src/core/visual/win32/krmovie.h",
    "content": "//---------------------------------------------------------------------------\n/*\n\tTVP2 ( T Visual Presenter 2 )  A script authoring tool\n\tCopyright (C) 2000 W.Dee <dee@kikyou.info> and contributors\n\n\tSee details of license at \"license.txt\"\n*/\n//---------------------------------------------------------------------------\n// krmovie.dll ( kirikiri movie playback support DLL ) interface\n//---------------------------------------------------------------------------\n\n\n#ifndef __KRMOVIE_H__\n#define __KRMOVIE_H__\n\n//#include \"typedefine.h\"\n\n//---------------------------------------------------------------------------\nenum tTVPVideoStatus { vsStopped, vsPlaying, vsPaused, vsProcessing, vsEnded, vsReady };\n//---------------------------------------------------------------------------\n#define __stdcall\nclass tTVPBaseTexture;\n//---------------------------------------------------------------------------\n// iTVPVideoOverlay\n//---------------------------------------------------------------------------\nclass iTVPVideoOverlay // this is not a COM object\n{\npublic:\n\tvirtual void __stdcall AddRef() = 0;\n\tvirtual void __stdcall Release() = 0;\n\n\tvirtual void __stdcall SetWindow(class tTJSNI_Window* window) = 0;\n\tvirtual void __stdcall SetMessageDrainWindow(void* window) = 0;\n\tvirtual void __stdcall SetRect(int l, int t, int r, int b) = 0;\n\tvirtual void __stdcall SetVisible(bool b) = 0;\n\tvirtual void __stdcall Play() = 0;\n\tvirtual void __stdcall Stop() = 0;\n\tvirtual void __stdcall Pause() = 0;\n\tvirtual void __stdcall SetPosition(uint64_t tick) = 0;\n\tvirtual void __stdcall GetPosition(uint64_t *tick) = 0;\n\tvirtual void __stdcall GetStatus(tTVPVideoStatus *status) = 0;\n// \tvirtual void __stdcall GetEvent(long *evcode, LONG_PTR *param1,\n// \t\t\tLONG_PTR *param2, bool *got) = 0;\n\n//\tvirtual void __stdcall FreeEventParams(long evcode, LONG_PTR param1, LONG_PTR param2) = 0;\n\n\tvirtual void __stdcall Rewind() = 0;\n\tvirtual void __stdcall SetFrame( int f ) = 0;\n\tvirtual void __stdcall GetFrame( int *f ) = 0;\n\tvirtual void __stdcall GetFPS( double *f ) = 0;\n\tvirtual void __stdcall GetNumberOfFrame( int *f ) = 0;\n\tvirtual void __stdcall GetTotalTime(int64_t *t) = 0;\n\t\n\tvirtual void __stdcall GetVideoSize( long *width, long *height ) = 0;\n\tvirtual tTVPBaseTexture* GetFrontBuffer() = 0;\n\tvirtual void __stdcall SetVideoBuffer(tTVPBaseTexture *buff1, tTVPBaseTexture *buff2, long size) = 0;\n\n\tvirtual void __stdcall SetStopFrame( int frame ) = 0;\n\tvirtual void __stdcall GetStopFrame( int *frame ) = 0;\n\tvirtual void __stdcall SetDefaultStopFrame() = 0;\n\n\tvirtual void __stdcall SetPlayRate( double rate ) = 0;\n\tvirtual void __stdcall GetPlayRate( double *rate ) = 0;\n\n\tvirtual void __stdcall SetAudioBalance( long balance ) = 0;\n\tvirtual void __stdcall GetAudioBalance( long *balance ) = 0;\n\tvirtual void __stdcall SetAudioVolume( long volume ) = 0;\n\tvirtual void __stdcall GetAudioVolume( long *volume ) = 0;\n\n\tvirtual void __stdcall GetNumberOfAudioStream( unsigned long *streamCount ) = 0;\n\tvirtual void __stdcall SelectAudioStream( unsigned long num ) = 0;\n\tvirtual void __stdcall GetEnableAudioStreamNum( long *num ) = 0;\n\tvirtual void __stdcall DisableAudioStream( void ) = 0;\n\n\tvirtual void __stdcall GetNumberOfVideoStream( unsigned long *streamCount ) = 0;\n\tvirtual void __stdcall SelectVideoStream( unsigned long num ) = 0;\n\tvirtual void __stdcall GetEnableVideoStreamNum( long *num ) = 0;\n\n\tvirtual void __stdcall SetMixingBitmap(class tTVPBaseTexture *dest, float alpha) = 0;\n\tvirtual void __stdcall ResetMixingBitmap() = 0;\n\n\tvirtual void __stdcall SetMixingMovieAlpha( float a ) = 0;\n\tvirtual void __stdcall GetMixingMovieAlpha( float *a ) = 0;\n\tvirtual void __stdcall SetMixingMovieBGColor( unsigned long col ) = 0;\n\tvirtual void __stdcall GetMixingMovieBGColor( unsigned long *col ) = 0;\n\n\tvirtual void __stdcall PresentVideoImage() = 0;\n\n\tvirtual void __stdcall GetContrastRangeMin( float *v ) = 0;\n\tvirtual void __stdcall GetContrastRangeMax( float *v ) = 0;\n\tvirtual void __stdcall GetContrastDefaultValue( float *v ) = 0;\n\tvirtual void __stdcall GetContrastStepSize( float *v ) = 0;\n\tvirtual void __stdcall GetContrast( float *v ) = 0;\n\tvirtual void __stdcall SetContrast( float v ) = 0;\n\n\tvirtual void __stdcall GetBrightnessRangeMin( float *v ) = 0;\n\tvirtual void __stdcall GetBrightnessRangeMax( float *v ) = 0;\n\tvirtual void __stdcall GetBrightnessDefaultValue( float *v ) = 0;\n\tvirtual void __stdcall GetBrightnessStepSize( float *v ) = 0;\n\tvirtual void __stdcall GetBrightness( float *v ) = 0;\n\tvirtual void __stdcall SetBrightness( float v ) = 0;\n\n\tvirtual void __stdcall GetHueRangeMin( float *v ) = 0;\n\tvirtual void __stdcall GetHueRangeMax( float *v ) = 0;\n\tvirtual void __stdcall GetHueDefaultValue( float *v ) = 0;\n\tvirtual void __stdcall GetHueStepSize( float *v ) = 0;\n\tvirtual void __stdcall GetHue( float *v ) = 0;\n\tvirtual void __stdcall SetHue( float v ) = 0;\n\n\tvirtual void __stdcall GetSaturationRangeMin( float *v ) = 0;\n\tvirtual void __stdcall GetSaturationRangeMax( float *v ) = 0;\n\tvirtual void __stdcall GetSaturationDefaultValue( float *v ) = 0;\n\tvirtual void __stdcall GetSaturationStepSize( float *v ) = 0;\n\tvirtual void __stdcall GetSaturation( float *v ) = 0;\n\tvirtual void __stdcall SetSaturation( float v ) = 0;\n\n\t// extended features\n\tvirtual void SetLoopSegement(int beginFrame, int endFrame) = 0;\n};\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\n#define WM_GRAPHNOTIFY  (/*WM_USER+*/15)\n#define WM_CALLBACKCMD  (/*WM_USER+*/16)\n#define EC_UPDATE\t\t(/*EC_USER*/0x8000+1)\n#define WM_STATE_CHANGE\t(/*WM_USER+*/18)\n\n#ifndef EC_COMPLETE\n#define EC_COMPLETE                         0x01\n#endif\n//---------------------------------------------------------------------------\n\n#undef __stdcall\n#endif\n\n\n"
  },
  {
    "path": "src/plugins/Android.mk",
    "content": "LOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := kr2plugin\n\nLOCAL_SRC_FILES := \\\n$(wildcard $(LOCAL_PATH)/*.cpp) \\\n$(wildcard $(LOCAL_PATH)/*.c) \\\nncbind/ncbind.cpp \\\n\nLOCAL_SRC_FILES := $(LOCAL_SRC_FILES:$(LOCAL_PATH)/%=%)\n\nLOCAL_C_INCLUDES += \\\n$(LOCAL_PATH) \\\n$(LOCAL_PATH)/ncbind \\\n$(LOCAL_PATH)/../../vendor/freetype/current/include \\\n$(LOCAL_PATH)/../core \\\n$(LOCAL_PATH)/../core/base  \\\n$(LOCAL_PATH)/../core/base/win32 \\\n$(LOCAL_PATH)/../core/environ \\\n$(LOCAL_PATH)/../core/environ/sdl \\\n$(LOCAL_PATH)/../core/msg \\\n$(LOCAL_PATH)/../core/msg/win32 \\\n$(LOCAL_PATH)/../core/sound \\\n$(LOCAL_PATH)/../core/sound/win32 \\\n$(LOCAL_PATH)/../core/tjs2 \\\n$(LOCAL_PATH)/../core/utils \\\n$(LOCAL_PATH)/../core/utils/win32 \\\n$(LOCAL_PATH)/../core/visual \\\n$(LOCAL_PATH)/../core/visual/ARM \\\n$(LOCAL_PATH)/../core/visual/win32 \\\n$(LOCAL_PATH)/../plugins \\\n$(LOCAL_PATH)/../../vendor/boost/current \\\n$(LOCAL_PATH)/../../vendor/libiconv/current/include \\\n$(LOCAL_PATH)/../../vendor/libgdiplus/src \\\n$(LOCAL_PATH)/../../vendor/agg/current/include \\\n$(LOCAL_PATH)/../../vendor/expat/current/lib \\\n$(LOCAL_PATH)/../../vendor/openal/current/include \\\n$(LOCAL_PATH)/../../libs/android/ffmpeg/include \\\n    $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/jpeg/include/android \\\n\t\t\t\t \n#LOCAL_LDLIBS := -lGLESv1_CM -lz -llog\nLOCAL_CPPFLAGS := -fexceptions -std=c++11 -D__STDC_CONSTANT_MACROS -DTJS_TEXT_OUT_CRLF -fvisibility=hidden\nLOCAL_CFLAGS += -DTJS_TEXT_OUT_CRLF\nLOCAL_STATIC_LIBRARIES := cpufeatures\n\ninclude $(BUILD_STATIC_LIBRARY)\n$(call import-module,android/cpufeatures)\n"
  },
  {
    "path": "src/plugins/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.6)\r\nproject(krkr2plugin)\r\nset(KRKR2PLUGIN_PATH ${CMAKE_CURRENT_SOURCE_DIR})\r\nset(KRKR2CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../core)\r\n\r\n# search kr2plugin src\r\nfile(GLOB KR2KR2PLUGIN_CODE\r\n    ${KRKR2PLUGIN_PATH}/*.c\r\n    ${KRKR2PLUGIN_PATH}/*.cpp\r\n)\r\nlist(APPEND KR2KR2PLUGIN_CODE ${KRKR2PLUGIN_PATH}/ncbind/ncbind.cpp)\r\n\r\n# make krkr2plugin\r\nadd_library(${PROJECT_NAME} STATIC ${KR2KR2PLUGIN_CODE})\r\ntarget_include_directories(${PROJECT_NAME} PUBLIC\r\n    ${KRKR2PLUGIN_PATH}\r\n    ${KRKR2PLUGIN_PATH}/ncbind\r\n\r\n    ${KRKR2CORE_PATH}\r\n    ${KRKR2CORE_PATH}/tjs2\r\n    ${KRKR2CORE_PATH}/environ\r\n    ${KRKR2CORE_PATH}/msg\r\n    ${KRKR2CORE_PATH}/msg/win32\r\n    ${KRKR2CORE_PATH}/utils\r\n    ${KRKR2CORE_PATH}/utils/win32\r\n    ${KRKR2CORE_PATH}/base\r\n    ${KRKR2CORE_PATH}/base/win32\r\n    ${KRKR2CORE_PATH}/sound\r\n    ${KRKR2CORE_PATH}/sound/win32\r\n    ${KRKR2CORE_PATH}/visual\r\n    ${KRKR2CORE_PATH}/visual/win32\r\n\r\n    ${PORTBUILD_PATH}/include\r\n)\r\ntarget_compile_options(${PROJECT_NAME} PUBLIC \r\n    -fPIC -fexceptions -std=c++14 -fvisibility=hidden\r\n)\r\n\r\ntarget_compile_definitions(${PROJECT_NAME} PUBLIC\r\n    -D__STDC_CONSTANT_MACROS -DTJS_TEXT_OUT_CRLF \r\n    -DTJS_TEXT_OUT_CRLF\r\n)"
  },
  {
    "path": "src/plugins/InternalPlugins.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n//extern void InitPlugin_CSVParser();\n\nvoid TVPLoadInternalPlugins()\n{\n    ncbAutoRegister::AllRegist();\n\tncbAutoRegister::LoadModule(TJS_W(\"xp3filter.dll\"));\n    //InitPlugin_CSVParser();\n}\n\nvoid TVPUnloadInternalPlugins()\n{\n    ncbAutoRegister::AllUnregist();\n}\n\nbool TVPLoadInternalPlugin(const ttstr &_name)\n{\n\treturn ncbAutoRegister::LoadModule(TVPExtractStorageName(_name));\n}"
  },
  {
    "path": "src/plugins/LayerExBase.cpp",
    "content": "﻿#include \"LayerExBase.h\"\n#include \"MsgIntf.h\"\n#include \"SysInitIntf.h\"\n\nint NI_LayerExBase::classId;\n\niTJSDispatch2 * NI_LayerExBase::_leftProp   = NULL;\niTJSDispatch2 * NI_LayerExBase::_topProp    = NULL;\niTJSDispatch2 * NI_LayerExBase::_widthProp  = NULL;\niTJSDispatch2 * NI_LayerExBase::_heightProp = NULL;\niTJSDispatch2 * NI_LayerExBase::_pitchProp  = NULL;\niTJSDispatch2 * NI_LayerExBase::_bufferProp = NULL;\niTJSDispatch2 * NI_LayerExBase::_updateProp = NULL;\n\nvoid\nNI_LayerExBase::init(iTJSDispatch2 *layerobj)\n{\n\tstatic bool inited = false;\n\tif (inited) return;\n\tinited = true;\n\n\t// プロパティ取得\n\ttTJSVariant var;\n\t\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"imageLeft\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.imageLeft failed.\"));\n\t} else {\n\t\t_leftProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"imageTop\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.imageTop failed.\"));\n\t} else {\n\t\t_topProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"imageWidth\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.imageWidth failed.\"));\n\t} else {\n\t\t_widthProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"imageHeight\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.imageHeight failed.\"));\n\t} else {\n\t\t_heightProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"mainImageBufferForWrite\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.mainImageBufferForWrite failed.\"));\n\t} else {\n\t\t_bufferProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"mainImageBufferPitch\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.mainImageBufferPitch failed.\"));\n\t} else {\n\t\t_pitchProp = var;\n\t}\n\tif (TJS_FAILED(layerobj->PropGet(TJS_IGNOREPROP, TJS_W(\"update\"), NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"invoking of Layer.update failed.\"));\n\t} else {\n\t\t_updateProp = var;\n\t}\n}\n\nvoid\nNI_LayerExBase::unInit()\n{\n\tif (_leftProp)   _leftProp->Release();\n\tif (_topProp)    _topProp->Release();\n\tif (_widthProp)  _widthProp->Release();\n\tif (_heightProp) _heightProp->Release();\n\tif (_bufferProp) _bufferProp->Release();\n\tif (_pitchProp)  _pitchProp->Release();\n\tif (_updateProp) _updateProp->Release();\n}\n\ntTVPAtExit _NI_LayerExBase_unInit(TVP_ATEXIT_PRI_PREPARE, NI_LayerExBase::unInit);\n\n/// プロパティから int 値を取得する\nstatic tjs_int64 getPropValue(iTJSDispatch2 *dispatch, iTJSDispatch2 *layerobj)\n{\n\ttTJSVariant var;\n\tif(TJS_FAILED(dispatch->PropGet(0, NULL, NULL, &var, layerobj))) {\n\t\tTVPThrowExceptionMessage(TJS_W(\"can't get int value from property.\"));\n\t}\n\treturn var;\n}\n\t\nvoid\nNI_LayerExBase::reset(iTJSDispatch2 *layerobj)\n{\n\t_width  = (int)getPropValue(_widthProp, layerobj);\n\t_height = (int)getPropValue(_heightProp, layerobj);\n\t_buffer = (unsigned char *)getPropValue(_bufferProp, layerobj);\n\t_pitch  = (int)getPropValue(_pitchProp, layerobj);\n}\n\n/**\n * 更新処理呼び出し\n * layer.update(x,y,w,h) を呼び出す\n * 画像領域全体を更新とする\n */\nvoid\nNI_LayerExBase::redraw(iTJSDispatch2 *layerobj)\n{\n\ttTJSVariant vars[4];\n\t_leftProp->PropGet(0,NULL,NULL,&vars[0], layerobj);\n\t_topProp->PropGet(0,NULL,NULL,&vars[1], layerobj);\n\t_widthProp->PropGet(0,NULL,NULL,&vars[2], layerobj);\n\t_heightProp->PropGet(0,NULL,NULL,&vars[3], layerobj);\n\ttTJSVariant *varsp[4] = {vars, vars+1, vars+2, vars+3};\n\t_updateProp->FuncCall(0, NULL, NULL, NULL, 4, varsp, layerobj);\n}\n\nNI_LayerExBase *\nNI_LayerExBase::getNative(iTJSDispatch2 *objthis, bool create)\n{\n\tNI_LayerExBase *_this = NULL;\n\tif (TJS_FAILED(objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n\t\t\t\t\t\t\t\t\t\t\t\t  classId, (iTJSNativeInstance**)&_this)) && create) {\n\t\t_this = new NI_LayerExBase();\n\t\tif (TJS_FAILED(objthis->NativeInstanceSupport(TJS_NIS_REGISTER,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  classId, (iTJSNativeInstance **)&_this))) {\n\t\t\tdelete _this;\n\t\t\t_this = NULL;\n\t\t}\n\t}\n\treturn _this;\n}\n\t\n/**\n * コンストラクタ\n */\nNI_LayerExBase::NI_LayerExBase()\n{\n\t_width = 0;\n\t_height = 0;\n\t_pitch = 0;\n\t_buffer = NULL;\n}\n"
  },
  {
    "path": "src/plugins/LayerExBase.h",
    "content": "﻿#ifndef __LayerExBase__\n#define __LayerExBase__\n\n//#include <windows.h>\n//#include \"tp_stub.h\"\n#include \"tjsNative.h\"\n\n/**\n * レイヤ拡張 基本情報保持用ネイティブインスタンス。\n */\nclass NI_LayerExBase : public tTJSNativeInstance\n{\nprotected:\n\t// レイヤから情報を取得するためのプロパティ\n\t// 少しでも高速化するためキャッシュしておく\n\tstatic iTJSDispatch2 * _leftProp;\n\tstatic iTJSDispatch2 * _topProp;\n\tstatic iTJSDispatch2 * _widthProp;\n\tstatic iTJSDispatch2 * _heightProp;\n\tstatic iTJSDispatch2 * _pitchProp;\n\tstatic iTJSDispatch2 * _bufferProp;\n\tstatic iTJSDispatch2 * _updateProp;\n\npublic:\n\t// レイヤ情報比較保持用\n\ttjs_int _width;\n\ttjs_int _height;\n\ttjs_int _pitch;\n\tunsigned char *_buffer;\n\npublic:\n\t// クラスＩＤ保持用\n\tstatic int classId;\n\tstatic void init(iTJSDispatch2 *layerobj);\n\tstatic void unInit();\n\t\n\t/**\n\t * ネイティブオブジェクトの取得\n\t * @param layerobj レイヤオブジェクト\n\t * @return ネイティブオブジェクト\n\t */\n\tstatic NI_LayerExBase *getNative(iTJSDispatch2 *objthis, bool create=true);\n\n\t/**\n\t * 再描画要請\n\t * @param layerobj レイヤオブジェクト\n\t */\n\tvoid redraw(iTJSDispatch2 *layerobj);\n\t\n\t/**\n\t * グラフィックを初期化する\n\t * レイヤのビットマップ情報が変更されている可能性があるので毎回チェックする。\n\t * 変更されている場合は描画用のコンテキストを組みなおす\n\t * @param layerobj レイヤオブジェクト\n\t * @return 初期化実行された場合は true を返す\n\t */\n\tvoid reset(iTJSDispatch2 *layerobj);\n\t\npublic:\n\t/**\n\t * コンストラクタ\n\t */\n\tNI_LayerExBase();\n};\n\n#endif\n"
  },
  {
    "path": "src/plugins/PluginStub.h",
    "content": "#pragma once\n//#define __TP_STUB_H__\n#include \"tjsCommHead.h\"\n#include \"StorageImpl.h\"\n#include \"tjsNative.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"DebugIntf.h\"\n#include \"TextStream.h\"\n#include \"MsgIntf.h\"\n//#include \"PluginImpl.h\"\n#include \"CharacterSet.h\"\n"
  },
  {
    "path": "src/plugins/addFont.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n\n#include <vector>\n#include \"FontImpl.h\"\nusing namespace std;\n\n#define NCB_MODULE_NAME TJS_W(\"addFont.dll\")\n\nstruct FontEx\n{\n\t/**\n\t * プライベートフォントの追加\n\t * @param fontFileName フォントファイル名\n\t * @param extract アーカイブからテンポラリ展開する\n\t * @return void:ファイルを開くのに失敗 0:フォント登録に失敗 数値:登録したフォントの数\n\t */\n\tstatic tjs_error TJS_INTF_METHOD addFont(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t\t tjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t\t tTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t\t iTJSDispatch2 *objthis) {\n\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t\tttstr filename = TVPGetPlacedPath(*param[0]);\n\t\tif (filename.length()) {\n\t\t\tint ret = TVPEnumFontsProc(filename);\n\t\t\tif (result) {\n\t\t\t\t*result = (int)ret;\n\t\t\t}\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n};\n\n// フックつきアタッチ\nNCB_ATTACH_CLASS(FontEx, System) {\n\tRawCallback(\"addFont\", &FontEx::addFont, TJS_STATICMEMBER);\n}\n"
  },
  {
    "path": "src/plugins/csvParser.cpp",
    "content": "#include \"PluginStub.h\"\n#include <string>\n#include \"ncbind/ncbind.hpp\"\n\n#define NCB_MODULE_NAME TJS_W(\"csvParser.dll\")\nusing namespace std;\n\n//---------------------------------------------------------------------------\n\n// Array NXo\nstatic iTJSDispatch2 *ArrayClearMethod   = NULL;   // Array.clear\n\n// -----------------------------------------------------------------\n\nclass IFile {\npublic:\n\tvirtual ~IFile() {};\n\tvirtual bool addNextLine(ttstr &str) = 0;\n};\n\nclass IFileStr : public IFile {\n\n\tttstr dat;\n\tuint32_t pos;\n\npublic:\n\tIFileStr(const ttstr &str) {\n\t\tdat = str;\n\t\tpos = 0;\n\t}\n\n\tint getc() {\n\t\treturn pos < (uint32_t)dat.length() ? dat[pos++] : EOF;\n\t}\n\n\tvoid ungetc() {\n\t\tif (pos > 0) {\n\t\t\tpos--;\n\t\t}\n\t}\n\n\tbool eof() {\n\t\treturn pos >= (uint32_t)dat.length();\n\t}\n\n\t/**\n\t * s`FbN\n\t */\n\tbool endOfLine(tjs_char c) {\n\t\tbool eol = (c =='\\r' || c == '\\n');\n\t\tif (c == '\\r'){\n\t\t\tc = getc();\n\t\t\tif (!eof() && c != '\\n') {\n\t\t\t\tungetc();\n\t\t\t}\n\t\t}\n\t\treturn eol;\n\t}\n\n\tbool addNextLine(ttstr &str) {\n\t\tint l = 0;\n\t\tint c;\n\t\twhile ((c = getc()) != EOF && !endOfLine(c)) {\n\t\t\tstr += c;\n\t\t\tl++;\n\t\t}\n\t\tif (l > 0 || c != EOF) {\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n// -----------------------------------------------------------------\n\nstatic void\naddMember(iTJSDispatch2 *dispatch, const tjs_char *name, iTJSDispatch2 *member)\n{\n\ttTJSVariant var (member);\n\tmember->Release();\n\tdispatch->PropSet(\n\t\tTJS_MEMBERENSURE, // oȂꍇɂ͍쐬悤ɂtO\n\t\tname, // o ( Ȃ炸 TJS_W( ) ň͂ )\n\t\tNULL, // qg ( {̓õnbVlANULL ł悢 )\n\t\t&var, // o^l\n\t\tdispatch // ReLXg\n\t\t);\n}\n\nstatic iTJSDispatch2*\ngetMember(iTJSDispatch2 *dispatch, const tjs_char *name)\n{\n\ttTJSVariant val;\n\tif (TJS_FAILED(dispatch->PropGet(TJS_IGNOREPROP,\n\t\t\t\t\t\t\t\t\t name,\n\t\t\t\t\t\t\t\t\t NULL,\n\t\t\t\t\t\t\t\t\t &val,\n\t\t\t\t\t\t\t\t\t dispatch))) {\n\t\tttstr msg = TJS_W(\"can't get member:\");\n\t\tmsg += name;\n\t\tTVPThrowExceptionMessage(msg.c_str());\n\t}\n\treturn val.AsObject();\n}\n\nstatic bool\nisValidMember(iTJSDispatch2 *dispatch, const tjs_char *name)\n{\n\treturn dispatch->IsValid(TJS_IGNOREPROP,\n\t\t\t\t\t\t\t name,\n\t\t\t\t\t\t\t NULL,\n\t\t\t\t\t\t\t dispatch) == TJS_S_TRUE;\n}\n\nstatic void\ndelMember(iTJSDispatch2 *dispatch, const tjs_char *name)\n{\n\tdispatch->DeleteMember(\n\t\t0, // tO ( 0 ł悢 )\n\t\tname, // o\n\t\tNULL, // qg\n\t\tdispatch // ReLXg\n\t\t);\n}\n//---------------------------------------------------------------------------\n\n#ifdef TJS_NATIVE_CLASSID_NAME\n#undef TJS_NATIVE_CLASSID_NAME\n#undef TJS_NCM_REG_THIS\n#undef TJS_NATIVE_SET_ClassID\n#endif\n#define TJS_NCM_REG_THIS classobj\n#define TJS_NATIVE_SET_ClassID TJS_NATIVE_CLASSID_NAME = TJS_NCM_CLASSID;\n#define TJS_NATIVE_CLASSID_NAME ClassID_CSVParser\nstatic tjs_int32 TJS_NATIVE_CLASSID_NAME = -1;\n\n/**\n * CSVParser\n */\nclass NI_CSVParser : public tTJSNativeInstance // lCeBuCX^X\n{\nprotected:\n\tiTJSDispatch2 *target;\n\tIFile *file;\n\ttjs_int32 lineNo;\n\n\t// ؂蕶\n\ttjs_char separator;\n\n\t// s\n\tttstr newline;\n\t\n\t// s(ChLŏ)\n\tttstr line;\n\t\n\tbool addline() {\n\t\treturn file->addNextLine(line);\n\t}\n\t\n\t// \n\tint find(ttstr &line, tjs_char ch, int start) {\n\t\tint i;\n\t\tfor (i=start; i < line.length(); i++) {\n\t\t\tif (ch == line[i]) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn i;\n\t}\n\n\t// \n\tvoid split(iTJSDispatch2 *fields) {\n\n\t\tttstr fld;\n\t\tint i, j;\n\t\ttjs_int cnt = 0;\n\t\n\t\tif (line.length() == 0) {\n\t\t\treturn;\n\t\t}\n\t\ti = 0;\n\t\tdo {\n\t\t\tif (i < line.length() && line[i] == '\"') {\n\t\t\t\t++i;\n\t\t\t\tfld = TJS_W(\"\");\n\t\t\t\tj = i;\n\t\t\t\tdo {\n\t\t\t\t\tfor (;j < line.length(); j++){\n\t\t\t\t\t\tif (line[j] == '\"' && line[++j] != '\"'){\n\t\t\t\t\t\t\tint k = find(line, separator, j);\n\t\t\t\t\t\t\tif (k > line.length()) {\n\t\t\t\t\t\t\t\tk = line.length();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (k -= j; k-- > 0;)\n\t\t\t\t\t\t\t\tfld += line[j++];\n\t\t\t\t\t\t\tgoto next;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfld += line[j];\n\t\t\t\t\t}\n\t\t\t\t\t// sǉ\n\t\t\t\t\tfld += newline;\n\t\t\t\t} while (addline());\n\t\t\t} else {\n\t\t\t\tj = find(line, separator, i);\n\t\t\t\tif (j > line.length()) {\n\t\t\t\t\tj = line.length();\n\t\t\t\t}\n\t\t\t\tfld = ttstr(line.c_str() + i, j-i);\n\t\t\t}\n\t\tnext:\n\t\t\t{\n\t\t\t\t// o^\n\t\t\t\ttTJSVariant var(fld);\n\t\t\t\tfields->PropSetByNum(TJS_MEMBERENSURE, cnt++, &var, fields);\n\t\t\t}\n\t\t\ti = j + 1;\n\t\t} while (j < line.length());\n\t}\n\t\npublic:\n\n\t/**\n\t * RXgN^\n\t */\n\tNI_CSVParser() {\n\t\ttarget = NULL;\n\t\tfile = NULL;\n\t\tlineNo = 0;\n\t\tseparator = ',';\n\t\tnewline = TJS_W(\"\\r\\n\");\n\t}\n\n\t~NI_CSVParser() {\n\t\tclear();\n\t}\n\n\t/**\n\t * TJS RXgN^\n\t * @param numparams p[^\n\t * @param param\n\t * @param tjs_obj this IuWFNg\n\t */\n\ttjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj) {\n\t\tif (numparams > 0) {\n\t\t\ttarget = param[0]->AsObject();\n\t\t\tif (numparams > 1) {\n\t\t\t\tseparator = (tjs_int)*param[1];\n\t\t\t\tif (numparams > 2) {\n\t\t\t\t\tnewline = *param[2];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\n\t/**\n\t * t@CN[Y\n\t */\n\tvoid clear() {\n\t\tif (file) {\n\t\t\tdelete file;\n\t\t\tfile = NULL;\n\t\t}\n\t}\n\t\n\t/**\n\t * TJS invalidate\n\t */\n\tvoid TJS_INTF_METHOD Invalidate() {\n\t\tclear();\n\t\tif (target) {\n\t\t\ttarget->Release();\n\t\t\ttarget = NULL;\n\t\t}\n\t}\n\n\t/**\n\t * p[T̏\n\t */\n\tvoid init(tTJSVariantString *text) {\n\t\tclear();\n\t\tfile = new IFileStr(text);\n\t\tlineNo = 0;\n\t}\n\n\t/**\n\t * \n\t */\n\tvoid initStorage(tTJSVariantString *filename, bool utf8=false) {\n\t\tclear();\n\t\tttstr text;\n\t\tif (utf8) {\n\t\t\ttTJSBinaryStream* pStream = TVPCreateStream(filename, TJS_BS_READ);\n\t\t\ttjs_uint streamsize = pStream->GetSize();\n\t\t\tchar *buff = new char[streamsize + 1];\n\t\t\tbuff[streamsize] = 0;\n\t\t\tpStream->ReadBuffer(buff, streamsize);\n\t\t\ttext = buff;\n\t\t\tdelete []buff;\n\t\t\tdelete pStream;\n\t\t} else {\n\t\t\tiTJSTextReadStream *pStream = TVPCreateTextStreamForRead(filename, TJS_W(\"\"));\n\t\t\tpStream->Read(text, 0);\n\t\t\tdelete pStream;\n\t\t}\n\t\tfile = new IFileStr(text);\n\t\tlineNo = 0;\n\t}\n\n\n\t// 1sǂݏo\n\tbool getNextLine(tTJSVariant *result = NULL) {\n\t\tbool ret = false;\n\t\tif (file) {\n\t\t\tline = TJS_W(\"\");\n\t\t\tif (addline()) {\n\t\t\t\tlineNo++;\n\t\t\t\tiTJSDispatch2 *fields = TJSCreateArrayObject();\n\t\t\t\tsplit(fields);\n\t\t\t\tif (result) {\n\t\t\t\t\tresult->SetObject(fields,fields);\n\t\t\t\t}\n\t\t\t\tfields->Release();\n\t\t\t\tret = true;\n\t\t\t} else {\n\t\t\t\tclear();\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t}\n\t\n\t/**\n\t * ݂̍sԍ̎擾\n\t * @return sԍ\n\t */\n\ttjs_int32 getLineNumber() {\n\t\treturn lineNo;\n\t}\n\t\n\t/**\n\t * p[X̎s\n\t */\n\tvoid parse(iTJSDispatch2 *objthis) {\n\t\tiTJSDispatch2 *target = this->target ? this->target : objthis;\n\t\tif (file && isValidMember(target, TJS_W(\"doLine\"))) {\n\t\t\tiTJSDispatch2 *method = getMember(target, TJS_W(\"doLine\"));\n\t\t\ttTJSVariant result;\n\t\t\twhile (getNextLine(&result)) {\n\t\t\t\ttTJSVariant var2 (lineNo);\n\t\t\t\ttTJSVariant *vars[2];\n\t\t\t\tvars[0] = &result;\n\t\t\t\tvars[1] = &var2;\n\t\t\t\tmethod->FuncCall(0, NULL, NULL, NULL, 2, vars, target);\n\t\t\t}\n\t\t\tclear();\n\t\t\tmethod->Release();\n\t\t}\n\t}\n\n};\n\nstatic iTJSNativeInstance * TJS_INTF_METHOD Create_NI_CSVParser()\n{\n\treturn new NI_CSVParser();\n}\n\nstatic iTJSDispatch2 * Create_NC_CSVParser()\n{\n\ttTJSNativeClassForPlugin * classobj = TJSCreateNativeClassForPlugin(TJS_W(\"CSVParser\"), Create_NI_CSVParser);\n\n\tTJS_BEGIN_NATIVE_MEMBERS(/*TJS class name*/CSVParser)\n\n\t\tTJS_DECL_EMPTY_FINALIZE_METHOD\n\n\t\tTJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(\n\t\t\t/*var.name*/_this,\n\t\t\t/*var.type*/NI_CSVParser,\n\t\t\t/*TJS class name*/CSVParser)\n\t\t{\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/CSVParser)\n\n\t\tTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/init)\n\t\t{\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/NI_CSVParser);\n\t\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t\t\t_this->init(param[0]->AsStringNoAddRef());\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_METHOD_DECL(/*func. name*/init)\n\n\t\tTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/initStorage)\n\t\t{\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/NI_CSVParser);\n\t\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t\t\t_this->initStorage(param[0]->AsStringNoAddRef(), numparams > 1 && (tjs_int)*param[1] != 0);\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_METHOD_DECL(/*func. name*/initStorage)\n\t\t\t\n\t\tTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getNextLine)\n\t\t{\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/NI_CSVParser);\n\t\t\t_this->getNextLine(result);\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_METHOD_DECL(/*func. name*/getNextLine)\n\t\t\t\n\t\tTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/parse)\n\t\t{\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/NI_CSVParser);\n\t\t\tif (numparams > 0) {\n\t\t\t\t_this->init(param[0]->AsStringNoAddRef());\n\t\t\t}\n\t\t\t_this->parse(objthis);\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_METHOD_DECL(/*func. name*/parse)\n\n\t\tTJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/parseStorage)\n\t\t{\n\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/NI_CSVParser);\n\t\t\tif (numparams > 0) {\n\t\t\t\t_this->initStorage(param[0]->AsStringNoAddRef(), numparams > 1 && (tjs_int)*param[1] != 0);\n\t\t\t}\n\t\t\t_this->parse(objthis);\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\tTJS_END_NATIVE_METHOD_DECL(/*func. name*/parseStorage)\n\n\t\tTJS_BEGIN_NATIVE_PROP_DECL(currentLineNumber)\n\t\t{\n\t\t\tTJS_BEGIN_NATIVE_PROP_GETTER\n\t\t\t{\n\t\t\t\tTJS_GET_NATIVE_INSTANCE(/*var. name*/_this,\t/*var. type*/NI_CSVParser);\n\t\t\t\t*result = _this->getLineNumber();\n\t\t\t\treturn TJS_S_OK;\n\t\t\t}\n\t\t\tTJS_END_NATIVE_PROP_GETTER\n\t\t\tTJS_DENY_NATIVE_PROP_SETTER\n\t\t}\n\t\tTJS_END_NATIVE_PROP_DECL(currentLineNumber)\n\n\tTJS_END_NATIVE_MEMBERS\n\n\t// 萔̓o^\n\n\t/*\n\t * ̊֐ classobj Ԃ܂B\n\t */\n\treturn classobj;\n}\n\nvoid InitPlugin_CSVParser() {\n    // TJS ̃O[oIuWFNg擾\n    iTJSDispatch2 * global = TVPGetScriptDispatch();\n\n    if (global) {\n\n        // Arary NXo[擾\n        {\n            tTJSVariant varScripts;\n            TVPExecuteExpression(TJS_W(\"Array\"), &varScripts);\n            iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef();\n            // o擾\n            ArrayClearMethod = getMember(dispatch, TJS_W(\"clear\"));\n        }\n\n        addMember(global, TJS_W(\"CSVParser\"), Create_NC_CSVParser());\n        global->Release();\n    }\n}\n//---------------------------------------------------------------------------\n// extern \"C\" __declspec(dllexport) HRESULT _stdcall V2Unlink()\n// {\n// \t// - ܂ATJS ̃O[oIuWFNg擾\n// \tiTJSDispatch2 * global = TVPGetScriptDispatch();\n// \n// \t// - global  DeleteMember \\bhpAIuWFNg폜\n// \tif (global)\t{\n// \t\tdelMember(global, L\"CSVParser\");\n// \t\tif (ArrayClearMethod) {\n// \t\t\tArrayClearMethod->Release();\n// \t\t\tArrayClearMethod = NULL;\n// \t\t}\n// \t\tglobal->Release();\n// \t}\n// }\n\nNCB_PRE_REGIST_CALLBACK(InitPlugin_CSVParser);\n"
  },
  {
    "path": "src/plugins/dirlist.cpp",
    "content": "//---------------------------------------------------------------------------\n//#include <windows.h>\n//#include \"tp_stub.h\"\n#include \"tp_stub.h\"\n#include \"ncbind/ncbind.hpp\"\n//---------------------------------------------------------------------------\n\n#define NCB_MODULE_NAME TJS_W(\"dirlist.dll\")\n\n\n//---------------------------------------------------------------------------\n// 指定されたディレクトリ内のファイルの一覧を得る関数\n//---------------------------------------------------------------------------\nclass tGetDirListFunction : public tTJSDispatch\n{\n\ttjs_error TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\tif(membername) return TJS_E_MEMBERNOTFOUND;\n\n\t\t// 引数 : ディレクトリ\n\t\tif(numparams < 1) return TJS_E_BADPARAMCOUNT;\n\n\t\tttstr dir(*param[0]);\n\n\t\tif(dir.GetLastChar() != TJS_W('/'))\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"'/' must be specified at the end of given directory name.\"));\n\n\t\t// OSネイティブな表現に変換\n\t\tdir = TVPNormalizeStorageName(dir);\n\n\t\t// Array クラスのオブジェクトを作成\n\t\tiTJSDispatch2 * array = TJSCreateArrayObject();\n\t\tif (!result) return TJS_S_OK;\n\t\ttry {\n\t\t\ttTJSArrayNI* ni;\n\t\t\tarray->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJSGetArrayClassID(), (iTJSNativeInstance**)&ni);\n\t\t\tTVPGetLocalName(dir);\n\t\t\tTVPGetLocalFileListAt(dir, [ni](const ttstr &name, tTVPLocalFileInfo* s) {\n\t\t\t\tif (s->Mode & (S_IFREG | S_IFDIR)) {\n\t\t\t\t\tni->Items.emplace_back(name);\n\t\t\t\t}\n\t\t\t});\n\t\t\t*result = tTJSVariant(array, array);\n\t\t\tarray->Release();\n\t\t}\n\t\tcatch (...) {\n\t\t\tarray->Release();\n\t\t\tthrow;\n\t\t}\n\n\t\t// 戻る\n\t\treturn TJS_S_OK;\n\t}\n} * GetDirListFunction;\n//---------------------------------------------------------------------------\n\n//---------------------------------------------------------------------------\nstatic void PostRegistCallback()\n{\n\t// GetDirListFunction の作成と登録\n\ttTJSVariant val;\n\n\t// TJS のグローバルオブジェクトを取得する\n\tiTJSDispatch2 * global = TVPGetScriptDispatch();\n\n\t// 1 まずオブジェクトを作成\n\tGetDirListFunction = new tGetDirListFunction();\n\n\t// 2 GetDirListFunction を tTJSVariant 型に変換\n\tval = tTJSVariant(GetDirListFunction);\n\n\t// 3 すでに val が GetDirListFunction を保持しているので、GetDirListFunction は\n\t//   Release する\n\tGetDirListFunction->Release();\n\n\n\t// 4 global の PropSet メソッドを用い、オブジェクトを登録する\n\tglobal->PropSet(\n\t\tTJS_MEMBERENSURE, // メンバがなかった場合には作成するようにするフラグ\n\t\tTJS_W(\"getDirList\"), // メンバ名 ( かならず TJS_W( ) で囲む )\n\t\tNULL, // ヒント ( 本来はメンバ名のハッシュ値だが、NULL でもよい )\n\t\t&val, // 登録する値\n\t\tglobal // コンテキスト ( global でよい )\n\t\t);\n\n\n\t// - global を Release する\n\tglobal->Release();\n\n\t// val をクリアする。\n\t// これは必ず行う。そうしないと val が保持しているオブジェクト\n\t// が Release されず、次に使う TVPPluginGlobalRefCount が正確にならない。\n\tval.Clear();\n}\nNCB_POST_REGIST_CALLBACK(PostRegistCallback);\n"
  },
  {
    "path": "src/plugins/fftgraph.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n\n#define NCB_MODULE_NAME TJS_W(\"fftgraph.dll\")\n\nstatic void InitPlugin()\n{\n\tTVPExecuteScript(TJS_W(\"function drawFFTGraph(){}\"));\n}\n\nNCB_PRE_REGIST_CALLBACK(InitPlugin);\n"
  },
  {
    "path": "src/plugins/getSample.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n#include <algorithm>\n#include <cstdlib>\n\n#define NCB_MODULE_NAME TJS_W(\"getSample.dll\")\n//------------------------------------------------------------------------------------------------\n// 旧方式（互換のために残されています）\n\n/**\n * サンプル値の取得（旧方式）\n * 現在の再生位置から指定数のサンプルを取得してその平均値を返します。\n * 値が負のサンプル値は無視されます。\n * @param n 取得するサンプルの数。省略すると 100\n */\ntjs_error\ngetSample(tTJSVariant *result,tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n{\n\ttjs_error ret = TJS_S_OK;\n\ttjs_int n = numparams > 0 ? (tjs_int)*param[0] : 100;\n\tif (n > 0 && result) {\n\t\tshort *buf = (short*)malloc(n * sizeof(*buf));\n\t\tif (buf) {\n\t\t\ttTJSVariant buffer     = (tTVInteger)buf;\n\t\t\ttTJSVariant numsamples = n;\n\t\t\ttTJSVariant channel    = 1;\n\t\t\ttTJSVariant *p[3] = {&buffer, &numsamples, &channel};\n\t\t\tif (TJS_SUCCEEDED(ret = objthis->FuncCall(0, TJS_W(\"getVisBuffer\"), NULL, NULL, 3, p, objthis))) {\n\t\t\t\tint c=0;\n\t\t\t\tint sum = 0;\n\t\t\t\tfor (int i=0;i<n;i++) {\n\t\t\t\t\tif (buf[i] >= 0) {\n\t\t\t\t\t\tsum += buf[i]; c++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t*result = c>0 ? sum / c : 0;\n\t\t\t}\n\t\t\tfree(buf);\n\t\t}\n\t}\n\treturn ret;\n}\n\nNCB_ATTACH_FUNCTION(getSample, WaveSoundBuffer, getSample);\n//struct ncbFunctionTag_WaveSoundBuffer_getSample {};\n//template <> struct ncbNativeFunctionAutoRegisterTempl<ncbFunctionTag_WaveSoundBuffer_getSample>\n//\t: public ncbNativeFunctionAutoRegister\n//{\n//\tvoid Regist()   const { RegistFunction(TJS_W(\"getSample\"), TJS_W(\"WaveSoundBuffer\"), &getSample); }\n//\tvoid Unregist() const { UnregistFunction(TJS_W(\"getSample\"), TJS_W(\"WaveSoundBuffer\")); }\n//};\n//static ncbNativeFunctionAutoRegisterTempl<ncbFunctionTag_WaveSoundBuffer_getSample> ncbFunctionAutoRegister_WaveSoundBuffer_getSample;\n\n\n//------------------------------------------------------------------------------------------------\n// 新方式の拡張プロパティ・メソッド\n\nclass WaveSoundBufferAdd {\nprotected:\n\tiTJSDispatch2 *objthis; //< オブジェクト情報の参照\n\tint counts, aheads;\n\ttjs_uint32 hint;\n\ttTJSVariant vBuffer, vNumSamples, vChannel, vAheads, *params[4];\n\tshort *buf;\n\n\tstatic int defaultCounts, defaultAheads;\npublic:\n\tWaveSoundBufferAdd(iTJSDispatch2 *objthis)\n\t\t:   objthis(objthis),\n\t\t\tcounts(defaultCounts),\n\t\t\taheads(defaultAheads),\n\t\t\thint(0)\n\t{\n\t\tbuf = new short[counts];\n\t\t// useVisBuffer = true; にする\n\t\ttTJSVariant val(1);\n\t\ttjs_error r = objthis->PropSet(0, TJS_W(\"useVisBuffer\"), NULL, &val, objthis);\n\t\tif (r != TJS_S_OK)\n\t\t\tTVPAddLog(ttstr(TJS_W(\"useVisBuffer=1 failed: \")) + ttstr(r));\n\n\t\t// getVisBuffer用の引数を作る\n\t\tvBuffer     = (tTVInteger)buf;\n\t\tvChannel    = 1;\n\t\tvNumSamples = counts;\n\t\tvAheads     = aheads;\n\t\tparams[0] = &vBuffer;\n\t\tparams[1] = &vNumSamples;\n\t\tparams[2] = &vChannel;\n\t\tparams[3] = &vAheads;\n\t}\n\t~WaveSoundBufferAdd() {\n\t\tdelete[] buf;\n\t}\n\n\t/**\n\t * サンプル値の取得（新方式）\n\t * getVisBuffer(buf, sampleCount, 1, sampleAhead)でサンプルを取得し，\n\t * (value/32768)^2の最大値を取得します。(0～1の実数で返ります)\n\t * ※このプロパティを読み出すと暗黙でuseVisBuffer=trueに設定されます\n\t */\n\tdouble getSampleValue() {\n\t\tmemset(buf, 0, counts*sizeof(short));\n\t\ttTJSVariant result;\n\t\ttjs_error r = objthis->FuncCall(0, TJS_W(\"getVisBuffer\"), &hint, &result, 4, params, objthis);\n\n\t\tif (r != TJS_S_OK) TVPAddLog(ttstr(TJS_W(\"getVisBuffer failed: \"))+ttstr(r));\n\n\t\tint cnt = (int)result.AsInteger();\n\t\tif (cnt > counts || cnt < 0) cnt = counts;\n\n\t\t// サンプルの二乗中の最大値を返す\n\t\tdouble max = 0;\n\t\tint imax = 0;\n\t\tfor (int i=cnt-1;i>=0;i--) {\n\t\t\timax = std::max(imax, (int)std::abs(buf[i]));\n\t\t}\n\t\tmax = (imax) / +32768.0;\n\t\tmax *= max;\n\t\treturn max;\n\t}\n\n\t/**\n\t * バッファ取得用パラメータプロパティ（sampleValueを参照）\n\t * デフォルトはsetDefaultCounts/setDefaultAheadsで決定されます\n\t */\n\tint  getSampleCount() const  { return counts; }\n\tvoid setSampleCount(int cnt) {\n\t\tcounts = cnt;\n\t\tdelete[] buf;\n\t\tbuf = new short[counts];\n\t\tvBuffer     = (tTVInteger)buf;\n\t\tvNumSamples = counts;\n\t}\n\tint  getSampleAhead() const  { return aheads; }\n\tvoid setSampleAhead(int ahd) {\n\t\tvAheads     = (aheads = ahd);\n\t}\n\n\t/**\n\t * 新方式のデフォルトのパラメータ設定用関数\n\t * 以降で生成されるWaveSoundBufferのインスタンスについて\n\t * sampleCount/sampleAheadのデフォルト値を設定できます\n\t */\n\tstatic void setDefaultCounts(int cnt) { defaultCounts = cnt; }\n\tstatic void setDefaultAheads(int ahd) { defaultAheads = ahd; }\n};\n\nint WaveSoundBufferAdd::defaultCounts = 100;\nint WaveSoundBufferAdd::defaultAheads = 0;\n\n// インスタンスゲッタ\nNCB_GET_INSTANCE_HOOK(WaveSoundBufferAdd)\n{\n\tNCB_INSTANCE_GETTER(objthis) { // objthis を iTJSDispatch2* 型の引数とする\n\t\tClassT* obj = GetNativeInstance(objthis);\t// ネイティブインスタンスポインタ取得\n\t\tif (!obj) {\n\t\t\tobj = new ClassT(objthis);\t\t\t\t// ない場合は生成する\n\t\t\tSetNativeInstance(objthis, obj);\t\t// objthis に obj をネイティブインスタンスとして登録する\n\t\t}\n\t\treturn obj;\n\t}\n};\n\n// 登録\nNCB_ATTACH_CLASS_WITH_HOOK(WaveSoundBufferAdd, WaveSoundBuffer) {\n\tProperty(TJS_W(\"sampleValue\"), &Class::getSampleValue, (int)0);\n\tProperty(TJS_W(\"sampleCount\"), &Class::getSampleCount, &Class::setSampleCount);\n\tProperty(TJS_W(\"sampleAhead\"), &Class::getSampleAhead, &Class::setSampleAhead);\n}\nNCB_ATTACH_FUNCTION(setDefaultCounts, WaveSoundBuffer, WaveSoundBufferAdd::setDefaultCounts);\nNCB_ATTACH_FUNCTION(setDefaultAheads, WaveSoundBuffer, WaveSoundBufferAdd::setDefaultAheads);\n\n"
  },
  {
    "path": "src/plugins/getabout.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n#include \"MsgIntf.h\"\n\n#define NCB_MODULE_NAME TJS_W(\"getabout.dll\")\nNCB_ATTACH_FUNCTION(getAboutString, System, TVPGetAboutString);\n"
  },
  {
    "path": "src/plugins/layerExBase.hpp",
    "content": "#ifndef _layExBase_hpp_\n#define _layExBase_hpp_\n\n#include \"PluginStub.h\"\n#include \"LayerImpl.h\"\n#include \"RenderManager.h\"\n\n/**\n * プロパティのキャッシュ処理用\n */\nstruct ObjectCache\n{\n\ttypedef iTJSDispatch2*  DispatchT;\n\ttypedef tjs_char const* NameT;\n\ttypedef tTVInteger      IntegerT;\n\ttypedef ttstr           StringT;\n\ttypedef tTJSVariant     VariantT;\n\n\tObjectCache(DispatchT obj, NameT name) : _obj(obj), _cache(0), _name(name) {\n\n\t\ttTJSVariant layer;\n\t\tTVPExecuteExpression(TJS_W(\"Layer\"), &layer);\n\t\ttTJSVariant var;\n\t\tif (TJS_SUCCEEDED(layer.AsObjectNoAddRef()->PropGet(TJS_IGNOREPROP, name, NULL, &var, layer.AsObjectNoAddRef()))) _cache = var;\n\t\telse _Exception(TJS_W(\"FAILED: get property object :\"));\n\t}\n\n\t~ObjectCache() {\n\t\tif (_cache) _cache->Release();\n\t}\n\n\tinline VariantT GetValue() const {\n\t\tVariantT var;\n\t\tif (TJS_FAILED(_cache->PropGet(0, 0, 0, &var, _obj)))\n\t\t\t_Exception(TJS_W(\"FAILED: get property value :\"));\n\t\treturn var;\n\t}\n\tinline operator VariantT() const { return GetValue(); }\n\tinline operator IntegerT() const { return static_cast<IntegerT>(GetValue()); }\n\n\tinline VariantT operator ()(int numparams, VariantT **param) {\n\t\tVariantT var;\n\t\tif (TJS_FAILED(_cache->FuncCall(0, 0, 0, &var, numparams, param, _obj)))\n\t\t\t_Exception(TJS_W(\"FAILED: function call :\"));\n\t\treturn var;\n\t}\n\n\tinline void SetValue(int n) const {\n\t\tVariantT var = n;\n\t\tif (TJS_FAILED(_cache->PropSet(0, 0, 0, &var, _obj)))\n\t\t\t_Exception(TJS_W(\"FAILED: get property value :\"));\n\t}\n\nprivate:\n\tDispatchT _obj, _cache;\n\tNameT _name;\n\n\tvoid _Exception(NameT mes) const {\n\t\tTVPThrowExceptionMessage(mes, _name);\n\t}\n};\n\n/**\n * レイヤ拡張処理のベース\n */\nstruct layerExBase\n{\n\ttypedef iTJSDispatch2* DispatchT;\n\ttypedef ObjectCache    ObjectT;\n\ttypedef unsigned char* BufferT;\n\ttypedef unsigned char* BufferRT;\n\ttypedef tjs_int        PitchT;\n\ttypedef tjs_int        GeometryT;\n\tDispatchT _obj;\n\t/**\n\t * コンストラクタ\n\t */\n\tlayerExBase(DispatchT obj)\n\t\t: _obj(obj),\n\t\t  _pWidth( obj, TJS_W(\"imageWidth\")),\n\t\t  _pHeight(obj, TJS_W(\"imageHeight\")),\n\t\t  //_pBuffer(obj, TJS_W(\"mainImageBufferForWrite\")),\n\t\t  //_pPitch( obj, TJS_W(\"mainImageBufferPitch\")),\n\t\t  _pUpdate(obj, TJS_W(\"update\")),\n\t\t  _pClipLeft(  obj, TJS_W(\"clipLeft\")),\n\t      _pClipTop(   obj, TJS_W(\"clipTop\")),\n\t      _pClipWidth( obj, TJS_W(\"clipWidth\")),\n\t      _pClipHeight(obj, TJS_W(\"clipHeight\")),\n\t\t  _width(0), _height(0), /*_pitch(0),*/ /*_buffer(0),*/ _clipLeft(0), _clipTop(0), _clipWidth(0), _clipHeight(0)\n\t{\n\t}\n\n\t/**\n\t * デストラクタ\n\t */\n\tvirtual ~layerExBase() {}\n\n\t/**\n\t * 再描画指定\n\t */\n\tvirtual void redraw() {\n\t\ttTJSVariant  vars [4] = { _pClipLeft, _pClipTop, _pClipWidth, _pClipHeight };\n\t\ttTJSVariant *varsp[4] = { vars, vars+1, vars+2, vars+3 };\n\t\t_pUpdate(4, varsp);\n\t}\n\n\t/**\n\t * 情報更新\n\t */\n\tvirtual void reset() {\n\t\t_width  = (GeometryT)_pWidth;\n\t\t_height = (GeometryT)_pHeight;\n\t\t//_buffer = (BufferT)(ObjectCache::IntegerT)_pBuffer;\n\t\t//_pitch  = (PitchT)_pPitch;\n\t\t_clipLeft   = (GeometryT)_pClipLeft;\n\t\t_clipTop    = (GeometryT)_pClipTop;\n\t\t_clipWidth  = (GeometryT)_pClipWidth;\n\t\t_clipHeight = (GeometryT)_pClipHeight;\n\t}\n\nprotected:\n\tObjectT   _pWidth, _pHeight/*, _pBuffer, _pPitch*/, _pUpdate;\n\n\tGeometryT _width, _height;\n\t//BufferT   _buffer;\n\t//PitchT    _pitch;\n\n\t// クリップ情報\n\tObjectT   _pClipLeft, _pClipTop, _pClipWidth, _pClipHeight;\n\tGeometryT _clipLeft, _clipTop, _clipWidth, _clipHeight;\n};\n\nstruct layerExBase_GL\n{\n    typedef iTJSDispatch2* DispatchT;\n    typedef tjs_int        GeometryT;\n    typedef tjs_int        PitchT;\n    typedef unsigned char* BufferT;\n    typedef unsigned char* BufferRT;\n\n    tTJSNI_Layer *_this;\n\n    GeometryT _width, _height;\n    BufferT   _buffer;\n    PitchT    _pitch;\n\n    // ･ｯ･・ﾃ･ﾗﾇ驤・\n    GeometryT _clipLeft, _clipTop, _clipWidth, _clipHeight;\n    DispatchT _obj;\n\n    layerExBase_GL(DispatchT obj)\n        : _obj(obj)\n    {\n        tjs_error hr; \n        hr = obj->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \n            tTJSNC_Layer::ClassID, (iTJSNativeInstance**)&_this);\n        if(TJS_FAILED(hr)) TVPThrowExceptionMessage(TJS_W(\"Not Layer\"));\n        _buffer = nullptr;\n        _pitch = 0;\n        reset();\n    }\n\n    virtual void reset() {\n        _width  = (GeometryT)_this->GetWidth();\n        _height = (GeometryT)_this->GetHeight();\n        if(TVPIsSoftwareRenderManager()) {\n            _buffer = (BufferT)_this->GetMainImagePixelBufferForWrite();\n            _pitch  = (PitchT)_this->GetMainImagePixelBufferPitch();\n        }\n        _clipLeft   = (GeometryT)_this->GetClipLeft();\n        _clipTop    = (GeometryT)_this->GetClipTop();\n        _clipWidth  = (GeometryT)_this->GetClipWidth();\n        _clipHeight = (GeometryT)_this->GetClipHeight();\n    }\n    virtual void redraw() {\n        tTVPRect rc(_clipLeft, _clipTop, _clipLeft+_clipWidth, _clipTop+_clipHeight);\n        _this->Update(rc);\n    }\n};\n\n#endif\n"
  },
  {
    "path": "src/plugins/layerExMovie.cpp",
    "content": "//#pragma comment(lib, \"strmiids.lib\")\n#include <stdlib.h>\n#ifdef _MSC_VER\n//#include <concrt.h>\n#endif\n#include <stdint.h>\n#include \"tjsCommHead.h\"\n#include \"EventIntf.h\"\n#include \"layerExBase.hpp\"\n#include \"ncbind/ncbind.hpp\"\n#include \"Application.h\"\n#include \"LayerBitmapIntf.h\"\n#include <algorithm>\n#include \"krmovie.h\"\n#include \"movie/ffmpeg/KRMovieLayer.h\"\n\n#define NCB_MODULE_NAME TJS_W(\"layerExMovie.dll\")\n\n/*\n* Movie 描画用レイヤ\n*/\nstruct layerExMovie : public layerExBase_GL, tTVPContinuousEventCallbackIntf\n{\nprotected:\n\tclass VideoLayer : public KRMovie::VideoPresentLayer {\n\t\tstd::function<void(KRMovieEvent, void *)> m_funcCallback;\n\n\tpublic:\n\t\tVideoLayer(const std::function<void(KRMovieEvent, void *)> &func) : m_funcCallback(func) {}\n\t\tvoid BuildGraph(IStream *stream, const tjs_char * streamname, const tjs_char *type, uint64_t size)\n\t\t{\n\t\t\tm_pPlayer->SetCallback(m_funcCallback);\n\t\t\tm_pPlayer->OpenFromStream(stream, streamname, type, size);\n\t\t}\n\t\tvirtual void OnPlayEvent(KRMovieEvent msg, void *p) override {\n\t\t\tm_funcCallback(msg, p);\n\t\t}\n\t};\n\tVideoLayer *VideoOverlay;\n\t//MessageDelegate *UtilWindow;\n\t//ObjectT _pType;\n\n\tlong movieWidth;\n\tlong movieHeight;\n\tclass tTVPBaseTexture\t*Bitmap[2];\n\n\tbool loop;\n\tbool alpha;\n\n\ttTJSBinaryStream *in;\n#ifdef FILEBASE\n\tttstr tempFile;\n#else\n// \tCIStreamProxy\t\t\t*m_Proxy;\n// \tCIStreamReader\t\t\t*m_Reader;\n#endif\n\n\tvoid clearMovie();\n\n\tDispatchT onStartMovie;\n\tDispatchT onUpdateMovie;\n\tDispatchT onStopMovie;\n\n\tbool playing;\n\tstd::mutex mtxEvent;\n\tstd::vector<KRMovieEvent> PostEvents;\n\npublic:\n\tlayerExMovie(DispatchT obj);\n\t~layerExMovie();\n\npublic:\n\n\t// ムービーのロード\n\tvoid openMovie(const tjs_char* filename, bool alpha);\n\n\tvoid startMovie(bool loop);\n\tvoid stopMovie();\n\n\tvoid start();\n\tvoid stop();\n\n\tbool isPlayingMovie();\n\n\tvoid onUpdate();\n\tvoid onEnded();\n\n\t/**\n\t* Continuous コールバック\n\t* 吉里吉里が暇なときに常に呼ばれる\n\t* 塗り直し処理\n\t*/\n\tvirtual void TJS_INTF_METHOD OnContinuousCallback(tjs_uint64 tick);\n};\n\n/**\n * コンストラクタ\n */\nlayerExMovie::layerExMovie(DispatchT obj) : /*_pType(obj, TJS_W(\"type\")),*/ layerExBase_GL(obj)\n{\n\tVideoOverlay = NULL;\n\tloop = false;\n\talpha = false;\n\tmovieWidth = 0;\n\tmovieHeight = 0;\n\tin = nullptr;\n\t{\n\t\ttTJSVariant var;\n\t\tif (TJS_SUCCEEDED(obj->PropGet(TJS_IGNOREPROP, TJS_W(\"onStartMovie\"), NULL, &var, obj))) onStartMovie = var;\n\t\telse onStartMovie = NULL;\n\t\tif (TJS_SUCCEEDED(obj->PropGet(TJS_IGNOREPROP, TJS_W(\"onStopMovie\"), NULL, &var, obj))) onStopMovie = var;\n\t\telse onStopMovie = NULL;\n\t\tif (TJS_SUCCEEDED(obj->PropGet(TJS_IGNOREPROP, TJS_W(\"onUpdateMovie\"), NULL, &var, obj))) onUpdateMovie = var;\n\t\telse onUpdateMovie = NULL;\n\t}\n\tplaying = false;\n\t//UtilWindow = new MessageDelegate(EVENT_FUNC2(layerExMovie, WndProc));\n\tBitmap[0] = Bitmap[1] = nullptr;\n}\n\n/**\n * デストラクタ\n */\nlayerExMovie::~layerExMovie()\n{\n\tstopMovie();\n\t//if (UtilWindow) delete UtilWindow;\n\tif (Bitmap[0]) delete Bitmap[0];\n\tif (Bitmap[1]) delete Bitmap[1];\n}\n\nvoid\nlayerExMovie::clearMovie()\n{\n\tif (VideoOverlay) {\n\t\tVideoOverlay->Release(), VideoOverlay = NULL;\n\t}\n// \tif (in) {\n// \t\tdelete in;\n// \t}\n}\n\n/**\n * ムービーファイルを開いて準備する\n * @param filename ファイル名\n * @param alpha アルファ指定（半分のサイズでα処理する）\n */\nvoid\nlayerExMovie::openMovie(const tjs_char* filename, bool alpha)\n{ \n\tclearMovie();\n\tthis->alpha = alpha;\n\tmovieWidth = 0;\n\tmovieHeight = 0;\n\n\t// ファイルをテンポラリにコピーして対応\n\tif ((in = TVPCreateStream(filename, TJS_BS_READ)) == NULL) {\n\t\tttstr error = filename;\n\t\terror += TJS_W(\":ファイルが開けません\");\n\t\tTVPAddLog(error);\n\t\treturn;\n\t}\n\tttstr ext = TVPExtractStorageExt(filename);\n\text.ToLowerCase();\n\tVideoLayer *pOverlay = new VideoLayer([this](KRMovieEvent msg, void* p) {\n\t\tstd::lock_guard<std::mutex> lk(mtxEvent);\n\t\tPostEvents.push_back(msg);\n\t});\n\tpOverlay->BuildGraph(TVPCreateIStream(in), filename, ext.c_str(), in->GetSize());\n\tVideoOverlay = pOverlay;\n\tVideoOverlay->GetVideoSize(&movieWidth, &movieHeight);\n\tif (Bitmap[0]) delete Bitmap[0];\n\tif (Bitmap[1]) delete Bitmap[1];\n\tlong size = movieWidth * movieHeight * 4;\n\tBitmap[0] = new tTVPBaseTexture(movieWidth, movieHeight/*, 32*/);\n\tBitmap[1] = new tTVPBaseTexture(movieWidth, movieHeight/*, 32*/);\n\tVideoOverlay->SetVideoBuffer(Bitmap[0], Bitmap[1], size);\n\tif (alpha) {\n\t\tmovieWidth /= 2;\n\t}\n// \t_pWidth.SetValue(movieWidth);\n// \t_pHeight.SetValue(movieHeight);\n    _this->SetSize(movieWidth, movieHeight);\n\t//_pType.SetValue(alpha ? ltAlpha : ltOpaque);\n    _this->SetType(alpha ? ltAlpha : ltOpaque);\n}\n\n/**\n * ムービーの開始\n */\nvoid\nlayerExMovie::startMovie(bool loop)\n{\n\tif (VideoOverlay) {\n\t\t// 再生開始\n\t\tthis->loop = loop;\n\t\tVideoOverlay->Play();\n\t\tstart();\n\t\tif (onStartMovie != NULL) {\n\t\t\tonStartMovie->FuncCall(0, NULL, NULL, NULL, 0, NULL, _obj);\n\t\t}\n\t}\n}\n\n/**\n * ムービーの停止\n */\nvoid\nlayerExMovie::stopMovie()\n{\n\tbool p = playing;\n\tif (VideoOverlay) VideoOverlay->Stop();\n\tstop();\n\tclearMovie();\n\tif (p) {\n\t\tif (onStopMovie != NULL) {\n\t\t\tonStopMovie->FuncCall(0, NULL, NULL, NULL, 0, NULL, _obj);\n\t\t}\n\t}\n}\n\nbool\nlayerExMovie::isPlayingMovie()\n{\n\treturn playing;\n}\n\nvoid\nlayerExMovie::start()\n{\n\tstop();\n\tTVPAddContinuousEventHook(this);\n\tplaying = true;\n}\n\n/**\n * Irrlicht 呼び出し処理停止\n */\nvoid\nlayerExMovie::stop()\n{\n\tTVPRemoveContinuousEventHook(this);\n\tplaying = false;\n}\n\nvoid layerExMovie::onUpdate() {\n\t// 更新完了\n\t// サーフェースからレイヤに画面コピー\n\treset();\n\ttTVPBaseTexture *frontbmp = VideoOverlay->GetFrontBuffer();\n\tif (frontbmp) {\n\t\tiTVPTexture2D* src = frontbmp->GetTexture();\n\t\tiTVPTexture2D* dst = _this->GetMainImage()->GetTextureForRender(false, nullptr);\n\t\ttTVPRect rcdst(_clipLeft, _clipTop, _clipLeft + _clipWidth, _clipTop + _clipHeight);\n\t\tiTVPRenderMethod *method;\n\t\tif (alpha) {\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"CopyColor\");\n\t\t\tmethod = _method;\n\t\t} else {\n\t\t\tstatic iTVPRenderMethod *_method = TVPGetRenderManager()->GetRenderMethod(\"Copy\");\n\t\t\tmethod = _method;\n\t\t}\n\t\ttRenderTexRectArray::Element src_tex[] = {\n\t\t\ttRenderTexRectArray::Element(src,\n\t\t\ttTVPRect(0, 0, std::min(_width, (tjs_int)movieWidth), std::min(_height, (tjs_int)movieHeight)))\n\t\t};\n\t\tTVPGetRenderManager()->OperateRect(method, dst, nullptr, rcdst, src_tex);\n\t}\n\t//redraw();\n\tif (onUpdateMovie != NULL) {\n\t\tonUpdateMovie->FuncCall(0, NULL, NULL, NULL, 0, NULL, _obj);\n\t}\n}\n\nvoid layerExMovie::onEnded() {\n\t// 更新終了\n\tif (loop) {\n\t\tVideoOverlay->Rewind();\n\t\tVideoOverlay->Play();\n\t} else {\n\t\tApplication->PostUserMessage(std::bind(&layerExMovie::stopMovie, this));\n\t}\n}\n\nvoid TJS_INTF_METHOD\nlayerExMovie::OnContinuousCallback(tjs_uint64 tick)\n{\n\tif (VideoOverlay) {\n\t\t// 更新\n\t\tVideoOverlay->OnContinuousCallback(tick);\n\t\tstd::vector<KRMovieEvent> vecEvent;\n\t\t{\n\t\t\tstd::lock_guard<std::mutex> lk(mtxEvent);\n\t\t\tvecEvent.swap(PostEvents);\n\t\t}\n\t\tfor (KRMovieEvent msg : vecEvent) {\n\t\t\tswitch (msg) {\n\t\t\tcase KRMovieEvent::Update:\n\t\t\t\tonUpdate(); break;\n\t\t\tcase KRMovieEvent::Ended:\n\t\t\t\tonEnded(); break;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tstop();\n\t}\n}\n\n// ----------------------------------- クラスの登録\n\nNCB_GET_INSTANCE_HOOK(layerExMovie)\n{\n\t// インスタンスゲッタ\n\tNCB_INSTANCE_GETTER(objthis) { // objthis を iTJSDispatch2* 型の引数とする\n\t\tClassT* obj = GetNativeInstance(objthis);\t// ネイティブインスタンスポインタ取得\n\t\tif (!obj) {\n\t\t\tobj = new ClassT(objthis);\t\t\t\t// ない場合は生成する\n\t\t\tSetNativeInstance(objthis, obj);\t\t// objthis に obj をネイティブインスタンスとして登録する\n\t\t}\n\t\treturn obj;\n\t}\n\n\t// デストラクタ（実際のメソッドが呼ばれた後に呼ばれる）\n\t~NCB_GET_INSTANCE_HOOK_CLASS() {\n\t}\n};\n\n\n// フックつきアタッチ\nNCB_ATTACH_CLASS_WITH_HOOK(layerExMovie, Layer) {\n\tNCB_METHOD(openMovie);\n\tNCB_METHOD(startMovie);\n\tNCB_METHOD(stopMovie);\n\tNCB_METHOD(isPlayingMovie);\n}"
  },
  {
    "path": "src/plugins/layerExPerspective.cpp",
    "content": "#include <stdio.h>\n#include <list>\n#include <map>\n\nusing namespace std;\n\n#define NCB_MODULE_NAME TJS_W(\"perspective.dll\")\n\nstatic const char *copyright = \n\"----- AntiGrainGeometry Copyright START -----\\n\"\n\"Anti-Grain Geometry - Version 2.4\\n\"\n\"Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)\\n\"\n\"\\n\"\n\"Permission to copy, use, modify, sell and distribute this software\\n\"\n\"is granted provided this copyright notice appears in all copies. \\n\"\n\"This software is provided \\\"as is\\\" without express or implied\\n\"\n\"warranty, and with no claim as to its suitability for any purpose.\\n\"\n\"----- AntiGrainGeometry Copyright END -----\\n\";\n\n#include \"ncbind/ncbind.hpp\"\n\n#include \"LayerExBase.h\"\n#include \"LayerImpl.h\"\n#include \"tjsNative.h\"\n#include \"RenderManager.h\"\n#if 0\n/**\n * 透視変換コピー\n * @param src\n * @param sleft\n * @param stop\n * @param swidth\n * @param sheight\n * @param x1 左上隅\n * @param y1\n * @param x2 右上隅\n * @param y2\n * @param x3 左下隅\n * @param y3\n * @param x4 右下隅\n * @param y4\n */\nclass tPerspectiveCopy : public tTJSDispatch\n{\nprotected:\npublic:\n\ttjs_error TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis) {\n\n\t\tif (numparams < 13) return TJS_E_BADPARAMCOUNT;\n\n\t\tNI_LayerExBase *dest;\n\t\tif ((dest = NI_LayerExBase::getNative(objthis)) == NULL) return TJS_E_NATIVECLASSCRASH;\n\t\tdest->reset(objthis);\n\t\t\n\t\tNI_LayerExBase *src;\n\t\tif ((src = NI_LayerExBase::getNative(param[0]->AsObjectNoAddRef())) == NULL) return TJS_E_NATIVECLASSCRASH;\n\t\tsrc->reset(param[0]->AsObjectNoAddRef());\n\t\t\n\t\tdouble g_x1 = param[1]->AsReal();\n\t\tdouble g_y1 = param[2]->AsReal();\n\t\tdouble g_x2 = g_x1 + param[3]->AsReal();\n\t\tdouble g_y2 = g_y1 + param[4]->AsReal();\n\n\t\tdouble quad[8];\n        quad[0] = param[5]->AsReal(); // 左上\n        quad[1] = param[6]->AsReal();\n        quad[2] = param[7]->AsReal(); // 右上\n        quad[3] = param[8]->AsReal();\n\t\tquad[4] = param[11]->AsReal(); // 右下\n        quad[5] = param[12]->AsReal(); \n        quad[6] = param[9]->AsReal(); // 左下\n        quad[7] = param[10]->AsReal();\n\n\n\t\t{\n\t\t\t/// ソースの準備\n\t\t\tunsigned char *buffer = src->_buffer;\n\t\t\t// AGG 用に先頭位置に補正\n\t\t\tif (src->_pitch < 0) {\n\t\t\t\tbuffer += int(src->_height - 1) * src->_pitch;\n\t\t\t}\n\n\t\t\ttypedef agg::image_accessor_clip<pixfmt> source_type;\n\t\t\tagg::rendering_buffer rbufs(buffer, src->_width, src->_height, src->_pitch);\n            pixfmt pixbuf(rbufs);\n\t\t\tsource_type rbuf_src(pixbuf, agg::rgba_pre(0, 0, 0, 0)/*buffer, src->_width, src->_height, src->_pitch*/);\n\n\t\t\t/// レンダリング用バッファ\n\t\t\tbuffer = dest->_buffer;\n\t\t\t// AGG 用に先頭位置に補正\n\t\t\tif (dest->_pitch < 0) {\n\t\t\t\tbuffer += int(dest->_height - 1) * dest->_pitch;\n\t\t\t}\n\t\t\tagg::rendering_buffer rbuf(buffer, dest->_width, dest->_height, dest->_pitch);\n\n\t\t\t// レンダラの準備\n\t\t\tpixfmt_pre  pixf_pre(rbuf);\n\t\t\trenderer_base_pre rb_pre(pixf_pre);\n\t\t\t\n\t\t\tg_rasterizer.clip_box(0, 0, dest->_width, dest->_height);\n\t\t\tg_rasterizer.reset();\n\t\t\tg_rasterizer.move_to_d(quad[0], quad[1]);\n\t\t\tg_rasterizer.line_to_d(quad[2], quad[3]);\n\t\t\tg_rasterizer.line_to_d(quad[4], quad[5]);\n\t\t\tg_rasterizer.line_to_d(quad[6], quad[7]);\n\t\t\t\n\t\t\t// 変形コピー\n\t\t\tagg::trans_perspective tr(quad, g_x1, g_y1, g_x2, g_y2);\n\t\t\t//if(tr.is_valid())\n\t\t\t{\n\t\t\t\ttypedef agg::span_interpolator_linear<agg::trans_perspective> interpolator_type;\n\t\t\t\ttypedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;\n\t\t\t\tinterpolator_type interpolator(tr);\n\t\t\t\tsubdiv_adaptor_type subdiv_adaptor(interpolator);\n\n\t\t\t\ttypedef agg::span_image_filter_rgba_2x2</*color_type*/source_type,\n\t\t\t\t//agg::order_bgra,\n\t\t\t\tsubdiv_adaptor_type> span_gen_type;\n\t\t\t\ttypedef agg::span_allocator<agg::rgba8> span_alloc_type;\n\t\t\t\ttypedef agg::renderer_scanline_aa<renderer_base_pre, span_alloc_type, span_gen_type> renderer_type;\n\n\t\t\t\tspan_alloc_type sa;\n\t\t\t\tagg::image_filter_hermite filter_kernel;\n\t\t\t\tagg::image_filter_lut filter(filter_kernel, false);\n\t\t\t\t\n\t\t\t\tspan_gen_type sg(//sa, \n\t\t\t\t\t\t\t\t rbuf_src, \n\t\t\t\t\t\t\t\t //agg::rgba_pre(0, 0, 0, 0),\n\t\t\t\t\t\t\t\t subdiv_adaptor,\n\t\t\t\t\t\t\t\t filter);\n\t\t\t\t\n\t\t\t\trenderer_type ri(rb_pre, sa, sg);\n\t\t\t\tagg::render_scanlines(g_rasterizer, g_scanline, ri);\n\t\t\t}\n\n\t\t}\n\n\t\tdest->redraw(objthis);\n\t\treturn TJS_S_OK;\n\t}\n};\n#endif\nstatic int TJS_NATIVE_CLASSID_NAME = -1;\n\nstatic tjs_error PerspectiveCopy_GL( tTJSVariant *result, \n    tjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n{\n    if(!objthis) return TJS_E_NATIVECLASSCRASH;\n    tTJSNI_Layer *_this;\n    { \n        tjs_error hr; \n        hr = objthis->NativeInstanceSupport(TJS_NIS_GETINSTANCE, \n            tTJSNC_Layer::ClassID, (iTJSNativeInstance**)&_this); \n        if(TJS_FAILED(hr)) return TJS_E_NATIVECLASSCRASH; \n    }\n\n    if (numparams < 13) return TJS_E_BADPARAMCOUNT;\n\n    tTJSNI_BaseLayer * src = NULL;\n    tTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef();\n    if(clo.Object)\n    {\n        if(TJS_FAILED(clo.Object->NativeInstanceSupport(TJS_NIS_GETINSTANCE,\n            tTJSNC_Layer::ClassID, (iTJSNativeInstance**)&src)))\n            TVPThrowExceptionMessage(TVPSpecifyLayer);\n    }\n\n    double g_x1 = param[1]->AsReal();\n    double g_y1 = param[2]->AsReal();\n    double g_x2 = g_x1 + param[3]->AsReal();\n    double g_y2 = g_y1 + param[4]->AsReal();\n\n    tTVPPointD srcpt[4] = {\n        { g_x1, g_y1 },\n        { g_x2, g_y1 },\n\t\t{ g_x1, g_y2 },\n        { g_x2, g_y2 },\n    };\n    tTVPPointD dstpt[4] = {\n        { param[5 ]->AsReal(), param[6 ]->AsReal() }, // 左上\n        { param[7 ]->AsReal(), param[8 ]->AsReal() }, // 右上\n\t\t{ param[9]->AsReal(), param[10]->AsReal() }, // 左下\n        { param[11]->AsReal(), param[12]->AsReal() }, // 右下\n    };\n\tstatic iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod(\"PerspectiveAlphaBlend_a\");\n\tstatic int id_opa = method->EnumParameterID(\"opacity\");\n\tmethod->SetParameterOpa(id_opa, 255);\n\tiTVPTexture2D *tex = src->GetMainImage()->GetTexture();\n\ttRenderTexQuadArray::Element src_tex[] = {\n\t\ttRenderTexQuadArray::Element(tex, srcpt)\n\t};\n\tint w = _this->GetMainImage()->GetWidth(), h = _this->GetMainImage()->GetHeight();\n\ttTVPRect rctar(w, h, 0, 0);\n\tfor (int i = 0; i < 4; ++i) {\n\t\tif (rctar.left > dstpt[i].x) rctar.left = dstpt[i].x;\n\t\tif (rctar.top > dstpt[i].y) rctar.top = dstpt[i].y;\n\t\tif (rctar.right < dstpt[i].x) rctar.right = dstpt[i].x;\n\t\tif (rctar.bottom < dstpt[i].y) rctar.bottom = dstpt[i].y;\n\t}\n\tif (rctar.left < 0) rctar.left = 0;\n\tif (rctar.top < 0) rctar.top = 0;\n\tif (rctar.right > w) rctar.right = w;\n\tif (rctar.bottom > h) rctar.bottom = h;\n\tTVPGetRenderManager()->OperatePerspective(method, 1,\n\t\t_this->GetMainImage()->GetTextureForRender(method->IsBlendTarget(), &rctar), nullptr, rctar, dstpt,\n\t\ttRenderTexQuadArray(src_tex));\n\t_this->Update();\n    return TJS_S_OK;\n}\n\nstatic void\naddMethod(iTJSDispatch2 *dispatch, const tjs_char *methodName, tTJSDispatch *method)\n{\n\ttTJSVariant var = tTJSVariant(method);\n\tmethod->Release();\n\tdispatch->PropSet(\n\t\tTJS_MEMBERENSURE, // メンバがなかった場合には作成するようにするフラグ\n\t\tmethodName, // メンバ名 ( かならず TJS_W( ) で囲む )\n\t\tNULL, // ヒント ( 本来はメンバ名のハッシュ値だが、NULL でもよい )\n\t\t&var, // 登録する値\n\t\tdispatch // コンテキスト\n\t\t);\n}\n\nstatic void\ndelMethod(iTJSDispatch2 *dispatch, const tjs_char *methodName)\n{\n\tdispatch->DeleteMember(\n\t\t0, // フラグ ( 0 でよい )\n\t\tmethodName, // メンバ名\n\t\tNULL, // ヒント\n\t\tdispatch // コンテキスト\n\t\t);\n}\n\n//---------------------------------------------------------------------------\nvoid InitPlugin_Perspective()\n{\n// \tif (TVPGetRenderManager()->IsSoftware()) {\n// \t    TVPAddImportantLog(ttstr(copyright));\n// \t\n// \t    // クラスオブジェクトチェック\n// \t    if ((NI_LayerExBase::classId = TJSFindNativeClassID(TJS_W(\"LayerExBase\"))) <= 0) {\n// \t\t    NI_LayerExBase::classId = TJSRegisterNativeClass(TJS_W(\"LayerExBase\"));\n// \t    }\n// \t\n// \t    {\n// \t\t    // TJS のグローバルオブジェクトを取得する\n// \t\t    iTJSDispatch2 * global = TVPGetScriptDispatch();\n// \n// \t\t    // Layer クラスオブジェクトを取得\n// \t\t    tTJSVariant varScripts;\n// \t\t    TVPExecuteExpression(TJS_W(\"Layer\"), &varScripts);\n// \t\t    iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef();\n// \t\t    if (dispatch) {\n// \t\t\t    // プロパティ初期化\n// \t\t\t    NI_LayerExBase::init(dispatch);\n// \n// \t\t\t    // 専用メソッドの追加\n// \t\t\t    addMethod(dispatch, TJS_W(\"perspectiveCopy\"), new tPerspectiveCopy());\n// \t\t    }\n// \n// \t\t    global->Release();\n// \t    }\n//     } else {\n        iTJSDispatch2 * global = TVPGetScriptDispatch();\n        tTJSVariant varScripts;\n        global->PropGet(0, TJS_W(\"Layer\"), nullptr, &varScripts, global);\n        iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef();\n        if (dispatch) {\n            addMethod(dispatch, TJS_W(\"perspectiveCopy\"), TJSCreateNativeClassMethod(PerspectiveCopy_GL));\n        }\n    //}\n}\n\nNCB_PRE_REGIST_CALLBACK(InitPlugin_Perspective);\n"
  },
  {
    "path": "src/plugins/ncbind/ncb_foreach.h",
    "content": "#ifndef FOREACH_MAX\n#define FOREACH_MAX 20\n#endif\n\n#if defined(FOREACH) && defined(FOREACH_START) && defined(FOREACH_END)\n\n#undef  FOREACH_COMMA\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 0\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#define FOREACH_COMMA\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT)\nFOREACH\n#endif\n\n#undef  FOREACH_COMMA\n#define FOREACH_COMMA ,\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 1\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 2\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 3\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 4\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 5\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 6\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 7\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 8\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 9\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 10\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 11\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 12\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 13\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 14\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 15\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 16\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15) EXT(16)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15),EXT(16)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 17\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15) EXT(16) EXT(17)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15),EXT(16),EXT(17)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 18\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15) EXT(16) EXT(17) EXT(18)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15),EXT(16),EXT(17),EXT(18)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 19\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15) EXT(16) EXT(17) EXT(18) EXT(19)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15),EXT(16),EXT(17),EXT(18),EXT(19)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#define FOREACH_COUNT 20\n#if    (FOREACH_START <= FOREACH_COUNT && FOREACH_COUNT <= FOREACH_END)\n#undef  FOREACH_SPACE_EXT\n#define FOREACH_SPACE_EXT(EXT) EXT(1) EXT(2) EXT(3) EXT(4) EXT(5) EXT(6) EXT(7) EXT(8) EXT(9) EXT(10) EXT(11) EXT(12) EXT(13) EXT(14) EXT(15) EXT(16) EXT(17) EXT(18) EXT(19) EXT(20)\n#undef  FOREACH_COMMA_EXT\n#define FOREACH_COMMA_EXT(EXT) EXT(1),EXT(2),EXT(3),EXT(4),EXT(5),EXT(6),EXT(7),EXT(8),EXT(9),EXT(10),EXT(11),EXT(12),EXT(13),EXT(14),EXT(15),EXT(16),EXT(17),EXT(18),EXT(19),EXT(20)\nFOREACH\n#endif\n\n#undef  FOREACH_COUNT\n#undef  FOREACH_COMMA\n#undef  FOREACH_SPACE_EXT\n#undef  FOREACH_COMMA_EXT\n#endif\n"
  },
  {
    "path": "src/plugins/ncbind/ncb_invoke.hpp",
    "content": "#ifndef _ncb_invoke_hpp_\n#define _ncb_invoke_hpp_\n\nstruct MethodCaller {\n\t//--------------------------------------\n\t// template prototypes\n\n\ttemplate   <typename MethodT                       > struct tMethodTraits; // has ResultType, ClassType, ArgsType typedefs / HasResult IsStatic IsConst enums\n\t//template <typename ResultT, typename ClassT, ... > struct tMethodType;   // has (method-typed) Type typedef\n\ttemplate   <typename ResultT, typename ClassT, typename ArgsT> struct tMethodResolver;  // ArgsT = tMethodTraits::ArgsType / has MethodType (or Type) typedef\n\n\t// method parameter type-tag (use userdefined Functor)\n\ttemplate <typename TypeT>                            struct tTypeTag { typedef TypeT Type; };\n\ttemplate <int N>                                     struct tNumTag  { enum { Number = N }; };\n\n\t// method args helper template\n\ttemplate <template <typename> class Templ, class ArgsT, int N> struct tArgsExtract; // { typedef Templ<ArgsT::Arg[n]Type>::Type T[n];  T[n] t[n]; ... (n=1-N) }\n\ttemplate <class ArgsExtT, int N>                               struct tArgsSelect;  // { static inline ArgsExtT::T[N] &Get(ArgsExtT &arg) { return arg.t[N]; } };\n\n#if 0 // userdefined Functor sample\n\tstruct      ResultAndParamsHolderExample {\n\t\t// get params operator method\n\t\ttemplate <int N, typename T> T operator ()(tNumTag<N> index, tTypeTag<T> dummy) const;\n\t\t// set result operator method\n\t\ttemplate <typename T> bool operator ()(T result, tTypeTag<T> dummy);\n\t\t/*                  */bool operator ()(); // if result is void\n\t};\n#endif\n\n/**\n\tUsage:\n\n\tclass Target {\n\tpublic:\n\t\ttypedef int    ParamT1;\n\t\ttypedef double ParamT2;\n\t\tint Method(ParamT1, ParamT2, ...);\n\t\tstatic void StaticMethod();\n\t};\n\ttypedef class ResultAndParamsHolderFunctor {...} FunctT; // like ResultAndParamsHolderExample.\n\n\tTarget t;\n\tFunctT p;\n\n\tMethodCaller::Invoke(p, &Target::Method, t);    // as: return p(t.Method(p(1, tTypeTag<int>()), p(2, tTypeTag<double>()), ...), tTypeTag<int>());\n\tMethodCaller::Invoke(p, &Target::StaticMethod); // as: return Target::StaticMethod(), p();\n\n */\n\n\n//--------------------------------------\n// inner helper templates prototype\nprivate:\n\ttemplate <typename ResultT, typename ClassT, typename ArgsT, class FncT> struct tMethodCallerImpl;\n\ttemplate <                  typename ClassT, typename ArgsT, class FncT> struct tInstanceFactoryImpl;\n\n\ttemplate <typename T> struct tMethodHasResult;\n\npublic:\n#define FOREACH_INCLUDE \"ncb_foreach.h\"\n#undef  FOREACH_START\n#define FOREACH_START FOREACH_MAX\n#undef  FOREACH_END\n#define FOREACH_END   FOREACH_MAX\n\n#define MARGS_DEF_EXT(n) typename T ## n = void\n#define MARGS_PRM_EXT(n) typename T ## n\n#define MARGS_ARG_EXT(n)          T ## n\n#define MARGS_REF_EXT(n) typedef  T ## n Arg ## n ## Type;\n#undef  FOREACH\n#define FOREACH \\\n\ttemplate <                                   FOREACH_COMMA_EXT(MARGS_DEF_EXT)> struct tMethodArgs { FOREACH_SPACE_EXT(MARGS_REF_EXT) }; \\\n\ttemplate <typename ResultT, typename ClassT, FOREACH_COMMA_EXT(MARGS_DEF_EXT) > \\\n\tstruct tMethodType { typedef typename tMethodResolver<ResultT, ClassT, tMethodArgs<FOREACH_COMMA_EXT(MARGS_ARG_EXT)> >::MethodType Type; };\n#include FOREACH_INCLUDE\n#undef  MARGS_DEF_EXT\n#undef  MARGS_PRM_EXT\n#undef  MARGS_ARG_EXT\n#undef  MARGS_REF_EXT\n\n//--------------------------------------\n// main template\n\n#define MCIMPL_TEMPL tMethodCallerImpl< \\\n\ttypename tMethodTraits<MethodT>::ResultType, \\\n\ttypename tMethodTraits<MethodT>::ClassWithConstType, \\\n\ttypename tMethodTraits<MethodT>::ArgsType, \\\n\tFncT>\n\n\ttemplate <class FncT, typename MethodT>\n\tstatic bool Invoke(FncT io, MethodT const &m) {\n\t\treturn MCIMPL_TEMPL::Invoke(io, m);\n\t}\nprivate:\n//\ttemplate <class FncT, typename MethodT>               static inline bool invokeSelect(FncT io, MethodT const &m, void*)        { return Invoke(io, m); } // for static method\n\ttemplate <class FncT, typename MethodT>               static inline bool invokeSelect(FncT io, MethodT const &m, void*&)       { return Invoke(io, m); } // for static method\n\ttemplate <class FncT, typename MethodT, class ClassT> static inline bool invokeSelect(FncT io, MethodT const &m, ClassT *inst) { return (inst != 0) && MCIMPL_TEMPL::Invoke(io, m, inst); } // for class method\npublic:\n\ttemplate <class FncT, typename MethodT> \n\tstatic bool Invoke(FncT io, MethodT const &m, typename tMethodTraits<MethodT>::ClassWithConstType *inst) {\n\t\treturn invokeSelect(io, m, inst);\n\t}\n\ttemplate <class FncT, typename MethodT>\n\tstatic bool Invoke(FncT io, MethodT const &m, typename tMethodTraits<MethodT>::ClassWithConstType &inst) {\n\t\treturn MCIMPL_TEMPL::Invoke(io, m, &inst);\n\t}\n\ttemplate <class FncT, typename MethodT>\n\tstatic typename tMethodTraits<MethodT>::ClassType * Factory(FncT io, tTypeTag<MethodT>) {\n\t\treturn (tInstanceFactoryImpl<\n\t\t\t\ttypename tMethodTraits<MethodT>::ClassType *, \n\t\t\t\ttypename tMethodTraits<MethodT>::ArgsType,\n\t\t\t\tFncT>::Factory(io));\n\t}\n\ttemplate <class FncT, typename MethodT>\n\tstatic typename tMethodTraits<MethodT>::ResultType Factory(FncT io, MethodT const &m) {\n\t\treturn (tInstanceFactoryImpl<\n\t\t\t\ttypename tMethodTraits<MethodT>::ResultType, \n\t\t\t\ttypename tMethodTraits<MethodT>::ArgsType,\n\t\t\t\tFncT>::Factory(io, m));\n\t}\n\ttemplate <class FncT, typename ClassT, typename ArgsT>\n\tstatic ClassT* Factory(FncT io, tTypeTag<ClassT>, tTypeTag<ArgsT>) {\n\t\treturn (tInstanceFactoryImpl<ClassT*, ArgsT, FncT>::Factory(io));\n\t}\n};\n\n#undef MCIMPL_TEMPL\n#define MC MethodCaller\n\ntemplate <typename T> struct MC::tMethodHasResult       { enum { HasResult = true  }; };\ntemplate <>           struct MC::tMethodHasResult<void> { enum { HasResult = false }; };\n\n//--------------------------------------\n// method {invoker-implement, type-resolver, traits} template specializations (by foreach extraction :D)\n\n#define METHODCALLER_IMPL(res, cls, cnst) \\\n\ttemplate <class FncT         res ## _DEF /**/          cls ## _DEF /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCIMPL_TMPL_ARGS_EXT) >                 \\\n\t\tstruct MC::tMethodCallerImpl<res ## _REF, cnst ## _REF cls ## _REF2, MC::tMethodArgs < FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT) >, FncT > {       \\\n\t\t\ttypedef              res ## _REF              (cls ## _REF           *MethodType)( FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT)) cnst ## _REF;    \\\n\t\t\tstatic inline bool Invoke(FncT io, MethodType const &mptr /**/ cls ## _COMMA /**/ cnst ## _REF /**/ cls ## _INST(inst)) {                    \\\n\t\t\t\t/**/ return      res ## _RESULT(io)      ((cls ## _CALL(inst,mptr)        )(   FOREACH_COMMA_EXT(MCIMPL_READ_ARGS_EXT))) res ## _CLOSE(io); } \\\n\t\t}\n#define INSTANCEFACTORY_IMPL \\\n\ttemplate <class FncT                                 , class ClassT/**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCIMPL_TMPL_ARGS_EXT) >                 \\\n\t\tstruct MC::tInstanceFactoryImpl<                         ClassT*,    MC::tMethodArgs < FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT) >, FncT > {       \\\n\t\t\ttypedef       ClassT*                                               (*MethodType)( FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT));                 \\\n\t\t\tstatic inline ClassT* Factory(FncT io) { (void)io; return new ClassT           (   FOREACH_COMMA_EXT(MCIMPL_READ_ARGS_EXT)); }               \\\n\t\t\tstatic inline ClassT* Factory(FncT io, MethodType const &mptr) { return (*mptr)(   FOREACH_COMMA_EXT(MCIMPL_READ_ARGS_EXT)); }               \\\n\t\t}\n#define METHODRESOLVER_SPECIALIZATION(cls, cnst) \\\n\ttemplate <         typename ResultT /**/               cls ## _DEF /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCIMPL_TMPL_ARGS_EXT) >                     \\\n\t\tstruct MC::tMethodResolver< ResultT,      cnst ## _REF cls ## _REF2, MC::tMethodArgs < FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT) > > {                 \\\n\t\t\ttypedef             ResultT                   (cls ## _REF           *MethodType)( FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT)) cnst ## _REF;        \\\n\t\t\ttypedef MethodType Type; };                                                                                                                      \\\n\ttemplate <         typename ResultT /**/               cls ## _DEF /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCIMPL_TMPL_ARGS_EXT) >                     \\\n\tstruct MC::tMethodTraits<   ResultT                   (cls ## _REF           *          )( FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT)) cnst ## _REF> {      \\\n\t\t\ttypedef             ResultT                   (cls ## _REF           *MethodType)( FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT)) cnst ## _REF;        \\\n\t\t\ttypedef             ResultT                                                                                                  ResultType;         \\\n\t\t\ttypedef                                        cls ## _REF2                                                                  ClassType;          \\\n\t\t\ttypedef                           cnst ## _REF cls ## _REF2                                                                  ClassWithConstType; \\\n\t\t\ttypedef                                                        tMethodArgs<        FOREACH_COMMA_EXT(MCIMPL_METH_ARGS_EXT) > ArgsType;           \\\n\t\t\tenum { HasResult = tMethodHasResult<ResultType>::HasResult, IsStatic = cls ## _BOOL, IsConst = cnst ## _BOOL, ArgsCount = FOREACH_COUNT };       \\\n\t\t}\n\n#define MCIMPL_TMPL_ARGS_EXT(n) typename T ## n\n#define MCIMPL_METH_ARGS_EXT(n) T ## n\n#define MCIMPL_READ_ARGS_EXT(n) io(tNumTag<n>(), tTypeTag<T ## n>())\n\n#define MCIMPL_VOID_DEF\n#define MCIMPL_VOID_REF /*                 */void\n#define MCIMPL_VOID_RESULT(io) /*          */(\n#define MCIMPL_VOID_CLOSE(io) /*           */, io())\n#define MCIMPL_NONVOID_DEF /*              */,typename ResultT\n#define MCIMPL_NONVOID_REF /*              */ResultT\n#define MCIMPL_NONVOID_RESULT(io) /*       */io(\n#define MCIMPL_NONVOID_CLOSE(io) /*        */, tTypeTag<ResultT>())\n\n#define MCIMPL_STATIC_DEF\n#define MCIMPL_STATIC_REF\n#define MCIMPL_STATIC_REF2 /*              */void\n#define MCIMPL_STATIC_BOOL /*              */true\n#define MCIMPL_STATIC_COMMA\n#define MCIMPL_STATIC_INST(inst)\n#define MCIMPL_STATIC_CALL(inst, method) /**/*method\n#define MCIMPL_CLASS_DEF /*                */,class ClassT\n#define MCIMPL_CLASS_REF /*                */ClassT::\n#define MCIMPL_CLASS_REF2 /*               */ClassT\n#define MCIMPL_CLASS_BOOL /*               */false\n#define MCIMPL_CLASS_COMMA /*              */,\n#define MCIMPL_CLASS_INST(inst) /*         */ClassT *inst\n#define MCIMPL_CLASS_CALL(inst,method) /*  */inst->*method\n\n#define MCIMPL_NONCONST_REF\n#define MCIMPL_NONCONST_BOOL /*            */false\n#define MCIMPL_CONST_REF /*                */const\n#define MCIMPL_CONST_BOOL /*               */true\n\n\n#define MAHELP_CONCAT0(a,b) a ## b\n#define MAHELP_CONCAT(a,b) MAHELP_CONCAT0(a,b)\n#define MAHELP_EXT(n) /* templ type */ typedef typename Templ<typename ArgsT::Arg ## n ## Type>::Type T ## n; /* instance */ T ## n  t ## n;\n#define METHODARGSHELPER_IMPL \\\n\ttemplate <template <typename> class Templ, class ArgsT> struct MC::tArgsExtract<Templ, ArgsT, FOREACH_COUNT> { FOREACH_SPACE_EXT(MAHELP_EXT) }; \\\n\ttemplate <class ArgsT>                                  struct MC::tArgsSelect<ArgsT, FOREACH_COUNT> \\\n\t{ static inline typename MAHELP_CONCAT(ArgsT::T,FOREACH_COUNT) &Get(ArgsT &arg) { return MAHELP_CONCAT(arg.t,FOREACH_COUNT); } }\n\n#undef  FOREACH_START\n#define FOREACH_START 0\n#undef  FOREACH_END\n#define FOREACH_END   FOREACH_MAX\n\n#undef  FOREACH\n#define FOREACH \\\n\tMETHODCALLER_IMPL(MCIMPL_VOID,    MCIMPL_STATIC, MCIMPL_NONCONST); \\\n\tMETHODCALLER_IMPL(MCIMPL_NONVOID, MCIMPL_STATIC, MCIMPL_NONCONST); \\\n\tMETHODCALLER_IMPL(MCIMPL_VOID,    MCIMPL_CLASS,  MCIMPL_NONCONST); \\\n\tMETHODCALLER_IMPL(MCIMPL_NONVOID, MCIMPL_CLASS,  MCIMPL_NONCONST); \\\n\tMETHODCALLER_IMPL(MCIMPL_VOID,    MCIMPL_CLASS,  MCIMPL_CONST);    \\\n\tMETHODCALLER_IMPL(MCIMPL_NONVOID, MCIMPL_CLASS,  MCIMPL_CONST);    \\\n\tMETHODRESOLVER_SPECIALIZATION(    MCIMPL_STATIC, MCIMPL_NONCONST); \\\n\tMETHODRESOLVER_SPECIALIZATION(    MCIMPL_CLASS,  MCIMPL_NONCONST); \\\n\tMETHODRESOLVER_SPECIALIZATION(    MCIMPL_CLASS,  MCIMPL_CONST);    \\\n\tINSTANCEFACTORY_IMPL; \\\n\tMETHODARGSHELPER_IMPL;\n#include FOREACH_INCLUDE\n\n#undef MC\n#undef METHODCALLER_IMPL\n#undef INSTANCEFACTORY_IMPL\n#undef METHODRESOLVER_SPECIALIZATION\n\n#undef METHODARGSHELPER_IMPL\n#undef MAHELP_EXT\n\n#undef MCIMPL_TMPL_ARGS_EXT\n#undef MCIMPL_METH_ARGS_EXT\n#undef MCIMPL_READ_ARGS_EXT\n\n#undef MCIMPL_VOID_DEF\n#undef MCIMPL_VOID_REF\n#undef MCIMPL_VOID_RESULT\n#undef MCIMPL_VOID_CLOSE\n#undef MCIMPL_NONVOID_DEF\n#undef MCIMPL_NONVOID_REF\n#undef MCIMPL_NONVOID_RESULT\n#undef MCIMPL_NONVOID_CLOSE\n\n#undef MCIMPL_STATIC_DEF\n#undef MCIMPL_STATIC_REF\n#undef MCIMPL_STATIC_BOOL\n#undef MCIMPL_STATIC_CALL\n#undef MCIMPL_CLASS_DEF\n#undef MCIMPL_CLASS_REF\n#undef MCIMPL_CLASS_BOOL\n#undef MCIMPL_CLASS_CALL\n\n#undef MCIMPL_NONCONST_REF\n#undef MCIMPL_NONCONST_BOOL\n#undef MCIMPL_CONST_REF\n#undef MCIMPL_CONST_BOOL\n\n\n#define MCCAST_20(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>::Type>(MM)\n#define MCCAST_19(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19     ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19     >::Type>(MM)\n#define MCCAST_18(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18          ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18          >::Type>(MM)\n#define MCCAST_17(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17               ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17               >::Type>(MM)\n#define MCCAST_16(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16                    ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16                    >::Type>(MM)\n#define MCCAST_15(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15                         ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15                         >::Type>(MM)\n#define MCCAST_14(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14                              ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14                              >::Type>(MM)\n#define MCCAST_13(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13                                   ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13                                   >::Type>(MM)\n#define MCCAST_12(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12                                        ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12                                        >::Type>(MM)\n#define MCCAST_11(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11                                             ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11                                             >::Type>(MM)\n#define MCCAST_10(MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10                                                  ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10                                                  >::Type>(MM)\n#define MCCAST_9( MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9                                                       ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8, T9                                                       >::Type>(MM)\n#define MCCAST_8( MM, MR, MC, T1, T2, T3, T4, T5, T6, T7, T8                                                           ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7, T8                                                           >::Type>(MM)\n#define MCCAST_7( MM, MR, MC, T1, T2, T3, T4, T5, T6, T7                                                               ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6, T7                                                               >::Type>(MM)\n#define MCCAST_6( MM, MR, MC, T1, T2, T3, T4, T5, T6                                                                   ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5, T6                                                                   >::Type>(MM)\n#define MCCAST_5( MM, MR, MC, T1, T2, T3, T4, T5                                                                       ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4, T5                                                                       >::Type>(MM)\n#define MCCAST_4( MM, MR, MC, T1, T2, T3, T4                                                                           ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3, T4                                                                           >::Type>(MM)\n#define MCCAST_3( MM, MR, MC, T1, T2, T3                                                                               ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2, T3                                                                               >::Type>(MM)\n#define MCCAST_2( MM, MR, MC, T1, T2                                                                                   ) static_cast<MethodCaller::tMethodType<MR, MC, T1, T2                                                                                   >::Type>(MM)\n#define MCCAST_1( MM, MR, MC, T1                                                                                       ) static_cast<MethodCaller::tMethodType<MR, MC, T1                                                                                       >::Type>(MM)\n#define MCCAST_0( MM, MR, MC                                                                                           ) static_cast<MethodCaller::tMethodType<MR, MC                                                                                           >::Type>(MM)\n\n\n#undef  FOREACH_START\n#define FOREACH_START 0\n#undef  FOREACH_END\n#define FOREACH_END   FOREACH_MAX\n#define MCAST_PRM_EXT(n) typename T ## n\n#define MCAST_ARG_EXT(n)          T ## n\n#undef  FOREACH\n#define FOREACH \\\n\ttemplate <             typename ResultT, typename ClassT /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCAST_PRM_EXT) > \\\n\t\tstatic inline   typename MethodCaller::tMethodType<ResultT, ClassT /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCAST_ARG_EXT)>::Type \\\n\t\t\tmethod_cast(typename MethodCaller::tMethodType<ResultT, ClassT /**/ FOREACH_COMMA /**/ FOREACH_COMMA_EXT(MCAST_ARG_EXT)>::Type method) { return method; }\n#include FOREACH_INCLUDE\n#undef  MCAST_PRM_EXT\n#undef  MCAST_ARG_EXT\n\ntemplate <typename T> static inline T method_cast(T method) { return method; }\n\n#endif\n"
  },
  {
    "path": "src/plugins/ncbind/ncbind.cpp",
    "content": "#include \"ncbind.hpp\"\n#include <set>\n\n//---------------------------------------------------------------------------\n// static変数の実体\n\n// auto register 先頭ポインタ\nncbAutoRegister::ThisClassT const*\nncbAutoRegister::_top[ncbAutoRegister::LINE_COUNT] = NCB_INNER_AUTOREGISTER_LINES_INSTANCE;\n\nstd::set<ttstr> TVPRegisteredPlugins;\n\nstd::map<ttstr, ncbAutoRegister::INTERNAL_PLUGIN_LISTS > ncbAutoRegister::_internal_plugins;\n\nbool ncbAutoRegister::LoadModule(const ttstr &_name)\n{\n\tttstr name = _name.AsLowerCase();\n\tif (TVPRegisteredPlugins.find(name) != TVPRegisteredPlugins.end())\n\t\treturn false;\n\tauto it = _internal_plugins.find(name);\n\tif (it != _internal_plugins.end()) {\n\t\tfor (int line = 0; line < ncbAutoRegister::LINE_COUNT; ++line) {\n\t\t\tconst std::list<ncbAutoRegister const*> &plugin_list = it->second.lists[line];\n\t\t\tfor (auto i = plugin_list.begin(); i != plugin_list.end(); ++i) {\n\t\t\t\t(*i)->Regist();\n\t\t\t}\n\t\t}\n\t\tTVPRegisteredPlugins.insert(name);\n\t\treturn true;\n\t}\n\treturn false;\n}"
  },
  {
    "path": "src/plugins/ncbind/ncbind.hpp",
    "content": "#ifndef _ncbind_hpp_\n#define _ncbind_hpp_\n\n#include \"PluginStub.h\"\n#include \"ncb_invoke.hpp\"\n#include <map>\n#include <list>\n\n////////////////////////////////////////\n// ログ出力用マクロ\n\n#define NCB_WARN(n)     TVPAddLog(ttstr(n))\n#define NCB_WARN_2(a,b) TVPAddLog(ttstr(a) + ttstr(b))\n#define NCB_WARN_W(str) NCB_WARN(TJS_W(str))\n\n#if (defined(DEBUG) || defined(_DEBUG))\n#define NCB_LOG(n)     NCB_WARN(n)\n#define NCB_LOG_2(a,b) NCB_WARN_2(a,b)\n#define NCB_LOG_W(str) NCB_WARN_W(str)\n#else\n#define NCB_LOG_VOID   ((void)0)\n#define NCB_LOG(n)     NCB_LOG_VOID\n#define NCB_LOG_2(a,b) NCB_LOG_VOID\n#define NCB_LOG_W(str) NCB_LOG_VOID\n#endif\n\n\n////////////////////////////////////////\n// 共通型定義\nstruct ncbTypedefs {\n\ttypedef tjs_char const*           NameT;\n\ttypedef tjs_uint32                FlagsT;\n\ttypedef tjs_int32                 IdentT;\n\n\ttypedef MethodCaller              CallerT;\n\ttypedef tTJSNativeInstanceType    InstanceTypeT;\n\ttypedef tTJSNativeClassForPlugin  ClassObjectT;\n\n\t/// 型の受け渡しで使用\n\ttemplate <typename T> struct Tag { typedef T Type; };\n\n\t/// 場合わけで使用\n\ttemplate <int  N> struct NumTag  { enum { n = N }; };\n\ttemplate <bool B> struct BoolTag { enum { b = B }; };\n\n\t// tTJSVariant::Type() ラッパ (ここでいいのか微妙だけど)\n\tstatic inline tTJSVariantType GetVariantType(tTJSVariant const &var) { return (const_cast<tTJSVariant*>(&var))->Type(); }\n//\tstatic inline tTJSVariantType GetVariantType(tTJSVariant &var)       { return var.Type(); }\n\n\t// コールバック型\n\ttypedef tTJSNativeClassMethodCallback CallbackT;\n\n\t// インスタンスに変換して渡すコールバック\n\ttemplate <class T> \n\tstruct CallbackWithInstance {\n\t\ttypedef tjs_error (TJS_INTF_METHOD    *Type)(tTJSVariant *result, tjs_int numparams, tTJSVariant **param, T *nativeInstance);\n\t};\n\n\ttemplate <typename A, typename B> struct TypeEqual       { enum { NotEqual, Result = false }; };\n\ttemplate <typename A>             struct TypeEqual<A, A> { enum {    Equal, Result = true  }; };\n\ttemplate <bool F, int A,      int B>      struct IntSelect              { enum { Result = B }; };\n\ttemplate <        int A,      int B>      struct IntSelect< true, A, B> { enum { Result = A }; };\n\ttemplate <bool F, typename A, typename B> struct TypeSelect             { typedef B Result; };\n\ttemplate <        typename A, typename B> struct TypeSelect<true, A, B> { typedef A Result; };\n\ttemplate <bool F, typename ERR> struct TypeAssert            { typedef void Result; };\n\ttemplate <        typename ERR> struct TypeAssert<true, ERR> { typedef typename ERR::CompileError Result; };\n};\n\n/// サブクラスフラグ\ntemplate <class T>\nstruct ncbSubClassCheck { enum { IsSubClass = false }; };\n\n////////////////////////////////////////\n/// NativeClass 名前/ID/クラスオブジェクト保持用\ntemplate <class T>\nstruct ncbClassInfo {\n\ttypedef T NativeClassT;\n\n\ttypedef ncbTypedefs::NameT        NameT;\n\ttypedef ncbTypedefs::IdentT       IdentT;\n\ttypedef ncbTypedefs::ClassObjectT ClassObjectT;\n\n\t/// プロパティ取得\n\tstatic inline NameT         GetName()        { return _info.name; }\n\tstatic inline IdentT        GetID()          { return _info.id; }\n\tstatic inline ClassObjectT *GetClassObject() { return _info.obj; }\n\tstatic inline bool          IsSubClass()     { return ncbSubClassCheck<NativeClassT>::IsSubClass; }\n\n\t/// イニシャライザ\n\tstatic inline bool Set(NameT name, IdentT id, ClassObjectT *obj) {\n\t\tif (_info.initialized) return false;\n\t\t_info.name = name;\n\t\t_info.id   = id;\n\t\t_info.obj  = obj;\n\t\treturn (_info.initialized = true);\n\t}\n\t/// 再初期化\n\tstatic inline void Clear() {\n\t\t_info.name = 0;\n\t\t_info.id   = 0;\n\t\t_info.obj  = 0;\n\t\t_info.initialized = false;\n\t}\nprivate:\n\ttypedef struct info {\n\t\tinfo() : initialized(false), name(0), id(0), obj(0) {}\n\n\t\tbool initialized;\n\t\tNameT name;\n\t\tIdentT id;\n\t\tClassObjectT *obj;\n\t} InfoT;\n\tstatic InfoT _info;\n};\ntemplate <> struct ncbClassInfo<void> {};\ntemplate <class T> typename ncbClassInfo<T>::InfoT ncbClassInfo<T>::_info;\n\n\n////////////////////////////////////////\n/// インスタンスアダプタ\ntemplate <class T>\nstruct ncbInstanceAdaptor : public tTJSNativeInstance {\n\ttypedef T NativeClassT;\n\ttypedef ncbInstanceAdaptor<NativeClassT> AdaptorT;\n\ttypedef ncbClassInfo<NativeClassT>       ClassInfoT;\n\n\t/*constructor*/ ncbInstanceAdaptor() : _instance(0), _sticky(false) {}\n\t/*destructor*/ ~ncbInstanceAdaptor() { _deleteInstance(); }\n\n\t// TJS2 オブジェクトが作成されるときに呼ばれる\n\t//tjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj);\n\t// …のだが，TJS_BEGIN_NATIVE_CONSTRUCTOR マクロから呼ばれるので\n\t// 上記マクロを使用せずに独自実装しているここでは使用しない(⇒ncbNativeClassConstructor)\n\n\t/// オブジェクトが無効化されるときに呼ばれる\n\tvoid TJS_INTF_METHOD Invalidate() { _deleteInstance(); }\n\nprivate:\n\t/// 実インスタンスへのポインタ\n\tNativeClassT *_instance;\n\n\t/// deleteしないフラグ\n\tbool _sticky;\n\n\t/// 実インスタンス破棄\n\tvoid _deleteInstance() {\n\t\tif (_instance && !_sticky) delete _instance;\n\t\t_instance = 0;\n\t\t_sticky   = false;\n\t}\n\npublic:\n\tvoid setSticky() { _sticky = true; }\n\n\t//--------------------------------------\n\t// staticヘルパ関数\n\n\t/// iTJSDispatch2 から Adaptor を取得\n\tstatic AdaptorT *GetAdaptor(iTJSDispatch2 *obj, bool err = false) {\n\t\tiTJSNativeInstance* adp = 0;\n\t\tif (!obj) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"No instance.\"));\n\t\t\treturn 0;\n\t\t}\n\t\tif (TJS_FAILED(obj->NativeInstanceSupport(TJS_NIS_GETINSTANCE, ClassInfoT::GetID(), &adp))) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"Invalid instance type.\"));\n\t\t\treturn 0;\n\t\t}\n\t\treturn static_cast<AdaptorT*>(adp);\n\t}\n\n\t/// iTJSDispatch2 から NativeClassインスタンスを取得\n\tstatic NativeClassT *GetNativeInstance(iTJSDispatch2 *obj, bool err = false) {\n\t\tAdaptorT *adp = GetAdaptor(obj, err);\n\t\treturn adp ? adp->_instance : 0;\n\t}\n\n\t/// NativeClassインスタンスを設定\n\tstatic bool SetNativeInstance(iTJSDispatch2 *obj, NativeClassT *instance, bool err = false) {\n\t\tAdaptorT *adp = GetAdaptor(obj, err);\n\t\tif (!adp) return false;\n\t\tadp->_instance = instance;\n\t\treturn true;\n\t}\n\n\t/// アダプタを生成しつつNativeClassインスタンスを設定\n\tstatic bool SetAdaptorWithNativeInstance(iTJSDispatch2 *obj, NativeClassT *instance, bool err = false) {\n\t\tAdaptorT *adp = GetAdaptor(obj, false);\n\t\tif (adp) {\n\t\t\tif (adp->_instance) adp->_deleteInstance();\n\t\t} else if (!(adp = new AdaptorT())) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"Create adaptor failed.\"));\n\t\t\treturn false;\n\t\t}\n\t\tadp->_instance = instance;\n\t\tiTJSNativeInstance *ni = static_cast<iTJSNativeInstance*>(adp);\n\t\tif (TJS_FAILED(obj->NativeInstanceSupport(TJS_NIS_REGISTER, ClassInfoT::GetID(), &ni))) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"Adaptor registration failed.\"));\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/// クラスオブジェクトからAdaptorインスタンスを生成してinstanceを代入\n\tstatic iTJSDispatch2* CreateAdaptor(NativeClassT *inst, bool sticky = false, bool err = false) {\n\t\ttypename ClassInfoT::ClassObjectT *clsobj = ClassInfoT::GetClassObject();\n\t\tif (!clsobj) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"No class object.\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\tiTJSDispatch2 *global = TVPGetScriptDispatch(), *obj = 0;\n\t\ttTJSVariant dummy, *param = &dummy;\n\t\t// 引数が1つでかつvoidであれば実インスタンスをnewしない動作になる\n\t\ttjs_error r = clsobj->CreateNew(0, 0, 0, &obj, 1, &param, global);\n\t\tif (global) global->Release();\n\n\t\tif (TJS_FAILED(r) || !obj) {\n\t\t\tif (err) TVPThrowExceptionMessage(TJS_W(\"Can't create instance\"));\n\t\t\treturn 0;\n\t\t}\n\t\tAdaptorT *adp = GetAdaptor(obj, err);\n\t\tif (adp) {\n\t\t\tadp->_instance = inst;\n\t\t\tif (sticky) adp->setSticky();\n\t\t}\n\t\treturn obj;\n\t}\n\n\t/// 空の Adaptor を生成する (tTJSNativeClassForPlugin型の関数)\n\tstatic iTJSNativeInstance* TJS_INTF_METHOD CreateEmptyAdaptor() {\n\t\treturn static_cast<iTJSNativeInstance*>(new AdaptorT());\n\t}\n};\n\n////////////////////////////////////////\n/// 型変換用ヘルパテンプレート\nstruct ncbTypeConvertor {\n\n\t/// FROM から TO へ変換できるか\n\ttemplate <typename FROM, typename TO>\n\tstruct Conversion {\n\tprivate:\n\t\ttypedef char OK;\n\t\ttypedef struct { char ng[2]; } NG;\n\t\tstatic OK check(TO);\n\t\tstatic NG check(...);\n\t\tstatic FROM wrap();\n\tpublic:\n\t\tenum {\n\t\t\tExists = (sizeof(check(wrap())) == sizeof(OK)),\n\t\t\tSame   = false\n\t\t};\n\t};\n\ttemplate <typename T> struct Conversion<T, T>       { enum { Exists = true,  Same = true  }; };\n\ttemplate <typename T> struct Conversion<T, void>    { enum { Exists = false, Same = false }; };\n\ttemplate <typename T> struct Conversion<void, T>    { enum { Exists = false, Same = false }; };\n//\ttemplate <>           struct Conversion<void, void> { enum { Exists = false, Same = true  }; };\n#define NCB_INNER_CONVERSION_SPECIALIZATION \\\n\ttemplate <> struct ncbTypeConvertor::Conversion<void, void> { enum { Exists = false, Same = true  }; };\n\n\t/// 修飾子取り外し(ポインタ，参照，const等を外した素の型が typedef される)\n\ttemplate <typename T> struct Stripper             { typedef T Type; };\n\ttemplate <typename T> struct Stripper<T*>         { typedef typename Stripper<T>::Type Type; };\n\ttemplate <typename T> struct Stripper<T&>         { typedef typename Stripper<T>::Type Type; };\n\ttemplate <typename T> struct Stripper<const    T> { typedef typename Stripper<T>::Type Type; };\n//\ttemplate <typename T> struct Stripper<volatile T> { typedef typename Stripper<T>::Type Type; };\n\n\t/// ポインタ取得\n\ttemplate <typename T> struct ToPointer            { static T* Get(T &t) { return &t; } };\n\ttemplate <typename T> struct ToPointer<T&>        { static T* Get(T &t) { return &t; } };\n\ttemplate <typename T> struct ToPointer<T*>        { static T* Get(T* t) { return  t; } };\n\ttemplate <typename T> struct ToPointer<T const&>  { static T* Get(T const &t) { return const_cast<T*>(&t); } };\n\ttemplate <typename T> struct ToPointer<T const*>  { static T* Get(T const *t) { return const_cast<T*>( t); } };\n\n\t/// ポインタ⇒修飾子変換\n\ttemplate <typename T> struct ToTarget             { static T& Get(T *t) { return *t; } };\n\ttemplate <typename T> struct ToTarget<T&>         { static T& Get(T *t) { return *t; } };\n\ttemplate <typename T> struct ToTarget<T*>         { static T* Get(T *t) { return  t; } };\n\n\t/// const外し\n\ttemplate <typename T> struct NonConst             { typedef T  Type; };\n\ttemplate <typename T> struct NonConst<const T>    { typedef T  Type; };\n\ttemplate <typename T> struct NonConst<const T&>   { typedef T& Type; };\n\ttemplate <typename T> struct NonConst<const T*>   { typedef T* Type; };\n\n\t/// reference 外し\n\ttemplate <typename T> struct NonReference         { typedef T Type; };\n\ttemplate <typename T> struct NonReference<T&>     { typedef T Type; };\n\n\t// 直コピー動作\n\tstruct DirectCopy {\n\t\ttemplate <typename DST, typename SRC>\n\t\tinline void operator()(DST &dst, SRC const &src) const { dst = src; }\n\t};\n\n\t// キャスト動作\n\ttemplate <typename CAST>\n\tstruct CastCopy {\n\t\ttemplate <typename DST, typename SRC>\n\t\tinline void operator()(DST &dst, SRC const &src) const { dst = static_cast<DST>(static_cast<CAST>(src)); }\n\t};\n\n\t// 型特殊化が存在するかのマップ用\n\ttemplate <typename T, bool SRCF>\n\tstruct SpecialMap {\n\t\tenum { Exists = false, Modifier = false, IsSource = SRCF };\n\t\ttypedef T Type;\n\t};\n\n\t/// 動作未定（コンパイルエラー用）\n\tstruct NCB_COMPILE_ERROR_NoImplement;\n\n\t// コンバータ動作選択\n\tstruct SelectConvertorTypeBase {\n\tprotected:\n\t\t/// ３項演算子\n\t\ttemplate <bool EXP, class THEN, class ELSE> struct ifelse                   { typedef ELSE Type; };\n\t\ttemplate <          class THEN, class ELSE> struct ifelse<true, THEN, ELSE> { typedef THEN Type; };\n\n\t\t/// 特殊化が存在するか調べるテンプレート\n\t\ttemplate <typename T, bool IsSrcF>\n\t\tstruct hasSpecial {\n\t\t\ttypedef typename Stripper<T>::Type StripT;\n\t\t\ttypedef SpecialMap<T,      IsSrcF> ThisMapT;\n\t\t\ttypedef SpecialMap<StripT, IsSrcF> StripMapT;\n\t\t\tenum {\n\t\t\t\texthis  = ThisMapT::Exists,\n\t\t\t\texstrip = StripMapT::Exists && StripMapT::Modifier,\n\t\t\t\tExists = exthis | exstrip,\n\t\t\t};\n\t\t\ttypedef typename ifelse<exthis,  typename ThisMapT::Type,\n\t\t\t/*    */typename ifelse<exstrip, typename StripMapT::Type, void>::Type\n\t\t\t\t/*                */>::Type Type;\n\t\t};\n\t\ttemplate <typename T> struct wrap { typedef T Type; };\n\n\t\ttemplate <typename SRC, typename DST>\n\t\tstruct directSelect {\n\t\t\ttypedef typename ifelse<Conversion<SRC, DST>::Exists, DirectCopy, NCB_COMPILE_ERROR_NoImplement>::Type Type;\n\t\t};\n\t};\n\n\t/// コンバータのタイプを調べる\n\ttemplate <typename SRC, typename DST>\n\tstruct SelectConvertorType : public SelectConvertorTypeBase {\n\tprivate:\n\t\ttypedef hasSpecial<SRC, true > SrcSpecialT;\n\t\ttypedef hasSpecial<DST, false> DstSpecialT;\n\n\t\tstruct specialSelect {\n\t\t\ttypedef typename ifelse<DstSpecialT::Exists, typename DstSpecialT::Type, typename SrcSpecialT::Type>::Type Type;\n\t\t};\n\t\ttypedef typename ifelse<\n\t\t\tSrcSpecialT::Exists || DstSpecialT::Exists, specialSelect, directSelect<SRC, DST>\n\t\t\t\t>::Type select;\n\tpublic:\n\t\ttypedef typename select::Type Type;\n\t};\n};\n// ncbTypeConvertor::Conversion の特殊化\n       NCB_INNER_CONVERSION_SPECIALIZATION\n#undef NCB_INNER_CONVERSION_SPECIALIZATION\n\n//--------------------------------------\n/// 返り値の型を正確に取りたい場合，コンバータはこれを継承する\nstruct ncbStrictResultConvertor {};\n\n//--------------------------------------\n// TypeConvertor関連の各種マクロ\n\n/// SpecialMap に登録するマクロ\n#define NCB_TYPECONV_MAPSET(mapsel, type, conv, mod) \\\n\ttemplate <> struct ncbTypeConvertor::SpecialMap<type, mapsel> { \\\n\t\tenum { Exists = true, Modifier = mod, IsSource = mapsel }; \\\n\t\ttypedef conv Type; \\\n\t}\n#define NCB_TYPECONV_SRCMAP_SET(type, conv, mod) NCB_TYPECONV_MAPSET(true,  type, conv, mod)\n#define NCB_TYPECONV_DSTMAP_SET(type, conv, mod) NCB_TYPECONV_MAPSET(false, type, conv, mod)\n\n/// DirectCopy動作としてマップに登録\n#define NCB_TYPECONV_DIRECT(type) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbTypeConvertor::DirectCopy, false); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbTypeConvertor::DirectCopy, false)\n\n/// Cast動作としてマップに登録\n#define NCB_TYPECONV_CAST(type, cast) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbTypeConvertor::CastCopy<cast>, false); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbTypeConvertor::CastCopy<cast>, false)\n\n/// 数値キャストで登録\n#define NCB_TYPECONV_CAST_INTEGER(type)    NCB_TYPECONV_CAST(type, tTVInteger)\n#define NCB_TYPECONV_CAST_REAL(type)       NCB_TYPECONV_CAST(type, tTVReal)\n\n/// 数値はキャストで変換する\nNCB_TYPECONV_CAST_INTEGER(   signed char);\nNCB_TYPECONV_CAST_INTEGER( unsigned char);\nNCB_TYPECONV_CAST_INTEGER(signed int);\nNCB_TYPECONV_CAST_INTEGER(unsigned int);\nNCB_TYPECONV_CAST_INTEGER(  signed short);\nNCB_TYPECONV_CAST_INTEGER(unsigned short);\nNCB_TYPECONV_CAST_INTEGER(signed long);\nNCB_TYPECONV_CAST_INTEGER(unsigned long);\nNCB_TYPECONV_CAST_REAL(            float);\nNCB_TYPECONV_CAST_REAL(           double);\nNCB_TYPECONV_CAST(            bool, bool);\n\n// ナロー文字変換\nstruct ncbNarrowCharConvertor {\n\t/// 一時的にバッファを確保してそこに NarrowStr として書き込む\n\tstruct ToNChar {\n\t\t/// Constructor (メソッドが呼ばれる前)\n\t\tToNChar() : _nstr(0) {}\n\t\t/// Destructor (メソッドが呼ばれた後)\n\t\t~ToNChar() {\n\t\t\tif (_nstr) {\n\t\t\t\t//\t\t\t\tNCB_LOG_W(\"~ncbVariatToNChar > delete[]\");\n\t\t\t\tdelete[] _nstr;\n\t\t\t}\n\t\t}\n\t\t/// 引き数を受け渡すためのファンクタ\n\t\ttemplate <typename DST>\n\t\tinline void operator()(DST &dst, tTJSVariant const &src) {\n\t\t\tif (ncbTypedefs::GetVariantType(src) == tvtString) {\n\t\t\t\ttTJSString s(src.AsStringNoAddRef());\n\t\t\t\ttjs_int len = s.GetNarrowStrLen();\n\n//\t\t\t\tNCB_LOG_W(\"ncbVariatToNChar::operator() > new tjs_nchar[]\");\n\t\t\t\t_nstr = new tjs_nchar[len+1];\n\t\t\t\ts.ToNarrowStr(_nstr, len+1);\n\t\t\t}\n\t\t\tdst = static_cast<DST>(_nstr);\n\t\t}\n\tprivate:\n\t\ttjs_nchar *_nstr;\n\t};\n\tstruct ToVariant {\n\t\ttemplate <typename SRC>\n\t\tinline void operator()(tTJSVariant &dst, SRC const &src) const {\n//\t\t\tNCB_LOG_2(\"ncbNCharToVariatTo::operator() : \", src);\n\t\t\tdst = tTJSString(src);\n\t\t}\n\t};\n};\n// Narrow文字列として登録するマクロ\n#define NCB_TYPECONV_NARROW_STRING(type) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbNarrowCharConvertor::ToVariant, false); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbNarrowCharConvertor::ToNChar,   false)\n\n/// signed char と char って別物なのかすら？\nNCB_TYPECONV_NARROW_STRING(         char const*);\nNCB_TYPECONV_NARROW_STRING(  signed char const*);\nNCB_TYPECONV_NARROW_STRING(unsigned char const*);\n\n// ワイド文字変換\nstruct ncbWideCharConvertor {\n\tstruct ToWChar {\n\t\ttemplate <typename DST>\n\t\tinline void operator()(DST &dst, tTJSVariant const &src) {\n\t\t\tdst = static_cast<DST>(src.GetString());\n\t\t}\n\t};\n};\n// Wide文字列として登録するマクロ\n#define NCB_TYPECONV_WIDE_STRING(type) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbTypeConvertor::CastCopy<tjs_char const*>, false); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbWideCharConvertor::ToWChar,               false)\n\nNCB_TYPECONV_WIDE_STRING(tjs_char const*);\n\n\n/// std::stringなどを c_str() で受け渡す\ntemplate <class StringT>\nstruct ncbStringConvertor {\n\ttypedef ncbTypedefs      DefsT;\n\ttypedef ncbTypeConvertor ConvT;\n\ttypedef DefsT::NumTag<sizeof(typename StringT::value_type)> SizeTagT;\n\n\ttemplate <class STR>\n\tinline void operator()(tTJSVariant &dst, STR const &src) const {\n\t\tdst = (ConvT::ToPointer<STR const&>::Get(src))->c_str();\n\t}\n\ttemplate <class STR>\n\tinline void operator()(STR &dst, tTJSVariant const &src) {\n\t\tif (ncbTypedefs::GetVariantType(src) == tvtString) {\n\t\t\ttTJSString str(src.AsStringNoAddRef());\n\t\t\tset(str, SizeTagT());\n\t\t}\n\t\tdst = ConvT::ToTarget<STR>::Get(&_temp);\n\t}\n\tinline void set(tTJSString const &str, DefsT::NumTag<sizeof(tjs_nchar)>) { // for Narrow char\n\t\ttjs_int len = str.GetNarrowStrLen();\n\t\ttjs_nchar tmp[len+1];\n\t\tstr.ToNarrowStr(tmp, len+1);\n\t\t_temp.assign(tmp, len);\n\t}\n\tinline void set(tTJSString const &str, DefsT::NumTag<sizeof(tjs_char)>) { // for Wide char\n\t\t_temp = str.c_str();\n\t}\nprivate:\n\tStringT _temp;\n};\n#define NCB_TYPECONV_STL_STRING(type) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbStringConvertor<type>, true); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbStringConvertor<type>, true)\n\n\n/// ネイティブインスタンスアダプタで Boxing/Unboxing する\nstruct ncbNativeObjectBoxing {\n\ttypedef tTJSVariant VarT;\n\ttypedef ncbTypeConvertor ConvT;\n\t/// Boxing\n\tstruct Boxing : public ncbStrictResultConvertor {\n\t\ttemplate <typename T> struct box            { static T* Get(T const &t) { return           new T(t); } enum { Sticky = false }; };\n\t\ttemplate <typename T> struct box<T&>        { static T* Get(T       &t) { return                &t ; } enum { Sticky = true  }; };\n\t\ttemplate <typename T> struct box<T const&>  { static T* Get(T const &t) { return const_cast<T*>(&t); } enum { Sticky = true  }; };\n\t\ttemplate <typename T> struct box<T*>        { static T* Get(T       *t) { return                 t ; } enum { Sticky = false }; };\n\t\ttemplate <typename T> struct box<T const*>  { static T* Get(T const *t) { return const_cast<T*>( t); } enum { Sticky = false }; };\n\n\t\ttemplate <typename SRC>\n\t\tinline void operator ()(VarT &dst, SRC src, ncbTypedefs::Tag<SRC> const&) const {\n\t\t\ttypedef SRC                                     TargetT;\n\t\t\ttypedef typename ConvT::Stripper<TargetT>::Type ClassT;\n\t\t\ttypedef ncbInstanceAdaptor<ClassT>              AdaptorT;\n\n\t\t\tClassT *p = box<TargetT>::Get(src);\t\t\t\t\t\t//< コピー/参照/ポインタ場合分け\n\t\t\tbool const s = box<TargetT>::Sticky;\t\t\t\t\t//< sticky フラグ\n\t\t\tiTJSDispatch2 *adpobj = AdaptorT::CreateAdaptor(p, s);\t//< アダプタTJSオブジェクト生成\n\t\t\tdst = tTJSVariant(adpobj, adpobj);\t\t\t\t\t\t//< Variantにコピー\n\t\t\tadpobj->Release();\t\t\t\t\t\t\t\t\t\t//< コピー済みなのでadaptorは不要\n\t\t}\n\n\t\t// for reference\n\t\ttemplate <typename SRC>\n\t\tinline void operator ()(VarT &dst, SRC &src, ncbTypedefs::Tag<SRC&> const &tag) const {\n\t\t\toperator()<SRC&> (dst, src, tag);\n\t\t}\n\t};\n\n\t/// Unboxing\n\tstruct Unboxing {\n\t\ttemplate <typename DST>\n\t\tinline void operator ()(DST &dst, VarT const &src) const {\n\t\t\ttypedef DST                                     TargetT;\n\t\t\ttypedef typename ConvT::Stripper<TargetT>::Type ClassT;\n\t\t\ttypedef ncbInstanceAdaptor<ClassT>              AdaptorT;\n\n\t\t\tiTJSDispatch2 *obj = src.AsObjectNoAddRef();\t\t\t//< 参照カウンタ増加なしでDispatchオブジェクト取得\n\t\t\tClassT *p = AdaptorT::GetNativeInstance(obj, true);\t\t//< 実インスタンスのポインタを取得\n\t\t\tdst = ConvT::ToTarget<TargetT>::Get(p);\t\t\t\t\t//< 必要とされる型に変換して返す\n\t\t}\n\t};\n};\n\n/// ボックス化する型として登録するマクロ\n#define NCB_TYPECONV_BOXING(type) \\\n\tNCB_TYPECONV_SRCMAP_SET(type, ncbNativeObjectBoxing::Boxing,   true); \\\n\tNCB_TYPECONV_DSTMAP_SET(type, ncbNativeObjectBoxing::Unboxing, true)\n\n\n\n/// 特殊化用のマクロ (自動変換でなく直で指定する場合はこのマクロを使用する)\n#define NCB_SET_TOVARIANT_CONVERTOR(type, convertor) \\\n\ttemplate <> struct ncbTypeConvertor::SelectConvertorType<type, tTJSVariant> { typedef convertor Type; }\n\n#define NCB_SET_TOVALUE_CONVERTOR(type, convertor) \\\n\ttemplate <> struct ncbTypeConvertor::SelectConvertorType<tTJSVariant, type> { typedef convertor Type; }\n\n#define NCB_SET_CONVERTOR(type, convertor) \\\n\tNCB_SET_TOVARIANT_CONVERTOR(type, convertor); \\\n\tNCB_SET_TOVALUE_CONVERTOR(  type, convertor) \\\n\n/// 返り値なしの場合のダミーの TOVARIANT を登録\nNCB_SET_TOVARIANT_CONVERTOR(void, struct {});\n\n// iTJSDispatch2*を引き数・返り値にする場合\nstruct ncbDispatchConvertor {\n\tinline void operator ()(tTJSVariant &dst, iTJSDispatch2* &src) const {\n\t\tdst = tTJSVariant(src, src);\n\t\tsrc->Release();\n\t}\n\tinline void operator ()(iTJSDispatch2* &dst, tTJSVariant const &src) const {\n\t\tdst = src.AsObjectNoAddRef();\n\t}\n\tinline void operator ()(iTJSDispatch2 const* &dst, tTJSVariant const &src) const {\n\t\tdst = src.AsObjectNoAddRef();\n\t}\n};\nNCB_SET_TOVARIANT_CONVERTOR(iTJSDispatch2*,       ncbDispatchConvertor);\nNCB_SET_TOVALUE_CONVERTOR(  iTJSDispatch2*,       ncbDispatchConvertor);\nNCB_SET_TOVALUE_CONVERTOR(  iTJSDispatch2 const*, ncbDispatchConvertor);\n\n\n/*\n\t型変換を直で書きたい時は\n\n\tstruct CustomType; // 変換する対象の型\n\tstruct CustomConvertor { // コンバータ\n\t\tvoid operator ()(tTJSVariant &dst, CustomType const &src);\n\t\tvoid operator ()(CustomType const &src, tTJSVariant &dst);\n\t};\n\tNCB_SET_CONVERTOR(CustomType, CustomConvertor);\n\tといったような感じで適当に\n */\n\n// Dicionary/Array 向けラッパ(手抜き実装)\nstruct ncbPropAccessor {\n\ttypedef ncbTypedefs   DefsT;\n\ttypedef DefsT::NameT  NameT;\n\ttypedef DefsT::FlagsT FlagsT;\n\ttypedef DefsT::NameT  KeyT;\n\ttypedef tjs_int32     IndexT;\n\ttypedef tjs_int       CountT;\n\ttypedef tjs_uint32    SizeT;\n\ttypedef tjs_error     ErrorT;\n\ttypedef tjs_uint32*   HintT;\n\ttypedef tTJSVariant   VariantT;\n\n\tncbPropAccessor(iTJSDispatch2 *obj, bool addref = true) : _obj(obj) {\n\t\tif (addref) _obj->AddRef();\n\t}\n\tncbPropAccessor(ncbPropAccessor const &ref) : _obj(ref._obj) { _obj->AddRef(); }\n\tncbPropAccessor(tTJSVariant var) : _obj(var.AsObject()) {\n\t\t//_obj->AddRef();\n\t}\n    ncbPropAccessor(NameT name) {\n\t    tTJSVariant val;\n\t    iTJSDispatch2 *global = TVPGetScriptDispatch();\n\t    if (global) {\n\t        global->PropGet(0, name, 0, &val, global);\n\t\t}\n\t    _obj = val.AsObject();\n\t}\n\tvirtual ~ncbPropAccessor() {\n\t    if (_obj) {\n\t\t    _obj->Release();\n\t\t}\n\t}\n\tCountT GetCount() const {\n\t\tCountT sz;\n\t\tErrorT r = _obj->GetCount(&sz, 0, 0, _obj);\n\t\treturn (r == TJS_S_OK) ? sz : 0;\n\t}\n\tCountT GetArrayCount() const {\n\t\tVariantT var;\n\t\t_obj->PropGet(0, TJS_W(\"count\"), 0, &var, _obj);\n\t\treturn (CountT)var;\n\t}\n\ttemplate <typename TargetT>\n\tTargetT GetValue(IndexT ofs, DefsT::Tag<TargetT> const &tag, FlagsT f = 0) {\n\t\tVariantT var;\n\t\t_obj->PropGetByNum(f, ofs, &var, _obj);\n\t\treturn _toTarget(var, tag);\n\t}\n\ttemplate <typename TargetT>\n\tTargetT GetValue(iTJSDispatch2 *obj, IndexT ofs, DefsT::Tag<TargetT> const &tag, FlagsT f = 0) {\n\t\tVariantT var;\n\t\t_obj->PropGetByNum(f, ofs, &var, obj);\n\t\treturn _toTarget(var, tag);\n\t}\n\ttjs_int getIntValue(IndexT ofs, tjs_int defaultValue=0) {\n\t\tif (HasValue(ofs)) {\n\t\t\treturn GetValue(ofs, DefsT::Tag<tjs_int>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\ttjs_real getRealValue(IndexT ofs, tjs_real defaultValue=0) {\n\t\tif (HasValue(ofs)) {\n\t\t\treturn GetValue(ofs, DefsT::Tag<tjs_real>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\tttstr getStrValue(IndexT ofs, ttstr const &defaultValue=ttstr(\"\")) {\n\t\tif (HasValue(ofs)) {\n\t\t\treturn GetValue(ofs, DefsT::Tag<ttstr>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\ttemplate <typename TargetT>\n\tTargetT GetValue(KeyT key, DefsT::Tag<TargetT> const &tag, FlagsT f = 0, HintT hint = 0) {\n\t\tVariantT var;\n\t\t_obj->PropGet(f, key, hint, &var, _obj);\n\t\treturn _toTarget(var, tag);\n\t}\n\ttemplate <typename TargetT>\n\tTargetT GetValue(iTJSDispatch2* obj, KeyT key, DefsT::Tag<TargetT> const &tag, FlagsT f = 0, HintT hint = 0) {\n\t\tVariantT var;\n\t\t_obj->PropGet(f, key, hint, &var, obj);\n\t\treturn _toTarget(var, tag);\n\t}\n\ttjs_int getIntValue(KeyT key, tjs_int defaultValue=0) {\n\t\tif (HasValue(key)) {\n\t\t\treturn GetValue(key, DefsT::Tag<tjs_int>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\ttjs_real getRealValue(KeyT key, tjs_real defaultValue=0) {\n\t\tif (HasValue(key)) {\n\t\t\treturn GetValue(key, DefsT::Tag<tjs_real>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\tttstr getStrValue(KeyT key, ttstr const &defaultValue=ttstr(\"\")) {\n\t\tif (HasValue(key)) {\n\t\t\treturn GetValue(key, DefsT::Tag<ttstr>());\n\t\t} else {\n\t\t\treturn defaultValue;\n\t\t}\n\t}\n\tbool checkVariant(IndexT ofs, VariantT &var) {\n\t\treturn TJS_SUCCEEDED(_obj->PropGetByNum(TJS_MEMBERMUSTEXIST, ofs, &var, _obj));\n\t}\n\tbool checkVariant(KeyT key, VariantT &var) {\n\t\treturn TJS_SUCCEEDED(_obj->PropGet(TJS_MEMBERMUSTEXIST, key, 0, &var, _obj));\n\t}\n\tbool HasValue(IndexT ofs, tTJSVariantType *type = 0) {\n\t\tVariantT var;\n\t\tbool ret = TJS_SUCCEEDED(_obj->PropGetByNum(TJS_MEMBERMUSTEXIST, ofs, &var, _obj));\n\t\tif (ret && type) *type = var.Type();\n\t\treturn ret;\n\t}\n\tbool HasValue(iTJSDispatch2 *obj, IndexT ofs, tTJSVariantType *type = 0) {\n\t\tVariantT var;\n\t\tbool ret = TJS_SUCCEEDED(_obj->PropGetByNum(TJS_MEMBERMUSTEXIST, ofs, &var, obj));\n\t\tif (ret && type) *type = var.Type();\n\t\treturn ret;\n\t}\n\tbool HasValue(KeyT key, HintT hint = 0, tTJSVariantType *type = 0) {\n\t\tVariantT var;\n\t\tbool ret = TJS_SUCCEEDED(_obj->PropGet(TJS_MEMBERMUSTEXIST, key, hint, &var, _obj));\n\t\tif (ret && type) *type = var.Type();\n\t\treturn ret;\n\t}\n\tbool HasValue(iTJSDispatch2 *obj, KeyT key, HintT hint = 0, tTJSVariantType *type = 0) {\n\t\tVariantT var;\n\t\tbool ret = TJS_SUCCEEDED(_obj->PropGet(TJS_MEMBERMUSTEXIST, key, hint, &var, obj));\n\t\tif (ret && type) *type = var.Type();\n\t\treturn ret;\n\t}\n\ttemplate <typename TargetT>\n\tbool SetValue(IndexT ofs, TargetT const &val, FlagsT f = TJS_MEMBERENSURE) {\n\t\tVariantT var;\n\t\t_toVariant(var, val);\n\t\treturn (_obj->PropSetByNum(f, ofs, &var, _obj) == TJS_S_OK);\n\t}\n\ttemplate <typename TargetT>\n\tbool SetValue(iTJSDispatch2 *obj, IndexT ofs, TargetT const &val, FlagsT f = TJS_MEMBERENSURE) {\n\t\tVariantT var;\n\t\t_toVariant(var, val);\n\t\treturn (_obj->PropSetByNum(f, ofs, &var, obj) == TJS_S_OK);\n\t}\n\ttemplate <typename TargetT>\n\tbool SetValue(KeyT key, TargetT const &val, FlagsT f = TJS_MEMBERENSURE, HintT hint = 0) {\n\t\tVariantT var;\n\t\t_toVariant(var, val);\n\t\treturn (_obj->PropSet(f, key, hint, &var, _obj) == TJS_S_OK);\n\t}\n\ttemplate <typename TargetT>\n\tbool SetValue(iTJSDispatch2 *obj, KeyT key, TargetT const &val, FlagsT f = TJS_MEMBERENSURE, HintT hint = 0) {\n\t\tVariantT var;\n\t\t_toVariant(var, val);\n\t\treturn (_obj->PropSet(f, key, hint, &var, obj) == TJS_S_OK);\n\t}\n\tbool IsValid() const { return _obj != 0; }\n\tiTJSDispatch2* GetDispatch() const { return _obj; }\n\toperator iTJSDispatch2*   () const { return _obj; }\n\n#undef  FOREACH_START\n#define FOREACH_START 1\n#undef  FOREACH_END\n#define FOREACH_END   FOREACH_MAX\n#define FCALL_PRM_EXT(num) tTJSVariant          param ## num\n#define FCALL_SET_EXT(num) params[ num - 1 ] = &param ## num;\n\t// FuncCallを任意個数のtTJSVariantを引数で受けるようなメソッドを展開\n#undef  FOREACH\n#define FOREACH \\\n\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, tTJSVariant *result, FOREACH_COMMA_EXT(FCALL_PRM_EXT) ) { \\\n\t\ttTJSVariant *params[FOREACH_COUNT]; FOREACH_SPACE_EXT(FCALL_SET_EXT) \\\n\t\treturn _obj->FuncCall(flag, membername, hint, result, FOREACH_COUNT, params, _obj); \\\n\t}\n#include FOREACH_INCLUDE\n#undef  FOREACH\n#define FOREACH \\\n\ttjs_error TJS_INTF_METHOD FuncCall(iTJSDispatch2 *obj, tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, tTJSVariant *result, FOREACH_COMMA_EXT(FCALL_PRM_EXT) ) { \\\n\t\ttTJSVariant *params[FOREACH_COUNT]; FOREACH_SPACE_EXT(FCALL_SET_EXT) \\\n\t\treturn _obj->FuncCall(flag, membername, hint, result, FOREACH_COUNT, params, obj); \\\n\t}\n#include FOREACH_INCLUDE\n#undef  FCALL_PRM_EXT\n#undef  FCALL_SET_EXT\n\t// 引数なしの場合だけ特殊\n\ttjs_error TJS_INTF_METHOD FuncCall(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, tTJSVariant *result) {\n\t\treturn _obj->FuncCall(flag, membername, hint, result, 0, NULL, _obj);\n\t}\n\ttjs_error TJS_INTF_METHOD FuncCall(iTJSDispatch2 *obj, tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, tTJSVariant *result) {\n\t\treturn _obj->FuncCall(flag, membername, hint, result, 0, NULL, obj);\n\t}\nprotected:\n\tiTJSDispatch2 *_obj;\n\n\ttemplate <typename TargetT>\n\tTargetT _toTarget(VariantT &v, DefsT::Tag<TargetT> const&) {\n\t\ttypedef typename ncbTypeConvertor::SelectConvertorType<VariantT, TargetT>::Type ToTargetT;\n\t\tTargetT r;\n\t\tToTargetT conv;\n\t\tconv(r, v);\n\t\treturn r;\n\t}\n\ttemplate <typename TargetT>\n\tvoid _toVariant(VariantT &v, TargetT const &r) {\n\t\ttypedef typename ncbTypeConvertor::SelectConvertorType<TargetT, VariantT>::Type ToVariantT;\n\t\tToVariantT conv;\n\t\tconv(v, r);\n\t}\n\tVariantT _toTarget( VariantT &v, DefsT::Tag<VariantT> const&) { return v; }\n\tvoid     _toVariant(VariantT &v, VariantT const &r) { v = r; }\n\tiTJSDispatch2* _toTarget( VariantT &v, DefsT::Tag<iTJSDispatch2*> const&) { return v; }\n\tvoid           _toVariant(VariantT &v, iTJSDispatch2*  const &r) { v = VariantT(r, r); }\n\tvoid           _toVariant(VariantT &v, ncbPropAccessor  const &r) { _toVariant(v, r._obj);  }\n\tvoid           _toVariant(VariantT &v, ncbPropAccessor* const &r) { _toVariant(v, r->_obj); }\n};\n\nstruct ncbArrayAccessor : public ncbPropAccessor {\n\tncbArrayAccessor() : ncbPropAccessor(TJSCreateArrayObject(), false) {}\nprivate:\n\tncbArrayAccessor(ncbArrayAccessor const&);\n};\nstruct ncbDictionaryAccessor : public ncbPropAccessor {\n\tncbDictionaryAccessor() : ncbPropAccessor(TJSCreateDictionaryObject(), false) {}\nprivate:\n\tncbDictionaryAccessor(ncbDictionaryAccessor const&);\n};\n\n\n////////////////////////////////////////\n/// メソッドオブジェクト（と，そのタイプとフラグ）を受け渡すためのインターフェース\nstruct ncbIMethodObject {\n\ttypedef iTJSDispatch2*             DispatchT;\n\ttypedef ncbTypedefs::FlagsT        FlagsT;\n\ttypedef ncbTypedefs::InstanceTypeT TypesT;\n\n\tvirtual DispatchT GetDispatch() const = 0;\n\tvirtual FlagsT    GetFlags()    const = 0;\n\tvirtual TypesT    GetType()     const = 0;\n\tvirtual void      Release()     const = 0;\n};\n\n////////////////////////////////////////\n/// メソッド呼び出し用ベースクラス\n\nstruct ncbNativeClassMethodBase : public tTJSDispatch {\n\ttypedef tTJSDispatch             BaseT;\n\ttypedef ncbNativeClassMethodBase ThisClassT;\n\ttypedef ncbTypedefs              DefsT;\n\ttypedef DefsT::NameT             NameT;\n\ttypedef DefsT::FlagsT            FlagsT;\n\ttypedef DefsT::InstanceTypeT     TypesT;\n\ttypedef ncbIMethodObject const*  iMethodT;\n\ttypedef tTJSNativeInstanceType   MethodTypeT;\n\n\t/// constructor\n\tncbNativeClassMethodBase(MethodTypeT t) : _type(t), _name(0) {\n\t\t_imethod = this;\n\t\tswitch (t) { // タイプ名を設定\n//\t\tcase nitClass:    _name = TJS_W(\"Class\");    break; // クラスになることはありえない\n\t\tcase nitMethod:   _name = TJS_W(\"Function\"); break;\n\t\tcase nitProperty: _name = TJS_W(\"Property\"); break;\n\t\tdefault: break;\n\t\t}\n\t}\n\t~ncbNativeClassMethodBase() {}\n\n\t/// IsInstanceOf 実装\n\ttjs_error TJS_INTF_METHOD IsInstanceOf(\n\t\ttjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, \n\t\tconst tjs_char *classname, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身(membername==0)で比較クラス名が_nameならTRUE，それ以外は丸投げ\n\t\treturn (!membername && _name && !TJS_stricmp(classname, _name)) ? TJS_S_TRUE\n\t\t\t: BaseT::IsInstanceOf(flag, membername, hint, classname, objthis);\n\t}\n\nprivate:\n\tMethodTypeT const _type;\n\tNameT _name;\n\n\t// privateで隠蔽してみる\n\ttypedef DefsT::CallerT CallerT;\n\n\t//--------------------------------------\n\t/// TJSNativeClassRegisterNCM に渡すタイプ\n\tvirtual TypesT GetType() const { return _type; }\n\n\t/// TJSNativeClassRegisterNCM に渡すフラグ\n\tvirtual FlagsT GetFlags() const { return 0; }\n\n\t/// IMethod 実装\n\tstruct iMethod : public ncbIMethodObject {\n\t\ttypedef ncbNativeClassMethodBase MethodObjectT;\n\t\tvoid operator = (MethodObjectT *mo) { _this = mo; }\n\t\tDispatchT GetDispatch() const { return static_cast<DispatchT>(_this); }\n\t\tFlagsT    GetFlags()    const { return _this->GetFlags(); }\n\t\tTypesT    GetType()     const { return _this->GetType(); }\n\t\tvoid      Release()     const {}\n\tprivate:\n\t\tMethodObjectT *_this;\n\t} _imethod;\n\nprotected:\n\t/// IMethod 取得\n\tiMethodT GetIMethod() const { return &_imethod; }\n\n\n\n\t//--------------------------------------\nprotected:\n\t/// tMethodTraitsラッパー\n\ttemplate <typename T>\n\tstruct traits {\n\t\ttypedef CallerT::tMethodTraits<T> TraitsT;\n\t\ttypedef typename TraitsT::ResultType ResultT;\n\t\ttypedef typename TraitsT::ClassType ClassT;\n\t\ttypedef typename TraitsT::ArgsType  ArgsT;\n\t\tenum { ArgsCount = TraitsT::ArgsCount };\n\t};\n\n\t//--------------------------------------\nprivate:\n\t/// 引数/返り値の引き渡し用ファンクタ (ncb_invoke.hpp/MethodCallerに渡すために必要)\n\ttemplate <typename METHOD>\n\tstruct paramsFunctor {\n\t\ttypedef traits<METHOD> TraitsT;\n\t\t// 旧テンプレパラメタ\n\t\ttypedef typename TraitsT::ResultT RES;\n\t\ttypedef typename TraitsT::ArgsT   ARGS;\n\t\tenum { ARGC = TraitsT::ArgsCount };\n\n\t\ttypedef tTJSVariant      VariantT;\n\t\ttypedef ncbTypeConvertor ConvT;\n\t\ttypedef typename     ConvT::SelectConvertorType<RES, VariantT>::Type ResultConvT;\n\t\tenum { StrictResult = ncbTypeConvertor::Conversion<ResultConvT*, ncbStrictResultConvertor*>::Exists };\n\n\t\ttemplate <typename T> struct TypeWrap           { typedef T        Type; static inline T        Restore(Type t) { return  t; } };\n\t\ttemplate <typename T> struct TypeWrap<T&>       { typedef T*       Type; static inline T&       Restore(Type t) { return *t; } };\n\t\ttemplate <typename T> struct TypeWrap<T const&> { typedef T const* Type; static inline T const& Restore(Type t) { return *t; } };\n\n\t\ttemplate <typename T> struct ArgsExtor { typedef typename ConvT::SelectConvertorType<VariantT, typename TypeWrap<T>::Type>::Type Type; };\n\t\ttypedef CallerT::tArgsExtract<ArgsExtor, ARGS, ARGC> ArgsConvT;\n\t\t/* ArgsConvT は以下のように展開される：\n\t\t\tstruct ArgsConvT {\n\t\t\t\tncbToValueConvertor<ARGS::Arg1Type> t1; // 一番目の引数の ncbToValueConvertor\n\t\t\t\tncbToValueConvertor<ARGS::Arg2Type> t2; // 二番目の\n\t\t\t\t  :\n\t\t\t\tncbToValueConvertor<ARGS::Arg[ARGC]Type> tARGC; // ARGC番目の\n\t\t\t}; */\n\n\t\t/// constructor\n\t\tparamsFunctor(VariantT *r, tjs_int n, VariantT const *const *p) : _numparams(n), _result(r),_param(p) {}\n\n\t\t/// 引数を NativeClassMethod へ引渡し\n\t\ttemplate <int N, typename T>\n\t\tinline T operator ()(CallerT::tNumTag<N> const& /*index*/, CallerT::tTypeTag<T> const& /*type*/) {\n\t\t\ttypedef typename TypeWrap<T>::Type ParamT;\n\t\t\tParamT ret;\n\t\t\t// N番目の ncbToValueConvertor を取り出して変換\n\t\t\t(CallerT::tArgsSelect<ArgsConvT, N>::Get(_aconv))(ret, (_numparams >= N) ? *(_param[N - 1]) : VariantT());\n\t\t\treturn TypeWrap<T>::Restore(ret);\n\t\t}\n\n\t\t/// NativeClassMethod の返り値なし\n\t\tinline bool operator ()() const { return true; }\n\n\t\t/// NativeClassMethod の返り値をresultへ格納\n\t\ttemplate <typename ResultT>\n\t\tinline bool operator()(ResultT r, CallerT::tTypeTag<ResultT> const&) {\n\t\t\treturn SetResult(r, DefsT::Tag<ResultT>(),  DefsT::BoolTag<StrictResult>());\n\t\t}\n\n\t\t// StrictResult = false\n\t\ttemplate <typename ResultT>\n\t\tinline bool SetResult(ResultT r, DefsT::Tag<ResultT> const&, DefsT::BoolTag<false> const&) {\n\t\t\tif (_result) _rconv(*_result, r); // ncbToVariantConvertor で返り値に変換\n\t\t\treturn true;\n\t\t}\n\n\t\t// StrictResult = true\n\t\ttemplate <typename ResultT>\n\t\tinline bool SetResult(ResultT r, DefsT::Tag<ResultT> const &tag, DefsT::BoolTag<true> const&) {\n\t\t\tif (_result) _rconv(*_result, r, tag);\n\t\t\treturn true;\n\t\t}\n\n\t\t// for reference\n\t\ttemplate <typename ResultT>\n\t\tinline bool operator()(ResultT &r, CallerT::tTypeTag<ResultT&> const& tag) {\n\t\t\treturn  operator()<ResultT &>(r, tag);\n\t\t}\n\t\ttemplate <typename ResultT, bool B>\n\t\tinline bool SetResult(ResultT &r, DefsT::Tag<ResultT&> const &tag, DefsT::BoolTag<B> const &sel) {\n\t\t\treturn  SetResult<ResultT &>(r, tag, sel);\n\t\t}\n\n\n\tprivate:\n\t\t// 型変換用ワーク\n\t\tArgsConvT   _aconv;\n\t\tResultConvT _rconv;\n\n\t\t// 引数・返り値パラメータ\n\t\ttjs_int                _numparams;\n\t\tVariantT             * _result;\n\t\tVariantT const *const* _param;\n\t};\n\n\t// 先頭にインスタンスポインタを渡すPROXY METHODのファンクタ\n\ttemplate <class CLASS, class FUNCT>\n\tstruct paramsFunctorWithInstance : public FUNCT {\n\t\ttypedef FUNCT       BaseT;\n\t\ttypedef CLASS       ClassT;\n\t\ttypedef tTJSVariant VariantT;\n\t\tparamsFunctorWithInstance(VariantT *r, tjs_int n, VariantT const *const *p, ClassT *inst) : BaseT(r, n+1, p-1), _inst(inst) {}\n\t\ttemplate <int N, typename T> inline T operator ()(CallerT::tNumTag<N> const &idx, CallerT::tTypeTag<T> const &tag) { return BaseT::operator ()(idx, tag); }\n\t\ttemplate <       typename T> inline T operator ()(CallerT::tNumTag<1> const &,    CallerT::tTypeTag<T> const &   ) { return _inst; }\n\t\ttemplate <typename ResultT>  inline bool operator()(ResultT  r, CallerT::tTypeTag<ResultT>  const &tag) { return BaseT::operator()(r, tag); }\n\t\ttemplate <typename ResultT>  inline bool operator()(ResultT &r, CallerT::tTypeTag<ResultT&> const &tag) { return BaseT::operator()(r, tag); }\n\t\t/*                         */inline bool operator()() const { return BaseT::operator ()(); }\n\tprivate:\n\t\tClassT *_inst;\n\t};\n\n\n\t//--------------------------------------\nprivate:\n\t/// ネイティブインスタンスを取得するためのテンプレート（特殊化で上書きできるようにするため\n\ttemplate <class T>\n\tstruct nativeInstanceGetterBase {\n\t\ttypedef T  ClassT;\n\t\ttypedef ncbInstanceAdaptor<ClassT> AdaptorT;\n\t\ttypedef iTJSDispatch2* DispatchT;\n\t\ttypedef tjs_error      ErrorT;\n\n\t\tnativeInstanceGetterBase() : _error(TJS_S_OK) {}\n\n\t\tinline ClassT *GetNativeInstance(DispatchT objthis) {\n\t\t\tClassT *r = AdaptorT::GetNativeInstance(objthis); // 実インスタンスのポインタ\n\t\t\tif (!r) SetError(TJS_E_NATIVECLASSCRASH);\n\t\t\treturn r;\n\t\t}\n\t\tinline bool SetNativeInstance(DispatchT objthis, ClassT *obj) {\n\t\t\tSetError(TJS_S_OK);\n\t\t\treturn AdaptorT::SetAdaptorWithNativeInstance(objthis, obj);\n\t\t}\n\t\tinline ErrorT  GetError() const   { return _error; }\n\t\tinline void    SetError(ErrorT e) { _error = e; }\n\n\t\t/// デフォルト動作\n\t\tinline ClassT* Get(DispatchT objthis) { return GetNativeInstance(objthis); }\n\tprivate:\n\t\tErrorT _error;\n\t};\n\n\t/// 指定がない場合はデフォルト動作（BaseのGetが呼ばれる）\n\ttemplate <class T>\n\tstruct nativeInstanceGetter : public nativeInstanceGetterBase<T> {};\n\n\t/// Bridge用\n\ttemplate <class FROM, class TO, typename CONV>\n\tstruct bridgeInstanceGetter : public nativeInstanceGetterBase<FROM> {\n\t\ttypedef                          nativeInstanceGetterBase<FROM> BaseT;\n\t\tinline TO* Get(typename BaseT::DispatchT objthis) {\n\t\t\tFROM *obj = BaseT::GetNativeInstance(objthis);\n\t\t\treturn obj ? conv(obj) : 0;\n\t\t}\n\tprivate:\n\t\tCONV conv;\n\t};\n\n\t// ダミー用\n\ttypedef struct dummyGetter { dummyGetter() {} } const noInstanceGetter;\n\n\t//--------------------------------------\nprotected:\n\t/// メソッド/コンストラクタ呼び出しにtry/catchを挟み込むためのヘルパテンプレート\n\ttemplate <bool  IsAny>  struct invokeHookAll   { template <typename T> static inline typename T::ResultT Do(T &t) { return t(); } };\n\ttemplate <class ClassT> struct invokeHookClass { template <typename T> static inline typename T::ResultT Do(T &t) { return invokeHookAll<T::Hook>::Do(t); } };\n\n\t//--------------------------------------\nprotected:\n\t// フックの引き数に渡すファンクタのベース（パラメータ保持）\n\tstruct doInvokeBase {\n\t\ttypedef tjs_error ResultT;\n\t\tenum { Hook = true };\n\t\tenum { ivsMethod, ivsProxy, ivsConstructor, ivsFactory };\n\n\t\ttypedef tTJSVariant  * RetT;\n\t\ttypedef tjs_int        NumT;\n\t\ttypedef tTJSVariant ** ArgsT;\n\t\ttypedef iTJSDispatch2            *ObjT;\n\t\tdoInvokeBase(RetT r, NumT n, ArgsT p, ObjT o)\n\t\t\t: _result(r), _numparams(n), _param(p), _objthis(o) { if (r) r->Clear(); }\n\tprotected:\n\t\tRetT  const _result;\n\t\tNumT  const _numparams;\n\t\tArgsT const _param;\n\t\tObjT  const _objthis;\n\n\t\t// 通常メソッド\n\t\ttemplate <typename MethodT, class ClassT, class FunctorT>\n\t\tResultT CallInvoke(MethodT const &m, ClassT *inst, DefsT::Tag<FunctorT>, DefsT::NumTag<ivsMethod>) const {\n\t\t\treturn CallerT::Invoke(FunctorT(_result, _numparams, _param),       m, inst) ? TJS_S_OK : TJS_E_FAIL;\n\t\t}\n\t\t// Proxy 用\n\t\ttemplate <typename MethodT, class ClassT, class FunctorT>\n\t\tResultT CallInvoke(MethodT const &m, ClassT *inst, DefsT::Tag<FunctorT>, DefsT::NumTag<ivsProxy>) const {\n\t\t\treturn CallerT::Invoke(FunctorT(_result, _numparams, _param, inst), m, inst) ? TJS_S_OK : TJS_E_FAIL;\n\t\t}\n\t\t// コンストラクタ用\n\t\ttemplate <typename MethodT, class ClassT, class FunctorT>\n\t\tResultT CallInvoke(MethodT const &,  ClassT *inst, DefsT::Tag<FunctorT>, DefsT::NumTag<ivsConstructor>) const {\n\t\t\ttry {\n\t\t\t\tFunctorT fnct(_result, _numparams, _param);\n\t\t\t\tif (!(inst = CallerT::Factory(fnct, CallerT::tTypeTag<ClassT>(), CallerT::tTypeTag<typename FunctorT::TraitsT::ArgsT>()))) {\n\t\t\t\t\tTVPThrowExceptionMessage(TJS_W(\"NativeClassInstance creation faild.\"));\n\t\t\t\t\treturn TJS_E_FAIL;\n\t\t\t\t}\n\t\t\t\tif (!ncbInstanceAdaptor<ClassT>::SetNativeInstance(_objthis, inst)) {\n\t\t\t\t\tdelete inst;\n\t\t\t\t\treturn TJS_E_NATIVECLASSCRASH;\n\t\t\t\t}\n\t\t\t} catch (...) {\n\t\t\t\tif (inst) delete inst;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\t// コンストラクタ代替ファクトリ\n\t\ttemplate <typename MethodT, class ClassT, class FunctorT>\n\t\tResultT CallInvoke(MethodT const &m, ClassT *inst, DefsT::Tag<FunctorT>, DefsT::NumTag<ivsFactory>) const {\n\t\t\ttypedef ncbInstanceAdaptor<ClassT> AdaptorT;\n\t\t\ttry {\n\t\t\t\tif (!(inst = CallerT::Factory(FunctorT(_result, _numparams, _param, _objthis), m))) {\n\t\t\t\t\tTVPThrowExceptionMessage(TJS_W(\"NativeClassInstance creation faild.\"));\n\t\t\t\t\treturn TJS_E_FAIL;\n\t\t\t\t}\n\t\t\t\tif (!ncbInstanceAdaptor<ClassT>::SetNativeInstance(_objthis, inst)) {\n\t\t\t\t\tdelete inst;\n\t\t\t\t\treturn TJS_E_NATIVECLASSCRASH;\n\t\t\t\t}\n\t\t\t} catch (...) {\n\t\t\t\tif (inst) delete inst;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t\treturn TJS_S_OK;\n\t\t}\n\n\t\t// インスタンス取得\n\t\ttemplate <class ClassT, typename GetterT>\n\t\tResultT GetInstance(ClassT **obj, GetterT &g) const {\n\t\t\t*obj = g.Get(_objthis);\n\t\t\treturn g.GetError();\n\t\t}\n\t\t// インスタンスなし\n\t\ttemplate <class ANY>\n\t\tResultT GetInstance(ANY**, noInstanceGetter&) const { return TJS_S_OK; }\n\t};\n\t// クラスメソッド呼び出しファンクタ\n\ttemplate <class SELECTOR>\n\tstruct doInvoke : public doInvokeBase {\n\t\ttypedef SELECTOR SelectorT;\n\t\ttypedef typename SelectorT::RefClassT    RefClassT;    // 大元のネイティブクラス\n\t\ttypedef typename SelectorT::ClassT       ClassT;       // メソッド呼び出しの対象クラス(staticならvoid, bridgeなら転送先クラス)\n\t\ttypedef typename SelectorT::MethodT      MethodT;      // メソッド型\n\t\ttypedef typename SelectorT::GetInstanceT GetInstanceT; // インスタンス取得するための型(voidなら取得しない, bridgeなら転送先インスタンス取得)\n\t\ttypedef typename SelectorT::FunctorT     FunctorT;     // 引き数取得用ファンクタ型(通常はparamsFunctor, proxyならparamsFunctorWithInstance)\n\t\t//enum { InvokeSelect = SelectorT::InvokeSelect };     // ivsMethod, ivsProxy, ivsConstructor\n\t\t//enum { ArgsCount = SelectorT::ArgsCount };           // 引数の個数(proxy なら-1された値)\n\n\t\tdoInvoke(MethodT const &m, RetT r, NumT n, ArgsT p, ObjT o) : doInvokeBase(r, n, p, o), _m(m) {}\n\t\tinline ResultT operator()() const {\n\t\t\t// 引き数の個数が少ない場合はエラー\n\t\t\tif (_numparams < SelectorT::ArgsCount) return TJS_E_BADPARAMCOUNT;\n\n\t\t\t// インスタンスポインタを取得\n\t\t\tClassT *inst = 0;\n\t\t\tGetInstanceT gi;\n\t\t\tResultT r = GetInstance(&inst, gi);\n\t\t\tif (TJS_FAILED(r)) return r;\n\n\t\t\t// インスタンスを渡してクラスメソッドを実行\n\t\t\treturn CallInvoke(_m, inst, DefsT::Tag<FunctorT>(), DefsT::NumTag<SelectorT::InvokeSelect>());\n\t\t}\n\t\tinline ResultT Invoke() const {\n\t\t\treturn invokeHookClass<RefClassT>::Do(*this);\n\t\t}\n\tprivate:\n\t\tMethodT const &_m;\n\t};\n\t//--------------------------------------\npublic:\n\tstruct InvokeType {\n\t\t// InvokeCommandに使用する場合わけ用タグ\n\t\tstruct ivtCtor {};\n\t\tstruct ivtFactory {};\n\t\tstruct ivtNormal {};\n\t\ttemplate <class BASE>\n\t\tstruct ivtProxy { typedef BASE BaseT; };\n\t\ttemplate <typename METHOD>\n\t\tstruct ivtBridge {\n\t\t\ttypedef typename traits<METHOD>::ClassT BridgeT;\n\t\t\ttypedef typename ncbTypeConvertor::Stripper<typename traits<METHOD>::ResultT>::Type TargetT;\n\t\t};\n\n\t\t// Normal\n\t\ttemplate <class REFCLASS, typename METHOD, class SEL = ivtNormal>\n\t\tstruct InvokeCommand {\n\t\t\ttypedef REFCLASS RefClassT;\n\t\t\ttypedef METHOD   MethodT;\n\t\t\ttypedef traits<MethodT> TraitsT;\n\t\t\ttypedef typename TraitsT::ClassT ClassT;\n\t\t\ttypedef typename DefsT::TypeSelect<\n\t\t\t\t(DefsT::TypeEqual<ClassT, void>::Result), noInstanceGetter, nativeInstanceGetter<RefClassT> >::Result GetInstanceT;\n\t\t\t// GetInstanceT=     (ClassT==void) ?         noInstanceGetter: nativeInstanceGetter<RefClassT>;\n\t\t\ttypedef paramsFunctor<MethodT> FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsMethod,\n\t\t\t\tArgsCount    = TraitsT::ArgsCount,\n\t\t\t\tFlags = (DefsT::IntSelect<\n\t\t\t\t\t\t DefsT::TypeEqual<ClassT, void>::Result, TJS_STATICMEMBER, 0>::Result)\n\t\t\t\t\t//   Flags =         (ClassT==void) ?        TJS_STATICMEMBER :0;\n\t\t\t};\n\t\t};\n\t\t// Bridge : instanceGetter を置き換え\n\t\ttemplate <class REFCLASS, typename METHOD, typename BRIDGE>\n\t\tstruct InvokeCommand<REFCLASS, METHOD, ivtBridge<BRIDGE> > {\n\t\t\ttypedef                            ivtBridge<BRIDGE> BridgeT;\n\t\t\ttypedef REFCLASS RefClassT;\n\t\t\ttypedef METHOD   MethodT;\n\t\t\ttypedef typename BridgeT::TargetT ClassT;\n\t\t\ttypedef traits<MethodT> TraitsT;\n\t\t\ttypedef bridgeInstanceGetter<RefClassT, ClassT, typename BridgeT::BridgeT> GetInstanceT;\n\t\t\ttypedef paramsFunctor<MethodT> FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsMethod,\n\t\t\t\tArgsCount    = TraitsT::ArgsCount,\n\t\t\t\tFlags        = 0,\n\t\t\t};\n\t\t};\n\t\t// Proxy : Normal から FunctorT と ArgsCount を置き換える\n\t\ttemplate <class REFCLASS, typename METHOD>\n\t\tstruct InvokeCommand<REFCLASS, METHOD, ivtProxy<ivtNormal> > : public InvokeCommand<REFCLASS, METHOD> {\n\t\t\ttypedef /*                                                      */InvokeCommand<REFCLASS, METHOD> BaseT;\n\t\t\ttypedef REFCLASS ClassT;\n\t\t\ttypedef nativeInstanceGetter<ClassT> GetInstanceT;\n\t\t\ttypedef paramsFunctorWithInstance<REFCLASS, typename BaseT::FunctorT> FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsProxy,\n\t\t\t\tArgsCount    = BaseT::ArgsCount - 1,\n\t\t\t\tFlags        = 0,\n\t\t\t};\n\t\t};\n\t\t// ProxyBridge : Bridge から FunctorT と ArgsCount を置き換える\n\t\ttemplate <class REFCLASS, typename METHOD, class BRIDGE>\n\t\tstruct InvokeCommand<      REFCLASS, METHOD, ivtProxy< ivtBridge<BRIDGE> > >\n\t\t\t: public InvokeCommand<REFCLASS, METHOD,           ivtBridge<BRIDGE> > {\n\t\t\ttypedef  InvokeCommand<REFCLASS, METHOD,           ivtBridge<BRIDGE> > BaseT;\n\t\t\ttypedef paramsFunctorWithInstance<typename BaseT::ClassT, typename BaseT::FunctorT> FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsProxy,\n\t\t\t\tArgsCount    = BaseT::ArgsCount - 1,\n\t\t\t\tFlags        = 0,\n\t\t\t};\n\t\t};\n\t\t// Constructor\n\t\ttemplate <class CLASS, typename METHOD>\n\t\tstruct InvokeCommand<CLASS, METHOD, ivtCtor> {\n\t\t\ttypedef CLASS RefClassT;\n\t\t\ttypedef CLASS ClassT;\n\t\t\ttypedef void* MethodT;\n\t\t\ttypedef noInstanceGetter GetInstanceT;\n\t\t\ttypedef traits<METHOD> TraitsT;\n\t\t\ttypedef paramsFunctor<METHOD> FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsConstructor,\n\t\t\t\tArgsCount = TraitsT::ArgsCount\n\t\t\t};\n\t\t};\n\t\t// Factory\n\t\ttemplate <class CLASS, typename METHOD>\n\t\tstruct InvokeCommand<CLASS, METHOD, ivtFactory> {\n\t\t\ttypedef CLASS RefClassT;\n\t\t\ttypedef CLASS ClassT;\n\t\t\ttypedef METHOD   MethodT;\n\t\t\ttypedef noInstanceGetter GetInstanceT;\n\t\t\ttypedef traits<METHOD> TraitsT;\n\t\t\ttypedef paramsFunctorWithInstance<iTJSDispatch2, paramsFunctor<METHOD> > FunctorT;\n\t\t\tenum {\n\t\t\t\tInvokeSelect = doInvokeBase::ivsFactory,\n\t\t\t\tArgsCount = TraitsT::ArgsCount - 1\n\t\t\t};\n\t\t\t// ファクトリ関数の返り値チェック\n\t\t\tstruct NoInstanceReturn {};\n\t\t\ttypedef typename DefsT::TypeAssert<\n\t\t\t\t!DefsT::TypeEqual<typename TraitsT::ResultT, ClassT*>::Result,\n\t\t\t/**/NoInstanceReturn>::Result CheckResultType;\n\n\t\t\t// staticメソッドチェック\n\t\t\tstruct NoStaticMethod {};\n\t\t\ttypedef typename DefsT::TypeAssert<\n\t\t\t\t!DefsT::TypeEqual<typename TraitsT::ClassT, void>::Result,\n\t\t\t/**/NoStaticMethod >::Result CheckClassType;\n\t\t};\n\t\t\n\t\t// プロパティは Getter と Setter の InvokeCommand を束ねる\n\t\ttemplate <class REFCLASS, typename GETTER, typename SETTER, class SEL>\n\t\tstruct PropertyCommand {\n\t\t\ttypedef InvokeCommand<REFCLASS, GETTER, SEL> GetCommandT;\n\t\t\ttypedef InvokeCommand<REFCLASS, SETTER, SEL> SetCommandT;\n\t\t};\n\t};\n};\n\n\n\n////////////////////////////////////////\n/// メソッド呼び出しクラステンプレート\n// 本来は TJSCreateNativeClassMethod（及び吉里吉里内のtTJSNativeClassMethod）を使用するところを\n// 自前で実装する(TJSCreateNativeClassMethodではstaticな関数しか呼べないのでメソッドへのポインタの保持が困難なため)\ntemplate <class CommandT>\nstruct ncbNativeClassMethod : public ncbNativeClassMethodBase { \n\ttypedef ncbNativeClassMethod ThisClassT;\n\ttypedef typename CommandT::MethodT MethodT;\n\n\t/// constructor\n\tncbNativeClassMethod(MethodT m) : ncbNativeClassMethodBase(nitMethod), _method(m) {\n\t\tif (!_method) TVPThrowExceptionMessage(TJS_W(\"No method pointer.\"));\n\t} \n\n\t/// FuncCall実装\n\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::FuncCall(flag, membername, hint, result, numparams, param, objthis);\n\n\t\t// エラーチェック\n\t\tif (!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\t\t// メソッド呼び出し\n\t\treturn (doInvoke<CommandT>(_method, result, numparams, param, objthis)).Invoke();\n\t}\n\t/// factory\n\tstatic iMethodT Create(MethodT m, bool create = true) { return !create ? 0 : (new ThisClassT(m))->GetIMethod(); }\n\nprotected:\n\tMethodT const _method;\n\nprivate:\n\t/// TJSNativeClassRegisterNCMフラグ\n\tFlagsT GetFlags() const { return CommandT::Flags; }\n};\n\n////////////////////////////////////////\n/// コンストラクタ呼び出しクラステンプレート\ntemplate <class CommandT>\nstruct ncbNativeClassConstructor : public ncbNativeClassMethodBase {\n\ttypedef ncbNativeClassConstructor ThisClassT;\n\ttypedef typename CommandT::MethodT MethodT;\n\n\t/// constructor\n\tncbNativeClassConstructor(MethodT m) : ncbNativeClassMethodBase(nitMethod), _method(m) {\n\t\tif (!_method && (int)CommandT::InvokeSelect == (int)doInvokeBase::ivsFactory)\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"No factory pointer.\"));\n\t}\n\n\t/// FuncCall実装\n\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::FuncCall(flag, membername, hint, result, numparams, param, objthis);\n\n\t\t// 引き数がひとつでかつvoidの場合はインスタンスを設定しない\n\t\tif ((numparams == 1) && (ncbTypedefs::GetVariantType(*param[0]) == tvtVoid)) {\n//\t\t\tNCB_LOG_W(\"Constructor(void)\");\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\t// ネイティブインスタンス生成\n\t\treturn (doInvoke<CommandT>(_method, result, numparams, param, objthis)).Invoke();\n\t}\n\n\t/// iMethod factory\n\tstatic iMethodT Create(MethodT m, bool create = true) { return !create ? 0 : (new ThisClassT(m))->GetIMethod(); }\n\nprotected:\n\tMethodT const _method;\n};\n\ntemplate <class ClassT>\nstruct ncbNativeClassFactory : public ncbNativeClassMethodBase {\n\ttypedef ncbNativeClassFactory ThisClassT;\n\ttypedef tjs_error (TJS_INTF_METHOD *MethodT)(ClassT **result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis);\n\n\t/// constructor\n\tncbNativeClassFactory(MethodT m) : ncbNativeClassMethodBase(nitMethod), _method(m) {\n\t\tif (!_method) TVPThrowExceptionMessage(TJS_W(\"No factory pointer.\"));\n\t}\n\n\t/// FuncCall実装\n\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::FuncCall(flag, membername, hint, result, numparams, param, objthis);\n\n\t\t// 引き数がひとつでかつvoidの場合はインスタンスを設定しない\n\t\tif ((numparams == 1) && (ncbTypedefs::GetVariantType(*param[0]) == tvtVoid)) {\n//\t\t\tNCB_LOG_W(\"Constructor(void)\");\n\t\t\treturn TJS_S_OK;\n\t\t}\n\t\t// ネイティブインスタンス生成\n\t\tClassT *inst = 0;\n\t\ttjs_error r = _method(&inst, numparams, param, objthis);\n\t\tif (r != TJS_S_OK) return r;\n\t\tif (!ncbInstanceAdaptor<ClassT>::SetNativeInstance(objthis, inst)) {\n\t\t\tdelete inst;\n\t\t\treturn TJS_E_NATIVECLASSCRASH;\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\n\t/// iMethod factory\n\tstatic iMethodT Create(MethodT m, bool create = true) { return !create ? 0 : (new ThisClassT(m))->GetIMethod(); }\n\nprotected:\n\tMethodT const _method;\n};\n\n\n////////////////////////////////////////\n\ntemplate <class PropCommandT>\nstruct ncbNativeClassProperty : public ncbNativeClassMethodBase {\n\ttypedef ncbNativeClassProperty ThisClassT;\n\ttypedef typename PropCommandT::GetCommandT GetCommandT;\n\ttypedef typename PropCommandT::SetCommandT SetCommandT;\n\ttypedef typename GetCommandT::MethodT GetterT;\n\ttypedef typename SetCommandT::MethodT SetterT;\n\n\t/// constructor\n\tncbNativeClassProperty(GetterT get, SetterT set) : ncbNativeClassMethodBase(nitProperty), _getter(get), _setter(set) {}\n\n\t/// PropGet 実装\n\ttjs_error TJS_INTF_METHOD PropGet(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::PropGet(flag, membername, hint, result, objthis);\n\n\t\t// エラーチェック\n\t\tif (!_getter) return TJS_E_ACCESSDENYED;\n\t\tif (!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\t\t// メソッド呼び出し\n\t\treturn (doInvoke<GetCommandT>(_getter, result, 0, 0, objthis)).Invoke();\n\t}\n\n\t/// PropSet 実装\n\ttjs_error TJS_INTF_METHOD PropSet(\n\t\ttjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, \n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::PropSet(flag, membername, hint, param, objthis);\n\n\t\t// エラーチェック\n\t\tif (!_setter) return TJS_E_ACCESSDENYED;\n\t\tif (!objthis) return TJS_E_NATIVECLASSCRASH;\n\t\tif (!param)   return TJS_E_FAIL;\n\n\t\t// メソッド呼び出し\n\t\treturn (doInvoke<SetCommandT>(_setter, 0, 1, const_cast<tTJSVariant**>(&param), objthis)).Invoke();\n\t}\n\n\t/// factory\n\tstatic iMethodT Create(GetterT g, SetterT s, bool create = true) { return !create ? 0 : (new ThisClassT(g, s))->GetIMethod(); }\n\nprivate:\n\t/// TJSNativeClassRegisterNCMフラグ\n\tFlagsT GetFlags() const { return GetCommandT::Flags; }\n\nprotected:\n\t/// プロパティメソッドへのポインタ\n\tGetterT const _getter;\n\tSetterT const _setter;\n};\n\n\n////////////////////////////////////////\n/// 生コールバック用\ntemplate <typename T> struct ncbRawCallbackMethod;\n\n// ネイティブインスタンスのポインタのみあらかじめ取得するコールバック\ntemplate <class T>\nstruct ncbRawCallbackMethod<\n/*        */tjs_error (TJS_INTF_METHOD *         )(tTJSVariant *result, tjs_int numparams, tTJSVariant **param, T *nativeInstance) > : public ncbNativeClassMethodBase {\n\ttypedef tjs_error (TJS_INTF_METHOD *CallbackT)(tTJSVariant *result, tjs_int numparams, tTJSVariant **param, T *nativeInstance);\n\ttypedef T                                NativeClassT;\n\ttypedef ncbRawCallbackMethod             ThisClassT;\n\ttypedef ncbInstanceAdaptor<NativeClassT> AdaptorT;\n\n\n\t/// constructor\n\tncbRawCallbackMethod(CallbackT m, FlagsT f)\n\t\t: ncbNativeClassMethodBase(nitMethod), // TJSオブジェクト的には Function\n\t\t  _callback(m), _flag(f)\n\t{\n\t\tif (!_callback) TVPThrowExceptionMessage(TJS_W(\"No callback pointer.\"));\n\t}\n\n\t/// FuncCall実装\n\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::FuncCall(flag, membername, hint, result, numparams, param, objthis);\n\n\t\t// エラーチェック\n\t\tif (!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\t\t// 返り値クリア\n\t\tif (result) result->Clear();\n\n\t\tNativeClassT *obj = 0;\n\t\tif (!(_flag & TJS_STATICMEMBER)) {\n\t\t\t//< 実インスタンスのポインタ\n\t\t\tobj = AdaptorT::GetNativeInstance(objthis); \n\t\t\tif (!obj) return TJS_E_NATIVECLASSCRASH;\n\t\t}\n\t\t// Callback呼び出し\n\t\treturn _callback(result, numparams, param, obj);     //< Callback呼び出し\n\t}\n\n\t/// factory\n\tstatic iMethodT Create(CallbackT cb, FlagsT f, bool create = true) { return !create ? 0 : (new ThisClassT(cb, f))->GetIMethod(); }\n\nprotected:\n\tCallbackT const _callback;\n\tFlagsT    const _flag;\n\nprivate:\n\tFlagsT    GetFlags()    const { return _flag; }\n};\n\n/// 従来の TJSCreateNativeClassMethod用 ncbIMethodObjectラッパ\ntemplate <>\nstruct ncbRawCallbackMethod<tTJSNativeClassMethodCallback> : public ncbIMethodObject {\n\ttypedef ncbRawCallbackMethod ThisClassT;\n\ttypedef tTJSNativeClassMethodCallback CallbackT;\n\ttypedef ncbNativeClassMethodBase::iMethodT iMethodT;\n\n\tncbRawCallbackMethod(CallbackT m, FlagsT f) : _dispatch(TJSCreateNativeClassMethod(m)), _flags(f) {}\n\n\tDispatchT GetDispatch() const { return _dispatch; }\n\tFlagsT    GetFlags()    const { return _flags; }\n\tTypesT    GetType()     const { return nitMethod; }\n\tvoid      Release()     const { delete this; }\n\n\t/// PropertyからFuncCallが直接呼ばれるのでラップ\n\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\treturn _dispatch->FuncCall(flag, membername, hint, result, numparams, param, objthis);\n\t}\n\n\t/// factory\n\tstatic iMethodT Create(CallbackT cb, FlagsT f, bool create = true) { return !create ? 0 : (new ThisClassT(cb, f)); }\nprivate:\n\tDispatchT const _dispatch;\n\tFlagsT    const _flags;\n};\n\n\n////////////////////////////////////////\n/// プロパティ用 RawCallback\n\n// ncbRawCallbackMethod と AccessDenied を返すダミー型のセレクタ\ntemplate <typename CallbackT>\nstruct ncbRawCallbackPropertySelector {\n\ttypedef ncbRawCallbackMethod<CallbackT> Type;\n};\ntemplate <>\nstruct ncbRawCallbackPropertySelector<int> {\n\ttypedef struct AccessDenied {\n\t\tAccessDenied(int, ncbNativeClassMethodBase::FlagsT) {}\n\t\ttjs_error  TJS_INTF_METHOD FuncCall(\n\t\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\t\ttTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t\t{\n\t\t\treturn TJS_E_ACCESSDENYED;\n\t\t}\n\t} Type;\n};\n\n// ncbRawCallbackMethod を二つ束ねて実装\ntemplate <typename GETTER, typename SETTER>\nstruct ncbRawCallbackProperty : public ncbNativeClassMethodBase {\n\ttypedef ncbRawCallbackProperty ThisClassT;\n\ttypedef GETTER GetCallbackT;\n\ttypedef SETTER SetCallbackT;\n\ttypedef typename ncbRawCallbackPropertySelector<GetCallbackT>::Type GetterT;\n\ttypedef typename ncbRawCallbackPropertySelector<SetCallbackT>::Type SetterT;\n\n\t/// constructor\n\tncbRawCallbackProperty(GetCallbackT get, SetCallbackT set, FlagsT f)\n\t\t: ncbNativeClassMethodBase(nitProperty), // TJSオブジェクト的には Property\n\t\t  _getter(get, f), _setter(set, f), _flag(f) {} \n\n\t/// PropGet 実装\n\ttjs_error TJS_INTF_METHOD PropGet(\n\t\ttjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, \n\t\ttTJSVariant *result, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::PropGet(flag, membername, hint, result, objthis);\n\t\t// メソッド呼び出し\n\t\treturn _getter.FuncCall(flag, membername, hint, result, 0, 0, objthis);\n\t}\n\n\t/// PropSet 実装\n\ttjs_error TJS_INTF_METHOD PropSet(\n\t\ttjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, \n\t\tconst tTJSVariant *param, iTJSDispatch2 *objthis)\n\t{\n\t\t// 自分自身が呼ばれたのではない場合は丸投げ\n\t\tif (membername) return BaseT::PropSet(flag, membername, hint, param, objthis);\n\t\t// メソッド呼び出し\n\t\ttTJSVariant *params[1] = { const_cast<tTJSVariant *>(param) };\n\t\treturn _setter.FuncCall(flag, membername, hint, 0, 1, params, objthis);\n\t}\n\n\t/// TJSNativeClassRegisterNCMフラグ\n\tFlagsT GetFlags() const { return _flag; }\n\n\t/// factory\n\tstatic iMethodT Create(GetCallbackT get, SetCallbackT set, FlagsT f, bool create = true) { return !create ? 0 : (new ThisClassT(get, set, f))->GetIMethod(); }\nprotected:\n\tGetterT _getter;\n\tSetterT _setter;\n\tFlagsT _flag;\n};\n\n\n/// サブクラス登録用\ntemplate <class T>\nstruct ncbSubClassItem;\n\n\n////////////////////////////////////////\n/// NativeClass クラスオブジェクト登録テンプレート\n\ntemplate <class IMPL>\nstruct ncbRegistClass : public ncbNativeClassMethodBase::InvokeType {\n\ttypedef ncbTypedefs _DefsT;\n\ttypedef IMPL     _ImplementT;\n\ttypedef typename _ImplementT::NativeClassT _ClassT;\n\ttypedef typename _ImplementT::NameT        _NameT;\n\ttypedef typename _ImplementT::StringT      _StringT;\n\ttypedef typename _ImplementT::FlagsT       _FlagsT;\n\ttypedef typename _ImplementT::ItemT        _ItemT;\n\n\tncbRegistClass(_ImplementT &d, bool r) : _impl(d), _isRegist(r), Normal(), Proxy() { Begin(); }\n\t~ncbRegistClass() { End(); }\n\nprivate:\n\t_ImplementT &_impl;\n\tbool  const _isRegist;\n\n\tivtNormal           const Normal;\n\tivtProxy<ivtNormal> const Proxy;\n\n\ttemplate <class BRIDGE> struct      Bridge { typedef BRIDGE BridgeT; };\n\ttemplate <class BRIDGE> struct ProxyBridge { typedef BRIDGE BridgeT; };\n\ttemplate <class BRIDGE> struct BridgeProxy { typedef BRIDGE BridgeT; };\n\ttemplate <class METHOD>          ivtBridge<METHOD>        getBridgeType(METHOD) const { return          ivtBridge<METHOD>  (); }\n\ttemplate <class METHOD> ivtProxy<ivtBridge<METHOD> > getProxyBridgeType(METHOD) const { return ivtProxy<ivtBridge<METHOD> >(); }\n\n\ttypedef _ClassT       Class;\n\ttypedef _ClassT       ClassT;\n\ttypedef _ClassT const Const;\n\ttypedef void          Static;\n\n\ttemplate <typename BASE, typename METHOD>\n\tstruct MethodType {\n\t\ttypedef typename _DefsT::CallerT::tMethodResolver<\n\t\t\ttypename _DefsT::CallerT::tMethodTraits<METHOD>::ResultType, BASE,\n\t\t/**/typename _DefsT::CallerT::tMethodTraits<METHOD>::ArgsType>::Type Type;\n\t};\n\npublic:\n\ttemplate <typename T>\n\tstruct TypeWrap { typedef T Type; };\n\t_NameT   GetName() const\t\t\t{ return _impl.GetName(); }\n\t_NameT   GetName(_NameT  n) const\t{ return n; }\n\ttemplate <typename OTHER>\n\t_StringT GetName(OTHER s) const\t\t{ return _StringT(s); }\n\tvoid Begin()\t\t\t\t\t\t{ if (_isRegist) _impl.RegistBegin();            else _impl.UnregistBegin(); }\n\tvoid End()\t\t\t\t\t\t\t{ if (_isRegist) _impl.RegistEnd();              else _impl.UnregistEnd(); }\n\tvoid DoItem(_NameT   n, _ItemT t)\t{ if (_isRegist) _impl.RegistItem(n,         t); else _impl.UnregistItem(n);         }\n\tvoid DoItem(_StringT s, _ItemT t)\t{ if (_isRegist) _impl.RegistItem(s.c_str(), t); else _impl.UnregistItem(s.c_str()); }\n\n\t/// メソッドを登録する\n\ttemplate <typename NAME, typename MethodT, class IVT>\n\tvoid Method(NAME n, MethodT m, IVT const&) {\n\t\tDoItem(GetName(n), ncbNativeClassMethod< InvokeCommand<ClassT, MethodT, IVT> >::Create(m, _isRegist));\n\t}\n\n\t/// プロパティを登録する\n\ttemplate <typename NAME, typename GetterT, typename SetterT, class IVT>\n\tvoid Property(NAME n, GetterT g, SetterT s, IVT const&) {\n\t\tDoItem(GetName(n), ncbNativeClassProperty< PropertyCommand<ClassT, GetterT, SetterT, IVT> >::Create(g, s, _isRegist));\n\t}\n\n\t// 読み込み・書き込み専用プロパティ\n\ttemplate <typename NAME, typename GetterT, class IVT> void Property(NAME n, GetterT g, int, IVT const &tag) { Property(n, g, static_cast<GetterT>(0), tag); }\n\ttemplate <typename NAME, typename SetterT, class IVT> void Property(NAME n, int, SetterT s, IVT const &tag) { Property(n, static_cast<SetterT>(0), s, tag); }\n\n\t// InvokeType省略時\n\ttemplate <typename NAME, typename MethodT>                   void Method(  NAME n, MethodT m)            { Method(  n, m,    Normal); }\n\ttemplate <typename NAME, typename GetterT, typename SetterT> void Property(NAME n, GetterT g, SetterT s) { Property(n, g, s, Normal); }\n\n\t// Bridge 時\n\ttemplate <typename N, typename M, class B>             void Method(  N n, M m,           Bridge<B> const&) { Method(  n, m,    getBridgeType(     &B::operator())); }\n\ttemplate <typename N, typename M, class B>             void Method(  N n, M m,      ProxyBridge<B> const&) { Method(  n, m,    getProxyBridgeType(&B::operator())); }\n\ttemplate <typename N, typename M, class B>             void Method(  N n, M m,      BridgeProxy<B> const&) { Method(  n, m,    getProxyBridgeType(&B::operator())); }\n\ttemplate <typename N, typename G, typename S, class B> void Property(N n, G g, S s,      Bridge<B> const&) { Property(n, g, s, getBridgeType(     &B::operator())); }\n\ttemplate <typename N, typename G, typename S, class B> void Property(N n, G g, S s, ProxyBridge<B> const&) { Property(n, g, s, getProxyBridgeType(&B::operator())); }\n\ttemplate <typename N, typename G, typename S, class B> void Property(N n, G g, S s, BridgeProxy<B> const&) { Property(n, g, s, getProxyBridgeType(&B::operator())); }\n\n\t/// コンストラクタを登録する\n\ttemplate <typename MethodT>\n\tvoid Constructor(TypeWrap<MethodT>) {\n\t\tDoItem(GetName(), ncbNativeClassConstructor< InvokeCommand<ClassT, MethodT, ivtCtor> >::Create(0, _isRegist));\n\t}\n\t// デフォルトコンストラクタの登録\n\tvoid Constructor(int dummy = 0) { Constructor(TypeWrap<void (_ClassT::*)()>()); }\n#undef  FOREACH_START\n#define FOREACH_START 1\n#undef  FOREACH_END\n#define FOREACH_END   FOREACH_MAX\n#define CTOR_PRM_EXT(n) typename T ## n\n#define CTOR_ARG_EXT(n)          T ## n\n\t// テンプレによる展開\n\t// Constructor<T1, T2, ...>(0); で ClassT(T1, T2, ...) のコンストラクタを登録する\n#undef  FOREACH\n#define FOREACH \\\n\ttemplate <FOREACH_COMMA_EXT(CTOR_PRM_EXT) > \\\n\t\tvoid    Constructor(         typename _DefsT::CallerT::tMethodType<void, _ClassT, FOREACH_COMMA_EXT(CTOR_ARG_EXT)>::Type) { \\\n\t\t\t/**/Constructor(TypeWrap<typename _DefsT::CallerT::tMethodType<void, _ClassT, FOREACH_COMMA_EXT(CTOR_ARG_EXT)>::Type>()); \\\n\t\t}\n#include FOREACH_INCLUDE\n#undef  CTOR_PRM_EXT\n#undef  CTOR_ARG_EXT\n\n\t// ファクトリを登録\n\ttemplate <typename MethodT>\n\tvoid Factory(MethodT m) {\n\t\tDoItem(GetName(), ncbNativeClassConstructor< InvokeCommand<ClassT, MethodT, ivtFactory> >::Create(m, _isRegist));\n\t}\n\t// RawCallback Factory\n\tvoid RawCallback(typename ncbNativeClassFactory<ClassT>::MethodT m) { Factory(m); }\n\tvoid Factory(    typename ncbNativeClassFactory<ClassT>::MethodT m) {\n\t\tDoItem(GetName(),     ncbNativeClassFactory<ClassT>::Create(m, _isRegist));\n\t}\n\n\t/// RawCallback Method\n\ttemplate <typename NAME, typename MethodT>\n\tvoid RawCallback(NAME n, MethodT m, _FlagsT flags) {\n\t\tDoItem(GetName(n), ncbRawCallbackMethod<MethodT>::Create(m, flags, _isRegist));\n\t}\n\n\t/// RawCallback Property\n\ttemplate <typename NAME, typename GetterT, typename SetterT>\n\tvoid RawCallback(NAME n, GetterT g, SetterT s, _FlagsT flags) {\n\t\tDoItem(GetName(n), ncbRawCallbackProperty<GetterT, SetterT>::Create(g, s, flags, _isRegist));\n\t}\n\n\t/// サブクラスを登録する\n\ttemplate <typename NAME, typename CLASS>\n\tvoid SubClass(NAME n, TypeWrap<CLASS>) {\n\t\ttypedef ncbSubClassItem<CLASS> SubClassT;\n\t\tif (!SubClassT::Setup(GetName(n), _isRegist))\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"SubClass registration failed.\"));\n\t\tDoItem(GetName(n), SubClassT::Create(_isRegist));\n\t}\n\n\t/// tTJSVariantを登録する\n\ttemplate <typename NAME, typename VALUE>\n\tvoid Variant(NAME n, VALUE const v, _FlagsT flag = TJS_STATICMEMBER) {\n\t\ttypedef typename ncbTypeConvertor::SelectConvertorType<tTJSVariant, VALUE>::Type ConvT;\n\t\t_StringT s(n);\n\t\t_NameT name = s.c_str();\n\t\tif (!_isRegist)_impl.UnregistItem( name);\n\t\telse {\n\t\t\tConvT cv;\n\t\t\ttTJSVariant var;\n\t\t\tcv(var, v);\n\t\t\t_impl.RegistVariant(name, var, flag);\n\t\t}\n\t}\n\n\tvoid Regist();\n};\n\n////////////////////////////////////////\n\nstruct ncbRegistNativeClassBase {\n\ttypedef ncbNativeClassMethodBase::NameT      NameT;\n\ttypedef ncbNativeClassMethodBase::iMethodT   ItemT;\n\ttypedef ncbNativeClassMethodBase::FlagsT     FlagsT;\n\ttypedef tTJSString                           StringT;\n\tncbRegistNativeClassBase(NameT name) : _className(name) {}\n\n\tvoid   RegistBegin()\t\t\t{}\n\tvoid   RegistItem(NameT, ItemT)\t{}\n\tvoid   RegistEnd()\t\t\t\t{}\n\tvoid UnregistBegin()\t\t\t{}\n\tvoid UnregistItem(NameT)\t\t{}\n\tvoid UnregistEnd()\t\t\t\t{}\n\tvoid   RegistVariant(NameT, tTJSVariant const &, FlagsT) {}\n\n\tNameT  GetName() const {return _className; }\nprotected:\n\tNameT const _className;\n};\n\ntemplate <class CLASS>\nstruct ncbRegistNativeClass : public ncbRegistNativeClassBase {\n\ttypedef                          ncbRegistNativeClassBase BaseT;\n\ttypedef CLASS                                NativeClassT;\n\ttypedef ncbInstanceAdaptor<NativeClassT>     AdaptorT;\n\n\ttypedef ncbClassInfo<NativeClassT>           ClassInfoT;\n\ttypedef typename ClassInfoT::IdentT          IdentT;\n\ttypedef typename ClassInfoT::ClassObjectT    ClassObjectT;\n\n\tncbRegistNativeClass(NameT n) : BaseT(n), _classobj(0), _hasCtor(false) {}\n\n\tvoid RegistBegin() {\n\t\tNCB_LOG_2(TJS_W(\"BeginRegistClass: \"), _className);\n\n\t\t// クラスオブジェクトを生成\n\t\t_classobj = TJSCreateNativeClassForPlugin(_className, AdaptorT::CreateEmptyAdaptor);\n\n\t\t// クラスIDを生成\n\t\tIdentT id  = TJSRegisterNativeClass(_className);\n\n\t\t// ncbClassInfoに登録\n\t\tif (!ClassInfoT::Set(_className, id, _classobj))\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Already registerd class.\"));\n\n\t\t// クラスオブジェクトにIDを設定\n\t\tTJSNativeClassSetClassID(_classobj, id);\n\n\t\t// 空のfinalizeメソッドを追加\n\t\tTJSNativeClassRegisterNCM(_classobj, TJS_W(\"finalize\"),\n\t\t\t\t\t\t\t\t  TJSCreateNativeClassMethod(EmptyCallback),\n\t\t\t\t\t\t\t\t  _className, nitMethod);\n\t}\n\n\tvoid RegistVariant(NameT name, tTJSVariant const &val, FlagsT flg) {\n\t\t_classobj->PropSet(TJS_MEMBERENSURE | flg, name, 0, &val, _classobj);\n\t}\n\n\tvoid RegistItem(NameT name, ItemT item) {\n\t\tNCB_LOG_2(TJS_W(\"  RegistItem: \"), name);\n\t\tif (name == _className) {\n\t\t\tif (_hasCtor) TVPAddLog(tTJSString(TJS_W(\"Multiple constructors.(\")) + _className + TJS_W(\")\"));\n\t\t\t_hasCtor = true;\n\t\t}\n\t\tif (item) {\n\t\t\tTJSNativeClassRegisterNCM(_classobj, name, item->GetDispatch(), _className, item->GetType(), item->GetFlags());\n\t\t\titem->Release();\n\t\t}\n\t}\n\n\tvoid RegistEnd() {\n\t\t// コンストラクタがない場合はエラーを返すコンストラクタを追加する\n\t\t_AddDummyConstructor();\n\n\t\t// TJS のグローバルオブジェクトを取得する\n\t\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\t\tif (!global) {\n\t\t\tNCB_WARN_W(\"No Global Dispatch, Regist failed.\");\n\t\t\treturn;\n\t\t}\n\n\t\t// 2 _classobj を tTJSVariant 型に変換\n\t\ttTJSVariant val(static_cast<iTJSDispatch2*>(_classobj));\n\n\t\t// 3 すでに val が _classobj を保持しているので、_classobj は Release する\n\t\t_classobj->Release();\n\n\t\t// 4 global の PropSet メソッドを用い、オブジェクトを登録する\n\t\tglobal->PropSet(\n\t\t\tTJS_MEMBERENSURE, // メンバがなかった場合には作成するようにするフラグ\n\t\t\t_className, // メンバ名\n\t\t\t0, // ヒント ( 本来はメンバ名のハッシュ値だが、NULL でもよい )\n\t\t\t&val, // 登録する値\n\t\t\tglobal // コンテキスト ( global でよい )\n\t\t\t);\n\n\t\t// - global を Release する\n\t\tglobal->Release();\n\n\t\t// val をクリアする。\n\t\t// これは必ず行う。そうしないと val が保持しているオブジェクト\n\t\t// が Release されず、次に使う TVPPluginGlobalRefCount が正確にならない。\n\t\t//val.Clear();\n\t\t// …のだがローカルスコープで自動的に消去されるので必要ない\n\n\t\tNCB_LOG_2(TJS_W(\"EndRegistClass: \"), _className);\n\t}\n\n\t/// プラグイン開放時にクラスオブジェクトをリリースする\n\tvoid UnregistEnd() {\n\t\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\t\tif (global) {\n\t\t\tglobal->DeleteMember(0, _className, 0, global);\n\t\t\tglobal->Release();\n\t\t}\n\t\t_RemoveClassInfo();\n\t\tNCB_LOG_2(TJS_W(\"EndUnregistClass: \"), _className);\n\t}\n\tvoid UnregistBegin() {\n\t\tNCB_LOG_2(TJS_W(\"BeginUnregistClass: \"), _className);\n\t}\n\nprivate:\n\tClassObjectT *_classobj;\t//< クラスオブジェクト\n\tbool          _hasCtor;\t\t//< コンストラクタを登録したか\n\n\t/// 空のメソッド(finalize Callback用)\n\tstatic tjs_error TJS_INTF_METHOD EmptyCallback(  tTJSVariant *, tjs_int, tTJSVariant **, iTJSDispatch2 *) { return TJS_S_OK; }\n\n\t/// エラーを返すメソッド(empty Constructor用)\n\tstatic tjs_error TJS_INTF_METHOD NotImplCallback(tTJSVariant *, tjs_int, tTJSVariant **, iTJSDispatch2 *) { return TJS_E_NOTIMPL; }\n\nprotected:\n\tvoid _AddDummyConstructor() const {\n\t\tif (!_hasCtor) TJSNativeClassRegisterNCM(_classobj, _className,\n\t\t\t\t\t\t\t\t\t\t\t\t TJSCreateNativeClassMethod(NotImplCallback),\n\t\t\t\t\t\t\t\t\t\t\t\t _className, nitMethod);\n\t}\n\tvoid _RemoveClassInfo() const {\n\t\tNCB_LOG_2(TJS_W(\"  RemoveClassInfo: \"), _className);\n\t\tClassInfoT::Clear();\n\t}\n};\n\n////////////////////////////////////////\ntemplate <class CLASS>\nstruct ncbRegistSubClass : public ncbRegistNativeClass<CLASS> {\n\ttypedef                       ncbRegistNativeClass<CLASS> BaseT;\n\tncbRegistSubClass(typename BaseT::NameT n) : BaseT(n) {}\n\tvoid RegistEnd() {\n\t\tBaseT::_AddDummyConstructor();\n\t\tNCB_LOG_2(TJS_W(\"EndSubClass: \"), BaseT::_className);\n\t}\n\tvoid UnregistEnd() {\n\t\tBaseT::_RemoveClassInfo();\n\t\tNCB_LOG_2(TJS_W(\"EndUnregistSubClass: \"), BaseT::_className);\n\t}\n};\n\ntemplate <class T>\nstruct ncbSubClassItem : public ncbIMethodObject {\n\ttypedef ncbSubClassItem ThisClassT;\n\ttypedef ncbNativeClassMethodBase::iMethodT iMethodT;\n\ttypedef ncbClassInfo<T> ClassInfoT;\n\n\tDispatchT GetDispatch() const { return static_cast<DispatchT>(ClassInfoT::GetClassObject()); }\n\tFlagsT    GetFlags()    const { return TJS_STATICMEMBER; }\n\tTypesT    GetType()     const { return nitClass; }\n\tvoid      Release()     const { delete this; }\n\n\t/// factory\n\tstatic iMethodT Create(bool create = true) { return !create ? 0 : (new ThisClassT()); }\n\n\tstatic bool Setup(ncbTypedefs::NameT name, bool isRegist) {\n\t\ttypedef ncbRegistSubClass<T> DelegateT;\n\t\ttypedef ncbRegistClass<DelegateT> RegistT;\n\n\t\tif (isRegist && ClassInfoT::GetClassObject()) return false;\n\t\tDelegateT d(name);\n\t\t{\n\t\t\tRegistT r(d, isRegist);\n\t\t\tr.Regist();\n\t\t}\n\t\treturn isRegist ? (ClassInfoT::GetClassObject() != 0) : true;\n\t}\n};\n\n\n////////////////////////////////////////\n/// 既存クラスオブジェクトを変更する\n\ntemplate <class CLASS>\nstruct ncbAttachTJS2Class : public ncbRegistNativeClassBase {\n\ttypedef                        ncbRegistNativeClassBase BaseT;\n\ttypedef CLASS                                NativeClassT;\n\ttypedef ncbClassInfo<NativeClassT>           ClassInfoT;\n\ttypedef typename ClassInfoT::IdentT          IdentT;\n\ttypedef typename ClassInfoT::ClassObjectT    ClassObjectT;\n\n\tncbAttachTJS2Class(NameT nativeClass, NameT tjs2Class) : BaseT(nativeClass), _tjs2ClassName(tjs2Class) {}\n\n\tvoid RegistBegin() {\n\t\tNCB_LOG_2(TJS_W(\"BeginAttachTJS2Class: \"), _className);\n\n\t\t// TJS のグローバルオブジェクトを取得する\n\t\t_global = TVPGetScriptDispatch();\n\t\t_tjs2ClassObj = GetGlobalObject(_tjs2ClassName, _global);\n\n\t\t// クラスIDを生成\n\t\tIdentT id  = TJSRegisterNativeClass(_className);\n\t\tNCB_LOG_2(TJS_W(\"  ID: \"), (tjs_int)id);\n\n\t\t// ncbClassInfoに登録\n\t\tif (!ClassInfoT::Set(_className, id, 0)) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Already registerd class:\"), ttstr(_className));\n\t\t}\n\t}\n\n\tvoid RegistVariant(NameT name, tTJSVariant const &val, FlagsT flg) {\n\t\t_tjs2ClassObj->PropSet(TJS_MEMBERENSURE | flg, name, 0, &val, ((flg & TJS_STATICMEMBER) ? _global : _tjs2ClassObj));\n\t}\n\n\tvoid RegistItem(NameT name, ItemT item) {\n\t\tNCB_LOG_2(TJS_W(\"  RegistItem: \"), name);\n\t\tif (!item) return;\n\t\tif (name == _className) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Constructor attached: \"), ttstr(_className));\n\t\t}\n\t\tiTJSDispatch2 *dsp = item->GetDispatch();\n\t\ttTJSVariant val(dsp);\n\t\tdsp->Release();\n\t\tFlagsT flg = item->GetFlags();\n\t\tRegistVariant(name, val, flg);\n\t\titem->Release();\n\t}\n\n\tvoid RegistEnd() {\n\t\tif (_global) _global->Release();\n\t\t_global = 0;\n\t\tNCB_LOG_2(TJS_W(\"EndAttachClass: \"), _className);\n\t\t// _tjs2ClassObj は NoAddRef なので Release 不要\n\t}\n\n\tvoid UnregistBegin() {\n\t\tNCB_LOG_2(TJS_W(\"BeginDetach: \"), _className);\n\t\t// クラスオブジェクトを取得\n\t\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\t\tif (global) {\n\t\t\t_tjs2ClassObj = GetGlobalObject(_tjs2ClassName, global);\n\t\t\tglobal->Release();\n\t\t} else {\n\t\t\t_tjs2ClassObj = NULL;\n\t\t}\n\t}\n\tvoid UnregistItem(NameT name) {\n\t\tNCB_LOG_2(TJS_W(\"DetachItem: \"), name);\n\t\tif (_tjs2ClassObj) {\n\t\t\t_tjs2ClassObj->DeleteMember(0, name, 0, _tjs2ClassObj);\n\t\t}\n\t}\n\tvoid UnregistEnd() {\n\t\tClassInfoT::Clear();\n\t\tNCB_LOG_2(TJS_W(\"EndDetach: \"), _className);\n\t\t// _tjs2ClassObj は NoAddRef なので Release 不要\n\t}\nprotected:\n\tNameT const    _tjs2ClassName;\n\tiTJSDispatch2* _tjs2ClassObj;\t//< クラスオブジェクト\n\tiTJSDispatch2* _global;\n\n\t// クラスオブジェクトを取得\n\tstatic iTJSDispatch2* GetGlobalObject(NameT name, iTJSDispatch2 *global) {\n\t\ttTJSVariant val;\n\t\tif (global) global->PropGet(0, name, 0, &val, global);\n\t\telse {\n\t\t\tNCB_WARN_W(\"No Global Dispatch.\");\n\t\t\tTVPExecuteExpression(name, &val);\n\t\t}\n\t\treturn val.AsObjectNoAddRef();\n\t}\n};\n\n\n\n\n////////////////////////////////////////\n/// TJSクラス自動レジストクラス（スレッドアンセーフなので必要なら適当に修正のこと）\n// 基本的に static const なインスタンスしか使用されないのでこれで十分な気はする\nstruct ncbAutoRegister {\n\ttypedef ncbAutoRegister ThisClassT;\n\ttypedef void (*CallBackT)();\n\ttypedef ncbTypedefs DefsT;\n\ttypedef DefsT::NameT NameT;\n\ttypedef DefsT::BoolTag<true>  TrueTagT;\n\ttypedef DefsT::BoolTag<false> FalseTagT;\n\n\tenum LineT {\n\t\tPreRegist = 0,\n\t\tClassRegist,\n\t\tPostRegist,\n\t\tLINE_COUNT };\n#define NCB_INNER_AUTOREGISTER_LINES_INSTANCE { 0, 0, 0 }\n\tNameT modulename;\n\tncbAutoRegister(NameT name, LineT line) : modulename(name), _next(_top[line]) { _top[line] = this; }\n\n\tstatic void AllRegist(  LineT line) {\n#ifdef _DEBUG\n\t\tNCB_LOG_2(TJS_W(\"AllRegist:\"), line);\n#endif\n\t\tfor (ThisClassT const* p = _top[line]; p; p = p->_next) {\n\t\t\tttstr name = p->modulename;\n\t\t\tname.ToLowerCase();\n\t\t\t_internal_plugins[name].lists[line].push_back(p);//p->Regist();\n\t\t}\n\t}\n\tstatic void AllUnregist(LineT line) {\n#ifdef _DEBUG\n\t\tNCB_LOG_2(TJS_W(\"AllUnregist:\"), line);\n#endif\n\t\tfor (ThisClassT const* p = _top[line]; p; p = p->_next)\n\t\t\tp->Unregist();\n\t}\n\n\tstatic void AllRegist()   { for (int line = 0; line < LINE_COUNT; line++) AllRegist(  static_cast<LineT>(line)); }\n\tstatic void AllUnregist() { for (int line = 0; line < LINE_COUNT; line++) AllUnregist(static_cast<LineT>(line)); }\n\tstatic bool LoadModule(const ttstr &_name);\nprotected:\n\tvirtual void Regist()   const = 0;\n\tvirtual void Unregist() const = 0;\nprivate:\n\tncbAutoRegister();\n\t/****/ ThisClassT const* _next;\n\tstatic ThisClassT const* _top[LINE_COUNT];\n\n    struct INTERNAL_PLUGIN_LISTS {\n        std::list<ThisClassT const*> lists[LINE_COUNT];\n    };\n\n\tstatic std::map<ttstr, INTERNAL_PLUGIN_LISTS > _internal_plugins;\n};\n\n////////////////////////////////////////\ntemplate <class T>\nstruct  ncbNativeClassAutoRegister : public ncbAutoRegister {\n\t/**/ncbNativeClassAutoRegister(NameT modulename, NameT n) : ncbAutoRegister(modulename, ClassRegist), _name(n) {}\n\n\ttypedef ncbRegistNativeClass<T> DelegateT;\n\ttypedef ncbRegistClass<DelegateT> RegistT;\nprivate:\n\tNameT const _name;\nprotected:\n\tvoid Regist()   const { DelegateT d(_name); { RegistT r(d, true);  r.Regist(); } }\n\tvoid Unregist() const { DelegateT d(_name); { RegistT r(d, false); r.Regist(); } }\n};\n\n#define NCB_REGISTER_CLASS_COMMON(cls, tmpl, init) \\\n\ttemplate    struct ncbClassInfo<cls>; \\\n/*\ttemplate <>        ncbClassInfo<cls>::InfoT ncbClassInfo<cls>::_info;*/ \\\n\tstatic tmpl<cls> tmpl ## _ ## cls init; \\\n\ttemplate <> void   tmpl<cls>::RegistT::Regist()\n\n#define NCB_REGISTER_CLASS_DELAY(name, cls) \\\n\tNCB_REGISTER_CLASS_COMMON(cls, ncbNativeClassAutoRegister, (NCB_MODULE_NAME, TJS_W(# name)))\n\n#define NCB_REGISTER_CLASS(cls) NCB_REGISTER_CLASS_DIFFER(cls, cls)\n#define NCB_REGISTER_CLASS_DIFFER(name, cls) \\\n\tNCB_TYPECONV_BOXING(cls); \\\n\tNCB_REGISTER_CLASS_COMMON(cls, ncbNativeClassAutoRegister, (NCB_MODULE_NAME, TJS_W(# name)))\n\n#define NCB_REGISTER_SUBCLASS_DELAY(cls) \\\n\ttemplate <> struct ncbSubClassCheck<cls> { enum { IsSubClass = true }; }; \\\n\ttemplate    struct ncbClassInfo<cls>; \\\n/*\ttemplate <>        ncbClassInfo<cls>::InfoT ncbClassInfo<cls>::_info;*/ \\\n\ttemplate <> void   ncbRegistClass<ncbRegistSubClass<cls> >::Regist()\n\n#define NCB_REGISTER_SUBCLASS(cls) \\\n\tNCB_TYPECONV_BOXING(cls); \\\n\tNCB_REGISTER_SUBCLASS_DELAY(cls)\n\n////////////////////////////////////////\ntemplate <class T>\nstruct  ncbAttachTJS2ClassAutoRegister : public ncbAutoRegister {\n\t/**/ncbAttachTJS2ClassAutoRegister(NameT modulename, NameT ncn, NameT tjscn) : ncbAutoRegister(modulename, ClassRegist), _nativeClassName(ncn), _tjs2ClassName(tjscn) {}\n\n\ttypedef ncbAttachTJS2Class<T>     DelegateT;\n\ttypedef ncbRegistClass<DelegateT> RegistT;\nprotected:\n\tvoid Regist()   const { DelegateT d(_nativeClassName, _tjs2ClassName); { RegistT r(d, true);  r.Regist(); } }\n\tvoid Unregist() const { DelegateT d(_nativeClassName, _tjs2ClassName); { RegistT r(d, false); r.Regist(); } }\nprivate:\n\tNameT const _nativeClassName;\n\tNameT const _tjs2ClassName;\n};\n\n////////////////////////////////////////\ntemplate <class T>\nstruct  ncbRequireClassAutoRegister : public ncbAutoRegister {\n\t/**/ncbRequireClassAutoRegister(NameT modulename, NameT name, NameT sub = 0) : ncbAutoRegister(modulename, ClassRegist), _className(name), _expName(sub) {}\n\n\ttypedef ncbClassInfo<T> ClassInfoT;\nprotected:\n\tvoid Regist()   const {\n\t\tNCB_LOG_2(TJS_W(\"RequireClass: \"), _className);\n\n\t\t// クラスオブジェクト取得\n\t\ttTJSVariant val;\n\t\tTVPExecuteExpression(ttstr(_expName ? _expName : _className), &val);\n\t\tif (val.Type() != tvtObject)\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Require class not found.\"));\n\n\t\t// IDとクラスオブジェクトを登録\n\t\tif (!ClassInfoT::Set(_className, TJSFindNativeClassID(_className), val.AsObjectNoAddRef()))\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"Already registerd class.\"));\n\t}\n\tvoid Unregist() const {}\nprivate:\n\tNameT const _className;\n\tNameT const _expName;\n};\n\n////////////////////////////////////////\n#define NCB_GET_INSTANCE_HOOK(cls) \\\n\ttemplate <> struct ncbNativeClassMethodBase::nativeInstanceGetter<cls> : public ncbNativeClassMethodBase::nativeInstanceGetterBase<cls>\n\n#define NCB_GET_INSTANCE_HOOK_CLASS nativeInstanceGetter\n\n#define NCB_INSTANCE_GETTER(objthis) \\\n\tinline ClassT* Get(DispatchT objthis)\n\n#define NCB_ATTACHED_INSTANCE_DELAY_CREATE(cls) \\\n\tNCB_GET_INSTANCE_HOOK(cls) { NCB_INSTANCE_GETTER(objthis) { \\\n\t\tClassT* obj = GetNativeInstance(objthis); \\\n\t\tif (!obj) { obj = new ClassT(); SetNativeInstance(objthis, obj); } \\\n\t\treturn obj; } }\n\n#define NCB_ATTACH_CLASS_WITH_HOOK(cls, attach) \\\n\ttemplate <> struct ncbNativeClassMethodBase::nativeInstanceGetter<cls>; \\\n\tNCB_REGISTER_CLASS_COMMON(cls, ncbAttachTJS2ClassAutoRegister, (NCB_MODULE_NAME, TJS_W(# cls), TJS_W(# attach)))\n\n#define NCB_ATTACH_CLASS(cls, attach) \\\n\tNCB_ATTACHED_INSTANCE_DELAY_CREATE(cls); \\\n\tNCB_ATTACH_CLASS_WITH_HOOK(cls, attach)\n\n#define NCB_REQUIRE_CLASS(cls)          template struct ncbClassInfo<cls>; static ncbRequireClassAutoRegister<cls> ncbRequireClass_ ## cls(TJS_W(# cls), 0)\n#define NCB_REQUIRE_SUBCLASS(cls, name) template struct ncbClassInfo<cls>; static ncbRequireClassAutoRegister<cls> ncbRequireClass_ ## cls(TJS_W(# cls), TJS_W(# name))\n\n\n////////////////////////////////////////\n#define NCB_METHOD_RAW_CALLBACK(name, cb, flag)         RawCallback(TJS_W(# name), cb,          flag)\n#define NCB_PROPERTY_RAW_CALLBACK(name, get, set, flag) RawCallback(TJS_W(# name), get,    set, flag)\n#define NCB_PROPERTY_RAW_CALLBACK_RO(name, get, flag)   RawCallback(TJS_W(# name), get, (int)0, flag)\n#define NCB_PROPERTY_RAW_CALLBACK_WO(name, set, flag)   RawCallback(TJS_W(# name), (int)0, set, flag)\n\n#define NCB_CONSTRUCTOR(cargs)                          Constructor(TypeWrap<void (Class::*) cargs >())\n\n#define NCB_METHOD_DIFFER(name, method)                 Method(TJS_W(# name), &Class::method)\n#define NCB_METHOD(method)                              NCB_METHOD_DIFFER(method, method)\n\n#define NCB_METHOD_CAST(tag, result, method, args)      static_cast<MethodType<tag, result (*) args >::Type>(&method)  // tag = { Class, Const, Static }\n#define NCB_METHOD_DETAIL(name, T,R,M,A)                Method(TJS_W(# name), NCB_METHOD_CAST(T, R, M, A))\n\n#define NCB_PROPERTY(name,get,set)                      Property(TJS_W(# name), &Class::get, &Class::set)\n#define NCB_PROPERTY_RO(name,get)                       Property(TJS_W(# name), &Class::get, (int)0)\n#define NCB_PROPERTY_WO(name,set)                       Property(TJS_W(# name), (int)0, &Class::set)\n\n#define NCB_PROPERTY_DETAIL(N,RT,RR,RM,RA,WT,WR,WM,WA)  Property(TJS_W(# N),    NCB_METHOD_CAST(RT,RR,RM,RA), NCB_METHOD_CAST(WT,WR,WM,WA))\n#define NCB_PROPERTY_DETAIL_RO(name, RT,RR,RM,RA)       Property(TJS_W(# name), NCB_METHOD_CAST(RT,RR,RM,RA), (int)0)\n#define NCB_PROPERTY_DETAIL_WO(name, WT,WR,WM,WA)       Property(TJS_W(# name), (int)0,                       NCB_METHOD_CAST(WT,WR,WM,WA))\n\n// さあ何がなんだかわかんなくなってきました（汗\n#define NCB_METHOD_PROXY(name, method)                  Method(TJS_W(# name), &method, Proxy)\n#define NCB_METHOD_PROXY_DETAIL(name, T,R,M,A)          Method(TJS_W(# name), NCB_METHOD_CAST(T,R,M,A), Proxy)\n#define NCB_PROPERTY_PROXY(name,get,set)                Property(TJS_W(# name), &get, &set, Proxy)\n#define NCB_PROPERTY_PROXY_RO(name,get)                 Property(TJS_W(# name), &Class::get, (int)0, Proxy)\n#define NCB_PROPERTY_PROXY_WO(name,set)                 Property(TJS_W(# name), (int)0, &Class::set, Proxy)\n#define NCB_PROPERTY_PROXY_DETAIL(N,RT,RR,RM,RA,WT,WR,WM,WA)\\\n\t/*                                                */Property(TJS_W(# N),    NCB_METHOD_CAST(RT,RR,RM,RA), NCB_METHOD_CAST(WT,WR,WM,WA)), Proxy)\n#define NCB_PROPERTY_PROXY_DETAIL_RO(name, RT,RR,RM,RA) Property(TJS_W(# name), NCB_METHOD_CAST(RT,RR,RM,RA), (int)0,                        Proxy)\n#define NCB_PROPERTY_PROXY_DETAIL_WO(name, WT,WR,WM,WA) Property(TJS_W(# name), (int)0,                       NCB_METHOD_CAST(WT,WR,WM,WA)), Proxy)\n\n#define NCB_SUBCLASS(name, cls)                         SubClass(TJS_W(# name), TypeWrap<cls>())\n\n\n////////////////////////////////////////\n/// TJSファンクション自動レジストクラス\n\nstruct  ncbNativeFunctionAutoRegister : public ncbAutoRegister {\n\tncbNativeFunctionAutoRegister(NameT name) : ncbAutoRegister(name, ClassRegist) {}\nprotected:\n\ttemplate <typename MethodT>\n\tstatic void RegistFunction(NameT name, NameT attach, MethodT m) {\n\t\ttypedef ncbNativeClassMethodBase::InvokeType IVT;\n\t\ttypedef ncbNativeClassMethod< IVT::InvokeCommand<void, MethodT, IVT::ivtNormal> > MethodObjectT;\n\t\tiTJSDispatch2 *dsp = GetDispatch(attach);\n\t\tif (!dsp) return;\n\t\tRegistItem(dsp, name, new MethodObjectT(m));\n\t}\n\tstatic void RegistFunction(NameT name, NameT attach, ncbTypedefs::CallbackT m) {\n\t\tiTJSDispatch2 *dsp = GetDispatch(attach);\n\t\tif (!dsp) return;\n\t\tRegistItem(dsp, name, TJSCreateNativeClassMethod(m));\n\t}\n\ttemplate <typename T>\n\tstatic inline void RegistItem(iTJSDispatch2 *dsp, NameT name, T *mobj) {\n\t\tif (mobj) {\n\t\t\ttTJSVariant val(mobj);\n\t\t\tmobj->Release();\n\t\t\tdsp->PropSet(TJS_MEMBERENSURE, name, 0, &val, dsp);\n\t\t}\n\t\tdsp->Release();\n\t}\n\n\tstatic void UnregistFunction(NameT name, NameT attach) {\n\t\tiTJSDispatch2 *dsp = GetDispatch(attach);\n\t\tif (!dsp) return;\n\t\tdsp->DeleteMember(0, name, 0, dsp);\n\t\tdsp->Release();\n\t}\n\nprivate:\n\tstatic iTJSDispatch2* GetDispatch(NameT attach) {\n\t\tiTJSDispatch2 *ret, *global = TVPGetScriptDispatch();\n\t\tif (!global) return 0;\n\n\t\tif (!attach) ret = global;\n\t\telse {\n\t\t\ttTJSVariant val;\n\t\t\tNameT p = attach;\n\t\t\t// ピリオド有無チェック\n\t\t\twhile (*p) if (*p++ == TJS_W('.')) break;\n\t\t\tif (!*p) {\n\t\t\t\t// global直下\n\t\t\t\tglobal->PropGet(0, attach, 0, &val, global);\n\t\t\t} else {\n\t\t\t\t// 複数階層奥の場合は面倒なのでevalで誤魔化す\n\t\t\t\tTVPExecuteExpression(ttstr(attach), &val);\n\t\t\t}\n\t\t\tret = val.AsObject();\n\t\t\tglobal->Release();\n\t\t}\n\t\treturn ret;\n\t}\n};\ntemplate <typename DUMMY>\nstruct ncbNativeFunctionAutoRegisterTempl;\n\n#define NCB_REGISTER_FUNCTION_COMMON(name, tag, attach, function) \\\n\tstruct ncbFunctionTag_ ## tag {}; \\\n\ttemplate <> struct ncbNativeFunctionAutoRegisterTempl<ncbFunctionTag_ ## tag> : public ncbNativeFunctionAutoRegister \\\n\t{\tncbNativeFunctionAutoRegisterTempl() : ncbNativeFunctionAutoRegister(NCB_MODULE_NAME){} \\\n\t\tvoid Regist()   const { RegistFunction(TJS_W(# name), attach, &function); } \\\n\t\tvoid Unregist() const { UnregistFunction(TJS_W(# name), attach); } }; \\\n\tstatic ncbNativeFunctionAutoRegisterTempl<ncbFunctionTag_ ## tag> ncbFunctionAutoRegister_ ## tag\n\n#define NCB_REGISTER_FUNCTION(name, function)                    NCB_REGISTER_FUNCTION_COMMON(name, name, 0, function)\n#define NCB_ATTACH_FUNCTION(name, attach, function)              NCB_REGISTER_FUNCTION_COMMON(name, attach ## _ ## name, TJS_W(# attach), function)\n#define NCB_ATTACH_FUNCTION_WITHTAG(name, tag, attach, function) NCB_REGISTER_FUNCTION_COMMON(name, tag ## _ ## name, TJS_W(# attach), function)\n\n\n\n\n////////////////////////////////////////\n/// レジスト前後のコールバック登録\nstruct ncbCallbackAutoRegister : public ncbAutoRegister {\n\ttypedef void (*CallbackT)();\n\n\tncbCallbackAutoRegister(NameT name, LineT line, CallbackT init, CallbackT term)\n\t\t: ncbAutoRegister(name, line), _init(init), _term(term) {}\nprotected:\n\tvoid Regist()   const { if (_init) _init(); }\n\tvoid Unregist() const { if (_term) _term(); }\nprivate:\n\tCallbackT _init, _term;\n};\n\n#define NCB_REGISTER_CALLBACK(pos, init, term, tag) static ncbCallbackAutoRegister ncbCallbackAutoRegister_ ## pos ## _ ## tag (NCB_MODULE_NAME, ncbAutoRegister::pos, init, term)\n#define NCB_PRE_REGIST_CALLBACK(cb)    NCB_REGISTER_CALLBACK(PreRegist,  &cb, 0, cb ## _0)\n#define NCB_POST_REGIST_CALLBACK(cb)   NCB_REGISTER_CALLBACK(PostRegist, &cb, 0, cb ## _0)\n#define NCB_PRE_UNREGIST_CALLBACK(cb)  NCB_REGISTER_CALLBACK(PreRegist,  0, &cb, 0_ ## cb)\n#define NCB_POST_UNREGIST_CALLBACK(cb) NCB_REGISTER_CALLBACK(PostRegist, 0, &cb, 0_ ## cb)\n\n\n#endif\n"
  },
  {
    "path": "src/plugins/saveStruct.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n#include \"PluginIntf.h\"\n#define NCB_MODULE_NAME TJS_W(\"saveStruct.dll\")\n\nclass tTVPStringStream\n{\n\ttTJSBinaryStream *stream;\n\tconst tjs_char *_newline;\n\npublic:\n\ttTVPStringStream(tTJSBinaryStream *s, bool onlyLF = false);\n\tvoid write(tjs_char c);\n\tvoid write(const tjs_char *s);\n\tvoid write(tTVInteger var);\n\tvoid write(tTVReal var);\n\tvoid newline();\n};\n\ntTVPStringStream::tTVPStringStream(tTJSBinaryStream *s, bool onlyLF /*= false*/) : stream(s) {\n\tif (onlyLF)  _newline = TJS_W(\"\\n\");\n\telse        _newline = TJS_W(\"\\r\\n\");\n}\n\nvoid tTVPStringStream::write(tjs_char c) {\n\tstream->Write(&c, sizeof(c));\n}\n\nvoid tTVPStringStream::write(const tjs_char *s) {\n\tstream->Write(s, TJS_strlen(s) * sizeof(*s));\n}\n\nvoid tTVPStringStream::write(tTVInteger var) {\n\tttstr s = tTJSVariant(var).AsString();\n\tstream->Write(s.c_str(), s.length() * sizeof(tjs_char));\n}\n\nvoid tTVPStringStream::write(tTVReal var) {\n\tttstr s = tTJSVariant(var).AsString();\n\tstream->Write(s.c_str(), s.length() * sizeof(tjs_char));\n}\n\nvoid tTVPStringStream::newline() {\n\twrite(_newline);\n}\n\nstatic void\nquoteString(const tjs_char *str, tTVPStringStream *writer)\n{\n\tif (str) {\n\t\twriter->write((tjs_char)'\"');\n\t\tconst tjs_char *p = str;\n\t\tint ch;\n\t\twhile ((ch = *p++)) {\n\t\t\tif (ch == '\"') {\n\t\t\t\twriter->write(TJS_W(\"\\\\\\\"\"));\n\t\t\t} else if (ch == '\\\\') {\n\t\t\t\twriter->write(TJS_W(\"\\\\\\\\\"));\n\t\t\t} else {\n\t\t\t\twriter->write((tjs_char)ch);\n\t\t\t}\n\t\t}\n\t\twriter->write((tjs_char)'\"');\n\t} else {\n\t\twriter->write(TJS_W(\"\\\"\\\"\"));\n\t}\n}\n\nstatic void quoteOctet(tTJSVariantOctet *octet, tTVPStringStream *writer)\n{\n  const tjs_uint8 *data = octet->GetData();\n  tjs_uint length = octet->GetLength();\n  writer->write(TJS_W(\"<% \"));\n  for (tjs_uint i = 0; i < length; i++) {\n    tjs_char buf[256];\n    TJS_sprintf(buf, TJS_W(\"%02x \"), data[i]);\n    writer->write(buf);\n  }\n  writer->write(TJS_W(\"%>\"));\n}\n\nstatic void getVariantString(tTJSVariant &var, tTVPStringStream *writer);\n\n/**\n * ̓e\\p̌ĂяoWbN\n */\nclass DictMemberDispCaller : public tTJSDispatch /** EnumMembers p */\n{\nprotected:\n\ttTVPStringStream *writer;\n\tbool first;\npublic:\n\tDictMemberDispCaller(tTVPStringStream *writer) : writer(writer) { first = true; };\n\tvirtual tjs_error TJS_INTF_METHOD FuncCall( // function invocation\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\t\t\t\t\t\t\t\t\t\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant *result,\t\t// result\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant **param,\t\t// parameters\n\t\t\t\t\t\t\t\t\t\t\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t\t\t\t\t\t\t\t\t\t\t) {\n\t\tif (numparams > 1) {\n\t\t\ttTVInteger flag = param[1]->AsInteger();\n\t\t\tif (!(flag & TJS_HIDDENMEMBER)) {\n\t\t\t\tif (first) {\n\t\t\t\t\tfirst = false;\n\t\t\t\t} else {\n\t\t\t\t\twriter->write((tjs_char)',');\n\t\t\t\t\twriter->newline();\n\t\t\t\t}\n\t\t\t\tconst tjs_char *name = param[0]->GetString();\n\t\t\t\tquoteString(name, writer);\n\t\t\t\twriter->write(TJS_W(\"=>\"));\n\t\t\t\tgetVariantString(*param[2], writer);\n\t\t\t}\n\t\t}\n\t\tif (result) {\n\t\t\t*result = true;\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n};\n\nstatic void getDictString(iTJSDispatch2 *dict, tTVPStringStream *writer)\n{\n\twriter->write(TJS_W(\"%[\"));\n\t//writer->addIndent();\n\tDictMemberDispCaller *caller = new DictMemberDispCaller(writer);\n\ttTJSVariantClosure closure(caller);\n\tdict->EnumMembers(TJS_IGNOREPROP, &closure, dict);\n\tcaller->Release();\n\t//writer->delIndent();\n\twriter->write((tjs_char)']');\n}\n\n// Array NXo\nstatic iTJSDispatch2 *ArrayCountProp   = NULL;   // Array.count\n\nstatic void getArrayString(iTJSDispatch2 *array, tTVPStringStream *writer)\n{\n\twriter->write((tjs_char)'[');\n\t//writer->addIndent();\n\ttjs_int count = 0;\n\t{\n\t\ttTJSVariant result;\n\t\tif (TJS_SUCCEEDED(ArrayCountProp->PropGet(0, NULL, NULL, &result, array))) {\n\t\t\tcount = result;\n\t\t}\n\t}\n\tfor (tjs_int i=0; i<count; i++) {\n\t\tif (i != 0) {\n\t\t\twriter->write((tjs_char)',');\n\t\t\t//writer->newline();\n\t\t}\n\t\ttTJSVariant result;\n\t\tif (array->PropGetByNum(TJS_IGNOREPROP, i, &result, array) == TJS_S_OK) {\n\t\t\tgetVariantString(result, writer);\n\t\t}\n\t}\n\t//writer->delIndent();\n\twriter->write((tjs_char)']');\n}\n\nstatic void\ngetVariantString(tTJSVariant &var, tTVPStringStream *writer)\n{\n\tswitch(var.Type()) {\n\n\tcase tvtVoid:\n\t\twriter->write(TJS_W(\"void\"));\n\t\tbreak;\n\t\t\n\tcase tvtObject:\n\t\t{\n\t\t\tiTJSDispatch2 *obj = var.AsObjectNoAddRef();\n\t\t\tif (obj == NULL) {\n\t\t\t\twriter->write(TJS_W(\"null\"));\n\t\t\t} else if (obj->IsInstanceOf(TJS_IGNOREPROP,NULL,NULL,TJS_W(\"Array\"),obj) == TJS_S_TRUE) {\n\t\t\t\tgetArrayString(obj, writer);\n\t\t\t} else {\n\t\t\t\tgetDictString(obj, writer);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t\t\n\tcase tvtString:\n\t\tquoteString(var.GetString(), writer);\n\t\tbreak;\n\n        case tvtOctet:\n               quoteOctet(var.AsOctetNoAddRef(), writer);\n               break;\n\n\tcase tvtInteger:\n\t\twriter->write(TJS_W(\"int \"));\n\t\twriter->write(TJSIntegerToString((tTVInteger)var)->operator const tjs_char *());\n\t\tbreak;\n\n\tcase tvtReal:\n\t\twriter->write(TJS_W(\"real \"));\n\t\twriter->write((tTVReal)var);\n\t\tbreak;\n\n\tdefault:\n\t\twriter->write(TJS_W(\"void\"));\n\t\tbreak;\n\t};\n}\n\n//---------------------------------------------------------------------------\n\n/**\n * \\bhǉp\n */\nclass ArrayAdd {\n\npublic:\n\tArrayAdd(){};\n\n\t/**\n\t * save `ł̎܂͔z̕ۑ\n\t * @param filename t@C\n\t * @param utf true Ȃ UTF-8 ŏo\n\t * @param newline sR[h 0:CRLF 1:LF\n\t * @return s\n\t */\n\tstatic tjs_error TJS_INTF_METHOD save2(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t   tjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t   tTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t   iTJSDispatch2 *objthis) {\n\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n        tTJSBinaryStream *stream = TVPCreateStream(param[0]->AsString(), TJS_BS_WRITE);\n        tTVPStringStream writer(stream,\n            //numparams > 1 ? (int)*param[1] != 0: false,\n            numparams > 2 ? (int)*param[2] : 0\n            );\n// \t\tIFileWriter writer(param[0]->GetString(),\n// \t\t\t\t\t\t   numparams > 1 ? (int)*param[1] != 0: false,\n// \t\t\t\t\t\t   numparams > 2 ? (int)*param[2] : 0\n// \t\t\t\t\t\t   );\n//                 writer.hex = true;\n\t\ttjs_int count = 0;\n\t\t{\n\t\t\ttTJSVariant result;\n\t\t\tif (TJS_SUCCEEDED(ArrayCountProp->PropGet(0, NULL, NULL, &result, objthis))) {\n\t\t\t\tcount = result;\n\t\t\t}\n\t\t}\n\t\tfor (tjs_int i=0; i<count; i++) {\n\t\t\ttTJSVariant result;\n\t\t\tif (objthis->PropGetByNum(TJS_IGNOREPROP, i, &result, objthis) == TJS_S_OK) {\n\t\t\t\twriter.write(result.GetString());\n\t\t\t\twriter.newline();\n\t\t\t}\n\t\t}\n        delete stream;\n\t\treturn TJS_S_OK;\n\t}\n\n\t/**\n\t * saveStruct `ł̃IuWFNg̕ۑ\n\t * @param filename t@C\n\t * @param utf true Ȃ UTF-8 ŏo\n\t * @param newline sR[h 0:CRLF 1:LF\n\t * @return s\n\t */\n\tstatic tjs_error TJS_INTF_METHOD saveStruct2(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t\t\t tjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t\t\t tTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t\t\t iTJSDispatch2 *objthis) {\n\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n        tTJSBinaryStream *stream = TVPCreateStream(param[0]->AsString(), TJS_BS_WRITE);\n\t\ttTVPStringStream writer(stream,\n\t\t\t\t\t\t   //numparams > 1 ? (int)*param[1] != 0: false,\n\t\t\t\t\t\t   numparams > 2 ? (int)*param[2] : 0\n\t\t\t\t\t\t   );\n// \t\tIFileWriter writer(param[0]->GetString(),\n// \t\t\t\t\t\t   numparams > 1 ? (int)*param[1] != 0: false,\n// \t\t\t\t\t\t   numparams > 2 ? (int)*param[2] : 0\n// \t\t\t\t\t\t   );\n//                 writer.hex = true;\n\t\tgetArrayString(objthis, &writer);\n        delete stream;\n\t\treturn TJS_S_OK;\n\t}\n\t\n\t/**\n\t * saveStruct `ŕ\n\t * @param newline sR[h 0:CRLF 1:LF\n\t * @return s\n\t */\n\tstatic tjs_error TJS_INTF_METHOD toStructString(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t\t\t\tiTJSDispatch2 *objthis) {\n\t\tif (result) {\n            tTVPMemoryStream ms;\n            tTVPStringStream writer(&ms, numparams > 0 ? (int)*param[0] : 0);\n\t\t\tgetArrayString(objthis, &writer);\n            *result = (const tjs_char*)ms.GetInternalBuffer();\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n};\n\nNCB_ATTACH_CLASS(ArrayAdd, Array) {\n\tRawCallback(\"save2\", &ArrayAdd::save2, 0);\n\tRawCallback(\"saveStruct2\", &ArrayAdd::saveStruct2, 0);\n\tRawCallback(\"toStructString\", &ArrayAdd::toStructString, 0);\n};\n\n/**\n * \\bhǉp\n */\nclass DictAdd {\n\npublic:\n\tDictAdd(){};\n\n\t/**\n\t * saveStruct `ł̃IuWFNg̕ۑ\n\t * @param filename t@C\n\t * @param utf true Ȃ UTF-8 ŏo\n\t * @param newline sR[h 0:CRLF 1:LF\n\t * @return s\n\t */\n\tstatic tjs_error TJS_INTF_METHOD saveStruct2(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t\t\t tjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t\t\t tTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t\t\t iTJSDispatch2 *objthis) {\n\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n        tTJSBinaryStream *stream = TVPCreateStream(param[0]->AsString(), TJS_BS_WRITE);\n\t\ttTVPStringStream writer(stream,\n\t\t\t\t\t\t   //numparams > 1 ? (int)*param[1] != 0: false,\n\t\t\t\t\t\t   numparams > 2 ? (int)*param[2] : 0\n\t\t\t\t\t\t   );\n\t\tgetDictString(objthis, &writer);\n        delete stream;\n\t\treturn TJS_S_OK;\n\t}\n\t\n\t/**\n\t * saveStruct `ŕ\n\t * @param newline sR[h 0:CRLF 1:LF\n\t * @return s\n\t */\n\tstatic tjs_error TJS_INTF_METHOD toStructString(tTJSVariant *result,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttjs_int numparams,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant **param,\n\t\t\t\t\t\t\t\t\t\t\t\t\tiTJSDispatch2 *objthis) {\n\t\tif (result) {\n            tTVPMemoryStream ms;\n            tTVPStringStream writer(&ms, numparams > 0 ? (int)*param[0] : 0);\n\t\t\tgetDictString(objthis, &writer);\n            writer.write((tjs_char)0);\n\t\t\t*result = (const tjs_char*)ms.GetInternalBuffer();\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n};\n\nNCB_ATTACH_CLASS(DictAdd, Dictionary) {\n\tRawCallback(\"saveStruct2\", &DictAdd::saveStruct2, TJS_STATICMEMBER);\n\tRawCallback(\"toStructString\", &DictAdd::toStructString, TJS_STATICMEMBER);\n};\n\n/**\n * o^\n */\nstatic void PostRegistCallback()\n{\n\t// Array.count 擾\n\t{\n\t\ttTJSVariant varScripts;\n\t\tTVPExecuteExpression(TJS_W(\"Array\"), &varScripts);\n\t\tiTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef();\n\t\ttTJSVariant val;\n\t\tif (TJS_FAILED(dispatch->PropGet(TJS_IGNOREPROP,\n\t\t\t\t\t\t\t\t\t\t TJS_W(\"count\"),\n\t\t\t\t\t\t\t\t\t\t NULL,\n\t\t\t\t\t\t\t\t\t\t &val,\n\t\t\t\t\t\t\t\t\t\t dispatch))) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"can't get Array.count\"));\n\t\t}\n\t\tArrayCountProp = val.AsObject();\n\t}\n}\n\n/**\n * JO\n */\nstatic void PreUnregistCallback()\n{\n\tif (ArrayCountProp) {\n\t\tArrayCountProp->Release();\n\t\tArrayCountProp = NULL;\n\t}\n}\n\nNCB_POST_REGIST_CALLBACK(PostRegistCallback);\nNCB_PRE_UNREGIST_CALLBACK(PreUnregistCallback);\n"
  },
  {
    "path": "src/plugins/tp_stub.h",
    "content": "#pragma once\n//#define __TP_STUB_H__\n#include \"tjsCommHead.h\"\n#include \"tjsNative.h\"\n#include \"ScriptMgnIntf.h\"\n#include \"tjsArray.h\"\n#include \"tjsDictionary.h\"\n#include \"DebugIntf.h\"\n#include \"StorageImpl.h\"\n#include \"TextStream.h\"\n#include \"MsgIntf.h\"\n#include \"PluginImpl.h\"\n#include \"CharacterSet.h\"\n#include \"TransIntf.h\"\n"
  },
  {
    "path": "src/plugins/varfile.cpp",
    "content": "#include <stdio.h>\n#include <string.h>\n#include \"ncbind/ncbind.hpp\"\n#include <map>\n\n#define NCB_MODULE_NAME TJS_W(\"varfile.dll\")\n#define BASENAME TJS_W(\"var\")\n\n// 辞書かどうかの判定\nstatic bool isDirectory(tTJSVariant &base) {\n\treturn base.Type() == tvtObject && base.AsObjectNoAddRef() != NULL;\n}\n\n// ファイルかどうかの判定\nstatic bool isFile(const tTJSVariant &file) {\n\treturn file.Type() == tvtOctet;\n}\n\n/**\n * Variant参照型ストリーム\n */\nclass VariantStream : public tTJSBinaryStream {\n\npublic:\n\t/**\n\t * コンストラクタ\n\t */\n\tVariantStream(tTJSVariant &parent) : refCount(1), parent(parent), stream(0), cur(0) {};\n\n\t/**\n\t* デストラクタ\n\t*/\n\tvirtual ~VariantStream() {\n\t\tclose();\n\t}\n\n\t/**\n\t * ファイルを開く\n\t */\n\tbool open(const ttstr &name, tjs_uint32 flags) {\n\t\tclose();\n\t\tthis->name = name;\n\n\t\t// 読み込みのみの場合\n\t\tif (flags == TJS_BS_READ) {\n\t\t\tparent.AsObjectClosureNoAddRef().PropGet(0, name.c_str(), NULL, &value, NULL);\n\t\t\treturn isFile(value);\n\t\t}\n\n\t\t// 書き込みが必要な場合\n        stream = new tTVPMemoryStream();\n\n\t\t// オブジェクトの内容を複製\n\t\tif (flags == TJS_BS_UPDATE || flags == TJS_BS_APPEND) {\n\t\t\tparent.AsObjectClosureNoAddRef().PropGet(0, name.c_str(), NULL, &value, NULL);\n\t\t\tif (isFile(value)) {\n\t\t\t\tstream->Write(value.AsOctetNoAddRef()->GetData(), value.AsOctetNoAddRef()->GetLength());\n\t\t\t\tstream->Seek(0, flags == TJS_BS_UPDATE ? TJS_BS_SEEK_SET : TJS_BS_SEEK_END);\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\t\n\t// ISequentialStream\n    virtual tjs_uint TJS_INTF_METHOD Read(void *pv, tjs_uint cb) {\n\t\tif (stream) {\n\t\t\treturn stream->Read(pv, cb);\n\t\t} else {\n\t\t\tconst tjs_uint8 *base = getBase();\n\t\t\ttTVInteger size = getSize() - cur;\n\t\t\tif (base && cb > 0 && size > 0) {\n\t\t\t\tif (cb > size) {\n\t\t\t\t\tcb = size;\n\t\t\t\t}\n\t\t\t\tmemcpy(pv, base + cur, cb);\n\t\t\t\tcur += cb;\n\t\t\t\treturn cb;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\n    virtual tjs_uint TJS_INTF_METHOD Write(const void *pv, tjs_uint cb) {\n\t\tif (stream) {\n\t\t\treturn stream->Write(pv, cb);\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t// IStream\n    virtual tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 dlibMove, tjs_int dwOrigin) {\n\t\tif (stream) {\n\t\t\treturn stream->Seek(dlibMove, dwOrigin);\n\t\t} else {\n\t\t\tswitch (dwOrigin) {\n\t\t\tcase TJS_BS_SEEK_CUR:\n\t\t\t\tcur += dlibMove;\n\t\t\t\tbreak;\n\t\t\tcase TJS_BS_SEEK_SET:\n\t\t\t\tcur = dlibMove;\n\t\t\t\tbreak;\n\t\t\tcase TJS_BS_SEEK_END:\n\t\t\t\tcur = getSize();\n\t\t\t\tcur += dlibMove;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn cur;\n\t\t}\n\t}\n\n    virtual tjs_uint64 TJS_INTF_METHOD GetSize() {\n        if (stream) {\n            return stream->GetSize();\n        } else {\n            return getSize();\n        }\n    }\n\t\nprotected:\n\n\t/**\n\t * ファイルを閉じる処理\n\t */\n\tvoid close() {\n\t\tif (stream) {\n\t\t\tdelete stream;\n\t\t\tstream = NULL;\n\t\t}\n\t\tvalue.Clear();\n\t\tcur = 0;\n\t}\n\n\t// 読み込み用メモリ領域取得\n\tconst tjs_uint8 *getBase() {\n\t\treturn isFile(value) ? value.AsOctetNoAddRef()->GetData() : NULL;\n\t}\n\n\t// 読み込み用メモリサイズ取得\n    virtual tjs_uint64 TJS_INTF_METHOD getSize() {\n\t\treturn isFile(value) ? value.AsOctetNoAddRef()->GetLength() : 0;\n\t}\n\nprivate:\n\tint refCount;\n\ttTJSVariant parent;\n\tttstr name;\n\ttTJSVariant value;\n\ttTJSBinaryStream *stream;\n\ttTVInteger cur;\n};\n\n/**\n * メンバ登録処理用\n */\nclass GetLister : public tTJSDispatch /** EnumMembers 用 */\n{\n\npublic:\n\t// コンストラクタ\n\tGetLister(iTVPStorageLister *lister) : lister(lister) {};\n\n\t// EnumMember用繰り返し実行部\n\t// param[0] メンバ名\n\t// param[1] フラグ\n\t// param[2] メンバの値\n\tvirtual tjs_error TJS_INTF_METHOD FuncCall( // function invocation\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\t\t\t\t\t\t\t\t\t\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant *result,\t\t// result\n\t\t\t\t\t\t\t\t\t\t\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\t\t\t\t\t\t\t\t\t\t\ttTJSVariant **param,\t\t// parameters\n\t\t\t\t\t\t\t\t\t\t\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t\t\t\t\t\t\t\t\t\t\t) {\n\t\tif (numparams > 1) {\n\t\t\ttTVInteger flag = param[1]->AsInteger();\n\t\t\tif (!(flag & TJS_HIDDENMEMBER) && isFile(*param[2])) {\n\t\t\t\tlister->Add(ttstr(param[0]->GetString()));\n\t\t\t}\n\t\t}\n\t\tif (result) {\n\t\t\t*result = true;\n\t\t}\n\t\treturn TJS_S_OK;\n\t}\n\nprivate:\n\tiTVPStorageLister *lister;\n};\n\n\n/**\n * Varストレージ\n */\nclass VarStorage : public iTVPStorageMedia\n{\n\npublic:\n\t/**\n\t * コンストラクタ\n\t */\n\tVarStorage() : refCount(1) {\n\t}\n\n\t// -----------------------------------\n\t// iTVPStorageMedia Intefaces\n\t// -----------------------------------\n\n\tvirtual void TJS_INTF_METHOD AddRef() {\n\t\trefCount++;\n\t};\n\n\tvirtual void TJS_INTF_METHOD Release() {\n\t\tif (refCount == 1) {\n\t\t\tdelete this;\n\t\t} else {\n\t\t\trefCount--;\n\t\t}\n\t};\n\n\t// returns media name like \"file\", \"http\" etc.\n\tvirtual void TJS_INTF_METHOD GetName(ttstr &name) {\n\t\tname = BASENAME;\n\t}\n\n\t//\tvirtual ttstr IsCaseSensitive() = 0;\n\t// returns whether this media is case sensitive or not\n\n\t// normalize domain name according with the media's rule\n\tvirtual void TJS_INTF_METHOD NormalizeDomainName(ttstr &name) {\n\t\t// nothing to do\n\t}\n\n\t// normalize path name according with the media's rule\n\tvirtual void TJS_INTF_METHOD NormalizePathName(ttstr &name) {\n\t\t// nothing to do\n\t}\n\n\t// check file existence\n\tvirtual bool TJS_INTF_METHOD CheckExistentStorage(const ttstr &name) {\n\t\treturn isFile(getFile(name));\n\t}\n\n\t// open a storage and return a tTJSBinaryStream instance.\n\t// name does not contain in-archive storage name but\n\t// is normalized.\n\tvirtual tTJSBinaryStream * TJS_INTF_METHOD Open(const ttstr & name, tjs_uint32 flags) {\n\t\ttTJSBinaryStream *ret = NULL;\n\t\tttstr fname;\n\t\ttTJSVariant parent = getParentName(name, fname);\n\t\tif (isDirectory(parent) && fname.length() > 0) {\n\t\t\tVariantStream *stream = new VariantStream(parent);\n\t\t\tif (!stream->open(fname, flags)) {\n\t\t\t\tdelete stream;\n\t\t\t} else {\n\t\t\t\tret = stream;\n\t\t\t}\n\t\t}\n\t\tif (!ret) {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"cannot open memfile:%1\"), name);\n\t\t}\n\t\treturn ret;\n\t}\n\n\t// list files at given place\n\tvirtual void TJS_INTF_METHOD GetListAt(const ttstr &name, iTVPStorageLister * lister) {\n\t\ttTJSVariant base = getFile(name);\n\t\tif (isDirectory(base)) {\n\t\t\ttTJSVariantClosure closure(new GetLister(lister));\n\t\t\tbase.AsObjectClosureNoAddRef().EnumMembers(TJS_IGNOREPROP, &closure, NULL);\n\t\t\tclosure.Release();\n\t\t}\n\t}\n\n\t// basically the same as above,\n\t// check wether given name is easily accessible from local OS filesystem.\n\t// if true, returns local OS native name. otherwise returns an empty string.\n\tvirtual void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name) {\n\t\tname = \"\";\n\t}\n\nprotected:\n\n\t/**\n\t * デストラクタ\n\t */\n\tvirtual ~VarStorage() {\n\t}\n\t\n\t/*\n\t * 親フォルダとパスを返す\n\t * @param name ファイル名\n\t * @param fname ファイル名を返す\n\t * @return 親フォルダ\n\t */\n\ttTJSVariant getParentName(const ttstr &name, ttstr &fname) {\n\t\t// ドメイン部を分離\n\t\tconst tjs_char *p = name.c_str();\n\t\tconst tjs_char *q;\n\t\tif ((q = TJS_strchr(p, '/'))) {\n\t\t\tttstr dname = ttstr(p, q-p);\n\t\t\tif (dname != TJS_W(\".\")) {\n\t\t\t\tTVPThrowExceptionMessage(TJS_W(\"no such domain:%1\"), dname);\n\t\t\t}\n\t\t} else {\n\t\t\tTVPThrowExceptionMessage(TJS_W(\"invalid path:%1\"), name);\n\t\t}\n\t\t// パス名\n\t\tttstr path = ttstr(q+1);\n\t\tiTJSDispatch2 *global = TVPGetScriptDispatch();\n\t\ttTJSVariant base(global, global);\n\t\twhile (path.length() > 0) {\n\t\t\tp = path.c_str();\n\t\t\tq = TJS_strchr(p, '/');\n\t\t\tif (q == NULL) {\n\t\t\t\t// ファイル\n\t\t\t\tbreak;\n\t\t\t} else if (q == p) {\n\t\t\t\t// フォルダ名が空\n\t\t\t\tbase.Clear();\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t// フォルダ\n\t\t\t\tttstr member = ttstr(p, q-p);\n\t\t\t\ttTJSVariant value;\n\t\t\t\ttTJSVariantClosure &o = base.AsObjectClosureNoAddRef();\n\t\t\t\tif (((o.IsInstanceOf(0, NULL, NULL, TJS_W(\"Array\"), NULL) == TJS_S_TRUE &&\n\t\t\t\t\t  TJS_SUCCEEDED(o.PropGetByNum(0, (tjs_int)TJSStringToInteger(member.c_str()), &value, NULL))) ||\n\t\t\t\t\t (TJS_SUCCEEDED(o.PropGet(0, member.c_str(), NULL, &value, NULL)))) && isDirectory(value)) {\n\t\t\t\t\tbase = value;\n\t\t\t\t\tpath = ttstr(q+1);\n\t\t\t\t} else {\n\t\t\t\t\tbase.Clear();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfname = path;\n\t\treturn base;\n\t}\n\t\n\t/*\n\t * ファイル名に合致する変数を探して返す\n\t * @param name ファイル名\n\t * @return 発見したファイルまたはフォルダ。見つからない場合は tvtVoid\n\t */\n\ttTJSVariant getFile(const ttstr &name) {\n\t\tttstr fname;\n\t\ttTJSVariant base = getParentName(name, fname);\n\t\tif (isDirectory(base) && fname.length() > 0) {\n\t\t\t// ファイル\n\t\t\ttTJSVariant value;\n\t\t\tif (TJS_SUCCEEDED(base.AsObjectClosureNoAddRef().PropGet(0, fname.c_str(), NULL, &value, NULL))) {\n\t\t\t\tbase = value;\n\t\t\t} else {\n\t\t\t\tbase.Clear();\n\t\t\t}\n\t\t}\n\t\treturn base;\n\t}\n\nprivate:\n\ttjs_uint refCount; //< リファレンスカウント\n};\n\nVarStorage *var = NULL;\n\n/**\n * 開放処理後\n */\nstatic void PreRegistCallback()\n{\n\tif (var == NULL) {\n\t\tvar = new VarStorage();\n\t\tTVPRegisterStorageMedia(var);\n\t}\n}\n\n/**\n * 開放処理後\n */\nstatic void PostUnregistCallback()\n{\n\tif (var != NULL) {\n\t\tTVPUnregisterStorageMedia(var);\n\t\tvar->Release();\n\t\tvar = NULL;\n\t}\n}\n\nNCB_PRE_REGIST_CALLBACK(PreRegistCallback);\nNCB_POST_UNREGIST_CALLBACK(PostUnregistCallback);\n"
  },
  {
    "path": "src/plugins/win32dialog.cpp",
    "content": "\n#include \"ncbind/ncbind.hpp\"\n\n#define NCB_MODULE_NAME TJS_W(\"win32dialog.dll\")\n\nstatic void InitPlugin_WIN32Dialog()\n{\n\tTVPExecuteScript(\n\t\tTJS_W(\"class WIN32Dialog {\")\n\t\tTJS_W(\"\tfunction messageBox(message, caption, type) {return !System.inform(message, caption, 2);}\")\n\t\tTJS_W(\"}\")\n\t\t);\n}\n\nNCB_PRE_REGIST_CALLBACK(InitPlugin_WIN32Dialog);\n"
  },
  {
    "path": "src/plugins/wutcwf.cpp",
    "content": "//---------------------------------------------------------------------------\n#include \"ncbind/ncbind.hpp\"\n#include <stdio.h>\n#include \"WaveIntf.h\"\n//#include \"typedefine.h\"\n#define BYTE uint8_t\n#define LONG int32_t\n#define ULONG uint32_t\n\n#define NCB_MODULE_NAME TJS_W(\"wutcwf.dll\")\n\n#pragma pack(push,1)\nstruct TTCWFHeader\n{\n\tchar mark[6];  // = \"TCWF0\\x1a\"\n\tBYTE channels; // チャネル数\n\tBYTE reserved;\n\tLONG frequency; // サンプリング周波数\n\tLONG numblocks; // ブロック数\n\tLONG bytesperblock; // ブロックごとのバイト数\n\tLONG samplesperblock; // ブロックごとのサンプル数\n};\nstruct TTCWUnexpectedPeak\n{\n\tunsigned short int pos;\n\tshort int revise;\n};\nstruct TTCWBlockHeader  // ブロックヘッダ ( ステレオの場合はブロックが右・左の順に２つ続く)\n{\n\tshort int ms_sample0;\n\tshort int ms_sample1;\n\tshort int ms_idelta;\n\tunsigned char ms_bpred;\n\tunsigned char ima_stepindex;\n\tTTCWUnexpectedPeak peaks[6];\n};\n#pragma pack(pop)\n\nstatic const int AdaptationTable[]= \n{\n\t230, 230, 230, 230, 307, 409, 512, 614,\n\t768, 614, 512, 409, 307, 230, 230, 230 \n};\n\nstatic const int AdaptCoeff1 [] = \n{\t256, 512, 0, 192, 240, 460, 392 \n} ;\n\nstatic const int AdaptCoeff2 [] = \n{\t0, -256, 0, 64, 0, -208, -232\n} ;\n\nstatic const int ima_index_adjust [16] =\n{\t-1, -1, -1, -1,\t\t// +0 - +3, decrease the step size\n\t 2,  4,  6,  8,     // +4 - +7, increase the step size\n\t-1, -1, -1, -1,\t\t// -0 - -3, decrease the step size\n\t 2,  4,  6,  8,\t\t// -4 - -7, increase the step size\n} ;\n\nstatic const int ima_step_size [89] = \n{\t7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, \n\t50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, \n\t253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, \n\t1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, \n\t3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,\n\t11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, \n\t32767\n} ;\n\n//---------------------------------------------------------------------------\nclass TCWFDecoder : public tTVPWaveDecoder\n{\n    TTCWFHeader Header;\n    tTJSBinaryStream *InputStream;\n    tjs_int64 StreamPos;\n    short int *SamplePos;\n    long DataStart;\n    long DataSize;\n    tjs_int64 Pos;\n    long BufferRemain;\n    BYTE *BlockBuffer;\n    short int *Samples;\n    tTVPWaveFormat TSSFormat;\n\npublic:\n    TCWFDecoder();\n    ~TCWFDecoder();\n\npublic:\n    // ITSSWaveDecoder\n    virtual void GetFormat(tTVPWaveFormat & format);\n    virtual bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered);\n    virtual bool SetPosition(tjs_uint64 samplepos);\n\n    bool Open(const ttstr & url);\n    bool ReadBlock(int , int );\n};\n\nclass TCWFWaveDecoderCreator : public tTVPWaveDecoderCreator\n{\npublic:\n    tTVPWaveDecoder * Create(const ttstr & storagename, const ttstr & extension) {\n        TCWFDecoder * decoder = new TCWFDecoder();\n        if(!decoder->Open(storagename))\n        {\n            delete decoder;\n            return nullptr;\n        }\n        return decoder;\n    }\n};\n//---------------------------------------------------------------------------\n// TCWFDecoder インプリメンテーション #######################################\n//---------------------------------------------------------------------------\nTCWFDecoder::TCWFDecoder()\n{\n\tInputStream = NULL;\n\tBlockBuffer=NULL;\n\tSamples=NULL;\n}\n//---------------------------------------------------------------------------\nTCWFDecoder::~TCWFDecoder()\n{\n\tif(InputStream)\n\t{\n\t\tdelete InputStream;\n\t\tInputStream = NULL;\n\t}\n\tif(BlockBuffer) delete [] BlockBuffer;\n\tif(Samples) delete [] Samples;\n}\n//---------------------------------------------------------------------------\nvoid  TCWFDecoder::GetFormat(tTVPWaveFormat & format)\n{\n\tformat = TSSFormat;\n}\n//---------------------------------------------------------------------------\nbool  TCWFDecoder::Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered)\n{\n\t// 展開\n\tunsigned long n;\n\tshort int *pbuf=(short int*)buf;\n\tfor(n=0;n<bufsamplelen;n++)\n\t{\n\t\tif(BufferRemain<=0)\n\t\t{\n\t\t\tint i;\n\t\t\tfor(i=0; i<Header.channels; i++)\n\t\t\t{\n\t\t\t\tif(!ReadBlock(Header.channels, i))\n\t\t\t\t{\n\t\t\t\t\trendered = n;\n\t\t\t\t\tPos+=n;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tSamplePos = Samples;\n\t\t\tBufferRemain = Header.samplesperblock;\n\t\t}\n\t\tint i = Header.channels;\n\t\twhile(i--) *(pbuf++)=*(SamplePos++);\n\t\tBufferRemain--;\n\t}\n\n\trendered=n;\n\tPos+=n;\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool  TCWFDecoder::SetPosition(tjs_uint64 samplepos)\n{\n\t// pos (ms単位) に移動する\n\t// 現在位置を保存\n\ttjs_uint64 bytepossave=InputStream->GetPosition();\n\ttjs_uint64 samplepossave=Pos;\n\n\t// 新しい位置を特定\n\tlong newbytepos = samplepos / (Header.samplesperblock);\n\tlong remnant = samplepos - newbytepos * (Header.samplesperblock);\n\tPos = samplepos;\n\tnewbytepos *= Header.bytesperblock * Header.channels;\n\n\t// シーク\n    tjs_uint64 newpos = DataStart+newbytepos;\n    if(InputStream->Seek(DataStart+newbytepos, TJS_BS_SEEK_SET) != newpos)\n    {\n\t\t// シーク失敗\n\t\tnewpos=bytepossave;\n\t\tInputStream->SetPosition(newpos);\n\t\tPos=samplepossave;\n\t\treturn false;\n\t}\n\t\n\tStreamPos=DataStart+newbytepos;\n\n\tint i;\n\tfor(i=0; i<Header.channels; i++)\n\t{\n\t\tReadBlock(Header.channels, i);\n\t}\n\n\tSamplePos = Samples + remnant * Header.channels;\n\tBufferRemain = Header.samplesperblock - remnant;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool TCWFDecoder::Open(const ttstr & url)\n{\n\t// url で指定された URL を開きます\n\tInputStream = TVPCreateStream(url, TJS_BS_READ);\n\tif(!InputStream)\n\t{\n\t\treturn false;\n\t}\n\tInputStream->SetPosition(0);\n\t// TCWF0 チェック\n\ttjs_uint read = InputStream->Read(&Header, sizeof(Header));\n\tif(read!=sizeof(Header)) return false;\n\tif (memcmp(Header.mark, \"TCWF0\\x1a\", 6)) return false; // マーク\n\n\t// 現在位置を取得\n\tStreamPos=InputStream->GetPosition();\n\tDataStart=StreamPos;\n\n\t// その他、初期化\n\tBufferRemain=0;\n\tPos=0;\n\n\tmemset(&TSSFormat, 0, sizeof(TSSFormat));\n\tTSSFormat.SamplesPerSec = Header.frequency;\n\tTSSFormat.Channels = Header.channels;\n    TSSFormat.BitsPerSample = 16;\n    TSSFormat.BytesPerSample = 2;\n\tTSSFormat.Seekable = 2;\n\tTSSFormat.TotalSamples = 0;\n\tTSSFormat.TotalTime = 0;\n    TSSFormat.SpeakerConfig = 0;\n    TSSFormat.IsFloat = false;\n// \tTSSFormat.BigEndian = false;\n// \tTSSFormat.Signed = true;\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\nbool TCWFDecoder::ReadBlock(int numchans, int chan)\n{\n\n\t// メモリ確保\n\tif(!BlockBuffer)\n\t\tBlockBuffer=new BYTE[Header.bytesperblock];\n\tif(!this->Samples)\n\t\tthis->Samples=new short int[Header.samplesperblock * Header.channels];\n\n\tshort int * Samples = this->Samples + chan;\n\n\n\t// シーク\n\tif(InputStream->GetPosition()!=StreamPos)\n\t{\n\t\tif(InputStream->Seek(StreamPos, TJS_BS_SEEK_SET) != StreamPos) return false;\n\t}\n\n\n\t// ブロックヘッダ読み込み\n\tTTCWBlockHeader bheader;\n\tULONG read;\n\tread = InputStream->Read(&bheader,sizeof(bheader));\n\tStreamPos+=read;\n\tif(sizeof(bheader)!=read) return false;\n\tread = InputStream->Read(BlockBuffer, Header.bytesperblock - sizeof(bheader));\n\tStreamPos+=read;\n\tif((ULONG)Header.bytesperblock- sizeof(bheader)!=read) return false;\n\n\t// デコード\n\tSamples[0*numchans] = bheader.ms_sample0;\n\tSamples[1*numchans] = bheader.ms_sample1;\n\tint idelta = bheader.ms_idelta;\n\tint bpred = bheader.ms_bpred;\n\tif(bpred>=7) return false; // おそらく同期がとれていない\n\n\tint k;\n\tint p;\n\n\t//MS ADPCM デコード\n\tint predict;\n\tint bytecode;\n\tfor (k = 2, p = 0 ; k < Header.samplesperblock ; k ++, p++)\n\t{\n\t\tbytecode = BlockBuffer[p] & 0xF ;\n\n\t    int idelta_save=idelta;\n\t\tidelta = (AdaptationTable [bytecode] * idelta) >> 8 ;\n\t    if (idelta < 16) idelta = 16;\n\t    if (bytecode & 0x8) bytecode -= 0x10 ;\n\t\n    \tpredict = ((Samples [(k - 1)*numchans] * AdaptCoeff1 [bpred]) \n\t\t\t\t\t+ (Samples [(k - 2)*numchans] * AdaptCoeff2 [bpred])) >> 8 ;\n \n\t\tint current = (bytecode * idelta_save) + predict;\n    \n\t    if (current > 32767) \n\t\t\tcurrent = 32767 ;\n\t    else if (current < -32768) \n\t\t\tcurrent = -32768 ;\n    \n\t\tSamples [k*numchans] = (short int) current ;\n\t};\n\n\t//IMA ADPCM デコード\n\tint step;\n\tint stepindex = bheader.ima_stepindex;\n\tint prev = 0;\n\tint diff;\n\tfor (k = 2, p = 0 ; k < Header.samplesperblock ; k ++, p++)\n\t{\n\t\tbytecode= (BlockBuffer[p]>>4) & 0xF;\n\t\t\n\t\tstep = ima_step_size [stepindex] ;\n\t\tint current = prev;\n  \n\n\t\tdiff = step >> 3 ;\n\t\tif (bytecode & 1) \n\t\t\tdiff += step >> 2 ;\n\t\tif (bytecode & 2) \n\t\t\tdiff += step >> 1 ;\n\t\tif (bytecode & 4) \n\t\t\tdiff += step ;\n\t\tif (bytecode & 8) \n\t\t\tdiff = -diff ;\n\n\t\tcurrent += diff ;\n\n\t\tif (current > 32767) current = 32767;\n\t\telse if (current < -32768) current = -32768 ;\n\n\t\tstepindex+= ima_index_adjust [bytecode] ;\n\t\n\t\tif (stepindex< 0)  stepindex = 0 ;\n\t\telse if (stepindex > 88)\tstepindex = 88 ;\n\n\t\tprev = current ;\n\n\t\tint n = Samples[k*numchans];\n\t\tn+=current;\n\t\tif (n > 32767) n = 32767;\n\t\telse if (n < -32768) n = -32768 ;\n\t\tSamples[k*numchans] =n;\n\t};\n\n\t// unexpected peak の修正\n\tint i;\n\tfor(i=0; i<6; i++)\n\t{\n\t\tif(bheader.peaks[i].revise)\n\t\t{\n\t\t\tint pos = bheader.peaks[i].pos;\n\t\t\tint n = Samples[pos*numchans];\n\t\t\tn -= bheader.peaks[i].revise;\n\t\t\tif (n > 32767) n = 32767;\n\t\t\telse if (n < -32768) n = -32768 ;\n\t\t\tSamples[pos*numchans] = n;\n\t\t}\n\t}\n\n\treturn true;\n}\n//---------------------------------------------------------------------------\n\nstatic TCWFWaveDecoderCreator creator;\nstatic void _init()\n{\n    TVPRegisterWaveDecoderCreator(&creator);\n}\n\nNCB_PRE_REGIST_CALLBACK(_init);\n"
  },
  {
    "path": "src/plugins/xp3filter.cpp",
    "content": "#include \"ncbind/ncbind.hpp\"\n#include \"XP3Archive.h\"\n#include \"SystemIntf.h\"\n#include \"tjsNative.h\"\n#include <assert.h>\n#include <list>\n#include \"tjsDebug.h\"\n#include \"xp3filter.h\"\n#include \"SysInitIntf.h\"\n#include \"ThreadIntf.h\"\n#include <memory>\n#include <thread>\n\n#define NCB_MODULE_NAME TJS_W(\"xp3filter.dll\")\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::OperationByNum( /* operation with member by index number */ tjs_uint32 flag, /* calling flag */ tjs_int num, /* index number */ tTJSVariant *result, /* result ( can be NULL ) */ const tTJSVariant *param, /* parameters */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tnum += m_curPos;\n\tif (num < 0 || num >= m_length) return TJS_E_MEMBERNOTFOUND;\n\tunsigned char opnum = param->AsInteger();\n\tswitch (flag & TJS_OP_MASK) {\n\tcase TJS_OP_BAND: m_buff[num] &= opnum; break;\n\tcase TJS_OP_BOR:  m_buff[num] |= opnum; break;\n\tcase TJS_OP_BXOR: m_buff[num] ^= opnum; break;\n\tcase TJS_OP_SUB:  m_buff[num] -= opnum; break;\n\tcase TJS_OP_ADD:  m_buff[num] += opnum; break;\n\tcase TJS_OP_MOD:  m_buff[num] %= opnum; break;\n\tcase TJS_OP_DIV:  m_buff[num] /= (signed char)opnum; break;\n\tcase TJS_OP_IDIV: m_buff[num] /= opnum; break;\n\tcase TJS_OP_MUL:  m_buff[num] *= opnum; break;\n\tcase TJS_OP_LOR:  m_buff[num] = m_buff[num] || opnum; break;\n\tcase TJS_OP_LAND: m_buff[num] = m_buff[num] && opnum; break;\n\tcase TJS_OP_SAR:  m_buff[num] >>= opnum; break;\n\tcase TJS_OP_SAL:  m_buff[num] <<= opnum; break;\n\tcase TJS_OP_SR:   m_buff[num] >>= opnum; break;\n\tcase TJS_OP_INC:  m_buff[num] ++; break;\n\tcase TJS_OP_DEC:  m_buff[num] --; break;\n\tdefault:\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::Operation( /* operation with member */ tjs_uint32 flag, /* calling flag */ const tjs_char *membername, /* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ tTJSVariant *result, /* result ( can be NULL ) */ const tTJSVariant *param, /* parameters */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tif (membername) {\n\t\tstatic const ttstr str_ptr(TJS_W(\"ptr\"));\n\t\tif (hint) {\n\t\t\tstatic const tjs_uint32 hash_ptr = tTJSHashFunc<tjs_char *>::Make(str_ptr.c_str());\n\t\t\tif (!*hint)\n\t\t\t\t*hint = tTJSHashFunc<tjs_char *>::Make(membername);\n\t\t\tif (*hint != hash_ptr)\n\t\t\t\treturn TJS_E_NOTIMPL;\n\t\t} else if (str_ptr != membername) {\n\t\t\treturn TJS_E_NOTIMPL;\n\t\t}\n\t}\n\ttjs_uint32 op = flag & TJS_OP_MASK;\n\tswitch (op) {\n\tcase TJS_OP_ADD:\n\t\tm_curPos += param->AsInteger();\n\t\tbreak;\n\tcase TJS_OP_SUB:\n\t\tm_curPos -= param->AsInteger();\n\t\tbreak;\n\tcase TJS_OP_INC:\n\t\t++m_curPos;\n\t\tbreak;\n\tcase TJS_OP_DEC:\n\t\t--m_curPos;\n\t\tbreak;\n\tdefault:\n\t\treturn TJS_E_NOTIMPL;\n\t}\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::IsValid( /* get validation, returns TJS_S_TRUE (valid) or TJS_S_FALSE (invalid) */ tjs_uint32 flag, /* calling flag */ const tjs_char *membername, /* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\treturn m_buff ? TJS_S_TRUE : TJS_S_FALSE;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::Invalidate( /* invalidation */ tjs_uint32 flag, /* calling flag */ const tjs_char *membername, /* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tm_buff = NULL;\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::GetCount( /* get member count */ tjs_int *result, /* variable that receives the result */ const tjs_char *membername, /* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tif (membername) return TJS_E_MEMBERNOTFOUND;\n\t*result = m_length;\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::PropSetByNum( /* property set by index number */ tjs_uint32 flag, /* calling flag */ tjs_int num, /* index number */ const tTJSVariant *param, /* parameters */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tnum += m_curPos;\n\tif (num < 0 || num >= m_length) return TJS_E_MEMBERNOTFOUND;\n\tm_buff[num] = param->AsInteger();\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::PropSet( /* property set */ tjs_uint32 flag, /* calling flag */ const tjs_char *membername, /* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ const tTJSVariant *param, /* parameters */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tif (!membername) return TJS_E_NOTIMPL;\n\tif (!TJS_strcmp(membername, TJS_W(\"ptr\"))) {\n\t\tm_curPos = param->AsInteger();\n\t\treturn TJS_S_OK;\n\t}\n\treturn TJS_E_NOTIMPL;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::PropGetByNum( /* property get by index number */ tjs_uint32 flag, /* calling flag */ tjs_int num, /* index number */ tTJSVariant *result, /* result */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tnum += m_curPos;\n\tif (num < 0 || num >= m_length) return TJS_E_MEMBERNOTFOUND;\n\tresult->operator =((tjs_int32)m_buff[num]);\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::PropGet( /* property get */ tjs_uint32 flag, /* calling flag */ const tjs_char * membername,/* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ tTJSVariant *result, /* result */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tif (!membername) return TJS_E_NOTIMPL;\n\tif (!TJS_strcmp(membername, TJS_W(\"count\"))) {\n\t\tresult->operator =((tjs_int64)m_length);\n\t} else if (!TJS_strcmp(membername, TJS_W(\"ptr\"))) {\n\t\tresult->operator =((tjs_int64)m_curPos);\n\t} else {\n\t\tresult->Clear();\n\t}\n\treturn TJS_S_OK;\n}\n\ntjs_error TJS_INTF_METHOD CBinaryAccessor::FuncCall( /* function invocation */ tjs_uint32 flag, /* calling flag */ const tjs_char * membername,/* member name ( NULL for a default member ) */ tjs_uint32 *hint, /* hint for the member name (in/out) */ tTJSVariant *result, /* result */ tjs_int numparams, /* number of parameters */ tTJSVariant **param, /* parameters */ iTJSDispatch2 *objthis /* object as \"this\" */)\n{\n\tif (hint) {\n\t\tif (!*hint) {\n\t\t\t*hint = !TJS_strcmp(membername, TJS_W(\"xor\"));\n\t\t\tif (*hint) {\n\t\t\t\treturn FuncXor(numparams, param);\n\t\t\t}\n\t\t} else {\n\t\t\treturn FuncXor(numparams, param);\n\t\t}\n\t} else if (!TJS_strcmp(membername, TJS_W(\"xor\"))) {\n\t\treturn FuncXor(numparams, param);\n\t}\n\treturn TJS_E_NOTIMPL;\n}\n\nCBinaryAccessor::CBinaryAccessor(unsigned char* buff, unsigned int len)\n{\n\tm_buff = buff;\n\tm_length = len;\n\tm_curPos = 0;\n}\n\ntjs_error CBinaryAccessor::FuncAdd(tjs_int numparams, tTJSVariant **param)\n{\n\tif (numparams < 3) {\n\t\treturn TJS_E_BADPARAMCOUNT;\n\t}\n\n\tint bufoff = param[0]->AsInteger();\n\tint len = param[1]->AsInteger();\n\tunsigned char xorval = param[2]->AsInteger();\n\n\tunsigned char *buf = m_buff + m_curPos + bufoff;\n\tunsigned int i;\n\tfor (i = 0; i < len; ++i)\n\t\tbuf[i] += xorval;\n\treturn TJS_S_OK;\n}\n\ntjs_error CBinaryAccessor::FuncXor(tjs_int numparams, tTJSVariant **param)\n{\n\tif (numparams < 3) {\n\t\treturn TJS_E_BADPARAMCOUNT;\n\t}\n\n\tint bufoff = param[0]->AsInteger();\n\tint len = param[1]->AsInteger();\n\tunsigned char xorval = param[2]->AsInteger();\n\n\tunsigned char *buf = m_buff + m_curPos + bufoff;\n\tunsigned char *pend = buf + len;\n\tif (len>32)\n\t{\n\t\tint PreFragLen = (unsigned char*)((((intptr_t)buf) + 7)&~7) - buf;\n\t\tfor (int i = 0; i < PreFragLen; i++) *(buf++) ^= xorval;\n\n\t\tuint64_t k = /*0x101010101010101 * */xorval;\n\t\tk |= k << 8;\n\t\tk |= k << 16;\n\t\tk |= k << 32;\n\t\tunsigned char* pVecEnd = (unsigned char*)(((intptr_t)pend)&~7) - 7;\n\t\twhile (buf < pVecEnd) {\n\t\t\t*(uint64_t*)(buf) ^= k;\n\t\t\tbuf += 8;\n\t\t}\n\t}\n\twhile (buf < pend) *(buf++) ^= xorval;\n\n\treturn TJS_S_OK;\n}\n\nstatic bool _ManagedDecoderInited = false;\nstatic bool _ManagedFilterInited = false;\n\nstruct XP3FilterDecoder {\n\ttTJS * ScriptEngine = new tTJS();\n\ttTJSVariantClosure ManagedDecoder;\n\ttTJSVariantClosure ManagedFilter;\n\tXP3FilterDecoder() : ManagedDecoder(nullptr), ManagedFilter(nullptr) { }\n\t~XP3FilterDecoder() {\n\t\tif (ScriptEngine) ScriptEngine->Release();\n\t}\n};\n\n// static std::vector<XP3FilterDecoder*> sTVPScriptEngineStack;\n// static std::mutex sTVPScriptEngineStackLock;\nstatic ttstr sXP3FilterScript;\n\nclass XP3FilterRegister : public tTJSDispatch\n{\n    typedef tTJSDispatch inherited;\nprotected:\n    XP3FilterDecoder *Decoder;\npublic:\n\n    XP3FilterRegister(XP3FilterDecoder *decoder) {\n        Decoder = decoder;\n        if(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this);\n    }\n    ~XP3FilterRegister() {\n        if(TJSObjectHashMapEnabled()) TJSRemoveObjectHashRecord(this);\n    }\n\n    tjs_error TJS_INTF_METHOD\n        IsInstanceOf(tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint,\n        const tjs_char *classname,\n        iTJSDispatch2 *objthis)\n    {\n        if(membername == NULL)\n        {\n            if(!TJS_strcmp(classname, TJS_W(\"Function\"))) return TJS_S_TRUE;\n        }\n\n        return inherited::IsInstanceOf(flag, membername, hint, classname, objthis);\n    }\n    tjs_error  TJS_INTF_METHOD\n        FuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n        tTJSVariant *result,\n        tjs_int numparams, tTJSVariant **param,\tiTJSDispatch2 *objthis)\n    {\n        if(membername) return inherited::FuncCall(flag, membername, hint,\n            result, numparams, param, objthis);\n        if(!objthis) return TJS_E_NATIVECLASSCRASH;\n\n        if(result) result->Clear();\n\n        if (numparams < 1) return TJS_E_BADPARAMCOUNT;\n        if (Decoder->ManagedDecoder.Object) Decoder->ManagedDecoder.Release();\n        Decoder->ManagedDecoder = param[0]->AsObjectClosure();\n\t\t_ManagedDecoderInited = true;\n        return TJS_S_OK;\n    }\n};\n\nclass XP3ContentFilterRegister : public XP3FilterRegister {\n\ttypedef XP3FilterRegister inherited;\npublic:\n\tXP3ContentFilterRegister(XP3FilterDecoder *decoder) : XP3FilterRegister(decoder) {}\n\ttjs_error  TJS_INTF_METHOD\n\t\tFuncCall(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint,\n\t\ttTJSVariant *result,\n\t\ttjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis)\n\t{\n\t\tif (membername) return inherited::FuncCall(flag, membername, hint,\n\t\t\tresult, numparams, param, objthis);\n\t\tif (!objthis) return TJS_E_NATIVECLASSCRASH;\n\n\t\tif (result) result->Clear();\n\n\t\tif (numparams < 1) return TJS_E_BADPARAMCOUNT;\n\t\tif (Decoder->ManagedFilter.Object) Decoder->ManagedFilter.Release();\n\t\tDecoder->ManagedFilter = param[0]->AsObjectClosure();\n\t\t_ManagedFilterInited = true;\n\t\treturn TJS_S_OK;\n\t}\n};\n\nstatic XP3FilterDecoder* AddXP3Decoder() {\n    XP3FilterDecoder *decoder = new XP3FilterDecoder;\n    tTJSVariant val;\n    iTJSDispatch2 *dsp;\n\tiTJSDispatch2 *global = decoder->ScriptEngine->GetGlobalNoAddRef();\n#define REGISTER_OBJECT(classname, instance) \\\n    dsp = (instance); \\\n    val = tTJSVariant(dsp/*, dsp*/); \\\n    dsp->Release(); \\\n    global->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, TJS_W(#classname), NULL, \\\n    &val, global);\n    REGISTER_OBJECT(Debug, TVPCreateNativeClass_Debug());\n    REGISTER_OBJECT(System, TVPCreateNativeClass_System());\n    tTJSNativeClass *cls = TVPCreateNativeClass_Storages();\n    TJSNativeClassRegisterNCM(cls, TJS_W(\"setXP3ArchiveExtractionFilter\"),\n        new XP3FilterRegister(decoder),\n\t\tcls->GetClassName().c_str(), nitMethod, TJS_STATICMEMBER);\n\tTJSNativeClassRegisterNCM(cls, TJS_W(\"setXP3ArchiveContentFilter\"),\n\t\tnew XP3ContentFilterRegister(decoder),\n\t\tcls->GetClassName().c_str(), nitMethod, TJS_STATICMEMBER);\n    REGISTER_OBJECT(Storages, cls);\n\n\tdecoder->ScriptEngine->ExecScript(sXP3FilterScript);\n//\tsTVPScriptEngineStack.emplace_back(decoder);\n\treturn decoder;\n}\n\nstatic std::map<std::thread::id, XP3FilterDecoder*> _thread_decoders;\n#if 1 || (defined(_MSC_VER) /*&& _MSC_VER <= 1800*/) || defined(CC_TARGET_OS_IPHONE)\nstatic std::mutex _decoders_mtx;\nstatic std::vector<XP3FilterDecoder*> _cached_decoders;\nstatic XP3FilterDecoder *FetchXP3Decoder() {\n\tstd::lock_guard<std::mutex> lk(_decoders_mtx);\n\tauto it = _thread_decoders.find(std::this_thread::get_id());\n\tif (it != _thread_decoders.end()) {\n\t\tXP3FilterDecoder *ret = it->second;\n\t\treturn ret;\n\t}\n\tstatic bool Inited = false;\n\tif (!Inited) {\n\t\tInited = true;\n\t\tTVPAddOnThreadExitEvent([](){\n\t\t\tstd::lock_guard<std::mutex> lk(_decoders_mtx);\n\t\t\tauto it = _thread_decoders.find(std::this_thread::get_id());\n\t\t\tif (it != _thread_decoders.end()) {\n\t\t\t\t_cached_decoders.emplace_back(it->second);\n\t\t\t\t_thread_decoders.erase(it);\n\t\t\t}\n\t\t});\n\t}\n\tXP3FilterDecoder *ret;\n\tif(!_cached_decoders.empty()) {\n\t\tret = _cached_decoders.back();\n\t\t_cached_decoders.pop_back();\n\t} else {\n\t\tret = AddXP3Decoder();\n\t}\n\t_thread_decoders[std::this_thread::get_id()] = ret;\n\treturn ret;\n}\n#else\nstatic XP3FilterDecoder *FetchXP3Decoder() {\n\tthread_local std::auto_ptr<XP3FilterDecoder> ret;\n\tif(!ret) ret = AddXP3Decoder();\n\treturn ret.get();\n}\n#endif\ntjs_int TVPXP3ArchiveContentFilterWrapper(const ttstr &filepath, const ttstr &archivename, tjs_uint64 filesize, tTJSVariant *ctx) {\n\tif (!_ManagedFilterInited) return 0;\n\n\tXP3FilterDecoder* decoder = FetchXP3Decoder();\n\tif (!decoder->ManagedFilter.Object) return 0;\n\ttTJSVariant FilePath(filepath);\n\ttTJSVariant ArcName(archivename);\n\ttTJSVariant FileSize((tjs_int64)filesize);\n\ttTJSVariant *vars[] = {\n\t\t&FilePath, &ArcName, &FileSize\n\t};\n\ttTJSVariant result;\n\tdecoder->ManagedFilter.FuncCall(0, NULL, NULL, &result, sizeof(vars) / sizeof(vars[0]), vars, NULL);\n\ttjs_int ret = 0;\n\tif (result.Type() == tvtObject) {\n\t\tiTJSDispatch2* arr = result.AsObjectNoAddRef();\n\t\tncbPropAccessor a(arr);\n\t\tret = a.GetValue(0, ncbTypedefs::Tag<tjs_int>());\n\t\t*ctx = a.GetValue(1, ncbTypedefs::Tag<tTJSVariant>());\n\t}\n\treturn ret;\n}\n\nvoid TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION\n    TVPXP3ArchiveExtractionFilterWrapper(tTVPXP3ExtractionFilterInfo *info, tTJSVariant *ctx)\n{\n    if (info->SizeOfSelf != sizeof(tTVPXP3ExtractionFilterInfo))\n        TVPThrowExceptionMessage(TJS_W(\"Incompatible tTVPXP3ExtractionFilterInfo size\"));\n\tXP3FilterDecoder* decoder = FetchXP3Decoder();\n    if (decoder->ManagedDecoder.Object) {\n        tTJSVariant FileHash = (tjs_int64)info->FileHash;\n        tTJSVariant Offset = (tjs_int64)info->Offset;\n\t\tCBinaryAccessor *buf = new CBinaryAccessor((unsigned char*)info->Buffer, info->BufferSize);\n        tTJSVariant Buffer(buf);\n\t\tbuf->Release();\n\t\ttTJSVariant BufferSize((tjs_int64)info->BufferSize);\n\t\ttTJSVariant FileName(info->FileName);\n        tTJSVariant *vars[] = {\n            &FileHash, &Offset, &Buffer, &BufferSize, &FileName, ctx\n        };\n#if defined(WIN32) && defined(CHECK_CXDEC)\n        unsigned char *pBackup = new unsigned char[info->BufferSize], *pBuffer = (unsigned char*)info->Buffer;\n        memcpy(pBackup, info->Buffer, info->BufferSize);\n#endif\n\t\tdecoder->ManagedDecoder.FuncCall(0, NULL, NULL, NULL, sizeof(vars) / sizeof(vars[0]), vars, NULL);\n#if defined(WIN32) && defined(CHECK_CXDEC)\n\t\tcxdec_decode(&dec_callback, info->FileHash, info->Offset, pBackup, info->BufferSize);\n        for (int i = 0; i < info->BufferSize; ++i)\n        {\n            if (pBackup[i] != pBuffer[i]) {\n                assert(false);\n\t\t\t\tbreak;\n            }\n        }\n        delete []pBackup;\n#endif\n    }\n}\n\nvoid TVPSetXP3FilterScript(ttstr content) {\n\tif (sXP3FilterScript != content) {\n\t\tfor (auto it : _thread_decoders) {\n\t\t\tdelete it.second;\n\t\t}\n\t\t_thread_decoders.clear();\n\t}\n\tif (content.IsEmpty()) {\n\t\tTVPSetXP3ArchiveExtractionFilter(nullptr);\n\t\tTVPSetXP3ArchiveContentFilter(nullptr);\n\t} else {\n\t\tTVPSetXP3ArchiveExtractionFilter(TVPXP3ArchiveExtractionFilterWrapper);\n\t\tTVPSetXP3ArchiveContentFilter(TVPXP3ArchiveContentFilterWrapper);\n\t}\n\tsXP3FilterScript = content;\n}\n\nstatic void PostRegistCallback()\n{\n    ttstr path = TVPGetAppPath() + TJS_W(\"xp3filter.tjs\");\n    if (TVPIsExistentStorageNoSearch(path)) {\n        iTJSTextReadStream * stream = TVPCreateTextStreamForRead(path, \"\");\n        try\n        {\n            stream->Read(sXP3FilterScript, 0);\n        }\n        catch(...)\n        {\n            stream->Destruct();\n            throw;\n        }\n        stream->Destruct();\n    //    AddXP3Decoder();\n\t\tTVPSetXP3ArchiveExtractionFilter(TVPXP3ArchiveExtractionFilterWrapper);\n\t\tTVPSetXP3ArchiveContentFilter(TVPXP3ArchiveContentFilterWrapper);\n    }\n    //TVPSetXP3ArchiveExtractionFilter(TVPXP3ArchiveExtractionFilter);\n}\n\nNCB_POST_REGIST_CALLBACK(PostRegistCallback);\n"
  },
  {
    "path": "src/plugins/xp3filter.h",
    "content": "#pragma once\n#include \"tjsObject.h\"\n\nclass CBinaryAccessor : public tTJSDispatch\n{\n\tunsigned int m_length;\n\tunsigned int m_curPos;\n\tunsigned char *m_buff;\n\n\ttjs_error FuncXor(tjs_int numparams, tTJSVariant **param);\n\n\ttjs_error FuncAdd(tjs_int numparams, tTJSVariant **param);\n\npublic:\n\tCBinaryAccessor(unsigned char* buff, unsigned int len);\npublic:\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tFuncCall( // function invocation\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result\n\t\ttjs_int numparams,\t\t\t// number of parameters\n\t\ttTJSVariant **param,\t\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tPropGet( // property get\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char * membername,// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tPropGetByNum( // property get by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\ttTJSVariant *result,\t\t// result\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tPropSet( // property set\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tPropSetByNum( // property set by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tGetCount( // get member count\n\t\ttjs_int *result,         \t// variable that receives the result\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis      // object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tInvalidate( // invalidation\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tIsValid( // get validation, returns TJS_S_TRUE (valid) or TJS_S_FALSE (invalid)\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tOperation( // operation with member\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\tconst tjs_char *membername,\t// member name ( NULL for a default member )\n\t\ttjs_uint32 *hint,\t\t\t// hint for the member name (in/out)\n\t\ttTJSVariant *result,\t\t// result ( can be NULL )\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n\n\tvirtual tjs_error TJS_INTF_METHOD\n\t\tOperationByNum( // operation with member by index number\n\t\ttjs_uint32 flag,\t\t\t// calling flag\n\t\ttjs_int num,\t\t\t\t// index number\n\t\ttTJSVariant *result,\t\t// result ( can be NULL )\n\t\tconst tTJSVariant *param,\t// parameters\n\t\tiTJSDispatch2 *objthis\t\t// object as \"this\"\n\t\t);\n};\n"
  },
  {
    "path": "thirdparty/patch/cocos2d-x/android_CCFileUtils-android.cpp",
    "content": "/****************************************************************************\nCopyright (c) 2010-2012 cocos2d-x.org\nCopyright (c) 2013-2016 Chukong Technologies Inc.\nCopyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.\n\nhttp://www.cocos2d-x.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n****************************************************************************/\n\n#include \"platform/CCPlatformConfig.h\"\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\n#include \"platform/android/CCFileUtils-android.h\"\n#include \"platform/CCCommon.h\"\n#include \"platform/android/jni/JniHelper.h\"\n#include \"platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h\"\n#include \"android/asset_manager.h\"\n#include \"android/asset_manager_jni.h\"\n#include \"base/ZipUtils.h\"\n\n#include <stdlib.h>\n#include <sys/stat.h>\n\n#define  LOG_TAG    \"CCFileUtils-android.cpp\"\n#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)\n\n#define  ASSETS_FOLDER_NAME          \"assets/\"\n#define  ASSETS_FOLDER_NAME_LENGTH   7\n\nusing namespace std;\n\n#define DECLARE_GUARD std::lock_guard<std::recursive_mutex> mutexGuard(_mutex)\n\nNS_CC_BEGIN\n\nAAssetManager* FileUtilsAndroid::assetmanager = nullptr;\nZipFile* FileUtilsAndroid::obbfile = nullptr;\n\nvoid FileUtilsAndroid::setassetmanager(AAssetManager* a) {\n    if (nullptr == a) {\n        LOGD(\"setassetmanager : received unexpected nullptr parameter\");\n        return;\n    }\n\n    cocos2d::FileUtilsAndroid::assetmanager = a;\n}\n\nFileUtils* FileUtils::getInstance()\n{\n    if (s_sharedFileUtils == nullptr)\n    {\n        s_sharedFileUtils = new FileUtilsAndroid();\n        if (!s_sharedFileUtils->init())\n        {\n          delete s_sharedFileUtils;\n          s_sharedFileUtils = nullptr;\n          CCLOG(\"ERROR: Could not init CCFileUtilsAndroid\");\n        }\n    }\n    return s_sharedFileUtils;\n}\n\nFileUtilsAndroid::FileUtilsAndroid()\n{\n}\n\nFileUtilsAndroid::~FileUtilsAndroid()\n{\n    if (obbfile)\n    {\n        delete obbfile;\n        obbfile = nullptr;\n    }\n}\n\nbool FileUtilsAndroid::init()\n{\n    DECLARE_GUARD;\n\n    _defaultResRootPath = ASSETS_FOLDER_NAME;\n    \n    std::string assetsPath(getApkPath());\n    if (assetsPath.find(\"/obb/\") != std::string::npos)\n    {\n        obbfile = new ZipFile(assetsPath);\n    }\n\n    return FileUtils::init();\n}\n\nstd::string FileUtilsAndroid::getNewFilename(const std::string &filename) const\n{\n    std::string newFileName = FileUtils::getNewFilename(filename);\n    // ../xxx do not fix this path\n    auto pos = newFileName.find(\"../\");\n    if (pos == std::string::npos || pos == 0)\n    {\n        return newFileName;\n    }\n\n    std::vector<std::string> v(3);\n    v.resize(0);\n    auto change = false;\n    size_t size = newFileName.size();\n    size_t idx = 0;\n    bool noexit = true;\n    while (noexit)\n    {\n        pos = newFileName.find('/', idx);\n        std::string tmp;\n        if (pos == std::string::npos)\n        {\n            tmp = newFileName.substr(idx, size - idx);\n            noexit = false;\n        }else\n        {\n            tmp = newFileName.substr(idx, pos - idx + 1);\n        }\n        auto t = v.size();\n        if (t > 0 && v[t-1].compare(\"../\") != 0 &&\n             (tmp.compare(\"../\") == 0 || tmp.compare(\"..\") == 0))\n        {\n            v.pop_back();\n            change = true;\n        }else\n        {\n            v.push_back(tmp);\n        }\n        idx = pos + 1;\n    }\n\n    if (change)\n    {\n        newFileName.clear();\n        for (auto &s : v)\n        {\n            newFileName.append(s);\n        }\n    }\n    return newFileName;\n}\n\nbool FileUtilsAndroid::isFileExistInternal(const std::string& strFilePath) const\n{\n    \n    DECLARE_GUARD;\n\n    if (strFilePath.empty())\n    {\n        return false;\n    }\n\n    bool bFound = false;\n\n    // Check whether file exists in apk.\n    if (strFilePath[0] != '/')\n    {\n        const char* s = strFilePath.c_str();\n\n        // Found \"assets/\" at the beginning of the path and we don't want it\n        if (strFilePath.find(_defaultResRootPath) == 0) s += _defaultResRootPath.length();\n        \n        if (obbfile && obbfile->fileExists(s))\n        {\n            bFound = true;\n        }\n        else if (FileUtilsAndroid::assetmanager)\n        {\n            AAsset* aa = AAssetManager_open(FileUtilsAndroid::assetmanager, s, AASSET_MODE_UNKNOWN);\n            if (aa)\n            {\n                bFound = true;\n                AAsset_close(aa);\n            } else {\n                // CCLOG(\"[AssetManager] ... in APK %s, found = false!\", strFilePath.c_str());\n            }\n        }\n    }\n    else\n    {\n        FILE *fp = fopen(strFilePath.c_str(), \"r\");\n        if (fp)\n        {\n            bFound = true;\n            fclose(fp);\n        }\n    }\n    return bFound;\n}\n\nbool FileUtilsAndroid::isDirectoryExistInternal(const std::string& dirPath) const\n{\n    if (dirPath.empty())\n    {\n        return false;\n    }\n\n    std::string dirPathCopy = dirPath;\n    if(dirPathCopy[dirPathCopy.length() - 1] == '/')\n    {\n        dirPathCopy.erase(dirPathCopy.length() - 1);\n    }\n\n    const char* s = dirPathCopy.c_str();\n    \n    // find absolute path in flash memory\n    if (s[0] == '/')\n    {\n        //CCLOG(\"find in flash memory dirPath(%s)\", s);\n        struct stat st;\n        if (stat(s, &st) == 0)\n        {\n            return S_ISDIR(st.st_mode);\n        }\n    }\n    else\n    {\n\n\n        // find it in apk's assets dir\n        // Found \"assets/\" at the beginning of the path and we don't want it\n        //CCLOG(\"find in apk dirPath(%s)\", s);\n        if (dirPath.find(ASSETS_FOLDER_NAME) == 0)\n        {\n            s += ASSETS_FOLDER_NAME_LENGTH;\n        }\n\n        if (FileUtilsAndroid::assetmanager)\n        {\n            AAssetDir* aa = AAssetManager_openDir(FileUtilsAndroid::assetmanager, s);\n            if (aa && AAssetDir_getNextFileName(aa))\n            {\n                AAssetDir_close(aa);\n                return true;\n            }\n        }\n    }\n    \n    return false;\n}\n\nbool FileUtilsAndroid::isAbsolutePath(const std::string& strPath) const\n{\n    DECLARE_GUARD;\n    // On Android, there are two situations for full path.\n    // 1) Files in APK, e.g. assets/path/path/file.png\n    // 2) Files not in APK, e.g. /data/data/org.cocos2dx.hellocpp/cache/path/path/file.png, or /sdcard/path/path/file.png.\n    // So these two situations need to be checked on Android.\n    if (strPath[0] == '/' || strPath.find(_defaultResRootPath) == 0)\n    {\n        return true;\n    }\n    return false;\n}\n\nlong FileUtilsAndroid::getFileSize(const std::string& filepath) const\n{\n    DECLARE_GUARD;\n    long size = FileUtils::getFileSize(filepath);\n    if (size != -1) {\n        return size;\n    }\n    \n    if (FileUtilsAndroid::assetmanager)\n    {\n        string relativePath = filepath;\n        if (filepath.find(_defaultResRootPath) == 0)\n        {\n            relativePath = filepath.substr(_defaultResRootPath.size());\n        }\n        \n        AAsset* asset = AAssetManager_open(FileUtilsAndroid::assetmanager, relativePath.data(), AASSET_MODE_UNKNOWN);\n        if (asset)\n        {\n            size = AAsset_getLength(asset);\n            AAsset_close(asset);\n        }\n    }\n    \n    return size;\n}\n\nstd::vector<std::string> FileUtilsAndroid::listFiles(const std::string& dirPath) const\n{\n\n    if(!dirPath.empty() && dirPath[0] == '/') return FileUtils::listFiles(dirPath);\n\n    std::vector<std::string> fileList;\n    string fullPath = fullPathForDirectory(dirPath);\n\n    static const std::string apkprefix(\"assets/\");\n    string relativePath = \"\";\n    size_t position = fullPath.find(apkprefix);\n    if (0 == position) {\n        // \"assets/\" is at the beginning of the path and we don't want it\n        relativePath += fullPath.substr(apkprefix.size());\n    } else {\n        relativePath = fullPath;\n    }\n\n    if(obbfile) return obbfile->listFiles(relativePath);\n\n    if (nullptr == assetmanager) {\n        LOGD(\"... FileUtilsAndroid::assetmanager is nullptr\");\n        return fileList;\n    }\n\n    if(relativePath[relativePath.length() - 1] == '/')\n    {\n        relativePath.erase(relativePath.length() - 1);\n    }\n\n    auto *dir = AAssetManager_openDir(assetmanager, relativePath.c_str());\n    if(nullptr == dir) {\n        LOGD(\"... FileUtilsAndroid::failed to open dir %s\", relativePath.c_str());\n        AAssetDir_close(dir);\n        return fileList;\n    }\n    const char *tmpDir = nullptr;\n    while((tmpDir = AAssetDir_getNextFileName(dir))!= nullptr)\n    {\n        string filepath(tmpDir);\n        if(isDirectoryExistInternal(filepath)) filepath += \"/\";\n        fileList.push_back(filepath);\n    }\n    AAssetDir_close(dir);\n    return fileList;\n}\n\nbool FileUtilsAndroid::removeDirectory(const std::string& path) const\n{\n    if (path.empty())\n        return false;\n    \n    return removeDirectoryJNI(path.c_str());\n}\n\nFileUtils::Status FileUtilsAndroid::getContents(const std::string& filename, ResizableBuffer* buffer) const\n{\n    static const std::string apkprefix(\"assets/\");\n    if (filename.empty())\n        return FileUtils::Status::NotExists;\n\n    string fullPath = fullPathForFilename(filename);\n\n    if (fullPath[0] == '/')\n        return FileUtils::getContents(fullPath, buffer);\n\n    string relativePath = string();\n    size_t position = fullPath.find(apkprefix);\n    if (0 == position) {\n        // \"assets/\" is at the beginning of the path and we don't want it\n        relativePath += fullPath.substr(apkprefix.size());\n    } else {\n        relativePath = fullPath;\n    }\n    \n    if (obbfile)\n    {\n        if (obbfile->getFileData(relativePath, buffer))\n            return FileUtils::Status::OK;\n    }\n\n    if (nullptr == assetmanager) {\n        LOGD(\"... FileUtilsAndroid::assetmanager is nullptr\");\n        return FileUtils::Status::NotInitialized;\n    }\n\n    AAsset* asset = AAssetManager_open(assetmanager, relativePath.data(), AASSET_MODE_UNKNOWN);\n    if (nullptr == asset) {\n        LOGD(\"asset is nullptr\");\n        return FileUtils::Status::OpenFailed;\n    }\n\n    auto size = AAsset_getLength(asset);\n    buffer->resize(size);\n\n    int readsize = AAsset_read(asset, buffer->buffer(), size);\n    AAsset_close(asset);\n\n    if (readsize < size) {\n        if (readsize >= 0)\n            buffer->resize(readsize);\n        return FileUtils::Status::ReadFailed;\n    }\n\n    return FileUtils::Status::OK;\n}\n\nstring FileUtilsAndroid::getWritablePath() const\n{\n    // Fix for Nexus 10 (Android 4.2 multi-user environment)\n    // the path is retrieved through Java Context.getCacheDir() method\n    string dir(\"\");\n    string tmp = JniHelper::callStaticStringMethod(\"org.cocos2dx.lib.Cocos2dxHelper\", \"getCocos2dxWritablePath\");\n\n    if (tmp.length() > 0)\n    {\n        dir.append(tmp).append(\"/\");\n\n        return dir;\n    }\n    else\n    {\n        return \"\";\n    }\n}\n\nNS_CC_END\n\n#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID"
  },
  {
    "path": "thirdparty/patch/cocos2d-x/android_CCFileUtils-android.h",
    "content": "/****************************************************************************\nCopyright (c) 2010-2012 cocos2d-x.org\nCopyright (c) 2013-2016 Chukong Technologies Inc.\nCopyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.\n\n http://www.cocos2d-x.org\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n ****************************************************************************/\n#ifndef __CC_FILEUTILS_ANDROID_H__\n#define __CC_FILEUTILS_ANDROID_H__\n\n#include \"platform/CCPlatformConfig.h\"\n#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\n#include \"platform/CCFileUtils.h\"\n#include \"platform/CCPlatformMacros.h\"\n#include \"base/ccTypes.h\"\n#include <string>\n#include <vector>\n#include <unordered_map>\n#include <memory>\n#include \"jni.h\"\n#include \"android/asset_manager.h\"\n\nNS_CC_BEGIN\n\nclass ZipFile;\n\n/**\n * @addtogroup platform\n * @{\n */\n\n//! @brief  Helper class to handle file operations\nclass CC_DLL FileUtilsAndroid : public FileUtils\n{\n    friend class FileUtils;\npublic:\n    FileUtilsAndroid();\n    /**\n     * @js NA\n     * @lua NA\n     */\n    virtual ~FileUtilsAndroid();\n\n    static void setassetmanager(AAssetManager* a);\n    static AAssetManager* getAssetManager() { return assetmanager; }\n    static ZipFile* getObbFile() { return obbfile; }\n\n    /* override functions */\n    bool init() override;\n\n    virtual std::string getNewFilename(const std::string &filename) const override;\n\n    virtual FileUtils::Status getContents(const std::string& filename, ResizableBuffer* buffer) const override;\n\n    virtual std::string getWritablePath() const override;\n    virtual bool isAbsolutePath(const std::string& strPath) const override;\n    \n    virtual long getFileSize(const std::string& filepath) const override;\n    virtual std::vector<std::string> listFiles(const std::string& dirPath) const override;\n\n    virtual bool removeDirectory(const std::string& dirPath) const override;\nprotected:\n    virtual bool isFileExistInternal(const std::string& strFilePath) const override;\n    virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;\n\n    static AAssetManager* assetmanager;\n    static ZipFile* obbfile;\n};\n\n// end of platform group\n/// @}\n\nNS_CC_END\n\n#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID\n\n#endif // __CC_FILEUTILS_ANDROID_H__\n"
  },
  {
    "path": "thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.cpp",
    "content": "/****************************************************************************\nCopyright (c) 2010-2012 cocos2d-x.org\nCopyright (c) 2013-2016 Chukong Technologies Inc.\nCopyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.\n\nhttp://www.cocos2d-x.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n****************************************************************************/\n#include <stdlib.h>\n#include <jni.h>\n#include <android/log.h>\n#include <string>\n#include \"platform/android/jni/JniHelper.h\"\n#include \"platform/android/CCFileUtils-android.h\"\n#include \"android/asset_manager_jni.h\"\n#include \"platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h\"\n\n#include \"base/ccUTF8.h\"\n\n#define  LOG_TAG    \"Java_org_cocos2dx_lib_Cocos2dxHelper.cpp\"\n#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)\n\nstatic const std::string className = \"org.cocos2dx.lib.Cocos2dxHelper\";\n\nstatic EditTextCallback s_editTextCallback = nullptr;\nstatic void* s_ctx = nullptr;\n\nstatic int __deviceSampleRate = 44100;\nstatic int __deviceAudioBufferSizeInFrames = 192;\n\nstatic std::string g_apkPath;\n\nusing namespace cocos2d;\nusing namespace std;\n\nextern \"C\" {\n\n    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetContext(JNIEnv*  env, jobject thiz, jobject context, jobject assetManager) {\n        JniHelper::setClassLoaderFrom(context);\n        FileUtilsAndroid::setassetmanager(AAssetManager_fromJava(env, assetManager));\n    }\n\n    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetAudioDeviceInfo(JNIEnv*  env, jobject thiz, jboolean isSupportLowLatency, jint deviceSampleRate, jint deviceAudioBufferSizeInFrames) {\n        __deviceSampleRate = deviceSampleRate;\n        __deviceAudioBufferSizeInFrames = deviceAudioBufferSizeInFrames;\n        LOGD(\"nativeSetAudioDeviceInfo: sampleRate: %d, bufferSizeInFrames: %d\", __deviceSampleRate, __deviceAudioBufferSizeInFrames);\n    }\n\n    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult(JNIEnv * env, jobject obj, jbyteArray text) {\n        jsize  size = env->GetArrayLength(text);\n\n        if (size > 0) {\n            jbyte * data = (jbyte*)env->GetByteArrayElements(text, 0);\n            char* buffer = (char*)malloc(size+1);\n            if (buffer != nullptr) {\n                memcpy(buffer, data, size);\n                buffer[size] = '\\0';\n                // pass data to edittext's delegate\n                if (s_editTextCallback) s_editTextCallback(buffer, s_ctx);\n                free(buffer);\n            }\n            env->ReleaseByteArrayElements(text, data, 0);\n        } else {\n            if (s_editTextCallback) s_editTextCallback(\"\", s_ctx);\n        }\n    }\n\n}\n\nconst char * getApkPath() {\n    if (g_apkPath.empty())\n    {\n        g_apkPath = JniHelper::callStaticStringMethod(className, \"getAssetsPath\");\n    }\n\n    return g_apkPath.c_str();\n}\n\nstd::string getPackageNameJNI() {\n    return JniHelper::callStaticStringMethod(className, \"getCocos2dxPackageName\");\n}\n\nint getObbAssetFileDescriptorJNI(const char* path, long* startOffset, long* size) {\n    JniMethodInfo methodInfo;\n    int fd = 0;\n    \n    if (JniHelper::getStaticMethodInfo(methodInfo, className.c_str(), \"getObbAssetFileDescriptor\", \"(Ljava/lang/String;)[J\")) {\n        jstring stringArg = methodInfo.env->NewStringUTF(path);\n        jlongArray newArray = (jlongArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, stringArg);\n        jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);\n        \n        if (theArrayLen == 3) {\n            jboolean copy = JNI_FALSE;\n            jlong *array = methodInfo.env->GetLongArrayElements(newArray, &copy);\n            fd = static_cast<int>(array[0]);\n            *startOffset = array[1];\n            *size = array[2];\n            methodInfo.env->ReleaseLongArrayElements(newArray, array, 0);\n        }\n        \n        methodInfo.env->DeleteLocalRef(methodInfo.classID);\n        methodInfo.env->DeleteLocalRef(stringArg);\n    }\n    \n    return fd;\n}\n\nint getDeviceSampleRate()\n{\n    return __deviceSampleRate;\n}\n\nint getDeviceAudioBufferSizeInFrames()\n{\n    return __deviceAudioBufferSizeInFrames;\n}\n\nvoid conversionEncodingJNI(const char* src, int byteSize, const char* fromCharset, char* dst, const char* newCharset)\n{\n    JniMethodInfo methodInfo;\n\n    if (JniHelper::getStaticMethodInfo(methodInfo, className.c_str(), \"conversionEncoding\", \"([BLjava/lang/String;Ljava/lang/String;)[B\")) {\n        jbyteArray strArray = methodInfo.env->NewByteArray(byteSize);\n        methodInfo.env->SetByteArrayRegion(strArray, 0, byteSize, reinterpret_cast<const jbyte*>(src));\n\n        jstring stringArg1 = methodInfo.env->NewStringUTF(fromCharset);\n        jstring stringArg2 = methodInfo.env->NewStringUTF(newCharset);\n\n        jbyteArray newArray = (jbyteArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, strArray, stringArg1, stringArg2);\n        jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);\n        methodInfo.env->GetByteArrayRegion(newArray, 0, theArrayLen, (jbyte*)dst);\n\n        methodInfo.env->DeleteLocalRef(strArray);\n        methodInfo.env->DeleteLocalRef(stringArg1);\n        methodInfo.env->DeleteLocalRef(stringArg2);\n        methodInfo.env->DeleteLocalRef(newArray);\n        methodInfo.env->DeleteLocalRef(methodInfo.classID);\n    }\n}\n\n\nbool removeDirectoryJNI(const char* path)\n{\n    JniMethodInfo methodInfo;\n    if (JniHelper::getStaticMethodInfo(methodInfo,className.c_str(),\"removeDirectory\",\"(Ljava/lang/String;)Z\"))\n    {\n        jstring stringArgPath = methodInfo.env->NewStringUTF(path);\n        jboolean suc = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID,methodInfo.methodID,stringArgPath);\n\n        methodInfo.env->DeleteLocalRef(methodInfo.classID);\n        methodInfo.env->DeleteLocalRef(stringArgPath);\n\n        return suc;\n    }\n\n    return false;\n}"
  },
  {
    "path": "thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.h",
    "content": "/****************************************************************************\nCopyright (c) 2010-2012 cocos2d-x.org\nCopyright (c) 2013-2016 Chukong Technologies Inc.\nCopyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.\n\nhttp://www.cocos2d-x.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n****************************************************************************/\n#ifndef __Java_org_cocos2dx_lib_Cocos2dxHelper_H__\n#define __Java_org_cocos2dx_lib_Cocos2dxHelper_H__\n\n#include <string>\n\ntypedef void (*EditTextCallback)(const char* text, void* ctx);\n\nextern const char * getApkPath();\nextern std::string getPackageNameJNI();\nextern int getObbAssetFileDescriptorJNI(const char* path, long* startOffset, long* size);\nextern void conversionEncodingJNI(const char* src, int byteSize, const char* fromCharset, char* dst, const char* newCharset);\nextern bool removeDirectoryJNI(const char* path);\n\nextern int getDeviceSampleRate();\nextern int getDeviceAudioBufferSizeInFrames();\n\n#endif /* __Java_org_cocos2dx_lib_Cocos2dxHelper_H__ */"
  },
  {
    "path": "thirdparty/patch/cocos2d-x/android_cocos2dx.cmake",
    "content": "#/****************************************************************************\n# Copyright (c) 2013 cocos2d-x.org\n# Copyright (c) 2014 martell malone\n# Copyright (c) 2015-2017 Chukong Technologies Inc.\n#\n# http://www.cocos2d-x.org\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n# ****************************************************************************/\n\n# build engine library and all tests\n\ncmake_minimum_required(VERSION 3.6)\n\nproject(Cocos2d-x)\n\n# cocos2dx root path\nset(COCOS2DX_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})\nset(CMAKE_MODULE_PATH ${COCOS2DX_ROOT_PATH}/cmake/Modules/)\n\n# prevent in-source-build\ninclude(PreventInSourceBuilds)\n\n# works before build libcocos2d\ninclude(CocosBuildSet)\n\n# build options\noption(BUILD_TESTS \"Build tests\" ON)\n\n# default tests include lua, js test project, so we set those option on to build libs\noption(BUILD_LUA_LIBS ON)\noption(BUILD_JS_LIBS ON)\n\nadd_subdirectory(${COCOS2DX_ROOT_PATH}/cocos ${ENGINE_BINARY_PATH}/cocos/core)\nadd_subdirectory(${COCOS2DX_ROOT_PATH}/cocos/platform/android ${ENGINE_BINARY_PATH}/cocos/android)\n\n# prevent tests project to build \"cocos2d-x/cocos\" again\nset(BUILD_ENGINE_DONE ON)\n# add engine all tests project\nif (BUILD_TESTS)\n  add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/cpp-empty-test ${ENGINE_BINARY_PATH}/tests/cpp-empty-test)\n  add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/cpp-tests ${ENGINE_BINARY_PATH}/tests/cpp-tests)\n  add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/js-tests/project ${ENGINE_BINARY_PATH}/tests/js-tests)\n  add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/lua-empty-test/project ${ENGINE_BINARY_PATH}/tests/lua-empty-test)\n  add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/lua-tests/project ${ENGINE_BINARY_PATH}/tests/lua-test)\nendif()\n"
  },
  {
    "path": "thirdparty/patch/ffmpeg/android_ffmpeg.diff",
    "content": "diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c\nindex 15629755a1..29c0a65171 100644\n--- a/libavdevice/v4l2.c\n+++ b/libavdevice/v4l2.c\n@@ -95,7 +95,7 @@ struct video_data {\n     int (*open_f)(const char *file, int oflag, ...);\n     int (*close_f)(int fd);\n     int (*dup_f)(int fd);\n-    int (*ioctl_f)(int fd, unsigned long int request, ...);\n+    int (*ioctl_f)(int fd, unsigned int request, ...);\n     ssize_t (*read_f)(int fd, void *buffer, size_t n);\n     void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);\n     int (*munmap_f)(void *_start, size_t length);\n"
  },
  {
    "path": "thirdparty/patch/oniguruma/oniguruma.cmake",
    "content": "\ncmake_minimum_required(VERSION 2.8)\n# required for exports? cmake_minimum_required (VERSION 2.8.6)\nproject(oniguruma C)\n\nset(PACKAGE onig)\nset(PACKAGE_VERSION \"6.0.0\")\n\nset(USE_COMBINATION_EXPLOSION_CHECK 0)\nset(USE_CRNL_AS_LINE_TERMINATOR 0)\nset(VERSION ${PACKAGE_VERSION})\n\nif(MSVC)\n  # Force to always compile with W4\n  if(CMAKE_CXX_FLAGS MATCHES \"/W[0-4]\")\n    string(REGEX REPLACE \"/W[0-4]\" \"/W4\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n  else()\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /W4\")\n  endif()\nelseif(CMAKE_COMPILER_IS_GNUCXX)\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall\")\nelseif(CMAKE_COMPILER_IS_GNUCC)\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -Wall\")\nendif()\n\n\ninclude(cmake/dist.cmake)\ninclude(CheckCSourceCompiles)\ninclude(CheckIncludeFiles)\ninclude(CheckFunctionExists)\ninclude(CheckSymbolExists)\ninclude(CheckTypeSize)\ninclude(TestBigEndian)\n\ncheck_function_exists(alloca HAVE_ALLOCA)\ncheck_include_files(alloca.h HAVE_ALLOCA_H)\nset(HAVE_PROTOTYPES 1)\ncheck_include_files(stdarg.h    HAVE_STDARG_PROTOTYPES)\ncheck_include_files(stdint.h    HAVE_STDINT_H)\ncheck_include_files(stdlib.h    HAVE_STDLIB_H)\ncheck_include_files(strings.h   HAVE_STRINGS_H)\ncheck_include_files(string.h    HAVE_STRING_H)\ncheck_include_files(sys/times.h HAVE_SYS_TIMES_H)\ncheck_include_files(sys/time.h  HAVE_SYS_TIME_H)\ncheck_include_files(sys/types.h HAVE_SYS_TYPES_H)\ncheck_include_files(unistd.h    HAVE_UNISTD_H)\ncheck_type_size(int SIZEOF_INT)\ncheck_type_size(long SIZEOF_LONG)\ncheck_type_size(short SIZEOF_SHORT)\ncheck_include_files(\"stdlib.h;stdarg.h;string.h;float.h\" STDC_HEADERS)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/oniguruma.pc.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/oniguruma.pc @ONLY)\n\n\ninclude_directories(${CMAKE_CURRENT_BINARY_DIR})\ninclude_directories(${CMAKE_CURRENT_SOURCE_DIR})\n\nset(_SRCS src/regint.h src/regparse.h src/regenc.h src/st.h\n src/regerror.c src/regparse.c src/regext.c src/regcomp.c src/regexec.c\n src/reggnu.c src/regenc.c src/regsyntax.c src/regtrav.c src/regversion.c\n src/st.c src/regposix.c src/regposerr.c src/onig_init.c\n src/unicode.c src/ascii.c src/utf8.c src/utf16_be.c src/utf16_le.c\n src/utf32_be.c src/utf32_le.c src/euc_jp.c src/sjis.c src/iso8859_1.c\n src/iso8859_2.c src/iso8859_3.c src/iso8859_4.c src/iso8859_5.c\n src/iso8859_6.c src/iso8859_7.c src/iso8859_8.c src/iso8859_9.c\n src/iso8859_10.c src/iso8859_11.c src/iso8859_13.c src/iso8859_14.c\n src/iso8859_15.c src/iso8859_16.c src/euc_tw.c src/euc_kr.c src/big5.c\n src/gb18030.c src/koi8_r.c src/cp1251.c\n src/euc_jp_prop.c src/sjis_prop.c\n src/unicode_unfold_key.c\n src/unicode_fold1_key.c src/unicode_fold2_key.c src/unicode_fold3_key.c)\n\n\nadd_library(onig STATIC ${_SRCS})\n\ninstall_library(onig)\n\ninstall_header(src/oniguruma.h src/onigposix.h src/oniggnu.h)\n\ninstall_doc(doc/API doc/API.ja doc/RE doc/RE.ja doc/UNICODE_PROPERTIES)\ninstall_data(AUTHORS COPYING HISTORY README)\n\ninstall(FILES ${CMAKE_CURRENT_BINARY_DIR}/oniguruma.pc\n  DESTINATION lib/pkgconfig)\n"
  },
  {
    "path": "thirdparty/patch/opus/opusfile.h",
    "content": "/********************************************************************\n *                                                                  *\n * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *\n * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *\n * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *\n * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *\n *                                                                  *\n * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012           *\n * by the Xiph.Org Foundation and contributors https://xiph.org/    *\n *                                                                  *\n ********************************************************************\n\n function: stdio-based convenience library for opening/seeking/decoding\n last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $\n\n ********************************************************************/\n#if !defined(_opusfile_h)\n# define _opusfile_h (1)\n\n/**\\mainpage\n   \\section Introduction\n\n   This is the documentation for the <tt>libopusfile</tt> C API.\n\n   The <tt>libopusfile</tt> package provides a convenient high-level API for\n    decoding and basic manipulation of all Ogg Opus audio streams.\n   <tt>libopusfile</tt> is implemented as a layer on top of Xiph.Org's\n    reference\n    <tt><a href=\"https://www.xiph.org/ogg/doc/libogg/reference.html\">libogg</a></tt>\n    and\n    <tt><a href=\"https://opus-codec.org/docs/opus_api-1.3.1/\">libopus</a></tt>\n    libraries.\n\n   <tt>libopusfile</tt> provides several sets of built-in routines for\n    file/stream access, and may also use custom stream I/O routines provided by\n    the embedded environment.\n   There are built-in I/O routines provided for ANSI-compliant\n    <code>stdio</code> (<code>FILE *</code>), memory buffers, and URLs\n    (including <file:> URLs, plus optionally <http:> and <https:> URLs).\n\n   \\section Organization\n\n   The main API is divided into several sections:\n   - \\ref stream_open_close\n   - \\ref stream_info\n   - \\ref stream_decoding\n   - \\ref stream_seeking\n\n   Several additional sections are not tied to the main API.\n   - \\ref stream_callbacks\n   - \\ref header_info\n   - \\ref error_codes\n\n   \\section Overview\n\n   The <tt>libopusfile</tt> API always decodes files to 48&nbsp;kHz.\n   The original sample rate is not preserved by the lossy compression, though\n    it is stored in the header to allow you to resample to it after decoding\n    (the <tt>libopusfile</tt> API does not currently provide a resampler,\n    but the\n    <a href=\"https://www.speex.org/docs/manual/speex-manual/node7.html#SECTION00760000000000000000\">the\n    Speex resampler</a> is a good choice if you need one).\n   In general, if you are playing back the audio, you should leave it at\n    48&nbsp;kHz, provided your audio hardware supports it.\n   When decoding to a file, it may be worth resampling back to the original\n    sample rate, so as not to surprise users who might not expect the sample\n    rate to change after encoding to Opus and decoding.\n\n   Opus files can contain anywhere from 1 to 255 channels of audio.\n   The channel mappings for up to 8 channels are the same as the\n    <a href=\"https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9\">Vorbis\n    mappings</a>.\n   A special stereo API can convert everything to 2 channels, making it simple\n    to support multichannel files in an application which only has stereo\n    output.\n   Although the <tt>libopusfile</tt> ABI provides support for the theoretical\n    maximum number of channels, the current implementation does not support\n    files with more than 8 channels, as they do not have well-defined channel\n    mappings.\n\n   Like all Ogg files, Opus files may be \"chained\".\n   That is, multiple Opus files may be combined into a single, longer file just\n    by concatenating the original files.\n   This is commonly done in internet radio streaming, as it allows the title\n    and artist to be updated each time the song changes, since each link in the\n    chain includes its own set of metadata.\n\n   <tt>libopusfile</tt> fully supports chained files.\n   It will decode the first Opus stream found in each link of a chained file\n    (ignoring any other streams that might be concurrently multiplexed with it,\n    such as a video stream).\n\n   The channel count can also change between links.\n   If your application is not prepared to deal with this, it can use the stereo\n    API to ensure the audio from all links will always get decoded into a\n    common format.\n   Since <tt>libopusfile</tt> always decodes to 48&nbsp;kHz, you do not have to\n    worry about the sample rate changing between links (as was possible with\n    Vorbis).\n   This makes application support for chained files with <tt>libopusfile</tt>\n    very easy.*/\n\n# if defined(__cplusplus)\nextern \"C\" {\n# endif\n\n# include <stdarg.h>\n# include <stdio.h>\n# include <ogg/ogg.h>\n# include \"opus_multistream.h\"\n\n/**@cond PRIVATE*/\n\n/*Enable special features for gcc and gcc-compatible compilers.*/\n# if !defined(OP_GNUC_PREREQ)\n#  if defined(__GNUC__)&&defined(__GNUC_MINOR__)\n#   define OP_GNUC_PREREQ(_maj,_min) \\\n ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))\n#  else\n#   define OP_GNUC_PREREQ(_maj,_min) 0\n#  endif\n# endif\n\n# if OP_GNUC_PREREQ(4,0)\n#  pragma GCC visibility push(default)\n# endif\n\ntypedef struct OpusHead          OpusHead;\ntypedef struct OpusTags          OpusTags;\ntypedef struct OpusPictureTag    OpusPictureTag;\ntypedef struct OpusServerInfo    OpusServerInfo;\ntypedef struct OpusFileCallbacks OpusFileCallbacks;\ntypedef struct OggOpusFile       OggOpusFile;\n\n/*Warning attributes for libopusfile functions.*/\n# if OP_GNUC_PREREQ(3,4)\n#  define OP_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))\n# else\n#  define OP_WARN_UNUSED_RESULT\n# endif\n# if OP_GNUC_PREREQ(3,4)\n#  define OP_ARG_NONNULL(_x) __attribute__((__nonnull__(_x)))\n# else\n#  define OP_ARG_NONNULL(_x)\n# endif\n\n/**@endcond*/\n\n/**\\defgroup error_codes Error Codes*/\n/*@{*/\n/**\\name List of possible error codes\n   Many of the functions in this library return a negative error code when a\n    function fails.\n   This list provides a brief explanation of the common errors.\n   See each individual function for more details on what a specific error code\n    means in that context.*/\n/*@{*/\n\n/**A request did not succeed.*/\n#define OP_FALSE         (-1)\n/*Currently not used externally.*/\n#define OP_EOF           (-2)\n/**There was a hole in the page sequence numbers (e.g., a page was corrupt or\n    missing).*/\n#define OP_HOLE          (-3)\n/**An underlying read, seek, or tell operation failed when it should have\n    succeeded.*/\n#define OP_EREAD         (-128)\n/**A <code>NULL</code> pointer was passed where one was unexpected, or an\n    internal memory allocation failed, or an internal library error was\n    encountered.*/\n#define OP_EFAULT        (-129)\n/**The stream used a feature that is not implemented, such as an unsupported\n    channel family.*/\n#define OP_EIMPL         (-130)\n/**One or more parameters to a function were invalid.*/\n#define OP_EINVAL        (-131)\n/**A purported Ogg Opus stream did not begin with an Ogg page, a purported\n    header packet did not start with one of the required strings, \"OpusHead\" or\n    \"OpusTags\", or a link in a chained file was encountered that did not\n    contain any logical Opus streams.*/\n#define OP_ENOTFORMAT    (-132)\n/**A required header packet was not properly formatted, contained illegal\n    values, or was missing altogether.*/\n#define OP_EBADHEADER    (-133)\n/**The ID header contained an unrecognized version number.*/\n#define OP_EVERSION      (-134)\n/*Currently not used at all.*/\n#define OP_ENOTAUDIO     (-135)\n/**An audio packet failed to decode properly.\n   This is usually caused by a multistream Ogg packet where the durations of\n    the individual Opus packets contained in it are not all the same.*/\n#define OP_EBADPACKET    (-136)\n/**We failed to find data we had seen before, or the bitstream structure was\n    sufficiently malformed that seeking to the target destination was\n    impossible.*/\n#define OP_EBADLINK      (-137)\n/**An operation that requires seeking was requested on an unseekable stream.*/\n#define OP_ENOSEEK       (-138)\n/**The first or last granule position of a link failed basic validity checks.*/\n#define OP_EBADTIMESTAMP (-139)\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup header_info Header Information*/\n/*@{*/\n\n/**The maximum number of channels in an Ogg Opus stream.*/\n#define OPUS_CHANNEL_COUNT_MAX (255)\n\n/**Ogg Opus bitstream information.\n   This contains the basic playback parameters for a stream, and corresponds to\n    the initial ID header packet of an Ogg Opus stream.*/\nstruct OpusHead{\n  /**The Ogg Opus format version, in the range 0...255.\n     The top 4 bits represent a \"major\" version, and the bottom four bits\n      represent backwards-compatible \"minor\" revisions.\n     The current specification describes version 1.\n     This library will recognize versions up through 15 as backwards compatible\n      with the current specification.\n     An earlier draft of the specification described a version 0, but the only\n      difference between version 1 and version 0 is that version 0 did\n      not specify the semantics for handling the version field.*/\n  int           version;\n  /**The number of channels, in the range 1...255.*/\n  int           channel_count;\n  /**The number of samples that should be discarded from the beginning of the\n      stream.*/\n  unsigned      pre_skip;\n  /**The sampling rate of the original input.\n     All Opus audio is coded at 48 kHz, and should also be decoded at 48 kHz\n      for playback (unless the target hardware does not support this sampling\n      rate).\n     However, this field may be used to resample the audio back to the original\n      sampling rate, for example, when saving the output to a file.*/\n  opus_uint32   input_sample_rate;\n  /**The gain to apply to the decoded output, in dB, as a Q8 value in the range\n      -32768...32767.\n     The <tt>libopusfile</tt> API will automatically apply this gain to the\n      decoded output before returning it, scaling it by\n      <code>pow(10,output_gain/(20.0*256))</code>.\n     You can adjust this behavior with op_set_gain_offset().*/\n  int           output_gain;\n  /**The channel mapping family, in the range 0...255.\n     Channel mapping family 0 covers mono or stereo in a single stream.\n     Channel mapping family 1 covers 1 to 8 channels in one or more streams,\n      using the Vorbis speaker assignments.\n     Channel mapping family 255 covers 1 to 255 channels in one or more\n      streams, but without any defined speaker assignment.*/\n  int           mapping_family;\n  /**The number of Opus streams in each Ogg packet, in the range 1...255.*/\n  int           stream_count;\n  /**The number of coupled Opus streams in each Ogg packet, in the range\n      0...127.\n     This must satisfy <code>0 <= coupled_count <= stream_count</code> and\n      <code>coupled_count + stream_count <= 255</code>.\n     The coupled streams appear first, before all uncoupled streams, in an Ogg\n      Opus packet.*/\n  int           coupled_count;\n  /**The mapping from coded stream channels to output channels.\n     Let <code>index=mapping[k]</code> be the value for channel <code>k</code>.\n     If <code>index<2*coupled_count</code>, then it refers to the left channel\n      from stream <code>(index/2)</code> if even, and the right channel from\n      stream <code>(index/2)</code> if odd.\n     Otherwise, it refers to the output of the uncoupled stream\n      <code>(index-coupled_count)</code>.*/\n  unsigned char mapping[OPUS_CHANNEL_COUNT_MAX];\n};\n\n/**The metadata from an Ogg Opus stream.\n\n   This structure holds the in-stream metadata corresponding to the 'comment'\n    header packet of an Ogg Opus stream.\n   The comment header is meant to be used much like someone jotting a quick\n    note on the label of a CD.\n   It should be a short, to the point text note that can be more than a couple\n    words, but not more than a short paragraph.\n\n   The metadata is stored as a series of (tag, value) pairs, in length-encoded\n    string vectors, using the same format as Vorbis (without the final \"framing\n    bit\"), Theora, and Speex, except for the packet header.\n   The first occurrence of the '=' character delimits the tag and value.\n   A particular tag may occur more than once, and order is significant.\n   The character set encoding for the strings is always UTF-8, but the tag\n    names are limited to ASCII, and treated as case-insensitive.\n   See <a href=\"https://www.xiph.org/vorbis/doc/v-comment.html\">the Vorbis\n    comment header specification</a> for details.\n\n   In filling in this structure, <tt>libopusfile</tt> will null-terminate the\n    #user_comments strings for safety.\n   However, the bitstream format itself treats them as 8-bit clean vectors,\n    possibly containing NUL characters, so the #comment_lengths array should be\n    treated as their authoritative length.\n\n   This structure is binary and source-compatible with a\n    <code>vorbis_comment</code>, and pointers to it may be freely cast to\n    <code>vorbis_comment</code> pointers, and vice versa.\n   It is provided as a separate type to avoid introducing a compile-time\n    dependency on the libvorbis headers.*/\nstruct OpusTags{\n  /**The array of comment string vectors.*/\n  char **user_comments;\n  /**An array of the corresponding length of each vector, in bytes.*/\n  int   *comment_lengths;\n  /**The total number of comment streams.*/\n  int    comments;\n  /**The null-terminated vendor string.\n     This identifies the software used to encode the stream.*/\n  char  *vendor;\n};\n\n/**\\name Picture tag image formats*/\n/*@{*/\n\n/**The MIME type was not recognized, or the image data did not match the\n    declared MIME type.*/\n#define OP_PIC_FORMAT_UNKNOWN (-1)\n/**The MIME type indicates the image data is really a URL.*/\n#define OP_PIC_FORMAT_URL     (0)\n/**The image is a JPEG.*/\n#define OP_PIC_FORMAT_JPEG    (1)\n/**The image is a PNG.*/\n#define OP_PIC_FORMAT_PNG     (2)\n/**The image is a GIF.*/\n#define OP_PIC_FORMAT_GIF     (3)\n\n/*@}*/\n\n/**The contents of a METADATA_BLOCK_PICTURE tag.*/\nstruct OpusPictureTag{\n  /**The picture type according to the ID3v2 APIC frame:\n     <ol start=\"0\">\n     <li>Other</li>\n     <li>32x32 pixels 'file icon' (PNG only)</li>\n     <li>Other file icon</li>\n     <li>Cover (front)</li>\n     <li>Cover (back)</li>\n     <li>Leaflet page</li>\n     <li>Media (e.g. label side of CD)</li>\n     <li>Lead artist/lead performer/soloist</li>\n     <li>Artist/performer</li>\n     <li>Conductor</li>\n     <li>Band/Orchestra</li>\n     <li>Composer</li>\n     <li>Lyricist/text writer</li>\n     <li>Recording Location</li>\n     <li>During recording</li>\n     <li>During performance</li>\n     <li>Movie/video screen capture</li>\n     <li>A bright colored fish</li>\n     <li>Illustration</li>\n     <li>Band/artist logotype</li>\n     <li>Publisher/Studio logotype</li>\n     </ol>\n     Others are reserved and should not be used.\n     There may only be one each of picture type 1 and 2 in a file.*/\n  opus_int32     type;\n  /**The MIME type of the picture, in printable ASCII characters 0x20-0x7E.\n     The MIME type may also be <code>\"-->\"</code> to signify that the data part\n      is a URL pointing to the picture instead of the picture data itself.\n     In this case, a terminating NUL is appended to the URL string in #data,\n      but #data_length is set to the length of the string excluding that\n      terminating NUL.*/\n  char          *mime_type;\n  /**The description of the picture, in UTF-8.*/\n  char          *description;\n  /**The width of the picture in pixels.*/\n  opus_uint32    width;\n  /**The height of the picture in pixels.*/\n  opus_uint32    height;\n  /**The color depth of the picture in bits-per-pixel (<em>not</em>\n      bits-per-channel).*/\n  opus_uint32    depth;\n  /**For indexed-color pictures (e.g., GIF), the number of colors used, or 0\n      for non-indexed pictures.*/\n  opus_uint32    colors;\n  /**The length of the picture data in bytes.*/\n  opus_uint32    data_length;\n  /**The binary picture data.*/\n  unsigned char *data;\n  /**The format of the picture data, if known.\n     One of\n     <ul>\n     <li>#OP_PIC_FORMAT_UNKNOWN,</li>\n     <li>#OP_PIC_FORMAT_URL,</li>\n     <li>#OP_PIC_FORMAT_JPEG,</li>\n     <li>#OP_PIC_FORMAT_PNG, or</li>\n     <li>#OP_PIC_FORMAT_GIF.</li>\n     </ul>*/\n  int            format;\n};\n\n/**\\name Functions for manipulating header data\n\n   These functions manipulate the #OpusHead and #OpusTags structures,\n    which describe the audio parameters and tag-value metadata, respectively.\n   These can be used to query the headers returned by <tt>libopusfile</tt>, or\n    to parse Opus headers from sources other than an Ogg Opus stream, provided\n    they use the same format.*/\n/*@{*/\n\n/**Parses the contents of the ID header packet of an Ogg Opus stream.\n   \\param[out] _head Returns the contents of the parsed packet.\n                     The contents of this structure are untouched on error.\n                     This may be <code>NULL</code> to merely test the header\n                      for validity.\n   \\param[in]  _data The contents of the ID header packet.\n   \\param      _len  The number of bytes of data in the ID header packet.\n   \\return 0 on success or a negative value on error.\n   \\retval #OP_ENOTFORMAT If the data does not start with the \"OpusHead\"\n                           string.\n   \\retval #OP_EVERSION   If the version field signaled a version this library\n                           does not know how to parse.\n   \\retval #OP_EIMPL      If the channel mapping family was 255, which general\n                           purpose players should not attempt to play.\n   \\retval #OP_EBADHEADER If the contents of the packet otherwise violate the\n                           Ogg Opus specification:\n                          <ul>\n                           <li>Insufficient data,</li>\n                           <li>Too much data for the known minor versions,</li>\n                           <li>An unrecognized channel mapping family,</li>\n                           <li>Zero channels or too many channels,</li>\n                           <li>Zero coded streams,</li>\n                           <li>Too many coupled streams, or</li>\n                           <li>An invalid channel mapping index.</li>\n                          </ul>*/\nOP_WARN_UNUSED_RESULT int opus_head_parse(OpusHead *_head,\n const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2);\n\n/**Converts a granule position to a sample offset for a given Ogg Opus stream.\n   The sample offset is simply <code>_gp-_head->pre_skip</code>.\n   Granule position values smaller than OpusHead#pre_skip correspond to audio\n    that should never be played, and thus have no associated sample offset.\n   This function returns -1 for such values.\n   This function also correctly handles extremely large granule positions,\n    which may have wrapped around to a negative number when stored in a signed\n    ogg_int64_t value.\n   \\param _head The #OpusHead information from the ID header of the stream.\n   \\param _gp   The granule position to convert.\n   \\return The sample offset associated with the given granule position\n            (counting at a 48 kHz sampling rate), or the special value -1 on\n            error (i.e., the granule position was smaller than the pre-skip\n            amount).*/\nogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp)\n OP_ARG_NONNULL(1);\n\n/**Parses the contents of the 'comment' header packet of an Ogg Opus stream.\n   \\param[out] _tags An uninitialized #OpusTags structure.\n                     This returns the contents of the parsed packet.\n                     The contents of this structure are untouched on error.\n                     This may be <code>NULL</code> to merely test the header\n                      for validity.\n   \\param[in]  _data The contents of the 'comment' header packet.\n   \\param      _len  The number of bytes of data in the 'info' header packet.\n   \\retval 0              Success.\n   \\retval #OP_ENOTFORMAT If the data does not start with the \"OpusTags\"\n                           string.\n   \\retval #OP_EBADHEADER If the contents of the packet otherwise violate the\n                           Ogg Opus specification.\n   \\retval #OP_EFAULT     If there wasn't enough memory to store the tags.*/\nOP_WARN_UNUSED_RESULT int opus_tags_parse(OpusTags *_tags,\n const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2);\n\n/**Performs a deep copy of an #OpusTags structure.\n   \\param _dst The #OpusTags structure to copy into.\n               If this function fails, the contents of this structure remain\n                untouched.\n   \\param _src The #OpusTags structure to copy from.\n   \\retval 0          Success.\n   \\retval #OP_EFAULT If there wasn't enough memory to copy the tags.*/\nint opus_tags_copy(OpusTags *_dst,const OpusTags *_src) OP_ARG_NONNULL(1);\n\n/**Initializes an #OpusTags structure.\n   This should be called on a freshly allocated #OpusTags structure before\n    attempting to use it.\n   \\param _tags The #OpusTags structure to initialize.*/\nvoid opus_tags_init(OpusTags *_tags) OP_ARG_NONNULL(1);\n\n/**Add a (tag, value) pair to an initialized #OpusTags structure.\n   \\note Neither opus_tags_add() nor opus_tags_add_comment() support values\n    containing embedded NULs, although the bitstream format does support them.\n   To add such tags, you will need to manipulate the #OpusTags structure\n    directly.\n   \\param _tags  The #OpusTags structure to add the (tag, value) pair to.\n   \\param _tag   A NUL-terminated, case-insensitive, ASCII string containing\n                  the tag to add (without an '=' character).\n   \\param _value A NUL-terminated UTF-8 containing the corresponding value.\n   \\return 0 on success, or a negative value on failure.\n   \\retval #OP_EFAULT An internal memory allocation failed.*/\nint opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) OP_ARG_NONNULL(3);\n\n/**Add a comment to an initialized #OpusTags structure.\n   \\note Neither opus_tags_add_comment() nor opus_tags_add() support comments\n    containing embedded NULs, although the bitstream format does support them.\n   To add such tags, you will need to manipulate the #OpusTags structure\n    directly.\n   \\param _tags    The #OpusTags structure to add the comment to.\n   \\param _comment A NUL-terminated UTF-8 string containing the comment in\n                    \"TAG=value\" form.\n   \\return 0 on success, or a negative value on failure.\n   \\retval #OP_EFAULT An internal memory allocation failed.*/\nint opus_tags_add_comment(OpusTags *_tags,const char *_comment)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Replace the binary suffix data at the end of the packet (if any).\n   \\param _tags An initialized #OpusTags structure.\n   \\param _data A buffer of binary data to append after the encoded user\n                 comments.\n                The least significant bit of the first byte of this data must\n                 be set (to ensure the data is preserved by other editors).\n   \\param _len  The number of bytes of binary data to append.\n                This may be zero to remove any existing binary suffix data.\n   \\return 0 on success, or a negative value on error.\n   \\retval #OP_EINVAL \\a _len was negative, or \\a _len was positive but\n                       \\a _data was <code>NULL</code> or the least significant\n                       bit of the first byte was not set.\n   \\retval #OP_EFAULT An internal memory allocation failed.*/\nint opus_tags_set_binary_suffix(OpusTags *_tags,\n const unsigned char *_data,int _len) OP_ARG_NONNULL(1);\n\n/**Look up a comment value by its tag.\n   \\param _tags  An initialized #OpusTags structure.\n   \\param _tag   The tag to look up.\n   \\param _count The instance of the tag.\n                 The same tag can appear multiple times, each with a distinct\n                  value, so an index is required to retrieve them all.\n                 The order in which these values appear is significant and\n                  should be preserved.\n                 Use opus_tags_query_count() to get the legal range for the\n                  \\a _count parameter.\n   \\return A pointer to the queried tag's value.\n           This points directly to data in the #OpusTags structure.\n           It should not be modified or freed by the application, and\n            modifications to the structure may invalidate the pointer.\n   \\retval NULL If no matching tag is found.*/\nconst char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Look up the number of instances of a tag.\n   Call this first when querying for a specific tag and then iterate over the\n    number of instances with separate calls to opus_tags_query() to retrieve\n    all the values for that tag in order.\n   \\param _tags An initialized #OpusTags structure.\n   \\param _tag  The tag to look up.\n   \\return The number of instances of this particular tag.*/\nint opus_tags_query_count(const OpusTags *_tags,const char *_tag)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Retrieve the binary suffix data at the end of the packet (if any).\n   \\param      _tags An initialized #OpusTags structure.\n   \\param[out] _len  Returns the number of bytes of binary suffix data returned.\n   \\return A pointer to the binary suffix data, or <code>NULL</code> if none\n            was present.*/\nconst unsigned char *opus_tags_get_binary_suffix(const OpusTags *_tags,\n int *_len) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Get the album gain from an R128_ALBUM_GAIN tag, if one was specified.\n   This searches for the first R128_ALBUM_GAIN tag with a valid signed,\n    16-bit decimal integer value and returns the value.\n   This routine is exposed merely for convenience for applications which wish\n    to do something special with the album gain (i.e., display it).\n   If you simply wish to apply the album gain instead of the header gain, you\n    can use op_set_gain_offset() with an #OP_ALBUM_GAIN type and no offset.\n   \\param      _tags    An initialized #OpusTags structure.\n   \\param[out] _gain_q8 The album gain, in 1/256ths of a dB.\n                        This will lie in the range [-32768,32767], and should\n                         be applied in <em>addition</em> to the header gain.\n                        On error, no value is returned, and the previous\n                         contents remain unchanged.\n   \\return 0 on success, or a negative value on error.\n   \\retval #OP_FALSE There was no album gain available in the given tags.*/\nint opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Get the track gain from an R128_TRACK_GAIN tag, if one was specified.\n   This searches for the first R128_TRACK_GAIN tag with a valid signed,\n    16-bit decimal integer value and returns the value.\n   This routine is exposed merely for convenience for applications which wish\n    to do something special with the track gain (i.e., display it).\n   If you simply wish to apply the track gain instead of the header gain, you\n    can use op_set_gain_offset() with an #OP_TRACK_GAIN type and no offset.\n   \\param      _tags    An initialized #OpusTags structure.\n   \\param[out] _gain_q8 The track gain, in 1/256ths of a dB.\n                        This will lie in the range [-32768,32767], and should\n                         be applied in <em>addition</em> to the header gain.\n                        On error, no value is returned, and the previous\n                         contents remain unchanged.\n   \\return 0 on success, or a negative value on error.\n   \\retval #OP_FALSE There was no track gain available in the given tags.*/\nint opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8)\n OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Clears the #OpusTags structure.\n   This should be called on an #OpusTags structure after it is no longer\n    needed.\n   It will free all memory used by the structure members.\n   \\param _tags The #OpusTags structure to clear.*/\nvoid opus_tags_clear(OpusTags *_tags) OP_ARG_NONNULL(1);\n\n/**Check if \\a _comment is an instance of a \\a _tag_name tag.\n   \\see opus_tagncompare\n   \\param _tag_name A NUL-terminated, case-insensitive, ASCII string containing\n                     the name of the tag to check for (without the terminating\n                     '=' character).\n   \\param _comment  The comment string to check.\n   \\return An integer less than, equal to, or greater than zero if \\a _comment\n            is found respectively, to be less than, to match, or be greater\n            than a \"tag=value\" string whose tag matches \\a _tag_name.*/\nint opus_tagcompare(const char *_tag_name,const char *_comment);\n\n/**Check if \\a _comment is an instance of a \\a _tag_name tag.\n   This version is slightly more efficient than opus_tagcompare() if the length\n    of the tag name is already known (e.g., because it is a constant).\n   \\see opus_tagcompare\n   \\param _tag_name A case-insensitive ASCII string containing the name of the\n                     tag to check for (without the terminating '=' character).\n   \\param _tag_len  The number of characters in the tag name.\n                    This must be non-negative.\n   \\param _comment  The comment string to check.\n   \\return An integer less than, equal to, or greater than zero if \\a _comment\n            is found respectively, to be less than, to match, or be greater\n            than a \"tag=value\" string whose tag matches the first \\a _tag_len\n            characters of \\a _tag_name.*/\nint opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment);\n\n/**Parse a single METADATA_BLOCK_PICTURE tag.\n   This decodes the BASE64-encoded content of the tag and returns a structure\n    with the MIME type, description, image parameters (if known), and the\n    compressed image data.\n   If the MIME type indicates the presence of an image format we recognize\n    (JPEG, PNG, or GIF) and the actual image data contains the magic signature\n    associated with that format, then the OpusPictureTag::format field will be\n    set to the corresponding format.\n   This is provided as a convenience to avoid requiring applications to parse\n    the MIME type and/or do their own format detection for the commonly used\n    formats.\n   In this case, we also attempt to extract the image parameters directly from\n    the image data (overriding any that were present in the tag, which the\n    specification says applications are not meant to rely on).\n   The application must still provide its own support for actually decoding the\n    image data and, if applicable, retrieving that data from URLs.\n   \\param[out] _pic Returns the parsed picture data.\n                    No sanitation is done on the type, MIME type, or\n                     description fields, so these might return invalid values.\n                    The contents of this structure are left unmodified on\n                     failure.\n   \\param      _tag The METADATA_BLOCK_PICTURE tag contents.\n                    The leading \"METADATA_BLOCK_PICTURE=\" portion is optional,\n                     to allow the function to be used on either directly on the\n                     values in OpusTags::user_comments or on the return value\n                     of opus_tags_query().\n   \\return 0 on success or a negative value on error.\n   \\retval #OP_ENOTFORMAT The METADATA_BLOCK_PICTURE contents were not valid.\n   \\retval #OP_EFAULT     There was not enough memory to store the picture tag\n                           contents.*/\nOP_WARN_UNUSED_RESULT int opus_picture_tag_parse(OpusPictureTag *_pic,\n const char *_tag) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Initializes an #OpusPictureTag structure.\n   This should be called on a freshly allocated #OpusPictureTag structure\n    before attempting to use it.\n   \\param _pic The #OpusPictureTag structure to initialize.*/\nvoid opus_picture_tag_init(OpusPictureTag *_pic) OP_ARG_NONNULL(1);\n\n/**Clears the #OpusPictureTag structure.\n   This should be called on an #OpusPictureTag structure after it is no longer\n    needed.\n   It will free all memory used by the structure members.\n   \\param _pic The #OpusPictureTag structure to clear.*/\nvoid opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1);\n\n/*@}*/\n\n/*@}*/\n\n/**\\defgroup url_options URL Reading Options*/\n/*@{*/\n/**\\name URL reading options\n   Options for op_url_stream_create() and associated functions.\n   These allow you to provide proxy configuration parameters, skip SSL\n    certificate checks, etc.\n   Options are processed in order, and if the same option is passed multiple\n    times, only the value specified by the last occurrence has an effect\n    (unless otherwise specified).\n   They may be expanded in the future.*/\n/*@{*/\n\n/**@cond PRIVATE*/\n\n/*These are the raw numbers used to define the request codes.\n  They should not be used directly.*/\n#define OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST (6464)\n#define OP_HTTP_PROXY_HOST_REQUEST            (6528)\n#define OP_HTTP_PROXY_PORT_REQUEST            (6592)\n#define OP_HTTP_PROXY_USER_REQUEST            (6656)\n#define OP_HTTP_PROXY_PASS_REQUEST            (6720)\n#define OP_GET_SERVER_INFO_REQUEST            (6784)\n\n#define OP_URL_OPT(_request) ((char *)(_request))\n\n/*These macros trigger compilation errors or warnings if the wrong types are\n   provided to one of the URL options.*/\n#define OP_CHECK_INT(_x) ((void)((_x)==(opus_int32)0),(opus_int32)(_x))\n#define OP_CHECK_CONST_CHAR_PTR(_x) ((_x)+((_x)-(const char *)(_x)))\n#define OP_CHECK_SERVER_INFO_PTR(_x) ((_x)+((_x)-(OpusServerInfo *)(_x)))\n\n/**@endcond*/\n\n/**HTTP/Shoutcast/Icecast server information associated with a URL.*/\nstruct OpusServerInfo{\n  /**The name of the server (icy-name/ice-name).\n     This is <code>NULL</code> if there was no <code>icy-name</code> or\n      <code>ice-name</code> header.*/\n  char        *name;\n  /**A short description of the server (icy-description/ice-description).\n     This is <code>NULL</code> if there was no <code>icy-description</code> or\n      <code>ice-description</code> header.*/\n  char        *description;\n  /**The genre the server falls under (icy-genre/ice-genre).\n     This is <code>NULL</code> if there was no <code>icy-genre</code> or\n      <code>ice-genre</code> header.*/\n  char        *genre;\n  /**The homepage for the server (icy-url/ice-url).\n     This is <code>NULL</code> if there was no <code>icy-url</code> or\n      <code>ice-url</code> header.*/\n  char        *url;\n  /**The software used by the origin server (Server).\n     This is <code>NULL</code> if there was no <code>Server</code> header.*/\n  char        *server;\n  /**The media type of the entity sent to the recepient (Content-Type).\n     This is <code>NULL</code> if there was no <code>Content-Type</code>\n      header.*/\n  char        *content_type;\n  /**The nominal stream bitrate in kbps (icy-br/ice-bitrate).\n     This is <code>-1</code> if there was no <code>icy-br</code> or\n      <code>ice-bitrate</code> header.*/\n  opus_int32   bitrate_kbps;\n  /**Flag indicating whether the server is public (<code>1</code>) or not\n      (<code>0</code>) (icy-pub/ice-public).\n     This is <code>-1</code> if there was no <code>icy-pub</code> or\n      <code>ice-public</code> header.*/\n  int          is_public;\n  /**Flag indicating whether the server is using HTTPS instead of HTTP.\n     This is <code>0</code> unless HTTPS is being used.\n     This may not match the protocol used in the original URL if there were\n      redirections.*/\n  int          is_ssl;\n};\n\n/**Initializes an #OpusServerInfo structure.\n   All fields are set as if the corresponding header was not available.\n   \\param _info The #OpusServerInfo structure to initialize.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.*/\nvoid opus_server_info_init(OpusServerInfo *_info) OP_ARG_NONNULL(1);\n\n/**Clears the #OpusServerInfo structure.\n   This should be called on an #OpusServerInfo structure after it is no longer\n    needed.\n   It will free all memory used by the structure members.\n   \\param _info The #OpusServerInfo structure to clear.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.*/\nvoid opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1);\n\n/**Skip the certificate check when connecting via TLS/SSL (https).\n   \\param _b <code>opus_int32</code>: Whether or not to skip the certificate\n              check.\n             The check will be skipped if \\a _b is non-zero, and will not be\n              skipped if \\a _b is zero.\n   \\hideinitializer*/\n#define OP_SSL_SKIP_CERTIFICATE_CHECK(_b) \\\n OP_URL_OPT(OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST),OP_CHECK_INT(_b)\n\n/**Proxy connections through the given host.\n   If no port is specified via #OP_HTTP_PROXY_PORT, the port number defaults\n    to 8080 (http-alt).\n   All proxy parameters are ignored for non-http and non-https URLs.\n   \\param _host <code>const char *</code>: The proxy server hostname.\n                This may be <code>NULL</code> to disable the use of a proxy\n                 server.\n   \\hideinitializer*/\n#define OP_HTTP_PROXY_HOST(_host) \\\n OP_URL_OPT(OP_HTTP_PROXY_HOST_REQUEST),OP_CHECK_CONST_CHAR_PTR(_host)\n\n/**Use the given port when proxying connections.\n   This option only has an effect if #OP_HTTP_PROXY_HOST is specified with a\n    non-<code>NULL</code> \\a _host.\n   If this option is not provided, the proxy port number defaults to 8080\n    (http-alt).\n   All proxy parameters are ignored for non-http and non-https URLs.\n   \\param _port <code>opus_int32</code>: The proxy server port.\n                This must be in the range 0...65535 (inclusive), or the\n                 URL function this is passed to will fail.\n   \\hideinitializer*/\n#define OP_HTTP_PROXY_PORT(_port) \\\n OP_URL_OPT(OP_HTTP_PROXY_PORT_REQUEST),OP_CHECK_INT(_port)\n\n/**Use the given user name for authentication when proxying connections.\n   All proxy parameters are ignored for non-http and non-https URLs.\n   \\param _user const char *: The proxy server user name.\n                              This may be <code>NULL</code> to disable proxy\n                               authentication.\n                              A non-<code>NULL</code> value only has an effect\n                               if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_PASS\n                               are also specified with non-<code>NULL</code>\n                               arguments.\n   \\hideinitializer*/\n#define OP_HTTP_PROXY_USER(_user) \\\n OP_URL_OPT(OP_HTTP_PROXY_USER_REQUEST),OP_CHECK_CONST_CHAR_PTR(_user)\n\n/**Use the given password for authentication when proxying connections.\n   All proxy parameters are ignored for non-http and non-https URLs.\n   \\param _pass const char *: The proxy server password.\n                              This may be <code>NULL</code> to disable proxy\n                               authentication.\n                              A non-<code>NULL</code> value only has an effect\n                               if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_USER\n                               are also specified with non-<code>NULL</code>\n                               arguments.\n   \\hideinitializer*/\n#define OP_HTTP_PROXY_PASS(_pass) \\\n OP_URL_OPT(OP_HTTP_PROXY_PASS_REQUEST),OP_CHECK_CONST_CHAR_PTR(_pass)\n\n/**Parse information about the streaming server (if any) and return it.\n   Very little validation is done.\n   In particular, OpusServerInfo::url may not be a valid URL,\n    OpusServerInfo::bitrate_kbps may not really be in kbps, and\n    OpusServerInfo::content_type may not be a valid MIME type.\n   The character set of the string fields is not specified anywhere, and should\n    not be assumed to be valid UTF-8.\n   \\param _info OpusServerInfo *: Returns information about the server.\n                                  If there is any error opening the stream, the\n                                   contents of this structure remain\n                                   unmodified.\n                                  On success, fills in the structure with the\n                                   server information that was available, if\n                                   any.\n                                  After a successful return, the contents of\n                                   this structure should be freed by calling\n                                   opus_server_info_clear().\n   \\hideinitializer*/\n#define OP_GET_SERVER_INFO(_info) \\\n OP_URL_OPT(OP_GET_SERVER_INFO_REQUEST),OP_CHECK_SERVER_INFO_PTR(_info)\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup stream_callbacks Abstract Stream Reading Interface*/\n/*@{*/\n/**\\name Functions for reading from streams\n   These functions define the interface used to read from and seek in a stream\n    of data.\n   A stream does not need to implement seeking, but the decoder will not be\n    able to seek if it does not do so.\n   These functions also include some convenience routines for working with\n    standard <code>FILE</code> pointers, complete streams stored in a single\n    block of memory, or URLs.*/\n/*@{*/\n\n/**Reads up to \\a _nbytes bytes of data from \\a _stream.\n   \\param      _stream The stream to read from.\n   \\param[out] _ptr    The buffer to store the data in.\n   \\param      _nbytes The maximum number of bytes to read.\n                       This function may return fewer, though it will not\n                        return zero unless it reaches end-of-file.\n   \\return The number of bytes successfully read, or a negative value on\n            error.*/\ntypedef int (*op_read_func)(void *_stream,unsigned char *_ptr,int _nbytes);\n\n/**Sets the position indicator for \\a _stream.\n   The new position, measured in bytes, is obtained by adding \\a _offset\n    bytes to the position specified by \\a _whence.\n   If \\a _whence is set to <code>SEEK_SET</code>, <code>SEEK_CUR</code>, or\n    <code>SEEK_END</code>, the offset is relative to the start of the stream,\n    the current position indicator, or end-of-file, respectively.\n   \\retval 0  Success.\n   \\retval -1 Seeking is not supported or an error occurred.\n              <code>errno</code> need not be set.*/\ntypedef int (*op_seek_func)(void *_stream,opus_int64 _offset,int _whence);\n\n/**Obtains the current value of the position indicator for \\a _stream.\n   \\return The current position indicator.*/\ntypedef opus_int64 (*op_tell_func)(void *_stream);\n\n/**Closes the underlying stream.\n   \\retval 0   Success.\n   \\retval EOF An error occurred.\n               <code>errno</code> need not be set.*/\ntypedef int (*op_close_func)(void *_stream);\n\n/**The callbacks used to access non-<code>FILE</code> stream resources.\n   The function prototypes are basically the same as for the stdio functions\n    <code>fread()</code>, <code>fseek()</code>, <code>ftell()</code>, and\n    <code>fclose()</code>.\n   The differences are that the <code>FILE *</code> arguments have been\n    replaced with a <code>void *</code>, which is to be used as a pointer to\n    whatever internal data these functions might need, that #seek and #tell\n    take and return 64-bit offsets, and that #seek <em>must</em> return -1 if\n    the stream is unseekable.*/\nstruct OpusFileCallbacks{\n  /**Used to read data from the stream.\n     This must not be <code>NULL</code>.*/\n  op_read_func  read;\n  /**Used to seek in the stream.\n     This may be <code>NULL</code> if seeking is not implemented.*/\n  op_seek_func  seek;\n  /**Used to return the current read position in the stream.\n     This may be <code>NULL</code> if seeking is not implemented.*/\n  op_tell_func  tell;\n  /**Used to close the stream when the decoder is freed.\n     This may be <code>NULL</code> to leave the stream open.*/\n  op_close_func close;\n};\n\n/**Opens a stream with <code>fopen()</code> and fills in a set of callbacks\n    that can be used to access it.\n   This is useful to avoid writing your own portable 64-bit seeking wrappers,\n    and also avoids cross-module linking issues on Windows, where a\n    <code>FILE *</code> must be accessed by routines defined in the same module\n    that opened it.\n   \\param[out] _cb   The callbacks to use for this file.\n                     If there is an error opening the file, nothing will be\n                      filled in here.\n   \\param      _path The path to the file to open.\n                     On Windows, this string must be UTF-8 (to allow access to\n                      files whose names cannot be represented in the current\n                      MBCS code page).\n                     All other systems use the native character encoding.\n   \\param      _mode The mode to open the file in.\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_fopen(OpusFileCallbacks *_cb,\n const char *_path,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2)\n OP_ARG_NONNULL(3);\n\n/**Opens a stream with <code>fdopen()</code> and fills in a set of callbacks\n    that can be used to access it.\n   This is useful to avoid writing your own portable 64-bit seeking wrappers,\n    and also avoids cross-module linking issues on Windows, where a\n    <code>FILE *</code> must be accessed by routines defined in the same module\n    that opened it.\n   \\param[out] _cb   The callbacks to use for this file.\n                     If there is an error opening the file, nothing will be\n                      filled in here.\n   \\param      _fd   The file descriptor to open.\n   \\param      _mode The mode to open the file in.\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_fdopen(OpusFileCallbacks *_cb,\n int _fd,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(3);\n\n/**Opens a stream with <code>freopen()</code> and fills in a set of callbacks\n    that can be used to access it.\n   This is useful to avoid writing your own portable 64-bit seeking wrappers,\n    and also avoids cross-module linking issues on Windows, where a\n    <code>FILE *</code> must be accessed by routines defined in the same module\n    that opened it.\n   \\param[out] _cb     The callbacks to use for this file.\n                       If there is an error opening the file, nothing will be\n                        filled in here.\n   \\param      _path   The path to the file to open.\n                       On Windows, this string must be UTF-8 (to allow access\n                        to files whose names cannot be represented in the\n                        current MBCS code page).\n                       All other systems use the native character encoding.\n   \\param      _mode   The mode to open the file in.\n   \\param      _stream A stream previously returned by op_fopen(), op_fdopen(),\n                        or op_freopen().\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_freopen(OpusFileCallbacks *_cb,\n const char *_path,const char *_mode,void *_stream) OP_ARG_NONNULL(1)\n OP_ARG_NONNULL(2) OP_ARG_NONNULL(3) OP_ARG_NONNULL(4);\n\n/**Creates a stream that reads from the given block of memory.\n   This block of memory must contain the complete stream to decode.\n   This is useful for caching small streams (e.g., sound effects) in RAM.\n   \\param[out] _cb   The callbacks to use for this stream.\n                     If there is an error creating the stream, nothing will be\n                      filled in here.\n   \\param      _data The block of memory to read from.\n   \\param      _size The size of the block of memory.\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_mem_stream_create(OpusFileCallbacks *_cb,\n const unsigned char *_data,size_t _size) OP_ARG_NONNULL(1);\n\n/**Creates a stream that reads from the given URL.\n   This function behaves identically to op_url_stream_create(), except that it\n    takes a va_list instead of a variable number of arguments.\n   It does not call the <code>va_end</code> macro, and because it invokes the\n    <code>va_arg</code> macro, the value of \\a _ap is undefined after the call.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\param[out]    _cb  The callbacks to use for this stream.\n                       If there is an error creating the stream, nothing will\n                        be filled in here.\n   \\param         _url The URL to read from.\n                       Currently only the <file:>, <http:>, and <https:>\n                        schemes are supported.\n                       Both <http:> and <https:> may be disabled at compile\n                        time, in which case opening such URLs will always fail.\n                       Currently this only supports URIs.\n                       IRIs should be converted to UTF-8 and URL-escaped, with\n                        internationalized domain names encoded in punycode,\n                        before passing them to this function.\n   \\param[in,out] _ap  A list of the \\ref url_options \"optional flags\" to use.\n                       This is a variable-length list of options terminated\n                        with <code>NULL</code>.\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_url_stream_vcreate(OpusFileCallbacks *_cb,\n const char *_url,va_list _ap) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/**Creates a stream that reads from the given URL.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\param[out] _cb  The callbacks to use for this stream.\n                    If there is an error creating the stream, nothing will be\n                     filled in here.\n   \\param      _url The URL to read from.\n                    Currently only the <file:>, <http:>, and <https:> schemes\n                     are supported.\n                    Both <http:> and <https:> may be disabled at compile time,\n                     in which case opening such URLs will always fail.\n                    Currently this only supports URIs.\n                    IRIs should be converted to UTF-8 and URL-escaped, with\n                     internationalized domain names encoded in punycode, before\n                     passing them to this function.\n   \\param      ...  The \\ref url_options \"optional flags\" to use.\n                    This is a variable-length list of options terminated with\n                     <code>NULL</code>.\n   \\return A stream handle to use with the callbacks, or <code>NULL</code> on\n            error.*/\nOP_WARN_UNUSED_RESULT void *op_url_stream_create(OpusFileCallbacks *_cb,\n const char *_url,...) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup stream_open_close Opening and Closing*/\n/*@{*/\n/**\\name Functions for opening and closing streams\n\n   These functions allow you to test a stream to see if it is Opus, open it,\n    and close it.\n   Several flavors are provided for each of the built-in stream types, plus a\n    more general version which takes a set of application-provided callbacks.*/\n/*@{*/\n\n/**Test to see if this is an Opus stream.\n   For good results, you will need at least 57 bytes (for a pure Opus-only\n    stream).\n   Something like 512 bytes will give more reliable results for multiplexed\n    streams.\n   This function is meant to be a quick-rejection filter.\n   Its purpose is not to guarantee that a stream is a valid Opus stream, but to\n    ensure that it looks enough like Opus that it isn't going to be recognized\n    as some other format (except possibly an Opus stream that is also\n    multiplexed with other codecs, such as video).\n   \\param[out] _head     The parsed ID header contents.\n                         You may pass <code>NULL</code> if you do not need\n                          this information.\n                         If the function fails, the contents of this structure\n                          remain untouched.\n   \\param _initial_data  An initial buffer of data from the start of the\n                          stream.\n   \\param _initial_bytes The number of bytes in \\a _initial_data.\n   \\return 0 if the data appears to be Opus, or a negative value on error.\n   \\retval #OP_FALSE      There was not enough data to tell if this was an Opus\n                           stream or not.\n   \\retval #OP_EFAULT     An internal memory allocation failed.\n   \\retval #OP_EIMPL      The stream used a feature that is not implemented,\n                           such as an unsupported channel family.\n   \\retval #OP_ENOTFORMAT If the data did not contain a recognizable ID\n                           header for an Opus stream.\n   \\retval #OP_EVERSION   If the version field signaled a version this library\n                           does not know how to parse.\n   \\retval #OP_EBADHEADER The ID header was not properly formatted or contained\n                           illegal values.*/\nint op_test(OpusHead *_head,\n const unsigned char *_initial_data,size_t _initial_bytes);\n\n/**Open a stream from the given file path.\n   \\param      _path  The path to the file to open.\n   \\param[out] _error Returns 0 on success, or a failure code on error.\n                      You may pass in <code>NULL</code> if you don't want the\n                       failure code.\n                      The failure code will be #OP_EFAULT if the file could not\n                       be opened, or one of the other failure codes from\n                       op_open_callbacks() otherwise.\n   \\return A freshly opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_open_file(const char *_path,int *_error)\n OP_ARG_NONNULL(1);\n\n/**Open a stream from a memory buffer.\n   \\param      _data  The memory buffer to open.\n   \\param      _size  The number of bytes in the buffer.\n   \\param[out] _error Returns 0 on success, or a failure code on error.\n                      You may pass in <code>NULL</code> if you don't want the\n                       failure code.\n                      See op_open_callbacks() for a full list of failure codes.\n   \\return A freshly opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_open_memory(const unsigned char *_data,\n size_t _size,int *_error);\n\n/**Open a stream from a URL.\n   This function behaves identically to op_open_url(), except that it\n    takes a va_list instead of a variable number of arguments.\n   It does not call the <code>va_end</code> macro, and because it invokes the\n    <code>va_arg</code> macro, the value of \\a _ap is undefined after the call.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\param         _url   The URL to open.\n                         Currently only the <file:>, <http:>, and <https:>\n                          schemes are supported.\n                         Both <http:> and <https:> may be disabled at compile\n                          time, in which case opening such URLs will always\n                          fail.\n                         Currently this only supports URIs.\n                         IRIs should be converted to UTF-8 and URL-escaped,\n                          with internationalized domain names encoded in\n                          punycode, before passing them to this function.\n   \\param[out]    _error Returns 0 on success, or a failure code on error.\n                         You may pass in <code>NULL</code> if you don't want\n                          the failure code.\n                         See op_open_callbacks() for a full list of failure\n                          codes.\n   \\param[in,out] _ap    A list of the \\ref url_options \"optional flags\" to\n                          use.\n                         This is a variable-length list of options terminated\n                          with <code>NULL</code>.\n   \\return A freshly opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_vopen_url(const char *_url,\n int *_error,va_list _ap) OP_ARG_NONNULL(1);\n\n/**Open a stream from a URL.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\param      _url   The URL to open.\n                      Currently only the <file:>, <http:>, and <https:> schemes\n                       are supported.\n                      Both <http:> and <https:> may be disabled at compile\n                       time, in which case opening such URLs will always fail.\n                      Currently this only supports URIs.\n                      IRIs should be converted to UTF-8 and URL-escaped, with\n                       internationalized domain names encoded in punycode,\n                       before passing them to this function.\n   \\param[out] _error Returns 0 on success, or a failure code on error.\n                      You may pass in <code>NULL</code> if you don't want the\n                       failure code.\n                      See op_open_callbacks() for a full list of failure codes.\n   \\param      ...    The \\ref url_options \"optional flags\" to use.\n                      This is a variable-length list of options terminated with\n                       <code>NULL</code>.\n   \\return A freshly opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,\n int *_error,...) OP_ARG_NONNULL(1);\n\n/**Open a stream using the given set of callbacks to access it.\n   \\param _stream        The stream to read from (e.g., a <code>FILE *</code>).\n                         This value will be passed verbatim as the first\n                          argument to all of the callbacks.\n   \\param _cb            The callbacks with which to access the stream.\n                         <code><a href=\"#op_read_func\">read()</a></code> must\n                          be implemented.\n                         <code><a href=\"#op_seek_func\">seek()</a></code> and\n                          <code><a href=\"#op_tell_func\">tell()</a></code> may\n                          be <code>NULL</code>, or may always return -1 to\n                          indicate a stream is unseekable, but if\n                          <code><a href=\"#op_seek_func\">seek()</a></code> is\n                          implemented and succeeds on a particular stream, then\n                          <code><a href=\"#op_tell_func\">tell()</a></code> must\n                          also.\n                         <code><a href=\"#op_close_func\">close()</a></code> may\n                          be <code>NULL</code>, but if it is not, it will be\n                          called when the \\c OggOpusFile is destroyed by\n                          op_free().\n                         It will not be called if op_open_callbacks() fails\n                          with an error.\n   \\param _initial_data  An initial buffer of data from the start of the\n                          stream.\n                         Applications can read some number of bytes from the\n                          start of the stream to help identify this as an Opus\n                          stream, and then provide them here to allow the\n                          stream to be opened, even if it is unseekable.\n   \\param _initial_bytes The number of bytes in \\a _initial_data.\n                         If the stream is seekable, its current position (as\n                          reported by\n                          <code><a href=\"#opus_tell_func\">tell()</a></code>\n                          at the start of this function) must be equal to\n                          \\a _initial_bytes.\n                         Otherwise, seeking to absolute positions will\n                          generate inconsistent results.\n   \\param[out] _error    Returns 0 on success, or a failure code on error.\n                         You may pass in <code>NULL</code> if you don't want\n                          the failure code.\n                         The failure code will be one of\n                         <dl>\n                           <dt>#OP_EREAD</dt>\n                           <dd>An underlying read, seek, or tell operation\n                            failed when it should have succeeded, or we failed\n                            to find data in the stream we had seen before.</dd>\n                           <dt>#OP_EFAULT</dt>\n                           <dd>There was a memory allocation failure, or an\n                            internal library error.</dd>\n                           <dt>#OP_EIMPL</dt>\n                           <dd>The stream used a feature that is not\n                            implemented, such as an unsupported channel\n                            family.</dd>\n                           <dt>#OP_EINVAL</dt>\n                           <dd><code><a href=\"#op_seek_func\">seek()</a></code>\n                            was implemented and succeeded on this source, but\n                            <code><a href=\"#op_tell_func\">tell()</a></code>\n                            did not, or the starting position indicator was\n                            not equal to \\a _initial_bytes.</dd>\n                           <dt>#OP_ENOTFORMAT</dt>\n                           <dd>The stream contained a link that did not have\n                            any logical Opus streams in it.</dd>\n                           <dt>#OP_EBADHEADER</dt>\n                           <dd>A required header packet was not properly\n                            formatted, contained illegal values, or was missing\n                            altogether.</dd>\n                           <dt>#OP_EVERSION</dt>\n                           <dd>An ID header contained an unrecognized version\n                            number.</dd>\n                           <dt>#OP_EBADLINK</dt>\n                           <dd>We failed to find data we had seen before after\n                            seeking.</dd>\n                           <dt>#OP_EBADTIMESTAMP</dt>\n                           <dd>The first or last timestamp in a link failed\n                            basic validity checks.</dd>\n                         </dl>\n   \\return A freshly opened \\c OggOpusFile, or <code>NULL</code> on error.\n           <tt>libopusfile</tt> does <em>not</em> take ownership of the stream\n            if the call fails.\n           The calling application is responsible for closing the stream if\n            this call returns an error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_stream,\n const OpusFileCallbacks *_cb,const unsigned char *_initial_data,\n size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2);\n\n/**Partially open a stream from the given file path.\n   \\see op_test_callbacks\n   \\param      _path  The path to the file to open.\n   \\param[out] _error Returns 0 on success, or a failure code on error.\n                      You may pass in <code>NULL</code> if you don't want the\n                       failure code.\n                      The failure code will be #OP_EFAULT if the file could not\n                       be opened, or one of the other failure codes from\n                       op_open_callbacks() otherwise.\n   \\return A partially opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_test_file(const char *_path,int *_error)\n OP_ARG_NONNULL(1);\n\n/**Partially open a stream from a memory buffer.\n   \\see op_test_callbacks\n   \\param      _data  The memory buffer to open.\n   \\param      _size  The number of bytes in the buffer.\n   \\param[out] _error Returns 0 on success, or a failure code on error.\n                      You may pass in <code>NULL</code> if you don't want the\n                       failure code.\n                      See op_open_callbacks() for a full list of failure codes.\n   \\return A partially opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_test_memory(const unsigned char *_data,\n size_t _size,int *_error);\n\n/**Partially open a stream from a URL.\n   This function behaves identically to op_test_url(), except that it\n    takes a va_list instead of a variable number of arguments.\n   It does not call the <code>va_end</code> macro, and because it invokes the\n    <code>va_arg</code> macro, the value of \\a _ap is undefined after the call.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\see op_test_url\n   \\see op_test_callbacks\n   \\param         _url    The URL to open.\n                          Currently only the <file:>, <http:>, and <https:>\n                           schemes are supported.\n                          Both <http:> and <https:> may be disabled at compile\n                           time, in which case opening such URLs will always\n                           fail.\n                          Currently this only supports URIs.\n                          IRIs should be converted to UTF-8 and URL-escaped,\n                           with internationalized domain names encoded in\n                           punycode, before passing them to this function.\n   \\param[out]    _error  Returns 0 on success, or a failure code on error.\n                          You may pass in <code>NULL</code> if you don't want\n                           the failure code.\n                          See op_open_callbacks() for a full list of failure\n                           codes.\n   \\param[in,out] _ap     A list of the \\ref url_options \"optional flags\" to\n                           use.\n                          This is a variable-length list of options terminated\n                           with <code>NULL</code>.\n   \\return A partially opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_vtest_url(const char *_url,\n int *_error,va_list _ap) OP_ARG_NONNULL(1);\n\n/**Partially open a stream from a URL.\n   \\note If you use this function, you must link against <tt>libopusurl</tt>.\n   \\see op_test_callbacks\n   \\param      _url    The URL to open.\n                       Currently only the <file:>, <http:>, and <https:>\n                        schemes are supported.\n                       Both <http:> and <https:> may be disabled at compile\n                        time, in which case opening such URLs will always fail.\n                       Currently this only supports URIs.\n                       IRIs should be converted to UTF-8 and URL-escaped, with\n                        internationalized domain names encoded in punycode,\n                        before passing them to this function.\n   \\param[out] _error  Returns 0 on success, or a failure code on error.\n                       You may pass in <code>NULL</code> if you don't want the\n                        failure code.\n                       See op_open_callbacks() for a full list of failure\n                        codes.\n   \\param      ...     The \\ref url_options \"optional flags\" to use.\n                       This is a variable-length list of options terminated\n                        with <code>NULL</code>.\n   \\return A partially opened \\c OggOpusFile, or <code>NULL</code> on error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url,\n int *_error,...) OP_ARG_NONNULL(1);\n\n/**Partially open a stream using the given set of callbacks to access it.\n   This tests for Opusness and loads the headers for the first link.\n   It does not seek (although it tests for seekability).\n   You can query a partially open stream for the few pieces of basic\n    information returned by op_serialno(), op_channel_count(), op_head(), and\n    op_tags() (but only for the first link).\n   You may also determine if it is seekable via a call to op_seekable().\n   You cannot read audio from the stream, seek, get the size or duration,\n    get information from links other than the first one, or even get the total\n    number of links until you finish opening the stream with op_test_open().\n   If you do not need to do any of these things, you can dispose of it with\n    op_free() instead.\n\n   This function is provided mostly to simplify porting existing code that used\n    <tt>libvorbisfile</tt>.\n   For new code, you are likely better off using op_test() instead, which\n    is less resource-intensive, requires less data to succeed, and imposes a\n    hard limit on the amount of data it examines (important for unseekable\n    streams, where all such data must be buffered until you are sure of the\n    stream type).\n   \\param _stream        The stream to read from (e.g., a <code>FILE *</code>).\n                         This value will be passed verbatim as the first\n                          argument to all of the callbacks.\n   \\param _cb            The callbacks with which to access the stream.\n                         <code><a href=\"#op_read_func\">read()</a></code> must\n                          be implemented.\n                         <code><a href=\"#op_seek_func\">seek()</a></code> and\n                          <code><a href=\"#op_tell_func\">tell()</a></code> may\n                          be <code>NULL</code>, or may always return -1 to\n                          indicate a stream is unseekable, but if\n                          <code><a href=\"#op_seek_func\">seek()</a></code> is\n                          implemented and succeeds on a particular stream, then\n                          <code><a href=\"#op_tell_func\">tell()</a></code> must\n                          also.\n                         <code><a href=\"#op_close_func\">close()</a></code> may\n                          be <code>NULL</code>, but if it is not, it will be\n                          called when the \\c OggOpusFile is destroyed by\n                          op_free().\n                         It will not be called if op_open_callbacks() fails\n                          with an error.\n   \\param _initial_data  An initial buffer of data from the start of the\n                          stream.\n                         Applications can read some number of bytes from the\n                          start of the stream to help identify this as an Opus\n                          stream, and then provide them here to allow the\n                          stream to be tested more thoroughly, even if it is\n                          unseekable.\n   \\param _initial_bytes The number of bytes in \\a _initial_data.\n                         If the stream is seekable, its current position (as\n                          reported by\n                          <code><a href=\"#opus_tell_func\">tell()</a></code>\n                          at the start of this function) must be equal to\n                          \\a _initial_bytes.\n                         Otherwise, seeking to absolute positions will\n                          generate inconsistent results.\n   \\param[out] _error    Returns 0 on success, or a failure code on error.\n                         You may pass in <code>NULL</code> if you don't want\n                          the failure code.\n                         See op_open_callbacks() for a full list of failure\n                          codes.\n   \\return A partially opened \\c OggOpusFile, or <code>NULL</code> on error.\n           <tt>libopusfile</tt> does <em>not</em> take ownership of the stream\n            if the call fails.\n           The calling application is responsible for closing the stream if\n            this call returns an error.*/\nOP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_stream,\n const OpusFileCallbacks *_cb,const unsigned char *_initial_data,\n size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2);\n\n/**Finish opening a stream partially opened with op_test_callbacks() or one of\n    the associated convenience functions.\n   If this function fails, you are still responsible for freeing the\n    \\c OggOpusFile with op_free().\n   \\param _of The \\c OggOpusFile to finish opening.\n   \\return 0 on success, or a negative value on error.\n   \\retval #OP_EREAD         An underlying read, seek, or tell operation failed\n                              when it should have succeeded.\n   \\retval #OP_EFAULT        There was a memory allocation failure, or an\n                              internal library error.\n   \\retval #OP_EIMPL         The stream used a feature that is not implemented,\n                              such as an unsupported channel family.\n   \\retval #OP_EINVAL        The stream was not partially opened with\n                              op_test_callbacks() or one of the associated\n                              convenience functions.\n   \\retval #OP_ENOTFORMAT    The stream contained a link that did not have any\n                              logical Opus streams in it.\n   \\retval #OP_EBADHEADER    A required header packet was not properly\n                              formatted, contained illegal values, or was\n                              missing altogether.\n   \\retval #OP_EVERSION      An ID header contained an unrecognized version\n                              number.\n   \\retval #OP_EBADLINK      We failed to find data we had seen before after\n                              seeking.\n   \\retval #OP_EBADTIMESTAMP The first or last timestamp in a link failed basic\n                              validity checks.*/\nint op_test_open(OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Release all memory used by an \\c OggOpusFile.\n   \\param _of The \\c OggOpusFile to free.*/\nvoid op_free(OggOpusFile *_of);\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup stream_info Stream Information*/\n/*@{*/\n/**\\name Functions for obtaining information about streams\n\n   These functions allow you to get basic information about a stream, including\n    seekability, the number of links (for chained streams), plus the size,\n    duration, bitrate, header parameters, and meta information for each link\n    (or, where available, the stream as a whole).\n   Some of these (size, duration) are only available for seekable streams.\n   You can also query the current stream position, link, and playback time,\n    and instantaneous bitrate during playback.\n\n   Some of these functions may be used successfully on the partially open\n    streams returned by op_test_callbacks() or one of the associated\n    convenience functions.\n   Their documention will indicate so explicitly.*/\n/*@{*/\n\n/**Returns whether or not the stream being read is seekable.\n   This is true if\n   <ol>\n   <li>The <code><a href=\"#op_seek_func\">seek()</a></code> and\n    <code><a href=\"#op_tell_func\">tell()</a></code> callbacks are both\n    non-<code>NULL</code>,</li>\n   <li>The <code><a href=\"#op_seek_func\">seek()</a></code> callback was\n    successfully executed at least once, and</li>\n   <li>The <code><a href=\"#op_tell_func\">tell()</a></code> callback was\n    successfully able to report the position indicator afterwards.</li>\n   </ol>\n   This function may be called on partially-opened streams.\n   \\param _of The \\c OggOpusFile whose seekable status is to be returned.\n   \\return A non-zero value if seekable, and 0 if unseekable.*/\nint op_seekable(const OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Returns the number of links in this chained stream.\n   This function may be called on partially-opened streams, but it will always\n    return 1.\n   The actual number of links is not known until the stream is fully opened.\n   \\param _of The \\c OggOpusFile from which to retrieve the link count.\n   \\return For fully-open seekable streams, this returns the total number of\n            links in the whole stream, which will be at least 1.\n           For partially-open or unseekable streams, this always returns 1.*/\nint op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Get the serial number of the given link in a (possibly-chained) Ogg Opus\n    stream.\n   This function may be called on partially-opened streams, but it will always\n    return the serial number of the Opus stream in the first link.\n   \\param _of The \\c OggOpusFile from which to retrieve the serial number.\n   \\param _li The index of the link whose serial number should be retrieved.\n              Use a negative number to get the serial number of the current\n               link.\n   \\return The serial number of the given link.\n           If \\a _li is greater than the total number of links, this returns\n            the serial number of the last link.\n           If the stream is not seekable, this always returns the serial number\n            of the current link.*/\nopus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Get the channel count of the given link in a (possibly-chained) Ogg Opus\n    stream.\n   This is equivalent to <code>op_head(_of,_li)->channel_count</code>, but\n    is provided for convenience.\n   This function may be called on partially-opened streams, but it will always\n    return the channel count of the Opus stream in the first link.\n   \\param _of The \\c OggOpusFile from which to retrieve the channel count.\n   \\param _li The index of the link whose channel count should be retrieved.\n              Use a negative number to get the channel count of the current\n               link.\n   \\return The channel count of the given link.\n           If \\a _li is greater than the total number of links, this returns\n            the channel count of the last link.\n           If the stream is not seekable, this always returns the channel count\n            of the current link.*/\nint op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Get the total (compressed) size of the stream, or of an individual link in\n    a (possibly-chained) Ogg Opus stream, including all headers and Ogg muxing\n    overhead.\n   \\warning If the Opus stream (or link) is concurrently multiplexed with other\n    logical streams (e.g., video), this returns the size of the entire stream\n    (or link), not just the number of bytes in the first logical Opus stream.\n   Returning the latter would require scanning the entire file.\n   \\param _of The \\c OggOpusFile from which to retrieve the compressed size.\n   \\param _li The index of the link whose compressed size should be computed.\n              Use a negative number to get the compressed size of the entire\n               stream.\n   \\return The compressed size of the entire stream if \\a _li is negative, the\n            compressed size of link \\a _li if it is non-negative, or a negative\n            value on error.\n           The compressed size of the entire stream may be smaller than that\n            of the underlying stream if trailing garbage was detected in the\n            file.\n   \\retval #OP_EINVAL The stream is not seekable (so we can't know the length),\n                       \\a _li wasn't less than the total number of links in\n                       the stream, or the stream was only partially open.*/\nopus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Get the total PCM length (number of samples at 48 kHz) of the stream, or of\n    an individual link in a (possibly-chained) Ogg Opus stream.\n   Users looking for <code>op_time_total()</code> should use op_pcm_total()\n    instead.\n   Because timestamps in Opus are fixed at 48 kHz, there is no need for a\n    separate function to convert this to seconds (and leaving it out avoids\n    introducing floating point to the API, for those that wish to avoid it).\n   \\param _of The \\c OggOpusFile from which to retrieve the PCM offset.\n   \\param _li The index of the link whose PCM length should be computed.\n              Use a negative number to get the PCM length of the entire stream.\n   \\return The PCM length of the entire stream if \\a _li is negative, the PCM\n            length of link \\a _li if it is non-negative, or a negative value on\n            error.\n   \\retval #OP_EINVAL The stream is not seekable (so we can't know the length),\n                       \\a _li wasn't less than the total number of links in\n                       the stream, or the stream was only partially open.*/\nogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Get the ID header information for the given link in a (possibly chained) Ogg\n    Opus stream.\n   This function may be called on partially-opened streams, but it will always\n    return the ID header information of the Opus stream in the first link.\n   \\param _of The \\c OggOpusFile from which to retrieve the ID header\n               information.\n   \\param _li The index of the link whose ID header information should be\n               retrieved.\n              Use a negative number to get the ID header information of the\n               current link.\n              For an unseekable stream, \\a _li is ignored, and the ID header\n               information for the current link is always returned, if\n               available.\n   \\return The contents of the ID header for the given link.*/\nconst OpusHead *op_head(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Get the comment header information for the given link in a (possibly\n    chained) Ogg Opus stream.\n   This function may be called on partially-opened streams, but it will always\n    return the tags from the Opus stream in the first link.\n   \\param _of The \\c OggOpusFile from which to retrieve the comment header\n               information.\n   \\param _li The index of the link whose comment header information should be\n               retrieved.\n              Use a negative number to get the comment header information of\n               the current link.\n              For an unseekable stream, \\a _li is ignored, and the comment\n               header information for the current link is always returned, if\n               available.\n   \\return The contents of the comment header for the given link, or\n            <code>NULL</code> if this is an unseekable stream that encountered\n            an invalid link.*/\nconst OpusTags *op_tags(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Retrieve the index of the current link.\n   This is the link that produced the data most recently read by\n    op_read_float() or its associated functions, or, after a seek, the link\n    that the seek target landed in.\n   Reading more data may advance the link index (even on the first read after a\n    seek).\n   \\param _of The \\c OggOpusFile from which to retrieve the current link index.\n   \\return The index of the current link on success, or a negative value on\n            failure.\n           For seekable streams, this is a number between 0 (inclusive) and the\n            value returned by op_link_count() (exclusive).\n           For unseekable streams, this value starts at 0 and increments by one\n            each time a new link is encountered (even though op_link_count()\n            always returns 1).\n   \\retval #OP_EINVAL The stream was only partially open.*/\nint op_current_link(const OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Computes the bitrate of the stream, or of an individual link in a\n    (possibly-chained) Ogg Opus stream.\n   The stream must be seekable to compute the bitrate.\n   For unseekable streams, use op_bitrate_instant() to get periodic estimates.\n   \\warning If the Opus stream (or link) is concurrently multiplexed with other\n    logical streams (e.g., video), this uses the size of the entire stream (or\n    link) to compute the bitrate, not just the number of bytes in the first\n    logical Opus stream.\n   Returning the latter requires scanning the entire file, but this may be done\n    by decoding the whole file and calling op_bitrate_instant() once at the\n    end.\n   Install a trivial decoding callback with op_set_decode_callback() if you\n    wish to skip actual decoding during this process.\n   \\param _of The \\c OggOpusFile from which to retrieve the bitrate.\n   \\param _li The index of the link whose bitrate should be computed.\n              Use a negative number to get the bitrate of the whole stream.\n   \\return The bitrate on success, or a negative value on error.\n   \\retval #OP_EINVAL The stream was only partially open, the stream was not\n                       seekable, or \\a _li was larger than the number of\n                       links.*/\nopus_int32 op_bitrate(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);\n\n/**Compute the instantaneous bitrate, measured as the ratio of bits to playable\n    samples decoded since a) the last call to op_bitrate_instant(), b) the last\n    seek, or c) the start of playback, whichever was most recent.\n   This will spike somewhat after a seek or at the start/end of a chain\n    boundary, as pre-skip, pre-roll, and end-trimming causes samples to be\n    decoded but not played.\n   \\param _of The \\c OggOpusFile from which to retrieve the bitrate.\n   \\return The bitrate, in bits per second, or a negative value on error.\n   \\retval #OP_FALSE  No data has been decoded since any of the events\n                       described above.\n   \\retval #OP_EINVAL The stream was only partially open.*/\nopus_int32 op_bitrate_instant(OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Obtain the current value of the position indicator for \\a _of.\n   \\param _of The \\c OggOpusFile from which to retrieve the position indicator.\n   \\return The byte position that is currently being read from.\n   \\retval #OP_EINVAL The stream was only partially open.*/\nopus_int64 op_raw_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/**Obtain the PCM offset of the next sample to be read.\n   If the stream is not properly timestamped, this might not increment by the\n    proper amount between reads, or even return monotonically increasing\n    values.\n   \\param _of The \\c OggOpusFile from which to retrieve the PCM offset.\n   \\return The PCM offset of the next sample to be read.\n   \\retval #OP_EINVAL The stream was only partially open.*/\nogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup stream_seeking Seeking*/\n/*@{*/\n/**\\name Functions for seeking in Opus streams\n\n   These functions let you seek in Opus streams, if the underlying stream\n    support it.\n   Seeking is implemented for all built-in stream I/O routines, though some\n    individual streams may not be seekable (pipes, live HTTP streams, or HTTP\n    streams from a server that does not support <code>Range</code> requests).\n\n   op_raw_seek() is the fastest: it is guaranteed to perform at most one\n    physical seek, but, since the target is a byte position, makes no guarantee\n    how close to a given time it will come.\n   op_pcm_seek() provides sample-accurate seeking.\n   The number of physical seeks it requires is still quite small (often 1 or\n    2, even in highly variable bitrate streams).\n\n   Seeking in Opus requires decoding some pre-roll amount before playback to\n    allow the internal state to converge (as if recovering from packet loss).\n   This is handled internally by <tt>libopusfile</tt>, but means there is\n    little extra overhead for decoding up to the exact position requested\n    (since it must decode some amount of audio anyway).\n   It also means that decoding after seeking may not return exactly the same\n    values as would be obtained by decoding the stream straight through.\n   However, such differences are expected to be smaller than the loss\n    introduced by Opus's lossy compression.*/\n/*@{*/\n\n/**Seek to a byte offset relative to the <b>compressed</b> data.\n   This also scans packets to update the PCM cursor.\n   It will cross a logical bitstream boundary, but only if it can't get any\n    packets out of the tail of the link to which it seeks.\n   \\param _of          The \\c OggOpusFile in which to seek.\n   \\param _byte_offset The byte position to seek to.\n                       This must be between 0 and #op_raw_total(\\a _of,\\c -1)\n                        (inclusive).\n   \\return 0 on success, or a negative error code on failure.\n   \\retval #OP_EREAD    The underlying seek operation failed.\n   \\retval #OP_EINVAL   The stream was only partially open, or the target was\n                         outside the valid range for the stream.\n   \\retval #OP_ENOSEEK  This stream is not seekable.\n   \\retval #OP_EBADLINK Failed to initialize a decoder for a stream for an\n                         unknown reason.*/\nint op_raw_seek(OggOpusFile *_of,opus_int64 _byte_offset) OP_ARG_NONNULL(1);\n\n/**Seek to the specified PCM offset, such that decoding will begin at exactly\n    the requested position.\n   \\param _of         The \\c OggOpusFile in which to seek.\n   \\param _pcm_offset The PCM offset to seek to.\n                      This is in samples at 48 kHz relative to the start of the\n                       stream.\n   \\return 0 on success, or a negative value on error.\n   \\retval #OP_EREAD    An underlying read or seek operation failed.\n   \\retval #OP_EINVAL   The stream was only partially open, or the target was\n                         outside the valid range for the stream.\n   \\retval #OP_ENOSEEK  This stream is not seekable.\n   \\retval #OP_EBADLINK We failed to find data we had seen before, or the\n                         bitstream structure was sufficiently malformed that\n                         seeking to the target destination was impossible.*/\nint op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1);\n\n/*@}*/\n/*@}*/\n\n/**\\defgroup stream_decoding Decoding*/\n/*@{*/\n/**\\name Functions for decoding audio data\n\n   These functions retrieve actual decoded audio data from the stream.\n   The general functions, op_read() and op_read_float() return 16-bit or\n    floating-point output, both using native endian ordering.\n   The number of channels returned can change from link to link in a chained\n    stream.\n   There are special functions, op_read_stereo() and op_read_float_stereo(),\n    which always output two channels, to simplify applications which do not\n    wish to handle multichannel audio.\n   These downmix multichannel files to two channels, so they can always return\n    samples in the same format for every link in a chained file.\n\n   If the rest of your audio processing chain can handle floating point, the\n    floating-point routines should be preferred, as they prevent clipping and\n    other issues which might be avoided entirely if, e.g., you scale down the\n    volume at some other stage.\n   However, if you intend to consume 16-bit samples directly, the conversion in\n    <tt>libopusfile</tt> provides noise-shaping dithering and, if compiled\n    against <tt>libopus</tt>&nbsp;1.1 or later, soft-clipping prevention.\n\n   <tt>libopusfile</tt> can also be configured at compile time to use the\n    fixed-point <tt>libopus</tt> API.\n   If so, <tt>libopusfile</tt>'s floating-point API may also be disabled.\n   In that configuration, nothing in <tt>libopusfile</tt> will use any\n    floating-point operations, to simplify support on devices without an\n    adequate FPU.\n\n   \\warning HTTPS streams may be be vulnerable to truncation attacks if you do\n    not check the error return code from op_read_float() or its associated\n    functions.\n   If the remote peer does not close the connection gracefully (with a TLS\n    \"close notify\" message), these functions will return #OP_EREAD instead of 0\n    when they reach the end of the file.\n   If you are reading from an <https:> URL (particularly if seeking is not\n    supported), you should make sure to check for this error and warn the user\n    appropriately.*/\n/*@{*/\n\n/**Indicates that the decoding callback should produce signed 16-bit\n    native-endian output samples.*/\n#define OP_DEC_FORMAT_SHORT (7008)\n/**Indicates that the decoding callback should produce 32-bit native-endian\n    float samples.*/\n#define OP_DEC_FORMAT_FLOAT (7040)\n\n/**Indicates that the decoding callback did not decode anything, and that\n    <tt>libopusfile</tt> should decode normally instead.*/\n#define OP_DEC_USE_DEFAULT  (6720)\n\n/**Called to decode an Opus packet.\n   This should invoke the functional equivalent of opus_multistream_decode() or\n    opus_multistream_decode_float(), except that it returns 0 on success\n    instead of the number of decoded samples (which is known a priori).\n   \\param _ctx       The application-provided callback context.\n   \\param _decoder   The decoder to use to decode the packet.\n   \\param[out] _pcm  The buffer to decode into.\n                     This will always have enough room for \\a _nchannels of\n                      \\a _nsamples samples, which should be placed into this\n                      buffer interleaved.\n   \\param _op        The packet to decode.\n                     This will always have its granule position set to a valid\n                      value.\n   \\param _nsamples  The number of samples expected from the packet.\n   \\param _nchannels The number of channels expected from the packet.\n   \\param _format    The desired sample output format.\n                     This is either #OP_DEC_FORMAT_SHORT or\n                      #OP_DEC_FORMAT_FLOAT.\n   \\param _li        The index of the link from which this packet was decoded.\n   \\return A non-negative value on success, or a negative value on error.\n           Any error codes should be the same as those returned by\n            opus_multistream_decode() or opus_multistream_decode_float().\n           Success codes are as follows:\n   \\retval 0                   Decoding was successful.\n                               The application has filled the buffer with\n                                exactly <code>\\a _nsamples*\\a\n                                _nchannels</code> samples in the requested\n                                format.\n   \\retval #OP_DEC_USE_DEFAULT No decoding was done.\n                               <tt>libopusfile</tt> should do the decoding\n                                by itself instead.*/\ntypedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm,\n const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li);\n\n/**Sets the packet decode callback function.\n   If set, this is called once for each packet that needs to be decoded.\n   This can be used by advanced applications to do additional processing on the\n    compressed or uncompressed data.\n   For example, an application might save the final entropy coder state for\n    debugging and testing purposes, or it might apply additional filters\n    before the downmixing, dithering, or soft-clipping performed by\n    <tt>libopusfile</tt>, so long as these filters do not introduce any\n    latency.\n\n   A call to this function is no guarantee that the audio will eventually be\n    delivered to the application.\n   <tt>libopusfile</tt> may discard some or all of the decoded audio data\n    (i.e., at the beginning or end of a link, or after a seek), however the\n    callback is still required to provide all of it.\n   \\param _of        The \\c OggOpusFile on which to set the decode callback.\n   \\param _decode_cb The callback function to call.\n                     This may be <code>NULL</code> to disable calling the\n                      callback.\n   \\param _ctx       The application-provided context pointer to pass to the\n                      callback on each call.*/\nvoid op_set_decode_callback(OggOpusFile *_of,\n op_decode_cb_func _decode_cb,void *_ctx) OP_ARG_NONNULL(1);\n\n/**Gain offset type that indicates that the provided offset is relative to the\n    header gain.\n   This is the default.*/\n#define OP_HEADER_GAIN   (0)\n\n/**Gain offset type that indicates that the provided offset is relative to the\n    R128_ALBUM_GAIN value (if any), in addition to the header gain.*/\n#define OP_ALBUM_GAIN    (3007)\n\n/**Gain offset type that indicates that the provided offset is relative to the\n    R128_TRACK_GAIN value (if any), in addition to the header gain.*/\n#define OP_TRACK_GAIN    (3008)\n\n/**Gain offset type that indicates that the provided offset should be used as\n    the gain directly, without applying any the header or track gains.*/\n#define OP_ABSOLUTE_GAIN (3009)\n\n/**Sets the gain to be used for decoded output.\n   By default, the gain in the header is applied with no additional offset.\n   The total gain (including header gain and/or track gain, if applicable, and\n    this offset), will be clamped to [-32768,32767]/256 dB.\n   This is more than enough to saturate or underflow 16-bit PCM.\n   \\note The new gain will not be applied to any already buffered, decoded\n    output.\n   This means you cannot change it sample-by-sample, as at best it will be\n    updated packet-by-packet.\n   It is meant for setting a target volume level, rather than applying smooth\n    fades, etc.\n   \\param _of             The \\c OggOpusFile on which to set the gain offset.\n   \\param _gain_type      One of #OP_HEADER_GAIN, #OP_ALBUM_GAIN,\n                           #OP_TRACK_GAIN, or #OP_ABSOLUTE_GAIN.\n   \\param _gain_offset_q8 The gain offset to apply, in 1/256ths of a dB.\n   \\return 0 on success or a negative value on error.\n   \\retval #OP_EINVAL The \\a _gain_type was unrecognized.*/\nint op_set_gain_offset(OggOpusFile *_of,\n int _gain_type,opus_int32 _gain_offset_q8) OP_ARG_NONNULL(1);\n\n/**Sets whether or not dithering is enabled for 16-bit decoding.\n   By default, when <tt>libopusfile</tt> is compiled to use floating-point\n    internally, calling op_read() or op_read_stereo() will first decode to\n    float, and then convert to fixed-point using noise-shaping dithering.\n   This flag can be used to disable that dithering.\n   When the application uses op_read_float() or op_read_float_stereo(), or when\n    the library has been compiled to decode directly to fixed point, this flag\n    has no effect.\n   \\param _of      The \\c OggOpusFile on which to enable or disable dithering.\n   \\param _enabled A non-zero value to enable dithering, or 0 to disable it.*/\nvoid op_set_dither_enabled(OggOpusFile *_of,int _enabled) OP_ARG_NONNULL(1);\n\n/**Reads more samples from the stream.\n   \\note Although \\a _buf_size must indicate the total number of values that\n    can be stored in \\a _pcm, the return value is the number of samples\n    <em>per channel</em>.\n   This is done because\n   <ol>\n   <li>The channel count cannot be known a priori (reading more samples might\n        advance us into the next link, with a different channel count), so\n        \\a _buf_size cannot also be in units of samples per channel,</li>\n   <li>Returning the samples per channel matches the <code>libopus</code> API\n        as closely as we're able,</li>\n   <li>Returning the total number of values instead of samples per channel\n        would mean the caller would need a division to compute the samples per\n        channel, and might worry about the possibility of getting back samples\n        for some channels and not others, and</li>\n   <li>This approach is relatively fool-proof: if an application passes too\n        small a value to \\a _buf_size, they will simply get fewer samples back,\n        and if they assume the return value is the total number of values, then\n        they will simply read too few (rather than reading too many and going\n        off the end of the buffer).</li>\n   </ol>\n   \\param      _of       The \\c OggOpusFile from which to read.\n   \\param[out] _pcm      A buffer in which to store the output PCM samples, as\n                          signed native-endian 16-bit values at 48&nbsp;kHz\n                          with a nominal range of <code>[-32768,32767)</code>.\n                         Multiple channels are interleaved using the\n                          <a href=\"https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9\">Vorbis\n                          channel ordering</a>.\n                         This must have room for at least \\a _buf_size values.\n   \\param      _buf_size The number of values that can be stored in \\a _pcm.\n                         It is recommended that this be large enough for at\n                          least 120 ms of data at 48 kHz per channel (5760\n                          values per channel).\n                         Smaller buffers will simply return less data, possibly\n                          consuming more memory to buffer the data internally.\n                         <tt>libopusfile</tt> may return less data than\n                          requested.\n                         If so, there is no guarantee that the remaining data\n                          in \\a _pcm will be unmodified.\n   \\param[out] _li       The index of the link this data was decoded from.\n                         You may pass <code>NULL</code> if you do not need this\n                          information.\n                         If this function fails (returning a negative value),\n                          this parameter is left unset.\n   \\return The number of samples read per channel on success, or a negative\n            value on failure.\n           The channel count can be retrieved on success by calling\n            <code>op_head(_of,*_li)</code>.\n           The number of samples returned may be 0 if the buffer was too small\n            to store even a single sample for all channels, or if end-of-file\n            was reached.\n           The list of possible failure codes follows.\n           Most of them can only be returned by unseekable, chained streams\n            that encounter a new link.\n   \\retval #OP_HOLE          There was a hole in the data, and some samples\n                              may have been skipped.\n                             Call this function again to continue decoding\n                              past the hole.\n   \\retval #OP_EREAD         An underlying read operation failed.\n                             This may signal a truncation attack from an\n                              <https:> source.\n   \\retval #OP_EFAULT        An internal memory allocation failed.\n   \\retval #OP_EIMPL         An unseekable stream encountered a new link that\n                              used a feature that is not implemented, such as\n                              an unsupported channel family.\n   \\retval #OP_EINVAL        The stream was only partially open.\n   \\retval #OP_ENOTFORMAT    An unseekable stream encountered a new link that\n                              did not have any logical Opus streams in it.\n   \\retval #OP_EBADHEADER    An unseekable stream encountered a new link with a\n                              required header packet that was not properly\n                              formatted, contained illegal values, or was\n                              missing altogether.\n   \\retval #OP_EVERSION      An unseekable stream encountered a new link with\n                              an ID header that contained an unrecognized\n                              version number.\n   \\retval #OP_EBADPACKET    Failed to properly decode the next packet.\n   \\retval #OP_EBADLINK      We failed to find data we had seen before.\n   \\retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with\n                              a starting timestamp that failed basic validity\n                              checks.*/\nOP_WARN_UNUSED_RESULT int op_read(OggOpusFile *_of,\n opus_int16 *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1);\n\n/**Reads more samples from the stream.\n   \\note Although \\a _buf_size must indicate the total number of values that\n    can be stored in \\a _pcm, the return value is the number of samples\n    <em>per channel</em>.\n   <ol>\n   <li>The channel count cannot be known a priori (reading more samples might\n        advance us into the next link, with a different channel count), so\n        \\a _buf_size cannot also be in units of samples per channel,</li>\n   <li>Returning the samples per channel matches the <code>libopus</code> API\n        as closely as we're able,</li>\n   <li>Returning the total number of values instead of samples per channel\n        would mean the caller would need a division to compute the samples per\n        channel, and might worry about the possibility of getting back samples\n        for some channels and not others, and</li>\n   <li>This approach is relatively fool-proof: if an application passes too\n        small a value to \\a _buf_size, they will simply get fewer samples back,\n        and if they assume the return value is the total number of values, then\n        they will simply read too few (rather than reading too many and going\n        off the end of the buffer).</li>\n   </ol>\n   \\param      _of       The \\c OggOpusFile from which to read.\n   \\param[out] _pcm      A buffer in which to store the output PCM samples as\n                          signed floats at 48&nbsp;kHz with a nominal range of\n                          <code>[-1.0,1.0]</code>.\n                         Multiple channels are interleaved using the\n                          <a href=\"https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9\">Vorbis\n                          channel ordering</a>.\n                         This must have room for at least \\a _buf_size floats.\n   \\param      _buf_size The number of floats that can be stored in \\a _pcm.\n                         It is recommended that this be large enough for at\n                          least 120 ms of data at 48 kHz per channel (5760\n                          samples per channel).\n                         Smaller buffers will simply return less data, possibly\n                          consuming more memory to buffer the data internally.\n                         If less than \\a _buf_size values are returned,\n                          <tt>libopusfile</tt> makes no guarantee that the\n                          remaining data in \\a _pcm will be unmodified.\n   \\param[out] _li       The index of the link this data was decoded from.\n                         You may pass <code>NULL</code> if you do not need this\n                          information.\n                         If this function fails (returning a negative value),\n                          this parameter is left unset.\n   \\return The number of samples read per channel on success, or a negative\n            value on failure.\n           The channel count can be retrieved on success by calling\n            <code>op_head(_of,*_li)</code>.\n           The number of samples returned may be 0 if the buffer was too small\n            to store even a single sample for all channels, or if end-of-file\n            was reached.\n           The list of possible failure codes follows.\n           Most of them can only be returned by unseekable, chained streams\n            that encounter a new link.\n   \\retval #OP_HOLE          There was a hole in the data, and some samples\n                              may have been skipped.\n                             Call this function again to continue decoding\n                              past the hole.\n   \\retval #OP_EREAD         An underlying read operation failed.\n                             This may signal a truncation attack from an\n                              <https:> source.\n   \\retval #OP_EFAULT        An internal memory allocation failed.\n   \\retval #OP_EIMPL         An unseekable stream encountered a new link that\n                              used a feature that is not implemented, such as\n                              an unsupported channel family.\n   \\retval #OP_EINVAL        The stream was only partially open.\n   \\retval #OP_ENOTFORMAT    An unseekable stream encountered a new link that\n                              did not have any logical Opus streams in it.\n   \\retval #OP_EBADHEADER    An unseekable stream encountered a new link with a\n                              required header packet that was not properly\n                              formatted, contained illegal values, or was\n                              missing altogether.\n   \\retval #OP_EVERSION      An unseekable stream encountered a new link with\n                              an ID header that contained an unrecognized\n                              version number.\n   \\retval #OP_EBADPACKET    Failed to properly decode the next packet.\n   \\retval #OP_EBADLINK      We failed to find data we had seen before.\n   \\retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with\n                              a starting timestamp that failed basic validity\n                              checks.*/\nOP_WARN_UNUSED_RESULT int op_read_float(OggOpusFile *_of,\n float *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1);\n\n/**Reads more samples from the stream and downmixes to stereo, if necessary.\n   This function is intended for simple players that want a uniform output\n    format, even if the channel count changes between links in a chained\n    stream.\n   \\note \\a _buf_size indicates the total number of values that can be stored\n    in \\a _pcm, while the return value is the number of samples <em>per\n    channel</em>, even though the channel count is known, for consistency with\n    op_read().\n   \\param      _of       The \\c OggOpusFile from which to read.\n   \\param[out] _pcm      A buffer in which to store the output PCM samples, as\n                          signed native-endian 16-bit values at 48&nbsp;kHz\n                          with a nominal range of <code>[-32768,32767)</code>.\n                         The left and right channels are interleaved in the\n                          buffer.\n                         This must have room for at least \\a _buf_size values.\n   \\param      _buf_size The number of values that can be stored in \\a _pcm.\n                         It is recommended that this be large enough for at\n                          least 120 ms of data at 48 kHz per channel (11520\n                          values total).\n                         Smaller buffers will simply return less data, possibly\n                          consuming more memory to buffer the data internally.\n                         If less than \\a _buf_size values are returned,\n                          <tt>libopusfile</tt> makes no guarantee that the\n                          remaining data in \\a _pcm will be unmodified.\n   \\return The number of samples read per channel on success, or a negative\n            value on failure.\n           The number of samples returned may be 0 if the buffer was too small\n            to store even a single sample for both channels, or if end-of-file\n            was reached.\n           The list of possible failure codes follows.\n           Most of them can only be returned by unseekable, chained streams\n            that encounter a new link.\n   \\retval #OP_HOLE          There was a hole in the data, and some samples\n                              may have been skipped.\n                             Call this function again to continue decoding\n                              past the hole.\n   \\retval #OP_EREAD         An underlying read operation failed.\n                             This may signal a truncation attack from an\n                              <https:> source.\n   \\retval #OP_EFAULT        An internal memory allocation failed.\n   \\retval #OP_EIMPL         An unseekable stream encountered a new link that\n                              used a feature that is not implemented, such as\n                              an unsupported channel family.\n   \\retval #OP_EINVAL        The stream was only partially open.\n   \\retval #OP_ENOTFORMAT    An unseekable stream encountered a new link that\n                              did not have any logical Opus streams in it.\n   \\retval #OP_EBADHEADER    An unseekable stream encountered a new link with a\n                              required header packet that was not properly\n                              formatted, contained illegal values, or was\n                              missing altogether.\n   \\retval #OP_EVERSION      An unseekable stream encountered a new link with\n                              an ID header that contained an unrecognized\n                              version number.\n   \\retval #OP_EBADPACKET    Failed to properly decode the next packet.\n   \\retval #OP_EBADLINK      We failed to find data we had seen before.\n   \\retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with\n                              a starting timestamp that failed basic validity\n                              checks.*/\nOP_WARN_UNUSED_RESULT int op_read_stereo(OggOpusFile *_of,\n opus_int16 *_pcm,int _buf_size) OP_ARG_NONNULL(1);\n\n/**Reads more samples from the stream and downmixes to stereo, if necessary.\n   This function is intended for simple players that want a uniform output\n    format, even if the channel count changes between links in a chained\n    stream.\n   \\note \\a _buf_size indicates the total number of values that can be stored\n    in \\a _pcm, while the return value is the number of samples <em>per\n    channel</em>, even though the channel count is known, for consistency with\n    op_read_float().\n   \\param      _of       The \\c OggOpusFile from which to read.\n   \\param[out] _pcm      A buffer in which to store the output PCM samples, as\n                          signed floats at 48&nbsp;kHz with a nominal range of\n                          <code>[-1.0,1.0]</code>.\n                         The left and right channels are interleaved in the\n                          buffer.\n                         This must have room for at least \\a _buf_size values.\n   \\param      _buf_size The number of values that can be stored in \\a _pcm.\n                         It is recommended that this be large enough for at\n                          least 120 ms of data at 48 kHz per channel (11520\n                          values total).\n                         Smaller buffers will simply return less data, possibly\n                          consuming more memory to buffer the data internally.\n                         If less than \\a _buf_size values are returned,\n                          <tt>libopusfile</tt> makes no guarantee that the\n                          remaining data in \\a _pcm will be unmodified.\n   \\return The number of samples read per channel on success, or a negative\n            value on failure.\n           The number of samples returned may be 0 if the buffer was too small\n            to store even a single sample for both channels, or if end-of-file\n            was reached.\n           The list of possible failure codes follows.\n           Most of them can only be returned by unseekable, chained streams\n            that encounter a new link.\n   \\retval #OP_HOLE          There was a hole in the data, and some samples\n                              may have been skipped.\n                             Call this function again to continue decoding\n                              past the hole.\n   \\retval #OP_EREAD         An underlying read operation failed.\n                             This may signal a truncation attack from an\n                              <https:> source.\n   \\retval #OP_EFAULT        An internal memory allocation failed.\n   \\retval #OP_EIMPL         An unseekable stream encountered a new link that\n                              used a feature that is not implemented, such as\n                              an unsupported channel family.\n   \\retval #OP_EINVAL        The stream was only partially open.\n   \\retval #OP_ENOTFORMAT    An unseekable stream encountered a new link that\n                              that did not have any logical Opus streams in it.\n   \\retval #OP_EBADHEADER    An unseekable stream encountered a new link with a\n                              required header packet that was not properly\n                              formatted, contained illegal values, or was\n                              missing altogether.\n   \\retval #OP_EVERSION      An unseekable stream encountered a new link with\n                              an ID header that contained an unrecognized\n                              version number.\n   \\retval #OP_EBADPACKET    Failed to properly decode the next packet.\n   \\retval #OP_EBADLINK      We failed to find data we had seen before.\n   \\retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with\n                              a starting timestamp that failed basic validity\n                              checks.*/\nOP_WARN_UNUSED_RESULT int op_read_float_stereo(OggOpusFile *_of,\n float *_pcm,int _buf_size) OP_ARG_NONNULL(1);\n\n/*@}*/\n/*@}*/\n\n# if OP_GNUC_PREREQ(4,0)\n#  pragma GCC visibility pop\n# endif\n\n# if defined(__cplusplus)\n}\n# endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/patch/p7zip/7z.h",
    "content": "/* 7z.h -- 7z interface\r\n2015-11-18 : Igor Pavlov : Public domain */\r\n\r\n#ifndef __7Z_H\r\n#define __7Z_H\r\n\r\n#include \"7zTypes.h\"\r\n\r\nEXTERN_C_BEGIN\r\n\r\n#define k7zStartHeaderSize 0x20\r\n#define k7zSignatureSize 6\r\n\r\nextern const Byte k7zSignature[k7zSignatureSize];\r\n\r\ntypedef struct\r\n{\r\n  const Byte *Data;\r\n  size_t Size;\r\n} CSzData;\r\n\r\n/* CSzCoderInfo & CSzFolder support only default methods */\r\n\r\ntypedef struct\r\n{\r\n  size_t PropsOffset;\r\n  UInt32 MethodID;\r\n  Byte NumStreams;\r\n  Byte PropsSize;\r\n} CSzCoderInfo;\r\n\r\ntypedef struct\r\n{\r\n  UInt32 InIndex;\r\n  UInt32 OutIndex;\r\n} CSzBond;\r\n\r\n#define SZ_NUM_CODERS_IN_FOLDER_MAX 4\r\n#define SZ_NUM_BONDS_IN_FOLDER_MAX 3\r\n#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4\r\n\r\ntypedef struct\r\n{\r\n  UInt32 NumCoders;\r\n  UInt32 NumBonds;\r\n  UInt32 NumPackStreams;\r\n  UInt32 UnpackStream;\r\n  UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];\r\n  CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];\r\n  CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];\r\n} CSzFolder;\r\n\r\n\r\nSRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);\r\n\r\ntypedef struct\r\n{\r\n  UInt32 Low;\r\n  UInt32 High;\r\n} CNtfsFileTime;\r\n\r\ntypedef struct\r\n{\r\n  Byte *Defs; /* MSB 0 bit numbering */\r\n  UInt32 *Vals;\r\n} CSzBitUi32s;\r\n\r\ntypedef struct\r\n{\r\n  Byte *Defs; /* MSB 0 bit numbering */\r\n  // UInt64 *Vals;\r\n  CNtfsFileTime *Vals;\r\n} CSzBitUi64s;\r\n\r\n#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)\r\n\r\n#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)\r\n\r\ntypedef struct\r\n{\r\n  UInt32 NumPackStreams;\r\n  UInt32 NumFolders;\r\n\r\n  UInt64 *PackPositions;          // NumPackStreams + 1\r\n  CSzBitUi32s FolderCRCs;         // NumFolders\r\n\r\n  size_t *FoCodersOffsets;        // NumFolders + 1\r\n  UInt32 *FoStartPackStreamIndex; // NumFolders + 1\r\n  UInt32 *FoToCoderUnpackSizes;   // NumFolders + 1\r\n  Byte *FoToMainUnpackSizeIndex;  // NumFolders\r\n  UInt64 *CoderUnpackSizes;       // for all coders in all folders\r\n\r\n  Byte *CodersData;\r\n} CSzAr;\r\n\r\nUInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);\r\n\r\nSRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,\r\n    ILookInStream *stream, UInt64 startPos,\r\n    Byte *outBuffer, size_t outSize,\r\n    ISzAlloc *allocMain);\r\n\r\ntypedef struct\r\n{\r\n  CSzAr db;\r\n\r\n  UInt64 startPosAfterHeader;\r\n  UInt64 dataPos;\r\n  \r\n  UInt32 NumFiles;\r\n\r\n  UInt64 *UnpackPositions;  // NumFiles + 1\r\n  // Byte *IsEmptyFiles;\r\n  Byte *IsDirs;\r\n  CSzBitUi32s CRCs;\r\n\r\n  CSzBitUi32s Attribs;\r\n  // CSzBitUi32s Parents;\r\n  CSzBitUi64s MTime;\r\n  CSzBitUi64s CTime;\r\n\r\n  UInt32 *FolderToFile;   // NumFolders + 1\r\n  UInt32 *FileToFolder;   // NumFiles\r\n\r\n  size_t *FileNameOffsets; /* in 2-byte steps */\r\n  Byte *FileNames;  /* UTF-16-LE */\r\n} CSzArEx;\r\n\r\n#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))\r\n\r\n#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])\r\n\r\nvoid SzArEx_Init(CSzArEx *p);\r\nvoid SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);\r\nUInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);\r\nint SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);\r\n\r\n/*\r\nif dest == NULL, the return value specifies the required size of the buffer,\r\n  in 16-bit characters, including the null-terminating character.\r\nif dest != NULL, the return value specifies the number of 16-bit characters that\r\n  are written to the dest, including the null-terminating character. */\r\n\r\nsize_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);\r\n\r\n/*\r\nsize_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);\r\nUInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);\r\n*/\r\n\r\n\r\n\r\n/*\r\n  SzArEx_Extract extracts file from archive\r\n\r\n  *outBuffer must be 0 before first call for each new archive.\r\n\r\n  Extracting cache:\r\n    If you need to decompress more than one file, you can send\r\n    these values from previous call:\r\n      *blockIndex,\r\n      *outBuffer,\r\n      *outBufferSize\r\n    You can consider \"*outBuffer\" as cache of solid block. If your archive is solid,\r\n    it will increase decompression speed.\r\n  \r\n    If you use external function, you can declare these 3 cache variables\r\n    (blockIndex, outBuffer, outBufferSize) as static in that external function.\r\n    \r\n    Free *outBuffer and set *outBuffer to 0, if you want to flush cache.\r\n*/\r\n\r\nSRes SzArEx_Extract(\r\n    const CSzArEx *db,\r\n    ILookInStream *inStream,\r\n    UInt32 fileIndex,         /* index of file */\r\n    UInt32 *blockIndex,       /* index of solid block */\r\n    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */\r\n    size_t *outBufferSize,    /* buffer size for output buffer */\r\n    size_t *offset,           /* offset of stream for required file in *outBuffer */\r\n    size_t *outSizeProcessed, /* size of file in *outBuffer */\r\n    ISzAlloc *allocMain,\r\n    ISzAlloc *allocTemp);\r\n\r\n\r\n/*\r\nSzArEx_Open Errors:\r\nSZ_ERROR_NO_ARCHIVE\r\nSZ_ERROR_ARCHIVE\r\nSZ_ERROR_UNSUPPORTED\r\nSZ_ERROR_MEM\r\nSZ_ERROR_CRC\r\nSZ_ERROR_INPUT_EOF\r\nSZ_ERROR_FAIL\r\n*/\r\n\r\nSRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,\r\n    ISzAlloc *allocMain, ISzAlloc *allocTemp);\r\n\r\nEXTERN_C_END\r\n\r\n#endif\r\n"
  },
  {
    "path": "thirdparty/patch/p7zip/7zArcIn.c",
    "content": "/* 7zArcIn.c -- 7z Input functions\r\n2016-05-16 : Igor Pavlov : Public domain */\r\n\r\n#include \"Precomp.h\"\r\n\r\n#include <string.h>\r\n\r\n#include \"7z.h\"\r\n#include \"7zBuf.h\"\r\n#include \"7zCrc.h\"\r\n#include \"CpuArch.h\"\r\n\r\n#define MY_ALLOC(T, p, size, alloc) { \\\r\n  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }\r\n\r\n#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }\r\n\r\n#define MY_ALLOC_AND_CPY(to, size, from, alloc) \\\r\n  { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }\r\n\r\n#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \\\r\n  { if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }\r\n\r\n#define k7zMajorVersion 0\r\n\r\nenum EIdEnum\r\n{\r\n  k7zIdEnd,\r\n  k7zIdHeader,\r\n  k7zIdArchiveProperties,\r\n  k7zIdAdditionalStreamsInfo,\r\n  k7zIdMainStreamsInfo,\r\n  k7zIdFilesInfo,\r\n  k7zIdPackInfo,\r\n  k7zIdUnpackInfo,\r\n  k7zIdSubStreamsInfo,\r\n  k7zIdSize,\r\n  k7zIdCRC,\r\n  k7zIdFolder,\r\n  k7zIdCodersUnpackSize,\r\n  k7zIdNumUnpackStream,\r\n  k7zIdEmptyStream,\r\n  k7zIdEmptyFile,\r\n  k7zIdAnti,\r\n  k7zIdName,\r\n  k7zIdCTime,\r\n  k7zIdATime,\r\n  k7zIdMTime,\r\n  k7zIdWinAttrib,\r\n  k7zIdComment,\r\n  k7zIdEncodedHeader,\r\n  k7zIdStartPos,\r\n  k7zIdDummy\r\n  // k7zNtSecure,\r\n  // k7zParent,\r\n  // k7zIsReal\r\n};\r\n\r\nconst Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};\r\n\r\n#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }\r\n\r\nstatic SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)\r\n{\r\n  if (num == 0)\r\n  {\r\n    p->Defs = NULL;\r\n    p->Vals = NULL;\r\n  }\r\n  else\r\n  {\r\n    MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);\r\n    MY_ALLOC(UInt32, p->Vals, num, alloc);\r\n  }\r\n  return SZ_OK;\r\n}\r\n\r\nvoid SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)\r\n{\r\n  IAlloc_Free(alloc, p->Defs); p->Defs = NULL;\r\n  IAlloc_Free(alloc, p->Vals); p->Vals = NULL;\r\n}\r\n\r\n#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }\r\n\r\nvoid SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)\r\n{\r\n  IAlloc_Free(alloc, p->Defs); p->Defs = NULL;\r\n  IAlloc_Free(alloc, p->Vals); p->Vals = NULL;\r\n}\r\n\r\n\r\nstatic void SzAr_Init(CSzAr *p)\r\n{\r\n  p->NumPackStreams = 0;\r\n  p->NumFolders = 0;\r\n  \r\n  p->PackPositions = NULL;\r\n  SzBitUi32s_Init(&p->FolderCRCs);\r\n\r\n  p->FoCodersOffsets = NULL;\r\n  p->FoStartPackStreamIndex = NULL;\r\n  p->FoToCoderUnpackSizes = NULL;\r\n  p->FoToMainUnpackSizeIndex = NULL;\r\n  p->CoderUnpackSizes = NULL;\r\n\r\n  p->CodersData = NULL;\r\n}\r\n\r\nstatic void SzAr_Free(CSzAr *p, ISzAlloc *alloc)\r\n{\r\n  IAlloc_Free(alloc, p->PackPositions);\r\n  SzBitUi32s_Free(&p->FolderCRCs, alloc);\r\n \r\n  IAlloc_Free(alloc, p->FoCodersOffsets);\r\n  IAlloc_Free(alloc, p->FoStartPackStreamIndex);\r\n  IAlloc_Free(alloc, p->FoToCoderUnpackSizes);\r\n  IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);\r\n  IAlloc_Free(alloc, p->CoderUnpackSizes);\r\n  \r\n  IAlloc_Free(alloc, p->CodersData);\r\n\r\n  SzAr_Init(p);\r\n}\r\n\r\n\r\nvoid SzArEx_Init(CSzArEx *p)\r\n{\r\n  SzAr_Init(&p->db);\r\n  \r\n  p->NumFiles = 0;\r\n  p->dataPos = 0;\r\n  \r\n  p->UnpackPositions = NULL;\r\n  p->IsDirs = NULL;\r\n  \r\n  p->FolderToFile = NULL;\r\n  p->FileToFolder = NULL;\r\n  \r\n  p->FileNameOffsets = NULL;\r\n  p->FileNames = NULL;\r\n  \r\n  SzBitUi32s_Init(&p->CRCs);\r\n  SzBitUi32s_Init(&p->Attribs);\r\n  // SzBitUi32s_Init(&p->Parents);\r\n  SzBitUi64s_Init(&p->MTime);\r\n  SzBitUi64s_Init(&p->CTime);\r\n}\r\n\r\nvoid SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)\r\n{\r\n  IAlloc_Free(alloc, p->UnpackPositions);\r\n  IAlloc_Free(alloc, p->IsDirs);\r\n\r\n  IAlloc_Free(alloc, p->FolderToFile);\r\n  IAlloc_Free(alloc, p->FileToFolder);\r\n\r\n  IAlloc_Free(alloc, p->FileNameOffsets);\r\n  IAlloc_Free(alloc, p->FileNames);\r\n\r\n  SzBitUi32s_Free(&p->CRCs, alloc);\r\n  SzBitUi32s_Free(&p->Attribs, alloc);\r\n  // SzBitUi32s_Free(&p->Parents, alloc);\r\n  SzBitUi64s_Free(&p->MTime, alloc);\r\n  SzBitUi64s_Free(&p->CTime, alloc);\r\n  \r\n  SzAr_Free(&p->db, alloc);\r\n  SzArEx_Init(p);\r\n}\r\n\r\n\r\nstatic int TestSignatureCandidate(const Byte *testBytes)\r\n{\r\n  unsigned i;\r\n  for (i = 0; i < k7zSignatureSize; i++)\r\n    if (testBytes[i] != k7zSignature[i])\r\n      return 0;\r\n  return 1;\r\n}\r\n\r\n#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }\r\n\r\n#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;\r\n#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)\r\n#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++;\r\n\r\n#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); }\r\n#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); }\r\n\r\n#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \\\r\n   dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4);\r\n\r\nstatic MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)\r\n{\r\n  Byte firstByte, mask;\r\n  unsigned i;\r\n  UInt32 v;\r\n\r\n  SZ_READ_BYTE(firstByte);\r\n  if ((firstByte & 0x80) == 0)\r\n  {\r\n    *value = firstByte;\r\n    return SZ_OK;\r\n  }\r\n  SZ_READ_BYTE(v);\r\n  if ((firstByte & 0x40) == 0)\r\n  {\r\n    *value = (((UInt32)firstByte & 0x3F) << 8) | v;\r\n    return SZ_OK;\r\n  }\r\n  SZ_READ_BYTE(mask);\r\n  *value = v | ((UInt32)mask << 8);\r\n  mask = 0x20;\r\n  for (i = 2; i < 8; i++)\r\n  {\r\n    Byte b;\r\n    if ((firstByte & mask) == 0)\r\n    {\r\n      UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);\r\n      *value |= (highPart << (8 * i));\r\n      return SZ_OK;\r\n    }\r\n    SZ_READ_BYTE(b);\r\n    *value |= ((UInt64)b << (8 * i));\r\n    mask >>= 1;\r\n  }\r\n  return SZ_OK;\r\n}\r\n\r\n\r\nstatic MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)\r\n{\r\n  Byte firstByte;\r\n  UInt64 value64;\r\n  if (sd->Size == 0)\r\n    return SZ_ERROR_ARCHIVE;\r\n  firstByte = *sd->Data;\r\n  if ((firstByte & 0x80) == 0)\r\n  {\r\n    *value = firstByte;\r\n    sd->Data++;\r\n    sd->Size--;\r\n    return SZ_OK;\r\n  }\r\n  RINOK(ReadNumber(sd, &value64));\r\n  if (value64 >= (UInt32)0x80000000 - 1)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4)))\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  *value = (UInt32)value64;\r\n  return SZ_OK;\r\n}\r\n\r\n#define ReadID(sd, value) ReadNumber(sd, value)\r\n\r\nstatic SRes SkipData(CSzData *sd)\r\n{\r\n  UInt64 size;\r\n  RINOK(ReadNumber(sd, &size));\r\n  if (size > sd->Size)\r\n    return SZ_ERROR_ARCHIVE;\r\n  SKIP_DATA(sd, size);\r\n  return SZ_OK;\r\n}\r\n\r\nstatic SRes WaitId(CSzData *sd, UInt32 id)\r\n{\r\n  for (;;)\r\n  {\r\n    UInt64 type;\r\n    RINOK(ReadID(sd, &type));\r\n    if (type == id)\r\n      return SZ_OK;\r\n    if (type == k7zIdEnd)\r\n      return SZ_ERROR_ARCHIVE;\r\n    RINOK(SkipData(sd));\r\n  }\r\n}\r\n\r\nstatic SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v)\r\n{\r\n  UInt32 numBytes = (numItems + 7) >> 3;\r\n  if (numBytes > sd->Size)\r\n    return SZ_ERROR_ARCHIVE;\r\n  *v = sd->Data;\r\n  SKIP_DATA(sd, numBytes);\r\n  return SZ_OK;\r\n}\r\n\r\nstatic UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)\r\n{\r\n  Byte b = 0;\r\n  unsigned m = 0;\r\n  UInt32 sum = 0;\r\n  for (; numItems != 0; numItems--)\r\n  {\r\n    if (m == 0)\r\n    {\r\n      b = *bits++;\r\n      m = 8;\r\n    }\r\n    m--;\r\n    sum += ((b >> m) & 1);\r\n  }\r\n  return sum;\r\n}\r\n\r\nstatic MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)\r\n{\r\n  Byte allAreDefined;\r\n  Byte *v2;\r\n  UInt32 numBytes = (numItems + 7) >> 3;\r\n  *v = NULL;\r\n  SZ_READ_BYTE(allAreDefined);\r\n  if (numBytes == 0)\r\n    return SZ_OK;\r\n  if (allAreDefined == 0)\r\n  {\r\n    if (numBytes > sd->Size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);\r\n    SKIP_DATA(sd, numBytes);\r\n    return SZ_OK;\r\n  }\r\n  MY_ALLOC(Byte, *v, numBytes, alloc);\r\n  v2 = *v;\r\n  memset(v2, 0xFF, (size_t)numBytes);\r\n  {\r\n    unsigned numBits = (unsigned)numItems & 7;\r\n    if (numBits != 0)\r\n      v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));\r\n  }\r\n  return SZ_OK;\r\n}\r\n\r\nstatic MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)\r\n{\r\n  UInt32 i;\r\n  CSzData sd;\r\n  UInt32 *vals;\r\n  const Byte *defs;\r\n  MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);\r\n  sd = *sd2;\r\n  defs = crcs->Defs;\r\n  vals = crcs->Vals;\r\n  for (i = 0; i < numItems; i++)\r\n    if (SzBitArray_Check(defs, i))\r\n    {\r\n      SZ_READ_32(vals[i]);\r\n    }\r\n    else\r\n      vals[i] = 0;\r\n  *sd2 = sd;\r\n  return SZ_OK;\r\n}\r\n\r\nstatic SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)\r\n{\r\n  SzBitUi32s_Free(crcs, alloc);\r\n  RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));\r\n  return ReadUi32s(sd, numItems, crcs, alloc);\r\n}\r\n\r\nstatic SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)\r\n{\r\n  Byte allAreDefined;\r\n  UInt32 numDefined = numItems;\r\n  SZ_READ_BYTE(allAreDefined);\r\n  if (!allAreDefined)\r\n  {\r\n    size_t numBytes = (numItems + 7) >> 3;\r\n    if (numBytes > sd->Size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    numDefined = CountDefinedBits(sd->Data, numItems);\r\n    SKIP_DATA(sd, numBytes);\r\n  }\r\n  if (numDefined > (sd->Size >> 2))\r\n    return SZ_ERROR_ARCHIVE;\r\n  SKIP_DATA(sd, (size_t)numDefined * 4);\r\n  return SZ_OK;\r\n}\r\n\r\nstatic SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)\r\n{\r\n  RINOK(SzReadNumber32(sd, &p->NumPackStreams));\r\n\r\n  RINOK(WaitId(sd, k7zIdSize));\r\n  MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc);\r\n  {\r\n    UInt64 sum = 0;\r\n    UInt32 i;\r\n    UInt32 numPackStreams = p->NumPackStreams;\r\n    for (i = 0; i < numPackStreams; i++)\r\n    {\r\n      UInt64 packSize;\r\n      p->PackPositions[i] = sum;\r\n      RINOK(ReadNumber(sd, &packSize));\r\n      sum += packSize;\r\n      if (sum < packSize)\r\n        return SZ_ERROR_ARCHIVE;\r\n    }\r\n    p->PackPositions[i] = sum;\r\n  }\r\n\r\n  for (;;)\r\n  {\r\n    UInt64 type;\r\n    RINOK(ReadID(sd, &type));\r\n    if (type == k7zIdEnd)\r\n      return SZ_OK;\r\n    if (type == k7zIdCRC)\r\n    {\r\n      /* CRC of packed streams is unused now */\r\n      RINOK(SkipBitUi32s(sd, p->NumPackStreams));\r\n      continue;\r\n    }\r\n    RINOK(SkipData(sd));\r\n  }\r\n}\r\n\r\n/*\r\nstatic SRes SzReadSwitch(CSzData *sd)\r\n{\r\n  Byte external;\r\n  RINOK(SzReadByte(sd, &external));\r\n  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;\r\n}\r\n*/\r\n\r\n#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)\r\n\r\nSRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)\r\n{\r\n  UInt32 numCoders, i;\r\n  UInt32 numInStreams = 0;\r\n  const Byte *dataStart = sd->Data;\r\n\r\n  f->NumCoders = 0;\r\n  f->NumBonds = 0;\r\n  f->NumPackStreams = 0;\r\n  f->UnpackStream = 0;\r\n  \r\n  RINOK(SzReadNumber32(sd, &numCoders));\r\n  if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  \r\n  for (i = 0; i < numCoders; i++)\r\n  {\r\n    Byte mainByte;\r\n    CSzCoderInfo *coder = f->Coders + i;\r\n    unsigned idSize, j;\r\n    UInt64 id;\r\n    \r\n    SZ_READ_BYTE(mainByte);\r\n    if ((mainByte & 0xC0) != 0)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    \r\n    idSize = (unsigned)(mainByte & 0xF);\r\n    if (idSize > sizeof(id))\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    if (idSize > sd->Size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    id = 0;\r\n    for (j = 0; j < idSize; j++)\r\n    {\r\n      id = ((id << 8) | *sd->Data);\r\n      sd->Data++;\r\n      sd->Size--;\r\n    }\r\n    if (id > (UInt32)0xFFFFFFFF)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    coder->MethodID = (UInt32)id;\r\n    \r\n    coder->NumStreams = 1;\r\n    coder->PropsOffset = 0;\r\n    coder->PropsSize = 0;\r\n    \r\n    if ((mainByte & 0x10) != 0)\r\n    {\r\n      UInt32 numStreams;\r\n      \r\n      RINOK(SzReadNumber32(sd, &numStreams));\r\n      if (numStreams > k_NumCodersStreams_in_Folder_MAX)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      coder->NumStreams = (Byte)numStreams;\r\n\r\n      RINOK(SzReadNumber32(sd, &numStreams));\r\n      if (numStreams != 1)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n    }\r\n\r\n    numInStreams += coder->NumStreams;\r\n\r\n    if (numInStreams > k_NumCodersStreams_in_Folder_MAX)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n\r\n    if ((mainByte & 0x20) != 0)\r\n    {\r\n      UInt32 propsSize = 0;\r\n      RINOK(SzReadNumber32(sd, &propsSize));\r\n      if (propsSize > sd->Size)\r\n        return SZ_ERROR_ARCHIVE;\r\n      if (propsSize >= 0x80)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      coder->PropsOffset = sd->Data - dataStart;\r\n      coder->PropsSize = (Byte)propsSize;\r\n      sd->Data += (size_t)propsSize;\r\n      sd->Size -= (size_t)propsSize;\r\n    }\r\n  }\r\n\r\n  /*\r\n  if (numInStreams == 1 && numCoders == 1)\r\n  {\r\n    f->NumPackStreams = 1;\r\n    f->PackStreams[0] = 0;\r\n  }\r\n  else\r\n  */\r\n  {\r\n    Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];\r\n    UInt32 numBonds, numPackStreams;\r\n    \r\n    numBonds = numCoders - 1;\r\n    if (numInStreams < numBonds)\r\n      return SZ_ERROR_ARCHIVE;\r\n    if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    f->NumBonds = numBonds;\r\n    \r\n    numPackStreams = numInStreams - numBonds;\r\n    if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    f->NumPackStreams = numPackStreams;\r\n  \r\n    for (i = 0; i < numInStreams; i++)\r\n      streamUsed[i] = False;\r\n    \r\n    if (numBonds != 0)\r\n    {\r\n      Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];\r\n\r\n      for (i = 0; i < numCoders; i++)\r\n        coderUsed[i] = False;\r\n      \r\n      for (i = 0; i < numBonds; i++)\r\n      {\r\n        CSzBond *bp = f->Bonds + i;\r\n        \r\n        RINOK(SzReadNumber32(sd, &bp->InIndex));\r\n        if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])\r\n          return SZ_ERROR_ARCHIVE;\r\n        streamUsed[bp->InIndex] = True;\r\n        \r\n        RINOK(SzReadNumber32(sd, &bp->OutIndex));\r\n        if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])\r\n          return SZ_ERROR_ARCHIVE;\r\n        coderUsed[bp->OutIndex] = True;\r\n      }\r\n      \r\n      for (i = 0; i < numCoders; i++)\r\n        if (!coderUsed[i])\r\n        {\r\n          f->UnpackStream = i;\r\n          break;\r\n        }\r\n      \r\n      if (i == numCoders)\r\n        return SZ_ERROR_ARCHIVE;\r\n    }\r\n    \r\n    if (numPackStreams == 1)\r\n    {\r\n      for (i = 0; i < numInStreams; i++)\r\n        if (!streamUsed[i])\r\n          break;\r\n      if (i == numInStreams)\r\n        return SZ_ERROR_ARCHIVE;\r\n      f->PackStreams[0] = i;\r\n    }\r\n    else\r\n      for (i = 0; i < numPackStreams; i++)\r\n      {\r\n        UInt32 index;\r\n        RINOK(SzReadNumber32(sd, &index));\r\n        if (index >= numInStreams || streamUsed[index])\r\n          return SZ_ERROR_ARCHIVE;\r\n        streamUsed[index] = True;\r\n        f->PackStreams[i] = index;\r\n      }\r\n  }\r\n\r\n  f->NumCoders = numCoders;\r\n\r\n  return SZ_OK;\r\n}\r\n\r\n\r\nstatic MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)\r\n{\r\n  CSzData sd;\r\n  sd = *sd2;\r\n  for (; num != 0; num--)\r\n  {\r\n    Byte firstByte, mask;\r\n    unsigned i;\r\n    SZ_READ_BYTE_2(firstByte);\r\n    if ((firstByte & 0x80) == 0)\r\n      continue;\r\n    if ((firstByte & 0x40) == 0)\r\n    {\r\n      if (sd.Size == 0)\r\n        return SZ_ERROR_ARCHIVE;\r\n      sd.Size--;\r\n      sd.Data++;\r\n      continue;\r\n    }\r\n    mask = 0x20;\r\n    for (i = 2; i < 8 && (firstByte & mask) != 0; i++)\r\n      mask >>= 1;\r\n    if (i > sd.Size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    SKIP_DATA2(sd, i);\r\n  }\r\n  *sd2 = sd;\r\n  return SZ_OK;\r\n}\r\n\r\n\r\n#define k_Scan_NumCoders_MAX 64\r\n#define k_Scan_NumCodersStreams_in_Folder_MAX 64\r\n\r\n\r\nstatic SRes ReadUnpackInfo(CSzAr *p,\r\n    CSzData *sd2,\r\n    UInt32 numFoldersMax,\r\n    const CBuf *tempBufs, UInt32 numTempBufs,\r\n    ISzAlloc *alloc)\r\n{\r\n  CSzData sd;\r\n  \r\n  UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;\r\n  const Byte *startBufPtr;\r\n  Byte external;\r\n  \r\n  RINOK(WaitId(sd2, k7zIdFolder));\r\n  \r\n  RINOK(SzReadNumber32(sd2, &numFolders));\r\n  if (numFolders > numFoldersMax)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  p->NumFolders = numFolders;\r\n\r\n  SZ_READ_BYTE_SD(sd2, external);\r\n  if (external == 0)\r\n    sd = *sd2;\r\n  else\r\n  {\r\n    UInt32 index;\r\n    RINOK(SzReadNumber32(sd2, &index));\r\n    if (index >= numTempBufs)\r\n      return SZ_ERROR_ARCHIVE;\r\n    sd.Data = tempBufs[index].data;\r\n    sd.Size = tempBufs[index].size;\r\n  }\r\n  \r\n  MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);\r\n  MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);\r\n  MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);\r\n  MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);\r\n  \r\n  startBufPtr = sd.Data;\r\n  \r\n  packStreamIndex = 0;\r\n  numCodersOutStreams = 0;\r\n\r\n  for (fo = 0; fo < numFolders; fo++)\r\n  {\r\n    UInt32 numCoders, ci, numInStreams = 0;\r\n    \r\n    p->FoCodersOffsets[fo] = sd.Data - startBufPtr;\r\n    \r\n    RINOK(SzReadNumber32(&sd, &numCoders));\r\n    if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    \r\n    for (ci = 0; ci < numCoders; ci++)\r\n    {\r\n      Byte mainByte;\r\n      unsigned idSize;\r\n      UInt32 coderInStreams;\r\n      \r\n      SZ_READ_BYTE_2(mainByte);\r\n      if ((mainByte & 0xC0) != 0)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      idSize = (mainByte & 0xF);\r\n      if (idSize > 8)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      if (idSize > sd.Size)\r\n        return SZ_ERROR_ARCHIVE;\r\n      SKIP_DATA2(sd, idSize);\r\n      \r\n      coderInStreams = 1;\r\n      \r\n      if ((mainByte & 0x10) != 0)\r\n      {\r\n        UInt32 coderOutStreams;\r\n        RINOK(SzReadNumber32(&sd, &coderInStreams));\r\n        RINOK(SzReadNumber32(&sd, &coderOutStreams));\r\n        if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)\r\n          return SZ_ERROR_UNSUPPORTED;\r\n      }\r\n      \r\n      numInStreams += coderInStreams;\r\n\r\n      if ((mainByte & 0x20) != 0)\r\n      {\r\n        UInt32 propsSize;\r\n        RINOK(SzReadNumber32(&sd, &propsSize));\r\n        if (propsSize > sd.Size)\r\n          return SZ_ERROR_ARCHIVE;\r\n        SKIP_DATA2(sd, propsSize);\r\n      }\r\n    }\r\n    \r\n    {\r\n      UInt32 indexOfMainStream = 0;\r\n      UInt32 numPackStreams = 1;\r\n      \r\n      if (numCoders != 1 || numInStreams != 1)\r\n      {\r\n        Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];\r\n        Byte coderUsed[k_Scan_NumCoders_MAX];\r\n    \r\n        UInt32 i;\r\n        UInt32 numBonds = numCoders - 1;\r\n        if (numInStreams < numBonds)\r\n          return SZ_ERROR_ARCHIVE;\r\n        \r\n        if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)\r\n          return SZ_ERROR_UNSUPPORTED;\r\n        \r\n        for (i = 0; i < numInStreams; i++)\r\n          streamUsed[i] = False;\r\n        for (i = 0; i < numCoders; i++)\r\n          coderUsed[i] = False;\r\n        \r\n        for (i = 0; i < numBonds; i++)\r\n        {\r\n          UInt32 index;\r\n          \r\n          RINOK(SzReadNumber32(&sd, &index));\r\n          if (index >= numInStreams || streamUsed[index])\r\n            return SZ_ERROR_ARCHIVE;\r\n          streamUsed[index] = True;\r\n          \r\n          RINOK(SzReadNumber32(&sd, &index));\r\n          if (index >= numCoders || coderUsed[index])\r\n            return SZ_ERROR_ARCHIVE;\r\n          coderUsed[index] = True;\r\n        }\r\n        \r\n        numPackStreams = numInStreams - numBonds;\r\n        \r\n        if (numPackStreams != 1)\r\n          for (i = 0; i < numPackStreams; i++)\r\n          {\r\n            UInt32 index;\r\n            RINOK(SzReadNumber32(&sd, &index));\r\n            if (index >= numInStreams || streamUsed[index])\r\n              return SZ_ERROR_ARCHIVE;\r\n            streamUsed[index] = True;\r\n          }\r\n          \r\n        for (i = 0; i < numCoders; i++)\r\n          if (!coderUsed[i])\r\n          {\r\n            indexOfMainStream = i;\r\n            break;\r\n          }\r\n \r\n        if (i == numCoders)\r\n          return SZ_ERROR_ARCHIVE;\r\n      }\r\n      \r\n      p->FoStartPackStreamIndex[fo] = packStreamIndex;\r\n      p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;\r\n      p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;\r\n      numCodersOutStreams += numCoders;\r\n      if (numCodersOutStreams < numCoders)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      if (numPackStreams > p->NumPackStreams - packStreamIndex)\r\n        return SZ_ERROR_ARCHIVE;\r\n      packStreamIndex += numPackStreams;\r\n    }\r\n  }\r\n\r\n  p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;\r\n  \r\n  {\r\n    size_t dataSize = sd.Data - startBufPtr;\r\n    p->FoStartPackStreamIndex[fo] = packStreamIndex;\r\n    p->FoCodersOffsets[fo] = dataSize;\r\n    MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);\r\n  }\r\n  \r\n  if (external != 0)\r\n  {\r\n    if (sd.Size != 0)\r\n      return SZ_ERROR_ARCHIVE;\r\n    sd = *sd2;\r\n  }\r\n  \r\n  RINOK(WaitId(&sd, k7zIdCodersUnpackSize));\r\n  \r\n  MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);\r\n  {\r\n    UInt32 i;\r\n    for (i = 0; i < numCodersOutStreams; i++)\r\n    {\r\n      RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));\r\n    }\r\n  }\r\n\r\n  for (;;)\r\n  {\r\n    UInt64 type;\r\n    RINOK(ReadID(&sd, &type));\r\n    if (type == k7zIdEnd)\r\n    {\r\n      *sd2 = sd;\r\n      return SZ_OK;\r\n    }\r\n    if (type == k7zIdCRC)\r\n    {\r\n      RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc));\r\n      continue;\r\n    }\r\n    RINOK(SkipData(&sd));\r\n  }\r\n}\r\n\r\n\r\nUInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)\r\n{\r\n  return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];\r\n}\r\n\r\n\r\ntypedef struct\r\n{\r\n  UInt32 NumTotalSubStreams;\r\n  UInt32 NumSubDigests;\r\n  CSzData sdNumSubStreams;\r\n  CSzData sdSizes;\r\n  CSzData sdCRCs;\r\n} CSubStreamInfo;\r\n\r\n\r\nstatic SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)\r\n{\r\n  UInt64 type = 0;\r\n  UInt32 numSubDigests = 0;\r\n  UInt32 numFolders = p->NumFolders;\r\n  UInt32 numUnpackStreams = numFolders;\r\n  UInt32 numUnpackSizesInData = 0;\r\n\r\n  for (;;)\r\n  {\r\n    RINOK(ReadID(sd, &type));\r\n    if (type == k7zIdNumUnpackStream)\r\n    {\r\n      UInt32 i;\r\n      ssi->sdNumSubStreams.Data = sd->Data;\r\n      numUnpackStreams = 0;\r\n      numSubDigests = 0;\r\n      for (i = 0; i < numFolders; i++)\r\n      {\r\n        UInt32 numStreams;\r\n        RINOK(SzReadNumber32(sd, &numStreams));\r\n        if (numUnpackStreams > numUnpackStreams + numStreams)\r\n          return SZ_ERROR_UNSUPPORTED;\r\n        numUnpackStreams += numStreams;\r\n        if (numStreams != 0)\r\n          numUnpackSizesInData += (numStreams - 1);\r\n        if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i))\r\n          numSubDigests += numStreams;\r\n      }\r\n      ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data;\r\n      continue;\r\n    }\r\n    if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd)\r\n      break;\r\n    RINOK(SkipData(sd));\r\n  }\r\n\r\n  if (!ssi->sdNumSubStreams.Data)\r\n  {\r\n    numSubDigests = numFolders;\r\n    if (p->FolderCRCs.Defs)\r\n      numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);\r\n  }\r\n  \r\n  ssi->NumTotalSubStreams = numUnpackStreams;\r\n  ssi->NumSubDigests = numSubDigests;\r\n\r\n  if (type == k7zIdSize)\r\n  {\r\n    ssi->sdSizes.Data = sd->Data;\r\n    RINOK(SkipNumbers(sd, numUnpackSizesInData));\r\n    ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data;\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n\r\n  for (;;)\r\n  {\r\n    if (type == k7zIdEnd)\r\n      return SZ_OK;\r\n    if (type == k7zIdCRC)\r\n    {\r\n      ssi->sdCRCs.Data = sd->Data;\r\n      RINOK(SkipBitUi32s(sd, numSubDigests));\r\n      ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data;\r\n    }\r\n    else\r\n    {\r\n      RINOK(SkipData(sd));\r\n    }\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n}\r\n\r\nstatic SRes SzReadStreamsInfo(CSzAr *p,\r\n    CSzData *sd,\r\n    UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,\r\n    UInt64 *dataOffset,\r\n    CSubStreamInfo *ssi,\r\n    ISzAlloc *alloc)\r\n{\r\n  UInt64 type;\r\n\r\n  SzData_Clear(&ssi->sdSizes);\r\n  SzData_Clear(&ssi->sdCRCs);\r\n  SzData_Clear(&ssi->sdNumSubStreams);\r\n\r\n  *dataOffset = 0;\r\n  RINOK(ReadID(sd, &type));\r\n  if (type == k7zIdPackInfo)\r\n  {\r\n    RINOK(ReadNumber(sd, dataOffset));\r\n    RINOK(ReadPackInfo(p, sd, alloc));\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n  if (type == k7zIdUnpackInfo)\r\n  {\r\n    RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc));\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n  if (type == k7zIdSubStreamsInfo)\r\n  {\r\n    RINOK(ReadSubStreamsInfo(p, sd, ssi));\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n  else\r\n  {\r\n    ssi->NumTotalSubStreams = p->NumFolders;\r\n    // ssi->NumSubDigests = 0;\r\n  }\r\n\r\n  return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED);\r\n}\r\n\r\nstatic SRes SzReadAndDecodePackedStreams(\r\n    ILookInStream *inStream,\r\n    CSzData *sd,\r\n    CBuf *tempBufs,\r\n    UInt32 numFoldersMax,\r\n    UInt64 baseOffset,\r\n    CSzAr *p,\r\n    ISzAlloc *allocTemp)\r\n{\r\n  UInt64 dataStartPos;\r\n  UInt32 fo;\r\n  CSubStreamInfo ssi;\r\n\r\n  RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));\r\n  \r\n  dataStartPos += baseOffset;\r\n  if (p->NumFolders == 0)\r\n    return SZ_ERROR_ARCHIVE;\r\n \r\n  for (fo = 0; fo < p->NumFolders; fo++)\r\n    Buf_Init(tempBufs + fo);\r\n  \r\n  for (fo = 0; fo < p->NumFolders; fo++)\r\n  {\r\n    CBuf *tempBuf = tempBufs + fo;\r\n    UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);\r\n    if ((size_t)unpackSize != unpackSize)\r\n      return SZ_ERROR_MEM;\r\n    if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))\r\n      return SZ_ERROR_MEM;\r\n  }\r\n  \r\n  for (fo = 0; fo < p->NumFolders; fo++)\r\n  {\r\n    const CBuf *tempBuf = tempBufs + fo;\r\n    RINOK(LookInStream_SeekTo(inStream, dataStartPos));\r\n    RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));\r\n  }\r\n  \r\n  return SZ_OK;\r\n}\r\n\r\nstatic SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)\r\n{\r\n  size_t pos = 0;\r\n  *offsets++ = 0;\r\n  if (numFiles == 0)\r\n    return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;\r\n  if (size < 2)\r\n    return SZ_ERROR_ARCHIVE;\r\n  if (data[size - 2] != 0 || data[size - 1] != 0)\r\n    return SZ_ERROR_ARCHIVE;\r\n  do\r\n  {\r\n    const Byte *p;\r\n    if (pos == size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    for (p = data + pos;\r\n      #ifdef _WIN32\r\n      *(const UInt16 *)p != 0\r\n      #else\r\n      p[0] != 0 || p[1] != 0\r\n      #endif\r\n      ; p += 2);\r\n    pos = p - data + 2;\r\n    *offsets++ = (pos >> 1);\r\n  }\r\n  while (--numFiles);\r\n  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;\r\n}\r\n\r\nstatic MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,\r\n    CSzData *sd2,\r\n    const CBuf *tempBufs, UInt32 numTempBufs,\r\n    ISzAlloc *alloc)\r\n{\r\n  CSzData sd;\r\n  UInt32 i;\r\n  CNtfsFileTime *vals;\r\n  Byte *defs;\r\n  Byte external;\r\n  \r\n  RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));\r\n  \r\n  SZ_READ_BYTE_SD(sd2, external);\r\n  if (external == 0)\r\n    sd = *sd2;\r\n  else\r\n  {\r\n    UInt32 index;\r\n    RINOK(SzReadNumber32(sd2, &index));\r\n    if (index >= numTempBufs)\r\n      return SZ_ERROR_ARCHIVE;\r\n    sd.Data = tempBufs[index].data;\r\n    sd.Size = tempBufs[index].size;\r\n  }\r\n  \r\n  MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);\r\n  vals = p->Vals;\r\n  defs = p->Defs;\r\n  for (i = 0; i < num; i++)\r\n    if (SzBitArray_Check(defs, i))\r\n    {\r\n      if (sd.Size < 8)\r\n        return SZ_ERROR_ARCHIVE;\r\n      vals[i].Low = GetUi32(sd.Data);\r\n      vals[i].High = GetUi32(sd.Data + 4);\r\n      SKIP_DATA2(sd, 8);\r\n    }\r\n    else\r\n      vals[i].High = vals[i].Low = 0;\r\n  \r\n  if (external == 0)\r\n    *sd2 = sd;\r\n  \r\n  return SZ_OK;\r\n}\r\n\r\n\r\n#define NUM_ADDITIONAL_STREAMS_MAX 8\r\n\r\n\r\nstatic SRes SzReadHeader2(\r\n    CSzArEx *p,   /* allocMain */\r\n    CSzData *sd,\r\n    ILookInStream *inStream,\r\n    CBuf *tempBufs, UInt32 *numTempBufs,\r\n    ISzAlloc *allocMain,\r\n    ISzAlloc *allocTemp\r\n    )\r\n{\r\n  CSubStreamInfo ssi;\r\n\r\n{\r\n  UInt64 type;\r\n  \r\n  SzData_Clear(&ssi.sdSizes);\r\n  SzData_Clear(&ssi.sdCRCs);\r\n  SzData_Clear(&ssi.sdNumSubStreams);\r\n\r\n  ssi.NumSubDigests = 0;\r\n  ssi.NumTotalSubStreams = 0;\r\n\r\n  RINOK(ReadID(sd, &type));\r\n\r\n  if (type == k7zIdArchiveProperties)\r\n  {\r\n    for (;;)\r\n    {\r\n      UInt64 type2;\r\n      RINOK(ReadID(sd, &type2));\r\n      if (type2 == k7zIdEnd)\r\n        break;\r\n      RINOK(SkipData(sd));\r\n    }\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n\r\n  if (type == k7zIdAdditionalStreamsInfo)\r\n  {\r\n    CSzAr tempAr;\r\n    SRes res;\r\n    \r\n    SzAr_Init(&tempAr);\r\n    res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,\r\n        p->startPosAfterHeader, &tempAr, allocTemp);\r\n    *numTempBufs = tempAr.NumFolders;\r\n    SzAr_Free(&tempAr, allocTemp);\r\n    \r\n    if (res != SZ_OK)\r\n      return res;\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n\r\n  if (type == k7zIdMainStreamsInfo)\r\n  {\r\n    RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs,\r\n        &p->dataPos, &ssi, allocMain));\r\n    p->dataPos += p->startPosAfterHeader;\r\n    RINOK(ReadID(sd, &type));\r\n  }\r\n\r\n  if (type == k7zIdEnd)\r\n  {\r\n    return SZ_OK;\r\n  }\r\n\r\n  if (type != k7zIdFilesInfo)\r\n    return SZ_ERROR_ARCHIVE;\r\n}\r\n\r\n{\r\n  UInt32 numFiles = 0;\r\n  UInt32 numEmptyStreams = 0;\r\n  const Byte *emptyStreams = NULL;\r\n  const Byte *emptyFiles = NULL;\r\n  \r\n  RINOK(SzReadNumber32(sd, &numFiles));\r\n  p->NumFiles = numFiles;\r\n\r\n  for (;;)\r\n  {\r\n    UInt64 type;\r\n    UInt64 size;\r\n    RINOK(ReadID(sd, &type));\r\n    if (type == k7zIdEnd)\r\n      break;\r\n    RINOK(ReadNumber(sd, &size));\r\n    if (size > sd->Size)\r\n      return SZ_ERROR_ARCHIVE;\r\n    \r\n    if (type >= ((UInt32)1 << 8))\r\n    {\r\n      SKIP_DATA(sd, size);\r\n    }\r\n    else switch ((unsigned)type)\r\n    {\r\n      case k7zIdName:\r\n      {\r\n        size_t namesSize;\r\n        const Byte *namesData;\r\n        Byte external;\r\n\r\n        SZ_READ_BYTE(external);\r\n        if (external == 0)\r\n        {\r\n          namesSize = (size_t)size - 1;\r\n          namesData = sd->Data;\r\n        }\r\n        else\r\n        {\r\n          UInt32 index;\r\n          RINOK(SzReadNumber32(sd, &index));\r\n          if (index >= *numTempBufs)\r\n            return SZ_ERROR_ARCHIVE;\r\n          namesData = (tempBufs)[index].data;\r\n          namesSize = (tempBufs)[index].size;\r\n        }\r\n\r\n        if ((namesSize & 1) != 0)\r\n          return SZ_ERROR_ARCHIVE;\r\n        MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);\r\n        MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain);\r\n        RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))\r\n        if (external == 0)\r\n        {\r\n          SKIP_DATA(sd, namesSize);\r\n        }\r\n        break;\r\n      }\r\n      case k7zIdEmptyStream:\r\n      {\r\n        RINOK(RememberBitVector(sd, numFiles, &emptyStreams));\r\n        numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);\r\n        emptyFiles = NULL;\r\n        break;\r\n      }\r\n      case k7zIdEmptyFile:\r\n      {\r\n        RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles));\r\n        break;\r\n      }\r\n      case k7zIdWinAttrib:\r\n      {\r\n        Byte external;\r\n        CSzData sdSwitch;\r\n        CSzData *sdPtr;\r\n        SzBitUi32s_Free(&p->Attribs, allocMain);\r\n        RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain));\r\n\r\n        SZ_READ_BYTE(external);\r\n        if (external == 0)\r\n          sdPtr = sd;\r\n        else\r\n        {\r\n          UInt32 index;\r\n          RINOK(SzReadNumber32(sd, &index));\r\n          if (index >= *numTempBufs)\r\n            return SZ_ERROR_ARCHIVE;\r\n          sdSwitch.Data = (tempBufs)[index].data;\r\n          sdSwitch.Size = (tempBufs)[index].size;\r\n          sdPtr = &sdSwitch;\r\n        }\r\n        RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain));\r\n        break;\r\n      }\r\n      /*\r\n      case k7zParent:\r\n      {\r\n        SzBitUi32s_Free(&p->Parents, allocMain);\r\n        RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain));\r\n        RINOK(SzReadSwitch(sd));\r\n        RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain));\r\n        break;\r\n      }\r\n      */\r\n      case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;\r\n      case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;\r\n      default:\r\n      {\r\n        SKIP_DATA(sd, size);\r\n      }\r\n    }\r\n  }\r\n\r\n  if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams)\r\n    return SZ_ERROR_ARCHIVE;\r\n\r\n  for (;;)\r\n  {\r\n    UInt64 type;\r\n    RINOK(ReadID(sd, &type));\r\n    if (type == k7zIdEnd)\r\n      break;\r\n    RINOK(SkipData(sd));\r\n  }\r\n\r\n  {\r\n    UInt32 i;\r\n    UInt32 emptyFileIndex = 0;\r\n    UInt32 folderIndex = 0;\r\n    UInt32 remSubStreams = 0;\r\n    UInt32 numSubStreams = 0;\r\n    UInt64 unpackPos = 0;\r\n    const Byte *digestsDefs = NULL;\r\n    const Byte *digestsVals = NULL;\r\n    UInt32 digestsValsIndex = 0;\r\n    UInt32 digestIndex;\r\n    Byte allDigestsDefined = 0;\r\n    Byte isDirMask = 0;\r\n    Byte crcMask = 0;\r\n    Byte mask = 0x80;\r\n    \r\n    MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);\r\n    MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);\r\n    MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);\r\n    MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);\r\n\r\n    RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));\r\n\r\n    if (ssi.sdCRCs.Size != 0)\r\n    {\r\n      SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);\r\n      if (allDigestsDefined)\r\n        digestsVals = ssi.sdCRCs.Data;\r\n      else\r\n      {\r\n        size_t numBytes = (ssi.NumSubDigests + 7) >> 3;\r\n        digestsDefs = ssi.sdCRCs.Data;\r\n        digestsVals = digestsDefs + numBytes;\r\n      }\r\n    }\r\n\r\n    digestIndex = 0;\r\n    \r\n    for (i = 0; i < numFiles; i++, mask >>= 1)\r\n    {\r\n      if (mask == 0)\r\n      {\r\n        UInt32 byteIndex = (i - 1) >> 3;\r\n        p->IsDirs[byteIndex] = isDirMask;\r\n        p->CRCs.Defs[byteIndex] = crcMask;\r\n        isDirMask = 0;\r\n        crcMask = 0;\r\n        mask = 0x80;\r\n      }\r\n\r\n      p->UnpackPositions[i] = unpackPos;\r\n      p->CRCs.Vals[i] = 0;\r\n      \r\n      if (emptyStreams && SzBitArray_Check(emptyStreams, i))\r\n      {\r\n        if (emptyFiles)\r\n        {\r\n          if (!SzBitArray_Check(emptyFiles, emptyFileIndex))\r\n            isDirMask |= mask;\r\n          emptyFileIndex++;\r\n        }\r\n        else\r\n          isDirMask |= mask;\r\n        if (remSubStreams == 0)\r\n        {\r\n          p->FileToFolder[i] = (UInt32)-1;\r\n          continue;\r\n        }\r\n      }\r\n      \r\n      if (remSubStreams == 0)\r\n      {\r\n        for (;;)\r\n        {\r\n          if (folderIndex >= p->db.NumFolders)\r\n            return SZ_ERROR_ARCHIVE;\r\n          p->FolderToFile[folderIndex] = i;\r\n          numSubStreams = 1;\r\n          if (ssi.sdNumSubStreams.Data)\r\n          {\r\n            RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));\r\n          }\r\n          remSubStreams = numSubStreams;\r\n          if (numSubStreams != 0)\r\n            break;\r\n          {\r\n            UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);\r\n            unpackPos += folderUnpackSize;\r\n            if (unpackPos < folderUnpackSize)\r\n              return SZ_ERROR_ARCHIVE;\r\n          }\r\n\r\n          folderIndex++;\r\n        }\r\n      }\r\n      \r\n      p->FileToFolder[i] = folderIndex;\r\n      \r\n      if (emptyStreams && SzBitArray_Check(emptyStreams, i))\r\n        continue;\r\n      \r\n      if (--remSubStreams == 0)\r\n      {\r\n        UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);\r\n        UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];\r\n        if (folderUnpackSize < unpackPos - startFolderUnpackPos)\r\n          return SZ_ERROR_ARCHIVE;\r\n        unpackPos = startFolderUnpackPos + folderUnpackSize;\r\n        if (unpackPos < folderUnpackSize)\r\n          return SZ_ERROR_ARCHIVE;\r\n\r\n        if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))\r\n        {\r\n          p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];\r\n          crcMask |= mask;\r\n        }\r\n        else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))\r\n        {\r\n          p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);\r\n          digestsValsIndex++;\r\n          crcMask |= mask;\r\n        }\r\n        \r\n        folderIndex++;\r\n      }\r\n      else\r\n      {\r\n        UInt64 v;\r\n        RINOK(ReadNumber(&ssi.sdSizes, &v));\r\n        unpackPos += v;\r\n        if (unpackPos < v)\r\n          return SZ_ERROR_ARCHIVE;\r\n        if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))\r\n        {\r\n          p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);\r\n          digestsValsIndex++;\r\n          crcMask |= mask;\r\n        }\r\n      }\r\n    }\r\n\r\n    if (mask != 0x80)\r\n    {\r\n      UInt32 byteIndex = (i - 1) >> 3;\r\n      p->IsDirs[byteIndex] = isDirMask;\r\n      p->CRCs.Defs[byteIndex] = crcMask;\r\n    }\r\n    \r\n    p->UnpackPositions[i] = unpackPos;\r\n\r\n    if (remSubStreams != 0)\r\n      return SZ_ERROR_ARCHIVE;\r\n\r\n    for (;;)\r\n    {\r\n      p->FolderToFile[folderIndex] = i;\r\n      if (folderIndex >= p->db.NumFolders)\r\n        break;\r\n      if (!ssi.sdNumSubStreams.Data)\r\n        return SZ_ERROR_ARCHIVE;\r\n      RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));\r\n      if (numSubStreams != 0)\r\n        return SZ_ERROR_ARCHIVE;\r\n      /*\r\n      {\r\n        UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);\r\n        unpackPos += folderUnpackSize;\r\n        if (unpackPos < folderUnpackSize)\r\n          return SZ_ERROR_ARCHIVE;\r\n      }\r\n      */\r\n      folderIndex++;\r\n    }\r\n\r\n    if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)\r\n      return SZ_ERROR_ARCHIVE;\r\n  }\r\n}\r\n  return SZ_OK;\r\n}\r\n\r\n\r\nstatic SRes SzReadHeader(\r\n    CSzArEx *p,\r\n    CSzData *sd,\r\n    ILookInStream *inStream,\r\n    ISzAlloc *allocMain,\r\n    ISzAlloc *allocTemp)\r\n{\r\n  UInt32 i;\r\n  UInt32 numTempBufs = 0;\r\n  SRes res;\r\n  CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];\r\n\r\n  for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)\r\n    Buf_Init(tempBufs + i);\r\n  \r\n  res = SzReadHeader2(p, sd, inStream,\r\n      tempBufs, &numTempBufs,\r\n      allocMain, allocTemp);\r\n  \r\n  for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)\r\n    Buf_Free(tempBufs + i, allocTemp);\r\n\r\n  RINOK(res);\r\n\r\n  if (sd->Size != 0)\r\n    return SZ_ERROR_FAIL;\r\n\r\n  return res;\r\n}\r\n\r\nstatic SRes SzArEx_Open2(\r\n    CSzArEx *p,\r\n    ILookInStream *inStream,\r\n    ISzAlloc *allocMain,\r\n    ISzAlloc *allocTemp)\r\n{\r\n  Byte header[k7zStartHeaderSize];\r\n  Int64 startArcPos;\r\n  UInt64 nextHeaderOffset, nextHeaderSize;\r\n  size_t nextHeaderSizeT;\r\n  UInt32 nextHeaderCRC;\r\n  CBuf buf;\r\n  SRes res;\r\n\r\n  startArcPos = 0;\r\n  RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));\r\n\r\n  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));\r\n\r\n  if (!TestSignatureCandidate(header))\r\n    return SZ_ERROR_NO_ARCHIVE;\r\n  if (header[6] != k7zMajorVersion)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n\r\n  nextHeaderOffset = GetUi64(header + 12);\r\n  nextHeaderSize = GetUi64(header + 20);\r\n  nextHeaderCRC = GetUi32(header + 28);\r\n\r\n  p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;\r\n  \r\n  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))\r\n    return SZ_ERROR_CRC;\r\n\r\n  nextHeaderSizeT = (size_t)nextHeaderSize;\r\n  if (nextHeaderSizeT != nextHeaderSize)\r\n    return SZ_ERROR_MEM;\r\n  if (nextHeaderSizeT == 0)\r\n    return SZ_OK;\r\n  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||\r\n      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)\r\n    return SZ_ERROR_NO_ARCHIVE;\r\n\r\n  {\r\n    Int64 pos = 0;\r\n    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));\r\n    if ((UInt64)pos < startArcPos + nextHeaderOffset ||\r\n        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||\r\n        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)\r\n      return SZ_ERROR_INPUT_EOF;\r\n  }\r\n\r\n  RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));\r\n\r\n  if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))\r\n    return SZ_ERROR_MEM;\r\n\r\n  res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);\r\n  \r\n  if (res == SZ_OK)\r\n  {\r\n    res = SZ_ERROR_ARCHIVE;\r\n    if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC)\r\n    {\r\n      CSzData sd;\r\n      UInt64 type;\r\n      sd.Data = buf.data;\r\n      sd.Size = buf.size;\r\n      \r\n      res = ReadID(&sd, &type);\r\n      \r\n      if (res == SZ_OK && type == k7zIdEncodedHeader)\r\n      {\r\n        CSzAr tempAr;\r\n        CBuf tempBuf;\r\n        Buf_Init(&tempBuf);\r\n        \r\n        SzAr_Init(&tempAr);\r\n        res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp);\r\n        SzAr_Free(&tempAr, allocTemp);\r\n       \r\n        if (res != SZ_OK)\r\n        {\r\n          Buf_Free(&tempBuf, allocTemp);\r\n        }\r\n        else\r\n        {\r\n          Buf_Free(&buf, allocTemp);\r\n          buf.data = tempBuf.data;\r\n          buf.size = tempBuf.size;\r\n          sd.Data = buf.data;\r\n          sd.Size = buf.size;\r\n          res = ReadID(&sd, &type);\r\n        }\r\n      }\r\n  \r\n      if (res == SZ_OK)\r\n      {\r\n        if (type == k7zIdHeader)\r\n        {\r\n          /*\r\n          CSzData sd2;\r\n          unsigned ttt;\r\n          for (ttt = 0; ttt < 40000; ttt++)\r\n          {\r\n            SzArEx_Free(p, allocMain);\r\n            sd2 = sd;\r\n            res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);\r\n            if (res != SZ_OK)\r\n              break;\r\n          }\r\n          */\r\n          res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);\r\n        }\r\n        else\r\n          res = SZ_ERROR_UNSUPPORTED;\r\n      }\r\n    }\r\n  }\r\n \r\n  Buf_Free(&buf, allocTemp);\r\n  return res;\r\n}\r\n\r\n\r\nSRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,\r\n    ISzAlloc *allocMain, ISzAlloc *allocTemp)\r\n{\r\n  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);\r\n  if (res != SZ_OK)\r\n    SzArEx_Free(p, allocMain);\r\n  return res;\r\n}\r\n\r\n\r\nSRes SzArEx_Extract(\r\n    const CSzArEx *p,\r\n    ILookInStream *inStream,\r\n    UInt32 fileIndex,\r\n    UInt32 *blockIndex,\r\n    Byte **tempBuf,\r\n    size_t *outBufferSize,\r\n    size_t *offset,\r\n    size_t *outSizeProcessed,\r\n    ISzAlloc *allocMain,\r\n    ISzAlloc *allocTemp)\r\n{\r\n  UInt32 folderIndex = p->FileToFolder[fileIndex];\r\n  SRes res = SZ_OK;\r\n  \r\n  *offset = 0;\r\n  *outSizeProcessed = 0;\r\n  \r\n  if (folderIndex == (UInt32)-1)\r\n  {\r\n    IAlloc_Free(allocMain, *tempBuf);\r\n    *blockIndex = folderIndex;\r\n    *tempBuf = NULL;\r\n    *outBufferSize = 0;\r\n    return SZ_OK;\r\n  }\r\n\r\n  if (*tempBuf == NULL || *blockIndex != folderIndex)\r\n  {\r\n    UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);\r\n    /*\r\n    UInt64 unpackSizeSpec =\r\n        p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -\r\n        p->UnpackPositions[p->FolderToFile[folderIndex]];\r\n    */\r\n    size_t unpackSize = (size_t)unpackSizeSpec;\r\n\r\n    if (unpackSize != unpackSizeSpec)\r\n      return SZ_ERROR_MEM;\r\n    *blockIndex = folderIndex;\r\n    IAlloc_Free(allocMain, *tempBuf);\r\n    *tempBuf = NULL;\r\n    \r\n    if (res == SZ_OK)\r\n    {\r\n      *outBufferSize = unpackSize;\r\n      if (unpackSize != 0)\r\n      {\r\n        *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);\r\n        if (*tempBuf == NULL)\r\n          res = SZ_ERROR_MEM;\r\n      }\r\n  \r\n      if (res == SZ_OK)\r\n      {\r\n        res = SzAr_DecodeFolder(&p->db, folderIndex,\r\n            inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);\r\n      }\r\n    }\r\n  }\r\n\r\n  if (res == SZ_OK)\r\n  {\r\n    UInt64 unpackPos = p->UnpackPositions[fileIndex];\r\n    *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);\r\n    *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);\r\n    if (*offset + *outSizeProcessed > *outBufferSize)\r\n      return SZ_ERROR_FAIL;\r\n    if (SzBitWithVals_Check(&p->CRCs, fileIndex))\r\n      if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])\r\n        res = SZ_ERROR_CRC;\r\n  }\r\n\r\n  return res;\r\n}\r\n\r\n\r\nsize_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)\r\n{\r\n  size_t offs = p->FileNameOffsets[fileIndex];\r\n  size_t len = p->FileNameOffsets[fileIndex + 1] - offs;\r\n  if (dest != 0)\r\n  {\r\n    size_t i;\r\n    const Byte *src = p->FileNames + offs * 2;\r\n    for (i = 0; i < len; i++)\r\n      dest[i] = GetUi16(src + i * 2);\r\n  }\r\n  return len;\r\n}\r\n\r\n/*\r\nsize_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)\r\n{\r\n  size_t len;\r\n  if (!p->FileNameOffsets)\r\n    return 1;\r\n  len = 0;\r\n  for (;;)\r\n  {\r\n    UInt32 parent = (UInt32)(Int32)-1;\r\n    len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];\r\n    if SzBitWithVals_Check(&p->Parents, fileIndex)\r\n      parent = p->Parents.Vals[fileIndex];\r\n    if (parent == (UInt32)(Int32)-1)\r\n      return len;\r\n    fileIndex = parent;\r\n  }\r\n}\r\n\r\nUInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)\r\n{\r\n  Bool needSlash;\r\n  if (!p->FileNameOffsets)\r\n  {\r\n    *(--dest) = 0;\r\n    return dest;\r\n  }\r\n  needSlash = False;\r\n  for (;;)\r\n  {\r\n    UInt32 parent = (UInt32)(Int32)-1;\r\n    size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];\r\n    SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen);\r\n    if (needSlash)\r\n      *(dest - 1) = '/';\r\n    needSlash = True;\r\n    dest -= curLen;\r\n\r\n    if SzBitWithVals_Check(&p->Parents, fileIndex)\r\n      parent = p->Parents.Vals[fileIndex];\r\n    if (parent == (UInt32)(Int32)-1)\r\n      return dest;\r\n    fileIndex = parent;\r\n  }\r\n}\r\n*/\r\n"
  },
  {
    "path": "thirdparty/patch/p7zip/7zBuf.c",
    "content": "/* 7zBuf.c -- Byte Buffer\r\n2013-01-21 : Igor Pavlov : Public domain */\r\n\r\n#include \"Precomp.h\"\r\n\r\n#include \"7zBuf.h\"\r\n\r\nvoid Buf_Init(CBuf *p)\r\n{\r\n  p->data = 0;\r\n  p->size = 0;\r\n}\r\n\r\nint Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)\r\n{\r\n  p->size = 0;\r\n  if (size == 0)\r\n  {\r\n    p->data = 0;\r\n    return 1;\r\n  }\r\n  p->data = (Byte *)alloc->Alloc(alloc, size);\r\n  if (p->data != 0)\r\n  {\r\n    p->size = size;\r\n    return 1;\r\n  }\r\n  return 0;\r\n}\r\n\r\nvoid Buf_Free(CBuf *p, ISzAlloc *alloc)\r\n{\r\n  alloc->Free(alloc, p->data);\r\n  p->data = 0;\r\n  p->size = 0;\r\n}\r\n"
  },
  {
    "path": "thirdparty/patch/p7zip/7zDec.c",
    "content": "/* 7zDec.c -- Decoding from 7z folder\r\n2015-11-18 : Igor Pavlov : Public domain */\r\n\r\n#include \"Precomp.h\"\r\n\r\n#include <string.h>\r\n\r\n/* #define _7ZIP_PPMD_SUPPPORT */\r\n\r\n#include \"7z.h\"\r\n#include \"7zCrc.h\"\r\n\r\n#include \"Bcj2.h\"\r\n#include \"Bra.h\"\r\n#include \"CpuArch.h\"\r\n#include \"Delta.h\"\r\n#include \"LzmaDec.h\"\r\n#include \"Lzma2Dec.h\"\r\n#ifdef _7ZIP_PPMD_SUPPPORT\r\n#include \"Ppmd7.h\"\r\n#endif\r\n\r\n#define k_Copy 0\r\n#define k_Delta 3\r\n#define k_LZMA2 0x21\r\n#define k_LZMA  0x30101\r\n#define k_BCJ   0x3030103\r\n#define k_BCJ2  0x303011B\r\n#define k_PPC   0x3030205\r\n#define k_IA64  0x3030401\r\n#define k_ARM   0x3030501\r\n#define k_ARMT  0x3030701\r\n#define k_SPARC 0x3030805\r\n\r\n\r\n#ifdef _7ZIP_PPMD_SUPPPORT\r\n\r\n#define k_PPMD 0x30401\r\n\r\ntypedef struct\r\n{\r\n  IByteIn p;\r\n  const Byte *cur;\r\n  const Byte *end;\r\n  const Byte *begin;\r\n  UInt64 processed;\r\n  Bool extra;\r\n  SRes res;\r\n  ILookInStream *inStream;\r\n} CByteInToLook;\r\n\r\nstatic Byte ReadByte(void *pp)\r\n{\r\n  CByteInToLook *p = (CByteInToLook *)pp;\r\n  if (p->cur != p->end)\r\n    return *p->cur++;\r\n  if (p->res == SZ_OK)\r\n  {\r\n    size_t size = p->cur - p->begin;\r\n    p->processed += size;\r\n    p->res = p->inStream->Skip(p->inStream, size);\r\n    size = (1 << 25);\r\n    p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);\r\n    p->cur = p->begin;\r\n    p->end = p->begin + size;\r\n    if (size != 0)\r\n      return *p->cur++;;\r\n  }\r\n  p->extra = True;\r\n  return 0;\r\n}\r\n\r\nstatic SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,\r\n    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r\n{\r\n  CPpmd7 ppmd;\r\n  CByteInToLook s;\r\n  SRes res = SZ_OK;\r\n\r\n  s.p.Read = ReadByte;\r\n  s.inStream = inStream;\r\n  s.begin = s.end = s.cur = NULL;\r\n  s.extra = False;\r\n  s.res = SZ_OK;\r\n  s.processed = 0;\r\n\r\n  if (propsSize != 5)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n\r\n  {\r\n    unsigned order = props[0];\r\n    UInt32 memSize = GetUi32(props + 1);\r\n    if (order < PPMD7_MIN_ORDER ||\r\n        order > PPMD7_MAX_ORDER ||\r\n        memSize < PPMD7_MIN_MEM_SIZE ||\r\n        memSize > PPMD7_MAX_MEM_SIZE)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    Ppmd7_Construct(&ppmd);\r\n    if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))\r\n      return SZ_ERROR_MEM;\r\n    Ppmd7_Init(&ppmd, order);\r\n  }\r\n  {\r\n    CPpmd7z_RangeDec rc;\r\n    Ppmd7z_RangeDec_CreateVTable(&rc);\r\n    rc.Stream = &s.p;\r\n    if (!Ppmd7z_RangeDec_Init(&rc))\r\n      res = SZ_ERROR_DATA;\r\n    else if (s.extra)\r\n      res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);\r\n    else\r\n    {\r\n      SizeT i;\r\n      for (i = 0; i < outSize; i++)\r\n      {\r\n        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);\r\n        if (s.extra || sym < 0)\r\n          break;\r\n        outBuffer[i] = (Byte)sym;\r\n      }\r\n      if (i != outSize)\r\n        res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);\r\n      else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))\r\n        res = SZ_ERROR_DATA;\r\n    }\r\n  }\r\n  Ppmd7_Free(&ppmd, allocMain);\r\n  return res;\r\n}\r\n\r\n#endif\r\n\r\n\r\nstatic SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,\r\n    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r\n{\r\n  CLzmaDec state;\r\n  SRes res = SZ_OK;\r\n\r\n  LzmaDec_Construct(&state);\r\n  RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));\r\n  state.dic = outBuffer;\r\n  state.dicBufSize = outSize;\r\n  LzmaDec_Init(&state);\r\n\r\n  for (;;)\r\n  {\r\n    const void *inBuf = NULL;\r\n    size_t lookahead = (1 << 18);\r\n    if (lookahead > inSize)\r\n      lookahead = (size_t)inSize;\r\n    res = inStream->Look(inStream, &inBuf, &lookahead);\r\n    if (res != SZ_OK)\r\n      break;\r\n\r\n    {\r\n      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;\r\n      ELzmaStatus status;\r\n      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);\r\n      lookahead -= inProcessed;\r\n      inSize -= inProcessed;\r\n      if (res != SZ_OK)\r\n        break;\r\n\r\n      if (status == LZMA_STATUS_FINISHED_WITH_MARK)\r\n      {\r\n        if (outSize != state.dicPos || inSize != 0)\r\n          res = SZ_ERROR_DATA;\r\n        break;\r\n      }\r\n\r\n      if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)\r\n        break;\r\n\r\n      if (inProcessed == 0 && dicPos == state.dicPos)\r\n      {\r\n        res = SZ_ERROR_DATA;\r\n        break;\r\n      }\r\n\r\n      res = inStream->Skip((void *)inStream, inProcessed);\r\n      if (res != SZ_OK)\r\n        break;\r\n    }\r\n  }\r\n\r\n  LzmaDec_FreeProbs(&state, allocMain);\r\n  return res;\r\n}\r\n\r\n\r\n#ifndef _7Z_NO_METHOD_LZMA2\r\n\r\nstatic SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,\r\n    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r\n{\r\n  CLzma2Dec state;\r\n  SRes res = SZ_OK;\r\n\r\n  Lzma2Dec_Construct(&state);\r\n  if (propsSize != 1)\r\n    return SZ_ERROR_DATA;\r\n  RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));\r\n  state.decoder.dic = outBuffer;\r\n  state.decoder.dicBufSize = outSize;\r\n  Lzma2Dec_Init(&state);\r\n\r\n  for (;;)\r\n  {\r\n    const void *inBuf = NULL;\r\n    size_t lookahead = (1 << 18);\r\n    if (lookahead > inSize)\r\n      lookahead = (size_t)inSize;\r\n    res = inStream->Look(inStream, &inBuf, &lookahead);\r\n    if (res != SZ_OK)\r\n      break;\r\n\r\n    {\r\n      SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;\r\n      ELzmaStatus status;\r\n      res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);\r\n      lookahead -= inProcessed;\r\n      inSize -= inProcessed;\r\n      if (res != SZ_OK)\r\n        break;\r\n\r\n      if (status == LZMA_STATUS_FINISHED_WITH_MARK)\r\n      {\r\n        if (outSize != state.decoder.dicPos || inSize != 0)\r\n          res = SZ_ERROR_DATA;\r\n        break;\r\n      }\r\n\r\n      if (inProcessed == 0 && dicPos == state.decoder.dicPos)\r\n      {\r\n        res = SZ_ERROR_DATA;\r\n        break;\r\n      }\r\n\r\n      res = inStream->Skip((void *)inStream, inProcessed);\r\n      if (res != SZ_OK)\r\n        break;\r\n    }\r\n  }\r\n\r\n  Lzma2Dec_FreeProbs(&state, allocMain);\r\n  return res;\r\n}\r\n\r\n#endif\r\n\r\n\r\nstatic SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)\r\n{\r\n  while (inSize > 0)\r\n  {\r\n    const void *inBuf;\r\n    size_t curSize = (1 << 18);\r\n    if (curSize > inSize)\r\n      curSize = (size_t)inSize;\r\n    RINOK(inStream->Look(inStream, &inBuf, &curSize));\r\n    if (curSize == 0)\r\n      return SZ_ERROR_INPUT_EOF;\r\n    memcpy(outBuffer, inBuf, curSize);\r\n    outBuffer += curSize;\r\n    inSize -= curSize;\r\n    RINOK(inStream->Skip((void *)inStream, curSize));\r\n  }\r\n  return SZ_OK;\r\n}\r\n\r\nstatic Bool IS_MAIN_METHOD(UInt32 m)\r\n{\r\n  switch (m)\r\n  {\r\n    case k_Copy:\r\n    case k_LZMA:\r\n    #ifndef _7Z_NO_METHOD_LZMA2\r\n    case k_LZMA2:\r\n    #endif\r\n    #ifdef _7ZIP_PPMD_SUPPPORT\r\n    case k_PPMD:\r\n    #endif\r\n      return True;\r\n  }\r\n  return False;\r\n}\r\n\r\nstatic Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)\r\n{\r\n  return\r\n      c->NumStreams == 1\r\n      /* && c->MethodID <= (UInt32)0xFFFFFFFF */\r\n      && IS_MAIN_METHOD((UInt32)c->MethodID);\r\n}\r\n\r\n#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)\r\n\r\nstatic SRes CheckSupportedFolder(const CSzFolder *f)\r\n{\r\n  if (f->NumCoders < 1 || f->NumCoders > 4)\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  if (!IS_SUPPORTED_CODER(&f->Coders[0]))\r\n    return SZ_ERROR_UNSUPPORTED;\r\n  if (f->NumCoders == 1)\r\n  {\r\n    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    return SZ_OK;\r\n  }\r\n  \r\n  \r\n  #ifndef _7Z_NO_METHODS_FILTERS\r\n\r\n  if (f->NumCoders == 2)\r\n  {\r\n    const CSzCoderInfo *c = &f->Coders[1];\r\n    if (\r\n        /* c->MethodID > (UInt32)0xFFFFFFFF || */\r\n        c->NumStreams != 1\r\n        || f->NumPackStreams != 1\r\n        || f->PackStreams[0] != 0\r\n        || f->NumBonds != 1\r\n        || f->Bonds[0].InIndex != 1\r\n        || f->Bonds[0].OutIndex != 0)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    switch ((UInt32)c->MethodID)\r\n    {\r\n      case k_Delta:\r\n      case k_BCJ:\r\n      case k_PPC:\r\n      case k_IA64:\r\n      case k_SPARC:\r\n      case k_ARM:\r\n      case k_ARMT:\r\n        break;\r\n      default:\r\n        return SZ_ERROR_UNSUPPORTED;\r\n    }\r\n    return SZ_OK;\r\n  }\r\n\r\n  #endif\r\n\r\n  \r\n  if (f->NumCoders == 4)\r\n  {\r\n    if (!IS_SUPPORTED_CODER(&f->Coders[1])\r\n        || !IS_SUPPORTED_CODER(&f->Coders[2])\r\n        || !IS_BCJ2(&f->Coders[3]))\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    if (f->NumPackStreams != 4\r\n        || f->PackStreams[0] != 2\r\n        || f->PackStreams[1] != 6\r\n        || f->PackStreams[2] != 1\r\n        || f->PackStreams[3] != 0\r\n        || f->NumBonds != 3\r\n        || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0\r\n        || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1\r\n        || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)\r\n      return SZ_ERROR_UNSUPPORTED;\r\n    return SZ_OK;\r\n  }\r\n  \r\n  return SZ_ERROR_UNSUPPORTED;\r\n}\r\n\r\n#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;\r\n\r\nstatic SRes SzFolder_Decode2(const CSzFolder *folder,\r\n    const Byte *propsData,\r\n    const UInt64 *unpackSizes,\r\n    const UInt64 *packPositions,\r\n    ILookInStream *inStream, UInt64 startPos,\r\n    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,\r\n    Byte *tempBuf[])\r\n{\r\n  UInt32 ci;\r\n  SizeT tempSizes[3] = { 0, 0, 0};\r\n  SizeT tempSize3 = 0;\r\n  Byte *tempBuf3 = 0;\r\n\r\n  RINOK(CheckSupportedFolder(folder));\r\n\r\n  for (ci = 0; ci < folder->NumCoders; ci++)\r\n  {\r\n    const CSzCoderInfo *coder = &folder->Coders[ci];\r\n\r\n    if (IS_MAIN_METHOD((UInt32)coder->MethodID))\r\n    {\r\n      UInt32 si = 0;\r\n      UInt64 offset;\r\n      UInt64 inSize;\r\n      Byte *outBufCur = outBuffer;\r\n      SizeT outSizeCur = outSize;\r\n      if (folder->NumCoders == 4)\r\n      {\r\n        UInt32 indices[] = { 3, 2, 0 };\r\n        UInt64 unpackSize = unpackSizes[ci];\r\n        si = indices[ci];\r\n        if (ci < 2)\r\n        {\r\n          Byte *temp;\r\n          outSizeCur = (SizeT)unpackSize;\r\n          if (outSizeCur != unpackSize)\r\n            return SZ_ERROR_MEM;\r\n          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);\r\n          if (!temp && outSizeCur != 0)\r\n            return SZ_ERROR_MEM;\r\n          outBufCur = tempBuf[1 - ci] = temp;\r\n          tempSizes[1 - ci] = outSizeCur;\r\n        }\r\n        else if (ci == 2)\r\n        {\r\n          if (unpackSize > outSize) /* check it */\r\n            return SZ_ERROR_PARAM;\r\n          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);\r\n          tempSize3 = outSizeCur = (SizeT)unpackSize;\r\n        }\r\n        else\r\n          return SZ_ERROR_UNSUPPORTED;\r\n      }\r\n      offset = packPositions[si];\r\n      inSize = packPositions[si + 1] - offset;\r\n      RINOK(LookInStream_SeekTo(inStream, startPos + offset));\r\n\r\n      if (coder->MethodID == k_Copy)\r\n      {\r\n        if (inSize != outSizeCur) /* check it */\r\n          return SZ_ERROR_DATA;\r\n        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));\r\n      }\r\n      else if (coder->MethodID == k_LZMA)\r\n      {\r\n        RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));\r\n      }\r\n      #ifndef _7Z_NO_METHOD_LZMA2\r\n      else if (coder->MethodID == k_LZMA2)\r\n      {\r\n        RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));\r\n      }\r\n      #endif\r\n      #ifdef _7ZIP_PPMD_SUPPPORT\r\n      else if (coder->MethodID == k_PPMD)\r\n      {\r\n        RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));\r\n      }\r\n      #endif\r\n      else\r\n        return SZ_ERROR_UNSUPPORTED;\r\n    }\r\n    else if (coder->MethodID == k_BCJ2)\r\n    {\r\n      UInt64 offset = packPositions[1];\r\n      UInt64 s3Size = packPositions[2] - offset;\r\n      \r\n      if (ci != 3)\r\n        return SZ_ERROR_UNSUPPORTED;\r\n      \r\n      tempSizes[2] = (SizeT)s3Size;\r\n      if (tempSizes[2] != s3Size)\r\n        return SZ_ERROR_MEM;\r\n      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);\r\n      if (!tempBuf[2] && tempSizes[2] != 0)\r\n        return SZ_ERROR_MEM;\r\n      \r\n      RINOK(LookInStream_SeekTo(inStream, startPos + offset));\r\n      RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));\r\n\r\n      if ((tempSizes[0] & 3) != 0 ||\r\n          (tempSizes[1] & 3) != 0 ||\r\n          tempSize3 + tempSizes[0] + tempSizes[1] != outSize)\r\n        return SZ_ERROR_DATA;\r\n\r\n      {\r\n        CBcj2Dec p;\r\n        \r\n        p.bufs[0] = tempBuf3;   p.lims[0] = tempBuf3 + tempSize3;\r\n        p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];\r\n        p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];\r\n        p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];\r\n        \r\n        p.dest = outBuffer;\r\n        p.destLim = outBuffer + outSize;\r\n        \r\n        Bcj2Dec_Init(&p);\r\n        RINOK(Bcj2Dec_Decode(&p));\r\n\r\n        {\r\n          unsigned i;\r\n          for (i = 0; i < 4; i++)\r\n            if (p.bufs[i] != p.lims[i])\r\n              return SZ_ERROR_DATA;\r\n          \r\n          if (!Bcj2Dec_IsFinished(&p))\r\n            return SZ_ERROR_DATA;\r\n\r\n          if (p.dest != p.destLim\r\n             || p.state != BCJ2_STREAM_MAIN)\r\n            return SZ_ERROR_DATA;\r\n        }\r\n      }\r\n    }\r\n    #ifndef _7Z_NO_METHODS_FILTERS\r\n    else if (ci == 1)\r\n    {\r\n      if (coder->MethodID == k_Delta)\r\n      {\r\n        if (coder->PropsSize != 1)\r\n          return SZ_ERROR_UNSUPPORTED;\r\n        {\r\n          Byte state[DELTA_STATE_SIZE];\r\n          Delta_Init(state);\r\n          Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);\r\n        }\r\n      }\r\n      else\r\n      {\r\n        if (coder->PropsSize != 0)\r\n          return SZ_ERROR_UNSUPPORTED;\r\n        switch (coder->MethodID)\r\n        {\r\n          case k_BCJ:\r\n          {\r\n            UInt32 state;\r\n            x86_Convert_Init(state);\r\n            x86_Convert(outBuffer, outSize, 0, &state, 0);\r\n            break;\r\n          }\r\n          CASE_BRA_CONV(PPC)\r\n          CASE_BRA_CONV(IA64)\r\n          CASE_BRA_CONV(SPARC)\r\n          CASE_BRA_CONV(ARM)\r\n          CASE_BRA_CONV(ARMT)\r\n          default:\r\n            return SZ_ERROR_UNSUPPORTED;\r\n        }\r\n      }\r\n    }\r\n    #endif\r\n    else\r\n      return SZ_ERROR_UNSUPPORTED;\r\n  }\r\n\r\n  return SZ_OK;\r\n}\r\n\r\n\r\nSRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,\r\n    ILookInStream *inStream, UInt64 startPos,\r\n    Byte *outBuffer, size_t outSize,\r\n    ISzAlloc *allocMain)\r\n{\r\n  SRes res;\r\n  CSzFolder folder;\r\n  CSzData sd;\r\n  \r\n  const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];\r\n  sd.Data = data;\r\n  sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];\r\n  \r\n  res = SzGetNextFolderItem(&folder, &sd);\r\n  \r\n  if (res != SZ_OK)\r\n    return res;\r\n\r\n  if (sd.Size != 0\r\n      || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]\r\n      || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))\r\n    return SZ_ERROR_FAIL;\r\n  {\r\n    unsigned i;\r\n    Byte *tempBuf[3] = { 0, 0, 0};\r\n\r\n    res = SzFolder_Decode2(&folder, data,\r\n        &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],\r\n        p->PackPositions + p->FoStartPackStreamIndex[folderIndex],\r\n        inStream, startPos,\r\n        outBuffer, (SizeT)outSize, allocMain, tempBuf);\r\n    \r\n    for (i = 0; i < 3; i++)\r\n      IAlloc_Free(allocMain, tempBuf[i]);\r\n\r\n    if (res == SZ_OK)\r\n      if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))\r\n        if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])\r\n          res = SZ_ERROR_CRC;\r\n\r\n    return res;\r\n  }\r\n}\r\n"
  },
  {
    "path": "thirdparty/patch/p7zip/7zFile.h",
    "content": "/* 7zFile.h -- File IO\r\n2013-01-18 : Igor Pavlov : Public domain */\r\n\r\n#ifndef __7Z_FILE_H\r\n#define __7Z_FILE_H\r\n\r\n#ifdef _WIN32\r\n#define USE_WINDOWS_FILE\r\n#endif\r\n\r\n#ifdef USE_WINDOWS_FILE\r\n#include <windows.h>\r\n#else\r\n#include <stdio.h>\r\n#endif\r\n\r\n#include \"7zTypes.h\"\r\n\r\nEXTERN_C_BEGIN\r\n\r\n/* ---------- File ---------- */\r\n\r\ntypedef struct\r\n{\r\n  #ifdef USE_WINDOWS_FILE\r\n  HANDLE handle;\r\n  #else\r\n  FILE *file;\r\n  #endif\r\n} CSzFile;\r\n\r\nvoid File_Construct(CSzFile *p);\r\n#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)\r\nWRes InFile_Open(CSzFile *p, const char *name);\r\nWRes OutFile_Open(CSzFile *p, const char *name);\r\n#endif\r\n#ifdef USE_WINDOWS_FILE\r\nWRes InFile_OpenW(CSzFile *p, const WCHAR *name);\r\nWRes OutFile_OpenW(CSzFile *p, const WCHAR *name);\r\n#endif\r\nWRes File_Close(CSzFile *p);\r\n\r\n/* reads max(*size, remain file's size) bytes */\r\nWRes File_Read(CSzFile *p, void *data, size_t *size);\r\n\r\n/* writes *size bytes */\r\nWRes File_Write(CSzFile *p, const void *data, size_t *size);\r\n\r\nWRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);\r\nWRes File_GetLength(CSzFile *p, UInt64 *length);\r\n\r\n\r\n/* ---------- FileInStream ---------- */\r\n\r\ntypedef struct\r\n{\r\n  ISeqInStream s;\r\n  CSzFile file;\r\n} CFileSeqInStream;\r\n\r\nvoid FileSeqInStream_CreateVTable(CFileSeqInStream *p);\r\n\r\n\r\ntypedef struct\r\n{\r\n  ISeekInStream s;\r\n  CSzFile file;\r\n} CFileInStream;\r\n\r\nvoid FileInStream_CreateVTable(CFileInStream *p);\r\n\r\n\r\ntypedef struct\r\n{\r\n  ISeqOutStream s;\r\n  CSzFile file;\r\n} CFileOutStream;\r\n\r\nvoid FileOutStream_CreateVTable(CFileOutStream *p);\r\n\r\nEXTERN_C_END\r\n\r\n#endif\r\n"
  },
  {
    "path": "thirdparty/patch/p7zip/android_p7zip.cmake",
    "content": "cmake_minimum_required(VERSION 3.6)\nproject(7za)\nadd_library(${PROJECT_NAME} STATIC\n    ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zDecode.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zEncode.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zExtract.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zHandler.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zHeader.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zIn.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zOut.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zProperties.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zRegister.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp  \n    ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp  \n    ../../../../CPP/7zip/Archive/Bz2Handler.cpp  \n    ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp  \n    ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp  \n    ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp  \n    ../../../../CPP/7zip/Archive/Cab/CabIn.cpp  \n    ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp  \n    ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp  \n    ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp  \n    ../../../../CPP/7zip/Archive/Common/FindSignature.cpp  \n    ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp  \n    ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp  \n    ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp  \n    ../../../../CPP/7zip/Archive/Common/MultiStream.cpp  \n    ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp  \n    ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp  \n    ../../../../CPP/7zip/Archive/DeflateProps.cpp  \n    ../../../../CPP/7zip/Archive/GzHandler.cpp  \n    ../../../../CPP/7zip/Archive/LzmaHandler.cpp  \n    ../../../../CPP/7zip/Archive/PpmdHandler.cpp  \n    ../../../../CPP/7zip/Archive/SplitHandler.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarIn.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarOut.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp  \n    ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp  \n    ../../../../CPP/7zip/Archive/XzHandler.cpp  \n    ../../../../CPP/7zip/Archive/ZHandler.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp  \n    ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp  \n    ../../../../CPP/7zip/Common/CWrappers.cpp  \n    ../../../../CPP/7zip/Common/CreateCoder.cpp  \n    ../../../../CPP/7zip/Common/FilePathAutoRename.cpp  \n    ../../../../CPP/7zip/Common/FileStreams.cpp  \n    ../../../../CPP/7zip/Common/FilterCoder.cpp  \n    ../../../../CPP/7zip/Common/InBuffer.cpp  \n    ../../../../CPP/7zip/Common/InOutTempBuffer.cpp  \n    ../../../../CPP/7zip/Common/LimitedStreams.cpp  \n    ../../../../CPP/7zip/Common/MemBlocks.cpp  \n    ../../../../CPP/7zip/Common/MethodId.cpp  \n    ../../../../CPP/7zip/Common/MethodProps.cpp  \n    ../../../../CPP/7zip/Common/OffsetStream.cpp  \n    ../../../../CPP/7zip/Common/OutBuffer.cpp  \n    ../../../../CPP/7zip/Common/OutMemStream.cpp  \n    ../../../../CPP/7zip/Common/ProgressMt.cpp  \n    ../../../../CPP/7zip/Common/ProgressUtils.cpp  \n    ../../../../CPP/7zip/Common/PropId.cpp  \n    ../../../../CPP/7zip/Common/StreamBinder.cpp  \n    ../../../../CPP/7zip/Common/StreamObjects.cpp  \n    ../../../../CPP/7zip/Common/StreamUtils.cpp  \n    ../../../../CPP/7zip/Common/UniqBlocks.cpp  \n    ../../../../CPP/7zip/Common/VirtThread.cpp  \n    ../../../../CPP/7zip/Compress/BZip2Crc.cpp  \n    ../../../../CPP/7zip/Compress/BZip2Decoder.cpp  \n    ../../../../CPP/7zip/Compress/BZip2Encoder.cpp  \n    ../../../../CPP/7zip/Compress/BZip2Register.cpp  \n    ../../../../CPP/7zip/Compress/Bcj2Coder.cpp  \n    ../../../../CPP/7zip/Compress/Bcj2Register.cpp  \n    ../../../../CPP/7zip/Compress/BcjCoder.cpp  \n    ../../../../CPP/7zip/Compress/BcjRegister.cpp  \n    ../../../../CPP/7zip/Compress/BitlDecoder.cpp  \n    ../../../../CPP/7zip/Compress/BranchMisc.cpp  \n    ../../../../CPP/7zip/Compress/BranchRegister.cpp  \n    ../../../../CPP/7zip/Compress/ByteSwap.cpp  \n    ../../../../CPP/7zip/Compress/CopyCoder.cpp  \n    ../../../../CPP/7zip/Compress/CopyRegister.cpp  \n    ../../../../CPP/7zip/Compress/Deflate64Register.cpp  \n    ../../../../CPP/7zip/Compress/DeflateDecoder.cpp  \n    ../../../../CPP/7zip/Compress/DeflateEncoder.cpp  \n    ../../../../CPP/7zip/Compress/DeflateRegister.cpp  \n    ../../../../CPP/7zip/Compress/DeltaFilter.cpp  \n    ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp  \n    ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp  \n    ../../../../CPP/7zip/Compress/LzOutWindow.cpp  \n    ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp  \n    ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp  \n    ../../../../CPP/7zip/Compress/Lzma2Register.cpp  \n    ../../../../CPP/7zip/Compress/LzmaDecoder.cpp  \n    ../../../../CPP/7zip/Compress/LzmaEncoder.cpp  \n    ../../../../CPP/7zip/Compress/LzmaRegister.cpp  \n    ../../../../CPP/7zip/Compress/LzxDecoder.cpp  \n    ../../../../CPP/7zip/Compress/PpmdDecoder.cpp  \n    ../../../../CPP/7zip/Compress/PpmdEncoder.cpp  \n    ../../../../CPP/7zip/Compress/PpmdRegister.cpp  \n    ../../../../CPP/7zip/Compress/PpmdZip.cpp  \n    ../../../../CPP/7zip/Compress/QuantumDecoder.cpp  \n    ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp  \n    ../../../../CPP/7zip/Compress/ZDecoder.cpp  \n    ../../../../CPP/7zip/Crypto/7zAes.cpp  \n    ../../../../CPP/7zip/Crypto/7zAesRegister.cpp  \n    ../../../../CPP/7zip/Crypto/HmacSha1.cpp  \n    ../../../../CPP/7zip/Crypto/MyAes.cpp  \n    ../../../../CPP/7zip/Crypto/MyAesReg.cpp  \n    ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp  \n    ../../../../CPP/7zip/Crypto/RandGen.cpp  \n    ../../../../CPP/7zip/Crypto/WzAes.cpp  \n    ../../../../CPP/7zip/Crypto/ZipCrypto.cpp  \n    ../../../../CPP/7zip/Crypto/ZipStrong.cpp  \n    ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp  \n    ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp  \n    ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp  \n    ../../../../CPP/7zip/UI/Common/Bench.cpp  \n    ../../../../CPP/7zip/UI/Common/DefaultName.cpp  \n    ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp  \n    ../../../../CPP/7zip/UI/Common/Extract.cpp  \n    ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp  \n    ../../../../CPP/7zip/UI/Common/HashCalc.cpp  \n    ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp  \n    ../../../../CPP/7zip/UI/Common/OpenArchive.cpp  \n    ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp  \n    ../../../../CPP/7zip/UI/Common/SetProperties.cpp  \n    ../../../../CPP/7zip/UI/Common/SortUtils.cpp  \n    ../../../../CPP/7zip/UI/Common/TempFiles.cpp  \n    ../../../../CPP/7zip/UI/Common/Update.cpp  \n    ../../../../CPP/7zip/UI/Common/UpdateAction.cpp  \n    ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp  \n    ../../../../CPP/7zip/UI/Common/UpdatePair.cpp  \n    ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp  \n    ../../../../CPP/7zip/UI/Console/BenchCon.cpp  \n    ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp  \n    ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp  \n    ../../../../CPP/7zip/UI/Console/HashCon.cpp  \n    ../../../../CPP/7zip/UI/Console/List.cpp  \n    ../../../../CPP/7zip/UI/Console/Main.cpp  \n    ../../../../CPP/7zip/UI/Console/MainAr.cpp  \n    ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp  \n    ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp  \n    ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp  \n    ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp  \n    ../../../../CPP/Common/CRC.cpp  \n    ../../../../CPP/Common/CommandLineParser.cpp  \n    ../../../../CPP/Common/CrcReg.cpp  \n    ../../../../CPP/Common/IntToString.cpp  \n    ../../../../CPP/Common/ListFileUtils.cpp  \n    ../../../../CPP/Common/MyString.cpp  \n    ../../../../CPP/Common/MyVector.cpp  \n    ../../../../CPP/Common/MyWindows.cpp  \n    ../../../../CPP/Common/Sha1Reg.cpp  \n    ../../../../CPP/Common/Sha256Reg.cpp  \n    ../../../../CPP/Common/StdInStream.cpp  \n    ../../../../CPP/Common/StdOutStream.cpp  \n    ../../../../CPP/Common/StringConvert.cpp  \n    ../../../../CPP/Common/StringToInt.cpp  \n    ../../../../CPP/Common/UTFConvert.cpp  \n    ../../../../CPP/Common/Wildcard.cpp  \n    ../../../../CPP/Common/XzCrc64Reg.cpp  \n    ../../../../CPP/Windows/ErrorMsg.cpp  \n    ../../../../CPP/Windows/FileDir.cpp  \n    ../../../../CPP/Windows/FileFind.cpp  \n    ../../../../CPP/Windows/FileIO.cpp  \n    ../../../../CPP/Windows/FileName.cpp  \n    ../../../../CPP/Windows/PropVariant.cpp  \n    ../../../../CPP/Windows/PropVariantConv.cpp  \n    ../../../../CPP/Windows/Synchronization.cpp  \n    ../../../../CPP/Windows/System.cpp  \n    ../../../../CPP/Windows/TimeUtils.cpp  \n    ../../../../CPP/myWindows/myAddExeFlag.cpp  \n    ../../../../CPP/myWindows/mySplitCommandLine.cpp  \n    ../../../../CPP/myWindows/wine_date_and_time.cpp  \n    ../../../../C/7zArcIn.c  \n    ../../../../C/7zBuf.c  \n    ../../../../C/7zCrc.c  \n    ../../../../C/7zCrcOpt.c \n    ../../../../C/7zDec.c  \n    ../../../../C/7zStream.c  \n    ../../../../C/Aes.c  \n    ../../../../C/Alloc.c  \n    ../../../../C/Bcj2.c  \n    ../../../../C/Bcj2Enc.c  \n    ../../../../C/Bra.c  \n    ../../../../C/Bra86.c  \n    ../../../../C/BraIA64.c  \n    ../../../../C/BwtSort.c  \n    ../../../../C/CpuArch.c  \n    ../../../../C/Delta.c  \n    ../../../../C/HuffEnc.c  \n    ../../../../C/LzFind.c  \n    ../../../../C/LzFindMt.c  \n    ../../../../C/Lzma2Dec.c  \n    ../../../../C/Lzma2Enc.c  \n    ../../../../C/LzmaDec.c  \n    ../../../../C/LzmaEnc.c  \n    ../../../../C/MtCoder.c  \n    ../../../../C/Ppmd7.c  \n    ../../../../C/Ppmd7Dec.c  \n    ../../../../C/Ppmd7Enc.c  \n    ../../../../C/Ppmd8.c  \n    ../../../../C/Ppmd8Dec.c  \n    ../../../../C/Ppmd8Enc.c  \n    ../../../../C/Sha1.c  \n    ../../../../C/Sha256.c  \n    ../../../../C/Sort.c  \n    ../../../../C/Threads.c  \n    ../../../../C/Xz.c  \n    ../../../../C/XzCrc64.c  \n    ../../../../C/XzCrc64Opt.c  \n    ../../../../C/XzDec.c  \n    ../../../../C/XzEnc.c  \n    ../../../../C/XzIn.c  \n)\n\n\ntarget_compile_definitions(${PROJECT_NAME} PUBLIC\n    -DANDROID_NDK \n    -DNDEBUG -D_REENTRANT -DENV_UNIX  \n    -DBREAK_HANDLER  \n    -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE\n)\n\ntarget_include_directories(${PROJECT_NAME} PRIVATE\n\t../../../7zip/Archive  \n\t../../../7zip/Archive/7z  \n\t../../../7zip/Archive/BZip2  \n\t../../../7zip/Archive/Common  \n\t../../../7zip/Archive/GZip  \n\t../../../7zip/Archive/Cab  \n\t../../../7zip/Archive/Lzma  \n\t../../../7zip/Archive/Tar  \n\t../../../7zip/Archive/Zip  \n\t../../../7zip/Archive/Split  \n\t../../../7zip/Archive/Z  \n\t../../../7zip/Compress  \n    ../../../7zip/Crypto  \n\t../../../7zip/UI/Console  \n\t../../../7zip/UI/Common  \n\t../../../Windows  \n\t../../../Common  \n\t../../../7zip/Common  \n\t../../../../C  \n    ../../../myWindows  \n    ../../../  \n    ../../../include_windows\n)\n\n# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+)\ntarget_compile_options(${PROJECT_NAME} PUBLIC\n    -fPIC -fexceptions -Wno-c++11-narrowing\n)"
  },
  {
    "path": "thirdparty/patch/sdl2/android_SDL_android.c",
    "content": "/*\n  Simple DirectMedia Layer\n  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n*/\n#include \"../../SDL_internal.h\"\n\n#include \"SDL_stdinc.h\"\n#include \"SDL_atomic.h\"\n#include \"SDL_hints.h\"\n#include \"SDL_main.h\"\n#include \"SDL_timer.h\"\n\n#ifdef __ANDROID__\n\n#include \"SDL_system.h\"\n#include \"SDL_android.h\"\n\n#include \"keyinfotable.h\"\n\n#include \"../../events/SDL_events_c.h\"\n#include \"../../video/android/SDL_androidkeyboard.h\"\n#include \"../../video/android/SDL_androidmouse.h\"\n#include \"../../video/android/SDL_androidtouch.h\"\n#include \"../../video/android/SDL_androidvideo.h\"\n#include \"../../video/android/SDL_androidwindow.h\"\n#include \"../../joystick/android/SDL_sysjoystick_c.h\"\n#include \"../../haptic/android/SDL_syshaptic_c.h\"\n\n#include <android/log.h>\n#include <android/configuration.h>\n#include <android/asset_manager_jni.h>\n#include <sys/system_properties.h>\n#include <pthread.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <dlfcn.h>\n\n#define SDL_JAVA_PREFIX                                 org_libsdl_app\n#define CONCAT1(prefix, class, function)                CONCAT2(prefix, class, function)\n#define CONCAT2(prefix, class, function)                Java_ ## prefix ## _ ## class ## _ ## function\n#define SDL_JAVA_INTERFACE(function)                    CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function)\n#define SDL_JAVA_AUDIO_INTERFACE(function)              CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function)\n#define SDL_JAVA_CONTROLLER_INTERFACE(function)         CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)\n#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function)   CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)\n\n/* Audio encoding definitions */\n#define ENCODING_PCM_8BIT   3\n#define ENCODING_PCM_16BIT  2\n#define ENCODING_PCM_FLOAT  4\n\n/* Java class SDLActivity */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(\n        JNIEnv *env, jclass cls,\n        jstring library, jstring function, jobject array);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(\n        JNIEnv *env, jclass jcls,\n        jstring filename);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(\n        JNIEnv *env, jclass jcls,\n        jint surfaceWidth, jint surfaceHeight,\n        jint deviceWidth, jint deviceHeight, jint format, jfloat rate);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(\n        JNIEnv *env, jclass jcls,\n        jint keycode);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(\n        JNIEnv *env, jclass jcls,\n        jint keycode);\n\nJNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(\n        JNIEnv *env, jclass jcls,\n        jint touch_device_id_in, jint pointer_finger_id_in,\n        jint action, jfloat x, jfloat y, jfloat p);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(\n        JNIEnv *env, jclass jcls,\n        jint button, jint action, jfloat x, jfloat y, jboolean relative);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(\n        JNIEnv *env, jclass jcls,\n        jfloat x, jfloat y, jfloat z);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(\n        JNIEnv *env, jclass cls);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(\n        JNIEnv *env, jclass cls, jboolean hasFocus);\n\nJNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(\n        JNIEnv *env, jclass cls,\n        jstring name);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(\n        JNIEnv *env, jclass cls,\n        jstring name, jstring value);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(\n        JNIEnv *env, jclass cls,\n        jint orientation);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(\n        JNIEnv* env, jclass cls,\n        jint touchId, jstring name);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(\n        JNIEnv* env, jclass cls,\n        jint requestCode, jboolean result);\n\nstatic JNINativeMethod SDLActivity_tab[] = {\n    { \"nativeSetupJNI\",             \"()I\", SDL_JAVA_INTERFACE(nativeSetupJNI) },\n    { \"nativeRunMain\",              \"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I\", SDL_JAVA_INTERFACE(nativeRunMain) },\n    { \"onNativeDropFile\",           \"(Ljava/lang/String;)V\", SDL_JAVA_INTERFACE(onNativeDropFile) },\n    { \"nativeSetScreenResolution\",  \"(IIIIIF)V\", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },\n    { \"onNativeResize\",             \"()V\", SDL_JAVA_INTERFACE(onNativeResize) },\n    { \"onNativeSurfaceCreated\",     \"()V\", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) },\n    { \"onNativeSurfaceChanged\",     \"()V\", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) },\n    { \"onNativeSurfaceDestroyed\",   \"()V\", SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed) },\n    { \"onNativeKeyDown\",            \"(I)V\", SDL_JAVA_INTERFACE(onNativeKeyDown) },\n    { \"onNativeKeyUp\",              \"(I)V\", SDL_JAVA_INTERFACE(onNativeKeyUp) },\n    { \"onNativeSoftReturnKey\",      \"()Z\", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) },\n    { \"onNativeKeyboardFocusLost\",  \"()V\", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) },\n    { \"onNativeTouch\",              \"(IIIFFF)V\", SDL_JAVA_INTERFACE(onNativeTouch) },\n    { \"onNativeMouse\",              \"(IIFFZ)V\", SDL_JAVA_INTERFACE(onNativeMouse) },\n    { \"onNativeAccel\",              \"(FFF)V\", SDL_JAVA_INTERFACE(onNativeAccel) },\n    { \"onNativeClipboardChanged\",   \"()V\", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },\n    { \"nativeLowMemory\",            \"()V\", SDL_JAVA_INTERFACE(nativeLowMemory) },\n    { \"onNativeLocaleChanged\",      \"()V\", SDL_JAVA_INTERFACE(onNativeLocaleChanged) },\n    { \"nativeSendQuit\",             \"()V\", SDL_JAVA_INTERFACE(nativeSendQuit) },\n    { \"nativeQuit\",                 \"()V\", SDL_JAVA_INTERFACE(nativeQuit) },\n    { \"nativePause\",                \"()V\", SDL_JAVA_INTERFACE(nativePause) },\n    { \"nativeResume\",               \"()V\", SDL_JAVA_INTERFACE(nativeResume) },\n    { \"nativeFocusChanged\",         \"(Z)V\", SDL_JAVA_INTERFACE(nativeFocusChanged) },\n    { \"nativeGetHint\",              \"(Ljava/lang/String;)Ljava/lang/String;\", SDL_JAVA_INTERFACE(nativeGetHint) },\n    { \"nativeSetenv\",               \"(Ljava/lang/String;Ljava/lang/String;)V\", SDL_JAVA_INTERFACE(nativeSetenv) },\n    { \"onNativeOrientationChanged\", \"(I)V\", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },\n    { \"nativeAddTouch\",             \"(ILjava/lang/String;)V\", SDL_JAVA_INTERFACE(nativeAddTouch) },\n    { \"nativePermissionResult\",     \"(IZ)V\", SDL_JAVA_INTERFACE(nativePermissionResult) }\n};\n\n/* Java class SDLInputConnection */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(\n        JNIEnv *env, jclass cls,\n        jstring text, jint newCursorPosition);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(\n        JNIEnv *env, jclass cls,\n        jchar chUnicode);\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(\n        JNIEnv *env, jclass cls,\n        jstring text, jint newCursorPosition);\n\nstatic JNINativeMethod SDLInputConnection_tab[] = {\n    { \"nativeCommitText\",                   \"(Ljava/lang/String;I)V\", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText) },\n    { \"nativeGenerateScancodeForUnichar\",   \"(C)V\", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar) },\n    { \"nativeSetComposingText\",             \"(Ljava/lang/String;I)V\", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText) }\n};\n\n/* Java class SDLAudioManager */\nJNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(\n        JNIEnv *env, jclass jcls);\n\nstatic JNINativeMethod SDLAudioManager_tab[] = {\n    { \"nativeSetupJNI\", \"()I\", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }\n};\n\n/* Java class SDLControllerManager */\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(\n        JNIEnv *env, jclass jcls);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jint keycode);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jint keycode);\n\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jint axis, jfloat value);\n\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jint hat_id, jint x, jint y);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,\n        jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(\n        JNIEnv *env, jclass jcls,\n        jint device_id);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(\n        JNIEnv *env, jclass jcls,\n        jint device_id, jstring device_name);\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(\n        JNIEnv *env, jclass jcls,\n        jint device_id);\n\nstatic JNINativeMethod SDLControllerManager_tab[] = {\n    { \"nativeSetupJNI\",         \"()I\", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) },\n    { \"onNativePadDown\",        \"(II)I\", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) },\n    { \"onNativePadUp\",          \"(II)I\", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },\n    { \"onNativeJoy\",            \"(IIF)V\", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },\n    { \"onNativeHat\",            \"(IIII)V\", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) },\n    { \"nativeAddJoystick\",      \"(ILjava/lang/String;Ljava/lang/String;IIZIIII)I\", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },\n    { \"nativeRemoveJoystick\",   \"(I)I\", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) },\n    { \"nativeAddHaptic\",        \"(ILjava/lang/String;)I\", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) },\n    { \"nativeRemoveHaptic\",     \"(I)I\", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) }\n};\n\n\n/* Uncomment this to log messages entering and exiting methods in this file */\n/* #define DEBUG_JNI */\n\nstatic void checkJNIReady(void);\n\n/*******************************************************************************\n This file links the Java side of Android with libsdl\n*******************************************************************************/\n#include <jni.h>\n\n\n/*******************************************************************************\n                               Globals\n*******************************************************************************/\nstatic pthread_key_t mThreadKey;\nstatic pthread_once_t key_once = PTHREAD_ONCE_INIT;\nstatic JavaVM *mJavaVM = NULL;\n\n/* Main activity */\nstatic jclass mActivityClass;\n\n/* method signatures */\nstatic jmethodID midClipboardGetText;\nstatic jmethodID midClipboardHasText;\nstatic jmethodID midClipboardSetText;\nstatic jmethodID midCreateCustomCursor;\nstatic jmethodID midGetContext;\nstatic jmethodID midGetDisplayDPI;\nstatic jmethodID midGetManifestEnvironmentVariables;\nstatic jmethodID midGetNativeSurface;\nstatic jmethodID midInitTouch;\nstatic jmethodID midIsAndroidTV;\nstatic jmethodID midIsChromebook;\nstatic jmethodID midIsDeXMode;\nstatic jmethodID midIsScreenKeyboardShown;\nstatic jmethodID midIsTablet;\nstatic jmethodID midManualBackButton;\nstatic jmethodID midMinimizeWindow;\nstatic jmethodID midOpenURL;\nstatic jmethodID midRequestPermission;\nstatic jmethodID midSendMessage;\nstatic jmethodID midSetActivityTitle;\nstatic jmethodID midSetCustomCursor;\nstatic jmethodID midSetOrientation;\nstatic jmethodID midSetRelativeMouseEnabled;\nstatic jmethodID midSetSurfaceViewFormat;\nstatic jmethodID midSetSystemCursor;\nstatic jmethodID midSetWindowStyle;\nstatic jmethodID midShouldMinimizeOnFocusLoss;\nstatic jmethodID midShowTextInput;\nstatic jmethodID midSupportsRelativeMouse;\n\n/* audio manager */\nstatic jclass mAudioManagerClass;\n\n/* method signatures */\nstatic jmethodID midAudioOpen;\nstatic jmethodID midAudioWriteByteBuffer;\nstatic jmethodID midAudioWriteShortBuffer;\nstatic jmethodID midAudioWriteFloatBuffer;\nstatic jmethodID midAudioClose;\nstatic jmethodID midCaptureOpen;\nstatic jmethodID midCaptureReadByteBuffer;\nstatic jmethodID midCaptureReadShortBuffer;\nstatic jmethodID midCaptureReadFloatBuffer;\nstatic jmethodID midCaptureClose;\nstatic jmethodID midAudioSetThreadPriority;\n\n/* controller manager */\nstatic jclass mControllerManagerClass;\n\n/* method signatures */\nstatic jmethodID midPollInputDevices;\nstatic jmethodID midPollHapticDevices;\nstatic jmethodID midHapticRun;\nstatic jmethodID midHapticStop;\n\n/* Accelerometer data storage */\nstatic SDL_DisplayOrientation displayOrientation;\nstatic float fLastAccelerometer[3];\nstatic SDL_bool bHasNewData;\n\nstatic SDL_bool bHasEnvironmentVariables;\n\nstatic SDL_atomic_t bPermissionRequestPending;\nstatic SDL_bool bPermissionRequestResult;\n\n/* Android AssetManager */\nstatic void Internal_Android_Create_AssetManager(void);\nstatic void Internal_Android_Destroy_AssetManager(void);\nstatic AAssetManager *asset_manager = NULL;\nstatic jobject javaAssetManagerRef = 0;\n\n/*******************************************************************************\n                 Functions called by JNI\n*******************************************************************************/\n\n/* From http://developer.android.com/guide/practices/jni.html\n * All threads are Linux threads, scheduled by the kernel.\n * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then\n * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the\n * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,\n * and cannot make JNI calls.\n * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the \"main\"\n * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread\n * is a no-op.\n * Note: You can call this function any number of times for the same thread, there's no harm in it\n */\n\n/* From http://developer.android.com/guide/practices/jni.html\n * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,\n * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be\n * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific\n * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)\n * Note: The destructor is not called unless the stored value is != NULL\n * Note: You can call this function any number of times for the same thread, there's no harm in it\n *       (except for some lost CPU cycles)\n */\n\n/* Set local storage value */\nstatic int\nAndroid_JNI_SetEnv(JNIEnv *env) {\n    int status = pthread_setspecific(mThreadKey, env);\n    if (status < 0) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed pthread_setspecific() in Android_JNI_SetEnv() (err=%d)\", status);\n    }\n    return status;\n}\n\n/* Get local storage value */\nJNIEnv* Android_JNI_GetEnv(void)\n{\n    /* Get JNIEnv from the Thread local storage */\n    JNIEnv *env = pthread_getspecific(mThreadKey);\n    if (env == NULL) {\n        /* If it fails, try to attach ! (e.g the thread isn't created with SDL_CreateThread() */\n        int status;\n\n        /* There should be a JVM */\n        if (mJavaVM == NULL) {\n            __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed, there is no JavaVM\");\n            return NULL;\n        }\n\n        /* Attach the current thread to the JVM and get a JNIEnv.\n         * It will be detached by pthread_create destructor 'Android_JNI_ThreadDestroyed' */\n        status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);\n        if (status < 0) {\n            __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed to attach current thread (err=%d)\", status);\n            return NULL;\n        }\n\n        /* Save JNIEnv into the Thread local storage */\n        if (Android_JNI_SetEnv(env) < 0) {\n            return NULL;\n        }\n    }\n\n    return env;\n}\n\n/* Set up an external thread for using JNI with Android_JNI_GetEnv() */\nint Android_JNI_SetupThread(void)\n{\n    JNIEnv *env;\n    int status;\n\n    /* There should be a JVM */\n    if (mJavaVM == NULL) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed, there is no JavaVM\");\n        return 0;\n    }\n\n    /* Attach the current thread to the JVM and get a JNIEnv.\n     * It will be detached by pthread_create destructor 'Android_JNI_ThreadDestroyed' */\n    status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);\n    if (status < 0) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed to attach current thread (err=%d)\", status);\n        return 0;\n    }\n\n    /* Save JNIEnv into the Thread local storage */\n    if (Android_JNI_SetEnv(env) < 0) {\n        return 0;\n    }\n\n    return 1;\n}\n\n/* Destructor called for each thread where mThreadKey is not NULL */\nstatic void\nAndroid_JNI_ThreadDestroyed(void *value)\n{\n    /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */\n    JNIEnv *env = (JNIEnv *) value;\n    if (env != NULL) {\n        (*mJavaVM)->DetachCurrentThread(mJavaVM);\n        Android_JNI_SetEnv(NULL);\n    }\n}\n\n/* Creation of local storage mThreadKey */\nstatic void\nAndroid_JNI_CreateKey(void)\n{\n    int status = pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed);\n    if (status < 0) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Error initializing mThreadKey with pthread_key_create() (err=%d)\", status);\n    }\n}\n\nstatic void\nAndroid_JNI_CreateKey_once(void)\n{\n    int status = pthread_once(&key_once, Android_JNI_CreateKey);\n    if (status < 0) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Error initializing mThreadKey with pthread_once() (err=%d)\", status);\n    }\n}\n\nstatic void\nregister_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, int nb)\n{\n    jclass clazz = (*env)->FindClass(env, classname);\n    if (clazz == NULL || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed to register methods of %s\", classname);\n        return;\n    }\n}\n\n// /* Library init */\n// JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)\n// {\n//     mJavaVM = vm;\n//     JNIEnv *env = NULL;\n// \n//     if ((*mJavaVM)->GetEnv(mJavaVM, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {\n//         __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"Failed to get JNI Env\");\n//         return JNI_VERSION_1_4;\n//     }\n// \n//     register_methods(env, \"org/libsdl/app/SDLActivity\", SDLActivity_tab, SDL_arraysize(SDLActivity_tab));\n//     register_methods(env, \"org/libsdl/app/SDLInputConnection\", SDLInputConnection_tab, SDL_arraysize(SDLInputConnection_tab));\n//     register_methods(env, \"org/libsdl/app/SDLAudioManager\", SDLAudioManager_tab, SDL_arraysize(SDLAudioManager_tab));\n//     register_methods(env, \"org/libsdl/app/SDLControllerManager\", SDLControllerManager_tab, SDL_arraysize(SDLControllerManager_tab));\n// \n//     return JNI_VERSION_1_4;\n// }\n\nvoid checkJNIReady(void)\n{\n    if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) {\n        /* We aren't fully initialized, let's just return. */\n        return;\n    }\n\n    SDL_SetMainReady();\n}\n\n/* Activity initialization -- called before SDL_main() to initialize JNI bindings */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)\n{\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"nativeSetupJNI()\");\n\n    /*\n     * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread\n     * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this\n     */\n    Android_JNI_CreateKey_once();\n\n    /* Save JNIEnv of SDLActivity */\n    Android_JNI_SetEnv(env);\n\n    if (mJavaVM == NULL) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"failed to found a JavaVM\");\n    }\n\n    /* Use a mutex to prevent concurrency issues between Java Activity and Native thread code, when using 'Android_Window'.\n     * (Eg. Java sending Touch events, while native code is destroying the main SDL_Window. )\n     */\n    if (Android_ActivityMutex == NULL) {\n        Android_ActivityMutex = SDL_CreateMutex(); /* Could this be created twice if onCreate() is called a second time ? */\n    }\n\n    if (Android_ActivityMutex == NULL) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"failed to create Android_ActivityMutex mutex\");\n    }\n\n\n    Android_PauseSem = SDL_CreateSemaphore(0);\n    if (Android_PauseSem == NULL) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"failed to create Android_PauseSem semaphore\");\n    }\n\n    Android_ResumeSem = SDL_CreateSemaphore(0);\n    if (Android_ResumeSem == NULL) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"failed to create Android_ResumeSem semaphore\");\n    }\n\n    mActivityClass = (jclass)((*env)->NewGlobalRef(env, cls));\n\n    midClipboardGetText = (*env)->GetStaticMethodID(env, mActivityClass, \"clipboardGetText\", \"()Ljava/lang/String;\");\n    midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass, \"clipboardHasText\", \"()Z\");\n    midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass, \"clipboardSetText\", \"(Ljava/lang/String;)V\");\n    midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, \"createCustomCursor\", \"([IIIII)I\");\n    midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, \"getContext\",\"()Landroid/content/Context;\");\n    midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass, \"getDisplayDPI\", \"()Landroid/util/DisplayMetrics;\");\n    midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, \"getManifestEnvironmentVariables\", \"()Z\");\n    midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass, \"getNativeSurface\",\"()Landroid/view/Surface;\");\n    midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass, \"initTouch\", \"()V\");\n    midIsAndroidTV = (*env)->GetStaticMethodID(env, mActivityClass, \"isAndroidTV\",\"()Z\");\n    midIsChromebook = (*env)->GetStaticMethodID(env, mActivityClass, \"isChromebook\", \"()Z\");\n    midIsDeXMode = (*env)->GetStaticMethodID(env, mActivityClass, \"isDeXMode\", \"()Z\");\n    midIsScreenKeyboardShown = (*env)->GetStaticMethodID(env, mActivityClass, \"isScreenKeyboardShown\",\"()Z\");\n    midIsTablet = (*env)->GetStaticMethodID(env, mActivityClass, \"isTablet\", \"()Z\");\n    midManualBackButton = (*env)->GetStaticMethodID(env, mActivityClass, \"manualBackButton\", \"()V\");\n    midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass, \"minimizeWindow\",\"()V\");\n    midOpenURL = (*env)->GetStaticMethodID(env, mActivityClass, \"openURL\", \"(Ljava/lang/String;)I\");\n    midRequestPermission = (*env)->GetStaticMethodID(env, mActivityClass, \"requestPermission\", \"(Ljava/lang/String;I)V\");\n    midSendMessage = (*env)->GetStaticMethodID(env, mActivityClass, \"sendMessage\", \"(II)Z\");\n    midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass, \"setActivityTitle\",\"(Ljava/lang/String;)Z\");\n    midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, \"setCustomCursor\", \"(I)Z\");\n    midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, \"setOrientation\",\"(IIZLjava/lang/String;)V\");\n    midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass, \"setRelativeMouseEnabled\", \"(Z)Z\");\n    midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass, \"setSurfaceViewFormat\",\"(I)V\");\n    midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass, \"setSystemCursor\", \"(I)Z\");\n    midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, \"setWindowStyle\",\"(Z)V\");\n    midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, \"shouldMinimizeOnFocusLoss\",\"()Z\");\n    midShowTextInput =  (*env)->GetStaticMethodID(env, mActivityClass, \"showTextInput\", \"(IIII)Z\");\n    midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, \"supportsRelativeMouse\", \"()Z\");\n\n    if (!midClipboardGetText ||\n        !midClipboardHasText ||\n        !midClipboardSetText ||\n        !midCreateCustomCursor ||\n        !midGetContext ||\n        !midGetDisplayDPI ||\n        !midGetManifestEnvironmentVariables ||\n        !midGetNativeSurface ||\n        !midInitTouch ||\n        !midIsAndroidTV ||\n        !midIsChromebook ||\n        !midIsDeXMode ||\n        !midIsScreenKeyboardShown ||\n        !midIsTablet ||\n        !midManualBackButton ||\n        !midMinimizeWindow ||\n        !midOpenURL ||\n        !midRequestPermission ||\n        !midSendMessage ||\n        !midSetActivityTitle ||\n        !midSetCustomCursor ||\n        !midSetOrientation ||\n        !midSetRelativeMouseEnabled ||\n        !midSetSurfaceViewFormat ||\n        !midSetSystemCursor ||\n        !midSetWindowStyle ||\n        !midShouldMinimizeOnFocusLoss ||\n        !midShowTextInput ||\n        !midSupportsRelativeMouse) {\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"Missing some Java callbacks, do you have the latest version of SDLActivity.java?\");\n    }\n\n    checkJNIReady();\n}\n\n/* Audio initialization -- called before SDL_main() to initialize JNI bindings */\nJNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)\n{\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"AUDIO nativeSetupJNI()\");\n\n    mAudioManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));\n\n    midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioOpen\", \"(IIII)[I\");\n    midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioWriteByteBuffer\", \"([B)V\");\n    midAudioWriteShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioWriteShortBuffer\", \"([S)V\");\n    midAudioWriteFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioWriteFloatBuffer\", \"([F)V\");\n    midAudioClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioClose\", \"()V\");\n    midCaptureOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"captureOpen\", \"(IIII)[I\");\n    midCaptureReadByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"captureReadByteBuffer\", \"([BZ)I\");\n    midCaptureReadShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"captureReadShortBuffer\", \"([SZ)I\");\n    midCaptureReadFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"captureReadFloatBuffer\", \"([FZ)I\");\n    midCaptureClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"captureClose\", \"()V\");\n    midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass,\n                                \"audioSetThreadPriority\", \"(ZI)V\");\n\n    if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||\n       !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?\");\n    }\n\n    checkJNIReady();\n}\n\n/* Controller initialization -- called before SDL_main() to initialize JNI bindings */\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls)\n{\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"CONTROLLER nativeSetupJNI()\");\n\n    mControllerManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));\n\n    midPollInputDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,\n                                \"pollInputDevices\", \"()V\");\n    midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,\n                                \"pollHapticDevices\", \"()V\");\n    midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass,\n                                \"hapticRun\", \"(IFI)V\");\n    midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass,\n                                \"hapticStop\", \"(I)V\");\n\n    if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) {\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?\");\n    }\n\n    checkJNIReady();\n}\n\n/* SDL main function prototype */\ntypedef int (*SDL_main_func)(int argc, char *argv[]);\n\n/* Start up the SDL app */\nJNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, jstring library, jstring function, jobject array)\n{\n    int status = -1;\n    const char *library_file;\n    void *library_handle;\n\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"nativeRunMain()\");\n\n    /* Save JNIEnv of SDLThread */\n    Android_JNI_SetEnv(env);\n\n    library_file = (*env)->GetStringUTFChars(env, library, NULL);\n    library_handle = dlopen(library_file, RTLD_GLOBAL);\n\n    if (!library_handle) {\n        /* When deploying android app bundle format uncompressed native libs may not extract from apk to filesystem.\n           In this case we should use lib name without path. https://bugzilla.libsdl.org/show_bug.cgi?id=4739 */\n        const char *library_name = SDL_strrchr(library_file, '/');\n        if (library_name && *library_name) {\n            library_name += 1;\n            library_handle = dlopen(library_name, RTLD_GLOBAL);\n        }\n    }\n\n    if (library_handle) {\n        const char *function_name;\n        SDL_main_func SDL_main;\n\n        function_name = (*env)->GetStringUTFChars(env, function, NULL);\n        SDL_main = (SDL_main_func)dlsym(library_handle, function_name);\n        if (SDL_main) {\n            int i;\n            int argc;\n            int len;\n            char **argv;\n            SDL_bool isstack;\n\n            /* Prepare the arguments. */\n            len = (*env)->GetArrayLength(env, array);\n            argv = SDL_small_alloc(char *, 1 + len + 1, &isstack);  /* !!! FIXME: check for NULL */\n            argc = 0;\n            /* Use the name \"app_process\" so PHYSFS_platformCalcBaseDir() works.\n               https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start\n             */\n            argv[argc++] = SDL_strdup(\"app_process\");\n            for (i = 0; i < len; ++i) {\n                const char *utf;\n                char *arg = NULL;\n                jstring string = (*env)->GetObjectArrayElement(env, array, i);\n                if (string) {\n                    utf = (*env)->GetStringUTFChars(env, string, 0);\n                    if (utf) {\n                        arg = SDL_strdup(utf);\n                        (*env)->ReleaseStringUTFChars(env, string, utf);\n                    }\n                    (*env)->DeleteLocalRef(env, string);\n                }\n                if (!arg) {\n                    arg = SDL_strdup(\"\");\n                }\n                argv[argc++] = arg;\n            }\n            argv[argc] = NULL;\n\n\n            /* Run the application. */\n            status = SDL_main(argc, argv);\n\n            /* Release the arguments. */\n            for (i = 0; i < argc; ++i) {\n                SDL_free(argv[i]);\n            }\n            SDL_small_free(argv, isstack);\n\n        } else {\n            __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"nativeRunMain(): Couldn't find function %s in library %s\", function_name, library_file);\n        }\n        (*env)->ReleaseStringUTFChars(env, function, function_name);\n\n        dlclose(library_handle);\n\n    } else {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"nativeRunMain(): Couldn't load library %s\", library_file);\n    }\n    (*env)->ReleaseStringUTFChars(env, library, library_file);\n\n    /* This is a Java thread, it doesn't need to be Detached from the JVM.\n     * Set to mThreadKey value to NULL not to call pthread_create destructor 'Android_JNI_ThreadDestroyed' */\n    Android_JNI_SetEnv(NULL);\n\n    /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */\n    /* exit(status); */\n\n    return status;\n}\n\n/* Drop file */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(\n                                    JNIEnv *env, jclass jcls,\n                                    jstring filename)\n{\n    const char *path = (*env)->GetStringUTFChars(env, filename, NULL);\n    SDL_SendDropFile(NULL, path);\n    (*env)->ReleaseStringUTFChars(env, filename, path);\n    SDL_SendDropComplete(NULL);\n}\n\n/* Lock / Unlock Mutex */\nvoid Android_ActivityMutex_Lock() {\n    SDL_LockMutex(Android_ActivityMutex);\n}\n\nvoid Android_ActivityMutex_Unlock() {\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Lock the Mutex when the Activity is in its 'Running' state */\nvoid Android_ActivityMutex_Lock_Running() {\n    int pauseSignaled = 0;\n    int resumeSignaled = 0;\n\nretry:\n\n    SDL_LockMutex(Android_ActivityMutex);\n\n    pauseSignaled = SDL_SemValue(Android_PauseSem);\n    resumeSignaled = SDL_SemValue(Android_ResumeSem);\n\n    if (pauseSignaled > resumeSignaled) {\n        SDL_UnlockMutex(Android_ActivityMutex);\n        SDL_Delay(50);\n        goto retry;\n    }\n}\n\n/* Set screen resolution */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint surfaceWidth, jint surfaceHeight,\n                                    jint deviceWidth, jint deviceHeight, jint format, jfloat rate)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate);\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Resize */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(\n                                    JNIEnv *env, jclass jcls)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    if (Android_Window)\n    {\n        Android_SendResize(Android_Window);\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint orientation)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    displayOrientation = (SDL_DisplayOrientation)orientation;\n\n    if (Android_Window)\n    {\n        SDL_VideoDisplay *display = SDL_GetDisplay(0);\n        SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation);\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(\n        JNIEnv* env, jclass cls,\n        jint touchId, jstring name)\n{\n    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);\n\n    SDL_AddTouch((SDL_TouchID) touchId, SDL_TOUCH_DEVICE_DIRECT, utfname);\n\n    (*env)->ReleaseStringUTFChars(env, name, utfname);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(\n        JNIEnv* env, jclass cls,\n        jint requestCode, jboolean result)\n{\n    bPermissionRequestResult = result;\n    SDL_AtomicSet(&bPermissionRequestPending, SDL_FALSE);\n}\n\n/* Paddown */\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id, jint keycode)\n{\n    return Android_OnPadDown(device_id, keycode);\n}\n\n/* Padup */\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id, jint keycode)\n{\n    return Android_OnPadUp(device_id, keycode);\n}\n\n/* Joy */\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id, jint axis, jfloat value)\n{\n    Android_OnJoy(device_id, axis, value);\n}\n\n/* POV Hat */\nJNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id, jint hat_id, jint x, jint y)\n{\n    Android_OnHat(device_id, hat_id, x, y);\n}\n\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id, jstring device_name, jstring device_desc,\n                                    jint vendor_id, jint product_id, jboolean is_accelerometer,\n                                    jint button_mask, jint naxes, jint nhats, jint nballs)\n{\n    int retval;\n    const char *name = (*env)->GetStringUTFChars(env, device_name, NULL);\n    const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL);\n\n    retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, nhats, nballs);\n\n    (*env)->ReleaseStringUTFChars(env, device_name, name);\n    (*env)->ReleaseStringUTFChars(env, device_desc, desc);\n\n    return retval;\n}\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint device_id)\n{\n    return Android_RemoveJoystick(device_id);\n}\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)(\n    JNIEnv *env, jclass jcls, jint device_id, jstring device_name)\n{\n    int retval;\n    const char *name = (*env)->GetStringUTFChars(env, device_name, NULL);\n\n    retval = Android_AddHaptic(device_id, name);\n\n    (*env)->ReleaseStringUTFChars(env, device_name, name);\n\n    return retval;\n}\n\nJNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(\n    JNIEnv *env, jclass jcls, jint device_id)\n{\n    return Android_RemoveHaptic(device_id);\n}\n\n/* Called from surfaceCreated() */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(JNIEnv *env, jclass jcls)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    if (Android_Window)\n    {\n        SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;\n\n        data->native_window = Android_JNI_GetNativeWindow();\n        if (data->native_window == NULL) {\n            SDL_SetError(\"Could not fetch native window from UI thread\");\n        }\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Called from surfaceChanged() */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, jclass jcls)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    if (Android_Window)\n    {\n        SDL_VideoDevice *_this = SDL_GetVideoDevice();\n        SDL_WindowData  *data  = (SDL_WindowData *) Android_Window->driverdata;\n\n        /* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */\n        if (data->egl_surface == EGL_NO_SURFACE) {\n            data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);\n        }\n\n        /* GL Context handling is done in the event loop because this function is run from the Java thread */\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Called from surfaceDestroyed() */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv *env, jclass jcls)\n{\n    int nb_attempt = 50;\n\nretry:\n\n    SDL_LockMutex(Android_ActivityMutex);\n\n    if (Android_Window)\n    {\n        SDL_VideoDevice *_this = SDL_GetVideoDevice();\n        SDL_WindowData  *data  = (SDL_WindowData *) Android_Window->driverdata;\n\n        /* Wait for Main thread being paused and context un-activated to release 'egl_surface' */\n        if (! data->backup_done) {\n            nb_attempt -= 1;\n            if (nb_attempt == 0) {\n                SDL_SetError(\"Try to release egl_surface with context probably still active\");\n            } else {\n                SDL_UnlockMutex(Android_ActivityMutex);\n                SDL_Delay(10);\n                goto retry;\n            }\n        }\n\n        if (data->egl_surface != EGL_NO_SURFACE) {\n            SDL_EGL_DestroySurface(_this, data->egl_surface);\n            data->egl_surface = EGL_NO_SURFACE;\n        }\n\n        if (data->native_window) {\n            ANativeWindow_release(data->native_window);\n            data->native_window = NULL;\n        }\n\n        /* GL Context handling is done in the event loop because this function is run from the Java thread */\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Keydown */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint keycode)\n{\n    Android_OnKeyDown(keycode);\n}\n\n/* Keyup */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint keycode)\n{\n    Android_OnKeyUp(keycode);\n}\n\n/* Virtual keyboard return key might stop text input */\nJNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)(\n                                    JNIEnv *env, jclass jcls)\n{\n    if (SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) {\n        SDL_StopTextInput();\n        return JNI_TRUE;\n    }\n    return JNI_FALSE;\n}\n\n/* Keyboard Focus Lost */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)(\n                                    JNIEnv *env, jclass jcls)\n{\n    /* Calling SDL_StopTextInput will take care of hiding the keyboard and cleaning up the DummyText widget */\n    SDL_StopTextInput();\n}\n\n\n/* Touch */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint touch_device_id_in, jint pointer_finger_id_in,\n                                    jint action, jfloat x, jfloat y, jfloat p)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    Android_OnTouch(Android_Window, touch_device_id_in, pointer_finger_id_in, action, x, y, p);\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Mouse */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(\n                                    JNIEnv *env, jclass jcls,\n                                    jint button, jint action, jfloat x, jfloat y, jboolean relative)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    Android_OnMouse(Android_Window, button, action, x, y, relative);\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\n/* Accelerometer */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(\n                                    JNIEnv *env, jclass jcls,\n                                    jfloat x, jfloat y, jfloat z)\n{\n    fLastAccelerometer[0] = x;\n    fLastAccelerometer[1] = y;\n    fLastAccelerometer[2] = z;\n    bHasNewData = SDL_TRUE;\n}\n\n/* Clipboard */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(\n                                    JNIEnv *env, jclass jcls)\n{\n    SDL_SendClipboardUpdate();\n}\n\n/* Low memory */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(\n                                    JNIEnv *env, jclass cls)\n{\n    SDL_SendAppEvent(SDL_APP_LOWMEMORY);\n}\n\n/* Locale\n * requires android:configChanges=\"layoutDirection|locale\" in AndroidManifest.xml */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(\n                                    JNIEnv *env, jclass cls)\n{\n    SDL_SendAppEvent(SDL_LOCALECHANGED);\n}\n\n\n/* Send Quit event to \"SDLThread\" thread */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(\n                                    JNIEnv *env, jclass cls)\n{\n    /* Discard previous events. The user should have handled state storage\n     * in SDL_APP_WILLENTERBACKGROUND. After nativeSendQuit() is called, no\n     * events other than SDL_QUIT and SDL_APP_TERMINATING should fire */\n    SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);\n    /* Inject a SDL_QUIT event */\n    SDL_SendQuit();\n    SDL_SendAppEvent(SDL_APP_TERMINATING);\n    /* Robustness: clear any pending Pause */\n    while (SDL_SemTryWait(Android_PauseSem) == 0) {\n        /* empty */\n    }\n    /* Resume the event loop so that the app can catch SDL_QUIT which\n     * should now be the top event in the event queue. */\n    SDL_SemPost(Android_ResumeSem);\n}\n\n/* Activity ends */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(\n                                    JNIEnv *env, jclass cls)\n{\n    const char *str;\n\n    if (Android_ActivityMutex) {\n        SDL_DestroyMutex(Android_ActivityMutex);\n        Android_ActivityMutex = NULL;\n    }\n\n    if (Android_PauseSem) {\n        SDL_DestroySemaphore(Android_PauseSem);\n        Android_PauseSem = NULL;\n    }\n\n    if (Android_ResumeSem) {\n        SDL_DestroySemaphore(Android_ResumeSem);\n        Android_ResumeSem = NULL;\n    }\n\n    Internal_Android_Destroy_AssetManager();\n\n    str = SDL_GetError();\n    if (str && str[0]) {\n        __android_log_print(ANDROID_LOG_ERROR, \"SDL\", \"SDLActivity thread ends (error=%s)\", str);\n    } else {\n        __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"SDLActivity thread ends\");\n    }\n}\n\n/* Pause */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)(\n                                    JNIEnv *env, jclass cls)\n{\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"nativePause()\");\n\n    /* Signal the pause semaphore so the event loop knows to pause and (optionally) block itself.\n     * Sometimes 2 pauses can be queued (eg pause/resume/pause), so it's always increased. */\n    SDL_SemPost(Android_PauseSem);\n}\n\n/* Resume */\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(\n                                    JNIEnv *env, jclass cls)\n{\n    __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"nativeResume()\");\n\n    /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context\n     * We can't restore the GL Context here because it needs to be done on the SDL main thread\n     * and this function will be called from the Java thread instead.\n     */\n    SDL_SemPost(Android_ResumeSem);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)(\n                                    JNIEnv *env, jclass cls, jboolean hasFocus)\n{\n    SDL_LockMutex(Android_ActivityMutex);\n\n    if (Android_Window) {\n        __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"nativeFocusChanged()\");\n        SDL_SendWindowEvent(Android_Window, (hasFocus ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST), 0, 0);\n    }\n\n    SDL_UnlockMutex(Android_ActivityMutex);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(\n                                    JNIEnv *env, jclass cls,\n                                    jstring text, jint newCursorPosition)\n{\n    const char *utftext = (*env)->GetStringUTFChars(env, text, NULL);\n\n    SDL_SendKeyboardText(utftext);\n\n    (*env)->ReleaseStringUTFChars(env, text, utftext);\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(\n                                    JNIEnv *env, jclass cls,\n                                    jchar chUnicode)\n{\n    SDL_Scancode code = SDL_SCANCODE_UNKNOWN;\n    uint16_t mod = 0;\n\n    /* We do not care about bigger than 127. */\n    if (chUnicode < 127) {\n        AndroidKeyInfo info = unicharToAndroidKeyInfoTable[chUnicode];\n        code = info.code;\n        mod = info.mod;\n    }\n\n    if (mod & KMOD_SHIFT) {\n        /* If character uses shift, press shift down */\n        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);\n    }\n\n    /* send a keydown and keyup even for the character */\n    SDL_SendKeyboardKey(SDL_PRESSED, code);\n    SDL_SendKeyboardKey(SDL_RELEASED, code);\n\n    if (mod & KMOD_SHIFT) {\n        /* If character uses shift, press shift back up */\n        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);\n    }\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(\n                                    JNIEnv *env, jclass cls,\n                                    jstring text, jint newCursorPosition)\n{\n    const char *utftext = (*env)->GetStringUTFChars(env, text, NULL);\n\n    SDL_SendEditingText(utftext, 0, 0);\n\n    (*env)->ReleaseStringUTFChars(env, text, utftext);\n}\n\nJNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(\n                                    JNIEnv *env, jclass cls,\n                                    jstring name)\n{\n    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);\n    const char *hint = SDL_GetHint(utfname);\n\n    jstring result = (*env)->NewStringUTF(env, hint);\n    (*env)->ReleaseStringUTFChars(env, name, utfname);\n\n    return result;\n}\n\nJNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(\n                                    JNIEnv *env, jclass cls,\n                                    jstring name, jstring value)\n{\n    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);\n    const char *utfvalue = (*env)->GetStringUTFChars(env, value, NULL);\n\n    SDL_setenv(utfname, utfvalue, 1);\n\n    (*env)->ReleaseStringUTFChars(env, name, utfname);\n    (*env)->ReleaseStringUTFChars(env, value, utfvalue);\n\n}\n\n/*******************************************************************************\n             Functions called by SDL into Java\n*******************************************************************************/\n\nstatic SDL_atomic_t s_active;\nstruct LocalReferenceHolder\n{\n    JNIEnv *m_env;\n    const char *m_func;\n};\n\nstatic struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func)\n{\n    struct LocalReferenceHolder refholder;\n    refholder.m_env = NULL;\n    refholder.m_func = func;\n#ifdef DEBUG_JNI\n    SDL_Log(\"Entering function %s\", func);\n#endif\n    return refholder;\n}\n\nstatic SDL_bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env)\n{\n    const int capacity = 16;\n    if ((*env)->PushLocalFrame(env, capacity) < 0) {\n        SDL_SetError(\"Failed to allocate enough JVM local references\");\n        return SDL_FALSE;\n    }\n    SDL_AtomicIncRef(&s_active);\n    refholder->m_env = env;\n    return SDL_TRUE;\n}\n\nstatic void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder)\n{\n#ifdef DEBUG_JNI\n    SDL_Log(\"Leaving function %s\", refholder->m_func);\n#endif\n    if (refholder->m_env) {\n        JNIEnv *env = refholder->m_env;\n        (*env)->PopLocalFrame(env, NULL);\n        SDL_AtomicDecRef(&s_active);\n    }\n}\n\nANativeWindow* Android_JNI_GetNativeWindow(void)\n{\n    ANativeWindow *anw = NULL;\n    jobject s;\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface);\n    if (s) {\n        anw = ANativeWindow_fromSurface(env, s);\n        (*env)->DeleteLocalRef(env, s);\n    }\n\n    return anw;\n}\n\nvoid Android_JNI_SetSurfaceViewFormat(int format)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    int new_format = 0;\n\n    /* Format from android/native_window.h,\n     * convert to temporary arbitrary values,\n     * then to java PixelFormat */\n    if (format == WINDOW_FORMAT_RGBA_8888) {\n        new_format = 1;\n    } else if (format == WINDOW_FORMAT_RGBX_8888) {\n        new_format = 2;\n    } else if (format == WINDOW_FORMAT_RGB_565) {\n        /* Default */\n        new_format = 0;\n    }\n\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format);\n}\n\nvoid Android_JNI_SetActivityTitle(const char *title)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    jstring jtitle = (*env)->NewStringUTF(env, title);\n    (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetActivityTitle, jtitle);\n    (*env)->DeleteLocalRef(env, jtitle);\n}\n\nvoid Android_JNI_SetWindowStyle(SDL_bool fullscreen)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0);\n}\n\nvoid Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    jstring jhint = (*env)->NewStringUTF(env, (hint ? hint : \"\"));\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midSetOrientation, w, h, (resizable? 1 : 0), jhint);\n    (*env)->DeleteLocalRef(env, jhint);\n}\n\nvoid Android_JNI_MinizeWindow()\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midMinimizeWindow);\n}\n\nSDL_bool Android_JNI_ShouldMinimizeOnFocusLoss()\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midShouldMinimizeOnFocusLoss);\n}\n\nSDL_bool Android_JNI_GetAccelerometerValues(float values[3])\n{\n    int i;\n    SDL_bool retval = SDL_FALSE;\n\n    if (bHasNewData) {\n        for (i = 0; i < 3; ++i) {\n            values[i] = fLastAccelerometer[i];\n        }\n        bHasNewData = SDL_FALSE;\n        retval = SDL_TRUE;\n    }\n\n    return retval;\n}\n\n/*\n * Audio support\n */\nstatic int audioBufferFormat = 0;\nstatic jobject audioBuffer = NULL;\nstatic void *audioBufferPinned = NULL;\nstatic int captureBufferFormat = 0;\nstatic jobject captureBuffer = NULL;\n\nint Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)\n{\n    int audioformat;\n    jobject jbufobj = NULL;\n    jobject result;\n    int *resultElements;\n    jboolean isCopy;\n\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    switch (spec->format) {\n    case AUDIO_U8:\n        audioformat = ENCODING_PCM_8BIT;\n        break;\n    case AUDIO_S16:\n        audioformat = ENCODING_PCM_16BIT;\n        break;\n    case AUDIO_F32:\n        audioformat = ENCODING_PCM_FLOAT;\n        break;\n    default:\n        return SDL_SetError(\"Unsupported audio format: 0x%x\", spec->format);\n    }\n\n    if (iscapture) {\n        __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"SDL audio: opening device for capture\");\n        result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples);\n    } else {\n        __android_log_print(ANDROID_LOG_VERBOSE, \"SDL\", \"SDL audio: opening device for output\");\n        result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples);\n    }\n    if (result == NULL) {\n        /* Error during audio initialization, error printed from Java */\n        return SDL_SetError(\"Java-side initialization failed\");\n    }\n\n    if ((*env)->GetArrayLength(env, (jintArray)result) != 4) {\n        return SDL_SetError(\"Unexpected results from Java, expected 4, got %d\", (*env)->GetArrayLength(env, (jintArray)result));\n    }\n    isCopy = JNI_FALSE;\n    resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy);\n    spec->freq = resultElements[0];\n    audioformat = resultElements[1];\n    switch (audioformat) {\n    case ENCODING_PCM_8BIT:\n        spec->format = AUDIO_U8;\n        break;\n    case ENCODING_PCM_16BIT:\n        spec->format = AUDIO_S16;\n        break;\n    case ENCODING_PCM_FLOAT:\n        spec->format = AUDIO_F32;\n        break;\n    default:\n        return SDL_SetError(\"Unexpected audio format from Java: %d\\n\", audioformat);\n    }\n    spec->channels = resultElements[2];\n    spec->samples = resultElements[3];\n    (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT);\n    (*env)->DeleteLocalRef(env, result);\n\n    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on\n     * Android >= 4.2 due to a \"stale global reference\" error. So now we allocate this buffer directly from this side. */\n    switch (audioformat) {\n    case ENCODING_PCM_8BIT:\n        {\n            jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels);\n            if (audioBufferLocal) {\n                jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);\n                (*env)->DeleteLocalRef(env, audioBufferLocal);\n            }\n        }\n        break;\n    case ENCODING_PCM_16BIT:\n        {\n            jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels);\n            if (audioBufferLocal) {\n                jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);\n                (*env)->DeleteLocalRef(env, audioBufferLocal);\n            }\n        }\n        break;\n    case ENCODING_PCM_FLOAT:\n        {\n            jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels);\n            if (audioBufferLocal) {\n                jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);\n                (*env)->DeleteLocalRef(env, audioBufferLocal);\n            }\n        }\n        break;\n    default:\n        return SDL_SetError(\"Unexpected audio format from Java: %d\\n\", audioformat);\n    }\n\n    if (jbufobj == NULL) {\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"SDL audio: could not allocate an audio buffer\");\n        return SDL_OutOfMemory();\n    }\n\n    if (iscapture) {\n        captureBufferFormat = audioformat;\n        captureBuffer = jbufobj;\n    } else {\n        audioBufferFormat = audioformat;\n        audioBuffer = jbufobj;\n    }\n\n    if (!iscapture) {\n        isCopy = JNI_FALSE;\n\n        switch (audioformat) {\n        case ENCODING_PCM_8BIT:\n            audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);\n            break;\n        case ENCODING_PCM_16BIT:\n            audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);\n            break;\n        case ENCODING_PCM_FLOAT:\n            audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);\n            break;\n        default:\n            return SDL_SetError(\"Unexpected audio format from Java: %d\\n\", audioformat);\n        }\n    }\n    return 0;\n}\n\nSDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void)\n{\n    return displayOrientation;\n}\n\nint Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    jobject jDisplayObj = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDisplayDPI);\n    jclass jDisplayClass = (*env)->GetObjectClass(env, jDisplayObj);\n\n    jfieldID fidXdpi = (*env)->GetFieldID(env, jDisplayClass, \"xdpi\", \"F\");\n    jfieldID fidYdpi = (*env)->GetFieldID(env, jDisplayClass, \"ydpi\", \"F\");\n    jfieldID fidDdpi = (*env)->GetFieldID(env, jDisplayClass, \"densityDpi\", \"I\");\n\n    float nativeXdpi = (*env)->GetFloatField(env, jDisplayObj, fidXdpi);\n    float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi);\n    int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi);\n\n\n    (*env)->DeleteLocalRef(env, jDisplayObj);\n    (*env)->DeleteLocalRef(env, jDisplayClass);\n\n    if (ddpi) {\n        *ddpi = (float)nativeDdpi;\n    }\n    if (xdpi) {\n        *xdpi = nativeXdpi;\n    }\n    if (ydpi) {\n        *ydpi = nativeYdpi;\n    }\n\n    return 0;\n}\n\nvoid * Android_JNI_GetAudioBuffer(void)\n{\n    return audioBufferPinned;\n}\n\nvoid Android_JNI_WriteAudioBuffer(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    switch (audioBufferFormat) {\n    case ENCODING_PCM_8BIT:\n        (*env)->ReleaseByteArrayElements(env, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);\n        (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);\n        break;\n    case ENCODING_PCM_16BIT:\n        (*env)->ReleaseShortArrayElements(env, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);\n        (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);\n        break;\n    case ENCODING_PCM_FLOAT:\n        (*env)->ReleaseFloatArrayElements(env, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);\n        (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);\n        break;\n    default:\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"SDL audio: unhandled audio buffer format\");\n        break;\n    }\n\n    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */\n}\n\nint Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jboolean isCopy = JNI_FALSE;\n    jint br = -1;\n\n    switch (captureBufferFormat) {\n    case ENCODING_PCM_8BIT:\n        SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);\n        br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);\n        if (br > 0) {\n            jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy);\n            SDL_memcpy(buffer, ptr, br);\n            (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, ptr, JNI_ABORT);\n        }\n        break;\n    case ENCODING_PCM_16BIT:\n        SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16)));\n        br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);\n        if (br > 0) {\n            jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);\n            br *= sizeof(Sint16);\n            SDL_memcpy(buffer, ptr, br);\n            (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, ptr, JNI_ABORT);\n        }\n        break;\n    case ENCODING_PCM_FLOAT:\n        SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float)));\n        br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);\n        if (br > 0) {\n            jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);\n            br *= sizeof(float);\n            SDL_memcpy(buffer, ptr, br);\n            (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, ptr, JNI_ABORT);\n        }\n        break;\n    default:\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"SDL audio: unhandled capture buffer format\");\n        break;\n    }\n    return br;\n}\n\nvoid Android_JNI_FlushCapturedAudio(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n#if 0  /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */\n    switch (captureBufferFormat) {\n    case ENCODING_PCM_8BIT:\n        {\n            const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);\n            while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }\n        }\n        break;\n    case ENCODING_PCM_16BIT:\n        {\n            const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);\n            while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }\n        }\n        break;\n    case ENCODING_PCM_FLOAT:\n        {\n            const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);\n            while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }\n        }\n        break;\n    default:\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"SDL audio: flushing unhandled capture buffer format\");\n        break;\n    }\n#else\n    switch (captureBufferFormat) {\n    case ENCODING_PCM_8BIT:\n        (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);\n        break;\n    case ENCODING_PCM_16BIT:\n        (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);\n        break;\n    case ENCODING_PCM_FLOAT:\n        (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);\n        break;\n    default:\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"SDL audio: flushing unhandled capture buffer format\");\n        break;\n    }\n#endif\n}\n\nvoid Android_JNI_CloseAudioDevice(const int iscapture)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    if (iscapture) {\n        (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose);\n        if (captureBuffer) {\n            (*env)->DeleteGlobalRef(env, captureBuffer);\n            captureBuffer = NULL;\n        }\n    } else {\n        (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose);\n        if (audioBuffer) {\n            (*env)->DeleteGlobalRef(env, audioBuffer);\n            audioBuffer = NULL;\n            audioBufferPinned = NULL;\n        }\n    }\n}\n\nvoid Android_JNI_AudioSetThreadPriority(int iscapture, int device_id)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id);\n}\n\n/* Test for an exception and call SDL_SetError with its detail if one occurs */\n/* If the parameter silent is truthy then SDL_SetError() will not be called. */\nstatic SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jthrowable exception;\n\n    /* Detect mismatch LocalReferenceHolder_Init/Cleanup */\n    SDL_assert(SDL_AtomicGet(&s_active) > 0);\n\n    exception = (*env)->ExceptionOccurred(env);\n    if (exception != NULL) {\n        jmethodID mid;\n\n        /* Until this happens most JNI operations have undefined behaviour */\n        (*env)->ExceptionClear(env);\n\n        if (!silent) {\n            jclass exceptionClass = (*env)->GetObjectClass(env, exception);\n            jclass classClass = (*env)->FindClass(env, \"java/lang/Class\");\n            jstring exceptionName;\n            const char *exceptionNameUTF8;\n            jstring exceptionMessage;\n\n            mid = (*env)->GetMethodID(env, classClass, \"getName\", \"()Ljava/lang/String;\");\n            exceptionName = (jstring)(*env)->CallObjectMethod(env, exceptionClass, mid);\n            exceptionNameUTF8 = (*env)->GetStringUTFChars(env, exceptionName, 0);\n\n            mid = (*env)->GetMethodID(env, exceptionClass, \"getMessage\", \"()Ljava/lang/String;\");\n            exceptionMessage = (jstring)(*env)->CallObjectMethod(env, exception, mid);\n\n            if (exceptionMessage != NULL) {\n                const char *exceptionMessageUTF8 = (*env)->GetStringUTFChars(env, exceptionMessage, 0);\n                SDL_SetError(\"%s: %s\", exceptionNameUTF8, exceptionMessageUTF8);\n                (*env)->ReleaseStringUTFChars(env, exceptionMessage, exceptionMessageUTF8);\n            } else {\n                SDL_SetError(\"%s\", exceptionNameUTF8);\n            }\n\n            (*env)->ReleaseStringUTFChars(env, exceptionName, exceptionNameUTF8);\n        }\n\n        return SDL_TRUE;\n    }\n\n    return SDL_FALSE;\n}\n\nstatic void Internal_Android_Create_AssetManager() {\n\n    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);\n    JNIEnv *env = Android_JNI_GetEnv();\n    jmethodID mid;\n    jobject context;\n    jobject javaAssetManager;\n\n    if (!LocalReferenceHolder_Init(&refs, env)) {\n        LocalReferenceHolder_Cleanup(&refs);\n        return;\n    }\n\n    /* context = SDLActivity.getContext(); */\n    context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n\n    /* javaAssetManager = context.getAssets(); */\n    mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),\n            \"getAssets\", \"()Landroid/content/res/AssetManager;\");\n    javaAssetManager = (*env)->CallObjectMethod(env, context, mid);\n\n    /**\n     * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager\n     * object.  Note that the caller is responsible for obtaining and holding a VM reference\n     * to the jobject to prevent its being garbage collected while the native object is\n     * in use.\n     */\n    javaAssetManagerRef = (*env)->NewGlobalRef(env, javaAssetManager);\n    asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef);\n\n    if (asset_manager == NULL) {\n        (*env)->DeleteGlobalRef(env, javaAssetManagerRef);\n        Android_JNI_ExceptionOccurred(SDL_TRUE);\n    }\n\n    LocalReferenceHolder_Cleanup(&refs);\n}\n\nstatic void Internal_Android_Destroy_AssetManager() {\n    JNIEnv *env = Android_JNI_GetEnv();\n\n    if (asset_manager) {\n        (*env)->DeleteGlobalRef(env, javaAssetManagerRef);\n        asset_manager = NULL;\n    }\n}\n\nint Android_JNI_FileOpen(SDL_RWops *ctx,\n        const char *fileName, const char *mode)\n{\n    AAsset *asset = NULL;\n    ctx->hidden.androidio.asset = NULL;\n\n    if (asset_manager == NULL) {\n        Internal_Android_Create_AssetManager();\n    }\n\n    if (asset_manager == NULL) {\n        return -1;\n    }\n\n    asset = AAssetManager_open(asset_manager, fileName, AASSET_MODE_UNKNOWN);\n    if (asset == NULL) {\n        return -1;\n    }\n\n\n    ctx->hidden.androidio.asset = (void*) asset;\n    return 0;\n}\n\nsize_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,\n        size_t size, size_t maxnum)\n{\n    size_t result;\n    AAsset *asset = (AAsset*) ctx->hidden.androidio.asset;\n    result = AAsset_read(asset, buffer, size * maxnum);\n\n    if (result > 0) {\n        /* Number of chuncks */\n        return (result / size);\n    } else {\n        /* Error or EOF */\n        return result;\n    }\n}\n\nsize_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer,\n        size_t size, size_t num)\n{\n    SDL_SetError(\"Cannot write to Android package filesystem\");\n    return 0;\n}\n\nSint64 Android_JNI_FileSize(SDL_RWops *ctx)\n{\n    off64_t result;\n    AAsset *asset = (AAsset*) ctx->hidden.androidio.asset;\n    result = AAsset_getLength64(asset);\n    return result;\n}\n\nSint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)\n{\n    off64_t result;\n    AAsset *asset = (AAsset*) ctx->hidden.androidio.asset;\n    result = AAsset_seek64(asset, offset, whence);\n    return result;\n}\n\nint Android_JNI_FileClose(SDL_RWops *ctx)\n{\n    AAsset *asset = (AAsset*) ctx->hidden.androidio.asset;\n    AAsset_close(asset);\n    return 0;\n}\n\nint Android_JNI_SetClipboardText(const char *text)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jstring string = (*env)->NewStringUTF(env, text);\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText, string);\n    (*env)->DeleteLocalRef(env, string);\n    return 0;\n}\n\nchar* Android_JNI_GetClipboardText(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    char *text = NULL;\n    jstring string;\n\n    string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText);\n    if (string) {\n        const char *utf = (*env)->GetStringUTFChars(env, string, 0);\n        if (utf) {\n            text = SDL_strdup(utf);\n            (*env)->ReleaseStringUTFChars(env, string, utf);\n        }\n        (*env)->DeleteLocalRef(env, string);\n    }\n\n    return (text == NULL) ? SDL_strdup(\"\") : text;\n}\n\nSDL_bool Android_JNI_HasClipboardText(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jboolean retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText);\n    return (retval == JNI_TRUE) ? SDL_TRUE : SDL_FALSE;\n}\n\n/* returns 0 on success or -1 on error (others undefined then)\n * returns truthy or falsy value in plugged, charged and battery\n * returns the value in seconds and percent or -1 if not available\n */\nint Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent)\n{\n    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);\n    JNIEnv *env = Android_JNI_GetEnv();\n    jmethodID mid;\n    jobject context;\n    jstring action;\n    jclass cls;\n    jobject filter;\n    jobject intent;\n    jstring iname;\n    jmethodID imid;\n    jstring bname;\n    jmethodID bmid;\n    if (!LocalReferenceHolder_Init(&refs, env)) {\n        LocalReferenceHolder_Cleanup(&refs);\n        return -1;\n    }\n\n\n    /* context = SDLActivity.getContext(); */\n    context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n\n    action = (*env)->NewStringUTF(env, \"android.intent.action.BATTERY_CHANGED\");\n\n    cls = (*env)->FindClass(env, \"android/content/IntentFilter\");\n\n    mid = (*env)->GetMethodID(env, cls, \"<init>\", \"(Ljava/lang/String;)V\");\n    filter = (*env)->NewObject(env, cls, mid, action);\n\n    (*env)->DeleteLocalRef(env, action);\n\n    mid = (*env)->GetMethodID(env, mActivityClass, \"registerReceiver\", \"(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;\");\n    intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);\n\n    (*env)->DeleteLocalRef(env, filter);\n\n    cls = (*env)->GetObjectClass(env, intent);\n\n    imid = (*env)->GetMethodID(env, cls, \"getIntExtra\", \"(Ljava/lang/String;I)I\");\n\n    /* Watch out for C89 scoping rules because of the macro */\n#define GET_INT_EXTRA(var, key) \\\n    int var; \\\n    iname = (*env)->NewStringUTF(env, key); \\\n    (var) = (*env)->CallIntMethod(env, intent, imid, iname, -1); \\\n    (*env)->DeleteLocalRef(env, iname);\n\n    bmid = (*env)->GetMethodID(env, cls, \"getBooleanExtra\", \"(Ljava/lang/String;Z)Z\");\n\n    /* Watch out for C89 scoping rules because of the macro */\n#define GET_BOOL_EXTRA(var, key) \\\n    int var; \\\n    bname = (*env)->NewStringUTF(env, key); \\\n    (var) = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \\\n    (*env)->DeleteLocalRef(env, bname);\n\n    if (plugged) {\n        /* Watch out for C89 scoping rules because of the macro */\n        GET_INT_EXTRA(plug, \"plugged\") /* == BatteryManager.EXTRA_PLUGGED (API 5) */\n        if (plug == -1) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return -1;\n        }\n        /* 1 == BatteryManager.BATTERY_PLUGGED_AC */\n        /* 2 == BatteryManager.BATTERY_PLUGGED_USB */\n        *plugged = (0 < plug) ? 1 : 0;\n    }\n\n    if (charged) {\n        /* Watch out for C89 scoping rules because of the macro */\n        GET_INT_EXTRA(status, \"status\") /* == BatteryManager.EXTRA_STATUS (API 5) */\n        if (status == -1) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return -1;\n        }\n        /* 5 == BatteryManager.BATTERY_STATUS_FULL */\n        *charged = (status == 5) ? 1 : 0;\n    }\n\n    if (battery) {\n        GET_BOOL_EXTRA(present, \"present\") /* == BatteryManager.EXTRA_PRESENT (API 5) */\n        *battery = present ? 1 : 0;\n    }\n\n    if (seconds) {\n        *seconds = -1; /* not possible */\n    }\n\n    if (percent) {\n        int level;\n        int scale;\n\n        /* Watch out for C89 scoping rules because of the macro */\n        {\n            GET_INT_EXTRA(level_temp, \"level\") /* == BatteryManager.EXTRA_LEVEL (API 5) */\n            level = level_temp;\n        }\n        /* Watch out for C89 scoping rules because of the macro */\n        {\n            GET_INT_EXTRA(scale_temp, \"scale\") /* == BatteryManager.EXTRA_SCALE (API 5) */\n            scale = scale_temp;\n        }\n\n        if ((level == -1) || (scale == -1)) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return -1;\n        }\n        *percent = level * 100 / scale;\n    }\n\n    (*env)->DeleteLocalRef(env, intent);\n\n    LocalReferenceHolder_Cleanup(&refs);\n    return 0;\n}\n\n/* Add all touch devices */\nvoid Android_JNI_InitTouch() {\n     JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch);\n}\n\nvoid Android_JNI_PollInputDevices(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices);\n}\n\nvoid Android_JNI_PollHapticDevices(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);\n}\n\nvoid Android_JNI_HapticRun(int device_id, float intensity, int length)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length);\n}\n\nvoid Android_JNI_HapticStop(int device_id)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id);\n}\n\n/* See SDLActivity.java for constants. */\n#define COMMAND_SET_KEEP_SCREEN_ON    5\n\n/* sends message to be handled on the UI event dispatch thread */\nint Android_JNI_SendMessage(int command, int param)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jboolean success;\n    success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midSendMessage, command, param);\n    return success ? 0 : -1;\n}\n\nvoid Android_JNI_SuspendScreenSaver(SDL_bool suspend)\n{\n    Android_JNI_SendMessage(COMMAND_SET_KEEP_SCREEN_ON, (suspend == SDL_FALSE) ? 0 : 1);\n}\n\nvoid Android_JNI_ShowTextInput(SDL_Rect *inputRect)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput,\n                               inputRect->x,\n                               inputRect->y,\n                               inputRect->w,\n                               inputRect->h );\n}\n\nvoid Android_JNI_HideTextInput(void)\n{\n    /* has to match Activity constant */\n    const int COMMAND_TEXTEDIT_HIDE = 3;\n    Android_JNI_SendMessage(COMMAND_TEXTEDIT_HIDE, 0);\n}\n\nSDL_bool Android_JNI_IsScreenKeyboardShown(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jboolean is_shown = 0;\n    is_shown = (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsScreenKeyboardShown);\n    return is_shown;\n}\n\n\nint Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)\n{\n    JNIEnv *env;\n    jclass clazz;\n    jmethodID mid;\n    jobject context;\n    jstring title;\n    jstring message;\n    jintArray button_flags;\n    jintArray button_ids;\n    jobjectArray button_texts;\n    jintArray colors;\n    jobject text;\n    jint temp;\n    int i;\n\n    env = Android_JNI_GetEnv();\n\n    /* convert parameters */\n\n    clazz = (*env)->FindClass(env, \"java/lang/String\");\n\n    title = (*env)->NewStringUTF(env, messageboxdata->title);\n    message = (*env)->NewStringUTF(env, messageboxdata->message);\n\n    button_flags = (*env)->NewIntArray(env, messageboxdata->numbuttons);\n    button_ids = (*env)->NewIntArray(env, messageboxdata->numbuttons);\n    button_texts = (*env)->NewObjectArray(env, messageboxdata->numbuttons,\n        clazz, NULL);\n    for (i = 0; i < messageboxdata->numbuttons; ++i) {\n        const SDL_MessageBoxButtonData *sdlButton;\n\n        if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {\n            sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i];\n        } else {\n            sdlButton = &messageboxdata->buttons[i];\n        }\n\n        temp = sdlButton->flags;\n        (*env)->SetIntArrayRegion(env, button_flags, i, 1, &temp);\n        temp = sdlButton->buttonid;\n        (*env)->SetIntArrayRegion(env, button_ids, i, 1, &temp);\n        text = (*env)->NewStringUTF(env, sdlButton->text);\n        (*env)->SetObjectArrayElement(env, button_texts, i, text);\n        (*env)->DeleteLocalRef(env, text);\n    }\n\n    if (messageboxdata->colorScheme) {\n        colors = (*env)->NewIntArray(env, SDL_MESSAGEBOX_COLOR_MAX);\n        for (i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; ++i) {\n            temp = (0xFFU << 24) |\n                   (messageboxdata->colorScheme->colors[i].r << 16) |\n                   (messageboxdata->colorScheme->colors[i].g << 8) |\n                   (messageboxdata->colorScheme->colors[i].b << 0);\n            (*env)->SetIntArrayRegion(env, colors, i, 1, &temp);\n        }\n    } else {\n        colors = NULL;\n    }\n\n    (*env)->DeleteLocalRef(env, clazz);\n\n    /* context = SDLActivity.getContext(); */\n    context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n\n    clazz = (*env)->GetObjectClass(env, context);\n\n    mid = (*env)->GetMethodID(env, clazz,\n        \"messageboxShowMessageBox\", \"(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I\");\n    *buttonid = (*env)->CallIntMethod(env, context, mid,\n        messageboxdata->flags,\n        title,\n        message,\n        button_flags,\n        button_ids,\n        button_texts,\n        colors);\n\n    (*env)->DeleteLocalRef(env, context);\n    (*env)->DeleteLocalRef(env, clazz);\n\n    /* delete parameters */\n\n    (*env)->DeleteLocalRef(env, title);\n    (*env)->DeleteLocalRef(env, message);\n    (*env)->DeleteLocalRef(env, button_flags);\n    (*env)->DeleteLocalRef(env, button_ids);\n    (*env)->DeleteLocalRef(env, button_texts);\n    (*env)->DeleteLocalRef(env, colors);\n\n    return 0;\n}\n\n/*\n//////////////////////////////////////////////////////////////////////////////\n//\n// Functions exposed to SDL applications in SDL_system.h\n//////////////////////////////////////////////////////////////////////////////\n*/\n\nvoid *SDL_AndroidGetJNIEnv(void)\n{\n    return Android_JNI_GetEnv();\n}\n\nvoid *SDL_AndroidGetActivity(void)\n{\n    /* See SDL_system.h for caveats on using this function. */\n\n    JNIEnv *env = Android_JNI_GetEnv();\n    if (!env) {\n        return NULL;\n    }\n\n    /* return SDLActivity.getContext(); */\n    return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n}\n\nint SDL_GetAndroidSDKVersion(void)\n{\n    static int sdk_version;\n    if (!sdk_version) {\n        char sdk[PROP_VALUE_MAX] = {0};\n        if (__system_property_get(\"ro.build.version.sdk\", sdk) != 0) {\n            sdk_version = SDL_atoi(sdk);\n        }\n    }\n    return sdk_version;\n}\n\nSDL_bool SDL_IsAndroidTablet(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet);\n}\n\nSDL_bool SDL_IsAndroidTV(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV);\n}\n\nSDL_bool SDL_IsChromebook(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook);\n}\n\nSDL_bool SDL_IsDeXMode(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);\n}\n\nvoid SDL_AndroidBackButton(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);\n}\n\nconst char * SDL_AndroidGetInternalStoragePath(void)\n{\n    static char *s_AndroidInternalFilesPath = NULL;\n\n    if (!s_AndroidInternalFilesPath) {\n        struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);\n        jmethodID mid;\n        jobject context;\n        jobject fileObject;\n        jstring pathString;\n        const char *path;\n\n        JNIEnv *env = Android_JNI_GetEnv();\n        if (!LocalReferenceHolder_Init(&refs, env)) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        /* context = SDLActivity.getContext(); */\n        context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n        if (!context) {\n            SDL_SetError(\"Couldn't get Android context!\");\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        /* fileObj = context.getFilesDir(); */\n        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),\n                \"getFilesDir\", \"()Ljava/io/File;\");\n        fileObject = (*env)->CallObjectMethod(env, context, mid);\n        if (!fileObject) {\n            SDL_SetError(\"Couldn't get internal directory\");\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        /* path = fileObject.getCanonicalPath(); */\n        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),\n                \"getCanonicalPath\", \"()Ljava/lang/String;\");\n        pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);\n        if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        path = (*env)->GetStringUTFChars(env, pathString, NULL);\n        s_AndroidInternalFilesPath = SDL_strdup(path);\n        (*env)->ReleaseStringUTFChars(env, pathString, path);\n\n        LocalReferenceHolder_Cleanup(&refs);\n    }\n    return s_AndroidInternalFilesPath;\n}\n\nint SDL_AndroidGetExternalStorageState(void)\n{\n    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);\n    jmethodID mid;\n    jclass cls;\n    jstring stateString;\n    const char *state;\n    int stateFlags;\n\n    JNIEnv *env = Android_JNI_GetEnv();\n    if (!LocalReferenceHolder_Init(&refs, env)) {\n        LocalReferenceHolder_Cleanup(&refs);\n        return 0;\n    }\n\n    cls = (*env)->FindClass(env, \"android/os/Environment\");\n    mid = (*env)->GetStaticMethodID(env, cls,\n            \"getExternalStorageState\", \"()Ljava/lang/String;\");\n    stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid);\n\n    state = (*env)->GetStringUTFChars(env, stateString, NULL);\n\n    /* Print an info message so people debugging know the storage state */\n    __android_log_print(ANDROID_LOG_INFO, \"SDL\", \"external storage state: %s\", state);\n\n    if (SDL_strcmp(state, \"mounted\") == 0) {\n        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |\n                     SDL_ANDROID_EXTERNAL_STORAGE_WRITE;\n    } else if (SDL_strcmp(state, \"mounted_ro\") == 0) {\n        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;\n    } else {\n        stateFlags = 0;\n    }\n    (*env)->ReleaseStringUTFChars(env, stateString, state);\n\n    LocalReferenceHolder_Cleanup(&refs);\n    return stateFlags;\n}\n\nconst char * SDL_AndroidGetExternalStoragePath(void)\n{\n    static char *s_AndroidExternalFilesPath = NULL;\n\n    if (!s_AndroidExternalFilesPath) {\n        struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);\n        jmethodID mid;\n        jobject context;\n        jobject fileObject;\n        jstring pathString;\n        const char *path;\n\n        JNIEnv *env = Android_JNI_GetEnv();\n        if (!LocalReferenceHolder_Init(&refs, env)) {\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        /* context = SDLActivity.getContext(); */\n        context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);\n\n        /* fileObj = context.getExternalFilesDir(); */\n        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),\n                \"getExternalFilesDir\", \"(Ljava/lang/String;)Ljava/io/File;\");\n        fileObject = (*env)->CallObjectMethod(env, context, mid, NULL);\n        if (!fileObject) {\n            SDL_SetError(\"Couldn't get external directory\");\n            LocalReferenceHolder_Cleanup(&refs);\n            return NULL;\n        }\n\n        /* path = fileObject.getAbsolutePath(); */\n        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),\n                \"getAbsolutePath\", \"()Ljava/lang/String;\");\n        pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);\n\n        path = (*env)->GetStringUTFChars(env, pathString, NULL);\n        s_AndroidExternalFilesPath = SDL_strdup(path);\n        (*env)->ReleaseStringUTFChars(env, pathString, path);\n\n        LocalReferenceHolder_Cleanup(&refs);\n    }\n    return s_AndroidExternalFilesPath;\n}\n\nSDL_bool SDL_AndroidRequestPermission(const char *permission)\n{\n    return Android_JNI_RequestPermission(permission);\n}\n\nvoid Android_JNI_GetManifestEnvironmentVariables(void)\n{\n    if (!mActivityClass || !midGetManifestEnvironmentVariables) {\n        __android_log_print(ANDROID_LOG_WARN, \"SDL\", \"Request to get environment variables before JNI is ready\");\n        return;\n    }\n\n    if (!bHasEnvironmentVariables) {\n        JNIEnv *env = Android_JNI_GetEnv();\n        SDL_bool ret = (*env)->CallStaticBooleanMethod(env, mActivityClass, midGetManifestEnvironmentVariables);\n        if (ret) {\n            bHasEnvironmentVariables = SDL_TRUE;\n        }\n    }\n}\n\nint Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    int custom_cursor = 0;\n    jintArray pixels;\n    pixels = (*env)->NewIntArray(env, surface->w * surface->h);\n    if (pixels) {\n        (*env)->SetIntArrayRegion(env, pixels, 0, surface->w * surface->h, (int *)surface->pixels);\n        custom_cursor = (*env)->CallStaticIntMethod(env, mActivityClass, midCreateCustomCursor, pixels, surface->w, surface->h, hot_x, hot_y);\n        (*env)->DeleteLocalRef(env, pixels);\n    } else {\n        SDL_OutOfMemory();\n    }\n    return custom_cursor;\n}\n\n\nSDL_bool Android_JNI_SetCustomCursor(int cursorID)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetCustomCursor, cursorID);\n}\n\nSDL_bool Android_JNI_SetSystemCursor(int cursorID)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetSystemCursor, cursorID);\n}\n\nSDL_bool Android_JNI_SupportsRelativeMouse(void)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSupportsRelativeMouse);\n}\n\nSDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1));\n}\n\nSDL_bool Android_JNI_RequestPermission(const char *permission)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n\tconst int requestCode = 1;\n\n\t/* Wait for any pending request on another thread */\n\twhile (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {\n\t\tSDL_Delay(10);\n\t}\n\tSDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);\n\n    jstring jpermission = (*env)->NewStringUTF(env, permission);\n    (*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);\n    (*env)->DeleteLocalRef(env, jpermission);\n\n\t/* Wait for the request to complete */\n\twhile (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {\n\t\tSDL_Delay(10);\n\t}\n\treturn bPermissionRequestResult;\n}\n\nint Android_JNI_GetLocale(char *buf, size_t buflen)\n{\n    AConfiguration *cfg;\n\n    SDL_assert(buflen > 6);\n\n    /* Need to re-create the asset manager if locale has changed (SDL_LOCALECHANGED) */\n    Internal_Android_Destroy_AssetManager();\n\n    if (asset_manager == NULL) {\n        Internal_Android_Create_AssetManager();\n    }\n\n    if (asset_manager == NULL) {\n        return -1;\n    }\n\n    cfg = AConfiguration_new();\n    if (cfg == NULL) {\n        return -1;\n    }\n\n    {\n        char language[2] = {};\n        char country[2] = {};\n        size_t id = 0;\n\n        AConfiguration_fromAssetManager(cfg, asset_manager);\n        AConfiguration_getLanguage(cfg, language);\n        AConfiguration_getCountry(cfg, country);\n\n        /* copy language (not null terminated) */\n        if (language[0]) {\n            buf[id++] = language[0];\n            if (language[1]) {\n                buf[id++] = language[1];\n            }\n        }\n\n        buf[id++] = '_';\n\n        /* copy country (not null terminated) */\n        if (country[0]) {\n            buf[id++] = country[0];\n            if (country[1]) {\n                buf[id++] = country[1];\n            }\n        }\n        \n        buf[id++] = '\\0';\n        SDL_assert(id <= buflen);\n    }\n\n    AConfiguration_delete(cfg);\n\n    return 0;\n}\n\nint\nAndroid_JNI_OpenURL(const char *url)\n{\n    JNIEnv *env = Android_JNI_GetEnv();\n    jstring jurl = (*env)->NewStringUTF(env, url);\n    const int ret = (*env)->CallStaticIntMethod(env, mActivityClass, midOpenURL, jurl);\n    (*env)->DeleteLocalRef(env, jurl);\n    return ret;\n}\n\n#endif /* __ANDROID__ */\n\n/* vi: set ts=4 sw=4 expandtab: */\n"
  },
  {
    "path": "thirdparty/patch/sdl2/android_android_lf.h",
    "content": "/* \r\n * Macros for file64 functions\r\n *\r\n * Android does not support the macro _FILE_OFFSET_BITS=64\r\n * As of android-21 it does however support many file64 functions\r\n*/\r\n\r\n#ifndef ARCHIVE_ANDROID_LF_H_INCLUDED\r\n#define ARCHIVE_ANDROID_LF_H_INCLUDED\r\n\r\n#if __ANDROID_API__ > 20\r\n\r\n#include <dirent.h>\r\n#include <fcntl.h>\r\n#include <unistd.h>\r\n#include <sys/stat.h>\r\n#include <sys/statvfs.h>\r\n#include <sys/types.h>\r\n#include <sys/vfs.h>\r\n\r\n//dirent.h\r\n#define readdir_r readdir64_r\r\n#define readdir readdir64\r\n#define dirent dirent64\r\n//fcntl.h\r\n#define openat openat64\r\n#define open open64\r\n#define mkstemp mkstemp64\r\n//unistd.h\r\n#define lseek lseek64\r\n#define ftruncate ftruncate64\r\n//sys/stat.h\r\n#define fstatat fstatat64\r\n#define fstat fstat64\r\n#define lstat lstat64\r\n#define stat stat64\r\n//sys/statvfs.h\r\n#define fstatvfs fstatvfs64\r\n#define statvfs statvfs64\r\n//sys/types.h\r\n#define off_t off64_t\r\n//sys/vfs.h\r\n#define fstatfs fstatfs64\r\n#define statfs statfs64\r\n#endif\r\n\r\n#endif /* ARCHIVE_ANDROID_LF_H_INCLUDED */\r\n"
  },
  {
    "path": "thirdparty/patch/unrar/android_ulinks.cpp",
    "content": "\n\nstatic bool UnixSymlink(CommandData *Cmd,const char *Target,const wchar *LinkName,RarTime *ftm,RarTime *fta)\n{\n  CreatePath(LinkName,true,Cmd->DisableNames);\n\n  // Overwrite prompt was already issued and confirmed earlier, so we can\n  // remove existing symlink or regular file here. PrepareToDelete was also\n  // called earlier inside of uiAskReplaceEx.\n  DelFile(LinkName);\n\n  char LinkNameA[NM];\n  WideToChar(LinkName,LinkNameA,ASIZE(LinkNameA));\n  if (symlink(Target,LinkNameA)==-1) // Error.\n  {\n    if (errno==EEXIST)\n      uiMsg(UIERROR_ULINKEXIST,LinkName);\n    else\n    {\n      uiMsg(UIERROR_SLINKCREATE,UINULL,LinkName);\n      ErrHandler.SetErrorCode(RARX_WARNING);\n    }\n    return false;\n  }\n#ifdef USE_LUTIMES\n#ifdef UNIX_TIME_NS\n  timespec times[2];\n  times[0].tv_sec=fta->GetUnix();\n  times[0].tv_nsec=fta->IsSet() ? long(fta->GetUnixNS()%1000000000) : UTIME_NOW;\n  times[1].tv_sec=ftm->GetUnix();\n  times[1].tv_nsec=ftm->IsSet() ? long(ftm->GetUnixNS()%1000000000) : UTIME_NOW;\n  utimensat(AT_FDCWD,LinkNameA,times,AT_SYMLINK_NOFOLLOW);\n#else\n  struct timeval tv[2];\n  tv[0].tv_sec=fta->GetUnix();\n  tv[0].tv_usec=long(fta->GetUnixNS()%1000000000/1000);\n  tv[1].tv_sec=ftm->GetUnix();\n  tv[1].tv_usec=long(ftm->GetUnixNS()%1000000000/1000);\n  utimes(LinkNameA,tv);\n#endif\n#endif\n\n  return true;\n}\n\n\nstatic bool IsFullPath(const char *PathA) // Unix ASCII version.\n{\n  return *PathA==CPATHDIVIDER;\n}\n\n\nbool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)\n{\n  char Target[NM];\n  if (IsLink(Arc.FileHead.FileAttr))\n  {\n    size_t DataSize=(size_t)Arc.FileHead.PackSize;\n    if (DataSize>ASIZE(Target)-1)\n      return false;\n    if ((size_t)DataIO.UnpRead((byte *)Target,DataSize)!=DataSize)\n      return false;\n    Target[DataSize]=0;\n\n    DataIO.UnpHash.Init(Arc.FileHead.FileHash.Type,1);\n    DataIO.UnpHash.Update(Target,strlen(Target));\n    DataIO.UnpHash.Result(&Arc.FileHead.FileHash);\n\n    // Return true in case of bad checksum, so link will be processed further\n    // and extraction routine will report the checksum error.\n    if (!DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL))\n      return true;\n\n    wchar TargetW[NM];\n    CharToWide(Target,TargetW,ASIZE(TargetW));\n    // Check for *TargetW==0 to catch CharToWide failure.\n    // Use Arc.FileHead.FileName instead of LinkName, since LinkName\n    // can include the destination path as a prefix, which can\n    // confuse IsRelativeSymlinkSafe algorithm.\n    if (!Cmd->AbsoluteLinks && (*TargetW==0 || IsFullPath(TargetW) ||\n        !IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))\n      return false;\n    return UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);\n  }\n  return false;\n}\n\n\nbool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)\n{\n  char Target[NM];\n  WideToChar(hd->RedirName,Target,ASIZE(Target));\n  if (hd->RedirType==FSREDIR_WINSYMLINK || hd->RedirType==FSREDIR_JUNCTION)\n  {\n    // Cannot create Windows absolute path symlinks in Unix. Only relative path\n    // Windows symlinks can be created here. RAR 5.0 used \\??\\ prefix\n    // for Windows absolute symlinks, since RAR 5.1 /??/ is used.\n    // We escape ? as \\? to avoid \"trigraph\" warning\n    if (strncmp(Target,\"\\\\??\\\\\",4)==0 || strncmp(Target,\"/\\?\\?/\",4)==0)\n      return false;\n    DosSlashToUnix(Target,Target,ASIZE(Target));\n  }\n  // Use hd->FileName instead of LinkName, since LinkName can include\n  // the destination path as a prefix, which can confuse\n  // IsRelativeSymlinkSafe algorithm.\n  if (!Cmd->AbsoluteLinks && (IsFullPath(Target) ||\n      !IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,hd->RedirName)))\n    return false;\n  return UnixSymlink(Cmd,Target,Name,&hd->mtime,&hd->atime);\n}\n"
  }
]