diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..8ac84100
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,892 @@
+Copyright (c), W.Dee and contributors All rights reserved.
+Contributors
+ Go Watanabe, Kenjo, Kiyobee, Kouhei Yanagita, mey, MIK, Takenori Imoto, yun
+Kirikiri Z Project Contributors
+W.Dee, casper, 有限会社MCF, Biscrat, 青猫, nagai, ルー, 高際 雅之, 永劫,
+ゆんゆん探偵, りょうご(今は無きあの星), AZ-UME, 京 秋人,
+Katsumasa Tsuneyoshi, 小池潤, miahmie, サークル獏, アザナシ, はっしぃ,
+棚中製作所, わっふる/waffle, ワムソフト, TYPE-MOON, 有限会社エムツー,
+Takenori Imoto
+Kirikiri Z 64bit Project Contributors
+合資会社ワムソフト, Takenori Imoto, 他
+----------------------------------------------------------------------------
+ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満
+たす場合に限り、再頒布および使用が許可されます。
+
+・ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責
+ 条項を含めること。
+・バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の
+ 著作権表示、本条件一覧、および下記免責条項を含めること。
+・書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売
+ 促進に、組織の名前またはコントリビューターの名前を使用してはならない。
+
+本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供
+されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適
+合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありませ
+ん。著作権者もコントリビューターも、事由のいかんを問わず、損害発生の原因いか
+んを問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法
+行為であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとし
+ても、本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、
+使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されな
+い)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害に
+ついて、一切責任を負わないものとします。
+
+------------------------------------------------------------------------------
+Thanks for many libraries to contributors and other supporters that were not
+listed here.
+
+This software is based in part on the work of Independent JPEG Group.
+------------------------------------------------------------------------------
+libjpeg-turbo
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+? Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+? Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+? Neither the name of the libjpeg-turbo Project nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+Using "A C-program for MT19937"
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+libpng LICENSE
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.6.1, March 28, 2013, are
+Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+March 28, 2013
+------------------------------------------------------------------------------
+zlib LICENSE
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
+------------------------------------------------------------------------------
+
+Oniguruma LICENSE
+-----------------
+
+/*-
+ * Copyright (c) 2002-2007 K.Kosako
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+------------------------------------------------------------------------------
+ The FreeType Project LICENSE
+ ----------------------------
+
+ 2006-Jan-27
+
+ Copyright 1996-2002, 2006 by
+ David Turner, Robert Wilhelm, and Werner Lemberg
+
+
+
+Introduction
+============
+
+ The FreeType Project is distributed in several archive packages;
+ some of them may contain, in addition to the FreeType font engine,
+ various tools and contributions which rely on, or relate to, the
+ FreeType Project.
+
+ This license applies to all files found in such packages, and
+ which do not fall under their own explicit license. The license
+ affects thus the FreeType font engine, the test programs,
+ documentation and makefiles, at the very least.
+
+ This license was inspired by the BSD, Artistic, and IJG
+ (Independent JPEG Group) licenses, which all encourage inclusion
+ and use of free software in commercial and freeware products
+ alike. As a consequence, its main points are that:
+
+ o We don't promise that this software works. However, we will be
+ interested in any kind of bug reports. (`as is' distribution)
+
+ o You can use this software for whatever you want, in parts or
+ full form, without having to pay us. (`royalty-free' usage)
+
+ o You may not pretend that you wrote this software. If you use
+ it, or only parts of it, in a program, you must acknowledge
+ somewhere in your documentation that you have used the
+ FreeType code. (`credits')
+
+ We specifically permit and encourage the inclusion of this
+ software, with or without modifications, in commercial products.
+ We disclaim all warranties covering The FreeType Project and
+ assume no liability related to The FreeType Project.
+
+
+ Finally, many people asked us for a preferred form for a
+ credit/disclaimer to use in compliance with this license. We thus
+ encourage you to use the following text:
+
+ """
+ Portions of this software are copyright ゥ The FreeType
+ Project (www.freetype.org). All rights reserved.
+ """
+
+ Please replace with the value from the FreeType version you
+ actually use.
+
+
+Legal Terms
+===========
+
+0. Definitions
+--------------
+
+ Throughout this license, the terms `package', `FreeType Project',
+ and `FreeType archive' refer to the set of files originally
+ distributed by the authors (David Turner, Robert Wilhelm, and
+ Werner Lemberg) as the `FreeType Project', be they named as alpha,
+ beta or final release.
+
+ `You' refers to the licensee, or person using the project, where
+ `using' is a generic term including compiling the project's source
+ code as well as linking it to form a `program' or `executable'.
+ This program is referred to as `a program using the FreeType
+ engine'.
+
+ This license applies to all files distributed in the original
+ FreeType Project, including all source code, binaries and
+ documentation, unless otherwise stated in the file in its
+ original, unmodified form as distributed in the original archive.
+ If you are unsure whether or not a particular file is covered by
+ this license, you must contact us to verify this.
+
+ The FreeType Project is copyright (C) 1996-2000 by David Turner,
+ Robert Wilhelm, and Werner Lemberg. All rights reserved except as
+ specified below.
+
+1. No Warranty
+--------------
+
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
+ USE, OF THE FREETYPE PROJECT.
+
+2. Redistribution
+-----------------
+
+ This license grants a worldwide, royalty-free, perpetual and
+ irrevocable right and license to use, execute, perform, compile,
+ display, copy, create derivative works of, distribute and
+ sublicense the FreeType Project (in both source and object code
+ forms) and derivative works thereof for any purpose; and to
+ authorize others to exercise some or all of the rights granted
+ herein, subject to the following conditions:
+
+ o Redistribution of source code must retain this license file
+ (`FTL.TXT') unaltered; any additions, deletions or changes to
+ the original files must be clearly indicated in accompanying
+ documentation. The copyright notices of the unaltered,
+ original files must be preserved in all copies of source
+ files.
+
+ o Redistribution in binary form must provide a disclaimer that
+ states that the software is based in part of the work of the
+ FreeType Team, in the distribution documentation. We also
+ encourage you to put an URL to the FreeType web page in your
+ documentation, though this isn't mandatory.
+
+ These conditions apply to any software derived from or based on
+ the FreeType Project, not just the unmodified files. If you use
+ our work, you must acknowledge us. However, no fee need be paid
+ to us.
+
+3. Advertising
+--------------
+
+ Neither the FreeType authors and contributors nor you shall use
+ the name of the other for commercial, advertising, or promotional
+ purposes without specific prior written permission.
+
+ We suggest, but do not require, that you use one or more of the
+ following phrases to refer to this software in your documentation
+ or advertising materials: `FreeType Project', `FreeType Engine',
+ `FreeType library', or `FreeType Distribution'.
+
+ As you have not signed this license, you are not required to
+ accept it. However, as the FreeType Project is copyrighted
+ material, only this license, or another one contracted with the
+ authors, grants you the right to use, distribute, and modify it.
+ Therefore, by using, distributing, or modifying the FreeType
+ Project, you indicate that you understand and accept all the terms
+ of this license.
+
+4. Contacts
+-----------
+
+ There are two mailing lists related to FreeType:
+
+ o freetype@nongnu.org
+
+ Discusses general use and applications of FreeType, as well as
+ future and wanted additions to the library and distribution.
+ If you are looking for support, start in this list if you
+ haven't found anything to help you in the documentation.
+
+ o freetype-devel@nongnu.org
+
+ Discusses bugs, as well as engine internals, design issues,
+ specific licenses, porting, etc.
+
+ Our home page can be found at
+
+ http://www.freetype.org
+------------------------------------------------------------------------------
+picojson LICENSE
+
+/* Copyright 2009 Cybozu Labs, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of Cybozu Labs, Inc.
+ *
+ */
+------------------------------------------------------------------------------
+
+ Copyright (c) 2012, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+------------------------------------------------------------------------------
+Microsoft Corporation Technical Documentation License Agreement for the
+specification “JPEG XR Device Porting Kit”
+Copyright (c) 2013 Microsoft Corp.
+All rights reserved.
+Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BELIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE..
+------------------------------------------------------------------------------
+------------------------------------------------------------------------
+*** vorbis
+*** ogg
+
+Copyright (c) 1994-2004 Xiph.org Foundation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+- Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+------------------------------------------------------------------------
+*** theora
+
+Copyright (C) 2002-2008 Xiph.org Foundation and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of the Xiph.org Foundation nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+------------------------------------------------------------------------
+*** libfishsound
+*** dsfSeeking
+
+Copyright (C) 2003, 2004 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of the CSIRO Australia nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+------------------------------------------------------------------------
+*** libCMMLParse
+*** libCMMLTags
+*** libCMMLTagsDotNET
+*** libOOOggChef
+*** libTemporalURI
+*** libWinCMMLParse
+*** dsfCMMLDecoder
+*** dsfAnxDemux
+*** AnxCutter
+*** CMMLDump
+*** mod_oggchef
+
+Copyright (C) 2003-2005 Zentaro Kavanagh
+
+Copyright (C) 2003-2005 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of CSIRO Australia nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+------------------------------------------------------------------------
+*** dsfOggDemux
+*** dsfOggMux
+*** dsfSpeexDecoder
+*** dsfSpeexEncoder
+*** dsfVorbisDecoder
+*** dsfVorbisEncoder
+*** dsfFLACDecoder
+*** dsfFLACEncoder
+*** dsfTheoraDecoder
+*** dsfTheoraEncoder
+*** dsfAbstractAudioDecoder
+*** dsfAbstractAudioEncoder
+*** dsfAbstractVideoDecoder
+*** dsfAbstractVideoEncoder
+*** dsfSubtitleVMR9
+*** libiWrapper
+*** libilliCore
+*** libOOTheora
+*** libOOOgg
+*** libOOOggSeek
+*** libVorbisComment
+*** libVorbisCommentDotNET
+*** OOOggDump
+*** OOOggStat
+*** OOOggCommentDump
+*** CLOgg
+*** DNPlay
+*** iOCE
+
+Copyright (C) 2008-2010 Cristian Adam
+Copyright (C) 2003-2005 Zentaro Kavanagh
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+- Neither the name of Zentaro Kavanagh nor the names of contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------
diff --git a/project/android/AndroidManifest.xml b/project/android/AndroidManifest.xml
new file mode 100644
index 00000000..523d0cbe
--- /dev/null
+++ b/project/android/AndroidManifest.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/project/android/jni/Android.mk b/project/android/jni/Android.mk
new file mode 100644
index 00000000..117a9034
--- /dev/null
+++ b/project/android/jni/Android.mk
@@ -0,0 +1,43 @@
+#ndk-build MODULE_PATH=jni
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := kirikiri2
+
+LOCAL_MODULE_FILENAME := libgame
+
+LOCAL_SRC_FILES := src/SDL_android_main.cpp
+
+LOCAL_LDLIBS := -lGLESv1_CM -llog -ldl -lGLESv2 -landroid -lm
+LOCAL_LDLIBS += -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=realloc -Wl,--wrap=calloc
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../../../vendor/libgdiplus/src \
+ $(LOCAL_PATH)/../../../vendor/google_breakpad/current/src \
+ $(LOCAL_PATH)/../../../vendor/google_breakpad/current/src/common/android/include \
+ $(LOCAL_PATH)/../../../src/core/environ \
+ $(LOCAL_PATH)/../../../src/core/environ/android \
+ $(LOCAL_PATH)/../../../src/core/tjs2 \
+ $(LOCAL_PATH)/../../../src/core/base \
+ $(LOCAL_PATH)/../../../src/core/visual \
+ $(LOCAL_PATH)/../../../src/core/visual/win32 \
+ $(LOCAL_PATH)/../../../src/core/sound \
+ $(LOCAL_PATH)/../../../src/core/sound/win32 \
+ $(LOCAL_PATH)/../../../src/core/utils \
+
+LOCAL_WHOLE_STATIC_LIBRARIES := kr2plugin krkr2 krkr2_neon_opt cocos2dx_static
+#LOCAL_WHOLE_STATIC_LIBRARIES += tcmalloc
+LOCAL_STATIC_LIBRARIES := android-ndk-profiler
+LOCAL_CPPFLAGS += -Dtypeof=decltype
+
+include $(BUILD_SHARED_LIBRARY)
+$(call import-module, core)
+$(call import-module, ARM_neon)
+$(call import-module, plugins)
+#$(call import-module, png) #cocos
+#$(call import-module, jpeg) #cocos
+$(call import-module, cocos)
+#$(call import-module, tcmalloc)
+#$(call import-module, ../../../vendor/libgdiplus/jni)
\ No newline at end of file
diff --git a/project/android/jni/Application.mk b/project/android/jni/Application.mk
new file mode 100644
index 00000000..d428bd97
--- /dev/null
+++ b/project/android/jni/Application.mk
@@ -0,0 +1,9 @@
+APP_STL := gnustl_static
+APP_CPPFLAGS := -fexceptions -std=c++11
+APP_CPPFLAGS += -O3 -DNDEBUG -Wno-inconsistent-missing-override
+#APP_CPPFLAGS += -D__DO_PROF__ -g -pg
+APP_ABI := armeabi-v7a
+#APP_ABI += arm64-v8a
+APP_PLATFORM := android-9
+#NDK_TOOLCHAIN_VERSION := 4.9
+NDK_TOOLCHAIN_VERSION := clang
\ No newline at end of file
diff --git a/project/android/jni/src/SDL_android_main.cpp b/project/android/jni/src/SDL_android_main.cpp
new file mode 100644
index 00000000..2eb33e68
--- /dev/null
+++ b/project/android/jni/src/SDL_android_main.cpp
@@ -0,0 +1,277 @@
+/* Include the SDL main definition header */
+#include
+#include "platform/android/jni/JniHelper.h"
+#include "cocos2d/AppDelegate.h"
+#include "cocos2d/MainScene.h"
+#include "ConfigManager/GlobalConfigManager.h"
+
+/*******************************************************************************
+ Functions called by JNI
+*******************************************************************************/
+#include
+#include
+#include
+#include
+#include "client/linux/handler/exception_handler.h"
+#include "client/linux/handler/minidump_descriptor.h"
+
+//std::string Android_GetDumpStoragePath();
+void start_profile() {}
+void stop_profile() {}
+
+static bool __DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
+ void* context, bool succeeded)
+{
+ return succeeded;
+}
+
+extern bool TVPSystemUninitCalled;
+
+static bool __DumpFilter(void *data) {
+ if(TVPSystemUninitCalled) return false; // if trying exit system, ignore all exception
+ return true;
+}
+
+
+//static void __InitAndroidDump() {
+// static google_breakpad::MinidumpDescriptor descriptor(Android_GetDumpStoragePath());
+// static google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback,
+// NULL, true, -1);
+//}
+
+void cocos_android_app_init (JNIEnv* env) { // for cocos3.10+
+// __InitAndroidDump();
+ static TVPAppDelegate *pAppDelegate = new TVPAppDelegate();
+}
+
+void cocos_android_app_init(JNIEnv* env, jobject thiz) {
+// __InitAndroidDump();
+ static TVPAppDelegate *pAppDelegate = new TVPAppDelegate();
+}
+
+namespace kr2android {
+ extern std::condition_variable MessageBoxCond;
+ extern std::mutex MessageBoxLock;
+ extern int MsgBoxRet;
+ extern std::string MessageBoxRetText;
+}
+void Android_PushEvents(const std::function &func);
+using namespace kr2android;
+extern "C" {
+ void Java_org_tvp_kirikiri2_KR2Activity_initDump(JNIEnv* env, jclass cls, jstring path) {
+ const char* pszPath = env->GetStringUTFChars(path, NULL);
+ if (pszPath && *pszPath) {
+ static google_breakpad::MinidumpDescriptor descriptor(pszPath);
+ static google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback,
+ NULL, true, -1);
+ }
+ env->ReleaseStringUTFChars(path, pszPath);
+ }
+
+ void Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxOK(JNIEnv* env, jclass cls, jint nButton) {
+ MsgBoxRet = nButton;
+ MessageBoxCond.notify_one();
+ }
+
+ void Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxText(JNIEnv* env, jclass cls, jstring text) {
+ const char* pszText = env->GetStringUTFChars(text, NULL);
+ if (pszText && *pszText) {
+ MessageBoxRetText = pszText;
+ }
+ env->ReleaseStringUTFChars(text, pszText);
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
+ intptr_t idlong = id;
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);
+ });
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
+ intptr_t idlong = id;
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);
+ });
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesMove(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
+ int size = env->GetArrayLength(ids);
+ if (size == 1) {
+ intptr_t idlong;
+ jint id;
+ jfloat x;
+ jfloat y;
+ env->GetIntArrayRegion(ids, 0, size, &id);
+ env->GetFloatArrayRegion(xs, 0, size, &x);
+ env->GetFloatArrayRegion(ys, 0, size, &y);
+ idlong = id;
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);
+ });
+ return;
+ }
+
+ jint id[size];
+ std::vector x; x.resize(size);
+ std::vector y; y.resize(size);
+
+ env->GetIntArrayRegion(ids, 0, size, id);
+ env->GetFloatArrayRegion(xs, 0, size, &x[0]);
+ env->GetFloatArrayRegion(ys, 0, size, &y[0]);
+
+ std::vector idlong; idlong.resize(size);
+ for (int i = 0; i < size; i++)
+ idlong[i] = id[i];
+
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]);
+ });
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesCancel(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
+ int size = env->GetArrayLength(ids);
+ if (size == 1) {
+ intptr_t idlong;
+ jint id;
+ jfloat x;
+ jfloat y;
+ env->GetIntArrayRegion(ids, 0, size, &id);
+ env->GetFloatArrayRegion(xs, 0, size, &x);
+ env->GetFloatArrayRegion(ys, 0, size, &y);
+ idlong = id;
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(1, (intptr_t*)&idlong, (float*)&x, (float*)&y);
+ });
+ return;
+ }
+
+ jint id[size];
+ std::vector x; x.resize(size);
+ std::vector y; y.resize(size);
+
+ env->GetIntArrayRegion(ids, 0, size, id);
+ env->GetFloatArrayRegion(xs, 0, size, &x[0]);
+ env->GetFloatArrayRegion(ys, 0, size, &y[0]);
+
+ std::vector idlong; idlong.resize(size);
+ for (int i = 0; i < size; i++)
+ idlong[i] = id[i];
+
+ Android_PushEvents([idlong, x, y](){
+ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]);
+ });
+ }
+
+#define KEYCODE_BACK 0x04
+#define KEYCODE_MENU 0x52
+#define KEYCODE_DPAD_UP 0x13
+#define KEYCODE_DPAD_DOWN 0x14
+#define KEYCODE_DPAD_LEFT 0x15
+#define KEYCODE_DPAD_RIGHT 0x16
+#define KEYCODE_ENTER 0x42
+#define KEYCODE_PLAY 0x7e
+#define KEYCODE_DPAD_CENTER 0x17
+#define KEYCODE_DEL 0x43
+
+ JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeKeyAction(JNIEnv * env, jclass cls, jint keyCode, jboolean isPress) {
+ cocos2d::EventKeyboard::KeyCode pKeyCode;
+ switch (keyCode) {
+ case KEYCODE_BACK : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ESCAPE ; break;
+ case KEYCODE_MENU : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_MENU ; break;
+ case KEYCODE_DPAD_UP : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_UP ; break;
+ case KEYCODE_DPAD_DOWN : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_DOWN ; break;
+ case KEYCODE_DPAD_LEFT : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_LEFT ; break;
+ case KEYCODE_DPAD_RIGHT : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_RIGHT; break;
+ case KEYCODE_ENTER : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ENTER ; break;
+ case KEYCODE_PLAY : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_PLAY ; break;
+ case KEYCODE_DPAD_CENTER: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_CENTER; break;
+ case KEYCODE_DEL : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE; break;
+ default: return JNI_FALSE;
+ }
+
+ Android_PushEvents([pKeyCode, isPress](){
+ cocos2d::EventKeyboard event(pKeyCode, isPress);
+ cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
+ });
+ return JNI_TRUE;
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeInsertText(JNIEnv* env, jclass cls, jstring text) {
+ const char* pszText = env->GetStringUTFChars(text, NULL);
+ if (pszText && *pszText) {
+ std::string str = pszText;
+ Android_PushEvents([str](){
+ cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(str.c_str(), str.length());
+ });
+ }
+ env->ReleaseStringUTFChars(text, pszText);
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeDeleteBackward(JNIEnv* env, jclass cls) {
+ Android_PushEvents(std::bind(&cocos2d::IMEDispatcher::dispatchDeleteBackward,
+ cocos2d::IMEDispatcher::sharedDispatcher()));
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCharInput(JNIEnv* env, jclass cls, jint keyCode) {
+ TVPMainScene *pScene = TVPMainScene::GetInstance();
+ if (!pScene) return;
+ pScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onCharInput, keyCode));
+ }
+
+ JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCommitText(
+ JNIEnv* env, jclass cls,
+ jstring text, jint newCursorPosition)
+ {
+ TVPMainScene *pScene = TVPMainScene::GetInstance();
+ if (!pScene) return;
+ const char *utftext = env->GetStringUTFChars(text, NULL);
+ std::string str(utftext);
+ pScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onTextInput, str));
+ env->ReleaseStringUTFChars(text, utftext);
+ }
+
+ JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeGetHideSystemButton(JNIEnv* env, jclass cls)
+ {
+ return GlobalConfigManager::GetInstance()->GetValue("hide_android_sys_btn", false);
+ }
+
+ static float _mouseX, _mouseY;
+
+ JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeHoverMoved(JNIEnv* env, jclass cls, jfloat x, jfloat y)
+ {
+ Android_PushEvents([x, y]() {
+ cocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView();
+ float _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY();
+ _mouseX = x; _mouseY = y;
+ const cocos2d::Rect _viewPortRect = glview->getViewPortRect();
+
+ float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;
+ float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;
+
+ cocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_MOVE);
+ event.setCursorPosition(cursorX, cursorY);
+ cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
+ });
+ return true;
+ }
+
+ JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeMouseScrolled(JNIEnv* env, jclass cls, jfloat v)
+ {
+ Android_PushEvents([v]() {
+ cocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView();
+ float _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY();
+ const cocos2d::Rect _viewPortRect = glview->getViewPortRect();
+
+ float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;
+ float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;
+
+ cocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_SCROLL);
+ event.setScrollData(0, v);
+ event.setCursorPosition(cursorX, cursorY);
+ cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
+ });
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/project/android/project.properties b/project/android/project.properties
new file mode 100644
index 00000000..7f89e8a8
--- /dev/null
+++ b/project/android/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-22
+android.library.reference.1=../../vendor/cocos2d-x/current/cocos/platform/android/java
diff --git a/project/android/src/org/tvp/kirikiri2/KR2Activity.java b/project/android/src/org/tvp/kirikiri2/KR2Activity.java
new file mode 100644
index 00000000..dc35e694
--- /dev/null
+++ b/project/android/src/org/tvp/kirikiri2/KR2Activity.java
@@ -0,0 +1,1229 @@
+package org.tvp.kirikiri2;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.cocos2dx.lib.Cocos2dxActivity;
+import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.graphics.PixelFormat;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.os.storage.StorageManager;
+import android.preference.PreferenceManager;
+import android.provider.BaseColumns;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.provider.Settings.Secure;
+import android.support.annotation.NonNull;
+import android.support.v4.provider.DocumentFile;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ * Utility class for handling the media store.
+ */
+abstract class MediaStoreUtil {
+ public static Uri getUriFromFile(final String path,Context context) {
+ ContentResolver resolver = context.getContentResolver();
+
+ Cursor filecursor = resolver.query(MediaStore.Files.getContentUri("external"),
+ new String[] { BaseColumns._ID }, MediaColumns.DATA + " = ?",
+ new String[] { path }, MediaColumns.DATE_ADDED + " desc");
+ filecursor.moveToFirst();
+
+ if (filecursor.isAfterLast()) {
+ filecursor.close();
+ ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, path);
+ return resolver.insert(MediaStore.Files.getContentUri("external"), values);
+ }
+ else {
+ int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID));
+ Uri uri = MediaStore.Files.getContentUri("external").buildUpon().appendPath(
+ Integer.toString(imageId)).build();
+ filecursor.close();
+ return uri;
+ }
+ }
+
+ public static final void addFileToMediaStore(final String path,Context context) {
+ Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+ File file = new File(path);
+ Uri contentUri = Uri.fromFile(file);
+ mediaScanIntent.setData(contentUri);
+ context.sendBroadcast(mediaScanIntent);
+ }
+
+ /**
+ * Retrieve a thumbnail of a bitmap from the mediastore.
+ *
+ * @param path
+ * The path of the image
+ * @param maxSize
+ * The maximum size of this bitmap (used for selecting the sample size)
+ * @return the thumbnail.
+ */
+
+ /**
+ * Delete the thumbnail of a bitmap.
+ *
+ * @param path
+ * The path of the image
+ */
+
+}
+
+/* This is a fake invisible editor view that receives the input and defines the
+ * pan&scan region
+ */
+class DummyEdit extends View implements View.OnKeyListener {
+ InputConnection ic;
+
+ public DummyEdit(Context context) {
+ super(context);
+ setFocusableInTouchMode(true);
+ setFocusable(true);
+ setOnKeyListener(this);
+ }
+
+ @Override
+ public boolean onCheckIsTextEditor() {
+ return true;
+ }
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+
+ // This handles the hardware keyboard input
+ if (event.isPrintingKey()) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ }
+ return true;
+ }
+
+// if (event.getAction() == KeyEvent.ACTION_DOWN) {
+// KR2Activity.nativeKeyAction(keyCode, true);
+// return true;
+// } else if (event.getAction() == KeyEvent.ACTION_UP) {
+// KR2Activity.nativeKeyAction(keyCode, false);
+// return true;
+// }
+
+ return false;
+ }
+
+ //
+ @Override
+ public boolean onKeyPreIme (int keyCode, KeyEvent event) {
+ // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
+ // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
+ // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
+ // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
+ // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
+ // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
+ if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
+ if (KR2Activity.mTextEdit != null && KR2Activity.mTextEdit.getVisibility() == View.VISIBLE) {
+ KR2Activity.hideTextInput();
+ //KR2Activity.nativeKeyboardFocusLost();
+ }
+ }
+ return super.onKeyPreIme(keyCode, event);
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ ic = new SDLInputConnection(this, true);
+
+ outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
+ | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
+
+ return ic;
+ }
+}
+
+class SDLInputConnection extends BaseInputConnection {
+
+ public SDLInputConnection(View targetView, boolean fullEditor) {
+ super(targetView, fullEditor);
+
+ }
+
+ @Override
+ public boolean sendKeyEvent(KeyEvent event) {
+ /*
+ * This handles the keycodes from soft keyboard (and IME-translated
+ * input from hardkeyboard)
+ */
+ int keyCode = event.getKeyCode();
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ if (event.isPrintingKey()) {
+ commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ KR2Activity.nativeCharInput(keyCode);
+ } else if(keyCode == KeyEvent.KEYCODE_DEL) {
+ KR2Activity.nativeKeyAction(keyCode, true);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ if(keyCode == KeyEvent.KEYCODE_DEL) {
+ KR2Activity.nativeKeyAction(keyCode, false);
+ }
+ //KR2Activity.nativeKeyAction(keyCode, false);
+ return true;
+ }
+ return super.sendKeyEvent(event);
+ }
+
+ @Override
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+
+ KR2Activity.nativeCommitText(text.toString(), newCursorPosition);
+
+ return super.commitText(text, newCursorPosition);
+ }
+
+ @Override
+ public boolean setComposingText(CharSequence text, int newCursorPosition) {
+
+ //nativeSetComposingText(text.toString(), newCursorPosition);
+
+ return super.setComposingText(text, newCursorPosition);
+ }
+
+ //public native void nativeSetComposingText(String text, int newCursorPosition);
+
+ @Override
+ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+ // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
+ if (beforeLength == 1 && afterLength == 0) {
+ // backspace
+ return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
+ && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
+ }
+
+ return super.deleteSurroundingText(beforeLength, afterLength);
+ }
+}
+
+public class KR2Activity extends Cocos2dxActivity {
+ static ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
+ static ActivityManager mAcitivityManager = null;
+ static Debug.MemoryInfo mDbgMemoryInfo = new Debug.MemoryInfo();
+ public static void updateMemoryInfo() {
+ if(mAcitivityManager == null) {
+ mAcitivityManager =(ActivityManager)sInstance.getSystemService(Activity.ACTIVITY_SERVICE);
+ }
+ mAcitivityManager.getMemoryInfo(memoryInfo);
+ Debug.getMemoryInfo(mDbgMemoryInfo);
+ }
+
+ public static long getAvailMemory() {
+ return memoryInfo.availMem;
+ }
+
+ public static long getUsedMemory() {
+ return mDbgMemoryInfo.getTotalPss(); // in kB
+ }
+
+ static public String getDeviceId() {
+ TelephonyManager mgr = (TelephonyManager)GetInstance().getSystemService(Context.TELEPHONY_SERVICE);
+ String DeviceID = mgr.getDeviceId();
+ if(DeviceID != null) {
+ return "DevID:" + DeviceID;
+ }
+ String androidId = Secure.getString(GetInstance().getContentResolver(), Secure.ANDROID_ID);
+ if (null != androidId && androidId.length() > 8 &&
+ (!"9774d56d682e549c".equals(androidId)) ) {
+ return "AndroidID:" + androidId;
+ } else if(null != android.os.Build.SERIAL && android.os.Build.SERIAL.length() > 3) {
+ return "AndroidID:" + android.os.Build.SERIAL;
+ }
+ return "";
+ }
+
+ static public KR2Activity sInstance;
+ static public KR2Activity GetInstance() {return sInstance;}
+
+ static {
+ System.loadLibrary("ffmpeg");
+ System.loadLibrary("game");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ sInstance = this;
+ Sp = PreferenceManager.getDefaultSharedPreferences(this);
+ super.onCreate(savedInstanceState);
+
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
+ for(String path : getExtSdCardPaths(this)) {
+ if (!isWritableNormalOrSaf(path)) {
+ guideDialogForLEXA(path);
+ }
+ }
+ }
+
+ initDump(this.getFilesDir().getAbsolutePath() + "/dump");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ System.exit(0);
+ }
+
+ static class DialogMessage
+ {
+ public String Title;
+ public String Text;
+ public String[] Buttons;
+ public EditText TextEditor = null;
+
+ public DialogMessage()
+ {
+ }
+
+ public void Init(final String title, final String text, final String[] buttons)
+ {
+ this.Title = title;
+ this.Text = text;
+ this.Buttons = buttons;
+ }
+
+ void onButtonClick(int n) {
+ if(TextEditor != null) {
+ onMessageBoxText(TextEditor.getText().toString());
+ }
+ onMessageBoxOK(n);
+ }
+
+ public AlertDialog.Builder CreateBuilder() {
+ /* TextView showText = new TextView(sInstance);
+ showText.setText(Text);
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
+ showText.setTextIsSelectable(true);*/
+ AlertDialog.Builder builder = new AlertDialog.Builder(sInstance).
+ setTitle(Title).
+ setMessage(Text).
+ //setView(showText).
+ setCancelable(false);
+ if(Buttons.length >= 1) {
+ builder = builder.setPositiveButton(Buttons[0], new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onButtonClick(0);
+ }
+ });
+ }
+ if(Buttons.length >= 2) {
+ builder = builder.setNeutralButton(Buttons[1], new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onButtonClick(1);
+ }
+ });
+ }
+ if(Buttons.length >= 3) {
+ builder = builder.setNegativeButton(Buttons[2], new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onButtonClick(2);
+ }
+ });
+ }
+ return builder;
+ }
+
+ public void ShowMessageBox()
+ {
+ CreateBuilder().create().show();
+ }
+
+ public void ShowInputBox(final String text) {
+ AlertDialog.Builder builder = CreateBuilder();
+ TextEditor = new EditText(sInstance);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT);
+ TextEditor.setLayoutParams(lp);
+ TextEditor.setText(text);
+ builder.setView(TextEditor);
+ AlertDialog ad = builder.create();
+ ad.show();
+ TextEditor.requestFocus();
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(TextEditor, 0);
+ }
+ }
+ static DialogMessage mDialogMessage = new DialogMessage();
+
+ protected static View mTextEdit = null;
+ SharedPreferences Sp;
+
+ static Handler msgHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ sInstance.handleMessage(msg);
+ }
+ };
+
+ public void handleMessage(Message msg) {
+
+ }
+
+ static public void ShowMessageBox(final String title, final String text, final String[] Buttons) {
+ mDialogMessage.Init(title, text, Buttons);
+ msgHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDialogMessage.ShowMessageBox();
+ }
+ });
+ }
+
+ static public void ShowInputBox(final String title, final String prompt, final String text, final String[] Buttons) {
+ mDialogMessage.Init(title, prompt, Buttons);
+ msgHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDialogMessage.ShowInputBox(text);
+ }
+ });
+ }
+
+ static class ShowTextInputTask implements Runnable {
+ /*
+ * This is used to regulate the pan&scan method to have some offset from
+ * the bottom edge of the input region and the top edge of an input
+ * method (soft keyboard)
+ */
+ static final int HEIGHT_PADDING = 15;
+
+ public int x, y, w, h;
+
+ public ShowTextInputTask(int x, int y, int w, int h) {
+ this.x = x;
+ this.y = y;
+ this.w = w;
+ this.h = h;
+ }
+
+ @Override
+ public void run() {
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(w, h + HEIGHT_PADDING);
+ params.leftMargin = x;
+ params.topMargin = y;
+
+ if (mTextEdit == null) {
+ mTextEdit = new DummyEdit(getContext());
+
+ sInstance.mFrameLayout.addView(mTextEdit, params);
+ } else {
+ mTextEdit.setLayoutParams(params);
+ }
+
+ mTextEdit.setVisibility(View.VISIBLE);
+ mTextEdit.requestFocus();
+
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mTextEdit, 0);
+ }
+ }
+
+ static public void showTextInput(int x, int y, int w, int h) {
+ msgHandler.post(new ShowTextInputTask(x, y, w, h));
+ }
+ static public void hideTextInput() {
+ msgHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mTextEdit != null) {
+ mTextEdit.setVisibility(View.GONE);
+ InputMethodManager imm = (InputMethodManager) sInstance.getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
+ }
+ }
+ });
+ }
+
+ static private native void onMessageBoxOK(int nButton);
+ static private native void onMessageBoxText(String text);
+ static private native void onNativeExit();
+ static public native void onNativeInit();
+ static public native void onBannerSizeChanged(int w, int h);
+ static private native void initDump(String path);
+
+ static public void MessageController(int what, int arg1, int arg2) {
+ Message msg = msgHandler.obtainMessage();
+ msg.what = what;
+ msg.arg1 = arg1;
+ msg.arg2 = arg2;
+ msgHandler.sendMessage(msg);
+ }
+
+ static public String GetVersion() {
+ String verstr = null;
+ try {
+ verstr = sInstance.getPackageManager().getPackageInfo(sInstance.getPackageName(), 0).versionName;
+ } catch (NameNotFoundException e1) {
+ }
+ return verstr;
+ }
+
+ StorageManager mStorageManager = null;
+ Method mMethodGetPaths = null;
+ Method mGetVolumeState = null;
+
+ public String[] getStoragePath() {
+ String[] ret = new String[0];
+ if(mStorageManager == null) {
+ mStorageManager = (StorageManager)getSystemService(STORAGE_SERVICE);
+ try {
+ mMethodGetPaths = StorageManager.class.getMethod("getVolumePaths");
+ mGetVolumeState = StorageManager.class.getMethod("getVolumeState", String.class);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+ if(mMethodGetPaths != null) {
+ try {
+ ret = (String[])mMethodGetPaths.invoke(mStorageManager);
+ } catch (IllegalArgumentException e) {
+
+ } catch (IllegalAccessException e) {
+
+ } catch (InvocationTargetException e) {
+
+ } catch (Exception e) {
+
+ }
+ }
+
+ if(mGetVolumeState != null) {
+ try {
+ for(int i = 0; i < ret.length; ++i) {
+ String status = (String)mGetVolumeState.invoke(mStorageManager, ret[i]);
+ if(Environment.MEDIA_MOUNTED.equals(status) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)) {
+ ;
+ } else {
+ ret[i] = null;
+ }
+ }
+ } catch (IllegalArgumentException e) {
+
+ } catch (IllegalAccessException e) {
+
+ } catch (InvocationTargetException e) {
+
+ } catch (Exception e) {
+
+ }
+ }
+
+ return ret;
+ }
+
+ private static native void nativeTouchesBegin(final int id, final float x, final float y);
+ private static native void nativeTouchesEnd(final int id, final float x, final float y);
+ private static native void nativeTouchesMove(final int[] ids, final float[] xs, final float[] ys);
+ private static native void nativeTouchesCancel(final int[] ids, final float[] xs, final float[] ys);
+ public static native boolean nativeKeyAction(final int keyCode, final boolean isPress);
+ public static native void nativeCharInput(final int keyCode);
+ public static native void nativeCommitText(String text, int newCursorPosition);
+
+ private static native void nativeInsertText(final String text);
+ public static native void nativeDeleteBackward();
+ private static native String nativeGetContentText();
+ private static native void nativeHoverMoved(final float x, final float y);
+ private static native void nativeMouseScrolled(final float scroll);
+
+ class KR2GLSurfaceView extends Cocos2dxGLSurfaceView {
+
+ public KR2GLSurfaceView(final Context context) {
+ super(context);
+ }
+
+ public KR2GLSurfaceView(final Context context, final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void insertText(final String pText) {
+ nativeInsertText(pText);
+ }
+
+ @Override
+ public void deleteBackward() {
+ nativeDeleteBackward();
+ }
+
+ @Override
+ public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
+ switch (pKeyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ case KeyEvent.KEYCODE_MENU:
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ case KeyEvent.KEYCODE_DPAD_UP:
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ nativeKeyAction(pKeyCode, true);
+ return true;
+ default:
+ return super.onKeyDown(pKeyCode, pKeyEvent);
+ }
+ }
+
+ @Override
+ public boolean onKeyUp(final int pKeyCode, final KeyEvent pKeyEvent) {
+ switch (pKeyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ case KeyEvent.KEYCODE_MENU:
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ case KeyEvent.KEYCODE_DPAD_UP:
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ nativeKeyAction(pKeyCode, false);
+ return true;
+ default:
+ return super.onKeyUp(pKeyCode, pKeyEvent);
+ }
+ }
+
+ @Override
+ public boolean onHoverEvent(final MotionEvent pMotionEvent) {
+ final int pointerNumber = pMotionEvent.getPointerCount();
+ final float[] xs = new float[pointerNumber];
+ final float[] ys = new float[pointerNumber];
+ for (int i = 0; i < pointerNumber; i++) {
+ xs[i] = pMotionEvent.getX(i);
+ ys[i] = pMotionEvent.getY(i);
+ }
+
+ switch(pMotionEvent.getActionMasked()) {
+ case MotionEvent.ACTION_HOVER_MOVE:
+ nativeHoverMoved(xs[0], ys[0]);
+ break;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onTouchEvent(final MotionEvent pMotionEvent) {
+
+ // these data are used in ACTION_MOVE and ACTION_CANCEL
+ final int pointerNumber = pMotionEvent.getPointerCount();
+ final int[] ids = new int[pointerNumber];
+ final float[] xs = new float[pointerNumber];
+ final float[] ys = new float[pointerNumber];
+
+ for (int i = 0; i < pointerNumber; i++) {
+ ids[i] = pMotionEvent.getPointerId(i);
+ xs[i] = pMotionEvent.getX(i);
+ ys[i] = pMotionEvent.getY(i);
+ }
+
+ switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
+ final float xPointerDown = pMotionEvent.getX(indexPointerDown);
+ final float yPointerDown = pMotionEvent.getY(indexPointerDown);
+ nativeTouchesBegin(idPointerDown, xPointerDown, yPointerDown);
+ break;
+
+ case MotionEvent.ACTION_DOWN:
+ // there are only one finger on the screen
+ final int idDown = pMotionEvent.getPointerId(0);
+ final float xDown = xs[0];
+ final float yDown = ys[0];
+ nativeTouchesBegin(idDown, xDown, yDown);
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ nativeTouchesMove(ids, xs, ys);
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
+ final float xPointerUp = pMotionEvent.getX(indexPointUp);
+ final float yPointerUp = pMotionEvent.getY(indexPointUp);
+ nativeTouchesEnd(idPointerUp, xPointerUp, yPointerUp);
+ break;
+
+ case MotionEvent.ACTION_UP:
+ // there are only one finger on the screen
+ final int idUp = pMotionEvent.getPointerId(0);
+ final float xUp = xs[0];
+ final float yUp = ys[0];
+ nativeTouchesEnd(idUp, xUp, yUp);
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ nativeTouchesCancel(ids, xs, ys);
+ break;
+ }
+
+ /*
+ if (BuildConfig.DEBUG) {
+ Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);
+ }
+ */
+ return true;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_SCROLL:
+ float v = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ nativeMouseScrolled(-v);
+ return true;
+ default:
+ break;
+ }
+ return super.onGenericMotionEvent(event);
+ }
+ }
+
+ @Override
+ public Cocos2dxGLSurfaceView onCreateView() {
+ Cocos2dxGLSurfaceView glSurfaceView = new KR2GLSurfaceView(this);
+ hideSystemUI();
+ //this line is need on some device if we specify an alpha bits
+ if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+
+ Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs);
+ glSurfaceView.setEGLConfigChooser(chooser);
+
+ return glSurfaceView;
+ }
+
+ public int get_res_sd_operate_step() { return -1; }
+
+ void guideDialogForLEXA(String path) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ ImageView image = new ImageView(this);
+ image.setImageResource(get_res_sd_operate_step());
+ builder
+ .setView(image)
+ .setTitle(path)
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ triggerStorageAccessFramework();
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // nothing to do
+ }
+ })
+ .show();
+ }
+
+ static final boolean isWritable(final File file) {
+ if(file==null)
+ return false;
+ boolean isExisting = file.exists();
+
+ try {
+ FileOutputStream output = new FileOutputStream(file, true);
+ try {
+ output.close();
+ }
+ catch (IOException e) {
+ // do nothing.
+ }
+ }
+ catch (FileNotFoundException e) {
+ return false;
+ }
+ boolean result = file.canWrite();
+
+ // Ensure that file is not created during this process.
+ if (!isExisting) {
+ file.delete();
+ }
+
+ return result;
+ }
+
+ static final boolean isWritableNormalOrSaf(final String path) {
+ Context c = sInstance;
+ File folder = new File(path);
+ if (!folder.exists() || !folder.isDirectory()) {
+ return false;
+ }
+
+ // Find a non-existing file in this directory.
+ int i = 0;
+ File file;
+ do {
+ String fileName = "AugendiagnoseDummyFile" + (++i);
+ file = new File(folder, fileName);
+ }
+ while (file.exists());
+
+ // First check regular writability
+ if (isWritable(file)) {
+ return true;
+ }
+
+ // Next check SAF writability.
+ DocumentFile document = getDocumentFile(file, false,c);
+
+ if (document == null) {
+ return false;
+ }
+
+ // This should have created the file - otherwise something is wrong with access URL.
+ boolean result = document.canWrite() && file.exists();
+
+ // Ensure that the dummy file is not remaining.
+ document.delete();
+
+ return result;
+ }
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ private static String[] getExtSdCardPaths(Context context) {
+ List paths = new ArrayList();
+ for (File file : context.getExternalFilesDirs("external")) {
+ if (file != null && !file.equals(context.getExternalFilesDir("external"))) {
+ int index = file.getAbsolutePath().lastIndexOf("/Android/data");
+ if (index < 0) {
+ Log.w("FileUtils", "Unexpected external file dir: " + file.getAbsolutePath());
+ } else {
+ String path = file.getAbsolutePath().substring(0, index);
+ try {
+ path = new File(path).getCanonicalPath();
+ }
+ catch (IOException e) {
+ // Keep non-canonical path.
+ }
+ paths.add(path);
+ }
+ }
+ }
+ //if(paths.isEmpty())paths.add("/storage/sdcard1");
+ return paths.toArray(new String[0]);
+ }
+ static String[] _extSdPaths;
+
+ public static String getExtSdCardFolder(final File file,Context context) {
+ if(_extSdPaths == null)
+ _extSdPaths = getExtSdCardPaths(context);
+ try {
+ for (int i = 0; i < _extSdPaths.length; i++) {
+ if (file.getCanonicalPath().startsWith(_extSdPaths[i])) {
+ return _extSdPaths[i];
+ }
+ }
+ }
+ catch (IOException e) {
+ return null;
+ }
+ return null;
+ }
+
+ public static boolean isOnExtSdCard(final File file,Context c) {
+ return getExtSdCardFolder(file,c) != null;
+ }
+
+ public static DocumentFile getDocumentFile(final File file, final boolean isDirectory,Context context) {
+ String baseFolder = getExtSdCardFolder(file,context);
+ boolean originalDirectory=false;
+ if (baseFolder == null) {
+ return null;
+ }
+
+ String relativePath = null;
+ try {
+ String fullPath = file.getCanonicalPath();
+ if(!baseFolder.equals(fullPath))
+ relativePath = fullPath.substring(baseFolder.length() + 1);
+ else originalDirectory=true;
+ }
+ catch (IOException e) {
+ return null;
+ }
+ catch (Exception f){
+ originalDirectory=true;
+ //continue
+ }
+ String as=PreferenceManager.getDefaultSharedPreferences(context).getString("URI",null);
+
+ Uri treeUri =null;
+ if(as!=null)treeUri=Uri.parse(as);
+ if (treeUri == null) {
+ return null;
+ }
+
+ // start with root of SD card and then parse through document tree.
+ DocumentFile document = DocumentFile.fromTreeUri(context, treeUri);
+ if(originalDirectory)return document;
+ String[] parts = relativePath.split("\\/");
+ for (int i = 0; i < parts.length; i++) {
+ DocumentFile nextDocument = document.findFile(parts[i]);
+ if (nextDocument == null) {
+ try {
+ if ((i < parts.length - 1) || isDirectory) {
+ nextDocument = document.createDirectory(parts[i]);
+ } else {
+ nextDocument = document.createFile("image", parts[i]);
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ document = nextDocument;
+ }
+
+ return document;
+ }
+
+ static public boolean RenameFile(String from, String to) {
+ File file = new File(from);
+ File target = new File(to);
+ if(!file.exists())
+ return false;
+ if(target.exists()) {
+ if(!DeleteFile(target.getAbsolutePath())) return false;
+ }
+
+ File parent = target.getParentFile();
+ if(!parent.exists()) {
+ if(!CreateFolders(parent.getAbsolutePath())) return false;
+ }
+ // Try the normal way
+ if(file.renameTo(target)) return true;
+
+ // Try with Storage Access Framework.
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) {
+ DocumentFile document = getDocumentFile(file, false, sInstance);
+ if(document.renameTo(to))
+ return true;
+ }
+
+ // Try Media Store Hack
+ if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
+ try {
+ FileInputStream input = new FileInputStream(file);
+ int filesize = (int) file.length();
+ byte []buffer = new byte[filesize];
+ input.read(buffer);
+ input.close();
+ OutputStream out = MediaStoreHack.getOutputStream(sInstance, target.getAbsolutePath());
+ out.write(buffer);
+ out.close();
+ return MediaStoreHack.delete(sInstance, file);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ return false;
+ //e.printStackTrace();
+ }
+ }
+
+ return false;
+ }
+
+ public static final boolean deleteFilesInFolder(final File folder,Context context) {
+ boolean totalSuccess = true;
+ if(folder==null)
+ return false;
+ if (folder.isDirectory()) {
+ for (File child : folder.listFiles()) {
+ deleteFilesInFolder(child, context);
+ }
+
+ if (!folder.delete())
+ totalSuccess = false;
+ } else {
+
+ if (!folder.delete())
+ totalSuccess = false;
+ }
+ return totalSuccess;
+ }
+
+ static public boolean DeleteFile(String path) {
+ File file = new File(path);
+ // First try the normal deletion.
+ boolean fileDelete = deleteFilesInFolder(file, sInstance);
+ if (file.delete() || fileDelete)
+ return true;
+
+ // Try with Storage Access Framework.
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP && isOnExtSdCard(file, sInstance)) {
+
+ DocumentFile document = getDocumentFile(file, false,sInstance);
+ return document.delete();
+ }
+
+ // Try the Kitkat workaround.
+ if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
+ ContentResolver resolver = sInstance.getContentResolver();
+
+ try {
+ Uri uri = MediaStoreHack.getUriFromFile(file.getAbsolutePath(),sInstance);
+ resolver.delete(uri, null, null);
+ return !file.exists();
+ }
+ catch (Exception e) {
+ Log.e("FileUtils", "Error when deleting file " + file.getAbsolutePath(), e);
+ return false;
+ }
+ }
+
+ return !file.exists();
+ }
+
+ public static OutputStream getOutputStream(@NonNull final File target,Context context,long s)throws Exception {
+ OutputStream outStream = null;
+ try {
+ // First try the normal way
+ if (isWritable(target)) {
+ // standard way
+ outStream = new FileOutputStream(target);
+ } else {
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
+ // Storage Access Framework
+ DocumentFile targetDocument = getDocumentFile(target, false,context);
+ outStream = context.getContentResolver().openOutputStream(targetDocument.getUri());
+ } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
+ // Workaround for Kitkat ext SD card
+ return MediaStoreHack.getOutputStream(context,target.getPath());
+ }
+ }
+ } catch (Exception e) {
+ Log.e("FileUtils",
+ "Error when copying file from " + target.getAbsolutePath(), e);
+ }
+ return outStream;
+ }
+
+
+ static public boolean WriteFile(String path, byte data[]) {
+ File target = new File(path);
+ if(target.exists()) {
+ DeleteFile(target.getAbsolutePath()); // to avoid number suffix name
+ } else {
+ File parent = target.getParentFile();
+ if(!parent.exists())
+ CreateFolders(parent.getAbsolutePath());
+ }
+ OutputStream out = null;
+
+ // Try the normal way
+ try {
+ if(isWritable(target)) {
+ OutputStream os = new FileOutputStream(target);
+ os.write(data);
+ os.close();
+ return true;
+ }
+
+ // Try with Storage Access Framework.
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) {
+ DocumentFile document = getDocumentFile(target, false, sInstance);
+ try {
+ Uri docUri = document.getUri();
+ out = sInstance.getContentResolver().openOutputStream(docUri);
+ } catch (FileNotFoundException e) {
+ // e.printStackTrace();
+ } catch (IOException e) {
+ // e.printStackTrace();
+ }
+ } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
+ // Workaround for Kitkat ext SD card
+ Uri uri = MediaStoreHack.getUriFromFile(target.getAbsolutePath(),sInstance);
+ out = sInstance.getContentResolver().openOutputStream(uri);
+ } else {
+ return false;
+ }
+
+ if (out != null) {
+ out.write(data);
+ out.close();
+ return true;
+ }
+ } catch (FileNotFoundException e) {
+ //return false;
+ } catch (IOException e) {
+ //return false;
+ }
+
+ return false;
+ }
+
+ static public boolean CreateFolders(String path) {
+ File file = new File(path);
+
+ // Try the normal way
+ if(file.mkdirs()) {
+ return true;
+ }
+
+ // Try with Storage Access Framework.
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& FileUtil.isOnExtSdCard(file, context)*/) {
+ DocumentFile document = getDocumentFile(file, true,sInstance);
+ // getDocumentFile implicitly creates the directory.
+
+ return document.exists();
+ }
+
+ // Try the Kitkat workaround.
+ if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
+ try {
+ return MediaStoreHack.mkdir(sInstance,file);
+ } catch (IOException e) {
+ //return false;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+
+ //SDLActivity.mHasFocus = hasFocus;
+ if (hasFocus) {
+ hideSystemUI();
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ void doSetSystemUiVisibility() {
+ int uiOpts = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ getWindow().getDecorView().setSystemUiVisibility(uiOpts);
+ }
+
+ private static native boolean nativeGetHideSystemButton();
+ void hideSystemUI() {
+ if(nativeGetHideSystemButton() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+ doSetSystemUiVisibility();
+ }
+ }
+
+ static public String getLocaleName() {
+ Locale defloc = Locale.getDefault();
+ String lang = defloc.getLanguage();
+ String country = defloc.getCountry();
+ if(!country.isEmpty()) {
+ lang += "_";
+ lang += country.toLowerCase();
+ }
+ return lang;
+ }
+
+ static public void exit() {
+ System.exit(0);
+ }
+
+ static final int ORIENT_VERTICAL = 1;
+ static final int ORIENT_HORIZONTAL = 2;
+
+ static public void setOrientation(int orient) {
+ if(orient == ORIENT_VERTICAL) {
+ sInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ } else if(orient == ORIENT_HORIZONTAL) {
+ sInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ static public void triggerStorageAccessFramework() {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+ sInstance.startActivityForResult(intent, 3);
+ }
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
+ if (requestCode == 3) {
+ String p = Sp.getString("URI", null);
+ Uri oldUri = null;
+ if (p != null) oldUri = Uri.parse(p);
+ Uri treeUri = null;
+ if (responseCode == Activity.RESULT_OK) {
+ // Get Uri from Storage Access Framework.
+ treeUri = intent.getData();
+ // Persist URI - this is required for verification of writability.
+ if (treeUri != null) Sp.edit().putString("URI", treeUri.toString()).commit();
+ }
+
+ // If not confirmed SAF, or if still not writable, then revert settings.
+ if (responseCode != Activity.RESULT_OK) {
+ /* DialogUtil.displayError(getActivity(), R.string.message_dialog_cannot_write_to_folder_saf, false,
+ currentFolder);||!FileUtil.isWritableNormalOrSaf(currentFolder)
+*/
+ if (treeUri != null) Sp.edit().putString("URI", oldUri.toString()).commit();
+ return;
+ }
+
+ // After confirmation, update stored value of folder.
+ // Persist access permissions.
+ final int takeFlags = intent.getFlags()
+ & (Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
+ }
+ }
+
+}
diff --git a/project/android/src/org/tvp/kirikiri2/Kirikiroid2.java b/project/android/src/org/tvp/kirikiri2/Kirikiroid2.java
new file mode 100644
index 00000000..1c8bc53e
--- /dev/null
+++ b/project/android/src/org/tvp/kirikiri2/Kirikiroid2.java
@@ -0,0 +1,28 @@
+package org.tvp.kirikiri2;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Date;
+
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+
+public class Kirikiroid2 extends KR2Activity {
+
+ @Override
+ public int get_res_sd_operate_step() { return R.drawable.sd_operate_step; }
+}
diff --git a/project/android/src/org/tvp/kirikiri2/MediaStoreHack.java b/project/android/src/org/tvp/kirikiri2/MediaStoreHack.java
new file mode 100644
index 00000000..f8d64643
--- /dev/null
+++ b/project/android/src/org/tvp/kirikiri2/MediaStoreHack.java
@@ -0,0 +1,488 @@
+package org.tvp.kirikiri2;
+
+/**
+ * Created by Arpit on 29-06-2015.
+ */
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Locale;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.provider.BaseColumns;
+import android.provider.MediaStore;
+import android.util.Log;
+
+/**
+ * Wrapper for manipulating files via the Android Media Content Provider. As of Android 4.4 KitKat,
+ * applications can no longer write to the "secondary storage" of a device. Write operations using
+ * the java.io.File API will thus fail. This class restores access to those write operations by way
+ * of the Media Content Provider.
+ *
+ * Note that this class relies on the internal operational characteristics of the media content
+ * provider API, and as such is not guaranteed to be future-proof. Then again, we did all think the
+ * java.io.File API was going to be future-proof for media card access, so all bets are off.
+ *
+ * If you're forced to use this class, it's because Google/AOSP made a very poor API decision in
+ * Android 4.4 KitKat. Read more at https://plus.google.com/+TodLiebeck/posts/gjnmuaDM8sn
+ *
+ * Your application must declare the permission "android.permission.WRITE_EXTERNAL_STORAGE".
+ *
+ * Adapted from: http://forum.xda-developers.com/showpost.php?p=52151865&postcount=20
+ *
+ * @author Jared Rummler
+ */
+public class MediaStoreHack {
+
+ private static final String ALBUM_ART_URI = "content://media/external/audio/albumart";
+
+ private static final String[] ALBUM_PROJECTION = {
+ BaseColumns._ID, MediaStore.Audio.AlbumColumns.ALBUM_ID, "media_type"
+ };
+
+ /**
+ * Deletes the file. Returns true if the file has been successfully deleted or otherwise does
+ * not exist. This operation is not recursive.
+ */
+ public static boolean delete(final Context context, final File file) {
+ final String where = MediaStore.MediaColumns.DATA + "=?";
+ final String[] selectionArgs = new String[] {
+ file.getAbsolutePath()
+ };
+ final ContentResolver contentResolver = context.getContentResolver();
+ final Uri filesUri = MediaStore.Files.getContentUri("external");
+ // Delete the entry from the media database. This will actually delete media files.
+ contentResolver.delete(filesUri, where, selectionArgs);
+ // If the file is not a media file, create a new entry.
+ if (file.exists()) {
+ final ContentValues values = new ContentValues();
+ values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
+ contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+ // Delete the created entry, such that content provider will delete the file.
+ contentResolver.delete(filesUri, where, selectionArgs);
+ }
+ return !file.exists();
+ }
+
+ private static File getExternalFilesDir(final Context context) {
+ return context.getExternalFilesDir(null);
+ }
+
+ public static InputStream
+ getInputStream(final Context context, final File file, final long size) {
+ try {
+ final String where = MediaStore.MediaColumns.DATA + "=?";
+ final String[] selectionArgs = new String[] {
+ file.getAbsolutePath()
+ };
+ final ContentResolver contentResolver = context.getContentResolver();
+ final Uri filesUri = MediaStore.Files.getContentUri("external");
+ contentResolver.delete(filesUri, where, selectionArgs);
+ final ContentValues values = new ContentValues();
+ values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
+ values.put(MediaStore.MediaColumns.SIZE, size);
+ final Uri uri = contentResolver.insert(filesUri, values);
+ return contentResolver.openInputStream(uri);
+ } catch (final Throwable t) {
+ return null;
+ }
+ }
+ public static OutputStream getOutputStream(Context context,String str) {
+ OutputStream outputStream = null;
+ Uri fileUri = getUriFromFile(str,context);
+ if (fileUri != null) {
+ try {
+ outputStream = context.getContentResolver().openOutputStream(fileUri);
+ } catch (Throwable th) {
+ }
+ }
+ return outputStream;
+ }
+ public static Uri getUriFromFile(final String path,Context context) {
+ ContentResolver resolver = context.getContentResolver();
+
+ Cursor filecursor = resolver.query(MediaStore.Files.getContentUri("external"),
+ new String[] { BaseColumns._ID }, MediaStore.MediaColumns.DATA + " = ?",
+ new String[] { path }, MediaStore.MediaColumns.DATE_ADDED + " desc");
+ filecursor.moveToFirst();
+
+ if (filecursor.isAfterLast()) {
+ filecursor.close();
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.MediaColumns.DATA, path);
+ return resolver.insert(MediaStore.Files.getContentUri("external"), values);
+ }
+ else {
+ int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID));
+ Uri uri = MediaStore.Files.getContentUri("external").buildUpon().appendPath(
+ Integer.toString(imageId)).build();
+ filecursor.close();
+ return uri;
+ }
+ }
+
+ /**
+ * Returns an OutputStream to write to the file. The file will be truncated immediately.
+ */
+
+ private static int getTemporaryAlbumId(final Context context) {
+ final File temporaryTrack;
+ try {
+ temporaryTrack = installTemporaryTrack(context);
+ } catch (final IOException ex) {
+ Log.w("MediaFile", "Error installing tempory track.", ex);
+ return 0;
+ }
+ final Uri filesUri = MediaStore.Files.getContentUri("external");
+ final String[] selectionArgs = {
+ temporaryTrack.getAbsolutePath()
+ };
+ final ContentResolver contentResolver = context.getContentResolver();
+ Cursor cursor = contentResolver.query(filesUri, ALBUM_PROJECTION,
+ MediaStore.MediaColumns.DATA + "=?", selectionArgs, null);
+ if (cursor == null || !cursor.moveToFirst()) {
+ if (cursor != null) {
+ cursor.close();
+ cursor = null;
+ }
+ final ContentValues values = new ContentValues();
+ values.put(MediaStore.MediaColumns.DATA, temporaryTrack.getAbsolutePath());
+ values.put(MediaStore.MediaColumns.TITLE, "{MediaWrite Workaround}");
+ values.put(MediaStore.MediaColumns.SIZE, temporaryTrack.length());
+ values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
+ values.put(MediaStore.Audio.AudioColumns.IS_MUSIC, true);
+ contentResolver.insert(filesUri, values);
+ }
+ cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA
+ + "=?", selectionArgs, null);
+ if (cursor == null) {
+ return 0;
+ }
+ if (!cursor.moveToFirst()) {
+ cursor.close();
+ return 0;
+ }
+ final int id = cursor.getInt(0);
+ final int albumId = cursor.getInt(1);
+ final int mediaType = cursor.getInt(2);
+ cursor.close();
+ final ContentValues values = new ContentValues();
+ boolean updateRequired = false;
+ if (albumId == 0) {
+ values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, 13371337);
+ updateRequired = true;
+ }
+ if (mediaType != 2) {
+ values.put("media_type", 2);
+ updateRequired = true;
+ }
+ if (updateRequired) {
+ contentResolver.update(filesUri, values, BaseColumns._ID + "=" + id, null);
+ }
+ cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA
+ + "=?", selectionArgs, null);
+ if (cursor == null) {
+ return 0;
+ }
+ try {
+ if (!cursor.moveToFirst()) {
+ return 0;
+ }
+ return cursor.getInt(1);
+ } finally {
+ cursor.close();
+ }
+ }
+
+ private static final byte [] temptrack_mp3 = new byte [] {
+ 73, 68, 51, 4, 0, 0, 0, 0, 8, 65, 84, 80, 69, 49, 0, 0,
+ 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105, 116, 101,
+ 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 65, 76, 66,
+ 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105,
+ 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 73,
+ 84, 50, 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87,
+ 114, 105, 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125,
+ 65, 80, 73, 67, 0, 0, 2, 33, 0, 0, 0, 105, 109, 97, 103, 101,
+ 47, 112, 110, 103, 0, 3, 0, -119, 80, 78, 71, 13, 10, 26, 10, 0,
+ 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 32, 0, 0, 0, 32, 8,
+ 2, 0, 0, 0, -4, 24, -19, -93, 0, 0, 0, 1, 115, 82, 71, 66,
+ 0, -82, -50, 28, -23, 0, 0, 0, -50, 73, 68, 65, 84, 72, -57, -19,
+ 85, -55, 10, -128, 64, 8, 77, -1, -1, -97, -19, 48, 36, -30, 62, 83,
+ -76, 64, 30, 66, -59, -52, 124, 79, -35, -74, 95, -34, 38, 68, 68, 68,
+ 82, 81, -2, -95, -69, 78, 25, 31, 102, 87, -70, 124, 70, -2, 40, 114,
+ 8, 74, 3, 0, -22, 42, 76, 77, 0, -112, 4, -96, -78, 59, -33, -112,
+ 1, 101, 60, 90, 0, -72, 34, -42, 71, 22, 78, 20, -107, 92, -2, -51,
+ 45, 20, -78, 96, 42, -14, -48, 33, 74, -17, 98, 96, 69, 117, -103, -101,
+ -58, -26, 28, -56, -106, 106, 121, 103, 75, 70, -96, 11, 84, -97, 39, 37,
+ -86, -24, -66, -48, 39, 67, 107, -128, -97, 100, 81, -78, 121, 58, 0, -44,
+ 44, 82, -112, 44, -20, 18, -100, 34, -122, 59, -25, 57, 12, 53, -117, -94,
+ -103, 96, 61, 31, -123, -126, 69, 35, -53, -45, 27, 102, -115, 72, -10, -94,
+ 37, -121, -56, 61, -126, -2, -70, 118, -69, -100, 0, -93, -100, 54, 12, -49,
+ 92, -85, -23, -125, 51, 123, -83, 58, -21, 8, 59, -47, -110, 75, 57, -81,
+ -66, 70, -71, 95, 46, -111, 29, -73, 67, 31, -101, 122, -93, -81, 8, 0,
+ 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126, 84, 68, 84, 71, 0,
+ 0, 0, 20, 0, 0, 0, 50, 48, 49, 52, 45, 48, 52, 45, 48, 49,
+ 84, 50, 49, 58, 51, 57, 58, 51, 53, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -6, -112, -64, 95,
+ -85, 0, 0, 0, 0, 1, -92, 24, 0, 0, 0, 0, 0, 52, -125, -128,
+ 0, 0, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64,
+ -26, -97, -59, 3, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128,
+ 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46,
+ 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6,
+ -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0,
+ 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69,
+ 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0,
+ 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65,
+ 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0,
+ 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92,
+ 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85
+ };
+
+ private static File installTemporaryTrack(final Context context) throws IOException {
+ final File externalFilesDir = getExternalFilesDir(context);
+ if (externalFilesDir == null) {
+ return null;
+ }
+ final File temporaryTrack = new File(externalFilesDir, "temptrack.mp3");
+ OutputStream out = null;
+ try {
+ out = new FileOutputStream(temporaryTrack);
+ out.write(temptrack_mp3);
+ } finally {
+ out.close();
+ }
+ return temporaryTrack;
+ }
+
+ public static boolean mkdir(final Context context, final File file) throws IOException {
+ if (file.exists()) {
+ return file.isDirectory();
+ }
+ final File tmpFile = new File(file, ".MediaWriteTemp");
+ final int albumId = getTemporaryAlbumId(context);
+ if (albumId == 0) {
+ throw new IOException("Failed to create temporary album id.");
+ }
+ final Uri albumUri = Uri.parse(String.format(Locale.US, ALBUM_ART_URI + "/%d", albumId));
+ final ContentValues values = new ContentValues();
+ values.put(MediaStore.MediaColumns.DATA, tmpFile.getAbsolutePath());
+ final ContentResolver contentResolver = context.getContentResolver();
+ if (contentResolver.update(albumUri, values, null, null) == 0) {
+ values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, albumId);
+ contentResolver.insert(Uri.parse(ALBUM_ART_URI), values);
+ }
+ try {
+ final ParcelFileDescriptor fd = contentResolver.openFileDescriptor(albumUri, "r");
+ fd.close();
+ } finally {
+ delete(context, tmpFile);
+ }
+ return file.exists();
+ }
+
+ public static boolean mkfile(final Context context, final File file) {
+ final OutputStream outputStream = getOutputStream(context, file.getPath());
+ if (outputStream == null) {
+ return false;
+ }
+ try {
+ outputStream.close();
+ return true;
+ } catch (final IOException e) {
+ }
+ return false;
+ }
+
+}
diff --git a/src/core/Android.mk b/src/core/Android.mk
index 1f86f303..107f84fc 100644
--- a/src/core/Android.mk
+++ b/src/core/Android.mk
@@ -52,7 +52,6 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/base \
$(LOCAL_PATH)/environ/win32 \
$(LOCAL_PATH)/environ/android \
$(LOCAL_PATH)/environ/sdl \
- $(LOCAL_PATH)/environ/my_vcl \
$(LOCAL_PATH)/msg \
$(LOCAL_PATH)/msg/win32 \
$(LOCAL_PATH)/extension \
diff --git a/src/core/base/ScriptMgnIntf.cpp b/src/core/base/ScriptMgnIntf.cpp
index 5bbfe725..7f724c2a 100644
--- a/src/core/base/ScriptMgnIntf.cpp
+++ b/src/core/base/ScriptMgnIntf.cpp
@@ -52,6 +52,7 @@
#include "BitmapLayerTreeOwner.h"
#include "Extension.h"
#include "Platform.h"
+#include "ConfigManager/LocaleConfigManager.h"
//---------------------------------------------------------------------------
// Script system initialization script
@@ -880,11 +881,41 @@ bool TVPStartupSuccess = false;
//---------------------------------------------------------------------------
void TVPExecuteStartupScript()
{
+ ttstr strPatchError;
try {
ttstr patch = TVPGetAppPath() + "patch.tjs";
if(TVPIsExistentStorageNoSearch(patch))
- TVPExecuteStorage(patch);
- } catch (...) { }
+ TVPExecuteStorage(patch);
+ } catch (const TJS::eTJSScriptError &e) {
+ ttstr &msg = strPatchError;
+ msg += e.GetMessage();
+ const tjs_char *pszBlockName = e.GetBlockName();
+ if (pszBlockName && *pszBlockName) {
+ msg += TJS_W("\n@line(");
+ tjs_char tmp[34];
+ msg += TJS_int_to_str(e.GetSourceLine(), tmp);
+ msg += TJS_W(") ");
+ msg += pszBlockName;
+ }
+ msg += TJS_W("\n");
+ msg += e.GetTrace();
+ } catch (const TJS::eTJS &e) {
+ if (!TVPSystemUninitCalled)
+ strPatchError = e.GetMessage();
+ } catch (const std::exception &e) {
+ strPatchError = e.what();
+ } catch (const char* e) {
+ strPatchError = e;
+ } catch (const tjs_char* e) {
+ strPatchError = e;
+ }
+
+ if (!strPatchError.IsEmpty()) {
+ ttstr msg = LocaleConfigManager::GetInstance()->GetText("startup_patch_fail");
+ msg += "\n";
+ msg += strPatchError;
+ TVPShowSimpleMessageBox(msg, TVPGetPackageVersionString());
+ }
// execute "startup.tjs"
// try
diff --git a/src/core/base/SystemIntf.cpp b/src/core/base/SystemIntf.cpp
index 3772e0b9..92a872de 100644
--- a/src/core/base/SystemIntf.cpp
+++ b/src/core/base/SystemIntf.cpp
@@ -22,7 +22,7 @@
#include "Random.h"
#include "ScriptMgnIntf.h"
#include "DebugIntf.h"
-#include "ConfigManager\LocaleConfigManager.h"
+#include "ConfigManager/LocaleConfigManager.h"
#include "Platform.h"
extern bool TVPStartupSuccess;
diff --git a/src/core/base/UtilStreams.cpp b/src/core/base/UtilStreams.cpp
index 0d90229f..cac3ac7d 100644
--- a/src/core/base/UtilStreams.cpp
+++ b/src/core/base/UtilStreams.cpp
@@ -258,17 +258,17 @@ void tTVPMemoryStream::Init()
//---------------------------------------------------------------------------
void * tTVPMemoryStream::Alloc(size_t size)
{
- return malloc(size);
+ return TJS_malloc(size);
}
//---------------------------------------------------------------------------
void * tTVPMemoryStream::Realloc(void *orgblock, size_t size)
{
- return realloc(orgblock, size);
+ return TJS_realloc(orgblock, size);
}
//---------------------------------------------------------------------------
void tTVPMemoryStream::Free(void *block)
{
- free(block);
+ TJS_free(block);
}
//---------------------------------------------------------------------------
diff --git a/src/core/base/win32/StorageImpl.cpp b/src/core/base/win32/StorageImpl.cpp
index e1153c00..8bf55b4c 100644
--- a/src/core/base/win32/StorageImpl.cpp
+++ b/src/core/base/win32/StorageImpl.cpp
@@ -36,9 +36,13 @@
#include "dirent.h"
#include "TickCount.h"
#include
+#include
#include "win32io.h"
#include "combase.h"
#include
+#ifdef CC_TARGET_OS_IPHONE
+#define lseek64 lseek
+#endif
//---------------------------------------------------------------------------
// tTVPFileMedia
@@ -828,13 +832,13 @@ tjs_uint64 TJS_INTF_METHOD tTVPLocalFileStream::Seek(tjs_int64 offset, tjs_int w
return MemBuffer->Seek(offset, whence);
}
return lseek64(Handle, offset, whence);
- }
+}
//---------------------------------------------------------------------------
tjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Read(void *buffer, tjs_uint read_size)
{
if(MemBuffer) {
return MemBuffer->Read(buffer, read_size);
-}
+ }
return read(Handle, buffer, read_size);
}
//---------------------------------------------------------------------------
@@ -842,7 +846,7 @@ tjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Write(const void *buffer, tjs_uint
{
if(MemBuffer) {
return MemBuffer->Write(buffer, write_size);
-}
+ }
return write(Handle, buffer, write_size);
}
//---------------------------------------------------------------------------
@@ -850,7 +854,7 @@ void TJS_INTF_METHOD tTVPLocalFileStream::SetEndOfStorage()
{
if(MemBuffer) {
return MemBuffer->SetEndOfStorage();
-}
+ }
lseek64(Handle, 0, SEEK_END);
}
//---------------------------------------------------------------------------
diff --git a/src/core/base/win32/SysInitImpl.cpp b/src/core/base/win32/SysInitImpl.cpp
index ffd6a9a3..d415a3ca 100644
--- a/src/core/base/win32/SysInitImpl.cpp
+++ b/src/core/base/win32/SysInitImpl.cpp
@@ -1033,7 +1033,7 @@ void TVPBeforeSystemInit()
TVPAddImportantLog(TVPFormatMessage(TVPInfoTotalPhysicalMemory, tjs_int64(TVPTotalPhysMemory)));
if (TVPTotalPhysMemory > 256 * 1024 * 1024) {
- std::string str = IndividualConfigManager::GetInstance()->GetValueString("memusage", "unlimited");
+ std::string str = IndividualConfigManager::GetInstance()->GetValue("memusage", "unlimited");
if (str == ("low"))
TVPTotalPhysMemory = 0; // assumes zero
else if (str == ("medium"))
@@ -1339,11 +1339,11 @@ void TVPAfterSystemInit()
}
}
// check TVPGraphicSplitOperation option
- std::string _val = IndividualConfigManager::GetInstance()->GetValueString("renderer", "software");
+ std::string _val = IndividualConfigManager::GetInstance()->GetValue("renderer", "software");
if (_val != "software") {
TVPGraphicSplitOperationType = gsotNone;
} else {
- TVPDrawThreadNum = IndividualConfigManager::GetInstance()->GetValueInt("software_draw_thread", 0);
+ TVPDrawThreadNum = IndividualConfigManager::GetInstance()->GetValue("software_draw_thread", 0);
if (TVPGetCommandLine(TJS_W("-gsplit"), &opt))
{
ttstr str(opt);
diff --git a/src/core/base/win32/SystemImpl.cpp b/src/core/base/win32/SystemImpl.cpp
index 3054d229..2fa5553c 100644
--- a/src/core/base/win32/SystemImpl.cpp
+++ b/src/core/base/win32/SystemImpl.cpp
@@ -784,6 +784,7 @@ extern void TVPDoSaveSystemVariables()
try {
// hack for save system variable
iTJSDispatch2* global = TVPGetScriptDispatch();
+ if (!global) return;
tTJSVariant var;
if (global->PropGet(0, TJS_W("kag"), nullptr, &var, global) == TJS_S_OK && var.Type() == tvtObject) {
iTJSDispatch2* kag = var.AsObjectNoAddRef();
diff --git a/src/core/environ/Application.cpp b/src/core/environ/Application.cpp
index 454085d4..6197d199 100644
--- a/src/core/environ/Application.cpp
+++ b/src/core/environ/Application.cpp
@@ -48,6 +48,7 @@ tTVPApplication* Application = new tTVPApplication;
std::thread::id TVPMainThreadID;
static tTJSCriticalSection _NoMemCallBackCS;
static void *_reservedMem = malloc(1024 * 1024 * 4); // 4M reserved mem
+static bool _project_startup = false;
#define HOOK_MALLOC
static void _do_compact() {
@@ -459,6 +460,7 @@ tTVPApplication::~tTVPApplication() {
// // TTVPWindowForm �̃f�X�g���N�^���Ń��X�g����폜�����͂�
// }
// windows_list_.clear();
+ delete image_load_thread_;
}
#if 0
struct SEHException {
@@ -599,7 +601,7 @@ bool tTVPApplication::StartApplication(ttstr path) {
image_load_thread_->Resume();
/*if(TVPProjectDirSelected)*/ TVPInitializeStartupScript();
-
+ _project_startup = true;
// Run();
#if 0
try {
@@ -1010,18 +1012,23 @@ void tTVPApplication::FilterUserMessage(const std::functionLoadRequest( owner, bmp, name );
}
}
+
+void tTVPApplication::RegisterActiveEvent(void *host, const std::function& func/*empty = unregister*/)
+{
+ if (func)
+ m_activeEvents.emplace(host, func);
+ else
+ m_activeEvents.erase(host);
+}
+
#if 0
std::vector* LoadLinesFromFile( const std::wstring& path ) {
FILE *fp = NULL;
diff --git a/src/core/environ/Application.h b/src/core/environ/Application.h
index 2d3f315b..84481128 100644
--- a/src/core/environ/Application.h
+++ b/src/core/environ/Application.h
@@ -8,6 +8,7 @@
#include
#include
#include
+#include